| /**************************************************************************** |
| * |
| * Mesa 3-D graphics library |
| * Direct3D Driver Interface |
| * |
| * ======================================================================== |
| * |
| * Copyright (C) 1991-2004 SciTech Software, Inc. All rights reserved. |
| * |
| * Permission is hereby granted, free of charge, to any person obtaining a |
| * copy of this software and associated documentation files (the "Software"), |
| * to deal in the Software without restriction, including without limitation |
| * the rights to use, copy, modify, merge, publish, distribute, sublicense, |
| * and/or sell copies of the Software, and to permit persons to whom the |
| * Software is furnished to do so, subject to the following conditions: |
| * |
| * The above copyright notice and this permission notice shall be included |
| * in all copies or substantial portions of the Software. |
| * |
| * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS |
| * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
| * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL |
| * SCITECH SOFTWARE INC BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, |
| * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF |
| * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE |
| * SOFTWARE. |
| * |
| * ====================================================================== |
| * |
| * Language: ANSI C |
| * Environment: Windows 9x/2000/XP/XBox (Win32) |
| * |
| * Description: Mesa Software WGL (WindowsGL) |
| * |
| ****************************************************************************/ |
| |
| #include <windows.h> |
| #define GL_GLEXT_PROTOTYPES |
| #include <GL/gl.h> |
| #include <GL/glext.h> |
| |
| #include "glheader.h" |
| #include "colors.h" |
| #include "context.h" |
| #include "colormac.h" |
| #include "dd.h" |
| #include "depth.h" |
| #include "extensions.h" |
| #include "macros.h" |
| #include "matrix.h" |
| // #include "mem.h" |
| //#include "mmath.h" |
| #include "mtypes.h" |
| #include "texformat.h" |
| #include "texstore.h" |
| #include "teximage.h" |
| #include "vbo/vbo.h" |
| #include "swrast/swrast.h" |
| #include "swrast_setup/swrast_setup.h" |
| #include "swrast/s_context.h" |
| #include "swrast/s_depth.h" |
| #include "swrast/s_lines.h" |
| #include "swrast/s_triangle.h" |
| #include "tnl/tnl.h" |
| #include "tnl/t_context.h" |
| #include "tnl/t_pipeline.h" |
| |
| #include "dglcontext.h" |
| #include "gld_driver.h" |
| |
| //--------------------------------------------------------------------------- |
| //--------------------------------------------------------------------------- |
| |
| DGL_pixelFormat pfTemplateMesaSW = |
| { |
| { |
| sizeof(PIXELFORMATDESCRIPTOR), // Size of the data structure |
| 1, // Structure version - should be 1 |
| // Flags: |
| PFD_DRAW_TO_WINDOW | // The buffer can draw to a window or device surface. |
| PFD_DRAW_TO_BITMAP | // The buffer can draw to a bitmap. (DaveM) |
| PFD_SUPPORT_GDI | // The buffer supports GDI drawing. (DaveM) |
| PFD_SUPPORT_OPENGL | // The buffer supports OpenGL drawing. |
| PFD_DOUBLEBUFFER | // The buffer is double-buffered. |
| 0, // Placeholder for easy commenting of above flags |
| PFD_TYPE_RGBA, // Pixel type RGBA. |
| 32, // Total colour bitplanes (excluding alpha bitplanes) |
| 8, 0, // Red bits, shift |
| 8, 8, // Green bits, shift |
| 8, 16, // Blue bits, shift |
| 8, 24, // Alpha bits, shift (destination alpha) |
| 64, // Accumulator bits (total) |
| 16, 16, 16, 16, // Accumulator bits: Red, Green, Blue, Alpha |
| 16, // Depth bits |
| 8, // Stencil bits |
| 0, // Number of auxiliary buffers |
| 0, // Layer type |
| 0, // Specifies the number of overlay and underlay planes. |
| 0, // Layer mask |
| 0, // Specifies the transparent color or index of an underlay plane. |
| 0 // Damage mask |
| }, |
| 0, // Unused |
| }; |
| |
| //--------------------------------------------------------------------------- |
| // Extensions |
| //--------------------------------------------------------------------------- |
| |
| typedef struct { |
| PROC proc; |
| char *name; |
| } GLD_extension; |
| |
| static GLD_extension GLD_extList[] = { |
| #ifdef GL_EXT_polygon_offset |
| { (PROC)glPolygonOffsetEXT, "glPolygonOffsetEXT" }, |
| #endif |
| { (PROC)glBlendEquationEXT, "glBlendEquationEXT" }, |
| { (PROC)glBlendColorEXT, "glBlendColorExt" }, |
| { (PROC)glVertexPointerEXT, "glVertexPointerEXT" }, |
| { (PROC)glNormalPointerEXT, "glNormalPointerEXT" }, |
| { (PROC)glColorPointerEXT, "glColorPointerEXT" }, |
| { (PROC)glIndexPointerEXT, "glIndexPointerEXT" }, |
| { (PROC)glTexCoordPointerEXT, "glTexCoordPointer" }, |
| { (PROC)glEdgeFlagPointerEXT, "glEdgeFlagPointerEXT" }, |
| { (PROC)glGetPointervEXT, "glGetPointervEXT" }, |
| { (PROC)glArrayElementEXT, "glArrayElementEXT" }, |
| { (PROC)glDrawArraysEXT, "glDrawArrayEXT" }, |
| { (PROC)glAreTexturesResidentEXT, "glAreTexturesResidentEXT" }, |
| { (PROC)glBindTextureEXT, "glBindTextureEXT" }, |
| { (PROC)glDeleteTexturesEXT, "glDeleteTexturesEXT" }, |
| { (PROC)glGenTexturesEXT, "glGenTexturesEXT" }, |
| { (PROC)glIsTextureEXT, "glIsTextureEXT" }, |
| { (PROC)glPrioritizeTexturesEXT, "glPrioritizeTexturesEXT" }, |
| { (PROC)glCopyTexSubImage3DEXT, "glCopyTexSubImage3DEXT" }, |
| { (PROC)glTexImage3DEXT, "glTexImage3DEXT" }, |
| { (PROC)glTexSubImage3DEXT, "glTexSubImage3DEXT" }, |
| { (PROC)glPointParameterfEXT, "glPointParameterfEXT" }, |
| { (PROC)glPointParameterfvEXT, "glPointParameterfvEXT" }, |
| { (PROC)glLockArraysEXT, "glLockArraysEXT" }, |
| { (PROC)glUnlockArraysEXT, "glUnlockArraysEXT" }, |
| { NULL, "\0" } |
| }; |
| |
| //--------------------------------------------------------------------------- |
| // WMesa Internal Functions |
| //--------------------------------------------------------------------------- |
| |
| #define PAGE_FILE 0xffffffff |
| |
| #define REDBITS 0x03 |
| #define REDSHIFT 0x00 |
| #define GREENBITS 0x03 |
| #define GREENSHIFT 0x03 |
| #define BLUEBITS 0x02 |
| #define BLUESHIFT 0x06 |
| |
| typedef struct _dibSection { |
| HDC hDC; |
| HANDLE hFileMap; |
| BOOL fFlushed; |
| LPVOID base; |
| } WMDIBSECTION, *PWMDIBSECTION; |
| |
| typedef struct wmesa_context { |
| HWND Window; |
| HDC hDC; |
| HPALETTE hPalette; |
| HPALETTE hOldPalette; |
| HPEN hPen; |
| HPEN hOldPen; |
| HCURSOR hOldCursor; |
| COLORREF crColor; |
| // 3D projection stuff |
| RECT drawRect; |
| UINT uiDIBoffset; |
| // OpenGL stuff |
| HPALETTE hGLPalette; |
| GLuint width; |
| GLuint height; |
| GLuint ScanWidth; |
| GLboolean db_flag; //* double buffered? |
| GLboolean rgb_flag; //* RGB mode? |
| GLboolean dither_flag; //* use dither when 256 color mode for RGB? |
| GLuint depth; //* bits per pixel (1, 8, 24, etc) |
| ULONG pixel; // current color index or RGBA pixel value |
| ULONG clearpixel; //* pixel for clearing the color buffers |
| PBYTE ScreenMem; // WinG memory |
| BITMAPINFO *IndexFormat; |
| HPALETTE hPal; // Current Palette |
| HPALETTE hPalHalfTone; |
| |
| |
| WMDIBSECTION dib; |
| BITMAPINFO bmi; |
| HBITMAP hbmDIB; |
| HBITMAP hOldBitmap; |
| HBITMAP Old_Compat_BM; |
| HBITMAP Compat_BM; // Bitmap for double buffering |
| PBYTE pbPixels; |
| int nColors; |
| BYTE cColorBits; |
| int pixelformat; |
| |
| RECT rectOffScreen; |
| RECT rectSurface; |
| // HWND hwnd; |
| DWORD pitch; |
| PBYTE addrOffScreen; |
| |
| // We always double-buffer, for performance reasons, but |
| // we need to know which of SwapBuffers() or glFlush() to |
| // handle. If we're emulating, then we update on Flush(), |
| // otherwise we update on SwapBufers(). KeithH |
| BOOL bEmulateSingleBuffer; |
| } WMesaContext, *PWMC; |
| |
| #define GLD_GET_WMESA_DRIVER(c) (WMesaContext*)(c)->glPriv |
| |
| // TODO: |
| GLint stereo_flag = 0 ; |
| |
| /* If we are double-buffering, we want to get the DC for the |
| * off-screen DIB, otherwise the DC for the window. |
| */ |
| #define DD_GETDC ((Current->db_flag) ? Current->dib.hDC : Current->hDC ) |
| #define DD_RELEASEDC |
| |
| #define FLIP(Y) (Current->height-(Y)-1) |
| |
| struct DISPLAY_OPTIONS { |
| int stereo; |
| int fullScreen; |
| int mode; |
| int bpp; |
| }; |
| |
| struct DISPLAY_OPTIONS displayOptions; |
| |
| //--------------------------------------------------------------------------- |
| |
| static unsigned char threeto8[8] = { |
| 0, 0111>>1, 0222>>1, 0333>>1, 0444>>1, 0555>>1, 0666>>1, 0377 |
| }; |
| |
| static unsigned char twoto8[4] = { |
| 0, 0x55, 0xaa, 0xff |
| }; |
| |
| static unsigned char oneto8[2] = { |
| 0, 255 |
| }; |
| |
| //--------------------------------------------------------------------------- |
| |
| BYTE DITHER_RGB_2_8BIT( int red, int green, int blue, int pixel, int scanline) |
| { |
| char unsigned redtemp, greentemp, bluetemp, paletteindex; |
| |
| //*** now, look up each value in the halftone matrix |
| //*** using an 8x8 ordered dither. |
| redtemp = aDividedBy51[red] |
| + (aModulo51[red] > aHalftone8x8[(pixel%8)*8 |
| + scanline%8]); |
| greentemp = aDividedBy51[(char unsigned)green] |
| + (aModulo51[green] > aHalftone8x8[ |
| (pixel%8)*8 + scanline%8]); |
| bluetemp = aDividedBy51[(char unsigned)blue] |
| + (aModulo51[blue] > aHalftone8x8[ |
| (pixel%8)*8 +scanline%8]); |
| |
| //*** recombine the halftoned rgb values into a palette index |
| paletteindex = |
| redtemp + aTimes6[greentemp] + aTimes36[bluetemp]; |
| |
| //*** and translate through the wing halftone palette |
| //*** translation vector to give the correct value. |
| return aWinGHalftoneTranslation[paletteindex]; |
| } |
| |
| //--------------------------------------------------------------------------- |
| |
| static unsigned char componentFromIndex(UCHAR i, UINT nbits, UINT shift) |
| { |
| unsigned char val; |
| |
| val = i >> shift; |
| switch (nbits) { |
| |
| case 1: |
| val &= 0x1; |
| return oneto8[val]; |
| |
| case 2: |
| val &= 0x3; |
| return twoto8[val]; |
| |
| case 3: |
| val &= 0x7; |
| return threeto8[val]; |
| |
| default: |
| return 0; |
| } |
| } |
| |
| //--------------------------------------------------------------------------- |
| |
| |
| void wmSetPixel(PWMC pwc, int iScanLine, int iPixel, BYTE r, BYTE g, BYTE b) |
| { |
| WMesaContext *Current = pwc; |
| |
| // Test for invalid scanline parameter. KeithH |
| if ((iScanLine < 0) || (iScanLine >= pwc->height)) |
| return; |
| |
| if (Current->db_flag) { |
| LPBYTE lpb = pwc->pbPixels; |
| UINT nBypp = pwc->cColorBits >> 3; |
| UINT nOffset = iPixel % nBypp; |
| |
| lpb += pwc->ScanWidth * iScanLine; |
| lpb += iPixel * nBypp; |
| |
| if(nBypp == 1){ |
| if(pwc->dither_flag) |
| *lpb = DITHER_RGB_2_8BIT(r,g,b,iScanLine,iPixel); |
| else |
| *lpb = BGR8(r,g,b); |
| } |
| else if(nBypp == 2) |
| *((LPWORD)lpb) = BGR16(r,g,b); |
| else if (nBypp == 3) |
| *((LPDWORD)lpb) = BGR24(r,g,b); |
| else if (nBypp == 4) |
| *((LPDWORD)lpb) = BGR32(r,g,b); |
| } |
| else{ |
| SetPixel(Current->hDC, iPixel, iScanLine, RGB(r,g,b)); |
| } |
| } |
| |
| //--------------------------------------------------------------------------- |
| |
| void wmCreateDIBSection( |
| HDC hDC, |
| PWMC pwc, // handle of device context |
| CONST BITMAPINFO *pbmi, // bitmap size, format, and color data |
| UINT iUsage // color data type indicator: RGB values or palette indices |
| ) |
| { |
| DWORD dwSize = 0; |
| DWORD dwScanWidth; |
| UINT nBypp = pwc->cColorBits / 8; |
| HDC hic; |
| |
| dwScanWidth = (((pwc->ScanWidth * nBypp)+ 3) & ~3); |
| |
| pwc->ScanWidth =pwc->pitch = dwScanWidth; |
| |
| if (stereo_flag) |
| pwc->ScanWidth = 2* pwc->pitch; |
| |
| dwSize = sizeof(BITMAPINFO) + (dwScanWidth * pwc->height); |
| |
| pwc->dib.hFileMap = CreateFileMapping((HANDLE)PAGE_FILE, |
| NULL, |
| PAGE_READWRITE | SEC_COMMIT, |
| 0, |
| dwSize, |
| NULL); |
| |
| if (!pwc->dib.hFileMap) |
| return; |
| |
| pwc->dib.base = MapViewOfFile(pwc->dib.hFileMap, |
| FILE_MAP_ALL_ACCESS, |
| 0, |
| 0, |
| 0); |
| |
| if(!pwc->dib.base){ |
| CloseHandle(pwc->dib.hFileMap); |
| return; |
| } |
| |
| |
| CopyMemory(pwc->dib.base, pbmi, sizeof(BITMAPINFO)); |
| |
| hic = CreateIC("display", NULL, NULL, NULL); |
| pwc->dib.hDC = CreateCompatibleDC(hic); |
| |
| |
| pwc->hbmDIB = CreateDIBSection(hic, |
| &(pwc->bmi), |
| (iUsage ? DIB_PAL_COLORS : DIB_RGB_COLORS), |
| &(pwc->pbPixels), |
| pwc->dib.hFileMap, |
| 0); |
| pwc->ScreenMem = pwc->addrOffScreen = pwc->pbPixels; |
| pwc->hOldBitmap = SelectObject(pwc->dib.hDC, pwc->hbmDIB); |
| |
| DeleteDC(hic); |
| |
| return; |
| |
| } |
| |
| //--------------------------------------------------------------------------- |
| |
| void wmCreatePalette( PWMC pwdc ) |
| { |
| /* Create a compressed and re-expanded 3:3:2 palette */ |
| int i; |
| LOGPALETTE *pPal; |
| BYTE rb, rs, gb, gs, bb, bs; |
| |
| pwdc->nColors = 0x100; |
| |
| pPal = (PLOGPALETTE)malloc(sizeof(LOGPALETTE) + |
| pwdc->nColors * sizeof(PALETTEENTRY)); |
| memset( pPal, 0, sizeof(LOGPALETTE) + pwdc->nColors * sizeof(PALETTEENTRY) ); |
| |
| pPal->palVersion = 0x300; |
| |
| rb = REDBITS; |
| rs = REDSHIFT; |
| gb = GREENBITS; |
| gs = GREENSHIFT; |
| bb = BLUEBITS; |
| bs = BLUESHIFT; |
| |
| if (pwdc->db_flag) { |
| |
| /* Need to make two palettes: one for the screen DC and one for the DIB. */ |
| pPal->palNumEntries = pwdc->nColors; |
| for (i = 0; i < pwdc->nColors; i++) { |
| pPal->palPalEntry[i].peRed = componentFromIndex( i, rb, rs ); |
| pPal->palPalEntry[i].peGreen = componentFromIndex( i, gb, gs ); |
| pPal->palPalEntry[i].peBlue = componentFromIndex( i, bb, bs ); |
| pPal->palPalEntry[i].peFlags = 0; |
| } |
| pwdc->hGLPalette = CreatePalette( pPal ); |
| pwdc->hPalette = CreatePalette( pPal ); |
| } |
| |
| else { |
| pPal->palNumEntries = pwdc->nColors; |
| for (i = 0; i < pwdc->nColors; i++) { |
| pPal->palPalEntry[i].peRed = componentFromIndex( i, rb, rs ); |
| pPal->palPalEntry[i].peGreen = componentFromIndex( i, gb, gs ); |
| pPal->palPalEntry[i].peBlue = componentFromIndex( i, bb, bs ); |
| pPal->palPalEntry[i].peFlags = 0; |
| } |
| pwdc->hGLPalette = CreatePalette( pPal ); |
| } |
| |
| free(pPal); |
| |
| } |
| |
| //--------------------------------------------------------------------------- |
| |
| /* This function sets the color table of a DIB section |
| * to match that of the destination DC |
| */ |
| BOOL wmSetDibColors(PWMC pwc) |
| { |
| RGBQUAD *pColTab, *pRGB; |
| PALETTEENTRY *pPal, *pPE; |
| int i, nColors; |
| BOOL bRet=TRUE; |
| DWORD dwErr=0; |
| |
| /* Build a color table in the DIB that maps to the |
| * selected palette in the DC. |
| */ |
| nColors = 1 << pwc->cColorBits; |
| pPal = (PALETTEENTRY *)malloc( nColors * sizeof(PALETTEENTRY)); |
| memset( pPal, 0, nColors * sizeof(PALETTEENTRY) ); |
| GetPaletteEntries( pwc->hGLPalette, 0, nColors, pPal ); |
| pColTab = (RGBQUAD *)malloc( nColors * sizeof(RGBQUAD)); |
| for (i = 0, pRGB = pColTab, pPE = pPal; i < nColors; i++, pRGB++, pPE++) { |
| pRGB->rgbRed = pPE->peRed; |
| pRGB->rgbGreen = pPE->peGreen; |
| pRGB->rgbBlue = pPE->peBlue; |
| } |
| if(pwc->db_flag) |
| bRet = SetDIBColorTable(pwc->dib.hDC, 0, nColors, pColTab ); |
| |
| if(!bRet) |
| dwErr = GetLastError(); |
| |
| free( pColTab ); |
| free( pPal ); |
| |
| return bRet; |
| } |
| |
| //--------------------------------------------------------------------------- |
| |
| static void wmSetPixelFormat( PWMC wc, HDC hDC) |
| { |
| if(wc->rgb_flag) |
| wc->cColorBits = GetDeviceCaps(hDC, BITSPIXEL); |
| else |
| wc->cColorBits = 8; |
| switch(wc->cColorBits){ |
| case 8: |
| if(wc->dither_flag != GL_TRUE) |
| wc->pixelformat = PF_INDEX8; |
| else |
| wc->pixelformat = PF_DITHER8; |
| break; |
| case 16: |
| wc->pixelformat = PF_5R6G5B; |
| break; |
| case 32: |
| wc->pixelformat = PF_8R8G8B; |
| break; |
| default: |
| wc->pixelformat = PF_BADFORMAT; |
| } |
| } |
| |
| //--------------------------------------------------------------------------- |
| |
| /* |
| * This function creates the DIB section that is used for combined |
| * GL and GDI calls |
| */ |
| BOOL wmCreateBackingStore(PWMC pwc, long lxSize, long lySize) |
| { |
| HDC hdc = pwc->hDC; |
| LPBITMAPINFO pbmi = &(pwc->bmi); |
| int iUsage; |
| |
| pbmi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER); |
| pbmi->bmiHeader.biWidth = lxSize; |
| pbmi->bmiHeader.biHeight= -lySize; |
| pbmi->bmiHeader.biPlanes = 1; |
| if(pwc->rgb_flag) |
| pbmi->bmiHeader.biBitCount = GetDeviceCaps(pwc->hDC, BITSPIXEL); |
| else |
| pbmi->bmiHeader.biBitCount = 8; |
| 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; |
| |
| iUsage = (pbmi->bmiHeader.biBitCount <= 8) ? DIB_PAL_COLORS : DIB_RGB_COLORS; |
| |
| pwc->cColorBits = pbmi->bmiHeader.biBitCount; |
| pwc->ScanWidth = pwc->pitch = lxSize; |
| pwc->width = lxSize; |
| pwc->height = lySize; |
| |
| wmCreateDIBSection(hdc, pwc, pbmi, iUsage); |
| |
| if ((iUsage == DIB_PAL_COLORS) && !(pwc->hGLPalette)) { |
| wmCreatePalette( pwc ); |
| wmSetDibColors( pwc ); |
| } |
| wmSetPixelFormat(pwc, pwc->hDC); |
| return TRUE; |
| } |
| |
| //--------------------------------------------------------------------------- |
| |
| /* |
| * Free up the dib section that was created |
| */ |
| BOOL wmDeleteBackingStore(PWMC pwc) |
| { |
| SelectObject(pwc->dib.hDC, pwc->hOldBitmap); |
| DeleteDC(pwc->dib.hDC); |
| DeleteObject(pwc->hbmDIB); |
| UnmapViewOfFile(pwc->dib.base); |
| CloseHandle(pwc->dib.hFileMap); |
| return TRUE; |
| } |
| |
| //--------------------------------------------------------------------------- |
| |
| /* |
| * Blit memory DC to screen DC |
| */ |
| BOOL wmFlush(PWMC pwc, HDC hDC) |
| { |
| BOOL bRet = 0; |
| DWORD dwErr = 0; |
| |
| // Now using bEmulateSingleBuffer in the calling function. KeithH |
| |
| // if(pwc->db_flag){ |
| bRet = BitBlt(hDC, 0, 0, pwc->width, pwc->height, |
| pwc->dib.hDC, 0, 0, SRCCOPY); |
| // } |
| |
| return bRet; |
| |
| } |
| |
| //--------------------------------------------------------------------------- |
| // Support Functions |
| //--------------------------------------------------------------------------- |
| |
| static void flush(struct gl_context* ctx) |
| { |
| GLD_context *gldCtx = GLD_GET_CONTEXT(ctx); |
| WMesaContext *Current = GLD_GET_WMESA_DRIVER(gldCtx); |
| /* |
| if((Current->rgb_flag &&!(Current->db_flag)) |
| ||(!Current->rgb_flag)) |
| { |
| wmFlush(Current, Current->hDC); |
| } |
| */ |
| // Only flush if we're not in double-buffer mode. KeithH |
| // The demo fractal.c calls glutSwapBuffers() then glFlush()! |
| if (Current->bEmulateSingleBuffer) { |
| wmFlush(Current, Current->hDC); |
| } |
| } |
| |
| |
| //--------------------------------------------------------------------------- |
| |
| /* |
| * Set the color used to clear the color buffer. |
| */ |
| //static void clear_color( struct gl_context* ctx, const GLchan color[4] ) |
| // Changed for Mesa 5.x. KeithH |
| static void clear_color( |
| struct gl_context* ctx, |
| const GLfloat color[4]) |
| { |
| GLD_context *gldCtx = GLD_GET_CONTEXT(ctx); |
| WMesaContext *Current = GLD_GET_WMESA_DRIVER(gldCtx); |
| GLubyte col[4]; |
| 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->clearpixel = RGB(col[0], col[1], col[2]); |
| } |
| |
| |
| //--------------------------------------------------------------------------- |
| |
| |
| /* |
| * 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. |
| * We also only clear the color buffers if the color masks are all 1's. |
| * Otherwise, we let swrast do it. |
| */ |
| |
| static clear(struct gl_context* ctx, GLbitfield mask, |
| GLboolean all, GLint x, GLint y, GLint width, GLint height) |
| { |
| GLD_context *gldCtx = GLD_GET_CONTEXT(ctx); |
| WMesaContext *Current = GLD_GET_WMESA_DRIVER(gldCtx); |
| DWORD dwColor; |
| WORD wColor; |
| BYTE bColor; |
| LPDWORD lpdw = (LPDWORD)Current->pbPixels; |
| LPWORD lpw = (LPWORD)Current->pbPixels; |
| LPBYTE lpb = Current->pbPixels; |
| int lines; |
| const GLuint *colorMask = (GLuint *) &ctx->Color.ColorMask; |
| |
| if (all){ |
| x=y=0; |
| width=Current->width; |
| height=Current->height; |
| } |
| |
| |
| /* sanity check - can't have right(stereo) buffers */ |
| assert((mask & (DD_FRONT_RIGHT_BIT | DD_BACK_RIGHT_BIT)) == 0); |
| |
| /* clear alpha */ |
| if ((mask & (DD_FRONT_LEFT_BIT | DD_BACK_RIGHT_BIT)) && |
| ctx->DrawBuffer->UseSoftwareAlphaBuffers && |
| ctx->Color.ColorMask[ACOMP]) { |
| _swrast_clear_alpha_buffers( ctx ); |
| } |
| |
| if (*colorMask == 0xffffffff && ctx->Color.IndexMask == 0xffffffff) { |
| if (mask & DD_BACK_LEFT_BIT) { |
| /* Double-buffering - clear back buffer */ |
| UINT nBypp = Current->cColorBits / 8; |
| int i = 0; |
| int iSize = 0; |
| |
| assert(Current->db_flag==GL_TRUE); /* we'd better be double buffer */ |
| if(nBypp ==1 ){ |
| iSize = Current->width/4; |
| bColor = BGR8(GetRValue(Current->clearpixel), |
| GetGValue(Current->clearpixel), |
| GetBValue(Current->clearpixel)); |
| wColor = MAKEWORD(bColor,bColor); |
| dwColor = MAKELONG(wColor, wColor); |
| } |
| if(nBypp == 2){ |
| iSize = Current->width / 2; |
| wColor = BGR16(GetRValue(Current->clearpixel), |
| GetGValue(Current->clearpixel), |
| GetBValue(Current->clearpixel)); |
| dwColor = MAKELONG(wColor, wColor); |
| } |
| else if(nBypp == 4){ |
| iSize = Current->width; |
| dwColor = BGR32(GetRValue(Current->clearpixel), |
| GetGValue(Current->clearpixel), |
| GetBValue(Current->clearpixel)); |
| } |
| |
| /* clear a line */ |
| while(i < iSize){ |
| *lpdw = dwColor; |
| lpdw++; |
| i++; |
| } |
| |
| /* This is the 24bit case */ |
| if (nBypp == 3) { |
| iSize = Current->width *3/4; |
| dwColor = BGR24(GetRValue(Current->clearpixel), |
| GetGValue(Current->clearpixel), |
| GetBValue(Current->clearpixel)); |
| while(i < iSize){ |
| *lpdw = dwColor; |
| lpb += nBypp; |
| lpdw = (LPDWORD)lpb; |
| i++; |
| } |
| } |
| |
| i = 0; |
| if (stereo_flag) |
| lines = height /2; |
| else |
| lines = height; |
| /* copy cleared line to other lines in buffer */ |
| do { |
| memcpy(lpb, Current->pbPixels, iSize*4); |
| lpb += Current->ScanWidth; |
| i++; |
| } |
| while (i<lines-1); |
| mask &= ~DD_BACK_LEFT_BIT; |
| } /* double-buffer */ |
| |
| if (mask & DD_FRONT_LEFT_BIT) { |
| /* single-buffer */ |
| HDC DC=DD_GETDC; |
| HPEN Pen=CreatePen(PS_SOLID,1,Current->clearpixel); |
| HBRUSH Brush=CreateSolidBrush(Current->clearpixel); |
| HPEN Old_Pen=SelectObject(DC,Pen); |
| HBRUSH Old_Brush=SelectObject(DC,Brush); |
| Rectangle(DC,x,y,x+width,y+height); |
| SelectObject(DC,Old_Pen); |
| SelectObject(DC,Old_Brush); |
| DeleteObject(Pen); |
| DeleteObject(Brush); |
| DD_RELEASEDC; |
| mask &= ~DD_FRONT_LEFT_BIT; |
| } /* single-buffer */ |
| } /* if masks are all 1's */ |
| |
| /* Call swrast if there is anything left to clear (like DEPTH) */ |
| if (mask) |
| _swrast_Clear( ctx, mask, all, x, y, width, height ); |
| } |
| |
| |
| //--------------------------------------------------------------------------- |
| |
| |
| static void enable( struct gl_context* ctx, GLenum pname, GLboolean enable ) |
| { |
| GLD_context *gldCtx = GLD_GET_CONTEXT(ctx); |
| WMesaContext *Current = GLD_GET_WMESA_DRIVER(gldCtx); |
| |
| if (!Current) |
| return; |
| |
| if (pname == GL_DITHER) { |
| if(enable == GL_FALSE){ |
| Current->dither_flag = GL_FALSE; |
| if(Current->cColorBits == 8) |
| Current->pixelformat = PF_INDEX8; |
| } |
| else{ |
| if (Current->rgb_flag && Current->cColorBits == 8){ |
| Current->pixelformat = PF_DITHER8; |
| Current->dither_flag = GL_TRUE; |
| } |
| else |
| Current->dither_flag = GL_FALSE; |
| } |
| } |
| } |
| |
| //--------------------------------------------------------------------------- |
| |
| static GLboolean set_draw_buffer( struct gl_context* ctx, GLenum mode ) |
| { |
| /* TODO: this could be better */ |
| if (mode==GL_FRONT_LEFT || mode==GL_BACK_LEFT) { |
| return GL_TRUE; |
| } |
| else { |
| return GL_FALSE; |
| } |
| } |
| |
| //--------------------------------------------------------------------------- |
| |
| |
| static void set_read_buffer(struct gl_context *ctx, struct gl_framebuffer *colorBuffer, |
| GLenum buffer ) |
| { |
| /* XXX todo */ |
| return; |
| } |
| |
| |
| //--------------------------------------------------------------------------- |
| |
| |
| /* Return characteristics of the output buffer. */ |
| //static void buffer_size( struct gl_context* ctx, GLuint *width, GLuint *height ) |
| // Altered for Mesa 5.x. KeithH |
| static void buffer_size( |
| struct gl_framebuffer *buffer, |
| GLuint *width, |
| GLuint *height) |
| { |
| // For some reason the context is not passed into this function. |
| // Therefore we have to explicitly retrieve it. |
| GET_CURRENT_CONTEXT(ctx); |
| |
| GLD_context *gldCtx = GLD_GET_CONTEXT(ctx); |
| WMesaContext *Current = GLD_GET_WMESA_DRIVER(gldCtx); |
| int New_Size; |
| RECT CR; |
| |
| GetClientRect(Current->Window,&CR); |
| |
| *width=CR.right; |
| *height=CR.bottom; |
| |
| New_Size=((*width)!=Current->width) || ((*height)!=Current->height); |
| |
| if (New_Size){ |
| Current->width=*width; |
| Current->height=*height; |
| Current->ScanWidth=Current->width; |
| if ((Current->ScanWidth%sizeof(long))!=0) |
| Current->ScanWidth+=(sizeof(long)-(Current->ScanWidth%sizeof(long))); |
| |
| if (Current->db_flag){ |
| if (Current->rgb_flag==GL_TRUE && Current->dither_flag!=GL_TRUE){ |
| wmDeleteBackingStore(Current); |
| wmCreateBackingStore(Current, Current->width, Current->height); |
| } |
| } |
| |
| } |
| } |
| |
| |
| |
| /**********************************************************************/ |
| /***** Accelerated point, line, polygon rendering *****/ |
| /**********************************************************************/ |
| |
| /* Accelerated routines are not implemented in 4.0. See OSMesa for ideas. */ |
| |
| static void fast_rgb_points( struct gl_context* ctx, GLuint first, GLuint last ) |
| { |
| } |
| |
| //--------------------------------------------------------------------------- |
| |
| /* Return pointer to accelerated points function */ |
| extern tnl_points_func choose_points_function( struct gl_context* ctx ) |
| { |
| return NULL; |
| } |
| |
| //--------------------------------------------------------------------------- |
| |
| static void fast_flat_rgb_line( struct gl_context* ctx, GLuint v0, |
| GLuint v1, GLuint pv ) |
| { |
| } |
| |
| //--------------------------------------------------------------------------- |
| |
| static tnl_line_func choose_line_function( struct gl_context* ctx ) |
| { |
| } |
| |
| |
| /**********************************************************************/ |
| /***** Span-based pixel drawing *****/ |
| /**********************************************************************/ |
| |
| |
| /* Write a horizontal span of 32-bit color-index pixels with a boolean mask. */ |
| static void write_ci32_span( const struct gl_context* ctx, |
| GLuint n, GLint x, GLint y, |
| const GLuint index[], |
| const GLubyte mask[] ) |
| { |
| GLD_context *gldCtx = GLD_GET_CONTEXT(ctx); |
| WMesaContext *Current = GLD_GET_WMESA_DRIVER(gldCtx); |
| GLuint i; |
| PBYTE Mem=Current->ScreenMem+FLIP(y)*Current->ScanWidth+x; |
| assert(Current->rgb_flag==GL_FALSE); |
| for (i=0; i<n; i++) |
| if (mask[i]) |
| Mem[i]=index[i]; |
| } |
| |
| |
| //--------------------------------------------------------------------------- |
| |
| /* Write a horizontal span of 8-bit color-index pixels with a boolean mask. */ |
| static void write_ci8_span( const struct gl_context* ctx, |
| GLuint n, GLint x, GLint y, |
| const GLubyte index[], |
| const GLubyte mask[] ) |
| { |
| GLD_context *gldCtx = GLD_GET_CONTEXT(ctx); |
| WMesaContext *Current = GLD_GET_WMESA_DRIVER(gldCtx); |
| GLuint i; |
| PBYTE Mem=Current->ScreenMem+FLIP(y)*Current->ScanWidth+x; |
| assert(Current->rgb_flag==GL_FALSE); |
| for (i=0; i<n; i++) |
| if (mask[i]) |
| Mem[i]=index[i]; |
| } |
| |
| |
| //--------------------------------------------------------------------------- |
| |
| |
| /* |
| * Write a horizontal span of pixels with a boolean mask. The current |
| * color index is used for all pixels. |
| */ |
| static void write_mono_ci_span(const struct gl_context* ctx, |
| GLuint n,GLint x,GLint y, |
| GLuint colorIndex, const GLubyte mask[]) |
| { |
| GLD_context *gldCtx = GLD_GET_CONTEXT(ctx); |
| WMesaContext *Current = GLD_GET_WMESA_DRIVER(gldCtx); |
| GLuint i; |
| BYTE *Mem=Current->ScreenMem+FLIP(y)*Current->ScanWidth+x; |
| assert(Current->rgb_flag==GL_FALSE); |
| for (i=0; i<n; i++) |
| if (mask[i]) |
| Mem[i]=colorIndex; |
| } |
| |
| //--------------------------------------------------------------------------- |
| |
| /* |
| * To improve the performance of this routine, frob the data into an actual |
| * scanline and call bitblt on the complete scan line instead of SetPixel. |
| */ |
| |
| /* Write a horizontal span of RGBA color pixels with a boolean mask. */ |
| static void write_rgba_span( const struct gl_context* ctx, GLuint n, GLint x, GLint y, |
| const GLubyte rgba[][4], const GLubyte mask[] ) |
| { |
| GLD_context *gldCtx = GLD_GET_CONTEXT(ctx); |
| WMesaContext *Current = GLD_GET_WMESA_DRIVER(gldCtx); |
| PWMC pwc = Current; |
| |
| if (pwc->rgb_flag==GL_TRUE) |
| { |
| GLuint i; |
| HDC DC=DD_GETDC; |
| y=FLIP(y); |
| if (mask) { |
| for (i=0; i<n; i++) |
| if (mask[i]) |
| wmSetPixel(pwc, y, x + i, |
| rgba[i][RCOMP], rgba[i][GCOMP], rgba[i][BCOMP]); |
| } |
| else { |
| for (i=0; i<n; i++) |
| wmSetPixel(pwc, y, x + i, |
| rgba[i][RCOMP], rgba[i][GCOMP], rgba[i][BCOMP] ); |
| } |
| DD_RELEASEDC; |
| } |
| else |
| { |
| GLuint i; |
| BYTE *Mem=Current->ScreenMem+y*Current->ScanWidth+x; |
| y = FLIP(y); |
| if (mask) { |
| for (i=0; i<n; i++) |
| if (mask[i]) |
| Mem[i] = GetNearestPaletteIndex(Current->hPal, |
| RGB(rgba[i][RCOMP], |
| rgba[i][GCOMP], |
| rgba[i][BCOMP])); |
| } |
| else { |
| for (i=0; i<n; i++) |
| Mem[i] = GetNearestPaletteIndex(Current->hPal, |
| 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( const struct gl_context* ctx, |
| GLuint n, GLint x, GLint y, |
| const GLubyte rgb[][3], const GLubyte mask[] ) |
| { |
| GLD_context *gldCtx = GLD_GET_CONTEXT(ctx); |
| WMesaContext *Current = GLD_GET_WMESA_DRIVER(gldCtx); |
| PWMC pwc = Current; |
| |
| if (pwc->rgb_flag==GL_TRUE) |
| { |
| GLuint i; |
| HDC DC=DD_GETDC; |
| y=FLIP(y); |
| if (mask) { |
| for (i=0; i<n; i++) |
| if (mask[i]) |
| wmSetPixel(pwc, y, x + i, |
| rgb[i][RCOMP], rgb[i][GCOMP], rgb[i][BCOMP]); |
| } |
| else { |
| for (i=0; i<n; i++) |
| wmSetPixel(pwc, y, x + i, |
| rgb[i][RCOMP], rgb[i][GCOMP], rgb[i][BCOMP] ); |
| } |
| DD_RELEASEDC; |
| } |
| else |
| { |
| GLuint i; |
| BYTE *Mem=Current->ScreenMem+y*Current->ScanWidth+x; |
| y = FLIP(y); |
| if (mask) { |
| for (i=0; i<n; i++) |
| if (mask[i]) |
| Mem[i] = GetNearestPaletteIndex(Current->hPal, |
| RGB(rgb[i][RCOMP], |
| rgb[i][GCOMP], |
| rgb[i][BCOMP])); |
| } |
| else { |
| for (i=0; i<n; i++) |
| Mem[i] = GetNearestPaletteIndex(Current->hPal, |
| RGB(rgb[i][RCOMP], |
| rgb[i][GCOMP], |
| rgb[i][BCOMP])); |
| } |
| } |
| } |
| |
| //--------------------------------------------------------------------------- |
| |
| /* |
| * Write a horizontal span of pixels with a boolean mask. The current color |
| * is used for all pixels. |
| */ |
| static void write_mono_rgba_span( const struct gl_context* ctx, |
| GLuint n, GLint x, GLint y, |
| const GLchan color[4], const GLubyte mask[]) |
| { |
| GLD_context *gldCtx = GLD_GET_CONTEXT(ctx); |
| WMesaContext *Current = GLD_GET_WMESA_DRIVER(gldCtx); |
| ULONG pixel = RGB( color[RCOMP], color[GCOMP], color[BCOMP] ); |
| GLuint i; |
| HDC DC=DD_GETDC; |
| PWMC pwc = Current; |
| assert(Current->rgb_flag==GL_TRUE); |
| y=FLIP(y); |
| if(Current->rgb_flag==GL_TRUE){ |
| for (i=0; i<n; i++) |
| if (mask[i]) |
| wmSetPixel(pwc,y,x+i,color[RCOMP], color[GCOMP], color[BCOMP]); |
| } |
| else { |
| for (i=0; i<n; i++) |
| if (mask[i]) |
| SetPixel(DC, y, x+i, pixel); |
| } |
| DD_RELEASEDC; |
| } |
| |
| |
| |
| /**********************************************************************/ |
| /***** Array-based pixel drawing *****/ |
| /**********************************************************************/ |
| |
| |
| /* Write an array of 32-bit index pixels with a boolean mask. */ |
| static void write_ci32_pixels( const struct gl_context* ctx, |
| GLuint n, const GLint x[], const GLint y[], |
| const GLuint index[], const GLubyte mask[] ) |
| { |
| GLD_context *gldCtx = GLD_GET_CONTEXT(ctx); |
| WMesaContext *Current = GLD_GET_WMESA_DRIVER(gldCtx); |
| GLuint i; |
| assert(Current->rgb_flag==GL_FALSE); |
| for (i=0; i<n; i++) { |
| if (mask[i]) { |
| BYTE *Mem=Current->ScreenMem+FLIP(y[i])*Current->ScanWidth+x[i]; |
| *Mem = index[i]; |
| } |
| } |
| } |
| |
| |
| //--------------------------------------------------------------------------- |
| |
| |
| /* |
| * Write an array of pixels with a boolean mask. The current color |
| * index is used for all pixels. |
| */ |
| static void write_mono_ci_pixels( const struct gl_context* ctx, |
| GLuint n, |
| const GLint x[], const GLint y[], |
| GLuint colorIndex, const GLubyte mask[] ) |
| { |
| GLD_context *gldCtx = GLD_GET_CONTEXT(ctx); |
| WMesaContext *Current = GLD_GET_WMESA_DRIVER(gldCtx); |
| GLuint i; |
| assert(Current->rgb_flag==GL_FALSE); |
| for (i=0; i<n; i++) { |
| if (mask[i]) { |
| BYTE *Mem=Current->ScreenMem+FLIP(y[i])*Current->ScanWidth+x[i]; |
| *Mem = colorIndex; |
| } |
| } |
| } |
| |
| |
| //--------------------------------------------------------------------------- |
| |
| |
| /* Write an array of RGBA pixels with a boolean mask. */ |
| static void write_rgba_pixels( const struct gl_context* ctx, |
| GLuint n, const GLint x[], const GLint y[], |
| const GLubyte rgba[][4], const GLubyte mask[] ) |
| { |
| GLD_context *gldCtx = GLD_GET_CONTEXT(ctx); |
| WMesaContext *Current = GLD_GET_WMESA_DRIVER(gldCtx); |
| GLuint i; |
| PWMC pwc = Current; |
| HDC DC=DD_GETDC; |
| assert(Current->rgb_flag==GL_TRUE); |
| for (i=0; i<n; i++) |
| if (mask[i]) |
| wmSetPixel(pwc, FLIP(y[i]), x[i], |
| rgba[i][RCOMP], rgba[i][GCOMP], rgba[i][BCOMP]); |
| DD_RELEASEDC; |
| } |
| |
| |
| //--------------------------------------------------------------------------- |
| |
| |
| /* |
| * Write an array of pixels with a boolean mask. The current color |
| * is used for all pixels. |
| */ |
| static void write_mono_rgba_pixels( const struct gl_context* ctx, |
| GLuint n, |
| const GLint x[], const GLint y[], |
| const GLchan color[4], |
| const GLubyte mask[] ) |
| { |
| GLD_context *gldCtx = GLD_GET_CONTEXT(ctx); |
| WMesaContext *Current = GLD_GET_WMESA_DRIVER(gldCtx); |
| GLuint i; |
| PWMC pwc = Current; |
| HDC DC=DD_GETDC; |
| assert(Current->rgb_flag==GL_TRUE); |
| for (i=0; i<n; i++) |
| if (mask[i]) |
| wmSetPixel(pwc, FLIP(y[i]),x[i],color[RCOMP], |
| color[GCOMP], color[BCOMP]); |
| DD_RELEASEDC; |
| } |
| |
| /**********************************************************************/ |
| /***** Read spans/arrays of pixels *****/ |
| /**********************************************************************/ |
| |
| /* Read a horizontal span of color-index pixels. */ |
| static void read_ci32_span( const struct gl_context* ctx, GLuint n, GLint x, GLint y, |
| GLuint index[]) |
| { |
| GLD_context *gldCtx = GLD_GET_CONTEXT(ctx); |
| WMesaContext *Current = GLD_GET_WMESA_DRIVER(gldCtx); |
| GLuint i; |
| BYTE *Mem=Current->ScreenMem+FLIP(y)*Current->ScanWidth+x; |
| assert(Current->rgb_flag==GL_FALSE); |
| for (i=0; i<n; i++) |
| index[i]=Mem[i]; |
| } |
| |
| //--------------------------------------------------------------------------- |
| |
| /* Read an array of color index pixels. */ |
| static void read_ci32_pixels( const struct gl_context* ctx, |
| GLuint n, const GLint x[], const GLint y[], |
| GLuint indx[], const GLubyte mask[] ) |
| { |
| GLD_context *gldCtx = GLD_GET_CONTEXT(ctx); |
| WMesaContext *Current = GLD_GET_WMESA_DRIVER(gldCtx); |
| GLuint i; |
| assert(Current->rgb_flag==GL_FALSE); |
| for (i=0; i<n; i++) { |
| if (mask[i]) { |
| indx[i]=*(Current->ScreenMem+FLIP(y[i])*Current->ScanWidth+x[i]); |
| } |
| } |
| } |
| |
| //--------------------------------------------------------------------------- |
| |
| /* Read a horizontal span of color pixels. */ |
| static void read_rgba_span( const struct gl_context* ctx, |
| GLuint n, GLint x, GLint y, |
| GLubyte rgba[][4] ) |
| { |
| GLD_context *gldCtx = GLD_GET_CONTEXT(ctx); |
| WMesaContext *Current = GLD_GET_WMESA_DRIVER(gldCtx); |
| UINT i; |
| COLORREF Color; |
| HDC DC=DD_GETDC; |
| assert(Current->rgb_flag==GL_TRUE); |
| y = Current->height - y - 1; |
| for (i=0; i<n; i++) { |
| Color=GetPixel(DC,x+i,y); |
| rgba[i][RCOMP] = GetRValue(Color); |
| rgba[i][GCOMP] = GetGValue(Color); |
| rgba[i][BCOMP] = GetBValue(Color); |
| rgba[i][ACOMP] = 255; |
| } |
| DD_RELEASEDC; |
| } |
| |
| //--------------------------------------------------------------------------- |
| |
| /* Read an array of color pixels. */ |
| static void read_rgba_pixels( const struct gl_context* ctx, |
| GLuint n, const GLint x[], const GLint y[], |
| GLubyte rgba[][4], const GLubyte mask[] ) |
| { |
| GLD_context *gldCtx = GLD_GET_CONTEXT(ctx); |
| WMesaContext *Current = GLD_GET_WMESA_DRIVER(gldCtx); |
| GLuint i; |
| COLORREF Color; |
| HDC DC=DD_GETDC; |
| assert(Current->rgb_flag==GL_TRUE); |
| for (i=0; i<n; i++) { |
| if (mask[i]) { |
| GLint y2 = Current->height - y[i] - 1; |
| Color=GetPixel(DC,x[i],y2); |
| rgba[i][RCOMP] = GetRValue(Color); |
| rgba[i][GCOMP] = GetGValue(Color); |
| rgba[i][BCOMP] = GetBValue(Color); |
| rgba[i][ACOMP] = 255; |
| } |
| } |
| DD_RELEASEDC; |
| } |
| |
| //--------------------------------------------------------------------------- |
| |
| static void wmesa_update_state( |
| struct gl_context *ctx, |
| GLuint new_state) |
| { |
| _swrast_InvalidateState( ctx, new_state ); |
| _swsetup_InvalidateState( ctx, new_state ); |
| _vbo_InvalidateState( ctx, new_state ); |
| _tnl_InvalidateState( ctx, new_state ); |
| } |
| |
| //--------------------------------------------------------------------------- |
| |
| static void wmesa_viewport( |
| struct gl_context *ctx, |
| GLint x, |
| GLint y, |
| GLsizei w, |
| GLsizei h) |
| { |
| // ctx->Driver.ResizeBuffersMESA(ctx); |
| } |
| |
| //--------------------------------------------------------------------------- |
| |
| static void wmesa_update_state_first_time( |
| struct gl_context *ctx, |
| GLuint new_state) |
| { |
| struct swrast_device_driver *swdd = _swrast_GetDeviceDriverReference( ctx ); |
| TNLcontext *tnl = TNL_CONTEXT(ctx); |
| |
| _mesa_init_driver_functions(&ctx->Driver); |
| |
| /* |
| * XXX these function pointers could be initialized just once during |
| * context creation since they don't depend on any state changes. |
| * kws - This is true - this function gets called a lot and it |
| * would be good to minimize setting all this when not needed. |
| */ |
| // Good idea, so I'll do it. KeithH. :-) |
| |
| ctx->Driver.GetString = _gldGetStringGeneric; |
| ctx->Driver.UpdateState = wmesa_update_state; |
| ctx->Driver.DrawBuffer = set_draw_buffer; |
| ctx->Driver.ResizeBuffers = _swrast_alloc_buffers; |
| ctx->Driver.GetBufferSize = buffer_size; |
| |
| ctx->Driver.Viewport = wmesa_viewport; |
| |
| ctx->Driver.Clear = clear; |
| |
| ctx->Driver.Flush = flush; |
| ctx->Driver.ClearColor = clear_color; |
| ctx->Driver.Enable = enable; |
| |
| |
| // Does not apply for Mesa 5.x |
| //ctx->Driver.BaseCompressedTexFormat = _mesa_base_compressed_texformat; |
| //ctx->Driver.CompressedTextureSize = _mesa_compressed_texture_size; |
| //ctx->Driver.GetCompressedTexImage = _mesa_get_compressed_teximage; |
| |
| swdd->SetBuffer = set_read_buffer; |
| |
| |
| /* Pixel/span writing functions: */ |
| swdd->WriteRGBASpan = write_rgba_span; |
| swdd->WriteRGBSpan = write_rgb_span; |
| swdd->WriteMonoRGBASpan = write_mono_rgba_span; |
| swdd->WriteRGBAPixels = write_rgba_pixels; |
| swdd->WriteMonoRGBAPixels = write_mono_rgba_pixels; |
| swdd->WriteCI32Span = write_ci32_span; |
| swdd->WriteCI8Span = write_ci8_span; |
| swdd->WriteMonoCISpan = write_mono_ci_span; |
| swdd->WriteCI32Pixels = write_ci32_pixels; |
| swdd->WriteMonoCIPixels = write_mono_ci_pixels; |
| |
| swdd->ReadCI32Span = read_ci32_span; |
| swdd->ReadRGBASpan = read_rgba_span; |
| swdd->ReadCI32Pixels = read_ci32_pixels; |
| swdd->ReadRGBAPixels = read_rgba_pixels; |
| |
| |
| tnl->Driver.RunPipeline = _tnl_run_pipeline; |
| |
| wmesa_update_state(ctx, new_state); |
| } |
| |
| //--------------------------------------------------------------------------- |
| // Driver interface functions |
| //--------------------------------------------------------------------------- |
| |
| BOOL gldCreateDrawable_MesaSW( |
| DGL_ctx *pCtx, |
| BOOL bPersistantInterface, |
| BOOL bPersistantBuffers) |
| { |
| WMesaContext *c; |
| GLboolean true_color_flag; |
| GLboolean rgb_flag = GL_TRUE; |
| GLboolean db_flag = GL_TRUE; |
| |
| if (pCtx == NULL) |
| return FALSE; |
| |
| c = (struct wmesa_context * ) calloc(1,sizeof(struct wmesa_context)); |
| if (!c) |
| return FALSE; |
| |
| pCtx->glPriv = c; |
| |
| c->hDC = pCtx->hDC; |
| c->Window = pCtx->hWnd; |
| |
| true_color_flag = GetDeviceCaps(pCtx->hDC, BITSPIXEL) > 8; |
| |
| |
| #ifdef DITHER |
| if ((true_color_flag==GL_FALSE) && (rgb_flag == GL_TRUE)){ |
| c->dither_flag = GL_TRUE; |
| c->hPalHalfTone = WinGCreateHalftonePalette(); |
| } |
| else |
| c->dither_flag = GL_FALSE; |
| #else |
| c->dither_flag = GL_FALSE; |
| #endif |
| |
| |
| if (rgb_flag==GL_FALSE) |
| { |
| c->rgb_flag = GL_FALSE; |
| #if 0 |
| /* Old WinG stuff???? */ |
| c->db_flag = db_flag =GL_TRUE; /* WinG requires double buffering */ |
| printf("Single buffer is not supported in color index mode, ", |
| "setting to double buffer.\n"); |
| #endif |
| } |
| else |
| { |
| c->rgb_flag = GL_TRUE; |
| } |
| |
| // db_flag = pCtx->lpPF->pfd.dwFlags & PFD_DOUBLEBUFFER ? GL_TRUE : GL_FALSE; |
| db_flag = GL_TRUE; // Force double-buffer |
| if (db_flag) { |
| c->db_flag = 1; |
| /* Double buffered */ |
| { |
| wmCreateBackingStore(c, pCtx->dwWidth, pCtx->dwHeight); |
| |
| } |
| } else { |
| /* Single Buffered */ |
| if (c->rgb_flag) |
| c->db_flag = 0; |
| } |
| |
| c->bEmulateSingleBuffer = (pCtx->lpPF->pfd.dwFlags & PFD_DOUBLEBUFFER) |
| ? FALSE : TRUE; |
| |
| return TRUE; |
| } |
| |
| //--------------------------------------------------------------------------- |
| |
| BOOL gldResizeDrawable_MesaSW( |
| DGL_ctx *ctx, |
| BOOL bDefaultDriver, |
| BOOL bPersistantInterface, |
| BOOL bPersistantBuffers) |
| { |
| WMesaContext *c; |
| |
| if (ctx == NULL) |
| return FALSE; |
| |
| c = ctx->glPriv; |
| if (c == NULL) |
| return FALSE; |
| |
| c->hDC = ctx->hDC; |
| c->Window = ctx->hWnd; |
| // c->width = ctx->dwWidth; |
| // c->height = ctx->dwHeight; |
| |
| if (c->db_flag) { |
| wmDeleteBackingStore(c); |
| wmCreateBackingStore(c, ctx->dwWidth, ctx->dwHeight); |
| } |
| |
| return TRUE; |
| } |
| |
| //--------------------------------------------------------------------------- |
| |
| BOOL gldDestroyDrawable_MesaSW( |
| DGL_ctx *ctx) |
| { |
| WMesaContext *c; |
| |
| if (ctx == NULL) |
| return FALSE; |
| |
| c = ctx->glPriv; |
| if (c == NULL) |
| return FALSE; |
| |
| if (c->hPalHalfTone != NULL) |
| DeleteObject(c->hPalHalfTone); |
| |
| if (c->db_flag) |
| wmDeleteBackingStore(c); |
| |
| free(c); |
| |
| ctx->glPriv = NULL; |
| |
| return TRUE; |
| } |
| |
| //--------------------------------------------------------------------------- |
| |
| BOOL gldCreatePrivateGlobals_MesaSW(void) |
| { |
| // Mesa Software driver needs no private globals |
| return TRUE; |
| } |
| |
| //--------------------------------------------------------------------------- |
| |
| BOOL gldDestroyPrivateGlobals_MesaSW(void) |
| { |
| // Mesa Software driver needs no private globals |
| return TRUE; |
| } |
| |
| //--------------------------------------------------------------------------- |
| |
| BOOL gldBuildPixelformatList_MesaSW(void) |
| { |
| // Release any existing pixelformat list |
| if (glb.lpPF) { |
| free(glb.lpPF); |
| } |
| |
| glb.nPixelFormatCount = 0; |
| glb.lpPF = NULL; |
| |
| glb.lpPF = (DGL_pixelFormat *)calloc(2, sizeof(DGL_pixelFormat)); |
| if (glb.lpPF == NULL) |
| return FALSE; |
| // Single-buffered |
| memcpy(&glb.lpPF[0], &pfTemplateMesaSW, sizeof(DGL_pixelFormat)); |
| glb.lpPF[0].pfd.dwFlags &= ~PFD_DOUBLEBUFFER; // Remove doublebuffer flag |
| // Double-buffered |
| memcpy(&glb.lpPF[1], &pfTemplateMesaSW, sizeof(DGL_pixelFormat)); |
| glb.nPixelFormatCount = 2; |
| |
| // Mark list as 'current' |
| glb.bPixelformatsDirty = FALSE; |
| |
| return TRUE; |
| } |
| |
| //--------------------------------------------------------------------------- |
| |
| BOOL gldInitialiseMesa_MesaSW( |
| DGL_ctx *gld) |
| { |
| struct gl_context *ctx; |
| |
| if (gld == NULL) |
| return FALSE; |
| |
| ctx = gld->glCtx; |
| |
| // Set max texture size to 256 |
| ctx->Const.MaxTextureLevels = 8; |
| |
| // Multitexture enable/disable |
| ctx->Const.MaxTextureUnits = (glb.bMultitexture) ? MAX_TEXTURE_UNITS : 1; |
| |
| /* Initialize the software rasterizer and helper modules.*/ |
| |
| // Added this to force max texture diminsion to 256. KeithH |
| ctx->Const.MaxTextureLevels = 8; |
| ctx->Const.MaxDrawBuffers = 1; |
| |
| _mesa_enable_sw_extensions(ctx); |
| _mesa_enable_imaging_extensions(ctx); |
| _mesa_enable_1_3_extensions(ctx); |
| |
| // _swrast_CreateContext( ctx ); |
| // _vbo_CreateContext( ctx ); |
| // _tnl_CreateContext( ctx ); |
| // _swsetup_CreateContext( ctx ); |
| |
| _swsetup_Wakeup( ctx ); |
| |
| wmesa_update_state_first_time(ctx, ~0); |
| |
| return TRUE; |
| } |
| |
| //--------------------------------------------------------------------------- |
| |
| BOOL gldSwapBuffers_MesaSW( |
| DGL_ctx *ctx, |
| HDC hDC, |
| HWND hWnd) |
| { |
| WMesaContext *c; |
| |
| if (ctx == NULL) |
| return FALSE; |
| |
| c = ctx->glPriv; |
| if (c == NULL) |
| return FALSE; |
| |
| /* If we're swapping the buffer associated with the current context |
| * we have to flush any pending rendering commands first. |
| */ |
| |
| // Altered to respect bEmulateSingleBuffer. KeithH |
| // if (c->db_flag) |
| if (!c->bEmulateSingleBuffer) |
| wmFlush(c, hDC); |
| |
| return TRUE; |
| } |
| |
| //--------------------------------------------------------------------------- |
| |
| PROC gldGetProcAddress_MesaSW( |
| LPCSTR a) |
| { |
| int i; |
| PROC proc = NULL; |
| |
| for (i=0; GLD_extList[i].proc; i++) { |
| if (!strcmp(a, GLD_extList[i].name)) { |
| proc = GLD_extList[i].proc; |
| break; |
| } |
| } |
| |
| gldLogPrintf(GLDLOG_INFO, "GetProcAddress: %s (%s)", a, proc ? "OK" : "Failed"); |
| |
| return proc; |
| } |
| |
| //--------------------------------------------------------------------------- |
| |
| BOOL gldGetDisplayMode_MesaSW( |
| DGL_ctx *ctx, |
| GLD_displayMode *glddm) |
| { |
| HDC hdcDesktop; |
| |
| if (glddm == NULL) |
| return FALSE; |
| |
| // |
| // A bit hacky... KeithH |
| // |
| |
| hdcDesktop = GetDC(NULL); |
| glddm->Width = GetDeviceCaps(hdcDesktop, HORZRES); |
| glddm->Height = GetDeviceCaps(hdcDesktop, VERTRES); |
| glddm->BPP = GetDeviceCaps(hdcDesktop, BITSPIXEL); |
| glddm->Refresh = 0; |
| ReleaseDC(0, hdcDesktop); |
| |
| return TRUE; |
| } |
| |
| //--------------------------------------------------------------------------- |
| |