⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 wmesa.c

📁 Mesa is an open-source implementation of the OpenGL specification - a system for rendering interacti
💻 C
📖 第 1 页 / 共 4 页
字号:
/* * Windows (Win32/Win64) device driver for Mesa * */#include "wmesadef.h"#include "colors.h"#include <GL/wmesa.h>#include <winuser.h>#include "context.h"#include "extensions.h"#include "framebuffer.h"#include "renderbuffer.h"#include "drivers/common/driverfuncs.h"#include "vbo/vbo.h"#include "swrast/swrast.h"#include "swrast_setup/swrast_setup.h"#include "tnl/tnl.h"#include "tnl/t_context.h"#include "tnl/t_pipeline.h"/* linked list of our Framebuffers (windows) */static WMesaFramebuffer FirstFramebuffer = NULL;/** * Create a new WMesaFramebuffer object which will correspond to the * given HDC (Window handle). */WMesaFramebufferwmesa_new_framebuffer(HDC hdc, GLvisual *visual){    WMesaFramebuffer pwfb        = (WMesaFramebuffer) malloc(sizeof(struct wmesa_framebuffer));    if (pwfb) {        _mesa_initialize_framebuffer(&pwfb->Base, visual);        pwfb->hDC = hdc;        /* insert at head of list */        pwfb->next = FirstFramebuffer;        FirstFramebuffer = pwfb;    }    return pwfb;}/** * Given an hdc, free the corresponding WMesaFramebuffer */voidwmesa_free_framebuffer(HDC hdc){    WMesaFramebuffer pwfb, prev;    for (pwfb = FirstFramebuffer; pwfb; pwfb = pwfb->next) {        if (pwfb->hDC == hdc)            break;	prev = pwfb;    }    if (pwfb) {	if (pwfb == FirstFramebuffer)	    FirstFramebuffer = pwfb->next;	else	    prev->next = pwfb->next;	free(pwfb);    }}/** * Given an hdc, return the corresponding WMesaFramebuffer */WMesaFramebufferwmesa_lookup_framebuffer(HDC hdc){    WMesaFramebuffer pwfb;    for (pwfb = FirstFramebuffer; pwfb; pwfb = pwfb->next) {        if (pwfb->hDC == hdc)            return pwfb;    }    return NULL;}/** * Given a GLframebuffer, return the corresponding WMesaFramebuffer. */static WMesaFramebuffer wmesa_framebuffer(GLframebuffer *fb){    return (WMesaFramebuffer) fb;}/** * Given a GLcontext, return the corresponding WMesaContext. */static WMesaContext wmesa_context(const GLcontext *ctx){    return (WMesaContext) ctx;}/* * Every driver should implement a GetString function in order to * return a meaningful GL_RENDERER string. */static const GLubyte *wmesa_get_string(GLcontext *ctx, GLenum name){    return (name == GL_RENDERER) ? 	(GLubyte *) "Mesa Windows GDI Driver" : NULL;}/* * Determine the pixel format based on the pixel size. */static void wmSetPixelFormat(WMesaFramebuffer pwfb, HDC hDC){    pwfb->cColorBits = GetDeviceCaps(hDC, BITSPIXEL);    /* Only 16 and 32 bit targets are supported now */    assert(pwfb->cColorBits == 0 ||	   pwfb->cColorBits == 16 || 	   pwfb->cColorBits == 24 || 	   pwfb->cColorBits == 32);    switch(pwfb->cColorBits){    case 8:	pwfb->pixelformat = PF_INDEX8;	break;    case 16:	pwfb->pixelformat = PF_5R6G5B;	break;    case 24:    case 32:	pwfb->pixelformat = PF_8R8G8B;	break;    default:	pwfb->pixelformat = PF_BADFORMAT;    }}/** * Create DIB for back buffer. * We write into this memory with the span routines and then blit it * to the window on a buffer swap. */BOOL wmCreateBackingStore(WMesaFramebuffer pwfb, long lxSize, long lySize){    HDC          hdc = pwfb->hDC;    LPBITMAPINFO pbmi = &(pwfb->bmi);    HDC          hic;    pbmi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);    pbmi->bmiHeader.biWidth = lxSize;    pbmi->bmiHeader.biHeight= -lySize;    pbmi->bmiHeader.biPlanes = 1;    pbmi->bmiHeader.biBitCount = GetDeviceCaps(pwfb->hDC, BITSPIXEL);    pbmi->bmiHeader.biCompression = BI_RGB;    pbmi->bmiHeader.biSizeImage = 0;    pbmi->bmiHeader.biXPelsPerMeter = 0;    pbmi->bmiHeader.biYPelsPerMeter = 0;    pbmi->bmiHeader.biClrUsed = 0;    pbmi->bmiHeader.biClrImportant = 0;        pwfb->cColorBits = pbmi->bmiHeader.biBitCount;    pwfb->ScanWidth = (lxSize * (pwfb->cColorBits / 8) + 3) & ~3;        hic = CreateIC("display", NULL, NULL, NULL);    pwfb->dib_hDC = CreateCompatibleDC(hic);        pwfb->hbmDIB = CreateDIBSection(hic,				   &pwfb->bmi,				   DIB_RGB_COLORS,				   (void **)&(pwfb->pbPixels),				   0,				   0);    pwfb->hOldBitmap = SelectObject(pwfb->dib_hDC, pwfb->hbmDIB);        DeleteDC(hic);    wmSetPixelFormat(pwfb, pwfb->hDC);    return TRUE;}static wmDeleteBackingStore(WMesaFramebuffer pwfb){    if (pwfb->hbmDIB) {	SelectObject(pwfb->dib_hDC, pwfb->hOldBitmap);	DeleteDC(pwfb->dib_hDC);	DeleteObject(pwfb->hbmDIB);    }}/** * Find the width and height of the window named by hdc. */static voidget_window_size(HDC hdc, GLuint *width, GLuint *height){    if (WindowFromDC(hdc)) {        RECT rect;        GetClientRect(WindowFromDC(hdc), &rect);        *width = rect.right - rect.left;        *height = rect.bottom - rect.top;    }    else { /* Memory context */        /* From contributed code - use the size of the desktop         * for the size of a memory context (?) */        *width = GetDeviceCaps(hdc, HORZRES);        *height = GetDeviceCaps(hdc, VERTRES);    }}static voidwmesa_get_buffer_size(GLframebuffer *buffer, GLuint *width, GLuint *height){    WMesaFramebuffer pwfb = wmesa_framebuffer(buffer);    get_window_size(pwfb->hDC, width, height);}static void wmesa_flush(GLcontext *ctx){    WMesaContext pwc = wmesa_context(ctx);    WMesaFramebuffer pwfb = wmesa_framebuffer(ctx->WinSysDrawBuffer);    if (ctx->Visual.doubleBufferMode == 1) {	BitBlt(pwfb->hDC, 0, 0, pwfb->Base.Width, pwfb->Base.Height,	       pwfb->dib_hDC, 0, 0, SRCCOPY);    }    else {	/* Do nothing for single buffer */    }}/**********************************************************************//*****                   CLEAR Functions                          *****//**********************************************************************//* If we do not implement these, Mesa clears the buffers via the pixel * span writing interface, which is very slow for a clear operation. *//* * Set the color index used to clear the color buffer. */static void clear_index(GLcontext *ctx, GLuint index){    WMesaContext pwc = wmesa_context(ctx);    /* Note that indexed mode is not supported yet */    pwc->clearColorRef = RGB(0,0,0);}/* * Set the color used to clear the color buffer. */static void clear_color(GLcontext *ctx, const GLfloat color[4]){    WMesaContext pwc = wmesa_context(ctx);    WMesaFramebuffer pwfb = wmesa_framebuffer(ctx->DrawBuffer);    GLubyte col[3];    UINT    bytesPerPixel = pwfb->cColorBits / 8;     CLAMPED_FLOAT_TO_UBYTE(col[0], color[0]);    CLAMPED_FLOAT_TO_UBYTE(col[1], color[1]);    CLAMPED_FLOAT_TO_UBYTE(col[2], color[2]);    pwc->clearColorRef = RGB(col[0], col[1], col[2]);    DeleteObject(pwc->clearPen);    DeleteObject(pwc->clearBrush);    pwc->clearPen = CreatePen(PS_SOLID, 1, pwc->clearColorRef);     pwc->clearBrush = CreateSolidBrush(pwc->clearColorRef); }/*  * Clear the specified region of the color buffer using the clear color  * or index as specified by one of the two functions above.  *  * This procedure clears either the front and/or the back COLOR buffers.  * Only the "left" buffer is cleared since we are not stereo.  * Clearing of the other non-color buffers is left to the swrast.  */ static void clear(GLcontext *ctx, GLbitfield mask){#define FLIP(Y)  (ctx->DrawBuffer->Height - (Y) - 1)    const GLint x = ctx->DrawBuffer->_Xmin;    const GLint y = ctx->DrawBuffer->_Ymin;    const GLint height = ctx->DrawBuffer->_Ymax - ctx->DrawBuffer->_Ymin;    const GLint width  = ctx->DrawBuffer->_Xmax - ctx->DrawBuffer->_Xmin;    WMesaContext pwc = wmesa_context(ctx);    WMesaFramebuffer pwfb = wmesa_framebuffer(ctx->DrawBuffer);    int done = 0;    /* Let swrast do all the work if the masks are not set to     * clear all channels. */    if (ctx->Color.ColorMask[0] != 0xff ||	ctx->Color.ColorMask[1] != 0xff ||	ctx->Color.ColorMask[2] != 0xff ||	ctx->Color.ColorMask[3] != 0xff) {	_swrast_Clear(ctx, mask);	return;    }    /* Back buffer */    if (mask & BUFFER_BIT_BACK_LEFT) { 		int     i, rowSize; 	UINT    bytesPerPixel = pwfb->cColorBits / 8; 	LPBYTE  lpb, clearRow;	LPWORD  lpw;	BYTE    bColor; 	WORD    wColor; 	BYTE    r, g, b; 	DWORD   dwColor; 	LPDWORD lpdw; 		/* Try for a fast clear - clearing entire buffer with a single	 * byte value. */	if (width == ctx->DrawBuffer->Width &&            height == ctx->DrawBuffer->Height) { /* entire buffer */	    /* Now check for an easy clear value */	    switch (bytesPerPixel) {	    case 1:		bColor = BGR8(GetRValue(pwc->clearColorRef), 			      GetGValue(pwc->clearColorRef), 			      GetBValue(pwc->clearColorRef));		memset(pwfb->pbPixels, bColor, 		       pwfb->ScanWidth * height);		done = 1;		break;	    case 2:		wColor = BGR16(GetRValue(pwc->clearColorRef), 			       GetGValue(pwc->clearColorRef), 			       GetBValue(pwc->clearColorRef)); 		if (((wColor >> 8) & 0xff) == (wColor & 0xff)) {		    memset(pwfb->pbPixels, wColor & 0xff, 			   pwfb->ScanWidth * height);		    done = 1;		}		break;	    case 3:		/* fall through */	    case 4:		if (GetRValue(pwc->clearColorRef) == 		    GetGValue(pwc->clearColorRef) &&		    GetRValue(pwc->clearColorRef) == 		    GetBValue(pwc->clearColorRef)) {		    memset(pwfb->pbPixels, 			   GetRValue(pwc->clearColorRef), 			   pwfb->ScanWidth * height);		    done = 1;		}		break;	    default:		break;	    }	} /* all */	if (!done) {	    /* Need to clear a row at a time.  Begin by setting the first	     * row in the area to be cleared to the clear color. */	    	    clearRow = pwfb->pbPixels + 		pwfb->ScanWidth * FLIP(y) +		bytesPerPixel * x; 	    switch (bytesPerPixel) {	    case 1:		lpb = clearRow;		bColor = BGR8(GetRValue(pwc->clearColorRef), 			      GetGValue(pwc->clearColorRef), 			      GetBValue(pwc->clearColorRef));		memset(lpb, bColor, width);		break;	    case 2:		lpw = (LPWORD)clearRow;		wColor = BGR16(GetRValue(pwc->clearColorRef), 			       GetGValue(pwc->clearColorRef), 			       GetBValue(pwc->clearColorRef)); 		for (i=0; i<width; i++)		    *lpw++ = wColor;		break;	    case 3: 		lpb = clearRow;		r = GetRValue(pwc->clearColorRef); 		g = GetGValue(pwc->clearColorRef); 		b = GetBValue(pwc->clearColorRef); 		for (i=0; i<width; i++) {		    *lpb++ = b; 		    *lpb++ = g; 		    *lpb++ = r; 		} 		break;	    case 4: 		lpdw = (LPDWORD)clearRow; 		dwColor = BGR32(GetRValue(pwc->clearColorRef), 				GetGValue(pwc->clearColorRef), 				GetBValue(pwc->clearColorRef)); 		for (i=0; i<width; i++)		    *lpdw++ = dwColor;		break;	    default:		break;	    } /* switch */	    	    /* copy cleared row to other rows in buffer */	    lpb = clearRow - pwfb->ScanWidth;	    rowSize = width * bytesPerPixel;	    for (i=1; i<height; i++) { 		memcpy(lpb, clearRow, rowSize); 		lpb -= pwfb->ScanWidth; 	    } 	} /* not done */	mask &= ~BUFFER_BIT_BACK_LEFT;    } /* back buffer */     /* front buffer */    if (mask & BUFFER_BIT_FRONT_LEFT) { 	HDC DC = pwc->hDC; 	HPEN Old_Pen = SelectObject(DC, pwc->clearPen); 	HBRUSH Old_Brush = SelectObject(DC, pwc->clearBrush);	Rectangle(DC,		  x,		  FLIP(y) + 1,		  x + width + 1,		  FLIP(y) - height + 1);	SelectObject(DC, Old_Pen); 	SelectObject(DC, Old_Brush); 	mask &= ~BUFFER_BIT_FRONT_LEFT;    } /* front buffer */         /* Call swrast if there is anything left to clear (like DEPTH) */     if (mask) 	_swrast_Clear(ctx, mask);  

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -