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

📄 wmesa.c

📁 winNT技术操作系统,国外开放的原代码和LIUX一样
💻 C
📖 第 1 页 / 共 3 页
字号:
/*
 * Windows (Win32) device driver for Mesa
 *
 */

#include "wmesadef.h"
#include "colors.h"
#include <GL/wmesa.h>
#include "extensions.h"
#include "framebuffer.h"
#include "renderbuffer.h"
#include "drivers/common/driverfuncs.h"
#include "array_cache/acache.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"

#define FLIP(Y)  (Current->height-(Y)-1)

/* Static Data */

static PWMC Current = NULL;

/*
 * 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(PWMC pwc, HDC hDC)
{
    pwc->cColorBits = GetDeviceCaps(hDC, BITSPIXEL);

    // TEMP - only 16 and 32 bit targets are supported now
    assert(pwc->cColorBits == 16 || 
	   pwc->cColorBits == 32);

    switch(pwc->cColorBits){
    case 8:
	pwc->pixelformat = PF_INDEX8;
	break;
    case 16:
	pwc->pixelformat = PF_5R6G5B;
	break;
    case 32:
	pwc->pixelformat = PF_8R8G8B;
	break;
    default:
	pwc->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(PWMC pwc, long lxSize, long lySize)
{
    HDC          hdc = pwc->hDC;
    LPBITMAPINFO pbmi = &(pwc->bmi);
    HDC          hic;

    assert(pwc->db_flag == GL_TRUE);

    pbmi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
    pbmi->bmiHeader.biWidth = lxSize;
    pbmi->bmiHeader.biHeight= -lySize;
    pbmi->bmiHeader.biPlanes = 1;
    pbmi->bmiHeader.biBitCount = GetDeviceCaps(pwc->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;
    
    pwc->cColorBits = pbmi->bmiHeader.biBitCount;
    pwc->ScanWidth = (lxSize * (pwc->cColorBits / 8) + 3) & ~3;
    
    hic = CreateIC("display", NULL, NULL, NULL);
    pwc->dib.hDC = CreateCompatibleDC(hic);
    
    pwc->hbmDIB = CreateDIBSection(hic,
				   &pwc->bmi,
				   DIB_RGB_COLORS,
				   (void **)&(pwc->pbPixels),
				   0,
				   0);
    pwc->hOldBitmap = SelectObject(pwc->dib.hDC, pwc->hbmDIB);
    
    DeleteDC(hic);

    wmSetPixelFormat(pwc, pwc->hDC);
    return TRUE;
}

static void wmDeleteBackingStore(PWMC pwc)
{
    if (pwc->hbmDIB) {
	SelectObject(pwc->dib.hDC, pwc->hOldBitmap);
	DeleteDC(pwc->dib.hDC);
	DeleteObject(pwc->hbmDIB);
    }
}

static void wmesa_get_buffer_size(GLframebuffer *buffer, 
				  GLuint *width, 
				  GLuint *height )
{
    *width = Current->width;
    *height = Current->height;
}


static void wmesa_flush(GLcontext* ctx)
{
    if (Current->db_flag) {
	BitBlt(Current->hDC, 0, 0, Current->width, Current->height,
	       Current->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)
{
    /* Note that indexed mode is not supported yet */
    Current->clearColorRef = RGB(0,0,0);
}

/*
 * Set the color used to clear the color buffer.
 */
static void clear_color(GLcontext* ctx, const GLfloat color[4])
{
    GLubyte col[3];
    UINT    bytesPerPixel = Current->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]);
    Current->clearColorRef = RGB(col[0], col[1], col[2]);
    DeleteObject(Current->clearPen);
    DeleteObject(Current->clearBrush);
    Current->clearPen = CreatePen(PS_SOLID, 1, Current->clearColorRef); 
    Current->clearBrush = CreateSolidBrush(Current->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, 
		  GLboolean all, 
		  GLint x, GLint y, 
		  GLint width, GLint height) 
{
    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, all, x, y, width, height); 
	return;
    }

    /* 'all' means clear the entire window */
    if (all) { 
	x = y = 0; 
	width = Current->width; 
	height = Current->height; 
    } 

    /* Back buffer */
    if (mask & BUFFER_BIT_BACK_LEFT) { 
	
	int     i, rowSize; 
	UINT    bytesPerPixel = Current->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 (all) { /* entire buffer */
	    /* Now check for an easy clear value */
	    switch (bytesPerPixel) {
	    case 1:
		bColor = BGR8(GetRValue(Current->clearColorRef), 
			      GetGValue(Current->clearColorRef), 
			      GetBValue(Current->clearColorRef));
		memset(Current->pbPixels, bColor, 
		       Current->ScanWidth * height);
		done = 1;
		break;
	    case 2:
		wColor = BGR16(GetRValue(Current->clearColorRef), 
			       GetGValue(Current->clearColorRef), 
			       GetBValue(Current->clearColorRef)); 
		if (((wColor >> 8) & 0xff) == (wColor & 0xff)) {
		    memset(Current->pbPixels, wColor & 0xff, 
			   Current->ScanWidth * height);
		    done = 1;
		}
		break;
	    case 3:
		/* fall through */
	    case 4:
		if (GetRValue(Current->clearColorRef) == 
		    GetGValue(Current->clearColorRef) &&
		    GetRValue(Current->clearColorRef) == 
		    GetBValue(Current->clearColorRef)) {
		    memset(Current->pbPixels, 
			   GetRValue(Current->clearColorRef), 
			   Current->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 = Current->pbPixels + 
		Current->ScanWidth * FLIP(y) +
		bytesPerPixel * x; 
	    switch (bytesPerPixel) {
	    case 1:
		lpb = clearRow;
		bColor = BGR8(GetRValue(Current->clearColorRef), 
			      GetGValue(Current->clearColorRef), 
			      GetBValue(Current->clearColorRef));
		memset(lpb, bColor, width);
		break;
	    case 2:
		lpw = (LPWORD)clearRow;
		wColor = BGR16(GetRValue(Current->clearColorRef), 
			       GetGValue(Current->clearColorRef), 
			       GetBValue(Current->clearColorRef)); 
		for (i=0; i<width; i++)
		    *lpw++ = wColor;
		break;
	    case 3: 
		lpb = clearRow;
		r = GetRValue(Current->clearColorRef); 
		g = GetGValue(Current->clearColorRef); 
		b = GetBValue(Current->clearColorRef); 
		for (i=0; i<width; i++) {
		    *lpb++ = b; 
		    *lpb++ = g; 
		    *lpb++ = r; 
		} 
		break;
	    case 4: 
		lpdw = (LPDWORD)clearRow; 
		dwColor = BGR32(GetRValue(Current->clearColorRef), 
				GetGValue(Current->clearColorRef), 
				GetBValue(Current->clearColorRef)); 
		for (i=0; i<width; i++)
		    *lpdw++ = dwColor;
		break;
	    default:
		break;
	    } /* switch */
	    
	    /* copy cleared row to other rows in buffer */
	    lpb = clearRow - Current->ScanWidth;
	    rowSize = width * bytesPerPixel;
	    for (i=1; i<height; i++) { 
		memcpy(lpb, clearRow, rowSize); 
		lpb -= Current->ScanWidth; 
	    } 
	} /* not done */
	mask &= ~BUFFER_BIT_BACK_LEFT;
    } /* back buffer */ 

    /* front buffer */
    if (mask & BUFFER_BIT_FRONT_LEFT) { 
	HDC DC = Current->hDC; 
	HPEN Old_Pen = SelectObject(DC, Current->clearPen); 
	HBRUSH Old_Brush = SelectObject(DC, Current->clearBrush);
	Rectangle(DC,
		  x,
		  FLIP(y),
		  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, all, x, y, width, height); 
  
} 


/**********************************************************************/
/*****                   PIXEL Functions                          *****/
/**********************************************************************/

/* SINGLE BUFFER */

/* These are slow, but work with all non-indexed visual types */

/* Write a horizontal span of RGBA color pixels with a boolean mask. */
static void write_rgba_span_single(const GLcontext* ctx, 
				   struct gl_renderbuffer *rb, 
				   GLuint n, GLint x, GLint y,
				   const GLubyte rgba[][4], 
				   const GLubyte mask[] )
{
    PWMC    pwc = Current;
    GLuint i;
    
    (void) ctx;
    y=FLIP(y);
    if (mask) {
	for (i=0; i<n; i++)
	    if (mask[i])
		SetPixel(pwc->hDC, x+i, y, RGB(rgba[i][RCOMP], rgba[i][GCOMP], 
					       rgba[i][BCOMP]));
    }
    else {
	for (i=0; i<n; i++)
	    SetPixel(pwc->hDC, x+i, y, RGB(rgba[i][RCOMP], rgba[i][GCOMP], 
					   rgba[i][BCOMP]));
    }
    
}

/* Write a horizontal span of RGB color pixels with a boolean mask. */
static void write_rgb_span_single(const GLcontext* ctx, 
				  struct gl_renderbuffer *rb, 
				  GLuint n, GLint x, GLint y,
				  const GLubyte rgb[][3], 
				  const GLubyte mask[] )
{
    PWMC    pwc = Current;
    GLuint i;
    
    (void) ctx;
    y=FLIP(y);
    if (mask) {
	for (i=0; i<n; i++)
	    if (mask[i])
		SetPixel(pwc->hDC, x+i, y, RGB(rgb[i][RCOMP], rgb[i][GCOMP], 
					       rgb[i][BCOMP]));
    }
    else {
	for (i=0; i<n; i++)
	    SetPixel(pwc->hDC, x+i, y, RGB(rgb[i][RCOMP], rgb[i][GCOMP], 

⌨️ 快捷键说明

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