| /* $Id: wmesa.c,v 1.43 2003/01/30 15:47:06 kschultz Exp $ */ |
| |
| /* |
| * Windows (Win32) device driver for Mesa 3.4 |
| * |
| * Original author: |
| * |
| * Copyright (C) 1996- Li Wei |
| * Address : Institute of Artificial Intelligence |
| * : & Robotics |
| * : Xi'an Jiaotong University |
| * Email : liwei@aiar.xjtu.edu.cn |
| * Web page : http://sun.aiar.xjtu.edu.cn |
| * |
| * This file and its associations are partially borrowed from the |
| * Windows NT driver for Mesa 1.8 , written by Mark Leaming |
| * (mark@rsinc.com). |
| * |
| * Updated for Mesa 4.0 by Karl Schultz (kschultz@sourceforge.net) |
| */ |
| |
| #ifdef NDEBUG |
| #pragma auto_inline(on) |
| #pragma inline_depth(255) |
| #pragma inline_recursion(on) |
| #endif |
| |
| #include "wmesadef.h" |
| #include <GL/wmesa.h> |
| #include "mesa_extend.h" |
| |
| #include "glheader.h" |
| #include "colors.h" |
| #include "context.h" |
| #include "colormac.h" |
| #include "dd.h" |
| #include "depth.h" |
| #include "extensions.h" |
| #include "imports.h" |
| #include "macros.h" |
| #include "matrix.h" |
| #include "mmath.h" |
| #include "mtypes.h" |
| #include "texformat.h" |
| #include "texstore.h" |
| #include "array_cache/acache.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 "swrast/s_trispan.h" |
| #include "tnl/tnl.h" |
| #include "tnl/t_context.h" |
| #include "tnl/t_pipeline.h" |
| |
| /* Dither not tested for Mesa 4.0 */ |
| #ifdef DITHER |
| #ifdef USE_WING |
| #include <wing.h> |
| #endif // USE_WING |
| #endif |
| |
| #ifdef __CYGWIN32__ |
| #include "macros.h" |
| #include <string.h> |
| #define CopyMemory memcpy |
| #endif |
| |
| /* Stereo and parallel not tested for Mesa 4.0. */ |
| #if !defined(NO_STEREO) |
| #include "gl\glu.h" |
| #include "stereo.h" |
| #endif |
| |
| #if !defined(NO_PARALLEL) |
| #include "parallel.h" |
| #endif |
| |
| |
| /* File global varaibles */ |
| struct DISPLAY_OPTIONS displayOptions = |
| { |
| 0, // stereo |
| 0, // fullScreen |
| 0, // full screen mode (1,2,3,4) |
| 0 // bpp (8,16,24,32) |
| }; |
| GLenum stereoCompile = GL_FALSE ; |
| GLenum stereoShowing = GL_FALSE ; |
| GLenum stereoBuffer = GL_FALSE; |
| #if !defined(NO_STEREO) |
| GLint displayList = MAXIMUM_DISPLAY_LIST ; |
| #endif |
| GLint stereo_flag = 0 ; |
| |
| static PWMC Current = NULL; |
| WMesaContext WC = NULL; |
| |
| #ifdef COMPILE_SETPIXEL |
| |
| #if defined(_MSC_VER) && _MSC_VER >= 1200 |
| #define FORCEINLINE __forceinline |
| #else |
| #define FORCEINLINE __inline |
| #endif |
| |
| FORCEINLINE void wmSetPixel(PWMC pwc, int iScanLine, int iPixel, BYTE r, BYTE g, BYTE b) |
| { |
| pwc->wmSetPixel(pwc,iScanLine,iPixel,r,g,b); |
| } |
| |
| void ChooseSetPixel(PWMC pwc); |
| |
| #endif // COMPILE_SETPIXEL |
| |
| /* 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) |
| |
| #define DITHER_RGB_TO_8BIT_SETUP \ |
| GLubyte pixelDithered; |
| |
| #define DITHER_RGB_TO_8BIT(red, green, blue, pixel, scanline) \ |
| { \ |
| char unsigned redtemp, greentemp, bluetemp, paletteindex; \ |
| 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]); \ |
| paletteindex = redtemp + aTimes6[greentemp] + aTimes36[bluetemp];\ |
| pixelDithered = aWinGHalftoneTranslation[paletteindex]; \ |
| } |
| |
| #ifdef DDRAW |
| static BOOL DDInit( WMesaContext wc, HWND hwnd); |
| static void DDFree( WMesaContext wc); |
| static HRESULT DDRestoreAll( WMesaContext wc ); |
| static void DDDeleteOffScreen(WMesaContext wc); |
| static BOOL DDCreateOffScreen(WMesaContext wc); |
| |
| // define this to use the GDI Rectangle call to |
| // clear the back buffer. Otherwise will manually |
| // set the pixels. On an NVidia GEForce 2MX under Windows XP |
| // and DirectX 8 , defining this makes apps run much much faster |
| #define USE_GDI_TO_CLEAR 1 |
| #endif |
| |
| static void FlushToFile(PWMC pwc, PSTR szFile); |
| BOOL wmCreateBackingStore(PWMC pwc, long lxSize, long lySize); |
| BOOL wmDeleteBackingStore(PWMC pwc); |
| void wmCreatePalette( PWMC pwdc ); |
| BOOL wmSetDibColors(PWMC pwc); |
| void wmSetPixel(PWMC pwc, int iScanLine, int iPixel, BYTE r, BYTE g, BYTE b); |
| BOOL wmFlush(PWMC pwc); |
| 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 |
| ); |
| void WMesaViewport( GLcontext *ctx, |
| GLint x, GLint y, GLsizei width, GLsizei height ); |
| |
| |
| 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 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; |
| } |
| |
| |
| /* |
| * 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); |
| #ifdef USE_MAPPED_FILE |
| UnmapViewOfFile(pwc->dib.base); |
| CloseHandle(pwc->dib.hFileMap); |
| #endif |
| return TRUE; |
| } |
| |
| |
| /* |
| * 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; |
| |
| wmCreateDIBSection(hdc, pwc, pbmi, iUsage); |
| |
| if ((iUsage == DIB_PAL_COLORS) && !(pwc->hGLPalette)) { |
| wmCreatePalette( pwc ); |
| wmSetDibColors( pwc ); |
| } |
| wmSetPixelFormat(pwc, pwc->hDC); |
| return TRUE; |
| } |
| |
| #if 0 |
| // D.R.S. 10/30/01 - this function is never referenced |
| /* |
| * This function copies one scan line in a DIB section to another |
| */ |
| BOOL wmSetDIBits(PWMC pwc, UINT uiScanWidth, UINT uiNumScans, |
| UINT nBypp, UINT uiNewWidth, LPBYTE pBits) |
| { |
| UINT uiScans = 0; |
| LPBYTE pDest = pwc->pbPixels; |
| DWORD dwNextScan = uiScanWidth; |
| DWORD dwNewScan = uiNewWidth; |
| DWORD dwScanWidth = (uiScanWidth * nBypp); |
| |
| /* |
| * We need to round up to the nearest DWORD |
| * and multiply by the number of bytes per |
| * pixel |
| */ |
| dwNextScan = (((dwNextScan * nBypp)+ 3) & ~3); |
| dwNewScan = (((dwNewScan * nBypp)+ 3) & ~3); |
| |
| for(uiScans = 0; uiScans < uiNumScans; uiScans++){ |
| CopyMemory(pDest, pBits, dwScanWidth); |
| pBits += dwNextScan; |
| pDest += dwNewScan; |
| } |
| return TRUE; |
| } |
| #endif // 0 |
| |
| #if defined(FAST_RASTERIZERS) |
| |
| #define PIXELADDR(X,Y) \ |
| ((GLubyte *)Current->pbPixels + (Current->height-Y-1)* \ |
| Current->ScanWidth + (X)*nBypp) |
| #define PIXELADDR1( X, Y ) \ |
| ((GLubyte *)wmesa->pbPixels + (wmesa->height-Y-1)* wmesa->ScanWidth + (X)) |
| #define PIXELADDR2( X, Y ) \ |
| ((GLubyte *)wmesa->pbPixels + (wmesa->height-Y-1)* wmesa->ScanWidth + (X)*2) |
| #define PIXELADDR4( X, Y ) \ |
| ((GLubyte *)wmesa->pbPixels + (wmesa->height-Y-1)* wmesa->ScanWidth + (X)*4) |
| |
| #endif // 0 |
| |
| BYTE DITHER_RGB_2_8BIT( int r, int g, int b, int x, int y); |
| |
| /* Finish all pending operations and synchronize. */ |
| static void finish(GLcontext* ctx) |
| { |
| /* No op */ |
| } |
| |
| |
| static void flush(GLcontext* ctx) |
| { |
| if((Current->rgb_flag &&!(Current->db_flag)) |
| ||(!Current->rgb_flag)) |
| { |
| wmFlush(Current); |
| } |
| |
| } |
| |
| |
| |
| /* |
| * Set the color index used to clear the color buffer. |
| */ |
| static void clear_index(GLcontext* ctx, GLuint index) |
| { |
| Current->clearpixel = index; |
| } |
| |
| |
| |
| /* |
| * Set the color used to clear the color buffer. |
| */ |
| static void clear_color( GLcontext* ctx, const GLfloat color[4] ) |
| { |
| 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(GLcontext* ctx, GLbitfield mask, |
| GLboolean all, GLint x, GLint y, GLint width, GLint height) |
| { |
| 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_LEFT_BIT)) && |
| ctx->DrawBuffer->UseSoftwareAlphaBuffers && |
| ctx->Color.ColorMask[ACOMP]) { |
| _mesa_clear_alpha_buffers( ctx ); |
| } |
| |
| if (*colorMask == 0xffffffff && ctx->Color.IndexMask == 0xffffffff) { |
| if (mask & DD_BACK_LEFT_BIT) { |
| #if defined(USE_GDI_TO_CLEAR) |
| #if defined(DDRAW) |
| // D.R.S. 10/29/01 on my system (Pentium 4 with nvidia GeForce2 MX card, |
| // this is almose 100 times faster that the code below |
| HDC DC=NULL; |
| HPEN Pen=CreatePen(PS_SOLID,1,Current->clearpixel); |
| HBRUSH Brush=CreateSolidBrush(Current->clearpixel); |
| HPEN Old_Pen=NULL; |
| HBRUSH Old_Brush=NULL; |
| Current->lpDDSOffScreen->lpVtbl->Unlock(Current->lpDDSOffScreen,NULL); |
| Current->lpDDSOffScreen->lpVtbl->GetDC(Current->lpDDSOffScreen,&DC); |
| Old_Pen=SelectObject(DC,Pen); |
| 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); |
| Current->lpDDSOffScreen->lpVtbl->ReleaseDC(Current->lpDDSOffScreen,DC); |
| while (Current->lpDDSOffScreen->lpVtbl->Lock(Current->lpDDSOffScreen,NULL, &(Current->ddsd), 0, NULL) == DDERR_WASSTILLDRAWING); |
| |
| mask &= ~DD_BACK_LEFT_BIT; |
| #else |
| /* 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+Current->rectSurface.left,Current->rectSurface.top+y,x+width+Current->rectSurface.left,y+height+Current->rectSurface.top); |
| |
| SelectObject(DC,Old_Pen); |
| SelectObject(DC,Old_Brush); |
| DeleteObject(Pen); |
| DeleteObject(Brush); |
| DD_RELEASEDC; |
| mask &= ~DD_BACK_LEFT_BIT; |
| #endif // DDRAW |
| #else |
| DWORD dwColor; |
| WORD wColor; |
| BYTE bColor; |
| LPDWORD lpdw = (LPDWORD)Current->pbPixels; |
| LPWORD lpw = (LPWORD)Current->pbPixels; |
| LPBYTE lpb = Current->pbPixels; |
| int lines; |
| /* Double-buffering - clear back buffer */ |
| UINT nBypp = Current->cColorBits / 8; |
| int i = 0; |
| int iSize = 0; |
| int mult = 4; |
| |
| |
| 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); |
| } |
| else 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 == 3){ |
| BYTE r, g, b; |
| r = GetRValue(Current->clearpixel); |
| g = GetGValue(Current->clearpixel); |
| b = GetBValue(Current->clearpixel); |
| iSize = Current->width; |
| while (i < iSize) { |
| *lpb++ = b; |
| *lpb++ = g; |
| *lpb++ = r; |
| i++; |
| } |
| lpb = Current->pbPixels + Current->ScanWidth; |
| mult = 3; |
| } |
| else if(nBypp == 4){ |
| iSize = Current->width; |
| dwColor = BGR32(GetRValue(Current->clearpixel), |
| GetGValue(Current->clearpixel), |
| GetBValue(Current->clearpixel)); |
| } |
| |
| if (nBypp != 3) |
| { |
| /* clear a line */ |
| while(i < iSize){ |
| *lpdw = dwColor; |
| lpdw++; |
| 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*mult); |
| lpb += Current->ScanWidth; |
| i++; |
| } |
| while (i<lines-1); |
| mask &= ~DD_BACK_LEFT_BIT; |
| #endif // defined(USE_GDI_TO_CLEAR) |
| } /* 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+Current->rectSurface.left,Current->rectSurface.top+y,x+width+Current->rectSurface.left,y+height+Current->rectSurface.top); |
| |
| 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( GLcontext* ctx, GLenum pname, GLboolean enable ) |
| { |
| 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 void set_buffer(GLcontext *ctx, GLframebuffer *colorBuffer, |
| GLuint bufferBit ) |
| { |
| /* XXX todo - examine bufferBit and set read/write pointers */ |
| return; |
| } |
| |
| |
| |
| /* Return characteristics of the output buffer. */ |
| static void buffer_size( GLframebuffer *buffer, GLuint *width, GLuint *height ) |
| { |
| GET_CURRENT_CONTEXT(ctx); |
| 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){ |
| #ifdef DDRAW |
| DDDeleteOffScreen(Current); |
| DDCreateOffScreen(Current); |
| #else |
| if (Current->rgb_flag==GL_TRUE && Current->dither_flag!=GL_TRUE){ |
| wmDeleteBackingStore(Current); |
| wmCreateBackingStore(Current, Current->width, Current->height); |
| } |
| #endif |
| } |
| |
| /* Resize OsmesaBuffer if in Parallel mode */ |
| #if !defined(NO_PARALLEL) |
| if(parallelFlag) |
| PRSizeRenderBuffer(Current->width, Current->height,Current->ScanWidth, |
| Current->rgb_flag == GL_TRUE ? Current->pbPixels: |
| Current->ScreenMem); |
| #endif |
| } |
| } |
| |
| |
| |
| /**********************************************************************/ |
| /***** Accelerated point, line, polygon rendering *****/ |
| /**********************************************************************/ |
| |
| /* Accelerated routines are not implemented in 4.0. See OSMesa for ideas. */ |
| |
| static void fast_rgb_points( GLcontext* ctx, GLuint first, GLuint last ) |
| { |
| } |
| |
| /* Return pointer to accelerated points function */ |
| extern points_func choose_points_function( GLcontext* ctx ) |
| { |
| return NULL; |
| } |
| |
| static void fast_flat_rgb_line( GLcontext* ctx, GLuint v0, |
| GLuint v1, GLuint pv ) |
| { |
| } |
| |
| static line_func choose_line_function( GLcontext* 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 GLcontext* ctx, |
| GLuint n, GLint x, GLint y, |
| const GLuint index[], |
| const GLubyte mask[] ) |
| { |
| 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 GLcontext* ctx, |
| GLuint n, GLint x, GLint y, |
| const GLubyte index[], |
| const GLubyte mask[] ) |
| { |
| 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 GLcontext* ctx, |
| GLuint n,GLint x,GLint y, |
| GLuint colorIndex, const GLubyte mask[]) |
| { |
| 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 GLcontext* ctx, GLuint n, GLint x, GLint y, |
| const GLubyte rgba[][4], const GLubyte mask[] ) |
| { |
| 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 GLcontext* ctx, |
| GLuint n, GLint x, GLint y, |
| const GLubyte rgb[][3], const GLubyte mask[] ) |
| { |
| 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 GLcontext* ctx, |
| GLuint n, GLint x, GLint y, |
| const GLchan color[4], const GLubyte mask[]) |
| { |
| GLuint i; |
| 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 |
| { |
| HDC DC=DD_GETDC; |
| ULONG pixel = RGB( color[RCOMP], color[GCOMP], color[BCOMP] ); |
| 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 GLcontext* ctx, |
| GLuint n, const GLint x[], const GLint y[], |
| const GLuint index[], const GLubyte mask[] ) |
| { |
| 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 GLcontext* ctx, |
| GLuint n, |
| const GLint x[], const GLint y[], |
| GLuint colorIndex, const GLubyte mask[] ) |
| { |
| 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 GLcontext* ctx, |
| GLuint n, const GLint x[], const GLint y[], |
| const GLubyte rgba[][4], const GLubyte mask[] ) |
| { |
| 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 GLcontext* ctx, |
| GLuint n, |
| const GLint x[], const GLint y[], |
| const GLchan color[4], |
| const GLubyte mask[] ) |
| { |
| 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 GLcontext* ctx, GLuint n, GLint x, GLint y, |
| GLuint index[]) |
| { |
| 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 GLcontext* ctx, |
| GLuint n, const GLint x[], const GLint y[], |
| GLuint indx[], const GLubyte mask[] ) |
| { |
| 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 GLcontext* ctx, |
| GLuint n, GLint x, GLint y, |
| GLubyte rgba[][4] ) |
| { |
| 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 GLcontext* ctx, |
| GLuint n, const GLint x[], const GLint y[], |
| GLubyte rgba[][4], const GLubyte mask[] ) |
| { |
| 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 const GLubyte *get_string(GLcontext *ctx, GLenum name) |
| { |
| if (name == GL_RENDERER) { |
| return (GLubyte *) "Mesa Windows"; |
| } |
| else { |
| return NULL; |
| } |
| } |
| |
| static void wmesa_update_state( GLcontext *ctx, GLuint new_state ); |
| |
| static void SetFunctionPointers(GLcontext *ctx) |
| { |
| struct swrast_device_driver *swdd = _swrast_GetDeviceDriverReference( ctx ); |
| ctx->Driver.GetString = get_string; |
| ctx->Driver.UpdateState = wmesa_update_state; |
| ctx->Driver.ResizeBuffers = _swrast_alloc_buffers; |
| ctx->Driver.GetBufferSize = buffer_size; |
| |
| ctx->Driver.Accum = _swrast_Accum; |
| ctx->Driver.Bitmap = _swrast_Bitmap; |
| ctx->Driver.Clear = clear; |
| |
| ctx->Driver.Flush = flush; |
| ctx->Driver.ClearIndex = clear_index; |
| ctx->Driver.ClearColor = clear_color; |
| ctx->Driver.Enable = enable; |
| |
| ctx->Driver.CopyPixels = _swrast_CopyPixels; |
| ctx->Driver.DrawPixels = _swrast_DrawPixels; |
| ctx->Driver.ReadPixels = _swrast_ReadPixels; |
| ctx->Driver.DrawBuffer = _swrast_DrawBuffer; |
| |
| ctx->Driver.ChooseTextureFormat = _mesa_choose_tex_format; |
| ctx->Driver.TexImage1D = _mesa_store_teximage1d; |
| ctx->Driver.TexImage2D = _mesa_store_teximage2d; |
| ctx->Driver.TexImage3D = _mesa_store_teximage3d; |
| ctx->Driver.TexSubImage1D = _mesa_store_texsubimage1d; |
| ctx->Driver.TexSubImage2D = _mesa_store_texsubimage2d; |
| ctx->Driver.TexSubImage3D = _mesa_store_texsubimage3d; |
| ctx->Driver.TestProxyTexImage = _mesa_test_proxy_teximage; |
| |
| ctx->Driver.CompressedTexImage1D = _mesa_store_compressed_teximage1d; |
| ctx->Driver.CompressedTexImage2D = _mesa_store_compressed_teximage2d; |
| ctx->Driver.CompressedTexImage3D = _mesa_store_compressed_teximage3d; |
| ctx->Driver.CompressedTexSubImage1D = _mesa_store_compressed_texsubimage1d; |
| ctx->Driver.CompressedTexSubImage2D = _mesa_store_compressed_texsubimage2d; |
| ctx->Driver.CompressedTexSubImage3D = _mesa_store_compressed_texsubimage3d; |
| |
| ctx->Driver.CopyTexImage1D = _swrast_copy_teximage1d; |
| ctx->Driver.CopyTexImage2D = _swrast_copy_teximage2d; |
| ctx->Driver.CopyTexSubImage1D = _swrast_copy_texsubimage1d; |
| ctx->Driver.CopyTexSubImage2D = _swrast_copy_texsubimage2d; |
| ctx->Driver.CopyTexSubImage3D = _swrast_copy_texsubimage3d; |
| ctx->Driver.CopyColorTable = _swrast_CopyColorTable; |
| ctx->Driver.CopyColorSubTable = _swrast_CopyColorSubTable; |
| ctx->Driver.CopyConvolutionFilter1D = _swrast_CopyConvolutionFilter1D; |
| ctx->Driver.CopyConvolutionFilter2D = _swrast_CopyConvolutionFilter2D; |
| |
| swdd->SetBuffer = set_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; |
| |
| } |
| |
| static void wmesa_update_state( GLcontext *ctx, GLuint new_state ) |
| { |
| struct swrast_device_driver *swdd = _swrast_GetDeviceDriverReference( ctx ); |
| TNLcontext *tnl = TNL_CONTEXT(ctx); |
| |
| /* |
| * 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. |
| */ |
| #ifndef SET_FPOINTERS_ONCE |
| SetFunctionPointers(ctx); |
| #if 0 |
| ctx->Driver.GetString = get_string; |
| ctx->Driver.UpdateState = wmesa_update_state; |
| ctx->Driver.ResizeBuffers = _swrast_alloc_buffers; |
| ctx->Driver.GetBufferSize = buffer_size; |
| |
| ctx->Driver.Accum = _swrast_Accum; |
| ctx->Driver.Bitmap = _swrast_Bitmap; |
| ctx->Driver.Clear = clear; |
| |
| ctx->Driver.Flush = flush; |
| ctx->Driver.ClearIndex = clear_index; |
| ctx->Driver.ClearColor = clear_color; |
| ctx->Driver.Enable = enable; |
| |
| ctx->Driver.CopyPixels = _swrast_CopyPixels; |
| ctx->Driver.DrawPixels = _swrast_DrawPixels; |
| ctx->Driver.ReadPixels = _swrast_ReadPixels; |
| |
| ctx->Driver.ChooseTextureFormat = _mesa_choose_tex_format; |
| ctx->Driver.TexImage1D = _mesa_store_teximage1d; |
| ctx->Driver.TexImage2D = _mesa_store_teximage2d; |
| ctx->Driver.TexImage3D = _mesa_store_teximage3d; |
| ctx->Driver.TexSubImage1D = _mesa_store_texsubimage1d; |
| ctx->Driver.TexSubImage2D = _mesa_store_texsubimage2d; |
| ctx->Driver.TexSubImage3D = _mesa_store_texsubimage3d; |
| ctx->Driver.TestProxyTexImage = _mesa_test_proxy_teximage; |
| |
| ctx->Driver.CompressedTexImage1D = _mesa_store_compressed_teximage1d; |
| ctx->Driver.CompressedTexImage2D = _mesa_store_compressed_teximage2d; |
| ctx->Driver.CompressedTexImage3D = _mesa_store_compressed_teximage3d; |
| ctx->Driver.CompressedTexSubImage1D = _mesa_store_compressed_texsubimage1d; |
| ctx->Driver.CompressedTexSubImage2D = _mesa_store_compressed_texsubimage2d; |
| ctx->Driver.CompressedTexSubImage3D = _mesa_store_compressed_texsubimage3d; |
| |
| ctx->Driver.CopyTexImage1D = _swrast_copy_teximage1d; |
| ctx->Driver.CopyTexImage2D = _swrast_copy_teximage2d; |
| ctx->Driver.CopyTexSubImage1D = _swrast_copy_texsubimage1d; |
| ctx->Driver.CopyTexSubImage2D = _swrast_copy_texsubimage2d; |
| ctx->Driver.CopyTexSubImage3D = _swrast_copy_texsubimage3d; |
| ctx->Driver.CopyColorTable = _swrast_CopyColorTable; |
| ctx->Driver.CopyColorSubTable = _swrast_CopyColorSubTable; |
| ctx->Driver.CopyConvolutionFilter1D = _swrast_CopyConvolutionFilter1D; |
| ctx->Driver.CopyConvolutionFilter2D = _swrast_CopyConvolutionFilter2D; |
| |
| swdd->SetBuffer = set_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; |
| #endif // 0 |
| #endif // !SET_FPOINTERS_ONCE |
| tnl->Driver.RunPipeline = _tnl_run_pipeline; |
| |
| _swrast_InvalidateState( ctx, new_state ); |
| _swsetup_InvalidateState( ctx, new_state ); |
| _ac_InvalidateState( ctx, new_state ); |
| _tnl_InvalidateState( ctx, new_state ); |
| } |
| |
| |
| |
| |
| /**********************************************************************/ |
| /***** WMesa API Functions *****/ |
| /**********************************************************************/ |
| |
| |
| |
| #define PAL_SIZE 256 |
| static void GetPalette(HPALETTE Pal,RGBQUAD *aRGB) |
| { |
| int i; |
| HDC hdc; |
| struct |
| { |
| WORD Version; |
| WORD NumberOfEntries; |
| PALETTEENTRY aEntries[PAL_SIZE]; |
| } Palette = |
| { |
| 0x300, |
| PAL_SIZE |
| }; |
| hdc=GetDC(NULL); |
| if (Pal!=NULL) |
| GetPaletteEntries(Pal,0,PAL_SIZE,Palette.aEntries); |
| else |
| GetSystemPaletteEntries(hdc,0,PAL_SIZE,Palette.aEntries); |
| if (GetSystemPaletteUse(hdc) == SYSPAL_NOSTATIC) |
| { |
| for(i = 0; i <PAL_SIZE; i++) |
| Palette.aEntries[i].peFlags = PC_RESERVED; |
| Palette.aEntries[255].peRed = 255; |
| Palette.aEntries[255].peGreen = 255; |
| Palette.aEntries[255].peBlue = 255; |
| Palette.aEntries[255].peFlags = 0; |
| Palette.aEntries[0].peRed = 0; |
| Palette.aEntries[0].peGreen = 0; |
| Palette.aEntries[0].peBlue = 0; |
| Palette.aEntries[0].peFlags = 0; |
| } |
| else |
| { |
| int nStaticColors; |
| int nUsableColors; |
| nStaticColors = GetDeviceCaps(hdc, NUMCOLORS)/2; |
| for (i=0; i<nStaticColors; i++) |
| Palette.aEntries[i].peFlags = 0; |
| nUsableColors = PAL_SIZE-nStaticColors; |
| for (; i<nUsableColors; i++) |
| Palette.aEntries[i].peFlags = PC_RESERVED; |
| for (; i<PAL_SIZE-nStaticColors; i++) |
| Palette.aEntries[i].peFlags = PC_RESERVED; |
| for (i=PAL_SIZE-nStaticColors; i<PAL_SIZE; i++) |
| Palette.aEntries[i].peFlags = 0; |
| } |
| ReleaseDC(NULL,hdc); |
| for (i=0; i<PAL_SIZE; i++) |
| { |
| aRGB[i].rgbRed=Palette.aEntries[i].peRed; |
| aRGB[i].rgbGreen=Palette.aEntries[i].peGreen; |
| aRGB[i].rgbBlue=Palette.aEntries[i].peBlue; |
| aRGB[i].rgbReserved=Palette.aEntries[i].peFlags; |
| } |
| } |
| |
| |
| WMesaContext WMesaCreateContext( HWND hWnd, HPALETTE* Pal, |
| GLboolean rgb_flag, |
| GLboolean db_flag, |
| GLboolean alpha_flag ) |
| { |
| RECT CR; |
| WMesaContext c; |
| GLboolean true_color_flag; |
| |
| c = (struct wmesa_context * ) calloc(1,sizeof(struct wmesa_context)); |
| if (!c) |
| return NULL; |
| |
| c->Window=hWnd; |
| c->hDC = GetDC(hWnd); |
| true_color_flag = GetDeviceCaps(c->hDC, BITSPIXEL) > 8; |
| #ifdef DDRAW |
| if(true_color_flag) c->rgb_flag = rgb_flag = GL_TRUE; |
| #endif |
| |
| |
| #ifdef DITHER |
| if ((true_color_flag==GL_FALSE) && (rgb_flag == GL_TRUE)){ |
| c->dither_flag = GL_TRUE; |
| #ifdef USE_WING |
| c->hPalHalfTone = WinGCreateHalftonePalette(); |
| #else |
| c->hPalHalfTone = CreateHalftonePalette(c->hDC); |
| #endif |
| } |
| 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; |
| } |
| GetClientRect(c->Window,&CR); |
| c->width=CR.right; |
| c->height=CR.bottom; |
| if (db_flag) |
| { |
| c->db_flag = 1; |
| /* Double buffered */ |
| #ifndef DDRAW |
| { |
| wmCreateBackingStore(c, c->width, c->height); |
| |
| } |
| #endif |
| } |
| else |
| { |
| /* Single Buffered */ |
| if (c->rgb_flag) |
| c->db_flag = 0; |
| } |
| #ifdef DDRAW |
| if (DDInit(c,hWnd) == GL_FALSE) { |
| free( (void *) c ); |
| exit(1); |
| } |
| #endif |
| |
| |
| c->gl_visual = _mesa_create_visual(rgb_flag, |
| db_flag, /* db_flag */ |
| GL_FALSE, /* stereo */ |
| 8,8,8, /* r, g, b bits */ |
| alpha_flag ? 8 : 0, /* alpha bits */ |
| 0, /* index bits */ |
| 16, /* depth_bits */ |
| 8, /* stencil_bits */ |
| 16,16,16,/* accum_bits */ |
| alpha_flag ? 16 : 0, /* alpha accum */ |
| 1); |
| |
| if (!c->gl_visual) { |
| return NULL; |
| } |
| |
| /* allocate a new Mesa context */ |
| c->gl_ctx = _mesa_create_context( c->gl_visual, NULL, (void *) c, GL_FALSE ); |
| |
| if (!c->gl_ctx) { |
| _mesa_destroy_visual( c->gl_visual ); |
| free(c); |
| return NULL; |
| } |
| |
| _mesa_enable_sw_extensions(c->gl_ctx); |
| _mesa_enable_1_3_extensions(c->gl_ctx); |
| _mesa_enable_1_4_extensions(c->gl_ctx); |
| |
| c->gl_buffer = _mesa_create_framebuffer( c->gl_visual, |
| c->gl_visual->depthBits > 0, |
| c->gl_visual->stencilBits > 0, |
| c->gl_visual->accumRedBits > 0, |
| alpha_flag /* s/w alpha */ ); |
| if (!c->gl_buffer) { |
| _mesa_destroy_visual( c->gl_visual ); |
| _mesa_free_context_data( c->gl_ctx ); |
| free(c); |
| return NULL; |
| } |
| |
| /* Initialize the software rasterizer and helper modules. |
| */ |
| { |
| GLcontext *ctx = c->gl_ctx; |
| _swrast_CreateContext( ctx ); |
| _ac_CreateContext( ctx ); |
| _tnl_CreateContext( ctx ); |
| _swsetup_CreateContext( ctx ); |
| |
| #ifdef SET_FPOINTERS_ONCE |
| SetFunctionPointers(ctx); |
| #endif // SET_FPOINTERS_ONCE |
| _swsetup_Wakeup( ctx ); |
| } |
| #ifdef COMPILE_SETPIXEL |
| ChooseSetPixel(c); |
| #endif |
| return c; |
| } |
| |
| void WMesaDestroyContext( void ) |
| { |
| WMesaContext c = Current; |
| ReleaseDC(c->Window,c->hDC); |
| WC = c; |
| if(c->hPalHalfTone != NULL) |
| DeleteObject(c->hPalHalfTone); |
| |
| _swsetup_DestroyContext( c->gl_ctx ); |
| _tnl_DestroyContext( c->gl_ctx ); |
| _ac_DestroyContext( c->gl_ctx ); |
| _swrast_DestroyContext( c->gl_ctx ); |
| |
| _mesa_destroy_visual( c->gl_visual ); |
| _mesa_destroy_framebuffer( c->gl_buffer ); |
| _mesa_free_context_data( c->gl_ctx ); |
| free( (void *) c->gl_ctx); |
| |
| if (c->db_flag) |
| #ifdef DDRAW |
| DDFree(c); |
| #else |
| wmDeleteBackingStore(c); |
| #endif |
| free( (void *) c ); |
| #if !defined(NO_PARALLEL) |
| if(parallelMachine) |
| PRDestroyRenderBuffer(); |
| #endif |
| |
| // Destroyed context no longer valid |
| WMesaMakeCurrent( NULL ); |
| } |
| |
| |
| void WMesaMakeCurrent( WMesaContext c ) |
| { |
| if(!c){ |
| Current = c; |
| return; |
| } |
| |
| if(Current == c) |
| return; |
| |
| Current = c; |
| wmesa_update_state(c->gl_ctx, 0); |
| _mesa_make_current(c->gl_ctx, c->gl_buffer); |
| if (Current->gl_ctx->Viewport.Width==0) { |
| /* initialize viewport to window size */ |
| _mesa_Viewport( 0, 0, Current->width, Current->height ); |
| Current->gl_ctx->Scissor.Width = Current->width; |
| Current->gl_ctx->Scissor.Height = Current->height; |
| } |
| if ((c->cColorBits <= 8 ) && (c->rgb_flag == GL_TRUE)){ |
| WMesaPaletteChange(c->hPalHalfTone); |
| } |
| } |
| |
| |
| |
| void WMesaSwapBuffers( void ) |
| { |
| HDC DC = Current->hDC; |
| GET_CURRENT_CONTEXT(ctx); |
| |
| /* If we're swapping the buffer associated with the current context |
| * we have to flush any pending rendering commands first. |
| */ |
| if (Current && Current->gl_ctx == ctx) |
| _mesa_notifySwapBuffers(ctx); |
| |
| if (Current->db_flag) |
| wmFlush(Current); |
| } |
| |
| |
| |
| void WMesaPaletteChange(HPALETTE Pal) |
| { |
| #ifndef DDRAW |
| int vRet; |
| #endif |
| LPPALETTEENTRY pPal; |
| if (Current && (Current->rgb_flag==GL_FALSE || |
| Current->dither_flag == GL_TRUE)) |
| { |
| pPal = (PALETTEENTRY *)malloc( 256 * sizeof(PALETTEENTRY)); |
| Current->hPal=Pal; |
| GetPaletteEntries( Pal, 0, 256, pPal ); |
| #ifdef DDRAW |
| Current->lpDD->lpVtbl->CreatePalette(Current->lpDD,DDPCAPS_8BIT, |
| pPal, &(Current->lpDDPal), NULL); |
| if (Current->lpDDPal) |
| Current->lpDDSPrimary->lpVtbl->SetPalette(Current->lpDDSPrimary, |
| Current->lpDDPal); |
| #else |
| vRet = SetDIBColorTable(Current->dib.hDC, 0, 256, (RGBQUAD*)pPal); |
| #endif |
| free( pPal ); |
| } |
| } |
| |
| |
| |
| |
| 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 |
| }; |
| |
| 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 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); |
| |
| } |
| |
| |
| void |
| #ifdef COMPILE_SETPIXEL |
| |
| wmSetPixelDefault(PWMC pwc, int iScanLine, int iPixel, BYTE r, BYTE g, BYTE b) |
| { |
| if (Current->db_flag) |
| { |
| #ifdef DDRAW |
| HDC hdc = NULL; |
| Current->lpDDSOffScreen->lpVtbl->Unlock(Current->lpDDSOffScreen,NULL); |
| Current->lpDDSOffScreen->lpVtbl->GetDC(Current->lpDDSOffScreen,&hdc); |
| SetPixelV(hdc,iPixel, iScanLine, RGB(r,g,b)); |
| Current->lpDDSOffScreen->lpVtbl->ReleaseDC(Current->lpDDSOffScreen,hdc); |
| while (Current->lpDDSOffScreen->lpVtbl->Lock(Current->lpDDSOffScreen,NULL, &(Current->ddsd), 0, NULL) == DDERR_WASSTILLDRAWING); |
| #else |
| SetPixelV(Current->hDC, iPixel, iScanLine, RGB(r,g,b)); |
| #endif |
| } |
| else |
| { |
| SetPixelV(Current->hDC, iPixel+pwc->rectSurface.left, pwc->rectSurface.top+iScanLine, RGB(r,g,b)); |
| } |
| } |
| #else |
| wmSetPixel(PWMC pwc, int iScanLine, int iPixel, BYTE r, BYTE g, BYTE b) |
| { |
| if (Current->db_flag) |
| { |
| LPBYTE lpb = pwc->pbPixels; |
| UINT nBypp = pwc->cColorBits >> 3; |
| |
| 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) |
| { |
| *lpb++ = b; |
| *lpb++ = g; |
| *lpb = r; |
| } |
| else if (nBypp == 4) |
| *((LPDWORD)lpb) = BGR32(r,g,b); |
| } |
| else |
| { |
| SetPixel(Current->hDC, iPixel, iScanLine, RGB(r,g,b)); |
| } |
| } |
| #endif |
| #ifdef COMPILE_SETPIXEL |
| void wmSetPixel4(PWMC pwc, int iScanLine, int iPixel, BYTE r, BYTE g, BYTE b) |
| { |
| LPDWORD lpdw = ((LPDWORD)(pwc->pbPixels + pwc->ScanWidth * iScanLine)) + iPixel; |
| *lpdw = BGR32(r,g,b); |
| // LPBYTE lpb = pwc->pbPixels + pwc->ScanWidth * iScanLine + iPixel + iPixel + iPixel + iPixel; |
| // *((LPDWORD)lpb) = BGR32(r,g,b); |
| } |
| |
| void wmSetPixel3(PWMC pwc, int iScanLine, int iPixel, BYTE r, BYTE g, BYTE b) |
| { |
| LPBYTE lpb = pwc->pbPixels + pwc->ScanWidth * iScanLine + iPixel + iPixel + iPixel; |
| *lpb++ = b; |
| *lpb++ = g; |
| *lpb = r; |
| } |
| |
| void wmSetPixel2(PWMC pwc, int iScanLine, int iPixel, BYTE r, BYTE g, BYTE b) |
| { |
| LPWORD lpw = ((LPWORD)(pwc->pbPixels + pwc->ScanWidth * iScanLine)) + iPixel; |
| *lpw = BGR16(r,g,b); |
| // LPBYTE lpb = pwc->pbPixels + pwc->ScanWidth * iScanLine + iPixel + iPixel; |
| // *((LPWORD)lpb) = BGR16(r,g,b); |
| } |
| |
| void wmSetPixel1(PWMC pwc, int iScanLine, int iPixel, BYTE r, BYTE g, BYTE b) |
| { |
| LPBYTE lpb = pwc->pbPixels + pwc->ScanWidth * iScanLine + iPixel; |
| *lpb = BGR8(r,g,b); |
| } |
| |
| void wmSetPixel1Dither(PWMC pwc, int iScanLine, int iPixel, BYTE r, BYTE g, BYTE b) |
| { |
| LPBYTE lpb = pwc->pbPixels + pwc->ScanWidth * iScanLine + iPixel; |
| *lpb = DITHER_RGB_2_8BIT(r,g,b,iScanLine,iPixel); |
| } |
| |
| |
| void ChooseSetPixel(PWMC pwc) |
| { |
| UINT nBypp = (pwc ) ? pwc->cColorBits >> 3 : 0; |
| switch(nBypp) |
| { |
| case 1: |
| pwc->wmSetPixel = pwc->dither_flag ? &wmSetPixel1Dither : &wmSetPixel1; |
| break; |
| case 2: |
| pwc->wmSetPixel = &wmSetPixel2; |
| break; |
| case 3: |
| pwc->wmSetPixel = &wmSetPixel3; |
| break; |
| case 4: |
| pwc->wmSetPixel = &wmSetPixel4; |
| break; |
| default: |
| pwc->wmSetPixel = &wmSetPixelDefault; |
| break; |
| } |
| } |
| |
| #endif |
| |
| 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); |
| #ifdef USE_MAPPED_FILE |
| 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)); |
| #endif // USE_MAPPED_FILE |
| |
| hic = CreateIC("display", NULL, NULL, NULL); |
| pwc->dib.hDC = CreateCompatibleDC(hic); |
| |
| #ifdef USE_MAPPED_FILE |
| |
| pwc->hbmDIB = CreateDIBSection(hic, |
| &(pwc->bmi), |
| (iUsage ? DIB_PAL_COLORS : DIB_RGB_COLORS), |
| &(pwc->pbPixels), |
| pwc->dib.hFileMap, |
| 0); |
| #else |
| pwc->hbmDIB = CreateDIBSection(hic, |
| &(pwc->bmi), |
| (iUsage ? DIB_PAL_COLORS : DIB_RGB_COLORS), |
| &(pwc->pbPixels), |
| 0, |
| 0); |
| #endif // USE_MAPPED_FILE |
| pwc->ScreenMem = pwc->addrOffScreen = pwc->pbPixels; |
| pwc->hOldBitmap = SelectObject(pwc->dib.hDC, pwc->hbmDIB); |
| |
| DeleteDC(hic); |
| |
| return; |
| |
| } |
| |
| /* |
| * Blit memory DC to screen DC |
| */ |
| BOOL wmFlush(PWMC pwc) |
| { |
| BOOL bRet = 0; |
| DWORD dwErr = 0; |
| #ifdef DDRAW |
| HRESULT ddrval; |
| #endif |
| |
| if(pwc->db_flag){ |
| #ifdef DDRAW |
| if (pwc->lpDDSOffScreen == NULL) |
| if(DDCreateOffScreen(pwc) == GL_FALSE) |
| return FALSE; |
| |
| pwc->lpDDSOffScreen->lpVtbl->Unlock(pwc->lpDDSOffScreen, NULL); |
| |
| while( 1 ) |
| { |
| ddrval = pwc->lpDDSPrimary->lpVtbl->Blt( pwc->lpDDSPrimary, |
| &(pwc->rectSurface), |
| pwc->lpDDSOffScreen, |
| &(pwc->rectOffScreen), |
| 0, NULL ); |
| |
| if( ddrval == DD_OK ) |
| { |
| break; |
| } |
| if( ddrval == DDERR_SURFACELOST ) |
| { |
| if(!DDRestoreAll(pwc)) |
| { |
| break; |
| } |
| } |
| if( ddrval != DDERR_WASSTILLDRAWING ) |
| { |
| break; |
| } |
| } |
| |
| while (pwc->lpDDSOffScreen->lpVtbl->Lock(pwc->lpDDSOffScreen, |
| NULL, &(pwc->ddsd), 0, NULL) == |
| DDERR_WASSTILLDRAWING) |
| ; |
| |
| if(ddrval != DD_OK) |
| dwErr = GetLastError(); |
| #else |
| bRet = BitBlt(pwc->hDC, 0, 0, pwc->width, pwc->height, |
| pwc->dib.hDC, 0, 0, SRCCOPY); |
| #endif |
| } |
| |
| return(TRUE); |
| |
| } |
| |
| |
| /* The following code is added by Li Wei to enable stereo display */ |
| |
| #if !defined(NO_STEREO) |
| |
| static void __gluMakeIdentityf(GLfloat m[16]) |
| { |
| m[0+4*0] = 1; m[0+4*1] = 0; m[0+4*2] = 0; m[0+4*3] = 0; |
| m[1+4*0] = 0; m[1+4*1] = 1; m[1+4*2] = 0; m[1+4*3] = 0; |
| m[2+4*0] = 0; m[2+4*1] = 0; m[2+4*2] = 1; m[2+4*3] = 0; |
| m[3+4*0] = 0; m[3+4*1] = 0; m[3+4*2] = 0; m[3+4*3] = 1; |
| } |
| |
| static void normalize(float v[3]) |
| { |
| float r; |
| |
| r = sqrt( v[0]*v[0] + v[1]*v[1] + v[2]*v[2] ); |
| if (r == 0.0) return; |
| |
| v[0] /= r; |
| v[1] /= r; |
| v[2] /= r; |
| } |
| |
| static void cross(float v1[3], float v2[3], float result[3]) |
| { |
| result[0] = v1[1]*v2[2] - v1[2]*v2[1]; |
| result[1] = v1[2]*v2[0] - v1[0]*v2[2]; |
| result[2] = v1[0]*v2[1] - v1[1]*v2[0]; |
| } |
| |
| |
| static void |
| __gluLookAt(GLdouble eyex, GLdouble eyey, GLdouble eyez, GLdouble centerx, |
| GLdouble centery, GLdouble centerz, GLdouble upx, GLdouble upy, |
| GLdouble upz) |
| { |
| int i; |
| float forward[3], side[3], up[3]; |
| GLfloat m[4][4]; |
| |
| forward[0] = centerx - eyex; |
| forward[1] = centery - eyey; |
| forward[2] = centerz - eyez; |
| |
| up[0] = upx; |
| up[1] = upy; |
| up[2] = upz; |
| |
| normalize(forward); |
| |
| /* Side = forward x up */ |
| cross(forward, up, side); |
| normalize(side); |
| |
| /* Recompute up as: up = side x forward */ |
| cross(side, forward, up); |
| |
| __gluMakeIdentityf(&m[0][0]); |
| m[0][0] = side[0]; |
| m[1][0] = side[1]; |
| m[2][0] = side[2]; |
| |
| m[0][1] = up[0]; |
| m[1][1] = up[1]; |
| m[2][1] = up[2]; |
| |
| m[0][2] = -forward[0]; |
| m[1][2] = -forward[1]; |
| m[2][2] = -forward[2]; |
| |
| glMultMatrixf(&m[0][0]); |
| glTranslated(-eyex, -eyey, -eyez); |
| } |
| |
| GLfloat viewDistance = 1.0; |
| |
| void WMesaShowStereo(GLuint list) |
| { |
| |
| GLbitfield mask = GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT; |
| GLfloat cm[16]; |
| GLint matrix_mode; |
| /* Must use double Buffer */ |
| if( ! Current-> db_flag ) |
| return; |
| |
| |
| glGetIntegerv(GL_MATRIX_MODE,&matrix_mode); |
| |
| WMesaViewport(Current->gl_ctx,0,Current->height/2, |
| Current->width,Current->height/2); |
| if(matrix_mode!=GL_MODELVIEW) |
| glMatrixMode(GL_MODELVIEW); |
| |
| glGetFloatv(GL_MODELVIEW_MATRIX,cm); |
| glLoadIdentity(); |
| __gluLookAt(viewDistance/2,0.0,0.0 , |
| viewDistance/2,0.0,-1.0, |
| 0.0,1.0,0.0 ); |
| glMultMatrixf( cm ); |
| |
| Current->ScreenMem = Current->pbPixels = Current->addrOffScreen; |
| glCallList( list ); |
| |
| glGetFloatv(GL_MODELVIEW_MATRIX,cm); |
| glLoadIdentity(); |
| __gluLookAt(-viewDistance/2,0.0,0.0 , |
| -viewDistance/2,0.0,-1.0, |
| 0.0,1.0,0.0 ); |
| glMultMatrixf(cm); |
| |
| Current->ScreenMem = Current->pbPixels = Current->addrOffScreen + Current->pitch; |
| glCallList(list); |
| if(matrix_mode!=GL_MODELVIEW) |
| glMatrixMode(matrix_mode); |
| |
| glFlush(); |
| |
| WMesaViewport(Current->gl_ctx,0,0,Current->width,Current->height); |
| WMesaSwapBuffers(); |
| } |
| |
| void toggleStereoMode() |
| { |
| if(!Current->db_flag) |
| return; |
| if(!stereo_flag){ |
| stereo_flag = 1; |
| if(stereoBuffer==GL_FALSE) |
| #if !defined(NO_PARALLEL) |
| if(!parallelFlag) |
| #endif |
| { |
| Current->ScanWidth = Current->pitch*2; |
| } |
| } |
| else { |
| stereo_flag = 0; |
| #if !defined(NO_PARALLEL) |
| if(!parallelFlag) |
| #endif |
| Current->ScanWidth = Current->pitch; |
| Current->pbPixels = Current->addrOffScreen; |
| } |
| } |
| |
| /* if in stereo mode, the following function is called */ |
| void glShowStereo(GLuint list) |
| { |
| WMesaShowStereo(list); |
| } |
| |
| #endif /* NO_STEREO */ |
| |
| #if !defined(NO_PARALLEL) |
| |
| void toggleParallelMode(void) |
| { |
| if(!parallelFlag){ |
| parallelFlag = GL_TRUE; |
| if(parallelMachine==GL_FALSE){ |
| PRCreateRenderBuffer( Current->rgb_flag? GL_RGBA :GL_COLOR_INDEX, |
| Current->cColorBits/8, |
| Current->width ,Current->height, |
| Current->ScanWidth, |
| Current->rgb_flag? Current->pbPixels: |
| Current->ScreenMem); |
| parallelMachine = GL_TRUE; |
| } |
| } |
| else { |
| parallelFlag = GL_FALSE; |
| if(parallelMachine==GL_TRUE){ |
| PRDestroyRenderBuffer(); |
| parallelMachine=GL_FALSE; |
| ReadyForNextFrame = GL_TRUE; |
| } |
| |
| /*********************************************** |
| * Seems something wrong!!!! |
| ************************************************/ |
| |
| WMesaMakeCurrent(Current); |
| #if !defined(NO_STEREO) |
| stereo_flag = GL_FALSE ; |
| #endif |
| } |
| } |
| |
| void PRShowRenderResult(void) |
| { |
| int flag = 0; |
| if(!glImageRendered()) |
| return; |
| |
| if (parallelFlag) |
| { |
| WMesaSwapBuffers(); |
| } |
| |
| } |
| #endif /* NO_PARALLEL */ |
| |
| 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]; |
| } |
| |
| #ifdef DDRAW |
| /* |
| * restoreAll |
| * |
| * restore all lost objects |
| */ |
| HRESULT DDRestoreAll( WMesaContext wc ) |
| { |
| HRESULT ddrval; |
| |
| ddrval = wc->lpDDSPrimary->lpVtbl->Restore(wc->lpDDSPrimary); |
| if( ddrval == DD_OK ) |
| { |
| ddrval = wc->lpDDSOffScreen->lpVtbl->Restore(wc->lpDDSOffScreen); |
| } |
| return ddrval; |
| |
| } /* restoreAll */ |
| |
| |
| /* |
| * This function is called if the initialization function fails |
| */ |
| BOOL initFail( HWND hwnd, WMesaContext wc ) |
| { |
| DDFree(wc); |
| MessageBox( hwnd, "DirectDraw Init FAILED", "", MB_OK ); |
| return FALSE; |
| |
| } /* initFail */ |
| |
| |
| static void DDDeleteOffScreen(WMesaContext wc) |
| { |
| if( wc->lpDDSOffScreen != NULL ) |
| { |
| wc->lpDDSOffScreen->lpVtbl->Unlock(wc->lpDDSOffScreen,NULL); |
| wc->lpDDSOffScreen->lpVtbl->Release(wc->lpDDSOffScreen); |
| wc->lpDDSOffScreen = NULL; |
| } |
| |
| } |
| |
| static void DDFreePrimarySurface(WMesaContext wc) |
| { |
| if( wc->lpDDSPrimary != NULL ) |
| { |
| if(wc->db_flag == GL_FALSE) |
| wc->lpDDSPrimary->lpVtbl->ReleaseDC(wc->lpDDSPrimary, wc->hDC); |
| wc->lpDDSPrimary->lpVtbl->Release(wc->lpDDSPrimary); |
| wc->lpDDSPrimary = NULL; |
| } |
| } |
| |
| static BOOL DDCreatePrimarySurface(WMesaContext wc) |
| { |
| HRESULT ddrval; |
| // DDSCAPS ddscaps; |
| wc->ddsd.dwSize = sizeof( wc->ddsd ); |
| wc->ddsd.dwFlags = DDSD_CAPS; |
| wc->ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE; |
| |
| ddrval = wc->lpDD->lpVtbl->CreateSurface( wc->lpDD,&(wc->ddsd), |
| &(wc->lpDDSPrimary), NULL ); |
| if( ddrval != DD_OK ) |
| { |
| return initFail(wc->hwnd , wc); |
| } |
| if(wc->db_flag == GL_FALSE) |
| wc->lpDDSPrimary->lpVtbl->GetDC(wc->lpDDSPrimary, &(wc->hDC)); |
| return TRUE; |
| } |
| |
| static BOOL DDCreateOffScreen(WMesaContext wc) |
| { |
| POINT pt; |
| HRESULT ddrval; |
| if(wc->lpDD == NULL) |
| return FALSE; |
| GetClientRect( wc->hwnd, &(wc->rectOffScreen) ); |
| wc->ddsd.dwFlags = DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH; |
| wc->ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN; |
| wc->ddsd.dwHeight = wc->rectOffScreen.bottom - wc->rectOffScreen.top; |
| wc->ddsd.dwWidth = wc->rectOffScreen.right - wc->rectOffScreen.left; |
| |
| ddrval = wc->lpDD->lpVtbl->CreateSurface( wc->lpDD, &(wc->ddsd), |
| &(wc->lpDDSOffScreen), NULL ); |
| if( ddrval != DD_OK ) |
| { |
| return FALSE; |
| } |
| |
| while (wc->lpDDSOffScreen->lpVtbl->Lock(wc->lpDDSOffScreen,NULL, |
| &(wc->ddsd), 0, NULL) == |
| DDERR_WASSTILLDRAWING) |
| ; |
| |
| if(wc->ddsd.lpSurface==NULL) |
| return initFail(wc->hwnd, wc); |
| |
| wc->ScreenMem = wc->pbPixels = wc->addrOffScreen = |
| (PBYTE)(wc->ddsd.lpSurface); |
| wc->ScanWidth = wc->pitch = wc->ddsd.lPitch; |
| if (stereo_flag) |
| wc->ScanWidth = wc->ddsd.lPitch*2; |
| |
| GetClientRect( wc->hwnd, &(wc->rectSurface) ); |
| pt.x = pt.y = 0; |
| ClientToScreen( wc->hwnd, &pt ); |
| OffsetRect(&(wc->rectSurface), pt.x, pt.y); |
| wmSetPixelFormat(wc, wc->hDC); |
| return TRUE; |
| } |
| |
| typedef |
| struct tagWMesaContextList |
| { |
| WMesaContext wc; |
| struct tagWMesaContextList *next; |
| }WMesaContextList; |
| |
| WMesaContextList *head = 0; |
| |
| void AddContext(WMesaContext wc) |
| { |
| WMesaContextList *lst = (WMesaContextList *)malloc(sizeof(WMesaContextList)); |
| lst->wc = wc; |
| if( head ) |
| lst->next = head; |
| head = lst; |
| } |
| |
| WMesaContext FindContext(HWND hWnd) |
| { |
| WMesaContextList *tmp = head; |
| while(tmp) |
| { |
| if( tmp->wc->hwnd == hWnd ) |
| return tmp->wc; |
| tmp = tmp->next; |
| } |
| return NULL; |
| } |
| |
| void RemoveContext(HWND hWnd) |
| { |
| WMesaContextList *tmp = head; |
| if(tmp ) |
| { |
| if( tmp->wc->hwnd == hWnd ) |
| { |
| WMesaContextList *lst = tmp; |
| |
| head = tmp->next; |
| free((void *)lst); |
| } |
| else |
| while(tmp->next) |
| { |
| if( tmp->next->wc->hwnd == hWnd ) |
| { |
| WMesaContextList *lst = tmp->next; |
| tmp->next = tmp->next->next; |
| free((void *)lst); |
| } |
| tmp = tmp->next; |
| } |
| } |
| } |
| |
| static LRESULT CALLBACK MyWndProc(HWND hwnd,UINT message,WPARAM wParam, LPARAM lParam) |
| { |
| WMesaContext wc = Current->hwnd == hwnd ? Current : FindContext(hwnd); |
| if( wc ) |
| { |
| LRESULT lret = CallWindowProc((WNDPROC)(wc->oldWndProc),hwnd,message,wParam,lParam); |
| if( message = WM_MOVE ) |
| { |
| POINT pt = {0}; |
| GetClientRect( wc->hwnd, &(wc->rectSurface) ); |
| ClientToScreen( hwnd, &pt ); |
| OffsetRect(&(wc->rectSurface), pt.x, pt.y); |
| } |
| return lret; |
| } |
| return 0L; |
| } |
| |
| /* |
| * doInit - do work required for every instance of the application: |
| * create the window, initialize data |
| */ |
| static BOOL DDInit( WMesaContext wc, HWND hwnd) |
| { |
| HRESULT ddrval; |
| // DWORD dwFrequency; |
| |
| // LPDIRECTDRAW lpDD; // DirectDraw object |
| // LPDIRECTDRAW2 lpDD2; |
| LPDIRECTDRAWCLIPPER pcClipper = NULL; |
| |
| wc->fullScreen = displayOptions.fullScreen; |
| wc->gMode = displayOptions.mode; |
| wc->hwnd = hwnd; |
| stereo_flag = displayOptions.stereo; |
| if(wc->db_flag!= GL_TRUE) |
| stereo_flag = GL_FALSE; |
| /* |
| * create the main DirectDraw object |
| */ |
| ddrval = DirectDrawCreate( NULL, &(wc->lpDD), NULL ); |
| if( ddrval != DD_OK ) |
| { |
| return initFail(hwnd,wc); |
| } |
| |
| // Get exclusive mode if requested |
| if(wc->fullScreen) |
| { |
| ddrval = wc->lpDD->lpVtbl->SetCooperativeLevel( wc->lpDD, hwnd, |
| DDSCL_EXCLUSIVE | |
| DDSCL_FULLSCREEN ); |
| } |
| else |
| { |
| ddrval = wc->lpDD->lpVtbl->SetCooperativeLevel( wc->lpDD, hwnd, |
| DDSCL_NORMAL ); |
| } |
| if( ddrval != DD_OK ) |
| { |
| return initFail(hwnd , wc); |
| } |
| |
| |
| if(ddrval != DD_OK) |
| return initFail(hwnd , wc); |
| |
| |
| switch( wc->gMode ) |
| { |
| case 1: |
| ddrval = wc->lpDD->lpVtbl->SetDisplayMode( wc->lpDD, 640, 480, |
| displayOptions.bpp); |
| break; |
| case 2: |
| ddrval = wc->lpDD->lpVtbl->SetDisplayMode( wc->lpDD, 800, 600, |
| displayOptions.bpp); |
| break; |
| case 3: |
| ddrval = wc->lpDD->lpVtbl->SetDisplayMode( wc->lpDD, 1024, 768, |
| displayOptions.bpp); |
| break; |
| case 4: |
| ddrval = wc->lpDD->lpVtbl->SetDisplayMode( wc->lpDD, 1152, 864, |
| displayOptions.bpp); |
| break; |
| case 5: |
| ddrval = wc->lpDD->lpVtbl->SetDisplayMode( wc->lpDD, 1280, 1024, |
| displayOptions.bpp); |
| break; |
| } |
| |
| if( ddrval != DD_OK ) |
| { |
| printf("Can't modify display mode, current mode used\n"); |
| } |
| switch(ddrval){ |
| case DDERR_INVALIDOBJECT: |
| break; |
| case DDERR_INVALIDPARAMS: |
| break; |
| case DDERR_UNSUPPORTEDMODE: |
| ; |
| } |
| |
| if(DDCreatePrimarySurface(wc) == GL_FALSE) |
| return initFail(hwnd, wc); |
| |
| if(wc->db_flag) |
| DDCreateOffScreen(wc); |
| |
| if( FAILED( ddrval = wc->lpDD->lpVtbl->CreateClipper(wc->lpDD, 0, &pcClipper, NULL ) ) ) |
| return E_FAIL; |
| |
| if( FAILED( ddrval = pcClipper->lpVtbl->SetHWnd(pcClipper, 0, wc->hwnd ) ) ) |
| { |
| pcClipper->lpVtbl->Release(pcClipper); |
| return E_FAIL; |
| } |
| |
| if( FAILED( ddrval = wc->lpDDSPrimary->lpVtbl->SetClipper(wc->lpDDSPrimary, pcClipper ) ) ) |
| { |
| pcClipper->lpVtbl->Release(pcClipper); |
| return E_FAIL; |
| } |
| |
| // Done with clipper |
| pcClipper->lpVtbl->Release(pcClipper); |
| AddContext(wc); |
| // Hook the window so we can update the drawing rectangle when the window moves |
| wc->oldWndProc = SetWindowLong(wc->hwnd,GWL_WNDPROC,(LONG)MyWndProc); |
| |
| return TRUE; |
| |
| } /* DDInit */ |
| |
| static void DDFree( WMesaContext wc) |
| { |
| RemoveContext(wc->hwnd); |
| SetWindowLong(wc->hwnd,GWL_WNDPROC,(LONG)(wc->oldWndProc)); |
| wc->oldWndProc = 0; |
| if( wc->lpDD != NULL ) |
| { |
| DDFreePrimarySurface(wc); |
| DDDeleteOffScreen(wc); |
| wc->lpDD->lpVtbl->Release(wc->lpDD); |
| wc->lpDD = NULL; |
| } |
| // Clean up the screen on exit |
| RedrawWindow( NULL, NULL, NULL, RDW_INVALIDATE | RDW_ERASE | |
| RDW_ALLCHILDREN ); |
| |
| } |
| #endif |
| |
| void WMesaMove(void) |
| { |
| WMesaContext wc = Current; |
| POINT pt; |
| if (Current != NULL){ |
| GetClientRect( wc->hwnd, &(wc->rectSurface) ); |
| pt.x = pt.y = 0; |
| ClientToScreen( wc->hwnd, &pt ); |
| OffsetRect(&(wc->rectSurface), pt.x, pt.y); |
| } |
| } |
| |
| |
| /************************************************ |
| * Mesa 4.0 - These triangle rasterizers are not |
| * implemented in this version of the Windows |
| * driver. They could be implemented for a |
| * potential performance improvement. |
| * See OSMesa for an example of the approach |
| * to use. |
| * This old code is left in this file in case |
| * it is useful. However, it may end up looking |
| * a lot more like the OSMesa code. |
| ************************************************/ |
| |
| |
| #if defined(FAST_RASTERIZERS) |
| |
| |
| /* |
| * Like PACK_8A8B8G8R() but don't use alpha. This is usually an acceptable |
| * shortcut. |
| */ |
| #define PACK_8B8G8R( R, G, B ) ( ((B) << 16) | ((G) << 8) | (R) ) |
| |
| /**********************************************************************/ |
| /*** Triangle rendering ***/ |
| /**********************************************************************/ |
| |
| /* |
| * XImage, smooth, depth-buffered, PF_8A8B8G8R triangle. |
| */ |
| static void smooth_8A8B8G8R_z_triangle( GLcontext *ctx, |
| GLuint v0, GLuint v1, GLuint v2, |
| GLuint pv ) |
| { |
| WMesaContext wmesa = (WMesaContext) ctx->DriverCtx; |
| #define INTERP_Z 1 |
| #define DEPTH_TYPE DEFAULT_SOFTWARE_DEPTH_TYPE |
| #define INTERP_RGB 1 |
| #define PIXEL_ADDRESS(X,Y) PIXELADDR4(X,Y) |
| #define PIXEL_TYPE GLuint |
| //#define BYTES_PER_ROW (wmesa->xm_buffer->backimage->bytes_per_line) |
| #define BYTES_PER_ROW (wmesa->ScanWidth) |
| #define INNER_LOOP( LEFT, RIGHT, Y ) \ |
| { \ |
| GLint i, len = RIGHT-LEFT; \ |
| for (i=0;i<len;i++) { \ |
| GLdepth z = FixedToDepth(ffz); \ |
| if (z < zRow[i]) { \ |
| pRow[i] = PACK_8B8G8R( FixedToInt(ffr), FixedToInt(ffg), \ |
| FixedToInt(ffb) ); \ |
| zRow[i] = z; \ |
| } \ |
| ffr += fdrdx; ffg += fdgdx; ffb += fdbdx; \ |
| ffz += fdzdx; \ |
| } \ |
| } |
| |
| #ifdef __MINGW32__ |
| #include "tritemp.h" |
| #else |
| |
| #ifdef WIN32 |
| // #include "..\tritemp.h" |
| #else |
| #include "tritemp.h" |
| #endif |
| #endif |
| } |
| |
| |
| /* |
| * XImage, smooth, depth-buffered, PF_8R8G8B triangle. |
| */ |
| static void smooth_8R8G8B_z_triangle( GLcontext *ctx, |
| GLuint v0, GLuint v1, GLuint v2, |
| GLuint pv ) |
| { |
| WMesaContext wmesa = (WMesaContext) ctx->DriverCtx; |
| #define INTERP_Z 1 |
| #define INTERP_RGB 1 |
| #define PIXEL_ADDRESS(X,Y) PIXELADDR4(X,Y) |
| #define PIXEL_TYPE GLuint |
| //#define BYTES_PER_ROW (wmesa->xm_buffer->backimage->bytes_per_line) |
| #define BYTES_PER_ROW (wmesa->ScanWidth) |
| #define INNER_LOOP( LEFT, RIGHT, Y ) \ |
| { \ |
| GLint i, len = RIGHT-LEFT; \ |
| for (i=0;i<len;i++) { \ |
| GLdepth z = FixedToDepth(ffz); \ |
| if (z < zRow[i]) { \ |
| pRow[i] = PACK_8R8G8B( FixedToInt(ffr), FixedToInt(ffg), \ |
| FixedToInt(ffb) ); \ |
| zRow[i] = z; \ |
| } \ |
| ffr += fdrdx; ffg += fdgdx; ffb += fdbdx; \ |
| ffz += fdzdx; \ |
| } \ |
| } |
| #ifdef __MINGW32__ |
| #include "tritemp.h" |
| #else |
| |
| #ifdef WIN32 |
| // #include "..\tritemp.h" |
| #else |
| #include "tritemp.h" |
| #endif |
| #endif |
| } |
| |
| |
| |
| /* |
| * XImage, smooth, depth-buffered, PF_5R6G5B triangle. |
| */ |
| static void smooth_5R6G5B_z_triangle( GLcontext *ctx, |
| GLuint v0, GLuint v1, GLuint v2, |
| GLuint pv ) |
| { |
| WMesaContext wmesa = (WMesaContext) ctx->DriverCtx; |
| #define INTERP_Z 1 |
| #define INTERP_RGB 1 |
| #define PIXEL_ADDRESS(X,Y) PIXELADDR2(X,Y) |
| #define PIXEL_TYPE GLushort |
| //#define BYTES_PER_ROW (wmesa->xm_buffer->backimage->bytes_per_line) |
| #define BYTES_PER_ROW (wmesa->ScanWidth) |
| #define INNER_LOOP( LEFT, RIGHT, Y ) \ |
| { \ |
| GLint i, len = RIGHT-LEFT; \ |
| for (i=0;i<len;i++) { \ |
| GLdepth z = FixedToDepth(ffz); \ |
| if (z < zRow[i]) { \ |
| pRow[i] = PACK_5R6G5B( FixedToInt(ffr), FixedToInt(ffg), \ |
| FixedToInt(ffb) ); \ |
| zRow[i] = z; \ |
| } \ |
| ffr += fdrdx; ffg += fdgdx; ffb += fdbdx; \ |
| ffz += fdzdx; \ |
| } \ |
| } |
| #ifdef __MINGW32__ |
| #include "tritemp.h" |
| #else |
| |
| #ifdef WIN32 |
| // #include "..\tritemp.h" |
| #else |
| #include "tritemp.h" |
| #endif |
| #endif |
| } |
| |
| /* |
| * XImage, flat, depth-buffered, PF_8A8B8G8R triangle. |
| */ |
| static void flat_8A8B8G8R_z_triangle( GLcontext *ctx, GLuint v0, |
| GLuint v1, GLuint v2, GLuint pv ) |
| { |
| WMesaContext wmesa = (WMesaContext) ctx->DriverCtx; |
| #define INTERP_Z 1 |
| #define PIXEL_ADDRESS(X,Y) PIXELADDR4(X,Y) |
| #define PIXEL_TYPE GLuint |
| //#define BYTES_PER_ROW (wmesa->xm_buffer->backimage->bytes_per_line) |
| #define BYTES_PER_ROW (wmesa->ScanWidth) |
| #define SETUP_CODE \ |
| unsigned long p = PACK_8B8G8R( VB->ColorPtr->data[pv][0], \ |
| VB->ColorPtr->data[pv][1], VB->ColorPtr->data[pv][2] ); |
| #define INNER_LOOP( LEFT, RIGHT, Y ) \ |
| { \ |
| GLint i, len = RIGHT-LEFT; \ |
| for (i=0;i<len;i++) { \ |
| GLdepth z = FixedToDepth(ffz); \ |
| if (z < zRow[i]) { \ |
| pRow[i] = p; \ |
| zRow[i] = z; \ |
| } \ |
| ffz += fdzdx; \ |
| } \ |
| } |
| #ifdef __MINGW32__ |
| #include "tritemp.h" |
| #else |
| |
| #ifdef WIN32 |
| // #include "..\tritemp.h" |
| #else |
| #include "tritemp.h" |
| #endif |
| #endif |
| } |
| |
| |
| /* |
| * XImage, flat, depth-buffered, PF_8R8G8B triangle. |
| */ |
| static void flat_8R8G8B_z_triangle( GLcontext *ctx, GLuint v0, GLuint v1, |
| GLuint v2, GLuint pv ) |
| { |
| WMesaContext wmesa = (WMesaContext) ctx->DriverCtx; |
| #define INTERP_Z 1 |
| #define PIXEL_ADDRESS(X,Y) PIXELADDR4(X,Y) |
| #define PIXEL_TYPE GLuint |
| //#define BYTES_PER_ROW (wmesa->xm_buffer->backimage->bytes_per_line) |
| #define BYTES_PER_ROW (wmesa->ScanWidth) |
| #define SETUP_CODE \ |
| unsigned long p = PACK_8R8G8B( VB->ColorPtr->data[pv][0], \ |
| VB->ColorPtr->data[pv][1], VB->ColorPtr->data[pv][2] ); |
| #define INNER_LOOP( LEFT, RIGHT, Y ) \ |
| { \ |
| GLint i, len = RIGHT-LEFT; \ |
| for (i=0;i<len;i++) { \ |
| GLdepth z = FixedToDepth(ffz); \ |
| if (z < zRow[i]) { \ |
| pRow[i] = p; \ |
| zRow[i] = z; \ |
| } \ |
| ffz += fdzdx; \ |
| } \ |
| } |
| #ifdef __MINGW32__ |
| #include "tritemp.h" |
| #else |
| |
| #ifdef WIN32 |
| // #include "..\tritemp.h" |
| #else |
| #include "tritemp.h" |
| #endif |
| #endif |
| } |
| |
| |
| /* |
| * XImage, flat, depth-buffered, PF_5R6G5B triangle. |
| */ |
| static void flat_5R6G5B_z_triangle( GLcontext *ctx, GLuint v0, GLuint v1, |
| GLuint v2, GLuint pv ) |
| { |
| WMesaContext wmesa = (WMesaContext) ctx->DriverCtx; |
| #define INTERP_Z 1 |
| #define PIXEL_ADDRESS(X,Y) PIXELADDR2(X,Y) |
| #define PIXEL_TYPE GLushort |
| //#define BYTES_PER_ROW (wmesa->xm_buffer->backimage->bytes_per_line) |
| #define BYTES_PER_ROW (wmesa->ScanWidth) |
| #define SETUP_CODE \ |
| unsigned long p = PACK_5R6G5B( VB->ColorPtr->data[pv][0], \ |
| VB->ColorPtr->data[pv][1], VB->ColorPtr->data[pv][2] ); |
| #define INNER_LOOP( LEFT, RIGHT, Y ) \ |
| { \ |
| GLint i, len = RIGHT-LEFT; \ |
| for (i=0;i<len;i++) { \ |
| GLdepth z = FixedToDepth(ffz); \ |
| if (z < zRow[i]) { \ |
| pRow[i] = p; \ |
| zRow[i] = z; \ |
| } \ |
| ffz += fdzdx; \ |
| } \ |
| } |
| #ifdef __MINGW32__ |
| #include "tritemp.h" |
| #else |
| |
| #ifdef WIN32 |
| // #include "..\tritemp.h" |
| #else |
| #include "tritemp.h" |
| #endif |
| #endif |
| } |
| |
| |
| /* |
| * XImage, smooth, NON-depth-buffered, PF_8A8B8G8R triangle. |
| */ |
| static void smooth_8A8B8G8R_triangle( GLcontext *ctx, GLuint v0, GLuint v1, |
| GLuint v2, GLuint pv ) |
| { |
| WMesaContext wmesa = (WMesaContext) ctx->DriverCtx; |
| #define INTERP_RGB 1 |
| #define PIXEL_ADDRESS(X,Y) PIXELADDR4(X,Y) |
| #define PIXEL_TYPE GLuint |
| //#define BYTES_PER_ROW (wmesa->xm_buffer->backimage->bytes_per_line) |
| #define BYTES_PER_ROW (wmesa->ScanWidth) |
| #define INNER_LOOP( LEFT, RIGHT, Y ) \ |
| { \ |
| GLint xx; \ |
| PIXEL_TYPE *pixel = pRow; \ |
| for (xx=LEFT;xx<RIGHT;xx++,pixel++) { \ |
| *pixel = PACK_8B8G8R( FixedToInt(ffr), FixedToInt(ffg), \ |
| FixedToInt(ffb) ); \ |
| ffr += fdrdx; ffg += fdgdx; ffb += fdbdx; \ |
| } \ |
| } |
| #ifdef __MINGW32__ |
| #include "tritemp.h" |
| #else |
| |
| #ifdef WIN32 |
| // #include "..\tritemp.h" |
| #else |
| #include "tritemp.h" |
| #endif |
| #endif |
| } |
| |
| |
| /* |
| * XImage, smooth, NON-depth-buffered, PF_8R8G8B triangle. |
| */ |
| static void smooth_8R8G8B_triangle( GLcontext *ctx, GLuint v0, GLuint v1, |
| GLuint v2, GLuint pv ) |
| { |
| WMesaContext wmesa = (WMesaContext) ctx->DriverCtx; |
| #define INTERP_RGB 1 |
| #define PIXEL_ADDRESS(X,Y) PIXELADDR4(X,Y) |
| #define PIXEL_TYPE GLuint |
| //#define BYTES_PER_ROW (wmesa->xm_buffer->backimage->bytes_per_line) |
| #define BYTES_PER_ROW (wmesa->ScanWidth) |
| #define INNER_LOOP( LEFT, RIGHT, Y ) \ |
| { \ |
| GLint xx; \ |
| PIXEL_TYPE *pixel = pRow; \ |
| for (xx=LEFT;xx<RIGHT;xx++,pixel++) { \ |
| *pixel = PACK_8R8G8B( FixedToInt(ffr), FixedToInt(ffg), \ |
| FixedToInt(ffb) ); \ |
| ffr += fdrdx; ffg += fdgdx; ffb += fdbdx; \ |
| } \ |
| } |
| #ifdef __MINGW32__ |
| #include "tritemp.h" |
| #else |
| |
| #ifdef WIN32 |
| // #include "..\tritemp.h" |
| #else |
| #include "tritemp.h" |
| #endif |
| #endif |
| } |
| |
| |
| /* |
| * XImage, smooth, NON-depth-buffered, PF_5R6G5B triangle. |
| */ |
| static void smooth_5R6G5B_triangle( GLcontext *ctx, GLuint v0, GLuint v1, |
| GLuint v2, GLuint pv ) |
| { |
| WMesaContext wmesa = (WMesaContext) ctx->DriverCtx; |
| #define INTERP_RGB 1 |
| #define PIXEL_ADDRESS(X,Y) PIXELADDR2(X,Y) |
| #define PIXEL_TYPE GLushort |
| //#define BYTES_PER_ROW (wmesa->xm_buffer->backimage->bytes_per_line) |
| #define BYTES_PER_ROW (wmesa->ScanWidth) |
| #define INNER_LOOP( LEFT, RIGHT, Y ) \ |
| { \ |
| GLint xx; \ |
| PIXEL_TYPE *pixel = pRow; \ |
| for (xx=LEFT;xx<RIGHT;xx++,pixel++) { \ |
| *pixel = PACK_5R6G5B( FixedToInt(ffr), FixedToInt(ffg), \ |
| FixedToInt(ffb) ); \ |
| ffr += fdrdx; ffg += fdgdx; ffb += fdbdx; \ |
| } \ |
| } |
| #ifdef __MINGW32__ |
| #include "tritemp.h" |
| #else |
| |
| #ifdef WIN32 |
| // #include "..\tritemp.h" |
| #else |
| #include "tritemp.h" |
| #endif |
| #endif |
| } |
| |
| |
| |
| /* |
| * XImage, flat, NON-depth-buffered, PF_8A8B8G8R triangle. |
| */ |
| static void flat_8A8B8G8R_triangle( GLcontext *ctx, GLuint v0, |
| GLuint v1, GLuint v2, GLuint pv ) |
| { |
| WMesaContext wmesa = (WMesaContext) ctx->DriverCtx; |
| #define PIXEL_ADDRESS(X,Y) PIXELADDR4(X,Y) |
| #define PIXEL_TYPE GLuint |
| //#define BYTES_PER_ROW (wmesa->xm_buffer->backimage->bytes_per_line) |
| #define BYTES_PER_ROW (wmesa->ScanWidth) |
| #define SETUP_CODE \ |
| unsigned long p = PACK_8B8G8R( VB->ColorPtr->data[pv][0], \ |
| VB->ColorPtr->data[pv][1], VB->ColorPtr->data[pv][2] ); |
| #define INNER_LOOP( LEFT, RIGHT, Y ) \ |
| { \ |
| GLint xx; \ |
| PIXEL_TYPE *pixel = pRow; \ |
| for (xx=LEFT;xx<RIGHT;xx++,pixel++) { \ |
| *pixel = p; \ |
| } \ |
| } |
| |
| #ifdef __MINGW32__ |
| #include "tritemp.h" |
| #else |
| |
| #ifdef WIN32 |
| // #include "..\tritemp.h" |
| #else |
| #include "tritemp.h" |
| #endif |
| #endif |
| } |
| |
| |
| /* |
| * XImage, flat, NON-depth-buffered, PF_8R8G8B triangle. |
| */ |
| static void flat_8R8G8B_triangle( GLcontext *ctx, GLuint v0, GLuint v1, |
| GLuint v2, GLuint pv ) |
| { |
| WMesaContext wmesa = (WMesaContext) ctx->DriverCtx; |
| #define PIXEL_ADDRESS(X,Y) PIXELADDR4(X,Y) |
| #define PIXEL_TYPE GLuint |
| //#define BYTES_PER_ROW (wmesa->xm_buffer->backimage->bytes_per_line) |
| #define BYTES_PER_ROW (wmesa->ScanWidth) |
| #define SETUP_CODE \ |
| unsigned long p = PACK_8R8G8B( VB->ColorPtr->data[pv][0], \ |
| VB->ColorPtr->data[pv][1], VB->ColorPtr->data[pv][2] ); |
| #define INNER_LOOP( LEFT, RIGHT, Y ) \ |
| { \ |
| GLint xx; \ |
| PIXEL_TYPE *pixel = pRow; \ |
| for (xx=LEFT;xx<RIGHT;xx++,pixel++) { \ |
| *pixel = p; \ |
| } \ |
| } |
| #ifdef __MINGW32__ |
| #include "tritemp.h" |
| #else |
| |
| #ifdef WIN32 |
| // #include "..\tritemp.h" |
| #else |
| #include "tritemp.h" |
| #endif |
| #endif |
| } |
| |
| |
| /* |
| * XImage, flat, NON-depth-buffered, PF_5R6G5B triangle. |
| */ |
| static void flat_5R6G5B_triangle( GLcontext *ctx, GLuint v0, GLuint v1, |
| GLuint v2, GLuint pv ) |
| { |
| WMesaContext wmesa = (WMesaContext) ctx->DriverCtx; |
| #define PIXEL_ADDRESS(X,Y) PIXELADDR2(X,Y) |
| #define PIXEL_TYPE GLushort |
| //#define BYTES_PER_ROW (wmesa->xm_buffer->backimage->bytes_per_line) |
| #define BYTES_PER_ROW (wmesa->ScanWidth) |
| #define SETUP_CODE \ |
| unsigned long p = PACK_5R6G5B( VB->ColorPtr->data[pv][0], \ |
| VB->ColorPtr->data[pv][1], VB->ColorPtr->data[pv][2] ); |
| #define INNER_LOOP( LEFT, RIGHT, Y ) \ |
| { \ |
| GLint xx; \ |
| PIXEL_TYPE *pixel = pRow; \ |
| for (xx=LEFT;xx<RIGHT;xx++,pixel++) { \ |
| *pixel = p; \ |
| } \ |
| } |
| #ifdef __MINGW32__ |
| #include "tritemp.h" |
| #else |
| |
| #ifdef WIN32 |
| // #include "..\tritemp.h" |
| #else |
| #include "tritemp.h" |
| #endif |
| #endif |
| } |
| |
| |
| /* |
| * XImage, smooth, depth-buffered, 8-bit PF_LOOKUP triangle. |
| */ |
| |
| static void smooth_ci_z_triangle( GLcontext *ctx, GLuint v0, GLuint v1, |
| GLuint v2, GLuint pv ) |
| { |
| WMesaContext wmesa = (WMesaContext) ctx->DriverCtx; |
| #define INTERP_Z 1 |
| #define INTERP_INDEX 1 |
| #define PIXEL_ADDRESS(X,Y) PIXELADDR1(X,Y) |
| #define PIXEL_TYPE GLubyte |
| #define BYTES_PER_ROW (wmesa->ScanWidth) |
| #define INNER_LOOP( LEFT, RIGHT, Y ) \ |
| { \ |
| GLint i, len = RIGHT-LEFT; \ |
| for (i=0;i<len;i++) { \ |
| GLdepth z = FixedToDepth(ffz); \ |
| if (z < zRow[i]) { \ |
| pRow[i] = FixedToInt(ffi); \ |
| zRow[i] = z; \ |
| } \ |
| ffi += fdidx; \ |
| ffz += fdzdx; \ |
| } \ |
| } |
| #ifdef __MINGW32__ |
| #include "tritemp.h" |
| #else |
| |
| #ifdef WIN32 |
| // #include "..\tritemp.h" |
| #else |
| #include "tritemp.h" |
| #endif |
| #endif |
| } |
| |
| |
| /* |
| * XImage, flat, depth-buffered, 8-bit PF_LOOKUP triangle. |
| */ |
| |
| static void flat_ci_z_triangle( GLcontext *ctx, GLuint v0, GLuint v1, |
| GLuint v2, GLuint pv ) |
| { |
| WMesaContext wmesa = (WMesaContext) ctx->DriverCtx; |
| #define INTERP_Z 1 |
| #define PIXEL_ADDRESS(X,Y) PIXELADDR1(X,Y) |
| #define PIXEL_TYPE GLubyte |
| #define BYTES_PER_ROW (wmesa->ScanWidth) |
| #define SETUP_CODE \ |
| GLuint index = VB->IndexPtr->data[pv]; \ |
| (*ctx->Driver.Index)( ctx, index ); |
| #define INNER_LOOP( LEFT, RIGHT, Y ) \ |
| { \ |
| GLint i, len = RIGHT-LEFT; \ |
| for (i=0;i<len;i++) { \ |
| GLdepth z = FixedToDepth(ffz); \ |
| if (z < zRow[i]) { \ |
| pRow[i] = index; \ |
| zRow[i] = z; \ |
| } \ |
| ffz += fdzdx; \ |
| } \ |
| } |
| #ifdef __MINGW32__ |
| #include "tritemp.h" |
| #else |
| |
| #ifdef WIN32 |
| // #include "..\tritemp.h" |
| #else |
| #include "tritemp.h" |
| #endif |
| #endif |
| } |
| |
| |
| |
| /* |
| * XImage, smooth, NON-depth-buffered, 8-bit PF_LOOKUP triangle. |
| */ |
| |
| static void smooth_ci_triangle( GLcontext *ctx, GLuint v0, GLuint v1, |
| GLuint v2, GLuint pv ) |
| { |
| WMesaContext wmesa = (WMesaContext) ctx->DriverCtx; |
| #define INTERP_Z 1 |
| #define INTERP_INDEX 1 |
| #define PIXEL_ADDRESS(X,Y) PIXELADDR1(X,Y) |
| #define PIXEL_TYPE GLubyte |
| #define BYTES_PER_ROW (wmesa->ScanWidth) |
| #define INNER_LOOP( LEFT, RIGHT, Y ) \ |
| { \ |
| GLint xx; \ |
| PIXEL_TYPE *pixel = pRow; \ |
| for (xx=LEFT;xx<RIGHT;xx++,pixel++) { \ |
| *pixel = FixedToInt(ffi); \ |
| ffi += fdidx; \ |
| } \ |
| } |
| #ifdef __MINGW32__ |
| #include "tritemp.h" |
| #else |
| |
| #ifdef WIN32 |
| // #include "..\tritemp.h" |
| #else |
| #include "tritemp.h" |
| #endif |
| #endif |
| } |
| |
| |
| /* |
| * XImage, flat, NON-depth-buffered, 8-bit PF_LOOKUP triangle. |
| */ |
| static void flat_ci_triangle( GLcontext *ctx, GLuint v0, GLuint v1, |
| GLuint v2, GLuint pv ) |
| { |
| WMesaContext wmesa = (WMesaContext) ctx->DriverCtx; |
| #define INTERP_Z 1 |
| #define PIXEL_ADDRESS(X,Y) PIXELADDR1(X,Y) |
| #define PIXEL_TYPE GLubyte |
| #define BYTES_PER_ROW (wmesa->ScanWidth) |
| #define SETUP_CODE \ |
| GLuint index = VB->IndexPtr->data[pv]; \ |
| (*ctx->Driver.Index)( ctx, index ); |
| #define INNER_LOOP( LEFT, RIGHT, Y ) \ |
| { \ |
| GLint xx; \ |
| PIXEL_TYPE *pixel = pRow; \ |
| for (xx=LEFT;xx<RIGHT;xx++,pixel++) { \ |
| *pixel = index; \ |
| } \ |
| } |
| #ifdef __MINGW32__ |
| #include "tritemp.h" |
| #else |
| |
| #ifdef WIN32 |
| // #include "..\tritemp.h" |
| #else |
| #include "tritemp.h" |
| #endif |
| #endif |
| } |
| |
| /* |
| * XImage, smooth, depth-buffered, 8-bit, PF_DITHER8 triangle. |
| */ |
| static void smooth_DITHER8_z_triangle( GLcontext *ctx, |
| GLuint v0, GLuint v1, GLuint v2, |
| GLuint pv ) |
| { |
| WMesaContext wmesa = (WMesaContext) ctx->DriverCtx; |
| DITHER_RGB_TO_8BIT_SETUP |
| #define INTERP_Z 1 |
| #define INTERP_RGB 1 |
| #define PIXEL_ADDRESS(X,Y) PIXELADDR1(X,Y) |
| #define PIXEL_TYPE GLubyte |
| #define BYTES_PER_ROW (wmesa->ScanWidth) |
| #define INNER_LOOP( LEFT, RIGHT, Y ) \ |
| { \ |
| GLint i, xx = LEFT, yy = FLIP(Y), len = RIGHT-LEFT; \ |
| for (i=0;i<len;i++,xx++) { \ |
| GLdepth z = FixedToDepth(ffz); \ |
| if (z < zRow[i]) { \ |
| DITHER_RGB_TO_8BIT( FixedToInt(ffr), FixedToInt(ffg), \ |
| FixedToInt(ffb), xx, yy); \ |
| pRow[i] = pixelDithered; \ |
| zRow[i] = z; \ |
| } \ |
| ffr += fdrdx; ffg += fdgdx; ffb += fdbdx; \ |
| ffz += fdzdx; \ |
| } \ |
| } |
| #ifdef __MINGW32__ |
| #include "tritemp.h" |
| #else |
| |
| #ifdef WIN32 |
| // #include "..\tritemp.h" |
| #else |
| #include "tritemp.h" |
| #endif |
| #endif |
| } |
| |
| /* |
| * XImage, flat, depth-buffered, 8-bit PF_DITHER triangle. |
| */ |
| static void flat_DITHER8_z_triangle( GLcontext *ctx, GLuint v0, GLuint v1, |
| GLuint v2, GLuint pv ) |
| { |
| WMesaContext wmesa = (WMesaContext) ctx->DriverCtx; |
| DITHER_RGB_TO_8BIT_SETUP |
| #define INTERP_Z 1 |
| #define PIXEL_ADDRESS(X,Y) PIXELADDR1(X,Y) |
| #define PIXEL_TYPE GLubyte |
| #define BYTES_PER_ROW (wmesa->ScanWidth) |
| |
| #define INNER_LOOP( LEFT, RIGHT, Y ) \ |
| { \ |
| GLint i, xx = LEFT, yy = FLIP(Y), len = RIGHT-LEFT; \ |
| for (i=0;i<len;i++,xx++) { \ |
| GLdepth z = FixedToDepth(ffz); \ |
| if (z < zRow[i]) { \ |
| DITHER_RGB_TO_8BIT( VB->ColorPtr->data[pv][0], \ |
| VB->ColorPtr->data[pv][1], VB->ColorPtr->data[pv][2], xx, yy); \ |
| pRow[i] = pixelDithered; \ |
| zRow[i] = z; \ |
| } \ |
| ffz += fdzdx; \ |
| } \ |
| } |
| #ifdef __MINGW32__ |
| #include "tritemp.h" |
| #else |
| |
| #ifdef WIN32 |
| // #include "..\tritemp.h" |
| #else |
| #include "tritemp.h" |
| #endif |
| #endif |
| } |
| |
| /* |
| * XImage, smooth, NON-depth-buffered, 8-bit PF_DITHER triangle. |
| */ |
| static void smooth_DITHER8_triangle( GLcontext *ctx, GLuint v0, GLuint v1, |
| GLuint v2, GLuint pv ) |
| { |
| WMesaContext wmesa = (WMesaContext) ctx->DriverCtx; |
| DITHER_RGB_TO_8BIT_SETUP |
| #define INTERP_RGB 1 |
| #define PIXEL_ADDRESS(X,Y) PIXELADDR1(X,Y) |
| #define PIXEL_TYPE GLubyte |
| #define BYTES_PER_ROW (wmesa->ScanWidth) |
| #define INNER_LOOP( LEFT, RIGHT, Y ) \ |
| { \ |
| GLint xx, yy = FLIP(Y); \ |
| PIXEL_TYPE *pixel = pRow; \ |
| for (xx=LEFT;xx<RIGHT;xx++,pixel++) { \ |
| DITHER_RGB_TO_8BIT( VB->ColorPtr->data[pv][0], VB->ColorPtr->data[pv][1], VB->ColorPtr->data[pv][2], xx, yy);\ |
| *pixel = pixelDithered; \ |
| ffr += fdrdx; ffg += fdgdx; ffb += fdbdx; \ |
| } \ |
| } |
| #ifdef __MINGW32__ |
| #include "tritemp.h" |
| #else |
| |
| #ifdef WIN32 |
| // #include "..\tritemp.h" |
| #else |
| #include "tritemp.h" |
| #endif |
| #endif |
| } |
| |
| /* |
| * XImage, flat, NON-depth-buffered, 8-bit PF_DITHER triangle. |
| */ |
| |
| static void flat_DITHER8_triangle( GLcontext *ctx, GLuint v0, GLuint v1, |
| GLuint v2, GLuint pv ) |
| { |
| WMesaContext wmesa = (WMesaContext) ctx->DriverCtx; |
| DITHER_RGB_TO_8BIT_SETUP |
| #define PIXEL_ADDRESS(X,Y) PIXELADDR1(X,Y) |
| #define PIXEL_TYPE GLubyte |
| #define BYTES_PER_ROW (wmesa->ScanWidth) |
| |
| #define INNER_LOOP( LEFT, RIGHT, Y ) \ |
| { \ |
| GLint xx, yy = FLIP(Y); \ |
| PIXEL_TYPE *pixel = pRow; \ |
| for (xx=LEFT;xx<RIGHT;xx++,pixel++) { \ |
| DITHER_RGB_TO_8BIT( VB->ColorPtr->data[pv][0], \ |
| VB->ColorPtr->data[pv][1], VB->ColorPtr->data[pv][2], xx, yy); \ |
| *pixel = pixelDithered; \ |
| } \ |
| } |
| #ifdef __MINGW32__ |
| #include "tritemp.h" |
| #else |
| |
| #ifdef WIN32 |
| // #include "..\tritemp.h" |
| #else |
| #include "tritemp.h" |
| #endif |
| #endif |
| } |
| |
| #endif |
| /************** END DEAD TRIANGLE CODE ***********************/ |
| |
| static triangle_func choose_triangle_function( GLcontext *ctx ) |
| { |
| #if 0 |
| WMesaContext wmesa = (WMesaContext) ctx->DriverCtx; |
| int depth = wmesa->cColorBits; |
| |
| if (ctx->Polygon.SmoothFlag) return NULL; |
| if (ctx->Texture._EnabledUnits) return NULL; |
| if (!wmesa->db_flag) return NULL; |
| if (ctx->swrast->_RasterMask & MULTI_DRAW_BIT) return NULL; |
| |
| /*if (wmesa->xm_buffer->buffer==XIMAGE)*/ { |
| if ( ctx->Light.ShadeModel==GL_SMOOTH |
| && ctx->_RasterMask==DEPTH_BIT |
| && ctx->Depth.Func==GL_LESS |
| && ctx->Depth.Mask==GL_TRUE |
| && ctx->Polygon.StippleFlag==GL_FALSE) { |
| switch (wmesa->pixelformat) { |
| case PF_8A8B8G8R: |
| return smooth_8A8B8G8R_z_triangle; |
| case PF_8R8G8B: |
| return smooth_8R8G8B_z_triangle; |
| case PF_5R6G5B: |
| return smooth_5R6G5B_z_triangle; |
| case PF_DITHER8: |
| return smooth_DITHER8_z_triangle; |
| case PF_INDEX8: |
| return smooth_ci_z_triangle; |
| default: |
| return NULL; |
| } |
| } |
| if ( ctx->Light.ShadeModel==GL_FLAT |
| && ctx->_RasterMask==DEPTH_BIT |
| && ctx->Depth.Func==GL_LESS |
| && ctx->Depth.Mask==GL_TRUE |
| && ctx->Polygon.StippleFlag==GL_FALSE) { |
| switch (wmesa->pixelformat) { |
| case PF_8A8B8G8R: |
| return flat_8A8B8G8R_z_triangle; |
| case PF_8R8G8B: |
| return flat_8R8G8B_z_triangle; |
| case PF_5R6G5B: |
| return flat_5R6G5B_z_triangle; |
| case PF_DITHER8: |
| return flat_DITHER8_z_triangle; |
| case PF_INDEX8: |
| return flat_ci_z_triangle; |
| default: |
| return NULL; |
| } |
| } |
| if ( ctx->_RasterMask==0 /* no depth test */ |
| && ctx->Light.ShadeModel==GL_SMOOTH |
| && ctx->Polygon.StippleFlag==GL_FALSE) { |
| switch (wmesa->pixelformat) { |
| case PF_8A8B8G8R: |
| return smooth_8A8B8G8R_triangle; |
| case PF_8R8G8B: |
| return smooth_8R8G8B_triangle; |
| case PF_5R6G5B: |
| return smooth_5R6G5B_triangle; |
| case PF_DITHER8: |
| return smooth_DITHER8_triangle; |
| case PF_INDEX8: |
| return smooth_ci_triangle; |
| default: |
| return NULL; |
| } |
| } |
| |
| if ( ctx->_RasterMask==0 /* no depth test */ |
| && ctx->Light.ShadeModel==GL_FLAT |
| && ctx->Polygon.StippleFlag==GL_FALSE) { |
| switch (wmesa->pixelformat) { |
| case PF_8A8B8G8R: |
| return flat_8A8B8G8R_triangle; |
| case PF_8R8G8B: |
| return flat_8R8G8B_triangle; |
| case PF_5R6G5B: |
| return flat_5R6G5B_triangle; |
| case PF_DITHER8: |
| return flat_DITHER8_triangle; |
| case PF_INDEX8: |
| return flat_ci_triangle; |
| default: |
| return NULL; |
| } |
| } |
| |
| return NULL; |
| } |
| #endif |
| } |
| |
| /* |
| * Define a new viewport and reallocate auxillary buffers if the size of |
| * the window (color buffer) has changed. |
| */ |
| void WMesaViewport( GLcontext *ctx, |
| GLint x, GLint y, GLsizei width, GLsizei height ) |
| { |
| assert(0); /* I don't think that this is being used. */ |
| #if 0 |
| /* Save viewport */ |
| ctx->Viewport.X = x; |
| ctx->Viewport.Width = width; |
| ctx->Viewport.Y = y; |
| ctx->Viewport.Height = height; |
| |
| /* compute scale and bias values */ |
| /* Pre-Keith 3.1 changes |
| ctx->Viewport.Map.m[Sx] = (GLfloat) width / 2.0F; |
| ctx->Viewport.Map.m[Tx] = ctx->Viewport.Sx + x; |
| ctx->Viewport.Map.m[Sy] = (GLfloat) height / 2.0F; |
| ctx->Viewport.Map.m[Ty] = ctx->Viewport.Sy + y; |
| */ |
| ctx->Viewport.WindowMap.m[MAT_SX] = (GLfloat) width / 2.0F; |
| ctx->Viewport.WindowMap.m[MAT_TX] = ctx->Viewport.WindowMap.m[MAT_SX] + x; |
| ctx->Viewport.WindowMap.m[MAT_SY] = (GLfloat) height / 2.0F; |
| ctx->Viewport.WindowMap.m[MAT_TY] = ctx->Viewport.WindowMap.m[MAT_SY] + y; |
| #endif |
| } |