Index: boot/bootdata/hivesft.inf =================================================================== --- boot/bootdata/hivesft.inf (revision 58564) +++ boot/bootdata/hivesft.inf (working copy) @@ -219,12 +219,12 @@ HKLM,"SOFTWARE\Microsoft\Windows NT\CurrentVersion\MCI Extensions","wmx",0x00000002,"MPEGVideo" HKLM,"SOFTWARE\Microsoft\Windows NT\CurrentVersion\MCI Extensions","wvx",0x00000002,"MPEGVideo" -; Mesa OpenGL Driver -HKLM,"SOFTWARE\Microsoft\Windows NT\CurrentVersion\OpenGLDrivers","DefaultDriver",0x00000000,"Mesa" -HKLM,"SOFTWARE\Microsoft\Windows NT\CurrentVersion\OpenGLDrivers\Mesa","Version",0x00010001,0x00000002 -HKLM,"SOFTWARE\Microsoft\Windows NT\CurrentVersion\OpenGLDrivers\Mesa","Dll",0x00000000,"mesa32" -HKLM,"SOFTWARE\Microsoft\Windows NT\CurrentVersion\OpenGLDrivers\Mesa","DriverVersion",0x00010001,0x00000001 -HKLM,"SOFTWARE\Microsoft\Windows NT\CurrentVersion\OpenGLDrivers\Mesa","Flags",0x00010001,0x00000001 +; ; Mesa OpenGL Driver +; HKLM,"SOFTWARE\Microsoft\Windows NT\CurrentVersion\OpenGLDrivers","DefaultDriver",0x00000000,"Mesa" +; HKLM,"SOFTWARE\Microsoft\Windows NT\CurrentVersion\OpenGLDrivers\Mesa","Version",0x00010001,0x00000002 +; HKLM,"SOFTWARE\Microsoft\Windows NT\CurrentVersion\OpenGLDrivers\Mesa","Dll",0x00000000,"mesa32" +; HKLM,"SOFTWARE\Microsoft\Windows NT\CurrentVersion\OpenGLDrivers\Mesa","DriverVersion",0x00010001,0x00000001 +; HKLM,"SOFTWARE\Microsoft\Windows NT\CurrentVersion\OpenGLDrivers\Mesa","Flags",0x00010001,0x00000001 ; User Profile List HKLM,"SOFTWARE\Microsoft\Windows NT\CurrentVersion\ProfileList",,0x00000012 Index: cmake/baseaddress.cmake =================================================================== --- cmake/baseaddress.cmake (revision 58564) +++ cmake/baseaddress.cmake (working copy) @@ -41,7 +41,7 @@ set(baseaddress_cabinet 0x75c20000) set(baseaddress_dsound 0x75ba0000) set(baseaddress_glu32 0x75aa0000) -set(baseaddress_opengl32 0x75a70000) +# set(baseaddress_opengl32 0x75a70000) set(baseaddress_riched20 0x759e0000) set(baseaddress_smdll 0x759c0000) set(baseaddress_userenv 0x75970000) Index: dll/opengl/CMakeLists.txt =================================================================== --- dll/opengl/CMakeLists.txt (revision 58564) +++ dll/opengl/CMakeLists.txt (working copy) @@ -1,3 +1,3 @@ add_subdirectory(glu32) -add_subdirectory(mesa) +#add_subdirectory(mesa) add_subdirectory(opengl32) Index: dll/opengl/opengl32/CMakeLists.txt =================================================================== --- dll/opengl/opengl32/CMakeLists.txt (revision 58564) +++ dll/opengl/opengl32/CMakeLists.txt (working copy) @@ -5,18 +5,27 @@ add_definitions( -D_GDI32_ # prevent gl* being declared __declspec(dllimport) in MS headers -DBUILD_GL32 # declare gl* as __declspec(dllexport) in Mesa headers + -DWIN32_THREADS ) +include_directories(BEFORE mesa) + +add_subdirectory(mesa) + list(APPEND SOURCE font.c gl.c opengl32.c + # sw_mesa.c wgl.c ${CMAKE_CURRENT_BINARY_DIR}/opengl32_stubs.c - ${CMAKE_CURRENT_BINARY_DIR}/opengl32.def) + ${CMAKE_CURRENT_BINARY_DIR}/opengl32.def +) add_library(opengl32 SHARED ${SOURCE}) +target_link_libraries(opengl32 wine mesa) + set_module_type(opengl32 win32dll UNICODE) add_importlibs(opengl32 @@ -24,7 +33,6 @@ gdi32 user32 advapi32 - glu32 kernel32 ntdll) Index: dll/opengl/opengl32/font.c =================================================================== --- dll/opengl/opengl32/font.c (revision 58564) +++ dll/opengl/opengl32/font.c (working copy) @@ -1,1155 +1,565 @@ -/**************************************************************************** -* 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. -****************************************************************************/ +/* Window-specific OpenGL functions implementation. + * + * Copyright (c) 1999 Lionel Ulmer + * Copyright (c) 2005 Raphael Junqueira + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ -#include "opengl32.h" +#include #include +#include -#define LINE_BUF_QUANT 4000 -#define VERT_BUF_QUANT 4000 +#include +#include +#include -static HFONT hNewFont, hOldFont; -static FLOAT ScaleFactor; -static FLOAT* LineBuf; -static DWORD LineBufSize; -static DWORD LineBufIndex; -static FLOAT* VertBuf; -static DWORD VertBufSize; -static DWORD VertBufIndex; -static GLenum TessErrorOccurred; +#include "wine/debug.h" -/***************************************************************************** -* AppendToLineBuf -* -* Appends one floating-point value to the global LineBuf array. Return value -* is non-zero for success, zero for failure. -*****************************************************************************/ +WINE_DEFAULT_DEBUG_CHANNEL(wgl); -INT AppendToLineBuf(FLOAT value) +/*********************************************************************** + * wglUseFontBitmaps_common + */ +static BOOL wglUseFontBitmaps_common( HDC hdc, DWORD first, DWORD count, DWORD listBase, BOOL unicode ) { - if (LineBufIndex >= LineBufSize) - { - FLOAT* f; - LineBufSize += LINE_BUF_QUANT; + GLYPHMETRICS gm; + unsigned int glyph, size = 0; + void *bitmap = NULL, *gl_bitmap = NULL; + int org_alignment; + BOOL ret = TRUE; - f = (FLOAT*) HeapReAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, LineBuf, (LineBufSize) * sizeof(FLOAT)); - if (!f) - return 0; - LineBuf = f; - } - LineBuf[LineBufIndex++] = value; - return 1; -} + glGetIntegerv(GL_UNPACK_ALIGNMENT, &org_alignment); + glPixelStorei(GL_UNPACK_ALIGNMENT, 4); -/***************************************************************************** -* AppendToVertBuf -* -* Appends one floating-point value to the global VertBuf array. Return value -* is non-zero for success, zero for failure. -* -* Note that we can't realloc this one, because the tessellator is using -* pointers into it. -*****************************************************************************/ + for (glyph = first; glyph < first + count; glyph++) { + static const MAT2 identity = { {0,1},{0,0},{0,0},{0,1} }; + unsigned int needed_size, height, width, width_int; -INT AppendToVertBuf(FLOAT value) -{ - if (VertBufIndex >= VertBufSize) - return 0; - VertBuf[VertBufIndex++] = value; - return 1; -} + if (unicode) + needed_size = GetGlyphOutlineW(hdc, glyph, GGO_BITMAP, &gm, 0, NULL, &identity); + else + needed_size = GetGlyphOutlineA(hdc, glyph, GGO_BITMAP, &gm, 0, NULL, &identity); -/***************************************************************************** -* GetWord -* -* Fetch the next 16-bit word from a little-endian byte stream, and increment -* the stream pointer to the next unscanned byte. -*****************************************************************************/ + TRACE("Glyph: %3d / List: %d size %d\n", glyph, listBase, needed_size); + if (needed_size == GDI_ERROR) { + ret = FALSE; + break; + } -LONG GetWord(UCHAR** p) -{ - LONG value; + if (needed_size > size) { + size = needed_size; + HeapFree(GetProcessHeap(), 0, bitmap); + HeapFree(GetProcessHeap(), 0, gl_bitmap); + bitmap = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, size); + gl_bitmap = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, size); + } + if (unicode) + ret = (GetGlyphOutlineW(hdc, glyph, GGO_BITMAP, &gm, size, bitmap, &identity) != GDI_ERROR); + else + ret = (GetGlyphOutlineA(hdc, glyph, GGO_BITMAP, &gm, size, bitmap, &identity) != GDI_ERROR); + if (!ret) break; - value = ((*p)[1] << 8) + (*p)[0]; - *p += 2; - return value; -} + if (TRACE_ON(wgl)) { + unsigned int bitmask; + unsigned char *bitmap_ = bitmap; -/***************************************************************************** -* GetDWord -* -* Fetch the next 32-bit word from a little-endian byte stream, and increment -* the stream pointer to the next unscanned byte. -*****************************************************************************/ + TRACE(" - bbox: %d x %d\n", gm.gmBlackBoxX, gm.gmBlackBoxY); + TRACE(" - origin: (%d, %d)\n", gm.gmptGlyphOrigin.x, gm.gmptGlyphOrigin.y); + TRACE(" - increment: %d - %d\n", gm.gmCellIncX, gm.gmCellIncY); + if (needed_size != 0) { + TRACE(" - bitmap:\n"); + for (height = 0; height < gm.gmBlackBoxY; height++) { + TRACE(" "); + for (width = 0, bitmask = 0x80; width < gm.gmBlackBoxX; width++, bitmask >>= 1) { + if (bitmask == 0) { + bitmap_ += 1; + bitmask = 0x80; + } + if (*bitmap_ & bitmask) + TRACE("*"); + else + TRACE(" "); + } + bitmap_ += (4 - ((UINT_PTR)bitmap_ & 0x03)); + TRACE("\n"); + } + } + } -LONG GetDWord(UCHAR** p) -{ - LONG value; + /* In OpenGL, the bitmap is drawn from the bottom to the top... So we need to invert the + * glyph for it to be drawn properly. + */ + if (needed_size != 0) { + width_int = (gm.gmBlackBoxX + 31) / 32; + for (height = 0; height < gm.gmBlackBoxY; height++) { + for (width = 0; width < width_int; width++) { + ((int *) gl_bitmap)[(gm.gmBlackBoxY - height - 1) * width_int + width] = + ((int *) bitmap)[height * width_int + width]; + } + } + } - value = ((*p)[3] << 24) + ((*p)[2] << 16) + ((*p)[1] << 8) + (*p)[0]; - *p += 4; - return value; + glNewList(listBase++, GL_COMPILE); + if (needed_size != 0) { + glBitmap(gm.gmBlackBoxX, gm.gmBlackBoxY, + 0 - gm.gmptGlyphOrigin.x, (int) gm.gmBlackBoxY - gm.gmptGlyphOrigin.y, + gm.gmCellIncX, gm.gmCellIncY, + gl_bitmap); + } else { + /* This is the case of 'empty' glyphs like the space character */ + glBitmap(0, 0, 0, 0, gm.gmCellIncX, gm.gmCellIncY, NULL); + } + glEndList(); + } + + glPixelStorei(GL_UNPACK_ALIGNMENT, org_alignment); + HeapFree(GetProcessHeap(), 0, bitmap); + HeapFree(GetProcessHeap(), 0, gl_bitmap); + return ret; } -/***************************************************************************** -* GetFixed -* -* Fetch the next 32-bit fixed-point value from a little-endian byte stream, -* convert it to floating-point, and increment the stream pointer to the next -* unscanned byte. -*****************************************************************************/ -double GetFixed(UCHAR** p) +/*********************************************************************** + * wglUseFontBitmapsA (OPENGL32.@) + */ +BOOL WINAPI wglUseFontBitmapsA(HDC hdc, DWORD first, DWORD count, DWORD listBase) { - LONG hiBits, loBits; - double value; - - loBits = GetWord(p); - hiBits = GetWord(p); - value = (double) ((hiBits << 16) | loBits) / 65536.0; - - return value * ScaleFactor; + return wglUseFontBitmaps_common( hdc, first, count, listBase, FALSE ); } - -/***************************************************************************** -** -** InvertGlyphBitmap. -** -** Invert the bitmap so that it suits OpenGL's representation. -** Each row starts on a double word boundary. -** -*****************************************************************************/ - -VOID InvertGlyphBitmap(INT w, INT h, DWORD *fptr, DWORD *tptr) +/*********************************************************************** + * wglUseFontBitmapsW (OPENGL32.@) + */ +BOOL WINAPI wglUseFontBitmapsW(HDC hdc, DWORD first, DWORD count, DWORD listBase) { - INT dWordsInRow = (w+31)/32; - INT i, j; - - if (w <= 0 || h <= 0) { - return; - } - - tptr += ((h-1)*dWordsInRow); - for (i = 0; i < h; i++) { - for (j = 0; j < dWordsInRow; j++) { - *(tptr + j) = *(fptr + j); - } - tptr -= dWordsInRow; - fptr += dWordsInRow; - } + return wglUseFontBitmaps_common( hdc, first, count, listBase, TRUE ); } -/***************************************************************************** -* CreateHighResolutionFont -* -* Gets metrics for the current font and creates an equivalent font -* scaled to the design units of the font. -* -*****************************************************************************/ +/* FIXME: should probably have a glu.h header */ -HFONT CreateHighResolutionFont(HDC hDC) -{ - UINT otmSize; - OUTLINETEXTMETRIC *otm; - LONG fontHeight, fontWidth, fontUnits; - LOGFONTW logFont, logFontFaceName; +typedef struct GLUtesselator GLUtesselator; +typedef void (WINAPI *_GLUfuncptr)(void); - otmSize = GetOutlineTextMetricsW(hDC, 0, NULL); - if (!otmSize) - return NULL; +#define GLU_TESS_BEGIN 100100 +#define GLU_TESS_VERTEX 100101 +#define GLU_TESS_END 100102 - otm = (OUTLINETEXTMETRIC *) HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, otmSize); - if (!otm) - return NULL; +static GLUtesselator * (WINAPI *pgluNewTess)(void); +static void (WINAPI *pgluDeleteTess)(GLUtesselator *tess); +static void (WINAPI *pgluTessNormal)(GLUtesselator *tess, GLdouble x, GLdouble y, GLdouble z); +static void (WINAPI *pgluTessBeginPolygon)(GLUtesselator *tess, void *polygon_data); +static void (WINAPI *pgluTessEndPolygon)(GLUtesselator *tess); +static void (WINAPI *pgluTessCallback)(GLUtesselator *tess, GLenum which, _GLUfuncptr fn); +static void (WINAPI *pgluTessBeginContour)(GLUtesselator *tess); +static void (WINAPI *pgluTessEndContour)(GLUtesselator *tess); +static void (WINAPI *pgluTessVertex)(GLUtesselator *tess, GLdouble *location, GLvoid* data); - otm->otmSize = otmSize; - if (!GetOutlineTextMetricsW(hDC, otmSize, otm)) - return NULL; - - GetObjectW(GetCurrentObject(hDC, OBJ_FONT), sizeof(logFontFaceName), &logFontFaceName); - - fontHeight = otm->otmTextMetrics.tmHeight - - otm->otmTextMetrics.tmInternalLeading; - fontWidth = otm->otmTextMetrics.tmAveCharWidth; - fontUnits = (LONG) otm->otmEMSquare; - - ScaleFactor = 1.0F / (FLOAT) fontUnits; - - logFont.lfHeight = - ((LONG) fontUnits); - logFont.lfWidth = (LONG)((FLOAT) (fontWidth * fontUnits) / (FLOAT) fontHeight); - logFont.lfEscapement = 0; - logFont.lfOrientation = 0; - logFont.lfWeight = otm->otmTextMetrics.tmWeight; - logFont.lfItalic = otm->otmTextMetrics.tmItalic; - logFont.lfUnderline = otm->otmTextMetrics.tmUnderlined; - logFont.lfStrikeOut = otm->otmTextMetrics.tmStruckOut; - logFont.lfCharSet = otm->otmTextMetrics.tmCharSet; - logFont.lfOutPrecision = OUT_OUTLINE_PRECIS; - logFont.lfClipPrecision = CLIP_DEFAULT_PRECIS; - logFont.lfQuality = DEFAULT_QUALITY; - logFont.lfPitchAndFamily = - otm->otmTextMetrics.tmPitchAndFamily & 0xf0; - wcscpy(logFont.lfFaceName, logFontFaceName.lfFaceName); - - hNewFont = CreateFontIndirectW(&logFont); - - HeapFree(GetProcessHeap(), 0, otm); - - return hNewFont; -} - -/***************************************************************************** -* MakeLinesFromArc -* -* Subdivides one arc of a quadratic spline until the chordal deviation -* tolerance requirement is met, then places the resulting set of line -* segments in the global LineBuf. -*****************************************************************************/ -INT MakeLinesFromArc(FLOAT x0, FLOAT y0, FLOAT x1, FLOAT y1, FLOAT x2, FLOAT y2, - DWORD vertexCountIndex, FLOAT chordalDeviationSquared) +static HMODULE load_libglu(void) { - FLOAT x01; - FLOAT y01; - FLOAT x12; - FLOAT y12; - FLOAT midPointX; - FLOAT midPointY; - FLOAT deltaX; - FLOAT deltaY; + static const WCHAR glu32W[] = {'g','l','u','3','2','.','d','l','l',0}; + static int already_loaded; + static HMODULE module; - /* - * Calculate midpoint of the curve by de Casteljau: - */ - x01 = 0.5F * (x0 + x1); - y01 = 0.5F * (y0 + y1); - x12 = 0.5F * (x1 + x2); - y12 = 0.5F * (y1 + y2); - midPointX = 0.5F * (x01 + x12); - midPointY = 0.5F * (y01 + y12); + if (already_loaded) return module; + already_loaded = 1; - - /* - * Estimate chordal deviation by the distance from the midpoint - * of the curve to its non-pointpolated control point. If this - * distance is greater than the specified chordal deviation - * constraint, then subdivide. Otherwise, generate polylines - * from the three control points. - */ - deltaX = midPointX - x1; - deltaY = midPointY - y1; - - if (deltaX * deltaX + deltaY * deltaY > chordalDeviationSquared) + TRACE("Trying to load GLU library\n"); + module = LoadLibraryW( glu32W ); + if (!module) { - MakeLinesFromArc( x0, y0, - x01, y01, - midPointX, midPointY, - vertexCountIndex, - chordalDeviationSquared); - - MakeLinesFromArc( midPointX, midPointY, - x12, y12, - x2, y2, - vertexCountIndex, - chordalDeviationSquared); + WARN("Failed to load glu32\n"); + return NULL; } - else - { - /* - * The "pen" is already at (x0, y0), so we don't need to - * add that point to the LineBuf. - */ - if (!AppendToLineBuf(x1) - || !AppendToLineBuf(y1) - || !AppendToLineBuf(x2) - || !AppendToLineBuf(y2)) - return 0; - LineBuf[vertexCountIndex] += 2.0F; - } +#define LOAD_FUNCPTR(f) p##f = (void *)GetProcAddress( module, #f ) + LOAD_FUNCPTR(gluNewTess); + LOAD_FUNCPTR(gluDeleteTess); + LOAD_FUNCPTR(gluTessBeginContour); + LOAD_FUNCPTR(gluTessNormal); + LOAD_FUNCPTR(gluTessBeginPolygon); + LOAD_FUNCPTR(gluTessCallback); + LOAD_FUNCPTR(gluTessEndContour); + LOAD_FUNCPTR(gluTessEndPolygon); + LOAD_FUNCPTR(gluTessVertex); +#undef LOAD_FUNCPTR + return module; +} - return 1; +static void fixed_to_double(POINTFX fixed, UINT em_size, GLdouble vertex[3]) +{ + vertex[0] = (fixed.x.value + (GLdouble)fixed.x.fract / (1 << 16)) / em_size; + vertex[1] = (fixed.y.value + (GLdouble)fixed.y.fract / (1 << 16)) / em_size; + vertex[2] = 0.0; } -/***************************************************************************** -* MakeLinesFromTTQSpline -* -* Converts points from the poly quadratic spline in a TT_PRIM_QSPLINE -* structure to polyline points in the global LineBuf. -*****************************************************************************/ - -INT MakeLinesFromTTQSpline( UCHAR** pp, DWORD vertexCountIndex, WORD pointCount, FLOAT chordalDeviation) +static void WINAPI tess_callback_vertex(GLvoid *vertex) { - FLOAT x0, y0, x1, y1, x2, y2; - WORD point; - - /* - * Process each of the non-pointpolated points in the outline. - * To do this, we need to generate two pointpolated points (the - * start and end of the arc) for each non-pointpolated point. - * The first pointpolated point is always the one most recently - * stored in LineBuf, so we just extract it from there. The - * second pointpolated point is either the average of the next - * two points in the QSpline, or the last point in the QSpline - * if only one remains. - */ - for (point = 0; point < pointCount - 1; ++point) - { - x0 = LineBuf[LineBufIndex - 2]; - y0 = LineBuf[LineBufIndex - 1]; - - x1 = (FLOAT) GetFixed(pp); - y1 = (FLOAT) GetFixed(pp); - - if (point == pointCount - 2) - { - /* - * This is the last arc in the QSpline. The final - * point is the end of the arc. - */ - x2 = (FLOAT) GetFixed(pp); - y2 = (FLOAT) GetFixed(pp); - } - else - { - /* - * Peek at the next point in the input to compute - * the end of the arc: - */ - x2 = 0.5F * (x1 + (FLOAT) GetFixed(pp)); - y2 = 0.5F * (y1 + (FLOAT) GetFixed(pp)); - /* - * Push the point back onto the input so it will - * be reused as the next off-curve point: - */ - *pp -= 8; - } - - if (!MakeLinesFromArc( x0, y0, - x1, y1, - x2, y2, - vertexCountIndex, - chordalDeviation * chordalDeviation)) - return 0; - } - - return 1; + GLdouble *dbl = vertex; + TRACE("%f, %f, %f\n", dbl[0], dbl[1], dbl[2]); + glVertex3dv(vertex); } -/***************************************************************************** -* MakeLinesFromTTLine -* -* Converts points from the polyline in a TT_PRIM_LINE structure to -* equivalent points in the global LineBuf. -*****************************************************************************/ -INT MakeLinesFromTTLine(UCHAR** pp, DWORD vertexCountIndex, WORD pointCount) +static void WINAPI tess_callback_begin(GLenum which) { - /* - * Just copy the line segments into the line buffer (converting - * type as we go): - */ - LineBuf[vertexCountIndex] += pointCount; - while (pointCount--) - { - if (!AppendToLineBuf((FLOAT) GetFixed(pp)) /* X coord */ - || !AppendToLineBuf((FLOAT) GetFixed(pp))) /* Y coord */ - return 0; - } - - return 1; + TRACE("%d\n", which); + glBegin(which); } -/***************************************************************************** -* MakeLinesFromTTPolyCurve -* -* Converts the lines and splines in a single TTPOLYCURVE structure to points -* in the global LineBuf. -*****************************************************************************/ - -INT MakeLinesFromTTPolycurve(UCHAR** pp, DWORD vertexCountIndex, FLOAT chordalDeviation) +static void WINAPI tess_callback_end(void) { - WORD type; - WORD pointCount; - - /* - * Pick up the relevant fields of the TTPOLYCURVE structure: - */ - type = (WORD) GetWord(pp); - pointCount = (WORD) GetWord(pp); - - /* - * Convert the "curve" to line segments: - */ - if (type == TT_PRIM_LINE) - return MakeLinesFromTTLine( pp, - vertexCountIndex, - pointCount); - else if (type == TT_PRIM_QSPLINE) - return MakeLinesFromTTQSpline( pp, - vertexCountIndex, - pointCount, - chordalDeviation); - else - return 0; + TRACE("\n"); + glEnd(); } -/***************************************************************************** -* MakeLinesFromTTPolygon -* -* Converts a TTPOLYGONHEADER and its associated curve structures into a -* single polyline loop in the global LineBuf. -*****************************************************************************/ +typedef struct _bezier_vector { + GLdouble x; + GLdouble y; +} bezier_vector; -INT MakeLinesFromTTPolygon(UCHAR** pp, FLOAT chordalDeviation) +static double bezier_deviation_squared(const bezier_vector *p) { - DWORD polySize; - UCHAR* polyStart; - DWORD vertexCountIndex; + bezier_vector deviation; + bezier_vector vertex; + bezier_vector base; + double base_length; + double dot; - /* - * Record where the polygon data begins, and where the loop's - * vertex count resides: - */ - polyStart = *pp; - vertexCountIndex = LineBufIndex; - if (!AppendToLineBuf(0.0F)) - return 0; + vertex.x = (p[0].x + p[1].x*2 + p[2].x)/4 - p[0].x; + vertex.y = (p[0].y + p[1].y*2 + p[2].y)/4 - p[0].y; - /* - * Extract relevant data from the TTPOLYGONHEADER: - */ - polySize = GetDWord(pp); - if (GetDWord(pp) != TT_POLYGON_TYPE) /* polygon type */ - return 0; - if (!AppendToLineBuf((FLOAT) GetFixed(pp))) /* first X coord */ - return 0; - if (!AppendToLineBuf((FLOAT) GetFixed(pp))) /* first Y coord */ - return 0; - LineBuf[vertexCountIndex] += 1.0F; + base.x = p[2].x - p[0].x; + base.y = p[2].y - p[0].y; - /* - * Process each of the TTPOLYCURVE structures in the polygon: - */ - while (*pp < polyStart + polySize) - if (!MakeLinesFromTTPolycurve( pp, - vertexCountIndex, - chordalDeviation)) - return 0; + base_length = sqrt(base.x*base.x + base.y*base.y); + base.x /= base_length; + base.y /= base_length; - return 1; -} + dot = base.x*vertex.x + base.y*vertex.y; + dot = min(max(dot, 0.0), base_length); + base.x *= dot; + base.y *= dot; -/***************************************************************************** -* TessVertexOut -* -* Used by tessellator to handle output vertexes. -*****************************************************************************/ + deviation.x = vertex.x-base.x; + deviation.y = vertex.y-base.y; -VOID CALLBACK TessVertexOutData(FLOAT p[3], GLfloat *pz) -{ - GLfloat v[3]; - v[0] = (GLfloat) p[0]; - v[1] = (GLfloat) p[1]; - v[2] = *pz; - glVertex3fv(v); + return deviation.x*deviation.x + deviation.y*deviation.y; } -/***************************************************************************** -* TessCombine -* -* Used by tessellator to handle self-pointsecting contours and degenerate -* geometry. -*****************************************************************************/ -VOID CALLBACK TessCombine(double coords[3], VOID* vertex_data[4], FLOAT weight[4], VOID** outData) +static int bezier_approximate(const bezier_vector *p, bezier_vector *points, FLOAT deviation) { - if (!AppendToVertBuf((FLOAT) coords[0]) - || !AppendToVertBuf((FLOAT) coords[1]) - || !AppendToVertBuf((FLOAT) coords[2])) - TessErrorOccurred = GL_OUT_OF_MEMORY; + bezier_vector first_curve[3]; + bezier_vector second_curve[3]; + bezier_vector vertex; + int total_vertices; - *outData = VertBuf + (VertBufIndex - 3); -} + if(bezier_deviation_squared(p) <= deviation*deviation) + { + if(points) + *points = p[2]; + return 1; + } -/***************************************************************************** -* TessError -* -* Saves the last tessellator error code in the global TessErrorOccurred. -*****************************************************************************/ + vertex.x = (p[0].x + p[1].x*2 + p[2].x)/4; + vertex.y = (p[0].y + p[1].y*2 + p[2].y)/4; -VOID CALLBACK TessError(GLenum error) -{ - TessErrorOccurred = error; -} + first_curve[0] = p[0]; + first_curve[1].x = (p[0].x + p[1].x)/2; + first_curve[1].y = (p[0].y + p[1].y)/2; + first_curve[2] = vertex; -/***************************************************************************** -* MakeLinesFromGlyph -* -* Converts the outline of a glyph from the TTPOLYGON format to a simple -* array of floating-point values containing one or more loops. -* -* The first element of the output array is a count of the number of loops. -* The loop data follows this count. Each loop consists of a count of the -* number of vertices it contains, followed by the vertices. Each vertex -* is an X and Y coordinate. For example, a single triangle might be -* described by this array: -* -* 1., 3., 0., 0., 1., 0., 0., 1. -* ^ ^ ^ ^ ^ ^ ^ ^ -* #loops #verts x1 y1 x2 y2 x3 y3 -* -* A two-loop glyph would look like this: -* -* 2., 3., 0.,0., 1.,0., 0.,1., 3., .2,.2, .4,.2, .2,.4 -* -* Line segments from the TTPOLYGON are transferred to the output array in -* the obvious way. Quadratic splines in the TTPOLYGON are converted to -* collections of line segments -*****************************************************************************/ + second_curve[0] = vertex; + second_curve[1].x = (p[2].x + p[1].x)/2; + second_curve[1].y = (p[2].y + p[1].y)/2; + second_curve[2] = p[2]; -INT MakeLinesFromGlyph(UCHAR* glyphBuf, DWORD glyphSize, FLOAT chordalDeviation) -{ - UCHAR* p; - INT status = 0; - - /* - * Pick up all the polygons (aka loops) that make up the glyph: - */ - if (!AppendToLineBuf(0.0F)) /* loop count at LineBuf[0] */ - goto exit; - - p = glyphBuf; - while (p < glyphBuf + glyphSize) - { - if (!MakeLinesFromTTPolygon(&p, chordalDeviation)) - goto exit; - LineBuf[0] += 1.0F; /* increment loop count */ - } - - status = 1; - -exit: - return status; + total_vertices = bezier_approximate(first_curve, points, deviation); + if(points) + points += total_vertices; + total_vertices += bezier_approximate(second_curve, points, deviation); + return total_vertices; } -/***************************************************************************** -* DrawGlyph -* -* Converts the outline of a glyph to OpenGL drawing primitives, tessellating -* as needed, and then draws the glyph. Tessellation of the quadratic splines -* in the outline is controlled by "chordalDeviation", and the drawing -* primitives (lines or polygons) are selected by "format". -* -* Return value is nonzero for success, zero for failure. -* -* Does not check for OpenGL errors, so if the caller needs to know about them, -* it should call glGetError(). -*****************************************************************************/ - -INT DrawGlyph(UCHAR* glyphBuf, DWORD glyphSize, FLOAT chordalDeviation, FLOAT extrusion, INT format) +/*********************************************************************** + * wglUseFontOutlines_common + */ +static BOOL wglUseFontOutlines_common(HDC hdc, + DWORD first, + DWORD count, + DWORD listBase, + FLOAT deviation, + FLOAT extrusion, + int format, + LPGLYPHMETRICSFLOAT lpgmf, + BOOL unicode) { - INT status = 0; - FLOAT* p; - DWORD loop; - DWORD point; - GLUtesselator* tess = NULL; + UINT glyph; + const MAT2 identity = {{0,1},{0,0},{0,0},{0,1}}; + GLUtesselator *tess = NULL; + LOGFONTW lf; + HFONT old_font, unscaled_font; + UINT em_size = 1024; + RECT rc; - /* - * Initialize the global buffer into which we place the outlines: - */ - LineBuf = (FLOAT*) HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, (LINE_BUF_QUANT) * sizeof(FLOAT)); + TRACE("(%p, %d, %d, %d, %f, %f, %d, %p, %s)\n", hdc, first, count, + listBase, deviation, extrusion, format, lpgmf, unicode ? "W" : "A"); - if(!LineBuf) - goto exit; + if(deviation <= 0.0) + deviation = 1.0/em_size; - LineBufSize = LINE_BUF_QUANT; - LineBufIndex = 0; - - /* - * Convert the glyph outlines to a set of polyline loops. - * (See MakeLinesFromGlyph() for the format of the loop data - * structure.) - */ - if (!MakeLinesFromGlyph(glyphBuf, glyphSize, chordalDeviation)) - goto exit; - p = LineBuf; - - - /* - * Now draw the loops in the appropriate format: - */ - if (format == WGL_FONT_LINES) + if(format == WGL_FONT_POLYGONS) { - /* - * This is the easy case. Just draw the outlines. - */ - for (loop = (DWORD) *p++; loop; --loop) + if (!load_libglu()) { - glBegin(GL_LINE_LOOP); - for (point = (DWORD) *p++; point; --point) - { - glVertex2fv(p); - p += 2; - } - glEnd(); + ERR("glu32 is required for this function but isn't available\n"); + return FALSE; } - status = 1; + + tess = pgluNewTess(); + if(!tess) return FALSE; + pgluTessCallback(tess, GLU_TESS_VERTEX, (_GLUfuncptr)tess_callback_vertex); + pgluTessCallback(tess, GLU_TESS_BEGIN, (_GLUfuncptr)tess_callback_begin); + pgluTessCallback(tess, GLU_TESS_END, tess_callback_end); } - else if (format == WGL_FONT_POLYGONS) + GetObjectW(GetCurrentObject(hdc, OBJ_FONT), sizeof(lf), &lf); + rc.left = rc.right = rc.bottom = 0; + rc.top = em_size; + DPtoLP(hdc, (POINT*)&rc, 2); + lf.lfHeight = -abs(rc.top - rc.bottom); + lf.lfOrientation = lf.lfEscapement = 0; + unscaled_font = CreateFontIndirectW(&lf); + old_font = SelectObject(hdc, unscaled_font); + + for (glyph = first; glyph < first + count; glyph++) { - double v[3]; - FLOAT *save_p = p; - GLfloat z_value; + DWORD needed; + GLYPHMETRICS gm; + BYTE *buf; + TTPOLYGONHEADER *pph; + TTPOLYCURVE *ppc; + GLdouble *vertices = NULL; + int vertex_total = -1; - /* - * This is the hard case. We have to set up a tessellator - * to convert the outlines into a set of polygonal - * primitives, which the tessellator passes to some - * auxiliary routines for drawing. - */ + if(unicode) + needed = GetGlyphOutlineW(hdc, glyph, GGO_NATIVE, &gm, 0, NULL, &identity); + else + needed = GetGlyphOutlineA(hdc, glyph, GGO_NATIVE, &gm, 0, NULL, &identity); - VertBuf = (FLOAT*) HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, (VERT_BUF_QUANT) * sizeof(FLOAT)); + if(needed == GDI_ERROR) + goto error; - if (!VertBuf) - goto exit; + buf = HeapAlloc(GetProcessHeap(), 0, needed); - VertBufSize = VERT_BUF_QUANT; - VertBufIndex = 0; + if(unicode) + GetGlyphOutlineW(hdc, glyph, GGO_NATIVE, &gm, needed, buf, &identity); + else + GetGlyphOutlineA(hdc, glyph, GGO_NATIVE, &gm, needed, buf, &identity); - if (!(tess = gluNewTess())) - goto exit; + TRACE("glyph %d\n", glyph); - gluTessCallback(tess, GLU_BEGIN, (VOID(CALLBACK *)()) glBegin); - gluTessCallback(tess, GLU_TESS_VERTEX_DATA, (VOID(CALLBACK *)()) TessVertexOutData); - gluTessCallback(tess, GLU_END, (VOID(CALLBACK *)()) glEnd); - gluTessCallback(tess, GLU_ERROR, (VOID(CALLBACK *)()) TessError); - gluTessCallback(tess, GLU_TESS_COMBINE, (VOID(CALLBACK *)()) TessCombine); - gluTessNormal(tess, 0.0F, 0.0F, 1.0F); + if(lpgmf) + { + lpgmf->gmfBlackBoxX = (float)gm.gmBlackBoxX / em_size; + lpgmf->gmfBlackBoxY = (float)gm.gmBlackBoxY / em_size; + lpgmf->gmfptGlyphOrigin.x = (float)gm.gmptGlyphOrigin.x / em_size; + lpgmf->gmfptGlyphOrigin.y = (float)gm.gmptGlyphOrigin.y / em_size; + lpgmf->gmfCellIncX = (float)gm.gmCellIncX / em_size; + lpgmf->gmfCellIncY = (float)gm.gmCellIncY / em_size; - TessErrorOccurred = 0; - glNormal3f(0.0f, 0.0f, 1.0f); - v[2] = 0.0; - z_value = 0.0f; + TRACE("%fx%f at %f,%f inc %f,%f\n", lpgmf->gmfBlackBoxX, lpgmf->gmfBlackBoxY, + lpgmf->gmfptGlyphOrigin.x, lpgmf->gmfptGlyphOrigin.y, lpgmf->gmfCellIncX, lpgmf->gmfCellIncY); + lpgmf++; + } - gluTessBeginPolygon(tess, &z_value); - - for (loop = (DWORD) *p++; loop; --loop) + glNewList(listBase++, GL_COMPILE); + glFrontFace(GL_CCW); + if(format == WGL_FONT_POLYGONS) { - gluTessBeginContour(tess); - - for (point = (DWORD) *p++; point; --point) - { - v[0] = p[0]; - v[1] = p[1]; - gluTessVertex(tess, v, p); - p += 2; - } - - gluTessEndContour(tess); + glNormal3d(0.0, 0.0, 1.0); + pgluTessNormal(tess, 0, 0, 1); + pgluTessBeginPolygon(tess, NULL); } - gluTessEndPolygon(tess); - status = !TessErrorOccurred; - - /* Extrusion code */ - if (extrusion) + while(!vertices) { - DWORD loops; - GLfloat thickness = (GLfloat) - extrusion; - FLOAT *vert, *vert2; - DWORD count; + if(vertex_total != -1) + vertices = HeapAlloc(GetProcessHeap(), 0, vertex_total * 3 * sizeof(GLdouble)); + vertex_total = 0; - p = save_p; - loops = (DWORD) *p++; - - for (loop = 0; loop < loops; loop++) + pph = (TTPOLYGONHEADER*)buf; + while((BYTE*)pph < buf + needed) { - GLfloat dx, dy, len; - DWORD last; + GLdouble previous[3]; + fixed_to_double(pph->pfxStart, em_size, previous); - count = (DWORD) *p++; - glBegin(GL_QUAD_STRIP); + if(vertices) + TRACE("\tstart %d, %d\n", pph->pfxStart.x.value, pph->pfxStart.y.value); - /* Check if the first and last vertex are identical - * so we don't draw the same quad twice. - */ - vert = p + (count-1)*2; - last = (p[0] == vert[0] && p[1] == vert[1]) ? count-1 : count; + if(format == WGL_FONT_POLYGONS) + pgluTessBeginContour(tess); + else + glBegin(GL_LINE_LOOP); - for (point = 0; point <= last; point++) + if(vertices) { - vert = p + 2 * (point % last); - vert2 = p + 2 * ((point+1) % last); - - dx = vert[0] - vert2[0]; - dy = vert[1] - vert2[1]; - len = (GLfloat)sqrt(dx * dx + dy * dy); - - glNormal3f(dy / len, -dx / len, 0.0f); - glVertex3f((GLfloat) vert[0], - (GLfloat) vert[1], thickness); - glVertex3f((GLfloat) vert[0], - (GLfloat) vert[1], 0.0f); + fixed_to_double(pph->pfxStart, em_size, vertices); + if(format == WGL_FONT_POLYGONS) + pgluTessVertex(tess, vertices, vertices); + else + glVertex3d(vertices[0], vertices[1], vertices[2]); + vertices += 3; } + vertex_total++; - glEnd(); - p += count*2; - } + ppc = (TTPOLYCURVE*)((char*)pph + sizeof(*pph)); + while((char*)ppc < (char*)pph + pph->cb) + { + int i, j; + int num; - /* Draw the back face */ - p = save_p; - v[2] = thickness; - glNormal3f(0.0f, 0.0f, -1.0f); - gluTessNormal(tess, 0.0F, 0.0F, -1.0F); + switch(ppc->wType) { + case TT_PRIM_LINE: + for(i = 0; i < ppc->cpfx; i++) + { + if(vertices) + { + TRACE("\t\tline to %d, %d\n", + ppc->apfx[i].x.value, ppc->apfx[i].y.value); + fixed_to_double(ppc->apfx[i], em_size, vertices); + if(format == WGL_FONT_POLYGONS) + pgluTessVertex(tess, vertices, vertices); + else + glVertex3d(vertices[0], vertices[1], vertices[2]); + vertices += 3; + } + fixed_to_double(ppc->apfx[i], em_size, previous); + vertex_total++; + } + break; - gluTessBeginPolygon(tess, &thickness); + case TT_PRIM_QSPLINE: + for(i = 0; i < ppc->cpfx-1; i++) + { + bezier_vector curve[3]; + bezier_vector *points; + GLdouble curve_vertex[3]; - for (loop = (DWORD) *p++; loop; --loop) - { - count = (DWORD) *p++; + if(vertices) + TRACE("\t\tcurve %d,%d %d,%d\n", + ppc->apfx[i].x.value, ppc->apfx[i].y.value, + ppc->apfx[i + 1].x.value, ppc->apfx[i + 1].y.value); - gluTessBeginContour(tess); + curve[0].x = previous[0]; + curve[0].y = previous[1]; + fixed_to_double(ppc->apfx[i], em_size, curve_vertex); + curve[1].x = curve_vertex[0]; + curve[1].y = curve_vertex[1]; + fixed_to_double(ppc->apfx[i + 1], em_size, curve_vertex); + curve[2].x = curve_vertex[0]; + curve[2].y = curve_vertex[1]; + if(i < ppc->cpfx-2) + { + curve[2].x = (curve[1].x + curve[2].x)/2; + curve[2].y = (curve[1].y + curve[2].y)/2; + } + num = bezier_approximate(curve, NULL, deviation); + points = HeapAlloc(GetProcessHeap(), 0, num*sizeof(bezier_vector)); + num = bezier_approximate(curve, points, deviation); + vertex_total += num; + if(vertices) + { + for(j=0; jwType); + if(format == WGL_FONT_POLYGONS) + pgluTessEndContour(tess); + else + glEnd(); + goto error_in_list; + } - for (point = 0; point < count; point++) - { - vert = p + ((count-point-1)<<1); - v[0] = vert[0]; - v[1] = vert[1]; - gluTessVertex(tess, v, vert); + ppc = (TTPOLYCURVE*)((char*)ppc + sizeof(*ppc) + + (ppc->cpfx - 1) * sizeof(POINTFX)); } - p += count*2; - - gluTessEndContour(tess); + if(format == WGL_FONT_POLYGONS) + pgluTessEndContour(tess); + else + glEnd(); + pph = (TTPOLYGONHEADER*)((char*)pph + pph->cb); } - gluTessEndPolygon(tess); } -#if !defined(NDEBUG) - if (TessErrorOccurred) - DBGPRINT("Tessellation error %s\n", gluErrorString(TessErrorOccurred)); -#endif - } - - -exit: - - if(LineBuf) - HeapFree(GetProcessHeap(), 0, LineBuf); - - if(VertBuf) - HeapFree(GetProcessHeap(), 0, VertBuf); - - if (tess) - gluDeleteTess(tess); - - return status; -} - - -/***************************************************************************** -* MakeDisplayListFromGlyph -* -* Converts the outline of a glyph to an OpenGL display list. -* -* Return value is nonzero for success, zero for failure. -* -* Does not check for OpenGL errors, so if the caller needs to know about them, -* it should call glGetError(). -*****************************************************************************/ - -INT MakeDisplayListFromGlyph(DWORD listName, UCHAR* glyphBuf, DWORD glyphSize, LPGLYPHMETRICSFLOAT glyphMetricsFloat, - FLOAT chordalDeviation, FLOAT extrusion, INT format) -{ - INT status; - - glNewList(listName, GL_COMPILE); - status = DrawGlyph(glyphBuf, glyphSize, chordalDeviation, extrusion, format); - glTranslatef(glyphMetricsFloat->gmfCellIncX, glyphMetricsFloat->gmfCellIncY, 0.0F); - glEndList(); - - return status; -} - -// *********************************************************************** - -/***************************************************************************** -* IntUseFontBitmaps -* -* Converts a subrange of the glyphs in a GDI font to OpenGL display -* lists. -* -* Extended to support any GDI font, not just TrueType fonts. (DaveM) -* -*****************************************************************************/ - -BOOL APIENTRY IntUseFontBitmapsW(HDC hDC, DWORD first, DWORD count, DWORD listBase) -{ - INT i, ox, oy, ix, iy; - INT w = 0, h = 0; - INT iBufSize, iCurBufSize = 0; - DWORD *bitmapBuffer = NULL; - DWORD *invertedBitmapBuffer = NULL; - BOOL bSuccessOrFail = TRUE; - BOOL bTrueType = FALSE; - TEXTMETRIC tm; - GLYPHMETRICS gm; - RASTERIZER_STATUS rs; - MAT2 mat; - SIZE size; - RECT rect; - HDC hDCMem; - HBITMAP hBitmap; - BITMAPINFO bmi; - HFONT hFont; - - // Set up a unity matrix. - ZeroMemory(&mat, sizeof(mat)); - mat.eM11.value = 1; - mat.eM22.value = 1; - - // Test to see if selected font is TrueType or not - ZeroMemory(&tm, sizeof(tm)); - if (!GetTextMetrics(hDC, &tm)) - { - DBGPRINT("Font metrics error\n"); - return FALSE; - } - bTrueType = (tm.tmPitchAndFamily & TMPF_TRUETYPE) ? TRUE : FALSE; - - // Test to see if TRUE-TYPE capabilities are installed - // (only necessary if TrueType font selected) - ZeroMemory(&rs, sizeof(rs)); - - if (bTrueType) - { - if (!GetRasterizerCaps (&rs, sizeof (RASTERIZER_STATUS)) || !(rs.wFlags & TT_ENABLED)) - { - DBGPRINT("No TrueType caps\n"); - bTrueType = FALSE; - } - } - - // Trick to get the current font handle - hFont = SelectObject(hDC, GetStockObject(SYSTEM_FONT)); - SelectObject(hDC, hFont); - - // Have memory device context available for holding bitmaps of font glyphs - hDCMem = CreateCompatibleDC(hDC); - SelectObject(hDCMem, hFont); - SetTextColor(hDCMem, RGB(0xFF, 0xFF, 0xFF)); - SetBkColor(hDCMem, 0); - - for (i = first; (DWORD) i < (first + count); i++) - { - // Find out how much space is needed for the bitmap so we can - // Set the buffer size correctly. - if (bTrueType) - { - // Use TrueType support to get bitmap size of glyph - iBufSize = GetGlyphOutline(hDC, i, GGO_BITMAP, &gm, 0, NULL, &mat); - if (iBufSize == GDI_ERROR) - { - bSuccessOrFail = FALSE; - break; - } - } - else - { - // Use generic GDI support to compute bitmap size of glyph - w = tm.tmMaxCharWidth; - h = tm.tmHeight; - if (GetTextExtentPoint32(hDC, (LPCTSTR)&i, 1, &size)) - { - w = size.cx; - h = size.cy; - } - iBufSize = w * h; - // Use DWORD multiple for compatibility - iBufSize += 3; - iBufSize /= 4; - iBufSize *= 4; - } - - // If we need to allocate Larger Buffers, then do so - but allocate - // An extra 50 % so that we don't do too many mallocs ! - if (iBufSize > iCurBufSize) - { - if (bitmapBuffer) - { - HeapFree(GetProcessHeap(), 0, bitmapBuffer); - } - if (invertedBitmapBuffer) - { - HeapFree(GetProcessHeap(), 0, invertedBitmapBuffer); - } - - iCurBufSize = iBufSize * 2; - bitmapBuffer = (DWORD *) HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, iCurBufSize); - invertedBitmapBuffer = (DWORD *) HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, iCurBufSize); - - if (bitmapBuffer == NULL || invertedBitmapBuffer == NULL) - { - bSuccessOrFail = FALSE; - break; - } - } - - // If we fail to get the Glyph data, delete the display lists - // Created so far and return FALSE. - if (bTrueType) - { - // Use TrueType support to get bitmap of glyph - if (GetGlyphOutline(hDC, i, GGO_BITMAP, &gm, iBufSize, bitmapBuffer, &mat) == GDI_ERROR) - { - bSuccessOrFail = FALSE; - break; - } - - // Setup glBitmap parameters for current font glyph - w = gm.gmBlackBoxX; - h = gm.gmBlackBoxY; - ox = gm.gmptGlyphOrigin.x; - oy = gm.gmptGlyphOrigin.y; - ix = gm.gmCellIncX; - iy = gm.gmCellIncY; - } - else - { - // Use generic GDI support to create bitmap of glyph - ZeroMemory(bitmapBuffer, iBufSize); - - if (i >= tm.tmFirstChar && i <= tm.tmLastChar) - { - // Only create bitmaps for actual font glyphs - hBitmap = CreateBitmap(w, h, 1, 1, NULL); - SelectObject(hDCMem, hBitmap); - // Make bitmap of current font glyph - SetRect(&rect, 0, 0, w, h); - DrawText(hDCMem, (LPCTSTR)&i, 1, &rect, - DT_LEFT | DT_BOTTOM | DT_SINGLELINE | DT_NOCLIP); - // Make copy of bitmap in our local buffer - ZeroMemory(&bmi, sizeof(bmi)); - bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER); - bmi.bmiHeader.biWidth = w; - bmi.bmiHeader.biHeight = -h; - bmi.bmiHeader.biPlanes = 1; - bmi.bmiHeader.biBitCount = 1; - bmi.bmiHeader.biCompression = BI_RGB; - GetDIBits(hDCMem, hBitmap, 0, h, bitmapBuffer, &bmi, 0); - DeleteObject(hBitmap); - } - else - { - // Otherwise use empty display list for non-existing glyph - iBufSize = 0; - } - - // Setup glBitmap parameters for current font glyph - ox = 0; - oy = tm.tmDescent; - ix = w; - iy = 0; - } - - // Create an OpenGL display list. - glNewList((listBase + i), GL_COMPILE); - - // Some fonts have no data for the space character, yet advertise - // a non-zero size. - if (0 == iBufSize) - { - glBitmap(0, 0, 0.0f, 0.0f, (GLfloat) ix, (GLfloat) iy, NULL); - } - else - { - // Invert the Glyph data. - InvertGlyphBitmap(w, h, bitmapBuffer, invertedBitmapBuffer); - - // Render an OpenGL bitmap and invert the origin. - glBitmap(w, h, - (GLfloat) ox, (GLfloat) (h-oy), - (GLfloat) ix, (GLfloat) iy, - (GLubyte *) invertedBitmapBuffer); - } - - // Close this display list. +error_in_list: + if(format == WGL_FONT_POLYGONS) + pgluTessEndPolygon(tess); + glTranslated((GLdouble)gm.gmCellIncX / em_size, (GLdouble)gm.gmCellIncY / em_size, 0.0); glEndList(); + HeapFree(GetProcessHeap(), 0, buf); + HeapFree(GetProcessHeap(), 0, vertices); } - if (bSuccessOrFail == FALSE) - { - DBGPRINT("DGL_UseFontBitmaps: Get glyph failed\n"); - glDeleteLists((i+listBase), (i-first)); - } + error: + DeleteObject(SelectObject(hdc, old_font)); + if(format == WGL_FONT_POLYGONS) + pgluDeleteTess(tess); + return TRUE; - // Release resources used - DeleteObject(hFont); - DeleteDC(hDCMem); - - if (bitmapBuffer) - HeapFree(GetProcessHeap(), 0, bitmapBuffer); - - if (invertedBitmapBuffer) - HeapFree(GetProcessHeap(), 0, invertedBitmapBuffer); - - return(bSuccessOrFail); } -BOOL APIENTRY IntUseFontBitmapsA(HDC hDC, DWORD first, DWORD count, DWORD listBase) +/*********************************************************************** + * wglUseFontOutlinesA (OPENGL32.@) + */ +BOOL WINAPI wglUseFontOutlinesA(HDC hdc, + DWORD first, + DWORD count, + DWORD listBase, + FLOAT deviation, + FLOAT extrusion, + int format, + LPGLYPHMETRICSFLOAT lpgmf) { - /* Just call IntUseFontBitmapsW for now */ - return IntUseFontBitmapsW(hDC, first, count, listBase); + return wglUseFontOutlines_common(hdc, first, count, listBase, deviation, extrusion, format, lpgmf, FALSE); } - - -/***************************************************************************** -* IntUseFontOutlines -* -* Converts a subrange of the glyphs in a TrueType font to OpenGL display -* lists. -*****************************************************************************/ - -BOOL APIENTRY IntUseFontOutlinesW(HDC hDC, DWORD first, DWORD count, DWORD listBase, FLOAT chordalDeviation, - FLOAT extrusion, INT format, GLYPHMETRICSFLOAT *glyphMetricsFloatArray) +/*********************************************************************** + * wglUseFontOutlinesW (OPENGL32.@) + */ +BOOL WINAPI wglUseFontOutlinesW(HDC hdc, + DWORD first, + DWORD count, + DWORD listBase, + FLOAT deviation, + FLOAT extrusion, + int format, + LPGLYPHMETRICSFLOAT lpgmf) { - DWORD glyphIndex; - UCHAR* glyphBuf; - DWORD glyphBufSize; - - /* - * Flush any previous OpenGL errors. This allows us to check for - * new errors so they can be reported via the function return value. - */ - while (glGetError() != GL_NO_ERROR); - - /* - * Make sure that the current font can be sampled accurately. - */ - hNewFont = CreateHighResolutionFont(hDC); - - if (!hNewFont) - return FALSE; - - hOldFont = SelectObject(hDC, hNewFont); - if (!hOldFont) - return FALSE; - - /* - * Preallocate a buffer for the outline data, and track its size: - */ - glyphBuf = (UCHAR*) HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, glyphBufSize = 10240); - - if (!glyphBuf) - return FALSE; /*WGL_STATUS_NOT_ENOUGH_MEMORY*/ - - /* - * Process each glyph in the given range: - */ - for (glyphIndex = first; glyphIndex - first < count; ++glyphIndex) - { - GLYPHMETRICS glyphMetrics; - DWORD glyphSize; - static MAT2 matrix = - { - {0, 1}, {0, 0}, - {0, 0}, {0, 1} - }; - LPGLYPHMETRICSFLOAT glyphMetricsFloat = &glyphMetricsFloatArray[glyphIndex - first]; - - /* - * Determine how much space is needed to store the glyph's - * outlines. If our glyph buffer isn't large enough, - * resize it. - */ - - glyphSize = GetGlyphOutline(hDC, glyphIndex, GGO_NATIVE, &glyphMetrics, 0, NULL, &matrix); - - if (glyphSize == GDI_ERROR) - return FALSE; /*WGL_STATUS_FAILURE*/ - - if (glyphSize > glyphBufSize) - { - HeapFree(GetProcessHeap(), 0, glyphBuf); - glyphBuf = (UCHAR*) HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, glyphBufSize = glyphSize); - if (!glyphBuf) - return FALSE; /*WGL_STATUS_NOT_ENOUGH_MEMORY*/ - } - - - /* - * Get the glyph's outlines. - */ - if (GetGlyphOutline(hDC, glyphIndex, GGO_NATIVE, &glyphMetrics, glyphBufSize, glyphBuf, &matrix) == GDI_ERROR) - { - HeapFree(GetProcessHeap(), 0, glyphBuf); - return FALSE; /*WGL_STATUS_FAILURE*/ - } - - glyphMetricsFloat->gmfBlackBoxX = - (FLOAT) glyphMetrics.gmBlackBoxX * ScaleFactor; - glyphMetricsFloat->gmfBlackBoxY = - (FLOAT) glyphMetrics.gmBlackBoxY * ScaleFactor; - glyphMetricsFloat->gmfptGlyphOrigin.x = - (FLOAT) glyphMetrics.gmptGlyphOrigin.x * ScaleFactor; - glyphMetricsFloat->gmfptGlyphOrigin.y = - (FLOAT) glyphMetrics.gmptGlyphOrigin.y * ScaleFactor; - glyphMetricsFloat->gmfCellIncX = - (FLOAT) glyphMetrics.gmCellIncX * ScaleFactor; - glyphMetricsFloat->gmfCellIncY = - (FLOAT) glyphMetrics.gmCellIncY * ScaleFactor; - - /* - * Turn the glyph into a display list: - */ - if (!MakeDisplayListFromGlyph((glyphIndex - first) + listBase, glyphBuf, glyphSize, glyphMetricsFloat, - chordalDeviation + ScaleFactor, extrusion, format)) - { - HeapFree(GetProcessHeap(), 0, glyphBuf); - return FALSE; /*WGL_STATUS_FAILURE*/ - } - } - - /* - * Clean up temporary storage and return. If an error occurred, - * clear all OpenGL error flags and return FAILURE status; - * otherwise just return SUCCESS. - */ - HeapFree(GetProcessHeap(), 0, glyphBuf); - - DeleteObject(SelectObject(hDC, hOldFont)); - - if (glGetError() == GL_NO_ERROR) - { - return TRUE; /*WGL_STATUS_SUCCESS*/ - } - else - { - while (glGetError() != GL_NO_ERROR); - - return FALSE; /*WGL_STATUS_FAILURE*/ - } -} - -BOOL APIENTRY IntUseFontOutlinesA(HDC hDC, DWORD first, DWORD count, DWORD listBase, FLOAT chordalDeviation, - FLOAT extrusion, INT format, GLYPHMETRICSFLOAT *glyphMetricsFloatArray) -{ - /* Just call IntUseFontOutlinesW for now */ - return IntUseFontOutlinesW(hDC, first, count, listBase, chordalDeviation, extrusion, format, glyphMetricsFloatArray); -} + return wglUseFontOutlines_common(hdc, first, count, listBase, deviation, extrusion, format, lpgmf, TRUE); +} \ No newline at end of file Index: dll/opengl/opengl32/gl.c =================================================================== --- dll/opengl/opengl32/gl.c (revision 58564) +++ dll/opengl/opengl32/gl.c (working copy) @@ -58,7 +58,7 @@ long l11, long l12, long l13, long l14 ) { return 0; } -#if defined(_M_IX86) +#if defined(_M_IX86) && 0 # define FOO(x) #x #ifdef __GNUC__ Index: dll/opengl/opengl32/mesa/accum.c =================================================================== --- dll/opengl/opengl32/mesa/accum.c (revision 0) +++ dll/opengl/opengl32/mesa/accum.c (working copy) @@ -0,0 +1,95 @@ +/* $Id: accum.c,v 1.37 2001/03/12 00:48:37 gareth Exp $ */ + +/* + * Mesa 3-D graphics library + * Version: 3.5 + * + * Copyright (C) 1999-2001 Brian Paul 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 + * BRIAN PAUL 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. + */ + + +#ifdef PC_HEADER +#include "all.h" +#else +#include "glheader.h" +#include "accum.h" +#include "context.h" +#include "macros.h" +#include "mem.h" +#include "state.h" +#include "mtypes.h" +#endif + + + + +void +_mesa_ClearAccum( GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha ) +{ + GLfloat tmp[4]; + GET_CURRENT_CONTEXT(ctx); + ASSERT_OUTSIDE_BEGIN_END(ctx); + + tmp[0] = CLAMP( red, -1.0, 1.0 ); + tmp[1] = CLAMP( green, -1.0, 1.0 ); + tmp[2] = CLAMP( blue, -1.0, 1.0 ); + tmp[3] = CLAMP( alpha, -1.0, 1.0 ); + + if (TEST_EQ_4V(tmp, ctx->Accum.ClearColor)) + return; + + FLUSH_VERTICES(ctx, _NEW_ACCUM); + COPY_4FV( ctx->Accum.ClearColor, tmp ); +} + +/* Should really be a driver-supplied function? + */ +void +_mesa_Accum( GLenum op, GLfloat value ) +{ + GET_CURRENT_CONTEXT(ctx); + GLuint xpos, ypos, width, height; + ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx); + + if (ctx->Visual.accumRedBits == 0 || ctx->DrawBuffer != ctx->ReadBuffer) { + _mesa_error(ctx, GL_INVALID_OPERATION, "glAccum"); + return; + } + + if (ctx->NewState) + _mesa_update_state( ctx ); + + /* Determine region to operate upon. */ + if (ctx->Scissor.Enabled) { + xpos = ctx->Scissor.X; + ypos = ctx->Scissor.Y; + width = ctx->Scissor.Width; + height = ctx->Scissor.Height; + } + else { + /* whole window */ + xpos = 0; + ypos = 0; + width = ctx->DrawBuffer->Width; + height = ctx->DrawBuffer->Height; + } + + ctx->Driver.Accum( ctx, op, value, xpos, ypos, width, height ); +} Index: dll/opengl/opengl32/mesa/accum.h =================================================================== --- dll/opengl/opengl32/mesa/accum.h (revision 0) +++ dll/opengl/opengl32/mesa/accum.h (working copy) @@ -0,0 +1,43 @@ +/* $Id: accum.h,v 1.6 2001/03/12 00:48:37 gareth Exp $ */ + +/* + * Mesa 3-D graphics library + * Version: 3.5 + * + * Copyright (C) 1999-2001 Brian Paul 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 + * BRIAN PAUL 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. + */ + + +#ifndef ACCUM_H +#define ACCUM_H + + +#include "mtypes.h" + + +extern void +_mesa_Accum( GLenum op, GLfloat value ); + + +extern void +_mesa_ClearAccum( GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha ); + + +#endif Index: dll/opengl/opengl32/mesa/all.h =================================================================== --- dll/opengl/opengl32/mesa/all.h (revision 0) +++ dll/opengl/opengl32/mesa/all.h (working copy) @@ -0,0 +1,95 @@ +/* $Id: all.h,v 1.16 2001/06/18 17:26:08 brianp Exp $ */ + +/* + * Mesa 3-D graphics library + * Version: 3.5 + * + * Copyright (C) 1999-2001 Brian Paul 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 + * BRIAN PAUL 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. + */ + + +/* + * The purpose of this file is to collect all the header files that Mesa + * uses into a single header so that we can get new compilers that support + * pre-compiled headers to compile much faster. + * All we do is list all the internal headers used by Mesa in this one + * main header file, and most compilers will pre-compile all these headers + * and use them over and over again for each source module. This makes a + * big difference for Win32 support, because the headers take + * a *long* time to compile. + */ + + +#ifndef SRC_ALL_H +#define SRC_ALL_H + + +#ifndef PC_HEADER + This is an error. all.h should be included only if PC_HEADER is defined. +#endif + +#include "glheader.h" +#include "accum.h" +#include "attrib.h" +#include "blend.h" +#include "buffers.h" +#include "clip.h" +#include "colortab.h" +#include "config.h" +#include "context.h" +#include "convolve.h" +#include "dd.h" +#include "depth.h" +#include "dlist.h" +#include "drawpix.h" +#include "enable.h" +#include "enums.h" +#include "eval.h" +#include "extensions.h" +#include "feedback.h" +#include "fog.h" +#include "get.h" +#include "glapi.h" +#include "glthread.h" +#include "hash.h" +#include "hint.h" +#include "histogram.h" +#include "image.h" +#include "light.h" +#include "lines.h" +#include "macros.h" +#include "matrix.h" +#include "mem.h" +#include "mmath.h" +#include "pixel.h" +#include "points.h" +#include "polygon.h" +#include "rastpos.h" +#include "state.h" +#include "stencil.h" +#include "teximage.h" +#include "texobj.h" +#include "texstate.h" +#include "texstore.h" +#include "mtypes.h" +#include "varray.h" + + +#endif /*SRC_ALL_H*/ Index: dll/opengl/opengl32/mesa/api_arrayelt.c =================================================================== --- dll/opengl/opengl32/mesa/api_arrayelt.c (revision 0) +++ dll/opengl/opengl32/mesa/api_arrayelt.c (working copy) @@ -0,0 +1,302 @@ +/* $Id: api_arrayelt.c,v 1.3 2001/06/01 22:22:10 keithw Exp $ */ + +/* + * Mesa 3-D graphics library + * Version: 3.5 + * + * Copyright (C) 1999-2001 Brian Paul 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 + * BRIAN PAUL 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. + */ + +#include "glheader.h" +#include "api_arrayelt.h" +#include "context.h" +#include "mem.h" +#include "macros.h" +#include "mtypes.h" + + +typedef struct { + GLint unit; + struct gl_client_array *array; + void (*func)( GLenum, const void * ); +} AEtexarray; + + +typedef struct { + struct gl_client_array *array; + void (*func)( const void * ); +} AEarray; + +typedef struct { + AEtexarray texarrays[MAX_TEXTURE_UNITS+1]; + AEarray arrays[32]; + GLuint NewState; +} AEcontext; + +#define AE_CONTEXT(ctx) ((AEcontext *)(ctx)->aelt_context) +#define TYPE_IDX(t) ((t) & 0xf) + +static void (*colorfuncs[2][8])( const void * ) = { + { (void (*)( const void * ))glColor3bv, + (void (*)( const void * ))glColor3ub, + (void (*)( const void * ))glColor3sv, + (void (*)( const void * ))glColor3usv, + (void (*)( const void * ))glColor3iv, + (void (*)( const void * ))glColor3uiv, + (void (*)( const void * ))glColor3fv, + (void (*)( const void * ))glColor3dv }, + + { (void (*)( const void * ))glColor4bv, + (void (*)( const void * ))glColor4ub, + (void (*)( const void * ))glColor4sv, + (void (*)( const void * ))glColor4usv, + (void (*)( const void * ))glColor4iv, + (void (*)( const void * ))glColor4uiv, + (void (*)( const void * ))glColor4fv, + (void (*)( const void * ))glColor4dv } +}; + +static void (*vertexfuncs[3][8])( const void * ) = { + { 0, + 0, + (void (*)( const void * ))glVertex2sv, + 0, + (void (*)( const void * ))glVertex2iv, + 0, + (void (*)( const void * ))glVertex2fv, + (void (*)( const void * ))glVertex2dv }, + + { 0, + 0, + (void (*)( const void * ))glVertex3sv, + 0, + (void (*)( const void * ))glVertex3iv, + 0, + (void (*)( const void * ))glVertex3fv, + (void (*)( const void * ))glVertex3dv }, + + { 0, + 0, + (void (*)( const void * ))glVertex4sv, + 0, + (void (*)( const void * ))glVertex4iv, + 0, + (void (*)( const void * ))glVertex4fv, + (void (*)( const void * ))glVertex4dv } +}; + + +static void (*multitexfuncs[4][8])( GLenum, const void * ) = { + { 0, + 0, + (void (*)( GLenum, const void * ))glMultiTexCoord1svARB, + 0, + (void (*)( GLenum, const void * ))glMultiTexCoord1ivARB, + 0, + (void (*)( GLenum, const void * ))glMultiTexCoord1fvARB, + (void (*)( GLenum, const void * ))glMultiTexCoord1dvARB }, + + { 0, + 0, + (void (*)( GLenum, const void * ))glMultiTexCoord2svARB, + 0, + (void (*)( GLenum, const void * ))glMultiTexCoord2ivARB, + 0, + (void (*)( GLenum, const void * ))glMultiTexCoord2fvARB, + (void (*)( GLenum, const void * ))glMultiTexCoord2dvARB }, + + { 0, + 0, + (void (*)( GLenum, const void * ))glMultiTexCoord3svARB, + 0, + (void (*)( GLenum, const void * ))glMultiTexCoord3ivARB, + 0, + (void (*)( GLenum, const void * ))glMultiTexCoord3fvARB, + (void (*)( GLenum, const void * ))glMultiTexCoord3dvARB }, + + { 0, + 0, + (void (*)( GLenum, const void * ))glMultiTexCoord4svARB, + 0, + (void (*)( GLenum, const void * ))glMultiTexCoord4ivARB, + 0, + (void (*)( GLenum, const void * ))glMultiTexCoord4fvARB, + (void (*)( GLenum, const void * ))glMultiTexCoord4dvARB } +}; + +static void (*indexfuncs[8])( const void * ) = { + 0, + (void (*)( const void * ))glIndexubv, + (void (*)( const void * ))glIndexsv, + 0, + (void (*)( const void * ))glIndexiv, + 0, + (void (*)( const void * ))glIndexfv, + (void (*)( const void * ))glIndexdv +}; + + +static void (*normalfuncs[8])( const void * ) = { + (void (*)( const void * ))glNormal3bv, + 0, + (void (*)( const void * ))glNormal3sv, + 0, + (void (*)( const void * ))glNormal3iv, + 0, + (void (*)( const void * ))glNormal3fv, + (void (*)( const void * ))glNormal3dv, +}; + +static void (*fogcoordfuncs[8])( const void * ) = { + 0, + 0, + 0, + 0, + 0, + 0, + (void (*)( const void * ))glFogCoordfvEXT, + (void (*)( const void * ))glFogCoorddvEXT, +}; + +static void (*secondarycolorfuncs[8])( const void * ) = { + (void (*)( const void * ))glSecondaryColor3bvEXT, + (void (*)( const void * ))glSecondaryColor3ubvEXT, + (void (*)( const void * ))glSecondaryColor3svEXT, + (void (*)( const void * ))glSecondaryColor3usvEXT, + (void (*)( const void * ))glSecondaryColor3ivEXT, + (void (*)( const void * ))glSecondaryColor3uivEXT, + (void (*)( const void * ))glSecondaryColor3fvEXT, + (void (*)( const void * ))glSecondaryColor3dvEXT, +}; + + +GLboolean _ae_create_context( GLcontext *ctx ) +{ + ctx->aelt_context = MALLOC( sizeof(AEcontext) ); + if (!ctx->aelt_context) + return GL_FALSE; + + AE_CONTEXT(ctx)->NewState = ~0; + return GL_TRUE; +} + + +void _ae_destroy_context( GLcontext *ctx ) +{ + if ( AE_CONTEXT( ctx ) ) { + FREE( ctx->aelt_context ); + ctx->aelt_context = 0; + } +} + + +static void _ae_update_state( GLcontext *ctx ) +{ + AEcontext *actx = AE_CONTEXT(ctx); + AEtexarray *ta = actx->texarrays; + AEarray *aa = actx->arrays; + int i; + + for (i = 0 ; i < ctx->Const.MaxTextureUnits ; i++) + if (ctx->Array.TexCoord[i].Enabled) { + ta->unit = i; + ta->array = &ctx->Array.TexCoord[i]; + ta->func = multitexfuncs[ta->array->Size-1][TYPE_IDX(ta->array->Type)]; + ta++; + } + + ta->func = 0; + + if (ctx->Array.Color.Enabled) { + aa->array = &ctx->Array.Color; + aa->func = colorfuncs[aa->array->Size-3][TYPE_IDX(aa->array->Type)]; + aa++; + } + + if (ctx->Array.Normal.Enabled) { + aa->array = &ctx->Array.Normal; + aa->func = normalfuncs[TYPE_IDX(aa->array->Type)]; + aa++; + } + + if (ctx->Array.Index.Enabled) { + aa->array = &ctx->Array.Index; + aa->func = indexfuncs[TYPE_IDX(aa->array->Type)]; + aa++; + } + + if (ctx->Array.EdgeFlag.Enabled) { + aa->array = &ctx->Array.EdgeFlag; + aa->func = (void (*)( const void * ))glEdgeFlagv; + aa++; + } + + if (ctx->Array.FogCoord.Enabled) { + aa->array = &ctx->Array.FogCoord; + aa->func = fogcoordfuncs[TYPE_IDX(aa->array->Type)]; + aa++; + } + + if (ctx->Array.SecondaryColor.Enabled) { + aa->array = &ctx->Array.SecondaryColor; + aa->func = secondarycolorfuncs[TYPE_IDX(aa->array->Type)]; + aa++; + } + + /* Must be last + */ + if (ctx->Array.Vertex.Enabled) { + aa->array = &ctx->Array.Vertex; + aa->func = vertexfuncs[aa->array->Size-2][TYPE_IDX(aa->array->Type)]; + aa++; + } + + aa->func = 0; + actx->NewState = 0; +} + + +void _ae_loopback_array_elt( GLint elt ) +{ + GET_CURRENT_CONTEXT(ctx); + AEcontext *actx = AE_CONTEXT(ctx); + AEtexarray *ta; + AEarray *aa; + + if (actx->NewState) + _ae_update_state( ctx ); + + for (ta = actx->texarrays ; ta->func ; ta++) { + ta->func( ta->unit, (char *)ta->array->Ptr + elt * ta->array->StrideB ); + } + + /* Must be last + */ + for (aa = actx->arrays ; aa->func ; aa++) { + aa->func( (char *)aa->array->Ptr + elt * aa->array->StrideB ); + } +} + + + +void _ae_invalidate_state( GLcontext *ctx, GLuint new_state ) +{ + AE_CONTEXT(ctx)->NewState |= new_state; +} Index: dll/opengl/opengl32/mesa/api_arrayelt.h =================================================================== --- dll/opengl/opengl32/mesa/api_arrayelt.h (revision 0) +++ dll/opengl/opengl32/mesa/api_arrayelt.h (working copy) @@ -0,0 +1,38 @@ +/* $Id: api_arrayelt.h,v 1.1 2001/06/01 22:22:10 keithw Exp $ */ + +/* + * Mesa 3-D graphics library + * Version: 3.5 + * + * Copyright (C) 1999-2001 Brian Paul 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 + * BRIAN PAUL 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. + */ + + +#ifndef API_ARRAYELT_H +#define API_ARRAYELT_H + +#include "mtypes.h" + +extern GLboolean _ae_create_context( GLcontext *ctx ); +extern void _ae_destroy_context( GLcontext *ctx ); +extern void _ae_invalidate_state( GLcontext *ctx, GLuint new_state ); +extern void _ae_loopback_array_elt( GLint elt ); + +#endif Index: dll/opengl/opengl32/mesa/api_eval.c =================================================================== --- dll/opengl/opengl32/mesa/api_eval.c (revision 0) +++ dll/opengl/opengl32/mesa/api_eval.c (working copy) @@ -0,0 +1,324 @@ +/* $Id: api_eval.c,v 1.1 2001/06/04 13:57:35 keithw Exp $ */ + +/* + * Mesa 3-D graphics library + * Version: 3.5 + * + * Copyright (C) 1999-2001 Brian Paul 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 + * BRIAN PAUL 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. + * + * Authors: + * Keith Whitwell + */ + +#include "glheader.h" +#include "api_eval.h" +#include "context.h" +#include "macros.h" +#include "mmath.h" +#include "math/m_eval.h" + +static void do_EvalCoord1f(GLcontext* ctx, GLfloat u) +{ + + /** Color Index **/ + if (ctx->Eval.Map1Index) + { + GLfloat findex; + struct gl_1d_map *map = &ctx->EvalMap.Map1Index; + GLfloat uu = (u - map->u1) * map->du; + _math_horner_bezier_curve(map->Points, &findex, uu, 1, map->Order); + glIndexi( (GLint) findex ); + } + + /** Color **/ + if (ctx->Eval.Map1Color4) { + GLfloat fcolor[4]; + struct gl_1d_map *map = &ctx->EvalMap.Map1Color4; + GLfloat uu = (u - map->u1) * map->du; + _math_horner_bezier_curve(map->Points, fcolor, uu, 4, map->Order); + glColor4fv( fcolor ); + } + + /** Normal Vector **/ + if (ctx->Eval.Map1Normal) { + GLfloat normal[3]; + struct gl_1d_map *map = &ctx->EvalMap.Map1Normal; + GLfloat uu = (u - map->u1) * map->du; + _math_horner_bezier_curve(map->Points, normal, uu, 3, map->Order); + glNormal3fv( normal ); + } + + /** Texture Coordinates **/ + if (ctx->Eval.Map1TextureCoord4) { + GLfloat texcoord[4]; + struct gl_1d_map *map = &ctx->EvalMap.Map1Texture4; + GLfloat uu = (u - map->u1) * map->du; + _math_horner_bezier_curve(map->Points, texcoord, uu, 4, map->Order); + glTexCoord4fv( texcoord ); + } + else if (ctx->Eval.Map1TextureCoord3) { + GLfloat texcoord[4]; + struct gl_1d_map *map = &ctx->EvalMap.Map1Texture3; + GLfloat uu = (u - map->u1) * map->du; + _math_horner_bezier_curve(map->Points, texcoord, uu, 3, map->Order); + glTexCoord3fv( texcoord ); + } + else if (ctx->Eval.Map1TextureCoord2) { + GLfloat texcoord[4]; + struct gl_1d_map *map = &ctx->EvalMap.Map1Texture2; + GLfloat uu = (u - map->u1) * map->du; + _math_horner_bezier_curve(map->Points, texcoord, uu, 2, map->Order); + glTexCoord2fv( texcoord ); + } + else if (ctx->Eval.Map1TextureCoord1) { + GLfloat texcoord[4]; + struct gl_1d_map *map = &ctx->EvalMap.Map1Texture1; + GLfloat uu = (u - map->u1) * map->du; + _math_horner_bezier_curve(map->Points, texcoord, uu, 1, map->Order); + glTexCoord1fv( texcoord ); + } + + /** Vertex **/ + if (ctx->Eval.Map1Vertex4) + { + GLfloat vertex[4]; + struct gl_1d_map *map = &ctx->EvalMap.Map1Vertex4; + GLfloat uu = (u - map->u1) * map->du; + _math_horner_bezier_curve(map->Points, vertex, uu, 4, map->Order); + glVertex4fv( vertex ); + } + else if (ctx->Eval.Map1Vertex3) + { + GLfloat vertex[4]; + struct gl_1d_map *map = &ctx->EvalMap.Map1Vertex3; + GLfloat uu = (u - map->u1) * map->du; + _math_horner_bezier_curve(map->Points, vertex, uu, 3, map->Order); + glVertex3fv( vertex ); + } +} + +#define CROSS_PROD(n, u, v) \ + (n)[0] = (u)[1]*(v)[2] - (u)[2]*(v)[1]; \ + (n)[1] = (u)[2]*(v)[0] - (u)[0]*(v)[2]; \ + (n)[2] = (u)[0]*(v)[1] - (u)[1]*(v)[0] + + +static void do_EvalCoord2f( GLcontext* ctx, GLfloat u, GLfloat v ) +{ + /** Color Index **/ + if (ctx->Eval.Map2Index) { + GLfloat findex; + struct gl_2d_map *map = &ctx->EvalMap.Map2Index; + GLfloat uu = (u - map->u1) * map->du; + GLfloat vv = (v - map->v1) * map->dv; + _math_horner_bezier_surf(map->Points, &findex, uu, vv, 1, + map->Uorder, map->Vorder); + glIndexi( (GLuint) (GLint) findex ); + } + + /** Color **/ + if (ctx->Eval.Map2Color4) { + GLfloat fcolor[4]; + struct gl_2d_map *map = &ctx->EvalMap.Map2Color4; + GLfloat uu = (u - map->u1) * map->du; + GLfloat vv = (v - map->v1) * map->dv; + _math_horner_bezier_surf(map->Points, fcolor, uu, vv, 4, + map->Uorder, map->Vorder); + glColor4fv( fcolor ); + } + + /** Normal **/ + if (ctx->Eval.Map2Normal && + (!ctx->Eval.AutoNormal || (!ctx->Eval.Map2Vertex3 && + !ctx->Eval.Map2Vertex4))) { + GLfloat normal[3]; + struct gl_2d_map *map = &ctx->EvalMap.Map2Normal; + GLfloat uu = (u - map->u1) * map->du; + GLfloat vv = (v - map->v1) * map->dv; + _math_horner_bezier_surf(map->Points, normal, uu, vv, 3, + map->Uorder, map->Vorder); + glNormal3fv( normal ); + } + + /** Texture Coordinates **/ + if (ctx->Eval.Map2TextureCoord4) { + GLfloat texcoord[4]; + struct gl_2d_map *map = &ctx->EvalMap.Map2Texture4; + GLfloat uu = (u - map->u1) * map->du; + GLfloat vv = (v - map->v1) * map->dv; + _math_horner_bezier_surf(map->Points, texcoord, uu, vv, 4, + map->Uorder, map->Vorder); + glTexCoord4fv( texcoord ); + } + else if (ctx->Eval.Map2TextureCoord3) { + GLfloat texcoord[4]; + struct gl_2d_map *map = &ctx->EvalMap.Map2Texture3; + GLfloat uu = (u - map->u1) * map->du; + GLfloat vv = (v - map->v1) * map->dv; + _math_horner_bezier_surf(map->Points, texcoord, uu, vv, 3, + map->Uorder, map->Vorder); + glTexCoord3fv( texcoord ); + } + else if (ctx->Eval.Map2TextureCoord2) { + GLfloat texcoord[4]; + struct gl_2d_map *map = &ctx->EvalMap.Map2Texture2; + GLfloat uu = (u - map->u1) * map->du; + GLfloat vv = (v - map->v1) * map->dv; + _math_horner_bezier_surf(map->Points, texcoord, uu, vv, 2, + map->Uorder, map->Vorder); + glTexCoord2fv( texcoord ); + } + else if (ctx->Eval.Map2TextureCoord1) { + GLfloat texcoord[4]; + struct gl_2d_map *map = &ctx->EvalMap.Map2Texture1; + GLfloat uu = (u - map->u1) * map->du; + GLfloat vv = (v - map->v1) * map->dv; + _math_horner_bezier_surf(map->Points, texcoord, uu, vv, 1, + map->Uorder, map->Vorder); + glTexCoord1fv( texcoord ); + } + + /** Vertex **/ + if(ctx->Eval.Map2Vertex4) { + GLfloat vertex[4]; + GLfloat normal[3]; + struct gl_2d_map *map = &ctx->EvalMap.Map2Vertex4; + GLfloat uu = (u - map->u1) * map->du; + GLfloat vv = (v - map->v1) * map->dv; + + if (ctx->Eval.AutoNormal) { + GLfloat du[4], dv[4]; + + _math_de_casteljau_surf(map->Points, vertex, du, dv, uu, vv, 4, + map->Uorder, map->Vorder); + + CROSS_PROD(normal, du, dv); + NORMALIZE_3FV(normal); + } + else { + _math_horner_bezier_surf(map->Points, vertex, uu, vv, 4, + map->Uorder, map->Vorder); + } + } + else if (ctx->Eval.Map2Vertex3) { + GLfloat vertex[4]; + struct gl_2d_map *map = &ctx->EvalMap.Map2Vertex3; + GLfloat uu = (u - map->u1) * map->du; + GLfloat vv = (v - map->v1) * map->dv; + if (ctx->Eval.AutoNormal) { + GLfloat du[3], dv[3]; + GLfloat normal[3]; + _math_de_casteljau_surf(map->Points, vertex, du, dv, uu, vv, 3, + map->Uorder, map->Vorder); + CROSS_PROD(normal, du, dv); + NORMALIZE_3FV(normal); + glNormal3fv( normal ); + glVertex3fv( vertex ); + } + else { + _math_horner_bezier_surf(map->Points, vertex, uu, vv, 3, + map->Uorder, map->Vorder); + glVertex3fv( vertex ); + } + } +} + + +void _mesa_EvalPoint1( GLint i ) +{ + GET_CURRENT_CONTEXT( ctx ); + GLfloat du = ((ctx->Eval.MapGrid1u2 - ctx->Eval.MapGrid1u1) / + (GLfloat) ctx->Eval.MapGrid1un); + GLfloat u = i * du + ctx->Eval.MapGrid1u1; + + glEvalCoord1f( u ); +} + + +void _mesa_EvalPoint2( GLint i, GLint j ) +{ + GET_CURRENT_CONTEXT( ctx ); + GLfloat du = ((ctx->Eval.MapGrid2u2 - ctx->Eval.MapGrid2u1) / + (GLfloat) ctx->Eval.MapGrid2un); + GLfloat dv = ((ctx->Eval.MapGrid2v2 - ctx->Eval.MapGrid2v1) / + (GLfloat) ctx->Eval.MapGrid2vn); + GLfloat u = i * du + ctx->Eval.MapGrid2u1; + GLfloat v = j * dv + ctx->Eval.MapGrid2v1; + + glEvalCoord2f( u, v ); +} + +/* Wierd thing about eval is that it doesn't affect 'current' values. + * This technique of saving and resetting current values requires + * that: + * + * 1) Current values are updated immediately in the glColor, + * etc. functions. + * + * 2) Hardware color values are stored seperately from ctx->Current, + * for example in dma buffers, or direct emit to registers. + */ +void _mesa_EvalCoord1f( GLfloat u ) +{ + GET_CURRENT_CONTEXT( ctx ); + GLfloat normal[3], texcoord[4], color[4]; + GLuint index; + + COPY_3FV( normal, ctx->Current.Normal ); + COPY_4FV( texcoord, ctx->Current.Texcoord[0] ); + COPY_4FV( color, ctx->Current.Color ); + index = ctx->Current.Index; + + do_EvalCoord1f( ctx, u ); + + COPY_3FV( ctx->Current.Normal, normal ); + COPY_4FV( ctx->Current.Texcoord[0], texcoord ); + COPY_4FV( ctx->Current.Color, color ); + ctx->Current.Index = index; +} + +void _mesa_EvalCoord2f( GLfloat u, GLfloat v ) +{ + GET_CURRENT_CONTEXT( ctx ); + GLfloat normal[3], texcoord[4], color[4]; + GLuint index; + + COPY_3FV( normal, ctx->Current.Normal ); + COPY_4FV( texcoord, ctx->Current.Texcoord[0] ); + COPY_4FV( color, ctx->Current.Color ); + index = ctx->Current.Index; + + do_EvalCoord2f( ctx, u, v ); + + COPY_3FV( ctx->Current.Normal, normal ); + COPY_4FV( ctx->Current.Texcoord[0], texcoord ); + COPY_4FV( ctx->Current.Color, color ); + ctx->Current.Index = index; +} + +void _mesa_EvalCoord1fv( const GLfloat *u ) +{ + glEvalCoord1f( u[0] ); +} + +void _mesa_EvalCoord2fv( const GLfloat *u ) +{ + glEvalCoord2f( u[0], u[1] ); +} Index: dll/opengl/opengl32/mesa/api_eval.h =================================================================== --- dll/opengl/opengl32/mesa/api_eval.h (revision 0) +++ dll/opengl/opengl32/mesa/api_eval.h (working copy) @@ -0,0 +1,43 @@ +/* $Id: api_eval.h,v 1.1 2001/06/04 13:57:35 keithw Exp $ */ + +/* + * Mesa 3-D graphics library + * Version: 3.5 + * + * Copyright (C) 1999-2001 Brian Paul 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 + * BRIAN PAUL 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. + */ + + +#ifndef API_EVAL_H +#define API_EVAL_H + +#include "mtypes.h" + +extern void _mesa_EvalPoint1( GLint i ); +extern void _mesa_EvalPoint2( GLint i, GLint j ); +extern void _mesa_EvalCoord1f( GLfloat u ); +extern void _mesa_EvalCoord2f( GLfloat u, GLfloat v ); +extern void _mesa_EvalCoord1fv( const GLfloat *u ); +extern void _mesa_EvalCoord2fv( const GLfloat *u ); + +#endif + + + Index: dll/opengl/opengl32/mesa/api_loopback.c =================================================================== --- dll/opengl/opengl32/mesa/api_loopback.c (revision 0) +++ dll/opengl/opengl32/mesa/api_loopback.c (working copy) @@ -0,0 +1,1561 @@ +/* $Id: api_loopback.c,v 1.8 2001/05/10 15:42:42 keithw Exp $ */ + +/* + * Mesa 3-D graphics library + * Version: 3.5 + * + * Copyright (C) 1999-2001 Brian Paul 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 + * BRIAN PAUL 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. + * + * Authors: + * Keith Whitwell + */ + + +#include "glheader.h" +#include "glapitable.h" +#include "macros.h" +#include "colormac.h" +#include "api_loopback.h" + +/* KW: A set of functions to convert unusual Color/Normal/Vertex/etc + * calls to a smaller set of driver-provided formats. Currently just + * go back to dispatch to find these (eg. call glNormal3f directly), + * hence 'loopback'. + * + * The driver must supply all of the remaining entry points, which are + * listed in dd.h. The easiest way for a driver to do this is to + * install the supplied software t&l module. + */ +#define DRIVER(x) gl##x +#define COLORUBV(v) DRIVER(Color4ubv)(v) +#define COLORF(r,g,b,a) DRIVER(Color4f)(r,g,b,a) +#define FOGCOORDF(x) DRIVER(FogCoordfEXT)(x) +#define VERTEX2(x,y) DRIVER(Vertex2f)(x,y) +#define VERTEX3(x,y,z) DRIVER(Vertex3f)(x,y,z) +#define VERTEX4(x,y,z,w) DRIVER(Vertex4f)(x,y,z,w) +#define NORMAL(x,y,z) DRIVER(Normal3f)(x,y,z) +#define TEXCOORD1(s) DRIVER(TexCoord1f)(s) +#define TEXCOORD2(s,t) DRIVER(TexCoord2f)(s,t) +#define TEXCOORD3(s,t,u) DRIVER(TexCoord3f)(s,t,u) +#define TEXCOORD4(s,t,u,v) DRIVER(TexCoord4f)(s,t,u,v) +#define INDEX(c) DRIVER(Indexi)(c) +#define MULTI_TEXCOORD1(z,s) DRIVER(MultiTexCoord1fARB)(z,s) +#define MULTI_TEXCOORD2(z,s,t) DRIVER(MultiTexCoord2fARB)(z,s,t) +#define MULTI_TEXCOORD3(z,s,t,u) DRIVER(MultiTexCoord3fARB)(z,s,t,u) +#define MULTI_TEXCOORD4(z,s,t,u,v) DRIVER(MultiTexCoord4fARB)(z,s,t,u,v) +#define EVALCOORD1(x) DRIVER(EvalCoord1f)(x) +#define EVALCOORD2(x,y) DRIVER(EvalCoord2f)(x,y) +#define MATERIALFV(a,b,c) DRIVER(Materialfv)(a,b,c) +#define RECTF(a,b,c,d) DRIVER(Rectf)(a,b,c,d) +#define SECONDARYCOLORUB(a,b,c) DRIVER(SecondaryColor3ubEXT)(a,b,c) +#define SECONDARYCOLORF(a,b,c) DRIVER(SecondaryColor3fEXT)(a,b,c) + + +static void +loopback_Color3b( GLbyte red, GLbyte green, GLbyte blue ) +{ + GLubyte col[4]; + col[0] = BYTE_TO_UBYTE(red); + col[1] = BYTE_TO_UBYTE(green); + col[2] = BYTE_TO_UBYTE(blue); + col[3] = 255; + COLORUBV(col); +} + +static void +loopback_Color3d( GLdouble red, GLdouble green, GLdouble blue ) +{ + GLubyte col[4]; + GLfloat r = red; + GLfloat g = green; + GLfloat b = blue; + UNCLAMPED_FLOAT_TO_UBYTE(col[0], r); + UNCLAMPED_FLOAT_TO_UBYTE(col[1], g); + UNCLAMPED_FLOAT_TO_UBYTE(col[2], b); + col[3] = 255; + COLORUBV( col ); +} + +static void +loopback_Color3i( GLint red, GLint green, GLint blue ) +{ + GLubyte col[4]; + col[0] = INT_TO_UBYTE(red); + col[1] = INT_TO_UBYTE(green); + col[2] = INT_TO_UBYTE(blue); + col[3] = 255; + COLORUBV(col); +} + +static void +loopback_Color3s( GLshort red, GLshort green, GLshort blue ) +{ + GLubyte col[4]; + col[0] = SHORT_TO_UBYTE(red); + col[1] = SHORT_TO_UBYTE(green); + col[2] = SHORT_TO_UBYTE(blue); + col[3] = 255; + COLORUBV(col); +} + +static void +loopback_Color3ui( GLuint red, GLuint green, GLuint blue ) +{ + GLubyte col[4]; + col[0] = UINT_TO_UBYTE(red); + col[1] = UINT_TO_UBYTE(green); + col[2] = UINT_TO_UBYTE(blue); + col[3] = 255; + COLORUBV(col); +} + +static void +loopback_Color3us( GLushort red, GLushort green, GLushort blue ) +{ + GLubyte col[4]; + col[0] = USHORT_TO_UBYTE(red); + col[1] = USHORT_TO_UBYTE(green); + col[2] = USHORT_TO_UBYTE(blue); + col[3] = 255; + COLORUBV(col); +} + +static void +loopback_Color4b( GLbyte red, GLbyte green, GLbyte blue, GLbyte alpha ) +{ + GLubyte col[4]; + col[0] = BYTE_TO_UBYTE(red); + col[1] = BYTE_TO_UBYTE(green); + col[2] = BYTE_TO_UBYTE(blue); + col[3] = 255; + COLORUBV(col); +} + +static void +loopback_Color4d( GLdouble red, GLdouble green, GLdouble blue, GLdouble alpha ) +{ + GLubyte col[4]; + GLfloat r = red; + GLfloat g = green; + GLfloat b = blue; + GLfloat a = alpha; + UNCLAMPED_FLOAT_TO_UBYTE(col[0], r); + UNCLAMPED_FLOAT_TO_UBYTE(col[1], g); + UNCLAMPED_FLOAT_TO_UBYTE(col[2], b); + UNCLAMPED_FLOAT_TO_UBYTE(col[3], a); + COLORUBV( col ); +} + +static void +loopback_Color4i( GLint red, GLint green, GLint blue, GLint alpha ) +{ + GLubyte col[4]; + col[0] = INT_TO_UBYTE(red); + col[1] = INT_TO_UBYTE(green); + col[2] = INT_TO_UBYTE(blue); + col[3] = INT_TO_UBYTE(alpha); + COLORUBV(col); +} + +static void +loopback_Color4s( GLshort red, GLshort green, GLshort blue, + GLshort alpha ) +{ + GLubyte col[4]; + col[0] = SHORT_TO_UBYTE(red); + col[1] = SHORT_TO_UBYTE(green); + col[2] = SHORT_TO_UBYTE(blue); + col[3] = SHORT_TO_UBYTE(alpha); + COLORUBV(col); +} + +static void +loopback_Color4ui( GLuint red, GLuint green, GLuint blue, GLuint alpha ) +{ + GLubyte col[4]; + col[0] = UINT_TO_UBYTE(red); + col[1] = UINT_TO_UBYTE(green); + col[2] = UINT_TO_UBYTE(blue); + col[3] = UINT_TO_UBYTE(alpha); + COLORUBV(col); +} + +static void +loopback_Color4us( GLushort red, GLushort green, GLushort blue, + GLushort alpha ) +{ + GLubyte col[4]; + col[0] = USHORT_TO_UBYTE(red); + col[1] = USHORT_TO_UBYTE(green); + col[2] = USHORT_TO_UBYTE(blue); + col[3] = USHORT_TO_UBYTE(alpha); + COLORUBV(col); +} + +static void +loopback_Color3bv( const GLbyte *v ) +{ + GLubyte col[4]; + col[0] = BYTE_TO_UBYTE(v[0]); + col[1] = BYTE_TO_UBYTE(v[1]); + col[2] = BYTE_TO_UBYTE(v[2]); + col[3] = 255; + COLORUBV(col); +} + +static void +loopback_Color3dv( const GLdouble *v ) +{ + GLubyte col[4]; + GLfloat r = v[0]; + GLfloat g = v[1]; + GLfloat b = v[2]; + UNCLAMPED_FLOAT_TO_UBYTE(col[0], r); + UNCLAMPED_FLOAT_TO_UBYTE(col[1], g); + UNCLAMPED_FLOAT_TO_UBYTE(col[2], b); + col[3] = 255; + COLORUBV( col ); +} + +static void +loopback_Color3iv( const GLint *v ) +{ + GLubyte col[4]; + col[0] = INT_TO_UBYTE(v[0]); + col[1] = INT_TO_UBYTE(v[1]); + col[2] = INT_TO_UBYTE(v[2]); + col[3] = 255; + COLORUBV(col); +} + +static void +loopback_Color3sv( const GLshort *v ) +{ + GLubyte col[4]; + col[0] = SHORT_TO_UBYTE(v[0]); + col[1] = SHORT_TO_UBYTE(v[1]); + col[2] = SHORT_TO_UBYTE(v[2]); + col[3] = 255; + COLORUBV(col); +} + +static void +loopback_Color3uiv( const GLuint *v ) +{ + GLubyte col[4]; + col[0] = UINT_TO_UBYTE(v[0]); + col[1] = UINT_TO_UBYTE(v[1]); + col[2] = UINT_TO_UBYTE(v[2]); + col[3] = 255; + COLORUBV(col); +} + +static void +loopback_Color3usv( const GLushort *v ) +{ + GLubyte col[4]; + col[0] = USHORT_TO_UBYTE(v[0]); + col[1] = USHORT_TO_UBYTE(v[1]); + col[2] = USHORT_TO_UBYTE(v[2]); + col[3] = 255; + COLORUBV(col); + +} + +static void +loopback_Color4bv( const GLbyte *v ) +{ + GLubyte col[4]; + col[0] = BYTE_TO_UBYTE(v[0]); + col[1] = BYTE_TO_UBYTE(v[1]); + col[2] = BYTE_TO_UBYTE(v[2]); + col[3] = BYTE_TO_UBYTE(v[3]); + COLORUBV(col); +} + +static void +loopback_Color4dv( const GLdouble *v ) +{ + GLubyte col[4]; + GLfloat r = v[0]; + GLfloat g = v[1]; + GLfloat b = v[2]; + GLfloat a = v[3]; + UNCLAMPED_FLOAT_TO_UBYTE(col[0], r); + UNCLAMPED_FLOAT_TO_UBYTE(col[1], g); + UNCLAMPED_FLOAT_TO_UBYTE(col[2], b); + UNCLAMPED_FLOAT_TO_UBYTE(col[3], a); + COLORUBV( col ); +} + +static void +loopback_Color4iv( const GLint *v ) +{ + GLubyte col[4]; + col[0] = INT_TO_UBYTE(v[0]); + col[1] = INT_TO_UBYTE(v[1]); + col[2] = INT_TO_UBYTE(v[2]); + col[3] = INT_TO_UBYTE(v[3]); + COLORUBV(col); +} + +static void +loopback_Color4sv( const GLshort *v) +{ + GLubyte col[4]; + col[0] = SHORT_TO_UBYTE(v[0]); + col[1] = SHORT_TO_UBYTE(v[1]); + col[2] = SHORT_TO_UBYTE(v[2]); + col[3] = SHORT_TO_UBYTE(v[3]); + COLORUBV(col); +} + +static void +loopback_Color4uiv( const GLuint *v) +{ + GLubyte col[4]; + col[0] = UINT_TO_UBYTE(v[0]); + col[1] = UINT_TO_UBYTE(v[1]); + col[2] = UINT_TO_UBYTE(v[2]); + col[3] = UINT_TO_UBYTE(v[3]); + COLORUBV(col); +} + +static void +loopback_Color4usv( const GLushort *v) +{ + GLubyte col[4]; + col[0] = USHORT_TO_UBYTE(v[0]); + col[1] = USHORT_TO_UBYTE(v[1]); + col[2] = USHORT_TO_UBYTE(v[2]); + col[3] = USHORT_TO_UBYTE(v[3]); + COLORUBV(col); +} + +static void +loopback_Color3b_f( GLbyte red, GLbyte green, GLbyte blue ) +{ + COLORF( BYTE_TO_FLOAT(red), + BYTE_TO_FLOAT(green), + BYTE_TO_FLOAT(blue), + 1.0 ); +} + +static void +loopback_Color3d_f( GLdouble red, GLdouble green, GLdouble blue ) +{ + COLORF( red, green, blue, 1.0 ); +} + +static void +loopback_Color3i_f( GLint red, GLint green, GLint blue ) +{ + COLORF( INT_TO_FLOAT(red), INT_TO_FLOAT(green), + INT_TO_FLOAT(blue), 1.0); +} + +static void +loopback_Color3s_f( GLshort red, GLshort green, GLshort blue ) +{ + COLORF( SHORT_TO_FLOAT(red), SHORT_TO_FLOAT(green), + SHORT_TO_FLOAT(blue), 1.0); +} + +static void +loopback_Color3ui_f( GLuint red, GLuint green, GLuint blue ) +{ + COLORF( UINT_TO_FLOAT(red), UINT_TO_FLOAT(green), + UINT_TO_FLOAT(blue), 1.0 ); +} + +static void +loopback_Color3us_f( GLushort red, GLushort green, GLushort blue ) +{ + COLORF( USHORT_TO_FLOAT(red), USHORT_TO_FLOAT(green), + USHORT_TO_FLOAT(blue), 1.0 ); +} + + +static void +loopback_Color3bv_f( const GLbyte *v ) +{ + COLORF( BYTE_TO_FLOAT(v[0]), BYTE_TO_FLOAT(v[1]), + BYTE_TO_FLOAT(v[2]), 1.0 ); +} + +static void +loopback_Color3dv_f( const GLdouble *v ) +{ + COLORF( v[0], v[1], v[2], 1.0 ); +} + +static void +loopback_Color3iv_f( const GLint *v ) +{ + COLORF( INT_TO_FLOAT(v[0]), INT_TO_FLOAT(v[1]), + INT_TO_FLOAT(v[2]), INT_TO_FLOAT(v[3]) ); +} + +static void +loopback_Color3sv_f( const GLshort *v ) +{ + COLORF( SHORT_TO_FLOAT(v[0]), SHORT_TO_FLOAT(v[1]), + SHORT_TO_FLOAT(v[2]), 1.0 ); +} + +static void +loopback_Color3uiv_f( const GLuint *v ) +{ + COLORF( UINT_TO_FLOAT(v[0]), UINT_TO_FLOAT(v[1]), + UINT_TO_FLOAT(v[2]), 1.0 ); +} + +static void +loopback_Color3usv_f( const GLushort *v ) +{ + COLORF( USHORT_TO_FLOAT(v[0]), USHORT_TO_FLOAT(v[1]), + USHORT_TO_FLOAT(v[2]), 1.0 ); +} + + +static void +loopback_Color4b_f( GLbyte red, GLbyte green, GLbyte blue, + GLbyte alpha ) +{ + COLORF( BYTE_TO_FLOAT(red), BYTE_TO_FLOAT(green), + BYTE_TO_FLOAT(blue), BYTE_TO_FLOAT(alpha) ); +} + +static void +loopback_Color4d_f( GLdouble red, GLdouble green, GLdouble blue, + GLdouble alpha ) +{ + COLORF( red, green, blue, alpha ); +} + +static void +loopback_Color4i_f( GLint red, GLint green, GLint blue, GLint alpha ) +{ + COLORF( INT_TO_FLOAT(red), INT_TO_FLOAT(green), + INT_TO_FLOAT(blue), INT_TO_FLOAT(alpha) ); +} + +static void +loopback_Color4s_f( GLshort red, GLshort green, GLshort blue, + GLshort alpha ) +{ + COLORF( SHORT_TO_FLOAT(red), SHORT_TO_FLOAT(green), + SHORT_TO_FLOAT(blue), SHORT_TO_FLOAT(alpha) ); +} + +static void +loopback_Color4ui_f( GLuint red, GLuint green, GLuint blue, GLuint alpha ) +{ + COLORF( UINT_TO_FLOAT(red), UINT_TO_FLOAT(green), + UINT_TO_FLOAT(blue), UINT_TO_FLOAT(alpha) ); +} + +static void +loopback_Color4us_f( GLushort red, GLushort green, GLushort blue, GLushort alpha ) +{ + COLORF( USHORT_TO_FLOAT(red), USHORT_TO_FLOAT(green), + USHORT_TO_FLOAT(blue), USHORT_TO_FLOAT(alpha) ); +} + + +static void +loopback_Color4iv_f( const GLint *v ) +{ + COLORF( INT_TO_FLOAT(v[0]), INT_TO_FLOAT(v[1]), + INT_TO_FLOAT(v[2]), INT_TO_FLOAT(v[3]) ); +} + + +static void +loopback_Color4bv_f( const GLbyte *v ) +{ + COLORF( BYTE_TO_FLOAT(v[0]), BYTE_TO_FLOAT(v[1]), + BYTE_TO_FLOAT(v[2]), BYTE_TO_FLOAT(v[3]) ); +} + +static void +loopback_Color4dv_f( const GLdouble *v ) +{ + COLORF( v[0], v[1], v[2], v[3] ); +} + + +static void +loopback_Color4sv_f( const GLshort *v) +{ + COLORF( SHORT_TO_FLOAT(v[0]), SHORT_TO_FLOAT(v[1]), + SHORT_TO_FLOAT(v[2]), SHORT_TO_FLOAT(v[3]) ); +} + + +static void +loopback_Color4uiv_f( const GLuint *v) +{ + COLORF( UINT_TO_FLOAT(v[0]), UINT_TO_FLOAT(v[1]), + UINT_TO_FLOAT(v[2]), UINT_TO_FLOAT(v[3]) ); +} + +static void +loopback_Color4usv_f( const GLushort *v) +{ + COLORF( USHORT_TO_FLOAT(v[0]), USHORT_TO_FLOAT(v[1]), + USHORT_TO_FLOAT(v[2]), USHORT_TO_FLOAT(v[3]) ); +} + +static void +loopback_FogCoorddEXT( GLdouble d ) +{ + FOGCOORDF( d ); +} + +static void +loopback_FogCoorddvEXT( const GLdouble *v ) +{ + FOGCOORDF( *v ); +} + + +static void +loopback_Indexd( GLdouble c ) +{ + INDEX( (GLint) c ); +} + +static void +loopback_Indexf( GLfloat c ) +{ + INDEX( (GLuint) (GLint) c ); +} + +static void +loopback_Indexs( GLshort c ) +{ + INDEX( (GLint) c ); +} + +static void +loopback_Indexub( GLubyte c ) +{ + INDEX( (GLint) c ); +} + +static void +loopback_Indexdv( const GLdouble *c ) +{ + INDEX( (GLint) (GLint) *c ); +} + +static void +loopback_Indexfv( const GLfloat *c ) +{ + INDEX( (GLint) (GLint) *c ); +} + +static void +loopback_Indexiv( const GLint *c ) +{ + INDEX( *c ); +} + +static void +loopback_Indexsv( const GLshort *c ) +{ + INDEX( (GLint) *c ); +} + +static void +loopback_Indexubv( const GLubyte *c ) +{ + INDEX( (GLint) *c ); +} + +static void +loopback_Normal3b( GLbyte nx, GLbyte ny, GLbyte nz ) +{ + NORMAL( BYTE_TO_FLOAT(nx), BYTE_TO_FLOAT(ny), BYTE_TO_FLOAT(nz) ); +} + +static void +loopback_Normal3d( GLdouble nx, GLdouble ny, GLdouble nz ) +{ + NORMAL(nx, ny, nz); +} + +static void +loopback_Normal3i( GLint nx, GLint ny, GLint nz ) +{ + NORMAL( INT_TO_FLOAT(nx), INT_TO_FLOAT(ny), INT_TO_FLOAT(nz) ); +} + +static void +loopback_Normal3s( GLshort nx, GLshort ny, GLshort nz ) +{ + NORMAL( SHORT_TO_FLOAT(nx), SHORT_TO_FLOAT(ny), SHORT_TO_FLOAT(nz) ); +} + +static void +loopback_Normal3bv( const GLbyte *v ) +{ + NORMAL( BYTE_TO_FLOAT(v[0]), BYTE_TO_FLOAT(v[1]), BYTE_TO_FLOAT(v[2]) ); +} + +static void +loopback_Normal3dv( const GLdouble *v ) +{ + NORMAL( v[0], v[1], v[2] ); +} + +static void +loopback_Normal3iv( const GLint *v ) +{ + NORMAL( INT_TO_FLOAT(v[0]), INT_TO_FLOAT(v[1]), INT_TO_FLOAT(v[2]) ); +} + +static void +loopback_Normal3sv( const GLshort *v ) +{ + NORMAL( SHORT_TO_FLOAT(v[0]), SHORT_TO_FLOAT(v[1]), SHORT_TO_FLOAT(v[2]) ); +} + +static void +loopback_TexCoord1d( GLdouble s ) +{ + TEXCOORD1(s); +} + +static void +loopback_TexCoord1i( GLint s ) +{ + TEXCOORD1(s); +} + +static void +loopback_TexCoord1s( GLshort s ) +{ + TEXCOORD1(s); +} + +static void +loopback_TexCoord2d( GLdouble s, GLdouble t ) +{ + TEXCOORD2(s,t); +} + +static void +loopback_TexCoord2s( GLshort s, GLshort t ) +{ + TEXCOORD2(s,t); +} + +static void +loopback_TexCoord2i( GLint s, GLint t ) +{ + TEXCOORD2(s,t); +} + +static void +loopback_TexCoord3d( GLdouble s, GLdouble t, GLdouble r ) +{ + TEXCOORD3(s,t,r); +} + +static void +loopback_TexCoord3i( GLint s, GLint t, GLint r ) +{ + TEXCOORD3(s,t,r); +} + +static void +loopback_TexCoord3s( GLshort s, GLshort t, GLshort r ) +{ + TEXCOORD3(s,t,r); +} + +static void +loopback_TexCoord4d( GLdouble s, GLdouble t, GLdouble r, GLdouble q ) +{ + TEXCOORD4(s,t,r,q); +} + +static void +loopback_TexCoord4i( GLint s, GLint t, GLint r, GLint q ) +{ + TEXCOORD4(s,t,r,q); +} + +static void +loopback_TexCoord4s( GLshort s, GLshort t, GLshort r, GLshort q ) +{ + TEXCOORD4(s,t,r,q); +} + +static void +loopback_TexCoord1dv( const GLdouble *v ) +{ + TEXCOORD1(v[0]); +} + +static void +loopback_TexCoord1iv( const GLint *v ) +{ + TEXCOORD1(v[0]); +} + +static void +loopback_TexCoord1sv( const GLshort *v ) +{ + TEXCOORD1(v[0]); +} + +static void +loopback_TexCoord2dv( const GLdouble *v ) +{ + TEXCOORD2(v[0],v[1]); +} + +static void +loopback_TexCoord2iv( const GLint *v ) +{ + TEXCOORD2(v[0],v[1]); +} + +static void +loopback_TexCoord2sv( const GLshort *v ) +{ + TEXCOORD2(v[0],v[1]); +} + +static void +loopback_TexCoord3dv( const GLdouble *v ) +{ + TEXCOORD2(v[0],v[1]); +} + +static void +loopback_TexCoord3iv( const GLint *v ) +{ + TEXCOORD3(v[0],v[1],v[2]); +} + +static void +loopback_TexCoord3sv( const GLshort *v ) +{ + TEXCOORD3(v[0],v[1],v[2]); +} + +static void +loopback_TexCoord4dv( const GLdouble *v ) +{ + TEXCOORD4(v[0],v[1],v[2],v[3]); +} + +static void +loopback_TexCoord4iv( const GLint *v ) +{ + TEXCOORD4(v[0],v[1],v[2],v[3]); +} + +static void +loopback_TexCoord4sv( const GLshort *v ) +{ + TEXCOORD4(v[0],v[1],v[2],v[3]); +} + +static void +loopback_Vertex2d( GLdouble x, GLdouble y ) +{ + VERTEX2( (GLfloat) x, (GLfloat) y ); +} + +static void +loopback_Vertex2i( GLint x, GLint y ) +{ + VERTEX2( (GLfloat) x, (GLfloat) y ); +} + +static void +loopback_Vertex2s( GLshort x, GLshort y ) +{ + VERTEX2( (GLfloat) x, (GLfloat) y ); +} + +static void +loopback_Vertex3d( GLdouble x, GLdouble y, GLdouble z ) +{ + VERTEX3( (GLfloat) x, (GLfloat) y, (GLfloat) z ); +} + +static void +loopback_Vertex3i( GLint x, GLint y, GLint z ) +{ + VERTEX3( (GLfloat) x, (GLfloat) y, (GLfloat) z ); +} + +static void +loopback_Vertex3s( GLshort x, GLshort y, GLshort z ) +{ + VERTEX3( (GLfloat) x, (GLfloat) y, (GLfloat) z ); +} + +static void +loopback_Vertex4d( GLdouble x, GLdouble y, GLdouble z, GLdouble w ) +{ + VERTEX4( (GLfloat) x, (GLfloat) y, (GLfloat) z, (GLfloat) w ); +} + +static void +loopback_Vertex4i( GLint x, GLint y, GLint z, GLint w ) +{ + VERTEX4( (GLfloat) x, (GLfloat) y, (GLfloat) z, (GLfloat) w ); +} + +static void +loopback_Vertex4s( GLshort x, GLshort y, GLshort z, GLshort w ) +{ + VERTEX4( (GLfloat) x, (GLfloat) y, (GLfloat) z, (GLfloat) w ); +} + +static void +loopback_Vertex2dv( const GLdouble *v ) +{ + VERTEX2( (GLfloat) v[0], (GLfloat) v[1] ); +} + +static void +loopback_Vertex2iv( const GLint *v ) +{ + VERTEX2( (GLfloat) v[0], (GLfloat) v[1] ); +} + +static void +loopback_Vertex2sv( const GLshort *v ) +{ + VERTEX2( (GLfloat) v[0], (GLfloat) v[1] ); +} + +static void +loopback_Vertex3dv( const GLdouble *v ) +{ + VERTEX3( (GLfloat) v[0], (GLfloat) v[1], (GLfloat) v[2] ); +} + +static void +loopback_Vertex3iv( const GLint *v ) +{ + VERTEX3( (GLfloat) v[0], (GLfloat) v[1], (GLfloat) v[2] ); +} + +static void +loopback_Vertex3sv( const GLshort *v ) +{ + VERTEX3( (GLfloat) v[0], (GLfloat) v[1], (GLfloat) v[2] ); +} + +static void +loopback_Vertex4dv( const GLdouble *v ) +{ + VERTEX4( (GLfloat) v[0], (GLfloat) v[1], + (GLfloat) v[2], (GLfloat) v[3] ); +} + +static void +loopback_Vertex4iv( const GLint *v ) +{ + VERTEX4( (GLfloat) v[0], (GLfloat) v[1], + (GLfloat) v[2], (GLfloat) v[3] ); +} + +static void +loopback_Vertex4sv( const GLshort *v ) +{ + VERTEX4( (GLfloat) v[0], (GLfloat) v[1], + (GLfloat) v[2], (GLfloat) v[3] ); +} + +static void +loopback_MultiTexCoord1dARB(GLenum target, GLdouble s) +{ + MULTI_TEXCOORD1( target, s ); +} + +static void +loopback_MultiTexCoord1dvARB(GLenum target, const GLdouble *v) +{ + MULTI_TEXCOORD1( target, v[0] ); +} + +static void +loopback_MultiTexCoord1iARB(GLenum target, GLint s) +{ + MULTI_TEXCOORD1( target, s ); +} + +static void +loopback_MultiTexCoord1ivARB(GLenum target, const GLint *v) +{ + MULTI_TEXCOORD1( target, v[0] ); +} + +static void +loopback_MultiTexCoord1sARB(GLenum target, GLshort s) +{ + MULTI_TEXCOORD1( target, s ); +} + +static void +loopback_MultiTexCoord1svARB(GLenum target, const GLshort *v) +{ + MULTI_TEXCOORD1( target, v[0] ); +} + +static void +loopback_MultiTexCoord2dARB(GLenum target, GLdouble s, GLdouble t) +{ + MULTI_TEXCOORD2( target, s, t ); +} + +static void +loopback_MultiTexCoord2dvARB(GLenum target, const GLdouble *v) +{ + MULTI_TEXCOORD2( target, v[0], v[1] ); +} + +static void +loopback_MultiTexCoord2iARB(GLenum target, GLint s, GLint t) +{ + MULTI_TEXCOORD2( target, s, t ); +} + +static void +loopback_MultiTexCoord2ivARB(GLenum target, const GLint *v) +{ + MULTI_TEXCOORD2( target, v[0], v[1] ); +} + +static void +loopback_MultiTexCoord2sARB(GLenum target, GLshort s, GLshort t) +{ + MULTI_TEXCOORD2( target, s, t ); +} + +static void +loopback_MultiTexCoord2svARB(GLenum target, const GLshort *v) +{ + MULTI_TEXCOORD2( target, v[0], v[1] ); +} + +static void +loopback_MultiTexCoord3dARB(GLenum target, GLdouble s, GLdouble t, GLdouble r) +{ + MULTI_TEXCOORD3( target, s, t, r ); +} + +static void +loopback_MultiTexCoord3dvARB(GLenum target, const GLdouble *v) +{ + MULTI_TEXCOORD3( target, v[0], v[1], v[2] ); +} + +static void +loopback_MultiTexCoord3iARB(GLenum target, GLint s, GLint t, GLint r) +{ + MULTI_TEXCOORD3( target, s, t, r ); +} + +static void +loopback_MultiTexCoord3ivARB(GLenum target, const GLint *v) +{ + MULTI_TEXCOORD3( target, v[0], v[1], v[2] ); +} + +static void +loopback_MultiTexCoord3sARB(GLenum target, GLshort s, GLshort t, GLshort r) +{ + MULTI_TEXCOORD3( target, s, t, r ); +} + +static void +loopback_MultiTexCoord3svARB(GLenum target, const GLshort *v) +{ + MULTI_TEXCOORD3( target, v[0], v[1], v[2] ); +} + +static void +loopback_MultiTexCoord4dARB(GLenum target, GLdouble s, GLdouble t, GLdouble r, GLdouble q) +{ + MULTI_TEXCOORD4( target, s, t, r, q ); +} + +static void +loopback_MultiTexCoord4dvARB(GLenum target, const GLdouble *v) +{ + MULTI_TEXCOORD4( target, v[0], v[1], v[2], v[3] ); +} + +static void +loopback_MultiTexCoord4iARB(GLenum target, GLint s, GLint t, GLint r, GLint q) +{ + MULTI_TEXCOORD4( target, s, t, r, q ); +} + +static void +loopback_MultiTexCoord4ivARB(GLenum target, const GLint *v) +{ + MULTI_TEXCOORD4( target, v[0], v[1], v[2], v[3] ); +} + +static void +loopback_MultiTexCoord4sARB(GLenum target, GLshort s, GLshort t, GLshort r, GLshort q) +{ + MULTI_TEXCOORD4( target, s, t, r, q ); +} + +static void +loopback_MultiTexCoord4svARB(GLenum target, const GLshort *v) +{ + MULTI_TEXCOORD4( target, v[0], v[1], v[2], v[3] ); +} + +static void +loopback_EvalCoord2dv( const GLdouble *u ) +{ + EVALCOORD2( (GLfloat) u[0], (GLfloat) u[1] ); +} + +static void +loopback_EvalCoord2fv( const GLfloat *u ) +{ + EVALCOORD2( u[0], u[1] ); +} + +static void +loopback_EvalCoord2d( GLdouble u, GLdouble v ) +{ + EVALCOORD2( (GLfloat) u, (GLfloat) v ); +} + +static void +loopback_EvalCoord1dv( const GLdouble *u ) +{ + EVALCOORD1( (GLfloat) *u ); +} + +static void +loopback_EvalCoord1fv( const GLfloat *u ) +{ + EVALCOORD1( (GLfloat) *u ); +} + +static void +loopback_EvalCoord1d( GLdouble u ) +{ + EVALCOORD1( (GLfloat) u ); +} + +static void +loopback_Materialf( GLenum face, GLenum pname, GLfloat param ) +{ + GLfloat fparam[4]; + fparam[0] = param; + MATERIALFV( face, pname, fparam ); +} + +static void +loopback_Materiali(GLenum face, GLenum pname, GLint param ) +{ + GLfloat p = (GLfloat) param; + MATERIALFV(face, pname, &p); +} + +static void +loopback_Materialiv(GLenum face, GLenum pname, const GLint *params ) +{ + GLfloat fparam[4]; + switch (pname) { + case GL_AMBIENT: + case GL_DIFFUSE: + case GL_SPECULAR: + case GL_EMISSION: + case GL_AMBIENT_AND_DIFFUSE: + fparam[0] = INT_TO_FLOAT( params[0] ); + fparam[1] = INT_TO_FLOAT( params[1] ); + fparam[2] = INT_TO_FLOAT( params[2] ); + fparam[3] = INT_TO_FLOAT( params[3] ); + break; + case GL_SHININESS: + fparam[0] = (GLfloat) params[0]; + break; + case GL_COLOR_INDEXES: + fparam[0] = (GLfloat) params[0]; + fparam[1] = (GLfloat) params[1]; + fparam[2] = (GLfloat) params[2]; + break; + default: + ; + } + MATERIALFV(face, pname, fparam); +} + + +static void +loopback_Rectd(GLdouble x1, GLdouble y1, GLdouble x2, GLdouble y2) +{ + RECTF(x1, y1, x2, y2); +} + +static void +loopback_Rectdv(const GLdouble *v1, const GLdouble *v2) +{ + RECTF(v1[0], v1[1], v2[0], v2[1]); +} + +static void +loopback_Rectfv(const GLfloat *v1, const GLfloat *v2) +{ + RECTF(v1[0], v1[1], v2[0], v2[1]); +} + +static void +loopback_Recti(GLint x1, GLint y1, GLint x2, GLint y2) +{ + RECTF(x1, y1, x2, y2); +} + +static void +loopback_Rectiv(const GLint *v1, const GLint *v2) +{ + RECTF(v1[0], v1[1], v2[0], v2[1]); +} + +static void +loopback_Rects(GLshort x1, GLshort y1, GLshort x2, GLshort y2) +{ + RECTF(x1, y1, x2, y2); +} + +static void +loopback_Rectsv(const GLshort *v1, const GLshort *v2) +{ + RECTF(v1[0], v1[1], v2[0], v2[1]); +} + +static void +loopback_SecondaryColor3bEXT( GLbyte red, GLbyte green, GLbyte blue ) +{ + SECONDARYCOLORUB( BYTE_TO_UBYTE(red), + BYTE_TO_UBYTE(green), + BYTE_TO_UBYTE(blue) ); +} + +static void +loopback_SecondaryColor3dEXT( GLdouble red, GLdouble green, GLdouble blue ) +{ + GLubyte col[3]; + GLfloat r = red; + GLfloat g = green; + GLfloat b = blue; + UNCLAMPED_FLOAT_TO_UBYTE(col[0], r); + UNCLAMPED_FLOAT_TO_UBYTE(col[1], g); + UNCLAMPED_FLOAT_TO_UBYTE(col[2], b); + SECONDARYCOLORUB( col[0], col[1], col[2] ); +} + +static void +loopback_SecondaryColor3iEXT( GLint red, GLint green, GLint blue ) +{ + SECONDARYCOLORUB( INT_TO_UBYTE(red), + INT_TO_UBYTE(green), + INT_TO_UBYTE(blue)); +} + +static void +loopback_SecondaryColor3sEXT( GLshort red, GLshort green, GLshort blue ) +{ + SECONDARYCOLORUB(SHORT_TO_UBYTE(red), + SHORT_TO_UBYTE(green), + SHORT_TO_UBYTE(blue)); +} + +static void +loopback_SecondaryColor3uiEXT( GLuint red, GLuint green, GLuint blue ) +{ + SECONDARYCOLORUB(UINT_TO_UBYTE(red), + UINT_TO_UBYTE(green), + UINT_TO_UBYTE(blue)); +} + +static void +loopback_SecondaryColor3usEXT( GLushort red, GLushort green, GLushort blue ) +{ + SECONDARYCOLORUB(USHORT_TO_UBYTE(red), + USHORT_TO_UBYTE(green), + USHORT_TO_UBYTE(blue)); +} + +static void +loopback_SecondaryColor3bvEXT( const GLbyte *v ) +{ + const GLfloat r = BYTE_TO_FLOAT(v[0]); + const GLfloat g = BYTE_TO_FLOAT(v[1]); + const GLfloat b = BYTE_TO_FLOAT(v[2]); + SECONDARYCOLORF(r, g, b); +} + +static void +loopback_SecondaryColor3dvEXT( const GLdouble *v ) +{ + GLubyte col[3]; + GLfloat r = v[0]; + GLfloat g = v[1]; + GLfloat b = v[2]; + UNCLAMPED_FLOAT_TO_UBYTE(col[0], r); + UNCLAMPED_FLOAT_TO_UBYTE(col[1], g); + UNCLAMPED_FLOAT_TO_UBYTE(col[2], b); + SECONDARYCOLORUB( col[0], col[1], col[2] ); +} + +static void +loopback_SecondaryColor3ivEXT( const GLint *v ) +{ + SECONDARYCOLORUB(INT_TO_UBYTE(v[0]), + INT_TO_UBYTE(v[1]), + INT_TO_UBYTE(v[2])); +} + +static void +loopback_SecondaryColor3svEXT( const GLshort *v ) +{ + SECONDARYCOLORUB(SHORT_TO_UBYTE(v[0]), + SHORT_TO_UBYTE(v[1]), + SHORT_TO_UBYTE(v[2])); +} + +static void +loopback_SecondaryColor3uivEXT( const GLuint *v ) +{ + SECONDARYCOLORUB(UINT_TO_UBYTE(v[0]), + UINT_TO_UBYTE(v[1]), + UINT_TO_UBYTE(v[2])); +} + +static void +loopback_SecondaryColor3usvEXT( const GLushort *v ) +{ + SECONDARYCOLORUB(USHORT_TO_UBYTE(v[0]), + USHORT_TO_UBYTE(v[1]), + USHORT_TO_UBYTE(v[2])); +} + + +static void +loopback_SecondaryColor3bEXT_f( GLbyte red, GLbyte green, GLbyte blue ) +{ + SECONDARYCOLORF( BYTE_TO_FLOAT(red), + BYTE_TO_FLOAT(green), + BYTE_TO_FLOAT(blue) ); +} + +static void +loopback_SecondaryColor3dEXT_f( GLdouble red, GLdouble green, GLdouble blue ) +{ + SECONDARYCOLORF( red, green, blue ); +} + +static void +loopback_SecondaryColor3iEXT_f( GLint red, GLint green, GLint blue ) +{ + SECONDARYCOLORF( INT_TO_FLOAT(red), + INT_TO_FLOAT(green), + INT_TO_FLOAT(blue)); +} + +static void +loopback_SecondaryColor3sEXT_f( GLshort red, GLshort green, GLshort blue ) +{ + SECONDARYCOLORF(SHORT_TO_FLOAT(red), + SHORT_TO_FLOAT(green), + SHORT_TO_FLOAT(blue)); +} + +static void +loopback_SecondaryColor3uiEXT_f( GLuint red, GLuint green, GLuint blue ) +{ + SECONDARYCOLORF(UINT_TO_FLOAT(red), + UINT_TO_FLOAT(green), + UINT_TO_FLOAT(blue)); +} + +static void +loopback_SecondaryColor3usEXT_f( GLushort red, GLushort green, GLushort blue ) +{ + SECONDARYCOLORF(USHORT_TO_FLOAT(red), + USHORT_TO_FLOAT(green), + USHORT_TO_FLOAT(blue)); +} + +static void +loopback_SecondaryColor3bvEXT_f( const GLbyte *v ) +{ + SECONDARYCOLORF(BYTE_TO_FLOAT(v[0]), + BYTE_TO_FLOAT(v[1]), + BYTE_TO_FLOAT(v[2])); +} + +static void +loopback_SecondaryColor3dvEXT_f( const GLdouble *v ) +{ + SECONDARYCOLORF( v[0], v[1], v[2] ); +} +static void +loopback_SecondaryColor3ivEXT_f( const GLint *v ) +{ + SECONDARYCOLORF(INT_TO_FLOAT(v[0]), + INT_TO_FLOAT(v[1]), + INT_TO_FLOAT(v[2])); +} + +static void +loopback_SecondaryColor3svEXT_f( const GLshort *v ) +{ + SECONDARYCOLORF(SHORT_TO_FLOAT(v[0]), + SHORT_TO_FLOAT(v[1]), + SHORT_TO_FLOAT(v[2])); +} + +static void +loopback_SecondaryColor3uivEXT_f( const GLuint *v ) +{ + SECONDARYCOLORF(UINT_TO_FLOAT(v[0]), + UINT_TO_FLOAT(v[1]), + UINT_TO_FLOAT(v[2])); +} + +static void +loopback_SecondaryColor3usvEXT_f( const GLushort *v ) +{ + SECONDARYCOLORF(USHORT_TO_FLOAT(v[0]), + USHORT_TO_FLOAT(v[1]), + USHORT_TO_FLOAT(v[2])); +} + + + +void +_mesa_loopback_prefer_float( struct _glapi_table *dest, + GLboolean prefer_float_colors ) +{ + if (!prefer_float_colors) { + dest->Color3b = loopback_Color3b; + dest->Color3d = loopback_Color3d; + dest->Color3i = loopback_Color3i; + dest->Color3s = loopback_Color3s; + dest->Color3ui = loopback_Color3ui; + dest->Color3us = loopback_Color3us; + dest->Color4b = loopback_Color4b; + dest->Color4d = loopback_Color4d; + dest->Color4i = loopback_Color4i; + dest->Color4s = loopback_Color4s; + dest->Color4ui = loopback_Color4ui; + dest->Color4us = loopback_Color4us; + dest->Color3bv = loopback_Color3bv; + dest->Color3dv = loopback_Color3dv; + dest->Color3iv = loopback_Color3iv; + dest->Color3sv = loopback_Color3sv; + dest->Color3uiv = loopback_Color3uiv; + dest->Color3usv = loopback_Color3usv; + dest->Color4bv = loopback_Color4bv; + dest->Color4dv = loopback_Color4dv; + dest->Color4iv = loopback_Color4iv; + dest->Color4sv = loopback_Color4sv; + dest->Color4uiv = loopback_Color4uiv; + dest->Color4usv = loopback_Color4usv; + dest->SecondaryColor3bEXT = loopback_SecondaryColor3bEXT; + dest->SecondaryColor3dEXT = loopback_SecondaryColor3dEXT; + dest->SecondaryColor3iEXT = loopback_SecondaryColor3iEXT; + dest->SecondaryColor3sEXT = loopback_SecondaryColor3sEXT; + dest->SecondaryColor3uiEXT = loopback_SecondaryColor3uiEXT; + dest->SecondaryColor3usEXT = loopback_SecondaryColor3usEXT; + dest->SecondaryColor3bvEXT = loopback_SecondaryColor3bvEXT; + dest->SecondaryColor3dvEXT = loopback_SecondaryColor3dvEXT; + dest->SecondaryColor3ivEXT = loopback_SecondaryColor3ivEXT; + dest->SecondaryColor3svEXT = loopback_SecondaryColor3svEXT; + dest->SecondaryColor3uivEXT = loopback_SecondaryColor3uivEXT; + dest->SecondaryColor3usvEXT = loopback_SecondaryColor3usvEXT; + } + else { + dest->Color3b = loopback_Color3b_f; + dest->Color3d = loopback_Color3d_f; + dest->Color3i = loopback_Color3i_f; + dest->Color3s = loopback_Color3s_f; + dest->Color3ui = loopback_Color3ui_f; + dest->Color3us = loopback_Color3us_f; + dest->Color4b = loopback_Color4b_f; + dest->Color4d = loopback_Color4d_f; + dest->Color4i = loopback_Color4i_f; + dest->Color4s = loopback_Color4s_f; + dest->Color4ui = loopback_Color4ui_f; + dest->Color4us = loopback_Color4us_f; + dest->Color3bv = loopback_Color3bv_f; + dest->Color3dv = loopback_Color3dv_f; + dest->Color3iv = loopback_Color3iv_f; + dest->Color3sv = loopback_Color3sv_f; + dest->Color3uiv = loopback_Color3uiv_f; + dest->Color3usv = loopback_Color3usv_f; + dest->Color4bv = loopback_Color4bv_f; + dest->Color4dv = loopback_Color4dv_f; + dest->Color4iv = loopback_Color4iv_f; + dest->Color4sv = loopback_Color4sv_f; + dest->Color4uiv = loopback_Color4uiv_f; + dest->Color4usv = loopback_Color4usv_f; + dest->SecondaryColor3bEXT = loopback_SecondaryColor3bEXT_f; + dest->SecondaryColor3dEXT = loopback_SecondaryColor3dEXT_f; + dest->SecondaryColor3iEXT = loopback_SecondaryColor3iEXT_f; + dest->SecondaryColor3sEXT = loopback_SecondaryColor3sEXT_f; + dest->SecondaryColor3uiEXT = loopback_SecondaryColor3uiEXT_f; + dest->SecondaryColor3usEXT = loopback_SecondaryColor3usEXT_f; + dest->SecondaryColor3bvEXT = loopback_SecondaryColor3bvEXT_f; + dest->SecondaryColor3dvEXT = loopback_SecondaryColor3dvEXT_f; + dest->SecondaryColor3ivEXT = loopback_SecondaryColor3ivEXT_f; + dest->SecondaryColor3svEXT = loopback_SecondaryColor3svEXT_f; + dest->SecondaryColor3uivEXT = loopback_SecondaryColor3uivEXT_f; + dest->SecondaryColor3usvEXT = loopback_SecondaryColor3usvEXT_f; + } +} + +/* Passing prefer_float_colors as true will mean that all colors + * *except* Color{34}ub{v} are passed as floats. Setting it false will + * mean all colors *except* Color{34}f{v} are passed as ubytes. + * + * This code never registers handlers for any of the entry points + * listed in vtxfmt.h. + */ +void +_mesa_loopback_init_api_table( struct _glapi_table *dest, + GLboolean prefer_float_colors ) +{ + _mesa_loopback_prefer_float( dest, prefer_float_colors ); + + dest->Indexd = loopback_Indexd; + dest->Indexf = loopback_Indexf; + dest->Indexs = loopback_Indexs; + dest->Indexub = loopback_Indexub; + dest->Indexdv = loopback_Indexdv; + dest->Indexfv = loopback_Indexfv; + dest->Indexiv = loopback_Indexiv; + dest->Indexsv = loopback_Indexsv; + dest->Indexubv = loopback_Indexubv; + dest->Normal3b = loopback_Normal3b; + dest->Normal3d = loopback_Normal3d; + dest->Normal3i = loopback_Normal3i; + dest->Normal3s = loopback_Normal3s; + dest->Normal3bv = loopback_Normal3bv; + dest->Normal3dv = loopback_Normal3dv; + dest->Normal3iv = loopback_Normal3iv; + dest->Normal3sv = loopback_Normal3sv; + dest->TexCoord1d = loopback_TexCoord1d; + dest->TexCoord1i = loopback_TexCoord1i; + dest->TexCoord1s = loopback_TexCoord1s; + dest->TexCoord2d = loopback_TexCoord2d; + dest->TexCoord2s = loopback_TexCoord2s; + dest->TexCoord2i = loopback_TexCoord2i; + dest->TexCoord3d = loopback_TexCoord3d; + dest->TexCoord3i = loopback_TexCoord3i; + dest->TexCoord3s = loopback_TexCoord3s; + dest->TexCoord4d = loopback_TexCoord4d; + dest->TexCoord4i = loopback_TexCoord4i; + dest->TexCoord4s = loopback_TexCoord4s; + dest->TexCoord1dv = loopback_TexCoord1dv; + dest->TexCoord1iv = loopback_TexCoord1iv; + dest->TexCoord1sv = loopback_TexCoord1sv; + dest->TexCoord2dv = loopback_TexCoord2dv; + dest->TexCoord2iv = loopback_TexCoord2iv; + dest->TexCoord2sv = loopback_TexCoord2sv; + dest->TexCoord3dv = loopback_TexCoord3dv; + dest->TexCoord3iv = loopback_TexCoord3iv; + dest->TexCoord3sv = loopback_TexCoord3sv; + dest->TexCoord4dv = loopback_TexCoord4dv; + dest->TexCoord4iv = loopback_TexCoord4iv; + dest->TexCoord4sv = loopback_TexCoord4sv; + dest->Vertex2d = loopback_Vertex2d; + dest->Vertex2i = loopback_Vertex2i; + dest->Vertex2s = loopback_Vertex2s; + dest->Vertex3d = loopback_Vertex3d; + dest->Vertex3i = loopback_Vertex3i; + dest->Vertex3s = loopback_Vertex3s; + dest->Vertex4d = loopback_Vertex4d; + dest->Vertex4i = loopback_Vertex4i; + dest->Vertex4s = loopback_Vertex4s; + dest->Vertex2dv = loopback_Vertex2dv; + dest->Vertex2iv = loopback_Vertex2iv; + dest->Vertex2sv = loopback_Vertex2sv; + dest->Vertex3dv = loopback_Vertex3dv; + dest->Vertex3iv = loopback_Vertex3iv; + dest->Vertex3sv = loopback_Vertex3sv; + dest->Vertex4dv = loopback_Vertex4dv; + dest->Vertex4iv = loopback_Vertex4iv; + dest->Vertex4sv = loopback_Vertex4sv; + dest->MultiTexCoord1dARB = loopback_MultiTexCoord1dARB; + dest->MultiTexCoord1dvARB = loopback_MultiTexCoord1dvARB; + dest->MultiTexCoord1iARB = loopback_MultiTexCoord1iARB; + dest->MultiTexCoord1ivARB = loopback_MultiTexCoord1ivARB; + dest->MultiTexCoord1sARB = loopback_MultiTexCoord1sARB; + dest->MultiTexCoord1svARB = loopback_MultiTexCoord1svARB; + dest->MultiTexCoord2dARB = loopback_MultiTexCoord2dARB; + dest->MultiTexCoord2dvARB = loopback_MultiTexCoord2dvARB; + dest->MultiTexCoord2iARB = loopback_MultiTexCoord2iARB; + dest->MultiTexCoord2ivARB = loopback_MultiTexCoord2ivARB; + dest->MultiTexCoord2sARB = loopback_MultiTexCoord2sARB; + dest->MultiTexCoord2svARB = loopback_MultiTexCoord2svARB; + dest->MultiTexCoord3dARB = loopback_MultiTexCoord3dARB; + dest->MultiTexCoord3dvARB = loopback_MultiTexCoord3dvARB; + dest->MultiTexCoord3iARB = loopback_MultiTexCoord3iARB; + dest->MultiTexCoord3ivARB = loopback_MultiTexCoord3ivARB; + dest->MultiTexCoord3sARB = loopback_MultiTexCoord3sARB; + dest->MultiTexCoord3svARB = loopback_MultiTexCoord3svARB; + dest->MultiTexCoord4dARB = loopback_MultiTexCoord4dARB; + dest->MultiTexCoord4dvARB = loopback_MultiTexCoord4dvARB; + dest->MultiTexCoord4iARB = loopback_MultiTexCoord4iARB; + dest->MultiTexCoord4ivARB = loopback_MultiTexCoord4ivARB; + dest->MultiTexCoord4sARB = loopback_MultiTexCoord4sARB; + dest->MultiTexCoord4svARB = loopback_MultiTexCoord4svARB; + dest->EvalCoord2dv = loopback_EvalCoord2dv; + dest->EvalCoord2fv = loopback_EvalCoord2fv; + dest->EvalCoord2d = loopback_EvalCoord2d; + dest->EvalCoord1dv = loopback_EvalCoord1dv; + dest->EvalCoord1fv = loopback_EvalCoord1fv; + dest->EvalCoord1d = loopback_EvalCoord1d; + dest->Materialf = loopback_Materialf; + dest->Materiali = loopback_Materiali; + dest->Materialiv = loopback_Materialiv; + dest->Rectd = loopback_Rectd; + dest->Rectdv = loopback_Rectdv; + dest->Rectfv = loopback_Rectfv; + dest->Recti = loopback_Recti; + dest->Rectiv = loopback_Rectiv; + dest->Rects = loopback_Rects; + dest->Rectsv = loopback_Rectsv; + dest->FogCoorddEXT = loopback_FogCoorddEXT; + dest->FogCoorddvEXT = loopback_FogCoorddvEXT; +} Index: dll/opengl/opengl32/mesa/api_loopback.h =================================================================== --- dll/opengl/opengl32/mesa/api_loopback.h (revision 0) +++ dll/opengl/opengl32/mesa/api_loopback.h (working copy) @@ -0,0 +1,40 @@ +/* $Id: api_loopback.h,v 1.2 2001/03/12 00:48:37 gareth Exp $ */ + +/* + * Mesa 3-D graphics library + * Version: 3.5 + * + * Copyright (C) 1999-2001 Brian Paul 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 + * BRIAN PAUL 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. + */ + +#ifndef API_LOOPBACK_H +#define API_LOOPBACK_H + +#include "glheader.h" + +struct _glapi_table; + +extern void _mesa_loopback_prefer_float( struct _glapi_table *dest, + GLboolean prefer_float_colors ); + +extern void _mesa_loopback_init_api_table( struct _glapi_table *dest, + GLboolean prefer_float_colors ); + +#endif Index: dll/opengl/opengl32/mesa/api_noop.c =================================================================== --- dll/opengl/opengl32/mesa/api_noop.c (revision 0) +++ dll/opengl/opengl32/mesa/api_noop.c (working copy) @@ -0,0 +1,578 @@ +/* $Id: api_noop.c,v 1.8 2001/04/28 08:39:17 keithw Exp $ */ + +/* + * Mesa 3-D graphics library + * Version: 3.5 + * + * Copyright (C) 1999-2001 Brian Paul 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 + * BRIAN PAUL 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. + */ + + +#include "glheader.h" +#include "api_noop.h" +#include "api_validate.h" +#include "context.h" +#include "colormac.h" +#include "light.h" +#include "macros.h" +#include "mmath.h" +#include "mtypes.h" + + +/* In states where certain vertex components are required for t&l or + * rasterization, we still need to keep track of the current values. + * These functions provide this service by keeping uptodate the + * 'ctx->Current' struct for all data elements not included in the + * currently enabled hardware vertex. + * + */ +void _mesa_noop_EdgeFlag( GLboolean b ) +{ + GET_CURRENT_CONTEXT(ctx); + ctx->Current.EdgeFlag = b; +} + +void _mesa_noop_EdgeFlagv( const GLboolean *b ) +{ + GET_CURRENT_CONTEXT(ctx); + ctx->Current.EdgeFlag = *b; +} + +void _mesa_noop_FogCoordfEXT( GLfloat a ) +{ + GET_CURRENT_CONTEXT(ctx); + ctx->Current.FogCoord = a; +} + +void _mesa_noop_FogCoordfvEXT( const GLfloat *v ) +{ + GET_CURRENT_CONTEXT(ctx); + ctx->Current.FogCoord = *v; +} + +void _mesa_noop_Indexi( GLint i ) +{ + GET_CURRENT_CONTEXT(ctx); + ctx->Current.Index = i; +} + +void _mesa_noop_Indexiv( const GLint *v ) +{ + GET_CURRENT_CONTEXT(ctx); + ctx->Current.Index = *v; +} + +void _mesa_noop_Normal3f( GLfloat a, GLfloat b, GLfloat c ) +{ + GET_CURRENT_CONTEXT(ctx); + GLfloat *dest = ctx->Current.Normal; + COPY_FLOAT(dest[0], a); + COPY_FLOAT(dest[1], b); + COPY_FLOAT(dest[2], c); +} + +void _mesa_noop_Normal3fv( const GLfloat *v ) +{ + GET_CURRENT_CONTEXT(ctx); + GLfloat *dest = ctx->Current.Normal; + COPY_FLOAT(dest[0], v[0]); + COPY_FLOAT(dest[1], v[1]); + COPY_FLOAT(dest[2], v[2]); +} + +void _mesa_noop_Materialfv( GLenum face, GLenum pname, const GLfloat *params ) +{ + GET_CURRENT_CONTEXT(ctx); + struct gl_material mat[2]; + GLuint bitmask = _mesa_material_bitmask( ctx, face, pname, ~0, + "_mesa_noop_Materialfv" ); + if (bitmask == 0) + return; + + if (bitmask & FRONT_AMBIENT_BIT) { + COPY_4FV( mat[0].Ambient, params ); + } + if (bitmask & BACK_AMBIENT_BIT) { + COPY_4FV( mat[1].Ambient, params ); + } + if (bitmask & FRONT_DIFFUSE_BIT) { + COPY_4FV( mat[0].Diffuse, params ); + } + if (bitmask & BACK_DIFFUSE_BIT) { + COPY_4FV( mat[1].Diffuse, params ); + } + if (bitmask & FRONT_SPECULAR_BIT) { + COPY_4FV( mat[0].Specular, params ); + } + if (bitmask & BACK_SPECULAR_BIT) { + COPY_4FV( mat[1].Specular, params ); + } + if (bitmask & FRONT_EMISSION_BIT) { + COPY_4FV( mat[0].Emission, params ); + } + if (bitmask & BACK_EMISSION_BIT) { + COPY_4FV( mat[1].Emission, params ); + } + if (bitmask & FRONT_SHININESS_BIT) { + GLfloat shininess = CLAMP( params[0], 0.0F, 128.0F ); + mat[0].Shininess = shininess; + } + if (bitmask & BACK_SHININESS_BIT) { + GLfloat shininess = CLAMP( params[0], 0.0F, 128.0F ); + mat[1].Shininess = shininess; + } + if (bitmask & FRONT_INDEXES_BIT) { + mat[0].AmbientIndex = params[0]; + mat[0].DiffuseIndex = params[1]; + mat[0].SpecularIndex = params[2]; + } + if (bitmask & BACK_INDEXES_BIT) { + mat[1].AmbientIndex = params[0]; + mat[1].DiffuseIndex = params[1]; + mat[1].SpecularIndex = params[2]; + } + + _mesa_update_material( ctx, mat, bitmask ); +} + +void _mesa_noop_Color4ub( GLubyte a, GLubyte b, GLubyte c, GLubyte d ) +{ + GET_CURRENT_CONTEXT(ctx); + GLfloat *color = ctx->Current.Color; + color[0] = UBYTE_TO_FLOAT(a); + color[1] = UBYTE_TO_FLOAT(b); + color[2] = UBYTE_TO_FLOAT(c); + color[3] = UBYTE_TO_FLOAT(d); +} + +void _mesa_noop_Color4ubv( const GLubyte *v ) +{ + GET_CURRENT_CONTEXT(ctx); + GLfloat *color = ctx->Current.Color; + color[0] = UBYTE_TO_FLOAT(v[0]); + color[1] = UBYTE_TO_FLOAT(v[1]); + color[2] = UBYTE_TO_FLOAT(v[2]); + color[3] = UBYTE_TO_FLOAT(v[3]); +} + +void _mesa_noop_Color4f( GLfloat a, GLfloat b, GLfloat c, GLfloat d ) +{ + GET_CURRENT_CONTEXT(ctx); + GLfloat *color = ctx->Current.Color; + color[0] = a; + color[1] = b; + color[2] = c; + color[3] = d; +} + +void _mesa_noop_Color4fv( const GLfloat *v ) +{ + GET_CURRENT_CONTEXT(ctx); + GLfloat *color = ctx->Current.Color; + color[0] = v[0]; + color[1] = v[1]; + color[2] = v[2]; + color[3] = v[3]; +} + +void _mesa_noop_Color3ub( GLubyte a, GLubyte b, GLubyte c ) +{ + GET_CURRENT_CONTEXT(ctx); + GLfloat *color = ctx->Current.Color; + color[0] = UBYTE_TO_FLOAT(a); + color[1] = UBYTE_TO_FLOAT(b); + color[2] = UBYTE_TO_FLOAT(c); + color[3] = 1.0; +} + +void _mesa_noop_Color3ubv( const GLubyte *v ) +{ + GET_CURRENT_CONTEXT(ctx); + GLfloat *color = ctx->Current.Color; + color[0] = UBYTE_TO_FLOAT(v[0]); + color[1] = UBYTE_TO_FLOAT(v[1]); + color[2] = UBYTE_TO_FLOAT(v[2]); + color[3] = 1.0; +} + +void _mesa_noop_Color3f( GLfloat a, GLfloat b, GLfloat c ) +{ + GET_CURRENT_CONTEXT(ctx); + GLfloat *color = ctx->Current.Color; + color[0] = a; + color[1] = b; + color[2] = c; + color[3] = 1.0; +} + +void _mesa_noop_Color3fv( const GLfloat *v ) +{ + GET_CURRENT_CONTEXT(ctx); + GLfloat *color = ctx->Current.Color; + color[0] = v[0]; + color[1] = v[1]; + color[2] = v[2]; + color[3] = 1.0; +} + +void _mesa_noop_MultiTexCoord1fARB( GLenum target, GLfloat a ) +{ + GET_CURRENT_CONTEXT(ctx); + GLuint unit = target - GL_TEXTURE0_ARB; + + /* unit is unsigned -- cannot be less than zero. + */ + if (unit < MAX_TEXTURE_UNITS) + { + GLfloat *dest = ctx->Current.Texcoord[unit]; + COPY_FLOAT(dest[0], a); + dest[1] = 0; + dest[2] = 0; + dest[3] = 1; + } +} + +void _mesa_noop_MultiTexCoord1fvARB( GLenum target, GLfloat *v ) +{ + GET_CURRENT_CONTEXT(ctx); + GLuint unit = target - GL_TEXTURE0_ARB; + + /* unit is unsigned -- cannot be less than zero. + */ + if (unit < MAX_TEXTURE_UNITS) + { + GLfloat *dest = ctx->Current.Texcoord[unit]; + COPY_FLOAT(dest[0], v[0]); + dest[1] = 0; + dest[2] = 0; + dest[3] = 1; + } +} + +void _mesa_noop_MultiTexCoord2fARB( GLenum target, GLfloat a, GLfloat b ) +{ + GET_CURRENT_CONTEXT(ctx); + GLuint unit = target - GL_TEXTURE0_ARB; + + /* unit is unsigned -- cannot be less than zero. + */ + if (unit < MAX_TEXTURE_UNITS) + { + GLfloat *dest = ctx->Current.Texcoord[unit]; + COPY_FLOAT(dest[0], a); + COPY_FLOAT(dest[1], b); + dest[2] = 0; + dest[3] = 1; + } +} + +void _mesa_noop_MultiTexCoord2fvARB( GLenum target, GLfloat *v ) +{ + GET_CURRENT_CONTEXT(ctx); + GLuint unit = target - GL_TEXTURE0_ARB; + + /* unit is unsigned -- cannot be less than zero. + */ + if (unit < MAX_TEXTURE_UNITS) + { + GLfloat *dest = ctx->Current.Texcoord[unit]; + COPY_FLOAT(dest[0], v[0]); + COPY_FLOAT(dest[1], v[1]); + dest[2] = 0; + dest[3] = 1; + } +} + +void _mesa_noop_MultiTexCoord3fARB( GLenum target, GLfloat a, GLfloat b, GLfloat c) +{ + GET_CURRENT_CONTEXT(ctx); + GLuint unit = target - GL_TEXTURE0_ARB; + + /* unit is unsigned -- cannot be less than zero. + */ + if (unit < MAX_TEXTURE_UNITS) + { + GLfloat *dest = ctx->Current.Texcoord[unit]; + COPY_FLOAT(dest[0], a); + COPY_FLOAT(dest[1], b); + COPY_FLOAT(dest[2], c); + dest[3] = 1; + } +} + +void _mesa_noop_MultiTexCoord3fvARB( GLenum target, GLfloat *v ) +{ + GET_CURRENT_CONTEXT(ctx); + GLuint unit = target - GL_TEXTURE0_ARB; + + /* unit is unsigned -- cannot be less than zero. + */ + if (unit < MAX_TEXTURE_UNITS) + { + GLfloat *dest = ctx->Current.Texcoord[unit]; + COPY_FLOAT(dest[0], v[0]); + COPY_FLOAT(dest[1], v[1]); + COPY_FLOAT(dest[2], v[2]); + dest[3] = 1; + } +} + +void _mesa_noop_MultiTexCoord4fARB( GLenum target, GLfloat a, GLfloat b, + GLfloat c, GLfloat d ) +{ + GET_CURRENT_CONTEXT(ctx); + GLuint unit = target - GL_TEXTURE0_ARB; + + /* unit is unsigned -- cannot be less than zero. + */ + if (unit < MAX_TEXTURE_UNITS) + { + GLfloat *dest = ctx->Current.Texcoord[unit]; + COPY_FLOAT(dest[0], a); + COPY_FLOAT(dest[1], b); + COPY_FLOAT(dest[2], c); + dest[3] = d; + } +} + +void _mesa_noop_MultiTexCoord4fvARB( GLenum target, GLfloat *v ) +{ + GET_CURRENT_CONTEXT(ctx); + GLuint unit = target - GL_TEXTURE0_ARB; + + /* unit is unsigned -- cannot be less than zero. + */ + if (unit < MAX_TEXTURE_UNITS) + { + GLfloat *dest = ctx->Current.Texcoord[unit]; + COPY_FLOAT(dest[0], v[0]); + COPY_FLOAT(dest[1], v[1]); + COPY_FLOAT(dest[2], v[2]); + COPY_FLOAT(dest[3], v[3]); + } +} + +void _mesa_noop_SecondaryColor3ubEXT( GLubyte a, GLubyte b, GLubyte c ) +{ + GET_CURRENT_CONTEXT(ctx); + GLfloat *color = ctx->Current.SecondaryColor; + color[0] = UBYTE_TO_FLOAT(a); + color[1] = UBYTE_TO_FLOAT(b); + color[2] = UBYTE_TO_FLOAT(c); + color[3] = 1.0; +} + +void _mesa_noop_SecondaryColor3ubvEXT( const GLubyte *v ) +{ + GET_CURRENT_CONTEXT(ctx); + GLfloat *color = ctx->Current.SecondaryColor; + color[0] = UBYTE_TO_FLOAT(v[0]); + color[1] = UBYTE_TO_FLOAT(v[1]); + color[2] = UBYTE_TO_FLOAT(v[2]); + color[3] = 1.0; +} + +void _mesa_noop_SecondaryColor3fEXT( GLfloat a, GLfloat b, GLfloat c ) +{ + GET_CURRENT_CONTEXT(ctx); + GLfloat *color = ctx->Current.SecondaryColor; + color[0] = a; + color[1] = b; + color[2] = c; + color[3] = 1.0; +} + +void _mesa_noop_SecondaryColor3fvEXT( const GLfloat *v ) +{ + GET_CURRENT_CONTEXT(ctx); + GLfloat *color = ctx->Current.SecondaryColor; + color[0] = v[0]; + color[1] = v[1]; + color[2] = v[2]; + color[3] = 1.0; +} + +void _mesa_noop_TexCoord1f( GLfloat a ) +{ + GET_CURRENT_CONTEXT(ctx); + GLfloat *dest = ctx->Current.Texcoord[0]; + COPY_FLOAT(dest[0], a); + dest[1] = 0; + dest[2] = 0; + dest[3] = 1; +} + +void _mesa_noop_TexCoord1fv( GLfloat *v ) +{ + GET_CURRENT_CONTEXT(ctx); + GLfloat *dest = ctx->Current.Texcoord[0]; + COPY_FLOAT(dest[0], v[0]); + dest[1] = 0; + dest[2] = 0; + dest[3] = 1; +} + +void _mesa_noop_TexCoord2f( GLfloat a, GLfloat b ) +{ + GET_CURRENT_CONTEXT(ctx); + GLfloat *dest = ctx->Current.Texcoord[0]; + COPY_FLOAT(dest[0], a); + COPY_FLOAT(dest[1], b); + dest[2] = 0; + dest[3] = 1; +} + +void _mesa_noop_TexCoord2fv( GLfloat *v ) +{ + GET_CURRENT_CONTEXT(ctx); + GLfloat *dest = ctx->Current.Texcoord[0]; + COPY_FLOAT(dest[0], v[0]); + COPY_FLOAT(dest[1], v[1]); + dest[2] = 0; + dest[3] = 1; +} + +void _mesa_noop_TexCoord3f( GLfloat a, GLfloat b, GLfloat c ) +{ + GET_CURRENT_CONTEXT(ctx); + GLfloat *dest = ctx->Current.Texcoord[0]; + COPY_FLOAT(dest[0], a); + COPY_FLOAT(dest[1], b); + COPY_FLOAT(dest[2], c); + dest[3] = 1; +} + +void _mesa_noop_TexCoord3fv( GLfloat *v ) +{ + GET_CURRENT_CONTEXT(ctx); + GLfloat *dest = ctx->Current.Texcoord[0]; + COPY_FLOAT(dest[0], v[0]); + COPY_FLOAT(dest[1], v[1]); + COPY_FLOAT(dest[2], v[2]); + dest[3] = 1; +} + +void _mesa_noop_TexCoord4f( GLfloat a, GLfloat b, GLfloat c, GLfloat d ) +{ + GET_CURRENT_CONTEXT(ctx); + GLfloat *dest = ctx->Current.Texcoord[0]; + COPY_FLOAT(dest[0], a); + COPY_FLOAT(dest[1], b); + COPY_FLOAT(dest[2], c); + COPY_FLOAT(dest[3], d); +} + +void _mesa_noop_TexCoord4fv( GLfloat *v ) +{ + GET_CURRENT_CONTEXT(ctx); + GLfloat *dest = ctx->Current.Texcoord[0]; + COPY_FLOAT(dest[0], v[0]); + COPY_FLOAT(dest[1], v[1]); + COPY_FLOAT(dest[2], v[2]); + COPY_FLOAT(dest[3], v[3]); +} + +/* Execute a glRectf() function. This is not suitable for GL_COMPILE + * modes (as the test for outside begin/end is not compiled), + * but may be useful for drivers in circumstances which exclude + * display list interactions. + * + * (None of the functions in this file are suitable for GL_COMPILE + * modes). + */ +void _mesa_noop_Rectf( GLfloat x1, GLfloat y1, GLfloat x2, GLfloat y2 ) +{ + { + GET_CURRENT_CONTEXT(ctx); + ASSERT_OUTSIDE_BEGIN_END(ctx); + } + + glBegin( GL_QUADS ); + glVertex2f( x1, y1 ); + glVertex2f( x2, y1 ); + glVertex2f( x2, y2 ); + glVertex2f( x1, y2 ); + glEnd(); +} + + +/* Some very basic support for arrays. Drivers without explicit array + * support can hook these in, but still need to supply an array-elt + * implementation. + */ +void _mesa_noop_DrawArrays(GLenum mode, GLint start, GLsizei count) +{ + GET_CURRENT_CONTEXT(ctx); + GLint i; + + if (!_mesa_validate_DrawArrays( ctx, mode, start, count )) + return; + + glBegin(mode); + for (i = start ; i <= count ; i++) + glArrayElement( i ); + glEnd(); +} + + +void _mesa_noop_DrawElements(GLenum mode, GLsizei count, GLenum type, + const GLvoid *indices) +{ + GET_CURRENT_CONTEXT(ctx); + GLint i; + + if (!_mesa_validate_DrawElements( ctx, mode, count, type, indices )) + return; + + glBegin(mode); + + switch (type) { + case GL_UNSIGNED_BYTE: + for (i = 0 ; i < count ; i++) + glArrayElement( ((GLubyte *)indices)[i] ); + break; + case GL_UNSIGNED_SHORT: + for (i = 0 ; i < count ; i++) + glArrayElement( ((GLushort *)indices)[i] ); + break; + case GL_UNSIGNED_INT: + for (i = 0 ; i < count ; i++) + glArrayElement( ((GLuint *)indices)[i] ); + break; + default: + _mesa_error( ctx, GL_INVALID_ENUM, "glDrawElements(type)" ); + break; + } + + glEnd(); +} + +void _mesa_noop_DrawRangeElements(GLenum mode, + GLuint start, GLuint end, + GLsizei count, GLenum type, + const GLvoid *indices) +{ + GET_CURRENT_CONTEXT(ctx); + + if (_mesa_validate_DrawRangeElements( ctx, mode, + start, end, + count, type, indices )) + glDrawElements( mode, count, type, indices ); +} Index: dll/opengl/opengl32/mesa/api_noop.h =================================================================== --- dll/opengl/opengl32/mesa/api_noop.h (revision 0) +++ dll/opengl/opengl32/mesa/api_noop.h (working copy) @@ -0,0 +1,137 @@ +/* $Id: api_noop.h,v 1.3 2001/03/12 00:48:37 gareth Exp $ */ + +/* + * Mesa 3-D graphics library + * Version: 3.5 + * + * Copyright (C) 1999-2001 Brian Paul 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 + * BRIAN PAUL 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. + */ + +#ifndef _API_NOOP_H +#define _API_NOOP_H + + +#include "glheader.h" +#include "mtypes.h" +#include "context.h" + +/* In states where certain vertex components are required for t&l or + * rasterization, we still need to keep track of the current values. + * These functions provide this service by keeping uptodate the + * 'ctx->Current' struct for all data elements not included in the + * currently enabled hardware vertex. + * + */ +extern void _mesa_noop_EdgeFlag( GLboolean b ); + +extern void _mesa_noop_EdgeFlagv( const GLboolean *b ); + +extern void _mesa_noop_FogCoordfEXT( GLfloat a ); + +extern void _mesa_noop_FogCoordfvEXT( const GLfloat *v ); + +extern void _mesa_noop_Indexi( GLint i ); + +extern void _mesa_noop_Indexiv( const GLint *v ); + +extern void _mesa_noop_Normal3f( GLfloat a, GLfloat b, GLfloat c ); + +extern void _mesa_noop_Normal3fv( const GLfloat *v ); + +extern void _mesa_noop_Materialfv( GLenum face, GLenum pname, const GLfloat *param ); + +extern void _mesa_noop_Color4ub( GLubyte a, GLubyte b, GLubyte c, GLubyte d ); + +extern void _mesa_noop_Color4ubv( const GLubyte *v ); + +extern void _mesa_noop_Color4f( GLfloat a, GLfloat b, GLfloat c, GLfloat d ); + +extern void _mesa_noop_Color4fv( const GLfloat *v ); + +extern void _mesa_noop_Color3ub( GLubyte a, GLubyte b, GLubyte c ); + +extern void _mesa_noop_Color3ubv( const GLubyte *v ); + +extern void _mesa_noop_Color3f( GLfloat a, GLfloat b, GLfloat c ); + +extern void _mesa_noop_Color3fv( const GLfloat *v ); + +extern void _mesa_noop_MultiTexCoord1fARB( GLenum target, GLfloat a ); + +extern void _mesa_noop_MultiTexCoord1fvARB( GLenum target, GLfloat *v ); + +extern void _mesa_noop_MultiTexCoord2fARB( GLenum target, GLfloat a, + GLfloat b ); + +extern void _mesa_noop_MultiTexCoord2fvARB( GLenum target, GLfloat *v ); + +extern void _mesa_noop_MultiTexCoord3fARB( GLenum target, GLfloat a, + GLfloat b, GLfloat c); + +extern void _mesa_noop_MultiTexCoord3fvARB( GLenum target, GLfloat *v ); + +extern void _mesa_noop_MultiTexCoord4fARB( GLenum target, GLfloat a, + GLfloat b, GLfloat c, GLfloat d ); + +extern void _mesa_noop_MultiTexCoord4fvARB( GLenum target, GLfloat *v ); + +extern void _mesa_noop_SecondaryColor3ubEXT( GLubyte a, GLubyte b, GLubyte c ); + +extern void _mesa_noop_SecondaryColor3ubvEXT( const GLubyte *v ); + +extern void _mesa_noop_SecondaryColor3fEXT( GLfloat a, GLfloat b, GLfloat c ); + +extern void _mesa_noop_SecondaryColor3fvEXT( const GLfloat *v ); + +extern void _mesa_noop_TexCoord1f( GLfloat a ); + +extern void _mesa_noop_TexCoord1fv( GLfloat *v ); + +extern void _mesa_noop_TexCoord2f( GLfloat a, GLfloat b ); + +extern void _mesa_noop_TexCoord2fv( GLfloat *v ); + +extern void _mesa_noop_TexCoord3f( GLfloat a, GLfloat b, GLfloat c ); + +extern void _mesa_noop_TexCoord3fv( GLfloat *v ); + +extern void _mesa_noop_TexCoord4f( GLfloat a, GLfloat b, GLfloat c, GLfloat d ); + +extern void _mesa_noop_TexCoord4fv( GLfloat *v ); + + +/* Not strictly a noop -- translate Rectf down to Begin/End and + * vertices. Closer to the loopback operations, but doesn't meet the + * criteria for inclusion there (cannot be used in the Save table). + */ +extern void _mesa_noop_Rectf( GLfloat x1, GLfloat y1, GLfloat x2, GLfloat y2 ); + + +extern void _mesa_noop_DrawArrays(GLenum mode, GLint start, GLsizei count); +extern void _mesa_noop_DrawElements(GLenum mode, GLsizei count, GLenum type, + const GLvoid *indices); +extern void _mesa_noop_DrawRangeElements(GLenum mode, + GLuint start, GLuint end, + GLsizei count, GLenum type, + const GLvoid *indices); + + + +#endif Index: dll/opengl/opengl32/mesa/api_validate.c =================================================================== --- dll/opengl/opengl32/mesa/api_validate.c (revision 0) +++ dll/opengl/opengl32/mesa/api_validate.c (working copy) @@ -0,0 +1,137 @@ +/* $Id: api_validate.c,v 1.5 2001/03/12 00:48:37 gareth Exp $ */ + +/* + * Mesa 3-D graphics library + * Version: 3.5 + * + * Copyright (C) 1999-2001 Brian Paul 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 + * BRIAN PAUL 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. + */ + +#include "glheader.h" +#include "api_validate.h" +#include "context.h" +#include "mtypes.h" +#include "state.h" + + +GLboolean +_mesa_validate_DrawElements(GLcontext *ctx, + GLenum mode, GLsizei count, GLenum type, + const GLvoid *indices) +{ + ASSERT_OUTSIDE_BEGIN_END_WITH_RETVAL(ctx, GL_FALSE); + + if (count <= 0) { + if (count < 0) + _mesa_error(ctx, GL_INVALID_VALUE, "glDrawElements(count)" ); + return GL_FALSE; + } + + if (mode < 0 || + mode > GL_POLYGON) { + _mesa_error(ctx, GL_INVALID_ENUM, "glDrawArrays(mode)" ); + return GL_FALSE; + } + + if (type != GL_UNSIGNED_INT && + type != GL_UNSIGNED_BYTE && + type != GL_UNSIGNED_SHORT) + { + _mesa_error(ctx, GL_INVALID_ENUM, "glDrawElements(type)" ); + return GL_FALSE; + } + + if (ctx->NewState) + _mesa_update_state( ctx ); + + if (!ctx->Array.Vertex.Enabled) + return GL_FALSE; + + return GL_TRUE; +} + + +GLboolean +_mesa_validate_DrawRangeElements(GLcontext *ctx, GLenum mode, + GLuint start, GLuint end, + GLsizei count, GLenum type, + const GLvoid *indices) +{ + ASSERT_OUTSIDE_BEGIN_END_WITH_RETVAL(ctx, GL_FALSE); + + if (count <= 0) { + if (count < 0) + _mesa_error(ctx, GL_INVALID_VALUE, "glDrawElements(count)" ); + return GL_FALSE; + } + + if (mode < 0 || mode > GL_POLYGON) { + _mesa_error(ctx, GL_INVALID_ENUM, "glDrawArrays(mode)" ); + return GL_FALSE; + } + + if (end < start) { + _mesa_error(ctx, GL_INVALID_VALUE, "glDrawRangeElements(endNewState) + _mesa_update_state( ctx ); + + if (!ctx->Array.Vertex.Enabled) + return GL_FALSE; + + return GL_TRUE; +} + + + +GLboolean +_mesa_validate_DrawArrays(GLcontext *ctx, + GLenum mode, GLint start, GLsizei count) +{ + ASSERT_OUTSIDE_BEGIN_END_WITH_RETVAL(ctx, GL_FALSE); + + if (count<0) { + _mesa_error(ctx, GL_INVALID_VALUE, "glDrawArrays(count)" ); + return GL_FALSE; + } + + if (mode < 0 || mode > GL_POLYGON) { + _mesa_error(ctx, GL_INVALID_ENUM, "glDrawArrays(mode)" ); + return GL_FALSE; + } + + if (ctx->NewState) + _mesa_update_state( ctx ); + + if (!ctx->Array.Vertex.Enabled) + return GL_FALSE; + + return GL_TRUE; +} Index: dll/opengl/opengl32/mesa/api_validate.h =================================================================== --- dll/opengl/opengl32/mesa/api_validate.h (revision 0) +++ dll/opengl/opengl32/mesa/api_validate.h (working copy) @@ -0,0 +1,50 @@ +/* $Id: api_validate.h,v 1.2 2001/03/12 00:48:37 gareth Exp $ */ + +/* + * Mesa 3-D graphics library + * Version: 3.5 + * + * Copyright (C) 1999-2001 Brian Paul 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 + * BRIAN PAUL 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. + */ + + +#ifndef API_VALIDATE_H +#define API_VALIDATE_H + + +#include "mtypes.h" + +extern GLboolean +_mesa_validate_DrawArrays(GLcontext *ctx, + GLenum mode, GLint start, GLsizei count); + +extern GLboolean +_mesa_validate_DrawElements(GLcontext *ctx, + GLenum mode, GLsizei count, GLenum type, + const GLvoid *indices); + +extern GLboolean +_mesa_validate_DrawRangeElements(GLcontext *ctx, GLenum mode, + GLuint start, GLuint end, + GLsizei count, GLenum type, + const GLvoid *indices); + + +#endif Index: dll/opengl/opengl32/mesa/array_cache/ac_context.c =================================================================== --- dll/opengl/opengl32/mesa/array_cache/ac_context.c (revision 0) +++ dll/opengl/opengl32/mesa/array_cache/ac_context.c (working copy) @@ -0,0 +1,272 @@ +/* $Id: ac_context.c,v 1.4 2001/04/28 08:39:18 keithw Exp $ */ + +/* + * Mesa 3-D graphics library + * Version: 3.5 + * + * Copyright (C) 1999-2001 Brian Paul 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 + * BRIAN PAUL 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. + * + * Authors: + * Keith Whitwell + */ + +#include "glheader.h" +#include "macros.h" +#include "mem.h" +#include "mmath.h" +#include "mtypes.h" + +#include "array_cache/ac_context.h" + +static void _ac_fallbacks_init( GLcontext *ctx ) +{ + ACcontext *ac = AC_CONTEXT(ctx); + struct gl_client_array *cl; + GLuint i; + + cl = &ac->Fallback.Normal; + cl->Size = 3; + cl->Type = GL_FLOAT; + cl->Stride = 0; + cl->StrideB = 0; + cl->Ptr = (void *) ctx->Current.Normal; + cl->Enabled = 1; + cl->Flags = CA_CLIENT_DATA; /* hack */ + + cl = &ac->Fallback.Color; + cl->Size = 4; + cl->Type = GL_FLOAT; + cl->Stride = 0; + cl->StrideB = 0; + cl->Ptr = (void *) ctx->Current.Color; + cl->Enabled = 1; + cl->Flags = CA_CLIENT_DATA; /* hack */ + + cl = &ac->Fallback.SecondaryColor; + cl->Size = 3; + cl->Type = GL_FLOAT; + cl->Stride = 0; + cl->StrideB = 0; + cl->Ptr = (void *) ctx->Current.SecondaryColor; + cl->Enabled = 1; + cl->Flags = CA_CLIENT_DATA; /* hack */ + + cl = &ac->Fallback.FogCoord; + cl->Size = 1; + cl->Type = GL_FLOAT; + cl->Stride = 0; + cl->StrideB = 0; + cl->Ptr = (void *) &ctx->Current.FogCoord; + cl->Enabled = 1; + cl->Flags = CA_CLIENT_DATA; /* hack */ + + cl = &ac->Fallback.Index; + cl->Size = 1; + cl->Type = GL_UNSIGNED_INT; + cl->Stride = 0; + cl->StrideB = 0; + cl->Ptr = (void *) &ctx->Current.Index; + cl->Enabled = 1; + cl->Flags = CA_CLIENT_DATA; /* hack */ + + for (i = 0 ; i < MAX_TEXTURE_UNITS ; i++) { + cl = &ac->Fallback.TexCoord[i]; + cl->Size = 4; + cl->Type = GL_FLOAT; + cl->Stride = 0; + cl->StrideB = 0; + cl->Ptr = (void *) ctx->Current.Texcoord[i]; + cl->Enabled = 1; + cl->Flags = CA_CLIENT_DATA; /* hack */ + } + + cl = &ac->Fallback.EdgeFlag; + cl->Size = 1; + cl->Type = GL_UNSIGNED_BYTE; + cl->Stride = 0; + cl->StrideB = 0; + cl->Ptr = (void *) &ctx->Current.EdgeFlag; + cl->Enabled = 1; + cl->Flags = CA_CLIENT_DATA; /* hack */ +} + + +static void _ac_cache_init( GLcontext *ctx ) +{ + ACcontext *ac = AC_CONTEXT(ctx); + struct gl_client_array *cl; + GLuint size = ctx->Const.MaxArrayLockSize + MAX_CLIPPED_VERTICES; + GLuint i; + + cl = &ac->Cache.Vertex; + cl->Size = 4; + cl->Type = GL_FLOAT; + cl->Stride = 0; + cl->StrideB = 4 * sizeof(GLfloat); + cl->Ptr = MALLOC( cl->StrideB * size ); + cl->Enabled = 1; + cl->Flags = 0; + + cl = &ac->Cache.Normal; + cl->Size = 3; + cl->Type = GL_FLOAT; + cl->Stride = 0; + cl->StrideB = 3 * sizeof(GLfloat); + cl->Ptr = MALLOC( cl->StrideB * size ); + cl->Enabled = 1; + cl->Flags = 0; + + cl = &ac->Cache.Color; + cl->Size = 4; + cl->Type = GL_FLOAT; + cl->Stride = 0; + cl->StrideB = 4 * sizeof(GLfloat); + cl->Ptr = MALLOC( cl->StrideB * size ); + cl->Enabled = 1; + cl->Flags = 0; + + cl = &ac->Cache.SecondaryColor; + cl->Size = 3; + cl->Type = GL_FLOAT; + cl->Stride = 0; + cl->StrideB = 4 * sizeof(GLfloat); + cl->Ptr = MALLOC( cl->StrideB * size ); + cl->Enabled = 1; + cl->Flags = 0; + + cl = &ac->Cache.FogCoord; + cl->Size = 1; + cl->Type = GL_FLOAT; + cl->Stride = 0; + cl->StrideB = sizeof(GLfloat); + cl->Ptr = MALLOC( cl->StrideB * size ); + cl->Enabled = 1; + cl->Flags = 0; + + cl = &ac->Cache.Index; + cl->Size = 1; + cl->Type = GL_UNSIGNED_INT; + cl->Stride = 0; + cl->StrideB = sizeof(GLuint); + cl->Ptr = MALLOC( cl->StrideB * size ); + cl->Enabled = 1; + cl->Flags = 0; + + for (i = 0 ; i < MAX_TEXTURE_UNITS ; i++) { + cl = &ac->Cache.TexCoord[i]; + cl->Size = 4; + cl->Type = GL_FLOAT; + cl->Stride = 0; + cl->StrideB = 4 * sizeof(GLfloat); + cl->Ptr = MALLOC( cl->StrideB * size ); + cl->Enabled = 1; + cl->Flags = 0; + } + + cl = &ac->Cache.EdgeFlag; + cl->Size = 1; + cl->Type = GL_UNSIGNED_BYTE; + cl->Stride = 0; + cl->StrideB = sizeof(GLubyte); + cl->Ptr = MALLOC( cl->StrideB * size ); + cl->Enabled = 1; + cl->Flags = 0; +} + + +/* This storage used to hold translated client data if type or stride + * need to be fixed. + */ +static void _ac_elts_init( GLcontext *ctx ) +{ + ACcontext *ac = AC_CONTEXT(ctx); + GLuint size = 1000; + + ac->Elts = (GLuint *)MALLOC( sizeof(GLuint) * size ); + ac->elt_size = size; +} + +static void _ac_raw_init( GLcontext *ctx ) +{ + ACcontext *ac = AC_CONTEXT(ctx); + GLuint i; + + ac->Raw.Color = ac->Fallback.Color; + ac->Raw.EdgeFlag = ac->Fallback.EdgeFlag; + ac->Raw.FogCoord = ac->Fallback.FogCoord; + ac->Raw.Index = ac->Fallback.Index; + ac->Raw.Normal = ac->Fallback.Normal; + ac->Raw.SecondaryColor = ac->Fallback.SecondaryColor; + ac->Raw.Vertex = ctx->Array.Vertex; + + ac->IsCached.Color = GL_FALSE; + ac->IsCached.EdgeFlag = GL_FALSE; + ac->IsCached.FogCoord = GL_FALSE; + ac->IsCached.Index = GL_FALSE; + ac->IsCached.Normal = GL_FALSE; + ac->IsCached.SecondaryColor = GL_FALSE; + ac->IsCached.Vertex = GL_FALSE; + + for (i = 0 ; i < MAX_TEXTURE_UNITS ; i++) { + ac->Raw.TexCoord[i] = ac->Fallback.TexCoord[i]; + ac->IsCached.TexCoord[i] = GL_FALSE; + } + +} + +GLboolean _ac_CreateContext( GLcontext *ctx ) +{ + ctx->acache_context = CALLOC(sizeof(ACcontext)); + if (ctx->acache_context) { + _ac_cache_init( ctx ); + _ac_fallbacks_init( ctx ); + _ac_raw_init( ctx ); + _ac_elts_init( ctx ); + return GL_TRUE; + } + return GL_FALSE; +} + +void _ac_DestroyContext( GLcontext *ctx ) +{ + ACcontext *ac = AC_CONTEXT(ctx); + GLint i; + + if (ac->Cache.Vertex.Ptr) FREE( ac->Cache.Vertex.Ptr ); + if (ac->Cache.Normal.Ptr) FREE( ac->Cache.Normal.Ptr ); + if (ac->Cache.Color.Ptr) FREE( ac->Cache.Color.Ptr ); + if (ac->Cache.SecondaryColor.Ptr) FREE( ac->Cache.SecondaryColor.Ptr ); + if (ac->Cache.EdgeFlag.Ptr) FREE( ac->Cache.EdgeFlag.Ptr ); + if (ac->Cache.Index.Ptr) FREE( ac->Cache.Index.Ptr ); + if (ac->Cache.FogCoord.Ptr) FREE( ac->Cache.FogCoord.Ptr ); + + for (i = 0; i < MAX_TEXTURE_UNITS; i++) { + if (ac->Cache.TexCoord[i].Ptr) + FREE( ac->Cache.TexCoord[i].Ptr ); + } + + if (ac->Elts) FREE( ac->Elts ); +} + +void _ac_InvalidateState( GLcontext *ctx, GLuint new_state ) +{ + AC_CONTEXT(ctx)->NewState |= new_state; + AC_CONTEXT(ctx)->NewArrayState |= ctx->Array.NewState; +} Index: dll/opengl/opengl32/mesa/array_cache/ac_context.h =================================================================== --- dll/opengl/opengl32/mesa/array_cache/ac_context.h (revision 0) +++ dll/opengl/opengl32/mesa/array_cache/ac_context.h (working copy) @@ -0,0 +1,97 @@ +/* $Id: ac_context.h,v 1.3 2001/03/12 00:48:41 gareth Exp $ */ + +/* + * Mesa 3-D graphics library + * Version: 3.5 + * + * Copyright (C) 1999-2001 Brian Paul 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 + * BRIAN PAUL 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. + * + * Authors: + * Keith Whitwell + */ + +#ifndef _AC_CONTEXT_H +#define _AC_CONTEXT_H + +#include "glheader.h" +#include "mtypes.h" + +#include "array_cache/acache.h" + +/* These are used to make the ctx->Current values look like + * arrays (with zero StrideB). + */ +struct ac_arrays { + struct gl_client_array Vertex; + struct gl_client_array Normal; + struct gl_client_array Color; + struct gl_client_array SecondaryColor; + struct gl_client_array FogCoord; + struct gl_client_array Index; + struct gl_client_array TexCoord[MAX_TEXTURE_UNITS]; + struct gl_client_array EdgeFlag; +}; + +struct ac_array_pointers { + struct gl_client_array *Vertex; + struct gl_client_array *Normal; + struct gl_client_array *Color; + struct gl_client_array *SecondaryColor; + struct gl_client_array *FogCoord; + struct gl_client_array *Index; + struct gl_client_array *TexCoord[MAX_TEXTURE_UNITS]; + struct gl_client_array *EdgeFlag; +}; + +struct ac_array_flags { + GLboolean Vertex; + GLboolean Normal; + GLboolean Color; + GLboolean SecondaryColor; + GLboolean FogCoord; + GLboolean Index; + GLboolean TexCoord[MAX_TEXTURE_UNITS]; + GLboolean EdgeFlag; +}; + + +typedef struct { + GLuint NewState; /* not needed? */ + GLuint NewArrayState; + + /* Facility for importing and caching array data: + */ + struct ac_arrays Fallback; + struct ac_arrays Cache; + struct ac_arrays Raw; + struct ac_array_flags IsCached; + GLuint start; + GLuint count; + + /* Facility for importing element lists: + */ + GLuint *Elts; + GLuint elt_size; + +} ACcontext; + +#define AC_CONTEXT(ctx) ((ACcontext *)ctx->acache_context) + +#endif Index: dll/opengl/opengl32/mesa/array_cache/ac_import.c =================================================================== --- dll/opengl/opengl32/mesa/array_cache/ac_import.c (revision 0) +++ dll/opengl/opengl32/mesa/array_cache/ac_import.c (working copy) @@ -0,0 +1,784 @@ +/* $Id: ac_import.c,v 1.14 2001/04/28 08:39:18 keithw Exp $ */ + +/* + * Mesa 3-D graphics library + * Version: 3.5 + * + * Copyright (C) 1999-2001 Brian Paul 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 + * BRIAN PAUL 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. + * + * Authors: + * Keith Whitwell + */ + +#include "glheader.h" +#include "macros.h" +#include "mem.h" +#include "mmath.h" +#include "mtypes.h" + +#include "math/m_translate.h" +#include "array_cache/ac_context.h" +#include "math/m_translate.h" + +#define STRIDE_ARRAY( array, offset ) \ +do { \ + char *tmp = (char *) (array).Ptr; \ + tmp += (offset) * (array).StrideB; \ + (array).Ptr = tmp; \ +} while (0) + +/* Set the array pointer back to its source when the cached data is + * invalidated: + */ + +static void reset_texcoord( GLcontext *ctx, GLuint unit ) +{ + ACcontext *ac = AC_CONTEXT(ctx); + + if (ctx->Array._Enabled & _NEW_ARRAY_TEXCOORD(unit)) { + ac->Raw.TexCoord[unit] = ctx->Array.TexCoord[unit]; + STRIDE_ARRAY(ac->Raw.TexCoord[unit], ac->start); + } + else { + ac->Raw.TexCoord[unit] = ac->Fallback.TexCoord[unit]; + + if (ctx->Current.Texcoord[unit][3] != 1.0) + ac->Raw.TexCoord[unit].Size = 4; + else if (ctx->Current.Texcoord[unit][2] != 0.0) + ac->Raw.TexCoord[unit].Size = 3; + else + ac->Raw.TexCoord[unit].Size = 2; + } + + ac->IsCached.TexCoord[unit] = GL_FALSE; + ac->NewArrayState &= ~_NEW_ARRAY_TEXCOORD(unit); +} + +static void reset_vertex( GLcontext *ctx ) +{ + ACcontext *ac = AC_CONTEXT(ctx); + ASSERT(ctx->Array.Vertex.Enabled); + ac->Raw.Vertex = ctx->Array.Vertex; + STRIDE_ARRAY(ac->Raw.Vertex, ac->start); + ac->IsCached.Vertex = GL_FALSE; + ac->NewArrayState &= ~_NEW_ARRAY_VERTEX; +} + + +static void reset_normal( GLcontext *ctx ) +{ + ACcontext *ac = AC_CONTEXT(ctx); + + if (ctx->Array._Enabled & _NEW_ARRAY_NORMAL) { + ac->Raw.Normal = ctx->Array.Normal; + STRIDE_ARRAY(ac->Raw.Normal, ac->start); + } + else { + ac->Raw.Normal = ac->Fallback.Normal; + } + + ac->IsCached.Normal = GL_FALSE; + ac->NewArrayState &= ~_NEW_ARRAY_NORMAL; +} + + +static void reset_color( GLcontext *ctx ) +{ + ACcontext *ac = AC_CONTEXT(ctx); + + + if (ctx->Array._Enabled & _NEW_ARRAY_COLOR) { + ac->Raw.Color = ctx->Array.Color; + STRIDE_ARRAY(ac->Raw.Color, ac->start); + } + else + ac->Raw.Color = ac->Fallback.Color; + + ac->IsCached.Color = GL_FALSE; + ac->NewArrayState &= ~_NEW_ARRAY_COLOR; +} + + +static void reset_secondarycolor( GLcontext *ctx ) +{ + ACcontext *ac = AC_CONTEXT(ctx); + + if (ctx->Array._Enabled & _NEW_ARRAY_SECONDARYCOLOR) { + ac->Raw.SecondaryColor = ctx->Array.SecondaryColor; + STRIDE_ARRAY(ac->Raw.SecondaryColor, ac->start); + } + else + ac->Raw.SecondaryColor = ac->Fallback.SecondaryColor; + + ac->IsCached.SecondaryColor = GL_FALSE; + ac->NewArrayState &= ~_NEW_ARRAY_SECONDARYCOLOR; +} + + +static void reset_index( GLcontext *ctx ) +{ + ACcontext *ac = AC_CONTEXT(ctx); + + if (ctx->Array._Enabled & _NEW_ARRAY_INDEX) { + ac->Raw.Index = ctx->Array.Index; + STRIDE_ARRAY(ac->Raw.Index, ac->start); + } + else + ac->Raw.Index = ac->Fallback.Index; + + ac->IsCached.Index = GL_FALSE; + ac->NewArrayState &= ~_NEW_ARRAY_INDEX; +} + +static void reset_fogcoord( GLcontext *ctx ) +{ + ACcontext *ac = AC_CONTEXT(ctx); + + if (ctx->Array._Enabled & _NEW_ARRAY_FOGCOORD) { + ac->Raw.FogCoord = ctx->Array.FogCoord; + STRIDE_ARRAY(ac->Raw.FogCoord, ac->start); + } + else + ac->Raw.FogCoord = ac->Fallback.FogCoord; + + ac->IsCached.FogCoord = GL_FALSE; + ac->NewArrayState &= ~_NEW_ARRAY_FOGCOORD; +} + +static void reset_edgeflag( GLcontext *ctx ) +{ + ACcontext *ac = AC_CONTEXT(ctx); + + if (ctx->Array._Enabled & _NEW_ARRAY_EDGEFLAG) { + ac->Raw.EdgeFlag = ctx->Array.EdgeFlag; + STRIDE_ARRAY(ac->Raw.EdgeFlag, ac->start); + } + else + ac->Raw.EdgeFlag = ac->Fallback.EdgeFlag; + + ac->IsCached.EdgeFlag = GL_FALSE; + ac->NewArrayState &= ~_NEW_ARRAY_EDGEFLAG; +} + + + +static void import( GLcontext *ctx, + GLenum type, + struct gl_client_array *to, + struct gl_client_array *from ) +{ + ACcontext *ac = AC_CONTEXT(ctx); + + if (type == 0) + type = from->Type; + + switch (type) { + case GL_FLOAT: + _math_trans_4f( (GLfloat (*)[4]) to->Ptr, + from->Ptr, + from->StrideB, + from->Type, + from->Size, + 0, + ac->count - ac->start); + + to->StrideB = 4 * sizeof(GLfloat); + to->Type = GL_FLOAT; + break; + + case GL_UNSIGNED_BYTE: + _math_trans_4ub( (GLubyte (*)[4]) to->Ptr, + from->Ptr, + from->StrideB, + from->Type, + from->Size, + 0, + ac->count - ac->start); + + to->StrideB = 4 * sizeof(GLubyte); + to->Type = GL_UNSIGNED_BYTE; + break; + + case GL_UNSIGNED_SHORT: + _math_trans_4us( (GLushort (*)[4]) to->Ptr, + from->Ptr, + from->StrideB, + from->Type, + from->Size, + 0, + ac->count - ac->start); + + to->StrideB = 4 * sizeof(GLushort); + to->Type = GL_UNSIGNED_SHORT; + break; + + default: + ASSERT(0); + break; + } +} + + + +/* Functions to import array ranges with specified types and strides. + */ +static void import_texcoord( GLcontext *ctx, GLuint unit, + GLenum type, GLuint stride ) +{ + ACcontext *ac = AC_CONTEXT(ctx); + struct gl_client_array *from = &ac->Raw.TexCoord[unit]; + struct gl_client_array *to = &ac->Cache.TexCoord[unit]; + + /* Limited choices at this stage: + */ + ASSERT(type == GL_FLOAT); + ASSERT(stride == 4*sizeof(GLfloat) || stride == 0); + ASSERT(ac->count - ac->start < ctx->Const.MaxArrayLockSize); + + _math_trans_4f( (GLfloat (*)[4]) to->Ptr, + from->Ptr, + from->StrideB, + from->Type, + from->Size, + 0, + ac->count - ac->start); + + to->Size = from->Size; + to->StrideB = 4 * sizeof(GLfloat); + to->Type = GL_FLOAT; + ac->IsCached.TexCoord[unit] = GL_TRUE; +} + +static void import_vertex( GLcontext *ctx, + GLenum type, GLuint stride ) +{ + ACcontext *ac = AC_CONTEXT(ctx); + struct gl_client_array *from = &ac->Raw.Vertex; + struct gl_client_array *to = &ac->Cache.Vertex; + + /* Limited choices at this stage: + */ + ASSERT(type == GL_FLOAT); + ASSERT(stride == 4*sizeof(GLfloat) || stride == 0); + + _math_trans_4f( (GLfloat (*)[4]) to->Ptr, + from->Ptr, + from->StrideB, + from->Type, + from->Size, + 0, + ac->count - ac->start); + + to->Size = from->Size; + to->StrideB = 4 * sizeof(GLfloat); + to->Type = GL_FLOAT; + ac->IsCached.Vertex = GL_TRUE; +} + +static void import_normal( GLcontext *ctx, + GLenum type, GLuint stride ) +{ + ACcontext *ac = AC_CONTEXT(ctx); + struct gl_client_array *from = &ac->Raw.Normal; + struct gl_client_array *to = &ac->Cache.Normal; + + /* Limited choices at this stage: + */ + ASSERT(type == GL_FLOAT); + ASSERT(stride == 3*sizeof(GLfloat) || stride == 0); + + _math_trans_3f( (GLfloat (*)[3]) to->Ptr, + from->Ptr, + from->StrideB, + from->Type, + 0, + ac->count - ac->start); + + to->StrideB = 3 * sizeof(GLfloat); + to->Type = GL_FLOAT; + ac->IsCached.Normal = GL_TRUE; +} + + + + +static void import_color( GLcontext *ctx, + GLenum type, GLuint stride ) +{ + ACcontext *ac = AC_CONTEXT(ctx); + struct gl_client_array *from = &ac->Raw.Color; + struct gl_client_array *to = &ac->Cache.Color; + + import( ctx, type, to, from ); + + ac->IsCached.Color = GL_TRUE; +} + +static void import_index( GLcontext *ctx, + GLenum type, GLuint stride ) +{ + ACcontext *ac = AC_CONTEXT(ctx); + struct gl_client_array *from = &ac->Raw.Index; + struct gl_client_array *to = &ac->Cache.Index; + + /* Limited choices at this stage: + */ + ASSERT(type == GL_UNSIGNED_INT); + ASSERT(stride == sizeof(GLuint) || stride == 0); + + _math_trans_1ui( (GLuint *) to->Ptr, + from->Ptr, + from->StrideB, + from->Type, + 0, + ac->count - ac->start); + + to->StrideB = sizeof(GLuint); + to->Type = GL_UNSIGNED_INT; + ac->IsCached.Index = GL_TRUE; +} + +static void import_secondarycolor( GLcontext *ctx, + GLenum type, GLuint stride ) +{ + ACcontext *ac = AC_CONTEXT(ctx); + struct gl_client_array *from = &ac->Raw.SecondaryColor; + struct gl_client_array *to = &ac->Cache.SecondaryColor; + + import( ctx, type, to, from ); + + ac->IsCached.SecondaryColor = GL_TRUE; +} + +static void import_fogcoord( GLcontext *ctx, + GLenum type, GLuint stride ) +{ + ACcontext *ac = AC_CONTEXT(ctx); + struct gl_client_array *from = &ac->Raw.FogCoord; + struct gl_client_array *to = &ac->Cache.FogCoord; + + /* Limited choices at this stage: + */ + ASSERT(type == GL_FLOAT); + ASSERT(stride == sizeof(GLfloat) || stride == 0); + + _math_trans_1f( (GLfloat *) to->Ptr, + from->Ptr, + from->StrideB, + from->Type, + 0, + ac->count - ac->start); + + to->StrideB = sizeof(GLfloat); + to->Type = GL_FLOAT; + ac->IsCached.FogCoord = GL_TRUE; +} + +static void import_edgeflag( GLcontext *ctx, + GLenum type, GLuint stride ) +{ + ACcontext *ac = AC_CONTEXT(ctx); + struct gl_client_array *from = &ac->Raw.EdgeFlag; + struct gl_client_array *to = &ac->Cache.EdgeFlag; + + /* Limited choices at this stage: + */ + ASSERT(type == GL_UNSIGNED_BYTE); + ASSERT(stride == sizeof(GLubyte) || stride == 0); + + _math_trans_1ub( (GLubyte *) to->Ptr, + from->Ptr, + from->StrideB, + from->Type, + 0, + ac->count - ac->start); + + to->StrideB = sizeof(GLubyte); + to->Type = GL_UNSIGNED_BYTE; + ac->IsCached.EdgeFlag = GL_TRUE; +} + + + +/* Externals to request arrays with specific properties: + */ +struct gl_client_array *_ac_import_texcoord( GLcontext *ctx, + GLuint unit, + GLenum type, + GLuint reqstride, + GLuint reqsize, + GLboolean reqwriteable, + GLboolean *writeable ) +{ + ACcontext *ac = AC_CONTEXT(ctx); + + /* Can we keep the existing version? + */ + if (ac->NewArrayState & _NEW_ARRAY_TEXCOORD(unit)) + reset_texcoord( ctx, unit ); + + /* Is the request impossible? + */ + if (reqsize != 0 && ac->Raw.TexCoord[unit].Size > (GLint) reqsize) + return 0; + + /* Do we need to pull in a copy of the client data: + */ + if (ac->Raw.TexCoord[unit].Type != type || + (reqstride != 0 && ac->Raw.TexCoord[unit].StrideB != (GLint)reqstride) || + reqwriteable) + { + if (!ac->IsCached.TexCoord[unit]) + import_texcoord(ctx, unit, type, reqstride ); + *writeable = GL_TRUE; + return &ac->Cache.TexCoord[unit]; + } + else { + *writeable = GL_FALSE; + return &ac->Raw.TexCoord[unit]; + } +} + +struct gl_client_array *_ac_import_vertex( GLcontext *ctx, + GLenum type, + GLuint reqstride, + GLuint reqsize, + GLboolean reqwriteable, + GLboolean *writeable ) +{ + ACcontext *ac = AC_CONTEXT(ctx); + + /* Can we keep the existing version? + */ + if (ac->NewArrayState & _NEW_ARRAY_VERTEX) + reset_vertex( ctx ); + + /* Is the request impossible? + */ + if (reqsize != 0 && ac->Raw.Vertex.Size > (GLint) reqsize) + return 0; + + /* Do we need to pull in a copy of the client data: + */ + if (ac->Raw.Vertex.Type != type || + (reqstride != 0 && ac->Raw.Vertex.StrideB != (GLint) reqstride) || + reqwriteable) + { + if (!ac->IsCached.Vertex) + import_vertex(ctx, type, reqstride ); + *writeable = GL_TRUE; + return &ac->Cache.Vertex; + } + else { + *writeable = GL_FALSE; + return &ac->Raw.Vertex; + } +} + +struct gl_client_array *_ac_import_normal( GLcontext *ctx, + GLenum type, + GLuint reqstride, + GLboolean reqwriteable, + GLboolean *writeable ) +{ + ACcontext *ac = AC_CONTEXT(ctx); + + /* Can we keep the existing version? + */ + if (ac->NewArrayState & _NEW_ARRAY_NORMAL) + reset_normal( ctx ); + + /* Do we need to pull in a copy of the client data: + */ + if (ac->Raw.Normal.Type != type || + (reqstride != 0 && ac->Raw.Normal.StrideB != (GLint) reqstride) || + reqwriteable) + { + if (!ac->IsCached.Normal) + import_normal(ctx, type, reqstride ); + *writeable = GL_TRUE; + return &ac->Cache.Normal; + } + else { + *writeable = GL_FALSE; + return &ac->Raw.Normal; + } +} + +struct gl_client_array *_ac_import_color( GLcontext *ctx, + GLenum type, + GLuint reqstride, + GLuint reqsize, + GLboolean reqwriteable, + GLboolean *writeable ) +{ + ACcontext *ac = AC_CONTEXT(ctx); + + /* Can we keep the existing version? + */ + if (ac->NewArrayState & _NEW_ARRAY_COLOR) + reset_color( ctx ); + + /* Is the request impossible? + */ + if (reqsize != 0 && ac->Raw.Color.Size > (GLint) reqsize) { + return 0; + } + + /* Do we need to pull in a copy of the client data: + */ + if ((type != 0 && ac->Raw.Color.Type != type) || + (reqstride != 0 && ac->Raw.Color.StrideB != (GLint) reqstride) || + reqwriteable) + { + if (!ac->IsCached.Color) + import_color(ctx, type, reqstride ); + *writeable = GL_TRUE; + return &ac->Cache.Color; + } + else { + *writeable = GL_FALSE; + return &ac->Raw.Color; + } +} + +struct gl_client_array *_ac_import_index( GLcontext *ctx, + GLenum type, + GLuint reqstride, + GLboolean reqwriteable, + GLboolean *writeable ) +{ + ACcontext *ac = AC_CONTEXT(ctx); + + /* Can we keep the existing version? + */ + if (ac->NewArrayState & _NEW_ARRAY_INDEX) + reset_index( ctx ); + + + /* Do we need to pull in a copy of the client data: + */ + if (ac->Raw.Index.Type != type || + (reqstride != 0 && ac->Raw.Index.StrideB != (GLint) reqstride) || + reqwriteable) + { + if (!ac->IsCached.Index) + import_index(ctx, type, reqstride ); + *writeable = GL_TRUE; + return &ac->Cache.Index; + } + else { + *writeable = GL_FALSE; + return &ac->Raw.Index; + } +} + +struct gl_client_array *_ac_import_secondarycolor( GLcontext *ctx, + GLenum type, + GLuint reqstride, + GLuint reqsize, + GLboolean reqwriteable, + GLboolean *writeable ) +{ + ACcontext *ac = AC_CONTEXT(ctx); + + /* Can we keep the existing version? + */ + if (ac->NewArrayState & _NEW_ARRAY_SECONDARYCOLOR) + reset_secondarycolor( ctx ); + + /* Is the request impossible? + */ + if (reqsize != 0 && ac->Raw.SecondaryColor.Size > (GLint) reqsize) + return 0; + + /* Do we need to pull in a copy of the client data: + */ + if ((type != 0 && ac->Raw.SecondaryColor.Type != type) || + (reqstride != 0 && ac->Raw.SecondaryColor.StrideB != (GLint)reqstride) || + reqwriteable) + { + if (!ac->IsCached.SecondaryColor) + import_secondarycolor(ctx, type, reqstride ); + *writeable = GL_TRUE; + return &ac->Cache.SecondaryColor; + } + else { + *writeable = GL_FALSE; + return &ac->Raw.SecondaryColor; + } +} + +struct gl_client_array *_ac_import_fogcoord( GLcontext *ctx, + GLenum type, + GLuint reqstride, + GLboolean reqwriteable, + GLboolean *writeable ) +{ + ACcontext *ac = AC_CONTEXT(ctx); + + /* Can we keep the existing version? + */ + if (ac->NewArrayState & _NEW_ARRAY_FOGCOORD) + reset_fogcoord( ctx ); + + /* Do we need to pull in a copy of the client data: + */ + if (ac->Raw.FogCoord.Type != type || + (reqstride != 0 && ac->Raw.FogCoord.StrideB != (GLint) reqstride) || + reqwriteable) + { + if (!ac->IsCached.FogCoord) + import_fogcoord(ctx, type, reqstride ); + *writeable = GL_TRUE; + return &ac->Cache.FogCoord; + } + else { + *writeable = GL_FALSE; + return &ac->Raw.FogCoord; + } +} + + + + +struct gl_client_array *_ac_import_edgeflag( GLcontext *ctx, + GLenum type, + GLuint reqstride, + GLboolean reqwriteable, + GLboolean *writeable ) +{ + ACcontext *ac = AC_CONTEXT(ctx); + + /* Can we keep the existing version? + */ + if (ac->NewArrayState & _NEW_ARRAY_EDGEFLAG) + reset_edgeflag( ctx ); + + /* Do we need to pull in a copy of the client data: + */ + if (ac->Raw.EdgeFlag.Type != type || + (reqstride != 0 && ac->Raw.EdgeFlag.StrideB != (GLint) reqstride) || + reqwriteable) + { + if (!ac->IsCached.EdgeFlag) + import_edgeflag(ctx, type, reqstride ); + *writeable = GL_TRUE; + return &ac->Cache.EdgeFlag; + } + else { + *writeable = GL_FALSE; + return &ac->Raw.EdgeFlag; + } +} + + + + + +/* Clients must call this function to validate state and set bounds + * before importing any data: + */ +void _ac_import_range( GLcontext *ctx, GLuint start, GLuint count ) +{ + ACcontext *ac = AC_CONTEXT(ctx); + + if (!ctx->Array.LockCount) { + /* Not locked, discard cached data. Changes to lock + * status are caught via. _ac_invalidate_state(). + */ + ac->NewArrayState = _NEW_ARRAY_ALL; + ac->start = start; + ac->count = count; + } + else { + /* Locked, discard data for any disabled arrays. Require that + * the whole locked range always be dealt with, otherwise hard to + * maintain cached data in the face of clipping. + */ + ac->NewArrayState |= ~ctx->Array._Enabled; + ac->start = ctx->Array.LockFirst; + ac->count = ctx->Array.LockCount; + ASSERT(ac->start == start); /* hmm? */ + ASSERT(ac->count == count); + } +} + + + +/* Additional convienence function for importing a the element list + * for drawelements, drawrangeelements: + */ +CONST void * +_ac_import_elements( GLcontext *ctx, + GLenum new_type, + GLuint count, + GLenum old_type, + CONST void *indices ) +{ + ACcontext *ac = AC_CONTEXT(ctx); + + if (old_type == new_type) + return indices; + + if (ac->elt_size < count * sizeof(GLuint)) { + if (ac->Elts) FREE(ac->Elts); + while (ac->elt_size < count * sizeof(GLuint)) + ac->elt_size *= 2; + ac->Elts = (GLuint *) MALLOC(ac->elt_size); + } + + switch (new_type) { + case GL_UNSIGNED_BYTE: + ASSERT(0); + return 0; + case GL_UNSIGNED_SHORT: + ASSERT(0); + return 0; + case GL_UNSIGNED_INT: { + GLuint *out = (GLuint *)ac->Elts; + GLuint i; + + switch (old_type) { + case GL_UNSIGNED_BYTE: { + CONST GLubyte *in = (CONST GLubyte *)indices; + for (i = 0 ; i < count ; i++) + out[i] = in[i]; + break; + } + case GL_UNSIGNED_SHORT: { + CONST GLushort *in = (CONST GLushort *)indices; + for (i = 0 ; i < count ; i++) + out[i] = in[i]; + break; + } + default: + ASSERT(0); + } + + return (CONST void *)out; + } + default: + ASSERT(0); + break; + } + + return 0; +} Index: dll/opengl/opengl32/mesa/array_cache/acache.h =================================================================== --- dll/opengl/opengl32/mesa/array_cache/acache.h (revision 0) +++ dll/opengl/opengl32/mesa/array_cache/acache.h (working copy) @@ -0,0 +1,124 @@ +/* $Id: acache.h,v 1.2 2001/03/12 00:48:41 gareth Exp $ */ + +/* + * Mesa 3-D graphics library + * Version: 3.5 + * + * Copyright (C) 1999-2001 Brian Paul 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 + * BRIAN PAUL 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. + * + * Authors: + * Keith Whitwell + */ + +#ifndef _ARRAYCACHE_H +#define _ARRAYCACHE_H + +#include "mtypes.h" + + +extern GLboolean +_ac_CreateContext( GLcontext *ctx ); + +extern void +_ac_DestroyContext( GLcontext *ctx ); + +extern void +_ac_InvalidateState( GLcontext *ctx, GLuint new_state ); + +extern struct gl_client_array * +_ac_import_texcoord( GLcontext *ctx, + GLuint unit, + GLenum type, + GLuint reqstride, + GLuint reqsize, + GLboolean reqwritable, + GLboolean *writable ); + +extern struct gl_client_array * +_ac_import_vertex( GLcontext *ctx, + GLenum type, + GLuint reqstride, + GLuint reqsize, + GLboolean reqwritable, + GLboolean *writable ); + +extern struct gl_client_array * +_ac_import_normal( GLcontext *ctx, + GLenum type, + GLuint reqstride, + GLboolean reqwritable, + GLboolean *writable ); + +extern struct gl_client_array * +_ac_import_color( GLcontext *ctx, + GLenum type, + GLuint reqstride, + GLuint reqsize, + GLboolean reqwritable, + GLboolean *writable ); + +extern struct gl_client_array * +_ac_import_index( GLcontext *ctx, + GLenum type, + GLuint reqstride, + GLboolean reqwritable, + GLboolean *writable ); + +extern struct gl_client_array * +_ac_import_secondarycolor( GLcontext *ctx, + GLenum type, + GLuint reqstride, + GLuint reqsize, + GLboolean reqwritable, + GLboolean *writable ); + +extern struct gl_client_array * +_ac_import_fogcoord( GLcontext *ctx, + GLenum type, + GLuint reqstride, + GLboolean reqwritable, + GLboolean *writable ); + +extern struct gl_client_array * +_ac_import_edgeflag( GLcontext *ctx, + GLenum type, + GLuint reqstride, + GLboolean reqwritable, + GLboolean *writable ); + + +/* Clients must call this function to validate state and set bounds + * before importing any data: + */ +extern void +_ac_import_range( GLcontext *ctx, GLuint start, GLuint count ); + + +/* Additional convenience function: + */ +extern CONST void * +_ac_import_elements( GLcontext *ctx, + GLenum new_type, + GLuint count, + GLenum old_type, + CONST void *indices ); + + +#endif Index: dll/opengl/opengl32/mesa/attrib.c =================================================================== --- dll/opengl/opengl32/mesa/attrib.c (revision 0) +++ dll/opengl/opengl32/mesa/attrib.c (working copy) @@ -0,0 +1,1148 @@ +/* $Id: attrib.c,v 1.52 2001/06/18 17:26:08 brianp Exp $ */ + +/* + * Mesa 3-D graphics library + * Version: 3.5 + * + * Copyright (C) 1999-2001 Brian Paul 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 + * BRIAN PAUL 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. + */ + + +#ifdef PC_HEADER +#include "all.h" +#else +#include "glheader.h" +#include "accum.h" +#include "attrib.h" +#include "blend.h" +#include "buffers.h" +#include "clip.h" +#include "colormac.h" +#include "context.h" +#include "depth.h" +#include "enable.h" +#include "enums.h" +#include "fog.h" +#include "hint.h" +#include "light.h" +#include "lines.h" +#include "matrix.h" +#include "mem.h" +#include "points.h" +#include "polygon.h" +#include "simple_list.h" +#include "stencil.h" +#include "texstate.h" +#include "mtypes.h" +#endif + + + + +/* + * Allocate a new attribute state node. These nodes have a + * "kind" value and a pointer to a struct of state data. + */ +static struct gl_attrib_node * +new_attrib_node( GLbitfield kind ) +{ + struct gl_attrib_node *an = MALLOC_STRUCT(gl_attrib_node); + if (an) { + an->kind = kind; + } + return an; +} + + + +/* + * Copy texture object state from one texture object to another. + */ +static void +copy_texobj_state( struct gl_texture_object *dest, + const struct gl_texture_object *src ) +{ + /* + dest->Name = src->Name; + dest->Dimensions = src->Dimensions; + */ + dest->Priority = src->Priority; + dest->BorderColor[0] = src->BorderColor[0]; + dest->BorderColor[1] = src->BorderColor[1]; + dest->BorderColor[2] = src->BorderColor[2]; + dest->BorderColor[3] = src->BorderColor[3]; + dest->WrapS = src->WrapS; + dest->WrapT = src->WrapT; + dest->WrapR = src->WrapR; + dest->MinFilter = src->MinFilter; + dest->MagFilter = src->MagFilter; + dest->MinLod = src->MinLod; + dest->MaxLod = src->MaxLod; + dest->BaseLevel = src->BaseLevel; + dest->MaxLevel = src->MaxLevel; + dest->MaxAnisotropy = src->MaxAnisotropy; + dest->CompareFlag = src->CompareFlag; + dest->CompareOperator = src->CompareOperator; + dest->ShadowAmbient = src->ShadowAmbient; + dest->_MaxLevel = src->_MaxLevel; + dest->_MaxLambda = src->_MaxLambda; + dest->Palette = src->Palette; + dest->Complete = src->Complete; +} + + + +void +_mesa_PushAttrib(GLbitfield mask) +{ + struct gl_attrib_node *newnode; + struct gl_attrib_node *head; + + GET_CURRENT_CONTEXT(ctx); + ASSERT_OUTSIDE_BEGIN_END(ctx); + + if (MESA_VERBOSE&VERBOSE_API) + fprintf(stderr, "glPushAttrib %x\n", (int)mask); + + if (ctx->AttribStackDepth >= MAX_ATTRIB_STACK_DEPTH) { + _mesa_error( ctx, GL_STACK_OVERFLOW, "glPushAttrib" ); + return; + } + + /* Build linked list of attribute nodes which save all attribute */ + /* groups specified by the mask. */ + head = NULL; + + if (mask & GL_ACCUM_BUFFER_BIT) { + struct gl_accum_attrib *attr; + attr = MALLOC_STRUCT( gl_accum_attrib ); + MEMCPY( attr, &ctx->Accum, sizeof(struct gl_accum_attrib) ); + newnode = new_attrib_node( GL_ACCUM_BUFFER_BIT ); + newnode->data = attr; + newnode->next = head; + head = newnode; + } + + if (mask & GL_COLOR_BUFFER_BIT) { + struct gl_colorbuffer_attrib *attr; + attr = MALLOC_STRUCT( gl_colorbuffer_attrib ); + MEMCPY( attr, &ctx->Color, sizeof(struct gl_colorbuffer_attrib) ); + newnode = new_attrib_node( GL_COLOR_BUFFER_BIT ); + newnode->data = attr; + newnode->next = head; + head = newnode; + } + + if (mask & GL_CURRENT_BIT) { + struct gl_current_attrib *attr; + FLUSH_CURRENT( ctx, 0 ); + attr = MALLOC_STRUCT( gl_current_attrib ); + MEMCPY( attr, &ctx->Current, sizeof(struct gl_current_attrib) ); + newnode = new_attrib_node( GL_CURRENT_BIT ); + newnode->data = attr; + newnode->next = head; + head = newnode; + } + + if (mask & GL_DEPTH_BUFFER_BIT) { + struct gl_depthbuffer_attrib *attr; + attr = MALLOC_STRUCT( gl_depthbuffer_attrib ); + MEMCPY( attr, &ctx->Depth, sizeof(struct gl_depthbuffer_attrib) ); + newnode = new_attrib_node( GL_DEPTH_BUFFER_BIT ); + newnode->data = attr; + newnode->next = head; + head = newnode; + } + + if (mask & GL_ENABLE_BIT) { + struct gl_enable_attrib *attr; + GLuint i; + attr = MALLOC_STRUCT( gl_enable_attrib ); + /* Copy enable flags from all other attributes into the enable struct. */ + attr->AlphaTest = ctx->Color.AlphaEnabled; + attr->AutoNormal = ctx->Eval.AutoNormal; + attr->Blend = ctx->Color.BlendEnabled; + for (i=0;iClipPlane[i] = ctx->Transform.ClipEnabled[i]; + } + attr->ColorMaterial = ctx->Light.ColorMaterialEnabled; + attr->Convolution1D = ctx->Pixel.Convolution1DEnabled; + attr->Convolution2D = ctx->Pixel.Convolution2DEnabled; + attr->Separable2D = ctx->Pixel.Separable2DEnabled; + attr->CullFace = ctx->Polygon.CullFlag; + attr->DepthTest = ctx->Depth.Test; + attr->Dither = ctx->Color.DitherFlag; + attr->Fog = ctx->Fog.Enabled; + for (i=0;iLight[i] = ctx->Light.Light[i].Enabled; + } + attr->Lighting = ctx->Light.Enabled; + attr->LineSmooth = ctx->Line.SmoothFlag; + attr->LineStipple = ctx->Line.StippleFlag; + attr->Histogram = ctx->Pixel.HistogramEnabled; + attr->MinMax = ctx->Pixel.MinMaxEnabled; + attr->IndexLogicOp = ctx->Color.IndexLogicOpEnabled; + attr->ColorLogicOp = ctx->Color.ColorLogicOpEnabled; + attr->Map1Color4 = ctx->Eval.Map1Color4; + attr->Map1Index = ctx->Eval.Map1Index; + attr->Map1Normal = ctx->Eval.Map1Normal; + attr->Map1TextureCoord1 = ctx->Eval.Map1TextureCoord1; + attr->Map1TextureCoord2 = ctx->Eval.Map1TextureCoord2; + attr->Map1TextureCoord3 = ctx->Eval.Map1TextureCoord3; + attr->Map1TextureCoord4 = ctx->Eval.Map1TextureCoord4; + attr->Map1Vertex3 = ctx->Eval.Map1Vertex3; + attr->Map1Vertex4 = ctx->Eval.Map1Vertex4; + attr->Map2Color4 = ctx->Eval.Map2Color4; + attr->Map2Index = ctx->Eval.Map2Index; + attr->Map2Normal = ctx->Eval.Map2Normal; + attr->Map2TextureCoord1 = ctx->Eval.Map2TextureCoord1; + attr->Map2TextureCoord2 = ctx->Eval.Map2TextureCoord2; + attr->Map2TextureCoord3 = ctx->Eval.Map2TextureCoord3; + attr->Map2TextureCoord4 = ctx->Eval.Map2TextureCoord4; + attr->Map2Vertex3 = ctx->Eval.Map2Vertex3; + attr->Map2Vertex4 = ctx->Eval.Map2Vertex4; + attr->Normalize = ctx->Transform.Normalize; + attr->PixelTexture = ctx->Pixel.PixelTextureEnabled; + attr->PointSmooth = ctx->Point.SmoothFlag; + attr->PolygonOffsetPoint = ctx->Polygon.OffsetPoint; + attr->PolygonOffsetLine = ctx->Polygon.OffsetLine; + attr->PolygonOffsetFill = ctx->Polygon.OffsetFill; + attr->PolygonSmooth = ctx->Polygon.SmoothFlag; + attr->PolygonStipple = ctx->Polygon.StippleFlag; + attr->RescaleNormals = ctx->Transform.RescaleNormals; + attr->Scissor = ctx->Scissor.Enabled; + attr->Stencil = ctx->Stencil.Enabled; + attr->MultisampleEnabled = ctx->Multisample.Enabled; + attr->SampleAlphaToCoverage = ctx->Multisample.SampleAlphaToCoverage; + attr->SampleAlphaToOne = ctx->Multisample.SampleAlphaToOne; + attr->SampleCoverage = ctx->Multisample.SampleCoverage; + attr->SampleCoverageInvert = ctx->Multisample.SampleCoverageInvert; + for (i=0; iTexture[i] = ctx->Texture.Unit[i].Enabled; + attr->TexGen[i] = ctx->Texture.Unit[i].TexGenEnabled; + } + newnode = new_attrib_node( GL_ENABLE_BIT ); + newnode->data = attr; + newnode->next = head; + head = newnode; + } + + if (mask & GL_EVAL_BIT) { + struct gl_eval_attrib *attr; + attr = MALLOC_STRUCT( gl_eval_attrib ); + MEMCPY( attr, &ctx->Eval, sizeof(struct gl_eval_attrib) ); + newnode = new_attrib_node( GL_EVAL_BIT ); + newnode->data = attr; + newnode->next = head; + head = newnode; + } + + if (mask & GL_FOG_BIT) { + struct gl_fog_attrib *attr; + attr = MALLOC_STRUCT( gl_fog_attrib ); + MEMCPY( attr, &ctx->Fog, sizeof(struct gl_fog_attrib) ); + newnode = new_attrib_node( GL_FOG_BIT ); + newnode->data = attr; + newnode->next = head; + head = newnode; + } + + if (mask & GL_HINT_BIT) { + struct gl_hint_attrib *attr; + attr = MALLOC_STRUCT( gl_hint_attrib ); + MEMCPY( attr, &ctx->Hint, sizeof(struct gl_hint_attrib) ); + newnode = new_attrib_node( GL_HINT_BIT ); + newnode->data = attr; + newnode->next = head; + head = newnode; + } + + if (mask & GL_LIGHTING_BIT) { + struct gl_light_attrib *attr; + FLUSH_CURRENT(ctx, 0); /* flush material changes */ + attr = MALLOC_STRUCT( gl_light_attrib ); + MEMCPY( attr, &ctx->Light, sizeof(struct gl_light_attrib) ); + newnode = new_attrib_node( GL_LIGHTING_BIT ); + newnode->data = attr; + newnode->next = head; + head = newnode; + } + + if (mask & GL_LINE_BIT) { + struct gl_line_attrib *attr; + attr = MALLOC_STRUCT( gl_line_attrib ); + MEMCPY( attr, &ctx->Line, sizeof(struct gl_line_attrib) ); + newnode = new_attrib_node( GL_LINE_BIT ); + newnode->data = attr; + newnode->next = head; + head = newnode; + } + + if (mask & GL_LIST_BIT) { + struct gl_list_attrib *attr; + attr = MALLOC_STRUCT( gl_list_attrib ); + MEMCPY( attr, &ctx->List, sizeof(struct gl_list_attrib) ); + newnode = new_attrib_node( GL_LIST_BIT ); + newnode->data = attr; + newnode->next = head; + head = newnode; + } + + if (mask & GL_PIXEL_MODE_BIT) { + struct gl_pixel_attrib *attr; + attr = MALLOC_STRUCT( gl_pixel_attrib ); + MEMCPY( attr, &ctx->Pixel, sizeof(struct gl_pixel_attrib) ); + newnode = new_attrib_node( GL_PIXEL_MODE_BIT ); + newnode->data = attr; + newnode->next = head; + head = newnode; + } + + if (mask & GL_POINT_BIT) { + struct gl_point_attrib *attr; + attr = MALLOC_STRUCT( gl_point_attrib ); + MEMCPY( attr, &ctx->Point, sizeof(struct gl_point_attrib) ); + newnode = new_attrib_node( GL_POINT_BIT ); + newnode->data = attr; + newnode->next = head; + head = newnode; + } + + if (mask & GL_POLYGON_BIT) { + struct gl_polygon_attrib *attr; + attr = MALLOC_STRUCT( gl_polygon_attrib ); + MEMCPY( attr, &ctx->Polygon, sizeof(struct gl_polygon_attrib) ); + newnode = new_attrib_node( GL_POLYGON_BIT ); + newnode->data = attr; + newnode->next = head; + head = newnode; + } + + if (mask & GL_POLYGON_STIPPLE_BIT) { + GLuint *stipple; + stipple = (GLuint *) MALLOC( 32*sizeof(GLuint) ); + MEMCPY( stipple, ctx->PolygonStipple, 32*sizeof(GLuint) ); + newnode = new_attrib_node( GL_POLYGON_STIPPLE_BIT ); + newnode->data = stipple; + newnode->next = head; + head = newnode; + } + + if (mask & GL_SCISSOR_BIT) { + struct gl_scissor_attrib *attr; + attr = MALLOC_STRUCT( gl_scissor_attrib ); + MEMCPY( attr, &ctx->Scissor, sizeof(struct gl_scissor_attrib) ); + newnode = new_attrib_node( GL_SCISSOR_BIT ); + newnode->data = attr; + newnode->next = head; + head = newnode; + } + + if (mask & GL_STENCIL_BUFFER_BIT) { + struct gl_stencil_attrib *attr; + attr = MALLOC_STRUCT( gl_stencil_attrib ); + MEMCPY( attr, &ctx->Stencil, sizeof(struct gl_stencil_attrib) ); + newnode = new_attrib_node( GL_STENCIL_BUFFER_BIT ); + newnode->data = attr; + newnode->next = head; + head = newnode; + } + + if (mask & GL_TEXTURE_BIT) { + struct gl_texture_attrib *attr; + GLuint u; + /* Bump the texture object reference counts so that they don't + * inadvertantly get deleted. + */ + for (u = 0; u < ctx->Const.MaxTextureUnits; u++) { + ctx->Texture.Unit[u].Current1D->RefCount++; + ctx->Texture.Unit[u].Current2D->RefCount++; + ctx->Texture.Unit[u].Current3D->RefCount++; + ctx->Texture.Unit[u].CurrentCubeMap->RefCount++; + } + attr = MALLOC_STRUCT( gl_texture_attrib ); + MEMCPY( attr, &ctx->Texture, sizeof(struct gl_texture_attrib) ); + /* copy state of the currently bound texture objects */ + for (u = 0; u < ctx->Const.MaxTextureUnits; u++) { + copy_texobj_state(&attr->Unit[u].Saved1D, attr->Unit[u].Current1D); + copy_texobj_state(&attr->Unit[u].Saved2D, attr->Unit[u].Current2D); + copy_texobj_state(&attr->Unit[u].Saved3D, attr->Unit[u].Current3D); + copy_texobj_state(&attr->Unit[u].SavedCubeMap, attr->Unit[u].CurrentCubeMap); + } + newnode = new_attrib_node( GL_TEXTURE_BIT ); + newnode->data = attr; + newnode->next = head; + head = newnode; + } + + if (mask & GL_TRANSFORM_BIT) { + struct gl_transform_attrib *attr; + attr = MALLOC_STRUCT( gl_transform_attrib ); + MEMCPY( attr, &ctx->Transform, sizeof(struct gl_transform_attrib) ); + newnode = new_attrib_node( GL_TRANSFORM_BIT ); + newnode->data = attr; + newnode->next = head; + head = newnode; + } + + if (mask & GL_VIEWPORT_BIT) { + struct gl_viewport_attrib *attr; + attr = MALLOC_STRUCT( gl_viewport_attrib ); + MEMCPY( attr, &ctx->Viewport, sizeof(struct gl_viewport_attrib) ); + newnode = new_attrib_node( GL_VIEWPORT_BIT ); + newnode->data = attr; + newnode->next = head; + head = newnode; + } + + /* GL_ARB_multisample */ + if (mask & GL_MULTISAMPLE_BIT_ARB) { + struct gl_multisample_attrib *attr; + attr = MALLOC_STRUCT( gl_multisample_attrib ); + MEMCPY( attr, &ctx->Multisample, sizeof(struct gl_multisample_attrib) ); + newnode = new_attrib_node( GL_MULTISAMPLE_BIT_ARB ); + newnode->data = attr; + newnode->next = head; + head = newnode; + } + + ctx->AttribStack[ctx->AttribStackDepth] = head; + ctx->AttribStackDepth++; +} + + + +static void +pop_enable_group(GLcontext *ctx, const struct gl_enable_attrib *enable) +{ + GLuint i; + +#define TEST_AND_UPDATE(VALUE, NEWVALUE, ENUM) \ + if ((VALUE) != (NEWVALUE)) { \ + _mesa_set_enable( ctx, ENUM, (NEWVALUE) ); \ + } + + TEST_AND_UPDATE(ctx->Color.AlphaEnabled, enable->AlphaTest, GL_ALPHA_TEST); + TEST_AND_UPDATE(ctx->Transform.Normalize, enable->AutoNormal, GL_NORMALIZE); + TEST_AND_UPDATE(ctx->Color.BlendEnabled, enable->Blend, GL_BLEND); + + for (i=0;iTransform.ClipEnabled[i] != enable->ClipPlane[i]) + _mesa_set_enable(ctx, (GLenum) (GL_CLIP_PLANE0 + i), + enable->ClipPlane[i]); + } + + TEST_AND_UPDATE(ctx->Light.ColorMaterialEnabled, enable->ColorMaterial, + GL_COLOR_MATERIAL); + TEST_AND_UPDATE(ctx->Polygon.CullFlag, enable->CullFace, GL_CULL_FACE); + TEST_AND_UPDATE(ctx->Depth.Test, enable->DepthTest, GL_DEPTH_TEST); + TEST_AND_UPDATE(ctx->Color.DitherFlag, enable->Dither, GL_DITHER); + TEST_AND_UPDATE(ctx->Pixel.Convolution1DEnabled, enable->Convolution1D, + GL_CONVOLUTION_1D); + TEST_AND_UPDATE(ctx->Pixel.Convolution2DEnabled, enable->Convolution2D, + GL_CONVOLUTION_2D); + TEST_AND_UPDATE(ctx->Pixel.Separable2DEnabled, enable->Separable2D, + GL_SEPARABLE_2D); + TEST_AND_UPDATE(ctx->Fog.Enabled, enable->Fog, GL_FOG); + TEST_AND_UPDATE(ctx->Light.Enabled, enable->Lighting, GL_LIGHTING); + TEST_AND_UPDATE(ctx->Line.SmoothFlag, enable->LineSmooth, GL_LINE_SMOOTH); + TEST_AND_UPDATE(ctx->Line.StippleFlag, enable->LineStipple, + GL_LINE_STIPPLE); + TEST_AND_UPDATE(ctx->Color.IndexLogicOpEnabled, enable->IndexLogicOp, + GL_INDEX_LOGIC_OP); + TEST_AND_UPDATE(ctx->Color.ColorLogicOpEnabled, enable->ColorLogicOp, + GL_COLOR_LOGIC_OP); + TEST_AND_UPDATE(ctx->Eval.Map1Color4, enable->Map1Color4, GL_MAP1_COLOR_4); + TEST_AND_UPDATE(ctx->Eval.Map1Index, enable->Map1Index, GL_MAP1_INDEX); + TEST_AND_UPDATE(ctx->Eval.Map1Normal, enable->Map1Normal, GL_MAP1_NORMAL); + TEST_AND_UPDATE(ctx->Eval.Map1TextureCoord1, enable->Map1TextureCoord1, + GL_MAP1_TEXTURE_COORD_1); + TEST_AND_UPDATE(ctx->Eval.Map1TextureCoord2, enable->Map1TextureCoord2, + GL_MAP1_TEXTURE_COORD_2); + TEST_AND_UPDATE(ctx->Eval.Map1TextureCoord3, enable->Map1TextureCoord3, + GL_MAP1_TEXTURE_COORD_3); + TEST_AND_UPDATE(ctx->Eval.Map1TextureCoord4, enable->Map1TextureCoord4, + GL_MAP1_TEXTURE_COORD_4); + TEST_AND_UPDATE(ctx->Eval.Map1Vertex3, enable->Map1Vertex3, + GL_MAP1_VERTEX_3); + TEST_AND_UPDATE(ctx->Eval.Map1Vertex4, enable->Map1Vertex4, + GL_MAP1_VERTEX_4); + TEST_AND_UPDATE(ctx->Eval.Map2Color4, enable->Map2Color4, GL_MAP2_COLOR_4); + TEST_AND_UPDATE(ctx->Eval.Map2Index, enable->Map2Index, GL_MAP2_INDEX); + TEST_AND_UPDATE(ctx->Eval.Map2Normal, enable->Map2Normal, GL_MAP2_NORMAL); + TEST_AND_UPDATE(ctx->Eval.Map2TextureCoord1, enable->Map2TextureCoord1, + GL_MAP2_TEXTURE_COORD_1); + TEST_AND_UPDATE(ctx->Eval.Map2TextureCoord2, enable->Map2TextureCoord2, + GL_MAP2_TEXTURE_COORD_2); + TEST_AND_UPDATE(ctx->Eval.Map2TextureCoord3, enable->Map2TextureCoord3, + GL_MAP2_TEXTURE_COORD_3); + TEST_AND_UPDATE(ctx->Eval.Map2TextureCoord4, enable->Map2TextureCoord4, + GL_MAP2_TEXTURE_COORD_4); + TEST_AND_UPDATE(ctx->Eval.Map2Vertex3, enable->Map2Vertex3, + GL_MAP2_VERTEX_3); + TEST_AND_UPDATE(ctx->Eval.Map2Vertex4, enable->Map2Vertex4, + GL_MAP2_VERTEX_4); + TEST_AND_UPDATE(ctx->Transform.Normalize, enable->Normalize, GL_NORMALIZE); + TEST_AND_UPDATE(ctx->Transform.RescaleNormals, enable->RescaleNormals, + GL_RESCALE_NORMAL_EXT); + TEST_AND_UPDATE(ctx->Pixel.PixelTextureEnabled, enable->PixelTexture, + GL_POINT_SMOOTH); + TEST_AND_UPDATE(ctx->Point.SmoothFlag, enable->PointSmooth, + GL_POINT_SMOOTH); + TEST_AND_UPDATE(ctx->Polygon.OffsetPoint, enable->PolygonOffsetPoint, + GL_POLYGON_OFFSET_POINT); + TEST_AND_UPDATE(ctx->Polygon.OffsetLine, enable->PolygonOffsetLine, + GL_POLYGON_OFFSET_LINE); + TEST_AND_UPDATE(ctx->Polygon.OffsetFill, enable->PolygonOffsetFill, + GL_POLYGON_OFFSET_FILL); + TEST_AND_UPDATE(ctx->Polygon.SmoothFlag, enable->PolygonSmooth, + GL_POLYGON_SMOOTH); + TEST_AND_UPDATE(ctx->Polygon.StippleFlag, enable->PolygonStipple, + GL_POLYGON_STIPPLE); + TEST_AND_UPDATE(ctx->Scissor.Enabled, enable->Scissor, GL_SCISSOR_TEST); + TEST_AND_UPDATE(ctx->Stencil.Enabled, enable->Stencil, GL_STENCIL_TEST); + TEST_AND_UPDATE(ctx->Multisample.Enabled, enable->MultisampleEnabled, + GL_MULTISAMPLE_ARB); + TEST_AND_UPDATE(ctx->Multisample.SampleAlphaToCoverage, + enable->SampleAlphaToCoverage, + GL_SAMPLE_ALPHA_TO_COVERAGE_ARB); + TEST_AND_UPDATE(ctx->Multisample.SampleAlphaToOne, + enable->SampleAlphaToOne, + GL_SAMPLE_ALPHA_TO_ONE_ARB); + TEST_AND_UPDATE(ctx->Multisample.SampleCoverage, + enable->SampleCoverage, + GL_SAMPLE_COVERAGE_ARB); + TEST_AND_UPDATE(ctx->Multisample.SampleCoverageInvert, + enable->SampleCoverageInvert, + GL_SAMPLE_COVERAGE_INVERT_ARB); +#undef TEST_AND_UPDATE + + /* texture unit enables */ + for (i = 0; i < ctx->Const.MaxTextureUnits; i++) { + if (ctx->Texture.Unit[i].Enabled != enable->Texture[i]) { + ctx->Texture.Unit[i].Enabled = enable->Texture[i]; + if (ctx->Driver.Enable) { + if (ctx->Driver.ActiveTexture) { + (*ctx->Driver.ActiveTexture)(ctx, i); + } + (*ctx->Driver.Enable)( ctx, GL_TEXTURE_1D, + (GLboolean) (enable->Texture[i] & TEXTURE0_1D) ); + (*ctx->Driver.Enable)( ctx, GL_TEXTURE_2D, + (GLboolean) (enable->Texture[i] & TEXTURE0_2D) ); + (*ctx->Driver.Enable)( ctx, GL_TEXTURE_3D, + (GLboolean) (enable->Texture[i] & TEXTURE0_3D) ); + } + } + + if (ctx->Texture.Unit[i].TexGenEnabled != enable->TexGen[i]) { + ctx->Texture.Unit[i].TexGenEnabled = enable->TexGen[i]; + if (ctx->Driver.Enable) { + if (ctx->Driver.ActiveTexture) { + (*ctx->Driver.ActiveTexture)(ctx, i); + } + if (enable->TexGen[i] & S_BIT) + (*ctx->Driver.Enable)( ctx, GL_TEXTURE_GEN_S, GL_TRUE); + else + (*ctx->Driver.Enable)( ctx, GL_TEXTURE_GEN_S, GL_FALSE); + if (enable->TexGen[i] & T_BIT) + (*ctx->Driver.Enable)( ctx, GL_TEXTURE_GEN_T, GL_TRUE); + else + (*ctx->Driver.Enable)( ctx, GL_TEXTURE_GEN_T, GL_FALSE); + if (enable->TexGen[i] & R_BIT) + (*ctx->Driver.Enable)( ctx, GL_TEXTURE_GEN_R, GL_TRUE); + else + (*ctx->Driver.Enable)( ctx, GL_TEXTURE_GEN_R, GL_FALSE); + if (enable->TexGen[i] & Q_BIT) + (*ctx->Driver.Enable)( ctx, GL_TEXTURE_GEN_Q, GL_TRUE); + else + (*ctx->Driver.Enable)( ctx, GL_TEXTURE_GEN_Q, GL_FALSE); + } + } + } + + if (ctx->Driver.ActiveTexture) { + (*ctx->Driver.ActiveTexture)(ctx, ctx->Texture.CurrentUnit); + } +} + + +static void +pop_texture_group(GLcontext *ctx, const struct gl_texture_attrib *texAttrib) +{ + GLuint u; + + /* "un-bump" the texture object reference counts. We did that so they + * wouldn't inadvertantly get deleted. + */ + for (u = 0; u < ctx->Const.MaxTextureUnits; u++) { + ctx->Texture.Unit[u].Current1D->RefCount--; + ctx->Texture.Unit[u].Current2D->RefCount--; + ctx->Texture.Unit[u].Current3D->RefCount--; + ctx->Texture.Unit[u].CurrentCubeMap->RefCount--; + } + + for (u = 0; u < ctx->Const.MaxTextureUnits; u++) { + const struct gl_texture_unit *unit = &texAttrib->Unit[u]; + GLuint numObjs, i; + + _mesa_ActiveTextureARB(GL_TEXTURE0_ARB + u); + _mesa_set_enable(ctx, GL_TEXTURE_1D, unit->Enabled & TEXTURE0_1D); + _mesa_set_enable(ctx, GL_TEXTURE_2D, unit->Enabled & TEXTURE0_2D); + _mesa_set_enable(ctx, GL_TEXTURE_3D, unit->Enabled & TEXTURE0_3D); + if (ctx->Extensions.ARB_texture_cube_map) { + _mesa_set_enable(ctx, GL_TEXTURE_CUBE_MAP_ARB, + unit->Enabled & TEXTURE0_CUBE); + } + _mesa_TexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, unit->EnvMode); + _mesa_TexEnvfv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, unit->EnvColor); + _mesa_TexGeni(GL_S, GL_TEXTURE_GEN_MODE, unit->GenModeS); + _mesa_TexGeni(GL_T, GL_TEXTURE_GEN_MODE, unit->GenModeT); + _mesa_TexGeni(GL_R, GL_TEXTURE_GEN_MODE, unit->GenModeR); + _mesa_TexGeni(GL_Q, GL_TEXTURE_GEN_MODE, unit->GenModeQ); + _mesa_TexGenfv(GL_S, GL_OBJECT_PLANE, unit->ObjectPlaneS); + _mesa_TexGenfv(GL_T, GL_OBJECT_PLANE, unit->ObjectPlaneT); + _mesa_TexGenfv(GL_R, GL_OBJECT_PLANE, unit->ObjectPlaneR); + _mesa_TexGenfv(GL_Q, GL_OBJECT_PLANE, unit->ObjectPlaneQ); + _mesa_TexGenfv(GL_S, GL_EYE_PLANE, unit->EyePlaneS); + _mesa_TexGenfv(GL_T, GL_EYE_PLANE, unit->EyePlaneT); + _mesa_TexGenfv(GL_R, GL_EYE_PLANE, unit->EyePlaneR); + _mesa_TexGenfv(GL_Q, GL_EYE_PLANE, unit->EyePlaneQ); + if (ctx->Extensions.EXT_texture_lod_bias) { + _mesa_TexEnvf(GL_TEXTURE_FILTER_CONTROL_EXT, + GL_TEXTURE_LOD_BIAS_EXT, unit->LodBias); + } + if (ctx->Extensions.EXT_texture_env_combine || + ctx->Extensions.ARB_texture_env_combine) { + _mesa_TexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB_EXT, + unit->CombineModeRGB); + _mesa_TexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA_EXT, + unit->CombineModeA); + _mesa_TexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB_EXT, + unit->CombineSourceRGB[0]); + _mesa_TexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_RGB_EXT, + unit->CombineSourceRGB[1]); + _mesa_TexEnvi(GL_TEXTURE_ENV, GL_SOURCE2_RGB_EXT, + unit->CombineSourceRGB[2]); + _mesa_TexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA_EXT, + unit->CombineSourceA[0]); + _mesa_TexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_ALPHA_EXT, + unit->CombineSourceA[1]); + _mesa_TexEnvi(GL_TEXTURE_ENV, GL_SOURCE2_ALPHA_EXT, + unit->CombineSourceA[2]); + _mesa_TexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_RGB_EXT, + unit->CombineOperandRGB[0]); + _mesa_TexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_RGB_EXT, + unit->CombineOperandRGB[1]); + _mesa_TexEnvi(GL_TEXTURE_ENV, GL_OPERAND2_RGB_EXT, + unit->CombineOperandRGB[2]); + _mesa_TexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_ALPHA_EXT, + unit->CombineOperandA[0]); + _mesa_TexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_ALPHA_EXT, + unit->CombineOperandA[1]); + _mesa_TexEnvi(GL_TEXTURE_ENV, GL_OPERAND2_ALPHA_EXT, + unit->CombineOperandA[2]); + _mesa_TexEnvi(GL_TEXTURE_ENV, GL_RGB_SCALE_EXT, + 1 << unit->CombineScaleShiftRGB); + _mesa_TexEnvi(GL_TEXTURE_ENV, GL_ALPHA_SCALE, + 1 << unit->CombineScaleShiftA); + } + + /* Restore texture object state */ + numObjs = ctx->Extensions.ARB_texture_cube_map ? 4 : 3; + + for (i = 0; i < numObjs; i++) { + GLenum target = 0; + const struct gl_texture_object *obj = NULL; + GLfloat bordColor[4]; + + switch (i) { + case 0: + target = GL_TEXTURE_1D; + obj = &unit->Saved1D; + break; + case 1: + target = GL_TEXTURE_2D; + obj = &unit->Saved2D; + break; + case 2: + target = GL_TEXTURE_3D; + obj = &unit->Saved3D; + break; + case 3: + target = GL_TEXTURE_CUBE_MAP_ARB; + obj = &unit->SavedCubeMap; + break; + default: + ; /* silence warnings */ + } + + bordColor[0] = CHAN_TO_FLOAT(obj->BorderColor[0]); + bordColor[1] = CHAN_TO_FLOAT(obj->BorderColor[1]); + bordColor[2] = CHAN_TO_FLOAT(obj->BorderColor[2]); + bordColor[3] = CHAN_TO_FLOAT(obj->BorderColor[3]); + + _mesa_TexParameterf(target, GL_TEXTURE_PRIORITY, obj->Priority); + _mesa_TexParameterfv(target, GL_TEXTURE_BORDER_COLOR, bordColor); + _mesa_TexParameteri(target, GL_TEXTURE_WRAP_S, obj->WrapS); + _mesa_TexParameteri(target, GL_TEXTURE_WRAP_T, obj->WrapT); + _mesa_TexParameteri(target, GL_TEXTURE_WRAP_R, obj->WrapR); + _mesa_TexParameteri(target, GL_TEXTURE_MIN_FILTER, obj->MinFilter); + _mesa_TexParameteri(target, GL_TEXTURE_MAG_FILTER, obj->MagFilter); + _mesa_TexParameterf(target, GL_TEXTURE_MIN_LOD, obj->MinLod); + _mesa_TexParameterf(target, GL_TEXTURE_MAX_LOD, obj->MaxLod); + _mesa_TexParameteri(target, GL_TEXTURE_BASE_LEVEL, obj->BaseLevel); + _mesa_TexParameteri(target, GL_TEXTURE_MAX_LEVEL, obj->MaxLevel); + if (ctx->Extensions.EXT_texture_filter_anisotropic) { + _mesa_TexParameterf(target, GL_TEXTURE_MAX_ANISOTROPY_EXT, + obj->MaxAnisotropy); + } + if (ctx->Extensions.SGIX_shadow) { + _mesa_TexParameteri(target, GL_TEXTURE_COMPARE_SGIX, + obj->CompareFlag); + _mesa_TexParameteri(target, GL_TEXTURE_COMPARE_OPERATOR_SGIX, + obj->CompareOperator); + } + if (ctx->Extensions.SGIX_shadow_ambient) { + _mesa_TexParameterf(target, GL_SHADOW_AMBIENT_SGIX, + CHAN_TO_FLOAT(obj->ShadowAmbient)); + } + + } + } + _mesa_ActiveTextureARB(GL_TEXTURE0_ARB + + texAttrib->CurrentUnit); +} + + +/* + * This function is kind of long just because we have to call a lot + * of device driver functions to update device driver state. + * + * XXX As it is now, most of the pop-code calls immediate-mode Mesa functions + * in order to restore GL state. This isn't terribly efficient but it + * ensures that dirty flags and any derived state gets updated correctly. + * We could at least check if the value to restore equals the current value + * and then skip the Mesa call. + */ +void +_mesa_PopAttrib(void) +{ + struct gl_attrib_node *attr, *next; + GET_CURRENT_CONTEXT(ctx); + ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx); + + if (ctx->AttribStackDepth == 0) { + _mesa_error( ctx, GL_STACK_UNDERFLOW, "glPopAttrib" ); + return; + } + + ctx->AttribStackDepth--; + attr = ctx->AttribStack[ctx->AttribStackDepth]; + + while (attr) { + + if (MESA_VERBOSE&VERBOSE_API) { + fprintf(stderr, "glPopAttrib %s\n", + _mesa_lookup_enum_by_nr(attr->kind)); + } + + switch (attr->kind) { + case GL_ACCUM_BUFFER_BIT: + { + const struct gl_accum_attrib *accum; + accum = (const struct gl_accum_attrib *) attr->data; + _mesa_ClearAccum(accum->ClearColor[0], + accum->ClearColor[1], + accum->ClearColor[2], + accum->ClearColor[3]); + } + break; + case GL_COLOR_BUFFER_BIT: + { + const struct gl_colorbuffer_attrib *color; + color = (const struct gl_colorbuffer_attrib *) attr->data; + _mesa_ClearIndex(color->ClearIndex); + _mesa_ClearColor(CHAN_TO_FLOAT(color->ClearColor[0]), + CHAN_TO_FLOAT(color->ClearColor[1]), + CHAN_TO_FLOAT(color->ClearColor[2]), + CHAN_TO_FLOAT(color->ClearColor[3])); + _mesa_IndexMask(color->IndexMask); + _mesa_ColorMask((GLboolean) (color->ColorMask[0] != 0), + (GLboolean) (color->ColorMask[1] != 0), + (GLboolean) (color->ColorMask[2] != 0), + (GLboolean) (color->ColorMask[3] != 0)); + _mesa_DrawBuffer(color->DrawBuffer); + _mesa_set_enable(ctx, GL_ALPHA_TEST, color->AlphaEnabled); + _mesa_AlphaFunc(color->AlphaFunc, + CHAN_TO_FLOAT(color->AlphaRef)); + _mesa_set_enable(ctx, GL_BLEND, color->BlendEnabled); + _mesa_BlendFuncSeparateEXT(color->BlendSrcRGB, + color->BlendDstRGB, + color->BlendSrcA, + color->BlendDstA); + _mesa_BlendEquation(color->BlendEquation); + _mesa_BlendColor(color->BlendColor[0], + color->BlendColor[1], + color->BlendColor[2], + color->BlendColor[3]); + _mesa_LogicOp(color->LogicOp); + _mesa_set_enable(ctx, GL_COLOR_LOGIC_OP, + color->ColorLogicOpEnabled); + _mesa_set_enable(ctx, GL_INDEX_LOGIC_OP, + color->IndexLogicOpEnabled); + _mesa_set_enable(ctx, GL_DITHER, color->DitherFlag); + } + break; + case GL_CURRENT_BIT: + FLUSH_CURRENT( ctx, 0 ); + MEMCPY( &ctx->Current, attr->data, + sizeof(struct gl_current_attrib) ); + break; + case GL_DEPTH_BUFFER_BIT: + { + const struct gl_depthbuffer_attrib *depth; + depth = (const struct gl_depthbuffer_attrib *) attr->data; + _mesa_DepthFunc(depth->Func); + _mesa_ClearDepth(depth->Clear); + _mesa_set_enable(ctx, GL_DEPTH_TEST, depth->Test); + _mesa_DepthMask(depth->Mask); + if (ctx->Extensions.HP_occlusion_test) + _mesa_set_enable(ctx, GL_OCCLUSION_TEST_HP, + depth->OcclusionTest); + } + break; + case GL_ENABLE_BIT: + { + const struct gl_enable_attrib *enable; + enable = (const struct gl_enable_attrib *) attr->data; + pop_enable_group(ctx, enable); + ctx->NewState |= _NEW_ALL; + } + break; + case GL_EVAL_BIT: + MEMCPY( &ctx->Eval, attr->data, sizeof(struct gl_eval_attrib) ); + ctx->NewState |= _NEW_EVAL; + break; + case GL_FOG_BIT: + { + const struct gl_fog_attrib *fog; + fog = (const struct gl_fog_attrib *) attr->data; + _mesa_set_enable(ctx, GL_FOG, fog->Enabled); + _mesa_Fogfv(GL_FOG_COLOR, fog->Color); + _mesa_Fogf(GL_FOG_DENSITY, fog->Density); + _mesa_Fogf(GL_FOG_START, fog->Start); + _mesa_Fogf(GL_FOG_END, fog->End); + _mesa_Fogf(GL_FOG_INDEX, fog->Index); + _mesa_Fogi(GL_FOG_MODE, fog->Mode); + } + break; + case GL_HINT_BIT: + { + const struct gl_hint_attrib *hint; + hint = (const struct gl_hint_attrib *) attr->data; + _mesa_Hint(GL_PERSPECTIVE_CORRECTION_HINT, + hint->PerspectiveCorrection ); + _mesa_Hint(GL_POINT_SMOOTH_HINT, hint->PointSmooth); + _mesa_Hint(GL_LINE_SMOOTH_HINT, hint->LineSmooth); + _mesa_Hint(GL_POLYGON_SMOOTH_HINT, hint->PolygonSmooth); + _mesa_Hint(GL_FOG_HINT, hint->Fog); + _mesa_Hint(GL_CLIP_VOLUME_CLIPPING_HINT_EXT, + hint->ClipVolumeClipping); + if (ctx->Extensions.ARB_texture_compression) + _mesa_Hint(GL_TEXTURE_COMPRESSION_HINT_ARB, + hint->TextureCompression); + } + break; + case GL_LIGHTING_BIT: + { + GLuint i; + const struct gl_light_attrib *light; + light = (const struct gl_light_attrib *) attr->data; + /* lighting enable */ + _mesa_set_enable(ctx, GL_LIGHTING, light->Enabled); + /* per-light state */ + for (i = 0; i < MAX_LIGHTS; i++) { + GLenum lgt = (GLenum) (GL_LIGHT0 + i); + _mesa_set_enable(ctx, lgt, light->Light[i].Enabled); + MEMCPY(&ctx->Light.Light[i], &light->Light[i], + sizeof(struct gl_light)); + } + /* light model */ + _mesa_LightModelfv(GL_LIGHT_MODEL_AMBIENT, + light->Model.Ambient); + _mesa_LightModelf(GL_LIGHT_MODEL_LOCAL_VIEWER, + (GLfloat) light->Model.LocalViewer); + _mesa_LightModelf(GL_LIGHT_MODEL_TWO_SIDE, + (GLfloat) light->Model.TwoSide); + _mesa_LightModelf(GL_LIGHT_MODEL_COLOR_CONTROL, + (GLfloat) light->Model.ColorControl); + /* materials */ + MEMCPY(ctx->Light.Material, light->Material, + 2 * sizeof(struct gl_material)); + /* shade model */ + _mesa_ShadeModel(light->ShadeModel); + /* color material */ + _mesa_ColorMaterial(light->ColorMaterialFace, + light->ColorMaterialMode); + _mesa_set_enable(ctx, GL_COLOR_MATERIAL, + light->ColorMaterialEnabled); + } + break; + case GL_LINE_BIT: + { + const struct gl_line_attrib *line; + line = (const struct gl_line_attrib *) attr->data; + _mesa_set_enable(ctx, GL_LINE_SMOOTH, line->SmoothFlag); + _mesa_set_enable(ctx, GL_LINE_STIPPLE, line->StippleFlag); + _mesa_LineStipple(line->StippleFactor, line->StipplePattern); + _mesa_LineWidth(line->Width); + } + break; + case GL_LIST_BIT: + MEMCPY( &ctx->List, attr->data, sizeof(struct gl_list_attrib) ); + break; + case GL_PIXEL_MODE_BIT: + MEMCPY( &ctx->Pixel, attr->data, sizeof(struct gl_pixel_attrib) ); + ctx->NewState |= _NEW_PIXEL; + break; + case GL_POINT_BIT: + { + const struct gl_point_attrib *point; + point = (const struct gl_point_attrib *) attr->data; + _mesa_PointSize(point->Size); + _mesa_set_enable(ctx, GL_POINT_SMOOTH, point->SmoothFlag); + _mesa_PointParameterfvEXT(GL_DISTANCE_ATTENUATION_EXT, + point->Params); + _mesa_PointParameterfEXT(GL_POINT_SIZE_MIN_EXT, point->MinSize); + _mesa_PointParameterfEXT(GL_POINT_SIZE_MAX_EXT, point->MaxSize); + _mesa_PointParameterfEXT(GL_POINT_FADE_THRESHOLD_SIZE_EXT, + point->Threshold); + } + break; + case GL_POLYGON_BIT: + { + const struct gl_polygon_attrib *polygon; + polygon = (const struct gl_polygon_attrib *) attr->data; + _mesa_CullFace(polygon->CullFaceMode); + _mesa_FrontFace(polygon->FrontFace); + _mesa_PolygonMode(GL_FRONT, polygon->FrontMode); + _mesa_PolygonMode(GL_BACK, polygon->BackMode); + _mesa_PolygonOffset(polygon->OffsetFactor, + polygon->OffsetUnits); + _mesa_set_enable(ctx, GL_POLYGON_SMOOTH, polygon->SmoothFlag); + _mesa_set_enable(ctx, GL_POLYGON_STIPPLE, polygon->StippleFlag); + _mesa_set_enable(ctx, GL_CULL_FACE, polygon->CullFlag); + _mesa_set_enable(ctx, GL_POLYGON_OFFSET_POINT, + polygon->OffsetPoint); + _mesa_set_enable(ctx, GL_POLYGON_OFFSET_LINE, + polygon->OffsetLine); + _mesa_set_enable(ctx, GL_POLYGON_OFFSET_FILL, + polygon->OffsetFill); + } + break; + case GL_POLYGON_STIPPLE_BIT: + MEMCPY( ctx->PolygonStipple, attr->data, 32*sizeof(GLuint) ); + ctx->NewState |= _NEW_POLYGONSTIPPLE; + if (ctx->Driver.PolygonStipple) + ctx->Driver.PolygonStipple( ctx, (const GLubyte *) attr->data ); + break; + case GL_SCISSOR_BIT: + { + const struct gl_scissor_attrib *scissor; + scissor = (const struct gl_scissor_attrib *) attr->data; + _mesa_Scissor(scissor->X, scissor->Y, + scissor->Width, scissor->Height); + _mesa_set_enable(ctx, GL_SCISSOR_TEST, scissor->Enabled); + } + break; + case GL_STENCIL_BUFFER_BIT: + { + const struct gl_stencil_attrib *stencil; + stencil = (const struct gl_stencil_attrib *) attr->data; + _mesa_set_enable(ctx, GL_STENCIL_TEST, stencil->Enabled); + _mesa_ClearStencil(stencil->Clear); + _mesa_StencilFunc(stencil->Function, stencil->Ref, + stencil->ValueMask); + _mesa_StencilMask(stencil->WriteMask); + _mesa_StencilOp(stencil->FailFunc, stencil->ZFailFunc, + stencil->ZPassFunc); + } + break; + case GL_TRANSFORM_BIT: + { + GLuint i; + const struct gl_transform_attrib *xform; + xform = (const struct gl_transform_attrib *) attr->data; + _mesa_MatrixMode(xform->MatrixMode); + /* clip planes */ + MEMCPY(ctx->Transform.EyeUserPlane, xform->EyeUserPlane, + sizeof(xform->EyeUserPlane)); + MEMCPY(ctx->Transform._ClipUserPlane, xform->_ClipUserPlane, + sizeof(xform->EyeUserPlane)); + /* clip plane enable flags */ + for (i = 0; i < MAX_CLIP_PLANES; i++) { + _mesa_set_enable(ctx, GL_CLIP_PLANE0 + i, + xform->ClipEnabled[i]); + } + /* normalize/rescale */ + _mesa_set_enable(ctx, GL_NORMALIZE, ctx->Transform.Normalize); + _mesa_set_enable(ctx, GL_RESCALE_NORMAL_EXT, + ctx->Transform.RescaleNormals); + } + break; + case GL_TEXTURE_BIT: + /* Take care of texture object reference counters */ + { + const struct gl_texture_attrib *texture; + texture = (const struct gl_texture_attrib *) attr->data; + pop_texture_group(ctx, texture); + ctx->NewState |= _NEW_TEXTURE; + } + break; + case GL_VIEWPORT_BIT: + { + const struct gl_viewport_attrib *vp; + vp = (const struct gl_viewport_attrib *) attr->data; + _mesa_Viewport(vp->X, vp->Y, vp->Width, vp->Height); + _mesa_DepthRange(vp->Near, vp->Far); + } + break; + case GL_MULTISAMPLE_BIT_ARB: + { + const struct gl_multisample_attrib *ms; + ms = (const struct gl_multisample_attrib *) attr->data; + _mesa_SampleCoverageARB(ms->SampleCoverageValue, + ms->SampleCoverageInvert); + } + break; + + default: + _mesa_problem( ctx, "Bad attrib flag in PopAttrib"); + break; + } + + next = attr->next; + FREE( attr->data ); + FREE( attr ); + attr = next; + } +} + + +#define GL_CLIENT_PACK_BIT (1<<20) +#define GL_CLIENT_UNPACK_BIT (1<<21) + + +void +_mesa_PushClientAttrib(GLbitfield mask) +{ + struct gl_attrib_node *newnode; + struct gl_attrib_node *head; + + GET_CURRENT_CONTEXT(ctx); + ASSERT_OUTSIDE_BEGIN_END(ctx); + + if (ctx->ClientAttribStackDepth >= MAX_CLIENT_ATTRIB_STACK_DEPTH) { + _mesa_error( ctx, GL_STACK_OVERFLOW, "glPushClientAttrib" ); + return; + } + + /* Build linked list of attribute nodes which save all attribute */ + /* groups specified by the mask. */ + head = NULL; + + if (mask & GL_CLIENT_PIXEL_STORE_BIT) { + struct gl_pixelstore_attrib *attr; + /* packing attribs */ + attr = MALLOC_STRUCT( gl_pixelstore_attrib ); + MEMCPY( attr, &ctx->Pack, sizeof(struct gl_pixelstore_attrib) ); + newnode = new_attrib_node( GL_CLIENT_PACK_BIT ); + newnode->data = attr; + newnode->next = head; + head = newnode; + /* unpacking attribs */ + attr = MALLOC_STRUCT( gl_pixelstore_attrib ); + MEMCPY( attr, &ctx->Unpack, sizeof(struct gl_pixelstore_attrib) ); + newnode = new_attrib_node( GL_CLIENT_UNPACK_BIT ); + newnode->data = attr; + newnode->next = head; + head = newnode; + } + if (mask & GL_CLIENT_VERTEX_ARRAY_BIT) { + struct gl_array_attrib *attr; + attr = MALLOC_STRUCT( gl_array_attrib ); + MEMCPY( attr, &ctx->Array, sizeof(struct gl_array_attrib) ); + newnode = new_attrib_node( GL_CLIENT_VERTEX_ARRAY_BIT ); + newnode->data = attr; + newnode->next = head; + head = newnode; + } + + ctx->ClientAttribStack[ctx->ClientAttribStackDepth] = head; + ctx->ClientAttribStackDepth++; +} + + + + +void +_mesa_PopClientAttrib(void) +{ + struct gl_attrib_node *attr, *next; + + GET_CURRENT_CONTEXT(ctx); + ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx); + + if (ctx->ClientAttribStackDepth == 0) { + _mesa_error( ctx, GL_STACK_UNDERFLOW, "glPopClientAttrib" ); + return; + } + + ctx->ClientAttribStackDepth--; + attr = ctx->ClientAttribStack[ctx->ClientAttribStackDepth]; + + while (attr) { + switch (attr->kind) { + case GL_CLIENT_PACK_BIT: + MEMCPY( &ctx->Pack, attr->data, + sizeof(struct gl_pixelstore_attrib) ); + ctx->NewState = _NEW_PACKUNPACK; + break; + case GL_CLIENT_UNPACK_BIT: + MEMCPY( &ctx->Unpack, attr->data, + sizeof(struct gl_pixelstore_attrib) ); + ctx->NewState = _NEW_PACKUNPACK; + break; + case GL_CLIENT_VERTEX_ARRAY_BIT: + MEMCPY( &ctx->Array, attr->data, + sizeof(struct gl_array_attrib) ); + ctx->NewState = _NEW_ARRAY; + break; + default: + _mesa_problem( ctx, "Bad attrib flag in PopClientAttrib"); + break; + } + + next = attr->next; + FREE( attr->data ); + FREE( attr ); + attr = next; + } +} Index: dll/opengl/opengl32/mesa/attrib.h =================================================================== --- dll/opengl/opengl32/mesa/attrib.h (revision 0) +++ dll/opengl/opengl32/mesa/attrib.h (working copy) @@ -0,0 +1,48 @@ +/* $Id: attrib.h,v 1.5 2001/03/12 00:48:37 gareth Exp $ */ + +/* + * Mesa 3-D graphics library + * Version: 3.5 + * + * Copyright (C) 1999-2001 Brian Paul 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 + * BRIAN PAUL 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. + */ + + +#ifndef ATTRIB_H +#define ATTRIB_h + + +#include "mtypes.h" + + +extern void +_mesa_PushAttrib( GLbitfield mask ); + +extern void +_mesa_PopAttrib( void ); + +extern void +_mesa_PushClientAttrib( GLbitfield mask ); + +extern void +_mesa_PopClientAttrib( void ); + + +#endif Index: dll/opengl/opengl32/mesa/blend.c =================================================================== --- dll/opengl/opengl32/mesa/blend.c (revision 0) +++ dll/opengl/opengl32/mesa/blend.c (working copy) @@ -0,0 +1,466 @@ +/* $Id: blend.c,v 1.33 2001/06/18 17:26:08 brianp Exp $ */ + +/* + * Mesa 3-D graphics library + * Version: 3.5 + * + * Copyright (C) 1999-2001 Brian Paul 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 + * BRIAN PAUL 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. + */ + + +#ifdef PC_HEADER +#include "all.h" +#else +#include "glheader.h" +#include "blend.h" +#include "colormac.h" +#include "context.h" +#include "enums.h" +#include "macros.h" +#include "mtypes.h" +#endif + + +void +_mesa_BlendFunc( GLenum sfactor, GLenum dfactor ) +{ + + GET_CURRENT_CONTEXT(ctx); + ASSERT_OUTSIDE_BEGIN_END(ctx); + + if (MESA_VERBOSE & (VERBOSE_API|VERBOSE_TEXTURE)) + fprintf(stderr, "glBlendFunc %s %s\n", + _mesa_lookup_enum_by_nr(sfactor), + _mesa_lookup_enum_by_nr(dfactor)); + + switch (sfactor) { + case GL_SRC_COLOR: + case GL_ONE_MINUS_SRC_COLOR: + if (!ctx->Extensions.NV_blend_square) { + _mesa_error( ctx, GL_INVALID_ENUM, "glBlendFunc(sfactor)" ); + return; + } + /* fall-through */ + case GL_ZERO: + case GL_ONE: + case GL_DST_COLOR: + case GL_ONE_MINUS_DST_COLOR: + case GL_SRC_ALPHA: + case GL_ONE_MINUS_SRC_ALPHA: + case GL_DST_ALPHA: + case GL_ONE_MINUS_DST_ALPHA: + case GL_SRC_ALPHA_SATURATE: + case GL_CONSTANT_COLOR: + case GL_ONE_MINUS_CONSTANT_COLOR: + case GL_CONSTANT_ALPHA: + case GL_ONE_MINUS_CONSTANT_ALPHA: + break; + default: + _mesa_error( ctx, GL_INVALID_ENUM, "glBlendFunc(sfactor)" ); + return; + } + + switch (dfactor) { + case GL_DST_COLOR: + case GL_ONE_MINUS_DST_COLOR: + if (!ctx->Extensions.NV_blend_square) { + _mesa_error( ctx, GL_INVALID_ENUM, "glBlendFunc(dfactor)" ); + return; + } + /* fall-through */ + case GL_ZERO: + case GL_ONE: + case GL_SRC_COLOR: + case GL_ONE_MINUS_SRC_COLOR: + case GL_SRC_ALPHA: + case GL_ONE_MINUS_SRC_ALPHA: + case GL_DST_ALPHA: + case GL_ONE_MINUS_DST_ALPHA: + case GL_CONSTANT_COLOR: + case GL_ONE_MINUS_CONSTANT_COLOR: + case GL_CONSTANT_ALPHA: + case GL_ONE_MINUS_CONSTANT_ALPHA: + break; + default: + _mesa_error( ctx, GL_INVALID_ENUM, "glBlendFunc(dfactor)" ); + return; + } + + if (ctx->Color.BlendDstRGB == dfactor && + ctx->Color.BlendSrcRGB == sfactor && + ctx->Color.BlendDstA == dfactor && + ctx->Color.BlendSrcA == sfactor) + return; + + FLUSH_VERTICES(ctx, _NEW_COLOR); + ctx->Color.BlendDstRGB = ctx->Color.BlendDstA = dfactor; + ctx->Color.BlendSrcRGB = ctx->Color.BlendSrcA = sfactor; + + if (ctx->Driver.BlendFunc) + ctx->Driver.BlendFunc( ctx, sfactor, dfactor ); +} + + +/* GL_EXT_blend_func_separate */ +void +_mesa_BlendFuncSeparateEXT( GLenum sfactorRGB, GLenum dfactorRGB, + GLenum sfactorA, GLenum dfactorA ) +{ + GET_CURRENT_CONTEXT(ctx); + ASSERT_OUTSIDE_BEGIN_END(ctx); + + if (MESA_VERBOSE & (VERBOSE_API|VERBOSE_TEXTURE)) + fprintf(stderr, "glBlendFuncSeparate %s %s %s %s\n", + _mesa_lookup_enum_by_nr(sfactorRGB), + _mesa_lookup_enum_by_nr(dfactorRGB), + _mesa_lookup_enum_by_nr(sfactorA), + _mesa_lookup_enum_by_nr(dfactorA)); + + switch (sfactorRGB) { + case GL_SRC_COLOR: + case GL_ONE_MINUS_SRC_COLOR: + if (!ctx->Extensions.NV_blend_square) { + _mesa_error(ctx, GL_INVALID_ENUM, "glBlendFuncSeparate(sfactorRGB)"); + return; + } + /* fall-through */ + case GL_ZERO: + case GL_ONE: + case GL_DST_COLOR: + case GL_ONE_MINUS_DST_COLOR: + case GL_SRC_ALPHA: + case GL_ONE_MINUS_SRC_ALPHA: + case GL_DST_ALPHA: + case GL_ONE_MINUS_DST_ALPHA: + case GL_SRC_ALPHA_SATURATE: + case GL_CONSTANT_COLOR: + case GL_ONE_MINUS_CONSTANT_COLOR: + case GL_CONSTANT_ALPHA: + case GL_ONE_MINUS_CONSTANT_ALPHA: + break; + default: + _mesa_error(ctx, GL_INVALID_ENUM, "glBlendFuncSeparate(sfactorRGB)"); + return; + } + + switch (dfactorRGB) { + case GL_DST_COLOR: + case GL_ONE_MINUS_DST_COLOR: + if (!ctx->Extensions.NV_blend_square) { + _mesa_error(ctx, GL_INVALID_ENUM, "glBlendFuncSeparate(dfactorRGB)"); + return; + } + /* fall-through */ + case GL_ZERO: + case GL_ONE: + case GL_SRC_COLOR: + case GL_ONE_MINUS_SRC_COLOR: + case GL_SRC_ALPHA: + case GL_ONE_MINUS_SRC_ALPHA: + case GL_DST_ALPHA: + case GL_ONE_MINUS_DST_ALPHA: + case GL_CONSTANT_COLOR: + case GL_ONE_MINUS_CONSTANT_COLOR: + case GL_CONSTANT_ALPHA: + case GL_ONE_MINUS_CONSTANT_ALPHA: + break; + default: + _mesa_error(ctx, GL_INVALID_ENUM, "glBlendFuncSeparate(dfactorRGB)"); + return; + } + + switch (sfactorA) { + case GL_SRC_COLOR: + case GL_ONE_MINUS_SRC_COLOR: + if (!ctx->Extensions.NV_blend_square) { + _mesa_error(ctx, GL_INVALID_ENUM, "glBlendFuncSeparate(sfactorA)"); + return; + } + /* fall-through */ + case GL_ZERO: + case GL_ONE: + case GL_DST_COLOR: + case GL_ONE_MINUS_DST_COLOR: + case GL_SRC_ALPHA: + case GL_ONE_MINUS_SRC_ALPHA: + case GL_DST_ALPHA: + case GL_ONE_MINUS_DST_ALPHA: + case GL_SRC_ALPHA_SATURATE: + case GL_CONSTANT_COLOR: + case GL_ONE_MINUS_CONSTANT_COLOR: + case GL_CONSTANT_ALPHA: + case GL_ONE_MINUS_CONSTANT_ALPHA: + break; + default: + _mesa_error(ctx, GL_INVALID_ENUM, "glBlendFuncSeparate(sfactorA)"); + return; + } + + switch (dfactorA) { + case GL_DST_COLOR: + case GL_ONE_MINUS_DST_COLOR: + if (!ctx->Extensions.NV_blend_square) { + _mesa_error(ctx, GL_INVALID_ENUM, "glBlendFuncSeparate(dfactorA)"); + return; + } + /* fall-through */ + case GL_ZERO: + case GL_ONE: + case GL_SRC_COLOR: + case GL_ONE_MINUS_SRC_COLOR: + case GL_SRC_ALPHA: + case GL_ONE_MINUS_SRC_ALPHA: + case GL_DST_ALPHA: + case GL_ONE_MINUS_DST_ALPHA: + case GL_CONSTANT_COLOR: + case GL_ONE_MINUS_CONSTANT_COLOR: + case GL_CONSTANT_ALPHA: + case GL_ONE_MINUS_CONSTANT_ALPHA: + break; + default: + _mesa_error( ctx, GL_INVALID_ENUM, "glBlendFuncSeparate(dfactorA)" ); + return; + } + + if (ctx->Color.BlendSrcRGB == sfactorRGB && + ctx->Color.BlendDstRGB == dfactorRGB && + ctx->Color.BlendSrcA == sfactorA && + ctx->Color.BlendDstA == dfactorA) + return; + + FLUSH_VERTICES(ctx, _NEW_COLOR); + + ctx->Color.BlendSrcRGB = sfactorRGB; + ctx->Color.BlendDstRGB = dfactorRGB; + ctx->Color.BlendSrcA = sfactorA; + ctx->Color.BlendDstA = dfactorA; + + if (ctx->Driver.BlendFuncSeparate) { + (*ctx->Driver.BlendFuncSeparate)( ctx, sfactorRGB, dfactorRGB, + sfactorA, dfactorA ); + } +} + + + +/* This is really an extension function! */ +void +_mesa_BlendEquation( GLenum mode ) +{ + GET_CURRENT_CONTEXT(ctx); + ASSERT_OUTSIDE_BEGIN_END(ctx); + + if (MESA_VERBOSE & (VERBOSE_API|VERBOSE_TEXTURE)) + fprintf(stderr, "glBlendEquation %s\n", + _mesa_lookup_enum_by_nr(mode)); + + switch (mode) { + case GL_FUNC_ADD_EXT: + break; + case GL_MIN_EXT: + case GL_MAX_EXT: + if (!ctx->Extensions.EXT_blend_minmax && + !ctx->Extensions.ARB_imaging) { + _mesa_error(ctx, GL_INVALID_ENUM, "glBlendEquation"); + return; + } + break; + case GL_LOGIC_OP: + if (!ctx->Extensions.EXT_blend_logic_op) { + _mesa_error(ctx, GL_INVALID_ENUM, "glBlendEquation"); + return; + } + break; + case GL_FUNC_SUBTRACT_EXT: + case GL_FUNC_REVERSE_SUBTRACT_EXT: + if (!ctx->Extensions.EXT_blend_subtract && + !ctx->Extensions.ARB_imaging) { + _mesa_error(ctx, GL_INVALID_ENUM, "glBlendEquation"); + return; + } + break; + default: + _mesa_error( ctx, GL_INVALID_ENUM, "glBlendEquation" ); + return; + } + + if (ctx->Color.BlendEquation == mode) + return; + + FLUSH_VERTICES(ctx, _NEW_COLOR); + ctx->Color.BlendEquation = mode; + + /* This is needed to support 1.1's RGB logic ops AND + * 1.0's blending logicops. + */ + ctx->Color.ColorLogicOpEnabled = (mode==GL_LOGIC_OP && + ctx->Color.BlendEnabled); + + if (ctx->Driver.BlendEquation) + (*ctx->Driver.BlendEquation)( ctx, mode ); +} + + + +void +_mesa_BlendColor( GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha ) +{ + GLfloat tmp[4]; + GET_CURRENT_CONTEXT(ctx); + ASSERT_OUTSIDE_BEGIN_END(ctx); + + tmp[0] = CLAMP( red, 0.0, 1.0 ); + tmp[1] = CLAMP( green, 0.0, 1.0 ); + tmp[2] = CLAMP( blue, 0.0, 1.0 ); + tmp[3] = CLAMP( alpha, 0.0, 1.0 ); + + if (TEST_EQ_4V(tmp, ctx->Color.BlendColor)) + return; + + FLUSH_VERTICES(ctx, _NEW_COLOR); + COPY_4FV( ctx->Color.BlendColor, tmp ); + + if (ctx->Driver.BlendColor) + (*ctx->Driver.BlendColor)(ctx, tmp); +} + + +void +_mesa_AlphaFunc( GLenum func, GLclampf ref ) +{ + GET_CURRENT_CONTEXT(ctx); + GLchan cref; + ASSERT_OUTSIDE_BEGIN_END(ctx); + + switch (func) { + case GL_NEVER: + case GL_LESS: + case GL_EQUAL: + case GL_LEQUAL: + case GL_GREATER: + case GL_NOTEQUAL: + case GL_GEQUAL: + case GL_ALWAYS: + /* convert float alpha ref to GLchan type */ + UNCLAMPED_FLOAT_TO_CHAN(cref, ref); + + if (ctx->Color.AlphaFunc == func && ctx->Color.AlphaRef == cref) + return; + + FLUSH_VERTICES(ctx, _NEW_COLOR); + ctx->Color.AlphaFunc = func; + ctx->Color.AlphaRef = cref; + + if (ctx->Driver.AlphaFunc) + ctx->Driver.AlphaFunc(ctx, func, cref); + return; + + default: + _mesa_error( ctx, GL_INVALID_ENUM, "glAlphaFunc(func)" ); + return; + } +} + + +void +_mesa_LogicOp( GLenum opcode ) +{ + GET_CURRENT_CONTEXT(ctx); + ASSERT_OUTSIDE_BEGIN_END(ctx); + + switch (opcode) { + case GL_CLEAR: + case GL_SET: + case GL_COPY: + case GL_COPY_INVERTED: + case GL_NOOP: + case GL_INVERT: + case GL_AND: + case GL_NAND: + case GL_OR: + case GL_NOR: + case GL_XOR: + case GL_EQUIV: + case GL_AND_REVERSE: + case GL_AND_INVERTED: + case GL_OR_REVERSE: + case GL_OR_INVERTED: + break; + default: + _mesa_error( ctx, GL_INVALID_ENUM, "glLogicOp" ); + return; + } + + if (ctx->Color.LogicOp == opcode) + return; + + FLUSH_VERTICES(ctx, _NEW_COLOR); + ctx->Color.LogicOp = opcode; + + if (ctx->Driver.LogicOpcode) + ctx->Driver.LogicOpcode( ctx, opcode ); +} + + +void +_mesa_IndexMask( GLuint mask ) +{ + GET_CURRENT_CONTEXT(ctx); + ASSERT_OUTSIDE_BEGIN_END(ctx); + + if (ctx->Color.IndexMask == mask) + return; + + FLUSH_VERTICES(ctx, _NEW_COLOR); + ctx->Color.IndexMask = mask; + + if (ctx->Driver.IndexMask) + ctx->Driver.IndexMask( ctx, mask ); +} + + +void +_mesa_ColorMask( GLboolean red, GLboolean green, + GLboolean blue, GLboolean alpha ) +{ + GET_CURRENT_CONTEXT(ctx); + GLubyte tmp[4]; + ASSERT_OUTSIDE_BEGIN_END(ctx); + + if (MESA_VERBOSE & VERBOSE_API) + fprintf(stderr, "glColorMask %d %d %d %d\n", red, green, blue, alpha); + + /* Shouldn't have any information about channel depth in core mesa + * -- should probably store these as the native booleans: + */ + tmp[RCOMP] = red ? 0xff : 0x0; + tmp[GCOMP] = green ? 0xff : 0x0; + tmp[BCOMP] = blue ? 0xff : 0x0; + tmp[ACOMP] = alpha ? 0xff : 0x0; + + if (TEST_EQ_4UBV(tmp, ctx->Color.ColorMask)) + return; + + FLUSH_VERTICES(ctx, _NEW_COLOR); + COPY_4UBV(ctx->Color.ColorMask, tmp); + + if (ctx->Driver.ColorMask) + ctx->Driver.ColorMask( ctx, red, green, blue, alpha ); +} Index: dll/opengl/opengl32/mesa/blend.h =================================================================== --- dll/opengl/opengl32/mesa/blend.h (revision 0) +++ dll/opengl/opengl32/mesa/blend.h (working copy) @@ -0,0 +1,68 @@ +/* $Id: blend.h,v 1.9 2001/06/18 17:26:08 brianp Exp $ */ + +/* + * Mesa 3-D graphics library + * Version: 3.5 + * + * Copyright (C) 1999-2001 Brian Paul 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 + * BRIAN PAUL 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. + */ + + +#ifndef BLEND_H +#define BLEND_H + + +#include "mtypes.h" + + +extern void +_mesa_BlendFunc( GLenum sfactor, GLenum dfactor ); + + +extern void +_mesa_BlendFuncSeparateEXT( GLenum sfactorRGB, GLenum dfactorRGB, + GLenum sfactorA, GLenum dfactorA ); + + +extern void +_mesa_BlendEquation( GLenum mode ); + + +extern void +_mesa_BlendColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha); + + +extern void +_mesa_AlphaFunc( GLenum func, GLclampf ref ); + + +extern void +_mesa_LogicOp( GLenum opcode ); + + +extern void +_mesa_IndexMask( GLuint mask ); + +extern void +_mesa_ColorMask( GLboolean red, GLboolean green, + GLboolean blue, GLboolean alpha ); + + +#endif Index: dll/opengl/opengl32/mesa/buffers.c =================================================================== --- dll/opengl/opengl32/mesa/buffers.c (revision 0) +++ dll/opengl/opengl32/mesa/buffers.c (working copy) @@ -0,0 +1,423 @@ +/* $Id: buffers.c,v 1.30 2001/06/18 17:26:08 brianp Exp $ */ + +/* + * Mesa 3-D graphics library + * Version: 3.5 + * + * Copyright (C) 1999-2001 Brian Paul 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 + * BRIAN PAUL 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. + */ + + +#ifdef PC_HEADER +#include "all.h" +#else +#include "glheader.h" +#include "accum.h" +#include "buffers.h" +#include "colormac.h" +#include "context.h" +#include "depth.h" +#include "enums.h" +#include "macros.h" +#include "mem.h" +#include "stencil.h" +#include "state.h" +#include "mtypes.h" +#endif + + + +void +_mesa_ClearIndex( GLfloat c ) +{ + GET_CURRENT_CONTEXT(ctx); + ASSERT_OUTSIDE_BEGIN_END(ctx); + + if (ctx->Color.ClearIndex == (GLuint) c) + return; + + FLUSH_VERTICES(ctx, _NEW_COLOR); + ctx->Color.ClearIndex = (GLuint) c; + + if (!ctx->Visual.rgbMode && ctx->Driver.ClearIndex) { + /* it's OK to call glClearIndex in RGBA mode but it should be a NOP */ + (*ctx->Driver.ClearIndex)( ctx, ctx->Color.ClearIndex ); + } +} + + + +void +_mesa_ClearColor( GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha ) +{ + GLchan tmp[4]; + GET_CURRENT_CONTEXT(ctx); + ASSERT_OUTSIDE_BEGIN_END(ctx); + + UNCLAMPED_FLOAT_TO_CHAN(tmp[0], red); + UNCLAMPED_FLOAT_TO_CHAN(tmp[1], green); + UNCLAMPED_FLOAT_TO_CHAN(tmp[2], blue); + UNCLAMPED_FLOAT_TO_CHAN(tmp[3], alpha); + + if (TEST_EQ_4V(tmp, ctx->Color.ClearColor)) + return; + + FLUSH_VERTICES(ctx, _NEW_COLOR); + COPY_CHAN4(ctx->Color.ClearColor, tmp); + + if (ctx->Visual.rgbMode && ctx->Driver.ClearColor) { + /* it's OK to call glClearColor in CI mode but it should be a NOP */ + (*ctx->Driver.ClearColor)(ctx, ctx->Color.ClearColor); + } +} + + + +void +_mesa_Clear( GLbitfield mask ) +{ + GET_CURRENT_CONTEXT(ctx); + ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx); + + if (MESA_VERBOSE & VERBOSE_API) + fprintf(stderr, "glClear 0x%x\n", mask); + + if (ctx->NewState) { + _mesa_update_state( ctx ); /* update _Xmin, etc */ + } + + if (ctx->RenderMode==GL_RENDER) { + const GLint x = ctx->DrawBuffer->_Xmin; + const GLint y = ctx->DrawBuffer->_Ymin; + const GLint height = ctx->DrawBuffer->_Ymax - ctx->DrawBuffer->_Ymin; + const GLint width = ctx->DrawBuffer->_Xmax - ctx->DrawBuffer->_Xmin; + GLbitfield ddMask; + + /* don't clear depth buffer if depth writing disabled */ + if (!ctx->Depth.Mask) + CLEAR_BITS(mask, GL_DEPTH_BUFFER_BIT); + + /* Build bitmask to send to driver Clear function */ + ddMask = mask & (GL_DEPTH_BUFFER_BIT | + GL_STENCIL_BUFFER_BIT | + GL_ACCUM_BUFFER_BIT); + if (mask & GL_COLOR_BUFFER_BIT) { + ddMask |= ctx->Color.DrawDestMask; + } + + ASSERT(ctx->Driver.Clear); + ctx->Driver.Clear( ctx, ddMask, !ctx->Scissor.Enabled, + x, y, width, height ); + } +} + + +void +_mesa_DrawBuffer( GLenum mode ) +{ + GET_CURRENT_CONTEXT(ctx); + ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx); /* too complex... */ + + + if (MESA_VERBOSE & VERBOSE_API) + fprintf(stderr, "glDrawBuffer %s\n", _mesa_lookup_enum_by_nr(mode)); + + switch (mode) { + case GL_AUX0: + case GL_AUX1: + case GL_AUX2: + case GL_AUX3: + /* AUX buffers not implemented in Mesa at this time */ + _mesa_error( ctx, GL_INVALID_OPERATION, "glDrawBuffer" ); + return; + case GL_RIGHT: + if (!ctx->Visual.stereoMode) { + _mesa_error( ctx, GL_INVALID_OPERATION, "glDrawBuffer" ); + return;} + if (ctx->Visual.doubleBufferMode) + ctx->Color.DrawDestMask = FRONT_RIGHT_BIT | BACK_RIGHT_BIT; + else + ctx->Color.DrawDestMask = FRONT_RIGHT_BIT; + break; + case GL_FRONT_RIGHT: + if (!ctx->Visual.stereoMode) { + _mesa_error( ctx, GL_INVALID_OPERATION, "glDrawBuffer" ); + return; + } + ctx->Color.DrawDestMask = FRONT_RIGHT_BIT; + break; + case GL_BACK_RIGHT: + if (!ctx->Visual.stereoMode) { + _mesa_error( ctx, GL_INVALID_OPERATION, "glDrawBuffer" ); + return; + } + if (!ctx->Visual.doubleBufferMode) { + _mesa_error( ctx, GL_INVALID_OPERATION, "glDrawBuffer" ); + return; + } + ctx->Color.DrawDestMask = BACK_RIGHT_BIT; + break; + case GL_BACK_LEFT: + if (!ctx->Visual.doubleBufferMode) { + _mesa_error( ctx, GL_INVALID_OPERATION, "glDrawBuffer" ); + return; + } + ctx->Color.DrawDestMask = BACK_LEFT_BIT; + break; + case GL_FRONT_AND_BACK: + if (!ctx->Visual.doubleBufferMode) { + _mesa_error( ctx, GL_INVALID_OPERATION, "glDrawBuffer" ); + return; + } + if (ctx->Visual.stereoMode) + ctx->Color.DrawDestMask = FRONT_LEFT_BIT | BACK_LEFT_BIT + | FRONT_RIGHT_BIT | BACK_RIGHT_BIT; + else + ctx->Color.DrawDestMask = FRONT_LEFT_BIT | BACK_LEFT_BIT; + break; + case GL_BACK: + if (!ctx->Visual.doubleBufferMode) { + _mesa_error( ctx, GL_INVALID_OPERATION, "glDrawBuffer" ); + return; + } + if (ctx->Visual.stereoMode) + ctx->Color.DrawDestMask = BACK_LEFT_BIT | BACK_RIGHT_BIT; + else + ctx->Color.DrawDestMask = BACK_LEFT_BIT; + break; + case GL_LEFT: + /* never an error */ + if (ctx->Visual.doubleBufferMode) + ctx->Color.DrawDestMask = FRONT_LEFT_BIT | BACK_LEFT_BIT; + else + ctx->Color.DrawDestMask = FRONT_LEFT_BIT; + break; + case GL_FRONT_LEFT: + /* never an error */ + ctx->Color.DrawDestMask = FRONT_LEFT_BIT; + break; + case GL_FRONT: + /* never an error */ + if (ctx->Visual.stereoMode) + ctx->Color.DrawDestMask = FRONT_LEFT_BIT | FRONT_RIGHT_BIT; + else + ctx->Color.DrawDestMask = FRONT_LEFT_BIT; + break; + case GL_NONE: + /* never an error */ + ctx->Color.DrawDestMask = 0; + break; + default: + _mesa_error( ctx, GL_INVALID_ENUM, "glDrawBuffer" ); + return; + } + + /* + * Make the dest buffer mode more precise if possible + */ + if (mode == GL_LEFT && !ctx->Visual.doubleBufferMode) + ctx->Color.DriverDrawBuffer = GL_FRONT_LEFT; + else if (mode == GL_RIGHT && !ctx->Visual.doubleBufferMode) + ctx->Color.DriverDrawBuffer = GL_FRONT_RIGHT; + else if (mode == GL_FRONT && !ctx->Visual.stereoMode) + ctx->Color.DriverDrawBuffer = GL_FRONT_LEFT; + else if (mode == GL_BACK && !ctx->Visual.stereoMode) + ctx->Color.DriverDrawBuffer = GL_BACK_LEFT; + else + ctx->Color.DriverDrawBuffer = mode; + + /* + * Set current alpha buffer pointer + */ + if (ctx->DrawBuffer->UseSoftwareAlphaBuffers) { + if (ctx->Color.DriverDrawBuffer == GL_FRONT_LEFT) + ctx->DrawBuffer->Alpha = ctx->DrawBuffer->FrontLeftAlpha; + else if (ctx->Color.DriverDrawBuffer == GL_BACK_LEFT) + ctx->DrawBuffer->Alpha = ctx->DrawBuffer->BackLeftAlpha; + else if (ctx->Color.DriverDrawBuffer == GL_FRONT_RIGHT) + ctx->DrawBuffer->Alpha = ctx->DrawBuffer->FrontRightAlpha; + else if (ctx->Color.DriverDrawBuffer == GL_BACK_RIGHT) + ctx->DrawBuffer->Alpha = ctx->DrawBuffer->BackRightAlpha; + } + + /* + * If we get here there can't have been an error. + * Now see if device driver can implement the drawing to the target + * buffer(s). The driver may not be able to do GL_FRONT_AND_BACK mode + * for example. We'll take care of that in the core code by looping + * over the individual buffers. + */ + ASSERT(ctx->Driver.SetDrawBuffer); + if ( (*ctx->Driver.SetDrawBuffer)(ctx, ctx->Color.DriverDrawBuffer) ) { + /* All OK, the driver will do all buffer writes */ + ctx->Color.MultiDrawBuffer = GL_FALSE; + } + else { + /* We'll have to loop over the multiple draw buffer targets */ + ctx->Color.MultiDrawBuffer = GL_TRUE; + /* Set drawing buffer to front for now */ + (void) (*ctx->Driver.SetDrawBuffer)(ctx, GL_FRONT_LEFT); + } + + ctx->Color.DrawBuffer = mode; + ctx->NewState |= _NEW_COLOR; +} + + + +void +_mesa_ReadBuffer( GLenum mode ) +{ + GET_CURRENT_CONTEXT(ctx); + ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx); + + if (MESA_VERBOSE & VERBOSE_API) + fprintf(stderr, "glReadBuffer %s\n", _mesa_lookup_enum_by_nr(mode)); + + switch (mode) { + case GL_AUX0: + case GL_AUX1: + case GL_AUX2: + case GL_AUX3: + /* AUX buffers not implemented in Mesa at this time */ + _mesa_error( ctx, GL_INVALID_OPERATION, "glReadBuffer" ); + return; + case GL_LEFT: + case GL_FRONT: + case GL_FRONT_LEFT: + /* Front-Left buffer, always exists */ + ctx->Pixel.DriverReadBuffer = GL_FRONT_LEFT; + break; + case GL_BACK: + case GL_BACK_LEFT: + /* Back-Left buffer, requires double buffering */ + if (!ctx->Visual.doubleBufferMode) { + _mesa_error( ctx, GL_INVALID_OPERATION, "glReadBuffer" ); + return; + } + ctx->Pixel.DriverReadBuffer = GL_BACK_LEFT; + break; + case GL_FRONT_RIGHT: + case GL_RIGHT: + if (!ctx->Visual.stereoMode) { + _mesa_error( ctx, GL_INVALID_OPERATION, "glReadBuffer" ); + return; + } + ctx->Pixel.DriverReadBuffer = GL_FRONT_RIGHT; + break; + case GL_BACK_RIGHT: + if (!ctx->Visual.stereoMode || !ctx->Visual.doubleBufferMode) { + _mesa_error( ctx, GL_INVALID_OPERATION, "glReadBuffer" ); + return; + } + ctx->Pixel.DriverReadBuffer = GL_BACK_RIGHT; + break; + default: + _mesa_error( ctx, GL_INVALID_ENUM, "glReadBuffer" ); + return; + } + + ctx->Pixel.ReadBuffer = mode; + ctx->NewState |= _NEW_PIXEL; +} + + +/* + * GL_MESA_resize_buffers extension + */ +void +_mesa_ResizeBuffersMESA( void ) +{ + GLcontext *ctx = _mesa_get_current_context(); + GLuint buf_width, buf_height; + ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH( ctx ); + + + if (MESA_VERBOSE & VERBOSE_API) + fprintf(stderr, "glResizeBuffersMESA\n"); + + /* ask device driver for size of output buffer */ + (*ctx->Driver.GetBufferSize)( ctx, &buf_width, &buf_height ); + + /* see if size of device driver's color buffer (window) has changed */ + if (ctx->DrawBuffer->Width == (GLint) buf_width && + ctx->DrawBuffer->Height == (GLint) buf_height) + return; + + ctx->NewState |= _NEW_BUFFERS; /* to update scissor / window bounds */ + + /* save buffer size */ + ctx->DrawBuffer->Width = buf_width; + ctx->DrawBuffer->Height = buf_height; + + ctx->Driver.ResizeBuffersMESA( ctx ); +} + + +void +_mesa_Scissor( GLint x, GLint y, GLsizei width, GLsizei height ) +{ + GET_CURRENT_CONTEXT(ctx); + ASSERT_OUTSIDE_BEGIN_END(ctx); + + if (width < 0 || height < 0) { + _mesa_error( ctx, GL_INVALID_VALUE, "glScissor" ); + return; + } + + if (MESA_VERBOSE & VERBOSE_API) + fprintf(stderr, "glScissor %d %d %d %d\n", x, y, width, height); + + if (x == ctx->Scissor.X && + y == ctx->Scissor.Y && + width == ctx->Scissor.Width && + height == ctx->Scissor.Height) + return; + + FLUSH_VERTICES(ctx, _NEW_SCISSOR); + ctx->Scissor.X = x; + ctx->Scissor.Y = y; + ctx->Scissor.Width = width; + ctx->Scissor.Height = height; + + if (ctx->Driver.Scissor) + ctx->Driver.Scissor( ctx, x, y, width, height ); +} + + +/* + * XXX move somewhere else someday? + */ +void +_mesa_SampleCoverageARB(GLclampf value, GLboolean invert) +{ + GLcontext *ctx = _mesa_get_current_context(); + + if (!ctx->Extensions.ARB_multisample) { + _mesa_error(ctx, GL_INVALID_OPERATION, "glSampleCoverageARB"); + return; + } + + ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH( ctx ); + ctx->Multisample.SampleCoverageValue = CLAMP(value, 0.0, 1.0); + ctx->Multisample.SampleCoverageInvert = invert; + ctx->NewState |= _NEW_MULTISAMPLE; +} + Index: dll/opengl/opengl32/mesa/buffers.h =================================================================== --- dll/opengl/opengl32/mesa/buffers.h (revision 0) +++ dll/opengl/opengl32/mesa/buffers.h (working copy) @@ -0,0 +1,61 @@ +/* $Id: buffers.h,v 1.5 2001/06/18 17:26:08 brianp Exp $ */ + +/* + * Mesa 3-D graphics library + * Version: 3.5 + * + * Copyright (C) 1999-2001 Brian Paul 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 + * BRIAN PAUL 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. + */ + + +#ifndef BUFFERS_H +#define BUFFERS_H + + +#include "mtypes.h" + + +extern void +_mesa_ClearIndex( GLfloat c ); + +extern void +_mesa_ClearColor( GLclampf red, GLclampf green, + GLclampf blue, GLclampf alpha ); + +extern void +_mesa_Clear( GLbitfield mask ); + +extern void +_mesa_DrawBuffer( GLenum mode ); + +extern void +_mesa_ReadBuffer( GLenum mode ); + +extern void +_mesa_ResizeBuffersMESA( void ); + +extern void +_mesa_Scissor( GLint x, GLint y, GLsizei width, GLsizei height ); + +extern void +_mesa_SampleCoverageARB(GLclampf value, GLboolean invert); + + +#endif Index: dll/opengl/opengl32/mesa/clip.c =================================================================== --- dll/opengl/opengl32/mesa/clip.c (revision 0) +++ dll/opengl/opengl32/mesa/clip.c (working copy) @@ -0,0 +1,126 @@ +/* $Id: clip.c,v 1.22 2001/03/12 00:48:37 gareth Exp $ */ + +/* + * Mesa 3-D graphics library + * Version: 3.5 + * + * Copyright (C) 1999-2001 Brian Paul 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 + * BRIAN PAUL 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. + */ + + +#ifdef PC_HEADER +#include "all.h" +#else +#include "glheader.h" +#include "clip.h" +#include "context.h" +#include "macros.h" +#include "mmath.h" +#include "mtypes.h" + +#include "math/m_xform.h" +#include "math/m_matrix.h" +#endif + + + + + + +/**********************************************************************/ +/* Get/Set User clip-planes. */ +/**********************************************************************/ + + + +void +_mesa_ClipPlane( GLenum plane, const GLdouble *eq ) +{ + GET_CURRENT_CONTEXT(ctx); + GLint p; + GLfloat equation[4]; + ASSERT_OUTSIDE_BEGIN_END(ctx); + + p = (GLint) plane - (GLint) GL_CLIP_PLANE0; + if (p < 0 || p >= (GLint) ctx->Const.MaxClipPlanes) { + _mesa_error( ctx, GL_INVALID_ENUM, "glClipPlane" ); + return; + } + + equation[0] = eq[0]; + equation[1] = eq[1]; + equation[2] = eq[2]; + equation[3] = eq[3]; + + /* + * The equation is transformed by the transpose of the inverse of the + * current modelview matrix and stored in the resulting eye coordinates. + * + * KW: Eqn is then transformed to the current clip space, where user + * clipping now takes place. The clip-space equations are recalculated + * whenever the projection matrix changes. + */ + if (ctx->ModelView.flags & MAT_DIRTY) + _math_matrix_analyse( &ctx->ModelView ); + + _mesa_transform_vector( equation, equation, ctx->ModelView.inv ); + + if (TEST_EQ_4V(ctx->Transform.EyeUserPlane[p], equation)) + return; + + FLUSH_VERTICES(ctx, _NEW_TRANSFORM); + COPY_4FV(ctx->Transform.EyeUserPlane[p], equation); + + /* Update derived state. This state also depends on the projection + * matrix, and is recalculated on changes to the projection matrix by + * code in _mesa_update_state(). + */ + if (ctx->Transform.ClipEnabled[p]) { + if (ctx->ProjectionMatrix.flags & MAT_DIRTY) + _math_matrix_analyse( &ctx->ProjectionMatrix ); + + _mesa_transform_vector( ctx->Transform._ClipUserPlane[p], + ctx->Transform.EyeUserPlane[p], + ctx->ProjectionMatrix.inv ); + } + + if (ctx->Driver.ClipPlane) + ctx->Driver.ClipPlane( ctx, plane, equation ); +} + + +void +_mesa_GetClipPlane( GLenum plane, GLdouble *equation ) +{ + GET_CURRENT_CONTEXT(ctx); + GLint p; + ASSERT_OUTSIDE_BEGIN_END(ctx); + + p = (GLint) (plane - GL_CLIP_PLANE0); + if (p < 0 || p >= (GLint) ctx->Const.MaxClipPlanes) { + _mesa_error( ctx, GL_INVALID_ENUM, "glGetClipPlane" ); + return; + } + + equation[0] = (GLdouble) ctx->Transform.EyeUserPlane[p][0]; + equation[1] = (GLdouble) ctx->Transform.EyeUserPlane[p][1]; + equation[2] = (GLdouble) ctx->Transform.EyeUserPlane[p][2]; + equation[3] = (GLdouble) ctx->Transform.EyeUserPlane[p][3]; +} Index: dll/opengl/opengl32/mesa/clip.h =================================================================== --- dll/opengl/opengl32/mesa/clip.h (revision 0) +++ dll/opengl/opengl32/mesa/clip.h (working copy) @@ -0,0 +1,40 @@ +/* $Id: clip.h,v 1.6 2001/03/12 00:48:37 gareth Exp $ */ + +/* + * Mesa 3-D graphics library + * Version: 3.5 + * + * Copyright (C) 1999-2001 Brian Paul 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 + * BRIAN PAUL 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. + */ + + + + + +#ifndef CLIP_H +#define CLIP_H + +#include "mtypes.h" + +extern void _mesa_ClipPlane( GLenum plane, const GLdouble *equation ); + +extern void _mesa_GetClipPlane( GLenum plane, GLdouble *equation ); + +#endif Index: dll/opengl/opengl32/mesa/CMakeLists.txt =================================================================== --- dll/opengl/opengl32/mesa/CMakeLists.txt (revision 0) +++ dll/opengl/opengl32/mesa/CMakeLists.txt (working copy) @@ -0,0 +1,132 @@ +add_definitions( + -DUSE_MGL_NAMESPACE + -D_DLL + -D__USE_CRTIMP +) + +list(APPEND SOURCE + accum.c + api_arrayelt.c + api_eval.c + api_loopback.c + api_noop.c + api_validate.c + attrib.c + blend.c + buffers.c + clip.c + colortab.c + config.c + context.c + convolve.c + debug.c + depth.c + dispatch.c + dlist.c + drawpix.c + enable.c + enums.c + eval.c + extensions.c + feedback.c + fog.c + get.c + glapi.c + # glthread.c # We provide our own functions + hash.c + highpc.c + hint.c + histogram.c + image.c + imports.c + light.c + lines.c + lowpc.c + matrix.c + mem.c + mmath.c + pixel.c + points.c + polygon.c + rastpos.c + state.c + stencil.c + texformat.c + teximage.c + texobj.c + texstate.c + texstore.c + texutil.c + varray.c + vtxfmt.c + array_cache/ac_context.c + array_cache/ac_import.c + math/m_debug_clip.c + math/m_debug_norm.c + math/m_debug_vertex.c + math/m_debug_xform.c + math/m_eval.c + math/m_matrix.c + math/m_translate.c + math/m_vector.c + math/m_vertices.c + math/m_xform.c + swrast/s_aaline.c + swrast/s_aatriangle.c + swrast/s_accum.c + swrast/s_alpha.c + swrast/s_alphabuf.c + swrast/s_bitmap.c + swrast/s_blend.c + swrast/s_buffers.c + swrast/s_context.c + swrast/s_copypix.c + swrast/s_depth.c + swrast/s_drawpix.c + swrast/s_feedback.c + swrast/s_fog.c + swrast/s_histogram.c + swrast/s_imaging.c + swrast/s_lines.c + swrast/s_logic.c + swrast/s_masking.c + swrast/s_pb.c + swrast/s_pixeltex.c + swrast/s_points.c + swrast/s_readpix.c + swrast/s_scissor.c + swrast/s_span.c + swrast/s_stencil.c + swrast/s_texstore.c + swrast/s_texture.c + swrast/s_triangle.c + swrast/s_zoom.c + swrast_setup/ss_context.c + swrast_setup/ss_interp.c + swrast_setup/ss_triangle.c + swrast_setup/ss_vb.c + tnl/t_array_api.c + tnl/t_array_import.c + tnl/t_context.c + tnl/t_eval_api.c + tnl/t_imm_alloc.c + tnl/t_imm_api.c + tnl/t_imm_debug.c + tnl/t_imm_dlist.c + tnl/t_imm_elt.c + tnl/t_imm_eval.c + tnl/t_imm_exec.c + tnl/t_imm_fixup.c + tnl/t_pipeline.c + tnl/t_vb_fog.c + tnl/t_vb_light.c + tnl/t_vb_normals.c + tnl/t_vb_points.c + tnl/t_vb_render.c + tnl/t_vb_texgen.c + tnl/t_vb_texmat.c + tnl/t_vb_vertex.c + ../sw_mesa.c +) + +add_library(mesa STATIC EXCLUDE_FROM_ALL ${SOURCE}) Index: dll/opengl/opengl32/mesa/colormac.h =================================================================== --- dll/opengl/opengl32/mesa/colormac.h (revision 0) +++ dll/opengl/opengl32/mesa/colormac.h (working copy) @@ -0,0 +1,138 @@ +/* $Id: colormac.h,v 1.9 2001/03/11 18:49:11 gareth Exp $ */ + +/* + * Mesa 3-D graphics library + * Version: 3.5 + * + * Copyright (C) 1999-2001 Brian Paul 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 + * BRIAN PAUL 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. + */ + + + +/* + * Color-related macros + */ + +#ifndef COLORMAC_H +#define COLORMAC_H + + +#include "glheader.h" +#include "config.h" +#include "macros.h" +#include "mmath.h" +/* Do not reference mtypes.h from this file. + */ + + +#if CHAN_BITS == 8 + +#define BYTE_TO_CHAN(b) ((b) < 0 ? 0 : (GLchan) (b)) +#define UBYTE_TO_CHAN(b) (b) +#define SHORT_TO_CHAN(s) ((s) < 0 ? 0 : (GLchan) ((s) >> 7)) +#define USHORT_TO_CHAN(s) ((GLchan) ((s) >> 8)) +#define INT_TO_CHAN(i) ((i) < 0 ? 0 : (GLchan) ((i) >> 23)) +#define UINT_TO_CHAN(i) ((GLchan) ((i) >> 24)) + +#define CHAN_TO_UBYTE(c) (c) +#define CHAN_TO_FLOAT(c) UBYTE_TO_FLOAT(c) + +#define CLAMPED_FLOAT_TO_CHAN(c, f) CLAMPED_FLOAT_TO_UBYTE(c, f) +#define UNCLAMPED_FLOAT_TO_CHAN(c, f) UNCLAMPED_FLOAT_TO_UBYTE(c, f) + +#define COPY_CHAN4(DST, SRC) COPY_4UBV(DST, SRC) + +#define CHAN_PRODUCT(a, b) ((GLubyte) (((GLint)(a) * ((GLint)(b) + 1)) >> 8)) + + +#elif CHAN_BITS == 16 + +#define BYTE_TO_CHAN(b) ((b) < 0 ? 0 : (((GLchan) (b)) * 516)) +#define UBYTE_TO_CHAN(b) ((((GLchan) (b)) << 8) | ((GLchan) (b))) +#define SHORT_TO_CHAN(s) ((s) < 0 ? 0 : (GLchan) (s)) +#define USHORT_TO_CHAN(s) (s) +#define INT_TO_CHAN(i) ((i) < 0 ? 0 : (GLchan) ((i) >> 15)) +#define UINT_TO_CHAN(i) ((GLchan) ((i) >> 16)) + +#define CHAN_TO_UBYTE(c) ((c) >> 8) +#define CHAN_TO_FLOAT(c) ((GLfloat) ((c) * (1.0 / CHAN_MAXF))) + +#define CLAMPED_FLOAT_TO_CHAN(c, f) \ + c = ((GLchan) IROUND((f) * CHAN_MAXF)) +#define UNCLAMPED_FLOAT_TO_CHAN(c, f) \ + c = ( (GLchan) IROUND( CLAMP(f, 0.0, 1.0) * CHAN_MAXF) ) + +#define COPY_CHAN4(DST, SRC) COPY_4V(DST, SRC) + +#define CHAN_PRODUCT(a, b) ((GLchan) ((((GLint) (a)) * ((GLint) (b))) / 65535)) + + +#elif CHAN_BITS == 32 + +/* XXX floating-point color channels not fully thought-out */ +#define BYTE_TO_CHAN(b) ((GLfloat) ((b) * (1.0F / 127.0F))) +#define UBYTE_TO_CHAN(b) ((GLfloat) ((b) * (1.0F / 255.0F))) +#define SHORT_TO_CHAN(s) ((GLfloat) ((s) * (1.0F / 32767.0F))) +#define USHORT_TO_CHAN(s) ((GLfloat) ((s) * (1.0F / 65535.0F))) +#define INT_TO_CHAN(i) ((GLfloat) ((i) * (1.0F / 2147483647.0F))) +#define UINT_TO_CHAN(i) ((GLfloat) ((i) * (1.0F / 4294967295.0F))) + +#define CHAN_TO_UBYTE(c) FLOAT_TO_UBYTE(c) +#define CHAN_TO_FLOAT(c) (c) + +#define CLAMPED_FLOAT_TO_CHAN(c, f) c = (f) +#define UNCLAMPED_FLOAT_TO_CHAN(c, f) c = (f) + +#define COPY_CHAN4(DST, SRC) COPY_4V(DST, SRC) + +#define CHAN_PRODUCT(a, b) ((a) * (b)) + +#else + +#error unexpected CHAN_BITS size + +#endif + + + +/* + * Convert 3 channels at once. + */ +#define UNCLAMPED_FLOAT_TO_RGB_CHAN(dst, f) \ +do { \ + UNCLAMPED_FLOAT_TO_CHAN(dst[0], f[0]); \ + UNCLAMPED_FLOAT_TO_CHAN(dst[1], f[1]); \ + UNCLAMPED_FLOAT_TO_CHAN(dst[2], f[2]); \ +} while (0) + + +/* + * Convert 4 channels at once. + */ +#define UNCLAMPED_FLOAT_TO_RGBA_CHAN(dst, f) \ +do { \ + UNCLAMPED_FLOAT_TO_CHAN(dst[0], f[0]); \ + UNCLAMPED_FLOAT_TO_CHAN(dst[1], f[1]); \ + UNCLAMPED_FLOAT_TO_CHAN(dst[2], f[2]); \ + UNCLAMPED_FLOAT_TO_CHAN(dst[3], f[3]); \ +} while (0) + + +#endif /* COLORMAC_H */ Index: dll/opengl/opengl32/mesa/colortab.c =================================================================== --- dll/opengl/opengl32/mesa/colortab.c (revision 0) +++ dll/opengl/opengl32/mesa/colortab.c (working copy) @@ -0,0 +1,1170 @@ +/* $Id: colortab.c,v 1.40 2001/04/20 19:21:41 brianp Exp $ */ + +/* + * Mesa 3-D graphics library + * Version: 3.5 + * + * Copyright (C) 1999-2001 Brian Paul 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 + * BRIAN PAUL 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. + */ + + +#ifdef PC_HEADER +#include "all.h" +#else +#include "glheader.h" +#include "colortab.h" +#include "context.h" +#include "image.h" +#include "macros.h" +#include "mem.h" +#include "mmath.h" +#include "state.h" +#include "swrast/s_span.h" /* XXX SWRAST hack */ +#endif + + + +/* + * Given an internalFormat token passed to glColorTable, + * return the corresponding base format. + * Return -1 if invalid token. + */ +static GLint +base_colortab_format( GLenum format ) +{ + switch (format) { + case GL_ALPHA: + case GL_ALPHA4: + case GL_ALPHA8: + case GL_ALPHA12: + case GL_ALPHA16: + return GL_ALPHA; + case GL_LUMINANCE: + case GL_LUMINANCE4: + case GL_LUMINANCE8: + case GL_LUMINANCE12: + case GL_LUMINANCE16: + return GL_LUMINANCE; + case GL_LUMINANCE_ALPHA: + case GL_LUMINANCE4_ALPHA4: + case GL_LUMINANCE6_ALPHA2: + case GL_LUMINANCE8_ALPHA8: + case GL_LUMINANCE12_ALPHA4: + case GL_LUMINANCE12_ALPHA12: + case GL_LUMINANCE16_ALPHA16: + return GL_LUMINANCE_ALPHA; + case GL_INTENSITY: + case GL_INTENSITY4: + case GL_INTENSITY8: + case GL_INTENSITY12: + case GL_INTENSITY16: + return GL_INTENSITY; + case GL_RGB: + case GL_R3_G3_B2: + case GL_RGB4: + case GL_RGB5: + case GL_RGB8: + case GL_RGB10: + case GL_RGB12: + case GL_RGB16: + return GL_RGB; + case GL_RGBA: + case GL_RGBA2: + case GL_RGBA4: + case GL_RGB5_A1: + case GL_RGBA8: + case GL_RGB10_A2: + case GL_RGBA12: + case GL_RGBA16: + return GL_RGBA; + default: + return -1; /* error */ + } +} + + +void +_mesa_init_colortable( struct gl_color_table *p ) +{ + p->FloatTable = GL_FALSE; + p->Table = NULL; + p->Size = 0; + p->IntFormat = GL_RGBA; +} + + + +void +_mesa_free_colortable_data( struct gl_color_table *p ) +{ + if (p->Table) { + FREE(p->Table); + p->Table = NULL; + } +} + + +/* + * Examine table's format and set the component sizes accordingly. + */ +static void +set_component_sizes( struct gl_color_table *table ) +{ + /* XXX what about GLfloat tables? */ + switch (table->Format) { + case GL_ALPHA: + table->RedSize = 0; + table->GreenSize = 0; + table->BlueSize = 0; + table->AlphaSize = CHAN_BITS; + table->IntensitySize = 0; + table->LuminanceSize = 0; + break; + case GL_LUMINANCE: + table->RedSize = 0; + table->GreenSize = 0; + table->BlueSize = 0; + table->AlphaSize = 0; + table->IntensitySize = 0; + table->LuminanceSize = CHAN_BITS; + break; + case GL_LUMINANCE_ALPHA: + table->RedSize = 0; + table->GreenSize = 0; + table->BlueSize = 0; + table->AlphaSize = CHAN_BITS; + table->IntensitySize = 0; + table->LuminanceSize = CHAN_BITS; + break; + case GL_INTENSITY: + table->RedSize = 0; + table->GreenSize = 0; + table->BlueSize = 0; + table->AlphaSize = 0; + table->IntensitySize = CHAN_BITS; + table->LuminanceSize = 0; + break; + case GL_RGB: + table->RedSize = CHAN_BITS; + table->GreenSize = CHAN_BITS; + table->BlueSize = CHAN_BITS; + table->AlphaSize = 0; + table->IntensitySize = 0; + table->LuminanceSize = 0; + break; + case GL_RGBA: + table->RedSize = CHAN_BITS; + table->GreenSize = CHAN_BITS; + table->BlueSize = CHAN_BITS; + table->AlphaSize = CHAN_BITS; + table->IntensitySize = 0; + table->LuminanceSize = 0; + break; + default: + _mesa_problem(NULL, "unexpected format in set_component_sizes"); + } +} + + + +void +_mesa_ColorTable( GLenum target, GLenum internalFormat, + GLsizei width, GLenum format, GLenum type, + const GLvoid *data ) +{ + GET_CURRENT_CONTEXT(ctx); + struct gl_texture_unit *texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit]; + struct gl_texture_object *texObj = NULL; + struct gl_color_table *table = NULL; + GLboolean proxy = GL_FALSE; + GLint baseFormat; + GLfloat rScale = 1.0, gScale = 1.0, bScale = 1.0, aScale = 1.0; + GLfloat rBias = 0.0, gBias = 0.0, bBias = 0.0, aBias = 0.0; + GLboolean floatTable = GL_FALSE; + GLint comps; + ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx); /* too complex */ + + switch (target) { + case GL_TEXTURE_1D: + texObj = texUnit->Current1D; + table = &texObj->Palette; + break; + case GL_TEXTURE_2D: + texObj = texUnit->Current2D; + table = &texObj->Palette; + break; + case GL_TEXTURE_3D: + texObj = texUnit->Current3D; + table = &texObj->Palette; + break; + case GL_PROXY_TEXTURE_1D: + texObj = ctx->Texture.Proxy1D; + table = &texObj->Palette; + proxy = GL_TRUE; + break; + case GL_PROXY_TEXTURE_2D: + texObj = ctx->Texture.Proxy2D; + table = &texObj->Palette; + proxy = GL_TRUE; + break; + case GL_PROXY_TEXTURE_3D: + texObj = ctx->Texture.Proxy3D; + table = &texObj->Palette; + proxy = GL_TRUE; + break; + case GL_SHARED_TEXTURE_PALETTE_EXT: + table = &ctx->Texture.Palette; + break; + case GL_COLOR_TABLE: + table = &ctx->ColorTable; + floatTable = GL_TRUE; + rScale = ctx->Pixel.ColorTableScale[0]; + gScale = ctx->Pixel.ColorTableScale[1]; + bScale = ctx->Pixel.ColorTableScale[2]; + aScale = ctx->Pixel.ColorTableScale[3]; + rBias = ctx->Pixel.ColorTableBias[0]; + gBias = ctx->Pixel.ColorTableBias[1]; + bBias = ctx->Pixel.ColorTableBias[2]; + aBias = ctx->Pixel.ColorTableBias[3]; + break; + case GL_PROXY_COLOR_TABLE: + table = &ctx->ProxyColorTable; + proxy = GL_TRUE; + break; + case GL_POST_CONVOLUTION_COLOR_TABLE: + table = &ctx->PostConvolutionColorTable; + floatTable = GL_TRUE; + rScale = ctx->Pixel.PCCTscale[0]; + gScale = ctx->Pixel.PCCTscale[1]; + bScale = ctx->Pixel.PCCTscale[2]; + aScale = ctx->Pixel.PCCTscale[3]; + rBias = ctx->Pixel.PCCTbias[0]; + gBias = ctx->Pixel.PCCTbias[1]; + bBias = ctx->Pixel.PCCTbias[2]; + aBias = ctx->Pixel.PCCTbias[3]; + break; + case GL_PROXY_POST_CONVOLUTION_COLOR_TABLE: + table = &ctx->ProxyPostConvolutionColorTable; + proxy = GL_TRUE; + break; + case GL_POST_COLOR_MATRIX_COLOR_TABLE: + table = &ctx->PostColorMatrixColorTable; + floatTable = GL_TRUE; + rScale = ctx->Pixel.PCMCTscale[0]; + gScale = ctx->Pixel.PCMCTscale[1]; + bScale = ctx->Pixel.PCMCTscale[2]; + aScale = ctx->Pixel.PCMCTscale[3]; + rBias = ctx->Pixel.PCMCTbias[0]; + gBias = ctx->Pixel.PCMCTbias[1]; + bBias = ctx->Pixel.PCMCTbias[2]; + aBias = ctx->Pixel.PCMCTbias[3]; + break; + case GL_PROXY_POST_COLOR_MATRIX_COLOR_TABLE: + table = &ctx->ProxyPostColorMatrixColorTable; + proxy = GL_TRUE; + break; + default: + _mesa_error(ctx, GL_INVALID_ENUM, "glColorTable(target)"); + return; + } + + assert(table); + + if (!_mesa_is_legal_format_and_type(format, type) || + format == GL_INTENSITY) { + _mesa_error(ctx, GL_INVALID_OPERATION, "glColorTable(format or type)"); + return; + } + + baseFormat = base_colortab_format(internalFormat); + if (baseFormat < 0 || baseFormat == GL_COLOR_INDEX) { + _mesa_error(ctx, GL_INVALID_ENUM, "glColorTable(internalFormat)"); + return; + } + + if (width < 0 || (width != 0 && _mesa_bitcount(width) != 1)) { + /* error */ + if (proxy) { + table->Size = 0; + table->IntFormat = (GLenum) 0; + table->Format = (GLenum) 0; + } + else { + char msg[100]; + sprintf(msg, "glColorTable(width=%d)", width); + _mesa_error(ctx, GL_INVALID_VALUE, msg); + } + return; + } + + if (width > (GLsizei) ctx->Const.MaxColorTableSize) { + if (proxy) { + table->Size = 0; + table->IntFormat = (GLenum) 0; + table->Format = (GLenum) 0; + } + else { + _mesa_error(ctx, GL_TABLE_TOO_LARGE, "glColorTable(width)"); + } + return; + } + + table->Size = width; + table->IntFormat = internalFormat; + table->Format = (GLenum) baseFormat; + set_component_sizes(table); + + comps = _mesa_components_in_format(table->Format); + assert(comps > 0); /* error should have been caught sooner */ + + if (!proxy) { + /* free old table, if any */ + if (table->Table) { + FREE(table->Table); + table->Table = NULL; + } + if (width > 0) { + if (floatTable) { + GLfloat tempTab[MAX_COLOR_TABLE_SIZE * 4]; + GLfloat *tableF; + GLint i; + + _mesa_unpack_float_color_span(ctx, width, table->Format, + tempTab, /* dest */ + format, type, data, &ctx->Unpack, + 0, GL_FALSE); + + table->FloatTable = GL_TRUE; + table->Table = MALLOC(comps * width * sizeof(GLfloat)); + if (!table->Table) { + _mesa_error(ctx, GL_OUT_OF_MEMORY, "glColorTable"); + return; + } + + tableF = (GLfloat *) table->Table; + + switch (table->Format) { + case GL_INTENSITY: + for (i = 0; i < width; i++) { + tableF[i] = CLAMP(tempTab[i] * rScale + rBias, 0.0F, 1.0F); + } + break; + case GL_LUMINANCE: + for (i = 0; i < width; i++) { + tableF[i] = CLAMP(tempTab[i] * rScale + rBias, 0.0F, 1.0F); + } + break; + case GL_ALPHA: + for (i = 0; i < width; i++) { + tableF[i] = CLAMP(tempTab[i] * aScale + aBias, 0.0F, 1.0F); + } + break; + case GL_LUMINANCE_ALPHA: + for (i = 0; i < width; i++) { + tableF[i*2+0] = CLAMP(tempTab[i*2+0] * rScale + rBias, 0.0F, 1.0F); + tableF[i*2+1] = CLAMP(tempTab[i*2+1] * aScale + aBias, 0.0F, 1.0F); + } + break; + case GL_RGB: + for (i = 0; i < width; i++) { + tableF[i*3+0] = CLAMP(tempTab[i*3+0] * rScale + rBias, 0.0F, 1.0F); + tableF[i*3+1] = CLAMP(tempTab[i*3+1] * gScale + gBias, 0.0F, 1.0F); + tableF[i*3+2] = CLAMP(tempTab[i*3+2] * bScale + bBias, 0.0F, 1.0F); + } + break; + case GL_RGBA: + for (i = 0; i < width; i++) { + tableF[i*4+0] = CLAMP(tempTab[i*4+0] * rScale + rBias, 0.0F, 1.0F); + tableF[i*4+1] = CLAMP(tempTab[i*4+1] * gScale + gBias, 0.0F, 1.0F); + tableF[i*4+2] = CLAMP(tempTab[i*4+2] * bScale + bBias, 0.0F, 1.0F); + tableF[i*4+3] = CLAMP(tempTab[i*4+3] * aScale + aBias, 0.0F, 1.0F); + } + break; + default: + _mesa_problem(ctx, "Bad format in _mesa_ColorTable"); + return; + } + } + else { + /* store GLchan table */ + table->FloatTable = GL_FALSE; + table->Table = MALLOC(comps * width * sizeof(GLchan)); + if (!table->Table) { + _mesa_error(ctx, GL_OUT_OF_MEMORY, "glColorTable"); + return; + } + _mesa_unpack_chan_color_span(ctx, width, table->Format, + (GLchan *) table->Table, /* dest */ + format, type, data, + &ctx->Unpack, 0); + } /* floatTable */ + } /* width > 0 */ + } /* proxy */ + + if (texObj || target == GL_SHARED_TEXTURE_PALETTE_EXT) { + /* texture object palette, texObj==NULL means the shared palette */ + if (ctx->Driver.UpdateTexturePalette) { + (*ctx->Driver.UpdateTexturePalette)( ctx, texObj ); + } + } + + ctx->NewState |= _NEW_PIXEL; +} + + + +void +_mesa_ColorSubTable( GLenum target, GLsizei start, + GLsizei count, GLenum format, GLenum type, + const GLvoid *data ) +{ + GET_CURRENT_CONTEXT(ctx); + struct gl_texture_unit *texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit]; + struct gl_texture_object *texObj = NULL; + struct gl_color_table *table = NULL; + GLfloat rScale = 1.0, gScale = 1.0, bScale = 1.0, aScale = 1.0; + GLfloat rBias = 0.0, gBias = 0.0, bBias = 0.0, aBias = 0.0; + GLint comps; + ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx); + + switch (target) { + case GL_TEXTURE_1D: + texObj = texUnit->Current1D; + table = &texObj->Palette; + break; + case GL_TEXTURE_2D: + texObj = texUnit->Current2D; + table = &texObj->Palette; + break; + case GL_TEXTURE_3D: + texObj = texUnit->Current3D; + table = &texObj->Palette; + break; + case GL_SHARED_TEXTURE_PALETTE_EXT: + table = &ctx->Texture.Palette; + break; + case GL_COLOR_TABLE: + table = &ctx->ColorTable; + rScale = ctx->Pixel.ColorTableScale[0]; + gScale = ctx->Pixel.ColorTableScale[1]; + bScale = ctx->Pixel.ColorTableScale[2]; + aScale = ctx->Pixel.ColorTableScale[3]; + rBias = ctx->Pixel.ColorTableBias[0]; + gBias = ctx->Pixel.ColorTableBias[1]; + bBias = ctx->Pixel.ColorTableBias[2]; + aBias = ctx->Pixel.ColorTableBias[3]; + break; + case GL_POST_CONVOLUTION_COLOR_TABLE: + table = &ctx->PostConvolutionColorTable; + rScale = ctx->Pixel.PCCTscale[0]; + gScale = ctx->Pixel.PCCTscale[1]; + bScale = ctx->Pixel.PCCTscale[2]; + aScale = ctx->Pixel.PCCTscale[3]; + rBias = ctx->Pixel.PCCTbias[0]; + gBias = ctx->Pixel.PCCTbias[1]; + bBias = ctx->Pixel.PCCTbias[2]; + aBias = ctx->Pixel.PCCTbias[3]; + break; + case GL_POST_COLOR_MATRIX_COLOR_TABLE: + table = &ctx->PostColorMatrixColorTable; + rScale = ctx->Pixel.PCMCTscale[0]; + gScale = ctx->Pixel.PCMCTscale[1]; + bScale = ctx->Pixel.PCMCTscale[2]; + aScale = ctx->Pixel.PCMCTscale[3]; + rBias = ctx->Pixel.PCMCTbias[0]; + gBias = ctx->Pixel.PCMCTbias[1]; + bBias = ctx->Pixel.PCMCTbias[2]; + aBias = ctx->Pixel.PCMCTbias[3]; + break; + default: + _mesa_error(ctx, GL_INVALID_ENUM, "glColorSubTable(target)"); + return; + } + + assert(table); + + if (!_mesa_is_legal_format_and_type(format, type) || + format == GL_INTENSITY) { + _mesa_error(ctx, GL_INVALID_OPERATION, "glColorSubTable(format or type)"); + return; + } + + if (count < 1) { + _mesa_error(ctx, GL_INVALID_VALUE, "glColorSubTable(count)"); + return; + } + + comps = _mesa_components_in_format(table->Format); + assert(comps > 0); /* error should have been caught sooner */ + + if (start + count > (GLint) table->Size) { + _mesa_error(ctx, GL_INVALID_VALUE, "glColorSubTable(count)"); + return; + } + + if (!table->Table) { + _mesa_error(ctx, GL_OUT_OF_MEMORY, "glColorSubTable"); + return; + } + + if (!table->FloatTable) { + GLchan *dest = (GLchan *) table->Table + start * comps * sizeof(GLchan); + _mesa_unpack_chan_color_span(ctx, count, table->Format, dest, + format, type, data, &ctx->Unpack, 0); + } + else { + GLfloat tempTab[MAX_COLOR_TABLE_SIZE * 4]; + GLfloat *tableF; + GLint i; + + ASSERT(table->FloatTable); + + _mesa_unpack_float_color_span(ctx, count, table->Format, + tempTab, /* dest */ + format, type, data, &ctx->Unpack, + 0, GL_FALSE); + + tableF = (GLfloat *) table->Table; + + switch (table->Format) { + case GL_INTENSITY: + for (i = 0; i < count; i++) { + GLuint j = start + i; + tableF[j] = CLAMP(tempTab[i] * rScale + rBias, 0.0F, 1.0F); + } + break; + case GL_LUMINANCE: + for (i = 0; i < count; i++) { + GLuint j = start + i; + tableF[j] = CLAMP(tempTab[i] * rScale + rBias, 0.0F, 1.0F); + } + break; + case GL_ALPHA: + for (i = 0; i < count; i++) { + GLuint j = start + i; + tableF[j] = CLAMP(tempTab[i] * aScale + aBias, 0.0F, 1.0F); + } + break; + case GL_LUMINANCE_ALPHA: + for (i = 0; i < count; i++) { + GLuint j = start + i; + tableF[j*2+0] = CLAMP(tempTab[i*2+0] * rScale + rBias, 0.0F, 1.0F); + tableF[j*2+1] = CLAMP(tempTab[i*2+1] * aScale + aBias, 0.0F, 1.0F); + } + break; + case GL_RGB: + for (i = 0; i < count; i++) { + GLuint j = start + i; + tableF[j*3+0] = CLAMP(tempTab[i*3+0] * rScale + rBias, 0.0F, 1.0F); + tableF[j*3+1] = CLAMP(tempTab[i*3+1] * gScale + gBias, 0.0F, 1.0F); + tableF[j*3+2] = CLAMP(tempTab[i*3+2] * bScale + bBias, 0.0F, 1.0F); + } + break; + case GL_RGBA: + for (i = 0; i < count; i++) { + GLuint j = start + i; + tableF[j*4+0] = CLAMP(tempTab[i*4+0] * rScale + rBias, 0.0F, 1.0F); + tableF[j*4+1] = CLAMP(tempTab[i*4+1] * gScale + gBias, 0.0F, 1.0F); + tableF[j*4+2] = CLAMP(tempTab[i*4+2] * bScale + bBias, 0.0F, 1.0F); + tableF[j*4+3] = CLAMP(tempTab[i*4+3] * aScale + aBias, 0.0F, 1.0F); + } + break; + default: + _mesa_problem(ctx, "Bad format in _mesa_ColorSubTable"); + return; + } + } + + if (texObj || target == GL_SHARED_TEXTURE_PALETTE_EXT) { + /* per-texture object palette */ + if (ctx->Driver.UpdateTexturePalette) { + (*ctx->Driver.UpdateTexturePalette)( ctx, texObj ); + } + } + + ctx->NewState |= _NEW_PIXEL; +} + + + +/* XXX not tested */ +void +_mesa_CopyColorTable(GLenum target, GLenum internalformat, + GLint x, GLint y, GLsizei width) +{ + GET_CURRENT_CONTEXT(ctx); + ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx); + + /* Select buffer to read from */ + ctx->Driver.CopyColorTable( ctx, target, internalformat, x, y, width ); +} + + + +/* XXX not tested */ +void +_mesa_CopyColorSubTable(GLenum target, GLsizei start, + GLint x, GLint y, GLsizei width) +{ + GET_CURRENT_CONTEXT(ctx); + ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx); + + ctx->Driver.CopyColorSubTable( ctx, target, start, x, y, width ); +} + + + +void +_mesa_GetColorTable( GLenum target, GLenum format, + GLenum type, GLvoid *data ) +{ + GET_CURRENT_CONTEXT(ctx); + struct gl_texture_unit *texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit]; + struct gl_color_table *table = NULL; + GLchan rgba[MAX_COLOR_TABLE_SIZE][4]; + ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx); + + if (ctx->NewState) { + _mesa_update_state(ctx); + } + + switch (target) { + case GL_TEXTURE_1D: + table = &texUnit->Current1D->Palette; + break; + case GL_TEXTURE_2D: + table = &texUnit->Current2D->Palette; + break; + case GL_TEXTURE_3D: + table = &texUnit->Current3D->Palette; + break; + case GL_SHARED_TEXTURE_PALETTE_EXT: + table = &ctx->Texture.Palette; + break; + case GL_COLOR_TABLE: + table = &ctx->ColorTable; + break; + case GL_POST_CONVOLUTION_COLOR_TABLE: + table = &ctx->PostConvolutionColorTable; + break; + case GL_POST_COLOR_MATRIX_COLOR_TABLE: + table = &ctx->PostColorMatrixColorTable; + break; + default: + _mesa_error(ctx, GL_INVALID_ENUM, "glGetColorTable(target)"); + return; + } + + assert(table); + + switch (table->Format) { + case GL_ALPHA: + if (table->FloatTable) { + const GLfloat *tableF = (const GLfloat *) table->Table; + GLuint i; + for (i = 0; i < table->Size; i++) { + rgba[i][RCOMP] = 0; + rgba[i][GCOMP] = 0; + rgba[i][BCOMP] = 0; + rgba[i][ACOMP] = IROUND_POS(tableF[i] * CHAN_MAXF); + } + } + else { + const GLchan *tableUB = (const GLchan *) table->Table; + GLuint i; + for (i = 0; i < table->Size; i++) { + rgba[i][RCOMP] = 0; + rgba[i][GCOMP] = 0; + rgba[i][BCOMP] = 0; + rgba[i][ACOMP] = tableUB[i]; + } + } + break; + case GL_LUMINANCE: + if (table->FloatTable) { + const GLfloat *tableF = (const GLfloat *) table->Table; + GLuint i; + for (i = 0; i < table->Size; i++) { + rgba[i][RCOMP] = IROUND_POS(tableF[i] * CHAN_MAXF); + rgba[i][GCOMP] = IROUND_POS(tableF[i] * CHAN_MAXF); + rgba[i][BCOMP] = IROUND_POS(tableF[i] * CHAN_MAXF); + rgba[i][ACOMP] = CHAN_MAX; + } + } + else { + const GLchan *tableUB = (const GLchan *) table->Table; + GLuint i; + for (i = 0; i < table->Size; i++) { + rgba[i][RCOMP] = tableUB[i]; + rgba[i][GCOMP] = tableUB[i]; + rgba[i][BCOMP] = tableUB[i]; + rgba[i][ACOMP] = CHAN_MAX; + } + } + break; + case GL_LUMINANCE_ALPHA: + if (table->FloatTable) { + const GLfloat *tableF = (const GLfloat *) table->Table; + GLuint i; + for (i = 0; i < table->Size; i++) { + rgba[i][RCOMP] = IROUND_POS(tableF[i*2+0] * CHAN_MAXF); + rgba[i][GCOMP] = IROUND_POS(tableF[i*2+0] * CHAN_MAXF); + rgba[i][BCOMP] = IROUND_POS(tableF[i*2+0] * CHAN_MAXF); + rgba[i][ACOMP] = IROUND_POS(tableF[i*2+1] * CHAN_MAXF); + } + } + else { + const GLchan *tableUB = (const GLchan *) table->Table; + GLuint i; + for (i = 0; i < table->Size; i++) { + rgba[i][RCOMP] = tableUB[i*2+0]; + rgba[i][GCOMP] = tableUB[i*2+0]; + rgba[i][BCOMP] = tableUB[i*2+0]; + rgba[i][ACOMP] = tableUB[i*2+1]; + } + } + break; + case GL_INTENSITY: + if (table->FloatTable) { + const GLfloat *tableF = (const GLfloat *) table->Table; + GLuint i; + for (i = 0; i < table->Size; i++) { + rgba[i][RCOMP] = IROUND_POS(tableF[i] * CHAN_MAXF); + rgba[i][GCOMP] = IROUND_POS(tableF[i] * CHAN_MAXF); + rgba[i][BCOMP] = IROUND_POS(tableF[i] * CHAN_MAXF); + rgba[i][ACOMP] = IROUND_POS(tableF[i] * CHAN_MAXF); + } + } + else { + const GLchan *tableUB = (const GLchan *) table->Table; + GLuint i; + for (i = 0; i < table->Size; i++) { + rgba[i][RCOMP] = tableUB[i]; + rgba[i][GCOMP] = tableUB[i]; + rgba[i][BCOMP] = tableUB[i]; + rgba[i][ACOMP] = tableUB[i]; + } + } + break; + case GL_RGB: + if (table->FloatTable) { + const GLfloat *tableF = (const GLfloat *) table->Table; + GLuint i; + for (i = 0; i < table->Size; i++) { + rgba[i][RCOMP] = IROUND_POS(tableF[i*3+0] * CHAN_MAXF); + rgba[i][GCOMP] = IROUND_POS(tableF[i*3+1] * CHAN_MAXF); + rgba[i][BCOMP] = IROUND_POS(tableF[i*3+2] * CHAN_MAXF); + rgba[i][ACOMP] = CHAN_MAX; + } + } + else { + const GLchan *tableUB = (const GLchan *) table->Table; + GLuint i; + for (i = 0; i < table->Size; i++) { + rgba[i][RCOMP] = tableUB[i*3+0]; + rgba[i][GCOMP] = tableUB[i*3+1]; + rgba[i][BCOMP] = tableUB[i*3+2]; + rgba[i][ACOMP] = CHAN_MAX; + } + } + break; + case GL_RGBA: + if (table->FloatTable) { + const GLfloat *tableF = (const GLfloat *) table->Table; + GLuint i; + for (i = 0; i < table->Size; i++) { + rgba[i][RCOMP] = IROUND_POS(tableF[i*4+0] * CHAN_MAXF); + rgba[i][GCOMP] = IROUND_POS(tableF[i*4+1] * CHAN_MAXF); + rgba[i][BCOMP] = IROUND_POS(tableF[i*4+2] * CHAN_MAXF); + rgba[i][ACOMP] = IROUND_POS(tableF[i*4+3] * CHAN_MAXF); + } + } + else { + const GLchan *tableUB = (const GLchan *) table->Table; + GLuint i; + for (i = 0; i < table->Size; i++) { + rgba[i][RCOMP] = tableUB[i*4+0]; + rgba[i][GCOMP] = tableUB[i*4+1]; + rgba[i][BCOMP] = tableUB[i*4+2]; + rgba[i][ACOMP] = tableUB[i*4+3]; + } + } + break; + default: + _mesa_problem(ctx, "bad table format in glGetColorTable"); + return; + } + + _mesa_pack_rgba_span(ctx, table->Size, (const GLchan (*)[4]) rgba, + format, type, data, &ctx->Pack, GL_FALSE); +} + + + +void +_mesa_ColorTableParameterfv(GLenum target, GLenum pname, const GLfloat *params) +{ + GET_CURRENT_CONTEXT(ctx); + ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx); + + switch (target) { + case GL_COLOR_TABLE_SGI: + if (pname == GL_COLOR_TABLE_SCALE_SGI) { + ctx->Pixel.ColorTableScale[0] = params[0]; + ctx->Pixel.ColorTableScale[1] = params[1]; + ctx->Pixel.ColorTableScale[2] = params[2]; + ctx->Pixel.ColorTableScale[3] = params[3]; + } + else if (pname == GL_COLOR_TABLE_BIAS_SGI) { + ctx->Pixel.ColorTableBias[0] = params[0]; + ctx->Pixel.ColorTableBias[1] = params[1]; + ctx->Pixel.ColorTableBias[2] = params[2]; + ctx->Pixel.ColorTableBias[3] = params[3]; + } + else { + _mesa_error(ctx, GL_INVALID_ENUM, "glColorTableParameterfv(pname)"); + return; + } + break; + case GL_POST_CONVOLUTION_COLOR_TABLE_SGI: + if (pname == GL_COLOR_TABLE_SCALE_SGI) { + ctx->Pixel.PCCTscale[0] = params[0]; + ctx->Pixel.PCCTscale[1] = params[1]; + ctx->Pixel.PCCTscale[2] = params[2]; + ctx->Pixel.PCCTscale[3] = params[3]; + } + else if (pname == GL_COLOR_TABLE_BIAS_SGI) { + ctx->Pixel.PCCTbias[0] = params[0]; + ctx->Pixel.PCCTbias[1] = params[1]; + ctx->Pixel.PCCTbias[2] = params[2]; + ctx->Pixel.PCCTbias[3] = params[3]; + } + else { + _mesa_error(ctx, GL_INVALID_ENUM, "glColorTableParameterfv(pname)"); + return; + } + break; + case GL_POST_COLOR_MATRIX_COLOR_TABLE_SGI: + if (pname == GL_COLOR_TABLE_SCALE_SGI) { + ctx->Pixel.PCMCTscale[0] = params[0]; + ctx->Pixel.PCMCTscale[1] = params[1]; + ctx->Pixel.PCMCTscale[2] = params[2]; + ctx->Pixel.PCMCTscale[3] = params[3]; + } + else if (pname == GL_COLOR_TABLE_BIAS_SGI) { + ctx->Pixel.PCMCTbias[0] = params[0]; + ctx->Pixel.PCMCTbias[1] = params[1]; + ctx->Pixel.PCMCTbias[2] = params[2]; + ctx->Pixel.PCMCTbias[3] = params[3]; + } + else { + _mesa_error(ctx, GL_INVALID_ENUM, "glColorTableParameterfv(pname)"); + return; + } + break; + default: + _mesa_error(ctx, GL_INVALID_ENUM, "glColorTableParameter(target)"); + return; + } + + ctx->NewState |= _NEW_PIXEL; +} + + + +void +_mesa_ColorTableParameteriv(GLenum target, GLenum pname, const GLint *params) +{ + GLfloat fparams[4]; + if (pname == GL_COLOR_TABLE_SGI || + pname == GL_POST_CONVOLUTION_COLOR_TABLE_SGI || + pname == GL_POST_COLOR_MATRIX_COLOR_TABLE_SGI) { + /* four values */ + fparams[0] = (GLfloat) params[0]; + fparams[1] = (GLfloat) params[1]; + fparams[2] = (GLfloat) params[2]; + fparams[3] = (GLfloat) params[3]; + } + else { + /* one values */ + fparams[0] = (GLfloat) params[0]; + } + _mesa_ColorTableParameterfv(target, pname, fparams); +} + + + +void +_mesa_GetColorTableParameterfv( GLenum target, GLenum pname, GLfloat *params ) +{ + GET_CURRENT_CONTEXT(ctx); + struct gl_texture_unit *texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit]; + struct gl_color_table *table = NULL; + ASSERT_OUTSIDE_BEGIN_END(ctx); + + switch (target) { + case GL_TEXTURE_1D: + table = &texUnit->Current1D->Palette; + break; + case GL_TEXTURE_2D: + table = &texUnit->Current2D->Palette; + break; + case GL_TEXTURE_3D: + table = &texUnit->Current3D->Palette; + break; + case GL_PROXY_TEXTURE_1D: + table = &ctx->Texture.Proxy1D->Palette; + break; + case GL_PROXY_TEXTURE_2D: + table = &ctx->Texture.Proxy2D->Palette; + break; + case GL_PROXY_TEXTURE_3D: + table = &ctx->Texture.Proxy3D->Palette; + break; + case GL_SHARED_TEXTURE_PALETTE_EXT: + table = &ctx->Texture.Palette; + break; + case GL_COLOR_TABLE: + table = &ctx->ColorTable; + if (pname == GL_COLOR_TABLE_SCALE_SGI) { + params[0] = ctx->Pixel.ColorTableScale[0]; + params[1] = ctx->Pixel.ColorTableScale[1]; + params[2] = ctx->Pixel.ColorTableScale[2]; + params[3] = ctx->Pixel.ColorTableScale[3]; + return; + } + else if (pname == GL_COLOR_TABLE_BIAS_SGI) { + params[0] = ctx->Pixel.ColorTableBias[0]; + params[1] = ctx->Pixel.ColorTableBias[1]; + params[2] = ctx->Pixel.ColorTableBias[2]; + params[3] = ctx->Pixel.ColorTableBias[3]; + return; + } + break; + case GL_PROXY_COLOR_TABLE: + table = &ctx->ProxyColorTable; + break; + case GL_POST_CONVOLUTION_COLOR_TABLE: + table = &ctx->PostConvolutionColorTable; + if (pname == GL_COLOR_TABLE_SCALE_SGI) { + params[0] = ctx->Pixel.PCCTscale[0]; + params[1] = ctx->Pixel.PCCTscale[1]; + params[2] = ctx->Pixel.PCCTscale[2]; + params[3] = ctx->Pixel.PCCTscale[3]; + return; + } + else if (pname == GL_COLOR_TABLE_BIAS_SGI) { + params[0] = ctx->Pixel.PCCTbias[0]; + params[1] = ctx->Pixel.PCCTbias[1]; + params[2] = ctx->Pixel.PCCTbias[2]; + params[3] = ctx->Pixel.PCCTbias[3]; + return; + } + break; + case GL_PROXY_POST_CONVOLUTION_COLOR_TABLE: + table = &ctx->ProxyPostConvolutionColorTable; + break; + case GL_POST_COLOR_MATRIX_COLOR_TABLE: + table = &ctx->PostColorMatrixColorTable; + if (pname == GL_COLOR_TABLE_SCALE_SGI) { + params[0] = ctx->Pixel.PCMCTscale[0]; + params[1] = ctx->Pixel.PCMCTscale[1]; + params[2] = ctx->Pixel.PCMCTscale[2]; + params[3] = ctx->Pixel.PCMCTscale[3]; + return; + } + else if (pname == GL_COLOR_TABLE_BIAS_SGI) { + params[0] = ctx->Pixel.PCMCTbias[0]; + params[1] = ctx->Pixel.PCMCTbias[1]; + params[2] = ctx->Pixel.PCMCTbias[2]; + params[3] = ctx->Pixel.PCMCTbias[3]; + return; + } + break; + case GL_PROXY_POST_COLOR_MATRIX_COLOR_TABLE: + table = &ctx->ProxyPostColorMatrixColorTable; + break; + default: + _mesa_error(ctx, GL_INVALID_ENUM, "glGetColorTableParameterfv(target)"); + return; + } + + assert(table); + + switch (pname) { + case GL_COLOR_TABLE_FORMAT: + *params = table->IntFormat; + break; + case GL_COLOR_TABLE_WIDTH: + *params = table->Size; + break; + case GL_COLOR_TABLE_RED_SIZE: + *params = table->RedSize; + break; + case GL_COLOR_TABLE_GREEN_SIZE: + *params = table->GreenSize; + break; + case GL_COLOR_TABLE_BLUE_SIZE: + *params = table->BlueSize; + break; + case GL_COLOR_TABLE_ALPHA_SIZE: + *params = table->AlphaSize; + break; + case GL_COLOR_TABLE_LUMINANCE_SIZE: + *params = table->LuminanceSize; + break; + case GL_COLOR_TABLE_INTENSITY_SIZE: + *params = table->IntensitySize; + break; + default: + _mesa_error(ctx, GL_INVALID_ENUM, "glGetColorTableParameterfv(pname)" ); + return; + } +} + + + +void +_mesa_GetColorTableParameteriv( GLenum target, GLenum pname, GLint *params ) +{ + GET_CURRENT_CONTEXT(ctx); + struct gl_texture_unit *texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit]; + struct gl_color_table *table = NULL; + ASSERT_OUTSIDE_BEGIN_END(ctx); + + switch (target) { + case GL_TEXTURE_1D: + table = &texUnit->Current1D->Palette; + break; + case GL_TEXTURE_2D: + table = &texUnit->Current2D->Palette; + break; + case GL_TEXTURE_3D: + table = &texUnit->Current3D->Palette; + break; + case GL_PROXY_TEXTURE_1D: + table = &ctx->Texture.Proxy1D->Palette; + break; + case GL_PROXY_TEXTURE_2D: + table = &ctx->Texture.Proxy2D->Palette; + break; + case GL_PROXY_TEXTURE_3D: + table = &ctx->Texture.Proxy3D->Palette; + break; + case GL_SHARED_TEXTURE_PALETTE_EXT: + table = &ctx->Texture.Palette; + break; + case GL_COLOR_TABLE: + table = &ctx->ColorTable; + if (pname == GL_COLOR_TABLE_SCALE_SGI) { + params[0] = (GLint) ctx->Pixel.ColorTableScale[0]; + params[1] = (GLint) ctx->Pixel.ColorTableScale[1]; + params[2] = (GLint) ctx->Pixel.ColorTableScale[2]; + params[3] = (GLint) ctx->Pixel.ColorTableScale[3]; + return; + } + else if (pname == GL_COLOR_TABLE_BIAS_SGI) { + params[0] = (GLint) ctx->Pixel.ColorTableBias[0]; + params[1] = (GLint) ctx->Pixel.ColorTableBias[1]; + params[2] = (GLint) ctx->Pixel.ColorTableBias[2]; + params[3] = (GLint) ctx->Pixel.ColorTableBias[3]; + return; + } + break; + case GL_PROXY_COLOR_TABLE: + table = &ctx->ProxyColorTable; + break; + case GL_POST_CONVOLUTION_COLOR_TABLE: + table = &ctx->PostConvolutionColorTable; + if (pname == GL_COLOR_TABLE_SCALE_SGI) { + params[0] = (GLint) ctx->Pixel.PCCTscale[0]; + params[1] = (GLint) ctx->Pixel.PCCTscale[1]; + params[2] = (GLint) ctx->Pixel.PCCTscale[2]; + params[3] = (GLint) ctx->Pixel.PCCTscale[3]; + return; + } + else if (pname == GL_COLOR_TABLE_BIAS_SGI) { + params[0] = (GLint) ctx->Pixel.PCCTbias[0]; + params[1] = (GLint) ctx->Pixel.PCCTbias[1]; + params[2] = (GLint) ctx->Pixel.PCCTbias[2]; + params[3] = (GLint) ctx->Pixel.PCCTbias[3]; + return; + } + break; + case GL_PROXY_POST_CONVOLUTION_COLOR_TABLE: + table = &ctx->ProxyPostConvolutionColorTable; + break; + case GL_POST_COLOR_MATRIX_COLOR_TABLE: + table = &ctx->PostColorMatrixColorTable; + if (pname == GL_COLOR_TABLE_SCALE_SGI) { + params[0] = (GLint) ctx->Pixel.PCMCTscale[0]; + params[1] = (GLint) ctx->Pixel.PCMCTscale[1]; + params[2] = (GLint) ctx->Pixel.PCMCTscale[2]; + params[3] = (GLint) ctx->Pixel.PCMCTscale[3]; + return; + } + else if (pname == GL_COLOR_TABLE_BIAS_SGI) { + params[0] = (GLint) ctx->Pixel.PCMCTbias[0]; + params[1] = (GLint) ctx->Pixel.PCMCTbias[1]; + params[2] = (GLint) ctx->Pixel.PCMCTbias[2]; + params[3] = (GLint) ctx->Pixel.PCMCTbias[3]; + return; + } + break; + case GL_PROXY_POST_COLOR_MATRIX_COLOR_TABLE: + table = &ctx->ProxyPostColorMatrixColorTable; + break; + default: + _mesa_error(ctx, GL_INVALID_ENUM, "glGetColorTableParameteriv(target)"); + return; + } + + assert(table); + + switch (pname) { + case GL_COLOR_TABLE_FORMAT: + *params = table->IntFormat; + break; + case GL_COLOR_TABLE_WIDTH: + *params = table->Size; + break; + case GL_COLOR_TABLE_RED_SIZE: + *params = table->RedSize; + break; + case GL_COLOR_TABLE_GREEN_SIZE: + *params = table->GreenSize; + break; + case GL_COLOR_TABLE_BLUE_SIZE: + *params = table->BlueSize; + break; + case GL_COLOR_TABLE_ALPHA_SIZE: + *params = table->AlphaSize; + break; + case GL_COLOR_TABLE_LUMINANCE_SIZE: + *params = table->LuminanceSize; + break; + case GL_COLOR_TABLE_INTENSITY_SIZE: + *params = table->IntensitySize; + break; + default: + _mesa_error(ctx, GL_INVALID_ENUM, "glGetColorTableParameteriv(pname)" ); + return; + } +} Index: dll/opengl/opengl32/mesa/colortab.h =================================================================== --- dll/opengl/opengl32/mesa/colortab.h (revision 0) +++ dll/opengl/opengl32/mesa/colortab.h (working copy) @@ -0,0 +1,87 @@ +/* $Id: colortab.h,v 1.9 2001/03/12 00:48:37 gareth Exp $ */ + +/* + * Mesa 3-D graphics library + * Version: 3.5 + * + * Copyright (C) 1999-2001 Brian Paul 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 + * BRIAN PAUL 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. + */ + + +#ifndef COLORTAB_H +#define COLORTAB_H + + +#include "mtypes.h" + + +extern void +_mesa_init_colortable( struct gl_color_table *p ); + +extern void +_mesa_free_colortable_data( struct gl_color_table *p ); + + +extern void +_mesa_ColorTable( GLenum target, GLenum internalformat, + GLsizei width, GLenum format, GLenum type, + const GLvoid *table ); + + +extern void +_mesa_ColorSubTable( GLenum target, GLsizei start, + GLsizei count, GLenum format, GLenum type, + const GLvoid *table ); + + +extern void +_mesa_CopyColorSubTable(GLenum target, GLsizei start, + GLint x, GLint y, GLsizei width); + + +extern void +_mesa_CopyColorTable(GLenum target, GLenum internalformat, + GLint x, GLint y, GLsizei width); + + +extern void +_mesa_GetColorTable( GLenum target, GLenum format, + GLenum type, GLvoid *table ); + + +extern void +_mesa_ColorTableParameterfv(GLenum target, GLenum pname, + const GLfloat *params); + + +extern void +_mesa_ColorTableParameteriv(GLenum target, GLenum pname, + const GLint *params); + + +extern void +_mesa_GetColorTableParameterfv( GLenum target, GLenum pname, GLfloat *params ); + + +extern void +_mesa_GetColorTableParameteriv( GLenum target, GLenum pname, GLint *params ); + + +#endif Index: dll/opengl/opengl32/mesa/config.c =================================================================== --- dll/opengl/opengl32/mesa/config.c (revision 0) +++ dll/opengl/opengl32/mesa/config.c (working copy) @@ -0,0 +1,425 @@ +/* $Id: config.c,v 1.16 2001/03/12 00:48:37 gareth Exp $ */ + +/* + * Mesa 3-D graphics library + * Version: 3.5 + * + * Copyright (C) 1999-2001 Brian Paul 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 + * BRIAN PAUL 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. + */ + + +/* Mesa config file parse and execute code. + * Copyright (C) 1999 Keith Whitwell. + * + * I hate parsers, so I've choosen a lisp-like syntax - extremely easy + * to parse and potentially very expressive. + */ + + +#ifdef PC_HEADER +#include "all.h" +#else +#include "glheader.h" +#include "context.h" +#include "enums.h" +#include "extensions.h" +#include "hint.h" +#include "simple_list.h" +#include "mem.h" +#include "mtypes.h" +#endif + + +typedef enum { nil_t, list_t, word_t } node_type; + +struct cnode { + node_type type; + int line; + union { + struct { struct cnode *head, *tail; } l; + struct { char *text; } w; + } data; +}; + +/* Accessors to query the contents of a cnode. + */ +static int is_list( struct cnode *x, struct cnode **h, struct cnode **t) +{ + if (x->type == list_t) { + struct cnode *tmp = x; + *h = tmp->data.l.head; + *t = tmp->data.l.tail; + return 1; + } + return 0; +} + +static int is_nil( const struct cnode *x ) +{ + return x->type == nil_t; +} + +static int is_word( struct cnode *x, const char **s ) +{ + if (x->type == word_t) { + *s = x->data.w.text; + return 1; + } + return 0; +} + +static int match_word( struct cnode *x, const char *s ) +{ + if (x->type == word_t) + return strcmp(s, x->data.w.text) == 0; + return 0; +} + +/* Build the parsed expression. + */ +static void skip_comment( FILE *file ) +{ + int c; + while ((c = getc(file)) != EOF && c != '\n') {}; + ungetc( c, file ); +} + + +static struct cnode *get_word( int line, FILE *file ) +{ + int sz = 16, len = 0; + char *text = (char *) MALLOC( sz * sizeof(char) ); + + while (1) { + int c = getc(file); + if (len == sz) + text = (char *) realloc( text, sizeof(char) * (sz *= 2) ); + if (c == EOF || isspace(c) || c == ')') { + struct cnode *n = MALLOC_STRUCT(cnode); + ungetc(c, file); + text[len] = 0; + n->type = word_t; + n->line = line; + n->data.w.text = text; + return n; + } + else + text[len++] = c; + } +} + +static struct cnode *get_list( int *line, FILE *file ) +{ + struct cnode *head, **current = &head; + head = MALLOC_STRUCT(cnode); + head->line = *line; + head->type = nil_t; + + while (1) { + struct cnode *n = 0; + int c = getc(file); + + switch (c) { + case EOF: return head; + case ')': return head; + case ';': skip_comment( file ); continue; + case '\n': (*line)++; continue; + case '(': + n = get_list( line, file ); + break; + default: + if (isspace(c)) continue; + ungetc(c, file); + n = get_word( *line, file ); + break; + } + + (*current)->type = list_t; + (*current)->data.l.head = n; + current = &(*current)->data.l.tail; + (*current) = MALLOC_STRUCT(cnode); + (*current)->line = *line; + (*current)->type = nil_t; + } +} + +/* Execute it. + */ +static void error( struct cnode *n, const char *err ) +{ + printf("Error in init file, line %d: %s\n", n->line, err ); +} + +static void disable_extension( GLcontext *ctx, struct cnode *args ) +{ + struct cnode *head, *tail; + const char *c; + + if (is_list(args, &head, &tail) && + is_nil(tail) && + is_word(head, &c)) { + _mesa_disable_extension( ctx, c ); + } + else { + error( args, "bad args for disable-extension" ); + } +} + + +static void default_hint( GLcontext *ctx, struct cnode *args ) +{ + struct cnode *hint, *tail, *value; + const char *hname, *vname; + + if (is_list(args, &hint, &tail) && + is_list(tail, &value, &tail) && + is_nil(tail) && + is_word(hint, &hname) && + is_word(value, &vname)) + { + GLint h = _mesa_lookup_enum_by_name(hname); + GLint v = _mesa_lookup_enum_by_name(vname); + if (h != -1 && v != -1) + { + if (!_mesa_try_Hint( ctx, (GLenum) h, (GLenum) v )) + error( hint, "glHint failed"); + return; + } + else + error( hint, "unknown or illegal value for default-hint" ); + } + else + error( args, "bad args for default-hint" ); +} + +/* Use the general-purpose set-variable + */ +static void fx_catch_signals( GLcontext *ctx, struct cnode *args ) +{ + struct cnode *head, *tail; + const char *value; + +/* error( args, */ +/* "fx-catch-signals deprecated, use " */ +/* "(set-variable fx-catch-signals ...) instead"); */ + + if (is_list(args, &head, &tail) && + is_nil(tail) && + is_word(head, &value)) { + if (strcmp(value, "false") == 0) + ctx->CatchSignals = GL_FALSE; + else if (strcmp(value, "true") == 0) + ctx->CatchSignals = GL_TRUE; + else + error( args, "expected 'true' or 'false'" ); + } + else { + error( args, "bad args for fx-catch-signal" ); + } +} + +/* Well, should these also check the environment? + * Should environment vars override config vars? + */ + +struct var { + struct var *next, *prev; + const char *name; + void (*notify)(const char *value, int line); +}; + +static struct var varlist = { &varlist, &varlist, 0, 0 }; + +static void set_var( GLcontext *ctx, struct cnode *args ) +{ + struct var *v; + struct cnode *head, *tail; + const char *variable, *value; + + if (is_list(args, &head, &tail) && + is_word(head, &variable) && + is_list(tail, &head, &tail) && + is_word(head, &value) && + is_nil(tail)) + { + foreach(v, &varlist) { + if (strcmp(v->name, variable) == 0) { + v->notify(value, head->line); + return; + } + } + + error( head, "unknown variable" ); + } + else { + error( args, "bad format for (set VARIABLE VALUE)" ); + } +} + +void +_mesa_register_config_var(const char *name, + void (*notify)( const char *, int )) +{ + struct var *v = MALLOC_STRUCT(var); + v->name = name; + v->notify = notify; + insert_at_tail( &varlist, v ); +} + + +static void do_init( GLcontext *ctx, struct cnode *list ) +{ + struct cnode *head, *tail, *func, *args; + + if (is_list(list, &head, &tail) && is_nil(tail)) { + list = head; + while (is_list(list, &head, &list)) { + if (is_list(head, &func, &args)) { + if (match_word(func, "disable-extension")) + disable_extension( ctx, args ); + else if (match_word(func, "default-hint")) + default_hint( ctx, args ); + else if (match_word(func, "fx-catch-signals")) + fx_catch_signals( ctx, args ); + else if (match_word(func, "set-variable")) + set_var( ctx, args ); + else + error( func, "unknown configuration method" ); + } + } + } + else if (!is_nil(list)) { + error( list, "configurations must form a list" ); + } +} + +static int run_init( GLcontext *ctx, const char *version, struct cnode *list ) +{ + struct cnode *head, *arg1, *arg2; + const char *v; + + /* Uses the first matching init list. + */ + while (is_list(list, &head, &list)) + if (is_list(head, &arg1, &head) && + is_list(head, &arg2, &head) && + match_word(arg1, "config-mesa") && + is_word(arg2, &v)) + { + if (strcmp(v, version) == 0) { + do_init( ctx, head ); + return 1; + } + } + else + error( head, "malformed toplevel configuration" ); + + return 0; +} + + + +static void free_list( struct cnode *n ) +{ + while (n->type == list_t) { + struct cnode *tmp = n; + switch (n->data.l.head->type) { + case list_t: + free_list( n->data.l.head ); + break; + case word_t: + FREE( n->data.l.head->data.w.text ); + FREE( n->data.l.head ); + break; + case nil_t: + FREE( n->data.l.head ); + break; + default: + return; + } + n = n->data.l.tail; + FREE( tmp ); + } + FREE( n ); +} + + + + +/* How paranoid do you have to be when reading a config file? I don't + * know half the ways to exploit this stuff, and given that this may + * be run with root access, I think we're better off hardcoding the + * pathname. Some clever joe can fix this later if they care. + */ +void _mesa_read_config_file( GLcontext *ctx ) +{ + const char *default_config = "mesa3.1beta1"; + +#if defined(__WIN32__) || defined(__MSDOS__) + const char *filename = "mesa.cnf"; +#else + const char *filename = "/etc/mesa.conf"; +#endif + FILE *file; + struct cnode *list; + int line = 1; + char *v; + +#if 0 + int f; + struct stat statbuf; + + if ((f = open(filename, O_RDONLY)) == -1) + return; + + if (fstat( f, &statbuf ) == -1 || + !S_ISREG( statbuf.st_mode ) || + (file = fdopen(f, "r")) == 0) + { + close( f ); + return; + } +#endif + + if ((file = fopen(filename, "r")) == 0) + return; + + list = get_list( &line, file ); + fclose( file ); + + if ((v = getenv("MESA_CONFIG")) != 0 && *v != 0) { + if (run_init( ctx, v, list )) { + free_list( list ); + return; + } + else + fprintf(stderr, "No configuration '%s' in init file\n", v); + } + + + if (!run_init( ctx, default_config, list )) { + if (getenv("MESA_DEBUG")) { + fprintf(stderr, "No default configuration '%s' in init file\n", + default_config); + } + } + + free_list( list ); +} Index: dll/opengl/opengl32/mesa/config.h =================================================================== --- dll/opengl/opengl32/mesa/config.h (revision 0) +++ dll/opengl/opengl32/mesa/config.h (working copy) @@ -0,0 +1,188 @@ +/* $Id: config.h,v 1.32 2001/06/13 14:56:14 brianp Exp $ */ + +/* + * Mesa 3-D graphics library + * Version: 3.5 + * + * Copyright (C) 1999-2001 Brian Paul 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 + * BRIAN PAUL 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. + */ + + +/* + * Tunable configuration parameters. + */ + + + +#ifndef CONFIG_H +#define CONFIG_H + +#ifdef HAVE_CONFIG_H +#include "conf.h" +#endif + + +/* + * OpenGL implementation limits + */ + +/* Maximum modelview matrix stack depth: */ +#define MAX_MODELVIEW_STACK_DEPTH 32 + +/* Maximum projection matrix stack depth: */ +#define MAX_PROJECTION_STACK_DEPTH 32 + +/* Maximum texture matrix stack depth: */ +#define MAX_TEXTURE_STACK_DEPTH 10 + +/* Maximum color matrix stack depth: */ +#define MAX_COLOR_STACK_DEPTH 4 + +/* Maximum attribute stack depth: */ +#define MAX_ATTRIB_STACK_DEPTH 16 + +/* Maximum client attribute stack depth: */ +#define MAX_CLIENT_ATTRIB_STACK_DEPTH 16 + +/* Maximum recursion depth of display list calls: */ +#define MAX_LIST_NESTING 64 + +/* Maximum number of lights: */ +#define MAX_LIGHTS 8 + +/* Maximum user-defined clipping planes: */ +#define MAX_CLIP_PLANES 6 + +/* Maximum pixel map lookup table size: */ +#define MAX_PIXEL_MAP_TABLE 256 + +/* Number of auxillary color buffers: */ +#define NUM_AUX_BUFFERS 0 + +/* Maximum order (degree) of curves: */ +#ifdef AMIGA +# define MAX_EVAL_ORDER 12 +#else +# define MAX_EVAL_ORDER 30 +#endif + +/* Maximum Name stack depth */ +#define MAX_NAME_STACK_DEPTH 64 + +/* Min and Max point sizes and granularity */ +#define MIN_POINT_SIZE 1.0 +#define MAX_POINT_SIZE 10.0 +#define POINT_SIZE_GRANULARITY 0.1 + +/* Min and Max line widths and granularity */ +#define MIN_LINE_WIDTH 1.0 +#define MAX_LINE_WIDTH 10.0 +#define LINE_WIDTH_GRANULARITY 0.1 + +/* Max texture palette / color table size */ +#define MAX_COLOR_TABLE_SIZE 256 + +/* Number of 1D/2D texture mipmap levels */ +#define MAX_TEXTURE_LEVELS 12 + +/* Number of 3D texture mipmap levels */ +#define MAX_3D_TEXTURE_LEVELS 8 + +/* Number of cube texture mipmap levels */ +#define MAX_CUBE_TEXTURE_LEVELS 12 + +/* Number of texture units - GL_ARB_multitexture */ +#define MAX_TEXTURE_UNITS 8 + +/* Maximum viewport/image size: */ +#define MAX_WIDTH 2048 +#define MAX_HEIGHT 2048 + +/* Maxmimum size for CVA. May be overridden by the drivers. */ +#define MAX_ARRAY_LOCK_SIZE 3000 + +/* Subpixel precision for antialiasing, window coordinate snapping */ +#define SUB_PIXEL_BITS 4 + +/* Size of histogram tables */ +#define HISTOGRAM_TABLE_SIZE 256 + +/* Max convolution filter sizes */ +#define MAX_CONVOLUTION_WIDTH 9 +#define MAX_CONVOLUTION_HEIGHT 9 + +/* GL_ARB_texture_compression */ +#define MAX_COMPRESSED_TEXTURE_FORMATS 25 + +/* GL_EXT_texture_filter_anisotropic */ +#define MAX_TEXTURE_MAX_ANISOTROPY 16.0 + + + +/* + * Mesa-specific parameters + */ + + +/* + * Bits per accumulation buffer color component: 8 or 16 + */ +#define ACCUM_BITS 16 + + +/* + * Bits per depth buffer value. Any reasonable value up to 31 will + * work. 32 doesn't work because of integer overflow problems in the + * rasterizer code. + */ +#define DEFAULT_SOFTWARE_DEPTH_BITS 16 +#if DEFAULT_SOFTWARE_DEPTH_BITS <= 16 +#define DEFAULT_SOFTWARE_DEPTH_TYPE GLushort +#else +#define DEFAULT_SOFTWARE_DEPTH_TYPE GLuint +#endif + + + +/* + * Bits per stencil value: 8 + */ +#define STENCIL_BITS 8 + + +/* + * Bits per color channel (must be 8 at this time!) + */ +#ifndef CHAN_BITS +#define CHAN_BITS 8 +#endif + + +/* + * Color channel component order + * (changes will almost certainly cause problems at this time) + */ +#define RCOMP 0 +#define GCOMP 1 +#define BCOMP 2 +#define ACOMP 3 + + +#endif /* CONFIG_H */ Index: dll/opengl/opengl32/mesa/context.c =================================================================== --- dll/opengl/opengl32/mesa/context.c (revision 0) +++ dll/opengl/opengl32/mesa/context.c (working copy) @@ -0,0 +1,2079 @@ +/* $Id: context.c,v 1.143 2001/06/13 14:56:14 brianp Exp $ */ + +/* + * Mesa 3-D graphics library + * Version: 3.5 + * + * Copyright (C) 1999-2001 Brian Paul 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 + * BRIAN PAUL 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. + */ + + +#ifdef PC_HEADER +#include "all.h" +#else +#include "glheader.h" +#include "buffers.h" +#include "clip.h" +#include "colortab.h" +#include "context.h" +#include "dlist.h" +#include "eval.h" +#include "enums.h" +#include "extensions.h" +#include "fog.h" +#include "get.h" +#include "glthread.h" +#include "hash.h" +#include "imports.h" +#include "light.h" +#include "macros.h" +#include "mem.h" +#include "mmath.h" +#include "simple_list.h" +#include "state.h" +#include "teximage.h" +#include "texobj.h" +#include "mtypes.h" +#include "varray.h" +#include "vtxfmt.h" + +#include "math/m_translate.h" +#include "math/m_vertices.h" +#include "math/m_matrix.h" +#include "math/m_xform.h" +#include "math/mathmod.h" +#endif + +#if defined(MESA_TRACE) +#include "Trace/tr_context.h" +#include "Trace/tr_wrapper.h" +#endif + +#ifdef USE_SPARC_ASM +#include "SPARC/sparc.h" +#endif + +#ifndef MESA_VERBOSE +int MESA_VERBOSE = 0 +/* | VERBOSE_PIPELINE */ +/* | VERBOSE_IMMEDIATE */ +/* | VERBOSE_VARRAY */ +/* | VERBOSE_TEXTURE */ +/* | VERBOSE_API */ +/* | VERBOSE_DRIVER */ +/* | VERBOSE_STATE */ +/* | VERBOSE_DISPLAY_LIST */ +; +#endif + +#ifndef MESA_DEBUG_FLAGS +int MESA_DEBUG_FLAGS = 0 +/* | DEBUG_ALWAYS_FLUSH */ +; +#endif + +/**********************************************************************/ +/***** OpenGL SI-style interface (new in Mesa 3.5) *****/ +/**********************************************************************/ + +static GLboolean +_mesa_DestroyContext(__GLcontext *gc) +{ + if (gc) { + _mesa_free_context_data(gc); + (*gc->imports.free)(gc, gc); + } + return GL_TRUE; +} + + +/* exported OpenGL SI interface */ +__GLcontext * +__glCoreCreateContext(__GLimports *imports, __GLcontextModes *modes) +{ + GLcontext *ctx; + + ctx = (GLcontext *) (*imports->calloc)(0, 1, sizeof(GLcontext)); + if (ctx == NULL) { + return NULL; + } + ctx->imports = *imports; + + _mesa_initialize_visual(&ctx->Visual, + modes->rgbMode, + modes->doubleBufferMode, + modes->stereoMode, + modes->redBits, + modes->greenBits, + modes->blueBits, + modes->alphaBits, + modes->indexBits, + modes->depthBits, + modes->stencilBits, + modes->accumRedBits, + modes->accumGreenBits, + modes->accumBlueBits, + modes->accumAlphaBits, + 0); + + /* KW: was imports->wscx */ + _mesa_initialize_context(ctx, &ctx->Visual, NULL, imports->other, GL_FALSE); + + ctx->exports.destroyContext = _mesa_DestroyContext; + + return ctx; +} + + +/* exported OpenGL SI interface */ +void +__glCoreNopDispatch(void) +{ +#if 0 + /* SI */ + __gl_dispatch = __glNopDispatchState; +#else + /* Mesa */ + _glapi_set_dispatch(NULL); +#endif +} + + +/**********************************************************************/ +/***** Context and Thread management *****/ +/**********************************************************************/ + + + +/**********************************************************************/ +/***** GL Visual allocation/destruction *****/ +/**********************************************************************/ + + +/* + * Allocate a new GLvisual object. + * Input: rgbFlag - GL_TRUE=RGB(A) mode, GL_FALSE=Color Index mode + * dbFlag - double buffering? + * stereoFlag - stereo buffer? + * depthBits - requested bits per depth buffer value + * Any value in [0, 32] is acceptable but the actual + * depth type will be GLushort or GLuint as needed. + * stencilBits - requested minimum bits per stencil buffer value + * accumBits - requested minimum bits per accum buffer component + * indexBits - number of bits per pixel if rgbFlag==GL_FALSE + * red/green/blue/alphaBits - number of bits per color component + * in frame buffer for RGB(A) mode. + * We always use 8 in core Mesa though. + * Return: pointer to new GLvisual or NULL if requested parameters can't + * be met. + */ +GLvisual * +_mesa_create_visual( GLboolean rgbFlag, + GLboolean dbFlag, + GLboolean stereoFlag, + GLint redBits, + GLint greenBits, + GLint blueBits, + GLint alphaBits, + GLint indexBits, + GLint depthBits, + GLint stencilBits, + GLint accumRedBits, + GLint accumGreenBits, + GLint accumBlueBits, + GLint accumAlphaBits, + GLint numSamples ) +{ + GLvisual *vis = (GLvisual *) CALLOC( sizeof(GLvisual) ); + if (vis) { + if (!_mesa_initialize_visual(vis, rgbFlag, dbFlag, stereoFlag, + redBits, greenBits, blueBits, alphaBits, + indexBits, depthBits, stencilBits, + accumRedBits, accumGreenBits, + accumBlueBits, accumAlphaBits, + numSamples)) { + FREE(vis); + return NULL; + } + } + return vis; +} + + +/* + * Initialize the fields of the given GLvisual. + * Input: see _mesa_create_visual() above. + * Return: GL_TRUE = success + * GL_FALSE = failure. + */ +GLboolean +_mesa_initialize_visual( GLvisual *vis, + GLboolean rgbFlag, + GLboolean dbFlag, + GLboolean stereoFlag, + GLint redBits, + GLint greenBits, + GLint blueBits, + GLint alphaBits, + GLint indexBits, + GLint depthBits, + GLint stencilBits, + GLint accumRedBits, + GLint accumGreenBits, + GLint accumBlueBits, + GLint accumAlphaBits, + GLint numSamples ) +{ + (void) numSamples; + + assert(vis); + + /* This is to catch bad values from device drivers not updated for + * Mesa 3.3. Some device drivers just passed 1. That's a REALLY + * bad value now (a 1-bit depth buffer!?!). + */ + assert(depthBits == 0 || depthBits > 1); + + if (depthBits < 0 || depthBits > 32) { + return GL_FALSE; + } + if (stencilBits < 0 || stencilBits > (GLint) (8 * sizeof(GLstencil))) { + return GL_FALSE; + } + if (accumRedBits < 0 || accumRedBits > (GLint) (8 * sizeof(GLaccum))) { + return GL_FALSE; + } + if (accumGreenBits < 0 || accumGreenBits > (GLint) (8 * sizeof(GLaccum))) { + return GL_FALSE; + } + if (accumBlueBits < 0 || accumBlueBits > (GLint) (8 * sizeof(GLaccum))) { + return GL_FALSE; + } + if (accumAlphaBits < 0 || accumAlphaBits > (GLint) (8 * sizeof(GLaccum))) { + return GL_FALSE; + } + + vis->rgbMode = rgbFlag; + vis->doubleBufferMode = dbFlag; + vis->stereoMode = stereoFlag; + vis->redBits = redBits; + vis->greenBits = greenBits; + vis->blueBits = blueBits; + vis->alphaBits = alphaBits; + + vis->indexBits = indexBits; + vis->depthBits = depthBits; + vis->accumRedBits = (accumRedBits > 0) ? (8 * sizeof(GLaccum)) : 0; + vis->accumGreenBits = (accumGreenBits > 0) ? (8 * sizeof(GLaccum)) : 0; + vis->accumBlueBits = (accumBlueBits > 0) ? (8 * sizeof(GLaccum)) : 0; + vis->accumAlphaBits = (accumAlphaBits > 0) ? (8 * sizeof(GLaccum)) : 0; + vis->stencilBits = (stencilBits > 0) ? (8 * sizeof(GLstencil)) : 0; + + return GL_TRUE; +} + + +void +_mesa_destroy_visual( GLvisual *vis ) +{ + FREE(vis); +} + + +/**********************************************************************/ +/***** GL Framebuffer allocation/destruction *****/ +/**********************************************************************/ + + +/* + * Create a new framebuffer. A GLframebuffer is a struct which + * encapsulates the depth, stencil and accum buffers and related + * parameters. + * Input: visual - a GLvisual pointer (we copy the struct contents) + * softwareDepth - create/use a software depth buffer? + * softwareStencil - create/use a software stencil buffer? + * softwareAccum - create/use a software accum buffer? + * softwareAlpha - create/use a software alpha buffer? + * Return: pointer to new GLframebuffer struct or NULL if error. + */ +GLframebuffer * +_mesa_create_framebuffer( const GLvisual *visual, + GLboolean softwareDepth, + GLboolean softwareStencil, + GLboolean softwareAccum, + GLboolean softwareAlpha ) +{ + GLframebuffer *buffer = CALLOC_STRUCT(gl_frame_buffer); + assert(visual); + if (buffer) { + _mesa_initialize_framebuffer(buffer, visual, + softwareDepth, softwareStencil, + softwareAccum, softwareAlpha ); + } + return buffer; +} + + +/* + * Initialize a GLframebuffer object. + * Input: See _mesa_create_framebuffer() above. + */ +void +_mesa_initialize_framebuffer( GLframebuffer *buffer, + const GLvisual *visual, + GLboolean softwareDepth, + GLboolean softwareStencil, + GLboolean softwareAccum, + GLboolean softwareAlpha ) +{ + assert(buffer); + assert(visual); + + /* sanity checks */ + if (softwareDepth ) { + assert(visual->depthBits > 0); + } + if (softwareStencil) { + assert(visual->stencilBits > 0); + } + if (softwareAccum) { + assert(visual->rgbMode); + assert(visual->accumRedBits > 0); + assert(visual->accumGreenBits > 0); + assert(visual->accumBlueBits > 0); + } + if (softwareAlpha) { + assert(visual->rgbMode); + assert(visual->alphaBits > 0); + } + + buffer->Visual = *visual; + buffer->UseSoftwareDepthBuffer = softwareDepth; + buffer->UseSoftwareStencilBuffer = softwareStencil; + buffer->UseSoftwareAccumBuffer = softwareAccum; + buffer->UseSoftwareAlphaBuffers = softwareAlpha; +} + + +/* + * Free a framebuffer struct and its buffers. + */ +void +_mesa_destroy_framebuffer( GLframebuffer *buffer ) +{ + if (buffer) { + _mesa_free_framebuffer_data(buffer); + FREE(buffer); + } +} + + +/* + * Free the data hanging off of , but not itself. + */ +void +_mesa_free_framebuffer_data( GLframebuffer *buffer ) +{ + if (!buffer) + return; + + if (buffer->DepthBuffer) { + FREE( buffer->DepthBuffer ); + buffer->DepthBuffer = NULL; + } + if (buffer->Accum) { + FREE( buffer->Accum ); + buffer->Accum = NULL; + } + if (buffer->Stencil) { + FREE( buffer->Stencil ); + buffer->Stencil = NULL; + } + if (buffer->FrontLeftAlpha) { + FREE( buffer->FrontLeftAlpha ); + buffer->FrontLeftAlpha = NULL; + } + if (buffer->BackLeftAlpha) { + FREE( buffer->BackLeftAlpha ); + buffer->BackLeftAlpha = NULL; + } + if (buffer->FrontRightAlpha) { + FREE( buffer->FrontRightAlpha ); + buffer->FrontRightAlpha = NULL; + } + if (buffer->BackRightAlpha) { + FREE( buffer->BackRightAlpha ); + buffer->BackRightAlpha = NULL; + } +} + + + +/**********************************************************************/ +/***** Context allocation, initialization, destroying *****/ +/**********************************************************************/ + + +_glthread_DECLARE_STATIC_MUTEX(OneTimeLock); + + +/* + * This function just calls all the various one-time-init functions in Mesa. + */ +static void +one_time_init( void ) +{ + static GLboolean alreadyCalled = GL_FALSE; + _glthread_LOCK_MUTEX(OneTimeLock); + if (!alreadyCalled) { + /* do some implementation tests */ + assert( sizeof(GLbyte) == 1 ); + assert( sizeof(GLshort) >= 2 ); + assert( sizeof(GLint) >= 4 ); + assert( sizeof(GLubyte) == 1 ); + assert( sizeof(GLushort) >= 2 ); + assert( sizeof(GLuint) >= 4 ); + + _mesa_init_lists(); + + _math_init(); + _mesa_init_math(); + +#ifdef USE_SPARC_ASM + _mesa_init_sparc_glapi_relocs(); +#endif + if (getenv("MESA_DEBUG")) { + _glapi_noop_enable_warnings(GL_TRUE); + } + else { + _glapi_noop_enable_warnings(GL_FALSE); + } + +#if defined(DEBUG) && defined(__DATE__) && defined(__TIME__) + fprintf(stderr, "Mesa DEBUG build %s %s\n", __DATE__, __TIME__); +#endif + + alreadyCalled = GL_TRUE; + } + _glthread_UNLOCK_MUTEX(OneTimeLock); +} + + + +/* + * Allocate and initialize a shared context state structure. + */ +static struct gl_shared_state * +alloc_shared_state( void ) +{ + struct gl_shared_state *ss; + GLboolean outOfMemory; + + ss = CALLOC_STRUCT(gl_shared_state); + if (!ss) + return NULL; + + _glthread_INIT_MUTEX(ss->Mutex); + + ss->DisplayList = _mesa_NewHashTable(); + ss->TexObjects = _mesa_NewHashTable(); + + /* Default Texture objects */ + outOfMemory = GL_FALSE; + + ss->Default1D = _mesa_alloc_texture_object(ss, 0, 1); + if (!ss->Default1D) { + outOfMemory = GL_TRUE; + } + + ss->Default2D = _mesa_alloc_texture_object(ss, 0, 2); + if (!ss->Default2D) { + outOfMemory = GL_TRUE; + } + + ss->Default3D = _mesa_alloc_texture_object(ss, 0, 3); + if (!ss->Default3D) { + outOfMemory = GL_TRUE; + } + + ss->DefaultCubeMap = _mesa_alloc_texture_object(ss, 0, 6); + if (!ss->DefaultCubeMap) { + outOfMemory = GL_TRUE; + } + + if (!ss->DisplayList || !ss->TexObjects || outOfMemory) { + /* Ran out of memory at some point. Free everything and return NULL */ + if (ss->DisplayList) + _mesa_DeleteHashTable(ss->DisplayList); + if (ss->TexObjects) + _mesa_DeleteHashTable(ss->TexObjects); + if (ss->Default1D) + _mesa_free_texture_object(ss, ss->Default1D); + if (ss->Default2D) + _mesa_free_texture_object(ss, ss->Default2D); + if (ss->Default3D) + _mesa_free_texture_object(ss, ss->Default3D); + if (ss->DefaultCubeMap) + _mesa_free_texture_object(ss, ss->DefaultCubeMap); + FREE(ss); + return NULL; + } + else { + return ss; + } +} + + +/* + * Deallocate a shared state context and all children structures. + */ +static void +free_shared_state( GLcontext *ctx, struct gl_shared_state *ss ) +{ + /* Free display lists */ + while (1) { + GLuint list = _mesa_HashFirstEntry(ss->DisplayList); + if (list) { + _mesa_destroy_list(ctx, list); + } + else { + break; + } + } + _mesa_DeleteHashTable(ss->DisplayList); + + /* Free texture objects */ + while (ss->TexObjectList) { + if (ctx->Driver.DeleteTexture) + (*ctx->Driver.DeleteTexture)( ctx, ss->TexObjectList ); + /* this function removes from linked list too! */ + _mesa_free_texture_object(ss, ss->TexObjectList); + } + _mesa_DeleteHashTable(ss->TexObjects); + + FREE(ss); +} + + + +/* + * Initialize the nth light. Note that the defaults for light 0 are + * different than the other lights. + */ +static void +init_light( struct gl_light *l, GLuint n ) +{ + make_empty_list( l ); + + ASSIGN_4V( l->Ambient, 0.0, 0.0, 0.0, 1.0 ); + if (n==0) { + ASSIGN_4V( l->Diffuse, 1.0, 1.0, 1.0, 1.0 ); + ASSIGN_4V( l->Specular, 1.0, 1.0, 1.0, 1.0 ); + } + else { + ASSIGN_4V( l->Diffuse, 0.0, 0.0, 0.0, 1.0 ); + ASSIGN_4V( l->Specular, 0.0, 0.0, 0.0, 1.0 ); + } + ASSIGN_4V( l->EyePosition, 0.0, 0.0, 1.0, 0.0 ); + ASSIGN_3V( l->EyeDirection, 0.0, 0.0, -1.0 ); + l->SpotExponent = 0.0; + _mesa_invalidate_spot_exp_table( l ); + l->SpotCutoff = 180.0; + l->_CosCutoff = 0.0; /* KW: -ve values not admitted */ + l->ConstantAttenuation = 1.0; + l->LinearAttenuation = 0.0; + l->QuadraticAttenuation = 0.0; + l->Enabled = GL_FALSE; +} + + + +static void +init_lightmodel( struct gl_lightmodel *lm ) +{ + ASSIGN_4V( lm->Ambient, 0.2, 0.2, 0.2, 1.0 ); + lm->LocalViewer = GL_FALSE; + lm->TwoSide = GL_FALSE; + lm->ColorControl = GL_SINGLE_COLOR; +} + + +static void +init_material( struct gl_material *m ) +{ + ASSIGN_4V( m->Ambient, 0.2, 0.2, 0.2, 1.0 ); + ASSIGN_4V( m->Diffuse, 0.8, 0.8, 0.8, 1.0 ); + ASSIGN_4V( m->Specular, 0.0, 0.0, 0.0, 1.0 ); + ASSIGN_4V( m->Emission, 0.0, 0.0, 0.0, 1.0 ); + m->Shininess = 0.0; + m->AmbientIndex = 0; + m->DiffuseIndex = 1; + m->SpecularIndex = 1; +} + + + +static void +init_texture_unit( GLcontext *ctx, GLuint unit ) +{ + struct gl_texture_unit *texUnit = &ctx->Texture.Unit[unit]; + + texUnit->EnvMode = GL_MODULATE; + texUnit->CombineModeRGB = GL_MODULATE; + texUnit->CombineModeA = GL_MODULATE; + texUnit->CombineSourceRGB[0] = GL_TEXTURE; + texUnit->CombineSourceRGB[1] = GL_PREVIOUS_EXT; + texUnit->CombineSourceRGB[2] = GL_CONSTANT_EXT; + texUnit->CombineSourceA[0] = GL_TEXTURE; + texUnit->CombineSourceA[1] = GL_PREVIOUS_EXT; + texUnit->CombineSourceA[2] = GL_CONSTANT_EXT; + texUnit->CombineOperandRGB[0] = GL_SRC_COLOR; + texUnit->CombineOperandRGB[1] = GL_SRC_COLOR; + texUnit->CombineOperandRGB[2] = GL_SRC_ALPHA; + texUnit->CombineOperandA[0] = GL_SRC_ALPHA; + texUnit->CombineOperandA[1] = GL_SRC_ALPHA; + texUnit->CombineOperandA[2] = GL_SRC_ALPHA; + texUnit->CombineScaleShiftRGB = 0; + texUnit->CombineScaleShiftA = 0; + + ASSIGN_4V( texUnit->EnvColor, 0.0, 0.0, 0.0, 0.0 ); + texUnit->TexGenEnabled = 0; + texUnit->GenModeS = GL_EYE_LINEAR; + texUnit->GenModeT = GL_EYE_LINEAR; + texUnit->GenModeR = GL_EYE_LINEAR; + texUnit->GenModeQ = GL_EYE_LINEAR; + texUnit->_GenBitS = TEXGEN_EYE_LINEAR; + texUnit->_GenBitT = TEXGEN_EYE_LINEAR; + texUnit->_GenBitR = TEXGEN_EYE_LINEAR; + texUnit->_GenBitQ = TEXGEN_EYE_LINEAR; + + /* Yes, these plane coefficients are correct! */ + ASSIGN_4V( texUnit->ObjectPlaneS, 1.0, 0.0, 0.0, 0.0 ); + ASSIGN_4V( texUnit->ObjectPlaneT, 0.0, 1.0, 0.0, 0.0 ); + ASSIGN_4V( texUnit->ObjectPlaneR, 0.0, 0.0, 0.0, 0.0 ); + ASSIGN_4V( texUnit->ObjectPlaneQ, 0.0, 0.0, 0.0, 0.0 ); + ASSIGN_4V( texUnit->EyePlaneS, 1.0, 0.0, 0.0, 0.0 ); + ASSIGN_4V( texUnit->EyePlaneT, 0.0, 1.0, 0.0, 0.0 ); + ASSIGN_4V( texUnit->EyePlaneR, 0.0, 0.0, 0.0, 0.0 ); + ASSIGN_4V( texUnit->EyePlaneQ, 0.0, 0.0, 0.0, 0.0 ); + + texUnit->Current1D = ctx->Shared->Default1D; + texUnit->Current2D = ctx->Shared->Default2D; + texUnit->Current3D = ctx->Shared->Default3D; + texUnit->CurrentCubeMap = ctx->Shared->DefaultCubeMap; +} + + + + +/* Initialize a 1-D evaluator map */ +static void +init_1d_map( struct gl_1d_map *map, int n, const float *initial ) +{ + map->Order = 1; + map->u1 = 0.0; + map->u2 = 1.0; + map->Points = (GLfloat *) MALLOC(n * sizeof(GLfloat)); + if (map->Points) { + GLint i; + for (i=0;iPoints[i] = initial[i]; + } +} + + +/* Initialize a 2-D evaluator map */ +static void +init_2d_map( struct gl_2d_map *map, int n, const float *initial ) +{ + map->Uorder = 1; + map->Vorder = 1; + map->u1 = 0.0; + map->u2 = 1.0; + map->v1 = 0.0; + map->v2 = 1.0; + map->Points = (GLfloat *) MALLOC(n * sizeof(GLfloat)); + if (map->Points) { + GLint i; + for (i=0;iPoints[i] = initial[i]; + } +} + + +/* + * Initialize the attribute groups in a GLcontext. + */ +static void +init_attrib_groups( GLcontext *ctx ) +{ + GLuint i, j; + + assert(ctx); + + assert(MAX_TEXTURE_LEVELS >= MAX_3D_TEXTURE_LEVELS); + assert(MAX_TEXTURE_LEVELS >= MAX_CUBE_TEXTURE_LEVELS); + + /* Constants, may be overriden by device drivers */ + ctx->Const.MaxTextureLevels = MAX_TEXTURE_LEVELS; + ctx->Const.Max3DTextureLevels = MAX_3D_TEXTURE_LEVELS; + ctx->Const.MaxCubeTextureLevels = MAX_CUBE_TEXTURE_LEVELS; + ctx->Const.MaxTextureUnits = MAX_TEXTURE_UNITS; + ctx->Const.MaxTextureMaxAnisotropy = MAX_TEXTURE_MAX_ANISOTROPY; + ctx->Const.MaxArrayLockSize = MAX_ARRAY_LOCK_SIZE; + ctx->Const.SubPixelBits = SUB_PIXEL_BITS; + ctx->Const.MinPointSize = MIN_POINT_SIZE; + ctx->Const.MaxPointSize = MAX_POINT_SIZE; + ctx->Const.MinPointSizeAA = MIN_POINT_SIZE; + ctx->Const.MaxPointSizeAA = MAX_POINT_SIZE; + ctx->Const.PointSizeGranularity = POINT_SIZE_GRANULARITY; + ctx->Const.MinLineWidth = MIN_LINE_WIDTH; + ctx->Const.MaxLineWidth = MAX_LINE_WIDTH; + ctx->Const.MinLineWidthAA = MIN_LINE_WIDTH; + ctx->Const.MaxLineWidthAA = MAX_LINE_WIDTH; + ctx->Const.LineWidthGranularity = LINE_WIDTH_GRANULARITY; + ctx->Const.NumAuxBuffers = NUM_AUX_BUFFERS; + ctx->Const.MaxColorTableSize = MAX_COLOR_TABLE_SIZE; + ctx->Const.MaxConvolutionWidth = MAX_CONVOLUTION_WIDTH; + ctx->Const.MaxConvolutionHeight = MAX_CONVOLUTION_HEIGHT; + ctx->Const.NumCompressedTextureFormats = 0; + ctx->Const.MaxClipPlanes = MAX_CLIP_PLANES; + ctx->Const.MaxLights = MAX_LIGHTS; + + /* Modelview matrix */ + _math_matrix_ctr( &ctx->ModelView ); + _math_matrix_alloc_inv( &ctx->ModelView ); + + ctx->ModelViewStackDepth = 0; + for (i = 0; i < MAX_MODELVIEW_STACK_DEPTH - 1; i++) { + _math_matrix_ctr( &ctx->ModelViewStack[i] ); + _math_matrix_alloc_inv( &ctx->ModelViewStack[i] ); + } + + /* Projection matrix - need inv for user clipping in clip space*/ + _math_matrix_ctr( &ctx->ProjectionMatrix ); + _math_matrix_alloc_inv( &ctx->ProjectionMatrix ); + + ctx->ProjectionStackDepth = 0; + for (i = 0; i < MAX_PROJECTION_STACK_DEPTH - 1; i++) { + _math_matrix_ctr( &ctx->ProjectionStack[i] ); + _math_matrix_alloc_inv( &ctx->ProjectionStack[i] ); + } + + /* Derived ModelProject matrix */ + _math_matrix_ctr( &ctx->_ModelProjectMatrix ); + + /* Texture matrix */ + for (i = 0; i < MAX_TEXTURE_UNITS; i++) { + _math_matrix_ctr( &ctx->TextureMatrix[i] ); + ctx->TextureStackDepth[i] = 0; + for (j = 0; j < MAX_TEXTURE_STACK_DEPTH - 1; j++) { + _math_matrix_ctr( &ctx->TextureStack[i][j] ); + ctx->TextureStack[i][j].inv = 0; + } + } + + /* Color matrix */ + _math_matrix_ctr(&ctx->ColorMatrix); + ctx->ColorStackDepth = 0; + for (j = 0; j < MAX_COLOR_STACK_DEPTH - 1; j++) { + _math_matrix_ctr(&ctx->ColorStack[j]); + } + + /* Accumulate buffer group */ + ASSIGN_4V( ctx->Accum.ClearColor, 0.0, 0.0, 0.0, 0.0 ); + + /* Color buffer group */ + ctx->Color.IndexMask = 0xffffffff; + ctx->Color.ColorMask[0] = 0xff; + ctx->Color.ColorMask[1] = 0xff; + ctx->Color.ColorMask[2] = 0xff; + ctx->Color.ColorMask[3] = 0xff; + ctx->Color.ClearIndex = 0; + ASSIGN_4V( ctx->Color.ClearColor, 0, 0, 0, 0 ); + ctx->Color.DrawBuffer = GL_FRONT; + ctx->Color.AlphaEnabled = GL_FALSE; + ctx->Color.AlphaFunc = GL_ALWAYS; + ctx->Color.AlphaRef = 0; + ctx->Color.BlendEnabled = GL_FALSE; + ctx->Color.BlendSrcRGB = GL_ONE; + ctx->Color.BlendDstRGB = GL_ZERO; + ctx->Color.BlendSrcA = GL_ONE; + ctx->Color.BlendDstA = GL_ZERO; + ctx->Color.BlendEquation = GL_FUNC_ADD_EXT; + ASSIGN_4V( ctx->Color.BlendColor, 0.0, 0.0, 0.0, 0.0 ); + ctx->Color.IndexLogicOpEnabled = GL_FALSE; + ctx->Color.ColorLogicOpEnabled = GL_FALSE; + ctx->Color.LogicOp = GL_COPY; + ctx->Color.DitherFlag = GL_TRUE; + ctx->Color.MultiDrawBuffer = GL_FALSE; + + /* Current group */ + ASSIGN_4V( ctx->Current.Color, 1.0, 1.0, 1.0, 1.0 ); + ctx->Current.Index = 1; + for (i=0; iCurrent.Texcoord[i], 0.0, 0.0, 0.0, 1.0 ); + ASSIGN_4V( ctx->Current.RasterPos, 0.0, 0.0, 0.0, 1.0 ); + ctx->Current.RasterDistance = 0.0; + ASSIGN_4V( ctx->Current.RasterColor, 1.0, 1.0, 1.0, 1.0 ); + ctx->Current.RasterIndex = 1; + for (i=0; iCurrent.RasterMultiTexCoord[i], 0.0, 0.0, 0.0, 1.0 ); + ctx->Current.RasterTexCoord = ctx->Current.RasterMultiTexCoord[0]; + ctx->Current.RasterPosValid = GL_TRUE; + ctx->Current.EdgeFlag = GL_TRUE; + ASSIGN_3V( ctx->Current.Normal, 0.0, 0.0, 1.0 ); + + + /* Depth buffer group */ + ctx->Depth.Test = GL_FALSE; + ctx->Depth.Clear = 1.0; + ctx->Depth.Func = GL_LESS; + ctx->Depth.Mask = GL_TRUE; + ctx->Depth.OcclusionTest = GL_FALSE; + + /* Evaluators group */ + ctx->Eval.Map1Color4 = GL_FALSE; + ctx->Eval.Map1Index = GL_FALSE; + ctx->Eval.Map1Normal = GL_FALSE; + ctx->Eval.Map1TextureCoord1 = GL_FALSE; + ctx->Eval.Map1TextureCoord2 = GL_FALSE; + ctx->Eval.Map1TextureCoord3 = GL_FALSE; + ctx->Eval.Map1TextureCoord4 = GL_FALSE; + ctx->Eval.Map1Vertex3 = GL_FALSE; + ctx->Eval.Map1Vertex4 = GL_FALSE; + ctx->Eval.Map2Color4 = GL_FALSE; + ctx->Eval.Map2Index = GL_FALSE; + ctx->Eval.Map2Normal = GL_FALSE; + ctx->Eval.Map2TextureCoord1 = GL_FALSE; + ctx->Eval.Map2TextureCoord2 = GL_FALSE; + ctx->Eval.Map2TextureCoord3 = GL_FALSE; + ctx->Eval.Map2TextureCoord4 = GL_FALSE; + ctx->Eval.Map2Vertex3 = GL_FALSE; + ctx->Eval.Map2Vertex4 = GL_FALSE; + ctx->Eval.AutoNormal = GL_FALSE; + ctx->Eval.MapGrid1un = 1; + ctx->Eval.MapGrid1u1 = 0.0; + ctx->Eval.MapGrid1u2 = 1.0; + ctx->Eval.MapGrid2un = 1; + ctx->Eval.MapGrid2vn = 1; + ctx->Eval.MapGrid2u1 = 0.0; + ctx->Eval.MapGrid2u2 = 1.0; + ctx->Eval.MapGrid2v1 = 0.0; + ctx->Eval.MapGrid2v2 = 1.0; + + /* Evaluator data */ + { + static GLfloat vertex[4] = { 0.0, 0.0, 0.0, 1.0 }; + static GLfloat normal[3] = { 0.0, 0.0, 1.0 }; + static GLfloat index[1] = { 1.0 }; + static GLfloat color[4] = { 1.0, 1.0, 1.0, 1.0 }; + static GLfloat texcoord[4] = { 0.0, 0.0, 0.0, 1.0 }; + + init_1d_map( &ctx->EvalMap.Map1Vertex3, 3, vertex ); + init_1d_map( &ctx->EvalMap.Map1Vertex4, 4, vertex ); + init_1d_map( &ctx->EvalMap.Map1Index, 1, index ); + init_1d_map( &ctx->EvalMap.Map1Color4, 4, color ); + init_1d_map( &ctx->EvalMap.Map1Normal, 3, normal ); + init_1d_map( &ctx->EvalMap.Map1Texture1, 1, texcoord ); + init_1d_map( &ctx->EvalMap.Map1Texture2, 2, texcoord ); + init_1d_map( &ctx->EvalMap.Map1Texture3, 3, texcoord ); + init_1d_map( &ctx->EvalMap.Map1Texture4, 4, texcoord ); + + init_2d_map( &ctx->EvalMap.Map2Vertex3, 3, vertex ); + init_2d_map( &ctx->EvalMap.Map2Vertex4, 4, vertex ); + init_2d_map( &ctx->EvalMap.Map2Index, 1, index ); + init_2d_map( &ctx->EvalMap.Map2Color4, 4, color ); + init_2d_map( &ctx->EvalMap.Map2Normal, 3, normal ); + init_2d_map( &ctx->EvalMap.Map2Texture1, 1, texcoord ); + init_2d_map( &ctx->EvalMap.Map2Texture2, 2, texcoord ); + init_2d_map( &ctx->EvalMap.Map2Texture3, 3, texcoord ); + init_2d_map( &ctx->EvalMap.Map2Texture4, 4, texcoord ); + } + + /* Fog group */ + ctx->Fog.Enabled = GL_FALSE; + ctx->Fog.Mode = GL_EXP; + ASSIGN_4V( ctx->Fog.Color, 0.0, 0.0, 0.0, 0.0 ); + ctx->Fog.Index = 0.0; + ctx->Fog.Density = 1.0; + ctx->Fog.Start = 0.0; + ctx->Fog.End = 1.0; + ctx->Fog.ColorSumEnabled = GL_FALSE; + ctx->Fog.FogCoordinateSource = GL_FRAGMENT_DEPTH_EXT; + + /* Hint group */ + ctx->Hint.PerspectiveCorrection = GL_DONT_CARE; + ctx->Hint.PointSmooth = GL_DONT_CARE; + ctx->Hint.LineSmooth = GL_DONT_CARE; + ctx->Hint.PolygonSmooth = GL_DONT_CARE; + ctx->Hint.Fog = GL_DONT_CARE; + ctx->Hint.ClipVolumeClipping = GL_DONT_CARE; + ctx->Hint.TextureCompression = GL_DONT_CARE; + ctx->Hint.GenerateMipmap = GL_DONT_CARE; + + /* Histogram group */ + ctx->Histogram.Width = 0; + ctx->Histogram.Format = GL_RGBA; + ctx->Histogram.Sink = GL_FALSE; + ctx->Histogram.RedSize = 0; + ctx->Histogram.GreenSize = 0; + ctx->Histogram.BlueSize = 0; + ctx->Histogram.AlphaSize = 0; + ctx->Histogram.LuminanceSize = 0; + for (i = 0; i < HISTOGRAM_TABLE_SIZE; i++) { + ctx->Histogram.Count[i][0] = 0; + ctx->Histogram.Count[i][1] = 0; + ctx->Histogram.Count[i][2] = 0; + ctx->Histogram.Count[i][3] = 0; + } + + /* Min/Max group */ + ctx->MinMax.Format = GL_RGBA; + ctx->MinMax.Sink = GL_FALSE; + ctx->MinMax.Min[RCOMP] = 1000; ctx->MinMax.Max[RCOMP] = -1000; + ctx->MinMax.Min[GCOMP] = 1000; ctx->MinMax.Max[GCOMP] = -1000; + ctx->MinMax.Min[BCOMP] = 1000; ctx->MinMax.Max[BCOMP] = -1000; + ctx->MinMax.Min[ACOMP] = 1000; ctx->MinMax.Max[ACOMP] = -1000; + + /* Extensions */ + _mesa_extensions_ctr( ctx ); + + /* Lighting group */ + for (i=0;iLight.Light[i], i ); + } + make_empty_list( &ctx->Light.EnabledList ); + + init_lightmodel( &ctx->Light.Model ); + init_material( &ctx->Light.Material[0] ); + init_material( &ctx->Light.Material[1] ); + ctx->Light.ShadeModel = GL_SMOOTH; + ctx->Light.Enabled = GL_FALSE; + ctx->Light.ColorMaterialFace = GL_FRONT_AND_BACK; + ctx->Light.ColorMaterialMode = GL_AMBIENT_AND_DIFFUSE; + ctx->Light.ColorMaterialBitmask = _mesa_material_bitmask( ctx, + GL_FRONT_AND_BACK, + GL_AMBIENT_AND_DIFFUSE, ~0, 0 ); + + ctx->Light.ColorMaterialEnabled = GL_FALSE; + + /* Lighting miscellaneous */ + ctx->_ShineTabList = MALLOC_STRUCT( gl_shine_tab ); + make_empty_list( ctx->_ShineTabList ); + for (i = 0 ; i < 10 ; i++) { + struct gl_shine_tab *s = MALLOC_STRUCT( gl_shine_tab ); + s->shininess = -1; + s->refcount = 0; + insert_at_tail( ctx->_ShineTabList, s ); + } + + + /* Line group */ + ctx->Line.SmoothFlag = GL_FALSE; + ctx->Line.StippleFlag = GL_FALSE; + ctx->Line.Width = 1.0; + ctx->Line._Width = 1.0; + ctx->Line.StipplePattern = 0xffff; + ctx->Line.StippleFactor = 1; + + /* Display List group */ + ctx->List.ListBase = 0; + + /* Multisample */ + ctx->Multisample.Enabled = GL_FALSE; + ctx->Multisample.SampleAlphaToCoverage = GL_FALSE; + ctx->Multisample.SampleAlphaToOne = GL_FALSE; + ctx->Multisample.SampleCoverage = GL_FALSE; + ctx->Multisample.SampleCoverageValue = 1.0; + ctx->Multisample.SampleCoverageInvert = GL_FALSE; + + /* Pixel group */ + ctx->Pixel.RedBias = 0.0; + ctx->Pixel.RedScale = 1.0; + ctx->Pixel.GreenBias = 0.0; + ctx->Pixel.GreenScale = 1.0; + ctx->Pixel.BlueBias = 0.0; + ctx->Pixel.BlueScale = 1.0; + ctx->Pixel.AlphaBias = 0.0; + ctx->Pixel.AlphaScale = 1.0; + ctx->Pixel.DepthBias = 0.0; + ctx->Pixel.DepthScale = 1.0; + ctx->Pixel.IndexOffset = 0; + ctx->Pixel.IndexShift = 0; + ctx->Pixel.ZoomX = 1.0; + ctx->Pixel.ZoomY = 1.0; + ctx->Pixel.MapColorFlag = GL_FALSE; + ctx->Pixel.MapStencilFlag = GL_FALSE; + ctx->Pixel.MapStoSsize = 1; + ctx->Pixel.MapItoIsize = 1; + ctx->Pixel.MapItoRsize = 1; + ctx->Pixel.MapItoGsize = 1; + ctx->Pixel.MapItoBsize = 1; + ctx->Pixel.MapItoAsize = 1; + ctx->Pixel.MapRtoRsize = 1; + ctx->Pixel.MapGtoGsize = 1; + ctx->Pixel.MapBtoBsize = 1; + ctx->Pixel.MapAtoAsize = 1; + ctx->Pixel.MapStoS[0] = 0; + ctx->Pixel.MapItoI[0] = 0; + ctx->Pixel.MapItoR[0] = 0.0; + ctx->Pixel.MapItoG[0] = 0.0; + ctx->Pixel.MapItoB[0] = 0.0; + ctx->Pixel.MapItoA[0] = 0.0; + ctx->Pixel.MapItoR8[0] = 0; + ctx->Pixel.MapItoG8[0] = 0; + ctx->Pixel.MapItoB8[0] = 0; + ctx->Pixel.MapItoA8[0] = 0; + ctx->Pixel.MapRtoR[0] = 0.0; + ctx->Pixel.MapGtoG[0] = 0.0; + ctx->Pixel.MapBtoB[0] = 0.0; + ctx->Pixel.MapAtoA[0] = 0.0; + ctx->Pixel.HistogramEnabled = GL_FALSE; + ctx->Pixel.MinMaxEnabled = GL_FALSE; + ctx->Pixel.PixelTextureEnabled = GL_FALSE; + ctx->Pixel.FragmentRgbSource = GL_PIXEL_GROUP_COLOR_SGIS; + ctx->Pixel.FragmentAlphaSource = GL_PIXEL_GROUP_COLOR_SGIS; + ASSIGN_4V(ctx->Pixel.PostColorMatrixScale, 1.0, 1.0, 1.0, 1.0); + ASSIGN_4V(ctx->Pixel.PostColorMatrixBias, 0.0, 0.0, 0.0, 0.0); + ASSIGN_4V(ctx->Pixel.ColorTableScale, 1.0, 1.0, 1.0, 1.0); + ASSIGN_4V(ctx->Pixel.ColorTableBias, 0.0, 0.0, 0.0, 0.0); + ASSIGN_4V(ctx->Pixel.PCCTscale, 1.0, 1.0, 1.0, 1.0); + ASSIGN_4V(ctx->Pixel.PCCTbias, 0.0, 0.0, 0.0, 0.0); + ASSIGN_4V(ctx->Pixel.PCMCTscale, 1.0, 1.0, 1.0, 1.0); + ASSIGN_4V(ctx->Pixel.PCMCTbias, 0.0, 0.0, 0.0, 0.0); + ctx->Pixel.ColorTableEnabled = GL_FALSE; + ctx->Pixel.PostConvolutionColorTableEnabled = GL_FALSE; + ctx->Pixel.PostColorMatrixColorTableEnabled = GL_FALSE; + ctx->Pixel.Convolution1DEnabled = GL_FALSE; + ctx->Pixel.Convolution2DEnabled = GL_FALSE; + ctx->Pixel.Separable2DEnabled = GL_FALSE; + for (i = 0; i < 3; i++) { + ASSIGN_4V(ctx->Pixel.ConvolutionBorderColor[i], 0.0, 0.0, 0.0, 0.0); + ctx->Pixel.ConvolutionBorderMode[i] = GL_REDUCE; + ASSIGN_4V(ctx->Pixel.ConvolutionFilterScale[i], 1.0, 1.0, 1.0, 1.0); + ASSIGN_4V(ctx->Pixel.ConvolutionFilterBias[i], 0.0, 0.0, 0.0, 0.0); + } + for (i = 0; i < MAX_CONVOLUTION_WIDTH * MAX_CONVOLUTION_WIDTH * 4; i++) { + ctx->Convolution1D.Filter[i] = 0.0; + ctx->Convolution2D.Filter[i] = 0.0; + ctx->Separable2D.Filter[i] = 0.0; + } + ASSIGN_4V(ctx->Pixel.PostConvolutionScale, 1.0, 1.0, 1.0, 1.0); + ASSIGN_4V(ctx->Pixel.PostConvolutionBias, 0.0, 0.0, 0.0, 0.0); + + /* Point group */ + ctx->Point.SmoothFlag = GL_FALSE; + ctx->Point.Size = 1.0; + ctx->Point._Size = 1.0; + ctx->Point.Params[0] = 1.0; + ctx->Point.Params[1] = 0.0; + ctx->Point.Params[2] = 0.0; + ctx->Point._Attenuated = GL_FALSE; + ctx->Point.MinSize = 0.0; + ctx->Point.MaxSize = ctx->Const.MaxPointSize; + ctx->Point.Threshold = 1.0; + + /* Polygon group */ + ctx->Polygon.CullFlag = GL_FALSE; + ctx->Polygon.CullFaceMode = GL_BACK; + ctx->Polygon.FrontFace = GL_CCW; + ctx->Polygon._FrontBit = 0; + ctx->Polygon.FrontMode = GL_FILL; + ctx->Polygon.BackMode = GL_FILL; + ctx->Polygon.SmoothFlag = GL_FALSE; + ctx->Polygon.StippleFlag = GL_FALSE; + ctx->Polygon.OffsetFactor = 0.0F; + ctx->Polygon.OffsetUnits = 0.0F; + ctx->Polygon.OffsetMRD = 0.0F; + ctx->Polygon.OffsetPoint = GL_FALSE; + ctx->Polygon.OffsetLine = GL_FALSE; + ctx->Polygon.OffsetFill = GL_FALSE; + + /* Polygon Stipple group */ + MEMSET( ctx->PolygonStipple, 0xff, 32*sizeof(GLuint) ); + + /* Scissor group */ + ctx->Scissor.Enabled = GL_FALSE; + ctx->Scissor.X = 0; + ctx->Scissor.Y = 0; + ctx->Scissor.Width = 0; + ctx->Scissor.Height = 0; + + /* Stencil group */ + ctx->Stencil.Enabled = GL_FALSE; + ctx->Stencil.Function = GL_ALWAYS; + ctx->Stencil.FailFunc = GL_KEEP; + ctx->Stencil.ZPassFunc = GL_KEEP; + ctx->Stencil.ZFailFunc = GL_KEEP; + ctx->Stencil.Ref = 0; + ctx->Stencil.ValueMask = STENCIL_MAX; + ctx->Stencil.Clear = 0; + ctx->Stencil.WriteMask = STENCIL_MAX; + + /* Texture group */ + ctx->Texture.CurrentUnit = 0; /* multitexture */ + ctx->Texture._ReallyEnabled = 0; + for (i=0; iTexture.SharedPalette = GL_FALSE; + _mesa_init_colortable(&ctx->Texture.Palette); + + /* Transformation group */ + ctx->Transform.MatrixMode = GL_MODELVIEW; + ctx->Transform.Normalize = GL_FALSE; + ctx->Transform.RescaleNormals = GL_FALSE; + for (i=0;iTransform.ClipEnabled[i] = GL_FALSE; + ASSIGN_4V( ctx->Transform.EyeUserPlane[i], 0.0, 0.0, 0.0, 0.0 ); + } + ctx->Transform._AnyClip = GL_FALSE; + + /* Viewport group */ + ctx->Viewport.X = 0; + ctx->Viewport.Y = 0; + ctx->Viewport.Width = 0; + ctx->Viewport.Height = 0; + ctx->Viewport.Near = 0.0; + ctx->Viewport.Far = 1.0; + _math_matrix_ctr(&ctx->Viewport._WindowMap); + +#define Sz 10 +#define Tz 14 + ctx->Viewport._WindowMap.m[Sz] = 0.5 * ctx->DepthMaxF; + ctx->Viewport._WindowMap.m[Tz] = 0.5 * ctx->DepthMaxF; +#undef Sz +#undef Tz + + ctx->Viewport._WindowMap.flags = MAT_FLAG_GENERAL_SCALE|MAT_FLAG_TRANSLATION; + ctx->Viewport._WindowMap.type = MATRIX_3D_NO_ROT; + + /* Vertex arrays */ + ctx->Array.Vertex.Size = 4; + ctx->Array.Vertex.Type = GL_FLOAT; + ctx->Array.Vertex.Stride = 0; + ctx->Array.Vertex.StrideB = 0; + ctx->Array.Vertex.Ptr = NULL; + ctx->Array.Vertex.Enabled = GL_FALSE; + ctx->Array.Vertex.Flags = CA_CLIENT_DATA; + ctx->Array.Normal.Type = GL_FLOAT; + ctx->Array.Normal.Stride = 0; + ctx->Array.Normal.StrideB = 0; + ctx->Array.Normal.Ptr = NULL; + ctx->Array.Normal.Enabled = GL_FALSE; + ctx->Array.Normal.Flags = CA_CLIENT_DATA; + ctx->Array.Color.Size = 4; + ctx->Array.Color.Type = GL_FLOAT; + ctx->Array.Color.Stride = 0; + ctx->Array.Color.StrideB = 0; + ctx->Array.Color.Ptr = NULL; + ctx->Array.Color.Enabled = GL_FALSE; + ctx->Array.Color.Flags = CA_CLIENT_DATA; + ctx->Array.SecondaryColor.Size = 4; + ctx->Array.SecondaryColor.Type = GL_FLOAT; + ctx->Array.SecondaryColor.Stride = 0; + ctx->Array.SecondaryColor.StrideB = 0; + ctx->Array.SecondaryColor.Ptr = NULL; + ctx->Array.SecondaryColor.Enabled = GL_FALSE; + ctx->Array.SecondaryColor.Flags = CA_CLIENT_DATA; + ctx->Array.FogCoord.Size = 1; + ctx->Array.FogCoord.Type = GL_FLOAT; + ctx->Array.FogCoord.Stride = 0; + ctx->Array.FogCoord.StrideB = 0; + ctx->Array.FogCoord.Ptr = NULL; + ctx->Array.FogCoord.Enabled = GL_FALSE; + ctx->Array.FogCoord.Flags = CA_CLIENT_DATA; + ctx->Array.Index.Type = GL_FLOAT; + ctx->Array.Index.Stride = 0; + ctx->Array.Index.StrideB = 0; + ctx->Array.Index.Ptr = NULL; + ctx->Array.Index.Enabled = GL_FALSE; + ctx->Array.Index.Flags = CA_CLIENT_DATA; + for (i = 0; i < MAX_TEXTURE_UNITS; i++) { + ctx->Array.TexCoord[i].Size = 4; + ctx->Array.TexCoord[i].Type = GL_FLOAT; + ctx->Array.TexCoord[i].Stride = 0; + ctx->Array.TexCoord[i].StrideB = 0; + ctx->Array.TexCoord[i].Ptr = NULL; + ctx->Array.TexCoord[i].Enabled = GL_FALSE; + ctx->Array.TexCoord[i].Flags = CA_CLIENT_DATA; + } + ctx->Array.TexCoordInterleaveFactor = 1; + ctx->Array.EdgeFlag.Stride = 0; + ctx->Array.EdgeFlag.StrideB = 0; + ctx->Array.EdgeFlag.Ptr = NULL; + ctx->Array.EdgeFlag.Enabled = GL_FALSE; + ctx->Array.EdgeFlag.Flags = CA_CLIENT_DATA; + ctx->Array.ActiveTexture = 0; /* GL_ARB_multitexture */ + + /* Pixel transfer */ + ctx->Pack.Alignment = 4; + ctx->Pack.RowLength = 0; + ctx->Pack.ImageHeight = 0; + ctx->Pack.SkipPixels = 0; + ctx->Pack.SkipRows = 0; + ctx->Pack.SkipImages = 0; + ctx->Pack.SwapBytes = GL_FALSE; + ctx->Pack.LsbFirst = GL_FALSE; + ctx->Unpack.Alignment = 4; + ctx->Unpack.RowLength = 0; + ctx->Unpack.ImageHeight = 0; + ctx->Unpack.SkipPixels = 0; + ctx->Unpack.SkipRows = 0; + ctx->Unpack.SkipImages = 0; + ctx->Unpack.SwapBytes = GL_FALSE; + ctx->Unpack.LsbFirst = GL_FALSE; + + /* Feedback */ + ctx->Feedback.Type = GL_2D; /* TODO: verify */ + ctx->Feedback.Buffer = NULL; + ctx->Feedback.BufferSize = 0; + ctx->Feedback.Count = 0; + + /* Selection/picking */ + ctx->Select.Buffer = NULL; + ctx->Select.BufferSize = 0; + ctx->Select.BufferCount = 0; + ctx->Select.Hits = 0; + ctx->Select.NameStackDepth = 0; + + /* Renderer and client attribute stacks */ + ctx->AttribStackDepth = 0; + ctx->ClientAttribStackDepth = 0; + + /* Display list */ + ctx->CallDepth = 0; + ctx->ExecuteFlag = GL_TRUE; + ctx->CompileFlag = GL_FALSE; + ctx->CurrentListPtr = NULL; + ctx->CurrentBlock = NULL; + ctx->CurrentListNum = 0; + ctx->CurrentPos = 0; + + /* Color tables */ + _mesa_init_colortable(&ctx->ColorTable); + _mesa_init_colortable(&ctx->ProxyColorTable); + _mesa_init_colortable(&ctx->PostConvolutionColorTable); + _mesa_init_colortable(&ctx->ProxyPostConvolutionColorTable); + _mesa_init_colortable(&ctx->PostColorMatrixColorTable); + _mesa_init_colortable(&ctx->ProxyPostColorMatrixColorTable); + + /* Miscellaneous */ + ctx->NewState = _NEW_ALL; + ctx->RenderMode = GL_RENDER; + ctx->_ImageTransferState = 0; + + ctx->_NeedNormals = 0; + ctx->_NeedEyeCoords = 0; + ctx->_ModelViewInvScale = 1.0; + + ctx->ErrorValue = (GLenum) GL_NO_ERROR; + + ctx->CatchSignals = GL_TRUE; + ctx->OcclusionResult = GL_FALSE; + ctx->OcclusionResultSaved = GL_FALSE; + + /* For debug/development only */ + ctx->NoRaster = getenv("MESA_NO_RASTER") ? GL_TRUE : GL_FALSE; + ctx->FirstTimeCurrent = GL_TRUE; + + /* Dither disable */ + ctx->NoDither = getenv("MESA_NO_DITHER") ? GL_TRUE : GL_FALSE; + if (ctx->NoDither) { + if (getenv("MESA_DEBUG")) { + fprintf(stderr, "MESA_NO_DITHER set - dithering disabled\n"); + } + ctx->Color.DitherFlag = GL_FALSE; + } +} + + + + +/* + * Allocate the proxy textures. If we run out of memory part way through + * the allocations clean up and return GL_FALSE. + * Return: GL_TRUE=success, GL_FALSE=failure + */ +static GLboolean +alloc_proxy_textures( GLcontext *ctx ) +{ + GLboolean out_of_memory; + GLint i; + + ctx->Texture.Proxy1D = _mesa_alloc_texture_object(NULL, 0, 1); + if (!ctx->Texture.Proxy1D) { + return GL_FALSE; + } + + ctx->Texture.Proxy2D = _mesa_alloc_texture_object(NULL, 0, 2); + if (!ctx->Texture.Proxy2D) { + _mesa_free_texture_object(NULL, ctx->Texture.Proxy1D); + return GL_FALSE; + } + + ctx->Texture.Proxy3D = _mesa_alloc_texture_object(NULL, 0, 3); + if (!ctx->Texture.Proxy3D) { + _mesa_free_texture_object(NULL, ctx->Texture.Proxy1D); + _mesa_free_texture_object(NULL, ctx->Texture.Proxy2D); + return GL_FALSE; + } + + ctx->Texture.ProxyCubeMap = _mesa_alloc_texture_object(NULL, 0, 6); + if (!ctx->Texture.ProxyCubeMap) { + _mesa_free_texture_object(NULL, ctx->Texture.Proxy1D); + _mesa_free_texture_object(NULL, ctx->Texture.Proxy2D); + _mesa_free_texture_object(NULL, ctx->Texture.Proxy3D); + return GL_FALSE; + } + + out_of_memory = GL_FALSE; + for (i=0;iTexture.Proxy1D->Image[i] = _mesa_alloc_texture_image(); + ctx->Texture.Proxy2D->Image[i] = _mesa_alloc_texture_image(); + ctx->Texture.Proxy3D->Image[i] = _mesa_alloc_texture_image(); + if (!ctx->Texture.Proxy1D->Image[i] + || !ctx->Texture.Proxy2D->Image[i] + || !ctx->Texture.Proxy3D->Image[i]) { + out_of_memory = GL_TRUE; + } + } + if (out_of_memory) { + for (i=0;iTexture.Proxy1D->Image[i]) { + _mesa_free_texture_image(ctx->Texture.Proxy1D->Image[i]); + } + if (ctx->Texture.Proxy2D->Image[i]) { + _mesa_free_texture_image(ctx->Texture.Proxy2D->Image[i]); + } + if (ctx->Texture.Proxy3D->Image[i]) { + _mesa_free_texture_image(ctx->Texture.Proxy3D->Image[i]); + } + } + _mesa_free_texture_object(NULL, ctx->Texture.Proxy1D); + _mesa_free_texture_object(NULL, ctx->Texture.Proxy2D); + _mesa_free_texture_object(NULL, ctx->Texture.Proxy3D); + return GL_FALSE; + } + else { + return GL_TRUE; + } +} + + +/* + * Initialize a GLcontext struct. This includes allocating all the + * other structs and arrays which hang off of the context by pointers. + */ +GLboolean +_mesa_initialize_context( GLcontext *ctx, + const GLvisual *visual, + GLcontext *share_list, + void *driver_ctx, + GLboolean direct ) +{ + GLuint dispatchSize; + + (void) direct; /* not used */ + + /* misc one-time initializations */ + one_time_init(); + + /** + ** OpenGL SI stuff + **/ + if (!ctx->imports.malloc) { + _mesa_InitDefaultImports(&ctx->imports, driver_ctx, NULL); + } + /* exports are setup by the device driver */ + + ctx->DriverCtx = driver_ctx; + ctx->Visual = *visual; + ctx->DrawBuffer = NULL; + ctx->ReadBuffer = NULL; + + if (share_list) { + /* share state with another context */ + ctx->Shared = share_list->Shared; + } + else { + /* allocate new, unshared state */ + ctx->Shared = alloc_shared_state(); + if (!ctx->Shared) { + return GL_FALSE; + } + } + _glthread_LOCK_MUTEX(ctx->Shared->Mutex); + ctx->Shared->RefCount++; + _glthread_UNLOCK_MUTEX(ctx->Shared->Mutex); + + /* Effectively bind the default textures to all texture units */ + ctx->Shared->Default1D->RefCount += MAX_TEXTURE_UNITS; + ctx->Shared->Default2D->RefCount += MAX_TEXTURE_UNITS; + ctx->Shared->Default3D->RefCount += MAX_TEXTURE_UNITS; + ctx->Shared->DefaultCubeMap->RefCount += MAX_TEXTURE_UNITS; + + init_attrib_groups( ctx ); + + if (visual->doubleBufferMode) { + ctx->Color.DrawBuffer = GL_BACK; + ctx->Color.DriverDrawBuffer = GL_BACK_LEFT; + ctx->Color.DrawDestMask = BACK_LEFT_BIT; + ctx->Pixel.ReadBuffer = GL_BACK; + ctx->Pixel.DriverReadBuffer = GL_BACK_LEFT; + } + else { + ctx->Color.DrawBuffer = GL_FRONT; + ctx->Color.DriverDrawBuffer = GL_FRONT_LEFT; + ctx->Color.DrawDestMask = FRONT_LEFT_BIT; + ctx->Pixel.ReadBuffer = GL_FRONT; + ctx->Pixel.DriverReadBuffer = GL_FRONT_LEFT; + } + + if (!alloc_proxy_textures(ctx)) { + free_shared_state(ctx, ctx->Shared); + return GL_FALSE; + } + + /* register the most recent extension functions with libGL */ + _glapi_add_entrypoint("glTbufferMask3DFX", 553); + _glapi_add_entrypoint("glCompressedTexImage3DARB", 554); + _glapi_add_entrypoint("glCompressedTexImage2DARB", 555); + _glapi_add_entrypoint("glCompressedTexImage1DARB", 556); + _glapi_add_entrypoint("glCompressedTexSubImage3DARB", 557); + _glapi_add_entrypoint("glCompressedTexSubImage2DARB", 558); + _glapi_add_entrypoint("glCompressedTexSubImage1DARB", 559); + _glapi_add_entrypoint("glGetCompressedTexImageARB", 560); + + /* Find the larger of Mesa's dispatch table and libGL's dispatch table. + * In practice, this'll be the same for stand-alone Mesa. But for DRI + * Mesa we do this to accomodate different versions of libGL and various + * DRI drivers. + */ + dispatchSize = MAX2(_glapi_get_dispatch_table_size(), + sizeof(struct _glapi_table) / sizeof(void *)); + + /* setup API dispatch tables */ + ctx->Exec = (struct _glapi_table *) CALLOC(dispatchSize * sizeof(void*)); + ctx->Save = (struct _glapi_table *) CALLOC(dispatchSize * sizeof(void*)); + if (!ctx->Exec || !ctx->Save) { + free_shared_state(ctx, ctx->Shared); + if (ctx->Exec) + FREE( ctx->Exec ); + } + _mesa_init_exec_table(ctx->Exec, dispatchSize); + _mesa_init_dlist_table(ctx->Save, dispatchSize); + ctx->CurrentDispatch = ctx->Exec; + + ctx->ExecPrefersFloat = GL_FALSE; + ctx->SavePrefersFloat = GL_FALSE; + + /* Neutral tnl module stuff */ + _mesa_init_exec_vtxfmt( ctx ); + ctx->TnlModule.Current = NULL; + ctx->TnlModule.SwapCount = 0; + + /* Z buffer stuff */ + if (ctx->Visual.depthBits == 0) { + /* Special case. Even if we don't have a depth buffer we need + * good values for DepthMax for Z vertex transformation purposes + * and for per-fragment fog computation. + */ + ctx->DepthMax = 1 << 16; + ctx->DepthMaxF = (GLfloat) ctx->DepthMax; + } + else if (ctx->Visual.depthBits < 32) { + ctx->DepthMax = (1 << ctx->Visual.depthBits) - 1; + ctx->DepthMaxF = (GLfloat) ctx->DepthMax; + } + else { + /* Special case since shift values greater than or equal to the + * number of bits in the left hand expression's type are undefined. + */ + ctx->DepthMax = 0xffffffff; + ctx->DepthMaxF = (GLfloat) ctx->DepthMax; + } + ctx->MRD = 1.0; /* Minimum resolvable depth value, for polygon offset */ + + +#if defined(MESA_TRACE) + ctx->TraceCtx = (trace_context_t *) CALLOC( sizeof(trace_context_t) ); +#if 0 + /* Brian: do you want to have CreateContext fail here, + or should we just trap in NewTrace (currently done)? */ + if (!(ctx->TraceCtx)) { + free_shared_state(ctx, ctx->Shared); + FREE( ctx->Exec ); + FREE( ctx->Save ); + return GL_FALSE; + } +#endif + trInitContext(ctx->TraceCtx); + + ctx->TraceDispatch = (struct _glapi_table *) + CALLOC(dispatchSize * sizeof(void*)); +#if 0 + if (!(ctx->TraceCtx)) { + free_shared_state(ctx, ctx->Shared); + FREE( ctx->Exec ); + FREE( ctx->Save ); + FREE( ctx->TraceCtx ); + return GL_FALSE; + } +#endif + trInitDispatch(ctx->TraceDispatch); +#endif + + return GL_TRUE; +} + + + +/* + * Allocate and initialize a GLcontext structure. + * Input: visual - a GLvisual pointer (we copy the struct contents) + * sharelist - another context to share display lists with or NULL + * driver_ctx - pointer to device driver's context state struct + * Return: pointer to a new __GLcontextRec or NULL if error. + */ +GLcontext * +_mesa_create_context( const GLvisual *visual, + GLcontext *share_list, + void *driver_ctx, + GLboolean direct ) +{ + GLcontext *ctx = (GLcontext *) CALLOC( sizeof(GLcontext) ); + if (!ctx) { + return NULL; + } + + if (_mesa_initialize_context(ctx, visual, share_list, driver_ctx, direct)) { + return ctx; + } + else { + FREE(ctx); + return NULL; + } +} + + + +/* + * Free the data associated with the given context. + * But don't free() the GLcontext struct itself! + */ +void +_mesa_free_context_data( GLcontext *ctx ) +{ + struct gl_shine_tab *s, *tmps; + GLuint i, j; + + /* if we're destroying the current context, unbind it first */ + if (ctx == _mesa_get_current_context()) { + _mesa_make_current(NULL, NULL); + } + + _math_matrix_dtr( &ctx->ModelView ); + for (i = 0; i < MAX_MODELVIEW_STACK_DEPTH - 1; i++) { + _math_matrix_dtr( &ctx->ModelViewStack[i] ); + } + _math_matrix_dtr( &ctx->ProjectionMatrix ); + for (i = 0; i < MAX_PROJECTION_STACK_DEPTH - 1; i++) { + _math_matrix_dtr( &ctx->ProjectionStack[i] ); + } + for (i = 0; i < MAX_TEXTURE_UNITS; i++) { + _math_matrix_dtr( &ctx->TextureMatrix[i] ); + for (j = 0; j < MAX_TEXTURE_STACK_DEPTH - 1; j++) { + _math_matrix_dtr( &ctx->TextureStack[i][j] ); + } + } + + _glthread_LOCK_MUTEX(ctx->Shared->Mutex); + ctx->Shared->RefCount--; + assert(ctx->Shared->RefCount >= 0); + _glthread_UNLOCK_MUTEX(ctx->Shared->Mutex); + if (ctx->Shared->RefCount == 0) { + /* free shared state */ + free_shared_state( ctx, ctx->Shared ); + } + + foreach_s( s, tmps, ctx->_ShineTabList ) { + FREE( s ); + } + FREE( ctx->_ShineTabList ); + + /* Free proxy texture objects */ + _mesa_free_texture_object( NULL, ctx->Texture.Proxy1D ); + _mesa_free_texture_object( NULL, ctx->Texture.Proxy2D ); + _mesa_free_texture_object( NULL, ctx->Texture.Proxy3D ); + + /* Free evaluator data */ + if (ctx->EvalMap.Map1Vertex3.Points) + FREE( ctx->EvalMap.Map1Vertex3.Points ); + if (ctx->EvalMap.Map1Vertex4.Points) + FREE( ctx->EvalMap.Map1Vertex4.Points ); + if (ctx->EvalMap.Map1Index.Points) + FREE( ctx->EvalMap.Map1Index.Points ); + if (ctx->EvalMap.Map1Color4.Points) + FREE( ctx->EvalMap.Map1Color4.Points ); + if (ctx->EvalMap.Map1Normal.Points) + FREE( ctx->EvalMap.Map1Normal.Points ); + if (ctx->EvalMap.Map1Texture1.Points) + FREE( ctx->EvalMap.Map1Texture1.Points ); + if (ctx->EvalMap.Map1Texture2.Points) + FREE( ctx->EvalMap.Map1Texture2.Points ); + if (ctx->EvalMap.Map1Texture3.Points) + FREE( ctx->EvalMap.Map1Texture3.Points ); + if (ctx->EvalMap.Map1Texture4.Points) + FREE( ctx->EvalMap.Map1Texture4.Points ); + + if (ctx->EvalMap.Map2Vertex3.Points) + FREE( ctx->EvalMap.Map2Vertex3.Points ); + if (ctx->EvalMap.Map2Vertex4.Points) + FREE( ctx->EvalMap.Map2Vertex4.Points ); + if (ctx->EvalMap.Map2Index.Points) + FREE( ctx->EvalMap.Map2Index.Points ); + if (ctx->EvalMap.Map2Color4.Points) + FREE( ctx->EvalMap.Map2Color4.Points ); + if (ctx->EvalMap.Map2Normal.Points) + FREE( ctx->EvalMap.Map2Normal.Points ); + if (ctx->EvalMap.Map2Texture1.Points) + FREE( ctx->EvalMap.Map2Texture1.Points ); + if (ctx->EvalMap.Map2Texture2.Points) + FREE( ctx->EvalMap.Map2Texture2.Points ); + if (ctx->EvalMap.Map2Texture3.Points) + FREE( ctx->EvalMap.Map2Texture3.Points ); + if (ctx->EvalMap.Map2Texture4.Points) + FREE( ctx->EvalMap.Map2Texture4.Points ); + + _mesa_free_colortable_data( &ctx->ColorTable ); + _mesa_free_colortable_data( &ctx->PostConvolutionColorTable ); + _mesa_free_colortable_data( &ctx->PostColorMatrixColorTable ); + _mesa_free_colortable_data( &ctx->Texture.Palette ); + + _mesa_extensions_dtr(ctx); + + FREE(ctx->Exec); + FREE(ctx->Save); +} + + + +/* + * Destroy a GLcontext structure. + */ +void +_mesa_destroy_context( GLcontext *ctx ) +{ + if (ctx) { + _mesa_free_context_data(ctx); + FREE( (void *) ctx ); + } +} + + + +/* + * Copy attribute groups from one context to another. + * Input: src - source context + * dst - destination context + * mask - bitwise OR of GL_*_BIT flags + */ +void +_mesa_copy_context( const GLcontext *src, GLcontext *dst, GLuint mask ) +{ + if (mask & GL_ACCUM_BUFFER_BIT) { + MEMCPY( &dst->Accum, &src->Accum, sizeof(struct gl_accum_attrib) ); + } + if (mask & GL_COLOR_BUFFER_BIT) { + MEMCPY( &dst->Color, &src->Color, sizeof(struct gl_colorbuffer_attrib) ); + } + if (mask & GL_CURRENT_BIT) { + MEMCPY( &dst->Current, &src->Current, sizeof(struct gl_current_attrib) ); + } + if (mask & GL_DEPTH_BUFFER_BIT) { + MEMCPY( &dst->Depth, &src->Depth, sizeof(struct gl_depthbuffer_attrib) ); + } + if (mask & GL_ENABLE_BIT) { + /* no op */ + } + if (mask & GL_EVAL_BIT) { + MEMCPY( &dst->Eval, &src->Eval, sizeof(struct gl_eval_attrib) ); + } + if (mask & GL_FOG_BIT) { + MEMCPY( &dst->Fog, &src->Fog, sizeof(struct gl_fog_attrib) ); + } + if (mask & GL_HINT_BIT) { + MEMCPY( &dst->Hint, &src->Hint, sizeof(struct gl_hint_attrib) ); + } + if (mask & GL_LIGHTING_BIT) { + MEMCPY( &dst->Light, &src->Light, sizeof(struct gl_light_attrib) ); + /* gl_reinit_light_attrib( &dst->Light ); */ + } + if (mask & GL_LINE_BIT) { + MEMCPY( &dst->Line, &src->Line, sizeof(struct gl_line_attrib) ); + } + if (mask & GL_LIST_BIT) { + MEMCPY( &dst->List, &src->List, sizeof(struct gl_list_attrib) ); + } + if (mask & GL_PIXEL_MODE_BIT) { + MEMCPY( &dst->Pixel, &src->Pixel, sizeof(struct gl_pixel_attrib) ); + } + if (mask & GL_POINT_BIT) { + MEMCPY( &dst->Point, &src->Point, sizeof(struct gl_point_attrib) ); + } + if (mask & GL_POLYGON_BIT) { + MEMCPY( &dst->Polygon, &src->Polygon, sizeof(struct gl_polygon_attrib) ); + } + if (mask & GL_POLYGON_STIPPLE_BIT) { + /* Use loop instead of MEMCPY due to problem with Portland Group's + * C compiler. Reported by John Stone. + */ + int i; + for (i=0;i<32;i++) { + dst->PolygonStipple[i] = src->PolygonStipple[i]; + } + } + if (mask & GL_SCISSOR_BIT) { + MEMCPY( &dst->Scissor, &src->Scissor, sizeof(struct gl_scissor_attrib) ); + } + if (mask & GL_STENCIL_BUFFER_BIT) { + MEMCPY( &dst->Stencil, &src->Stencil, sizeof(struct gl_stencil_attrib) ); + } + if (mask & GL_TEXTURE_BIT) { + MEMCPY( &dst->Texture, &src->Texture, sizeof(struct gl_texture_attrib) ); + } + if (mask & GL_TRANSFORM_BIT) { + MEMCPY( &dst->Transform, &src->Transform, sizeof(struct gl_transform_attrib) ); + } + if (mask & GL_VIEWPORT_BIT) { + MEMCPY( &dst->Viewport, &src->Viewport, sizeof(struct gl_viewport_attrib) ); + } + /* XXX FIXME: Call callbacks? + */ + dst->NewState = _NEW_ALL; +} + + +/* + * Set the current context, binding the given frame buffer to the context. + */ +void +_mesa_make_current( GLcontext *newCtx, GLframebuffer *buffer ) +{ + _mesa_make_current2( newCtx, buffer, buffer ); +} + + +static void print_info( void ) +{ + fprintf(stderr, "Mesa GL_VERSION = %s\n", + (char *) _mesa_GetString(GL_VERSION)); + fprintf(stderr, "Mesa GL_RENDERER = %s\n", + (char *) _mesa_GetString(GL_RENDERER)); + fprintf(stderr, "Mesa GL_VENDOR = %s\n", + (char *) _mesa_GetString(GL_VENDOR)); + fprintf(stderr, "Mesa GL_EXTENSIONS = %s\n", + (char *) _mesa_GetString(GL_EXTENSIONS)); +#if defined(THREADS) + fprintf(stderr, "Mesa thread-safe: YES\n"); +#else + fprintf(stderr, "Mesa thread-safe: NO\n"); +#endif +#if defined(USE_X86_ASM) + fprintf(stderr, "Mesa x86-optimized: YES\n"); +#else + fprintf(stderr, "Mesa x86-optimized: NO\n"); +#endif +#if defined(USE_SPARC_ASM) + fprintf(stderr, "Mesa sparc-optimized: YES\n"); +#else + fprintf(stderr, "Mesa sparc-optimized: NO\n"); +#endif +} + + +/* + * Bind the given context to the given draw-buffer and read-buffer + * and make it the current context for this thread. + */ +void +_mesa_make_current2( GLcontext *newCtx, GLframebuffer *drawBuffer, + GLframebuffer *readBuffer ) +{ + if (MESA_VERBOSE) + fprintf(stderr, "_mesa_make_current2()\n"); + + /* Check that the context's and framebuffer's visuals are compatible. + * We could do a lot more checking here but this'll catch obvious + * problems. + */ + if (newCtx && drawBuffer && readBuffer) { + if (newCtx->Visual.rgbMode != drawBuffer->Visual.rgbMode || + newCtx->Visual.redBits != drawBuffer->Visual.redBits || + newCtx->Visual.depthBits != drawBuffer->Visual.depthBits || + newCtx->Visual.stencilBits != drawBuffer->Visual.stencilBits || + newCtx->Visual.accumRedBits != drawBuffer->Visual.accumRedBits) { + return; /* incompatible */ + } + } + + /* We call this function periodically (just here for now) in + * order to detect when multithreading has begun. + */ + _glapi_check_multithread(); + + _glapi_set_context((void *) newCtx); + ASSERT(_mesa_get_current_context() == newCtx); + + + if (!newCtx) { + _glapi_set_dispatch(NULL); /* none current */ + } + else { + _glapi_set_dispatch(newCtx->CurrentDispatch); + + if (drawBuffer && readBuffer) { + /* TODO: check if newCtx and buffer's visual match??? */ + newCtx->DrawBuffer = drawBuffer; + newCtx->ReadBuffer = readBuffer; + newCtx->NewState |= _NEW_BUFFERS; + /* _mesa_update_state( newCtx ); */ + } + + if (newCtx->Driver.MakeCurrent) + newCtx->Driver.MakeCurrent( newCtx, drawBuffer, readBuffer ); + + /* We can use this to help debug user's problems. Tell them to set + * the MESA_INFO env variable before running their app. Then the + * first time each context is made current we'll print some useful + * information. + */ + if (newCtx->FirstTimeCurrent) { + if (getenv("MESA_INFO")) { + print_info(); + } + newCtx->FirstTimeCurrent = GL_FALSE; + } + } +} + + + +/* + * Return current context handle for the calling thread. + * This isn't the fastest way to get the current context. + * If you need speed, see the GET_CURRENT_CONTEXT() macro in context.h + */ +GLcontext * +_mesa_get_current_context( void ) +{ + return (GLcontext *) _glapi_get_context(); +} + + + +/* + * This should be called by device drivers just before they do a + * swapbuffers. Any pending rendering commands will be executed. + */ +void +_mesa_swapbuffers(GLcontext *ctx) +{ + FLUSH_VERTICES( ctx, 0 ); +} + + + +/* + * Return pointer to this context's current API dispatch table. + * It'll either be the immediate-mode execute dispatcher or the + * display list compile dispatcher. + */ +struct _glapi_table * +_mesa_get_dispatch(GLcontext *ctx) +{ + return ctx->CurrentDispatch; +} + + + +/**********************************************************************/ +/***** Miscellaneous functions *****/ +/**********************************************************************/ + + +/* + * This function is called when the Mesa user has stumbled into a code + * path which may not be implemented fully or correctly. + */ +void _mesa_problem( const GLcontext *ctx, const char *s ) +{ + fprintf( stderr, "Mesa implementation error: %s\n", s ); +#ifdef XF86DRI + fprintf( stderr, "Please report to the DRI bug database at dri.sourceforge.net\n"); +#else + fprintf( stderr, "Please report to the Mesa bug database at www.mesa3d.org\n" ); +#endif + (void) ctx; +} + + + +/* + * This is called to inform the user that he or she has tried to do + * something illogical or if there's likely a bug in their program + * (like enabled depth testing without a depth buffer). + */ +void +_mesa_warning( const GLcontext *ctx, const char *s ) +{ + (*ctx->imports.warning)((__GLcontext *) ctx, (char *) s); +} + + + +/* + * Compile an error into current display list. + */ +void +_mesa_compile_error( GLcontext *ctx, GLenum error, const char *s ) +{ + if (ctx->CompileFlag) + _mesa_save_error( ctx, error, s ); + + if (ctx->ExecuteFlag) + _mesa_error( ctx, error, s ); +} + + + +/* + * This is Mesa's error handler. Normally, all that's done is the updating + * of the current error value. If Mesa is compiled with -DDEBUG or if the + * environment variable "MESA_DEBUG" is defined then a real error message + * is printed to stderr. + * Input: ctx - the GL context + * error - the error value + * where - usually the name of function where error was detected + */ +void +_mesa_error( GLcontext *ctx, GLenum error, const char *where ) +{ + const char *debugEnv = getenv("MESA_DEBUG"); + GLboolean debug; + +#ifdef DEBUG + if (debugEnv && strstr(debugEnv, "silent")) + debug = GL_FALSE; + else + debug = GL_TRUE; +#else + if (debugEnv) + debug = GL_TRUE; + else + debug = GL_FALSE; +#endif + + if (debug) { + const char *errstr; + switch (error) { + case GL_NO_ERROR: + errstr = "GL_NO_ERROR"; + break; + case GL_INVALID_VALUE: + errstr = "GL_INVALID_VALUE"; + break; + case GL_INVALID_ENUM: + errstr = "GL_INVALID_ENUM"; + break; + case GL_INVALID_OPERATION: + errstr = "GL_INVALID_OPERATION"; + break; + case GL_STACK_OVERFLOW: + errstr = "GL_STACK_OVERFLOW"; + break; + case GL_STACK_UNDERFLOW: + errstr = "GL_STACK_UNDERFLOW"; + break; + case GL_OUT_OF_MEMORY: + errstr = "GL_OUT_OF_MEMORY"; + break; + case GL_TABLE_TOO_LARGE: + errstr = "GL_TABLE_TOO_LARGE"; + break; + default: + errstr = "unknown"; + break; + } + fprintf(stderr, "Mesa user error: %s in %s\n", errstr, where); + } + + if (ctx->ErrorValue == GL_NO_ERROR) { + ctx->ErrorValue = error; + } + + /* Call device driver's error handler, if any. This is used on the Mac. */ + if (ctx->Driver.Error) { + (*ctx->Driver.Error)( ctx ); + } +} + + + +void +_mesa_Finish( void ) +{ + GET_CURRENT_CONTEXT(ctx); + ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx); + if (ctx->Driver.Finish) { + (*ctx->Driver.Finish)( ctx ); + } +} + + + +void +_mesa_Flush( void ) +{ + GET_CURRENT_CONTEXT(ctx); + ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx); + if (ctx->Driver.Flush) { + (*ctx->Driver.Flush)( ctx ); + } +} + + + +const char *_mesa_prim_name[GL_POLYGON+4] = { + "GL_POINTS", + "GL_LINES", + "GL_LINE_LOOP", + "GL_LINE_STRIP", + "GL_TRIANGLES", + "GL_TRIANGLE_STRIP", + "GL_TRIANGLE_FAN", + "GL_QUADS", + "GL_QUAD_STRIP", + "GL_POLYGON", + "outside begin/end", + "inside unkown primitive", + "unknown state" +}; Index: dll/opengl/opengl32/mesa/context.h =================================================================== --- dll/opengl/opengl32/mesa/context.h (revision 0) +++ dll/opengl/opengl32/mesa/context.h (working copy) @@ -0,0 +1,228 @@ +/* $Id: context.h,v 1.27 2001/05/03 14:11:18 brianp Exp $ */ + +/* + * Mesa 3-D graphics library + * Version: 3.5 + * + * Copyright (C) 1999-2001 Brian Paul 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 + * BRIAN PAUL 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. + */ + + +#ifndef CONTEXT_H +#define CONTEXT_H + + +#include "glapi.h" +#include "mtypes.h" + + +/* + * There are three Mesa datatypes which are meant to be used by device + * drivers: + * GLcontext: this contains the Mesa rendering state + * GLvisual: this describes the color buffer (rgb vs. ci), whether + * or not there's a depth buffer, stencil buffer, etc. + * GLframebuffer: contains pointers to the depth buffer, stencil + * buffer, accum buffer and alpha buffers. + * + * These types should be encapsulated by corresponding device driver + * datatypes. See xmesa.h and xmesaP.h for an example. + * + * In OOP terms, GLcontext, GLvisual, and GLframebuffer are base classes + * which the device driver must derive from. + * + * The following functions create and destroy these datatypes. + */ + + +/* + * Create/destroy a GLvisual. A GLvisual is like a GLX visual. It describes + * the colorbuffer, depth buffer, stencil buffer and accum buffer which will + * be used by the GL context and framebuffer. + */ +extern GLvisual * +_mesa_create_visual( GLboolean rgbFlag, + GLboolean dbFlag, + GLboolean stereoFlag, + GLint redBits, + GLint greenBits, + GLint blueBits, + GLint alphaBits, + GLint indexBits, + GLint depthBits, + GLint stencilBits, + GLint accumRedBits, + GLint accumGreenBits, + GLint accumBlueBits, + GLint accumAlphaBits, + GLint numSamples ); + +extern GLboolean +_mesa_initialize_visual( GLvisual *v, + GLboolean rgbFlag, + GLboolean dbFlag, + GLboolean stereoFlag, + GLint redBits, + GLint greenBits, + GLint blueBits, + GLint alphaBits, + GLint indexBits, + GLint depthBits, + GLint stencilBits, + GLint accumRedBits, + GLint accumGreenBits, + GLint accumBlueBits, + GLint accumAlphaBits, + GLint numSamples ); + +extern void +_mesa_destroy_visual( GLvisual *vis ); + + + +/* + * Create/destroy a GLframebuffer. A GLframebuffer is like a GLX drawable. + * It bundles up the depth buffer, stencil buffer and accum buffers into a + * single entity. + */ +extern GLframebuffer * +_mesa_create_framebuffer( const GLvisual *visual, + GLboolean softwareDepth, + GLboolean softwareStencil, + GLboolean softwareAccum, + GLboolean softwareAlpha ); + +extern void +_mesa_initialize_framebuffer( GLframebuffer *fb, + const GLvisual *visual, + GLboolean softwareDepth, + GLboolean softwareStencil, + GLboolean softwareAccum, + GLboolean softwareAlpha ); + +extern void +_mesa_free_framebuffer_data( GLframebuffer *buffer ); + +extern void +_mesa_destroy_framebuffer( GLframebuffer *buffer ); + + + +/* + * Create/destroy a GLcontext. A GLcontext is like a GLX context. It + * contains the rendering state. + */ +extern GLcontext * +_mesa_create_context( const GLvisual *visual, + GLcontext *share_list, + void *driver_ctx, + GLboolean direct); + +extern GLboolean +_mesa_initialize_context( GLcontext *ctx, + const GLvisual *visual, + GLcontext *share_list, + void *driver_ctx, + GLboolean direct ); + +extern void +_mesa_free_context_data( GLcontext *ctx ); + +extern void +_mesa_destroy_context( GLcontext *ctx ); + + +extern void +_mesa_copy_context(const GLcontext *src, GLcontext *dst, GLuint mask); + + +extern void +_mesa_make_current( GLcontext *ctx, GLframebuffer *buffer ); + + +extern void +_mesa_make_current2( GLcontext *ctx, GLframebuffer *drawBuffer, + GLframebuffer *readBuffer ); + + +extern GLcontext * +_mesa_get_current_context(void); + + + +/* + * Macros for fetching current context. + */ +#ifdef THREADS + +#define GET_CURRENT_CONTEXT(C) GLcontext *C = (GLcontext *) (_glapi_Context ? _glapi_Context : _glapi_get_context()) + +#else + +#define GET_CURRENT_CONTEXT(C) GLcontext *C = (GLcontext *) _glapi_Context + +#endif + + + +extern void +_mesa_swapbuffers(GLcontext *ctx); + + +extern struct _glapi_table * +_mesa_get_dispatch(GLcontext *ctx); + + + +/* + * Miscellaneous + */ + +extern void +_mesa_problem( const GLcontext *ctx, const char *s ); + +extern void +_mesa_warning( const GLcontext *ctx, const char *s ); + +extern void +_mesa_error( GLcontext *ctx, GLenum error, const char *s ); + +extern void +_mesa_compile_error( GLcontext *ctx, GLenum error, const char *s ); + + + +extern void +_mesa_Finish( void ); + +extern void +_mesa_Flush( void ); + + + +extern void +_mesa_read_config_file(GLcontext *ctx); + +extern void +_mesa_register_config_var(const char *name, + void (*notify)( const char *, int )); + + +#endif Index: dll/opengl/opengl32/mesa/convolve.c =================================================================== --- dll/opengl/opengl32/mesa/convolve.c (revision 0) +++ dll/opengl/opengl32/mesa/convolve.c (working copy) @@ -0,0 +1,1417 @@ +/* $Id: convolve.c,v 1.24 2001/05/09 22:24:22 brianp Exp $ */ + +/* + * Mesa 3-D graphics library + * Version: 3.5 + * + * Copyright (C) 1999-2001 Brian Paul 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 + * BRIAN PAUL 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. + */ + + +/* + * Image convolution functions. + * + * Notes: filter kernel elements are indexed by and as in + * the GL spec. + */ + + +#ifdef PC_HEADER +#include "all.h" +#else +#include "glheader.h" +#include "colormac.h" +#include "convolve.h" +#include "context.h" +#include "image.h" +#include "mtypes.h" +#include "state.h" +#include "swrast/s_span.h" /* XXX SWRAST hack */ +#endif + + +/* + * Given an internalFormat token passed to glConvolutionFilter + * or glSeparableFilter, return the corresponding base format. + * Return -1 if invalid token. + */ +static GLint +base_filter_format( GLenum format ) +{ + switch (format) { + case GL_ALPHA: + case GL_ALPHA4: + case GL_ALPHA8: + case GL_ALPHA12: + case GL_ALPHA16: + return GL_ALPHA; + case GL_LUMINANCE: + case GL_LUMINANCE4: + case GL_LUMINANCE8: + case GL_LUMINANCE12: + case GL_LUMINANCE16: + return GL_LUMINANCE; + case GL_LUMINANCE_ALPHA: + case GL_LUMINANCE4_ALPHA4: + case GL_LUMINANCE6_ALPHA2: + case GL_LUMINANCE8_ALPHA8: + case GL_LUMINANCE12_ALPHA4: + case GL_LUMINANCE12_ALPHA12: + case GL_LUMINANCE16_ALPHA16: + return GL_LUMINANCE_ALPHA; + case GL_INTENSITY: + case GL_INTENSITY4: + case GL_INTENSITY8: + case GL_INTENSITY12: + case GL_INTENSITY16: + return GL_INTENSITY; + case GL_RGB: + case GL_R3_G3_B2: + case GL_RGB4: + case GL_RGB5: + case GL_RGB8: + case GL_RGB10: + case GL_RGB12: + case GL_RGB16: + return GL_RGB; + case 4: + case GL_RGBA: + case GL_RGBA2: + case GL_RGBA4: + case GL_RGB5_A1: + case GL_RGBA8: + case GL_RGB10_A2: + case GL_RGBA12: + case GL_RGBA16: + return GL_RGBA; + default: + return -1; /* error */ + } +} + + +void +_mesa_ConvolutionFilter1D(GLenum target, GLenum internalFormat, GLsizei width, GLenum format, GLenum type, const GLvoid *image) +{ + GLenum baseFormat; + GET_CURRENT_CONTEXT(ctx); + ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx); + + if (target != GL_CONVOLUTION_1D) { + _mesa_error(ctx, GL_INVALID_ENUM, "glConvolutionFilter1D(target)"); + return; + } + + baseFormat = base_filter_format(internalFormat); + if (baseFormat < 0 || baseFormat == GL_COLOR_INDEX) { + _mesa_error(ctx, GL_INVALID_ENUM, "glConvolutionFilter1D(internalFormat)"); + return; + } + + if (width < 0 || width > MAX_CONVOLUTION_WIDTH) { + _mesa_error(ctx, GL_INVALID_VALUE, "glConvolutionFilter1D(width)"); + return; + } + + if (!_mesa_is_legal_format_and_type(format, type)) { + _mesa_error(ctx, GL_INVALID_OPERATION, "glConvolutionFilter1D(format or type)"); + return; + } + + if (format == GL_COLOR_INDEX || + format == GL_STENCIL_INDEX || + format == GL_DEPTH_COMPONENT || + format == GL_INTENSITY || + type == GL_BITMAP) { + _mesa_error(ctx, GL_INVALID_ENUM, "glConvolutionFilter1D(format or type)"); + return; + } + + ctx->Convolution1D.Format = format; + ctx->Convolution1D.InternalFormat = internalFormat; + ctx->Convolution1D.Width = width; + ctx->Convolution1D.Height = 1; + + /* unpack filter image */ + _mesa_unpack_float_color_span(ctx, width, GL_RGBA, + ctx->Convolution1D.Filter, + format, type, image, &ctx->Unpack, + 0, GL_FALSE); + + /* apply scale and bias */ + { + const GLfloat *scale = ctx->Pixel.ConvolutionFilterScale[0]; + const GLfloat *bias = ctx->Pixel.ConvolutionFilterBias[0]; + GLint i; + for (i = 0; i < width; i++) { + GLfloat r = ctx->Convolution1D.Filter[i * 4 + 0]; + GLfloat g = ctx->Convolution1D.Filter[i * 4 + 1]; + GLfloat b = ctx->Convolution1D.Filter[i * 4 + 2]; + GLfloat a = ctx->Convolution1D.Filter[i * 4 + 3]; + r = r * scale[0] + bias[0]; + g = g * scale[1] + bias[1]; + b = b * scale[2] + bias[2]; + a = a * scale[3] + bias[3]; + ctx->Convolution1D.Filter[i * 4 + 0] = r; + ctx->Convolution1D.Filter[i * 4 + 1] = g; + ctx->Convolution1D.Filter[i * 4 + 2] = b; + ctx->Convolution1D.Filter[i * 4 + 3] = a; + } + } + + ctx->NewState |= _NEW_PIXEL; +} + + +void +_mesa_ConvolutionFilter2D(GLenum target, GLenum internalFormat, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *image) +{ + GLenum baseFormat; + GLint i, components; + GET_CURRENT_CONTEXT(ctx); + ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx); + + if (target != GL_CONVOLUTION_2D) { + _mesa_error(ctx, GL_INVALID_ENUM, "glConvolutionFilter2D(target)"); + return; + } + + baseFormat = base_filter_format(internalFormat); + if (baseFormat < 0 || baseFormat == GL_COLOR_INDEX) { + _mesa_error(ctx, GL_INVALID_ENUM, "glConvolutionFilter2D(internalFormat)"); + return; + } + + if (width < 0 || width > MAX_CONVOLUTION_WIDTH) { + _mesa_error(ctx, GL_INVALID_VALUE, "glConvolutionFilter2D(width)"); + return; + } + if (height < 0 || height > MAX_CONVOLUTION_HEIGHT) { + _mesa_error(ctx, GL_INVALID_VALUE, "glConvolutionFilter2D(height)"); + return; + } + + if (!_mesa_is_legal_format_and_type(format, type)) { + _mesa_error(ctx, GL_INVALID_OPERATION, "glConvolutionFilter2D(format or type)"); + return; + } + if (format == GL_COLOR_INDEX || + format == GL_STENCIL_INDEX || + format == GL_DEPTH_COMPONENT || + format == GL_INTENSITY || + type == GL_BITMAP) { + _mesa_error(ctx, GL_INVALID_ENUM, "glConvolutionFilter2D(format or type)"); + return; + } + + components = _mesa_components_in_format(format); + assert(components > 0); /* this should have been caught earlier */ + + ctx->Convolution2D.Format = format; + ctx->Convolution2D.InternalFormat = internalFormat; + ctx->Convolution2D.Width = width; + ctx->Convolution2D.Height = height; + + /* Unpack filter image. We always store filters in RGBA format. */ + for (i = 0; i < height; i++) { + const GLvoid *src = _mesa_image_address(&ctx->Unpack, image, width, + height, format, type, 0, i, 0); + GLfloat *dst = ctx->Convolution2D.Filter + i * width * 4; + _mesa_unpack_float_color_span(ctx, width, GL_RGBA, dst, + format, type, src, &ctx->Unpack, + 0, GL_FALSE); + } + + /* apply scale and bias */ + { + const GLfloat *scale = ctx->Pixel.ConvolutionFilterScale[1]; + const GLfloat *bias = ctx->Pixel.ConvolutionFilterBias[1]; + for (i = 0; i < width * height; i++) { + GLfloat r = ctx->Convolution2D.Filter[i * 4 + 0]; + GLfloat g = ctx->Convolution2D.Filter[i * 4 + 1]; + GLfloat b = ctx->Convolution2D.Filter[i * 4 + 2]; + GLfloat a = ctx->Convolution2D.Filter[i * 4 + 3]; + r = r * scale[0] + bias[0]; + g = g * scale[1] + bias[1]; + b = b * scale[2] + bias[2]; + a = a * scale[3] + bias[3]; + ctx->Convolution2D.Filter[i * 4 + 0] = r; + ctx->Convolution2D.Filter[i * 4 + 1] = g; + ctx->Convolution2D.Filter[i * 4 + 2] = b; + ctx->Convolution2D.Filter[i * 4 + 3] = a; + } + } + + ctx->NewState |= _NEW_PIXEL; +} + + +void +_mesa_ConvolutionParameterf(GLenum target, GLenum pname, GLfloat param) +{ + GET_CURRENT_CONTEXT(ctx); + GLuint c; + ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx); + + switch (target) { + case GL_CONVOLUTION_1D: + c = 0; + break; + case GL_CONVOLUTION_2D: + c = 1; + break; + case GL_SEPARABLE_2D: + c = 2; + break; + default: + _mesa_error(ctx, GL_INVALID_ENUM, "glConvolutionParameterf(target)"); + return; + } + + switch (pname) { + case GL_CONVOLUTION_BORDER_MODE: + if (param == (GLfloat) GL_REDUCE || + param == (GLfloat) GL_CONSTANT_BORDER || + param == (GLfloat) GL_REPLICATE_BORDER) { + ctx->Pixel.ConvolutionBorderMode[c] = (GLenum) param; + } + else { + _mesa_error(ctx, GL_INVALID_ENUM, "glConvolutionParameterf(params)"); + return; + } + break; + default: + _mesa_error(ctx, GL_INVALID_ENUM, "glConvolutionParameterf(pname)"); + return; + } + + ctx->NewState |= _NEW_PIXEL; +} + + +void +_mesa_ConvolutionParameterfv(GLenum target, GLenum pname, const GLfloat *params) +{ + GET_CURRENT_CONTEXT(ctx); + struct gl_convolution_attrib *conv; + GLuint c; + ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx); + + switch (target) { + case GL_CONVOLUTION_1D: + c = 0; + conv = &ctx->Convolution1D; + break; + case GL_CONVOLUTION_2D: + c = 1; + conv = &ctx->Convolution2D; + break; + case GL_SEPARABLE_2D: + c = 2; + conv = &ctx->Separable2D; + break; + default: + _mesa_error(ctx, GL_INVALID_ENUM, "glConvolutionParameterfv(target)"); + return; + } + + switch (pname) { + case GL_CONVOLUTION_BORDER_COLOR: + COPY_4V(ctx->Pixel.ConvolutionBorderColor[c], params); + break; + case GL_CONVOLUTION_BORDER_MODE: + if (params[0] == (GLfloat) GL_REDUCE || + params[0] == (GLfloat) GL_CONSTANT_BORDER || + params[0] == (GLfloat) GL_REPLICATE_BORDER) { + ctx->Pixel.ConvolutionBorderMode[c] = (GLenum) params[0]; + } + else { + _mesa_error(ctx, GL_INVALID_ENUM, "glConvolutionParameterfv(params)"); + return; + } + break; + case GL_CONVOLUTION_FILTER_SCALE: + COPY_4V(ctx->Pixel.ConvolutionFilterScale[c], params); + break; + case GL_CONVOLUTION_FILTER_BIAS: + COPY_4V(ctx->Pixel.ConvolutionFilterBias[c], params); + break; + default: + _mesa_error(ctx, GL_INVALID_ENUM, "glConvolutionParameterfv(pname)"); + return; + } + + ctx->NewState |= _NEW_PIXEL; +} + + +void +_mesa_ConvolutionParameteri(GLenum target, GLenum pname, GLint param) +{ + GET_CURRENT_CONTEXT(ctx); + GLuint c; + ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx); + + switch (target) { + case GL_CONVOLUTION_1D: + c = 0; + break; + case GL_CONVOLUTION_2D: + c = 1; + break; + case GL_SEPARABLE_2D: + c = 2; + break; + default: + _mesa_error(ctx, GL_INVALID_ENUM, "glConvolutionParameteri(target)"); + return; + } + + switch (pname) { + case GL_CONVOLUTION_BORDER_MODE: + if (param == (GLint) GL_REDUCE || + param == (GLint) GL_CONSTANT_BORDER || + param == (GLint) GL_REPLICATE_BORDER) { + ctx->Pixel.ConvolutionBorderMode[c] = (GLenum) param; + } + else { + _mesa_error(ctx, GL_INVALID_ENUM, "glConvolutionParameteri(params)"); + return; + } + break; + default: + _mesa_error(ctx, GL_INVALID_ENUM, "glConvolutionParameteri(pname)"); + return; + } + + ctx->NewState |= _NEW_PIXEL; +} + + +void +_mesa_ConvolutionParameteriv(GLenum target, GLenum pname, const GLint *params) +{ + GET_CURRENT_CONTEXT(ctx); + struct gl_convolution_attrib *conv; + GLuint c; + ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx); + + switch (target) { + case GL_CONVOLUTION_1D: + c = 0; + conv = &ctx->Convolution1D; + break; + case GL_CONVOLUTION_2D: + c = 1; + conv = &ctx->Convolution2D; + break; + case GL_SEPARABLE_2D: + c = 2; + conv = &ctx->Separable2D; + break; + default: + _mesa_error(ctx, GL_INVALID_ENUM, "glConvolutionParameteriv(target)"); + return; + } + + switch (pname) { + case GL_CONVOLUTION_BORDER_COLOR: + ctx->Pixel.ConvolutionBorderColor[c][0] = INT_TO_FLOAT(params[0]); + ctx->Pixel.ConvolutionBorderColor[c][1] = INT_TO_FLOAT(params[1]); + ctx->Pixel.ConvolutionBorderColor[c][2] = INT_TO_FLOAT(params[2]); + ctx->Pixel.ConvolutionBorderColor[c][3] = INT_TO_FLOAT(params[3]); + break; + case GL_CONVOLUTION_BORDER_MODE: + if (params[0] == (GLint) GL_REDUCE || + params[0] == (GLint) GL_CONSTANT_BORDER || + params[0] == (GLint) GL_REPLICATE_BORDER) { + ctx->Pixel.ConvolutionBorderMode[c] = (GLenum) params[0]; + } + else { + _mesa_error(ctx, GL_INVALID_ENUM, "glConvolutionParameteriv(params)"); + return; + } + break; + case GL_CONVOLUTION_FILTER_SCALE: + COPY_4V(ctx->Pixel.ConvolutionFilterScale[c], params); + break; + case GL_CONVOLUTION_FILTER_BIAS: + COPY_4V(ctx->Pixel.ConvolutionFilterBias[c], params); + break; + default: + _mesa_error(ctx, GL_INVALID_ENUM, "glConvolutionParameteriv(pname)"); + return; + } + + ctx->NewState |= _NEW_PIXEL; +} + + +void +_mesa_CopyConvolutionFilter1D(GLenum target, GLenum internalFormat, GLint x, GLint y, GLsizei width) +{ + GLenum baseFormat; + GET_CURRENT_CONTEXT(ctx); + ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx); + + if (target != GL_CONVOLUTION_1D) { + _mesa_error(ctx, GL_INVALID_ENUM, "glCopyConvolutionFilter1D(target)"); + return; + } + + baseFormat = base_filter_format(internalFormat); + if (baseFormat < 0 || baseFormat == GL_COLOR_INDEX) { + _mesa_error(ctx, GL_INVALID_ENUM, "glCopyConvolutionFilter1D(internalFormat)"); + return; + } + + if (width < 0 || width > MAX_CONVOLUTION_WIDTH) { + _mesa_error(ctx, GL_INVALID_VALUE, "glCopyConvolutionFilter1D(width)"); + return; + } + + ctx->Driver.CopyConvolutionFilter1D( ctx, target, + internalFormat, x, y, width); +} + + +void +_mesa_CopyConvolutionFilter2D(GLenum target, GLenum internalFormat, GLint x, GLint y, GLsizei width, GLsizei height) +{ + GLenum baseFormat; + GET_CURRENT_CONTEXT(ctx); + ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx); + + if (target != GL_CONVOLUTION_2D) { + _mesa_error(ctx, GL_INVALID_ENUM, "glCopyConvolutionFilter2D(target)"); + return; + } + + baseFormat = base_filter_format(internalFormat); + if (baseFormat < 0 || baseFormat == GL_COLOR_INDEX) { + _mesa_error(ctx, GL_INVALID_ENUM, "glCopyConvolutionFilter2D(internalFormat)"); + return; + } + + if (width < 0 || width > MAX_CONVOLUTION_WIDTH) { + _mesa_error(ctx, GL_INVALID_VALUE, "glCopyConvolutionFilter2D(width)"); + return; + } + if (height < 0 || height > MAX_CONVOLUTION_HEIGHT) { + _mesa_error(ctx, GL_INVALID_VALUE, "glCopyConvolutionFilter2D(height)"); + return; + } + + ctx->Driver.CopyConvolutionFilter2D( ctx, target, internalFormat, x, y, + width, height ); + +} + + +void +_mesa_GetConvolutionFilter(GLenum target, GLenum format, GLenum type, GLvoid *image) +{ + const struct gl_convolution_attrib *filter; + GLuint row; + GET_CURRENT_CONTEXT(ctx); + ASSERT_OUTSIDE_BEGIN_END(ctx); + + if (ctx->NewState) { + _mesa_update_state(ctx); + } + + if (!_mesa_is_legal_format_and_type(format, type)) { + _mesa_error(ctx, GL_INVALID_OPERATION, "glGetConvolutionFilter(format or type)"); + return; + } + + if (format == GL_COLOR_INDEX || + format == GL_STENCIL_INDEX || + format == GL_DEPTH_COMPONENT || + format == GL_INTENSITY || + type == GL_BITMAP) { + _mesa_error(ctx, GL_INVALID_ENUM, "glGetConvolutionFilter(format or type)"); + return; + } + + switch (target) { + case GL_CONVOLUTION_1D: + filter = &(ctx->Convolution1D); + break; + case GL_CONVOLUTION_2D: + filter = &(ctx->Convolution2D); + break; + default: + _mesa_error(ctx, GL_INVALID_ENUM, "glGetConvolutionFilter(target)"); + return; + } + + for (row = 0; row < filter->Height; row++) { + GLvoid *dst = _mesa_image_address( &ctx->Pack, image, filter->Width, + filter->Height, format, type, + 0, row, 0); + const GLfloat *src = filter->Filter + row * filter->Width * 4; + _mesa_pack_float_rgba_span(ctx, filter->Width, + (const GLfloat (*)[4]) src, + format, type, dst, &ctx->Pack, 0); + } +} + + +void +_mesa_GetConvolutionParameterfv(GLenum target, GLenum pname, GLfloat *params) +{ + GET_CURRENT_CONTEXT(ctx); + const struct gl_convolution_attrib *conv; + GLuint c; + ASSERT_OUTSIDE_BEGIN_END(ctx); + + switch (target) { + case GL_CONVOLUTION_1D: + c = 0; + conv = &ctx->Convolution1D; + break; + case GL_CONVOLUTION_2D: + c = 1; + conv = &ctx->Convolution2D; + break; + case GL_SEPARABLE_2D: + c = 2; + conv = &ctx->Separable2D; + break; + default: + _mesa_error(ctx, GL_INVALID_ENUM, "glGetConvolutionParameterfv(target)"); + return; + } + + switch (pname) { + case GL_CONVOLUTION_BORDER_COLOR: + COPY_4V(params, ctx->Pixel.ConvolutionBorderColor[c]); + break; + case GL_CONVOLUTION_BORDER_MODE: + *params = (GLfloat) ctx->Pixel.ConvolutionBorderMode[c]; + break; + case GL_CONVOLUTION_FILTER_SCALE: + COPY_4V(params, ctx->Pixel.ConvolutionFilterScale[c]); + break; + case GL_CONVOLUTION_FILTER_BIAS: + COPY_4V(params, ctx->Pixel.ConvolutionFilterBias[c]); + break; + case GL_CONVOLUTION_FORMAT: + *params = (GLfloat) conv->Format; + break; + case GL_CONVOLUTION_WIDTH: + *params = (GLfloat) conv->Width; + break; + case GL_CONVOLUTION_HEIGHT: + *params = (GLfloat) conv->Height; + break; + case GL_MAX_CONVOLUTION_WIDTH: + *params = (GLfloat) ctx->Const.MaxConvolutionWidth; + break; + case GL_MAX_CONVOLUTION_HEIGHT: + *params = (GLfloat) ctx->Const.MaxConvolutionHeight; + break; + default: + _mesa_error(ctx, GL_INVALID_ENUM, "glGetConvolutionParameterfv(pname)"); + return; + } +} + + +void +_mesa_GetConvolutionParameteriv(GLenum target, GLenum pname, GLint *params) +{ + GET_CURRENT_CONTEXT(ctx); + const struct gl_convolution_attrib *conv; + GLuint c; + ASSERT_OUTSIDE_BEGIN_END(ctx); + + switch (target) { + case GL_CONVOLUTION_1D: + c = 0; + conv = &ctx->Convolution1D; + break; + case GL_CONVOLUTION_2D: + c = 1; + conv = &ctx->Convolution2D; + break; + case GL_SEPARABLE_2D: + c = 2; + conv = &ctx->Separable2D; + break; + default: + _mesa_error(ctx, GL_INVALID_ENUM, "glGetConvolutionParameteriv(target)"); + return; + } + + switch (pname) { + case GL_CONVOLUTION_BORDER_COLOR: + params[0] = FLOAT_TO_INT(ctx->Pixel.ConvolutionBorderColor[c][0]); + params[1] = FLOAT_TO_INT(ctx->Pixel.ConvolutionBorderColor[c][1]); + params[2] = FLOAT_TO_INT(ctx->Pixel.ConvolutionBorderColor[c][2]); + params[3] = FLOAT_TO_INT(ctx->Pixel.ConvolutionBorderColor[c][3]); + break; + case GL_CONVOLUTION_BORDER_MODE: + *params = (GLint) ctx->Pixel.ConvolutionBorderMode[c]; + break; + case GL_CONVOLUTION_FILTER_SCALE: + params[0] = (GLint) ctx->Pixel.ConvolutionFilterScale[c][0]; + params[1] = (GLint) ctx->Pixel.ConvolutionFilterScale[c][1]; + params[2] = (GLint) ctx->Pixel.ConvolutionFilterScale[c][2]; + params[3] = (GLint) ctx->Pixel.ConvolutionFilterScale[c][3]; + break; + case GL_CONVOLUTION_FILTER_BIAS: + params[0] = (GLint) ctx->Pixel.ConvolutionFilterBias[c][0]; + params[1] = (GLint) ctx->Pixel.ConvolutionFilterBias[c][1]; + params[2] = (GLint) ctx->Pixel.ConvolutionFilterBias[c][2]; + params[3] = (GLint) ctx->Pixel.ConvolutionFilterBias[c][3]; + break; + case GL_CONVOLUTION_FORMAT: + *params = (GLint) conv->Format; + break; + case GL_CONVOLUTION_WIDTH: + *params = (GLint) conv->Width; + break; + case GL_CONVOLUTION_HEIGHT: + *params = (GLint) conv->Height; + break; + case GL_MAX_CONVOLUTION_WIDTH: + *params = (GLint) ctx->Const.MaxConvolutionWidth; + break; + case GL_MAX_CONVOLUTION_HEIGHT: + *params = (GLint) ctx->Const.MaxConvolutionHeight; + break; + default: + _mesa_error(ctx, GL_INVALID_ENUM, "glGetConvolutionParameteriv(pname)"); + return; + } +} + + +void +_mesa_GetSeparableFilter(GLenum target, GLenum format, GLenum type, GLvoid *row, GLvoid *column, GLvoid *span) +{ + const GLint colStart = MAX_CONVOLUTION_WIDTH * 4; + const struct gl_convolution_attrib *filter; + GET_CURRENT_CONTEXT(ctx); + ASSERT_OUTSIDE_BEGIN_END(ctx); + + if (ctx->NewState) { + _mesa_update_state(ctx); + } + + if (target != GL_SEPARABLE_2D) { + _mesa_error(ctx, GL_INVALID_ENUM, "glGetSeparableFilter(target)"); + return; + } + + if (!_mesa_is_legal_format_and_type(format, type)) { + _mesa_error(ctx, GL_INVALID_OPERATION, "glGetConvolutionFilter(format or type)"); + return; + } + + if (format == GL_COLOR_INDEX || + format == GL_STENCIL_INDEX || + format == GL_DEPTH_COMPONENT || + format == GL_INTENSITY || + type == GL_BITMAP) { + _mesa_error(ctx, GL_INVALID_ENUM, "glGetConvolutionFilter(format or type)"); + return; + } + + filter = &ctx->Separable2D; + + /* Row filter */ + { + GLvoid *dst = _mesa_image_address( &ctx->Pack, row, filter->Width, + filter->Height, format, type, + 0, 0, 0); + _mesa_pack_float_rgba_span(ctx, filter->Width, + (const GLfloat (*)[4]) filter->Filter, + format, type, dst, &ctx->Pack, 0); + } + + /* Column filter */ + { + GLvoid *dst = _mesa_image_address( &ctx->Pack, column, filter->Width, + 1, format, type, + 0, 0, 0); + const GLfloat *src = filter->Filter + colStart; + _mesa_pack_float_rgba_span(ctx, filter->Height, + (const GLfloat (*)[4]) src, + format, type, dst, &ctx->Pack, 0); + } + + (void) span; /* unused at this time */ +} + + +void +_mesa_SeparableFilter2D(GLenum target, GLenum internalFormat, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *row, const GLvoid *column) +{ + const GLint colStart = MAX_CONVOLUTION_WIDTH * 4; + GLenum baseFormat; + GET_CURRENT_CONTEXT(ctx); + ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx); + + if (target != GL_SEPARABLE_2D) { + _mesa_error(ctx, GL_INVALID_ENUM, "glSeparableFilter2D(target)"); + return; + } + + baseFormat = base_filter_format(internalFormat); + if (baseFormat < 0 || baseFormat == GL_COLOR_INDEX) { + _mesa_error(ctx, GL_INVALID_ENUM, "glSeparableFilter2D(internalFormat)"); + return; + } + + if (width < 0 || width > MAX_CONVOLUTION_WIDTH) { + _mesa_error(ctx, GL_INVALID_VALUE, "glSeparableFilter2D(width)"); + return; + } + if (height < 0 || height > MAX_CONVOLUTION_HEIGHT) { + _mesa_error(ctx, GL_INVALID_VALUE, "glSeparableFilter2D(height)"); + return; + } + + if (!_mesa_is_legal_format_and_type(format, type)) { + _mesa_error(ctx, GL_INVALID_OPERATION, "glSeparableFilter2D(format or type)"); + return; + } + + if (format == GL_COLOR_INDEX || + format == GL_STENCIL_INDEX || + format == GL_DEPTH_COMPONENT || + format == GL_INTENSITY || + type == GL_BITMAP) { + _mesa_error(ctx, GL_INVALID_ENUM, "glSeparableFilter2D(format or type)"); + return; + } + + ctx->Separable2D.Format = format; + ctx->Separable2D.InternalFormat = internalFormat; + ctx->Separable2D.Width = width; + ctx->Separable2D.Height = height; + + /* unpack row filter */ + _mesa_unpack_float_color_span(ctx, width, GL_RGBA, + ctx->Separable2D.Filter, + format, type, row, &ctx->Unpack, + 0, GL_FALSE); + + /* apply scale and bias */ + { + const GLfloat *scale = ctx->Pixel.ConvolutionFilterScale[2]; + const GLfloat *bias = ctx->Pixel.ConvolutionFilterBias[2]; + GLint i; + for (i = 0; i < width; i++) { + GLfloat r = ctx->Separable2D.Filter[i * 4 + 0]; + GLfloat g = ctx->Separable2D.Filter[i * 4 + 1]; + GLfloat b = ctx->Separable2D.Filter[i * 4 + 2]; + GLfloat a = ctx->Separable2D.Filter[i * 4 + 3]; + r = r * scale[0] + bias[0]; + g = g * scale[1] + bias[1]; + b = b * scale[2] + bias[2]; + a = a * scale[3] + bias[3]; + ctx->Separable2D.Filter[i * 4 + 0] = r; + ctx->Separable2D.Filter[i * 4 + 1] = g; + ctx->Separable2D.Filter[i * 4 + 2] = b; + ctx->Separable2D.Filter[i * 4 + 3] = a; + } + } + + /* unpack column filter */ + _mesa_unpack_float_color_span(ctx, width, GL_RGBA, + &ctx->Separable2D.Filter[colStart], + format, type, column, &ctx->Unpack, + 0, GL_FALSE); + + /* apply scale and bias */ + { + const GLfloat *scale = ctx->Pixel.ConvolutionFilterScale[2]; + const GLfloat *bias = ctx->Pixel.ConvolutionFilterBias[2]; + GLint i; + for (i = 0; i < width; i++) { + GLfloat r = ctx->Separable2D.Filter[i * 4 + 0 + colStart]; + GLfloat g = ctx->Separable2D.Filter[i * 4 + 1 + colStart]; + GLfloat b = ctx->Separable2D.Filter[i * 4 + 2 + colStart]; + GLfloat a = ctx->Separable2D.Filter[i * 4 + 3 + colStart]; + r = r * scale[0] + bias[0]; + g = g * scale[1] + bias[1]; + b = b * scale[2] + bias[2]; + a = a * scale[3] + bias[3]; + ctx->Separable2D.Filter[i * 4 + 0 + colStart] = r; + ctx->Separable2D.Filter[i * 4 + 1 + colStart] = g; + ctx->Separable2D.Filter[i * 4 + 2 + colStart] = b; + ctx->Separable2D.Filter[i * 4 + 3 + colStart] = a; + } + } + + ctx->NewState |= _NEW_PIXEL; +} + + +/**********************************************************************/ +/*** image convolution functions ***/ +/**********************************************************************/ + +static void +convolve_1d_reduce(GLint srcWidth, const GLfloat src[][4], + GLint filterWidth, const GLfloat filter[][4], + GLfloat dest[][4]) +{ + GLint dstWidth; + GLint i, n; + + if (filterWidth >= 1) + dstWidth = srcWidth - (filterWidth - 1); + else + dstWidth = srcWidth; + + if (dstWidth <= 0) + return; /* null result */ + + for (i = 0; i < dstWidth; i++) { + GLfloat sumR = 0.0; + GLfloat sumG = 0.0; + GLfloat sumB = 0.0; + GLfloat sumA = 0.0; + for (n = 0; n < filterWidth; n++) { + sumR += src[i + n][RCOMP] * filter[n][RCOMP]; + sumG += src[i + n][GCOMP] * filter[n][GCOMP]; + sumB += src[i + n][BCOMP] * filter[n][BCOMP]; + sumA += src[i + n][ACOMP] * filter[n][ACOMP]; + } + dest[i][RCOMP] = sumR; + dest[i][GCOMP] = sumG; + dest[i][BCOMP] = sumB; + dest[i][ACOMP] = sumA; + } +} + + +static void +convolve_1d_constant(GLint srcWidth, const GLfloat src[][4], + GLint filterWidth, const GLfloat filter[][4], + GLfloat dest[][4], + const GLfloat borderColor[4]) +{ + const GLint halfFilterWidth = filterWidth / 2; + GLint i, n; + + for (i = 0; i < srcWidth; i++) { + GLfloat sumR = 0.0; + GLfloat sumG = 0.0; + GLfloat sumB = 0.0; + GLfloat sumA = 0.0; + for (n = 0; n < filterWidth; n++) { + if (i + n < halfFilterWidth || i + n - halfFilterWidth >= srcWidth) { + sumR += borderColor[RCOMP] * filter[n][RCOMP]; + sumG += borderColor[GCOMP] * filter[n][GCOMP]; + sumB += borderColor[BCOMP] * filter[n][BCOMP]; + sumA += borderColor[ACOMP] * filter[n][ACOMP]; + } + else { + sumR += src[i + n - halfFilterWidth][RCOMP] * filter[n][RCOMP]; + sumG += src[i + n - halfFilterWidth][GCOMP] * filter[n][GCOMP]; + sumB += src[i + n - halfFilterWidth][BCOMP] * filter[n][BCOMP]; + sumA += src[i + n - halfFilterWidth][ACOMP] * filter[n][ACOMP]; + } + } + dest[i][RCOMP] = sumR; + dest[i][GCOMP] = sumG; + dest[i][BCOMP] = sumB; + dest[i][ACOMP] = sumA; + } +} + + +static void +convolve_1d_replicate(GLint srcWidth, const GLfloat src[][4], + GLint filterWidth, const GLfloat filter[][4], + GLfloat dest[][4]) +{ + const GLint halfFilterWidth = filterWidth / 2; + GLint i, n; + + for (i = 0; i < srcWidth; i++) { + GLfloat sumR = 0.0; + GLfloat sumG = 0.0; + GLfloat sumB = 0.0; + GLfloat sumA = 0.0; + for (n = 0; n < filterWidth; n++) { + if (i + n < halfFilterWidth) { + sumR += src[0][RCOMP] * filter[n][RCOMP]; + sumG += src[0][GCOMP] * filter[n][GCOMP]; + sumB += src[0][BCOMP] * filter[n][BCOMP]; + sumA += src[0][ACOMP] * filter[n][ACOMP]; + } + else if (i + n - halfFilterWidth >= srcWidth) { + sumR += src[srcWidth - 1][RCOMP] * filter[n][RCOMP]; + sumG += src[srcWidth - 1][GCOMP] * filter[n][GCOMP]; + sumB += src[srcWidth - 1][BCOMP] * filter[n][BCOMP]; + sumA += src[srcWidth - 1][ACOMP] * filter[n][ACOMP]; + } + else { + sumR += src[i + n - halfFilterWidth][RCOMP] * filter[n][RCOMP]; + sumG += src[i + n - halfFilterWidth][GCOMP] * filter[n][GCOMP]; + sumB += src[i + n - halfFilterWidth][BCOMP] * filter[n][BCOMP]; + sumA += src[i + n - halfFilterWidth][ACOMP] * filter[n][ACOMP]; + } + } + dest[i][RCOMP] = sumR; + dest[i][GCOMP] = sumG; + dest[i][BCOMP] = sumB; + dest[i][ACOMP] = sumA; + } +} + + +static void +convolve_2d_reduce(GLint srcWidth, GLint srcHeight, + const GLfloat src[][4], + GLint filterWidth, GLint filterHeight, + const GLfloat filter[][4], + GLfloat dest[][4]) +{ + GLint dstWidth, dstHeight; + GLint i, j, n, m; + + if (filterWidth >= 1) + dstWidth = srcWidth - (filterWidth - 1); + else + dstWidth = srcWidth; + + if (filterHeight >= 1) + dstHeight = srcHeight - (filterHeight - 1); + else + dstHeight = srcHeight; + + if (dstWidth <= 0 || dstHeight <= 0) + return; + + for (j = 0; j < dstHeight; j++) { + for (i = 0; i < dstWidth; i++) { + GLfloat sumR = 0.0; + GLfloat sumG = 0.0; + GLfloat sumB = 0.0; + GLfloat sumA = 0.0; + for (m = 0; m < filterHeight; m++) { + for (n = 0; n < filterWidth; n++) { + const GLint k = (j + m) * srcWidth + i + n; + const GLint f = m * filterWidth + n; + sumR += src[k][RCOMP] * filter[f][RCOMP]; + sumG += src[k][GCOMP] * filter[f][GCOMP]; + sumB += src[k][BCOMP] * filter[f][BCOMP]; + sumA += src[k][ACOMP] * filter[f][ACOMP]; + } + } + dest[j * dstWidth + i][RCOMP] = sumR; + dest[j * dstWidth + i][GCOMP] = sumG; + dest[j * dstWidth + i][BCOMP] = sumB; + dest[j * dstWidth + i][ACOMP] = sumA; + } + } +} + + +static void +convolve_2d_constant(GLint srcWidth, GLint srcHeight, + const GLfloat src[][4], + GLint filterWidth, GLint filterHeight, + const GLfloat filter[][4], + GLfloat dest[][4], + const GLfloat borderColor[4]) +{ + const GLint halfFilterWidth = filterWidth / 2; + const GLint halfFilterHeight = filterHeight / 2; + GLint i, j, n, m; + + for (j = 0; j < srcHeight; j++) { + for (i = 0; i < srcWidth; i++) { + GLfloat sumR = 0.0; + GLfloat sumG = 0.0; + GLfloat sumB = 0.0; + GLfloat sumA = 0.0; + for (m = 0; m < filterHeight; m++) { + for (n = 0; n < filterWidth; n++) { + const GLint f = m * filterWidth + n; + const GLint is = i + n - halfFilterWidth; + const GLint js = j + m - halfFilterHeight; + if (is < 0 || is >= srcWidth || + js < 0 || js >= srcHeight) { + sumR += borderColor[RCOMP] * filter[f][RCOMP]; + sumG += borderColor[GCOMP] * filter[f][GCOMP]; + sumB += borderColor[BCOMP] * filter[f][BCOMP]; + sumA += borderColor[ACOMP] * filter[f][ACOMP]; + } + else { + const GLint k = js * srcWidth + is; + sumR += src[k][RCOMP] * filter[f][RCOMP]; + sumG += src[k][GCOMP] * filter[f][GCOMP]; + sumB += src[k][BCOMP] * filter[f][BCOMP]; + sumA += src[k][ACOMP] * filter[f][ACOMP]; + } + } + } + dest[j * srcWidth + i][RCOMP] = sumR; + dest[j * srcWidth + i][GCOMP] = sumG; + dest[j * srcWidth + i][BCOMP] = sumB; + dest[j * srcWidth + i][ACOMP] = sumA; + } + } +} + + +static void +convolve_2d_replicate(GLint srcWidth, GLint srcHeight, + const GLfloat src[][4], + GLint filterWidth, GLint filterHeight, + const GLfloat filter[][4], + GLfloat dest[][4]) +{ + const GLint halfFilterWidth = filterWidth / 2; + const GLint halfFilterHeight = filterHeight / 2; + GLint i, j, n, m; + + for (j = 0; j < srcHeight; j++) { + for (i = 0; i < srcWidth; i++) { + GLfloat sumR = 0.0; + GLfloat sumG = 0.0; + GLfloat sumB = 0.0; + GLfloat sumA = 0.0; + for (m = 0; m < filterHeight; m++) { + for (n = 0; n < filterWidth; n++) { + const GLint f = m * filterWidth + n; + GLint is = i + n - halfFilterWidth; + GLint js = j + m - halfFilterHeight; + GLint k; + if (is < 0) + is = 0; + else if (is >= srcWidth) + is = srcWidth - 1; + if (js < 0) + js = 0; + else if (js >= srcHeight) + js = srcHeight - 1; + k = js * srcWidth + is; + sumR += src[k][RCOMP] * filter[f][RCOMP]; + sumG += src[k][GCOMP] * filter[f][GCOMP]; + sumB += src[k][BCOMP] * filter[f][BCOMP]; + sumA += src[k][ACOMP] * filter[f][ACOMP]; + } + } + dest[j * srcWidth + i][RCOMP] = sumR; + dest[j * srcWidth + i][GCOMP] = sumG; + dest[j * srcWidth + i][BCOMP] = sumB; + dest[j * srcWidth + i][ACOMP] = sumA; + } + } +} + + +static void +convolve_sep_reduce(GLint srcWidth, GLint srcHeight, + const GLfloat src[][4], + GLint filterWidth, GLint filterHeight, + const GLfloat rowFilt[][4], + const GLfloat colFilt[][4], + GLfloat dest[][4]) +{ + GLint dstWidth, dstHeight; + GLint i, j, n, m; + + if (filterWidth >= 1) + dstWidth = srcWidth - (filterWidth - 1); + else + dstWidth = srcWidth; + + if (filterHeight >= 1) + dstHeight = srcHeight - (filterHeight - 1); + else + dstHeight = srcHeight; + + if (dstWidth <= 0 || dstHeight <= 0) + return; + + for (j = 0; j < dstHeight; j++) { + for (i = 0; i < dstWidth; i++) { + GLfloat sumR = 0.0; + GLfloat sumG = 0.0; + GLfloat sumB = 0.0; + GLfloat sumA = 0.0; + for (m = 0; m < filterHeight; m++) { + for (n = 0; n < filterWidth; n++) { + GLint k = (j + m) * srcWidth + i + n; + sumR += src[k][RCOMP] * rowFilt[n][RCOMP] * colFilt[m][RCOMP]; + sumG += src[k][GCOMP] * rowFilt[n][GCOMP] * colFilt[m][GCOMP]; + sumB += src[k][BCOMP] * rowFilt[n][BCOMP] * colFilt[m][BCOMP]; + sumA += src[k][ACOMP] * rowFilt[n][ACOMP] * colFilt[m][ACOMP]; + } + } + dest[j * dstWidth + i][RCOMP] = sumR; + dest[j * dstWidth + i][GCOMP] = sumG; + dest[j * dstWidth + i][BCOMP] = sumB; + dest[j * dstWidth + i][ACOMP] = sumA; + } + } +} + + +static void +convolve_sep_constant(GLint srcWidth, GLint srcHeight, + const GLfloat src[][4], + GLint filterWidth, GLint filterHeight, + const GLfloat rowFilt[][4], + const GLfloat colFilt[][4], + GLfloat dest[][4], + const GLfloat borderColor[4]) +{ + const GLint halfFilterWidth = filterWidth / 2; + const GLint halfFilterHeight = filterHeight / 2; + GLint i, j, n, m; + + for (j = 0; j < srcHeight; j++) { + for (i = 0; i < srcWidth; i++) { + GLfloat sumR = 0.0; + GLfloat sumG = 0.0; + GLfloat sumB = 0.0; + GLfloat sumA = 0.0; + for (m = 0; m < filterHeight; m++) { + for (n = 0; n < filterWidth; n++) { + const GLint is = i + n - halfFilterWidth; + const GLint js = j + m - halfFilterHeight; + if (is < 0 || is >= srcWidth || + js < 0 || js >= srcHeight) { + sumR += borderColor[RCOMP] * rowFilt[n][RCOMP] * colFilt[m][RCOMP]; + sumG += borderColor[GCOMP] * rowFilt[n][GCOMP] * colFilt[m][GCOMP]; + sumB += borderColor[BCOMP] * rowFilt[n][BCOMP] * colFilt[m][BCOMP]; + sumA += borderColor[ACOMP] * rowFilt[n][ACOMP] * colFilt[m][ACOMP]; + } + else { + GLint k = js * srcWidth + is; + sumR += src[k][RCOMP] * rowFilt[n][RCOMP] * colFilt[m][RCOMP]; + sumG += src[k][GCOMP] * rowFilt[n][GCOMP] * colFilt[m][GCOMP]; + sumB += src[k][BCOMP] * rowFilt[n][BCOMP] * colFilt[m][BCOMP]; + sumA += src[k][ACOMP] * rowFilt[n][ACOMP] * colFilt[m][ACOMP]; + } + + } + } + dest[j * srcWidth + i][RCOMP] = sumR; + dest[j * srcWidth + i][GCOMP] = sumG; + dest[j * srcWidth + i][BCOMP] = sumB; + dest[j * srcWidth + i][ACOMP] = sumA; + } + } +} + + +static void +convolve_sep_replicate(GLint srcWidth, GLint srcHeight, + const GLfloat src[][4], + GLint filterWidth, GLint filterHeight, + const GLfloat rowFilt[][4], + const GLfloat colFilt[][4], + GLfloat dest[][4]) +{ + const GLint halfFilterWidth = filterWidth / 2; + const GLint halfFilterHeight = filterHeight / 2; + GLint i, j, n, m; + + for (j = 0; j < srcHeight; j++) { + for (i = 0; i < srcWidth; i++) { + GLfloat sumR = 0.0; + GLfloat sumG = 0.0; + GLfloat sumB = 0.0; + GLfloat sumA = 0.0; + for (m = 0; m < filterHeight; m++) { + for (n = 0; n < filterWidth; n++) { + GLint is = i + n - halfFilterWidth; + GLint js = j + m - halfFilterHeight; + GLint k; + if (is < 0) + is = 0; + else if (is >= srcWidth) + is = srcWidth - 1; + if (js < 0) + js = 0; + else if (js >= srcHeight) + js = srcHeight - 1; + k = js * srcWidth + is; + sumR += src[k][RCOMP] * rowFilt[n][RCOMP] * colFilt[m][RCOMP]; + sumG += src[k][GCOMP] * rowFilt[n][GCOMP] * colFilt[m][GCOMP]; + sumB += src[k][BCOMP] * rowFilt[n][BCOMP] * colFilt[m][BCOMP]; + sumA += src[k][ACOMP] * rowFilt[n][ACOMP] * colFilt[m][ACOMP]; + } + } + dest[j * srcWidth + i][RCOMP] = sumR; + dest[j * srcWidth + i][GCOMP] = sumG; + dest[j * srcWidth + i][BCOMP] = sumB; + dest[j * srcWidth + i][ACOMP] = sumA; + } + } +} + + + +void +_mesa_convolve_1d_image(const GLcontext *ctx, GLsizei *width, + const GLfloat *srcImage, GLfloat *dstImage) +{ + switch (ctx->Pixel.ConvolutionBorderMode[0]) { + case GL_REDUCE: + convolve_1d_reduce(*width, (const GLfloat (*)[4]) srcImage, + ctx->Convolution1D.Width, + (const GLfloat (*)[4]) ctx->Convolution1D.Filter, + (GLfloat (*)[4]) dstImage); + *width = *width - (MAX2(ctx->Convolution1D.Width, 1) - 1); + break; + case GL_CONSTANT_BORDER: + convolve_1d_constant(*width, (const GLfloat (*)[4]) srcImage, + ctx->Convolution1D.Width, + (const GLfloat (*)[4]) ctx->Convolution1D.Filter, + (GLfloat (*)[4]) dstImage, + ctx->Pixel.ConvolutionBorderColor[0]); + break; + case GL_REPLICATE_BORDER: + convolve_1d_replicate(*width, (const GLfloat (*)[4]) srcImage, + ctx->Convolution1D.Width, + (const GLfloat (*)[4]) ctx->Convolution1D.Filter, + (GLfloat (*)[4]) dstImage); + break; + default: + ; + } +} + + +void +_mesa_convolve_2d_image(const GLcontext *ctx, GLsizei *width, GLsizei *height, + const GLfloat *srcImage, GLfloat *dstImage) +{ + switch (ctx->Pixel.ConvolutionBorderMode[1]) { + case GL_REDUCE: + convolve_2d_reduce(*width, *height, + (const GLfloat (*)[4]) srcImage, + ctx->Convolution2D.Width, + ctx->Convolution2D.Height, + (const GLfloat (*)[4]) ctx->Convolution2D.Filter, + (GLfloat (*)[4]) dstImage); + *width = *width - (MAX2(ctx->Convolution2D.Width, 1) - 1); + *height = *height - (MAX2(ctx->Convolution2D.Height, 1) - 1); + break; + case GL_CONSTANT_BORDER: + convolve_2d_constant(*width, *height, + (const GLfloat (*)[4]) srcImage, + ctx->Convolution2D.Width, + ctx->Convolution2D.Height, + (const GLfloat (*)[4]) ctx->Convolution2D.Filter, + (GLfloat (*)[4]) dstImage, + ctx->Pixel.ConvolutionBorderColor[1]); + break; + case GL_REPLICATE_BORDER: + convolve_2d_replicate(*width, *height, + (const GLfloat (*)[4]) srcImage, + ctx->Convolution2D.Width, + ctx->Convolution2D.Height, + (const GLfloat (*)[4])ctx->Convolution2D.Filter, + (GLfloat (*)[4]) dstImage); + break; + default: + ; + } +} + + +void +_mesa_convolve_sep_image(const GLcontext *ctx, + GLsizei *width, GLsizei *height, + const GLfloat *srcImage, GLfloat *dstImage) +{ + const GLfloat *rowFilter = ctx->Separable2D.Filter; + const GLfloat *colFilter = rowFilter + 4 * MAX_CONVOLUTION_WIDTH; + + switch (ctx->Pixel.ConvolutionBorderMode[2]) { + case GL_REDUCE: + convolve_sep_reduce(*width, *height, + (const GLfloat (*)[4]) srcImage, + ctx->Separable2D.Width, + ctx->Separable2D.Height, + (const GLfloat (*)[4]) rowFilter, + (const GLfloat (*)[4]) colFilter, + (GLfloat (*)[4]) dstImage); + *width = *width - (MAX2(ctx->Separable2D.Width, 1) - 1); + *height = *height - (MAX2(ctx->Separable2D.Height, 1) - 1); + break; + case GL_CONSTANT_BORDER: + convolve_sep_constant(*width, *height, + (const GLfloat (*)[4]) srcImage, + ctx->Separable2D.Width, + ctx->Separable2D.Height, + (const GLfloat (*)[4]) rowFilter, + (const GLfloat (*)[4]) colFilter, + (GLfloat (*)[4]) dstImage, + ctx->Pixel.ConvolutionBorderColor[2]); + break; + case GL_REPLICATE_BORDER: + convolve_sep_replicate(*width, *height, + (const GLfloat (*)[4]) srcImage, + ctx->Separable2D.Width, + ctx->Separable2D.Height, + (const GLfloat (*)[4]) rowFilter, + (const GLfloat (*)[4]) colFilter, + (GLfloat (*)[4]) dstImage); + break; + default: + ; + } +} + + + +/* + * This function computes an image's size after convolution. + * If the convolution border mode is GL_REDUCE, the post-convolution + * image will be smaller than the original. + */ +void +_mesa_adjust_image_for_convolution(const GLcontext *ctx, GLuint dimensions, + GLsizei *width, GLsizei *height) +{ + if (ctx->Pixel.Convolution1DEnabled + && dimensions == 1 + && ctx->Pixel.ConvolutionBorderMode[0] == GL_REDUCE) { + *width = *width - (MAX2(ctx->Convolution1D.Width, 1) - 1); + } + else if (ctx->Pixel.Convolution2DEnabled + && dimensions > 1 + && ctx->Pixel.ConvolutionBorderMode[1] == GL_REDUCE) { + *width = *width - (MAX2(ctx->Convolution2D.Width, 1) - 1); + *height = *height - (MAX2(ctx->Convolution2D.Height, 1) - 1); + } + else if (ctx->Pixel.Separable2DEnabled + && dimensions > 1 + && ctx->Pixel.ConvolutionBorderMode[2] == GL_REDUCE) { + *width = *width - (MAX2(ctx->Separable2D.Width, 1) - 1); + *height = *height - (MAX2(ctx->Separable2D.Height, 1) - 1); + } +} Index: dll/opengl/opengl32/mesa/convolve.h =================================================================== --- dll/opengl/opengl32/mesa/convolve.h (revision 0) +++ dll/opengl/opengl32/mesa/convolve.h (working copy) @@ -0,0 +1,108 @@ +/* $Id: convolve.h,v 1.4 2001/02/06 17:22:16 brianp Exp $ */ + +/* + * Mesa 3-D graphics library + * Version: 3.5 + * + * Copyright (C) 1999-2001 Brian Paul 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 + * BRIAN PAUL 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. + */ + + +#ifndef CONVOLVE_H +#define CONVOLVE_H + + +#include "mtypes.h" + + +extern void +_mesa_ConvolutionFilter1D(GLenum target, GLenum internalformat, GLsizei width, + GLenum format, GLenum type, const GLvoid *image); + +extern void +_mesa_ConvolutionFilter2D(GLenum target, GLenum internalformat, GLsizei width, + GLsizei height, GLenum format, GLenum type, + const GLvoid *image); + +extern void +_mesa_ConvolutionParameterf(GLenum target, GLenum pname, GLfloat params); + +extern void +_mesa_ConvolutionParameterfv(GLenum target, GLenum pname, + const GLfloat *params); + +extern void +_mesa_ConvolutionParameteri(GLenum target, GLenum pname, GLint params); + +extern void +_mesa_ConvolutionParameteriv(GLenum target, GLenum pname, const GLint *params); + +extern void +_mesa_CopyConvolutionFilter1D(GLenum target, GLenum internalformat, + GLint x, GLint y, GLsizei width); + +extern void +_mesa_CopyConvolutionFilter2D(GLenum target, GLenum internalformat, + GLint x, GLint y, GLsizei width, GLsizei height); + +extern void +_mesa_GetConvolutionFilter(GLenum target, GLenum format, GLenum type, + GLvoid *image); + +extern void +_mesa_GetConvolutionParameterfv(GLenum target, GLenum pname, GLfloat *params); + +extern void +_mesa_GetConvolutionParameteriv(GLenum target, GLenum pname, GLint *params); + +extern void +_mesa_GetSeparableFilter(GLenum target, GLenum format, GLenum type, + GLvoid *row, GLvoid *column, GLvoid *span); + +extern void +_mesa_SeparableFilter2D(GLenum target, GLenum internalformat, + GLsizei width, GLsizei height, + GLenum format, GLenum type, + const GLvoid *row, const GLvoid *column); + + + +extern void +_mesa_convolve_1d_image(const GLcontext *ctx, GLsizei *width, + const GLfloat *srcImage, GLfloat *dstImage); + + +extern void +_mesa_convolve_2d_image(const GLcontext *ctx, GLsizei *width, GLsizei *height, + const GLfloat *srcImage, GLfloat *dstImage); + + +extern void +_mesa_convolve_sep_image(const GLcontext *ctx, + GLsizei *width, GLsizei *height, + const GLfloat *srcImage, GLfloat *dstImage); + + +extern void +_mesa_adjust_image_for_convolution(const GLcontext *ctx, GLuint dimensions, + GLsizei *width, GLsizei *height); + + +#endif Index: dll/opengl/opengl32/mesa/dd.h =================================================================== --- dll/opengl/opengl32/mesa/dd.h (revision 0) +++ dll/opengl/opengl32/mesa/dd.h (working copy) @@ -0,0 +1,747 @@ +/* $Id: dd.h,v 1.62 2001/06/15 14:18:46 brianp Exp $ */ + +/* + * Mesa 3-D graphics library + * Version: 3.5 + * + * Copyright (C) 1999-2001 Brian Paul 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 + * BRIAN PAUL 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. + */ + + + +#ifndef DD_INCLUDED +#define DD_INCLUDED + +/* THIS FILE ONLY INCLUDED BY mtypes.h !!!!! */ + +struct gl_pixelstore_attrib; + +/* Mask bits sent to the driver Clear() function */ +#define DD_FRONT_LEFT_BIT FRONT_LEFT_BIT /* 1 */ +#define DD_FRONT_RIGHT_BIT FRONT_RIGHT_BIT /* 2 */ +#define DD_BACK_LEFT_BIT BACK_LEFT_BIT /* 4 */ +#define DD_BACK_RIGHT_BIT BACK_RIGHT_BIT /* 8 */ +#define DD_DEPTH_BIT GL_DEPTH_BUFFER_BIT /* 0x00000100 */ +#define DD_STENCIL_BIT GL_STENCIL_BUFFER_BIT /* 0x00000400 */ +#define DD_ACCUM_BIT GL_ACCUM_BUFFER_BIT /* 0x00000200 */ + + +/* + * Device Driver function table. + */ +struct dd_function_table { + + /********************************************************************** + *** Mandatory functions: these functions must be implemented by *** + *** every device driver. *** + **********************************************************************/ + + const GLubyte * (*GetString)( GLcontext *ctx, GLenum name ); + /* Return a string as needed by glGetString(). + * Only the GL_RENDERER token must be implemented. Otherwise, + * NULL can be returned. + */ + + void (*UpdateState)( GLcontext *ctx, GLuint new_state ); + /* + * UpdateState() is called to notify the driver after Mesa has made + * some internal state changes. This is in addition to any + * statechange callbacks Mesa may already have made. + */ + + void (*Clear)( GLcontext *ctx, GLbitfield mask, GLboolean all, + GLint x, GLint y, GLint width, GLint height ); + /* Clear the color/depth/stencil/accum buffer(s). + * 'mask' is a bitmask of the DD_*_BIT values defined above that indicates + * which buffers need to be cleared. + * If 'all' is true then the clear the whole buffer, else clear only the + * region defined by (x,y,width,height). + * This function must obey the glColorMask, glIndexMask and glStencilMask + * settings! Software Mesa can do masked clears if the device driver can't. + */ + + GLboolean (*SetDrawBuffer)( GLcontext *ctx, GLenum buffer ); + /* + * Specifies the current buffer for writing. + * The following values must be accepted when applicable: + * GL_FRONT_LEFT - this buffer always exists + * GL_BACK_LEFT - when double buffering + * GL_FRONT_RIGHT - when using stereo + * GL_BACK_RIGHT - when using stereo and double buffering + * The folowing values may optionally be accepted. Return GL_TRUE + * if accepted, GL_FALSE if not accepted. In practice, only drivers + * which can write to multiple color buffers at once should accept + * these values. + * GL_FRONT - write to front left and front right if it exists + * GL_BACK - write to back left and back right if it exists + * GL_LEFT - write to front left and back left if it exists + * GL_RIGHT - write to right left and back right if they exist + * GL_FRONT_AND_BACK - write to all four buffers if they exist + * GL_NONE - disable buffer write in device driver. + */ + + void (*GetBufferSize)( GLcontext *ctx, GLuint *width, GLuint *height ); + /* + * Returns the width and height of the current color buffer. + */ + + void (*Finish)( GLcontext *ctx ); + /* + * This is called whenever glFinish() is called. + */ + + void (*Flush)( GLcontext *ctx ); + /* + * This is called whenever glFlush() is called. + */ + + void (*Error)( GLcontext *ctx ); + /* + * Called whenever an error is generated. ctx->ErrorValue contains + * the error value. + */ + + + /*** + *** For hardware accumulation buffer: + ***/ + void (*Accum)( GLcontext *ctx, GLenum op, GLfloat value, + GLint xpos, GLint ypos, GLint width, GLint height ); + /* Execute glAccum command within the given scissor region. + */ + + + /*** + *** glDraw/Read/CopyPixels and glBitmap functions: + ***/ + + void (*DrawPixels)( GLcontext *ctx, + GLint x, GLint y, GLsizei width, GLsizei height, + GLenum format, GLenum type, + const struct gl_pixelstore_attrib *unpack, + const GLvoid *pixels ); + /* This is called by glDrawPixels. + * 'unpack' describes how to unpack the source image data. + */ + + void (*ReadPixels)( GLcontext *ctx, + GLint x, GLint y, GLsizei width, GLsizei height, + GLenum format, GLenum type, + const struct gl_pixelstore_attrib *unpack, + GLvoid *dest ); + /* Called by glReadPixels. + */ + + void (*CopyPixels)( GLcontext *ctx, + GLint srcx, GLint srcy, + GLsizei width, GLsizei height, + GLint dstx, GLint dsty, GLenum type ); + /* Do a glCopyPixels. This function must respect all rasterization + * state, glPixelTransfer, glPixelZoom, etc. + */ + + void (*Bitmap)( GLcontext *ctx, + GLint x, GLint y, GLsizei width, GLsizei height, + const struct gl_pixelstore_attrib *unpack, + const GLubyte *bitmap ); + /* This is called by glBitmap. Works the same as DrawPixels, above. + */ + + void (*ResizeBuffersMESA)( GLcontext *ctx ); + + + /*** + *** Texture image functions: + ***/ + const struct gl_texture_format * + (*ChooseTextureFormat)( GLcontext *ctx, GLint internalFormat, + GLenum srcFormat, GLenum srcType ); + /* This is called by the _mesa_store_tex[sub]image[123]d() fallback + * functions. The driver should examine and return a + * pointer to an appropriate gl_texture_format. + */ + + void (*TexImage1D)( GLcontext *ctx, GLenum target, GLint level, + GLint internalFormat, + GLint width, GLint border, + GLenum format, GLenum type, const GLvoid *pixels, + const struct gl_pixelstore_attrib *packing, + struct gl_texture_object *texObj, + struct gl_texture_image *texImage ); + void (*TexImage2D)( GLcontext *ctx, GLenum target, GLint level, + GLint internalFormat, + GLint width, GLint height, GLint border, + GLenum format, GLenum type, const GLvoid *pixels, + const struct gl_pixelstore_attrib *packing, + struct gl_texture_object *texObj, + struct gl_texture_image *texImage ); + void (*TexImage3D)( GLcontext *ctx, GLenum target, GLint level, + GLint internalFormat, + GLint width, GLint height, GLint depth, GLint border, + GLenum format, GLenum type, const GLvoid *pixels, + const struct gl_pixelstore_attrib *packing, + struct gl_texture_object *texObj, + struct gl_texture_image *texImage ); + /* Called by glTexImage1/2/3D. + * Arguments: + * , , , and are user specified. + * indicates the image packing of pixels. + * is the target texture object. + * is the target texture image. It will have the texture + * width, height, depth, border and internalFormat information. + * is returned by this function and indicates whether + * core Mesa should keep an internal copy of the texture image. + * Drivers should call a fallback routine from texstore.c if needed. + */ + + void (*TexSubImage1D)( GLcontext *ctx, GLenum target, GLint level, + GLint xoffset, GLsizei width, + GLenum format, GLenum type, + const GLvoid *pixels, + const struct gl_pixelstore_attrib *packing, + struct gl_texture_object *texObj, + struct gl_texture_image *texImage ); + void (*TexSubImage2D)( GLcontext *ctx, GLenum target, GLint level, + GLint xoffset, GLint yoffset, + GLsizei width, GLsizei height, + GLenum format, GLenum type, + const GLvoid *pixels, + const struct gl_pixelstore_attrib *packing, + struct gl_texture_object *texObj, + struct gl_texture_image *texImage ); + void (*TexSubImage3D)( GLcontext *ctx, GLenum target, GLint level, + GLint xoffset, GLint yoffset, GLint zoffset, + GLsizei width, GLsizei height, GLint depth, + GLenum format, GLenum type, + const GLvoid *pixels, + const struct gl_pixelstore_attrib *packing, + struct gl_texture_object *texObj, + struct gl_texture_image *texImage ); + /* Called by glTexSubImage1/2/3D. + * Arguments: + * , , , , , , , + * , , and are user specified. + * indicates the image packing of pixels. + * is the target texture object. + * is the target texture image. It will have the texture + * width, height, border and internalFormat information. + * The driver should use a fallback routine from texstore.c if needed. + */ + + void (*CopyTexImage1D)( GLcontext *ctx, GLenum target, GLint level, + GLenum internalFormat, GLint x, GLint y, + GLsizei width, GLint border ); + void (*CopyTexImage2D)( GLcontext *ctx, GLenum target, GLint level, + GLenum internalFormat, GLint x, GLint y, + GLsizei width, GLsizei height, GLint border ); + /* Called by glCopyTexImage1D and glCopyTexImage2D. + * Drivers should use a fallback routine from texstore.c if needed. + */ + + void (*CopyTexSubImage1D)( GLcontext *ctx, GLenum target, GLint level, + GLint xoffset, + GLint x, GLint y, GLsizei width ); + void (*CopyTexSubImage2D)( GLcontext *ctx, GLenum target, GLint level, + GLint xoffset, GLint yoffset, + GLint x, GLint y, + GLsizei width, GLsizei height ); + void (*CopyTexSubImage3D)( GLcontext *ctx, GLenum target, GLint level, + GLint xoffset, GLint yoffset, GLint zoffset, + GLint x, GLint y, + GLsizei width, GLsizei height ); + /* Called by glCopyTexSubImage1/2/3D. + * Drivers should use a fallback routine from texstore.c if needed. + */ + + GLboolean (*TestProxyTexImage)(GLcontext *ctx, GLenum target, + GLint level, GLint internalFormat, + GLenum format, GLenum type, + GLint width, GLint height, + GLint depth, GLint border); + /* Called by glTexImage[123]D when user specifies a proxy texture + * target. Return GL_TRUE if the proxy test passes, return GL_FALSE + * if the test fails. + */ + + /*** + *** Compressed texture functions: + ***/ + + void (*CompressedTexImage1D)( GLcontext *ctx, GLenum target, + GLint level, GLint internalFormat, + GLsizei width, GLint border, + GLsizei imageSize, const GLvoid *data, + struct gl_texture_object *texObj, + struct gl_texture_image *texImage ); + void (*CompressedTexImage2D)( GLcontext *ctx, GLenum target, + GLint level, GLint internalFormat, + GLsizei width, GLsizei height, GLint border, + GLsizei imageSize, const GLvoid *data, + struct gl_texture_object *texObj, + struct gl_texture_image *texImage ); + void (*CompressedTexImage3D)( GLcontext *ctx, GLenum target, + GLint level, GLint internalFormat, + GLsizei width, GLsizei height, GLsizei depth, + GLint border, + GLsizei imageSize, const GLvoid *data, + struct gl_texture_object *texObj, + struct gl_texture_image *texImage ); + /* Called by glCompressedTexImage1/2/3D. + * Arguments: + * , , , are user specified. + * is the target texture object. + * is the target texture image. It will have the texture + * width, height, depth, border and internalFormat information. + * is returned by this function and indicates whether + * core Mesa should keep an internal copy of the texture image. + * Return GL_TRUE if operation completed, return GL_FALSE if core Mesa + * should do the job. + */ + + void (*CompressedTexSubImage1D)(GLcontext *ctx, GLenum target, GLint level, + GLint xoffset, GLsizei width, + GLenum format, + GLsizei imageSize, const GLvoid *data, + struct gl_texture_object *texObj, + struct gl_texture_image *texImage); + void (*CompressedTexSubImage2D)(GLcontext *ctx, GLenum target, GLint level, + GLint xoffset, GLint yoffset, + GLsizei width, GLint height, + GLenum format, + GLsizei imageSize, const GLvoid *data, + struct gl_texture_object *texObj, + struct gl_texture_image *texImage); + void (*CompressedTexSubImage3D)(GLcontext *ctx, GLenum target, GLint level, + GLint xoffset, GLint yoffset, GLint zoffset, + GLsizei width, GLint height, GLint depth, + GLenum format, + GLsizei imageSize, const GLvoid *data, + struct gl_texture_object *texObj, + struct gl_texture_image *texImage); + /* Called by glCompressedTexSubImage1/2/3D. + * Arguments: + * , , , , , , + * , and are user specified. + * is the target texture object. + * is the target texture image. It will have the texture + * width, height, depth, border and internalFormat information. + * Return GL_TRUE if operation completed, return GL_FALSE if core Mesa + * should do the job. + */ + + void (*GetCompressedTexImage)( GLcontext *ctx, GLenum target, + GLint level, void *image, + const struct gl_texture_object *texObj, + struct gl_texture_image *texImage ); + /* Called by glGetCompressedTexImageARB. + * , , are specified by user. + * is the source texture object. + * is the source texture image. + */ + + GLint (*BaseCompressedTexFormat)(GLcontext *ctx, + GLint internalFormat); + /* Called to compute the base format for a specific compressed + * format. Return -1 if the internalFormat is not a specific + * compressed format that the driver recognizes. + * Example: if internalFormat==GL_COMPRESSED_RGB_FXT1_3DFX, return GL_RGB. + */ + + GLint (*CompressedTextureSize)(GLcontext *ctx, + const struct gl_texture_image *texImage); + +#if 000 + /* ... Note the + * return value differences between this function and + * SpecificCompressedTexFormat below. + */ + + GLint (*SpecificCompressedTexFormat)(GLcontext *ctx, + GLint internalFormat, + GLint numDimensions, + GLint *levelp, + GLsizei *widthp, + GLsizei *heightp, + GLsizei *depthp, + GLint *borderp, + GLenum *formatp, + GLenum *typep); + /* Called to turn a generic texture format into a specific + * texture format. For example, if a driver implements + * GL_3DFX_texture_compression_FXT1, this would map + * GL_COMPRESSED_RGBA_ARB to GL_COMPRESSED_RGBA_FXT1_3DFX. + * + * If the driver does not know how to handle the compressed + * format, then just return the generic format, and Mesa will + * do the right thing with it. + */ + +#endif + + /*** + *** Texture object functions: + ***/ + + void (*BindTexture)( GLcontext *ctx, GLenum target, + struct gl_texture_object *tObj ); + /* Called by glBindTexture(). + */ + + void (*CreateTexture)( GLcontext *ctx, struct gl_texture_object *tObj ); + /* Called when a texture object is created. + */ + + void (*DeleteTexture)( GLcontext *ctx, struct gl_texture_object *tObj ); + /* Called when a texture object is about to be deallocated. Driver + * should free anything attached to the DriverData pointers. + */ + + GLboolean (*IsTextureResident)( GLcontext *ctx, + struct gl_texture_object *t ); + /* Called by glAreTextureResident(). + */ + + void (*PrioritizeTexture)( GLcontext *ctx, struct gl_texture_object *t, + GLclampf priority ); + /* Called by glPrioritizeTextures(). + */ + + void (*ActiveTexture)( GLcontext *ctx, GLuint texUnitNumber ); + /* Called by glActiveTextureARB to set current texture unit. + */ + + void (*UpdateTexturePalette)( GLcontext *ctx, + struct gl_texture_object *tObj ); + /* Called when the texture's color lookup table is changed. + * If tObj is NULL then the shared texture palette ctx->Texture.Palette + * is to be updated. + */ + + /*** + *** Imaging functionality: + ***/ + void (*CopyColorTable)( GLcontext *ctx, + GLenum target, GLenum internalformat, + GLint x, GLint y, GLsizei width ); + + void (*CopyColorSubTable)( GLcontext *ctx, + GLenum target, GLsizei start, + GLint x, GLint y, GLsizei width ); + + void (*CopyConvolutionFilter1D)( GLcontext *ctx, GLenum target, + GLenum internalFormat, + GLint x, GLint y, GLsizei width ); + + void (*CopyConvolutionFilter2D)( GLcontext *ctx, GLenum target, + GLenum internalFormat, + GLint x, GLint y, + GLsizei width, GLsizei height ); + + + + /*** + *** State-changing functions (drawing functions are above) + *** + *** These functions are called by their corresponding OpenGL API functions. + *** They're ALSO called by the gl_PopAttrib() function!!! + *** May add more functions like these to the device driver in the future. + ***/ + void (*AlphaFunc)(GLcontext *ctx, GLenum func, GLchan ref); + void (*BlendColor)(GLcontext *ctx, const GLfloat color[4]); + void (*BlendEquation)(GLcontext *ctx, GLenum mode); + void (*BlendFunc)(GLcontext *ctx, GLenum sfactor, GLenum dfactor); + void (*BlendFuncSeparate)(GLcontext *ctx, + GLenum sfactorRGB, GLenum dfactorRGB, + GLenum sfactorA, GLenum dfactorA); + void (*ClearColor)(GLcontext *ctx, const GLchan color[4]); + void (*ClearDepth)(GLcontext *ctx, GLclampd d); + void (*ClearIndex)(GLcontext *ctx, GLuint index); + void (*ClearStencil)(GLcontext *ctx, GLint s); + void (*ColorMask)(GLcontext *ctx, GLboolean rmask, GLboolean gmask, + GLboolean bmask, GLboolean amask ); + void (*CullFace)(GLcontext *ctx, GLenum mode); + void (*ClipPlane)(GLcontext *ctx, GLenum plane, const GLfloat *equation ); + void (*FrontFace)(GLcontext *ctx, GLenum mode); + void (*DepthFunc)(GLcontext *ctx, GLenum func); + void (*DepthMask)(GLcontext *ctx, GLboolean flag); + void (*DepthRange)(GLcontext *ctx, GLclampd nearval, GLclampd farval); + void (*Enable)(GLcontext* ctx, GLenum cap, GLboolean state); + void (*Fogfv)(GLcontext *ctx, GLenum pname, const GLfloat *params); + void (*Hint)(GLcontext *ctx, GLenum target, GLenum mode); + void (*IndexMask)(GLcontext *ctx, GLuint mask); + void (*Lightfv)(GLcontext *ctx, GLenum light, + GLenum pname, const GLfloat *params ); + void (*LightModelfv)(GLcontext *ctx, GLenum pname, const GLfloat *params); + void (*LineStipple)(GLcontext *ctx, GLint factor, GLushort pattern ); + void (*LineWidth)(GLcontext *ctx, GLfloat width); + void (*LogicOpcode)(GLcontext *ctx, GLenum opcode); + void (*PointParameterfv)(GLcontext *ctx, GLenum pname, + const GLfloat *params); + void (*PointSize)(GLcontext *ctx, GLfloat size); + void (*PolygonMode)(GLcontext *ctx, GLenum face, GLenum mode); + void (*PolygonOffset)(GLcontext *ctx, GLfloat factor, GLfloat units); + void (*PolygonStipple)(GLcontext *ctx, const GLubyte *mask ); + void (*RenderMode)(GLcontext *ctx, GLenum mode ); + void (*Scissor)(GLcontext *ctx, GLint x, GLint y, GLsizei w, GLsizei h); + void (*ShadeModel)(GLcontext *ctx, GLenum mode); + void (*StencilFunc)(GLcontext *ctx, GLenum func, GLint ref, GLuint mask); + void (*StencilMask)(GLcontext *ctx, GLuint mask); + void (*StencilOp)(GLcontext *ctx, GLenum fail, GLenum zfail, GLenum zpass); + void (*TexGen)(GLcontext *ctx, GLenum coord, GLenum pname, + const GLfloat *params); + void (*TexEnv)(GLcontext *ctx, GLenum target, GLenum pname, + const GLfloat *param); + void (*TexParameter)(GLcontext *ctx, GLenum target, + struct gl_texture_object *texObj, + GLenum pname, const GLfloat *params); + void (*TextureMatrix)(GLcontext *ctx, GLuint unit, const GLmatrix *mat); + void (*Viewport)(GLcontext *ctx, GLint x, GLint y, GLsizei w, GLsizei h); + + + /*** + *** Vertex array functions + *** + *** Called by the corresponding OpenGL functions. + ***/ + void (*VertexPointer)(GLcontext *ctx, GLint size, GLenum type, + GLsizei stride, const GLvoid *ptr); + void (*NormalPointer)(GLcontext *ctx, GLenum type, + GLsizei stride, const GLvoid *ptr); + void (*ColorPointer)(GLcontext *ctx, GLint size, GLenum type, + GLsizei stride, const GLvoid *ptr); + void (*FogCoordPointer)(GLcontext *ctx, GLenum type, + GLsizei stride, const GLvoid *ptr); + void (*IndexPointer)(GLcontext *ctx, GLenum type, + GLsizei stride, const GLvoid *ptr); + void (*SecondaryColorPointer)(GLcontext *ctx, GLint size, GLenum type, + GLsizei stride, const GLvoid *ptr); + void (*TexCoordPointer)(GLcontext *ctx, GLint size, GLenum type, + GLsizei stride, const GLvoid *ptr); + void (*EdgeFlagPointer)(GLcontext *ctx, GLsizei stride, const GLvoid *ptr); + + + /*** State-query functions + *** + *** Return GL_TRUE if query was completed, GL_FALSE otherwise. + ***/ + GLboolean (*GetBooleanv)(GLcontext *ctx, GLenum pname, GLboolean *result); + GLboolean (*GetDoublev)(GLcontext *ctx, GLenum pname, GLdouble *result); + GLboolean (*GetFloatv)(GLcontext *ctx, GLenum pname, GLfloat *result); + GLboolean (*GetIntegerv)(GLcontext *ctx, GLenum pname, GLint *result); + GLboolean (*GetPointerv)(GLcontext *ctx, GLenum pname, GLvoid **result); + + + + /*** + *** Support for multiple t&l engines + ***/ + + GLuint NeedValidate; + /* Bitmask of state changes that require the current tnl module to be + * validated, using ValidateTnlModule() below. + */ + + void (*ValidateTnlModule)( GLcontext *ctx, GLuint new_state ); + /* Validate the current tnl module. This is called directly after + * UpdateState() when a state change that has occured matches the + * NeedValidate bitmask above. This ensures all computed values are + * up to date, thus allowing the driver to decide if the current tnl + * module needs to be swapped out. + * + * This must be non-NULL if a driver installs a custom tnl module and + * sets the NeedValidate bitmask, but may be NULL otherwise. + */ + + +#define PRIM_OUTSIDE_BEGIN_END GL_POLYGON+1 +#define PRIM_INSIDE_UNKNOWN_PRIM GL_POLYGON+2 +#define PRIM_UNKNOWN GL_POLYGON+3 + + GLuint CurrentExecPrimitive; + /* Set by the driver-supplied t&l engine. Set to + * PRIM_OUTSIDE_BEGIN_END when outside begin/end. + */ + + GLuint CurrentSavePrimitive; + /* Current state of an in-progress compilation. May take on any of + * the additional values defined above. + */ + + +#define FLUSH_STORED_VERTICES 0x1 +#define FLUSH_UPDATE_CURRENT 0x2 + GLuint NeedFlush; + /* Set by the driver-supplied t&l engine whenever vertices are + * buffered between begin/end objects or ctx->Current is not uptodate. + * + * The FlushVertices() call below may be used to resolve + * these conditions. + */ + + void (*FlushVertices)( GLcontext *ctx, GLuint flags ); + /* If inside begin/end, ASSERT(0). + * Otherwise, + * if (flags & FLUSH_STORED_VERTICES) flushes any buffered vertices, + * if (flags & FLUSH_UPDATE_CURRENT) updates ctx->Current + * and ctx->Light.Material + * + * Note that the default t&l engine never clears the + * FLUSH_UPDATE_CURRENT bit, even after performing the update. + */ + + void (*LightingSpaceChange)( GLcontext *ctx ); + /* Notify driver that the special derived value _NeedEyeCoords has + * changed. + */ + + void (*NewList)( GLcontext *ctx, GLuint list, GLenum mode ); + void (*EndList)( GLcontext *ctx ); + /* Let the t&l component know what is going on with display lists + * in time to make changes to dispatch tables, etc. + * Called by glNewList() and glEndList(), respectively. + */ + + void (*BeginCallList)( GLcontext *ctx, GLuint list ); + void (*EndCallList)( GLcontext *ctx ); + /* Notify the t&l component before and after calling a display list. + * Called by glCallList(s), but not recursively. + */ + + void (*MakeCurrent)( GLcontext *ctx, GLframebuffer *drawBuffer, + GLframebuffer *readBuffer ); + /* Let the t&l component know when the context becomes current. + */ + + + void (*LockArraysEXT)( GLcontext *ctx, GLint first, GLsizei count ); + void (*UnlockArraysEXT)( GLcontext *ctx ); + /* Called by glLockArraysEXT() and glUnlockArraysEXT(), respectively. + */ + +}; + + + +/* + * Transform/Clip/Lighting interface + */ +typedef struct { + void (*ArrayElement)( GLint ); /* NOTE */ + void (*Color3f)( GLfloat, GLfloat, GLfloat ); + void (*Color3fv)( const GLfloat * ); + void (*Color3ub)( GLubyte, GLubyte, GLubyte ); + void (*Color3ubv)( const GLubyte * ); + void (*Color4f)( GLfloat, GLfloat, GLfloat, GLfloat ); + void (*Color4fv)( const GLfloat * ); + void (*Color4ub)( GLubyte, GLubyte, GLubyte, GLubyte ); + void (*Color4ubv)( const GLubyte * ); + void (*EdgeFlag)( GLboolean ); + void (*EdgeFlagv)( const GLboolean * ); + void (*EvalCoord1f)( GLfloat ); /* NOTE */ + void (*EvalCoord1fv)( const GLfloat * ); /* NOTE */ + void (*EvalCoord2f)( GLfloat, GLfloat ); /* NOTE */ + void (*EvalCoord2fv)( const GLfloat * ); /* NOTE */ + void (*EvalPoint1)( GLint ); /* NOTE */ + void (*EvalPoint2)( GLint, GLint ); /* NOTE */ + void (*FogCoordfEXT)( GLfloat ); + void (*FogCoordfvEXT)( const GLfloat * ); + void (*Indexi)( GLint ); + void (*Indexiv)( const GLint * ); + void (*Materialfv)( GLenum face, GLenum pname, const GLfloat * ); /* NOTE */ + void (*MultiTexCoord1fARB)( GLenum, GLfloat ); + void (*MultiTexCoord1fvARB)( GLenum, const GLfloat * ); + void (*MultiTexCoord2fARB)( GLenum, GLfloat, GLfloat ); + void (*MultiTexCoord2fvARB)( GLenum, const GLfloat * ); + void (*MultiTexCoord3fARB)( GLenum, GLfloat, GLfloat, GLfloat ); + void (*MultiTexCoord3fvARB)( GLenum, const GLfloat * ); + void (*MultiTexCoord4fARB)( GLenum, GLfloat, GLfloat, GLfloat, GLfloat ); + void (*MultiTexCoord4fvARB)( GLenum, const GLfloat * ); + void (*Normal3f)( GLfloat, GLfloat, GLfloat ); + void (*Normal3fv)( const GLfloat * ); + void (*SecondaryColor3fEXT)( GLfloat, GLfloat, GLfloat ); + void (*SecondaryColor3fvEXT)( const GLfloat * ); + void (*SecondaryColor3ubEXT)( GLubyte, GLubyte, GLubyte ); + void (*SecondaryColor3ubvEXT)( const GLubyte * ); + void (*TexCoord1f)( GLfloat ); + void (*TexCoord1fv)( const GLfloat * ); + void (*TexCoord2f)( GLfloat, GLfloat ); + void (*TexCoord2fv)( const GLfloat * ); + void (*TexCoord3f)( GLfloat, GLfloat, GLfloat ); + void (*TexCoord3fv)( const GLfloat * ); + void (*TexCoord4f)( GLfloat, GLfloat, GLfloat, GLfloat ); + void (*TexCoord4fv)( const GLfloat * ); + void (*Vertex2f)( GLfloat, GLfloat ); + void (*Vertex2fv)( const GLfloat * ); + void (*Vertex3f)( GLfloat, GLfloat, GLfloat ); + void (*Vertex3fv)( const GLfloat * ); + void (*Vertex4f)( GLfloat, GLfloat, GLfloat, GLfloat ); + void (*Vertex4fv)( const GLfloat * ); + void (*CallList)( GLuint ); /* NOTE */ + void (*Begin)( GLenum ); + void (*End)( void ); + /* Drivers present a reduced set of the functions possible in + * begin/end objects. Core mesa provides translation stubs for the + * remaining functions to map down to these entrypoints. + * + * These are the initial values to be installed into dispatch by + * mesa. If the t&l driver wants to modify the dispatch table + * while installed, it must do so itself. It would be possible for + * the vertexformat to install it's own initial values for these + * functions, but this way there is an obvious list of what is + * expected of the driver. + * + * If the driver wants to hook in entrypoints other than those + * listed above, it must restore them to their original values in + * the disable() callback, below. + */ + + void (*Rectf)( GLfloat, GLfloat, GLfloat, GLfloat ); + /* + */ + + void (*DrawArrays)( GLenum mode, GLint start, GLsizei count ); + void (*DrawElements)( GLenum mode, GLsizei count, GLenum type, + const GLvoid *indices ); + void (*DrawRangeElements)( GLenum mode, GLuint start, + GLuint end, GLsizei count, + GLenum type, const GLvoid *indices ); + /* These may or may not belong here. Heuristic: If an array is + * enabled, the installed vertex format should support that array and + * it's current size natively. + */ + + void (*EvalMesh1)( GLenum mode, GLint i1, GLint i2 ); + void (*EvalMesh2)( GLenum mode, GLint i1, GLint i2, GLint j1, GLint j2 ); + /* If you don't support eval, fallback to the default vertex format + * on receiving an eval call and use the pipeline mechanism to + * provide partial t&l acceleration. + * + * Mesa will provide a set of helper functions to do eval within + * accelerated vertex formats, eventually... + */ + + GLboolean prefer_float_colors; + /* Should core try to send colors to glColor4f or glColor4chan, + * where it has a choice? + */ +} GLvertexformat; + + +#endif /* DD_INCLUDED */ Index: dll/opengl/opengl32/mesa/debug.c =================================================================== --- dll/opengl/opengl32/mesa/debug.c (revision 0) +++ dll/opengl/opengl32/mesa/debug.c (working copy) @@ -0,0 +1,85 @@ +/* $Id: debug.c,v 1.12 2001/03/29 21:16:25 keithw Exp $ */ + +/* + * Mesa 3-D graphics library + * Version: 3.5 + * + * Copyright (C) 1999-2001 Brian Paul 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 + * BRIAN PAUL 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. + */ + +#include "mtypes.h" +#include "debug.h" + +void _mesa_print_state( const char *msg, GLuint state ) +{ + fprintf(stderr, + "%s: (0x%x) %s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s\n", + msg, + state, + (state & _NEW_MODELVIEW) ? "ctx->ModelView, " : "", + (state & _NEW_PROJECTION) ? "ctx->Projection, " : "", + (state & _NEW_TEXTURE_MATRIX) ? "ctx->TextureMatrix, " : "", + (state & _NEW_COLOR_MATRIX) ? "ctx->ColorMatrix, " : "", + (state & _NEW_ACCUM) ? "ctx->Accum, " : "", + (state & _NEW_COLOR) ? "ctx->Color, " : "", + (state & _NEW_DEPTH) ? "ctx->Depth, " : "", + (state & _NEW_EVAL) ? "ctx->Eval/EvalMap, " : "", + (state & _NEW_FOG) ? "ctx->Fog, " : "", + (state & _NEW_HINT) ? "ctx->Hint, " : "", + (state & _NEW_LIGHT) ? "ctx->Light, " : "", + (state & _NEW_LINE) ? "ctx->Line, " : "", + (state & _NEW_PIXEL) ? "ctx->Pixel, " : "", + (state & _NEW_POINT) ? "ctx->Point, " : "", + (state & _NEW_POLYGON) ? "ctx->Polygon, " : "", + (state & _NEW_POLYGONSTIPPLE) ? "ctx->PolygonStipple, " : "", + (state & _NEW_SCISSOR) ? "ctx->Scissor, " : "", + (state & _NEW_TEXTURE) ? "ctx->Texture, " : "", + (state & _NEW_TRANSFORM) ? "ctx->Transform, " : "", + (state & _NEW_VIEWPORT) ? "ctx->Viewport, " : "", + (state & _NEW_PACKUNPACK) ? "ctx->Pack/Unpack, " : "", + (state & _NEW_ARRAY) ? "ctx->Array, " : "", + (state & _NEW_RENDERMODE) ? "ctx->RenderMode, " : "", + (state & _NEW_BUFFERS) ? "ctx->Visual, ctx->DrawBuffer,, " : ""); +} + + + +void _mesa_print_tri_caps( const char *name, GLuint flags ) +{ + fprintf(stderr, + "%s: (0x%x) %s%s%s%s%s%s%s%s%s%s%s%s%s%s\n", + name, + flags, + (flags & DD_FLATSHADE) ? "flat-shade, " : "", + (flags & DD_SEPARATE_SPECULAR) ? "separate-specular, " : "", + (flags & DD_TRI_LIGHT_TWOSIDE) ? "tri-light-twoside, " : "", + (flags & DD_TRI_UNFILLED) ? "tri-unfilled, " : "", + (flags & DD_TRI_STIPPLE) ? "tri-stipple, " : "", + (flags & DD_TRI_OFFSET) ? "tri-offset, " : "", + (flags & DD_TRI_SMOOTH) ? "tri-smooth, " : "", + (flags & DD_LINE_SMOOTH) ? "line-smooth, " : "", + (flags & DD_LINE_STIPPLE) ? "line-stipple, " : "", + (flags & DD_LINE_WIDTH) ? "line-wide, " : "", + (flags & DD_POINT_SMOOTH) ? "point-smooth, " : "", + (flags & DD_POINT_SIZE) ? "point-size, " : "", + (flags & DD_POINT_ATTEN) ? "point-atten, " : "", + (flags & DD_TRI_CULL_FRONT_BACK) ? "cull-all, " : "" + ); +} Index: dll/opengl/opengl32/mesa/debug.h =================================================================== --- dll/opengl/opengl32/mesa/debug.h (revision 0) +++ dll/opengl/opengl32/mesa/debug.h (working copy) @@ -0,0 +1,34 @@ +/* $Id: debug.h,v 1.3 2001/03/12 00:48:37 gareth Exp $ */ + +/* + * Mesa 3-D graphics library + * Version: 3.5 + * + * Copyright (C) 1999-2001 Brian Paul 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 + * BRIAN PAUL 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. + */ + +#ifndef _DEBUG_H +#define _DEBUG_H + +void _mesa_print_tri_caps( const char *name, GLuint flags ); +void _mesa_print_enable_flags( const char *msg, GLuint flags ); +void _mesa_print_state( const char *msg, GLuint state ); + +#endif Index: dll/opengl/opengl32/mesa/depth.c =================================================================== --- dll/opengl/opengl32/mesa/depth.c (revision 0) +++ dll/opengl/opengl32/mesa/depth.c (working copy) @@ -0,0 +1,123 @@ +/* $Id: depth.c,v 1.28 2001/03/29 16:50:32 brianp Exp $ */ + +/* + * Mesa 3-D graphics library + * Version: 3.5 + * + * Copyright (C) 1999-2001 Brian Paul 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 + * BRIAN PAUL 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. + */ + + +#ifdef PC_HEADER +#include "all.h" +#else +#include "glheader.h" +#include "context.h" +#include "enums.h" +#include "depth.h" +#include "macros.h" +#include "mem.h" +#include "mtypes.h" +#endif + + + +/**********************************************************************/ +/***** API Functions *****/ +/**********************************************************************/ + + + +void +_mesa_ClearDepth( GLclampd depth ) +{ + GET_CURRENT_CONTEXT(ctx); + GLfloat tmp = (GLfloat) CLAMP( depth, 0.0, 1.0 ); + ASSERT_OUTSIDE_BEGIN_END(ctx); + + if (ctx->Depth.Clear == tmp) + return; + + FLUSH_VERTICES(ctx, _NEW_DEPTH); + ctx->Depth.Clear = tmp; + if (ctx->Driver.ClearDepth) + (*ctx->Driver.ClearDepth)( ctx, ctx->Depth.Clear ); +} + + + +void +_mesa_DepthFunc( GLenum func ) +{ + GET_CURRENT_CONTEXT(ctx); + ASSERT_OUTSIDE_BEGIN_END(ctx); + + if (MESA_VERBOSE & (VERBOSE_API|VERBOSE_TEXTURE)) + fprintf(stderr, "glDepthFunc %s\n", _mesa_lookup_enum_by_nr(func)); + + switch (func) { + case GL_LESS: /* (default) pass if incoming z < stored z */ + case GL_GEQUAL: + case GL_LEQUAL: + case GL_GREATER: + case GL_NOTEQUAL: + case GL_EQUAL: + case GL_ALWAYS: + case GL_NEVER: + break; + default: + _mesa_error( ctx, GL_INVALID_ENUM, "glDepth.Func" ); + return; + } + + if (ctx->Depth.Func == func) + return; + + FLUSH_VERTICES(ctx, _NEW_DEPTH); + ctx->Depth.Func = func; + + if (ctx->Driver.DepthFunc) + ctx->Driver.DepthFunc( ctx, func ); +} + + + +void +_mesa_DepthMask( GLboolean flag ) +{ + GET_CURRENT_CONTEXT(ctx); + ASSERT_OUTSIDE_BEGIN_END(ctx); + + if (MESA_VERBOSE & (VERBOSE_API|VERBOSE_TEXTURE)) + fprintf(stderr, "glDepthMask %d\n", flag); + + /* + * GL_TRUE indicates depth buffer writing is enabled (default) + * GL_FALSE indicates depth buffer writing is disabled + */ + if (ctx->Depth.Mask == flag) + return; + + FLUSH_VERTICES(ctx, _NEW_DEPTH); + ctx->Depth.Mask = flag; + + if (ctx->Driver.DepthMask) + ctx->Driver.DepthMask( ctx, flag ); +} Index: dll/opengl/opengl32/mesa/depth.h =================================================================== --- dll/opengl/opengl32/mesa/depth.h (revision 0) +++ dll/opengl/opengl32/mesa/depth.h (working copy) @@ -0,0 +1,53 @@ +/* $Id: depth.h,v 1.11 2001/03/12 00:48:37 gareth Exp $ */ + +/* + * Mesa 3-D graphics library + * Version: 3.5 + * + * Copyright (C) 1999-2001 Brian Paul 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 + * BRIAN PAUL 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. + */ + + +#ifndef DEPTH_H +#define DEPTH_H + + +#include "mtypes.h" + + +/* + * Immediate-mode API entrpoints + */ + +extern void +_mesa_ClearDepth( GLclampd depth ); + + +extern void +_mesa_DepthFunc( GLenum func ); + + +extern void +_mesa_DepthMask( GLboolean flag ); + + + + +#endif Index: dll/opengl/opengl32/mesa/dispatch.c =================================================================== --- dll/opengl/opengl32/mesa/dispatch.c (revision 0) +++ dll/opengl/opengl32/mesa/dispatch.c (working copy) @@ -0,0 +1,75 @@ +/* $Id: dispatch.c,v 1.23 2001/06/05 23:54:00 davem69 Exp $ */ + +/* + * Mesa 3-D graphics library + * Version: 3.5 + * + * Copyright (C) 1999-2001 Brian Paul 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 + * BRIAN PAUL 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. + */ + + +/* + * This file generates all the gl* function entyrpoints. + * But if we're using X86-optimized dispatch (X86/glapi_x86.S) then + * we don't use this file's code. + * + * Eventually this file may be replaced by automatically generated + * code from an API spec file. + * + * NOTE: This file should _not_ be used when compiling Mesa for a DRI- + * based device driver. + * + */ + + +#ifdef PC_HEADER +#include "all.h" +#else +#include "glheader.h" +#include "glapi.h" +#include "glapitable.h" +#include "glthread.h" +#endif + +#if !(defined(USE_X86_ASM) || defined(USE_SPARC_ASM)) + +#define KEYWORD1 +#define KEYWORD2 GLAPIENTRY +#if defined(USE_MGL_NAMESPACE) +#define NAME(func) mgl##func +#else +#define NAME(func) gl##func +#endif + +#define DISPATCH(FUNC, ARGS, MESSAGE) \ + (_glapi_Dispatch->FUNC) ARGS + +#define RETURN_DISPATCH(FUNC, ARGS, MESSAGE) \ + return (_glapi_Dispatch->FUNC) ARGS + + +#ifndef GLAPIENTRY +#define GLAPIENTRY +#endif + +#include "glapitemp.h" + + +#endif /* USE_X86_ASM */ Index: dll/opengl/opengl32/mesa/dlist.c =================================================================== --- dll/opengl/opengl32/mesa/dlist.c (revision 0) +++ dll/opengl/opengl32/mesa/dlist.c (working copy) @@ -0,0 +1,6103 @@ +/* $Id: dlist.c,v 1.75 2001/06/18 17:26:08 brianp Exp $ */ + +/* + * Mesa 3-D graphics library + * Version: 3.5 + * + * Copyright (C) 1999-2001 Brian Paul 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 + * BRIAN PAUL 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. + */ + + +#ifdef PC_HEADER +#include "all.h" +#else +#include "glheader.h" +#include "api_loopback.h" +#include "attrib.h" +#include "blend.h" +#include "buffers.h" +#include "clip.h" +#include "colormac.h" +#include "colortab.h" +#include "context.h" +#include "convolve.h" +#include "depth.h" +#include "dlist.h" +#include "enable.h" +#include "enums.h" +#include "eval.h" +#include "extensions.h" +#include "feedback.h" +#include "get.h" +#include "glapi.h" +#include "hash.h" +#include "histogram.h" +#include "image.h" +#include "light.h" +#include "lines.h" +#include "dlist.h" +#include "macros.h" +#include "matrix.h" +#include "mem.h" +#include "pixel.h" +#include "points.h" +#include "polygon.h" +#include "state.h" +#include "texobj.h" +#include "teximage.h" +#include "texstate.h" +#include "mtypes.h" +#include "varray.h" + +#include "math/m_matrix.h" +#include "math/m_xform.h" + +#endif + + + +/* +Functions which aren't compiled but executed immediately: + glIsList + glGenLists + glDeleteLists + glEndList --- BUT: call ctx->Driver.EndList at end of list execution? + glFeedbackBuffer + glSelectBuffer + glRenderMode + glReadPixels + glPixelStore + glFlush + glFinish + glIsEnabled + glGet* + +Functions which cause errors if called while compiling a display list: + glNewList +*/ + + + +/* + * Display list instructions are stored as sequences of "nodes". Nodes + * are allocated in blocks. Each block has BLOCK_SIZE nodes. Blocks + * are linked together with a pointer. + */ + + +/* How many nodes to allocate at a time: + * - reduced now that we hold vertices etc. elsewhere. + */ +#define BLOCK_SIZE 256 + + +/* + * Display list opcodes. + * + * The fact that these identifiers are assigned consecutive + * integer values starting at 0 is very important, see InstSize array usage) + * + */ +typedef enum { + OPCODE_ACCUM, + OPCODE_ALPHA_FUNC, + OPCODE_BIND_TEXTURE, + OPCODE_BITMAP, + OPCODE_BLEND_COLOR, + OPCODE_BLEND_EQUATION, + OPCODE_BLEND_FUNC, + OPCODE_BLEND_FUNC_SEPARATE, + OPCODE_CALL_LIST, + OPCODE_CALL_LIST_OFFSET, + OPCODE_CLEAR, + OPCODE_CLEAR_ACCUM, + OPCODE_CLEAR_COLOR, + OPCODE_CLEAR_DEPTH, + OPCODE_CLEAR_INDEX, + OPCODE_CLEAR_STENCIL, + OPCODE_CLIP_PLANE, + OPCODE_COLOR_MASK, + OPCODE_COLOR_MATERIAL, + OPCODE_COLOR_TABLE, + OPCODE_COLOR_TABLE_PARAMETER_FV, + OPCODE_COLOR_TABLE_PARAMETER_IV, + OPCODE_COLOR_SUB_TABLE, + OPCODE_CONVOLUTION_FILTER_1D, + OPCODE_CONVOLUTION_FILTER_2D, + OPCODE_CONVOLUTION_PARAMETER_I, + OPCODE_CONVOLUTION_PARAMETER_IV, + OPCODE_CONVOLUTION_PARAMETER_F, + OPCODE_CONVOLUTION_PARAMETER_FV, + OPCODE_COPY_COLOR_SUB_TABLE, + OPCODE_COPY_COLOR_TABLE, + OPCODE_COPY_PIXELS, + OPCODE_COPY_TEX_IMAGE1D, + OPCODE_COPY_TEX_IMAGE2D, + OPCODE_COPY_TEX_SUB_IMAGE1D, + OPCODE_COPY_TEX_SUB_IMAGE2D, + OPCODE_COPY_TEX_SUB_IMAGE3D, + OPCODE_CULL_FACE, + OPCODE_DEPTH_FUNC, + OPCODE_DEPTH_MASK, + OPCODE_DEPTH_RANGE, + OPCODE_DISABLE, + OPCODE_DRAW_BUFFER, + OPCODE_DRAW_PIXELS, + OPCODE_ENABLE, + OPCODE_EVALMESH1, + OPCODE_EVALMESH2, + OPCODE_FOG, + OPCODE_FRONT_FACE, + OPCODE_FRUSTUM, + OPCODE_HINT, + OPCODE_HISTOGRAM, + OPCODE_INDEX_MASK, + OPCODE_INIT_NAMES, + OPCODE_LIGHT, + OPCODE_LIGHT_MODEL, + OPCODE_LINE_STIPPLE, + OPCODE_LINE_WIDTH, + OPCODE_LIST_BASE, + OPCODE_LOAD_IDENTITY, + OPCODE_LOAD_MATRIX, + OPCODE_LOAD_NAME, + OPCODE_LOGIC_OP, + OPCODE_MAP1, + OPCODE_MAP2, + OPCODE_MAPGRID1, + OPCODE_MAPGRID2, + OPCODE_MATRIX_MODE, + OPCODE_MIN_MAX, + OPCODE_MULT_MATRIX, + OPCODE_ORTHO, + OPCODE_PASSTHROUGH, + OPCODE_PIXEL_MAP, + OPCODE_PIXEL_TRANSFER, + OPCODE_PIXEL_ZOOM, + OPCODE_POINT_SIZE, + OPCODE_POINT_PARAMETERS, + OPCODE_POLYGON_MODE, + OPCODE_POLYGON_STIPPLE, + OPCODE_POLYGON_OFFSET, + OPCODE_POP_ATTRIB, + OPCODE_POP_MATRIX, + OPCODE_POP_NAME, + OPCODE_PRIORITIZE_TEXTURE, + OPCODE_PUSH_ATTRIB, + OPCODE_PUSH_MATRIX, + OPCODE_PUSH_NAME, + OPCODE_RASTER_POS, + OPCODE_READ_BUFFER, + OPCODE_RESET_HISTOGRAM, + OPCODE_RESET_MIN_MAX, + OPCODE_ROTATE, + OPCODE_SCALE, + OPCODE_SCISSOR, + OPCODE_SELECT_TEXTURE_SGIS, + OPCODE_SELECT_TEXTURE_COORD_SET, + OPCODE_SHADE_MODEL, + OPCODE_STENCIL_FUNC, + OPCODE_STENCIL_MASK, + OPCODE_STENCIL_OP, + OPCODE_TEXENV, + OPCODE_TEXGEN, + OPCODE_TEXPARAMETER, + OPCODE_TEX_IMAGE1D, + OPCODE_TEX_IMAGE2D, + OPCODE_TEX_IMAGE3D, + OPCODE_TEX_SUB_IMAGE1D, + OPCODE_TEX_SUB_IMAGE2D, + OPCODE_TEX_SUB_IMAGE3D, + OPCODE_TRANSLATE, + OPCODE_VIEWPORT, + OPCODE_WINDOW_POS, + /* GL_ARB_multitexture */ + OPCODE_ACTIVE_TEXTURE, + /* GL_SGIX/SGIS_pixel_texture */ + OPCODE_PIXEL_TEXGEN_SGIX, + OPCODE_PIXEL_TEXGEN_PARAMETER_SGIS, + /* GL_ARB_texture_compression */ + OPCODE_COMPRESSED_TEX_IMAGE_1D, + OPCODE_COMPRESSED_TEX_IMAGE_2D, + OPCODE_COMPRESSED_TEX_IMAGE_3D, + OPCODE_COMPRESSED_TEX_SUB_IMAGE_1D, + OPCODE_COMPRESSED_TEX_SUB_IMAGE_2D, + OPCODE_COMPRESSED_TEX_SUB_IMAGE_3D, + /* GL_ARB_multisample */ + OPCODE_SAMPLE_COVERAGE, + /* The following three are meta instructions */ + OPCODE_ERROR, /* raise compiled-in error */ + OPCODE_CONTINUE, + OPCODE_END_OF_LIST, + OPCODE_DRV_0 +} OpCode; + + +/* + * Each instruction in the display list is stored as a sequence of + * contiguous nodes in memory. + * Each node is the union of a variety of datatypes. + */ +union node { + OpCode opcode; + GLboolean b; + GLbitfield bf; + GLubyte ub; + GLshort s; + GLushort us; + GLint i; + GLuint ui; + GLenum e; + GLfloat f; + GLvoid *data; + void *next; /* If prev node's opcode==OPCODE_CONTINUE */ +}; + + + +/* Number of nodes of storage needed for each instruction. Sizes for + * dynamically allocated opcodes are stored in the context struct. + */ +static GLuint InstSize[ OPCODE_END_OF_LIST+1 ]; + +void mesa_print_display_list( GLuint list ); + + +/**********************************************************************/ +/***** Private *****/ +/**********************************************************************/ + + + + + +/* + * Make an empty display list. This is used by glGenLists() to + * reserver display list IDs. + */ +static Node *make_empty_list( void ) +{ + Node *n = (Node *) MALLOC( sizeof(Node) ); + n[0].opcode = OPCODE_END_OF_LIST; + return n; +} + + + +/* + * Destroy all nodes in a display list. + * Input: list - display list number + */ +void _mesa_destroy_list( GLcontext *ctx, GLuint list ) +{ + Node *n, *block; + GLboolean done; + + if (list==0) + return; + + block = (Node *) _mesa_HashLookup(ctx->Shared->DisplayList, list); + n = block; + + done = block ? GL_FALSE : GL_TRUE; + while (!done) { + + /* check for extension opcodes first */ + + GLint i = (GLint) n[0].opcode - (GLint) OPCODE_DRV_0; + if (i >= 0 && i < (GLint) ctx->listext.nr_opcodes) { + ctx->listext.opcode[i].destroy(ctx, &n[1]); + n += ctx->listext.opcode[i].size; + } + else { + switch (n[0].opcode) { + case OPCODE_MAP1: + FREE(n[6].data); + n += InstSize[n[0].opcode]; + break; + case OPCODE_MAP2: + FREE(n[10].data); + n += InstSize[n[0].opcode]; + break; + case OPCODE_DRAW_PIXELS: + FREE( n[5].data ); + n += InstSize[n[0].opcode]; + break; + case OPCODE_BITMAP: + FREE( n[7].data ); + n += InstSize[n[0].opcode]; + break; + case OPCODE_COLOR_TABLE: + FREE( n[6].data ); + n += InstSize[n[0].opcode]; + break; + case OPCODE_COLOR_SUB_TABLE: + FREE( n[6].data ); + n += InstSize[n[0].opcode]; + break; + case OPCODE_CONVOLUTION_FILTER_1D: + FREE( n[6].data ); + n += InstSize[n[0].opcode]; + break; + case OPCODE_CONVOLUTION_FILTER_2D: + FREE( n[7].data ); + n += InstSize[n[0].opcode]; + break; + case OPCODE_POLYGON_STIPPLE: + FREE( n[1].data ); + n += InstSize[n[0].opcode]; + break; + case OPCODE_TEX_IMAGE1D: + FREE(n[8].data); + n += InstSize[n[0].opcode]; + break; + case OPCODE_TEX_IMAGE2D: + FREE( n[9]. data ); + n += InstSize[n[0].opcode]; + break; + case OPCODE_TEX_IMAGE3D: + FREE( n[10]. data ); + n += InstSize[n[0].opcode]; + break; + case OPCODE_TEX_SUB_IMAGE1D: + FREE(n[7].data); + n += InstSize[n[0].opcode]; + break; + case OPCODE_TEX_SUB_IMAGE2D: + FREE(n[9].data); + n += InstSize[n[0].opcode]; + break; + case OPCODE_TEX_SUB_IMAGE3D: + FREE(n[11].data); + n += InstSize[n[0].opcode]; + break; + case OPCODE_COMPRESSED_TEX_IMAGE_1D: + FREE(n[7].data); + n += InstSize[n[0].opcode]; + break; + case OPCODE_COMPRESSED_TEX_IMAGE_2D: + FREE(n[8].data); + n += InstSize[n[0].opcode]; + break; + case OPCODE_COMPRESSED_TEX_IMAGE_3D: + FREE(n[9].data); + n += InstSize[n[0].opcode]; + break; + case OPCODE_COMPRESSED_TEX_SUB_IMAGE_1D: + FREE(n[7].data); + n += InstSize[n[0].opcode]; + break; + case OPCODE_COMPRESSED_TEX_SUB_IMAGE_2D: + FREE(n[9].data); + n += InstSize[n[0].opcode]; + break; + case OPCODE_COMPRESSED_TEX_SUB_IMAGE_3D: + FREE(n[11].data); + n += InstSize[n[0].opcode]; + break; + case OPCODE_CONTINUE: + n = (Node *) n[1].next; + FREE( block ); + block = n; + break; + case OPCODE_END_OF_LIST: + FREE( block ); + done = GL_TRUE; + break; + default: + /* Most frequent case */ + n += InstSize[n[0].opcode]; + break; + } + } + } + + _mesa_HashRemove(ctx->Shared->DisplayList, list); +} + + + +/* + * Translate the nth element of list from type to GLuint. + */ +static GLuint translate_id( GLsizei n, GLenum type, const GLvoid *list ) +{ + GLbyte *bptr; + GLubyte *ubptr; + GLshort *sptr; + GLushort *usptr; + GLint *iptr; + GLuint *uiptr; + GLfloat *fptr; + + switch (type) { + case GL_BYTE: + bptr = (GLbyte *) list; + return (GLuint) *(bptr+n); + case GL_UNSIGNED_BYTE: + ubptr = (GLubyte *) list; + return (GLuint) *(ubptr+n); + case GL_SHORT: + sptr = (GLshort *) list; + return (GLuint) *(sptr+n); + case GL_UNSIGNED_SHORT: + usptr = (GLushort *) list; + return (GLuint) *(usptr+n); + case GL_INT: + iptr = (GLint *) list; + return (GLuint) *(iptr+n); + case GL_UNSIGNED_INT: + uiptr = (GLuint *) list; + return (GLuint) *(uiptr+n); + case GL_FLOAT: + fptr = (GLfloat *) list; + return (GLuint) *(fptr+n); + case GL_2_BYTES: + ubptr = ((GLubyte *) list) + 2*n; + return (GLuint) *ubptr * 256 + (GLuint) *(ubptr+1); + case GL_3_BYTES: + ubptr = ((GLubyte *) list) + 3*n; + return (GLuint) *ubptr * 65536 + + (GLuint) *(ubptr+1) * 256 + + (GLuint) *(ubptr+2); + case GL_4_BYTES: + ubptr = ((GLubyte *) list) + 4*n; + return (GLuint) *ubptr * 16777216 + + (GLuint) *(ubptr+1) * 65536 + + (GLuint) *(ubptr+2) * 256 + + (GLuint) *(ubptr+3); + default: + return 0; + } +} + + + + +/**********************************************************************/ +/***** Public *****/ +/**********************************************************************/ + +void _mesa_init_lists( void ) +{ + static int init_flag = 0; + + if (init_flag==0) { + InstSize[OPCODE_ACCUM] = 3; + InstSize[OPCODE_ALPHA_FUNC] = 3; + InstSize[OPCODE_BIND_TEXTURE] = 3; + InstSize[OPCODE_BITMAP] = 8; + InstSize[OPCODE_BLEND_COLOR] = 5; + InstSize[OPCODE_BLEND_EQUATION] = 2; + InstSize[OPCODE_BLEND_FUNC] = 3; + InstSize[OPCODE_BLEND_FUNC_SEPARATE] = 5; + InstSize[OPCODE_CALL_LIST] = 2; + InstSize[OPCODE_CALL_LIST_OFFSET] = 2; + InstSize[OPCODE_CLEAR] = 2; + InstSize[OPCODE_CLEAR_ACCUM] = 5; + InstSize[OPCODE_CLEAR_COLOR] = 5; + InstSize[OPCODE_CLEAR_DEPTH] = 2; + InstSize[OPCODE_CLEAR_INDEX] = 2; + InstSize[OPCODE_CLEAR_STENCIL] = 2; + InstSize[OPCODE_CLIP_PLANE] = 6; + InstSize[OPCODE_COLOR_MASK] = 5; + InstSize[OPCODE_COLOR_MATERIAL] = 3; + InstSize[OPCODE_COLOR_TABLE] = 7; + InstSize[OPCODE_COLOR_TABLE_PARAMETER_FV] = 7; + InstSize[OPCODE_COLOR_TABLE_PARAMETER_IV] = 7; + InstSize[OPCODE_COLOR_SUB_TABLE] = 7; + InstSize[OPCODE_CONVOLUTION_FILTER_1D] = 7; + InstSize[OPCODE_CONVOLUTION_FILTER_2D] = 8; + InstSize[OPCODE_CONVOLUTION_PARAMETER_I] = 4; + InstSize[OPCODE_CONVOLUTION_PARAMETER_IV] = 7; + InstSize[OPCODE_CONVOLUTION_PARAMETER_F] = 4; + InstSize[OPCODE_CONVOLUTION_PARAMETER_FV] = 7; + InstSize[OPCODE_COPY_PIXELS] = 6; + InstSize[OPCODE_COPY_COLOR_SUB_TABLE] = 6; + InstSize[OPCODE_COPY_COLOR_TABLE] = 6; + InstSize[OPCODE_COPY_TEX_IMAGE1D] = 8; + InstSize[OPCODE_COPY_TEX_IMAGE2D] = 9; + InstSize[OPCODE_COPY_TEX_SUB_IMAGE1D] = 7; + InstSize[OPCODE_COPY_TEX_SUB_IMAGE2D] = 9; + InstSize[OPCODE_COPY_TEX_SUB_IMAGE3D] = 10; + InstSize[OPCODE_CULL_FACE] = 2; + InstSize[OPCODE_DEPTH_FUNC] = 2; + InstSize[OPCODE_DEPTH_MASK] = 2; + InstSize[OPCODE_DEPTH_RANGE] = 3; + InstSize[OPCODE_DISABLE] = 2; + InstSize[OPCODE_DRAW_BUFFER] = 2; + InstSize[OPCODE_DRAW_PIXELS] = 6; + InstSize[OPCODE_ENABLE] = 2; + InstSize[OPCODE_EVALMESH1] = 4; + InstSize[OPCODE_EVALMESH2] = 6; + InstSize[OPCODE_FOG] = 6; + InstSize[OPCODE_FRONT_FACE] = 2; + InstSize[OPCODE_FRUSTUM] = 7; + InstSize[OPCODE_HINT] = 3; + InstSize[OPCODE_HISTOGRAM] = 5; + InstSize[OPCODE_INDEX_MASK] = 2; + InstSize[OPCODE_INIT_NAMES] = 1; + InstSize[OPCODE_LIGHT] = 7; + InstSize[OPCODE_LIGHT_MODEL] = 6; + InstSize[OPCODE_LINE_STIPPLE] = 3; + InstSize[OPCODE_LINE_WIDTH] = 2; + InstSize[OPCODE_LIST_BASE] = 2; + InstSize[OPCODE_LOAD_IDENTITY] = 1; + InstSize[OPCODE_LOAD_MATRIX] = 17; + InstSize[OPCODE_LOAD_NAME] = 2; + InstSize[OPCODE_LOGIC_OP] = 2; + InstSize[OPCODE_MAP1] = 7; + InstSize[OPCODE_MAP2] = 11; + InstSize[OPCODE_MAPGRID1] = 4; + InstSize[OPCODE_MAPGRID2] = 7; + InstSize[OPCODE_MATRIX_MODE] = 2; + InstSize[OPCODE_MIN_MAX] = 4; + InstSize[OPCODE_MULT_MATRIX] = 17; + InstSize[OPCODE_ORTHO] = 7; + InstSize[OPCODE_PASSTHROUGH] = 2; + InstSize[OPCODE_PIXEL_MAP] = 4; + InstSize[OPCODE_PIXEL_TRANSFER] = 3; + InstSize[OPCODE_PIXEL_ZOOM] = 3; + InstSize[OPCODE_POINT_SIZE] = 2; + InstSize[OPCODE_POINT_PARAMETERS] = 5; + InstSize[OPCODE_POLYGON_MODE] = 3; + InstSize[OPCODE_POLYGON_STIPPLE] = 2; + InstSize[OPCODE_POLYGON_OFFSET] = 3; + InstSize[OPCODE_POP_ATTRIB] = 1; + InstSize[OPCODE_POP_MATRIX] = 1; + InstSize[OPCODE_POP_NAME] = 1; + InstSize[OPCODE_PRIORITIZE_TEXTURE] = 3; + InstSize[OPCODE_PUSH_ATTRIB] = 2; + InstSize[OPCODE_PUSH_MATRIX] = 1; + InstSize[OPCODE_PUSH_NAME] = 2; + InstSize[OPCODE_RASTER_POS] = 5; + InstSize[OPCODE_READ_BUFFER] = 2; + InstSize[OPCODE_RESET_HISTOGRAM] = 2; + InstSize[OPCODE_RESET_MIN_MAX] = 2; + InstSize[OPCODE_ROTATE] = 5; + InstSize[OPCODE_SCALE] = 4; + InstSize[OPCODE_SCISSOR] = 5; + InstSize[OPCODE_STENCIL_FUNC] = 4; + InstSize[OPCODE_STENCIL_MASK] = 2; + InstSize[OPCODE_STENCIL_OP] = 4; + InstSize[OPCODE_SHADE_MODEL] = 2; + InstSize[OPCODE_TEXENV] = 7; + InstSize[OPCODE_TEXGEN] = 7; + InstSize[OPCODE_TEXPARAMETER] = 7; + InstSize[OPCODE_TEX_IMAGE1D] = 9; + InstSize[OPCODE_TEX_IMAGE2D] = 10; + InstSize[OPCODE_TEX_IMAGE3D] = 11; + InstSize[OPCODE_TEX_SUB_IMAGE1D] = 8; + InstSize[OPCODE_TEX_SUB_IMAGE2D] = 10; + InstSize[OPCODE_TEX_SUB_IMAGE3D] = 12; + InstSize[OPCODE_TRANSLATE] = 4; + InstSize[OPCODE_VIEWPORT] = 5; + InstSize[OPCODE_WINDOW_POS] = 5; + InstSize[OPCODE_CONTINUE] = 2; + InstSize[OPCODE_ERROR] = 3; + InstSize[OPCODE_END_OF_LIST] = 1; + /* GL_SGIX/SGIS_pixel_texture */ + InstSize[OPCODE_PIXEL_TEXGEN_SGIX] = 2; + InstSize[OPCODE_PIXEL_TEXGEN_PARAMETER_SGIS] = 3; + /* GL_ARB_texture_compression */ + InstSize[OPCODE_COMPRESSED_TEX_IMAGE_1D] = 8; + InstSize[OPCODE_COMPRESSED_TEX_IMAGE_2D] = 9; + InstSize[OPCODE_COMPRESSED_TEX_IMAGE_3D] = 10; + InstSize[OPCODE_COMPRESSED_TEX_SUB_IMAGE_1D] = 8; + InstSize[OPCODE_COMPRESSED_TEX_SUB_IMAGE_2D] = 10; + InstSize[OPCODE_COMPRESSED_TEX_SUB_IMAGE_3D] = 12; + /* GL_ARB_multisample */ + InstSize[OPCODE_SAMPLE_COVERAGE] = 3; + /* GL_ARB_multitexture */ + InstSize[OPCODE_ACTIVE_TEXTURE] = 2; + } + init_flag = 1; +} + + +/* + * Allocate space for a display list instruction. + * Input: opcode - type of instruction + * argcount - size in bytes of data required. + * Return: pointer to the usable data area (not including the internal + * opcode). + */ +void * +_mesa_alloc_instruction( GLcontext *ctx, int opcode, GLint sz ) +{ + Node *n, *newblock; + GLuint count = 1 + (sz + sizeof(Node) - 1) / sizeof(Node); + +#ifdef DEBUG + if (opcode < (int) OPCODE_DRV_0) { + assert( count == InstSize[opcode] ); + } +#endif + + if (ctx->CurrentPos + count + 2 > BLOCK_SIZE) { + /* This block is full. Allocate a new block and chain to it */ + n = ctx->CurrentBlock + ctx->CurrentPos; + n[0].opcode = OPCODE_CONTINUE; + newblock = (Node *) MALLOC( sizeof(Node) * BLOCK_SIZE ); + if (!newblock) { + _mesa_error( ctx, GL_OUT_OF_MEMORY, "Building display list" ); + return NULL; + } + n[1].next = (Node *) newblock; + ctx->CurrentBlock = newblock; + ctx->CurrentPos = 0; + } + + n = ctx->CurrentBlock + ctx->CurrentPos; + ctx->CurrentPos += count; + + n[0].opcode = (OpCode) opcode; + + return (void *)&n[1]; +} + + +/* Allow modules and drivers to get their own opcodes. + */ +int +_mesa_alloc_opcode( GLcontext *ctx, + GLuint sz, + void (*execute)( GLcontext *, void * ), + void (*destroy)( GLcontext *, void * ), + void (*print)( GLcontext *, void * ) ) +{ + if (ctx->listext.nr_opcodes < GL_MAX_EXT_OPCODES) { + GLuint i = ctx->listext.nr_opcodes++; + ctx->listext.opcode[i].size = 1 + (sz + sizeof(Node) - 1)/sizeof(Node); + ctx->listext.opcode[i].execute = execute; + ctx->listext.opcode[i].destroy = destroy; + ctx->listext.opcode[i].print = print; + return i + OPCODE_DRV_0; + } + return -1; +} + + + +/* Mimic the old behaviour of alloc_instruction: + * - sz is in units of sizeof(Node) + * - return value a pointer to sizeof(Node) before the actual + * usable data area. + */ +#define ALLOC_INSTRUCTION(ctx, opcode, sz) \ + ((Node *)_mesa_alloc_instruction(ctx, opcode, sz*sizeof(Node)) - 1) + + + +/* + * Display List compilation functions + */ +static void save_Accum( GLenum op, GLfloat value ) +{ + GET_CURRENT_CONTEXT(ctx); + Node *n; + ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx); + n = ALLOC_INSTRUCTION( ctx, OPCODE_ACCUM, 2 ); + if (n) { + n[1].e = op; + n[2].f = value; + } + if (ctx->ExecuteFlag) { + (*ctx->Exec->Accum)( op, value ); + } +} + + +static void save_AlphaFunc( GLenum func, GLclampf ref ) +{ + GET_CURRENT_CONTEXT(ctx); + Node *n; + ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx); + n = ALLOC_INSTRUCTION( ctx, OPCODE_ALPHA_FUNC, 2 ); + if (n) { + n[1].e = func; + n[2].f = (GLfloat) ref; + } + if (ctx->ExecuteFlag) { + (*ctx->Exec->AlphaFunc)( func, ref ); + } +} + + +static void save_BindTexture( GLenum target, GLuint texture ) +{ + GET_CURRENT_CONTEXT(ctx); + Node *n; + ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx); + n = ALLOC_INSTRUCTION( ctx, OPCODE_BIND_TEXTURE, 2 ); + if (n) { + n[1].e = target; + n[2].ui = texture; + } + if (ctx->ExecuteFlag) { + (*ctx->Exec->BindTexture)( target, texture ); + } +} + + +static void save_Bitmap( GLsizei width, GLsizei height, + GLfloat xorig, GLfloat yorig, + GLfloat xmove, GLfloat ymove, + const GLubyte *pixels ) +{ + GET_CURRENT_CONTEXT(ctx); + GLvoid *image = _mesa_unpack_bitmap( width, height, pixels, &ctx->Unpack ); + Node *n; + ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx); + n = ALLOC_INSTRUCTION( ctx, OPCODE_BITMAP, 7 ); + if (n) { + n[1].i = (GLint) width; + n[2].i = (GLint) height; + n[3].f = xorig; + n[4].f = yorig; + n[5].f = xmove; + n[6].f = ymove; + n[7].data = image; + } + else if (image) { + FREE(image); + } + if (ctx->ExecuteFlag) { + (*ctx->Exec->Bitmap)( width, height, + xorig, yorig, xmove, ymove, pixels ); + } +} + + +static void save_BlendEquation( GLenum mode ) +{ + GET_CURRENT_CONTEXT(ctx); + Node *n; + ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx); + n = ALLOC_INSTRUCTION( ctx, OPCODE_BLEND_EQUATION, 1 ); + if (n) { + n[1].e = mode; + } + if (ctx->ExecuteFlag) { + (*ctx->Exec->BlendEquation)( mode ); + } +} + + +static void save_BlendFunc( GLenum sfactor, GLenum dfactor ) +{ + GET_CURRENT_CONTEXT(ctx); + Node *n; + ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx); + n = ALLOC_INSTRUCTION( ctx, OPCODE_BLEND_FUNC, 2 ); + if (n) { + n[1].e = sfactor; + n[2].e = dfactor; + } + if (ctx->ExecuteFlag) { + (*ctx->Exec->BlendFunc)( sfactor, dfactor ); + } +} + + +static void save_BlendFuncSeparateEXT(GLenum sfactorRGB, GLenum dfactorRGB, + GLenum sfactorA, GLenum dfactorA) +{ + GET_CURRENT_CONTEXT(ctx); + Node *n; + ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx); + n = ALLOC_INSTRUCTION( ctx, OPCODE_BLEND_FUNC_SEPARATE, 4 ); + if (n) { + n[1].e = sfactorRGB; + n[2].e = dfactorRGB; + n[3].e = sfactorA; + n[4].e = dfactorA; + } + if (ctx->ExecuteFlag) { + (*ctx->Exec->BlendFuncSeparateEXT)( sfactorRGB, dfactorRGB, + sfactorA, dfactorA); + } +} + + +static void save_BlendColor( GLfloat red, GLfloat green, + GLfloat blue, GLfloat alpha ) +{ + GET_CURRENT_CONTEXT(ctx); + Node *n; + ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx); + n = ALLOC_INSTRUCTION( ctx, OPCODE_BLEND_COLOR, 4 ); + if (n) { + n[1].f = red; + n[2].f = green; + n[3].f = blue; + n[4].f = alpha; + } + if (ctx->ExecuteFlag) { + (*ctx->Exec->BlendColor)( red, green, blue, alpha ); + } +} + + +void _mesa_save_CallList( GLuint list ) +{ + GET_CURRENT_CONTEXT(ctx); + Node *n; + ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx); + FLUSH_CURRENT(ctx, 0); + + n = ALLOC_INSTRUCTION( ctx, OPCODE_CALL_LIST, 1 ); + if (n) { + n[1].ui = list; + } + if (ctx->ExecuteFlag) { + (*ctx->Exec->CallList)( list ); + } +} + + +void _mesa_save_CallLists( GLsizei n, GLenum type, const GLvoid *lists ) +{ + GET_CURRENT_CONTEXT(ctx); + GLint i; + ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx); + FLUSH_CURRENT(ctx, 0); + + for (i=0;iExecuteFlag) { + (*ctx->Exec->CallLists)( n, type, lists ); + } +} + + +static void save_Clear( GLbitfield mask ) +{ + GET_CURRENT_CONTEXT(ctx); + Node *n; + ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx); + n = ALLOC_INSTRUCTION( ctx, OPCODE_CLEAR, 1 ); + if (n) { + n[1].bf = mask; + } + if (ctx->ExecuteFlag) { + (*ctx->Exec->Clear)( mask ); + } +} + + +static void save_ClearAccum( GLfloat red, GLfloat green, + GLfloat blue, GLfloat alpha ) +{ + GET_CURRENT_CONTEXT(ctx); + Node *n; + ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx); + n = ALLOC_INSTRUCTION( ctx, OPCODE_CLEAR_ACCUM, 4 ); + if (n) { + n[1].f = red; + n[2].f = green; + n[3].f = blue; + n[4].f = alpha; + } + if (ctx->ExecuteFlag) { + (*ctx->Exec->ClearAccum)( red, green, blue, alpha ); + } +} + + +static void save_ClearColor( GLclampf red, GLclampf green, + GLclampf blue, GLclampf alpha ) +{ + GET_CURRENT_CONTEXT(ctx); + Node *n; + ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx); + n = ALLOC_INSTRUCTION( ctx, OPCODE_CLEAR_COLOR, 4 ); + if (n) { + n[1].f = red; + n[2].f = green; + n[3].f = blue; + n[4].f = alpha; + } + if (ctx->ExecuteFlag) { + (*ctx->Exec->ClearColor)( red, green, blue, alpha ); + } +} + + +static void save_ClearDepth( GLclampd depth ) +{ + GET_CURRENT_CONTEXT(ctx); + Node *n; + ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx); + n = ALLOC_INSTRUCTION( ctx, OPCODE_CLEAR_DEPTH, 1 ); + if (n) { + n[1].f = (GLfloat) depth; + } + if (ctx->ExecuteFlag) { + (*ctx->Exec->ClearDepth)( depth ); + } +} + + +static void save_ClearIndex( GLfloat c ) +{ + GET_CURRENT_CONTEXT(ctx); + Node *n; + ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx); + n = ALLOC_INSTRUCTION( ctx, OPCODE_CLEAR_INDEX, 1 ); + if (n) { + n[1].f = c; + } + if (ctx->ExecuteFlag) { + (*ctx->Exec->ClearIndex)( c ); + } +} + + +static void save_ClearStencil( GLint s ) +{ + GET_CURRENT_CONTEXT(ctx); + Node *n; + ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx); + n = ALLOC_INSTRUCTION( ctx, OPCODE_CLEAR_STENCIL, 1 ); + if (n) { + n[1].i = s; + } + if (ctx->ExecuteFlag) { + (*ctx->Exec->ClearStencil)( s ); + } +} + + +static void save_ClipPlane( GLenum plane, const GLdouble *equ ) +{ + GET_CURRENT_CONTEXT(ctx); + Node *n; + ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx); + n = ALLOC_INSTRUCTION( ctx, OPCODE_CLIP_PLANE, 5 ); + if (n) { + n[1].e = plane; + n[2].f = equ[0]; + n[3].f = equ[1]; + n[4].f = equ[2]; + n[5].f = equ[3]; + } + if (ctx->ExecuteFlag) { + (*ctx->Exec->ClipPlane)( plane, equ ); + } +} + + + +static void save_ColorMask( GLboolean red, GLboolean green, + GLboolean blue, GLboolean alpha ) +{ + GET_CURRENT_CONTEXT(ctx); + Node *n; + ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx); + n = ALLOC_INSTRUCTION( ctx, OPCODE_COLOR_MASK, 4 ); + if (n) { + n[1].b = red; + n[2].b = green; + n[3].b = blue; + n[4].b = alpha; + } + if (ctx->ExecuteFlag) { + (*ctx->Exec->ColorMask)( red, green, blue, alpha ); + } +} + + +static void save_ColorMaterial( GLenum face, GLenum mode ) +{ + GET_CURRENT_CONTEXT(ctx); + Node *n; + ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx); + FLUSH_CURRENT(ctx, 0); + + n = ALLOC_INSTRUCTION( ctx, OPCODE_COLOR_MATERIAL, 2 ); + if (n) { + n[1].e = face; + n[2].e = mode; + } + if (ctx->ExecuteFlag) { + (*ctx->Exec->ColorMaterial)( face, mode ); + } +} + + +static void save_ColorTable( GLenum target, GLenum internalFormat, + GLsizei width, GLenum format, GLenum type, + const GLvoid *table ) +{ + GET_CURRENT_CONTEXT(ctx); + if (target == GL_PROXY_TEXTURE_1D || + target == GL_PROXY_TEXTURE_2D || + target == GL_PROXY_TEXTURE_3D || + target == GL_PROXY_TEXTURE_CUBE_MAP_ARB) { + /* execute immediately */ + (*ctx->Exec->ColorTable)( target, internalFormat, width, + format, type, table ); + } + else { + GLvoid *image = _mesa_unpack_image(width, 1, 1, format, type, table, + &ctx->Unpack); + Node *n; + ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx); + n = ALLOC_INSTRUCTION( ctx, OPCODE_COLOR_TABLE, 6 ); + if (n) { + n[1].e = target; + n[2].e = internalFormat; + n[3].i = width; + n[4].e = format; + n[5].e = type; + n[6].data = image; + } + else if (image) { + FREE(image); + } + if (ctx->ExecuteFlag) { + (*ctx->Exec->ColorTable)( target, internalFormat, width, + format, type, table ); + } + } +} + + + +static void +save_ColorTableParameterfv(GLenum target, GLenum pname, const GLfloat *params) +{ + GET_CURRENT_CONTEXT(ctx); + Node *n; + + ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx); + + n = ALLOC_INSTRUCTION( ctx, OPCODE_COLOR_TABLE_PARAMETER_FV, 6 ); + if (n) { + n[1].e = target; + n[2].e = pname; + n[3].f = params[0]; + if (pname == GL_COLOR_TABLE_SGI || + pname == GL_POST_CONVOLUTION_COLOR_TABLE_SGI || + pname == GL_POST_COLOR_MATRIX_COLOR_TABLE_SGI) { + n[4].f = params[1]; + n[5].f = params[2]; + n[6].f = params[3]; + } + } + + if (ctx->ExecuteFlag) { + (*ctx->Exec->ColorTableParameterfv)( target, pname, params ); + } +} + + +static void +save_ColorTableParameteriv(GLenum target, GLenum pname, const GLint *params) +{ + GET_CURRENT_CONTEXT(ctx); + Node *n; + + ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx); + + n = ALLOC_INSTRUCTION( ctx, OPCODE_COLOR_TABLE_PARAMETER_IV, 6 ); + if (n) { + n[1].e = target; + n[2].e = pname; + n[3].i = params[0]; + if (pname == GL_COLOR_TABLE_SGI || + pname == GL_POST_CONVOLUTION_COLOR_TABLE_SGI || + pname == GL_POST_COLOR_MATRIX_COLOR_TABLE_SGI) { + n[4].i = params[1]; + n[5].i = params[2]; + n[6].i = params[3]; + } + } + + if (ctx->ExecuteFlag) { + (*ctx->Exec->ColorTableParameteriv)( target, pname, params ); + } +} + + + +static void save_ColorSubTable( GLenum target, GLsizei start, GLsizei count, + GLenum format, GLenum type, + const GLvoid *table) +{ + GET_CURRENT_CONTEXT(ctx); + GLvoid *image = _mesa_unpack_image(count, 1, 1, format, type, table, + &ctx->Unpack); + Node *n; + ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx); + n = ALLOC_INSTRUCTION( ctx, OPCODE_COLOR_SUB_TABLE, 6 ); + if (n) { + n[1].e = target; + n[2].i = start; + n[3].i = count; + n[4].e = format; + n[5].e = type; + n[6].data = image; + } + else if (image) { + FREE(image); + } + if (ctx->ExecuteFlag) { + (*ctx->Exec->ColorSubTable)(target, start, count, format, type, table); + } +} + + +static void +save_CopyColorSubTable(GLenum target, GLsizei start, + GLint x, GLint y, GLsizei width) +{ + GET_CURRENT_CONTEXT(ctx); + Node *n; + + ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx); + n = ALLOC_INSTRUCTION( ctx, OPCODE_COPY_COLOR_SUB_TABLE, 5 ); + if (n) { + n[1].e = target; + n[2].i = start; + n[3].i = x; + n[4].i = y; + n[5].i = width; + } + if (ctx->ExecuteFlag) { + (*ctx->Exec->CopyColorSubTable)(target, start, x, y, width); + } +} + + +static void +save_CopyColorTable(GLenum target, GLenum internalformat, + GLint x, GLint y, GLsizei width) +{ + GET_CURRENT_CONTEXT(ctx); + Node *n; + + ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx); + n = ALLOC_INSTRUCTION( ctx, OPCODE_COPY_COLOR_TABLE, 5 ); + if (n) { + n[1].e = target; + n[2].e = internalformat; + n[3].i = x; + n[4].i = y; + n[5].i = width; + } + if (ctx->ExecuteFlag) { + (*ctx->Exec->CopyColorTable)(target, internalformat, x, y, width); + } +} + + +static void +save_ConvolutionFilter1D(GLenum target, GLenum internalFormat, GLsizei width, + GLenum format, GLenum type, const GLvoid *filter) +{ + GET_CURRENT_CONTEXT(ctx); + GLvoid *image = _mesa_unpack_image(width, 1, 1, format, type, filter, + &ctx->Unpack); + Node *n; + ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx); + n = ALLOC_INSTRUCTION( ctx, OPCODE_CONVOLUTION_FILTER_1D, 6 ); + if (n) { + n[1].e = target; + n[2].e = internalFormat; + n[3].i = width; + n[4].e = format; + n[5].e = type; + n[6].data = image; + } + else if (image) { + FREE(image); + } + if (ctx->ExecuteFlag) { + (*ctx->Exec->ConvolutionFilter1D)( target, internalFormat, width, + format, type, filter ); + } +} + + +static void +save_ConvolutionFilter2D(GLenum target, GLenum internalFormat, + GLsizei width, GLsizei height, GLenum format, + GLenum type, const GLvoid *filter) +{ + GET_CURRENT_CONTEXT(ctx); + GLvoid *image = _mesa_unpack_image(width, height, 1, format, type, filter, + &ctx->Unpack); + Node *n; + ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx); + n = ALLOC_INSTRUCTION( ctx, OPCODE_CONVOLUTION_FILTER_2D, 7 ); + if (n) { + n[1].e = target; + n[2].e = internalFormat; + n[3].i = width; + n[4].i = height; + n[5].e = format; + n[6].e = type; + n[7].data = image; + } + else if (image) { + FREE(image); + } + if (ctx->ExecuteFlag) { + (*ctx->Exec->ConvolutionFilter2D)( target, internalFormat, width, height, + format, type, filter ); + } +} + + +static void +save_ConvolutionParameteri(GLenum target, GLenum pname, GLint param) +{ + GET_CURRENT_CONTEXT(ctx); + Node *n; + ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx); + n = ALLOC_INSTRUCTION( ctx, OPCODE_CONVOLUTION_PARAMETER_I, 3 ); + if (n) { + n[1].e = target; + n[2].e = pname; + n[3].i = param; + } + if (ctx->ExecuteFlag) { + (*ctx->Exec->ConvolutionParameteri)( target, pname, param ); + } +} + + +static void +save_ConvolutionParameteriv(GLenum target, GLenum pname, const GLint *params) +{ + GET_CURRENT_CONTEXT(ctx); + Node *n; + ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx); + n = ALLOC_INSTRUCTION( ctx, OPCODE_CONVOLUTION_PARAMETER_IV, 6 ); + if (n) { + n[1].e = target; + n[2].e = pname; + n[3].i = params[0]; + if (pname == GL_CONVOLUTION_BORDER_COLOR || + pname == GL_CONVOLUTION_FILTER_SCALE || + pname == GL_CONVOLUTION_FILTER_BIAS) { + n[4].i = params[1]; + n[5].i = params[2]; + n[6].i = params[3]; + } + else { + n[4].i = n[5].i = n[6].i = 0; + } + } + if (ctx->ExecuteFlag) { + (*ctx->Exec->ConvolutionParameteriv)( target, pname, params ); + } +} + + +static void +save_ConvolutionParameterf(GLenum target, GLenum pname, GLfloat param) +{ + GET_CURRENT_CONTEXT(ctx); + Node *n; + ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx); + n = ALLOC_INSTRUCTION( ctx, OPCODE_CONVOLUTION_PARAMETER_F, 3 ); + if (n) { + n[1].e = target; + n[2].e = pname; + n[3].f = param; + } + if (ctx->ExecuteFlag) { + (*ctx->Exec->ConvolutionParameterf)( target, pname, param ); + } +} + + +static void +save_ConvolutionParameterfv(GLenum target, GLenum pname, const GLfloat *params) +{ + GET_CURRENT_CONTEXT(ctx); + Node *n; + ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx); + n = ALLOC_INSTRUCTION( ctx, OPCODE_CONVOLUTION_PARAMETER_FV, 6 ); + if (n) { + n[1].e = target; + n[2].e = pname; + n[3].f = params[0]; + if (pname == GL_CONVOLUTION_BORDER_COLOR || + pname == GL_CONVOLUTION_FILTER_SCALE || + pname == GL_CONVOLUTION_FILTER_BIAS) { + n[4].f = params[1]; + n[5].f = params[2]; + n[6].f = params[3]; + } + else { + n[4].f = n[5].f = n[6].f = 0.0F; + } + } + if (ctx->ExecuteFlag) { + (*ctx->Exec->ConvolutionParameterfv)( target, pname, params ); + } +} + + +static void +save_CopyPixels( GLint x, GLint y, + GLsizei width, GLsizei height, GLenum type ) +{ + GET_CURRENT_CONTEXT(ctx); + Node *n; + ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx); + n = ALLOC_INSTRUCTION( ctx, OPCODE_COPY_PIXELS, 5 ); + if (n) { + n[1].i = x; + n[2].i = y; + n[3].i = (GLint) width; + n[4].i = (GLint) height; + n[5].e = type; + } + if (ctx->ExecuteFlag) { + (*ctx->Exec->CopyPixels)( x, y, width, height, type ); + } +} + + + +static void +save_CopyTexImage1D( GLenum target, GLint level, GLenum internalformat, + GLint x, GLint y, GLsizei width, GLint border ) +{ + GET_CURRENT_CONTEXT(ctx); + Node *n; + ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx); + n = ALLOC_INSTRUCTION( ctx, OPCODE_COPY_TEX_IMAGE1D, 7 ); + if (n) { + n[1].e = target; + n[2].i = level; + n[3].e = internalformat; + n[4].i = x; + n[5].i = y; + n[6].i = width; + n[7].i = border; + } + if (ctx->ExecuteFlag) { + (*ctx->Exec->CopyTexImage1D)( target, level, internalformat, + x, y, width, border ); + } +} + + +static void +save_CopyTexImage2D( GLenum target, GLint level, + GLenum internalformat, + GLint x, GLint y, GLsizei width, + GLsizei height, GLint border ) +{ + GET_CURRENT_CONTEXT(ctx); + Node *n; + ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx); + n = ALLOC_INSTRUCTION( ctx, OPCODE_COPY_TEX_IMAGE2D, 8 ); + if (n) { + n[1].e = target; + n[2].i = level; + n[3].e = internalformat; + n[4].i = x; + n[5].i = y; + n[6].i = width; + n[7].i = height; + n[8].i = border; + } + if (ctx->ExecuteFlag) { + (*ctx->Exec->CopyTexImage2D)( target, level, internalformat, + x, y, width, height, border ); + } +} + + + +static void +save_CopyTexSubImage1D( GLenum target, GLint level, + GLint xoffset, GLint x, GLint y, + GLsizei width ) +{ + GET_CURRENT_CONTEXT(ctx); + Node *n; + ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx); + n = ALLOC_INSTRUCTION( ctx, OPCODE_COPY_TEX_SUB_IMAGE1D, 6 ); + if (n) { + n[1].e = target; + n[2].i = level; + n[3].i = xoffset; + n[4].i = x; + n[5].i = y; + n[6].i = width; + } + if (ctx->ExecuteFlag) { + (*ctx->Exec->CopyTexSubImage1D)( target, level, xoffset, x, y, width ); + } +} + + +static void +save_CopyTexSubImage2D( GLenum target, GLint level, + GLint xoffset, GLint yoffset, + GLint x, GLint y, + GLsizei width, GLint height ) +{ + GET_CURRENT_CONTEXT(ctx); + Node *n; + ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx); + n = ALLOC_INSTRUCTION( ctx, OPCODE_COPY_TEX_SUB_IMAGE2D, 8 ); + if (n) { + n[1].e = target; + n[2].i = level; + n[3].i = xoffset; + n[4].i = yoffset; + n[5].i = x; + n[6].i = y; + n[7].i = width; + n[8].i = height; + } + if (ctx->ExecuteFlag) { + (*ctx->Exec->CopyTexSubImage2D)( target, level, xoffset, yoffset, + x, y, width, height ); + } +} + + +static void +save_CopyTexSubImage3D( GLenum target, GLint level, + GLint xoffset, GLint yoffset, GLint zoffset, + GLint x, GLint y, + GLsizei width, GLint height ) +{ + GET_CURRENT_CONTEXT(ctx); + Node *n; + ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx); + n = ALLOC_INSTRUCTION( ctx, OPCODE_COPY_TEX_SUB_IMAGE3D, 9 ); + if (n) { + n[1].e = target; + n[2].i = level; + n[3].i = xoffset; + n[4].i = yoffset; + n[5].i = zoffset; + n[6].i = x; + n[7].i = y; + n[8].i = width; + n[9].i = height; + } + if (ctx->ExecuteFlag) { + (*ctx->Exec->CopyTexSubImage3D)( target, level, + xoffset, yoffset, zoffset, + x, y, width, height ); + } +} + + +static void save_CullFace( GLenum mode ) +{ + GET_CURRENT_CONTEXT(ctx); + Node *n; + ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx); + n = ALLOC_INSTRUCTION( ctx, OPCODE_CULL_FACE, 1 ); + if (n) { + n[1].e = mode; + } + if (ctx->ExecuteFlag) { + (*ctx->Exec->CullFace)( mode ); + } +} + + +static void save_DepthFunc( GLenum func ) +{ + GET_CURRENT_CONTEXT(ctx); + Node *n; + ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx); + n = ALLOC_INSTRUCTION( ctx, OPCODE_DEPTH_FUNC, 1 ); + if (n) { + n[1].e = func; + } + if (ctx->ExecuteFlag) { + (*ctx->Exec->DepthFunc)( func ); + } +} + + +static void save_DepthMask( GLboolean mask ) +{ + GET_CURRENT_CONTEXT(ctx); + Node *n; + ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx); + n = ALLOC_INSTRUCTION( ctx, OPCODE_DEPTH_MASK, 1 ); + if (n) { + n[1].b = mask; + } + if (ctx->ExecuteFlag) { + (*ctx->Exec->DepthMask)( mask ); + } +} + + +static void save_DepthRange( GLclampd nearval, GLclampd farval ) +{ + GET_CURRENT_CONTEXT(ctx); + Node *n; + ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx); + n = ALLOC_INSTRUCTION( ctx, OPCODE_DEPTH_RANGE, 2 ); + if (n) { + n[1].f = (GLfloat) nearval; + n[2].f = (GLfloat) farval; + } + if (ctx->ExecuteFlag) { + (*ctx->Exec->DepthRange)( nearval, farval ); + } +} + + +static void save_Disable( GLenum cap ) +{ + GET_CURRENT_CONTEXT(ctx); + Node *n; + ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx); + n = ALLOC_INSTRUCTION( ctx, OPCODE_DISABLE, 1 ); + if (n) { + n[1].e = cap; + } + if (ctx->ExecuteFlag) { + (*ctx->Exec->Disable)( cap ); + } +} + + +static void save_DrawBuffer( GLenum mode ) +{ + GET_CURRENT_CONTEXT(ctx); + Node *n; + ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx); + n = ALLOC_INSTRUCTION( ctx, OPCODE_DRAW_BUFFER, 1 ); + if (n) { + n[1].e = mode; + } + if (ctx->ExecuteFlag) { + (*ctx->Exec->DrawBuffer)( mode ); + } +} + + +static void save_DrawPixels( GLsizei width, GLsizei height, + GLenum format, GLenum type, + const GLvoid *pixels ) +{ + GET_CURRENT_CONTEXT(ctx); + GLvoid *image = _mesa_unpack_image(width, height, 1, format, type, + pixels, &ctx->Unpack); + Node *n; + ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx); + n = ALLOC_INSTRUCTION( ctx, OPCODE_DRAW_PIXELS, 5 ); + if (n) { + n[1].i = width; + n[2].i = height; + n[3].e = format; + n[4].e = type; + n[5].data = image; + } + else if (image) { + FREE(image); + } + if (ctx->ExecuteFlag) { + (*ctx->Exec->DrawPixels)( width, height, format, type, pixels ); + } +} + + + +static void save_Enable( GLenum cap ) +{ + GET_CURRENT_CONTEXT(ctx); + Node *n; + ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx); + n = ALLOC_INSTRUCTION( ctx, OPCODE_ENABLE, 1 ); + if (n) { + n[1].e = cap; + } + if (ctx->ExecuteFlag) { + (*ctx->Exec->Enable)( cap ); + } +} + + + +void _mesa_save_EvalMesh1( GLenum mode, GLint i1, GLint i2 ) +{ + GET_CURRENT_CONTEXT(ctx); + Node *n; + ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx); + n = ALLOC_INSTRUCTION( ctx, OPCODE_EVALMESH1, 3 ); + if (n) { + n[1].e = mode; + n[2].i = i1; + n[3].i = i2; + } + if (ctx->ExecuteFlag) { + (*ctx->Exec->EvalMesh1)( mode, i1, i2 ); + } +} + + +void _mesa_save_EvalMesh2(GLenum mode, GLint i1, GLint i2, GLint j1, GLint j2 ) +{ + GET_CURRENT_CONTEXT(ctx); + Node *n; + ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx); + n = ALLOC_INSTRUCTION( ctx, OPCODE_EVALMESH2, 5 ); + if (n) { + n[1].e = mode; + n[2].i = i1; + n[3].i = i2; + n[4].i = j1; + n[5].i = j2; + } + if (ctx->ExecuteFlag) { + (*ctx->Exec->EvalMesh2)( mode, i1, i2, j1, j2 ); + } +} + + + + +static void save_Fogfv( GLenum pname, const GLfloat *params ) +{ + GET_CURRENT_CONTEXT(ctx); + Node *n; + ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx); + n = ALLOC_INSTRUCTION( ctx, OPCODE_FOG, 5 ); + if (n) { + n[1].e = pname; + n[2].f = params[0]; + n[3].f = params[1]; + n[4].f = params[2]; + n[5].f = params[3]; + } + if (ctx->ExecuteFlag) { + (*ctx->Exec->Fogfv)( pname, params ); + } +} + + +static void save_Fogf( GLenum pname, GLfloat param ) +{ + save_Fogfv(pname, ¶m); +} + + +static void save_Fogiv(GLenum pname, const GLint *params ) +{ + GLfloat p[4]; + switch (pname) { + case GL_FOG_MODE: + case GL_FOG_DENSITY: + case GL_FOG_START: + case GL_FOG_END: + case GL_FOG_INDEX: + p[0] = (GLfloat) *params; + break; + case GL_FOG_COLOR: + p[0] = INT_TO_FLOAT( params[0] ); + p[1] = INT_TO_FLOAT( params[1] ); + p[2] = INT_TO_FLOAT( params[2] ); + p[3] = INT_TO_FLOAT( params[3] ); + break; + default: + /* Error will be caught later in gl_Fogfv */ + ; + } + save_Fogfv(pname, p); +} + + +static void save_Fogi(GLenum pname, GLint param ) +{ + save_Fogiv(pname, ¶m); +} + + +static void save_FrontFace( GLenum mode ) +{ + GET_CURRENT_CONTEXT(ctx); + Node *n; + ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx); + n = ALLOC_INSTRUCTION( ctx, OPCODE_FRONT_FACE, 1 ); + if (n) { + n[1].e = mode; + } + if (ctx->ExecuteFlag) { + (*ctx->Exec->FrontFace)( mode ); + } +} + + +static void save_Frustum( GLdouble left, GLdouble right, + GLdouble bottom, GLdouble top, + GLdouble nearval, GLdouble farval ) +{ + GET_CURRENT_CONTEXT(ctx); + Node *n; + ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx); + n = ALLOC_INSTRUCTION( ctx, OPCODE_FRUSTUM, 6 ); + if (n) { + n[1].f = left; + n[2].f = right; + n[3].f = bottom; + n[4].f = top; + n[5].f = nearval; + n[6].f = farval; + } + if (ctx->ExecuteFlag) { + (*ctx->Exec->Frustum)( left, right, bottom, top, nearval, farval ); + } +} + + +static void save_Hint( GLenum target, GLenum mode ) +{ + GET_CURRENT_CONTEXT(ctx); + Node *n; + ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx); + n = ALLOC_INSTRUCTION( ctx, OPCODE_HINT, 2 ); + if (n) { + n[1].e = target; + n[2].e = mode; + } + if (ctx->ExecuteFlag) { + (*ctx->Exec->Hint)( target, mode ); + } +} + + +static void +save_Histogram(GLenum target, GLsizei width, GLenum internalFormat, GLboolean sink) +{ + GET_CURRENT_CONTEXT(ctx); + Node *n; + + ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx); + n = ALLOC_INSTRUCTION( ctx, OPCODE_HISTOGRAM, 4 ); + if (n) { + n[1].e = target; + n[2].i = width; + n[3].e = internalFormat; + n[4].b = sink; + } + if (ctx->ExecuteFlag) { + (*ctx->Exec->Histogram)( target, width, internalFormat, sink ); + } +} + + +static void save_IndexMask( GLuint mask ) +{ + GET_CURRENT_CONTEXT(ctx); + Node *n; + ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx); + n = ALLOC_INSTRUCTION( ctx, OPCODE_INDEX_MASK, 1 ); + if (n) { + n[1].ui = mask; + } + if (ctx->ExecuteFlag) { + (*ctx->Exec->IndexMask)( mask ); + } +} + + +static void save_InitNames( void ) +{ + GET_CURRENT_CONTEXT(ctx); + ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx); + (void) ALLOC_INSTRUCTION( ctx, OPCODE_INIT_NAMES, 0 ); + if (ctx->ExecuteFlag) { + (*ctx->Exec->InitNames)(); + } +} + + +static void save_Lightfv( GLenum light, GLenum pname, const GLfloat *params ) +{ + GET_CURRENT_CONTEXT(ctx); + Node *n; + ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx); + n = ALLOC_INSTRUCTION( ctx, OPCODE_LIGHT, 6 ); + if (OPCODE_LIGHT) { + GLint i, nParams; + n[1].e = light; + n[2].e = pname; + switch (pname) { + case GL_AMBIENT: + nParams = 4; + break; + case GL_DIFFUSE: + nParams = 4; + break; + case GL_SPECULAR: + nParams = 4; + break; + case GL_POSITION: + nParams = 4; + break; + case GL_SPOT_DIRECTION: + nParams = 3; + break; + case GL_SPOT_EXPONENT: + nParams = 1; + break; + case GL_SPOT_CUTOFF: + nParams = 1; + break; + case GL_CONSTANT_ATTENUATION: + nParams = 1; + break; + case GL_LINEAR_ATTENUATION: + nParams = 1; + break; + case GL_QUADRATIC_ATTENUATION: + nParams = 1; + break; + default: + nParams = 0; + } + for (i = 0; i < nParams; i++) { + n[3+i].f = params[i]; + } + } + if (ctx->ExecuteFlag) { + (*ctx->Exec->Lightfv)( light, pname, params ); + } +} + + +static void save_Lightf( GLenum light, GLenum pname, GLfloat params ) +{ + save_Lightfv(light, pname, ¶ms); +} + + +static void save_Lightiv( GLenum light, GLenum pname, const GLint *params ) +{ + GLfloat fparam[4]; + switch (pname) { + case GL_AMBIENT: + case GL_DIFFUSE: + case GL_SPECULAR: + fparam[0] = INT_TO_FLOAT( params[0] ); + fparam[1] = INT_TO_FLOAT( params[1] ); + fparam[2] = INT_TO_FLOAT( params[2] ); + fparam[3] = INT_TO_FLOAT( params[3] ); + break; + case GL_POSITION: + fparam[0] = (GLfloat) params[0]; + fparam[1] = (GLfloat) params[1]; + fparam[2] = (GLfloat) params[2]; + fparam[3] = (GLfloat) params[3]; + break; + case GL_SPOT_DIRECTION: + fparam[0] = (GLfloat) params[0]; + fparam[1] = (GLfloat) params[1]; + fparam[2] = (GLfloat) params[2]; + break; + case GL_SPOT_EXPONENT: + case GL_SPOT_CUTOFF: + case GL_CONSTANT_ATTENUATION: + case GL_LINEAR_ATTENUATION: + case GL_QUADRATIC_ATTENUATION: + fparam[0] = (GLfloat) params[0]; + break; + default: + /* error will be caught later in gl_Lightfv */ + ; + } + save_Lightfv( light, pname, fparam ); +} + + +static void save_Lighti( GLenum light, GLenum pname, GLint param ) +{ + save_Lightiv( light, pname, ¶m ); +} + + +static void save_LightModelfv( GLenum pname, const GLfloat *params ) +{ + GET_CURRENT_CONTEXT(ctx); + Node *n; + ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx); + n = ALLOC_INSTRUCTION( ctx, OPCODE_LIGHT_MODEL, 5 ); + if (n) { + n[1].e = pname; + n[2].f = params[0]; + n[3].f = params[1]; + n[4].f = params[2]; + n[5].f = params[3]; + } + if (ctx->ExecuteFlag) { + (*ctx->Exec->LightModelfv)( pname, params ); + } +} + + +static void save_LightModelf( GLenum pname, GLfloat param ) +{ + save_LightModelfv(pname, ¶m); +} + + +static void save_LightModeliv( GLenum pname, const GLint *params ) +{ + GLfloat fparam[4]; + switch (pname) { + case GL_LIGHT_MODEL_AMBIENT: + fparam[0] = INT_TO_FLOAT( params[0] ); + fparam[1] = INT_TO_FLOAT( params[1] ); + fparam[2] = INT_TO_FLOAT( params[2] ); + fparam[3] = INT_TO_FLOAT( params[3] ); + break; + case GL_LIGHT_MODEL_LOCAL_VIEWER: + case GL_LIGHT_MODEL_TWO_SIDE: + case GL_LIGHT_MODEL_COLOR_CONTROL: + fparam[0] = (GLfloat) params[0]; + break; + default: + /* Error will be caught later in gl_LightModelfv */ + ; + } + save_LightModelfv(pname, fparam); +} + + +static void save_LightModeli( GLenum pname, GLint param ) +{ + save_LightModeliv(pname, ¶m); +} + + +static void save_LineStipple( GLint factor, GLushort pattern ) +{ + GET_CURRENT_CONTEXT(ctx); + Node *n; + ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx); + n = ALLOC_INSTRUCTION( ctx, OPCODE_LINE_STIPPLE, 2 ); + if (n) { + n[1].i = factor; + n[2].us = pattern; + } + if (ctx->ExecuteFlag) { + (*ctx->Exec->LineStipple)( factor, pattern ); + } +} + + +static void save_LineWidth( GLfloat width ) +{ + GET_CURRENT_CONTEXT(ctx); + Node *n; + ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx); + n = ALLOC_INSTRUCTION( ctx, OPCODE_LINE_WIDTH, 1 ); + if (n) { + n[1].f = width; + } + if (ctx->ExecuteFlag) { + (*ctx->Exec->LineWidth)( width ); + } +} + + +static void save_ListBase( GLuint base ) +{ + GET_CURRENT_CONTEXT(ctx); + Node *n; + ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx); + n = ALLOC_INSTRUCTION( ctx, OPCODE_LIST_BASE, 1 ); + if (n) { + n[1].ui = base; + } + if (ctx->ExecuteFlag) { + (*ctx->Exec->ListBase)( base ); + } +} + + +static void save_LoadIdentity( void ) +{ + GET_CURRENT_CONTEXT(ctx); + ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx); + (void) ALLOC_INSTRUCTION( ctx, OPCODE_LOAD_IDENTITY, 0 ); + if (ctx->ExecuteFlag) { + (*ctx->Exec->LoadIdentity)(); + } +} + + +static void save_LoadMatrixf( const GLfloat *m ) +{ + GET_CURRENT_CONTEXT(ctx); + Node *n; + ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx); + n = ALLOC_INSTRUCTION( ctx, OPCODE_LOAD_MATRIX, 16 ); + if (n) { + GLuint i; + for (i=0;i<16;i++) { + n[1+i].f = m[i]; + } + } + if (ctx->ExecuteFlag) { + (*ctx->Exec->LoadMatrixf)( m ); + } +} + + +static void save_LoadMatrixd( const GLdouble *m ) +{ + GLfloat f[16]; + GLint i; + for (i = 0; i < 16; i++) { + f[i] = m[i]; + } + save_LoadMatrixf(f); +} + + +static void save_LoadName( GLuint name ) +{ + GET_CURRENT_CONTEXT(ctx); + Node *n; + ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx); + n = ALLOC_INSTRUCTION( ctx, OPCODE_LOAD_NAME, 1 ); + if (n) { + n[1].ui = name; + } + if (ctx->ExecuteFlag) { + (*ctx->Exec->LoadName)( name ); + } +} + + +static void save_LogicOp( GLenum opcode ) +{ + GET_CURRENT_CONTEXT(ctx); + Node *n; + ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx); + n = ALLOC_INSTRUCTION( ctx, OPCODE_LOGIC_OP, 1 ); + if (n) { + n[1].e = opcode; + } + if (ctx->ExecuteFlag) { + (*ctx->Exec->LogicOp)( opcode ); + } +} + + +static void save_Map1d( GLenum target, GLdouble u1, GLdouble u2, GLint stride, + GLint order, const GLdouble *points) +{ + GET_CURRENT_CONTEXT(ctx); + Node *n; + ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx); + n = ALLOC_INSTRUCTION( ctx, OPCODE_MAP1, 6 ); + if (n) { + GLfloat *pnts = _mesa_copy_map_points1d( target, stride, order, points ); + n[1].e = target; + n[2].f = u1; + n[3].f = u2; + n[4].i = _mesa_evaluator_components(target); /* stride */ + n[5].i = order; + n[6].data = (void *) pnts; + } + if (ctx->ExecuteFlag) { + (*ctx->Exec->Map1d)( target, u1, u2, stride, order, points ); + } +} + +static void save_Map1f( GLenum target, GLfloat u1, GLfloat u2, GLint stride, + GLint order, const GLfloat *points) +{ + GET_CURRENT_CONTEXT(ctx); + Node *n; + ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx); + n = ALLOC_INSTRUCTION( ctx, OPCODE_MAP1, 6 ); + if (n) { + GLfloat *pnts = _mesa_copy_map_points1f( target, stride, order, points ); + n[1].e = target; + n[2].f = u1; + n[3].f = u2; + n[4].i = _mesa_evaluator_components(target); /* stride */ + n[5].i = order; + n[6].data = (void *) pnts; + } + if (ctx->ExecuteFlag) { + (*ctx->Exec->Map1f)( target, u1, u2, stride, order, points ); + } +} + + +static void save_Map2d( GLenum target, + GLdouble u1, GLdouble u2, GLint ustride, GLint uorder, + GLdouble v1, GLdouble v2, GLint vstride, GLint vorder, + const GLdouble *points ) +{ + GET_CURRENT_CONTEXT(ctx); + Node *n; + ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx); + n = ALLOC_INSTRUCTION( ctx, OPCODE_MAP2, 10 ); + if (n) { + GLfloat *pnts = _mesa_copy_map_points2d( target, ustride, uorder, + vstride, vorder, points ); + n[1].e = target; + n[2].f = u1; + n[3].f = u2; + n[4].f = v1; + n[5].f = v2; + /* XXX verify these strides are correct */ + n[6].i = _mesa_evaluator_components(target) * vorder; /*ustride*/ + n[7].i = _mesa_evaluator_components(target); /*vstride*/ + n[8].i = uorder; + n[9].i = vorder; + n[10].data = (void *) pnts; + } + if (ctx->ExecuteFlag) { + (*ctx->Exec->Map2d)( target, + u1, u2, ustride, uorder, + v1, v2, vstride, vorder, points ); + } +} + + +static void save_Map2f( GLenum target, + GLfloat u1, GLfloat u2, GLint ustride, GLint uorder, + GLfloat v1, GLfloat v2, GLint vstride, GLint vorder, + const GLfloat *points ) +{ + GET_CURRENT_CONTEXT(ctx); + Node *n; + ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx); + n = ALLOC_INSTRUCTION( ctx, OPCODE_MAP2, 10 ); + if (n) { + GLfloat *pnts = _mesa_copy_map_points2f( target, ustride, uorder, + vstride, vorder, points ); + n[1].e = target; + n[2].f = u1; + n[3].f = u2; + n[4].f = v1; + n[5].f = v2; + /* XXX verify these strides are correct */ + n[6].i = _mesa_evaluator_components(target) * vorder; /*ustride*/ + n[7].i = _mesa_evaluator_components(target); /*vstride*/ + n[8].i = uorder; + n[9].i = vorder; + n[10].data = (void *) pnts; + } + if (ctx->ExecuteFlag) { + (*ctx->Exec->Map2f)( target, u1, u2, ustride, uorder, + v1, v2, vstride, vorder, points ); + } +} + + +static void save_MapGrid1f( GLint un, GLfloat u1, GLfloat u2 ) +{ + GET_CURRENT_CONTEXT(ctx); + Node *n; + ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx); + n = ALLOC_INSTRUCTION( ctx, OPCODE_MAPGRID1, 3 ); + if (n) { + n[1].i = un; + n[2].f = u1; + n[3].f = u2; + } + if (ctx->ExecuteFlag) { + (*ctx->Exec->MapGrid1f)( un, u1, u2 ); + } +} + + +static void save_MapGrid1d( GLint un, GLdouble u1, GLdouble u2 ) +{ + save_MapGrid1f(un, u1, u2); +} + + +static void save_MapGrid2f( GLint un, GLfloat u1, GLfloat u2, + GLint vn, GLfloat v1, GLfloat v2 ) +{ + GET_CURRENT_CONTEXT(ctx); + Node *n; + ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx); + n = ALLOC_INSTRUCTION( ctx, OPCODE_MAPGRID2, 6 ); + if (n) { + n[1].i = un; + n[2].f = u1; + n[3].f = u2; + n[4].i = vn; + n[5].f = v1; + n[6].f = v2; + } + if (ctx->ExecuteFlag) { + (*ctx->Exec->MapGrid2f)( un, u1, u2, vn, v1, v2 ); + } +} + + + +static void save_MapGrid2d( GLint un, GLdouble u1, GLdouble u2, + GLint vn, GLdouble v1, GLdouble v2 ) +{ + save_MapGrid2f(un, u1, u2, vn, v1, v2); +} + + +static void save_MatrixMode( GLenum mode ) +{ + GET_CURRENT_CONTEXT(ctx); + Node *n; + ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx); + n = ALLOC_INSTRUCTION( ctx, OPCODE_MATRIX_MODE, 1 ); + if (n) { + n[1].e = mode; + } + if (ctx->ExecuteFlag) { + (*ctx->Exec->MatrixMode)( mode ); + } +} + + +static void +save_Minmax(GLenum target, GLenum internalFormat, GLboolean sink) +{ + GET_CURRENT_CONTEXT(ctx); + Node *n; + + ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx); + n = ALLOC_INSTRUCTION( ctx, OPCODE_MIN_MAX, 3 ); + if (n) { + n[1].e = target; + n[2].e = internalFormat; + n[3].b = sink; + } + if (ctx->ExecuteFlag) { + (*ctx->Exec->Minmax)( target, internalFormat, sink ); + } +} + + +static void save_MultMatrixf( const GLfloat *m ) +{ + GET_CURRENT_CONTEXT(ctx); + Node *n; + ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx); + n = ALLOC_INSTRUCTION( ctx, OPCODE_MULT_MATRIX, 16 ); + if (n) { + GLuint i; + for (i=0;i<16;i++) { + n[1+i].f = m[i]; + } + } + if (ctx->ExecuteFlag) { + (*ctx->Exec->MultMatrixf)( m ); + } +} + + +static void save_MultMatrixd( const GLdouble *m ) +{ + GLfloat f[16]; + GLint i; + for (i = 0; i < 16; i++) { + f[i] = m[i]; + } + save_MultMatrixf(f); +} + + +static void save_NewList( GLuint list, GLenum mode ) +{ + GET_CURRENT_CONTEXT(ctx); + /* It's an error to call this function while building a display list */ + _mesa_error( ctx, GL_INVALID_OPERATION, "glNewList" ); + (void) list; + (void) mode; +} + + + +static void save_Ortho( GLdouble left, GLdouble right, + GLdouble bottom, GLdouble top, + GLdouble nearval, GLdouble farval ) +{ + GET_CURRENT_CONTEXT(ctx); + Node *n; + ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx); + n = ALLOC_INSTRUCTION( ctx, OPCODE_ORTHO, 6 ); + if (n) { + n[1].f = left; + n[2].f = right; + n[3].f = bottom; + n[4].f = top; + n[5].f = nearval; + n[6].f = farval; + } + if (ctx->ExecuteFlag) { + (*ctx->Exec->Ortho)( left, right, bottom, top, nearval, farval ); + } +} + + +static void +save_PixelMapfv( GLenum map, GLint mapsize, const GLfloat *values ) +{ + GET_CURRENT_CONTEXT(ctx); + Node *n; + ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx); + n = ALLOC_INSTRUCTION( ctx, OPCODE_PIXEL_MAP, 3 ); + if (n) { + n[1].e = map; + n[2].i = mapsize; + n[3].data = (void *) MALLOC( mapsize * sizeof(GLfloat) ); + MEMCPY( n[3].data, (void *) values, mapsize * sizeof(GLfloat) ); + } + if (ctx->ExecuteFlag) { + (*ctx->Exec->PixelMapfv)( map, mapsize, values ); + } +} + + +static void +save_PixelMapuiv(GLenum map, GLint mapsize, const GLuint *values ) +{ + GLfloat fvalues[MAX_PIXEL_MAP_TABLE]; + GLint i; + if (map==GL_PIXEL_MAP_I_TO_I || map==GL_PIXEL_MAP_S_TO_S) { + for (i=0;iExecuteFlag) { + (*ctx->Exec->PixelTransferf)( pname, param ); + } +} + + +static void +save_PixelTransferi( GLenum pname, GLint param ) +{ + save_PixelTransferf( pname, (GLfloat) param ); +} + + +static void +save_PixelZoom( GLfloat xfactor, GLfloat yfactor ) +{ + GET_CURRENT_CONTEXT(ctx); + Node *n; + ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx); + n = ALLOC_INSTRUCTION( ctx, OPCODE_PIXEL_ZOOM, 2 ); + if (n) { + n[1].f = xfactor; + n[2].f = yfactor; + } + if (ctx->ExecuteFlag) { + (*ctx->Exec->PixelZoom)( xfactor, yfactor ); + } +} + + +static void +save_PointParameterfvEXT( GLenum pname, const GLfloat *params ) +{ + GET_CURRENT_CONTEXT(ctx); + Node *n; + ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx); + n = ALLOC_INSTRUCTION( ctx, OPCODE_POINT_PARAMETERS, 4 ); + if (n) { + n[1].e = pname; + n[2].f = params[0]; + n[3].f = params[1]; + n[4].f = params[2]; + } + if (ctx->ExecuteFlag) { + (*ctx->Exec->PointParameterfvEXT)( pname, params ); + } +} + + +static void save_PointParameterfEXT( GLenum pname, GLfloat param ) +{ + save_PointParameterfvEXT(pname, ¶m); +} + + +static void save_PointSize( GLfloat size ) +{ + GET_CURRENT_CONTEXT(ctx); + Node *n; + ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx); + n = ALLOC_INSTRUCTION( ctx, OPCODE_POINT_SIZE, 1 ); + if (n) { + n[1].f = size; + } + if (ctx->ExecuteFlag) { + (*ctx->Exec->PointSize)( size ); + } +} + + +static void save_PolygonMode( GLenum face, GLenum mode ) +{ + GET_CURRENT_CONTEXT(ctx); + Node *n; + ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx); + n = ALLOC_INSTRUCTION( ctx, OPCODE_POLYGON_MODE, 2 ); + if (n) { + n[1].e = face; + n[2].e = mode; + } + if (ctx->ExecuteFlag) { + (*ctx->Exec->PolygonMode)( face, mode ); + } +} + + +/* + * Polygon stipple must have been upacked already! + */ +static void save_PolygonStipple( const GLubyte *pattern ) +{ + GET_CURRENT_CONTEXT(ctx); + Node *n; + ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx); + n = ALLOC_INSTRUCTION( ctx, OPCODE_POLYGON_STIPPLE, 1 ); + if (n) { + void *data; + n[1].data = MALLOC( 32 * 4 ); + data = n[1].data; /* This needed for Acorn compiler */ + MEMCPY( data, pattern, 32 * 4 ); + } + if (ctx->ExecuteFlag) { + (*ctx->Exec->PolygonStipple)( (GLubyte*) pattern ); + } +} + + +static void save_PolygonOffset( GLfloat factor, GLfloat units ) +{ + GET_CURRENT_CONTEXT(ctx); + Node *n; + ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx); + n = ALLOC_INSTRUCTION( ctx, OPCODE_POLYGON_OFFSET, 2 ); + if (n) { + n[1].f = factor; + n[2].f = units; + } + if (ctx->ExecuteFlag) { + (*ctx->Exec->PolygonOffset)( factor, units ); + } +} + + +static void save_PolygonOffsetEXT( GLfloat factor, GLfloat bias ) +{ + GET_CURRENT_CONTEXT(ctx); + save_PolygonOffset(factor, ctx->DepthMaxF * bias); +} + + +static void save_PopAttrib( void ) +{ + GET_CURRENT_CONTEXT(ctx); + ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx); + (void) ALLOC_INSTRUCTION( ctx, OPCODE_POP_ATTRIB, 0 ); + if (ctx->ExecuteFlag) { + (*ctx->Exec->PopAttrib)(); + } +} + + +static void save_PopMatrix( void ) +{ + GET_CURRENT_CONTEXT(ctx); + ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx); + FLUSH_CURRENT(ctx, 0); + (void) ALLOC_INSTRUCTION( ctx, OPCODE_POP_MATRIX, 0 ); + if (ctx->ExecuteFlag) { + (*ctx->Exec->PopMatrix)(); + } +} + + +static void save_PopName( void ) +{ + GET_CURRENT_CONTEXT(ctx); + ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx); + (void) ALLOC_INSTRUCTION( ctx, OPCODE_POP_NAME, 0 ); + if (ctx->ExecuteFlag) { + (*ctx->Exec->PopName)(); + } +} + + +static void save_PrioritizeTextures( GLsizei num, const GLuint *textures, + const GLclampf *priorities ) +{ + GET_CURRENT_CONTEXT(ctx); + GLint i; + ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx); + + for (i=0;iExecuteFlag) { + (*ctx->Exec->PrioritizeTextures)( num, textures, priorities ); + } +} + + +static void save_PushAttrib( GLbitfield mask ) +{ + GET_CURRENT_CONTEXT(ctx); + Node *n; + ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx); + FLUSH_CURRENT(ctx, 0); + n = ALLOC_INSTRUCTION( ctx, OPCODE_PUSH_ATTRIB, 1 ); + if (n) { + n[1].bf = mask; + } + if (ctx->ExecuteFlag) { + (*ctx->Exec->PushAttrib)( mask ); + } +} + + +static void save_PushMatrix( void ) +{ + GET_CURRENT_CONTEXT(ctx); + ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx); + (void) ALLOC_INSTRUCTION( ctx, OPCODE_PUSH_MATRIX, 0 ); + if (ctx->ExecuteFlag) { + (*ctx->Exec->PushMatrix)(); + } +} + + +static void save_PushName( GLuint name ) +{ + GET_CURRENT_CONTEXT(ctx); + Node *n; + ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx); + n = ALLOC_INSTRUCTION( ctx, OPCODE_PUSH_NAME, 1 ); + if (n) { + n[1].ui = name; + } + if (ctx->ExecuteFlag) { + (*ctx->Exec->PushName)( name ); + } +} + + +static void save_RasterPos4f( GLfloat x, GLfloat y, GLfloat z, GLfloat w ) +{ + GET_CURRENT_CONTEXT(ctx); + Node *n; + ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx); + FLUSH_CURRENT(ctx, 0); + n = ALLOC_INSTRUCTION( ctx, OPCODE_RASTER_POS, 4 ); + if (n) { + n[1].f = x; + n[2].f = y; + n[3].f = z; + n[4].f = w; + } + if (ctx->ExecuteFlag) { + (*ctx->Exec->RasterPos4f)( x, y, z, w ); + } +} + +static void save_RasterPos2d(GLdouble x, GLdouble y) +{ + save_RasterPos4f(x, y, 0.0F, 1.0F); +} + +static void save_RasterPos2f(GLfloat x, GLfloat y) +{ + save_RasterPos4f(x, y, 0.0F, 1.0F); +} + +static void save_RasterPos2i(GLint x, GLint y) +{ + save_RasterPos4f(x, y, 0.0F, 1.0F); +} + +static void save_RasterPos2s(GLshort x, GLshort y) +{ + save_RasterPos4f(x, y, 0.0F, 1.0F); +} + +static void save_RasterPos3d(GLdouble x, GLdouble y, GLdouble z) +{ + save_RasterPos4f(x, y, z, 1.0F); +} + +static void save_RasterPos3f(GLfloat x, GLfloat y, GLfloat z) +{ + save_RasterPos4f(x, y, z, 1.0F); +} + +static void save_RasterPos3i(GLint x, GLint y, GLint z) +{ + save_RasterPos4f(x, y, z, 1.0F); +} + +static void save_RasterPos3s(GLshort x, GLshort y, GLshort z) +{ + save_RasterPos4f(x, y, z, 1.0F); +} + +static void save_RasterPos4d(GLdouble x, GLdouble y, GLdouble z, GLdouble w) +{ + save_RasterPos4f(x, y, z, w); +} + +static void save_RasterPos4i(GLint x, GLint y, GLint z, GLint w) +{ + save_RasterPos4f(x, y, z, w); +} + +static void save_RasterPos4s(GLshort x, GLshort y, GLshort z, GLshort w) +{ + save_RasterPos4f(x, y, z, w); +} + +static void save_RasterPos2dv(const GLdouble *v) +{ + save_RasterPos4f(v[0], v[1], 0.0F, 1.0F); +} + +static void save_RasterPos2fv(const GLfloat *v) +{ + save_RasterPos4f(v[0], v[1], 0.0F, 1.0F); +} + +static void save_RasterPos2iv(const GLint *v) +{ + save_RasterPos4f(v[0], v[1], 0.0F, 1.0F); +} + +static void save_RasterPos2sv(const GLshort *v) +{ + save_RasterPos4f(v[0], v[1], 0.0F, 1.0F); +} + +static void save_RasterPos3dv(const GLdouble *v) +{ + save_RasterPos4f(v[0], v[1], v[2], 1.0F); +} + +static void save_RasterPos3fv(const GLfloat *v) +{ + save_RasterPos4f(v[0], v[1], v[2], 1.0F); +} + +static void save_RasterPos3iv(const GLint *v) +{ + save_RasterPos4f(v[0], v[1], v[2], 1.0F); +} + +static void save_RasterPos3sv(const GLshort *v) +{ + save_RasterPos4f(v[0], v[1], v[2], 1.0F); +} + +static void save_RasterPos4dv(const GLdouble *v) +{ + save_RasterPos4f(v[0], v[1], v[2], v[3]); +} + +static void save_RasterPos4fv(const GLfloat *v) +{ + save_RasterPos4f(v[0], v[1], v[2], v[3]); +} + +static void save_RasterPos4iv(const GLint *v) +{ + save_RasterPos4f(v[0], v[1], v[2], v[3]); +} + +static void save_RasterPos4sv(const GLshort *v) +{ + save_RasterPos4f(v[0], v[1], v[2], v[3]); +} + + +static void save_PassThrough( GLfloat token ) +{ + GET_CURRENT_CONTEXT(ctx); + Node *n; + ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx); + n = ALLOC_INSTRUCTION( ctx, OPCODE_PASSTHROUGH, 1 ); + if (n) { + n[1].f = token; + } + if (ctx->ExecuteFlag) { + (*ctx->Exec->PassThrough)( token ); + } +} + + +static void save_ReadBuffer( GLenum mode ) +{ + GET_CURRENT_CONTEXT(ctx); + Node *n; + ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx); + n = ALLOC_INSTRUCTION( ctx, OPCODE_READ_BUFFER, 1 ); + if (n) { + n[1].e = mode; + } + if (ctx->ExecuteFlag) { + (*ctx->Exec->ReadBuffer)( mode ); + } +} + + +static void +save_ResetHistogram(GLenum target) +{ + GET_CURRENT_CONTEXT(ctx); + Node *n; + ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx); + n = ALLOC_INSTRUCTION( ctx, OPCODE_RESET_HISTOGRAM, 1 ); + if (n) { + n[1].e = target; + } + if (ctx->ExecuteFlag) { + (*ctx->Exec->ResetHistogram)( target ); + } +} + + +static void +save_ResetMinmax(GLenum target) +{ + GET_CURRENT_CONTEXT(ctx); + Node *n; + ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx); + n = ALLOC_INSTRUCTION( ctx, OPCODE_RESET_MIN_MAX, 1 ); + if (n) { + n[1].e = target; + } + if (ctx->ExecuteFlag) { + (*ctx->Exec->ResetMinmax)( target ); + } +} + + +static void save_Rotatef( GLfloat angle, GLfloat x, GLfloat y, GLfloat z ) +{ + GET_CURRENT_CONTEXT(ctx); + Node *n; + ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx); + n = ALLOC_INSTRUCTION( ctx, OPCODE_ROTATE, 4 ); + if (n) { + n[1].f = angle; + n[2].f = x; + n[3].f = y; + n[4].f = z; + } + if (ctx->ExecuteFlag) { + (*ctx->Exec->Rotatef)( angle, x, y, z ); + } +} + + +static void save_Rotated( GLdouble angle, GLdouble x, GLdouble y, GLdouble z ) +{ + save_Rotatef(angle, x, y, z); +} + + +static void save_Scalef( GLfloat x, GLfloat y, GLfloat z ) +{ + GET_CURRENT_CONTEXT(ctx); + Node *n; + ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx); + n = ALLOC_INSTRUCTION( ctx, OPCODE_SCALE, 3 ); + if (n) { + n[1].f = x; + n[2].f = y; + n[3].f = z; + } + if (ctx->ExecuteFlag) { + (*ctx->Exec->Scalef)( x, y, z ); + } +} + + +static void save_Scaled( GLdouble x, GLdouble y, GLdouble z ) +{ + save_Scalef(x, y, z); +} + + +static void save_Scissor( GLint x, GLint y, GLsizei width, GLsizei height ) +{ + GET_CURRENT_CONTEXT(ctx); + Node *n; + ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx); + n = ALLOC_INSTRUCTION( ctx, OPCODE_SCISSOR, 4 ); + if (n) { + n[1].i = x; + n[2].i = y; + n[3].i = width; + n[4].i = height; + } + if (ctx->ExecuteFlag) { + (*ctx->Exec->Scissor)( x, y, width, height ); + } +} + + +static void save_ShadeModel( GLenum mode ) +{ + GET_CURRENT_CONTEXT(ctx); + Node *n; + ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx); + n = ALLOC_INSTRUCTION( ctx, OPCODE_SHADE_MODEL, 1 ); + if (n) { + n[1].e = mode; + } + if (ctx->ExecuteFlag) { + (*ctx->Exec->ShadeModel)( mode ); + } +} + + +static void save_StencilFunc( GLenum func, GLint ref, GLuint mask ) +{ + GET_CURRENT_CONTEXT(ctx); + Node *n; + ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx); + n = ALLOC_INSTRUCTION( ctx, OPCODE_STENCIL_FUNC, 3 ); + if (n) { + n[1].e = func; + n[2].i = ref; + n[3].ui = mask; + } + if (ctx->ExecuteFlag) { + (*ctx->Exec->StencilFunc)( func, ref, mask ); + } +} + + +static void save_StencilMask( GLuint mask ) +{ + GET_CURRENT_CONTEXT(ctx); + Node *n; + ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx); + n = ALLOC_INSTRUCTION( ctx, OPCODE_STENCIL_MASK, 1 ); + if (n) { + n[1].ui = mask; + } + if (ctx->ExecuteFlag) { + (*ctx->Exec->StencilMask)( mask ); + } +} + + +static void save_StencilOp( GLenum fail, GLenum zfail, GLenum zpass ) +{ + GET_CURRENT_CONTEXT(ctx); + Node *n; + ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx); + n = ALLOC_INSTRUCTION( ctx, OPCODE_STENCIL_OP, 3 ); + if (n) { + n[1].e = fail; + n[2].e = zfail; + n[3].e = zpass; + } + if (ctx->ExecuteFlag) { + (*ctx->Exec->StencilOp)( fail, zfail, zpass ); + } +} + + +static void save_TexEnvfv( GLenum target, GLenum pname, const GLfloat *params ) +{ + GET_CURRENT_CONTEXT(ctx); + Node *n; + ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx); + n = ALLOC_INSTRUCTION( ctx, OPCODE_TEXENV, 6 ); + if (n) { + n[1].e = target; + n[2].e = pname; + n[3].f = params[0]; + n[4].f = params[1]; + n[5].f = params[2]; + n[6].f = params[3]; + } + if (ctx->ExecuteFlag) { + (*ctx->Exec->TexEnvfv)( target, pname, params ); + } +} + + +static void save_TexEnvf( GLenum target, GLenum pname, GLfloat param ) +{ + save_TexEnvfv( target, pname, ¶m ); +} + + +static void save_TexEnvi( GLenum target, GLenum pname, GLint param ) +{ + GLfloat p[4]; + p[0] = (GLfloat) param; + p[1] = p[2] = p[3] = 0.0; + save_TexEnvfv( target, pname, p ); +} + + +static void save_TexEnviv( GLenum target, GLenum pname, const GLint *param ) +{ + GLfloat p[4]; + p[0] = INT_TO_FLOAT( param[0] ); + p[1] = INT_TO_FLOAT( param[1] ); + p[2] = INT_TO_FLOAT( param[2] ); + p[3] = INT_TO_FLOAT( param[3] ); + save_TexEnvfv( target, pname, p ); +} + + +static void save_TexGenfv( GLenum coord, GLenum pname, const GLfloat *params ) +{ + GET_CURRENT_CONTEXT(ctx); + Node *n; + ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx); + n = ALLOC_INSTRUCTION( ctx, OPCODE_TEXGEN, 6 ); + if (n) { + n[1].e = coord; + n[2].e = pname; + n[3].f = params[0]; + n[4].f = params[1]; + n[5].f = params[2]; + n[6].f = params[3]; + } + if (ctx->ExecuteFlag) { + (*ctx->Exec->TexGenfv)( coord, pname, params ); + } +} + + +static void save_TexGeniv(GLenum coord, GLenum pname, const GLint *params ) +{ + GLfloat p[4]; + p[0] = params[0]; + p[1] = params[1]; + p[2] = params[2]; + p[3] = params[3]; + save_TexGenfv(coord, pname, p); +} + + +static void save_TexGend(GLenum coord, GLenum pname, GLdouble param ) +{ + GLfloat p = (GLfloat) param; + save_TexGenfv( coord, pname, &p ); +} + + +static void save_TexGendv(GLenum coord, GLenum pname, const GLdouble *params ) +{ + GLfloat p[4]; + p[0] = params[0]; + p[1] = params[1]; + p[2] = params[2]; + p[3] = params[3]; + save_TexGenfv( coord, pname, p ); +} + + +static void save_TexGenf( GLenum coord, GLenum pname, GLfloat param ) +{ + save_TexGenfv(coord, pname, ¶m); +} + + +static void save_TexGeni( GLenum coord, GLenum pname, GLint param ) +{ + save_TexGeniv( coord, pname, ¶m ); +} + + +static void save_TexParameterfv( GLenum target, + GLenum pname, const GLfloat *params ) +{ + GET_CURRENT_CONTEXT(ctx); + Node *n; + ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx); + n = ALLOC_INSTRUCTION( ctx, OPCODE_TEXPARAMETER, 6 ); + if (n) { + n[1].e = target; + n[2].e = pname; + n[3].f = params[0]; + n[4].f = params[1]; + n[5].f = params[2]; + n[6].f = params[3]; + } + if (ctx->ExecuteFlag) { + (*ctx->Exec->TexParameterfv)( target, pname, params ); + } +} + + +static void save_TexParameterf( GLenum target, GLenum pname, GLfloat param ) +{ + save_TexParameterfv(target, pname, ¶m); +} + + +static void save_TexParameteri( GLenum target, GLenum pname, const GLint param ) +{ + GLfloat fparam[4]; + fparam[0] = (GLfloat) param; + fparam[1] = fparam[2] = fparam[3] = 0.0; + save_TexParameterfv(target, pname, fparam); +} + + +static void save_TexParameteriv( GLenum target, GLenum pname, const GLint *params ) +{ + GLfloat fparam[4]; + fparam[0] = (GLfloat) params[0]; + fparam[1] = fparam[2] = fparam[3] = 0.0; + save_TexParameterfv(target, pname, fparam); +} + + +static void save_TexImage1D( GLenum target, + GLint level, GLint components, + GLsizei width, GLint border, + GLenum format, GLenum type, + const GLvoid *pixels ) +{ + GET_CURRENT_CONTEXT(ctx); + if (target == GL_PROXY_TEXTURE_1D) { + /* don't compile, execute immediately */ + (*ctx->Exec->TexImage1D)( target, level, components, width, + border, format, type, pixels ); + } + else { + GLvoid *image = _mesa_unpack_image(width, 1, 1, format, type, + pixels, &ctx->Unpack); + Node *n; + ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx); + n = ALLOC_INSTRUCTION( ctx, OPCODE_TEX_IMAGE1D, 8 ); + if (n) { + n[1].e = target; + n[2].i = level; + n[3].i = components; + n[4].i = (GLint) width; + n[5].i = border; + n[6].e = format; + n[7].e = type; + n[8].data = image; + } + else if (image) { + FREE(image); + } + if (ctx->ExecuteFlag) { + (*ctx->Exec->TexImage1D)( target, level, components, width, + border, format, type, pixels ); + } + } +} + + +static void save_TexImage2D( GLenum target, + GLint level, GLint components, + GLsizei width, GLsizei height, GLint border, + GLenum format, GLenum type, + const GLvoid *pixels) +{ + GET_CURRENT_CONTEXT(ctx); + if (target == GL_PROXY_TEXTURE_2D) { + /* don't compile, execute immediately */ + (*ctx->Exec->TexImage2D)( target, level, components, width, + height, border, format, type, pixels ); + } + else { + GLvoid *image = _mesa_unpack_image(width, height, 1, format, type, + pixels, &ctx->Unpack); + Node *n; + ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx); + n = ALLOC_INSTRUCTION( ctx, OPCODE_TEX_IMAGE2D, 9 ); + if (n) { + n[1].e = target; + n[2].i = level; + n[3].i = components; + n[4].i = (GLint) width; + n[5].i = (GLint) height; + n[6].i = border; + n[7].e = format; + n[8].e = type; + n[9].data = image; + } + else if (image) { + FREE(image); + } + if (ctx->ExecuteFlag) { + (*ctx->Exec->TexImage2D)( target, level, components, width, + height, border, format, type, pixels ); + } + } +} + + +static void save_TexImage3D( GLenum target, + GLint level, GLenum internalFormat, + GLsizei width, GLsizei height, GLsizei depth, + GLint border, + GLenum format, GLenum type, + const GLvoid *pixels ) +{ + GET_CURRENT_CONTEXT(ctx); + if (target == GL_PROXY_TEXTURE_3D) { + /* don't compile, execute immediately */ + (*ctx->Exec->TexImage3D)( target, level, internalFormat, width, + height, depth, border, format, type, pixels ); + } + else { + Node *n; + GLvoid *image = _mesa_unpack_image(width, height, depth, format, type, + pixels, &ctx->Unpack); + ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx); + n = ALLOC_INSTRUCTION( ctx, OPCODE_TEX_IMAGE3D, 10 ); + if (n) { + n[1].e = target; + n[2].i = level; + n[3].i = (GLint) internalFormat; + n[4].i = (GLint) width; + n[5].i = (GLint) height; + n[6].i = (GLint) depth; + n[7].i = border; + n[8].e = format; + n[9].e = type; + n[10].data = image; + } + else if (image) { + FREE(image); + } + if (ctx->ExecuteFlag) { + (*ctx->Exec->TexImage3D)( target, level, internalFormat, width, + height, depth, border, format, type, pixels ); + } + } +} + + +static void save_TexSubImage1D( GLenum target, GLint level, GLint xoffset, + GLsizei width, GLenum format, GLenum type, + const GLvoid *pixels ) +{ + GET_CURRENT_CONTEXT(ctx); + Node *n; + GLvoid *image = _mesa_unpack_image(width, 1, 1, format, type, + pixels, &ctx->Unpack); + ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx); + n = ALLOC_INSTRUCTION( ctx, OPCODE_TEX_SUB_IMAGE1D, 7 ); + if (n) { + n[1].e = target; + n[2].i = level; + n[3].i = xoffset; + n[4].i = (GLint) width; + n[5].e = format; + n[6].e = type; + n[7].data = image; + } + else if (image) { + FREE(image); + } + if (ctx->ExecuteFlag) { + (*ctx->Exec->TexSubImage1D)( target, level, xoffset, width, + format, type, pixels ); + } +} + + +static void save_TexSubImage2D( GLenum target, GLint level, + GLint xoffset, GLint yoffset, + GLsizei width, GLsizei height, + GLenum format, GLenum type, + const GLvoid *pixels ) +{ + GET_CURRENT_CONTEXT(ctx); + Node *n; + GLvoid *image = _mesa_unpack_image(width, height, 1, format, type, + pixels, &ctx->Unpack); + ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx); + n = ALLOC_INSTRUCTION( ctx, OPCODE_TEX_SUB_IMAGE2D, 9 ); + if (n) { + n[1].e = target; + n[2].i = level; + n[3].i = xoffset; + n[4].i = yoffset; + n[5].i = (GLint) width; + n[6].i = (GLint) height; + n[7].e = format; + n[8].e = type; + n[9].data = image; + } + else if (image) { + FREE(image); + } + if (ctx->ExecuteFlag) { + (*ctx->Exec->TexSubImage2D)( target, level, xoffset, yoffset, + width, height, format, type, pixels ); + } +} + + +static void save_TexSubImage3D( GLenum target, GLint level, + GLint xoffset, GLint yoffset,GLint zoffset, + GLsizei width, GLsizei height, GLsizei depth, + GLenum format, GLenum type, + const GLvoid *pixels ) +{ + GET_CURRENT_CONTEXT(ctx); + Node *n; + GLvoid *image = _mesa_unpack_image(width, height, depth, format, type, + pixels, &ctx->Unpack); + ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx); + n = ALLOC_INSTRUCTION( ctx, OPCODE_TEX_SUB_IMAGE3D, 11 ); + if (n) { + n[1].e = target; + n[2].i = level; + n[3].i = xoffset; + n[4].i = yoffset; + n[5].i = zoffset; + n[6].i = (GLint) width; + n[7].i = (GLint) height; + n[8].i = (GLint) depth; + n[9].e = format; + n[10].e = type; + n[11].data = image; + } + else if (image) { + FREE(image); + } + if (ctx->ExecuteFlag) { + (*ctx->Exec->TexSubImage3D)( target, level, + xoffset, yoffset, zoffset, + width, height, depth, format, type, pixels ); + } +} + + +static void save_Translatef( GLfloat x, GLfloat y, GLfloat z ) +{ + GET_CURRENT_CONTEXT(ctx); + Node *n; + ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx); + n = ALLOC_INSTRUCTION( ctx, OPCODE_TRANSLATE, 3 ); + if (n) { + n[1].f = x; + n[2].f = y; + n[3].f = z; + } + if (ctx->ExecuteFlag) { + (*ctx->Exec->Translatef)( x, y, z ); + } +} + + +static void save_Translated( GLdouble x, GLdouble y, GLdouble z ) +{ + save_Translatef(x, y, z); +} + + + +static void save_Viewport( GLint x, GLint y, GLsizei width, GLsizei height ) +{ + GET_CURRENT_CONTEXT(ctx); + Node *n; + ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx); + n = ALLOC_INSTRUCTION( ctx, OPCODE_VIEWPORT, 4 ); + if (n) { + n[1].i = x; + n[2].i = y; + n[3].i = (GLint) width; + n[4].i = (GLint) height; + } + if (ctx->ExecuteFlag) { + (*ctx->Exec->Viewport)( x, y, width, height ); + } +} + + +static void save_WindowPos4fMESA( GLfloat x, GLfloat y, GLfloat z, GLfloat w ) +{ + GET_CURRENT_CONTEXT(ctx); + Node *n; + ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx); + FLUSH_CURRENT(ctx, 0); + n = ALLOC_INSTRUCTION( ctx, OPCODE_WINDOW_POS, 4 ); + if (n) { + n[1].f = x; + n[2].f = y; + n[3].f = z; + n[4].f = w; + } + if (ctx->ExecuteFlag) { + (*ctx->Exec->WindowPos4fMESA)( x, y, z, w ); + } +} + +static void save_WindowPos2dMESA(GLdouble x, GLdouble y) +{ + save_WindowPos4fMESA(x, y, 0.0F, 1.0F); +} + +static void save_WindowPos2fMESA(GLfloat x, GLfloat y) +{ + save_WindowPos4fMESA(x, y, 0.0F, 1.0F); +} + +static void save_WindowPos2iMESA(GLint x, GLint y) +{ + save_WindowPos4fMESA(x, y, 0.0F, 1.0F); +} + +static void save_WindowPos2sMESA(GLshort x, GLshort y) +{ + save_WindowPos4fMESA(x, y, 0.0F, 1.0F); +} + +static void save_WindowPos3dMESA(GLdouble x, GLdouble y, GLdouble z) +{ + save_WindowPos4fMESA(x, y, z, 1.0F); +} + +static void save_WindowPos3fMESA(GLfloat x, GLfloat y, GLfloat z) +{ + save_WindowPos4fMESA(x, y, z, 1.0F); +} + +static void save_WindowPos3iMESA(GLint x, GLint y, GLint z) +{ + save_WindowPos4fMESA(x, y, z, 1.0F); +} + +static void save_WindowPos3sMESA(GLshort x, GLshort y, GLshort z) +{ + save_WindowPos4fMESA(x, y, z, 1.0F); +} + +static void save_WindowPos4dMESA(GLdouble x, GLdouble y, GLdouble z, GLdouble w) +{ + save_WindowPos4fMESA(x, y, z, w); +} + +static void save_WindowPos4iMESA(GLint x, GLint y, GLint z, GLint w) +{ + save_WindowPos4fMESA(x, y, z, w); +} + +static void save_WindowPos4sMESA(GLshort x, GLshort y, GLshort z, GLshort w) +{ + save_WindowPos4fMESA(x, y, z, w); +} + +static void save_WindowPos2dvMESA(const GLdouble *v) +{ + save_WindowPos4fMESA(v[0], v[1], 0.0F, 1.0F); +} + +static void save_WindowPos2fvMESA(const GLfloat *v) +{ + save_WindowPos4fMESA(v[0], v[1], 0.0F, 1.0F); +} + +static void save_WindowPos2ivMESA(const GLint *v) +{ + save_WindowPos4fMESA(v[0], v[1], 0.0F, 1.0F); +} + +static void save_WindowPos2svMESA(const GLshort *v) +{ + save_WindowPos4fMESA(v[0], v[1], 0.0F, 1.0F); +} + +static void save_WindowPos3dvMESA(const GLdouble *v) +{ + save_WindowPos4fMESA(v[0], v[1], v[2], 1.0F); +} + +static void save_WindowPos3fvMESA(const GLfloat *v) +{ + save_WindowPos4fMESA(v[0], v[1], v[2], 1.0F); +} + +static void save_WindowPos3ivMESA(const GLint *v) +{ + save_WindowPos4fMESA(v[0], v[1], v[2], 1.0F); +} + +static void save_WindowPos3svMESA(const GLshort *v) +{ + save_WindowPos4fMESA(v[0], v[1], v[2], 1.0F); +} + +static void save_WindowPos4dvMESA(const GLdouble *v) +{ + save_WindowPos4fMESA(v[0], v[1], v[2], v[3]); +} + +static void save_WindowPos4fvMESA(const GLfloat *v) +{ + save_WindowPos4fMESA(v[0], v[1], v[2], v[3]); +} + +static void save_WindowPos4ivMESA(const GLint *v) +{ + save_WindowPos4fMESA(v[0], v[1], v[2], v[3]); +} + +static void save_WindowPos4svMESA(const GLshort *v) +{ + save_WindowPos4fMESA(v[0], v[1], v[2], v[3]); +} + + + +/* GL_ARB_multitexture */ +static void save_ActiveTextureARB( GLenum target ) +{ + GET_CURRENT_CONTEXT(ctx); + Node *n; + ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx); + n = ALLOC_INSTRUCTION( ctx, OPCODE_ACTIVE_TEXTURE, 1 ); + if (n) { + n[1].e = target; + } + if (ctx->ExecuteFlag) { + (*ctx->Exec->ActiveTextureARB)( target ); + } +} + + +/* GL_ARB_transpose_matrix */ + +static void save_LoadTransposeMatrixdARB( const GLdouble m[16] ) +{ + GLfloat tm[16]; + _math_transposefd(tm, m); + save_LoadMatrixf(tm); +} + + +static void save_LoadTransposeMatrixfARB( const GLfloat m[16] ) +{ + GLfloat tm[16]; + _math_transposef(tm, m); + save_LoadMatrixf(tm); +} + + +static void +save_MultTransposeMatrixdARB( const GLdouble m[16] ) +{ + GLfloat tm[16]; + _math_transposefd(tm, m); + save_MultMatrixf(tm); +} + + +static void +save_MultTransposeMatrixfARB( const GLfloat m[16] ) +{ + GLfloat tm[16]; + _math_transposef(tm, m); + save_MultMatrixf(tm); +} + + +static void +save_PixelTexGenSGIX(GLenum mode) +{ + GET_CURRENT_CONTEXT(ctx); + Node *n; + ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx); + n = ALLOC_INSTRUCTION( ctx, OPCODE_PIXEL_TEXGEN_SGIX, 1 ); + if (n) { + n[1].e = mode; + } + if (ctx->ExecuteFlag) { + (*ctx->Exec->PixelTexGenSGIX)( mode ); + } +} + + +/* GL_ARB_texture_compression */ +static void +save_CompressedTexImage1DARB(GLenum target, GLint level, + GLenum internalFormat, GLsizei width, + GLint border, GLsizei imageSize, + const GLvoid *data) +{ + GET_CURRENT_CONTEXT(ctx); + if (target == GL_PROXY_TEXTURE_1D) { + /* don't compile, execute immediately */ + (*ctx->Exec->CompressedTexImage1DARB)(target, level, internalFormat, + width, border, imageSize, data); + } + else { + Node *n; + GLvoid *image; + ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx); + /* make copy of image */ + image = MALLOC(imageSize); + if (!image) { + _mesa_error(ctx, GL_OUT_OF_MEMORY, "glCompressedTexImage1DARB"); + return; + } + MEMCPY(image, data, imageSize); + n = ALLOC_INSTRUCTION( ctx, OPCODE_COMPRESSED_TEX_IMAGE_1D, 7 ); + if (n) { + n[1].e = target; + n[2].i = level; + n[3].e = internalFormat; + n[4].i = (GLint) width; + n[5].i = border; + n[6].i = imageSize; + n[7].data = image; + } + else if (image) { + FREE(image); + } + if (ctx->ExecuteFlag) { + (*ctx->Exec->CompressedTexImage1DARB)(target, level, internalFormat, + width, border, imageSize, data); + } + } +} + + +static void +save_CompressedTexImage2DARB(GLenum target, GLint level, + GLenum internalFormat, GLsizei width, + GLsizei height, GLint border, GLsizei imageSize, + const GLvoid *data) +{ + GET_CURRENT_CONTEXT(ctx); + if (target == GL_PROXY_TEXTURE_2D) { + /* don't compile, execute immediately */ + (*ctx->Exec->CompressedTexImage2DARB)(target, level, internalFormat, + width, height, border, imageSize, data); + } + else { + Node *n; + GLvoid *image; + ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx); + /* make copy of image */ + image = MALLOC(imageSize); + if (!image) { + _mesa_error(ctx, GL_OUT_OF_MEMORY, "glCompressedTexImage2DARB"); + return; + } + MEMCPY(image, data, imageSize); + n = ALLOC_INSTRUCTION( ctx, OPCODE_COMPRESSED_TEX_IMAGE_2D, 8 ); + if (n) { + n[1].e = target; + n[2].i = level; + n[3].e = internalFormat; + n[4].i = (GLint) width; + n[5].i = (GLint) height; + n[6].i = border; + n[7].i = imageSize; + n[8].data = image; + } + else if (image) { + FREE(image); + } + if (ctx->ExecuteFlag) { + (*ctx->Exec->CompressedTexImage2DARB)(target, level, internalFormat, + width, height, border, imageSize, data); + } + } +} + + +static void +save_CompressedTexImage3DARB(GLenum target, GLint level, + GLenum internalFormat, GLsizei width, + GLsizei height, GLsizei depth, GLint border, + GLsizei imageSize, const GLvoid *data) +{ + GET_CURRENT_CONTEXT(ctx); + if (target == GL_PROXY_TEXTURE_3D) { + /* don't compile, execute immediately */ + (*ctx->Exec->CompressedTexImage3DARB)(target, level, internalFormat, + width, height, depth, border, imageSize, data); + } + else { + Node *n; + GLvoid *image; + ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx); + /* make copy of image */ + image = MALLOC(imageSize); + if (!image) { + _mesa_error(ctx, GL_OUT_OF_MEMORY, "glCompressedTexImage3DARB"); + return; + } + MEMCPY(image, data, imageSize); + n = ALLOC_INSTRUCTION( ctx, OPCODE_COMPRESSED_TEX_IMAGE_3D, 9 ); + if (n) { + n[1].e = target; + n[2].i = level; + n[3].e = internalFormat; + n[4].i = (GLint) width; + n[5].i = (GLint) height; + n[6].i = (GLint) depth; + n[7].i = border; + n[8].i = imageSize; + n[9].data = image; + } + else if (image) { + FREE(image); + } + if (ctx->ExecuteFlag) { + (*ctx->Exec->CompressedTexImage3DARB)(target, level, internalFormat, + width, height, depth, border, imageSize, data); + } + } +} + + +static void +save_CompressedTexSubImage1DARB(GLenum target, GLint level, GLint xoffset, + GLsizei width, GLenum format, + GLsizei imageSize, const GLvoid *data) +{ + Node *n; + GLvoid *image; + + GET_CURRENT_CONTEXT(ctx); + ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx); + + /* make copy of image */ + image = MALLOC(imageSize); + if (!image) { + _mesa_error(ctx, GL_OUT_OF_MEMORY, "glCompressedTexSubImage1DARB"); + return; + } + MEMCPY(image, data, imageSize); + n = ALLOC_INSTRUCTION( ctx, OPCODE_COMPRESSED_TEX_SUB_IMAGE_1D, 7 ); + if (n) { + n[1].e = target; + n[2].i = level; + n[3].i = xoffset; + n[4].i = (GLint) width; + n[5].e = format; + n[6].i = imageSize; + n[7].data = image; + } + else if (image) { + FREE(image); + } + if (ctx->ExecuteFlag) { + (*ctx->Exec->CompressedTexSubImage1DARB)(target, level, xoffset, + width, format, imageSize, data); + } +} + + +static void +save_CompressedTexSubImage2DARB(GLenum target, GLint level, GLint xoffset, + GLint yoffset, GLsizei width, GLsizei height, + GLenum format, GLsizei imageSize, + const GLvoid *data) +{ + Node *n; + GLvoid *image; + + GET_CURRENT_CONTEXT(ctx); + ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx); + + /* make copy of image */ + image = MALLOC(imageSize); + if (!image) { + _mesa_error(ctx, GL_OUT_OF_MEMORY, "glCompressedTexSubImage2DARB"); + return; + } + MEMCPY(image, data, imageSize); + n = ALLOC_INSTRUCTION( ctx, OPCODE_COMPRESSED_TEX_SUB_IMAGE_2D, 9 ); + if (n) { + n[1].e = target; + n[2].i = level; + n[3].i = xoffset; + n[4].i = yoffset; + n[5].i = (GLint) width; + n[6].i = (GLint) height; + n[7].e = format; + n[8].i = imageSize; + n[9].data = image; + } + else if (image) { + FREE(image); + } + if (ctx->ExecuteFlag) { + (*ctx->Exec->CompressedTexSubImage2DARB)(target, level, xoffset, yoffset, + width, height, format, imageSize, data); + } +} + + +static void +save_CompressedTexSubImage3DARB(GLenum target, GLint level, GLint xoffset, + GLint yoffset, GLint zoffset, GLsizei width, + GLsizei height, GLsizei depth, GLenum format, + GLsizei imageSize, const GLvoid *data) +{ + Node *n; + GLvoid *image; + + GET_CURRENT_CONTEXT(ctx); + ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx); + + /* make copy of image */ + image = MALLOC(imageSize); + if (!image) { + _mesa_error(ctx, GL_OUT_OF_MEMORY, "glCompressedTexSubImage3DARB"); + return; + } + MEMCPY(image, data, imageSize); + n = ALLOC_INSTRUCTION( ctx, OPCODE_COMPRESSED_TEX_SUB_IMAGE_3D, 11 ); + if (n) { + n[1].e = target; + n[2].i = level; + n[3].i = xoffset; + n[4].i = yoffset; + n[5].i = zoffset; + n[6].i = (GLint) width; + n[7].i = (GLint) height; + n[8].i = (GLint) depth; + n[9].e = format; + n[10].i = imageSize; + n[11].data = image; + } + else if (image) { + FREE(image); + } + if (ctx->ExecuteFlag) { + (*ctx->Exec->CompressedTexSubImage3DARB)(target, level, xoffset, yoffset, + zoffset, width, height, depth, format, imageSize, data); + } +} + + +/* GL_ARB_multisample */ +static void +save_SampleCoverageARB(GLclampf value, GLboolean invert) +{ + GET_CURRENT_CONTEXT(ctx); + Node *n; + ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx); + n = ALLOC_INSTRUCTION( ctx, OPCODE_SAMPLE_COVERAGE, 2 ); + if (n) { + n[1].f = value; + n[2].b = invert; + } + if (ctx->ExecuteFlag) { + (*ctx->Exec->SampleCoverageARB)( value, invert ); + } +} + + +/* GL_SGIS_pixel_texture */ + +static void +save_PixelTexGenParameteriSGIS(GLenum target, GLint value) +{ + GET_CURRENT_CONTEXT(ctx); + Node *n; + ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx); + n = ALLOC_INSTRUCTION( ctx, OPCODE_PIXEL_TEXGEN_PARAMETER_SGIS, 2 ); + if (n) { + n[1].e = target; + n[2].i = value; + } + if (ctx->ExecuteFlag) { + (*ctx->Exec->PixelTexGenParameteriSGIS)( target, value ); + } +} + + +static void +save_PixelTexGenParameterfSGIS(GLenum target, GLfloat value) +{ + save_PixelTexGenParameteriSGIS(target, (GLint) value); +} + + +static void +save_PixelTexGenParameterivSGIS(GLenum target, const GLint *value) +{ + save_PixelTexGenParameteriSGIS(target, *value); +} + + +static void +save_PixelTexGenParameterfvSGIS(GLenum target, const GLfloat *value) +{ + save_PixelTexGenParameteriSGIS(target, (GLint) *value); +} + + +/* KW: Compile commands + * + * Will appear in the list before the vertex buffer containing the + * command that provoked the error. I don't see this as a problem. + */ +void +_mesa_save_error( GLcontext *ctx, GLenum error, const char *s ) +{ + Node *n; + n = ALLOC_INSTRUCTION( ctx, OPCODE_ERROR, 2 ); + if (n) { + n[1].e = error; + n[2].data = (void *) s; + } + /* execute already done */ +} + + +static GLboolean +islist(GLcontext *ctx, GLuint list) +{ + if (list > 0 && _mesa_HashLookup(ctx->Shared->DisplayList, list)) { + return GL_TRUE; + } + else { + return GL_FALSE; + } +} + + + +/**********************************************************************/ +/* Display list execution */ +/**********************************************************************/ + + +/* + * Execute a display list. Note that the ListBase offset must have already + * been added before calling this function. I.e. the list argument is + * the absolute list number, not relative to ListBase. + * Input: list - display list number + */ +static void +execute_list( GLcontext *ctx, GLuint list ) +{ + Node *n; + GLboolean done; + + if (!islist(ctx,list)) + return; + + if (ctx->Driver.BeginCallList) + ctx->Driver.BeginCallList( ctx, list ); + +/* fprintf(stderr, "execute list %d\n", list); */ +/* mesa_print_display_list( list ); */ + + ctx->CallDepth++; + + n = (Node *) _mesa_HashLookup(ctx->Shared->DisplayList, list); + + done = GL_FALSE; + while (!done) { + OpCode opcode = n[0].opcode; + int i = (int)n[0].opcode - (int)OPCODE_DRV_0; + + if (i >= 0 && i < (GLint) ctx->listext.nr_opcodes) { + ctx->listext.opcode[i].execute(ctx, &n[1]); + n += ctx->listext.opcode[i].size; + } + else { + switch (opcode) { + case OPCODE_ERROR: + _mesa_error( ctx, n[1].e, (const char *) n[2].data ); + break; + case OPCODE_ACCUM: + (*ctx->Exec->Accum)( n[1].e, n[2].f ); + break; + case OPCODE_ALPHA_FUNC: + (*ctx->Exec->AlphaFunc)( n[1].e, n[2].f ); + break; + case OPCODE_BIND_TEXTURE: + (*ctx->Exec->BindTexture)( n[1].e, n[2].ui ); + break; + case OPCODE_BITMAP: + { + struct gl_pixelstore_attrib save = ctx->Unpack; + ctx->Unpack = _mesa_native_packing; + (*ctx->Exec->Bitmap)( (GLsizei) n[1].i, (GLsizei) n[2].i, + n[3].f, n[4].f, n[5].f, n[6].f, (const GLubyte *) n[7].data ); + ctx->Unpack = save; /* restore */ + } + break; + case OPCODE_BLEND_COLOR: + (*ctx->Exec->BlendColor)( n[1].f, n[2].f, n[3].f, n[4].f ); + break; + case OPCODE_BLEND_EQUATION: + (*ctx->Exec->BlendEquation)( n[1].e ); + break; + case OPCODE_BLEND_FUNC: + (*ctx->Exec->BlendFunc)( n[1].e, n[2].e ); + break; + case OPCODE_BLEND_FUNC_SEPARATE: + (*ctx->Exec->BlendFuncSeparateEXT)(n[1].e, n[2].e, n[3].e, n[4].e); + break; + case OPCODE_CALL_LIST: + /* Generated by glCallList(), don't add ListBase */ + if (ctx->CallDepthCallDepthList.ListBase + n[1].ui ); + } + break; + case OPCODE_CLEAR: + (*ctx->Exec->Clear)( n[1].bf ); + break; + case OPCODE_CLEAR_COLOR: + (*ctx->Exec->ClearColor)( n[1].f, n[2].f, n[3].f, n[4].f ); + break; + case OPCODE_CLEAR_ACCUM: + (*ctx->Exec->ClearAccum)( n[1].f, n[2].f, n[3].f, n[4].f ); + break; + case OPCODE_CLEAR_DEPTH: + (*ctx->Exec->ClearDepth)( (GLclampd) n[1].f ); + break; + case OPCODE_CLEAR_INDEX: + (*ctx->Exec->ClearIndex)( n[1].ui ); + break; + case OPCODE_CLEAR_STENCIL: + (*ctx->Exec->ClearStencil)( n[1].i ); + break; + case OPCODE_CLIP_PLANE: + { + GLdouble eq[4]; + eq[0] = n[2].f; + eq[1] = n[3].f; + eq[2] = n[4].f; + eq[3] = n[5].f; + (*ctx->Exec->ClipPlane)( n[1].e, eq ); + } + break; + case OPCODE_COLOR_MASK: + (*ctx->Exec->ColorMask)( n[1].b, n[2].b, n[3].b, n[4].b ); + break; + case OPCODE_COLOR_MATERIAL: + (*ctx->Exec->ColorMaterial)( n[1].e, n[2].e ); + break; + case OPCODE_COLOR_TABLE: + { + struct gl_pixelstore_attrib save = ctx->Unpack; + ctx->Unpack = _mesa_native_packing; + (*ctx->Exec->ColorTable)( n[1].e, n[2].e, n[3].i, n[4].e, + n[5].e, n[6].data ); + ctx->Unpack = save; /* restore */ + } + break; + case OPCODE_COLOR_TABLE_PARAMETER_FV: + { + GLfloat params[4]; + params[0] = n[3].f; + params[1] = n[4].f; + params[2] = n[5].f; + params[3] = n[6].f; + (*ctx->Exec->ColorTableParameterfv)( n[1].e, n[2].e, params ); + } + break; + case OPCODE_COLOR_TABLE_PARAMETER_IV: + { + GLint params[4]; + params[0] = n[3].i; + params[1] = n[4].i; + params[2] = n[5].i; + params[3] = n[6].i; + (*ctx->Exec->ColorTableParameteriv)( n[1].e, n[2].e, params ); + } + break; + case OPCODE_COLOR_SUB_TABLE: + { + struct gl_pixelstore_attrib save = ctx->Unpack; + ctx->Unpack = _mesa_native_packing; + (*ctx->Exec->ColorSubTable)( n[1].e, n[2].i, n[3].i, + n[4].e, n[5].e, n[6].data ); + ctx->Unpack = save; /* restore */ + } + break; + case OPCODE_CONVOLUTION_FILTER_1D: + { + struct gl_pixelstore_attrib save = ctx->Unpack; + ctx->Unpack = _mesa_native_packing; + (*ctx->Exec->ConvolutionFilter1D)( n[1].e, n[2].i, n[3].i, + n[4].e, n[5].e, n[6].data ); + ctx->Unpack = save; /* restore */ + } + break; + case OPCODE_CONVOLUTION_FILTER_2D: + { + struct gl_pixelstore_attrib save = ctx->Unpack; + ctx->Unpack = _mesa_native_packing; + (*ctx->Exec->ConvolutionFilter2D)( n[1].e, n[2].i, n[3].i, + n[4].i, n[5].e, n[6].e, n[7].data ); + ctx->Unpack = save; /* restore */ + } + break; + case OPCODE_CONVOLUTION_PARAMETER_I: + (*ctx->Exec->ConvolutionParameteri)( n[1].e, n[2].e, n[3].i ); + break; + case OPCODE_CONVOLUTION_PARAMETER_IV: + { + GLint params[4]; + params[0] = n[3].i; + params[1] = n[4].i; + params[2] = n[5].i; + params[3] = n[6].i; + (*ctx->Exec->ConvolutionParameteriv)( n[1].e, n[2].e, params ); + } + break; + case OPCODE_CONVOLUTION_PARAMETER_F: + (*ctx->Exec->ConvolutionParameterf)( n[1].e, n[2].e, n[3].f ); + break; + case OPCODE_CONVOLUTION_PARAMETER_FV: + { + GLfloat params[4]; + params[0] = n[3].f; + params[1] = n[4].f; + params[2] = n[5].f; + params[3] = n[6].f; + (*ctx->Exec->ConvolutionParameterfv)( n[1].e, n[2].e, params ); + } + break; + case OPCODE_COPY_COLOR_SUB_TABLE: + (*ctx->Exec->CopyColorSubTable)( n[1].e, n[2].i, + n[3].i, n[4].i, n[5].i ); + break; + case OPCODE_COPY_COLOR_TABLE: + (*ctx->Exec->CopyColorSubTable)( n[1].e, n[2].i, + n[3].i, n[4].i, n[5].i ); + break; + case OPCODE_COPY_PIXELS: + (*ctx->Exec->CopyPixels)( n[1].i, n[2].i, + (GLsizei) n[3].i, (GLsizei) n[4].i, n[5].e ); + break; + case OPCODE_COPY_TEX_IMAGE1D: + (*ctx->Exec->CopyTexImage1D)( n[1].e, n[2].i, n[3].e, n[4].i, + n[5].i, n[6].i, n[7].i ); + break; + case OPCODE_COPY_TEX_IMAGE2D: + (*ctx->Exec->CopyTexImage2D)( n[1].e, n[2].i, n[3].e, n[4].i, + n[5].i, n[6].i, n[7].i, n[8].i ); + break; + case OPCODE_COPY_TEX_SUB_IMAGE1D: + (*ctx->Exec->CopyTexSubImage1D)( n[1].e, n[2].i, n[3].i, + n[4].i, n[5].i, n[6].i ); + break; + case OPCODE_COPY_TEX_SUB_IMAGE2D: + (*ctx->Exec->CopyTexSubImage2D)( n[1].e, n[2].i, n[3].i, + n[4].i, n[5].i, n[6].i, n[7].i, n[8].i ); + break; + case OPCODE_COPY_TEX_SUB_IMAGE3D: + (*ctx->Exec->CopyTexSubImage3D)( n[1].e, n[2].i, n[3].i, + n[4].i, n[5].i, n[6].i, n[7].i, n[8].i , n[9].i); + break; + case OPCODE_CULL_FACE: + (*ctx->Exec->CullFace)( n[1].e ); + break; + case OPCODE_DEPTH_FUNC: + (*ctx->Exec->DepthFunc)( n[1].e ); + break; + case OPCODE_DEPTH_MASK: + (*ctx->Exec->DepthMask)( n[1].b ); + break; + case OPCODE_DEPTH_RANGE: + (*ctx->Exec->DepthRange)( (GLclampd) n[1].f, (GLclampd) n[2].f ); + break; + case OPCODE_DISABLE: + (*ctx->Exec->Disable)( n[1].e ); + break; + case OPCODE_DRAW_BUFFER: + (*ctx->Exec->DrawBuffer)( n[1].e ); + break; + case OPCODE_DRAW_PIXELS: + { + struct gl_pixelstore_attrib save = ctx->Unpack; + ctx->Unpack = _mesa_native_packing; + (*ctx->Exec->DrawPixels)( n[1].i, n[2].i, n[3].e, n[4].e, + n[5].data ); + ctx->Unpack = save; /* restore */ + } + break; + case OPCODE_ENABLE: + (*ctx->Exec->Enable)( n[1].e ); + break; + case OPCODE_EVALMESH1: + (*ctx->Exec->EvalMesh1)( n[1].e, n[2].i, n[3].i ); + break; + case OPCODE_EVALMESH2: + (*ctx->Exec->EvalMesh2)( n[1].e, n[2].i, n[3].i, n[4].i, n[5].i ); + break; + case OPCODE_FOG: + { + GLfloat p[4]; + p[0] = n[2].f; + p[1] = n[3].f; + p[2] = n[4].f; + p[3] = n[5].f; + (*ctx->Exec->Fogfv)( n[1].e, p ); + } + break; + case OPCODE_FRONT_FACE: + (*ctx->Exec->FrontFace)( n[1].e ); + break; + case OPCODE_FRUSTUM: + (*ctx->Exec->Frustum)( n[1].f, n[2].f, n[3].f, n[4].f, n[5].f, n[6].f ); + break; + case OPCODE_HINT: + (*ctx->Exec->Hint)( n[1].e, n[2].e ); + break; + case OPCODE_HISTOGRAM: + (*ctx->Exec->Histogram)( n[1].e, n[2].i, n[3].e, n[4].b ); + break; + case OPCODE_INDEX_MASK: + (*ctx->Exec->IndexMask)( n[1].ui ); + break; + case OPCODE_INIT_NAMES: + (*ctx->Exec->InitNames)(); + break; + case OPCODE_LIGHT: + { + GLfloat p[4]; + p[0] = n[3].f; + p[1] = n[4].f; + p[2] = n[5].f; + p[3] = n[6].f; + (*ctx->Exec->Lightfv)( n[1].e, n[2].e, p ); + } + break; + case OPCODE_LIGHT_MODEL: + { + GLfloat p[4]; + p[0] = n[2].f; + p[1] = n[3].f; + p[2] = n[4].f; + p[3] = n[5].f; + (*ctx->Exec->LightModelfv)( n[1].e, p ); + } + break; + case OPCODE_LINE_STIPPLE: + (*ctx->Exec->LineStipple)( n[1].i, n[2].us ); + break; + case OPCODE_LINE_WIDTH: + (*ctx->Exec->LineWidth)( n[1].f ); + break; + case OPCODE_LIST_BASE: + (*ctx->Exec->ListBase)( n[1].ui ); + break; + case OPCODE_LOAD_IDENTITY: + (*ctx->Exec->LoadIdentity)(); + break; + case OPCODE_LOAD_MATRIX: + if (sizeof(Node)==sizeof(GLfloat)) { + (*ctx->Exec->LoadMatrixf)( &n[1].f ); + } + else { + GLfloat m[16]; + GLuint i; + for (i=0;i<16;i++) { + m[i] = n[1+i].f; + } + (*ctx->Exec->LoadMatrixf)( m ); + } + break; + case OPCODE_LOAD_NAME: + (*ctx->Exec->LoadName)( n[1].ui ); + break; + case OPCODE_LOGIC_OP: + (*ctx->Exec->LogicOp)( n[1].e ); + break; + case OPCODE_MAP1: + { + GLenum target = n[1].e; + GLint ustride = _mesa_evaluator_components(target); + GLint uorder = n[5].i; + GLfloat u1 = n[2].f; + GLfloat u2 = n[3].f; + (*ctx->Exec->Map1f)( target, u1, u2, ustride, uorder, + (GLfloat *) n[6].data ); + } + break; + case OPCODE_MAP2: + { + GLenum target = n[1].e; + GLfloat u1 = n[2].f; + GLfloat u2 = n[3].f; + GLfloat v1 = n[4].f; + GLfloat v2 = n[5].f; + GLint ustride = n[6].i; + GLint vstride = n[7].i; + GLint uorder = n[8].i; + GLint vorder = n[9].i; + (*ctx->Exec->Map2f)( target, u1, u2, ustride, uorder, + v1, v2, vstride, vorder, + (GLfloat *) n[10].data ); + } + break; + case OPCODE_MAPGRID1: + (*ctx->Exec->MapGrid1f)( n[1].i, n[2].f, n[3].f ); + break; + case OPCODE_MAPGRID2: + (*ctx->Exec->MapGrid2f)( n[1].i, n[2].f, n[3].f, n[4].i, n[5].f, n[6].f); + break; + case OPCODE_MATRIX_MODE: + (*ctx->Exec->MatrixMode)( n[1].e ); + break; + case OPCODE_MIN_MAX: + (*ctx->Exec->Minmax)(n[1].e, n[2].e, n[3].b); + break; + case OPCODE_MULT_MATRIX: + if (sizeof(Node)==sizeof(GLfloat)) { + (*ctx->Exec->MultMatrixf)( &n[1].f ); + } + else { + GLfloat m[16]; + GLuint i; + for (i=0;i<16;i++) { + m[i] = n[1+i].f; + } + (*ctx->Exec->MultMatrixf)( m ); + } + break; + case OPCODE_ORTHO: + (*ctx->Exec->Ortho)( n[1].f, n[2].f, n[3].f, n[4].f, n[5].f, n[6].f ); + break; + case OPCODE_PASSTHROUGH: + (*ctx->Exec->PassThrough)( n[1].f ); + break; + case OPCODE_PIXEL_MAP: + (*ctx->Exec->PixelMapfv)( n[1].e, n[2].i, (GLfloat *) n[3].data ); + break; + case OPCODE_PIXEL_TRANSFER: + (*ctx->Exec->PixelTransferf)( n[1].e, n[2].f ); + break; + case OPCODE_PIXEL_ZOOM: + (*ctx->Exec->PixelZoom)( n[1].f, n[2].f ); + break; + case OPCODE_POINT_SIZE: + (*ctx->Exec->PointSize)( n[1].f ); + break; + case OPCODE_POINT_PARAMETERS: + { + GLfloat params[3]; + params[0] = n[2].f; + params[1] = n[3].f; + params[2] = n[4].f; + (*ctx->Exec->PointParameterfvEXT)( n[1].e, params ); + } + break; + case OPCODE_POLYGON_MODE: + (*ctx->Exec->PolygonMode)( n[1].e, n[2].e ); + break; + case OPCODE_POLYGON_STIPPLE: + (*ctx->Exec->PolygonStipple)( (GLubyte *) n[1].data ); + break; + case OPCODE_POLYGON_OFFSET: + (*ctx->Exec->PolygonOffset)( n[1].f, n[2].f ); + break; + case OPCODE_POP_ATTRIB: + (*ctx->Exec->PopAttrib)(); + break; + case OPCODE_POP_MATRIX: + (*ctx->Exec->PopMatrix)(); + break; + case OPCODE_POP_NAME: + (*ctx->Exec->PopName)(); + break; + case OPCODE_PRIORITIZE_TEXTURE: + (*ctx->Exec->PrioritizeTextures)( 1, &n[1].ui, &n[2].f ); + break; + case OPCODE_PUSH_ATTRIB: + (*ctx->Exec->PushAttrib)( n[1].bf ); + break; + case OPCODE_PUSH_MATRIX: + (*ctx->Exec->PushMatrix)(); + break; + case OPCODE_PUSH_NAME: + (*ctx->Exec->PushName)( n[1].ui ); + break; + case OPCODE_RASTER_POS: + (*ctx->Exec->RasterPos4f)( n[1].f, n[2].f, n[3].f, n[4].f ); + break; + case OPCODE_READ_BUFFER: + (*ctx->Exec->ReadBuffer)( n[1].e ); + break; + case OPCODE_RESET_HISTOGRAM: + (*ctx->Exec->ResetHistogram)( n[1].e ); + break; + case OPCODE_RESET_MIN_MAX: + (*ctx->Exec->ResetMinmax)( n[1].e ); + break; + case OPCODE_ROTATE: + (*ctx->Exec->Rotatef)( n[1].f, n[2].f, n[3].f, n[4].f ); + break; + case OPCODE_SCALE: + (*ctx->Exec->Scalef)( n[1].f, n[2].f, n[3].f ); + break; + case OPCODE_SCISSOR: + (*ctx->Exec->Scissor)( n[1].i, n[2].i, n[3].i, n[4].i ); + break; + case OPCODE_SHADE_MODEL: + (*ctx->Exec->ShadeModel)( n[1].e ); + break; + case OPCODE_STENCIL_FUNC: + (*ctx->Exec->StencilFunc)( n[1].e, n[2].i, n[3].ui ); + break; + case OPCODE_STENCIL_MASK: + (*ctx->Exec->StencilMask)( n[1].ui ); + break; + case OPCODE_STENCIL_OP: + (*ctx->Exec->StencilOp)( n[1].e, n[2].e, n[3].e ); + break; + case OPCODE_TEXENV: + { + GLfloat params[4]; + params[0] = n[3].f; + params[1] = n[4].f; + params[2] = n[5].f; + params[3] = n[6].f; + (*ctx->Exec->TexEnvfv)( n[1].e, n[2].e, params ); + } + break; + case OPCODE_TEXGEN: + { + GLfloat params[4]; + params[0] = n[3].f; + params[1] = n[4].f; + params[2] = n[5].f; + params[3] = n[6].f; + (*ctx->Exec->TexGenfv)( n[1].e, n[2].e, params ); + } + break; + case OPCODE_TEXPARAMETER: + { + GLfloat params[4]; + params[0] = n[3].f; + params[1] = n[4].f; + params[2] = n[5].f; + params[3] = n[6].f; + (*ctx->Exec->TexParameterfv)( n[1].e, n[2].e, params ); + } + break; + case OPCODE_TEX_IMAGE1D: + { + struct gl_pixelstore_attrib save = ctx->Unpack; + ctx->Unpack = _mesa_native_packing; + (*ctx->Exec->TexImage1D)( + n[1].e, /* target */ + n[2].i, /* level */ + n[3].i, /* components */ + n[4].i, /* width */ + n[5].e, /* border */ + n[6].e, /* format */ + n[7].e, /* type */ + n[8].data ); + ctx->Unpack = save; /* restore */ + } + break; + case OPCODE_TEX_IMAGE2D: + { + struct gl_pixelstore_attrib save = ctx->Unpack; + ctx->Unpack = _mesa_native_packing; + (*ctx->Exec->TexImage2D)( + n[1].e, /* target */ + n[2].i, /* level */ + n[3].i, /* components */ + n[4].i, /* width */ + n[5].i, /* height */ + n[6].e, /* border */ + n[7].e, /* format */ + n[8].e, /* type */ + n[9].data ); + ctx->Unpack = save; /* restore */ + } + break; + case OPCODE_TEX_IMAGE3D: + { + struct gl_pixelstore_attrib save = ctx->Unpack; + ctx->Unpack = _mesa_native_packing; + (*ctx->Exec->TexImage3D)( + n[1].e, /* target */ + n[2].i, /* level */ + n[3].i, /* components */ + n[4].i, /* width */ + n[5].i, /* height */ + n[6].i, /* depth */ + n[7].e, /* border */ + n[8].e, /* format */ + n[9].e, /* type */ + n[10].data ); + ctx->Unpack = save; /* restore */ + } + break; + case OPCODE_TEX_SUB_IMAGE1D: + { + struct gl_pixelstore_attrib save = ctx->Unpack; + ctx->Unpack = _mesa_native_packing; + (*ctx->Exec->TexSubImage1D)( n[1].e, n[2].i, n[3].i, + n[4].i, n[5].e, + n[6].e, n[7].data ); + ctx->Unpack = save; /* restore */ + } + break; + case OPCODE_TEX_SUB_IMAGE2D: + { + struct gl_pixelstore_attrib save = ctx->Unpack; + ctx->Unpack = _mesa_native_packing; + (*ctx->Exec->TexSubImage2D)( n[1].e, n[2].i, n[3].i, + n[4].i, n[5].e, + n[6].i, n[7].e, n[8].e, n[9].data ); + ctx->Unpack = save; /* restore */ + } + break; + case OPCODE_TEX_SUB_IMAGE3D: + { + struct gl_pixelstore_attrib save = ctx->Unpack; + ctx->Unpack = _mesa_native_packing; + (*ctx->Exec->TexSubImage3D)( n[1].e, n[2].i, n[3].i, + n[4].i, n[5].i, n[6].i, n[7].i, + n[8].i, n[9].e, n[10].e, + n[11].data ); + ctx->Unpack = save; /* restore */ + } + break; + case OPCODE_TRANSLATE: + (*ctx->Exec->Translatef)( n[1].f, n[2].f, n[3].f ); + break; + case OPCODE_VIEWPORT: + (*ctx->Exec->Viewport)(n[1].i, n[2].i, + (GLsizei) n[3].i, (GLsizei) n[4].i); + break; + case OPCODE_WINDOW_POS: + (*ctx->Exec->WindowPos4fMESA)( n[1].f, n[2].f, n[3].f, n[4].f ); + break; + case OPCODE_ACTIVE_TEXTURE: /* GL_ARB_multitexture */ + (*ctx->Exec->ActiveTextureARB)( n[1].e ); + break; + case OPCODE_PIXEL_TEXGEN_SGIX: /* GL_SGIX_pixel_texture */ + (*ctx->Exec->PixelTexGenSGIX)( n[1].e ); + break; + case OPCODE_PIXEL_TEXGEN_PARAMETER_SGIS: /* GL_SGIS_pixel_texture */ + (*ctx->Exec->PixelTexGenParameteriSGIS)( n[1].e, n[2].i ); + break; + case OPCODE_COMPRESSED_TEX_IMAGE_1D: /* GL_ARB_texture_compression */ + (*ctx->Exec->CompressedTexImage1DARB)(n[1].e, n[2].i, n[3].e, + n[4].i, n[5].i, n[6].i, n[7].data); + break; + case OPCODE_COMPRESSED_TEX_IMAGE_2D: /* GL_ARB_texture_compression */ + (*ctx->Exec->CompressedTexImage2DARB)(n[1].e, n[2].i, n[3].e, + n[4].i, n[5].i, n[6].i, n[7].i, n[8].data); + break; + case OPCODE_COMPRESSED_TEX_IMAGE_3D: /* GL_ARB_texture_compression */ + (*ctx->Exec->CompressedTexImage3DARB)(n[1].e, n[2].i, n[3].e, + n[4].i, n[5].i, n[6].i, n[7].i, n[8].i, n[9].data); + break; + case OPCODE_COMPRESSED_TEX_SUB_IMAGE_1D: /* GL_ARB_texture_compress */ + (*ctx->Exec->CompressedTexSubImage1DARB)(n[1].e, n[2].i, n[3].i, + n[4].i, n[5].e, n[6].i, n[7].data); + break; + case OPCODE_COMPRESSED_TEX_SUB_IMAGE_2D: /* GL_ARB_texture_compress */ + (*ctx->Exec->CompressedTexSubImage2DARB)(n[1].e, n[2].i, n[3].i, + n[4].i, n[5].i, n[6].i, n[7].e, n[8].i, n[9].data); + break; + case OPCODE_COMPRESSED_TEX_SUB_IMAGE_3D: /* GL_ARB_texture_compress */ + (*ctx->Exec->CompressedTexSubImage3DARB)(n[1].e, n[2].i, n[3].i, + n[4].i, n[5].i, n[6].i, n[7].i, n[8].i, + n[9].e, n[10].i, n[11].data); + break; + case OPCODE_SAMPLE_COVERAGE: /* GL_ARB_multisample */ + (*ctx->Exec->SampleCoverageARB)(n[1].f, n[2].b); + break; + case OPCODE_CONTINUE: + n = (Node *) n[1].next; + break; + case OPCODE_END_OF_LIST: + done = GL_TRUE; + break; + default: + { + char msg[1000]; + sprintf(msg, "Error in execute_list: opcode=%d", (int) opcode); + _mesa_problem( ctx, msg ); + } + done = GL_TRUE; + } + + /* increment n to point to next compiled command */ + if (opcode!=OPCODE_CONTINUE) { + n += InstSize[opcode]; + } + } + } + ctx->CallDepth--; + + if (ctx->Driver.EndCallList) + ctx->Driver.EndCallList( ctx ); +} + + + + + +/**********************************************************************/ +/* GL functions */ +/**********************************************************************/ + + + + +/* + * Test if a display list number is valid. + */ +GLboolean +_mesa_IsList( GLuint list ) +{ + GET_CURRENT_CONTEXT(ctx); + FLUSH_VERTICES(ctx, 0); /* must be called before assert */ + ASSERT_OUTSIDE_BEGIN_END_WITH_RETVAL(ctx, GL_FALSE); + return islist(ctx, list); +} + + +/* + * Delete a sequence of consecutive display lists. + */ +void +_mesa_DeleteLists( GLuint list, GLsizei range ) +{ + GET_CURRENT_CONTEXT(ctx); + GLuint i; + FLUSH_VERTICES(ctx, 0); /* must be called before assert */ + ASSERT_OUTSIDE_BEGIN_END(ctx); + + if (range<0) { + _mesa_error( ctx, GL_INVALID_VALUE, "glDeleteLists" ); + return; + } + for (i=list;iShared->Mutex); + + base = _mesa_HashFindFreeKeyBlock(ctx->Shared->DisplayList, range); + if (base) { + /* reserve the list IDs by with empty/dummy lists */ + GLint i; + for (i=0; iShared->DisplayList, base+i, make_empty_list()); + } + } + + _glthread_UNLOCK_MUTEX(ctx->Shared->Mutex); + + return base; +} + + + +/* + * Begin a new display list. + */ +void +_mesa_NewList( GLuint list, GLenum mode ) +{ + GET_CURRENT_CONTEXT(ctx); + FLUSH_CURRENT(ctx, 0); /* must be called before assert */ + ASSERT_OUTSIDE_BEGIN_END(ctx); + + if (MESA_VERBOSE&VERBOSE_API) + fprintf(stderr, "glNewList %u %s\n", list, _mesa_lookup_enum_by_nr(mode)); + + if (list==0) { + _mesa_error( ctx, GL_INVALID_VALUE, "glNewList" ); + return; + } + + if (mode!=GL_COMPILE && mode!=GL_COMPILE_AND_EXECUTE) { + _mesa_error( ctx, GL_INVALID_ENUM, "glNewList" ); + return; + } + + if (ctx->CurrentListPtr) { + /* already compiling a display list */ + _mesa_error( ctx, GL_INVALID_OPERATION, "glNewList" ); + return; + } + + /* Allocate new display list */ + ctx->CurrentListNum = list; + ctx->CurrentBlock = (Node *) MALLOC( sizeof(Node) * BLOCK_SIZE ); + ctx->CurrentListPtr = ctx->CurrentBlock; + ctx->CurrentPos = 0; + ctx->CompileFlag = GL_TRUE; + ctx->ExecuteFlag = (mode == GL_COMPILE_AND_EXECUTE); + + ctx->Driver.NewList( ctx, list, mode ); + + ctx->CurrentDispatch = ctx->Save; + _glapi_set_dispatch( ctx->CurrentDispatch ); +} + + + +/* + * End definition of current display list. Is the current + * ASSERT_OUTSIDE_BEGIN_END strong enough to really guarentee that + * we are outside begin/end calls? + */ +void +_mesa_EndList( void ) +{ + GET_CURRENT_CONTEXT(ctx); + FLUSH_CURRENT(ctx, 0); /* must be called before assert */ + ASSERT_OUTSIDE_BEGIN_END(ctx); + if (MESA_VERBOSE&VERBOSE_API) + fprintf(stderr, "glEndList\n"); + + ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH( ctx ); /* ??? */ + + /* Check that a list is under construction */ + if (!ctx->CurrentListPtr) { + _mesa_error( ctx, GL_INVALID_OPERATION, "glEndList" ); + return; + } + + (void) ALLOC_INSTRUCTION( ctx, OPCODE_END_OF_LIST, 0 ); + + /* Destroy old list, if any */ + _mesa_destroy_list(ctx, ctx->CurrentListNum); + /* Install the list */ + _mesa_HashInsert(ctx->Shared->DisplayList, ctx->CurrentListNum, ctx->CurrentListPtr); + + + if (MESA_VERBOSE & VERBOSE_DISPLAY_LIST) + mesa_print_display_list(ctx->CurrentListNum); + + ctx->CurrentListNum = 0; + ctx->CurrentListPtr = NULL; + ctx->ExecuteFlag = GL_TRUE; + ctx->CompileFlag = GL_FALSE; + + ctx->Driver.EndList( ctx ); + + ctx->CurrentDispatch = ctx->Exec; + _glapi_set_dispatch( ctx->CurrentDispatch ); + +} + + + +void +_mesa_CallList( GLuint list ) +{ + GLboolean save_compile_flag; + GET_CURRENT_CONTEXT(ctx); + FLUSH_CURRENT(ctx, 0); + /* VERY IMPORTANT: Save the CompileFlag status, turn it off, */ + /* execute the display list, and restore the CompileFlag. */ + +/* mesa_print_display_list( list ); */ + + save_compile_flag = ctx->CompileFlag; + if (save_compile_flag) { + ctx->CompileFlag = GL_FALSE; + } + + execute_list( ctx, list ); + ctx->CompileFlag = save_compile_flag; + + /* also restore API function pointers to point to "save" versions */ + if (save_compile_flag) { + ctx->CurrentDispatch = ctx->Save; + _glapi_set_dispatch( ctx->CurrentDispatch ); + } +} + + + +/* + * Execute glCallLists: call multiple display lists. + */ +void +_mesa_CallLists( GLsizei n, GLenum type, const GLvoid *lists ) +{ + GET_CURRENT_CONTEXT(ctx); + GLuint list; + GLint i; + GLboolean save_compile_flag; + + /* Save the CompileFlag status, turn it off, execute display list, + * and restore the CompileFlag. + */ + save_compile_flag = ctx->CompileFlag; + ctx->CompileFlag = GL_FALSE; + + for (i=0;iList.ListBase + list ); + } + + ctx->CompileFlag = save_compile_flag; + + /* also restore API function pointers to point to "save" versions */ + if (save_compile_flag) { + ctx->CurrentDispatch = ctx->Save; + _glapi_set_dispatch( ctx->CurrentDispatch ); + } +} + + + +/* + * Set the offset added to list numbers in glCallLists. + */ +void +_mesa_ListBase( GLuint base ) +{ + GET_CURRENT_CONTEXT(ctx); + FLUSH_VERTICES(ctx, 0); /* must be called before assert */ + ASSERT_OUTSIDE_BEGIN_END(ctx); + ctx->List.ListBase = base; +} + + +/* Can no longer assume ctx->Exec->Func is equal to _mesa_Func. + */ +static void exec_Finish( void ) +{ + GET_CURRENT_CONTEXT(ctx); + FLUSH_VERTICES(ctx, 0); + ctx->Exec->Finish(); +} + +static void exec_Flush( void ) +{ + GET_CURRENT_CONTEXT(ctx); + FLUSH_VERTICES(ctx, 0); + ctx->Exec->Flush( ); +} + +static void exec_GetBooleanv( GLenum pname, GLboolean *params ) +{ + GET_CURRENT_CONTEXT(ctx); + FLUSH_VERTICES(ctx, 0); + ctx->Exec->GetBooleanv( pname, params ); +} + +static void exec_GetClipPlane( GLenum plane, GLdouble *equation ) +{ + GET_CURRENT_CONTEXT(ctx); + FLUSH_VERTICES(ctx, 0); + ctx->Exec->GetClipPlane( plane, equation ); +} + +static void exec_GetDoublev( GLenum pname, GLdouble *params ) +{ + GET_CURRENT_CONTEXT(ctx); + FLUSH_VERTICES(ctx, 0); + ctx->Exec->GetDoublev( pname, params ); +} + +static GLenum exec_GetError( void ) +{ + GET_CURRENT_CONTEXT(ctx); + FLUSH_VERTICES(ctx, 0); + return ctx->Exec->GetError( ); +} + +static void exec_GetFloatv( GLenum pname, GLfloat *params ) +{ + GET_CURRENT_CONTEXT(ctx); + FLUSH_VERTICES(ctx, 0); + ctx->Exec->GetFloatv( pname, params ); +} + +static void exec_GetIntegerv( GLenum pname, GLint *params ) +{ + GET_CURRENT_CONTEXT(ctx); + FLUSH_VERTICES(ctx, 0); + ctx->Exec->GetIntegerv( pname, params ); +} + +static void exec_GetLightfv( GLenum light, GLenum pname, GLfloat *params ) +{ + GET_CURRENT_CONTEXT(ctx); + FLUSH_VERTICES(ctx, 0); + ctx->Exec->GetLightfv( light, pname, params ); +} + +static void exec_GetLightiv( GLenum light, GLenum pname, GLint *params ) +{ + GET_CURRENT_CONTEXT(ctx); + FLUSH_VERTICES(ctx, 0); + ctx->Exec->GetLightiv( light, pname, params ); +} + +static void exec_GetMapdv( GLenum target, GLenum query, GLdouble *v ) +{ + GET_CURRENT_CONTEXT(ctx); + FLUSH_VERTICES(ctx, 0); + ctx->Exec->GetMapdv( target, query, v ); +} + +static void exec_GetMapfv( GLenum target, GLenum query, GLfloat *v ) +{ + GET_CURRENT_CONTEXT(ctx); + FLUSH_VERTICES(ctx, 0); + ctx->Exec->GetMapfv( target, query, v ); +} + +static void exec_GetMapiv( GLenum target, GLenum query, GLint *v ) +{ + GET_CURRENT_CONTEXT(ctx); + FLUSH_VERTICES(ctx, 0); + ctx->Exec->GetMapiv( target, query, v ); +} + +static void exec_GetMaterialfv( GLenum face, GLenum pname, GLfloat *params ) +{ + GET_CURRENT_CONTEXT(ctx); + FLUSH_VERTICES(ctx, 0); + ctx->Exec->GetMaterialfv( face, pname, params ); +} + +static void exec_GetMaterialiv( GLenum face, GLenum pname, GLint *params ) +{ + GET_CURRENT_CONTEXT(ctx); + FLUSH_VERTICES(ctx, 0); + ctx->Exec->GetMaterialiv( face, pname, params ); +} + +static void exec_GetPixelMapfv( GLenum map, GLfloat *values ) +{ + GET_CURRENT_CONTEXT(ctx); + FLUSH_VERTICES(ctx, 0); + ctx->Exec->GetPixelMapfv( map, values ); +} + +static void exec_GetPixelMapuiv( GLenum map, GLuint *values ) +{ + GET_CURRENT_CONTEXT(ctx); + FLUSH_VERTICES(ctx, 0); + ctx->Exec->GetPixelMapuiv( map, values ); +} + +static void exec_GetPixelMapusv( GLenum map, GLushort *values ) +{ + GET_CURRENT_CONTEXT(ctx); + FLUSH_VERTICES(ctx, 0); + ctx->Exec->GetPixelMapusv( map, values ); +} + +static void exec_GetPolygonStipple( GLubyte *dest ) +{ + GET_CURRENT_CONTEXT(ctx); + FLUSH_VERTICES(ctx, 0); + ctx->Exec->GetPolygonStipple( dest ); +} + +static const GLubyte *exec_GetString( GLenum name ) +{ + GET_CURRENT_CONTEXT(ctx); + FLUSH_VERTICES(ctx, 0); + return ctx->Exec->GetString( name ); +} + +static void exec_GetTexEnvfv( GLenum target, GLenum pname, GLfloat *params ) +{ + GET_CURRENT_CONTEXT(ctx); + FLUSH_VERTICES(ctx, 0); + ctx->Exec->GetTexEnvfv( target, pname, params ); +} + +static void exec_GetTexEnviv( GLenum target, GLenum pname, GLint *params ) +{ + GET_CURRENT_CONTEXT(ctx); + FLUSH_VERTICES(ctx, 0); + ctx->Exec->GetTexEnviv( target, pname, params ); +} + +static void exec_GetTexGendv( GLenum coord, GLenum pname, GLdouble *params ) +{ + GET_CURRENT_CONTEXT(ctx); + FLUSH_VERTICES(ctx, 0); + ctx->Exec->GetTexGendv( coord, pname, params ); +} + +static void exec_GetTexGenfv( GLenum coord, GLenum pname, GLfloat *params ) +{ + GET_CURRENT_CONTEXT(ctx); + FLUSH_VERTICES(ctx, 0); + ctx->Exec->GetTexGenfv( coord, pname, params ); +} + +static void exec_GetTexGeniv( GLenum coord, GLenum pname, GLint *params ) +{ + GET_CURRENT_CONTEXT(ctx); + FLUSH_VERTICES(ctx, 0); + ctx->Exec->GetTexGeniv( coord, pname, params ); +} + +static void exec_GetTexImage( GLenum target, GLint level, GLenum format, + GLenum type, GLvoid *pixels ) +{ + GET_CURRENT_CONTEXT(ctx); + FLUSH_VERTICES(ctx, 0); + ctx->Exec->GetTexImage( target, level, format, type, pixels ); +} + +static void exec_GetTexLevelParameterfv( GLenum target, GLint level, + GLenum pname, GLfloat *params ) +{ + GET_CURRENT_CONTEXT(ctx); + FLUSH_VERTICES(ctx, 0); + ctx->Exec->GetTexLevelParameterfv( target, level, pname, params ); +} + +static void exec_GetTexLevelParameteriv( GLenum target, GLint level, + GLenum pname, GLint *params ) +{ + GET_CURRENT_CONTEXT(ctx); + FLUSH_VERTICES(ctx, 0); + ctx->Exec->GetTexLevelParameteriv( target, level, pname, params ); +} + +static void exec_GetTexParameterfv( GLenum target, GLenum pname, + GLfloat *params ) +{ + GET_CURRENT_CONTEXT(ctx); + FLUSH_VERTICES(ctx, 0); + ctx->Exec->GetTexParameterfv( target, pname, params ); +} + +static void exec_GetTexParameteriv( GLenum target, GLenum pname, GLint *params ) +{ + GET_CURRENT_CONTEXT(ctx); + FLUSH_VERTICES(ctx, 0); + ctx->Exec->GetTexParameteriv( target, pname, params ); +} + +static GLboolean exec_IsEnabled( GLenum cap ) +{ + GET_CURRENT_CONTEXT(ctx); + FLUSH_VERTICES(ctx, 0); + return ctx->Exec->IsEnabled( cap ); +} + +static void exec_PixelStoref( GLenum pname, GLfloat param ) +{ + GET_CURRENT_CONTEXT(ctx); + FLUSH_VERTICES(ctx, 0); + ctx->Exec->PixelStoref( pname, param ); +} + +static void exec_PixelStorei( GLenum pname, GLint param ) +{ + GET_CURRENT_CONTEXT(ctx); + FLUSH_VERTICES(ctx, 0); + ctx->Exec->PixelStorei( pname, param ); +} + +static void exec_ReadPixels( GLint x, GLint y, GLsizei width, GLsizei height, + GLenum format, GLenum type, GLvoid *pixels ) +{ + GET_CURRENT_CONTEXT(ctx); + FLUSH_VERTICES(ctx, 0); + ctx->Exec->ReadPixels( x, y, width, height, format, type, pixels ); +} + +static GLint exec_RenderMode( GLenum mode ) +{ + GET_CURRENT_CONTEXT(ctx); + FLUSH_VERTICES(ctx, 0); + return ctx->Exec->RenderMode( mode ); +} + +static void exec_FeedbackBuffer( GLsizei size, GLenum type, GLfloat *buffer ) +{ + GET_CURRENT_CONTEXT(ctx); + FLUSH_VERTICES(ctx, 0); + ctx->Exec->FeedbackBuffer( size, type, buffer ); +} + +static void exec_SelectBuffer( GLsizei size, GLuint *buffer ) +{ + GET_CURRENT_CONTEXT(ctx); + FLUSH_VERTICES(ctx, 0); + ctx->Exec->SelectBuffer( size, buffer ); +} + +static GLboolean exec_AreTexturesResident(GLsizei n, const GLuint *texName, + GLboolean *residences) +{ + GET_CURRENT_CONTEXT(ctx); + FLUSH_VERTICES(ctx, 0); + return ctx->Exec->AreTexturesResident( n, texName, residences); +} + +static void exec_ColorPointer(GLint size, GLenum type, GLsizei stride, + const GLvoid *ptr) +{ + GET_CURRENT_CONTEXT(ctx); + FLUSH_VERTICES(ctx, 0); + ctx->Exec->ColorPointer( size, type, stride, ptr); +} + +static void exec_DeleteTextures( GLsizei n, const GLuint *texName) +{ + GET_CURRENT_CONTEXT(ctx); + FLUSH_VERTICES(ctx, 0); + ctx->Exec->DeleteTextures( n, texName); +} + +static void exec_DisableClientState( GLenum cap ) +{ + GET_CURRENT_CONTEXT(ctx); + FLUSH_VERTICES(ctx, 0); + ctx->Exec->DisableClientState( cap ); +} + +static void exec_EdgeFlagPointer(GLsizei stride, const void *vptr) +{ + GET_CURRENT_CONTEXT(ctx); + FLUSH_VERTICES(ctx, 0); + ctx->Exec->EdgeFlagPointer( stride, vptr); +} + +static void exec_EnableClientState( GLenum cap ) +{ + GET_CURRENT_CONTEXT(ctx); + FLUSH_VERTICES(ctx, 0); + ctx->Exec->EnableClientState( cap ); +} + +static void exec_GenTextures( GLsizei n, GLuint *texName ) +{ + GET_CURRENT_CONTEXT(ctx); + FLUSH_VERTICES(ctx, 0); + ctx->Exec->GenTextures( n, texName ); +} + +static void exec_GetPointerv( GLenum pname, GLvoid **params ) +{ + GET_CURRENT_CONTEXT(ctx); + FLUSH_VERTICES(ctx, 0); + ctx->Exec->GetPointerv( pname, params ); +} + +static void exec_IndexPointer(GLenum type, GLsizei stride, const GLvoid *ptr) +{ + GET_CURRENT_CONTEXT(ctx); + FLUSH_VERTICES(ctx, 0); + ctx->Exec->IndexPointer( type, stride, ptr); +} + +static void exec_InterleavedArrays(GLenum format, GLsizei stride, + const GLvoid *pointer) +{ + GET_CURRENT_CONTEXT(ctx); + FLUSH_VERTICES(ctx, 0); + ctx->Exec->InterleavedArrays( format, stride, pointer); +} + +static GLboolean exec_IsTexture( GLuint texture ) +{ + GET_CURRENT_CONTEXT(ctx); + FLUSH_VERTICES(ctx, 0); + return ctx->Exec->IsTexture( texture ); +} + +static void exec_NormalPointer(GLenum type, GLsizei stride, const GLvoid *ptr ) +{ + GET_CURRENT_CONTEXT(ctx); + FLUSH_VERTICES(ctx, 0); + ctx->Exec->NormalPointer( type, stride, ptr ); +} + +static void exec_PopClientAttrib(void) +{ + GET_CURRENT_CONTEXT(ctx); + FLUSH_VERTICES(ctx, 0); + ctx->Exec->PopClientAttrib(); +} + +static void exec_PushClientAttrib(GLbitfield mask) +{ + GET_CURRENT_CONTEXT(ctx); + FLUSH_VERTICES(ctx, 0); + ctx->Exec->PushClientAttrib( mask); +} + +static void exec_TexCoordPointer(GLint size, GLenum type, GLsizei stride, + const GLvoid *ptr) +{ + GET_CURRENT_CONTEXT(ctx); + FLUSH_VERTICES(ctx, 0); + ctx->Exec->TexCoordPointer( size, type, stride, ptr); +} + +static void exec_GetCompressedTexImageARB(GLenum target, GLint level, + GLvoid *img) +{ + GET_CURRENT_CONTEXT(ctx); + FLUSH_VERTICES(ctx, 0); + ctx->Exec->GetCompressedTexImageARB( target, level, img); +} + +static void exec_VertexPointer(GLint size, GLenum type, GLsizei stride, + const GLvoid *ptr) +{ + GET_CURRENT_CONTEXT(ctx); + FLUSH_VERTICES(ctx, 0); + ctx->Exec->VertexPointer( size, type, stride, ptr); +} + +static void exec_CopyConvolutionFilter1D(GLenum target, GLenum internalFormat, + GLint x, GLint y, GLsizei width) +{ + GET_CURRENT_CONTEXT(ctx); + FLUSH_VERTICES(ctx, 0); + ctx->Exec->CopyConvolutionFilter1D( target, internalFormat, x, y, width); +} + +static void exec_CopyConvolutionFilter2D(GLenum target, GLenum internalFormat, + GLint x, GLint y, GLsizei width, + GLsizei height) +{ + GET_CURRENT_CONTEXT(ctx); + FLUSH_VERTICES(ctx, 0); + ctx->Exec->CopyConvolutionFilter2D( target, internalFormat, x, y, width, + height); +} + +static void exec_GetColorTable( GLenum target, GLenum format, + GLenum type, GLvoid *data ) +{ + GET_CURRENT_CONTEXT(ctx); + FLUSH_VERTICES(ctx, 0); + ctx->Exec->GetColorTable( target, format, type, data ); +} + +static void exec_GetColorTableParameterfv( GLenum target, GLenum pname, + GLfloat *params ) +{ + GET_CURRENT_CONTEXT(ctx); + FLUSH_VERTICES(ctx, 0); + ctx->Exec->GetColorTableParameterfv( target, pname, params ); +} + +static void exec_GetColorTableParameteriv( GLenum target, GLenum pname, + GLint *params ) +{ + GET_CURRENT_CONTEXT(ctx); + FLUSH_VERTICES(ctx, 0); + ctx->Exec->GetColorTableParameteriv( target, pname, params ); +} + +static void exec_GetConvolutionFilter(GLenum target, GLenum format, GLenum type, + GLvoid *image) +{ + GET_CURRENT_CONTEXT(ctx); + FLUSH_VERTICES(ctx, 0); + ctx->Exec->GetConvolutionFilter( target, format, type, image); +} + +static void exec_GetConvolutionParameterfv(GLenum target, GLenum pname, + GLfloat *params) +{ + GET_CURRENT_CONTEXT(ctx); + FLUSH_VERTICES(ctx, 0); + ctx->Exec->GetConvolutionParameterfv( target, pname, params); +} + +static void exec_GetConvolutionParameteriv(GLenum target, GLenum pname, + GLint *params) +{ + GET_CURRENT_CONTEXT(ctx); + FLUSH_VERTICES(ctx, 0); + ctx->Exec->GetConvolutionParameteriv( target, pname, params); +} + +static void exec_GetHistogram(GLenum target, GLboolean reset, GLenum format, + GLenum type, GLvoid *values) +{ + GET_CURRENT_CONTEXT(ctx); + FLUSH_VERTICES(ctx, 0); + ctx->Exec->GetHistogram( target, reset, format, type, values); +} + +static void exec_GetHistogramParameterfv(GLenum target, GLenum pname, + GLfloat *params) +{ + GET_CURRENT_CONTEXT(ctx); + FLUSH_VERTICES(ctx, 0); + ctx->Exec->GetHistogramParameterfv( target, pname, params); +} + +static void exec_GetHistogramParameteriv(GLenum target, GLenum pname, + GLint *params) +{ + GET_CURRENT_CONTEXT(ctx); + FLUSH_VERTICES(ctx, 0); + ctx->Exec->GetHistogramParameteriv( target, pname, params); +} + +static void exec_GetMinmax(GLenum target, GLboolean reset, GLenum format, + GLenum type, GLvoid *values) +{ + GET_CURRENT_CONTEXT(ctx); + FLUSH_VERTICES(ctx, 0); + ctx->Exec->GetMinmax( target, reset, format, type, values); +} + +static void exec_GetMinmaxParameterfv(GLenum target, GLenum pname, + GLfloat *params) +{ + GET_CURRENT_CONTEXT(ctx); + FLUSH_VERTICES(ctx, 0); + ctx->Exec->GetMinmaxParameterfv( target, pname, params); +} + +static void exec_GetMinmaxParameteriv(GLenum target, GLenum pname, + GLint *params) +{ + GET_CURRENT_CONTEXT(ctx); + FLUSH_VERTICES(ctx, 0); + ctx->Exec->GetMinmaxParameteriv( target, pname, params); +} + +static void exec_GetSeparableFilter(GLenum target, GLenum format, GLenum type, + GLvoid *row, GLvoid *column, GLvoid *span) +{ + GET_CURRENT_CONTEXT(ctx); + FLUSH_VERTICES(ctx, 0); + ctx->Exec->GetSeparableFilter( target, format, type, row, column, span); +} + +static void exec_SeparableFilter2D(GLenum target, GLenum internalFormat, + GLsizei width, GLsizei height, GLenum format, + GLenum type, const GLvoid *row, + const GLvoid *column) +{ + GET_CURRENT_CONTEXT(ctx); + FLUSH_VERTICES(ctx, 0); + ctx->Exec->SeparableFilter2D( target, internalFormat, width, height, format, + type, row, column); +} + +static void exec_GetPixelTexGenParameterivSGIS(GLenum target, GLint *value) +{ + GET_CURRENT_CONTEXT(ctx); + FLUSH_VERTICES(ctx, 0); + ctx->Exec->GetPixelTexGenParameterivSGIS( target, value); +} + +static void exec_GetPixelTexGenParameterfvSGIS(GLenum target, GLfloat *value) +{ + GET_CURRENT_CONTEXT(ctx); + FLUSH_VERTICES(ctx, 0); + ctx->Exec->GetPixelTexGenParameterfvSGIS( target, value); +} + +static void exec_ColorPointerEXT(GLint size, GLenum type, GLsizei stride, + GLsizei count, const GLvoid *ptr) +{ + GET_CURRENT_CONTEXT(ctx); + FLUSH_VERTICES(ctx, 0); + ctx->Exec->ColorPointerEXT( size, type, stride, count, ptr); +} + +static void exec_EdgeFlagPointerEXT(GLsizei stride, GLsizei count, + const GLboolean *ptr) +{ + GET_CURRENT_CONTEXT(ctx); + FLUSH_VERTICES(ctx, 0); + ctx->Exec->EdgeFlagPointerEXT( stride, count, ptr); +} + +static void exec_IndexPointerEXT(GLenum type, GLsizei stride, GLsizei count, + const GLvoid *ptr) +{ + GET_CURRENT_CONTEXT(ctx); + FLUSH_VERTICES(ctx, 0); + ctx->Exec->IndexPointerEXT( type, stride, count, ptr); +} + +static void exec_NormalPointerEXT(GLenum type, GLsizei stride, GLsizei count, + const GLvoid *ptr) +{ + GET_CURRENT_CONTEXT(ctx); + FLUSH_VERTICES(ctx, 0); + ctx->Exec->NormalPointerEXT( type, stride, count, ptr); +} + +static void exec_TexCoordPointerEXT(GLint size, GLenum type, GLsizei stride, + GLsizei count, const GLvoid *ptr) +{ + GET_CURRENT_CONTEXT(ctx); + FLUSH_VERTICES(ctx, 0); + ctx->Exec->TexCoordPointerEXT( size, type, stride, count, ptr); +} + +static void exec_VertexPointerEXT(GLint size, GLenum type, GLsizei stride, + GLsizei count, const GLvoid *ptr) +{ + GET_CURRENT_CONTEXT(ctx); + FLUSH_VERTICES(ctx, 0); + ctx->Exec->VertexPointerEXT( size, type, stride, count, ptr); +} + +static void exec_LockArraysEXT(GLint first, GLsizei count) +{ + GET_CURRENT_CONTEXT(ctx); + FLUSH_VERTICES(ctx, 0); + ctx->Exec->LockArraysEXT( first, count); +} + +static void exec_UnlockArraysEXT( void ) +{ + GET_CURRENT_CONTEXT(ctx); + FLUSH_VERTICES(ctx, 0); + ctx->Exec->UnlockArraysEXT( ); +} + +static void exec_ResizeBuffersMESA( void ) +{ + GET_CURRENT_CONTEXT(ctx); + FLUSH_VERTICES(ctx, 0); + ctx->Exec->ResizeBuffersMESA( ); +} + + +static void exec_ClientActiveTextureARB( GLenum target ) +{ + GET_CURRENT_CONTEXT(ctx); + FLUSH_VERTICES(ctx, 0); + ctx->Exec->ClientActiveTextureARB(target); +} + +static void exec_SecondaryColorPointerEXT(GLint size, GLenum type, + GLsizei stride, const GLvoid *ptr) +{ + GET_CURRENT_CONTEXT(ctx); + FLUSH_VERTICES(ctx, 0); + ctx->Exec->SecondaryColorPointerEXT( size, type, stride, ptr); +} + +static void exec_FogCoordPointerEXT(GLenum type, GLsizei stride, + const GLvoid *ptr) +{ + GET_CURRENT_CONTEXT(ctx); + FLUSH_VERTICES(ctx, 0); + ctx->Exec->FogCoordPointerEXT( type, stride, ptr); +} + + +/* + * Assign all the pointers in to point to Mesa's display list + * building functions. + * + * This does not include any of the tnl functions - they are + * initialized from _mesa_init_api_defaults and from the active vtxfmt + * struct. + */ +void +_mesa_init_dlist_table( struct _glapi_table *table, GLuint tableSize ) +{ + _mesa_init_no_op_table(table, tableSize); + + _mesa_loopback_init_api_table( table, GL_TRUE ); + + /* GL 1.0 */ + table->Accum = save_Accum; + table->AlphaFunc = save_AlphaFunc; + table->Bitmap = save_Bitmap; + table->BlendFunc = save_BlendFunc; + table->CallList = _mesa_save_CallList; + table->CallLists = _mesa_save_CallLists; + table->Clear = save_Clear; + table->ClearAccum = save_ClearAccum; + table->ClearColor = save_ClearColor; + table->ClearDepth = save_ClearDepth; + table->ClearIndex = save_ClearIndex; + table->ClearStencil = save_ClearStencil; + table->ClipPlane = save_ClipPlane; + table->ColorMask = save_ColorMask; + table->ColorMaterial = save_ColorMaterial; + table->CopyPixels = save_CopyPixels; + table->CullFace = save_CullFace; + table->DeleteLists = _mesa_DeleteLists; + table->DepthFunc = save_DepthFunc; + table->DepthMask = save_DepthMask; + table->DepthRange = save_DepthRange; + table->Disable = save_Disable; + table->DrawBuffer = save_DrawBuffer; + table->DrawPixels = save_DrawPixels; + table->Enable = save_Enable; + table->EndList = _mesa_EndList; + table->EvalMesh1 = _mesa_save_EvalMesh1; + table->EvalMesh2 = _mesa_save_EvalMesh2; + table->Finish = exec_Finish; + table->Flush = exec_Flush; + table->Fogf = save_Fogf; + table->Fogfv = save_Fogfv; + table->Fogi = save_Fogi; + table->Fogiv = save_Fogiv; + table->FrontFace = save_FrontFace; + table->Frustum = save_Frustum; + table->GenLists = _mesa_GenLists; + table->GetBooleanv = exec_GetBooleanv; + table->GetClipPlane = exec_GetClipPlane; + table->GetDoublev = exec_GetDoublev; + table->GetError = exec_GetError; + table->GetFloatv = exec_GetFloatv; + table->GetIntegerv = exec_GetIntegerv; + table->GetLightfv = exec_GetLightfv; + table->GetLightiv = exec_GetLightiv; + table->GetMapdv = exec_GetMapdv; + table->GetMapfv = exec_GetMapfv; + table->GetMapiv = exec_GetMapiv; + table->GetMaterialfv = exec_GetMaterialfv; + table->GetMaterialiv = exec_GetMaterialiv; + table->GetPixelMapfv = exec_GetPixelMapfv; + table->GetPixelMapuiv = exec_GetPixelMapuiv; + table->GetPixelMapusv = exec_GetPixelMapusv; + table->GetPolygonStipple = exec_GetPolygonStipple; + table->GetString = exec_GetString; + table->GetTexEnvfv = exec_GetTexEnvfv; + table->GetTexEnviv = exec_GetTexEnviv; + table->GetTexGendv = exec_GetTexGendv; + table->GetTexGenfv = exec_GetTexGenfv; + table->GetTexGeniv = exec_GetTexGeniv; + table->GetTexImage = exec_GetTexImage; + table->GetTexLevelParameterfv = exec_GetTexLevelParameterfv; + table->GetTexLevelParameteriv = exec_GetTexLevelParameteriv; + table->GetTexParameterfv = exec_GetTexParameterfv; + table->GetTexParameteriv = exec_GetTexParameteriv; + table->Hint = save_Hint; + table->IndexMask = save_IndexMask; + table->InitNames = save_InitNames; + table->IsEnabled = exec_IsEnabled; + table->IsList = _mesa_IsList; + table->LightModelf = save_LightModelf; + table->LightModelfv = save_LightModelfv; + table->LightModeli = save_LightModeli; + table->LightModeliv = save_LightModeliv; + table->Lightf = save_Lightf; + table->Lightfv = save_Lightfv; + table->Lighti = save_Lighti; + table->Lightiv = save_Lightiv; + table->LineStipple = save_LineStipple; + table->LineWidth = save_LineWidth; + table->ListBase = save_ListBase; + table->LoadIdentity = save_LoadIdentity; + table->LoadMatrixd = save_LoadMatrixd; + table->LoadMatrixf = save_LoadMatrixf; + table->LoadName = save_LoadName; + table->LogicOp = save_LogicOp; + table->Map1d = save_Map1d; + table->Map1f = save_Map1f; + table->Map2d = save_Map2d; + table->Map2f = save_Map2f; + table->MapGrid1d = save_MapGrid1d; + table->MapGrid1f = save_MapGrid1f; + table->MapGrid2d = save_MapGrid2d; + table->MapGrid2f = save_MapGrid2f; + table->MatrixMode = save_MatrixMode; + table->MultMatrixd = save_MultMatrixd; + table->MultMatrixf = save_MultMatrixf; + table->NewList = save_NewList; + table->Ortho = save_Ortho; + table->PassThrough = save_PassThrough; + table->PixelMapfv = save_PixelMapfv; + table->PixelMapuiv = save_PixelMapuiv; + table->PixelMapusv = save_PixelMapusv; + table->PixelStoref = exec_PixelStoref; + table->PixelStorei = exec_PixelStorei; + table->PixelTransferf = save_PixelTransferf; + table->PixelTransferi = save_PixelTransferi; + table->PixelZoom = save_PixelZoom; + table->PointSize = save_PointSize; + table->PolygonMode = save_PolygonMode; + table->PolygonOffset = save_PolygonOffset; + table->PolygonStipple = save_PolygonStipple; + table->PopAttrib = save_PopAttrib; + table->PopMatrix = save_PopMatrix; + table->PopName = save_PopName; + table->PushAttrib = save_PushAttrib; + table->PushMatrix = save_PushMatrix; + table->PushName = save_PushName; + table->RasterPos2d = save_RasterPos2d; + table->RasterPos2dv = save_RasterPos2dv; + table->RasterPos2f = save_RasterPos2f; + table->RasterPos2fv = save_RasterPos2fv; + table->RasterPos2i = save_RasterPos2i; + table->RasterPos2iv = save_RasterPos2iv; + table->RasterPos2s = save_RasterPos2s; + table->RasterPos2sv = save_RasterPos2sv; + table->RasterPos3d = save_RasterPos3d; + table->RasterPos3dv = save_RasterPos3dv; + table->RasterPos3f = save_RasterPos3f; + table->RasterPos3fv = save_RasterPos3fv; + table->RasterPos3i = save_RasterPos3i; + table->RasterPos3iv = save_RasterPos3iv; + table->RasterPos3s = save_RasterPos3s; + table->RasterPos3sv = save_RasterPos3sv; + table->RasterPos4d = save_RasterPos4d; + table->RasterPos4dv = save_RasterPos4dv; + table->RasterPos4f = save_RasterPos4f; + table->RasterPos4fv = save_RasterPos4fv; + table->RasterPos4i = save_RasterPos4i; + table->RasterPos4iv = save_RasterPos4iv; + table->RasterPos4s = save_RasterPos4s; + table->RasterPos4sv = save_RasterPos4sv; + table->ReadBuffer = save_ReadBuffer; + table->ReadPixels = exec_ReadPixels; + table->RenderMode = exec_RenderMode; + table->Rotated = save_Rotated; + table->Rotatef = save_Rotatef; + table->Scaled = save_Scaled; + table->Scalef = save_Scalef; + table->Scissor = save_Scissor; + table->FeedbackBuffer = exec_FeedbackBuffer; + table->SelectBuffer = exec_SelectBuffer; + table->ShadeModel = save_ShadeModel; + table->StencilFunc = save_StencilFunc; + table->StencilMask = save_StencilMask; + table->StencilOp = save_StencilOp; + table->TexEnvf = save_TexEnvf; + table->TexEnvfv = save_TexEnvfv; + table->TexEnvi = save_TexEnvi; + table->TexEnviv = save_TexEnviv; + table->TexGend = save_TexGend; + table->TexGendv = save_TexGendv; + table->TexGenf = save_TexGenf; + table->TexGenfv = save_TexGenfv; + table->TexGeni = save_TexGeni; + table->TexGeniv = save_TexGeniv; + table->TexImage1D = save_TexImage1D; + table->TexImage2D = save_TexImage2D; + table->TexParameterf = save_TexParameterf; + table->TexParameterfv = save_TexParameterfv; + table->TexParameteri = save_TexParameteri; + table->TexParameteriv = save_TexParameteriv; + table->Translated = save_Translated; + table->Translatef = save_Translatef; + table->Viewport = save_Viewport; + + /* GL 1.1 */ + table->AreTexturesResident = exec_AreTexturesResident; + table->BindTexture = save_BindTexture; + table->ColorPointer = exec_ColorPointer; + table->CopyTexImage1D = save_CopyTexImage1D; + table->CopyTexImage2D = save_CopyTexImage2D; + table->CopyTexSubImage1D = save_CopyTexSubImage1D; + table->CopyTexSubImage2D = save_CopyTexSubImage2D; + table->DeleteTextures = exec_DeleteTextures; + table->DisableClientState = exec_DisableClientState; + table->EdgeFlagPointer = exec_EdgeFlagPointer; + table->EnableClientState = exec_EnableClientState; + table->GenTextures = exec_GenTextures; + table->GetPointerv = exec_GetPointerv; + table->IndexPointer = exec_IndexPointer; + table->InterleavedArrays = exec_InterleavedArrays; + table->IsTexture = exec_IsTexture; + table->NormalPointer = exec_NormalPointer; + table->PopClientAttrib = exec_PopClientAttrib; + table->PrioritizeTextures = save_PrioritizeTextures; + table->PushClientAttrib = exec_PushClientAttrib; + table->TexCoordPointer = exec_TexCoordPointer; + table->TexSubImage1D = save_TexSubImage1D; + table->TexSubImage2D = save_TexSubImage2D; + table->VertexPointer = exec_VertexPointer; + + /* GL 1.2 */ + table->CopyTexSubImage3D = save_CopyTexSubImage3D; + table->TexImage3D = save_TexImage3D; + table->TexSubImage3D = save_TexSubImage3D; + + /* GL_ARB_imaging */ + /* Not all are supported */ + table->BlendColor = save_BlendColor; + table->BlendEquation = save_BlendEquation; + table->ColorSubTable = save_ColorSubTable; + table->ColorTable = save_ColorTable; + table->ColorTableParameterfv = save_ColorTableParameterfv; + table->ColorTableParameteriv = save_ColorTableParameteriv; + table->ConvolutionFilter1D = save_ConvolutionFilter1D; + table->ConvolutionFilter2D = save_ConvolutionFilter2D; + table->ConvolutionParameterf = save_ConvolutionParameterf; + table->ConvolutionParameterfv = save_ConvolutionParameterfv; + table->ConvolutionParameteri = save_ConvolutionParameteri; + table->ConvolutionParameteriv = save_ConvolutionParameteriv; + table->CopyColorSubTable = save_CopyColorSubTable; + table->CopyColorTable = save_CopyColorTable; + table->CopyConvolutionFilter1D = exec_CopyConvolutionFilter1D; + table->CopyConvolutionFilter2D = exec_CopyConvolutionFilter2D; + table->GetColorTable = exec_GetColorTable; + table->GetColorTableParameterfv = exec_GetColorTableParameterfv; + table->GetColorTableParameteriv = exec_GetColorTableParameteriv; + table->GetConvolutionFilter = exec_GetConvolutionFilter; + table->GetConvolutionParameterfv = exec_GetConvolutionParameterfv; + table->GetConvolutionParameteriv = exec_GetConvolutionParameteriv; + table->GetHistogram = exec_GetHistogram; + table->GetHistogramParameterfv = exec_GetHistogramParameterfv; + table->GetHistogramParameteriv = exec_GetHistogramParameteriv; + table->GetMinmax = exec_GetMinmax; + table->GetMinmaxParameterfv = exec_GetMinmaxParameterfv; + table->GetMinmaxParameteriv = exec_GetMinmaxParameteriv; + table->GetSeparableFilter = exec_GetSeparableFilter; + table->Histogram = save_Histogram; + table->Minmax = save_Minmax; + table->ResetHistogram = save_ResetHistogram; + table->ResetMinmax = save_ResetMinmax; + table->SeparableFilter2D = exec_SeparableFilter2D; + + /* 2. GL_EXT_blend_color */ +#if 0 + table->BlendColorEXT = save_BlendColorEXT; +#endif + + /* 3. GL_EXT_polygon_offset */ + table->PolygonOffsetEXT = save_PolygonOffsetEXT; + + /* 6. GL_EXT_texture3d */ +#if 0 + table->CopyTexSubImage3DEXT = save_CopyTexSubImage3D; + table->TexImage3DEXT = save_TexImage3DEXT; + table->TexSubImage3DEXT = save_TexSubImage3D; +#endif + + /* 15. GL_SGIX_pixel_texture */ + table->PixelTexGenSGIX = save_PixelTexGenSGIX; + + /* 15. GL_SGIS_pixel_texture */ + table->PixelTexGenParameteriSGIS = save_PixelTexGenParameteriSGIS; + table->PixelTexGenParameterfSGIS = save_PixelTexGenParameterfSGIS; + table->PixelTexGenParameterivSGIS = save_PixelTexGenParameterivSGIS; + table->PixelTexGenParameterfvSGIS = save_PixelTexGenParameterfvSGIS; + table->GetPixelTexGenParameterivSGIS = exec_GetPixelTexGenParameterivSGIS; + table->GetPixelTexGenParameterfvSGIS = exec_GetPixelTexGenParameterfvSGIS; + + /* 30. GL_EXT_vertex_array */ + table->ColorPointerEXT = exec_ColorPointerEXT; + table->EdgeFlagPointerEXT = exec_EdgeFlagPointerEXT; + table->IndexPointerEXT = exec_IndexPointerEXT; + table->NormalPointerEXT = exec_NormalPointerEXT; + table->TexCoordPointerEXT = exec_TexCoordPointerEXT; + table->VertexPointerEXT = exec_VertexPointerEXT; + + /* 37. GL_EXT_blend_minmax */ +#if 0 + table->BlendEquationEXT = save_BlendEquationEXT; +#endif + + /* 54. GL_EXT_point_parameters */ + table->PointParameterfEXT = save_PointParameterfEXT; + table->PointParameterfvEXT = save_PointParameterfvEXT; + + /* 78. GL_EXT_paletted_texture */ +#if 0 + table->ColorTableEXT = save_ColorTable; + table->ColorSubTableEXT = save_ColorSubTable; +#endif + table->GetColorTableEXT = exec_GetColorTable; + table->GetColorTableParameterfvEXT = exec_GetColorTableParameterfv; + table->GetColorTableParameterivEXT = exec_GetColorTableParameteriv; + + /* 97. GL_EXT_compiled_vertex_array */ + table->LockArraysEXT = exec_LockArraysEXT; + table->UnlockArraysEXT = exec_UnlockArraysEXT; + + /* GL_ARB_multitexture */ + table->ActiveTextureARB = save_ActiveTextureARB; + table->ClientActiveTextureARB = exec_ClientActiveTextureARB; + + /* GL_EXT_blend_func_separate */ + table->BlendFuncSeparateEXT = save_BlendFuncSeparateEXT; + + /* GL_MESA_window_pos */ + table->WindowPos2dMESA = save_WindowPos2dMESA; + table->WindowPos2dvMESA = save_WindowPos2dvMESA; + table->WindowPos2fMESA = save_WindowPos2fMESA; + table->WindowPos2fvMESA = save_WindowPos2fvMESA; + table->WindowPos2iMESA = save_WindowPos2iMESA; + table->WindowPos2ivMESA = save_WindowPos2ivMESA; + table->WindowPos2sMESA = save_WindowPos2sMESA; + table->WindowPos2svMESA = save_WindowPos2svMESA; + table->WindowPos3dMESA = save_WindowPos3dMESA; + table->WindowPos3dvMESA = save_WindowPos3dvMESA; + table->WindowPos3fMESA = save_WindowPos3fMESA; + table->WindowPos3fvMESA = save_WindowPos3fvMESA; + table->WindowPos3iMESA = save_WindowPos3iMESA; + table->WindowPos3ivMESA = save_WindowPos3ivMESA; + table->WindowPos3sMESA = save_WindowPos3sMESA; + table->WindowPos3svMESA = save_WindowPos3svMESA; + table->WindowPos4dMESA = save_WindowPos4dMESA; + table->WindowPos4dvMESA = save_WindowPos4dvMESA; + table->WindowPos4fMESA = save_WindowPos4fMESA; + table->WindowPos4fvMESA = save_WindowPos4fvMESA; + table->WindowPos4iMESA = save_WindowPos4iMESA; + table->WindowPos4ivMESA = save_WindowPos4ivMESA; + table->WindowPos4sMESA = save_WindowPos4sMESA; + table->WindowPos4svMESA = save_WindowPos4svMESA; + + /* GL_MESA_resize_buffers */ + table->ResizeBuffersMESA = exec_ResizeBuffersMESA; + + /* GL_ARB_transpose_matrix */ + table->LoadTransposeMatrixdARB = save_LoadTransposeMatrixdARB; + table->LoadTransposeMatrixfARB = save_LoadTransposeMatrixfARB; + table->MultTransposeMatrixdARB = save_MultTransposeMatrixdARB; + table->MultTransposeMatrixfARB = save_MultTransposeMatrixfARB; + + /* GL_ARB_multisample */ + table->SampleCoverageARB = save_SampleCoverageARB; + + /* ARB 12. GL_ARB_texture_compression */ + table->CompressedTexImage3DARB = save_CompressedTexImage3DARB; + table->CompressedTexImage2DARB = save_CompressedTexImage2DARB; + table->CompressedTexImage1DARB = save_CompressedTexImage1DARB; + table->CompressedTexSubImage3DARB = save_CompressedTexSubImage3DARB; + table->CompressedTexSubImage2DARB = save_CompressedTexSubImage2DARB; + table->CompressedTexSubImage1DARB = save_CompressedTexSubImage1DARB; + table->GetCompressedTexImageARB = exec_GetCompressedTexImageARB; + + /* GL_EXT_secondary_color */ + table->SecondaryColorPointerEXT = exec_SecondaryColorPointerEXT; + + /* GL_EXT_fog_coord */ + table->FogCoordPointerEXT = exec_FogCoordPointerEXT; +} + + + +/*** + *** Debugging code + ***/ +static const char *enum_string( GLenum k ) +{ + return _mesa_lookup_enum_by_nr( k ); +} + + +/* + * Print the commands in a display list. For debugging only. + * TODO: many commands aren't handled yet. + */ +static void print_list( GLcontext *ctx, FILE *f, GLuint list ) +{ + Node *n; + GLboolean done; + + if (!glIsList(list)) { + fprintf(f,"%u is not a display list ID\n",list); + return; + } + + n = (Node *) _mesa_HashLookup(ctx->Shared->DisplayList, list); + + fprintf( f, "START-LIST %u, address %p\n", list, (void*)n ); + + done = n ? GL_FALSE : GL_TRUE; + while (!done) { + OpCode opcode = n[0].opcode; + GLint i = (GLint) n[0].opcode - (GLint) OPCODE_DRV_0; + + if (i >= 0 && i < (GLint) ctx->listext.nr_opcodes) { + ctx->listext.opcode[i].print(ctx, &n[1]); + n += ctx->listext.opcode[i].size; + } + else { + switch (opcode) { + case OPCODE_ACCUM: + fprintf(f,"accum %s %g\n", enum_string(n[1].e), n[2].f ); + break; + case OPCODE_BITMAP: + fprintf(f,"Bitmap %d %d %g %g %g %g %p\n", n[1].i, n[2].i, + n[3].f, n[4].f, n[5].f, n[6].f, (void *) n[7].data ); + break; + case OPCODE_CALL_LIST: + fprintf(f,"CallList %d\n", (int) n[1].ui ); + break; + case OPCODE_CALL_LIST_OFFSET: + fprintf(f,"CallList %d + offset %u = %u\n", (int) n[1].ui, + ctx->List.ListBase, ctx->List.ListBase + n[1].ui ); + break; + case OPCODE_COLOR_TABLE_PARAMETER_FV: + fprintf(f,"ColorTableParameterfv %s %s %f %f %f %f\n", + enum_string(n[1].e), enum_string(n[2].e), + n[3].f, n[4].f, n[5].f, n[6].f); + break; + case OPCODE_COLOR_TABLE_PARAMETER_IV: + fprintf(f,"ColorTableParameteriv %s %s %d %d %d %d\n", + enum_string(n[1].e), enum_string(n[2].e), + n[3].i, n[4].i, n[5].i, n[6].i); + break; + case OPCODE_DISABLE: + fprintf(f,"Disable %s\n", enum_string(n[1].e)); + break; + case OPCODE_ENABLE: + fprintf(f,"Enable %s\n", enum_string(n[1].e)); + break; + case OPCODE_FRUSTUM: + fprintf(f,"Frustum %g %g %g %g %g %g\n", + n[1].f, n[2].f, n[3].f, n[4].f, n[5].f, n[6].f ); + break; + case OPCODE_LINE_STIPPLE: + fprintf(f,"LineStipple %d %x\n", n[1].i, (int) n[2].us ); + break; + case OPCODE_LOAD_IDENTITY: + fprintf(f,"LoadIdentity\n"); + break; + case OPCODE_LOAD_MATRIX: + fprintf(f,"LoadMatrix\n"); + fprintf(f," %8f %8f %8f %8f\n", n[1].f, n[5].f, n[9].f, n[13].f); + fprintf(f," %8f %8f %8f %8f\n", n[2].f, n[6].f, n[10].f, n[14].f); + fprintf(f," %8f %8f %8f %8f\n", n[3].f, n[7].f, n[11].f, n[15].f); + fprintf(f," %8f %8f %8f %8f\n", n[4].f, n[8].f, n[12].f, n[16].f); + break; + case OPCODE_MULT_MATRIX: + fprintf(f,"MultMatrix (or Rotate)\n"); + fprintf(f," %8f %8f %8f %8f\n", n[1].f, n[5].f, n[9].f, n[13].f); + fprintf(f," %8f %8f %8f %8f\n", n[2].f, n[6].f, n[10].f, n[14].f); + fprintf(f," %8f %8f %8f %8f\n", n[3].f, n[7].f, n[11].f, n[15].f); + fprintf(f," %8f %8f %8f %8f\n", n[4].f, n[8].f, n[12].f, n[16].f); + break; + case OPCODE_ORTHO: + fprintf(f,"Ortho %g %g %g %g %g %g\n", + n[1].f, n[2].f, n[3].f, n[4].f, n[5].f, n[6].f ); + break; + case OPCODE_POP_ATTRIB: + fprintf(f,"PopAttrib\n"); + break; + case OPCODE_POP_MATRIX: + fprintf(f,"PopMatrix\n"); + break; + case OPCODE_POP_NAME: + fprintf(f,"PopName\n"); + break; + case OPCODE_PUSH_ATTRIB: + fprintf(f,"PushAttrib %x\n", n[1].bf ); + break; + case OPCODE_PUSH_MATRIX: + fprintf(f,"PushMatrix\n"); + break; + case OPCODE_PUSH_NAME: + fprintf(f,"PushName %d\n", (int) n[1].ui ); + break; + case OPCODE_RASTER_POS: + fprintf(f,"RasterPos %g %g %g %g\n", n[1].f, n[2].f,n[3].f,n[4].f); + break; + case OPCODE_ROTATE: + fprintf(f,"Rotate %g %g %g %g\n", n[1].f, n[2].f, n[3].f, n[4].f ); + break; + case OPCODE_SCALE: + fprintf(f,"Scale %g %g %g\n", n[1].f, n[2].f, n[3].f ); + break; + case OPCODE_TRANSLATE: + fprintf(f,"Translate %g %g %g\n", n[1].f, n[2].f, n[3].f ); + break; + case OPCODE_BIND_TEXTURE: + fprintf(f,"BindTexture %s %d\n", _mesa_lookup_enum_by_nr(n[1].ui), + n[2].ui); + break; + case OPCODE_SHADE_MODEL: + fprintf(f,"ShadeModel %s\n", _mesa_lookup_enum_by_nr(n[1].ui)); + break; + case OPCODE_MAP1: + fprintf(f,"Map1 %s %.3f %.3f %d %d\n", + _mesa_lookup_enum_by_nr(n[1].ui), + n[2].f, n[3].f, n[4].i, n[5].i); + break; + case OPCODE_MAP2: + fprintf(f,"Map2 %s %.3f %.3f %.3f %.3f %d %d %d %d\n", + _mesa_lookup_enum_by_nr(n[1].ui), + n[2].f, n[3].f, n[4].f, n[5].f, + n[6].i, n[7].i, n[8].i, n[9].i); + break; + case OPCODE_MAPGRID1: + fprintf(f,"MapGrid1 %d %.3f %.3f\n", n[1].i, n[2].f, n[3].f); + break; + case OPCODE_MAPGRID2: + fprintf(f,"MapGrid2 %d %.3f %.3f, %d %.3f %.3f\n", + n[1].i, n[2].f, n[3].f, + n[4].i, n[5].f, n[6].f); + break; + case OPCODE_EVALMESH1: + fprintf(f,"EvalMesh1 %d %d\n", n[1].i, n[2].i); + break; + case OPCODE_EVALMESH2: + fprintf(f,"EvalMesh2 %d %d %d %d\n", + n[1].i, n[2].i, n[3].i, n[4].i); + break; + + /* + * meta opcodes/commands + */ + case OPCODE_ERROR: + fprintf(f,"Error: %s %s\n", enum_string(n[1].e), (const char *)n[2].data ); + break; + case OPCODE_CONTINUE: + fprintf(f,"DISPLAY-LIST-CONTINUE\n"); + n = (Node *) n[1].next; + break; + case OPCODE_END_OF_LIST: + fprintf(f,"END-LIST %u\n", list); + done = GL_TRUE; + break; + default: + if (opcode < 0 || opcode > OPCODE_END_OF_LIST) { + fprintf(f,"ERROR IN DISPLAY LIST: opcode = %d, address = %p\n", + opcode, (void*) n); + return; + } + else { + fprintf(f,"command %d, %u operands\n",opcode,InstSize[opcode]); + } + } + /* increment n to point to next compiled command */ + if (opcode!=OPCODE_CONTINUE) { + n += InstSize[opcode]; + } + } + } +} + + + +/* + * Clients may call this function to help debug display list problems. + * This function is _ONLY_FOR_DEBUGGING_PURPOSES_. It may be removed, + * changed, or break in the future without notice. + */ +void mesa_print_display_list( GLuint list ) +{ + GET_CURRENT_CONTEXT(ctx); + print_list( ctx, stderr, list ); +} Index: dll/opengl/opengl32/mesa/dlist.h =================================================================== --- dll/opengl/opengl32/mesa/dlist.h (revision 0) +++ dll/opengl/opengl32/mesa/dlist.h (working copy) @@ -0,0 +1,108 @@ +/* $Id: dlist.h,v 1.16 2001/03/24 06:01:27 gareth Exp $ */ + +/* + * Mesa 3-D graphics library + * Version: 3.5 + * + * Copyright (C) 1999-2001 Brian Paul 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 + * BRIAN PAUL 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. + */ + + +#ifndef DLIST_H +#define DLIST_H + + +#include "mtypes.h" + + +#define ASSERT_OUTSIDE_SAVE_BEGIN_END_WITH_RETVAL(ctx, retval) \ +do { \ + if (ctx->Driver.CurrentSavePrimitive <= GL_POLYGON || \ + ctx->Driver.CurrentSavePrimitive == PRIM_INSIDE_UNKNOWN_PRIM) { \ + _mesa_compile_error( ctx, GL_INVALID_OPERATION, "begin/end" ); \ + return retval; \ + } \ +} while (0) + +#define ASSERT_OUTSIDE_SAVE_BEGIN_END(ctx) \ +do { \ + if (ctx->Driver.CurrentSavePrimitive <= GL_POLYGON || \ + ctx->Driver.CurrentSavePrimitive == PRIM_INSIDE_UNKNOWN_PRIM) { \ + _mesa_compile_error( ctx, GL_INVALID_OPERATION, "begin/end" ); \ + return; \ + } \ +} while (0) + +#define ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx) \ +do { \ + ASSERT_OUTSIDE_SAVE_BEGIN_END(ctx); \ + FLUSH_VERTICES(ctx, 0); \ +} while (0) + +#define ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH_WITH_RETVAL(ctx, retval)\ +do { \ + ASSERT_OUTSIDE_SAVE_BEGIN_END_WITH_RETVAL(ctx, retval); \ + FLUSH_VERTICES(ctx, 0); \ +} while (0) + + +extern void _mesa_init_lists( void ); + +extern void _mesa_destroy_list( GLcontext *ctx, GLuint list ); + +extern void _mesa_CallList( GLuint list ); + +extern void _mesa_CallLists( GLsizei n, GLenum type, const GLvoid *lists ); + +extern void _mesa_DeleteLists( GLuint list, GLsizei range ); + +extern void _mesa_EndList( void ); + +extern GLuint _mesa_GenLists( GLsizei range ); + +extern GLboolean _mesa_IsList( GLuint list ); + +extern void _mesa_ListBase( GLuint base ); + +extern void _mesa_NewList( GLuint list, GLenum mode ); + +extern void _mesa_init_dlist_table( struct _glapi_table *table, GLuint tableSize ); + +extern void _mesa_save_error( GLcontext *ctx, GLenum error, const char *s ); + + +void * +_mesa_alloc_instruction( GLcontext *ctx, int opcode, GLint sz ); + +int +_mesa_alloc_opcode( GLcontext *ctx, GLuint sz, + void (*execute)( GLcontext *, void * ), + void (*destroy)( GLcontext *, void * ), + void (*print)( GLcontext *, void * ) ); + +extern void _mesa_save_EvalMesh2(GLenum mode, GLint i1, GLint i2, + GLint j1, GLint j2 ); +extern void _mesa_save_EvalMesh1( GLenum mode, GLint i1, GLint i2 ); +extern void _mesa_save_CallLists( GLsizei n, GLenum type, const GLvoid *lists ); +extern void _mesa_save_CallList( GLuint list ); + + + +#endif Index: dll/opengl/opengl32/mesa/drawpix.c =================================================================== --- dll/opengl/opengl32/mesa/drawpix.c (revision 0) +++ dll/opengl/opengl32/mesa/drawpix.c (working copy) @@ -0,0 +1,228 @@ +/* $Id: drawpix.c,v 1.54 2001/06/18 17:26:08 brianp Exp $ */ + +/* + * Mesa 3-D graphics library + * Version: 3.5 + * + * Copyright (C) 1999-2001 Brian Paul 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 + * BRIAN PAUL 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. + */ + + +#ifdef PC_HEADER +#include "all.h" +#else +#include "glheader.h" +#include "colormac.h" +#include "context.h" +#include "drawpix.h" +#include "feedback.h" +#include "macros.h" +#include "mem.h" +#include "mmath.h" +#include "state.h" +#include "mtypes.h" +#endif + + + + + +/* + * Execute glDrawPixels + */ +void +_mesa_DrawPixels( GLsizei width, GLsizei height, + GLenum format, GLenum type, const GLvoid *pixels ) +{ + GET_CURRENT_CONTEXT(ctx); + ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx); + + if (ctx->RenderMode==GL_RENDER) { + GLint x, y; + if (!pixels || !ctx->Current.RasterPosValid) { + return; + } + + if (ctx->NewState) { + _mesa_update_state(ctx); + } + + x = IROUND(ctx->Current.RasterPos[0]); + y = IROUND(ctx->Current.RasterPos[1]); + + ctx->OcclusionResult = GL_TRUE; + ctx->Driver.DrawPixels(ctx, x, y, width, height, format, type, + &ctx->Unpack, pixels); + } + else if (ctx->RenderMode==GL_FEEDBACK) { + if (ctx->Current.RasterPosValid) { + GLfloat texcoord[4], invq; + + FLUSH_CURRENT(ctx, 0); + invq = 1.0F / ctx->Current.Texcoord[0][3]; + texcoord[0] = ctx->Current.Texcoord[0][0] * invq; + texcoord[1] = ctx->Current.Texcoord[0][1] * invq; + texcoord[2] = ctx->Current.Texcoord[0][2] * invq; + texcoord[3] = ctx->Current.Texcoord[0][3]; + FEEDBACK_TOKEN( ctx, (GLfloat) (GLint) GL_DRAW_PIXEL_TOKEN ); + _mesa_feedback_vertex( ctx, + ctx->Current.RasterPos, + ctx->Current.Color, + ctx->Current.Index, + texcoord ); + } + } + else if (ctx->RenderMode==GL_SELECT) { + if (ctx->Current.RasterPosValid) { + _mesa_update_hitflag( ctx, ctx->Current.RasterPos[2] ); + } + } +} + + + +void +_mesa_ReadPixels( GLint x, GLint y, GLsizei width, GLsizei height, + GLenum format, GLenum type, GLvoid *pixels ) +{ + GET_CURRENT_CONTEXT(ctx); + ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx); + + if (!pixels) { + _mesa_error( ctx, GL_INVALID_VALUE, "glReadPixels(pixels)" ); + return; + } + + if (ctx->NewState) + _mesa_update_state(ctx); + + ctx->Driver.ReadPixels(ctx, x, y, width, height, + format, type, &ctx->Pack, pixels); + +} + + + +void +_mesa_CopyPixels( GLint srcx, GLint srcy, GLsizei width, GLsizei height, + GLenum type ) +{ + GET_CURRENT_CONTEXT(ctx); + GLint destx, desty; + ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx); + + if (width < 0 || height < 0) { + _mesa_error( ctx, GL_INVALID_VALUE, "glCopyPixels" ); + return; + } + + if (ctx->NewState) { + _mesa_update_state(ctx); + } + + if (ctx->RenderMode==GL_RENDER) { + /* Destination of copy: */ + if (!ctx->Current.RasterPosValid) { + return; + } + destx = IROUND(ctx->Current.RasterPos[0]); + desty = IROUND(ctx->Current.RasterPos[1]); + + ctx->OcclusionResult = GL_TRUE; + + ctx->Driver.CopyPixels( ctx, srcx, srcy, width, height, destx, desty, + type ); + } + else if (ctx->RenderMode == GL_FEEDBACK) { + FLUSH_CURRENT( ctx, 0 ); + FEEDBACK_TOKEN( ctx, (GLfloat) (GLint) GL_COPY_PIXEL_TOKEN ); + _mesa_feedback_vertex( ctx, + ctx->Current.RasterPos, + ctx->Current.Color, + ctx->Current.Index, + ctx->Current.Texcoord[0] ); + } + else if (ctx->RenderMode == GL_SELECT) { + _mesa_update_hitflag( ctx, ctx->Current.RasterPos[2] ); + } +} + + + +void +_mesa_Bitmap( GLsizei width, GLsizei height, + GLfloat xorig, GLfloat yorig, GLfloat xmove, GLfloat ymove, + const GLubyte *bitmap ) +{ + GET_CURRENT_CONTEXT(ctx); + ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx); + + + /* Error checking */ + if (width < 0 || height < 0) { + _mesa_error( ctx, GL_INVALID_VALUE, "glBitmap" ); + return; + } + + if (ctx->Current.RasterPosValid == GL_FALSE) { + return; /* do nothing */ + } + + if (ctx->RenderMode==GL_RENDER) { + if (bitmap) { + GLint x = (GLint) ( (ctx->Current.RasterPos[0] - xorig) + 0.0F ); + GLint y = (GLint) ( (ctx->Current.RasterPos[1] - yorig) + 0.0F ); + + if (ctx->NewState) { + _mesa_update_state(ctx); + } + + ctx->OcclusionResult = GL_TRUE; + ctx->Driver.Bitmap( ctx, x, y, width, height, &ctx->Unpack, bitmap ); + } + } + else if (ctx->RenderMode==GL_FEEDBACK) { + GLfloat color[4], texcoord[4], invq; + + color[0] = ctx->Current.RasterColor[0]; + color[1] = ctx->Current.RasterColor[1]; + color[2] = ctx->Current.RasterColor[2]; + color[3] = ctx->Current.RasterColor[3]; + if (ctx->Current.Texcoord[0][3] == 0.0) + invq = 1.0F; + else + invq = 1.0F / ctx->Current.RasterTexCoord[3]; + texcoord[0] = ctx->Current.RasterTexCoord[0] * invq; + texcoord[1] = ctx->Current.RasterTexCoord[1] * invq; + texcoord[2] = ctx->Current.RasterTexCoord[2] * invq; + texcoord[3] = ctx->Current.RasterTexCoord[3]; + FEEDBACK_TOKEN( ctx, (GLfloat) (GLint) GL_BITMAP_TOKEN ); + _mesa_feedback_vertex( ctx, + ctx->Current.RasterPos, + color, ctx->Current.RasterIndex, texcoord ); + } + else if (ctx->RenderMode==GL_SELECT) { + /* Bitmaps don't generate selection hits. See appendix B of 1.1 spec. */ + } + + /* update raster position */ + ctx->Current.RasterPos[0] += xmove; + ctx->Current.RasterPos[1] += ymove; +} Index: dll/opengl/opengl32/mesa/drawpix.h =================================================================== --- dll/opengl/opengl32/mesa/drawpix.h (revision 0) +++ dll/opengl/opengl32/mesa/drawpix.h (working copy) @@ -0,0 +1,56 @@ +/* $Id: drawpix.h,v 1.7 2001/06/18 17:26:08 brianp Exp $ */ + +/* + * Mesa 3-D graphics library + * Version: 3.5 + * + * Copyright (C) 1999-2001 Brian Paul 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 + * BRIAN PAUL 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. + */ + + +#ifndef DRAWPIXELS_H +#define DRAWPIXELS_H + + +#include "mtypes.h" + + +extern void +_mesa_DrawPixels( GLsizei width, GLsizei height, + GLenum format, GLenum type, const GLvoid *pixels ); + + +extern void +_mesa_ReadPixels( GLint x, GLint y, GLsizei width, GLsizei height, + GLenum format, GLenum type, GLvoid *pixels ); + + +extern void +_mesa_CopyPixels( GLint srcx, GLint srcy, GLsizei width, GLsizei height, + GLenum type ); + + +extern void +_mesa_Bitmap( GLsizei width, GLsizei height, + GLfloat xorig, GLfloat yorig, GLfloat xmove, GLfloat ymove, + const GLubyte *bitmap ); + + +#endif Index: dll/opengl/opengl32/mesa/enable.c =================================================================== --- dll/opengl/opengl32/mesa/enable.c (revision 0) +++ dll/opengl/opengl32/mesa/enable.c (working copy) @@ -0,0 +1,1087 @@ +/* $Id: enable.c,v 1.49 2001/05/29 15:23:48 brianp Exp $ */ + +/* + * Mesa 3-D graphics library + * Version: 3.5 + * + * Copyright (C) 1999-2001 Brian Paul 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 + * BRIAN PAUL 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. + */ + + +#ifdef PC_HEADER +#include "all.h" +#else +#include "glheader.h" +#include "context.h" +#include "enable.h" +#include "light.h" +#include "macros.h" +#include "mmath.h" +#include "simple_list.h" +#include "mtypes.h" +#include "enums.h" + +#include "math/m_matrix.h" +#include "math/m_xform.h" + +#endif + + +static void +client_state( GLcontext *ctx, GLenum cap, GLboolean state ) +{ + GLuint flag; + GLboolean *var; + + switch (cap) { + case GL_VERTEX_ARRAY: + var = &ctx->Array.Vertex.Enabled; + flag = _NEW_ARRAY_VERTEX; + break; + case GL_NORMAL_ARRAY: + var = &ctx->Array.Normal.Enabled; + flag = _NEW_ARRAY_NORMAL; + break; + case GL_COLOR_ARRAY: + var = &ctx->Array.Color.Enabled; + flag = _NEW_ARRAY_COLOR; + break; + case GL_INDEX_ARRAY: + var = &ctx->Array.Index.Enabled; + flag = _NEW_ARRAY_INDEX; + break; + case GL_TEXTURE_COORD_ARRAY: + var = &ctx->Array.TexCoord[ctx->Array.ActiveTexture].Enabled; + flag = _NEW_ARRAY_TEXCOORD(ctx->Array.ActiveTexture); + break; + case GL_EDGE_FLAG_ARRAY: + var = &ctx->Array.EdgeFlag.Enabled; + flag = _NEW_ARRAY_EDGEFLAG; + break; + case GL_FOG_COORDINATE_ARRAY_EXT: + var = &ctx->Array.FogCoord.Enabled; + flag = _NEW_ARRAY_FOGCOORD; + break; + case GL_SECONDARY_COLOR_ARRAY_EXT: + var = &ctx->Array.SecondaryColor.Enabled; + flag = _NEW_ARRAY_SECONDARYCOLOR; + break; + default: + _mesa_error( ctx, GL_INVALID_ENUM, "glEnable/DisableClientState" ); + return; + } + + if (*var == flag) + return; + + FLUSH_VERTICES(ctx, _NEW_ARRAY); + ctx->Array.NewState |= flag; + *var = state; + + if (state) + ctx->Array._Enabled |= flag; + else + ctx->Array._Enabled &= ~flag; + + if (ctx->Driver.Enable) { + (*ctx->Driver.Enable)( ctx, cap, state ); + } +} + + + +void +_mesa_EnableClientState( GLenum cap ) +{ + GET_CURRENT_CONTEXT(ctx); + ASSERT_OUTSIDE_BEGIN_END(ctx); + client_state( ctx, cap, GL_TRUE ); +} + + + +void +_mesa_DisableClientState( GLenum cap ) +{ + GET_CURRENT_CONTEXT(ctx); + ASSERT_OUTSIDE_BEGIN_END(ctx); + client_state( ctx, cap, GL_FALSE ); +} + + +/* + * Perform glEnable and glDisable calls. + */ +void _mesa_set_enable( GLcontext *ctx, GLenum cap, GLboolean state ) +{ + if (MESA_VERBOSE & VERBOSE_API) + fprintf(stderr, "%s %s (newstate is %x)\n", + state ? "glEnable" : "glDisable", + _mesa_lookup_enum_by_nr(cap), + ctx->NewState); + + switch (cap) { + case GL_ALPHA_TEST: + if (ctx->Color.AlphaEnabled == state) + return; + FLUSH_VERTICES(ctx, _NEW_COLOR); + ctx->Color.AlphaEnabled = state; + break; + case GL_AUTO_NORMAL: + if (ctx->Eval.AutoNormal == state) + return; + FLUSH_VERTICES(ctx, _NEW_EVAL); + ctx->Eval.AutoNormal = state; + break; + case GL_BLEND: + if (ctx->Color.BlendEnabled == state) + return; + + FLUSH_VERTICES(ctx, _NEW_COLOR); + ctx->Color.BlendEnabled = state; + /* The following needed to accomodate 1.0 RGB logic op blending */ + ctx->Color.ColorLogicOpEnabled = + (ctx->Color.BlendEquation == GL_LOGIC_OP && state); + break; + case GL_CLIP_PLANE0: + case GL_CLIP_PLANE1: + case GL_CLIP_PLANE2: + case GL_CLIP_PLANE3: + case GL_CLIP_PLANE4: + case GL_CLIP_PLANE5: { + GLuint p = cap-GL_CLIP_PLANE0; + + if (ctx->Transform.ClipEnabled[p] == state) + return; + + FLUSH_VERTICES(ctx, _NEW_TRANSFORM); + ctx->Transform.ClipEnabled[p] = state; + + if (state) { + ctx->Transform._AnyClip++; + + if (ctx->ProjectionMatrix.flags & MAT_DIRTY) { + _math_matrix_analyse( &ctx->ProjectionMatrix ); + } + + /* This derived state also calculated in clip.c and + * from _mesa_update_state() on changes to EyeUserPlane + * and ctx->ProjectionMatrix respectively. + */ + _mesa_transform_vector( ctx->Transform._ClipUserPlane[p], + ctx->Transform.EyeUserPlane[p], + ctx->ProjectionMatrix.inv ); + } + } + break; + case GL_COLOR_MATERIAL: + if (ctx->Light.ColorMaterialEnabled == state) + return; + FLUSH_VERTICES(ctx, _NEW_LIGHT); + ctx->Light.ColorMaterialEnabled = state; + if (state) { + FLUSH_CURRENT(ctx, 0); + _mesa_update_color_material( ctx, ctx->Current.Color ); + } + break; + case GL_CULL_FACE: + if (ctx->Polygon.CullFlag == state) + return; + FLUSH_VERTICES(ctx, _NEW_POLYGON); + ctx->Polygon.CullFlag = state; + break; + case GL_DEPTH_TEST: + if (state && ctx->Visual.depthBits==0) { + _mesa_warning(ctx,"glEnable(GL_DEPTH_TEST) but no depth buffer"); + return; + } + if (ctx->Depth.Test==state) + return; + FLUSH_VERTICES(ctx, _NEW_DEPTH); + ctx->Depth.Test = state; + break; + case GL_DITHER: + if (ctx->NoDither) { + state = GL_FALSE; /* MESA_NO_DITHER env var */ + } + if (ctx->Color.DitherFlag==state) + return; + FLUSH_VERTICES(ctx, _NEW_COLOR); + ctx->Color.DitherFlag = state; + break; + case GL_FOG: + if (ctx->Fog.Enabled==state) + return; + FLUSH_VERTICES(ctx, _NEW_FOG); + ctx->Fog.Enabled = state; + break; + case GL_HISTOGRAM: + if (!ctx->Extensions.EXT_histogram && !ctx->Extensions.ARB_imaging) { + _mesa_error(ctx, GL_INVALID_ENUM, "glEnable(GL_HISTOGRAM)"); + return; + } + if (ctx->Pixel.HistogramEnabled == state) + return; + FLUSH_VERTICES(ctx, _NEW_PIXEL); + ctx->Pixel.HistogramEnabled = state; + break; + case GL_LIGHT0: + case GL_LIGHT1: + case GL_LIGHT2: + case GL_LIGHT3: + case GL_LIGHT4: + case GL_LIGHT5: + case GL_LIGHT6: + case GL_LIGHT7: + if (ctx->Light.Light[cap-GL_LIGHT0].Enabled == state) + return; + FLUSH_VERTICES(ctx, _NEW_LIGHT); + ctx->Light.Light[cap-GL_LIGHT0].Enabled = state; + if (state) { + insert_at_tail(&ctx->Light.EnabledList, + &ctx->Light.Light[cap-GL_LIGHT0]); + } + else { + remove_from_list(&ctx->Light.Light[cap-GL_LIGHT0]); + } + break; + case GL_LIGHTING: + if (ctx->Light.Enabled == state) + return; + FLUSH_VERTICES(ctx, _NEW_LIGHT); + ctx->Light.Enabled = state; + + if ((ctx->Light.Enabled && + ctx->Light.Model.ColorControl==GL_SEPARATE_SPECULAR_COLOR) + || ctx->Fog.ColorSumEnabled) + ctx->_TriangleCaps |= DD_SEPARATE_SPECULAR; + else + ctx->_TriangleCaps &= ~DD_SEPARATE_SPECULAR; + + break; + case GL_LINE_SMOOTH: + if (ctx->Line.SmoothFlag == state) + return; + FLUSH_VERTICES(ctx, _NEW_LINE); + ctx->Line.SmoothFlag = state; + ctx->_TriangleCaps ^= DD_LINE_SMOOTH; + break; + case GL_LINE_STIPPLE: + if (ctx->Line.StippleFlag == state) + return; + FLUSH_VERTICES(ctx, _NEW_LINE); + ctx->Line.StippleFlag = state; + ctx->_TriangleCaps ^= DD_LINE_STIPPLE; + break; + case GL_INDEX_LOGIC_OP: + if (ctx->Color.IndexLogicOpEnabled == state) + return; + FLUSH_VERTICES(ctx, _NEW_COLOR); + ctx->Color.IndexLogicOpEnabled = state; + break; + case GL_COLOR_LOGIC_OP: + if (ctx->Color.ColorLogicOpEnabled == state) + return; + FLUSH_VERTICES(ctx, _NEW_COLOR); + ctx->Color.ColorLogicOpEnabled = state; + break; + case GL_MAP1_COLOR_4: + if (ctx->Eval.Map1Color4 == state) + return; + FLUSH_VERTICES(ctx, _NEW_EVAL); + ctx->Eval.Map1Color4 = state; + break; + case GL_MAP1_INDEX: + if (ctx->Eval.Map1Index == state) + return; + FLUSH_VERTICES(ctx, _NEW_EVAL); + ctx->Eval.Map1Index = state; + break; + case GL_MAP1_NORMAL: + if (ctx->Eval.Map1Normal == state) + return; + FLUSH_VERTICES(ctx, _NEW_EVAL); + ctx->Eval.Map1Normal = state; + break; + case GL_MAP1_TEXTURE_COORD_1: + if (ctx->Eval.Map1TextureCoord1 == state) + return; + FLUSH_VERTICES(ctx, _NEW_EVAL); + ctx->Eval.Map1TextureCoord1 = state; + break; + case GL_MAP1_TEXTURE_COORD_2: + if (ctx->Eval.Map1TextureCoord2 == state) + return; + FLUSH_VERTICES(ctx, _NEW_EVAL); + ctx->Eval.Map1TextureCoord2 = state; + break; + case GL_MAP1_TEXTURE_COORD_3: + if (ctx->Eval.Map1TextureCoord3 == state) + return; + FLUSH_VERTICES(ctx, _NEW_EVAL); + ctx->Eval.Map1TextureCoord3 = state; + break; + case GL_MAP1_TEXTURE_COORD_4: + if (ctx->Eval.Map1TextureCoord4 == state) + return; + FLUSH_VERTICES(ctx, _NEW_EVAL); + ctx->Eval.Map1TextureCoord4 = state; + break; + case GL_MAP1_VERTEX_3: + if (ctx->Eval.Map1Vertex3 == state) + return; + FLUSH_VERTICES(ctx, _NEW_EVAL); + ctx->Eval.Map1Vertex3 = state; + break; + case GL_MAP1_VERTEX_4: + if (ctx->Eval.Map1Vertex4 == state) + return; + FLUSH_VERTICES(ctx, _NEW_EVAL); + ctx->Eval.Map1Vertex4 = state; + break; + case GL_MAP2_COLOR_4: + if (ctx->Eval.Map2Color4 == state) + return; + FLUSH_VERTICES(ctx, _NEW_EVAL); + ctx->Eval.Map2Color4 = state; + break; + case GL_MAP2_INDEX: + if (ctx->Eval.Map2Index == state) + return; + FLUSH_VERTICES(ctx, _NEW_EVAL); + ctx->Eval.Map2Index = state; + break; + case GL_MAP2_NORMAL: + if (ctx->Eval.Map2Normal == state) + return; + FLUSH_VERTICES(ctx, _NEW_EVAL); + ctx->Eval.Map2Normal = state; + break; + case GL_MAP2_TEXTURE_COORD_1: + if (ctx->Eval.Map2TextureCoord1 == state) + return; + FLUSH_VERTICES(ctx, _NEW_EVAL); + ctx->Eval.Map2TextureCoord1 = state; + break; + case GL_MAP2_TEXTURE_COORD_2: + if (ctx->Eval.Map2TextureCoord2 == state) + return; + FLUSH_VERTICES(ctx, _NEW_EVAL); + ctx->Eval.Map2TextureCoord2 = state; + break; + case GL_MAP2_TEXTURE_COORD_3: + if (ctx->Eval.Map2TextureCoord3 == state) + return; + FLUSH_VERTICES(ctx, _NEW_EVAL); + ctx->Eval.Map2TextureCoord3 = state; + break; + case GL_MAP2_TEXTURE_COORD_4: + if (ctx->Eval.Map2TextureCoord4 == state) + return; + FLUSH_VERTICES(ctx, _NEW_EVAL); + ctx->Eval.Map2TextureCoord4 = state; + break; + case GL_MAP2_VERTEX_3: + if (ctx->Eval.Map2Vertex3 == state) + return; + FLUSH_VERTICES(ctx, _NEW_EVAL); + ctx->Eval.Map2Vertex3 = state; + break; + case GL_MAP2_VERTEX_4: + if (ctx->Eval.Map2Vertex4 == state) + return; + FLUSH_VERTICES(ctx, _NEW_EVAL); + ctx->Eval.Map2Vertex4 = state; + break; + case GL_MINMAX: + if (ctx->Pixel.MinMaxEnabled == state) + return; + FLUSH_VERTICES(ctx, _NEW_PIXEL); + ctx->Pixel.MinMaxEnabled = state; + break; + case GL_NORMALIZE: + if (ctx->Transform.Normalize == state) + return; + FLUSH_VERTICES(ctx, _NEW_TRANSFORM); + ctx->Transform.Normalize = state; + break; + case GL_POINT_SMOOTH: + if (ctx->Point.SmoothFlag==state) + return; + FLUSH_VERTICES(ctx, _NEW_POINT); + ctx->Point.SmoothFlag = state; + ctx->_TriangleCaps ^= DD_POINT_SMOOTH; + break; + case GL_POLYGON_SMOOTH: + if (ctx->Polygon.SmoothFlag==state) + return; + FLUSH_VERTICES(ctx, _NEW_POLYGON); + ctx->Polygon.SmoothFlag = state; + ctx->_TriangleCaps ^= DD_TRI_SMOOTH; + break; + case GL_POLYGON_STIPPLE: + if (ctx->Polygon.StippleFlag==state) + return; + FLUSH_VERTICES(ctx, _NEW_POLYGON); + ctx->Polygon.StippleFlag = state; + ctx->_TriangleCaps ^= DD_TRI_STIPPLE; + break; + case GL_POLYGON_OFFSET_POINT: + if (ctx->Polygon.OffsetPoint==state) + return; + FLUSH_VERTICES(ctx, _NEW_POLYGON); + ctx->Polygon.OffsetPoint = state; + break; + case GL_POLYGON_OFFSET_LINE: + if (ctx->Polygon.OffsetLine==state) + return; + FLUSH_VERTICES(ctx, _NEW_POLYGON); + ctx->Polygon.OffsetLine = state; + break; + case GL_POLYGON_OFFSET_FILL: + /*case GL_POLYGON_OFFSET_EXT:*/ + if (ctx->Polygon.OffsetFill==state) + return; + FLUSH_VERTICES(ctx, _NEW_POLYGON); + ctx->Polygon.OffsetFill = state; + break; + case GL_RESCALE_NORMAL_EXT: + if (ctx->Transform.RescaleNormals == state) + return; + FLUSH_VERTICES(ctx, _NEW_TRANSFORM); + ctx->Transform.RescaleNormals = state; + break; + case GL_SCISSOR_TEST: + if (ctx->Scissor.Enabled==state) + return; + FLUSH_VERTICES(ctx, _NEW_SCISSOR); + ctx->Scissor.Enabled = state; + break; + case GL_SHARED_TEXTURE_PALETTE_EXT: + if (ctx->Texture.SharedPalette == state) + return; + FLUSH_VERTICES(ctx, _NEW_TEXTURE); + ctx->Texture.SharedPalette = state; + break; + case GL_STENCIL_TEST: + if (state && ctx->Visual.stencilBits==0) { + _mesa_warning(ctx, "glEnable(GL_STENCIL_TEST) but no stencil buffer"); + return; + } + if (ctx->Stencil.Enabled==state) + return; + FLUSH_VERTICES(ctx, _NEW_STENCIL); + ctx->Stencil.Enabled = state; + break; + case GL_TEXTURE_1D: { + const GLuint curr = ctx->Texture.CurrentUnit; + struct gl_texture_unit *texUnit = &ctx->Texture.Unit[curr]; + GLuint newenabled = texUnit->Enabled & ~TEXTURE0_1D; + if (state) + newenabled |= TEXTURE0_1D; + if (!ctx->Visual.rgbMode || texUnit->Enabled == newenabled) + return; + FLUSH_VERTICES(ctx, _NEW_TEXTURE); + texUnit->Enabled = newenabled; + break; + } + case GL_TEXTURE_2D: { + const GLuint curr = ctx->Texture.CurrentUnit; + struct gl_texture_unit *texUnit = &ctx->Texture.Unit[curr]; + GLuint newenabled = texUnit->Enabled & ~TEXTURE0_2D; + if (state) + newenabled |= TEXTURE0_2D; + if (!ctx->Visual.rgbMode || texUnit->Enabled == newenabled) + return; + FLUSH_VERTICES(ctx, _NEW_TEXTURE); + texUnit->Enabled = newenabled; + break; + } + case GL_TEXTURE_3D: { + const GLuint curr = ctx->Texture.CurrentUnit; + struct gl_texture_unit *texUnit = &ctx->Texture.Unit[curr]; + GLuint newenabled = texUnit->Enabled & ~TEXTURE0_3D; + if (state) + newenabled |= TEXTURE0_3D; + if (!ctx->Visual.rgbMode || texUnit->Enabled == newenabled) + return; + FLUSH_VERTICES(ctx, _NEW_TEXTURE); + texUnit->Enabled = newenabled; + break; + } + case GL_TEXTURE_GEN_Q: { + GLuint unit = ctx->Texture.CurrentUnit; + struct gl_texture_unit *texUnit = &ctx->Texture.Unit[unit]; + GLuint newenabled = texUnit->TexGenEnabled & ~Q_BIT; + if (state) + newenabled |= Q_BIT; + if (texUnit->TexGenEnabled == newenabled) + return; + FLUSH_VERTICES(ctx, _NEW_TEXTURE); + texUnit->TexGenEnabled = newenabled; + break; + } + case GL_TEXTURE_GEN_R: { + GLuint unit = ctx->Texture.CurrentUnit; + struct gl_texture_unit *texUnit = &ctx->Texture.Unit[unit]; + GLuint newenabled = texUnit->TexGenEnabled & ~R_BIT; + if (state) + newenabled |= R_BIT; + if (texUnit->TexGenEnabled == newenabled) + return; + FLUSH_VERTICES(ctx, _NEW_TEXTURE); + texUnit->TexGenEnabled = newenabled; + break; + } + break; + case GL_TEXTURE_GEN_S: { + GLuint unit = ctx->Texture.CurrentUnit; + struct gl_texture_unit *texUnit = &ctx->Texture.Unit[unit]; + GLuint newenabled = texUnit->TexGenEnabled & ~S_BIT; + if (state) + newenabled |= S_BIT; + if (texUnit->TexGenEnabled == newenabled) + return; + FLUSH_VERTICES(ctx, _NEW_TEXTURE); + texUnit->TexGenEnabled = newenabled; + break; + } + break; + case GL_TEXTURE_GEN_T: { + GLuint unit = ctx->Texture.CurrentUnit; + struct gl_texture_unit *texUnit = &ctx->Texture.Unit[unit]; + GLuint newenabled = texUnit->TexGenEnabled & ~T_BIT; + if (state) + newenabled |= T_BIT; + if (texUnit->TexGenEnabled == newenabled) + return; + FLUSH_VERTICES(ctx, _NEW_TEXTURE); + texUnit->TexGenEnabled = newenabled; + break; + } + break; + + /* + * CLIENT STATE!!! + */ + case GL_VERTEX_ARRAY: + case GL_NORMAL_ARRAY: + case GL_COLOR_ARRAY: + case GL_INDEX_ARRAY: + case GL_TEXTURE_COORD_ARRAY: + case GL_EDGE_FLAG_ARRAY: + case GL_FOG_COORDINATE_ARRAY_EXT: + case GL_SECONDARY_COLOR_ARRAY_EXT: + client_state( ctx, cap, state ); + return; + + /* GL_HP_occlusion_test */ + case GL_OCCLUSION_TEST_HP: + if (!ctx->Extensions.HP_occlusion_test) { + _mesa_error( ctx, GL_INVALID_ENUM, state ? "glEnable": "glDisable" ); + return; + } + if (ctx->Depth.OcclusionTest == state) + return; + FLUSH_VERTICES(ctx, _NEW_DEPTH); + ctx->Depth.OcclusionTest = state; + if (state) + ctx->OcclusionResult = ctx->OcclusionResultSaved; + else + ctx->OcclusionResultSaved = ctx->OcclusionResult; + break; + + /* GL_SGIS_pixel_texture */ + case GL_PIXEL_TEXTURE_SGIS: + if (!ctx->Extensions.SGIS_pixel_texture) { + _mesa_error( ctx, GL_INVALID_ENUM, state ? "glEnable": "glDisable" ); + return; + } + if (ctx->Pixel.PixelTextureEnabled == state) + return; + FLUSH_VERTICES(ctx, _NEW_PIXEL); + ctx->Pixel.PixelTextureEnabled = state; + break; + + /* GL_SGIX_pixel_texture */ + case GL_PIXEL_TEX_GEN_SGIX: + if (!ctx->Extensions.SGIX_pixel_texture) { + _mesa_error( ctx, GL_INVALID_ENUM, state ? "glEnable": "glDisable" ); + return; + } + if (ctx->Pixel.PixelTextureEnabled == state) + return; + FLUSH_VERTICES(ctx, _NEW_PIXEL); + ctx->Pixel.PixelTextureEnabled = state; + break; + + /* GL_SGI_color_table */ + case GL_COLOR_TABLE_SGI: + if (!ctx->Extensions.SGI_color_table && !ctx->Extensions.ARB_imaging) { + _mesa_error( ctx, GL_INVALID_ENUM, state ? "glEnable": "glDisable" ); + return; + } + if (ctx->Pixel.ColorTableEnabled == state) + return; + FLUSH_VERTICES(ctx, _NEW_PIXEL); + ctx->Pixel.ColorTableEnabled = state; + break; + case GL_POST_CONVOLUTION_COLOR_TABLE_SGI: + if (!ctx->Extensions.SGI_color_table && !ctx->Extensions.ARB_imaging) { + _mesa_error( ctx, GL_INVALID_ENUM, state ? "glEnable": "glDisable" ); + return; + } + if (ctx->Pixel.PostConvolutionColorTableEnabled == state) + return; + FLUSH_VERTICES(ctx, _NEW_PIXEL); + ctx->Pixel.PostConvolutionColorTableEnabled = state; + break; + case GL_POST_COLOR_MATRIX_COLOR_TABLE_SGI: + if (!ctx->Extensions.SGI_color_table && !ctx->Extensions.ARB_imaging) { + _mesa_error( ctx, GL_INVALID_ENUM, state ? "glEnable": "glDisable" ); + return; + } + if (ctx->Pixel.PostColorMatrixColorTableEnabled == state) + return; + FLUSH_VERTICES(ctx, _NEW_PIXEL); + ctx->Pixel.PostColorMatrixColorTableEnabled = state; + break; + + /* GL_EXT_convolution */ + case GL_CONVOLUTION_1D: + if (!ctx->Extensions.EXT_convolution && !ctx->Extensions.ARB_imaging) { + _mesa_error(ctx, GL_INVALID_ENUM, state ? "glEnable" : "glDisable"); + return; + } + if (ctx->Pixel.Convolution1DEnabled == state) + return; + FLUSH_VERTICES(ctx, _NEW_PIXEL); + ctx->Pixel.Convolution1DEnabled = state; + break; + case GL_CONVOLUTION_2D: + if (!ctx->Extensions.EXT_convolution && !ctx->Extensions.ARB_imaging) { + _mesa_error(ctx, GL_INVALID_ENUM, state ? "glEnable" : "glDisable"); + return; + } + if (ctx->Pixel.Convolution2DEnabled == state) + return; + FLUSH_VERTICES(ctx, _NEW_PIXEL); + ctx->Pixel.Convolution2DEnabled = state; + break; + case GL_SEPARABLE_2D: + if (!ctx->Extensions.EXT_convolution && !ctx->Extensions.ARB_imaging) { + _mesa_error(ctx, GL_INVALID_ENUM, state ? "glEnable" : "glDisable"); + return; + } + if (ctx->Pixel.Separable2DEnabled == state) + return; + FLUSH_VERTICES(ctx, _NEW_PIXEL); + ctx->Pixel.Separable2DEnabled = state; + break; + + /* GL_ARB_texture_cube_map */ + case GL_TEXTURE_CUBE_MAP_ARB: { + const GLuint curr = ctx->Texture.CurrentUnit; + struct gl_texture_unit *texUnit = &ctx->Texture.Unit[curr]; + GLuint newenabled = texUnit->Enabled & ~TEXTURE0_CUBE; + if (state) + newenabled |= TEXTURE0_CUBE; + if (!ctx->Extensions.ARB_texture_cube_map) { + _mesa_error(ctx, GL_INVALID_ENUM, state ? "glEnable" : "glDisable"); + return; + } + if (!ctx->Visual.rgbMode || texUnit->Enabled == newenabled) + return; + FLUSH_VERTICES(ctx, _NEW_TEXTURE); + texUnit->Enabled = newenabled; + break; + } + /* GL_EXT_secondary_color */ + case GL_COLOR_SUM_EXT: + if (!ctx->Extensions.EXT_secondary_color) { + _mesa_error(ctx, GL_INVALID_ENUM, state ? "glEnable" : "glDisable"); + return; + } + if (ctx->Fog.ColorSumEnabled == state) + return; + FLUSH_VERTICES(ctx, _NEW_FOG); + ctx->Fog.ColorSumEnabled = state; + + if ((ctx->Light.Enabled && + ctx->Light.Model.ColorControl==GL_SEPARATE_SPECULAR_COLOR) + || ctx->Fog.ColorSumEnabled) + ctx->_TriangleCaps |= DD_SEPARATE_SPECULAR; + else + ctx->_TriangleCaps &= ~DD_SEPARATE_SPECULAR; + + break; + + /* GL_ARB_multisample */ + case GL_MULTISAMPLE_ARB: + if (!ctx->Extensions.ARB_multisample) { + _mesa_error(ctx, GL_INVALID_ENUM, state ? "glEnable" : "glDisable"); + return; + } + if (ctx->Multisample.Enabled == state) + return; + FLUSH_VERTICES(ctx, _NEW_MULTISAMPLE); + ctx->Multisample.Enabled = state; + ctx->NewState |= _NEW_MULTISAMPLE; + break; + case GL_SAMPLE_ALPHA_TO_COVERAGE_ARB: + if (!ctx->Extensions.ARB_multisample) { + _mesa_error(ctx, GL_INVALID_ENUM, state ? "glEnable" : "glDisable"); + return; + } + if (ctx->Multisample.SampleAlphaToCoverage == state) + return; + FLUSH_VERTICES(ctx, _NEW_MULTISAMPLE); + ctx->Multisample.SampleAlphaToCoverage = state; + ctx->NewState |= _NEW_MULTISAMPLE; + break; + case GL_SAMPLE_ALPHA_TO_ONE_ARB: + if (!ctx->Extensions.ARB_multisample) { + _mesa_error(ctx, GL_INVALID_ENUM, state ? "glEnable" : "glDisable"); + return; + } + if (ctx->Multisample.SampleAlphaToOne == state) + return; + FLUSH_VERTICES(ctx, _NEW_MULTISAMPLE); + ctx->Multisample.SampleAlphaToOne = state; + ctx->NewState |= _NEW_MULTISAMPLE; + break; + case GL_SAMPLE_COVERAGE_ARB: + if (!ctx->Extensions.ARB_multisample) { + _mesa_error(ctx, GL_INVALID_ENUM, state ? "glEnable" : "glDisable"); + return; + } + if (ctx->Multisample.SampleCoverage == state) + return; + FLUSH_VERTICES(ctx, _NEW_MULTISAMPLE); + ctx->Multisample.SampleCoverage = state; + ctx->NewState |= _NEW_MULTISAMPLE; + break; + case GL_SAMPLE_COVERAGE_INVERT_ARB: + if (!ctx->Extensions.ARB_multisample) { + _mesa_error(ctx, GL_INVALID_ENUM, state ? "glEnable" : "glDisable"); + return; + } + if (ctx->Multisample.SampleCoverageInvert == state) + return; + FLUSH_VERTICES(ctx, _NEW_MULTISAMPLE); + ctx->Multisample.SampleCoverageInvert = state; + ctx->NewState |= _NEW_MULTISAMPLE; + break; + + default: + _mesa_error(ctx, GL_INVALID_ENUM, state ? "glEnable" : "glDisable"); + return; + } + + if (ctx->Driver.Enable) { + (*ctx->Driver.Enable)( ctx, cap, state ); + } +} + + + + +void +_mesa_Enable( GLenum cap ) +{ + GET_CURRENT_CONTEXT(ctx); + ASSERT_OUTSIDE_BEGIN_END(ctx); + + _mesa_set_enable( ctx, cap, GL_TRUE ); +} + + + +void +_mesa_Disable( GLenum cap ) +{ + GET_CURRENT_CONTEXT(ctx); + ASSERT_OUTSIDE_BEGIN_END(ctx); + + _mesa_set_enable( ctx, cap, GL_FALSE ); +} + + + +GLboolean +_mesa_IsEnabled( GLenum cap ) +{ + GET_CURRENT_CONTEXT(ctx); + switch (cap) { + case GL_ALPHA_TEST: + return ctx->Color.AlphaEnabled; + case GL_AUTO_NORMAL: + return ctx->Eval.AutoNormal; + case GL_BLEND: + return ctx->Color.BlendEnabled; + case GL_CLIP_PLANE0: + case GL_CLIP_PLANE1: + case GL_CLIP_PLANE2: + case GL_CLIP_PLANE3: + case GL_CLIP_PLANE4: + case GL_CLIP_PLANE5: + return ctx->Transform.ClipEnabled[cap-GL_CLIP_PLANE0]; + case GL_COLOR_MATERIAL: + return ctx->Light.ColorMaterialEnabled; + case GL_CULL_FACE: + return ctx->Polygon.CullFlag; + case GL_DEPTH_TEST: + return ctx->Depth.Test; + case GL_DITHER: + return ctx->Color.DitherFlag; + case GL_FOG: + return ctx->Fog.Enabled; + case GL_HISTOGRAM: + if (ctx->Extensions.EXT_histogram || ctx->Extensions.ARB_imaging) { + return ctx->Pixel.HistogramEnabled; + } + else { + _mesa_error(ctx, GL_INVALID_ENUM, "glIsEnabled"); + return GL_FALSE; + } + case GL_LIGHTING: + return ctx->Light.Enabled; + case GL_LIGHT0: + case GL_LIGHT1: + case GL_LIGHT2: + case GL_LIGHT3: + case GL_LIGHT4: + case GL_LIGHT5: + case GL_LIGHT6: + case GL_LIGHT7: + return ctx->Light.Light[cap-GL_LIGHT0].Enabled; + case GL_LINE_SMOOTH: + return ctx->Line.SmoothFlag; + case GL_LINE_STIPPLE: + return ctx->Line.StippleFlag; + case GL_INDEX_LOGIC_OP: + return ctx->Color.IndexLogicOpEnabled; + case GL_COLOR_LOGIC_OP: + return ctx->Color.ColorLogicOpEnabled; + case GL_MAP1_COLOR_4: + return ctx->Eval.Map1Color4; + case GL_MAP1_INDEX: + return ctx->Eval.Map1Index; + case GL_MAP1_NORMAL: + return ctx->Eval.Map1Normal; + case GL_MAP1_TEXTURE_COORD_1: + return ctx->Eval.Map1TextureCoord1; + case GL_MAP1_TEXTURE_COORD_2: + return ctx->Eval.Map1TextureCoord2; + case GL_MAP1_TEXTURE_COORD_3: + return ctx->Eval.Map1TextureCoord3; + case GL_MAP1_TEXTURE_COORD_4: + return ctx->Eval.Map1TextureCoord4; + case GL_MAP1_VERTEX_3: + return ctx->Eval.Map1Vertex3; + case GL_MAP1_VERTEX_4: + return ctx->Eval.Map1Vertex4; + case GL_MAP2_COLOR_4: + return ctx->Eval.Map2Color4; + case GL_MAP2_INDEX: + return ctx->Eval.Map2Index; + case GL_MAP2_NORMAL: + return ctx->Eval.Map2Normal; + case GL_MAP2_TEXTURE_COORD_1: + return ctx->Eval.Map2TextureCoord1; + case GL_MAP2_TEXTURE_COORD_2: + return ctx->Eval.Map2TextureCoord2; + case GL_MAP2_TEXTURE_COORD_3: + return ctx->Eval.Map2TextureCoord3; + case GL_MAP2_TEXTURE_COORD_4: + return ctx->Eval.Map2TextureCoord4; + case GL_MAP2_VERTEX_3: + return ctx->Eval.Map2Vertex3; + case GL_MAP2_VERTEX_4: + return ctx->Eval.Map2Vertex4; + case GL_MINMAX: + return ctx->Pixel.MinMaxEnabled; + case GL_NORMALIZE: + return ctx->Transform.Normalize; + case GL_POINT_SMOOTH: + return ctx->Point.SmoothFlag; + case GL_POLYGON_SMOOTH: + return ctx->Polygon.SmoothFlag; + case GL_POLYGON_STIPPLE: + return ctx->Polygon.StippleFlag; + case GL_POLYGON_OFFSET_POINT: + return ctx->Polygon.OffsetPoint; + case GL_POLYGON_OFFSET_LINE: + return ctx->Polygon.OffsetLine; + case GL_POLYGON_OFFSET_FILL: + /*case GL_POLYGON_OFFSET_EXT:*/ + return ctx->Polygon.OffsetFill; + case GL_RESCALE_NORMAL_EXT: + return ctx->Transform.RescaleNormals; + case GL_SCISSOR_TEST: + return ctx->Scissor.Enabled; + case GL_SHARED_TEXTURE_PALETTE_EXT: + return ctx->Texture.SharedPalette; + case GL_STENCIL_TEST: + return ctx->Stencil.Enabled; + case GL_TEXTURE_1D: + { + const struct gl_texture_unit *texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit]; + return (texUnit->Enabled & TEXTURE0_1D) ? GL_TRUE : GL_FALSE; + } + case GL_TEXTURE_2D: + { + const struct gl_texture_unit *texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit]; + return (texUnit->Enabled & TEXTURE0_2D) ? GL_TRUE : GL_FALSE; + } + case GL_TEXTURE_3D: + { + const struct gl_texture_unit *texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit]; + return (texUnit->Enabled & TEXTURE0_3D) ? GL_TRUE : GL_FALSE; + } + case GL_TEXTURE_GEN_Q: + { + const struct gl_texture_unit *texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit]; + return (texUnit->TexGenEnabled & Q_BIT) ? GL_TRUE : GL_FALSE; + } + case GL_TEXTURE_GEN_R: + { + const struct gl_texture_unit *texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit]; + return (texUnit->TexGenEnabled & R_BIT) ? GL_TRUE : GL_FALSE; + } + case GL_TEXTURE_GEN_S: + { + const struct gl_texture_unit *texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit]; + return (texUnit->TexGenEnabled & S_BIT) ? GL_TRUE : GL_FALSE; + } + case GL_TEXTURE_GEN_T: + { + const struct gl_texture_unit *texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit]; + return (texUnit->TexGenEnabled & T_BIT) ? GL_TRUE : GL_FALSE; + } + + /* + * CLIENT STATE!!! + */ + case GL_VERTEX_ARRAY: + return ctx->Array.Vertex.Enabled; + case GL_NORMAL_ARRAY: + return ctx->Array.Normal.Enabled; + case GL_COLOR_ARRAY: + return ctx->Array.Color.Enabled; + case GL_INDEX_ARRAY: + return ctx->Array.Index.Enabled; + case GL_TEXTURE_COORD_ARRAY: + return ctx->Array.TexCoord[ctx->Array.ActiveTexture].Enabled; + case GL_EDGE_FLAG_ARRAY: + return ctx->Array.EdgeFlag.Enabled; + + /* GL_HP_occlusion_test */ + case GL_OCCLUSION_TEST_HP: + if (ctx->Extensions.HP_occlusion_test) { + return ctx->Depth.OcclusionTest; + } + else { + _mesa_error( ctx, GL_INVALID_ENUM, "glIsEnabled" ); + return GL_FALSE; + } + + /* GL_SGIS_pixel_texture */ + case GL_PIXEL_TEXTURE_SGIS: + return ctx->Pixel.PixelTextureEnabled; + + /* GL_SGIX_pixel_texture */ + case GL_PIXEL_TEX_GEN_SGIX: + return ctx->Pixel.PixelTextureEnabled; + + /* GL_SGI_color_table */ + case GL_COLOR_TABLE_SGI: + return ctx->Pixel.ColorTableEnabled; + case GL_POST_CONVOLUTION_COLOR_TABLE_SGI: + return ctx->Pixel.PostConvolutionColorTableEnabled; + case GL_POST_COLOR_MATRIX_COLOR_TABLE_SGI: + return ctx->Pixel.PostColorMatrixColorTableEnabled; + + /* GL_EXT_convolution */ + case GL_CONVOLUTION_1D: + return ctx->Pixel.Convolution1DEnabled; + case GL_CONVOLUTION_2D: + return ctx->Pixel.Convolution2DEnabled; + case GL_SEPARABLE_2D: + return ctx->Pixel.Separable2DEnabled; + + /* GL_ARB_texture_cube_map */ + case GL_TEXTURE_CUBE_MAP_ARB: + if (ctx->Extensions.ARB_texture_cube_map) { + const struct gl_texture_unit *texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit]; + return (texUnit->Enabled & TEXTURE0_CUBE) ? GL_TRUE : GL_FALSE; + } + else { + _mesa_error(ctx, GL_INVALID_ENUM, "glIsEnabled"); + return GL_FALSE; + } + + /* GL_ARB_multisample */ + case GL_MULTISAMPLE_ARB: + if (ctx->Extensions.ARB_multisample) { + return ctx->Multisample.Enabled; + } + else { + _mesa_error(ctx, GL_INVALID_ENUM, "glIsEnabled"); + return GL_FALSE; + } + case GL_SAMPLE_ALPHA_TO_COVERAGE_ARB: + if (ctx->Extensions.ARB_multisample) { + return ctx->Multisample.SampleAlphaToCoverage; + } + else { + _mesa_error(ctx, GL_INVALID_ENUM, "glIsEnabled"); + return GL_FALSE; + } + case GL_SAMPLE_ALPHA_TO_ONE_ARB: + if (ctx->Extensions.ARB_multisample) { + return ctx->Multisample.SampleAlphaToOne; + } + else { + _mesa_error(ctx, GL_INVALID_ENUM, "glIsEnabled"); + return GL_FALSE; + } + case GL_SAMPLE_COVERAGE_ARB: + if (ctx->Extensions.ARB_multisample) { + return ctx->Multisample.SampleCoverage; + } + else { + _mesa_error(ctx, GL_INVALID_ENUM, "glIsEnabled"); + return GL_FALSE; + } + case GL_SAMPLE_COVERAGE_INVERT_ARB: + if (ctx->Extensions.ARB_multisample) { + return ctx->Multisample.SampleCoverageInvert; + } + else { + _mesa_error(ctx, GL_INVALID_ENUM, "glIsEnabled"); + return GL_FALSE; + } + + default: + _mesa_error( ctx, GL_INVALID_ENUM, "glIsEnabled" ); + return GL_FALSE; + } +} Index: dll/opengl/opengl32/mesa/enable.h =================================================================== --- dll/opengl/opengl32/mesa/enable.h (revision 0) +++ dll/opengl/opengl32/mesa/enable.h (working copy) @@ -0,0 +1,54 @@ +/* $Id: enable.h,v 1.4 2001/03/12 00:48:37 gareth Exp $ */ + +/* + * Mesa 3-D graphics library + * Version: 3.5 + * + * Copyright (C) 1999-2001 Brian Paul 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 + * BRIAN PAUL 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. + */ + + +#ifndef ENABLE_H +#define ENABLE_H + + +#include "mtypes.h" + + +extern void +_mesa_set_enable( GLcontext* ctx, GLenum cap, GLboolean state ); + +extern void +_mesa_Disable( GLenum cap ); + +extern void +_mesa_Enable( GLenum cap ); + +extern GLboolean +_mesa_IsEnabled( GLenum cap ); + +extern void +_mesa_EnableClientState( GLenum cap ); + +extern void +_mesa_DisableClientState( GLenum cap ); + + +#endif Index: dll/opengl/opengl32/mesa/enums.c =================================================================== --- dll/opengl/opengl32/mesa/enums.c (revision 0) +++ dll/opengl/opengl32/mesa/enums.c (working copy) @@ -0,0 +1,934 @@ +/* $Id: enums.c,v 1.20 2001/06/08 20:10:55 brianp Exp $ */ + +/* + * Mesa 3-D graphics library + * Version: 3.5 + * + * Copyright (C) 1999-2001 Brian Paul 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 + * BRIAN PAUL 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. + * + * Author: + * Keith Whitwell + */ + + +#ifdef PC_HEADER +#include "all.h" +#else +#include "glheader.h" +#include "enums.h" +#include "mem.h" +#endif + + +typedef struct { + const char *c; + int n; +} enum_elt; + +enum_elt all_enums[] = +{ + /* Boolean values */ + { "GL_FALSE", 0 }, + { "GL_TRUE", 1 }, + + /* Data types */ + { "GL_BYTE", 0x1400 }, + { "GL_UNSIGNED_BYTE", 0x1401 }, + { "GL_SHORT", 0x1402 }, + { "GL_UNSIGNED_SHORT", 0x1403 }, + { "GL_INT", 0x1404 }, + { "GL_UNSIGNED_INT", 0x1405 }, + { "GL_FLOAT", 0x1406 }, + { "GL_DOUBLE", 0x140A }, + { "GL_2_BYTES", 0x1407 }, + { "GL_3_BYTES", 0x1408 }, + { "GL_4_BYTES", 0x1409 }, + + /* Primitives */ + { "GL_LINES", 0x0001 }, + { "GL_POINTS", 0x0000 }, + { "GL_LINE_STRIP", 0x0003 }, + { "GL_LINE_LOOP", 0x0002 }, + { "GL_TRIANGLES", 0x0004 }, + { "GL_TRIANGLE_STRIP", 0x0005 }, + { "GL_TRIANGLE_FAN", 0x0006 }, + { "GL_QUADS", 0x0007 }, + { "GL_QUAD_STRIP", 0x0008 }, + { "GL_POLYGON", 0x0009 }, + { "GL_EDGE_FLAG", 0x0B43 }, + + /* Vertex Arrays */ + { "GL_VERTEX_ARRAY", 0x8074 }, + { "GL_NORMAL_ARRAY", 0x8075 }, + { "GL_COLOR_ARRAY", 0x8076 }, + { "GL_INDEX_ARRAY", 0x8077 }, + { "GL_TEXTURE_COORD_ARRAY", 0x8078 }, + { "GL_EDGE_FLAG_ARRAY", 0x8079 }, + { "GL_VERTEX_ARRAY_SIZE", 0x807A }, + { "GL_VERTEX_ARRAY_TYPE", 0x807B }, + { "GL_VERTEX_ARRAY_STRIDE", 0x807C }, + { "GL_NORMAL_ARRAY_TYPE", 0x807E }, + { "GL_NORMAL_ARRAY_STRIDE", 0x807F }, + { "GL_COLOR_ARRAY_SIZE", 0x8081 }, + { "GL_COLOR_ARRAY_TYPE", 0x8082 }, + { "GL_COLOR_ARRAY_STRIDE", 0x8083 }, + { "GL_INDEX_ARRAY_TYPE", 0x8085 }, + { "GL_INDEX_ARRAY_STRIDE", 0x8086 }, + { "GL_TEXTURE_COORD_ARRAY_SIZE", 0x8088 }, + { "GL_TEXTURE_COORD_ARRAY_TYPE", 0x8089 }, + { "GL_TEXTURE_COORD_ARRAY_STRIDE", 0x808A }, + { "GL_EDGE_FLAG_ARRAY_STRIDE", 0x808C }, + { "GL_VERTEX_ARRAY_POINTER", 0x808E }, + { "GL_NORMAL_ARRAY_POINTER", 0x808F }, + { "GL_COLOR_ARRAY_POINTER", 0x8090 }, + { "GL_INDEX_ARRAY_POINTER", 0x8091 }, + { "GL_TEXTURE_COORD_ARRAY_POINTER", 0x8092 }, + { "GL_EDGE_FLAG_ARRAY_POINTER", 0x8093 }, + { "GL_V2F", 0x2A20 }, + { "GL_V3F", 0x2A21 }, + { "GL_C4UB_V2F", 0x2A22 }, + { "GL_C4UB_V3F", 0x2A23 }, + { "GL_C3F_V3F", 0x2A24 }, + { "GL_N3F_V3F", 0x2A25 }, + { "GL_C4F_N3F_V3F", 0x2A26 }, + { "GL_T2F_V3F", 0x2A27 }, + { "GL_T4F_V4F", 0x2A28 }, + { "GL_T2F_C4UB_V3F", 0x2A29 }, + { "GL_T2F_C3F_V3F", 0x2A2A }, + { "GL_T2F_N3F_V3F", 0x2A2B }, + { "GL_T2F_C4F_N3F_V3F", 0x2A2C }, + { "GL_T4F_C4F_N3F_V4F", 0x2A2D }, + + /* Matrix Mode */ + { "GL_MATRIX_MODE", 0x0BA0 }, + { "GL_MODELVIEW", 0x1700 }, + { "GL_PROJECTION", 0x1701 }, + { "GL_TEXTURE", 0x1702 }, + + /* Points */ + { "GL_POINT_SMOOTH", 0x0B10 }, + { "GL_POINT_SIZE", 0x0B11 }, + { "GL_POINT_SIZE_GRANULARITY ", 0x0B13 }, + { "GL_POINT_SIZE_RANGE", 0x0B12 }, + + /* Lines */ + { "GL_LINE_SMOOTH", 0x0B20 }, + { "GL_LINE_STIPPLE", 0x0B24 }, + { "GL_LINE_STIPPLE_PATTERN", 0x0B25 }, + { "GL_LINE_STIPPLE_REPEAT", 0x0B26 }, + { "GL_LINE_WIDTH", 0x0B21 }, + { "GL_LINE_WIDTH_GRANULARITY", 0x0B23 }, + { "GL_LINE_WIDTH_RANGE", 0x0B22 }, + + /* Polygons */ + { "GL_POINT", 0x1B00 }, + { "GL_LINE", 0x1B01 }, + { "GL_FILL", 0x1B02 }, + { "GL_CCW", 0x0901 }, + { "GL_CW", 0x0900 }, + { "GL_FRONT", 0x0404 }, + { "GL_BACK", 0x0405 }, + { "GL_CULL_FACE", 0x0B44 }, + { "GL_CULL_FACE_MODE", 0x0B45 }, + { "GL_POLYGON_SMOOTH", 0x0B41 }, + { "GL_POLYGON_STIPPLE", 0x0B42 }, + { "GL_FRONT_FACE", 0x0B46 }, + { "GL_POLYGON_MODE", 0x0B40 }, + { "GL_POLYGON_OFFSET_FACTOR", 0x8038 }, + { "GL_POLYGON_OFFSET_UNITS", 0x2A00 }, + { "GL_POLYGON_OFFSET_POINT", 0x2A01 }, + { "GL_POLYGON_OFFSET_LINE", 0x2A02 }, + { "GL_POLYGON_OFFSET_FILL", 0x8037 }, + + /* Display Lists */ + { "GL_COMPILE", 0x1300 }, + { "GL_COMPILE_AND_EXECUTE", 0x1301 }, + { "GL_LIST_BASE", 0x0B32 }, + { "GL_LIST_INDEX", 0x0B33 }, + { "GL_LIST_MODE", 0x0B30 }, + + /* Depth buffer */ + { "GL_NEVER", 0x0200 }, + { "GL_LESS", 0x0201 }, + { "GL_GEQUAL", 0x0206 }, + { "GL_LEQUAL", 0x0203 }, + { "GL_GREATER", 0x0204 }, + { "GL_NOTEQUAL", 0x0205 }, + { "GL_EQUAL", 0x0202 }, + { "GL_ALWAYS", 0x0207 }, + { "GL_DEPTH_TEST", 0x0B71 }, + { "GL_DEPTH_BITS", 0x0D56 }, + { "GL_DEPTH_CLEAR_VALUE", 0x0B73 }, + { "GL_DEPTH_FUNC", 0x0B74 }, + { "GL_DEPTH_RANGE", 0x0B70 }, + { "GL_DEPTH_WRITEMASK", 0x0B72 }, + { "GL_DEPTH_COMPONENT", 0x1902 }, + + /* Lighting */ + { "GL_LIGHTING", 0x0B50 }, + { "GL_LIGHT0", 0x4000 }, + { "GL_LIGHT1", 0x4001 }, + { "GL_LIGHT2", 0x4002 }, + { "GL_LIGHT3", 0x4003 }, + { "GL_LIGHT4", 0x4004 }, + { "GL_LIGHT5", 0x4005 }, + { "GL_LIGHT6", 0x4006 }, + { "GL_LIGHT7", 0x4007 }, + { "GL_SPOT_EXPONENT", 0x1205 }, + { "GL_SPOT_CUTOFF", 0x1206 }, + { "GL_CONSTANT_ATTENUATION", 0x1207 }, + { "GL_LINEAR_ATTENUATION", 0x1208 }, + { "GL_QUADRATIC_ATTENUATION", 0x1209 }, + { "GL_AMBIENT", 0x1200 }, + { "GL_DIFFUSE", 0x1201 }, + { "GL_SPECULAR", 0x1202 }, + { "GL_SHININESS", 0x1601 }, + { "GL_EMISSION", 0x1600 }, + { "GL_POSITION", 0x1203 }, + { "GL_SPOT_DIRECTION", 0x1204 }, + { "GL_AMBIENT_AND_DIFFUSE", 0x1602 }, + { "GL_COLOR_INDEXES", 0x1603 }, + { "GL_LIGHT_MODEL_TWO_SIDE", 0x0B52 }, + { "GL_LIGHT_MODEL_LOCAL_VIEWER", 0x0B51 }, + { "GL_LIGHT_MODEL_AMBIENT", 0x0B53 }, + { "GL_FRONT_AND_BACK", 0x0408 }, + { "GL_SHADE_MODEL", 0x0B54 }, + { "GL_FLAT", 0x1D00 }, + { "GL_SMOOTH", 0x1D01 }, + { "GL_COLOR_MATERIAL", 0x0B57 }, + { "GL_COLOR_MATERIAL_FACE", 0x0B55 }, + { "GL_COLOR_MATERIAL_PARAMETER", 0x0B56 }, + { "GL_NORMALIZE", 0x0BA1 }, + + /* User clipping planes */ + { "GL_CLIP_PLANE0", 0x3000 }, + { "GL_CLIP_PLANE1", 0x3001 }, + { "GL_CLIP_PLANE2", 0x3002 }, + { "GL_CLIP_PLANE3", 0x3003 }, + { "GL_CLIP_PLANE4", 0x3004 }, + { "GL_CLIP_PLANE5", 0x3005 }, + + /* Accumulation buffer */ + { "GL_ACCUM_RED_BITS", 0x0D58 }, + { "GL_ACCUM_GREEN_BITS", 0x0D59 }, + { "GL_ACCUM_BLUE_BITS", 0x0D5A }, + { "GL_ACCUM_ALPHA_BITS", 0x0D5B }, + { "GL_ACCUM_CLEAR_VALUE", 0x0B80 }, + { "GL_ACCUM", 0x0100 }, + { "GL_ADD", 0x0104 }, + { "GL_LOAD", 0x0101 }, + { "GL_MULT", 0x0103 }, + { "GL_RETURN", 0x0102 }, + + /* Alpha testing */ + { "GL_ALPHA_TEST", 0x0BC0 }, + { "GL_ALPHA_TEST_REF", 0x0BC2 }, + { "GL_ALPHA_TEST_FUNC", 0x0BC1 }, + + /* Blending */ + { "GL_BLEND", 0x0BE2 }, + { "GL_BLEND_SRC", 0x0BE1 }, + { "GL_BLEND_DST", 0x0BE0 }, + { "GL_ZERO", 0 }, + { "GL_ONE", 1 }, + { "GL_SRC_COLOR", 0x0300 }, + { "GL_ONE_MINUS_SRC_COLOR", 0x0301 }, + { "GL_DST_COLOR", 0x0306 }, + { "GL_ONE_MINUS_DST_COLOR", 0x0307 }, + { "GL_SRC_ALPHA", 0x0302 }, + { "GL_ONE_MINUS_SRC_ALPHA", 0x0303 }, + { "GL_DST_ALPHA", 0x0304 }, + { "GL_ONE_MINUS_DST_ALPHA", 0x0305 }, + { "GL_SRC_ALPHA_SATURATE", 0x0308 }, + { "GL_CONSTANT_COLOR", 0x8001 }, + { "GL_ONE_MINUS_CONSTANT_COLOR", 0x8002 }, + { "GL_CONSTANT_ALPHA", 0x8003 }, + { "GL_ONE_MINUS_CONSTANT_ALPHA", 0x8004 }, + + /* Render Mode */ + { "GL_FEEDBACK", 0x1C01 }, + { "GL_RENDER", 0x1C00 }, + { "GL_SELECT", 0x1C02 }, + + /* Feedback */ + { "GL_2D", 0x0600 }, + { "GL_3D", 0x0601 }, + { "GL_3D_COLOR", 0x0602 }, + { "GL_3D_COLOR_TEXTURE", 0x0603 }, + { "GL_4D_COLOR_TEXTURE", 0x0604 }, + { "GL_POINT_TOKEN", 0x0701 }, + { "GL_LINE_TOKEN", 0x0702 }, + { "GL_LINE_RESET_TOKEN", 0x0707 }, + { "GL_POLYGON_TOKEN", 0x0703 }, + { "GL_BITMAP_TOKEN", 0x0704 }, + { "GL_DRAW_PIXEL_TOKEN", 0x0705 }, + { "GL_COPY_PIXEL_TOKEN", 0x0706 }, + { "GL_PASS_THROUGH_TOKEN", 0x0700 }, + { "GL_FEEDBACK_BUFFER_POINTER", 0x0DF0 }, + { "GL_FEEDBACK_BUFFER_SIZE", 0x0DF1 }, + { "GL_FEEDBACK_BUFFER_TYPE", 0x0DF2 }, + + /* Selection */ + { "GL_SELECTION_BUFFER_POINTER", 0x0DF3 }, + { "GL_SELECTION_BUFFER_SIZE", 0x0DF4 }, + + /* Fog */ + { "GL_FOG", 0x0B60 }, + { "GL_FOG_MODE", 0x0B65 }, + { "GL_FOG_DENSITY", 0x0B62 }, + { "GL_FOG_COLOR", 0x0B66 }, + { "GL_FOG_INDEX", 0x0B61 }, + { "GL_FOG_START", 0x0B63 }, + { "GL_FOG_END", 0x0B64 }, + { "GL_LINEAR", 0x2601 }, + { "GL_EXP", 0x0800 }, + { "GL_EXP2", 0x0801 }, + + /* Logic Ops */ + { "GL_LOGIC_OP", 0x0BF1 }, + { "GL_INDEX_LOGIC_OP", 0x0BF1 }, + { "GL_COLOR_LOGIC_OP", 0x0BF2 }, + { "GL_LOGIC_OP_MODE", 0x0BF0 }, + { "GL_CLEAR", 0x1500 }, + { "GL_SET", 0x150F }, + { "GL_COPY", 0x1503 }, + { "GL_COPY_INVERTED", 0x150C }, + { "GL_NOOP", 0x1505 }, + { "GL_INVERT", 0x150A }, + { "GL_AND", 0x1501 }, + { "GL_NAND", 0x150E }, + { "GL_OR", 0x1507 }, + { "GL_NOR", 0x1508 }, + { "GL_XOR", 0x1506 }, + { "GL_EQUIV", 0x1509 }, + { "GL_AND_REVERSE", 0x1502 }, + { "GL_AND_INVERTED", 0x1504 }, + { "GL_OR_REVERSE", 0x150B }, + { "GL_OR_INVERTED", 0x150D }, + + /* Stencil */ + { "GL_STENCIL_TEST", 0x0B90 }, + { "GL_STENCIL_WRITEMASK", 0x0B98 }, + { "GL_STENCIL_BITS", 0x0D57 }, + { "GL_STENCIL_FUNC", 0x0B92 }, + { "GL_STENCIL_VALUE_MASK", 0x0B93 }, + { "GL_STENCIL_REF", 0x0B97 }, + { "GL_STENCIL_FAIL", 0x0B94 }, + { "GL_STENCIL_PASS_DEPTH_PASS", 0x0B96 }, + { "GL_STENCIL_PASS_DEPTH_FAIL", 0x0B95 }, + { "GL_STENCIL_CLEAR_VALUE", 0x0B91 }, + { "GL_STENCIL_INDEX", 0x1901 }, + { "GL_KEEP", 0x1E00 }, + { "GL_REPLACE", 0x1E01 }, + { "GL_INCR", 0x1E02 }, + { "GL_DECR", 0x1E03 }, + + /* Buffers, Pixel Drawing/Reading */ + { "GL_NONE", 0 }, + { "GL_LEFT", 0x0406 }, + { "GL_RIGHT", 0x0407 }, + { "GL_FRONT_LEFT", 0x0400 }, + { "GL_FRONT_RIGHT", 0x0401 }, + { "GL_BACK_LEFT", 0x0402 }, + { "GL_BACK_RIGHT", 0x0403 }, + { "GL_AUX0", 0x0409 }, + { "GL_AUX1", 0x040A }, + { "GL_AUX2", 0x040B }, + { "GL_AUX3", 0x040C }, + { "GL_COLOR_INDEX", 0x1900 }, + { "GL_RED", 0x1903 }, + { "GL_GREEN", 0x1904 }, + { "GL_BLUE", 0x1905 }, + { "GL_ALPHA", 0x1906 }, + { "GL_LUMINANCE", 0x1909 }, + { "GL_LUMINANCE_ALPHA", 0x190A }, + { "GL_ALPHA_BITS", 0x0D55 }, + { "GL_RED_BITS", 0x0D52 }, + { "GL_GREEN_BITS", 0x0D53 }, + { "GL_BLUE_BITS", 0x0D54 }, + { "GL_INDEX_BITS", 0x0D51 }, + { "GL_SUBPIXEL_BITS", 0x0D50 }, + { "GL_AUX_BUFFERS", 0x0C00 }, + { "GL_READ_BUFFER", 0x0C02 }, + { "GL_DRAW_BUFFER", 0x0C01 }, + { "GL_DOUBLEBUFFER", 0x0C32 }, + { "GL_STEREO", 0x0C33 }, + { "GL_BITMAP", 0x1A00 }, + { "GL_COLOR", 0x1800 }, + { "GL_DEPTH", 0x1801 }, + { "GL_STENCIL", 0x1802 }, + { "GL_DITHER", 0x0BD0 }, + { "GL_RGB", 0x1907 }, + { "GL_RGBA", 0x1908 }, + + /* Implementation limits */ + { "GL_MAX_LIST_NESTING", 0x0B31 }, + { "GL_MAX_ATTRIB_STACK_DEPTH", 0x0D35 }, + { "GL_MAX_MODELVIEW_STACK_DEPTH", 0x0D36 }, + { "GL_MAX_NAME_STACK_DEPTH", 0x0D37 }, + { "GL_MAX_PROJECTION_STACK_DEPTH", 0x0D38 }, + { "GL_MAX_TEXTURE_STACK_DEPTH", 0x0D39 }, + { "GL_MAX_EVAL_ORDER", 0x0D30 }, + { "GL_MAX_LIGHTS", 0x0D31 }, + { "GL_MAX_CLIP_PLANES", 0x0D32 }, + { "GL_MAX_TEXTURE_SIZE", 0x0D33 }, + { "GL_MAX_PIXEL_MAP_TABLE", 0x0D34 }, + { "GL_MAX_VIEWPORT_DIMS", 0x0D3A }, + { "GL_MAX_CLIENT_ATTRIB_STACK_DEPTH", 0x0D3B }, + + + { "GL_ATTRIB_STACK_DEPTH", 0x0BB0 }, + { "GL_CLIENT_ATTRIB_STACK_DEPTH", 0x0BB1 }, + { "GL_COLOR_CLEAR_VALUE", 0x0C22 }, + { "GL_COLOR_WRITEMASK", 0x0C23 }, + { "GL_CURRENT_INDEX", 0x0B01 }, + { "GL_CURRENT_COLOR", 0x0B00 }, + { "GL_CURRENT_NORMAL", 0x0B02 }, + { "GL_CURRENT_RASTER_COLOR", 0x0B04 }, + { "GL_CURRENT_RASTER_DISTANCE", 0x0B09 }, + { "GL_CURRENT_RASTER_INDEX", 0x0B05 }, + { "GL_CURRENT_RASTER_POSITION", 0x0B07 }, + { "GL_CURRENT_RASTER_TEXTURE_COORDS", 0x0B06}, + { "GL_CURRENT_RASTER_POSITION_VALID", 0x0B08 }, + { "GL_CURRENT_TEXTURE_COORDS", 0x0B03 }, + { "GL_INDEX_CLEAR_VALUE", 0x0C20 }, + { "GL_INDEX_MODE", 0x0C30 }, + { "GL_INDEX_WRITEMASK", 0x0C21 }, + { "GL_MODELVIEW_MATRIX", 0x0BA6 }, + { "GL_MODELVIEW_STACK_DEPTH", 0x0BA3 }, + { "GL_NAME_STACK_DEPTH", 0x0D70 }, + { "GL_PROJECTION_MATRIX", 0x0BA7 }, + { "GL_PROJECTION_STACK_DEPTH", 0x0BA4 }, + { "GL_RENDER_MODE", 0x0C40 }, + { "GL_RGBA_MODE", 0x0C31 }, + { "GL_TEXTURE_MATRIX", 0x0BA8 }, + { "GL_TEXTURE_STACK_DEPTH", 0x0BA5 }, + { "GL_VIEWPORT", 0x0BA2 }, + + + /* Evaluators */ + { "GL_AUTO_NORMAL", 0x0D80 }, + { "GL_MAP1_COLOR_4", 0x0D90 }, + { "GL_MAP1_GRID_DOMAIN", 0x0DD0 }, + { "GL_MAP1_GRID_SEGMENTS", 0x0DD1 }, + { "GL_MAP1_INDEX", 0x0D91 }, + { "GL_MAP1_NORMAL", 0x0D92 }, + { "GL_MAP1_TEXTURE_COORD_1", 0x0D93 }, + { "GL_MAP1_TEXTURE_COORD_2", 0x0D94 }, + { "GL_MAP1_TEXTURE_COORD_3", 0x0D95 }, + { "GL_MAP1_TEXTURE_COORD_4", 0x0D96 }, + { "GL_MAP1_VERTEX_3", 0x0D97 }, + { "GL_MAP1_VERTEX_4", 0x0D98 }, + { "GL_MAP2_COLOR_4", 0x0DB0 }, + { "GL_MAP2_GRID_DOMAIN", 0x0DD2 }, + { "GL_MAP2_GRID_SEGMENTS", 0x0DD3 }, + { "GL_MAP2_INDEX", 0x0DB1 }, + { "GL_MAP2_NORMAL", 0x0DB2 }, + { "GL_MAP2_TEXTURE_COORD_1", 0x0DB3 }, + { "GL_MAP2_TEXTURE_COORD_2", 0x0DB4 }, + { "GL_MAP2_TEXTURE_COORD_3", 0x0DB5 }, + { "GL_MAP2_TEXTURE_COORD_4", 0x0DB6 }, + { "GL_MAP2_VERTEX_3", 0x0DB7 }, + { "GL_MAP2_VERTEX_4", 0x0DB8 }, + { "GL_COEFF", 0x0A00 }, + { "GL_DOMAIN", 0x0A02 }, + { "GL_ORDER", 0x0A01 }, + + /* Hints */ + { "GL_FOG_HINT", 0x0C54 }, + { "GL_LINE_SMOOTH_HINT", 0x0C52 }, + { "GL_PERSPECTIVE_CORRECTION_HINT", 0x0C50 }, + { "GL_POINT_SMOOTH_HINT", 0x0C51 }, + { "GL_POLYGON_SMOOTH_HINT", 0x0C53 }, + { "GL_DONT_CARE", 0x1100 }, + { "GL_FASTEST", 0x1101 }, + { "GL_NICEST", 0x1102 }, + + /* Scissor box */ + { "GL_SCISSOR_TEST", 0x0C11 }, + { "GL_SCISSOR_BOX", 0x0C10 }, + + /* Pixel Mode / Transfer */ + { "GL_MAP_COLOR", 0x0D10 }, + { "GL_MAP_STENCIL", 0x0D11 }, + { "GL_INDEX_SHIFT", 0x0D12 }, + { "GL_INDEX_OFFSET", 0x0D13 }, + { "GL_RED_SCALE", 0x0D14 }, + { "GL_RED_BIAS", 0x0D15 }, + { "GL_GREEN_SCALE", 0x0D18 }, + { "GL_GREEN_BIAS", 0x0D19 }, + { "GL_BLUE_SCALE", 0x0D1A }, + { "GL_BLUE_BIAS", 0x0D1B }, + { "GL_ALPHA_SCALE", 0x0D1C }, + { "GL_ALPHA_BIAS", 0x0D1D }, + { "GL_DEPTH_SCALE", 0x0D1E }, + { "GL_DEPTH_BIAS", 0x0D1F }, + { "GL_PIXEL_MAP_S_TO_S_SIZE", 0x0CB1 }, + { "GL_PIXEL_MAP_I_TO_I_SIZE", 0x0CB0 }, + { "GL_PIXEL_MAP_I_TO_R_SIZE", 0x0CB2 }, + { "GL_PIXEL_MAP_I_TO_G_SIZE", 0x0CB3 }, + { "GL_PIXEL_MAP_I_TO_B_SIZE", 0x0CB4 }, + { "GL_PIXEL_MAP_I_TO_A_SIZE", 0x0CB5 }, + { "GL_PIXEL_MAP_R_TO_R_SIZE", 0x0CB6 }, + { "GL_PIXEL_MAP_G_TO_G_SIZE", 0x0CB7 }, + { "GL_PIXEL_MAP_B_TO_B_SIZE", 0x0CB8 }, + { "GL_PIXEL_MAP_A_TO_A_SIZE", 0x0CB9 }, + { "GL_PIXEL_MAP_S_TO_S", 0x0C71 }, + { "GL_PIXEL_MAP_I_TO_I", 0x0C70 }, + { "GL_PIXEL_MAP_I_TO_R", 0x0C72 }, + { "GL_PIXEL_MAP_I_TO_G", 0x0C73 }, + { "GL_PIXEL_MAP_I_TO_B", 0x0C74 }, + { "GL_PIXEL_MAP_I_TO_A", 0x0C75 }, + { "GL_PIXEL_MAP_R_TO_R", 0x0C76 }, + { "GL_PIXEL_MAP_G_TO_G", 0x0C77 }, + { "GL_PIXEL_MAP_B_TO_B", 0x0C78 }, + { "GL_PIXEL_MAP_A_TO_A", 0x0C79 }, + { "GL_PACK_ALIGNMENT", 0x0D05 }, + { "GL_PACK_LSB_FIRST", 0x0D01 }, + { "GL_PACK_ROW_LENGTH", 0x0D02 }, + { "GL_PACK_SKIP_PIXELS", 0x0D04 }, + { "GL_PACK_SKIP_ROWS", 0x0D03 }, + { "GL_PACK_SWAP_BYTES", 0x0D00 }, + { "GL_UNPACK_ALIGNMENT", 0x0CF5 }, + { "GL_UNPACK_LSB_FIRST", 0x0CF1 }, + { "GL_UNPACK_ROW_LENGTH", 0x0CF2 }, + { "GL_UNPACK_SKIP_PIXELS", 0x0CF4 }, + { "GL_UNPACK_SKIP_ROWS", 0x0CF3 }, + { "GL_UNPACK_SWAP_BYTES", 0x0CF0 }, + { "GL_ZOOM_X", 0x0D16 }, + { "GL_ZOOM_Y", 0x0D17 }, + + /* Texture mapping */ + { "GL_TEXTURE_ENV", 0x2300 }, + { "GL_TEXTURE_ENV_MODE", 0x2200 }, + { "GL_TEXTURE_1D", 0x0DE0 }, + { "GL_TEXTURE_2D", 0x0DE1 }, + { "GL_TEXTURE_WRAP_S", 0x2802 }, + { "GL_TEXTURE_WRAP_T", 0x2803 }, + { "GL_TEXTURE_MAG_FILTER", 0x2800 }, + { "GL_TEXTURE_MIN_FILTER", 0x2801 }, + { "GL_TEXTURE_ENV_COLOR", 0x2201 }, + { "GL_TEXTURE_GEN_S", 0x0C60 }, + { "GL_TEXTURE_GEN_T", 0x0C61 }, + { "GL_TEXTURE_GEN_MODE", 0x2500 }, + { "GL_TEXTURE_BORDER_COLOR", 0x1004 }, + { "GL_TEXTURE_WIDTH", 0x1000 }, + { "GL_TEXTURE_HEIGHT", 0x1001 }, + { "GL_TEXTURE_BORDER", 0x1005 }, + { "GL_TEXTURE_COMPONENTS", 0x1003 }, + { "GL_TEXTURE_RED_SIZE", 0x805C }, + { "GL_TEXTURE_GREEN_SIZE", 0x805D }, + { "GL_TEXTURE_BLUE_SIZE", 0x805E }, + { "GL_TEXTURE_ALPHA_SIZE", 0x805F }, + { "GL_TEXTURE_LUMINANCE_SIZE", 0x8060 }, + { "GL_TEXTURE_INTENSITY_SIZE", 0x8061 }, + { "GL_NEAREST_MIPMAP_NEAREST", 0x2700 }, + { "GL_NEAREST_MIPMAP_LINEAR", 0x2702 }, + { "GL_LINEAR_MIPMAP_NEAREST", 0x2701 }, + { "GL_LINEAR_MIPMAP_LINEAR", 0x2703 }, + { "GL_OBJECT_LINEAR", 0x2401 }, + { "GL_OBJECT_PLANE", 0x2501 }, + { "GL_EYE_LINEAR", 0x2400 }, + { "GL_EYE_PLANE", 0x2502 }, + { "GL_SPHERE_MAP", 0x2402 }, + { "GL_DECAL", 0x2101 }, + { "GL_MODULATE", 0x2100 }, + { "GL_NEAREST", 0x2600 }, + { "GL_REPEAT", 0x2901 }, + { "GL_CLAMP", 0x2900 }, + { "GL_S", 0x2000 }, + { "GL_T", 0x2001 }, + { "GL_R", 0x2002 }, + { "GL_Q", 0x2003 }, + { "GL_TEXTURE_GEN_R", 0x0C62 }, + { "GL_TEXTURE_GEN_Q", 0x0C63 }, + + /* GL 1.1 texturing */ + { "GL_PROXY_TEXTURE_1D", 0x8063 }, + { "GL_PROXY_TEXTURE_2D", 0x8064 }, + { "GL_TEXTURE_PRIORITY", 0x8066 }, + { "GL_TEXTURE_RESIDENT", 0x8067 }, + { "GL_TEXTURE_BINDING_1D", 0x8068 }, + { "GL_TEXTURE_BINDING_2D", 0x8069 }, + { "GL_TEXTURE_INTERNAL_FORMAT", 0x1003 }, + + /* GL 1.2 texturing */ + { "GL_PACK_SKIP_IMAGES", 0x806B }, + { "GL_PACK_IMAGE_HEIGHT", 0x806C }, + { "GL_UNPACK_SKIP_IMAGES", 0x806D }, + { "GL_UNPACK_IMAGE_HEIGHT", 0x806E }, + { "GL_TEXTURE_3D", 0x806F }, + { "GL_PROXY_TEXTURE_3D", 0x8070 }, + { "GL_TEXTURE_DEPTH", 0x8071 }, + { "GL_TEXTURE_WRAP_R", 0x8072 }, + { "GL_MAX_3D_TEXTURE_SIZE", 0x8073 }, + { "GL_TEXTURE_BINDING_3D", 0x806A }, + + /* Internal texture formats (GL 1.1) */ + { "GL_ALPHA4", 0x803B }, + { "GL_ALPHA8", 0x803C }, + { "GL_ALPHA12", 0x803D }, + { "GL_ALPHA16", 0x803E }, + { "GL_LUMINANCE4", 0x803F }, + { "GL_LUMINANCE8", 0x8040 }, + { "GL_LUMINANCE12", 0x8041 }, + { "GL_LUMINANCE16", 0x8042 }, + { "GL_LUMINANCE4_ALPHA4", 0x8043 }, + { "GL_LUMINANCE6_ALPHA2", 0x8044 }, + { "GL_LUMINANCE8_ALPHA8", 0x8045 }, + { "GL_LUMINANCE12_ALPHA4", 0x8046 }, + { "GL_LUMINANCE12_ALPHA12", 0x8047 }, + { "GL_LUMINANCE16_ALPHA16", 0x8048 }, + { "GL_INTENSITY", 0x8049 }, + { "GL_INTENSITY4", 0x804A }, + { "GL_INTENSITY8", 0x804B }, + { "GL_INTENSITY12", 0x804C }, + { "GL_INTENSITY16", 0x804D }, + { "GL_R3_G3_B2", 0x2A10 }, + { "GL_RGB4", 0x804F }, + { "GL_RGB5", 0x8050 }, + { "GL_RGB8", 0x8051 }, + { "GL_RGB10", 0x8052 }, + { "GL_RGB12", 0x8053 }, + { "GL_RGB16", 0x8054 }, + { "GL_RGBA2", 0x8055 }, + { "GL_RGBA4", 0x8056 }, + { "GL_RGB5_A1", 0x8057 }, + { "GL_RGBA8", 0x8058 }, + { "GL_RGB10_A2", 0x8059 }, + { "GL_RGBA12", 0x805A }, + { "GL_RGBA16", 0x805B }, + + /* Utility */ + { "GL_VENDOR", 0x1F00 }, + { "GL_RENDERER", 0x1F01 }, + { "GL_VERSION", 0x1F02 }, + { "GL_EXTENSIONS", 0x1F03 }, + + /* Errors */ + { "GL_INVALID_VALUE", 0x0501 }, + { "GL_INVALID_ENUM", 0x0500 }, + { "GL_INVALID_OPERATION", 0x0502 }, + { "GL_STACK_OVERFLOW", 0x0503 }, + { "GL_STACK_UNDERFLOW", 0x0504 }, + { "GL_OUT_OF_MEMORY", 0x0505 }, + + /* + * Extensions + */ + + { "GL_CONSTANT_COLOR_EXT", 0x8001 }, + { "GL_ONE_MINUS_CONSTANT_COLOR_EXT", 0x8002 }, + { "GL_CONSTANT_ALPHA_EXT", 0x8003 }, + { "GL_ONE_MINUS_CONSTANT_ALPHA_EXT", 0x8004 }, + { "GL_BLEND_EQUATION_EXT", 0x8009 }, + { "GL_MIN_EXT", 0x8007 }, + { "GL_MAX_EXT", 0x8008 }, + { "GL_FUNC_ADD_EXT", 0x8006 }, + { "GL_FUNC_SUBTRACT_EXT", 0x800A }, + { "GL_FUNC_REVERSE_SUBTRACT_EXT", 0x800B }, + { "GL_BLEND_COLOR_EXT", 0x8005 }, + + { "GL_POLYGON_OFFSET_EXT", 0x8037 }, + { "GL_POLYGON_OFFSET_FACTOR_EXT", 0x8038 }, + { "GL_POLYGON_OFFSET_BIAS_EXT", 0x8039 }, + + + { "GL_VERTEX_ARRAY_EXT", 0x8074 }, + { "GL_NORMAL_ARRAY_EXT", 0x8075 }, + { "GL_COLOR_ARRAY_EXT", 0x8076 }, + { "GL_INDEX_ARRAY_EXT", 0x8077 }, + { "GL_TEXTURE_COORD_ARRAY_EXT", 0x8078 }, + { "GL_EDGE_FLAG_ARRAY_EXT", 0x8079 }, + { "GL_VERTEX_ARRAY_SIZE_EXT", 0x807A }, + { "GL_VERTEX_ARRAY_TYPE_EXT", 0x807B }, + { "GL_VERTEX_ARRAY_STRIDE_EXT", 0x807C }, + { "GL_VERTEX_ARRAY_COUNT_EXT", 0x807D }, + { "GL_NORMAL_ARRAY_TYPE_EXT", 0x807E }, + { "GL_NORMAL_ARRAY_STRIDE_EXT", 0x807F }, + { "GL_NORMAL_ARRAY_COUNT_EXT", 0x8080 }, + { "GL_COLOR_ARRAY_SIZE_EXT", 0x8081 }, + { "GL_COLOR_ARRAY_TYPE_EXT", 0x8082 }, + { "GL_COLOR_ARRAY_STRIDE_EXT", 0x8083 }, + { "GL_COLOR_ARRAY_COUNT_EXT", 0x8084 }, + { "GL_INDEX_ARRAY_TYPE_EXT", 0x8085 }, + { "GL_INDEX_ARRAY_STRIDE_EXT", 0x8086 }, + { "GL_INDEX_ARRAY_COUNT_EXT", 0x8087 }, + { "GL_TEXTURE_COORD_ARRAY_SIZE_EXT", 0x8088 }, + { "GL_TEXTURE_COORD_ARRAY_TYPE_EXT", 0x8089 }, + { "GL_TEXTURE_COORD_ARRAY_STRIDE_EXT", 0x808A }, + { "GL_TEXTURE_COORD_ARRAY_COUNT_EXT", 0x808B }, + { "GL_EDGE_FLAG_ARRAY_STRIDE_EXT", 0x808C }, + { "GL_EDGE_FLAG_ARRAY_COUNT_EXT", 0x808D }, + { "GL_VERTEX_ARRAY_POINTER_EXT", 0x808E }, + { "GL_NORMAL_ARRAY_POINTER_EXT", 0x808F }, + { "GL_COLOR_ARRAY_POINTER_EXT", 0x8090 }, + { "GL_INDEX_ARRAY_POINTER_EXT", 0x8091 }, + { "GL_TEXTURE_COORD_ARRAY_POINTER_EXT", 0x8092 }, + { "GL_EDGE_FLAG_ARRAY_POINTER_EXT", 0x8093 }, + + { "GL_TEXTURE_PRIORITY_EXT", 0x8066 }, + { "GL_TEXTURE_RESIDENT_EXT", 0x8067 }, + { "GL_TEXTURE_1D_BINDING_EXT", 0x8068 }, + { "GL_TEXTURE_2D_BINDING_EXT", 0x8069 }, + + { "GL_PACK_SKIP_IMAGES_EXT", 0x806B }, + { "GL_PACK_IMAGE_HEIGHT_EXT", 0x806C }, + { "GL_UNPACK_SKIP_IMAGES_EXT", 0x806D }, + { "GL_UNPACK_IMAGE_HEIGHT_EXT", 0x806E }, + { "GL_TEXTURE_3D_EXT", 0x806F }, + { "GL_PROXY_TEXTURE_3D_EXT", 0x8070 }, + { "GL_TEXTURE_DEPTH_EXT", 0x8071 }, + { "GL_TEXTURE_WRAP_R_EXT", 0x8072 }, + { "GL_MAX_3D_TEXTURE_SIZE_EXT", 0x8073 }, + { "GL_TEXTURE_3D_BINDING_EXT", 0x806A }, + + { "GL_TABLE_TOO_LARGE_EXT", 0x8031 }, + { "GL_COLOR_TABLE_FORMAT_EXT", 0x80D8 }, + { "GL_COLOR_TABLE_WIDTH_EXT", 0x80D9 }, + { "GL_COLOR_TABLE_RED_SIZE_EXT", 0x80DA }, + { "GL_COLOR_TABLE_GREEN_SIZE_EXT", 0x80DB }, + { "GL_COLOR_TABLE_BLUE_SIZE_EXT", 0x80DC }, + { "GL_COLOR_TABLE_ALPHA_SIZE_EXT", 0x80DD }, + { "GL_COLOR_TABLE_LUMINANCE_SIZE_EXT", 0x80DE }, + { "GL_COLOR_TABLE_INTENSITY_SIZE_EXT", 0x80DF }, + { "GL_TEXTURE_INDEX_SIZE_EXT", 0x80ED }, + { "GL_COLOR_INDEX1_EXT", 0x80E2 }, + { "GL_COLOR_INDEX2_EXT", 0x80E3 }, + { "GL_COLOR_INDEX4_EXT", 0x80E4 }, + { "GL_COLOR_INDEX8_EXT", 0x80E5 }, + { "GL_COLOR_INDEX12_EXT", 0x80E6 }, + { "GL_COLOR_INDEX16_EXT", 0x80E7 }, + + { "GL_SHARED_TEXTURE_PALETTE_EXT", 0x81FB }, + + { "GL_POINT_SIZE_MIN_EXT", 0x8126 }, + { "GL_POINT_SIZE_MAX_EXT", 0x8127 }, + { "GL_POINT_FADE_THRESHOLD_SIZE_EXT", 0x8128 }, + { "GL_DISTANCE_ATTENUATION_EXT", 0x8129 }, + + { "GL_RESCALE_NORMAL_EXT", 0x803A }, + + { "GL_ABGR_EXT", 0x8000 }, + + { "GL_INCR_WRAP_EXT", 0x8507 }, + { "GL_DECR_WRAP_EXT", 0x8508 }, + + { "GL_CLAMP_TO_EDGE_SGIS", 0x812F }, + + { "GL_BLEND_DST_RGB_INGR", 0x80C8 }, + { "GL_BLEND_SRC_RGB_INGR", 0x80C9 }, + { "GL_BLEND_DST_ALPHA_INGR", 0x80CA }, + { "GL_BLEND_SRC_ALPHA_INGR", 0x80CB }, + + { "GL_RESCALE_NORMAL", 0x803A }, + { "GL_CLAMP_TO_EDGE", 0x812F }, + { "GL_MAX_ELEMENTS_VERTICES", 0xF0E8 }, + { "GL_MAX_ELEMENTS_INDICES", 0xF0E9 }, + { "GL_BGR", 0x80E0 }, + { "GL_BGRA", 0x80E1 }, + { "GL_UNSIGNED_BYTE_3_3_2", 0x8032 }, + { "GL_UNSIGNED_BYTE_2_3_3_REV", 0x8362 }, + { "GL_UNSIGNED_SHORT_5_6_5", 0x8363 }, + { "GL_UNSIGNED_SHORT_5_6_5_REV", 0x8364 }, + { "GL_UNSIGNED_SHORT_4_4_4_4", 0x8033 }, + { "GL_UNSIGNED_SHORT_4_4_4_4_REV", 0x8365 }, + { "GL_UNSIGNED_SHORT_5_5_5_1", 0x8034 }, + { "GL_UNSIGNED_SHORT_1_5_5_5_REV", 0x8366 }, + { "GL_UNSIGNED_INT_8_8_8_8", 0x8035 }, + { "GL_UNSIGNED_INT_8_8_8_8_REV", 0x8367 }, + { "GL_UNSIGNED_INT_10_10_10_2", 0x8036 }, + { "GL_UNSIGNED_INT_2_10_10_10_REV", 0x8368 }, + { "GL_LIGHT_MODEL_COLOR_CONTROL", 0x81F8 }, + { "GL_SINGLE_COLOR", 0x81F9 }, + { "GL_SEPARATE_SPECULAR_COLOR", 0x81FA }, + { "GL_TEXTURE_MIN_LOD", 0x813A }, + { "GL_TEXTURE_MAX_LOD", 0x813B }, + { "GL_TEXTURE_BASE_LEVEL", 0x813C }, + { "GL_TEXTURE_MAX_LEVEL", 0x813D }, + + { "GL_TEXTURE0_ARB", 0x84C0 }, + { "GL_TEXTURE1_ARB", 0x84C1 }, + { "GL_TEXTURE2_ARB", 0x84C2 }, + { "GL_TEXTURE3_ARB", 0x84C3 }, + { "GL_ACTIVE_TEXTURE_ARB", 0x84E0 }, + { "GL_CLIENT_ACTIVE_TEXTURE_ARB", 0x84E1 }, + { "GL_MAX_TEXTURE_UNITS_ARB", 0x84E2 }, + + { "GL_OCCLUSION_TEST_HP", 0x8165 }, + { "GL_OCCLUSION_TEST_RESULT_HP", 0x8166 }, + + { "GL_TEXTURE_FILTER_CONTROL_EXT", 0x8500 }, + { "GL_TEXTUER_LOD_BIAS_EXT", 0x8501 }, + + { "GL_NORMAL_MAP_NV", 0x8511 }, + { "GL_REFLECTION_MAP_NV", 0x8512 }, + + { "GL_PREFER_DOUBLEBUFFER_HINT_PGI", 107000 }, + { "GL_STRICT_DEPTHFUNC_HINT_PGI", 107030 }, + { "GL_STRICT_LIGHTING_HINT_PGI", 107031 }, + { "GL_STRICT_SCISSOR_HINT_PGI", 107032 }, + { "GL_FULL_STIPPLE_HINT_PGI", 107033 }, + { "GL_NATIVE_GRAPHICS_BEGIN_HINT_PGI", 107011 }, + { "GL_NATIVE_GRAPHICS_END_HINT_PGI", 107012 }, + { "GL_CONSERVE_MEMORY_HINT_PGI", 107005 }, + { "GL_RECLAIM_MEMORY_HINT_PGI", 107006 }, + { "GL_ALWAYS_FAST_HINT_PGI", 107020 }, + { "GL_ALWAYS_SOFT_HINT_PGI", 107021 }, + { "GL_ALLOW_DRAW_OBJ_HINT_PGI", 107022 }, + { "GL_ALLOW_DRAW_WIN_HINT_PGI", 107023 }, + { "GL_ALLOW_DRAW_FRG_HINT_PGI", 107024 }, + { "GL_ALLOW_DRAW_SPN_HINT_PGI", 107024 }, + { "GL_ALLOW_DRAW_MEM_HINT_PGI", 107025 }, + { "GL_CLIP_NEAR_HINT_PGI", 107040 }, + { "GL_CLIP_FAR_HINT_PGI", 107041 }, + { "GL_WIDE_LINE_HINT_PGI", 107042 }, + { "GL_BACK_NORMALS_HINT_PGI", 107043 }, + { "GL_NATIVE_GRAPHICS_HANDLE_PGI", 107010 }, + + /* GL_EXT_compiled_vertex_array */ + { "GL_ARRAY_ELEMENT_LOCK_FIRST_EXT", 0x81A8}, + { "GL_ARRAY_ELEMENT_LOCK_COUNT_EXT", 0x81A9}, + + /* GL_EXT_clip_volume_hint */ + { "GL_CLIP_VOLUME_CLIPPING_HINT_EXT", 0x80F0}, + + /* GL_EXT_texture_env_combine */ + { "GL_COMBINE_EXT", 0x8570 }, + { "GL_COMBINE_RGB_EXT", 0x8571 }, + { "GL_COMBINE_ALPHA_EXT", 0x8572 }, + { "GL_SOURCE0_RGB_EXT", 0x8580 }, + { "GL_SOURCE1_RGB_EXT", 0x8581 }, + { "GL_SOURCE2_RGB_EXT", 0x8582 }, + { "GL_SOURCE0_ALPHA_EXT", 0x8588 }, + { "GL_SOURCE1_ALPHA_EXT", 0x8589 }, + { "GL_SOURCE2_ALPHA_EXT", 0x858A }, + { "GL_OPERAND0_RGB_EXT", 0x8590 }, + { "GL_OPERAND1_RGB_EXT", 0x8591 }, + { "GL_OPERAND2_RGB_EXT", 0x8592 }, + { "GL_OPERAND0_ALPHA_EXT", 0x8598 }, + { "GL_OPERAND1_ALPHA_EXT", 0x8599 }, + { "GL_OPERAND2_ALPHA_EXT", 0x859A }, + { "GL_RGB_SCALE_EXT", 0x8573 }, + { "GL_ADD_SIGNED_EXT", 0x8574 }, + { "GL_INTERPOLATE_EXT", 0x8575 }, + { "GL_CONSTANT_EXT", 0x8576 }, + { "GL_PRIMARY_COLOR_EXT", 0x8577 }, + { "GL_PREVIOUS_EXT", 0x8578 }, + + /* GL_ARB_texture_env_combine */ + { "GL_SUBTRACT_ARB", 0x84E7 }, + + /* GL_EXT_texture_env_dot3 */ + { "GL_DOT3_RGB_EXT", 0x8740 }, + { "GL_DOT3_RGBA_EXT", 0x8741 }, + + /* GL_ARB_texture_env_dot3 */ + { "GL_DOT3_RGB_EXT", 0x86ae }, + { "GL_DOT3_RGBA_EXT", 0x86af }, + + /* GL_ARB_texture_border_clamp */ + { "GL_CLAMP_TO_BORDER_ARB", 0x812D }, +}; + +#define Elements(x) sizeof(x)/sizeof(*x) + +typedef int (__cdecl *cfunc)(const void *, const void *); + +static enum_elt **index1 = 0; +static int sorted = 0; + +static int compar_name( const enum_elt *a, const enum_elt *b ) +{ + return strcmp(a->c, b->c); +} + + +/* note the extra level of indirection + */ +static int compar_nr( const enum_elt **a, const enum_elt **b ) +{ + return (*a)->n - (*b)->n; +} + + +static void sort_enums( void ) +{ + GLuint i; + index1 = (enum_elt **)MALLOC( Elements(all_enums) * sizeof(enum_elt *) ); + sorted = 1; + + if (!index1) + return; /* what else can we do? */ + + qsort( all_enums, Elements(all_enums), sizeof(*all_enums), + (cfunc) compar_name ); + + for (i = 0 ; i < Elements(all_enums) ; i++) + index1[i] = &all_enums[i]; + + qsort( index1, Elements(all_enums), sizeof(*index1), (cfunc) compar_nr ); +} + + + +int _mesa_lookup_enum_by_name( const char *symbol ) +{ + enum_elt tmp; + enum_elt *e; + + if (!sorted) + sort_enums(); + + if (!symbol) + return 0; + + tmp.c = symbol; + e = (enum_elt *)bsearch( &tmp, all_enums, Elements(all_enums), + sizeof(*all_enums), (cfunc) compar_name ); + + return e ? e->n : -1; +} + + +static char token_tmp[20]; + +const char *_mesa_lookup_enum_by_nr( int nr ) +{ + enum_elt tmp, *e, **f; + + if (!sorted) + sort_enums(); + + tmp.n = nr; + e = &tmp; + + f = (enum_elt **)bsearch( &e, index1, Elements(all_enums), + sizeof(*index1), (cfunc) compar_nr ); + + if (f) { + return (*f)->c; + } + else { + /* this isn't re-entrant safe, no big deal here */ + sprintf(token_tmp, "0x%x", nr); + return token_tmp; + } +} Index: dll/opengl/opengl32/mesa/enums.h =================================================================== --- dll/opengl/opengl32/mesa/enums.h (revision 0) +++ dll/opengl/opengl32/mesa/enums.h (working copy) @@ -0,0 +1,34 @@ +/* $Id: enums.h,v 1.3 2001/03/12 00:48:37 gareth Exp $ */ + +/* + * Mesa 3-D graphics library + * Version: 3.5 + * + * Copyright (C) 1999-2001 Brian Paul 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 + * BRIAN PAUL 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. + */ + + +#ifndef _ENUMS_H_ +#define _ENUMS_H_ + +extern const char *_mesa_lookup_enum_by_nr( int nr ); +extern int _mesa_lookup_enum_by_name( const char *symbol ); + +#endif Index: dll/opengl/opengl32/mesa/eval.c =================================================================== --- dll/opengl/opengl32/mesa/eval.c (revision 0) +++ dll/opengl/opengl32/mesa/eval.c (working copy) @@ -0,0 +1,1368 @@ +/* $Id: eval.c,v 1.20 2001/05/16 17:06:28 brianp Exp $ */ + +/* + * Mesa 3-D graphics library + * Version: 3.5 + * + * Copyright (C) 1999-2001 Brian Paul 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 + * BRIAN PAUL 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. + */ + + +/* + * eval.c was written by + * Bernd Barsuhn (bdbarsuh@cip.informatik.uni-erlangen.de) and + * Volker Weiss (vrweiss@cip.informatik.uni-erlangen.de). + * + * My original implementation of evaluators was simplistic and didn't + * compute surface normal vectors properly. Bernd and Volker applied + * used more sophisticated methods to get better results. + * + * Thanks guys! + */ + + +#ifdef PC_HEADER +#include "all.h" +#else +#include "glheader.h" +#include "colormac.h" +#include "context.h" +#include "eval.h" +#include "macros.h" +#include "mem.h" +#include "mmath.h" +#include "mtypes.h" +#endif + + +/* + * Return the number of components per control point for any type of + * evaluator. Return 0 if bad target. + * See table 5.1 in the OpenGL 1.2 spec. + */ +GLuint _mesa_evaluator_components( GLenum target ) +{ + switch (target) { + case GL_MAP1_VERTEX_3: return 3; + case GL_MAP1_VERTEX_4: return 4; + case GL_MAP1_INDEX: return 1; + case GL_MAP1_COLOR_4: return 4; + case GL_MAP1_NORMAL: return 3; + case GL_MAP1_TEXTURE_COORD_1: return 1; + case GL_MAP1_TEXTURE_COORD_2: return 2; + case GL_MAP1_TEXTURE_COORD_3: return 3; + case GL_MAP1_TEXTURE_COORD_4: return 4; + case GL_MAP2_VERTEX_3: return 3; + case GL_MAP2_VERTEX_4: return 4; + case GL_MAP2_INDEX: return 1; + case GL_MAP2_COLOR_4: return 4; + case GL_MAP2_NORMAL: return 3; + case GL_MAP2_TEXTURE_COORD_1: return 1; + case GL_MAP2_TEXTURE_COORD_2: return 2; + case GL_MAP2_TEXTURE_COORD_3: return 3; + case GL_MAP2_TEXTURE_COORD_4: return 4; + default: return 0; + } +} + + +/**********************************************************************/ +/*** Copy and deallocate control points ***/ +/**********************************************************************/ + + +/* + * Copy 1-parametric evaluator control points from user-specified + * memory space to a buffer of contiguous control points. + * Input: see glMap1f for details + * Return: pointer to buffer of contiguous control points or NULL if out + * of memory. + */ +GLfloat *_mesa_copy_map_points1f( GLenum target, GLint ustride, GLint uorder, + const GLfloat *points ) +{ + GLfloat *buffer, *p; + GLint i, k, size = _mesa_evaluator_components(target); + + if (!points || size==0) { + return NULL; + } + + buffer = (GLfloat *) MALLOC(uorder * size * sizeof(GLfloat)); + + if(buffer) + for(i=0, p=buffer; i vorder ? uorder : vorder)*size; + + if(hsize>dsize) + buffer = (GLfloat *) MALLOC((uorder*vorder*size+hsize)*sizeof(GLfloat)); + else + buffer = (GLfloat *) MALLOC((uorder*vorder*size+dsize)*sizeof(GLfloat)); + + /* compute the increment value for the u-loop */ + uinc = ustride - vorder*vstride; + + if (buffer) + for (i=0, p=buffer; i vorder ? uorder : vorder)*size; + + if(hsize>dsize) + buffer = (GLfloat *) MALLOC((uorder*vorder*size+hsize)*sizeof(GLfloat)); + else + buffer = (GLfloat *) MALLOC((uorder*vorder*size+dsize)*sizeof(GLfloat)); + + /* compute the increment value for the u-loop */ + uinc = ustride - vorder*vstride; + + if (buffer) + for (i=0, p=buffer; i MAX_EVAL_ORDER) { + _mesa_error( ctx, GL_INVALID_VALUE, "glMap1(order)" ); + return; + } + if (!points) { + _mesa_error( ctx, GL_INVALID_VALUE, "glMap1(points)" ); + return; + } + + k = _mesa_evaluator_components( target ); + if (k == 0) { + _mesa_error( ctx, GL_INVALID_ENUM, "glMap1(target)" ); + } + + if (ustride < k) { + _mesa_error( ctx, GL_INVALID_VALUE, "glMap1(stride)" ); + return; + } + + if (ctx->Texture.CurrentUnit != 0) { + /* See OpenGL 1.2.1 spec, section F.2.13 */ + _mesa_error( ctx, GL_INVALID_OPERATION, "glMap2(ACTIVE_TEXTURE != 0)" ); + return; + } + + switch (target) { + case GL_MAP1_VERTEX_3: + map = &ctx->EvalMap.Map1Vertex3; + break; + case GL_MAP1_VERTEX_4: + map = &ctx->EvalMap.Map1Vertex4; + break; + case GL_MAP1_INDEX: + map = &ctx->EvalMap.Map1Index; + break; + case GL_MAP1_COLOR_4: + map = &ctx->EvalMap.Map1Color4; + break; + case GL_MAP1_NORMAL: + map = &ctx->EvalMap.Map1Normal; + break; + case GL_MAP1_TEXTURE_COORD_1: + map = &ctx->EvalMap.Map1Texture1; + break; + case GL_MAP1_TEXTURE_COORD_2: + map = &ctx->EvalMap.Map1Texture2; + break; + case GL_MAP1_TEXTURE_COORD_3: + map = &ctx->EvalMap.Map1Texture3; + break; + case GL_MAP1_TEXTURE_COORD_4: + map = &ctx->EvalMap.Map1Texture4; + break; + default: + _mesa_error( ctx, GL_INVALID_ENUM, "glMap1(target)" ); + return; + } + + /* make copy of the control points */ + if (type == GL_FLOAT) + pnts = _mesa_copy_map_points1f(target, ustride, uorder, (GLfloat*) points); + else + pnts = _mesa_copy_map_points1d(target, ustride, uorder, (GLdouble*) points); + + + FLUSH_VERTICES(ctx, _NEW_EVAL); + map->Order = uorder; + map->u1 = u1; + map->u2 = u2; + map->du = 1.0 / (u2 - u1); + if (map->Points) + FREE( map->Points ); + map->Points = pnts; +} + + + +void +_mesa_Map1f( GLenum target, GLfloat u1, GLfloat u2, GLint stride, + GLint order, const GLfloat *points ) +{ + map1(target, u1, u2, stride, order, points, GL_FLOAT); +} + + +void +_mesa_Map1d( GLenum target, GLdouble u1, GLdouble u2, GLint stride, + GLint order, const GLdouble *points ) +{ + map1(target, u1, u2, stride, order, points, GL_DOUBLE); +} + + +static void +map2( GLenum target, GLfloat u1, GLfloat u2, GLint ustride, GLint uorder, + GLfloat v1, GLfloat v2, GLint vstride, GLint vorder, + const GLvoid *points, GLenum type ) +{ + GET_CURRENT_CONTEXT(ctx); + GLint k; + GLfloat *pnts; + struct gl_2d_map *map = 0; + ASSERT_OUTSIDE_BEGIN_END(ctx); + + if (u1==u2) { + _mesa_error( ctx, GL_INVALID_VALUE, "glMap2(u1,u2)" ); + return; + } + + if (v1==v2) { + _mesa_error( ctx, GL_INVALID_VALUE, "glMap2(v1,v2)" ); + return; + } + + if (uorder<1 || uorder>MAX_EVAL_ORDER) { + _mesa_error( ctx, GL_INVALID_VALUE, "glMap2(uorder)" ); + return; + } + + if (vorder<1 || vorder>MAX_EVAL_ORDER) { + _mesa_error( ctx, GL_INVALID_VALUE, "glMap2(vorder)" ); + return; + } + + k = _mesa_evaluator_components( target ); + if (k==0) { + _mesa_error( ctx, GL_INVALID_ENUM, "glMap2(target)" ); + } + + if (ustride < k) { + _mesa_error( ctx, GL_INVALID_VALUE, "glMap2(ustride)" ); + return; + } + if (vstride < k) { + _mesa_error( ctx, GL_INVALID_VALUE, "glMap2(vstride)" ); + return; + } + + if (ctx->Texture.CurrentUnit != 0) { + /* See OpenGL 1.2.1 spec, section F.2.13 */ + _mesa_error( ctx, GL_INVALID_OPERATION, "glMap2(ACTIVE_TEXTURE != 0)" ); + return; + } + + switch (target) { + case GL_MAP2_VERTEX_3: + map = &ctx->EvalMap.Map2Vertex3; + break; + case GL_MAP2_VERTEX_4: + map = &ctx->EvalMap.Map2Vertex4; + break; + case GL_MAP2_INDEX: + map = &ctx->EvalMap.Map2Index; + break; + case GL_MAP2_COLOR_4: + map = &ctx->EvalMap.Map2Color4; + break; + case GL_MAP2_NORMAL: + map = &ctx->EvalMap.Map2Normal; + break; + case GL_MAP2_TEXTURE_COORD_1: + map = &ctx->EvalMap.Map2Texture1; + break; + case GL_MAP2_TEXTURE_COORD_2: + map = &ctx->EvalMap.Map2Texture2; + break; + case GL_MAP2_TEXTURE_COORD_3: + map = &ctx->EvalMap.Map2Texture3; + break; + case GL_MAP2_TEXTURE_COORD_4: + map = &ctx->EvalMap.Map2Texture4; + break; + default: + _mesa_error( ctx, GL_INVALID_ENUM, "glMap2(target)" ); + return; + } + + /* make copy of the control points */ + if (type == GL_FLOAT) + pnts = _mesa_copy_map_points2f(target, ustride, uorder, + vstride, vorder, (GLfloat*) points); + else + pnts = _mesa_copy_map_points2d(target, ustride, uorder, + vstride, vorder, (GLdouble*) points); + + + FLUSH_VERTICES(ctx, _NEW_EVAL); + map->Uorder = uorder; + map->u1 = u1; + map->u2 = u2; + map->du = 1.0 / (u2 - u1); + map->Vorder = vorder; + map->v1 = v1; + map->v2 = v2; + map->dv = 1.0 / (v2 - v1); + if (map->Points) + FREE( map->Points ); + map->Points = pnts; +} + + +void +_mesa_Map2f( GLenum target, + GLfloat u1, GLfloat u2, GLint ustride, GLint uorder, + GLfloat v1, GLfloat v2, GLint vstride, GLint vorder, + const GLfloat *points) +{ + map2(target, u1, u2, ustride, uorder, v1, v2, vstride, vorder, + points, GL_FLOAT); +} + + +void +_mesa_Map2d( GLenum target, + GLdouble u1, GLdouble u2, GLint ustride, GLint uorder, + GLdouble v1, GLdouble v2, GLint vstride, GLint vorder, + const GLdouble *points ) +{ + map2(target, u1, u2, ustride, uorder, v1, v2, vstride, vorder, + points, GL_DOUBLE); +} + + + +void +_mesa_GetMapdv( GLenum target, GLenum query, GLdouble *v ) +{ + GET_CURRENT_CONTEXT(ctx); + GLint i, n; + GLfloat *data; + ASSERT_OUTSIDE_BEGIN_END(ctx); + + switch (query) { + case GL_COEFF: + switch (target) { + case GL_MAP1_COLOR_4: + data = ctx->EvalMap.Map1Color4.Points; + n = ctx->EvalMap.Map1Color4.Order * 4; + break; + case GL_MAP1_INDEX: + data = ctx->EvalMap.Map1Index.Points; + n = ctx->EvalMap.Map1Index.Order; + break; + case GL_MAP1_NORMAL: + data = ctx->EvalMap.Map1Normal.Points; + n = ctx->EvalMap.Map1Normal.Order * 3; + break; + case GL_MAP1_TEXTURE_COORD_1: + data = ctx->EvalMap.Map1Texture1.Points; + n = ctx->EvalMap.Map1Texture1.Order * 1; + break; + case GL_MAP1_TEXTURE_COORD_2: + data = ctx->EvalMap.Map1Texture2.Points; + n = ctx->EvalMap.Map1Texture2.Order * 2; + break; + case GL_MAP1_TEXTURE_COORD_3: + data = ctx->EvalMap.Map1Texture3.Points; + n = ctx->EvalMap.Map1Texture3.Order * 3; + break; + case GL_MAP1_TEXTURE_COORD_4: + data = ctx->EvalMap.Map1Texture4.Points; + n = ctx->EvalMap.Map1Texture4.Order * 4; + break; + case GL_MAP1_VERTEX_3: + data = ctx->EvalMap.Map1Vertex3.Points; + n = ctx->EvalMap.Map1Vertex3.Order * 3; + break; + case GL_MAP1_VERTEX_4: + data = ctx->EvalMap.Map1Vertex4.Points; + n = ctx->EvalMap.Map1Vertex4.Order * 4; + break; + case GL_MAP2_COLOR_4: + data = ctx->EvalMap.Map2Color4.Points; + n = ctx->EvalMap.Map2Color4.Uorder + * ctx->EvalMap.Map2Color4.Vorder * 4; + break; + case GL_MAP2_INDEX: + data = ctx->EvalMap.Map2Index.Points; + n = ctx->EvalMap.Map2Index.Uorder + * ctx->EvalMap.Map2Index.Vorder; + break; + case GL_MAP2_NORMAL: + data = ctx->EvalMap.Map2Normal.Points; + n = ctx->EvalMap.Map2Normal.Uorder + * ctx->EvalMap.Map2Normal.Vorder * 3; + break; + case GL_MAP2_TEXTURE_COORD_1: + data = ctx->EvalMap.Map2Texture1.Points; + n = ctx->EvalMap.Map2Texture1.Uorder + * ctx->EvalMap.Map2Texture1.Vorder * 1; + break; + case GL_MAP2_TEXTURE_COORD_2: + data = ctx->EvalMap.Map2Texture2.Points; + n = ctx->EvalMap.Map2Texture2.Uorder + * ctx->EvalMap.Map2Texture2.Vorder * 2; + break; + case GL_MAP2_TEXTURE_COORD_3: + data = ctx->EvalMap.Map2Texture3.Points; + n = ctx->EvalMap.Map2Texture3.Uorder + * ctx->EvalMap.Map2Texture3.Vorder * 3; + break; + case GL_MAP2_TEXTURE_COORD_4: + data = ctx->EvalMap.Map2Texture4.Points; + n = ctx->EvalMap.Map2Texture4.Uorder + * ctx->EvalMap.Map2Texture4.Vorder * 4; + break; + case GL_MAP2_VERTEX_3: + data = ctx->EvalMap.Map2Vertex3.Points; + n = ctx->EvalMap.Map2Vertex3.Uorder + * ctx->EvalMap.Map2Vertex3.Vorder * 3; + break; + case GL_MAP2_VERTEX_4: + data = ctx->EvalMap.Map2Vertex4.Points; + n = ctx->EvalMap.Map2Vertex4.Uorder + * ctx->EvalMap.Map2Vertex4.Vorder * 4; + break; + default: + _mesa_error( ctx, GL_INVALID_ENUM, "glGetMapdv(target)" ); + return; + } + if (data) { + for (i=0;iEvalMap.Map1Color4.Order; + break; + case GL_MAP1_INDEX: + *v = ctx->EvalMap.Map1Index.Order; + break; + case GL_MAP1_NORMAL: + *v = ctx->EvalMap.Map1Normal.Order; + break; + case GL_MAP1_TEXTURE_COORD_1: + *v = ctx->EvalMap.Map1Texture1.Order; + break; + case GL_MAP1_TEXTURE_COORD_2: + *v = ctx->EvalMap.Map1Texture2.Order; + break; + case GL_MAP1_TEXTURE_COORD_3: + *v = ctx->EvalMap.Map1Texture3.Order; + break; + case GL_MAP1_TEXTURE_COORD_4: + *v = ctx->EvalMap.Map1Texture4.Order; + break; + case GL_MAP1_VERTEX_3: + *v = ctx->EvalMap.Map1Vertex3.Order; + break; + case GL_MAP1_VERTEX_4: + *v = ctx->EvalMap.Map1Vertex4.Order; + break; + case GL_MAP2_COLOR_4: + v[0] = ctx->EvalMap.Map2Color4.Uorder; + v[1] = ctx->EvalMap.Map2Color4.Vorder; + break; + case GL_MAP2_INDEX: + v[0] = ctx->EvalMap.Map2Index.Uorder; + v[1] = ctx->EvalMap.Map2Index.Vorder; + break; + case GL_MAP2_NORMAL: + v[0] = ctx->EvalMap.Map2Normal.Uorder; + v[1] = ctx->EvalMap.Map2Normal.Vorder; + break; + case GL_MAP2_TEXTURE_COORD_1: + v[0] = ctx->EvalMap.Map2Texture1.Uorder; + v[1] = ctx->EvalMap.Map2Texture1.Vorder; + break; + case GL_MAP2_TEXTURE_COORD_2: + v[0] = ctx->EvalMap.Map2Texture2.Uorder; + v[1] = ctx->EvalMap.Map2Texture2.Vorder; + break; + case GL_MAP2_TEXTURE_COORD_3: + v[0] = ctx->EvalMap.Map2Texture3.Uorder; + v[1] = ctx->EvalMap.Map2Texture3.Vorder; + break; + case GL_MAP2_TEXTURE_COORD_4: + v[0] = ctx->EvalMap.Map2Texture4.Uorder; + v[1] = ctx->EvalMap.Map2Texture4.Vorder; + break; + case GL_MAP2_VERTEX_3: + v[0] = ctx->EvalMap.Map2Vertex3.Uorder; + v[1] = ctx->EvalMap.Map2Vertex3.Vorder; + break; + case GL_MAP2_VERTEX_4: + v[0] = ctx->EvalMap.Map2Vertex4.Uorder; + v[1] = ctx->EvalMap.Map2Vertex4.Vorder; + break; + default: + _mesa_error( ctx, GL_INVALID_ENUM, "glGetMapdv(target)" ); + return; + } + break; + case GL_DOMAIN: + switch (target) { + case GL_MAP1_COLOR_4: + v[0] = ctx->EvalMap.Map1Color4.u1; + v[1] = ctx->EvalMap.Map1Color4.u2; + break; + case GL_MAP1_INDEX: + v[0] = ctx->EvalMap.Map1Index.u1; + v[1] = ctx->EvalMap.Map1Index.u2; + break; + case GL_MAP1_NORMAL: + v[0] = ctx->EvalMap.Map1Normal.u1; + v[1] = ctx->EvalMap.Map1Normal.u2; + break; + case GL_MAP1_TEXTURE_COORD_1: + v[0] = ctx->EvalMap.Map1Texture1.u1; + v[1] = ctx->EvalMap.Map1Texture1.u2; + break; + case GL_MAP1_TEXTURE_COORD_2: + v[0] = ctx->EvalMap.Map1Texture2.u1; + v[1] = ctx->EvalMap.Map1Texture2.u2; + break; + case GL_MAP1_TEXTURE_COORD_3: + v[0] = ctx->EvalMap.Map1Texture3.u1; + v[1] = ctx->EvalMap.Map1Texture3.u2; + break; + case GL_MAP1_TEXTURE_COORD_4: + v[0] = ctx->EvalMap.Map1Texture4.u1; + v[1] = ctx->EvalMap.Map1Texture4.u2; + break; + case GL_MAP1_VERTEX_3: + v[0] = ctx->EvalMap.Map1Vertex3.u1; + v[1] = ctx->EvalMap.Map1Vertex3.u2; + break; + case GL_MAP1_VERTEX_4: + v[0] = ctx->EvalMap.Map1Vertex4.u1; + v[1] = ctx->EvalMap.Map1Vertex4.u2; + break; + case GL_MAP2_COLOR_4: + v[0] = ctx->EvalMap.Map2Color4.u1; + v[1] = ctx->EvalMap.Map2Color4.u2; + v[2] = ctx->EvalMap.Map2Color4.v1; + v[3] = ctx->EvalMap.Map2Color4.v2; + break; + case GL_MAP2_INDEX: + v[0] = ctx->EvalMap.Map2Index.u1; + v[1] = ctx->EvalMap.Map2Index.u2; + v[2] = ctx->EvalMap.Map2Index.v1; + v[3] = ctx->EvalMap.Map2Index.v2; + break; + case GL_MAP2_NORMAL: + v[0] = ctx->EvalMap.Map2Normal.u1; + v[1] = ctx->EvalMap.Map2Normal.u2; + v[2] = ctx->EvalMap.Map2Normal.v1; + v[3] = ctx->EvalMap.Map2Normal.v2; + break; + case GL_MAP2_TEXTURE_COORD_1: + v[0] = ctx->EvalMap.Map2Texture1.u1; + v[1] = ctx->EvalMap.Map2Texture1.u2; + v[2] = ctx->EvalMap.Map2Texture1.v1; + v[3] = ctx->EvalMap.Map2Texture1.v2; + break; + case GL_MAP2_TEXTURE_COORD_2: + v[0] = ctx->EvalMap.Map2Texture2.u1; + v[1] = ctx->EvalMap.Map2Texture2.u2; + v[2] = ctx->EvalMap.Map2Texture2.v1; + v[3] = ctx->EvalMap.Map2Texture2.v2; + break; + case GL_MAP2_TEXTURE_COORD_3: + v[0] = ctx->EvalMap.Map2Texture3.u1; + v[1] = ctx->EvalMap.Map2Texture3.u2; + v[2] = ctx->EvalMap.Map2Texture3.v1; + v[3] = ctx->EvalMap.Map2Texture3.v2; + break; + case GL_MAP2_TEXTURE_COORD_4: + v[0] = ctx->EvalMap.Map2Texture4.u1; + v[1] = ctx->EvalMap.Map2Texture4.u2; + v[2] = ctx->EvalMap.Map2Texture4.v1; + v[3] = ctx->EvalMap.Map2Texture4.v2; + break; + case GL_MAP2_VERTEX_3: + v[0] = ctx->EvalMap.Map2Vertex3.u1; + v[1] = ctx->EvalMap.Map2Vertex3.u2; + v[2] = ctx->EvalMap.Map2Vertex3.v1; + v[3] = ctx->EvalMap.Map2Vertex3.v2; + break; + case GL_MAP2_VERTEX_4: + v[0] = ctx->EvalMap.Map2Vertex4.u1; + v[1] = ctx->EvalMap.Map2Vertex4.u2; + v[2] = ctx->EvalMap.Map2Vertex4.v1; + v[3] = ctx->EvalMap.Map2Vertex4.v2; + break; + default: + _mesa_error( ctx, GL_INVALID_ENUM, "glGetMapdv(target)" ); + } + break; + default: + _mesa_error( ctx, GL_INVALID_ENUM, "glGetMapdv(query)" ); + } +} + + +void +_mesa_GetMapfv( GLenum target, GLenum query, GLfloat *v ) +{ + GET_CURRENT_CONTEXT(ctx); + GLint i, n; + GLfloat *data; + ASSERT_OUTSIDE_BEGIN_END(ctx); + + switch (query) { + case GL_COEFF: + switch (target) { + case GL_MAP1_COLOR_4: + data = ctx->EvalMap.Map1Color4.Points; + n = ctx->EvalMap.Map1Color4.Order * 4; + break; + case GL_MAP1_INDEX: + data = ctx->EvalMap.Map1Index.Points; + n = ctx->EvalMap.Map1Index.Order; + break; + case GL_MAP1_NORMAL: + data = ctx->EvalMap.Map1Normal.Points; + n = ctx->EvalMap.Map1Normal.Order * 3; + break; + case GL_MAP1_TEXTURE_COORD_1: + data = ctx->EvalMap.Map1Texture1.Points; + n = ctx->EvalMap.Map1Texture1.Order * 1; + break; + case GL_MAP1_TEXTURE_COORD_2: + data = ctx->EvalMap.Map1Texture2.Points; + n = ctx->EvalMap.Map1Texture2.Order * 2; + break; + case GL_MAP1_TEXTURE_COORD_3: + data = ctx->EvalMap.Map1Texture3.Points; + n = ctx->EvalMap.Map1Texture3.Order * 3; + break; + case GL_MAP1_TEXTURE_COORD_4: + data = ctx->EvalMap.Map1Texture4.Points; + n = ctx->EvalMap.Map1Texture4.Order * 4; + break; + case GL_MAP1_VERTEX_3: + data = ctx->EvalMap.Map1Vertex3.Points; + n = ctx->EvalMap.Map1Vertex3.Order * 3; + break; + case GL_MAP1_VERTEX_4: + data = ctx->EvalMap.Map1Vertex4.Points; + n = ctx->EvalMap.Map1Vertex4.Order * 4; + break; + case GL_MAP2_COLOR_4: + data = ctx->EvalMap.Map2Color4.Points; + n = ctx->EvalMap.Map2Color4.Uorder + * ctx->EvalMap.Map2Color4.Vorder * 4; + break; + case GL_MAP2_INDEX: + data = ctx->EvalMap.Map2Index.Points; + n = ctx->EvalMap.Map2Index.Uorder + * ctx->EvalMap.Map2Index.Vorder; + break; + case GL_MAP2_NORMAL: + data = ctx->EvalMap.Map2Normal.Points; + n = ctx->EvalMap.Map2Normal.Uorder + * ctx->EvalMap.Map2Normal.Vorder * 3; + break; + case GL_MAP2_TEXTURE_COORD_1: + data = ctx->EvalMap.Map2Texture1.Points; + n = ctx->EvalMap.Map2Texture1.Uorder + * ctx->EvalMap.Map2Texture1.Vorder * 1; + break; + case GL_MAP2_TEXTURE_COORD_2: + data = ctx->EvalMap.Map2Texture2.Points; + n = ctx->EvalMap.Map2Texture2.Uorder + * ctx->EvalMap.Map2Texture2.Vorder * 2; + break; + case GL_MAP2_TEXTURE_COORD_3: + data = ctx->EvalMap.Map2Texture3.Points; + n = ctx->EvalMap.Map2Texture3.Uorder + * ctx->EvalMap.Map2Texture3.Vorder * 3; + break; + case GL_MAP2_TEXTURE_COORD_4: + data = ctx->EvalMap.Map2Texture4.Points; + n = ctx->EvalMap.Map2Texture4.Uorder + * ctx->EvalMap.Map2Texture4.Vorder * 4; + break; + case GL_MAP2_VERTEX_3: + data = ctx->EvalMap.Map2Vertex3.Points; + n = ctx->EvalMap.Map2Vertex3.Uorder + * ctx->EvalMap.Map2Vertex3.Vorder * 3; + break; + case GL_MAP2_VERTEX_4: + data = ctx->EvalMap.Map2Vertex4.Points; + n = ctx->EvalMap.Map2Vertex4.Uorder + * ctx->EvalMap.Map2Vertex4.Vorder * 4; + break; + default: + _mesa_error( ctx, GL_INVALID_ENUM, "glGetMapfv(target)" ); + return; + } + if (data) { + for (i=0;iEvalMap.Map1Color4.Order; + break; + case GL_MAP1_INDEX: + *v = ctx->EvalMap.Map1Index.Order; + break; + case GL_MAP1_NORMAL: + *v = ctx->EvalMap.Map1Normal.Order; + break; + case GL_MAP1_TEXTURE_COORD_1: + *v = ctx->EvalMap.Map1Texture1.Order; + break; + case GL_MAP1_TEXTURE_COORD_2: + *v = ctx->EvalMap.Map1Texture2.Order; + break; + case GL_MAP1_TEXTURE_COORD_3: + *v = ctx->EvalMap.Map1Texture3.Order; + break; + case GL_MAP1_TEXTURE_COORD_4: + *v = ctx->EvalMap.Map1Texture4.Order; + break; + case GL_MAP1_VERTEX_3: + *v = ctx->EvalMap.Map1Vertex3.Order; + break; + case GL_MAP1_VERTEX_4: + *v = ctx->EvalMap.Map1Vertex4.Order; + break; + case GL_MAP2_COLOR_4: + v[0] = ctx->EvalMap.Map2Color4.Uorder; + v[1] = ctx->EvalMap.Map2Color4.Vorder; + break; + case GL_MAP2_INDEX: + v[0] = ctx->EvalMap.Map2Index.Uorder; + v[1] = ctx->EvalMap.Map2Index.Vorder; + break; + case GL_MAP2_NORMAL: + v[0] = ctx->EvalMap.Map2Normal.Uorder; + v[1] = ctx->EvalMap.Map2Normal.Vorder; + break; + case GL_MAP2_TEXTURE_COORD_1: + v[0] = ctx->EvalMap.Map2Texture1.Uorder; + v[1] = ctx->EvalMap.Map2Texture1.Vorder; + break; + case GL_MAP2_TEXTURE_COORD_2: + v[0] = ctx->EvalMap.Map2Texture2.Uorder; + v[1] = ctx->EvalMap.Map2Texture2.Vorder; + break; + case GL_MAP2_TEXTURE_COORD_3: + v[0] = ctx->EvalMap.Map2Texture3.Uorder; + v[1] = ctx->EvalMap.Map2Texture3.Vorder; + break; + case GL_MAP2_TEXTURE_COORD_4: + v[0] = ctx->EvalMap.Map2Texture4.Uorder; + v[1] = ctx->EvalMap.Map2Texture4.Vorder; + break; + case GL_MAP2_VERTEX_3: + v[0] = ctx->EvalMap.Map2Vertex3.Uorder; + v[1] = ctx->EvalMap.Map2Vertex3.Vorder; + break; + case GL_MAP2_VERTEX_4: + v[0] = ctx->EvalMap.Map2Vertex4.Uorder; + v[1] = ctx->EvalMap.Map2Vertex4.Vorder; + break; + default: + _mesa_error( ctx, GL_INVALID_ENUM, "glGetMapfv(target)" ); + return; + } + break; + case GL_DOMAIN: + switch (target) { + case GL_MAP1_COLOR_4: + v[0] = ctx->EvalMap.Map1Color4.u1; + v[1] = ctx->EvalMap.Map1Color4.u2; + break; + case GL_MAP1_INDEX: + v[0] = ctx->EvalMap.Map1Index.u1; + v[1] = ctx->EvalMap.Map1Index.u2; + break; + case GL_MAP1_NORMAL: + v[0] = ctx->EvalMap.Map1Normal.u1; + v[1] = ctx->EvalMap.Map1Normal.u2; + break; + case GL_MAP1_TEXTURE_COORD_1: + v[0] = ctx->EvalMap.Map1Texture1.u1; + v[1] = ctx->EvalMap.Map1Texture1.u2; + break; + case GL_MAP1_TEXTURE_COORD_2: + v[0] = ctx->EvalMap.Map1Texture2.u1; + v[1] = ctx->EvalMap.Map1Texture2.u2; + break; + case GL_MAP1_TEXTURE_COORD_3: + v[0] = ctx->EvalMap.Map1Texture3.u1; + v[1] = ctx->EvalMap.Map1Texture3.u2; + break; + case GL_MAP1_TEXTURE_COORD_4: + v[0] = ctx->EvalMap.Map1Texture4.u1; + v[1] = ctx->EvalMap.Map1Texture4.u2; + break; + case GL_MAP1_VERTEX_3: + v[0] = ctx->EvalMap.Map1Vertex3.u1; + v[1] = ctx->EvalMap.Map1Vertex3.u2; + break; + case GL_MAP1_VERTEX_4: + v[0] = ctx->EvalMap.Map1Vertex4.u1; + v[1] = ctx->EvalMap.Map1Vertex4.u2; + break; + case GL_MAP2_COLOR_4: + v[0] = ctx->EvalMap.Map2Color4.u1; + v[1] = ctx->EvalMap.Map2Color4.u2; + v[2] = ctx->EvalMap.Map2Color4.v1; + v[3] = ctx->EvalMap.Map2Color4.v2; + break; + case GL_MAP2_INDEX: + v[0] = ctx->EvalMap.Map2Index.u1; + v[1] = ctx->EvalMap.Map2Index.u2; + v[2] = ctx->EvalMap.Map2Index.v1; + v[3] = ctx->EvalMap.Map2Index.v2; + break; + case GL_MAP2_NORMAL: + v[0] = ctx->EvalMap.Map2Normal.u1; + v[1] = ctx->EvalMap.Map2Normal.u2; + v[2] = ctx->EvalMap.Map2Normal.v1; + v[3] = ctx->EvalMap.Map2Normal.v2; + break; + case GL_MAP2_TEXTURE_COORD_1: + v[0] = ctx->EvalMap.Map2Texture1.u1; + v[1] = ctx->EvalMap.Map2Texture1.u2; + v[2] = ctx->EvalMap.Map2Texture1.v1; + v[3] = ctx->EvalMap.Map2Texture1.v2; + break; + case GL_MAP2_TEXTURE_COORD_2: + v[0] = ctx->EvalMap.Map2Texture2.u1; + v[1] = ctx->EvalMap.Map2Texture2.u2; + v[2] = ctx->EvalMap.Map2Texture2.v1; + v[3] = ctx->EvalMap.Map2Texture2.v2; + break; + case GL_MAP2_TEXTURE_COORD_3: + v[0] = ctx->EvalMap.Map2Texture3.u1; + v[1] = ctx->EvalMap.Map2Texture3.u2; + v[2] = ctx->EvalMap.Map2Texture3.v1; + v[3] = ctx->EvalMap.Map2Texture3.v2; + break; + case GL_MAP2_TEXTURE_COORD_4: + v[0] = ctx->EvalMap.Map2Texture4.u1; + v[1] = ctx->EvalMap.Map2Texture4.u2; + v[2] = ctx->EvalMap.Map2Texture4.v1; + v[3] = ctx->EvalMap.Map2Texture4.v2; + break; + case GL_MAP2_VERTEX_3: + v[0] = ctx->EvalMap.Map2Vertex3.u1; + v[1] = ctx->EvalMap.Map2Vertex3.u2; + v[2] = ctx->EvalMap.Map2Vertex3.v1; + v[3] = ctx->EvalMap.Map2Vertex3.v2; + break; + case GL_MAP2_VERTEX_4: + v[0] = ctx->EvalMap.Map2Vertex4.u1; + v[1] = ctx->EvalMap.Map2Vertex4.u2; + v[2] = ctx->EvalMap.Map2Vertex4.v1; + v[3] = ctx->EvalMap.Map2Vertex4.v2; + break; + default: + _mesa_error( ctx, GL_INVALID_ENUM, "glGetMapfv(target)" ); + } + break; + default: + _mesa_error( ctx, GL_INVALID_ENUM, "glGetMapfv(query)" ); + } +} + + +void +_mesa_GetMapiv( GLenum target, GLenum query, GLint *v ) +{ + GET_CURRENT_CONTEXT(ctx); + GLuint i, n; + GLfloat *data; + ASSERT_OUTSIDE_BEGIN_END(ctx); + + switch (query) { + case GL_COEFF: + switch (target) { + case GL_MAP1_COLOR_4: + data = ctx->EvalMap.Map1Color4.Points; + n = ctx->EvalMap.Map1Color4.Order * 4; + break; + case GL_MAP1_INDEX: + data = ctx->EvalMap.Map1Index.Points; + n = ctx->EvalMap.Map1Index.Order; + break; + case GL_MAP1_NORMAL: + data = ctx->EvalMap.Map1Normal.Points; + n = ctx->EvalMap.Map1Normal.Order * 3; + break; + case GL_MAP1_TEXTURE_COORD_1: + data = ctx->EvalMap.Map1Texture1.Points; + n = ctx->EvalMap.Map1Texture1.Order * 1; + break; + case GL_MAP1_TEXTURE_COORD_2: + data = ctx->EvalMap.Map1Texture2.Points; + n = ctx->EvalMap.Map1Texture2.Order * 2; + break; + case GL_MAP1_TEXTURE_COORD_3: + data = ctx->EvalMap.Map1Texture3.Points; + n = ctx->EvalMap.Map1Texture3.Order * 3; + break; + case GL_MAP1_TEXTURE_COORD_4: + data = ctx->EvalMap.Map1Texture4.Points; + n = ctx->EvalMap.Map1Texture4.Order * 4; + break; + case GL_MAP1_VERTEX_3: + data = ctx->EvalMap.Map1Vertex3.Points; + n = ctx->EvalMap.Map1Vertex3.Order * 3; + break; + case GL_MAP1_VERTEX_4: + data = ctx->EvalMap.Map1Vertex4.Points; + n = ctx->EvalMap.Map1Vertex4.Order * 4; + break; + case GL_MAP2_COLOR_4: + data = ctx->EvalMap.Map2Color4.Points; + n = ctx->EvalMap.Map2Color4.Uorder + * ctx->EvalMap.Map2Color4.Vorder * 4; + break; + case GL_MAP2_INDEX: + data = ctx->EvalMap.Map2Index.Points; + n = ctx->EvalMap.Map2Index.Uorder + * ctx->EvalMap.Map2Index.Vorder; + break; + case GL_MAP2_NORMAL: + data = ctx->EvalMap.Map2Normal.Points; + n = ctx->EvalMap.Map2Normal.Uorder + * ctx->EvalMap.Map2Normal.Vorder * 3; + break; + case GL_MAP2_TEXTURE_COORD_1: + data = ctx->EvalMap.Map2Texture1.Points; + n = ctx->EvalMap.Map2Texture1.Uorder + * ctx->EvalMap.Map2Texture1.Vorder * 1; + break; + case GL_MAP2_TEXTURE_COORD_2: + data = ctx->EvalMap.Map2Texture2.Points; + n = ctx->EvalMap.Map2Texture2.Uorder + * ctx->EvalMap.Map2Texture2.Vorder * 2; + break; + case GL_MAP2_TEXTURE_COORD_3: + data = ctx->EvalMap.Map2Texture3.Points; + n = ctx->EvalMap.Map2Texture3.Uorder + * ctx->EvalMap.Map2Texture3.Vorder * 3; + break; + case GL_MAP2_TEXTURE_COORD_4: + data = ctx->EvalMap.Map2Texture4.Points; + n = ctx->EvalMap.Map2Texture4.Uorder + * ctx->EvalMap.Map2Texture4.Vorder * 4; + break; + case GL_MAP2_VERTEX_3: + data = ctx->EvalMap.Map2Vertex3.Points; + n = ctx->EvalMap.Map2Vertex3.Uorder + * ctx->EvalMap.Map2Vertex3.Vorder * 3; + break; + case GL_MAP2_VERTEX_4: + data = ctx->EvalMap.Map2Vertex4.Points; + n = ctx->EvalMap.Map2Vertex4.Uorder + * ctx->EvalMap.Map2Vertex4.Vorder * 4; + break; + default: + _mesa_error( ctx, GL_INVALID_ENUM, "glGetMapiv(target)" ); + return; + } + if (data) { + for (i=0;iEvalMap.Map1Color4.Order; + break; + case GL_MAP1_INDEX: + *v = ctx->EvalMap.Map1Index.Order; + break; + case GL_MAP1_NORMAL: + *v = ctx->EvalMap.Map1Normal.Order; + break; + case GL_MAP1_TEXTURE_COORD_1: + *v = ctx->EvalMap.Map1Texture1.Order; + break; + case GL_MAP1_TEXTURE_COORD_2: + *v = ctx->EvalMap.Map1Texture2.Order; + break; + case GL_MAP1_TEXTURE_COORD_3: + *v = ctx->EvalMap.Map1Texture3.Order; + break; + case GL_MAP1_TEXTURE_COORD_4: + *v = ctx->EvalMap.Map1Texture4.Order; + break; + case GL_MAP1_VERTEX_3: + *v = ctx->EvalMap.Map1Vertex3.Order; + break; + case GL_MAP1_VERTEX_4: + *v = ctx->EvalMap.Map1Vertex4.Order; + break; + case GL_MAP2_COLOR_4: + v[0] = ctx->EvalMap.Map2Color4.Uorder; + v[1] = ctx->EvalMap.Map2Color4.Vorder; + break; + case GL_MAP2_INDEX: + v[0] = ctx->EvalMap.Map2Index.Uorder; + v[1] = ctx->EvalMap.Map2Index.Vorder; + break; + case GL_MAP2_NORMAL: + v[0] = ctx->EvalMap.Map2Normal.Uorder; + v[1] = ctx->EvalMap.Map2Normal.Vorder; + break; + case GL_MAP2_TEXTURE_COORD_1: + v[0] = ctx->EvalMap.Map2Texture1.Uorder; + v[1] = ctx->EvalMap.Map2Texture1.Vorder; + break; + case GL_MAP2_TEXTURE_COORD_2: + v[0] = ctx->EvalMap.Map2Texture2.Uorder; + v[1] = ctx->EvalMap.Map2Texture2.Vorder; + break; + case GL_MAP2_TEXTURE_COORD_3: + v[0] = ctx->EvalMap.Map2Texture3.Uorder; + v[1] = ctx->EvalMap.Map2Texture3.Vorder; + break; + case GL_MAP2_TEXTURE_COORD_4: + v[0] = ctx->EvalMap.Map2Texture4.Uorder; + v[1] = ctx->EvalMap.Map2Texture4.Vorder; + break; + case GL_MAP2_VERTEX_3: + v[0] = ctx->EvalMap.Map2Vertex3.Uorder; + v[1] = ctx->EvalMap.Map2Vertex3.Vorder; + break; + case GL_MAP2_VERTEX_4: + v[0] = ctx->EvalMap.Map2Vertex4.Uorder; + v[1] = ctx->EvalMap.Map2Vertex4.Vorder; + break; + default: + _mesa_error( ctx, GL_INVALID_ENUM, "glGetMapiv(target)" ); + return; + } + break; + case GL_DOMAIN: + switch (target) { + case GL_MAP1_COLOR_4: + v[0] = ROUNDF(ctx->EvalMap.Map1Color4.u1); + v[1] = ROUNDF(ctx->EvalMap.Map1Color4.u2); + break; + case GL_MAP1_INDEX: + v[0] = ROUNDF(ctx->EvalMap.Map1Index.u1); + v[1] = ROUNDF(ctx->EvalMap.Map1Index.u2); + break; + case GL_MAP1_NORMAL: + v[0] = ROUNDF(ctx->EvalMap.Map1Normal.u1); + v[1] = ROUNDF(ctx->EvalMap.Map1Normal.u2); + break; + case GL_MAP1_TEXTURE_COORD_1: + v[0] = ROUNDF(ctx->EvalMap.Map1Texture1.u1); + v[1] = ROUNDF(ctx->EvalMap.Map1Texture1.u2); + break; + case GL_MAP1_TEXTURE_COORD_2: + v[0] = ROUNDF(ctx->EvalMap.Map1Texture2.u1); + v[1] = ROUNDF(ctx->EvalMap.Map1Texture2.u2); + break; + case GL_MAP1_TEXTURE_COORD_3: + v[0] = ROUNDF(ctx->EvalMap.Map1Texture3.u1); + v[1] = ROUNDF(ctx->EvalMap.Map1Texture3.u2); + break; + case GL_MAP1_TEXTURE_COORD_4: + v[0] = ROUNDF(ctx->EvalMap.Map1Texture4.u1); + v[1] = ROUNDF(ctx->EvalMap.Map1Texture4.u2); + break; + case GL_MAP1_VERTEX_3: + v[0] = ROUNDF(ctx->EvalMap.Map1Vertex3.u1); + v[1] = ROUNDF(ctx->EvalMap.Map1Vertex3.u2); + break; + case GL_MAP1_VERTEX_4: + v[0] = ROUNDF(ctx->EvalMap.Map1Vertex4.u1); + v[1] = ROUNDF(ctx->EvalMap.Map1Vertex4.u2); + break; + case GL_MAP2_COLOR_4: + v[0] = ROUNDF(ctx->EvalMap.Map2Color4.u1); + v[1] = ROUNDF(ctx->EvalMap.Map2Color4.u2); + v[2] = ROUNDF(ctx->EvalMap.Map2Color4.v1); + v[3] = ROUNDF(ctx->EvalMap.Map2Color4.v2); + break; + case GL_MAP2_INDEX: + v[0] = ROUNDF(ctx->EvalMap.Map2Index.u1); + v[1] = ROUNDF(ctx->EvalMap.Map2Index.u2); + v[2] = ROUNDF(ctx->EvalMap.Map2Index.v1); + v[3] = ROUNDF(ctx->EvalMap.Map2Index.v2); + break; + case GL_MAP2_NORMAL: + v[0] = ROUNDF(ctx->EvalMap.Map2Normal.u1); + v[1] = ROUNDF(ctx->EvalMap.Map2Normal.u2); + v[2] = ROUNDF(ctx->EvalMap.Map2Normal.v1); + v[3] = ROUNDF(ctx->EvalMap.Map2Normal.v2); + break; + case GL_MAP2_TEXTURE_COORD_1: + v[0] = ROUNDF(ctx->EvalMap.Map2Texture1.u1); + v[1] = ROUNDF(ctx->EvalMap.Map2Texture1.u2); + v[2] = ROUNDF(ctx->EvalMap.Map2Texture1.v1); + v[3] = ROUNDF(ctx->EvalMap.Map2Texture1.v2); + break; + case GL_MAP2_TEXTURE_COORD_2: + v[0] = ROUNDF(ctx->EvalMap.Map2Texture2.u1); + v[1] = ROUNDF(ctx->EvalMap.Map2Texture2.u2); + v[2] = ROUNDF(ctx->EvalMap.Map2Texture2.v1); + v[3] = ROUNDF(ctx->EvalMap.Map2Texture2.v2); + break; + case GL_MAP2_TEXTURE_COORD_3: + v[0] = ROUNDF(ctx->EvalMap.Map2Texture3.u1); + v[1] = ROUNDF(ctx->EvalMap.Map2Texture3.u2); + v[2] = ROUNDF(ctx->EvalMap.Map2Texture3.v1); + v[3] = ROUNDF(ctx->EvalMap.Map2Texture3.v2); + break; + case GL_MAP2_TEXTURE_COORD_4: + v[0] = ROUNDF(ctx->EvalMap.Map2Texture4.u1); + v[1] = ROUNDF(ctx->EvalMap.Map2Texture4.u2); + v[2] = ROUNDF(ctx->EvalMap.Map2Texture4.v1); + v[3] = ROUNDF(ctx->EvalMap.Map2Texture4.v2); + break; + case GL_MAP2_VERTEX_3: + v[0] = ROUNDF(ctx->EvalMap.Map2Vertex3.u1); + v[1] = ROUNDF(ctx->EvalMap.Map2Vertex3.u2); + v[2] = ROUNDF(ctx->EvalMap.Map2Vertex3.v1); + v[3] = ROUNDF(ctx->EvalMap.Map2Vertex3.v2); + break; + case GL_MAP2_VERTEX_4: + v[0] = ROUNDF(ctx->EvalMap.Map2Vertex4.u1); + v[1] = ROUNDF(ctx->EvalMap.Map2Vertex4.u2); + v[2] = ROUNDF(ctx->EvalMap.Map2Vertex4.v1); + v[3] = ROUNDF(ctx->EvalMap.Map2Vertex4.v2); + break; + default: + _mesa_error( ctx, GL_INVALID_ENUM, "glGetMapiv(target)" ); + } + break; + default: + _mesa_error( ctx, GL_INVALID_ENUM, "glGetMapiv(query)" ); + } +} + + + +void +_mesa_MapGrid1f( GLint un, GLfloat u1, GLfloat u2 ) +{ + GET_CURRENT_CONTEXT(ctx); + ASSERT_OUTSIDE_BEGIN_END(ctx); + + if (un<1) { + _mesa_error( ctx, GL_INVALID_VALUE, "glMapGrid1f" ); + return; + } + FLUSH_VERTICES(ctx, _NEW_EVAL); + ctx->Eval.MapGrid1un = un; + ctx->Eval.MapGrid1u1 = u1; + ctx->Eval.MapGrid1u2 = u2; + ctx->Eval.MapGrid1du = (u2 - u1) / (GLfloat) un; +} + + +void +_mesa_MapGrid1d( GLint un, GLdouble u1, GLdouble u2 ) +{ + _mesa_MapGrid1f( un, u1, u2 ); +} + + +void +_mesa_MapGrid2f( GLint un, GLfloat u1, GLfloat u2, + GLint vn, GLfloat v1, GLfloat v2 ) +{ + GET_CURRENT_CONTEXT(ctx); + ASSERT_OUTSIDE_BEGIN_END(ctx); + + if (un<1) { + _mesa_error( ctx, GL_INVALID_VALUE, "glMapGrid2f(un)" ); + return; + } + if (vn<1) { + _mesa_error( ctx, GL_INVALID_VALUE, "glMapGrid2f(vn)" ); + return; + } + + FLUSH_VERTICES(ctx, _NEW_EVAL); + ctx->Eval.MapGrid2un = un; + ctx->Eval.MapGrid2u1 = u1; + ctx->Eval.MapGrid2u2 = u2; + ctx->Eval.MapGrid2du = (u2 - u1) / (GLfloat) un; + ctx->Eval.MapGrid2vn = vn; + ctx->Eval.MapGrid2v1 = v1; + ctx->Eval.MapGrid2v2 = v2; + ctx->Eval.MapGrid2dv = (v2 - v1) / (GLfloat) vn; +} + + +void +_mesa_MapGrid2d( GLint un, GLdouble u1, GLdouble u2, + GLint vn, GLdouble v1, GLdouble v2 ) +{ + _mesa_MapGrid2f( un, u1, u2, vn, v1, v2 ); +} Index: dll/opengl/opengl32/mesa/eval.h =================================================================== --- dll/opengl/opengl32/mesa/eval.h (revision 0) +++ dll/opengl/opengl32/mesa/eval.h (working copy) @@ -0,0 +1,109 @@ +/* $Id: eval.h,v 1.6 2001/03/12 00:48:37 gareth Exp $ */ + +/* + * Mesa 3-D graphics library + * Version: 3.5 + * + * Copyright (C) 1999-2001 Brian Paul 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 + * BRIAN PAUL 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. + */ + + +#ifndef EVAL_H +#define EVAL_H + + +#include "mtypes.h" + + +extern void _mesa_init_eval( void ); + + +extern GLuint _mesa_evaluator_components( GLenum target ); + + +extern void gl_free_control_points( GLcontext *ctx, + GLenum target, GLfloat *data ); + + +extern GLfloat *_mesa_copy_map_points1f( GLenum target, + GLint ustride, GLint uorder, + const GLfloat *points ); + +extern GLfloat *_mesa_copy_map_points1d( GLenum target, + GLint ustride, GLint uorder, + const GLdouble *points ); + +extern GLfloat *_mesa_copy_map_points2f( GLenum target, + GLint ustride, GLint uorder, + GLint vstride, GLint vorder, + const GLfloat *points ); + +extern GLfloat *_mesa_copy_map_points2d(GLenum target, + GLint ustride, GLint uorder, + GLint vstride, GLint vorder, + const GLdouble *points ); + + + +extern void +_mesa_Map1f( GLenum target, GLfloat u1, GLfloat u2, GLint stride, + GLint order, const GLfloat *points ); + +extern void +_mesa_Map2f( GLenum target, + GLfloat u1, GLfloat u2, GLint ustride, GLint uorder, + GLfloat v1, GLfloat v2, GLint vstride, GLint vorder, + const GLfloat *points ); + +extern void +_mesa_Map1d( GLenum target, GLdouble u1, GLdouble u2, GLint stride, + GLint order, const GLdouble *points ); + +extern void +_mesa_Map2d( GLenum target, + GLdouble u1, GLdouble u2, GLint ustride, GLint uorder, + GLdouble v1, GLdouble v2, GLint vstride, GLint vorder, + const GLdouble *points ); + +extern void +_mesa_MapGrid1f( GLint un, GLfloat u1, GLfloat u2 ); + +extern void +_mesa_MapGrid1d( GLint un, GLdouble u1, GLdouble u2 ); + +extern void +_mesa_MapGrid2f( GLint un, GLfloat u1, GLfloat u2, + GLint vn, GLfloat v1, GLfloat v2 ); + +extern void +_mesa_MapGrid2d( GLint un, GLdouble u1, GLdouble u2, + GLint vn, GLdouble v1, GLdouble v2 ); + +extern void +_mesa_GetMapdv( GLenum target, GLenum query, GLdouble *v ); + +extern void +_mesa_GetMapfv( GLenum target, GLenum query, GLfloat *v ); + +extern void +_mesa_GetMapiv( GLenum target, GLenum query, GLint *v ); + + +#endif Index: dll/opengl/opengl32/mesa/extensions.c =================================================================== --- dll/opengl/opengl32/mesa/extensions.c (revision 0) +++ dll/opengl/opengl32/mesa/extensions.c (working copy) @@ -0,0 +1,400 @@ +/* $Id: extensions.c,v 1.62 2001/06/15 14:18:46 brianp Exp $ */ + +/* + * Mesa 3-D graphics library + * Version: 3.5 + * + * Copyright (C) 1999-2001 Brian Paul 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 + * BRIAN PAUL 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. + */ + + +#ifdef PC_HEADER +#include "all.h" +#else +#include "glheader.h" +#include "context.h" +#include "extensions.h" +#include "mem.h" +#include "simple_list.h" +#include "mtypes.h" +#endif + + +#define MAX_EXT_NAMELEN 80 + +struct extension { + struct extension *next, *prev; + GLint enabled; + GLboolean *flag; /* optional flag stored elsewhere */ + char name[MAX_EXT_NAMELEN+1]; + void (*notify)( GLcontext *, GLboolean ); +}; + +#define F(x) (int)&(((struct gl_extensions *)0)->x) +#define ON GL_TRUE +#define OFF GL_FALSE + +static struct { + GLboolean enabled; + const char *name; + int flag_offset; +} default_extensions[] = { + { OFF, "GL_ARB_imaging", F(ARB_imaging) }, + { OFF, "GL_ARB_multisample", F(ARB_multisample) }, + { OFF, "GL_ARB_multitexture", F(ARB_multitexture) }, + { OFF, "GL_ARB_texture_border_clamp", F(ARB_texture_border_clamp) }, + { OFF, "GL_ARB_texture_compression", F(ARB_texture_compression) }, + { OFF, "GL_ARB_texture_cube_map", F(ARB_texture_cube_map) }, + { OFF, "GL_ARB_texture_env_add", F(EXT_texture_env_add) }, + { OFF, "GL_ARB_texture_env_combine", F(ARB_texture_env_combine) }, + { OFF, "GL_ARB_texture_env_dot3", F(ARB_texture_env_dot3) }, + { ON, "GL_ARB_transpose_matrix", 0 }, + { ON, "GL_EXT_abgr", 0 }, + { ON, "GL_EXT_bgra", 0 }, + { OFF, "GL_EXT_blend_color", F(EXT_blend_color) }, + { OFF, "GL_EXT_blend_func_separate", F(EXT_blend_func_separate) }, + { OFF, "GL_EXT_blend_logic_op", F(EXT_blend_logic_op) }, + { OFF, "GL_EXT_blend_minmax", F(EXT_blend_minmax) }, + { OFF, "GL_EXT_blend_subtract", F(EXT_blend_subtract) }, + { ON, "GL_EXT_clip_volume_hint", F(EXT_clip_volume_hint) }, + { OFF, "GL_EXT_cull_vertex", 0 }, + { OFF, "GL_EXT_convolution", F(EXT_convolution) }, + { ON, "GL_EXT_compiled_vertex_array", F(EXT_compiled_vertex_array) }, + { OFF, "GL_EXT_fog_coord", F(EXT_fog_coord) }, + { OFF, "GL_EXT_histogram", F(EXT_histogram) }, + { ON, "GL_EXT_packed_pixels", F(EXT_packed_pixels) }, + { OFF, "GL_EXT_paletted_texture", F(EXT_paletted_texture) }, + { OFF, "GL_EXT_point_parameters", F(EXT_point_parameters) }, + { ON, "GL_EXT_polygon_offset", F(EXT_polygon_offset) }, + { ON, "GL_EXT_rescale_normal", F(EXT_rescale_normal) }, + { OFF, "GL_EXT_secondary_color", F(EXT_secondary_color) }, + { OFF, "GL_EXT_shared_texture_palette", F(EXT_shared_texture_palette) }, + { OFF, "GL_EXT_stencil_wrap", F(EXT_stencil_wrap) }, + { ON, "GL_EXT_texture3D", F(EXT_texture3D) }, + { OFF, "GL_EXT_texture_compression_s3tc", F(EXT_texture_compression_s3tc) }, + { OFF, "GL_EXT_texture_env_add", F(EXT_texture_env_add) }, + { OFF, "GL_EXT_texture_env_combine", F(EXT_texture_env_combine) }, + { OFF, "GL_EXT_texture_env_dot3", F(EXT_texture_env_dot3) }, + { OFF, "GL_EXT_texture_filter_anisotropic", F(EXT_texture_filter_anisotropic) }, + { ON, "GL_EXT_texture_object", F(EXT_texture_object) }, + { OFF, "GL_EXT_texture_lod_bias", F(EXT_texture_lod_bias) }, + { ON, "GL_EXT_vertex_array", 0 }, + { OFF, "GL_EXT_vertex_array_set", F(EXT_vertex_array_set) }, + { OFF, "GL_HP_occlusion_test", F(HP_occlusion_test) }, + { OFF, "GL_INGR_blend_func_separate", F(INGR_blend_func_separate) }, + { OFF, "GL_MESA_packed_depth_stencil", 0 }, + { OFF, "GL_MESA_resize_buffers", F(MESA_resize_buffers) }, + { ON, "GL_MESA_window_pos", F(MESA_window_pos) }, + { OFF, "GL_NV_blend_square", F(NV_blend_square) }, + { ON, "GL_NV_texgen_reflection", F(NV_texgen_reflection) }, + { OFF, "GL_SGI_color_matrix", F(SGI_color_matrix) }, + { OFF, "GL_SGI_color_table", F(SGI_color_table) }, + { OFF, "GL_SGIS_generate_mipmap", F(SGIS_generate_mipmap) }, + { OFF, "GL_SGIS_pixel_texture", F(SGIS_pixel_texture) }, + { OFF, "GL_SGIS_texture_border_clamp", F(ARB_texture_border_clamp) }, + { OFF, "GL_SGIS_texture_edge_clamp", F(SGIS_texture_edge_clamp) }, + { OFF, "GL_SGIX_depth_texture", F(SGIX_depth_texture) }, + { OFF, "GL_SGIX_pixel_texture", F(SGIX_pixel_texture) }, + { OFF, "GL_SGIX_shadow", F(SGIX_shadow) }, + { OFF, "GL_SGIX_shadow_ambient", F(SGIX_shadow_ambient) }, + { OFF, "GL_3DFX_texture_compression_FXT1", F(_3DFX_texture_compression_FXT1) } +}; + + + + +/* + * Enable all extensions suitable for a software-only renderer. + * This is a convenience function used by the XMesa, OSMesa, GGI drivers, etc. + */ +void +_mesa_enable_sw_extensions(GLcontext *ctx) +{ + const char *extensions[] = { + "GL_ARB_imaging", + "GL_ARB_multitexture", + "GL_ARB_texture_border_clamp", + "GL_ARB_texture_cube_map", + "GL_ARB_texture_env_add", + "GL_ARB_texture_env_combine", + "GL_ARB_texture_env_dot3", + "GL_EXT_blend_color", + "GL_EXT_blend_func_separate", + "GL_EXT_blend_logic_op", + "GL_EXT_blend_minmax", + "GL_EXT_blend_subtract", + "GL_EXT_convolution", + "GL_EXT_fog_coord", + "GL_EXT_histogram", + "GL_EXT_paletted_texture", + "GL_EXT_point_parameters", + "GL_EXT_secondary_color", + "GL_EXT_shared_texture_palette", + "GL_EXT_stencil_wrap", + "GL_EXT_texture_env_add", + "GL_EXT_texture_env_combine", + "GL_EXT_texture_env_dot3", + "GL_EXT_texture_lod_bias", + "GL_HP_occlusion_test", + "GL_INGR_blend_func_separate", + "GL_MESA_resize_buffers", + "GL_NV_blend_square", + "GL_NV_texgen_reflection", + "GL_SGI_color_matrix", + "GL_SGI_color_table", + "GL_SGIS_generate_mipmap", + "GL_SGIS_pixel_texture", + "GL_SGIS_texture_edge_clamp", + "GL_SGIS_texture_border_clamp", + "GL_SGIX_depth_texture", + "GL_SGIX_pixel_texture", + "GL_SGIX_shadow", + "GL_SGIX_shadow_ambient", + NULL + }; + GLuint i; + + for (i = 0; extensions[i]; i++) { + _mesa_enable_extension(ctx, extensions[i]); + } +} + + +/* + * Enable GL_ARB_imaging and all the EXT extensions that are subsets of it. + */ +void +_mesa_enable_imaging_extensions(GLcontext *ctx) +{ + const char *extensions[] = { + "GL_ARB_imaging", + "GL_EXT_blend_color", + "GL_EXT_blend_minmax", + "GL_EXT_blend_subtract", + "GL_EXT_convolution", + "GL_EXT_histogram", + "GL_SGI_color_matrix", + "GL_SGI_color_table", + NULL + }; + GLuint i; + + for (i = 0; extensions[i]; i++) { + _mesa_enable_extension(ctx, extensions[i]); + } +} + + + +/* + * Enable all OpenGL 1.3 features and extensions. + */ +void +_mesa_enable_1_3_extensions(GLcontext *ctx) +{ + const char *extensions[] = { + "GL_ARB_multisample", + "GL_ARB_multitexture", + "GL_ARB_texture_border_clamp", + "GL_ARB_texture_compression", + "GL_ARB_texture_cube_map", + "GL_ARB_texture_env_add", + "GL_ARB_texture_env_combine", + "GL_ARB_texture_env_dot3", + "GL_ARB_transpose_matrix", + NULL + }; + GLuint i; + + for (i = 0; extensions[i]; i++) { + _mesa_enable_extension(ctx, extensions[i]); + } +} + + + +/* + * Add a new extenstion. This would be called from a Mesa driver. + */ +void +_mesa_add_extension( GLcontext *ctx, + GLboolean enabled, + const char *name, + GLboolean *flag_ptr ) +{ + /* We should never try to add an extension after + * _mesa_extensions_get_string() has been called! + */ + assert(ctx->Extensions.ext_string == 0); + + { + struct extension *t = MALLOC_STRUCT(extension); + t->enabled = enabled; + strncpy(t->name, name, MAX_EXT_NAMELEN); + t->name[MAX_EXT_NAMELEN] = 0; + t->flag = flag_ptr; + if (t->flag) + *t->flag = enabled; + insert_at_tail( ctx->Extensions.ext_list, t ); + } +} + + +/* + * Either enable or disable the named extension. + */ +static void +set_extension( GLcontext *ctx, const char *name, GLint state ) +{ + /* XXX we should assert that ext_string is null. We should never be + * enabling/disabling extensions after _mesa_extensions_get_string() + * has been called! + */ + struct extension *i; + foreach( i, ctx->Extensions.ext_list ) + if (strncmp(i->name, name, MAX_EXT_NAMELEN) == 0) + break; + + if (i == ctx->Extensions.ext_list) { + /* this is an error. Drivers should never try to enable/disable + * an extension which is unknown to Mesa or wasn't added by calling + * _mesa_add_extension(). + */ + return; + } + + if (i->flag) + *(i->flag) = state; + i->enabled = state; +} + + + +void +_mesa_enable_extension( GLcontext *ctx, const char *name ) +{ + if (ctx->Extensions.ext_string == 0) + set_extension( ctx, name, 1 ); +} + + +void +_mesa_disable_extension( GLcontext *ctx, const char *name ) +{ + if (ctx->Extensions.ext_string == 0) + set_extension( ctx, name, 0 ); +} + + +/* + * Test if the named extension is enabled in this context. + */ +GLboolean +_mesa_extension_is_enabled( GLcontext *ctx, const char *name) +{ + struct extension *i; + foreach( i, ctx->Extensions.ext_list ) + if (strncmp(i->name, name, MAX_EXT_NAMELEN) == 0) { + if (i->enabled) + return GL_TRUE; + else + return GL_FALSE; + } + + return GL_FALSE; +} + + +void +_mesa_extensions_dtr( GLcontext *ctx ) +{ + struct extension *i, *nexti; + + if (ctx->Extensions.ext_string) { + FREE( ctx->Extensions.ext_string ); + ctx->Extensions.ext_string = 0; + } + + if (ctx->Extensions.ext_list) { + foreach_s( i, nexti, ctx->Extensions.ext_list ) { + remove_from_list( i ); + FREE( i ); + } + + FREE(ctx->Extensions.ext_list); + ctx->Extensions.ext_list = 0; + } +} + + +void +_mesa_extensions_ctr( GLcontext *ctx ) +{ + GLuint i; + GLboolean *base = (GLboolean *)&ctx->Extensions; + + ctx->Extensions.ext_string = NULL; + ctx->Extensions.ext_list = MALLOC_STRUCT(extension); + make_empty_list( ctx->Extensions.ext_list ); + + for (i = 0 ; i < Elements(default_extensions) ; i++) { + GLboolean *ptr = NULL; + + if (default_extensions[i].flag_offset) + ptr = base + default_extensions[i].flag_offset; + + (void) _mesa_add_extension( ctx, + default_extensions[i].enabled, + default_extensions[i].name, + ptr); + } +} + + +const char * +_mesa_extensions_get_string( GLcontext *ctx ) +{ + if (ctx->Extensions.ext_string == 0) + { + struct extension *i; + char *str; + GLuint len = 0; + foreach (i, ctx->Extensions.ext_list) + if (i->enabled) + len += strlen(i->name) + 1; + + if (len == 0) + return ""; + + str = (char *)MALLOC(len * sizeof(char)); + ctx->Extensions.ext_string = str; + + foreach (i, ctx->Extensions.ext_list) + if (i->enabled) { + strcpy(str, i->name); + str += strlen(str); + *str++ = ' '; + } + + *(str-1) = 0; + } + + return ctx->Extensions.ext_string; +} Index: dll/opengl/opengl32/mesa/extensions.h =================================================================== --- dll/opengl/opengl32/mesa/extensions.h (revision 0) +++ dll/opengl/opengl32/mesa/extensions.h (working copy) @@ -0,0 +1,55 @@ +/* $Id: extensions.h,v 1.14 2001/06/15 14:18:46 brianp Exp $ */ + +/* + * Mesa 3-D graphics library + * Version: 3.5 + * + * Copyright (C) 1999-2001 Brian Paul 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 + * BRIAN PAUL 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. + */ + + +#ifndef _EXTENSIONS_H_ +#define _EXTENSIONS_H_ + +#include "mtypes.h" + + +extern void _mesa_enable_sw_extensions(GLcontext *ctx); + +extern void _mesa_enable_imaging_extensions(GLcontext *ctx); + +extern void _mesa_enable_1_3_extensions(GLcontext *ctx); + +extern void _mesa_add_extension( GLcontext *ctx, GLboolean enabled, + const char *name, GLboolean *flag_ptr ); + +extern void _mesa_enable_extension( GLcontext *ctx, const char *name ); + +extern void _mesa_disable_extension( GLcontext *ctx, const char *name ); + +extern GLboolean _mesa_extension_is_enabled( GLcontext *ctx, const char *name); + +extern void _mesa_extensions_dtr( GLcontext *ctx ); + +extern void _mesa_extensions_ctr( GLcontext *ctx ); + +extern const char *_mesa_extensions_get_string( GLcontext *ctx ); + +#endif Index: dll/opengl/opengl32/mesa/feedback.c =================================================================== --- dll/opengl/opengl32/mesa/feedback.c (revision 0) +++ dll/opengl/opengl32/mesa/feedback.c (working copy) @@ -0,0 +1,409 @@ +/* $Id: feedback.c,v 1.24 2001/03/29 17:08:26 keithw Exp $ */ + +/* + * Mesa 3-D graphics library + * Version: 3.5 + * + * Copyright (C) 1999-2001 Brian Paul 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 + * BRIAN PAUL 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. + */ + + +#ifdef PC_HEADER +#include "all.h" +#else +#include "glheader.h" +#include "colormac.h" +#include "context.h" +#include "enums.h" +#include "feedback.h" +#include "macros.h" +#include "mmath.h" +#include "mtypes.h" +#endif + + + +#define FB_3D 0x01 +#define FB_4D 0x02 +#define FB_INDEX 0x04 +#define FB_COLOR 0x08 +#define FB_TEXTURE 0X10 + + + +void +_mesa_FeedbackBuffer( GLsizei size, GLenum type, GLfloat *buffer ) +{ + GET_CURRENT_CONTEXT(ctx); + ASSERT_OUTSIDE_BEGIN_END(ctx); + + if (ctx->RenderMode==GL_FEEDBACK) { + _mesa_error( ctx, GL_INVALID_OPERATION, "glFeedbackBuffer" ); + return; + } + if (size<0) { + _mesa_error( ctx, GL_INVALID_VALUE, "glFeedbackBuffer(size<0)" ); + return; + } + if (!buffer) { + _mesa_error( ctx, GL_INVALID_VALUE, "glFeedbackBuffer(buffer==NULL)" ); + ctx->Feedback.BufferSize = 0; + return; + } + + switch (type) { + case GL_2D: + ctx->Feedback._Mask = 0; + break; + case GL_3D: + ctx->Feedback._Mask = FB_3D; + break; + case GL_3D_COLOR: + ctx->Feedback._Mask = (FB_3D | + (ctx->Visual.rgbMode ? FB_COLOR : FB_INDEX)); + break; + case GL_3D_COLOR_TEXTURE: + ctx->Feedback._Mask = (FB_3D | + (ctx->Visual.rgbMode ? FB_COLOR : FB_INDEX) | + FB_TEXTURE); + break; + case GL_4D_COLOR_TEXTURE: + ctx->Feedback._Mask = (FB_3D | FB_4D | + (ctx->Visual.rgbMode ? FB_COLOR : FB_INDEX) | + FB_TEXTURE); + break; + default: + _mesa_error( ctx, GL_INVALID_ENUM, "glFeedbackBuffer" ); + return; + } + + FLUSH_VERTICES(ctx, _NEW_RENDERMODE); /* Always flush */ + ctx->Feedback.Type = type; + ctx->Feedback.BufferSize = size; + ctx->Feedback.Buffer = buffer; + ctx->Feedback.Count = 0; /* Becaues of this. */ +} + + +void +_mesa_PassThrough( GLfloat token ) +{ + GET_CURRENT_CONTEXT(ctx); + ASSERT_OUTSIDE_BEGIN_END(ctx); + + if (ctx->RenderMode==GL_FEEDBACK) { + FLUSH_VERTICES(ctx, 0); + FEEDBACK_TOKEN( ctx, (GLfloat) (GLint) GL_PASS_THROUGH_TOKEN ); + FEEDBACK_TOKEN( ctx, token ); + } +} + + + +/* + * Put a vertex into the feedback buffer. + */ +void _mesa_feedback_vertex( GLcontext *ctx, + const GLfloat win[4], + const GLfloat color[4], + GLuint index, + const GLfloat texcoord[4] ) +{ + FEEDBACK_TOKEN( ctx, win[0] ); + FEEDBACK_TOKEN( ctx, win[1] ); + if (ctx->Feedback._Mask & FB_3D) { + FEEDBACK_TOKEN( ctx, win[2] ); + } + if (ctx->Feedback._Mask & FB_4D) { + FEEDBACK_TOKEN( ctx, win[3] ); + } + if (ctx->Feedback._Mask & FB_INDEX) { + FEEDBACK_TOKEN( ctx, (GLfloat) index ); + } + if (ctx->Feedback._Mask & FB_COLOR) { + FEEDBACK_TOKEN( ctx, color[0] ); + FEEDBACK_TOKEN( ctx, color[1] ); + FEEDBACK_TOKEN( ctx, color[2] ); + FEEDBACK_TOKEN( ctx, color[3] ); + } + if (ctx->Feedback._Mask & FB_TEXTURE) { + FEEDBACK_TOKEN( ctx, texcoord[0] ); + FEEDBACK_TOKEN( ctx, texcoord[1] ); + FEEDBACK_TOKEN( ctx, texcoord[2] ); + FEEDBACK_TOKEN( ctx, texcoord[3] ); + } +} + + +/**********************************************************************/ +/* Selection */ +/**********************************************************************/ + + +/* + * NOTE: this function can't be put in a display list. + */ +void +_mesa_SelectBuffer( GLsizei size, GLuint *buffer ) +{ + GET_CURRENT_CONTEXT(ctx); + ASSERT_OUTSIDE_BEGIN_END(ctx); + + if (ctx->RenderMode==GL_SELECT) { + _mesa_error( ctx, GL_INVALID_OPERATION, "glSelectBuffer" ); + return; /* KW: added return */ + } + + FLUSH_VERTICES(ctx, _NEW_RENDERMODE); /* why bother? */ + ctx->Select.Buffer = buffer; + ctx->Select.BufferSize = size; + ctx->Select.BufferCount = 0; + ctx->Select.HitFlag = GL_FALSE; + ctx->Select.HitMinZ = 1.0; + ctx->Select.HitMaxZ = 0.0; +} + + +#define WRITE_RECORD( CTX, V ) \ + if (CTX->Select.BufferCount < CTX->Select.BufferSize) { \ + CTX->Select.Buffer[CTX->Select.BufferCount] = (V); \ + } \ + CTX->Select.BufferCount++; + + + +void _mesa_update_hitflag( GLcontext *ctx, GLfloat z ) +{ + ctx->Select.HitFlag = GL_TRUE; + if (z < ctx->Select.HitMinZ) { + ctx->Select.HitMinZ = z; + } + if (z > ctx->Select.HitMaxZ) { + ctx->Select.HitMaxZ = z; + } +} + + +static void write_hit_record( GLcontext *ctx ) +{ + GLuint i; + GLuint zmin, zmax, zscale = (~0u); + + /* HitMinZ and HitMaxZ are in [0,1]. Multiply these values by */ + /* 2^32-1 and round to nearest unsigned integer. */ + + assert( ctx != NULL ); /* this line magically fixes a SunOS 5.x/gcc bug */ + zmin = (GLuint) ((GLfloat) zscale * ctx->Select.HitMinZ); + zmax = (GLuint) ((GLfloat) zscale * ctx->Select.HitMaxZ); + + WRITE_RECORD( ctx, ctx->Select.NameStackDepth ); + WRITE_RECORD( ctx, zmin ); + WRITE_RECORD( ctx, zmax ); + for (i = 0; i < ctx->Select.NameStackDepth; i++) { + WRITE_RECORD( ctx, ctx->Select.NameStack[i] ); + } + + ctx->Select.Hits++; + ctx->Select.HitFlag = GL_FALSE; + ctx->Select.HitMinZ = 1.0; + ctx->Select.HitMaxZ = -1.0; +} + + + +void +_mesa_InitNames( void ) +{ + GET_CURRENT_CONTEXT(ctx); + ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx); + + /* Record the hit before the HitFlag is wiped out again. */ + if (ctx->RenderMode == GL_SELECT) { + if (ctx->Select.HitFlag) { + write_hit_record( ctx ); + } + } + ctx->Select.NameStackDepth = 0; + ctx->Select.HitFlag = GL_FALSE; + ctx->Select.HitMinZ = 1.0; + ctx->Select.HitMaxZ = 0.0; + ctx->NewState |= _NEW_RENDERMODE; +} + + + +void +_mesa_LoadName( GLuint name ) +{ + GET_CURRENT_CONTEXT(ctx); + ASSERT_OUTSIDE_BEGIN_END(ctx); + + if (ctx->RenderMode != GL_SELECT) { + return; + } + if (ctx->Select.NameStackDepth == 0) { + _mesa_error( ctx, GL_INVALID_OPERATION, "glLoadName" ); + return; + } + + FLUSH_VERTICES(ctx, _NEW_RENDERMODE); + + if (ctx->Select.HitFlag) { + write_hit_record( ctx ); + } + if (ctx->Select.NameStackDepth < MAX_NAME_STACK_DEPTH) { + ctx->Select.NameStack[ctx->Select.NameStackDepth-1] = name; + } + else { + ctx->Select.NameStack[MAX_NAME_STACK_DEPTH-1] = name; + } +} + + +void +_mesa_PushName( GLuint name ) +{ + GET_CURRENT_CONTEXT(ctx); + ASSERT_OUTSIDE_BEGIN_END(ctx); + + if (ctx->RenderMode != GL_SELECT) { + return; + } + + FLUSH_VERTICES(ctx, _NEW_RENDERMODE); + if (ctx->Select.HitFlag) { + write_hit_record( ctx ); + } + if (ctx->Select.NameStackDepth >= MAX_NAME_STACK_DEPTH) { + _mesa_error( ctx, GL_STACK_OVERFLOW, "glPushName" ); + } + else + ctx->Select.NameStack[ctx->Select.NameStackDepth++] = name; +} + + + +void +_mesa_PopName( void ) +{ + GET_CURRENT_CONTEXT(ctx); + ASSERT_OUTSIDE_BEGIN_END(ctx); + + if (ctx->RenderMode != GL_SELECT) { + return; + } + + FLUSH_VERTICES(ctx, _NEW_RENDERMODE); + if (ctx->Select.HitFlag) { + write_hit_record( ctx ); + } + if (ctx->Select.NameStackDepth == 0) { + _mesa_error( ctx, GL_STACK_UNDERFLOW, "glPopName" ); + } + else + ctx->Select.NameStackDepth--; +} + + + +/**********************************************************************/ +/* Render Mode */ +/**********************************************************************/ + + + +/* + * NOTE: this function can't be put in a display list. + */ +GLint +_mesa_RenderMode( GLenum mode ) +{ + GET_CURRENT_CONTEXT(ctx); + GLint result; + ASSERT_OUTSIDE_BEGIN_END_WITH_RETVAL(ctx, 0); + + if (MESA_VERBOSE & VERBOSE_API) + fprintf(stderr, "glRenderMode %s\n", _mesa_lookup_enum_by_nr(mode)); + + FLUSH_VERTICES(ctx, _NEW_RENDERMODE); + + switch (ctx->RenderMode) { + case GL_RENDER: + result = 0; + break; + case GL_SELECT: + if (ctx->Select.HitFlag) { + write_hit_record( ctx ); + } + if (ctx->Select.BufferCount > ctx->Select.BufferSize) { + /* overflow */ +#ifdef DEBUG + _mesa_warning(ctx, "Feedback buffer overflow"); +#endif + result = -1; + } + else { + result = ctx->Select.Hits; + } + ctx->Select.BufferCount = 0; + ctx->Select.Hits = 0; + ctx->Select.NameStackDepth = 0; + break; + case GL_FEEDBACK: + if (ctx->Feedback.Count > ctx->Feedback.BufferSize) { + /* overflow */ + result = -1; + } + else { + result = ctx->Feedback.Count; + } + ctx->Feedback.Count = 0; + break; + default: + _mesa_error( ctx, GL_INVALID_ENUM, "glRenderMode" ); + return 0; + } + + switch (mode) { + case GL_RENDER: + break; + case GL_SELECT: + if (ctx->Select.BufferSize==0) { + /* haven't called glSelectBuffer yet */ + _mesa_error( ctx, GL_INVALID_OPERATION, "glRenderMode" ); + } + break; + case GL_FEEDBACK: + if (ctx->Feedback.BufferSize==0) { + /* haven't called glFeedbackBuffer yet */ + _mesa_error( ctx, GL_INVALID_OPERATION, "glRenderMode" ); + } + break; + default: + _mesa_error( ctx, GL_INVALID_ENUM, "glRenderMode" ); + return 0; + } + + ctx->RenderMode = mode; + if (ctx->Driver.RenderMode) + ctx->Driver.RenderMode( ctx, mode ); + + return result; +} Index: dll/opengl/opengl32/mesa/feedback.h =================================================================== --- dll/opengl/opengl32/mesa/feedback.h (revision 0) +++ dll/opengl/opengl32/mesa/feedback.h (working copy) @@ -0,0 +1,77 @@ +/* $Id: feedback.h,v 1.7 2001/03/12 00:48:37 gareth Exp $ */ + +/* + * Mesa 3-D graphics library + * Version: 3.5 + * + * Copyright (C) 1999-2001 Brian Paul 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 + * BRIAN PAUL 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. + */ + + +#ifndef FEEDBACK_H +#define FEEDBACK_H + + +#include "mtypes.h" + + +#define FEEDBACK_TOKEN( CTX, T ) \ + if (CTX->Feedback.Count < CTX->Feedback.BufferSize) { \ + CTX->Feedback.Buffer[CTX->Feedback.Count] = (GLfloat) (T); \ + } \ + CTX->Feedback.Count++; + + +extern void _mesa_feedback_vertex( GLcontext *ctx, + const GLfloat win[4], + const GLfloat color[4], + GLuint index, + const GLfloat texcoord[4] ); + + +extern void _mesa_update_hitflag( GLcontext *ctx, GLfloat z ); + + +extern void +_mesa_PassThrough( GLfloat token ); + +extern void +_mesa_FeedbackBuffer( GLsizei size, GLenum type, GLfloat *buffer ); + +extern void +_mesa_SelectBuffer( GLsizei size, GLuint *buffer ); + +extern void +_mesa_InitNames( void ); + +extern void +_mesa_LoadName( GLuint name ); + +extern void +_mesa_PushName( GLuint name ); + +extern void +_mesa_PopName( void ); + +extern GLint +_mesa_RenderMode( GLenum mode ); + + +#endif Index: dll/opengl/opengl32/mesa/fog.c =================================================================== --- dll/opengl/opengl32/mesa/fog.c (revision 0) +++ dll/opengl/opengl32/mesa/fog.c (working copy) @@ -0,0 +1,164 @@ +/* $Id: fog.c,v 1.35 2001/05/30 14:43:17 brianp Exp $ */ + +/* + * Mesa 3-D graphics library + * Version: 3.5 + * + * Copyright (C) 1999-2001 Brian Paul 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 + * BRIAN PAUL 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. + */ + + +#ifdef PC_HEADER +#include "all.h" +#else +#include "glheader.h" +#include "colormac.h" +#include "context.h" +#include "fog.h" +#include "mtypes.h" +#endif + + + +void +_mesa_Fogf(GLenum pname, GLfloat param) +{ + _mesa_Fogfv(pname, ¶m); +} + + +void +_mesa_Fogi(GLenum pname, GLint param ) +{ + GLfloat fparam = (GLfloat) param; + _mesa_Fogfv(pname, &fparam); +} + + +void +_mesa_Fogiv(GLenum pname, const GLint *params ) +{ + GLfloat p[4]; + switch (pname) { + case GL_FOG_MODE: + case GL_FOG_DENSITY: + case GL_FOG_START: + case GL_FOG_END: + case GL_FOG_INDEX: + case GL_FOG_COORDINATE_SOURCE_EXT: + p[0] = (GLfloat) *params; + break; + case GL_FOG_COLOR: + p[0] = INT_TO_FLOAT( params[0] ); + p[1] = INT_TO_FLOAT( params[1] ); + p[2] = INT_TO_FLOAT( params[2] ); + p[3] = INT_TO_FLOAT( params[3] ); + break; + default: + /* Error will be caught later in _mesa_Fogfv */ + ; + } + _mesa_Fogfv(pname, p); +} + + +void +_mesa_Fogfv( GLenum pname, const GLfloat *params ) +{ + GET_CURRENT_CONTEXT(ctx); + GLenum m; + ASSERT_OUTSIDE_BEGIN_END(ctx); + + switch (pname) { + case GL_FOG_MODE: + m = (GLenum) (GLint) *params; + switch (m) { + case GL_LINEAR: + case GL_EXP: + case GL_EXP2: + break; + default: + _mesa_error( ctx, GL_INVALID_ENUM, "glFog" ); + return; + } + if (ctx->Fog.Mode == m) + return; + FLUSH_VERTICES(ctx, _NEW_FOG); + ctx->Fog.Mode = m; + break; + case GL_FOG_DENSITY: + if (*params<0.0) { + _mesa_error( ctx, GL_INVALID_VALUE, "glFog" ); + return; + } + if (ctx->Fog.Density == *params) + return; + FLUSH_VERTICES(ctx, _NEW_FOG); + ctx->Fog.Density = *params; + break; + case GL_FOG_START: + if (ctx->Fog.Start == *params) + return; + FLUSH_VERTICES(ctx, _NEW_FOG); + ctx->Fog.Start = *params; + break; + case GL_FOG_END: + if (ctx->Fog.End == *params) + return; + FLUSH_VERTICES(ctx, _NEW_FOG); + ctx->Fog.End = *params; + break; + case GL_FOG_INDEX: + if (ctx->Fog.Index == *params) + return; + FLUSH_VERTICES(ctx, _NEW_FOG); + ctx->Fog.Index = *params; + break; + case GL_FOG_COLOR: + if (TEST_EQ_4V(ctx->Fog.Color, params)) + return; + FLUSH_VERTICES(ctx, _NEW_FOG); + ctx->Fog.Color[0] = params[0]; + ctx->Fog.Color[1] = params[1]; + ctx->Fog.Color[2] = params[2]; + ctx->Fog.Color[3] = params[3]; + break; + case GL_FOG_COORDINATE_SOURCE_EXT: { + GLenum p = (GLenum) (GLint) *params; + if (!ctx->Extensions.EXT_fog_coord || + (p != GL_FOG_COORDINATE_EXT && p != GL_FRAGMENT_DEPTH_EXT)) { + _mesa_error(ctx, GL_INVALID_ENUM, "glFog"); + return; + } + if (ctx->Fog.FogCoordinateSource == p) + return; + FLUSH_VERTICES(ctx, _NEW_FOG); + ctx->Fog.FogCoordinateSource = p; + break; + } + default: + _mesa_error( ctx, GL_INVALID_ENUM, "glFog" ); + return; + } + + if (ctx->Driver.Fogfv) { + (*ctx->Driver.Fogfv)( ctx, pname, params ); + } +} Index: dll/opengl/opengl32/mesa/fog.h =================================================================== --- dll/opengl/opengl32/mesa/fog.h (revision 0) +++ dll/opengl/opengl32/mesa/fog.h (working copy) @@ -0,0 +1,52 @@ +/* $Id: fog.h,v 1.12 2001/03/12 00:48:37 gareth Exp $ */ + +/* + * Mesa 3-D graphics library + * Version: 3.5 + * + * Copyright (C) 1999-2001 Brian Paul 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 + * BRIAN PAUL 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. + */ + + +#ifndef FOG_H +#define FOG_H + + +#include "mtypes.h" + + + +extern void +_mesa_Fogf(GLenum pname, GLfloat param); + + +extern void +_mesa_Fogi(GLenum pname, GLint param ); + + +extern void +_mesa_Fogfv(GLenum pname, const GLfloat *params ); + + +extern void +_mesa_Fogiv(GLenum pname, const GLint *params ); + + +#endif Index: dll/opengl/opengl32/mesa/get.c =================================================================== --- dll/opengl/opengl32/mesa/get.c (revision 0) +++ dll/opengl/opengl32/mesa/get.c (working copy) @@ -0,0 +1,5264 @@ +/* $Id: get.c,v 1.64 2001/06/20 18:54:43 brianp Exp $ */ + +/* + * Mesa 3-D graphics library + * Version: 3.5 + * + * Copyright (C) 1999-2001 Brian Paul 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 + * BRIAN PAUL 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. + */ + + +#ifdef PC_HEADER +#include "all.h" +#else +#include "glheader.h" +#include "colormac.h" +#include "context.h" +#include "enable.h" +#include "enums.h" +#include "extensions.h" +#include "get.h" +#include "macros.h" +#include "mmath.h" +#include "mtypes.h" + +#include "math/m_matrix.h" +#endif + + + +#define FLOAT_TO_BOOL(X) ( (X)==0.0F ? GL_FALSE : GL_TRUE ) +#define INT_TO_BOOL(I) ( (I)==0 ? GL_FALSE : GL_TRUE ) +#define ENUM_TO_BOOL(E) ( (E)==0 ? GL_FALSE : GL_TRUE ) + +#ifdef SPECIALCAST +/* Needed for an Amiga compiler */ +#define ENUM_TO_FLOAT(X) ((GLfloat)(GLint)(X)) +#define ENUM_TO_DOUBLE(X) ((GLdouble)(GLint)(X)) +#else +/* all other compilers */ +#define ENUM_TO_FLOAT(X) ((GLfloat)(X)) +#define ENUM_TO_DOUBLE(X) ((GLdouble)(X)) +#endif + + + +static GLenum +pixel_texgen_mode(const GLcontext *ctx) +{ + if (ctx->Pixel.FragmentRgbSource == GL_CURRENT_RASTER_POSITION) { + if (ctx->Pixel.FragmentAlphaSource == GL_CURRENT_RASTER_POSITION) { + return GL_RGBA; + } + else { + return GL_RGB; + } + } + else { + if (ctx->Pixel.FragmentAlphaSource == GL_CURRENT_RASTER_POSITION) { + return GL_ALPHA; + } + else { + return GL_NONE; + } + } +} + + +void +_mesa_GetBooleanv( GLenum pname, GLboolean *params ) +{ + GET_CURRENT_CONTEXT(ctx); + GLuint i; + GLuint texUnit = ctx->Texture.CurrentUnit; + const struct gl_texture_unit *textureUnit = &ctx->Texture.Unit[texUnit]; + ASSERT_OUTSIDE_BEGIN_END(ctx); + + if (!params) + return; + + /* We need this in order to get correct results for + * GL_OCCLUSION_TEST_RESULT_HP. There might be other important cases. + */ + FLUSH_VERTICES(ctx, 0); + + if (MESA_VERBOSE & VERBOSE_API) + fprintf(stderr, "glGetBooleanv %s\n", _mesa_lookup_enum_by_nr(pname)); + + if (ctx->Driver.GetBooleanv + && (*ctx->Driver.GetBooleanv)(ctx, pname, params)) + return; + + switch (pname) { + case GL_ACCUM_RED_BITS: + *params = INT_TO_BOOL(ctx->Visual.accumRedBits); + break; + case GL_ACCUM_GREEN_BITS: + *params = INT_TO_BOOL(ctx->Visual.accumGreenBits); + break; + case GL_ACCUM_BLUE_BITS: + *params = INT_TO_BOOL(ctx->Visual.accumBlueBits); + break; + case GL_ACCUM_ALPHA_BITS: + *params = INT_TO_BOOL(ctx->Visual.accumAlphaBits); + break; + case GL_ACCUM_CLEAR_VALUE: + params[0] = FLOAT_TO_BOOL(ctx->Accum.ClearColor[0]); + params[1] = FLOAT_TO_BOOL(ctx->Accum.ClearColor[1]); + params[2] = FLOAT_TO_BOOL(ctx->Accum.ClearColor[2]); + params[3] = FLOAT_TO_BOOL(ctx->Accum.ClearColor[3]); + break; + case GL_ALPHA_BIAS: + *params = FLOAT_TO_BOOL(ctx->Pixel.AlphaBias); + break; + case GL_ALPHA_BITS: + *params = INT_TO_BOOL(ctx->Visual.alphaBits); + break; + case GL_ALPHA_SCALE: + *params = FLOAT_TO_BOOL(ctx->Pixel.AlphaScale); + break; + case GL_ALPHA_TEST: + *params = ctx->Color.AlphaEnabled; + break; + case GL_ALPHA_TEST_FUNC: + *params = ENUM_TO_BOOL(ctx->Color.AlphaFunc); + break; + case GL_ALPHA_TEST_REF: + *params = FLOAT_TO_BOOL((GLfloat) ctx->Color.AlphaRef / CHAN_MAXF); + break; + case GL_ATTRIB_STACK_DEPTH: + *params = INT_TO_BOOL(ctx->AttribStackDepth); + break; + case GL_AUTO_NORMAL: + *params = ctx->Eval.AutoNormal; + break; + case GL_AUX_BUFFERS: + *params = (ctx->Const.NumAuxBuffers) ? GL_TRUE : GL_FALSE; + break; + case GL_BLEND: + *params = ctx->Color.BlendEnabled; + break; + case GL_BLEND_DST: + *params = ENUM_TO_BOOL(ctx->Color.BlendDstRGB); + break; + case GL_BLEND_SRC: + *params = ENUM_TO_BOOL(ctx->Color.BlendSrcRGB); + break; + case GL_BLEND_SRC_RGB_EXT: + *params = ENUM_TO_BOOL(ctx->Color.BlendSrcRGB); + break; + case GL_BLEND_DST_RGB_EXT: + *params = ENUM_TO_BOOL(ctx->Color.BlendDstRGB); + break; + case GL_BLEND_SRC_ALPHA_EXT: + *params = ENUM_TO_BOOL(ctx->Color.BlendSrcA); + break; + case GL_BLEND_DST_ALPHA_EXT: + *params = ENUM_TO_BOOL(ctx->Color.BlendDstA); + break; + case GL_BLEND_EQUATION_EXT: + *params = ENUM_TO_BOOL( ctx->Color.BlendEquation ); + break; + case GL_BLEND_COLOR_EXT: + params[0] = FLOAT_TO_BOOL( ctx->Color.BlendColor[0] ); + params[1] = FLOAT_TO_BOOL( ctx->Color.BlendColor[1] ); + params[2] = FLOAT_TO_BOOL( ctx->Color.BlendColor[2] ); + params[3] = FLOAT_TO_BOOL( ctx->Color.BlendColor[3] ); + break; + case GL_BLUE_BIAS: + *params = FLOAT_TO_BOOL(ctx->Pixel.BlueBias); + break; + case GL_BLUE_BITS: + *params = INT_TO_BOOL( ctx->Visual.blueBits ); + break; + case GL_BLUE_SCALE: + *params = FLOAT_TO_BOOL(ctx->Pixel.BlueScale); + break; + case GL_CLIENT_ATTRIB_STACK_DEPTH: + *params = INT_TO_BOOL(ctx->ClientAttribStackDepth); + break; + case GL_CLIP_PLANE0: + case GL_CLIP_PLANE1: + case GL_CLIP_PLANE2: + case GL_CLIP_PLANE3: + case GL_CLIP_PLANE4: + case GL_CLIP_PLANE5: + *params = ctx->Transform.ClipEnabled[pname-GL_CLIP_PLANE0]; + break; + case GL_COLOR_CLEAR_VALUE: + params[0] = ctx->Color.ClearColor[0] ? GL_TRUE : GL_FALSE; + params[1] = ctx->Color.ClearColor[1] ? GL_TRUE : GL_FALSE; + params[2] = ctx->Color.ClearColor[2] ? GL_TRUE : GL_FALSE; + params[3] = ctx->Color.ClearColor[3] ? GL_TRUE : GL_FALSE; + break; + case GL_COLOR_MATERIAL: + *params = ctx->Light.ColorMaterialEnabled; + break; + case GL_COLOR_MATERIAL_FACE: + *params = ENUM_TO_BOOL(ctx->Light.ColorMaterialFace); + break; + case GL_COLOR_MATERIAL_PARAMETER: + *params = ENUM_TO_BOOL(ctx->Light.ColorMaterialMode); + break; + case GL_COLOR_WRITEMASK: + params[0] = ctx->Color.ColorMask[RCOMP] ? GL_TRUE : GL_FALSE; + params[1] = ctx->Color.ColorMask[GCOMP] ? GL_TRUE : GL_FALSE; + params[2] = ctx->Color.ColorMask[BCOMP] ? GL_TRUE : GL_FALSE; + params[3] = ctx->Color.ColorMask[ACOMP] ? GL_TRUE : GL_FALSE; + break; + case GL_CULL_FACE: + *params = ctx->Polygon.CullFlag; + break; + case GL_CULL_FACE_MODE: + *params = ENUM_TO_BOOL(ctx->Polygon.CullFaceMode); + break; + case GL_CURRENT_COLOR: + FLUSH_CURRENT(ctx, 0); + params[0] = FLOAT_TO_BOOL(ctx->Current.Color[0]); + params[1] = FLOAT_TO_BOOL(ctx->Current.Color[1]); + params[2] = FLOAT_TO_BOOL(ctx->Current.Color[2]); + params[3] = FLOAT_TO_BOOL(ctx->Current.Color[3]); + break; + case GL_CURRENT_INDEX: + FLUSH_CURRENT(ctx, 0); + *params = INT_TO_BOOL(ctx->Current.Index); + break; + case GL_CURRENT_NORMAL: + FLUSH_CURRENT(ctx, 0); + params[0] = FLOAT_TO_BOOL(ctx->Current.Normal[0]); + params[1] = FLOAT_TO_BOOL(ctx->Current.Normal[1]); + params[2] = FLOAT_TO_BOOL(ctx->Current.Normal[2]); + break; + case GL_CURRENT_RASTER_COLOR: + params[0] = FLOAT_TO_BOOL(ctx->Current.RasterColor[0]); + params[1] = FLOAT_TO_BOOL(ctx->Current.RasterColor[1]); + params[2] = FLOAT_TO_BOOL(ctx->Current.RasterColor[2]); + params[3] = FLOAT_TO_BOOL(ctx->Current.RasterColor[3]); + break; + case GL_CURRENT_RASTER_DISTANCE: + *params = FLOAT_TO_BOOL(ctx->Current.RasterDistance); + break; + case GL_CURRENT_RASTER_INDEX: + *params = FLOAT_TO_BOOL(ctx->Current.RasterIndex); + break; + case GL_CURRENT_RASTER_POSITION: + params[0] = FLOAT_TO_BOOL(ctx->Current.RasterPos[0]); + params[1] = FLOAT_TO_BOOL(ctx->Current.RasterPos[1]); + params[2] = FLOAT_TO_BOOL(ctx->Current.RasterPos[2]); + params[3] = FLOAT_TO_BOOL(ctx->Current.RasterPos[3]); + break; + case GL_CURRENT_RASTER_TEXTURE_COORDS: + params[0] = FLOAT_TO_BOOL(ctx->Current.RasterMultiTexCoord[texUnit][0]); + params[1] = FLOAT_TO_BOOL(ctx->Current.RasterMultiTexCoord[texUnit][1]); + params[2] = FLOAT_TO_BOOL(ctx->Current.RasterMultiTexCoord[texUnit][2]); + params[3] = FLOAT_TO_BOOL(ctx->Current.RasterMultiTexCoord[texUnit][3]); + break; + case GL_CURRENT_RASTER_POSITION_VALID: + *params = ctx->Current.RasterPosValid; + break; + case GL_CURRENT_TEXTURE_COORDS: + FLUSH_CURRENT(ctx, 0); + params[0] = FLOAT_TO_BOOL(ctx->Current.Texcoord[texUnit][0]); + params[1] = FLOAT_TO_BOOL(ctx->Current.Texcoord[texUnit][1]); + params[2] = FLOAT_TO_BOOL(ctx->Current.Texcoord[texUnit][2]); + params[3] = FLOAT_TO_BOOL(ctx->Current.Texcoord[texUnit][3]); + break; + case GL_DEPTH_BIAS: + *params = FLOAT_TO_BOOL(ctx->Pixel.DepthBias); + break; + case GL_DEPTH_BITS: + *params = INT_TO_BOOL(ctx->Visual.depthBits); + break; + case GL_DEPTH_CLEAR_VALUE: + *params = FLOAT_TO_BOOL(ctx->Depth.Clear); + break; + case GL_DEPTH_FUNC: + *params = ENUM_TO_BOOL(ctx->Depth.Func); + break; + case GL_DEPTH_RANGE: + params[0] = FLOAT_TO_BOOL(ctx->Viewport.Near); + params[1] = FLOAT_TO_BOOL(ctx->Viewport.Far); + break; + case GL_DEPTH_SCALE: + *params = FLOAT_TO_BOOL(ctx->Pixel.DepthScale); + break; + case GL_DEPTH_TEST: + *params = ctx->Depth.Test; + break; + case GL_DEPTH_WRITEMASK: + *params = ctx->Depth.Mask; + break; + case GL_DITHER: + *params = ctx->Color.DitherFlag; + break; + case GL_DOUBLEBUFFER: + *params = ctx->Visual.doubleBufferMode; + break; + case GL_DRAW_BUFFER: + *params = ENUM_TO_BOOL(ctx->Color.DrawBuffer); + break; + case GL_EDGE_FLAG: + FLUSH_CURRENT(ctx, 0); + *params = ctx->Current.EdgeFlag; + break; + case GL_FEEDBACK_BUFFER_SIZE: + *params = INT_TO_BOOL(ctx->Feedback.BufferSize); + break; + case GL_FEEDBACK_BUFFER_TYPE: + *params = INT_TO_BOOL(ctx->Feedback.Type); + break; + case GL_FOG: + *params = ctx->Fog.Enabled; + break; + case GL_FOG_COLOR: + params[0] = FLOAT_TO_BOOL(ctx->Fog.Color[0]); + params[1] = FLOAT_TO_BOOL(ctx->Fog.Color[1]); + params[2] = FLOAT_TO_BOOL(ctx->Fog.Color[2]); + params[3] = FLOAT_TO_BOOL(ctx->Fog.Color[3]); + break; + case GL_FOG_DENSITY: + *params = FLOAT_TO_BOOL(ctx->Fog.Density); + break; + case GL_FOG_END: + *params = FLOAT_TO_BOOL(ctx->Fog.End); + break; + case GL_FOG_HINT: + *params = ENUM_TO_BOOL(ctx->Hint.Fog); + break; + case GL_FOG_INDEX: + *params = FLOAT_TO_BOOL(ctx->Fog.Index); + break; + case GL_FOG_MODE: + *params = ENUM_TO_BOOL(ctx->Fog.Mode); + break; + case GL_FOG_START: + *params = FLOAT_TO_BOOL(ctx->Fog.End); + break; + case GL_FRONT_FACE: + *params = ENUM_TO_BOOL(ctx->Polygon.FrontFace); + break; + case GL_GREEN_BIAS: + *params = FLOAT_TO_BOOL(ctx->Pixel.GreenBias); + break; + case GL_GREEN_BITS: + *params = INT_TO_BOOL( ctx->Visual.greenBits ); + break; + case GL_GREEN_SCALE: + *params = FLOAT_TO_BOOL(ctx->Pixel.GreenScale); + break; + case GL_HISTOGRAM: + if (ctx->Extensions.EXT_histogram) { + *params = ctx->Pixel.HistogramEnabled; + } + else { + _mesa_error(ctx, GL_INVALID_ENUM, "glGetBooleanv"); + return; + } + break; + case GL_INDEX_BITS: + *params = INT_TO_BOOL( ctx->Visual.indexBits ); + break; + case GL_INDEX_CLEAR_VALUE: + *params = INT_TO_BOOL(ctx->Color.ClearIndex); + break; + case GL_INDEX_MODE: + *params = ctx->Visual.rgbMode ? GL_FALSE : GL_TRUE; + break; + case GL_INDEX_OFFSET: + *params = INT_TO_BOOL(ctx->Pixel.IndexOffset); + break; + case GL_INDEX_SHIFT: + *params = INT_TO_BOOL(ctx->Pixel.IndexShift); + break; + case GL_INDEX_WRITEMASK: + *params = INT_TO_BOOL(ctx->Color.IndexMask); + break; + case GL_LIGHT0: + case GL_LIGHT1: + case GL_LIGHT2: + case GL_LIGHT3: + case GL_LIGHT4: + case GL_LIGHT5: + case GL_LIGHT6: + case GL_LIGHT7: + *params = ctx->Light.Light[pname-GL_LIGHT0].Enabled; + break; + case GL_LIGHTING: + *params = ctx->Light.Enabled; + break; + case GL_LIGHT_MODEL_AMBIENT: + params[0] = FLOAT_TO_BOOL(ctx->Light.Model.Ambient[0]); + params[1] = FLOAT_TO_BOOL(ctx->Light.Model.Ambient[1]); + params[2] = FLOAT_TO_BOOL(ctx->Light.Model.Ambient[2]); + params[3] = FLOAT_TO_BOOL(ctx->Light.Model.Ambient[3]); + break; + case GL_LIGHT_MODEL_COLOR_CONTROL: + params[0] = ENUM_TO_BOOL(ctx->Light.Model.ColorControl); + break; + case GL_LIGHT_MODEL_LOCAL_VIEWER: + *params = ctx->Light.Model.LocalViewer; + break; + case GL_LIGHT_MODEL_TWO_SIDE: + *params = ctx->Light.Model.TwoSide; + break; + case GL_LINE_SMOOTH: + *params = ctx->Line.SmoothFlag; + break; + case GL_LINE_SMOOTH_HINT: + *params = ENUM_TO_BOOL(ctx->Hint.LineSmooth); + break; + case GL_LINE_STIPPLE: + *params = ctx->Line.StippleFlag; + break; + case GL_LINE_STIPPLE_PATTERN: + *params = INT_TO_BOOL(ctx->Line.StipplePattern); + break; + case GL_LINE_STIPPLE_REPEAT: + *params = INT_TO_BOOL(ctx->Line.StippleFactor); + break; + case GL_LINE_WIDTH: + *params = FLOAT_TO_BOOL(ctx->Line.Width); + break; + case GL_LINE_WIDTH_GRANULARITY: + *params = FLOAT_TO_BOOL(ctx->Const.LineWidthGranularity); + break; + case GL_LINE_WIDTH_RANGE: + params[0] = FLOAT_TO_BOOL(ctx->Const.MinLineWidthAA); + params[1] = FLOAT_TO_BOOL(ctx->Const.MaxLineWidthAA); + break; + case GL_ALIASED_LINE_WIDTH_RANGE: + params[0] = FLOAT_TO_BOOL(ctx->Const.MinLineWidth); + params[1] = FLOAT_TO_BOOL(ctx->Const.MaxLineWidth); + break; + case GL_LIST_BASE: + *params = INT_TO_BOOL(ctx->List.ListBase); + break; + case GL_LIST_INDEX: + *params = INT_TO_BOOL( ctx->CurrentListNum ); + break; + case GL_LIST_MODE: + *params = ENUM_TO_BOOL( ctx->ExecuteFlag + ? GL_COMPILE_AND_EXECUTE : GL_COMPILE ); + break; + case GL_INDEX_LOGIC_OP: + *params = ctx->Color.IndexLogicOpEnabled; + break; + case GL_COLOR_LOGIC_OP: + *params = ctx->Color.ColorLogicOpEnabled; + break; + case GL_LOGIC_OP_MODE: + *params = ENUM_TO_BOOL(ctx->Color.LogicOp); + break; + case GL_MAP1_COLOR_4: + *params = ctx->Eval.Map1Color4; + break; + case GL_MAP1_GRID_DOMAIN: + params[0] = FLOAT_TO_BOOL(ctx->Eval.MapGrid1u1); + params[1] = FLOAT_TO_BOOL(ctx->Eval.MapGrid1u2); + break; + case GL_MAP1_GRID_SEGMENTS: + *params = INT_TO_BOOL(ctx->Eval.MapGrid1un); + break; + case GL_MAP1_INDEX: + *params = ctx->Eval.Map1Index; + break; + case GL_MAP1_NORMAL: + *params = ctx->Eval.Map1Normal; + break; + case GL_MAP1_TEXTURE_COORD_1: + *params = ctx->Eval.Map1TextureCoord1; + break; + case GL_MAP1_TEXTURE_COORD_2: + *params = ctx->Eval.Map1TextureCoord2; + break; + case GL_MAP1_TEXTURE_COORD_3: + *params = ctx->Eval.Map1TextureCoord3; + break; + case GL_MAP1_TEXTURE_COORD_4: + *params = ctx->Eval.Map1TextureCoord4; + break; + case GL_MAP1_VERTEX_3: + *params = ctx->Eval.Map1Vertex3; + break; + case GL_MAP1_VERTEX_4: + *params = ctx->Eval.Map1Vertex4; + break; + case GL_MAP2_COLOR_4: + *params = ctx->Eval.Map2Color4; + break; + case GL_MAP2_GRID_DOMAIN: + params[0] = FLOAT_TO_BOOL(ctx->Eval.MapGrid2u1); + params[1] = FLOAT_TO_BOOL(ctx->Eval.MapGrid2u2); + params[2] = FLOAT_TO_BOOL(ctx->Eval.MapGrid2v1); + params[3] = FLOAT_TO_BOOL(ctx->Eval.MapGrid2v2); + break; + case GL_MAP2_GRID_SEGMENTS: + params[0] = INT_TO_BOOL(ctx->Eval.MapGrid2un); + params[1] = INT_TO_BOOL(ctx->Eval.MapGrid2vn); + break; + case GL_MAP2_INDEX: + *params = ctx->Eval.Map2Index; + break; + case GL_MAP2_NORMAL: + *params = ctx->Eval.Map2Normal; + break; + case GL_MAP2_TEXTURE_COORD_1: + *params = ctx->Eval.Map2TextureCoord1; + break; + case GL_MAP2_TEXTURE_COORD_2: + *params = ctx->Eval.Map2TextureCoord2; + break; + case GL_MAP2_TEXTURE_COORD_3: + *params = ctx->Eval.Map2TextureCoord3; + break; + case GL_MAP2_TEXTURE_COORD_4: + *params = ctx->Eval.Map2TextureCoord4; + break; + case GL_MAP2_VERTEX_3: + *params = ctx->Eval.Map2Vertex3; + break; + case GL_MAP2_VERTEX_4: + *params = ctx->Eval.Map2Vertex4; + break; + case GL_MAP_COLOR: + *params = ctx->Pixel.MapColorFlag; + break; + case GL_MAP_STENCIL: + *params = ctx->Pixel.MapStencilFlag; + break; + case GL_MATRIX_MODE: + *params = ENUM_TO_BOOL( ctx->Transform.MatrixMode ); + break; + case GL_MAX_ATTRIB_STACK_DEPTH: + *params = INT_TO_BOOL(MAX_ATTRIB_STACK_DEPTH); + break; + case GL_MAX_CLIENT_ATTRIB_STACK_DEPTH: + *params = INT_TO_BOOL( MAX_CLIENT_ATTRIB_STACK_DEPTH); + break; + case GL_MAX_CLIP_PLANES: + *params = INT_TO_BOOL(ctx->Const.MaxClipPlanes); + break; + case GL_MAX_ELEMENTS_VERTICES: /* GL_VERSION_1_2 */ + *params = INT_TO_BOOL(ctx->Const.MaxArrayLockSize); + break; + case GL_MAX_ELEMENTS_INDICES: /* GL_VERSION_1_2 */ + *params = INT_TO_BOOL(ctx->Const.MaxArrayLockSize); + break; + case GL_MAX_EVAL_ORDER: + *params = INT_TO_BOOL(MAX_EVAL_ORDER); + break; + case GL_MAX_LIGHTS: + *params = INT_TO_BOOL(ctx->Const.MaxLights); + break; + case GL_MAX_LIST_NESTING: + *params = INT_TO_BOOL(MAX_LIST_NESTING); + break; + case GL_MAX_MODELVIEW_STACK_DEPTH: + *params = INT_TO_BOOL(MAX_MODELVIEW_STACK_DEPTH); + break; + case GL_MAX_NAME_STACK_DEPTH: + *params = INT_TO_BOOL(MAX_NAME_STACK_DEPTH); + break; + case GL_MAX_PIXEL_MAP_TABLE: + *params = INT_TO_BOOL(MAX_PIXEL_MAP_TABLE); + break; + case GL_MAX_PROJECTION_STACK_DEPTH: + *params = INT_TO_BOOL(MAX_PROJECTION_STACK_DEPTH); + break; + case GL_MAX_TEXTURE_SIZE: + *params = INT_TO_BOOL(1 << (ctx->Const.MaxTextureLevels - 1)); + break; + case GL_MAX_3D_TEXTURE_SIZE: + *params = INT_TO_BOOL(1 << (ctx->Const.Max3DTextureLevels - 1)); + break; + case GL_MAX_TEXTURE_STACK_DEPTH: + *params = INT_TO_BOOL(MAX_TEXTURE_STACK_DEPTH); + break; + case GL_MAX_VIEWPORT_DIMS: + params[0] = INT_TO_BOOL(MAX_WIDTH); + params[1] = INT_TO_BOOL(MAX_HEIGHT); + break; + case GL_MINMAX: + *params = ctx->Pixel.MinMaxEnabled; + break; + case GL_MODELVIEW_MATRIX: + for (i=0;i<16;i++) { + params[i] = FLOAT_TO_BOOL(ctx->ModelView.m[i]); + } + break; + case GL_MODELVIEW_STACK_DEPTH: + *params = INT_TO_BOOL(ctx->ModelViewStackDepth + 1); + break; + case GL_NAME_STACK_DEPTH: + *params = INT_TO_BOOL(ctx->Select.NameStackDepth); + break; + case GL_NORMALIZE: + *params = ctx->Transform.Normalize; + break; + case GL_PACK_ALIGNMENT: + *params = INT_TO_BOOL(ctx->Pack.Alignment); + break; + case GL_PACK_LSB_FIRST: + *params = ctx->Pack.LsbFirst; + break; + case GL_PACK_ROW_LENGTH: + *params = INT_TO_BOOL(ctx->Pack.RowLength); + break; + case GL_PACK_SKIP_PIXELS: + *params = INT_TO_BOOL(ctx->Pack.SkipPixels); + break; + case GL_PACK_SKIP_ROWS: + *params = INT_TO_BOOL(ctx->Pack.SkipRows); + break; + case GL_PACK_SWAP_BYTES: + *params = ctx->Pack.SwapBytes; + break; + case GL_PACK_SKIP_IMAGES_EXT: + *params = ctx->Pack.SkipImages; + break; + case GL_PACK_IMAGE_HEIGHT_EXT: + *params = ctx->Pack.ImageHeight; + break; + case GL_PERSPECTIVE_CORRECTION_HINT: + *params = ENUM_TO_BOOL(ctx->Hint.PerspectiveCorrection); + break; + case GL_PIXEL_MAP_A_TO_A_SIZE: + *params = INT_TO_BOOL(ctx->Pixel.MapAtoAsize); + break; + case GL_PIXEL_MAP_B_TO_B_SIZE: + *params = INT_TO_BOOL(ctx->Pixel.MapBtoBsize); + break; + case GL_PIXEL_MAP_G_TO_G_SIZE: + *params = INT_TO_BOOL(ctx->Pixel.MapGtoGsize); + break; + case GL_PIXEL_MAP_I_TO_A_SIZE: + *params = INT_TO_BOOL(ctx->Pixel.MapItoAsize); + break; + case GL_PIXEL_MAP_I_TO_B_SIZE: + *params = INT_TO_BOOL(ctx->Pixel.MapItoBsize); + break; + case GL_PIXEL_MAP_I_TO_G_SIZE: + *params = INT_TO_BOOL(ctx->Pixel.MapItoGsize); + break; + case GL_PIXEL_MAP_I_TO_I_SIZE: + *params = INT_TO_BOOL(ctx->Pixel.MapItoIsize); + break; + case GL_PIXEL_MAP_I_TO_R_SIZE: + *params = INT_TO_BOOL(ctx->Pixel.MapItoRsize); + break; + case GL_PIXEL_MAP_R_TO_R_SIZE: + *params = INT_TO_BOOL(ctx->Pixel.MapRtoRsize); + break; + case GL_PIXEL_MAP_S_TO_S_SIZE: + *params = INT_TO_BOOL(ctx->Pixel.MapStoSsize); + break; + case GL_POINT_SIZE: + *params = FLOAT_TO_BOOL(ctx->Point.Size); + break; + case GL_POINT_SIZE_GRANULARITY: + *params = FLOAT_TO_BOOL(ctx->Const.PointSizeGranularity ); + break; + case GL_POINT_SIZE_RANGE: + params[0] = FLOAT_TO_BOOL(ctx->Const.MinPointSizeAA); + params[1] = FLOAT_TO_BOOL(ctx->Const.MaxPointSizeAA); + break; + case GL_ALIASED_POINT_SIZE_RANGE: + params[0] = FLOAT_TO_BOOL(ctx->Const.MinPointSize); + params[1] = FLOAT_TO_BOOL(ctx->Const.MaxPointSize); + break; + case GL_POINT_SMOOTH: + *params = ctx->Point.SmoothFlag; + break; + case GL_POINT_SMOOTH_HINT: + *params = ENUM_TO_BOOL(ctx->Hint.PointSmooth); + break; + case GL_POINT_SIZE_MIN_EXT: + *params = FLOAT_TO_BOOL(ctx->Point.MinSize); + break; + case GL_POINT_SIZE_MAX_EXT: + *params = FLOAT_TO_BOOL(ctx->Point.MaxSize); + break; + case GL_POINT_FADE_THRESHOLD_SIZE_EXT: + *params = FLOAT_TO_BOOL(ctx->Point.Threshold); + break; + case GL_DISTANCE_ATTENUATION_EXT: + params[0] = FLOAT_TO_BOOL(ctx->Point.Params[0]); + params[1] = FLOAT_TO_BOOL(ctx->Point.Params[1]); + params[2] = FLOAT_TO_BOOL(ctx->Point.Params[2]); + break; + case GL_POLYGON_MODE: + params[0] = ENUM_TO_BOOL(ctx->Polygon.FrontMode); + params[1] = ENUM_TO_BOOL(ctx->Polygon.BackMode); + break; + case GL_POLYGON_OFFSET_BIAS_EXT: /* GL_EXT_polygon_offset */ + *params = FLOAT_TO_BOOL( ctx->Polygon.OffsetUnits ); + break; + case GL_POLYGON_OFFSET_FACTOR: + *params = FLOAT_TO_BOOL( ctx->Polygon.OffsetFactor ); + break; + case GL_POLYGON_OFFSET_UNITS: + *params = FLOAT_TO_BOOL( ctx->Polygon.OffsetUnits ); + break; + case GL_POLYGON_SMOOTH: + *params = ctx->Polygon.SmoothFlag; + break; + case GL_POLYGON_SMOOTH_HINT: + *params = ENUM_TO_BOOL(ctx->Hint.PolygonSmooth); + break; + case GL_POLYGON_STIPPLE: + *params = ctx->Polygon.StippleFlag; + break; + case GL_PROJECTION_MATRIX: + for (i=0;i<16;i++) { + params[i] = FLOAT_TO_BOOL(ctx->ProjectionMatrix.m[i]); + } + break; + case GL_PROJECTION_STACK_DEPTH: + *params = INT_TO_BOOL(ctx->ProjectionStackDepth + 1); + break; + case GL_READ_BUFFER: + *params = ENUM_TO_BOOL(ctx->Pixel.ReadBuffer); + break; + case GL_RED_BIAS: + *params = FLOAT_TO_BOOL(ctx->Pixel.RedBias); + break; + case GL_RED_BITS: + *params = INT_TO_BOOL( ctx->Visual.redBits ); + break; + case GL_RED_SCALE: + *params = FLOAT_TO_BOOL(ctx->Pixel.RedScale); + break; + case GL_RENDER_MODE: + *params = ENUM_TO_BOOL(ctx->RenderMode); + break; + case GL_RESCALE_NORMAL: + *params = ctx->Transform.RescaleNormals; + break; + case GL_RGBA_MODE: + *params = ctx->Visual.rgbMode; + break; + case GL_SCISSOR_BOX: + params[0] = INT_TO_BOOL(ctx->Scissor.X); + params[1] = INT_TO_BOOL(ctx->Scissor.Y); + params[2] = INT_TO_BOOL(ctx->Scissor.Width); + params[3] = INT_TO_BOOL(ctx->Scissor.Height); + break; + case GL_SCISSOR_TEST: + *params = ctx->Scissor.Enabled; + break; + case GL_SELECTION_BUFFER_SIZE: + *params = INT_TO_BOOL(ctx->Select.BufferSize); + break; + case GL_SHADE_MODEL: + *params = ENUM_TO_BOOL(ctx->Light.ShadeModel); + break; + case GL_SHARED_TEXTURE_PALETTE_EXT: + *params = ctx->Texture.SharedPalette; + break; + case GL_STENCIL_BITS: + *params = INT_TO_BOOL(ctx->Visual.stencilBits); + break; + case GL_STENCIL_CLEAR_VALUE: + *params = INT_TO_BOOL(ctx->Stencil.Clear); + break; + case GL_STENCIL_FAIL: + *params = ENUM_TO_BOOL(ctx->Stencil.FailFunc); + break; + case GL_STENCIL_FUNC: + *params = ENUM_TO_BOOL(ctx->Stencil.Function); + break; + case GL_STENCIL_PASS_DEPTH_FAIL: + *params = ENUM_TO_BOOL(ctx->Stencil.ZFailFunc); + break; + case GL_STENCIL_PASS_DEPTH_PASS: + *params = ENUM_TO_BOOL(ctx->Stencil.ZPassFunc); + break; + case GL_STENCIL_REF: + *params = INT_TO_BOOL(ctx->Stencil.Ref); + break; + case GL_STENCIL_TEST: + *params = ctx->Stencil.Enabled; + break; + case GL_STENCIL_VALUE_MASK: + *params = INT_TO_BOOL(ctx->Stencil.ValueMask); + break; + case GL_STENCIL_WRITEMASK: + *params = INT_TO_BOOL(ctx->Stencil.WriteMask); + break; + case GL_STEREO: + *params = ctx->Visual.stereoMode; + break; + case GL_SUBPIXEL_BITS: + *params = INT_TO_BOOL(ctx->Const.SubPixelBits); + break; + case GL_TEXTURE_1D: + *params = _mesa_IsEnabled(GL_TEXTURE_1D); + break; + case GL_TEXTURE_2D: + *params = _mesa_IsEnabled(GL_TEXTURE_2D); + break; + case GL_TEXTURE_3D: + *params = _mesa_IsEnabled(GL_TEXTURE_3D); + break; + case GL_TEXTURE_BINDING_1D: + *params = INT_TO_BOOL(textureUnit->Current1D->Name); + break; + case GL_TEXTURE_BINDING_2D: + *params = INT_TO_BOOL(textureUnit->Current2D->Name); + break; + case GL_TEXTURE_BINDING_3D: + *params = INT_TO_BOOL(textureUnit->Current3D->Name); + break; + case GL_TEXTURE_ENV_COLOR: + { + params[0] = FLOAT_TO_BOOL(textureUnit->EnvColor[0]); + params[1] = FLOAT_TO_BOOL(textureUnit->EnvColor[1]); + params[2] = FLOAT_TO_BOOL(textureUnit->EnvColor[2]); + params[3] = FLOAT_TO_BOOL(textureUnit->EnvColor[3]); + } + break; + case GL_TEXTURE_ENV_MODE: + *params = ENUM_TO_BOOL(textureUnit->EnvMode); + break; + case GL_TEXTURE_GEN_S: + *params = (textureUnit->TexGenEnabled & S_BIT) ? GL_TRUE : GL_FALSE; + break; + case GL_TEXTURE_GEN_T: + *params = (textureUnit->TexGenEnabled & T_BIT) ? GL_TRUE : GL_FALSE; + break; + case GL_TEXTURE_GEN_R: + *params = (textureUnit->TexGenEnabled & R_BIT) ? GL_TRUE : GL_FALSE; + break; + case GL_TEXTURE_GEN_Q: + *params = (textureUnit->TexGenEnabled & Q_BIT) ? GL_TRUE : GL_FALSE; + break; + case GL_TEXTURE_MATRIX: + for (i=0;i<16;i++) { + params[i] = + FLOAT_TO_BOOL(ctx->TextureMatrix[texUnit].m[i]); + } + break; + case GL_TEXTURE_STACK_DEPTH: + *params = INT_TO_BOOL(ctx->TextureStackDepth[texUnit] + 1); + break; + case GL_UNPACK_ALIGNMENT: + *params = INT_TO_BOOL(ctx->Unpack.Alignment); + break; + case GL_UNPACK_LSB_FIRST: + *params = ctx->Unpack.LsbFirst; + break; + case GL_UNPACK_ROW_LENGTH: + *params = INT_TO_BOOL(ctx->Unpack.RowLength); + break; + case GL_UNPACK_SKIP_PIXELS: + *params = INT_TO_BOOL(ctx->Unpack.SkipPixels); + break; + case GL_UNPACK_SKIP_ROWS: + *params = INT_TO_BOOL(ctx->Unpack.SkipRows); + break; + case GL_UNPACK_SWAP_BYTES: + *params = ctx->Unpack.SwapBytes; + break; + case GL_UNPACK_SKIP_IMAGES_EXT: + *params = ctx->Unpack.SkipImages; + break; + case GL_UNPACK_IMAGE_HEIGHT_EXT: + *params = ctx->Unpack.ImageHeight; + break; + case GL_VIEWPORT: + params[0] = INT_TO_BOOL(ctx->Viewport.X); + params[1] = INT_TO_BOOL(ctx->Viewport.Y); + params[2] = INT_TO_BOOL(ctx->Viewport.Width); + params[3] = INT_TO_BOOL(ctx->Viewport.Height); + break; + case GL_ZOOM_X: + *params = FLOAT_TO_BOOL(ctx->Pixel.ZoomX); + break; + case GL_ZOOM_Y: + *params = FLOAT_TO_BOOL(ctx->Pixel.ZoomY); + break; + case GL_VERTEX_ARRAY: + *params = ctx->Array.Vertex.Enabled; + break; + case GL_VERTEX_ARRAY_SIZE: + *params = INT_TO_BOOL(ctx->Array.Vertex.Size); + break; + case GL_VERTEX_ARRAY_TYPE: + *params = ENUM_TO_BOOL(ctx->Array.Vertex.Type); + break; + case GL_VERTEX_ARRAY_STRIDE: + *params = INT_TO_BOOL(ctx->Array.Vertex.Stride); + break; + case GL_VERTEX_ARRAY_COUNT_EXT: + *params = INT_TO_BOOL(0); + break; + case GL_NORMAL_ARRAY: + *params = ctx->Array.Normal.Enabled; + break; + case GL_NORMAL_ARRAY_TYPE: + *params = ENUM_TO_BOOL(ctx->Array.Normal.Type); + break; + case GL_NORMAL_ARRAY_STRIDE: + *params = INT_TO_BOOL(ctx->Array.Normal.Stride); + break; + case GL_NORMAL_ARRAY_COUNT_EXT: + *params = INT_TO_BOOL(0); + break; + case GL_COLOR_ARRAY: + *params = ctx->Array.Color.Enabled; + break; + case GL_COLOR_ARRAY_SIZE: + *params = INT_TO_BOOL(ctx->Array.Color.Size); + break; + case GL_COLOR_ARRAY_TYPE: + *params = ENUM_TO_BOOL(ctx->Array.Color.Type); + break; + case GL_COLOR_ARRAY_STRIDE: + *params = INT_TO_BOOL(ctx->Array.Color.Stride); + break; + case GL_COLOR_ARRAY_COUNT_EXT: + *params = INT_TO_BOOL(0); + break; + case GL_INDEX_ARRAY: + *params = ctx->Array.Index.Enabled; + break; + case GL_INDEX_ARRAY_TYPE: + *params = ENUM_TO_BOOL(ctx->Array.Index.Type); + break; + case GL_INDEX_ARRAY_STRIDE: + *params = INT_TO_BOOL(ctx->Array.Index.Stride); + break; + case GL_INDEX_ARRAY_COUNT_EXT: + *params = INT_TO_BOOL(0); + break; + case GL_TEXTURE_COORD_ARRAY: + *params = ctx->Array.TexCoord[texUnit].Enabled; + break; + case GL_TEXTURE_COORD_ARRAY_SIZE: + *params = INT_TO_BOOL(ctx->Array.TexCoord[texUnit].Size); + break; + case GL_TEXTURE_COORD_ARRAY_TYPE: + *params = ENUM_TO_BOOL(ctx->Array.TexCoord[texUnit].Type); + break; + case GL_TEXTURE_COORD_ARRAY_STRIDE: + *params = INT_TO_BOOL(ctx->Array.TexCoord[texUnit].Stride); + break; + case GL_TEXTURE_COORD_ARRAY_COUNT_EXT: + *params = INT_TO_BOOL(0); + break; + case GL_EDGE_FLAG_ARRAY: + *params = ctx->Array.EdgeFlag.Enabled; + break; + case GL_EDGE_FLAG_ARRAY_STRIDE: + *params = INT_TO_BOOL(ctx->Array.EdgeFlag.Stride); + break; + + /* GL_ARB_multitexture */ + case GL_MAX_TEXTURE_UNITS_ARB: + *params = ctx->Const.MaxTextureUnits; + break; + case GL_ACTIVE_TEXTURE_ARB: + *params = INT_TO_BOOL(GL_TEXTURE0_ARB + ctx->Texture.CurrentUnit); + break; + case GL_CLIENT_ACTIVE_TEXTURE_ARB: + *params = INT_TO_BOOL(GL_TEXTURE0_ARB + ctx->Array.ActiveTexture); + break; + + /* GL_ARB_texture_cube_map */ + case GL_TEXTURE_CUBE_MAP_ARB: + if (ctx->Extensions.ARB_texture_cube_map) + *params = _mesa_IsEnabled(GL_TEXTURE_CUBE_MAP_ARB); + else + _mesa_error(ctx, GL_INVALID_ENUM, "glGetBooleanv"); + return; + case GL_TEXTURE_BINDING_CUBE_MAP_ARB: + if (ctx->Extensions.ARB_texture_cube_map) + *params = INT_TO_BOOL(textureUnit->CurrentCubeMap->Name); + else + _mesa_error(ctx, GL_INVALID_ENUM, "glGetBooleanv"); + return; + case GL_MAX_CUBE_MAP_TEXTURE_SIZE_ARB: + if (ctx->Extensions.ARB_texture_cube_map) + *params = INT_TO_BOOL(1 << (ctx->Const.MaxCubeTextureLevels - 1)); + else + _mesa_error(ctx, GL_INVALID_ENUM, "glGetBooleanv"); + break; + + /* GL_ARB_texture_compression */ + case GL_TEXTURE_COMPRESSION_HINT_ARB: + if (ctx->Extensions.ARB_texture_compression) { + *params = INT_TO_BOOL(ctx->Hint.TextureCompression); + } + else + _mesa_error(ctx, GL_INVALID_ENUM, "glGetBooleanv"); + break; + case GL_NUM_COMPRESSED_TEXTURE_FORMATS_ARB: + if (ctx->Extensions.ARB_texture_compression) { + *params = INT_TO_BOOL(ctx->Const.NumCompressedTextureFormats); + } + else + _mesa_error(ctx, GL_INVALID_ENUM, "glGetBooleanv"); + break; + case GL_COMPRESSED_TEXTURE_FORMATS_ARB: + if (ctx->Extensions.ARB_texture_compression) { + GLuint i; + for (i = 0; i < ctx->Const.NumCompressedTextureFormats; i++) + params[i] = INT_TO_BOOL(ctx->Const.CompressedTextureFormats[i]); + } + else + _mesa_error(ctx, GL_INVALID_ENUM, "glGetBooleanv"); + break; + + /* GL_EXT_compiled_vertex_array */ + case GL_ARRAY_ELEMENT_LOCK_FIRST_EXT: + *params = ctx->Array.LockFirst ? GL_TRUE : GL_FALSE; + break; + case GL_ARRAY_ELEMENT_LOCK_COUNT_EXT: + *params = ctx->Array.LockCount ? GL_TRUE : GL_FALSE; + break; + + /* GL_ARB_transpose_matrix */ + case GL_TRANSPOSE_COLOR_MATRIX_ARB: + { + GLfloat tm[16]; + GLuint i; + _math_transposef(tm, ctx->ColorMatrix.m); + for (i=0;i<16;i++) { + params[i] = FLOAT_TO_BOOL(tm[i]); + } + } + break; + case GL_TRANSPOSE_MODELVIEW_MATRIX_ARB: + { + GLfloat tm[16]; + GLuint i; + _math_transposef(tm, ctx->ModelView.m); + for (i=0;i<16;i++) { + params[i] = FLOAT_TO_BOOL(tm[i]); + } + } + break; + case GL_TRANSPOSE_PROJECTION_MATRIX_ARB: + { + GLfloat tm[16]; + GLuint i; + _math_transposef(tm, ctx->ProjectionMatrix.m); + for (i=0;i<16;i++) { + params[i] = FLOAT_TO_BOOL(tm[i]); + } + } + break; + case GL_TRANSPOSE_TEXTURE_MATRIX_ARB: + { + GLfloat tm[16]; + GLuint i; + _math_transposef(tm, ctx->TextureMatrix[texUnit].m); + for (i=0;i<16;i++) { + params[i] = FLOAT_TO_BOOL(tm[i]); + } + } + break; + + /* GL_HP_occlusion_test */ + case GL_OCCLUSION_TEST_HP: + if (ctx->Extensions.HP_occlusion_test) { + *params = ctx->Depth.OcclusionTest; + } + else { + _mesa_error( ctx, GL_INVALID_ENUM, "glGetBooleanv" ); + } + return; + case GL_OCCLUSION_TEST_RESULT_HP: + if (ctx->Extensions.HP_occlusion_test) { + if (ctx->Depth.OcclusionTest) + *params = ctx->OcclusionResult; + else + *params = ctx->OcclusionResultSaved; + /* reset flag now */ + ctx->OcclusionResult = GL_FALSE; + ctx->OcclusionResultSaved = GL_FALSE; + } + else { + _mesa_error( ctx, GL_INVALID_ENUM, "glGetBooleanv" ); + } + return; + + /* GL_SGIS_pixel_texture */ + case GL_PIXEL_TEXTURE_SGIS: + *params = ctx->Pixel.PixelTextureEnabled; + break; + + /* GL_SGIX_pixel_texture */ + case GL_PIXEL_TEX_GEN_SGIX: + *params = ctx->Pixel.PixelTextureEnabled; + break; + case GL_PIXEL_TEX_GEN_MODE_SGIX: + *params = (GLboolean) pixel_texgen_mode(ctx); + break; + + /* GL_SGI_color_matrix (also in 1.2 imaging) */ + case GL_COLOR_MATRIX_SGI: + for (i=0;i<16;i++) { + params[i] = FLOAT_TO_BOOL(ctx->ColorMatrix.m[i]); + } + break; + case GL_COLOR_MATRIX_STACK_DEPTH_SGI: + *params = INT_TO_BOOL(ctx->ColorStackDepth + 1); + break; + case GL_MAX_COLOR_MATRIX_STACK_DEPTH_SGI: + *params = FLOAT_TO_BOOL(MAX_COLOR_STACK_DEPTH); + break; + case GL_POST_COLOR_MATRIX_RED_SCALE_SGI: + *params = FLOAT_TO_BOOL(ctx->Pixel.PostColorMatrixScale[0]); + break; + case GL_POST_COLOR_MATRIX_GREEN_SCALE_SGI: + *params = FLOAT_TO_BOOL(ctx->Pixel.PostColorMatrixScale[1]); + break; + case GL_POST_COLOR_MATRIX_BLUE_SCALE_SGI: + *params = FLOAT_TO_BOOL(ctx->Pixel.PostColorMatrixScale[2]); + break; + case GL_POST_COLOR_MATRIX_ALPHA_SCALE_SGI: + *params = FLOAT_TO_BOOL(ctx->Pixel.PostColorMatrixScale[3]); + break; + case GL_POST_COLOR_MATRIX_RED_BIAS_SGI: + *params = FLOAT_TO_BOOL(ctx->Pixel.PostColorMatrixBias[0]); + break; + case GL_POST_COLOR_MATRIX_GREEN_BIAS_SGI: + *params = FLOAT_TO_BOOL(ctx->Pixel.PostColorMatrixBias[1]); + break; + case GL_POST_COLOR_MATRIX_BLUE_BIAS_SGI: + *params = FLOAT_TO_BOOL(ctx->Pixel.PostColorMatrixBias[2]); + break; + case GL_POST_COLOR_MATRIX_ALPHA_BIAS_SGI: + *params = FLOAT_TO_BOOL(ctx->Pixel.PostColorMatrixBias[3]); + break; + + /* GL_EXT_convolution (also in 1.2 imaging) */ + case GL_CONVOLUTION_1D_EXT: + if (ctx->Extensions.EXT_convolution || ctx->Extensions.ARB_imaging) { + *params = ctx->Pixel.Convolution1DEnabled; + } + else { + _mesa_error(ctx, GL_INVALID_ENUM, "glGetBooleanv"); + return; + } + break; + case GL_CONVOLUTION_2D: + if (ctx->Extensions.EXT_convolution || ctx->Extensions.ARB_imaging) { + *params = ctx->Pixel.Convolution2DEnabled; + } + else { + _mesa_error(ctx, GL_INVALID_ENUM, "glGetBooleanv"); + return; + } + break; + case GL_SEPARABLE_2D: + if (ctx->Extensions.EXT_convolution || ctx->Extensions.ARB_imaging) { + *params = ctx->Pixel.Separable2DEnabled; + } + else { + _mesa_error(ctx, GL_INVALID_ENUM, "glGetBooleanv"); + return; + } + break; + case GL_MAX_CONVOLUTION_WIDTH: + *params = INT_TO_BOOL(ctx->Const.MaxConvolutionWidth); + break; + case GL_MAX_CONVOLUTION_HEIGHT: + *params = INT_TO_BOOL(ctx->Const.MaxConvolutionHeight); + break; + case GL_POST_CONVOLUTION_RED_SCALE_EXT: + *params = FLOAT_TO_BOOL(ctx->Pixel.PostConvolutionScale[0]); + break; + case GL_POST_CONVOLUTION_GREEN_SCALE_EXT: + *params = FLOAT_TO_BOOL(ctx->Pixel.PostConvolutionScale[1]); + break; + case GL_POST_CONVOLUTION_BLUE_SCALE_EXT: + *params = FLOAT_TO_BOOL(ctx->Pixel.PostConvolutionScale[2]); + break; + case GL_POST_CONVOLUTION_ALPHA_SCALE_EXT: + *params = FLOAT_TO_BOOL(ctx->Pixel.PostConvolutionScale[3]); + break; + case GL_POST_CONVOLUTION_RED_BIAS_EXT: + *params = FLOAT_TO_BOOL(ctx->Pixel.PostConvolutionBias[0]); + break; + case GL_POST_CONVOLUTION_GREEN_BIAS_EXT: + *params = FLOAT_TO_BOOL(ctx->Pixel.PostConvolutionBias[1]); + break; + case GL_POST_CONVOLUTION_BLUE_BIAS_EXT: + *params = FLOAT_TO_BOOL(ctx->Pixel.PostConvolutionBias[2]); + break; + case GL_POST_CONVOLUTION_ALPHA_BIAS_EXT: + *params = FLOAT_TO_BOOL(ctx->Pixel.PostConvolutionBias[2]); + break; + + /* GL_SGI_color_table (also in 1.2 imaging */ + case GL_COLOR_TABLE_SGI: + *params = ctx->Pixel.ColorTableEnabled; + break; + case GL_POST_CONVOLUTION_COLOR_TABLE_SGI: + *params = ctx->Pixel.PostConvolutionColorTableEnabled; + break; + case GL_POST_COLOR_MATRIX_COLOR_TABLE_SGI: + *params = ctx->Pixel.PostColorMatrixColorTableEnabled; + break; + + /* GL_EXT_secondary_color */ + case GL_COLOR_SUM_EXT: + *params = ctx->Fog.ColorSumEnabled; + break; + case GL_CURRENT_SECONDARY_COLOR_EXT: + FLUSH_CURRENT(ctx, 0); + params[0] = INT_TO_BOOL(ctx->Current.SecondaryColor[0]); + params[1] = INT_TO_BOOL(ctx->Current.SecondaryColor[1]); + params[2] = INT_TO_BOOL(ctx->Current.SecondaryColor[2]); + break; + case GL_SECONDARY_COLOR_ARRAY_EXT: + *params = ctx->Array.SecondaryColor.Enabled; + break; + case GL_SECONDARY_COLOR_ARRAY_TYPE_EXT: + *params = ENUM_TO_BOOL(ctx->Array.SecondaryColor.Type); + break; + case GL_SECONDARY_COLOR_ARRAY_STRIDE_EXT: + *params = INT_TO_BOOL(ctx->Array.SecondaryColor.Stride); + break; + case GL_SECONDARY_COLOR_ARRAY_SIZE_EXT: + *params = INT_TO_BOOL(ctx->Array.SecondaryColor.Stride); + break; + + /* GL_EXT_fog_coord */ + case GL_CURRENT_FOG_COORDINATE_EXT: + FLUSH_CURRENT(ctx, 0); + *params = FLOAT_TO_BOOL(ctx->Current.FogCoord); + break; + case GL_FOG_COORDINATE_ARRAY_EXT: + *params = ctx->Array.FogCoord.Enabled; + break; + case GL_FOG_COORDINATE_ARRAY_TYPE_EXT: + *params = ENUM_TO_BOOL(ctx->Array.FogCoord.Type); + break; + case GL_FOG_COORDINATE_ARRAY_STRIDE_EXT: + *params = INT_TO_BOOL(ctx->Array.FogCoord.Stride); + break; + + /* GL_EXT_texture_filter_anisotropic */ + case GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT: + if (ctx->Extensions.EXT_texture_filter_anisotropic) { + *params = FLOAT_TO_BOOL(ctx->Const.MaxTextureMaxAnisotropy); + } + else { + _mesa_error( ctx, GL_INVALID_ENUM, "glGetBooleanv" ); + return; + } + break; + + /* GL_ARB_multisample */ + case GL_MULTISAMPLE_ARB: + if (ctx->Extensions.ARB_multisample) { + *params = ctx->Multisample.Enabled; + } + else { + _mesa_error(ctx, GL_INVALID_ENUM, "glGetBooleanv"); + return; + } + case GL_SAMPLE_ALPHA_TO_COVERAGE_ARB: + if (ctx->Extensions.ARB_multisample) { + *params = ctx->Multisample.SampleAlphaToCoverage; + } + else { + _mesa_error(ctx, GL_INVALID_ENUM, "glGetBooleanv"); + return; + } + case GL_SAMPLE_ALPHA_TO_ONE_ARB: + if (ctx->Extensions.ARB_multisample) { + *params = ctx->Multisample.SampleAlphaToOne; + } + else { + _mesa_error(ctx, GL_INVALID_ENUM, "glGetBooleanv"); + return; + } + case GL_SAMPLE_COVERAGE_ARB: + if (ctx->Extensions.ARB_multisample) { + *params = ctx->Multisample.SampleCoverage; + } + else { + _mesa_error(ctx, GL_INVALID_ENUM, "glGetBooleanv"); + return; + } + case GL_SAMPLE_COVERAGE_VALUE_ARB: + if (ctx->Extensions.ARB_multisample) { + *params = FLOAT_TO_BOOL(ctx->Multisample.SampleCoverageValue); + } + else { + _mesa_error(ctx, GL_INVALID_ENUM, "glGetBooleanv"); + return; + } + case GL_SAMPLE_COVERAGE_INVERT_ARB: + if (ctx->Extensions.ARB_multisample) { + *params = ctx->Multisample.SampleCoverageInvert; + } + else { + _mesa_error(ctx, GL_INVALID_ENUM, "glGetBooleanv"); + return; + } + case GL_SAMPLE_BUFFERS_ARB: + if (ctx->Extensions.ARB_multisample) { + *params = 0; /* XXX fix someday */ + } + else { + _mesa_error(ctx, GL_INVALID_ENUM, "glGetBooleanv"); + return; + } + case GL_SAMPLES_ARB: + if (ctx->Extensions.ARB_multisample) { + *params = 0; /* XXX fix someday */ + } + else { + _mesa_error(ctx, GL_INVALID_ENUM, "glGetBooleanv"); + return; + } + + /* GL_SGIS_generate_mipmap */ + case GL_GENERATE_MIPMAP_HINT_SGIS: + if (ctx->Extensions.SGIS_generate_mipmap) { + *params = ENUM_TO_BOOL(ctx->Hint.GenerateMipmap); + } + else { + _mesa_error(ctx, GL_INVALID_ENUM, "glGetBooleanv"); + return; + } + break; + + default: + _mesa_error( ctx, GL_INVALID_ENUM, "glGetBooleanv" ); + } +} + + +void +_mesa_GetDoublev( GLenum pname, GLdouble *params ) +{ + GET_CURRENT_CONTEXT(ctx); + GLuint i; + GLuint texUnit = ctx->Texture.CurrentUnit; + const struct gl_texture_unit *textureUnit = &ctx->Texture.Unit[texUnit]; + ASSERT_OUTSIDE_BEGIN_END(ctx); + + if (!params) + return; + + /* We need this in order to get correct results for + * GL_OCCLUSION_TEST_RESULT_HP. There might be other important cases. + */ + FLUSH_VERTICES(ctx, 0); + + if (MESA_VERBOSE & VERBOSE_API) + fprintf(stderr, "glGetDoublev %s\n", _mesa_lookup_enum_by_nr(pname)); + + if (ctx->Driver.GetDoublev && (*ctx->Driver.GetDoublev)(ctx, pname, params)) + return; + + switch (pname) { + case GL_ACCUM_RED_BITS: + *params = (GLdouble) ctx->Visual.accumRedBits; + break; + case GL_ACCUM_GREEN_BITS: + *params = (GLdouble) ctx->Visual.accumGreenBits; + break; + case GL_ACCUM_BLUE_BITS: + *params = (GLdouble) ctx->Visual.accumBlueBits; + break; + case GL_ACCUM_ALPHA_BITS: + *params = (GLdouble) ctx->Visual.accumAlphaBits; + break; + case GL_ACCUM_CLEAR_VALUE: + params[0] = (GLdouble) ctx->Accum.ClearColor[0]; + params[1] = (GLdouble) ctx->Accum.ClearColor[1]; + params[2] = (GLdouble) ctx->Accum.ClearColor[2]; + params[3] = (GLdouble) ctx->Accum.ClearColor[3]; + break; + case GL_ALPHA_BIAS: + *params = (GLdouble) ctx->Pixel.AlphaBias; + break; + case GL_ALPHA_BITS: + *params = (GLdouble) ctx->Visual.alphaBits; + break; + case GL_ALPHA_SCALE: + *params = (GLdouble) ctx->Pixel.AlphaScale; + break; + case GL_ALPHA_TEST: + *params = (GLdouble) ctx->Color.AlphaEnabled; + break; + case GL_ALPHA_TEST_FUNC: + *params = ENUM_TO_DOUBLE(ctx->Color.AlphaFunc); + break; + case GL_ALPHA_TEST_REF: + *params = (GLdouble) ctx->Color.AlphaRef / CHAN_MAXF; + break; + case GL_ATTRIB_STACK_DEPTH: + *params = (GLdouble ) (ctx->AttribStackDepth); + break; + case GL_AUTO_NORMAL: + *params = (GLdouble) ctx->Eval.AutoNormal; + break; + case GL_AUX_BUFFERS: + *params = (GLdouble) ctx->Const.NumAuxBuffers; + break; + case GL_BLEND: + *params = (GLdouble) ctx->Color.BlendEnabled; + break; + case GL_BLEND_DST: + *params = ENUM_TO_DOUBLE(ctx->Color.BlendDstRGB); + break; + case GL_BLEND_SRC: + *params = ENUM_TO_DOUBLE(ctx->Color.BlendSrcRGB); + break; + case GL_BLEND_SRC_RGB_EXT: + *params = ENUM_TO_DOUBLE(ctx->Color.BlendSrcRGB); + break; + case GL_BLEND_DST_RGB_EXT: + *params = ENUM_TO_DOUBLE(ctx->Color.BlendDstRGB); + break; + case GL_BLEND_SRC_ALPHA_EXT: + *params = ENUM_TO_DOUBLE(ctx->Color.BlendSrcA); + break; + case GL_BLEND_DST_ALPHA_EXT: + *params = ENUM_TO_DOUBLE(ctx->Color.BlendDstA); + break; + case GL_BLEND_EQUATION_EXT: + *params = ENUM_TO_DOUBLE(ctx->Color.BlendEquation); + break; + case GL_BLEND_COLOR_EXT: + params[0] = (GLdouble) ctx->Color.BlendColor[0]; + params[1] = (GLdouble) ctx->Color.BlendColor[1]; + params[2] = (GLdouble) ctx->Color.BlendColor[2]; + params[3] = (GLdouble) ctx->Color.BlendColor[3]; + break; + case GL_BLUE_BIAS: + *params = (GLdouble) ctx->Pixel.BlueBias; + break; + case GL_BLUE_BITS: + *params = (GLdouble) ctx->Visual.blueBits; + break; + case GL_BLUE_SCALE: + *params = (GLdouble) ctx->Pixel.BlueScale; + break; + case GL_CLIENT_ATTRIB_STACK_DEPTH: + *params = (GLdouble) (ctx->ClientAttribStackDepth); + break; + case GL_CLIP_PLANE0: + case GL_CLIP_PLANE1: + case GL_CLIP_PLANE2: + case GL_CLIP_PLANE3: + case GL_CLIP_PLANE4: + case GL_CLIP_PLANE5: + *params = (GLdouble) ctx->Transform.ClipEnabled[pname-GL_CLIP_PLANE0]; + break; + case GL_COLOR_CLEAR_VALUE: + params[0] = (GLdouble) CHAN_TO_FLOAT(ctx->Color.ClearColor[0]); + params[1] = (GLdouble) CHAN_TO_FLOAT(ctx->Color.ClearColor[1]); + params[2] = (GLdouble) CHAN_TO_FLOAT(ctx->Color.ClearColor[2]); + params[3] = (GLdouble) CHAN_TO_FLOAT(ctx->Color.ClearColor[3]); + break; + case GL_COLOR_MATERIAL: + *params = (GLdouble) ctx->Light.ColorMaterialEnabled; + break; + case GL_COLOR_MATERIAL_FACE: + *params = ENUM_TO_DOUBLE(ctx->Light.ColorMaterialFace); + break; + case GL_COLOR_MATERIAL_PARAMETER: + *params = ENUM_TO_DOUBLE(ctx->Light.ColorMaterialMode); + break; + case GL_COLOR_WRITEMASK: + params[0] = ctx->Color.ColorMask[RCOMP] ? 1.0 : 0.0; + params[1] = ctx->Color.ColorMask[GCOMP] ? 1.0 : 0.0; + params[2] = ctx->Color.ColorMask[BCOMP] ? 1.0 : 0.0; + params[3] = ctx->Color.ColorMask[ACOMP] ? 1.0 : 0.0; + break; + case GL_CULL_FACE: + *params = (GLdouble) ctx->Polygon.CullFlag; + break; + case GL_CULL_FACE_MODE: + *params = ENUM_TO_DOUBLE(ctx->Polygon.CullFaceMode); + break; + case GL_CURRENT_COLOR: + FLUSH_CURRENT(ctx, 0); + params[0] = (ctx->Current.Color[0]); + params[1] = (ctx->Current.Color[1]); + params[2] = (ctx->Current.Color[2]); + params[3] = (ctx->Current.Color[3]); + break; + case GL_CURRENT_INDEX: + FLUSH_CURRENT(ctx, 0); + *params = (GLdouble) ctx->Current.Index; + break; + case GL_CURRENT_NORMAL: + FLUSH_CURRENT(ctx, 0); + params[0] = (GLdouble) ctx->Current.Normal[0]; + params[1] = (GLdouble) ctx->Current.Normal[1]; + params[2] = (GLdouble) ctx->Current.Normal[2]; + break; + case GL_CURRENT_RASTER_COLOR: + params[0] = (GLdouble) ctx->Current.RasterColor[0]; + params[1] = (GLdouble) ctx->Current.RasterColor[1]; + params[2] = (GLdouble) ctx->Current.RasterColor[2]; + params[3] = (GLdouble) ctx->Current.RasterColor[3]; + break; + case GL_CURRENT_RASTER_DISTANCE: + params[0] = (GLdouble) ctx->Current.RasterDistance; + break; + case GL_CURRENT_RASTER_INDEX: + *params = (GLdouble) ctx->Current.RasterIndex; + break; + case GL_CURRENT_RASTER_POSITION: + params[0] = (GLdouble) ctx->Current.RasterPos[0]; + params[1] = (GLdouble) ctx->Current.RasterPos[1]; + params[2] = (GLdouble) ctx->Current.RasterPos[2]; + params[3] = (GLdouble) ctx->Current.RasterPos[3]; + break; + case GL_CURRENT_RASTER_TEXTURE_COORDS: + params[0] = (GLdouble) ctx->Current.RasterMultiTexCoord[texUnit][0]; + params[1] = (GLdouble) ctx->Current.RasterMultiTexCoord[texUnit][1]; + params[2] = (GLdouble) ctx->Current.RasterMultiTexCoord[texUnit][2]; + params[3] = (GLdouble) ctx->Current.RasterMultiTexCoord[texUnit][3]; + break; + case GL_CURRENT_RASTER_POSITION_VALID: + *params = (GLdouble) ctx->Current.RasterPosValid; + break; + case GL_CURRENT_TEXTURE_COORDS: + FLUSH_CURRENT(ctx, 0); + params[0] = (GLdouble) ctx->Current.Texcoord[texUnit][0]; + params[1] = (GLdouble) ctx->Current.Texcoord[texUnit][1]; + params[2] = (GLdouble) ctx->Current.Texcoord[texUnit][2]; + params[3] = (GLdouble) ctx->Current.Texcoord[texUnit][3]; + break; + case GL_DEPTH_BIAS: + *params = (GLdouble) ctx->Pixel.DepthBias; + break; + case GL_DEPTH_BITS: + *params = (GLdouble) ctx->Visual.depthBits; + break; + case GL_DEPTH_CLEAR_VALUE: + *params = (GLdouble) ctx->Depth.Clear; + break; + case GL_DEPTH_FUNC: + *params = ENUM_TO_DOUBLE(ctx->Depth.Func); + break; + case GL_DEPTH_RANGE: + params[0] = (GLdouble) ctx->Viewport.Near; + params[1] = (GLdouble) ctx->Viewport.Far; + break; + case GL_DEPTH_SCALE: + *params = (GLdouble) ctx->Pixel.DepthScale; + break; + case GL_DEPTH_TEST: + *params = (GLdouble) ctx->Depth.Test; + break; + case GL_DEPTH_WRITEMASK: + *params = (GLdouble) ctx->Depth.Mask; + break; + case GL_DITHER: + *params = (GLdouble) ctx->Color.DitherFlag; + break; + case GL_DOUBLEBUFFER: + *params = (GLdouble) ctx->Visual.doubleBufferMode; + break; + case GL_DRAW_BUFFER: + *params = ENUM_TO_DOUBLE(ctx->Color.DrawBuffer); + break; + case GL_EDGE_FLAG: + FLUSH_CURRENT(ctx, 0); + *params = (GLdouble) ctx->Current.EdgeFlag; + break; + case GL_FEEDBACK_BUFFER_SIZE: + *params = (GLdouble) ctx->Feedback.BufferSize; + break; + case GL_FEEDBACK_BUFFER_TYPE: + *params = ENUM_TO_DOUBLE(ctx->Feedback.Type); + break; + case GL_FOG: + *params = (GLdouble) ctx->Fog.Enabled; + break; + case GL_FOG_COLOR: + params[0] = (GLdouble) ctx->Fog.Color[0]; + params[1] = (GLdouble) ctx->Fog.Color[1]; + params[2] = (GLdouble) ctx->Fog.Color[2]; + params[3] = (GLdouble) ctx->Fog.Color[3]; + break; + case GL_FOG_DENSITY: + *params = (GLdouble) ctx->Fog.Density; + break; + case GL_FOG_END: + *params = (GLdouble) ctx->Fog.End; + break; + case GL_FOG_HINT: + *params = ENUM_TO_DOUBLE(ctx->Hint.Fog); + break; + case GL_FOG_INDEX: + *params = (GLdouble) ctx->Fog.Index; + break; + case GL_FOG_MODE: + *params = ENUM_TO_DOUBLE(ctx->Fog.Mode); + break; + case GL_FOG_START: + *params = (GLdouble) ctx->Fog.Start; + break; + case GL_FRONT_FACE: + *params = ENUM_TO_DOUBLE(ctx->Polygon.FrontFace); + break; + case GL_GREEN_BIAS: + *params = (GLdouble) ctx->Pixel.GreenBias; + break; + case GL_GREEN_BITS: + *params = (GLdouble) ctx->Visual.greenBits; + break; + case GL_GREEN_SCALE: + *params = (GLdouble) ctx->Pixel.GreenScale; + break; + case GL_HISTOGRAM: + if (ctx->Extensions.EXT_histogram || ctx->Extensions.ARB_imaging) { + *params = (GLdouble) ctx->Pixel.HistogramEnabled; + } + else { + _mesa_error(ctx, GL_INVALID_ENUM, "glGetDoublev"); + return; + } + break; + case GL_INDEX_BITS: + *params = (GLdouble) ctx->Visual.indexBits; + break; + case GL_INDEX_CLEAR_VALUE: + *params = (GLdouble) ctx->Color.ClearIndex; + break; + case GL_INDEX_MODE: + *params = ctx->Visual.rgbMode ? 0.0 : 1.0; + break; + case GL_INDEX_OFFSET: + *params = (GLdouble) ctx->Pixel.IndexOffset; + break; + case GL_INDEX_SHIFT: + *params = (GLdouble) ctx->Pixel.IndexShift; + break; + case GL_INDEX_WRITEMASK: + *params = (GLdouble) ctx->Color.IndexMask; + break; + case GL_LIGHT0: + case GL_LIGHT1: + case GL_LIGHT2: + case GL_LIGHT3: + case GL_LIGHT4: + case GL_LIGHT5: + case GL_LIGHT6: + case GL_LIGHT7: + *params = (GLdouble) ctx->Light.Light[pname-GL_LIGHT0].Enabled; + break; + case GL_LIGHTING: + *params = (GLdouble) ctx->Light.Enabled; + break; + case GL_LIGHT_MODEL_AMBIENT: + params[0] = (GLdouble) ctx->Light.Model.Ambient[0]; + params[1] = (GLdouble) ctx->Light.Model.Ambient[1]; + params[2] = (GLdouble) ctx->Light.Model.Ambient[2]; + params[3] = (GLdouble) ctx->Light.Model.Ambient[3]; + break; + case GL_LIGHT_MODEL_COLOR_CONTROL: + params[0] = (GLdouble) ctx->Light.Model.ColorControl; + break; + case GL_LIGHT_MODEL_LOCAL_VIEWER: + *params = (GLdouble) ctx->Light.Model.LocalViewer; + break; + case GL_LIGHT_MODEL_TWO_SIDE: + *params = (GLdouble) ctx->Light.Model.TwoSide; + break; + case GL_LINE_SMOOTH: + *params = (GLdouble) ctx->Line.SmoothFlag; + break; + case GL_LINE_SMOOTH_HINT: + *params = ENUM_TO_DOUBLE(ctx->Hint.LineSmooth); + break; + case GL_LINE_STIPPLE: + *params = (GLdouble) ctx->Line.StippleFlag; + break; + case GL_LINE_STIPPLE_PATTERN: + *params = (GLdouble) ctx->Line.StipplePattern; + break; + case GL_LINE_STIPPLE_REPEAT: + *params = (GLdouble) ctx->Line.StippleFactor; + break; + case GL_LINE_WIDTH: + *params = (GLdouble) ctx->Line.Width; + break; + case GL_LINE_WIDTH_GRANULARITY: + *params = (GLdouble) ctx->Const.LineWidthGranularity; + break; + case GL_LINE_WIDTH_RANGE: + params[0] = (GLdouble) ctx->Const.MinLineWidthAA; + params[1] = (GLdouble) ctx->Const.MaxLineWidthAA; + break; + case GL_ALIASED_LINE_WIDTH_RANGE: + params[0] = (GLdouble) ctx->Const.MinLineWidth; + params[1] = (GLdouble) ctx->Const.MaxLineWidth; + break; + case GL_LIST_BASE: + *params = (GLdouble) ctx->List.ListBase; + break; + case GL_LIST_INDEX: + *params = (GLdouble) ctx->CurrentListNum; + break; + case GL_LIST_MODE: + *params = ctx->ExecuteFlag ? ENUM_TO_DOUBLE(GL_COMPILE_AND_EXECUTE) + : ENUM_TO_DOUBLE(GL_COMPILE); + break; + case GL_INDEX_LOGIC_OP: + *params = (GLdouble) ctx->Color.IndexLogicOpEnabled; + break; + case GL_COLOR_LOGIC_OP: + *params = (GLdouble) ctx->Color.ColorLogicOpEnabled; + break; + case GL_LOGIC_OP_MODE: + *params = ENUM_TO_DOUBLE(ctx->Color.LogicOp); + break; + case GL_MAP1_COLOR_4: + *params = (GLdouble) ctx->Eval.Map1Color4; + break; + case GL_MAP1_GRID_DOMAIN: + params[0] = (GLdouble) ctx->Eval.MapGrid1u1; + params[1] = (GLdouble) ctx->Eval.MapGrid1u2; + break; + case GL_MAP1_GRID_SEGMENTS: + *params = (GLdouble) ctx->Eval.MapGrid1un; + break; + case GL_MAP1_INDEX: + *params = (GLdouble) ctx->Eval.Map1Index; + break; + case GL_MAP1_NORMAL: + *params = (GLdouble) ctx->Eval.Map1Normal; + break; + case GL_MAP1_TEXTURE_COORD_1: + *params = (GLdouble) ctx->Eval.Map1TextureCoord1; + break; + case GL_MAP1_TEXTURE_COORD_2: + *params = (GLdouble) ctx->Eval.Map1TextureCoord2; + break; + case GL_MAP1_TEXTURE_COORD_3: + *params = (GLdouble) ctx->Eval.Map1TextureCoord3; + break; + case GL_MAP1_TEXTURE_COORD_4: + *params = (GLdouble) ctx->Eval.Map1TextureCoord4; + break; + case GL_MAP1_VERTEX_3: + *params = (GLdouble) ctx->Eval.Map1Vertex3; + break; + case GL_MAP1_VERTEX_4: + *params = (GLdouble) ctx->Eval.Map1Vertex4; + break; + case GL_MAP2_COLOR_4: + *params = (GLdouble) ctx->Eval.Map2Color4; + break; + case GL_MAP2_GRID_DOMAIN: + params[0] = (GLdouble) ctx->Eval.MapGrid2u1; + params[1] = (GLdouble) ctx->Eval.MapGrid2u2; + params[2] = (GLdouble) ctx->Eval.MapGrid2v1; + params[3] = (GLdouble) ctx->Eval.MapGrid2v2; + break; + case GL_MAP2_GRID_SEGMENTS: + params[0] = (GLdouble) ctx->Eval.MapGrid2un; + params[1] = (GLdouble) ctx->Eval.MapGrid2vn; + break; + case GL_MAP2_INDEX: + *params = (GLdouble) ctx->Eval.Map2Index; + break; + case GL_MAP2_NORMAL: + *params = (GLdouble) ctx->Eval.Map2Normal; + break; + case GL_MAP2_TEXTURE_COORD_1: + *params = (GLdouble) ctx->Eval.Map2TextureCoord1; + break; + case GL_MAP2_TEXTURE_COORD_2: + *params = (GLdouble) ctx->Eval.Map2TextureCoord2; + break; + case GL_MAP2_TEXTURE_COORD_3: + *params = (GLdouble) ctx->Eval.Map2TextureCoord3; + break; + case GL_MAP2_TEXTURE_COORD_4: + *params = (GLdouble) ctx->Eval.Map2TextureCoord4; + break; + case GL_MAP2_VERTEX_3: + *params = (GLdouble) ctx->Eval.Map2Vertex3; + break; + case GL_MAP2_VERTEX_4: + *params = (GLdouble) ctx->Eval.Map2Vertex4; + break; + case GL_MAP_COLOR: + *params = (GLdouble) ctx->Pixel.MapColorFlag; + break; + case GL_MAP_STENCIL: + *params = (GLdouble) ctx->Pixel.MapStencilFlag; + break; + case GL_MATRIX_MODE: + *params = ENUM_TO_DOUBLE(ctx->Transform.MatrixMode); + break; + case GL_MAX_ATTRIB_STACK_DEPTH: + *params = (GLdouble) MAX_ATTRIB_STACK_DEPTH; + break; + case GL_MAX_CLIENT_ATTRIB_STACK_DEPTH: + *params = (GLdouble) MAX_CLIENT_ATTRIB_STACK_DEPTH; + break; + case GL_MAX_CLIP_PLANES: + *params = (GLdouble) ctx->Const.MaxClipPlanes; + break; + case GL_MAX_ELEMENTS_VERTICES: /* GL_VERSION_1_2 */ + *params = (GLdouble) ctx->Const.MaxArrayLockSize; + break; + case GL_MAX_ELEMENTS_INDICES: /* GL_VERSION_1_2 */ + *params = (GLdouble) ctx->Const.MaxArrayLockSize; + break; + case GL_MAX_EVAL_ORDER: + *params = (GLdouble) MAX_EVAL_ORDER; + break; + case GL_MAX_LIGHTS: + *params = (GLdouble) ctx->Const.MaxLights; + break; + case GL_MAX_LIST_NESTING: + *params = (GLdouble) MAX_LIST_NESTING; + break; + case GL_MAX_MODELVIEW_STACK_DEPTH: + *params = (GLdouble) MAX_MODELVIEW_STACK_DEPTH; + break; + case GL_MAX_NAME_STACK_DEPTH: + *params = (GLdouble) MAX_NAME_STACK_DEPTH; + break; + case GL_MAX_PIXEL_MAP_TABLE: + *params = (GLdouble) MAX_PIXEL_MAP_TABLE; + break; + case GL_MAX_PROJECTION_STACK_DEPTH: + *params = (GLdouble) MAX_PROJECTION_STACK_DEPTH; + break; + case GL_MAX_TEXTURE_SIZE: + *params = (GLdouble) (1 << (ctx->Const.MaxTextureLevels - 1)); + break; + case GL_MAX_3D_TEXTURE_SIZE: + *params = (GLdouble) (1 << (ctx->Const.Max3DTextureLevels - 1)); + break; + case GL_MAX_TEXTURE_STACK_DEPTH: + *params = (GLdouble) MAX_TEXTURE_STACK_DEPTH; + break; + case GL_MAX_VIEWPORT_DIMS: + params[0] = (GLdouble) MAX_WIDTH; + params[1] = (GLdouble) MAX_HEIGHT; + break; + case GL_MINMAX: + *params = (GLdouble) ctx->Pixel.MinMaxEnabled; + break; + case GL_MODELVIEW_MATRIX: + for (i=0;i<16;i++) { + params[i] = (GLdouble) ctx->ModelView.m[i]; + } + break; + case GL_MODELVIEW_STACK_DEPTH: + *params = (GLdouble) (ctx->ModelViewStackDepth + 1); + break; + case GL_NAME_STACK_DEPTH: + *params = (GLdouble) ctx->Select.NameStackDepth; + break; + case GL_NORMALIZE: + *params = (GLdouble) ctx->Transform.Normalize; + break; + case GL_PACK_ALIGNMENT: + *params = (GLdouble) ctx->Pack.Alignment; + break; + case GL_PACK_LSB_FIRST: + *params = (GLdouble) ctx->Pack.LsbFirst; + break; + case GL_PACK_ROW_LENGTH: + *params = (GLdouble) ctx->Pack.RowLength; + break; + case GL_PACK_SKIP_PIXELS: + *params = (GLdouble) ctx->Pack.SkipPixels; + break; + case GL_PACK_SKIP_ROWS: + *params = (GLdouble) ctx->Pack.SkipRows; + break; + case GL_PACK_SWAP_BYTES: + *params = (GLdouble) ctx->Pack.SwapBytes; + break; + case GL_PACK_SKIP_IMAGES_EXT: + *params = (GLdouble) ctx->Pack.SkipImages; + break; + case GL_PACK_IMAGE_HEIGHT_EXT: + *params = (GLdouble) ctx->Pack.ImageHeight; + break; + case GL_PERSPECTIVE_CORRECTION_HINT: + *params = ENUM_TO_DOUBLE(ctx->Hint.PerspectiveCorrection); + break; + case GL_PIXEL_MAP_A_TO_A_SIZE: + *params = (GLdouble) ctx->Pixel.MapAtoAsize; + break; + case GL_PIXEL_MAP_B_TO_B_SIZE: + *params = (GLdouble) ctx->Pixel.MapBtoBsize; + break; + case GL_PIXEL_MAP_G_TO_G_SIZE: + *params = (GLdouble) ctx->Pixel.MapGtoGsize; + break; + case GL_PIXEL_MAP_I_TO_A_SIZE: + *params = (GLdouble) ctx->Pixel.MapItoAsize; + break; + case GL_PIXEL_MAP_I_TO_B_SIZE: + *params = (GLdouble) ctx->Pixel.MapItoBsize; + break; + case GL_PIXEL_MAP_I_TO_G_SIZE: + *params = (GLdouble) ctx->Pixel.MapItoGsize; + break; + case GL_PIXEL_MAP_I_TO_I_SIZE: + *params = (GLdouble) ctx->Pixel.MapItoIsize; + break; + case GL_PIXEL_MAP_I_TO_R_SIZE: + *params = (GLdouble) ctx->Pixel.MapItoRsize; + break; + case GL_PIXEL_MAP_R_TO_R_SIZE: + *params = (GLdouble) ctx->Pixel.MapRtoRsize; + break; + case GL_PIXEL_MAP_S_TO_S_SIZE: + *params = (GLdouble) ctx->Pixel.MapStoSsize; + break; + case GL_POINT_SIZE: + *params = (GLdouble) ctx->Point.Size; + break; + case GL_POINT_SIZE_GRANULARITY: + *params = (GLdouble) ctx->Const.PointSizeGranularity; + break; + case GL_POINT_SIZE_RANGE: + params[0] = (GLdouble) ctx->Const.MinPointSizeAA; + params[1] = (GLdouble) ctx->Const.MaxPointSizeAA; + break; + case GL_ALIASED_POINT_SIZE_RANGE: + params[0] = (GLdouble) ctx->Const.MinPointSize; + params[1] = (GLdouble) ctx->Const.MaxPointSize; + break; + case GL_POINT_SMOOTH: + *params = (GLdouble) ctx->Point.SmoothFlag; + break; + case GL_POINT_SMOOTH_HINT: + *params = ENUM_TO_DOUBLE(ctx->Hint.PointSmooth); + break; + case GL_POINT_SIZE_MIN_EXT: + *params = (GLdouble) (ctx->Point.MinSize); + break; + case GL_POINT_SIZE_MAX_EXT: + *params = (GLdouble) (ctx->Point.MaxSize); + break; + case GL_POINT_FADE_THRESHOLD_SIZE_EXT: + *params = (GLdouble) (ctx->Point.Threshold); + break; + case GL_DISTANCE_ATTENUATION_EXT: + params[0] = (GLdouble) (ctx->Point.Params[0]); + params[1] = (GLdouble) (ctx->Point.Params[1]); + params[2] = (GLdouble) (ctx->Point.Params[2]); + break; + case GL_POLYGON_MODE: + params[0] = ENUM_TO_DOUBLE(ctx->Polygon.FrontMode); + params[1] = ENUM_TO_DOUBLE(ctx->Polygon.BackMode); + break; + case GL_POLYGON_OFFSET_BIAS_EXT: /* GL_EXT_polygon_offset */ + *params = (GLdouble) ctx->Polygon.OffsetUnits; + break; + case GL_POLYGON_OFFSET_FACTOR: + *params = (GLdouble) ctx->Polygon.OffsetFactor; + break; + case GL_POLYGON_OFFSET_UNITS: + *params = (GLdouble) ctx->Polygon.OffsetUnits; + break; + case GL_POLYGON_SMOOTH: + *params = (GLdouble) ctx->Polygon.SmoothFlag; + break; + case GL_POLYGON_SMOOTH_HINT: + *params = ENUM_TO_DOUBLE(ctx->Hint.PolygonSmooth); + break; + case GL_POLYGON_STIPPLE: + *params = (GLdouble) ctx->Polygon.StippleFlag; + break; + case GL_PROJECTION_MATRIX: + for (i=0;i<16;i++) { + params[i] = (GLdouble) ctx->ProjectionMatrix.m[i]; + } + break; + case GL_PROJECTION_STACK_DEPTH: + *params = (GLdouble) (ctx->ProjectionStackDepth + 1); + break; + case GL_READ_BUFFER: + *params = ENUM_TO_DOUBLE(ctx->Pixel.ReadBuffer); + break; + case GL_RED_BIAS: + *params = (GLdouble) ctx->Pixel.RedBias; + break; + case GL_RED_BITS: + *params = (GLdouble) ctx->Visual.redBits; + break; + case GL_RED_SCALE: + *params = (GLdouble) ctx->Pixel.RedScale; + break; + case GL_RENDER_MODE: + *params = ENUM_TO_DOUBLE(ctx->RenderMode); + break; + case GL_RESCALE_NORMAL: + *params = (GLdouble) ctx->Transform.RescaleNormals; + break; + case GL_RGBA_MODE: + *params = (GLdouble) ctx->Visual.rgbMode; + break; + case GL_SCISSOR_BOX: + params[0] = (GLdouble) ctx->Scissor.X; + params[1] = (GLdouble) ctx->Scissor.Y; + params[2] = (GLdouble) ctx->Scissor.Width; + params[3] = (GLdouble) ctx->Scissor.Height; + break; + case GL_SCISSOR_TEST: + *params = (GLdouble) ctx->Scissor.Enabled; + break; + case GL_SELECTION_BUFFER_SIZE: + *params = (GLdouble) ctx->Select.BufferSize; + break; + case GL_SHADE_MODEL: + *params = ENUM_TO_DOUBLE(ctx->Light.ShadeModel); + break; + case GL_SHARED_TEXTURE_PALETTE_EXT: + *params = (GLdouble) ctx->Texture.SharedPalette; + break; + case GL_STENCIL_BITS: + *params = (GLdouble) ctx->Visual.stencilBits; + break; + case GL_STENCIL_CLEAR_VALUE: + *params = (GLdouble) ctx->Stencil.Clear; + break; + case GL_STENCIL_FAIL: + *params = ENUM_TO_DOUBLE(ctx->Stencil.FailFunc); + break; + case GL_STENCIL_FUNC: + *params = ENUM_TO_DOUBLE(ctx->Stencil.Function); + break; + case GL_STENCIL_PASS_DEPTH_FAIL: + *params = ENUM_TO_DOUBLE(ctx->Stencil.ZFailFunc); + break; + case GL_STENCIL_PASS_DEPTH_PASS: + *params = ENUM_TO_DOUBLE(ctx->Stencil.ZPassFunc); + break; + case GL_STENCIL_REF: + *params = (GLdouble) ctx->Stencil.Ref; + break; + case GL_STENCIL_TEST: + *params = (GLdouble) ctx->Stencil.Enabled; + break; + case GL_STENCIL_VALUE_MASK: + *params = (GLdouble) ctx->Stencil.ValueMask; + break; + case GL_STENCIL_WRITEMASK: + *params = (GLdouble) ctx->Stencil.WriteMask; + break; + case GL_STEREO: + *params = (GLdouble) ctx->Visual.stereoMode; + break; + case GL_SUBPIXEL_BITS: + *params = (GLdouble) ctx->Const.SubPixelBits; + break; + case GL_TEXTURE_1D: + *params = _mesa_IsEnabled(GL_TEXTURE_1D) ? 1.0 : 0.0; + break; + case GL_TEXTURE_2D: + *params = _mesa_IsEnabled(GL_TEXTURE_2D) ? 1.0 : 0.0; + break; + case GL_TEXTURE_3D: + *params = _mesa_IsEnabled(GL_TEXTURE_3D) ? 1.0 : 0.0; + break; + case GL_TEXTURE_BINDING_1D: + *params = (GLdouble) textureUnit->Current1D->Name; + break; + case GL_TEXTURE_BINDING_2D: + *params = (GLdouble) textureUnit->Current2D->Name; + break; + case GL_TEXTURE_BINDING_3D: + *params = (GLdouble) textureUnit->Current3D->Name; + break; + case GL_TEXTURE_ENV_COLOR: + params[0] = (GLdouble) textureUnit->EnvColor[0]; + params[1] = (GLdouble) textureUnit->EnvColor[1]; + params[2] = (GLdouble) textureUnit->EnvColor[2]; + params[3] = (GLdouble) textureUnit->EnvColor[3]; + break; + case GL_TEXTURE_ENV_MODE: + *params = ENUM_TO_DOUBLE(textureUnit->EnvMode); + break; + case GL_TEXTURE_GEN_S: + *params = (textureUnit->TexGenEnabled & S_BIT) ? 1.0 : 0.0; + break; + case GL_TEXTURE_GEN_T: + *params = (textureUnit->TexGenEnabled & T_BIT) ? 1.0 : 0.0; + break; + case GL_TEXTURE_GEN_R: + *params = (textureUnit->TexGenEnabled & R_BIT) ? 1.0 : 0.0; + break; + case GL_TEXTURE_GEN_Q: + *params = (textureUnit->TexGenEnabled & Q_BIT) ? 1.0 : 0.0; + break; + case GL_TEXTURE_MATRIX: + for (i=0;i<16;i++) { + params[i] = (GLdouble) ctx->TextureMatrix[texUnit].m[i]; + } + break; + case GL_TEXTURE_STACK_DEPTH: + *params = (GLdouble) (ctx->TextureStackDepth[texUnit] + 1); + break; + case GL_UNPACK_ALIGNMENT: + *params = (GLdouble) ctx->Unpack.Alignment; + break; + case GL_UNPACK_LSB_FIRST: + *params = (GLdouble) ctx->Unpack.LsbFirst; + break; + case GL_UNPACK_ROW_LENGTH: + *params = (GLdouble) ctx->Unpack.RowLength; + break; + case GL_UNPACK_SKIP_PIXELS: + *params = (GLdouble) ctx->Unpack.SkipPixels; + break; + case GL_UNPACK_SKIP_ROWS: + *params = (GLdouble) ctx->Unpack.SkipRows; + break; + case GL_UNPACK_SWAP_BYTES: + *params = (GLdouble) ctx->Unpack.SwapBytes; + break; + case GL_UNPACK_SKIP_IMAGES_EXT: + *params = (GLdouble) ctx->Unpack.SkipImages; + break; + case GL_UNPACK_IMAGE_HEIGHT_EXT: + *params = (GLdouble) ctx->Unpack.ImageHeight; + break; + case GL_VIEWPORT: + params[0] = (GLdouble) ctx->Viewport.X; + params[1] = (GLdouble) ctx->Viewport.Y; + params[2] = (GLdouble) ctx->Viewport.Width; + params[3] = (GLdouble) ctx->Viewport.Height; + break; + case GL_ZOOM_X: + *params = (GLdouble) ctx->Pixel.ZoomX; + break; + case GL_ZOOM_Y: + *params = (GLdouble) ctx->Pixel.ZoomY; + break; + case GL_VERTEX_ARRAY: + *params = (GLdouble) ctx->Array.Vertex.Enabled; + break; + case GL_VERTEX_ARRAY_SIZE: + *params = (GLdouble) ctx->Array.Vertex.Size; + break; + case GL_VERTEX_ARRAY_TYPE: + *params = ENUM_TO_DOUBLE(ctx->Array.Vertex.Type); + break; + case GL_VERTEX_ARRAY_STRIDE: + *params = (GLdouble) ctx->Array.Vertex.Stride; + break; + case GL_VERTEX_ARRAY_COUNT_EXT: + *params = 0.0; + break; + case GL_NORMAL_ARRAY: + *params = (GLdouble) ctx->Array.Normal.Enabled; + break; + case GL_NORMAL_ARRAY_TYPE: + *params = ENUM_TO_DOUBLE(ctx->Array.Normal.Type); + break; + case GL_NORMAL_ARRAY_STRIDE: + *params = (GLdouble) ctx->Array.Normal.Stride; + break; + case GL_NORMAL_ARRAY_COUNT_EXT: + *params = 0.0; + break; + case GL_COLOR_ARRAY: + *params = (GLdouble) ctx->Array.Color.Enabled; + break; + case GL_COLOR_ARRAY_SIZE: + *params = (GLdouble) ctx->Array.Color.Size; + break; + case GL_COLOR_ARRAY_TYPE: + *params = ENUM_TO_DOUBLE(ctx->Array.Color.Type); + break; + case GL_COLOR_ARRAY_STRIDE: + *params = (GLdouble) ctx->Array.Color.Stride; + break; + case GL_COLOR_ARRAY_COUNT_EXT: + *params = 0.0; + break; + case GL_INDEX_ARRAY: + *params = (GLdouble) ctx->Array.Index.Enabled; + break; + case GL_INDEX_ARRAY_TYPE: + *params = ENUM_TO_DOUBLE(ctx->Array.Index.Type); + break; + case GL_INDEX_ARRAY_STRIDE: + *params = (GLdouble) ctx->Array.Index.Stride; + break; + case GL_INDEX_ARRAY_COUNT_EXT: + *params = 0.0; + break; + case GL_TEXTURE_COORD_ARRAY: + *params = (GLdouble) ctx->Array.TexCoord[texUnit].Enabled; + break; + case GL_TEXTURE_COORD_ARRAY_SIZE: + *params = (GLdouble) ctx->Array.TexCoord[texUnit].Size; + break; + case GL_TEXTURE_COORD_ARRAY_TYPE: + *params = ENUM_TO_DOUBLE(ctx->Array.TexCoord[texUnit].Type); + break; + case GL_TEXTURE_COORD_ARRAY_STRIDE: + *params = (GLdouble) ctx->Array.TexCoord[texUnit].Stride; + break; + case GL_TEXTURE_COORD_ARRAY_COUNT_EXT: + *params = 0.0; + break; + case GL_EDGE_FLAG_ARRAY: + *params = (GLdouble) ctx->Array.EdgeFlag.Enabled; + break; + case GL_EDGE_FLAG_ARRAY_STRIDE: + *params = (GLdouble) ctx->Array.EdgeFlag.Stride; + break; + case GL_EDGE_FLAG_ARRAY_COUNT_EXT: + *params = 0.0; + break; + + /* GL_ARB_multitexture */ + case GL_MAX_TEXTURE_UNITS_ARB: + *params = (GLdouble) ctx->Const.MaxTextureUnits; + break; + case GL_ACTIVE_TEXTURE_ARB: + *params = (GLdouble) (GL_TEXTURE0_ARB + ctx->Texture.CurrentUnit); + break; + case GL_CLIENT_ACTIVE_TEXTURE_ARB: + *params = (GLdouble) (GL_TEXTURE0_ARB + ctx->Array.ActiveTexture); + break; + + /* GL_ARB_texture_cube_map */ + case GL_TEXTURE_CUBE_MAP_ARB: + if (ctx->Extensions.ARB_texture_cube_map) + *params = (GLdouble) _mesa_IsEnabled(GL_TEXTURE_CUBE_MAP_ARB); + else + _mesa_error(ctx, GL_INVALID_ENUM, "glGetDoublev"); + return; + case GL_TEXTURE_BINDING_CUBE_MAP_ARB: + if (ctx->Extensions.ARB_texture_cube_map) + *params = (GLdouble) textureUnit->CurrentCubeMap->Name; + else + _mesa_error(ctx, GL_INVALID_ENUM, "glGetDoublev"); + return; + case GL_MAX_CUBE_MAP_TEXTURE_SIZE_ARB: + if (ctx->Extensions.ARB_texture_cube_map) + *params = (GLdouble) (1 << (ctx->Const.MaxCubeTextureLevels - 1)); + else + _mesa_error(ctx, GL_INVALID_ENUM, "glGetDoublev"); + return; + + /* GL_ARB_texture_compression */ + case GL_TEXTURE_COMPRESSION_HINT_ARB: + if (ctx->Extensions.ARB_texture_compression) { + *params = (GLdouble) ctx->Hint.TextureCompression; + } + else + _mesa_error(ctx, GL_INVALID_ENUM, "glGetDoublev"); + break; + case GL_NUM_COMPRESSED_TEXTURE_FORMATS_ARB: + if (ctx->Extensions.ARB_texture_compression) { + *params = (GLdouble) ctx->Const.NumCompressedTextureFormats; + } + else + _mesa_error(ctx, GL_INVALID_ENUM, "glGetDoublev"); + break; + case GL_COMPRESSED_TEXTURE_FORMATS_ARB: + if (ctx->Extensions.ARB_texture_compression) { + GLuint i; + for (i = 0; i < ctx->Const.NumCompressedTextureFormats; i++) + params[i] = (GLdouble) ctx->Const.CompressedTextureFormats[i]; + } + else + _mesa_error(ctx, GL_INVALID_ENUM, "glGetDoublev"); + break; + + /* GL_EXT_compiled_vertex_array */ + case GL_ARRAY_ELEMENT_LOCK_FIRST_EXT: + *params = (GLdouble) ctx->Array.LockFirst; + break; + case GL_ARRAY_ELEMENT_LOCK_COUNT_EXT: + *params = (GLdouble) ctx->Array.LockCount; + break; + + /* GL_ARB_transpose_matrix */ + case GL_TRANSPOSE_COLOR_MATRIX_ARB: + { + GLfloat tm[16]; + GLuint i; + _math_transposef(tm, ctx->ColorMatrix.m); + for (i=0;i<16;i++) { + params[i] = (GLdouble) tm[i]; + } + } + break; + case GL_TRANSPOSE_MODELVIEW_MATRIX_ARB: + { + GLfloat tm[16]; + GLuint i; + _math_transposef(tm, ctx->ModelView.m); + for (i=0;i<16;i++) { + params[i] = (GLdouble) tm[i]; + } + } + break; + case GL_TRANSPOSE_PROJECTION_MATRIX_ARB: + { + GLfloat tm[16]; + GLuint i; + _math_transposef(tm, ctx->ProjectionMatrix.m); + for (i=0;i<16;i++) { + params[i] = (GLdouble) tm[i]; + } + } + break; + case GL_TRANSPOSE_TEXTURE_MATRIX_ARB: + { + GLfloat tm[16]; + GLuint i; + _math_transposef(tm, ctx->TextureMatrix[texUnit].m); + for (i=0;i<16;i++) { + params[i] = (GLdouble) tm[i]; + } + } + break; + + /* GL_HP_occlusion_test */ + case GL_OCCLUSION_TEST_HP: + if (ctx->Extensions.HP_occlusion_test) { + *params = (GLdouble) ctx->Depth.OcclusionTest; + } + else { + _mesa_error( ctx, GL_INVALID_ENUM, "glGetDoublev" ); + } + return; + case GL_OCCLUSION_TEST_RESULT_HP: + if (ctx->Extensions.HP_occlusion_test) { + if (ctx->Depth.OcclusionTest) + *params = (GLdouble) ctx->OcclusionResult; + else + *params = (GLdouble) ctx->OcclusionResultSaved; + /* reset flag now */ + ctx->OcclusionResult = GL_FALSE; + ctx->OcclusionResultSaved = GL_FALSE; + } + else { + _mesa_error( ctx, GL_INVALID_ENUM, "glGetDoublev" ); + } + return; + + /* GL_SGIS_pixel_texture */ + case GL_PIXEL_TEXTURE_SGIS: + *params = (GLdouble) ctx->Pixel.PixelTextureEnabled; + break; + + /* GL_SGIX_pixel_texture */ + case GL_PIXEL_TEX_GEN_SGIX: + *params = (GLdouble) ctx->Pixel.PixelTextureEnabled; + break; + case GL_PIXEL_TEX_GEN_MODE_SGIX: + *params = (GLdouble) pixel_texgen_mode(ctx); + break; + + /* GL_SGI_color_matrix (also in 1.2 imaging) */ + case GL_COLOR_MATRIX_SGI: + for (i=0;i<16;i++) { + params[i] = (GLdouble) ctx->ColorMatrix.m[i]; + } + break; + case GL_COLOR_MATRIX_STACK_DEPTH_SGI: + *params = (GLdouble) (ctx->ColorStackDepth + 1); + break; + case GL_MAX_COLOR_MATRIX_STACK_DEPTH_SGI: + *params = (GLdouble) MAX_COLOR_STACK_DEPTH; + break; + case GL_POST_COLOR_MATRIX_RED_SCALE_SGI: + *params = (GLdouble) ctx->Pixel.PostColorMatrixScale[0]; + break; + case GL_POST_COLOR_MATRIX_GREEN_SCALE_SGI: + *params = (GLdouble) ctx->Pixel.PostColorMatrixScale[1]; + break; + case GL_POST_COLOR_MATRIX_BLUE_SCALE_SGI: + *params = (GLdouble) ctx->Pixel.PostColorMatrixScale[2]; + break; + case GL_POST_COLOR_MATRIX_ALPHA_SCALE_SGI: + *params = (GLdouble) ctx->Pixel.PostColorMatrixScale[3]; + break; + case GL_POST_COLOR_MATRIX_RED_BIAS_SGI: + *params = (GLdouble) ctx->Pixel.PostColorMatrixBias[0]; + break; + case GL_POST_COLOR_MATRIX_GREEN_BIAS_SGI: + *params = (GLdouble) ctx->Pixel.PostColorMatrixBias[1]; + break; + case GL_POST_COLOR_MATRIX_BLUE_BIAS_SGI: + *params = (GLdouble) ctx->Pixel.PostColorMatrixBias[2]; + break; + case GL_POST_COLOR_MATRIX_ALPHA_BIAS_SGI: + *params = (GLdouble) ctx->Pixel.PostColorMatrixBias[3]; + break; + + /* GL_EXT_convolution (also in 1.2 imaging) */ + case GL_CONVOLUTION_1D_EXT: + if (ctx->Extensions.EXT_convolution || ctx->Extensions.ARB_imaging) { + *params = (GLdouble) ctx->Pixel.Convolution1DEnabled; + } + else { + _mesa_error(ctx, GL_INVALID_ENUM, "glGetDoublev"); + return; + } + break; + case GL_CONVOLUTION_2D: + if (ctx->Extensions.EXT_convolution || ctx->Extensions.ARB_imaging) { + *params = (GLdouble) ctx->Pixel.Convolution2DEnabled; + } + else { + _mesa_error(ctx, GL_INVALID_ENUM, "glGetDoublev"); + return; + } + break; + case GL_SEPARABLE_2D: + if (ctx->Extensions.EXT_convolution || ctx->Extensions.ARB_imaging) { + *params = (GLdouble) ctx->Pixel.Separable2DEnabled; + } + else { + _mesa_error(ctx, GL_INVALID_ENUM, "glGetDoublev"); + return; + } + break; + case GL_MAX_CONVOLUTION_WIDTH: + *params = (GLdouble) ctx->Const.MaxConvolutionWidth; + break; + case GL_MAX_CONVOLUTION_HEIGHT: + *params = (GLdouble) ctx->Const.MaxConvolutionHeight; + break; + case GL_POST_CONVOLUTION_RED_SCALE_EXT: + *params = (GLdouble) ctx->Pixel.PostConvolutionScale[0]; + break; + case GL_POST_CONVOLUTION_GREEN_SCALE_EXT: + *params = (GLdouble) ctx->Pixel.PostConvolutionScale[1]; + break; + case GL_POST_CONVOLUTION_BLUE_SCALE_EXT: + *params = (GLdouble) ctx->Pixel.PostConvolutionScale[2]; + break; + case GL_POST_CONVOLUTION_ALPHA_SCALE_EXT: + *params = (GLdouble) ctx->Pixel.PostConvolutionScale[3]; + break; + case GL_POST_CONVOLUTION_RED_BIAS_EXT: + *params = (GLdouble) ctx->Pixel.PostConvolutionBias[0]; + break; + case GL_POST_CONVOLUTION_GREEN_BIAS_EXT: + *params = (GLdouble) ctx->Pixel.PostConvolutionBias[1]; + break; + case GL_POST_CONVOLUTION_BLUE_BIAS_EXT: + *params = (GLdouble) ctx->Pixel.PostConvolutionBias[2]; + break; + case GL_POST_CONVOLUTION_ALPHA_BIAS_EXT: + *params = (GLdouble) ctx->Pixel.PostConvolutionBias[2]; + break; + + /* GL_SGI_color_table (also in 1.2 imaging */ + case GL_COLOR_TABLE_SGI: + *params = (GLdouble) ctx->Pixel.ColorTableEnabled; + break; + case GL_POST_CONVOLUTION_COLOR_TABLE_SGI: + *params = (GLdouble) ctx->Pixel.PostConvolutionColorTableEnabled; + break; + case GL_POST_COLOR_MATRIX_COLOR_TABLE_SGI: + *params = (GLdouble) ctx->Pixel.PostColorMatrixColorTableEnabled; + break; + + /* GL_EXT_secondary_color */ + case GL_COLOR_SUM_EXT: + *params = (GLdouble) ctx->Fog.ColorSumEnabled; + break; + case GL_CURRENT_SECONDARY_COLOR_EXT: + FLUSH_CURRENT(ctx, 0); + params[0] = (ctx->Current.SecondaryColor[0]); + params[1] = (ctx->Current.SecondaryColor[1]); + params[2] = (ctx->Current.SecondaryColor[2]); + break; + case GL_SECONDARY_COLOR_ARRAY_EXT: + *params = (GLdouble) ctx->Array.SecondaryColor.Enabled; + break; + case GL_SECONDARY_COLOR_ARRAY_TYPE_EXT: + *params = (GLdouble) ctx->Array.SecondaryColor.Type; + break; + case GL_SECONDARY_COLOR_ARRAY_STRIDE_EXT: + *params = (GLdouble) ctx->Array.SecondaryColor.Stride; + break; + case GL_SECONDARY_COLOR_ARRAY_SIZE_EXT: + *params = (GLdouble) ctx->Array.SecondaryColor.Stride; + break; + + /* GL_EXT_fog_coord */ + case GL_CURRENT_FOG_COORDINATE_EXT: + FLUSH_CURRENT(ctx, 0); + *params = (GLdouble) ctx->Current.FogCoord; + break; + case GL_FOG_COORDINATE_ARRAY_EXT: + *params = (GLdouble) ctx->Array.FogCoord.Enabled; + break; + case GL_FOG_COORDINATE_ARRAY_TYPE_EXT: + *params = (GLdouble) ctx->Array.FogCoord.Type; + break; + case GL_FOG_COORDINATE_ARRAY_STRIDE_EXT: + *params = (GLdouble) ctx->Array.FogCoord.Stride; + break; + + /* GL_EXT_texture_filter_anisotropic */ + case GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT: + if (ctx->Extensions.EXT_texture_filter_anisotropic) { + *params = (GLdouble) ctx->Const.MaxTextureMaxAnisotropy; + } + else { + _mesa_error( ctx, GL_INVALID_ENUM, "glGetDoublev" ); + return; + } + break; + + /* GL_ARB_multisample */ + case GL_MULTISAMPLE_ARB: + if (ctx->Extensions.ARB_multisample) { + *params = (GLdouble) ctx->Multisample.Enabled; + } + else { + _mesa_error(ctx, GL_INVALID_ENUM, "glGetDoublev"); + return; + } + case GL_SAMPLE_ALPHA_TO_COVERAGE_ARB: + if (ctx->Extensions.ARB_multisample) { + *params = (GLdouble) ctx->Multisample.SampleAlphaToCoverage; + } + else { + _mesa_error(ctx, GL_INVALID_ENUM, "glGetDoublev"); + return; + } + case GL_SAMPLE_ALPHA_TO_ONE_ARB: + if (ctx->Extensions.ARB_multisample) { + *params = (GLdouble) ctx->Multisample.SampleAlphaToOne; + } + else { + _mesa_error(ctx, GL_INVALID_ENUM, "glGetDoublev"); + return; + } + case GL_SAMPLE_COVERAGE_ARB: + if (ctx->Extensions.ARB_multisample) { + *params = (GLdouble) ctx->Multisample.SampleCoverage; + } + else { + _mesa_error(ctx, GL_INVALID_ENUM, "glGetDoublev"); + return; + } + case GL_SAMPLE_COVERAGE_VALUE_ARB: + if (ctx->Extensions.ARB_multisample) { + *params = ctx->Multisample.SampleCoverageValue; + } + else { + _mesa_error(ctx, GL_INVALID_ENUM, "glGetDoublev"); + return; + } + case GL_SAMPLE_COVERAGE_INVERT_ARB: + if (ctx->Extensions.ARB_multisample) { + *params = (GLdouble) ctx->Multisample.SampleCoverageInvert; + } + else { + _mesa_error(ctx, GL_INVALID_ENUM, "glGetDoublev"); + return; + } + case GL_SAMPLE_BUFFERS_ARB: + if (ctx->Extensions.ARB_multisample) { + *params = 0.0; /* XXX fix someday */ + } + else { + _mesa_error(ctx, GL_INVALID_ENUM, "glGetDoublev"); + return; + } + case GL_SAMPLES_ARB: + if (ctx->Extensions.ARB_multisample) { + *params = 0.0; /* XXX fix someday */ + } + else { + _mesa_error(ctx, GL_INVALID_ENUM, "glGetDoublev"); + return; + } + + /* GL_SGIS_generate_mipmap */ + case GL_GENERATE_MIPMAP_HINT_SGIS: + if (ctx->Extensions.SGIS_generate_mipmap) { + *params = (GLdouble) ctx->Hint.GenerateMipmap; + } + else { + _mesa_error(ctx, GL_INVALID_ENUM, "glGetDoublev"); + return; + } + break; + + default: + _mesa_error( ctx, GL_INVALID_ENUM, "glGetDoublev" ); + } +} + + +void +_mesa_GetFloatv( GLenum pname, GLfloat *params ) +{ + GET_CURRENT_CONTEXT(ctx); + GLuint i; + GLuint texUnit = ctx->Texture.CurrentUnit; + const struct gl_texture_unit *textureUnit = &ctx->Texture.Unit[texUnit]; + ASSERT_OUTSIDE_BEGIN_END(ctx); + + if (!params) + return; + + /* We need this in order to get correct results for + * GL_OCCLUSION_TEST_RESULT_HP. There might be other important cases. + */ + FLUSH_VERTICES(ctx, 0); + + if (MESA_VERBOSE & VERBOSE_API) + fprintf(stderr, "glGetFloatv %s\n", _mesa_lookup_enum_by_nr(pname)); + + if (ctx->Driver.GetFloatv && (*ctx->Driver.GetFloatv)(ctx, pname, params)) + return; + + switch (pname) { + case GL_ACCUM_RED_BITS: + *params = (GLfloat) ctx->Visual.accumRedBits; + break; + case GL_ACCUM_GREEN_BITS: + *params = (GLfloat) ctx->Visual.accumGreenBits; + break; + case GL_ACCUM_BLUE_BITS: + *params = (GLfloat) ctx->Visual.accumBlueBits; + break; + case GL_ACCUM_ALPHA_BITS: + *params = (GLfloat) ctx->Visual.accumAlphaBits; + break; + case GL_ACCUM_CLEAR_VALUE: + params[0] = ctx->Accum.ClearColor[0]; + params[1] = ctx->Accum.ClearColor[1]; + params[2] = ctx->Accum.ClearColor[2]; + params[3] = ctx->Accum.ClearColor[3]; + break; + case GL_ALPHA_BIAS: + *params = ctx->Pixel.AlphaBias; + break; + case GL_ALPHA_BITS: + *params = (GLfloat) ctx->Visual.alphaBits; + break; + case GL_ALPHA_SCALE: + *params = ctx->Pixel.AlphaScale; + break; + case GL_ALPHA_TEST: + *params = (GLfloat) ctx->Color.AlphaEnabled; + break; + case GL_ALPHA_TEST_FUNC: + *params = ENUM_TO_FLOAT(ctx->Color.AlphaFunc); + break; + case GL_ALPHA_TEST_REF: + *params = (GLfloat) ctx->Color.AlphaRef / CHAN_MAXF; + break; + case GL_ATTRIB_STACK_DEPTH: + *params = (GLfloat) (ctx->AttribStackDepth); + break; + case GL_AUTO_NORMAL: + *params = (GLfloat) ctx->Eval.AutoNormal; + break; + case GL_AUX_BUFFERS: + *params = (GLfloat) ctx->Const.NumAuxBuffers; + break; + case GL_BLEND: + *params = (GLfloat) ctx->Color.BlendEnabled; + break; + case GL_BLEND_DST: + *params = ENUM_TO_FLOAT(ctx->Color.BlendDstRGB); + break; + case GL_BLEND_SRC: + *params = ENUM_TO_FLOAT(ctx->Color.BlendSrcRGB); + break; + case GL_BLEND_SRC_RGB_EXT: + *params = ENUM_TO_FLOAT(ctx->Color.BlendSrcRGB); + break; + case GL_BLEND_DST_RGB_EXT: + *params = ENUM_TO_FLOAT(ctx->Color.BlendDstRGB); + break; + case GL_BLEND_SRC_ALPHA_EXT: + *params = ENUM_TO_FLOAT(ctx->Color.BlendSrcA); + break; + case GL_BLEND_DST_ALPHA_EXT: + *params = ENUM_TO_FLOAT(ctx->Color.BlendDstA); + break; + case GL_BLEND_EQUATION_EXT: + *params = ENUM_TO_FLOAT(ctx->Color.BlendEquation); + break; + case GL_BLEND_COLOR_EXT: + params[0] = ctx->Color.BlendColor[0]; + params[1] = ctx->Color.BlendColor[1]; + params[2] = ctx->Color.BlendColor[2]; + params[3] = ctx->Color.BlendColor[3]; + break; + case GL_BLUE_BIAS: + *params = ctx->Pixel.BlueBias; + break; + case GL_BLUE_BITS: + *params = (GLfloat) ctx->Visual.blueBits; + break; + case GL_BLUE_SCALE: + *params = ctx->Pixel.BlueScale; + break; + case GL_CLIENT_ATTRIB_STACK_DEPTH: + *params = (GLfloat) (ctx->ClientAttribStackDepth); + break; + case GL_CLIP_PLANE0: + case GL_CLIP_PLANE1: + case GL_CLIP_PLANE2: + case GL_CLIP_PLANE3: + case GL_CLIP_PLANE4: + case GL_CLIP_PLANE5: + *params = (GLfloat) ctx->Transform.ClipEnabled[pname-GL_CLIP_PLANE0]; + break; + case GL_COLOR_CLEAR_VALUE: + params[0] = CHAN_TO_FLOAT(ctx->Color.ClearColor[0]); + params[1] = CHAN_TO_FLOAT(ctx->Color.ClearColor[1]); + params[2] = CHAN_TO_FLOAT(ctx->Color.ClearColor[2]); + params[3] = CHAN_TO_FLOAT(ctx->Color.ClearColor[3]); + break; + case GL_COLOR_MATERIAL: + *params = (GLfloat) ctx->Light.ColorMaterialEnabled; + break; + case GL_COLOR_MATERIAL_FACE: + *params = ENUM_TO_FLOAT(ctx->Light.ColorMaterialFace); + break; + case GL_COLOR_MATERIAL_PARAMETER: + *params = ENUM_TO_FLOAT(ctx->Light.ColorMaterialMode); + break; + case GL_COLOR_WRITEMASK: + params[0] = ctx->Color.ColorMask[RCOMP] ? 1.0F : 0.0F; + params[1] = ctx->Color.ColorMask[GCOMP] ? 1.0F : 0.0F; + params[2] = ctx->Color.ColorMask[BCOMP] ? 1.0F : 0.0F; + params[3] = ctx->Color.ColorMask[ACOMP] ? 1.0F : 0.0F; + break; + case GL_CULL_FACE: + *params = (GLfloat) ctx->Polygon.CullFlag; + break; + case GL_CULL_FACE_MODE: + *params = ENUM_TO_FLOAT(ctx->Polygon.CullFaceMode); + break; + case GL_CURRENT_COLOR: + FLUSH_CURRENT(ctx, 0); + params[0] = (ctx->Current.Color[0]); + params[1] = (ctx->Current.Color[1]); + params[2] = (ctx->Current.Color[2]); + params[3] = (ctx->Current.Color[3]); + break; + case GL_CURRENT_INDEX: + FLUSH_CURRENT(ctx, 0); + *params = (GLfloat) ctx->Current.Index; + break; + case GL_CURRENT_NORMAL: + FLUSH_CURRENT(ctx, 0); + params[0] = ctx->Current.Normal[0]; + params[1] = ctx->Current.Normal[1]; + params[2] = ctx->Current.Normal[2]; + break; + case GL_CURRENT_RASTER_COLOR: + params[0] = ctx->Current.RasterColor[0]; + params[1] = ctx->Current.RasterColor[1]; + params[2] = ctx->Current.RasterColor[2]; + params[3] = ctx->Current.RasterColor[3]; + break; + case GL_CURRENT_RASTER_DISTANCE: + params[0] = ctx->Current.RasterDistance; + break; + case GL_CURRENT_RASTER_INDEX: + *params = (GLfloat) ctx->Current.RasterIndex; + break; + case GL_CURRENT_RASTER_POSITION: + params[0] = ctx->Current.RasterPos[0]; + params[1] = ctx->Current.RasterPos[1]; + params[2] = ctx->Current.RasterPos[2]; + params[3] = ctx->Current.RasterPos[3]; + break; + case GL_CURRENT_RASTER_TEXTURE_COORDS: + params[0] = ctx->Current.RasterMultiTexCoord[texUnit][0]; + params[1] = ctx->Current.RasterMultiTexCoord[texUnit][1]; + params[2] = ctx->Current.RasterMultiTexCoord[texUnit][2]; + params[3] = ctx->Current.RasterMultiTexCoord[texUnit][3]; + break; + case GL_CURRENT_RASTER_POSITION_VALID: + *params = (GLfloat) ctx->Current.RasterPosValid; + break; + case GL_CURRENT_TEXTURE_COORDS: + FLUSH_CURRENT(ctx, 0); + params[0] = (GLfloat) ctx->Current.Texcoord[texUnit][0]; + params[1] = (GLfloat) ctx->Current.Texcoord[texUnit][1]; + params[2] = (GLfloat) ctx->Current.Texcoord[texUnit][2]; + params[3] = (GLfloat) ctx->Current.Texcoord[texUnit][3]; + break; + case GL_DEPTH_BIAS: + *params = (GLfloat) ctx->Pixel.DepthBias; + break; + case GL_DEPTH_BITS: + *params = (GLfloat) ctx->Visual.depthBits; + break; + case GL_DEPTH_CLEAR_VALUE: + *params = (GLfloat) ctx->Depth.Clear; + break; + case GL_DEPTH_FUNC: + *params = ENUM_TO_FLOAT(ctx->Depth.Func); + break; + case GL_DEPTH_RANGE: + params[0] = (GLfloat) ctx->Viewport.Near; + params[1] = (GLfloat) ctx->Viewport.Far; + break; + case GL_DEPTH_SCALE: + *params = (GLfloat) ctx->Pixel.DepthScale; + break; + case GL_DEPTH_TEST: + *params = (GLfloat) ctx->Depth.Test; + break; + case GL_DEPTH_WRITEMASK: + *params = (GLfloat) ctx->Depth.Mask; + break; + case GL_DITHER: + *params = (GLfloat) ctx->Color.DitherFlag; + break; + case GL_DOUBLEBUFFER: + *params = (GLfloat) ctx->Visual.doubleBufferMode; + break; + case GL_DRAW_BUFFER: + *params = ENUM_TO_FLOAT(ctx->Color.DrawBuffer); + break; + case GL_EDGE_FLAG: + FLUSH_CURRENT(ctx, 0); + *params = (GLfloat) ctx->Current.EdgeFlag; + break; + case GL_FEEDBACK_BUFFER_SIZE: + *params = (GLfloat) ctx->Feedback.BufferSize; + break; + case GL_FEEDBACK_BUFFER_TYPE: + *params = ENUM_TO_FLOAT(ctx->Feedback.Type); + break; + case GL_FOG: + *params = (GLfloat) ctx->Fog.Enabled; + break; + case GL_FOG_COLOR: + params[0] = ctx->Fog.Color[0]; + params[1] = ctx->Fog.Color[1]; + params[2] = ctx->Fog.Color[2]; + params[3] = ctx->Fog.Color[3]; + break; + case GL_FOG_DENSITY: + *params = ctx->Fog.Density; + break; + case GL_FOG_END: + *params = ctx->Fog.End; + break; + case GL_FOG_HINT: + *params = ENUM_TO_FLOAT(ctx->Hint.Fog); + break; + case GL_FOG_INDEX: + *params = ctx->Fog.Index; + break; + case GL_FOG_MODE: + *params = ENUM_TO_FLOAT(ctx->Fog.Mode); + break; + case GL_FOG_START: + *params = ctx->Fog.Start; + break; + case GL_FRONT_FACE: + *params = ENUM_TO_FLOAT(ctx->Polygon.FrontFace); + break; + case GL_GREEN_BIAS: + *params = (GLfloat) ctx->Pixel.GreenBias; + break; + case GL_GREEN_BITS: + *params = (GLfloat) ctx->Visual.greenBits; + break; + case GL_GREEN_SCALE: + *params = (GLfloat) ctx->Pixel.GreenScale; + break; + case GL_HISTOGRAM: + if (ctx->Extensions.EXT_histogram || ctx->Extensions.ARB_imaging) { + *params = (GLfloat) ctx->Pixel.HistogramEnabled; + } + else { + _mesa_error(ctx, GL_INVALID_ENUM, "glGetFloatv"); + return; + } + break; + case GL_INDEX_BITS: + *params = (GLfloat) ctx->Visual.indexBits; + break; + case GL_INDEX_CLEAR_VALUE: + *params = (GLfloat) ctx->Color.ClearIndex; + break; + case GL_INDEX_MODE: + *params = ctx->Visual.rgbMode ? 0.0F : 1.0F; + break; + case GL_INDEX_OFFSET: + *params = (GLfloat) ctx->Pixel.IndexOffset; + break; + case GL_INDEX_SHIFT: + *params = (GLfloat) ctx->Pixel.IndexShift; + break; + case GL_INDEX_WRITEMASK: + *params = (GLfloat) ctx->Color.IndexMask; + break; + case GL_LIGHT0: + case GL_LIGHT1: + case GL_LIGHT2: + case GL_LIGHT3: + case GL_LIGHT4: + case GL_LIGHT5: + case GL_LIGHT6: + case GL_LIGHT7: + *params = (GLfloat) ctx->Light.Light[pname-GL_LIGHT0].Enabled; + break; + case GL_LIGHTING: + *params = (GLfloat) ctx->Light.Enabled; + break; + case GL_LIGHT_MODEL_AMBIENT: + params[0] = ctx->Light.Model.Ambient[0]; + params[1] = ctx->Light.Model.Ambient[1]; + params[2] = ctx->Light.Model.Ambient[2]; + params[3] = ctx->Light.Model.Ambient[3]; + break; + case GL_LIGHT_MODEL_COLOR_CONTROL: + params[0] = ENUM_TO_FLOAT(ctx->Light.Model.ColorControl); + break; + case GL_LIGHT_MODEL_LOCAL_VIEWER: + *params = (GLfloat) ctx->Light.Model.LocalViewer; + break; + case GL_LIGHT_MODEL_TWO_SIDE: + *params = (GLfloat) ctx->Light.Model.TwoSide; + break; + case GL_LINE_SMOOTH: + *params = (GLfloat) ctx->Line.SmoothFlag; + break; + case GL_LINE_SMOOTH_HINT: + *params = ENUM_TO_FLOAT(ctx->Hint.LineSmooth); + break; + case GL_LINE_STIPPLE: + *params = (GLfloat) ctx->Line.StippleFlag; + break; + case GL_LINE_STIPPLE_PATTERN: + *params = (GLfloat) ctx->Line.StipplePattern; + break; + case GL_LINE_STIPPLE_REPEAT: + *params = (GLfloat) ctx->Line.StippleFactor; + break; + case GL_LINE_WIDTH: + *params = (GLfloat) ctx->Line.Width; + break; + case GL_LINE_WIDTH_GRANULARITY: + *params = (GLfloat) ctx->Const.LineWidthGranularity; + break; + case GL_LINE_WIDTH_RANGE: + params[0] = (GLfloat) ctx->Const.MinLineWidthAA; + params[1] = (GLfloat) ctx->Const.MaxLineWidthAA; + break; + case GL_ALIASED_LINE_WIDTH_RANGE: + params[0] = (GLfloat) ctx->Const.MinLineWidth; + params[1] = (GLfloat) ctx->Const.MaxLineWidth; + break; + case GL_LIST_BASE: + *params = (GLfloat) ctx->List.ListBase; + break; + case GL_LIST_INDEX: + *params = (GLfloat) ctx->CurrentListNum; + break; + case GL_LIST_MODE: + *params = ctx->ExecuteFlag ? ENUM_TO_FLOAT(GL_COMPILE_AND_EXECUTE) + : ENUM_TO_FLOAT(GL_COMPILE); + break; + case GL_INDEX_LOGIC_OP: + *params = (GLfloat) ctx->Color.IndexLogicOpEnabled; + break; + case GL_COLOR_LOGIC_OP: + *params = (GLfloat) ctx->Color.ColorLogicOpEnabled; + break; + case GL_LOGIC_OP_MODE: + *params = ENUM_TO_FLOAT(ctx->Color.LogicOp); + break; + case GL_MAP1_COLOR_4: + *params = (GLfloat) ctx->Eval.Map1Color4; + break; + case GL_MAP1_GRID_DOMAIN: + params[0] = ctx->Eval.MapGrid1u1; + params[1] = ctx->Eval.MapGrid1u2; + break; + case GL_MAP1_GRID_SEGMENTS: + *params = (GLfloat) ctx->Eval.MapGrid1un; + break; + case GL_MAP1_INDEX: + *params = (GLfloat) ctx->Eval.Map1Index; + break; + case GL_MAP1_NORMAL: + *params = (GLfloat) ctx->Eval.Map1Normal; + break; + case GL_MAP1_TEXTURE_COORD_1: + *params = (GLfloat) ctx->Eval.Map1TextureCoord1; + break; + case GL_MAP1_TEXTURE_COORD_2: + *params = (GLfloat) ctx->Eval.Map1TextureCoord2; + break; + case GL_MAP1_TEXTURE_COORD_3: + *params = (GLfloat) ctx->Eval.Map1TextureCoord3; + break; + case GL_MAP1_TEXTURE_COORD_4: + *params = (GLfloat) ctx->Eval.Map1TextureCoord4; + break; + case GL_MAP1_VERTEX_3: + *params = (GLfloat) ctx->Eval.Map1Vertex3; + break; + case GL_MAP1_VERTEX_4: + *params = (GLfloat) ctx->Eval.Map1Vertex4; + break; + case GL_MAP2_COLOR_4: + *params = (GLfloat) ctx->Eval.Map2Color4; + break; + case GL_MAP2_GRID_DOMAIN: + params[0] = ctx->Eval.MapGrid2u1; + params[1] = ctx->Eval.MapGrid2u2; + params[2] = ctx->Eval.MapGrid2v1; + params[3] = ctx->Eval.MapGrid2v2; + break; + case GL_MAP2_GRID_SEGMENTS: + params[0] = (GLfloat) ctx->Eval.MapGrid2un; + params[1] = (GLfloat) ctx->Eval.MapGrid2vn; + break; + case GL_MAP2_INDEX: + *params = (GLfloat) ctx->Eval.Map2Index; + break; + case GL_MAP2_NORMAL: + *params = (GLfloat) ctx->Eval.Map2Normal; + break; + case GL_MAP2_TEXTURE_COORD_1: + *params = ctx->Eval.Map2TextureCoord1; + break; + case GL_MAP2_TEXTURE_COORD_2: + *params = ctx->Eval.Map2TextureCoord2; + break; + case GL_MAP2_TEXTURE_COORD_3: + *params = ctx->Eval.Map2TextureCoord3; + break; + case GL_MAP2_TEXTURE_COORD_4: + *params = ctx->Eval.Map2TextureCoord4; + break; + case GL_MAP2_VERTEX_3: + *params = (GLfloat) ctx->Eval.Map2Vertex3; + break; + case GL_MAP2_VERTEX_4: + *params = (GLfloat) ctx->Eval.Map2Vertex4; + break; + case GL_MAP_COLOR: + *params = (GLfloat) ctx->Pixel.MapColorFlag; + break; + case GL_MAP_STENCIL: + *params = (GLfloat) ctx->Pixel.MapStencilFlag; + break; + case GL_MATRIX_MODE: + *params = ENUM_TO_FLOAT(ctx->Transform.MatrixMode); + break; + case GL_MAX_ATTRIB_STACK_DEPTH: + *params = (GLfloat) MAX_ATTRIB_STACK_DEPTH; + break; + case GL_MAX_CLIENT_ATTRIB_STACK_DEPTH: + *params = (GLfloat) MAX_CLIENT_ATTRIB_STACK_DEPTH; + break; + case GL_MAX_CLIP_PLANES: + *params = (GLfloat) ctx->Const.MaxClipPlanes; + break; + case GL_MAX_ELEMENTS_VERTICES: /* GL_VERSION_1_2 */ + *params = (GLfloat) ctx->Const.MaxArrayLockSize; + break; + case GL_MAX_ELEMENTS_INDICES: /* GL_VERSION_1_2 */ + *params = (GLfloat) ctx->Const.MaxArrayLockSize; + break; + case GL_MAX_EVAL_ORDER: + *params = (GLfloat) MAX_EVAL_ORDER; + break; + case GL_MAX_LIGHTS: + *params = (GLfloat) ctx->Const.MaxLights; + break; + case GL_MAX_LIST_NESTING: + *params = (GLfloat) MAX_LIST_NESTING; + break; + case GL_MAX_MODELVIEW_STACK_DEPTH: + *params = (GLfloat) MAX_MODELVIEW_STACK_DEPTH; + break; + case GL_MAX_NAME_STACK_DEPTH: + *params = (GLfloat) MAX_NAME_STACK_DEPTH; + break; + case GL_MAX_PIXEL_MAP_TABLE: + *params = (GLfloat) MAX_PIXEL_MAP_TABLE; + break; + case GL_MAX_PROJECTION_STACK_DEPTH: + *params = (GLfloat) MAX_PROJECTION_STACK_DEPTH; + break; + case GL_MAX_TEXTURE_SIZE: + *params = (GLfloat) (1 << (ctx->Const.MaxTextureLevels - 1)); + break; + case GL_MAX_3D_TEXTURE_SIZE: + *params = (GLfloat) (1 << (ctx->Const.Max3DTextureLevels - 1)); + break; + case GL_MAX_TEXTURE_STACK_DEPTH: + *params = (GLfloat) MAX_TEXTURE_STACK_DEPTH; + break; + case GL_MAX_VIEWPORT_DIMS: + params[0] = (GLfloat) MAX_WIDTH; + params[1] = (GLfloat) MAX_HEIGHT; + break; + case GL_MINMAX: + *params = (GLfloat) ctx->Pixel.MinMaxEnabled; + break; + case GL_MODELVIEW_MATRIX: + for (i=0;i<16;i++) { + params[i] = ctx->ModelView.m[i]; + } + break; + case GL_MODELVIEW_STACK_DEPTH: + *params = (GLfloat) (ctx->ModelViewStackDepth + 1); + break; + case GL_NAME_STACK_DEPTH: + *params = (GLfloat) ctx->Select.NameStackDepth; + break; + case GL_NORMALIZE: + *params = (GLfloat) ctx->Transform.Normalize; + break; + case GL_PACK_ALIGNMENT: + *params = (GLfloat) ctx->Pack.Alignment; + break; + case GL_PACK_LSB_FIRST: + *params = (GLfloat) ctx->Pack.LsbFirst; + break; + case GL_PACK_ROW_LENGTH: + *params = (GLfloat) ctx->Pack.RowLength; + break; + case GL_PACK_SKIP_PIXELS: + *params = (GLfloat) ctx->Pack.SkipPixels; + break; + case GL_PACK_SKIP_ROWS: + *params = (GLfloat) ctx->Pack.SkipRows; + break; + case GL_PACK_SWAP_BYTES: + *params = (GLfloat) ctx->Pack.SwapBytes; + break; + case GL_PACK_SKIP_IMAGES_EXT: + *params = (GLfloat) ctx->Pack.SkipImages; + break; + case GL_PACK_IMAGE_HEIGHT_EXT: + *params = (GLfloat) ctx->Pack.ImageHeight; + break; + case GL_PERSPECTIVE_CORRECTION_HINT: + *params = ENUM_TO_FLOAT(ctx->Hint.PerspectiveCorrection); + break; + case GL_PIXEL_MAP_A_TO_A_SIZE: + *params = (GLfloat) ctx->Pixel.MapAtoAsize; + break; + case GL_PIXEL_MAP_B_TO_B_SIZE: + *params = (GLfloat) ctx->Pixel.MapBtoBsize; + break; + case GL_PIXEL_MAP_G_TO_G_SIZE: + *params = (GLfloat) ctx->Pixel.MapGtoGsize; + break; + case GL_PIXEL_MAP_I_TO_A_SIZE: + *params = (GLfloat) ctx->Pixel.MapItoAsize; + break; + case GL_PIXEL_MAP_I_TO_B_SIZE: + *params = (GLfloat) ctx->Pixel.MapItoBsize; + break; + case GL_PIXEL_MAP_I_TO_G_SIZE: + *params = (GLfloat) ctx->Pixel.MapItoGsize; + break; + case GL_PIXEL_MAP_I_TO_I_SIZE: + *params = (GLfloat) ctx->Pixel.MapItoIsize; + break; + case GL_PIXEL_MAP_I_TO_R_SIZE: + *params = (GLfloat) ctx->Pixel.MapItoRsize; + break; + case GL_PIXEL_MAP_R_TO_R_SIZE: + *params = (GLfloat) ctx->Pixel.MapRtoRsize; + break; + case GL_PIXEL_MAP_S_TO_S_SIZE: + *params = (GLfloat) ctx->Pixel.MapStoSsize; + break; + case GL_POINT_SIZE: + *params = (GLfloat) ctx->Point.Size; + break; + case GL_POINT_SIZE_GRANULARITY: + *params = (GLfloat) ctx->Const.PointSizeGranularity; + break; + case GL_POINT_SIZE_RANGE: + params[0] = (GLfloat) ctx->Const.MinPointSizeAA; + params[1] = (GLfloat) ctx->Const.MaxPointSizeAA; + break; + case GL_ALIASED_POINT_SIZE_RANGE: + params[0] = (GLfloat) ctx->Const.MinPointSize; + params[1] = (GLfloat) ctx->Const.MaxPointSize; + break; + case GL_POINT_SMOOTH: + *params = (GLfloat) ctx->Point.SmoothFlag; + break; + case GL_POINT_SMOOTH_HINT: + *params = ENUM_TO_FLOAT(ctx->Hint.PointSmooth); + break; + case GL_POINT_SIZE_MIN_EXT: + *params = (GLfloat) (ctx->Point.MinSize); + break; + case GL_POINT_SIZE_MAX_EXT: + *params = (GLfloat) (ctx->Point.MaxSize); + break; + case GL_POINT_FADE_THRESHOLD_SIZE_EXT: + *params = (GLfloat) (ctx->Point.Threshold); + break; + case GL_DISTANCE_ATTENUATION_EXT: + params[0] = (GLfloat) (ctx->Point.Params[0]); + params[1] = (GLfloat) (ctx->Point.Params[1]); + params[2] = (GLfloat) (ctx->Point.Params[2]); + break; + case GL_POLYGON_MODE: + params[0] = ENUM_TO_FLOAT(ctx->Polygon.FrontMode); + params[1] = ENUM_TO_FLOAT(ctx->Polygon.BackMode); + break; +#ifdef GL_EXT_polygon_offset + case GL_POLYGON_OFFSET_BIAS_EXT: + *params = ctx->Polygon.OffsetUnits; + break; +#endif + case GL_POLYGON_OFFSET_FACTOR: + *params = ctx->Polygon.OffsetFactor; + break; + case GL_POLYGON_OFFSET_UNITS: + *params = ctx->Polygon.OffsetUnits; + break; + case GL_POLYGON_SMOOTH: + *params = (GLfloat) ctx->Polygon.SmoothFlag; + break; + case GL_POLYGON_SMOOTH_HINT: + *params = ENUM_TO_FLOAT(ctx->Hint.PolygonSmooth); + break; + case GL_POLYGON_STIPPLE: + *params = (GLfloat) ctx->Polygon.StippleFlag; + break; + case GL_PROJECTION_MATRIX: + for (i=0;i<16;i++) { + params[i] = ctx->ProjectionMatrix.m[i]; + } + break; + case GL_PROJECTION_STACK_DEPTH: + *params = (GLfloat) (ctx->ProjectionStackDepth + 1); + break; + case GL_READ_BUFFER: + *params = ENUM_TO_FLOAT(ctx->Pixel.ReadBuffer); + break; + case GL_RED_BIAS: + *params = ctx->Pixel.RedBias; + break; + case GL_RED_BITS: + *params = (GLfloat) ctx->Visual.redBits; + break; + case GL_RED_SCALE: + *params = ctx->Pixel.RedScale; + break; + case GL_RENDER_MODE: + *params = ENUM_TO_FLOAT(ctx->RenderMode); + break; + case GL_RESCALE_NORMAL: + *params = (GLfloat) ctx->Transform.RescaleNormals; + break; + case GL_RGBA_MODE: + *params = (GLfloat) ctx->Visual.rgbMode; + break; + case GL_SCISSOR_BOX: + params[0] = (GLfloat) ctx->Scissor.X; + params[1] = (GLfloat) ctx->Scissor.Y; + params[2] = (GLfloat) ctx->Scissor.Width; + params[3] = (GLfloat) ctx->Scissor.Height; + break; + case GL_SCISSOR_TEST: + *params = (GLfloat) ctx->Scissor.Enabled; + break; + case GL_SELECTION_BUFFER_SIZE: + *params = (GLfloat) ctx->Select.BufferSize; + break; + case GL_SHADE_MODEL: + *params = ENUM_TO_FLOAT(ctx->Light.ShadeModel); + break; + case GL_SHARED_TEXTURE_PALETTE_EXT: + *params = (GLfloat) ctx->Texture.SharedPalette; + break; + case GL_STENCIL_BITS: + *params = (GLfloat) ctx->Visual.stencilBits; + break; + case GL_STENCIL_CLEAR_VALUE: + *params = (GLfloat) ctx->Stencil.Clear; + break; + case GL_STENCIL_FAIL: + *params = ENUM_TO_FLOAT(ctx->Stencil.FailFunc); + break; + case GL_STENCIL_FUNC: + *params = ENUM_TO_FLOAT(ctx->Stencil.Function); + break; + case GL_STENCIL_PASS_DEPTH_FAIL: + *params = ENUM_TO_FLOAT(ctx->Stencil.ZFailFunc); + break; + case GL_STENCIL_PASS_DEPTH_PASS: + *params = ENUM_TO_FLOAT(ctx->Stencil.ZPassFunc); + break; + case GL_STENCIL_REF: + *params = (GLfloat) ctx->Stencil.Ref; + break; + case GL_STENCIL_TEST: + *params = (GLfloat) ctx->Stencil.Enabled; + break; + case GL_STENCIL_VALUE_MASK: + *params = (GLfloat) ctx->Stencil.ValueMask; + break; + case GL_STENCIL_WRITEMASK: + *params = (GLfloat) ctx->Stencil.WriteMask; + break; + case GL_STEREO: + *params = (GLfloat) ctx->Visual.stereoMode; + break; + case GL_SUBPIXEL_BITS: + *params = (GLfloat) ctx->Const.SubPixelBits; + break; + case GL_TEXTURE_1D: + *params = _mesa_IsEnabled(GL_TEXTURE_1D) ? 1.0 : 0.0; + break; + case GL_TEXTURE_2D: + *params = _mesa_IsEnabled(GL_TEXTURE_2D) ? 1.0 : 0.0; + break; + case GL_TEXTURE_3D: + *params = _mesa_IsEnabled(GL_TEXTURE_3D) ? 1.0 : 0.0; + break; + case GL_TEXTURE_BINDING_1D: + *params = (GLfloat) textureUnit->Current1D->Name; + break; + case GL_TEXTURE_BINDING_2D: + *params = (GLfloat) textureUnit->Current2D->Name; + break; + case GL_TEXTURE_BINDING_3D: + *params = (GLfloat) textureUnit->Current2D->Name; + break; + case GL_TEXTURE_ENV_COLOR: + params[0] = textureUnit->EnvColor[0]; + params[1] = textureUnit->EnvColor[1]; + params[2] = textureUnit->EnvColor[2]; + params[3] = textureUnit->EnvColor[3]; + break; + case GL_TEXTURE_ENV_MODE: + *params = ENUM_TO_FLOAT(textureUnit->EnvMode); + break; + case GL_TEXTURE_GEN_S: + *params = (textureUnit->TexGenEnabled & S_BIT) ? 1.0 : 0.0; + break; + case GL_TEXTURE_GEN_T: + *params = (textureUnit->TexGenEnabled & T_BIT) ? 1.0 : 0.0; + break; + case GL_TEXTURE_GEN_R: + *params = (textureUnit->TexGenEnabled & R_BIT) ? 1.0 : 0.0; + break; + case GL_TEXTURE_GEN_Q: + *params = (textureUnit->TexGenEnabled & Q_BIT) ? 1.0 : 0.0; + break; + case GL_TEXTURE_MATRIX: + for (i=0;i<16;i++) { + params[i] = ctx->TextureMatrix[texUnit].m[i]; + } + break; + case GL_TEXTURE_STACK_DEPTH: + *params = (GLfloat) (ctx->TextureStackDepth[texUnit] + 1); + break; + case GL_UNPACK_ALIGNMENT: + *params = (GLfloat) ctx->Unpack.Alignment; + break; + case GL_UNPACK_LSB_FIRST: + *params = (GLfloat) ctx->Unpack.LsbFirst; + break; + case GL_UNPACK_ROW_LENGTH: + *params = (GLfloat) ctx->Unpack.RowLength; + break; + case GL_UNPACK_SKIP_PIXELS: + *params = (GLfloat) ctx->Unpack.SkipPixels; + break; + case GL_UNPACK_SKIP_ROWS: + *params = (GLfloat) ctx->Unpack.SkipRows; + break; + case GL_UNPACK_SWAP_BYTES: + *params = (GLfloat) ctx->Unpack.SwapBytes; + break; + case GL_UNPACK_SKIP_IMAGES_EXT: + *params = (GLfloat) ctx->Unpack.SkipImages; + break; + case GL_UNPACK_IMAGE_HEIGHT_EXT: + *params = (GLfloat) ctx->Unpack.ImageHeight; + break; + case GL_VIEWPORT: + params[0] = (GLfloat) ctx->Viewport.X; + params[1] = (GLfloat) ctx->Viewport.Y; + params[2] = (GLfloat) ctx->Viewport.Width; + params[3] = (GLfloat) ctx->Viewport.Height; + break; + case GL_ZOOM_X: + *params = (GLfloat) ctx->Pixel.ZoomX; + break; + case GL_ZOOM_Y: + *params = (GLfloat) ctx->Pixel.ZoomY; + break; + case GL_VERTEX_ARRAY: + *params = (GLfloat) ctx->Array.Vertex.Enabled; + break; + case GL_VERTEX_ARRAY_SIZE: + *params = (GLfloat) ctx->Array.Vertex.Size; + break; + case GL_VERTEX_ARRAY_TYPE: + *params = ENUM_TO_FLOAT(ctx->Array.Vertex.Type); + break; + case GL_VERTEX_ARRAY_STRIDE: + *params = (GLfloat) ctx->Array.Vertex.Stride; + break; + case GL_VERTEX_ARRAY_COUNT_EXT: + *params = 0.0; + break; + case GL_NORMAL_ARRAY: + *params = (GLfloat) ctx->Array.Normal.Enabled; + break; + case GL_NORMAL_ARRAY_TYPE: + *params = ENUM_TO_FLOAT(ctx->Array.Normal.Type); + break; + case GL_NORMAL_ARRAY_STRIDE: + *params = (GLfloat) ctx->Array.Normal.Stride; + break; + case GL_NORMAL_ARRAY_COUNT_EXT: + *params = 0.0; + break; + case GL_COLOR_ARRAY: + *params = (GLfloat) ctx->Array.Color.Enabled; + break; + case GL_COLOR_ARRAY_SIZE: + *params = (GLfloat) ctx->Array.Color.Size; + break; + case GL_COLOR_ARRAY_TYPE: + *params = ENUM_TO_FLOAT(ctx->Array.Color.Type); + break; + case GL_COLOR_ARRAY_STRIDE: + *params = (GLfloat) ctx->Array.Color.Stride; + break; + case GL_COLOR_ARRAY_COUNT_EXT: + *params = 0.0; + break; + case GL_INDEX_ARRAY: + *params = (GLfloat) ctx->Array.Index.Enabled; + break; + case GL_INDEX_ARRAY_TYPE: + *params = ENUM_TO_FLOAT(ctx->Array.Index.Type); + break; + case GL_INDEX_ARRAY_STRIDE: + *params = (GLfloat) ctx->Array.Index.Stride; + break; + case GL_INDEX_ARRAY_COUNT_EXT: + *params = 0.0; + break; + case GL_TEXTURE_COORD_ARRAY: + *params = (GLfloat) ctx->Array.TexCoord[texUnit].Enabled; + break; + case GL_TEXTURE_COORD_ARRAY_SIZE: + *params = (GLfloat) ctx->Array.TexCoord[texUnit].Size; + break; + case GL_TEXTURE_COORD_ARRAY_TYPE: + *params = ENUM_TO_FLOAT(ctx->Array.TexCoord[texUnit].Type); + break; + case GL_TEXTURE_COORD_ARRAY_STRIDE: + *params = (GLfloat) ctx->Array.TexCoord[texUnit].Stride; + break; + case GL_TEXTURE_COORD_ARRAY_COUNT_EXT: + *params = 0.0; + break; + case GL_EDGE_FLAG_ARRAY: + *params = (GLfloat) ctx->Array.EdgeFlag.Enabled; + break; + case GL_EDGE_FLAG_ARRAY_STRIDE: + *params = (GLfloat) ctx->Array.EdgeFlag.Stride; + break; + case GL_EDGE_FLAG_ARRAY_COUNT_EXT: + *params = 0.0; + break; + + /* GL_ARB_multitexture */ + case GL_MAX_TEXTURE_UNITS_ARB: + *params = (GLfloat) ctx->Const.MaxTextureUnits; + break; + case GL_ACTIVE_TEXTURE_ARB: + *params = (GLfloat) (GL_TEXTURE0_ARB + ctx->Texture.CurrentUnit); + break; + case GL_CLIENT_ACTIVE_TEXTURE_ARB: + *params = (GLfloat) (GL_TEXTURE0_ARB + ctx->Array.ActiveTexture); + break; + + /* GL_ARB_texture_cube_map */ + case GL_TEXTURE_CUBE_MAP_ARB: + if (ctx->Extensions.ARB_texture_cube_map) + *params = (GLfloat) _mesa_IsEnabled(GL_TEXTURE_CUBE_MAP_ARB); + else + _mesa_error(ctx, GL_INVALID_ENUM, "glGetFloatv"); + return; + case GL_TEXTURE_BINDING_CUBE_MAP_ARB: + if (ctx->Extensions.ARB_texture_cube_map) + *params = (GLfloat) textureUnit->CurrentCubeMap->Name; + else + _mesa_error(ctx, GL_INVALID_ENUM, "glGetFloatv"); + return; + case GL_MAX_CUBE_MAP_TEXTURE_SIZE_ARB: + if (ctx->Extensions.ARB_texture_cube_map) + *params = (GLfloat) (1 << (ctx->Const.MaxCubeTextureLevels - 1)); + else + _mesa_error(ctx, GL_INVALID_ENUM, "glGetFloatv"); + return; + + /* GL_ARB_texture_compression */ + case GL_TEXTURE_COMPRESSION_HINT_ARB: + if (ctx->Extensions.ARB_texture_compression) { + *params = (GLfloat) ctx->Hint.TextureCompression; + } + else + _mesa_error(ctx, GL_INVALID_ENUM, "glGetFloatv"); + break; + case GL_NUM_COMPRESSED_TEXTURE_FORMATS_ARB: + if (ctx->Extensions.ARB_texture_compression) { + *params = (GLfloat) ctx->Const.NumCompressedTextureFormats; + } + else + _mesa_error(ctx, GL_INVALID_ENUM, "glGetFloatv"); + break; + case GL_COMPRESSED_TEXTURE_FORMATS_ARB: + if (ctx->Extensions.ARB_texture_compression) { + GLuint i; + for (i = 0; i < ctx->Const.NumCompressedTextureFormats; i++) + params[i] = (GLfloat) ctx->Const.CompressedTextureFormats[i]; + } + else + _mesa_error(ctx, GL_INVALID_ENUM, "glGetFloatv"); + break; + + /* GL_EXT_compiled_vertex_array */ + case GL_ARRAY_ELEMENT_LOCK_FIRST_EXT: + *params = (GLfloat) ctx->Array.LockFirst; + break; + case GL_ARRAY_ELEMENT_LOCK_COUNT_EXT: + *params = (GLfloat) ctx->Array.LockCount; + break; + + /* GL_ARB_transpose_matrix */ + case GL_TRANSPOSE_COLOR_MATRIX_ARB: + _math_transposef(params, ctx->ColorMatrix.m); + break; + case GL_TRANSPOSE_MODELVIEW_MATRIX_ARB: + _math_transposef(params, ctx->ModelView.m); + break; + case GL_TRANSPOSE_PROJECTION_MATRIX_ARB: + _math_transposef(params, ctx->ProjectionMatrix.m); + break; + case GL_TRANSPOSE_TEXTURE_MATRIX_ARB: + _math_transposef(params, ctx->TextureMatrix[texUnit].m); + break; + + /* GL_HP_occlusion_test */ + case GL_OCCLUSION_TEST_HP: + if (ctx->Extensions.HP_occlusion_test) { + *params = (GLfloat) ctx->Depth.OcclusionTest; + } + else { + _mesa_error( ctx, GL_INVALID_ENUM, "glGetFloatv" ); + } + return; + case GL_OCCLUSION_TEST_RESULT_HP: + if (ctx->Extensions.HP_occlusion_test) { + if (ctx->Depth.OcclusionTest) + *params = (GLfloat) ctx->OcclusionResult; + else + *params = (GLfloat) ctx->OcclusionResultSaved; + /* reset flag now */ + ctx->OcclusionResult = GL_FALSE; + ctx->OcclusionResultSaved = GL_FALSE; + } + else { + _mesa_error( ctx, GL_INVALID_ENUM, "glGetFloatv" ); + } + return; + + /* GL_SGIS_pixel_texture */ + case GL_PIXEL_TEXTURE_SGIS: + *params = (GLfloat) ctx->Pixel.PixelTextureEnabled; + break; + + /* GL_SGIX_pixel_texture */ + case GL_PIXEL_TEX_GEN_SGIX: + *params = (GLfloat) ctx->Pixel.PixelTextureEnabled; + break; + case GL_PIXEL_TEX_GEN_MODE_SGIX: + *params = (GLfloat) pixel_texgen_mode(ctx); + break; + + /* GL_SGI_color_matrix (also in 1.2 imaging) */ + case GL_COLOR_MATRIX_SGI: + for (i=0;i<16;i++) { + params[i] = ctx->ColorMatrix.m[i]; + } + break; + case GL_COLOR_MATRIX_STACK_DEPTH_SGI: + *params = (GLfloat) (ctx->ColorStackDepth + 1); + break; + case GL_MAX_COLOR_MATRIX_STACK_DEPTH_SGI: + *params = (GLfloat) MAX_COLOR_STACK_DEPTH; + break; + case GL_POST_COLOR_MATRIX_RED_SCALE_SGI: + *params = ctx->Pixel.PostColorMatrixScale[0]; + break; + case GL_POST_COLOR_MATRIX_GREEN_SCALE_SGI: + *params = ctx->Pixel.PostColorMatrixScale[1]; + break; + case GL_POST_COLOR_MATRIX_BLUE_SCALE_SGI: + *params = ctx->Pixel.PostColorMatrixScale[2]; + break; + case GL_POST_COLOR_MATRIX_ALPHA_SCALE_SGI: + *params = ctx->Pixel.PostColorMatrixScale[3]; + break; + case GL_POST_COLOR_MATRIX_RED_BIAS_SGI: + *params = ctx->Pixel.PostColorMatrixBias[0]; + break; + case GL_POST_COLOR_MATRIX_GREEN_BIAS_SGI: + *params = ctx->Pixel.PostColorMatrixBias[1]; + break; + case GL_POST_COLOR_MATRIX_BLUE_BIAS_SGI: + *params = ctx->Pixel.PostColorMatrixBias[2]; + break; + case GL_POST_COLOR_MATRIX_ALPHA_BIAS_SGI: + *params = ctx->Pixel.PostColorMatrixBias[3]; + break; + + /* GL_EXT_convolution (also in 1.2 imaging) */ + case GL_CONVOLUTION_1D_EXT: + if (ctx->Extensions.EXT_convolution || ctx->Extensions.ARB_imaging) { + *params = (GLfloat) ctx->Pixel.Convolution1DEnabled; + } + else { + _mesa_error(ctx, GL_INVALID_ENUM, "glGetFloatv"); + return; + } + break; + case GL_CONVOLUTION_2D: + if (ctx->Extensions.EXT_convolution || ctx->Extensions.ARB_imaging) { + *params = (GLfloat) ctx->Pixel.Convolution2DEnabled; + } + else { + _mesa_error(ctx, GL_INVALID_ENUM, "glGetFloatv"); + return; + } + break; + case GL_SEPARABLE_2D: + if (ctx->Extensions.EXT_convolution || ctx->Extensions.ARB_imaging) { + *params = (GLfloat) ctx->Pixel.Separable2DEnabled; + } + else { + _mesa_error(ctx, GL_INVALID_ENUM, "glGetFloatv"); + return; + } + break; + case GL_MAX_CONVOLUTION_WIDTH: + *params = (GLfloat) ctx->Const.MaxConvolutionWidth; + break; + case GL_MAX_CONVOLUTION_HEIGHT: + *params = (GLfloat) ctx->Const.MaxConvolutionHeight; + break; + case GL_POST_CONVOLUTION_RED_SCALE_EXT: + *params = ctx->Pixel.PostConvolutionScale[0]; + break; + case GL_POST_CONVOLUTION_GREEN_SCALE_EXT: + *params = ctx->Pixel.PostConvolutionScale[1]; + break; + case GL_POST_CONVOLUTION_BLUE_SCALE_EXT: + *params = ctx->Pixel.PostConvolutionScale[2]; + break; + case GL_POST_CONVOLUTION_ALPHA_SCALE_EXT: + *params = ctx->Pixel.PostConvolutionScale[3]; + break; + case GL_POST_CONVOLUTION_RED_BIAS_EXT: + *params = ctx->Pixel.PostConvolutionBias[0]; + break; + case GL_POST_CONVOLUTION_GREEN_BIAS_EXT: + *params = ctx->Pixel.PostConvolutionBias[1]; + break; + case GL_POST_CONVOLUTION_BLUE_BIAS_EXT: + *params = ctx->Pixel.PostConvolutionBias[2]; + break; + case GL_POST_CONVOLUTION_ALPHA_BIAS_EXT: + *params = ctx->Pixel.PostConvolutionBias[2]; + break; + + /* GL_SGI_color_table (also in 1.2 imaging */ + case GL_COLOR_TABLE_SGI: + *params = (GLfloat) ctx->Pixel.ColorTableEnabled; + break; + case GL_POST_CONVOLUTION_COLOR_TABLE_SGI: + *params = (GLfloat) ctx->Pixel.PostConvolutionColorTableEnabled; + break; + case GL_POST_COLOR_MATRIX_COLOR_TABLE_SGI: + *params = (GLfloat) ctx->Pixel.PostColorMatrixColorTableEnabled; + break; + + /* GL_EXT_secondary_color */ + case GL_COLOR_SUM_EXT: + *params = (GLfloat) ctx->Fog.ColorSumEnabled; + break; + case GL_CURRENT_SECONDARY_COLOR_EXT: + FLUSH_CURRENT(ctx, 0); + params[0] = (ctx->Current.SecondaryColor[0]); + params[1] = (ctx->Current.SecondaryColor[1]); + params[2] = (ctx->Current.SecondaryColor[2]); + break; + case GL_SECONDARY_COLOR_ARRAY_EXT: + *params = (GLfloat) ctx->Array.SecondaryColor.Enabled; + break; + case GL_SECONDARY_COLOR_ARRAY_TYPE_EXT: + *params = (GLfloat) ctx->Array.SecondaryColor.Type; + break; + case GL_SECONDARY_COLOR_ARRAY_STRIDE_EXT: + *params = (GLfloat) ctx->Array.SecondaryColor.Stride; + break; + case GL_SECONDARY_COLOR_ARRAY_SIZE_EXT: + *params = (GLfloat) ctx->Array.SecondaryColor.Stride; + break; + + /* GL_EXT_fog_coord */ + case GL_CURRENT_FOG_COORDINATE_EXT: + FLUSH_CURRENT(ctx, 0); + *params = (GLfloat) ctx->Current.FogCoord; + break; + case GL_FOG_COORDINATE_ARRAY_EXT: + *params = (GLfloat) ctx->Array.FogCoord.Enabled; + break; + case GL_FOG_COORDINATE_ARRAY_TYPE_EXT: + *params = (GLfloat) ctx->Array.FogCoord.Type; + break; + case GL_FOG_COORDINATE_ARRAY_STRIDE_EXT: + *params = (GLfloat) ctx->Array.FogCoord.Stride; + break; + + /* GL_EXT_texture_filter_anisotropic */ + case GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT: + if (ctx->Extensions.EXT_texture_filter_anisotropic) { + *params = ctx->Const.MaxTextureMaxAnisotropy; + } + else { + _mesa_error( ctx, GL_INVALID_ENUM, "glGetFloatv" ); + return; + } + break; + + /* GL_ARB_multisample */ + case GL_MULTISAMPLE_ARB: + if (ctx->Extensions.ARB_multisample) { + *params = (GLfloat) ctx->Multisample.Enabled; + } + else { + _mesa_error(ctx, GL_INVALID_ENUM, "glGetFloatv"); + return; + } + case GL_SAMPLE_ALPHA_TO_COVERAGE_ARB: + if (ctx->Extensions.ARB_multisample) { + *params = (GLfloat) ctx->Multisample.SampleAlphaToCoverage; + } + else { + _mesa_error(ctx, GL_INVALID_ENUM, "glGetFloatv"); + return; + } + case GL_SAMPLE_ALPHA_TO_ONE_ARB: + if (ctx->Extensions.ARB_multisample) { + *params = (GLfloat) ctx->Multisample.SampleAlphaToOne; + } + else { + _mesa_error(ctx, GL_INVALID_ENUM, "glGetFloatv"); + return; + } + case GL_SAMPLE_COVERAGE_ARB: + if (ctx->Extensions.ARB_multisample) { + *params = (GLfloat) ctx->Multisample.SampleCoverage; + } + else { + _mesa_error(ctx, GL_INVALID_ENUM, "glGetFloatv"); + return; + } + case GL_SAMPLE_COVERAGE_VALUE_ARB: + if (ctx->Extensions.ARB_multisample) { + *params = ctx->Multisample.SampleCoverageValue; + } + else { + _mesa_error(ctx, GL_INVALID_ENUM, "glGetFloatv"); + return; + } + case GL_SAMPLE_COVERAGE_INVERT_ARB: + if (ctx->Extensions.ARB_multisample) { + *params = (GLfloat) ctx->Multisample.SampleCoverageInvert; + } + else { + _mesa_error(ctx, GL_INVALID_ENUM, "glGetFloatv"); + return; + } + case GL_SAMPLE_BUFFERS_ARB: + if (ctx->Extensions.ARB_multisample) { + *params = 0.0; /* XXX fix someday */ + } + else { + _mesa_error(ctx, GL_INVALID_ENUM, "glGetFloatv"); + return; + } + case GL_SAMPLES_ARB: + if (ctx->Extensions.ARB_multisample) { + *params = 0.0; /* XXX fix someday */ + } + else { + _mesa_error(ctx, GL_INVALID_ENUM, "glGetFloatv"); + return; + } + + /* GL_SGIS_generate_mipmap */ + case GL_GENERATE_MIPMAP_HINT_SGIS: + if (ctx->Extensions.SGIS_generate_mipmap) { + *params = (GLfloat) ctx->Hint.GenerateMipmap; + } + else { + _mesa_error(ctx, GL_INVALID_ENUM, "glGetFloatv"); + return; + } + break; + + default: + _mesa_error( ctx, GL_INVALID_ENUM, "glGetFloatv" ); + } +} + + +void +_mesa_GetIntegerv( GLenum pname, GLint *params ) +{ + GET_CURRENT_CONTEXT(ctx); + GLuint i; + GLuint texUnit = ctx->Texture.CurrentUnit; + const struct gl_texture_unit *textureUnit = &ctx->Texture.Unit[texUnit]; + ASSERT_OUTSIDE_BEGIN_END(ctx); + + if (!params) + return; + + /* We need this in order to get correct results for + * GL_OCCLUSION_TEST_RESULT_HP. There might be other important cases. + */ + FLUSH_VERTICES(ctx, 0); + + if (MESA_VERBOSE & VERBOSE_API) + fprintf(stderr, "glGetIntegerv %s\n", _mesa_lookup_enum_by_nr(pname)); + + if (ctx->Driver.GetIntegerv + && (*ctx->Driver.GetIntegerv)(ctx, pname, params)) + return; + + switch (pname) { + case GL_ACCUM_RED_BITS: + *params = (GLint) ctx->Visual.accumRedBits; + break; + case GL_ACCUM_GREEN_BITS: + *params = (GLint) ctx->Visual.accumGreenBits; + break; + case GL_ACCUM_BLUE_BITS: + *params = (GLint) ctx->Visual.accumBlueBits; + break; + case GL_ACCUM_ALPHA_BITS: + *params = (GLint) ctx->Visual.accumAlphaBits; + break; + case GL_ACCUM_CLEAR_VALUE: + params[0] = FLOAT_TO_INT( ctx->Accum.ClearColor[0] ); + params[1] = FLOAT_TO_INT( ctx->Accum.ClearColor[1] ); + params[2] = FLOAT_TO_INT( ctx->Accum.ClearColor[2] ); + params[3] = FLOAT_TO_INT( ctx->Accum.ClearColor[3] ); + break; + case GL_ALPHA_BIAS: + *params = (GLint) ctx->Pixel.AlphaBias; + break; + case GL_ALPHA_BITS: + *params = ctx->Visual.alphaBits; + break; + case GL_ALPHA_SCALE: + *params = (GLint) ctx->Pixel.AlphaScale; + break; + case GL_ALPHA_TEST: + *params = (GLint) ctx->Color.AlphaEnabled; + break; + case GL_ALPHA_TEST_REF: + *params = FLOAT_TO_INT( (GLfloat) ctx->Color.AlphaRef / CHAN_MAXF ); + break; + case GL_ALPHA_TEST_FUNC: + *params = (GLint) ctx->Color.AlphaFunc; + break; + case GL_ATTRIB_STACK_DEPTH: + *params = (GLint) (ctx->AttribStackDepth); + break; + case GL_AUTO_NORMAL: + *params = (GLint) ctx->Eval.AutoNormal; + break; + case GL_AUX_BUFFERS: + *params = (GLint) ctx->Const.NumAuxBuffers; + break; + case GL_BLEND: + *params = (GLint) ctx->Color.BlendEnabled; + break; + case GL_BLEND_DST: + *params = (GLint) ctx->Color.BlendDstRGB; + break; + case GL_BLEND_SRC: + *params = (GLint) ctx->Color.BlendSrcRGB; + break; + case GL_BLEND_SRC_RGB_EXT: + *params = (GLint) ctx->Color.BlendSrcRGB; + break; + case GL_BLEND_DST_RGB_EXT: + *params = (GLint) ctx->Color.BlendDstRGB; + break; + case GL_BLEND_SRC_ALPHA_EXT: + *params = (GLint) ctx->Color.BlendSrcA; + break; + case GL_BLEND_DST_ALPHA_EXT: + *params = (GLint) ctx->Color.BlendDstA; + break; + case GL_BLEND_EQUATION_EXT: + *params = (GLint) ctx->Color.BlendEquation; + break; + case GL_BLEND_COLOR_EXT: + params[0] = FLOAT_TO_INT( ctx->Color.BlendColor[0] ); + params[1] = FLOAT_TO_INT( ctx->Color.BlendColor[1] ); + params[2] = FLOAT_TO_INT( ctx->Color.BlendColor[2] ); + params[3] = FLOAT_TO_INT( ctx->Color.BlendColor[3] ); + break; + case GL_BLUE_BIAS: + *params = (GLint) ctx->Pixel.BlueBias; + break; + case GL_BLUE_BITS: + *params = (GLint) ctx->Visual.blueBits; + break; + case GL_BLUE_SCALE: + *params = (GLint) ctx->Pixel.BlueScale; + break; + case GL_CLIENT_ATTRIB_STACK_DEPTH: + *params = (GLint) (ctx->ClientAttribStackDepth); + break; + case GL_CLIP_PLANE0: + case GL_CLIP_PLANE1: + case GL_CLIP_PLANE2: + case GL_CLIP_PLANE3: + case GL_CLIP_PLANE4: + case GL_CLIP_PLANE5: + i = (GLint) (pname - GL_CLIP_PLANE0); + *params = (GLint) ctx->Transform.ClipEnabled[i]; + break; + case GL_COLOR_CLEAR_VALUE: + params[0] = FLOAT_TO_INT( (ctx->Color.ClearColor[0]) ); + params[1] = FLOAT_TO_INT( (ctx->Color.ClearColor[1]) ); + params[2] = FLOAT_TO_INT( (ctx->Color.ClearColor[2]) ); + params[3] = FLOAT_TO_INT( (ctx->Color.ClearColor[3]) ); + break; + case GL_COLOR_MATERIAL: + *params = (GLint) ctx->Light.ColorMaterialEnabled; + break; + case GL_COLOR_MATERIAL_FACE: + *params = (GLint) ctx->Light.ColorMaterialFace; + break; + case GL_COLOR_MATERIAL_PARAMETER: + *params = (GLint) ctx->Light.ColorMaterialMode; + break; + case GL_COLOR_WRITEMASK: + params[0] = ctx->Color.ColorMask[RCOMP] ? 1 : 0; + params[1] = ctx->Color.ColorMask[GCOMP] ? 1 : 0; + params[2] = ctx->Color.ColorMask[BCOMP] ? 1 : 0; + params[3] = ctx->Color.ColorMask[ACOMP] ? 1 : 0; + break; + case GL_CULL_FACE: + *params = (GLint) ctx->Polygon.CullFlag; + break; + case GL_CULL_FACE_MODE: + *params = (GLint) ctx->Polygon.CullFaceMode; + break; + case GL_CURRENT_COLOR: + FLUSH_CURRENT(ctx, 0); + params[0] = FLOAT_TO_INT( ( ctx->Current.Color[0] ) ); + params[1] = FLOAT_TO_INT( ( ctx->Current.Color[1] ) ); + params[2] = FLOAT_TO_INT( ( ctx->Current.Color[2] ) ); + params[3] = FLOAT_TO_INT( ( ctx->Current.Color[3] ) ); + break; + case GL_CURRENT_INDEX: + FLUSH_CURRENT(ctx, 0); + *params = (GLint) ctx->Current.Index; + break; + case GL_CURRENT_NORMAL: + FLUSH_CURRENT(ctx, 0); + params[0] = FLOAT_TO_INT( ctx->Current.Normal[0] ); + params[1] = FLOAT_TO_INT( ctx->Current.Normal[1] ); + params[2] = FLOAT_TO_INT( ctx->Current.Normal[2] ); + break; + case GL_CURRENT_RASTER_COLOR: + params[0] = FLOAT_TO_INT( ctx->Current.RasterColor[0] ); + params[1] = FLOAT_TO_INT( ctx->Current.RasterColor[1] ); + params[2] = FLOAT_TO_INT( ctx->Current.RasterColor[2] ); + params[3] = FLOAT_TO_INT( ctx->Current.RasterColor[3] ); + break; + case GL_CURRENT_RASTER_DISTANCE: + params[0] = (GLint) ctx->Current.RasterDistance; + break; + case GL_CURRENT_RASTER_INDEX: + *params = (GLint) ctx->Current.RasterIndex; + break; + case GL_CURRENT_RASTER_POSITION: + params[0] = (GLint) ctx->Current.RasterPos[0]; + params[1] = (GLint) ctx->Current.RasterPos[1]; + params[2] = (GLint) ctx->Current.RasterPos[2]; + params[3] = (GLint) ctx->Current.RasterPos[3]; + break; + case GL_CURRENT_RASTER_TEXTURE_COORDS: + params[0] = (GLint) ctx->Current.RasterMultiTexCoord[texUnit][0]; + params[1] = (GLint) ctx->Current.RasterMultiTexCoord[texUnit][1]; + params[2] = (GLint) ctx->Current.RasterMultiTexCoord[texUnit][2]; + params[3] = (GLint) ctx->Current.RasterMultiTexCoord[texUnit][3]; + break; + case GL_CURRENT_RASTER_POSITION_VALID: + *params = (GLint) ctx->Current.RasterPosValid; + break; + case GL_CURRENT_TEXTURE_COORDS: + FLUSH_CURRENT(ctx, 0); + params[0] = (GLint) ctx->Current.Texcoord[texUnit][0]; + params[1] = (GLint) ctx->Current.Texcoord[texUnit][1]; + params[2] = (GLint) ctx->Current.Texcoord[texUnit][2]; + params[3] = (GLint) ctx->Current.Texcoord[texUnit][3]; + break; + case GL_DEPTH_BIAS: + *params = (GLint) ctx->Pixel.DepthBias; + break; + case GL_DEPTH_BITS: + *params = ctx->Visual.depthBits; + break; + case GL_DEPTH_CLEAR_VALUE: + *params = (GLint) ctx->Depth.Clear; + break; + case GL_DEPTH_FUNC: + *params = (GLint) ctx->Depth.Func; + break; + case GL_DEPTH_RANGE: + params[0] = (GLint) ctx->Viewport.Near; + params[1] = (GLint) ctx->Viewport.Far; + break; + case GL_DEPTH_SCALE: + *params = (GLint) ctx->Pixel.DepthScale; + break; + case GL_DEPTH_TEST: + *params = (GLint) ctx->Depth.Test; + break; + case GL_DEPTH_WRITEMASK: + *params = (GLint) ctx->Depth.Mask; + break; + case GL_DITHER: + *params = (GLint) ctx->Color.DitherFlag; + break; + case GL_DOUBLEBUFFER: + *params = (GLint) ctx->Visual.doubleBufferMode; + break; + case GL_DRAW_BUFFER: + *params = (GLint) ctx->Color.DrawBuffer; + break; + case GL_EDGE_FLAG: + FLUSH_CURRENT(ctx, 0); + *params = (GLint) ctx->Current.EdgeFlag; + break; + case GL_FEEDBACK_BUFFER_SIZE: + *params = ctx->Feedback.BufferSize; + break; + case GL_FEEDBACK_BUFFER_TYPE: + *params = ctx->Feedback.Type; + break; + case GL_FOG: + *params = (GLint) ctx->Fog.Enabled; + break; + case GL_FOG_COLOR: + params[0] = FLOAT_TO_INT( ctx->Fog.Color[0] ); + params[1] = FLOAT_TO_INT( ctx->Fog.Color[1] ); + params[2] = FLOAT_TO_INT( ctx->Fog.Color[2] ); + params[3] = FLOAT_TO_INT( ctx->Fog.Color[3] ); + break; + case GL_FOG_DENSITY: + *params = (GLint) ctx->Fog.Density; + break; + case GL_FOG_END: + *params = (GLint) ctx->Fog.End; + break; + case GL_FOG_HINT: + *params = (GLint) ctx->Hint.Fog; + break; + case GL_FOG_INDEX: + *params = (GLint) ctx->Fog.Index; + break; + case GL_FOG_MODE: + *params = (GLint) ctx->Fog.Mode; + break; + case GL_FOG_START: + *params = (GLint) ctx->Fog.Start; + break; + case GL_FRONT_FACE: + *params = (GLint) ctx->Polygon.FrontFace; + break; + case GL_GREEN_BIAS: + *params = (GLint) ctx->Pixel.GreenBias; + break; + case GL_GREEN_BITS: + *params = (GLint) ctx->Visual.greenBits; + break; + case GL_GREEN_SCALE: + *params = (GLint) ctx->Pixel.GreenScale; + break; + case GL_HISTOGRAM: + if (ctx->Extensions.EXT_histogram || ctx->Extensions.ARB_imaging) { + *params = (GLint) ctx->Pixel.HistogramEnabled; + } + else { + _mesa_error(ctx, GL_INVALID_ENUM, "glGetFloatv"); + return; + } + break; + case GL_INDEX_BITS: + *params = (GLint) ctx->Visual.indexBits; + break; + case GL_INDEX_CLEAR_VALUE: + *params = (GLint) ctx->Color.ClearIndex; + break; + case GL_INDEX_MODE: + *params = ctx->Visual.rgbMode ? 0 : 1; + break; + case GL_INDEX_OFFSET: + *params = ctx->Pixel.IndexOffset; + break; + case GL_INDEX_SHIFT: + *params = ctx->Pixel.IndexShift; + break; + case GL_INDEX_WRITEMASK: + *params = (GLint) ctx->Color.IndexMask; + break; + case GL_LIGHT0: + case GL_LIGHT1: + case GL_LIGHT2: + case GL_LIGHT3: + case GL_LIGHT4: + case GL_LIGHT5: + case GL_LIGHT6: + case GL_LIGHT7: + *params = (GLint) ctx->Light.Light[pname-GL_LIGHT0].Enabled; + break; + case GL_LIGHTING: + *params = (GLint) ctx->Light.Enabled; + break; + case GL_LIGHT_MODEL_AMBIENT: + params[0] = FLOAT_TO_INT( ctx->Light.Model.Ambient[0] ); + params[1] = FLOAT_TO_INT( ctx->Light.Model.Ambient[1] ); + params[2] = FLOAT_TO_INT( ctx->Light.Model.Ambient[2] ); + params[3] = FLOAT_TO_INT( ctx->Light.Model.Ambient[3] ); + break; + case GL_LIGHT_MODEL_COLOR_CONTROL: + params[0] = (GLint) ctx->Light.Model.ColorControl; + break; + case GL_LIGHT_MODEL_LOCAL_VIEWER: + *params = (GLint) ctx->Light.Model.LocalViewer; + break; + case GL_LIGHT_MODEL_TWO_SIDE: + *params = (GLint) ctx->Light.Model.TwoSide; + break; + case GL_LINE_SMOOTH: + *params = (GLint) ctx->Line.SmoothFlag; + break; + case GL_LINE_SMOOTH_HINT: + *params = (GLint) ctx->Hint.LineSmooth; + break; + case GL_LINE_STIPPLE: + *params = (GLint) ctx->Line.StippleFlag; + break; + case GL_LINE_STIPPLE_PATTERN: + *params = (GLint) ctx->Line.StipplePattern; + break; + case GL_LINE_STIPPLE_REPEAT: + *params = (GLint) ctx->Line.StippleFactor; + break; + case GL_LINE_WIDTH: + *params = (GLint) ctx->Line.Width; + break; + case GL_LINE_WIDTH_GRANULARITY: + *params = (GLint) ctx->Const.LineWidthGranularity; + break; + case GL_LINE_WIDTH_RANGE: + params[0] = (GLint) ctx->Const.MinLineWidthAA; + params[1] = (GLint) ctx->Const.MaxLineWidthAA; + break; + case GL_ALIASED_LINE_WIDTH_RANGE: + params[0] = (GLint) ctx->Const.MinLineWidth; + params[1] = (GLint) ctx->Const.MaxLineWidth; + break; + case GL_LIST_BASE: + *params = (GLint) ctx->List.ListBase; + break; + case GL_LIST_INDEX: + *params = (GLint) ctx->CurrentListNum; + break; + case GL_LIST_MODE: + *params = ctx->ExecuteFlag ? (GLint) GL_COMPILE_AND_EXECUTE + : (GLint) GL_COMPILE; + break; + case GL_INDEX_LOGIC_OP: + *params = (GLint) ctx->Color.IndexLogicOpEnabled; + break; + case GL_COLOR_LOGIC_OP: + *params = (GLint) ctx->Color.ColorLogicOpEnabled; + break; + case GL_LOGIC_OP_MODE: + *params = (GLint) ctx->Color.LogicOp; + break; + case GL_MAP1_COLOR_4: + *params = (GLint) ctx->Eval.Map1Color4; + break; + case GL_MAP1_GRID_DOMAIN: + params[0] = (GLint) ctx->Eval.MapGrid1u1; + params[1] = (GLint) ctx->Eval.MapGrid1u2; + break; + case GL_MAP1_GRID_SEGMENTS: + *params = (GLint) ctx->Eval.MapGrid1un; + break; + case GL_MAP1_INDEX: + *params = (GLint) ctx->Eval.Map1Index; + break; + case GL_MAP1_NORMAL: + *params = (GLint) ctx->Eval.Map1Normal; + break; + case GL_MAP1_TEXTURE_COORD_1: + *params = (GLint) ctx->Eval.Map1TextureCoord1; + break; + case GL_MAP1_TEXTURE_COORD_2: + *params = (GLint) ctx->Eval.Map1TextureCoord2; + break; + case GL_MAP1_TEXTURE_COORD_3: + *params = (GLint) ctx->Eval.Map1TextureCoord3; + break; + case GL_MAP1_TEXTURE_COORD_4: + *params = (GLint) ctx->Eval.Map1TextureCoord4; + break; + case GL_MAP1_VERTEX_3: + *params = (GLint) ctx->Eval.Map1Vertex3; + break; + case GL_MAP1_VERTEX_4: + *params = (GLint) ctx->Eval.Map1Vertex4; + break; + case GL_MAP2_COLOR_4: + *params = (GLint) ctx->Eval.Map2Color4; + break; + case GL_MAP2_GRID_DOMAIN: + params[0] = (GLint) ctx->Eval.MapGrid2u1; + params[1] = (GLint) ctx->Eval.MapGrid2u2; + params[2] = (GLint) ctx->Eval.MapGrid2v1; + params[3] = (GLint) ctx->Eval.MapGrid2v2; + break; + case GL_MAP2_GRID_SEGMENTS: + params[0] = (GLint) ctx->Eval.MapGrid2un; + params[1] = (GLint) ctx->Eval.MapGrid2vn; + break; + case GL_MAP2_INDEX: + *params = (GLint) ctx->Eval.Map2Index; + break; + case GL_MAP2_NORMAL: + *params = (GLint) ctx->Eval.Map2Normal; + break; + case GL_MAP2_TEXTURE_COORD_1: + *params = (GLint) ctx->Eval.Map2TextureCoord1; + break; + case GL_MAP2_TEXTURE_COORD_2: + *params = (GLint) ctx->Eval.Map2TextureCoord2; + break; + case GL_MAP2_TEXTURE_COORD_3: + *params = (GLint) ctx->Eval.Map2TextureCoord3; + break; + case GL_MAP2_TEXTURE_COORD_4: + *params = (GLint) ctx->Eval.Map2TextureCoord4; + break; + case GL_MAP2_VERTEX_3: + *params = (GLint) ctx->Eval.Map2Vertex3; + break; + case GL_MAP2_VERTEX_4: + *params = (GLint) ctx->Eval.Map2Vertex4; + break; + case GL_MAP_COLOR: + *params = (GLint) ctx->Pixel.MapColorFlag; + break; + case GL_MAP_STENCIL: + *params = (GLint) ctx->Pixel.MapStencilFlag; + break; + case GL_MATRIX_MODE: + *params = (GLint) ctx->Transform.MatrixMode; + break; + case GL_MAX_ATTRIB_STACK_DEPTH: + *params = (GLint) MAX_ATTRIB_STACK_DEPTH; + break; + case GL_MAX_CLIENT_ATTRIB_STACK_DEPTH: + *params = (GLint) MAX_CLIENT_ATTRIB_STACK_DEPTH; + break; + case GL_MAX_CLIP_PLANES: + *params = (GLint) ctx->Const.MaxClipPlanes; + break; + case GL_MAX_ELEMENTS_VERTICES: /* GL_VERSION_1_2 */ + *params = (GLint) ctx->Const.MaxArrayLockSize; + break; + case GL_MAX_ELEMENTS_INDICES: /* GL_VERSION_1_2 */ + *params = (GLint) ctx->Const.MaxArrayLockSize; + break; + case GL_MAX_EVAL_ORDER: + *params = (GLint) MAX_EVAL_ORDER; + break; + case GL_MAX_LIGHTS: + *params = (GLint) ctx->Const.MaxLights; + break; + case GL_MAX_LIST_NESTING: + *params = (GLint) MAX_LIST_NESTING; + break; + case GL_MAX_MODELVIEW_STACK_DEPTH: + *params = (GLint) MAX_MODELVIEW_STACK_DEPTH; + break; + case GL_MAX_NAME_STACK_DEPTH: + *params = (GLint) MAX_NAME_STACK_DEPTH; + break; + case GL_MAX_PIXEL_MAP_TABLE: + *params = (GLint) MAX_PIXEL_MAP_TABLE; + break; + case GL_MAX_PROJECTION_STACK_DEPTH: + *params = (GLint) MAX_PROJECTION_STACK_DEPTH; + break; + case GL_MAX_TEXTURE_SIZE: + *params = (1 << (ctx->Const.MaxTextureLevels - 1)); + break; + case GL_MAX_3D_TEXTURE_SIZE: + *params = (1 << (ctx->Const.Max3DTextureLevels - 1)); + break; + case GL_MAX_TEXTURE_STACK_DEPTH: + *params = (GLint) MAX_TEXTURE_STACK_DEPTH; + break; + case GL_MAX_VIEWPORT_DIMS: + params[0] = (GLint) MAX_WIDTH; + params[1] = (GLint) MAX_HEIGHT; + break; + case GL_MINMAX: + *params = (GLint) ctx->Pixel.MinMaxEnabled; + break; + case GL_MODELVIEW_MATRIX: + for (i=0;i<16;i++) { + params[i] = (GLint) ctx->ModelView.m[i]; + } + break; + case GL_MODELVIEW_STACK_DEPTH: + *params = (GLint) (ctx->ModelViewStackDepth + 1); + break; + case GL_NAME_STACK_DEPTH: + *params = (GLint) ctx->Select.NameStackDepth; + break; + case GL_NORMALIZE: + *params = (GLint) ctx->Transform.Normalize; + break; + case GL_PACK_ALIGNMENT: + *params = ctx->Pack.Alignment; + break; + case GL_PACK_LSB_FIRST: + *params = (GLint) ctx->Pack.LsbFirst; + break; + case GL_PACK_ROW_LENGTH: + *params = ctx->Pack.RowLength; + break; + case GL_PACK_SKIP_PIXELS: + *params = ctx->Pack.SkipPixels; + break; + case GL_PACK_SKIP_ROWS: + *params = ctx->Pack.SkipRows; + break; + case GL_PACK_SWAP_BYTES: + *params = (GLint) ctx->Pack.SwapBytes; + break; + case GL_PACK_SKIP_IMAGES_EXT: + *params = ctx->Pack.SkipImages; + break; + case GL_PACK_IMAGE_HEIGHT_EXT: + *params = ctx->Pack.ImageHeight; + break; + case GL_PERSPECTIVE_CORRECTION_HINT: + *params = (GLint) ctx->Hint.PerspectiveCorrection; + break; + case GL_PIXEL_MAP_A_TO_A_SIZE: + *params = ctx->Pixel.MapAtoAsize; + break; + case GL_PIXEL_MAP_B_TO_B_SIZE: + *params = ctx->Pixel.MapBtoBsize; + break; + case GL_PIXEL_MAP_G_TO_G_SIZE: + *params = ctx->Pixel.MapGtoGsize; + break; + case GL_PIXEL_MAP_I_TO_A_SIZE: + *params = ctx->Pixel.MapItoAsize; + break; + case GL_PIXEL_MAP_I_TO_B_SIZE: + *params = ctx->Pixel.MapItoBsize; + break; + case GL_PIXEL_MAP_I_TO_G_SIZE: + *params = ctx->Pixel.MapItoGsize; + break; + case GL_PIXEL_MAP_I_TO_I_SIZE: + *params = ctx->Pixel.MapItoIsize; + break; + case GL_PIXEL_MAP_I_TO_R_SIZE: + *params = ctx->Pixel.MapItoRsize; + break; + case GL_PIXEL_MAP_R_TO_R_SIZE: + *params = ctx->Pixel.MapRtoRsize; + break; + case GL_PIXEL_MAP_S_TO_S_SIZE: + *params = ctx->Pixel.MapStoSsize; + break; + case GL_POINT_SIZE: + *params = (GLint) ctx->Point.Size; + break; + case GL_POINT_SIZE_GRANULARITY: + *params = (GLint) ctx->Const.PointSizeGranularity; + break; + case GL_POINT_SIZE_RANGE: + params[0] = (GLint) ctx->Const.MinPointSizeAA; + params[1] = (GLint) ctx->Const.MaxPointSizeAA; + break; + case GL_ALIASED_POINT_SIZE_RANGE: + params[0] = (GLint) ctx->Const.MinPointSize; + params[1] = (GLint) ctx->Const.MaxPointSize; + break; + case GL_POINT_SMOOTH: + *params = (GLint) ctx->Point.SmoothFlag; + break; + case GL_POINT_SMOOTH_HINT: + *params = (GLint) ctx->Hint.PointSmooth; + break; + case GL_POINT_SIZE_MIN_EXT: + *params = (GLint) (ctx->Point.MinSize); + break; + case GL_POINT_SIZE_MAX_EXT: + *params = (GLint) (ctx->Point.MaxSize); + break; + case GL_POINT_FADE_THRESHOLD_SIZE_EXT: + *params = (GLint) (ctx->Point.Threshold); + break; + case GL_DISTANCE_ATTENUATION_EXT: + params[0] = (GLint) (ctx->Point.Params[0]); + params[1] = (GLint) (ctx->Point.Params[1]); + params[2] = (GLint) (ctx->Point.Params[2]); + break; + case GL_POLYGON_MODE: + params[0] = (GLint) ctx->Polygon.FrontMode; + params[1] = (GLint) ctx->Polygon.BackMode; + break; + case GL_POLYGON_OFFSET_BIAS_EXT: /* GL_EXT_polygon_offset */ + *params = (GLint) ctx->Polygon.OffsetUnits; + break; + case GL_POLYGON_OFFSET_FACTOR: + *params = (GLint) ctx->Polygon.OffsetFactor; + break; + case GL_POLYGON_OFFSET_UNITS: + *params = (GLint) ctx->Polygon.OffsetUnits; + break; + case GL_POLYGON_SMOOTH: + *params = (GLint) ctx->Polygon.SmoothFlag; + break; + case GL_POLYGON_SMOOTH_HINT: + *params = (GLint) ctx->Hint.PolygonSmooth; + break; + case GL_POLYGON_STIPPLE: + *params = (GLint) ctx->Polygon.StippleFlag; + break; + case GL_PROJECTION_MATRIX: + for (i=0;i<16;i++) { + params[i] = (GLint) ctx->ProjectionMatrix.m[i]; + } + break; + case GL_PROJECTION_STACK_DEPTH: + *params = (GLint) (ctx->ProjectionStackDepth + 1); + break; + case GL_READ_BUFFER: + *params = (GLint) ctx->Pixel.ReadBuffer; + break; + case GL_RED_BIAS: + *params = (GLint) ctx->Pixel.RedBias; + break; + case GL_RED_BITS: + *params = (GLint) ctx->Visual.redBits; + break; + case GL_RED_SCALE: + *params = (GLint) ctx->Pixel.RedScale; + break; + case GL_RENDER_MODE: + *params = (GLint) ctx->RenderMode; + break; + case GL_RESCALE_NORMAL: + *params = (GLint) ctx->Transform.RescaleNormals; + break; + case GL_RGBA_MODE: + *params = (GLint) ctx->Visual.rgbMode; + break; + case GL_SCISSOR_BOX: + params[0] = (GLint) ctx->Scissor.X; + params[1] = (GLint) ctx->Scissor.Y; + params[2] = (GLint) ctx->Scissor.Width; + params[3] = (GLint) ctx->Scissor.Height; + break; + case GL_SCISSOR_TEST: + *params = (GLint) ctx->Scissor.Enabled; + break; + case GL_SELECTION_BUFFER_SIZE: + *params = (GLint) ctx->Select.BufferSize; + break; + case GL_SHADE_MODEL: + *params = (GLint) ctx->Light.ShadeModel; + break; + case GL_SHARED_TEXTURE_PALETTE_EXT: + *params = (GLint) ctx->Texture.SharedPalette; + break; + case GL_STENCIL_BITS: + *params = ctx->Visual.stencilBits; + break; + case GL_STENCIL_CLEAR_VALUE: + *params = (GLint) ctx->Stencil.Clear; + break; + case GL_STENCIL_FAIL: + *params = (GLint) ctx->Stencil.FailFunc; + break; + case GL_STENCIL_FUNC: + *params = (GLint) ctx->Stencil.Function; + break; + case GL_STENCIL_PASS_DEPTH_FAIL: + *params = (GLint) ctx->Stencil.ZFailFunc; + break; + case GL_STENCIL_PASS_DEPTH_PASS: + *params = (GLint) ctx->Stencil.ZPassFunc; + break; + case GL_STENCIL_REF: + *params = (GLint) ctx->Stencil.Ref; + break; + case GL_STENCIL_TEST: + *params = (GLint) ctx->Stencil.Enabled; + break; + case GL_STENCIL_VALUE_MASK: + *params = (GLint) ctx->Stencil.ValueMask; + break; + case GL_STENCIL_WRITEMASK: + *params = (GLint) ctx->Stencil.WriteMask; + break; + case GL_STEREO: + *params = (GLint) ctx->Visual.stereoMode; + break; + case GL_SUBPIXEL_BITS: + *params = ctx->Const.SubPixelBits; + break; + case GL_TEXTURE_1D: + *params = _mesa_IsEnabled(GL_TEXTURE_1D) ? 1 : 0; + break; + case GL_TEXTURE_2D: + *params = _mesa_IsEnabled(GL_TEXTURE_2D) ? 1 : 0; + break; + case GL_TEXTURE_3D: + *params = _mesa_IsEnabled(GL_TEXTURE_3D) ? 1 : 0; + break; + case GL_TEXTURE_BINDING_1D: + *params = textureUnit->Current1D->Name; + break; + case GL_TEXTURE_BINDING_2D: + *params = textureUnit->Current2D->Name; + break; + case GL_TEXTURE_BINDING_3D: + *params = textureUnit->Current3D->Name; + break; + case GL_TEXTURE_ENV_COLOR: + params[0] = FLOAT_TO_INT( textureUnit->EnvColor[0] ); + params[1] = FLOAT_TO_INT( textureUnit->EnvColor[1] ); + params[2] = FLOAT_TO_INT( textureUnit->EnvColor[2] ); + params[3] = FLOAT_TO_INT( textureUnit->EnvColor[3] ); + break; + case GL_TEXTURE_ENV_MODE: + *params = (GLint) textureUnit->EnvMode; + break; + case GL_TEXTURE_GEN_S: + *params = (textureUnit->TexGenEnabled & S_BIT) ? 1 : 0; + break; + case GL_TEXTURE_GEN_T: + *params = (textureUnit->TexGenEnabled & T_BIT) ? 1 : 0; + break; + case GL_TEXTURE_GEN_R: + *params = (textureUnit->TexGenEnabled & R_BIT) ? 1 : 0; + break; + case GL_TEXTURE_GEN_Q: + *params = (textureUnit->TexGenEnabled & Q_BIT) ? 1 : 0; + break; + case GL_TEXTURE_MATRIX: + for (i=0;i<16;i++) { + params[i] = (GLint) ctx->TextureMatrix[texUnit].m[i]; + } + break; + case GL_TEXTURE_STACK_DEPTH: + *params = (GLint) (ctx->TextureStackDepth[texUnit] + 1); + break; + case GL_UNPACK_ALIGNMENT: + *params = ctx->Unpack.Alignment; + break; + case GL_UNPACK_LSB_FIRST: + *params = (GLint) ctx->Unpack.LsbFirst; + break; + case GL_UNPACK_ROW_LENGTH: + *params = ctx->Unpack.RowLength; + break; + case GL_UNPACK_SKIP_PIXELS: + *params = ctx->Unpack.SkipPixels; + break; + case GL_UNPACK_SKIP_ROWS: + *params = ctx->Unpack.SkipRows; + break; + case GL_UNPACK_SWAP_BYTES: + *params = (GLint) ctx->Unpack.SwapBytes; + break; + case GL_UNPACK_SKIP_IMAGES_EXT: + *params = ctx->Unpack.SkipImages; + break; + case GL_UNPACK_IMAGE_HEIGHT_EXT: + *params = ctx->Unpack.ImageHeight; + break; + case GL_VIEWPORT: + params[0] = (GLint) ctx->Viewport.X; + params[1] = (GLint) ctx->Viewport.Y; + params[2] = (GLint) ctx->Viewport.Width; + params[3] = (GLint) ctx->Viewport.Height; + break; + case GL_ZOOM_X: + *params = (GLint) ctx->Pixel.ZoomX; + break; + case GL_ZOOM_Y: + *params = (GLint) ctx->Pixel.ZoomY; + break; + case GL_VERTEX_ARRAY: + *params = (GLint) ctx->Array.Vertex.Enabled; + break; + case GL_VERTEX_ARRAY_SIZE: + *params = ctx->Array.Vertex.Size; + break; + case GL_VERTEX_ARRAY_TYPE: + *params = ctx->Array.Vertex.Type; + break; + case GL_VERTEX_ARRAY_STRIDE: + *params = ctx->Array.Vertex.Stride; + break; + case GL_VERTEX_ARRAY_COUNT_EXT: + *params = 0; + break; + case GL_NORMAL_ARRAY: + *params = (GLint) ctx->Array.Normal.Enabled; + break; + case GL_NORMAL_ARRAY_TYPE: + *params = ctx->Array.Normal.Type; + break; + case GL_NORMAL_ARRAY_STRIDE: + *params = ctx->Array.Normal.Stride; + break; + case GL_NORMAL_ARRAY_COUNT_EXT: + *params = 0; + break; + case GL_COLOR_ARRAY: + *params = (GLint) ctx->Array.Color.Enabled; + break; + case GL_COLOR_ARRAY_SIZE: + *params = ctx->Array.Color.Size; + break; + case GL_COLOR_ARRAY_TYPE: + *params = ctx->Array.Color.Type; + break; + case GL_COLOR_ARRAY_STRIDE: + *params = ctx->Array.Color.Stride; + break; + case GL_COLOR_ARRAY_COUNT_EXT: + *params = 0; + break; + case GL_INDEX_ARRAY: + *params = (GLint) ctx->Array.Index.Enabled; + break; + case GL_INDEX_ARRAY_TYPE: + *params = ctx->Array.Index.Type; + break; + case GL_INDEX_ARRAY_STRIDE: + *params = ctx->Array.Index.Stride; + break; + case GL_INDEX_ARRAY_COUNT_EXT: + *params = 0; + break; + case GL_TEXTURE_COORD_ARRAY: + *params = (GLint) ctx->Array.TexCoord[texUnit].Enabled; + break; + case GL_TEXTURE_COORD_ARRAY_SIZE: + *params = ctx->Array.TexCoord[texUnit].Size; + break; + case GL_TEXTURE_COORD_ARRAY_TYPE: + *params = ctx->Array.TexCoord[texUnit].Type; + break; + case GL_TEXTURE_COORD_ARRAY_STRIDE: + *params = ctx->Array.TexCoord[texUnit].Stride; + break; + case GL_TEXTURE_COORD_ARRAY_COUNT_EXT: + *params = 0; + break; + case GL_EDGE_FLAG_ARRAY: + *params = (GLint) ctx->Array.EdgeFlag.Enabled; + break; + case GL_EDGE_FLAG_ARRAY_STRIDE: + *params = ctx->Array.EdgeFlag.Stride; + break; + case GL_EDGE_FLAG_ARRAY_COUNT_EXT: + *params = 0; + break; + + /* GL_ARB_multitexture */ + case GL_MAX_TEXTURE_UNITS_ARB: + *params = ctx->Const.MaxTextureUnits; + break; + case GL_ACTIVE_TEXTURE_ARB: + *params = GL_TEXTURE0_ARB + ctx->Texture.CurrentUnit; + break; + case GL_CLIENT_ACTIVE_TEXTURE_ARB: + *params = GL_TEXTURE0_ARB + ctx->Array.ActiveTexture; + break; + + /* GL_ARB_texture_cube_map */ + case GL_TEXTURE_CUBE_MAP_ARB: + if (ctx->Extensions.ARB_texture_cube_map) + *params = (GLint) _mesa_IsEnabled(GL_TEXTURE_CUBE_MAP_ARB); + else + _mesa_error(ctx, GL_INVALID_ENUM, "glGetIntegerv"); + return; + case GL_TEXTURE_BINDING_CUBE_MAP_ARB: + if (ctx->Extensions.ARB_texture_cube_map) + *params = textureUnit->CurrentCubeMap->Name; + else + _mesa_error(ctx, GL_INVALID_ENUM, "glGetIntegerv"); + return; + case GL_MAX_CUBE_MAP_TEXTURE_SIZE_ARB: + if (ctx->Extensions.ARB_texture_cube_map) + *params = (1 << (ctx->Const.MaxCubeTextureLevels - 1)); + else + _mesa_error(ctx, GL_INVALID_ENUM, "glGetIntegerv"); + return; + + /* GL_ARB_texture_compression */ + case GL_TEXTURE_COMPRESSION_HINT_ARB: + if (ctx->Extensions.ARB_texture_compression) { + *params = (GLint) ctx->Hint.TextureCompression; + } + else + _mesa_error(ctx, GL_INVALID_ENUM, "glGetIntegerv"); + break; + case GL_NUM_COMPRESSED_TEXTURE_FORMATS_ARB: + if (ctx->Extensions.ARB_texture_compression) { + *params = (GLint) ctx->Const.NumCompressedTextureFormats; + } + else + _mesa_error(ctx, GL_INVALID_ENUM, "glGetIntegerv"); + break; + case GL_COMPRESSED_TEXTURE_FORMATS_ARB: + if (ctx->Extensions.ARB_texture_compression) { + GLuint i; + for (i = 0; i < ctx->Const.NumCompressedTextureFormats; i++) + params[i] = (GLint) ctx->Const.CompressedTextureFormats[i]; + } + else + _mesa_error(ctx, GL_INVALID_ENUM, "glGetIntegerv"); + break; + + /* GL_EXT_compiled_vertex_array */ + case GL_ARRAY_ELEMENT_LOCK_FIRST_EXT: + *params = ctx->Array.LockFirst; + break; + case GL_ARRAY_ELEMENT_LOCK_COUNT_EXT: + *params = ctx->Array.LockCount; + break; + + /* GL_ARB_transpose_matrix */ + case GL_TRANSPOSE_COLOR_MATRIX_ARB: + { + GLfloat tm[16]; + GLuint i; + _math_transposef(tm, ctx->ColorMatrix.m); + for (i=0;i<16;i++) { + params[i] = (GLint) tm[i]; + } + } + break; + case GL_TRANSPOSE_MODELVIEW_MATRIX_ARB: + { + GLfloat tm[16]; + GLuint i; + _math_transposef(tm, ctx->ModelView.m); + for (i=0;i<16;i++) { + params[i] = (GLint) tm[i]; + } + } + break; + case GL_TRANSPOSE_PROJECTION_MATRIX_ARB: + { + GLfloat tm[16]; + GLuint i; + _math_transposef(tm, ctx->ProjectionMatrix.m); + for (i=0;i<16;i++) { + params[i] = (GLint) tm[i]; + } + } + break; + case GL_TRANSPOSE_TEXTURE_MATRIX_ARB: + { + GLfloat tm[16]; + GLuint i; + _math_transposef(tm, ctx->TextureMatrix[texUnit].m); + for (i=0;i<16;i++) { + params[i] = (GLint) tm[i]; + } + } + break; + + /* GL_HP_occlusion_test */ + case GL_OCCLUSION_TEST_HP: + if (ctx->Extensions.HP_occlusion_test) { + *params = (GLint) ctx->Depth.OcclusionTest; + } + else { + _mesa_error( ctx, GL_INVALID_ENUM, "glGetIntegerv" ); + } + return; + case GL_OCCLUSION_TEST_RESULT_HP: + if (ctx->Extensions.HP_occlusion_test) { + if (ctx->Depth.OcclusionTest) + *params = (GLint) ctx->OcclusionResult; + else + *params = (GLint) ctx->OcclusionResultSaved; + /* reset flag now */ + ctx->OcclusionResult = GL_FALSE; + ctx->OcclusionResultSaved = GL_FALSE; + } + else { + _mesa_error( ctx, GL_INVALID_ENUM, "glGetIntegerv" ); + } + return; + + /* GL_SGIS_pixel_texture */ + case GL_PIXEL_TEXTURE_SGIS: + *params = (GLint) ctx->Pixel.PixelTextureEnabled; + break; + + /* GL_SGIX_pixel_texture */ + case GL_PIXEL_TEX_GEN_SGIX: + *params = (GLint) ctx->Pixel.PixelTextureEnabled; + break; + case GL_PIXEL_TEX_GEN_MODE_SGIX: + *params = (GLint) pixel_texgen_mode(ctx); + break; + + /* GL_SGI_color_matrix (also in 1.2 imaging) */ + case GL_COLOR_MATRIX_SGI: + for (i=0;i<16;i++) { + params[i] = (GLint) ctx->ColorMatrix.m[i]; + } + break; + case GL_COLOR_MATRIX_STACK_DEPTH_SGI: + *params = ctx->ColorStackDepth + 1; + break; + case GL_MAX_COLOR_MATRIX_STACK_DEPTH_SGI: + *params = MAX_COLOR_STACK_DEPTH; + break; + case GL_POST_COLOR_MATRIX_RED_SCALE_SGI: + *params = (GLint) ctx->Pixel.PostColorMatrixScale[0]; + break; + case GL_POST_COLOR_MATRIX_GREEN_SCALE_SGI: + *params = (GLint) ctx->Pixel.PostColorMatrixScale[1]; + break; + case GL_POST_COLOR_MATRIX_BLUE_SCALE_SGI: + *params = (GLint) ctx->Pixel.PostColorMatrixScale[2]; + break; + case GL_POST_COLOR_MATRIX_ALPHA_SCALE_SGI: + *params = (GLint) ctx->Pixel.PostColorMatrixScale[3]; + break; + case GL_POST_COLOR_MATRIX_RED_BIAS_SGI: + *params = (GLint) ctx->Pixel.PostColorMatrixBias[0]; + break; + case GL_POST_COLOR_MATRIX_GREEN_BIAS_SGI: + *params = (GLint) ctx->Pixel.PostColorMatrixBias[1]; + break; + case GL_POST_COLOR_MATRIX_BLUE_BIAS_SGI: + *params = (GLint) ctx->Pixel.PostColorMatrixBias[2]; + break; + case GL_POST_COLOR_MATRIX_ALPHA_BIAS_SGI: + *params = (GLint) ctx->Pixel.PostColorMatrixBias[3]; + break; + + /* GL_EXT_convolution (also in 1.2 imaging) */ + case GL_CONVOLUTION_1D_EXT: + if (ctx->Extensions.EXT_convolution || ctx->Extensions.ARB_imaging) { + *params = (GLint) ctx->Pixel.Convolution1DEnabled; + } + else { + _mesa_error(ctx, GL_INVALID_ENUM, "glGetIntegerv"); + return; + } + break; + case GL_CONVOLUTION_2D: + if (ctx->Extensions.EXT_convolution || ctx->Extensions.ARB_imaging) { + *params = (GLint) ctx->Pixel.Convolution2DEnabled; + } + else { + _mesa_error(ctx, GL_INVALID_ENUM, "glGetIntegerv"); + return; + } + break; + case GL_SEPARABLE_2D: + if (ctx->Extensions.EXT_convolution || ctx->Extensions.ARB_imaging) { + *params = (GLint) ctx->Pixel.Separable2DEnabled; + } + else { + _mesa_error(ctx, GL_INVALID_ENUM, "glGetIntegerv"); + return; + } + break; + case GL_MAX_CONVOLUTION_WIDTH: + *params = ctx->Const.MaxConvolutionWidth; + break; + case GL_MAX_CONVOLUTION_HEIGHT: + *params = ctx->Const.MaxConvolutionHeight; + break; + case GL_POST_CONVOLUTION_RED_SCALE_EXT: + *params = (GLint) ctx->Pixel.PostConvolutionScale[0]; + break; + case GL_POST_CONVOLUTION_GREEN_SCALE_EXT: + *params = (GLint) ctx->Pixel.PostConvolutionScale[1]; + break; + case GL_POST_CONVOLUTION_BLUE_SCALE_EXT: + *params = (GLint) ctx->Pixel.PostConvolutionScale[2]; + break; + case GL_POST_CONVOLUTION_ALPHA_SCALE_EXT: + *params = (GLint) ctx->Pixel.PostConvolutionScale[3]; + break; + case GL_POST_CONVOLUTION_RED_BIAS_EXT: + *params = (GLint) ctx->Pixel.PostConvolutionBias[0]; + break; + case GL_POST_CONVOLUTION_GREEN_BIAS_EXT: + *params = (GLint) ctx->Pixel.PostConvolutionBias[1]; + break; + case GL_POST_CONVOLUTION_BLUE_BIAS_EXT: + *params = (GLint) ctx->Pixel.PostConvolutionBias[2]; + break; + case GL_POST_CONVOLUTION_ALPHA_BIAS_EXT: + *params = (GLint) ctx->Pixel.PostConvolutionBias[2]; + break; + + /* GL_SGI_color_table (also in 1.2 imaging */ + case GL_COLOR_TABLE_SGI: + *params = (GLint) ctx->Pixel.ColorTableEnabled; + break; + case GL_POST_CONVOLUTION_COLOR_TABLE_SGI: + *params = (GLint) ctx->Pixel.PostConvolutionColorTableEnabled; + break; + case GL_POST_COLOR_MATRIX_COLOR_TABLE_SGI: + *params = (GLint) ctx->Pixel.PostColorMatrixColorTableEnabled; + break; + + + /* GL_EXT_secondary_color */ + case GL_COLOR_SUM_EXT: + *params = (GLint) ctx->Fog.ColorSumEnabled; + break; + case GL_CURRENT_SECONDARY_COLOR_EXT: + FLUSH_CURRENT(ctx, 0); + params[0] = FLOAT_TO_INT( (ctx->Current.SecondaryColor[0]) ); + params[1] = FLOAT_TO_INT( (ctx->Current.SecondaryColor[1]) ); + params[2] = FLOAT_TO_INT( (ctx->Current.SecondaryColor[2]) ); + break; + case GL_SECONDARY_COLOR_ARRAY_EXT: + *params = (GLint) ctx->Array.SecondaryColor.Enabled; + break; + case GL_SECONDARY_COLOR_ARRAY_TYPE_EXT: + *params = (GLint) ctx->Array.SecondaryColor.Type; + break; + case GL_SECONDARY_COLOR_ARRAY_STRIDE_EXT: + *params = (GLint) ctx->Array.SecondaryColor.Stride; + break; + case GL_SECONDARY_COLOR_ARRAY_SIZE_EXT: + *params = (GLint) ctx->Array.SecondaryColor.Stride; + break; + + /* GL_EXT_fog_coord */ + case GL_CURRENT_FOG_COORDINATE_EXT: + if (ctx->Extensions.EXT_fog_coord) { + FLUSH_CURRENT(ctx, 0); + *params = (GLint) ctx->Current.FogCoord; + } + else { + _mesa_error( ctx, GL_INVALID_ENUM, "glGetIntegerv" ); + } + break; + case GL_FOG_COORDINATE_ARRAY_EXT: + if (ctx->Extensions.EXT_fog_coord) { + *params = (GLint) ctx->Array.FogCoord.Enabled; + } + else { + _mesa_error( ctx, GL_INVALID_ENUM, "glGetIntegerv" ); + } + break; + case GL_FOG_COORDINATE_ARRAY_TYPE_EXT: + if (ctx->Extensions.EXT_fog_coord) { + *params = (GLint) ctx->Array.FogCoord.Type; + } + else { + _mesa_error( ctx, GL_INVALID_ENUM, "glGetIntegerv" ); + } + break; + case GL_FOG_COORDINATE_ARRAY_STRIDE_EXT: + if (ctx->Extensions.EXT_fog_coord) { + *params = (GLint) ctx->Array.FogCoord.Stride; + } + else { + _mesa_error( ctx, GL_INVALID_ENUM, "glGetIntegerv" ); + } + break; + + /* GL_EXT_texture_filter_anisotropic */ + case GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT: + if (ctx->Extensions.EXT_texture_filter_anisotropic) { + *params = (GLint) ctx->Const.MaxTextureMaxAnisotropy; + } + else { + _mesa_error( ctx, GL_INVALID_ENUM, "glGetIntegerv" ); + return; + } + break; + + /* GL_ARB_multisample */ + case GL_MULTISAMPLE_ARB: + if (ctx->Extensions.ARB_multisample) { + *params = (GLint) ctx->Multisample.Enabled; + } + else { + _mesa_error(ctx, GL_INVALID_ENUM, "glGetIntegerv"); + return; + } + case GL_SAMPLE_ALPHA_TO_COVERAGE_ARB: + if (ctx->Extensions.ARB_multisample) { + *params = (GLint) ctx->Multisample.SampleAlphaToCoverage; + } + else { + _mesa_error(ctx, GL_INVALID_ENUM, "glGetIntegerv"); + return; + } + case GL_SAMPLE_ALPHA_TO_ONE_ARB: + if (ctx->Extensions.ARB_multisample) { + *params = (GLint) ctx->Multisample.SampleAlphaToOne; + } + else { + _mesa_error(ctx, GL_INVALID_ENUM, "glGetIntegerv"); + return; + } + case GL_SAMPLE_COVERAGE_ARB: + if (ctx->Extensions.ARB_multisample) { + *params = (GLint) ctx->Multisample.SampleCoverage; + } + else { + _mesa_error(ctx, GL_INVALID_ENUM, "glGetIntegerv"); + return; + } + case GL_SAMPLE_COVERAGE_VALUE_ARB: + if (ctx->Extensions.ARB_multisample) { + *params = (GLint) ctx->Multisample.SampleCoverageValue; + } + else { + _mesa_error(ctx, GL_INVALID_ENUM, "glGetIntegerv"); + return; + } + case GL_SAMPLE_COVERAGE_INVERT_ARB: + if (ctx->Extensions.ARB_multisample) { + *params = (GLint) ctx->Multisample.SampleCoverageInvert; + } + else { + _mesa_error(ctx, GL_INVALID_ENUM, "glGetIntegerv"); + return; + } + case GL_SAMPLE_BUFFERS_ARB: + if (ctx->Extensions.ARB_multisample) { + *params = 0; /* XXX fix someday */ + } + else { + _mesa_error(ctx, GL_INVALID_ENUM, "glGetIntegerv"); + return; + } + case GL_SAMPLES_ARB: + if (ctx->Extensions.ARB_multisample) { + *params = 0; /* XXX fix someday */ + } + else { + _mesa_error(ctx, GL_INVALID_ENUM, "glGetIntegerv"); + return; + } + + /* GL_SGIS_generate_mipmap */ + case GL_GENERATE_MIPMAP_HINT_SGIS: + if (ctx->Extensions.SGIS_generate_mipmap) { + *params = (GLint) ctx->Hint.GenerateMipmap; + } + else { + _mesa_error(ctx, GL_INVALID_ENUM, "glGetIntegerv"); + return; + } + break; + + default: + _mesa_error( ctx, GL_INVALID_ENUM, "glGetIntegerv" ); + } +} + + + +void +_mesa_GetPointerv( GLenum pname, GLvoid **params ) +{ + GET_CURRENT_CONTEXT(ctx); + GLuint texUnit = ctx->Texture.CurrentUnit; + ASSERT_OUTSIDE_BEGIN_END(ctx); + + if (!params) + return; + + if (MESA_VERBOSE & VERBOSE_API) + fprintf(stderr, "glGetPointerv %s\n", _mesa_lookup_enum_by_nr(pname)); + + if (ctx->Driver.GetPointerv + && (*ctx->Driver.GetPointerv)(ctx, pname, params)) + return; + + switch (pname) { + case GL_VERTEX_ARRAY_POINTER: + *params = ctx->Array.Vertex.Ptr; + break; + case GL_NORMAL_ARRAY_POINTER: + *params = ctx->Array.Normal.Ptr; + break; + case GL_COLOR_ARRAY_POINTER: + *params = ctx->Array.Color.Ptr; + break; + case GL_SECONDARY_COLOR_ARRAY_POINTER_EXT: + *params = ctx->Array.SecondaryColor.Ptr; + break; + case GL_FOG_COORDINATE_ARRAY_POINTER_EXT: + *params = ctx->Array.FogCoord.Ptr; + break; + case GL_INDEX_ARRAY_POINTER: + *params = ctx->Array.Index.Ptr; + break; + case GL_TEXTURE_COORD_ARRAY_POINTER: + *params = ctx->Array.TexCoord[texUnit].Ptr; + break; + case GL_EDGE_FLAG_ARRAY_POINTER: + *params = ctx->Array.EdgeFlag.Ptr; + break; + case GL_FEEDBACK_BUFFER_POINTER: + *params = ctx->Feedback.Buffer; + break; + case GL_SELECTION_BUFFER_POINTER: + *params = ctx->Select.Buffer; + break; + default: + _mesa_error( ctx, GL_INVALID_ENUM, "glGetPointerv" ); + return; + } +} + + + +const GLubyte * +_mesa_GetString( GLenum name ) +{ + GET_CURRENT_CONTEXT(ctx); + static const char *vendor = "Brian Paul"; + static const char *renderer = "Mesa"; + static const char *version = "1.2 Mesa 3.5"; + ASSERT_OUTSIDE_BEGIN_END_WITH_RETVAL(ctx, 0); + + /* this is a required driver function */ + assert(ctx->Driver.GetString); + { + const GLubyte *str = (*ctx->Driver.GetString)(ctx, name); + if (str) + return str; + + switch (name) { + case GL_VENDOR: + return (const GLubyte *) vendor; + case GL_RENDERER: + return (const GLubyte *) renderer; + case GL_VERSION: + return (const GLubyte *) version; + case GL_EXTENSIONS: + return (const GLubyte *) _mesa_extensions_get_string(ctx); + default: + _mesa_error( ctx, GL_INVALID_ENUM, "glGetString" ); + return (const GLubyte *) 0; + } + } +} + + +/* + * Execute a glGetError command + */ +GLenum +_mesa_GetError( void ) +{ + GET_CURRENT_CONTEXT(ctx); + GLenum e = ctx->ErrorValue; + ASSERT_OUTSIDE_BEGIN_END_WITH_RETVAL(ctx, 0); + + if (MESA_VERBOSE & VERBOSE_API) + fprintf(stderr, "glGetError <-- %s\n", _mesa_lookup_enum_by_nr(e)); + + ctx->ErrorValue = (GLenum) GL_NO_ERROR; + return e; +} Index: dll/opengl/opengl32/mesa/get.h =================================================================== --- dll/opengl/opengl32/mesa/get.h (revision 0) +++ dll/opengl/opengl32/mesa/get.h (working copy) @@ -0,0 +1,58 @@ +/* $Id: get.h,v 1.5 2001/03/12 00:48:38 gareth Exp $ */ + +/* + * Mesa 3-D graphics library + * Version: 3.5 + * + * Copyright (C) 1999-2001 Brian Paul 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 + * BRIAN PAUL 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. + */ + + +#ifndef GET_H +#define GET_H + + +#include "mtypes.h" + + +extern void +_mesa_GetBooleanv( GLenum pname, GLboolean *params ); + +extern void +_mesa_GetDoublev( GLenum pname, GLdouble *params ); + +extern void +_mesa_GetFloatv( GLenum pname, GLfloat *params ); + +extern void +_mesa_GetIntegerv( GLenum pname, GLint *params ); + +extern void +_mesa_GetPointerv( GLenum pname, GLvoid **params ); + +extern const GLubyte * +_mesa_GetString( GLenum name ); + +extern GLenum +_mesa_GetError( void ); + + + +#endif Index: dll/opengl/opengl32/mesa/glapi.c =================================================================== --- dll/opengl/opengl32/mesa/glapi.c (revision 0) +++ dll/opengl/opengl32/mesa/glapi.c (working copy) @@ -0,0 +1,2060 @@ +/* $Id: glapi.c,v 1.56 2001/06/06 22:55:28 davem69 Exp $ */ + +/* + * Mesa 3-D graphics library + * Version: 3.5 + * + * Copyright (C) 1999-2001 Brian Paul 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 + * BRIAN PAUL 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. + */ + + +/* + * This file manages the OpenGL API dispatch layer. + * The dispatch table (struct _glapi_table) is basically just a list + * of function pointers. + * There are functions to set/get the current dispatch table for the + * current thread and to manage registration/dispatch of dynamically + * added extension functions. + * + * It's intended that this file and the other glapi*.[ch] files are + * flexible enough to be reused in several places: XFree86, DRI- + * based libGL.so, and perhaps the SGI SI. + * + * There are no dependencies on Mesa in this code. + * + * Versions (API changes): + * 2000/02/23 - original version for Mesa 3.3 and XFree86 4.0 + * 2001/01/16 - added dispatch override feature for Mesa 3.5 + */ + + + +#include "glheader.h" +#include "glapi.h" +#include "glapioffsets.h" +#include "glapitable.h" +#include "glthread.h" + +/***** BEGIN NO-OP DISPATCH *****/ + +static GLboolean WarnFlag = GL_FALSE; + +void +_glapi_noop_enable_warnings(GLboolean enable) +{ + WarnFlag = enable; +} + +static GLboolean +warn(void) +{ + if (WarnFlag || getenv("MESA_DEBUG") || getenv("LIBGL_DEBUG")) + return GL_TRUE; + else + return GL_FALSE; +} + + +#define KEYWORD1 static +#define KEYWORD2 +#define NAME(func) NoOp##func + +#define F stderr + +#define DISPATCH(func, args, msg) \ + if (warn()) { \ + fprintf(stderr, "GL User Error: calling "); \ + fprintf msg; \ + fprintf(stderr, " without a current context\n"); \ + } + +#define RETURN_DISPATCH(func, args, msg) \ + if (warn()) { \ + fprintf(stderr, "GL User Error: calling "); \ + fprintf msg; \ + fprintf(stderr, " without a current context\n"); \ + } \ + return 0 + +#define DISPATCH_TABLE_NAME __glapi_noop_table +#define UNUSED_TABLE_NAME __usused_noop_functions + +#define TABLE_ENTRY(name) (void *) NoOp##name + +static int NoOpUnused(void) +{ + if (warn()) { + fprintf(stderr, "GL User Error: calling extension function without a current context\n"); + } + return 0; +} + +#include "glapitemp.h" + +/***** END NO-OP DISPATCH *****/ + + + +/***** BEGIN THREAD-SAFE DISPATCH *****/ +/* if we support thread-safety, build a special dispatch table for use + * in thread-safety mode (ThreadSafe == GL_TRUE). Each entry in the + * dispatch table will call _glthread_GetTSD() to get the actual dispatch + * table bound to the current thread, then jump through that table. + */ + +#if defined(THREADS) + +static GLboolean ThreadSafe = GL_FALSE; /* In thread-safe mode? */ +static _glthread_TSD DispatchTSD; /* Per-thread dispatch pointer */ +static _glthread_TSD RealDispatchTSD; /* only when using override */ +static _glthread_TSD ContextTSD; /* Per-thread context pointer */ + + +#define KEYWORD1 static +#define KEYWORD2 GLAPIENTRY +#define NAME(func) _ts_##func + +#define DISPATCH(FUNC, ARGS, MESSAGE) \ + struct _glapi_table *dispatch; \ + dispatch = (struct _glapi_table *) _glthread_GetTSD(&DispatchTSD); \ + if (!dispatch) \ + dispatch = (struct _glapi_table *) __glapi_noop_table; \ + (dispatch->FUNC) ARGS + +#define RETURN_DISPATCH(FUNC, ARGS, MESSAGE) \ + struct _glapi_table *dispatch; \ + dispatch = (struct _glapi_table *) _glthread_GetTSD(&DispatchTSD); \ + if (!dispatch) \ + dispatch = (struct _glapi_table *) __glapi_noop_table; \ + return (dispatch->FUNC) ARGS + +#define DISPATCH_TABLE_NAME __glapi_threadsafe_table +#define UNUSED_TABLE_NAME __usused_threadsafe_functions + +#define TABLE_ENTRY(name) (void *) _ts_##name + +static int _ts_Unused(void) +{ + return 0; +} + +#include "glapitemp.h" + +#endif + +/***** END THREAD-SAFE DISPATCH *****/ + + + +struct _glapi_table *_glapi_Dispatch = (struct _glapi_table *) __glapi_noop_table; +struct _glapi_table *_glapi_RealDispatch = (struct _glapi_table *) __glapi_noop_table; + +/* Used when thread safety disabled */ +void *_glapi_Context = NULL; + + +static GLuint MaxDispatchOffset = sizeof(struct _glapi_table) / sizeof(void *) - 1; +static GLboolean GetSizeCalled = GL_FALSE; + +static GLboolean DispatchOverride = GL_FALSE; + + +/* strdup() is actually not a standard ANSI C or POSIX routine. + * Irix will not define it if ANSI mode is in effect. + */ +static char * +str_dup(const char *str) +{ + char *copy; + copy = (char*) malloc(strlen(str) + 1); + if (!copy) + return NULL; + strcpy(copy, str); + return copy; +} + + + +/* + * We should call this periodically from a function such as glXMakeCurrent + * in order to test if multiple threads are being used. When we detect + * that situation we should then call _glapi_enable_thread_safety() + */ +void +_glapi_check_multithread(void) +{ +#if defined(THREADS) + if (!ThreadSafe) { + static unsigned long knownID; + static GLboolean firstCall = GL_TRUE; + if (firstCall) { + knownID = _glthread_GetID(); + firstCall = GL_FALSE; + } + else if (knownID != _glthread_GetID()) { + ThreadSafe = GL_TRUE; + } + } + if (ThreadSafe) { + /* make sure that this thread's dispatch pointer isn't null */ + if (!_glapi_get_dispatch()) { + _glapi_set_dispatch(NULL); + } + } +#endif +} + + + +/* + * Set the current context pointer for this thread. + * The context pointer is an opaque type which should be cast to + * void from the real context pointer type. + */ +void +_glapi_set_context(void *context) +{ +#if defined(THREADS) + _glthread_SetTSD(&ContextTSD, context); + if (ThreadSafe) + _glapi_Context = NULL; + else + _glapi_Context = context; +#else + _glapi_Context = context; +#endif +} + + + +/* + * Get the current context pointer for this thread. + * The context pointer is an opaque type which should be cast from + * void to the real context pointer type. + */ +void * +_glapi_get_context(void) +{ +#if defined(THREADS) + if (ThreadSafe) { + return _glthread_GetTSD(&ContextTSD); + } + else { + return _glapi_Context; + } +#else + return _glapi_Context; +#endif +} + + + +/* + * Set the global or per-thread dispatch table pointer. + */ +void +_glapi_set_dispatch(struct _glapi_table *dispatch) +{ + if (!dispatch) { + /* use the no-op functions */ + dispatch = (struct _glapi_table *) __glapi_noop_table; + } +#ifdef DEBUG + else { + _glapi_check_table(dispatch); + } +#endif + +#if defined(THREADS) + if (DispatchOverride) { + _glthread_SetTSD(&RealDispatchTSD, (void *) dispatch); + if (ThreadSafe) + _glapi_RealDispatch = (struct _glapi_table*) __glapi_threadsafe_table; + else + _glapi_RealDispatch = dispatch; + } + else { + /* normal operation */ + _glthread_SetTSD(&DispatchTSD, (void *) dispatch); + if (ThreadSafe) + _glapi_Dispatch = (struct _glapi_table *) __glapi_threadsafe_table; + else + _glapi_Dispatch = dispatch; + } +#else /*THREADS*/ + if (DispatchOverride) { + _glapi_RealDispatch = dispatch; + } + else { + _glapi_Dispatch = dispatch; + } +#endif /*THREADS*/ +} + + + +/* + * Return pointer to current dispatch table for calling thread. + */ +struct _glapi_table * +_glapi_get_dispatch(void) +{ +#if defined(THREADS) + if (ThreadSafe) { + if (DispatchOverride) { + return (struct _glapi_table *) _glthread_GetTSD(&RealDispatchTSD); + } + else { + return (struct _glapi_table *) _glthread_GetTSD(&DispatchTSD); + } + } + else { + if (DispatchOverride) { + assert(_glapi_RealDispatch); + return _glapi_RealDispatch; + } + else { + assert(_glapi_Dispatch); + return _glapi_Dispatch; + } + } +#else + return _glapi_Dispatch; +#endif +} + + +/* + * Notes on dispatch overrride: + * + * Dispatch override allows an external agent to hook into the GL dispatch + * mechanism before execution goes into the core rendering library. For + * example, a trace mechanism would insert itself as an overrider, print + * logging info for each GL function, then dispatch to the real GL function. + * + * libGLS (GL Stream library) is another agent that might use override. + * + * We don't allow more than one layer of overriding at this time. + * In the future we may allow nested/layered override. In that case + * _glapi_begin_dispatch_override() will return an override layer, + * _glapi_end_dispatch_override(layer) will remove an override layer + * and _glapi_get_override_dispatch(layer) will return the dispatch + * table for a given override layer. layer = 0 will be the "real" + * dispatch table. + */ + +/* + * Return: dispatch override layer number. + */ +int +_glapi_begin_dispatch_override(struct _glapi_table *override) +{ + struct _glapi_table *real = _glapi_get_dispatch(); + + assert(!DispatchOverride); /* can't nest at this time */ + DispatchOverride = GL_TRUE; + + _glapi_set_dispatch(real); + +#if defined(THREADS) + _glthread_SetTSD(&DispatchTSD, (void *) override); + if (ThreadSafe) + _glapi_Dispatch = (struct _glapi_table *) __glapi_threadsafe_table; + else + _glapi_Dispatch = override; +#else + _glapi_Dispatch = override; +#endif + return 1; +} + + +void +_glapi_end_dispatch_override(int layer) +{ + struct _glapi_table *real = _glapi_get_dispatch(); + (void) layer; + DispatchOverride = GL_FALSE; + _glapi_set_dispatch(real); + /* the rest of this isn't needed, just play it safe */ +#if defined(THREADS) + _glthread_SetTSD(&RealDispatchTSD, NULL); +#endif + _glapi_RealDispatch = NULL; +} + + +struct _glapi_table * +_glapi_get_override_dispatch(int layer) +{ + if (layer == 0) { + return _glapi_get_dispatch(); + } + else { + if (DispatchOverride) { +#if defined(THREADS) + return (struct _glapi_table *) _glthread_GetTSD(&DispatchTSD); +#else + return _glapi_Dispatch; +#endif + } + else { + return NULL; + } + } +} + + + +/* + * Return size of dispatch table struct as number of functions (or + * slots). + */ +GLuint +_glapi_get_dispatch_table_size(void) +{ + /* return sizeof(struct _glapi_table) / sizeof(void *);*/ + GetSizeCalled = GL_TRUE; + return MaxDispatchOffset + 1; +} + + + +/* + * Get API dispatcher version string. + */ +const char * +_glapi_get_version(void) +{ + return "20010116"; /* YYYYMMDD */ +} + + +/* + * For each entry in static_functions[] which use this function + * we should implement a dispatch function in glapitemp.h and + * in glapinoop.c + */ +static int NotImplemented(void) +{ + return 0; +} + + +struct name_address_offset { + const char *Name; + GLvoid *Address; + GLuint Offset; +}; + + +static struct name_address_offset static_functions[] = { + /* GL 1.1 */ + { "glNewList", (GLvoid *) glNewList, _gloffset_NewList }, + { "glEndList", (GLvoid *) glEndList, _gloffset_EndList }, + { "glCallList", (GLvoid *) glCallList, _gloffset_CallList }, + { "glCallLists", (GLvoid *) glCallLists, _gloffset_CallLists }, + { "glDeleteLists", (GLvoid *) glDeleteLists, _gloffset_DeleteLists }, + { "glGenLists", (GLvoid *) glGenLists, _gloffset_GenLists }, + { "glListBase", (GLvoid *) glListBase, _gloffset_ListBase }, + { "glBegin", (GLvoid *) glBegin, _gloffset_Begin }, + { "glBitmap", (GLvoid *) glBitmap, _gloffset_Bitmap }, + { "glColor3b", (GLvoid *) glColor3b, _gloffset_Color3b }, + { "glColor3bv", (GLvoid *) glColor3bv, _gloffset_Color3bv }, + { "glColor3d", (GLvoid *) glColor3d, _gloffset_Color3d }, + { "glColor3dv", (GLvoid *) glColor3dv, _gloffset_Color3dv }, + { "glColor3f", (GLvoid *) glColor3f, _gloffset_Color3f }, + { "glColor3fv", (GLvoid *) glColor3fv, _gloffset_Color3fv }, + { "glColor3i", (GLvoid *) glColor3i, _gloffset_Color3i }, + { "glColor3iv", (GLvoid *) glColor3iv, _gloffset_Color3iv }, + { "glColor3s", (GLvoid *) glColor3s, _gloffset_Color3s }, + { "glColor3sv", (GLvoid *) glColor3sv, _gloffset_Color3sv }, + { "glColor3ub", (GLvoid *) glColor3ub, _gloffset_Color3ub }, + { "glColor3ubv", (GLvoid *) glColor3ubv, _gloffset_Color3ubv }, + { "glColor3ui", (GLvoid *) glColor3ui, _gloffset_Color3ui }, + { "glColor3uiv", (GLvoid *) glColor3uiv, _gloffset_Color3uiv }, + { "glColor3us", (GLvoid *) glColor3us, _gloffset_Color3us }, + { "glColor3usv", (GLvoid *) glColor3usv, _gloffset_Color3usv }, + { "glColor4b", (GLvoid *) glColor4b, _gloffset_Color4b }, + { "glColor4bv", (GLvoid *) glColor4bv, _gloffset_Color4bv }, + { "glColor4d", (GLvoid *) glColor4d, _gloffset_Color4d }, + { "glColor4dv", (GLvoid *) glColor4dv, _gloffset_Color4dv }, + { "glColor4f", (GLvoid *) glColor4f, _gloffset_Color4f }, + { "glColor4fv", (GLvoid *) glColor4fv, _gloffset_Color4fv }, + { "glColor4i", (GLvoid *) glColor4i, _gloffset_Color4i }, + { "glColor4iv", (GLvoid *) glColor4iv, _gloffset_Color4iv }, + { "glColor4s", (GLvoid *) glColor4s, _gloffset_Color4s }, + { "glColor4sv", (GLvoid *) glColor4sv, _gloffset_Color4sv }, + { "glColor4ub", (GLvoid *) glColor4ub, _gloffset_Color4ub }, + { "glColor4ubv", (GLvoid *) glColor4ubv, _gloffset_Color4ubv }, + { "glColor4ui", (GLvoid *) glColor4ui, _gloffset_Color4ui }, + { "glColor4uiv", (GLvoid *) glColor4uiv, _gloffset_Color4uiv }, + { "glColor4us", (GLvoid *) glColor4us, _gloffset_Color4us }, + { "glColor4usv", (GLvoid *) glColor4usv, _gloffset_Color4usv }, + { "glEdgeFlag", (GLvoid *) glEdgeFlag, _gloffset_EdgeFlag }, + { "glEdgeFlagv", (GLvoid *) glEdgeFlagv, _gloffset_EdgeFlagv }, + { "glEnd", (GLvoid *) glEnd, _gloffset_End }, + { "glIndexd", (GLvoid *) glIndexd, _gloffset_Indexd }, + { "glIndexdv", (GLvoid *) glIndexdv, _gloffset_Indexdv }, + { "glIndexf", (GLvoid *) glIndexf, _gloffset_Indexf }, + { "glIndexfv", (GLvoid *) glIndexfv, _gloffset_Indexfv }, + { "glIndexi", (GLvoid *) glIndexi, _gloffset_Indexi }, + { "glIndexiv", (GLvoid *) glIndexiv, _gloffset_Indexiv }, + { "glIndexs", (GLvoid *) glIndexs, _gloffset_Indexs }, + { "glIndexsv", (GLvoid *) glIndexsv, _gloffset_Indexsv }, + { "glNormal3b", (GLvoid *) glNormal3b, _gloffset_Normal3b }, + { "glNormal3bv", (GLvoid *) glNormal3bv, _gloffset_Normal3bv }, + { "glNormal3d", (GLvoid *) glNormal3d, _gloffset_Normal3d }, + { "glNormal3dv", (GLvoid *) glNormal3dv, _gloffset_Normal3dv }, + { "glNormal3f", (GLvoid *) glNormal3f, _gloffset_Normal3f }, + { "glNormal3fv", (GLvoid *) glNormal3fv, _gloffset_Normal3fv }, + { "glNormal3i", (GLvoid *) glNormal3i, _gloffset_Normal3i }, + { "glNormal3iv", (GLvoid *) glNormal3iv, _gloffset_Normal3iv }, + { "glNormal3s", (GLvoid *) glNormal3s, _gloffset_Normal3s }, + { "glNormal3sv", (GLvoid *) glNormal3sv, _gloffset_Normal3sv }, + { "glRasterPos2d", (GLvoid *) glRasterPos2d, _gloffset_RasterPos2d }, + { "glRasterPos2dv", (GLvoid *) glRasterPos2dv, _gloffset_RasterPos2dv }, + { "glRasterPos2f", (GLvoid *) glRasterPos2f, _gloffset_RasterPos2f }, + { "glRasterPos2fv", (GLvoid *) glRasterPos2fv, _gloffset_RasterPos2fv }, + { "glRasterPos2i", (GLvoid *) glRasterPos2i, _gloffset_RasterPos2i }, + { "glRasterPos2iv", (GLvoid *) glRasterPos2iv, _gloffset_RasterPos2iv }, + { "glRasterPos2s", (GLvoid *) glRasterPos2s, _gloffset_RasterPos2s }, + { "glRasterPos2sv", (GLvoid *) glRasterPos2sv, _gloffset_RasterPos2sv }, + { "glRasterPos3d", (GLvoid *) glRasterPos3d, _gloffset_RasterPos3d }, + { "glRasterPos3dv", (GLvoid *) glRasterPos3dv, _gloffset_RasterPos3dv }, + { "glRasterPos3f", (GLvoid *) glRasterPos3f, _gloffset_RasterPos3f }, + { "glRasterPos3fv", (GLvoid *) glRasterPos3fv, _gloffset_RasterPos3fv }, + { "glRasterPos3i", (GLvoid *) glRasterPos3i, _gloffset_RasterPos3i }, + { "glRasterPos3iv", (GLvoid *) glRasterPos3iv, _gloffset_RasterPos3iv }, + { "glRasterPos3s", (GLvoid *) glRasterPos3s, _gloffset_RasterPos3s }, + { "glRasterPos3sv", (GLvoid *) glRasterPos3sv, _gloffset_RasterPos3sv }, + { "glRasterPos4d", (GLvoid *) glRasterPos4d, _gloffset_RasterPos4d }, + { "glRasterPos4dv", (GLvoid *) glRasterPos4dv, _gloffset_RasterPos4dv }, + { "glRasterPos4f", (GLvoid *) glRasterPos4f, _gloffset_RasterPos4f }, + { "glRasterPos4fv", (GLvoid *) glRasterPos4fv, _gloffset_RasterPos4fv }, + { "glRasterPos4i", (GLvoid *) glRasterPos4i, _gloffset_RasterPos4i }, + { "glRasterPos4iv", (GLvoid *) glRasterPos4iv, _gloffset_RasterPos4iv }, + { "glRasterPos4s", (GLvoid *) glRasterPos4s, _gloffset_RasterPos4s }, + { "glRasterPos4sv", (GLvoid *) glRasterPos4sv, _gloffset_RasterPos4sv }, + { "glRectd", (GLvoid *) glRectd, _gloffset_Rectd }, + { "glRectdv", (GLvoid *) glRectdv, _gloffset_Rectdv }, + { "glRectf", (GLvoid *) glRectf, _gloffset_Rectf }, + { "glRectfv", (GLvoid *) glRectfv, _gloffset_Rectfv }, + { "glRecti", (GLvoid *) glRecti, _gloffset_Recti }, + { "glRectiv", (GLvoid *) glRectiv, _gloffset_Rectiv }, + { "glRects", (GLvoid *) glRects, _gloffset_Rects }, + { "glRectsv", (GLvoid *) glRectsv, _gloffset_Rectsv }, + { "glTexCoord1d", (GLvoid *) glTexCoord1d, _gloffset_TexCoord1d }, + { "glTexCoord1dv", (GLvoid *) glTexCoord1dv, _gloffset_TexCoord1dv }, + { "glTexCoord1f", (GLvoid *) glTexCoord1f, _gloffset_TexCoord1f }, + { "glTexCoord1fv", (GLvoid *) glTexCoord1fv, _gloffset_TexCoord1fv }, + { "glTexCoord1i", (GLvoid *) glTexCoord1i, _gloffset_TexCoord1i }, + { "glTexCoord1iv", (GLvoid *) glTexCoord1iv, _gloffset_TexCoord1iv }, + { "glTexCoord1s", (GLvoid *) glTexCoord1s, _gloffset_TexCoord1s }, + { "glTexCoord1sv", (GLvoid *) glTexCoord1sv, _gloffset_TexCoord1sv }, + { "glTexCoord2d", (GLvoid *) glTexCoord2d, _gloffset_TexCoord2d }, + { "glTexCoord2dv", (GLvoid *) glTexCoord2dv, _gloffset_TexCoord2dv }, + { "glTexCoord2f", (GLvoid *) glTexCoord2f, _gloffset_TexCoord2f }, + { "glTexCoord2fv", (GLvoid *) glTexCoord2fv, _gloffset_TexCoord2fv }, + { "glTexCoord2i", (GLvoid *) glTexCoord2i, _gloffset_TexCoord2i }, + { "glTexCoord2iv", (GLvoid *) glTexCoord2iv, _gloffset_TexCoord2iv }, + { "glTexCoord2s", (GLvoid *) glTexCoord2s, _gloffset_TexCoord2s }, + { "glTexCoord2sv", (GLvoid *) glTexCoord2sv, _gloffset_TexCoord2sv }, + { "glTexCoord3d", (GLvoid *) glTexCoord3d, _gloffset_TexCoord3d }, + { "glTexCoord3dv", (GLvoid *) glTexCoord3dv, _gloffset_TexCoord3dv }, + { "glTexCoord3f", (GLvoid *) glTexCoord3f, _gloffset_TexCoord3f }, + { "glTexCoord3fv", (GLvoid *) glTexCoord3fv, _gloffset_TexCoord3fv }, + { "glTexCoord3i", (GLvoid *) glTexCoord3i, _gloffset_TexCoord3i }, + { "glTexCoord3iv", (GLvoid *) glTexCoord3iv, _gloffset_TexCoord3iv }, + { "glTexCoord3s", (GLvoid *) glTexCoord3s, _gloffset_TexCoord3s }, + { "glTexCoord3sv", (GLvoid *) glTexCoord3sv, _gloffset_TexCoord3sv }, + { "glTexCoord4d", (GLvoid *) glTexCoord4d, _gloffset_TexCoord4d }, + { "glTexCoord4dv", (GLvoid *) glTexCoord4dv, _gloffset_TexCoord4dv }, + { "glTexCoord4f", (GLvoid *) glTexCoord4f, _gloffset_TexCoord4f }, + { "glTexCoord4fv", (GLvoid *) glTexCoord4fv, _gloffset_TexCoord4fv }, + { "glTexCoord4i", (GLvoid *) glTexCoord4i, _gloffset_TexCoord4i }, + { "glTexCoord4iv", (GLvoid *) glTexCoord4iv, _gloffset_TexCoord4iv }, + { "glTexCoord4s", (GLvoid *) glTexCoord4s, _gloffset_TexCoord4s }, + { "glTexCoord4sv", (GLvoid *) glTexCoord4sv, _gloffset_TexCoord4sv }, + { "glVertex2d", (GLvoid *) glVertex2d, _gloffset_Vertex2d }, + { "glVertex2dv", (GLvoid *) glVertex2dv, _gloffset_Vertex2dv }, + { "glVertex2f", (GLvoid *) glVertex2f, _gloffset_Vertex2f }, + { "glVertex2fv", (GLvoid *) glVertex2fv, _gloffset_Vertex2fv }, + { "glVertex2i", (GLvoid *) glVertex2i, _gloffset_Vertex2i }, + { "glVertex2iv", (GLvoid *) glVertex2iv, _gloffset_Vertex2iv }, + { "glVertex2s", (GLvoid *) glVertex2s, _gloffset_Vertex2s }, + { "glVertex2sv", (GLvoid *) glVertex2sv, _gloffset_Vertex2sv }, + { "glVertex3d", (GLvoid *) glVertex3d, _gloffset_Vertex3d }, + { "glVertex3dv", (GLvoid *) glVertex3dv, _gloffset_Vertex3dv }, + { "glVertex3f", (GLvoid *) glVertex3f, _gloffset_Vertex3f }, + { "glVertex3fv", (GLvoid *) glVertex3fv, _gloffset_Vertex3fv }, + { "glVertex3i", (GLvoid *) glVertex3i, _gloffset_Vertex3i }, + { "glVertex3iv", (GLvoid *) glVertex3iv, _gloffset_Vertex3iv }, + { "glVertex3s", (GLvoid *) glVertex3s, _gloffset_Vertex3s }, + { "glVertex3sv", (GLvoid *) glVertex3sv, _gloffset_Vertex3sv }, + { "glVertex4d", (GLvoid *) glVertex4d, _gloffset_Vertex4d }, + { "glVertex4dv", (GLvoid *) glVertex4dv, _gloffset_Vertex4dv }, + { "glVertex4f", (GLvoid *) glVertex4f, _gloffset_Vertex4f }, + { "glVertex4fv", (GLvoid *) glVertex4fv, _gloffset_Vertex4fv }, + { "glVertex4i", (GLvoid *) glVertex4i, _gloffset_Vertex4i }, + { "glVertex4iv", (GLvoid *) glVertex4iv, _gloffset_Vertex4iv }, + { "glVertex4s", (GLvoid *) glVertex4s, _gloffset_Vertex4s }, + { "glVertex4sv", (GLvoid *) glVertex4sv, _gloffset_Vertex4sv }, + { "glClipPlane", (GLvoid *) glClipPlane, _gloffset_ClipPlane }, + { "glColorMaterial", (GLvoid *) glColorMaterial, _gloffset_ColorMaterial }, + { "glCullFace", (GLvoid *) glCullFace, _gloffset_CullFace }, + { "glFogf", (GLvoid *) glFogf, _gloffset_Fogf }, + { "glFogfv", (GLvoid *) glFogfv, _gloffset_Fogfv }, + { "glFogi", (GLvoid *) glFogi, _gloffset_Fogi }, + { "glFogiv", (GLvoid *) glFogiv, _gloffset_Fogiv }, + { "glFrontFace", (GLvoid *) glFrontFace, _gloffset_FrontFace }, + { "glHint", (GLvoid *) glHint, _gloffset_Hint }, + { "glLightf", (GLvoid *) glLightf, _gloffset_Lightf }, + { "glLightfv", (GLvoid *) glLightfv, _gloffset_Lightfv }, + { "glLighti", (GLvoid *) glLighti, _gloffset_Lighti }, + { "glLightiv", (GLvoid *) glLightiv, _gloffset_Lightiv }, + { "glLightModelf", (GLvoid *) glLightModelf, _gloffset_LightModelf }, + { "glLightModelfv", (GLvoid *) glLightModelfv, _gloffset_LightModelfv }, + { "glLightModeli", (GLvoid *) glLightModeli, _gloffset_LightModeli }, + { "glLightModeliv", (GLvoid *) glLightModeliv, _gloffset_LightModeliv }, + { "glLineStipple", (GLvoid *) glLineStipple, _gloffset_LineStipple }, + { "glLineWidth", (GLvoid *) glLineWidth, _gloffset_LineWidth }, + { "glMaterialf", (GLvoid *) glMaterialf, _gloffset_Materialf }, + { "glMaterialfv", (GLvoid *) glMaterialfv, _gloffset_Materialfv }, + { "glMateriali", (GLvoid *) glMateriali, _gloffset_Materiali }, + { "glMaterialiv", (GLvoid *) glMaterialiv, _gloffset_Materialiv }, + { "glPointSize", (GLvoid *) glPointSize, _gloffset_PointSize }, + { "glPolygonMode", (GLvoid *) glPolygonMode, _gloffset_PolygonMode }, + { "glPolygonStipple", (GLvoid *) glPolygonStipple, _gloffset_PolygonStipple }, + { "glScissor", (GLvoid *) glScissor, _gloffset_Scissor }, + { "glShadeModel", (GLvoid *) glShadeModel, _gloffset_ShadeModel }, + { "glTexParameterf", (GLvoid *) glTexParameterf, _gloffset_TexParameterf }, + { "glTexParameterfv", (GLvoid *) glTexParameterfv, _gloffset_TexParameterfv }, + { "glTexParameteri", (GLvoid *) glTexParameteri, _gloffset_TexParameteri }, + { "glTexParameteriv", (GLvoid *) glTexParameteriv, _gloffset_TexParameteriv }, + { "glTexImage1D", (GLvoid *) glTexImage1D, _gloffset_TexImage1D }, + { "glTexImage2D", (GLvoid *) glTexImage2D, _gloffset_TexImage2D }, + { "glTexEnvf", (GLvoid *) glTexEnvf, _gloffset_TexEnvf }, + { "glTexEnvfv", (GLvoid *) glTexEnvfv, _gloffset_TexEnvfv }, + { "glTexEnvi", (GLvoid *) glTexEnvi, _gloffset_TexEnvi }, + { "glTexEnviv", (GLvoid *) glTexEnviv, _gloffset_TexEnviv }, + { "glTexGend", (GLvoid *) glTexGend, _gloffset_TexGend }, + { "glTexGendv", (GLvoid *) glTexGendv, _gloffset_TexGendv }, + { "glTexGenf", (GLvoid *) glTexGenf, _gloffset_TexGenf }, + { "glTexGenfv", (GLvoid *) glTexGenfv, _gloffset_TexGenfv }, + { "glTexGeni", (GLvoid *) glTexGeni, _gloffset_TexGeni }, + { "glTexGeniv", (GLvoid *) glTexGeniv, _gloffset_TexGeniv }, + { "glFeedbackBuffer", (GLvoid *) glFeedbackBuffer, _gloffset_FeedbackBuffer }, + { "glSelectBuffer", (GLvoid *) glSelectBuffer, _gloffset_SelectBuffer }, + { "glRenderMode", (GLvoid *) glRenderMode, _gloffset_RenderMode }, + { "glInitNames", (GLvoid *) glInitNames, _gloffset_InitNames }, + { "glLoadName", (GLvoid *) glLoadName, _gloffset_LoadName }, + { "glPassThrough", (GLvoid *) glPassThrough, _gloffset_PassThrough }, + { "glPopName", (GLvoid *) glPopName, _gloffset_PopName }, + { "glPushName", (GLvoid *) glPushName, _gloffset_PushName }, + { "glDrawBuffer", (GLvoid *) glDrawBuffer, _gloffset_DrawBuffer }, + { "glClear", (GLvoid *) glClear, _gloffset_Clear }, + { "glClearAccum", (GLvoid *) glClearAccum, _gloffset_ClearAccum }, + { "glClearIndex", (GLvoid *) glClearIndex, _gloffset_ClearIndex }, + { "glClearColor", (GLvoid *) glClearColor, _gloffset_ClearColor }, + { "glClearStencil", (GLvoid *) glClearStencil, _gloffset_ClearStencil }, + { "glClearDepth", (GLvoid *) glClearDepth, _gloffset_ClearDepth }, + { "glStencilMask", (GLvoid *) glStencilMask, _gloffset_StencilMask }, + { "glColorMask", (GLvoid *) glColorMask, _gloffset_ColorMask }, + { "glDepthMask", (GLvoid *) glDepthMask, _gloffset_DepthMask }, + { "glIndexMask", (GLvoid *) glIndexMask, _gloffset_IndexMask }, + { "glAccum", (GLvoid *) glAccum, _gloffset_Accum }, + { "glDisable", (GLvoid *) glDisable, _gloffset_Disable }, + { "glEnable", (GLvoid *) glEnable, _gloffset_Enable }, + { "glFinish", (GLvoid *) glFinish, _gloffset_Finish }, + { "glFlush", (GLvoid *) glFlush, _gloffset_Flush }, + { "glPopAttrib", (GLvoid *) glPopAttrib, _gloffset_PopAttrib }, + { "glPushAttrib", (GLvoid *) glPushAttrib, _gloffset_PushAttrib }, + { "glMap1d", (GLvoid *) glMap1d, _gloffset_Map1d }, + { "glMap1f", (GLvoid *) glMap1f, _gloffset_Map1f }, + { "glMap2d", (GLvoid *) glMap2d, _gloffset_Map2d }, + { "glMap2f", (GLvoid *) glMap2f, _gloffset_Map2f }, + { "glMapGrid1d", (GLvoid *) glMapGrid1d, _gloffset_MapGrid1d }, + { "glMapGrid1f", (GLvoid *) glMapGrid1f, _gloffset_MapGrid1f }, + { "glMapGrid2d", (GLvoid *) glMapGrid2d, _gloffset_MapGrid2d }, + { "glMapGrid2f", (GLvoid *) glMapGrid2f, _gloffset_MapGrid2f }, + { "glEvalCoord1d", (GLvoid *) glEvalCoord1d, _gloffset_EvalCoord1d }, + { "glEvalCoord1dv", (GLvoid *) glEvalCoord1dv, _gloffset_EvalCoord1dv }, + { "glEvalCoord1f", (GLvoid *) glEvalCoord1f, _gloffset_EvalCoord1f }, + { "glEvalCoord1fv", (GLvoid *) glEvalCoord1fv, _gloffset_EvalCoord1fv }, + { "glEvalCoord2d", (GLvoid *) glEvalCoord2d, _gloffset_EvalCoord2d }, + { "glEvalCoord2dv", (GLvoid *) glEvalCoord2dv, _gloffset_EvalCoord2dv }, + { "glEvalCoord2f", (GLvoid *) glEvalCoord2f, _gloffset_EvalCoord2f }, + { "glEvalCoord2fv", (GLvoid *) glEvalCoord2fv, _gloffset_EvalCoord2fv }, + { "glEvalMesh1", (GLvoid *) glEvalMesh1, _gloffset_EvalMesh1 }, + { "glEvalPoint1", (GLvoid *) glEvalPoint1, _gloffset_EvalPoint1 }, + { "glEvalMesh2", (GLvoid *) glEvalMesh2, _gloffset_EvalMesh2 }, + { "glEvalPoint2", (GLvoid *) glEvalPoint2, _gloffset_EvalPoint2 }, + { "glAlphaFunc", (GLvoid *) glAlphaFunc, _gloffset_AlphaFunc }, + { "glBlendFunc", (GLvoid *) glBlendFunc, _gloffset_BlendFunc }, + { "glLogicOp", (GLvoid *) glLogicOp, _gloffset_LogicOp }, + { "glStencilFunc", (GLvoid *) glStencilFunc, _gloffset_StencilFunc }, + { "glStencilOp", (GLvoid *) glStencilOp, _gloffset_StencilOp }, + { "glDepthFunc", (GLvoid *) glDepthFunc, _gloffset_DepthFunc }, + { "glPixelZoom", (GLvoid *) glPixelZoom, _gloffset_PixelZoom }, + { "glPixelTransferf", (GLvoid *) glPixelTransferf, _gloffset_PixelTransferf }, + { "glPixelTransferi", (GLvoid *) glPixelTransferi, _gloffset_PixelTransferi }, + { "glPixelStoref", (GLvoid *) glPixelStoref, _gloffset_PixelStoref }, + { "glPixelStorei", (GLvoid *) glPixelStorei, _gloffset_PixelStorei }, + { "glPixelMapfv", (GLvoid *) glPixelMapfv, _gloffset_PixelMapfv }, + { "glPixelMapuiv", (GLvoid *) glPixelMapuiv, _gloffset_PixelMapuiv }, + { "glPixelMapusv", (GLvoid *) glPixelMapusv, _gloffset_PixelMapusv }, + { "glReadBuffer", (GLvoid *) glReadBuffer, _gloffset_ReadBuffer }, + { "glCopyPixels", (GLvoid *) glCopyPixels, _gloffset_CopyPixels }, + { "glReadPixels", (GLvoid *) glReadPixels, _gloffset_ReadPixels }, + { "glDrawPixels", (GLvoid *) glDrawPixels, _gloffset_DrawPixels }, + { "glGetBooleanv", (GLvoid *) glGetBooleanv, _gloffset_GetBooleanv }, + { "glGetClipPlane", (GLvoid *) glGetClipPlane, _gloffset_GetClipPlane }, + { "glGetDoublev", (GLvoid *) glGetDoublev, _gloffset_GetDoublev }, + { "glGetError", (GLvoid *) glGetError, _gloffset_GetError }, + { "glGetFloatv", (GLvoid *) glGetFloatv, _gloffset_GetFloatv }, + { "glGetIntegerv", (GLvoid *) glGetIntegerv, _gloffset_GetIntegerv }, + { "glGetLightfv", (GLvoid *) glGetLightfv, _gloffset_GetLightfv }, + { "glGetLightiv", (GLvoid *) glGetLightiv, _gloffset_GetLightiv }, + { "glGetMapdv", (GLvoid *) glGetMapdv, _gloffset_GetMapdv }, + { "glGetMapfv", (GLvoid *) glGetMapfv, _gloffset_GetMapfv }, + { "glGetMapiv", (GLvoid *) glGetMapiv, _gloffset_GetMapiv }, + { "glGetMaterialfv", (GLvoid *) glGetMaterialfv, _gloffset_GetMaterialfv }, + { "glGetMaterialiv", (GLvoid *) glGetMaterialiv, _gloffset_GetMaterialiv }, + { "glGetPixelMapfv", (GLvoid *) glGetPixelMapfv, _gloffset_GetPixelMapfv }, + { "glGetPixelMapuiv", (GLvoid *) glGetPixelMapuiv, _gloffset_GetPixelMapuiv }, + { "glGetPixelMapusv", (GLvoid *) glGetPixelMapusv, _gloffset_GetPixelMapusv }, + { "glGetPolygonStipple", (GLvoid *) glGetPolygonStipple, _gloffset_GetPolygonStipple }, + { "glGetString", (GLvoid *) glGetString, _gloffset_GetString }, + { "glGetTexEnvfv", (GLvoid *) glGetTexEnvfv, _gloffset_GetTexEnvfv }, + { "glGetTexEnviv", (GLvoid *) glGetTexEnviv, _gloffset_GetTexEnviv }, + { "glGetTexGendv", (GLvoid *) glGetTexGendv, _gloffset_GetTexGendv }, + { "glGetTexGenfv", (GLvoid *) glGetTexGenfv, _gloffset_GetTexGenfv }, + { "glGetTexGeniv", (GLvoid *) glGetTexGeniv, _gloffset_GetTexGeniv }, + { "glGetTexImage", (GLvoid *) glGetTexImage, _gloffset_GetTexImage }, + { "glGetTexParameterfv", (GLvoid *) glGetTexParameterfv, _gloffset_GetTexParameterfv }, + { "glGetTexParameteriv", (GLvoid *) glGetTexParameteriv, _gloffset_GetTexParameteriv }, + { "glGetTexLevelParameterfv", (GLvoid *) glGetTexLevelParameterfv, _gloffset_GetTexLevelParameterfv }, + { "glGetTexLevelParameteriv", (GLvoid *) glGetTexLevelParameteriv, _gloffset_GetTexLevelParameteriv }, + { "glIsEnabled", (GLvoid *) glIsEnabled, _gloffset_IsEnabled }, + { "glIsList", (GLvoid *) glIsList, _gloffset_IsList }, + { "glDepthRange", (GLvoid *) glDepthRange, _gloffset_DepthRange }, + { "glFrustum", (GLvoid *) glFrustum, _gloffset_Frustum }, + { "glLoadIdentity", (GLvoid *) glLoadIdentity, _gloffset_LoadIdentity }, + { "glLoadMatrixf", (GLvoid *) glLoadMatrixf, _gloffset_LoadMatrixf }, + { "glLoadMatrixd", (GLvoid *) glLoadMatrixd, _gloffset_LoadMatrixd }, + { "glMatrixMode", (GLvoid *) glMatrixMode, _gloffset_MatrixMode }, + { "glMultMatrixf", (GLvoid *) glMultMatrixf, _gloffset_MultMatrixf }, + { "glMultMatrixd", (GLvoid *) glMultMatrixd, _gloffset_MultMatrixd }, + { "glOrtho", (GLvoid *) glOrtho, _gloffset_Ortho }, + { "glPopMatrix", (GLvoid *) glPopMatrix, _gloffset_PopMatrix }, + { "glPushMatrix", (GLvoid *) glPushMatrix, _gloffset_PushMatrix }, + { "glRotated", (GLvoid *) glRotated, _gloffset_Rotated }, + { "glRotatef", (GLvoid *) glRotatef, _gloffset_Rotatef }, + { "glScaled", (GLvoid *) glScaled, _gloffset_Scaled }, + { "glScalef", (GLvoid *) glScalef, _gloffset_Scalef }, + { "glTranslated", (GLvoid *) glTranslated, _gloffset_Translated }, + { "glTranslatef", (GLvoid *) glTranslatef, _gloffset_Translatef }, + { "glViewport", (GLvoid *) glViewport, _gloffset_Viewport }, + /* 1.1 */ + { "glArrayElement", (GLvoid *) glArrayElement, _gloffset_ArrayElement }, + { "glColorPointer", (GLvoid *) glColorPointer, _gloffset_ColorPointer }, + { "glDisableClientState", (GLvoid *) glDisableClientState, _gloffset_DisableClientState }, + { "glDrawArrays", (GLvoid *) glDrawArrays, _gloffset_DrawArrays }, + { "glDrawElements", (GLvoid *) glDrawElements, _gloffset_DrawElements }, + { "glEdgeFlagPointer", (GLvoid *) glEdgeFlagPointer, _gloffset_EdgeFlagPointer }, + { "glEnableClientState", (GLvoid *) glEnableClientState, _gloffset_EnableClientState }, + { "glGetPointerv", (GLvoid *) glGetPointerv, _gloffset_GetPointerv }, + { "glIndexPointer", (GLvoid *) glIndexPointer, _gloffset_IndexPointer }, + { "glInterleavedArrays", (GLvoid *) glInterleavedArrays, _gloffset_InterleavedArrays }, + { "glNormalPointer", (GLvoid *) glNormalPointer, _gloffset_NormalPointer }, + { "glTexCoordPointer", (GLvoid *) glTexCoordPointer, _gloffset_TexCoordPointer }, + { "glVertexPointer", (GLvoid *) glVertexPointer, _gloffset_VertexPointer }, + { "glPolygonOffset", (GLvoid *) glPolygonOffset, _gloffset_PolygonOffset }, + { "glCopyTexImage1D", (GLvoid *) glCopyTexImage1D, _gloffset_CopyTexImage1D }, + { "glCopyTexImage2D", (GLvoid *) glCopyTexImage2D, _gloffset_CopyTexImage2D }, + { "glCopyTexSubImage1D", (GLvoid *) glCopyTexSubImage1D, _gloffset_CopyTexSubImage1D }, + { "glCopyTexSubImage2D", (GLvoid *) glCopyTexSubImage2D, _gloffset_CopyTexSubImage2D }, + { "glTexSubImage1D", (GLvoid *) glTexSubImage1D, _gloffset_TexSubImage1D }, + { "glTexSubImage2D", (GLvoid *) glTexSubImage2D, _gloffset_TexSubImage2D }, + { "glAreTexturesResident", (GLvoid *) glAreTexturesResident, _gloffset_AreTexturesResident }, + { "glBindTexture", (GLvoid *) glBindTexture, _gloffset_BindTexture }, + { "glDeleteTextures", (GLvoid *) glDeleteTextures, _gloffset_DeleteTextures }, + { "glGenTextures", (GLvoid *) glGenTextures, _gloffset_GenTextures }, + { "glIsTexture", (GLvoid *) glIsTexture, _gloffset_IsTexture }, + { "glPrioritizeTextures", (GLvoid *) glPrioritizeTextures, _gloffset_PrioritizeTextures }, + { "glIndexub", (GLvoid *) glIndexub, _gloffset_Indexub }, + { "glIndexubv", (GLvoid *) glIndexubv, _gloffset_Indexubv }, + { "glPopClientAttrib", (GLvoid *) glPopClientAttrib, _gloffset_PopClientAttrib }, + { "glPushClientAttrib", (GLvoid *) glPushClientAttrib, _gloffset_PushClientAttrib }, + /* 1.2 */ +#ifdef GL_VERSION_1_2 +#define NAME(X) (GLvoid *) X +#else +#define NAME(X) NotImplemented +#endif + { "glBlendColor", (GLvoid *) NAME(glBlendColor), _gloffset_BlendColor }, + { "glBlendEquation", (GLvoid *) NAME(glBlendEquation), _gloffset_BlendEquation }, + { "glDrawRangeElements", (GLvoid *) NAME(glDrawRangeElements), _gloffset_DrawRangeElements }, + { "glColorTable", (GLvoid *) NAME(glColorTable), _gloffset_ColorTable }, + { "glColorTableParameterfv", (GLvoid *) NAME(glColorTableParameterfv), _gloffset_ColorTableParameterfv }, + { "glColorTableParameteriv", (GLvoid *) NAME(glColorTableParameteriv), _gloffset_ColorTableParameteriv }, + { "glCopyColorTable", (GLvoid *) NAME(glCopyColorTable), _gloffset_CopyColorTable }, + { "glGetColorTable", (GLvoid *) NAME(glGetColorTable), _gloffset_GetColorTable }, + { "glGetColorTableParameterfv", (GLvoid *) NAME(glGetColorTableParameterfv), _gloffset_GetColorTableParameterfv }, + { "glGetColorTableParameteriv", (GLvoid *) NAME(glGetColorTableParameteriv), _gloffset_GetColorTableParameteriv }, + { "glColorSubTable", (GLvoid *) NAME(glColorSubTable), _gloffset_ColorSubTable }, + { "glCopyColorSubTable", (GLvoid *) NAME(glCopyColorSubTable), _gloffset_CopyColorSubTable }, + { "glConvolutionFilter1D", (GLvoid *) NAME(glConvolutionFilter1D), _gloffset_ConvolutionFilter1D }, + { "glConvolutionFilter2D", (GLvoid *) NAME(glConvolutionFilter2D), _gloffset_ConvolutionFilter2D }, + { "glConvolutionParameterf", (GLvoid *) NAME(glConvolutionParameterf), _gloffset_ConvolutionParameterf }, + { "glConvolutionParameterfv", (GLvoid *) NAME(glConvolutionParameterfv), _gloffset_ConvolutionParameterfv }, + { "glConvolutionParameteri", (GLvoid *) NAME(glConvolutionParameteri), _gloffset_ConvolutionParameteri }, + { "glConvolutionParameteriv", (GLvoid *) NAME(glConvolutionParameteriv), _gloffset_ConvolutionParameteriv }, + { "glCopyConvolutionFilter1D", (GLvoid *) NAME(glCopyConvolutionFilter1D), _gloffset_CopyConvolutionFilter1D }, + { "glCopyConvolutionFilter2D", (GLvoid *) NAME(glCopyConvolutionFilter2D), _gloffset_CopyConvolutionFilter2D }, + { "glGetConvolutionFilter", (GLvoid *) NAME(glGetConvolutionFilter), _gloffset_GetConvolutionFilter }, + { "glGetConvolutionParameterfv", (GLvoid *) NAME(glGetConvolutionParameterfv), _gloffset_GetConvolutionParameterfv }, + { "glGetConvolutionParameteriv", (GLvoid *) NAME(glGetConvolutionParameteriv), _gloffset_GetConvolutionParameteriv }, + { "glGetSeparableFilter", (GLvoid *) NAME(glGetSeparableFilter), _gloffset_GetSeparableFilter }, + { "glSeparableFilter2D", (GLvoid *) NAME(glSeparableFilter2D), _gloffset_SeparableFilter2D }, + { "glGetHistogram", (GLvoid *) NAME(glGetHistogram), _gloffset_GetHistogram }, + { "glGetHistogramParameterfv", (GLvoid *) NAME(glGetHistogramParameterfv), _gloffset_GetHistogramParameterfv }, + { "glGetHistogramParameteriv", (GLvoid *) NAME(glGetHistogramParameteriv), _gloffset_GetHistogramParameteriv }, + { "glGetMinmax", (GLvoid *) NAME(glGetMinmax), _gloffset_GetMinmax }, + { "glGetMinmaxParameterfv", (GLvoid *) NAME(glGetMinmaxParameterfv), _gloffset_GetMinmaxParameterfv }, + { "glGetMinmaxParameteriv", (GLvoid *) NAME(glGetMinmaxParameteriv), _gloffset_GetMinmaxParameteriv }, + { "glHistogram", (GLvoid *) NAME(glHistogram), _gloffset_Histogram }, + { "glMinmax", (GLvoid *) NAME(glMinmax), _gloffset_Minmax }, + { "glResetHistogram", (GLvoid *) NAME(glResetHistogram), _gloffset_ResetHistogram }, + { "glResetMinmax", (GLvoid *) NAME(glResetMinmax), _gloffset_ResetMinmax }, + { "glTexImage3D", (GLvoid *) NAME(glTexImage3D), _gloffset_TexImage3D }, + { "glTexSubImage3D", (GLvoid *) NAME(glTexSubImage3D), _gloffset_TexSubImage3D }, + { "glCopyTexSubImage3D", (GLvoid *) NAME(glCopyTexSubImage3D), _gloffset_CopyTexSubImage3D }, +#undef NAME + + /* ARB 1. GL_ARB_multitexture */ +#ifdef GL_ARB_multitexture +#define NAME(X) (GLvoid *) X +#else +#define NAME(X) NotImplemented +#endif + { "glActiveTextureARB", (GLvoid *) NAME(glActiveTextureARB), _gloffset_ActiveTextureARB }, + { "glClientActiveTextureARB", (GLvoid *) NAME(glClientActiveTextureARB), _gloffset_ClientActiveTextureARB }, + { "glMultiTexCoord1dARB", (GLvoid *) NAME(glMultiTexCoord1dARB), _gloffset_MultiTexCoord1dARB }, + { "glMultiTexCoord1dvARB", (GLvoid *) NAME(glMultiTexCoord1dvARB), _gloffset_MultiTexCoord1dvARB }, + { "glMultiTexCoord1fARB", (GLvoid *) NAME(glMultiTexCoord1fARB), _gloffset_MultiTexCoord1fARB }, + { "glMultiTexCoord1fvARB", (GLvoid *) NAME(glMultiTexCoord1fvARB), _gloffset_MultiTexCoord1fvARB }, + { "glMultiTexCoord1iARB", (GLvoid *) NAME(glMultiTexCoord1iARB), _gloffset_MultiTexCoord1iARB }, + { "glMultiTexCoord1ivARB", (GLvoid *) NAME(glMultiTexCoord1ivARB), _gloffset_MultiTexCoord1ivARB }, + { "glMultiTexCoord1sARB", (GLvoid *) NAME(glMultiTexCoord1sARB), _gloffset_MultiTexCoord1sARB }, + { "glMultiTexCoord1svARB", (GLvoid *) NAME(glMultiTexCoord1svARB), _gloffset_MultiTexCoord1svARB }, + { "glMultiTexCoord2dARB", (GLvoid *) NAME(glMultiTexCoord2dARB), _gloffset_MultiTexCoord2dARB }, + { "glMultiTexCoord2dvARB", (GLvoid *) NAME(glMultiTexCoord2dvARB), _gloffset_MultiTexCoord2dvARB }, + { "glMultiTexCoord2fARB", (GLvoid *) NAME(glMultiTexCoord2fARB), _gloffset_MultiTexCoord2fARB }, + { "glMultiTexCoord2fvARB", (GLvoid *) NAME(glMultiTexCoord2fvARB), _gloffset_MultiTexCoord2fvARB }, + { "glMultiTexCoord2iARB", (GLvoid *) NAME(glMultiTexCoord2iARB), _gloffset_MultiTexCoord2iARB }, + { "glMultiTexCoord2ivARB", (GLvoid *) NAME(glMultiTexCoord2ivARB), _gloffset_MultiTexCoord2ivARB }, + { "glMultiTexCoord2sARB", (GLvoid *) NAME(glMultiTexCoord2sARB), _gloffset_MultiTexCoord2sARB }, + { "glMultiTexCoord2svARB", (GLvoid *) NAME(glMultiTexCoord2svARB), _gloffset_MultiTexCoord2svARB }, + { "glMultiTexCoord3dARB", (GLvoid *) NAME(glMultiTexCoord3dARB), _gloffset_MultiTexCoord3dARB }, + { "glMultiTexCoord3dvARB", (GLvoid *) NAME(glMultiTexCoord3dvARB), _gloffset_MultiTexCoord3dvARB }, + { "glMultiTexCoord3fARB", (GLvoid *) NAME(glMultiTexCoord3fARB), _gloffset_MultiTexCoord3fARB }, + { "glMultiTexCoord3fvARB", (GLvoid *) NAME(glMultiTexCoord3fvARB), _gloffset_MultiTexCoord3fvARB }, + { "glMultiTexCoord3iARB", (GLvoid *) NAME(glMultiTexCoord3iARB), _gloffset_MultiTexCoord3iARB }, + { "glMultiTexCoord3ivARB", (GLvoid *) NAME(glMultiTexCoord3ivARB), _gloffset_MultiTexCoord3ivARB }, + { "glMultiTexCoord3sARB", (GLvoid *) NAME(glMultiTexCoord3sARB), _gloffset_MultiTexCoord3sARB }, + { "glMultiTexCoord3svARB", (GLvoid *) NAME(glMultiTexCoord3svARB), _gloffset_MultiTexCoord3svARB }, + { "glMultiTexCoord4dARB", (GLvoid *) NAME(glMultiTexCoord4dARB), _gloffset_MultiTexCoord4dARB }, + { "glMultiTexCoord4dvARB", (GLvoid *) NAME(glMultiTexCoord4dvARB), _gloffset_MultiTexCoord4dvARB }, + { "glMultiTexCoord4fARB", (GLvoid *) NAME(glMultiTexCoord4fARB), _gloffset_MultiTexCoord4fARB }, + { "glMultiTexCoord4fvARB", (GLvoid *) NAME(glMultiTexCoord4fvARB), _gloffset_MultiTexCoord4fvARB }, + { "glMultiTexCoord4iARB", (GLvoid *) NAME(glMultiTexCoord4iARB), _gloffset_MultiTexCoord4iARB }, + { "glMultiTexCoord4ivARB", (GLvoid *) NAME(glMultiTexCoord4ivARB), _gloffset_MultiTexCoord4ivARB }, + { "glMultiTexCoord4sARB", (GLvoid *) NAME(glMultiTexCoord4sARB), _gloffset_MultiTexCoord4sARB }, + { "glMultiTexCoord4svARB", (GLvoid *) NAME(glMultiTexCoord4svARB), _gloffset_MultiTexCoord4svARB }, +#undef NAME + + /* ARB 3. GL_ARB_transpose_matrix */ +#ifdef GL_ARB_transpose_matrix +#define NAME(X) (GLvoid *) X +#else +#define NAME(X) NotImplemented +#endif + { "glLoadTransposeMatrixdARB", (GLvoid *) NAME(glLoadTransposeMatrixdARB), _gloffset_LoadTransposeMatrixdARB }, + { "glLoadTransposeMatrixfARB", (GLvoid *) NAME(glLoadTransposeMatrixfARB), _gloffset_LoadTransposeMatrixfARB }, + { "glMultTransposeMatrixdARB", (GLvoid *) NAME(glMultTransposeMatrixdARB), _gloffset_MultTransposeMatrixdARB }, + { "glMultTransposeMatrixfARB", (GLvoid *) NAME(glMultTransposeMatrixfARB), _gloffset_MultTransposeMatrixfARB }, +#undef NAME + + /* ARB 5. GL_ARB_multisample */ +#ifdef GL_ARB_multisample +#define NAME(X) (GLvoid *) X +#else +#define NAME(X) (GLvoid *) NotImplemented +#endif + { "glSampleCoverageARB", NAME(glSampleCoverageARB), _gloffset_SampleCoverageARB }, +#undef NAME + + /* ARB 12. GL_ARB_texture_compression */ +#if 000 +#if defined(GL_ARB_texture_compression) && defined(_gloffset_CompressedTexImage3DARB) +#define NAME(X) (GLvoid *) X +#else +#define NAME(X) (GLvoid *) NotImplemented +#endif + { "glCompressedTexImage3DARB", NAME(glCompressedTexImage3DARB), _gloffset_CompressedTexImage3DARB }, + { "glCompressedTexImage2DARB", NAME(glCompressedTexImage2DARB), _gloffset_CompressedTexImage2DARB }, + { "glCompressedTexImage1DARB", NAME(glCompressedTexImage1DARB), _gloffset_CompressedTexImage1DARB }, + { "glCompressedTexSubImage3DARB", NAME(glCompressedTexSubImage3DARB), _gloffset_CompressedTexSubImage3DARB }, + { "glCompressedTexSubImage2DARB", NAME(glCompressedTexSubImage2DARB), _gloffset_CompressedTexSubImage2DARB }, + { "glCompressedTexSubImage1DARB", NAME(glCompressedTexSubImage1DARB), _gloffset_CompressedTexSubImage1DARB }, + { "glGetCompressedTexImageARB", NAME(glGetCompressedTexImageARB), _gloffset_GetCompressedTexImageARB }, +#undef NAME +#endif + + /* 2. GL_EXT_blend_color */ +#ifdef GL_EXT_blend_color +#define NAME(X) (GLvoid *) X +#else +#define NAME(X) (GLvoid *) NotImplemented +#endif + { "glBlendColorEXT", NAME(glBlendColorEXT), _gloffset_BlendColor }, +#undef NAME + + /* 3. GL_EXT_polygon_offset */ +#ifdef GL_EXT_polygon_offset +#define NAME(X) (GLvoid *) X +#else +#define NAME(X) (GLvoid *) NotImplemented +#endif + { "glPolygonOffsetEXT", NAME(glPolygonOffsetEXT), _gloffset_PolygonOffsetEXT }, +#undef NAME + + /* 6. GL_EXT_texture3D */ +#ifdef GL_EXT_texture3D +#define NAME(X) (GLvoid *) X +#else +#define NAME(X) (GLvoid *) NotImplemented +#endif + { "glCopyTexSubImage3DEXT", NAME(glCopyTexSubImage3DEXT), _gloffset_CopyTexSubImage3D }, + { "glTexImage3DEXT", NAME(glTexImage3DEXT), _gloffset_TexImage3D }, + { "glTexSubImage3DEXT", NAME(glTexSubImage3DEXT), _gloffset_TexSubImage3D }, +#undef NAME + + /* 7. GL_SGI_texture_filter4 */ +#ifdef GL_SGI_texture_filter4 +#define NAME(X) (GLvoid *) X +#else +#define NAME(X) (GLvoid *) NotImplemented +#endif + { "glGetTexFilterFuncSGIS", NAME(glGetTexFilterFuncSGIS), _gloffset_GetTexFilterFuncSGIS }, + { "glTexFilterFuncSGIS", NAME(glTexFilterFuncSGIS), _gloffset_TexFilterFuncSGIS }, +#undef NAME + + /* 9. GL_EXT_subtexture */ +#ifdef GL_EXT_subtexture +#define NAME(X) (GLvoid *) X +#else +#define NAME(X) (GLvoid *) NotImplemented +#endif + { "glTexSubImage1DEXT", NAME(glTexSubImage1DEXT), _gloffset_TexSubImage1D }, + { "glTexSubImage2DEXT", NAME(glTexSubImage2DEXT), _gloffset_TexSubImage2D }, +#undef NAME + + /* 10. GL_EXT_copy_texture */ +#ifdef GL_EXT_copy_texture +#define NAME(X) (GLvoid *) X +#else +#define NAME(X) (GLvoid *) NotImplemented +#endif + { "glCopyTexImage1DEXT", NAME(glCopyTexImage1DEXT), _gloffset_CopyTexImage1D }, + { "glCopyTexImage2DEXT", NAME(glCopyTexImage2DEXT), _gloffset_CopyTexImage2D }, + { "glCopyTexSubImage1DEXT", NAME(glCopyTexSubImage1DEXT), _gloffset_CopyTexSubImage1D }, + { "glCopyTexSubImage2DEXT", NAME(glCopyTexSubImage2DEXT), _gloffset_CopyTexSubImage2D }, +#undef NAME + + /* 11. GL_EXT_histogram */ +#ifdef GL_EXT_histogram +#define NAME(X) (GLvoid *) X +#else +#define NAME(X) (GLvoid *) NotImplemented +#endif + { "glGetHistogramEXT", NAME(glGetHistogramEXT), _gloffset_GetHistogramEXT }, + { "glGetHistogramParameterfvEXT", NAME(glGetHistogramParameterfvEXT), _gloffset_GetHistogramParameterfvEXT }, + { "glGetHistogramParameterivEXT", NAME(glGetHistogramParameterivEXT), _gloffset_GetHistogramParameterivEXT }, + { "glGetMinmaxEXT", NAME(glGetMinmaxEXT), _gloffset_GetMinmaxEXT }, + { "glGetMinmaxParameterfvEXT", NAME(glGetMinmaxParameterfvEXT), _gloffset_GetMinmaxParameterfvEXT }, + { "glGetMinmaxParameterivEXT", NAME(glGetMinmaxParameterivEXT), _gloffset_GetMinmaxParameterivEXT }, + { "glHistogramEXT", NAME(glHistogramEXT), _gloffset_Histogram }, + { "glMinmaxEXT", NAME(glMinmaxEXT), _gloffset_Minmax }, + { "glResetHistogramEXT", NAME(glResetHistogramEXT), _gloffset_ResetHistogram }, + { "glResetMinmaxEXT", NAME(glResetMinmaxEXT), _gloffset_ResetMinmax }, +#undef NAME + + /* 12. GL_EXT_convolution */ +#ifdef GL_EXT_convolution +#define NAME(X) (GLvoid *) X +#else +#define NAME(X) (GLvoid *) NotImplemented +#endif + { "glConvolutionFilter1DEXT", NAME(glConvolutionFilter1DEXT), _gloffset_ConvolutionFilter1D }, + { "glConvolutionFilter2DEXT", NAME(glConvolutionFilter2DEXT), _gloffset_ConvolutionFilter2D }, + { "glConvolutionParameterfEXT", NAME(glConvolutionParameterfEXT), _gloffset_ConvolutionParameterf }, + { "glConvolutionParameterfvEXT", NAME(glConvolutionParameterfvEXT), _gloffset_ConvolutionParameterfv }, + { "glConvolutionParameteriEXT", NAME(glConvolutionParameteriEXT), _gloffset_ConvolutionParameteri }, + { "glConvolutionParameterivEXT", NAME(glConvolutionParameterivEXT), _gloffset_ConvolutionParameteriv }, + { "glCopyConvolutionFilter1DEXT", NAME(glCopyConvolutionFilter1DEXT), _gloffset_CopyConvolutionFilter1D }, + { "glCopyConvolutionFilter2DEXT", NAME(glCopyConvolutionFilter2DEXT), _gloffset_CopyConvolutionFilter2D }, + { "glGetConvolutionFilterEXT", NAME(glGetConvolutionFilterEXT), _gloffset_GetConvolutionFilterEXT }, + { "glGetConvolutionParameterivEXT", NAME(glGetConvolutionParameterivEXT), _gloffset_GetConvolutionParameterivEXT }, + { "glGetConvolutionParameterfvEXT", NAME(glGetConvolutionParameterfvEXT), _gloffset_GetConvolutionParameterfvEXT }, + { "glGetSeparableFilterEXT", NAME(glGetSeparableFilterEXT), _gloffset_GetSeparableFilterEXT }, + { "glSeparableFilter2DEXT", NAME(glSeparableFilter2DEXT), _gloffset_SeparableFilter2D }, +#undef NAME + + /* 14. GL_SGI_color_table */ +#ifdef GL_SGI_color_table +#define NAME(X) (GLvoid *) X +#else +#define NAME(X) (GLvoid *) NotImplemented +#endif + { "glColorTableSGI", NAME(glColorTableSGI), _gloffset_ColorTable }, + { "glColorTableParameterfvSGI", NAME(glColorTableParameterfvSGI), _gloffset_ColorTableParameterfv }, + { "glColorTableParameterivSGI", NAME(glColorTableParameterivSGI), _gloffset_ColorTableParameteriv }, + { "glCopyColorTableSGI", NAME(glCopyColorTableSGI), _gloffset_CopyColorTable }, + { "glGetColorTableSGI", NAME(glGetColorTableSGI), _gloffset_GetColorTableSGI }, + { "glGetColorTableParameterfvSGI", NAME(glGetColorTableParameterfvSGI), _gloffset_GetColorTableParameterfvSGI }, + { "glGetColorTableParameterivSGI", NAME(glGetColorTableParameterivSGI), _gloffset_GetColorTableParameterivSGI }, +#undef NAME + + /* 15. GL_SGIS_pixel_texture */ +#ifdef GL_SGIS_pixel_texture +#define NAME(X) (GLvoid *) X +#else +#define NAME(X) (GLvoid *) NotImplemented +#endif + { "glPixelTexGenParameterfSGIS", NAME(glPixelTexGenParameterfSGIS), _gloffset_PixelTexGenParameterfSGIS }, + { "glPixelTexGenParameteriSGIS", NAME(glPixelTexGenParameteriSGIS), _gloffset_PixelTexGenParameteriSGIS }, + { "glGetPixelTexGenParameterfvSGIS", NAME(glGetPixelTexGenParameterfvSGIS), _gloffset_GetPixelTexGenParameterfvSGIS }, + { "glGetPixelTexGenParameterivSGIS", NAME(glGetPixelTexGenParameterivSGIS), _gloffset_GetPixelTexGenParameterivSGIS }, +#undef NAME + + /* 16. GL_SGIS_texture4D */ +#ifdef GL_SGIS_texture4D +#define NAME(X) (GLvoid *) X +#else +#define NAME(X) (GLvoid *) NotImplemented +#endif + { "glTexImage4DSGIS", NAME(glTexImage4DSGIS), _gloffset_TexImage4DSGIS }, + { "glTexSubImage4DSGIS", NAME(glTexSubImage4DSGIS), _gloffset_TexSubImage4DSGIS }, +#undef NAME + + /* 20. GL_EXT_texture_object */ +#ifdef GL_EXT_texture_object +#define NAME(X) (GLvoid *) X +#else +#define NAME(X) (GLvoid *) NotImplemented +#endif + { "glAreTexturesResidentEXT", NAME(glAreTexturesResidentEXT), _gloffset_AreTexturesResidentEXT }, + { "glBindTextureEXT", NAME(glBindTextureEXT), _gloffset_BindTexture }, + { "glDeleteTexturesEXT", NAME(glDeleteTexturesEXT), _gloffset_DeleteTextures }, + { "glGenTexturesEXT", NAME(glGenTexturesEXT), _gloffset_GenTexturesEXT }, + { "glIsTextureEXT", NAME(glIsTextureEXT), _gloffset_IsTextureEXT }, + { "glPrioritizeTexturesEXT", NAME(glPrioritizeTexturesEXT), _gloffset_PrioritizeTextures }, +#undef NAME + + /* 21. GL_SGIS_detail_texture */ +#ifdef GL_SGIS_detail_texture +#define NAME(X) (GLvoid *) X +#else +#define NAME(X) (GLvoid *) NotImplemented +#endif + { "glDetailTexFuncSGIS", NAME(glDetailTexFuncSGIS), _gloffset_DetailTexFuncSGIS }, + { "glGetDetailTexFuncSGIS", NAME(glGetDetailTexFuncSGIS), _gloffset_GetDetailTexFuncSGIS }, +#undef NAME + + /* 22. GL_SGIS_sharpen_texture */ +#ifdef GL_SGIS_sharpen_texture +#define NAME(X) (GLvoid *) X +#else +#define NAME(X) (GLvoid *) NotImplemented +#endif + { "glGetSharpenTexFuncSGIS", NAME(glGetSharpenTexFuncSGIS), _gloffset_GetSharpenTexFuncSGIS }, + { "glSharpenTexFuncSGIS", NAME(glSharpenTexFuncSGIS), _gloffset_SharpenTexFuncSGIS }, +#undef NAME + + /* 25. GL_SGIS_multisample */ +#ifdef GL_SGIS_multisample +#define NAME(X) (GLvoid *) X +#else +#define NAME(X) (GLvoid *) NotImplemented +#endif + { "glSampleMaskSGIS", NAME(glSampleMaskSGIS), _gloffset_SampleMaskSGIS }, + { "glSamplePatternSGIS", NAME(glSamplePatternSGIS), _gloffset_SamplePatternSGIS }, +#undef NAME + + /* 30. GL_EXT_vertex_array */ +#ifdef GL_EXT_vertex_array +#define NAME(X) (GLvoid *) X +#else +#define NAME(X) (GLvoid *) NotImplemented +#endif + { "glArrayElementEXT", NAME(glArrayElementEXT), _gloffset_ArrayElement }, + { "glColorPointerEXT", NAME(glColorPointerEXT), _gloffset_ColorPointerEXT }, + { "glDrawArraysEXT", NAME(glDrawArraysEXT), _gloffset_DrawArrays }, + { "glEdgeFlagPointerEXT", NAME(glEdgeFlagPointerEXT), _gloffset_EdgeFlagPointerEXT }, + { "glGetPointervEXT", NAME(glGetPointervEXT), _gloffset_GetPointerv }, + { "glIndexPointerEXT", NAME(glIndexPointerEXT), _gloffset_IndexPointerEXT }, + { "glNormalPointerEXT", NAME(glNormalPointerEXT), _gloffset_NormalPointerEXT }, + { "glTexCoordPointerEXT", NAME(glTexCoordPointerEXT), _gloffset_TexCoordPointerEXT }, + { "glVertexPointerEXT", NAME(glVertexPointerEXT), _gloffset_VertexPointerEXT }, +#undef NAME + + /* 37. GL_EXT_blend_minmax */ +#ifdef GL_EXT_blend_minmax +#define NAME(X) (GLvoid *) X +#else +#define NAME(X) (GLvoid *) NotImplemented +#endif + { "glBlendEquationEXT", NAME(glBlendEquationEXT), _gloffset_BlendEquation }, +#undef NAME + + /* 52. GL_SGIX_sprite */ +#ifdef GL_SGIX_sprite +#define NAME(X) (GLvoid *) X +#else +#define NAME(X) (GLvoid *) NotImplemented +#endif + { "glSpriteParameterfSGIX", NAME(glSpriteParameterfSGIX), _gloffset_SpriteParameterfSGIX }, + { "glSpriteParameterfvSGIX", NAME(glSpriteParameterfvSGIX), _gloffset_SpriteParameterfvSGIX }, + { "glSpriteParameteriSGIX", NAME(glSpriteParameteriSGIX), _gloffset_SpriteParameteriSGIX }, + { "glSpriteParameterivSGIX", NAME(glSpriteParameterivSGIX), _gloffset_SpriteParameterivSGIX }, +#undef NAME + + /* 54. GL_EXT_point_parameters */ +#ifdef GL_EXT_point_parameters +#define NAME(X) (GLvoid *) X +#else +#define NAME(X) (GLvoid *) NotImplemented +#endif + { "glPointParameterfEXT", NAME(glPointParameterfEXT), _gloffset_PointParameterfEXT }, + { "glPointParameterfvEXT", NAME(glPointParameterfvEXT), _gloffset_PointParameterfvEXT }, + { "glPointParameterfSGIS", NAME(glPointParameterfSGIS), _gloffset_PointParameterfEXT }, + { "glPointParameterfvSGIS", NAME(glPointParameterfvSGIS), _gloffset_PointParameterfvEXT }, +#undef NAME + + /* 55. GL_SGIX_instruments */ +#ifdef GL_SGIX_instruments +#define NAME(X) (GLvoid *) X +#else +#define NAME(X) (GLvoid *) NotImplemented +#endif + { "glInstrumentsBufferSGIX", NAME(glInstrumentsBufferSGIX), _gloffset_InstrumentsBufferSGIX }, + { "glStartInstrumentsSGIX", NAME(glStartInstrumentsSGIX), _gloffset_StartInstrumentsSGIX }, + { "glStopInstrumentsSGIX", NAME(glStopInstrumentsSGIX), _gloffset_StopInstrumentsSGIX }, + { "glReadInstrumentsSGIX", NAME(glReadInstrumentsSGIX), _gloffset_ReadInstrumentsSGIX }, + { "glPollInstrumentsSGIX", NAME(glPollInstrumentsSGIX), _gloffset_PollInstrumentsSGIX }, + { "glGetInstrumentsSGIX", NAME(glGetInstrumentsSGIX), _gloffset_GetInstrumentsSGIX }, +#undef NAME + + /* 57. GL_SGIX_framezoom */ +#ifdef GL_SGIX_framezoom +#define NAME(X) (GLvoid *) X +#else +#define NAME(X) (GLvoid *) NotImplemented +#endif + { "glFrameZoomSGIX", NAME(glFrameZoomSGIX), _gloffset_FrameZoomSGIX }, +#undef NAME + + /* 58. GL_SGIX_tag_sample_buffer */ +#ifdef GL_SGIX_tag_sample_buffer +#define NAME(X) (GLvoid *) X +#else +#define NAME(X) (GLvoid *) NotImplemented +#endif + { "glTagSampleBufferSGIX", NAME(glTagSampleBufferSGIX), _gloffset_TagSampleBufferSGIX }, +#undef NAME + + /* 60. GL_SGIX_reference_plane */ +#ifdef GL_SGIX_reference_plane +#define NAME(X) (GLvoid *) X +#else +#define NAME(X) (GLvoid *) NotImplemented +#endif + { "glReferencePlaneSGIX", NAME(glReferencePlaneSGIX), _gloffset_ReferencePlaneSGIX }, +#undef NAME + + /* 61. GL_SGIX_flush_raster */ +#ifdef GL_SGIX_flush_raster +#define NAME(X) (GLvoid *) X +#else +#define NAME(X) (GLvoid *) NotImplemented +#endif + { "glFlushRasterSGIX", NAME(glFlushRasterSGIX), _gloffset_FlushRasterSGIX }, +#undef NAME + + /* 66. GL_HP_image_transform */ +#if 0 +#ifdef GL_HP_image_transform +#define NAME(X) (GLvoid *) X +#else +#define NAME(X) (GLvoid *) NotImplemented +#endif + { "glGetImageTransformParameterfvHP", NAME(glGetImageTransformParameterfvHP), _gloffset_GetImageTransformParameterfvHP }, + { "glGetImageTransformParameterivHP", NAME(glGetImageTransformParameterivHP), _gloffset_GetImageTransformParameterivHP }, + { "glImageTransformParameterfHP", NAME(glImageTransformParameterfHP), _gloffset_ImageTransformParameterfHP }, + { "glImageTransformParameterfvHP", NAME(glImageTransformParameterfvHP), _gloffset_ImageTransformParameterfvHP }, + { "glImageTransformParameteriHP", NAME(glImageTransformParameteriHP), _gloffset_ImageTransformParameteriHP }, + { "glImageTransformParameterivHP", NAME(glImageTransformParameterivHP), _gloffset_ImageTransformParameterivHP }, +#undef NAME +#endif + + /* 74. GL_EXT_color_subtable */ +#ifdef GL_EXT_color_subtable +#define NAME(X) (GLvoid *) X +#else +#define NAME(X) (GLvoid *) NotImplemented +#endif + { "glColorSubTableEXT", NAME(glColorSubTableEXT), _gloffset_ColorSubTable }, + { "glCopyColorSubTableEXT", NAME(glCopyColorSubTableEXT), _gloffset_CopyColorSubTable }, +#undef NAME + + /* 77. GL_PGI_misc_hints */ +#ifdef GL_PGI_misc_hints +#define NAME(X) (GLvoid *) X +#else +#define NAME(X) (GLvoid *) NotImplemented +#endif + { "glHintPGI", NAME(glHintPGI), _gloffset_HintPGI }, +#undef NAME + + /* 78. GL_EXT_paletted_texture */ +#ifdef GL_EXT_paletted_texture +#define NAME(X) (GLvoid *) X +#else +#define NAME(X) (GLvoid *) NotImplemented +#endif + { "glColorTableEXT", NAME(glColorTableEXT), _gloffset_ColorTable }, + { "glGetColorTableEXT", NAME(glGetColorTableEXT), _gloffset_GetColorTable }, + { "glGetColorTableParameterfvEXT", NAME(glGetColorTableParameterfvEXT), _gloffset_GetColorTableParameterfv }, + { "glGetColorTableParameterivEXT", NAME(glGetColorTableParameterivEXT), _gloffset_GetColorTableParameteriv }, +#undef NAME + + /* 80. GL_SGIX_list_priority */ +#ifdef GL_SGIX_list_priority +#define NAME(X) (GLvoid *) X +#else +#define NAME(X) (GLvoid *) NotImplemented +#endif + { "glGetListParameterfvSGIX", NAME(glGetListParameterfvSGIX), _gloffset_GetListParameterfvSGIX }, + { "glGetListParameterivSGIX", NAME(glGetListParameterivSGIX), _gloffset_GetListParameterivSGIX }, + { "glListParameterfSGIX", NAME(glListParameterfSGIX), _gloffset_ListParameterfSGIX }, + { "glListParameterfvSGIX", NAME(glListParameterfvSGIX), _gloffset_ListParameterfvSGIX }, + { "glListParameteriSGIX", NAME(glListParameteriSGIX), _gloffset_ListParameteriSGIX }, + { "glListParameterivSGIX", NAME(glListParameterivSGIX), _gloffset_ListParameterivSGIX }, +#undef NAME + + /* 94. GL_EXT_index_material */ +#ifdef GL_EXT_index_material +#define NAME(X) (GLvoid *) X +#else +#define NAME(X) (GLvoid *) NotImplemented +#endif + { "glIndexMaterialEXT", NAME(glIndexMaterialEXT), _gloffset_IndexMaterialEXT }, +#undef NAME + + /* 95. GL_EXT_index_func */ +#ifdef GL_EXT_index_func +#define NAME(X) (GLvoid *) X +#else +#define NAME(X) (GLvoid *) NotImplemented +#endif + { "glIndexFuncEXT", NAME(glIndexFuncEXT), _gloffset_IndexFuncEXT }, +#undef NAME + + /* 97. GL_EXT_compiled_vertex_array */ +#ifdef GL_EXT_compiled_vertex_array +#define NAME(X) (GLvoid *) X +#else +#define NAME(X) (GLvoid *) NotImplemented +#endif + { "glLockArraysEXT", NAME(glLockArraysEXT), _gloffset_LockArraysEXT }, + { "glUnlockArraysEXT", NAME(glUnlockArraysEXT), _gloffset_UnlockArraysEXT }, +#undef NAME + + /* 98. GL_EXT_cull_vertex */ +#ifdef GL_EXT_cull_vertex +#define NAME(X) (GLvoid *) X +#else +#define NAME(X) (GLvoid *) NotImplemented +#endif + { "glCullParameterfvEXT", NAME(glCullParameterfvEXT), _gloffset_CullParameterfvEXT }, + { "glCullParameterdvEXT", NAME(glCullParameterdvEXT), _gloffset_CullParameterdvEXT }, +#undef NAME + + /* 102. GL_SGIX_fragment_lighting */ +#ifdef GL_SGIX_fragment_lighting +#define NAME(X) (GLvoid *) X +#else +#define NAME(X) (GLvoid *) NotImplemented +#endif + { "glFragmentColorMaterialSGIX", NAME(glFragmentColorMaterialSGIX), _gloffset_FragmentColorMaterialSGIX }, + { "glFragmentLightfSGIX", NAME(glFragmentLightfSGIX), _gloffset_FragmentLightfSGIX }, + { "glFragmentLightfvSGIX", NAME(glFragmentLightfvSGIX), _gloffset_FragmentLightfvSGIX }, + { "glFragmentLightiSGIX", NAME(glFragmentLightiSGIX), _gloffset_FragmentLightiSGIX }, + { "glFragmentLightivSGIX", NAME(glFragmentLightivSGIX), _gloffset_FragmentLightivSGIX }, + { "glFragmentLightModelfSGIX", NAME(glFragmentLightModelfSGIX), _gloffset_FragmentLightModelfSGIX }, + { "glFragmentLightModelfvSGIX", NAME(glFragmentLightModelfvSGIX), _gloffset_FragmentLightModelfvSGIX }, + { "glFragmentLightModeliSGIX", NAME(glFragmentLightModeliSGIX), _gloffset_FragmentLightModeliSGIX }, + { "glFragmentLightModelivSGIX", NAME(glFragmentLightModelivSGIX), _gloffset_FragmentLightModelivSGIX }, + { "glFragmentMaterialfSGIX", NAME(glFragmentMaterialfSGIX), _gloffset_FragmentMaterialfSGIX }, + { "glFragmentMaterialfvSGIX", NAME(glFragmentMaterialfvSGIX), _gloffset_FragmentMaterialfvSGIX }, + { "glFragmentMaterialiSGIX", NAME(glFragmentMaterialiSGIX), _gloffset_FragmentMaterialiSGIX }, + { "glFragmentMaterialivSGIX", NAME(glFragmentMaterialivSGIX), _gloffset_FragmentMaterialivSGIX }, + { "glGetFragmentLightfvSGIX", NAME(glGetFragmentLightfvSGIX), _gloffset_GetFragmentLightfvSGIX }, + { "glGetFragmentLightivSGIX", NAME(glGetFragmentLightivSGIX), _gloffset_GetFragmentLightivSGIX }, + { "glGetFragmentMaterialfvSGIX", NAME(glGetFragmentMaterialfvSGIX), _gloffset_GetFragmentMaterialfvSGIX }, + { "glGetFragmentMaterialivSGIX", NAME(glGetFragmentMaterialivSGIX), _gloffset_GetFragmentMaterialivSGIX }, + { "glLightEnviSGIX", NAME(glLightEnviSGIX), _gloffset_LightEnviSGIX }, +#undef NAME + + /* 112. GL_EXT_draw_range_elements */ +#if 000 +#ifdef GL_EXT_draw_range_elements +#define NAME(X) (GLvoid *) X +#else +#define NAME(X) (GLvoid *) NotImplemented +#endif + { "glDrawRangeElementsEXT", NAME(glDrawRangeElementsEXT), _gloffset_DrawRangeElementsEXT }, +#undef NAME +#endif + + /* 117. GL_EXT_light_texture */ +#if 000 +#ifdef GL_EXT_light_texture +#define NAME(X) (GLvoid *) X +#else +#define NAME(X) (GLvoid *) NotImplemented +#endif + { "glApplyTextureEXT", NAME(glApplyTextureEXT), _gloffset_ApplyTextureEXT }, + { "glTextureLightEXT", NAME(glTextureLightEXT), _gloffset_TextureLightEXT }, + { "glTextureMaterialEXT", NAME(glTextureMaterialEXT), _gloffset_TextureMaterialEXT }, +#undef NAME + + /* 135. GL_INTEL_texture_scissor */ +#ifdef GL_INTEL_texture_scissor +#define NAME(X) (GLvoid *) X +#else +#define NAME(X) (GLvoid *) NotImplemented +#endif + { "glTexScissorINTEL", NAME(glTexScissorINTEL), _gloffset_TexScissorINTEL }, + { "glTexScissorFuncINTEL", NAME(glTexScissorFuncINTEL), _gloffset_glTexScissorFuncINTEL }, +#undef NAME + + /* 136. GL_INTEL_parallel_arrays */ +#ifdef GL_INTEL_parallel_arrays +#define NAME(X) (GLvoid *) X +#else +#define NAME(X) (GLvoid *) NotImplemented +#endif + { "glVertexPointervINTEL", NAME(glVertexPointervINTEL), _gloffset_VertexPointervINTEL }, + { "glNormalPointervINTEL", NAME(glNormalPointervINTEL), _gloffset_NormalPointervINTEL }, + { "glColorPointervINTEL", NAME(glColorPointervINTEL), _gloffset_ColorPointervINTEL }, + { "glTexCoordPointervINTEL", NAME(glTexCoordPointervINTEL), _gloffset_glxCoordPointervINTEL }, +#undef NAME +#endif + + /* 138. GL_EXT_pixel_transform */ +#if 000 +#ifdef GL_EXT_pixel_transform +#define NAME(X) (GLvoid *) X +#else +#define NAME(X) (GLvoid *) NotImplemented +#endif + { "glPixelTransformParameteriEXT", NAME(glPixelTransformParameteriEXT), _gloffset_PixelTransformParameteriEXT }, + { "glPixelTransformParameterfEXT", NAME(glPixelTransformParameterfEXT), _gloffset_PixelTransformParameterfEXT }, + { "glPixelTransformParameterivEXT", NAME(glPixelTransformParameterivEXT), _gloffset_PixelTransformParameterivEXT }, + { "glPixelTransformParameterfvEXT", NAME(glPixelTransformParameterfvEXT), _gloffset_PixelTransformParameterfvEXT }, + { "glGetPixelTransformParameterivEXT", NAME(glGetPixelTransformParameterivEXT), _gloffset_GetPixelTransformParameterivEXT }, + { "glGetPixelTransformParameterfvEXT", NAME(glGetPixelTransformParameterfvEXT), _gloffset_GetPixelTransformParameterfvEXT }, +#undef NAME +#endif + + /* 145. GL_EXT_secondary_color */ +#ifdef GL_EXT_secondary_color +#define NAME(X) (GLvoid *) X +#else +#define NAME(X) (GLvoid *) NotImplemented +#endif + { "glSecondaryColor3bEXT", NAME(glSecondaryColor3bEXT), _gloffset_SecondaryColor3bEXT }, + { "glSecondaryColor3dEXT", NAME(glSecondaryColor3dEXT), _gloffset_SecondaryColor3dEXT }, + { "glSecondaryColor3fEXT", NAME(glSecondaryColor3fEXT), _gloffset_SecondaryColor3fEXT }, + { "glSecondaryColor3iEXT", NAME(glSecondaryColor3iEXT), _gloffset_SecondaryColor3iEXT }, + { "glSecondaryColor3sEXT", NAME(glSecondaryColor3sEXT), _gloffset_SecondaryColor3sEXT }, + { "glSecondaryColor3ubEXT", NAME(glSecondaryColor3ubEXT), _gloffset_SecondaryColor3ubEXT }, + { "glSecondaryColor3uiEXT", NAME(glSecondaryColor3uiEXT), _gloffset_SecondaryColor3uiEXT }, + { "glSecondaryColor3usEXT", NAME(glSecondaryColor3usEXT), _gloffset_SecondaryColor3usEXT }, + { "glSecondaryColor3bvEXT", NAME(glSecondaryColor3bvEXT), _gloffset_SecondaryColor3bvEXT }, + { "glSecondaryColor3dvEXT", NAME(glSecondaryColor3dvEXT), _gloffset_SecondaryColor3dvEXT }, + { "glSecondaryColor3fvEXT", NAME(glSecondaryColor3fvEXT), _gloffset_SecondaryColor3fvEXT }, + { "glSecondaryColor3ivEXT", NAME(glSecondaryColor3ivEXT), _gloffset_SecondaryColor3ivEXT }, + { "glSecondaryColor3svEXT", NAME(glSecondaryColor3svEXT), _gloffset_SecondaryColor3svEXT }, + { "glSecondaryColor3ubvEXT", NAME(glSecondaryColor3ubvEXT), _gloffset_SecondaryColor3ubvEXT }, + { "glSecondaryColor3uivEXT", NAME(glSecondaryColor3uivEXT), _gloffset_SecondaryColor3uivEXT }, + { "glSecondaryColor3usvEXT", NAME(glSecondaryColor3usvEXT), _gloffset_SecondaryColor3usvEXT }, + { "glSecondaryColorPointerEXT", NAME(glSecondaryColorPointerEXT), _gloffset_SecondaryColorPointerEXT }, +#undef NAME + + /* 147. GL_EXT_texture_perturb_normal */ +#if 000 +#ifdef GL_EXT_texture_perturb_normal +#define NAME(X) (GLvoid *) X +#else +#define NAME(X) (GLvoid *) NotImplemented +#endif + { "glTextureNormalEXT", NAME(glTextureNormalEXT), _gloffset_TextureNormalEXT }, +#undef NAME +#endif + + /* 148. GL_EXT_multi_draw_arrays */ +#if 000 +#ifdef GL_EXT_multi_draw_arrays +#define NAME(X) (GLvoid *) X +#else +#define NAME(X) (GLvoid *) NotImplemented +#endif + { "glMultiDrawArraysEXT", NAME(glMultiDrawArraysEXT), _gloffset_MultiDrawArraysEXT }, +#undef NAME +#endif + + /* 149. GL_EXT_fog_coord */ +#ifdef GL_EXT_fog_coord +#define NAME(X) (GLvoid *) X +#else +#define NAME(X) (GLvoid *) NotImplemented +#endif + { "glFogCoordfEXT", NAME(glFogCoordfEXT), _gloffset_FogCoordfEXT }, + { "glFogCoordfvEXT", NAME(glFogCoordfvEXT), _gloffset_FogCoordfvEXT }, + { "glFogCoorddEXT", NAME(glFogCoorddEXT), _gloffset_FogCoorddEXT }, + { "glFogCoorddEXT", NAME(glFogCoorddEXT), _gloffset_FogCoorddEXT }, + { "glFogCoordPointerEXT", NAME(glFogCoordPointerEXT), _gloffset_FogCoordPointerEXT }, +#undef NAME + + /* 156. GL_EXT_coordinate_frame */ +#if 000 +#ifdef GL_EXT_coordinate_frame +#define NAME(X) (GLvoid *) X +#else +#define NAME(X) (GLvoid *) NotImplemented +#endif + { "glTangent3bEXT", NAME(glTangent3bEXT), _gloffset_Tangent3bEXT }, + { "glTangent3dEXT", NAME(glTangent3dEXT), _gloffset_Tangent3dEXT }, + { "glTangent3fEXT", NAME(glTangent3fEXT), _gloffset_Tangent3fEXT }, + { "glTangent3iEXT", NAME(glTangent3iEXT), _gloffset_Tangent3iEXT }, + { "glTangent3sEXT", NAME(glTangent3sEXT), _gloffset_Tangent3sEXT }, + { "glTangent3bvEXT", NAME(glTangent3bvEXT), _gloffset_Tangent3bvEXT }, + { "glTangent3dvEXT", NAME(glTangent3dvEXT), _gloffset_Tangent3dvEXT }, + { "glTangent3fvEXT", NAME(glTangent3fvEXT), _gloffset_Tangent3fvEXT }, + { "glTangent3ivEXT", NAME(glTangent3ivEXT), _gloffset_Tangent3ivEXT }, + { "glTangent3svEXT", NAME(glTangent3svEXT), _gloffset_Tangent3svEXT }, + { "glBinormal3bEXT", NAME(glBinormal3bEXT), _gloffset_Binormal3bEXT }, + { "glBinormal3dEXT", NAME(glBinormal3dEXT), _gloffset_Binormal3dEXT }, + { "glBinormal3fEXT", NAME(glBinormal3fEXT), _gloffset_Binormal3fEXT }, + { "glBinormal3iEXT", NAME(glBinormal3iEXT), _gloffset_Binormal3iEXT }, + { "glBinormal3sEXT", NAME(glBinormal3sEXT), _gloffset_Binormal3sEXT }, + { "glBinormal3bvEXT", NAME(glBinormal3bvEXT), _gloffset_Binormal3bvEXT }, + { "glBinormal3dvEXT", NAME(glBinormal3dvEXT), _gloffset_Binormal3dvEXT }, + { "glBinormal3fvEXT", NAME(glBinormal3fvEXT), _gloffset_Binormal3fvEXT }, + { "glBinormal3ivEXT", NAME(glBinormal3ivEXT), _gloffset_Binormal3ivEXT }, + { "glBinormal3svEXT", NAME(glBinormal3svEXT), _gloffset_Binormal3svEXT }, + { "glTangentPointerEXT", NAME(glTangentPointerEXT), _gloffset_TangentPointerEXT }, + { "glBinormalPointerEXT", NAME(glBinormalPointerEXT), _gloffset_BinormalPointerEXT }, +#undef NAME +#endif + + /* 164. GL_SUN_global_alpha */ +#if 000 +#ifdef GL_SUN_global_alpha +#define NAME(X) (GLvoid *) X +#else +#define NAME(X) (GLvoid *) NotImplemented +#endif + { "glGlobalAlphaFactorbSUN", NAME(glGlobalAlphaFactorbSUN), _gloffset_GlobalAlphaFactorbSUN }, + { "glGlobalAlphaFactorsSUN", NAME(glGlobalAlphaFactorsSUN), _gloffset_GlobalAlphaFactorsSUN }, + { "glGlobalAlphaFactoriSUN", NAME(glGlobalAlphaFactoriSUN), _gloffset_GlobalAlphaFactoriSUN }, + { "glGlobalAlphaFactorfSUN", NAME(glGlobalAlphaFactorfSUN), _gloffset_GlobalAlphaFactorfSUN }, + { "glGlobalAlphaFactordSUN", NAME(glGlobalAlphaFactordSUN), _gloffset_GlobalAlphaFactordSUN }, + { "glGlobalAlphaFactorubSUN", NAME(glGlobalAlphaFactorubSUN), _gloffset_GlobalAlphaFactorubSUN }, + { "glGlobalAlphaFactorusSUN", NAME(glGlobalAlphaFactorusSUN), _gloffset_GlobalAlphaFactorusSUN }, + { "glGlobalAlphaFactoruiSUN", NAME(glGlobalAlphaFactoruiSUN), _gloffset_GlobalAlphaFactoruiSUN }, +#undef NAME +#endif + + /* 165. GL_SUN_triangle_list */ +#if 000 +#ifdef GL_SUN_triangle_list +#define NAME(X) (GLvoid *) X +#else +#define NAME(X) (GLvoid *) NotImplemented +#endif + { "glReplacementCodeuiSUN", NAME(glReplacementCodeuiSUN), _gloffset_ReplacementCodeuiSUN }, + { "glReplacementCodeusSUN", NAME(glReplacementCodeusSUN), _gloffset_ReplacementCodeusSUN }, + { "glReplacementCodeubSUN", NAME(glReplacementCodeubSUN), _gloffset_ReplacementCodeubSUN }, + { "glReplacementCodeuivSUN", NAME(glReplacementCodeuivSUN), _gloffset_ReplacementCodeuivSUN }, + { "glReplacementCodeusvSUN", NAME(glReplacementCodeusvSUN), _gloffset_ReplacementCodeusvSUN }, + { "glReplacementCodeubvSUN", NAME(glReplacementCodeubvSUN), _gloffset_ReplacementCodeubvSUN }, + { "glReplacementCodePointerSUN", NAME(glReplacementCodePointerSUN), _gloffset_ReplacementCodePointerSUN }, +#undef NAME +#endif + + /* 166. GL_SUN_vertex */ +#if 000 +#ifdef GL_SUN_vertex +#define NAME(X) (GLvoid *) X +#else +#define NAME(X) (GLvoid *) NotImplemented +#endif + { "glColor4ubVertex2fSUN", NAME(glColor4ubVertex2fSUN), _gloffset_Color4ubVertex2fSUN }, + { "glColor4ubVertex2fvSUN", NAME(glColor4ubVertex2fvSUN), _gloffset_Color4ubVertex2fvSUN }, + { "glColor4ubVertex3fSUN", NAME(glColor4ubVertex3fSUN), _gloffset_Color4ubVertex3fSUN }, + { "glColor4ubVertex3fvSUN", NAME(glColor4ubVertex3fvSUN), _gloffset_Color4ubVertex3fvSUN }, + { "glColor3fVertex3fSUN", NAME(glColor3fVertex3fSUN), _gloffset_Color3fVertex3fSUN }, + { "glColor3fVertex3fvSUN", NAME(glColor3fVertex3fvSUN), _gloffset_Color3fVertex3fvSUN }, + { "glNormal3fVertex3fSUN", NAME(glNormal3fVertex3fSUN), _gloffset_Normal3fVertex3fSUN }, + { "glNormal3fVertex3fvSUN", NAME(glNormal3fVertex3fvSUN), _gloffset_Normal3fVertex3fvSUN }, + { "glColor4fNormal3fVertex3fSUN", NAME(glColor4fNormal3fVertex3fSUN), _gloffset_Color4fNormal3fVertex3fSUN }, + { "glColor4fNormal3fVertex3fvSUN", NAME(glColor4fNormal3fVertex3fvSUN), _gloffset_Color4fNormal3fVertex3fvSUN }, + { "glTexCoord2fVertex3fSUN", NAME(glTexCoord2fVertex3fSUN), _gloffset_TexCoord2fVertex3fSUN }, + { "glTexCoord2fVertex3fvSUN", NAME(glTexCoord2fVertex3fvSUN), _gloffset_TexCoord2fVertex3fvSUN }, + { "glTexCoord4fVertex4fSUN", NAME(glTexCoord4fVertex4fSUN), _gloffset_TexCoord4fVertex4fSUN }, + { "glTexCoord4fVertex4fvSUN", NAME(glTexCoord4fVertex4fvSUN), _gloffset_TexCoord4fVertex4fvSUN }, + { "glTexCoord2fColor4ubVertex3fSUN", NAME(glTexCoord2fColor4ubVertex3fSUN), _gloffset_TexCoord2fColor4ubVertex3fSUN }, + { "glTexCoord2fColor4ubVertex3fvSUN", NAME(glTexCoord2fColor4ubVertex3fvSUN), _gloffset_TexCoord2fColor4ubVertex3fvSUN }, + { "glTexCoord2fColor3fVertex3fSUN", NAME(glTexCoord2fColor3fVertex3fSUN), _gloffset_TexCoord2fColor3fVertex3fSUN }, + { "glTexCoord2fColor3fVertex3fvSUN", NAME(glTexCoord2fColor3fVertex3fvSUN), _gloffset_TexCoord2fColor3fVertex3fvSUN }, + { "glTexCoord2fNormal3fVertex3fSUN", NAME(glTexCoord2fNormal3fVertex3fSUN), _gloffset_TexCoord2fNormal3fVertex3fSUN }, + { "glTexCoord2fNormal3fVertex3fvSUN", NAME(glTexCoord2fNormal3fVertex3fvSUN), _gloffset_TexCoord2fNormal3fVertex3fvSUN }, + { "glTexCoord2fColor4fNormal3fVertex3fSUN", NAME(glTexCoord2fColor4fNormal3fVertex3fSUN), _gloffset_TexCoord2fColor4fNormal3fVertex3fSUN }, + { "glTexCoord2fColor4fNormal3fVertex3fvSUN", NAME(glTexCoord2fColor4fNormal3fVertex3fvSUN), _gloffset_TexCoord2fColor4fNormal3fVertex3fvSUN }, + { "glTexCoord4fColor4fNormal3fVertex4fSUN", NAME(glTexCoord4fColor4fNormal3fVertex4fSUN), _gloffset_TexCoord4fColor4fNormal3fVertex4fSUN }, + { "glTexCoord4fColor4fNormal3fVertex4fvSUN", NAME(glTexCoord4fColor4fNormal3fVertex4fvSUN), _gloffset_TexCoord4fColor4fNormal3fVertex4fvSUN }, + { "glReplacementCodeuiVertex3fSUN", NAME(glReplacementCodeuiVertex3fSUN), _gloffset_ReplacementCodeuiVertex3fSUN }, + { "glReplacementCodeuiVertex3fvSUN", NAME(glReplacementCodeuiVertex3fvSUN), _gloffset_ReplacementCodeuiVertex3fvSUN }, + { "glReplacementCodeuiColor4ubVertex3fSUN", NAME(glReplacementCodeuiColor4ubVertex3fSUN), _gloffset_ReplacementCodeuiColor4ubVertex3fSUN }, + { "glReplacementCodeuiColor4ubVertex3fvSUN", NAME(glReplacementCodeuiColor4ubVertex3fvSUN), _gloffset_ReplacementCodeuiColor4ubVertex3fvSUN }, + { "glReplacementCodeuiColor3fVertex3fSUN", NAME(glReplacementCodeuiColor3fVertex3fSUN), _gloffset_ReplacementCodeuiColor3fVertex3fSUN }, + { "glReplacementCodeuiColor3fVertex3fvSUN", NAME(glReplacementCodeuiColor3fVertex3fvSUN), _gloffset_ReplacementCodeuiColor3fVertex3fvSUN }, + { "glReplacementCodeuiNormal3fVertex3fSUN", NAME(glReplacementCodeuiNormal3fVertex3fSUN), _gloffset_ReplacementCodeuiNormal3fVertex3fSUN }, + { "glReplacementCodeuiNormal3fVertex3fvSUN", NAME(glReplacementCodeuiNormal3fVertex3fvSUN), _gloffset_ReplacementCodeuiNormal3fVertex3fvSUN }, + { "glReplacementCodeuiColor4fNormal3fVertex3fSUN", NAME(glReplacementCodeuiColor4fNormal3fVertex3fSUN), _gloffset_ReplacementCodeuiColor4fNormal3fVertex3fSUN }, + { "glReplacementCodeuiColor4fNormal3fVertex3fvSUN", NAME(glReplacementCodeuiColor4fNormal3fVertex3fvSUN), _gloffset_ReplacementCodeuiColor4fNormal3fVertex3fvSUN }, + { "glReplacementCodeuiTexCoord2fVertex3fSUN", NAME(glReplacementCodeuiTexCoord2fVertex3fSUN), _gloffset_ReplacementCodeuiTexCoord2fVertex3fSUN }, + { "glReplacementCodeuiTexCoord2fVertex3fvSUN", NAME(glReplacementCodeuiTexCoord2fVertex3fvSUN), _gloffset_ReplacementCodeuiTexCoord2fVertex3fvSUN }, + { "glReplacementCodeuiTexCoord2fNormal3fVertex3fSUN", NAME(glReplacementCodeuiTexCoord2fNormal3fVertex3fSUN), _gloffset_ReplacementCodeuiTexCoord2fNormal3fVertex3fSUN }, + { "glReplacementCodeuiTexCoord2fNormal3fVertex3fvSUN", NAME(glReplacementCodeuiTexCoord2fNormal3fVertex3fvSUN), _gloffset_ReplacementCodeuiTexCoord2fNormal3fVertex3fvSUN }, + { "glReplacementCodeuiTexCoord2fColor4fNormal3fVertex3fSUN", NAME(glReplacementCodeuiTexCoord2fColor4fNormal3fVertex3fSUN), _gloffset_ReplacementCodeuiTexCoord2fColor4fNormal3fVertex3fSUN }, + { "glReplacementCodeuiTexCoord2fColor4fNormal3fVertex3fvSUN", NAME(glReplacementCodeuiTexCoord2fColor4fNormal3fVertex3fvSUN), _gloffset_ReplacementCodeuiTexCoord2fColor4fNormal3fVertex3fvSUN }, +#undef NAME +#endif + + /* 173. GL_EXT/INGR_blend_func_separate */ +#ifdef GL_EXT_blend_func_separate +#define NAME(X) (GLvoid *) X +#else +#define NAME(X) (GLvoid *) NotImplemented +#endif + { "glBlendFuncSeparateEXT", NAME(glBlendFuncSeparateEXT), _gloffset_BlendFuncSeparateEXT }, + { "glBlendFuncSeparateINGR", NAME(glBlendFuncSeparateEXT), _gloffset_BlendFuncSeparateEXT }, +#undef NAME + + /* 188. GL_EXT_vertex_weighting */ +#ifdef GL_EXT_vertex_weighting +#define NAME(X) (GLvoid *) X +#else +#define NAME(X) (GLvoid *) NotImplemented +#endif + { "glVertexWeightfEXT", NAME(glVertexWeightfEXT), _gloffset_VertexWeightfEXT }, + { "glVertexWeightfvEXT", NAME(glVertexWeightfvEXT), _gloffset_VertexWeightfvEXT }, + { "glVertexWeightPointerEXT", NAME(glVertexWeightPointerEXT), _gloffset_VertexWeightPointerEXT }, +#undef NAME + + /* 190. GL_NV_vertex_array_range */ +#ifdef GL_NV_vertex_array_range +#define NAME(X) (GLvoid *) X +#else +#define NAME(X) (GLvoid *) NotImplemented +#endif + { "glFlushVertexArrayRangeNV", NAME(glFlushVertexArrayRangeNV), _gloffset_FlushVertexArrayRangeNV }, + { "glVertexArrayRangeNV", NAME(glVertexArrayRangeNV), _gloffset_VertexArrayRangeNV }, +#undef NAME + + /* 191. GL_NV_register_combiners */ +#ifdef GL_NV_register_combiners +#define NAME(X) (GLvoid *) X +#else +#define NAME(X) (GLvoid *) NotImplemented +#endif + { "glCombinerParameterfvNV", NAME(glCombinerParameterfvNV), _gloffset_CombinerParameterfvNV }, + { "glCombinerParameterfNV", NAME(glCombinerParameterfNV), _gloffset_CombinerParameterfNV }, + { "glCombinerParameterivNV", NAME(glCombinerParameterivNV), _gloffset_CombinerParameterivNV }, + { "glCombinerParameteriNV", NAME(glCombinerParameteriNV), _gloffset_CombinerParameteriNV }, + { "glCombinerInputNV", NAME(glCombinerInputNV), _gloffset_CombinerInputNV }, + { "glCombinerOutputNV", NAME(glCombinerOutputNV), _gloffset_CombinerOutputNV }, + { "glFinalCombinerInputNV", NAME(glFinalCombinerInputNV), _gloffset_FinalCombinerInputNV }, + { "glGetCombinerInputParameterfvNV", NAME(glGetCombinerInputParameterfvNV), _gloffset_GetCombinerInputParameterfvNV }, + { "glGetCombinerInputParameterivNV", NAME(glGetCombinerInputParameterivNV), _gloffset_GetCombinerInputParameterivNV }, + { "glGetCombinerOutputParameterfvNV", NAME(glGetCombinerOutputParameterfvNV), _gloffset_GetCombinerOutputParameterfvNV }, + { "glGetCombinerOutputParameterivNV", NAME(glGetCombinerOutputParameterivNV), _gloffset_GetCombinerOutputParameterivNV }, + { "glGetFinalCombinerInputParameterfvNV", NAME(glGetFinalCombinerInputParameterfvNV), _gloffset_GetFinalCombinerInputParameterfvNV }, + { "glGetFinalCombinerInputParameterivNV", NAME(glGetFinalCombinerInputParameterivNV), _gloffset_GetFinalCombinerInputParameterivNV }, +#undef NAME + + /* 196. GL_MESA_resize_buffers */ +#ifdef MESA_resize_buffers +#define NAME(X) (GLvoid *) X +#else +#define NAME(X) (GLvoid *) NotImplemented +#endif + { "glResizeBuffersMESA", NAME(glResizeBuffersMESA), _gloffset_ResizeBuffersMESA }, +#undef NAME + + /* 197. GL_MESA_window_pos */ +#ifdef MESA_window_pos +#define NAME(X) (GLvoid *) X +#else +#define NAME(X) (GLvoid *) NotImplemented +#endif + { "glWindowPos4fMESA", NAME(glWindowPos4fMESA), _gloffset_WindowPos4fMESA }, +#undef NAME + + /* 209. WGL_EXT_multisample */ +#ifdef WGL_EXT_multisample +#define NAME(X) (GLvoid *) X +#else +#define NAME(X) (GLvoid *) NotImplemented +#endif + { "glSampleMaskEXT", NAME(glSampleMaskEXT), _gloffset_SampleMaskSGIS }, + { "glSamplePatternEXT", NAME(glSamplePatternEXT), _gloffset_SamplePatternSGIS }, +#undef NAME + + { NULL, NULL } /* end of list marker */ +}; + + + +/* + * Return dispatch table offset of the named static (built-in) function. + * Return -1 if function not found. + */ +static GLint +get_static_proc_offset(const char *funcName) +{ + GLuint i; + for (i = 0; static_functions[i].Name; i++) { + if (strcmp(static_functions[i].Name, funcName) == 0) { + return static_functions[i].Offset; + } + } + return -1; +} + + +/* + * Return dispatch function address the named static (built-in) function. + * Return NULL if function not found. + */ +static GLvoid * +get_static_proc_address(const char *funcName) +{ + GLint i; + for (i = 0; static_functions[i].Name; i++) { + if (strcmp(static_functions[i].Name, funcName) == 0) { + return static_functions[i].Address; + } + } + return NULL; +} + + + +/********************************************************************** + * Extension function management. + */ + + +#define MAX_EXTENSION_FUNCS 1000 + +static struct name_address_offset ExtEntryTable[MAX_EXTENSION_FUNCS]; +static GLuint NumExtEntryPoints = 0; + +#ifdef USE_SPARC_ASM +extern void __glapi_sparc_icache_flush(unsigned int *); +#endif + +/* + * Generate a dispatch function (entrypoint) which jumps through + * the given slot number (offset) in the current dispatch table. + * We need assembly language in order to accomplish this. + */ +static void * +generate_entrypoint(GLuint functionOffset) +{ +#if defined(USE_X86_ASM) + /* + * This x86 code contributed by Josh Vanderhoof. + * + * 0: a1 10 32 54 76 movl __glapi_Dispatch,%eax + * 00 01 02 03 04 + * 5: 85 c0 testl %eax,%eax + * 05 06 + * 7: 74 06 je f + * 07 08 + * 9: ff a0 10 32 54 76 jmp *0x76543210(%eax) + * 09 0a 0b 0c 0d 0e + * f: e8 fc ff ff ff call __glapi_get_dispatch + * 0f 10 11 12 13 + * 14: ff a0 10 32 54 76 jmp *0x76543210(%eax) + * 14 15 16 17 18 19 + */ + static const unsigned char temp[] = { + 0xa1, 0x00, 0x00, 0x00, 0x00, + 0x85, 0xc0, + 0x74, 0x06, + 0xff, 0xa0, 0x00, 0x00, 0x00, 0x00, + 0xe8, 0x00, 0x00, 0x00, 0x00, + 0xff, 0xa0, 0x00, 0x00, 0x00, 0x00 + }; + unsigned char *code = malloc(sizeof(temp)); + unsigned int next_insn; + if (code) { + memcpy(code, temp, sizeof(temp)); + + *(unsigned int *)(code + 0x01) = (unsigned int)&_glapi_Dispatch; + *(unsigned int *)(code + 0x0b) = (unsigned int)functionOffset * 4; + next_insn = (unsigned int)(code + 0x14); + *(unsigned int *)(code + 0x10) = (unsigned int)_glapi_get_dispatch - next_insn; + *(unsigned int *)(code + 0x16) = (unsigned int)functionOffset * 4; + } + return code; +#elif defined(USE_SPARC_ASM) + +#ifdef __sparc_v9__ + static const unsigned int insn_template[] = { + 0x05000000, /* sethi %uhi(_glapi_Dispatch), %g2 */ + 0x03000000, /* sethi %hi(_glapi_Dispatch), %g1 */ + 0x8410a000, /* or %g2, %ulo(_glapi_Dispatch), %g2 */ + 0x82106000, /* or %g1, %lo(_glapi_Dispatch), %g1 */ + 0x8528b020, /* sllx %g2, 32, %g2 */ + 0xc2584002, /* ldx [%g1 + %g2], %g1 */ + 0x05000000, /* sethi %hi(8 * glapioffset), %g2 */ + 0x8410a000, /* or %g2, %lo(8 * glapioffset), %g2 */ + 0xc6584002, /* ldx [%g1 + %g2], %g3 */ + 0x81c0c000, /* jmpl %g3, %g0 */ + 0x01000000 /* nop */ + }; +#else + static const unsigned int insn_template[] = { + 0x03000000, /* sethi %hi(_glapi_Dispatch), %g1 */ + 0xc2006000, /* ld [%g1 + %lo(_glapi_Dispatch)], %g1 */ + 0xc6006000, /* ld [%g1 + %lo(4*glapioffset)], %g3 */ + 0x81c0c000, /* jmpl %g3, %g0 */ + 0x01000000 /* nop */ + }; +#endif + unsigned int *code = malloc(sizeof(insn_template)); + unsigned long glapi_addr = (unsigned long) &_glapi_Dispatch; + if (code) { + memcpy(code, insn_template, sizeof(insn_template)); + +#ifdef __sparc_v9__ + code[0] |= (glapi_addr >> (32 + 10)); + code[1] |= ((glapi_addr & 0xffffffff) >> 10); + __glapi_sparc_icache_flush(&code[0]); + code[2] |= ((glapi_addr >> 32) & ((1 << 10) - 1)); + code[3] |= (glapi_addr & ((1 << 10) - 1)); + __glapi_sparc_icache_flush(&code[2]); + code[6] |= ((functionOffset * 8) >> 10); + code[7] |= ((functionOffset * 8) & ((1 << 10) - 1)); + __glapi_sparc_icache_flush(&code[6]); +#else + code[0] |= (glapi_addr >> 10); + code[1] |= (glapi_addr & ((1 << 10) - 1)); + __glapi_sparc_icache_flush(&code[0]); + code[2] |= (functionOffset * 4); + __glapi_sparc_icache_flush(&code[2]); +#endif + } + return code; +#else + return NULL; +#endif +} + + + +/* + * Add a new extension function entrypoint. + * Return: GL_TRUE = success or GL_FALSE = failure + */ +GLboolean +_glapi_add_entrypoint(const char *funcName, GLuint offset) +{ + /* first check if the named function is already statically present */ + { + GLint index = get_static_proc_offset(funcName); + if (index >= 0) { + return (GLboolean) ((GLuint) index == offset); /* bad offset! */ + } + } + + { + /* make sure this offset/name pair is legal */ + const char *name = _glapi_get_proc_name(offset); + if (name && strcmp(name, funcName) != 0) + return GL_FALSE; /* bad name! */ + } + + { + /* be sure index and name match known data */ + GLuint i; + for (i = 0; i < NumExtEntryPoints; i++) { + if (strcmp(ExtEntryTable[i].Name, funcName) == 0) { + /* function already registered with api */ + if (ExtEntryTable[i].Offset == offset) { + return GL_TRUE; /* offsets match */ + } + else { + return GL_FALSE; /* bad offset! */ + } + } + } + + /* Make sure we don't try to add a new entrypoint after someone + * has already called _glapi_get_dispatch_table_size()! If that's + * happened the caller's information would become out of date. + */ + if (GetSizeCalled) + return GL_FALSE; + + /* make sure we have space */ + if (NumExtEntryPoints >= MAX_EXTENSION_FUNCS) { + return GL_FALSE; + } + else { + void *entrypoint = generate_entrypoint(offset); + if (!entrypoint) + return GL_FALSE; + + ExtEntryTable[NumExtEntryPoints].Name = str_dup(funcName); + ExtEntryTable[NumExtEntryPoints].Offset = offset; + ExtEntryTable[NumExtEntryPoints].Address = entrypoint; + NumExtEntryPoints++; + + if (offset > MaxDispatchOffset) + MaxDispatchOffset = offset; + + return GL_TRUE; /* success */ + } + } + + /* should never get here, but play it safe */ + return GL_FALSE; +} + + + +#if 0000 /* prototype code for dynamic extension slot allocation */ + +static int NextFreeOffset = 409; /*XXX*/ +#define MAX_DISPATCH_TABLE_SIZE 1000 + +/* + * Dynamically allocate a dispatch slot for an extension entrypoint + * and generate the assembly language dispatch stub. + * Return the dispatch offset for the function or -1 if no room or error. + */ +GLint +_glapi_add_entrypoint2(const char *funcName) +{ + int offset; + + /* first see if extension func is already known */ + offset = _glapi_get_proc_offset(funcName); + if (offset >= 0) + return offset; + + if (NumExtEntryPoints < MAX_EXTENSION_FUNCS + && NextFreeOffset < MAX_DISPATCH_TABLE_SIZE) { + void *entryPoint; + offset = NextFreeOffset; + entryPoint = generate_entrypoint(offset); + if (entryPoint) { + NextFreeOffset++; + ExtEntryTable[NumExtEntryPoints].Name = str_dup(funcName); + ExtEntryTable[NumExtEntryPoints].Offset = offset; + ExtEntryTable[NumExtEntryPoints].Address = entryPoint; + NumExtEntryPoints++; + return offset; + } + } + return -1; +} + +#endif + + + +/* + * Return offset of entrypoint for named function within dispatch table. + */ +GLint +_glapi_get_proc_offset(const char *funcName) +{ + /* search extension functions first */ + GLuint i; + for (i = 0; i < NumExtEntryPoints; i++) { + if (strcmp(ExtEntryTable[i].Name, funcName) == 0) { + return ExtEntryTable[i].Offset; + } + } + + /* search static functions */ + return get_static_proc_offset(funcName); +} + + + +/* + * Return entrypoint for named function. + */ +const GLvoid * +_glapi_get_proc_address(const char *funcName) +{ + /* search extension functions first */ + GLuint i; + for (i = 0; i < NumExtEntryPoints; i++) { + if (strcmp(ExtEntryTable[i].Name, funcName) == 0) { + return ExtEntryTable[i].Address; + } + } + + /* search static functions */ + return get_static_proc_address(funcName); +} + + + + +/* + * Return the name of the function at the given dispatch offset. + * This is only intended for debugging. + */ +const char * +_glapi_get_proc_name(GLuint offset) +{ + const GLuint n = sizeof(static_functions) / sizeof(struct name_address_offset); + GLuint i; + for (i = 0; i < n; i++) { + if (static_functions[i].Offset == offset) + return static_functions[i].Name; + } + + /* search added extension functions */ + for (i = 0; i < NumExtEntryPoints; i++) { + if (ExtEntryTable[i].Offset == offset) { + return ExtEntryTable[i].Name; + } + } + return NULL; +} + + + +/* + * Make sure there are no NULL pointers in the given dispatch table. + * Intented for debugging purposes. + */ +void +_glapi_check_table(const struct _glapi_table *table) +{ + const GLuint entries = _glapi_get_dispatch_table_size(); + const void **tab = (const void **) table; + GLuint i; + for (i = 1; i < entries; i++) { + assert(tab[i]); + } + +#ifdef DEBUG + /* Do some spot checks to be sure that the dispatch table + * slots are assigned correctly. + */ + { + GLuint BeginOffset = _glapi_get_proc_offset("glBegin"); + char *BeginFunc = (char*) &table->Begin; + GLuint offset = (BeginFunc - (char *) table) / sizeof(void *); + assert(BeginOffset == _gloffset_Begin); + assert(BeginOffset == offset); + } + { + GLuint viewportOffset = _glapi_get_proc_offset("glViewport"); + char *viewportFunc = (char*) &table->Viewport; + GLuint offset = (viewportFunc - (char *) table) / sizeof(void *); + assert(viewportOffset == _gloffset_Viewport); + assert(viewportOffset == offset); + } + { + GLuint VertexPointerOffset = _glapi_get_proc_offset("glVertexPointer"); + char *VertexPointerFunc = (char*) &table->VertexPointer; + GLuint offset = (VertexPointerFunc - (char *) table) / sizeof(void *); + assert(VertexPointerOffset == _gloffset_VertexPointer); + assert(VertexPointerOffset == offset); + } + { + GLuint ResetMinMaxOffset = _glapi_get_proc_offset("glResetMinmax"); + char *ResetMinMaxFunc = (char*) &table->ResetMinmax; + GLuint offset = (ResetMinMaxFunc - (char *) table) / sizeof(void *); + assert(ResetMinMaxOffset == _gloffset_ResetMinmax); + assert(ResetMinMaxOffset == offset); + } + { + GLuint blendColorOffset = _glapi_get_proc_offset("glBlendColor"); + char *blendColorFunc = (char*) &table->BlendColor; + GLuint offset = (blendColorFunc - (char *) table) / sizeof(void *); + assert(blendColorOffset == _gloffset_BlendColor); + assert(blendColorOffset == offset); + } + { + GLuint istextureOffset = _glapi_get_proc_offset("glIsTextureEXT"); + char *istextureFunc = (char*) &table->IsTextureEXT; + GLuint offset = (istextureFunc - (char *) table) / sizeof(void *); + assert(istextureOffset == _gloffset_IsTextureEXT); + assert(istextureOffset == offset); + } + { + GLuint secondaryColor3fOffset = _glapi_get_proc_offset("glSecondaryColor3fEXT"); + char *secondaryColor3fFunc = (char*) &table->SecondaryColor3fEXT; + GLuint offset = (secondaryColor3fFunc - (char *) table) / sizeof(void *); + assert(secondaryColor3fOffset == _gloffset_SecondaryColor3fEXT); + assert(secondaryColor3fOffset == offset); + assert(_glapi_get_proc_address("glSecondaryColor3fEXT") == (void *) &glSecondaryColor3fEXT); + } +#endif +} Index: dll/opengl/opengl32/mesa/glapi.h =================================================================== --- dll/opengl/opengl32/mesa/glapi.h (revision 0) +++ dll/opengl/opengl32/mesa/glapi.h (working copy) @@ -0,0 +1,106 @@ +/* $Id: glapi.h,v 1.19 2001/03/28 17:20:20 brianp Exp $ */ + +/* + * Mesa 3-D graphics library + * Version: 3.5 + * + * Copyright (C) 1999-2001 Brian Paul 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 + * BRIAN PAUL 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. + */ + + +#ifndef _GLAPI_H +#define _GLAPI_H + + +#include "GL/gl.h" + +struct _glapi_table; + + +extern void *_glapi_Context; + +extern struct _glapi_table *_glapi_Dispatch; + + +extern void +_glapi_noop_enable_warnings(GLboolean enable); + + +extern void +_glapi_check_multithread(void); + + +extern void +_glapi_set_context(void *context); + + +extern void * +_glapi_get_context(void); + + +extern void +_glapi_set_dispatch(struct _glapi_table *dispatch); + + +extern struct _glapi_table * +_glapi_get_dispatch(void); + + +extern int +_glapi_begin_dispatch_override(struct _glapi_table *override); + + +extern void +_glapi_end_dispatch_override(int layer); + + +struct _glapi_table * +_glapi_get_override_dispatch(int layer); + + +extern GLuint +_glapi_get_dispatch_table_size(void); + + +extern const char * +_glapi_get_version(void); + + +extern void +_glapi_check_table(const struct _glapi_table *table); + + +extern GLboolean +_glapi_add_entrypoint(const char *funcName, GLuint offset); + + +extern GLint +_glapi_get_proc_offset(const char *funcName); + + +extern const GLvoid * +_glapi_get_proc_address(const char *funcName); + + +extern const char * +_glapi_get_proc_name(GLuint offset); + + +#endif Index: dll/opengl/opengl32/mesa/glapioffsets.h =================================================================== --- dll/opengl/opengl32/mesa/glapioffsets.h (revision 0) +++ dll/opengl/opengl32/mesa/glapioffsets.h (working copy) @@ -0,0 +1,584 @@ +/* DO NOT EDIT - This file generated automatically by gloffsets.py script */ +#ifndef _GLAPI_OFFSETS_H_ +#define _GLAPI_OFFSETS_H_ + +#define _gloffset_NewList 0 +#define _gloffset_EndList 1 +#define _gloffset_CallList 2 +#define _gloffset_CallLists 3 +#define _gloffset_DeleteLists 4 +#define _gloffset_GenLists 5 +#define _gloffset_ListBase 6 +#define _gloffset_Begin 7 +#define _gloffset_Bitmap 8 +#define _gloffset_Color3b 9 +#define _gloffset_Color3bv 10 +#define _gloffset_Color3d 11 +#define _gloffset_Color3dv 12 +#define _gloffset_Color3f 13 +#define _gloffset_Color3fv 14 +#define _gloffset_Color3i 15 +#define _gloffset_Color3iv 16 +#define _gloffset_Color3s 17 +#define _gloffset_Color3sv 18 +#define _gloffset_Color3ub 19 +#define _gloffset_Color3ubv 20 +#define _gloffset_Color3ui 21 +#define _gloffset_Color3uiv 22 +#define _gloffset_Color3us 23 +#define _gloffset_Color3usv 24 +#define _gloffset_Color4b 25 +#define _gloffset_Color4bv 26 +#define _gloffset_Color4d 27 +#define _gloffset_Color4dv 28 +#define _gloffset_Color4f 29 +#define _gloffset_Color4fv 30 +#define _gloffset_Color4i 31 +#define _gloffset_Color4iv 32 +#define _gloffset_Color4s 33 +#define _gloffset_Color4sv 34 +#define _gloffset_Color4ub 35 +#define _gloffset_Color4ubv 36 +#define _gloffset_Color4ui 37 +#define _gloffset_Color4uiv 38 +#define _gloffset_Color4us 39 +#define _gloffset_Color4usv 40 +#define _gloffset_EdgeFlag 41 +#define _gloffset_EdgeFlagv 42 +#define _gloffset_End 43 +#define _gloffset_Indexd 44 +#define _gloffset_Indexdv 45 +#define _gloffset_Indexf 46 +#define _gloffset_Indexfv 47 +#define _gloffset_Indexi 48 +#define _gloffset_Indexiv 49 +#define _gloffset_Indexs 50 +#define _gloffset_Indexsv 51 +#define _gloffset_Normal3b 52 +#define _gloffset_Normal3bv 53 +#define _gloffset_Normal3d 54 +#define _gloffset_Normal3dv 55 +#define _gloffset_Normal3f 56 +#define _gloffset_Normal3fv 57 +#define _gloffset_Normal3i 58 +#define _gloffset_Normal3iv 59 +#define _gloffset_Normal3s 60 +#define _gloffset_Normal3sv 61 +#define _gloffset_RasterPos2d 62 +#define _gloffset_RasterPos2dv 63 +#define _gloffset_RasterPos2f 64 +#define _gloffset_RasterPos2fv 65 +#define _gloffset_RasterPos2i 66 +#define _gloffset_RasterPos2iv 67 +#define _gloffset_RasterPos2s 68 +#define _gloffset_RasterPos2sv 69 +#define _gloffset_RasterPos3d 70 +#define _gloffset_RasterPos3dv 71 +#define _gloffset_RasterPos3f 72 +#define _gloffset_RasterPos3fv 73 +#define _gloffset_RasterPos3i 74 +#define _gloffset_RasterPos3iv 75 +#define _gloffset_RasterPos3s 76 +#define _gloffset_RasterPos3sv 77 +#define _gloffset_RasterPos4d 78 +#define _gloffset_RasterPos4dv 79 +#define _gloffset_RasterPos4f 80 +#define _gloffset_RasterPos4fv 81 +#define _gloffset_RasterPos4i 82 +#define _gloffset_RasterPos4iv 83 +#define _gloffset_RasterPos4s 84 +#define _gloffset_RasterPos4sv 85 +#define _gloffset_Rectd 86 +#define _gloffset_Rectdv 87 +#define _gloffset_Rectf 88 +#define _gloffset_Rectfv 89 +#define _gloffset_Recti 90 +#define _gloffset_Rectiv 91 +#define _gloffset_Rects 92 +#define _gloffset_Rectsv 93 +#define _gloffset_TexCoord1d 94 +#define _gloffset_TexCoord1dv 95 +#define _gloffset_TexCoord1f 96 +#define _gloffset_TexCoord1fv 97 +#define _gloffset_TexCoord1i 98 +#define _gloffset_TexCoord1iv 99 +#define _gloffset_TexCoord1s 100 +#define _gloffset_TexCoord1sv 101 +#define _gloffset_TexCoord2d 102 +#define _gloffset_TexCoord2dv 103 +#define _gloffset_TexCoord2f 104 +#define _gloffset_TexCoord2fv 105 +#define _gloffset_TexCoord2i 106 +#define _gloffset_TexCoord2iv 107 +#define _gloffset_TexCoord2s 108 +#define _gloffset_TexCoord2sv 109 +#define _gloffset_TexCoord3d 110 +#define _gloffset_TexCoord3dv 111 +#define _gloffset_TexCoord3f 112 +#define _gloffset_TexCoord3fv 113 +#define _gloffset_TexCoord3i 114 +#define _gloffset_TexCoord3iv 115 +#define _gloffset_TexCoord3s 116 +#define _gloffset_TexCoord3sv 117 +#define _gloffset_TexCoord4d 118 +#define _gloffset_TexCoord4dv 119 +#define _gloffset_TexCoord4f 120 +#define _gloffset_TexCoord4fv 121 +#define _gloffset_TexCoord4i 122 +#define _gloffset_TexCoord4iv 123 +#define _gloffset_TexCoord4s 124 +#define _gloffset_TexCoord4sv 125 +#define _gloffset_Vertex2d 126 +#define _gloffset_Vertex2dv 127 +#define _gloffset_Vertex2f 128 +#define _gloffset_Vertex2fv 129 +#define _gloffset_Vertex2i 130 +#define _gloffset_Vertex2iv 131 +#define _gloffset_Vertex2s 132 +#define _gloffset_Vertex2sv 133 +#define _gloffset_Vertex3d 134 +#define _gloffset_Vertex3dv 135 +#define _gloffset_Vertex3f 136 +#define _gloffset_Vertex3fv 137 +#define _gloffset_Vertex3i 138 +#define _gloffset_Vertex3iv 139 +#define _gloffset_Vertex3s 140 +#define _gloffset_Vertex3sv 141 +#define _gloffset_Vertex4d 142 +#define _gloffset_Vertex4dv 143 +#define _gloffset_Vertex4f 144 +#define _gloffset_Vertex4fv 145 +#define _gloffset_Vertex4i 146 +#define _gloffset_Vertex4iv 147 +#define _gloffset_Vertex4s 148 +#define _gloffset_Vertex4sv 149 +#define _gloffset_ClipPlane 150 +#define _gloffset_ColorMaterial 151 +#define _gloffset_CullFace 152 +#define _gloffset_Fogf 153 +#define _gloffset_Fogfv 154 +#define _gloffset_Fogi 155 +#define _gloffset_Fogiv 156 +#define _gloffset_FrontFace 157 +#define _gloffset_Hint 158 +#define _gloffset_Lightf 159 +#define _gloffset_Lightfv 160 +#define _gloffset_Lighti 161 +#define _gloffset_Lightiv 162 +#define _gloffset_LightModelf 163 +#define _gloffset_LightModelfv 164 +#define _gloffset_LightModeli 165 +#define _gloffset_LightModeliv 166 +#define _gloffset_LineStipple 167 +#define _gloffset_LineWidth 168 +#define _gloffset_Materialf 169 +#define _gloffset_Materialfv 170 +#define _gloffset_Materiali 171 +#define _gloffset_Materialiv 172 +#define _gloffset_PointSize 173 +#define _gloffset_PolygonMode 174 +#define _gloffset_PolygonStipple 175 +#define _gloffset_Scissor 176 +#define _gloffset_ShadeModel 177 +#define _gloffset_TexParameterf 178 +#define _gloffset_TexParameterfv 179 +#define _gloffset_TexParameteri 180 +#define _gloffset_TexParameteriv 181 +#define _gloffset_TexImage1D 182 +#define _gloffset_TexImage2D 183 +#define _gloffset_TexEnvf 184 +#define _gloffset_TexEnvfv 185 +#define _gloffset_TexEnvi 186 +#define _gloffset_TexEnviv 187 +#define _gloffset_TexGend 188 +#define _gloffset_TexGendv 189 +#define _gloffset_TexGenf 190 +#define _gloffset_TexGenfv 191 +#define _gloffset_TexGeni 192 +#define _gloffset_TexGeniv 193 +#define _gloffset_FeedbackBuffer 194 +#define _gloffset_SelectBuffer 195 +#define _gloffset_RenderMode 196 +#define _gloffset_InitNames 197 +#define _gloffset_LoadName 198 +#define _gloffset_PassThrough 199 +#define _gloffset_PopName 200 +#define _gloffset_PushName 201 +#define _gloffset_DrawBuffer 202 +#define _gloffset_Clear 203 +#define _gloffset_ClearAccum 204 +#define _gloffset_ClearIndex 205 +#define _gloffset_ClearColor 206 +#define _gloffset_ClearStencil 207 +#define _gloffset_ClearDepth 208 +#define _gloffset_StencilMask 209 +#define _gloffset_ColorMask 210 +#define _gloffset_DepthMask 211 +#define _gloffset_IndexMask 212 +#define _gloffset_Accum 213 +#define _gloffset_Disable 214 +#define _gloffset_Enable 215 +#define _gloffset_Finish 216 +#define _gloffset_Flush 217 +#define _gloffset_PopAttrib 218 +#define _gloffset_PushAttrib 219 +#define _gloffset_Map1d 220 +#define _gloffset_Map1f 221 +#define _gloffset_Map2d 222 +#define _gloffset_Map2f 223 +#define _gloffset_MapGrid1d 224 +#define _gloffset_MapGrid1f 225 +#define _gloffset_MapGrid2d 226 +#define _gloffset_MapGrid2f 227 +#define _gloffset_EvalCoord1d 228 +#define _gloffset_EvalCoord1dv 229 +#define _gloffset_EvalCoord1f 230 +#define _gloffset_EvalCoord1fv 231 +#define _gloffset_EvalCoord2d 232 +#define _gloffset_EvalCoord2dv 233 +#define _gloffset_EvalCoord2f 234 +#define _gloffset_EvalCoord2fv 235 +#define _gloffset_EvalMesh1 236 +#define _gloffset_EvalPoint1 237 +#define _gloffset_EvalMesh2 238 +#define _gloffset_EvalPoint2 239 +#define _gloffset_AlphaFunc 240 +#define _gloffset_BlendFunc 241 +#define _gloffset_LogicOp 242 +#define _gloffset_StencilFunc 243 +#define _gloffset_StencilOp 244 +#define _gloffset_DepthFunc 245 +#define _gloffset_PixelZoom 246 +#define _gloffset_PixelTransferf 247 +#define _gloffset_PixelTransferi 248 +#define _gloffset_PixelStoref 249 +#define _gloffset_PixelStorei 250 +#define _gloffset_PixelMapfv 251 +#define _gloffset_PixelMapuiv 252 +#define _gloffset_PixelMapusv 253 +#define _gloffset_ReadBuffer 254 +#define _gloffset_CopyPixels 255 +#define _gloffset_ReadPixels 256 +#define _gloffset_DrawPixels 257 +#define _gloffset_GetBooleanv 258 +#define _gloffset_GetClipPlane 259 +#define _gloffset_GetDoublev 260 +#define _gloffset_GetError 261 +#define _gloffset_GetFloatv 262 +#define _gloffset_GetIntegerv 263 +#define _gloffset_GetLightfv 264 +#define _gloffset_GetLightiv 265 +#define _gloffset_GetMapdv 266 +#define _gloffset_GetMapfv 267 +#define _gloffset_GetMapiv 268 +#define _gloffset_GetMaterialfv 269 +#define _gloffset_GetMaterialiv 270 +#define _gloffset_GetPixelMapfv 271 +#define _gloffset_GetPixelMapuiv 272 +#define _gloffset_GetPixelMapusv 273 +#define _gloffset_GetPolygonStipple 274 +#define _gloffset_GetString 275 +#define _gloffset_GetTexEnvfv 276 +#define _gloffset_GetTexEnviv 277 +#define _gloffset_GetTexGendv 278 +#define _gloffset_GetTexGenfv 279 +#define _gloffset_GetTexGeniv 280 +#define _gloffset_GetTexImage 281 +#define _gloffset_GetTexParameterfv 282 +#define _gloffset_GetTexParameteriv 283 +#define _gloffset_GetTexLevelParameterfv 284 +#define _gloffset_GetTexLevelParameteriv 285 +#define _gloffset_IsEnabled 286 +#define _gloffset_IsList 287 +#define _gloffset_DepthRange 288 +#define _gloffset_Frustum 289 +#define _gloffset_LoadIdentity 290 +#define _gloffset_LoadMatrixf 291 +#define _gloffset_LoadMatrixd 292 +#define _gloffset_MatrixMode 293 +#define _gloffset_MultMatrixf 294 +#define _gloffset_MultMatrixd 295 +#define _gloffset_Ortho 296 +#define _gloffset_PopMatrix 297 +#define _gloffset_PushMatrix 298 +#define _gloffset_Rotated 299 +#define _gloffset_Rotatef 300 +#define _gloffset_Scaled 301 +#define _gloffset_Scalef 302 +#define _gloffset_Translated 303 +#define _gloffset_Translatef 304 +#define _gloffset_Viewport 305 +#define _gloffset_ArrayElement 306 +#define _gloffset_BindTexture 307 +#define _gloffset_ColorPointer 308 +#define _gloffset_DisableClientState 309 +#define _gloffset_DrawArrays 310 +#define _gloffset_DrawElements 311 +#define _gloffset_EdgeFlagPointer 312 +#define _gloffset_EnableClientState 313 +#define _gloffset_IndexPointer 314 +#define _gloffset_Indexub 315 +#define _gloffset_Indexubv 316 +#define _gloffset_InterleavedArrays 317 +#define _gloffset_NormalPointer 318 +#define _gloffset_PolygonOffset 319 +#define _gloffset_TexCoordPointer 320 +#define _gloffset_VertexPointer 321 +#define _gloffset_AreTexturesResident 322 +#define _gloffset_CopyTexImage1D 323 +#define _gloffset_CopyTexImage2D 324 +#define _gloffset_CopyTexSubImage1D 325 +#define _gloffset_CopyTexSubImage2D 326 +#define _gloffset_DeleteTextures 327 +#define _gloffset_GenTextures 328 +#define _gloffset_GetPointerv 329 +#define _gloffset_IsTexture 330 +#define _gloffset_PrioritizeTextures 331 +#define _gloffset_TexSubImage1D 332 +#define _gloffset_TexSubImage2D 333 +#define _gloffset_PopClientAttrib 334 +#define _gloffset_PushClientAttrib 335 +#define _gloffset_BlendColor 336 +#define _gloffset_BlendEquation 337 +#define _gloffset_DrawRangeElements 338 +#define _gloffset_ColorTable 339 +#define _gloffset_ColorTableParameterfv 340 +#define _gloffset_ColorTableParameteriv 341 +#define _gloffset_CopyColorTable 342 +#define _gloffset_GetColorTable 343 +#define _gloffset_GetColorTableParameterfv 344 +#define _gloffset_GetColorTableParameteriv 345 +#define _gloffset_ColorSubTable 346 +#define _gloffset_CopyColorSubTable 347 +#define _gloffset_ConvolutionFilter1D 348 +#define _gloffset_ConvolutionFilter2D 349 +#define _gloffset_ConvolutionParameterf 350 +#define _gloffset_ConvolutionParameterfv 351 +#define _gloffset_ConvolutionParameteri 352 +#define _gloffset_ConvolutionParameteriv 353 +#define _gloffset_CopyConvolutionFilter1D 354 +#define _gloffset_CopyConvolutionFilter2D 355 +#define _gloffset_GetConvolutionFilter 356 +#define _gloffset_GetConvolutionParameterfv 357 +#define _gloffset_GetConvolutionParameteriv 358 +#define _gloffset_GetSeparableFilter 359 +#define _gloffset_SeparableFilter2D 360 +#define _gloffset_GetHistogram 361 +#define _gloffset_GetHistogramParameterfv 362 +#define _gloffset_GetHistogramParameteriv 363 +#define _gloffset_GetMinmax 364 +#define _gloffset_GetMinmaxParameterfv 365 +#define _gloffset_GetMinmaxParameteriv 366 +#define _gloffset_Histogram 367 +#define _gloffset_Minmax 368 +#define _gloffset_ResetHistogram 369 +#define _gloffset_ResetMinmax 370 +#define _gloffset_TexImage3D 371 +#define _gloffset_TexSubImage3D 372 +#define _gloffset_CopyTexSubImage3D 373 +#define _gloffset_ActiveTextureARB 374 +#define _gloffset_ClientActiveTextureARB 375 +#define _gloffset_MultiTexCoord1dARB 376 +#define _gloffset_MultiTexCoord1dvARB 377 +#define _gloffset_MultiTexCoord1fARB 378 +#define _gloffset_MultiTexCoord1fvARB 379 +#define _gloffset_MultiTexCoord1iARB 380 +#define _gloffset_MultiTexCoord1ivARB 381 +#define _gloffset_MultiTexCoord1sARB 382 +#define _gloffset_MultiTexCoord1svARB 383 +#define _gloffset_MultiTexCoord2dARB 384 +#define _gloffset_MultiTexCoord2dvARB 385 +#define _gloffset_MultiTexCoord2fARB 386 +#define _gloffset_MultiTexCoord2fvARB 387 +#define _gloffset_MultiTexCoord2iARB 388 +#define _gloffset_MultiTexCoord2ivARB 389 +#define _gloffset_MultiTexCoord2sARB 390 +#define _gloffset_MultiTexCoord2svARB 391 +#define _gloffset_MultiTexCoord3dARB 392 +#define _gloffset_MultiTexCoord3dvARB 393 +#define _gloffset_MultiTexCoord3fARB 394 +#define _gloffset_MultiTexCoord3fvARB 395 +#define _gloffset_MultiTexCoord3iARB 396 +#define _gloffset_MultiTexCoord3ivARB 397 +#define _gloffset_MultiTexCoord3sARB 398 +#define _gloffset_MultiTexCoord3svARB 399 +#define _gloffset_MultiTexCoord4dARB 400 +#define _gloffset_MultiTexCoord4dvARB 401 +#define _gloffset_MultiTexCoord4fARB 402 +#define _gloffset_MultiTexCoord4fvARB 403 +#define _gloffset_MultiTexCoord4iARB 404 +#define _gloffset_MultiTexCoord4ivARB 405 +#define _gloffset_MultiTexCoord4sARB 406 +#define _gloffset_MultiTexCoord4svARB 407 +#define _gloffset_LoadTransposeMatrixfARB 408 +#define _gloffset_LoadTransposeMatrixdARB 409 +#define _gloffset_MultTransposeMatrixfARB 410 +#define _gloffset_MultTransposeMatrixdARB 411 +#define _gloffset_SampleCoverageARB 412 +#define _gloffset_SamplePassARB 413 +#define _gloffset_PolygonOffsetEXT 414 +#define _gloffset_GetTexFilterFuncSGIS 415 +#define _gloffset_TexFilterFuncSGIS 416 +#define _gloffset_GetHistogramEXT 417 +#define _gloffset_GetHistogramParameterfvEXT 418 +#define _gloffset_GetHistogramParameterivEXT 419 +#define _gloffset_GetMinmaxEXT 420 +#define _gloffset_GetMinmaxParameterfvEXT 421 +#define _gloffset_GetMinmaxParameterivEXT 422 +#define _gloffset_GetConvolutionFilterEXT 423 +#define _gloffset_GetConvolutionParameterfvEXT 424 +#define _gloffset_GetConvolutionParameterivEXT 425 +#define _gloffset_GetSeparableFilterEXT 426 +#define _gloffset_GetColorTableSGI 427 +#define _gloffset_GetColorTableParameterfvSGI 428 +#define _gloffset_GetColorTableParameterivSGI 429 +#define _gloffset_PixelTexGenSGIX 430 +#define _gloffset_PixelTexGenParameteriSGIS 431 +#define _gloffset_PixelTexGenParameterivSGIS 432 +#define _gloffset_PixelTexGenParameterfSGIS 433 +#define _gloffset_PixelTexGenParameterfvSGIS 434 +#define _gloffset_GetPixelTexGenParameterivSGIS 435 +#define _gloffset_GetPixelTexGenParameterfvSGIS 436 +#define _gloffset_TexImage4DSGIS 437 +#define _gloffset_TexSubImage4DSGIS 438 +#define _gloffset_AreTexturesResidentEXT 439 +#define _gloffset_GenTexturesEXT 440 +#define _gloffset_IsTextureEXT 441 +#define _gloffset_DetailTexFuncSGIS 442 +#define _gloffset_GetDetailTexFuncSGIS 443 +#define _gloffset_SharpenTexFuncSGIS 444 +#define _gloffset_GetSharpenTexFuncSGIS 445 +#define _gloffset_SampleMaskSGIS 446 +#define _gloffset_SamplePatternSGIS 447 +#define _gloffset_ColorPointerEXT 448 +#define _gloffset_EdgeFlagPointerEXT 449 +#define _gloffset_IndexPointerEXT 450 +#define _gloffset_NormalPointerEXT 451 +#define _gloffset_TexCoordPointerEXT 452 +#define _gloffset_VertexPointerEXT 453 +#define _gloffset_SpriteParameterfSGIX 454 +#define _gloffset_SpriteParameterfvSGIX 455 +#define _gloffset_SpriteParameteriSGIX 456 +#define _gloffset_SpriteParameterivSGIX 457 +#define _gloffset_PointParameterfEXT 458 +#define _gloffset_PointParameterfvEXT 459 +#define _gloffset_GetInstrumentsSGIX 460 +#define _gloffset_InstrumentsBufferSGIX 461 +#define _gloffset_PollInstrumentsSGIX 462 +#define _gloffset_ReadInstrumentsSGIX 463 +#define _gloffset_StartInstrumentsSGIX 464 +#define _gloffset_StopInstrumentsSGIX 465 +#define _gloffset_FrameZoomSGIX 466 +#define _gloffset_TagSampleBufferSGIX 467 +#define _gloffset_ReferencePlaneSGIX 468 +#define _gloffset_FlushRasterSGIX 469 +#define _gloffset_GetListParameterfvSGIX 470 +#define _gloffset_GetListParameterivSGIX 471 +#define _gloffset_ListParameterfSGIX 472 +#define _gloffset_ListParameterfvSGIX 473 +#define _gloffset_ListParameteriSGIX 474 +#define _gloffset_ListParameterivSGIX 475 +#define _gloffset_FragmentColorMaterialSGIX 476 +#define _gloffset_FragmentLightfSGIX 477 +#define _gloffset_FragmentLightfvSGIX 478 +#define _gloffset_FragmentLightiSGIX 479 +#define _gloffset_FragmentLightivSGIX 480 +#define _gloffset_FragmentLightModelfSGIX 481 +#define _gloffset_FragmentLightModelfvSGIX 482 +#define _gloffset_FragmentLightModeliSGIX 483 +#define _gloffset_FragmentLightModelivSGIX 484 +#define _gloffset_FragmentMaterialfSGIX 485 +#define _gloffset_FragmentMaterialfvSGIX 486 +#define _gloffset_FragmentMaterialiSGIX 487 +#define _gloffset_FragmentMaterialivSGIX 488 +#define _gloffset_GetFragmentLightfvSGIX 489 +#define _gloffset_GetFragmentLightivSGIX 490 +#define _gloffset_GetFragmentMaterialfvSGIX 491 +#define _gloffset_GetFragmentMaterialivSGIX 492 +#define _gloffset_LightEnviSGIX 493 +#define _gloffset_VertexWeightfEXT 494 +#define _gloffset_VertexWeightfvEXT 495 +#define _gloffset_VertexWeightPointerEXT 496 +#define _gloffset_FlushVertexArrayRangeNV 497 +#define _gloffset_VertexArrayRangeNV 498 +#define _gloffset_CombinerParameterfvNV 499 +#define _gloffset_CombinerParameterfNV 500 +#define _gloffset_CombinerParameterivNV 501 +#define _gloffset_CombinerParameteriNV 502 +#define _gloffset_CombinerInputNV 503 +#define _gloffset_CombinerOutputNV 504 +#define _gloffset_FinalCombinerInputNV 505 +#define _gloffset_GetCombinerInputParameterfvNV 506 +#define _gloffset_GetCombinerInputParameterivNV 507 +#define _gloffset_GetCombinerOutputParameterfvNV 508 +#define _gloffset_GetCombinerOutputParameterivNV 509 +#define _gloffset_GetFinalCombinerInputParameterfvNV 510 +#define _gloffset_GetFinalCombinerInputParameterivNV 511 +#define _gloffset_ResizeBuffersMESA 512 +#define _gloffset_WindowPos2dMESA 513 +#define _gloffset_WindowPos2dvMESA 514 +#define _gloffset_WindowPos2fMESA 515 +#define _gloffset_WindowPos2fvMESA 516 +#define _gloffset_WindowPos2iMESA 517 +#define _gloffset_WindowPos2ivMESA 518 +#define _gloffset_WindowPos2sMESA 519 +#define _gloffset_WindowPos2svMESA 520 +#define _gloffset_WindowPos3dMESA 521 +#define _gloffset_WindowPos3dvMESA 522 +#define _gloffset_WindowPos3fMESA 523 +#define _gloffset_WindowPos3fvMESA 524 +#define _gloffset_WindowPos3iMESA 525 +#define _gloffset_WindowPos3ivMESA 526 +#define _gloffset_WindowPos3sMESA 527 +#define _gloffset_WindowPos3svMESA 528 +#define _gloffset_WindowPos4dMESA 529 +#define _gloffset_WindowPos4dvMESA 530 +#define _gloffset_WindowPos4fMESA 531 +#define _gloffset_WindowPos4fvMESA 532 +#define _gloffset_WindowPos4iMESA 533 +#define _gloffset_WindowPos4ivMESA 534 +#define _gloffset_WindowPos4sMESA 535 +#define _gloffset_WindowPos4svMESA 536 +#define _gloffset_BlendFuncSeparateEXT 537 +#define _gloffset_IndexMaterialEXT 538 +#define _gloffset_IndexFuncEXT 539 +#define _gloffset_LockArraysEXT 540 +#define _gloffset_UnlockArraysEXT 541 +#define _gloffset_CullParameterdvEXT 542 +#define _gloffset_CullParameterfvEXT 543 +#define _gloffset_HintPGI 544 +#define _gloffset_FogCoordfEXT 545 +#define _gloffset_FogCoordfvEXT 546 +#define _gloffset_FogCoorddEXT 547 +#define _gloffset_FogCoorddvEXT 548 +#define _gloffset_FogCoordPointerEXT 549 +#define _gloffset_GetColorTableEXT 550 +#define _gloffset_GetColorTableParameterivEXT 551 +#define _gloffset_GetColorTableParameterfvEXT 552 +#define _gloffset_TbufferMask3DFX 553 +#define _gloffset_CompressedTexImage3DARB 554 +#define _gloffset_CompressedTexImage2DARB 555 +#define _gloffset_CompressedTexImage1DARB 556 +#define _gloffset_CompressedTexSubImage3DARB 557 +#define _gloffset_CompressedTexSubImage2DARB 558 +#define _gloffset_CompressedTexSubImage1DARB 559 +#define _gloffset_GetCompressedTexImageARB 560 +#define _gloffset_SecondaryColor3bEXT 561 +#define _gloffset_SecondaryColor3bvEXT 562 +#define _gloffset_SecondaryColor3dEXT 563 +#define _gloffset_SecondaryColor3dvEXT 564 +#define _gloffset_SecondaryColor3fEXT 565 +#define _gloffset_SecondaryColor3fvEXT 566 +#define _gloffset_SecondaryColor3iEXT 567 +#define _gloffset_SecondaryColor3ivEXT 568 +#define _gloffset_SecondaryColor3sEXT 569 +#define _gloffset_SecondaryColor3svEXT 570 +#define _gloffset_SecondaryColor3ubEXT 571 +#define _gloffset_SecondaryColor3ubvEXT 572 +#define _gloffset_SecondaryColor3uiEXT 573 +#define _gloffset_SecondaryColor3uivEXT 574 +#define _gloffset_SecondaryColor3usEXT 575 +#define _gloffset_SecondaryColor3usvEXT 576 +#define _gloffset_SecondaryColorPointerEXT 577 + +#endif Index: dll/opengl/opengl32/mesa/glapitable.h =================================================================== --- dll/opengl/opengl32/mesa/glapitable.h (revision 0) +++ dll/opengl/opengl32/mesa/glapitable.h (working copy) @@ -0,0 +1,589 @@ +/* DO NOT EDIT - This file generated automatically with gltable.py script */ +#ifndef _GLAPI_TABLE_H_ +#define _GLAPI_TABLE_H_ + +#include + +struct _glapi_table +{ + void (*NewList)(GLuint list, GLenum mode); /* 0 */ + void (*EndList)(void); /* 1 */ + void (*CallList)(GLuint list); /* 2 */ + void (*CallLists)(GLsizei n, GLenum type, const GLvoid * lists); /* 3 */ + void (*DeleteLists)(GLuint list, GLsizei range); /* 4 */ + GLuint (*GenLists)(GLsizei range); /* 5 */ + void (*ListBase)(GLuint base); /* 6 */ + void (*Begin)(GLenum mode); /* 7 */ + void (*Bitmap)(GLsizei width, GLsizei height, GLfloat xorig, GLfloat yorig, GLfloat xmove, GLfloat ymove, const GLubyte * bitmap); /* 8 */ + void (*Color3b)(GLbyte red, GLbyte green, GLbyte blue); /* 9 */ + void (*Color3bv)(const GLbyte * v); /* 10 */ + void (*Color3d)(GLdouble red, GLdouble green, GLdouble blue); /* 11 */ + void (*Color3dv)(const GLdouble * v); /* 12 */ + void (*Color3f)(GLfloat red, GLfloat green, GLfloat blue); /* 13 */ + void (*Color3fv)(const GLfloat * v); /* 14 */ + void (*Color3i)(GLint red, GLint green, GLint blue); /* 15 */ + void (*Color3iv)(const GLint * v); /* 16 */ + void (*Color3s)(GLshort red, GLshort green, GLshort blue); /* 17 */ + void (*Color3sv)(const GLshort * v); /* 18 */ + void (*Color3ub)(GLubyte red, GLubyte green, GLubyte blue); /* 19 */ + void (*Color3ubv)(const GLubyte * v); /* 20 */ + void (*Color3ui)(GLuint red, GLuint green, GLuint blue); /* 21 */ + void (*Color3uiv)(const GLuint * v); /* 22 */ + void (*Color3us)(GLushort red, GLushort green, GLushort blue); /* 23 */ + void (*Color3usv)(const GLushort * v); /* 24 */ + void (*Color4b)(GLbyte red, GLbyte green, GLbyte blue, GLbyte alpha); /* 25 */ + void (*Color4bv)(const GLbyte * v); /* 26 */ + void (*Color4d)(GLdouble red, GLdouble green, GLdouble blue, GLdouble alpha); /* 27 */ + void (*Color4dv)(const GLdouble * v); /* 28 */ + void (*Color4f)(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha); /* 29 */ + void (*Color4fv)(const GLfloat * v); /* 30 */ + void (*Color4i)(GLint red, GLint green, GLint blue, GLint alpha); /* 31 */ + void (*Color4iv)(const GLint * v); /* 32 */ + void (*Color4s)(GLshort red, GLshort green, GLshort blue, GLshort alpha); /* 33 */ + void (*Color4sv)(const GLshort * v); /* 34 */ + void (*Color4ub)(GLubyte red, GLubyte green, GLubyte blue, GLubyte alpha); /* 35 */ + void (*Color4ubv)(const GLubyte * v); /* 36 */ + void (*Color4ui)(GLuint red, GLuint green, GLuint blue, GLuint alpha); /* 37 */ + void (*Color4uiv)(const GLuint * v); /* 38 */ + void (*Color4us)(GLushort red, GLushort green, GLushort blue, GLushort alpha); /* 39 */ + void (*Color4usv)(const GLushort * v); /* 40 */ + void (*EdgeFlag)(GLboolean flag); /* 41 */ + void (*EdgeFlagv)(const GLboolean * flag); /* 42 */ + void (*End)(void); /* 43 */ + void (*Indexd)(GLdouble c); /* 44 */ + void (*Indexdv)(const GLdouble * c); /* 45 */ + void (*Indexf)(GLfloat c); /* 46 */ + void (*Indexfv)(const GLfloat * c); /* 47 */ + void (*Indexi)(GLint c); /* 48 */ + void (*Indexiv)(const GLint * c); /* 49 */ + void (*Indexs)(GLshort c); /* 50 */ + void (*Indexsv)(const GLshort * c); /* 51 */ + void (*Normal3b)(GLbyte nx, GLbyte ny, GLbyte nz); /* 52 */ + void (*Normal3bv)(const GLbyte * v); /* 53 */ + void (*Normal3d)(GLdouble nx, GLdouble ny, GLdouble nz); /* 54 */ + void (*Normal3dv)(const GLdouble * v); /* 55 */ + void (*Normal3f)(GLfloat nx, GLfloat ny, GLfloat nz); /* 56 */ + void (*Normal3fv)(const GLfloat * v); /* 57 */ + void (*Normal3i)(GLint nx, GLint ny, GLint nz); /* 58 */ + void (*Normal3iv)(const GLint * v); /* 59 */ + void (*Normal3s)(GLshort nx, GLshort ny, GLshort nz); /* 60 */ + void (*Normal3sv)(const GLshort * v); /* 61 */ + void (*RasterPos2d)(GLdouble x, GLdouble y); /* 62 */ + void (*RasterPos2dv)(const GLdouble * v); /* 63 */ + void (*RasterPos2f)(GLfloat x, GLfloat y); /* 64 */ + void (*RasterPos2fv)(const GLfloat * v); /* 65 */ + void (*RasterPos2i)(GLint x, GLint y); /* 66 */ + void (*RasterPos2iv)(const GLint * v); /* 67 */ + void (*RasterPos2s)(GLshort x, GLshort y); /* 68 */ + void (*RasterPos2sv)(const GLshort * v); /* 69 */ + void (*RasterPos3d)(GLdouble x, GLdouble y, GLdouble z); /* 70 */ + void (*RasterPos3dv)(const GLdouble * v); /* 71 */ + void (*RasterPos3f)(GLfloat x, GLfloat y, GLfloat z); /* 72 */ + void (*RasterPos3fv)(const GLfloat * v); /* 73 */ + void (*RasterPos3i)(GLint x, GLint y, GLint z); /* 74 */ + void (*RasterPos3iv)(const GLint * v); /* 75 */ + void (*RasterPos3s)(GLshort x, GLshort y, GLshort z); /* 76 */ + void (*RasterPos3sv)(const GLshort * v); /* 77 */ + void (*RasterPos4d)(GLdouble x, GLdouble y, GLdouble z, GLdouble w); /* 78 */ + void (*RasterPos4dv)(const GLdouble * v); /* 79 */ + void (*RasterPos4f)(GLfloat x, GLfloat y, GLfloat z, GLfloat w); /* 80 */ + void (*RasterPos4fv)(const GLfloat * v); /* 81 */ + void (*RasterPos4i)(GLint x, GLint y, GLint z, GLint w); /* 82 */ + void (*RasterPos4iv)(const GLint * v); /* 83 */ + void (*RasterPos4s)(GLshort x, GLshort y, GLshort z, GLshort w); /* 84 */ + void (*RasterPos4sv)(const GLshort * v); /* 85 */ + void (*Rectd)(GLdouble x1, GLdouble y1, GLdouble x2, GLdouble y2); /* 86 */ + void (*Rectdv)(const GLdouble * v1, const GLdouble * v2); /* 87 */ + void (*Rectf)(GLfloat x1, GLfloat y1, GLfloat x2, GLfloat y2); /* 88 */ + void (*Rectfv)(const GLfloat * v1, const GLfloat * v2); /* 89 */ + void (*Recti)(GLint x1, GLint y1, GLint x2, GLint y2); /* 90 */ + void (*Rectiv)(const GLint * v1, const GLint * v2); /* 91 */ + void (*Rects)(GLshort x1, GLshort y1, GLshort x2, GLshort y2); /* 92 */ + void (*Rectsv)(const GLshort * v1, const GLshort * v2); /* 93 */ + void (*TexCoord1d)(GLdouble s); /* 94 */ + void (*TexCoord1dv)(const GLdouble * v); /* 95 */ + void (*TexCoord1f)(GLfloat s); /* 96 */ + void (*TexCoord1fv)(const GLfloat * v); /* 97 */ + void (*TexCoord1i)(GLint s); /* 98 */ + void (*TexCoord1iv)(const GLint * v); /* 99 */ + void (*TexCoord1s)(GLshort s); /* 100 */ + void (*TexCoord1sv)(const GLshort * v); /* 101 */ + void (*TexCoord2d)(GLdouble s, GLdouble t); /* 102 */ + void (*TexCoord2dv)(const GLdouble * v); /* 103 */ + void (*TexCoord2f)(GLfloat s, GLfloat t); /* 104 */ + void (*TexCoord2fv)(const GLfloat * v); /* 105 */ + void (*TexCoord2i)(GLint s, GLint t); /* 106 */ + void (*TexCoord2iv)(const GLint * v); /* 107 */ + void (*TexCoord2s)(GLshort s, GLshort t); /* 108 */ + void (*TexCoord2sv)(const GLshort * v); /* 109 */ + void (*TexCoord3d)(GLdouble s, GLdouble t, GLdouble r); /* 110 */ + void (*TexCoord3dv)(const GLdouble * v); /* 111 */ + void (*TexCoord3f)(GLfloat s, GLfloat t, GLfloat r); /* 112 */ + void (*TexCoord3fv)(const GLfloat * v); /* 113 */ + void (*TexCoord3i)(GLint s, GLint t, GLint r); /* 114 */ + void (*TexCoord3iv)(const GLint * v); /* 115 */ + void (*TexCoord3s)(GLshort s, GLshort t, GLshort r); /* 116 */ + void (*TexCoord3sv)(const GLshort * v); /* 117 */ + void (*TexCoord4d)(GLdouble s, GLdouble t, GLdouble r, GLdouble q); /* 118 */ + void (*TexCoord4dv)(const GLdouble * v); /* 119 */ + void (*TexCoord4f)(GLfloat s, GLfloat t, GLfloat r, GLfloat q); /* 120 */ + void (*TexCoord4fv)(const GLfloat * v); /* 121 */ + void (*TexCoord4i)(GLint s, GLint t, GLint r, GLint q); /* 122 */ + void (*TexCoord4iv)(const GLint * v); /* 123 */ + void (*TexCoord4s)(GLshort s, GLshort t, GLshort r, GLshort q); /* 124 */ + void (*TexCoord4sv)(const GLshort * v); /* 125 */ + void (*Vertex2d)(GLdouble x, GLdouble y); /* 126 */ + void (*Vertex2dv)(const GLdouble * v); /* 127 */ + void (*Vertex2f)(GLfloat x, GLfloat y); /* 128 */ + void (*Vertex2fv)(const GLfloat * v); /* 129 */ + void (*Vertex2i)(GLint x, GLint y); /* 130 */ + void (*Vertex2iv)(const GLint * v); /* 131 */ + void (*Vertex2s)(GLshort x, GLshort y); /* 132 */ + void (*Vertex2sv)(const GLshort * v); /* 133 */ + void (*Vertex3d)(GLdouble x, GLdouble y, GLdouble z); /* 134 */ + void (*Vertex3dv)(const GLdouble * v); /* 135 */ + void (*Vertex3f)(GLfloat x, GLfloat y, GLfloat z); /* 136 */ + void (*Vertex3fv)(const GLfloat * v); /* 137 */ + void (*Vertex3i)(GLint x, GLint y, GLint z); /* 138 */ + void (*Vertex3iv)(const GLint * v); /* 139 */ + void (*Vertex3s)(GLshort x, GLshort y, GLshort z); /* 140 */ + void (*Vertex3sv)(const GLshort * v); /* 141 */ + void (*Vertex4d)(GLdouble x, GLdouble y, GLdouble z, GLdouble w); /* 142 */ + void (*Vertex4dv)(const GLdouble * v); /* 143 */ + void (*Vertex4f)(GLfloat x, GLfloat y, GLfloat z, GLfloat w); /* 144 */ + void (*Vertex4fv)(const GLfloat * v); /* 145 */ + void (*Vertex4i)(GLint x, GLint y, GLint z, GLint w); /* 146 */ + void (*Vertex4iv)(const GLint * v); /* 147 */ + void (*Vertex4s)(GLshort x, GLshort y, GLshort z, GLshort w); /* 148 */ + void (*Vertex4sv)(const GLshort * v); /* 149 */ + void (*ClipPlane)(GLenum plane, const GLdouble * equation); /* 150 */ + void (*ColorMaterial)(GLenum face, GLenum mode); /* 151 */ + void (*CullFace)(GLenum mode); /* 152 */ + void (*Fogf)(GLenum pname, GLfloat param); /* 153 */ + void (*Fogfv)(GLenum pname, const GLfloat * params); /* 154 */ + void (*Fogi)(GLenum pname, GLint param); /* 155 */ + void (*Fogiv)(GLenum pname, const GLint * params); /* 156 */ + void (*FrontFace)(GLenum mode); /* 157 */ + void (*Hint)(GLenum target, GLenum mode); /* 158 */ + void (*Lightf)(GLenum light, GLenum pname, GLfloat param); /* 159 */ + void (*Lightfv)(GLenum light, GLenum pname, const GLfloat * params); /* 160 */ + void (*Lighti)(GLenum light, GLenum pname, GLint param); /* 161 */ + void (*Lightiv)(GLenum light, GLenum pname, const GLint * params); /* 162 */ + void (*LightModelf)(GLenum pname, GLfloat param); /* 163 */ + void (*LightModelfv)(GLenum pname, const GLfloat * params); /* 164 */ + void (*LightModeli)(GLenum pname, GLint param); /* 165 */ + void (*LightModeliv)(GLenum pname, const GLint * params); /* 166 */ + void (*LineStipple)(GLint factor, GLushort pattern); /* 167 */ + void (*LineWidth)(GLfloat width); /* 168 */ + void (*Materialf)(GLenum face, GLenum pname, GLfloat param); /* 169 */ + void (*Materialfv)(GLenum face, GLenum pname, const GLfloat * params); /* 170 */ + void (*Materiali)(GLenum face, GLenum pname, GLint param); /* 171 */ + void (*Materialiv)(GLenum face, GLenum pname, const GLint * params); /* 172 */ + void (*PointSize)(GLfloat size); /* 173 */ + void (*PolygonMode)(GLenum face, GLenum mode); /* 174 */ + void (*PolygonStipple)(const GLubyte * mask); /* 175 */ + void (*Scissor)(GLint x, GLint y, GLsizei width, GLsizei height); /* 176 */ + void (*ShadeModel)(GLenum mode); /* 177 */ + void (*TexParameterf)(GLenum target, GLenum pname, GLfloat param); /* 178 */ + void (*TexParameterfv)(GLenum target, GLenum pname, const GLfloat * params); /* 179 */ + void (*TexParameteri)(GLenum target, GLenum pname, GLint param); /* 180 */ + void (*TexParameteriv)(GLenum target, GLenum pname, const GLint * params); /* 181 */ + void (*TexImage1D)(GLenum target, GLint level, GLint internalformat, GLsizei width, GLint border, GLenum format, GLenum type, const GLvoid * pixels); /* 182 */ + void (*TexImage2D)(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const GLvoid * pixels); /* 183 */ + void (*TexEnvf)(GLenum target, GLenum pname, GLfloat param); /* 184 */ + void (*TexEnvfv)(GLenum target, GLenum pname, const GLfloat * params); /* 185 */ + void (*TexEnvi)(GLenum target, GLenum pname, GLint param); /* 186 */ + void (*TexEnviv)(GLenum target, GLenum pname, const GLint * params); /* 187 */ + void (*TexGend)(GLenum coord, GLenum pname, GLdouble param); /* 188 */ + void (*TexGendv)(GLenum coord, GLenum pname, const GLdouble * params); /* 189 */ + void (*TexGenf)(GLenum coord, GLenum pname, GLfloat param); /* 190 */ + void (*TexGenfv)(GLenum coord, GLenum pname, const GLfloat * params); /* 191 */ + void (*TexGeni)(GLenum coord, GLenum pname, GLint param); /* 192 */ + void (*TexGeniv)(GLenum coord, GLenum pname, const GLint * params); /* 193 */ + void (*FeedbackBuffer)(GLsizei size, GLenum type, GLfloat * buffer); /* 194 */ + void (*SelectBuffer)(GLsizei size, GLuint * buffer); /* 195 */ + GLint (*RenderMode)(GLenum mode); /* 196 */ + void (*InitNames)(void); /* 197 */ + void (*LoadName)(GLuint name); /* 198 */ + void (*PassThrough)(GLfloat token); /* 199 */ + void (*PopName)(void); /* 200 */ + void (*PushName)(GLuint name); /* 201 */ + void (*DrawBuffer)(GLenum mode); /* 202 */ + void (*Clear)(GLbitfield mask); /* 203 */ + void (*ClearAccum)(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha); /* 204 */ + void (*ClearIndex)(GLfloat c); /* 205 */ + void (*ClearColor)(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha); /* 206 */ + void (*ClearStencil)(GLint s); /* 207 */ + void (*ClearDepth)(GLclampd depth); /* 208 */ + void (*StencilMask)(GLuint mask); /* 209 */ + void (*ColorMask)(GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha); /* 210 */ + void (*DepthMask)(GLboolean flag); /* 211 */ + void (*IndexMask)(GLuint mask); /* 212 */ + void (*Accum)(GLenum op, GLfloat value); /* 213 */ + void (*Disable)(GLenum cap); /* 214 */ + void (*Enable)(GLenum cap); /* 215 */ + void (*Finish)(void); /* 216 */ + void (*Flush)(void); /* 217 */ + void (*PopAttrib)(void); /* 218 */ + void (*PushAttrib)(GLbitfield mask); /* 219 */ + void (*Map1d)(GLenum target, GLdouble u1, GLdouble u2, GLint stride, GLint order, const GLdouble * points); /* 220 */ + void (*Map1f)(GLenum target, GLfloat u1, GLfloat u2, GLint stride, GLint order, const GLfloat * points); /* 221 */ + void (*Map2d)(GLenum target, GLdouble u1, GLdouble u2, GLint ustride, GLint uorder, GLdouble v1, GLdouble v2, GLint vstride, GLint vorder, const GLdouble * points); /* 222 */ + void (*Map2f)(GLenum target, GLfloat u1, GLfloat u2, GLint ustride, GLint uorder, GLfloat v1, GLfloat v2, GLint vstride, GLint vorder, const GLfloat * points); /* 223 */ + void (*MapGrid1d)(GLint un, GLdouble u1, GLdouble u2); /* 224 */ + void (*MapGrid1f)(GLint un, GLfloat u1, GLfloat u2); /* 225 */ + void (*MapGrid2d)(GLint un, GLdouble u1, GLdouble u2, GLint vn, GLdouble v1, GLdouble v2); /* 226 */ + void (*MapGrid2f)(GLint un, GLfloat u1, GLfloat u2, GLint vn, GLfloat v1, GLfloat v2); /* 227 */ + void (*EvalCoord1d)(GLdouble u); /* 228 */ + void (*EvalCoord1dv)(const GLdouble * u); /* 229 */ + void (*EvalCoord1f)(GLfloat u); /* 230 */ + void (*EvalCoord1fv)(const GLfloat * u); /* 231 */ + void (*EvalCoord2d)(GLdouble u, GLdouble v); /* 232 */ + void (*EvalCoord2dv)(const GLdouble * u); /* 233 */ + void (*EvalCoord2f)(GLfloat u, GLfloat v); /* 234 */ + void (*EvalCoord2fv)(const GLfloat * u); /* 235 */ + void (*EvalMesh1)(GLenum mode, GLint i1, GLint i2); /* 236 */ + void (*EvalPoint1)(GLint i); /* 237 */ + void (*EvalMesh2)(GLenum mode, GLint i1, GLint i2, GLint j1, GLint j2); /* 238 */ + void (*EvalPoint2)(GLint i, GLint j); /* 239 */ + void (*AlphaFunc)(GLenum func, GLclampf ref); /* 240 */ + void (*BlendFunc)(GLenum sfactor, GLenum dfactor); /* 241 */ + void (*LogicOp)(GLenum opcode); /* 242 */ + void (*StencilFunc)(GLenum func, GLint ref, GLuint mask); /* 243 */ + void (*StencilOp)(GLenum fail, GLenum zfail, GLenum zpass); /* 244 */ + void (*DepthFunc)(GLenum func); /* 245 */ + void (*PixelZoom)(GLfloat xfactor, GLfloat yfactor); /* 246 */ + void (*PixelTransferf)(GLenum pname, GLfloat param); /* 247 */ + void (*PixelTransferi)(GLenum pname, GLint param); /* 248 */ + void (*PixelStoref)(GLenum pname, GLfloat param); /* 249 */ + void (*PixelStorei)(GLenum pname, GLint param); /* 250 */ + void (*PixelMapfv)(GLenum map, GLint mapsize, const GLfloat * values); /* 251 */ + void (*PixelMapuiv)(GLenum map, GLint mapsize, const GLuint * values); /* 252 */ + void (*PixelMapusv)(GLenum map, GLint mapsize, const GLushort * values); /* 253 */ + void (*ReadBuffer)(GLenum mode); /* 254 */ + void (*CopyPixels)(GLint x, GLint y, GLsizei width, GLsizei height, GLenum type); /* 255 */ + void (*ReadPixels)(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLvoid * pixels); /* 256 */ + void (*DrawPixels)(GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid * pixels); /* 257 */ + void (*GetBooleanv)(GLenum pname, GLboolean * params); /* 258 */ + void (*GetClipPlane)(GLenum plane, GLdouble * equation); /* 259 */ + void (*GetDoublev)(GLenum pname, GLdouble * params); /* 260 */ + GLenum (*GetError)(void); /* 261 */ + void (*GetFloatv)(GLenum pname, GLfloat * params); /* 262 */ + void (*GetIntegerv)(GLenum pname, GLint * params); /* 263 */ + void (*GetLightfv)(GLenum light, GLenum pname, GLfloat * params); /* 264 */ + void (*GetLightiv)(GLenum light, GLenum pname, GLint * params); /* 265 */ + void (*GetMapdv)(GLenum target, GLenum query, GLdouble * v); /* 266 */ + void (*GetMapfv)(GLenum target, GLenum query, GLfloat * v); /* 267 */ + void (*GetMapiv)(GLenum target, GLenum query, GLint * v); /* 268 */ + void (*GetMaterialfv)(GLenum face, GLenum pname, GLfloat * params); /* 269 */ + void (*GetMaterialiv)(GLenum face, GLenum pname, GLint * params); /* 270 */ + void (*GetPixelMapfv)(GLenum map, GLfloat * values); /* 271 */ + void (*GetPixelMapuiv)(GLenum map, GLuint * values); /* 272 */ + void (*GetPixelMapusv)(GLenum map, GLushort * values); /* 273 */ + void (*GetPolygonStipple)(GLubyte * mask); /* 274 */ + const GLubyte * (*GetString)(GLenum name); /* 275 */ + void (*GetTexEnvfv)(GLenum target, GLenum pname, GLfloat * params); /* 276 */ + void (*GetTexEnviv)(GLenum target, GLenum pname, GLint * params); /* 277 */ + void (*GetTexGendv)(GLenum coord, GLenum pname, GLdouble * params); /* 278 */ + void (*GetTexGenfv)(GLenum coord, GLenum pname, GLfloat * params); /* 279 */ + void (*GetTexGeniv)(GLenum coord, GLenum pname, GLint * params); /* 280 */ + void (*GetTexImage)(GLenum target, GLint level, GLenum format, GLenum type, GLvoid * pixels); /* 281 */ + void (*GetTexParameterfv)(GLenum target, GLenum pname, GLfloat * params); /* 282 */ + void (*GetTexParameteriv)(GLenum target, GLenum pname, GLint * params); /* 283 */ + void (*GetTexLevelParameterfv)(GLenum target, GLint level, GLenum pname, GLfloat * params); /* 284 */ + void (*GetTexLevelParameteriv)(GLenum target, GLint level, GLenum pname, GLint * params); /* 285 */ + GLboolean (*IsEnabled)(GLenum cap); /* 286 */ + GLboolean (*IsList)(GLuint list); /* 287 */ + void (*DepthRange)(GLclampd near, GLclampd far); /* 288 */ + void (*Frustum)(GLdouble left, GLdouble right, GLdouble bottom, GLdouble top, GLdouble zNear, GLdouble zFar); /* 289 */ + void (*LoadIdentity)(void); /* 290 */ + void (*LoadMatrixf)(const GLfloat * m); /* 291 */ + void (*LoadMatrixd)(const GLdouble * m); /* 292 */ + void (*MatrixMode)(GLenum mode); /* 293 */ + void (*MultMatrixf)(const GLfloat * m); /* 294 */ + void (*MultMatrixd)(const GLdouble * m); /* 295 */ + void (*Ortho)(GLdouble left, GLdouble right, GLdouble bottom, GLdouble top, GLdouble zNear, GLdouble zFar); /* 296 */ + void (*PopMatrix)(void); /* 297 */ + void (*PushMatrix)(void); /* 298 */ + void (*Rotated)(GLdouble angle, GLdouble x, GLdouble y, GLdouble z); /* 299 */ + void (*Rotatef)(GLfloat angle, GLfloat x, GLfloat y, GLfloat z); /* 300 */ + void (*Scaled)(GLdouble x, GLdouble y, GLdouble z); /* 301 */ + void (*Scalef)(GLfloat x, GLfloat y, GLfloat z); /* 302 */ + void (*Translated)(GLdouble x, GLdouble y, GLdouble z); /* 303 */ + void (*Translatef)(GLfloat x, GLfloat y, GLfloat z); /* 304 */ + void (*Viewport)(GLint x, GLint y, GLsizei width, GLsizei height); /* 305 */ + void (*ArrayElement)(GLint i); /* 306 */ + void (*BindTexture)(GLenum target, GLenum texture); /* 307 */ + void (*ColorPointer)(GLint size, GLenum type, GLsizei stride, const GLvoid * pointer); /* 308 */ + void (*DisableClientState)(GLenum array); /* 309 */ + void (*DrawArrays)(GLenum mode, GLint first, GLsizei count); /* 310 */ + void (*DrawElements)(GLenum mode, GLsizei count, GLenum type, const GLvoid * indices); /* 311 */ + void (*EdgeFlagPointer)(GLsizei stride, const GLvoid * pointer); /* 312 */ + void (*EnableClientState)(GLenum array); /* 313 */ + void (*IndexPointer)(GLenum type, GLsizei stride, const GLvoid * pointer); /* 314 */ + void (*Indexub)(GLubyte c); /* 315 */ + void (*Indexubv)(const GLubyte * c); /* 316 */ + void (*InterleavedArrays)(GLenum format, GLsizei stride, const GLvoid * pointer); /* 317 */ + void (*NormalPointer)(GLenum type, GLsizei stride, const GLvoid * pointer); /* 318 */ + void (*PolygonOffset)(GLfloat factor, GLfloat units); /* 319 */ + void (*TexCoordPointer)(GLint size, GLenum type, GLsizei stride, const GLvoid * pointer); /* 320 */ + void (*VertexPointer)(GLint size, GLenum type, GLsizei stride, const GLvoid * pointer); /* 321 */ + GLboolean (*AreTexturesResident)(GLsizei n, const GLenum * textures, GLboolean * residences); /* 322 */ + void (*CopyTexImage1D)(GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLint border); /* 323 */ + void (*CopyTexImage2D)(GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border); /* 324 */ + void (*CopyTexSubImage1D)(GLenum target, GLint level, GLint xoffset, GLint x, GLint y, GLsizei width); /* 325 */ + void (*CopyTexSubImage2D)(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height); /* 326 */ + void (*DeleteTextures)(GLsizei n, const GLenum * textures); /* 327 */ + void (*GenTextures)(GLsizei n, GLenum * textures); /* 328 */ + void (*GetPointerv)(GLenum pname, GLvoid * * params); /* 329 */ + GLboolean (*IsTexture)(GLenum texture); /* 330 */ + void (*PrioritizeTextures)(GLsizei n, const GLenum * textures, const GLclampf * priorities); /* 331 */ + void (*TexSubImage1D)(GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLenum type, const GLvoid * pixels); /* 332 */ + void (*TexSubImage2D)(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid * pixels); /* 333 */ + void (*PopClientAttrib)(void); /* 334 */ + void (*PushClientAttrib)(GLbitfield mask); /* 335 */ + void (*BlendColor)(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha); /* 336 */ + void (*BlendEquation)(GLenum mode); /* 337 */ + void (*DrawRangeElements)(GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const GLvoid * indices); /* 338 */ + void (*ColorTable)(GLenum target, GLenum internalformat, GLsizei width, GLenum format, GLenum type, const GLvoid * table); /* 339 */ + void (*ColorTableParameterfv)(GLenum target, GLenum pname, const GLfloat * params); /* 340 */ + void (*ColorTableParameteriv)(GLenum target, GLenum pname, const GLint * params); /* 341 */ + void (*CopyColorTable)(GLenum target, GLenum internalformat, GLint x, GLint y, GLsizei width); /* 342 */ + void (*GetColorTable)(GLenum target, GLenum format, GLenum type, GLvoid * table); /* 343 */ + void (*GetColorTableParameterfv)(GLenum target, GLenum pname, GLfloat * params); /* 344 */ + void (*GetColorTableParameteriv)(GLenum target, GLenum pname, GLint * params); /* 345 */ + void (*ColorSubTable)(GLenum target, GLsizei start, GLsizei count, GLenum format, GLenum type, const GLvoid * data); /* 346 */ + void (*CopyColorSubTable)(GLenum target, GLsizei start, GLint x, GLint y, GLsizei width); /* 347 */ + void (*ConvolutionFilter1D)(GLenum target, GLenum internalformat, GLsizei width, GLenum format, GLenum type, const GLvoid * image); /* 348 */ + void (*ConvolutionFilter2D)(GLenum target, GLenum internalformat, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid * image); /* 349 */ + void (*ConvolutionParameterf)(GLenum target, GLenum pname, GLfloat params); /* 350 */ + void (*ConvolutionParameterfv)(GLenum target, GLenum pname, const GLfloat * params); /* 351 */ + void (*ConvolutionParameteri)(GLenum target, GLenum pname, GLint params); /* 352 */ + void (*ConvolutionParameteriv)(GLenum target, GLenum pname, const GLint * params); /* 353 */ + void (*CopyConvolutionFilter1D)(GLenum target, GLenum internalformat, GLint x, GLint y, GLsizei width); /* 354 */ + void (*CopyConvolutionFilter2D)(GLenum target, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height); /* 355 */ + void (*GetConvolutionFilter)(GLenum target, GLenum format, GLenum type, GLvoid * image); /* 356 */ + void (*GetConvolutionParameterfv)(GLenum target, GLenum pname, GLfloat * params); /* 357 */ + void (*GetConvolutionParameteriv)(GLenum target, GLenum pname, GLint * params); /* 358 */ + void (*GetSeparableFilter)(GLenum target, GLenum format, GLenum type, GLvoid * row, GLvoid * column, GLvoid * span); /* 359 */ + void (*SeparableFilter2D)(GLenum target, GLenum internalformat, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid * row, const GLvoid * column); /* 360 */ + void (*GetHistogram)(GLenum target, GLboolean reset, GLenum format, GLenum type, GLvoid * values); /* 361 */ + void (*GetHistogramParameterfv)(GLenum target, GLenum pname, GLfloat * params); /* 362 */ + void (*GetHistogramParameteriv)(GLenum target, GLenum pname, GLint * params); /* 363 */ + void (*GetMinmax)(GLenum target, GLboolean reset, GLenum format, GLenum type, GLvoid * values); /* 364 */ + void (*GetMinmaxParameterfv)(GLenum target, GLenum pname, GLfloat * params); /* 365 */ + void (*GetMinmaxParameteriv)(GLenum target, GLenum pname, GLint * params); /* 366 */ + void (*Histogram)(GLenum target, GLsizei width, GLenum internalformat, GLboolean sink); /* 367 */ + void (*Minmax)(GLenum target, GLenum internalformat, GLboolean sink); /* 368 */ + void (*ResetHistogram)(GLenum target); /* 369 */ + void (*ResetMinmax)(GLenum target); /* 370 */ + void (*TexImage3D)(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const GLvoid * pixels); /* 371 */ + void (*TexSubImage3D)(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const GLvoid * pixels); /* 372 */ + void (*CopyTexSubImage3D)(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height); /* 373 */ + void (*ActiveTextureARB)(GLenum texture); /* 374 */ + void (*ClientActiveTextureARB)(GLenum texture); /* 375 */ + void (*MultiTexCoord1dARB)(GLenum target, GLdouble s); /* 376 */ + void (*MultiTexCoord1dvARB)(GLenum target, const GLdouble * v); /* 377 */ + void (*MultiTexCoord1fARB)(GLenum target, GLfloat s); /* 378 */ + void (*MultiTexCoord1fvARB)(GLenum target, const GLfloat * v); /* 379 */ + void (*MultiTexCoord1iARB)(GLenum target, GLint s); /* 380 */ + void (*MultiTexCoord1ivARB)(GLenum target, const GLint * v); /* 381 */ + void (*MultiTexCoord1sARB)(GLenum target, GLshort s); /* 382 */ + void (*MultiTexCoord1svARB)(GLenum target, const GLshort * v); /* 383 */ + void (*MultiTexCoord2dARB)(GLenum target, GLdouble s, GLdouble t); /* 384 */ + void (*MultiTexCoord2dvARB)(GLenum target, const GLdouble * v); /* 385 */ + void (*MultiTexCoord2fARB)(GLenum target, GLfloat s, GLfloat t); /* 386 */ + void (*MultiTexCoord2fvARB)(GLenum target, const GLfloat * v); /* 387 */ + void (*MultiTexCoord2iARB)(GLenum target, GLint s, GLint t); /* 388 */ + void (*MultiTexCoord2ivARB)(GLenum target, const GLint * v); /* 389 */ + void (*MultiTexCoord2sARB)(GLenum target, GLshort s, GLshort t); /* 390 */ + void (*MultiTexCoord2svARB)(GLenum target, const GLshort * v); /* 391 */ + void (*MultiTexCoord3dARB)(GLenum target, GLdouble s, GLdouble t, GLdouble r); /* 392 */ + void (*MultiTexCoord3dvARB)(GLenum target, const GLdouble * v); /* 393 */ + void (*MultiTexCoord3fARB)(GLenum target, GLfloat s, GLfloat t, GLfloat r); /* 394 */ + void (*MultiTexCoord3fvARB)(GLenum target, const GLfloat * v); /* 395 */ + void (*MultiTexCoord3iARB)(GLenum target, GLint s, GLint t, GLint r); /* 396 */ + void (*MultiTexCoord3ivARB)(GLenum target, const GLint * v); /* 397 */ + void (*MultiTexCoord3sARB)(GLenum target, GLshort s, GLshort t, GLshort r); /* 398 */ + void (*MultiTexCoord3svARB)(GLenum target, const GLshort * v); /* 399 */ + void (*MultiTexCoord4dARB)(GLenum target, GLdouble s, GLdouble t, GLdouble r, GLdouble q); /* 400 */ + void (*MultiTexCoord4dvARB)(GLenum target, const GLdouble * v); /* 401 */ + void (*MultiTexCoord4fARB)(GLenum target, GLfloat s, GLfloat t, GLfloat r, GLfloat q); /* 402 */ + void (*MultiTexCoord4fvARB)(GLenum target, const GLfloat * v); /* 403 */ + void (*MultiTexCoord4iARB)(GLenum target, GLint s, GLint t, GLint r, GLint q); /* 404 */ + void (*MultiTexCoord4ivARB)(GLenum target, const GLint * v); /* 405 */ + void (*MultiTexCoord4sARB)(GLenum target, GLshort s, GLshort t, GLshort r, GLshort q); /* 406 */ + void (*MultiTexCoord4svARB)(GLenum target, const GLshort * v); /* 407 */ + void (*LoadTransposeMatrixfARB)(const GLfloat * m); /* 408 */ + void (*LoadTransposeMatrixdARB)(const GLdouble * m); /* 409 */ + void (*MultTransposeMatrixfARB)(const GLfloat * m); /* 410 */ + void (*MultTransposeMatrixdARB)(const GLdouble * m); /* 411 */ + void (*SampleCoverageARB)(GLclampf value, GLboolean invert); /* 412 */ + void (*SamplePassARB)(GLenum pass); /* 413 */ + void (*PolygonOffsetEXT)(GLfloat factor, GLfloat bias); /* 414 */ + void (*GetTexFilterFuncSGIS)(GLenum target, GLenum filter, GLfloat * weights); /* 415 */ + void (*TexFilterFuncSGIS)(GLenum target, GLenum filter, GLsizei n, const GLfloat * weights); /* 416 */ + void (*GetHistogramEXT)(GLenum target, GLboolean reset, GLenum format, GLenum type, GLvoid * values); /* 417 */ + void (*GetHistogramParameterfvEXT)(GLenum target, GLenum pname, GLfloat * params); /* 418 */ + void (*GetHistogramParameterivEXT)(GLenum target, GLenum pname, GLint * params); /* 419 */ + void (*GetMinmaxEXT)(GLenum target, GLboolean reset, GLenum format, GLenum type, GLvoid * values); /* 420 */ + void (*GetMinmaxParameterfvEXT)(GLenum target, GLenum pname, GLfloat * params); /* 421 */ + void (*GetMinmaxParameterivEXT)(GLenum target, GLenum pname, GLint * params); /* 422 */ + void (*GetConvolutionFilterEXT)(GLenum target, GLenum format, GLenum type, GLvoid * image); /* 423 */ + void (*GetConvolutionParameterfvEXT)(GLenum target, GLenum pname, GLfloat * params); /* 424 */ + void (*GetConvolutionParameterivEXT)(GLenum target, GLenum pname, GLint * params); /* 425 */ + void (*GetSeparableFilterEXT)(GLenum target, GLenum format, GLenum type, GLvoid * row, GLvoid * column, GLvoid * span); /* 426 */ + void (*GetColorTableSGI)(GLenum target, GLenum format, GLenum type, GLvoid * table); /* 427 */ + void (*GetColorTableParameterfvSGI)(GLenum target, GLenum pname, GLfloat * params); /* 428 */ + void (*GetColorTableParameterivSGI)(GLenum target, GLenum pname, GLint * params); /* 429 */ + void (*PixelTexGenSGIX)(GLenum mode); /* 430 */ + void (*PixelTexGenParameteriSGIS)(GLenum pname, GLint param); /* 431 */ + void (*PixelTexGenParameterivSGIS)(GLenum pname, const GLint * params); /* 432 */ + void (*PixelTexGenParameterfSGIS)(GLenum pname, GLfloat param); /* 433 */ + void (*PixelTexGenParameterfvSGIS)(GLenum pname, const GLfloat * params); /* 434 */ + void (*GetPixelTexGenParameterivSGIS)(GLenum pname, GLint * params); /* 435 */ + void (*GetPixelTexGenParameterfvSGIS)(GLenum pname, GLfloat * params); /* 436 */ + void (*TexImage4DSGIS)(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLsizei size4d, GLint border, GLenum format, GLenum type, const GLvoid * pixels); /* 437 */ + void (*TexSubImage4DSGIS)(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint woffset, GLsizei width, GLsizei height, GLsizei depth, GLsizei size4d, GLenum format, GLenum type, const GLvoid * pixels); /* 438 */ + GLboolean (*AreTexturesResidentEXT)(GLsizei n, const GLenum * textures, GLboolean * residences); /* 439 */ + void (*GenTexturesEXT)(GLsizei n, GLenum * textures); /* 440 */ + GLboolean (*IsTextureEXT)(GLenum texture); /* 441 */ + void (*DetailTexFuncSGIS)(GLenum target, GLsizei n, const GLfloat * points); /* 442 */ + void (*GetDetailTexFuncSGIS)(GLenum target, GLfloat * points); /* 443 */ + void (*SharpenTexFuncSGIS)(GLenum target, GLsizei n, const GLfloat * points); /* 444 */ + void (*GetSharpenTexFuncSGIS)(GLenum target, GLfloat * points); /* 445 */ + void (*SampleMaskSGIS)(GLclampf value, GLboolean invert); /* 446 */ + void (*SamplePatternSGIS)(GLenum pattern); /* 447 */ + void (*ColorPointerEXT)(GLint size, GLenum type, GLsizei stride, GLsizei count, const GLvoid * pointer); /* 448 */ + void (*EdgeFlagPointerEXT)(GLsizei stride, GLsizei count, const GLboolean * pointer); /* 449 */ + void (*IndexPointerEXT)(GLenum type, GLsizei stride, GLsizei count, const GLvoid * pointer); /* 450 */ + void (*NormalPointerEXT)(GLenum type, GLsizei stride, GLsizei count, const GLvoid * pointer); /* 451 */ + void (*TexCoordPointerEXT)(GLint size, GLenum type, GLsizei stride, GLsizei count, const GLvoid * pointer); /* 452 */ + void (*VertexPointerEXT)(GLint size, GLenum type, GLsizei stride, GLsizei count, const GLvoid * pointer); /* 453 */ + void (*SpriteParameterfSGIX)(GLenum pname, GLfloat param); /* 454 */ + void (*SpriteParameterfvSGIX)(GLenum pname, const GLfloat * params); /* 455 */ + void (*SpriteParameteriSGIX)(GLenum pname, GLint param); /* 456 */ + void (*SpriteParameterivSGIX)(GLenum pname, const GLint * params); /* 457 */ + void (*PointParameterfEXT)(GLenum pname, GLfloat param); /* 458 */ + void (*PointParameterfvEXT)(GLenum pname, const GLfloat * params); /* 459 */ + GLint (*GetInstrumentsSGIX)(void); /* 460 */ + void (*InstrumentsBufferSGIX)(GLsizei size, GLint * buffer); /* 461 */ + GLint (*PollInstrumentsSGIX)(GLint * marker_p); /* 462 */ + void (*ReadInstrumentsSGIX)(GLint marker); /* 463 */ + void (*StartInstrumentsSGIX)(void); /* 464 */ + void (*StopInstrumentsSGIX)(GLint marker); /* 465 */ + void (*FrameZoomSGIX)(GLint factor); /* 466 */ + void (*TagSampleBufferSGIX)(void); /* 467 */ + void (*ReferencePlaneSGIX)(const GLdouble * equation); /* 468 */ + void (*FlushRasterSGIX)(void); /* 469 */ + void (*GetListParameterfvSGIX)(GLuint list, GLenum pname, GLfloat * params); /* 470 */ + void (*GetListParameterivSGIX)(GLuint list, GLenum pname, GLint * params); /* 471 */ + void (*ListParameterfSGIX)(GLuint list, GLenum pname, GLfloat param); /* 472 */ + void (*ListParameterfvSGIX)(GLuint list, GLenum pname, const GLfloat * params); /* 473 */ + void (*ListParameteriSGIX)(GLuint list, GLenum pname, GLint param); /* 474 */ + void (*ListParameterivSGIX)(GLuint list, GLenum pname, const GLint * params); /* 475 */ + void (*FragmentColorMaterialSGIX)(GLenum face, GLenum mode); /* 476 */ + void (*FragmentLightfSGIX)(GLenum light, GLenum pname, GLfloat param); /* 477 */ + void (*FragmentLightfvSGIX)(GLenum light, GLenum pname, const GLfloat * params); /* 478 */ + void (*FragmentLightiSGIX)(GLenum light, GLenum pname, GLint param); /* 479 */ + void (*FragmentLightivSGIX)(GLenum light, GLenum pname, const GLint * params); /* 480 */ + void (*FragmentLightModelfSGIX)(GLenum pname, GLfloat param); /* 481 */ + void (*FragmentLightModelfvSGIX)(GLenum pname, const GLfloat * params); /* 482 */ + void (*FragmentLightModeliSGIX)(GLenum pname, GLint param); /* 483 */ + void (*FragmentLightModelivSGIX)(GLenum pname, const GLint * params); /* 484 */ + void (*FragmentMaterialfSGIX)(GLenum face, GLenum pname, GLfloat param); /* 485 */ + void (*FragmentMaterialfvSGIX)(GLenum face, GLenum pname, const GLfloat * params); /* 486 */ + void (*FragmentMaterialiSGIX)(GLenum face, GLenum pname, GLint param); /* 487 */ + void (*FragmentMaterialivSGIX)(GLenum face, GLenum pname, const GLint * params); /* 488 */ + void (*GetFragmentLightfvSGIX)(GLenum light, GLenum pname, GLfloat * params); /* 489 */ + void (*GetFragmentLightivSGIX)(GLenum light, GLenum pname, GLint * params); /* 490 */ + void (*GetFragmentMaterialfvSGIX)(GLenum face, GLenum pname, GLfloat * params); /* 491 */ + void (*GetFragmentMaterialivSGIX)(GLenum face, GLenum pname, GLint * params); /* 492 */ + void (*LightEnviSGIX)(GLenum pname, GLint param); /* 493 */ + void (*VertexWeightfEXT)(GLfloat weight); /* 494 */ + void (*VertexWeightfvEXT)(const GLfloat * weight); /* 495 */ + void (*VertexWeightPointerEXT)(GLsizei size, GLenum type, GLsizei stride, const GLvoid * pointer); /* 496 */ + void (*FlushVertexArrayRangeNV)(void); /* 497 */ + void (*VertexArrayRangeNV)(GLsizei size, const GLvoid * pointer); /* 498 */ + void (*CombinerParameterfvNV)(GLenum pname, const GLfloat * params); /* 499 */ + void (*CombinerParameterfNV)(GLenum pname, GLfloat param); /* 500 */ + void (*CombinerParameterivNV)(GLenum pname, const GLint * params); /* 501 */ + void (*CombinerParameteriNV)(GLenum pname, GLint param); /* 502 */ + void (*CombinerInputNV)(GLenum stage, GLenum portion, GLenum variable, GLenum input, GLenum mapping, GLenum componentUsage); /* 503 */ + void (*CombinerOutputNV)(GLenum stage, GLenum portion, GLenum abOutput, GLenum cdOutput, GLenum sumOutput, GLenum scale, GLenum bias, GLboolean abDotProduct, GLboolean cdDotProduct, GLboolean muxSum); /* 504 */ + void (*FinalCombinerInputNV)(GLenum variable, GLenum input, GLenum mapping, GLenum componentUsage); /* 505 */ + void (*GetCombinerInputParameterfvNV)(GLenum stage, GLenum portion, GLenum variable, GLenum pname, GLfloat * params); /* 506 */ + void (*GetCombinerInputParameterivNV)(GLenum stage, GLenum portion, GLenum variable, GLenum pname, GLint * params); /* 507 */ + void (*GetCombinerOutputParameterfvNV)(GLenum stage, GLenum portion, GLenum pname, GLfloat * params); /* 508 */ + void (*GetCombinerOutputParameterivNV)(GLenum stage, GLenum portion, GLenum pname, GLint * params); /* 509 */ + void (*GetFinalCombinerInputParameterfvNV)(GLenum variable, GLenum pname, GLfloat * params); /* 510 */ + void (*GetFinalCombinerInputParameterivNV)(GLenum variable, GLenum pname, GLint * params); /* 511 */ + void (*ResizeBuffersMESA)(void); /* 512 */ + void (*WindowPos2dMESA)(GLdouble x, GLdouble y); /* 513 */ + void (*WindowPos2dvMESA)(const GLdouble * v); /* 514 */ + void (*WindowPos2fMESA)(GLfloat x, GLfloat y); /* 515 */ + void (*WindowPos2fvMESA)(const GLfloat * v); /* 516 */ + void (*WindowPos2iMESA)(GLint x, GLint y); /* 517 */ + void (*WindowPos2ivMESA)(const GLint * v); /* 518 */ + void (*WindowPos2sMESA)(GLshort x, GLshort y); /* 519 */ + void (*WindowPos2svMESA)(const GLshort * v); /* 520 */ + void (*WindowPos3dMESA)(GLdouble x, GLdouble y, GLdouble z); /* 521 */ + void (*WindowPos3dvMESA)(const GLdouble * v); /* 522 */ + void (*WindowPos3fMESA)(GLfloat x, GLfloat y, GLfloat z); /* 523 */ + void (*WindowPos3fvMESA)(const GLfloat * v); /* 524 */ + void (*WindowPos3iMESA)(GLint x, GLint y, GLint z); /* 525 */ + void (*WindowPos3ivMESA)(const GLint * v); /* 526 */ + void (*WindowPos3sMESA)(GLshort x, GLshort y, GLshort z); /* 527 */ + void (*WindowPos3svMESA)(const GLshort * v); /* 528 */ + void (*WindowPos4dMESA)(GLdouble x, GLdouble y, GLdouble z, GLdouble w); /* 529 */ + void (*WindowPos4dvMESA)(const GLdouble * v); /* 530 */ + void (*WindowPos4fMESA)(GLfloat x, GLfloat y, GLfloat z, GLfloat w); /* 531 */ + void (*WindowPos4fvMESA)(const GLfloat * v); /* 532 */ + void (*WindowPos4iMESA)(GLint x, GLint y, GLint z, GLint w); /* 533 */ + void (*WindowPos4ivMESA)(const GLint * v); /* 534 */ + void (*WindowPos4sMESA)(GLshort x, GLshort y, GLshort z, GLshort w); /* 535 */ + void (*WindowPos4svMESA)(const GLshort * v); /* 536 */ + void (*BlendFuncSeparateEXT)(GLenum sfactorRGB, GLenum dfactorRGB, GLenum sfactorAlpha, GLenum dfactorAlpha); /* 537 */ + void (*IndexMaterialEXT)(GLenum face, GLenum mode); /* 538 */ + void (*IndexFuncEXT)(GLenum func, GLclampf ref); /* 539 */ + void (*LockArraysEXT)(GLint first, GLsizei count); /* 540 */ + void (*UnlockArraysEXT)(void); /* 541 */ + void (*CullParameterdvEXT)(GLenum pname, GLdouble * params); /* 542 */ + void (*CullParameterfvEXT)(GLenum pname, GLfloat * params); /* 543 */ + void (*HintPGI)(GLenum target, GLint mode); /* 544 */ + void (*FogCoordfEXT)(GLfloat coord); /* 545 */ + void (*FogCoordfvEXT)(const GLfloat * coord); /* 546 */ + void (*FogCoorddEXT)(GLdouble coord); /* 547 */ + void (*FogCoorddvEXT)(const GLdouble * coord); /* 548 */ + void (*FogCoordPointerEXT)(GLenum type, GLsizei stride, const GLvoid * pointer); /* 549 */ + void (*GetColorTableEXT)(GLenum target, GLenum format, GLenum type, GLvoid * data); /* 550 */ + void (*GetColorTableParameterivEXT)(GLenum target, GLenum pname, GLint * params); /* 551 */ + void (*GetColorTableParameterfvEXT)(GLenum target, GLenum pname, GLfloat * params); /* 552 */ + void (*TbufferMask3DFX)(GLuint mask); /* 553 */ + void (*CompressedTexImage3DARB)(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLsizei imageSize, const GLvoid * data); /* 554 */ + void (*CompressedTexImage2DARB)(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const GLvoid * data); /* 555 */ + void (*CompressedTexImage1DARB)(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLint border, GLsizei imageSize, const GLvoid * data); /* 556 */ + void (*CompressedTexSubImage3DARB)(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const GLvoid * data); /* 557 */ + void (*CompressedTexSubImage2DARB)(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const GLvoid * data); /* 558 */ + void (*CompressedTexSubImage1DARB)(GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLsizei imageSize, const GLvoid * data); /* 559 */ + void (*GetCompressedTexImageARB)(GLenum target, GLint level, void * img); /* 560 */ + void (*SecondaryColor3bEXT)(GLbyte red, GLbyte green, GLbyte blue); /* 561 */ + void (*SecondaryColor3bvEXT)(const GLbyte * v); /* 562 */ + void (*SecondaryColor3dEXT)(GLdouble red, GLdouble green, GLdouble blue); /* 563 */ + void (*SecondaryColor3dvEXT)(const GLdouble * v); /* 564 */ + void (*SecondaryColor3fEXT)(GLfloat red, GLfloat green, GLfloat blue); /* 565 */ + void (*SecondaryColor3fvEXT)(const GLfloat * v); /* 566 */ + void (*SecondaryColor3iEXT)(GLint red, GLint green, GLint blue); /* 567 */ + void (*SecondaryColor3ivEXT)(const GLint * v); /* 568 */ + void (*SecondaryColor3sEXT)(GLshort red, GLshort green, GLshort blue); /* 569 */ + void (*SecondaryColor3svEXT)(const GLshort * v); /* 570 */ + void (*SecondaryColor3ubEXT)(GLubyte red, GLubyte green, GLubyte blue); /* 571 */ + void (*SecondaryColor3ubvEXT)(const GLubyte * v); /* 572 */ + void (*SecondaryColor3uiEXT)(GLuint red, GLuint green, GLuint blue); /* 573 */ + void (*SecondaryColor3uivEXT)(const GLuint * v); /* 574 */ + void (*SecondaryColor3usEXT)(GLushort red, GLushort green, GLushort blue); /* 575 */ + void (*SecondaryColor3usvEXT)(const GLushort * v); /* 576 */ + void (*SecondaryColorPointerEXT)(GLint size, GLenum type, GLsizei stride, const GLvoid * pointer); /* 577 */ +}; + +#endif Index: dll/opengl/opengl32/mesa/glapitemp.h =================================================================== --- dll/opengl/opengl32/mesa/glapitemp.h (revision 0) +++ dll/opengl/opengl32/mesa/glapitemp.h (working copy) @@ -0,0 +1,4268 @@ +/* $Id: glapitemp.h,v 1.29 2001/06/05 19:29:41 brianp Exp $ */ + +/* + * Mesa 3-D graphics library + * Version: 3.5 + * + * Copyright (C) 1999-2001 Brian Paul 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 + * BRIAN PAUL 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. + */ + + +/* + * This file is a template which generates the OpenGL API entry point + * functions. It should be included by a .c file which first defines + * the following macros: + * KEYWORD1 - usually nothing, but might be __declspec(dllexport) on Win32 + * KEYWORD2 - usually nothing, but might be __stdcall on Win32 + * NAME(n) - builds the final function name (usually add "gl" prefix) + * DISPATCH(func, args, msg) - code to do dispatch of named function. + * msg is a printf-style debug message. + * RETURN_DISPATCH(func, args, msg) - code to do dispatch with a return value + * + * Here's an example which generates the usual OpenGL functions: + * #define KEYWORD1 + * #define KEYWORD2 + * #define NAME(func) gl##func + * #define DISPATCH(func, args, msg) \ + * struct _glapi_table *dispatch = CurrentDispatch; \ + * (*dispatch->func) args + * #define RETURN DISPATCH(func, args, msg) \ + * struct _glapi_table *dispatch = CurrentDispatch; \ + * return (*dispatch->func) args + * + */ + +#ifndef NO_FUNCTIONS + +#ifndef KEYWORD1 +#define KEYWORD1 +#endif + +#ifndef KEYWORD2 +#define KEYWORD2 +#endif + +#ifndef NAME +#error NAME must be defined +#endif + +#ifndef DISPATCH +#error DISPATCH must be defined +#endif + +#ifndef RETURN_DISPATCH +#error RETURN_DISPATCH must be defined +#endif + + +/* + * XXX + * Most functions need the msg (printf-message) parameter to be finished. + * I.e. replace ";" with the real info. + */ + +/* + * XXX + * Someday this code should be automatically generated from a spec file + * like that used in the SGI OpenGL SI. + */ + + + +/* GL 1.0 */ + +KEYWORD1 void KEYWORD2 NAME(Accum)(GLenum op, GLfloat value) +{ + DISPATCH(Accum, (op, value), (F, "glAccum(0x%x, %g);", op, value)); +} + +KEYWORD1 void KEYWORD2 NAME(AlphaFunc)(GLenum func, GLclampf ref) +{ + DISPATCH(AlphaFunc, (func, ref), (F, "glAlphaFunc(0x%x, %g);", func, ref)); +} + +KEYWORD1 void KEYWORD2 NAME(Bitmap)(GLsizei width, GLsizei height, GLfloat xorig, GLfloat yorig, GLfloat xmove, GLfloat ymove, const GLubyte *bitmap) +{ + DISPATCH(Bitmap, (width, height, xorig, yorig, xmove, ymove, bitmap), (F, "glBitmap(%d %d %g %g %g %g %p;", width, height, xorig, yorig, xmove, ymove, bitmap)); +} + +KEYWORD1 void KEYWORD2 NAME(BlendFunc)(GLenum sfactor, GLenum dfactor) +{ + DISPATCH(BlendFunc, (sfactor, dfactor), (F, "glBlendFunc(0x%x, 0x%x);", sfactor, dfactor)); +} + +KEYWORD1 void KEYWORD2 NAME(Clear)(GLbitfield mask) +{ + DISPATCH(Clear, (mask), (F, "glClear(0x%x);", mask)); +} + +KEYWORD1 void KEYWORD2 NAME(ClearAccum)(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha) +{ + DISPATCH(ClearAccum, (red, green, blue, alpha), (F, "glClearAccum(%g, %g, %g, %g);", red, green, blue, alpha)); +} + +KEYWORD1 void KEYWORD2 NAME(ClearColor)(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha) +{ + DISPATCH(ClearColor, (red, green, blue, alpha), (F, "glClearColor(%g, %g, %g, %g);", red, green, blue, alpha)); +} + +KEYWORD1 void KEYWORD2 NAME(ClearDepth)(GLclampd depth) +{ + DISPATCH(ClearDepth, (depth), (F, "glClearDepth(%g);", depth)); +} + +KEYWORD1 void KEYWORD2 NAME(ClearIndex)(GLfloat c) +{ + DISPATCH(ClearIndex, (c), (F, "glClearIndex(%g);", c)); +} + +KEYWORD1 void KEYWORD2 NAME(ClearStencil)(GLint s) +{ + DISPATCH(ClearStencil, (s), (F, "glClearStencil(%d);", s)); +} + +KEYWORD1 void KEYWORD2 NAME(ClipPlane)(GLenum plane, const GLdouble *equation) +{ + DISPATCH(ClipPlane, (plane, equation), (F, "glClipPlane(%p);", equation)); +} + +KEYWORD1 void KEYWORD2 NAME(ColorMask)(GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha) +{ + DISPATCH(ColorMask, (red, green, blue, alpha), (F, "glColorMask(%d, %d, %d, %d);", red, green, blue, alpha)); +} + +KEYWORD1 void KEYWORD2 NAME(ColorMaterial)(GLenum face, GLenum mode) +{ + DISPATCH(ColorMaterial, (face, mode), (F, "glColorMaterial(0x%x, 0x%x);", face, mode)); +} + +KEYWORD1 void KEYWORD2 NAME(CopyPixels)(GLint x, GLint y, GLsizei width, GLsizei height, GLenum type) +{ + DISPATCH(CopyPixels, (x, y, width, height, type), (F, "glCopyPixels(%d, %d, %d, %d, 0x%x;", x, y, width, height, type)); +} + +KEYWORD1 void KEYWORD2 NAME(CullFace)(GLenum mode) +{ + DISPATCH(CullFace, (mode), (F, "glCullFace(0x%x);", mode)); +} + +KEYWORD1 void KEYWORD2 NAME(DepthFunc)(GLenum func) +{ + DISPATCH(DepthFunc, (func), (F, "glDepthFunc(0x%x);", func)); +} + +KEYWORD1 void KEYWORD2 NAME(DepthMask)(GLboolean flag) +{ + DISPATCH(DepthMask, (flag), (F, "glDepthMask(%d);", flag)); +} + +KEYWORD1 void KEYWORD2 NAME(DepthRange)(GLclampd nearVal, GLclampd farVal) +{ + DISPATCH(DepthRange, (nearVal, farVal), (F, "glDepthRange(%g, %g;", nearVal, farVal)); +} + +KEYWORD1 void KEYWORD2 NAME(DeleteLists)(GLuint list, GLsizei range) +{ + DISPATCH(DeleteLists, (list, range), (F, "glDeleteLists(%u, %d);", list, range)); +} + +KEYWORD1 void KEYWORD2 NAME(Disable)(GLenum cap) +{ + DISPATCH(Disable, (cap), (F, "glDisable(0x%x);", cap)); +} + +KEYWORD1 void KEYWORD2 NAME(DrawBuffer)(GLenum mode) +{ + DISPATCH(DrawBuffer, (mode), (F, "glDrawBuffer(0x%x);", mode)); +} + +KEYWORD1 void KEYWORD2 NAME(DrawElements)(GLenum mode, GLsizei count, GLenum type, const GLvoid *indices) +{ + DISPATCH(DrawElements, (mode, count, type, indices), (F, "glDrawElements(0x%x, %d, 0x%x, %p;", mode, count, type, indices)); +} + +KEYWORD1 void KEYWORD2 NAME(DrawPixels)(GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *pixels) +{ + DISPATCH(DrawPixels, (width, height, format, type, pixels), (F, "glDrawPixels(%d, %d, 0x%x, 0x%x, %p);", width, height, format, type, pixels)); +} + +KEYWORD1 void KEYWORD2 NAME(Enable)(GLenum cap) +{ + DISPATCH(Enable, (cap), (F, "glEnable(0x%x);", cap)); +} + +KEYWORD1 void KEYWORD2 NAME(EndList)(void) +{ + DISPATCH(EndList, (), (F, "glEndList();")); +} + +KEYWORD1 void KEYWORD2 NAME(EvalMesh1)(GLenum mode, GLint i1, GLint i2) +{ + DISPATCH(EvalMesh1, (mode, i1, i2), (F, "glEvalMesh(0x%x, %d, %d);", mode, i1, i2)); +} + +KEYWORD1 void KEYWORD2 NAME(EvalMesh2)(GLenum mode, GLint i1, GLint i2, GLint j1, GLint j2) +{ + DISPATCH(EvalMesh2, (mode, i1, i2, j1, j2), (F, "glEvalMesh2(0x%x, %d, %d, %d, %d);", mode, i1, i2, j1, j2)); +} + +KEYWORD1 void KEYWORD2 NAME(FeedbackBuffer)(GLsizei size, GLenum type, GLfloat *buffer) +{ + DISPATCH(FeedbackBuffer, (size, type, buffer), (F, "glFeedbackBuffer(%d, 0x%x, %p);", size, type, buffer)); +} + +KEYWORD1 void KEYWORD2 NAME(Finish)(void) +{ + DISPATCH(Finish, (), (F, "glFinish();")); +} + +KEYWORD1 void KEYWORD2 NAME(Flush)(void) +{ + DISPATCH(Flush, (), (F, "glFlush();")); +} + +KEYWORD1 void KEYWORD2 NAME(Fogf)(GLenum pname, GLfloat param) +{ + DISPATCH(Fogf, (pname, param), (F, "glFogf(0x%x, %g);", pname, param)); +} + +KEYWORD1 void KEYWORD2 NAME(Fogi)(GLenum pname, GLint param) +{ + DISPATCH(Fogi, (pname, param), (F, "glFogi(0x%x, %d);", pname, param)); +} + +KEYWORD1 void KEYWORD2 NAME(Fogfv)(GLenum pname, const GLfloat *params) +{ + DISPATCH(Fogfv, (pname, params), (F, "glFogfv(0x%x, %p);", pname, params)); +} + +KEYWORD1 void KEYWORD2 NAME(Fogiv)(GLenum pname, const GLint *params) +{ + DISPATCH(Fogiv, (pname, params), (F, "glFogiv(0x%x, %p);", pname, params)); +} + +KEYWORD1 void KEYWORD2 NAME(FrontFace)(GLenum mode) +{ + DISPATCH(FrontFace, (mode), (F, "glFrontFace(0x%x);", mode)); +} + +KEYWORD1 void KEYWORD2 NAME(Frustum)(GLdouble left, GLdouble right, GLdouble bottom, GLdouble top, GLdouble nearval, GLdouble farval) +{ + DISPATCH(Frustum, (left, right, bottom, top, nearval, farval), (F, "glFrustum(%f, %f, %f, %f, %f, %f);", left, right, bottom, top, nearval, farval)); +} + +KEYWORD1 GLuint KEYWORD2 NAME(GenLists)(GLsizei range) +{ + RETURN_DISPATCH(GenLists, (range), (F, "glGenLists(%d);", range)); +} + +KEYWORD1 void KEYWORD2 NAME(GetBooleanv)(GLenum pname, GLboolean *params) +{ + DISPATCH(GetBooleanv, (pname, params), (F, "glGetBooleanv(0x%x, %p);", pname, params)); +} + +KEYWORD1 void KEYWORD2 NAME(GetClipPlane)(GLenum plane, GLdouble *equation) +{ + DISPATCH(GetClipPlane, (plane, equation), (F, "glGetClipPlane(x0%x, %p);", plane, equation)); +} + +KEYWORD1 void KEYWORD2 NAME(GetDoublev)(GLenum pname, GLdouble *params) +{ + DISPATCH(GetDoublev, (pname, params), (F, "glGetDoublev(0x%x, %p);", pname, params)); +} + +KEYWORD1 GLenum KEYWORD2 NAME(GetError)(void) +{ + RETURN_DISPATCH(GetError, (), (F, "glGetError();")); +} + +KEYWORD1 void KEYWORD2 NAME(GetFloatv)(GLenum pname, GLfloat *params) +{ + DISPATCH(GetFloatv, (pname, params), (F, "glGetFloatv(0x%x, %p);", pname, params)); +} + +KEYWORD1 void KEYWORD2 NAME(GetIntegerv)(GLenum pname, GLint *params) +{ + DISPATCH(GetIntegerv, (pname, params), (F, "glGetIntegerv(0x%x, %p);", pname, params)); +} + +KEYWORD1 void KEYWORD2 NAME(GetLightfv)(GLenum light, GLenum pname, GLfloat *params) +{ + DISPATCH(GetLightfv, (light, pname, params), (F, "glGetLightfv(0x%x, 0x%x, %p);", light, pname, params)); +} + +KEYWORD1 void KEYWORD2 NAME(GetLightiv)(GLenum light, GLenum pname, GLint *params) +{ + DISPATCH(GetLightiv, (light, pname, params), (F, "glGetLightiv(0x%x, 0x%x, %p);", light, pname, params)); +} + +KEYWORD1 void KEYWORD2 NAME(GetMapdv)(GLenum target, GLenum query, GLdouble *v) +{ + DISPATCH(GetMapdv, (target, query, v), (F, "glGetMapdv(0x%x, 0x%x, %p);", target, query, v)); +} + +KEYWORD1 void KEYWORD2 NAME(GetMapfv)(GLenum target, GLenum query, GLfloat *v) +{ + DISPATCH(GetMapfv, (target, query, v), (F, "glGetMapfv(0x%x, 0x%x, %p);", target, query, v)); +} + +KEYWORD1 void KEYWORD2 NAME(GetMapiv)(GLenum target, GLenum query, GLint *v) +{ + DISPATCH(GetMapiv, (target, query, v), (F, "glGetMapiv(0x%x, 0x%x, %p);", target, query, v)); +} + +KEYWORD1 void KEYWORD2 NAME(GetMaterialfv)(GLenum face, GLenum pname, GLfloat *params) +{ + DISPATCH(GetMaterialfv, (face, pname, params), (F, "glGetMaterialfv(0x%x, 0x%x, %p;", face, pname, params)); +} + +KEYWORD1 void KEYWORD2 NAME(GetMaterialiv)(GLenum face, GLenum pname, GLint *params) +{ + DISPATCH(GetMaterialiv, (face, pname, params), (F, "glGetMaterialiv(0x%x, 0x%x, %p);", face, pname, params)); +} + +KEYWORD1 void KEYWORD2 NAME(GetPixelMapfv)(GLenum map, GLfloat *values) +{ + DISPATCH(GetPixelMapfv, (map, values), (F, "glGetPixelMapfv(0x%x, %p);", map, values)); +} + +KEYWORD1 void KEYWORD2 NAME(GetPixelMapuiv)(GLenum map, GLuint *values) +{ + DISPATCH(GetPixelMapuiv, (map, values), (F, "glGetPixelMapuiv(0x%x, %p);", map, values)); +} + +KEYWORD1 void KEYWORD2 NAME(GetPixelMapusv)(GLenum map, GLushort *values) +{ + DISPATCH(GetPixelMapusv, (map, values), (F, "glGetPixelMapusv(0x%x, %p);", map, values)); +} + +KEYWORD1 void KEYWORD2 NAME(GetPolygonStipple)(GLubyte *mask) +{ + DISPATCH(GetPolygonStipple, (mask), (F, "glGetPolygonStipple(%p);", mask)); +} + +KEYWORD1 const GLubyte * KEYWORD2 NAME(GetString)(GLenum name) +{ + RETURN_DISPATCH(GetString, (name), (F, "glGetString(0x%x);", name)); +} + +KEYWORD1 void KEYWORD2 NAME(GetTexEnvfv)(GLenum target, GLenum pname, GLfloat *params) +{ + DISPATCH(GetTexEnvfv, (target, pname, params), (F, "glGettexEnvfv(0x%x, 0x%x, %p);", target, pname, params)); +} + +KEYWORD1 void KEYWORD2 NAME(GetTexEnviv)(GLenum target, GLenum pname, GLint *params) +{ + DISPATCH(GetTexEnviv, (target, pname, params), (F, "glGetTexEnviv(0x%x, 0x%x, %p);", target, pname, params)); +} + +KEYWORD1 void KEYWORD2 NAME(GetTexGeniv)(GLenum target, GLenum pname, GLint *params) +{ + DISPATCH(GetTexGeniv, (target, pname, params), (F, "glGetTexGeniv(0x%x, 0x%x, %p);", target, pname, params)); +} + +KEYWORD1 void KEYWORD2 NAME(GetTexGendv)(GLenum target, GLenum pname, GLdouble *params) +{ + DISPATCH(GetTexGendv, (target, pname, params), (F, "glGetTexGendv(0x%x, 0x%x, %p;", target, pname, params)); +} + +KEYWORD1 void KEYWORD2 NAME(GetTexGenfv)(GLenum target, GLenum pname, GLfloat *params) +{ + DISPATCH(GetTexGenfv, (target, pname, params), (F, "glGetTexGenfv(0x%x, 0x%x, %p);", target, pname, params)); +} + +KEYWORD1 void KEYWORD2 NAME(GetTexImage)(GLenum target, GLint level, GLenum format, GLenum type, GLvoid *pixels) +{ + DISPATCH(GetTexImage, (target, level, format, type, pixels), (F, "glGetTexImage(0x%x, %d, 0x%x, 0x%x, %p);", target, level, format, type, pixels)); +} + +KEYWORD1 void KEYWORD2 NAME(GetTexLevelParameterfv)(GLenum target, GLint level, GLenum pname, GLfloat *params) +{ + DISPATCH(GetTexLevelParameterfv, (target, level, pname, params), (F, "glGetTexLevelParameterfv(0x%x, %d, 0x%x, %p);", target, level, pname, params)); +} + +KEYWORD1 void KEYWORD2 NAME(GetTexLevelParameteriv)(GLenum target, GLint level, GLenum pname, GLint *params) +{ + DISPATCH(GetTexLevelParameteriv, (target, level, pname, params), (F, "glGetTexLevelParameteriv(0x%x, %d, 0x%x, %p);", target, level, pname, params)); +} + +KEYWORD1 void KEYWORD2 NAME(GetTexParameterfv)(GLenum target, GLenum pname, GLfloat *params) +{ + DISPATCH(GetTexParameterfv, (target, pname, params), (F, "glGetTexParameterfv(0x%x, 0x%x, %p);", target, pname, params)); +} + +KEYWORD1 void KEYWORD2 NAME(GetTexParameteriv)(GLenum target, GLenum pname, GLint *params) +{ + DISPATCH(GetTexParameteriv, (target, pname, params), (F, "glGetTexParameteriv(0x%x, 0x%x, %p);", target, pname, params)); +} + +KEYWORD1 void KEYWORD2 NAME(Hint)(GLenum target, GLenum mode) +{ + DISPATCH(Hint, (target, mode), (F, "glHint(0x%x, 0x%x);", target, mode)); +} + +KEYWORD1 void KEYWORD2 NAME(IndexMask)(GLuint mask) +{ + DISPATCH(IndexMask, (mask), (F, "glIndexMask(%u);", mask)); +} + +KEYWORD1 void KEYWORD2 NAME(InitNames)(void) +{ + DISPATCH(InitNames, (), (F, "glInitNames();")); +} + +KEYWORD1 GLboolean KEYWORD2 NAME(IsEnabled)(GLenum cap) +{ + RETURN_DISPATCH(IsEnabled, (cap), (F, "glIsEnabled(0x%x);", cap)); +} + +KEYWORD1 GLboolean KEYWORD2 NAME(IsList)(GLuint list) +{ + RETURN_DISPATCH(IsList, (list), (F, "glIsList(%u);", list)); +} + +KEYWORD1 void KEYWORD2 NAME(Lightf)(GLenum light, GLenum pname, GLfloat param) +{ + DISPATCH(Lightf, (light, pname, param), (F, "glLightfv(0x%x, 0x%x, %g);", light, pname, param)); +} + +KEYWORD1 void KEYWORD2 NAME(Lighti)(GLenum light, GLenum pname, GLint param) +{ + DISPATCH(Lighti, (light, pname, param), (F, "glLighti(0x%x, 0x%x, %d);", light, pname, param)); +} + +KEYWORD1 void KEYWORD2 NAME(Lightfv)(GLenum light, GLenum pname, const GLfloat *params) +{ + DISPATCH(Lightfv, (light, pname, params), (F, "glLightfv(0x%x, 0x%x, %p);", light, pname, params)); +} + +KEYWORD1 void KEYWORD2 NAME(Lightiv)(GLenum light, GLenum pname, const GLint *params) +{ + DISPATCH(Lightiv, (light, pname, params), (F, "glLightiv(0x%x, 0x%x, %p);", light, pname, params)); +} + +KEYWORD1 void KEYWORD2 NAME(LightModelf)(GLenum pname, GLfloat param) +{ + DISPATCH(LightModelf, (pname, param), (F, "glLightModelf(0x%x, %f);", pname, param)); +} + +KEYWORD1 void KEYWORD2 NAME(LightModeli)(GLenum pname, GLint param) +{ + DISPATCH(LightModeli, (pname, param), (F, "glLightModeli(0x%x, %d);", pname, param)); +} + +KEYWORD1 void KEYWORD2 NAME(LightModelfv)(GLenum pname, const GLfloat *params) +{ + DISPATCH(LightModelfv, (pname, params), (F, "glLightModelfv(0x%x, %p);", pname, params)); +} + +KEYWORD1 void KEYWORD2 NAME(LightModeliv)(GLenum pname, const GLint *params) +{ + DISPATCH(LightModeliv, (pname, params), (F, "glLightModeliv(0x%x, %p);", pname, params)); +} + +KEYWORD1 void KEYWORD2 NAME(LineWidth)(GLfloat width) +{ + DISPATCH(LineWidth, (width), (F, "glLineWidth(%g);", width)); +} + +KEYWORD1 void KEYWORD2 NAME(LineStipple)(GLint factor, GLushort pattern) +{ + DISPATCH(LineStipple, (factor, pattern), (F, "glLineStipple(%d, 0x%x);", factor, pattern)); +} + +KEYWORD1 void KEYWORD2 NAME(ListBase)(GLuint base) +{ + DISPATCH(ListBase, (base), (F, "glListbase(%d);", base)); +} + +KEYWORD1 void KEYWORD2 NAME(LoadIdentity)(void) +{ + DISPATCH(LoadIdentity, (), (F, "glLoadIdentity();")); +} + +KEYWORD1 void KEYWORD2 NAME(LoadMatrixd)(const GLdouble *m) +{ + DISPATCH(LoadMatrixd, (m), (F, "glLoadMatirxd(%p);", m)); +} + +KEYWORD1 void KEYWORD2 NAME(LoadMatrixf)(const GLfloat *m) +{ + DISPATCH(LoadMatrixf, (m), (F, "glLoadMatrixf(%p);", m)); +} + +KEYWORD1 void KEYWORD2 NAME(LoadName)(GLuint name) +{ + DISPATCH(LoadName, (name), (F, "glLoadName(%u);", name)); +} + +KEYWORD1 void KEYWORD2 NAME(LogicOp)(GLenum opcode) +{ + DISPATCH(LogicOp, (opcode), (F, "glLogicOp(0x%x);", opcode)); +} + +KEYWORD1 void KEYWORD2 NAME(Map1d)(GLenum target, GLdouble u1, GLdouble u2, GLint stride, GLint order, const GLdouble *points) +{ + DISPATCH(Map1d, (target, u1, u2, stride, order, points), (F, ";")); +} + +KEYWORD1 void KEYWORD2 NAME(Map1f)(GLenum target, GLfloat u1, GLfloat u2, GLint stride, GLint order, const GLfloat *points) +{ + DISPATCH(Map1f, (target, u1, u2, stride, order, points), (F, ";")); +} + +KEYWORD1 void KEYWORD2 NAME(Map2d)(GLenum target, GLdouble u1, GLdouble u2, GLint ustride, GLint uorder, GLdouble v1, GLdouble v2, GLint vstride, GLint vorder, const GLdouble *points) +{ + DISPATCH(Map2d, (target, u1, u2, ustride, uorder, v1, v2, vstride, vorder, points), (F, ";")); +} + +KEYWORD1 void KEYWORD2 NAME(Map2f)(GLenum target, GLfloat u1, GLfloat u2, GLint ustride, GLint uorder, GLfloat v1, GLfloat v2, GLint vstride, GLint vorder, const GLfloat *points) +{ + DISPATCH(Map2f, (target, u1, u2, ustride, uorder, v1, v2, vstride, vorder, points), (F, ";")); +} + +KEYWORD1 void KEYWORD2 NAME(MapGrid1d)(GLint un, GLdouble u1, GLdouble u2) +{ + DISPATCH(MapGrid1d, (un, u1, u2), (F, ";")); +} + +KEYWORD1 void KEYWORD2 NAME(MapGrid1f)(GLint un, GLfloat u1, GLfloat u2) +{ + DISPATCH(MapGrid1f, (un, u1, u2), (F, ";")); +} + +KEYWORD1 void KEYWORD2 NAME(MapGrid2d)(GLint un, GLdouble u1, GLdouble u2, GLint vn, GLdouble v1, GLdouble v2) +{ + DISPATCH(MapGrid2d, (un, u1, u2, vn, v1, v2), (F, ";")); +} + +KEYWORD1 void KEYWORD2 NAME(MapGrid2f)(GLint un, GLfloat u1, GLfloat u2, GLint vn, GLfloat v1, GLfloat v2) +{ + DISPATCH(MapGrid2f, (un, u1, u2, vn, v1, v2), (F, ";")); +} + +KEYWORD1 void KEYWORD2 NAME(MatrixMode)(GLenum mode) +{ + DISPATCH(MatrixMode, (mode), (F, "glMatrixMode(0x%x);", mode)); +} + +KEYWORD1 void KEYWORD2 NAME(MultMatrixd)(const GLdouble *m) +{ + DISPATCH(MultMatrixd, (m), (F, "glMultMatrixd(%p);", m)); +} + +KEYWORD1 void KEYWORD2 NAME(MultMatrixf)(const GLfloat *m) +{ + DISPATCH(MultMatrixf, (m), (F, "glMultMatrixf(%p);", m)); +} + +KEYWORD1 void KEYWORD2 NAME(NewList)(GLuint list, GLenum mode) +{ + DISPATCH(NewList, (list, mode), (F, ";")); +} + +KEYWORD1 void KEYWORD2 NAME(Ortho)(GLdouble left, GLdouble right, GLdouble bottom, GLdouble top, GLdouble nearval, GLdouble farval) +{ + DISPATCH(Ortho, (left, right, bottom, top, nearval, farval), (F, "glOrtho(%f, %f, %f, %f, %f, %f);", left, right, bottom, top, nearval, farval)); +} + +KEYWORD1 void KEYWORD2 NAME(PassThrough)(GLfloat token) +{ + DISPATCH(PassThrough, (token), (F, "glPassThrough(%f);", token)); +} + +KEYWORD1 void KEYWORD2 NAME(PixelMapfv)(GLenum map, GLint mapsize, const GLfloat *values) +{ + DISPATCH(PixelMapfv, (map, mapsize, values), (F, ";")); +} + +KEYWORD1 void KEYWORD2 NAME(PixelMapuiv)(GLenum map, GLint mapsize, const GLuint *values) +{ + DISPATCH(PixelMapuiv, (map, mapsize, values), (F, ";")); +} + +KEYWORD1 void KEYWORD2 NAME(PixelMapusv)(GLenum map, GLint mapsize, const GLushort *values) +{ + DISPATCH(PixelMapusv, (map, mapsize, values), (F, ";")); +} + +KEYWORD1 void KEYWORD2 NAME(PixelStoref)(GLenum pname, GLfloat param) +{ + DISPATCH(PixelStoref, (pname, param), (F, "glPixelStoref(0x%x, %f);", pname, param)); +} + +KEYWORD1 void KEYWORD2 NAME(PixelStorei)(GLenum pname, GLint param) +{ + DISPATCH(PixelStorei, (pname, param), (F, "glPixelStorei(0x%x, %d);", pname, param)); +} + +KEYWORD1 void KEYWORD2 NAME(PixelTransferf)(GLenum pname, GLfloat param) +{ + DISPATCH(PixelTransferf, (pname, param), (F, "glPixelTransferf(0x%x, %f);", pname, param)); +} + +KEYWORD1 void KEYWORD2 NAME(PixelTransferi)(GLenum pname, GLint param) +{ + DISPATCH(PixelTransferi, (pname, param), (F, "glPixelTransferi(0x%x, %d);", pname, param)); +} + +KEYWORD1 void KEYWORD2 NAME(PixelZoom)(GLfloat xfactor, GLfloat yfactor) +{ + DISPATCH(PixelZoom, (xfactor, yfactor), (F, "glPixelZoom(%f, %f);", xfactor, yfactor)); +} + +KEYWORD1 void KEYWORD2 NAME(PointSize)(GLfloat size) +{ + DISPATCH(PointSize, (size), (F, "glPointSize(%f);", size)); +} + +KEYWORD1 void KEYWORD2 NAME(PolygonMode)(GLenum face, GLenum mode) +{ + DISPATCH(PolygonMode, (face, mode), (F, "glPolygonMode(0x%x, 0x%x);", face, mode)); +} + +KEYWORD1 void KEYWORD2 NAME(PolygonStipple)(const GLubyte *pattern) +{ + DISPATCH(PolygonStipple, (pattern), (F, "glPolygonStipple(%p);", pattern)); +} + +KEYWORD1 void KEYWORD2 NAME(PopAttrib)(void) +{ + DISPATCH(PopAttrib, (), (F, "glPopAttrib();")); +} + +KEYWORD1 void KEYWORD2 NAME(PopMatrix)(void) +{ + DISPATCH(PopMatrix, (), (F, "glPopMatrix();")); +} + +KEYWORD1 void KEYWORD2 NAME(PopName)(void) +{ + DISPATCH(PopName, (), (F, "glPopName();")); +} + +KEYWORD1 void KEYWORD2 NAME(PushAttrib)(GLbitfield mask) +{ + DISPATCH(PushAttrib, (mask), (F, "glPushAttrib(0x%x)", mask)); +} + +KEYWORD1 void KEYWORD2 NAME(PushMatrix)(void) +{ + DISPATCH(PushMatrix, (), (F, "glPushMatrix();")); +} + +KEYWORD1 void KEYWORD2 NAME(PushName)(GLuint name) +{ + DISPATCH(PushName, (name), (F, "glPushName(%u)", name)); +} + +KEYWORD1 void KEYWORD2 NAME(RasterPos2d)(GLdouble x, GLdouble y) +{ + DISPATCH(RasterPos2d, (x, y), (F, "glRasterPos2d(%g, %g);", x, y)); +} + +KEYWORD1 void KEYWORD2 NAME(RasterPos2f)(GLfloat x, GLfloat y) +{ + DISPATCH(RasterPos2f, (x, y), (F, "glRasterPos2f(%g, %g);", x, y)); +} + +KEYWORD1 void KEYWORD2 NAME(RasterPos2i)(GLint x, GLint y) +{ + DISPATCH(RasterPos2i, (x, y), (F, "glRasterPos2i(%d, %d);", x, y)); +} + +KEYWORD1 void KEYWORD2 NAME(RasterPos2s)(GLshort x, GLshort y) +{ + DISPATCH(RasterPos2s, (x, y), (F, "glRasterPos2s(%d, %d);", x, y)); +} + +KEYWORD1 void KEYWORD2 NAME(RasterPos3d)(GLdouble x, GLdouble y, GLdouble z) +{ + DISPATCH(RasterPos3d, (x, y, z), (F, "glRasterPos3d(%g, %g, %g);", x, y, z)); +} + +KEYWORD1 void KEYWORD2 NAME(RasterPos3f)(GLfloat x, GLfloat y, GLfloat z) +{ + DISPATCH(RasterPos3f, (x, y, z), (F, "glRasterPos3f(%g, %g, %g);", x, y, z)); +} + +KEYWORD1 void KEYWORD2 NAME(RasterPos3i)(GLint x, GLint y, GLint z) +{ + DISPATCH(RasterPos3i, (x, y, z), (F, "glRasterPos3i(%d, %d, %d);", x, y, z)); +} + +KEYWORD1 void KEYWORD2 NAME(RasterPos3s)(GLshort x, GLshort y, GLshort z) +{ + DISPATCH(RasterPos3s, (x, y, z), (F, "glRasterPos3s(%d, %d, %d);", x, y, z)); +} + +KEYWORD1 void KEYWORD2 NAME(RasterPos4d)(GLdouble x, GLdouble y, GLdouble z, GLdouble w) +{ + DISPATCH(RasterPos4d, (x, y, z, w), (F, "glRasterPos4d(%g, %g, %g, %g);", x, y, z, w)); +} + +KEYWORD1 void KEYWORD2 NAME(RasterPos4f)(GLfloat x, GLfloat y, GLfloat z, GLfloat w) +{ + DISPATCH(RasterPos4f, (x, y, z, w), (F, "glRasterPos4f(%g, %g, %g, %g);", x, y, z, w)); +} + +KEYWORD1 void KEYWORD2 NAME(RasterPos4i)(GLint x, GLint y, GLint z, GLint w) +{ + DISPATCH(RasterPos4i, (x, y, z, w), (F, "glRasterPos4i(%d, %d, %d, %d);", x, y, z, w)); +} + +KEYWORD1 void KEYWORD2 NAME(RasterPos4s)(GLshort x, GLshort y, GLshort z, GLshort w) +{ + DISPATCH(RasterPos4s, (x, y, z, w), (F, "glRasterPos4s(%d, %d, %d, %d);", x, y, z, w)); +} + +KEYWORD1 void KEYWORD2 NAME(RasterPos2dv)(const GLdouble *v) +{ + DISPATCH(RasterPos2dv, (v), (F, ";")); +} + +KEYWORD1 void KEYWORD2 NAME(RasterPos2fv)(const GLfloat *v) +{ + DISPATCH(RasterPos2fv, (v), (F, ";")); +} + +KEYWORD1 void KEYWORD2 NAME(RasterPos2iv)(const GLint *v) +{ + DISPATCH(RasterPos2iv, (v), (F, ";")); +} + +KEYWORD1 void KEYWORD2 NAME(RasterPos2sv)(const GLshort *v) +{ + DISPATCH(RasterPos2sv, (v), (F, ";")); +} + +KEYWORD1 void KEYWORD2 NAME(RasterPos3dv)(const GLdouble *v) +{ + DISPATCH(RasterPos3dv, (v), (F, ";")); +} + +KEYWORD1 void KEYWORD2 NAME(RasterPos3fv)(const GLfloat *v) +{ + DISPATCH(RasterPos3fv, (v), (F, ";")); +} + +KEYWORD1 void KEYWORD2 NAME(RasterPos3iv)(const GLint *v) +{ + DISPATCH(RasterPos3iv, (v), (F, ";")); +} + +KEYWORD1 void KEYWORD2 NAME(RasterPos3sv)(const GLshort *v) +{ + DISPATCH(RasterPos3sv, (v), (F, ";")); +} + +KEYWORD1 void KEYWORD2 NAME(RasterPos4dv)(const GLdouble *v) +{ + DISPATCH(RasterPos4dv, (v), (F, ";")); +} + +KEYWORD1 void KEYWORD2 NAME(RasterPos4fv)(const GLfloat *v) +{ + DISPATCH(RasterPos4fv, (v), (F, ";")); +} + +KEYWORD1 void KEYWORD2 NAME(RasterPos4iv)(const GLint *v) +{ + DISPATCH(RasterPos4iv, (v), (F, ";")); +} + +KEYWORD1 void KEYWORD2 NAME(RasterPos4sv)(const GLshort *v) +{ + DISPATCH(RasterPos4sv, (v), (F, ";")); +} + +KEYWORD1 void KEYWORD2 NAME(ReadBuffer)(GLenum mode) +{ + DISPATCH(ReadBuffer, (mode), (F, ";")); +} + +KEYWORD1 void KEYWORD2 NAME(ReadPixels)(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLvoid *pixels) +{ + DISPATCH(ReadPixels, (x, y, width, height, format, type, pixels), (F, ";")); +} + +KEYWORD1 void KEYWORD2 NAME(Rectd)(GLdouble x1, GLdouble y1, GLdouble x2, GLdouble y2) +{ + DISPATCH(Rectd, (x1, y1, x2, y2), (F, ";")); +} + +KEYWORD1 void KEYWORD2 NAME(Rectdv)(const GLdouble *v1, const GLdouble *v2) +{ + DISPATCH(Rectdv, (v1, v2), (F, ";")); +} + +KEYWORD1 void KEYWORD2 NAME(Rectf)(GLfloat x1, GLfloat y1, GLfloat x2, GLfloat y2) +{ + DISPATCH(Rectf, (x1, y1, x2, y2), (F, ";")); +} + +KEYWORD1 void KEYWORD2 NAME(Rectfv)(const GLfloat *v1, const GLfloat *v2) +{ + DISPATCH(Rectfv, (v1, v2), (F, ";")); +} + +KEYWORD1 void KEYWORD2 NAME(Recti)(GLint x1, GLint y1, GLint x2, GLint y2) +{ + DISPATCH(Recti, (x1, y1, x2, y2), (F, ";")); +} + +KEYWORD1 void KEYWORD2 NAME(Rectiv)(const GLint *v1, const GLint *v2) +{ + DISPATCH(Rectiv, (v1, v2), (F, ";")); +} + +KEYWORD1 void KEYWORD2 NAME(Rects)(GLshort x1, GLshort y1, GLshort x2, GLshort y2) +{ + DISPATCH(Rects, (x1, y1, x2, y2), (F, ";")); +} + +KEYWORD1 void KEYWORD2 NAME(Rectsv)(const GLshort *v1, const GLshort *v2) +{ + DISPATCH(Rectsv, (v1, v2), (F, ";")); +} + +KEYWORD1 GLint KEYWORD2 NAME(RenderMode)(GLenum mode) +{ + RETURN_DISPATCH(RenderMode, (mode), (F, "glRenderMode(0x%x);", mode)); +} + +KEYWORD1 void KEYWORD2 NAME(Rotated)(GLdouble angle, GLdouble x, GLdouble y, GLdouble z) +{ + DISPATCH(Rotated, (angle, x, y, z), (F, ";")); +} + +KEYWORD1 void KEYWORD2 NAME(Rotatef)(GLfloat angle, GLfloat x, GLfloat y, GLfloat z) +{ + DISPATCH(Rotatef, (angle, x, y, z), (F, "glRotatef(%g, %g, %g, %g);", angle, x, y, z)); +} + +KEYWORD1 void KEYWORD2 NAME(SelectBuffer)(GLsizei size, GLuint *buffer) +{ + DISPATCH(SelectBuffer, (size, buffer), (F, ";")); +} + +KEYWORD1 void KEYWORD2 NAME(Scaled)(GLdouble x, GLdouble y, GLdouble z) +{ + DISPATCH(Scaled, (x, y, z), (F, ";")); +} + +KEYWORD1 void KEYWORD2 NAME(Scalef)(GLfloat x, GLfloat y, GLfloat z) +{ + DISPATCH(Scalef, (x, y, z), (F, "glScalef(%g, %g, %g);", x, y, z)); +} + +KEYWORD1 void KEYWORD2 NAME(Scissor)(GLint x, GLint y, GLsizei width, GLsizei height) +{ + DISPATCH(Scissor, (x, y, width, height), (F, "glScissor(%d, %d, %d, %d);", x, y, width, height)); +} + +KEYWORD1 void KEYWORD2 NAME(ShadeModel)(GLenum mode) +{ + DISPATCH(ShadeModel, (mode), (F, "glShadeModel(0x%x);", mode)); +} + +KEYWORD1 void KEYWORD2 NAME(StencilFunc)(GLenum func, GLint ref, GLuint mask) +{ + DISPATCH(StencilFunc, (func, ref, mask), (F, ";")); +} + +KEYWORD1 void KEYWORD2 NAME(StencilMask)(GLuint mask) +{ + DISPATCH(StencilMask, (mask), (F, ";")); +} + +KEYWORD1 void KEYWORD2 NAME(StencilOp)(GLenum fail, GLenum zfail, GLenum zpass) +{ + DISPATCH(StencilOp, (fail, zfail, zpass), (F, ";")); +} + +KEYWORD1 void KEYWORD2 NAME(TexGend)(GLenum coord, GLenum pname, GLdouble param) +{ + DISPATCH(TexGend, (coord, pname, param), (F, ";")); +} + +KEYWORD1 void KEYWORD2 NAME(TexGendv)(GLenum coord, GLenum pname, const GLdouble *params) +{ + DISPATCH(TexGendv, (coord, pname, params), (F, ";")); +} + +KEYWORD1 void KEYWORD2 NAME(TexGenf)(GLenum coord, GLenum pname, GLfloat param) +{ + DISPATCH(TexGenf, (coord, pname, param), (F, ";")); +} + +KEYWORD1 void KEYWORD2 NAME(TexGenfv)(GLenum coord, GLenum pname, const GLfloat *params) +{ + DISPATCH(TexGenfv, (coord, pname, params), (F, ";")); +} + +KEYWORD1 void KEYWORD2 NAME(TexGeni)(GLenum coord, GLenum pname, GLint param) +{ + DISPATCH(TexGeni, (coord, pname, param), (F, ";")); +} + +KEYWORD1 void KEYWORD2 NAME(TexGeniv)(GLenum coord, GLenum pname, const GLint *params) +{ + DISPATCH(TexGeniv, (coord, pname, params), (F, ";")); +} + +KEYWORD1 void KEYWORD2 NAME(TexEnvf)(GLenum target, GLenum pname, GLfloat param) +{ + DISPATCH(TexEnvf, (target, pname, param), (F, ";")); +} + +KEYWORD1 void KEYWORD2 NAME(TexEnvfv)(GLenum target, GLenum pname, const GLfloat *param) +{ + DISPATCH(TexEnvfv, (target, pname, param), (F, ";")); +} + +KEYWORD1 void KEYWORD2 NAME(TexEnvi)(GLenum target, GLenum pname, GLint param) +{ + DISPATCH(TexEnvi, (target, pname, param), (F, ";")); +} + +KEYWORD1 void KEYWORD2 NAME(TexEnviv)(GLenum target, GLenum pname, const GLint *param) +{ + DISPATCH(TexEnviv, (target, pname, param), (F, ";")); +} + +KEYWORD1 void KEYWORD2 NAME(TexImage1D)(GLenum target, GLint level, GLint internalformat, GLsizei width, GLint border, GLenum format, GLenum type, const GLvoid *pixels) +{ + DISPATCH(TexImage1D, (target, level, internalformat, width, border, format, type, pixels), (F, ";")); +} + +KEYWORD1 void KEYWORD2 NAME(TexImage2D)(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const GLvoid *pixels) +{ + DISPATCH(TexImage2D, (target, level, internalformat, width, height, border, format, type, pixels), (F, ";")); +} + +KEYWORD1 void KEYWORD2 NAME(TexParameterf)(GLenum target, GLenum pname, GLfloat param) +{ + DISPATCH(TexParameterf, (target, pname, param), (F, ";")); +} + +KEYWORD1 void KEYWORD2 NAME(TexParameterfv)(GLenum target, GLenum pname, const GLfloat *params) +{ + DISPATCH(TexParameterfv, (target, pname, params), (F, ";")); +} + +KEYWORD1 void KEYWORD2 NAME(TexParameteri)(GLenum target, GLenum pname, GLint param) +{ + DISPATCH(TexParameteri, (target, pname, param), (F, ";")); +} + +KEYWORD1 void KEYWORD2 NAME(TexParameteriv)(GLenum target, GLenum pname, const GLint *params) +{ + DISPATCH(TexParameteriv, (target, pname, params), (F, ";")); +} + +KEYWORD1 void KEYWORD2 NAME(Translated)(GLdouble x, GLdouble y, GLdouble z) +{ + DISPATCH(Translated, (x, y, z), (F, "glTranslated(%g, %g, %g);", x, y, z)); +} + +KEYWORD1 void KEYWORD2 NAME(Translatef)(GLfloat x, GLfloat y, GLfloat z) +{ + DISPATCH(Translatef, (x, y, z), (F, "glTranslatef(%g, %g, %g);", x, y, z)); +} + +KEYWORD1 void KEYWORD2 NAME(Viewport)(GLint x, GLint y, GLsizei width, GLsizei height) +{ + DISPATCH(Viewport, (x, y, width, height), (F, "glViewport(%d, %d, %d, %d);", x, y, width, height)); +} + + + +/* GL 1.1 */ + +KEYWORD1 GLboolean KEYWORD2 NAME(AreTexturesResident)(GLsizei n, const GLuint *textures, GLboolean *residences) +{ + RETURN_DISPATCH(AreTexturesResident, (n, textures, residences), (F, "glAreTexturesResident(%d, %p, %p);", n, textures, residences)); +} + +KEYWORD1 void KEYWORD2 NAME(ArrayElement)(GLint i) +{ + DISPATCH(ArrayElement, (i), (F, ";")); +} + +KEYWORD1 void KEYWORD2 NAME(BindTexture)(GLenum target, GLuint texture) +{ + DISPATCH(BindTexture, (target, texture), (F, ";")); +} + +KEYWORD1 void KEYWORD2 NAME(ColorPointer)(GLint size, GLenum type, GLsizei stride, const GLvoid *ptr) +{ + DISPATCH(ColorPointer, (size, type, stride, ptr), (F, ";")); +} + +KEYWORD1 void KEYWORD2 NAME(CopyTexImage1D)(GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLint border) +{ + DISPATCH(CopyTexImage1D, (target, level, internalformat, x, y, width, border), (F, ";")); +} + +KEYWORD1 void KEYWORD2 NAME(CopyTexImage2D)(GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border) +{ + DISPATCH(CopyTexImage2D, (target, level, internalformat, x, y, width, height, border), (F, ";")); +} + +KEYWORD1 void KEYWORD2 NAME(CopyTexSubImage1D)(GLenum target, GLint level, GLint xoffset, GLint x, GLint y, GLsizei width) +{ + DISPATCH(CopyTexSubImage1D, (target, level, xoffset, x, y, width), (F, ";")); +} + +KEYWORD1 void KEYWORD2 NAME(CopyTexSubImage2D)(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height) +{ + DISPATCH(CopyTexSubImage2D, (target, level, xoffset, yoffset, x, y, width, height), (F, ";")); +} + +KEYWORD1 void KEYWORD2 NAME(DeleteTextures)(GLsizei n, const GLuint *textures) +{ + DISPATCH(DeleteTextures, (n, textures), (F, "glDeleteTextures(%d, %p);", n, textures)); +} + +KEYWORD1 void KEYWORD2 NAME(DisableClientState)(GLenum cap) +{ + DISPATCH(DisableClientState, (cap), (F, "glDisableClientState(0x%x);", cap)); +} + +KEYWORD1 void KEYWORD2 NAME(DrawArrays)(GLenum mode, GLint first, GLsizei count) +{ + DISPATCH(DrawArrays, (mode, first, count), (F, "glDrawArrays(0x%x, %d, %d);", mode, first, count)); +} + +KEYWORD1 void KEYWORD2 NAME(EdgeFlagPointer)(GLsizei stride, const GLvoid *ptr) +{ + DISPATCH(EdgeFlagPointer, (stride, ptr), (F, "glEdgeFlagPointer(%d, %p);", stride, ptr)); +} + +KEYWORD1 void KEYWORD2 NAME(EnableClientState)(GLenum cap) +{ + DISPATCH(EnableClientState, (cap), (F, "glEnableClientState(0x%x)", cap)); +} + +KEYWORD1 void KEYWORD2 NAME(GenTextures)(GLsizei n, GLuint *textures) +{ + DISPATCH(GenTextures, (n, textures), (F, "glGenTextures(%d, %p);", n, textures)); +} + +KEYWORD1 void KEYWORD2 NAME(GetPointerv)(GLenum pname, GLvoid **params) +{ + DISPATCH(GetPointerv, (pname, params), (F, "glGetPointerv(0x%x, %p);", pname, params)); +} + +KEYWORD1 void KEYWORD2 NAME(IndexPointer)(GLenum type, GLsizei stride, const GLvoid *ptr) +{ + DISPATCH(IndexPointer, (type, stride, ptr), (F, "glIndexPointer(0x%x, %d, %p);", type, stride, ptr)); +} + +KEYWORD1 void KEYWORD2 NAME(InterleavedArrays)(GLenum format, GLsizei stride, const GLvoid *pointer) +{ + DISPATCH(InterleavedArrays, (format, stride, pointer), (F, "glInterleavedArrays(0x%x, %d, %p);", format, stride, pointer)); +} + +KEYWORD1 GLboolean KEYWORD2 NAME(IsTexture)(GLuint texture) +{ + RETURN_DISPATCH(IsTexture, (texture), (F, "glIsTexture(%u);", texture)); +} + +KEYWORD1 void KEYWORD2 NAME(NormalPointer)(GLenum type, GLsizei stride, const GLvoid *ptr) +{ + DISPATCH(NormalPointer, (type, stride, ptr), (F, "glNormalPointer(0x%x, %d, %p);", type, stride, ptr)); +} + +KEYWORD1 void KEYWORD2 NAME(PolygonOffset)(GLfloat factor, GLfloat units) +{ + DISPATCH(PolygonOffset, (factor, units), (F, "glPolygonOffset(%g, %g);", factor, units)); +} + +KEYWORD1 void KEYWORD2 NAME(PopClientAttrib)(void) +{ + DISPATCH(PopClientAttrib, (), (F, "glPopClientAttrib();")); +} + +KEYWORD1 void KEYWORD2 NAME(PrioritizeTextures)(GLsizei n, const GLuint *textures, const GLclampf *priorities) +{ + DISPATCH(PrioritizeTextures, (n, textures, priorities), (F, "glPrioritizeTextures(%d, %p, %p);", n, textures, priorities)); +} + +KEYWORD1 void KEYWORD2 NAME(PushClientAttrib)(GLbitfield mask) +{ + DISPATCH(PushClientAttrib, (mask), (F, "glPushClientAttrib(0x%x)", mask)); +} + +KEYWORD1 void KEYWORD2 NAME(TexCoordPointer)(GLint size, GLenum type, GLsizei stride, const GLvoid *ptr) +{ + DISPATCH(TexCoordPointer, (size, type, stride, ptr), (F, ";")); +} + +KEYWORD1 void KEYWORD2 NAME(TexSubImage1D)(GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLenum type, const GLvoid *pixels) +{ + DISPATCH(TexSubImage1D, (target, level, xoffset, width, format, type, pixels), (F, ";")); +} + +KEYWORD1 void KEYWORD2 NAME(TexSubImage2D)(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *pixels) +{ + DISPATCH(TexSubImage2D, (target, level, xoffset, yoffset, width, height, format, type, pixels), (F, ";")); +} + +KEYWORD1 void KEYWORD2 NAME(VertexPointer)(GLint size, GLenum type, GLsizei stride, const GLvoid *ptr) +{ + DISPATCH(VertexPointer, (size, type, stride, ptr), (F, ";")); +} + + +/* GL 1.2 */ + +KEYWORD1 void KEYWORD2 NAME(CopyTexSubImage3D)(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height) +{ + DISPATCH(CopyTexSubImage3D, (target, level, xoffset, yoffset, zoffset, x, y, width, height), (F, ";")); +} + +KEYWORD1 void KEYWORD2 NAME(DrawRangeElements)(GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const GLvoid *indices) +{ + DISPATCH(DrawRangeElements, (mode, start, end, count, type, indices), (F, ";")); +} + +KEYWORD1 void KEYWORD2 NAME(TexImage3D)(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const GLvoid *pixels) +{ + DISPATCH(TexImage3D, (target, level, internalformat, width, height, depth, border, format, type, pixels), (F, ";")); +} + +KEYWORD1 void KEYWORD2 NAME(TexSubImage3D)(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const GLvoid *pixels) +{ + DISPATCH(TexSubImage3D, (target, level, xoffset, yoffset, zoffset, width, height, depth, format, type, pixels), (F, ";")); +} + +/* GL_ARB_imaging */ + +KEYWORD1 void KEYWORD2 NAME(BlendColor)(GLclampf r, GLclampf g, GLclampf b, GLclampf a) +{ + DISPATCH(BlendColor, (r, g, b, a), (F, ";")); +} + +KEYWORD1 void KEYWORD2 NAME(BlendEquation)(GLenum mode) +{ + DISPATCH(BlendEquation, (mode), (F, ";")); +} + +KEYWORD1 void KEYWORD2 NAME(ColorSubTable)(GLenum target, GLsizei start, GLsizei count, GLenum format, GLenum type, const GLvoid *data) +{ + DISPATCH(ColorSubTable, (target, start, count, format, type, data), (F, ";")); +} + +KEYWORD1 void KEYWORD2 NAME(ColorTable)(GLenum target, GLenum internalformat, GLsizei width, GLenum format, GLenum type, const GLvoid *table) +{ + DISPATCH(ColorTable, (target, internalformat, width, format, type, table), (F, ";")); +} + +KEYWORD1 void KEYWORD2 NAME(ColorTableParameterfv)(GLenum target, GLenum pname, const GLfloat *params) +{ + DISPATCH(ColorTableParameterfv, (target, pname, params), (F, ";")); +} + +KEYWORD1 void KEYWORD2 NAME(ColorTableParameteriv)(GLenum target, GLenum pname, const GLint *params) +{ + DISPATCH(ColorTableParameteriv, (target, pname, params), (F, ";")); +} + +KEYWORD1 void KEYWORD2 NAME(ConvolutionFilter1D)(GLenum target, GLenum internalformat, GLsizei width, GLenum format, GLenum type, const GLvoid *image) +{ + DISPATCH(ConvolutionFilter1D, (target, internalformat, width, format, type, image), (F, ";")); +} + +KEYWORD1 void KEYWORD2 NAME(ConvolutionFilter2D)(GLenum target, GLenum internalformat, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *image) +{ + DISPATCH(ConvolutionFilter2D, (target, internalformat, width, height, format, type, image), (F, ";")); +} + +KEYWORD1 void KEYWORD2 NAME(ConvolutionParameterf)(GLenum target, GLenum pname, GLfloat params) +{ + DISPATCH(ConvolutionParameterf, (target, pname, params), (F, ";")); +} + +KEYWORD1 void KEYWORD2 NAME(ConvolutionParameterfv)(GLenum target, GLenum pname, const GLfloat *params) +{ + DISPATCH(ConvolutionParameterfv, (target, pname, params), (F, ";")); +} + +KEYWORD1 void KEYWORD2 NAME(ConvolutionParameteri)(GLenum target, GLenum pname, GLint params) +{ + DISPATCH(ConvolutionParameteri, (target, pname, params), (F, ";")); +} + +KEYWORD1 void KEYWORD2 NAME(ConvolutionParameteriv)(GLenum target, GLenum pname, const GLint *params) +{ + DISPATCH(ConvolutionParameteriv, (target, pname, params), (F, ";")); +} + +KEYWORD1 void KEYWORD2 NAME(CopyColorSubTable)(GLenum target, GLsizei start, GLint x, GLint y, GLsizei width) +{ + DISPATCH(CopyColorSubTable, (target, start, x, y, width), (F, ";")); +} + +KEYWORD1 void KEYWORD2 NAME(CopyColorTable)(GLenum target, GLenum internalformat, GLint x, GLint y, GLsizei width) +{ + DISPATCH(CopyColorTable, (target, internalformat, x, y, width), (F, ";")); +} + +KEYWORD1 void KEYWORD2 NAME(CopyConvolutionFilter1D)(GLenum target, GLenum internalformat, GLint x, GLint y, GLsizei width) +{ + DISPATCH(CopyConvolutionFilter1D, (target, internalformat, x, y, width), (F, ";")); +} + +KEYWORD1 void KEYWORD2 NAME(CopyConvolutionFilter2D)(GLenum target, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height) +{ + DISPATCH(CopyConvolutionFilter2D, (target, internalformat, x, y, width, height), (F, ";")); +} + +KEYWORD1 void KEYWORD2 NAME(GetColorTable)(GLenum target, GLenum format, GLenum type, GLvoid *table) +{ + DISPATCH(GetColorTable, (target, format, type, table), (F, ";")); +} + +KEYWORD1 void KEYWORD2 NAME(GetColorTableParameterfv)(GLenum target, GLenum pname, GLfloat *params) +{ + DISPATCH(GetColorTableParameterfv, (target, pname, params), (F, ";")); +} + +KEYWORD1 void KEYWORD2 NAME(GetColorTableParameteriv)(GLenum target, GLenum pname, GLint *params) +{ + DISPATCH(GetColorTableParameteriv, (target, pname, params), (F, ";")); +} + +KEYWORD1 void KEYWORD2 NAME(GetConvolutionFilter)(GLenum target, GLenum format, GLenum type, GLvoid *image) +{ + DISPATCH(GetConvolutionFilter, (target, format, type, image), (F, ";")); +} + +KEYWORD1 void KEYWORD2 NAME(GetConvolutionParameterfv)(GLenum target, GLenum pname, GLfloat *params) +{ + DISPATCH(GetConvolutionParameterfv, (target, pname, params), (F, ";")); +} + +KEYWORD1 void KEYWORD2 NAME(GetConvolutionParameteriv)(GLenum target, GLenum pname, GLint *params) +{ + DISPATCH(GetConvolutionParameteriv, (target, pname, params), (F, ";")); +} + +KEYWORD1 void KEYWORD2 NAME(GetHistogram)(GLenum target, GLboolean reset, GLenum format, GLenum type, GLvoid *values) +{ + DISPATCH(GetHistogram, (target, reset, format, type, values), (F, ";")); +} + +KEYWORD1 void KEYWORD2 NAME(GetHistogramParameterfv)(GLenum target, GLenum pname, GLfloat *params) +{ + DISPATCH(GetHistogramParameterfv, (target, pname, params), (F, ";")); +} + +KEYWORD1 void KEYWORD2 NAME(GetHistogramParameteriv)(GLenum target, GLenum pname, GLint *params) +{ + DISPATCH(GetHistogramParameteriv, (target, pname, params), (F, ";")); +} + +KEYWORD1 void KEYWORD2 NAME(GetMinmax)(GLenum target, GLboolean reset, GLenum format, GLenum types, GLvoid *values) +{ + DISPATCH(GetMinmax, (target, reset, format, types, values), (F, ";")); +} + +KEYWORD1 void KEYWORD2 NAME(GetMinmaxParameterfv)(GLenum target, GLenum pname, GLfloat *params) +{ + DISPATCH(GetMinmaxParameterfv, (target, pname, params), (F, ";")); +} + +KEYWORD1 void KEYWORD2 NAME(GetMinmaxParameteriv)(GLenum target, GLenum pname, GLint *params) +{ + DISPATCH(GetMinmaxParameteriv, (target, pname, params), (F, ";")); +} + +KEYWORD1 void KEYWORD2 NAME(GetSeparableFilter)(GLenum target, GLenum format, GLenum type, GLvoid *row, GLvoid *column, GLvoid *span) +{ + DISPATCH(GetSeparableFilter, (target, format, type, row, column, span), (F, ";")); +} + +KEYWORD1 void KEYWORD2 NAME(Histogram)(GLenum target, GLsizei width, GLenum internalformat, GLboolean sink) +{ + DISPATCH(Histogram, (target, width, internalformat, sink), (F, ";")); +} + +KEYWORD1 void KEYWORD2 NAME(Minmax)(GLenum target, GLenum internalformat, GLboolean sink) +{ + DISPATCH(Minmax, (target, internalformat, sink), (F, ";")); +} + +KEYWORD1 void KEYWORD2 NAME(ResetMinmax)(GLenum target) +{ + DISPATCH(ResetMinmax, (target), (F, ";")); +} + +KEYWORD1 void KEYWORD2 NAME(ResetHistogram)(GLenum target) +{ + DISPATCH(ResetHistogram, (target), (F, ";")); +} + +KEYWORD1 void KEYWORD2 NAME(SeparableFilter2D)(GLenum target, GLenum internalformat, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *row, const GLvoid *column) +{ + DISPATCH(SeparableFilter2D, (target, internalformat, width, height, format, type, row, column), (F, ";")); +} + +/*** + *** Extension functions + ***/ + +/* 2. GL_EXT_blend_color */ +KEYWORD1 void KEYWORD2 NAME(BlendColorEXT)(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha) +{ + DISPATCH(BlendColor, (red, green, blue, alpha), (F, ";")); +} + +/* 3. GL_EXT_polygon_offset */ +KEYWORD1 void KEYWORD2 NAME(PolygonOffsetEXT)(GLfloat factor, GLfloat bias) +{ + DISPATCH(PolygonOffsetEXT, (factor, bias), (F, ";")); +} + +/* 6. GL_EXT_texture3D */ + +KEYWORD1 void KEYWORD2 NAME(CopyTexSubImage3DEXT)(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height) +{ + DISPATCH(CopyTexSubImage3D, (target, level, xoffset, yoffset, zoffset, x, y, width, height), (F, ";")); +} + +KEYWORD1 void KEYWORD2 NAME(TexImage3DEXT)(GLenum target, GLint level, GLenum internalFormat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const GLvoid *pixels) +{ + DISPATCH(TexImage3D, (target, level, internalFormat, width, height, depth, border, format, type, pixels), (F, ";")); +} + +KEYWORD1 void KEYWORD2 NAME(TexSubImage3DEXT)(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const GLvoid *pixels) +{ + DISPATCH(TexSubImage3D, (target, level, xoffset, yoffset, zoffset, width, height, depth, format, type, pixels), (F, ";")); +} + +/* 7. GL_SGI_texture_filter4 */ + +KEYWORD1 void KEYWORD2 NAME(GetTexFilterFuncSGIS)(GLenum target, GLenum filter, GLfloat *weights) +{ + DISPATCH(GetTexFilterFuncSGIS, (target, filter, weights), (F, ";")); +} + +KEYWORD1 void KEYWORD2 NAME(TexFilterFuncSGIS)(GLenum target, GLenum filter, GLsizei n, const GLfloat *weights) +{ + DISPATCH(TexFilterFuncSGIS, (target, filter, n, weights), (F, ";")); +} + +/* 9. GL_EXT_subtexture */ + +KEYWORD1 void KEYWORD2 NAME(CopyTexSubImage1DEXT)(GLenum target, GLint level, GLint xoffset, GLint x, GLint y, GLsizei width) +{ + DISPATCH(CopyTexSubImage1D, (target, level, xoffset, x, y, width), (F, ";")); +} + +KEYWORD1 void KEYWORD2 NAME(TexSubImage1DEXT)(GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLenum type, const GLvoid *pixels) +{ + DISPATCH(TexSubImage1D, (target, level, xoffset, width, format, type, pixels), (F, ";")); +} + +KEYWORD1 void KEYWORD2 NAME(TexSubImage2DEXT)(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *pixels) +{ + DISPATCH(TexSubImage2D, (target, level, xoffset, yoffset, width, height, format, type, pixels), (F, ";")); +} + +/* 10. GL_EXT_copy_texture */ + +KEYWORD1 void KEYWORD2 NAME(CopyTexImage1DEXT)(GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLint border) +{ + DISPATCH(CopyTexImage1D, (target, level, internalformat, x, y, width, border), (F, ";")); +} + +KEYWORD1 void KEYWORD2 NAME(CopyTexImage2DEXT)(GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border) +{ + DISPATCH(CopyTexImage2D, (target, level, internalformat, x, y, width, height, border), (F, ";")); +} + +KEYWORD1 void KEYWORD2 NAME(CopyTexSubImage2DEXT)(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height) +{ + DISPATCH(CopyTexSubImage2D, (target, level, xoffset, yoffset, x, y, width, height), (F, ";")); +} + +/* 11. GL_EXT_histogram */ +KEYWORD1 void KEYWORD2 NAME(GetHistogramEXT)(GLenum target, GLboolean reset, GLenum format, GLenum type, GLvoid *values) +{ + DISPATCH(GetHistogramEXT, (target, reset, format, type, values), (F, ";")); +} + +KEYWORD1 void KEYWORD2 NAME(GetHistogramParameterfvEXT)(GLenum target, GLenum pname, GLfloat *params) +{ + DISPATCH(GetHistogramParameterfvEXT, (target, pname, params), (F, ";")); +} + +KEYWORD1 void KEYWORD2 NAME(GetHistogramParameterivEXT)(GLenum target, GLenum pname, GLint *params) +{ + DISPATCH(GetHistogramParameterivEXT, (target, pname, params), (F, ";")); +} + +KEYWORD1 void KEYWORD2 NAME(GetMinmaxEXT)(GLenum target, GLboolean reset, GLenum format, GLenum types, GLvoid *values) +{ + DISPATCH(GetMinmaxEXT, (target, reset, format, types, values), (F, ";")); +} + +KEYWORD1 void KEYWORD2 NAME(GetMinmaxParameterfvEXT)(GLenum target, GLenum pname, GLfloat *params) +{ + DISPATCH(GetMinmaxParameterfvEXT, (target, pname, params), (F, ";")); +} + +KEYWORD1 void KEYWORD2 NAME(GetMinmaxParameterivEXT)(GLenum target, GLenum pname, GLint *params) +{ + DISPATCH(GetMinmaxParameterivEXT, (target, pname, params), (F, ";")); +} + +KEYWORD1 void KEYWORD2 NAME(HistogramEXT)(GLenum target, GLsizei width, GLenum internalformat, GLboolean sink) +{ + DISPATCH(Histogram, (target, width, internalformat, sink), (F, ";")); +} + +KEYWORD1 void KEYWORD2 NAME(MinmaxEXT)(GLenum target, GLenum internalformat, GLboolean sink) +{ + DISPATCH(Minmax, (target, internalformat, sink), (F, ";")); +} + +KEYWORD1 void KEYWORD2 NAME(ResetHistogramEXT)(GLenum target) +{ + DISPATCH(ResetHistogram, (target), (F, ";")); +} + +KEYWORD1 void KEYWORD2 NAME(ResetMinmaxEXT)(GLenum target) +{ + DISPATCH(ResetMinmax, (target), (F, ";")); +} + +/* 12. GL_EXT_convolution */ + +KEYWORD1 void KEYWORD2 NAME(ConvolutionFilter1DEXT)(GLenum target, GLenum internalformat, GLsizei width, GLenum format, GLenum type, const GLvoid *image) +{ + DISPATCH(ConvolutionFilter1D, (target, internalformat, width, format, type, image), (F, ";")); +} + +KEYWORD1 void KEYWORD2 NAME(ConvolutionFilter2DEXT)(GLenum target, GLenum internalformat, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *image) +{ + DISPATCH(ConvolutionFilter2D, (target, internalformat, width, height, format, type, image), (F, ";")); +} + +KEYWORD1 void KEYWORD2 NAME(ConvolutionParameterfEXT)(GLenum target, GLenum pname, GLfloat params) +{ + DISPATCH(ConvolutionParameterf, (target, pname, params), (F, ";")); +} + +KEYWORD1 void KEYWORD2 NAME(ConvolutionParameterfvEXT)(GLenum target, GLenum pname, const GLfloat *params) +{ + DISPATCH(ConvolutionParameterfv, (target, pname, params), (F, ";")); +} + +KEYWORD1 void KEYWORD2 NAME(ConvolutionParameteriEXT)(GLenum target, GLenum pname, GLint params) +{ + DISPATCH(ConvolutionParameteri, (target, pname, params), (F, ";")); +} + +KEYWORD1 void KEYWORD2 NAME(ConvolutionParameterivEXT)(GLenum target, GLenum pname, const GLint *params) +{ + DISPATCH(ConvolutionParameteriv, (target, pname, params), (F, ";")); +} + +KEYWORD1 void KEYWORD2 NAME(CopyConvolutionFilter1DEXT)(GLenum target, GLenum internalformat, GLint x, GLint y, GLsizei width) +{ + DISPATCH(CopyConvolutionFilter1D, (target, internalformat, x, y, width), (F, ";")); +} + +KEYWORD1 void KEYWORD2 NAME(CopyConvolutionFilter2DEXT)(GLenum target, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height) +{ + DISPATCH(CopyConvolutionFilter2D, (target, internalformat, x, y, width, height), (F, ";")); +} + +KEYWORD1 void KEYWORD2 NAME(GetConvolutionFilterEXT)(GLenum target, GLenum format, GLenum type, GLvoid *image) +{ + DISPATCH(GetConvolutionFilterEXT, (target, format, type, image), (F, ";")); +} + +KEYWORD1 void KEYWORD2 NAME(GetConvolutionParameterfvEXT)(GLenum target, GLenum pname, GLfloat *params) +{ + DISPATCH(GetConvolutionParameterfvEXT, (target, pname, params), (F, ";")); +} + +KEYWORD1 void KEYWORD2 NAME(GetConvolutionParameterivEXT)(GLenum target, GLenum pname, GLint *params) +{ + DISPATCH(GetConvolutionParameterivEXT, (target, pname, params), (F, ";")); +} + +KEYWORD1 void KEYWORD2 NAME(GetSeparableFilterEXT)(GLenum target, GLenum format, GLenum type, GLvoid *row, GLvoid *column, GLvoid *span) +{ + DISPATCH(GetSeparableFilterEXT, (target, format, type, row, column, span), (F, ";")); +} + +KEYWORD1 void KEYWORD2 NAME(SeparableFilter2DEXT)(GLenum target, GLenum internalformat, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *row, const GLvoid *column) +{ + DISPATCH(SeparableFilter2D, (target, internalformat, width, height, format, type, row, column), (F, ";")); +} + +/* 14. GL_SGI_color_table */ + +KEYWORD1 void KEYWORD2 NAME(ColorTableParameterfvSGI)(GLenum target, GLenum pname, const GLfloat *params) +{ + DISPATCH(ColorTableParameterfv, (target, pname, params), (F, ";")); +} + +KEYWORD1 void KEYWORD2 NAME(ColorTableParameterivSGI)(GLenum target, GLenum pname, const GLint *params) +{ + DISPATCH(ColorTableParameteriv, (target, pname, params), (F, ";")); +} + +KEYWORD1 void KEYWORD2 NAME(ColorTableSGI)(GLenum target, GLenum internalformat, GLsizei width, GLenum format, GLenum type, const GLvoid *table) +{ + DISPATCH(ColorTable, (target, internalformat, width, format, type, table), (F, ";")); +} + +KEYWORD1 void KEYWORD2 NAME(CopyColorTableSGI)(GLenum target, GLenum internalFormat, GLint x, GLint y, GLsizei width) +{ + DISPATCH(CopyColorTable, (target, internalFormat, x, y, width), (F, ";")); +} + +KEYWORD1 void KEYWORD2 NAME(GetColorTableSGI)(GLenum target, GLenum format, GLenum type, GLvoid *table) +{ + DISPATCH(GetColorTableSGI, (target, format, type, table), (F, ";")); +} +KEYWORD1 void KEYWORD2 NAME(GetColorTableParameterfvSGI)(GLenum target, GLenum pname, GLfloat *params) +{ + DISPATCH(GetColorTableParameterfvSGI, (target, pname, params), (F, ";")); +} + +KEYWORD1 void KEYWORD2 NAME(GetColorTableParameterivSGI)(GLenum target, GLenum pname, GLint *params) +{ + DISPATCH(GetColorTableParameterivSGI, (target, pname, params), (F, ";")); +} + +/* ??. GL_SGIX_pixel_texture */ + +KEYWORD1 void KEYWORD2 NAME(PixelTexGenSGIX)(GLenum mode) +{ + DISPATCH(PixelTexGenSGIX, (mode), (F, ";")); +} + +/* 15. GL_SGIS_pixel_texture */ + +KEYWORD1 void KEYWORD2 NAME(PixelTexGenParameterfSGIS)(GLenum target, GLfloat value) +{ + DISPATCH(PixelTexGenParameterfSGIS, (target, value), (F, ";")); +} + +KEYWORD1 void KEYWORD2 NAME(PixelTexGenParameterfvSGIS)(GLenum target, const GLfloat *value) +{ + DISPATCH(PixelTexGenParameterfvSGIS, (target, value), (F, ";")); +} + +KEYWORD1 void KEYWORD2 NAME(PixelTexGenParameteriSGIS)(GLenum target, GLint value) +{ + DISPATCH(PixelTexGenParameteriSGIS, (target, value), (F, ";")); +} + +KEYWORD1 void KEYWORD2 NAME(PixelTexGenParameterivSGIS)(GLenum target, const GLint *value) +{ + DISPATCH(PixelTexGenParameterivSGIS, (target, value), (F, ";")); +} + +KEYWORD1 void KEYWORD2 NAME(GetPixelTexGenParameterfvSGIS)(GLenum target, GLfloat *value) +{ + DISPATCH(GetPixelTexGenParameterfvSGIS, (target, value), (F, ";")); +} + +KEYWORD1 void KEYWORD2 NAME(GetPixelTexGenParameterivSGIS)(GLenum target, GLint *value) +{ + DISPATCH(GetPixelTexGenParameterivSGIS, (target, value), (F, ";")); +} + +/* 16. GL_SGIS_texture4D */ + +KEYWORD1 void KEYWORD2 NAME(TexImage4DSGIS)(GLenum target, GLint level, GLenum internalFormat, GLsizei width, GLsizei height, GLsizei depth, GLsizei extent, GLint border, GLenum format, GLenum type, const void *pixels) +{ + DISPATCH(TexImage4DSGIS, (target, level, internalFormat, width, height, depth, extent, border, format, type, pixels), (F, ";")); +} + +KEYWORD1 void KEYWORD2 NAME(TexSubImage4DSGIS)(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint woffset, GLsizei width, GLsizei height, GLsizei depth, GLsizei extent, GLenum format, GLenum type, const void *pixels) +{ + DISPATCH(TexSubImage4DSGIS, (target, level, xoffset, yoffset, zoffset, woffset, width, height, depth, extent, format, type, pixels), (F, ";")); +} + +/* 20. GL_EXT_texture_object */ + +KEYWORD1 void KEYWORD2 NAME(GenTexturesEXT)(GLsizei n, GLuint *textures) +{ + DISPATCH(GenTextures, (n, textures), (F, ";")); +} + +KEYWORD1 void KEYWORD2 NAME(DeleteTexturesEXT)(GLsizei n, const GLuint *texture) +{ + DISPATCH(DeleteTextures, (n, texture), (F, ";")); +} + +KEYWORD1 void KEYWORD2 NAME(BindTextureEXT)(GLenum target, GLuint texture) +{ + DISPATCH(BindTexture, (target, texture), (F, ";")); +} + +KEYWORD1 void KEYWORD2 NAME(PrioritizeTexturesEXT)(GLsizei n, const GLuint *textures, const GLclampf *priorities) +{ + DISPATCH(PrioritizeTextures, (n, textures, priorities), (F, ";")); +} + +KEYWORD1 GLboolean KEYWORD2 NAME(AreTexturesResidentEXT)(GLsizei n, const GLuint *textures, GLboolean *residences) +{ + RETURN_DISPATCH(AreTexturesResident, (n, textures, residences), (F, "glAreTexturesResidentEXT(%d %p %p);", n, textures, residences)); +} + +KEYWORD1 GLboolean KEYWORD2 NAME(IsTextureEXT)(GLuint texture) +{ + RETURN_DISPATCH(IsTexture, (texture), (F, "glIsTextureEXT(%u);", texture)); +} + +/* 21. GL_SGIS_detail_texture */ + +KEYWORD1 void KEYWORD2 NAME(DetailTexFuncSGIS)(GLenum target, GLsizei n, const GLfloat *points) +{ + DISPATCH(DetailTexFuncSGIS, (target, n, points), (F, ";")); +} + +KEYWORD1 void KEYWORD2 NAME(GetDetailTexFuncSGIS)(GLenum target, GLfloat *points) +{ + DISPATCH(GetDetailTexFuncSGIS, (target, points), (F, ";")); +} + +/* 22. GL_SGIS_sharpen_texture */ + +KEYWORD1 void KEYWORD2 NAME(GetSharpenTexFuncSGIS)(GLenum target, GLfloat *points) +{ + DISPATCH(GetSharpenTexFuncSGIS, (target, points), (F, ";")); +} + +KEYWORD1 void KEYWORD2 NAME(SharpenTexFuncSGIS)(GLenum target, GLsizei n, const GLfloat *points) +{ + DISPATCH(SharpenTexFuncSGIS, (target, n, points), (F, ";")); +} + +/* 25. GL_SGIS_multisample */ + +KEYWORD1 void KEYWORD2 NAME(SampleMaskSGIS)(GLclampf value, GLboolean invert) +{ + DISPATCH(SampleMaskSGIS, (value, invert), (F, ";")); +} + +KEYWORD1 void KEYWORD2 NAME(SamplePatternSGIS)(GLenum pattern) +{ + DISPATCH(SamplePatternSGIS, (pattern), (F, ";")); +} + +/* 30. GL_EXT_vertex_array */ + +KEYWORD1 void KEYWORD2 NAME(VertexPointerEXT)(GLint size, GLenum type, GLsizei stride, GLsizei count, const GLvoid *ptr) +{ + DISPATCH(VertexPointerEXT, (size, type, stride, count, ptr), (F, ";")); +} + +KEYWORD1 void KEYWORD2 NAME(NormalPointerEXT)(GLenum type, GLsizei stride, GLsizei count, const GLvoid *ptr) +{ + DISPATCH(NormalPointerEXT, (type, stride, count, ptr), (F, ";")); +} + +KEYWORD1 void KEYWORD2 NAME(ColorPointerEXT)(GLint size, GLenum type, GLsizei stride, GLsizei count, const GLvoid *ptr) +{ + DISPATCH(ColorPointerEXT, (size, type, stride, count, ptr), (F, ";")); +} + +KEYWORD1 void KEYWORD2 NAME(IndexPointerEXT)(GLenum type, GLsizei stride, GLsizei count, const GLvoid *ptr) +{ + DISPATCH(IndexPointerEXT, (type, stride, count, ptr), (F, ";")); +} + +KEYWORD1 void KEYWORD2 NAME(TexCoordPointerEXT)(GLint size, GLenum type, GLsizei stride, GLsizei count, const GLvoid *ptr) +{ + DISPATCH(ColorPointerEXT, (size, type, stride, count, ptr), (F, ";")); +} + +KEYWORD1 void KEYWORD2 NAME(EdgeFlagPointerEXT)(GLsizei stride, GLsizei count, const GLboolean *ptr) +{ + DISPATCH(EdgeFlagPointerEXT, (stride, count, ptr), (F, ";")); +} + +KEYWORD1 void KEYWORD2 NAME(GetPointervEXT)(GLenum pname, void **params) +{ + DISPATCH(GetPointerv, (pname, params), (F, ";")); +} + +KEYWORD1 void KEYWORD2 NAME(DrawArraysEXT)(GLenum mode, GLint first, GLsizei count) +{ + DISPATCH(DrawArrays, (mode, first, count), (F, ";")); +} + +/* 37. GL_EXT_blend_minmax */ +KEYWORD1 void KEYWORD2 NAME(BlendEquationEXT)(GLenum mode) +{ + DISPATCH(BlendEquation, (mode), (F, "glBlendEquationEXT(0x%x);", mode)); +} + +/* 52. GL_SGIX_sprite */ + +KEYWORD1 void KEYWORD2 NAME(SpriteParameterfSGIX)(GLenum pname, GLfloat param) +{ + DISPATCH(SpriteParameterfSGIX, (pname, param), (F, ";")); +} + +KEYWORD1 void KEYWORD2 NAME(SpriteParameterfvSGIX)(GLenum pname, const GLfloat *param) +{ + DISPATCH(SpriteParameterfvSGIX, (pname, param), (F, ";")); +} + +KEYWORD1 void KEYWORD2 NAME(SpriteParameteriSGIX)(GLenum pname, GLint param) +{ + DISPATCH(SpriteParameteriSGIX, (pname, param), (F, ";")); +} + +KEYWORD1 void KEYWORD2 NAME(SpriteParameterivSGIX)(GLenum pname, const GLint *param) +{ + DISPATCH(SpriteParameterivSGIX, (pname, param), (F, ";")); +} + +/* 54. GL_EXT_point_parameters */ + +KEYWORD1 void KEYWORD2 NAME(PointParameterfEXT)(GLenum target, GLfloat param) +{ + DISPATCH(PointParameterfEXT, (target, param), (F, ";")); +} + +KEYWORD1 void KEYWORD2 NAME(PointParameterfvEXT)(GLenum target, const GLfloat *param) +{ + DISPATCH(PointParameterfvEXT, (target, param), (F, ";")); +} + +KEYWORD1 void KEYWORD2 NAME(PointParameterfSGIS)(GLenum target, GLfloat param) +{ + DISPATCH(PointParameterfEXT, (target, param), (F, ";")); +} + +KEYWORD1 void KEYWORD2 NAME(PointParameterfvSGIS)(GLenum target, const GLfloat *param) +{ + DISPATCH(PointParameterfvEXT, (target, param), (F, ";")); +} + +/* 55. GL_SGIX_instruments */ +KEYWORD1 GLint KEYWORD2 NAME(GetInstrumentsSGIX)(void) +{ + RETURN_DISPATCH(GetInstrumentsSGIX, (), (F, ";")); +} + +KEYWORD1 void KEYWORD2 NAME(InstrumentsBufferSGIX)(GLsizei size, GLint *buf) +{ + DISPATCH(InstrumentsBufferSGIX, (size, buf), (F, ";")); +} + +KEYWORD1 GLint KEYWORD2 NAME(PollInstrumentsSGIX)(GLint *markerp) +{ + RETURN_DISPATCH(PollInstrumentsSGIX, (markerp), (F, ";")); +} + +KEYWORD1 void KEYWORD2 NAME(ReadInstrumentsSGIX)(GLint marker) +{ + DISPATCH(ReadInstrumentsSGIX, (marker), (F, ";")); +} + +KEYWORD1 void KEYWORD2 NAME(StartInstrumentsSGIX)(void) +{ + DISPATCH(StartInstrumentsSGIX, (), (F, ";")); +} + +KEYWORD1 void KEYWORD2 NAME(StopInstrumentsSGIX)(GLint marker) +{ + DISPATCH(StopInstrumentsSGIX, (marker), (F, ";")); +} + +/* 57. GL_SGIX_framezoom */ +KEYWORD1 void KEYWORD2 NAME(FrameZoomSGIX)(GLint factor) +{ + DISPATCH(FrameZoomSGIX, (factor), (F, ";")); +} + +/* 58. GL_SGIX_tag_sample_buffer */ +KEYWORD1 void KEYWORD2 NAME(TagSampleBufferSGIX)(void) +{ + DISPATCH(TagSampleBufferSGIX, (), (F, ";")); +} + +/* 60. GL_SGIX_reference_plane */ +KEYWORD1 void KEYWORD2 NAME(ReferencePlaneSGIX)(const GLdouble *plane) +{ + DISPATCH(ReferencePlaneSGIX, (plane), (F, ";")); +} + +/* 61. GL_SGIX_flush_raster */ +KEYWORD1 void KEYWORD2 NAME(FlushRasterSGIX)(void) +{ + DISPATCH(FlushRasterSGIX, (), (F, ";")); +} + +/* 66. GL_HP_image_transform */ +#if 00 +KEYWORD1 void KEYWORD2 NAME(GetImageTransformParameterfvHP)(GLenum target, GLenum pname, GLfloat *param) +{ + DISPATCH(GetImageTransformParameterfvHP, (target, pname, param), (F, ";")); +} + +KEYWORD1 void KEYWORD2 NAME(GetImageTransformParameterivHP)(GLenum target, GLenum pname, GLint *param) +{ + DISPATCH(GetImageTransformParameterivHP, (target, pname, param), (F, ";")); +} + +KEYWORD1 void KEYWORD2 NAME(ImageTransformParameterfHP)(GLenum target, GLenum pname, const GLfloat param) +{ + DISPATCH(ImageTransformParameterfHP, (target, pname, param), (F, ";")); +} + +KEYWORD1 void KEYWORD2 NAME(ImageTransformParameterfvHP)(GLenum target, GLenum pname, const GLfloat *param) +{ + DISPATCH(ImageTransformParameterfvHP, (target, pname, param), (F, ";")); +} + +KEYWORD1 void KEYWORD2 NAME(ImageTransformParameteriHP)(GLenum target, GLenum pname, const GLint param) +{ + DISPATCH(ImageTransformParameteriHP, (target, pname, param), (F, ";")); +} + +KEYWORD1 void KEYWORD2 NAME(ImageTransformParameterivHP)(GLenum target, GLenum pname, const GLint *param) +{ + DISPATCH(ImageTransformParameterivHP, (target, pname, param), (F, ";")); +} +#endif + +/* 74. GL_EXT_color_subtable */ +KEYWORD1 void KEYWORD2 NAME(ColorSubTableEXT)(GLenum target, GLsizei start, GLsizei count, GLenum format, GLenum type, const void *data) +{ + DISPATCH(ColorSubTable, (target, start, count, format, type, data), (F, ";")); +} + +KEYWORD1 void KEYWORD2 NAME(CopyColorSubTableEXT)(GLenum target, GLsizei start, GLint x, GLint y, GLsizei width) +{ + DISPATCH(CopyColorSubTable, (target, start, x, y, width), (F, ";")); +} + +/* 77. GL_PGI_misc_hints */ +KEYWORD1 void KEYWORD2 NAME(HintPGI)(GLenum target, GLint mode) +{ + DISPATCH(HintPGI, (target, mode), (F, ";")); +} + +/* 78. GL_EXT_paletted_texture */ + +KEYWORD1 void KEYWORD2 NAME(ColorTableEXT)(GLenum target, GLenum internalformat, GLsizei width, GLenum format, GLenum type, const GLvoid *table) +{ + DISPATCH(ColorTable, (target, internalformat, width, format, type, table), (F, ";")); +} + +KEYWORD1 void KEYWORD2 NAME(GetColorTableEXT)(GLenum target, GLenum format, GLenum type, GLvoid *table) +{ + DISPATCH(GetColorTableEXT, (target, format, type, table), (F, ";")); +} + +KEYWORD1 void KEYWORD2 NAME(GetColorTableParameterfvEXT)(GLenum target, GLenum pname, GLfloat *params) +{ + DISPATCH(GetColorTableParameterfvEXT, (target, pname, params), (F, ";")); +} + +KEYWORD1 void KEYWORD2 NAME(GetColorTableParameterivEXT)(GLenum target, GLenum pname, GLint *params) +{ + DISPATCH(GetColorTableParameterivEXT, (target, pname, params), (F, ";")); +} + +/* 80. GL_SGIX_list_priority */ + +KEYWORD1 void KEYWORD2 NAME(GetListParameterfvSGIX)(GLuint list, GLenum name, GLfloat *param) +{ + DISPATCH(GetListParameterfvSGIX, (list, name, param), (F, ";")); +} + +KEYWORD1 void KEYWORD2 NAME(GetListParameterivSGIX)(GLuint list, GLenum name, GLint *param) +{ + DISPATCH(GetListParameterivSGIX, (list, name, param), (F, ";")); +} + +KEYWORD1 void KEYWORD2 NAME(ListParameterfSGIX)(GLuint list, GLenum name, GLfloat param) +{ + DISPATCH(ListParameterfSGIX, (list, name, param), (F, ";")); +} + +KEYWORD1 void KEYWORD2 NAME(ListParameterfvSGIX)(GLuint list, GLenum name, const GLfloat *param) +{ + DISPATCH(ListParameterfvSGIX, (list, name, param), (F, ";")); +} + +KEYWORD1 void KEYWORD2 NAME(ListParameteriSGIX)(GLuint list, GLenum name, GLint param) +{ + DISPATCH(ListParameteriSGIX, (list, name, param), (F, ";")); +} + +KEYWORD1 void KEYWORD2 NAME(ListParameterivSGIX)(GLuint list, GLenum name, const GLint *param) +{ + DISPATCH(ListParameterivSGIX, (list, name, param), (F, ";")); +} + +/* 94. GL_EXT_index_material */ +KEYWORD1 void KEYWORD2 NAME(IndexMaterialEXT)(GLenum face, GLenum mode) +{ + DISPATCH(IndexMaterialEXT, (face, mode), (F, ";")); +} + +/* 95. GL_EXT_index_func */ +KEYWORD1 void KEYWORD2 NAME(IndexFuncEXT)(GLenum func, GLfloat ref) +{ + DISPATCH(IndexFuncEXT, (func, ref), (F, ";")); +} + +/* 97. GL_EXT_compiled_vertex_array */ +KEYWORD1 void KEYWORD2 NAME(LockArraysEXT)(GLint first, GLsizei count) +{ + DISPATCH(LockArraysEXT, (first, count), (F, ";")); +} + +KEYWORD1 void KEYWORD2 NAME(UnlockArraysEXT)(void) +{ + DISPATCH(UnlockArraysEXT, (), (F, ";")); +} + +/* 98. GL_EXT_cull_vertex */ +KEYWORD1 void KEYWORD2 NAME(CullParameterfvEXT)(GLenum pname, GLfloat *params) +{ + DISPATCH(CullParameterfvEXT, (pname, params), (F, ";")); +} + +KEYWORD1 void KEYWORD2 NAME(CullParameterdvEXT)(GLenum pname, GLdouble *params) +{ + DISPATCH(CullParameterdvEXT, (pname, params), (F, ";")); +} + +/* 102. GL_SGIX_fragment_lighting */ +KEYWORD1 void KEYWORD2 NAME(FragmentColorMaterialSGIX)(GLenum face, GLenum mode) +{ + DISPATCH(FragmentColorMaterialSGIX, (face, mode), (F, ";")); +} + +KEYWORD1 void KEYWORD2 NAME(FragmentLightfSGIX)(GLenum light, GLenum pname, GLfloat param) +{ + DISPATCH(FragmentLightfSGIX, (light, pname, param), (F, ";")); +} + +KEYWORD1 void KEYWORD2 NAME(FragmentLightfvSGIX)(GLenum light, GLenum pname, const GLfloat * params) +{ + DISPATCH(FragmentLightfvSGIX, (light, pname, params), (F, ";")); +} + +KEYWORD1 void KEYWORD2 NAME(FragmentLightiSGIX)(GLenum light, GLenum pname, GLint param) +{ + DISPATCH(FragmentLightiSGIX, (light, pname, param), (F, ";")); +} + +KEYWORD1 void KEYWORD2 NAME(FragmentLightivSGIX)(GLenum light, GLenum pname, const GLint * params) +{ + DISPATCH(FragmentLightivSGIX, (light, pname, params), (F, ";")); +} + +KEYWORD1 void KEYWORD2 NAME(FragmentLightModelfSGIX)(GLenum pname, GLfloat param) +{ + DISPATCH(FragmentLightModelfSGIX, (pname, param), (F, ";")); +} + +KEYWORD1 void KEYWORD2 NAME(FragmentLightModelfvSGIX)(GLenum pname, const GLfloat * params) +{ + DISPATCH(FragmentLightModelfvSGIX, (pname, params), (F, ";")); +} + +KEYWORD1 void KEYWORD2 NAME(FragmentLightModeliSGIX)(GLenum pname, GLint param) +{ + DISPATCH(FragmentLightModeliSGIX, (pname, param), (F, ";")); +} + +KEYWORD1 void KEYWORD2 NAME(FragmentLightModelivSGIX)(GLenum pname, const GLint * params) +{ + DISPATCH(FragmentLightModelivSGIX, (pname, params), (F, ";")); +} + +KEYWORD1 void KEYWORD2 NAME(FragmentMaterialfSGIX)(GLenum face, GLenum pname, GLfloat param) +{ + DISPATCH(FragmentMaterialfSGIX, (face, pname, param), (F, ";")); +} + +KEYWORD1 void KEYWORD2 NAME(FragmentMaterialfvSGIX)(GLenum face, GLenum pname, const GLfloat * params) +{ + DISPATCH(FragmentMaterialfvSGIX, (face, pname, params), (F, ";")); +} + +KEYWORD1 void KEYWORD2 NAME(FragmentMaterialiSGIX)(GLenum face, GLenum pname, GLint param) +{ + DISPATCH(FragmentMaterialiSGIX, (face, pname, param), (F, ";")); +} + +KEYWORD1 void KEYWORD2 NAME(FragmentMaterialivSGIX)(GLenum face, GLenum pname, const GLint * params) +{ + DISPATCH(FragmentMaterialivSGIX, (face, pname, params), (F, ";")); +} + +KEYWORD1 void KEYWORD2 NAME(GetFragmentLightfvSGIX)(GLenum light, GLenum pname, GLfloat * params) +{ + DISPATCH(FragmentLightfvSGIX, (light, pname, params), (F, ";")); +} + +KEYWORD1 void KEYWORD2 NAME(GetFragmentLightivSGIX)(GLenum light, GLenum pname, GLint * params) +{ + DISPATCH(FragmentLightivSGIX, (light, pname, params), (F, ";")); +} + +KEYWORD1 void KEYWORD2 NAME(GetFragmentMaterialfvSGIX)(GLenum face, GLenum pname, GLfloat * params) +{ + DISPATCH(FragmentMaterialfvSGIX, (face, pname, params), (F, ";")); +} + +KEYWORD1 void KEYWORD2 NAME(GetFragmentMaterialivSGIX)(GLenum face, GLenum pname, GLint * params) +{ + DISPATCH(FragmentMaterialivSGIX, (face, pname, params), (F, ";")); +} + +KEYWORD1 void KEYWORD2 NAME(LightEnviSGIX)(GLenum pname, GLint param) +{ + DISPATCH(LightEnviSGIX, (pname, param), (F, ";")); +} + +/* 112. GL_EXT_draw_range_elements */ +KEYWORD1 void KEYWORD2 NAME(DrawRangeElementsEXT)(GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const GLvoid *indices) +{ + DISPATCH(DrawRangeElements, (mode, start, end, count, type, indices), (F, "glDrawRangeElementsEXT(0x%x, %u %u %d 0x%x %p);", mode, start, end, count, type, indices)); +} + +/* 117. GL_EXT_light_texture */ +#if 00 +KEYWORD1 void KEYWORD2 NAME(ApplyTextureEXT)(GLenum mode) +{ + DISPATCH(ApplyTextureEXT, (mode), (F, "glApplyTextureEXT(0x%x);", mode)); +} + +KEYWORD1 void KEYWORD2 NAME(TextureLightEXT)(GLenum pname) +{ + DISPATCH(TextureLightEXT, (pname), (F, "glTextureLightEXT(0x%x);", pname)); +} + +KEYWORD1 void KEYWORD2 NAME(TextureMaterialEXT)(GLenum face, GLenum mode) +{ + DISPATCH(TextureMaterialEXT, (face, mode), (F, "glTextureMaterialEXT(0x%x, 0x%x);", face, mode)); +} +#endif + +/* 135. GL_INTEL_texture_scissor */ +#if 00 +KEYWORD1 void KEYWORD2 NAME(TexScissorINTEL)(GLenum target, GLclampf tlow, GLclampf thigh) +{ + DISPATCH(TexScissorINTEL, (target, tlow, thigh), (F, "glTexScissorINTEL(0x%x %g %g);", target, tlow, thigh)); +} + +KEYWORD1 void KEYWORD2 NAME(TexScissorFuncINTEL)(GLenum target, GLenum lfunc, GLenum hfunc) +{ + DISPATCH(TexScissorFuncINTEL, (target, lfunc, hfunc), (F, "glTexScissorFuncINTEL(0x%x 0x%x 0x%x);", target, tlow, thigh)); +} +#endif + +/* 136. GL_INTEL_parallel_arrays */ +#if 00 +KEYWORD1 void KEYWORD2 NAME(VertexPointervINTEL)(GLint size, GLenum type, const void ** pointer) +{ + DISPATCH(VertexPointervINTEL, (size, type, pointer), (F, "glVertexPointervINTEL(%d, 0x%x, %p);", size, type, pointer)); +} + +KEYWORD1 void KEYWORD2 NAME(NormalPointervINTEL)(GLenum type, const void** pointer) +{ + DISPATCH(NormalPointervINTEL, (size, pointer), (F, "glNormalPointervINTEL(%d, %p);", size, pointer)); +} + +KEYWORD1 void KEYWORD2 NAME(ColorPointervINTEL)(GLint size, GLenum type, const void** pointer) +{ + DISPATCH(ColorPointervINTEL, (size, type, pointer), (F, "glColorPointervINTEL(%d, 0x%x, %p);", size, type, pointer)); +} + +KEYWORD1 void KEYWORD2 NAME(TexCoordPointervINTEL)(GLint size, GLenum type, const void** pointer) +{ + DISPATCH(TexCoordPointervINTEL, (size, type, pointer), (F, "glTexCoordPointervINTEL(%d, 0x%x, %p);", size, type, pointer)); +} +#endif + +/* 138. GL_EXT_pixel_transform */ +#if 00 +KEYWORD1 void KEYWORD2 NAME(PixelTransformParameteriEXT)(GLenum target, GLenum pname, const GLint param) +{ + DISPATCH(PixelTransformParameteriEXT, (target, pname, param), (F, "glPixelTransformParameteriEXT(0x%x, 0x%x, %d);", target, pname, param)); +} + +KEYWORD1 void KEYWORD2 NAME(PixelTransformParameterfEXT)(GLenum target, GLenum pname, const GLfloat param) +{ + DISPATCH(PixelTransformParameterfEXT, (target, pname, param), (F, "glPixelTransformParameterfEXT(0x%x, 0x%x, %f);", target, pname, param)); +} + +KEYWORD1 void KEYWORD2 NAME(PixelTransformParameterivEXT)(GLenum target, GLenum pname, const GLint *params) +{ + DISPATCH(PixelTransformParameterivEXT, (target, pname, params), (F, "glPixelTransformParameterivEXT(0x%x, 0x%x, %p);", target, pname, params)); +} + +KEYWORD1 void KEYWORD2 NAME(PixelTransformParameterfvEXT)(GLenum target, GLenum pname, const GLfloat *params) +{ + DISPATCH(PixelTransformParameterfvEXT, (target, pname, params), (F, "glPixelTransformParameterfvEXT(0x%x, 0x%x, %p);", target, pname, params)); +} + +KEYWORD1 void KEYWORD2 NAME(GetPixelTransformParameterivEXT)(GLenum target, GLenum pname, const GLint *params) +{ + DISPATCH(GetPixelTransformParameterivEXT, (target, pname, params), (F, "glGetPixelTransformParameterivEXT(0x%x, 0x%x, %p);", target, pname, params)); +} + +KEYWORD1 void KEYWORD2 NAME(GetPixelTransformParameterfvEXT)(GLenum target, GLenum pname, const GLfloat *params) +{ + DISPATCH(GetPixelTransformParameterfvEXT, (target, pname, params), (F, "glGetPixelTransformParameterfvEXT(0x%x, 0x%x, %p);", target, pname, params)); +} +#endif + +/* 145. GL_EXT_secondary_color */ +KEYWORD1 void KEYWORD2 NAME(SecondaryColorPointerEXT)(GLint size, GLenum type, GLsizei stride, const GLvoid * pointer) +{ + DISPATCH(SecondaryColorPointerEXT, (size, type, stride, pointer), (F, "glSecondaryColorPointerEXT(%d, 0x%x, %d, %p);", size, type, stride, pointer)); +} + +/* 149. GL_EXT_fog_coord */ +KEYWORD1 void KEYWORD2 NAME(FogCoordPointerEXT)(GLenum type, GLsizei stride, const GLvoid * pointer) +{ + DISPATCH(FogCoordPointerEXT, (type, stride, pointer), (F, "glFogCoordPointerEXT(0x%x, %d, %p);", type, stride, pointer)); +} + +/* 173. GL_EXT/INGR_blend_func_separate */ +KEYWORD1 void KEYWORD2 NAME(BlendFuncSeparateEXT)(GLenum sfactorRGB, GLenum dfactorRGB, GLenum sfactorAlpha, GLenum dfactorAlpha) +{ + DISPATCH(BlendFuncSeparateEXT, (sfactorRGB, dfactorRGB, sfactorAlpha, dfactorAlpha), (F, ";")); +} + +KEYWORD1 void KEYWORD2 NAME(BlendFuncSeparateINGR)(GLenum sfactorRGB, GLenum dfactorRGB, GLenum sfactorAlpha, GLenum dfactorAlpha) +{ + DISPATCH(BlendFuncSeparateEXT, (sfactorRGB, dfactorRGB, sfactorAlpha, dfactorAlpha), (F, ";")); +} + +/* 190. GL_NV_vertex_array_range */ +KEYWORD1 void KEYWORD2 NAME(FlushVertexArrayRangeNV)(void) +{ + DISPATCH(FlushVertexArrayRangeNV, (), (F, ";")); +} + +KEYWORD1 void KEYWORD2 NAME(VertexArrayRangeNV)(GLsizei size, const GLvoid * pointer) +{ + DISPATCH(VertexArrayRangeNV, (size, pointer), (F, ";")); +} + +/* 191. GL_NV_register_combiners */ +KEYWORD1 void KEYWORD2 NAME(CombinerParameterfvNV)(GLenum pname, const GLfloat * params) +{ + DISPATCH(CombinerParameterfvNV, (pname, params), (F, ";")); +} + +KEYWORD1 void KEYWORD2 NAME(CombinerParameterfNV)(GLenum pname, GLfloat param) +{ + DISPATCH(CombinerParameterfNV, (pname, param), (F, ";")); +} + +KEYWORD1 void KEYWORD2 NAME(CombinerParameterivNV)(GLenum pname, const GLint * params) +{ + DISPATCH(CombinerParameterivNV, (pname, params), (F, ";")); +} + +KEYWORD1 void KEYWORD2 NAME(CombinerParameteriNV)(GLenum pname, GLint param) +{ + DISPATCH(CombinerParameteriNV, (pname, param), (F, ";")); +} + +KEYWORD1 void KEYWORD2 NAME(CombinerInputNV)(GLenum stage, GLenum portion, GLenum variable, GLenum input, GLenum mapping, GLenum componentUsage) +{ + DISPATCH(CombinerInputNV, (stage, portion, variable, input, mapping, componentUsage), (F, ";")); +} + +KEYWORD1 void KEYWORD2 NAME(CombinerOutputNV)(GLenum stage, GLenum portion, GLenum abOutput, GLenum cdOutput, GLenum sumOutput, GLenum scale, GLenum bias, GLboolean abDotProduct, GLboolean cdDotProduct, GLboolean muxSum) +{ + DISPATCH(CombinerOutputNV, (stage, portion, abOutput, cdOutput, sumOutput, scale, bias, abDotProduct, cdDotProduct, muxSum), (F, ";")); +} + +KEYWORD1 void KEYWORD2 NAME(FinalCombinerInputNV)(GLenum variable, GLenum input, GLenum mapping, GLenum componentUsage) +{ + DISPATCH(FinalCombinerInputNV, (variable, input, mapping, componentUsage), (F, ";")); +} + +KEYWORD1 void KEYWORD2 NAME(GetCombinerInputParameterfvNV)(GLenum stage, GLenum portion, GLenum variable, GLenum pname, GLfloat * params) +{ + DISPATCH(GetCombinerInputParameterfvNV, (stage, portion, variable, pname, params), (F, ";")); +} + +KEYWORD1 void KEYWORD2 NAME(GetCombinerInputParameterivNV)(GLenum stage, GLenum portion, GLenum variable, GLenum pname, GLint * params) +{ + DISPATCH(GetCombinerInputParameterivNV, (stage, portion, variable, pname, params), (F, ";")); +} + +KEYWORD1 void KEYWORD2 NAME(GetCombinerOutputParameterfvNV)(GLenum stage, GLenum portion, GLenum pname, GLfloat * params) +{ + DISPATCH(GetCombinerOutputParameterfvNV, (stage, portion, pname, params), (F, ";")); +} + +KEYWORD1 void KEYWORD2 NAME(GetCombinerOutputParameterivNV)(GLenum stage, GLenum portion, GLenum pname, GLint * params) +{ + DISPATCH(GetCombinerOutputParameterivNV, (stage, portion, pname, params), (F, ";")); +} + +KEYWORD1 void KEYWORD2 NAME(GetFinalCombinerInputParameterfvNV)(GLenum variable, GLenum pname, GLfloat * params) +{ +DISPATCH(GetFinalCombinerInputParameterfvNV, (variable, pname, params), (F, ";")); +} + +KEYWORD1 void KEYWORD2 NAME(GetFinalCombinerInputParameterivNV)(GLenum variable, GLenum pname, GLint * params) +{ +DISPATCH(GetFinalCombinerInputParameterivNV, (variable, pname, params), (F, ";")); +} + +/* 194. GL_EXT_vertex_weighting */ +KEYWORD1 void KEYWORD2 NAME(VertexWeightfEXT)(GLfloat weight) +{ + DISPATCH(VertexWeightfEXT, (weight), (F, ";")); +} + +KEYWORD1 void KEYWORD2 NAME(VertexWeightfvEXT)(const GLfloat * weight) +{ + DISPATCH(VertexWeightfvEXT, (weight), (F, ";")); +} + +KEYWORD1 void KEYWORD2 NAME(VertexWeightPointerEXT)(GLsizei size, GLenum type, GLsizei stride, const GLvoid * pointer) +{ + DISPATCH(VertexWeightPointerEXT, (size, type, stride, pointer), (F, ";")); +} + +/* 196. GL_MESA_resize_buffers */ +KEYWORD1 void KEYWORD2 NAME(ResizeBuffersMESA)(void) +{ + DISPATCH(ResizeBuffersMESA, (), (F, "glResizeBuffersMESA();")); +} + +/* 197. GL_MESA_window_pos */ +KEYWORD1 void KEYWORD2 NAME(WindowPos2iMESA)(GLint x, GLint y) +{ + DISPATCH(WindowPos2iMESA, (x, y), (F, ";")); +} + +KEYWORD1 void KEYWORD2 NAME(WindowPos2sMESA)(GLshort x, GLshort y) +{ + DISPATCH(WindowPos2sMESA, (x, y), (F, ";")); +} + +KEYWORD1 void KEYWORD2 NAME(WindowPos2fMESA)(GLfloat x, GLfloat y) +{ + DISPATCH(WindowPos2fMESA, (x, y), (F, ";")); +} + +KEYWORD1 void KEYWORD2 NAME(WindowPos2dMESA)(GLdouble x, GLdouble y) +{ + DISPATCH(WindowPos2dMESA, (x, y), (F, ";")); +} + +KEYWORD1 void KEYWORD2 NAME(WindowPos2ivMESA)(const GLint *p) +{ + DISPATCH(WindowPos2ivMESA, (p), (F, ";")); +} + +KEYWORD1 void KEYWORD2 NAME(WindowPos2svMESA)(const GLshort *p) +{ + DISPATCH(WindowPos2svMESA, (p), (F, ";")); +} + +KEYWORD1 void KEYWORD2 NAME(WindowPos2fvMESA)(const GLfloat *p) +{ + DISPATCH(WindowPos2fvMESA, (p), (F, ";")); +} + +KEYWORD1 void KEYWORD2 NAME(WindowPos2dvMESA)(const GLdouble *p) +{ + DISPATCH(WindowPos2dvMESA, (p), (F, ";")); +} + +KEYWORD1 void KEYWORD2 NAME(WindowPos3iMESA)(GLint x, GLint y, GLint z) +{ + DISPATCH(WindowPos3iMESA, (x, y, z), (F, ";")); +} + +KEYWORD1 void KEYWORD2 NAME(WindowPos3sMESA)(GLshort x, GLshort y, GLshort z) +{ + DISPATCH(WindowPos3sMESA, (x, y, z), (F, ";")); +} + +KEYWORD1 void KEYWORD2 NAME(WindowPos3fMESA)(GLfloat x, GLfloat y, GLfloat z) +{ + DISPATCH(WindowPos3fMESA, (x, y, z), (F, ";")); +} + +KEYWORD1 void KEYWORD2 NAME(WindowPos3dMESA)(GLdouble x, GLdouble y, GLdouble z) +{ + DISPATCH(WindowPos3dMESA, (x, y, z), (F, ";")); +} + +KEYWORD1 void KEYWORD2 NAME(WindowPos3ivMESA)(const GLint *p) +{ + DISPATCH(WindowPos3ivMESA, (p), (F, ";")); +} + +KEYWORD1 void KEYWORD2 NAME(WindowPos3svMESA)(const GLshort *p) +{ + DISPATCH(WindowPos3svMESA, (p), (F, ";")); +} + +KEYWORD1 void KEYWORD2 NAME(WindowPos3fvMESA)(const GLfloat *p) +{ + DISPATCH(WindowPos3fvMESA, (p), (F, ";")); +} + +KEYWORD1 void KEYWORD2 NAME(WindowPos3dvMESA)(const GLdouble *p) +{ + DISPATCH(WindowPos3dvMESA, (p), (F, ";")); +} + +KEYWORD1 void KEYWORD2 NAME(WindowPos4iMESA)(GLint x, GLint y, GLint z, GLint w) +{ + DISPATCH(WindowPos4iMESA, (x, y, z, w), (F, ";")); +} + +KEYWORD1 void KEYWORD2 NAME(WindowPos4sMESA)(GLshort x, GLshort y, GLshort z, GLshort w) +{ + DISPATCH(WindowPos4sMESA, (x, y, z, w), (F, ";")); +} + +KEYWORD1 void KEYWORD2 NAME(WindowPos4fMESA)(GLfloat x, GLfloat y, GLfloat z, GLfloat w) +{ + DISPATCH(WindowPos4fMESA, (x, y, z, w), (F, ";")); +} + +KEYWORD1 void KEYWORD2 NAME(WindowPos4dMESA)(GLdouble x, GLdouble y, GLdouble z, GLdouble w) +{ + DISPATCH(WindowPos4dMESA, (x, y, z, w), (F, ";")); +} + +KEYWORD1 void KEYWORD2 NAME(WindowPos4ivMESA)(const GLint *p) +{ + DISPATCH(WindowPos4ivMESA, (p), (F, ";")); +} + +KEYWORD1 void KEYWORD2 NAME(WindowPos4svMESA)(const GLshort *p) +{ + DISPATCH(WindowPos4svMESA, (p), (F, ";")); +} + +KEYWORD1 void KEYWORD2 NAME(WindowPos4fvMESA)(const GLfloat *p) +{ + DISPATCH(WindowPos4fvMESA, (p), (F, ";")); +} + +KEYWORD1 void KEYWORD2 NAME(WindowPos4dvMESA)(const GLdouble *p) +{ + DISPATCH(WindowPos4dvMESA, (p), (F, ";")); +} + +/* 208. GL_3DFX_tbuffer */ +KEYWORD1 void KEYWORD2 NAME(TbufferMask3DFX)(GLuint mask) +{ + DISPATCH(TbufferMask3DFX, (mask), (F, "glTbufferMask3DFX(0x%x);", mask)); +} + +/* 209. WGL_EXT_multisample */ + +KEYWORD1 void KEYWORD2 NAME(SampleMaskEXT)(GLclampf value, GLboolean invert) +{ + DISPATCH(SampleMaskSGIS, (value, invert), (F, ";")); +} + +KEYWORD1 void KEYWORD2 NAME(SamplePatternEXT)(GLenum pattern) +{ + DISPATCH(SamplePatternSGIS, (pattern), (F, ";")); +} + +/* ARB 1. GL_ARB_multitexture */ + +KEYWORD1 void KEYWORD2 NAME(ActiveTextureARB)(GLenum texture) +{ + DISPATCH(ActiveTextureARB, (texture), (F, ";")); +} + +KEYWORD1 void KEYWORD2 NAME(ClientActiveTextureARB)(GLenum texture) +{ + DISPATCH(ClientActiveTextureARB, (texture), (F, ";")); +} + + +/* ARB 3. GL_ARB_transpose_matrix */ +KEYWORD1 void KEYWORD2 NAME(LoadTransposeMatrixdARB)(const GLdouble m[16]) +{ + DISPATCH(LoadTransposeMatrixdARB, (m), (F, "glLoadTransposeMatrixARB(%p);", m)); +} + +KEYWORD1 void KEYWORD2 NAME(LoadTransposeMatrixfARB)(const GLfloat m[16]) +{ + DISPATCH(LoadTransposeMatrixfARB, (m), (F, "glLoadTransposeMatrixfARB(%p)", m)); +} + +KEYWORD1 void KEYWORD2 NAME(MultTransposeMatrixdARB)(const GLdouble m[16]) +{ + DISPATCH(MultTransposeMatrixdARB, (m), (F, "glMultTransposeMatrixfARB(%p)", m)); +} + +KEYWORD1 void KEYWORD2 NAME(MultTransposeMatrixfARB)(const GLfloat m[16]) +{ + DISPATCH(MultTransposeMatrixfARB, (m), (F, "glLoadTransposeMatrixfARB(%p)", m)); +} + +/* ARB 5. GL_ARB_multisample */ +KEYWORD1 void KEYWORD2 NAME(SampleCoverageARB)(GLclampf value, GLboolean invert) +{ + DISPATCH(SampleCoverageARB, (value, invert), (F, "glSampleCoverageARB(%f, %d);", value, invert)); +} + +KEYWORD1 void KEYWORD2 NAME(SamplePassARB)(GLenum pass) +{ + DISPATCH(SamplePassARB, (pass), (F, "glSamplePassARB(0x%x);", pass)); +} + +/* ARB 12. GL_ARB_texture_compression */ +KEYWORD1 void KEYWORD2 NAME(CompressedTexImage3DARB)(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLsizei imageSize, const GLvoid *data) +{ + DISPATCH(CompressedTexImage3DARB, (target, level, internalformat, width, height, depth, border, imageSize, data), (F, "glCompressedTexImage3DARB();")); +} + +KEYWORD1 void KEYWORD2 NAME(CompressedTexImage2DARB)(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const GLvoid *data) +{ + DISPATCH(CompressedTexImage2DARB, (target, level, internalformat, width, height, border, imageSize, data), (F, "glCompressedTexImage2DARB();")); +} + +KEYWORD1 void KEYWORD2 NAME(CompressedTexImage1DARB)(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLint border, GLsizei imageSize, const GLvoid *data) +{ + DISPATCH(CompressedTexImage1DARB, (target, level, internalformat, width, border, imageSize, data), (F, "glCompressedTexImage1DARB();")); +} + +KEYWORD1 void KEYWORD2 NAME(CompressedTexSubImage3DARB)(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const GLvoid *data) +{ + DISPATCH(CompressedTexSubImage3DARB, (target, level, xoffset, yoffset, zoffset, width, height, depth, format, imageSize, data), (F, "glCompressedTexSubImage3DARB();")); +} + +KEYWORD1 void KEYWORD2 NAME(CompressedTexSubImage2DARB)(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const GLvoid *data) +{ + DISPATCH(CompressedTexSubImage2DARB, (target, level, xoffset, yoffset, width, height, format, imageSize, data), (F, "glCompressedTexSubImage2DARB();")); +} + +KEYWORD1 void KEYWORD2 NAME(CompressedTexSubImage1DARB)(GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLsizei imageSize, const GLvoid *data) +{ + DISPATCH(CompressedTexSubImage1DARB, (target, level, xoffset, width, format, imageSize, data), (F, "glCompressedTexSubImage1DARB();")); +} + +KEYWORD1 void KEYWORD2 NAME(GetCompressedTexImageARB)(GLenum target, GLint lod, GLvoid *img) +{ + DISPATCH(GetCompressedTexImageARB, (target, lod, img), (F, "glGetCompressedTexImageARB();")); +} + + + + +KEYWORD1 void KEYWORD2 NAME(Begin)(GLenum mode) +{ + DISPATCH(Begin, (mode), (F, "glBegin(0x%x);", mode)); +} + +KEYWORD1 void KEYWORD2 NAME(CallList)(GLuint list) +{ + DISPATCH(CallList, (list), (F, "glCallList(%u);", list)); +} + +KEYWORD1 void KEYWORD2 NAME(CallLists)(GLsizei n, GLenum type, const GLvoid *lists) +{ + DISPATCH(CallLists, (n, type, lists), (F, "glCallLists(%d, 0x%x, %p);", n, type, lists)); +} + +KEYWORD1 void KEYWORD2 NAME(Color3b)(GLbyte red, GLbyte green, GLbyte blue) +{ + DISPATCH(Color3b, (red, green, blue), (F, "glColor3b(%d, %d, %d);", red, green, blue)); +} + +KEYWORD1 void KEYWORD2 NAME(Color3d)(GLdouble red, GLdouble green, GLdouble blue) +{ + DISPATCH(Color3d, (red, green, blue), (F, "glColor3d(%g, %g, %g);", red, green, blue)); +} + +KEYWORD1 void KEYWORD2 NAME(Color3f)(GLfloat red, GLfloat green, GLfloat blue) +{ + DISPATCH(Color3f, (red, green, blue), (F, "glColor3f(%g, %g, %g);", red, green, blue)); +} + +KEYWORD1 void KEYWORD2 NAME(Color3i)(GLint red, GLint green, GLint blue) +{ + DISPATCH(Color3i, (red, green, blue), (F, "glColor3i(%d, %d, %d);", red, green, blue)); +} + +KEYWORD1 void KEYWORD2 NAME(Color3s)(GLshort red, GLshort green, GLshort blue) +{ + DISPATCH(Color3s, (red, green, blue), (F, "glColor3s(%d, %d, %d);", red, green, blue)); +} + +KEYWORD1 void KEYWORD2 NAME(Color3ub)(GLubyte red, GLubyte green, GLubyte blue) +{ + DISPATCH(Color3ub, (red, green, blue), (F, "glColor3ub(%u, %u, %u);", red, green, blue)); +} + +KEYWORD1 void KEYWORD2 NAME(Color3ui)(GLuint red, GLuint green, GLuint blue) +{ + DISPATCH(Color3ui, (red, green, blue), (F, "glColor3ui(%u, %u, %u);", red, green, blue)); +} + +KEYWORD1 void KEYWORD2 NAME(Color3us)(GLushort red, GLushort green, GLushort blue) +{ + DISPATCH(Color3us, (red, green, blue), (F, "glColor3us(%u, %u, %u);", red, green, blue)); +} + +KEYWORD1 void KEYWORD2 NAME(Color4b)(GLbyte red, GLbyte green, GLbyte blue, GLbyte alpha) +{ + DISPATCH(Color4b, (red, green, blue, alpha), (F, "glColor4b(%d, %d, %d, %d);", red, green, blue, alpha)); +} + +KEYWORD1 void KEYWORD2 NAME(Color4d)(GLdouble red, GLdouble green, GLdouble blue, GLdouble alpha) +{ + DISPATCH(Color4d, (red, green, blue, alpha), (F, "glColor4d(%g, %g, %g, %g);", red, green, blue, alpha)); +} + +KEYWORD1 void KEYWORD2 NAME(Color4f)(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha) +{ + DISPATCH(Color4f, (red, green, blue, alpha), (F, "glColor4b(%g, %g, %g, %g);", red, green, blue, alpha)); +} + +KEYWORD1 void KEYWORD2 NAME(Color4i)(GLint red, GLint green, GLint blue, GLint alpha) +{ + DISPATCH(Color4i, (red, green, blue, alpha), (F, "glColor4i(%d, %d, %d);", red, green, blue)); +} + +KEYWORD1 void KEYWORD2 NAME(Color4s)(GLshort red, GLshort green, GLshort blue, GLshort alpha) +{ + DISPATCH(Color4s, (red, green, blue, alpha), (F, "glColor4s(%d, %d, %d, %d);", red, green, blue, alpha)); +} + +KEYWORD1 void KEYWORD2 NAME(Color4ub)(GLubyte red, GLubyte green, GLubyte blue, GLubyte alpha) +{ + DISPATCH(Color4ub, (red, green, blue, alpha), (F, "glColor4ub(%u, %u, %u, %u);", red, green, blue, alpha)); +} + +KEYWORD1 void KEYWORD2 NAME(Color4ui)(GLuint red, GLuint green, GLuint blue, GLuint alpha) +{ + DISPATCH(Color4ui, (red, green, blue, alpha), (F, "glColor4ui(%u, %u, %u, %u);", red, green, blue, alpha)); +} + +KEYWORD1 void KEYWORD2 NAME(Color4us)(GLushort red, GLushort green, GLushort blue, GLushort alpha) +{ + DISPATCH(Color4us, (red, green, blue, alpha), (F, "glColor4us(%u, %u, %u, %u);", red, green, blue, alpha)); +} + +KEYWORD1 void KEYWORD2 NAME(Color3bv)(const GLbyte *v) +{ + DISPATCH(Color3bv, (v), (F, "glColor3bf(%p);", v)); +} + +KEYWORD1 void KEYWORD2 NAME(Color3dv)(const GLdouble *v) +{ + DISPATCH(Color3dv, (v), (F, "glColor3dv(%p);", v)); +} + +KEYWORD1 void KEYWORD2 NAME(Color3fv)(const GLfloat *v) +{ + DISPATCH(Color3fv, (v), (F, "glColor3fv(%p);", v)); +} + +KEYWORD1 void KEYWORD2 NAME(Color3iv)(const GLint *v) +{ + DISPATCH(Color3iv, (v), (F, "glColor3iv(%p);", v)); +} + +KEYWORD1 void KEYWORD2 NAME(Color3sv)(const GLshort *v) +{ + DISPATCH(Color3sv, (v), (F, "glColor3sv(%p);", v)); +} + +KEYWORD1 void KEYWORD2 NAME(Color3ubv)(const GLubyte *v) +{ + DISPATCH(Color3ubv, (v), (F, "glColor3ubv(%p);", v)); +} + +KEYWORD1 void KEYWORD2 NAME(Color3uiv)(const GLuint *v) +{ + DISPATCH(Color3uiv, (v), (F, "glColor3uiv(%p);", v)); +} + +KEYWORD1 void KEYWORD2 NAME(Color3usv)(const GLushort *v) +{ + DISPATCH(Color3usv, (v), (F, "glColor3usv(%p);", v)); +} + +KEYWORD1 void KEYWORD2 NAME(Color4bv)(const GLbyte *v) +{ + DISPATCH(Color4bv, (v), (F, "glColor3bv(%p);", v)); +} + +KEYWORD1 void KEYWORD2 NAME(Color4dv)(const GLdouble *v) +{ + DISPATCH(Color4dv, (v), (F, "glColor4dv(%p);", v)); +} + +KEYWORD1 void KEYWORD2 NAME(Color4fv)(const GLfloat *v) +{ + DISPATCH(Color4fv, (v), (F, "glColor4fv(%p);", v)); +} + +KEYWORD1 void KEYWORD2 NAME(Color4iv)(const GLint *v) +{ + DISPATCH(Color4iv, (v), (F, "glColor4iv(%p);", v)); +} + +KEYWORD1 void KEYWORD2 NAME(Color4sv)(const GLshort *v) +{ + DISPATCH(Color4sv, (v), (F, "glColor4sv(%p);", v)); +} + +KEYWORD1 void KEYWORD2 NAME(Color4ubv)(const GLubyte *v) +{ + DISPATCH(Color4ubv, (v), (F, "glColor4ubv(%p);", v)); +} + +KEYWORD1 void KEYWORD2 NAME(Color4uiv)(const GLuint *v) +{ + DISPATCH(Color4uiv, (v), (F, "glColor4uiv(%p);", v)); +} + +KEYWORD1 void KEYWORD2 NAME(Color4usv)(const GLushort *v) +{ + DISPATCH(Color4usv, (v), (F, "glColor4usv(%p);", v)); +} + +KEYWORD1 void KEYWORD2 NAME(End)(void) +{ + DISPATCH(End, (), (F, "glEnd();")); +} + +KEYWORD1 void KEYWORD2 NAME(EvalCoord1d)(GLdouble u) +{ + DISPATCH(EvalCoord1d, (u), (F, "glEvalCoord1d(%g);", u)); +} + +KEYWORD1 void KEYWORD2 NAME(EvalCoord1f)(GLfloat u) +{ + DISPATCH(EvalCoord1f, (u), (F, ";")); +} + +KEYWORD1 void KEYWORD2 NAME(EvalCoord1dv)(const GLdouble *u) +{ + DISPATCH(EvalCoord1dv, (u), (F, ";")); +} + +KEYWORD1 void KEYWORD2 NAME(EvalCoord1fv)(const GLfloat *u) +{ + DISPATCH(EvalCoord1fv, (u), (F, ";")); +} + +KEYWORD1 void KEYWORD2 NAME(EvalCoord2d)(GLdouble u, GLdouble v) +{ + DISPATCH(EvalCoord2d, (u, v), (F, ";")); +} + +KEYWORD1 void KEYWORD2 NAME(EvalCoord2f)(GLfloat u, GLfloat v) +{ + DISPATCH(EvalCoord2f, (u, v), (F, ";")); +} + +KEYWORD1 void KEYWORD2 NAME(EvalCoord2dv)(const GLdouble *u) +{ + DISPATCH(EvalCoord2dv, (u), (F, ";")); +} + +KEYWORD1 void KEYWORD2 NAME(EvalCoord2fv)(const GLfloat *u) +{ + DISPATCH(EvalCoord2fv, (u), (F, ";")); +} + +KEYWORD1 void KEYWORD2 NAME(EvalPoint1)(GLint i) +{ + DISPATCH(EvalPoint1, (i), (F, ";")); +} + +KEYWORD1 void KEYWORD2 NAME(EvalPoint2)(GLint i, GLint j) +{ + DISPATCH(EvalPoint2, (i, j), (F, ";")); +} + +KEYWORD1 void KEYWORD2 NAME(EdgeFlag)(GLboolean flag) +{ + DISPATCH(EdgeFlag, (flag), (F, ";")); +} + +KEYWORD1 void KEYWORD2 NAME(EdgeFlagv)(const GLboolean *flag) +{ + DISPATCH(EdgeFlagv, (flag), (F, ";")); +} + +KEYWORD1 void KEYWORD2 NAME(Indexd)(GLdouble c) +{ + DISPATCH(Indexd, (c), (F, ";")); +} + +KEYWORD1 void KEYWORD2 NAME(Indexdv)(const GLdouble *c) +{ + DISPATCH(Indexdv, (c), (F, ";")); +} + +KEYWORD1 void KEYWORD2 NAME(Indexf)(GLfloat c) +{ + DISPATCH(Indexf, (c), (F, ";")); +} + +KEYWORD1 void KEYWORD2 NAME(Indexfv)(const GLfloat *c) +{ + DISPATCH(Indexfv, (c), (F, ";")); +} + +KEYWORD1 void KEYWORD2 NAME(Indexi)(GLint c) +{ + DISPATCH(Indexi, (c), (F, ";")); +} + +KEYWORD1 void KEYWORD2 NAME(Indexiv)(const GLint *c) +{ + DISPATCH(Indexiv, (c), (F, ";")); +} + +KEYWORD1 void KEYWORD2 NAME(Indexs)(GLshort c) +{ + DISPATCH(Indexs, (c), (F, ";")); +} + +KEYWORD1 void KEYWORD2 NAME(Indexsv)(const GLshort *c) +{ + DISPATCH(Indexsv, (c), (F, ";")); +} + +KEYWORD1 void KEYWORD2 NAME(Materialf)(GLenum face, GLenum pname, GLfloat param) +{ + DISPATCH(Materialf, (face, pname, param), (F, ";")); +} + +KEYWORD1 void KEYWORD2 NAME(Materiali)(GLenum face, GLenum pname, GLint param) +{ + DISPATCH(Materiali, (face, pname, param), (F, ";")); +} + +KEYWORD1 void KEYWORD2 NAME(Materialfv)(GLenum face, GLenum pname, const GLfloat *params) +{ + DISPATCH(Materialfv, (face, pname, params), (F, ";")); +} + +KEYWORD1 void KEYWORD2 NAME(Materialiv)(GLenum face, GLenum pname, const GLint *params) +{ + DISPATCH(Materialiv, (face, pname, params), (F, ";")); +} + +KEYWORD1 void KEYWORD2 NAME(Normal3b)(GLbyte nx, GLbyte ny, GLbyte nz) +{ + DISPATCH(Normal3b, (nx, ny, nz), (F, "glNormal3b(%d, %d, %d);", nx, ny, nz)); +} + +KEYWORD1 void KEYWORD2 NAME(Normal3bv)(const GLbyte *v) +{ + DISPATCH(Normal3bv, (v), (F, "glNormal3bv(%p);", v)); +} + +KEYWORD1 void KEYWORD2 NAME(Normal3d)(GLdouble nx, GLdouble ny, GLdouble nz) +{ + DISPATCH(Normal3d, (nx, ny, nz), (F, "glNormal3d(%f, %f, %f);", nx, ny, nz)); +} + +KEYWORD1 void KEYWORD2 NAME(Normal3dv)(const GLdouble *v) +{ + DISPATCH(Normal3dv, (v), (F, "glNormal3dv(%p);", v)); +} + +KEYWORD1 void KEYWORD2 NAME(Normal3f)(GLfloat nx, GLfloat ny, GLfloat nz) +{ + DISPATCH(Normal3f, (nx, ny, nz), (F, "glNormal3f(%g, %g, %g);", nx, ny, nz)); +} + +KEYWORD1 void KEYWORD2 NAME(Normal3fv)(const GLfloat *v) +{ + DISPATCH(Normal3fv, (v), (F, "glNormal3fv(%p);", v)); +} + +KEYWORD1 void KEYWORD2 NAME(Normal3i)(GLint nx, GLint ny, GLint nz) +{ + DISPATCH(Normal3i, (nx, ny, nz), (F, "glNormal3i(%d, %d, %d);", nx, ny, nz)); +} + +KEYWORD1 void KEYWORD2 NAME(Normal3iv)(const GLint *v) +{ + DISPATCH(Normal3iv, (v), (F, "glNormal3iv(%p);", v)); +} + +KEYWORD1 void KEYWORD2 NAME(Normal3s)(GLshort nx, GLshort ny, GLshort nz) +{ + DISPATCH(Normal3s, (nx, ny, nz), (F, "glNormal3s(%d, %d, %d);", nx, ny, nz)); +} + +KEYWORD1 void KEYWORD2 NAME(Normal3sv)(const GLshort *v) +{ + DISPATCH(Normal3sv, (v), (F, "glNormal3sv(%p);", v)); +} + +KEYWORD1 void KEYWORD2 NAME(TexCoord1d)(GLdouble s) +{ + DISPATCH(TexCoord1d, (s), (F, ";")); +} + +KEYWORD1 void KEYWORD2 NAME(TexCoord1f)(GLfloat s) +{ + DISPATCH(TexCoord1f, (s), (F, ";")); +} + +KEYWORD1 void KEYWORD2 NAME(TexCoord1i)(GLint s) +{ + DISPATCH(TexCoord1i, (s), (F, ";")); +} + +KEYWORD1 void KEYWORD2 NAME(TexCoord1s)(GLshort s) +{ + DISPATCH(TexCoord1s, (s), (F, ";")); +} + +KEYWORD1 void KEYWORD2 NAME(TexCoord2d)(GLdouble s, GLdouble t) +{ + DISPATCH(TexCoord2d, (s, t), (F, ";")); +} + +KEYWORD1 void KEYWORD2 NAME(TexCoord2f)(GLfloat s, GLfloat t) +{ + DISPATCH(TexCoord2f, (s, t), (F, ";")); +} + +KEYWORD1 void KEYWORD2 NAME(TexCoord2s)(GLshort s, GLshort t) +{ + DISPATCH(TexCoord2s, (s, t), (F, ";")); +} + +KEYWORD1 void KEYWORD2 NAME(TexCoord2i)(GLint s, GLint t) +{ + DISPATCH(TexCoord2i, (s, t), (F, ";")); +} + +KEYWORD1 void KEYWORD2 NAME(TexCoord3d)(GLdouble s, GLdouble t, GLdouble r) +{ + DISPATCH(TexCoord3d, (s, t, r), (F, ";")); +} + +KEYWORD1 void KEYWORD2 NAME(TexCoord3f)(GLfloat s, GLfloat t, GLfloat r) +{ + DISPATCH(TexCoord3f, (s, t, r), (F, ";")); +} + +KEYWORD1 void KEYWORD2 NAME(TexCoord3i)(GLint s, GLint t, GLint r) +{ + DISPATCH(TexCoord3i, (s, t, r), (F, ";")); +} + +KEYWORD1 void KEYWORD2 NAME(TexCoord3s)(GLshort s, GLshort t, GLshort r) +{ + DISPATCH(TexCoord3s, (s, t, r), (F, ";")); +} + +KEYWORD1 void KEYWORD2 NAME(TexCoord4d)(GLdouble s, GLdouble t, GLdouble r, GLdouble q) +{ + DISPATCH(TexCoord4d, (s, t, r, q), (F, ";")); +} + +KEYWORD1 void KEYWORD2 NAME(TexCoord4f)(GLfloat s, GLfloat t, GLfloat r, GLfloat q) +{ + DISPATCH(TexCoord4f, (s, t, r, q), (F, ";")); +} + +KEYWORD1 void KEYWORD2 NAME(TexCoord4i)(GLint s, GLint t, GLint r, GLint q) +{ + DISPATCH(TexCoord4i, (s, t, r, q), (F, ";")); +} + +KEYWORD1 void KEYWORD2 NAME(TexCoord4s)(GLshort s, GLshort t, GLshort r, GLshort q) +{ + DISPATCH(TexCoord4s, (s, t, r, q), (F, ";")); +} + +KEYWORD1 void KEYWORD2 NAME(TexCoord1dv)(const GLdouble *v) +{ + DISPATCH(TexCoord1dv, (v), (F, ";")); +} + +KEYWORD1 void KEYWORD2 NAME(TexCoord1fv)(const GLfloat *v) +{ + DISPATCH(TexCoord1fv, (v), (F, ";")); +} + +KEYWORD1 void KEYWORD2 NAME(TexCoord1iv)(const GLint *v) +{ + DISPATCH(TexCoord1iv, (v), (F, ";")); +} + +KEYWORD1 void KEYWORD2 NAME(TexCoord1sv)(const GLshort *v) +{ + DISPATCH(TexCoord1sv, (v), (F, ";")); +} + +KEYWORD1 void KEYWORD2 NAME(TexCoord2dv)(const GLdouble *v) +{ + DISPATCH(TexCoord2dv, (v), (F, ";")); +} + +KEYWORD1 void KEYWORD2 NAME(TexCoord2fv)(const GLfloat *v) +{ + DISPATCH(TexCoord2fv, (v), (F, ";")); +} + +KEYWORD1 void KEYWORD2 NAME(TexCoord2iv)(const GLint *v) +{ + DISPATCH(TexCoord2iv, (v), (F, ";")); +} + +KEYWORD1 void KEYWORD2 NAME(TexCoord2sv)(const GLshort *v) +{ + DISPATCH(TexCoord2sv, (v), (F, ";")); +} + +KEYWORD1 void KEYWORD2 NAME(TexCoord3dv)(const GLdouble *v) +{ + DISPATCH(TexCoord3dv, (v), (F, ";")); +} + +KEYWORD1 void KEYWORD2 NAME(TexCoord3fv)(const GLfloat *v) +{ + DISPATCH(TexCoord3fv, (v), (F, ";")); +} + +KEYWORD1 void KEYWORD2 NAME(TexCoord3iv)(const GLint *v) +{ + DISPATCH(TexCoord3iv, (v), (F, ";")); +} + +KEYWORD1 void KEYWORD2 NAME(TexCoord3sv)(const GLshort *v) +{ + DISPATCH(TexCoord3sv, (v), (F, ";")); +} + +KEYWORD1 void KEYWORD2 NAME(TexCoord4dv)(const GLdouble *v) +{ + DISPATCH(TexCoord4dv, (v), (F, ";")); +} + +KEYWORD1 void KEYWORD2 NAME(TexCoord4fv)(const GLfloat *v) +{ + DISPATCH(TexCoord4fv, (v), (F, ";")); +} + +KEYWORD1 void KEYWORD2 NAME(TexCoord4iv)(const GLint *v) +{ + DISPATCH(TexCoord4iv, (v), (F, ";")); +} + +KEYWORD1 void KEYWORD2 NAME(TexCoord4sv)(const GLshort *v) +{ + DISPATCH(TexCoord4sv, (v), (F, ";")); +} + +KEYWORD1 void KEYWORD2 NAME(Vertex2d)(GLdouble x, GLdouble y) +{ + DISPATCH(Vertex2d, (x, y), (F, "glVertex2d(%f, %f);", x, y)); +} + +KEYWORD1 void KEYWORD2 NAME(Vertex2dv)(const GLdouble *v) +{ + DISPATCH(Vertex2dv, (v), (F, "glVertex2dv(%p);", v)); +} + +KEYWORD1 void KEYWORD2 NAME(Vertex2f)(GLfloat x, GLfloat y) +{ + DISPATCH(Vertex2f, (x, y), (F, "glVertex2f(%g, %g);", x, y)); +} + +KEYWORD1 void KEYWORD2 NAME(Vertex2fv)(const GLfloat *v) +{ + DISPATCH(Vertex2fv, (v), (F, "glVertex2fv(%p);", v)); +} + +KEYWORD1 void KEYWORD2 NAME(Vertex2i)(GLint x, GLint y) +{ + DISPATCH(Vertex2i, (x, y), (F, "glVertex2i(%d, %d);", x, y)); +} + +KEYWORD1 void KEYWORD2 NAME(Vertex2iv)(const GLint *v) +{ + DISPATCH(Vertex2iv, (v), (F, "glVertex2iv(%p);", v)); +} + +KEYWORD1 void KEYWORD2 NAME(Vertex2s)(GLshort x, GLshort y) +{ + DISPATCH(Vertex2s, (x, y), (F, "glVertex2s(%d, %d);", x, y)); +} + +KEYWORD1 void KEYWORD2 NAME(Vertex2sv)(const GLshort *v) +{ + DISPATCH(Vertex2sv, (v), (F, "glVertex2sv(%p);", v)); +} + +KEYWORD1 void KEYWORD2 NAME(Vertex3d)(GLdouble x, GLdouble y, GLdouble z) +{ + DISPATCH(Vertex3d, (x, y, z), (F, "glVertex3d(%f, %f, %f);", x, y, z)); +} + +KEYWORD1 void KEYWORD2 NAME(Vertex3dv)(const GLdouble *v) +{ + DISPATCH(Vertex3dv, (v), (F, "glVertex3dv(%p);", v)); +} + +KEYWORD1 void KEYWORD2 NAME(Vertex3f)(GLfloat x, GLfloat y, GLfloat z) +{ + DISPATCH(Vertex3f, (x, y, z), (F, "glVertex3f(%g, %g, %g);", x, y, z)); +} + +KEYWORD1 void KEYWORD2 NAME(Vertex3fv)(const GLfloat *v) +{ + DISPATCH(Vertex3fv, (v), (F, "glVertex3fv(%p);", v)); +} + +KEYWORD1 void KEYWORD2 NAME(Vertex3i)(GLint x, GLint y, GLint z) +{ + DISPATCH(Vertex3i, (x, y, z), (F, "glVertex3i(%d, %d, %d);", x, y, z)); +} + +KEYWORD1 void KEYWORD2 NAME(Vertex3iv)(const GLint *v) +{ + DISPATCH(Vertex3iv, (v), (F, "glVertex3iv(%p);", v)); +} + +KEYWORD1 void KEYWORD2 NAME(Vertex3s)(GLshort x, GLshort y, GLshort z) +{ + DISPATCH(Vertex3s, (x, y, z), (F, "glVertex3s(%d, %d, %d);", x, y, z)); +} + +KEYWORD1 void KEYWORD2 NAME(Vertex3sv)(const GLshort *v) +{ + DISPATCH(Vertex3sv, (v), (F, "glVertex3sv(%p);", v)); +} + +KEYWORD1 void KEYWORD2 NAME(Vertex4d)(GLdouble x, GLdouble y, GLdouble z, GLdouble w) +{ + DISPATCH(Vertex4d, (x, y, z, w), (F, "glVertex4d(%f, %f, %f, %f);", x, y, z, w)); +} + +KEYWORD1 void KEYWORD2 NAME(Vertex4dv)(const GLdouble *v) +{ + DISPATCH(Vertex4dv, (v), (F, "glVertex4dv(%p);", v)); +} + +KEYWORD1 void KEYWORD2 NAME(Vertex4f)(GLfloat x, GLfloat y, GLfloat z, GLfloat w) +{ + DISPATCH(Vertex4f, (x, y, z, w), (F, "glVertex4f(%f, %f, %f, %f);", x, y, z, w)); +} + +KEYWORD1 void KEYWORD2 NAME(Vertex4fv)(const GLfloat *v) +{ + DISPATCH(Vertex4fv, (v), (F, "glVertex4fv(%p);", v)); +} + +KEYWORD1 void KEYWORD2 NAME(Vertex4i)(GLint x, GLint y, GLint z, GLint w) +{ + DISPATCH(Vertex4i, (x, y, z, w), (F, "glVertex4i(%d, %d, %d, %d);", x, y, z, w)); +} + +KEYWORD1 void KEYWORD2 NAME(Vertex4iv)(const GLint *v) +{ + DISPATCH(Vertex4iv, (v), (F, "glVertex4iv(%p);", v)); +} + +KEYWORD1 void KEYWORD2 NAME(Vertex4s)(GLshort x, GLshort y, GLshort z, GLshort w) +{ + DISPATCH(Vertex4s, (x, y, z, w), (F, "glVertex4s(%d, %d, %d, %d);", x, y, z, w)); +} + +KEYWORD1 void KEYWORD2 NAME(Vertex4sv)(const GLshort *v) +{ + DISPATCH(Vertex4sv, (v), (F, "glVertex4sv(%p);", v)); +} + +KEYWORD1 void KEYWORD2 NAME(Indexub)(GLubyte c) +{ + DISPATCH(Indexub, (c), (F, ";")); +} + +KEYWORD1 void KEYWORD2 NAME(Indexubv)(const GLubyte *c) +{ + DISPATCH(Indexubv, (c), (F, ";")); +} + +KEYWORD1 void KEYWORD2 NAME(ArrayElementEXT)(GLint i) +{ + DISPATCH(ArrayElement, (i), (F, ";")); +} + +KEYWORD1 void KEYWORD2 NAME(SecondaryColor3bEXT)(GLbyte red, GLbyte green, GLbyte blue) +{ + DISPATCH(SecondaryColor3bEXT, (red, green, blue), (F, "glSecondaryColor3bEXT(%d, %d, %d);", red, green, blue)); +} + +KEYWORD1 void KEYWORD2 NAME(SecondaryColor3bvEXT)(const GLbyte *v) +{ + DISPATCH(SecondaryColor3bvEXT, (v), (F, "glSecondaryColor3bvEXT(%d, %d, %d);", v[0], v[1], v[2])); +} + +KEYWORD1 void KEYWORD2 NAME(SecondaryColor3dEXT)(GLdouble red, GLdouble green, GLdouble blue) +{ + DISPATCH(SecondaryColor3dEXT, (red, green, blue), (F, "glSecondaryColor3dEXT(%g, %g, %g);", red, green, blue)); +} + +KEYWORD1 void KEYWORD2 NAME(SecondaryColor3dvEXT)(const GLdouble * v) +{ + DISPATCH(SecondaryColor3dvEXT, (v), (F, "glSecondaryColor3dvEXT(%g, %g, %g);", v[0], v[1], v[2])); +} + +KEYWORD1 void KEYWORD2 NAME(SecondaryColor3fEXT)(GLfloat red, GLfloat green, GLfloat blue) +{ + DISPATCH(SecondaryColor3fEXT, (red, green, blue), (F, "glSecondaryColor3fEXT(%g, %g, %g);", red, green, blue)); +} + +KEYWORD1 void KEYWORD2 NAME(SecondaryColor3fvEXT)(const GLfloat * v) +{ + DISPATCH(SecondaryColor3fvEXT, (v), (F, "glSecondaryColor3fvEXT(%g, %g, %g);", v[0], v[1], v[2])); +} + +KEYWORD1 void KEYWORD2 NAME(SecondaryColor3iEXT)(GLint red, GLint green, GLint blue) +{ + DISPATCH(SecondaryColor3iEXT, (red, green, blue), (F, "glSecondaryColor3iEXT(%d, %d, %d);", red, green, blue)); +} + +KEYWORD1 void KEYWORD2 NAME(SecondaryColor3ivEXT)(const GLint * v) +{ + DISPATCH(SecondaryColor3ivEXT, (v), (F, "glSecondaryColor3ivEXT(%d, %d, %d);", v[0], v[1], v[2])); +} + +KEYWORD1 void KEYWORD2 NAME(SecondaryColor3sEXT)(GLshort red, GLshort green, GLshort blue) +{ + DISPATCH(SecondaryColor3sEXT, (red, green, blue), (F, "glSecondaryColor3sEXT(%d, %d, %d);", red, green, blue)); +} + +KEYWORD1 void KEYWORD2 NAME(SecondaryColor3svEXT)(const GLshort * v) +{ + DISPATCH(SecondaryColor3svEXT, (v), (F, "glSecondaryColor3svEXT(%d, %d, %d);", v[0], v[1], v[2])); +} + +KEYWORD1 void KEYWORD2 NAME(SecondaryColor3ubEXT)(GLubyte red, GLubyte green, GLubyte blue) +{ + DISPATCH(SecondaryColor3ubEXT, (red, green, blue), (F, "glSecondaryColor3ubEXT(%d, %d, %d);", red, green, blue)); +} + +KEYWORD1 void KEYWORD2 NAME(SecondaryColor3ubvEXT)(const GLubyte * v) +{ + DISPATCH(SecondaryColor3ubvEXT, (v), (F, "glSecondaryColor3ubvEXT(%d, %d, %d);", v[0], v[1], v[2])); +} + +KEYWORD1 void KEYWORD2 NAME(SecondaryColor3uiEXT)(GLuint red, GLuint green, GLuint blue) +{ + DISPATCH(SecondaryColor3uiEXT, (red, green, blue), (F, "glSecondaryColor3uiEXT(%d, %d, %d);", red, green, blue)); +} + +KEYWORD1 void KEYWORD2 NAME(SecondaryColor3uivEXT)(const GLuint * v) +{ + DISPATCH(SecondaryColor3uivEXT, (v), (F, "glSecondaryColor3uivEXT(%d, %d, %d);", v[0], v[1], v[2])); +} + +KEYWORD1 void KEYWORD2 NAME(SecondaryColor3usEXT)(GLushort red, GLushort green, GLushort blue) +{ + DISPATCH(SecondaryColor3usEXT, (red, green, blue), (F, "glSecondaryColor3usEXT(%d, %d, %d);", red, green, blue)); +} + +KEYWORD1 void KEYWORD2 NAME(SecondaryColor3usvEXT)(const GLushort * v) +{ + DISPATCH(SecondaryColor3usvEXT, (v), (F, "glSecondaryColor3usvEXT(%d, %d, %d);", v[0], v[1], v[2])); +} + +KEYWORD1 void KEYWORD2 NAME(FogCoordfEXT)(GLfloat coord) +{ + DISPATCH(FogCoordfEXT, (coord), (F, "glFogCoordfEXT(%g);", coord)); +} + +KEYWORD1 void KEYWORD2 NAME(FogCoordfvEXT)(const GLfloat * coord) +{ + DISPATCH(FogCoordfvEXT, (coord), (F, "glFogCoordfvEXT(%p);", coord)); +} + +KEYWORD1 void KEYWORD2 NAME(FogCoorddEXT)(GLdouble coord) +{ + DISPATCH(FogCoorddEXT, (coord), (F, "glFogCoorddEXT(%g);", coord)); +} + +KEYWORD1 void KEYWORD2 NAME(FogCoorddvEXT)(const GLdouble * coord) +{ + DISPATCH(FogCoorddvEXT, (coord), (F, "glFogCoorddvEXT(%p);", coord)); +} + +KEYWORD1 void KEYWORD2 NAME(MultiTexCoord1dARB)(GLenum target, GLdouble s) +{ + DISPATCH(MultiTexCoord1dARB, (target, s), (F, ";")); +} + +KEYWORD1 void KEYWORD2 NAME(MultiTexCoord1dvARB)(GLenum target, const GLdouble *v) +{ + DISPATCH(MultiTexCoord1dvARB, (target, v), (F, ";")); +} + +KEYWORD1 void KEYWORD2 NAME(MultiTexCoord1fARB)(GLenum target, GLfloat s) +{ + DISPATCH(MultiTexCoord1fARB, (target, s), (F, ";")); +} + +KEYWORD1 void KEYWORD2 NAME(MultiTexCoord1fvARB)(GLenum target, const GLfloat *v) +{ + DISPATCH(MultiTexCoord1fvARB, (target, v), (F, ";")); +} + +KEYWORD1 void KEYWORD2 NAME(MultiTexCoord1iARB)(GLenum target, GLint s) +{ + DISPATCH(MultiTexCoord1iARB, (target, s), (F, ";")); +} + +KEYWORD1 void KEYWORD2 NAME(MultiTexCoord1ivARB)(GLenum target, const GLint *v) +{ + DISPATCH(MultiTexCoord1ivARB, (target, v), (F, ";")); +} + +KEYWORD1 void KEYWORD2 NAME(MultiTexCoord1sARB)(GLenum target, GLshort s) +{ + DISPATCH(MultiTexCoord1sARB, (target, s), (F, ";")); +} + +KEYWORD1 void KEYWORD2 NAME(MultiTexCoord1svARB)(GLenum target, const GLshort *v) +{ + DISPATCH(MultiTexCoord1svARB, (target, v), (F, ";")); +} + +KEYWORD1 void KEYWORD2 NAME(MultiTexCoord2dARB)(GLenum target, GLdouble s, GLdouble t) +{ + DISPATCH(MultiTexCoord2dARB, (target, s, t), (F, ";")); +} + +KEYWORD1 void KEYWORD2 NAME(MultiTexCoord2dvARB)(GLenum target, const GLdouble *v) +{ + DISPATCH(MultiTexCoord2dvARB, (target, v), (F, ";")); +} + +KEYWORD1 void KEYWORD2 NAME(MultiTexCoord2fARB)(GLenum target, GLfloat s, GLfloat t) +{ + DISPATCH(MultiTexCoord2fARB, (target, s, t), (F, ";")); +} + +KEYWORD1 void KEYWORD2 NAME(MultiTexCoord2fvARB)(GLenum target, const GLfloat *v) +{ + DISPATCH(MultiTexCoord2fvARB, (target, v), (F, ";")); +} + +KEYWORD1 void KEYWORD2 NAME(MultiTexCoord2iARB)(GLenum target, GLint s, GLint t) +{ + DISPATCH(MultiTexCoord2iARB, (target, s, t), (F, ";")); +} + +KEYWORD1 void KEYWORD2 NAME(MultiTexCoord2ivARB)(GLenum target, const GLint *v) +{ + DISPATCH(MultiTexCoord2ivARB, (target, v), (F, ";")); +} + +KEYWORD1 void KEYWORD2 NAME(MultiTexCoord2sARB)(GLenum target, GLshort s, GLshort t) +{ + DISPATCH(MultiTexCoord2sARB, (target, s, t), (F, ";")); +} + +KEYWORD1 void KEYWORD2 NAME(MultiTexCoord2svARB)(GLenum target, const GLshort *v) +{ + DISPATCH(MultiTexCoord2svARB, (target, v), (F, ";")); +} + +KEYWORD1 void KEYWORD2 NAME(MultiTexCoord3dARB)(GLenum target, GLdouble s, GLdouble t, GLdouble r) +{ + DISPATCH(MultiTexCoord3dARB, (target, s, t, r), (F, ";")); +} + +KEYWORD1 void KEYWORD2 NAME(MultiTexCoord3dvARB)(GLenum target, const GLdouble *v) +{ + DISPATCH(MultiTexCoord3dvARB, (target, v), (F, ";")); +} + +KEYWORD1 void KEYWORD2 NAME(MultiTexCoord3fARB)(GLenum target, GLfloat s, GLfloat t, GLfloat r) +{ + DISPATCH(MultiTexCoord3fARB, (target, s, t, r), (F, ";")); +} + +KEYWORD1 void KEYWORD2 NAME(MultiTexCoord3fvARB)(GLenum target, const GLfloat *v) +{ + DISPATCH(MultiTexCoord3fvARB, (target, v), (F, ";")); +} + +KEYWORD1 void KEYWORD2 NAME(MultiTexCoord3iARB)(GLenum target, GLint s, GLint t, GLint r) +{ + DISPATCH(MultiTexCoord3iARB, (target, s, t, r), (F, ";")); +} + +KEYWORD1 void KEYWORD2 NAME(MultiTexCoord3ivARB)(GLenum target, const GLint *v) +{ + DISPATCH(MultiTexCoord3ivARB, (target, v), (F, ";")); +} + +KEYWORD1 void KEYWORD2 NAME(MultiTexCoord3sARB)(GLenum target, GLshort s, GLshort t, GLshort r) +{ + DISPATCH(MultiTexCoord3sARB, (target, s, t, r), (F, ";")); +} + +KEYWORD1 void KEYWORD2 NAME(MultiTexCoord3svARB)(GLenum target, const GLshort *v) +{ + DISPATCH(MultiTexCoord3svARB, (target, v), (F, ";")); +} + +KEYWORD1 void KEYWORD2 NAME(MultiTexCoord4dARB)(GLenum target, GLdouble s, GLdouble t, GLdouble r, GLdouble q) +{ + DISPATCH(MultiTexCoord4dARB, (target, s, t, r, q), (F, ";")); +} + +KEYWORD1 void KEYWORD2 NAME(MultiTexCoord4dvARB)(GLenum target, const GLdouble *v) +{ + DISPATCH(MultiTexCoord4dvARB, (target, v), (F, ";")); +} + +KEYWORD1 void KEYWORD2 NAME(MultiTexCoord4fARB)(GLenum target, GLfloat s, GLfloat t, GLfloat r, GLfloat q) +{ + DISPATCH(MultiTexCoord4fARB, (target, s, t, r, q), (F, ";")); +} + +KEYWORD1 void KEYWORD2 NAME(MultiTexCoord4fvARB)(GLenum target, const GLfloat *v) +{ + DISPATCH(MultiTexCoord4fvARB, (target, v), (F, ";")); +} + +KEYWORD1 void KEYWORD2 NAME(MultiTexCoord4iARB)(GLenum target, GLint s, GLint t, GLint r, GLint q) +{ + DISPATCH(MultiTexCoord4iARB, (target, s, t, r, q), (F, ";")); +} + +KEYWORD1 void KEYWORD2 NAME(MultiTexCoord4ivARB)(GLenum target, const GLint *v) +{ + DISPATCH(MultiTexCoord4ivARB, (target, v), (F, ";")); +} + +KEYWORD1 void KEYWORD2 NAME(MultiTexCoord4sARB)(GLenum target, GLshort s, GLshort t, GLshort r, GLshort q) +{ + DISPATCH(MultiTexCoord4sARB, (target, s, t, r, q), (F, ";")); +} + +KEYWORD1 void KEYWORD2 NAME(MultiTexCoord4svARB)(GLenum target, const GLshort *v) +{ + DISPATCH(MultiTexCoord4svARB, (target, v), (F, ";")); +} + +#endif // NO_FUNCTIONS + +#ifdef DISPATCH_TABLE_NAME + +#ifndef TABLE_ENTRY +#error TABLE_ENTRY must be defined +#endif + +void *DISPATCH_TABLE_NAME[] = { + TABLE_ENTRY(NewList), + TABLE_ENTRY(EndList), + TABLE_ENTRY(CallList), + TABLE_ENTRY(CallLists), + TABLE_ENTRY(DeleteLists), + TABLE_ENTRY(GenLists), + TABLE_ENTRY(ListBase), + TABLE_ENTRY(Begin), + TABLE_ENTRY(Bitmap), + TABLE_ENTRY(Color3b), + TABLE_ENTRY(Color3bv), + TABLE_ENTRY(Color3d), + TABLE_ENTRY(Color3dv), + TABLE_ENTRY(Color3f), + TABLE_ENTRY(Color3fv), + TABLE_ENTRY(Color3i), + TABLE_ENTRY(Color3iv), + TABLE_ENTRY(Color3s), + TABLE_ENTRY(Color3sv), + TABLE_ENTRY(Color3ub), + TABLE_ENTRY(Color3ubv), + TABLE_ENTRY(Color3ui), + TABLE_ENTRY(Color3uiv), + TABLE_ENTRY(Color3us), + TABLE_ENTRY(Color3usv), + TABLE_ENTRY(Color4b), + TABLE_ENTRY(Color4bv), + TABLE_ENTRY(Color4d), + TABLE_ENTRY(Color4dv), + TABLE_ENTRY(Color4f), + TABLE_ENTRY(Color4fv), + TABLE_ENTRY(Color4i), + TABLE_ENTRY(Color4iv), + TABLE_ENTRY(Color4s), + TABLE_ENTRY(Color4sv), + TABLE_ENTRY(Color4ub), + TABLE_ENTRY(Color4ubv), + TABLE_ENTRY(Color4ui), + TABLE_ENTRY(Color4uiv), + TABLE_ENTRY(Color4us), + TABLE_ENTRY(Color4usv), + TABLE_ENTRY(EdgeFlag), + TABLE_ENTRY(EdgeFlagv), + TABLE_ENTRY(End), + TABLE_ENTRY(Indexd), + TABLE_ENTRY(Indexdv), + TABLE_ENTRY(Indexf), + TABLE_ENTRY(Indexfv), + TABLE_ENTRY(Indexi), + TABLE_ENTRY(Indexiv), + TABLE_ENTRY(Indexs), + TABLE_ENTRY(Indexsv), + TABLE_ENTRY(Normal3b), + TABLE_ENTRY(Normal3bv), + TABLE_ENTRY(Normal3d), + TABLE_ENTRY(Normal3dv), + TABLE_ENTRY(Normal3f), + TABLE_ENTRY(Normal3fv), + TABLE_ENTRY(Normal3i), + TABLE_ENTRY(Normal3iv), + TABLE_ENTRY(Normal3s), + TABLE_ENTRY(Normal3sv), + TABLE_ENTRY(RasterPos2d), + TABLE_ENTRY(RasterPos2dv), + TABLE_ENTRY(RasterPos2f), + TABLE_ENTRY(RasterPos2fv), + TABLE_ENTRY(RasterPos2i), + TABLE_ENTRY(RasterPos2iv), + TABLE_ENTRY(RasterPos2s), + TABLE_ENTRY(RasterPos2sv), + TABLE_ENTRY(RasterPos3d), + TABLE_ENTRY(RasterPos3dv), + TABLE_ENTRY(RasterPos3f), + TABLE_ENTRY(RasterPos3fv), + TABLE_ENTRY(RasterPos3i), + TABLE_ENTRY(RasterPos3iv), + TABLE_ENTRY(RasterPos3s), + TABLE_ENTRY(RasterPos3sv), + TABLE_ENTRY(RasterPos4d), + TABLE_ENTRY(RasterPos4dv), + TABLE_ENTRY(RasterPos4f), + TABLE_ENTRY(RasterPos4fv), + TABLE_ENTRY(RasterPos4i), + TABLE_ENTRY(RasterPos4iv), + TABLE_ENTRY(RasterPos4s), + TABLE_ENTRY(RasterPos4sv), + TABLE_ENTRY(Rectd), + TABLE_ENTRY(Rectdv), + TABLE_ENTRY(Rectf), + TABLE_ENTRY(Rectfv), + TABLE_ENTRY(Recti), + TABLE_ENTRY(Rectiv), + TABLE_ENTRY(Rects), + TABLE_ENTRY(Rectsv), + TABLE_ENTRY(TexCoord1d), + TABLE_ENTRY(TexCoord1dv), + TABLE_ENTRY(TexCoord1f), + TABLE_ENTRY(TexCoord1fv), + TABLE_ENTRY(TexCoord1i), + TABLE_ENTRY(TexCoord1iv), + TABLE_ENTRY(TexCoord1s), + TABLE_ENTRY(TexCoord1sv), + TABLE_ENTRY(TexCoord2d), + TABLE_ENTRY(TexCoord2dv), + TABLE_ENTRY(TexCoord2f), + TABLE_ENTRY(TexCoord2fv), + TABLE_ENTRY(TexCoord2i), + TABLE_ENTRY(TexCoord2iv), + TABLE_ENTRY(TexCoord2s), + TABLE_ENTRY(TexCoord2sv), + TABLE_ENTRY(TexCoord3d), + TABLE_ENTRY(TexCoord3dv), + TABLE_ENTRY(TexCoord3f), + TABLE_ENTRY(TexCoord3fv), + TABLE_ENTRY(TexCoord3i), + TABLE_ENTRY(TexCoord3iv), + TABLE_ENTRY(TexCoord3s), + TABLE_ENTRY(TexCoord3sv), + TABLE_ENTRY(TexCoord4d), + TABLE_ENTRY(TexCoord4dv), + TABLE_ENTRY(TexCoord4f), + TABLE_ENTRY(TexCoord4fv), + TABLE_ENTRY(TexCoord4i), + TABLE_ENTRY(TexCoord4iv), + TABLE_ENTRY(TexCoord4s), + TABLE_ENTRY(TexCoord4sv), + TABLE_ENTRY(Vertex2d), + TABLE_ENTRY(Vertex2dv), + TABLE_ENTRY(Vertex2f), + TABLE_ENTRY(Vertex2fv), + TABLE_ENTRY(Vertex2i), + TABLE_ENTRY(Vertex2iv), + TABLE_ENTRY(Vertex2s), + TABLE_ENTRY(Vertex2sv), + TABLE_ENTRY(Vertex3d), + TABLE_ENTRY(Vertex3dv), + TABLE_ENTRY(Vertex3f), + TABLE_ENTRY(Vertex3fv), + TABLE_ENTRY(Vertex3i), + TABLE_ENTRY(Vertex3iv), + TABLE_ENTRY(Vertex3s), + TABLE_ENTRY(Vertex3sv), + TABLE_ENTRY(Vertex4d), + TABLE_ENTRY(Vertex4dv), + TABLE_ENTRY(Vertex4f), + TABLE_ENTRY(Vertex4fv), + TABLE_ENTRY(Vertex4i), + TABLE_ENTRY(Vertex4iv), + TABLE_ENTRY(Vertex4s), + TABLE_ENTRY(Vertex4sv), + TABLE_ENTRY(ClipPlane), + TABLE_ENTRY(ColorMaterial), + TABLE_ENTRY(CullFace), + TABLE_ENTRY(Fogf), + TABLE_ENTRY(Fogfv), + TABLE_ENTRY(Fogi), + TABLE_ENTRY(Fogiv), + TABLE_ENTRY(FrontFace), + TABLE_ENTRY(Hint), + TABLE_ENTRY(Lightf), + TABLE_ENTRY(Lightfv), + TABLE_ENTRY(Lighti), + TABLE_ENTRY(Lightiv), + TABLE_ENTRY(LightModelf), + TABLE_ENTRY(LightModelfv), + TABLE_ENTRY(LightModeli), + TABLE_ENTRY(LightModeliv), + TABLE_ENTRY(LineStipple), + TABLE_ENTRY(LineWidth), + TABLE_ENTRY(Materialf), + TABLE_ENTRY(Materialfv), + TABLE_ENTRY(Materiali), + TABLE_ENTRY(Materialiv), + TABLE_ENTRY(PointSize), + TABLE_ENTRY(PolygonMode), + TABLE_ENTRY(PolygonStipple), + TABLE_ENTRY(Scissor), + TABLE_ENTRY(ShadeModel), + TABLE_ENTRY(TexParameterf), + TABLE_ENTRY(TexParameterfv), + TABLE_ENTRY(TexParameteri), + TABLE_ENTRY(TexParameteriv), + TABLE_ENTRY(TexImage1D), + TABLE_ENTRY(TexImage2D), + TABLE_ENTRY(TexEnvf), + TABLE_ENTRY(TexEnvfv), + TABLE_ENTRY(TexEnvi), + TABLE_ENTRY(TexEnviv), + TABLE_ENTRY(TexGend), + TABLE_ENTRY(TexGendv), + TABLE_ENTRY(TexGenf), + TABLE_ENTRY(TexGenfv), + TABLE_ENTRY(TexGeni), + TABLE_ENTRY(TexGeniv), + TABLE_ENTRY(FeedbackBuffer), + TABLE_ENTRY(SelectBuffer), + TABLE_ENTRY(RenderMode), + TABLE_ENTRY(InitNames), + TABLE_ENTRY(LoadName), + TABLE_ENTRY(PassThrough), + TABLE_ENTRY(PopName), + TABLE_ENTRY(PushName), + TABLE_ENTRY(DrawBuffer), + TABLE_ENTRY(Clear), + TABLE_ENTRY(ClearAccum), + TABLE_ENTRY(ClearIndex), + TABLE_ENTRY(ClearColor), + TABLE_ENTRY(ClearStencil), + TABLE_ENTRY(ClearDepth), + TABLE_ENTRY(StencilMask), + TABLE_ENTRY(ColorMask), + TABLE_ENTRY(DepthMask), + TABLE_ENTRY(IndexMask), + TABLE_ENTRY(Accum), + TABLE_ENTRY(Disable), + TABLE_ENTRY(Enable), + TABLE_ENTRY(Finish), + TABLE_ENTRY(Flush), + TABLE_ENTRY(PopAttrib), + TABLE_ENTRY(PushAttrib), + TABLE_ENTRY(Map1d), + TABLE_ENTRY(Map1f), + TABLE_ENTRY(Map2d), + TABLE_ENTRY(Map2f), + TABLE_ENTRY(MapGrid1d), + TABLE_ENTRY(MapGrid1f), + TABLE_ENTRY(MapGrid2d), + TABLE_ENTRY(MapGrid2f), + TABLE_ENTRY(EvalCoord1d), + TABLE_ENTRY(EvalCoord1dv), + TABLE_ENTRY(EvalCoord1f), + TABLE_ENTRY(EvalCoord1fv), + TABLE_ENTRY(EvalCoord2d), + TABLE_ENTRY(EvalCoord2dv), + TABLE_ENTRY(EvalCoord2f), + TABLE_ENTRY(EvalCoord2fv), + TABLE_ENTRY(EvalMesh1), + TABLE_ENTRY(EvalPoint1), + TABLE_ENTRY(EvalMesh2), + TABLE_ENTRY(EvalPoint2), + TABLE_ENTRY(AlphaFunc), + TABLE_ENTRY(BlendFunc), + TABLE_ENTRY(LogicOp), + TABLE_ENTRY(StencilFunc), + TABLE_ENTRY(StencilOp), + TABLE_ENTRY(DepthFunc), + TABLE_ENTRY(PixelZoom), + TABLE_ENTRY(PixelTransferf), + TABLE_ENTRY(PixelTransferi), + TABLE_ENTRY(PixelStoref), + TABLE_ENTRY(PixelStorei), + TABLE_ENTRY(PixelMapfv), + TABLE_ENTRY(PixelMapuiv), + TABLE_ENTRY(PixelMapusv), + TABLE_ENTRY(ReadBuffer), + TABLE_ENTRY(CopyPixels), + TABLE_ENTRY(ReadPixels), + TABLE_ENTRY(DrawPixels), + TABLE_ENTRY(GetBooleanv), + TABLE_ENTRY(GetClipPlane), + TABLE_ENTRY(GetDoublev), + TABLE_ENTRY(GetError), + TABLE_ENTRY(GetFloatv), + TABLE_ENTRY(GetIntegerv), + TABLE_ENTRY(GetLightfv), + TABLE_ENTRY(GetLightiv), + TABLE_ENTRY(GetMapdv), + TABLE_ENTRY(GetMapfv), + TABLE_ENTRY(GetMapiv), + TABLE_ENTRY(GetMaterialfv), + TABLE_ENTRY(GetMaterialiv), + TABLE_ENTRY(GetPixelMapfv), + TABLE_ENTRY(GetPixelMapuiv), + TABLE_ENTRY(GetPixelMapusv), + TABLE_ENTRY(GetPolygonStipple), + TABLE_ENTRY(GetString), + TABLE_ENTRY(GetTexEnvfv), + TABLE_ENTRY(GetTexEnviv), + TABLE_ENTRY(GetTexGendv), + TABLE_ENTRY(GetTexGenfv), + TABLE_ENTRY(GetTexGeniv), + TABLE_ENTRY(GetTexImage), + TABLE_ENTRY(GetTexParameterfv), + TABLE_ENTRY(GetTexParameteriv), + TABLE_ENTRY(GetTexLevelParameterfv), + TABLE_ENTRY(GetTexLevelParameteriv), + TABLE_ENTRY(IsEnabled), + TABLE_ENTRY(IsList), + TABLE_ENTRY(DepthRange), + TABLE_ENTRY(Frustum), + TABLE_ENTRY(LoadIdentity), + TABLE_ENTRY(LoadMatrixf), + TABLE_ENTRY(LoadMatrixd), + TABLE_ENTRY(MatrixMode), + TABLE_ENTRY(MultMatrixf), + TABLE_ENTRY(MultMatrixd), + TABLE_ENTRY(Ortho), + TABLE_ENTRY(PopMatrix), + TABLE_ENTRY(PushMatrix), + TABLE_ENTRY(Rotated), + TABLE_ENTRY(Rotatef), + TABLE_ENTRY(Scaled), + TABLE_ENTRY(Scalef), + TABLE_ENTRY(Translated), + TABLE_ENTRY(Translatef), + TABLE_ENTRY(Viewport), + /* 1.1 */ + TABLE_ENTRY(ArrayElement), + TABLE_ENTRY(BindTexture), + TABLE_ENTRY(ColorPointer), + TABLE_ENTRY(DisableClientState), + TABLE_ENTRY(DrawArrays), + TABLE_ENTRY(DrawElements), + TABLE_ENTRY(EdgeFlagPointer), + TABLE_ENTRY(EnableClientState), + TABLE_ENTRY(IndexPointer), + TABLE_ENTRY(Indexub), + TABLE_ENTRY(Indexubv), + TABLE_ENTRY(InterleavedArrays), + TABLE_ENTRY(NormalPointer), + TABLE_ENTRY(PolygonOffset), + TABLE_ENTRY(TexCoordPointer), + TABLE_ENTRY(VertexPointer), + TABLE_ENTRY(AreTexturesResident), + TABLE_ENTRY(CopyTexImage1D), + TABLE_ENTRY(CopyTexImage2D), + TABLE_ENTRY(CopyTexSubImage1D), + TABLE_ENTRY(CopyTexSubImage2D), + TABLE_ENTRY(DeleteTextures), + TABLE_ENTRY(GenTextures), + TABLE_ENTRY(GetPointerv), + TABLE_ENTRY(IsTexture), + TABLE_ENTRY(PrioritizeTextures), + TABLE_ENTRY(TexSubImage1D), + TABLE_ENTRY(TexSubImage2D), + TABLE_ENTRY(PopClientAttrib), + TABLE_ENTRY(PushClientAttrib), + /* 1.2 */ + TABLE_ENTRY(BlendColor), + TABLE_ENTRY(BlendEquation), + TABLE_ENTRY(DrawRangeElements), + TABLE_ENTRY(ColorTable), + TABLE_ENTRY(ColorTableParameterfv), + TABLE_ENTRY(ColorTableParameteriv), + TABLE_ENTRY(CopyColorTable), + TABLE_ENTRY(GetColorTable), + TABLE_ENTRY(GetColorTableParameterfv), + TABLE_ENTRY(GetColorTableParameteriv), + TABLE_ENTRY(ColorSubTable), + TABLE_ENTRY(CopyColorSubTable), + TABLE_ENTRY(ConvolutionFilter1D), + TABLE_ENTRY(ConvolutionFilter2D), + TABLE_ENTRY(ConvolutionParameterf), + TABLE_ENTRY(ConvolutionParameterfv), + TABLE_ENTRY(ConvolutionParameteri), + TABLE_ENTRY(ConvolutionParameteriv), + TABLE_ENTRY(CopyConvolutionFilter1D), + TABLE_ENTRY(CopyConvolutionFilter2D), + TABLE_ENTRY(GetConvolutionFilter), + TABLE_ENTRY(GetConvolutionParameterfv), + TABLE_ENTRY(GetConvolutionParameteriv), + TABLE_ENTRY(GetSeparableFilter), + TABLE_ENTRY(SeparableFilter2D), + TABLE_ENTRY(GetHistogram), + TABLE_ENTRY(GetHistogramParameterfv), + TABLE_ENTRY(GetHistogramParameteriv), + TABLE_ENTRY(GetMinmax), + TABLE_ENTRY(GetMinmaxParameterfv), + TABLE_ENTRY(GetMinmaxParameteriv), + TABLE_ENTRY(Histogram), + TABLE_ENTRY(Minmax), + TABLE_ENTRY(ResetHistogram), + TABLE_ENTRY(ResetMinmax), + TABLE_ENTRY(TexImage3D), + TABLE_ENTRY(TexSubImage3D), + TABLE_ENTRY(CopyTexSubImage3D), + /* GL_ARB_multitexture */ + TABLE_ENTRY(ActiveTextureARB), + TABLE_ENTRY(ClientActiveTextureARB), + TABLE_ENTRY(MultiTexCoord1dARB), + TABLE_ENTRY(MultiTexCoord1dvARB), + TABLE_ENTRY(MultiTexCoord1fARB), + TABLE_ENTRY(MultiTexCoord1fvARB), + TABLE_ENTRY(MultiTexCoord1iARB), + TABLE_ENTRY(MultiTexCoord1ivARB), + TABLE_ENTRY(MultiTexCoord1sARB), + TABLE_ENTRY(MultiTexCoord1svARB), + TABLE_ENTRY(MultiTexCoord2dARB), + TABLE_ENTRY(MultiTexCoord2dvARB), + TABLE_ENTRY(MultiTexCoord2fARB), + TABLE_ENTRY(MultiTexCoord2fvARB), + TABLE_ENTRY(MultiTexCoord2iARB), + TABLE_ENTRY(MultiTexCoord2ivARB), + TABLE_ENTRY(MultiTexCoord2sARB), + TABLE_ENTRY(MultiTexCoord2svARB), + TABLE_ENTRY(MultiTexCoord3dARB), + TABLE_ENTRY(MultiTexCoord3dvARB), + TABLE_ENTRY(MultiTexCoord3fARB), + TABLE_ENTRY(MultiTexCoord3fvARB), + TABLE_ENTRY(MultiTexCoord3iARB), + TABLE_ENTRY(MultiTexCoord3ivARB), + TABLE_ENTRY(MultiTexCoord3sARB), + TABLE_ENTRY(MultiTexCoord3svARB), + TABLE_ENTRY(MultiTexCoord4dARB), + TABLE_ENTRY(MultiTexCoord4dvARB), + TABLE_ENTRY(MultiTexCoord4fARB), + TABLE_ENTRY(MultiTexCoord4fvARB), + TABLE_ENTRY(MultiTexCoord4iARB), + TABLE_ENTRY(MultiTexCoord4ivARB), + TABLE_ENTRY(MultiTexCoord4sARB), + TABLE_ENTRY(MultiTexCoord4svARB), + /* GL_ARB_transpose_matrix */ + TABLE_ENTRY(LoadTransposeMatrixfARB), + TABLE_ENTRY(LoadTransposeMatrixdARB), + TABLE_ENTRY(MultTransposeMatrixfARB), + TABLE_ENTRY(MultTransposeMatrixdARB), + /* GL_ARB_multisample */ + TABLE_ENTRY(SampleCoverageARB), + TABLE_ENTRY(SamplePassARB), + /* GL_EXT_blend_color */ + /* GL_EXT_polygon_offset */ + TABLE_ENTRY(PolygonOffsetEXT), + /* GL_EXT_texture3D */ + /* GL_EXT_subtexture */ + /* GL_SGIS_texture_filter4 */ + TABLE_ENTRY(GetTexFilterFuncSGIS), + TABLE_ENTRY(TexFilterFuncSGIS), + /* GL_EXT_subtexture */ + /* GL_EXT_copy_texture */ + /* GL_EXT_histogram */ + TABLE_ENTRY(GetHistogramEXT), + TABLE_ENTRY(GetHistogramParameterfvEXT), + TABLE_ENTRY(GetHistogramParameterivEXT), + TABLE_ENTRY(GetMinmaxEXT), + TABLE_ENTRY(GetMinmaxParameterfvEXT), + TABLE_ENTRY(GetMinmaxParameterivEXT), + /* GL_EXT_convolution */ + TABLE_ENTRY(GetConvolutionFilterEXT), + TABLE_ENTRY(GetConvolutionParameterfvEXT), + TABLE_ENTRY(GetConvolutionParameterivEXT), + TABLE_ENTRY(GetSeparableFilterEXT), + /* GL_SGI_color_table */ + TABLE_ENTRY(GetColorTableSGI), + TABLE_ENTRY(GetColorTableParameterfvSGI), + TABLE_ENTRY(GetColorTableParameterivSGI), + /* GL_SGIX_pixel_texture */ + TABLE_ENTRY(PixelTexGenSGIX), + /* GL_SGIS_pixel_texture */ + TABLE_ENTRY(PixelTexGenParameteriSGIS), + TABLE_ENTRY(PixelTexGenParameterivSGIS), + TABLE_ENTRY(PixelTexGenParameterfSGIS), + TABLE_ENTRY(PixelTexGenParameterfvSGIS), + TABLE_ENTRY(GetPixelTexGenParameterivSGIS), + TABLE_ENTRY(GetPixelTexGenParameterfvSGIS), + /* GL_SGIS_texture4D */ + TABLE_ENTRY(TexImage4DSGIS), + TABLE_ENTRY(TexSubImage4DSGIS), + /* GL_EXT_texture_object */ + TABLE_ENTRY(AreTexturesResidentEXT), + TABLE_ENTRY(GenTexturesEXT), + TABLE_ENTRY(IsTextureEXT), + /* GL_SGIS_detail_texture */ + TABLE_ENTRY(DetailTexFuncSGIS), + TABLE_ENTRY(GetDetailTexFuncSGIS), + /* GL_SGIS_sharpen_texture */ + TABLE_ENTRY(SharpenTexFuncSGIS), + TABLE_ENTRY(GetSharpenTexFuncSGIS), + /* GL_SGIS_multisample */ + TABLE_ENTRY(SampleMaskSGIS), + TABLE_ENTRY(SamplePatternSGIS), + /* GL_EXT_vertex_array */ + TABLE_ENTRY(ColorPointerEXT), + TABLE_ENTRY(EdgeFlagPointerEXT), + TABLE_ENTRY(IndexPointerEXT), + TABLE_ENTRY(NormalPointerEXT), + TABLE_ENTRY(TexCoordPointerEXT), + TABLE_ENTRY(VertexPointerEXT), + /* GL_EXT_blend_minmax */ + /* GL_SGIX_sprite */ + TABLE_ENTRY(SpriteParameterfSGIX), + TABLE_ENTRY(SpriteParameterfvSGIX), + TABLE_ENTRY(SpriteParameteriSGIX), + TABLE_ENTRY(SpriteParameterivSGIX), + /* GL_EXT_point_parameters */ + TABLE_ENTRY(PointParameterfEXT), + TABLE_ENTRY(PointParameterfvEXT), + /* GL_SGIX_instruments */ + TABLE_ENTRY(GetInstrumentsSGIX), + TABLE_ENTRY(InstrumentsBufferSGIX), + TABLE_ENTRY(PollInstrumentsSGIX), + TABLE_ENTRY(ReadInstrumentsSGIX), + TABLE_ENTRY(StartInstrumentsSGIX), + TABLE_ENTRY(StopInstrumentsSGIX), + /* GL_SGIX_framezoom */ + TABLE_ENTRY(FrameZoomSGIX), + /* GL_SGIX_tag_sample_buffer */ + TABLE_ENTRY(TagSampleBufferSGIX), + /* GL_SGIX_reference_plane */ + TABLE_ENTRY(ReferencePlaneSGIX), + /* GL_SGIX_flush_raster */ + TABLE_ENTRY(FlushRasterSGIX), + /* GL_SGIX_list_priority */ + TABLE_ENTRY(GetListParameterfvSGIX), + TABLE_ENTRY(GetListParameterivSGIX), + TABLE_ENTRY(ListParameterfSGIX), + TABLE_ENTRY(ListParameterfvSGIX), + TABLE_ENTRY(ListParameteriSGIX), + TABLE_ENTRY(ListParameterivSGIX), + /* GL_SGIX_fragment_lighting */ + TABLE_ENTRY(FragmentColorMaterialSGIX), + TABLE_ENTRY(FragmentLightfSGIX), + TABLE_ENTRY(FragmentLightfvSGIX), + TABLE_ENTRY(FragmentLightiSGIX), + TABLE_ENTRY(FragmentLightivSGIX), + TABLE_ENTRY(FragmentLightModelfSGIX), + TABLE_ENTRY(FragmentLightModelfvSGIX), + TABLE_ENTRY(FragmentLightModeliSGIX), + TABLE_ENTRY(FragmentLightModelivSGIX), + TABLE_ENTRY(FragmentMaterialfSGIX), + TABLE_ENTRY(FragmentMaterialfvSGIX), + TABLE_ENTRY(FragmentMaterialiSGIX), + TABLE_ENTRY(FragmentMaterialivSGIX), + TABLE_ENTRY(GetFragmentLightfvSGIX), + TABLE_ENTRY(GetFragmentLightivSGIX), + TABLE_ENTRY(GetFragmentMaterialfvSGIX), + TABLE_ENTRY(GetFragmentMaterialivSGIX), + TABLE_ENTRY(LightEnviSGIX), + /* GL_EXT_vertex_weighting */ + TABLE_ENTRY(VertexWeightfEXT), + TABLE_ENTRY(VertexWeightfvEXT), + TABLE_ENTRY(VertexWeightPointerEXT), + /* GL_NV_vertex_array_range */ + TABLE_ENTRY(FlushVertexArrayRangeNV), + TABLE_ENTRY(VertexArrayRangeNV), + /* GL_NV_register_combiners */ + TABLE_ENTRY(CombinerParameterfvNV), + TABLE_ENTRY(CombinerParameterfNV), + TABLE_ENTRY(CombinerParameterivNV), + TABLE_ENTRY(CombinerParameteriNV), + TABLE_ENTRY(CombinerInputNV), + TABLE_ENTRY(CombinerOutputNV), + TABLE_ENTRY(FinalCombinerInputNV), + TABLE_ENTRY(GetCombinerInputParameterfvNV), + TABLE_ENTRY(GetCombinerInputParameterivNV), + TABLE_ENTRY(GetCombinerOutputParameterfvNV), + TABLE_ENTRY(GetCombinerOutputParameterivNV), + TABLE_ENTRY(GetFinalCombinerInputParameterfvNV), + TABLE_ENTRY(GetFinalCombinerInputParameterivNV), + /* GL_MESA_resize_buffers */ + TABLE_ENTRY(ResizeBuffersMESA), + /* GL_MESA_window_pos */ + TABLE_ENTRY(WindowPos2dMESA), + TABLE_ENTRY(WindowPos2dvMESA), + TABLE_ENTRY(WindowPos2fMESA), + TABLE_ENTRY(WindowPos2fvMESA), + TABLE_ENTRY(WindowPos2iMESA), + TABLE_ENTRY(WindowPos2ivMESA), + TABLE_ENTRY(WindowPos2sMESA), + TABLE_ENTRY(WindowPos2svMESA), + TABLE_ENTRY(WindowPos3dMESA), + TABLE_ENTRY(WindowPos3dvMESA), + TABLE_ENTRY(WindowPos3fMESA), + TABLE_ENTRY(WindowPos3fvMESA), + TABLE_ENTRY(WindowPos3iMESA), + TABLE_ENTRY(WindowPos3ivMESA), + TABLE_ENTRY(WindowPos3sMESA), + TABLE_ENTRY(WindowPos3svMESA), + TABLE_ENTRY(WindowPos4dMESA), + TABLE_ENTRY(WindowPos4dvMESA), + TABLE_ENTRY(WindowPos4fMESA), + TABLE_ENTRY(WindowPos4fvMESA), + TABLE_ENTRY(WindowPos4iMESA), + TABLE_ENTRY(WindowPos4ivMESA), + TABLE_ENTRY(WindowPos4sMESA), + TABLE_ENTRY(WindowPos4svMESA), + /* GL_EXT_draw_range_elements */ + TABLE_ENTRY(BlendFuncSeparateEXT), + /* GL_EXT_index_material */ + TABLE_ENTRY(IndexMaterialEXT), + /* GL_EXT_index_func */ + TABLE_ENTRY(IndexFuncEXT), + /* GL_EXT_compiled_vertex_array */ + TABLE_ENTRY(LockArraysEXT), + TABLE_ENTRY(UnlockArraysEXT), + /* GL_EXT_cull_vertex */ + TABLE_ENTRY(CullParameterdvEXT), + TABLE_ENTRY(CullParameterfvEXT), + /* GL_PGI_misc_hints */ + TABLE_ENTRY(HintPGI), + /* GL_EXT_fog_coord */ + TABLE_ENTRY(FogCoordfEXT), + TABLE_ENTRY(FogCoordfvEXT), + TABLE_ENTRY(FogCoorddEXT), + TABLE_ENTRY(FogCoorddvEXT), + TABLE_ENTRY(FogCoordPointerEXT), + /* GL_EXT_color_table */ + TABLE_ENTRY(GetColorTableEXT), + TABLE_ENTRY(GetColorTableParameterivEXT), + TABLE_ENTRY(GetColorTableParameterfvEXT), + /* GL_3DFX_tbuffer */ + TABLE_ENTRY(TbufferMask3DFX), + /* GL_ARB_texture_compression */ + TABLE_ENTRY(CompressedTexImage3DARB), + TABLE_ENTRY(CompressedTexImage2DARB), + TABLE_ENTRY(CompressedTexImage1DARB), + TABLE_ENTRY(CompressedTexSubImage3DARB), + TABLE_ENTRY(CompressedTexSubImage2DARB), + TABLE_ENTRY(CompressedTexSubImage1DARB), + TABLE_ENTRY(GetCompressedTexImageARB), + /* GL_EXT_secondary_color */ + TABLE_ENTRY(SecondaryColor3bEXT), + TABLE_ENTRY(SecondaryColor3bvEXT), + TABLE_ENTRY(SecondaryColor3dEXT), + TABLE_ENTRY(SecondaryColor3dvEXT), + TABLE_ENTRY(SecondaryColor3fEXT), + TABLE_ENTRY(SecondaryColor3fvEXT), + TABLE_ENTRY(SecondaryColor3iEXT), + TABLE_ENTRY(SecondaryColor3ivEXT), + TABLE_ENTRY(SecondaryColor3sEXT), + TABLE_ENTRY(SecondaryColor3svEXT), + TABLE_ENTRY(SecondaryColor3ubEXT), + TABLE_ENTRY(SecondaryColor3ubvEXT), + TABLE_ENTRY(SecondaryColor3uiEXT), + TABLE_ENTRY(SecondaryColor3uivEXT), + TABLE_ENTRY(SecondaryColor3usEXT), + TABLE_ENTRY(SecondaryColor3usvEXT), + TABLE_ENTRY(SecondaryColorPointerEXT), + /* A whole bunch of no-op functions. These might be called + * when someone tries to call a dynamically-registered extension + * function without a current rendering context. + */ + TABLE_ENTRY(Unused), + TABLE_ENTRY(Unused), + TABLE_ENTRY(Unused), + TABLE_ENTRY(Unused), + TABLE_ENTRY(Unused), + TABLE_ENTRY(Unused), + TABLE_ENTRY(Unused), + TABLE_ENTRY(Unused), + TABLE_ENTRY(Unused), + TABLE_ENTRY(Unused), + TABLE_ENTRY(Unused), + TABLE_ENTRY(Unused), + TABLE_ENTRY(Unused), + TABLE_ENTRY(Unused), + TABLE_ENTRY(Unused), + TABLE_ENTRY(Unused), + TABLE_ENTRY(Unused), + TABLE_ENTRY(Unused), + TABLE_ENTRY(Unused), + TABLE_ENTRY(Unused), + TABLE_ENTRY(Unused), + TABLE_ENTRY(Unused), + TABLE_ENTRY(Unused), + TABLE_ENTRY(Unused), + TABLE_ENTRY(Unused), + TABLE_ENTRY(Unused), + TABLE_ENTRY(Unused), + TABLE_ENTRY(Unused), + TABLE_ENTRY(Unused), + TABLE_ENTRY(Unused), + TABLE_ENTRY(Unused), + TABLE_ENTRY(Unused), + TABLE_ENTRY(Unused), + TABLE_ENTRY(Unused), + TABLE_ENTRY(Unused), + TABLE_ENTRY(Unused), + TABLE_ENTRY(Unused), + TABLE_ENTRY(Unused), + TABLE_ENTRY(Unused), + TABLE_ENTRY(Unused), + TABLE_ENTRY(Unused), + TABLE_ENTRY(Unused), + TABLE_ENTRY(Unused), + TABLE_ENTRY(Unused), + TABLE_ENTRY(Unused), + TABLE_ENTRY(Unused), + TABLE_ENTRY(Unused), + TABLE_ENTRY(Unused), + TABLE_ENTRY(Unused), + TABLE_ENTRY(Unused), + TABLE_ENTRY(Unused), + TABLE_ENTRY(Unused), + TABLE_ENTRY(Unused), + TABLE_ENTRY(Unused), + TABLE_ENTRY(Unused), + TABLE_ENTRY(Unused), + TABLE_ENTRY(Unused), + TABLE_ENTRY(Unused), + TABLE_ENTRY(Unused), + TABLE_ENTRY(Unused), + TABLE_ENTRY(Unused), + TABLE_ENTRY(Unused), + TABLE_ENTRY(Unused), + TABLE_ENTRY(Unused), + TABLE_ENTRY(Unused), + TABLE_ENTRY(Unused), + TABLE_ENTRY(Unused), + TABLE_ENTRY(Unused), + TABLE_ENTRY(Unused), + TABLE_ENTRY(Unused), + TABLE_ENTRY(Unused), + TABLE_ENTRY(Unused), + TABLE_ENTRY(Unused), + TABLE_ENTRY(Unused), + TABLE_ENTRY(Unused), + TABLE_ENTRY(Unused), + TABLE_ENTRY(Unused), + TABLE_ENTRY(Unused), + TABLE_ENTRY(Unused), + TABLE_ENTRY(Unused), + TABLE_ENTRY(Unused), + TABLE_ENTRY(Unused), + TABLE_ENTRY(Unused), + TABLE_ENTRY(Unused), + TABLE_ENTRY(Unused), + TABLE_ENTRY(Unused), + TABLE_ENTRY(Unused), + TABLE_ENTRY(Unused), + TABLE_ENTRY(Unused), + TABLE_ENTRY(Unused), + TABLE_ENTRY(Unused), + TABLE_ENTRY(Unused), + TABLE_ENTRY(Unused), + TABLE_ENTRY(Unused), + TABLE_ENTRY(Unused), + TABLE_ENTRY(Unused), + TABLE_ENTRY(Unused), + TABLE_ENTRY(Unused), + TABLE_ENTRY(Unused), + TABLE_ENTRY(Unused), + TABLE_ENTRY(Unused), + TABLE_ENTRY(Unused), + TABLE_ENTRY(Unused), + TABLE_ENTRY(Unused), + TABLE_ENTRY(Unused), + TABLE_ENTRY(Unused), + TABLE_ENTRY(Unused), + TABLE_ENTRY(Unused), + TABLE_ENTRY(Unused), + TABLE_ENTRY(Unused), + TABLE_ENTRY(Unused), + TABLE_ENTRY(Unused), + TABLE_ENTRY(Unused), + TABLE_ENTRY(Unused), + TABLE_ENTRY(Unused), + TABLE_ENTRY(Unused), + TABLE_ENTRY(Unused), + TABLE_ENTRY(Unused), + TABLE_ENTRY(Unused), + TABLE_ENTRY(Unused), + TABLE_ENTRY(Unused), + TABLE_ENTRY(Unused), + TABLE_ENTRY(Unused), + TABLE_ENTRY(Unused), + TABLE_ENTRY(Unused), + TABLE_ENTRY(Unused), + TABLE_ENTRY(Unused), + TABLE_ENTRY(Unused), + TABLE_ENTRY(Unused), + TABLE_ENTRY(Unused), + TABLE_ENTRY(Unused), + TABLE_ENTRY(Unused), + TABLE_ENTRY(Unused), + TABLE_ENTRY(Unused), + TABLE_ENTRY(Unused), + TABLE_ENTRY(Unused), + TABLE_ENTRY(Unused), + TABLE_ENTRY(Unused), + TABLE_ENTRY(Unused), + TABLE_ENTRY(Unused), + TABLE_ENTRY(Unused), + TABLE_ENTRY(Unused), + TABLE_ENTRY(Unused), + TABLE_ENTRY(Unused), + TABLE_ENTRY(Unused), + TABLE_ENTRY(Unused), + TABLE_ENTRY(Unused), + TABLE_ENTRY(Unused), + TABLE_ENTRY(Unused), + TABLE_ENTRY(Unused), + TABLE_ENTRY(Unused), + TABLE_ENTRY(Unused), + TABLE_ENTRY(Unused), + TABLE_ENTRY(Unused), + TABLE_ENTRY(Unused), + TABLE_ENTRY(Unused), + TABLE_ENTRY(Unused), + TABLE_ENTRY(Unused), + TABLE_ENTRY(Unused), + TABLE_ENTRY(Unused), + TABLE_ENTRY(Unused) +}; +#endif /* DISPATCH_TABLE_NAME */ + + + +/* + * This is just used to silence compiler warnings. + * We list the functions which aren't otherwise used. + */ +#ifdef UNUSED_TABLE_NAME +void *UNUSED_TABLE_NAME[] = { + TABLE_ENTRY(BlendColorEXT), + TABLE_ENTRY(CopyTexSubImage3DEXT), + TABLE_ENTRY(TexImage3DEXT), + TABLE_ENTRY(TexSubImage3DEXT), + TABLE_ENTRY(CopyTexSubImage1DEXT), + TABLE_ENTRY(TexSubImage1DEXT), + TABLE_ENTRY(TexSubImage2DEXT), + TABLE_ENTRY(CopyTexImage1DEXT), + TABLE_ENTRY(CopyTexImage2DEXT), + TABLE_ENTRY(CopyTexSubImage2DEXT), + TABLE_ENTRY(HistogramEXT), + TABLE_ENTRY(MinmaxEXT), + TABLE_ENTRY(ResetHistogramEXT), + TABLE_ENTRY(ResetMinmaxEXT), + TABLE_ENTRY(ConvolutionFilter1DEXT), + TABLE_ENTRY(ConvolutionFilter2DEXT), + TABLE_ENTRY(ConvolutionParameterfEXT), + TABLE_ENTRY(ConvolutionParameterfvEXT), + TABLE_ENTRY(ConvolutionParameteriEXT), + TABLE_ENTRY(ConvolutionParameterivEXT), + TABLE_ENTRY(CopyConvolutionFilter1DEXT), + TABLE_ENTRY(CopyConvolutionFilter2DEXT), + TABLE_ENTRY(SeparableFilter2DEXT), + TABLE_ENTRY(ColorTableParameterfvSGI), + TABLE_ENTRY(ColorTableParameterivSGI), + TABLE_ENTRY(ColorTableSGI), + TABLE_ENTRY(CopyColorTableSGI), + TABLE_ENTRY(DeleteTexturesEXT), + TABLE_ENTRY(BindTextureEXT), + TABLE_ENTRY(PrioritizeTexturesEXT), + TABLE_ENTRY(GetPointervEXT), + TABLE_ENTRY(ArrayElementEXT), + TABLE_ENTRY(DrawArraysEXT), + TABLE_ENTRY(BlendEquationEXT), + TABLE_ENTRY(PointParameterfSGIS), + TABLE_ENTRY(PointParameterfvSGIS), + TABLE_ENTRY(ColorSubTableEXT), + TABLE_ENTRY(CopyColorSubTableEXT), + TABLE_ENTRY(ColorTableEXT), + TABLE_ENTRY(DrawRangeElementsEXT), + TABLE_ENTRY(BlendFuncSeparateINGR), + TABLE_ENTRY(SampleMaskEXT), + TABLE_ENTRY(SamplePatternEXT) +}; +#endif /*UNUSED_TABLE_NAME*/ + + +#undef KEYWORD1 +#undef KEYWORD2 +#undef NAME +#undef DISPATCH +#undef RETURN_DISPATCH +#undef DISPATCH_TABLE_NAME +#undef UNUSED_TABLE_NAME +#undef TABLE_ENTRY +#undef NO_FUNCTIONS Index: dll/opengl/opengl32/mesa/glcore.h =================================================================== --- dll/opengl/opengl32/mesa/glcore.h (revision 0) +++ dll/opengl/opengl32/mesa/glcore.h (working copy) @@ -0,0 +1,424 @@ +/* $XFree86: xc/lib/GL/include/GL/internal/glcore.h,v 1.7 2001/03/25 05:32:00 tsi Exp $ */ +#ifndef __gl_core_h_ +#define __gl_core_h_ + +/* +** License Applicability. Except to the extent portions of this file are +** made subject to an alternative license as permitted in the SGI Free +** Software License B, Version 1.1 (the "License"), the contents of this +** file are subject only to the provisions of the License. You may not use +** this file except in compliance with the License. You may obtain a copy +** of the License at Silicon Graphics, Inc., attn: Legal Services, 1600 +** Amphitheatre Parkway, Mountain View, CA 94043-1351, or at: +** +** http://oss.sgi.com/projects/FreeB +** +** Note that, as provided in the License, the Software is distributed on an +** "AS IS" basis, with ALL EXPRESS AND IMPLIED WARRANTIES AND CONDITIONS +** DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED WARRANTIES AND +** CONDITIONS OF MERCHANTABILITY, SATISFACTORY QUALITY, FITNESS FOR A +** PARTICULAR PURPOSE, AND NON-INFRINGEMENT. +** +** Original Code. The Original Code is: OpenGL Sample Implementation, +** Version 1.2.1, released January 26, 2000, developed by Silicon Graphics, +** Inc. The Original Code is Copyright (c) 1991-2000 Silicon Graphics, Inc. +** Copyright in any portions created by third parties is as indicated +** elsewhere herein. All Rights Reserved. +** +** Additional Notice Provisions: The application programming interfaces +** established by SGI in conjunction with the Original Code are The +** OpenGL(R) Graphics System: A Specification (Version 1.2.1), released +** April 1, 1999; The OpenGL(R) Graphics System Utility Library (Version +** 1.3), released November 4, 1998; and OpenGL(R) Graphics with the X +** Window System(R) (Version 1.3), released October 19, 1998. This software +** was created using the OpenGL(R) version 1.2.1 Sample Implementation +** published by SGI, but has not been independently verified as being +** compliant with the OpenGL(R) version 1.2.1 Specification. +** +*/ + +#ifndef XFree86LOADER +#include +#endif + +#define GL_CORE_SGI 1 +#define GL_CORE_MESA 2 + +typedef struct __GLcontextRec __GLcontext; +typedef struct __GLinterfaceRec __GLinterface; + +/* +** This file defines the interface between the GL core and the surrounding +** "operating system" that supports it (currently the GLX or WGL extensions). +** +** Members (data and function pointers) are documented as imported or +** exported according to how they are used by the core rendering functions. +** Imported members are initialized by the "operating system" and used by +** the core functions. Exported members are initialized by the core functions +** and used by the "operating system". +*/ + +/* +** Mode and limit information for a context. This information is +** kept around in the context so that values can be used during +** command execution, and for returning information about the +** context to the application. +*/ +typedef struct __GLcontextModesRec { + GLboolean rgbMode; + GLboolean colorIndexMode; + GLboolean doubleBufferMode; + GLboolean stereoMode; + + GLboolean haveAccumBuffer; + GLboolean haveDepthBuffer; + GLboolean haveStencilBuffer; + + GLint redBits, greenBits, blueBits, alphaBits; /* bits per comp */ + GLuint redMask, greenMask, blueMask, alphaMask; + GLint rgbBits; /* total bits for rgb */ + GLint indexBits; /* total bits for colorindex */ + + GLint accumRedBits, accumGreenBits, accumBlueBits, accumAlphaBits; + GLint depthBits; + GLint stencilBits; + + GLint numAuxBuffers; + + GLint level; + + GLint pixmapMode; +} __GLcontextModes; + +/************************************************************************/ + +/* +** Structure used for allocating and freeing drawable private memory. +** (like software buffers, for example). +** +** The memory allocation routines are provided by the surrounding +** "operating system" code, and they are to be used for allocating +** software buffers and things which are associated with the drawable, +** and used by any context which draws to that drawable. There are +** separate memory allocation functions for drawables and contexts +** since drawables and contexts can be created and destroyed independently +** of one another, and the "operating system" may want to use separate +** allocation arenas for each. +** +** The freePrivate function is filled in by the core routines when they +** allocates software buffers, and stick them in "private". The freePrivate +** function will destroy anything allocated to this drawable (to be called +** when the drawable is destroyed). +*/ +typedef struct __GLdrawableRegionRec __GLdrawableRegion; +typedef struct __GLdrawableBufferRec __GLdrawableBuffer; +typedef struct __GLdrawablePrivateRec __GLdrawablePrivate; + +typedef struct __GLregionRectRec { + /* lower left (inside the rectangle) */ + GLint x0, y0; + /* upper right (outside the rectangle) */ + GLint x1, y1; +} __GLregionRect; + +struct __GLdrawableRegionRec { + GLint numRects; + __GLregionRect *rects; + __GLregionRect boundingRect; +}; + +/************************************************************************/ + +/* masks for the buffers */ +#define __GL_FRONT_BUFFER_MASK 0x00000001 +#define __GL_FRONT_LEFT_BUFFER_MASK 0x00000001 +#define __GL_FRONT_RIGHT_BUFFER_MASK 0x00000002 +#define __GL_BACK_BUFFER_MASK 0x00000004 +#define __GL_BACK_LEFT_BUFFER_MASK 0x00000004 +#define __GL_BACK_RIGHT_BUFFER_MASK 0x00000008 +#define __GL_ACCUM_BUFFER_MASK 0x00000010 +#define __GL_DEPTH_BUFFER_MASK 0x00000020 +#define __GL_STENCIL_BUFFER_MASK 0x00000040 +#define __GL_AUX_BUFFER_MASK(i) (0x0000080 << (i)) + +#define __GL_ALL_BUFFER_MASK 0xffffffff + +/* what Resize routines return if resize resorted to fallback case */ +#define __GL_BUFFER_FALLBACK 0x10 + +typedef void (*__GLbufFallbackInitFn)(__GLdrawableBuffer *buf, + __GLdrawablePrivate *glPriv, GLint bits); +typedef void (*__GLbufMainInitFn)(__GLdrawableBuffer *buf, + __GLdrawablePrivate *glPriv, GLint bits, + __GLbufFallbackInitFn back); + +/* +** A drawable buffer +** +** This data structure describes the context side of a drawable. +** +** According to the spec there could be multiple contexts bound to the same +** drawable at the same time (from different threads). In order to avoid +** multiple-access conflicts, locks are used to serialize access. When a +** thread needs to access (read or write) a member of the drawable, it takes +** a lock first. Some of the entries in the drawable are treated "mostly +** constant", so we take the freedom of allowing access to them without +** taking a lock (for optimization reasons). +** +** For more details regarding locking, see buffers.h in the GL core +*/ +struct __GLdrawableBufferRec { + /* + ** Buffer dimensions + */ + GLint width, height, depth; + + /* + ** Framebuffer base address + */ + void *base; + + /* + ** Framebuffer size (in bytes) + */ + GLuint size; + + /* + ** Size (in bytes) of each element in the framebuffer + */ + GLuint elementSize; + GLuint elementSizeLog2; + + /* + ** Element skip from one scanline to the next. + ** If the buffer is part of another buffer (for example, fullscreen + ** front buffer), outerWidth is the width of that buffer. + */ + GLint outerWidth; + + /* + ** outerWidth * elementSize + */ + GLint byteWidth; + + /* + ** Allocation/deallocation is done based on this handle. A handle + ** is conceptually different from the framebuffer 'base'. + */ + void *handle; + + /* imported */ + GLboolean (*resize)(__GLdrawableBuffer *buf, + GLint x, GLint y, GLuint width, GLuint height, + __GLdrawablePrivate *glPriv, GLuint bufferMask); + void (*lock)(__GLdrawableBuffer *buf, __GLdrawablePrivate *glPriv); + void (*unlock)(__GLdrawableBuffer *buf, __GLdrawablePrivate *glPriv); + void (*fill)(__GLdrawableBuffer *buf, __GLdrawablePrivate *glPriv, + GLuint val, GLint x, GLint y, GLint w, GLint h); + void (*free)(__GLdrawableBuffer *buf, __GLdrawablePrivate *glPriv); + + /* exported */ + void (*freePrivate)(__GLdrawableBuffer *buf, __GLdrawablePrivate *glPriv); +#ifdef __cplusplus + void *privatePtr; +#else + void *private; +#endif + + /* private */ + void *other; /* implementation private data */ + __GLbufMainInitFn mainInit; + __GLbufFallbackInitFn fallbackInit; +}; + +/* +** The context side of the drawable private +*/ +struct __GLdrawablePrivateRec { + /* + ** Drawable Modes + */ + __GLcontextModes *modes; + + /* + ** Drawable size + */ + GLuint width, height; + + /* + ** Origin in screen coordinates of the drawable + */ + GLint xOrigin, yOrigin; +#ifdef __GL_ALIGNED_BUFFERS + /* + ** Drawable offset from screen origin + */ + GLint xOffset, yOffset; + + /* + ** Alignment restriction + */ + GLint xAlignment, yAlignment; +#endif + /* + ** Should we invert the y axis? + */ + GLint yInverted; + + /* + ** Mask specifying which buffers are renderable by the hw + */ + GLuint accelBufferMask; + + /* + ** the buffers themselves + */ + __GLdrawableBuffer frontBuffer; + __GLdrawableBuffer backBuffer; + __GLdrawableBuffer accumBuffer; + __GLdrawableBuffer depthBuffer; + __GLdrawableBuffer stencilBuffer; +#if defined(__GL_NUMBER_OF_AUX_BUFFERS) && (__GL_NUMBER_OF_AUX_BUFFERS > 0) + __GLdrawableBuffer *auxBuffer; +#endif + + __GLdrawableRegion ownershipRegion; + + /* + ** Lock for the drawable private structure + */ + void *lock; +#ifdef DEBUG + /* lock debugging info */ + int lockRefCount; + int lockLine[10]; + char *lockFile[10]; +#endif + + /* imported */ + void *(*malloc)(size_t size); + void *(*calloc)(size_t numElem, size_t elemSize); + void *(*realloc)(void *oldAddr, size_t newSize); + void (*free)(void *addr); + + GLboolean (*addSwapRect)(__GLdrawablePrivate *glPriv, + GLint x, GLint y, GLsizei width, GLsizei height); + void (*setClipRect)(__GLdrawablePrivate *glPriv, + GLint x, GLint y, GLsizei width, GLsizei height); + void (*updateClipRegion)(__GLdrawablePrivate *glPriv); + GLboolean (*resize)(__GLdrawablePrivate *glPriv); + void (*getDrawableSize)(__GLdrawablePrivate *glPriv, + GLint *x, GLint *y, GLuint *width, GLuint *height); + + void (*lockDP)(__GLdrawablePrivate *glPriv, __GLcontext *gc); + void (*unlockDP)(__GLdrawablePrivate *glPriv); + + /* exported */ + void *wsPriv; /* pointer to the window system DrawablePrivate */ +#ifdef __cplusplus + void *privatePtr; +#else + void *private; +#endif + void (*freePrivate)(__GLdrawablePrivate *); + + /* client data */ + void *other; +}; + +/* +** Macros to lock/unlock the drawable private +*/ +#if defined(DEBUG) +#define __GL_LOCK_DP(glPriv,gc) \ + (*(glPriv)->lockDP)(glPriv,gc); \ + (glPriv)->lockLine[(glPriv)->lockRefCount] = __LINE__; \ + (glPriv)->lockFile[(glPriv)->lockRefCount] = __FILE__; \ + (glPriv)->lockRefCount++ +#define __GL_UNLOCK_DP(glPriv) \ + (glPriv)->lockRefCount--; \ + (glPriv)->lockLine[(glPriv)->lockRefCount] = 0; \ + (glPriv)->lockFile[(glPriv)->lockRefCount] = NULL; \ + (*(glPriv)->unlockDP)(glPriv) +#else /* DEBUG */ +#define __GL_LOCK_DP(glPriv,gc) (*(glPriv)->lockDP)(glPriv,gc) +#define __GL_UNLOCK_DP(glPriv) (*(glPriv)->unlockDP)(glPriv) +#endif /* DEBUG */ + + +/* +** Procedures which are imported by the GL from the surrounding +** "operating system". Math functions are not considered part of the +** "operating system". +*/ +typedef struct __GLimportsRec { + /* Memory management */ + void * (*malloc)(__GLcontext *gc, size_t size); + void *(*calloc)(__GLcontext *gc, size_t numElem, size_t elemSize); + void *(*realloc)(__GLcontext *gc, void *oldAddr, size_t newSize); + void (*free)(__GLcontext *gc, void *addr); + + /* Error handling */ + void (*warning)(__GLcontext *gc, char *fmt); + void (*fatal)(__GLcontext *gc, char *fmt); + + /* other system calls */ + char *(CAPI *getenv)(__GLcontext *gc, const char *var); + int (CAPI *atoi)(__GLcontext *gc, const char *str); + int (CAPI *sprintf)(__GLcontext *gc, char *str, const char *fmt, ...); + void *(CAPI *fopen)(__GLcontext *gc, const char *path, const char *mode); + int (CAPI *fclose)(__GLcontext *gc, void *stream); + int (CAPI *fprintf)(__GLcontext *gc, void *stream, const char *fmt, ...); + + /* Drawing surface management */ + __GLdrawablePrivate *(*getDrawablePrivate)(__GLcontext *gc); + + /* Pointer to the window system context */ + void *wscx; + + /* Operating system dependent data goes here */ + void *other; +} __GLimports; + +/************************************************************************/ + +/* +** Procedures which are exported by the GL to the surrounding "operating +** system" so that it can manage multiple GL context's. +*/ +typedef struct __GLexportsRec { + /* Context management (return GL_FALSE on failure) */ + GLboolean (*destroyContext)(__GLcontext *gc); + GLboolean (*loseCurrent)(__GLcontext *gc); + GLboolean (*makeCurrent)(__GLcontext *gc); + GLboolean (*shareContext)(__GLcontext *gc, __GLcontext *gcShare); + GLboolean (*copyContext)(__GLcontext *dst, const __GLcontext *src, GLuint mask); + GLboolean (*forceCurrent)(__GLcontext *gc); + + /* Drawing surface notification callbacks */ + GLboolean (*notifyResize)(__GLcontext *gc); + void (*notifyDestroy)(__GLcontext *gc); + void (*notifySwapBuffers)(__GLcontext *gc); + + /* Dispatch table override control for external agents like libGLS */ + struct __GLdispatchStateRec* (*dispatchExec)(__GLcontext *gc); + void (*beginDispatchOverride)(__GLcontext *gc); + void (*endDispatchOverride)(__GLcontext *gc); +} __GLexports; + +/************************************************************************/ + +/* +** This must be the first member of a __GLcontext structure. This is the +** only part of a context that is exposed to the outside world; everything +** else is opaque. +*/ +struct __GLinterfaceRec { + __GLimports imports; + __GLexports exports; +}; + +extern __GLcontext *__glCoreCreateContext(__GLimports *, __GLcontextModes *); +extern void __glCoreNopDispatch(void); + +#endif /* __gl_core_h_ */ Index: dll/opengl/opengl32/mesa/glheader.h =================================================================== --- dll/opengl/opengl32/mesa/glheader.h (revision 0) +++ dll/opengl/opengl32/mesa/glheader.h (working copy) @@ -0,0 +1,268 @@ +/* $Id: glheader.h,v 1.21 2001/06/15 15:22:07 brianp Exp $ */ + +/* + * Mesa 3-D graphics library + * Version: 3.5 + * + * Copyright (C) 1999-2001 Brian Paul 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 + * BRIAN PAUL 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. + */ + +#pragma once + +#include +#include +#include +#include + +#include + +#define GL_GLEXT_PROTOTYPES +#include +#include + +#ifndef CAPI +#define CAPI +#endif +#include "glcore.h" + +/* Function inlining */ +#if defined(__GNUC__) +# define INLINE __inline__ +#elif defined(__MSC__) +# define INLINE __inline +#else +# define INLINE +#endif + +/* Create a macro so that asm functions can be linked into compilers other + * than GNU C + */ +#ifndef _ASMAPI +#if !defined( __GNUC__ ) && !defined( VMS ) +#define _ASMAPI __cdecl +#else +#define _ASMAPI +#endif +#ifdef PTR_DECL_IN_FRONT +#define _ASMAPIP * _ASMAPI +#else +#define _ASMAPIP _ASMAPI * +#endif +#endif + +#ifdef USE_X86_ASM +#define _NORMAPI _ASMAPI +#define _NORMAPIP _ASMAPIP +#else +#define _NORMAPI +#define _NORMAPIP * +#endif + +#ifdef DEBUG +# define ASSERT(X) assert(X) +#else +# define ASSERT(X) +#endif + +typedef union { GLfloat f; GLint i; } fi_type; + +// #ifndef GLHEADER_H +// #define GLHEADER_H + + +// /* + // * This is the top-most include file of the Mesa sources. + // * It includes gl.h and all system headers which are needed. + // * Other Mesa source files should _not_ directly include any system + // * headers. This allows Mesa to be integrated into XFree86 and + // * allows system-dependent hacks/work-arounds to be collected in one place. + // * + // * If you touch this file, everything gets recompiled! + // * + // * This file should be included before any other header in the .c files. + // * + // * Put compiler/OS/assembly pragmas and macros here to avoid + // * cluttering other source files. + // */ + + + +// #ifdef XFree86LOADER +// #include "xf86_ansic.h" +// #else +// #include +// #include +// /* If we can use Compaq's Fast Math Library on Alpha */ +// #if defined(__alpha__) && defined(CCPML) +// #include +// #else +// #include +// #endif +// #include +// #include +// #include +// #include +// #if defined(__linux__) && defined(__i386__) +// #include +// #endif +// #endif +// #include + + +// #ifdef HAVE_CONFIG_H +// #include "conf.h" +// #endif + + + +// #if defined(_WIN32) && !defined(__WIN32__) && !defined(__CYGWIN__) +// # define __WIN32__ +// #endif + +// /* compatability guard so we don't need to change client code */ + +// #if defined(_WIN32) && !defined(_WINDEF_) && !defined(_GNU_H_WINDOWS32_BASE) && !defined(OPENSTEP) && !defined(__CYGWIN__) +// #if 0 +// # define CALLBACK GLCALLBACK +// typedef void *HGLRC; +// typedef void *HDC; +// #endif +// typedef int (GLAPIENTRY *PROC)(); +// typedef unsigned long COLORREF; +// #endif + + +// /* Make sure we include glext.h from gl.h */ +// #define GL_GLEXT_PROTOTYPES + + +// #if defined(_WIN32) && !defined(_WINGDI_) && !defined(_GNU_H_WINDOWS32_DEFINES) && !defined(OPENSTEP) +// # define WGL_FONT_LINES 0 +// # define WGL_FONT_POLYGONS 1 +// #ifndef _GNU_H_WINDOWS32_FUNCTIONS +// # ifdef UNICODE +// # define wglUseFontBitmaps wglUseFontBitmapsW +// # define wglUseFontOutlines wglUseFontOutlinesW +// # else +// # define wglUseFontBitmaps wglUseFontBitmapsA +// # define wglUseFontOutlines wglUseFontOutlinesA +// # endif /* !UNICODE */ +// #endif /* _GNU_H_WINDOWS32_FUNCTIONS */ +// typedef struct tagLAYERPLANEDESCRIPTOR LAYERPLANEDESCRIPTOR, *PLAYERPLANEDESCRIPTOR, *LPLAYERPLANEDESCRIPTOR; +// typedef struct _GLYPHMETRICSFLOAT GLYPHMETRICSFLOAT, *PGLYPHMETRICSFLOAT, *LPGLYPHMETRICSFLOAT; +// typedef struct tagPIXELFORMATDESCRIPTOR PIXELFORMATDESCRIPTOR, *PPIXELFORMATDESCRIPTOR, *LPPIXELFORMATDESCRIPTOR; +// #if !defined(GLX_USE_MESA) +// #include +// #endif +// #endif + + +// /* This is a macro on IRIX */ +// #ifdef _P +// #undef _P +// #endif + + + +// #include "GL/gl.h" +// #include "GL/glext.h" + + +// #ifndef CAPI +// #define CAPI +// #endif +// #include "glcore.h" + + + +// /* Disable unreachable code warnings for Watcom C++ */ +// #ifdef __WATCOMC__ +// #pragma disable_message(201) +// #endif + + +// /* Turn off macro checking systems used by other libraries */ +// #ifdef CHECK +// #undef CHECK +// #endif + + +// /* Create a macro so that asm functions can be linked into compilers other + // * than GNU C + // */ +// #ifndef _ASMAPI +// #if !defined( __GNUC__ ) && !defined( VMS ) +// #define _ASMAPI __cdecl +// #else +// #define _ASMAPI +// #endif +// #ifdef PTR_DECL_IN_FRONT +// #define _ASMAPIP * _ASMAPI +// #else +// #define _ASMAPIP _ASMAPI * +// #endif +// #endif + +// #ifdef USE_X86_ASM +// #define _NORMAPI _ASMAPI +// #define _NORMAPIP _ASMAPIP +// #else +// #define _NORMAPI +// #define _NORMAPIP * +// #endif + + +// /* Function inlining */ +// #if defined(__GNUC__) +// # define INLINE __inline__ +// #elif defined(__MSC__) +// # define INLINE __inline +// #else +// # define INLINE +// #endif + + +// /* Some compilers don't like some of Mesa's const usage */ +// #ifdef NO_CONST +// # define CONST +// #else +// # define CONST const +// #endif + + +// #ifdef DEBUG +// # define ASSERT(X) assert(X) +// #else +// # define ASSERT(X) +// #endif + + +// /* + // * Sometimes we treat GLfloats as GLints. On x86 systems, moving a float + // * as a int (thereby using integer registers instead of fp registers) is + // * a performance win. Typically, this can be done with ordinary casts. + // * But with gcc's -fstrict-aliasing flag (which defaults to on in gcc 3.0) + // * these casts generate warnings. + // * The following union typedef is used to solve that. + // */ +// typedef union { GLfloat f; GLint i; } fi_type; + + +// #endif /* GLHEADER_H */ Index: dll/opengl/opengl32/mesa/glthread.c =================================================================== --- dll/opengl/opengl32/mesa/glthread.c (revision 0) +++ dll/opengl/opengl32/mesa/glthread.c (working copy) @@ -0,0 +1,332 @@ +/* $Id: glthread.c,v 1.8 2001/03/12 00:48:38 gareth Exp $ */ + +/* + * Mesa 3-D graphics library + * Version: 3.5 + * + * Copyright (C) 1999-2001 Brian Paul 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 + * BRIAN PAUL 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. + */ + + +/* + * XXX There's probably some work to do in order to make this file + * truly reusable outside of Mesa. First, the glheader.h include must go. + */ + + +#ifdef PC_ALL +#include "all.h" +#else +#include "glheader.h" +#include "glthread.h" +#endif + + +/* + * This file should still compile even when THREADS is not defined. + * This is to make things easier to deal with on the makefile scene.. + */ +#ifdef THREADS +#include + +/* + * Error messages + */ +#define INIT_TSD_ERROR "_glthread_: failed to allocate key for thread specific data" +#define GET_TSD_ERROR "_glthread_: failed to get thread specific data" +#define SET_TSD_ERROR "_glthread_: thread failed to set thread specific data" + + +/* + * Magic number to determine if a TSD object has been initialized. + * Kind of a hack but there doesn't appear to be a better cross-platform + * solution. + */ +#define INIT_MAGIC 0xff8adc98 + + + +/* + * POSIX Threads -- The best way to go if your platform supports them. + * Solaris >= 2.5 have POSIX threads, IRIX >= 6.4 reportedly + * has them, and many of the free Unixes now have them. + * Be sure to use appropriate -mt or -D_REENTRANT type + * compile flags when building. + */ +#ifdef PTHREADS + +unsigned long +_glthread_GetID(void) +{ + return (unsigned long) pthread_self(); +} + + +void +_glthread_InitTSD(_glthread_TSD *tsd) +{ + if (pthread_key_create(&tsd->key, NULL/*free*/) != 0) { + perror(INIT_TSD_ERROR); + exit(-1); + } + tsd->initMagic = INIT_MAGIC; +} + + +void * +_glthread_GetTSD(_glthread_TSD *tsd) +{ + if (tsd->initMagic != (int) INIT_MAGIC) { + _glthread_InitTSD(tsd); + } + return pthread_getspecific(tsd->key); +} + + +void +_glthread_SetTSD(_glthread_TSD *tsd, void *ptr) +{ + if (tsd->initMagic != (int) INIT_MAGIC) { + _glthread_InitTSD(tsd); + } + if (pthread_setspecific(tsd->key, ptr) != 0) { + perror(SET_TSD_ERROR); + exit(-1); + } +} + +#endif /* PTHREADS */ + + + +/* + * Solaris/Unix International Threads -- Use only if POSIX threads + * aren't available on your Unix platform. Solaris 2.[34] are examples + * of platforms where this is the case. Be sure to use -mt and/or + * -D_REENTRANT when compiling. + */ +#ifdef SOLARIS_THREADS +#define USE_LOCK_FOR_KEY /* undef this to try a version without + lock for the global key... */ + +unsigned long +_glthread_GetID(void) +{ + abort(); /* XXX not implemented yet */ + return (unsigned long) 0; +} + + +void +_glthread_InitTSD(_glthread_TSD *tsd) +{ + if ((errno = mutex_init(&tsd->keylock, 0, NULL)) != 0 || + (errno = thr_keycreate(&(tsd->key), free)) != 0) { + perror(INIT_TSD_ERROR); + exit(-1); + } + tsd->initMagic = INIT_MAGIC; +} + + +void * +_glthread_GetTSD(_glthread_TSD *tsd) +{ + void* ret; + if (tsd->initMagic != INIT_MAGIC) { + _glthread_InitTSD(tsd); + } +#ifdef USE_LOCK_FOR_KEY + mutex_lock(&tsd->keylock); + thr_getspecific(tsd->key, &ret); + mutex_unlock(&tsd->keylock); +#else + if ((errno = thr_getspecific(tsd->key, &ret)) != 0) { + perror(GET_TSD_ERROR); + exit(-1); + } +#endif + return ret; +} + + +void +_glthread_SetTSD(_glthread_TSD *tsd, void *ptr) +{ + if (tsd->initMagic != INIT_MAGIC) { + _glthread_InitTSD(tsd); + } + if ((errno = thr_setspecific(tsd->key, ptr)) != 0) { + perror(SET_TSD_ERROR); + exit(-1); + } +} + +#undef USE_LOCK_FOR_KEY +#endif /* SOLARIS_THREADS */ + + + +/* + * Win32 Threads. The only available option for Windows 95/NT. + * Be sure that you compile using the Multithreaded runtime, otherwise + * bad things will happen. + */ +#ifdef WIN32_THREADS + +unsigned long +_glthread_GetID(void) +{ + abort(); /* XXX not implemented yet */ + return (unsigned long) 0; +} + + +void +_glthread_InitTSD(_glthread_TSD *tsd) +{ + tsd->key = TlsAlloc(); + if (tsd->key == 0xffffffff) { + /* Can Windows handle stderr messages for non-console + applications? Does Windows have perror? */ + /* perror(SET_INIT_ERROR);*/ + exit(-1); + } + tsd->initMagic = INIT_MAGIC; +} + + +void * +_glthread_GetTSD(_glthread_TSD *tsd) +{ + if (tsd->initMagic != INIT_MAGIC) { + _glthread_InitTSD(tsd); + } + return TlsGetValue(tsd->key); +} + + +void +_glthread_SetTSD(_glthread_TSD *tsd, void *ptr) +{ + /* the following code assumes that the _glthread_TSD has been initialized + to zero at creation */ + if (tsd->initMagic != INIT_MAGIC) { + _glthread_InitTSD(tsd); + } + if (TlsSetValue(tsd->key, ptr) == 0) { + /* Can Windows handle stderr messages for non-console + applications? Does Windows have perror? */ + /* perror(SET_TSD_ERROR);*/ + exit(-1); + } +} + +#endif /* WIN32_THREADS */ + + + +/* + * XFree86 has its own thread wrapper, Xthreads.h + * We wrap it again for GL. + */ +#ifdef XTHREADS + +unsigned long +_glthread_GetID(void) +{ + return (unsigned long) xthread_self(); +} + + +void +_glthread_InitTSD(_glthread_TSD *tsd) +{ + if (xthread_key_create(&tsd->key, NULL) != 0) { + perror(INIT_TSD_ERROR); + exit(-1); + } + tsd->initMagic = INIT_MAGIC; +} + + +void * +_glthread_GetTSD(_glthread_TSD *tsd) +{ + void *ptr; + if (tsd->initMagic != INIT_MAGIC) { + _glthread_InitTSD(tsd); + } + xthread_get_specific(tsd->key, &ptr); + return ptr; +} + + +void +_glthread_SetTSD(_glthread_TSD *tsd, void *ptr) +{ + if (tsd->initMagic != INIT_MAGIC) { + _glthread_InitTSD(tsd); + } + xthread_set_specific(tsd->key, ptr); +} + +#endif /* XTHREAD */ + + + +#else /* THREADS */ + + +/* + * no-op functions + */ + +unsigned long +_glthread_GetID(void) +{ + return 0; +} + + +void +_glthread_InitTSD(_glthread_TSD *tsd) +{ + (void) tsd; +} + + +void * +_glthread_GetTSD(_glthread_TSD *tsd) +{ + (void) tsd; + return NULL; +} + + +void +_glthread_SetTSD(_glthread_TSD *tsd, void *ptr) +{ + (void) tsd; + (void) ptr; +} + + +#endif /* THREADS */ Index: dll/opengl/opengl32/mesa/glthread.h =================================================================== --- dll/opengl/opengl32/mesa/glthread.h (revision 0) +++ dll/opengl/opengl32/mesa/glthread.h (working copy) @@ -0,0 +1,252 @@ +/* $Id: glthread.h,v 1.8 2001/03/12 00:48:38 gareth Exp $ */ + +/* + * Mesa 3-D graphics library + * Version: 3.5 + * + * Copyright (C) 1999-2001 Brian Paul 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 + * BRIAN PAUL 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. + */ + + +/* + * Thread support for gl dispatch. + * + * Initial version by John Stone (j.stone@acm.org) (johns@cs.umr.edu) + * and Christoph Poliwoda (poliwoda@volumegraphics.com) + * Revised by Keith Whitwell + * Adapted for new gl dispatcher by Brian Paul + * + * + * + * DOCUMENTATION + * + * This thread module exports the following types: + * _glthread_TSD Thread-specific data area + * _glthread_Thread Thread datatype + * _glthread_Mutex Mutual exclusion lock + * + * Macros: + * _glthread_DECLARE_STATIC_MUTEX(name) Declare a non-local mutex + * _glthread_INIT_MUTEX(name) Initialize a mutex + * _glthread_LOCK_MUTEX(name) Lock a mutex + * _glthread_UNLOCK_MUTEX(name) Unlock a mutex + * + * Functions: + * _glthread_GetID(v) Get integer thread ID + * _glthread_InitTSD() Initialize thread-specific data + * _glthread_GetTSD() Get thread-specific data + * _glthread_SetTSD() Set thread-specific data + * + */ + +/* + * If this file is accidentally included by a non-threaded build, + * it should not cause the build to fail, or otherwise cause problems. + * In general, it should only be included when needed however. + */ + +#ifndef GLTHREAD_H +#define GLTHREAD_H + + +#if defined(PTHREADS) || defined(SOLARIS_THREADS) || defined(WIN32_THREADS) || defined(XTHREADS) +#define THREADS +#endif + +#ifdef VMS +#include +#endif + +/* + * POSIX threads. This should be your choice in the Unix world + * whenever possible. When building with POSIX threads, be sure + * to enable any compiler flags which will cause the MT-safe + * libc (if one exists) to be used when linking, as well as any + * header macros for MT-safe errno, etc. For Solaris, this is the -mt + * compiler flag. On Solaris with gcc, use -D_REENTRANT to enable + * proper compiling for MT-safe libc etc. + */ +#if defined(PTHREADS) +#include /* POSIX threads headers */ + +typedef struct { + pthread_key_t key; + int initMagic; +} _glthread_TSD; + +typedef pthread_t _glthread_Thread; + +typedef pthread_mutex_t _glthread_Mutex; + +#define _glthread_DECLARE_STATIC_MUTEX(name) \ + static _glthread_Mutex name = PTHREAD_MUTEX_INITIALIZER + +#define _glthread_INIT_MUTEX(name) \ + pthread_mutex_init(&(name), NULL) + +#define _glthread_LOCK_MUTEX(name) \ + (void) pthread_mutex_lock(&(name)) + +#define _glthread_UNLOCK_MUTEX(name) \ + (void) pthread_mutex_unlock(&(name)) + +#endif /* PTHREADS */ + + + + +/* + * Solaris threads. Use only up to Solaris 2.4. + * Solaris 2.5 and higher provide POSIX threads. + * Be sure to compile with -mt on the Solaris compilers, or + * use -D_REENTRANT if using gcc. + */ +#ifdef SOLARIS_THREADS +#include + +typedef struct { + thread_key_t key; + mutex_t keylock; + int initMagic; +} _glthread_TSD; + +typedef thread_t _glthread_Thread; + +typedef mutex_t _glthread_Mutex; + +/* XXX need to really implement mutex-related macros */ +#define _glthread_DECLARE_STATIC_MUTEX(name) static _glthread_Mutex name = 0 +#define _glthread_INIT_MUTEX(name) (void) name +#define _glthread_LOCK_MUTEX(name) (void) name +#define _glthread_UNLOCK_MUTEX(name) (void) name + +#endif /* SOLARIS_THREADS */ + + + + +/* + * Windows threads. Should work with Windows NT and 95. + * IMPORTANT: Link with multithreaded runtime library when THREADS are + * used! + */ +#ifdef WIN32_THREADS +#include +#include + +typedef struct { + DWORD key; + int initMagic; +} _glthread_TSD; + +typedef HANDLE _glthread_Thread; + +typedef CRITICAL_SECTION _glthread_Mutex; + +/* XXX need to really implement mutex-related macros */ +#define _glthread_DECLARE_STATIC_MUTEX(name) static _glthread_Mutex name = {NULL, -1, 0, 0, 0, 0} +#define _glthread_INIT_MUTEX(name) InitializeCriticalSection(&name) +#define _glthread_LOCK_MUTEX(name) EnterCriticalSection(&name) +#define _glthread_UNLOCK_MUTEX(name) LeaveCriticalSection(&name) + +#endif /* WIN32_THREADS */ + + + + +/* + * XFree86 has its own thread wrapper, Xthreads.h + * We wrap it again for GL. + */ +#ifdef XTHREADS +#include "Xthreads.h" + +typedef struct { + xthread_key_t key; + int initMagic; +} _glthread_TSD; + +typedef xthread_t _glthread_Thread; + +typedef xmutex_rec _glthread_Mutex; + +#define _glthread_DECLARE_STATIC_MUTEX(name) \ + static _glthread_Mutex name = XMUTEX_INITIALIZER + +#define _glthread_INIT_MUTEX(name) \ + xmutex_init(&(name)) + +#define _glthread_LOCK_MUTEX(name) \ + (void) xmutex_lock(&(name)) + +#define _glthread_UNLOCK_MUTEX(name) \ + (void) xmutex_unlock(&(name)) + +#endif /* XTHREADS */ + + + + +#ifndef THREADS + +/* + * THREADS not defined + */ + +typedef GLuint _glthread_TSD; + +typedef GLuint _glthread_Thread; + +typedef GLuint _glthread_Mutex; + +#define _glthread_DECLARE_STATIC_MUTEX(name) static _glthread_Mutex name = 0 + +#define _glthread_INIT_MUTEX(name) (void) name + +#define _glthread_LOCK_MUTEX(name) (void) name + +#define _glthread_UNLOCK_MUTEX(name) (void) name + +#endif /* THREADS */ + + + +/* + * Platform independent thread specific data API. + */ + +extern unsigned long +_glthread_GetID(void); + + +extern void +_glthread_InitTSD(_glthread_TSD *); + + +extern void * +_glthread_GetTSD(_glthread_TSD *); + + +extern void +_glthread_SetTSD(_glthread_TSD *, void *); + + + +#endif /* THREADS_H */ Index: dll/opengl/opengl32/mesa/hash.c =================================================================== --- dll/opengl/opengl32/mesa/hash.c (revision 0) +++ dll/opengl/opengl32/mesa/hash.c (working copy) @@ -0,0 +1,310 @@ +/* $Id: hash.c,v 1.10 2001/03/12 00:48:38 gareth Exp $ */ + +/* + * Mesa 3-D graphics library + * Version: 3.5 + * + * Copyright (C) 1999-2001 Brian Paul 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 + * BRIAN PAUL 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. + */ + + +#ifdef PC_HEADER +#include "all.h" +#else +#include "glheader.h" +#include "glthread.h" +#include "hash.h" +#include "mem.h" +#endif + + +/* + * Generic hash table. + * + * This is used to implement display list and texture object lookup. + * NOTE: key=0 is illegal. + */ + + +#define TABLE_SIZE 1024 + +struct HashEntry { + GLuint Key; + void *Data; + struct HashEntry *Next; +}; + +struct _mesa_HashTable { + struct HashEntry *Table[TABLE_SIZE]; + GLuint MaxKey; + _glthread_Mutex Mutex; +}; + + + +/* + * Return pointer to a new, empty hash table. + */ +struct _mesa_HashTable *_mesa_NewHashTable(void) +{ + struct _mesa_HashTable* ret = CALLOC_STRUCT(_mesa_HashTable); + _glthread_INIT_MUTEX(ret->Mutex); + return ret; +} + + + +/* + * Delete a hash table. + */ +void _mesa_DeleteHashTable(struct _mesa_HashTable *table) +{ + GLuint i; + assert(table); + for (i=0;iTable[i]; + while (entry) { + struct HashEntry *next = entry->Next; + FREE(entry); + entry = next; + } + } + FREE(table); +} + + + +/* + * Lookup an entry in the hash table. + * Input: table - the hash table + * key - the key + * Return: user data pointer or NULL if key not in table + */ +void *_mesa_HashLookup(const struct _mesa_HashTable *table, GLuint key) +{ + GLuint pos; + const struct HashEntry *entry; + + assert(table); + assert(key); + + pos = key & (TABLE_SIZE-1); + entry = table->Table[pos]; + while (entry) { + if (entry->Key == key) { + return entry->Data; + } + entry = entry->Next; + } + return NULL; +} + + + +/* + * Insert into the hash table. If an entry with this key already exists + * we'll replace the existing entry. + * Input: table - the hash table + * key - the key (not zero) + * data - pointer to user data + */ +void _mesa_HashInsert(struct _mesa_HashTable *table, GLuint key, void *data) +{ + /* search for existing entry with this key */ + GLuint pos; + struct HashEntry *entry; + + assert(table); + assert(key); + + _glthread_LOCK_MUTEX(table->Mutex); + + if (key > table->MaxKey) + table->MaxKey = key; + + pos = key & (TABLE_SIZE-1); + entry = table->Table[pos]; + while (entry) { + if (entry->Key == key) { + /* replace entry's data */ + entry->Data = data; + _glthread_UNLOCK_MUTEX(table->Mutex); + return; + } + entry = entry->Next; + } + + /* alloc and insert new table entry */ + entry = MALLOC_STRUCT(HashEntry); + entry->Key = key; + entry->Data = data; + entry->Next = table->Table[pos]; + table->Table[pos] = entry; + + _glthread_UNLOCK_MUTEX(table->Mutex); +} + + + +/* + * Remove an entry from the hash table. + * Input: table - the hash table + * key - key of entry to remove + */ +void _mesa_HashRemove(struct _mesa_HashTable *table, GLuint key) +{ + GLuint pos; + struct HashEntry *entry, *prev; + + assert(table); + assert(key); + + _glthread_LOCK_MUTEX(table->Mutex); + + pos = key & (TABLE_SIZE-1); + prev = NULL; + entry = table->Table[pos]; + while (entry) { + if (entry->Key == key) { + /* found it! */ + if (prev) { + prev->Next = entry->Next; + } + else { + table->Table[pos] = entry->Next; + } + FREE(entry); + _glthread_UNLOCK_MUTEX(table->Mutex); + return; + } + prev = entry; + entry = entry->Next; + } + + _glthread_UNLOCK_MUTEX(table->Mutex); +} + + + +/* + * Return the key of the "first" entry in the hash table. + * This is used in the course of deleting all display lists when + * a context is destroyed. + */ +GLuint _mesa_HashFirstEntry(struct _mesa_HashTable *table) +{ + GLuint pos; + assert(table); + _glthread_LOCK_MUTEX(table->Mutex); + for (pos=0; pos < TABLE_SIZE; pos++) { + if (table->Table[pos]) { + _glthread_UNLOCK_MUTEX(table->Mutex); + return table->Table[pos]->Key; + } + } + _glthread_UNLOCK_MUTEX(table->Mutex); + return 0; +} + + + +/* + * Dump contents of hash table for debugging. + */ +void _mesa_HashPrint(const struct _mesa_HashTable *table) +{ + GLuint i; + assert(table); + for (i=0;iTable[i]; + while (entry) { + printf("%u %p\n", entry->Key, entry->Data); + entry = entry->Next; + } + } +} + + + +/* + * Find a block of 'numKeys' adjacent unused hash keys. + * Input: table - the hash table + * numKeys - number of keys needed + * Return: starting key of free block or 0 if failure + */ +GLuint _mesa_HashFindFreeKeyBlock(struct _mesa_HashTable *table, GLuint numKeys) +{ + GLuint maxKey = ~((GLuint) 0); + _glthread_LOCK_MUTEX(table->Mutex); + if (maxKey - numKeys > table->MaxKey) { + /* the quick solution */ + _glthread_UNLOCK_MUTEX(table->Mutex); + return table->MaxKey + 1; + } + else { + /* the slow solution */ + GLuint freeCount = 0; + GLuint freeStart = 1; + GLuint key; + for (key=1; key!=maxKey; key++) { + if (_mesa_HashLookup(table, key)) { + /* darn, this key is already in use */ + freeCount = 0; + freeStart = key+1; + } + else { + /* this key not in use, check if we've found enough */ + freeCount++; + if (freeCount == numKeys) { + _glthread_UNLOCK_MUTEX(table->Mutex); + return freeStart; + } + } + } + /* cannot allocate a block of numKeys consecutive keys */ + _glthread_UNLOCK_MUTEX(table->Mutex); + return 0; + } +} + + + +#ifdef HASH_TEST_HARNESS +int main(int argc, char *argv[]) +{ + int a, b, c; + struct HashTable *t; + + printf("&a = %p\n", &a); + printf("&b = %p\n", &b); + + t = _mesa_NewHashTable(); + _mesa_HashInsert(t, 501, &a); + _mesa_HashInsert(t, 10, &c); + _mesa_HashInsert(t, 0xfffffff8, &b); + _mesa_HashPrint(t); + printf("Find 501: %p\n", _mesa_HashLookup(t,501)); + printf("Find 1313: %p\n", _mesa_HashLookup(t,1313)); + printf("Find block of 100: %d\n", _mesa_HashFindFreeKeyBlock(t, 100)); + _mesa_DeleteHashTable(t); + + return 0; +} +#endif Index: dll/opengl/opengl32/mesa/hash.h =================================================================== --- dll/opengl/opengl32/mesa/hash.h (revision 0) +++ dll/opengl/opengl32/mesa/hash.h (working copy) @@ -0,0 +1,56 @@ +/* $Id: hash.h,v 1.5 2001/03/12 00:48:38 gareth Exp $ */ + +/* + * Mesa 3-D graphics library + * Version: 3.5 + * + * Copyright (C) 1999-2001 Brian Paul 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 + * BRIAN PAUL 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. + */ + + +#ifndef HASH_H +#define HASH_H + + +#include "glheader.h" + + +struct HashTable; + + + +extern struct _mesa_HashTable *_mesa_NewHashTable(void); + +extern void _mesa_DeleteHashTable(struct _mesa_HashTable *table); + +extern void *_mesa_HashLookup(const struct _mesa_HashTable *table, GLuint key); + +extern void _mesa_HashInsert(struct _mesa_HashTable *table, GLuint key, void *data); + +extern void _mesa_HashRemove(struct _mesa_HashTable *table, GLuint key); + +extern GLuint _mesa_HashFirstEntry(struct _mesa_HashTable *table); + +extern void _mesa_HashPrint(const struct _mesa_HashTable *table); + +extern GLuint _mesa_HashFindFreeKeyBlock(struct _mesa_HashTable *table, GLuint numKeys); + + +#endif Index: dll/opengl/opengl32/mesa/highpc.c =================================================================== --- dll/opengl/opengl32/mesa/highpc.c (revision 0) +++ dll/opengl/opengl32/mesa/highpc.c (working copy) @@ -0,0 +1,121 @@ +/* $Id: highpc.c,v 1.6 2001/03/12 00:48:38 gareth Exp $ */ + +/* + * Mesa 3-D graphics library + * Version: 3.5 + * + * Copyright (C) 1999-2001 Brian Paul 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 + * BRIAN PAUL 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. + */ + + +#ifdef PC_HEADER +#include "all.h" +#else +#include "glheader.h" +#include "mtypes.h" +#endif + + +/* + * This is the highest address in Mesa + */ +extern void mesa_highpc(void); /* silence compiler warning */ +void mesa_highpc(void) { } + +#if defined(__GNUC__) && defined(__linux__) + +void monstartup( char *lowpc, char *highpc ); +void _mcleanup( void ); +void mesa_lowpc( void ); +void mesa_highpc( void ); + +static int profile = 0; + +extern void force_init_prof( void ); /* silence compiler warning */ +void force_init_prof( void ) +{ + FILE *fp; + + if (profile) return; + + profile = 1; + + monstartup( (char *)mesa_lowpc, (char *)mesa_highpc ); + + fprintf(stderr, "Starting profiling, %x %x\n", + (unsigned int)mesa_lowpc, + (unsigned int)mesa_highpc); + + if ((fp = fopen( "mesa_lowpc", "w" )) != NULL) { + fprintf( fp, "0x%08x ", (unsigned int)mesa_lowpc ); + fclose( fp ); + } +} + +/* + * Start profiling + */ +extern void init_prof(void); /* silence compiler warning */ +void __attribute__ ((constructor)) +init_prof( void ) +{ + FILE *fp; + char *s = getenv("MESA_MON"); + + if (s == NULL || atoi(s) == 0) + return; + + profile = 1; + + monstartup( (char *)mesa_lowpc, (char *)mesa_highpc ); + + fprintf(stderr, "Starting profiling, %x %x\n", + (unsigned int)mesa_lowpc, + (unsigned int)mesa_highpc); + + if ((fp = fopen( "mesa_lowpc", "w" )) != NULL) { + fprintf( fp, "0x%08x ", (unsigned int)mesa_lowpc ); + fclose( fp ); + } +} + + + +/* + * Finish profiling + */ +extern void fini_prof(void); /* silence compiler warning */ +void __attribute__ ((destructor)) +fini_prof( void ) +{ + if (profile) { + _mcleanup( ); + + fprintf(stderr, "Finished profiling\n"); + } +} + +#else + +void force_init_prof( void ) +{ +} + +#endif Index: dll/opengl/opengl32/mesa/hint.c =================================================================== --- dll/opengl/opengl32/mesa/hint.c (revision 0) +++ dll/opengl/opengl32/mesa/hint.c (working copy) @@ -0,0 +1,134 @@ +/* $Id: hint.c,v 1.10 2001/05/21 16:41:03 brianp Exp $ */ + +/* + * Mesa 3-D graphics library + * Version: 3.5 + * + * Copyright (C) 1999-2001 Brian Paul 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 + * BRIAN PAUL 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. + */ + + +#ifdef PC_HEADER +#include "all.h" +#else +#include "glheader.h" +#include "enums.h" +#include "context.h" +#include "hint.h" +#include "state.h" +#endif + + + +void +_mesa_Hint( GLenum target, GLenum mode ) +{ + GET_CURRENT_CONTEXT(ctx); + ASSERT_OUTSIDE_BEGIN_END(ctx); + (void) _mesa_try_Hint( ctx, target, mode ); +} + + +GLboolean +_mesa_try_Hint( GLcontext *ctx, GLenum target, GLenum mode ) +{ + if (MESA_VERBOSE & VERBOSE_API) + fprintf(stderr, "glHint %s %d\n", _mesa_lookup_enum_by_nr(target), mode); + + if (mode != GL_NICEST && mode != GL_FASTEST && mode != GL_DONT_CARE) { + _mesa_error(ctx, GL_INVALID_ENUM, "glHint(mode)"); + return GL_FALSE; + } + + switch (target) { + case GL_FOG_HINT: + if (ctx->Hint.Fog == mode) + return GL_TRUE; + FLUSH_VERTICES(ctx, _NEW_HINT); + ctx->Hint.Fog = mode; + break; + case GL_LINE_SMOOTH_HINT: + if (ctx->Hint.LineSmooth == mode) + return GL_TRUE; + FLUSH_VERTICES(ctx, _NEW_HINT); + ctx->Hint.LineSmooth = mode; + break; + case GL_PERSPECTIVE_CORRECTION_HINT: + if (ctx->Hint.PerspectiveCorrection == mode) + return GL_TRUE; + FLUSH_VERTICES(ctx, _NEW_HINT); + ctx->Hint.PerspectiveCorrection = mode; + break; + case GL_POINT_SMOOTH_HINT: + if (ctx->Hint.PointSmooth == mode) + return GL_TRUE; + FLUSH_VERTICES(ctx, _NEW_HINT); + ctx->Hint.PointSmooth = mode; + break; + case GL_POLYGON_SMOOTH_HINT: + if (ctx->Hint.PolygonSmooth == mode) + return GL_TRUE; + FLUSH_VERTICES(ctx, _NEW_HINT); + ctx->Hint.PolygonSmooth = mode; + break; + + /* GL_EXT_clip_volume_hint */ + case GL_CLIP_VOLUME_CLIPPING_HINT_EXT: + if (ctx->Hint.ClipVolumeClipping == mode) + return GL_TRUE; + FLUSH_VERTICES(ctx, _NEW_HINT); + ctx->Hint.ClipVolumeClipping = mode; + break; + + /* GL_ARB_texture_compression */ + case GL_TEXTURE_COMPRESSION_HINT_ARB: + if (!ctx->Extensions.ARB_texture_compression) { + _mesa_error(ctx, GL_INVALID_ENUM, "glHint(target)"); + return GL_FALSE; + } + if (ctx->Hint.TextureCompression == mode) + return GL_TRUE; + FLUSH_VERTICES(ctx, _NEW_HINT); + ctx->Hint.TextureCompression = mode; + break; + + /* GL_SGIS_generate_mipmap */ + case GL_GENERATE_MIPMAP_HINT_SGIS: + if (!ctx->Extensions.SGIS_generate_mipmap) { + _mesa_error(ctx, GL_INVALID_ENUM, "glHint(target)"); + return GL_FALSE; + } + if (ctx->Hint.GenerateMipmap == mode) + return GL_TRUE; + FLUSH_VERTICES(ctx, _NEW_HINT); + ctx->Hint.GenerateMipmap = mode; + break; + + default: + _mesa_error(ctx, GL_INVALID_ENUM, "glHint(target)"); + return GL_FALSE; + } + + if (ctx->Driver.Hint) { + (*ctx->Driver.Hint)( ctx, target, mode ); + } + + return GL_TRUE; +} Index: dll/opengl/opengl32/mesa/hint.h =================================================================== --- dll/opengl/opengl32/mesa/hint.h (revision 0) +++ dll/opengl/opengl32/mesa/hint.h (working copy) @@ -0,0 +1,42 @@ +/* $Id: hint.h,v 1.3 2001/01/24 04:56:20 brianp Exp $ */ + +/* + * Mesa 3-D graphics library + * Version: 3.5 + * + * Copyright (C) 1999-2001 Brian Paul 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 + * BRIAN PAUL 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. + */ + + +#ifndef HINT_H +#define HINT_H + + +#include "mtypes.h" + + +extern GLboolean +_mesa_try_Hint( GLcontext *ctx, GLenum target, GLenum mode ); + +extern void +_mesa_Hint( GLenum target, GLenum mode ); + + +#endif Index: dll/opengl/opengl32/mesa/histogram.c =================================================================== --- dll/opengl/opengl32/mesa/histogram.c (revision 0) +++ dll/opengl/opengl32/mesa/histogram.c (working copy) @@ -0,0 +1,1035 @@ +/* $Id: histogram.c,v 1.10 2001/03/12 00:48:38 gareth Exp $ */ + +/* + * Mesa 3-D graphics library + * Version: 3.5 + * + * Copyright (C) 1999-2001 Brian Paul 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 + * BRIAN PAUL 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. + */ + + +#ifdef PC_HEADER +#include "all.h" +#else +#include "glheader.h" +#include "colormac.h" +#include "context.h" +#include "image.h" +#include "histogram.h" +#include "mmath.h" +#endif + + +/* + * XXX the packed pixel formats haven't been tested. + */ +static void +pack_histogram( GLcontext *ctx, + GLuint n, CONST GLuint rgba[][4], + GLenum format, GLenum type, GLvoid *destination, + const struct gl_pixelstore_attrib *packing ) +{ + const GLint comps = _mesa_components_in_format(format); + GLuint luminance[MAX_WIDTH]; + + if (format == GL_LUMINANCE || format == GL_LUMINANCE_ALPHA) { + GLuint i; + for (i = 0; i < n; i++) { + luminance[i] = rgba[i][RCOMP] + rgba[i][GCOMP] + rgba[i][BCOMP]; + } + } + +#define PACK_MACRO(TYPE) \ + { \ + GLuint i; \ + switch (format) { \ + case GL_RED: \ + for (i=0;iSwapBytes) { + _mesa_swap2(dst, n * comps); + } + } + break; + case GL_SHORT: + { + GLshort *dst = (GLshort *) destination; + PACK_MACRO(GLshort); + if (packing->SwapBytes) { + _mesa_swap2((GLushort *) dst, n * comps); + } + } + break; + case GL_UNSIGNED_INT: + { + GLuint *dst = (GLuint *) destination; + PACK_MACRO(GLuint); + if (packing->SwapBytes) { + _mesa_swap4(dst, n * comps); + } + } + break; + case GL_INT: + { + GLint *dst = (GLint *) destination; + PACK_MACRO(GLint); + if (packing->SwapBytes) { + _mesa_swap4((GLuint *) dst, n * comps); + } + } + break; + case GL_FLOAT: + { + GLfloat *dst = (GLfloat *) destination; + PACK_MACRO(GLfloat); + if (packing->SwapBytes) { + _mesa_swap4((GLuint *) dst, n * comps); + } + } + break; + case GL_UNSIGNED_BYTE_3_3_2: + if (format == GL_RGB) { + GLubyte *dst = (GLubyte *) destination; + GLuint i; + for (i = 0; i < n; i++) { + dst[i] = ((rgba[i][RCOMP] & 0x7) << 5) + | ((rgba[i][GCOMP] & 0x7) << 2) + | ((rgba[i][BCOMP] & 0x3) ); + } + } + else { + GLubyte *dst = (GLubyte *) destination; + GLuint i; + ASSERT(format == GL_BGR); + for (i = 0; i < n; i++) { + dst[i] = ((rgba[i][BCOMP] & 0x7) << 5) + | ((rgba[i][GCOMP] & 0x7) << 2) + | ((rgba[i][RCOMP] & 0x3) ); + } + } + break; + case GL_UNSIGNED_BYTE_2_3_3_REV: + if (format == GL_RGB) { + GLubyte *dst = (GLubyte *) destination; + GLuint i; + for (i = 0; i < n; i++) { + dst[i] = ((rgba[i][RCOMP] & 0x3) << 6) + | ((rgba[i][GCOMP] & 0x7) << 3) + | ((rgba[i][BCOMP] & 0x7) ); + } + } + else { + GLubyte *dst = (GLubyte *) destination; + GLuint i; + ASSERT(format == GL_BGR); + for (i = 0; i < n; i++) { + dst[i] = ((rgba[i][BCOMP] & 0x3) << 6) + | ((rgba[i][GCOMP] & 0x7) << 3) + | ((rgba[i][RCOMP] & 0x7) ); + } + } + break; + case GL_UNSIGNED_SHORT_5_6_5: + if (format == GL_RGB) { + GLushort *dst = (GLushort *) destination; + GLuint i; + for (i = 0; i < n; i++) { + dst[i] = ((rgba[i][RCOMP] & 0x1f) << 11) + | ((rgba[i][GCOMP] & 0x3f) << 5) + | ((rgba[i][BCOMP] & 0x1f) ); + } + } + else { + GLushort *dst = (GLushort *) destination; + GLuint i; + ASSERT(format == GL_BGR); + for (i = 0; i < n; i++) { + dst[i] = ((rgba[i][BCOMP] & 0x1f) << 11) + | ((rgba[i][GCOMP] & 0x3f) << 5) + | ((rgba[i][RCOMP] & 0x1f) ); + } + } + break; + case GL_UNSIGNED_SHORT_5_6_5_REV: + if (format == GL_RGB) { + GLushort *dst = (GLushort *) destination; + GLuint i; + for (i = 0; i < n; i++) { + dst[i] = ((rgba[i][BCOMP] & 0x1f) << 11) + | ((rgba[i][GCOMP] & 0x3f) << 5) + | ((rgba[i][RCOMP] & 0x1f) ); + } + } + else { + GLushort *dst = (GLushort *) destination; + GLuint i; + ASSERT(format == GL_BGR); + for (i = 0; i < n; i++) { + dst[i] = ((rgba[i][RCOMP] & 0x1f) << 11) + | ((rgba[i][GCOMP] & 0x3f) << 5) + | ((rgba[i][BCOMP] & 0x1f) ); + } + } + break; + case GL_UNSIGNED_SHORT_4_4_4_4: + if (format == GL_RGBA) { + GLushort *dst = (GLushort *) destination; + GLuint i; + for (i = 0; i < n; i++) { + dst[i] = ((rgba[i][RCOMP] & 0xf) << 12) + | ((rgba[i][GCOMP] & 0xf) << 8) + | ((rgba[i][BCOMP] & 0xf) << 4) + | ((rgba[i][ACOMP] & 0xf) ); + } + } + else if (format == GL_BGRA) { + GLushort *dst = (GLushort *) destination; + GLuint i; + for (i = 0; i < n; i++) { + dst[i] = ((rgba[i][BCOMP] & 0xf) << 12) + | ((rgba[i][GCOMP] & 0xf) << 8) + | ((rgba[i][RCOMP] & 0xf) << 4) + | ((rgba[i][ACOMP] & 0xf) ); + } + } + else { + GLushort *dst = (GLushort *) destination; + GLuint i; + ASSERT(format == GL_ABGR_EXT); + for (i = 0; i < n; i++) { + dst[i] = ((rgba[i][ACOMP] & 0xf) << 12) + | ((rgba[i][BCOMP] & 0xf) << 8) + | ((rgba[i][GCOMP] & 0xf) << 4) + | ((rgba[i][RCOMP] & 0xf) ); + } + } + break; + case GL_UNSIGNED_SHORT_4_4_4_4_REV: + if (format == GL_RGBA) { + GLushort *dst = (GLushort *) destination; + GLuint i; + for (i = 0; i < n; i++) { + dst[i] = ((rgba[i][ACOMP] & 0xf) << 12) + | ((rgba[i][BCOMP] & 0xf) << 8) + | ((rgba[i][GCOMP] & 0xf) << 4) + | ((rgba[i][RCOMP] & 0xf) ); + } + } + else if (format == GL_BGRA) { + GLushort *dst = (GLushort *) destination; + GLuint i; + for (i = 0; i < n; i++) { + dst[i] = ((rgba[i][ACOMP] & 0xf) << 12) + | ((rgba[i][RCOMP] & 0xf) << 8) + | ((rgba[i][GCOMP] & 0xf) << 4) + | ((rgba[i][BCOMP] & 0xf) ); + } + } + else { + GLushort *dst = (GLushort *) destination; + GLuint i; + ASSERT(format == GL_ABGR_EXT); + for (i = 0; i < n; i++) { + dst[i] = ((rgba[i][RCOMP] & 0xf) << 12) + | ((rgba[i][GCOMP] & 0xf) << 8) + | ((rgba[i][BCOMP] & 0xf) << 4) + | ((rgba[i][ACOMP] & 0xf) ); + } + } + break; + case GL_UNSIGNED_SHORT_5_5_5_1: + if (format == GL_RGBA) { + GLushort *dst = (GLushort *) destination; + GLuint i; + for (i = 0; i < n; i++) { + dst[i] = ((rgba[i][RCOMP] & 0x1f) << 11) + | ((rgba[i][GCOMP] & 0x1f) << 6) + | ((rgba[i][BCOMP] & 0x1f) << 1) + | ((rgba[i][ACOMP] & 0x1) ); + } + } + else if (format == GL_BGRA) { + GLushort *dst = (GLushort *) destination; + GLuint i; + for (i = 0; i < n; i++) { + dst[i] = ((rgba[i][BCOMP] & 0x1f) << 11) + | ((rgba[i][GCOMP] & 0x1f) << 6) + | ((rgba[i][RCOMP] & 0x1f) << 1) + | ((rgba[i][ACOMP] & 0x1) ); + } + } + else { + GLushort *dst = (GLushort *) destination; + GLuint i; + ASSERT(format == GL_ABGR_EXT); + for (i = 0; i < n; i++) { + dst[i] = ((rgba[i][ACOMP] & 0x1f) << 11) + | ((rgba[i][BCOMP] & 0x1f) << 6) + | ((rgba[i][GCOMP] & 0x1f) << 1) + | ((rgba[i][RCOMP] & 0x1) ); + } + } + break; + case GL_UNSIGNED_SHORT_1_5_5_5_REV: + if (format == GL_RGBA) { + GLushort *dst = (GLushort *) destination; + GLuint i; + for (i = 0; i < n; i++) { + dst[i] = ((rgba[i][ACOMP] & 0x1f) << 11) + | ((rgba[i][BCOMP] & 0x1f) << 6) + | ((rgba[i][GCOMP] & 0x1f) << 1) + | ((rgba[i][RCOMP] & 0x1) ); + } + } + else if (format == GL_BGRA) { + GLushort *dst = (GLushort *) destination; + GLuint i; + for (i = 0; i < n; i++) { + dst[i] = ((rgba[i][ACOMP] & 0x1f) << 11) + | ((rgba[i][RCOMP] & 0x1f) << 6) + | ((rgba[i][GCOMP] & 0x1f) << 1) + | ((rgba[i][BCOMP] & 0x1) ); + } + } + else { + GLushort *dst = (GLushort *) destination; + GLuint i; + ASSERT(format == GL_ABGR_EXT); + for (i = 0; i < n; i++) { + dst[i] = ((rgba[i][RCOMP] & 0x1f) << 11) + | ((rgba[i][GCOMP] & 0x1f) << 6) + | ((rgba[i][BCOMP] & 0x1f) << 1) + | ((rgba[i][ACOMP] & 0x1) ); + } + } + break; + case GL_UNSIGNED_INT_8_8_8_8: + if (format == GL_RGBA) { + GLuint *dst = (GLuint *) destination; + GLuint i; + for (i = 0; i < n; i++) { + dst[i] = ((rgba[i][RCOMP] & 0xff) << 24) + | ((rgba[i][GCOMP] & 0xff) << 16) + | ((rgba[i][BCOMP] & 0xff) << 8) + | ((rgba[i][ACOMP] & 0xff) ); + } + } + else if (format == GL_BGRA) { + GLuint *dst = (GLuint *) destination; + GLuint i; + for (i = 0; i < n; i++) { + dst[i] = ((rgba[i][BCOMP] & 0xff) << 24) + | ((rgba[i][GCOMP] & 0xff) << 16) + | ((rgba[i][RCOMP] & 0xff) << 8) + | ((rgba[i][ACOMP] & 0xff) ); + } + } + else { + GLuint *dst = (GLuint *) destination; + GLuint i; + ASSERT(format == GL_ABGR_EXT); + for (i = 0; i < n; i++) { + dst[i] = ((rgba[i][ACOMP] & 0xff) << 24) + | ((rgba[i][BCOMP] & 0xff) << 16) + | ((rgba[i][GCOMP] & 0xff) << 8) + | ((rgba[i][RCOMP] & 0xff) ); + } + } + break; + case GL_UNSIGNED_INT_8_8_8_8_REV: + if (format == GL_RGBA) { + GLuint *dst = (GLuint *) destination; + GLuint i; + for (i = 0; i < n; i++) { + dst[i] = ((rgba[i][ACOMP] & 0xff) << 24) + | ((rgba[i][BCOMP] & 0xff) << 16) + | ((rgba[i][GCOMP] & 0xff) << 8) + | ((rgba[i][RCOMP] & 0xff) ); + } + } + else if (format == GL_BGRA) { + GLuint *dst = (GLuint *) destination; + GLuint i; + for (i = 0; i < n; i++) { + dst[i] = ((rgba[i][ACOMP] & 0xff) << 24) + | ((rgba[i][RCOMP] & 0xff) << 16) + | ((rgba[i][GCOMP] & 0xff) << 8) + | ((rgba[i][BCOMP] & 0xff) ); + } + } + else { + GLuint *dst = (GLuint *) destination; + GLuint i; + ASSERT(format == GL_ABGR_EXT); + for (i = 0; i < n; i++) { + dst[i] = ((rgba[i][RCOMP] & 0xff) << 24) + | ((rgba[i][GCOMP] & 0xff) << 16) + | ((rgba[i][BCOMP] & 0xff) << 8) + | ((rgba[i][ACOMP] & 0xff) ); + } + } + break; + case GL_UNSIGNED_INT_10_10_10_2: + if (format == GL_RGBA) { + GLuint *dst = (GLuint *) destination; + GLuint i; + for (i = 0; i < n; i++) { + dst[i] = ((rgba[i][RCOMP] & 0x3ff) << 22) + | ((rgba[i][GCOMP] & 0x3ff) << 12) + | ((rgba[i][BCOMP] & 0x3ff) << 2) + | ((rgba[i][ACOMP] & 0x3) ); + } + } + else if (format == GL_BGRA) { + GLuint *dst = (GLuint *) destination; + GLuint i; + for (i = 0; i < n; i++) { + dst[i] = ((rgba[i][BCOMP] & 0x3ff) << 22) + | ((rgba[i][GCOMP] & 0x3ff) << 12) + | ((rgba[i][RCOMP] & 0x3ff) << 2) + | ((rgba[i][ACOMP] & 0x3) ); + } + } + else { + GLuint *dst = (GLuint *) destination; + GLuint i; + ASSERT(format == GL_ABGR_EXT); + for (i = 0; i < n; i++) { + dst[i] = ((rgba[i][ACOMP] & 0x3ff) << 22) + | ((rgba[i][BCOMP] & 0x3ff) << 12) + | ((rgba[i][GCOMP] & 0x3ff) << 2) + | ((rgba[i][RCOMP] & 0x3) ); + } + } + break; + case GL_UNSIGNED_INT_2_10_10_10_REV: + if (format == GL_RGBA) { + GLuint *dst = (GLuint *) destination; + GLuint i; + for (i = 0; i < n; i++) { + dst[i] = ((rgba[i][ACOMP] & 0x3ff) << 22) + | ((rgba[i][BCOMP] & 0x3ff) << 12) + | ((rgba[i][GCOMP] & 0x3ff) << 2) + | ((rgba[i][RCOMP] & 0x3) ); + } + } + else if (format == GL_BGRA) { + GLuint *dst = (GLuint *) destination; + GLuint i; + for (i = 0; i < n; i++) { + dst[i] = ((rgba[i][ACOMP] & 0x3ff) << 22) + | ((rgba[i][RCOMP] & 0x3ff) << 12) + | ((rgba[i][GCOMP] & 0x3ff) << 2) + | ((rgba[i][BCOMP] & 0x3) ); + } + } + else { + GLuint *dst = (GLuint *) destination; + GLuint i; + ASSERT(format == GL_ABGR_EXT); + for (i = 0; i < n; i++) { + dst[i] = ((rgba[i][RCOMP] & 0x3ff) << 22) + | ((rgba[i][GCOMP] & 0x3ff) << 12) + | ((rgba[i][BCOMP] & 0x3ff) << 2) + | ((rgba[i][ACOMP] & 0x3) ); + } + } + break; + default: + _mesa_problem(ctx, "Bad type in pack_histogram"); + } + +#undef PACK_MACRO +} + + +/* + * Given an internalFormat token passed to glHistogram or glMinMax, + * return the corresponding base format. + * Return -1 if invalid token. + */ +static GLint +base_histogram_format( GLenum format ) +{ + switch (format) { + case GL_ALPHA: + case GL_ALPHA4: + case GL_ALPHA8: + case GL_ALPHA12: + case GL_ALPHA16: + return GL_ALPHA; + case GL_LUMINANCE: + case GL_LUMINANCE4: + case GL_LUMINANCE8: + case GL_LUMINANCE12: + case GL_LUMINANCE16: + return GL_LUMINANCE; + case GL_LUMINANCE_ALPHA: + case GL_LUMINANCE4_ALPHA4: + case GL_LUMINANCE6_ALPHA2: + case GL_LUMINANCE8_ALPHA8: + case GL_LUMINANCE12_ALPHA4: + case GL_LUMINANCE12_ALPHA12: + case GL_LUMINANCE16_ALPHA16: + return GL_LUMINANCE_ALPHA; + case GL_RGB: + case GL_R3_G3_B2: + case GL_RGB4: + case GL_RGB5: + case GL_RGB8: + case GL_RGB10: + case GL_RGB12: + case GL_RGB16: + return GL_RGB; + case GL_RGBA: + case GL_RGBA2: + case GL_RGBA4: + case GL_RGB5_A1: + case GL_RGBA8: + case GL_RGB10_A2: + case GL_RGBA12: + case GL_RGBA16: + return GL_RGBA; + default: + return -1; /* error */ + } +} + + +void +_mesa_GetMinmax(GLenum target, GLboolean reset, GLenum format, GLenum type, GLvoid *values) +{ + GET_CURRENT_CONTEXT(ctx); + ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx); + + if (!ctx->Extensions.EXT_histogram && !ctx->Extensions.ARB_imaging) { + _mesa_error(ctx, GL_INVALID_OPERATION, "glGetMinmax"); + return; + } + + if (target != GL_MINMAX) { + _mesa_error(ctx, GL_INVALID_ENUM, "glGetMinmax(target)"); + return; + } + + if (!_mesa_is_legal_format_and_type(format, type)) { + _mesa_error(ctx, GL_INVALID_OPERATION, "glGetMinmax(format or type)"); + return; + } + + if (type != GL_UNSIGNED_BYTE && + type != GL_BYTE && + type != GL_UNSIGNED_SHORT && + type != GL_SHORT && + type != GL_UNSIGNED_INT && + type != GL_INT && + type != GL_FLOAT && + type != GL_UNSIGNED_BYTE_3_3_2 && + type != GL_UNSIGNED_BYTE_2_3_3_REV && + type != GL_UNSIGNED_SHORT_5_6_5 && + type != GL_UNSIGNED_SHORT_5_6_5_REV && + type != GL_UNSIGNED_SHORT_4_4_4_4 && + type != GL_UNSIGNED_SHORT_4_4_4_4_REV && + type != GL_UNSIGNED_SHORT_5_5_5_1 && + type != GL_UNSIGNED_SHORT_1_5_5_5_REV && + type != GL_UNSIGNED_INT_8_8_8_8 && + type != GL_UNSIGNED_INT_8_8_8_8_REV && + type != GL_UNSIGNED_INT_10_10_10_2 && + type != GL_UNSIGNED_INT_2_10_10_10_REV) { + _mesa_error(ctx, GL_INVALID_ENUM, "glGetMinmax(type)"); + return; + } + + if (!values) + return; + + { + GLfloat minmax[2][4]; + minmax[0][RCOMP] = CLAMP(ctx->MinMax.Min[RCOMP], 0.0F, 1.0F); + minmax[0][GCOMP] = CLAMP(ctx->MinMax.Min[GCOMP], 0.0F, 1.0F); + minmax[0][BCOMP] = CLAMP(ctx->MinMax.Min[BCOMP], 0.0F, 1.0F); + minmax[0][ACOMP] = CLAMP(ctx->MinMax.Min[ACOMP], 0.0F, 1.0F); + minmax[1][RCOMP] = CLAMP(ctx->MinMax.Max[RCOMP], 0.0F, 1.0F); + minmax[1][GCOMP] = CLAMP(ctx->MinMax.Max[GCOMP], 0.0F, 1.0F); + minmax[1][BCOMP] = CLAMP(ctx->MinMax.Max[BCOMP], 0.0F, 1.0F); + minmax[1][ACOMP] = CLAMP(ctx->MinMax.Max[ACOMP], 0.0F, 1.0F); + _mesa_pack_float_rgba_span(ctx, 2, (CONST GLfloat (*)[4]) minmax, + format, type, values, &ctx->Pack, 0); + } + + if (reset) { + _mesa_ResetMinmax(GL_MINMAX); + } +} + + +void +_mesa_GetHistogram(GLenum target, GLboolean reset, GLenum format, GLenum type, GLvoid *values) +{ + GET_CURRENT_CONTEXT(ctx); + ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx); + + if (!ctx->Extensions.EXT_histogram && !ctx->Extensions.ARB_imaging) { + _mesa_error(ctx, GL_INVALID_OPERATION, "glGetHistogram"); + return; + } + + if (target != GL_HISTOGRAM) { + _mesa_error(ctx, GL_INVALID_ENUM, "glGetHistogram(target)"); + return; + } + + if (!_mesa_is_legal_format_and_type(format, type)) { + _mesa_error(ctx, GL_INVALID_OPERATION, "glGetHistogram(format or type)"); + return; + } + + if (type != GL_UNSIGNED_BYTE && + type != GL_BYTE && + type != GL_UNSIGNED_SHORT && + type != GL_SHORT && + type != GL_UNSIGNED_INT && + type != GL_INT && + type != GL_FLOAT && + type != GL_UNSIGNED_BYTE_3_3_2 && + type != GL_UNSIGNED_BYTE_2_3_3_REV && + type != GL_UNSIGNED_SHORT_5_6_5 && + type != GL_UNSIGNED_SHORT_5_6_5_REV && + type != GL_UNSIGNED_SHORT_4_4_4_4 && + type != GL_UNSIGNED_SHORT_4_4_4_4_REV && + type != GL_UNSIGNED_SHORT_5_5_5_1 && + type != GL_UNSIGNED_SHORT_1_5_5_5_REV && + type != GL_UNSIGNED_INT_8_8_8_8 && + type != GL_UNSIGNED_INT_8_8_8_8_REV && + type != GL_UNSIGNED_INT_10_10_10_2 && + type != GL_UNSIGNED_INT_2_10_10_10_REV) { + _mesa_error(ctx, GL_INVALID_ENUM, "glGetHistogram(type)"); + return; + } + + if (!values) + return; + + pack_histogram(ctx, ctx->Histogram.Width, + (CONST GLuint (*)[4]) ctx->Histogram.Count, + format, type, values, &ctx->Pack); + + if (reset) { + GLuint i; + for (i = 0; i < HISTOGRAM_TABLE_SIZE; i++) { + ctx->Histogram.Count[i][0] = 0; + ctx->Histogram.Count[i][1] = 0; + ctx->Histogram.Count[i][2] = 0; + ctx->Histogram.Count[i][3] = 0; + } + } +} + + +void +_mesa_GetHistogramParameterfv(GLenum target, GLenum pname, GLfloat *params) +{ + GET_CURRENT_CONTEXT(ctx); + ASSERT_OUTSIDE_BEGIN_END(ctx); + + if (!ctx->Extensions.EXT_histogram && !ctx->Extensions.ARB_imaging) { + _mesa_error(ctx, GL_INVALID_OPERATION, "glGetHistogramParameterfv"); + return; + } + + if (target != GL_HISTOGRAM && target != GL_PROXY_HISTOGRAM) { + _mesa_error(ctx, GL_INVALID_ENUM, "glGetHistogramParameterfv(target)"); + return; + } + + switch (pname) { + case GL_HISTOGRAM_WIDTH: + *params = (GLfloat) ctx->Histogram.Width; + break; + case GL_HISTOGRAM_FORMAT: + *params = (GLfloat) ctx->Histogram.Format; + break; + case GL_HISTOGRAM_RED_SIZE: + *params = (GLfloat) ctx->Histogram.RedSize; + break; + case GL_HISTOGRAM_GREEN_SIZE: + *params = (GLfloat) ctx->Histogram.GreenSize; + break; + case GL_HISTOGRAM_BLUE_SIZE: + *params = (GLfloat) ctx->Histogram.BlueSize; + break; + case GL_HISTOGRAM_ALPHA_SIZE: + *params = (GLfloat) ctx->Histogram.AlphaSize; + break; + case GL_HISTOGRAM_LUMINANCE_SIZE: + *params = (GLfloat) ctx->Histogram.LuminanceSize; + break; + case GL_HISTOGRAM_SINK: + *params = (GLfloat) ctx->Histogram.Sink; + break; + default: + _mesa_error(ctx, GL_INVALID_ENUM, "glGetHistogramParameterfv(pname)"); + } +} + + +void +_mesa_GetHistogramParameteriv(GLenum target, GLenum pname, GLint *params) +{ + GET_CURRENT_CONTEXT(ctx); + ASSERT_OUTSIDE_BEGIN_END(ctx); + + if (!ctx->Extensions.EXT_histogram && !ctx->Extensions.ARB_imaging) { + _mesa_error(ctx, GL_INVALID_OPERATION, "glGetHistogramParameteriv"); + return; + } + + if (target != GL_HISTOGRAM && target != GL_PROXY_HISTOGRAM) { + _mesa_error(ctx, GL_INVALID_ENUM, "glGetHistogramParameteriv(target)"); + return; + } + + switch (pname) { + case GL_HISTOGRAM_WIDTH: + *params = (GLint) ctx->Histogram.Width; + break; + case GL_HISTOGRAM_FORMAT: + *params = (GLint) ctx->Histogram.Format; + break; + case GL_HISTOGRAM_RED_SIZE: + *params = (GLint) ctx->Histogram.RedSize; + break; + case GL_HISTOGRAM_GREEN_SIZE: + *params = (GLint) ctx->Histogram.GreenSize; + break; + case GL_HISTOGRAM_BLUE_SIZE: + *params = (GLint) ctx->Histogram.BlueSize; + break; + case GL_HISTOGRAM_ALPHA_SIZE: + *params = (GLint) ctx->Histogram.AlphaSize; + break; + case GL_HISTOGRAM_LUMINANCE_SIZE: + *params = (GLint) ctx->Histogram.LuminanceSize; + break; + case GL_HISTOGRAM_SINK: + *params = (GLint) ctx->Histogram.Sink; + break; + default: + _mesa_error(ctx, GL_INVALID_ENUM, "glGetHistogramParameteriv(pname)"); + } +} + + +void +_mesa_GetMinmaxParameterfv(GLenum target, GLenum pname, GLfloat *params) +{ + GET_CURRENT_CONTEXT(ctx); + ASSERT_OUTSIDE_BEGIN_END(ctx); + + if (!ctx->Extensions.EXT_histogram && !ctx->Extensions.ARB_imaging) { + _mesa_error(ctx, GL_INVALID_OPERATION, "glGetMinmaxParameterfv"); + return; + } + if (target != GL_MINMAX) { + _mesa_error(ctx, GL_INVALID_ENUM, "glGetMinmaxParameterfv(target)"); + return; + } + if (pname == GL_MINMAX_FORMAT) { + *params = (GLfloat) ctx->MinMax.Format; + } + else if (pname == GL_MINMAX_SINK) { + *params = (GLfloat) ctx->MinMax.Sink; + } + else { + _mesa_error(ctx, GL_INVALID_ENUM, "glGetMinMaxParameterfv(pname)"); + } +} + + +void +_mesa_GetMinmaxParameteriv(GLenum target, GLenum pname, GLint *params) +{ + GET_CURRENT_CONTEXT(ctx); + ASSERT_OUTSIDE_BEGIN_END(ctx); + + if (!ctx->Extensions.EXT_histogram && !ctx->Extensions.ARB_imaging) { + _mesa_error(ctx, GL_INVALID_OPERATION, "glGetMinmaxParameteriv"); + return; + } + if (target != GL_MINMAX) { + _mesa_error(ctx, GL_INVALID_ENUM, "glGetMinmaxParameteriv(target)"); + return; + } + if (pname == GL_MINMAX_FORMAT) { + *params = (GLint) ctx->MinMax.Format; + } + else if (pname == GL_MINMAX_SINK) { + *params = (GLint) ctx->MinMax.Sink; + } + else { + _mesa_error(ctx, GL_INVALID_ENUM, "glGetMinMaxParameteriv(pname)"); + } +} + + +void +_mesa_Histogram(GLenum target, GLsizei width, GLenum internalFormat, GLboolean sink) +{ + GLuint i; + GLboolean error = GL_FALSE; + GET_CURRENT_CONTEXT(ctx); + ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx); /* sideeffects */ + + if (!ctx->Extensions.EXT_histogram && !ctx->Extensions.ARB_imaging) { + _mesa_error(ctx, GL_INVALID_OPERATION, "glHistogram"); + return; + } + + if (target != GL_HISTOGRAM && target != GL_PROXY_HISTOGRAM) { + _mesa_error(ctx, GL_INVALID_ENUM, "glHistogram(target)"); + return; + } + + if (width < 0 || width > HISTOGRAM_TABLE_SIZE) { + if (target == GL_PROXY_HISTOGRAM) { + error = GL_TRUE; + } + else { + if (width < 0) + _mesa_error(ctx, GL_INVALID_VALUE, "glHistogram(width)"); + else + _mesa_error(ctx, GL_TABLE_TOO_LARGE, "glHistogram(width)"); + return; + } + } + + if (width != 0 && _mesa_bitcount(width) != 1) { + if (target == GL_PROXY_HISTOGRAM) { + error = GL_TRUE; + } + else { + _mesa_error(ctx, GL_INVALID_VALUE, "glHistogram(width)"); + return; + } + } + + if (base_histogram_format(internalFormat) < 0) { + if (target == GL_PROXY_HISTOGRAM) { + error = GL_TRUE; + } + else { + _mesa_error(ctx, GL_INVALID_ENUM, "glHistogram(internalFormat)"); + return; + } + } + + /* reset histograms */ + for (i = 0; i < HISTOGRAM_TABLE_SIZE; i++) { + ctx->Histogram.Count[i][0] = 0; + ctx->Histogram.Count[i][1] = 0; + ctx->Histogram.Count[i][2] = 0; + ctx->Histogram.Count[i][3] = 0; + } + + if (error) { + ctx->Histogram.Width = 0; + ctx->Histogram.Format = 0; + ctx->Histogram.RedSize = 0; + ctx->Histogram.GreenSize = 0; + ctx->Histogram.BlueSize = 0; + ctx->Histogram.AlphaSize = 0; + ctx->Histogram.LuminanceSize = 0; + } + else { + ctx->Histogram.Width = width; + ctx->Histogram.Format = internalFormat; + ctx->Histogram.Sink = sink; + ctx->Histogram.RedSize = 8 * sizeof(GLuint); + ctx->Histogram.GreenSize = 8 * sizeof(GLuint); + ctx->Histogram.BlueSize = 8 * sizeof(GLuint); + ctx->Histogram.AlphaSize = 8 * sizeof(GLuint); + ctx->Histogram.LuminanceSize = 8 * sizeof(GLuint); + } + + ctx->NewState |= _NEW_PIXEL; +} + + +void +_mesa_Minmax(GLenum target, GLenum internalFormat, GLboolean sink) +{ + GET_CURRENT_CONTEXT(ctx); + ASSERT_OUTSIDE_BEGIN_END(ctx); + + if (!ctx->Extensions.EXT_histogram && !ctx->Extensions.ARB_imaging) { + _mesa_error(ctx, GL_INVALID_OPERATION, "glMinmax"); + return; + } + + if (target != GL_MINMAX) { + _mesa_error(ctx, GL_INVALID_ENUM, "glMinMax(target)"); + return; + } + + if (base_histogram_format(internalFormat) < 0) { + _mesa_error(ctx, GL_INVALID_ENUM, "glMinMax(internalFormat)"); + return; + } + + if (ctx->MinMax.Sink == sink) + return; + FLUSH_VERTICES(ctx, _NEW_PIXEL); + ctx->MinMax.Sink = sink; +} + + +void +_mesa_ResetHistogram(GLenum target) +{ + GLuint i; + GET_CURRENT_CONTEXT(ctx); + ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx); /* sideeffects */ + + if (!ctx->Extensions.EXT_histogram && !ctx->Extensions.ARB_imaging) { + _mesa_error(ctx, GL_INVALID_OPERATION, "glResetHistogram"); + return; + } + + if (target != GL_HISTOGRAM) { + _mesa_error(ctx, GL_INVALID_ENUM, "glResetHistogram(target)"); + return; + } + + for (i = 0; i < HISTOGRAM_TABLE_SIZE; i++) { + ctx->Histogram.Count[i][0] = 0; + ctx->Histogram.Count[i][1] = 0; + ctx->Histogram.Count[i][2] = 0; + ctx->Histogram.Count[i][3] = 0; + } + + ctx->NewState |= _NEW_PIXEL; +} + + +void +_mesa_ResetMinmax(GLenum target) +{ + GET_CURRENT_CONTEXT(ctx); + ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx); + + if (!ctx->Extensions.EXT_histogram && !ctx->Extensions.ARB_imaging) { + _mesa_error(ctx, GL_INVALID_OPERATION, "glResetMinmax"); + return; + } + + if (target != GL_MINMAX) { + _mesa_error(ctx, GL_INVALID_ENUM, "glResetMinMax(target)"); + return; + } + + ctx->MinMax.Min[RCOMP] = 1000; ctx->MinMax.Max[RCOMP] = -1000; + ctx->MinMax.Min[GCOMP] = 1000; ctx->MinMax.Max[GCOMP] = -1000; + ctx->MinMax.Min[BCOMP] = 1000; ctx->MinMax.Max[BCOMP] = -1000; + ctx->MinMax.Min[ACOMP] = 1000; ctx->MinMax.Max[ACOMP] = -1000; + ctx->NewState |= _NEW_PIXEL; +} Index: dll/opengl/opengl32/mesa/histogram.h =================================================================== --- dll/opengl/opengl32/mesa/histogram.h (revision 0) +++ dll/opengl/opengl32/mesa/histogram.h (working copy) @@ -0,0 +1,68 @@ +/* $Id: histogram.h,v 1.3 2001/03/12 00:48:38 gareth Exp $ */ + +/* + * Mesa 3-D graphics library + * Version: 3.5 + * + * Copyright (C) 1999-2001 Brian Paul 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 + * BRIAN PAUL 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. + */ + + +#ifndef HISTOGRAM_H +#define HISTOGRAM_H + + +#ifdef PC_HEADER +#include "all.h" +#else +#include "glheader.h" +#include "mtypes.h" +#endif + + + +extern void _mesa_GetMinmax(GLenum target, GLboolean reset, GLenum format, GLenum types, GLvoid *values); + +extern void _mesa_GetHistogram(GLenum target, GLboolean reset, GLenum format, GLenum type, GLvoid *values); + +extern void _mesa_GetHistogramParameterfv(GLenum target, GLenum pname, GLfloat *params); + +extern void _mesa_GetHistogramParameteriv(GLenum target, GLenum pname, GLint *params); + +extern void _mesa_GetMinmaxParameterfv(GLenum target, GLenum pname, GLfloat *params); + +extern void _mesa_GetMinmaxParameteriv(GLenum target, GLenum pname, GLint *params); + +extern void _mesa_Histogram(GLenum target, GLsizei width, GLenum internalformat, GLboolean sink); + +extern void _mesa_Minmax(GLenum target, GLenum internalformat, GLboolean sink); + +extern void _mesa_ResetHistogram(GLenum target); + +extern void _mesa_ResetMinmax(GLenum target); + +extern void +_mesa_update_minmax(GLcontext *ctx, GLuint n, const GLfloat rgba[][4]); + +extern void +_mesa_update_histogram(GLcontext *ctx, GLuint n, const GLfloat rgba[][4]); + + +#endif Index: dll/opengl/opengl32/mesa/image.c =================================================================== --- dll/opengl/opengl32/mesa/image.c (revision 0) +++ dll/opengl/opengl32/mesa/image.c (working copy) @@ -0,0 +1,3782 @@ +/* $Id: image.c,v 1.62 2001/06/13 14:55:25 brianp Exp $ */ + +/* + * Mesa 3-D graphics library + * Version: 3.5 + * + * Copyright (C) 1999-2001 Brian Paul 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 + * BRIAN PAUL 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. + */ + + +#ifdef PC_HEADER +#include "all.h" +#else +#include "glheader.h" +#include "colormac.h" +#include "context.h" +#include "image.h" +#include "histogram.h" +#include "macros.h" +#include "mem.h" +#include "mmath.h" +#include "pixel.h" +#include "mtypes.h" +#endif + + + +/* + * These are the image packing parameters for Mesa's internal images. + * That is, _mesa_unpack_image() returns image data in this format. + * When we execute image commands (glDrawPixels, glTexImage, etc) + * from within display lists we have to be sure to set the current + * unpacking params to these values! + */ +const struct gl_pixelstore_attrib _mesa_native_packing = { + 1, /* Alignment */ + 0, /* RowLength */ + 0, /* SkipPixels */ + 0, /* SkipRows */ + 0, /* ImageHeight */ + 0, /* SkipImages */ + GL_FALSE, /* SwapBytes */ + GL_FALSE /* LsbFirst */ +}; + + + +/* + * Flip the 8 bits in each byte of the given array. + * + * XXX try this trick to flip bytes someday: + * v = ((v & 0x55555555) << 1) | ((v >> 1) & 0x55555555); + * v = ((v & 0x33333333) << 2) | ((v >> 2) & 0x33333333); + * v = ((v & 0x0f0f0f0f) << 4) | ((v >> 4) & 0x0f0f0f0f); + */ +static void +flip_bytes( GLubyte *p, GLuint n ) +{ + register GLuint i, a, b; + + for (i=0;i> 1) | + ((b & 0x20) >> 3) | + ((b & 0x40) >> 5) | + ((b & 0x80) >> 7); + p[i] = (GLubyte) a; + } +} + + +/* + * Flip the order of the 2 bytes in each word in the given array. + */ +void +_mesa_swap2( GLushort *p, GLuint n ) +{ + register GLuint i; + + for (i=0;i> 8) | ((p[i] << 8) & 0xff00); + } +} + + + +/* + * Flip the order of the 4 bytes in each word in the given array. + */ +void +_mesa_swap4( GLuint *p, GLuint n ) +{ + register GLuint i, a, b; + + for (i=0;i> 24) + | ((b >> 8) & 0xff00) + | ((b << 8) & 0xff0000) + | ((b << 24) & 0xff000000); + p[i] = a; + } +} + + + + +/* + * Return the size, in bytes, of the given GL datatype. + * Return 0 if GL_BITMAP. + * Return -1 if invalid type enum. + */ +GLint _mesa_sizeof_type( GLenum type ) +{ + switch (type) { + case GL_BITMAP: + return 0; + case GL_UNSIGNED_BYTE: + return sizeof(GLubyte); + case GL_BYTE: + return sizeof(GLbyte); + case GL_UNSIGNED_SHORT: + return sizeof(GLushort); + case GL_SHORT: + return sizeof(GLshort); + case GL_UNSIGNED_INT: + return sizeof(GLuint); + case GL_INT: + return sizeof(GLint); + case GL_FLOAT: + return sizeof(GLfloat); + default: + return -1; + } +} + + +/* + * Same as _mesa_sizeof_packed_type() but we also accept the + * packed pixel format datatypes. + */ +GLint _mesa_sizeof_packed_type( GLenum type ) +{ + switch (type) { + case GL_BITMAP: + return 0; + case GL_UNSIGNED_BYTE: + return sizeof(GLubyte); + case GL_BYTE: + return sizeof(GLbyte); + case GL_UNSIGNED_SHORT: + return sizeof(GLushort); + case GL_SHORT: + return sizeof(GLshort); + case GL_UNSIGNED_INT: + return sizeof(GLuint); + case GL_INT: + return sizeof(GLint); + case GL_FLOAT: + return sizeof(GLfloat); + case GL_UNSIGNED_BYTE_3_3_2: + return sizeof(GLubyte); + case GL_UNSIGNED_BYTE_2_3_3_REV: + return sizeof(GLubyte); + case GL_UNSIGNED_SHORT_5_6_5: + return sizeof(GLshort); + case GL_UNSIGNED_SHORT_5_6_5_REV: + return sizeof(GLshort); + case GL_UNSIGNED_SHORT_4_4_4_4: + return sizeof(GLshort); + case GL_UNSIGNED_SHORT_4_4_4_4_REV: + return sizeof(GLshort); + case GL_UNSIGNED_SHORT_5_5_5_1: + return sizeof(GLshort); + case GL_UNSIGNED_SHORT_1_5_5_5_REV: + return sizeof(GLshort); + case GL_UNSIGNED_INT_8_8_8_8: + return sizeof(GLuint); + case GL_UNSIGNED_INT_8_8_8_8_REV: + return sizeof(GLuint); + case GL_UNSIGNED_INT_10_10_10_2: + return sizeof(GLuint); + case GL_UNSIGNED_INT_2_10_10_10_REV: + return sizeof(GLuint); + default: + return -1; + } +} + + + +/* + * Return the number of components in a GL enum pixel type. + * Return -1 if bad format. + */ +GLint _mesa_components_in_format( GLenum format ) +{ + switch (format) { + case GL_COLOR_INDEX: + case GL_COLOR_INDEX1_EXT: + case GL_COLOR_INDEX2_EXT: + case GL_COLOR_INDEX4_EXT: + case GL_COLOR_INDEX8_EXT: + case GL_COLOR_INDEX12_EXT: + case GL_COLOR_INDEX16_EXT: + case GL_STENCIL_INDEX: + case GL_DEPTH_COMPONENT: + case GL_RED: + case GL_GREEN: + case GL_BLUE: + case GL_ALPHA: + case GL_LUMINANCE: + case GL_INTENSITY: + return 1; + case GL_LUMINANCE_ALPHA: + return 2; + case GL_RGB: + return 3; + case GL_RGBA: + return 4; + case GL_BGR: + return 3; + case GL_BGRA: + return 4; + case GL_ABGR_EXT: + return 4; + default: + return -1; + } +} + + +/* + * Return bytes per pixel for given format and type + * Return -1 if bad format or type. + */ +GLint _mesa_bytes_per_pixel( GLenum format, GLenum type ) +{ + GLint comps = _mesa_components_in_format( format ); + if (comps < 0) + return -1; + + switch (type) { + case GL_BITMAP: + return 0; /* special case */ + case GL_BYTE: + case GL_UNSIGNED_BYTE: + return comps * sizeof(GLubyte); + case GL_SHORT: + case GL_UNSIGNED_SHORT: + return comps * sizeof(GLshort); + case GL_INT: + case GL_UNSIGNED_INT: + return comps * sizeof(GLint); + case GL_FLOAT: + return comps * sizeof(GLfloat); + case GL_UNSIGNED_BYTE_3_3_2: + case GL_UNSIGNED_BYTE_2_3_3_REV: + if (format == GL_RGB || format == GL_BGR) + return sizeof(GLubyte); + else + return -1; /* error */ + case GL_UNSIGNED_SHORT_5_6_5: + case GL_UNSIGNED_SHORT_5_6_5_REV: + if (format == GL_RGB || format == GL_BGR) + return sizeof(GLshort); + else + return -1; /* error */ + case GL_UNSIGNED_SHORT_4_4_4_4: + case GL_UNSIGNED_SHORT_4_4_4_4_REV: + case GL_UNSIGNED_SHORT_5_5_5_1: + case GL_UNSIGNED_SHORT_1_5_5_5_REV: + if (format == GL_RGBA || format == GL_BGRA || format == GL_ABGR_EXT) + return sizeof(GLushort); + else + return -1; + case GL_UNSIGNED_INT_8_8_8_8: + case GL_UNSIGNED_INT_8_8_8_8_REV: + case GL_UNSIGNED_INT_10_10_10_2: + case GL_UNSIGNED_INT_2_10_10_10_REV: + if (format == GL_RGBA || format == GL_BGRA || format == GL_ABGR_EXT) + return sizeof(GLuint); + else + return -1; + default: + return -1; + } +} + + +/* + * Test if the given pixel format and type are legal. + * Return GL_TRUE for legal, GL_FALSE for illegal. + */ +GLboolean +_mesa_is_legal_format_and_type( GLenum format, GLenum type ) +{ + switch (format) { + case GL_COLOR_INDEX: + case GL_STENCIL_INDEX: + switch (type) { + case GL_BITMAP: + case GL_BYTE: + case GL_UNSIGNED_BYTE: + case GL_SHORT: + case GL_UNSIGNED_SHORT: + case GL_INT: + case GL_UNSIGNED_INT: + case GL_FLOAT: + return GL_TRUE; + default: + return GL_FALSE; + } + case GL_RED: + case GL_GREEN: + case GL_BLUE: + case GL_ALPHA: + case GL_INTENSITY: + case GL_LUMINANCE: + case GL_LUMINANCE_ALPHA: + case GL_DEPTH_COMPONENT: + switch (type) { + case GL_BYTE: + case GL_UNSIGNED_BYTE: + case GL_SHORT: + case GL_UNSIGNED_SHORT: + case GL_INT: + case GL_UNSIGNED_INT: + case GL_FLOAT: + return GL_TRUE; + default: + return GL_FALSE; + } + case GL_RGB: + case GL_BGR: + switch (type) { + case GL_BYTE: + case GL_UNSIGNED_BYTE: + case GL_SHORT: + case GL_UNSIGNED_SHORT: + case GL_INT: + case GL_UNSIGNED_INT: + case GL_FLOAT: + case GL_UNSIGNED_BYTE_3_3_2: + case GL_UNSIGNED_BYTE_2_3_3_REV: + case GL_UNSIGNED_SHORT_5_6_5: + case GL_UNSIGNED_SHORT_5_6_5_REV: + return GL_TRUE; + default: + return GL_FALSE; + } + case GL_RGBA: + case GL_BGRA: + case GL_ABGR_EXT: + switch (type) { + case GL_BYTE: + case GL_UNSIGNED_BYTE: + case GL_SHORT: + case GL_UNSIGNED_SHORT: + case GL_INT: + case GL_UNSIGNED_INT: + case GL_FLOAT: + case GL_UNSIGNED_SHORT_4_4_4_4: + case GL_UNSIGNED_SHORT_4_4_4_4_REV: + case GL_UNSIGNED_SHORT_5_5_5_1: + case GL_UNSIGNED_SHORT_1_5_5_5_REV: + case GL_UNSIGNED_INT_8_8_8_8: + case GL_UNSIGNED_INT_8_8_8_8_REV: + case GL_UNSIGNED_INT_10_10_10_2: + case GL_UNSIGNED_INT_2_10_10_10_REV: + return GL_TRUE; + default: + return GL_FALSE; + } + default: + ; /* fall-through */ + } + return GL_FALSE; +} + + + +/* + * Return the address of a pixel in an image (actually a volume). + * Pixel unpacking/packing parameters are observed according to 'packing'. + * Input: image - start of image data + * width, height - size of image + * format - image format + * type - pixel component type + * packing - the pixelstore attributes + * img - which image in the volume (0 for 1D or 2D images) + * row, column - location of pixel in the image + * Return: address of pixel at (image,row,column) in image or NULL if error. + */ +GLvoid * +_mesa_image_address( const struct gl_pixelstore_attrib *packing, + const GLvoid *image, GLsizei width, + GLsizei height, GLenum format, GLenum type, + GLint img, GLint row, GLint column ) +{ + GLint alignment; /* 1, 2 or 4 */ + GLint pixels_per_row; + GLint rows_per_image; + GLint skiprows; + GLint skippixels; + GLint skipimages; /* for 3-D volume images */ + GLubyte *pixel_addr; + + alignment = packing->Alignment; + if (packing->RowLength > 0) { + pixels_per_row = packing->RowLength; + } + else { + pixels_per_row = width; + } + if (packing->ImageHeight > 0) { + rows_per_image = packing->ImageHeight; + } + else { + rows_per_image = height; + } + skiprows = packing->SkipRows; + skippixels = packing->SkipPixels; + skipimages = packing->SkipImages; + + if (type==GL_BITMAP) { + /* BITMAP data */ + GLint comp_per_pixel; /* components per pixel */ + GLint bytes_per_comp; /* bytes per component */ + GLint bytes_per_row; + GLint bytes_per_image; + + /* Compute bytes per component */ + bytes_per_comp = _mesa_sizeof_packed_type( type ); + if (bytes_per_comp<0) { + return NULL; + } + + /* Compute number of components per pixel */ + comp_per_pixel = _mesa_components_in_format( format ); + if (comp_per_pixel<0 && type != GL_BITMAP) { + return NULL; + } + + bytes_per_row = alignment + * CEILING( comp_per_pixel*pixels_per_row, 8*alignment ); + + bytes_per_image = bytes_per_row * rows_per_image; + + pixel_addr = (GLubyte *) image + + (skipimages + img) * bytes_per_image + + (skiprows + row) * bytes_per_row + + (skippixels + column) / 8; + } + else { + /* Non-BITMAP data */ + GLint bytes_per_pixel, bytes_per_row, remainder, bytes_per_image; + + bytes_per_pixel = _mesa_bytes_per_pixel( format, type ); + + /* The pixel type and format should have been error checked earlier */ + assert(bytes_per_pixel > 0); + + bytes_per_row = pixels_per_row * bytes_per_pixel; + remainder = bytes_per_row % alignment; + if (remainder > 0) + bytes_per_row += (alignment - remainder); + + ASSERT(bytes_per_row % alignment == 0); + + bytes_per_image = bytes_per_row * rows_per_image; + + /* compute final pixel address */ + pixel_addr = (GLubyte *) image + + (skipimages + img) * bytes_per_image + + (skiprows + row) * bytes_per_row + + (skippixels + column) * bytes_per_pixel; + } + + return (GLvoid *) pixel_addr; +} + + + +/* + * Compute the stride between image rows (in bytes) for the given + * pixel packing parameters and image width, format and type. + */ +GLint +_mesa_image_row_stride( const struct gl_pixelstore_attrib *packing, + GLint width, GLenum format, GLenum type ) +{ + ASSERT(packing); + if (type == GL_BITMAP) { + /* BITMAP data */ + if (packing->RowLength == 0) { + GLint bytes = (width + 7) / 8; + return bytes; + } + else { + GLint bytes = (packing->RowLength + 7) / 8; + return bytes; + } + } + else { + /* Non-BITMAP data */ + const GLint bytesPerPixel = _mesa_bytes_per_pixel(format, type); + GLint bytesPerRow, remainder; + if (bytesPerPixel <= 0) + return -1; /* error */ + if (packing->RowLength == 0) { + bytesPerRow = bytesPerPixel * width; + } + else { + bytesPerRow = bytesPerPixel * packing->RowLength; + } + remainder = bytesPerRow % packing->Alignment; + if (remainder > 0) + bytesPerRow += (packing->Alignment - remainder); + return bytesPerRow; + } +} + + + +/* + * Unpack a 32x32 pixel polygon stipple from user memory using the + * current pixel unpack settings. + */ +void +_mesa_unpack_polygon_stipple( const GLubyte *pattern, GLuint dest[32], + const struct gl_pixelstore_attrib *unpacking ) +{ + GLubyte *ptrn = (GLubyte *) _mesa_unpack_bitmap( 32, 32, pattern, unpacking ); + if (ptrn) { + /* Convert pattern from GLubytes to GLuints and handle big/little + * endian differences + */ + GLubyte *p = ptrn; + GLint i; + for (i = 0; i < 32; i++) { + dest[i] = (p[0] << 24) + | (p[1] << 16) + | (p[2] << 8) + | (p[3] ); + p += 4; + } + FREE(ptrn); + } +} + + + +/* + * Pack polygon stipple into user memory given current pixel packing + * settings. + */ +void +_mesa_pack_polygon_stipple( const GLuint pattern[32], GLubyte *dest, + const struct gl_pixelstore_attrib *packing ) +{ + /* Convert pattern from GLuints to GLubytes to handle big/little + * endian differences. + */ + GLubyte ptrn[32*4]; + GLint i; + for (i = 0; i < 32; i++) { + ptrn[i * 4 + 0] = (GLubyte) ((pattern[i] >> 24) & 0xff); + ptrn[i * 4 + 1] = (GLubyte) ((pattern[i] >> 16) & 0xff); + ptrn[i * 4 + 2] = (GLubyte) ((pattern[i] >> 8 ) & 0xff); + ptrn[i * 4 + 3] = (GLubyte) ((pattern[i] ) & 0xff); + } + + _mesa_pack_bitmap(32, 32, ptrn, dest, packing); +} + + +/* + * Unpack bitmap data. Resulting data will be in most-significant-bit-first + * order with row alignment = 1 byte. + */ +GLvoid * +_mesa_unpack_bitmap( GLint width, GLint height, const GLubyte *pixels, + const struct gl_pixelstore_attrib *packing ) +{ + GLint bytes, row, width_in_bytes; + GLubyte *buffer, *dst; + + if (!pixels) + return NULL; + + /* Alloc dest storage */ + bytes = ((width + 7) / 8 * height); + buffer = (GLubyte *) MALLOC( bytes ); + if (!buffer) + return NULL; + + + width_in_bytes = CEILING( width, 8 ); + dst = buffer; + for (row = 0; row < height; row++) { + const GLubyte *src = (const GLubyte *) + _mesa_image_address(packing, pixels, width, height, + GL_COLOR_INDEX, GL_BITMAP, 0, row, 0); + if (!src) { + FREE(buffer); + return NULL; + } + + if (packing->SkipPixels == 0) { + MEMCPY( dst, src, width_in_bytes ); + if (packing->LsbFirst) { + flip_bytes( dst, width_in_bytes ); + } + } + else { + /* handling SkipPixels is a bit tricky (no pun intended!) */ + GLint i; + if (packing->LsbFirst) { + GLubyte srcMask = 1 << (packing->SkipPixels & 0x7); + GLubyte dstMask = 128; + const GLubyte *s = src; + GLubyte *d = dst; + *d = 0; + for (i = 0; i < width; i++) { + if (*s & srcMask) { + *d |= dstMask; + } + if (srcMask == 128) { + srcMask = 1; + s++; + } + else { + srcMask = srcMask << 1; + } + if (dstMask == 1) { + dstMask = 128; + d++; + *d = 0; + } + else { + dstMask = dstMask >> 1; + } + } + } + else { + GLubyte srcMask = 128 >> (packing->SkipPixels & 0x7); + GLubyte dstMask = 128; + const GLubyte *s = src; + GLubyte *d = dst; + *d = 0; + for (i = 0; i < width; i++) { + if (*s & srcMask) { + *d |= dstMask; + } + if (srcMask == 1) { + srcMask = 128; + s++; + } + else { + srcMask = srcMask >> 1; + } + if (dstMask == 1) { + dstMask = 128; + d++; + *d = 0; + } + else { + dstMask = dstMask >> 1; + } + } + } + } + dst += width_in_bytes; + } + + return buffer; +} + + +/* + * Pack bitmap data. + */ +void +_mesa_pack_bitmap( GLint width, GLint height, const GLubyte *source, + GLubyte *dest, const struct gl_pixelstore_attrib *packing ) +{ + GLint row, width_in_bytes; + const GLubyte *src; + + if (!source) + return; + + width_in_bytes = CEILING( width, 8 ); + src = source; + for (row = 0; row < height; row++) { + GLubyte *dst = (GLubyte *) _mesa_image_address( packing, dest, + width, height, GL_COLOR_INDEX, GL_BITMAP, 0, row, 0 ); + if (!dst) + return; + + if (packing->SkipPixels == 0) { + MEMCPY( dst, src, width_in_bytes ); + if (packing->LsbFirst) { + flip_bytes( dst, width_in_bytes ); + } + } + else { + /* handling SkipPixels is a bit tricky (no pun intended!) */ + GLint i; + if (packing->LsbFirst) { + GLubyte srcMask = 1 << (packing->SkipPixels & 0x7); + GLubyte dstMask = 128; + const GLubyte *s = src; + GLubyte *d = dst; + *d = 0; + for (i = 0; i < width; i++) { + if (*s & srcMask) { + *d |= dstMask; + } + if (srcMask == 128) { + srcMask = 1; + s++; + } + else { + srcMask = srcMask << 1; + } + if (dstMask == 1) { + dstMask = 128; + d++; + *d = 0; + } + else { + dstMask = dstMask >> 1; + } + } + } + else { + GLubyte srcMask = 128 >> (packing->SkipPixels & 0x7); + GLubyte dstMask = 128; + const GLubyte *s = src; + GLubyte *d = dst; + *d = 0; + for (i = 0; i < width; i++) { + if (*s & srcMask) { + *d |= dstMask; + } + if (srcMask == 1) { + srcMask = 128; + s++; + } + else { + srcMask = srcMask >> 1; + } + if (dstMask == 1) { + dstMask = 128; + d++; + *d = 0; + } + else { + dstMask = dstMask >> 1; + } + } + } + } + src += width_in_bytes; + } +} + + + +void +_mesa_pack_float_rgba_span( GLcontext *ctx, + GLuint n, CONST GLfloat rgbaIn[][4], + GLenum dstFormat, GLenum dstType, + GLvoid *dstAddr, + const struct gl_pixelstore_attrib *dstPacking, + GLuint transferOps ) +{ + const GLint comps = _mesa_components_in_format(dstFormat); + GLfloat luminance[MAX_WIDTH]; + GLfloat (*rgba)[4]; + GLuint i; + + if (transferOps) { + /* make copy of incoming data */ + DEFMARRAY(GLfloat, rgbaCopy, MAX_WIDTH, 4); /* mac 32k limitation */ + CHECKARRAY(rgbaCopy, return); /* mac 32k limitation */ + + for (i = 0; i < n; i++) { + rgbaCopy[i][0] = rgbaIn[i][0]; + rgbaCopy[i][1] = rgbaIn[i][1]; + rgbaCopy[i][2] = rgbaIn[i][2]; + rgbaCopy[i][3] = rgbaIn[i][3]; + } + + rgba = (GLfloat (*)[4]) rgbaCopy; + + /* scale & bias */ + if (transferOps & IMAGE_SCALE_BIAS_BIT) { + _mesa_scale_and_bias_rgba(ctx, n, rgba, + ctx->Pixel.RedScale, ctx->Pixel.GreenScale, + ctx->Pixel.BlueScale, ctx->Pixel.AlphaScale, + ctx->Pixel.RedBias, ctx->Pixel.GreenBias, + ctx->Pixel.BlueBias, ctx->Pixel.AlphaBias); + } + /* color map lookup */ + if (transferOps & IMAGE_MAP_COLOR_BIT) { + _mesa_map_rgba( ctx, n, rgba ); + } + /* GL_COLOR_TABLE lookup */ + if (transferOps & IMAGE_COLOR_TABLE_BIT) { + _mesa_lookup_rgba(&ctx->ColorTable, n, rgba); + } + /* convolution */ + if (transferOps & IMAGE_CONVOLUTION_BIT) { + /* this has to be done in the calling code */ + } + /* GL_POST_CONVOLUTION_RED/GREEN/BLUE/ALPHA_SCALE/BIAS */ + if (transferOps & IMAGE_POST_CONVOLUTION_SCALE_BIAS) { + _mesa_scale_and_bias_rgba(ctx, n, rgba, + ctx->Pixel.PostConvolutionScale[RCOMP], + ctx->Pixel.PostConvolutionScale[GCOMP], + ctx->Pixel.PostConvolutionScale[BCOMP], + ctx->Pixel.PostConvolutionScale[ACOMP], + ctx->Pixel.PostConvolutionBias[RCOMP], + ctx->Pixel.PostConvolutionBias[GCOMP], + ctx->Pixel.PostConvolutionBias[BCOMP], + ctx->Pixel.PostConvolutionBias[ACOMP]); + } + /* GL_POST_CONVOLUTION_COLOR_TABLE lookup */ + if (transferOps & IMAGE_POST_CONVOLUTION_COLOR_TABLE_BIT) { + _mesa_lookup_rgba(&ctx->PostConvolutionColorTable, n, rgba); + } + /* color matrix transform */ + if (transferOps & IMAGE_COLOR_MATRIX_BIT) { + _mesa_transform_rgba(ctx, n, rgba); + } + /* GL_POST_COLOR_MATRIX_COLOR_TABLE lookup */ + if (transferOps & IMAGE_POST_COLOR_MATRIX_COLOR_TABLE_BIT) { + _mesa_lookup_rgba(&ctx->PostColorMatrixColorTable, n, rgba); + } + /* update histogram count */ + if (transferOps & IMAGE_HISTOGRAM_BIT) { + _mesa_update_histogram(ctx, n, (CONST GLfloat (*)[4]) rgba); + } + /* min/max here */ + if (transferOps & IMAGE_MIN_MAX_BIT) { + _mesa_update_minmax(ctx, n, (CONST GLfloat (*)[4]) rgba); + if (ctx->MinMax.Sink) { + UNDEFARRAY(rgbaCopy); /* mac 32k limitation */ + return; + } + } + UNDEFARRAY(rgbaCopy); /* mac 32k limitation */ + } + else { + /* use incoming data, not a copy */ + rgba = (GLfloat (*)[4]) rgbaIn; + } + + /* XXX clamp rgba to [0,1]? */ + + + if (dstFormat == GL_LUMINANCE || dstFormat == GL_LUMINANCE_ALPHA) { + for (i = 0; i < n; i++) { + GLfloat sum = rgba[i][RCOMP] + rgba[i][GCOMP] + rgba[i][BCOMP]; + luminance[i] = CLAMP(sum, 0.0F, 1.0F); + } + } + + /* + * Pack/store the pixels. Ugh! Lots of cases!!! + */ + switch (dstType) { + case GL_UNSIGNED_BYTE: + { + GLubyte *dst = (GLubyte *) dstAddr; + switch (dstFormat) { + case GL_RED: + for (i=0;iSwapBytes) { + _mesa_swap2( (GLushort *) dst, n * comps); + } + } + break; + case GL_SHORT: + { + GLshort *dst = (GLshort *) dstAddr; + switch (dstFormat) { + case GL_RED: + for (i=0;iSwapBytes) { + _mesa_swap2( (GLushort *) dst, n * comps ); + } + } + break; + case GL_UNSIGNED_INT: + { + GLuint *dst = (GLuint *) dstAddr; + switch (dstFormat) { + case GL_RED: + for (i=0;iSwapBytes) { + _mesa_swap4( (GLuint *) dst, n * comps ); + } + } + break; + case GL_INT: + { + GLint *dst = (GLint *) dstAddr; + switch (dstFormat) { + case GL_RED: + for (i=0;iSwapBytes) { + _mesa_swap4( (GLuint *) dst, n * comps ); + } + } + break; + case GL_FLOAT: + { + GLfloat *dst = (GLfloat *) dstAddr; + switch (dstFormat) { + case GL_RED: + for (i=0;iSwapBytes) { + _mesa_swap4( (GLuint *) dst, n * comps ); + } + } + break; + case GL_UNSIGNED_BYTE_3_3_2: + if (dstFormat == GL_RGB) { + GLubyte *dst = (GLubyte *) dstAddr; + for (i=0;iNewState & _NEW_PIXEL) == 0 || transferOps == 0); + + /* Test for optimized case first */ + if (transferOps == 0 && dstFormat == GL_RGBA && dstType == CHAN_TYPE) { + /* common simple case */ + MEMCPY(dstAddr, srcRgba, n * 4 * sizeof(GLchan)); + } + else if (transferOps == 0 && dstFormat == GL_RGB && dstType == CHAN_TYPE) { + /* common simple case */ + GLuint i; + GLchan *dest = (GLchan *) dstAddr; + for (i = 0; i < n; i++) { + dest[0] = srcRgba[i][RCOMP]; + dest[1] = srcRgba[i][GCOMP]; + dest[2] = srcRgba[i][BCOMP]; + dest += 3; + } + } + else { + /* general solution */ + GLuint i; + DEFMARRAY(GLfloat, rgba, MAX_WIDTH, 4); /* mac 32k limitation */ + CHECKARRAY(rgba, return); /* mac 32k limitation */ + + assert(n <= MAX_WIDTH); + /* convert color components to floating point */ + for (i=0;iLsbFirst) { + GLubyte mask = 1 << (unpack->SkipPixels & 0x7); + GLuint i; + for (i = 0; i < n; i++) { + indexes[i] = (*ubsrc & mask) ? 1 : 0; + if (mask == 128) { + mask = 1; + ubsrc++; + } + else { + mask = mask << 1; + } + } + } + else { + GLubyte mask = 128 >> (unpack->SkipPixels & 0x7); + GLuint i; + for (i = 0; i < n; i++) { + indexes[i] = (*ubsrc & mask) ? 1 : 0; + if (mask == 1) { + mask = 128; + ubsrc++; + } + else { + mask = mask >> 1; + } + } + } + } + break; + case GL_UNSIGNED_BYTE: + { + GLuint i; + const GLubyte *s = (const GLubyte *) src; + for (i = 0; i < n; i++) + indexes[i] = s[i]; + } + break; + case GL_BYTE: + { + GLuint i; + const GLbyte *s = (const GLbyte *) src; + for (i = 0; i < n; i++) + indexes[i] = s[i]; + } + break; + case GL_UNSIGNED_SHORT: + { + GLuint i; + const GLushort *s = (const GLushort *) src; + if (unpack->SwapBytes) { + for (i = 0; i < n; i++) { + GLushort value = s[i]; + SWAP2BYTE(value); + indexes[i] = value; + } + } + else { + for (i = 0; i < n; i++) + indexes[i] = s[i]; + } + } + break; + case GL_SHORT: + { + GLuint i; + const GLshort *s = (const GLshort *) src; + if (unpack->SwapBytes) { + for (i = 0; i < n; i++) { + GLshort value = s[i]; + SWAP2BYTE(value); + indexes[i] = value; + } + } + else { + for (i = 0; i < n; i++) + indexes[i] = s[i]; + } + } + break; + case GL_UNSIGNED_INT: + { + GLuint i; + const GLuint *s = (const GLuint *) src; + if (unpack->SwapBytes) { + for (i = 0; i < n; i++) { + GLuint value = s[i]; + SWAP4BYTE(value); + indexes[i] = value; + } + } + else { + for (i = 0; i < n; i++) + indexes[i] = s[i]; + } + } + break; + case GL_INT: + { + GLuint i; + const GLint *s = (const GLint *) src; + if (unpack->SwapBytes) { + for (i = 0; i < n; i++) { + GLint value = s[i]; + SWAP4BYTE(value); + indexes[i] = value; + } + } + else { + for (i = 0; i < n; i++) + indexes[i] = s[i]; + } + } + break; + case GL_FLOAT: + { + GLuint i; + const GLfloat *s = (const GLfloat *) src; + if (unpack->SwapBytes) { + for (i = 0; i < n; i++) { + GLfloat value = s[i]; + SWAP4BYTE(value); + indexes[i] = (GLuint) value; + } + } + else { + for (i = 0; i < n; i++) + indexes[i] = (GLuint) s[i]; + } + } + break; + default: + _mesa_problem(NULL, "bad srcType in extract_uint_indexes"); + return; + } +} + + + +/* + * This function extracts floating point RGBA values from arbitrary + * image data. srcFormat and srcType are the format and type parameters + * passed to glDrawPixels, glTexImage[123]D, glTexSubImage[123]D, etc. + * + * Refering to section 3.6.4 of the OpenGL 1.2 spec, this function + * implements the "Conversion to floating point", "Conversion to RGB", + * and "Final Expansion to RGBA" operations. + * + * Args: n - number of pixels + * rgba - output colors + * srcFormat - format of incoming data + * srcType - datatype of incoming data + * src - source data pointer + * swapBytes - perform byteswapping of incoming data? + */ +static void +extract_float_rgba(GLuint n, GLfloat rgba[][4], + GLenum srcFormat, GLenum srcType, const GLvoid *src, + GLboolean swapBytes) +{ + GLint redIndex, greenIndex, blueIndex, alphaIndex; + GLint stride; + GLint rComp, bComp, gComp, aComp; + + ASSERT(srcFormat == GL_RED || + srcFormat == GL_GREEN || + srcFormat == GL_BLUE || + srcFormat == GL_ALPHA || + srcFormat == GL_LUMINANCE || + srcFormat == GL_LUMINANCE_ALPHA || + srcFormat == GL_INTENSITY || + srcFormat == GL_RGB || + srcFormat == GL_BGR || + srcFormat == GL_RGBA || + srcFormat == GL_BGRA || + srcFormat == GL_ABGR_EXT); + + ASSERT(srcType == GL_UNSIGNED_BYTE || + srcType == GL_BYTE || + srcType == GL_UNSIGNED_SHORT || + srcType == GL_SHORT || + srcType == GL_UNSIGNED_INT || + srcType == GL_INT || + srcType == GL_FLOAT || + srcType == GL_UNSIGNED_BYTE_3_3_2 || + srcType == GL_UNSIGNED_BYTE_2_3_3_REV || + srcType == GL_UNSIGNED_SHORT_5_6_5 || + srcType == GL_UNSIGNED_SHORT_5_6_5_REV || + srcType == GL_UNSIGNED_SHORT_4_4_4_4 || + srcType == GL_UNSIGNED_SHORT_4_4_4_4_REV || + srcType == GL_UNSIGNED_SHORT_5_5_5_1 || + srcType == GL_UNSIGNED_SHORT_1_5_5_5_REV || + srcType == GL_UNSIGNED_INT_8_8_8_8 || + srcType == GL_UNSIGNED_INT_8_8_8_8_REV || + srcType == GL_UNSIGNED_INT_10_10_10_2 || + srcType == GL_UNSIGNED_INT_2_10_10_10_REV); + + rComp = gComp = bComp = aComp = -1; + + switch (srcFormat) { + case GL_RED: + redIndex = 0; + greenIndex = blueIndex = alphaIndex = -1; + stride = 1; + break; + case GL_GREEN: + greenIndex = 0; + redIndex = blueIndex = alphaIndex = -1; + stride = 1; + break; + case GL_BLUE: + blueIndex = 0; + redIndex = greenIndex = alphaIndex = -1; + stride = 1; + break; + case GL_ALPHA: + redIndex = greenIndex = blueIndex = -1; + alphaIndex = 0; + stride = 1; + break; + case GL_LUMINANCE: + redIndex = greenIndex = blueIndex = 0; + alphaIndex = -1; + stride = 1; + break; + case GL_LUMINANCE_ALPHA: + redIndex = greenIndex = blueIndex = 0; + alphaIndex = 1; + stride = 2; + break; + case GL_INTENSITY: + redIndex = greenIndex = blueIndex = alphaIndex = 0; + stride = 1; + break; + case GL_RGB: + redIndex = 0; + greenIndex = 1; + blueIndex = 2; + alphaIndex = -1; + stride = 3; + break; + case GL_BGR: + redIndex = 2; + greenIndex = 1; + blueIndex = 0; + alphaIndex = -1; + stride = 3; + break; + case GL_RGBA: + redIndex = 0; + greenIndex = 1; + blueIndex = 2; + alphaIndex = 3; + rComp = 0; + gComp = 1; + bComp = 2; + aComp = 3; + stride = 4; + break; + case GL_BGRA: + redIndex = 2; + greenIndex = 1; + blueIndex = 0; + alphaIndex = 3; + rComp = 2; + gComp = 1; + bComp = 0; + aComp = 3; + stride = 4; + break; + case GL_ABGR_EXT: + redIndex = 3; + greenIndex = 2; + blueIndex = 1; + alphaIndex = 0; + rComp = 3; + gComp = 2; + bComp = 1; + aComp = 0; + stride = 4; + break; + default: + _mesa_problem(NULL, "bad srcFormat in extract float data"); + return; + } + + +#define PROCESS(INDEX, CHANNEL, DEFAULT, TYPE, CONVERSION) \ + if ((INDEX) < 0) { \ + GLuint i; \ + for (i = 0; i < n; i++) { \ + rgba[i][CHANNEL] = DEFAULT; \ + } \ + } \ + else if (swapBytes) { \ + const TYPE *s = (const TYPE *) src; \ + GLuint i; \ + for (i = 0; i < n; i++) { \ + TYPE value = s[INDEX]; \ + if (sizeof(TYPE) == 2) { \ + SWAP2BYTE(value); \ + } \ + else if (sizeof(TYPE) == 4) { \ + SWAP4BYTE(value); \ + } \ + rgba[i][CHANNEL] = (GLfloat) CONVERSION(value); \ + s += stride; \ + } \ + } \ + else { \ + const TYPE *s = (const TYPE *) src; \ + GLuint i; \ + for (i = 0; i < n; i++) { \ + rgba[i][CHANNEL] = (GLfloat) CONVERSION(s[INDEX]); \ + s += stride; \ + } \ + } + + switch (srcType) { + case GL_UNSIGNED_BYTE: + PROCESS(redIndex, RCOMP, 0.0F, GLubyte, UBYTE_TO_FLOAT); + PROCESS(greenIndex, GCOMP, 0.0F, GLubyte, UBYTE_TO_FLOAT); + PROCESS(blueIndex, BCOMP, 0.0F, GLubyte, UBYTE_TO_FLOAT); + PROCESS(alphaIndex, ACOMP, 1.0F, GLubyte, UBYTE_TO_FLOAT); + break; + case GL_BYTE: + PROCESS(redIndex, RCOMP, 0.0F, GLbyte, BYTE_TO_FLOAT); + PROCESS(greenIndex, GCOMP, 0.0F, GLbyte, BYTE_TO_FLOAT); + PROCESS(blueIndex, BCOMP, 0.0F, GLbyte, BYTE_TO_FLOAT); + PROCESS(alphaIndex, ACOMP, 1.0F, GLbyte, BYTE_TO_FLOAT); + break; + case GL_UNSIGNED_SHORT: + PROCESS(redIndex, RCOMP, 0.0F, GLushort, USHORT_TO_FLOAT); + PROCESS(greenIndex, GCOMP, 0.0F, GLushort, USHORT_TO_FLOAT); + PROCESS(blueIndex, BCOMP, 0.0F, GLushort, USHORT_TO_FLOAT); + PROCESS(alphaIndex, ACOMP, 1.0F, GLushort, USHORT_TO_FLOAT); + break; + case GL_SHORT: + PROCESS(redIndex, RCOMP, 0.0F, GLshort, SHORT_TO_FLOAT); + PROCESS(greenIndex, GCOMP, 0.0F, GLshort, SHORT_TO_FLOAT); + PROCESS(blueIndex, BCOMP, 0.0F, GLshort, SHORT_TO_FLOAT); + PROCESS(alphaIndex, ACOMP, 1.0F, GLshort, SHORT_TO_FLOAT); + break; + case GL_UNSIGNED_INT: + PROCESS(redIndex, RCOMP, 0.0F, GLuint, UINT_TO_FLOAT); + PROCESS(greenIndex, GCOMP, 0.0F, GLuint, UINT_TO_FLOAT); + PROCESS(blueIndex, BCOMP, 0.0F, GLuint, UINT_TO_FLOAT); + PROCESS(alphaIndex, ACOMP, 1.0F, GLuint, UINT_TO_FLOAT); + break; + case GL_INT: + PROCESS(redIndex, RCOMP, 0.0F, GLint, INT_TO_FLOAT); + PROCESS(greenIndex, GCOMP, 0.0F, GLint, INT_TO_FLOAT); + PROCESS(blueIndex, BCOMP, 0.0F, GLint, INT_TO_FLOAT); + PROCESS(alphaIndex, ACOMP, 1.0F, GLint, INT_TO_FLOAT); + break; + case GL_FLOAT: + PROCESS(redIndex, RCOMP, 0.0F, GLfloat, (GLfloat)); + PROCESS(greenIndex, GCOMP, 0.0F, GLfloat, (GLfloat)); + PROCESS(blueIndex, BCOMP, 0.0F, GLfloat, (GLfloat)); + PROCESS(alphaIndex, ACOMP, 1.0F, GLfloat, (GLfloat)); + break; + case GL_UNSIGNED_BYTE_3_3_2: + { + const GLubyte *ubsrc = (const GLubyte *) src; + GLuint i; + for (i = 0; i < n; i ++) { + GLubyte p = ubsrc[i]; + rgba[i][RCOMP] = ((p >> 5) ) * (1.0F / 7.0F); + rgba[i][GCOMP] = ((p >> 2) & 0x7) * (1.0F / 7.0F); + rgba[i][BCOMP] = ((p ) & 0x3) * (1.0F / 3.0F); + rgba[i][ACOMP] = 1.0F; + } + } + break; + case GL_UNSIGNED_BYTE_2_3_3_REV: + { + const GLubyte *ubsrc = (const GLubyte *) src; + GLuint i; + for (i = 0; i < n; i ++) { + GLubyte p = ubsrc[i]; + rgba[i][RCOMP] = ((p ) & 0x7) * (1.0F / 7.0F); + rgba[i][GCOMP] = ((p >> 3) & 0x7) * (1.0F / 7.0F); + rgba[i][BCOMP] = ((p >> 6) ) * (1.0F / 3.0F); + rgba[i][ACOMP] = 1.0F; + } + } + break; + case GL_UNSIGNED_SHORT_5_6_5: + if (swapBytes) { + const GLushort *ussrc = (const GLushort *) src; + GLuint i; + for (i = 0; i < n; i ++) { + GLushort p = ussrc[i]; + SWAP2BYTE(p); + rgba[i][RCOMP] = ((p >> 11) ) * (1.0F / 31.0F); + rgba[i][GCOMP] = ((p >> 5) & 0x3f) * (1.0F / 63.0F); + rgba[i][BCOMP] = ((p ) & 0x1f) * (1.0F / 31.0F); + rgba[i][ACOMP] = 1.0F; + } + } + else { + const GLushort *ussrc = (const GLushort *) src; + GLuint i; + for (i = 0; i < n; i ++) { + GLushort p = ussrc[i]; + rgba[i][RCOMP] = ((p >> 11) ) * (1.0F / 31.0F); + rgba[i][GCOMP] = ((p >> 5) & 0x3f) * (1.0F / 63.0F); + rgba[i][BCOMP] = ((p ) & 0x1f) * (1.0F / 31.0F); + rgba[i][ACOMP] = 1.0F; + } + } + break; + case GL_UNSIGNED_SHORT_5_6_5_REV: + if (swapBytes) { + const GLushort *ussrc = (const GLushort *) src; + GLuint i; + for (i = 0; i < n; i ++) { + GLushort p = ussrc[i]; + SWAP2BYTE(p); + rgba[i][RCOMP] = ((p ) & 0x1f) * (1.0F / 31.0F); + rgba[i][GCOMP] = ((p >> 5) & 0x3f) * (1.0F / 63.0F); + rgba[i][BCOMP] = ((p >> 11) ) * (1.0F / 31.0F); + rgba[i][ACOMP] = 1.0F; + } + } + else { + const GLushort *ussrc = (const GLushort *) src; + GLuint i; + for (i = 0; i < n; i ++) { + GLushort p = ussrc[i]; + rgba[i][RCOMP] = ((p ) & 0x1f) * (1.0F / 31.0F); + rgba[i][GCOMP] = ((p >> 5) & 0x3f) * (1.0F / 63.0F); + rgba[i][BCOMP] = ((p >> 11) ) * (1.0F / 31.0F); + rgba[i][ACOMP] = 1.0F; + } + } + break; + case GL_UNSIGNED_SHORT_4_4_4_4: + if (swapBytes) { + const GLushort *ussrc = (const GLushort *) src; + GLuint i; + for (i = 0; i < n; i ++) { + GLushort p = ussrc[i]; + SWAP2BYTE(p); + rgba[i][rComp] = ((p >> 12) ) * (1.0F / 15.0F); + rgba[i][gComp] = ((p >> 8) & 0xf) * (1.0F / 15.0F); + rgba[i][bComp] = ((p >> 4) & 0xf) * (1.0F / 15.0F); + rgba[i][aComp] = ((p ) & 0xf) * (1.0F / 15.0F); + } + } + else { + const GLushort *ussrc = (const GLushort *) src; + GLuint i; + for (i = 0; i < n; i ++) { + GLushort p = ussrc[i]; + rgba[i][rComp] = ((p >> 12) ) * (1.0F / 15.0F); + rgba[i][gComp] = ((p >> 8) & 0xf) * (1.0F / 15.0F); + rgba[i][bComp] = ((p >> 4) & 0xf) * (1.0F / 15.0F); + rgba[i][aComp] = ((p ) & 0xf) * (1.0F / 15.0F); + } + } + break; + case GL_UNSIGNED_SHORT_4_4_4_4_REV: + if (swapBytes) { + const GLushort *ussrc = (const GLushort *) src; + GLuint i; + for (i = 0; i < n; i ++) { + GLushort p = ussrc[i]; + SWAP2BYTE(p); + rgba[i][rComp] = ((p ) & 0xf) * (1.0F / 15.0F); + rgba[i][gComp] = ((p >> 4) & 0xf) * (1.0F / 15.0F); + rgba[i][bComp] = ((p >> 8) & 0xf) * (1.0F / 15.0F); + rgba[i][aComp] = ((p >> 12) ) * (1.0F / 15.0F); + } + } + else { + const GLushort *ussrc = (const GLushort *) src; + GLuint i; + for (i = 0; i < n; i ++) { + GLushort p = ussrc[i]; + rgba[i][rComp] = ((p ) & 0xf) * (1.0F / 15.0F); + rgba[i][gComp] = ((p >> 4) & 0xf) * (1.0F / 15.0F); + rgba[i][bComp] = ((p >> 8) & 0xf) * (1.0F / 15.0F); + rgba[i][aComp] = ((p >> 12) ) * (1.0F / 15.0F); + } + } + break; + case GL_UNSIGNED_SHORT_5_5_5_1: + if (swapBytes) { + const GLushort *ussrc = (const GLushort *) src; + GLuint i; + for (i = 0; i < n; i ++) { + GLushort p = ussrc[i]; + SWAP2BYTE(p); + rgba[i][rComp] = ((p >> 11) ) * (1.0F / 31.0F); + rgba[i][gComp] = ((p >> 6) & 0x1f) * (1.0F / 31.0F); + rgba[i][bComp] = ((p >> 1) & 0x1f) * (1.0F / 31.0F); + rgba[i][aComp] = ((p ) & 0x1) * (1.0F / 1.0F); + } + } + else { + const GLushort *ussrc = (const GLushort *) src; + GLuint i; + for (i = 0; i < n; i ++) { + GLushort p = ussrc[i]; + rgba[i][rComp] = ((p >> 11) ) * (1.0F / 31.0F); + rgba[i][gComp] = ((p >> 6) & 0x1f) * (1.0F / 31.0F); + rgba[i][bComp] = ((p >> 1) & 0x1f) * (1.0F / 31.0F); + rgba[i][aComp] = ((p ) & 0x1) * (1.0F / 1.0F); + } + } + break; + case GL_UNSIGNED_SHORT_1_5_5_5_REV: + if (swapBytes) { + const GLushort *ussrc = (const GLushort *) src; + GLuint i; + for (i = 0; i < n; i ++) { + GLushort p = ussrc[i]; + SWAP2BYTE(p); + rgba[i][rComp] = ((p ) & 0x1f) * (1.0F / 31.0F); + rgba[i][gComp] = ((p >> 5) & 0x1f) * (1.0F / 31.0F); + rgba[i][bComp] = ((p >> 10) & 0x1f) * (1.0F / 31.0F); + rgba[i][aComp] = ((p >> 15) ) * (1.0F / 1.0F); + } + } + else { + const GLushort *ussrc = (const GLushort *) src; + GLuint i; + for (i = 0; i < n; i ++) { + GLushort p = ussrc[i]; + rgba[i][rComp] = ((p ) & 0x1f) * (1.0F / 31.0F); + rgba[i][gComp] = ((p >> 5) & 0x1f) * (1.0F / 31.0F); + rgba[i][bComp] = ((p >> 10) & 0x1f) * (1.0F / 31.0F); + rgba[i][aComp] = ((p >> 15) ) * (1.0F / 1.0F); + } + } + break; + case GL_UNSIGNED_INT_8_8_8_8: + if (swapBytes) { + const GLuint *uisrc = (const GLuint *) src; + GLuint i; + for (i = 0; i < n; i ++) { + GLuint p = uisrc[i]; + rgba[i][rComp] = UBYTE_TO_FLOAT((p ) & 0xff); + rgba[i][gComp] = UBYTE_TO_FLOAT((p >> 8) & 0xff); + rgba[i][bComp] = UBYTE_TO_FLOAT((p >> 16) & 0xff); + rgba[i][aComp] = UBYTE_TO_FLOAT((p >> 24) ); + } + } + else { + const GLuint *uisrc = (const GLuint *) src; + GLuint i; + for (i = 0; i < n; i ++) { + GLuint p = uisrc[i]; + rgba[i][rComp] = UBYTE_TO_FLOAT((p >> 24) ); + rgba[i][gComp] = UBYTE_TO_FLOAT((p >> 16) & 0xff); + rgba[i][bComp] = UBYTE_TO_FLOAT((p >> 8) & 0xff); + rgba[i][aComp] = UBYTE_TO_FLOAT((p ) & 0xff); + } + } + break; + case GL_UNSIGNED_INT_8_8_8_8_REV: + if (swapBytes) { + const GLuint *uisrc = (const GLuint *) src; + GLuint i; + for (i = 0; i < n; i ++) { + GLuint p = uisrc[i]; + rgba[i][rComp] = UBYTE_TO_FLOAT((p >> 24) ); + rgba[i][gComp] = UBYTE_TO_FLOAT((p >> 16) & 0xff); + rgba[i][bComp] = UBYTE_TO_FLOAT((p >> 8) & 0xff); + rgba[i][aComp] = UBYTE_TO_FLOAT((p ) & 0xff); + } + } + else { + const GLuint *uisrc = (const GLuint *) src; + GLuint i; + for (i = 0; i < n; i ++) { + GLuint p = uisrc[i]; + rgba[i][rComp] = UBYTE_TO_FLOAT((p ) & 0xff); + rgba[i][gComp] = UBYTE_TO_FLOAT((p >> 8) & 0xff); + rgba[i][bComp] = UBYTE_TO_FLOAT((p >> 16) & 0xff); + rgba[i][aComp] = UBYTE_TO_FLOAT((p >> 24) ); + } + } + break; + case GL_UNSIGNED_INT_10_10_10_2: + if (swapBytes) { + const GLuint *uisrc = (const GLuint *) src; + GLuint i; + for (i = 0; i < n; i ++) { + GLuint p = uisrc[i]; + SWAP4BYTE(p); + rgba[i][rComp] = ((p >> 22) ) * (1.0F / 1023.0F); + rgba[i][gComp] = ((p >> 12) & 0x3ff) * (1.0F / 1023.0F); + rgba[i][bComp] = ((p >> 2) & 0x3ff) * (1.0F / 1023.0F); + rgba[i][aComp] = ((p ) & 0x3 ) * (1.0F / 3.0F); + } + } + else { + const GLuint *uisrc = (const GLuint *) src; + GLuint i; + for (i = 0; i < n; i ++) { + GLuint p = uisrc[i]; + rgba[i][rComp] = ((p >> 22) ) * (1.0F / 1023.0F); + rgba[i][gComp] = ((p >> 12) & 0x3ff) * (1.0F / 1023.0F); + rgba[i][bComp] = ((p >> 2) & 0x3ff) * (1.0F / 1023.0F); + rgba[i][aComp] = ((p ) & 0x3 ) * (1.0F / 3.0F); + } + } + break; + case GL_UNSIGNED_INT_2_10_10_10_REV: + if (swapBytes) { + const GLuint *uisrc = (const GLuint *) src; + GLuint i; + for (i = 0; i < n; i ++) { + GLuint p = uisrc[i]; + SWAP4BYTE(p); + rgba[i][rComp] = ((p ) & 0x3ff) * (1.0F / 1023.0F); + rgba[i][gComp] = ((p >> 10) & 0x3ff) * (1.0F / 1023.0F); + rgba[i][bComp] = ((p >> 20) & 0x3ff) * (1.0F / 1023.0F); + rgba[i][aComp] = ((p >> 30) ) * (1.0F / 3.0F); + } + } + else { + const GLuint *uisrc = (const GLuint *) src; + GLuint i; + for (i = 0; i < n; i ++) { + GLuint p = uisrc[i]; + rgba[i][rComp] = ((p ) & 0x3ff) * (1.0F / 1023.0F); + rgba[i][gComp] = ((p >> 10) & 0x3ff) * (1.0F / 1023.0F); + rgba[i][bComp] = ((p >> 20) & 0x3ff) * (1.0F / 1023.0F); + rgba[i][aComp] = ((p >> 30) ) * (1.0F / 3.0F); + } + } + break; + default: + _mesa_problem(NULL, "bad srcType in extract float data"); + break; + } +} + + + +/* + * Unpack a row of color image data from a client buffer according to + * the pixel unpacking parameters. + * Return GLubyte values in the specified dest image format. + * This is (or will be) used by glDrawPixels and glTexImage?D(). + * Input: ctx - the context + * n - number of pixels in the span + * dstFormat - format of destination color array + * dest - the destination color array + * srcFormat - source image format + * srcType - source image datatype + * source - source image pointer + * srcPacking - pixel unpacking parameters + * transferOps - bitmask of IMAGE_*_BIT values of operations to apply + * + * XXX perhaps expand this to process whole images someday. + */ +void +_mesa_unpack_chan_color_span( GLcontext *ctx, + GLuint n, GLenum dstFormat, GLchan dest[], + GLenum srcFormat, GLenum srcType, + const GLvoid *source, + const struct gl_pixelstore_attrib *srcPacking, + GLuint transferOps ) +{ + ASSERT(dstFormat == GL_ALPHA || + dstFormat == GL_LUMINANCE || + dstFormat == GL_LUMINANCE_ALPHA || + dstFormat == GL_INTENSITY || + dstFormat == GL_RGB || + dstFormat == GL_RGBA || + dstFormat == GL_COLOR_INDEX); + + ASSERT(srcFormat == GL_RED || + srcFormat == GL_GREEN || + srcFormat == GL_BLUE || + srcFormat == GL_ALPHA || + srcFormat == GL_LUMINANCE || + srcFormat == GL_LUMINANCE_ALPHA || + srcFormat == GL_INTENSITY || + srcFormat == GL_RGB || + srcFormat == GL_BGR || + srcFormat == GL_RGBA || + srcFormat == GL_BGRA || + srcFormat == GL_ABGR_EXT || + srcFormat == GL_COLOR_INDEX); + + ASSERT(srcType == GL_BITMAP || + srcType == GL_UNSIGNED_BYTE || + srcType == GL_BYTE || + srcType == GL_UNSIGNED_SHORT || + srcType == GL_SHORT || + srcType == GL_UNSIGNED_INT || + srcType == GL_INT || + srcType == GL_FLOAT || + srcType == GL_UNSIGNED_BYTE_3_3_2 || + srcType == GL_UNSIGNED_BYTE_2_3_3_REV || + srcType == GL_UNSIGNED_SHORT_5_6_5 || + srcType == GL_UNSIGNED_SHORT_5_6_5_REV || + srcType == GL_UNSIGNED_SHORT_4_4_4_4 || + srcType == GL_UNSIGNED_SHORT_4_4_4_4_REV || + srcType == GL_UNSIGNED_SHORT_5_5_5_1 || + srcType == GL_UNSIGNED_SHORT_1_5_5_5_REV || + srcType == GL_UNSIGNED_INT_8_8_8_8 || + srcType == GL_UNSIGNED_INT_8_8_8_8_REV || + srcType == GL_UNSIGNED_INT_10_10_10_2 || + srcType == GL_UNSIGNED_INT_2_10_10_10_REV); + + /* Try simple cases first */ + if (transferOps == 0 && srcType == CHAN_TYPE) { + if (dstFormat == GL_RGBA) { + if (srcFormat == GL_RGBA) { + MEMCPY( dest, source, n * 4 * sizeof(GLchan) ); + return; + } + else if (srcFormat == GL_RGB) { + GLuint i; + const GLchan *src = (const GLchan *) source; + GLchan *dst = dest; + for (i = 0; i < n; i++) { + dst[0] = src[0]; + dst[1] = src[1]; + dst[2] = src[2]; + dst[3] = CHAN_MAX; + src += 3; + dst += 4; + } + return; + } + } + else if (dstFormat == GL_RGB) { + if (srcFormat == GL_RGB) { + MEMCPY( dest, source, n * 3 * sizeof(GLchan) ); + return; + } + else if (srcFormat == GL_RGBA) { + GLuint i; + const GLchan *src = (const GLchan *) source; + GLchan *dst = dest; + for (i = 0; i < n; i++) { + dst[0] = src[0]; + dst[1] = src[1]; + dst[2] = src[2]; + src += 4; + dst += 3; + } + return; + } + } + else if (dstFormat == srcFormat) { + GLint comps = _mesa_components_in_format(srcFormat); + assert(comps > 0); + MEMCPY( dest, source, n * comps * sizeof(GLchan) ); + return; + } + } + + + /* general solution begins here */ + { + GLint dstComponents; + GLint dstRedIndex, dstGreenIndex, dstBlueIndex, dstAlphaIndex; + GLint dstLuminanceIndex, dstIntensityIndex; + DEFMARRAY(GLfloat, rgba, MAX_WIDTH, 4); /* mac 32k limitation */ + CHECKARRAY(rgba, return); /* mac 32k limitation */ + + dstComponents = _mesa_components_in_format( dstFormat ); + /* source & dest image formats should have been error checked by now */ + assert(dstComponents > 0); + + /* + * Extract image data and convert to RGBA floats + */ + assert(n <= MAX_WIDTH); + if (srcFormat == GL_COLOR_INDEX) { + GLuint indexes[MAX_WIDTH]; + extract_uint_indexes(n, indexes, srcFormat, srcType, source, + srcPacking); + + if (dstFormat == GL_COLOR_INDEX + && (transferOps & IMAGE_MAP_COLOR_BIT)) { + _mesa_map_ci(ctx, n, indexes); + } + if (transferOps & IMAGE_SHIFT_OFFSET_BIT) { + _mesa_shift_and_offset_ci(ctx, n, indexes); + } + + if (dstFormat == GL_COLOR_INDEX) { + /* convert to GLchan and return */ + GLuint i; + for (i = 0; i < n; i++) { + dest[i] = (GLchan) (indexes[i] & 0xff); + } + UNDEFARRAY(rgba); /* mac 32k limitation */ + return; + } + else { + /* Convert indexes to RGBA */ + _mesa_map_ci_to_rgba(ctx, n, indexes, rgba); + } + } + else { + extract_float_rgba(n, rgba, srcFormat, srcType, source, + srcPacking->SwapBytes); + + /* scale and bias colors */ + if (transferOps & IMAGE_SCALE_BIAS_BIT) { + _mesa_scale_and_bias_rgba(ctx, n, rgba, + ctx->Pixel.RedScale, ctx->Pixel.GreenScale, + ctx->Pixel.BlueScale, ctx->Pixel.AlphaScale, + ctx->Pixel.RedBias, ctx->Pixel.GreenBias, + ctx->Pixel.BlueBias, ctx->Pixel.AlphaBias); + } + /* color map lookup */ + if (transferOps & IMAGE_MAP_COLOR_BIT) { + _mesa_map_rgba(ctx, n, rgba); + } + } + + if (transferOps) { + /* GL_COLOR_TABLE lookup */ + if (transferOps & IMAGE_COLOR_TABLE_BIT) { + _mesa_lookup_rgba(&ctx->ColorTable, n, rgba); + } + /* convolution */ + if (transferOps & IMAGE_CONVOLUTION_BIT) { + /* this has to be done in the calling code */ + } + /* GL_POST_CONVOLUTION_RED/GREEN/BLUE/ALPHA_SCALE/BIAS */ + if (transferOps & IMAGE_POST_CONVOLUTION_SCALE_BIAS) { + _mesa_scale_and_bias_rgba(ctx, n, rgba, + ctx->Pixel.PostConvolutionScale[RCOMP], + ctx->Pixel.PostConvolutionScale[GCOMP], + ctx->Pixel.PostConvolutionScale[BCOMP], + ctx->Pixel.PostConvolutionScale[ACOMP], + ctx->Pixel.PostConvolutionBias[RCOMP], + ctx->Pixel.PostConvolutionBias[GCOMP], + ctx->Pixel.PostConvolutionBias[BCOMP], + ctx->Pixel.PostConvolutionBias[ACOMP]); + } + /* GL_POST_CONVOLUTION_COLOR_TABLE lookup */ + if (transferOps & IMAGE_POST_CONVOLUTION_COLOR_TABLE_BIT) { + _mesa_lookup_rgba(&ctx->PostConvolutionColorTable, n, rgba); + } + /* color matrix transform */ + if (transferOps & IMAGE_COLOR_MATRIX_BIT) { + _mesa_transform_rgba(ctx, n, rgba); + } + /* GL_POST_COLOR_MATRIX_COLOR_TABLE lookup */ + if (transferOps & IMAGE_POST_COLOR_MATRIX_COLOR_TABLE_BIT) { + _mesa_lookup_rgba(&ctx->PostColorMatrixColorTable, n, rgba); + } + /* update histogram count */ + if (transferOps & IMAGE_HISTOGRAM_BIT) { + _mesa_update_histogram(ctx, n, (CONST GLfloat (*)[4]) rgba); + } + /* min/max here */ + if (transferOps & IMAGE_MIN_MAX_BIT) { + _mesa_update_minmax(ctx, n, (CONST GLfloat (*)[4]) rgba); + } + } + + /* clamp to [0,1] */ + { + GLuint i; + for (i = 0; i < n; i++) { + rgba[i][RCOMP] = CLAMP(rgba[i][RCOMP], 0.0F, 1.0F); + rgba[i][GCOMP] = CLAMP(rgba[i][GCOMP], 0.0F, 1.0F); + rgba[i][BCOMP] = CLAMP(rgba[i][BCOMP], 0.0F, 1.0F); + rgba[i][ACOMP] = CLAMP(rgba[i][ACOMP], 0.0F, 1.0F); + } + } + + /* Now determine which color channels we need to produce. + * And determine the dest index (offset) within each color tuple. + */ + switch (dstFormat) { + case GL_ALPHA: + dstAlphaIndex = 0; + dstRedIndex = dstGreenIndex = dstBlueIndex = -1; + dstLuminanceIndex = dstIntensityIndex = -1; + break; + case GL_LUMINANCE: + dstLuminanceIndex = 0; + dstRedIndex = dstGreenIndex = dstBlueIndex = dstAlphaIndex = -1; + dstIntensityIndex = -1; + break; + case GL_LUMINANCE_ALPHA: + dstLuminanceIndex = 0; + dstAlphaIndex = 1; + dstRedIndex = dstGreenIndex = dstBlueIndex = -1; + dstIntensityIndex = -1; + break; + case GL_INTENSITY: + dstIntensityIndex = 0; + dstRedIndex = dstGreenIndex = dstBlueIndex = dstAlphaIndex = -1; + dstLuminanceIndex = -1; + break; + case GL_RGB: + dstRedIndex = 0; + dstGreenIndex = 1; + dstBlueIndex = 2; + dstAlphaIndex = dstLuminanceIndex = dstIntensityIndex = -1; + break; + case GL_RGBA: + dstRedIndex = 0; + dstGreenIndex = 1; + dstBlueIndex = 2; + dstAlphaIndex = 3; + dstLuminanceIndex = dstIntensityIndex = -1; + break; + default: + _mesa_problem(ctx, "bad dstFormat in _mesa_unpack_chan_span()"); + UNDEFARRAY(rgba); /* mac 32k limitation */ + return; + } + + + /* Now return the GLchan data in the requested dstFormat */ + + if (dstRedIndex >= 0) { + GLchan *dst = dest; + GLuint i; + for (i = 0; i < n; i++) { + CLAMPED_FLOAT_TO_CHAN(dst[dstRedIndex], rgba[i][RCOMP]); + dst += dstComponents; + } + } + + if (dstGreenIndex >= 0) { + GLchan *dst = dest; + GLuint i; + for (i = 0; i < n; i++) { + CLAMPED_FLOAT_TO_CHAN(dst[dstGreenIndex], rgba[i][GCOMP]); + dst += dstComponents; + } + } + + if (dstBlueIndex >= 0) { + GLchan *dst = dest; + GLuint i; + for (i = 0; i < n; i++) { + CLAMPED_FLOAT_TO_CHAN(dst[dstBlueIndex], rgba[i][BCOMP]); + dst += dstComponents; + } + } + + if (dstAlphaIndex >= 0) { + GLchan *dst = dest; + GLuint i; + for (i = 0; i < n; i++) { + CLAMPED_FLOAT_TO_CHAN(dst[dstAlphaIndex], rgba[i][ACOMP]); + dst += dstComponents; + } + } + + if (dstIntensityIndex >= 0) { + GLchan *dst = dest; + GLuint i; + assert(dstIntensityIndex == 0); + assert(dstComponents == 1); + for (i = 0; i < n; i++) { + /* Intensity comes from red channel */ + CLAMPED_FLOAT_TO_CHAN(dst[i], rgba[i][RCOMP]); + } + } + + if (dstLuminanceIndex >= 0) { + GLchan *dst = dest; + GLuint i; + assert(dstLuminanceIndex == 0); + for (i = 0; i < n; i++) { + /* Luminance comes from red channel */ + CLAMPED_FLOAT_TO_CHAN(dst[0], rgba[i][RCOMP]); + dst += dstComponents; + } + } + UNDEFARRAY(rgba); /* mac 32k limitation */ + } +} + + +void +_mesa_unpack_float_color_span( GLcontext *ctx, + GLuint n, GLenum dstFormat, GLfloat dest[], + GLenum srcFormat, GLenum srcType, + const GLvoid *source, + const struct gl_pixelstore_attrib *srcPacking, + GLuint transferOps, GLboolean clamp ) +{ + ASSERT(dstFormat == GL_ALPHA || + dstFormat == GL_LUMINANCE || + dstFormat == GL_LUMINANCE_ALPHA || + dstFormat == GL_INTENSITY || + dstFormat == GL_RGB || + dstFormat == GL_RGBA || + dstFormat == GL_COLOR_INDEX); + + ASSERT(srcFormat == GL_RED || + srcFormat == GL_GREEN || + srcFormat == GL_BLUE || + srcFormat == GL_ALPHA || + srcFormat == GL_LUMINANCE || + srcFormat == GL_LUMINANCE_ALPHA || + srcFormat == GL_INTENSITY || + srcFormat == GL_RGB || + srcFormat == GL_BGR || + srcFormat == GL_RGBA || + srcFormat == GL_BGRA || + srcFormat == GL_ABGR_EXT || + srcFormat == GL_COLOR_INDEX); + + ASSERT(srcType == GL_BITMAP || + srcType == GL_UNSIGNED_BYTE || + srcType == GL_BYTE || + srcType == GL_UNSIGNED_SHORT || + srcType == GL_SHORT || + srcType == GL_UNSIGNED_INT || + srcType == GL_INT || + srcType == GL_FLOAT || + srcType == GL_UNSIGNED_BYTE_3_3_2 || + srcType == GL_UNSIGNED_BYTE_2_3_3_REV || + srcType == GL_UNSIGNED_SHORT_5_6_5 || + srcType == GL_UNSIGNED_SHORT_5_6_5_REV || + srcType == GL_UNSIGNED_SHORT_4_4_4_4 || + srcType == GL_UNSIGNED_SHORT_4_4_4_4_REV || + srcType == GL_UNSIGNED_SHORT_5_5_5_1 || + srcType == GL_UNSIGNED_SHORT_1_5_5_5_REV || + srcType == GL_UNSIGNED_INT_8_8_8_8 || + srcType == GL_UNSIGNED_INT_8_8_8_8_REV || + srcType == GL_UNSIGNED_INT_10_10_10_2 || + srcType == GL_UNSIGNED_INT_2_10_10_10_REV); + + /* general solution, no special cases, yet */ + { + GLint dstComponents; + GLint dstRedIndex, dstGreenIndex, dstBlueIndex, dstAlphaIndex; + GLint dstLuminanceIndex, dstIntensityIndex; + DEFMARRAY(GLfloat, rgba, MAX_WIDTH, 4); /* mac 32k limitation */ + CHECKARRAY(rgba, return); /* mac 32k limitation */ + + dstComponents = _mesa_components_in_format( dstFormat ); + /* source & dest image formats should have been error checked by now */ + assert(dstComponents > 0); + + /* + * Extract image data and convert to RGBA floats + */ + assert(n <= MAX_WIDTH); + if (srcFormat == GL_COLOR_INDEX) { + GLuint indexes[MAX_WIDTH]; + extract_uint_indexes(n, indexes, srcFormat, srcType, source, + srcPacking); + + if (dstFormat == GL_COLOR_INDEX + && (transferOps & IMAGE_MAP_COLOR_BIT)) { + _mesa_map_ci(ctx, n, indexes); + } + if (transferOps & IMAGE_SHIFT_OFFSET_BIT) { + _mesa_shift_and_offset_ci(ctx, n, indexes); + } + + if (dstFormat == GL_COLOR_INDEX) { + /* convert to GLchan and return */ + GLuint i; + for (i = 0; i < n; i++) { + dest[i] = (GLchan) (indexes[i] & 0xff); + } + UNDEFARRAY(rgba); /* mac 32k limitation */ + return; + } + else { + /* Convert indexes to RGBA */ + _mesa_map_ci_to_rgba(ctx, n, indexes, rgba); + } + } + else { + extract_float_rgba(n, rgba, srcFormat, srcType, source, + srcPacking->SwapBytes); + + /* scale and bias colors */ + if (transferOps & IMAGE_SCALE_BIAS_BIT) { + _mesa_scale_and_bias_rgba(ctx, n, rgba, + ctx->Pixel.RedScale, ctx->Pixel.GreenScale, + ctx->Pixel.BlueScale, ctx->Pixel.AlphaScale, + ctx->Pixel.RedBias, ctx->Pixel.GreenBias, + ctx->Pixel.BlueBias, ctx->Pixel.AlphaBias); + } + /* color map lookup */ + if (transferOps & IMAGE_MAP_COLOR_BIT) { + _mesa_map_rgba(ctx, n, rgba); + } + } + + if (transferOps) { + /* GL_COLOR_TABLE lookup */ + if (transferOps & IMAGE_COLOR_TABLE_BIT) { + _mesa_lookup_rgba(&ctx->ColorTable, n, rgba); + } + /* convolution */ + if (transferOps & IMAGE_CONVOLUTION_BIT) { + /* XXX to do */ + } + /* GL_POST_CONVOLUTION_RED/GREEN/BLUE/ALPHA_SCALE/BIAS */ + if (transferOps & IMAGE_POST_CONVOLUTION_SCALE_BIAS) { + _mesa_scale_and_bias_rgba(ctx, n, rgba, + ctx->Pixel.PostConvolutionScale[RCOMP], + ctx->Pixel.PostConvolutionScale[GCOMP], + ctx->Pixel.PostConvolutionScale[BCOMP], + ctx->Pixel.PostConvolutionScale[ACOMP], + ctx->Pixel.PostConvolutionBias[RCOMP], + ctx->Pixel.PostConvolutionBias[GCOMP], + ctx->Pixel.PostConvolutionBias[BCOMP], + ctx->Pixel.PostConvolutionBias[ACOMP]); + } + /* GL_POST_CONVOLUTION_COLOR_TABLE lookup */ + if (transferOps & IMAGE_POST_CONVOLUTION_COLOR_TABLE_BIT) { + _mesa_lookup_rgba(&ctx->PostConvolutionColorTable, n, rgba); + } + /* color matrix transform */ + if (transferOps & IMAGE_COLOR_MATRIX_BIT) { + _mesa_transform_rgba(ctx, n, rgba); + } + /* GL_POST_COLOR_MATRIX_COLOR_TABLE lookup */ + if (transferOps & IMAGE_POST_COLOR_MATRIX_COLOR_TABLE_BIT) { + _mesa_lookup_rgba(&ctx->PostColorMatrixColorTable, n, rgba); + } + /* update histogram count */ + if (transferOps & IMAGE_HISTOGRAM_BIT) { + _mesa_update_histogram(ctx, n, (CONST GLfloat (*)[4]) rgba); + } + /* min/max here */ + if (transferOps & IMAGE_MIN_MAX_BIT) { + _mesa_update_minmax(ctx, n, (CONST GLfloat (*)[4]) rgba); + } + } + + /* clamp to [0,1] */ + if (clamp) { + GLuint i; + for (i = 0; i < n; i++) { + rgba[i][RCOMP] = CLAMP(rgba[i][RCOMP], 0.0F, 1.0F); + rgba[i][GCOMP] = CLAMP(rgba[i][GCOMP], 0.0F, 1.0F); + rgba[i][BCOMP] = CLAMP(rgba[i][BCOMP], 0.0F, 1.0F); + rgba[i][ACOMP] = CLAMP(rgba[i][ACOMP], 0.0F, 1.0F); + } + } + + /* Now determine which color channels we need to produce. + * And determine the dest index (offset) within each color tuple. + */ + switch (dstFormat) { + case GL_ALPHA: + dstAlphaIndex = 0; + dstRedIndex = dstGreenIndex = dstBlueIndex = -1; + dstLuminanceIndex = dstIntensityIndex = -1; + break; + case GL_LUMINANCE: + dstLuminanceIndex = 0; + dstRedIndex = dstGreenIndex = dstBlueIndex = dstAlphaIndex = -1; + dstIntensityIndex = -1; + break; + case GL_LUMINANCE_ALPHA: + dstLuminanceIndex = 0; + dstAlphaIndex = 1; + dstRedIndex = dstGreenIndex = dstBlueIndex = -1; + dstIntensityIndex = -1; + break; + case GL_INTENSITY: + dstIntensityIndex = 0; + dstRedIndex = dstGreenIndex = dstBlueIndex = dstAlphaIndex = -1; + dstLuminanceIndex = -1; + break; + case GL_RGB: + dstRedIndex = 0; + dstGreenIndex = 1; + dstBlueIndex = 2; + dstAlphaIndex = dstLuminanceIndex = dstIntensityIndex = -1; + break; + case GL_RGBA: + dstRedIndex = 0; + dstGreenIndex = 1; + dstBlueIndex = 2; + dstAlphaIndex = 3; + dstLuminanceIndex = dstIntensityIndex = -1; + break; + default: + _mesa_problem(ctx, "bad dstFormat in _mesa_unpack_float_color_span()"); + UNDEFARRAY(rgba); /* mac 32k limitation */ + return; + } + + /* Now pack results in the requested dstFormat */ + if (dstRedIndex >= 0) { + GLfloat *dst = dest; + GLuint i; + for (i = 0; i < n; i++) { + dst[dstRedIndex] = rgba[i][RCOMP]; + dst += dstComponents; + } + } + + if (dstGreenIndex >= 0) { + GLfloat *dst = dest; + GLuint i; + for (i = 0; i < n; i++) { + dst[dstGreenIndex] = rgba[i][GCOMP]; + dst += dstComponents; + } + } + + if (dstBlueIndex >= 0) { + GLfloat *dst = dest; + GLuint i; + for (i = 0; i < n; i++) { + dst[dstBlueIndex] = rgba[i][BCOMP]; + dst += dstComponents; + } + } + + if (dstAlphaIndex >= 0) { + GLfloat *dst = dest; + GLuint i; + for (i = 0; i < n; i++) { + dst[dstAlphaIndex] = rgba[i][ACOMP]; + dst += dstComponents; + } + } + + if (dstIntensityIndex >= 0) { + GLfloat *dst = dest; + GLuint i; + assert(dstIntensityIndex == 0); + assert(dstComponents == 1); + for (i = 0; i < n; i++) { + /* Intensity comes from red channel */ + dst[i] = rgba[i][RCOMP]; + } + } + + if (dstLuminanceIndex >= 0) { + GLfloat *dst = dest; + GLuint i; + assert(dstLuminanceIndex == 0); + for (i = 0; i < n; i++) { + /* Luminance comes from red channel */ + dst[0] = rgba[i][RCOMP]; + dst += dstComponents; + } + } + UNDEFARRAY(rgba); /* mac 32k limitation */ + } +} + + + + +/* + * Unpack a row of color index data from a client buffer according to + * the pixel unpacking parameters. + * This is (or will be) used by glDrawPixels, glTexImage[123]D, etc. + * + * Args: ctx - the context + * n - number of pixels + * dstType - destination datatype + * dest - destination array + * srcType - source pixel type + * source - source data pointer + * srcPacking - pixel unpacking parameters + * transferOps - the pixel transfer operations to apply + */ +void +_mesa_unpack_index_span( const GLcontext *ctx, GLuint n, + GLenum dstType, GLvoid *dest, + GLenum srcType, const GLvoid *source, + const struct gl_pixelstore_attrib *srcPacking, + GLuint transferOps ) +{ + ASSERT(srcType == GL_BITMAP || + srcType == GL_UNSIGNED_BYTE || + srcType == GL_BYTE || + srcType == GL_UNSIGNED_SHORT || + srcType == GL_SHORT || + srcType == GL_UNSIGNED_INT || + srcType == GL_INT || + srcType == GL_FLOAT); + + ASSERT(dstType == GL_UNSIGNED_BYTE || + dstType == GL_UNSIGNED_SHORT || + dstType == GL_UNSIGNED_INT); + + + transferOps &= (IMAGE_MAP_COLOR_BIT | IMAGE_SHIFT_OFFSET_BIT); + + /* + * Try simple cases first + */ + if (transferOps == 0 && srcType == GL_UNSIGNED_BYTE + && dstType == GL_UNSIGNED_BYTE) { + MEMCPY(dest, source, n * sizeof(GLubyte)); + } + else if (transferOps == 0 && srcType == GL_UNSIGNED_INT + && dstType == GL_UNSIGNED_INT && !srcPacking->SwapBytes) { + MEMCPY(dest, source, n * sizeof(GLuint)); + } + else { + /* + * general solution + */ + GLuint indexes[MAX_WIDTH]; + assert(n <= MAX_WIDTH); + + extract_uint_indexes(n, indexes, GL_COLOR_INDEX, srcType, source, + srcPacking); + + if (transferOps & IMAGE_SHIFT_OFFSET_BIT) { + /* shift and offset indexes */ + _mesa_shift_and_offset_ci(ctx, n, indexes); + } + if (transferOps & IMAGE_MAP_COLOR_BIT) { + /* Apply lookup table */ + _mesa_map_ci(ctx, n, indexes); + } + + /* convert to dest type */ + switch (dstType) { + case GL_UNSIGNED_BYTE: + { + GLubyte *dst = (GLubyte *) dest; + GLuint i; + for (i = 0; i < n; i++) { + dst[i] = (GLubyte) (indexes[i] & 0xff); + } + } + break; + case GL_UNSIGNED_SHORT: + { + GLuint *dst = (GLuint *) dest; + GLuint i; + for (i = 0; i < n; i++) { + dst[i] = (GLushort) (indexes[i] & 0xffff); + } + } + break; + case GL_UNSIGNED_INT: + MEMCPY(dest, indexes, n * sizeof(GLuint)); + break; + default: + _mesa_problem(ctx, "bad dstType in _mesa_unpack_index_span"); + } + } +} + + +void +_mesa_pack_index_span( const GLcontext *ctx, GLuint n, + GLenum dstType, GLvoid *dest, const GLuint *source, + const struct gl_pixelstore_attrib *dstPacking, + GLuint transferOps ) +{ + GLuint indexes[MAX_WIDTH]; + + ASSERT(n <= MAX_WIDTH); + + transferOps &= (IMAGE_MAP_COLOR_BIT | IMAGE_SHIFT_OFFSET_BIT); + + if (transferOps & (IMAGE_MAP_COLOR_BIT | IMAGE_SHIFT_OFFSET_BIT)) { + /* make a copy of input */ + MEMCPY(indexes, source, n * sizeof(GLuint)); + if (transferOps & IMAGE_SHIFT_OFFSET_BIT) { + _mesa_shift_and_offset_ci( ctx, n, indexes); + } + if (transferOps & IMAGE_MAP_COLOR_BIT) { + _mesa_map_ci(ctx, n, indexes); + } + source = indexes; + } + + switch (dstType) { + case GL_UNSIGNED_BYTE: + { + GLubyte *dst = (GLubyte *) dest; + GLuint i; + for (i = 0; i < n; i++) { + *dst++ = (GLubyte) source[i]; + } + } + break; + case GL_BYTE: + { + GLbyte *dst = (GLbyte *) dest; + GLuint i; + for (i = 0; i < n; i++) { + dst[i] = (GLbyte) source[i]; + } + } + break; + case GL_UNSIGNED_SHORT: + { + GLushort *dst = (GLushort *) dest; + GLuint i; + for (i = 0; i < n; i++) { + dst[i] = (GLushort) source[i]; + } + if (dstPacking->SwapBytes) { + _mesa_swap2( (GLushort *) dst, n ); + } + } + break; + case GL_SHORT: + { + GLshort *dst = (GLshort *) dest; + GLuint i; + for (i = 0; i < n; i++) { + dst[i] = (GLshort) source[i]; + } + if (dstPacking->SwapBytes) { + _mesa_swap2( (GLushort *) dst, n ); + } + } + break; + case GL_UNSIGNED_INT: + { + GLuint *dst = (GLuint *) dest; + GLuint i; + for (i = 0; i < n; i++) { + dst[i] = (GLuint) source[i]; + } + if (dstPacking->SwapBytes) { + _mesa_swap4( (GLuint *) dst, n ); + } + } + break; + case GL_INT: + { + GLint *dst = (GLint *) dest; + GLuint i; + for (i = 0; i < n; i++) { + dst[i] = (GLint) source[i]; + } + if (dstPacking->SwapBytes) { + _mesa_swap4( (GLuint *) dst, n ); + } + } + break; + case GL_FLOAT: + { + GLfloat *dst = (GLfloat *) dest; + GLuint i; + for (i = 0; i < n; i++) { + dst[i] = (GLfloat) source[i]; + } + if (dstPacking->SwapBytes) { + _mesa_swap4( (GLuint *) dst, n ); + } + } + break; + default: + _mesa_problem(ctx, "bad type in _mesa_pack_index_span"); + } +} + + + +/* + * Unpack a row of stencil data from a client buffer according to + * the pixel unpacking parameters. + * This is (or will be) used by glDrawPixels + * + * Args: ctx - the context + * n - number of pixels + * dstType - destination datatype + * dest - destination array + * srcType - source pixel type + * source - source data pointer + * srcPacking - pixel unpacking parameters + * transferOps - apply offset/bias/lookup ops? + */ +void +_mesa_unpack_stencil_span( const GLcontext *ctx, GLuint n, + GLenum dstType, GLvoid *dest, + GLenum srcType, const GLvoid *source, + const struct gl_pixelstore_attrib *srcPacking, + GLuint transferOps ) +{ + ASSERT(srcType == GL_BITMAP || + srcType == GL_UNSIGNED_BYTE || + srcType == GL_BYTE || + srcType == GL_UNSIGNED_SHORT || + srcType == GL_SHORT || + srcType == GL_UNSIGNED_INT || + srcType == GL_INT || + srcType == GL_FLOAT); + + ASSERT(dstType == GL_UNSIGNED_BYTE || + dstType == GL_UNSIGNED_SHORT || + dstType == GL_UNSIGNED_INT); + + /* only shift and offset apply to stencil */ + transferOps &= IMAGE_SHIFT_OFFSET_BIT; + + /* + * Try simple cases first + */ + if (transferOps == 0 && + srcType == GL_UNSIGNED_BYTE && + dstType == GL_UNSIGNED_BYTE) { + MEMCPY(dest, source, n * sizeof(GLubyte)); + } + else if (transferOps == 0 && + srcType == GL_UNSIGNED_INT && + dstType == GL_UNSIGNED_INT && + !srcPacking->SwapBytes) { + MEMCPY(dest, source, n * sizeof(GLuint)); + } + else { + /* + * general solution + */ + GLuint indexes[MAX_WIDTH]; + assert(n <= MAX_WIDTH); + + extract_uint_indexes(n, indexes, GL_COLOR_INDEX, srcType, source, + srcPacking); + + if (transferOps) { + if (transferOps & IMAGE_SHIFT_OFFSET_BIT) { + /* shift and offset indexes */ + _mesa_shift_and_offset_ci(ctx, n, indexes); + } + + if (ctx->Pixel.MapStencilFlag) { + /* Apply stencil lookup table */ + GLuint mask = ctx->Pixel.MapStoSsize - 1; + GLuint i; + for (i=0;iPixel.MapStoS[ indexes[i] & mask ]; + } + } + } + + /* convert to dest type */ + switch (dstType) { + case GL_UNSIGNED_BYTE: + { + GLubyte *dst = (GLubyte *) dest; + GLuint i; + for (i = 0; i < n; i++) { + dst[i] = (GLubyte) (indexes[i] & 0xff); + } + } + break; + case GL_UNSIGNED_SHORT: + { + GLuint *dst = (GLuint *) dest; + GLuint i; + for (i = 0; i < n; i++) { + dst[i] = (GLushort) (indexes[i] & 0xffff); + } + } + break; + case GL_UNSIGNED_INT: + MEMCPY(dest, indexes, n * sizeof(GLuint)); + break; + default: + _mesa_problem(ctx, "bad dstType in _mesa_unpack_stencil_span"); + } + } +} + + +void +_mesa_pack_stencil_span( const GLcontext *ctx, GLuint n, + GLenum dstType, GLvoid *dest, const GLstencil *source, + const struct gl_pixelstore_attrib *dstPacking ) +{ + GLstencil stencil[MAX_WIDTH]; + + ASSERT(n <= MAX_WIDTH); + + if (ctx->Pixel.IndexShift || ctx->Pixel.IndexOffset || + ctx->Pixel.MapStencilFlag) { + /* make a copy of input */ + MEMCPY(stencil, source, n * sizeof(GLstencil)); + if (ctx->Pixel.IndexShift || ctx->Pixel.IndexOffset) { + _mesa_shift_and_offset_stencil( ctx, n, stencil ); + } + if (ctx->Pixel.MapStencilFlag) { + _mesa_map_stencil( ctx, n, stencil ); + } + source = stencil; + } + + switch (dstType) { + case GL_UNSIGNED_BYTE: + if (sizeof(GLstencil) == 8) { + MEMCPY( dest, source, n ); + } + else { + GLubyte *dst = (GLubyte *) dest; + GLuint i; + for (i=0;iSwapBytes) { + _mesa_swap2( (GLushort *) dst, n ); + } + } + break; + case GL_SHORT: + { + GLshort *dst = (GLshort *) dest; + GLuint i; + for (i=0;iSwapBytes) { + _mesa_swap2( (GLushort *) dst, n ); + } + } + break; + case GL_UNSIGNED_INT: + { + GLuint *dst = (GLuint *) dest; + GLuint i; + for (i=0;iSwapBytes) { + _mesa_swap4( (GLuint *) dst, n ); + } + } + break; + case GL_INT: + { + GLint *dst = (GLint *) dest; + GLuint i; + for (i=0;iSwapBytes) { + _mesa_swap4( (GLuint *) dst, n ); + } + } + break; + case GL_FLOAT: + { + GLfloat *dst = (GLfloat *) dest; + GLuint i; + for (i=0;iSwapBytes) { + _mesa_swap4( (GLuint *) dst, n ); + } + } + break; + case GL_BITMAP: + if (dstPacking->LsbFirst) { + GLubyte *dst = (GLubyte *) dest; + GLint shift = 0; + GLuint i; + for (i = 0; i < n; i++) { + if (shift == 0) + *dst = 0; + *dst |= ((source[i] != 0) << shift); + shift++; + if (shift == 8) { + shift = 0; + dst++; + } + } + } + else { + GLubyte *dst = (GLubyte *) dest; + GLint shift = 7; + GLuint i; + for (i = 0; i < n; i++) { + if (shift == 7) + *dst = 0; + *dst |= ((source[i] != 0) << shift); + shift--; + if (shift < 0) { + shift = 7; + dst++; + } + } + } + break; + default: + _mesa_problem(ctx, "bad type in _mesa_pack_index_span"); + } +} + + + +void +_mesa_unpack_depth_span( const GLcontext *ctx, GLuint n, GLfloat *dest, + GLenum srcType, const GLvoid *source, + const struct gl_pixelstore_attrib *srcPacking ) +{ + switch (srcType) { + case GL_BYTE: + { + GLuint i; + const GLubyte *src = (const GLubyte *) source; + for (i = 0; i < n; i++) { + dest[i] = BYTE_TO_FLOAT(src[i]); + } + } + break; + case GL_UNSIGNED_BYTE: + { + GLuint i; + const GLubyte *src = (const GLubyte *) source; + for (i = 0; i < n; i++) { + dest[i] = UBYTE_TO_FLOAT(src[i]); + } + } + break; + case GL_SHORT: + { + GLuint i; + const GLshort *src = (const GLshort *) source; + for (i = 0; i < n; i++) { + dest[i] = SHORT_TO_FLOAT(src[i]); + } + } + break; + case GL_UNSIGNED_SHORT: + { + GLuint i; + const GLushort *src = (const GLushort *) source; + for (i = 0; i < n; i++) { + dest[i] = USHORT_TO_FLOAT(src[i]); + } + } + break; + case GL_INT: + { + GLuint i; + const GLint *src = (const GLint *) source; + for (i = 0; i < n; i++) { + dest[i] = INT_TO_FLOAT(src[i]); + } + } + break; + case GL_UNSIGNED_INT: + { + GLuint i; + const GLuint *src = (const GLuint *) source; + for (i = 0; i < n; i++) { + dest[i] = UINT_TO_FLOAT(src[i]); + } + } + break; + case GL_FLOAT: + MEMCPY(dest, source, n * sizeof(GLfloat)); + break; + default: + _mesa_problem(NULL, "bad type in _mesa_unpack_depth_span()"); + return; + } + + + /* apply depth scale and bias and clamp to [0,1] */ + if (ctx->Pixel.DepthScale != 1.0 || ctx->Pixel.DepthBias != 0.0) { + GLuint i; + for (i = 0; i < n; i++) { + GLfloat d = dest[i] * ctx->Pixel.DepthScale + ctx->Pixel.DepthBias; + dest[i] = CLAMP(d, 0.0F, 1.0F); + } + } +} + + + +/* + * Pack an array of depth values. The values are floats in [0,1]. + */ +void +_mesa_pack_depth_span( const GLcontext *ctx, GLuint n, GLvoid *dest, + GLenum dstType, const GLfloat *depthSpan, + const struct gl_pixelstore_attrib *dstPacking ) +{ + GLfloat depthCopy[MAX_WIDTH]; + const GLboolean bias_or_scale = ctx->Pixel.DepthBias != 0.0 || + ctx->Pixel.DepthScale != 1.0; + + ASSERT(n <= MAX_WIDTH); + + if (bias_or_scale) { + GLuint i; + for (i = 0; i < n; i++) { + GLfloat d; + d = depthSpan[i] * ctx->Pixel.DepthScale + ctx->Pixel.DepthBias; + depthCopy[i] = CLAMP(d, 0.0F, 1.0F); + } + depthSpan = depthCopy; + } + + switch (dstType) { + case GL_UNSIGNED_BYTE: + { + GLubyte *dst = (GLubyte *) dest; + GLuint i; + for (i = 0; i < n; i++) { + dst[i] = FLOAT_TO_UBYTE( depthSpan[i] ); + } + } + break; + case GL_BYTE: + { + GLbyte *dst = (GLbyte *) dest; + GLuint i; + for (i = 0; i < n; i++) { + dst[i] = FLOAT_TO_BYTE( depthSpan[i] ); + } + } + break; + case GL_UNSIGNED_SHORT: + { + GLushort *dst = (GLushort *) dest; + GLuint i; + for (i = 0; i < n; i++) { + dst[i] = FLOAT_TO_USHORT( depthSpan[i] ); + } + if (dstPacking->SwapBytes) { + _mesa_swap2( (GLushort *) dst, n ); + } + } + break; + case GL_SHORT: + { + GLshort *dst = (GLshort *) dest; + GLuint i; + for (i = 0; i < n; i++) { + dst[i] = FLOAT_TO_SHORT( depthSpan[i] ); + } + if (dstPacking->SwapBytes) { + _mesa_swap2( (GLushort *) dst, n ); + } + } + break; + case GL_UNSIGNED_INT: + { + GLuint *dst = (GLuint *) dest; + GLuint i; + for (i = 0; i < n; i++) { + dst[i] = FLOAT_TO_UINT( depthSpan[i] ); + } + if (dstPacking->SwapBytes) { + _mesa_swap4( (GLuint *) dst, n ); + } + } + break; + case GL_INT: + { + GLint *dst = (GLint *) dest; + GLuint i; + for (i = 0; i < n; i++) { + dst[i] = FLOAT_TO_INT( depthSpan[i] ); + } + if (dstPacking->SwapBytes) { + _mesa_swap4( (GLuint *) dst, n ); + } + } + break; + case GL_FLOAT: + { + GLfloat *dst = (GLfloat *) dest; + GLuint i; + for (i = 0; i < n; i++) { + dst[i] = depthSpan[i]; + } + if (dstPacking->SwapBytes) { + _mesa_swap4( (GLuint *) dst, n ); + } + } + break; + default: + _mesa_problem(ctx, "bad type in _mesa_pack_depth_span"); + } +} + + + + +/* + * Unpack image data. Apply byteswapping, byte flipping (bitmap). + * Return all image data in a contiguous block. + */ +void * +_mesa_unpack_image( GLsizei width, GLsizei height, GLsizei depth, + GLenum format, GLenum type, const GLvoid *pixels, + const struct gl_pixelstore_attrib *unpack ) +{ + GLint bytesPerRow, compsPerRow; + GLboolean flipBytes, swap2, swap4; + + if (!pixels) + return NULL; /* not necessarily an error */ + + if (width <= 0 || height <= 0 || depth <= 0) + return NULL; /* generate error later */ + + if (format == GL_BITMAP) { + bytesPerRow = (width + 7) >> 3; + flipBytes = !unpack->LsbFirst; + swap2 = swap4 = GL_FALSE; + compsPerRow = 0; + } + else { + const GLint bytesPerPixel = _mesa_bytes_per_pixel(format, type); + const GLint components = _mesa_components_in_format(format); + GLint bytesPerComp; + if (bytesPerPixel <= 0 || components <= 0) + return NULL; /* bad format or type. generate error later */ + bytesPerRow = bytesPerPixel * width; + bytesPerComp = bytesPerPixel / components; + flipBytes = GL_FALSE; + swap2 = (bytesPerComp == 2) && unpack->SwapBytes; + swap4 = (bytesPerComp == 4) && unpack->SwapBytes; + compsPerRow = components * width; + assert(compsPerRow >= width); + } + + { + GLubyte *destBuffer = (GLubyte *) MALLOC(bytesPerRow * height * depth); + GLubyte *dst; + GLint img, row; + if (!destBuffer) + return NULL; /* generate GL_OUT_OF_MEMORY later */ + + dst = destBuffer; + for (img = 0; img < depth; img++) { + for (row = 0; row < height; row++) { + const GLvoid *src = _mesa_image_address(unpack, pixels, + width, height, format, type, img, row, 0); + MEMCPY(dst, src, bytesPerRow); + /* byte flipping/swapping */ + if (flipBytes) { + flip_bytes((GLubyte *) dst, bytesPerRow); + } + else if (swap2) { + _mesa_swap2((GLushort*) dst, compsPerRow); + } + else if (swap4) { + _mesa_swap4((GLuint*) dst, compsPerRow); + } + dst += bytesPerRow; + } + } + return destBuffer; + } +} Index: dll/opengl/opengl32/mesa/image.h =================================================================== --- dll/opengl/opengl32/mesa/image.h (revision 0) +++ dll/opengl/opengl32/mesa/image.h (working copy) @@ -0,0 +1,170 @@ +/* $Id: image.h,v 1.17 2001/03/07 05:06:12 brianp Exp $ */ + +/* + * Mesa 3-D graphics library + * Version: 3.5 + * + * Copyright (C) 1999-2001 Brian Paul 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 + * BRIAN PAUL 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. + */ + + +#ifndef IMAGE_H +#define IMAGE_H + + +#include "mtypes.h" + + +extern const struct gl_pixelstore_attrib _mesa_native_packing; + + +extern void +_mesa_swap2( GLushort *p, GLuint n ); + +extern void +_mesa_swap4( GLuint *p, GLuint n ); + +extern GLint +_mesa_sizeof_type( GLenum type ); + +extern GLint +_mesa_sizeof_packed_type( GLenum type ); + +extern GLint +_mesa_components_in_format( GLenum format ); + +extern GLint +_mesa_bytes_per_pixel( GLenum format, GLenum type ); + +extern GLboolean +_mesa_is_legal_format_and_type( GLenum format, GLenum type ); + + +extern GLvoid * +_mesa_image_address( const struct gl_pixelstore_attrib *packing, + const GLvoid *image, GLsizei width, + GLsizei height, GLenum format, GLenum type, + GLint img, GLint row, GLint column ); + + +extern GLint +_mesa_image_row_stride( const struct gl_pixelstore_attrib *packing, + GLint width, GLenum format, GLenum type ); + + +extern void +_mesa_unpack_polygon_stipple( const GLubyte *pattern, GLuint dest[32], + const struct gl_pixelstore_attrib *unpacking ); + + +extern void +_mesa_pack_polygon_stipple( const GLuint pattern[32], GLubyte *dest, + const struct gl_pixelstore_attrib *packing ); + + +extern GLvoid * +_mesa_unpack_bitmap( GLint width, GLint height, const GLubyte *pixels, + const struct gl_pixelstore_attrib *packing ); + +extern void +_mesa_pack_bitmap( GLint width, GLint height, const GLubyte *source, + GLubyte *dest, const struct gl_pixelstore_attrib *packing ); + + +extern void +_mesa_pack_float_rgba_span( GLcontext *ctx, + GLuint n, CONST GLfloat rgba[][4], + GLenum dstFormat, GLenum dstType, GLvoid *dstAddr, + const struct gl_pixelstore_attrib *dstPacking, + GLuint transferOps ); + + +extern void +_mesa_pack_rgba_span( GLcontext *ctx, + GLuint n, CONST GLchan rgba[][4], + GLenum dstFormat, GLenum dstType, GLvoid *dstAddr, + const struct gl_pixelstore_attrib *dstPacking, + GLuint transferOps ); + + +extern void +_mesa_unpack_chan_color_span( GLcontext *ctx, + GLuint n, GLenum dstFormat, GLchan dest[], + GLenum srcFormat, GLenum srcType, + const GLvoid *source, + const struct gl_pixelstore_attrib *srcPacking, + GLuint transferOps ); + + +extern void +_mesa_unpack_float_color_span( GLcontext *ctx, + GLuint n, GLenum dstFormat, GLfloat dest[], + GLenum srcFormat, GLenum srcType, + const GLvoid *source, + const struct gl_pixelstore_attrib *srcPacking, + GLuint transferOps, GLboolean clamp ); + + +extern void +_mesa_unpack_index_span( const GLcontext *ctx, GLuint n, + GLenum dstType, GLvoid *dest, + GLenum srcType, const GLvoid *source, + const struct gl_pixelstore_attrib *srcPacking, + GLuint transferOps ); + + +extern void +_mesa_pack_index_span( const GLcontext *ctx, GLuint n, + GLenum dstType, GLvoid *dest, const GLuint *source, + const struct gl_pixelstore_attrib *dstPacking, + GLuint transferOps ); + + +extern void +_mesa_unpack_stencil_span( const GLcontext *ctx, GLuint n, + GLenum dstType, GLvoid *dest, + GLenum srcType, const GLvoid *source, + const struct gl_pixelstore_attrib *srcPacking, + GLuint transferOps ); + +extern void +_mesa_pack_stencil_span( const GLcontext *ctx, GLuint n, + GLenum dstType, GLvoid *dest, const GLstencil *source, + const struct gl_pixelstore_attrib *dstPacking ); + + +extern void +_mesa_unpack_depth_span( const GLcontext *ctx, GLuint n, GLfloat *dest, + GLenum srcType, const GLvoid *source, + const struct gl_pixelstore_attrib *srcPacking ); + +extern void +_mesa_pack_depth_span( const GLcontext *ctx, GLuint n, GLvoid *dest, + GLenum dstType, const GLfloat *depthSpan, + const struct gl_pixelstore_attrib *dstPacking ); + + +extern void * +_mesa_unpack_image( GLsizei width, GLsizei height, GLsizei depth, + GLenum format, GLenum type, const GLvoid *pixels, + const struct gl_pixelstore_attrib *unpack ); + + +#endif Index: dll/opengl/opengl32/mesa/imports.c =================================================================== --- dll/opengl/opengl32/mesa/imports.c (revision 0) +++ dll/opengl/opengl32/mesa/imports.c (working copy) @@ -0,0 +1,171 @@ +/* $Id: imports.c,v 1.9 2001/03/27 19:18:02 gareth Exp $ */ + +/* + * Mesa 3-D graphics library + * Version: 3.5 + * + * Copyright (C) 1999-2001 Brian Paul 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 + * BRIAN PAUL 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. + */ + + +/* + * Imports are functions which the device driver or window system or + * operating system provides to the core renderer. The core renderer (Mesa) + * will call these functions in order to do memory allocation, simple I/O, + * etc. + * + * Some drivers will need to implement these functions themselves but + * many (most?) Mesa drivers will be fine using these. + * + * A server-side GL renderer will likely not use these functions since + * the renderer should use the XFree86-wrapped system calls. + */ + + +#include "glheader.h" +#include "imports.h" +#include "mem.h" +#include "mtypes.h" + + +static void * +_mesa_Malloc(__GLcontext *gc, size_t size) +{ + return MALLOC(size); +} + +static void * +_mesa_Calloc(__GLcontext *gc, size_t numElem, size_t elemSize) +{ + return CALLOC(numElem * elemSize); +} + +static void * +_mesa_Realloc(__GLcontext *gc, void *oldAddr, size_t newSize) +{ + return realloc(oldAddr, newSize); +} + +static void +_mesa_Free(__GLcontext *gc, void *addr) +{ + FREE(addr); +} + +/* Must be before '#undef getenv' for inclusion in XFree86. + */ +static char * +_mesa_getenv(__GLcontext *gc, const char *var) +{ + (void) gc; + return getenv(var); +} + +static void +_mesa_warning(__GLcontext *gc, char *str) +{ + GLboolean debug; +#ifdef DEBUG + debug = GL_TRUE; +#else +/* Whacko XFree86 macro: + */ +#ifdef getenv +#undef getenv +#endif + if (gc->imports.getenv(gc, "MESA_DEBUG")) { + debug = GL_TRUE; + } + else { + debug = GL_FALSE; + } +#endif + if (debug) { + fprintf(stderr, "Mesa warning: %s\n", str); + } +} + +static void +_mesa_fatal(__GLcontext *gc, char *str) +{ + fprintf(stderr, "%s\n", str); + abort(); +} + +static int +_mesa_atoi(__GLcontext *gc, const char *str) +{ + (void) gc; + return atoi(str); +} + +static int +_mesa_sprintf(__GLcontext *gc, char *str, const char *fmt, ...) +{ + /* XXX fix this */ + return sprintf(str, fmt); +} + +static void * +_mesa_fopen(__GLcontext *gc, const char *path, const char *mode) +{ + return fopen(path, mode); +} + +static int +_mesa_fclose(__GLcontext *gc, void *stream) +{ + return fclose((FILE *) stream); +} + +static int +_mesa_fprintf(__GLcontext *gc, void *stream, const char *fmt, ...) +{ + /* XXX fix this */ + return fprintf((FILE *) stream, fmt); +} + +/* XXX this really is driver-specific and can't be here */ +static __GLdrawablePrivate * +_mesa_GetDrawablePrivate(__GLcontext *gc) +{ + return NULL; +} + + +void +_mesa_InitDefaultImports(__GLimports *imports, void *driverCtx, void *other) +{ + imports->malloc = _mesa_Malloc; + imports->calloc = _mesa_Calloc; + imports->realloc = _mesa_Realloc; + imports->free = _mesa_Free; + imports->warning = _mesa_warning; + imports->fatal = _mesa_fatal; + imports->getenv = _mesa_getenv; + imports->atoi = _mesa_atoi; + imports->sprintf = _mesa_sprintf; + imports->fopen = _mesa_fopen; + imports->fclose = _mesa_fclose; + imports->fprintf = _mesa_fprintf; + imports->getDrawablePrivate = _mesa_GetDrawablePrivate; +/* imports->wscx = driverCtx; */ + imports->other = driverCtx; +} Index: dll/opengl/opengl32/mesa/imports.h =================================================================== --- dll/opengl/opengl32/mesa/imports.h (revision 0) +++ dll/opengl/opengl32/mesa/imports.h (working copy) @@ -0,0 +1,39 @@ +/* $Id: imports.h,v 1.2 2001/03/12 00:48:38 gareth Exp $ */ + +/* + * Mesa 3-D graphics library + * Version: 3.5 + * + * Copyright (C) 1999-2001 Brian Paul 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 + * BRIAN PAUL 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. + */ + + +#ifndef IMPORTS_H +#define IMPORTS_H + + +#include "glheader.h" + + +extern void +_mesa_InitDefaultImports(__GLimports *imports, void *driverCtx, void *other); + + +#endif Index: dll/opengl/opengl32/mesa/light.c =================================================================== --- dll/opengl/opengl32/mesa/light.c (revision 0) +++ dll/opengl/opengl32/mesa/light.c (working copy) @@ -0,0 +1,1319 @@ +/* $Id: light.c,v 1.44 2001/05/09 12:24:51 keithw Exp $ */ + +/* + * Mesa 3-D graphics library + * Version: 3.5 + * + * Copyright (C) 1999-2001 Brian Paul 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 + * BRIAN PAUL 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. + */ + + +#ifdef PC_HEADER +#include "all.h" +#else +#include "glheader.h" +#include "colormac.h" +#include "context.h" +#include "enums.h" +#include "light.h" +#include "macros.h" +#include "mem.h" +#include "mmath.h" +#include "simple_list.h" +#include "mtypes.h" + +#include "math/m_xform.h" +#include "math/m_matrix.h" +#endif + + +/* XXX this is a bit of a hack needed for compilation within XFree86 */ +#ifndef FLT_MIN +#define FLT_MIN 1e-37 +#endif + + +void +_mesa_ShadeModel( GLenum mode ) +{ + GET_CURRENT_CONTEXT(ctx); + ASSERT_OUTSIDE_BEGIN_END(ctx); + + if (MESA_VERBOSE & VERBOSE_API) + fprintf(stderr, "glShadeModel %s\n", _mesa_lookup_enum_by_nr(mode)); + + if (mode != GL_FLAT && mode != GL_SMOOTH) { + _mesa_error( ctx, GL_INVALID_ENUM, "glShadeModel" ); + return; + } + + if (ctx->Light.ShadeModel == mode) + return; + + FLUSH_VERTICES(ctx, _NEW_LIGHT); + ctx->Light.ShadeModel = mode; + ctx->_TriangleCaps ^= DD_FLATSHADE; + if (ctx->Driver.ShadeModel) + (*ctx->Driver.ShadeModel)( ctx, mode ); +} + + + +void +_mesa_Lightf( GLenum light, GLenum pname, GLfloat param ) +{ + _mesa_Lightfv( light, pname, ¶m ); +} + + +void +_mesa_Lightfv( GLenum light, GLenum pname, const GLfloat *params ) +{ + GET_CURRENT_CONTEXT(ctx); + GLint i = (GLint) (light - GL_LIGHT0); + struct gl_light *l = &ctx->Light.Light[i]; + + if (i < 0 || i >= (GLint) ctx->Const.MaxLights) { + _mesa_error( ctx, GL_INVALID_ENUM, "glLight" ); + return; + } + + switch (pname) { + case GL_AMBIENT: + if (TEST_EQ_4V(l->Ambient, params)) + return; + FLUSH_VERTICES(ctx, _NEW_LIGHT); + COPY_4V( l->Ambient, params ); + break; + case GL_DIFFUSE: + if (TEST_EQ_4V(l->Diffuse, params)) + return; + FLUSH_VERTICES(ctx, _NEW_LIGHT); + COPY_4V( l->Diffuse, params ); + break; + case GL_SPECULAR: + if (TEST_EQ_4V(l->Specular, params)) + return; + FLUSH_VERTICES(ctx, _NEW_LIGHT); + COPY_4V( l->Specular, params ); + break; + case GL_POSITION: { + GLfloat tmp[4]; + /* transform position by ModelView matrix */ + TRANSFORM_POINT( tmp, ctx->ModelView.m, params ); + if (TEST_EQ_4V(l->EyePosition, tmp)) + return; + FLUSH_VERTICES(ctx, _NEW_LIGHT); + COPY_4V(l->EyePosition, tmp); + if (l->EyePosition[3] != 0.0F) + l->_Flags |= LIGHT_POSITIONAL; + else + l->_Flags &= ~LIGHT_POSITIONAL; + break; + } + case GL_SPOT_DIRECTION: { + GLfloat tmp[4]; + /* transform direction by inverse modelview */ + if (ctx->ModelView.flags & MAT_DIRTY_INVERSE) { + _math_matrix_analyse( &ctx->ModelView ); + } + TRANSFORM_NORMAL( tmp, params, ctx->ModelView.inv ); + if (TEST_EQ_3V(l->EyeDirection, tmp)) + return; + FLUSH_VERTICES(ctx, _NEW_LIGHT); + COPY_3V(l->EyeDirection, tmp); + break; + } + case GL_SPOT_EXPONENT: + if (params[0]<0.0 || params[0]>128.0) { + _mesa_error( ctx, GL_INVALID_VALUE, "glLight" ); + return; + } + if (l->SpotExponent == params[0]) + return; + FLUSH_VERTICES(ctx, _NEW_LIGHT); + l->SpotExponent = params[0]; + _mesa_invalidate_spot_exp_table( l ); + break; + case GL_SPOT_CUTOFF: + if ((params[0]<0.0 || params[0]>90.0) && params[0]!=180.0) { + _mesa_error( ctx, GL_INVALID_VALUE, "glLight" ); + return; + } + if (l->SpotCutoff == params[0]) + return; + FLUSH_VERTICES(ctx, _NEW_LIGHT); + l->SpotCutoff = params[0]; + l->_CosCutoff = cos(params[0]*DEG2RAD); + if (l->_CosCutoff < 0) + l->_CosCutoff = 0; + if (l->SpotCutoff != 180.0F) + l->_Flags |= LIGHT_SPOT; + else + l->_Flags &= ~LIGHT_SPOT; + break; + case GL_CONSTANT_ATTENUATION: + if (params[0]<0.0) { + _mesa_error( ctx, GL_INVALID_VALUE, "glLight" ); + return; + } + if (l->ConstantAttenuation == params[0]) + return; + FLUSH_VERTICES(ctx, _NEW_LIGHT); + l->ConstantAttenuation = params[0]; + break; + case GL_LINEAR_ATTENUATION: + if (params[0]<0.0) { + _mesa_error( ctx, GL_INVALID_VALUE, "glLight" ); + return; + } + if (l->LinearAttenuation == params[0]) + return; + FLUSH_VERTICES(ctx, _NEW_LIGHT); + l->LinearAttenuation = params[0]; + break; + case GL_QUADRATIC_ATTENUATION: + if (params[0]<0.0) { + _mesa_error( ctx, GL_INVALID_VALUE, "glLight" ); + return; + } + if (l->QuadraticAttenuation == params[0]) + return; + FLUSH_VERTICES(ctx, _NEW_LIGHT); + l->QuadraticAttenuation = params[0]; + break; + default: + _mesa_error( ctx, GL_INVALID_ENUM, "glLight" ); + return; + } + + if (ctx->Driver.Lightfv) + ctx->Driver.Lightfv( ctx, light, pname, params ); +} + + +void +_mesa_Lighti( GLenum light, GLenum pname, GLint param ) +{ + _mesa_Lightiv( light, pname, ¶m ); +} + + +void +_mesa_Lightiv( GLenum light, GLenum pname, const GLint *params ) +{ + GLfloat fparam[4]; + + switch (pname) { + case GL_AMBIENT: + case GL_DIFFUSE: + case GL_SPECULAR: + fparam[0] = INT_TO_FLOAT( params[0] ); + fparam[1] = INT_TO_FLOAT( params[1] ); + fparam[2] = INT_TO_FLOAT( params[2] ); + fparam[3] = INT_TO_FLOAT( params[3] ); + break; + case GL_POSITION: + fparam[0] = (GLfloat) params[0]; + fparam[1] = (GLfloat) params[1]; + fparam[2] = (GLfloat) params[2]; + fparam[3] = (GLfloat) params[3]; + break; + case GL_SPOT_DIRECTION: + fparam[0] = (GLfloat) params[0]; + fparam[1] = (GLfloat) params[1]; + fparam[2] = (GLfloat) params[2]; + break; + case GL_SPOT_EXPONENT: + case GL_SPOT_CUTOFF: + case GL_CONSTANT_ATTENUATION: + case GL_LINEAR_ATTENUATION: + case GL_QUADRATIC_ATTENUATION: + fparam[0] = (GLfloat) params[0]; + break; + default: + /* error will be caught later in gl_Lightfv */ + ; + } + + _mesa_Lightfv( light, pname, fparam ); +} + + + +void +_mesa_GetLightfv( GLenum light, GLenum pname, GLfloat *params ) +{ + GET_CURRENT_CONTEXT(ctx); + GLint l = (GLint) (light - GL_LIGHT0); + ASSERT_OUTSIDE_BEGIN_END(ctx); + + if (l < 0 || l >= (GLint) ctx->Const.MaxLights) { + _mesa_error( ctx, GL_INVALID_ENUM, "glGetLightfv" ); + return; + } + + switch (pname) { + case GL_AMBIENT: + COPY_4V( params, ctx->Light.Light[l].Ambient ); + break; + case GL_DIFFUSE: + COPY_4V( params, ctx->Light.Light[l].Diffuse ); + break; + case GL_SPECULAR: + COPY_4V( params, ctx->Light.Light[l].Specular ); + break; + case GL_POSITION: + COPY_4V( params, ctx->Light.Light[l].EyePosition ); + break; + case GL_SPOT_DIRECTION: + COPY_3V( params, ctx->Light.Light[l].EyeDirection ); + break; + case GL_SPOT_EXPONENT: + params[0] = ctx->Light.Light[l].SpotExponent; + break; + case GL_SPOT_CUTOFF: + params[0] = ctx->Light.Light[l].SpotCutoff; + break; + case GL_CONSTANT_ATTENUATION: + params[0] = ctx->Light.Light[l].ConstantAttenuation; + break; + case GL_LINEAR_ATTENUATION: + params[0] = ctx->Light.Light[l].LinearAttenuation; + break; + case GL_QUADRATIC_ATTENUATION: + params[0] = ctx->Light.Light[l].QuadraticAttenuation; + break; + default: + _mesa_error( ctx, GL_INVALID_ENUM, "glGetLightfv" ); + break; + } +} + + + +void +_mesa_GetLightiv( GLenum light, GLenum pname, GLint *params ) +{ + GET_CURRENT_CONTEXT(ctx); + GLint l = (GLint) (light - GL_LIGHT0); + ASSERT_OUTSIDE_BEGIN_END(ctx); + + if (l < 0 || l >= (GLint) ctx->Const.MaxLights) { + _mesa_error( ctx, GL_INVALID_ENUM, "glGetLightiv" ); + return; + } + + switch (pname) { + case GL_AMBIENT: + params[0] = FLOAT_TO_INT(ctx->Light.Light[l].Ambient[0]); + params[1] = FLOAT_TO_INT(ctx->Light.Light[l].Ambient[1]); + params[2] = FLOAT_TO_INT(ctx->Light.Light[l].Ambient[2]); + params[3] = FLOAT_TO_INT(ctx->Light.Light[l].Ambient[3]); + break; + case GL_DIFFUSE: + params[0] = FLOAT_TO_INT(ctx->Light.Light[l].Diffuse[0]); + params[1] = FLOAT_TO_INT(ctx->Light.Light[l].Diffuse[1]); + params[2] = FLOAT_TO_INT(ctx->Light.Light[l].Diffuse[2]); + params[3] = FLOAT_TO_INT(ctx->Light.Light[l].Diffuse[3]); + break; + case GL_SPECULAR: + params[0] = FLOAT_TO_INT(ctx->Light.Light[l].Specular[0]); + params[1] = FLOAT_TO_INT(ctx->Light.Light[l].Specular[1]); + params[2] = FLOAT_TO_INT(ctx->Light.Light[l].Specular[2]); + params[3] = FLOAT_TO_INT(ctx->Light.Light[l].Specular[3]); + break; + case GL_POSITION: + params[0] = (GLint) ctx->Light.Light[l].EyePosition[0]; + params[1] = (GLint) ctx->Light.Light[l].EyePosition[1]; + params[2] = (GLint) ctx->Light.Light[l].EyePosition[2]; + params[3] = (GLint) ctx->Light.Light[l].EyePosition[3]; + break; + case GL_SPOT_DIRECTION: + params[0] = (GLint) ctx->Light.Light[l].EyeDirection[0]; + params[1] = (GLint) ctx->Light.Light[l].EyeDirection[1]; + params[2] = (GLint) ctx->Light.Light[l].EyeDirection[2]; + break; + case GL_SPOT_EXPONENT: + params[0] = (GLint) ctx->Light.Light[l].SpotExponent; + break; + case GL_SPOT_CUTOFF: + params[0] = (GLint) ctx->Light.Light[l].SpotCutoff; + break; + case GL_CONSTANT_ATTENUATION: + params[0] = (GLint) ctx->Light.Light[l].ConstantAttenuation; + break; + case GL_LINEAR_ATTENUATION: + params[0] = (GLint) ctx->Light.Light[l].LinearAttenuation; + break; + case GL_QUADRATIC_ATTENUATION: + params[0] = (GLint) ctx->Light.Light[l].QuadraticAttenuation; + break; + default: + _mesa_error( ctx, GL_INVALID_ENUM, "glGetLightiv" ); + break; + } +} + + + +/**********************************************************************/ +/*** Light Model ***/ +/**********************************************************************/ + + +void +_mesa_LightModelfv( GLenum pname, const GLfloat *params ) +{ + GLenum newenum; + GLboolean newbool; + GET_CURRENT_CONTEXT(ctx); + ASSERT_OUTSIDE_BEGIN_END(ctx); + + switch (pname) { + case GL_LIGHT_MODEL_AMBIENT: + if (TEST_EQ_4V( ctx->Light.Model.Ambient, params )) + return; + FLUSH_VERTICES(ctx, _NEW_LIGHT); + COPY_4V( ctx->Light.Model.Ambient, params ); + break; + case GL_LIGHT_MODEL_LOCAL_VIEWER: + newbool = (params[0]!=0.0); + if (ctx->Light.Model.LocalViewer == newbool) + return; + FLUSH_VERTICES(ctx, _NEW_LIGHT); + ctx->Light.Model.LocalViewer = newbool; + break; + case GL_LIGHT_MODEL_TWO_SIDE: + newbool = (params[0]!=0.0); + if (ctx->Light.Model.TwoSide == newbool) + return; + FLUSH_VERTICES(ctx, _NEW_LIGHT); + ctx->Light.Model.TwoSide = newbool; + break; + case GL_LIGHT_MODEL_COLOR_CONTROL: + if (params[0] == (GLfloat) GL_SINGLE_COLOR) + newenum = GL_SINGLE_COLOR; + else if (params[0] == (GLfloat) GL_SEPARATE_SPECULAR_COLOR) + newenum = GL_SEPARATE_SPECULAR_COLOR; + else { + _mesa_error( ctx, GL_INVALID_ENUM, "glLightModel(param)" ); + return; + } + if (ctx->Light.Model.ColorControl == newenum) + return; + FLUSH_VERTICES(ctx, _NEW_LIGHT); + ctx->Light.Model.ColorControl = newenum; + + if ((ctx->Light.Enabled && + ctx->Light.Model.ColorControl==GL_SEPARATE_SPECULAR_COLOR) + || ctx->Fog.ColorSumEnabled) + ctx->_TriangleCaps |= DD_SEPARATE_SPECULAR; + else + ctx->_TriangleCaps &= ~DD_SEPARATE_SPECULAR; + + break; + default: + _mesa_error( ctx, GL_INVALID_ENUM, "glLightModel" ); + break; + } + + if (ctx->Driver.LightModelfv) + ctx->Driver.LightModelfv( ctx, pname, params ); +} + + +void +_mesa_LightModeliv( GLenum pname, const GLint *params ) +{ + GLfloat fparam[4]; + + switch (pname) { + case GL_LIGHT_MODEL_AMBIENT: + fparam[0] = INT_TO_FLOAT( params[0] ); + fparam[1] = INT_TO_FLOAT( params[1] ); + fparam[2] = INT_TO_FLOAT( params[2] ); + fparam[3] = INT_TO_FLOAT( params[3] ); + break; + case GL_LIGHT_MODEL_LOCAL_VIEWER: + case GL_LIGHT_MODEL_TWO_SIDE: + case GL_LIGHT_MODEL_COLOR_CONTROL: + fparam[0] = (GLfloat) params[0]; + break; + default: + /* Error will be caught later in gl_LightModelfv */ + ; + } + _mesa_LightModelfv( pname, fparam ); +} + + +void +_mesa_LightModeli( GLenum pname, GLint param ) +{ + _mesa_LightModeliv( pname, ¶m ); +} + + +void +_mesa_LightModelf( GLenum pname, GLfloat param ) +{ + _mesa_LightModelfv( pname, ¶m ); +} + + + +/********** MATERIAL **********/ + + +/* + * Given a face and pname value (ala glColorMaterial), compute a bitmask + * of the targeted material values. + */ +GLuint +_mesa_material_bitmask( GLcontext *ctx, GLenum face, GLenum pname, + GLuint legal, const char *where ) +{ + GLuint bitmask = 0; + + /* Make a bitmask indicating what material attribute(s) we're updating */ + switch (pname) { + case GL_EMISSION: + bitmask |= FRONT_EMISSION_BIT | BACK_EMISSION_BIT; + break; + case GL_AMBIENT: + bitmask |= FRONT_AMBIENT_BIT | BACK_AMBIENT_BIT; + break; + case GL_DIFFUSE: + bitmask |= FRONT_DIFFUSE_BIT | BACK_DIFFUSE_BIT; + break; + case GL_SPECULAR: + bitmask |= FRONT_SPECULAR_BIT | BACK_SPECULAR_BIT; + break; + case GL_SHININESS: + bitmask |= FRONT_SHININESS_BIT | BACK_SHININESS_BIT; + break; + case GL_AMBIENT_AND_DIFFUSE: + bitmask |= FRONT_AMBIENT_BIT | BACK_AMBIENT_BIT; + bitmask |= FRONT_DIFFUSE_BIT | BACK_DIFFUSE_BIT; + break; + case GL_COLOR_INDEXES: + bitmask |= FRONT_INDEXES_BIT | BACK_INDEXES_BIT; + break; + default: + _mesa_error( ctx, GL_INVALID_ENUM, where ); + return 0; + } + + if (face==GL_FRONT) { + bitmask &= FRONT_MATERIAL_BITS; + } + else if (face==GL_BACK) { + bitmask &= BACK_MATERIAL_BITS; + } + else if (face != GL_FRONT_AND_BACK) { + _mesa_error( ctx, GL_INVALID_ENUM, where ); + return 0; + } + + if (bitmask & ~legal) { + _mesa_error( ctx, GL_INVALID_ENUM, where ); + return 0; + } + + return bitmask; +} + + +/* Perform a straight copy between pairs of materials. + */ +void _mesa_copy_material_pairs( struct gl_material dst[2], + const struct gl_material src[2], + GLuint bitmask ) +{ + if (bitmask & FRONT_EMISSION_BIT) { + COPY_4FV( dst[0].Emission, src[0].Emission ); + } + if (bitmask & BACK_EMISSION_BIT) { + COPY_4FV( dst[1].Emission, src[1].Emission ); + } + if (bitmask & FRONT_AMBIENT_BIT) { + COPY_4FV( dst[0].Ambient, src[0].Ambient ); + } + if (bitmask & BACK_AMBIENT_BIT) { + COPY_4FV( dst[1].Ambient, src[1].Ambient ); + } + if (bitmask & FRONT_DIFFUSE_BIT) { + COPY_4FV( dst[0].Diffuse, src[0].Diffuse ); + } + if (bitmask & BACK_DIFFUSE_BIT) { + COPY_4FV( dst[1].Diffuse, src[1].Diffuse ); + } + if (bitmask & FRONT_SPECULAR_BIT) { + COPY_4FV( dst[0].Specular, src[0].Specular ); + } + if (bitmask & BACK_SPECULAR_BIT) { + COPY_4FV( dst[1].Specular, src[1].Specular ); + } + if (bitmask & FRONT_SHININESS_BIT) { + dst[0].Shininess = src[0].Shininess; + } + if (bitmask & BACK_SHININESS_BIT) { + dst[1].Shininess = src[1].Shininess; + } + if (bitmask & FRONT_INDEXES_BIT) { + dst[0].AmbientIndex = src[0].AmbientIndex; + dst[0].DiffuseIndex = src[0].DiffuseIndex; + dst[0].SpecularIndex = src[0].SpecularIndex; + } + if (bitmask & BACK_INDEXES_BIT) { + dst[1].AmbientIndex = src[1].AmbientIndex; + dst[1].DiffuseIndex = src[1].DiffuseIndex; + dst[1].SpecularIndex = src[1].SpecularIndex; + } +} + + +/* + * Check if the global material has to be updated with info that was + * associated with a vertex via glMaterial. + * This function is used when any material values get changed between + * glBegin/glEnd either by calling glMaterial() or by calling glColor() + * when GL_COLOR_MATERIAL is enabled. + * + * src[0] is front material, src[1] is back material + * + * Additionally keeps the precomputed lighting state uptodate. + */ +void _mesa_update_material( GLcontext *ctx, + const struct gl_material src[2], + GLuint bitmask ) +{ + struct gl_light *light, *list = &ctx->Light.EnabledList; + + if (ctx->Light.ColorMaterialEnabled) + bitmask &= ~ctx->Light.ColorMaterialBitmask; + + if (MESA_VERBOSE&VERBOSE_IMMEDIATE) + fprintf(stderr, "_mesa_update_material, mask 0x%x\n", bitmask); + + if (!bitmask) + return; + + /* update material emission */ + if (bitmask & FRONT_EMISSION_BIT) { + struct gl_material *mat = &ctx->Light.Material[0]; + COPY_4FV( mat->Emission, src[0].Emission ); + } + if (bitmask & BACK_EMISSION_BIT) { + struct gl_material *mat = &ctx->Light.Material[1]; + COPY_4FV( mat->Emission, src[1].Emission ); + } + + /* update material ambience */ + if (bitmask & FRONT_AMBIENT_BIT) { + struct gl_material *mat = &ctx->Light.Material[0]; + COPY_4FV( mat->Ambient, src[0].Ambient ); + foreach (light, list) { + SCALE_3V( light->_MatAmbient[0], light->Ambient, src[0].Ambient); + } + } + if (bitmask & BACK_AMBIENT_BIT) { + struct gl_material *mat = &ctx->Light.Material[1]; + COPY_4FV( mat->Ambient, src[1].Ambient ); + foreach (light, list) { + SCALE_3V( light->_MatAmbient[1], light->Ambient, src[1].Ambient); + } + } + + /* update BaseColor = emission + scene's ambience * material's ambience */ + if (bitmask & (FRONT_EMISSION_BIT | FRONT_AMBIENT_BIT)) { + struct gl_material *mat = &ctx->Light.Material[0]; + COPY_3V( ctx->Light._BaseColor[0], mat->Emission ); + ACC_SCALE_3V( ctx->Light._BaseColor[0], mat->Ambient, + ctx->Light.Model.Ambient ); + } + if (bitmask & (BACK_EMISSION_BIT | BACK_AMBIENT_BIT)) { + struct gl_material *mat = &ctx->Light.Material[1]; + COPY_3V( ctx->Light._BaseColor[1], mat->Emission ); + ACC_SCALE_3V( ctx->Light._BaseColor[1], mat->Ambient, + ctx->Light.Model.Ambient ); + } + + /* update material diffuse values */ + if (bitmask & FRONT_DIFFUSE_BIT) { + struct gl_material *mat = &ctx->Light.Material[0]; + COPY_4FV( mat->Diffuse, src[0].Diffuse ); + foreach (light, list) { + SCALE_3V( light->_MatDiffuse[0], light->Diffuse, mat->Diffuse ); + } + ctx->Light._BaseAlpha[0] = CLAMP( mat->Diffuse[3], 0.0, 1.0 ); + } + if (bitmask & BACK_DIFFUSE_BIT) { + struct gl_material *mat = &ctx->Light.Material[1]; + COPY_4FV( mat->Diffuse, src[1].Diffuse ); + foreach (light, list) { + SCALE_3V( light->_MatDiffuse[1], light->Diffuse, mat->Diffuse ); + } + ctx->Light._BaseAlpha[1] = CLAMP( mat->Diffuse[3], 0.0, 1.0 ); + } + + /* update material specular values */ + if (bitmask & FRONT_SPECULAR_BIT) { + struct gl_material *mat = &ctx->Light.Material[0]; + COPY_4FV( mat->Specular, src[0].Specular ); + foreach (light, list) { + SCALE_3V( light->_MatSpecular[0], light->Specular, mat->Specular); + } + } + if (bitmask & BACK_SPECULAR_BIT) { + struct gl_material *mat = &ctx->Light.Material[1]; + COPY_4FV( mat->Specular, src[1].Specular ); + foreach (light, list) { + SCALE_3V( light->_MatSpecular[1], light->Specular, mat->Specular); + } + } + + if (bitmask & FRONT_SHININESS_BIT) { + ctx->Light.Material[0].Shininess = src[0].Shininess; + _mesa_invalidate_shine_table( ctx, 0 ); + } + if (bitmask & BACK_SHININESS_BIT) { + ctx->Light.Material[1].Shininess = src[1].Shininess; + _mesa_invalidate_shine_table( ctx, 1 ); + } + + if (bitmask & FRONT_INDEXES_BIT) { + ctx->Light.Material[0].AmbientIndex = src[0].AmbientIndex; + ctx->Light.Material[0].DiffuseIndex = src[0].DiffuseIndex; + ctx->Light.Material[0].SpecularIndex = src[0].SpecularIndex; + } + if (bitmask & BACK_INDEXES_BIT) { + ctx->Light.Material[1].AmbientIndex = src[1].AmbientIndex; + ctx->Light.Material[1].DiffuseIndex = src[1].DiffuseIndex; + ctx->Light.Material[1].SpecularIndex = src[1].SpecularIndex; + } + + if (0) + { + struct gl_material *mat = &ctx->Light.Material[0]; + fprintf(stderr, "update_mat emission : %f %f %f\n", + mat->Emission[0], + mat->Emission[1], + mat->Emission[2]); + fprintf(stderr, "update_mat specular : %f %f %f\n", + mat->Specular[0], + mat->Specular[1], + mat->Specular[2]); + fprintf(stderr, "update_mat diffuse : %f %f %f\n", + mat->Diffuse[0], + mat->Diffuse[1], + mat->Diffuse[2]); + fprintf(stderr, "update_mat ambient : %f %f %f\n", + mat->Ambient[0], + mat->Ambient[1], + mat->Ambient[2]); + } +} + + + + + + + +/* + * Update the current materials from the given rgba color + * according to the bitmask in ColorMaterialBitmask, which is + * set by glColorMaterial(). + */ +void _mesa_update_color_material( GLcontext *ctx, + const GLfloat color[4] ) +{ + struct gl_light *light, *list = &ctx->Light.EnabledList; + GLuint bitmask = ctx->Light.ColorMaterialBitmask; + + if (MESA_VERBOSE&VERBOSE_IMMEDIATE) + fprintf(stderr, "_mesa_update_color_material, mask 0x%x\n", bitmask); + + /* update emissive colors */ + if (bitmask & FRONT_EMISSION_BIT) { + struct gl_material *mat = &ctx->Light.Material[0]; + COPY_4FV( mat->Emission, color ); + } + + if (bitmask & BACK_EMISSION_BIT) { + struct gl_material *mat = &ctx->Light.Material[1]; + COPY_4FV( mat->Emission, color ); + } + + /* update light->_MatAmbient = light's ambient * material's ambient */ + if (bitmask & FRONT_AMBIENT_BIT) { + struct gl_material *mat = &ctx->Light.Material[0]; + foreach (light, list) { + SCALE_3V( light->_MatAmbient[0], light->Ambient, color); + } + COPY_4FV( mat->Ambient, color ); + } + + if (bitmask & BACK_AMBIENT_BIT) { + struct gl_material *mat = &ctx->Light.Material[1]; + foreach (light, list) { + SCALE_3V( light->_MatAmbient[1], light->Ambient, color); + } + COPY_4FV( mat->Ambient, color ); + } + + /* update BaseColor = emission + scene's ambience * material's ambience */ + if (bitmask & (FRONT_EMISSION_BIT | FRONT_AMBIENT_BIT)) { + struct gl_material *mat = &ctx->Light.Material[0]; + COPY_3V( ctx->Light._BaseColor[0], mat->Emission ); + ACC_SCALE_3V( ctx->Light._BaseColor[0], mat->Ambient, ctx->Light.Model.Ambient ); + } + + if (bitmask & (BACK_EMISSION_BIT | BACK_AMBIENT_BIT)) { + struct gl_material *mat = &ctx->Light.Material[1]; + COPY_3V( ctx->Light._BaseColor[1], mat->Emission ); + ACC_SCALE_3V( ctx->Light._BaseColor[1], mat->Ambient, ctx->Light.Model.Ambient ); + } + + /* update light->_MatDiffuse = light's diffuse * material's diffuse */ + if (bitmask & FRONT_DIFFUSE_BIT) { + struct gl_material *mat = &ctx->Light.Material[0]; + COPY_4FV( mat->Diffuse, color ); + foreach (light, list) { + SCALE_3V( light->_MatDiffuse[0], light->Diffuse, mat->Diffuse ); + } + ctx->Light._BaseAlpha[0] = CLAMP( mat->Diffuse[3], 0.0, 1.0 ); + } + + if (bitmask & BACK_DIFFUSE_BIT) { + struct gl_material *mat = &ctx->Light.Material[1]; + COPY_4FV( mat->Diffuse, color ); + foreach (light, list) { + SCALE_3V( light->_MatDiffuse[1], light->Diffuse, mat->Diffuse ); + } + ctx->Light._BaseAlpha[1] = CLAMP( mat->Diffuse[3], 0.0, 1.0 ); + } + + /* update light->_MatSpecular = light's specular * material's specular */ + if (bitmask & FRONT_SPECULAR_BIT) { + struct gl_material *mat = &ctx->Light.Material[0]; + COPY_4FV( mat->Specular, color ); + foreach (light, list) { + ACC_SCALE_3V( light->_MatSpecular[0], light->Specular, mat->Specular); + } + } + + if (bitmask & BACK_SPECULAR_BIT) { + struct gl_material *mat = &ctx->Light.Material[1]; + COPY_4FV( mat->Specular, color ); + foreach (light, list) { + ACC_SCALE_3V( light->_MatSpecular[1], light->Specular, mat->Specular); + } + } + + if (0) + { + struct gl_material *mat = &ctx->Light.Material[0]; + fprintf(stderr, "update_color_mat emission : %f %f %f\n", + mat->Emission[0], + mat->Emission[1], + mat->Emission[2]); + fprintf(stderr, "update_color_mat specular : %f %f %f\n", + mat->Specular[0], + mat->Specular[1], + mat->Specular[2]); + fprintf(stderr, "update_color_mat diffuse : %f %f %f\n", + mat->Diffuse[0], + mat->Diffuse[1], + mat->Diffuse[2]); + fprintf(stderr, "update_color_mat ambient : %f %f %f\n", + mat->Ambient[0], + mat->Ambient[1], + mat->Ambient[2]); + } +} + + + + +void +_mesa_ColorMaterial( GLenum face, GLenum mode ) +{ + GET_CURRENT_CONTEXT(ctx); + GLuint bitmask; + GLuint legal = (FRONT_EMISSION_BIT | BACK_EMISSION_BIT | + FRONT_SPECULAR_BIT | BACK_SPECULAR_BIT | + FRONT_DIFFUSE_BIT | BACK_DIFFUSE_BIT | + FRONT_AMBIENT_BIT | BACK_AMBIENT_BIT); + ASSERT_OUTSIDE_BEGIN_END(ctx); + + if (MESA_VERBOSE&VERBOSE_API) + fprintf(stderr, "glColorMaterial %s %s\n", + _mesa_lookup_enum_by_nr(face), + _mesa_lookup_enum_by_nr(mode)); + + bitmask = _mesa_material_bitmask(ctx, face, mode, legal, "glColorMaterial"); + + if (ctx->Light.ColorMaterialBitmask == bitmask && + ctx->Light.ColorMaterialFace == face && + ctx->Light.ColorMaterialMode == mode) + return; + + FLUSH_VERTICES(ctx, _NEW_LIGHT); + ctx->Light.ColorMaterialBitmask = bitmask; + ctx->Light.ColorMaterialFace = face; + ctx->Light.ColorMaterialMode = mode; + + if (ctx->Light.ColorMaterialEnabled) { + FLUSH_CURRENT( ctx, 0 ); + _mesa_update_color_material( ctx, ctx->Current.Color ); + } +} + + + + + +void +_mesa_GetMaterialfv( GLenum face, GLenum pname, GLfloat *params ) +{ + GET_CURRENT_CONTEXT(ctx); + GLuint f; + ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx); /* update materials */ + + if (face==GL_FRONT) { + f = 0; + } + else if (face==GL_BACK) { + f = 1; + } + else { + _mesa_error( ctx, GL_INVALID_ENUM, "glGetMaterialfv(face)" ); + return; + } + switch (pname) { + case GL_AMBIENT: + COPY_4FV( params, ctx->Light.Material[f].Ambient ); + break; + case GL_DIFFUSE: + COPY_4FV( params, ctx->Light.Material[f].Diffuse ); + break; + case GL_SPECULAR: + COPY_4FV( params, ctx->Light.Material[f].Specular ); + break; + case GL_EMISSION: + COPY_4FV( params, ctx->Light.Material[f].Emission ); + break; + case GL_SHININESS: + *params = ctx->Light.Material[f].Shininess; + break; + case GL_COLOR_INDEXES: + params[0] = ctx->Light.Material[f].AmbientIndex; + params[1] = ctx->Light.Material[f].DiffuseIndex; + params[2] = ctx->Light.Material[f].SpecularIndex; + break; + default: + _mesa_error( ctx, GL_INVALID_ENUM, "glGetMaterialfv(pname)" ); + } +} + + + +void +_mesa_GetMaterialiv( GLenum face, GLenum pname, GLint *params ) +{ + GET_CURRENT_CONTEXT(ctx); + GLuint f; + ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx); /* update materials */ + + if (face==GL_FRONT) { + f = 0; + } + else if (face==GL_BACK) { + f = 1; + } + else { + _mesa_error( ctx, GL_INVALID_ENUM, "glGetMaterialiv(face)" ); + return; + } + switch (pname) { + case GL_AMBIENT: + params[0] = FLOAT_TO_INT( ctx->Light.Material[f].Ambient[0] ); + params[1] = FLOAT_TO_INT( ctx->Light.Material[f].Ambient[1] ); + params[2] = FLOAT_TO_INT( ctx->Light.Material[f].Ambient[2] ); + params[3] = FLOAT_TO_INT( ctx->Light.Material[f].Ambient[3] ); + break; + case GL_DIFFUSE: + params[0] = FLOAT_TO_INT( ctx->Light.Material[f].Diffuse[0] ); + params[1] = FLOAT_TO_INT( ctx->Light.Material[f].Diffuse[1] ); + params[2] = FLOAT_TO_INT( ctx->Light.Material[f].Diffuse[2] ); + params[3] = FLOAT_TO_INT( ctx->Light.Material[f].Diffuse[3] ); + break; + case GL_SPECULAR: + params[0] = FLOAT_TO_INT( ctx->Light.Material[f].Specular[0] ); + params[1] = FLOAT_TO_INT( ctx->Light.Material[f].Specular[1] ); + params[2] = FLOAT_TO_INT( ctx->Light.Material[f].Specular[2] ); + params[3] = FLOAT_TO_INT( ctx->Light.Material[f].Specular[3] ); + break; + case GL_EMISSION: + params[0] = FLOAT_TO_INT( ctx->Light.Material[f].Emission[0] ); + params[1] = FLOAT_TO_INT( ctx->Light.Material[f].Emission[1] ); + params[2] = FLOAT_TO_INT( ctx->Light.Material[f].Emission[2] ); + params[3] = FLOAT_TO_INT( ctx->Light.Material[f].Emission[3] ); + break; + case GL_SHININESS: + *params = ROUNDF( ctx->Light.Material[f].Shininess ); + break; + case GL_COLOR_INDEXES: + params[0] = ROUNDF( ctx->Light.Material[f].AmbientIndex ); + params[1] = ROUNDF( ctx->Light.Material[f].DiffuseIndex ); + params[2] = ROUNDF( ctx->Light.Material[f].SpecularIndex ); + break; + default: + _mesa_error( ctx, GL_INVALID_ENUM, "glGetMaterialfv(pname)" ); + } +} + + + + +/**********************************************************************/ +/***** Lighting computation *****/ +/**********************************************************************/ + + +/* + * Notes: + * When two-sided lighting is enabled we compute the color (or index) + * for both the front and back side of the primitive. Then, when the + * orientation of the facet is later learned, we can determine which + * color (or index) to use for rendering. + * + * KW: We now know orientation in advance and only shade for + * the side or sides which are actually required. + * + * Variables: + * n = normal vector + * V = vertex position + * P = light source position + * Pe = (0,0,0,1) + * + * Precomputed: + * IF P[3]==0 THEN + * // light at infinity + * IF local_viewer THEN + * _VP_inf_norm = unit vector from V to P // Precompute + * ELSE + * // eye at infinity + * _h_inf_norm = Normalize( VP + <0,0,1> ) // Precompute + * ENDIF + * ENDIF + * + * Functions: + * Normalize( v ) = normalized vector v + * Magnitude( v ) = length of vector v + */ + + + +/* + * Whenever the spotlight exponent for a light changes we must call + * this function to recompute the exponent lookup table. + */ +void +_mesa_invalidate_spot_exp_table( struct gl_light *l ) +{ + l->_SpotExpTable[0][0] = -1; +} + +static void validate_spot_exp_table( struct gl_light *l ) +{ + GLint i; + GLdouble exponent = l->SpotExponent; + GLdouble tmp = 0; + GLint clamp = 0; + + l->_SpotExpTable[0][0] = 0.0; + + for (i = EXP_TABLE_SIZE - 1; i > 0 ;i--) { + if (clamp == 0) { + tmp = pow(i / (GLdouble) (EXP_TABLE_SIZE - 1), exponent); + if (tmp < FLT_MIN * 100.0) { + tmp = 0.0; + clamp = 1; + } + } + l->_SpotExpTable[i][0] = tmp; + } + for (i = 0; i < EXP_TABLE_SIZE - 1; i++) { + l->_SpotExpTable[i][1] = (l->_SpotExpTable[i+1][0] - + l->_SpotExpTable[i][0]); + } + l->_SpotExpTable[EXP_TABLE_SIZE-1][1] = 0.0; +} + + + + +/* Calculate a new shine table. Doing this here saves a branch in + * lighting, and the cost of doing it early may be partially offset + * by keeping a MRU cache of shine tables for various shine values. + */ +void +_mesa_invalidate_shine_table( GLcontext *ctx, GLuint i ) +{ + if (ctx->_ShineTable[i]) + ctx->_ShineTable[i]->refcount--; + ctx->_ShineTable[i] = 0; +} + +static void validate_shine_table( GLcontext *ctx, GLuint i, GLfloat shininess ) +{ + struct gl_shine_tab *list = ctx->_ShineTabList; + struct gl_shine_tab *s; + + foreach(s, list) + if ( s->shininess == shininess ) + break; + + if (s == list) { + GLint j; + GLfloat *m; + + foreach(s, list) + if (s->refcount == 0) + break; + + m = s->tab; + m[0] = 0.0; + if (shininess == 0.0) { + for (j = 1 ; j <= SHINE_TABLE_SIZE ; j++) + m[j] = 1.0; + } + else { + for (j = 1 ; j < SHINE_TABLE_SIZE ; j++) { + GLdouble t, x = j / (GLfloat) (SHINE_TABLE_SIZE - 1); + if (x < 0.005) /* underflow check */ + x = 0.005; + t = pow(x, shininess); + if (t > 1e-20) + m[j] = t; + else + m[j] = 0.0; + } + m[SHINE_TABLE_SIZE] = 1.0; + } + + s->shininess = shininess; + } + + if (ctx->_ShineTable[i]) + ctx->_ShineTable[i]->refcount--; + + ctx->_ShineTable[i] = s; + move_to_tail( list, s ); + s->refcount++; +} + +void +_mesa_validate_all_lighting_tables( GLcontext *ctx ) +{ + GLint i; + GLfloat shininess; + + shininess = ctx->Light.Material[0].Shininess; + if (!ctx->_ShineTable[0] || ctx->_ShineTable[0]->shininess != shininess) + validate_shine_table( ctx, 0, shininess ); + + shininess = ctx->Light.Material[1].Shininess; + if (!ctx->_ShineTable[1] || ctx->_ShineTable[1]->shininess != shininess) + validate_shine_table( ctx, 1, shininess ); + + for (i = 0 ; i < MAX_LIGHTS ; i++) + if (ctx->Light.Light[i]._SpotExpTable[0][0] == -1) + validate_spot_exp_table( &ctx->Light.Light[i] ); +} + + + + +/* + * Examine current lighting parameters to determine if the optimized lighting + * function can be used. + * Also, precompute some lighting values such as the products of light + * source and material ambient, diffuse and specular coefficients. + */ +void +_mesa_update_lighting( GLcontext *ctx ) +{ + struct gl_light *light; + ctx->_TriangleCaps &= ~DD_TRI_LIGHT_TWOSIDE; + ctx->_NeedEyeCoords &= ~NEED_EYE_LIGHT; + ctx->_NeedNormals &= ~NEED_NORMALS_LIGHT; + ctx->Light._Flags = 0; + + if (!ctx->Light.Enabled) + return; + + ctx->_NeedNormals |= NEED_NORMALS_LIGHT; + + if (ctx->Light.Model.TwoSide) + ctx->_TriangleCaps |= DD_TRI_LIGHT_TWOSIDE; + + foreach(light, &ctx->Light.EnabledList) { + ctx->Light._Flags |= light->_Flags; + } + + ctx->Light._NeedVertices = + ((ctx->Light._Flags & (LIGHT_POSITIONAL|LIGHT_SPOT)) || + ctx->Light.Model.ColorControl == GL_SEPARATE_SPECULAR_COLOR || + ctx->Light.Model.LocalViewer); + + if ((ctx->Light._Flags & LIGHT_POSITIONAL) || + ctx->Light.Model.LocalViewer) + ctx->_NeedEyeCoords |= NEED_EYE_LIGHT; + + + /* XXX: This test is overkill & needs to be fixed both for software and + * hardware t&l drivers. The above should be sufficient & should + * be tested to verify this. + */ + if (ctx->Light._NeedVertices) + ctx->_NeedEyeCoords |= NEED_EYE_LIGHT; + + + /* Precompute some shading values. Although we reference + * Light.Material here, we can get away without flushing + * FLUSH_UPDATE_CURRENT, as when any outstanding material changes + * are flushed, they will update the derived state at that time. + */ + if (ctx->Visual.rgbMode) { + GLuint sides = ctx->Light.Model.TwoSide ? 2 : 1; + GLuint side; + for (side=0; side < sides; side++) { + struct gl_material *mat = &ctx->Light.Material[side]; + + COPY_3V(ctx->Light._BaseColor[side], mat->Emission); + ACC_SCALE_3V(ctx->Light._BaseColor[side], + ctx->Light.Model.Ambient, + mat->Ambient); + + ctx->Light._BaseAlpha[side] = + CLAMP( ctx->Light.Material[side].Diffuse[3], 0.0, 1.0 ); + } + + foreach (light, &ctx->Light.EnabledList) { + for (side=0; side< sides; side++) { + const struct gl_material *mat = &ctx->Light.Material[side]; + SCALE_3V( light->_MatDiffuse[side], light->Diffuse, mat->Diffuse ); + SCALE_3V( light->_MatAmbient[side], light->Ambient, mat->Ambient ); + SCALE_3V( light->_MatSpecular[side], light->Specular, + mat->Specular); + } + } + } + else { + static const GLfloat ci[3] = { .30, .59, .11 }; + foreach(light, &ctx->Light.EnabledList) { + light->_dli = DOT3(ci, light->Diffuse); + light->_sli = DOT3(ci, light->Specular); + } + } +} + + +/* _NEW_MODELVIEW + * _NEW_LIGHT + * _TNL_NEW_NEED_EYE_COORDS + * + * Update on (_NEW_MODELVIEW | _NEW_LIGHT) when lighting is enabled. + * Also update on lighting space changes. + */ +void +_mesa_compute_light_positions( GLcontext *ctx ) +{ + struct gl_light *light; + static const GLfloat eye_z[3] = { 0, 0, 1 }; + + if (!ctx->Light.Enabled) + return; + + if (ctx->_NeedEyeCoords) { + COPY_3V( ctx->_EyeZDir, eye_z ); + } + else { + TRANSFORM_NORMAL( ctx->_EyeZDir, eye_z, ctx->ModelView.m ); + } + + foreach (light, &ctx->Light.EnabledList) { + + if (ctx->_NeedEyeCoords) { + COPY_4FV( light->_Position, light->EyePosition ); + } + else { + TRANSFORM_POINT( light->_Position, ctx->ModelView.inv, + light->EyePosition ); + } + + if (!(light->_Flags & LIGHT_POSITIONAL)) { + /* VP (VP) = Normalize( Position ) */ + COPY_3V( light->_VP_inf_norm, light->_Position ); + NORMALIZE_3FV( light->_VP_inf_norm ); + + if (!ctx->Light.Model.LocalViewer) { + /* _h_inf_norm = Normalize( V_to_P + <0,0,1> ) */ + ADD_3V( light->_h_inf_norm, light->_VP_inf_norm, ctx->_EyeZDir); + NORMALIZE_3FV( light->_h_inf_norm ); + } + light->_VP_inf_spot_attenuation = 1.0; + } + + if (light->_Flags & LIGHT_SPOT) { + if (ctx->_NeedEyeCoords) { + COPY_3V( light->_NormDirection, light->EyeDirection ); + } + else { + TRANSFORM_NORMAL( light->_NormDirection, + light->EyeDirection, + ctx->ModelView.m); + } + + NORMALIZE_3FV( light->_NormDirection ); + + if (!(light->_Flags & LIGHT_POSITIONAL)) { + GLfloat PV_dot_dir = - DOT3(light->_VP_inf_norm, + light->_NormDirection); + + if (PV_dot_dir > light->_CosCutoff) { + double x = PV_dot_dir * (EXP_TABLE_SIZE-1); + int k = (int) x; + light->_VP_inf_spot_attenuation = + (light->_SpotExpTable[k][0] + + (x-k)*light->_SpotExpTable[k][1]); + } + else { + light->_VP_inf_spot_attenuation = 0; + } + } + } + } +} Index: dll/opengl/opengl32/mesa/light.h =================================================================== --- dll/opengl/opengl32/mesa/light.h (revision 0) +++ dll/opengl/opengl32/mesa/light.h (working copy) @@ -0,0 +1,122 @@ +/* $Id: light.h,v 1.13 2001/04/28 08:39:17 keithw Exp $ */ + +/* + * Mesa 3-D graphics library + * Version: 3.5 + * + * Copyright (C) 1999-2001 Brian Paul 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 + * BRIAN PAUL 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. + */ + + +#ifndef LIGHT_H +#define LIGHT_H + + +#include "mtypes.h" + + +extern void +_mesa_ShadeModel( GLenum mode ); + +extern void +_mesa_ColorMaterial( GLenum face, GLenum mode ); + +extern void +_mesa_Lightf( GLenum light, GLenum pname, GLfloat param ); + +extern void +_mesa_Lightfv( GLenum light, GLenum pname, const GLfloat *params ); + +extern void +_mesa_Lightiv( GLenum light, GLenum pname, const GLint *params ); + +extern void +_mesa_Lighti( GLenum light, GLenum pname, GLint param ); + +extern void +_mesa_LightModelf( GLenum pname, GLfloat param ); + +extern void +_mesa_LightModelfv( GLenum pname, const GLfloat *params ); + +extern void +_mesa_LightModeli( GLenum pname, GLint param ); + +extern void +_mesa_LightModeliv( GLenum pname, const GLint *params ); + +extern void +_mesa_GetLightfv( GLenum light, GLenum pname, GLfloat *params ); + +extern void +_mesa_GetLightiv( GLenum light, GLenum pname, GLint *params ); + +extern void +_mesa_GetMaterialfv( GLenum face, GLenum pname, GLfloat *params ); + +extern void +_mesa_GetMaterialiv( GLenum face, GLenum pname, GLint *params ); + + +/* Lerp between adjacent values in the f(x) lookup table, giving a + * continuous function, with adequeate overall accuracy. (Though + * still pretty good compared to a straight lookup). + */ +#define GET_SHINE_TAB_ENTRY( table, dp, result ) \ +do { \ + struct gl_shine_tab *_tab = table; \ + float f = (dp * (SHINE_TABLE_SIZE-1)); \ + int k = (int) f; \ + if (k > SHINE_TABLE_SIZE-2) \ + result = pow( dp, _tab->shininess ); \ + else \ + result = _tab->tab[k] + (f-k)*(_tab->tab[k+1]-_tab->tab[k]); \ +} while (0) + + + +extern GLuint _mesa_material_bitmask( GLcontext *ctx, + GLenum face, GLenum pname, + GLuint legal, + const char * ); + +extern void _mesa_invalidate_spot_exp_table( struct gl_light *l ); + +extern void _mesa_invalidate_shine_table( GLcontext *ctx, GLuint i ); + +extern void _mesa_validate_all_lighting_tables( GLcontext *ctx ); + +extern void _mesa_update_lighting( GLcontext *ctx ); + +extern void _mesa_compute_light_positions( GLcontext *ctx ); + +extern void _mesa_update_material( GLcontext *ctx, + const struct gl_material src[2], + GLuint bitmask ); + +extern void _mesa_copy_material_pairs( struct gl_material dst[2], + const struct gl_material src[2], + GLuint bitmask ); + +extern void _mesa_update_color_material( GLcontext *ctx, + const GLfloat rgba[4] ); + + +#endif Index: dll/opengl/opengl32/mesa/lines.c =================================================================== --- dll/opengl/opengl32/mesa/lines.c (revision 0) +++ dll/opengl/opengl32/mesa/lines.c (working copy) @@ -0,0 +1,93 @@ +/* $Id: lines.c,v 1.29 2001/03/12 00:48:38 gareth Exp $ */ + +/* + * Mesa 3-D graphics library + * Version: 3.5 + * + * Copyright (C) 1999-2001 Brian Paul 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 + * BRIAN PAUL 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. + */ + + +#ifdef PC_HEADER +#include "all.h" +#else +#include "glheader.h" +#include "context.h" +#include "depth.h" +#include "lines.h" +#include "macros.h" +#include "mmath.h" +#include "texstate.h" +#include "mtypes.h" +#endif + + + +void +_mesa_LineWidth( GLfloat width ) +{ + GET_CURRENT_CONTEXT(ctx); + ASSERT_OUTSIDE_BEGIN_END(ctx); + + if (width<=0.0) { + _mesa_error( ctx, GL_INVALID_VALUE, "glLineWidth" ); + return; + } + + if (ctx->Line.Width == width) + return; + + FLUSH_VERTICES(ctx, _NEW_LINE); + ctx->Line.Width = width; + ctx->Line._Width = CLAMP(width, + ctx->Const.MinLineWidth, + ctx->Const.MaxLineWidth); + + + if (width != 1.0) + ctx->_TriangleCaps |= DD_LINE_WIDTH; + else + ctx->_TriangleCaps &= ~DD_LINE_WIDTH; + + if (ctx->Driver.LineWidth) + (*ctx->Driver.LineWidth)(ctx, width); +} + + + +void +_mesa_LineStipple( GLint factor, GLushort pattern ) +{ + GET_CURRENT_CONTEXT(ctx); + ASSERT_OUTSIDE_BEGIN_END(ctx); + + factor = CLAMP( factor, 1, 256 ); + + if (ctx->Line.StippleFactor == factor && + ctx->Line.StipplePattern == pattern) + return; + + FLUSH_VERTICES(ctx, _NEW_LINE); + ctx->Line.StippleFactor = factor; + ctx->Line.StipplePattern = pattern; + + if (ctx->Driver.LineStipple) + ctx->Driver.LineStipple( ctx, factor, pattern ); +} Index: dll/opengl/opengl32/mesa/lines.h =================================================================== --- dll/opengl/opengl32/mesa/lines.h (revision 0) +++ dll/opengl/opengl32/mesa/lines.h (working copy) @@ -0,0 +1,42 @@ +/* $Id: lines.h,v 1.5 2001/03/12 00:48:38 gareth Exp $ */ + +/* + * Mesa 3-D graphics library + * Version: 3.5 + * + * Copyright (C) 1999-2001 Brian Paul 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 + * BRIAN PAUL 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. + */ + + +#ifndef LINES_H +#define LINES_H + + +#include "mtypes.h" + + +extern void +_mesa_LineWidth( GLfloat width ); + +extern void +_mesa_LineStipple( GLint factor, GLushort pattern ); + + +#endif Index: dll/opengl/opengl32/mesa/lowpc.c =================================================================== --- dll/opengl/opengl32/mesa/lowpc.c (revision 0) +++ dll/opengl/opengl32/mesa/lowpc.c (working copy) @@ -0,0 +1,31 @@ +/* $Id: lowpc.c,v 1.2 2001/03/12 00:48:38 gareth Exp $ */ + +/* + * Mesa 3-D graphics library + * Version: 3.5 + * + * Copyright (C) 1999-2001 Brian Paul 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 + * BRIAN PAUL 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. + */ + + +/* + * This is the lowest address in Mesa + */ +void mesa_lowpc(void) { } Index: dll/opengl/opengl32/mesa/macros.h =================================================================== --- dll/opengl/opengl32/mesa/macros.h (revision 0) +++ dll/opengl/opengl32/mesa/macros.h (working copy) @@ -0,0 +1,476 @@ +/* $Id: macros.h,v 1.24 2001/06/11 07:52:51 joukj Exp $ */ + +/* + * Mesa 3-D graphics library + * Version: 3.5 + * + * Copyright (C) 1999-2001 Brian Paul 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 + * BRIAN PAUL 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. + */ + + +/* + * A collection of useful macros. + */ + + +#ifndef MACROS_H +#define MACROS_H + + +#include "glheader.h" +/* Do not reference mtypes.h from this file. + */ + + +/* Limits: */ +#define MAX_GLUSHORT 0xffff +#define MAX_GLUINT 0xffffffff + + +/* Pi */ +#ifndef M_PI +#define M_PI (3.1415926) +#endif + + +/* Degrees to radians conversion: */ +#define DEG2RAD (M_PI/180.0) + + +#ifndef NULL +#define NULL 0 +#endif + + + +/* + * Bitmask helpers + */ +#define SET_BITS(WORD, BITS) (WORD) |= (BITS) +#define CLEAR_BITS(WORD, BITS) (WORD) &= ~(BITS) +#define TEST_BITS(WORD, BITS) ((WORD) & (BITS)) + + +/* Stepping a GLfloat pointer by a byte stride + */ +#define STRIDE_F(p, i) (p = (GLfloat *)((GLubyte *)p + i)) +#define STRIDE_UI(p, i) (p = (GLuint *)((GLubyte *)p + i)) +#define STRIDE_4UB(p, i) (p = (GLubyte (*)[4])((GLubyte *)p + i)) +#define STRIDE_4CHAN(p, i) (p = (GLchan (*)[4])((GLubyte *)p + i)) +#define STRIDE_CHAN(p, i) (p = (GLchan *)((GLubyte *)p + i)) +#define STRIDE_T(p, t, i) (p = (t)((GLubyte *)p + i)) + + +#define ZERO_2V( DST ) (DST)[0] = (DST)[1] = 0 +#define ZERO_3V( DST ) (DST)[0] = (DST)[1] = (DST)[2] = 0 +#define ZERO_4V( DST ) (DST)[0] = (DST)[1] = (DST)[2] = (DST)[3] = 0 + + +#define TEST_EQ_4V(a,b) ((a)[0] == (b)[0] && \ + (a)[1] == (b)[1] && \ + (a)[2] == (b)[2] && \ + (a)[3] == (b)[3]) + +#define TEST_EQ_3V(a,b) ((a)[0] == (b)[0] && \ + (a)[1] == (b)[1] && \ + (a)[2] == (b)[2]) + +#if defined(__i386__) +#define TEST_EQ_4UBV(DST, SRC) *((GLuint*)(DST)) == *((GLuint*)(SRC)) +#else +#define TEST_EQ_4UBV(DST, SRC) TEST_EQ_4V(DST, SRC) +#endif + + + +/* Copy short vectors: */ +#define COPY_2V( DST, SRC ) \ +do { \ + (DST)[0] = (SRC)[0]; \ + (DST)[1] = (SRC)[1]; \ +} while (0) + +#define COPY_3V( DST, SRC ) \ +do { \ + (DST)[0] = (SRC)[0]; \ + (DST)[1] = (SRC)[1]; \ + (DST)[2] = (SRC)[2]; \ +} while (0) + +#define COPY_4V( DST, SRC ) \ +do { \ + (DST)[0] = (SRC)[0]; \ + (DST)[1] = (SRC)[1]; \ + (DST)[2] = (SRC)[2]; \ + (DST)[3] = (SRC)[3]; \ +} while (0) + +#if defined(__i386__) +#define COPY_4UBV(DST, SRC) \ +do { \ + *((GLuint*)(DST)) = *((GLuint*)(SRC)); \ +} while (0) +#else +/* The GLuint cast might fail if DST or SRC are not dword-aligned (RISC) */ +#define COPY_4UBV(DST, SRC) \ +do { \ + (DST)[0] = (SRC)[0]; \ + (DST)[1] = (SRC)[1]; \ + (DST)[2] = (SRC)[2]; \ + (DST)[3] = (SRC)[3]; \ +} while (0) +#endif + +#define COPY_2FV( DST, SRC ) \ +do { \ + const GLfloat *_tmp = (SRC); \ + (DST)[0] = _tmp[0]; \ + (DST)[1] = _tmp[1]; \ +} while (0) + +#define COPY_3FV( DST, SRC ) \ +do { \ + const GLfloat *_tmp = (SRC); \ + (DST)[0] = _tmp[0]; \ + (DST)[1] = _tmp[1]; \ + (DST)[2] = _tmp[2]; \ +} while (0) + +#define COPY_4FV( DST, SRC ) \ +do { \ + const GLfloat *_tmp = (SRC); \ + (DST)[0] = _tmp[0]; \ + (DST)[1] = _tmp[1]; \ + (DST)[2] = _tmp[2]; \ + (DST)[3] = _tmp[3]; \ +} while (0) + + + +#define COPY_SZ_4V(DST, SZ, SRC) \ +do { \ + switch (SZ) { \ + case 4: (DST)[3] = (SRC)[3]; \ + case 3: (DST)[2] = (SRC)[2]; \ + case 2: (DST)[1] = (SRC)[1]; \ + case 1: (DST)[0] = (SRC)[0]; \ + } \ +} while(0) + +#define COPY_CLEAN_4V(DST, SZ, SRC) \ +do { \ + ASSIGN_4V( DST, 0, 0, 0, 1 ); \ + COPY_SZ_4V( DST, SZ, SRC ); \ +} while (0) + +#define SUB_4V( DST, SRCA, SRCB ) \ +do { \ + (DST)[0] = (SRCA)[0] - (SRCB)[0]; \ + (DST)[1] = (SRCA)[1] - (SRCB)[1]; \ + (DST)[2] = (SRCA)[2] - (SRCB)[2]; \ + (DST)[3] = (SRCA)[3] - (SRCB)[3]; \ +} while (0) + +#define ADD_4V( DST, SRCA, SRCB ) \ +do { \ + (DST)[0] = (SRCA)[0] + (SRCB)[0]; \ + (DST)[1] = (SRCA)[1] + (SRCB)[1]; \ + (DST)[2] = (SRCA)[2] + (SRCB)[2]; \ + (DST)[3] = (SRCA)[3] + (SRCB)[3]; \ +} while (0) + +#define SCALE_4V( DST, SRCA, SRCB ) \ +do { \ + (DST)[0] = (SRCA)[0] * (SRCB)[0]; \ + (DST)[1] = (SRCA)[1] * (SRCB)[1]; \ + (DST)[2] = (SRCA)[2] * (SRCB)[2]; \ + (DST)[3] = (SRCA)[3] * (SRCB)[3]; \ +} while (0) + +#define ACC_4V( DST, SRC ) \ +do { \ + (DST)[0] += (SRC)[0]; \ + (DST)[1] += (SRC)[1]; \ + (DST)[2] += (SRC)[2]; \ + (DST)[3] += (SRC)[3]; \ +} while (0) + +#define ACC_SCALE_4V( DST, SRCA, SRCB ) \ +do { \ + (DST)[0] += (SRCA)[0] * (SRCB)[0]; \ + (DST)[1] += (SRCA)[1] * (SRCB)[1]; \ + (DST)[2] += (SRCA)[2] * (SRCB)[2]; \ + (DST)[3] += (SRCA)[3] * (SRCB)[3]; \ +} while (0) + +#define ACC_SCALE_SCALAR_4V( DST, S, SRCB ) \ +do { \ + (DST)[0] += S * (SRCB)[0]; \ + (DST)[1] += S * (SRCB)[1]; \ + (DST)[2] += S * (SRCB)[2]; \ + (DST)[3] += S * (SRCB)[3]; \ +} while (0) + +#define SCALE_SCALAR_4V( DST, S, SRCB ) \ +do { \ + (DST)[0] = S * (SRCB)[0]; \ + (DST)[1] = S * (SRCB)[1]; \ + (DST)[2] = S * (SRCB)[2]; \ + (DST)[3] = S * (SRCB)[3]; \ +} while (0) + + +#define SELF_SCALE_SCALAR_4V( DST, S ) \ +do { \ + (DST)[0] *= S; \ + (DST)[1] *= S; \ + (DST)[2] *= S; \ + (DST)[3] *= S; \ +} while (0) + + +/* + * Similarly for 3-vectors. + */ +#define SUB_3V( DST, SRCA, SRCB ) \ +do { \ + (DST)[0] = (SRCA)[0] - (SRCB)[0]; \ + (DST)[1] = (SRCA)[1] - (SRCB)[1]; \ + (DST)[2] = (SRCA)[2] - (SRCB)[2]; \ +} while (0) + +#define ADD_3V( DST, SRCA, SRCB ) \ +do { \ + (DST)[0] = (SRCA)[0] + (SRCB)[0]; \ + (DST)[1] = (SRCA)[1] + (SRCB)[1]; \ + (DST)[2] = (SRCA)[2] + (SRCB)[2]; \ +} while (0) + +#define SCALE_3V( DST, SRCA, SRCB ) \ +do { \ + (DST)[0] = (SRCA)[0] * (SRCB)[0]; \ + (DST)[1] = (SRCA)[1] * (SRCB)[1]; \ + (DST)[2] = (SRCA)[2] * (SRCB)[2]; \ +} while (0) + +#define ACC_3V( DST, SRC ) \ +do { \ + (DST)[0] += (SRC)[0]; \ + (DST)[1] += (SRC)[1]; \ + (DST)[2] += (SRC)[2]; \ +} while (0) + +#define ACC_SCALE_3V( DST, SRCA, SRCB ) \ +do { \ + (DST)[0] += (SRCA)[0] * (SRCB)[0]; \ + (DST)[1] += (SRCA)[1] * (SRCB)[1]; \ + (DST)[2] += (SRCA)[2] * (SRCB)[2]; \ +} while (0) + +#define SCALE_SCALAR_3V( DST, S, SRCB ) \ +do { \ + (DST)[0] = S * (SRCB)[0]; \ + (DST)[1] = S * (SRCB)[1]; \ + (DST)[2] = S * (SRCB)[2]; \ +} while (0) + +#define ACC_SCALE_SCALAR_3V( DST, S, SRCB ) \ +do { \ + (DST)[0] += S * (SRCB)[0]; \ + (DST)[1] += S * (SRCB)[1]; \ + (DST)[2] += S * (SRCB)[2]; \ +} while (0) + +#define SELF_SCALE_SCALAR_3V( DST, S ) \ +do { \ + (DST)[0] *= S; \ + (DST)[1] *= S; \ + (DST)[2] *= S; \ +} while (0) + +#define ACC_SCALAR_3V( DST, S ) \ +do { \ + (DST)[0] += S; \ + (DST)[1] += S; \ + (DST)[2] += S; \ +} while (0) + +/* And also for 2-vectors + */ +#define SUB_2V( DST, SRCA, SRCB ) \ +do { \ + (DST)[0] = (SRCA)[0] - (SRCB)[0]; \ + (DST)[1] = (SRCA)[1] - (SRCB)[1]; \ +} while (0) + +#define ADD_2V( DST, SRCA, SRCB ) \ +do { \ + (DST)[0] = (SRCA)[0] + (SRCB)[0]; \ + (DST)[1] = (SRCA)[1] + (SRCB)[1]; \ +} while (0) + +#define SCALE_2V( DST, SRCA, SRCB ) \ +do { \ + (DST)[0] = (SRCA)[0] * (SRCB)[0]; \ + (DST)[1] = (SRCA)[1] * (SRCB)[1]; \ +} while (0) + +#define ACC_2V( DST, SRC ) \ +do { \ + (DST)[0] += (SRC)[0]; \ + (DST)[1] += (SRC)[1]; \ +} while (0) + +#define ACC_SCALE_2V( DST, SRCA, SRCB ) \ +do { \ + (DST)[0] += (SRCA)[0] * (SRCB)[0]; \ + (DST)[1] += (SRCA)[1] * (SRCB)[1]; \ +} while (0) + +#define SCALE_SCALAR_2V( DST, S, SRCB ) \ +do { \ + (DST)[0] = S * (SRCB)[0]; \ + (DST)[1] = S * (SRCB)[1]; \ +} while (0) + +#define ACC_SCALE_SCALAR_2V( DST, S, SRCB ) \ +do { \ + (DST)[0] += S * (SRCB)[0]; \ + (DST)[1] += S * (SRCB)[1]; \ +} while (0) + +#define SELF_SCALE_SCALAR_2V( DST, S ) \ +do { \ + (DST)[0] *= S; \ + (DST)[1] *= S; \ +} while (0) + +#define ACC_SCALAR_2V( DST, S ) \ +do { \ + (DST)[0] += S; \ + (DST)[1] += S; \ +} while (0) + + + +/* Assign scalers to short vectors: */ +#define ASSIGN_2V( V, V0, V1 ) \ +do { \ + V[0] = V0; \ + V[1] = V1; \ +} while(0) + +#define ASSIGN_3V( V, V0, V1, V2 ) \ +do { \ + V[0] = V0; \ + V[1] = V1; \ + V[2] = V2; \ +} while(0) + +#define ASSIGN_4V( V, V0, V1, V2, V3 ) \ +do { \ + V[0] = V0; \ + V[1] = V1; \ + V[2] = V2; \ + V[3] = V3; \ +} while(0) + + + + +/* Absolute value (for Int, Float, Double): */ +#define ABSI(X) ((X) < 0 ? -(X) : (X)) +#define ABSF(X) ((X) < 0.0F ? -(X) : (X)) +#define ABSD(X) ((X) < 0.0 ? -(X) : (X)) + + + +/* Round a floating-point value to the nearest integer: */ +#define ROUNDF(X) ( (X)<0.0F ? ((GLint) ((X)-0.5F)) : ((GLint) ((X)+0.5F)) ) + + +/* Compute ceiling of integer quotient of A divided by B: */ +#define CEILING( A, B ) ( (A) % (B) == 0 ? (A)/(B) : (A)/(B)+1 ) + + +/* Clamp X to [MIN,MAX]: */ +#define CLAMP( X, MIN, MAX ) ( (X)<(MIN) ? (MIN) : ((X)>(MAX) ? (MAX) : (X)) ) + +/* Assign X to CLAMP(X, MIN, MAX) */ +#define CLAMP_SELF(x, mn, mx) \ + ( (x)<(mn) ? ((x) = (mn)) : ((x)>(mx) ? ((x)=(mx)) : (x)) ) + + + +/* Min of two values: */ +#define MIN2( A, B ) ( (A)<(B) ? (A) : (B) ) + +/* MAX of two values: */ +#define MAX2( A, B ) ( (A)>(B) ? (A) : (B) ) + +/* Dot product of two 2-element vectors */ +#define DOT2( a, b ) ( (a)[0]*(b)[0] + (a)[1]*(b)[1] ) + +/* Dot product of two 3-element vectors */ +#define DOT3( a, b ) ( (a)[0]*(b)[0] + (a)[1]*(b)[1] + (a)[2]*(b)[2] ) + +/* Dot product of two 4-element vectors */ +#define DOT4( a, b ) ( (a)[0]*(b)[0] + (a)[1]*(b)[1] + \ + (a)[2]*(b)[2] + (a)[3]*(b)[3] ) + +#define DOT4V(v,a,b,c,d) (v[0]*(a) + v[1]*(b) + v[2]*(c) + v[3]*(d)) + + +#define CROSS3(n, u, v) \ +do { \ + (n)[0] = (u)[1]*(v)[2] - (u)[2]*(v)[1]; \ + (n)[1] = (u)[2]*(v)[0] - (u)[0]*(v)[2]; \ + (n)[2] = (u)[0]*(v)[1] - (u)[1]*(v)[0]; \ +} while (0) + + + +/* Generic color packing macros + */ + +#define PACK_COLOR_8888( a, b, c, d ) \ + (((a) << 24) | ((b) << 16) | ((c) << 8) | (d)) + +#define PACK_COLOR_888( a, b, c ) \ + (((a) << 16) | ((b) << 8) | (c)) + +#define PACK_COLOR_565( a, b, c ) \ + ((((a) & 0xf8) << 8) | (((b) & 0xfc) << 3) | (((c) & 0xf8) >> 3)) + +#define PACK_COLOR_1555( a, b, c, d ) \ + ((((b) & 0xf8) << 7) | (((c) & 0xf8) << 2) | (((d) & 0xf8) >> 3) | \ + ((a) ? 0x8000 : 0)) + +#define PACK_COLOR_4444( a, b, c, d ) \ + ((((a) & 0xf0) << 8) | (((b) & 0xf0) << 4) | ((c) & 0xf0) | ((d) >> 4)) + +#define PACK_COLOR_88( a, b ) \ + (((a) << 8) | (b)) + +#define PACK_COLOR_332( a, b, c ) \ + (((a) & 0xe0) | (((b) & 0xe0) >> 3) | (((c) & 0xc0) >> 6)) + + +#endif Index: dll/opengl/opengl32/mesa/math/m_clip_tmp.h =================================================================== --- dll/opengl/opengl32/mesa/math/m_clip_tmp.h (revision 0) +++ dll/opengl/opengl32/mesa/math/m_clip_tmp.h (working copy) @@ -0,0 +1,229 @@ +/* $Id: m_clip_tmp.h,v 1.7 2001/05/21 16:33:41 gareth Exp $ */ + +/* + * Mesa 3-D graphics library + * Version: 3.5 + * + * Copyright (C) 1999-2001 Brian Paul 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 + * BRIAN PAUL 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. + */ + +/* + * New (3.1) transformation code written by Keith Whitwell. + */ + + +/* KW: a clever asm implementation would nestle integer versions + * of the outcode calculation underneath the division. Gcc won't + * do this, strangely enough, so I only do the divide in + * the case where the cliptest passes. This isn't essential, + * and an asm implementation needn't replicate that behaviour. + */ +static GLvector4f * _XFORMAPI TAG(cliptest_points4)( GLvector4f *clip_vec, + GLvector4f *proj_vec, + GLubyte clipMask[], + GLubyte *orMask, + GLubyte *andMask ) +{ + const GLuint stride = clip_vec->stride; + const GLfloat *from = (GLfloat *)clip_vec->start; + const GLuint count = clip_vec->count; + GLuint c = 0; + GLfloat (*vProj)[4] = (GLfloat (*)[4])proj_vec->start; + GLubyte tmpAndMask = *andMask; + GLubyte tmpOrMask = *orMask; + GLuint i; + STRIDE_LOOP { + const GLfloat cx = from[0]; + const GLfloat cy = from[1]; + const GLfloat cz = from[2]; + const GLfloat cw = from[3]; +#if defined(macintosh) + /* on powerpc cliptest is 17% faster in this way. */ + GLuint mask; + mask = (((cw < cx) << CLIP_RIGHT_SHIFT)); + mask |= (((cw < -cx) << CLIP_LEFT_SHIFT)); + mask |= (((cw < cy) << CLIP_TOP_SHIFT)); + mask |= (((cw < -cy) << CLIP_BOTTOM_SHIFT)); + mask |= (((cw < cz) << CLIP_FAR_SHIFT)); + mask |= (((cw < -cz) << CLIP_NEAR_SHIFT)); +#else /* !defined(macintosh)) */ + GLubyte mask = 0; + if (-cx + cw < 0) mask |= CLIP_RIGHT_BIT; + if ( cx + cw < 0) mask |= CLIP_LEFT_BIT; + if (-cy + cw < 0) mask |= CLIP_TOP_BIT; + if ( cy + cw < 0) mask |= CLIP_BOTTOM_BIT; + if (-cz + cw < 0) mask |= CLIP_FAR_BIT; + if ( cz + cw < 0) mask |= CLIP_NEAR_BIT; +#endif /* defined(macintosh) */ + + clipMask[i] = mask; + if (mask) { + c++; + tmpAndMask &= mask; + tmpOrMask |= mask; + vProj[i][0] = 0; + vProj[i][1] = 0; + vProj[i][2] = 0; + vProj[i][3] = 1; + } else { + GLfloat oow = 1.0F / cw; + vProj[i][0] = cx * oow; + vProj[i][1] = cy * oow; + vProj[i][2] = cz * oow; + vProj[i][3] = oow; + } + } + + *orMask = tmpOrMask; + *andMask = (GLubyte) (c < count ? 0 : tmpAndMask); + + proj_vec->flags |= VEC_SIZE_4; + proj_vec->size = 4; + proj_vec->count = clip_vec->count; + return proj_vec; +} + + + +static GLvector4f * _XFORMAPI TAG(cliptest_np_points4)( GLvector4f *clip_vec, + GLvector4f *proj_vec, + GLubyte clipMask[], + GLubyte *orMask, + GLubyte *andMask ) +{ + const GLuint stride = clip_vec->stride; + const GLuint count = clip_vec->count; + const GLfloat *from = (GLfloat *)clip_vec->start; + GLuint c = 0; + GLubyte tmpAndMask = *andMask; + GLubyte tmpOrMask = *orMask; + GLuint i; + STRIDE_LOOP { + const GLfloat cx = from[0]; + const GLfloat cy = from[1]; + const GLfloat cz = from[2]; + const GLfloat cw = from[3]; +#if defined(macintosh) + /* on powerpc cliptest is 17% faster in this way. */ + GLuint mask; + mask = (((cw < cx) << CLIP_RIGHT_SHIFT)); + mask |= (((cw < -cx) << CLIP_LEFT_SHIFT)); + mask |= (((cw < cy) << CLIP_TOP_SHIFT)); + mask |= (((cw < -cy) << CLIP_BOTTOM_SHIFT)); + mask |= (((cw < cz) << CLIP_FAR_SHIFT)); + mask |= (((cw < -cz) << CLIP_NEAR_SHIFT)); +#else /* !defined(macintosh)) */ + GLubyte mask = 0; + if (-cx + cw < 0) mask |= CLIP_RIGHT_BIT; + if ( cx + cw < 0) mask |= CLIP_LEFT_BIT; + if (-cy + cw < 0) mask |= CLIP_TOP_BIT; + if ( cy + cw < 0) mask |= CLIP_BOTTOM_BIT; + if (-cz + cw < 0) mask |= CLIP_FAR_BIT; + if ( cz + cw < 0) mask |= CLIP_NEAR_BIT; +#endif /* defined(macintosh) */ + + clipMask[i] = mask; + if (mask) { + c++; + tmpAndMask &= mask; + tmpOrMask |= mask; + } + } + + *orMask = tmpOrMask; + *andMask = (GLubyte) (c < count ? 0 : tmpAndMask); + return clip_vec; +} + + +static GLvector4f * _XFORMAPI TAG(cliptest_points3)( GLvector4f *clip_vec, + GLvector4f *proj_vec, + GLubyte clipMask[], + GLubyte *orMask, + GLubyte *andMask ) +{ + const GLuint stride = clip_vec->stride; + const GLuint count = clip_vec->count; + const GLfloat *from = (GLfloat *)clip_vec->start; + + GLubyte tmpOrMask = *orMask; + GLubyte tmpAndMask = *andMask; + GLuint i; + STRIDE_LOOP { + const GLfloat cx = from[0], cy = from[1], cz = from[2]; + GLubyte mask = 0; + if (cx > 1.0) mask |= CLIP_RIGHT_BIT; + else if (cx < -1.0) mask |= CLIP_LEFT_BIT; + if (cy > 1.0) mask |= CLIP_TOP_BIT; + else if (cy < -1.0) mask |= CLIP_BOTTOM_BIT; + if (cz > 1.0) mask |= CLIP_FAR_BIT; + else if (cz < -1.0) mask |= CLIP_NEAR_BIT; + clipMask[i] = mask; + tmpOrMask |= mask; + tmpAndMask &= mask; + } + + *orMask = tmpOrMask; + *andMask = tmpAndMask; + return clip_vec; +} + + +static GLvector4f * _XFORMAPI TAG(cliptest_points2)( GLvector4f *clip_vec, + GLvector4f *proj_vec, + GLubyte clipMask[], + GLubyte *orMask, + GLubyte *andMask ) +{ + const GLuint stride = clip_vec->stride; + const GLuint count = clip_vec->count; + const GLfloat *from = (GLfloat *)clip_vec->start; + + GLubyte tmpOrMask = *orMask; + GLubyte tmpAndMask = *andMask; + GLuint i; + STRIDE_LOOP { + const GLfloat cx = from[0], cy = from[1]; + GLubyte mask = 0; + if (cx > 1.0) mask |= CLIP_RIGHT_BIT; + else if (cx < -1.0) mask |= CLIP_LEFT_BIT; + if (cy > 1.0) mask |= CLIP_TOP_BIT; + else if (cy < -1.0) mask |= CLIP_BOTTOM_BIT; + clipMask[i] = mask; + tmpOrMask |= mask; + tmpAndMask &= mask; + } + + *orMask = tmpOrMask; + *andMask = tmpAndMask; + return clip_vec; +} + + +static void TAG(init_c_cliptest)( void ) +{ + _mesa_clip_tab[4] = TAG(cliptest_points4); + _mesa_clip_tab[3] = TAG(cliptest_points3); + _mesa_clip_tab[2] = TAG(cliptest_points2); + + _mesa_clip_np_tab[4] = TAG(cliptest_np_points4); + _mesa_clip_np_tab[3] = TAG(cliptest_points3); + _mesa_clip_np_tab[2] = TAG(cliptest_points2); +} Index: dll/opengl/opengl32/mesa/math/m_copy_tmp.h =================================================================== --- dll/opengl/opengl32/mesa/math/m_copy_tmp.h (revision 0) +++ dll/opengl/opengl32/mesa/math/m_copy_tmp.h (working copy) @@ -0,0 +1,87 @@ +/* $Id: m_copy_tmp.h,v 1.6 2001/03/30 14:44:43 gareth Exp $ */ + +/* + * Mesa 3-D graphics library + * Version: 3.5 + * + * Copyright (C) 1999-2001 Brian Paul 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 + * BRIAN PAUL 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. + */ + +/* + * New (3.1) transformation code written by Keith Whitwell. + */ + + +#define COPY_FUNC( BITS ) \ +static void TAG2(copy, BITS)( GLvector4f *to, const GLvector4f *f ) \ +{ \ + GLfloat (*t)[4] = (GLfloat (*)[4])to->start; \ + GLfloat *from = f->start; \ + GLuint stride = f->stride; \ + GLuint count = f->count; \ + GLuint i; \ + \ + if (BITS) \ + STRIDE_LOOP { \ + if (BITS&1) t[i][0] = from[0]; \ + if (BITS&2) t[i][1] = from[1]; \ + if (BITS&4) t[i][2] = from[2]; \ + if (BITS&8) t[i][3] = from[3]; \ + } \ +} + +/* We got them all here: + */ +COPY_FUNC( 0x0 ) /* noop */ +COPY_FUNC( 0x1 ) +COPY_FUNC( 0x2 ) +COPY_FUNC( 0x3 ) +COPY_FUNC( 0x4 ) +COPY_FUNC( 0x5 ) +COPY_FUNC( 0x6 ) +COPY_FUNC( 0x7 ) +COPY_FUNC( 0x8 ) +COPY_FUNC( 0x9 ) +COPY_FUNC( 0xa ) +COPY_FUNC( 0xb ) +COPY_FUNC( 0xc ) +COPY_FUNC( 0xd ) +COPY_FUNC( 0xe ) +COPY_FUNC( 0xf ) + +static void TAG2(init_copy, 0)( void ) +{ + _mesa_copy_tab[0x0] = TAG2(copy, 0x0); + _mesa_copy_tab[0x1] = TAG2(copy, 0x1); + _mesa_copy_tab[0x2] = TAG2(copy, 0x2); + _mesa_copy_tab[0x3] = TAG2(copy, 0x3); + _mesa_copy_tab[0x4] = TAG2(copy, 0x4); + _mesa_copy_tab[0x5] = TAG2(copy, 0x5); + _mesa_copy_tab[0x6] = TAG2(copy, 0x6); + _mesa_copy_tab[0x7] = TAG2(copy, 0x7); + _mesa_copy_tab[0x8] = TAG2(copy, 0x8); + _mesa_copy_tab[0x9] = TAG2(copy, 0x9); + _mesa_copy_tab[0xa] = TAG2(copy, 0xa); + _mesa_copy_tab[0xb] = TAG2(copy, 0xb); + _mesa_copy_tab[0xc] = TAG2(copy, 0xc); + _mesa_copy_tab[0xd] = TAG2(copy, 0xd); + _mesa_copy_tab[0xe] = TAG2(copy, 0xe); + _mesa_copy_tab[0xf] = TAG2(copy, 0xf); +} Index: dll/opengl/opengl32/mesa/math/m_debug.h =================================================================== --- dll/opengl/opengl32/mesa/math/m_debug.h (revision 0) +++ dll/opengl/opengl32/mesa/math/m_debug.h (working copy) @@ -0,0 +1,43 @@ +/* $Id: m_debug.h,v 1.4 2001/05/21 16:33:41 gareth Exp $ */ + +/* + * Mesa 3-D graphics library + * Version: 3.5 + * + * Copyright (C) 1999-2001 Brian Paul 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 + * BRIAN PAUL 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. + * + * Authors: + * Gareth Hughes + */ + +#ifndef __M_DEBUG_H__ +#define __M_DEBUG_H__ + +extern void _math_test_all_transform_functions( char *description ); +extern void _math_test_all_normal_transform_functions( char *description ); +extern void _math_test_all_cliptest_functions( char *description ); + +/* Deprecated? + */ +extern void _math_test_all_vertex_functions( char *description ); + +extern char *mesa_profile; + +#endif Index: dll/opengl/opengl32/mesa/math/m_debug_clip.c =================================================================== --- dll/opengl/opengl32/mesa/math/m_debug_clip.c (revision 0) +++ dll/opengl/opengl32/mesa/math/m_debug_clip.c (working copy) @@ -0,0 +1,365 @@ +/* $Id: m_debug_clip.c,v 1.1 2001/05/21 16:33:41 gareth Exp $ */ + +/* + * Mesa 3-D graphics library + * Version: 3.5 + * + * Copyright (C) 1999-2001 Brian Paul 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 + * BRIAN PAUL 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. + * + * Authors: + * Gareth Hughes + */ + +#include "glheader.h" +#include "context.h" +#include "macros.h" +#include "mem.h" + +#include "m_matrix.h" +#include "m_xform.h" + +#include "m_debug.h" +#include "m_debug_util.h" + +#ifdef DEBUG /* This code only used for debugging */ + +static clip_func *clip_tab[2] = { + _mesa_clip_tab, + _mesa_clip_np_tab +}; +static char *cnames[2] = { + "_mesa_clip_tab", + "_mesa_clip_np_tab" +}; +static char *cstrings[2] = { + "clip, perspective divide", + "clip, no divide" +}; + + +/* ============================================================= + * Reference cliptests + */ + +static GLvector4f *ref_cliptest_points4( GLvector4f *clip_vec, + GLvector4f *proj_vec, + GLubyte clipMask[], + GLubyte *orMask, + GLubyte *andMask ) +{ + const GLuint stride = clip_vec->stride; + const GLuint count = clip_vec->count; + const GLfloat *from = (GLfloat *)clip_vec->start; + GLuint c = 0; + GLfloat (*vProj)[4] = (GLfloat (*)[4])proj_vec->start; + GLubyte tmpAndMask = *andMask; + GLubyte tmpOrMask = *orMask; + GLuint i; + for ( i = 0 ; i < count ; i++, STRIDE_F(from, stride) ) { + const GLfloat cx = from[0]; + const GLfloat cy = from[1]; + const GLfloat cz = from[2]; + const GLfloat cw = from[3]; + GLubyte mask = 0; + if ( -cx + cw < 0 ) mask |= CLIP_RIGHT_BIT; + if ( cx + cw < 0 ) mask |= CLIP_LEFT_BIT; + if ( -cy + cw < 0 ) mask |= CLIP_TOP_BIT; + if ( cy + cw < 0 ) mask |= CLIP_BOTTOM_BIT; + if ( -cz + cw < 0 ) mask |= CLIP_FAR_BIT; + if ( cz + cw < 0 ) mask |= CLIP_NEAR_BIT; + clipMask[i] = mask; + if ( mask ) { + c++; + tmpAndMask &= mask; + tmpOrMask |= mask; + vProj[i][0] = 0; + vProj[i][1] = 0; + vProj[i][2] = 0; + vProj[i][3] = 1; + } else { + GLfloat oow = 1.0F / cw; + vProj[i][0] = cx * oow; + vProj[i][1] = cy * oow; + vProj[i][2] = cz * oow; + vProj[i][3] = oow; + } + } + + *orMask = tmpOrMask; + *andMask = (GLubyte) (c < count ? 0 : tmpAndMask); + + proj_vec->flags |= VEC_SIZE_4; + proj_vec->size = 4; + proj_vec->count = clip_vec->count; + return proj_vec; +} + +/* Keep these here for now, even though we don't use them... + */ +static GLvector4f *ref_cliptest_points3( GLvector4f *clip_vec, + GLvector4f *proj_vec, + GLubyte clipMask[], + GLubyte *orMask, + GLubyte *andMask ) +{ + const GLuint stride = clip_vec->stride; + const GLuint count = clip_vec->count; + const GLfloat *from = (GLfloat *)clip_vec->start; + + GLubyte tmpOrMask = *orMask; + GLubyte tmpAndMask = *andMask; + GLuint i; + for ( i = 0 ; i < count ; i++, STRIDE_F(from, stride) ) { + const GLfloat cx = from[0], cy = from[1], cz = from[2]; + GLubyte mask = 0; + if ( cx > 1.0 ) mask |= CLIP_RIGHT_BIT; + else if ( cx < -1.0 ) mask |= CLIP_LEFT_BIT; + if ( cy > 1.0 ) mask |= CLIP_TOP_BIT; + else if ( cy < -1.0 ) mask |= CLIP_BOTTOM_BIT; + if ( cz > 1.0 ) mask |= CLIP_FAR_BIT; + else if ( cz < -1.0 ) mask |= CLIP_NEAR_BIT; + clipMask[i] = mask; + tmpOrMask |= mask; + tmpAndMask &= mask; + } + + *orMask = tmpOrMask; + *andMask = tmpAndMask; + return clip_vec; +} + +static GLvector4f * ref_cliptest_points2( GLvector4f *clip_vec, + GLvector4f *proj_vec, + GLubyte clipMask[], + GLubyte *orMask, + GLubyte *andMask ) +{ + const GLuint stride = clip_vec->stride; + const GLuint count = clip_vec->count; + const GLfloat *from = (GLfloat *)clip_vec->start; + + GLubyte tmpOrMask = *orMask; + GLubyte tmpAndMask = *andMask; + GLuint i; + for ( i = 0 ; i < count ; i++, STRIDE_F(from, stride) ) { + const GLfloat cx = from[0], cy = from[1]; + GLubyte mask = 0; + if ( cx > 1.0 ) mask |= CLIP_RIGHT_BIT; + else if ( cx < -1.0 ) mask |= CLIP_LEFT_BIT; + if ( cy > 1.0 ) mask |= CLIP_TOP_BIT; + else if ( cy < -1.0 ) mask |= CLIP_BOTTOM_BIT; + clipMask[i] = mask; + tmpOrMask |= mask; + tmpAndMask &= mask; + } + + *orMask = tmpOrMask; + *andMask = tmpAndMask; + return clip_vec; +} + +static clip_func ref_cliptest[5] = { + 0, + 0, + ref_cliptest_points2, + ref_cliptest_points3, + ref_cliptest_points4 +}; + + +/* ============================================================= + * Cliptest tests + */ + +static GLfloat s[TEST_COUNT][4] ALIGN16; +static GLfloat d[TEST_COUNT][4] ALIGN16; +static GLfloat r[TEST_COUNT][4] ALIGN16; + +static int test_cliptest_function( clip_func func, int np, + int psize, long *cycles ) +{ + GLvector4f source[1], dest[1], ref[1]; + GLubyte dm[TEST_COUNT], dco, dca; + GLubyte rm[TEST_COUNT], rco, rca; + int i, j; +#ifdef RUN_DEBUG_BENCHMARK + int cycle_i; /* the counter for the benchmarks we run */ +#endif + + (void) cycles; + + if ( psize > 4 ) { + _mesa_problem( NULL, "test_cliptest_function called with psize > 4\n" ); + return 0; + } + + for ( i = 0 ; i < TEST_COUNT ; i++) { + ASSIGN_4V( d[i], 0.0, 0.0, 0.0, 1.0 ); + ASSIGN_4V( s[i], 0.0, 0.0, 0.0, 1.0 ); + for ( j = 0 ; j < psize ; j++ ) + s[i][j] = rnd(); + } + + source->data = (GLfloat(*)[4])s; + source->start = (GLfloat *)s; + source->count = TEST_COUNT; + source->stride = sizeof(s[0]); + source->size = 4; + source->flags = 0; + + dest->data = (GLfloat(*)[4])d; + dest->start = (GLfloat *)d; + dest->count = TEST_COUNT; + dest->stride = sizeof(float[4]); + dest->size = 0; + dest->flags = 0; + + ref->data = (GLfloat(*)[4])r; + ref->start = (GLfloat *)r; + ref->count = TEST_COUNT; + ref->stride = sizeof(float[4]); + ref->size = 0; + ref->flags = 0; + + dco = rco = 0; + dca = rca = CLIP_ALL_BITS; + + ref_cliptest[psize]( source, ref, rm, &rco, &rca ); + + if ( mesa_profile ) { + BEGIN_RACE( *cycles ); + func( source, dest, dm, &dco, &dca ); + END_RACE( *cycles ); + } + else { + func( source, dest, dm, &dco, &dca ); + } + + if ( dco != rco ) { + printf( "\n-----------------------------\n" ); + printf( "dco = 0x%02x rco = 0x%02x\n", dco, rco ); + return 0; + } + if ( dca != rca ) { + printf( "\n-----------------------------\n" ); + printf( "dca = 0x%02x rca = 0x%02x\n", dca, rca ); + return 0; + } + for ( i = 0 ; i < TEST_COUNT ; i++ ) { + if ( dm[i] != rm[i] ) { + printf( "\n-----------------------------\n" ); + printf( "(i = %i)\n", i ); + printf( "dm = 0x%02x rm = 0x%02x\n", dm[i], rm[i] ); + return 0; + } + } + + /* Only verify output on projected points4 case. FIXME: Do we need + * to test other cases? + */ + if ( np || psize < 4 ) + return 1; + + for ( i = 0 ; i < TEST_COUNT ; i++ ) { + for ( j = 0 ; j < 4 ; j++ ) { + if ( significand_match( d[i][j], r[i][j] ) < REQUIRED_PRECISION ) { + printf( "\n-----------------------------\n" ); + printf( "(i = %i, j = %i) dm = 0x%02x rm = 0x%02x\n", + i, j, dm[i], rm[i] ); + printf( "%f \t %f \t [diff = %e - %i bit missed]\n", + d[i][0], r[i][0], r[i][0]-d[i][0], + MAX_PRECISION - significand_match( d[i][0], r[i][0] ) ); + printf( "%f \t %f \t [diff = %e - %i bit missed]\n", + d[i][1], r[i][1], r[i][1]-d[i][1], + MAX_PRECISION - significand_match( d[i][1], r[i][1] ) ); + printf( "%f \t %f \t [diff = %e - %i bit missed]\n", + d[i][2], r[i][2], r[i][2]-d[i][2], + MAX_PRECISION - significand_match( d[i][2], r[i][2] ) ); + printf( "%f \t %f \t [diff = %e - %i bit missed]\n", + d[i][3], r[i][3], r[i][3]-d[i][3], + MAX_PRECISION - significand_match( d[i][3], r[i][3] ) ); + return 0; + } + } + } + + return 1; +} + +void _math_test_all_cliptest_functions( char *description ) +{ + int np, psize; + long benchmark_tab[2][4]; + static int first_time = 1; + + if ( first_time ) { + first_time = 0; + mesa_profile = getenv( "MESA_PROFILE" ); + } + +#ifdef RUN_DEBUG_BENCHMARK + if ( mesa_profile ) { + if ( !counter_overhead ) { + INIT_COUNTER(); + printf( "counter overhead: %ld cycles\n\n", counter_overhead ); + } + printf( "cliptest results after hooking in %s functions:\n", description ); + } +#endif + +#ifdef RUN_DEBUG_BENCHMARK + if ( mesa_profile ) { + printf( "\n\t" ); + for ( psize = 2 ; psize <= 4 ; psize++ ) { + printf( " p%d\t", psize ); + } + printf( "\n--------------------------------------------------------\n\t" ); + } +#endif + + for ( np = 0 ; np < 2 ; np++ ) { + for ( psize = 2 ; psize <= 4 ; psize++ ) { + clip_func func = clip_tab[np][psize]; + long *cycles = &(benchmark_tab[np][psize-1]); + + if ( test_cliptest_function( func, np, psize, cycles ) == 0 ) { + char buf[100]; + sprintf( buf, "%s[%d] failed test (%s)", + cnames[np], psize, description ); + _mesa_problem( NULL, buf ); + } +#ifdef RUN_DEBUG_BENCHMARK + if ( mesa_profile ) + printf( " %li\t", benchmark_tab[np][psize-1] ); +#endif + } +#ifdef RUN_DEBUG_BENCHMARK + if ( mesa_profile ) + printf( " | [%s]\n\t", cstrings[np] ); +#endif + } +#ifdef RUN_DEBUG_BENCHMARK + if ( mesa_profile ) + printf( "\n" ); +#endif +} + + +#endif /* DEBUG */ Index: dll/opengl/opengl32/mesa/math/m_debug_norm.c =================================================================== --- dll/opengl/opengl32/mesa/math/m_debug_norm.c (revision 0) +++ dll/opengl/opengl32/mesa/math/m_debug_norm.c (working copy) @@ -0,0 +1,372 @@ +/* $Id: m_debug_norm.c,v 1.7 2001/03/30 14:44:43 gareth Exp $ */ + +/* + * Mesa 3-D graphics library + * Version: 3.5 + * + * Copyright (C) 1999-2001 Brian Paul 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 + * BRIAN PAUL 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. + * + * Authors: + * Gareth Hughes + */ + +#include "glheader.h" +#include "context.h" +#include "macros.h" +#include "mem.h" +#include "mmath.h" + +#include "m_matrix.h" +#include "m_xform.h" + +#include "m_debug.h" +#include "m_debug_util.h" + + +#ifdef DEBUG /* This code only used for debugging */ + + +static int m_norm_identity[16] = { + ONE, NIL, NIL, NIL, + NIL, ONE, NIL, NIL, + NIL, NIL, ONE, NIL, + NIL, NIL, NIL, NIL +}; +static int m_norm_general[16] = { + VAR, VAR, VAR, NIL, + VAR, VAR, VAR, NIL, + VAR, VAR, VAR, NIL, + NIL, NIL, NIL, NIL +}; +static int m_norm_no_rot[16] = { + VAR, NIL, NIL, NIL, + NIL, VAR, NIL, NIL, + NIL, NIL, VAR, NIL, + NIL, NIL, NIL, NIL +}; +static int *norm_templates[8] = { + m_norm_no_rot, + m_norm_no_rot, + m_norm_no_rot, + m_norm_general, + m_norm_general, + m_norm_general, + m_norm_identity, + m_norm_identity +}; +static int norm_types[8] = { + NORM_TRANSFORM_NO_ROT, + NORM_TRANSFORM_NO_ROT | NORM_RESCALE, + NORM_TRANSFORM_NO_ROT | NORM_NORMALIZE, + NORM_TRANSFORM, + NORM_TRANSFORM | NORM_RESCALE, + NORM_TRANSFORM | NORM_NORMALIZE, + NORM_RESCALE, + NORM_NORMALIZE +}; +static int norm_scale_types[8] = { /* rescale factor */ + NIL, /* NIL disables rescaling */ + VAR, + NIL, + NIL, + VAR, + NIL, + VAR, + NIL +}; +static int norm_normalize_types[8] = { /* normalizing ?? (no = 0) */ + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 1 +}; +static char *norm_strings[8] = { + "NORM_TRANSFORM_NO_ROT", + "NORM_TRANSFORM_NO_ROT | NORM_RESCALE", + "NORM_TRANSFORM_NO_ROT | NORM_NORMALIZE", + "NORM_TRANSFORM", + "NORM_TRANSFORM | NORM_RESCALE", + "NORM_TRANSFORM | NORM_NORMALIZE", + "NORM_RESCALE", + "NORM_NORMALIZE" +}; + + +/* ============================================================= + * Reference transformations + */ + +static void ref_norm_transform_rescale( const GLmatrix *mat, + GLfloat scale, + const GLvector3f *in, + const GLfloat *lengths, + GLvector3f *dest ) +{ + GLuint i; + const GLfloat *s = in->start; + const GLfloat *m = mat->inv; + GLfloat (*out)[3] = (GLfloat (*)[3])dest->start; + + (void) lengths; + + for ( i = 0 ; i < in->count ; i++ ) { + GLfloat t[3]; + + TRANSFORM_NORMAL( t, s, m ); + SCALE_SCALAR_3V( out[i], scale, t ); + + s = (GLfloat *)((char *)s + in->stride); + } +} + +static void ref_norm_transform_normalize( const GLmatrix *mat, + GLfloat scale, + const GLvector3f *in, + const GLfloat *lengths, + GLvector3f *dest ) +{ + GLuint i; + const GLfloat *s = in->start; + const GLfloat *m = mat->inv; + GLfloat (*out)[3] = (GLfloat (*)[3])dest->start; + + for ( i = 0 ; i < in->count ; i++ ) { + GLfloat t[3]; + + TRANSFORM_NORMAL( t, s, m ); + + if ( !lengths ) { + GLfloat len = LEN_SQUARED_3FV( t ); + if ( len > 1e-20 ) { + /* Hmmm, don't know how we could test the precalculated + * length case... + */ + scale = 1.0 / sqrt( len ); + SCALE_SCALAR_3V( out[i], scale, t ); + } else { + out[i][0] = out[i][1] = out[i][2] = 0; + } + } else { + scale = lengths[i];; + SCALE_SCALAR_3V( out[i], scale, t ); + } + + s = (GLfloat *)((char *)s + in->stride); + } +} + + +/* ============================================================= + * Normal transformation tests + */ + +static int test_norm_function( normal_func func, int mtype, long *cycles ) +{ + GLvector3f source[1], dest[1], dest2[1], ref[1], ref2[1]; + GLmatrix mat[1]; + GLfloat s[TEST_COUNT][5], d[TEST_COUNT][3], r[TEST_COUNT][3]; + GLfloat d2[TEST_COUNT][3], r2[TEST_COUNT][3], length[TEST_COUNT]; + GLfloat scale; + GLfloat *m; + int i, j; +#ifdef RUN_DEBUG_BENCHMARK + int cycle_i; /* the counter for the benchmarks we run */ +#endif + + (void) cycles; + + mat->m = (GLfloat *) ALIGN_MALLOC( 16 * sizeof(GLfloat), 16 ); + mat->inv = m = mat->m; + + init_matrix( m ); + + scale = 1.0F + rnd () * norm_scale_types[mtype]; + + for ( i = 0 ; i < 4 ; i++ ) { + for ( j = 0 ; j < 4 ; j++ ) { + switch ( norm_templates[mtype][i * 4 + j] ) { + case NIL: + m[j * 4 + i] = 0.0; + break; + case ONE: + m[j * 4 + i] = 1.0; + break; + case NEG: + m[j * 4 + i] = -1.0; + break; + case VAR: + break; + default: + abort(); + } + } + } + + for ( i = 0 ; i < TEST_COUNT ; i++ ) { + ASSIGN_3V( d[i], 0.0, 0.0, 0.0 ); + ASSIGN_3V( s[i], 0.0, 0.0, 0.0 ); + ASSIGN_3V( d2[i], 0.0, 0.0, 0.0 ); + for ( j = 0 ; j < 3 ; j++ ) + s[i][j] = rnd(); + length[i] = 1 / sqrt( LEN_SQUARED_3FV( s[i] ) ); + } + + source->data = (GLfloat(*)[3])s; + source->start = (GLfloat *)s; + source->count = TEST_COUNT; + source->stride = sizeof(s[0]); + source->flags = 0; + + dest->data = (GLfloat(*)[3])d; + dest->start = (GLfloat *)d; + dest->count = TEST_COUNT; + dest->stride = sizeof(float[3]); + dest->flags = 0; + + dest2->data = (GLfloat(*)[3])d2; + dest2->start = (GLfloat *)d2; + dest2->count = TEST_COUNT; + dest2->stride = sizeof(float[3]); + dest2->flags = 0; + + ref->data = (GLfloat(*)[3])r; + ref->start = (GLfloat *)r; + ref->count = TEST_COUNT; + ref->stride = sizeof(float[3]); + ref->flags = 0; + + ref2->data = (GLfloat(*)[3])r2; + ref2->start = (GLfloat *)r2; + ref2->count = TEST_COUNT; + ref2->stride = sizeof(float[3]); + ref2->flags = 0; + + if ( norm_normalize_types[mtype] == 0 ) { + ref_norm_transform_rescale( mat, scale, source, NULL, ref ); + } else { + ref_norm_transform_normalize( mat, scale, source, NULL, ref ); + ref_norm_transform_normalize( mat, scale, source, length, ref2 ); + } + + if ( mesa_profile ) { + BEGIN_RACE( *cycles ); + func( mat, scale, source, NULL, dest ); + END_RACE( *cycles ); + func( mat, scale, source, length, dest2 ); + } else { + func( mat, scale, source, NULL, dest ); + func( mat, scale, source, length, dest2 ); + } + + for ( i = 0 ; i < TEST_COUNT ; i++ ) { + for ( j = 0 ; j < 3 ; j++ ) { + if ( significand_match( d[i][j], r[i][j] ) < REQUIRED_PRECISION ) { + printf( "-----------------------------\n" ); + printf( "(i = %i, j = %i)\n", i, j ); + printf( "%f \t %f \t [ratio = %e - %i bit missed]\n", + d[i][0], r[i][0], r[i][0]/d[i][0], + MAX_PRECISION - significand_match( d[i][0], r[i][0] ) ); + printf( "%f \t %f \t [ratio = %e - %i bit missed]\n", + d[i][1], r[i][1], r[i][1]/d[i][1], + MAX_PRECISION - significand_match( d[i][1], r[i][1] ) ); + printf( "%f \t %f \t [ratio = %e - %i bit missed]\n", + d[i][2], r[i][2], r[i][2]/d[i][2], + MAX_PRECISION - significand_match( d[i][2], r[i][2] ) ); + return 0; + } + + if ( norm_normalize_types[mtype] != 0 ) { + if ( significand_match( d2[i][j], r2[i][j] ) < REQUIRED_PRECISION ) { + printf( "------------------- precalculated length case ------\n" ); + printf( "(i = %i, j = %i)\n", i, j ); + printf( "%f \t %f \t [ratio = %e - %i bit missed]\n", + d2[i][0], r2[i][0], r2[i][0]/d2[i][0], + MAX_PRECISION - significand_match( d2[i][0], r2[i][0] ) ); + printf( "%f \t %f \t [ratio = %e - %i bit missed]\n", + d2[i][1], r2[i][1], r2[i][1]/d2[i][1], + MAX_PRECISION - significand_match( d2[i][1], r2[i][1] ) ); + printf( "%f \t %f \t [ratio = %e - %i bit missed]\n", + d2[i][2], r2[i][2], r2[i][2]/d2[i][2], + MAX_PRECISION - significand_match( d2[i][2], r2[i][2] ) ); + return 0; + } + } + } + } + + ALIGN_FREE( mat->m ); + return 1; +} + +void _math_test_all_normal_transform_functions( char *description ) +{ + int mtype; + long benchmark_tab[0xf]; + static int first_time = 1; + + if ( first_time ) { + first_time = 0; + mesa_profile = getenv( "MESA_PROFILE" ); + } + +#ifdef RUN_DEBUG_BENCHMARK + if ( mesa_profile ) { + if ( !counter_overhead ) { + INIT_COUNTER(); + printf( "counter overhead: %ld cycles\n\n", counter_overhead ); + } + printf( "normal transform results after hooking in %s functions:\n", + description ); + printf( "\n-------------------------------------------------------\n" ); + } +#endif + + for ( mtype = 0 ; mtype < 8 ; mtype++ ) { + normal_func func = _mesa_normal_tab[norm_types[mtype]]; + long *cycles = &benchmark_tab[mtype]; + + if ( test_norm_function( func, mtype, cycles ) == 0 ) { + char buf[100]; + sprintf( buf, "_mesa_normal_tab[0][%s] failed test (%s)", + norm_strings[mtype], description ); + _mesa_problem( NULL, buf ); + } + +#ifdef RUN_DEBUG_BENCHMARK + if ( mesa_profile ) { + printf( " %li\t", benchmark_tab[mtype] ); + printf( " | [%s]\n", norm_strings[mtype] ); + } +#endif + } +#ifdef RUN_DEBUG_BENCHMARK + if ( mesa_profile ) { + printf( "\n" ); + fflush( stdout ); + } +#endif +} + + +#endif /* DEBUG */ Index: dll/opengl/opengl32/mesa/math/m_debug_util.h =================================================================== --- dll/opengl/opengl32/mesa/math/m_debug_util.h (revision 0) +++ dll/opengl/opengl32/mesa/math/m_debug_util.h (working copy) @@ -0,0 +1,289 @@ +/* $Id: m_debug_util.h,v 1.4 2001/05/23 14:27:03 brianp Exp $ */ + +/* + * Mesa 3-D graphics library + * Version: 3.5 + * + * Copyright (C) 1999-2001 Brian Paul 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 + * BRIAN PAUL 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. + * + * Authors: + * Gareth Hughes + */ + +#ifndef __M_DEBUG_UTIL_H__ +#define __M_DEBUG_UTIL_H__ + + +#ifdef DEBUG /* This code only used for debugging */ + + +/* Comment this out to deactivate the cycle counter. + * NOTE: it works only on CPUs which know the 'rdtsc' command (586 or higher) + * (hope, you don't try to debug Mesa on a 386 ;) + */ +#if defined(__GNUC__) && \ + ((defined(__i386__) && defined(USE_X86_ASM)) || \ + (defined(__sparc__) && defined(USE_SPARC_ASM))) +#define RUN_DEBUG_BENCHMARK +#endif + +#define TEST_COUNT 128 /* size of the tested vector array */ + +#define REQUIRED_PRECISION 10 /* allow 4 bits to miss */ +#define MAX_PRECISION 24 /* max. precision possible */ + + +#ifdef RUN_DEBUG_BENCHMARK +/* Overhead of profiling counter in cycles. Automatically adjusted to + * your machine at run time - counter initialization should give very + * consistent results. + */ +extern long counter_overhead; + +/* This is the value of the environment variable MESA_PROFILE, and is + * used to determine if we should benchmark the functions as well as + * verify their correctness. + */ +extern char *mesa_profile; + +/* Modify the the number of tests if you like. + * We take the minimum of all results, because every error should be + * positive (time used by other processes, task switches etc). + * It is assumed that all calculations are done in the cache. + */ + +#if defined(__i386__) + +#if 1 /* PPro, PII, PIII version */ + +/* Profiling on the P6 architecture requires a little more work, due to + * the internal out-of-order execution. We must perform a serializing + * 'cpuid' instruction before and after the 'rdtsc' instructions to make + * sure no other uops are executed when we sample the timestamp counter. + */ +#define INIT_COUNTER() \ + do { \ + int cycle_i; \ + counter_overhead = LONG_MAX; \ + for ( cycle_i = 0 ; cycle_i < 8 ; cycle_i++ ) { \ + long cycle_tmp1 = 0, cycle_tmp2 = 0; \ + __asm__ __volatile__ ( "push %%ebx \n" \ + "xor %%eax, %%eax \n" \ + "cpuid \n" \ + "rdtsc \n" \ + "mov %%eax, %0 \n" \ + "xor %%eax, %%eax \n" \ + "cpuid \n" \ + "pop %%ebx \n" \ + "push %%ebx \n" \ + "xor %%eax, %%eax \n" \ + "cpuid \n" \ + "rdtsc \n" \ + "mov %%eax, %1 \n" \ + "xor %%eax, %%eax \n" \ + "cpuid \n" \ + "pop %%ebx \n" \ + : "=m" (cycle_tmp1), "=m" (cycle_tmp2) \ + : : "eax", "ecx", "edx" ); \ + if ( counter_overhead > (cycle_tmp2 - cycle_tmp1) ) { \ + counter_overhead = cycle_tmp2 - cycle_tmp1; \ + } \ + } \ + } while (0) + +#define BEGIN_RACE(x) \ + x = LONG_MAX; \ + for ( cycle_i = 0 ; cycle_i < 10 ; cycle_i++ ) { \ + long cycle_tmp1 = 0, cycle_tmp2 = 0; \ + __asm__ __volatile__ ( "push %%ebx \n" \ + "xor %%eax, %%eax \n" \ + "cpuid \n" \ + "rdtsc \n" \ + "mov %%eax, %0 \n" \ + "xor %%eax, %%eax \n" \ + "cpuid \n" \ + "pop %%ebx \n" \ + : "=m" (cycle_tmp1) \ + : : "eax", "ecx", "edx" ); + +#define END_RACE(x) \ + __asm__ __volatile__ ( "push %%ebx \n" \ + "xor %%eax, %%eax \n" \ + "cpuid \n" \ + "rdtsc \n" \ + "mov %%eax, %0 \n" \ + "xor %%eax, %%eax \n" \ + "cpuid \n" \ + "pop %%ebx \n" \ + : "=m" (cycle_tmp2) \ + : : "eax", "ecx", "edx" ); \ + if ( x > (cycle_tmp2 - cycle_tmp1) ) { \ + x = cycle_tmp2 - cycle_tmp1; \ + } \ + } \ + x -= counter_overhead; + +#else /* PPlain, PMMX version */ + +/* To ensure accurate results, we stall the pipelines with the + * non-pairable 'cdq' instruction. This ensures all the code being + * profiled is complete when the 'rdtsc' instruction executes. + */ +#define INIT_COUNTER(x) \ + do { \ + int cycle_i; \ + x = LONG_MAX; \ + for ( cycle_i = 0 ; cycle_i < 32 ; cycle_i++ ) { \ + long cycle_tmp1, cycle_tmp2, dummy; \ + __asm__ ( "mov %%eax, %0" : "=a" (cycle_tmp1) ); \ + __asm__ ( "mov %%eax, %0" : "=a" (cycle_tmp2) ); \ + __asm__ ( "cdq" ); \ + __asm__ ( "cdq" ); \ + __asm__ ( "rdtsc" : "=a" (cycle_tmp1), "=d" (dummy) ); \ + __asm__ ( "cdq" ); \ + __asm__ ( "cdq" ); \ + __asm__ ( "rdtsc" : "=a" (cycle_tmp2), "=d" (dummy) ); \ + if ( x > (cycle_tmp2 - cycle_tmp1) ) \ + x = cycle_tmp2 - cycle_tmp1; \ + } \ + } while (0) + +#define BEGIN_RACE(x) \ + x = LONG_MAX; \ + for ( cycle_i = 0 ; cycle_i < 16 ; cycle_i++ ) { \ + long cycle_tmp1, cycle_tmp2, dummy; \ + __asm__ ( "mov %%eax, %0" : "=a" (cycle_tmp1) ); \ + __asm__ ( "mov %%eax, %0" : "=a" (cycle_tmp2) ); \ + __asm__ ( "cdq" ); \ + __asm__ ( "cdq" ); \ + __asm__ ( "rdtsc" : "=a" (cycle_tmp1), "=d" (dummy) ); + + +#define END_RACE(x) \ + __asm__ ( "cdq" ); \ + __asm__ ( "cdq" ); \ + __asm__ ( "rdtsc" : "=a" (cycle_tmp2), "=d" (dummy) ); \ + if ( x > (cycle_tmp2 - cycle_tmp1) ) \ + x = cycle_tmp2 - cycle_tmp1; \ + } \ + x -= counter_overhead; + +#endif + +#elif defined(__sparc__) + +#define INIT_COUNTER() \ + do { counter_overhead = 5; } while(0) + +#define BEGIN_RACE(x) \ +x = LONG_MAX; \ +for (cycle_i = 0; cycle_i <10; cycle_i++) { \ + register long cycle_tmp1 asm("l0"); \ + register long cycle_tmp2 asm("l1"); \ + /* rd %tick, %l0 */ \ + __asm__ __volatile__ (".word 0xa1410000" : "=r" (cycle_tmp1)); /* save timestamp */ + +#define END_RACE(x) \ + /* rd %tick, %l1 */ \ + __asm__ __volatile__ (".word 0xa3410000" : "=r" (cycle_tmp2)); \ + if (x > (cycle_tmp2-cycle_tmp1)) x = cycle_tmp2 - cycle_tmp1; \ +} \ +x -= counter_overhead; + +#else +#error Your processor is not supported for RUN_XFORM_BENCHMARK +#endif + +#else + +#define BEGIN_RACE(x) +#define END_RACE(x) + +#endif + + +/* ============================================================= + * Helper functions + */ + +static GLfloat rnd( void ) +{ + GLfloat f = (GLfloat)rand() / (GLfloat)RAND_MAX; + GLfloat gran = (GLfloat)(1 << 13); + + f = (GLfloat)(GLint)(f * gran) / gran; + + return f * 2.0 - 1.0; +} + +static int significand_match( GLfloat a, GLfloat b ) +{ + GLfloat d = a - b; + int a_ex, b_ex, d_ex; + + if ( d == 0.0F ) { + return MAX_PRECISION; /* Exact match */ + } + + if ( a == 0.0F || b == 0.0F ) { + /* It would probably be better to check if the + * non-zero number is denormalized and return + * the index of the highest set bit here. + */ + return 0; + } + + frexp( a, &a_ex ); + frexp( b, &b_ex ); + frexp( d, &d_ex ); + + if ( a_ex < b_ex ) { + return a_ex - d_ex; + } else { + return b_ex - d_ex; + } +} + +enum { NIL = 0, ONE = 1, NEG = -1, VAR = 2 }; + +static void init_matrix( GLfloat *m ) +{ + m[0] = 63.0; m[4] = 43.0; m[ 8] = 29.0; m[12] = 43.0; + m[1] = 55.0; m[5] = 17.0; m[ 9] = 31.0; m[13] = 7.0; + m[2] = 44.0; m[6] = 9.0; m[10] = 7.0; m[14] = 3.0; + m[3] = 11.0; m[7] = 23.0; m[11] = 91.0; m[15] = 9.0; +} + + +/* Ensure our arrays are correctly aligned. + */ +#if defined(__GNUC__) +# define ALIGN16 __attribute__ ((aligned (16))) +#elif defined(__MSC__) +# define ALIGN16 __declspec(align(16)) /* GH: Does this work? */ +#else +# warning "ALIGN16 will not 16-byte align!\n" +# define ALIGN16 +#endif + + +#endif /* DEBUG */ + +#endif /* __M_DEBUG_UTIL_H__ */ Index: dll/opengl/opengl32/mesa/math/m_debug_vertex.c =================================================================== --- dll/opengl/opengl32/mesa/math/m_debug_vertex.c (revision 0) +++ dll/opengl/opengl32/mesa/math/m_debug_vertex.c (working copy) @@ -0,0 +1,538 @@ +/* $Id: m_debug_vertex.c,v 1.5 2001/03/30 14:44:43 gareth Exp $ */ + +/* + * Mesa 3-D graphics library + * Version: 3.5 + * + * Copyright (C) 1999-2001 Brian Paul 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 + * BRIAN PAUL 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. + * + * Authors: + * Gareth Hughes + */ + +#include "glheader.h" +#include "context.h" +#include "macros.h" +#include "mem.h" + +#include "m_matrix.h" +#include "m_vertices.h" +#include "m_xform.h" + +#include "m_debug.h" +#include "m_debug_util.h" + + +#ifdef DEBUG /* This code only used for debugging */ + + +#define NUM_V16_FUNCS 4 + +#ifdef RUN_DEBUG_BENCHMARK +static char *v16_strings[NUM_V16_FUNCS] = { + "_mesa_xform_points3_v16_general", + "_mesa_cliptest_points4_v16", + "_mesa_project_v16", + "_mesa_project_clipped_v16" +}; +#endif + + +/* ============================================================= + * Reference transformations + */ + +static void ref_transform_v16( GLfloat *f, + const GLfloat *m, + const GLfloat *obj, + GLuint obj_stride, + GLuint count ) +{ + GLuint i; + + for ( i = 0 ; i < count ; i++, STRIDE_F(obj, obj_stride), f += 16 ) { + const GLfloat ox = obj[0], oy = obj[1], oz = obj[2]; + f[0] = m[0] * ox + m[4] * oy + m[8] * oz + m[12]; + f[1] = m[1] * ox + m[5] * oy + m[9] * oz + m[13]; + f[2] = m[2] * ox + m[6] * oy + m[10] * oz + m[14]; + f[3] = m[3] * ox + m[7] * oy + m[11] * oz + m[15]; + } +} + +static void ref_cliptest_v16( GLfloat *first, + GLfloat *last, + GLubyte *p_clipOr, + GLubyte *p_clipAnd, + GLubyte *clipmask ) +{ + GLubyte clipAnd = (GLubyte) ~0; + GLubyte clipOr = 0; + GLfloat *f = first; + static int i; + i = 0; + + for ( ; f != last ; f += 16, clipmask++, i++ ) { + const GLfloat cx = f[0]; + const GLfloat cy = f[1]; + const GLfloat cz = f[2]; + const GLfloat cw = f[3]; + GLubyte mask = 0; + + if (cx > cw) mask |= CLIP_RIGHT_BIT; + if (cx < -cw) mask |= CLIP_LEFT_BIT; + if (cy > cw) mask |= CLIP_TOP_BIT; + if (cy < -cw) mask |= CLIP_BOTTOM_BIT; + if (cz > cw) mask |= CLIP_FAR_BIT; + if (cz < -cw) mask |= CLIP_NEAR_BIT; + + *clipmask = mask; + clipAnd &= mask; + clipOr |= mask; + } + + (*p_clipOr) |= clipOr; + (*p_clipAnd) &= clipAnd; +} + +static void ref_project_verts( GLfloat *first, + GLfloat *last, + const GLfloat *m, + GLuint stride ) +{ + const GLfloat sx = m[0], sy = m[5], sz = m[10]; + const GLfloat tx = m[12], ty = m[13], tz = m[14]; + GLfloat *f; + + for (f = first; f != last; STRIDE_F(f, stride)) { + const GLfloat oow = 1.0F / f[3]; + f[0] = sx * f[0] * oow + tx; + f[1] = sy * f[1] * oow + ty; + f[2] = sz * f[2] * oow + tz; + f[3] = oow; + } +} + +static void ref_project_clipped_verts( GLfloat *first, + GLfloat *last, + const GLfloat *m, + GLuint stride, + const GLubyte *clipmask ) +{ + const GLfloat sx = m[0], sy = m[5], sz = m[10]; + const GLfloat tx = m[12], ty = m[13], tz = m[14]; + GLfloat *f; + + for ( f = first ; f != last ; STRIDE_F(f, stride), clipmask++ ) { + if (!(*clipmask)) { + const GLfloat oow = 1.0F / f[3]; + f[0] = sx * f[0] * oow + tx; + f[1] = sy * f[1] * oow + ty; + f[2] = sz * f[2] * oow + tz; + f[3] = oow; + } + } +} + + + +/* ============================================================= + * Vertex transformation, clipping etc tests + */ + +static GLfloat ALIGN16(s[TEST_COUNT][4]); +static GLfloat ALIGN16(d[TEST_COUNT][16]); +static GLfloat ALIGN16(r[TEST_COUNT][16]); + +static int test_transform_function( long *cycles ) +{ + GLvector4f source[1]; + GLfloat *m; + int i, j; +#ifdef RUN_DEBUG_BENCHMARK + int cycle_i; /* the counter for the benchmarks we run */ +#endif + + m = (GLfloat *) ALIGN_MALLOC( 16 * sizeof(GLfloat), 16 ); + + m[0] = 63.0; m[4] = 43.0; m[ 8] = 29.0; m[12] = 43.0; + m[1] = 55.0; m[5] = 17.0; m[ 9] = 31.0; m[13] = 7.0; + m[2] = 44.0; m[6] = 9.0; m[10] = 7.0; m[14] = 3.0; + m[3] = 11.0; m[7] = 23.0; m[11] = 91.0; m[15] = 9.0; + + for ( i = 0 ; i < TEST_COUNT ; i++ ) { + d[i][0] = s[i][0] = 0.0; + d[i][1] = s[i][1] = 0.0; + d[i][2] = s[i][2] = 0.0; + d[i][3] = s[i][3] = 1.0; + for ( j = 0 ; j < 3 ; j++ ) + s[i][j] = rnd(); + } + + source->data = (GLfloat(*)[4])s; + source->start = (GLfloat *)s; + source->count = TEST_COUNT; + source->stride = sizeof(s[0]); + source->size = 4; + source->flags = 0; + + ref_transform_v16( (GLfloat *)r, + m, + source->start, + source->stride, + TEST_COUNT ); + + if ( mesa_profile ) { + BEGIN_RACE( *cycles ); + _mesa_xform_points3_v16_general( (GLfloat *)d, + m, + source->start, + source->stride, + TEST_COUNT ); + END_RACE( *cycles ); + } else { + _mesa_xform_points3_v16_general( (GLfloat *)d, + m, + source->start, + source->stride, + TEST_COUNT ); + } + + ALIGN_FREE( m ); + + for ( i = 0 ; i < TEST_COUNT ; i++ ) { + for ( j = 0 ; j < 4 ; j++ ) { + if ( significand_match( d[i][j], r[i][j] ) < REQUIRED_PRECISION ) { + printf( "-----------------------------\n" ); + printf( "(i = %i, j = %i)\n", i, j ); + printf( "%f \t %f \t [diff = %e - %i bit missed]\n", + d[i][0], r[i][0], r[i][0]-d[i][0], + MAX_PRECISION - significand_match( d[i][0], r[i][0] ) ); + printf( "%f \t %f \t [diff = %e - %i bit missed]\n", + d[i][1], r[i][1], r[i][1]-d[i][1], + MAX_PRECISION - significand_match( d[i][1], r[i][1] ) ); + printf( "%f \t %f \t [diff = %e - %i bit missed]\n", + d[i][2], r[i][2], r[i][2]-d[i][2], + MAX_PRECISION - significand_match( d[i][2], r[i][2] ) ); + printf( "%f \t %f \t [diff = %e - %i bit missed]\n", + d[i][3], r[i][3], r[i][3]-d[i][3], + MAX_PRECISION - significand_match( d[i][3], r[i][3] ) ); + return 0; + } + } + } + + return 1; +} + +static int test_cliptest_function( long *cycles ) +{ + GLvector4f source[1]; + GLubyte dco, dca, rco, rca; + GLubyte dm[TEST_COUNT], rm[TEST_COUNT]; + GLfloat *m; + int i, j; +#ifdef RUN_DEBUG_BENCHMARK + int cycle_i; /* the counter for the benchmarks we run */ +#endif + + m = (GLfloat *) ALIGN_MALLOC( 16 * sizeof(GLfloat), 16 ); + + init_matrix( m ); + + for ( i = 0 ; i < TEST_COUNT ; i++ ) { + d[i][0] = s[i][0] = 0.0; + d[i][1] = s[i][1] = 0.0; + d[i][2] = s[i][2] = 0.0; + d[i][3] = s[i][3] = 1.0; + for ( j = 0 ; j < 3 ; j++ ) + s[i][j] = rnd(); + } + + source->data = (GLfloat(*)[4])s; + source->start = (GLfloat *)s; + source->count = TEST_COUNT; + source->stride = sizeof(s[0]); + source->size = 4; + source->flags = 0; + + /* Build up a reference list of transformed points + */ + ref_transform_v16( (GLfloat *)r, + m, + source->start, + source->stride, + TEST_COUNT ); + + dca = rca = ~0; + dco = rco = 0; + + ref_cliptest_v16( (GLfloat *)r, + (GLfloat *)&r[TEST_COUNT][0], + &rco, + &rca, + &rm[0] ); + + if ( mesa_profile ) { + BEGIN_RACE( *cycles ); + _mesa_cliptest_points4_v16( (GLfloat *)r, + (GLfloat *)&r[TEST_COUNT][0], + &dco, + &dca, + &dm[0] ); + END_RACE( *cycles ); + } else { + _mesa_cliptest_points4_v16( (GLfloat *)r, + (GLfloat *)&r[TEST_COUNT][0], + &dco, + &dca, + dm ); + } + + ALIGN_FREE( m ); + + if ( dco != rco ) { + printf( "-----------------------------\n" ); + printf( "dco = 0x%02x rco = 0x%02x\n", dco, rco ); + return 0; + } + if ( dca != rca ) { + printf( "-----------------------------\n" ); + printf( "dca = 0x%02x rca = 0x%02x\n", dca, rca ); + return 0; + } + for ( i = 0 ; i < TEST_COUNT ; i++ ) { + if ( dm[i] != rm[i] ) { + printf( "-----------------------------\n" ); + printf( "(i = %i)\n", i ); + printf( "dm = 0x%02x rm = 0x%02x\n", dm[i], rm[i] ); + return 0; + } + } + + return 1; +} + +static int test_project_function( long *cycles, int clipped ) +{ + GLvector4f source[1]; + GLubyte co, ca; + GLubyte mask[TEST_COUNT]; + GLfloat *m; + int i, j; +#ifdef RUN_DEBUG_BENCHMARK + int cycle_i; /* the counter for the benchmarks we run */ +#endif + + m = (GLfloat *) ALIGN_MALLOC( 16 * sizeof(GLfloat), 16 ); + + init_matrix( m ); + + for ( i = 0 ; i < TEST_COUNT ; i++ ) { + d[i][0] = s[i][0] = 0.0; + d[i][1] = s[i][1] = 0.0; + d[i][2] = s[i][2] = 0.0; + d[i][3] = s[i][3] = 1.0; + for ( j = 0 ; j < 3 ; j++ ) + s[i][j] = rnd(); + } + + source->data = (GLfloat(*)[4])s; + source->start = (GLfloat *)s; + source->count = TEST_COUNT; + source->stride = sizeof(s[0]); + source->size = 4; + source->flags = 0; + + /* Build up a reference list of transformed points + */ + ref_transform_v16( (GLfloat *)d, + m, + source->start, + source->stride, + TEST_COUNT ); + ref_transform_v16( (GLfloat *)r, + m, + source->start, + source->stride, + TEST_COUNT ); + + if ( clipped ) { + ca = ~0; + co = 0; + ref_cliptest_v16( (GLfloat *)r, + (GLfloat *)&r[TEST_COUNT][0], + &co, + &ca, + mask ); + ref_project_clipped_verts( (GLfloat *)r, + (GLfloat *)&r[TEST_COUNT][0], + m, + 16 * 4, + mask ); + } else { + ref_project_verts( (GLfloat *)r, + (GLfloat *)&r[TEST_COUNT][0], + m, + 16 * 4 ); + } + + if ( mesa_profile ) { + if ( clipped ) { + /*BEGIN_RACE( *cycles );*/ + _mesa_project_clipped_v16( (GLfloat *)d, + (GLfloat *)&d[TEST_COUNT][0], + m, + 16 * 4, + mask ); + /*END_RACE( *cycles );*/ + } else { + /*BEGIN_RACE( *cycles );*/ + _mesa_project_v16( (GLfloat *)d, + (GLfloat *)&d[TEST_COUNT][0], + m, + 16 * 4 ); + /*END_RACE( *cycles );*/ + } + } else { + if ( clipped ) { + _mesa_project_clipped_v16( (GLfloat *)d, + (GLfloat *)&d[TEST_COUNT][0], + m, + 16 * 4, + mask ); + } else { + _mesa_project_v16( (GLfloat *)d, + (GLfloat *)&d[TEST_COUNT][0], + m, + 16 * 4 ); + } + } + + ALIGN_FREE( m ); + + for ( i = 0 ; i < TEST_COUNT ; i++ ) { + for ( j = 0 ; j < 4 ; j++ ) { + if ( significand_match( d[i][j], r[i][j] ) < REQUIRED_PRECISION ) { + printf( "-----------------------------\n" ); + printf( "(i = %i, j = %i)\n", i, j ); + printf( "%f \t %f \t [diff = %e - %i bit missed]\n", + d[i][0], r[i][0], r[i][0]-d[i][0], + MAX_PRECISION - significand_match( d[i][0], r[i][0] ) ); + printf( "%f \t %f \t [diff = %e - %i bit missed]\n", + d[i][1], r[i][1], r[i][1]-d[i][1], + MAX_PRECISION - significand_match( d[i][1], r[i][1] ) ); + printf( "%f \t %f \t [diff = %e - %i bit missed]\n", + d[i][2], r[i][2], r[i][2]-d[i][2], + MAX_PRECISION - significand_match( d[i][2], r[i][2] ) ); + printf( "%f \t %f \t [diff = %e - %i bit missed]\n", + d[i][3], r[i][3], r[i][3]-d[i][3], + MAX_PRECISION - significand_match( d[i][3], r[i][3] ) ); + return 0; + } + } + } + + return 1; +} + +void _math_test_all_vertex_functions( char *description ) +{ + long benchmark_tab[NUM_V16_FUNCS]; + long *cycles; + static int first_time = 1; + + if ( first_time ) { + first_time = 0; + mesa_profile = getenv( "MESA_PROFILE" ); + } + +#ifdef RUN_DEBUG_BENCHMARK + if ( mesa_profile ) { + int i; + if ( !counter_overhead ) { + INIT_COUNTER(); + printf( "counter overhead: %ld cycles\n\n", counter_overhead ); + } + printf( "fastpath vertex results after hooking in %s functions:\n", + description ); + printf( "\n--------------------------------------------------------\n" ); + + for ( i = 0 ; i < NUM_V16_FUNCS ; i++ ) { + benchmark_tab[i] = 0; + } + } +#endif + + /* Test fastpath transformation + */ + cycles = &benchmark_tab[0]; + + if ( test_transform_function( cycles ) == 0 ) { + char buf[100]; + sprintf( buf, "_mesa_xform_points3_v16_general failed test (%s)", + description ); + _mesa_problem( NULL, buf ); + } + + /* Test fastpath clipping + */ + cycles = &benchmark_tab[1]; + + if ( test_cliptest_function( cycles ) == 0 ) { + char buf[100]; + sprintf( buf, "_mesa_cliptest_points4_v16 failed test (%s)", + description ); + _mesa_problem( NULL, buf ); + } + + /* Test fastpath projection + */ + cycles = &benchmark_tab[2]; + + if ( test_project_function( cycles, 0 ) == 0 ) { + char buf[100]; + sprintf( buf, "_mesa_project_v16 failed test (%s)", + description ); + _mesa_problem( NULL, buf ); + } + + cycles = &benchmark_tab[3]; + + if ( test_project_function( cycles, 1 ) == 0 ) { + char buf[100]; + sprintf( buf, "_mesa_project_clipped_v16 failed test (%s)", + description ); + _mesa_problem( NULL, buf ); + } + + +#ifdef RUN_DEBUG_BENCHMARK + if ( mesa_profile ) { + int i; + for ( i = 0 ; i < NUM_V16_FUNCS ; i++ ) { + printf( " %li\t | [%s]\n", benchmark_tab[i], v16_strings[i] ); + } + printf( "\n" ); + } +#endif +} + + +#endif /* DEBUG */ Index: dll/opengl/opengl32/mesa/math/m_debug_xform.c =================================================================== --- dll/opengl/opengl32/mesa/math/m_debug_xform.c (revision 0) +++ dll/opengl/opengl32/mesa/math/m_debug_xform.c (working copy) @@ -0,0 +1,327 @@ +/* $Id: m_debug_xform.c,v 1.8 2001/03/30 14:44:43 gareth Exp $ */ + +/* + * Mesa 3-D graphics library + * Version: 3.5 + * + * Copyright (C) 1999-2001 Brian Paul 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 + * BRIAN PAUL 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. + */ + +/* + * Updated for P6 architecture by Gareth Hughes. + */ + +#include "glheader.h" +#include "context.h" +#include "macros.h" +#include "mem.h" + +#include "m_matrix.h" +#include "m_xform.h" + +#include "m_debug.h" +#include "m_debug_util.h" + +#ifdef DEBUG /* This code only used for debugging */ + + +/* Overhead of profiling counter in cycles. Automatically adjusted to + * your machine at run time - counter initialization should give very + * consistent results. + */ +long counter_overhead = 0; + +/* This is the value of the environment variable MESA_PROFILE, and is + * used to determine if we should benchmark the functions as well as + * verify their correctness. + */ +char *mesa_profile = NULL; + + +static int m_general[16] = { + VAR, VAR, VAR, VAR, + VAR, VAR, VAR, VAR, + VAR, VAR, VAR, VAR, + VAR, VAR, VAR, VAR +}; +static int m_identity[16] = { + ONE, NIL, NIL, NIL, + NIL, ONE, NIL, NIL, + NIL, NIL, ONE, NIL, + NIL, NIL, NIL, ONE +}; +static int m_2d[16] = { + VAR, VAR, NIL, VAR, + VAR, VAR, NIL, VAR, + NIL, NIL, ONE, NIL, + NIL, NIL, NIL, ONE +}; +static int m_2d_no_rot[16] = { + VAR, NIL, NIL, VAR, + NIL, VAR, NIL, VAR, + NIL, NIL, ONE, NIL, + NIL, NIL, NIL, ONE +}; +static int m_3d[16] = { + VAR, VAR, VAR, VAR, + VAR, VAR, VAR, VAR, + VAR, VAR, VAR, VAR, + NIL, NIL, NIL, ONE +}; +static int m_3d_no_rot[16] = { + VAR, NIL, NIL, VAR, + NIL, VAR, NIL, VAR, + NIL, NIL, VAR, VAR, + NIL, NIL, NIL, ONE +}; +static int m_perspective[16] = { + VAR, NIL, VAR, NIL, + NIL, VAR, VAR, NIL, + NIL, NIL, VAR, VAR, + NIL, NIL, NEG, NIL +}; +static int *templates[7] = { + m_general, + m_identity, + m_3d_no_rot, + m_perspective, + m_2d, + m_2d_no_rot, + m_3d +}; +static int mtypes[7] = { + MATRIX_GENERAL, + MATRIX_IDENTITY, + MATRIX_3D_NO_ROT, + MATRIX_PERSPECTIVE, + MATRIX_2D, + MATRIX_2D_NO_ROT, + MATRIX_3D +}; +static char *mstrings[7] = { + "MATRIX_GENERAL", + "MATRIX_IDENTITY", + "MATRIX_3D_NO_ROT", + "MATRIX_PERSPECTIVE", + "MATRIX_2D", + "MATRIX_2D_NO_ROT", + "MATRIX_3D" +}; + + +/* ============================================================= + * Reference transformations + */ + +static void ref_transform( GLvector4f *dst, + const GLmatrix *mat, + const GLvector4f *src ) +{ + GLuint i; + GLfloat *s = (GLfloat *)src->start; + GLfloat (*d)[4] = (GLfloat (*)[4])dst->start; + const GLfloat *m = mat->m; + + for ( i = 0 ; i < src->count ; i++ ) { + TRANSFORM_POINT( d[i], m, s ); + s = (GLfloat *)((char *)s + src->stride); + } +} + + +/* ============================================================= + * Vertex transformation tests + */ + +static GLfloat s[TEST_COUNT][4] ALIGN16; +static GLfloat d[TEST_COUNT][4] ALIGN16; +static GLfloat r[TEST_COUNT][4] ALIGN16; + +static int test_transform_function( transform_func func, int psize, + int mtype, long *cycles ) +{ + GLvector4f source[1], dest[1], ref[1]; + GLmatrix mat[1]; + GLfloat *m; + int i, j; +#ifdef RUN_DEBUG_BENCHMARK + int cycle_i; /* the counter for the benchmarks we run */ +#endif + + (void) cycles; + + if ( psize > 4 ) { + _mesa_problem( NULL, "test_transform_function called with psize > 4\n" ); + return 0; + } + + mat->m = (GLfloat *) ALIGN_MALLOC( 16 * sizeof(GLfloat), 16 ); + mat->type = mtypes[mtype]; + + m = mat->m; + ASSERT( ((GLuint)m & 15) == 0 ); + + init_matrix( m ); + + for ( i = 0 ; i < 4 ; i++ ) { + for ( j = 0 ; j < 4 ; j++ ) { + switch ( templates[mtype][i * 4 + j] ) { + case NIL: + m[j * 4 + i] = 0.0; + break; + case ONE: + m[j * 4 + i] = 1.0; + break; + case NEG: + m[j * 4 + i] = -1.0; + break; + case VAR: + break; + default: + abort(); + } + } + } + + for ( i = 0 ; i < TEST_COUNT ; i++) { + ASSIGN_4V( d[i], 0.0, 0.0, 0.0, 1.0 ); + ASSIGN_4V( s[i], 0.0, 0.0, 0.0, 1.0 ); + for ( j = 0 ; j < psize ; j++ ) + s[i][j] = rnd(); + } + + source->data = (GLfloat(*)[4])s; + source->start = (GLfloat *)s; + source->count = TEST_COUNT; + source->stride = sizeof(s[0]); + source->size = 4; + source->flags = 0; + + dest->data = (GLfloat(*)[4])d; + dest->start = (GLfloat *)d; + dest->count = TEST_COUNT; + dest->stride = sizeof(float[4]); + dest->size = 0; + dest->flags = 0; + + ref->data = (GLfloat(*)[4])r; + ref->start = (GLfloat *)r; + ref->count = TEST_COUNT; + ref->stride = sizeof(float[4]); + ref->size = 0; + ref->flags = 0; + + ref_transform( ref, mat, source ); + + if ( mesa_profile ) { + BEGIN_RACE( *cycles ); + func( dest, mat->m, source ); + END_RACE( *cycles ); + } + else { + func( dest, mat->m, source ); + } + + for ( i = 0 ; i < TEST_COUNT ; i++ ) { + for ( j = 0 ; j < 4 ; j++ ) { + if ( significand_match( d[i][j], r[i][j] ) < REQUIRED_PRECISION ) { + printf( "-----------------------------\n" ); + printf( "(i = %i, j = %i)\n", i, j ); + printf( "%f \t %f \t [diff = %e - %i bit missed]\n", + d[i][0], r[i][0], r[i][0]-d[i][0], + MAX_PRECISION - significand_match( d[i][0], r[i][0] ) ); + printf( "%f \t %f \t [diff = %e - %i bit missed]\n", + d[i][1], r[i][1], r[i][1]-d[i][1], + MAX_PRECISION - significand_match( d[i][1], r[i][1] ) ); + printf( "%f \t %f \t [diff = %e - %i bit missed]\n", + d[i][2], r[i][2], r[i][2]-d[i][2], + MAX_PRECISION - significand_match( d[i][2], r[i][2] ) ); + printf( "%f \t %f \t [diff = %e - %i bit missed]\n", + d[i][3], r[i][3], r[i][3]-d[i][3], + MAX_PRECISION - significand_match( d[i][3], r[i][3] ) ); + return 0; + } + } + } + + ALIGN_FREE( mat->m ); + return 1; +} + +void _math_test_all_transform_functions( char *description ) +{ + int psize, mtype; + long benchmark_tab[4][7]; + static int first_time = 1; + + if ( first_time ) { + first_time = 0; + mesa_profile = getenv( "MESA_PROFILE" ); + } + +#ifdef RUN_DEBUG_BENCHMARK + if ( mesa_profile ) { + if ( !counter_overhead ) { + INIT_COUNTER(); + printf( "counter overhead: %ld cycles\n\n", counter_overhead ); + } + printf( "transform results after hooking in %s functions:\n", description ); + } +#endif + +#ifdef RUN_DEBUG_BENCHMARK + if ( mesa_profile ) { + printf( "\n" ); + for ( psize = 1 ; psize <= 4 ; psize++ ) { + printf( " p%d\t", psize ); + } + printf( "\n--------------------------------------------------------\n" ); + } +#endif + + for ( mtype = 0 ; mtype < 7 ; mtype++ ) { + for ( psize = 1 ; psize <= 4 ; psize++ ) { + transform_func func = _mesa_transform_tab[psize][mtypes[mtype]]; + long *cycles = &(benchmark_tab[psize-1][mtype]); + + if ( test_transform_function( func, psize, mtype, cycles ) == 0 ) { + char buf[100]; + sprintf( buf, "_mesa_transform_tab[0][%d][%s] failed test (%s)", + psize, mstrings[mtype], description ); + _mesa_problem( NULL, buf ); + } +#ifdef RUN_DEBUG_BENCHMARK + if ( mesa_profile ) + printf( " %li\t", benchmark_tab[psize-1][mtype] ); +#endif + } +#ifdef RUN_DEBUG_BENCHMARK + if ( mesa_profile ) + printf( " | [%s]\n", mstrings[mtype] ); +#endif + } +#ifdef RUN_DEBUG_BENCHMARK + if ( mesa_profile ) + printf( "\n" ); +#endif +} + + +#endif /* DEBUG */ Index: dll/opengl/opengl32/mesa/math/m_dotprod_tmp.h =================================================================== --- dll/opengl/opengl32/mesa/math/m_dotprod_tmp.h (revision 0) +++ dll/opengl/opengl32/mesa/math/m_dotprod_tmp.h (working copy) @@ -0,0 +1,103 @@ +/* $Id: m_dotprod_tmp.h,v 1.6 2001/03/30 14:44:43 gareth Exp $ */ + +/* + * Mesa 3-D graphics library + * Version: 3.5 + * + * Copyright (C) 1999-2001 Brian Paul 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 + * BRIAN PAUL 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. + */ + +/* + * New (3.1) transformation code written by Keith Whitwell. + */ + + +/* Note - respects the stride of the output vector. + */ +static void TAG(dotprod_vec2)( GLfloat *out, + GLuint outstride, + const GLvector4f *coord_vec, + const GLfloat plane[4] ) +{ + GLuint stride = coord_vec->stride; + GLfloat *coord = coord_vec->start; + GLuint count = coord_vec->count; + + GLuint i; + + const GLfloat plane0 = plane[0], plane1 = plane[1], plane3 = plane[3]; + + for (i=0;istride; + GLfloat *coord = coord_vec->start; + GLuint count = coord_vec->count; + + GLuint i; + + const GLfloat plane0 = plane[0], plane1 = plane[1], plane2 = plane[2]; + const GLfloat plane3 = plane[3]; + + for (i=0;istride; + GLfloat *coord = coord_vec->start; + GLuint count = coord_vec->count; + GLuint i; + + const GLfloat plane0 = plane[0], plane1 = plane[1], plane2 = plane[2]; + const GLfloat plane3 = plane[3]; + + for (i=0;i= 2) { + bincoeff = (GLfloat) (order - 1); + s = 1.0 - t; + + for (k = 0; k < dim; k++) + out[k] = s * cp[k] + bincoeff * t * cp[dim + k]; + + for (i = 2, cp += 2 * dim, powert = t * t; i < order; + i++, powert *= t, cp += dim) { + bincoeff *= (GLfloat) (order - i); + bincoeff *= inv_tab[i]; + + for (k = 0; k < dim; k++) + out[k] = s * out[k] + bincoeff * powert * cp[k]; + } + } + else { /* order=1 -> constant curve */ + + for (k = 0; k < dim; k++) + out[k] = cp[k]; + } +} + +/* + * Tensor product Bezier surfaces + * + * Again the Horner scheme is used to compute a point on a + * TP Bezier surface. First a control polygon for a curve + * on the surface in one parameter direction is computed, + * then the point on the curve for the other parameter + * direction is evaluated. + * + * To store the curve control polygon additional storage + * for max(uorder,vorder) points is needed in the + * control net cn. + */ + +void +_math_horner_bezier_surf(GLfloat * cn, GLfloat * out, GLfloat u, GLfloat v, + GLuint dim, GLuint uorder, GLuint vorder) +{ + GLfloat *cp = cn + uorder * vorder * dim; + GLuint i, uinc = vorder * dim; + + if (vorder > uorder) { + if (uorder >= 2) { + GLfloat s, poweru, bincoeff; + GLuint j, k; + + /* Compute the control polygon for the surface-curve in u-direction */ + for (j = 0; j < vorder; j++) { + GLfloat *ucp = &cn[j * dim]; + + /* Each control point is the point for parameter u on a */ + /* curve defined by the control polygons in u-direction */ + bincoeff = (GLfloat) (uorder - 1); + s = 1.0 - u; + + for (k = 0; k < dim; k++) + cp[j * dim + k] = s * ucp[k] + bincoeff * u * ucp[uinc + k]; + + for (i = 2, ucp += 2 * uinc, poweru = u * u; i < uorder; + i++, poweru *= u, ucp += uinc) { + bincoeff *= (GLfloat) (uorder - i); + bincoeff *= inv_tab[i]; + + for (k = 0; k < dim; k++) + cp[j * dim + k] = + s * cp[j * dim + k] + bincoeff * poweru * ucp[k]; + } + } + + /* Evaluate curve point in v */ + _math_horner_bezier_curve(cp, out, v, dim, vorder); + } + else /* uorder=1 -> cn defines a curve in v */ + _math_horner_bezier_curve(cn, out, v, dim, vorder); + } + else { /* vorder <= uorder */ + + if (vorder > 1) { + GLuint i; + + /* Compute the control polygon for the surface-curve in u-direction */ + for (i = 0; i < uorder; i++, cn += uinc) { + /* For constant i all cn[i][j] (j=0..vorder) are located */ + /* on consecutive memory locations, so we can use */ + /* horner_bezier_curve to compute the control points */ + + _math_horner_bezier_curve(cn, &cp[i * dim], v, dim, vorder); + } + + /* Evaluate curve point in u */ + _math_horner_bezier_curve(cp, out, u, dim, uorder); + } + else /* vorder=1 -> cn defines a curve in u */ + _math_horner_bezier_curve(cn, out, u, dim, uorder); + } +} + +/* + * The direct de Casteljau algorithm is used when a point on the + * surface and the tangent directions spanning the tangent plane + * should be computed (this is needed to compute normals to the + * surface). In this case the de Casteljau algorithm approach is + * nicer because a point and the partial derivatives can be computed + * at the same time. To get the correct tangent length du and dv + * must be multiplied with the (u2-u1)/uorder-1 and (v2-v1)/vorder-1. + * Since only the directions are needed, this scaling step is omitted. + * + * De Casteljau needs additional storage for uorder*vorder + * values in the control net cn. + */ + +void +_math_de_casteljau_surf(GLfloat * cn, GLfloat * out, GLfloat * du, + GLfloat * dv, GLfloat u, GLfloat v, GLuint dim, + GLuint uorder, GLuint vorder) +{ + GLfloat *dcn = cn + uorder * vorder * dim; + GLfloat us = 1.0 - u, vs = 1.0 - v; + GLuint h, i, j, k; + GLuint minorder = uorder < vorder ? uorder : vorder; + GLuint uinc = vorder * dim; + GLuint dcuinc = vorder; + + /* Each component is evaluated separately to save buffer space */ + /* This does not drasticaly decrease the performance of the */ + /* algorithm. If additional storage for (uorder-1)*(vorder-1) */ + /* points would be available, the components could be accessed */ + /* in the innermost loop which could lead to less cache misses. */ + +#define CN(I,J,K) cn[(I)*uinc+(J)*dim+(K)] +#define DCN(I, J) dcn[(I)*dcuinc+(J)] + if (minorder < 3) { + if (uorder == vorder) { + for (k = 0; k < dim; k++) { + /* Derivative direction in u */ + du[k] = vs * (CN(1, 0, k) - CN(0, 0, k)) + + v * (CN(1, 1, k) - CN(0, 1, k)); + + /* Derivative direction in v */ + dv[k] = us * (CN(0, 1, k) - CN(0, 0, k)) + + u * (CN(1, 1, k) - CN(1, 0, k)); + + /* bilinear de Casteljau step */ + out[k] = us * (vs * CN(0, 0, k) + v * CN(0, 1, k)) + + u * (vs * CN(1, 0, k) + v * CN(1, 1, k)); + } + } + else if (minorder == uorder) { + for (k = 0; k < dim; k++) { + /* bilinear de Casteljau step */ + DCN(1, 0) = CN(1, 0, k) - CN(0, 0, k); + DCN(0, 0) = us * CN(0, 0, k) + u * CN(1, 0, k); + + for (j = 0; j < vorder - 1; j++) { + /* for the derivative in u */ + DCN(1, j + 1) = CN(1, j + 1, k) - CN(0, j + 1, k); + DCN(1, j) = vs * DCN(1, j) + v * DCN(1, j + 1); + + /* for the `point' */ + DCN(0, j + 1) = us * CN(0, j + 1, k) + u * CN(1, j + 1, k); + DCN(0, j) = vs * DCN(0, j) + v * DCN(0, j + 1); + } + + /* remaining linear de Casteljau steps until the second last step */ + for (h = minorder; h < vorder - 1; h++) + for (j = 0; j < vorder - h; j++) { + /* for the derivative in u */ + DCN(1, j) = vs * DCN(1, j) + v * DCN(1, j + 1); + + /* for the `point' */ + DCN(0, j) = vs * DCN(0, j) + v * DCN(0, j + 1); + } + + /* derivative direction in v */ + dv[k] = DCN(0, 1) - DCN(0, 0); + + /* derivative direction in u */ + du[k] = vs * DCN(1, 0) + v * DCN(1, 1); + + /* last linear de Casteljau step */ + out[k] = vs * DCN(0, 0) + v * DCN(0, 1); + } + } + else { /* minorder == vorder */ + + for (k = 0; k < dim; k++) { + /* bilinear de Casteljau step */ + DCN(0, 1) = CN(0, 1, k) - CN(0, 0, k); + DCN(0, 0) = vs * CN(0, 0, k) + v * CN(0, 1, k); + for (i = 0; i < uorder - 1; i++) { + /* for the derivative in v */ + DCN(i + 1, 1) = CN(i + 1, 1, k) - CN(i + 1, 0, k); + DCN(i, 1) = us * DCN(i, 1) + u * DCN(i + 1, 1); + + /* for the `point' */ + DCN(i + 1, 0) = vs * CN(i + 1, 0, k) + v * CN(i + 1, 1, k); + DCN(i, 0) = us * DCN(i, 0) + u * DCN(i + 1, 0); + } + + /* remaining linear de Casteljau steps until the second last step */ + for (h = minorder; h < uorder - 1; h++) + for (i = 0; i < uorder - h; i++) { + /* for the derivative in v */ + DCN(i, 1) = us * DCN(i, 1) + u * DCN(i + 1, 1); + + /* for the `point' */ + DCN(i, 0) = us * DCN(i, 0) + u * DCN(i + 1, 0); + } + + /* derivative direction in u */ + du[k] = DCN(1, 0) - DCN(0, 0); + + /* derivative direction in v */ + dv[k] = us * DCN(0, 1) + u * DCN(1, 1); + + /* last linear de Casteljau step */ + out[k] = us * DCN(0, 0) + u * DCN(1, 0); + } + } + } + else if (uorder == vorder) { + for (k = 0; k < dim; k++) { + /* first bilinear de Casteljau step */ + for (i = 0; i < uorder - 1; i++) { + DCN(i, 0) = us * CN(i, 0, k) + u * CN(i + 1, 0, k); + for (j = 0; j < vorder - 1; j++) { + DCN(i, j + 1) = us * CN(i, j + 1, k) + u * CN(i + 1, j + 1, k); + DCN(i, j) = vs * DCN(i, j) + v * DCN(i, j + 1); + } + } + + /* remaining bilinear de Casteljau steps until the second last step */ + for (h = 2; h < minorder - 1; h++) + for (i = 0; i < uorder - h; i++) { + DCN(i, 0) = us * DCN(i, 0) + u * DCN(i + 1, 0); + for (j = 0; j < vorder - h; j++) { + DCN(i, j + 1) = us * DCN(i, j + 1) + u * DCN(i + 1, j + 1); + DCN(i, j) = vs * DCN(i, j) + v * DCN(i, j + 1); + } + } + + /* derivative direction in u */ + du[k] = vs * (DCN(1, 0) - DCN(0, 0)) + v * (DCN(1, 1) - DCN(0, 1)); + + /* derivative direction in v */ + dv[k] = us * (DCN(0, 1) - DCN(0, 0)) + u * (DCN(1, 1) - DCN(1, 0)); + + /* last bilinear de Casteljau step */ + out[k] = us * (vs * DCN(0, 0) + v * DCN(0, 1)) + + u * (vs * DCN(1, 0) + v * DCN(1, 1)); + } + } + else if (minorder == uorder) { + for (k = 0; k < dim; k++) { + /* first bilinear de Casteljau step */ + for (i = 0; i < uorder - 1; i++) { + DCN(i, 0) = us * CN(i, 0, k) + u * CN(i + 1, 0, k); + for (j = 0; j < vorder - 1; j++) { + DCN(i, j + 1) = us * CN(i, j + 1, k) + u * CN(i + 1, j + 1, k); + DCN(i, j) = vs * DCN(i, j) + v * DCN(i, j + 1); + } + } + + /* remaining bilinear de Casteljau steps until the second last step */ + for (h = 2; h < minorder - 1; h++) + for (i = 0; i < uorder - h; i++) { + DCN(i, 0) = us * DCN(i, 0) + u * DCN(i + 1, 0); + for (j = 0; j < vorder - h; j++) { + DCN(i, j + 1) = us * DCN(i, j + 1) + u * DCN(i + 1, j + 1); + DCN(i, j) = vs * DCN(i, j) + v * DCN(i, j + 1); + } + } + + /* last bilinear de Casteljau step */ + DCN(2, 0) = DCN(1, 0) - DCN(0, 0); + DCN(0, 0) = us * DCN(0, 0) + u * DCN(1, 0); + for (j = 0; j < vorder - 1; j++) { + /* for the derivative in u */ + DCN(2, j + 1) = DCN(1, j + 1) - DCN(0, j + 1); + DCN(2, j) = vs * DCN(2, j) + v * DCN(2, j + 1); + + /* for the `point' */ + DCN(0, j + 1) = us * DCN(0, j + 1) + u * DCN(1, j + 1); + DCN(0, j) = vs * DCN(0, j) + v * DCN(0, j + 1); + } + + /* remaining linear de Casteljau steps until the second last step */ + for (h = minorder; h < vorder - 1; h++) + for (j = 0; j < vorder - h; j++) { + /* for the derivative in u */ + DCN(2, j) = vs * DCN(2, j) + v * DCN(2, j + 1); + + /* for the `point' */ + DCN(0, j) = vs * DCN(0, j) + v * DCN(0, j + 1); + } + + /* derivative direction in v */ + dv[k] = DCN(0, 1) - DCN(0, 0); + + /* derivative direction in u */ + du[k] = vs * DCN(2, 0) + v * DCN(2, 1); + + /* last linear de Casteljau step */ + out[k] = vs * DCN(0, 0) + v * DCN(0, 1); + } + } + else { /* minorder == vorder */ + + for (k = 0; k < dim; k++) { + /* first bilinear de Casteljau step */ + for (i = 0; i < uorder - 1; i++) { + DCN(i, 0) = us * CN(i, 0, k) + u * CN(i + 1, 0, k); + for (j = 0; j < vorder - 1; j++) { + DCN(i, j + 1) = us * CN(i, j + 1, k) + u * CN(i + 1, j + 1, k); + DCN(i, j) = vs * DCN(i, j) + v * DCN(i, j + 1); + } + } + + /* remaining bilinear de Casteljau steps until the second last step */ + for (h = 2; h < minorder - 1; h++) + for (i = 0; i < uorder - h; i++) { + DCN(i, 0) = us * DCN(i, 0) + u * DCN(i + 1, 0); + for (j = 0; j < vorder - h; j++) { + DCN(i, j + 1) = us * DCN(i, j + 1) + u * DCN(i + 1, j + 1); + DCN(i, j) = vs * DCN(i, j) + v * DCN(i, j + 1); + } + } + + /* last bilinear de Casteljau step */ + DCN(0, 2) = DCN(0, 1) - DCN(0, 0); + DCN(0, 0) = vs * DCN(0, 0) + v * DCN(0, 1); + for (i = 0; i < uorder - 1; i++) { + /* for the derivative in v */ + DCN(i + 1, 2) = DCN(i + 1, 1) - DCN(i + 1, 0); + DCN(i, 2) = us * DCN(i, 2) + u * DCN(i + 1, 2); + + /* for the `point' */ + DCN(i + 1, 0) = vs * DCN(i + 1, 0) + v * DCN(i + 1, 1); + DCN(i, 0) = us * DCN(i, 0) + u * DCN(i + 1, 0); + } + + /* remaining linear de Casteljau steps until the second last step */ + for (h = minorder; h < uorder - 1; h++) + for (i = 0; i < uorder - h; i++) { + /* for the derivative in v */ + DCN(i, 2) = us * DCN(i, 2) + u * DCN(i + 1, 2); + + /* for the `point' */ + DCN(i, 0) = us * DCN(i, 0) + u * DCN(i + 1, 0); + } + + /* derivative direction in u */ + du[k] = DCN(1, 0) - DCN(0, 0); + + /* derivative direction in v */ + dv[k] = us * DCN(0, 2) + u * DCN(1, 2); + + /* last linear de Casteljau step */ + out[k] = us * DCN(0, 0) + u * DCN(1, 0); + } + } +#undef DCN +#undef CN +} + + +/* + * Do one-time initialization for evaluators. + */ +void +_math_init_eval(void) +{ + GLuint i; + + /* KW: precompute 1/x for useful x. + */ + for (i = 1; i < MAX_EVAL_ORDER; i++) + inv_tab[i] = 1.0 / i; +} Index: dll/opengl/opengl32/mesa/math/m_eval.h =================================================================== --- dll/opengl/opengl32/mesa/math/m_eval.h (revision 0) +++ dll/opengl/opengl32/mesa/math/m_eval.h (working copy) @@ -0,0 +1,104 @@ +/* $Id: m_eval.h,v 1.2 2001/03/12 00:48:41 gareth Exp $ */ + +/* + * Mesa 3-D graphics library + * Version: 3.5 + * + * Copyright (C) 1999-2001 Brian Paul 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 + * BRIAN PAUL 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. + */ + +#ifndef _M_EVAL_H +#define _M_EVAL_H + +#include "glheader.h" + +void _math_init_eval( void ); + + +/* + * Horner scheme for Bezier curves + * + * Bezier curves can be computed via a Horner scheme. + * Horner is numerically less stable than the de Casteljau + * algorithm, but it is faster. For curves of degree n + * the complexity of Horner is O(n) and de Casteljau is O(n^2). + * Since stability is not important for displaying curve + * points I decided to use the Horner scheme. + * + * A cubic Bezier curve with control points b0, b1, b2, b3 can be + * written as + * + * (([3] [3] ) [3] ) [3] + * c(t) = (([0]*s*b0 + [1]*t*b1)*s + [2]*t^2*b2)*s + [3]*t^2*b3 + * + * [n] + * where s=1-t and the binomial coefficients [i]. These can + * be computed iteratively using the identity: + * + * [n] [n ] [n] + * [i] = (n-i+1)/i * [i-1] and [0] = 1 + */ + + +void +_math_horner_bezier_curve(const GLfloat *cp, GLfloat *out, GLfloat t, + GLuint dim, GLuint order); + + +/* + * Tensor product Bezier surfaces + * + * Again the Horner scheme is used to compute a point on a + * TP Bezier surface. First a control polygon for a curve + * on the surface in one parameter direction is computed, + * then the point on the curve for the other parameter + * direction is evaluated. + * + * To store the curve control polygon additional storage + * for max(uorder,vorder) points is needed in the + * control net cn. + */ + +void +_math_horner_bezier_surf(GLfloat *cn, GLfloat *out, GLfloat u, GLfloat v, + GLuint dim, GLuint uorder, GLuint vorder); + + +/* + * The direct de Casteljau algorithm is used when a point on the + * surface and the tangent directions spanning the tangent plane + * should be computed (this is needed to compute normals to the + * surface). In this case the de Casteljau algorithm approach is + * nicer because a point and the partial derivatives can be computed + * at the same time. To get the correct tangent length du and dv + * must be multiplied with the (u2-u1)/uorder-1 and (v2-v1)/vorder-1. + * Since only the directions are needed, this scaling step is omitted. + * + * De Casteljau needs additional storage for uorder*vorder + * values in the control net cn. + */ + +void +_math_de_casteljau_surf(GLfloat *cn, GLfloat *out, GLfloat *du, GLfloat *dv, + GLfloat u, GLfloat v, GLuint dim, + GLuint uorder, GLuint vorder); + + +#endif Index: dll/opengl/opengl32/mesa/math/m_matrix.c =================================================================== --- dll/opengl/opengl32/mesa/math/m_matrix.c (revision 0) +++ dll/opengl/opengl32/mesa/math/m_matrix.c (working copy) @@ -0,0 +1,1114 @@ +/* $Id: m_matrix.c,v 1.8 2001/03/12 00:48:41 gareth Exp $ */ + +/* + * Mesa 3-D graphics library + * Version: 3.5 + * + * Copyright (C) 1999-2001 Brian Paul 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 + * BRIAN PAUL 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. + */ + + +/* + * Matrix operations + * + * NOTES: + * 1. 4x4 transformation matrices are stored in memory in column major order. + * 2. Points/vertices are to be thought of as column vectors. + * 3. Transformation of a point p by a matrix M is: p' = M * p + */ + +#include + +#include "glheader.h" +#include "macros.h" +#include "mem.h" +#include "mmath.h" + +#include "m_matrix.h" + + +static const char *types[] = { + "MATRIX_GENERAL", + "MATRIX_IDENTITY", + "MATRIX_3D_NO_ROT", + "MATRIX_PERSPECTIVE", + "MATRIX_2D", + "MATRIX_2D_NO_ROT", + "MATRIX_3D" +}; + + +static GLfloat Identity[16] = { + 1.0, 0.0, 0.0, 0.0, + 0.0, 1.0, 0.0, 0.0, + 0.0, 0.0, 1.0, 0.0, + 0.0, 0.0, 0.0, 1.0 +}; + + + + +/* + * This matmul was contributed by Thomas Malik + * + * Perform a 4x4 matrix multiplication (product = a x b). + * Input: a, b - matrices to multiply + * Output: product - product of a and b + * WARNING: (product != b) assumed + * NOTE: (product == a) allowed + * + * KW: 4*16 = 64 muls + */ +#define A(row,col) a[(col<<2)+row] +#define B(row,col) b[(col<<2)+row] +#define P(row,col) product[(col<<2)+row] + +static void matmul4( GLfloat *product, const GLfloat *a, const GLfloat *b ) +{ + GLint i; + for (i = 0; i < 4; i++) { + const GLfloat ai0=A(i,0), ai1=A(i,1), ai2=A(i,2), ai3=A(i,3); + P(i,0) = ai0 * B(0,0) + ai1 * B(1,0) + ai2 * B(2,0) + ai3 * B(3,0); + P(i,1) = ai0 * B(0,1) + ai1 * B(1,1) + ai2 * B(2,1) + ai3 * B(3,1); + P(i,2) = ai0 * B(0,2) + ai1 * B(1,2) + ai2 * B(2,2) + ai3 * B(3,2); + P(i,3) = ai0 * B(0,3) + ai1 * B(1,3) + ai2 * B(2,3) + ai3 * B(3,3); + } +} + + +/* Multiply two matrices known to occupy only the top three rows, such + * as typical model matrices, and ortho matrices. + */ +static void matmul34( GLfloat *product, const GLfloat *a, const GLfloat *b ) +{ + GLint i; + for (i = 0; i < 3; i++) { + const GLfloat ai0=A(i,0), ai1=A(i,1), ai2=A(i,2), ai3=A(i,3); + P(i,0) = ai0 * B(0,0) + ai1 * B(1,0) + ai2 * B(2,0); + P(i,1) = ai0 * B(0,1) + ai1 * B(1,1) + ai2 * B(2,1); + P(i,2) = ai0 * B(0,2) + ai1 * B(1,2) + ai2 * B(2,2); + P(i,3) = ai0 * B(0,3) + ai1 * B(1,3) + ai2 * B(2,3) + ai3; + } + P(3,0) = 0; + P(3,1) = 0; + P(3,2) = 0; + P(3,3) = 1; +} + + +#undef A +#undef B +#undef P + + +/* + * Multiply a matrix by an array of floats with known properties. + */ +static void matrix_multf( GLmatrix *mat, const GLfloat *m, GLuint flags ) +{ + mat->flags |= (flags | MAT_DIRTY_TYPE | MAT_DIRTY_INVERSE); + + if (TEST_MAT_FLAGS(mat, MAT_FLAGS_3D)) + matmul34( mat->m, mat->m, m ); + else + matmul4( mat->m, mat->m, m ); +} + + +static void print_matrix_floats( const GLfloat m[16] ) +{ + int i; + for (i=0;i<4;i++) { + fprintf(stderr,"\t%f %f %f %f\n", m[i], m[4+i], m[8+i], m[12+i] ); + } +} + +void +_math_matrix_print( const GLmatrix *m ) +{ + fprintf(stderr, "Matrix type: %s, flags: %x\n", types[m->type], m->flags); + print_matrix_floats(m->m); + fprintf(stderr, "Inverse: \n"); + if (m->inv) { + GLfloat prod[16]; + print_matrix_floats(m->inv); + matmul4(prod, m->m, m->inv); + fprintf(stderr, "Mat * Inverse:\n"); + print_matrix_floats(prod); + } + else { + fprintf(stderr, " - not available\n"); + } +} + + + + +#define SWAP_ROWS(a, b) { GLfloat *_tmp = a; (a)=(b); (b)=_tmp; } +#define MAT(m,r,c) (m)[(c)*4+(r)] + +/* + * Compute inverse of 4x4 transformation matrix. + * Code contributed by Jacques Leroy jle@star.be + * Return GL_TRUE for success, GL_FALSE for failure (singular matrix) + */ +static GLboolean invert_matrix_general( GLmatrix *mat ) +{ + const GLfloat *m = mat->m; + GLfloat *out = mat->inv; + GLfloat wtmp[4][8]; + GLfloat m0, m1, m2, m3, s; + GLfloat *r0, *r1, *r2, *r3; + + r0 = wtmp[0], r1 = wtmp[1], r2 = wtmp[2], r3 = wtmp[3]; + + r0[0] = MAT(m,0,0), r0[1] = MAT(m,0,1), + r0[2] = MAT(m,0,2), r0[3] = MAT(m,0,3), + r0[4] = 1.0, r0[5] = r0[6] = r0[7] = 0.0, + + r1[0] = MAT(m,1,0), r1[1] = MAT(m,1,1), + r1[2] = MAT(m,1,2), r1[3] = MAT(m,1,3), + r1[5] = 1.0, r1[4] = r1[6] = r1[7] = 0.0, + + r2[0] = MAT(m,2,0), r2[1] = MAT(m,2,1), + r2[2] = MAT(m,2,2), r2[3] = MAT(m,2,3), + r2[6] = 1.0, r2[4] = r2[5] = r2[7] = 0.0, + + r3[0] = MAT(m,3,0), r3[1] = MAT(m,3,1), + r3[2] = MAT(m,3,2), r3[3] = MAT(m,3,3), + r3[7] = 1.0, r3[4] = r3[5] = r3[6] = 0.0; + + /* choose pivot - or die */ + if (fabs(r3[0])>fabs(r2[0])) SWAP_ROWS(r3, r2); + if (fabs(r2[0])>fabs(r1[0])) SWAP_ROWS(r2, r1); + if (fabs(r1[0])>fabs(r0[0])) SWAP_ROWS(r1, r0); + if (0.0 == r0[0]) return GL_FALSE; + + /* eliminate first variable */ + m1 = r1[0]/r0[0]; m2 = r2[0]/r0[0]; m3 = r3[0]/r0[0]; + s = r0[1]; r1[1] -= m1 * s; r2[1] -= m2 * s; r3[1] -= m3 * s; + s = r0[2]; r1[2] -= m1 * s; r2[2] -= m2 * s; r3[2] -= m3 * s; + s = r0[3]; r1[3] -= m1 * s; r2[3] -= m2 * s; r3[3] -= m3 * s; + s = r0[4]; + if (s != 0.0) { r1[4] -= m1 * s; r2[4] -= m2 * s; r3[4] -= m3 * s; } + s = r0[5]; + if (s != 0.0) { r1[5] -= m1 * s; r2[5] -= m2 * s; r3[5] -= m3 * s; } + s = r0[6]; + if (s != 0.0) { r1[6] -= m1 * s; r2[6] -= m2 * s; r3[6] -= m3 * s; } + s = r0[7]; + if (s != 0.0) { r1[7] -= m1 * s; r2[7] -= m2 * s; r3[7] -= m3 * s; } + + /* choose pivot - or die */ + if (fabs(r3[1])>fabs(r2[1])) SWAP_ROWS(r3, r2); + if (fabs(r2[1])>fabs(r1[1])) SWAP_ROWS(r2, r1); + if (0.0 == r1[1]) return GL_FALSE; + + /* eliminate second variable */ + m2 = r2[1]/r1[1]; m3 = r3[1]/r1[1]; + r2[2] -= m2 * r1[2]; r3[2] -= m3 * r1[2]; + r2[3] -= m2 * r1[3]; r3[3] -= m3 * r1[3]; + s = r1[4]; if (0.0 != s) { r2[4] -= m2 * s; r3[4] -= m3 * s; } + s = r1[5]; if (0.0 != s) { r2[5] -= m2 * s; r3[5] -= m3 * s; } + s = r1[6]; if (0.0 != s) { r2[6] -= m2 * s; r3[6] -= m3 * s; } + s = r1[7]; if (0.0 != s) { r2[7] -= m2 * s; r3[7] -= m3 * s; } + + /* choose pivot - or die */ + if (fabs(r3[2])>fabs(r2[2])) SWAP_ROWS(r3, r2); + if (0.0 == r2[2]) return GL_FALSE; + + /* eliminate third variable */ + m3 = r3[2]/r2[2]; + r3[3] -= m3 * r2[3], r3[4] -= m3 * r2[4], + r3[5] -= m3 * r2[5], r3[6] -= m3 * r2[6], + r3[7] -= m3 * r2[7]; + + /* last check */ + if (0.0 == r3[3]) return GL_FALSE; + + s = 1.0/r3[3]; /* now back substitute row 3 */ + r3[4] *= s; r3[5] *= s; r3[6] *= s; r3[7] *= s; + + m2 = r2[3]; /* now back substitute row 2 */ + s = 1.0/r2[2]; + r2[4] = s * (r2[4] - r3[4] * m2), r2[5] = s * (r2[5] - r3[5] * m2), + r2[6] = s * (r2[6] - r3[6] * m2), r2[7] = s * (r2[7] - r3[7] * m2); + m1 = r1[3]; + r1[4] -= r3[4] * m1, r1[5] -= r3[5] * m1, + r1[6] -= r3[6] * m1, r1[7] -= r3[7] * m1; + m0 = r0[3]; + r0[4] -= r3[4] * m0, r0[5] -= r3[5] * m0, + r0[6] -= r3[6] * m0, r0[7] -= r3[7] * m0; + + m1 = r1[2]; /* now back substitute row 1 */ + s = 1.0/r1[1]; + r1[4] = s * (r1[4] - r2[4] * m1), r1[5] = s * (r1[5] - r2[5] * m1), + r1[6] = s * (r1[6] - r2[6] * m1), r1[7] = s * (r1[7] - r2[7] * m1); + m0 = r0[2]; + r0[4] -= r2[4] * m0, r0[5] -= r2[5] * m0, + r0[6] -= r2[6] * m0, r0[7] -= r2[7] * m0; + + m0 = r0[1]; /* now back substitute row 0 */ + s = 1.0/r0[0]; + r0[4] = s * (r0[4] - r1[4] * m0), r0[5] = s * (r0[5] - r1[5] * m0), + r0[6] = s * (r0[6] - r1[6] * m0), r0[7] = s * (r0[7] - r1[7] * m0); + + MAT(out,0,0) = r0[4]; MAT(out,0,1) = r0[5], + MAT(out,0,2) = r0[6]; MAT(out,0,3) = r0[7], + MAT(out,1,0) = r1[4]; MAT(out,1,1) = r1[5], + MAT(out,1,2) = r1[6]; MAT(out,1,3) = r1[7], + MAT(out,2,0) = r2[4]; MAT(out,2,1) = r2[5], + MAT(out,2,2) = r2[6]; MAT(out,2,3) = r2[7], + MAT(out,3,0) = r3[4]; MAT(out,3,1) = r3[5], + MAT(out,3,2) = r3[6]; MAT(out,3,3) = r3[7]; + + return GL_TRUE; +} +#undef SWAP_ROWS + + +/* Adapted from graphics gems II. + */ +static GLboolean invert_matrix_3d_general( GLmatrix *mat ) +{ + const GLfloat *in = mat->m; + GLfloat *out = mat->inv; + GLfloat pos, neg, t; + GLfloat det; + + /* Calculate the determinant of upper left 3x3 submatrix and + * determine if the matrix is singular. + */ + pos = neg = 0.0; + t = MAT(in,0,0) * MAT(in,1,1) * MAT(in,2,2); + if (t >= 0.0) pos += t; else neg += t; + + t = MAT(in,1,0) * MAT(in,2,1) * MAT(in,0,2); + if (t >= 0.0) pos += t; else neg += t; + + t = MAT(in,2,0) * MAT(in,0,1) * MAT(in,1,2); + if (t >= 0.0) pos += t; else neg += t; + + t = -MAT(in,2,0) * MAT(in,1,1) * MAT(in,0,2); + if (t >= 0.0) pos += t; else neg += t; + + t = -MAT(in,1,0) * MAT(in,0,1) * MAT(in,2,2); + if (t >= 0.0) pos += t; else neg += t; + + t = -MAT(in,0,0) * MAT(in,2,1) * MAT(in,1,2); + if (t >= 0.0) pos += t; else neg += t; + + det = pos + neg; + + if (det*det < 1e-25) + return GL_FALSE; + + det = 1.0 / det; + MAT(out,0,0) = ( (MAT(in,1,1)*MAT(in,2,2) - MAT(in,2,1)*MAT(in,1,2) )*det); + MAT(out,0,1) = (- (MAT(in,0,1)*MAT(in,2,2) - MAT(in,2,1)*MAT(in,0,2) )*det); + MAT(out,0,2) = ( (MAT(in,0,1)*MAT(in,1,2) - MAT(in,1,1)*MAT(in,0,2) )*det); + MAT(out,1,0) = (- (MAT(in,1,0)*MAT(in,2,2) - MAT(in,2,0)*MAT(in,1,2) )*det); + MAT(out,1,1) = ( (MAT(in,0,0)*MAT(in,2,2) - MAT(in,2,0)*MAT(in,0,2) )*det); + MAT(out,1,2) = (- (MAT(in,0,0)*MAT(in,1,2) - MAT(in,1,0)*MAT(in,0,2) )*det); + MAT(out,2,0) = ( (MAT(in,1,0)*MAT(in,2,1) - MAT(in,2,0)*MAT(in,1,1) )*det); + MAT(out,2,1) = (- (MAT(in,0,0)*MAT(in,2,1) - MAT(in,2,0)*MAT(in,0,1) )*det); + MAT(out,2,2) = ( (MAT(in,0,0)*MAT(in,1,1) - MAT(in,1,0)*MAT(in,0,1) )*det); + + /* Do the translation part */ + MAT(out,0,3) = - (MAT(in,0,3) * MAT(out,0,0) + + MAT(in,1,3) * MAT(out,0,1) + + MAT(in,2,3) * MAT(out,0,2) ); + MAT(out,1,3) = - (MAT(in,0,3) * MAT(out,1,0) + + MAT(in,1,3) * MAT(out,1,1) + + MAT(in,2,3) * MAT(out,1,2) ); + MAT(out,2,3) = - (MAT(in,0,3) * MAT(out,2,0) + + MAT(in,1,3) * MAT(out,2,1) + + MAT(in,2,3) * MAT(out,2,2) ); + + return GL_TRUE; +} + + +static GLboolean invert_matrix_3d( GLmatrix *mat ) +{ + const GLfloat *in = mat->m; + GLfloat *out = mat->inv; + + if (!TEST_MAT_FLAGS(mat, MAT_FLAGS_ANGLE_PRESERVING)) { + return invert_matrix_3d_general( mat ); + } + + if (mat->flags & MAT_FLAG_UNIFORM_SCALE) { + GLfloat scale = (MAT(in,0,0) * MAT(in,0,0) + + MAT(in,0,1) * MAT(in,0,1) + + MAT(in,0,2) * MAT(in,0,2)); + + if (scale == 0.0) + return GL_FALSE; + + scale = 1.0 / scale; + + /* Transpose and scale the 3 by 3 upper-left submatrix. */ + MAT(out,0,0) = scale * MAT(in,0,0); + MAT(out,1,0) = scale * MAT(in,0,1); + MAT(out,2,0) = scale * MAT(in,0,2); + MAT(out,0,1) = scale * MAT(in,1,0); + MAT(out,1,1) = scale * MAT(in,1,1); + MAT(out,2,1) = scale * MAT(in,1,2); + MAT(out,0,2) = scale * MAT(in,2,0); + MAT(out,1,2) = scale * MAT(in,2,1); + MAT(out,2,2) = scale * MAT(in,2,2); + } + else if (mat->flags & MAT_FLAG_ROTATION) { + /* Transpose the 3 by 3 upper-left submatrix. */ + MAT(out,0,0) = MAT(in,0,0); + MAT(out,1,0) = MAT(in,0,1); + MAT(out,2,0) = MAT(in,0,2); + MAT(out,0,1) = MAT(in,1,0); + MAT(out,1,1) = MAT(in,1,1); + MAT(out,2,1) = MAT(in,1,2); + MAT(out,0,2) = MAT(in,2,0); + MAT(out,1,2) = MAT(in,2,1); + MAT(out,2,2) = MAT(in,2,2); + } + else { + /* pure translation */ + MEMCPY( out, Identity, sizeof(Identity) ); + MAT(out,0,3) = - MAT(in,0,3); + MAT(out,1,3) = - MAT(in,1,3); + MAT(out,2,3) = - MAT(in,2,3); + return GL_TRUE; + } + + if (mat->flags & MAT_FLAG_TRANSLATION) { + /* Do the translation part */ + MAT(out,0,3) = - (MAT(in,0,3) * MAT(out,0,0) + + MAT(in,1,3) * MAT(out,0,1) + + MAT(in,2,3) * MAT(out,0,2) ); + MAT(out,1,3) = - (MAT(in,0,3) * MAT(out,1,0) + + MAT(in,1,3) * MAT(out,1,1) + + MAT(in,2,3) * MAT(out,1,2) ); + MAT(out,2,3) = - (MAT(in,0,3) * MAT(out,2,0) + + MAT(in,1,3) * MAT(out,2,1) + + MAT(in,2,3) * MAT(out,2,2) ); + } + else { + MAT(out,0,3) = MAT(out,1,3) = MAT(out,2,3) = 0.0; + } + + return GL_TRUE; +} + + + +static GLboolean invert_matrix_identity( GLmatrix *mat ) +{ + MEMCPY( mat->inv, Identity, sizeof(Identity) ); + return GL_TRUE; +} + + +static GLboolean invert_matrix_3d_no_rot( GLmatrix *mat ) +{ + const GLfloat *in = mat->m; + GLfloat *out = mat->inv; + + if (MAT(in,0,0) == 0 || MAT(in,1,1) == 0 || MAT(in,2,2) == 0 ) + return GL_FALSE; + + MEMCPY( out, Identity, 16 * sizeof(GLfloat) ); + MAT(out,0,0) = 1.0 / MAT(in,0,0); + MAT(out,1,1) = 1.0 / MAT(in,1,1); + MAT(out,2,2) = 1.0 / MAT(in,2,2); + + if (mat->flags & MAT_FLAG_TRANSLATION) { + MAT(out,0,3) = - (MAT(in,0,3) * MAT(out,0,0)); + MAT(out,1,3) = - (MAT(in,1,3) * MAT(out,1,1)); + MAT(out,2,3) = - (MAT(in,2,3) * MAT(out,2,2)); + } + + return GL_TRUE; +} + + +static GLboolean invert_matrix_2d_no_rot( GLmatrix *mat ) +{ + const GLfloat *in = mat->m; + GLfloat *out = mat->inv; + + if (MAT(in,0,0) == 0 || MAT(in,1,1) == 0) + return GL_FALSE; + + MEMCPY( out, Identity, 16 * sizeof(GLfloat) ); + MAT(out,0,0) = 1.0 / MAT(in,0,0); + MAT(out,1,1) = 1.0 / MAT(in,1,1); + + if (mat->flags & MAT_FLAG_TRANSLATION) { + MAT(out,0,3) = - (MAT(in,0,3) * MAT(out,0,0)); + MAT(out,1,3) = - (MAT(in,1,3) * MAT(out,1,1)); + } + + return GL_TRUE; +} + + +static GLboolean invert_matrix_perspective( GLmatrix *mat ) +{ + const GLfloat *in = mat->m; + GLfloat *out = mat->inv; + + if (MAT(in,2,3) == 0) + return GL_FALSE; + + MEMCPY( out, Identity, 16 * sizeof(GLfloat) ); + + MAT(out,0,0) = 1.0 / MAT(in,0,0); + MAT(out,1,1) = 1.0 / MAT(in,1,1); + + MAT(out,0,3) = MAT(in,0,2); + MAT(out,1,3) = MAT(in,1,2); + + MAT(out,2,2) = 0; + MAT(out,2,3) = -1; + + MAT(out,3,2) = 1.0 / MAT(in,2,3); + MAT(out,3,3) = MAT(in,2,2) * MAT(out,3,2); + + return GL_TRUE; +} + + +typedef GLboolean (*inv_mat_func)( GLmatrix *mat ); + + +static inv_mat_func inv_mat_tab[7] = { + invert_matrix_general, + invert_matrix_identity, + invert_matrix_3d_no_rot, + invert_matrix_perspective, + invert_matrix_3d, /* lazy! */ + invert_matrix_2d_no_rot, + invert_matrix_3d +}; + + +static GLboolean matrix_invert( GLmatrix *mat ) +{ + if (inv_mat_tab[mat->type](mat)) { + mat->flags &= ~MAT_FLAG_SINGULAR; + return GL_TRUE; + } else { + mat->flags |= MAT_FLAG_SINGULAR; + MEMCPY( mat->inv, Identity, sizeof(Identity) ); + return GL_FALSE; + } +} + + + + + + +/* + * Generate a 4x4 transformation matrix from glRotate parameters, and + * postmultiply the input matrix by it. + */ +void +_math_matrix_rotate( GLmatrix *mat, + GLfloat angle, GLfloat x, GLfloat y, GLfloat z ) +{ + /* This function contributed by Erich Boleyn (erich@uruk.org) */ + GLfloat mag, s, c; + GLfloat xx, yy, zz, xy, yz, zx, xs, ys, zs, one_c; + GLfloat m[16]; + + s = sin( angle * DEG2RAD ); + c = cos( angle * DEG2RAD ); + + mag = GL_SQRT( x*x + y*y + z*z ); + + if (mag <= 1.0e-4) { + /* generate an identity matrix and return */ + MEMCPY(m, Identity, sizeof(GLfloat)*16); + return; + } + + x /= mag; + y /= mag; + z /= mag; + +#define M(row,col) m[col*4+row] + + /* + * Arbitrary axis rotation matrix. + * + * This is composed of 5 matrices, Rz, Ry, T, Ry', Rz', multiplied + * like so: Rz * Ry * T * Ry' * Rz'. T is the final rotation + * (which is about the X-axis), and the two composite transforms + * Ry' * Rz' and Rz * Ry are (respectively) the rotations necessary + * from the arbitrary axis to the X-axis then back. They are + * all elementary rotations. + * + * Rz' is a rotation about the Z-axis, to bring the axis vector + * into the x-z plane. Then Ry' is applied, rotating about the + * Y-axis to bring the axis vector parallel with the X-axis. The + * rotation about the X-axis is then performed. Ry and Rz are + * simply the respective inverse transforms to bring the arbitrary + * axis back to it's original orientation. The first transforms + * Rz' and Ry' are considered inverses, since the data from the + * arbitrary axis gives you info on how to get to it, not how + * to get away from it, and an inverse must be applied. + * + * The basic calculation used is to recognize that the arbitrary + * axis vector (x, y, z), since it is of unit length, actually + * represents the sines and cosines of the angles to rotate the + * X-axis to the same orientation, with theta being the angle about + * Z and phi the angle about Y (in the order described above) + * as follows: + * + * cos ( theta ) = x / sqrt ( 1 - z^2 ) + * sin ( theta ) = y / sqrt ( 1 - z^2 ) + * + * cos ( phi ) = sqrt ( 1 - z^2 ) + * sin ( phi ) = z + * + * Note that cos ( phi ) can further be inserted to the above + * formulas: + * + * cos ( theta ) = x / cos ( phi ) + * sin ( theta ) = y / sin ( phi ) + * + * ...etc. Because of those relations and the standard trigonometric + * relations, it is pssible to reduce the transforms down to what + * is used below. It may be that any primary axis chosen will give the + * same results (modulo a sign convention) using thie method. + * + * Particularly nice is to notice that all divisions that might + * have caused trouble when parallel to certain planes or + * axis go away with care paid to reducing the expressions. + * After checking, it does perform correctly under all cases, since + * in all the cases of division where the denominator would have + * been zero, the numerator would have been zero as well, giving + * the expected result. + */ + + xx = x * x; + yy = y * y; + zz = z * z; + xy = x * y; + yz = y * z; + zx = z * x; + xs = x * s; + ys = y * s; + zs = z * s; + one_c = 1.0F - c; + + M(0,0) = (one_c * xx) + c; + M(0,1) = (one_c * xy) - zs; + M(0,2) = (one_c * zx) + ys; + M(0,3) = 0.0F; + + M(1,0) = (one_c * xy) + zs; + M(1,1) = (one_c * yy) + c; + M(1,2) = (one_c * yz) - xs; + M(1,3) = 0.0F; + + M(2,0) = (one_c * zx) - ys; + M(2,1) = (one_c * yz) + xs; + M(2,2) = (one_c * zz) + c; + M(2,3) = 0.0F; + + M(3,0) = 0.0F; + M(3,1) = 0.0F; + M(3,2) = 0.0F; + M(3,3) = 1.0F; + +#undef M + + matrix_multf( mat, m, MAT_FLAG_ROTATION ); +} + + +void +_math_matrix_frustum( GLmatrix *mat, + GLfloat left, GLfloat right, + GLfloat bottom, GLfloat top, + GLfloat nearval, GLfloat farval ) +{ + GLfloat x, y, a, b, c, d; + GLfloat m[16]; + + x = (2.0*nearval) / (right-left); + y = (2.0*nearval) / (top-bottom); + a = (right+left) / (right-left); + b = (top+bottom) / (top-bottom); + c = -(farval+nearval) / ( farval-nearval); + d = -(2.0*farval*nearval) / (farval-nearval); /* error? */ + +#define M(row,col) m[col*4+row] + M(0,0) = x; M(0,1) = 0.0F; M(0,2) = a; M(0,3) = 0.0F; + M(1,0) = 0.0F; M(1,1) = y; M(1,2) = b; M(1,3) = 0.0F; + M(2,0) = 0.0F; M(2,1) = 0.0F; M(2,2) = c; M(2,3) = d; + M(3,0) = 0.0F; M(3,1) = 0.0F; M(3,2) = -1.0F; M(3,3) = 0.0F; +#undef M + + matrix_multf( mat, m, MAT_FLAG_PERSPECTIVE ); +} + +void +_math_matrix_ortho( GLmatrix *mat, + GLfloat left, GLfloat right, + GLfloat bottom, GLfloat top, + GLfloat nearval, GLfloat farval ) +{ + GLfloat x, y, z; + GLfloat tx, ty, tz; + GLfloat m[16]; + + x = 2.0 / (right-left); + y = 2.0 / (top-bottom); + z = -2.0 / (farval-nearval); + tx = -(right+left) / (right-left); + ty = -(top+bottom) / (top-bottom); + tz = -(farval+nearval) / (farval-nearval); + +#define M(row,col) m[col*4+row] + M(0,0) = x; M(0,1) = 0.0F; M(0,2) = 0.0F; M(0,3) = tx; + M(1,0) = 0.0F; M(1,1) = y; M(1,2) = 0.0F; M(1,3) = ty; + M(2,0) = 0.0F; M(2,1) = 0.0F; M(2,2) = z; M(2,3) = tz; + M(3,0) = 0.0F; M(3,1) = 0.0F; M(3,2) = 0.0F; M(3,3) = 1.0F; +#undef M + + matrix_multf( mat, m, (MAT_FLAG_GENERAL_SCALE|MAT_FLAG_TRANSLATION)); +} + + +#define ZERO(x) (1<m; + GLuint mask = 0; + GLuint i; + + for (i = 0 ; i < 16 ; i++) { + if (m[i] == 0.0) mask |= (1<flags &= ~MAT_FLAGS_GEOMETRY; + + /* Check for translation - no-one really cares + */ + if ((mask & MASK_NO_TRX) != MASK_NO_TRX) + mat->flags |= MAT_FLAG_TRANSLATION; + + /* Do the real work + */ + if (mask == (GLuint) MASK_IDENTITY) { + mat->type = MATRIX_IDENTITY; + } + else if ((mask & MASK_2D_NO_ROT) == (GLuint) MASK_2D_NO_ROT) { + mat->type = MATRIX_2D_NO_ROT; + + if ((mask & MASK_NO_2D_SCALE) != MASK_NO_2D_SCALE) + mat->flags = MAT_FLAG_GENERAL_SCALE; + } + else if ((mask & MASK_2D) == (GLuint) MASK_2D) { + GLfloat mm = DOT2(m, m); + GLfloat m4m4 = DOT2(m+4,m+4); + GLfloat mm4 = DOT2(m,m+4); + + mat->type = MATRIX_2D; + + /* Check for scale */ + if (SQ(mm-1) > SQ(1e-6) || + SQ(m4m4-1) > SQ(1e-6)) + mat->flags |= MAT_FLAG_GENERAL_SCALE; + + /* Check for rotation */ + if (SQ(mm4) > SQ(1e-6)) + mat->flags |= MAT_FLAG_GENERAL_3D; + else + mat->flags |= MAT_FLAG_ROTATION; + + } + else if ((mask & MASK_3D_NO_ROT) == (GLuint) MASK_3D_NO_ROT) { + mat->type = MATRIX_3D_NO_ROT; + + /* Check for scale */ + if (SQ(m[0]-m[5]) < SQ(1e-6) && + SQ(m[0]-m[10]) < SQ(1e-6)) { + if (SQ(m[0]-1.0) > SQ(1e-6)) { + mat->flags |= MAT_FLAG_UNIFORM_SCALE; + } + } + else { + mat->flags |= MAT_FLAG_GENERAL_SCALE; + } + } + else if ((mask & MASK_3D) == (GLuint) MASK_3D) { + GLfloat c1 = DOT3(m,m); + GLfloat c2 = DOT3(m+4,m+4); + GLfloat c3 = DOT3(m+8,m+8); + GLfloat d1 = DOT3(m, m+4); + GLfloat cp[3]; + + mat->type = MATRIX_3D; + + /* Check for scale */ + if (SQ(c1-c2) < SQ(1e-6) && SQ(c1-c3) < SQ(1e-6)) { + if (SQ(c1-1.0) > SQ(1e-6)) + mat->flags |= MAT_FLAG_UNIFORM_SCALE; + /* else no scale at all */ + } + else { + mat->flags |= MAT_FLAG_GENERAL_SCALE; + } + + /* Check for rotation */ + if (SQ(d1) < SQ(1e-6)) { + CROSS3( cp, m, m+4 ); + SUB_3V( cp, cp, (m+8) ); + if (LEN_SQUARED_3FV(cp) < SQ(1e-6)) + mat->flags |= MAT_FLAG_ROTATION; + else + mat->flags |= MAT_FLAG_GENERAL_3D; + } + else { + mat->flags |= MAT_FLAG_GENERAL_3D; /* shear, etc */ + } + } + else if ((mask & MASK_PERSPECTIVE) == MASK_PERSPECTIVE && m[11]==-1.0F) { + mat->type = MATRIX_PERSPECTIVE; + mat->flags |= MAT_FLAG_GENERAL; + } + else { + mat->type = MATRIX_GENERAL; + mat->flags |= MAT_FLAG_GENERAL; + } +} + + +/* Analyse a matrix given that its flags are accurate - this is the + * more common operation, hopefully. + */ +static void analyse_from_flags( GLmatrix *mat ) +{ + const GLfloat *m = mat->m; + + if (TEST_MAT_FLAGS(mat, 0)) { + mat->type = MATRIX_IDENTITY; + } + else if (TEST_MAT_FLAGS(mat, (MAT_FLAG_TRANSLATION | + MAT_FLAG_UNIFORM_SCALE | + MAT_FLAG_GENERAL_SCALE))) { + if ( m[10]==1.0F && m[14]==0.0F ) { + mat->type = MATRIX_2D_NO_ROT; + } + else { + mat->type = MATRIX_3D_NO_ROT; + } + } + else if (TEST_MAT_FLAGS(mat, MAT_FLAGS_3D)) { + if ( m[ 8]==0.0F + && m[ 9]==0.0F + && m[2]==0.0F && m[6]==0.0F && m[10]==1.0F && m[14]==0.0F) { + mat->type = MATRIX_2D; + } + else { + mat->type = MATRIX_3D; + } + } + else if ( m[4]==0.0F && m[12]==0.0F + && m[1]==0.0F && m[13]==0.0F + && m[2]==0.0F && m[6]==0.0F + && m[3]==0.0F && m[7]==0.0F && m[11]==-1.0F && m[15]==0.0F) { + mat->type = MATRIX_PERSPECTIVE; + } + else { + mat->type = MATRIX_GENERAL; + } +} + + +void +_math_matrix_analyse( GLmatrix *mat ) +{ + if (mat->flags & MAT_DIRTY_TYPE) { + if (mat->flags & MAT_DIRTY_FLAGS) + analyse_from_scratch( mat ); + else + analyse_from_flags( mat ); + } + + if (mat->inv && (mat->flags & MAT_DIRTY_INVERSE)) { + matrix_invert( mat ); + } + + mat->flags &= ~(MAT_DIRTY_FLAGS| + MAT_DIRTY_TYPE| + MAT_DIRTY_INVERSE); +} + + +void +_math_matrix_copy( GLmatrix *to, const GLmatrix *from ) +{ + MEMCPY( to->m, from->m, sizeof(Identity) ); + to->flags = from->flags; + to->type = from->type; + + if (to->inv != 0) { + if (from->inv == 0) { + matrix_invert( to ); + } + else { + MEMCPY(to->inv, from->inv, sizeof(GLfloat)*16); + } + } +} + + +void +_math_matrix_scale( GLmatrix *mat, GLfloat x, GLfloat y, GLfloat z ) +{ + GLfloat *m = mat->m; + m[0] *= x; m[4] *= y; m[8] *= z; + m[1] *= x; m[5] *= y; m[9] *= z; + m[2] *= x; m[6] *= y; m[10] *= z; + m[3] *= x; m[7] *= y; m[11] *= z; + + if (fabs(x - y) < 1e-8 && fabs(x - z) < 1e-8) + mat->flags |= MAT_FLAG_UNIFORM_SCALE; + else + mat->flags |= MAT_FLAG_GENERAL_SCALE; + + mat->flags |= (MAT_DIRTY_TYPE | + MAT_DIRTY_INVERSE); +} + + +void +_math_matrix_translate( GLmatrix *mat, GLfloat x, GLfloat y, GLfloat z ) +{ + GLfloat *m = mat->m; + m[12] = m[0] * x + m[4] * y + m[8] * z + m[12]; + m[13] = m[1] * x + m[5] * y + m[9] * z + m[13]; + m[14] = m[2] * x + m[6] * y + m[10] * z + m[14]; + m[15] = m[3] * x + m[7] * y + m[11] * z + m[15]; + + mat->flags |= (MAT_FLAG_TRANSLATION | + MAT_DIRTY_TYPE | + MAT_DIRTY_INVERSE); +} + + +void +_math_matrix_loadf( GLmatrix *mat, const GLfloat *m ) +{ + MEMCPY( mat->m, m, 16*sizeof(GLfloat) ); + mat->flags = (MAT_FLAG_GENERAL | MAT_DIRTY); +} + +void +_math_matrix_ctr( GLmatrix *m ) +{ + if ( m->m == 0 ) { + m->m = (GLfloat *) ALIGN_MALLOC( 16 * sizeof(GLfloat), 16 ); + } + MEMCPY( m->m, Identity, sizeof(Identity) ); + m->inv = 0; + m->type = MATRIX_IDENTITY; + m->flags = 0; +} + +void +_math_matrix_dtr( GLmatrix *m ) +{ + if ( m->m != 0 ) { + ALIGN_FREE( m->m ); + m->m = 0; + } + if ( m->inv != 0 ) { + ALIGN_FREE( m->inv ); + m->inv = 0; + } +} + + +void +_math_matrix_alloc_inv( GLmatrix *m ) +{ + if ( m->inv == 0 ) { + m->inv = (GLfloat *) ALIGN_MALLOC( 16 * sizeof(GLfloat), 16 ); + MEMCPY( m->inv, Identity, 16 * sizeof(GLfloat) ); + } +} + + +void +_math_matrix_mul_matrix( GLmatrix *dest, const GLmatrix *a, const GLmatrix *b ) +{ + dest->flags = (a->flags | + b->flags | + MAT_DIRTY_TYPE | + MAT_DIRTY_INVERSE); + + if (TEST_MAT_FLAGS(dest, MAT_FLAGS_3D)) + matmul34( dest->m, a->m, b->m ); + else + matmul4( dest->m, a->m, b->m ); +} + + +void +_math_matrix_mul_floats( GLmatrix *dest, const GLfloat *m ) +{ + dest->flags |= (MAT_FLAG_GENERAL | + MAT_DIRTY_TYPE | + MAT_DIRTY_INVERSE); + + matmul4( dest->m, dest->m, m ); +} + +void +_math_matrix_set_identity( GLmatrix *mat ) +{ + MEMCPY( mat->m, Identity, 16*sizeof(GLfloat) ); + + if (mat->inv) + MEMCPY( mat->inv, Identity, 16*sizeof(GLfloat) ); + + mat->type = MATRIX_IDENTITY; + mat->flags &= ~(MAT_DIRTY_FLAGS| + MAT_DIRTY_TYPE| + MAT_DIRTY_INVERSE); +} + + + +void +_math_transposef( GLfloat to[16], const GLfloat from[16] ) +{ + to[0] = from[0]; + to[1] = from[4]; + to[2] = from[8]; + to[3] = from[12]; + to[4] = from[1]; + to[5] = from[5]; + to[6] = from[9]; + to[7] = from[13]; + to[8] = from[2]; + to[9] = from[6]; + to[10] = from[10]; + to[11] = from[14]; + to[12] = from[3]; + to[13] = from[7]; + to[14] = from[11]; + to[15] = from[15]; +} + + +void +_math_transposed( GLdouble to[16], const GLdouble from[16] ) +{ + to[0] = from[0]; + to[1] = from[4]; + to[2] = from[8]; + to[3] = from[12]; + to[4] = from[1]; + to[5] = from[5]; + to[6] = from[9]; + to[7] = from[13]; + to[8] = from[2]; + to[9] = from[6]; + to[10] = from[10]; + to[11] = from[14]; + to[12] = from[3]; + to[13] = from[7]; + to[14] = from[11]; + to[15] = from[15]; +} + +void +_math_transposefd( GLfloat to[16], const GLdouble from[16] ) +{ + to[0] = from[0]; + to[1] = from[4]; + to[2] = from[8]; + to[3] = from[12]; + to[4] = from[1]; + to[5] = from[5]; + to[6] = from[9]; + to[7] = from[13]; + to[8] = from[2]; + to[9] = from[6]; + to[10] = from[10]; + to[11] = from[14]; + to[12] = from[3]; + to[13] = from[7]; + to[14] = from[11]; + to[15] = from[15]; +} Index: dll/opengl/opengl32/mesa/math/m_matrix.h =================================================================== --- dll/opengl/opengl32/mesa/math/m_matrix.h (revision 0) +++ dll/opengl/opengl32/mesa/math/m_matrix.h (working copy) @@ -0,0 +1,176 @@ +/* $Id: m_matrix.h,v 1.4 2001/03/12 00:48:41 gareth Exp $ */ + +/* + * Mesa 3-D graphics library + * Version: 3.5 + * + * Copyright (C) 1999-2001 Brian Paul 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 + * BRIAN PAUL 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. + */ + + +#ifndef _M_MATRIX_H +#define _M_MATRIX_H + + + +/* Give symbolic names to some of the entries in the matrix to help + * out with the rework of the viewport_map as a matrix transform. + */ +#define MAT_SX 0 +#define MAT_SY 5 +#define MAT_SZ 10 +#define MAT_TX 12 +#define MAT_TY 13 +#define MAT_TZ 14 + +/* + * Different kinds of 4x4 transformation matrices: + */ +#define MATRIX_GENERAL 0 /* general 4x4 matrix */ +#define MATRIX_IDENTITY 1 /* identity matrix */ +#define MATRIX_3D_NO_ROT 2 /* ortho projection and others... */ +#define MATRIX_PERSPECTIVE 3 /* perspective projection matrix */ +#define MATRIX_2D 4 /* 2-D transformation */ +#define MATRIX_2D_NO_ROT 5 /* 2-D scale & translate only */ +#define MATRIX_3D 6 /* 3-D transformation */ + +#define MAT_FLAG_IDENTITY 0 +#define MAT_FLAG_GENERAL 0x1 +#define MAT_FLAG_ROTATION 0x2 +#define MAT_FLAG_TRANSLATION 0x4 +#define MAT_FLAG_UNIFORM_SCALE 0x8 +#define MAT_FLAG_GENERAL_SCALE 0x10 +#define MAT_FLAG_GENERAL_3D 0x20 +#define MAT_FLAG_PERSPECTIVE 0x40 +#define MAT_FLAG_SINGULAR 0x80 +#define MAT_DIRTY_TYPE 0x100 +#define MAT_DIRTY_FLAGS 0x200 +#define MAT_DIRTY_INVERSE 0x400 + +#define MAT_FLAGS_ANGLE_PRESERVING (MAT_FLAG_ROTATION | \ + MAT_FLAG_TRANSLATION | \ + MAT_FLAG_UNIFORM_SCALE) + +#define MAT_FLAGS_LENGTH_PRESERVING (MAT_FLAG_ROTATION | \ + MAT_FLAG_TRANSLATION) + +#define MAT_FLAGS_3D (MAT_FLAG_ROTATION | \ + MAT_FLAG_TRANSLATION | \ + MAT_FLAG_UNIFORM_SCALE | \ + MAT_FLAG_GENERAL_SCALE | \ + MAT_FLAG_GENERAL_3D) + +#define MAT_FLAGS_GEOMETRY (MAT_FLAG_GENERAL | \ + MAT_FLAG_ROTATION | \ + MAT_FLAG_TRANSLATION | \ + MAT_FLAG_UNIFORM_SCALE | \ + MAT_FLAG_GENERAL_SCALE | \ + MAT_FLAG_GENERAL_3D | \ + MAT_FLAG_PERSPECTIVE | \ + MAT_FLAG_SINGULAR) + +#define MAT_DIRTY (MAT_DIRTY_TYPE | \ + MAT_DIRTY_FLAGS | \ + MAT_DIRTY_INVERSE) + +#define TEST_MAT_FLAGS(mat, a) \ + ((MAT_FLAGS_GEOMETRY & (~(a)) & ((mat)->flags) ) == 0) + + +typedef struct { + GLfloat *m; /* 16-byte aligned */ + GLfloat *inv; /* optional, 16-byte aligned */ + GLuint flags; + GLuint type; /* one of the MATRIX_* values */ +} GLmatrix; + + + + +extern void +_math_matrix_ctr( GLmatrix *m ); + +extern void +_math_matrix_dtr( GLmatrix *m ); + +extern void +_math_matrix_alloc_inv( GLmatrix *m ); + +extern void +_math_matrix_mul_matrix( GLmatrix *dest, const GLmatrix *a, const GLmatrix *b ); + +extern void +_math_matrix_mul_floats( GLmatrix *dest, const GLfloat *b ); + +extern void +_math_matrix_loadf( GLmatrix *mat, const GLfloat *m ); + +extern void +_math_matrix_translate( GLmatrix *mat, GLfloat x, GLfloat y, GLfloat z ); + +extern void +_math_matrix_rotate( GLmatrix *m, GLfloat angle, + GLfloat x, GLfloat y, GLfloat z ); + +extern void +_math_matrix_scale( GLmatrix *mat, GLfloat x, GLfloat y, GLfloat z ); + +extern void +_math_matrix_ortho( GLmatrix *mat, + GLfloat left, GLfloat right, + GLfloat bottom, GLfloat top, + GLfloat nearval, GLfloat farval ); + +extern void +_math_matrix_frustum( GLmatrix *mat, + GLfloat left, GLfloat right, + GLfloat bottom, GLfloat top, + GLfloat nearval, GLfloat farval ); + +extern void +_math_matrix_set_identity( GLmatrix *dest ); + +extern void +_math_matrix_copy( GLmatrix *to, const GLmatrix *from ); + +extern void +_math_matrix_analyse( GLmatrix *mat ); + +extern void +_math_matrix_print( const GLmatrix *m ); + + + + +/* Related functions that don't actually operate on GLmatrix structs: + */ +extern void +_math_transposef( GLfloat to[16], const GLfloat from[16] ); + +extern void +_math_transposed( GLdouble to[16], const GLdouble from[16] ); + +extern void +_math_transposefd( GLfloat to[16], const GLdouble from[16] ); + + + + +#endif Index: dll/opengl/opengl32/mesa/math/m_norm_tmp.h =================================================================== --- dll/opengl/opengl32/mesa/math/m_norm_tmp.h (revision 0) +++ dll/opengl/opengl32/mesa/math/m_norm_tmp.h (working copy) @@ -0,0 +1,374 @@ +/* $Id: m_norm_tmp.h,v 1.7 2001/03/30 14:44:43 gareth Exp $ */ + +/* + * Mesa 3-D graphics library + * Version: 3.5 + * + * Copyright (C) 1999-2001 Brian Paul 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 + * BRIAN PAUL 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. + */ + +/* + * New (3.1) transformation code written by Keith Whitwell. + */ + +#include +#include "m_vertices.h" + +static void _XFORMAPI +TAG(transform_normalize_normals)( const GLmatrix *mat, + GLfloat scale, + const GLvector3f *in, + const GLfloat *lengths, + GLvector3f *dest ) +{ + GLuint i; + const GLfloat *from = in->start; + GLuint stride = in->stride; + GLuint count = in->count; + GLfloat (*out)[3] = (GLfloat (*)[3])dest->start; + GLfloat *m = mat->inv; + GLfloat m0 = m[0], m4 = m[4], m8 = m[8]; + GLfloat m1 = m[1], m5 = m[5], m9 = m[9]; + GLfloat m2 = m[2], m6 = m[6], m10 = m[10]; + + if (!lengths) { + STRIDE_LOOP { + GLfloat tx, ty, tz; + { + const GLfloat ux = from[0], uy = from[1], uz = from[2]; + tx = ux * m0 + uy * m1 + uz * m2; + ty = ux * m4 + uy * m5 + uz * m6; + tz = ux * m8 + uy * m9 + uz * m10; + } + { + GLdouble len = tx*tx + ty*ty + tz*tz; + if (len > 1e-20) { + GLdouble scale = 1.0 / GL_SQRT(len); + out[i][0] = (GLfloat) (tx * scale); + out[i][1] = (GLfloat) (ty * scale); + out[i][2] = (GLfloat) (tz * scale); + } + else + { + out[i][0] = out[i][1] = out[i][2] = 0; + } + } + } + } + else { + if (scale != 1.0) { + m0 *= scale, m4 *= scale, m8 *= scale; + m1 *= scale, m5 *= scale, m9 *= scale; + m2 *= scale, m6 *= scale, m10 *= scale; + } + + STRIDE_LOOP { + GLfloat tx, ty, tz; + { + const GLfloat ux = from[0], uy = from[1], uz = from[2]; + tx = ux * m0 + uy * m1 + uz * m2; + ty = ux * m4 + uy * m5 + uz * m6; + tz = ux * m8 + uy * m9 + uz * m10; + } + { + GLfloat len = lengths[i]; + out[i][0] = tx * len; + out[i][1] = ty * len; + out[i][2] = tz * len; + } + } + } + dest->count = in->count; +} + + +static void _XFORMAPI +TAG(transform_normalize_normals_no_rot)( const GLmatrix *mat, + GLfloat scale, + const GLvector3f *in, + const GLfloat *lengths, + GLvector3f *dest ) +{ + GLuint i; + const GLfloat *from = in->start; + GLuint stride = in->stride; + GLuint count = in->count; + GLfloat (*out)[3] = (GLfloat (*)[3])dest->start; + GLfloat *m = mat->inv; + GLfloat m0 = m[0]; + GLfloat m5 = m[5]; + GLfloat m10 = m[10]; + if (!lengths) { + STRIDE_LOOP { + GLfloat tx, ty, tz; + { + const GLfloat ux = from[0], uy = from[1], uz = from[2]; + tx = ux * m0 ; + ty = uy * m5 ; + tz = uz * m10; + } + { + GLdouble len = tx*tx + ty*ty + tz*tz; + if (len > 1e-20) { + GLdouble scale = 1.0 / GL_SQRT(len); + out[i][0] = (GLfloat) (tx * scale); + out[i][1] = (GLfloat) (ty * scale); + out[i][2] = (GLfloat) (tz * scale); + } + else + { + out[i][0] = out[i][1] = out[i][2] = 0; + } + } + } + } + else { + /* scale has been snapped to 1.0 if it is close. + */ + if (scale != 1.0) { + m0 *= scale; + m5 *= scale; + m10 *= scale; + } + + STRIDE_LOOP { + GLfloat tx, ty, tz; + { + const GLfloat ux = from[0], uy = from[1], uz = from[2]; + tx = ux * m0 ; + ty = uy * m5 ; + tz = uz * m10; + } + { + GLfloat len = lengths[i]; + out[i][0] = tx * len; + out[i][1] = ty * len; + out[i][2] = tz * len; + } + } + } + dest->count = in->count; +} + + +static void _XFORMAPI +TAG(transform_rescale_normals_no_rot)( const GLmatrix *mat, + GLfloat scale, + const GLvector3f *in, + const GLfloat *lengths, + GLvector3f *dest ) +{ + GLuint i; + const GLfloat *from = in->start; + GLuint stride = in->stride; + GLuint count = in->count; + GLfloat (*out)[3] = (GLfloat (*)[3])dest->start; + const GLfloat *m = mat->inv; + GLfloat m0 = scale*m[0]; + GLfloat m5 = scale*m[5]; + GLfloat m10 = scale*m[10]; + (void) lengths; + STRIDE_LOOP { + GLfloat ux = from[0], uy = from[1], uz = from[2]; + out[i][0] = ux * m0; + out[i][1] = uy * m5; + out[i][2] = uz * m10; + } + dest->count = in->count; +} + +static void _XFORMAPI +TAG(transform_rescale_normals)( const GLmatrix *mat, + GLfloat scale, + const GLvector3f *in, + const GLfloat *lengths, + GLvector3f *dest ) +{ + GLuint i; + const GLfloat *from = in->start; + GLuint stride = in->stride; + GLuint count = in->count; + GLfloat (*out)[3] = (GLfloat (*)[3])dest->start; + /* Since we are unlikely to have < 3 vertices in the buffer, + * it makes sense to pre-multiply by scale. + */ + const GLfloat *m = mat->inv; + GLfloat m0 = scale*m[0], m4 = scale*m[4], m8 = scale*m[8]; + GLfloat m1 = scale*m[1], m5 = scale*m[5], m9 = scale*m[9]; + GLfloat m2 = scale*m[2], m6 = scale*m[6], m10 = scale*m[10]; + (void) lengths; + STRIDE_LOOP { + GLfloat ux = from[0], uy = from[1], uz = from[2]; + out[i][0] = ux * m0 + uy * m1 + uz * m2; + out[i][1] = ux * m4 + uy * m5 + uz * m6; + out[i][2] = ux * m8 + uy * m9 + uz * m10; + } + dest->count = in->count; +} + + +static void _XFORMAPI +TAG(transform_normals_no_rot)( const GLmatrix *mat, + GLfloat scale, + const GLvector3f *in, + const GLfloat *lengths, + GLvector3f *dest ) +{ + GLuint i; + const GLfloat *from = in->start; + GLuint stride = in->stride; + GLuint count = in->count; + GLfloat (*out)[3] = (GLfloat (*)[3])dest->start; + const GLfloat *m = mat->inv; + GLfloat m0 = m[0]; + GLfloat m5 = m[5]; + GLfloat m10 = m[10]; + (void) scale; + (void) lengths; + STRIDE_LOOP { + GLfloat ux = from[0], uy = from[1], uz = from[2]; + out[i][0] = ux * m0; + out[i][1] = uy * m5; + out[i][2] = uz * m10; + } + dest->count = in->count; +} + + +static void _XFORMAPI +TAG(transform_normals)( const GLmatrix *mat, + GLfloat scale, + const GLvector3f *in, + const GLfloat *lengths, + GLvector3f *dest ) +{ + GLuint i; + const GLfloat *from = in->start; + GLuint stride = in->stride; + GLuint count = in->count; + GLfloat (*out)[3] = (GLfloat (*)[3])dest->start; + const GLfloat *m = mat->inv; + GLfloat m0 = m[0], m4 = m[4], m8 = m[8]; + GLfloat m1 = m[1], m5 = m[5], m9 = m[9]; + GLfloat m2 = m[2], m6 = m[6], m10 = m[10]; + (void) scale; + (void) lengths; + STRIDE_LOOP { + GLfloat ux = from[0], uy = from[1], uz = from[2]; + out[i][0] = ux * m0 + uy * m1 + uz * m2; + out[i][1] = ux * m4 + uy * m5 + uz * m6; + out[i][2] = ux * m8 + uy * m9 + uz * m10; + } + dest->count = in->count; +} + + +static void _XFORMAPI +TAG(normalize_normals)( const GLmatrix *mat, + GLfloat scale, + const GLvector3f *in, + const GLfloat *lengths, + GLvector3f *dest ) +{ + GLuint i; + const GLfloat *from = in->start; + GLuint stride = in->stride; + GLuint count = in->count; + GLfloat (*out)[3] = (GLfloat (*)[3])dest->start; + (void) mat; + (void) scale; + if (lengths) { + STRIDE_LOOP { + const GLfloat x = from[0], y = from[1], z = from[2]; + GLfloat invlen = lengths[i]; + out[i][0] = x * invlen; + out[i][1] = y * invlen; + out[i][2] = z * invlen; + } + } + else { + STRIDE_LOOP { + const GLfloat x = from[0], y = from[1], z = from[2]; + GLdouble len = x * x + y * y + z * z; + if (len > 1e-50) { + len = 1.0 / GL_SQRT(len); + out[i][0] = (GLfloat) (x * len); + out[i][1] = (GLfloat) (y * len); + out[i][2] = (GLfloat) (z * len); + } + else { + out[i][0] = x; + out[i][1] = y; + out[i][2] = z; + } + } + } + dest->count = in->count; +} + + +static void _XFORMAPI +TAG(rescale_normals)( const GLmatrix *mat, + GLfloat scale, + const GLvector3f *in, + const GLfloat *lengths, + GLvector3f *dest ) +{ + GLuint i; + const GLfloat *from = in->start; + GLuint stride = in->stride; + GLuint count = in->count; + GLfloat (*out)[3] = (GLfloat (*)[3])dest->start; + (void) mat; + (void) lengths; + STRIDE_LOOP { + SCALE_SCALAR_3V( out[i], scale, from ); + } + dest->count = in->count; +} + + +static void _XFORMAPI +TAG(init_c_norm_transform)( void ) +{ + _mesa_normal_tab[NORM_TRANSFORM_NO_ROT] = + TAG(transform_normals_no_rot); + + _mesa_normal_tab[NORM_TRANSFORM_NO_ROT | NORM_RESCALE] = + TAG(transform_rescale_normals_no_rot); + + _mesa_normal_tab[NORM_TRANSFORM_NO_ROT | NORM_NORMALIZE] = + TAG(transform_normalize_normals_no_rot); + + _mesa_normal_tab[NORM_TRANSFORM] = + TAG(transform_normals); + + _mesa_normal_tab[NORM_TRANSFORM | NORM_RESCALE] = + TAG(transform_rescale_normals); + + _mesa_normal_tab[NORM_TRANSFORM | NORM_NORMALIZE] = + TAG(transform_normalize_normals); + + _mesa_normal_tab[NORM_RESCALE] = + TAG(rescale_normals); + + _mesa_normal_tab[NORM_NORMALIZE] = + TAG(normalize_normals); +} Index: dll/opengl/opengl32/mesa/math/m_trans_tmp.h =================================================================== --- dll/opengl/opengl32/mesa/math/m_trans_tmp.h (revision 0) +++ dll/opengl/opengl32/mesa/math/m_trans_tmp.h (working copy) @@ -0,0 +1,236 @@ +/* $Id: m_trans_tmp.h,v 1.5 2001/03/12 02:02:36 gareth Exp $ */ + +/* + * Mesa 3-D graphics library + * Version: 3.5 + * + * Copyright (C) 1999-2001 Brian Paul 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 + * BRIAN PAUL 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. + */ + +/* + * New (3.1) transformation code written by Keith Whitwell. + */ + + +/* KW: This file also included by tnl/trans_elt.c to build code + * specific to the implementation of array-elements in the + * tnl module. + */ + + +#ifdef DEST_4F +static void DEST_4F( GLfloat (*t)[4], + CONST void *ptr, + GLuint stride, + ARGS ) +{ + const GLubyte *f = (GLubyte *) ptr + SRC_START * stride; + const GLubyte *first = f; + GLuint i; + + (void) first; + (void) start; + for (i = DST_START ; i < n ; i++, NEXT_F) { + CHECK { + NEXT_F2; + if (SZ >= 1) t[i][0] = TRX_4F(f, 0); + if (SZ >= 2) t[i][1] = TRX_4F(f, 1); + if (SZ >= 3) t[i][2] = TRX_4F(f, 2); + if (SZ == 4) t[i][3] = TRX_4F(f, 3); + } + } +} +#endif + + +#ifdef DEST_3F +static void DEST_3F( GLfloat (*t)[3], + CONST void *ptr, + GLuint stride, + ARGS ) +{ + const GLubyte *f = (GLubyte *) ptr + SRC_START * stride; + const GLubyte *first = f; + GLuint i; + (void) first; + (void) start; + for (i = DST_START ; i < n ; i++, NEXT_F) { + CHECK { + NEXT_F2; + t[i][0] = TRX_3F(f, 0); + t[i][1] = TRX_3F(f, 1); + t[i][2] = TRX_3F(f, 2); + } + } +} +#endif + +#ifdef DEST_1F +static void DEST_1F( GLfloat *t, + CONST void *ptr, + GLuint stride, + ARGS ) +{ + const GLubyte *f = (GLubyte *) ptr + SRC_START * stride; + const GLubyte *first = f; + GLuint i; + (void) first; + (void) start; + for (i = DST_START ; i < n ; i++, NEXT_F) { + CHECK { + NEXT_F2; + t[i] = TRX_1F(f, 0); + } + } +} +#endif + +#ifdef DEST_4UB +static void DEST_4UB( GLubyte (*t)[4], + CONST void *ptr, + GLuint stride, + ARGS ) +{ + const GLubyte *f = (GLubyte *) ptr + SRC_START * stride; + const GLubyte *first = f; + GLuint i; + (void) start; + (void) first; + for (i = DST_START ; i < n ; i++, NEXT_F) { + CHECK { + NEXT_F2; + if (SZ >= 1) TRX_UB(t[i][0], f, 0); + if (SZ >= 2) TRX_UB(t[i][1], f, 1); + if (SZ >= 3) TRX_UB(t[i][2], f, 2); + if (SZ == 4) TRX_UB(t[i][3], f, 3); else t[i][3] = 255; + } + } +} +#endif + + +#ifdef DEST_4US +static void DEST_4US( GLushort (*t)[4], + CONST void *ptr, + GLuint stride, + ARGS ) +{ + const GLushort *f = (GLushort *) ptr + SRC_START * stride; + const GLushort *first = f; + GLuint i; + (void) start; + (void) first; + for (i = DST_START ; i < n ; i++, NEXT_F) { + CHECK { + NEXT_F2; + if (SZ >= 1) TRX_US(t[i][0], f, 0); + if (SZ >= 2) TRX_US(t[i][1], f, 1); + if (SZ >= 3) TRX_US(t[i][2], f, 2); + if (SZ == 4) TRX_US(t[i][3], f, 3); else t[i][3] = 65535; + } + } +} +#endif + + +#ifdef DEST_1UB +static void DEST_1UB( GLubyte *t, + CONST void *ptr, + GLuint stride, + ARGS ) +{ + const GLubyte *f = (GLubyte *) ptr + SRC_START * stride; + const GLubyte *first = f; + GLuint i; + (void) start; + (void) first; + for (i = DST_START ; i < n ; i++, NEXT_F) { + CHECK { + NEXT_F2; + TRX_UB(t[i], f, 0); + } + } +} +#endif + + +#ifdef DEST_1UI +static void DEST_1UI( GLuint *t, + CONST void *ptr, + GLuint stride, + ARGS ) +{ + const GLubyte *f = (GLubyte *) ptr + SRC_START * stride; + const GLubyte *first = f; + GLuint i; + (void) start; + (void) first; + + for (i = DST_START ; i < n ; i++, NEXT_F) { + CHECK { + NEXT_F2; + t[i] = TRX_UI(f, 0); + } + } +} +#endif + + +static void INIT(void) +{ +#ifdef DEST_1UI + ASSERT(SZ == 1); + TAB(_1ui)[SRC_IDX] = DEST_1UI; +#endif +#ifdef DEST_1UB + ASSERT(SZ == 1); + TAB(_1ub)[SRC_IDX] = DEST_1UB; +#endif +#ifdef DEST_1F + ASSERT(SZ == 1); + TAB(_1f)[SRC_IDX] = DEST_1F; +#endif +#ifdef DEST_3F + ASSERT(SZ == 3); + TAB(_3f)[SRC_IDX] = DEST_3F; +#endif +#ifdef DEST_4UB + TAB(_4ub)[SZ][SRC_IDX] = DEST_4UB; +#endif +#ifdef DEST_4US + TAB(_4us)[SZ][SRC_IDX] = DEST_4US; +#endif +#ifdef DEST_4F + TAB(_4f)[SZ][SRC_IDX] = DEST_4F; +#endif + +} + + +#undef INIT +#undef DEST_1UI +#undef DEST_1UB +#undef DEST_4UB +#undef DEST_4US +#undef DEST_3F +#undef DEST_4F +#undef DEST_1F +#undef SZ +#undef TAG Index: dll/opengl/opengl32/mesa/math/m_translate.c =================================================================== --- dll/opengl/opengl32/mesa/math/m_translate.c (revision 0) +++ dll/opengl/opengl32/mesa/math/m_translate.c (working copy) @@ -0,0 +1,663 @@ +/* $Id: m_translate.c,v 1.8 2001/05/09 14:12:34 keithw Exp $ */ + +/* + * Mesa 3-D graphics library + * Version: 3.5 + * + * Copyright (C) 1999-2001 Brian Paul 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 + * BRIAN PAUL 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. + */ + +/* + * New (3.1) transformation code written by Keith Whitwell. + */ + + +#include "glheader.h" +#include "mtypes.h" /* GLchan hack */ +#include "colormac.h" +#include "mem.h" +#include "mmath.h" + +#include "m_translate.h" + + + +typedef void (*trans_1f_func)(GLfloat *to, + CONST void *ptr, + GLuint stride, + GLuint start, + GLuint n ); + +typedef void (*trans_1ui_func)(GLuint *to, + CONST void *ptr, + GLuint stride, + GLuint start, + GLuint n ); + +typedef void (*trans_1ub_func)(GLubyte *to, + CONST void *ptr, + GLuint stride, + GLuint start, + GLuint n ); + +typedef void (*trans_4ub_func)(GLubyte (*to)[4], + CONST void *ptr, + GLuint stride, + GLuint start, + GLuint n ); + +typedef void (*trans_4us_func)(GLushort (*to)[4], + CONST void *ptr, + GLuint stride, + GLuint start, + GLuint n ); + +typedef void (*trans_4f_func)(GLfloat (*to)[4], + CONST void *ptr, + GLuint stride, + GLuint start, + GLuint n ); + +typedef void (*trans_3f_func)(GLfloat (*to)[3], + CONST void *ptr, + GLuint stride, + GLuint start, + GLuint n ); + + + + +#define TYPE_IDX(t) ((t) & 0xf) +#define MAX_TYPES TYPE_IDX(GL_DOUBLE)+1 /* 0xa + 1 */ + + +/* This macro is used on other systems, so undefine it for this module */ + +#undef CHECK + +static trans_1f_func _math_trans_1f_tab[MAX_TYPES]; +static trans_1ui_func _math_trans_1ui_tab[MAX_TYPES]; +static trans_1ub_func _math_trans_1ub_tab[MAX_TYPES]; +static trans_3f_func _math_trans_3f_tab[MAX_TYPES]; +static trans_4ub_func _math_trans_4ub_tab[5][MAX_TYPES]; +static trans_4us_func _math_trans_4us_tab[5][MAX_TYPES]; +static trans_4f_func _math_trans_4f_tab[5][MAX_TYPES]; + + +#define PTR_ELT(ptr, elt) (((SRC *)ptr)[elt]) + + +#define TAB(x) _math_trans##x##_tab +#define ARGS GLuint start, GLuint n +#define SRC_START start +#define DST_START 0 +#define STRIDE stride +#define NEXT_F f += stride +#define NEXT_F2 +#define CHECK + + + + +/* GL_BYTE + */ +#define SRC GLbyte +#define SRC_IDX TYPE_IDX(GL_BYTE) +#define TRX_3F(f,n) BYTE_TO_FLOAT( PTR_ELT(f,n) ) +#define TRX_4F(f,n) BYTE_TO_FLOAT( PTR_ELT(f,n) ) +#define TRX_UB(ub, f,n) ub = BYTE_TO_UBYTE( PTR_ELT(f,n) ) +#define TRX_US(ch, f,n) ch = BYTE_TO_USHORT( PTR_ELT(f,n) ) +#define TRX_UI(f,n) (PTR_ELT(f,n) < 0 ? 0 : (GLuint) PTR_ELT(f,n)) + + +#define SZ 4 +#define INIT init_trans_4_GLbyte_raw +#define DEST_4F trans_4_GLbyte_4f_raw +#define DEST_4UB trans_4_GLbyte_4ub_raw +#define DEST_4US trans_4_GLbyte_4us_raw +#include "m_trans_tmp.h" + +#define SZ 3 +#define INIT init_trans_3_GLbyte_raw +#define DEST_4F trans_3_GLbyte_4f_raw +#define DEST_4UB trans_3_GLbyte_4ub_raw +#define DEST_4US trans_3_GLbyte_4us_raw +#define DEST_3F trans_3_GLbyte_3f_raw +#include "m_trans_tmp.h" + +#define SZ 2 +#define INIT init_trans_2_GLbyte_raw +#define DEST_4F trans_2_GLbyte_4f_raw +#include "m_trans_tmp.h" + +#define SZ 1 +#define INIT init_trans_1_GLbyte_raw +#define DEST_4F trans_1_GLbyte_4f_raw +#define DEST_1UB trans_1_GLbyte_1ub_raw +#define DEST_1UI trans_1_GLbyte_1ui_raw +#include "m_trans_tmp.h" + +#undef SRC +#undef TRX_3F +#undef TRX_4F +#undef TRX_UB +#undef TRX_US +#undef TRX_UI +#undef SRC_IDX + + +/* GL_UNSIGNED_BYTE + */ +#define SRC GLubyte +#define SRC_IDX TYPE_IDX(GL_UNSIGNED_BYTE) +#define TRX_3F(f,n) UBYTE_TO_FLOAT(PTR_ELT(f,n)) +#define TRX_4F(f,n) UBYTE_TO_FLOAT(PTR_ELT(f,n)) +#define TRX_UB(ub, f,n) ub = PTR_ELT(f,n) +#define TRX_US(us, f,n) us = UBYTE_TO_USHORT(PTR_ELT(f,n)) +#define TRX_UI(f,n) (GLuint)PTR_ELT(f,n) + +/* 4ub->4ub handled in special case below. + */ +#define SZ 4 +#define INIT init_trans_4_GLubyte_raw +#define DEST_4F trans_4_GLubyte_4f_raw +#define DEST_4US trans_4_GLubyte_4us_raw +#include "m_trans_tmp.h" + + +#define SZ 3 +#define INIT init_trans_3_GLubyte_raw +#define DEST_4UB trans_3_GLubyte_4ub_raw +#define DEST_4US trans_3_GLubyte_4us_raw +#define DEST_3F trans_3_GLubyte_3f_raw +#define DEST_4F trans_3_GLubyte_4f_raw +#include "m_trans_tmp.h" + + +#define SZ 1 +#define INIT init_trans_1_GLubyte_raw +#define DEST_1UI trans_1_GLubyte_1ui_raw +#define DEST_1UB trans_1_GLubyte_1ub_raw +#include "m_trans_tmp.h" + +#undef SRC +#undef SRC_IDX +#undef TRX_3F +#undef TRX_4F +#undef TRX_UB +#undef TRX_US +#undef TRX_UI + + +/* GL_SHORT + */ +#define SRC GLshort +#define SRC_IDX TYPE_IDX(GL_SHORT) +#define TRX_3F(f,n) SHORT_TO_FLOAT( PTR_ELT(f,n) ) +#define TRX_4F(f,n) (GLfloat)( PTR_ELT(f,n) ) +#define TRX_UB(ub, f,n) ub = SHORT_TO_UBYTE(PTR_ELT(f,n)) +#define TRX_US(us, f,n) us = SHORT_TO_USHORT(PTR_ELT(f,n)) +#define TRX_UI(f,n) (PTR_ELT(f,n) < 0 ? 0 : (GLuint) PTR_ELT(f,n)) + + +#define SZ 4 +#define INIT init_trans_4_GLshort_raw +#define DEST_4F trans_4_GLshort_4f_raw +#define DEST_4UB trans_4_GLshort_4ub_raw +#define DEST_4US trans_4_GLshort_4us_raw +#include "m_trans_tmp.h" + +#define SZ 3 +#define INIT init_trans_3_GLshort_raw +#define DEST_4F trans_3_GLshort_4f_raw +#define DEST_4UB trans_3_GLshort_4ub_raw +#define DEST_4US trans_3_GLshort_4us_raw +#define DEST_3F trans_3_GLshort_3f_raw +#include "m_trans_tmp.h" + +#define SZ 2 +#define INIT init_trans_2_GLshort_raw +#define DEST_4F trans_2_GLshort_4f_raw +#include "m_trans_tmp.h" + +#define SZ 1 +#define INIT init_trans_1_GLshort_raw +#define DEST_4F trans_1_GLshort_4f_raw +#define DEST_1UB trans_1_GLshort_1ub_raw +#define DEST_1UI trans_1_GLshort_1ui_raw +#include "m_trans_tmp.h" + + +#undef SRC +#undef SRC_IDX +#undef TRX_3F +#undef TRX_4F +#undef TRX_UB +#undef TRX_US +#undef TRX_UI + + +/* GL_UNSIGNED_SHORT + */ +#define SRC GLushort +#define SRC_IDX TYPE_IDX(GL_UNSIGNED_SHORT) +#define TRX_3F(f,n) USHORT_TO_FLOAT( PTR_ELT(f,n) ) +#define TRX_4F(f,n) (GLfloat)( PTR_ELT(f,n) ) +#define TRX_UB(ub,f,n) ub = (GLubyte) (PTR_ELT(f,n) >> 8) +#define TRX_US(us,f,n) us = (GLushort) (PTR_ELT(f,n) >> 8) +#define TRX_UI(f,n) (GLuint) PTR_ELT(f,n) + + +#define SZ 4 +#define INIT init_trans_4_GLushort_raw +#define DEST_4F trans_4_GLushort_4f_raw +#define DEST_4UB trans_4_GLushort_4ub_raw +#define DEST_4US trans_4_GLushort_4us_raw +#include "m_trans_tmp.h" + +#define SZ 3 +#define INIT init_trans_3_GLushort_raw +#define DEST_4F trans_3_GLushort_4f_raw +#define DEST_4UB trans_3_GLushort_4ub_raw +#define DEST_4US trans_3_GLushort_4us_raw +#define DEST_3F trans_3_GLushort_3f_raw +#include "m_trans_tmp.h" + +#define SZ 2 +#define INIT init_trans_2_GLushort_raw +#define DEST_4F trans_2_GLushort_4f_raw +#include "m_trans_tmp.h" + +#define SZ 1 +#define INIT init_trans_1_GLushort_raw +#define DEST_4F trans_1_GLushort_4f_raw +#define DEST_1UB trans_1_GLushort_1ub_raw +#define DEST_1UI trans_1_GLushort_1ui_raw +#include "m_trans_tmp.h" + +#undef SRC +#undef SRC_IDX +#undef TRX_3F +#undef TRX_4F +#undef TRX_UB +#undef TRX_US +#undef TRX_UI + + +/* GL_INT + */ +#define SRC GLint +#define SRC_IDX TYPE_IDX(GL_INT) +#define TRX_3F(f,n) INT_TO_FLOAT( PTR_ELT(f,n) ) +#define TRX_4F(f,n) (GLfloat)( PTR_ELT(f,n) ) +#define TRX_UB(ub, f,n) ub = INT_TO_UBYTE(PTR_ELT(f,n)) +#define TRX_US(us, f,n) us = INT_TO_USHORT(PTR_ELT(f,n)) +#define TRX_UI(f,n) (PTR_ELT(f,n) < 0 ? 0 : (GLuint) PTR_ELT(f,n)) + + +#define SZ 4 +#define INIT init_trans_4_GLint_raw +#define DEST_4F trans_4_GLint_4f_raw +#define DEST_4UB trans_4_GLint_4ub_raw +#define DEST_4US trans_4_GLint_4us_raw +#include "m_trans_tmp.h" + +#define SZ 3 +#define INIT init_trans_3_GLint_raw +#define DEST_4F trans_3_GLint_4f_raw +#define DEST_4UB trans_3_GLint_4ub_raw +#define DEST_4US trans_3_GLint_4us_raw +#define DEST_3F trans_3_GLint_3f_raw +#include "m_trans_tmp.h" + +#define SZ 2 +#define INIT init_trans_2_GLint_raw +#define DEST_4F trans_2_GLint_4f_raw +#include "m_trans_tmp.h" + +#define SZ 1 +#define INIT init_trans_1_GLint_raw +#define DEST_4F trans_1_GLint_4f_raw +#define DEST_1UB trans_1_GLint_1ub_raw +#define DEST_1UI trans_1_GLint_1ui_raw +#include "m_trans_tmp.h" + + +#undef SRC +#undef SRC_IDX +#undef TRX_3F +#undef TRX_4F +#undef TRX_UB +#undef TRX_US +#undef TRX_UI + + +/* GL_UNSIGNED_INT + */ +#define SRC GLuint +#define SRC_IDX TYPE_IDX(GL_UNSIGNED_INT) +#define TRX_3F(f,n) INT_TO_FLOAT( PTR_ELT(f,n) ) +#define TRX_4F(f,n) (GLfloat)( PTR_ELT(f,n) ) +#define TRX_UB(ub, f,n) ub = (GLubyte) (PTR_ELT(f,n) >> 24) +#define TRX_US(us, f,n) us = (GLshort) (PTR_ELT(f,n) >> 16) +#define TRX_UI(f,n) PTR_ELT(f,n) + + +#define SZ 4 +#define INIT init_trans_4_GLuint_raw +#define DEST_4F trans_4_GLuint_4f_raw +#define DEST_4UB trans_4_GLuint_4ub_raw +#define DEST_4US trans_4_GLuint_4us_raw +#include "m_trans_tmp.h" + +#define SZ 3 +#define INIT init_trans_3_GLuint_raw +#define DEST_4F trans_3_GLuint_4f_raw +#define DEST_4UB trans_3_GLuint_4ub_raw +#define DEST_4US trans_3_GLuint_4us_raw +#define DEST_3F trans_3_GLuint_3f_raw +#include "m_trans_tmp.h" + +#define SZ 2 +#define INIT init_trans_2_GLuint_raw +#define DEST_4F trans_2_GLuint_4f_raw +#include "m_trans_tmp.h" + +#define SZ 1 +#define INIT init_trans_1_GLuint_raw +#define DEST_4F trans_1_GLuint_4f_raw +#define DEST_1UB trans_1_GLuint_1ub_raw +#define DEST_1UI trans_1_GLuint_1ui_raw +#include "m_trans_tmp.h" + +#undef SRC +#undef SRC_IDX +#undef TRX_3F +#undef TRX_4F +#undef TRX_UB +#undef TRX_US +#undef TRX_UI + + +/* GL_DOUBLE + */ +#define SRC GLdouble +#define SRC_IDX TYPE_IDX(GL_DOUBLE) +#define TRX_3F(f,n) PTR_ELT(f,n) +#define TRX_4F(f,n) PTR_ELT(f,n) +#define TRX_UB(ub,f,n) UNCLAMPED_FLOAT_TO_UBYTE(ub, PTR_ELT(f,n)) +#define TRX_US(us,f,n) UNCLAMPED_FLOAT_TO_USHORT(us, PTR_ELT(f,n)) +#define TRX_UI(f,n) (GLuint) (GLint) PTR_ELT(f,n) +#define TRX_1F(f,n) PTR_ELT(f,n) + + +#define SZ 4 +#define INIT init_trans_4_GLdouble_raw +#define DEST_4F trans_4_GLdouble_4f_raw +#define DEST_4UB trans_4_GLdouble_4ub_raw +#define DEST_4US trans_4_GLdouble_4us_raw +#include "m_trans_tmp.h" + +#define SZ 3 +#define INIT init_trans_3_GLdouble_raw +#define DEST_4F trans_3_GLdouble_4f_raw +#define DEST_4UB trans_3_GLdouble_4ub_raw +#define DEST_4US trans_3_GLdouble_4us_raw +#define DEST_3F trans_3_GLdouble_3f_raw +#include "m_trans_tmp.h" + +#define SZ 2 +#define INIT init_trans_2_GLdouble_raw +#define DEST_4F trans_2_GLdouble_4f_raw +#include "m_trans_tmp.h" + +#define SZ 1 +#define INIT init_trans_1_GLdouble_raw +#define DEST_4F trans_1_GLdouble_4f_raw +#define DEST_1UB trans_1_GLdouble_1ub_raw +#define DEST_1UI trans_1_GLdouble_1ui_raw +#define DEST_1F trans_1_GLdouble_1f_raw +#include "m_trans_tmp.h" + +#undef SRC +#undef SRC_IDX + +/* GL_FLOAT + */ +#define SRC GLfloat +#define SRC_IDX TYPE_IDX(GL_FLOAT) +#define SZ 4 +#define INIT init_trans_4_GLfloat_raw +#define DEST_4UB trans_4_GLfloat_4ub_raw +#define DEST_4US trans_4_GLfloat_4us_raw +#define DEST_4F trans_4_GLfloat_4f_raw +#include "m_trans_tmp.h" + +#define SZ 3 +#define INIT init_trans_3_GLfloat_raw +#define DEST_4F trans_3_GLfloat_4f_raw +#define DEST_4UB trans_3_GLfloat_4ub_raw +#define DEST_4US trans_3_GLfloat_4us_raw +#define DEST_3F trans_3_GLfloat_3f_raw +#include "m_trans_tmp.h" + +#define SZ 2 +#define INIT init_trans_2_GLfloat_raw +#define DEST_4F trans_2_GLfloat_4f_raw +#include "m_trans_tmp.h" + +#define SZ 1 +#define INIT init_trans_1_GLfloat_raw +#define DEST_4F trans_1_GLfloat_4f_raw +#define DEST_1UB trans_1_GLfloat_1ub_raw +#define DEST_1UI trans_1_GLfloat_1ui_raw +#define DEST_1F trans_1_GLfloat_1f_raw + +#include "m_trans_tmp.h" + +#undef SRC +#undef SRC_IDX +#undef TRX_3F +#undef TRX_4F +#undef TRX_UB +#undef TRX_US +#undef TRX_UI + + +static void trans_4_GLubyte_4ub_raw(GLubyte (*t)[4], + CONST void *Ptr, + GLuint stride, + ARGS ) +{ + const GLubyte *f = (GLubyte *) Ptr + SRC_START * stride; + GLuint i; + + if (((((long) f | (long) stride)) & 3L) == 0L) { + /* Aligned. + */ + for (i = DST_START ; i < n ; i++, f += stride) { + COPY_4UBV( t[i], f ); + } + } else { + for (i = DST_START ; i < n ; i++, f += stride) { + t[i][0] = f[0]; + t[i][1] = f[1]; + t[i][2] = f[2]; + t[i][3] = f[3]; + } + } +} + + +static void init_translate_raw(void) +{ + MEMSET( TAB(_1ui), 0, sizeof(TAB(_1ui)) ); + MEMSET( TAB(_1ub), 0, sizeof(TAB(_1ub)) ); + MEMSET( TAB(_3f), 0, sizeof(TAB(_3f)) ); + MEMSET( TAB(_4ub), 0, sizeof(TAB(_4ub)) ); + MEMSET( TAB(_4us), 0, sizeof(TAB(_4us)) ); + MEMSET( TAB(_4f), 0, sizeof(TAB(_4f)) ); + + init_trans_4_GLbyte_raw(); + init_trans_3_GLbyte_raw(); + init_trans_2_GLbyte_raw(); + init_trans_1_GLbyte_raw(); + init_trans_1_GLubyte_raw(); + init_trans_3_GLubyte_raw(); + init_trans_4_GLubyte_raw(); + init_trans_4_GLshort_raw(); + init_trans_3_GLshort_raw(); + init_trans_2_GLshort_raw(); + init_trans_1_GLshort_raw(); + init_trans_4_GLushort_raw(); + init_trans_3_GLushort_raw(); + init_trans_2_GLushort_raw(); + init_trans_1_GLushort_raw(); + init_trans_4_GLint_raw(); + init_trans_3_GLint_raw(); + init_trans_2_GLint_raw(); + init_trans_1_GLint_raw(); + init_trans_4_GLuint_raw(); + init_trans_3_GLuint_raw(); + init_trans_2_GLuint_raw(); + init_trans_1_GLuint_raw(); + init_trans_4_GLdouble_raw(); + init_trans_3_GLdouble_raw(); + init_trans_2_GLdouble_raw(); + init_trans_1_GLdouble_raw(); + init_trans_4_GLfloat_raw(); + init_trans_3_GLfloat_raw(); + init_trans_2_GLfloat_raw(); + init_trans_1_GLfloat_raw(); + + TAB(_4ub)[4][TYPE_IDX(GL_UNSIGNED_BYTE)] = trans_4_GLubyte_4ub_raw; +} + + +#undef TAB +#undef CLASS +#undef ARGS +#undef CHECK +#undef SRC_START +#undef DST_START +#undef NEXT_F +#undef NEXT_F2 + + + + + +void _math_init_translate( void ) +{ + init_translate_raw(); +} + + + +void _math_trans_1f(GLfloat *to, + CONST void *ptr, + GLuint stride, + GLenum type, + GLuint start, + GLuint n ) +{ + _math_trans_1f_tab[TYPE_IDX(type)]( to, ptr, stride, start, n ); +} + +void _math_trans_1ui(GLuint *to, + CONST void *ptr, + GLuint stride, + GLenum type, + GLuint start, + GLuint n ) +{ + _math_trans_1ui_tab[TYPE_IDX(type)]( to, ptr, stride, start, n ); +} + +void _math_trans_1ub(GLubyte *to, + CONST void *ptr, + GLuint stride, + GLenum type, + GLuint start, + GLuint n ) +{ + _math_trans_1ub_tab[TYPE_IDX(type)]( to, ptr, stride, start, n ); +} + + +void _math_trans_4ub(GLubyte (*to)[4], + CONST void *ptr, + GLuint stride, + GLenum type, + GLuint size, + GLuint start, + GLuint n ) +{ + _math_trans_4ub_tab[size][TYPE_IDX(type)]( to, ptr, stride, start, n ); +} + +void _math_trans_4chan( GLchan (*to)[4], + CONST void *ptr, + GLuint stride, + GLenum type, + GLuint size, + GLuint start, + GLuint n ) +{ +#if CHAN_TYPE == GL_UNSIGNED_BYTE + _math_trans_4ub( to, ptr, stride, type, size, start, n ); +#elif CHAN_TYPE == GL_UNSIGNED_SHORT + _math_trans_4us( to, ptr, stride, type, size, start, n ); +#elif CHAN_TYPE == GL_FLOAT + _math_trans_4f( to, ptr, stride, type, size, start, n ); +#endif +} + +void _math_trans_4us(GLushort (*to)[4], + CONST void *ptr, + GLuint stride, + GLenum type, + GLuint size, + GLuint start, + GLuint n ) +{ + _math_trans_4us_tab[size][TYPE_IDX(type)]( to, ptr, stride, start, n ); +} + +void _math_trans_4f(GLfloat (*to)[4], + CONST void *ptr, + GLuint stride, + GLenum type, + GLuint size, + GLuint start, + GLuint n ) +{ + _math_trans_4f_tab[size][TYPE_IDX(type)]( to, ptr, stride, start, n ); +} + +void _math_trans_3f(GLfloat (*to)[3], + CONST void *ptr, + GLuint stride, + GLenum type, + GLuint start, + GLuint n ) +{ + _math_trans_3f_tab[TYPE_IDX(type)]( to, ptr, stride, start, n ); +} Index: dll/opengl/opengl32/mesa/math/m_translate.h =================================================================== --- dll/opengl/opengl32/mesa/math/m_translate.h (revision 0) +++ dll/opengl/opengl32/mesa/math/m_translate.h (working copy) @@ -0,0 +1,99 @@ +/* $Id: m_translate.h,v 1.6 2001/03/12 00:48:41 gareth Exp $ */ + +/* + * Mesa 3-D graphics library + * Version: 3.5 + * + * Copyright (C) 1999-2001 Brian Paul 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 + * BRIAN PAUL 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. + */ + + +#ifndef _M_TRANSLATE_H_ +#define _M_TRANSLATE_H_ + +#include "config.h" +#include "mtypes.h" /* hack for GLchan */ + + + +extern void _math_trans_1f(GLfloat *to, + CONST void *ptr, + GLuint stride, + GLenum type, + GLuint start, + GLuint n ); + +extern void _math_trans_1ui(GLuint *to, + CONST void *ptr, + GLuint stride, + GLenum type, + GLuint start, + GLuint n ); + +extern void _math_trans_1ub(GLubyte *to, + CONST void *ptr, + GLuint stride, + GLenum type, + GLuint start, + GLuint n ); + +extern void _math_trans_4ub(GLubyte (*to)[4], + CONST void *ptr, + GLuint stride, + GLenum type, + GLuint size, + GLuint start, + GLuint n ); + +extern void _math_trans_4chan( GLchan (*to)[4], + CONST void *ptr, + GLuint stride, + GLenum type, + GLuint size, + GLuint start, + GLuint n ); + +extern void _math_trans_4us(GLushort (*to)[4], + CONST void *ptr, + GLuint stride, + GLenum type, + GLuint size, + GLuint start, + GLuint n ); + +extern void _math_trans_4f(GLfloat (*to)[4], + CONST void *ptr, + GLuint stride, + GLenum type, + GLuint size, + GLuint start, + GLuint n ); + +extern void _math_trans_3f(GLfloat (*to)[3], + CONST void *ptr, + GLuint stride, + GLenum type, + GLuint start, + GLuint n ); + +extern void _math_init_translate( void ); + + +#endif Index: dll/opengl/opengl32/mesa/math/m_vector.c =================================================================== --- dll/opengl/opengl32/mesa/math/m_vector.c (revision 0) +++ dll/opengl/opengl32/mesa/math/m_vector.c (working copy) @@ -0,0 +1,429 @@ +/* $Id: m_vector.c,v 1.6 2001/03/12 00:48:41 gareth Exp $ */ + +/* + * Mesa 3-D graphics library + * Version: 3.5 + * + * Copyright (C) 1999-2001 Brian Paul 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 + * BRIAN PAUL 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. + */ + +/* + * New (3.1) transformation code written by Keith Whitwell. + */ + + +#include "glheader.h" +#include "macros.h" +#include "mem.h" + +#include "m_vector.h" + + + +/* + * Given a vector [count][4] of floats, set all the [][elt] values + * to 0 (if elt = 0, 1, 2) or 1.0 (if elt = 3). + */ +void _mesa_vector4f_clean_elem( GLvector4f *vec, GLuint count, GLuint elt ) +{ + static const GLubyte elem_bits[4] = { + VEC_DIRTY_0, + VEC_DIRTY_1, + VEC_DIRTY_2, + VEC_DIRTY_3 + }; + static const GLfloat clean[4] = { 0, 0, 0, 1 }; + const GLfloat v = clean[elt]; + GLfloat (*data)[4] = (GLfloat (*)[4])vec->start; + GLuint i; + + for (i = 0 ; i < count ; i++) + data[i][elt] = v; + + vec->flags &= ~elem_bits[elt]; +} + +static const GLubyte size_bits[5] = { + 0, + VEC_SIZE_1, + VEC_SIZE_2, + VEC_SIZE_3, + VEC_SIZE_4, +}; + + + +/* + * Initialize GLvector objects. + * Input: v - the vector object to initialize. + * flags - bitwise-OR of VEC_* flags + * storage - pointer to storage for the vector's data + */ + + +void _mesa_vector4f_init( GLvector4f *v, GLuint flags, GLfloat (*storage)[4] ) +{ + v->stride = 4 * sizeof(GLfloat); + v->size = 2; /* may change: 2-4 for vertices and 1-4 for texcoords */ + v->data = storage; + v->start = (GLfloat *) storage; + v->count = 0; + v->flags = size_bits[4] | flags ; +} + +void _mesa_vector3f_init( GLvector3f *v, GLuint flags, GLfloat (*storage)[3] ) +{ + v->stride = 3 * sizeof(GLfloat); + v->data = storage; + v->start = (GLfloat *) storage; + v->count = 0; + v->flags = flags ; +} + +void _mesa_vector1f_init( GLvector1f *v, GLuint flags, GLfloat *storage ) +{ + v->stride = 1*sizeof(GLfloat); + v->data = storage; + v->start = (GLfloat *)storage; + v->count = 0; + v->flags = flags ; +} + +void _mesa_vector4ub_init( GLvector4ub *v, GLuint flags, GLubyte (*storage)[4] ) +{ + v->stride = 4 * sizeof(GLubyte); + v->data = storage; + v->start = (GLubyte *) storage; + v->count = 0; + v->flags = flags ; +} + +void _mesa_vector4chan_init( GLvector4chan *v, GLuint flags, GLchan (*storage)[4] ) +{ + v->stride = 4 * sizeof(GLchan); + v->data = storage; + v->start = (GLchan *) storage; + v->count = 0; + v->flags = flags ; +} + +void _mesa_vector4us_init( GLvector4us *v, GLuint flags, GLushort (*storage)[4] ) +{ + v->stride = 4 * sizeof(GLushort); + v->data = storage; + v->start = (GLushort *) storage; + v->count = 0; + v->flags = flags ; +} + +void _mesa_vector1ub_init( GLvector1ub *v, GLuint flags, GLubyte *storage ) +{ + v->stride = 1 * sizeof(GLubyte); + v->data = storage; + v->start = (GLubyte *) storage; + v->count = 0; + v->flags = flags ; +} + +void _mesa_vector1ui_init( GLvector1ui *v, GLuint flags, GLuint *storage ) +{ + v->stride = 1 * sizeof(GLuint); + v->data = storage; + v->start = (GLuint *) storage; + v->count = 0; + v->flags = flags ; +} + + +/* + * Initialize GLvector objects and allocate storage. + * Input: v - the vector object + * sz - unused???? + * flags - bitwise-OR of VEC_* flags + * count - number of elements to allocate in vector + * alignment - desired memory alignment for the data (in bytes) + */ + + +void _mesa_vector4f_alloc( GLvector4f *v, GLuint flags, GLuint count, + GLuint alignment ) +{ + v->stride = 4 * sizeof(GLfloat); + v->size = 2; + v->storage = ALIGN_MALLOC( count * 4 * sizeof(GLfloat), alignment ); + v->start = (GLfloat *) v->storage; + v->data = (GLfloat (*)[4]) v->storage; + v->count = 0; + v->flags = size_bits[4] | flags | VEC_MALLOC ; +} + +void _mesa_vector3f_alloc( GLvector3f *v, GLuint flags, GLuint count, + GLuint alignment ) +{ + v->stride = 3 * sizeof(GLfloat); + v->storage = ALIGN_MALLOC( count * 3 * sizeof(GLfloat), alignment ); + v->start = (GLfloat *) v->storage; + v->data = (GLfloat (*)[3]) v->storage; + v->count = 0; + v->flags = flags | VEC_MALLOC ; +} + +void _mesa_vector1f_alloc( GLvector1f *v, GLuint flags, GLuint count, + GLuint alignment ) +{ + v->stride = sizeof(GLfloat); + v->storage = v->start = (GLfloat *) + ALIGN_MALLOC( count * sizeof(GLfloat), alignment ); + v->data = v->start; + v->count = 0; + v->flags = flags | VEC_MALLOC ; +} + +void _mesa_vector4ub_alloc( GLvector4ub *v, GLuint flags, GLuint count, + GLuint alignment ) +{ + v->stride = 4 * sizeof(GLubyte); + v->storage = ALIGN_MALLOC( count * 4 * sizeof(GLubyte), alignment ); + v->start = (GLubyte *) v->storage; + v->data = (GLubyte (*)[4]) v->storage; + v->count = 0; + v->flags = flags | VEC_MALLOC ; +} + +void _mesa_vector4chan_alloc( GLvector4chan *v, GLuint flags, GLuint count, + GLuint alignment ) +{ + v->stride = 4 * sizeof(GLchan); + v->storage = ALIGN_MALLOC( count * 4 * sizeof(GLchan), alignment ); + v->start = (GLchan *) v->storage; + v->data = (GLchan (*)[4]) v->storage; + v->count = 0; + v->flags = flags | VEC_MALLOC ; +} + +void _mesa_vector4us_alloc( GLvector4us *v, GLuint flags, GLuint count, + GLuint alignment ) +{ + v->stride = 4 * sizeof(GLushort); + v->storage = ALIGN_MALLOC( count * 4 * sizeof(GLushort), alignment ); + v->start = (GLushort *) v->storage; + v->data = (GLushort (*)[4]) v->storage; + v->count = 0; + v->flags = flags | VEC_MALLOC ; +} + +void _mesa_vector1ub_alloc( GLvector1ub *v, GLuint flags, GLuint count, + GLuint alignment ) +{ + v->stride = 1 * sizeof(GLubyte); + v->storage = ALIGN_MALLOC( count * sizeof(GLubyte), alignment ); + v->start = (GLubyte *) v->storage; + v->data = (GLubyte *) v->storage; + v->count = 0; + v->flags = flags | VEC_MALLOC ; +} + +void _mesa_vector1ui_alloc( GLvector1ui *v, GLuint flags, GLuint count, + GLuint alignment ) +{ + v->stride = 1 * sizeof(GLuint); + v->storage = ALIGN_MALLOC( count * sizeof(GLuint), alignment ); + v->start = (GLuint *) v->storage; + v->data = (GLuint *) v->storage; + v->count = 0; + v->flags = flags | VEC_MALLOC ; +} + + + +/* + * Vector deallocation. Free whatever memory is pointed to by the + * vector's storage field if the VEC_MALLOC flag is set. + * DO NOT free the GLvector object itself, though. + */ + + +void _mesa_vector4f_free( GLvector4f *v ) +{ + if (v->flags & VEC_MALLOC) { + ALIGN_FREE( v->storage ); + v->data = NULL; + v->start = NULL; + v->storage = NULL; + v->flags &= ~VEC_MALLOC; + } +} + +void _mesa_vector3f_free( GLvector3f *v ) +{ + if (v->flags & VEC_MALLOC) { + ALIGN_FREE( v->storage ); + v->data = 0; + v->start = 0; + v->storage = 0; + v->flags &= ~VEC_MALLOC; + } +} + +void _mesa_vector1f_free( GLvector1f *v ) +{ + if (v->flags & VEC_MALLOC) { + ALIGN_FREE( v->storage ); + v->data = NULL; + v->start = NULL; + v->storage = NULL; + v->flags &= ~VEC_MALLOC; + } +} + +void _mesa_vector4ub_free( GLvector4ub *v ) +{ + if (v->flags & VEC_MALLOC) { + ALIGN_FREE( v->storage ); + v->data = NULL; + v->start = NULL; + v->storage = NULL; + v->flags &= ~VEC_MALLOC; + } +} + +void _mesa_vector4chan_free( GLvector4chan *v ) +{ + if (v->flags & VEC_MALLOC) { + ALIGN_FREE( v->storage ); + v->data = NULL; + v->start = NULL; + v->storage = NULL; + v->flags &= ~VEC_MALLOC; + } +} + +void _mesa_vector4us_free( GLvector4us *v ) +{ + if (v->flags & VEC_MALLOC) { + ALIGN_FREE( v->storage ); + v->data = NULL; + v->start = NULL; + v->storage = NULL; + v->flags &= ~VEC_MALLOC; + } +} + +void _mesa_vector1ub_free( GLvector1ub *v ) +{ + if (v->flags & VEC_MALLOC) { + ALIGN_FREE( v->storage ); + v->data = NULL; + v->start = NULL; + v->storage = NULL; + v->flags &= ~VEC_MALLOC; + } +} + +void _mesa_vector1ui_free( GLvector1ui *v ) +{ + if (v->flags & VEC_MALLOC) { + ALIGN_FREE( v->storage ); + v->data = NULL; + v->start = NULL; + v->storage = NULL; + v->flags &= ~VEC_MALLOC; + } +} + + +/* + * For debugging + */ +void _mesa_vector4f_print( GLvector4f *v, GLubyte *cullmask, GLboolean culling ) +{ + GLfloat c[4] = { 0, 0, 0, 1 }; + const char *templates[5] = { + "%d:\t0, 0, 0, 1\n", + "%d:\t%f, 0, 0, 1\n", + "%d:\t%f, %f, 0, 1\n", + "%d:\t%f, %f, %f, 1\n", + "%d:\t%f, %f, %f, %f\n" + }; + + const char *t = templates[v->size]; + GLfloat *d = (GLfloat *)v->data; + GLuint j, i = 0, count; + + printf("data-start\n"); + for ( ; d != v->start ; STRIDE_F(d, v->stride), i++) + printf( t, i, d[0], d[1], d[2], d[3]); + + printf("start-count(%u)\n", v->count); + count = i + v->count; + + if (culling) { + for ( ; i < count ; STRIDE_F(d, v->stride), i++) + if (cullmask[i]) + printf( t, i, d[0], d[1], d[2], d[3]); + } + else { + for ( ; i < count ; STRIDE_F(d, v->stride), i++) + printf( t, i, d[0], d[1], d[2], d[3]); + } + + for (j = v->size ; j < 4; j++) { + if ((v->flags & (1<data ; + i < count && d[j] == c[j] ; + i++, STRIDE_F(d, v->stride)) {}; + + if (i == count) + printf(" --> ok\n"); + else + printf(" --> Failed at %u ******\n", i); + } + } +} + + +/* + * For debugging + */ +void _mesa_vector3f_print( GLvector3f *v, GLubyte *cullmask, GLboolean culling ) +{ + GLfloat *d = (GLfloat *)v->data; + GLuint i = 0, count; + + printf("data-start\n"); + for ( ; d != v->start ; STRIDE_F(d,v->stride), i++) + printf( "%u:\t%f, %f, %f\n", i, d[0], d[1], d[2]); + + printf("start-count(%u)\n", v->count); + count = i + v->count; + + if (culling) { + for ( ; i < count ; STRIDE_F(d,v->stride), i++) + if (cullmask[i]) + printf( "%u:\t%f, %f, %f\n", i, d[0], d[1], d[2]); + } + else { + for ( ; i < count ; STRIDE_F(d,v->stride), i++) + printf( "%u:\t%f, %f, %f\n", i, d[0], d[1], d[2]); + } +} Index: dll/opengl/opengl32/mesa/math/m_vector.h =================================================================== --- dll/opengl/opengl32/mesa/math/m_vector.h (revision 0) +++ dll/opengl/opengl32/mesa/math/m_vector.h (working copy) @@ -0,0 +1,222 @@ +/* $Id: m_vector.h,v 1.6 2001/03/12 00:48:41 gareth Exp $ */ + +/* + * Mesa 3-D graphics library + * Version: 3.5 + * + * Copyright (C) 1999-2001 Brian Paul 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 + * BRIAN PAUL 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. + */ + +/* + * New (3.1) transformation code written by Keith Whitwell. + */ + + +#ifndef _M_VECTOR_H_ +#define _M_VECTOR_H_ + +#include "glheader.h" +#include "mtypes.h" /* hack for GLchan */ + + +#define VEC_DIRTY_0 0x1 +#define VEC_DIRTY_1 0x2 +#define VEC_DIRTY_2 0x4 +#define VEC_DIRTY_3 0x8 +#define VEC_MALLOC 0x10 /* storage field points to self-allocated mem*/ +#define VEC_NOT_WRITEABLE 0x40 /* writable elements to hold clipped data */ +#define VEC_BAD_STRIDE 0x100 /* matches tnl's prefered stride */ + + +#define VEC_SIZE_1 VEC_DIRTY_0 +#define VEC_SIZE_2 (VEC_DIRTY_0|VEC_DIRTY_1) +#define VEC_SIZE_3 (VEC_DIRTY_0|VEC_DIRTY_1|VEC_DIRTY_2) +#define VEC_SIZE_4 (VEC_DIRTY_0|VEC_DIRTY_1|VEC_DIRTY_2|VEC_DIRTY_3) + + + +/* Wrap all the information about vectors up in a struct. Has + * additional fields compared to the other vectors to help us track of + * different vertex sizes, and whether we need to clean columns out + * because they contain non-(0,0,0,1) values. + * + * The start field is used to reserve data for copied vertices at the + * end of _mesa_transform_vb, and avoids the need for a multiplication in + * the transformation routines. + */ +typedef struct { + GLfloat (*data)[4]; /* may be malloc'd or point to client data */ + GLfloat *start; /* points somewhere inside of */ + GLuint count; /* size of the vector (in elements) */ + GLuint stride; /* stride from one element to the next (in bytes) */ + GLuint size; /* 2-4 for vertices and 1-4 for texcoords */ + GLuint flags; /* which columns are dirty */ + void *storage; /* self-allocated storage */ +} GLvector4f; + + +extern void _mesa_vector4f_init( GLvector4f *v, GLuint flags, + GLfloat (*storage)[4] ); +extern void _mesa_vector4f_alloc( GLvector4f *v, GLuint flags, + GLuint count, GLuint alignment ); +extern void _mesa_vector4f_free( GLvector4f *v ); +extern void _mesa_vector4f_print( GLvector4f *v, GLubyte *, GLboolean ); +extern void _mesa_vector4f_clean_elem( GLvector4f *vec, GLuint nr, GLuint elt ); + + +/* Could use a single vector type for normals and vertices, but + * this way avoids some casts. + */ +typedef struct { + GLfloat (*data)[3]; + GLfloat *start; + GLuint count; + GLuint stride; + GLuint flags; + void *storage; +} GLvector3f; + +extern void _mesa_vector3f_init( GLvector3f *v, GLuint flags, GLfloat (*)[3] ); +extern void _mesa_vector3f_alloc( GLvector3f *v, GLuint flags, GLuint count, + GLuint alignment ); +extern void _mesa_vector3f_free( GLvector3f *v ); +extern void _mesa_vector3f_print( GLvector3f *v, GLubyte *, GLboolean ); + + +typedef struct { + GLfloat *data; + GLfloat *start; + GLuint count; + GLuint stride; + GLuint flags; + void *storage; +} GLvector1f; + +extern void _mesa_vector1f_free( GLvector1f *v ); +extern void _mesa_vector1f_init( GLvector1f *v, GLuint flags, GLfloat * ); +extern void _mesa_vector1f_alloc( GLvector1f *v, GLuint flags, GLuint count, + GLuint alignment ); + + +/* For 4ub rgba values. + */ +typedef struct { + GLubyte (*data)[4]; + GLubyte *start; + GLuint count; + GLuint stride; + GLuint flags; + void *storage; +} GLvector4ub; + +extern void _mesa_vector4ub_init( GLvector4ub *v, GLuint flags, + GLubyte (*storage)[4] ); +extern void _mesa_vector4ub_alloc( GLvector4ub *v, GLuint flags, GLuint count, + GLuint alignment ); +extern void _mesa_vector4ub_free( GLvector4ub * ); + + +/* For 4 * GLchan values. + */ +typedef struct { + GLchan (*data)[4]; + GLchan *start; + GLuint count; + GLuint stride; + GLuint flags; + void *storage; +} GLvector4chan; + +extern void _mesa_vector4chan_init( GLvector4chan *v, GLuint flags, + GLchan (*storage)[4] ); +extern void _mesa_vector4chan_alloc( GLvector4chan *v, GLuint flags, GLuint count, + GLuint alignment ); +extern void _mesa_vector4chan_free( GLvector4chan * ); + + + + +/* For 4 * GLushort rgba values. + */ +typedef struct { + GLushort (*data)[4]; + GLushort *start; + GLuint count; + GLuint stride; + GLuint flags; + void *storage; +} GLvector4us; + +extern void _mesa_vector4us_init( GLvector4us *v, GLuint flags, + GLushort (*storage)[4] ); +extern void _mesa_vector4us_alloc( GLvector4us *v, GLuint flags, GLuint count, + GLuint alignment ); +extern void _mesa_vector4us_free( GLvector4us * ); + + + + +/* For 1ub values, eg edgeflag. + */ +typedef struct { + GLubyte *data; + GLubyte *start; + GLuint count; + GLuint stride; + GLuint flags; + void *storage; +} GLvector1ub; + +extern void _mesa_vector1ub_init( GLvector1ub *v, GLuint flags, GLubyte *storage); +extern void _mesa_vector1ub_alloc( GLvector1ub *v, GLuint flags, GLuint count, + GLuint alignment ); +extern void _mesa_vector1ub_free( GLvector1ub * ); + + + + +/* For, eg Index, Array element. + */ +typedef struct { + GLuint *data; + GLuint *start; + GLuint count; + GLuint stride; + GLuint flags; + void *storage; +} GLvector1ui; + +extern void _mesa_vector1ui_init( GLvector1ui *v, GLuint flags, GLuint *storage ); +extern void _mesa_vector1ui_alloc( GLvector1ui *v, GLuint flags, GLuint count, + GLuint alignment ); +extern void _mesa_vector1ui_free( GLvector1ui * ); + + + +/* + * Given vector , return a pointer (cast to to the -th element. + * + * End up doing a lot of slow imuls if not careful. + */ +#define VEC_ELT( v, type, i ) \ + ( (type *) ( ((GLbyte *) ((v)->data)) + (i) * (v)->stride) ) + + +#endif Index: dll/opengl/opengl32/mesa/math/m_vertices.c =================================================================== --- dll/opengl/opengl32/mesa/math/m_vertices.c (revision 0) +++ dll/opengl/opengl32/mesa/math/m_vertices.c (working copy) @@ -0,0 +1,215 @@ +/* $Id: m_vertices.c,v 1.5 2001/03/12 00:48:41 gareth Exp $ */ + +/* + * Mesa 3-D graphics library + * Version: 3.5 + * + * Copyright (C) 1999-2001 Brian Paul 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 + * BRIAN PAUL 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. + */ + + +#include "glheader.h" +#include "macros.h" + +#include "m_vertices.h" +#include "m_xform.h" + +#if defined(USE_X86_ASM) +#include "X86/common_x86_asm.h" +#endif + + +/* The start of a bunch of vertex oriented geometry routines. These + * are expected to support the production of driver-specific fast paths + * for CVA and eventually normal processing. + * + * These have been taken from fxfastpath.c, and are now also used in + * the mga driver. + * + * These should grow to include: + * - choice of 8/16 dword vertices + * - ?? + * - use of portable assembly layouts. + * + * More tentatively: + * - more (all?) matrix types + * - more (?) vertex sizes + * + * -- Keith Whitwell. + */ + +/* The inline 3dnow code seems to give problems with some peoples + * compiler/binutils. + */ +/* #undef USE_3DNOW_ASM */ + + +#if defined(USE_X86_ASM) && defined(__GNUC__) + + +#endif + + +/* + * Transform an array of coordinates by an arbitrary 4x4 matrix. + * Output: f - the results vector [][16] + * Input: m - the 4x4 matrix + * obj - pointer to first 4-component coordinate + * obj_stride - stride in bytes between input coordinates + * count - number of coordinates to transform + */ +static void _PROJAPI transform_v16( GLfloat *f, + const GLfloat *m, + const GLfloat *obj, + GLuint obj_stride, + GLuint count ) +{ + GLuint i; + + for (i = 0; i < count; i++, STRIDE_F(obj, obj_stride), f += 16) { + const GLfloat ox = obj[0], oy = obj[1], oz = obj[2]; + f[0] = m[0] * ox + m[4] * oy + m[8] * oz + m[12]; + f[1] = m[1] * ox + m[5] * oy + m[9] * oz + m[13]; + f[2] = m[2] * ox + m[6] * oy + m[10] * oz + m[14]; + f[3] = m[3] * ox + m[7] * oy + m[11] * oz + m[15]; + } +} + + +/* + * Compute the view frustum clipmask for an array of vertices. + * Input: first - pointer to first vertex to process + * (the stride must be 16 floats between coordinates) + * last - pointer to vertex just after the last vertex to process + * Input/output: p_clipOr - the bitwise-OR of all vertex clipmasks + * p_clipAnd - the bitwise-AND of all vertex clipmasks + * Output: clipmask - the clipmask for each vertex + */ +static void _PROJAPI cliptest_v16( GLfloat *firstVertex, + GLfloat *lastVertex, + GLubyte *p_clipOr, + GLubyte *p_clipAnd, + GLubyte *clipmask ) +{ + GLubyte clipAnd = (GLubyte) ~0; + GLubyte clipOr = 0; + GLfloat *v = firstVertex; + static int i; + i = 0; + + for ( ; v != lastVertex; v += 16, clipmask++, i++) { + const GLfloat cx = v[0]; + const GLfloat cy = v[1]; + const GLfloat cz = v[2]; + const GLfloat cw = v[3]; + GLubyte mask = 0; + + if (cx > cw) mask |= CLIP_RIGHT_BIT; + if (cx < -cw) mask |= CLIP_LEFT_BIT; + if (cy > cw) mask |= CLIP_TOP_BIT; + if (cy < -cw) mask |= CLIP_BOTTOM_BIT; + if (cz > cw) mask |= CLIP_FAR_BIT; + if (cz < -cw) mask |= CLIP_NEAR_BIT; + + *clipmask = mask; + clipAnd &= mask; + clipOr |= mask; + } + + (*p_clipOr) |= clipOr; + (*p_clipAnd) &= clipAnd; +} + + +/* + * Project all vertices upto but not including last. Guarenteed to be at + * least one such vertex. + * Input: firstVertex - pointer to first vertex + * lastVertex - pointer to vertex just afte the last to transform + * m - 4x4 matrix, we only look at the scale and translate terms + * stride - stride in bytes between coordinates + */ +static void _PROJAPI project_verts( GLfloat *firstVertex, + GLfloat *lastVertex, + const GLfloat *m, + GLuint stride ) +{ + const GLfloat sx = m[0], sy = m[5], sz = m[10]; + const GLfloat tx = m[12], ty = m[13], tz = m[14]; + GLfloat *v; + + for (v = firstVertex; v != lastVertex; STRIDE_F(v, stride)) { + const GLfloat oow = 1.0F / v[3]; + v[0] = sx * v[0] * oow + tx; + v[1] = sy * v[1] * oow + ty; + v[2] = sz * v[2] * oow + tz; + v[3] = oow; + } +} + +/* + * Same as the above function, except only process coordinate [i] if + * clipmask[i] is zero. + */ +static void _PROJAPI project_clipped_verts( GLfloat *firstVertex, + GLfloat *lastVertex, + const GLfloat *m, + GLuint stride, + const GLubyte clipmask[] ) +{ + const GLfloat sx = m[0], sy = m[5], sz = m[10]; + const GLfloat tx = m[12], ty = m[13], tz = m[14]; + GLfloat *v; + + for (v = firstVertex; v != lastVertex; STRIDE_F(v, stride), clipmask++) { + if (!(*clipmask)) { + const GLfloat oow = 1.0F / v[3]; + v[0] = sx * v[0] * oow + tx; + v[1] = sy * v[1] * oow + ty; + v[2] = sz * v[2] * oow + tz; + v[3] = oow; + } + } +} + + +_mesa_transform_func _mesa_xform_points3_v16_general = 0; +_mesa_cliptest_func _mesa_cliptest_points4_v16 = 0; +_mesa_project_func _mesa_project_v16 = 0; +_mesa_project_clipped_func _mesa_project_clipped_v16 = 0; + + +void +_math_init_vertices( void ) +{ + _mesa_xform_points3_v16_general = transform_v16; + _mesa_cliptest_points4_v16 = cliptest_v16; + _mesa_project_v16 = project_verts; + _mesa_project_clipped_v16 = project_clipped_verts; + +#if 0 + /* GH: Add tests/benchmarks for the vertex asm */ + gl_test_all_vertex_functions( "default" ); +#endif + +#ifdef USE_X86_ASM + _mesa_init_all_x86_vertex_asm(); +#endif +} Index: dll/opengl/opengl32/mesa/math/m_vertices.h =================================================================== --- dll/opengl/opengl32/mesa/math/m_vertices.h (revision 0) +++ dll/opengl/opengl32/mesa/math/m_vertices.h (working copy) @@ -0,0 +1,85 @@ +/* $Id: m_vertices.h,v 1.4 2001/03/12 00:48:41 gareth Exp $ */ + +/* + * Mesa 3-D graphics library + * Version: 3.5 + * + * Copyright (C) 1999-2001 Brian Paul 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 + * BRIAN PAUL 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. + */ + + +#ifndef _M_VERTICES_H_ +#define _M_VERTICES_H_ + +#ifdef USE_X86_ASM +#define _PROJAPI _ASMAPI +#define _PROJAPIP _ASMAPIP +#else +#define _PROJAPI +#define _PROJAPIP * +#endif + + +/* + * Some handy functions for "fastpath" vertex processing in DRI drivers. + */ + + +typedef void (_PROJAPIP _mesa_transform_func)( GLfloat *first_vert, + const GLfloat *m, + const GLfloat *src, + GLuint src_stride, + GLuint count ); + +/* use count instead of last vert? */ +typedef void (_PROJAPIP _mesa_cliptest_func)( GLfloat *first_vert, + GLfloat *last_vert, + GLubyte *or_mask, + GLubyte *and_mask, + GLubyte *clip_mask ); + +typedef void (_PROJAPIP _mesa_project_func)( GLfloat *first, + GLfloat *last, + const GLfloat *m, + GLuint stride ); + +typedef void (_PROJAPIP _mesa_project_clipped_func)( GLfloat *first, + GLfloat *last, + const GLfloat *m, + GLuint stride, + const GLubyte *clipmask ); + +typedef void (_PROJAPIP gl_vertex_interp_func)( GLfloat t, + GLfloat *result, + const GLfloat *in, + const GLfloat *out ); + + +extern _mesa_transform_func _mesa_xform_points3_v16_general; +extern _mesa_cliptest_func _mesa_cliptest_points4_v16; +extern _mesa_project_func _mesa_project_v16; +extern _mesa_project_clipped_func _mesa_project_clipped_v16; + + +extern void +_math_init_vertices( void ); + + +#endif Index: dll/opengl/opengl32/mesa/math/m_xform.c =================================================================== --- dll/opengl/opengl32/mesa/math/m_xform.c (revision 0) +++ dll/opengl/opengl32/mesa/math/m_xform.c (working copy) @@ -0,0 +1,225 @@ +/* $Id: m_xform.c,v 1.14 2001/05/23 14:27:03 brianp Exp $ */ + +/* + * Mesa 3-D graphics library + * Version: 3.5 + * + * Copyright (C) 1999-2001 Brian Paul 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 + * BRIAN PAUL 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. + */ + + +/* + * Matrix/vertex/vector transformation stuff + * + * + * NOTES: + * 1. 4x4 transformation matrices are stored in memory in column major order. + * 2. Points/vertices are to be thought of as column vectors. + * 3. Transformation of a point p by a matrix M is: p' = M * p + */ + +#include + +#include "glheader.h" +#include "macros.h" +#include "mmath.h" + +#include "m_eval.h" +#include "m_matrix.h" +#include "m_translate.h" +#include "m_xform.h" +#include "mathmod.h" + + +#ifdef DEBUG +#include "m_debug.h" +#endif + +#ifdef USE_X86_ASM +#include "X86/common_x86_asm.h" +#endif + +#ifdef USE_SPARC_ASM +#include "SPARC/sparc.h" +#endif + +clip_func _mesa_clip_tab[5]; +clip_func _mesa_clip_np_tab[5]; +dotprod_func _mesa_dotprod_tab[5]; +vec_copy_func _mesa_copy_tab[0x10]; +normal_func _mesa_normal_tab[0xf]; +transform_func *_mesa_transform_tab[5]; + + +/* Raw data format used for: + * - Object-to-eye transform prior to culling, although this too + * could be culled under some circumstances. + * - Eye-to-clip transform (via the function above). + * - Cliptesting + * - And everything else too, if culling happens to be disabled. + * + * GH: It's used for everything now, as clipping/culling is done + * elsewhere (most often by the driver itself). + */ +#define TAG(x) x +#define TAG2(x,y) x##y +#define STRIDE_LOOP for ( i = 0 ; i < count ; i++, STRIDE_F(from, stride) ) +#define LOOP for ( i = 0 ; i < n ; i++ ) +#define ARGS +#include "m_xform_tmp.h" +#include "m_clip_tmp.h" +#include "m_norm_tmp.h" +#include "m_dotprod_tmp.h" +#include "m_copy_tmp.h" +#undef TAG +#undef TAG2 +#undef LOOP +#undef ARGS + + + + +GLvector4f *_mesa_project_points( GLvector4f *proj_vec, + const GLvector4f *clip_vec ) +{ + const GLuint stride = clip_vec->stride; + const GLfloat *from = (GLfloat *)clip_vec->start; + const GLuint count = clip_vec->count; + GLfloat (*vProj)[4] = (GLfloat (*)[4])proj_vec->start; + GLuint i; + + for (i = 0 ; i < count ; i++, STRIDE_F(from, stride)) + { + GLfloat oow = 1.0F / from[3]; + vProj[i][3] = oow; + vProj[i][0] = from[0] * oow; + vProj[i][1] = from[1] * oow; + vProj[i][2] = from[2] * oow; + } + + proj_vec->flags |= VEC_SIZE_4; + proj_vec->size = 3; + proj_vec->count = clip_vec->count; + return proj_vec; +} + + + + + + +/* + * Transform a 4-element row vector (1x4 matrix) by a 4x4 matrix. This + * function is used for transforming clipping plane equations and spotlight + * directions. + * Mathematically, u = v * m. + * Input: v - input vector + * m - transformation matrix + * Output: u - transformed vector + */ +void _mesa_transform_vector( GLfloat u[4], const GLfloat v[4], const GLfloat m[16] ) +{ + GLfloat v0=v[0], v1=v[1], v2=v[2], v3=v[3]; +#define M(row,col) m[row + col*4] + u[0] = v0 * M(0,0) + v1 * M(1,0) + v2 * M(2,0) + v3 * M(3,0); + u[1] = v0 * M(0,1) + v1 * M(1,1) + v2 * M(2,1) + v3 * M(3,1); + u[2] = v0 * M(0,2) + v1 * M(1,2) + v2 * M(2,2) + v3 * M(3,2); + u[3] = v0 * M(0,3) + v1 * M(1,3) + v2 * M(2,3) + v3 * M(3,3); +#undef M +} + + +/* Useful for one-off point transformations, as in clipping. + * Note that because the matrix isn't analysed we do too many + * multiplies, and that the result is always 4-clean. + */ +void _mesa_transform_point_sz( GLfloat Q[4], const GLfloat M[16], + const GLfloat P[4], GLuint sz ) +{ + if (Q == P) + return; + + if (sz == 4) + { + Q[0] = M[0] * P[0] + M[4] * P[1] + M[8] * P[2] + M[12] * P[3]; + Q[1] = M[1] * P[0] + M[5] * P[1] + M[9] * P[2] + M[13] * P[3]; + Q[2] = M[2] * P[0] + M[6] * P[1] + M[10] * P[2] + M[14] * P[3]; + Q[3] = M[3] * P[0] + M[7] * P[1] + M[11] * P[2] + M[15] * P[3]; + } + else if (sz == 3) + { + Q[0] = M[0] * P[0] + M[4] * P[1] + M[8] * P[2] + M[12]; + Q[1] = M[1] * P[0] + M[5] * P[1] + M[9] * P[2] + M[13]; + Q[2] = M[2] * P[0] + M[6] * P[1] + M[10] * P[2] + M[14]; + Q[3] = M[3] * P[0] + M[7] * P[1] + M[11] * P[2] + M[15]; + } + else if (sz == 2) + { + Q[0] = M[0] * P[0] + M[4] * P[1] + M[12]; + Q[1] = M[1] * P[0] + M[5] * P[1] + M[13]; + Q[2] = M[2] * P[0] + M[6] * P[1] + M[14]; + Q[3] = M[3] * P[0] + M[7] * P[1] + M[15]; + } + else if (sz == 1) + { + Q[0] = M[0] * P[0] + M[12]; + Q[1] = M[1] * P[0] + M[13]; + Q[2] = M[2] * P[0] + M[14]; + Q[3] = M[3] * P[0] + M[15]; + } +} + + +/* + * This is called only once. It initializes several tables with pointers + * to optimized transformation functions. This is where we can test for + * AMD 3Dnow! capability, Intel Katmai, etc. and hook in the right code. + */ +void +_math_init_transformation( void ) +{ + init_c_transformations(); + init_c_norm_transform(); + init_c_cliptest(); + init_copy0(); + init_dotprod(); + +#ifdef DEBUG + _math_test_all_transform_functions( "default" ); + _math_test_all_normal_transform_functions( "default" ); + _math_test_all_cliptest_functions( "default" ); +#endif + +#ifdef USE_X86_ASM + _mesa_init_all_x86_transform_asm(); +#endif +#ifdef USE_SPARC_ASM + _mesa_init_all_sparc_transform_asm(); +#endif +} + +void +_math_init( void ) +{ + _math_init_transformation(); + _math_init_translate(); + _math_init_vertices(); + _math_init_eval(); +} Index: dll/opengl/opengl32/mesa/math/m_xform.h =================================================================== --- dll/opengl/opengl32/mesa/math/m_xform.h (revision 0) +++ dll/opengl/opengl32/mesa/math/m_xform.h (working copy) @@ -0,0 +1,217 @@ +/* $Id: m_xform.h,v 1.10 2001/03/30 14:44:43 gareth Exp $ */ + +/* + * Mesa 3-D graphics library + * Version: 3.5 + * + * Copyright (C) 1999-2001 Brian Paul 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 + * BRIAN PAUL 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. + */ + + + + + +#ifndef _M_XFORM_H +#define _M_XFORM_H + + +#include "glheader.h" +#include "config.h" +#include "math/m_vector.h" +#include "math/m_matrix.h" + +#ifdef USE_X86_ASM +#define _XFORMAPI _ASMAPI +#define _XFORMAPIP _ASMAPIP +#else +#define _XFORMAPI +#define _XFORMAPIP * +#endif + +/* + * Transform a point (column vector) by a matrix: Q = M * P + */ +#define TRANSFORM_POINT( Q, M, P ) \ + Q[0] = M[0] * P[0] + M[4] * P[1] + M[8] * P[2] + M[12] * P[3]; \ + Q[1] = M[1] * P[0] + M[5] * P[1] + M[9] * P[2] + M[13] * P[3]; \ + Q[2] = M[2] * P[0] + M[6] * P[1] + M[10] * P[2] + M[14] * P[3]; \ + Q[3] = M[3] * P[0] + M[7] * P[1] + M[11] * P[2] + M[15] * P[3]; + + +#define TRANSFORM_POINT3( Q, M, P ) \ + Q[0] = M[0] * P[0] + M[4] * P[1] + M[8] * P[2] + M[12]; \ + Q[1] = M[1] * P[0] + M[5] * P[1] + M[9] * P[2] + M[13]; \ + Q[2] = M[2] * P[0] + M[6] * P[1] + M[10] * P[2] + M[14]; \ + Q[3] = M[3] * P[0] + M[7] * P[1] + M[11] * P[2] + M[15]; + + +/* + * Transform a normal (row vector) by a matrix: [NX NY NZ] = N * MAT + */ +#define TRANSFORM_NORMAL( TO, N, MAT ) \ +do { \ + TO[0] = N[0] * MAT[0] + N[1] * MAT[1] + N[2] * MAT[2]; \ + TO[1] = N[0] * MAT[4] + N[1] * MAT[5] + N[2] * MAT[6]; \ + TO[2] = N[0] * MAT[8] + N[1] * MAT[9] + N[2] * MAT[10]; \ +} while (0) + + +extern void _mesa_transform_vector( GLfloat u[4], + CONST GLfloat v[4], + CONST GLfloat m[16] ); + + +extern void +_math_init_transformation( void ); + + +/* KW: Clip functions now do projective divide as well. The projected + * coordinates are very useful to us because they let us cull + * backfaces and eliminate vertices from lighting, fogging, etc + * calculations. Despite the fact that this divide could be done one + * day in hardware, we would still have a reason to want to do it here + * as long as those other calculations remain in software. + * + * Clipping is a convenient place to do the divide on x86 as it should be + * possible to overlap with integer outcode calculations. + * + * There are two cases where we wouldn't want to do the divide in cliptest: + * - When we aren't clipping. We still might want to cull backfaces + * so the divide should be done elsewhere. This currently never + * happens. + * + * - When culling isn't likely to help us, such as when the GL culling + * is disabled and we not lighting or are only lighting + * one-sided. In this situation, backface determination provides + * us with no useful information. A tricky case to detect is when + * all input data is already culled, although hopefully the + * application wouldn't turn on culling in such cases. + * + * We supply a buffer to hold the [x/w,y/w,z/w,1/w] values which + * are the result of the projection. This is only used in the + * 4-vector case - in other cases, we just use the clip coordinates + * as the projected coordinates - they are identical. + * + * This is doubly convenient because it means the Win[] array is now + * of the same stride as all the others, so I can now turn map_vertices + * into a straight-forward matrix transformation, with asm acceleration + * automatically available. + */ + +/* Vertex buffer clipping flags + */ +#define CLIP_RIGHT_SHIFT 0 +#define CLIP_LEFT_SHIFT 1 +#define CLIP_TOP_SHIFT 2 +#define CLIP_BOTTOM_SHIFT 3 +#define CLIP_NEAR_SHIFT 4 +#define CLIP_FAR_SHIFT 5 + +#define CLIP_RIGHT_BIT 0x01 +#define CLIP_LEFT_BIT 0x02 +#define CLIP_TOP_BIT 0x04 +#define CLIP_BOTTOM_BIT 0x08 +#define CLIP_NEAR_BIT 0x10 +#define CLIP_FAR_BIT 0x20 +#define CLIP_USER_BIT 0x40 +#define CLIP_ALL_BITS 0x3f + + +typedef GLvector4f * (_XFORMAPIP clip_func)( GLvector4f *vClip, + GLvector4f *vProj, + GLubyte clipMask[], + GLubyte *orMask, + GLubyte *andMask ); + +typedef void (*dotprod_func)( GLfloat *out, + GLuint out_stride, + CONST GLvector4f *coord_vec, + CONST GLfloat plane[4] ); + +typedef void (*vec_copy_func)( GLvector4f *to, + CONST GLvector4f *from ); + + + +/* + * Functions for transformation of normals in the VB. + */ +typedef void (_NORMAPIP normal_func)( CONST GLmatrix *mat, + GLfloat scale, + CONST GLvector3f *in, + CONST GLfloat lengths[], + GLvector3f *dest ); + + +/* Flags for selecting a normal transformation function. + */ +#define NORM_RESCALE 0x1 /* apply the scale factor */ +#define NORM_NORMALIZE 0x2 /* normalize */ +#define NORM_TRANSFORM 0x4 /* apply the transformation matrix */ +#define NORM_TRANSFORM_NO_ROT 0x8 /* apply the transformation matrix */ + + + + +/* KW: New versions of the transform function allow a mask array + * specifying that individual vector transform should be skipped + * when the mask byte is zero. This is always present as a + * parameter, to allow a unified interface. + */ +typedef void (_XFORMAPIP transform_func)( GLvector4f *to_vec, + CONST GLfloat m[16], + CONST GLvector4f *from_vec ); + + +extern GLvector4f *_mesa_project_points( GLvector4f *to, + CONST GLvector4f *from ); + +extern void _mesa_transform_bounds3( GLubyte *orMask, GLubyte *andMask, + CONST GLfloat m[16], + CONST GLfloat src[][3] ); + +extern void _mesa_transform_bounds2( GLubyte *orMask, GLubyte *andMask, + CONST GLfloat m[16], + CONST GLfloat src[][3] ); + + +extern dotprod_func _mesa_dotprod_tab[5]; +extern vec_copy_func _mesa_copy_tab[0x10]; +extern vec_copy_func _mesa_copy_clean_tab[5]; +extern clip_func _mesa_clip_tab[5]; +extern clip_func _mesa_clip_np_tab[5]; +extern normal_func _mesa_normal_tab[0xf]; + +/* Use of 2 layers of linked 1-dimensional arrays to reduce + * cost of lookup. + */ +extern transform_func *_mesa_transform_tab[5]; + + +extern void _mesa_transform_point_sz( GLfloat Q[4], CONST GLfloat M[16], + CONST GLfloat P[4], GLuint sz ); + + +#define TransformRaw( to, mat, from ) \ + ( _mesa_transform_tab[(from)->size][(mat)->type]( to, (mat)->m, from ), \ + (to) ) + + +#endif Index: dll/opengl/opengl32/mesa/math/m_xform_tmp.h =================================================================== --- dll/opengl/opengl32/mesa/math/m_xform_tmp.h (revision 0) +++ dll/opengl/opengl32/mesa/math/m_xform_tmp.h (working copy) @@ -0,0 +1,807 @@ +/* $Id: m_xform_tmp.h,v 1.7 2001/05/18 23:58:26 brianp Exp $ */ + +/* + * Mesa 3-D graphics library + * Version: 3.5 + * + * Copyright (C) 1999-2001 Brian Paul 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 + * BRIAN PAUL 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. + */ + +/* + * New (3.1) transformation code written by Keith Whitwell. + */ + + +/*---------------------------------------------------------------------- + * Begin Keith's new code + * + *---------------------------------------------------------------------- + */ + +/* KW: Fixed stride, now measured in bytes as is the OpenGL array stride. + */ + +/* KW: These are now parameterized to produce two versions, one + * which transforms all incoming points, and a second which + * takes notice of a cullmask array, and only transforms + * unculled vertices. + */ + +/* KW: 1-vectors can sneak into the texture pipeline via the array + * interface. These functions are here because I want consistant + * treatment of the vertex sizes and a lazy strategy for + * cleaning unused parts of the vector, and so as not to exclude + * them from the vertex array interface. + * + * Under our current analysis of matrices, there is no way that + * the product of a matrix and a 1-vector can remain a 1-vector, + * with the exception of the identity transform. + */ + +/* KW: No longer zero-pad outgoing vectors. Now that external + * vectors can get into the pipeline we cannot ever assume + * that there is more to a vector than indicated by its + * size. + */ + +/* KW: Now uses clipmask and a flag to allow us to skip both/either + * cliped and/or culled vertices. + */ + +/* GH: Not any more -- it's easier (and faster) to just process the + * entire vector. Clipping and culling are handled further down + * the pipe, most often during or after the conversion to some + * driver-specific vertex format. + */ + +static void _XFORMAPI +TAG(transform_points1_general)( GLvector4f *to_vec, + const GLfloat m[16], + const GLvector4f *from_vec ) +{ + const GLuint stride = from_vec->stride; + GLfloat *from = from_vec->start; + GLfloat (*to)[4] = (GLfloat (*)[4])to_vec->start; + GLuint count = from_vec->count; + const GLfloat m0 = m[0], m12 = m[12]; + const GLfloat m1 = m[1], m13 = m[13]; + const GLfloat m2 = m[2], m14 = m[14]; + const GLfloat m3 = m[3], m15 = m[15]; + GLuint i; + STRIDE_LOOP { + const GLfloat ox = from[0]; + to[i][0] = m0 * ox + m12; + to[i][1] = m1 * ox + m13; + to[i][2] = m2 * ox + m14; + to[i][3] = m3 * ox + m15; + } + to_vec->size = 4; + to_vec->flags |= VEC_SIZE_4; + to_vec->count = from_vec->count; +} + +static void _XFORMAPI +TAG(transform_points1_identity)( GLvector4f *to_vec, + const GLfloat m[16], + const GLvector4f *from_vec ) +{ + const GLuint stride = from_vec->stride; + GLfloat *from = from_vec->start; + GLuint count = from_vec->count; + GLfloat (*to)[4] = (GLfloat (*)[4])to_vec->start; + GLuint i; + if (to_vec == from_vec) return; + STRIDE_LOOP { + to[i][0] = from[0]; + } + to_vec->size = 1; + to_vec->flags |= VEC_SIZE_1; + to_vec->count = from_vec->count; +} + +static void _XFORMAPI +TAG(transform_points1_2d)( GLvector4f *to_vec, + const GLfloat m[16], + const GLvector4f *from_vec ) +{ + const GLuint stride = from_vec->stride; + GLfloat *from = from_vec->start; + GLfloat (*to)[4] = (GLfloat (*)[4])to_vec->start; + GLuint count = from_vec->count; + const GLfloat m0 = m[0], m1 = m[1]; + const GLfloat m12 = m[12], m13 = m[13]; + GLuint i; + STRIDE_LOOP { + const GLfloat ox = from[0]; + to[i][0] = m0 * ox + m12; + to[i][1] = m1 * ox + m13; + } + to_vec->size = 2; + to_vec->flags |= VEC_SIZE_2; + to_vec->count = from_vec->count; +} + +static void _XFORMAPI +TAG(transform_points1_2d_no_rot)( GLvector4f *to_vec, + const GLfloat m[16], + const GLvector4f *from_vec ) +{ + const GLuint stride = from_vec->stride; + GLfloat *from = from_vec->start; + GLfloat (*to)[4] = (GLfloat (*)[4])to_vec->start; + GLuint count = from_vec->count; + const GLfloat m0 = m[0], m12 = m[12], m13 = m[13]; + GLuint i; + STRIDE_LOOP { + const GLfloat ox = from[0]; + to[i][0] = m0 * ox + m12; + to[i][1] = m13; + } + to_vec->size = 2; + to_vec->flags |= VEC_SIZE_2; + to_vec->count = from_vec->count; +} + +static void _XFORMAPI +TAG(transform_points1_3d)( GLvector4f *to_vec, + const GLfloat m[16], + const GLvector4f *from_vec ) +{ + const GLuint stride = from_vec->stride; + GLfloat *from = from_vec->start; + GLfloat (*to)[4] = (GLfloat (*)[4])to_vec->start; + GLuint count = from_vec->count; + const GLfloat m0 = m[0], m1 = m[1], m2 = m[2]; + const GLfloat m12 = m[12], m13 = m[13], m14 = m[14]; + GLuint i; + STRIDE_LOOP { + const GLfloat ox = from[0]; + to[i][0] = m0 * ox + m12; + to[i][1] = m1 * ox + m13; + to[i][2] = m2 * ox + m14; + } + to_vec->size = 3; + to_vec->flags |= VEC_SIZE_3; + to_vec->count = from_vec->count; +} + + +static void _XFORMAPI +TAG(transform_points1_3d_no_rot)( GLvector4f *to_vec, + const GLfloat m[16], + const GLvector4f *from_vec ) +{ + const GLuint stride = from_vec->stride; + GLfloat *from = from_vec->start; + GLfloat (*to)[4] = (GLfloat (*)[4])to_vec->start; + GLuint count = from_vec->count; + const GLfloat m0 = m[0]; + const GLfloat m12 = m[12], m13 = m[13], m14 = m[14]; + GLuint i; + STRIDE_LOOP { + const GLfloat ox = from[0]; + to[i][0] = m0 * ox + m12; + to[i][1] = m13; + to[i][2] = m14; + } + to_vec->size = 3; + to_vec->flags |= VEC_SIZE_3; + to_vec->count = from_vec->count; +} + +static void _XFORMAPI +TAG(transform_points1_perspective)( GLvector4f *to_vec, + const GLfloat m[16], + const GLvector4f *from_vec ) +{ + const GLuint stride = from_vec->stride; + GLfloat *from = from_vec->start; + GLfloat (*to)[4] = (GLfloat (*)[4])to_vec->start; + GLuint count = from_vec->count; + const GLfloat m0 = m[0], m14 = m[14]; + GLuint i; + STRIDE_LOOP { + const GLfloat ox = from[0]; + to[i][0] = m0 * ox ; + to[i][1] = 0 ; + to[i][2] = m14; + to[i][3] = 0; + } + to_vec->size = 4; + to_vec->flags |= VEC_SIZE_4; + to_vec->count = from_vec->count; +} + + + + +/* 2-vectors, which are a lot more relevant than 1-vectors, are + * present early in the geometry pipeline and throughout the + * texture pipeline. + */ +static void _XFORMAPI +TAG(transform_points2_general)( GLvector4f *to_vec, + const GLfloat m[16], + const GLvector4f *from_vec ) +{ + const GLuint stride = from_vec->stride; + GLfloat *from = from_vec->start; + GLfloat (*to)[4] = (GLfloat (*)[4])to_vec->start; + GLuint count = from_vec->count; + const GLfloat m0 = m[0], m4 = m[4], m12 = m[12]; + const GLfloat m1 = m[1], m5 = m[5], m13 = m[13]; + const GLfloat m2 = m[2], m6 = m[6], m14 = m[14]; + const GLfloat m3 = m[3], m7 = m[7], m15 = m[15]; + GLuint i; + STRIDE_LOOP { + const GLfloat ox = from[0], oy = from[1]; + to[i][0] = m0 * ox + m4 * oy + m12; + to[i][1] = m1 * ox + m5 * oy + m13; + to[i][2] = m2 * ox + m6 * oy + m14; + to[i][3] = m3 * ox + m7 * oy + m15; + } + to_vec->size = 4; + to_vec->flags |= VEC_SIZE_4; + to_vec->count = from_vec->count; +} + +static void _XFORMAPI +TAG(transform_points2_identity)( GLvector4f *to_vec, + const GLfloat m[16], + const GLvector4f *from_vec ) +{ + const GLuint stride = from_vec->stride; + GLfloat *from = from_vec->start; + GLfloat (*to)[4] = (GLfloat (*)[4])to_vec->start; + GLuint count = from_vec->count; + GLuint i; + if (to_vec == from_vec) return; + STRIDE_LOOP { + to[i][0] = from[0]; + to[i][1] = from[1]; + } + to_vec->size = 2; + to_vec->flags |= VEC_SIZE_2; + to_vec->count = from_vec->count; +} + +static void _XFORMAPI +TAG(transform_points2_2d)( GLvector4f *to_vec, + const GLfloat m[16], + const GLvector4f *from_vec ) +{ + const GLuint stride = from_vec->stride; + GLfloat *from = from_vec->start; + GLfloat (*to)[4] = (GLfloat (*)[4])to_vec->start; + GLuint count = from_vec->count; + const GLfloat m0 = m[0], m1 = m[1], m4 = m[4], m5 = m[5]; + const GLfloat m12 = m[12], m13 = m[13]; + GLuint i; + STRIDE_LOOP { + const GLfloat ox = from[0], oy = from[1]; + to[i][0] = m0 * ox + m4 * oy + m12; + to[i][1] = m1 * ox + m5 * oy + m13; + } + to_vec->size = 2; + to_vec->flags |= VEC_SIZE_2; + to_vec->count = from_vec->count; +} + +static void _XFORMAPI +TAG(transform_points2_2d_no_rot)( GLvector4f *to_vec, + const GLfloat m[16], + const GLvector4f *from_vec ) +{ + const GLuint stride = from_vec->stride; + GLfloat *from = from_vec->start; + GLfloat (*to)[4] = (GLfloat (*)[4])to_vec->start; + GLuint count = from_vec->count; + const GLfloat m0 = m[0], m5 = m[5], m12 = m[12], m13 = m[13]; + GLuint i; + STRIDE_LOOP { + const GLfloat ox = from[0], oy = from[1]; + to[i][0] = m0 * ox + m12; + to[i][1] = m5 * oy + m13; + } + to_vec->size = 2; + to_vec->flags |= VEC_SIZE_2; + to_vec->count = from_vec->count; +} + +static void _XFORMAPI +TAG(transform_points2_3d)( GLvector4f *to_vec, + const GLfloat m[16], + const GLvector4f *from_vec ) +{ + const GLuint stride = from_vec->stride; + GLfloat *from = from_vec->start; + GLfloat (*to)[4] = (GLfloat (*)[4])to_vec->start; + GLuint count = from_vec->count; + const GLfloat m0 = m[0], m1 = m[1], m2 = m[2], m4 = m[4], m5 = m[5]; + const GLfloat m6 = m[6], m12 = m[12], m13 = m[13], m14 = m[14]; + GLuint i; + STRIDE_LOOP { + const GLfloat ox = from[0], oy = from[1]; + to[i][0] = m0 * ox + m4 * oy + m12; + to[i][1] = m1 * ox + m5 * oy + m13; + to[i][2] = m2 * ox + m6 * oy + m14; + } + to_vec->size = 3; + to_vec->flags |= VEC_SIZE_3; + to_vec->count = from_vec->count; +} + + +/* I would actually say this was a fairly important function, from + * a texture transformation point of view. + */ +static void _XFORMAPI +TAG(transform_points2_3d_no_rot)( GLvector4f *to_vec, + const GLfloat m[16], + const GLvector4f *from_vec ) +{ + const GLuint stride = from_vec->stride; + GLfloat *from = from_vec->start; + GLfloat (*to)[4] = (GLfloat (*)[4])to_vec->start; + GLuint count = from_vec->count; + const GLfloat m0 = m[0], m5 = m[5]; + const GLfloat m12 = m[12], m13 = m[13], m14 = m[14]; + GLuint i; + STRIDE_LOOP { + const GLfloat ox = from[0], oy = from[1]; + to[i][0] = m0 * ox + m12; + to[i][1] = m5 * oy + m13; + to[i][2] = m14; + } + if (m14 == 0) { + to_vec->size = 2; + to_vec->flags |= VEC_SIZE_2; + } else { + to_vec->size = 3; + to_vec->flags |= VEC_SIZE_3; + } + to_vec->count = from_vec->count; +} + + +static void _XFORMAPI +TAG(transform_points2_perspective)( GLvector4f *to_vec, + const GLfloat m[16], + const GLvector4f *from_vec ) +{ + const GLuint stride = from_vec->stride; + GLfloat *from = from_vec->start; + GLfloat (*to)[4] = (GLfloat (*)[4])to_vec->start; + GLuint count = from_vec->count; + const GLfloat m0 = m[0], m5 = m[5], m14 = m[14]; + GLuint i; + STRIDE_LOOP { + const GLfloat ox = from[0], oy = from[1]; + to[i][0] = m0 * ox ; + to[i][1] = m5 * oy ; + to[i][2] = m14; + to[i][3] = 0; + } + to_vec->size = 4; + to_vec->flags |= VEC_SIZE_4; + to_vec->count = from_vec->count; +} + + + +static void _XFORMAPI +TAG(transform_points3_general)( GLvector4f *to_vec, + const GLfloat m[16], + const GLvector4f *from_vec ) +{ + const GLuint stride = from_vec->stride; + GLfloat *from = from_vec->start; + GLfloat (*to)[4] = (GLfloat (*)[4])to_vec->start; + GLuint count = from_vec->count; + const GLfloat m0 = m[0], m4 = m[4], m8 = m[8], m12 = m[12]; + const GLfloat m1 = m[1], m5 = m[5], m9 = m[9], m13 = m[13]; + const GLfloat m2 = m[2], m6 = m[6], m10 = m[10], m14 = m[14]; + const GLfloat m3 = m[3], m7 = m[7], m11 = m[11], m15 = m[15]; + GLuint i; + STRIDE_LOOP { + const GLfloat ox = from[0], oy = from[1], oz = from[2]; + to[i][0] = m0 * ox + m4 * oy + m8 * oz + m12; + to[i][1] = m1 * ox + m5 * oy + m9 * oz + m13; + to[i][2] = m2 * ox + m6 * oy + m10 * oz + m14; + to[i][3] = m3 * ox + m7 * oy + m11 * oz + m15; + } + to_vec->size = 4; + to_vec->flags |= VEC_SIZE_4; + to_vec->count = from_vec->count; +} + +static void _XFORMAPI +TAG(transform_points3_identity)( GLvector4f *to_vec, + const GLfloat m[16], + const GLvector4f *from_vec ) +{ + const GLuint stride = from_vec->stride; + GLfloat *from = from_vec->start; + GLfloat (*to)[4] = (GLfloat (*)[4])to_vec->start; + GLuint count = from_vec->count; + GLuint i; + if (to_vec == from_vec) return; + STRIDE_LOOP { + to[i][0] = from[0]; + to[i][1] = from[1]; + to[i][2] = from[2]; + } + to_vec->size = 3; + to_vec->flags |= VEC_SIZE_3; + to_vec->count = from_vec->count; +} + +static void _XFORMAPI +TAG(transform_points3_2d)( GLvector4f *to_vec, + const GLfloat m[16], + const GLvector4f *from_vec ) +{ + const GLuint stride = from_vec->stride; + GLfloat *from = from_vec->start; + GLfloat (*to)[4] = (GLfloat (*)[4])to_vec->start; + GLuint count = from_vec->count; + const GLfloat m0 = m[0], m1 = m[1], m4 = m[4], m5 = m[5]; + const GLfloat m12 = m[12], m13 = m[13]; + GLuint i; + STRIDE_LOOP { + const GLfloat ox = from[0], oy = from[1], oz = from[2]; + to[i][0] = m0 * ox + m4 * oy + m12 ; + to[i][1] = m1 * ox + m5 * oy + m13 ; + to[i][2] = + oz ; + } + to_vec->size = 3; + to_vec->flags |= VEC_SIZE_3; + to_vec->count = from_vec->count; +} + +static void _XFORMAPI +TAG(transform_points3_2d_no_rot)( GLvector4f *to_vec, + const GLfloat m[16], + const GLvector4f *from_vec ) +{ + const GLuint stride = from_vec->stride; + GLfloat *from = from_vec->start; + GLfloat (*to)[4] = (GLfloat (*)[4])to_vec->start; + GLuint count = from_vec->count; + const GLfloat m0 = m[0], m5 = m[5], m12 = m[12], m13 = m[13]; + GLuint i; + STRIDE_LOOP { + const GLfloat ox = from[0], oy = from[1], oz = from[2]; + to[i][0] = m0 * ox + m12 ; + to[i][1] = m5 * oy + m13 ; + to[i][2] = + oz ; + } + to_vec->size = 3; + to_vec->flags |= VEC_SIZE_3; + to_vec->count = from_vec->count; +} + +static void _XFORMAPI +TAG(transform_points3_3d)( GLvector4f *to_vec, + const GLfloat m[16], + const GLvector4f *from_vec ) +{ + const GLuint stride = from_vec->stride; + GLfloat *from = from_vec->start; + GLfloat (*to)[4] = (GLfloat (*)[4])to_vec->start; + GLuint count = from_vec->count; + const GLfloat m0 = m[0], m1 = m[1], m2 = m[2], m4 = m[4], m5 = m[5]; + const GLfloat m6 = m[6], m8 = m[8], m9 = m[9], m10 = m[10]; + const GLfloat m12 = m[12], m13 = m[13], m14 = m[14]; + GLuint i; + STRIDE_LOOP { + const GLfloat ox = from[0], oy = from[1], oz = from[2]; + to[i][0] = m0 * ox + m4 * oy + m8 * oz + m12 ; + to[i][1] = m1 * ox + m5 * oy + m9 * oz + m13 ; + to[i][2] = m2 * ox + m6 * oy + m10 * oz + m14 ; + } + to_vec->size = 3; + to_vec->flags |= VEC_SIZE_3; + to_vec->count = from_vec->count; +} + +/* previously known as ortho... + */ +static void _XFORMAPI +TAG(transform_points3_3d_no_rot)( GLvector4f *to_vec, + const GLfloat m[16], + const GLvector4f *from_vec ) +{ + const GLuint stride = from_vec->stride; + GLfloat *from = from_vec->start; + GLfloat (*to)[4] = (GLfloat (*)[4])to_vec->start; + GLuint count = from_vec->count; + const GLfloat m0 = m[0], m5 = m[5]; + const GLfloat m10 = m[10], m12 = m[12], m13 = m[13], m14 = m[14]; + GLuint i; + STRIDE_LOOP { + const GLfloat ox = from[0], oy = from[1], oz = from[2]; + to[i][0] = m0 * ox + m12 ; + to[i][1] = m5 * oy + m13 ; + to[i][2] = m10 * oz + m14 ; + } + to_vec->size = 3; + to_vec->flags |= VEC_SIZE_3; + to_vec->count = from_vec->count; +} + +static void _XFORMAPI +TAG(transform_points3_perspective)( GLvector4f *to_vec, + const GLfloat m[16], + const GLvector4f *from_vec ) +{ + const GLuint stride = from_vec->stride; + GLfloat *from = from_vec->start; + GLfloat (*to)[4] = (GLfloat (*)[4])to_vec->start; + GLuint count = from_vec->count; + const GLfloat m0 = m[0], m5 = m[5], m8 = m[8], m9 = m[9]; + const GLfloat m10 = m[10], m14 = m[14]; + GLuint i; + STRIDE_LOOP { + const GLfloat ox = from[0], oy = from[1], oz = from[2]; + to[i][0] = m0 * ox + m8 * oz ; + to[i][1] = m5 * oy + m9 * oz ; + to[i][2] = m10 * oz + m14 ; + to[i][3] = -oz ; + } + to_vec->size = 4; + to_vec->flags |= VEC_SIZE_4; + to_vec->count = from_vec->count; +} + + + +static void _XFORMAPI +TAG(transform_points4_general)( GLvector4f *to_vec, + const GLfloat m[16], + const GLvector4f *from_vec ) +{ + const GLuint stride = from_vec->stride; + GLfloat *from = from_vec->start; + GLfloat (*to)[4] = (GLfloat (*)[4])to_vec->start; + GLuint count = from_vec->count; + const GLfloat m0 = m[0], m4 = m[4], m8 = m[8], m12 = m[12]; + const GLfloat m1 = m[1], m5 = m[5], m9 = m[9], m13 = m[13]; + const GLfloat m2 = m[2], m6 = m[6], m10 = m[10], m14 = m[14]; + const GLfloat m3 = m[3], m7 = m[7], m11 = m[11], m15 = m[15]; + GLuint i; + STRIDE_LOOP { + const GLfloat ox = from[0], oy = from[1], oz = from[2], ow = from[3]; + to[i][0] = m0 * ox + m4 * oy + m8 * oz + m12 * ow; + to[i][1] = m1 * ox + m5 * oy + m9 * oz + m13 * ow; + to[i][2] = m2 * ox + m6 * oy + m10 * oz + m14 * ow; + to[i][3] = m3 * ox + m7 * oy + m11 * oz + m15 * ow; + } + to_vec->size = 4; + to_vec->flags |= VEC_SIZE_4; + to_vec->count = from_vec->count; +} + +static void _XFORMAPI +TAG(transform_points4_identity)( GLvector4f *to_vec, + const GLfloat m[16], + const GLvector4f *from_vec ) +{ + const GLuint stride = from_vec->stride; + GLfloat *from = from_vec->start; + GLfloat (*to)[4] = (GLfloat (*)[4])to_vec->start; + GLuint count = from_vec->count; + GLuint i; + if (to_vec == from_vec) return; + STRIDE_LOOP { + to[i][0] = from[0]; + to[i][1] = from[1]; + to[i][2] = from[2]; + to[i][3] = from[3]; + } + to_vec->size = 4; + to_vec->flags |= VEC_SIZE_4; + to_vec->count = from_vec->count; +} + +static void _XFORMAPI +TAG(transform_points4_2d)( GLvector4f *to_vec, + const GLfloat m[16], + const GLvector4f *from_vec ) +{ + const GLuint stride = from_vec->stride; + GLfloat *from = from_vec->start; + GLfloat (*to)[4] = (GLfloat (*)[4])to_vec->start; + GLuint count = from_vec->count; + const GLfloat m0 = m[0], m1 = m[1], m4 = m[4], m5 = m[5]; + const GLfloat m12 = m[12], m13 = m[13]; + GLuint i; + STRIDE_LOOP { + const GLfloat ox = from[0], oy = from[1], oz = from[2], ow = from[3]; + to[i][0] = m0 * ox + m4 * oy + m12 * ow; + to[i][1] = m1 * ox + m5 * oy + m13 * ow; + to[i][2] = + oz ; + to[i][3] = ow; + } + to_vec->size = 4; + to_vec->flags |= VEC_SIZE_4; + to_vec->count = from_vec->count; +} + +static void _XFORMAPI +TAG(transform_points4_2d_no_rot)( GLvector4f *to_vec, + const GLfloat m[16], + const GLvector4f *from_vec ) +{ + const GLuint stride = from_vec->stride; + GLfloat *from = from_vec->start; + GLfloat (*to)[4] = (GLfloat (*)[4])to_vec->start; + GLuint count = from_vec->count; + const GLfloat m0 = m[0], m5 = m[5], m12 = m[12], m13 = m[13]; + GLuint i; + STRIDE_LOOP { + const GLfloat ox = from[0], oy = from[1], oz = from[2], ow = from[3]; + to[i][0] = m0 * ox + m12 * ow; + to[i][1] = m5 * oy + m13 * ow; + to[i][2] = + oz ; + to[i][3] = ow; + } + to_vec->size = 4; + to_vec->flags |= VEC_SIZE_4; + to_vec->count = from_vec->count; +} + +static void _XFORMAPI +TAG(transform_points4_3d)( GLvector4f *to_vec, + const GLfloat m[16], + const GLvector4f *from_vec ) +{ + const GLuint stride = from_vec->stride; + GLfloat *from = from_vec->start; + GLfloat (*to)[4] = (GLfloat (*)[4])to_vec->start; + GLuint count = from_vec->count; + const GLfloat m0 = m[0], m1 = m[1], m2 = m[2], m4 = m[4], m5 = m[5]; + const GLfloat m6 = m[6], m8 = m[8], m9 = m[9], m10 = m[10]; + const GLfloat m12 = m[12], m13 = m[13], m14 = m[14]; + GLuint i; + STRIDE_LOOP { + const GLfloat ox = from[0], oy = from[1], oz = from[2], ow = from[3]; + to[i][0] = m0 * ox + m4 * oy + m8 * oz + m12 * ow; + to[i][1] = m1 * ox + m5 * oy + m9 * oz + m13 * ow; + to[i][2] = m2 * ox + m6 * oy + m10 * oz + m14 * ow; + to[i][3] = ow; + } + to_vec->size = 4; + to_vec->flags |= VEC_SIZE_4; + to_vec->count = from_vec->count; +} + +static void _XFORMAPI +TAG(transform_points4_3d_no_rot)( GLvector4f *to_vec, + const GLfloat m[16], + const GLvector4f *from_vec ) +{ + const GLuint stride = from_vec->stride; + GLfloat *from = from_vec->start; + GLfloat (*to)[4] = (GLfloat (*)[4])to_vec->start; + GLuint count = from_vec->count; + const GLfloat m0 = m[0], m5 = m[5]; + const GLfloat m10 = m[10], m12 = m[12], m13 = m[13], m14 = m[14]; + GLuint i; + STRIDE_LOOP { + const GLfloat ox = from[0], oy = from[1], oz = from[2], ow = from[3]; + to[i][0] = m0 * ox + m12 * ow; + to[i][1] = m5 * oy + m13 * ow; + to[i][2] = m10 * oz + m14 * ow; + to[i][3] = ow; + } + to_vec->size = 4; + to_vec->flags |= VEC_SIZE_4; + to_vec->count = from_vec->count; +} + +static void _XFORMAPI +TAG(transform_points4_perspective)( GLvector4f *to_vec, + const GLfloat m[16], + const GLvector4f *from_vec ) +{ + const GLuint stride = from_vec->stride; + GLfloat *from = from_vec->start; + GLfloat (*to)[4] = (GLfloat (*)[4])to_vec->start; + GLuint count = from_vec->count; + const GLfloat m0 = m[0], m5 = m[5], m8 = m[8], m9 = m[9]; + const GLfloat m10 = m[10], m14 = m[14]; + GLuint i; + STRIDE_LOOP { + const GLfloat ox = from[0], oy = from[1], oz = from[2], ow = from[3]; + to[i][0] = m0 * ox + m8 * oz ; + to[i][1] = m5 * oy + m9 * oz ; + to[i][2] = m10 * oz + m14 * ow ; + to[i][3] = -oz ; + } + to_vec->size = 4; + to_vec->flags |= VEC_SIZE_4; + to_vec->count = from_vec->count; +} + +static transform_func _XFORMAPI TAG(transform_tab_1)[7]; +static transform_func _XFORMAPI TAG(transform_tab_2)[7]; +static transform_func _XFORMAPI TAG(transform_tab_3)[7]; +static transform_func _XFORMAPI TAG(transform_tab_4)[7]; + +/* Similar functions could be called several times, with more highly + * optimized routines overwriting the arrays. This only occurs during + * startup. + */ +static void _XFORMAPI TAG(init_c_transformations)( void ) +{ +#define TAG_TAB _mesa_transform_tab +#define TAG_TAB_1 TAG(transform_tab_1) +#define TAG_TAB_2 TAG(transform_tab_2) +#define TAG_TAB_3 TAG(transform_tab_3) +#define TAG_TAB_4 TAG(transform_tab_4) + + TAG_TAB[1] = TAG_TAB_1; + TAG_TAB[2] = TAG_TAB_2; + TAG_TAB[3] = TAG_TAB_3; + TAG_TAB[4] = TAG_TAB_4; + + /* 1-D points (ie texcoords) */ + TAG_TAB_1[MATRIX_GENERAL] = TAG(transform_points1_general); + TAG_TAB_1[MATRIX_IDENTITY] = TAG(transform_points1_identity); + TAG_TAB_1[MATRIX_3D_NO_ROT] = TAG(transform_points1_3d_no_rot); + TAG_TAB_1[MATRIX_PERSPECTIVE] = TAG(transform_points1_perspective); + TAG_TAB_1[MATRIX_2D] = TAG(transform_points1_2d); + TAG_TAB_1[MATRIX_2D_NO_ROT] = TAG(transform_points1_2d_no_rot); + TAG_TAB_1[MATRIX_3D] = TAG(transform_points1_3d); + + /* 2-D points */ + TAG_TAB_2[MATRIX_GENERAL] = TAG(transform_points2_general); + TAG_TAB_2[MATRIX_IDENTITY] = TAG(transform_points2_identity); + TAG_TAB_2[MATRIX_3D_NO_ROT] = TAG(transform_points2_3d_no_rot); + TAG_TAB_2[MATRIX_PERSPECTIVE] = TAG(transform_points2_perspective); + TAG_TAB_2[MATRIX_2D] = TAG(transform_points2_2d); + TAG_TAB_2[MATRIX_2D_NO_ROT] = TAG(transform_points2_2d_no_rot); + TAG_TAB_2[MATRIX_3D] = TAG(transform_points2_3d); + + /* 3-D points */ + TAG_TAB_3[MATRIX_GENERAL] = TAG(transform_points3_general); + TAG_TAB_3[MATRIX_IDENTITY] = TAG(transform_points3_identity); + TAG_TAB_3[MATRIX_3D_NO_ROT] = TAG(transform_points3_3d_no_rot); + TAG_TAB_3[MATRIX_PERSPECTIVE] = TAG(transform_points3_perspective); + TAG_TAB_3[MATRIX_2D] = TAG(transform_points3_2d); + TAG_TAB_3[MATRIX_2D_NO_ROT] = TAG(transform_points3_2d_no_rot); + TAG_TAB_3[MATRIX_3D] = TAG(transform_points3_3d); + + /* 4-D points */ + TAG_TAB_4[MATRIX_GENERAL] = TAG(transform_points4_general); + TAG_TAB_4[MATRIX_IDENTITY] = TAG(transform_points4_identity); + TAG_TAB_4[MATRIX_3D_NO_ROT] = TAG(transform_points4_3d_no_rot); + TAG_TAB_4[MATRIX_PERSPECTIVE] = TAG(transform_points4_perspective); + TAG_TAB_4[MATRIX_2D] = TAG(transform_points4_2d); + TAG_TAB_4[MATRIX_2D_NO_ROT] = TAG(transform_points4_2d_no_rot); + TAG_TAB_4[MATRIX_3D] = TAG(transform_points4_3d); + +#undef TAG_TAB +#undef TAG_TAB_1 +#undef TAG_TAB_2 +#undef TAG_TAB_3 +#undef TAG_TAB_4 +} Index: dll/opengl/opengl32/mesa/math/mathmod.h =================================================================== --- dll/opengl/opengl32/mesa/math/mathmod.h (revision 0) +++ dll/opengl/opengl32/mesa/math/mathmod.h (working copy) @@ -0,0 +1,32 @@ +/* $Id: mathmod.h,v 1.3 2001/03/12 00:48:41 gareth Exp $ */ + +/* + * Mesa 3-D graphics library + * Version: 3.5 + * + * Copyright (C) 1999-2001 Brian Paul 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 + * BRIAN PAUL 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. + */ + +#ifndef _MESA_MATH_H_ +#define _MESA_MATH_H_ + +extern void _math_init( void ); + +#endif Index: dll/opengl/opengl32/mesa/matrix.c =================================================================== --- dll/opengl/opengl32/mesa/matrix.c (revision 0) +++ dll/opengl/opengl32/mesa/matrix.c (working copy) @@ -0,0 +1,531 @@ +/* $Id: matrix.c,v 1.35 2001/06/12 22:08:41 brianp Exp $ */ + +/* + * Mesa 3-D graphics library + * Version: 3.5 + * + * Copyright (C) 1999-2001 Brian Paul 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 + * BRIAN PAUL 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. + */ + + +/* + * Matrix operations + * + * NOTES: + * 1. 4x4 transformation matrices are stored in memory in column major order. + * 2. Points/vertices are to be thought of as column vectors. + * 3. Transformation of a point p by a matrix M is: p' = M * p + */ + + +#ifdef PC_HEADER +#include "all.h" +#else +#include "glheader.h" +#include "buffers.h" +#include "context.h" +#include "enums.h" +#include "macros.h" +#include "matrix.h" +#include "mem.h" +#include "mmath.h" +#include "mtypes.h" + +#include "math/m_matrix.h" +#endif + + +/**********************************************************************/ +/* API functions */ +/**********************************************************************/ + + +#define GET_ACTIVE_MATRIX(ctx, mat, flags, where) \ +do { \ + if (MESA_VERBOSE&VERBOSE_API) fprintf(stderr, "%s\n", where); \ + switch (ctx->Transform.MatrixMode) { \ + case GL_MODELVIEW: \ + mat = &ctx->ModelView; \ + flags |= _NEW_MODELVIEW; \ + break; \ + case GL_PROJECTION: \ + mat = &ctx->ProjectionMatrix; \ + flags |= _NEW_PROJECTION; \ + break; \ + case GL_TEXTURE: \ + mat = &ctx->TextureMatrix[ctx->Texture.CurrentUnit]; \ + flags |= _NEW_TEXTURE_MATRIX; \ + break; \ + case GL_COLOR: \ + mat = &ctx->ColorMatrix; \ + flags |= _NEW_COLOR_MATRIX; \ + break; \ + default: \ + _mesa_problem(ctx, where); \ + } \ +} while (0) + + +void +_mesa_Frustum( GLdouble left, GLdouble right, + GLdouble bottom, GLdouble top, + GLdouble nearval, GLdouble farval ) +{ + GET_CURRENT_CONTEXT(ctx); + GLmatrix *mat = 0; + ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx); + + GET_ACTIVE_MATRIX( ctx, mat, ctx->NewState, "glFrustrum" ); + + if (nearval <= 0.0 || + farval <= 0.0 || + nearval == farval || + left == right || + top == bottom) + { + _mesa_error( ctx, GL_INVALID_VALUE, "glFrustum" ); + return; + } + + _math_matrix_frustum( mat, left, right, bottom, top, nearval, farval ); +} + + +void +_mesa_Ortho( GLdouble left, GLdouble right, + GLdouble bottom, GLdouble top, + GLdouble nearval, GLdouble farval ) +{ + GET_CURRENT_CONTEXT(ctx); + GLmatrix *mat = 0; + ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx); + + GET_ACTIVE_MATRIX( ctx, mat, ctx->NewState, "glOrtho" ); + + if (left == right || + bottom == top || + nearval == farval) + { + _mesa_error( ctx, GL_INVALID_VALUE, "glOrtho" ); + return; + } + + _math_matrix_ortho( mat, left, right, bottom, top, nearval, farval ); +} + + +void +_mesa_MatrixMode( GLenum mode ) +{ + GET_CURRENT_CONTEXT(ctx); + ASSERT_OUTSIDE_BEGIN_END(ctx); + + switch (mode) { + case GL_MODELVIEW: + case GL_PROJECTION: + case GL_TEXTURE: + case GL_COLOR: + if (ctx->Transform.MatrixMode == mode) + return; + ctx->Transform.MatrixMode = mode; + FLUSH_VERTICES(ctx, _NEW_TRANSFORM); + break; + default: + _mesa_error( ctx, GL_INVALID_ENUM, "glMatrixMode" ); + } +} + + + +void +_mesa_PushMatrix( void ) +{ + GET_CURRENT_CONTEXT(ctx); + ASSERT_OUTSIDE_BEGIN_END(ctx); + + if (MESA_VERBOSE&VERBOSE_API) + fprintf(stderr, "glPushMatrix %s\n", + _mesa_lookup_enum_by_nr(ctx->Transform.MatrixMode)); + + switch (ctx->Transform.MatrixMode) { + case GL_MODELVIEW: + if (ctx->ModelViewStackDepth >= MAX_MODELVIEW_STACK_DEPTH - 1) { + _mesa_error( ctx, GL_STACK_OVERFLOW, "glPushMatrix"); + return; + } + _math_matrix_copy( &ctx->ModelViewStack[ctx->ModelViewStackDepth++], + &ctx->ModelView ); + break; + case GL_PROJECTION: + if (ctx->ProjectionStackDepth >= MAX_PROJECTION_STACK_DEPTH - 1) { + _mesa_error( ctx, GL_STACK_OVERFLOW, "glPushMatrix"); + return; + } + _math_matrix_copy( &ctx->ProjectionStack[ctx->ProjectionStackDepth++], + &ctx->ProjectionMatrix ); + break; + case GL_TEXTURE: + { + GLuint t = ctx->Texture.CurrentUnit; + if (ctx->TextureStackDepth[t] >= MAX_TEXTURE_STACK_DEPTH - 1) { + _mesa_error( ctx, GL_STACK_OVERFLOW, "glPushMatrix"); + return; + } + _math_matrix_copy( &ctx->TextureStack[t][ctx->TextureStackDepth[t]++], + &ctx->TextureMatrix[t] ); + } + break; + case GL_COLOR: + if (ctx->ColorStackDepth >= MAX_COLOR_STACK_DEPTH - 1) { + _mesa_error( ctx, GL_STACK_OVERFLOW, "glPushMatrix"); + return; + } + _math_matrix_copy( &ctx->ColorStack[ctx->ColorStackDepth++], + &ctx->ColorMatrix ); + break; + default: + _mesa_problem(ctx, "Bad matrix mode in _mesa_PushMatrix"); + } +} + + + +void +_mesa_PopMatrix( void ) +{ + GET_CURRENT_CONTEXT(ctx); + ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx); + + if (MESA_VERBOSE&VERBOSE_API) + fprintf(stderr, "glPopMatrix %s\n", + _mesa_lookup_enum_by_nr(ctx->Transform.MatrixMode)); + + switch (ctx->Transform.MatrixMode) { + case GL_MODELVIEW: + if (ctx->ModelViewStackDepth==0) { + _mesa_error( ctx, GL_STACK_UNDERFLOW, "glPopMatrix"); + return; + } + _math_matrix_copy( &ctx->ModelView, + &ctx->ModelViewStack[--ctx->ModelViewStackDepth] ); + ctx->NewState |= _NEW_MODELVIEW; + break; + case GL_PROJECTION: + if (ctx->ProjectionStackDepth==0) { + _mesa_error( ctx, GL_STACK_UNDERFLOW, "glPopMatrix"); + return; + } + + _math_matrix_copy( &ctx->ProjectionMatrix, + &ctx->ProjectionStack[--ctx->ProjectionStackDepth] ); + ctx->NewState |= _NEW_PROJECTION; + break; + case GL_TEXTURE: + { + GLuint t = ctx->Texture.CurrentUnit; + if (ctx->TextureStackDepth[t]==0) { + _mesa_error( ctx, GL_STACK_UNDERFLOW, "glPopMatrix"); + return; + } + _math_matrix_copy(&ctx->TextureMatrix[t], + &ctx->TextureStack[t][--ctx->TextureStackDepth[t]]); + ctx->NewState |= _NEW_TEXTURE_MATRIX; + } + break; + case GL_COLOR: + if (ctx->ColorStackDepth==0) { + _mesa_error( ctx, GL_STACK_UNDERFLOW, "glPopMatrix"); + return; + } + _math_matrix_copy(&ctx->ColorMatrix, + &ctx->ColorStack[--ctx->ColorStackDepth]); + ctx->NewState |= _NEW_COLOR_MATRIX; + break; + default: + _mesa_problem(ctx, "Bad matrix mode in _mesa_PopMatrix"); + } +} + + + +void +_mesa_LoadIdentity( void ) +{ + GET_CURRENT_CONTEXT(ctx); + GLmatrix *mat = 0; + ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx); + GET_ACTIVE_MATRIX(ctx, mat, ctx->NewState, "glLoadIdentity"); + _math_matrix_set_identity( mat ); +} + + +void +_mesa_LoadMatrixf( const GLfloat *m ) +{ + GET_CURRENT_CONTEXT(ctx); + GLmatrix *mat = 0; + ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx); + GET_ACTIVE_MATRIX(ctx, mat, ctx->NewState, "glLoadMatrix"); + _math_matrix_loadf( mat, m ); +} + + +void +_mesa_LoadMatrixd( const GLdouble *m ) +{ + GLint i; + GLfloat f[16]; + for (i = 0; i < 16; i++) + f[i] = m[i]; + _mesa_LoadMatrixf(f); +} + + + +/* + * Multiply the active matrix by an arbitary matrix. + */ +void +_mesa_MultMatrixf( const GLfloat *m ) +{ + GET_CURRENT_CONTEXT(ctx); + GLmatrix *mat = 0; + ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx); + GET_ACTIVE_MATRIX( ctx, mat, ctx->NewState, "glMultMatrix" ); + _math_matrix_mul_floats( mat, m ); +} + + +/* + * Multiply the active matrix by an arbitary matrix. + */ +void +_mesa_MultMatrixd( const GLdouble *m ) +{ + GLint i; + GLfloat f[16]; + for (i = 0; i < 16; i++) + f[i] = m[i]; + _mesa_MultMatrixf( f ); +} + + + + +/* + * Execute a glRotate call + */ +void +_mesa_Rotatef( GLfloat angle, GLfloat x, GLfloat y, GLfloat z ) +{ + GET_CURRENT_CONTEXT(ctx); + ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx); + if (angle != 0.0F) { + GLmatrix *mat = 0; + GET_ACTIVE_MATRIX( ctx, mat, ctx->NewState, "glRotate" ); + _math_matrix_rotate( mat, angle, x, y, z ); + } +} + +void +_mesa_Rotated( GLdouble angle, GLdouble x, GLdouble y, GLdouble z ) +{ + _mesa_Rotatef(angle, x, y, z); +} + + +/* + * Execute a glScale call + */ +void +_mesa_Scalef( GLfloat x, GLfloat y, GLfloat z ) +{ + GET_CURRENT_CONTEXT(ctx); + GLmatrix *mat = 0; + ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx); + GET_ACTIVE_MATRIX(ctx, mat, ctx->NewState, "glScale"); + _math_matrix_scale( mat, x, y, z ); +} + + +void +_mesa_Scaled( GLdouble x, GLdouble y, GLdouble z ) +{ + _mesa_Scalef(x, y, z); +} + + +/* + * Execute a glTranslate call + */ +void +_mesa_Translatef( GLfloat x, GLfloat y, GLfloat z ) +{ + GET_CURRENT_CONTEXT(ctx); + GLmatrix *mat = 0; + ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx); + GET_ACTIVE_MATRIX(ctx, mat, ctx->NewState, "glTranslate"); + _math_matrix_translate( mat, x, y, z ); +} + + +void +_mesa_Translated( GLdouble x, GLdouble y, GLdouble z ) +{ + _mesa_Translatef(x, y, z); +} + + +void +_mesa_LoadTransposeMatrixfARB( const GLfloat *m ) +{ + GLfloat tm[16]; + _math_transposef(tm, m); + _mesa_LoadMatrixf(tm); +} + + +void +_mesa_LoadTransposeMatrixdARB( const GLdouble *m ) +{ + GLfloat tm[16]; + _math_transposefd(tm, m); + _mesa_LoadMatrixf(tm); +} + + +void +_mesa_MultTransposeMatrixfARB( const GLfloat *m ) +{ + GLfloat tm[16]; + _math_transposef(tm, m); + _mesa_MultMatrixf(tm); +} + + +void +_mesa_MultTransposeMatrixdARB( const GLdouble *m ) +{ + GLfloat tm[16]; + _math_transposefd(tm, m); + _mesa_MultMatrixf(tm); +} + + +/* + * Called via glViewport or display list execution. + */ +void +_mesa_Viewport( GLint x, GLint y, GLsizei width, GLsizei height ) +{ + GET_CURRENT_CONTEXT(ctx); + ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx); + _mesa_set_viewport(ctx, x, y, width, height); +} + + +/* + * Define a new viewport and reallocate auxillary buffers if the size of + * the window (color buffer) has changed. + */ +void +_mesa_set_viewport( GLcontext *ctx, GLint x, GLint y, + GLsizei width, GLsizei height ) +{ + const GLfloat n = ctx->Viewport.Near; + const GLfloat f = ctx->Viewport.Far; + + if (width < 0 || height < 0) { + _mesa_error( ctx, GL_INVALID_VALUE, "glViewport" ); + return; + } + + if (MESA_VERBOSE & VERBOSE_API) + fprintf(stderr, "glViewport %d %d %d %d\n", x, y, width, height); + + /* clamp width, and height to implementation dependent range */ + width = CLAMP( width, 1, MAX_WIDTH ); + height = CLAMP( height, 1, MAX_HEIGHT ); + + /* Save viewport */ + ctx->Viewport.X = x; + ctx->Viewport.Width = width; + ctx->Viewport.Y = y; + ctx->Viewport.Height = height; + + /* compute scale and bias values :: This is really driver-specific + * and should be maintained elsewhere if at all. + */ + 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; + ctx->Viewport._WindowMap.m[MAT_SZ] = ctx->DepthMaxF * ((f - n) / 2.0); + ctx->Viewport._WindowMap.m[MAT_TZ] = ctx->DepthMaxF * ((f - n) / 2.0 + n); + ctx->Viewport._WindowMap.flags = MAT_FLAG_GENERAL_SCALE|MAT_FLAG_TRANSLATION; + ctx->Viewport._WindowMap.type = MATRIX_3D_NO_ROT; + ctx->NewState |= _NEW_VIEWPORT; + + /* Check if window/buffer has been resized and if so, reallocate the + * ancillary buffers. + */ + _mesa_ResizeBuffersMESA(); + + if (ctx->Driver.Viewport) { + (*ctx->Driver.Viewport)( ctx, x, y, width, height ); + } +} + + + +void +_mesa_DepthRange( GLclampd nearval, GLclampd farval ) +{ + /* + * nearval - specifies mapping of the near clipping plane to window + * coordinates, default is 0 + * farval - specifies mapping of the far clipping plane to window + * coordinates, default is 1 + * + * After clipping and div by w, z coords are in -1.0 to 1.0, + * corresponding to near and far clipping planes. glDepthRange + * specifies a linear mapping of the normalized z coords in + * this range to window z coords. + */ + GLfloat n, f; + GET_CURRENT_CONTEXT(ctx); + ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx); + + if (MESA_VERBOSE&VERBOSE_API) + fprintf(stderr, "glDepthRange %f %f\n", nearval, farval); + + n = (GLfloat) CLAMP( nearval, 0.0, 1.0 ); + f = (GLfloat) CLAMP( farval, 0.0, 1.0 ); + + ctx->Viewport.Near = n; + ctx->Viewport.Far = f; + ctx->Viewport._WindowMap.m[MAT_SZ] = ctx->DepthMaxF * ((f - n) / 2.0); + ctx->Viewport._WindowMap.m[MAT_TZ] = ctx->DepthMaxF * ((f - n) / 2.0 + n); + ctx->NewState |= _NEW_VIEWPORT; + + if (ctx->Driver.DepthRange) { + (*ctx->Driver.DepthRange)( ctx, nearval, farval ); + } +} Index: dll/opengl/opengl32/mesa/matrix.h =================================================================== --- dll/opengl/opengl32/mesa/matrix.h (revision 0) +++ dll/opengl/opengl32/mesa/matrix.h (working copy) @@ -0,0 +1,109 @@ +/* $Id: matrix.h,v 1.12 2001/03/12 00:48:38 gareth Exp $ */ + +/* + * Mesa 3-D graphics library + * Version: 3.5 + * + * Copyright (C) 1999-2001 Brian Paul 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 + * BRIAN PAUL 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. + */ + + +#ifndef MATRIX_H +#define MATRIX_H + + +#include "mtypes.h" + + +extern void +_mesa_Frustum( GLdouble left, GLdouble right, + GLdouble bottom, GLdouble top, + GLdouble nearval, GLdouble farval ); + +extern void +_mesa_Ortho( GLdouble left, GLdouble right, + GLdouble bottom, GLdouble top, + GLdouble nearval, GLdouble farval ); + +extern void +_mesa_PushMatrix( void ); + +extern void +_mesa_PopMatrix( void ); + +extern void +_mesa_LoadIdentity( void ); + +extern void +_mesa_LoadMatrixf( const GLfloat *m ); + +extern void +_mesa_LoadMatrixd( const GLdouble *m ); + +extern void +_mesa_MatrixMode( GLenum mode ); + +extern void +_mesa_MultMatrixf( const GLfloat *m ); + +extern void +_mesa_MultMatrixd( const GLdouble *m ); + +extern void +_mesa_Rotatef( GLfloat angle, GLfloat x, GLfloat y, GLfloat z ); + +extern void +_mesa_Rotated( GLdouble angle, GLdouble x, GLdouble y, GLdouble z ); + +extern void +_mesa_Scalef( GLfloat x, GLfloat y, GLfloat z ); + +extern void +_mesa_Scaled( GLdouble x, GLdouble y, GLdouble z ); + +extern void +_mesa_Translatef( GLfloat x, GLfloat y, GLfloat z ); + +extern void +_mesa_Translated( GLdouble x, GLdouble y, GLdouble z ); + +extern void +_mesa_LoadTransposeMatrixfARB( const GLfloat *m ); + +extern void +_mesa_LoadTransposeMatrixdARB( const GLdouble *m ); + +extern void +_mesa_MultTransposeMatrixfARB( const GLfloat *m ); + +extern void +_mesa_MultTransposeMatrixdARB( const GLdouble *m ); + +extern void +_mesa_Viewport( GLint x, GLint y, GLsizei width, GLsizei height ); + +extern void +_mesa_set_viewport( GLcontext *ctx, GLint x, GLint y, GLsizei width, GLsizei height ); + +extern void +_mesa_DepthRange( GLclampd nearval, GLclampd farval ); + + +#endif Index: dll/opengl/opengl32/mesa/mem.c =================================================================== --- dll/opengl/opengl32/mesa/mem.c (revision 0) +++ dll/opengl/opengl32/mesa/mem.c (working copy) @@ -0,0 +1,168 @@ +/* $Id: mem.c,v 1.5 2001/03/12 00:48:38 gareth Exp $ */ + +/* + * Mesa 3-D graphics library + * Version: 3.5 + * + * Copyright (C) 1999-2001 Brian Paul 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 + * BRIAN PAUL 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. + */ + + +/* + * Memory allocation functions. Called via the MALLOC, CALLOC and + * FREE macros when DEBUG symbol is defined. + * You might want to set breakpoints on these functions or plug in + * other memory allocation functions. The Mesa sources should only + * use the MALLOC and FREE macros (which could also be overriden). + */ + +#ifdef PC_HEADER +#include "all.h" +#else +#include "glheader.h" +#include "config.h" +#include "macros.h" +#include "mem.h" +#endif + + + +/* + * Allocate memory (uninitialized) + */ +void * +_mesa_malloc(size_t bytes) +{ + return malloc(bytes); +} + + +/* + * Allocate memory and initialize to zero. + */ +void * +_mesa_calloc(size_t bytes) +{ + return calloc(1, bytes); +} + + +/* + * Free memory + */ +void +_mesa_free(void *ptr) +{ + free(ptr); +} + + + +/* + * N-byte aligned memory allocation functions. Called via the ALIGN_MALLOC, + * ALIGN_CALLOC and ALIGN_FREE macros. Debug versions? + * These functions allow dynamically allocated memory to be correctly + * aligned for improved cache utilization and specialized assembly + * support. + */ + + +/* + * Allocate N-byte aligned memory (uninitialized) + */ +void * +_mesa_align_malloc(size_t bytes, unsigned long alignment) +{ + unsigned long ptr, buf; + + ASSERT( alignment > 0 ); + + ptr = (unsigned long) MALLOC( bytes + alignment ); + + buf = (ptr + alignment) & ~(unsigned long)(alignment - 1); + *(unsigned long *)(buf - sizeof(void *)) = ptr; + +#ifdef DEBUG + /* mark the non-aligned area */ + while ( ptr < buf - sizeof(void *) ) { + *(unsigned long *)ptr = 0xcdcdcdcd; + ptr += sizeof(unsigned long); + } +#endif + + return (void *)buf; +} + + +/* + * Allocate N-byte aligned memory and initialize to zero + */ +void * +_mesa_align_calloc(size_t bytes, unsigned long alignment) +{ + unsigned long ptr, buf; + + ASSERT( alignment > 0 ); + + ptr = (unsigned long) CALLOC( bytes + alignment ); + + buf = (ptr + alignment) & ~(unsigned long)(alignment - 1); + *(unsigned long *)(buf - sizeof(void *)) = ptr; + +#ifdef DEBUG + /* mark the non-aligned area */ + while ( ptr < buf - sizeof(void *) ) { + *(unsigned long *)ptr = 0xcdcdcdcd; + ptr += sizeof(unsigned long); + } +#endif + + return (void *)buf; +} + + +/* + * Free N-byte aligned memory + */ +void +_mesa_align_free(void *ptr) +{ +#if 0 + FREE( (void *)(*(unsigned long *)((unsigned long)ptr - sizeof(void *))) ); +#else + /* The actuall address to free is stuffed in the word immediately + * before the address the client sees. + */ + void **cubbyHole = (void **) ((char *) ptr - sizeof(void *)); + void *realAddr = *cubbyHole; + FREE(realAddr); +#endif +} + + +/* + * Set a block of GLushorts to a particular value. + */ +void +_mesa_memset16( GLushort *dst, GLushort val, size_t n ) +{ + while (n-- > 0) + *dst++ = val; +} Index: dll/opengl/opengl32/mesa/mem.h =================================================================== --- dll/opengl/opengl32/mesa/mem.h (revision 0) +++ dll/opengl/opengl32/mesa/mem.h (working copy) @@ -0,0 +1,138 @@ +/* $Id: mem.h,v 1.10 2001/05/16 20:27:12 brianp Exp $ */ + +/* + * Mesa 3-D graphics library + * Version: 3.5 + * + * Copyright (C) 1999-2001 Brian Paul 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 + * BRIAN PAUL 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. + */ + + +#ifndef MEM_H +#define MEM_H + + +#include "glheader.h" +/* Do not reference mtypes.h from this file. + */ + +/* + * Memory allocation + */ +extern void *_mesa_malloc(size_t bytes); +extern void *_mesa_calloc(size_t bytes); +extern void _mesa_free(void *ptr); + +extern void *_mesa_align_malloc(size_t bytes, unsigned long alignment); +extern void *_mesa_align_calloc(size_t bytes, unsigned long alignment); +extern void _mesa_align_free(void *ptr); + + +#ifdef DEBUG + +/* call Mesa memory functions */ +#define MALLOC(BYTES) _mesa_malloc(BYTES) +#define CALLOC(BYTES) _mesa_calloc(BYTES) +#define MALLOC_STRUCT(T) (struct T *) _mesa_malloc(sizeof(struct T)) +#define CALLOC_STRUCT(T) (struct T *) _mesa_calloc(sizeof(struct T)) +#define FREE(PTR) _mesa_free(PTR) + +#else + +/* directly call C lib memory functions */ +#define MALLOC(BYTES) (void *) malloc(BYTES) +#define CALLOC(BYTES) (void *) calloc(1, BYTES) +#define MALLOC_STRUCT(T) (struct T *) malloc(sizeof(struct T)) +#define CALLOC_STRUCT(T) (struct T *) calloc(1,sizeof(struct T)) +#define FREE(PTR) free(PTR) + +#endif + +/* call Mesa N-byte aligned memory functions */ +#define ALIGN_MALLOC(BYTES, N) (void *) _mesa_align_malloc(BYTES, N) +#define ALIGN_CALLOC(BYTES, N) (void *) _mesa_align_calloc(BYTES, N) +#define ALIGN_MALLOC_STRUCT(T, N) (struct T *) _mesa_align_malloc(sizeof(struct T), N) +#define ALIGN_CALLOC_STRUCT(T, N) (struct T *) _mesa_align_calloc(sizeof(struct T), N) +#define ALIGN_FREE(PTR) _mesa_align_free(PTR) + + +/* Memory copy: */ +#ifdef SUNOS4 +#define MEMCPY( DST, SRC, BYTES) \ + memcpy( (char *) (DST), (char *) (SRC), (int) (BYTES) ) +#else +#define MEMCPY( DST, SRC, BYTES) \ + memcpy( (void *) (DST), (void *) (SRC), (size_t) (BYTES) ) +#endif + + +/* Memory set: */ +#ifdef SUNOS4 +#define MEMSET( DST, VAL, N ) \ + memset( (char *) (DST), (int) (VAL), (int) (N) ) +#else +#define MEMSET( DST, VAL, N ) \ + memset( (void *) (DST), (int) (VAL), (size_t) (N) ) +#endif + +extern void _mesa_memset16( GLushort *dst, GLushort val, size_t n ); + +#define MEMSET16( DST, VAL, N ) \ + _mesa_memset16( (GLushort *) (DST), (GLushort) (VAL), (size_t) (N) ) + + +/* On some systems we might want to use bzero() (but is bzero portable?) */ +#if defined(__FreeBSD__) +#define BZERO( ADDR, N ) \ + bzero( (void *) (ADDR), (size_t) (N) ) +#else +#define BZERO( ADDR, N ) \ + memset( (void *) (ADDR), 0, (size_t) (N) ) +#endif + + +/* MACs and BeOS don't support static larger than 32kb, so... */ +#if defined(macintosh) && !defined(__MRC__) +/*extern char *AGLAlloc(int size);*/ +/*extern void AGLFree(char* ptr);*/ +# define DEFARRAY(TYPE,NAME,SIZE) TYPE *NAME = (TYPE*)MALLOC(sizeof(TYPE)*(SIZE)) +# define DEFMARRAY(TYPE,NAME,SIZE1,SIZE2) TYPE (*NAME)[SIZE2] = (TYPE(*)[SIZE2])MALLOC(sizeof(TYPE)*(SIZE1)*(SIZE2)) +# define DEFMNARRAY(TYPE,NAME,SIZE1,SIZE2,SIZE3) TYPE (*NAME)[SIZE2][SIZE3] = (TYPE(*)[SIZE2][SIZE3])MALLOC(sizeof(TYPE)*(SIZE1)*(SIZE2)*(SIZE3) + +# define CHECKARRAY(NAME,CMD) do {if (!(NAME)) {CMD;}} while (0) +# define UNDEFARRAY(NAME) do {if ((NAME)) {FREE((char*)NAME);} }while (0) +#elif defined(__BEOS__) +# define DEFARRAY(TYPE,NAME,SIZE) TYPE *NAME = (TYPE*)malloc(sizeof(TYPE)*(SIZE)) +# define DEFMARRAY(TYPE,NAME,SIZE1,SIZE2) TYPE (*NAME)[SIZE2] = (TYPE(*)[SIZE2])malloc(sizeof(TYPE)*(SIZE1)*(SIZE2)) +# define DEFMNARRAY(TYPE,NAME,SIZE1,SIZE2,SIZE3) TYPE (*NAME)[SIZE2][SIZE3] = (TYPE(*)[SIZE2][SIZE3])malloc(sizeof(TYPE)*(SIZE1)*(SIZE2)*(SIZE3) +# define CHECKARRAY(NAME,CMD) do {if (!(NAME)) {CMD;}} while (0) +# define UNDEFARRAY(NAME) do {if ((NAME)) {free((char*)NAME);} }while (0) +#else +# define DEFARRAY(TYPE,NAME,SIZE) TYPE NAME[SIZE] +# define DEFMARRAY(TYPE,NAME,SIZE1,SIZE2) TYPE NAME[SIZE1][SIZE2] +# define DEFMNARRAY(TYPE,NAME,SIZE1,SIZE2,SIZE3) TYPE NAME[SIZE1][SIZE2][SIZE3] +# define CHECKARRAY(NAME,CMD) do {} while(0) +# define UNDEFARRAY(NAME) +#endif + + + + +#endif Index: dll/opengl/opengl32/mesa/mmath.c =================================================================== --- dll/opengl/opengl32/mesa/mmath.c (revision 0) +++ dll/opengl/opengl32/mesa/mmath.c (working copy) @@ -0,0 +1,183 @@ +/* $Id: mmath.c,v 1.9 2001/03/12 00:48:38 gareth Exp $ */ + +/* + * Mesa 3-D graphics library + * Version: 3.5 + * + * Copyright (C) 1999-2001 Brian Paul 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 + * BRIAN PAUL 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. + */ + + +#ifdef PC_HEADER +#include "all.h" +#else +#include "glheader.h" +#include "mmath.h" +#endif + + +static int in_fast_math; + +/* + * A High Speed, Low Precision Square Root + * by Paul Lalonde and Robert Dawson + * from "Graphics Gems", Academic Press, 1990 + */ + +/* + * SPARC implementation of a fast square root by table + * lookup. + * SPARC floating point format is as follows: + * + * BIT 31 30 23 22 0 + * sign exponent mantissa + */ +static short sqrttab[0x100]; /* declare table of square roots */ + +static void init_sqrt(void) +{ +#ifdef FAST_MATH + unsigned short i; + float f; + unsigned int *fi = (unsigned int *)&f; + /* to access the bits of a float in */ + /* C quickly we must misuse pointers */ + + for(i=0; i<= 0x7f; i++) { + *fi = 0; + + /* + * Build a float with the bit pattern i as mantissa + * and an exponent of 0, stored as 127 + */ + + *fi = (i << 16) | (127 << 23); + f = sqrt(f); + + /* + * Take the square root then strip the first 7 bits of + * the mantissa into the table + */ + + sqrttab[i] = (*fi & 0x7fffff) >> 16; + + /* + * Repeat the process, this time with an exponent of + * 1, stored as 128 + */ + + *fi = 0; + *fi = (i << 16) | (128 << 23); + f = sqrt(f); + sqrttab[i+0x80] = (*fi & 0x7fffff) >> 16; + } +#else + (void) sqrttab; /* silence compiler warnings */ +#endif /*FAST_MATH*/ +} + + +float gl_sqrt( float x ) +{ +#ifdef FAST_MATH + unsigned int *num = (unsigned int *)&x; + /* to access the bits of a float in C + * we must misuse pointers */ + + short e; /* the exponent */ + if (x == 0.0F) return 0.0F; /* check for square root of 0 */ + e = (*num >> 23) - 127; /* get the exponent - on a SPARC the */ + /* exponent is stored with 127 added */ + *num &= 0x7fffff; /* leave only the mantissa */ + if (e & 0x01) *num |= 0x800000; + /* the exponent is odd so we have to */ + /* look it up in the second half of */ + /* the lookup table, so we set the */ + /* high bit */ + e >>= 1; /* divide the exponent by two */ + /* note that in C the shift */ + /* operators are sign preserving */ + /* for signed operands */ + /* Do the table lookup, based on the quaternary mantissa, + * then reconstruct the result back into a float + */ + *num = ((sqrttab[*num >> 16]) << 16) | ((e + 127) << 23); + return x; +#else + return sqrt(x); +#endif +} + + +/* ubyte -> float conversion */ +float _mesa_ubyte_to_float_color_tab[256]; + + +/* + * Initialize tables, etc for fast math functions. + */ +void +_mesa_init_math(void) +{ + static GLboolean initialized = GL_FALSE; + + if (!initialized) { + int i; + for (i = 0; i < 256; i++) { + _mesa_ubyte_to_float_color_tab[i] = (float) i / 255.0; + } + + init_sqrt(); + + initialized = GL_TRUE; + in_fast_math = 0; + +#if defined(_FPU_GETCW) && defined(_FPU_SETCW) + { + const char *debug = getenv("MESA_DEBUG"); + if (debug && strcmp(debug, "FP")==0) { + /* die on FP exceptions */ + fpu_control_t mask; + _FPU_GETCW(mask); + mask &= ~(_FPU_MASK_IM | _FPU_MASK_DM | _FPU_MASK_ZM + | _FPU_MASK_OM | _FPU_MASK_UM); + _FPU_SETCW(mask); + } + } +#endif + } +} + + + +/* + * Return number of bits set in given GLuint. + */ +GLuint +_mesa_bitcount(GLuint n) +{ + GLuint bits; + for (bits = 0; n > 0; n = n >> 1) { + if (n & 1) { + bits++; + } + } + return bits; +} Index: dll/opengl/opengl32/mesa/mmath.h =================================================================== --- dll/opengl/opengl32/mesa/mmath.h (revision 0) +++ dll/opengl/opengl32/mesa/mmath.h (working copy) @@ -0,0 +1,580 @@ +/* $Id: mmath.h,v 1.39 2001/06/15 15:22:07 brianp Exp $ */ + +/* + * Mesa 3-D graphics library + * Version: 3.5 + * + * Copyright (C) 1999-2001 Brian Paul 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 + * BRIAN PAUL 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. + */ + + +/* + * Faster arithmetic functions. If the FAST_MATH preprocessor symbol is + * defined on the command line (-DFAST_MATH) then we'll use some (hopefully) + * faster functions for sqrt(), etc. + */ + + +#ifndef MMATH_H +#define MMATH_H + + +#include "glheader.h" +/* Do not reference mtypes.h from this file. + */ + +/* + * Set the x86 FPU control word to guarentee only 32 bits of presision + * are stored in registers. Allowing the FPU to store more introduces + * differences between situations where numbers are pulled out of memory + * vs. situations where the compiler is able to optimize register usage. + * + * In the worst case, we force the compiler to use a memory access to + * truncate the float, by specifying the 'volatile' keyword. + */ +#if defined(__GNUC__) && defined(__i386__) + +/* Hardware default: All exceptions masked, extended double precision, + * round to nearest. IEEE compliant. + */ +#define DEFAULT_X86_FPU 0x037f + +/* All exceptions masked, single precision, round to nearest. + */ +#define FAST_X86_FPU 0x003f + +/* Set it up how we want it. The fldcw instruction will cause any + * pending FP exceptions to be raised prior to entering the block, and + * we clear any pending exceptions before exiting the block. Hence, asm + * code has free reign over the FPU while in the fast math block. + */ +#if defined(NO_FAST_MATH) +#define START_FAST_MATH(x) \ +do { \ + static GLuint mask = DEFAULT_X86_FPU; \ + __asm__ ( "fnstcw %0" : "=m" (*&(x)) ); \ + __asm__ ( "fldcw %0" : : "m" (mask) ); \ +} while (0) +#else +#define START_FAST_MATH(x) \ +do { \ + static GLuint mask = FAST_X86_FPU; \ + __asm__ ( "fnstcw %0" : "=m" (*&(x)) ); \ + __asm__ ( "fldcw %0" : : "m" (mask) ); \ +} while (0) +#endif + +/* Put it back how the application had it, and clear any exceptions that + * may have occurred in the FAST_MATH block. + */ +#define END_FAST_MATH(x) \ +do { \ + __asm__ ( "fnclex ; fldcw %0" : : "m" (*&(x)) ); \ +} while (0) + +#define HAVE_FAST_MATH + +#elif defined(__WATCOMC__) && !defined(NO_FAST_MATH) + +/* This is the watcom specific inline assembly version of setcw and getcw */ + +void START_FAST_MATH2(unsigned short *x); +#pragma aux START_FAST_MATH2 = \ + "fstcw word ptr [esi]" \ + "or word ptr [esi], 0x3f" \ + "fldcw word ptr [esi]" \ + parm [esi] \ + modify exact []; + +void END_FAST_MATH2(unsigned short *x); +#pragma aux END_FAST_MATH2 = \ + "fldcw word ptr [esi]" \ + parm [esi] \ + modify exact []; + +#define START_FAST_MATH(x) START_FAST_MATH2(& x) +#define END_FAST_MATH(x) END_FAST_MATH2(& x) + +/* +__inline START_FAST_MATH(unsigned short x) + { + _asm { + fstcw ax + mov x , ax + or ax, 0x3f + fldcw ax + } + } + +__inline END_FAST_MATH(unsigned short x) + { + _asm { + fldcw x + } + } +*/ +#define HAVE_FAST_MATH + +#else +#define START_FAST_MATH(x) (void)(x) +#define END_FAST_MATH(x) (void)(x) + +/* The mac float really is a float, with the same precision as a + * single precision 387 float. + */ +#if defined(macintosh) +#define HAVE_FAST_MATH +#endif + +#endif + + + +/* + * Square root + */ + +extern float gl_sqrt(float x); + +#ifdef FAST_MATH +#if defined(__WATCOMC__) && defined(USE_X86_ASM) +# define GL_SQRT(X) asm_sqrt(X) +#else +# define GL_SQRT(X) gl_sqrt(X) +#endif +#else +# define GL_SQRT(X) sqrt(X) +#endif + + +/* + * Normalize a 3-element vector to unit length. + */ +#define NORMALIZE_3FV( V ) \ +do { \ + GLdouble len = LEN_SQUARED_3FV(V); \ + if (len > 1e-50) { \ + len = 1.0 / GL_SQRT(len); \ + V[0] = (GLfloat) (V[0] * len); \ + V[1] = (GLfloat) (V[1] * len); \ + V[2] = (GLfloat) (V[2] * len); \ + } \ +} while(0) + +#define LEN_3FV( V ) (GL_SQRT(V[0]*V[0]+V[1]*V[1]+V[2]*V[2])) +#define LEN_2FV( V ) (GL_SQRT(V[0]*V[0]+V[1]*V[1])) + +#define LEN_SQUARED_3FV( V ) (V[0]*V[0]+V[1]*V[1]+V[2]*V[2]) +#define LEN_SQUARED_2FV( V ) (V[0]*V[0]+V[1]*V[1]) + + +/* + * Single precision ceiling, floor, and absolute value functions + */ +#if defined(__sparc__) /* XXX this probably isn't the ideal test */ +#define CEILF(x) ceil(x) +#define FLOORF(x) floor(x) +#define FABSF(x) fabs(x) +#else +#define CEILF(x) ceilf(x) +#define FLOORF(x) floorf(x) +#define FABSF(x) fabsf(x) +#endif + + +#if defined(__i386__) || defined(__sparc__) || ( defined(__alpha__) && \ + ( defined( __IEEE_FLOAT ) || !defined( VMS ) ) ) +#define USE_IEEE +#endif + + + +#define GET_FLOAT_BITS(x) ((fi_type *) &(x))->i + +/* + * Float -> Int conversions (rounding, floor, ceiling) + */ + +#if defined(USE_SPARC_ASM) && defined(__GNUC__) && defined(__sparc__) + +static INLINE int iround(float f) +{ + int r; + __asm__ ("fstoi %1, %0" : "=f" (r) : "f" (f)); + return r; +} + +#define IROUND(x) iround(x) + +#elif defined(USE_X86_ASM) && defined(__GNUC__) && defined(__i386__) + + +static INLINE int iround(float f) +{ + int r; + __asm__ ("fistpl %0" : "=m" (r) : "t" (f) : "st"); + return r; +} + +#define IROUND(x) iround(x) + +/* + * IEEE floor for computers that round to nearest or even. + * 'f' must be between -4194304 and 4194303. + * This floor operation is done by "(iround(f + .5) + iround(f - .5)) >> 1", + * but uses some IEEE specific tricks for better speed. + * Contributed by Josh Vanderhoof + */ +static INLINE int ifloor(float f) +{ + int ai, bi; + double af, bf; + af = (3 << 22) + 0.5 + (double)f; + bf = (3 << 22) + 0.5 - (double)f; + /* GCC generates an extra fstp/fld without this. */ + __asm__ ("fstps %0" : "=m" (ai) : "t" (af) : "st"); + __asm__ ("fstps %0" : "=m" (bi) : "t" (bf) : "st"); + return (ai - bi) >> 1; +} + +#define IFLOOR(x) ifloor(x) + +/* + * IEEE ceil for computers that round to nearest or even. + * 'f' must be between -4194304 and 4194303. + * This ceil operation is done by "(iround(f + .5) + iround(f - .5) + 1) >> 1", + * but uses some IEEE specific tricks for better speed. + * Contributed by Josh Vanderhoof + */ +static INLINE int iceil(float f) +{ + int ai, bi; + double af, bf; + af = (3 << 22) + 0.5 + (double)f; + bf = (3 << 22) + 0.5 - (double)f; + /* GCC generates an extra fstp/fld without this. */ + __asm__ ("fstps %0" : "=m" (ai) : "t" (af) : "st"); + __asm__ ("fstps %0" : "=m" (bi) : "t" (bf) : "st"); + return (ai - bi + 1) >> 1; +} + +#define ICEIL(x) iceil(x) + + +#elif defined(USE_X86_ASM) && defined(__MSC__) && defined(__WIN32__) + + +static INLINE int iround(float f) +{ + int r; + _asm { + fld f + fistp r + } + return r; +} + +#define IROUND(x) iround(x) + + +#elif defined(USE_X86_ASM) && defined(__WATCOMC__) + + +long iround(float f); +#pragma aux iround = \ + "push eax" \ + "fistp dword ptr [esp]" \ + "pop eax" \ + parm [8087] \ + value [eax] \ + modify exact [eax]; + +#define IROUND(x) iround(x) + +float asm_sqrt (float x); +#pragma aux asm_sqrt = \ + "fsqrt" \ + parm [8087] \ + value [8087] \ + modify exact []; + + +#endif /* assembly/optimized IROUND, IROUND_POS, IFLOOR, ICEIL macros */ + + +/* default IROUND macro */ +#ifndef IROUND +#define IROUND(f) ((int) (((f) >= 0.0F) ? ((f) + 0.5F) : ((f) - 0.5F))) +#endif + + +/* default IROUND_POS macro */ +#ifndef IROUND_POS +#ifdef DEBUG +#define IROUND_POS(f) (ASSERT((f) >= 0.0F), IROUND(f)) +#else +#define IROUND_POS(f) (IROUND(f)) +#endif +#endif /* IROUND_POS */ + + +/* default IFLOOR macro */ +#ifndef IFLOOR +static INLINE int ifloor(float f) +{ +#ifdef USE_IEEE + int ai, bi; + double af, bf; + union { int i; float f; } u; + + af = (3 << 22) + 0.5 + (double)f; + bf = (3 << 22) + 0.5 - (double)f; + u.f = af; ai = u.i; + u.f = bf; bi = u.i; + return (ai - bi) >> 1; +#else + int i = IROUND(f); + return (i > f) ? i - 1 : i; +#endif +} +#define IFLOOR(x) ifloor(x) +#endif /* IFLOOR */ + + +/* default ICEIL macro */ +#ifndef ICEIL +static INLINE int iceil(float f) +{ +#ifdef USE_IEEE + int ai, bi; + double af, bf; + union { int i; float f; } u; + af = (3 << 22) + 0.5 + (double)f; + bf = (3 << 22) + 0.5 - (double)f; + u.f = af; ai = u.i; + u.f = bf; bi = u.i; + return (ai - bi + 1) >> 1; +#else + int i = IROUND(f); + return (i < f) ? i + 1 : i; +#endif +} +#define ICEIL(x) iceil(x) +#endif /* ICEIL */ + + + +/* + * Convert unclamped or clamped ([0,1]) floats to ubytes for color + * conversion only. These functions round to the nearest int. + */ +#define IEEE_ONE 0x3f800000 +#define IEEE_0996 0x3f7f0000 /* 0.996 or something??? used in macro + below only */ + +#if defined(USE_IEEE) && !defined(DEBUG) + +/* + * This function/macro is sensitive to precision. Test carefully + * if you change it. + */ +#define UNCLAMPED_FLOAT_TO_UBYTE(b, f) \ + do { \ + union { GLfloat r; GLuint i; } __tmp; \ + __tmp.r = f; \ + b = ((__tmp.i >= IEEE_0996) \ + ? ((GLint)__tmp.i < 0) ? (GLubyte)0 : (GLubyte)255 \ + : (__tmp.r = __tmp.r*(255.0F/256.0F) + 32768.0F, \ + (GLubyte)__tmp.i)); \ + } while (0) + +#define CLAMPED_FLOAT_TO_UBYTE(b, f) \ + UNCLAMPED_FLOAT_TO_UBYTE(b, f) + +#define COPY_FLOAT( dst, src ) \ + ((fi_type *) &(dst))->i = ((fi_type *) &(src))->i + +#else /* USE_IEEE */ + +#define UNCLAMPED_FLOAT_TO_UBYTE(b, f) \ + b = ((GLubyte) IROUND(CLAMP(f, 0.0F, 1.0F) * 255.0F)) + +#define CLAMPED_FLOAT_TO_UBYTE(b, f) \ + b = ((GLubyte) IROUND(f * 255.0F)) + +#define COPY_FLOAT( dst, src ) (dst) = (src) + +#endif /* USE_IEEE */ + + + +/* + * Integer / float conversion for colors, normals, etc. + */ + +/* Convert GLubyte in [0,255] to GLfloat in [0.0,1.0] */ +extern float _mesa_ubyte_to_float_color_tab[256]; +#define UBYTE_TO_FLOAT(u) _mesa_ubyte_to_float_color_tab[u] + +/* Convert GLfloat in [0.0,1.0] to GLubyte in [0,255] */ +#define FLOAT_TO_UBYTE(X) ((GLubyte) (GLint) (((X)) * 255.0F)) + + +/* Convert GLbyte in [-128,127] to GLfloat in [-1.0,1.0] */ +#define BYTE_TO_FLOAT(B) ((2.0F * (B) + 1.0F) * (1.0F/255.0F)) + +/* Convert GLfloat in [-1.0,1.0] to GLbyte in [-128,127] */ +#define FLOAT_TO_BYTE(X) ( (((GLint) (255.0F * (X))) - 1) / 2 ) + + +/* Convert GLushort in [0,65536] to GLfloat in [0.0,1.0] */ +#define USHORT_TO_FLOAT(S) ((GLfloat) (S) * (1.0F / 65535.0F)) + +/* Convert GLfloat in [0.0,1.0] to GLushort in [0,65536] */ +#define FLOAT_TO_USHORT(X) ((GLushort) (GLint) ((X) * 65535.0F)) + + +/* Convert GLshort in [-32768,32767] to GLfloat in [-1.0,1.0] */ +#define SHORT_TO_FLOAT(S) ((2.0F * (S) + 1.0F) * (1.0F/65535.0F)) + +/* Convert GLfloat in [0.0,1.0] to GLshort in [-32768,32767] */ +#define FLOAT_TO_SHORT(X) ( (((GLint) (65535.0F * (X))) - 1) / 2 ) + + +/* Convert GLuint in [0,4294967295] to GLfloat in [0.0,1.0] */ +#define UINT_TO_FLOAT(U) ((GLfloat) (U) * (1.0F / 4294967295.0F)) + +/* Convert GLfloat in [0.0,1.0] to GLuint in [0,4294967295] */ +#define FLOAT_TO_UINT(X) ((GLuint) ((X) * 4294967295.0)) + + +/* Convert GLint in [-2147483648,2147483647] to GLfloat in [-1.0,1.0] */ +#define INT_TO_FLOAT(I) ((2.0F * (I) + 1.0F) * (1.0F/4294967294.0F)) + +/* Convert GLfloat in [-1.0,1.0] to GLint in [-2147483648,2147483647] */ +/* causes overflow: +#define FLOAT_TO_INT(X) ( (((GLint) (4294967294.0F * (X))) - 1) / 2 ) +*/ +/* a close approximation: */ +#define FLOAT_TO_INT(X) ( (GLint) (2147483647.0 * (X)) ) + + +#define BYTE_TO_UBYTE(b) ((b) < 0 ? 0 : (GLubyte) (b)) +#define SHORT_TO_UBYTE(s) ((s) < 0 ? 0 : (GLubyte) ((s) >> 7)) +#define USHORT_TO_UBYTE(s) (GLubyte) ((s) >> 8) +#define INT_TO_UBYTE(i) ((i) < 0 ? 0 : (GLubyte) ((i) >> 23)) +#define UINT_TO_UBYTE(i) (GLubyte) ((i) >> 24) + + +#define BYTE_TO_USHORT(b) ((b) < 0 ? 0 : ((GLushort) (((b) * 65535) / 255))) +#define UBYTE_TO_USHORT(b) (((GLushort) (b) << 8) | (GLushort) (b)) +#define SHORT_TO_USHORT(s) ((s) < 0 ? 0 : ((GLushort) (((s) * 65535 / 32767)))) +#define INT_TO_USHORT(i) ((i) < 0 ? 0 : ((GLushort) ((i) >> 15))) +#define UINT_TO_USHORT(i) ((i) < 0 ? 0 : ((GLushort) ((i) >> 16))) +#define UNCLAMPED_FLOAT_TO_USHORT(us, f) us = (GLushort) (f * 65535.0F) + + + +/* + * Linear interpolation + */ +#define LINTERP(T, OUT, IN) ((OUT) + (T) * ((IN) - (OUT))) + +/* Can do better with integer math: + */ +#define INTERP_UB( t, dstub, outub, inub ) \ +do { \ + GLfloat inf = UBYTE_TO_FLOAT( inub ); \ + GLfloat outf = UBYTE_TO_FLOAT( outub ); \ + GLfloat dstf = LINTERP( t, outf, inf ); \ + UNCLAMPED_FLOAT_TO_UBYTE( dstub, dstf ); \ +} while (0) + +#define INTERP_CHAN( t, dstc, outc, inc ) \ +do { \ + GLfloat inf = CHAN_TO_FLOAT( inc ); \ + GLfloat outf = CHAN_TO_FLOAT( outc ); \ + GLfloat dstf = LINTERP( t, outf, inf ); \ + UNCLAMPED_FLOAT_TO_CHAN( dstc, dstf ); \ +} while (0) + +#define INTERP_UI( t, dstui, outui, inui ) \ + dstui = (GLuint) (GLint) LINTERP( t, (GLfloat) outui, (GLfloat) inui ) + +#define INTERP_F( t, dstf, outf, inf ) \ + dstf = LINTERP( t, outf, inf ) + +#define INTERP_4F( t, dst, out, in ) \ +do { \ + dst[0] = LINTERP( t, out[0], in[0] ); \ + dst[1] = LINTERP( t, out[1], in[1] ); \ + dst[2] = LINTERP( t, out[2], in[2] ); \ + dst[3] = LINTERP( t, out[3], in[3] ); \ +} while (0) + +#define INTERP_3F( t, dst, out, in ) \ +do { \ + dst[0] = LINTERP( t, out[0], in[0] ); \ + dst[1] = LINTERP( t, out[1], in[1] ); \ + dst[2] = LINTERP( t, out[2], in[2] ); \ +} while (0) + +#define INTERP_SZ( t, vec, to, out, in, sz ) \ +do { \ + switch (sz) { \ + case 4: vec[to][3] = LINTERP( t, vec[out][3], vec[in][3] ); \ + case 3: vec[to][2] = LINTERP( t, vec[out][2], vec[in][2] ); \ + case 2: vec[to][1] = LINTERP( t, vec[out][1], vec[in][1] ); \ + case 1: vec[to][0] = LINTERP( t, vec[out][0], vec[in][0] ); \ + } \ +} while(0) + + +/* + * Fixed point arithmetic macros + */ +#define FIXED_ONE 0x00000800 +#define FIXED_HALF 0x00000400 +#define FIXED_FRAC_MASK 0x000007FF +#define FIXED_INT_MASK (~FIXED_FRAC_MASK) +#define FIXED_EPSILON 1 +#define FIXED_SCALE 2048.0f +#define FIXED_SHIFT 11 +#define FloatToFixed(X) (IROUND((X) * FIXED_SCALE)) +#define IntToFixed(I) ((I) << FIXED_SHIFT) +#define FixedToInt(X) ((X) >> FIXED_SHIFT) +#define FixedToUns(X) (((unsigned int)(X)) >> FIXED_SHIFT) +#define FixedCeil(X) (((X) + FIXED_ONE - FIXED_EPSILON) & FIXED_INT_MASK) +#define FixedFloor(X) ((X) & FIXED_INT_MASK) +#define FixedToFloat(X) ((X) * (1.0F / FIXED_SCALE)) +#define PosFloatToFixed(X) FloatToFixed(X) +#define SignedFloatToFixed(X) FloatToFixed(X) + + + +extern void +_mesa_init_math(void); + + +extern GLuint +_mesa_bitcount(GLuint n); + + +#endif Index: dll/opengl/opengl32/mesa/mtypes.h =================================================================== --- dll/opengl/opengl32/mesa/mtypes.h (revision 0) +++ dll/opengl/opengl32/mesa/mtypes.h (working copy) @@ -0,0 +1,1686 @@ +/* $Id: mtypes.h,v 1.46 2001/06/13 14:56:14 brianp Exp $ */ + +/* + * Mesa 3-D graphics library + * Version: 3.5 + * + * Copyright (C) 1999-2001 Brian Paul 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 + * BRIAN PAUL 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. + */ + + +#ifndef TYPES_H +#define TYPES_H + + +#include "glheader.h" +#include "config.h" /* Hardwired parameters */ +#include "glapitable.h" +#include "glthread.h" + +#include "math/m_matrix.h" /* GLmatrix */ + +#if defined(MESA_TRACE) +#include "Trace/tr_context.h" +#endif + + +/* Please try to mark derived values with a leading underscore ('_'). + */ + +/* + * Color channel data type: + */ +#if CHAN_BITS == 8 + typedef GLubyte GLchan; +#define CHAN_MAX 255 +#define CHAN_MAXF 255.0F +#define CHAN_TYPE GL_UNSIGNED_BYTE +#elif CHAN_BITS == 16 + typedef GLushort GLchan; +#define CHAN_MAX 65535 +#define CHAN_MAXF 65535.0F +#define CHAN_TYPE GL_UNSIGNED_SHORT +#elif CHAN_BITS == 32 + typedef GLfloat GLchan; +#define CHAN_MAX 1.0 +#define CHAN_MAXF 1.0F +#define CHAN_TYPE GL_FLOAT +#else +#error illegal number of color channel bits +#endif + + +/* + * Accumulation buffer data type: + */ +#if ACCUM_BITS==8 + typedef GLbyte GLaccum; +#elif ACCUM_BITS==16 + typedef GLshort GLaccum; +#else +# error "illegal number of accumulation bits" +#endif + + +/* + * Stencil buffer data type: + */ +#if STENCIL_BITS==8 + typedef GLubyte GLstencil; +# define STENCIL_MAX 0xff +#elif STENCIL_BITS==16 + typedef GLushort GLstencil; +# define STENCIL_MAX 0xffff +#else +# error "illegal number of stencil bits" +#endif + + +/* + * Depth buffer data type: + */ +typedef GLuint GLdepth; /* Must be 32-bits! */ + + +/* + * Fixed point data type: + */ +typedef int GLfixed; + + + +/* + * Some forward type declarations + */ +struct _mesa_HashTable; +struct gl_texture_image; +struct gl_texture_object; +typedef struct __GLcontextRec GLcontext; +typedef struct __GLcontextModesRec GLvisual; +typedef struct gl_frame_buffer GLframebuffer; + + + +/* Maximum number of temporary vertices required for clipping. (Used + * in array_cache and tnl modules). + */ +#define MAX_CLIPPED_VERTICES ((2 * (6 + MAX_CLIP_PLANES))+1) + + +/* Data structure for color tables */ +struct gl_color_table { + GLenum Format; /* GL_ALPHA, GL_RGB, GL_RGB, etc */ + GLenum IntFormat; + GLuint Size; /* number of entries (rows) in table */ + GLvoid *Table; /* either GLfloat * or GLchan * */ + GLboolean FloatTable; /* are entries stored as floats? */ + GLubyte RedSize; + GLubyte GreenSize; + GLubyte BlueSize; + GLubyte AlphaSize; + GLubyte LuminanceSize; + GLubyte IntensitySize; +}; + + +/* + * Bit flags used for updating material values. + */ +#define FRONT_AMBIENT_BIT 0x1 +#define BACK_AMBIENT_BIT 0x2 +#define FRONT_DIFFUSE_BIT 0x4 +#define BACK_DIFFUSE_BIT 0x8 +#define FRONT_SPECULAR_BIT 0x10 +#define BACK_SPECULAR_BIT 0x20 +#define FRONT_EMISSION_BIT 0x40 +#define BACK_EMISSION_BIT 0x80 +#define FRONT_SHININESS_BIT 0x100 +#define BACK_SHININESS_BIT 0x200 +#define FRONT_INDEXES_BIT 0x400 +#define BACK_INDEXES_BIT 0x800 + +#define FRONT_MATERIAL_BITS (FRONT_EMISSION_BIT | FRONT_AMBIENT_BIT | \ + FRONT_DIFFUSE_BIT | FRONT_SPECULAR_BIT | \ + FRONT_SHININESS_BIT | FRONT_INDEXES_BIT) + +#define BACK_MATERIAL_BITS (BACK_EMISSION_BIT | BACK_AMBIENT_BIT | \ + BACK_DIFFUSE_BIT | BACK_SPECULAR_BIT | \ + BACK_SHININESS_BIT | BACK_INDEXES_BIT) + +#define ALL_MATERIAL_BITS (FRONT_MATERIAL_BITS | BACK_MATERIAL_BITS) + + + +/* + * Specular exponent and material shininess lookup table sizes: + */ +#define EXP_TABLE_SIZE 512 +#define SHINE_TABLE_SIZE 256 + +struct gl_shine_tab { + struct gl_shine_tab *next, *prev; + GLfloat tab[SHINE_TABLE_SIZE+1]; + GLfloat shininess; + GLuint refcount; +}; + + +struct gl_light { + struct gl_light *next; /* double linked list with sentinel */ + struct gl_light *prev; + + GLfloat Ambient[4]; /* ambient color */ + GLfloat Diffuse[4]; /* diffuse color */ + GLfloat Specular[4]; /* specular color */ + GLfloat EyePosition[4]; /* position in eye coordinates */ + GLfloat EyeDirection[4]; /* spotlight dir in eye coordinates */ + GLfloat SpotExponent; + GLfloat SpotCutoff; /* in degress */ + GLfloat _CosCutoff; /* = MAX(0, cos(SpotCutoff)) */ + GLfloat ConstantAttenuation; + GLfloat LinearAttenuation; + GLfloat QuadraticAttenuation; + GLboolean Enabled; /* On/off flag */ + + /* Derived fields */ + GLuint _Flags; /* State */ + + GLfloat _Position[4]; /* position in eye/obj coordinates */ + GLfloat _VP_inf_norm[3]; /* Norm direction to infinite light */ + GLfloat _h_inf_norm[3]; /* Norm( _VP_inf_norm + <0,0,1> ) */ + GLfloat _NormDirection[4]; /* normalized spotlight direction */ + GLfloat _VP_inf_spot_attenuation; + + GLfloat _SpotExpTable[EXP_TABLE_SIZE][2]; /* to replace a pow() call */ + GLfloat _MatAmbient[2][3]; /* material ambient * light ambient */ + GLfloat _MatDiffuse[2][3]; /* material diffuse * light diffuse */ + GLfloat _MatSpecular[2][3]; /* material spec * light specular */ + GLfloat _dli; /* CI diffuse light intensity */ + GLfloat _sli; /* CI specular light intensity */ +}; + + +struct gl_lightmodel { + GLfloat Ambient[4]; /* ambient color */ + GLboolean LocalViewer; /* Local (or infinite) view point? */ + GLboolean TwoSide; /* Two (or one) sided lighting? */ + GLenum ColorControl; /* either GL_SINGLE_COLOR */ + /* or GL_SEPARATE_SPECULAR_COLOR */ +}; + + +struct gl_material +{ + GLfloat Ambient[4]; + GLfloat Diffuse[4]; + GLfloat Specular[4]; + GLfloat Emission[4]; + GLfloat Shininess; + GLfloat AmbientIndex; /* for color index lighting */ + GLfloat DiffuseIndex; /* for color index lighting */ + GLfloat SpecularIndex; /* for color index lighting */ +}; + + +/* + * Attribute structures: + * We define a struct for each attribute group to make pushing and + * popping attributes easy. Also it's a good organization. + */ +struct gl_accum_attrib { + GLfloat ClearColor[4]; /* Accumulation buffer clear color */ +}; + + +/* + * Used in DrawDestMask below + */ +#define FRONT_LEFT_BIT 1 +#define FRONT_RIGHT_BIT 2 +#define BACK_LEFT_BIT 4 +#define BACK_RIGHT_BIT 8 + + +struct gl_colorbuffer_attrib { + GLuint ClearIndex; /* Index to use for glClear */ + GLchan ClearColor[4]; /* Color to use for glClear */ + + GLuint IndexMask; /* Color index write mask */ + GLubyte ColorMask[4]; /* Each flag is 0xff or 0x0 */ + + GLenum DrawBuffer; /* Which buffer to draw into */ + GLenum DriverDrawBuffer; /* Current device driver dest buffer */ + GLboolean MultiDrawBuffer; /* Drawing to mutliple buffers? */ + GLubyte DrawDestMask; /* bitwise-OR of bitflags above */ + + /* alpha testing */ + GLboolean AlphaEnabled; /* Alpha test enabled flag */ + GLenum AlphaFunc; /* Alpha test function */ + GLchan AlphaRef; /* Alpha ref value as GLchan */ + + /* blending */ + GLboolean BlendEnabled; /* Blending enabled flag */ + GLenum BlendSrcRGB; /* Blending source operator */ + GLenum BlendDstRGB; /* Blending destination operator */ + GLenum BlendSrcA; /* GL_INGR_blend_func_separate */ + GLenum BlendDstA; /* GL_INGR_blend_func_separate */ + GLenum BlendEquation; + GLfloat BlendColor[4]; + + /* logic op */ + GLenum LogicOp; /* Logic operator */ + GLboolean IndexLogicOpEnabled; /* Color index logic op enabled flag */ + GLboolean ColorLogicOpEnabled; /* RGBA logic op enabled flag */ + + GLboolean DitherFlag; /* Dither enable flag */ +}; + + +struct gl_current_attrib { + /* These values valid only when FLUSH_VERTICES has been called. + */ + GLfloat Normal[3]; /* Current vertex normal */ + GLfloat Color[4]; /* Current RGBA color */ + GLfloat SecondaryColor[4]; /* Current secondary color */ + GLfloat FogCoord; /* Current Fog coord */ + GLuint Index; /* Current color index */ + GLboolean EdgeFlag; /* Current edge flag */ + GLfloat Texcoord[MAX_TEXTURE_UNITS][4]; /* Current texture coords */ + + /* These values are always valid. + */ + GLfloat RasterPos[4]; /* Current raster position */ + GLfloat RasterDistance; /* Current raster distance */ + GLfloat RasterColor[4]; /* Current raster color */ + GLuint RasterIndex; /* Current raster index */ + GLfloat *RasterTexCoord; /* Current raster texcoord*/ + GLfloat RasterMultiTexCoord[MAX_TEXTURE_UNITS][4]; + GLfloat RasterFogCoord; + GLboolean RasterPosValid; /* Raster po valid flag */ +}; + + +struct gl_depthbuffer_attrib { + GLenum Func; /* Function for depth buffer compare */ + GLfloat Clear; /* Value to clear depth buffer to */ + GLboolean Test; /* Depth buffering enabled flag */ + GLboolean Mask; /* Depth buffer writable? */ + GLboolean OcclusionTest; /* GL_HP_occlusion_test */ +}; + + +struct gl_enable_attrib { + GLboolean AlphaTest; + GLboolean AutoNormal; + GLboolean Blend; + GLboolean ClipPlane[MAX_CLIP_PLANES]; + GLboolean ColorMaterial; + GLboolean Convolution1D; + GLboolean Convolution2D; + GLboolean Separable2D; + GLboolean CullFace; + GLboolean DepthTest; + GLboolean Dither; + GLboolean Fog; + GLboolean Histogram; + GLboolean Light[MAX_LIGHTS]; + GLboolean Lighting; + GLboolean LineSmooth; + GLboolean LineStipple; + GLboolean IndexLogicOp; + GLboolean ColorLogicOp; + GLboolean Map1Color4; + GLboolean Map1Index; + GLboolean Map1Normal; + GLboolean Map1TextureCoord1; + GLboolean Map1TextureCoord2; + GLboolean Map1TextureCoord3; + GLboolean Map1TextureCoord4; + GLboolean Map1Vertex3; + GLboolean Map1Vertex4; + GLboolean Map2Color4; + GLboolean Map2Index; + GLboolean Map2Normal; + GLboolean Map2TextureCoord1; + GLboolean Map2TextureCoord2; + GLboolean Map2TextureCoord3; + GLboolean Map2TextureCoord4; + GLboolean Map2Vertex3; + GLboolean Map2Vertex4; + GLboolean MinMax; + GLboolean Normalize; + GLboolean PixelTexture; + GLboolean PointSmooth; + GLboolean PolygonOffsetPoint; + GLboolean PolygonOffsetLine; + GLboolean PolygonOffsetFill; + GLboolean PolygonSmooth; + GLboolean PolygonStipple; + GLboolean RescaleNormals; + GLboolean Scissor; + GLboolean Stencil; + GLboolean MultisampleEnabled; /* GL_ARB_multisample */ + GLboolean SampleAlphaToCoverage; /* GL_ARB_multisample */ + GLboolean SampleAlphaToOne; /* GL_ARB_multisample */ + GLboolean SampleCoverage; /* GL_ARB_multisample */ + GLboolean SampleCoverageInvert; /* GL_ARB_multisample */ + GLuint Texture[MAX_TEXTURE_UNITS]; + GLuint TexGen[MAX_TEXTURE_UNITS]; +}; + + +struct gl_eval_attrib { + /* Enable bits */ + GLboolean Map1Color4; + GLboolean Map1Index; + GLboolean Map1Normal; + GLboolean Map1TextureCoord1; + GLboolean Map1TextureCoord2; + GLboolean Map1TextureCoord3; + GLboolean Map1TextureCoord4; + GLboolean Map1Vertex3; + GLboolean Map1Vertex4; + GLboolean Map2Color4; + GLboolean Map2Index; + GLboolean Map2Normal; + GLboolean Map2TextureCoord1; + GLboolean Map2TextureCoord2; + GLboolean Map2TextureCoord3; + GLboolean Map2TextureCoord4; + GLboolean Map2Vertex3; + GLboolean Map2Vertex4; + GLboolean AutoNormal; + /* Map Grid endpoints and divisions and calculated du values */ + GLint MapGrid1un; + GLfloat MapGrid1u1, MapGrid1u2, MapGrid1du; + GLint MapGrid2un, MapGrid2vn; + GLfloat MapGrid2u1, MapGrid2u2, MapGrid2du; + GLfloat MapGrid2v1, MapGrid2v2, MapGrid2dv; +}; + + +struct gl_fog_attrib { + GLboolean Enabled; /* Fog enabled flag */ + GLfloat Color[4]; /* Fog color */ + GLfloat Density; /* Density >= 0.0 */ + GLfloat Start; /* Start distance in eye coords */ + GLfloat End; /* End distance in eye coords */ + GLfloat Index; /* Fog index */ + GLenum Mode; /* Fog mode */ + GLboolean ColorSumEnabled; + GLenum FogCoordinateSource; /* GL_EXT_fog_coord */ +}; + + +struct gl_hint_attrib { + /* always one of GL_FASTEST, GL_NICEST, or GL_DONT_CARE */ + GLenum PerspectiveCorrection; + GLenum PointSmooth; + GLenum LineSmooth; + GLenum PolygonSmooth; + GLenum Fog; + GLenum ClipVolumeClipping; /* GL_EXT_clip_volume_hint */ + GLenum TextureCompression; /* GL_ARB_texture_compression */ + GLenum GenerateMipmap; /* GL_SGIS_generate_mipmap */ +}; + + +struct gl_histogram_attrib { + GLuint Width; /* number of table entries */ + GLint Format; /* GL_ALPHA, GL_RGB, etc */ + GLuint Count[HISTOGRAM_TABLE_SIZE][4]; /* the histogram */ + GLboolean Sink; /* terminate image transfer? */ + GLubyte RedSize; /* Bits per counter */ + GLubyte GreenSize; + GLubyte BlueSize; + GLubyte AlphaSize; + GLubyte LuminanceSize; +}; + + +struct gl_minmax_attrib { + GLenum Format; + GLboolean Sink; + GLfloat Min[4], Max[4]; /* RGBA */ +}; + + +struct gl_convolution_attrib { + GLenum Format; + GLenum InternalFormat; + GLuint Width; + GLuint Height; + GLfloat Filter[MAX_CONVOLUTION_WIDTH * MAX_CONVOLUTION_HEIGHT * 4]; +}; + + +struct gl_light_attrib { + struct gl_light Light[MAX_LIGHTS]; /* Array of lights */ + struct gl_lightmodel Model; /* Lighting model */ + + /* Must flush FLUSH_VERTICES before referencing: + */ + struct gl_material Material[2]; /* Material 0=front, 1=back */ + + GLboolean Enabled; /* Lighting enabled flag */ + GLenum ShadeModel; /* GL_FLAT or GL_SMOOTH */ + GLenum ColorMaterialFace; /* GL_FRONT, BACK or FRONT_AND_BACK */ + GLenum ColorMaterialMode; /* GL_AMBIENT, GL_DIFFUSE, etc */ + GLuint ColorMaterialBitmask; /* bitmask formed from Face and Mode */ + GLboolean ColorMaterialEnabled; + + struct gl_light EnabledList; /* List sentinel */ + + /* Derived for optimizations: */ + GLboolean _NeedVertices; /* Use fast shader? */ + GLuint _Flags; /* LIGHT_* flags, see below */ + GLfloat _BaseColor[2][3]; + GLfloat _BaseAlpha[2]; +}; + + +#define LIGHT_SPOT 0x1 +#define LIGHT_LOCAL_VIEWER 0x2 +#define LIGHT_POSITIONAL 0x4 + +#define LIGHT_NEED_VERTICES (LIGHT_POSITIONAL|LIGHT_LOCAL_VIEWER) + +struct gl_line_attrib { + GLboolean SmoothFlag; /* GL_LINE_SMOOTH enabled? */ + GLboolean StippleFlag; /* GL_LINE_STIPPLE enabled? */ + GLushort StipplePattern; /* Stipple pattern */ + GLint StippleFactor; /* Stipple repeat factor */ + GLfloat Width; /* Line width */ + GLfloat _Width; /* Clamped Line width */ +}; + + +struct gl_list_attrib { + GLuint ListBase; +}; + +struct gl_list_opcode { + GLuint size; + void (*execute)( GLcontext *ctx, void *data ); + void (*destroy)( GLcontext *ctx, void *data ); + void (*print)( GLcontext *ctx, void *data ); +}; + +#define GL_MAX_EXT_OPCODES 16 + +struct gl_list_extensions { + struct gl_list_opcode opcode[GL_MAX_EXT_OPCODES]; + GLuint nr_opcodes; +}; + + +struct gl_multisample_attrib { + GLboolean Enabled; + GLboolean SampleAlphaToCoverage; + GLboolean SampleAlphaToOne; + GLboolean SampleCoverage; + GLfloat SampleCoverageValue; + GLboolean SampleCoverageInvert; +}; + + +struct gl_pixel_attrib { + GLenum ReadBuffer; /* src buffer for glRead/CopyPixels */ + GLenum DriverReadBuffer; /* Driver's current source buffer */ + GLfloat RedBias, RedScale; + GLfloat GreenBias, GreenScale; + GLfloat BlueBias, BlueScale; + GLfloat AlphaBias, AlphaScale; + GLfloat DepthBias, DepthScale; + GLint IndexShift, IndexOffset; + GLboolean MapColorFlag; + GLboolean MapStencilFlag; + GLfloat ZoomX, ZoomY; + GLint MapStoSsize; /* Size of each pixel map */ + GLint MapItoIsize; + GLint MapItoRsize; + GLint MapItoGsize; + GLint MapItoBsize; + GLint MapItoAsize; + GLint MapRtoRsize; + GLint MapGtoGsize; + GLint MapBtoBsize; + GLint MapAtoAsize; + GLint MapStoS[MAX_PIXEL_MAP_TABLE]; /* Pixel map tables */ + GLint MapItoI[MAX_PIXEL_MAP_TABLE]; + GLfloat MapItoR[MAX_PIXEL_MAP_TABLE]; + GLfloat MapItoG[MAX_PIXEL_MAP_TABLE]; + GLfloat MapItoB[MAX_PIXEL_MAP_TABLE]; + GLfloat MapItoA[MAX_PIXEL_MAP_TABLE]; + GLubyte MapItoR8[MAX_PIXEL_MAP_TABLE]; /* converted to 8-bit color */ + GLubyte MapItoG8[MAX_PIXEL_MAP_TABLE]; + GLubyte MapItoB8[MAX_PIXEL_MAP_TABLE]; + GLubyte MapItoA8[MAX_PIXEL_MAP_TABLE]; + GLfloat MapRtoR[MAX_PIXEL_MAP_TABLE]; + GLfloat MapGtoG[MAX_PIXEL_MAP_TABLE]; + GLfloat MapBtoB[MAX_PIXEL_MAP_TABLE]; + GLfloat MapAtoA[MAX_PIXEL_MAP_TABLE]; + /* GL_EXT_histogram */ + GLboolean HistogramEnabled; + GLboolean MinMaxEnabled; + /* GL_SGIS_pixel_texture */ + GLboolean PixelTextureEnabled; + GLenum FragmentRgbSource; + GLenum FragmentAlphaSource; + /* GL_SGI_color_matrix */ + GLfloat PostColorMatrixScale[4]; /* RGBA */ + GLfloat PostColorMatrixBias[4]; /* RGBA */ + /* GL_SGI_color_table */ + GLfloat ColorTableScale[4]; + GLfloat ColorTableBias[4]; + GLboolean ColorTableEnabled; + GLfloat PCCTscale[4]; + GLfloat PCCTbias[4]; + GLboolean PostConvolutionColorTableEnabled; + GLfloat PCMCTscale[4]; + GLfloat PCMCTbias[4]; + GLboolean PostColorMatrixColorTableEnabled; + /* Convolution */ + GLboolean Convolution1DEnabled; + GLboolean Convolution2DEnabled; + GLboolean Separable2DEnabled; + GLfloat ConvolutionBorderColor[3][4]; + GLenum ConvolutionBorderMode[3]; + GLfloat ConvolutionFilterScale[3][4]; + GLfloat ConvolutionFilterBias[3][4]; + GLfloat PostConvolutionScale[4]; /* RGBA */ + GLfloat PostConvolutionBias[4]; /* RGBA */ +}; + + +struct gl_point_attrib { + GLboolean SmoothFlag; /* True if GL_POINT_SMOOTH is enabled */ + GLfloat Size; /* User-specified point size */ + GLfloat _Size; /* Size clamped to Const.Min/MaxPointSize */ + GLfloat Params[3]; /* GL_EXT_point_parameters */ + GLfloat MinSize, MaxSize; /* GL_EXT_point_parameters */ + GLfloat Threshold; /* GL_EXT_point_parameters */ + GLboolean _Attenuated; /* True if Params != [1, 0, 0] */ +}; + + +struct gl_polygon_attrib { + GLenum FrontFace; /* Either GL_CW or GL_CCW */ + GLenum FrontMode; /* Either GL_POINT, GL_LINE or GL_FILL */ + GLenum BackMode; /* Either GL_POINT, GL_LINE or GL_FILL */ + GLboolean _FrontBit; /* */ + GLboolean CullFlag; /* Culling on/off flag */ + GLboolean SmoothFlag; /* True if GL_POLYGON_SMOOTH is enabled */ + GLboolean StippleFlag; /* True if GL_POLYGON_STIPPLE is enabled */ + GLenum CullFaceMode; /* Culling mode GL_FRONT or GL_BACK */ + GLfloat OffsetFactor; /* Polygon offset factor, from user */ + GLfloat OffsetUnits; /* Polygon offset units, from user */ + GLfloat OffsetMRD; /* = OffsetUnits * visual->MRD */ + GLboolean OffsetPoint; /* Offset in GL_POINT mode */ + GLboolean OffsetLine; /* Offset in GL_LINE mode */ + GLboolean OffsetFill; /* Offset in GL_FILL mode */ + GLboolean _OffsetAny; +}; + + +struct gl_scissor_attrib { + GLboolean Enabled; /* Scissor test enabled? */ + GLint X, Y; /* Lower left corner of box */ + GLsizei Width, Height; /* Size of box */ +}; + + +struct gl_stencil_attrib { + GLboolean Enabled; /* Enabled flag */ + GLenum Function; /* Stencil function */ + GLenum FailFunc; /* Fail function */ + GLenum ZPassFunc; /* Depth buffer pass function */ + GLenum ZFailFunc; /* Depth buffer fail function */ + GLstencil Ref; /* Reference value */ + GLstencil ValueMask; /* Value mask */ + GLstencil Clear; /* Clear value */ + GLstencil WriteMask; /* Write mask */ +}; + + +/* TexGenEnabled flags */ +#define S_BIT 1 +#define T_BIT 2 +#define R_BIT 4 +#define Q_BIT 8 + +/* Texture Enabled flags */ +#define TEXTURE0_1D 0x1 /* Texture unit 0 (default) */ +#define TEXTURE0_2D 0x2 +#define TEXTURE0_3D 0x4 +#define TEXTURE0_CUBE 0x8 +#define TEXTURE0_ANY (TEXTURE0_1D | TEXTURE0_2D | TEXTURE0_3D | TEXTURE0_CUBE) +#define TEXTURE1_1D (TEXTURE0_1D << 4) /* Texture unit 1 */ +#define TEXTURE1_2D (TEXTURE0_2D << 4) +#define TEXTURE1_3D (TEXTURE0_3D << 4) +#define TEXTURE1_CUBE (TEXTURE0_CUBE << 4) +#define TEXTURE1_ANY (TEXTURE1_1D | TEXTURE1_2D | TEXTURE1_3D | TEXTURE1_CUBE) +#define TEXTURE2_1D (TEXTURE0_1D << 8) /* Texture unit 2 */ +#define TEXTURE2_2D (TEXTURE0_2D << 8) +#define TEXTURE2_3D (TEXTURE0_3D << 8) +#define TEXTURE2_CUBE (TEXTURE0_CUBE << 8) +#define TEXTURE2_ANY (TEXTURE2_1D | TEXTURE2_2D | TEXTURE2_3D | TEXTURE2_CUBE) +#define TEXTURE3_1D (TEXTURE0_1D << 12) /* Texture unit 3 */ +#define TEXTURE3_2D (TEXTURE0_2D << 12) +#define TEXTURE3_3D (TEXTURE0_3D << 12) +#define TEXTURE3_CUBE (TEXTURE0_CUBE << 12) +#define TEXTURE3_ANY (TEXTURE3_1D | TEXTURE3_2D | TEXTURE3_3D | TEXTURE3_CUBE) +#define TEXTURE4_1D (TEXTURE0_1D << 16) /* Texture unit 4 */ +#define TEXTURE4_2D (TEXTURE0_2D << 16) +#define TEXTURE4_3D (TEXTURE0_3D << 16) +#define TEXTURE4_CUBE (TEXTURE0_CUBE << 16) +#define TEXTURE5_ANY (TEXTURE3_1D | TEXTURE3_2D | TEXTURE3_3D | TEXTURE3_CUBE) +#define TEXTURE5_1D (TEXTURE0_1D << 20) /* Texture unit 5 */ +#define TEXTURE5_2D (TEXTURE0_2D << 20) +#define TEXTURE5_3D (TEXTURE0_3D << 20) +#define TEXTURE5_CUBE (TEXTURE0_CUBE << 20) +#define TEXTURE5_ANY (TEXTURE3_1D | TEXTURE3_2D | TEXTURE3_3D | TEXTURE3_CUBE) +#define TEXTURE6_1D (TEXTURE0_1D << 24) /* Texture unit 6 */ +#define TEXTURE6_2D (TEXTURE0_2D << 24) +#define TEXTURE6_3D (TEXTURE0_3D << 24) +#define TEXTURE6_CUBE (TEXTURE0_CUBE << 24) +#define TEXTURE6_ANY (TEXTURE3_1D | TEXTURE3_2D | TEXTURE3_3D | TEXTURE3_CUBE) +#define TEXTURE7_1D (TEXTURE0_1D << 28) /* Texture unit 7 */ +#define TEXTURE7_2D (TEXTURE0_2D << 28) +#define TEXTURE7_3D (TEXTURE0_3D << 28) +#define TEXTURE7_CUBE (TEXTURE0_CUBE << 28) +#define TEXTURE7_ANY (TEXTURE3_1D | TEXTURE3_2D | TEXTURE3_3D | TEXTURE3_CUBE) + +/* Bitmap versions of the GL_ constants. + */ +#define TEXGEN_SPHERE_MAP 0x1 +#define TEXGEN_OBJ_LINEAR 0x2 +#define TEXGEN_EYE_LINEAR 0x4 +#define TEXGEN_REFLECTION_MAP_NV 0x8 +#define TEXGEN_NORMAL_MAP_NV 0x10 + +#define TEXGEN_NEED_NORMALS (TEXGEN_SPHERE_MAP | \ + TEXGEN_REFLECTION_MAP_NV | \ + TEXGEN_NORMAL_MAP_NV) +#define TEXGEN_NEED_EYE_COORD (TEXGEN_SPHERE_MAP | \ + TEXGEN_REFLECTION_MAP_NV | \ + TEXGEN_NORMAL_MAP_NV | \ + TEXGEN_EYE_LINEAR) + + + +/* A selection of state flags to make driver and module's lives easier. + */ +#define ENABLE_TEXGEN0 0x1 +#define ENABLE_TEXGEN1 0x2 +#define ENABLE_TEXGEN2 0x4 +#define ENABLE_TEXGEN3 0x8 +#define ENABLE_TEXGEN4 0x10 +#define ENABLE_TEXGEN5 0x20 +#define ENABLE_TEXGEN6 0x40 +#define ENABLE_TEXGEN7 0x80 + +#define ENABLE_TEXMAT0 0x1 /* Ie. not the identity matrix */ +#define ENABLE_TEXMAT1 0x2 +#define ENABLE_TEXMAT2 0x4 +#define ENABLE_TEXMAT3 0x8 +#define ENABLE_TEXMAT4 0x10 +#define ENABLE_TEXMAT5 0x20 +#define ENABLE_TEXMAT6 0x40 +#define ENABLE_TEXMAT7 0x80 + +#define ENABLE_TEXGEN(i) (ENABLE_TEXGEN0 << (i)) +#define ENABLE_TEXMAT(i) (ENABLE_TEXMAT0 << (i)) + +/* + * If teximage is color-index, texelOut returns GLchan[1]. + * If teximage is depth, texelOut returns GLfloat[1]. + * Otherwise, texelOut returns GLchan[4]. + */ +typedef void (*FetchTexelFunc)( const struct gl_texture_image *texImage, + GLint col, GLint row, GLint img, + GLvoid *texelOut ); + +/* Texture format record */ +struct gl_texture_format { + GLint MesaFormat; /* One of the MESA_FORMAT_* values */ + + GLenum BaseFormat; /* Either GL_ALPHA, GL_INTENSITY, GL_LUMINANCE, + * GL_LUMINANCE_ALPHA, GL_RGB, GL_RGBA, + * GL_COLOR_INDEX or GL_DEPTH_COMPONENT. + */ + GLenum Type; /* Internal type as GL enum value */ + + GLubyte RedBits; /* Bits per texel component */ + GLubyte GreenBits; + GLubyte BlueBits; + GLubyte AlphaBits; + GLubyte LuminanceBits; + GLubyte IntensityBits; + GLubyte IndexBits; + GLubyte DepthBits; + + GLint TexelBytes; + + FetchTexelFunc FetchTexel1D; /* Texel fetch function pointers */ + FetchTexelFunc FetchTexel2D; + FetchTexelFunc FetchTexel3D; +}; + +/* Texture image record */ +struct gl_texture_image { + GLenum Format; /* GL_ALPHA, GL_LUMINANCE, GL_LUMINANCE_ALPHA, + * GL_INTENSITY, GL_RGB, GL_RGBA, + * GL_COLOR_INDEX or GL_DEPTH_COMPONENT only. + */ + GLint IntFormat; /* Internal format as given by the user */ + GLuint Border; /* 0 or 1 */ + GLuint Width; /* = 2^WidthLog2 + 2*Border */ + GLuint Height; /* = 2^HeightLog2 + 2*Border */ + GLuint Depth; /* = 2^DepthLog2 + 2*Border */ + GLuint Width2; /* = Width - 2*Border */ + GLuint Height2; /* = Height - 2*Border */ + GLuint Depth2; /* = Depth - 2*Border */ + GLuint WidthLog2; /* = log2(Width2) */ + GLuint HeightLog2; /* = log2(Height2) */ + GLuint DepthLog2; /* = log2(Depth2) */ + GLuint MaxLog2; /* = MAX(WidthLog2, HeightLog2) */ + GLvoid *Data; /* Image data, accessed via FetchTexel() */ + + const struct gl_texture_format *TexFormat; + + FetchTexelFunc FetchTexel; /* Texel fetch function pointer */ + + GLboolean IsCompressed; /* GL_ARB_texture_compression */ + GLuint CompressedSize; /* GL_ARB_texture_compression */ + + /* For device driver: */ + void *DriverData; /* Arbitrary device driver data */ +}; + + +/* Texture object record */ +struct gl_texture_object { + _glthread_Mutex Mutex; /* for thread safety */ + GLint RefCount; /* reference count */ + GLuint Name; /* an unsigned integer */ + GLuint Dimensions; /* 1 or 2 or 3 or 6 (cube map) */ + GLfloat Priority; /* in [0,1] */ + GLchan BorderColor[4]; + GLenum WrapS; /* Wrap modes are: GL_CLAMP, REPEAT */ + GLenum WrapT; /* GL_CLAMP_TO_EDGE, and */ + GLenum WrapR; /* GL_CLAMP_TO_BORDER_ARB */ + GLenum MinFilter; /* minification filter */ + GLenum MagFilter; /* magnification filter */ + GLfloat MinLod; /* min lambda, OpenGL 1.2 */ + GLfloat MaxLod; /* max lambda, OpenGL 1.2 */ + GLint BaseLevel; /* min mipmap level, OpenGL 1.2 */ + GLint MaxLevel; /* max mipmap level, OpenGL 1.2 */ + GLfloat MaxAnisotropy; /* GL_EXT_texture_filter_anisotropic */ + GLboolean CompareFlag; /* GL_SGIX_shadow */ + GLenum CompareOperator; /* GL_SGIX_shadow */ + GLchan ShadowAmbient; /* GL_SGIX_shadow_ambient */ + GLint _MaxLevel; /* actual max mipmap level (q in the spec) */ + GLfloat _MaxLambda; /* = _MaxLevel - BaseLevel (q - b in spec) */ + GLboolean GenerateMipmap; /* GL_SGIS_generate_mipmap */ + + struct gl_texture_image *Image[MAX_TEXTURE_LEVELS]; + + /* Texture cube faces */ + /* Image[] is alias for *PosX[MAX_TEXTURE_LEVELS]; */ + struct gl_texture_image *NegX[MAX_TEXTURE_LEVELS]; + struct gl_texture_image *PosY[MAX_TEXTURE_LEVELS]; + struct gl_texture_image *NegY[MAX_TEXTURE_LEVELS]; + struct gl_texture_image *PosZ[MAX_TEXTURE_LEVELS]; + struct gl_texture_image *NegZ[MAX_TEXTURE_LEVELS]; + + /* GL_EXT_paletted_texture */ + struct gl_color_table Palette; + + GLboolean Complete; /* Is texture object complete? */ + struct gl_texture_object *Next; /* Next in linked list */ + + /* For device driver: */ + void *DriverData; /* Arbitrary device driver data */ +}; + + + +/* + * Texture units are new with the multitexture extension. + */ +struct gl_texture_unit { + GLuint Enabled; /* bitmask of TEXTURE0_1D, _2D, _3D, _CUBE */ + GLuint _ReallyEnabled; /* 0 or one of TEXTURE0_1D, _2D, _3D, _CUBE */ + + GLenum EnvMode; /* GL_MODULATE, GL_DECAL, GL_BLEND, etc. */ + GLfloat EnvColor[4]; + GLuint TexGenEnabled; /* Bitwise-OR of [STRQ]_BIT values */ + GLenum GenModeS; /* Tex coord generation mode, either */ + GLenum GenModeT; /* GL_OBJECT_LINEAR, or */ + GLenum GenModeR; /* GL_EYE_LINEAR, or */ + GLenum GenModeQ; /* GL_SPHERE_MAP */ + GLuint _GenBitS; + GLuint _GenBitT; + GLuint _GenBitR; + GLuint _GenBitQ; + GLuint _GenFlags; /* bitwise or of GenBit[STRQ] */ + GLfloat ObjectPlaneS[4]; + GLfloat ObjectPlaneT[4]; + GLfloat ObjectPlaneR[4]; + GLfloat ObjectPlaneQ[4]; + GLfloat EyePlaneS[4]; + GLfloat EyePlaneT[4]; + GLfloat EyePlaneR[4]; + GLfloat EyePlaneQ[4]; + GLfloat LodBias; /* for biasing mipmap levels */ + + /* GL_EXT_texture_env_combine */ + GLenum CombineModeRGB; /* GL_REPLACE, GL_DECAL, GL_ADD, etc. */ + GLenum CombineModeA; /* GL_REPLACE, GL_DECAL, GL_ADD, etc. */ + GLenum CombineSourceRGB[3]; /* GL_PRIMARY_COLOR, GL_TEXTURE, etc. */ + GLenum CombineSourceA[3]; /* GL_PRIMARY_COLOR, GL_TEXTURE, etc. */ + GLenum CombineOperandRGB[3]; /* SRC_COLOR, ONE_MINUS_SRC_COLOR, etc */ + GLenum CombineOperandA[3]; /* SRC_ALPHA, ONE_MINUS_SRC_ALPHA, etc */ + GLuint CombineScaleShiftRGB; /* 0, 1 or 2 */ + GLuint CombineScaleShiftA; /* 0, 1 or 2 */ + + struct gl_texture_object *Current1D; + struct gl_texture_object *Current2D; + struct gl_texture_object *Current3D; + struct gl_texture_object *CurrentCubeMap; /* GL_ARB_texture_cube_map */ + + struct gl_texture_object *_Current; /* Points to really enabled tex obj */ + + struct gl_texture_object Saved1D; /* only used by glPush/PopAttrib */ + struct gl_texture_object Saved2D; + struct gl_texture_object Saved3D; + struct gl_texture_object SavedCubeMap; +}; + + +struct gl_texture_attrib { + /* multitexture */ + GLuint CurrentUnit; /* Active texture unit */ + + GLuint _ReallyEnabled; /* enables for all texture units: */ + /* = (Unit[0]._ReallyEnabled << 0) | */ + /* (Unit[1]._ReallyEnabled << 4) | */ + /* (Unit[2]._ReallyEnabled << 8) | etc... */ + + GLuint _GenFlags; /* for texgen */ + GLuint _TexGenEnabled; + GLuint _TexMatEnabled; + + struct gl_texture_unit Unit[MAX_TEXTURE_UNITS]; + + struct gl_texture_object *Proxy1D; + struct gl_texture_object *Proxy2D; + struct gl_texture_object *Proxy3D; + struct gl_texture_object *ProxyCubeMap; + + /* GL_EXT_shared_texture_palette */ + GLboolean SharedPalette; + struct gl_color_table Palette; +}; + + +struct gl_transform_attrib { + GLenum MatrixMode; /* Matrix mode */ + GLfloat EyeUserPlane[MAX_CLIP_PLANES][4]; + GLfloat _ClipUserPlane[MAX_CLIP_PLANES][4]; /* derived */ + GLboolean ClipEnabled[MAX_CLIP_PLANES]; + GLubyte _AnyClip; /* How many ClipEnabled? */ + GLboolean Normalize; /* Normalize all normals? */ + GLboolean RescaleNormals; /* GL_EXT_rescale_normal */ +}; + + +struct gl_viewport_attrib { + GLint X, Y; /* position */ + GLsizei Width, Height; /* size */ + GLfloat Near, Far; /* Depth buffer range */ + GLmatrix _WindowMap; /* Mapping transformation as a matrix. */ +}; + + +/* For the attribute stack: */ +struct gl_attrib_node { + GLbitfield kind; + void *data; + struct gl_attrib_node *next; +}; + + +/* + * Client pixel packing/unpacking attributes + */ +struct gl_pixelstore_attrib { + GLint Alignment; + GLint RowLength; + GLint SkipPixels; + GLint SkipRows; + GLint ImageHeight; /* for GL_EXT_texture3D */ + GLint SkipImages; /* for GL_EXT_texture3D */ + GLboolean SwapBytes; + GLboolean LsbFirst; +}; + + +#define CA_CLIENT_DATA 0x1 /* Data not alloced by mesa */ + + +/* + * Client vertex array attributes + */ +struct gl_client_array { + GLint Size; + GLenum Type; + GLsizei Stride; /* user-specified stride */ + GLsizei StrideB; /* actual stride in bytes */ + void *Ptr; + GLuint Flags; + GLboolean Enabled; +}; + + +struct gl_array_attrib { + struct gl_client_array Vertex; /* client data descriptors */ + struct gl_client_array Normal; + struct gl_client_array Color; + struct gl_client_array SecondaryColor; + struct gl_client_array FogCoord; + struct gl_client_array Index; + struct gl_client_array TexCoord[MAX_TEXTURE_UNITS]; + struct gl_client_array EdgeFlag; + + GLint TexCoordInterleaveFactor; + GLint ActiveTexture; /* Client Active Texture */ + GLuint LockFirst; + GLuint LockCount; + + GLuint _Enabled; /* _NEW_ARRAY_* - bit set if array enabled */ + GLuint NewState; /* _NEW_ARRAY_* */ +}; + + +struct gl_feedback { + GLenum Type; + GLuint _Mask; /* FB_* bits */ + GLfloat *Buffer; + GLuint BufferSize; + GLuint Count; +}; + + +struct gl_selection { + GLuint *Buffer; + GLuint BufferSize; /* size of SelectBuffer */ + GLuint BufferCount; /* number of values in SelectBuffer */ + GLuint Hits; /* number of records in SelectBuffer */ + GLuint NameStackDepth; + GLuint NameStack[MAX_NAME_STACK_DEPTH]; + GLboolean HitFlag; + GLfloat HitMinZ, HitMaxZ; +}; + + +/* + * 1-D Evaluator control points + */ +struct gl_1d_map { + GLuint Order; /* Number of control points */ + GLfloat u1, u2, du; /* u1, u2, 1.0/(u2-u1) */ + GLfloat *Points; /* Points to contiguous control points */ +}; + + +/* + * 2-D Evaluator control points + */ +struct gl_2d_map { + GLuint Uorder; /* Number of control points in U dimension */ + GLuint Vorder; /* Number of control points in V dimension */ + GLfloat u1, u2, du; + GLfloat v1, v2, dv; + GLfloat *Points; /* Points to contiguous control points */ +}; + + +/* + * All evalutator control points + */ +struct gl_evaluators { + /* 1-D maps */ + struct gl_1d_map Map1Vertex3; + struct gl_1d_map Map1Vertex4; + struct gl_1d_map Map1Index; + struct gl_1d_map Map1Color4; + struct gl_1d_map Map1Normal; + struct gl_1d_map Map1Texture1; + struct gl_1d_map Map1Texture2; + struct gl_1d_map Map1Texture3; + struct gl_1d_map Map1Texture4; + + /* 2-D maps */ + struct gl_2d_map Map2Vertex3; + struct gl_2d_map Map2Vertex4; + struct gl_2d_map Map2Index; + struct gl_2d_map Map2Color4; + struct gl_2d_map Map2Normal; + struct gl_2d_map Map2Texture1; + struct gl_2d_map Map2Texture2; + struct gl_2d_map Map2Texture3; + struct gl_2d_map Map2Texture4; +}; + + +/* + * State which can be shared by multiple contexts: + */ +struct gl_shared_state { + _glthread_Mutex Mutex; /* for thread safety */ + GLint RefCount; /* Reference count */ + struct _mesa_HashTable *DisplayList; /* Display lists hash table */ + struct _mesa_HashTable *TexObjects; /* Texture objects hash table */ + struct gl_texture_object *TexObjectList;/* Linked list of texture objects */ + + /* Default texture objects (shared by all multi-texture units) */ + struct gl_texture_object *Default1D; + struct gl_texture_object *Default2D; + struct gl_texture_object *Default3D; + struct gl_texture_object *DefaultCubeMap; + + void *DriverData; /* Device driver shared state */ +}; + + +/* + * A "frame buffer" is a color buffer and its optional ancillary buffers: + * depth, accum, stencil, and software-simulated alpha buffers. + * In C++ terms, think of this as a base class from which device drivers + * will make derived classes. + */ +struct gl_frame_buffer { + GLvisual Visual; /* The corresponding visual */ + + GLint Width, Height; /* size of frame buffer in pixels */ + + GLboolean UseSoftwareDepthBuffer; + GLboolean UseSoftwareAccumBuffer; + GLboolean UseSoftwareStencilBuffer; + GLboolean UseSoftwareAlphaBuffers; + + /* Software depth (aka Z) buffer */ + GLvoid *DepthBuffer; /* array [Width*Height] of GLushort or GLuint*/ + + /* Software stencil buffer */ + GLstencil *Stencil; /* array [Width*Height] of GLstencil values */ + + /* Software accumulation buffer */ + GLaccum *Accum; /* array [4*Width*Height] of GLaccum values */ + + /* Software alpha planes */ + GLchan *FrontLeftAlpha; /* array [Width*Height] of GLubyte */ + GLchan *BackLeftAlpha; /* array [Width*Height] of GLubyte */ + GLchan *FrontRightAlpha; /* array [Width*Height] of GLubyte */ + GLchan *BackRightAlpha; /* array [Width*Height] of GLubyte */ + GLchan *Alpha; /* Points to current alpha buffer */ + + /* Drawing bounds: intersection of window size and scissor box */ + GLint _Xmin, _Ymin; /* inclusive */ + GLint _Xmax, _Ymax; /* exclusive */ +}; + + +/* + * Constants which may be overriden by device driver during context creation + * but are never changed after that. + */ +struct gl_constants { + GLint MaxTextureLevels; + GLint Max3DTextureLevels; + GLint MaxCubeTextureLevels; + GLuint MaxTextureUnits; + GLfloat MaxTextureMaxAnisotropy; /* GL_EXT_texture_filter_anisotropic */ + GLuint MaxArrayLockSize; + GLint SubPixelBits; + GLfloat MinPointSize, MaxPointSize; /* aliased */ + GLfloat MinPointSizeAA, MaxPointSizeAA; /* antialiased */ + GLfloat PointSizeGranularity; + GLfloat MinLineWidth, MaxLineWidth; /* aliased */ + GLfloat MinLineWidthAA, MaxLineWidthAA; /* antialiased */ + GLfloat LineWidthGranularity; + GLuint NumAuxBuffers; + GLuint MaxColorTableSize; + GLuint MaxConvolutionWidth; + GLuint MaxConvolutionHeight; + GLuint NumCompressedTextureFormats; /* GL_ARB_texture_compression */ + GLenum CompressedTextureFormats[MAX_COMPRESSED_TEXTURE_FORMATS]; + GLuint MaxClipPlanes; + GLuint MaxLights; +}; + + +/* + * List of extensions. + */ +struct extension; +struct gl_extensions { + char *ext_string; + struct extension *ext_list; + /* Flags to quickly test if certain extensions are available. + * Not every extension needs to have such a flag, but it's encouraged. + */ + GLboolean ARB_imaging; + GLboolean ARB_multisample; + GLboolean ARB_multitexture; + GLboolean ARB_texture_border_clamp; + GLboolean ARB_texture_compression; + GLboolean ARB_texture_cube_map; + GLboolean ARB_texture_env_combine; + GLboolean ARB_texture_env_dot3; + GLboolean EXT_blend_color; + GLboolean EXT_blend_func_separate; + GLboolean EXT_blend_logic_op; + GLboolean EXT_blend_minmax; + GLboolean EXT_blend_subtract; + GLboolean EXT_clip_volume_hint; + GLboolean EXT_convolution; + GLboolean EXT_compiled_vertex_array; + GLboolean EXT_fog_coord; + GLboolean EXT_histogram; + GLboolean EXT_packed_pixels; + GLboolean EXT_paletted_texture; + GLboolean EXT_point_parameters; + GLboolean EXT_polygon_offset; + GLboolean EXT_rescale_normal; + GLboolean EXT_secondary_color; + GLboolean EXT_shared_texture_palette; + GLboolean EXT_stencil_wrap; + GLboolean EXT_texture3D; + GLboolean EXT_texture_compression_s3tc; + GLboolean EXT_texture_env_add; + GLboolean EXT_texture_env_combine; + GLboolean EXT_texture_env_dot3; + GLboolean EXT_texture_filter_anisotropic; + GLboolean EXT_texture_object; + GLboolean EXT_texture_lod_bias; + GLboolean EXT_vertex_array_set; + GLboolean HP_occlusion_test; + GLboolean INGR_blend_func_separate; + GLboolean MESA_window_pos; + GLboolean MESA_resize_buffers; + GLboolean MESA_sprite_point; + GLboolean NV_blend_square; + GLboolean NV_texgen_reflection; + GLboolean SGI_color_matrix; + GLboolean SGI_color_table; + GLboolean SGIS_generate_mipmap; + GLboolean SGIS_pixel_texture; + GLboolean SGIS_texture_edge_clamp; + GLboolean SGIX_depth_texture; + GLboolean SGIX_pixel_texture; + GLboolean SGIX_shadow; + GLboolean SGIX_shadow_ambient; + GLboolean _3DFX_texture_compression_FXT1; +}; + + + +/* + * Bits for image transfer operations (ctx->ImageTransferState). + */ +#define IMAGE_SCALE_BIAS_BIT 0x1 +#define IMAGE_SHIFT_OFFSET_BIT 0x2 +#define IMAGE_MAP_COLOR_BIT 0x4 +#define IMAGE_COLOR_TABLE_BIT 0x8 +#define IMAGE_CONVOLUTION_BIT 0x10 +#define IMAGE_POST_CONVOLUTION_SCALE_BIAS 0x20 +#define IMAGE_POST_CONVOLUTION_COLOR_TABLE_BIT 0x40 +#define IMAGE_COLOR_MATRIX_BIT 0x80 +#define IMAGE_POST_COLOR_MATRIX_COLOR_TABLE_BIT 0x100 +#define IMAGE_HISTOGRAM_BIT 0x200 +#define IMAGE_MIN_MAX_BIT 0x400 + +/* transfer ops up to convolution: */ +#define IMAGE_PRE_CONVOLUTION_BITS (IMAGE_SCALE_BIAS_BIT | \ + IMAGE_SHIFT_OFFSET_BIT | \ + IMAGE_MAP_COLOR_BIT | \ + IMAGE_COLOR_TABLE_BIT) + +/* transfer ops after convolution: */ +#define IMAGE_POST_CONVOLUTION_BITS (IMAGE_POST_CONVOLUTION_SCALE_BIAS | \ + IMAGE_POST_CONVOLUTION_COLOR_TABLE_BIT | \ + IMAGE_COLOR_MATRIX_BIT | \ + IMAGE_POST_COLOR_MATRIX_COLOR_TABLE_BIT |\ + IMAGE_HISTOGRAM_BIT | \ + IMAGE_MIN_MAX_BIT) + + +/* + * Bits to indicate what state has changed. 6 unused flags. + */ +#define _NEW_MODELVIEW 0x1 /* ctx->ModelView */ +#define _NEW_PROJECTION 0x2 /* ctx->Projection */ +#define _NEW_TEXTURE_MATRIX 0x4 /* ctx->TextureMatrix */ +#define _NEW_COLOR_MATRIX 0x8 /* ctx->ColorMatrix */ +#define _NEW_ACCUM 0x10 /* ctx->Accum */ +#define _NEW_COLOR 0x20 /* ctx->Color */ +#define _NEW_DEPTH 0x40 /* ctx->Depth */ +#define _NEW_EVAL 0x80 /* ctx->Eval, ctx->EvalMap */ +#define _NEW_FOG 0x100 /* ctx->Fog */ +#define _NEW_HINT 0x200 /* ctx->Hint */ +#define _NEW_LIGHT 0x400 /* ctx->Light */ +#define _NEW_LINE 0x800 /* ctx->Line */ +#define _NEW_PIXEL 0x1000 /* ctx->Pixel */ +#define _NEW_POINT 0x2000 /* ctx->Point */ +#define _NEW_POLYGON 0x4000 /* ctx->Polygon */ +#define _NEW_POLYGONSTIPPLE 0x8000 /* ctx->PolygonStipple */ +#define _NEW_SCISSOR 0x10000 /* ctx->Scissor */ +#define _NEW_STENCIL 0x20000 /* ctx->Stencil */ +#define _NEW_TEXTURE 0x40000 /* ctx->Texture */ +#define _NEW_TRANSFORM 0x80000 /* ctx->Transform */ +#define _NEW_VIEWPORT 0x100000 /* ctx->Viewport */ +#define _NEW_PACKUNPACK 0x200000 /* ctx->Pack, ctx->Unpack */ +#define _NEW_ARRAY 0x400000 /* ctx->Array */ +#define _NEW_RENDERMODE 0x800000 /* RenderMode, Feedback, Select */ +#define _NEW_BUFFERS 0x1000000 /* ctx->Visual, ctx->DrawBuffer, */ +#define _NEW_MULTISAMPLE 0x2000000 /* ctx->Multisample */ +#define _NEW_ALL ~0 + + + +/* Bits to track array state changes (also used to summarize array enabled) + */ +#define _NEW_ARRAY_VERTEX 0x1 +#define _NEW_ARRAY_COLOR 0x2 +#define _NEW_ARRAY_NORMAL 0x4 +#define _NEW_ARRAY_INDEX 0x8 +#define _NEW_ARRAY_EDGEFLAG 0x10 +#define _NEW_ARRAY_SECONDARYCOLOR 0x20 +#define _NEW_ARRAY_FOGCOORD 0x40 +#define _NEW_ARRAY_TEXCOORD_0 0x80 +#define _NEW_ARRAY_TEXCOORD_1 0x100 +#define _NEW_ARRAY_TEXCOORD_2 0x200 +#define _NEW_ARRAY_TEXCOORD_3 0x400 +#define _NEW_ARRAY_TEXCOORD_4 0x800 +#define _NEW_ARRAY_TEXCOORD_5 0x1000 +#define _NEW_ARRAY_TEXCOORD_6 0x2000 +#define _NEW_ARRAY_TEXCOORD_7 0x4000 +#define _NEW_ARRAY_ALL 0x7fff + +#define _NEW_ARRAY_TEXCOORD(i) (_NEW_ARRAY_TEXCOORD_0 << (i)) + +/* A bunch of flags that we think might be useful to drivers. + */ +#define DD_FLATSHADE 0x1 +#define DD_SEPARATE_SPECULAR 0x2 +#define DD_TRI_CULL_FRONT_BACK 0x4 /* special case on some hw */ +#define DD_TRI_LIGHT_TWOSIDE 0x8 +#define DD_TRI_UNFILLED 0x10 +#define DD_TRI_SMOOTH 0x20 +#define DD_TRI_STIPPLE 0x40 +#define DD_TRI_OFFSET 0x80 +#define DD_LINE_SMOOTH 0x100 +#define DD_LINE_STIPPLE 0x200 +#define DD_LINE_WIDTH 0x400 +#define DD_POINT_SMOOTH 0x800 +#define DD_POINT_SIZE 0x1000 +#define DD_POINT_ATTEN 0x2000 + +/* Define the state changes under which each of these bits might change + */ +#define _DD_NEW_FLATSHADE _NEW_LIGHT +#define _DD_NEW_SEPARATE_SPECULAR (_NEW_LIGHT | _NEW_FOG) +#define _DD_NEW_TRI_CULL_FRONT_BACK _NEW_POLYGON +#define _DD_NEW_TRI_LIGHT_TWOSIDE _NEW_LIGHT +#define _DD_NEW_TRI_UNFILLED _NEW_POLYGON +#define _DD_NEW_TRI_SMOOTH _NEW_POLYGON +#define _DD_NEW_TRI_STIPPLE _NEW_POLYGON +#define _DD_NEW_TRI_OFFSET _NEW_POLYGON +#define _DD_NEW_LINE_SMOOTH _NEW_LINE +#define _DD_NEW_LINE_STIPPLE _NEW_LINE +#define _DD_NEW_LINE_WIDTH _NEW_LINE +#define _DD_NEW_POINT_SMOOTH _NEW_POINT +#define _DD_NEW_POINT_SIZE _NEW_POINT +#define _DD_NEW_POINT_ATTEN _NEW_POINT + +#define _MESA_NEW_NEED_EYE_COORDS (_NEW_LIGHT | \ + _NEW_TEXTURE | \ + _NEW_POINT | \ + _NEW_MODELVIEW) + +#define _MESA_NEW_NEED_NORMALS (_NEW_LIGHT | \ + _NEW_TEXTURE) + +#define _IMAGE_NEW_TRANSFER_STATE (_NEW_PIXEL | _NEW_COLOR_MATRIX) + + +#define NEED_NORMALS_TEXGEN 0x1 +#define NEED_NORMALS_LIGHT 0x2 + +#define NEED_EYE_TEXGEN 0x1 +#define NEED_EYE_LIGHT 0x2 +#define NEED_EYE_LIGHT_MODELVIEW 0x4 +#define NEED_EYE_POINT_ATTEN 0x8 + + +/* + * Forward declaration of display list datatypes: + */ +union node; +typedef union node Node; + + +/* This has to be included here. */ +#include "dd.h" + + +/* + * Core Mesa's support for tnl modules: + */ +#define NUM_VERTEX_FORMAT_ENTRIES (sizeof(GLvertexformat) / sizeof(void *)) + +struct gl_tnl_module { + /* Vertex format to be lazily swapped into current dispatch. + */ + GLvertexformat *Current; + + /* Record of functions swapped out. On restore, only need to swap + * these functions back in. + */ + void *Swapped[NUM_VERTEX_FORMAT_ENTRIES][2]; + GLuint SwapCount; +}; + + +/* + * The library context: + */ +struct __GLcontextRec { + /* + ** Os related interfaces; these *must* be the first members of this + ** structure, because they are exposed to the outside world (i.e. GLX + ** extension). + */ + __GLimports imports; + __GLexports exports; + + /* State possibly shared with other contexts in the address space */ + struct gl_shared_state *Shared; + + /* API function pointer tables */ + struct _glapi_table *Save; /* Display list save funcs */ + struct _glapi_table *Exec; /* Execute funcs */ + struct _glapi_table *CurrentDispatch; /* == Save or Exec !! */ + + GLboolean ExecPrefersFloat; /* What preference for color conversion? */ + GLboolean SavePrefersFloat; + + GLvisual Visual; + GLframebuffer *DrawBuffer; /* buffer for writing */ + GLframebuffer *ReadBuffer; /* buffer for reading */ + + /* Driver function pointer table */ + struct dd_function_table Driver; + + void *DriverCtx; /* Points to device driver context/state */ + void *DriverMgrCtx; /* Points to device driver manager (optional)*/ + + /* Core/Driver constants */ + struct gl_constants Const; + + /* Modelview matrix and stack */ + GLmatrix ModelView; /* current matrix, not stored on stack */ + GLuint ModelViewStackDepth; + GLmatrix ModelViewStack[MAX_MODELVIEW_STACK_DEPTH - 1]; + + /* Projection matrix and stack */ + GLmatrix ProjectionMatrix; /* current matrix, not stored on stack */ + GLuint ProjectionStackDepth; + GLmatrix ProjectionStack[MAX_PROJECTION_STACK_DEPTH - 1]; + + /* Combined modelview and projection matrix */ + GLmatrix _ModelProjectMatrix; + + /* Texture matrix and stack */ + GLmatrix TextureMatrix[MAX_TEXTURE_UNITS]; + GLuint TextureStackDepth[MAX_TEXTURE_UNITS]; + GLmatrix TextureStack[MAX_TEXTURE_UNITS][MAX_TEXTURE_STACK_DEPTH - 1]; + + /* Color matrix and stack */ + GLmatrix ColorMatrix; + GLuint ColorStackDepth; + GLmatrix ColorStack[MAX_COLOR_STACK_DEPTH - 1]; + + /* Display lists */ + GLuint CallDepth; /* Current recursion calling depth */ + GLboolean ExecuteFlag; /* Execute GL commands? */ + GLboolean CompileFlag; /* Compile GL commands into display list? */ + Node *CurrentListPtr; /* Head of list being compiled */ + GLuint CurrentListNum; /* Number of the list being compiled */ + Node *CurrentBlock; /* Pointer to current block of nodes */ + GLuint CurrentPos; /* Index into current block of nodes */ + + /* Extensions */ + struct gl_extensions Extensions; + + /* Renderer attribute stack */ + GLuint AttribStackDepth; + struct gl_attrib_node *AttribStack[MAX_ATTRIB_STACK_DEPTH]; + + /* Renderer attribute groups */ + struct gl_accum_attrib Accum; + struct gl_colorbuffer_attrib Color; + struct gl_current_attrib Current; + struct gl_depthbuffer_attrib Depth; + struct gl_eval_attrib Eval; + struct gl_fog_attrib Fog; + struct gl_hint_attrib Hint; + struct gl_light_attrib Light; + struct gl_line_attrib Line; + struct gl_list_attrib List; + struct gl_multisample_attrib Multisample; + struct gl_pixel_attrib Pixel; + struct gl_point_attrib Point; + struct gl_polygon_attrib Polygon; + GLuint PolygonStipple[32]; + struct gl_scissor_attrib Scissor; + struct gl_stencil_attrib Stencil; + struct gl_texture_attrib Texture; + struct gl_transform_attrib Transform; + struct gl_viewport_attrib Viewport; + + /* Other attribute groups */ + struct gl_histogram_attrib Histogram; + struct gl_minmax_attrib MinMax; + struct gl_convolution_attrib Convolution1D; + struct gl_convolution_attrib Convolution2D; + struct gl_convolution_attrib Separable2D; + + /* Client attribute stack */ + GLuint ClientAttribStackDepth; + struct gl_attrib_node *ClientAttribStack[MAX_CLIENT_ATTRIB_STACK_DEPTH]; + + /* Client attribute groups */ + struct gl_array_attrib Array; /* Vertex arrays */ + struct gl_pixelstore_attrib Pack; /* Pixel packing */ + struct gl_pixelstore_attrib Unpack; /* Pixel unpacking */ + + struct gl_evaluators EvalMap; /* All evaluators */ + struct gl_feedback Feedback; /* Feedback */ + struct gl_selection Select; /* Selection */ + + struct gl_color_table ColorTable; /* Pre-convolution */ + struct gl_color_table ProxyColorTable; /* Pre-convolution */ + struct gl_color_table PostConvolutionColorTable; + struct gl_color_table ProxyPostConvolutionColorTable; + struct gl_color_table PostColorMatrixColorTable; + struct gl_color_table ProxyPostColorMatrixColorTable; + + GLenum ErrorValue; /* Last error code */ + GLenum RenderMode; /* either GL_RENDER, GL_SELECT, GL_FEEDBACK */ + GLuint NewState; /* bitwise-or of _NEW_* flags */ + + /* Derived */ + GLuint _TriangleCaps; /* bitwise-or of DD_* flags */ + GLuint _ImageTransferState;/* bitwise-or of IMAGE_*_BIT flags */ + GLfloat _EyeZDir[3]; + GLfloat _ModelViewInvScale; + GLuint _NeedEyeCoords; + GLuint _NeedNormals; /* Are vertex normal vectors needed? */ + + struct gl_shine_tab *_ShineTable[2]; /* Active shine tables */ + struct gl_shine_tab *_ShineTabList; /* Mru list of inactive shine tables */ + + struct gl_list_extensions listext; /* driver dlist extensions */ + + + GLboolean OcclusionResult; /* GL_HP_occlusion_test */ + GLboolean OcclusionResultSaved; /* GL_HP_occlusion_test */ + + /* Z buffer stuff */ + GLuint DepthMax; /* Max depth buffer value */ + GLfloat DepthMaxF; /* Float max depth buffer value */ + GLfloat MRD; /* minimum resolvable difference in Z values */ + + /* Should 3Dfx Glide driver catch signals? */ + GLboolean CatchSignals; + + /* For debugging/development only */ + GLboolean NoRaster; + GLboolean FirstTimeCurrent; + + /* Dither disable via MESA_NO_DITHER env var */ + GLboolean NoDither; + + GLboolean Rendering; + +#if defined(MESA_TRACE) + struct _glapi_table *TraceDispatch; + trace_context_t *TraceCtx; +#else + void *TraceDispatch; + void *TraceCtx; +#endif + + /* Core tnl module support */ + struct gl_tnl_module TnlModule; + + /* Hooks for module contexts. These will eventually live + * in the driver or elsewhere. + */ + void *swrast_context; + void *swsetup_context; + void *swtnl_context; + void *swtnl_im; + void *acache_context; + void *aelt_context; +}; + + +/* The string names for GL_POINT, GL_LINE_LOOP, etc */ +extern const char *_mesa_prim_name[GL_POLYGON+4]; + + +#ifdef MESA_DEBUG +extern int MESA_VERBOSE; +extern int MESA_DEBUG_FLAGS; +#else +# define MESA_VERBOSE 0 +# define MESA_DEBUG_FLAGS 0 +# ifndef NDEBUG +# define NDEBUG +# endif +#endif + + +enum _verbose { + VERBOSE_VARRAY = 0x0001, + VERBOSE_TEXTURE = 0x0002, + VERBOSE_IMMEDIATE = 0x0004, + VERBOSE_PIPELINE = 0x0008, + VERBOSE_DRIVER = 0x0010, + VERBOSE_STATE = 0x0020, + VERBOSE_API = 0x0040, + VERBOSE_DISPLAY_LIST = 0x0200, + VERBOSE_LIGHTING = 0x0400 +}; + + +enum _debug { + DEBUG_ALWAYS_FLUSH = 0x1 +}; + + + +#define Elements(x) sizeof(x)/sizeof(*(x)) + + + +/* Eventually let the driver specify what statechanges require a flush: + */ +#define FLUSH_VERTICES(ctx, newstate) \ +do { \ + if (ctx->Driver.NeedFlush & FLUSH_STORED_VERTICES) \ + ctx->Driver.FlushVertices(ctx, FLUSH_STORED_VERTICES); \ + ctx->NewState |= newstate; \ +} while (0) + +#define FLUSH_CURRENT(ctx, newstate) \ +do { \ + if (ctx->Driver.NeedFlush & FLUSH_UPDATE_CURRENT) \ + ctx->Driver.FlushVertices(ctx, FLUSH_UPDATE_CURRENT); \ + ctx->NewState |= newstate; \ +} while (0) + +#define ASSERT_OUTSIDE_BEGIN_END_WITH_RETVAL(ctx, retval) \ +do { \ + if (ctx->Driver.CurrentExecPrimitive != PRIM_OUTSIDE_BEGIN_END) { \ + _mesa_error( ctx, GL_INVALID_OPERATION, "begin/end" ); \ + return retval; \ + } \ +} while (0) + +#define ASSERT_OUTSIDE_BEGIN_END(ctx) \ +do { \ + if (ctx->Driver.CurrentExecPrimitive != PRIM_OUTSIDE_BEGIN_END) { \ + _mesa_error( ctx, GL_INVALID_OPERATION, "begin/end" ); \ + return; \ + } \ +} while (0) + +#define ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx) \ +do { \ + ASSERT_OUTSIDE_BEGIN_END(ctx); \ + FLUSH_VERTICES(ctx, 0); \ +} while (0) + +#define ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH_WITH_RETVAL(ctx, retval) \ +do { \ + ASSERT_OUTSIDE_BEGIN_END_WITH_RETVAL(ctx, retval); \ + FLUSH_VERTICES(ctx, 0); \ +} while (0) + + + + +#endif /* TYPES_H */ Index: dll/opengl/opengl32/mesa/pixel.c =================================================================== --- dll/opengl/opengl32/mesa/pixel.c (revision 0) +++ dll/opengl/opengl32/mesa/pixel.c (working copy) @@ -0,0 +1,1322 @@ +/* $Id: pixel.c,v 1.29 2001/05/23 23:55:01 brianp Exp $ */ + +/* + * Mesa 3-D graphics library + * Version: 3.5 + * + * Copyright (C) 1999-2001 Brian Paul 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 + * BRIAN PAUL 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. + */ + + +#ifdef PC_HEADER +#include "all.h" +#else +#include "glheader.h" +#include "colormac.h" +#include "context.h" +#include "macros.h" +#include "mem.h" +#include "pixel.h" +#include "mtypes.h" +#endif + + + +/**********************************************************************/ +/***** glPixelZoom *****/ +/**********************************************************************/ + + + +void +_mesa_PixelZoom( GLfloat xfactor, GLfloat yfactor ) +{ + GET_CURRENT_CONTEXT(ctx); + + if (ctx->Pixel.ZoomX == xfactor && + ctx->Pixel.ZoomY == yfactor) + return; + + FLUSH_VERTICES(ctx, _NEW_PIXEL); + ctx->Pixel.ZoomX = xfactor; + ctx->Pixel.ZoomY = yfactor; +} + + + +/**********************************************************************/ +/***** glPixelStore *****/ +/**********************************************************************/ + + +void +_mesa_PixelStorei( GLenum pname, GLint param ) +{ + /* NOTE: this call can't be compiled into the display list */ + GET_CURRENT_CONTEXT(ctx); + ASSERT_OUTSIDE_BEGIN_END(ctx); + + switch (pname) { + case GL_PACK_SWAP_BYTES: + if (param == (GLint)ctx->Pack.SwapBytes) + return; + FLUSH_VERTICES(ctx, _NEW_PACKUNPACK); + ctx->Pack.SwapBytes = param ? GL_TRUE : GL_FALSE; + break; + case GL_PACK_LSB_FIRST: + if (param == (GLint)ctx->Pack.LsbFirst) + return; + FLUSH_VERTICES(ctx, _NEW_PACKUNPACK); + ctx->Pack.LsbFirst = param ? GL_TRUE : GL_FALSE; + break; + case GL_PACK_ROW_LENGTH: + if (param<0) { + _mesa_error( ctx, GL_INVALID_VALUE, "glPixelStore(param)" ); + return; + } + if (ctx->Pack.RowLength == param) + return; + FLUSH_VERTICES(ctx, _NEW_PACKUNPACK); + ctx->Pack.RowLength = param; + break; + case GL_PACK_IMAGE_HEIGHT: + if (param<0) { + _mesa_error( ctx, GL_INVALID_VALUE, "glPixelStore(param)" ); + return; + } + if (ctx->Pack.ImageHeight == param) + return; + FLUSH_VERTICES(ctx, _NEW_PACKUNPACK); + ctx->Pack.ImageHeight = param; + break; + case GL_PACK_SKIP_PIXELS: + if (param<0) { + _mesa_error( ctx, GL_INVALID_VALUE, "glPixelStore(param)" ); + return; + } + if (ctx->Pack.SkipPixels == param) + return; + FLUSH_VERTICES(ctx, _NEW_PACKUNPACK); + ctx->Pack.SkipPixels = param; + break; + case GL_PACK_SKIP_ROWS: + if (param<0) { + _mesa_error( ctx, GL_INVALID_VALUE, "glPixelStore(param)" ); + return; + } + if (ctx->Pack.SkipRows == param) + return; + FLUSH_VERTICES(ctx, _NEW_PACKUNPACK); + ctx->Pack.SkipRows = param; + break; + case GL_PACK_SKIP_IMAGES: + if (param<0) { + _mesa_error( ctx, GL_INVALID_VALUE, "glPixelStore(param)" ); + return; + } + if (ctx->Pack.SkipImages == param) + return; + FLUSH_VERTICES(ctx, _NEW_PACKUNPACK); + ctx->Pack.SkipImages = param; + break; + case GL_PACK_ALIGNMENT: + if (param!=1 && param!=2 && param!=4 && param!=8) { + _mesa_error( ctx, GL_INVALID_VALUE, "glPixelStore(param)" ); + return; + } + if (ctx->Pack.Alignment == param) + return; + FLUSH_VERTICES(ctx, _NEW_PACKUNPACK); + ctx->Pack.Alignment = param; + break; + case GL_UNPACK_SWAP_BYTES: + if (param == (GLint)ctx->Unpack.SwapBytes) + return; + if ((GLint)ctx->Unpack.SwapBytes == param) + return; + FLUSH_VERTICES(ctx, _NEW_PACKUNPACK); + ctx->Unpack.SwapBytes = param ? GL_TRUE : GL_FALSE; + break; + case GL_UNPACK_LSB_FIRST: + if (param == (GLint)ctx->Unpack.LsbFirst) + return; + if ((GLint)ctx->Unpack.LsbFirst == param) + return; + FLUSH_VERTICES(ctx, _NEW_PACKUNPACK); + ctx->Unpack.LsbFirst = param ? GL_TRUE : GL_FALSE; + break; + case GL_UNPACK_ROW_LENGTH: + if (param<0) { + _mesa_error( ctx, GL_INVALID_VALUE, "glPixelStore(param)" ); + return; + } + if (ctx->Unpack.RowLength == param) + return; + FLUSH_VERTICES(ctx, _NEW_PACKUNPACK); + ctx->Unpack.RowLength = param; + break; + case GL_UNPACK_IMAGE_HEIGHT: + if (param<0) { + _mesa_error( ctx, GL_INVALID_VALUE, "glPixelStore(param)" ); + return; + } + if (ctx->Unpack.ImageHeight == param) + return; + + FLUSH_VERTICES(ctx, _NEW_PACKUNPACK); + ctx->Unpack.ImageHeight = param; + break; + case GL_UNPACK_SKIP_PIXELS: + if (param<0) { + _mesa_error( ctx, GL_INVALID_VALUE, "glPixelStore(param)" ); + return; + } + if (ctx->Unpack.SkipPixels == param) + return; + FLUSH_VERTICES(ctx, _NEW_PACKUNPACK); + ctx->Unpack.SkipPixels = param; + break; + case GL_UNPACK_SKIP_ROWS: + if (param<0) { + _mesa_error( ctx, GL_INVALID_VALUE, "glPixelStore(param)" ); + return; + } + if (ctx->Unpack.SkipRows == param) + return; + FLUSH_VERTICES(ctx, _NEW_PACKUNPACK); + ctx->Unpack.SkipRows = param; + break; + case GL_UNPACK_SKIP_IMAGES: + if (param < 0) { + _mesa_error( ctx, GL_INVALID_VALUE, "glPixelStore(param)" ); + return; + } + if (ctx->Unpack.SkipImages == param) + return; + FLUSH_VERTICES(ctx, _NEW_PACKUNPACK); + ctx->Unpack.SkipImages = param; + break; + case GL_UNPACK_ALIGNMENT: + if (param!=1 && param!=2 && param!=4 && param!=8) { + _mesa_error( ctx, GL_INVALID_VALUE, "glPixelStore" ); + return; + } + if (ctx->Unpack.Alignment == param) + return; + FLUSH_VERTICES(ctx, _NEW_PACKUNPACK); + ctx->Unpack.Alignment = param; + break; + default: + _mesa_error( ctx, GL_INVALID_ENUM, "glPixelStore" ); + return; + } +} + + +void +_mesa_PixelStoref( GLenum pname, GLfloat param ) +{ + _mesa_PixelStorei( pname, (GLint) param ); +} + + + +/**********************************************************************/ +/***** glPixelMap *****/ +/**********************************************************************/ + + + +void +_mesa_PixelMapfv( GLenum map, GLint mapsize, const GLfloat *values ) +{ + GLint i; + GET_CURRENT_CONTEXT(ctx); + ASSERT_OUTSIDE_BEGIN_END(ctx); + + if (mapsize<0 || mapsize>MAX_PIXEL_MAP_TABLE) { + _mesa_error( ctx, GL_INVALID_VALUE, "glPixelMapfv(mapsize)" ); + return; + } + + if (map>=GL_PIXEL_MAP_S_TO_S && map<=GL_PIXEL_MAP_I_TO_A) { + /* test that mapsize is a power of two */ + GLuint p; + GLboolean ok = GL_FALSE; + for (p=1; p<=MAX_PIXEL_MAP_TABLE; p=p<<1) { + if ( (p&mapsize) == p ) { + ok = GL_TRUE; + break; + } + } + if (!ok) { + _mesa_error( ctx, GL_INVALID_VALUE, "glPixelMapfv(mapsize)" ); + return; + } + } + + FLUSH_VERTICES(ctx, _NEW_PIXEL); + + switch (map) { + case GL_PIXEL_MAP_S_TO_S: + ctx->Pixel.MapStoSsize = mapsize; + for (i=0;iPixel.MapStoS[i] = (GLint) values[i]; + } + break; + case GL_PIXEL_MAP_I_TO_I: + ctx->Pixel.MapItoIsize = mapsize; + for (i=0;iPixel.MapItoI[i] = (GLint) values[i]; + } + break; + case GL_PIXEL_MAP_I_TO_R: + ctx->Pixel.MapItoRsize = mapsize; + for (i=0;iPixel.MapItoR[i] = val; + ctx->Pixel.MapItoR8[i] = (GLint) (val * 255.0F); + } + break; + case GL_PIXEL_MAP_I_TO_G: + ctx->Pixel.MapItoGsize = mapsize; + for (i=0;iPixel.MapItoG[i] = val; + ctx->Pixel.MapItoG8[i] = (GLint) (val * 255.0F); + } + break; + case GL_PIXEL_MAP_I_TO_B: + ctx->Pixel.MapItoBsize = mapsize; + for (i=0;iPixel.MapItoB[i] = val; + ctx->Pixel.MapItoB8[i] = (GLint) (val * 255.0F); + } + break; + case GL_PIXEL_MAP_I_TO_A: + ctx->Pixel.MapItoAsize = mapsize; + for (i=0;iPixel.MapItoA[i] = val; + ctx->Pixel.MapItoA8[i] = (GLint) (val * 255.0F); + } + break; + case GL_PIXEL_MAP_R_TO_R: + ctx->Pixel.MapRtoRsize = mapsize; + for (i=0;iPixel.MapRtoR[i] = CLAMP( values[i], 0.0, 1.0 ); + } + break; + case GL_PIXEL_MAP_G_TO_G: + ctx->Pixel.MapGtoGsize = mapsize; + for (i=0;iPixel.MapGtoG[i] = CLAMP( values[i], 0.0, 1.0 ); + } + break; + case GL_PIXEL_MAP_B_TO_B: + ctx->Pixel.MapBtoBsize = mapsize; + for (i=0;iPixel.MapBtoB[i] = CLAMP( values[i], 0.0, 1.0 ); + } + break; + case GL_PIXEL_MAP_A_TO_A: + ctx->Pixel.MapAtoAsize = mapsize; + for (i=0;iPixel.MapAtoA[i] = CLAMP( values[i], 0.0, 1.0 ); + } + break; + default: + _mesa_error( ctx, GL_INVALID_ENUM, "glPixelMapfv(map)" ); + } +} + + + +void +_mesa_PixelMapuiv(GLenum map, GLint mapsize, const GLuint *values ) +{ + GLfloat fvalues[MAX_PIXEL_MAP_TABLE]; + GLint i; + if (map==GL_PIXEL_MAP_I_TO_I || map==GL_PIXEL_MAP_S_TO_S) { + for (i=0;iPixel.MapItoIsize;i++) { + values[i] = (GLfloat) ctx->Pixel.MapItoI[i]; + } + break; + case GL_PIXEL_MAP_S_TO_S: + for (i=0;iPixel.MapStoSsize;i++) { + values[i] = (GLfloat) ctx->Pixel.MapStoS[i]; + } + break; + case GL_PIXEL_MAP_I_TO_R: + MEMCPY(values,ctx->Pixel.MapItoR,ctx->Pixel.MapItoRsize*sizeof(GLfloat)); + break; + case GL_PIXEL_MAP_I_TO_G: + MEMCPY(values,ctx->Pixel.MapItoG,ctx->Pixel.MapItoGsize*sizeof(GLfloat)); + break; + case GL_PIXEL_MAP_I_TO_B: + MEMCPY(values,ctx->Pixel.MapItoB,ctx->Pixel.MapItoBsize*sizeof(GLfloat)); + break; + case GL_PIXEL_MAP_I_TO_A: + MEMCPY(values,ctx->Pixel.MapItoA,ctx->Pixel.MapItoAsize*sizeof(GLfloat)); + break; + case GL_PIXEL_MAP_R_TO_R: + MEMCPY(values,ctx->Pixel.MapRtoR,ctx->Pixel.MapRtoRsize*sizeof(GLfloat)); + break; + case GL_PIXEL_MAP_G_TO_G: + MEMCPY(values,ctx->Pixel.MapGtoG,ctx->Pixel.MapGtoGsize*sizeof(GLfloat)); + break; + case GL_PIXEL_MAP_B_TO_B: + MEMCPY(values,ctx->Pixel.MapBtoB,ctx->Pixel.MapBtoBsize*sizeof(GLfloat)); + break; + case GL_PIXEL_MAP_A_TO_A: + MEMCPY(values,ctx->Pixel.MapAtoA,ctx->Pixel.MapAtoAsize*sizeof(GLfloat)); + break; + default: + _mesa_error( ctx, GL_INVALID_ENUM, "glGetPixelMapfv" ); + } +} + + +void +_mesa_GetPixelMapuiv( GLenum map, GLuint *values ) +{ + GET_CURRENT_CONTEXT(ctx); + GLint i; + ASSERT_OUTSIDE_BEGIN_END(ctx); + + switch (map) { + case GL_PIXEL_MAP_I_TO_I: + MEMCPY(values, ctx->Pixel.MapItoI, ctx->Pixel.MapItoIsize*sizeof(GLint)); + break; + case GL_PIXEL_MAP_S_TO_S: + MEMCPY(values, ctx->Pixel.MapStoS, ctx->Pixel.MapStoSsize*sizeof(GLint)); + break; + case GL_PIXEL_MAP_I_TO_R: + for (i=0;iPixel.MapItoRsize;i++) { + values[i] = FLOAT_TO_UINT( ctx->Pixel.MapItoR[i] ); + } + break; + case GL_PIXEL_MAP_I_TO_G: + for (i=0;iPixel.MapItoGsize;i++) { + values[i] = FLOAT_TO_UINT( ctx->Pixel.MapItoG[i] ); + } + break; + case GL_PIXEL_MAP_I_TO_B: + for (i=0;iPixel.MapItoBsize;i++) { + values[i] = FLOAT_TO_UINT( ctx->Pixel.MapItoB[i] ); + } + break; + case GL_PIXEL_MAP_I_TO_A: + for (i=0;iPixel.MapItoAsize;i++) { + values[i] = FLOAT_TO_UINT( ctx->Pixel.MapItoA[i] ); + } + break; + case GL_PIXEL_MAP_R_TO_R: + for (i=0;iPixel.MapRtoRsize;i++) { + values[i] = FLOAT_TO_UINT( ctx->Pixel.MapRtoR[i] ); + } + break; + case GL_PIXEL_MAP_G_TO_G: + for (i=0;iPixel.MapGtoGsize;i++) { + values[i] = FLOAT_TO_UINT( ctx->Pixel.MapGtoG[i] ); + } + break; + case GL_PIXEL_MAP_B_TO_B: + for (i=0;iPixel.MapBtoBsize;i++) { + values[i] = FLOAT_TO_UINT( ctx->Pixel.MapBtoB[i] ); + } + break; + case GL_PIXEL_MAP_A_TO_A: + for (i=0;iPixel.MapAtoAsize;i++) { + values[i] = FLOAT_TO_UINT( ctx->Pixel.MapAtoA[i] ); + } + break; + default: + _mesa_error( ctx, GL_INVALID_ENUM, "glGetPixelMapfv" ); + } +} + + +void +_mesa_GetPixelMapusv( GLenum map, GLushort *values ) +{ + GET_CURRENT_CONTEXT(ctx); + GLint i; + ASSERT_OUTSIDE_BEGIN_END(ctx); + + switch (map) { + case GL_PIXEL_MAP_I_TO_I: + for (i=0;iPixel.MapItoIsize;i++) { + values[i] = (GLushort) ctx->Pixel.MapItoI[i]; + } + break; + case GL_PIXEL_MAP_S_TO_S: + for (i=0;iPixel.MapStoSsize;i++) { + values[i] = (GLushort) ctx->Pixel.MapStoS[i]; + } + break; + case GL_PIXEL_MAP_I_TO_R: + for (i=0;iPixel.MapItoRsize;i++) { + values[i] = FLOAT_TO_USHORT( ctx->Pixel.MapItoR[i] ); + } + break; + case GL_PIXEL_MAP_I_TO_G: + for (i=0;iPixel.MapItoGsize;i++) { + values[i] = FLOAT_TO_USHORT( ctx->Pixel.MapItoG[i] ); + } + break; + case GL_PIXEL_MAP_I_TO_B: + for (i=0;iPixel.MapItoBsize;i++) { + values[i] = FLOAT_TO_USHORT( ctx->Pixel.MapItoB[i] ); + } + break; + case GL_PIXEL_MAP_I_TO_A: + for (i=0;iPixel.MapItoAsize;i++) { + values[i] = FLOAT_TO_USHORT( ctx->Pixel.MapItoA[i] ); + } + break; + case GL_PIXEL_MAP_R_TO_R: + for (i=0;iPixel.MapRtoRsize;i++) { + values[i] = FLOAT_TO_USHORT( ctx->Pixel.MapRtoR[i] ); + } + break; + case GL_PIXEL_MAP_G_TO_G: + for (i=0;iPixel.MapGtoGsize;i++) { + values[i] = FLOAT_TO_USHORT( ctx->Pixel.MapGtoG[i] ); + } + break; + case GL_PIXEL_MAP_B_TO_B: + for (i=0;iPixel.MapBtoBsize;i++) { + values[i] = FLOAT_TO_USHORT( ctx->Pixel.MapBtoB[i] ); + } + break; + case GL_PIXEL_MAP_A_TO_A: + for (i=0;iPixel.MapAtoAsize;i++) { + values[i] = FLOAT_TO_USHORT( ctx->Pixel.MapAtoA[i] ); + } + break; + default: + _mesa_error( ctx, GL_INVALID_ENUM, "glGetPixelMapfv" ); + } +} + + + +/**********************************************************************/ +/***** glPixelTransfer *****/ +/**********************************************************************/ + + +/* + * Implements glPixelTransfer[fi] whether called immediately or from a + * display list. + */ +void +_mesa_PixelTransferf( GLenum pname, GLfloat param ) +{ + GET_CURRENT_CONTEXT(ctx); + ASSERT_OUTSIDE_BEGIN_END(ctx); + + switch (pname) { + case GL_MAP_COLOR: + if (ctx->Pixel.MapColorFlag == param ? GL_TRUE : GL_FALSE) + return; + FLUSH_VERTICES(ctx, _NEW_PIXEL); + ctx->Pixel.MapColorFlag = param ? GL_TRUE : GL_FALSE; + break; + case GL_MAP_STENCIL: + if (ctx->Pixel.MapStencilFlag == param ? GL_TRUE : GL_FALSE) + return; + FLUSH_VERTICES(ctx, _NEW_PIXEL); + ctx->Pixel.MapStencilFlag = param ? GL_TRUE : GL_FALSE; + break; + case GL_INDEX_SHIFT: + if (ctx->Pixel.IndexShift == (GLint) param) + return; + FLUSH_VERTICES(ctx, _NEW_PIXEL); + ctx->Pixel.IndexShift = (GLint) param; + break; + case GL_INDEX_OFFSET: + if (ctx->Pixel.IndexOffset == (GLint) param) + return; + FLUSH_VERTICES(ctx, _NEW_PIXEL); + ctx->Pixel.IndexOffset = (GLint) param; + break; + case GL_RED_SCALE: + if (ctx->Pixel.RedScale == param) + return; + FLUSH_VERTICES(ctx, _NEW_PIXEL); + ctx->Pixel.RedScale = param; + break; + case GL_RED_BIAS: + if (ctx->Pixel.RedBias == param) + return; + FLUSH_VERTICES(ctx, _NEW_PIXEL); + ctx->Pixel.RedBias = param; + break; + case GL_GREEN_SCALE: + if (ctx->Pixel.GreenScale == param) + return; + FLUSH_VERTICES(ctx, _NEW_PIXEL); + ctx->Pixel.GreenScale = param; + break; + case GL_GREEN_BIAS: + if (ctx->Pixel.GreenBias == param) + return; + FLUSH_VERTICES(ctx, _NEW_PIXEL); + ctx->Pixel.GreenBias = param; + break; + case GL_BLUE_SCALE: + if (ctx->Pixel.BlueScale == param) + return; + FLUSH_VERTICES(ctx, _NEW_PIXEL); + ctx->Pixel.BlueScale = param; + break; + case GL_BLUE_BIAS: + if (ctx->Pixel.BlueBias == param) + return; + FLUSH_VERTICES(ctx, _NEW_PIXEL); + ctx->Pixel.BlueBias = param; + break; + case GL_ALPHA_SCALE: + if (ctx->Pixel.AlphaScale == param) + return; + FLUSH_VERTICES(ctx, _NEW_PIXEL); + ctx->Pixel.AlphaScale = param; + break; + case GL_ALPHA_BIAS: + if (ctx->Pixel.AlphaBias == param) + return; + FLUSH_VERTICES(ctx, _NEW_PIXEL); + ctx->Pixel.AlphaBias = param; + break; + case GL_DEPTH_SCALE: + if (ctx->Pixel.DepthScale == param) + return; + FLUSH_VERTICES(ctx, _NEW_PIXEL); + ctx->Pixel.DepthScale = param; + break; + case GL_DEPTH_BIAS: + if (ctx->Pixel.DepthBias == param) + return; + FLUSH_VERTICES(ctx, _NEW_PIXEL); + ctx->Pixel.DepthBias = param; + break; + case GL_POST_COLOR_MATRIX_RED_SCALE: + if (ctx->Pixel.PostColorMatrixScale[0] == param) + return; + FLUSH_VERTICES(ctx, _NEW_PIXEL); + ctx->Pixel.PostColorMatrixScale[0] = param; + break; + case GL_POST_COLOR_MATRIX_RED_BIAS: + if (ctx->Pixel.PostColorMatrixBias[0] == param) + return; + FLUSH_VERTICES(ctx, _NEW_PIXEL); + ctx->Pixel.PostColorMatrixBias[0] = param; + break; + case GL_POST_COLOR_MATRIX_GREEN_SCALE: + if (ctx->Pixel.PostColorMatrixScale[1] == param) + return; + FLUSH_VERTICES(ctx, _NEW_PIXEL); + ctx->Pixel.PostColorMatrixScale[1] = param; + break; + case GL_POST_COLOR_MATRIX_GREEN_BIAS: + if (ctx->Pixel.PostColorMatrixBias[1] == param) + return; + FLUSH_VERTICES(ctx, _NEW_PIXEL); + ctx->Pixel.PostColorMatrixBias[1] = param; + break; + case GL_POST_COLOR_MATRIX_BLUE_SCALE: + if (ctx->Pixel.PostColorMatrixScale[2] == param) + return; + FLUSH_VERTICES(ctx, _NEW_PIXEL); + ctx->Pixel.PostColorMatrixScale[2] = param; + break; + case GL_POST_COLOR_MATRIX_BLUE_BIAS: + if (ctx->Pixel.PostColorMatrixBias[2] == param) + return; + FLUSH_VERTICES(ctx, _NEW_PIXEL); + ctx->Pixel.PostColorMatrixBias[2] = param; + break; + case GL_POST_COLOR_MATRIX_ALPHA_SCALE: + if (ctx->Pixel.PostColorMatrixScale[3] == param) + return; + FLUSH_VERTICES(ctx, _NEW_PIXEL); + ctx->Pixel.PostColorMatrixScale[3] = param; + break; + case GL_POST_COLOR_MATRIX_ALPHA_BIAS: + if (ctx->Pixel.PostColorMatrixBias[3] == param) + return; + FLUSH_VERTICES(ctx, _NEW_PIXEL); + ctx->Pixel.PostColorMatrixBias[3] = param; + break; + case GL_POST_CONVOLUTION_RED_SCALE: + if (ctx->Pixel.PostConvolutionScale[0] == param) + return; + FLUSH_VERTICES(ctx, _NEW_PIXEL); + ctx->Pixel.PostConvolutionScale[0] = param; + break; + case GL_POST_CONVOLUTION_RED_BIAS: + if (ctx->Pixel.PostConvolutionBias[0] == param) + return; + FLUSH_VERTICES(ctx, _NEW_PIXEL); + ctx->Pixel.PostConvolutionBias[0] = param; + break; + case GL_POST_CONVOLUTION_GREEN_SCALE: + if (ctx->Pixel.PostConvolutionScale[1] == param) + return; + FLUSH_VERTICES(ctx, _NEW_PIXEL); + ctx->Pixel.PostConvolutionScale[1] = param; + break; + case GL_POST_CONVOLUTION_GREEN_BIAS: + if (ctx->Pixel.PostConvolutionBias[1] == param) + return; + FLUSH_VERTICES(ctx, _NEW_PIXEL); + ctx->Pixel.PostConvolutionBias[1] = param; + break; + case GL_POST_CONVOLUTION_BLUE_SCALE: + if (ctx->Pixel.PostConvolutionScale[2] == param) + return; + FLUSH_VERTICES(ctx, _NEW_PIXEL); + ctx->Pixel.PostConvolutionScale[2] = param; + break; + case GL_POST_CONVOLUTION_BLUE_BIAS: + if (ctx->Pixel.PostConvolutionBias[2] == param) + return; + FLUSH_VERTICES(ctx, _NEW_PIXEL); + ctx->Pixel.PostConvolutionBias[2] = param; + break; + case GL_POST_CONVOLUTION_ALPHA_SCALE: + if (ctx->Pixel.PostConvolutionScale[2] == param) + return; + FLUSH_VERTICES(ctx, _NEW_PIXEL); + ctx->Pixel.PostConvolutionScale[2] = param; + break; + case GL_POST_CONVOLUTION_ALPHA_BIAS: + if (ctx->Pixel.PostConvolutionBias[2] == param) + return; + FLUSH_VERTICES(ctx, _NEW_PIXEL); + ctx->Pixel.PostConvolutionBias[2] = param; + break; + default: + _mesa_error( ctx, GL_INVALID_ENUM, "glPixelTransfer(pname)" ); + return; + } +} + + +void +_mesa_PixelTransferi( GLenum pname, GLint param ) +{ + _mesa_PixelTransferf( pname, (GLfloat) param ); +} + + + +/**********************************************************************/ +/***** Pixel processing functions ******/ +/**********************************************************************/ + + +/* + * Apply scale and bias factors to an array of RGBA pixels. + */ +void +_mesa_scale_and_bias_rgba(const GLcontext *ctx, GLuint n, GLfloat rgba[][4], + GLfloat rScale, GLfloat gScale, + GLfloat bScale, GLfloat aScale, + GLfloat rBias, GLfloat gBias, + GLfloat bBias, GLfloat aBias) +{ + if (rScale != 1.0 || rBias != 0.0) { + GLuint i; + for (i = 0; i < n; i++) { + rgba[i][RCOMP] = rgba[i][RCOMP] * rScale + rBias; + } + } + if (gScale != 1.0 || gBias != 0.0) { + GLuint i; + for (i = 0; i < n; i++) { + rgba[i][GCOMP] = rgba[i][GCOMP] * gScale + gBias; + } + } + if (bScale != 1.0 || bBias != 0.0) { + GLuint i; + for (i = 0; i < n; i++) { + rgba[i][BCOMP] = rgba[i][BCOMP] * bScale + bBias; + } + } + if (aScale != 1.0 || aBias != 0.0) { + GLuint i; + for (i = 0; i < n; i++) { + rgba[i][ACOMP] = rgba[i][ACOMP] * aScale + aBias; + } + } +} + + +/* + * Apply pixel mapping to an array of floating point RGBA pixels. + */ +void +_mesa_map_rgba( const GLcontext *ctx, GLuint n, GLfloat rgba[][4] ) +{ + const GLfloat rscale = ctx->Pixel.MapRtoRsize - 1; + const GLfloat gscale = ctx->Pixel.MapGtoGsize - 1; + const GLfloat bscale = ctx->Pixel.MapBtoBsize - 1; + const GLfloat ascale = ctx->Pixel.MapAtoAsize - 1; + const GLfloat *rMap = ctx->Pixel.MapRtoR; + const GLfloat *gMap = ctx->Pixel.MapGtoG; + const GLfloat *bMap = ctx->Pixel.MapBtoB; + const GLfloat *aMap = ctx->Pixel.MapAtoA; + GLuint i; + for (i=0;iPixel.PostColorMatrixScale[0]; + const GLfloat rb = ctx->Pixel.PostColorMatrixBias[0]; + const GLfloat gs = ctx->Pixel.PostColorMatrixScale[1]; + const GLfloat gb = ctx->Pixel.PostColorMatrixBias[1]; + const GLfloat bs = ctx->Pixel.PostColorMatrixScale[2]; + const GLfloat bb = ctx->Pixel.PostColorMatrixBias[2]; + const GLfloat as = ctx->Pixel.PostColorMatrixScale[3]; + const GLfloat ab = ctx->Pixel.PostColorMatrixBias[3]; + const GLfloat *m = ctx->ColorMatrix.m; + GLuint i; + for (i = 0; i < n; i++) { + const GLfloat r = rgba[i][RCOMP]; + const GLfloat g = rgba[i][GCOMP]; + const GLfloat b = rgba[i][BCOMP]; + const GLfloat a = rgba[i][ACOMP]; + rgba[i][RCOMP] = (m[0] * r + m[4] * g + m[ 8] * b + m[12] * a) * rs + rb; + rgba[i][GCOMP] = (m[1] * r + m[5] * g + m[ 9] * b + m[13] * a) * gs + gb; + rgba[i][BCOMP] = (m[2] * r + m[6] * g + m[10] * b + m[14] * a) * bs + bb; + rgba[i][ACOMP] = (m[3] * r + m[7] * g + m[11] * b + m[15] * a) * as + ab; + } +} + + +/* + * Apply a color table lookup to an array of colors. + */ +void +_mesa_lookup_rgba(const struct gl_color_table *table, + GLuint n, GLfloat rgba[][4]) +{ + ASSERT(table->FloatTable); + if (!table->Table || table->Size == 0) + return; + + switch (table->Format) { + case GL_INTENSITY: + /* replace RGBA with I */ + if (!table->FloatTable) { + const GLint max = table->Size - 1; + const GLfloat scale = (GLfloat) max; + const GLchan *lut = (const GLchan *) table->Table; + GLuint i; + for (i = 0; i < n; i++) { + GLint j = IROUND(rgba[i][RCOMP] * scale); + GLfloat c = CHAN_TO_FLOAT(lut[CLAMP(j, 0, 1)]); + rgba[i][RCOMP] = rgba[i][GCOMP] = + rgba[i][BCOMP] = rgba[i][ACOMP] = c; + } + + } + else { + const GLint max = table->Size - 1; + const GLfloat scale = (GLfloat) max; + const GLfloat *lut = (const GLfloat *) table->Table; + GLuint i; + for (i = 0; i < n; i++) { + GLint j = IROUND(rgba[i][RCOMP] * scale); + GLfloat c = lut[CLAMP(j, 0, max)]; + rgba[i][RCOMP] = rgba[i][GCOMP] = + rgba[i][BCOMP] = rgba[i][ACOMP] = c; + } + } + break; + case GL_LUMINANCE: + /* replace RGB with L */ + if (!table->FloatTable) { + const GLint max = table->Size - 1; + const GLfloat scale = (GLfloat) max; + const GLchan *lut = (const GLchan *) table->Table; + GLuint i; + for (i = 0; i < n; i++) { + GLint j = IROUND(rgba[i][RCOMP] * scale); + GLfloat c = CHAN_TO_FLOAT(lut[CLAMP(j, 0, max)]); + rgba[i][RCOMP] = rgba[i][GCOMP] = rgba[i][BCOMP] = c; + } + } + else { + const GLint max = table->Size - 1; + const GLfloat scale = (GLfloat) max; + const GLfloat *lut = (const GLfloat *) table->Table; + GLuint i; + for (i = 0; i < n; i++) { + GLint j = IROUND(rgba[i][RCOMP] * scale); + GLfloat c = lut[CLAMP(j, 0, max)]; + rgba[i][RCOMP] = rgba[i][GCOMP] = rgba[i][BCOMP] = c; + } + } + break; + case GL_ALPHA: + /* replace A with A */ + if (!table->FloatTable) { + const GLint max = table->Size - 1; + const GLfloat scale = (GLfloat) max; + const GLchan *lut = (const GLchan *) table->Table; + GLuint i; + for (i = 0; i < n; i++) { + GLint j = IROUND(rgba[i][ACOMP] * scale); + rgba[i][ACOMP] = CHAN_TO_FLOAT(lut[CLAMP(j, 0, max)]); + } + } + else { + const GLint max = table->Size - 1; + const GLfloat scale = (GLfloat) max; + const GLfloat *lut = (const GLfloat *) table->Table; + GLuint i; + for (i = 0; i < n; i++) { + GLint j = IROUND(rgba[i][ACOMP] * scale); + rgba[i][ACOMP] = lut[CLAMP(j, 0, max)]; + } + } + break; + case GL_LUMINANCE_ALPHA: + /* replace RGBA with LLLA */ + if (!table->FloatTable) { + const GLint max = table->Size - 1; + const GLfloat scale = (GLfloat) max; + const GLchan *lut = (const GLchan *) table->Table; + GLuint i; + for (i = 0; i < n; i++) { + GLint jL = IROUND(rgba[i][RCOMP] * scale); + GLint jA = IROUND(rgba[i][ACOMP] * scale); + GLfloat luminance, alpha; + jL = CLAMP(jL, 0, max); + jA = CLAMP(jA, 0, max); + luminance = CHAN_TO_FLOAT(lut[jL * 2 + 0]); + alpha = CHAN_TO_FLOAT(lut[jA * 2 + 1]); + rgba[i][RCOMP] = rgba[i][GCOMP] = rgba[i][BCOMP] = luminance; + rgba[i][ACOMP] = alpha;; + } + } + else { + const GLint max = table->Size - 1; + const GLfloat scale = (GLfloat) max; + const GLfloat *lut = (const GLfloat *) table->Table; + GLuint i; + for (i = 0; i < n; i++) { + GLint jL = IROUND(rgba[i][RCOMP] * scale); + GLint jA = IROUND(rgba[i][ACOMP] * scale); + GLfloat luminance, alpha; + jL = CLAMP(jL, 0, max); + jA = CLAMP(jA, 0, max); + luminance = lut[jL * 2 + 0]; + alpha = lut[jA * 2 + 1]; + rgba[i][RCOMP] = rgba[i][GCOMP] = rgba[i][BCOMP] = luminance; + rgba[i][ACOMP] = alpha;; + } + } + break; + case GL_RGB: + /* replace RGB with RGB */ + if (!table->FloatTable) { + const GLint max = table->Size - 1; + const GLfloat scale = (GLfloat) max; + const GLchan *lut = (const GLchan *) table->Table; + GLuint i; + for (i = 0; i < n; i++) { + GLint jR = IROUND(rgba[i][RCOMP] * scale); + GLint jG = IROUND(rgba[i][GCOMP] * scale); + GLint jB = IROUND(rgba[i][BCOMP] * scale); + jR = CLAMP(jR, 0, max); + jG = CLAMP(jG, 0, max); + jB = CLAMP(jB, 0, max); + rgba[i][RCOMP] = CHAN_TO_FLOAT(lut[jR * 3 + 0]); + rgba[i][GCOMP] = CHAN_TO_FLOAT(lut[jG * 3 + 1]); + rgba[i][BCOMP] = CHAN_TO_FLOAT(lut[jB * 3 + 2]); + } + } + else { + const GLint max = table->Size - 1; + const GLfloat scale = (GLfloat) max; + const GLfloat *lut = (const GLfloat *) table->Table; + GLuint i; + for (i = 0; i < n; i++) { + GLint jR = IROUND(rgba[i][RCOMP] * scale); + GLint jG = IROUND(rgba[i][GCOMP] * scale); + GLint jB = IROUND(rgba[i][BCOMP] * scale); + jR = CLAMP(jR, 0, max); + jG = CLAMP(jG, 0, max); + jB = CLAMP(jB, 0, max); + rgba[i][RCOMP] = lut[jR * 3 + 0]; + rgba[i][GCOMP] = lut[jG * 3 + 1]; + rgba[i][BCOMP] = lut[jB * 3 + 2]; + } + } + break; + case GL_RGBA: + /* replace RGBA with RGBA */ + if (!table->FloatTable) { + const GLint max = table->Size - 1; + const GLfloat scale = (GLfloat) max; + const GLchan *lut = (const GLchan *) table->Table; + GLuint i; + for (i = 0; i < n; i++) { + GLint jR = IROUND(rgba[i][RCOMP] * scale); + GLint jG = IROUND(rgba[i][GCOMP] * scale); + GLint jB = IROUND(rgba[i][BCOMP] * scale); + GLint jA = IROUND(rgba[i][ACOMP] * scale); + jR = CLAMP(jR, 0, max); + jG = CLAMP(jG, 0, max); + jB = CLAMP(jB, 0, max); + jA = CLAMP(jA, 0, max); + rgba[i][RCOMP] = CHAN_TO_FLOAT(lut[jR * 4 + 0]); + rgba[i][GCOMP] = CHAN_TO_FLOAT(lut[jG * 4 + 1]); + rgba[i][BCOMP] = CHAN_TO_FLOAT(lut[jB * 4 + 2]); + rgba[i][ACOMP] = CHAN_TO_FLOAT(lut[jA * 4 + 3]); + } + } + else { + const GLint max = table->Size - 1; + const GLfloat scale = (GLfloat) max; + const GLfloat *lut = (const GLfloat *) table->Table; + GLuint i; + for (i = 0; i < n; i++) { + GLint jR = IROUND(rgba[i][RCOMP] * scale); + GLint jG = IROUND(rgba[i][GCOMP] * scale); + GLint jB = IROUND(rgba[i][BCOMP] * scale); + GLint jA = IROUND(rgba[i][ACOMP] * scale); + jR = CLAMP(jR, 0, max); + jG = CLAMP(jG, 0, max); + jB = CLAMP(jB, 0, max); + jA = CLAMP(jA, 0, max); + rgba[i][RCOMP] = lut[jR * 4 + 0]; + rgba[i][GCOMP] = lut[jG * 4 + 1]; + rgba[i][BCOMP] = lut[jB * 4 + 2]; + rgba[i][ACOMP] = lut[jA * 4 + 3]; + } + } + break; + default: + _mesa_problem(NULL, "Bad format in _mesa_lookup_rgba"); + return; + } +} + + + +/* + * Apply color index shift and offset to an array of pixels. + */ +void +_mesa_shift_and_offset_ci( const GLcontext *ctx, GLuint n, GLuint indexes[] ) +{ + GLint shift = ctx->Pixel.IndexShift; + GLint offset = ctx->Pixel.IndexOffset; + GLuint i; + if (shift > 0) { + for (i=0;i> shift) + offset; + } + } + else { + for (i=0;iPixel.MapItoIsize - 1; + GLuint i; + for (i=0;iPixel.MapItoI[ index[i] & mask ]; + } +} + + +/* + * Map color indexes to rgba values. + */ +void +_mesa_map_ci_to_rgba_chan( const GLcontext *ctx, GLuint n, + const GLuint index[], GLchan rgba[][4] ) +{ +#if CHAN_BITS == 8 + GLuint rmask = ctx->Pixel.MapItoRsize - 1; + GLuint gmask = ctx->Pixel.MapItoGsize - 1; + GLuint bmask = ctx->Pixel.MapItoBsize - 1; + GLuint amask = ctx->Pixel.MapItoAsize - 1; + const GLubyte *rMap = ctx->Pixel.MapItoR8; + const GLubyte *gMap = ctx->Pixel.MapItoG8; + const GLubyte *bMap = ctx->Pixel.MapItoB8; + const GLubyte *aMap = ctx->Pixel.MapItoA8; + GLuint i; + for (i=0;iPixel.MapItoRsize - 1; + GLuint gmask = ctx->Pixel.MapItoGsize - 1; + GLuint bmask = ctx->Pixel.MapItoBsize - 1; + GLuint amask = ctx->Pixel.MapItoAsize - 1; + const GLfloat *rMap = ctx->Pixel.MapItoR; + const GLfloat *gMap = ctx->Pixel.MapItoG; + const GLfloat *bMap = ctx->Pixel.MapItoB; + const GLfloat *aMap = ctx->Pixel.MapItoA; + GLuint i; + for (i=0;iPixel.MapItoRsize - 1; + GLuint gmask = ctx->Pixel.MapItoGsize - 1; + GLuint bmask = ctx->Pixel.MapItoBsize - 1; + GLuint amask = ctx->Pixel.MapItoAsize - 1; + const GLfloat *rMap = ctx->Pixel.MapItoR; + const GLfloat *gMap = ctx->Pixel.MapItoG; + const GLfloat *bMap = ctx->Pixel.MapItoB; + const GLfloat *aMap = ctx->Pixel.MapItoA; + GLuint i; + for (i=0;iPixel.MapItoRsize - 1; + GLuint gmask = ctx->Pixel.MapItoGsize - 1; + GLuint bmask = ctx->Pixel.MapItoBsize - 1; + GLuint amask = ctx->Pixel.MapItoAsize - 1; + const GLubyte *rMap = ctx->Pixel.MapItoR8; + const GLubyte *gMap = ctx->Pixel.MapItoG8; + const GLubyte *bMap = ctx->Pixel.MapItoB8; + const GLubyte *aMap = ctx->Pixel.MapItoA8; + GLuint i; + for (i=0;iPixel.MapItoRsize - 1; + GLuint gmask = ctx->Pixel.MapItoGsize - 1; + GLuint bmask = ctx->Pixel.MapItoBsize - 1; + GLuint amask = ctx->Pixel.MapItoAsize - 1; + const GLfloat *rMap = ctx->Pixel.MapItoR; + const GLfloat *gMap = ctx->Pixel.MapItoG; + const GLfloat *bMap = ctx->Pixel.MapItoB; + const GLfloat *aMap = ctx->Pixel.MapItoA; + GLuint i; + for (i=0;iPixel.IndexShift; + GLint offset = ctx->Pixel.IndexOffset; + if (shift > 0) { + for (i=0;i> shift) + offset; + } + } + else { + for (i=0;iPixel.MapStoSsize - 1; + GLuint i; + for (i=0;iPixel.MapStoS[ stencil[i] & mask ]; + } +} + + + +/* + * This function converts an array of GLchan colors to GLfloat colors. + * Most importantly, it undoes the non-uniform quantization of pixel + * values introduced when we convert shallow (< 8 bit) pixel values + * to GLubytes in the ctx->Driver.ReadRGBASpan() functions. + * This fixes a number of OpenGL conformance failures when running on + * 16bpp displays, for example. + */ +void +_mesa_chan_to_float_span(const GLcontext *ctx, GLuint n, + CONST GLchan rgba[][4], GLfloat rgbaf[][4]) +{ + const GLuint rShift = CHAN_BITS - ctx->Visual.redBits; + const GLuint gShift = CHAN_BITS - ctx->Visual.greenBits; + const GLuint bShift = CHAN_BITS - ctx->Visual.blueBits; + GLuint aShift; + const GLfloat rScale = 1.0 / (GLfloat) ((1 << ctx->Visual.redBits ) - 1); + const GLfloat gScale = 1.0 / (GLfloat) ((1 << ctx->Visual.greenBits) - 1); + const GLfloat bScale = 1.0 / (GLfloat) ((1 << ctx->Visual.blueBits ) - 1); + GLfloat aScale; + GLuint i; + + if (ctx->Visual.alphaBits > 0) { + aShift = CHAN_BITS - ctx->Visual.alphaBits; + aScale = 1.0 / (GLfloat) ((1 << ctx->Visual.alphaBits) - 1); + } + else { + aShift = 0; + aScale = 1.0F / CHAN_MAXF; + } + + for (i = 0; i < n; i++) { + const GLint r = rgba[i][RCOMP] >> rShift; + const GLint g = rgba[i][GCOMP] >> gShift; + const GLint b = rgba[i][BCOMP] >> bShift; + const GLint a = rgba[i][ACOMP] >> aShift; + rgbaf[i][RCOMP] = (GLfloat) r * rScale; + rgbaf[i][GCOMP] = (GLfloat) g * gScale; + rgbaf[i][BCOMP] = (GLfloat) b * bScale; + rgbaf[i][ACOMP] = (GLfloat) a * aScale; + } +} Index: dll/opengl/opengl32/mesa/pixel.h =================================================================== --- dll/opengl/opengl32/mesa/pixel.h (revision 0) +++ dll/opengl/opengl32/mesa/pixel.h (working copy) @@ -0,0 +1,139 @@ +/* $Id: pixel.h,v 1.10 2001/03/12 00:48:38 gareth Exp $ */ + +/* + * Mesa 3-D graphics library + * Version: 3.5 + * + * Copyright (C) 1999-2001 Brian Paul 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 + * BRIAN PAUL 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. + */ + + +#ifndef PIXEL_H +#define PIXEL_H + + +#include "mtypes.h" + + +/* + * API functions + */ + + +extern void +_mesa_GetPixelMapfv( GLenum map, GLfloat *values ); + +extern void +_mesa_GetPixelMapuiv( GLenum map, GLuint *values ); + +extern void +_mesa_GetPixelMapusv( GLenum map, GLushort *values ); + +extern void +_mesa_PixelMapfv( GLenum map, GLint mapsize, const GLfloat *values ); + +extern void +_mesa_PixelMapuiv(GLenum map, GLint mapsize, const GLuint *values ); + +extern void +_mesa_PixelMapusv(GLenum map, GLint mapsize, const GLushort *values ); + +extern void +_mesa_PixelStoref( GLenum pname, GLfloat param ); + +extern void +_mesa_PixelStorei( GLenum pname, GLint param ); + +extern void +_mesa_PixelTransferf( GLenum pname, GLfloat param ); + +extern void +_mesa_PixelTransferi( GLenum pname, GLint param ); + +extern void +_mesa_PixelZoom( GLfloat xfactor, GLfloat yfactor ); + + + +/* + * Pixel processing functions + */ + +extern void +_mesa_scale_and_bias_rgba(const GLcontext *ctx, GLuint n, GLfloat rgba[][4], + GLfloat rScale, GLfloat gScale, + GLfloat bScale, GLfloat aScale, + GLfloat rBias, GLfloat gBias, + GLfloat bBias, GLfloat aBias); + +extern void +_mesa_map_rgba(const GLcontext *ctx, GLuint n, GLfloat rgba[][4]); + + +extern void +_mesa_transform_rgba(const GLcontext *ctx, GLuint n, GLfloat rgba[][4]); + + +extern void +_mesa_lookup_rgba(const struct gl_color_table *table, + GLuint n, GLfloat rgba[][4]); + + +extern void +_mesa_shift_and_offset_ci(const GLcontext *ctx, GLuint n, + GLuint indexes[]); + + +extern void +_mesa_map_ci(const GLcontext *ctx, GLuint n, GLuint index[]); + + +extern void +_mesa_map_ci_to_rgba_chan(const GLcontext *ctx, + GLuint n, const GLuint index[], + GLchan rgba[][4]); + + +extern void +_mesa_map_ci_to_rgba(const GLcontext *ctx, + GLuint n, const GLuint index[], GLfloat rgba[][4]); + + +extern void +_mesa_map_ci8_to_rgba(const GLcontext *ctx, + GLuint n, const GLubyte index[], + GLchan rgba[][4]); + + +extern void +_mesa_shift_and_offset_stencil(const GLcontext *ctx, GLuint n, + GLstencil indexes[]); + + +extern void +_mesa_map_stencil(const GLcontext *ctx, GLuint n, GLstencil index[]); + + +extern void +_mesa_chan_to_float_span(const GLcontext *ctx, GLuint n, + CONST GLchan rgba[][4], GLfloat rgbaf[][4]); + + +#endif Index: dll/opengl/opengl32/mesa/points.c =================================================================== --- dll/opengl/opengl32/mesa/points.c (revision 0) +++ dll/opengl/opengl32/mesa/points.c (working copy) @@ -0,0 +1,147 @@ +/* $Id: points.c,v 1.31 2001/03/29 21:16:25 keithw Exp $ */ + +/* + * Mesa 3-D graphics library + * Version: 3.5 + * + * Copyright (C) 1999-2001 Brian Paul 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 + * BRIAN PAUL 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. + */ + + +#ifdef PC_HEADER +#include "all.h" +#else +#include "glheader.h" +#include "context.h" +#include "macros.h" +#include "mmath.h" +#include "points.h" +#include "texstate.h" +#include "mtypes.h" +#endif + + + +void +_mesa_PointSize( GLfloat size ) +{ + GET_CURRENT_CONTEXT(ctx); + ASSERT_OUTSIDE_BEGIN_END(ctx); + + if (size <= 0.0) { + _mesa_error( ctx, GL_INVALID_VALUE, "glPointSize" ); + return; + } + + if (ctx->Point.Size == size) + return; + + FLUSH_VERTICES(ctx, _NEW_POINT); + ctx->Point.Size = size; + ctx->Point._Size = CLAMP(size, + ctx->Const.MinPointSize, + ctx->Const.MaxPointSize); + + if (ctx->Point._Size == 1.0F) + ctx->_TriangleCaps &= ~DD_POINT_SIZE; + else + ctx->_TriangleCaps |= DD_POINT_SIZE; + + if (ctx->Driver.PointSize) + (*ctx->Driver.PointSize)(ctx, size); +} + + + +void +_mesa_PointParameterfEXT( GLenum pname, GLfloat param) +{ + _mesa_PointParameterfvEXT(pname, ¶m); +} + + +void +_mesa_PointParameterfvEXT( GLenum pname, const GLfloat *params) +{ + GET_CURRENT_CONTEXT(ctx); + ASSERT_OUTSIDE_BEGIN_END(ctx); + + switch (pname) { + case GL_DISTANCE_ATTENUATION_EXT: + { + const GLboolean tmp = ctx->Point._Attenuated; + if (TEST_EQ_3V(ctx->Point.Params, params)) + return; + + FLUSH_VERTICES(ctx, _NEW_POINT); + COPY_3V(ctx->Point.Params, params); + + /* Update several derived values now. This likely to be + * more efficient than trying to catch this statechange in + * state.c. + */ + ctx->Point._Attenuated = (params[0] != 1.0 || + params[1] != 0.0 || + params[2] != 0.0); + + if (tmp != ctx->Point._Attenuated) { + ctx->_TriangleCaps ^= DD_POINT_ATTEN; + ctx->_NeedEyeCoords ^= NEED_EYE_POINT_ATTEN; + } + } + break; + case GL_POINT_SIZE_MIN_EXT: + if (*params < 0.0F) { + _mesa_error( ctx, GL_INVALID_VALUE, "glPointParameterfvEXT" ); + return; + } + if (ctx->Point.MinSize == *params) + return; + FLUSH_VERTICES(ctx, _NEW_POINT); + ctx->Point.MinSize = *params; + break; + case GL_POINT_SIZE_MAX_EXT: + if (*params < 0.0F) { + _mesa_error( ctx, GL_INVALID_VALUE, "glPointParameterfvEXT" ); + return; + } + if (ctx->Point.MaxSize == *params) + return; + FLUSH_VERTICES(ctx, _NEW_POINT); + ctx->Point.MaxSize = *params; + break; + case GL_POINT_FADE_THRESHOLD_SIZE_EXT: + if (*params < 0.0F) { + _mesa_error( ctx, GL_INVALID_VALUE, "glPointParameterfvEXT" ); + return; + } + if (ctx->Point.Threshold == *params) + return; + FLUSH_VERTICES(ctx, _NEW_POINT); + ctx->Point.Threshold = *params; + break; + default: + _mesa_error( ctx, GL_INVALID_ENUM, "glPointParameterfvEXT" ); + return; + } + + if (ctx->Driver.PointParameterfv) + (*ctx->Driver.PointParameterfv)(ctx, pname, params); +} Index: dll/opengl/opengl32/mesa/points.h =================================================================== --- dll/opengl/opengl32/mesa/points.h (revision 0) +++ dll/opengl/opengl32/mesa/points.h (working copy) @@ -0,0 +1,51 @@ +/* $Id: points.h,v 1.5 2001/03/12 00:48:38 gareth Exp $ */ + +/* + * Mesa 3-D graphics library + * Version: 3.5 + * + * Copyright (C) 1999-2001 Brian Paul 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 + * BRIAN PAUL 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. + */ + + + + + +#ifndef POINTS_H +#define POINTS_H + + +#include "mtypes.h" + + +extern void +_mesa_PointSize( GLfloat size ); + + +extern void +_mesa_PointParameterfEXT( GLenum pname, GLfloat param); + + +extern void +_mesa_PointParameterfvEXT( GLenum pname, const GLfloat *params ); + + + +#endif Index: dll/opengl/opengl32/mesa/polygon.c =================================================================== --- dll/opengl/opengl32/mesa/polygon.c (revision 0) +++ dll/opengl/opengl32/mesa/polygon.c (working copy) @@ -0,0 +1,211 @@ +/* $Id: polygon.c,v 1.21 2001/03/22 00:36:27 gareth Exp $ */ + +/* + * Mesa 3-D graphics library + * Version: 3.5 + * + * Copyright (C) 1999-2001 Brian Paul 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 + * BRIAN PAUL 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. + */ + + +#ifdef PC_HEADER +#include "all.h" +#else +#include "glheader.h" +#include "context.h" +#include "image.h" +#include "enums.h" +#include "macros.h" +#include "mem.h" +#include "polygon.h" +#include "mtypes.h" +#endif + + + +void +_mesa_CullFace( GLenum mode ) +{ + GET_CURRENT_CONTEXT(ctx); + ASSERT_OUTSIDE_BEGIN_END(ctx); + + if (MESA_VERBOSE&VERBOSE_API) + fprintf(stderr, "glCullFace %s\n", _mesa_lookup_enum_by_nr(mode)); + + if (mode!=GL_FRONT && mode!=GL_BACK && mode!=GL_FRONT_AND_BACK) { + _mesa_error( ctx, GL_INVALID_ENUM, "glCullFace" ); + return; + } + + if (ctx->Polygon.CullFaceMode == mode) + return; + + FLUSH_VERTICES(ctx, _NEW_POLYGON); + ctx->Polygon.CullFaceMode = mode; + + if (ctx->Driver.CullFace) + ctx->Driver.CullFace( ctx, mode ); +} + + + +void +_mesa_FrontFace( GLenum mode ) +{ + GET_CURRENT_CONTEXT(ctx); + ASSERT_OUTSIDE_BEGIN_END(ctx); + + if (MESA_VERBOSE&VERBOSE_API) + fprintf(stderr, "glFrontFace %s\n", _mesa_lookup_enum_by_nr(mode)); + + if (mode!=GL_CW && mode!=GL_CCW) { + _mesa_error( ctx, GL_INVALID_ENUM, "glFrontFace" ); + return; + } + + if (ctx->Polygon.FrontFace == mode) + return; + + FLUSH_VERTICES(ctx, _NEW_POLYGON); + ctx->Polygon.FrontFace = mode; + + ctx->Polygon._FrontBit = (GLboolean) (mode == GL_CW); + + if (ctx->Driver.FrontFace) + ctx->Driver.FrontFace( ctx, mode ); +} + + + +void +_mesa_PolygonMode( GLenum face, GLenum mode ) +{ + GET_CURRENT_CONTEXT(ctx); + ASSERT_OUTSIDE_BEGIN_END(ctx); + + if (MESA_VERBOSE&VERBOSE_API) + fprintf(stderr, "glPolygonMode %s %s\n", + _mesa_lookup_enum_by_nr(face), + _mesa_lookup_enum_by_nr(mode)); + + if (mode!=GL_POINT && mode!=GL_LINE && mode!=GL_FILL) { + _mesa_error( ctx, GL_INVALID_ENUM, "glPolygonMode(mode)" ); + return; + } + + switch (face) { + case GL_FRONT: + if (ctx->Polygon.FrontMode == mode) + return; + FLUSH_VERTICES(ctx, _NEW_POLYGON); + ctx->Polygon.FrontMode = mode; + break; + case GL_FRONT_AND_BACK: + if (ctx->Polygon.FrontMode == mode && + ctx->Polygon.BackMode == mode) + return; + FLUSH_VERTICES(ctx, _NEW_POLYGON); + ctx->Polygon.FrontMode = mode; + ctx->Polygon.BackMode = mode; + break; + case GL_BACK: + if (ctx->Polygon.BackMode == mode) + return; + FLUSH_VERTICES(ctx, _NEW_POLYGON); + ctx->Polygon.BackMode = mode; + break; + default: + _mesa_error( ctx, GL_INVALID_ENUM, "glPolygonMode(face)" ); + return; + } + + ctx->_TriangleCaps &= ~DD_TRI_UNFILLED; + if (ctx->Polygon.FrontMode!=GL_FILL || ctx->Polygon.BackMode!=GL_FILL) + ctx->_TriangleCaps |= DD_TRI_UNFILLED; + + if (ctx->Driver.PolygonMode) { + (*ctx->Driver.PolygonMode)( ctx, face, mode ); + } +} + + + +void +_mesa_PolygonStipple( const GLubyte *pattern ) +{ + GET_CURRENT_CONTEXT(ctx); + ASSERT_OUTSIDE_BEGIN_END(ctx); + + if (MESA_VERBOSE&VERBOSE_API) + fprintf(stderr, "glPolygonStipple\n"); + + FLUSH_VERTICES(ctx, _NEW_POLYGONSTIPPLE); + _mesa_unpack_polygon_stipple(pattern, ctx->PolygonStipple, &ctx->Unpack); + + if (ctx->Driver.PolygonStipple) + ctx->Driver.PolygonStipple( ctx, (const GLubyte *) ctx->PolygonStipple ); +} + + + +void +_mesa_GetPolygonStipple( GLubyte *dest ) +{ + GET_CURRENT_CONTEXT(ctx); + ASSERT_OUTSIDE_BEGIN_END(ctx); + + if (MESA_VERBOSE&VERBOSE_API) + fprintf(stderr, "glGetPolygonStipple\n"); + + _mesa_pack_polygon_stipple(ctx->PolygonStipple, dest, &ctx->Pack); +} + + + +void +_mesa_PolygonOffset( GLfloat factor, GLfloat units ) +{ + GET_CURRENT_CONTEXT(ctx); + ASSERT_OUTSIDE_BEGIN_END(ctx); + + if (MESA_VERBOSE&VERBOSE_API) + fprintf(stderr, "glPolygonOffset %f %f\n", factor, units); + + if (ctx->Polygon.OffsetFactor == factor && + ctx->Polygon.OffsetUnits == units) + return; + + FLUSH_VERTICES(ctx, _NEW_POLYGON); + ctx->Polygon.OffsetFactor = factor; + ctx->Polygon.OffsetUnits = units; + ctx->Polygon.OffsetMRD = units * ctx->MRD; + + if (ctx->Driver.PolygonOffset) + ctx->Driver.PolygonOffset( ctx, factor, units ); +} + + + +void +_mesa_PolygonOffsetEXT( GLfloat factor, GLfloat bias ) +{ + GET_CURRENT_CONTEXT(ctx); + _mesa_PolygonOffset(factor, bias * ctx->DepthMaxF ); +} Index: dll/opengl/opengl32/mesa/polygon.h =================================================================== --- dll/opengl/opengl32/mesa/polygon.h (revision 0) +++ dll/opengl/opengl32/mesa/polygon.h (working copy) @@ -0,0 +1,57 @@ +/* $Id: polygon.h,v 1.4 2001/03/12 00:48:38 gareth Exp $ */ + +/* + * Mesa 3-D graphics library + * Version: 3.5 + * + * Copyright (C) 1999-2001 Brian Paul 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 + * BRIAN PAUL 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. + */ + + +#ifndef POLYGON_H +#define POLYGON_H + + +#include "mtypes.h" + + +extern void +_mesa_CullFace( GLenum mode ); + +extern void +_mesa_FrontFace( GLenum mode ); + +extern void +_mesa_PolygonMode( GLenum face, GLenum mode ); + +extern void +_mesa_PolygonOffset( GLfloat factor, GLfloat units ); + +extern void +_mesa_PolygonOffsetEXT( GLfloat factor, GLfloat bias ); + +extern void +_mesa_PolygonStipple( const GLubyte *mask ); + +extern void +_mesa_GetPolygonStipple( GLubyte *mask ); + + +#endif Index: dll/opengl/opengl32/mesa/rastpos.c =================================================================== --- dll/opengl/opengl32/mesa/rastpos.c (revision 0) +++ dll/opengl/opengl32/mesa/rastpos.c (working copy) @@ -0,0 +1,720 @@ +/* $Id: rastpos.c,v 1.26 2001/06/18 17:26:08 brianp Exp $ */ + +/* + * Mesa 3-D graphics library + * Version: 3.5 + * + * Copyright (C) 1999-2001 Brian Paul 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 + * BRIAN PAUL 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. + */ + + +#ifdef PC_HEADER +#include "all.h" +#else +#include "glheader.h" +#include "clip.h" +#include "colormac.h" +#include "context.h" +#include "feedback.h" +#include "light.h" +#include "macros.h" +#include "mmath.h" +#include "rastpos.h" +#include "state.h" +#include "simple_list.h" +#include "mtypes.h" + +#include "math/m_matrix.h" +#include "math/m_xform.h" +#endif + + +/* + * Clip a point against the view volume. + * Input: v - vertex-vector describing the point to clip + * Return: 0 = outside view volume + * 1 = inside view volume + */ +static GLuint +viewclip_point( const GLfloat v[] ) +{ + if ( v[0] > v[3] || v[0] < -v[3] + || v[1] > v[3] || v[1] < -v[3] + || v[2] > v[3] || v[2] < -v[3] ) { + return 0; + } + else { + return 1; + } +} + + +/* + * Clip a point against the user clipping planes. + * Input: v - vertex-vector describing the point to clip. + * Return: 0 = point was clipped + * 1 = point not clipped + */ +static GLuint +userclip_point( GLcontext* ctx, const GLfloat v[] ) +{ + GLuint p; + + for (p = 0; p < ctx->Const.MaxClipPlanes; p++) { + if (ctx->Transform.ClipEnabled[p]) { + GLfloat dot = v[0] * ctx->Transform._ClipUserPlane[p][0] + + v[1] * ctx->Transform._ClipUserPlane[p][1] + + v[2] * ctx->Transform._ClipUserPlane[p][2] + + v[3] * ctx->Transform._ClipUserPlane[p][3]; + if (dot < 0.0F) { + return 0; + } + } + } + + return 1; +} + + +/* This has been split off to allow the normal shade routines to + * get a little closer to the vertex buffer, and to use the + * GLvector objects directly. + */ +static void +shade_rastpos(GLcontext *ctx, + const GLfloat vertex[4], + const GLfloat normal[3], + GLfloat Rcolor[4], + GLuint *index) +{ + GLfloat (*base)[3] = ctx->Light._BaseColor; + const GLfloat *sumA = ctx->Light._BaseAlpha; + struct gl_light *light; + GLfloat color[4]; + GLfloat diffuse = 0, specular = 0; + + COPY_3V(color, base[0]); + color[3] = sumA[0]; + + foreach (light, &ctx->Light.EnabledList) { + GLfloat n_dot_h; + GLfloat attenuation = 1.0; + GLfloat VP[3]; + GLfloat n_dot_VP; + GLfloat *h; + GLfloat contrib[3]; + GLboolean normalized; + + if (!(light->_Flags & LIGHT_POSITIONAL)) { + COPY_3V(VP, light->_VP_inf_norm); + attenuation = light->_VP_inf_spot_attenuation; + } + else { + GLfloat d; + + SUB_3V(VP, light->_Position, vertex); + d = LEN_3FV( VP ); + + if ( d > 1e-6) { + GLfloat invd = 1.0F / d; + SELF_SCALE_SCALAR_3V(VP, invd); + } + attenuation = 1.0F / (light->ConstantAttenuation + d * + (light->LinearAttenuation + d * + light->QuadraticAttenuation)); + + if (light->_Flags & LIGHT_SPOT) { + GLfloat PV_dot_dir = - DOT3(VP, light->_NormDirection); + + if (PV_dot_dir_CosCutoff) { + continue; + } + else { + double x = PV_dot_dir * (EXP_TABLE_SIZE-1); + int k = (int) x; + GLfloat spot = (GLfloat) (light->_SpotExpTable[k][0] + + (x-k)*light->_SpotExpTable[k][1]); + attenuation *= spot; + } + } + } + + if (attenuation < 1e-3) + continue; + + n_dot_VP = DOT3( normal, VP ); + + if (n_dot_VP < 0.0F) { + ACC_SCALE_SCALAR_3V(color, attenuation, light->_MatAmbient[0]); + continue; + } + + COPY_3V(contrib, light->_MatAmbient[0]); + ACC_SCALE_SCALAR_3V(contrib, n_dot_VP, light->_MatDiffuse[0]); + diffuse += n_dot_VP * light->_dli * attenuation; + + { + if (ctx->Light.Model.LocalViewer) { + GLfloat v[3]; + COPY_3V(v, vertex); + NORMALIZE_3FV(v); + SUB_3V(VP, VP, v); + h = VP; + normalized = 0; + } + else if (light->_Flags & LIGHT_POSITIONAL) { + h = VP; + ACC_3V(h, ctx->_EyeZDir); + normalized = 0; + } + else { + h = light->_h_inf_norm; + normalized = 1; + } + + n_dot_h = DOT3(normal, h); + + if (n_dot_h > 0.0F) { + struct gl_material *mat = &ctx->Light.Material[0]; + GLfloat spec_coef; + GLfloat shininess = mat->Shininess; + + if (!normalized) { + n_dot_h *= n_dot_h; + n_dot_h /= LEN_SQUARED_3FV( h ); + shininess *= .5; + } + + GET_SHINE_TAB_ENTRY( ctx->_ShineTable[0], n_dot_h, spec_coef ); + + if (spec_coef > 1.0e-10) { + ACC_SCALE_SCALAR_3V( contrib, spec_coef, + light->_MatSpecular[0]); + specular += spec_coef * light->_sli * attenuation; + } + } + } + + ACC_SCALE_SCALAR_3V( color, attenuation, contrib ); + } + + if (ctx->Visual.rgbMode) { + Rcolor[0] = CLAMP(color[0], 0.0F, 1.0F); + Rcolor[1] = CLAMP(color[1], 0.0F, 1.0F); + Rcolor[2] = CLAMP(color[2], 0.0F, 1.0F); + Rcolor[3] = CLAMP(color[3], 0.0F, 1.0F); + } + else { + struct gl_material *mat = &ctx->Light.Material[0]; + GLfloat d_a = mat->DiffuseIndex - mat->AmbientIndex; + GLfloat s_a = mat->SpecularIndex - mat->AmbientIndex; + GLfloat ind = mat->AmbientIndex + + diffuse * (1.0F-specular) * d_a + + specular * s_a; + if (ind > mat->SpecularIndex) { + ind = mat->SpecularIndex; + } + *index = (GLuint) (GLint) ind; + } + +} + +/* + * Caller: context->API.RasterPos4f + */ +static void +raster_pos4f(GLcontext *ctx, GLfloat x, GLfloat y, GLfloat z, GLfloat w) +{ + GLfloat v[4], eye[4], clip[4], ndc[3], d; + ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx); + FLUSH_CURRENT(ctx, 0); + + if (ctx->NewState) + _mesa_update_state( ctx ); + + ASSIGN_4V( v, x, y, z, w ); + TRANSFORM_POINT( eye, ctx->ModelView.m, v ); + + /* raster color */ + if (ctx->Light.Enabled) { + GLfloat *norm, eyenorm[3]; + GLfloat *objnorm = ctx->Current.Normal; + + if (ctx->_NeedEyeCoords) { + GLfloat *inv = ctx->ModelView.inv; + TRANSFORM_NORMAL( eyenorm, objnorm, inv ); + norm = eyenorm; + } + else { + norm = objnorm; + } + + shade_rastpos( ctx, v, norm, + ctx->Current.RasterColor, + &ctx->Current.RasterIndex ); + + } + else { + /* use current color or index */ + if (ctx->Visual.rgbMode) { + ctx->Current.RasterColor[0] = (ctx->Current.Color[0]); + ctx->Current.RasterColor[1] = (ctx->Current.Color[1]); + ctx->Current.RasterColor[2] = (ctx->Current.Color[2]); + ctx->Current.RasterColor[3] = (ctx->Current.Color[3]); + } + else { + ctx->Current.RasterIndex = ctx->Current.Index; + } + } + + /* compute raster distance */ + ctx->Current.RasterDistance = (GLfloat) + GL_SQRT( eye[0]*eye[0] + eye[1]*eye[1] + eye[2]*eye[2] ); + + /* apply projection matrix: clip = Proj * eye */ + TRANSFORM_POINT( clip, ctx->ProjectionMatrix.m, eye ); + + /* clip to view volume */ + if (viewclip_point( clip )==0) { + ctx->Current.RasterPosValid = GL_FALSE; + return; + } + + /* clip to user clipping planes */ + if (ctx->Transform._AnyClip && + userclip_point(ctx, clip) == 0) { + ctx->Current.RasterPosValid = GL_FALSE; + return; + } + + /* ndc = clip / W */ + ASSERT( clip[3]!=0.0 ); + d = 1.0F / clip[3]; + ndc[0] = clip[0] * d; + ndc[1] = clip[1] * d; + ndc[2] = clip[2] * d; + + ctx->Current.RasterPos[0] = (ndc[0] * ctx->Viewport._WindowMap.m[MAT_SX] + + ctx->Viewport._WindowMap.m[MAT_TX]); + ctx->Current.RasterPos[1] = (ndc[1] * ctx->Viewport._WindowMap.m[MAT_SY] + + ctx->Viewport._WindowMap.m[MAT_TY]); + ctx->Current.RasterPos[2] = (ndc[2] * ctx->Viewport._WindowMap.m[MAT_SZ] + + ctx->Viewport._WindowMap.m[MAT_TZ]) / ctx->DepthMaxF; + ctx->Current.RasterPos[3] = clip[3]; + ctx->Current.RasterPosValid = GL_TRUE; + + ctx->Current.RasterFogCoord = ctx->Current.FogCoord; + + { + GLuint texSet; + for (texSet = 0; texSet < ctx->Const.MaxTextureUnits; texSet++) { + COPY_4FV( ctx->Current.RasterMultiTexCoord[texSet], + ctx->Current.Texcoord[texSet] ); + } + } + + if (ctx->RenderMode==GL_SELECT) { + _mesa_update_hitflag( ctx, ctx->Current.RasterPos[2] ); + } + +} + + + +void +_mesa_RasterPos2d(GLdouble x, GLdouble y) +{ + _mesa_RasterPos4f(x, y, 0.0F, 1.0F); +} + +void +_mesa_RasterPos2f(GLfloat x, GLfloat y) +{ + _mesa_RasterPos4f(x, y, 0.0F, 1.0F); +} + +void +_mesa_RasterPos2i(GLint x, GLint y) +{ + _mesa_RasterPos4f(x, y, 0.0F, 1.0F); +} + +void +_mesa_RasterPos2s(GLshort x, GLshort y) +{ + _mesa_RasterPos4f(x, y, 0.0F, 1.0F); +} + +void +_mesa_RasterPos3d(GLdouble x, GLdouble y, GLdouble z) +{ + _mesa_RasterPos4f(x, y, z, 1.0F); +} + +void +_mesa_RasterPos3f(GLfloat x, GLfloat y, GLfloat z) +{ + _mesa_RasterPos4f(x, y, z, 1.0F); +} + +void +_mesa_RasterPos3i(GLint x, GLint y, GLint z) +{ + _mesa_RasterPos4f(x, y, z, 1.0F); +} + +void +_mesa_RasterPos3s(GLshort x, GLshort y, GLshort z) +{ + _mesa_RasterPos4f(x, y, z, 1.0F); +} + +void +_mesa_RasterPos4d(GLdouble x, GLdouble y, GLdouble z, GLdouble w) +{ + _mesa_RasterPos4f(x, y, z, w); +} + +void +_mesa_RasterPos4f(GLfloat x, GLfloat y, GLfloat z, GLfloat w) +{ + GET_CURRENT_CONTEXT(ctx); + raster_pos4f(ctx, x, y, z, w); +} + +void +_mesa_RasterPos4i(GLint x, GLint y, GLint z, GLint w) +{ + _mesa_RasterPos4f(x, y, z, w); +} + +void +_mesa_RasterPos4s(GLshort x, GLshort y, GLshort z, GLshort w) +{ + _mesa_RasterPos4f(x, y, z, w); +} + +void +_mesa_RasterPos2dv(const GLdouble *v) +{ + _mesa_RasterPos4f(v[0], v[1], 0.0F, 1.0F); +} + +void +_mesa_RasterPos2fv(const GLfloat *v) +{ + _mesa_RasterPos4f(v[0], v[1], 0.0F, 1.0F); +} + +void +_mesa_RasterPos2iv(const GLint *v) +{ + _mesa_RasterPos4f(v[0], v[1], 0.0F, 1.0F); +} + +void +_mesa_RasterPos2sv(const GLshort *v) +{ + _mesa_RasterPos4f(v[0], v[1], 0.0F, 1.0F); +} + +void +_mesa_RasterPos3dv(const GLdouble *v) +{ + _mesa_RasterPos4f(v[0], v[1], v[2], 1.0F); +} + +void +_mesa_RasterPos3fv(const GLfloat *v) +{ + _mesa_RasterPos4f(v[0], v[1], v[2], 1.0F); +} + +void +_mesa_RasterPos3iv(const GLint *v) +{ + _mesa_RasterPos4f(v[0], v[1], v[2], 1.0F); +} + +void +_mesa_RasterPos3sv(const GLshort *v) +{ + _mesa_RasterPos4f(v[0], v[1], v[2], 1.0F); +} + +void +_mesa_RasterPos4dv(const GLdouble *v) +{ + _mesa_RasterPos4f(v[0], v[1], v[2], v[3]); +} + +void +_mesa_RasterPos4fv(const GLfloat *v) +{ + _mesa_RasterPos4f(v[0], v[1], v[2], v[3]); +} + +void +_mesa_RasterPos4iv(const GLint *v) +{ + _mesa_RasterPos4f(v[0], v[1], v[2], v[3]); +} + +void +_mesa_RasterPos4sv(const GLshort *v) +{ + _mesa_RasterPos4f(v[0], v[1], v[2], v[3]); +} + + + +/**********************************************************************/ +/*** GL_MESA_window_pos ***/ +/**********************************************************************/ + + +/* + * This is a MESA extension function. Pretty much just like glRasterPos + * except we don't apply the modelview or projection matrices; specify a + * window coordinate directly. + * Caller: context->API.WindowPos4fMESA pointer. + */ +void +_mesa_WindowPos4fMESA( GLfloat x, GLfloat y, GLfloat z, GLfloat w ) +{ + GET_CURRENT_CONTEXT(ctx); + ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx); + FLUSH_CURRENT(ctx, 0); + + /* set raster position */ + ctx->Current.RasterPos[0] = x; + ctx->Current.RasterPos[1] = y; + ctx->Current.RasterPos[2] = CLAMP( z, 0.0F, 1.0F ); + ctx->Current.RasterPos[3] = w; + + ctx->Current.RasterPosValid = GL_TRUE; + ctx->Current.RasterDistance = 0.0F; + ctx->Current.RasterFogCoord = 0.0F; + + /* raster color = current color or index */ + if (ctx->Visual.rgbMode) { + ctx->Current.RasterColor[0] = (ctx->Current.Color[0]); + ctx->Current.RasterColor[1] = (ctx->Current.Color[1]); + ctx->Current.RasterColor[2] = (ctx->Current.Color[2]); + ctx->Current.RasterColor[3] = (ctx->Current.Color[3]); + } + else { + ctx->Current.RasterIndex = ctx->Current.Index; + } + + /* raster texcoord = current texcoord */ + { + GLuint texSet; + for (texSet = 0; texSet < ctx->Const.MaxTextureUnits; texSet++) { + COPY_4FV( ctx->Current.RasterMultiTexCoord[texSet], + ctx->Current.Texcoord[texSet] ); + } + } + + if (ctx->RenderMode==GL_SELECT) { + _mesa_update_hitflag( ctx, ctx->Current.RasterPos[2] ); + } +} + + + + +void +_mesa_WindowPos2dMESA(GLdouble x, GLdouble y) +{ + _mesa_WindowPos4fMESA(x, y, 0.0F, 1.0F); +} + +void +_mesa_WindowPos2fMESA(GLfloat x, GLfloat y) +{ + _mesa_WindowPos4fMESA(x, y, 0.0F, 1.0F); +} + +void +_mesa_WindowPos2iMESA(GLint x, GLint y) +{ + _mesa_WindowPos4fMESA(x, y, 0.0F, 1.0F); +} + +void +_mesa_WindowPos2sMESA(GLshort x, GLshort y) +{ + _mesa_WindowPos4fMESA(x, y, 0.0F, 1.0F); +} + +void +_mesa_WindowPos3dMESA(GLdouble x, GLdouble y, GLdouble z) +{ + _mesa_WindowPos4fMESA(x, y, z, 1.0F); +} + +void +_mesa_WindowPos3fMESA(GLfloat x, GLfloat y, GLfloat z) +{ + _mesa_WindowPos4fMESA(x, y, z, 1.0F); +} + +void +_mesa_WindowPos3iMESA(GLint x, GLint y, GLint z) +{ + _mesa_WindowPos4fMESA(x, y, z, 1.0F); +} + +void +_mesa_WindowPos3sMESA(GLshort x, GLshort y, GLshort z) +{ + _mesa_WindowPos4fMESA(x, y, z, 1.0F); +} + +void +_mesa_WindowPos4dMESA(GLdouble x, GLdouble y, GLdouble z, GLdouble w) +{ + _mesa_WindowPos4fMESA(x, y, z, w); +} + +void +_mesa_WindowPos4iMESA(GLint x, GLint y, GLint z, GLint w) +{ + _mesa_WindowPos4fMESA(x, y, z, w); +} + +void +_mesa_WindowPos4sMESA(GLshort x, GLshort y, GLshort z, GLshort w) +{ + _mesa_WindowPos4fMESA(x, y, z, w); +} + +void +_mesa_WindowPos2dvMESA(const GLdouble *v) +{ + _mesa_WindowPos4fMESA(v[0], v[1], 0.0F, 1.0F); +} + +void +_mesa_WindowPos2fvMESA(const GLfloat *v) +{ + _mesa_WindowPos4fMESA(v[0], v[1], 0.0F, 1.0F); +} + +void +_mesa_WindowPos2ivMESA(const GLint *v) +{ + _mesa_WindowPos4fMESA(v[0], v[1], 0.0F, 1.0F); +} + +void +_mesa_WindowPos2svMESA(const GLshort *v) +{ + _mesa_WindowPos4fMESA(v[0], v[1], 0.0F, 1.0F); +} + +void +_mesa_WindowPos3dvMESA(const GLdouble *v) +{ + _mesa_WindowPos4fMESA(v[0], v[1], v[2], 1.0F); +} + +void +_mesa_WindowPos3fvMESA(const GLfloat *v) +{ + _mesa_WindowPos4fMESA(v[0], v[1], v[2], 1.0F); +} + +void +_mesa_WindowPos3ivMESA(const GLint *v) +{ + _mesa_WindowPos4fMESA(v[0], v[1], v[2], 1.0F); +} + +void +_mesa_WindowPos3svMESA(const GLshort *v) +{ + _mesa_WindowPos4fMESA(v[0], v[1], v[2], 1.0F); +} + +void +_mesa_WindowPos4dvMESA(const GLdouble *v) +{ + _mesa_WindowPos4fMESA(v[0], v[1], v[2], v[3]); +} + +void +_mesa_WindowPos4fvMESA(const GLfloat *v) +{ + _mesa_WindowPos4fMESA(v[0], v[1], v[2], v[3]); +} + +void +_mesa_WindowPos4ivMESA(const GLint *v) +{ + _mesa_WindowPos4fMESA(v[0], v[1], v[2], v[3]); +} + +void +_mesa_WindowPos4svMESA(const GLshort *v) +{ + _mesa_WindowPos4fMESA(v[0], v[1], v[2], v[3]); +} + + + +#if 0 + +/* + * OpenGL implementation of glWindowPos*MESA() + */ +void glWindowPos4fMESA( GLfloat x, GLfloat y, GLfloat z, GLfloat w ) +{ + GLfloat fx, fy; + + /* Push current matrix mode and viewport attributes */ + glPushAttrib( GL_TRANSFORM_BIT | GL_VIEWPORT_BIT ); + + /* Setup projection parameters */ + glMatrixMode( GL_PROJECTION ); + glPushMatrix(); + glLoadIdentity(); + glMatrixMode( GL_MODELVIEW ); + glPushMatrix(); + glLoadIdentity(); + + glDepthRange( z, z ); + glViewport( (int) x - 1, (int) y - 1, 2, 2 ); + + /* set the raster (window) position */ + fx = x - (int) x; + fy = y - (int) y; + glRasterPos4f( fx, fy, 0.0, w ); + + /* restore matrices, viewport and matrix mode */ + glPopMatrix(); + glMatrixMode( GL_PROJECTION ); + glPopMatrix(); + + glPopAttrib(); +} + +#endif Index: dll/opengl/opengl32/mesa/rastpos.h =================================================================== --- dll/opengl/opengl32/mesa/rastpos.h (revision 0) +++ dll/opengl/opengl32/mesa/rastpos.h (working copy) @@ -0,0 +1,185 @@ +/* $Id: rastpos.h,v 1.4 2001/06/18 17:26:08 brianp Exp $ */ + +/* + * Mesa 3-D graphics library + * Version: 3.5 + * + * Copyright (C) 1999-2001 Brian Paul 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 + * BRIAN PAUL 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. + */ + + +#ifndef RASTPOS_H +#define RASTPOS_H + + +#include "glheader.h" + + +extern void +_mesa_RasterPos2d(GLdouble x, GLdouble y); + +extern void +_mesa_RasterPos2f(GLfloat x, GLfloat y); + +extern void +_mesa_RasterPos2i(GLint x, GLint y); + +extern void +_mesa_RasterPos2s(GLshort x, GLshort y); + +extern void +_mesa_RasterPos3d(GLdouble x, GLdouble y, GLdouble z); + +extern void +_mesa_RasterPos3f(GLfloat x, GLfloat y, GLfloat z); + +extern void +_mesa_RasterPos3i(GLint x, GLint y, GLint z); + +extern void +_mesa_RasterPos3s(GLshort x, GLshort y, GLshort z); + +extern void +_mesa_RasterPos4d(GLdouble x, GLdouble y, GLdouble z, GLdouble w); + +extern void +_mesa_RasterPos4f(GLfloat x, GLfloat y, GLfloat z, GLfloat w); + +extern void +_mesa_RasterPos4i(GLint x, GLint y, GLint z, GLint w); + +extern void +_mesa_RasterPos4s(GLshort x, GLshort y, GLshort z, GLshort w); + +extern void +_mesa_RasterPos2dv(const GLdouble *v); + +extern void +_mesa_RasterPos2fv(const GLfloat *v); + +extern void +_mesa_RasterPos2iv(const GLint *v); + +extern void +_mesa_RasterPos2sv(const GLshort *v); + +extern void +_mesa_RasterPos3dv(const GLdouble *v); + +extern void +_mesa_RasterPos3fv(const GLfloat *v); + +extern void +_mesa_RasterPos3iv(const GLint *v); + +extern void +_mesa_RasterPos3sv(const GLshort *v); + +extern void +_mesa_RasterPos4dv(const GLdouble *v); + +extern void +_mesa_RasterPos4fv(const GLfloat *v); + +extern void +_mesa_RasterPos4iv(const GLint *v); + +extern void +_mesa_RasterPos4sv(const GLshort *v); + + +/**********************************************************************/ +/*** GL_MESA_window_pos ***/ +/**********************************************************************/ + +extern void +_mesa_WindowPos2dMESA(GLdouble x, GLdouble y); + +extern void +_mesa_WindowPos2fMESA(GLfloat x, GLfloat y); + +extern void +_mesa_WindowPos2iMESA(GLint x, GLint y); + +extern void +_mesa_WindowPos2sMESA(GLshort x, GLshort y); + +extern void +_mesa_WindowPos3dMESA(GLdouble x, GLdouble y, GLdouble z); + +extern void +_mesa_WindowPos3fMESA(GLfloat x, GLfloat y, GLfloat z); + +extern void +_mesa_WindowPos3iMESA(GLint x, GLint y, GLint z); + +extern void +_mesa_WindowPos3sMESA(GLshort x, GLshort y, GLshort z); + +extern void +_mesa_WindowPos4dMESA(GLdouble x, GLdouble y, GLdouble z, GLdouble w); + +extern void +_mesa_WindowPos4fMESA(GLfloat x, GLfloat y, GLfloat z, GLfloat w); + +extern void +_mesa_WindowPos4iMESA(GLint x, GLint y, GLint z, GLint w); + +extern void +_mesa_WindowPos4sMESA(GLshort x, GLshort y, GLshort z, GLshort w); + +extern void +_mesa_WindowPos2dvMESA(const GLdouble *v); + +extern void +_mesa_WindowPos2fvMESA(const GLfloat *v); + +extern void +_mesa_WindowPos2ivMESA(const GLint *v); + +extern void +_mesa_WindowPos2svMESA(const GLshort *v); + +extern void +_mesa_WindowPos3dvMESA(const GLdouble *v); + +extern void +_mesa_WindowPos3fvMESA(const GLfloat *v); + +extern void +_mesa_WindowPos3ivMESA(const GLint *v); + +extern void +_mesa_WindowPos3svMESA(const GLshort *v); + +extern void +_mesa_WindowPos4dvMESA(const GLdouble *v); + +extern void +_mesa_WindowPos4fvMESA(const GLfloat *v); + +extern void +_mesa_WindowPos4ivMESA(const GLint *v); + +extern void +_mesa_WindowPos4svMESA(const GLshort *v); + + +#endif Index: dll/opengl/opengl32/mesa/simple_list.h =================================================================== --- dll/opengl/opengl32/mesa/simple_list.h (revision 0) +++ dll/opengl/opengl32/mesa/simple_list.h (working copy) @@ -0,0 +1,98 @@ +/* $Id: simple_list.h,v 1.2 2001/03/12 00:48:38 gareth Exp $ */ + +/* + * Mesa 3-D graphics library + * Version: 3.5 + * + * Copyright (C) 1999-2001 Brian Paul 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 + * BRIAN PAUL 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. + */ + +/* Simple macros for typesafe, intrusive lists. + * (C) 1997, Keith Whitwell + * + * Intended to work with a list sentinal which is created as an empty + * list. Insert & delete are O(1). + */ + + +#ifndef _SIMPLE_LIST_H +#define _SIMPLE_LIST_H + +#define remove_from_list(elem) \ +do { \ + (elem)->next->prev = (elem)->prev; \ + (elem)->prev->next = (elem)->next; \ +} while (0) + +#define insert_at_head(list, elem) \ +do { \ + (elem)->prev = list; \ + (elem)->next = (list)->next; \ + (list)->next->prev = elem; \ + (list)->next = elem; \ +} while(0) + +#define insert_at_tail(list, elem) \ +do { \ + (elem)->next = list; \ + (elem)->prev = (list)->prev; \ + (list)->prev->next = elem; \ + (list)->prev = elem; \ +} while(0) + +#define move_to_head(list, elem) \ +do { \ + remove_from_list(elem); \ + insert_at_head(list, elem); \ +} while (0) + +#define move_to_tail(list, elem) \ +do { \ + remove_from_list(elem); \ + insert_at_tail(list, elem); \ +} while (0) + + +#define make_empty_list(sentinal) \ +do { \ + (sentinal)->next = sentinal; \ + (sentinal)->prev = sentinal; \ +} while (0) + + +#define first_elem(list) ((list)->next) +#define last_elem(list) ((list)->prev) +#define next_elem(elem) ((elem)->next) +#define prev_elem(elem) ((elem)->prev) +#define at_end(list, elem) ((elem) == (list)) +#define is_empty_list(list) ((list)->next == (list)) + +#define foreach(ptr, list) \ + for( ptr=(list)->next ; ptr!=list ; ptr=(ptr)->next ) + +/* Kludgey - Lets you unlink the current value during a list + * traversal. Useful for free()-ing a list, element + * by element. + */ +#define foreach_s(ptr, t, list) \ + for(ptr=(list)->next,t=(ptr)->next; list != ptr; ptr=t, t=(t)->next) + + +#endif Index: dll/opengl/opengl32/mesa/state.c =================================================================== --- dll/opengl/opengl32/mesa/state.c (revision 0) +++ dll/opengl/opengl32/mesa/state.c (working copy) @@ -0,0 +1,984 @@ +/* $Id: state.c,v 1.68 2001/06/18 17:26:08 brianp Exp $ */ + +/* + * Mesa 3-D graphics library + * Version: 3.5 + * + * Copyright (C) 1999-2001 Brian Paul 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 + * BRIAN PAUL 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. + */ + + +/* + * This file manages recalculation of derived values in the + * __GLcontext. + */ + + +#ifdef PC_HEADER +#include "all.h" +#else +#include "glheader.h" +#include "accum.h" +#include "api_loopback.h" +#include "attrib.h" +#include "blend.h" +#include "buffers.h" +#include "clip.h" +#include "colortab.h" +#include "context.h" +#include "convolve.h" +#include "depth.h" +#include "dlist.h" +#include "drawpix.h" +#include "enable.h" +#include "eval.h" +#include "get.h" +#include "feedback.h" +#include "fog.h" +#include "hint.h" +#include "histogram.h" +#include "light.h" +#include "lines.h" +#include "matrix.h" +#include "mmath.h" +#include "pixel.h" +#include "points.h" +#include "polygon.h" +#include "rastpos.h" +#include "state.h" +#include "stencil.h" +#include "teximage.h" +#include "texobj.h" +#include "texstate.h" +#include "mtypes.h" +#include "varray.h" + +#include "math/m_matrix.h" +#include "math/m_xform.h" +#endif + + +static int +generic_noop(void) +{ +#ifdef DEBUG + _mesa_problem(NULL, "undefined function dispatch"); +#endif + return 0; +} + + +/* + * Set all pointers in the given dispatch table to point to a + * generic no-op function. + */ +void +_mesa_init_no_op_table(struct _glapi_table *table, GLuint tableSize) +{ + GLuint i; + void **dispatch = (void **) table; + for (i = 0; i < tableSize; i++) { + dispatch[i] = (void *) generic_noop; + } +} + + + +/* + * Initialize the given dispatch table with pointers to Mesa's + * immediate-mode commands. + * + * Pointers to begin/end object commands and a few others + * are provided via the vtxfmt interface elsewhere. + */ +void +_mesa_init_exec_table(struct _glapi_table *exec, GLuint tableSize) +{ + /* first initialize all dispatch slots to no-op */ + _mesa_init_no_op_table(exec, tableSize); + + _mesa_loopback_init_api_table( exec, GL_TRUE ); + + /* load the dispatch slots we understand */ + exec->Accum = _mesa_Accum; + exec->AlphaFunc = _mesa_AlphaFunc; + exec->Bitmap = _mesa_Bitmap; + exec->BlendFunc = _mesa_BlendFunc; + exec->CallList = _mesa_CallList; + exec->CallLists = _mesa_CallLists; + exec->Clear = _mesa_Clear; + exec->ClearAccum = _mesa_ClearAccum; + exec->ClearColor = _mesa_ClearColor; + exec->ClearDepth = _mesa_ClearDepth; + exec->ClearIndex = _mesa_ClearIndex; + exec->ClearStencil = _mesa_ClearStencil; + exec->ClipPlane = _mesa_ClipPlane; + exec->ColorMask = _mesa_ColorMask; + exec->ColorMaterial = _mesa_ColorMaterial; + exec->CopyPixels = _mesa_CopyPixels; + exec->CullFace = _mesa_CullFace; + exec->DeleteLists = _mesa_DeleteLists; + exec->DepthFunc = _mesa_DepthFunc; + exec->DepthMask = _mesa_DepthMask; + exec->DepthRange = _mesa_DepthRange; + exec->Disable = _mesa_Disable; + exec->DrawBuffer = _mesa_DrawBuffer; + exec->DrawPixels = _mesa_DrawPixels; + exec->Enable = _mesa_Enable; + exec->EndList = _mesa_EndList; + exec->FeedbackBuffer = _mesa_FeedbackBuffer; + exec->Finish = _mesa_Finish; + exec->Flush = _mesa_Flush; + exec->FogCoordPointerEXT = _mesa_FogCoordPointerEXT; + exec->Fogf = _mesa_Fogf; + exec->Fogfv = _mesa_Fogfv; + exec->Fogi = _mesa_Fogi; + exec->Fogiv = _mesa_Fogiv; + exec->FrontFace = _mesa_FrontFace; + exec->Frustum = _mesa_Frustum; + exec->GenLists = _mesa_GenLists; + exec->GetBooleanv = _mesa_GetBooleanv; + exec->GetClipPlane = _mesa_GetClipPlane; + exec->GetDoublev = _mesa_GetDoublev; + exec->GetError = _mesa_GetError; + exec->GetFloatv = _mesa_GetFloatv; + exec->GetIntegerv = _mesa_GetIntegerv; + exec->GetLightfv = _mesa_GetLightfv; + exec->GetLightiv = _mesa_GetLightiv; + exec->GetMapdv = _mesa_GetMapdv; + exec->GetMapfv = _mesa_GetMapfv; + exec->GetMapiv = _mesa_GetMapiv; + exec->GetMaterialfv = _mesa_GetMaterialfv; + exec->GetMaterialiv = _mesa_GetMaterialiv; + exec->GetPixelMapfv = _mesa_GetPixelMapfv; + exec->GetPixelMapuiv = _mesa_GetPixelMapuiv; + exec->GetPixelMapusv = _mesa_GetPixelMapusv; + exec->GetPolygonStipple = _mesa_GetPolygonStipple; + exec->GetString = _mesa_GetString; + exec->GetTexEnvfv = _mesa_GetTexEnvfv; + exec->GetTexEnviv = _mesa_GetTexEnviv; + exec->GetTexGendv = _mesa_GetTexGendv; + exec->GetTexGenfv = _mesa_GetTexGenfv; + exec->GetTexGeniv = _mesa_GetTexGeniv; + exec->GetTexImage = _mesa_GetTexImage; + exec->GetTexLevelParameterfv = _mesa_GetTexLevelParameterfv; + exec->GetTexLevelParameteriv = _mesa_GetTexLevelParameteriv; + exec->GetTexParameterfv = _mesa_GetTexParameterfv; + exec->GetTexParameteriv = _mesa_GetTexParameteriv; + exec->Hint = _mesa_Hint; + exec->IndexMask = _mesa_IndexMask; + exec->InitNames = _mesa_InitNames; + exec->IsEnabled = _mesa_IsEnabled; + exec->IsList = _mesa_IsList; + exec->LightModelf = _mesa_LightModelf; + exec->LightModelfv = _mesa_LightModelfv; + exec->LightModeli = _mesa_LightModeli; + exec->LightModeliv = _mesa_LightModeliv; + exec->Lightf = _mesa_Lightf; + exec->Lightfv = _mesa_Lightfv; + exec->Lighti = _mesa_Lighti; + exec->Lightiv = _mesa_Lightiv; + exec->LineStipple = _mesa_LineStipple; + exec->LineWidth = _mesa_LineWidth; + exec->ListBase = _mesa_ListBase; + exec->LoadIdentity = _mesa_LoadIdentity; + exec->LoadMatrixd = _mesa_LoadMatrixd; + exec->LoadMatrixf = _mesa_LoadMatrixf; + exec->LoadName = _mesa_LoadName; + exec->LogicOp = _mesa_LogicOp; + exec->Map1d = _mesa_Map1d; + exec->Map1f = _mesa_Map1f; + exec->Map2d = _mesa_Map2d; + exec->Map2f = _mesa_Map2f; + exec->MapGrid1d = _mesa_MapGrid1d; + exec->MapGrid1f = _mesa_MapGrid1f; + exec->MapGrid2d = _mesa_MapGrid2d; + exec->MapGrid2f = _mesa_MapGrid2f; + exec->MatrixMode = _mesa_MatrixMode; + exec->MultMatrixd = _mesa_MultMatrixd; + exec->MultMatrixf = _mesa_MultMatrixf; + exec->NewList = _mesa_NewList; + exec->Ortho = _mesa_Ortho; + exec->PassThrough = _mesa_PassThrough; + exec->PixelMapfv = _mesa_PixelMapfv; + exec->PixelMapuiv = _mesa_PixelMapuiv; + exec->PixelMapusv = _mesa_PixelMapusv; + exec->PixelStoref = _mesa_PixelStoref; + exec->PixelStorei = _mesa_PixelStorei; + exec->PixelTransferf = _mesa_PixelTransferf; + exec->PixelTransferi = _mesa_PixelTransferi; + exec->PixelZoom = _mesa_PixelZoom; + exec->PointSize = _mesa_PointSize; + exec->PolygonMode = _mesa_PolygonMode; + exec->PolygonOffset = _mesa_PolygonOffset; + exec->PolygonStipple = _mesa_PolygonStipple; + exec->PopAttrib = _mesa_PopAttrib; + exec->PopMatrix = _mesa_PopMatrix; + exec->PopName = _mesa_PopName; + exec->PushAttrib = _mesa_PushAttrib; + exec->PushMatrix = _mesa_PushMatrix; + exec->PushName = _mesa_PushName; + exec->RasterPos2d = _mesa_RasterPos2d; + exec->RasterPos2dv = _mesa_RasterPos2dv; + exec->RasterPos2f = _mesa_RasterPos2f; + exec->RasterPos2fv = _mesa_RasterPos2fv; + exec->RasterPos2i = _mesa_RasterPos2i; + exec->RasterPos2iv = _mesa_RasterPos2iv; + exec->RasterPos2s = _mesa_RasterPos2s; + exec->RasterPos2sv = _mesa_RasterPos2sv; + exec->RasterPos3d = _mesa_RasterPos3d; + exec->RasterPos3dv = _mesa_RasterPos3dv; + exec->RasterPos3f = _mesa_RasterPos3f; + exec->RasterPos3fv = _mesa_RasterPos3fv; + exec->RasterPos3i = _mesa_RasterPos3i; + exec->RasterPos3iv = _mesa_RasterPos3iv; + exec->RasterPos3s = _mesa_RasterPos3s; + exec->RasterPos3sv = _mesa_RasterPos3sv; + exec->RasterPos4d = _mesa_RasterPos4d; + exec->RasterPos4dv = _mesa_RasterPos4dv; + exec->RasterPos4f = _mesa_RasterPos4f; + exec->RasterPos4fv = _mesa_RasterPos4fv; + exec->RasterPos4i = _mesa_RasterPos4i; + exec->RasterPos4iv = _mesa_RasterPos4iv; + exec->RasterPos4s = _mesa_RasterPos4s; + exec->RasterPos4sv = _mesa_RasterPos4sv; + exec->ReadBuffer = _mesa_ReadBuffer; + exec->ReadPixels = _mesa_ReadPixels; + exec->RenderMode = _mesa_RenderMode; + exec->Rotated = _mesa_Rotated; + exec->Rotatef = _mesa_Rotatef; + exec->Scaled = _mesa_Scaled; + exec->Scalef = _mesa_Scalef; + exec->Scissor = _mesa_Scissor; + exec->SecondaryColorPointerEXT = _mesa_SecondaryColorPointerEXT; + exec->SelectBuffer = _mesa_SelectBuffer; + exec->ShadeModel = _mesa_ShadeModel; + exec->StencilFunc = _mesa_StencilFunc; + exec->StencilMask = _mesa_StencilMask; + exec->StencilOp = _mesa_StencilOp; + exec->TexEnvf = _mesa_TexEnvf; + exec->TexEnvfv = _mesa_TexEnvfv; + exec->TexEnvi = _mesa_TexEnvi; + exec->TexEnviv = _mesa_TexEnviv; + exec->TexGend = _mesa_TexGend; + exec->TexGendv = _mesa_TexGendv; + exec->TexGenf = _mesa_TexGenf; + exec->TexGenfv = _mesa_TexGenfv; + exec->TexGeni = _mesa_TexGeni; + exec->TexGeniv = _mesa_TexGeniv; + exec->TexImage1D = _mesa_TexImage1D; + exec->TexImage2D = _mesa_TexImage2D; + exec->TexParameterf = _mesa_TexParameterf; + exec->TexParameterfv = _mesa_TexParameterfv; + exec->TexParameteri = _mesa_TexParameteri; + exec->TexParameteriv = _mesa_TexParameteriv; + exec->Translated = _mesa_Translated; + exec->Translatef = _mesa_Translatef; + exec->Viewport = _mesa_Viewport; + + /* 1.1 */ + exec->AreTexturesResident = _mesa_AreTexturesResident; + exec->BindTexture = _mesa_BindTexture; + exec->ColorPointer = _mesa_ColorPointer; + exec->CopyTexImage1D = _mesa_CopyTexImage1D; + exec->CopyTexImage2D = _mesa_CopyTexImage2D; + exec->CopyTexSubImage1D = _mesa_CopyTexSubImage1D; + exec->CopyTexSubImage2D = _mesa_CopyTexSubImage2D; + exec->DeleteTextures = _mesa_DeleteTextures; + exec->DisableClientState = _mesa_DisableClientState; + exec->EdgeFlagPointer = _mesa_EdgeFlagPointer; + exec->EnableClientState = _mesa_EnableClientState; + exec->GenTextures = _mesa_GenTextures; + exec->GetPointerv = _mesa_GetPointerv; + exec->IndexPointer = _mesa_IndexPointer; + exec->InterleavedArrays = _mesa_InterleavedArrays; + exec->IsTexture = _mesa_IsTexture; + exec->NormalPointer = _mesa_NormalPointer; + exec->PopClientAttrib = _mesa_PopClientAttrib; + exec->PrioritizeTextures = _mesa_PrioritizeTextures; + exec->PushClientAttrib = _mesa_PushClientAttrib; + exec->TexCoordPointer = _mesa_TexCoordPointer; + exec->TexSubImage1D = _mesa_TexSubImage1D; + exec->TexSubImage2D = _mesa_TexSubImage2D; + exec->VertexPointer = _mesa_VertexPointer; + + /* 1.2 */ + exec->CopyTexSubImage3D = _mesa_CopyTexSubImage3D; + exec->TexImage3D = _mesa_TexImage3D; + exec->TexSubImage3D = _mesa_TexSubImage3D; + + /* OpenGL 1.2 GL_ARB_imaging */ + exec->BlendColor = _mesa_BlendColor; + exec->BlendEquation = _mesa_BlendEquation; + exec->ColorSubTable = _mesa_ColorSubTable; + exec->ColorTable = _mesa_ColorTable; + exec->ColorTableParameterfv = _mesa_ColorTableParameterfv; + exec->ColorTableParameteriv = _mesa_ColorTableParameteriv; + exec->ConvolutionFilter1D = _mesa_ConvolutionFilter1D; + exec->ConvolutionFilter2D = _mesa_ConvolutionFilter2D; + exec->ConvolutionParameterf = _mesa_ConvolutionParameterf; + exec->ConvolutionParameterfv = _mesa_ConvolutionParameterfv; + exec->ConvolutionParameteri = _mesa_ConvolutionParameteri; + exec->ConvolutionParameteriv = _mesa_ConvolutionParameteriv; + exec->CopyColorSubTable = _mesa_CopyColorSubTable; + exec->CopyColorTable = _mesa_CopyColorTable; + exec->CopyConvolutionFilter1D = _mesa_CopyConvolutionFilter1D; + exec->CopyConvolutionFilter2D = _mesa_CopyConvolutionFilter2D; + exec->GetColorTable = _mesa_GetColorTable; + exec->GetColorTableParameterfv = _mesa_GetColorTableParameterfv; + exec->GetColorTableParameteriv = _mesa_GetColorTableParameteriv; + exec->GetConvolutionFilter = _mesa_GetConvolutionFilter; + exec->GetConvolutionParameterfv = _mesa_GetConvolutionParameterfv; + exec->GetConvolutionParameteriv = _mesa_GetConvolutionParameteriv; + exec->GetHistogram = _mesa_GetHistogram; + exec->GetHistogramParameterfv = _mesa_GetHistogramParameterfv; + exec->GetHistogramParameteriv = _mesa_GetHistogramParameteriv; + exec->GetMinmax = _mesa_GetMinmax; + exec->GetMinmaxParameterfv = _mesa_GetMinmaxParameterfv; + exec->GetMinmaxParameteriv = _mesa_GetMinmaxParameteriv; + exec->GetSeparableFilter = _mesa_GetSeparableFilter; + exec->Histogram = _mesa_Histogram; + exec->Minmax = _mesa_Minmax; + exec->ResetHistogram = _mesa_ResetHistogram; + exec->ResetMinmax = _mesa_ResetMinmax; + exec->SeparableFilter2D = _mesa_SeparableFilter2D; + + /* 2. GL_EXT_blend_color */ +#if 0 + exec->BlendColorEXT = _mesa_BlendColorEXT; +#endif + + /* 3. GL_EXT_polygon_offset */ + exec->PolygonOffsetEXT = _mesa_PolygonOffsetEXT; + + /* 6. GL_EXT_texture3d */ +#if 0 + exec->CopyTexSubImage3DEXT = _mesa_CopyTexSubImage3D; + exec->TexImage3DEXT = _mesa_TexImage3DEXT; + exec->TexSubImage3DEXT = _mesa_TexSubImage3D; +#endif + + /* 11. GL_EXT_histogram */ + exec->GetHistogramEXT = _mesa_GetHistogram; + exec->GetHistogramParameterfvEXT = _mesa_GetHistogramParameterfv; + exec->GetHistogramParameterivEXT = _mesa_GetHistogramParameteriv; + exec->GetMinmaxEXT = _mesa_GetMinmax; + exec->GetMinmaxParameterfvEXT = _mesa_GetMinmaxParameterfv; + exec->GetMinmaxParameterivEXT = _mesa_GetMinmaxParameteriv; + + /* ?. GL_SGIX_pixel_texture */ + exec->PixelTexGenSGIX = _mesa_PixelTexGenSGIX; + + /* 15. GL_SGIS_pixel_texture */ + exec->PixelTexGenParameteriSGIS = _mesa_PixelTexGenParameteriSGIS; + exec->PixelTexGenParameterivSGIS = _mesa_PixelTexGenParameterivSGIS; + exec->PixelTexGenParameterfSGIS = _mesa_PixelTexGenParameterfSGIS; + exec->PixelTexGenParameterfvSGIS = _mesa_PixelTexGenParameterfvSGIS; + exec->GetPixelTexGenParameterivSGIS = _mesa_GetPixelTexGenParameterivSGIS; + exec->GetPixelTexGenParameterfvSGIS = _mesa_GetPixelTexGenParameterfvSGIS; + + /* 30. GL_EXT_vertex_array */ + exec->ColorPointerEXT = _mesa_ColorPointerEXT; + exec->EdgeFlagPointerEXT = _mesa_EdgeFlagPointerEXT; + exec->IndexPointerEXT = _mesa_IndexPointerEXT; + exec->NormalPointerEXT = _mesa_NormalPointerEXT; + exec->TexCoordPointerEXT = _mesa_TexCoordPointerEXT; + exec->VertexPointerEXT = _mesa_VertexPointerEXT; + + /* 37. GL_EXT_blend_minmax */ +#if 0 + exec->BlendEquationEXT = _mesa_BlendEquationEXT; +#endif + + /* 54. GL_EXT_point_parameters */ + exec->PointParameterfEXT = _mesa_PointParameterfEXT; + exec->PointParameterfvEXT = _mesa_PointParameterfvEXT; + + /* 78. GL_EXT_paletted_texture */ +#if 0 + exec->ColorTableEXT = _mesa_ColorTableEXT; + exec->ColorSubTableEXT = _mesa_ColorSubTableEXT; +#endif + exec->GetColorTableEXT = _mesa_GetColorTable; + exec->GetColorTableParameterfvEXT = _mesa_GetColorTableParameterfv; + exec->GetColorTableParameterivEXT = _mesa_GetColorTableParameteriv; + + /* 97. GL_EXT_compiled_vertex_array */ + exec->LockArraysEXT = _mesa_LockArraysEXT; + exec->UnlockArraysEXT = _mesa_UnlockArraysEXT; + + /* 173. GL_INGR_blend_func_separate */ + exec->BlendFuncSeparateEXT = _mesa_BlendFuncSeparateEXT; + + /* 196. GL_MESA_resize_buffers */ + exec->ResizeBuffersMESA = _mesa_ResizeBuffersMESA; + + /* 197. GL_MESA_window_pos */ + exec->WindowPos2dMESA = _mesa_WindowPos2dMESA; + exec->WindowPos2dvMESA = _mesa_WindowPos2dvMESA; + exec->WindowPos2fMESA = _mesa_WindowPos2fMESA; + exec->WindowPos2fvMESA = _mesa_WindowPos2fvMESA; + exec->WindowPos2iMESA = _mesa_WindowPos2iMESA; + exec->WindowPos2ivMESA = _mesa_WindowPos2ivMESA; + exec->WindowPos2sMESA = _mesa_WindowPos2sMESA; + exec->WindowPos2svMESA = _mesa_WindowPos2svMESA; + exec->WindowPos3dMESA = _mesa_WindowPos3dMESA; + exec->WindowPos3dvMESA = _mesa_WindowPos3dvMESA; + exec->WindowPos3fMESA = _mesa_WindowPos3fMESA; + exec->WindowPos3fvMESA = _mesa_WindowPos3fvMESA; + exec->WindowPos3iMESA = _mesa_WindowPos3iMESA; + exec->WindowPos3ivMESA = _mesa_WindowPos3ivMESA; + exec->WindowPos3sMESA = _mesa_WindowPos3sMESA; + exec->WindowPos3svMESA = _mesa_WindowPos3svMESA; + exec->WindowPos4dMESA = _mesa_WindowPos4dMESA; + exec->WindowPos4dvMESA = _mesa_WindowPos4dvMESA; + exec->WindowPos4fMESA = _mesa_WindowPos4fMESA; + exec->WindowPos4fvMESA = _mesa_WindowPos4fvMESA; + exec->WindowPos4iMESA = _mesa_WindowPos4iMESA; + exec->WindowPos4ivMESA = _mesa_WindowPos4ivMESA; + exec->WindowPos4sMESA = _mesa_WindowPos4sMESA; + exec->WindowPos4svMESA = _mesa_WindowPos4svMESA; + + /* ARB 1. GL_ARB_multitexture */ + exec->ActiveTextureARB = _mesa_ActiveTextureARB; + exec->ClientActiveTextureARB = _mesa_ClientActiveTextureARB; + + /* ARB 3. GL_ARB_transpose_matrix */ + exec->LoadTransposeMatrixdARB = _mesa_LoadTransposeMatrixdARB; + exec->LoadTransposeMatrixfARB = _mesa_LoadTransposeMatrixfARB; + exec->MultTransposeMatrixdARB = _mesa_MultTransposeMatrixdARB; + exec->MultTransposeMatrixfARB = _mesa_MultTransposeMatrixfARB; + + /* ARB 5. GL_ARB_multisample */ + exec->SampleCoverageARB = _mesa_SampleCoverageARB; + + /* ARB 12. GL_ARB_texture_compression */ + exec->CompressedTexImage3DARB = _mesa_CompressedTexImage3DARB; + exec->CompressedTexImage2DARB = _mesa_CompressedTexImage2DARB; + exec->CompressedTexImage1DARB = _mesa_CompressedTexImage1DARB; + exec->CompressedTexSubImage3DARB = _mesa_CompressedTexSubImage3DARB; + exec->CompressedTexSubImage2DARB = _mesa_CompressedTexSubImage2DARB; + exec->CompressedTexSubImage1DARB = _mesa_CompressedTexSubImage1DARB; + exec->GetCompressedTexImageARB = _mesa_GetCompressedTexImageARB; + +} + + + +/**********************************************************************/ +/***** State update logic *****/ +/**********************************************************************/ + + +static void +update_polygon( GLcontext *ctx ) +{ + ctx->_TriangleCaps &= ~(DD_TRI_CULL_FRONT_BACK | DD_TRI_OFFSET); + + if (ctx->Polygon.CullFlag && ctx->Polygon.CullFaceMode == GL_FRONT_AND_BACK) + ctx->_TriangleCaps |= DD_TRI_CULL_FRONT_BACK; + + /* Any Polygon offsets enabled? */ + ctx->Polygon._OffsetAny = GL_FALSE; + ctx->_TriangleCaps &= ~DD_TRI_OFFSET; + + if (ctx->Polygon.OffsetPoint || + ctx->Polygon.OffsetLine || + ctx->Polygon.OffsetFill) { + ctx->_TriangleCaps |= DD_TRI_OFFSET; + ctx->Polygon._OffsetAny = GL_TRUE; + } +} + +static void +calculate_model_project_matrix( GLcontext *ctx ) +{ + if (!ctx->_NeedEyeCoords) { + _math_matrix_mul_matrix( &ctx->_ModelProjectMatrix, + &ctx->ProjectionMatrix, + &ctx->ModelView ); + + _math_matrix_analyse( &ctx->_ModelProjectMatrix ); + } +} + +static void +update_modelview_scale( GLcontext *ctx ) +{ + ctx->_ModelViewInvScale = 1.0F; + if (ctx->ModelView.flags & (MAT_FLAG_UNIFORM_SCALE | + MAT_FLAG_GENERAL_SCALE | + MAT_FLAG_GENERAL_3D | + MAT_FLAG_GENERAL) ) { + const GLfloat *m = ctx->ModelView.inv; + GLfloat f = m[2] * m[2] + m[6] * m[6] + m[10] * m[10]; + if (f < 1e-12) f = 1.0; + if (ctx->_NeedEyeCoords) + ctx->_ModelViewInvScale = 1.0/GL_SQRT(f); + else + ctx->_ModelViewInvScale = GL_SQRT(f); + } +} + + +/* Bring uptodate any state that relies on _NeedEyeCoords. + */ +static void +update_tnl_spaces( GLcontext *ctx, GLuint oldneedeyecoords ) +{ + /* Check if the truth-value interpretations of the bitfields have + * changed: + */ + if ((oldneedeyecoords == 0) != (ctx->_NeedEyeCoords == 0)) { + /* Recalculate all state that depends on _NeedEyeCoords. + */ + update_modelview_scale(ctx); + calculate_model_project_matrix(ctx); + _mesa_compute_light_positions( ctx ); + + if (ctx->Driver.LightingSpaceChange) + ctx->Driver.LightingSpaceChange( ctx ); + } + else { + GLuint new_state = ctx->NewState; + + /* Recalculate that same state only if it has been invalidated + * by other statechanges. + */ + if (new_state & _NEW_MODELVIEW) + update_modelview_scale(ctx); + + if (new_state & (_NEW_MODELVIEW|_NEW_PROJECTION)) + calculate_model_project_matrix(ctx); + + if (new_state & (_NEW_LIGHT|_NEW_MODELVIEW)) + _mesa_compute_light_positions( ctx ); + } +} + + +static void +update_drawbuffer( GLcontext *ctx ) +{ + ctx->DrawBuffer->_Xmin = 0; + ctx->DrawBuffer->_Ymin = 0; + ctx->DrawBuffer->_Xmax = ctx->DrawBuffer->Width; + ctx->DrawBuffer->_Ymax = ctx->DrawBuffer->Height; + if (ctx->Scissor.Enabled) { + if (ctx->Scissor.X > ctx->DrawBuffer->_Xmin) { + ctx->DrawBuffer->_Xmin = ctx->Scissor.X; + } + if (ctx->Scissor.Y > ctx->DrawBuffer->_Ymin) { + ctx->DrawBuffer->_Ymin = ctx->Scissor.Y; + } + if (ctx->Scissor.X + ctx->Scissor.Width < ctx->DrawBuffer->_Xmax) { + ctx->DrawBuffer->_Xmax = ctx->Scissor.X + ctx->Scissor.Width; + } + if (ctx->Scissor.Y + ctx->Scissor.Height < ctx->DrawBuffer->_Ymax) { + ctx->DrawBuffer->_Ymax = ctx->Scissor.Y + ctx->Scissor.Height; + } + } +} + + +/* NOTE: This routine references Tranform attribute values to compute + * userclip positions in clip space, but is only called on + * _NEW_PROJECTION. The _mesa_ClipPlane() function keeps these values + * uptodate across changes to the Transform attributes. + */ +static void +update_projection( GLcontext *ctx ) +{ + _math_matrix_analyse( &ctx->ProjectionMatrix ); + + /* Recompute clip plane positions in clipspace. This is also done + * in _mesa_ClipPlane(). + */ + if (ctx->Transform._AnyClip) { + GLuint p; + for (p = 0; p < ctx->Const.MaxClipPlanes; p++) { + if (ctx->Transform.ClipEnabled[p]) { + _mesa_transform_vector( ctx->Transform._ClipUserPlane[p], + ctx->Transform.EyeUserPlane[p], + ctx->ProjectionMatrix.inv ); + } + } + } +} + + +/* + * Return a bitmask of IMAGE_*_BIT flags which to indicate which + * pixel transfer operations are enabled. + */ +static void +update_image_transfer_state(GLcontext *ctx) +{ + GLuint mask = 0; + + if (ctx->Pixel.RedScale != 1.0F || ctx->Pixel.RedBias != 0.0F || + ctx->Pixel.GreenScale != 1.0F || ctx->Pixel.GreenBias != 0.0F || + ctx->Pixel.BlueScale != 1.0F || ctx->Pixel.BlueBias != 0.0F || + ctx->Pixel.AlphaScale != 1.0F || ctx->Pixel.AlphaBias != 0.0F) + mask |= IMAGE_SCALE_BIAS_BIT; + + if (ctx->Pixel.IndexShift || ctx->Pixel.IndexOffset) + mask |= IMAGE_SHIFT_OFFSET_BIT; + + if (ctx->Pixel.MapColorFlag) + mask |= IMAGE_MAP_COLOR_BIT; + + if (ctx->Pixel.ColorTableEnabled) + mask |= IMAGE_COLOR_TABLE_BIT; + + if (ctx->Pixel.Convolution1DEnabled || + ctx->Pixel.Convolution2DEnabled || + ctx->Pixel.Separable2DEnabled) { + mask |= IMAGE_CONVOLUTION_BIT; + if (ctx->Pixel.PostConvolutionScale[0] != 1.0F || + ctx->Pixel.PostConvolutionScale[1] != 1.0F || + ctx->Pixel.PostConvolutionScale[2] != 1.0F || + ctx->Pixel.PostConvolutionScale[3] != 1.0F || + ctx->Pixel.PostConvolutionBias[0] != 0.0F || + ctx->Pixel.PostConvolutionBias[1] != 0.0F || + ctx->Pixel.PostConvolutionBias[2] != 0.0F || + ctx->Pixel.PostConvolutionBias[3] != 0.0F) { + mask |= IMAGE_POST_CONVOLUTION_SCALE_BIAS; + } + } + + if (ctx->Pixel.PostConvolutionColorTableEnabled) + mask |= IMAGE_POST_CONVOLUTION_COLOR_TABLE_BIT; + + if (ctx->ColorMatrix.type != MATRIX_IDENTITY || + ctx->Pixel.PostColorMatrixScale[0] != 1.0F || + ctx->Pixel.PostColorMatrixBias[0] != 0.0F || + ctx->Pixel.PostColorMatrixScale[1] != 1.0F || + ctx->Pixel.PostColorMatrixBias[1] != 0.0F || + ctx->Pixel.PostColorMatrixScale[2] != 1.0F || + ctx->Pixel.PostColorMatrixBias[2] != 0.0F || + ctx->Pixel.PostColorMatrixScale[3] != 1.0F || + ctx->Pixel.PostColorMatrixBias[3] != 0.0F) + mask |= IMAGE_COLOR_MATRIX_BIT; + + if (ctx->Pixel.PostColorMatrixColorTableEnabled) + mask |= IMAGE_POST_COLOR_MATRIX_COLOR_TABLE_BIT; + + if (ctx->Pixel.HistogramEnabled) + mask |= IMAGE_HISTOGRAM_BIT; + + if (ctx->Pixel.MinMaxEnabled) + mask |= IMAGE_MIN_MAX_BIT; + + ctx->_ImageTransferState = mask; +} + + + + +/* Note: This routine refers to derived texture attribute values to + * compute the ENABLE_TEXMAT flags, but is only called on + * _NEW_TEXTURE_MATRIX. On changes to _NEW_TEXTURE, the ENABLE_TEXMAT + * flags are updated by _mesa_update_textures(), below. + * + * If both TEXTURE and TEXTURE_MATRIX change at once, these values + * will be computed twice. + */ +static void +update_texture_matrices( GLcontext *ctx ) +{ + GLuint i; + + ctx->Texture._TexMatEnabled = 0; + + for (i=0; i < ctx->Const.MaxTextureUnits; i++) { + if (ctx->TextureMatrix[i].flags & MAT_DIRTY) { + _math_matrix_analyse( &ctx->TextureMatrix[i] ); + + if (ctx->Driver.TextureMatrix) + ctx->Driver.TextureMatrix( ctx, i, &ctx->TextureMatrix[i] ); + + if (ctx->Texture.Unit[i]._ReallyEnabled && + ctx->TextureMatrix[i].type != MATRIX_IDENTITY) + ctx->Texture._TexMatEnabled |= ENABLE_TEXMAT(i); + } + } +} + + +/* Note: This routine refers to derived texture matrix values to + * compute the ENABLE_TEXMAT flags, but is only called on + * _NEW_TEXTURE. On changes to _NEW_TEXTURE_MATRIX, the ENABLE_TEXMAT + * flags are updated by _mesa_update_texture_matrices, above. + * + * If both TEXTURE and TEXTURE_MATRIX change at once, these values + * will be computed twice. + */ +static void +update_texture_state( GLcontext *ctx ) +{ + GLuint i; + + ctx->Texture._ReallyEnabled = 0; + ctx->Texture._GenFlags = 0; + ctx->_NeedNormals &= ~NEED_NORMALS_TEXGEN; + ctx->_NeedEyeCoords &= ~NEED_EYE_TEXGEN; + ctx->Texture._TexMatEnabled = 0; + ctx->Texture._TexGenEnabled = 0; + + /* Update texture unit state. + */ + for (i=0; i < ctx->Const.MaxTextureUnits; i++) { + struct gl_texture_unit *texUnit = &ctx->Texture.Unit[i]; + + texUnit->_ReallyEnabled = 0; + texUnit->_GenFlags = 0; + + if (!texUnit->Enabled) + continue; + + /* Find the texture of highest dimensionality that is enabled + * and complete. We'll use it for texturing. + */ + if (texUnit->Enabled & TEXTURE0_CUBE) { + struct gl_texture_object *texObj = texUnit->CurrentCubeMap; + if (!texObj->Complete) { + _mesa_test_texobj_completeness(ctx, texObj); + } + if (texObj->Complete) { + texUnit->_ReallyEnabled = TEXTURE0_CUBE; + texUnit->_Current = texObj; + } + } + + if (!texUnit->_ReallyEnabled && (texUnit->Enabled & TEXTURE0_3D)) { + struct gl_texture_object *texObj = texUnit->Current3D; + if (!texObj->Complete) { + _mesa_test_texobj_completeness(ctx, texObj); + } + if (texObj->Complete) { + texUnit->_ReallyEnabled = TEXTURE0_3D; + texUnit->_Current = texObj; + } + } + + if (!texUnit->_ReallyEnabled && (texUnit->Enabled & TEXTURE0_2D)) { + struct gl_texture_object *texObj = texUnit->Current2D; + if (!texObj->Complete) { + _mesa_test_texobj_completeness(ctx, texObj); + } + if (texObj->Complete) { + texUnit->_ReallyEnabled = TEXTURE0_2D; + texUnit->_Current = texObj; + } + } + + if (!texUnit->_ReallyEnabled && (texUnit->Enabled & TEXTURE0_1D)) { + struct gl_texture_object *texObj = texUnit->Current1D; + if (!texObj->Complete) { + _mesa_test_texobj_completeness(ctx, texObj); + } + if (texObj->Complete) { + texUnit->_ReallyEnabled = TEXTURE0_1D; + texUnit->_Current = texObj; + } + } + + if (!texUnit->_ReallyEnabled) { + texUnit->_Current = NULL; + continue; + } + + { + GLuint flag = texUnit->_ReallyEnabled << (i * 4); + ctx->Texture._ReallyEnabled |= flag; + } + + if (texUnit->TexGenEnabled) { + if (texUnit->TexGenEnabled & S_BIT) { + texUnit->_GenFlags |= texUnit->_GenBitS; + } + if (texUnit->TexGenEnabled & T_BIT) { + texUnit->_GenFlags |= texUnit->_GenBitT; + } + if (texUnit->TexGenEnabled & Q_BIT) { + texUnit->_GenFlags |= texUnit->_GenBitQ; + } + if (texUnit->TexGenEnabled & R_BIT) { + texUnit->_GenFlags |= texUnit->_GenBitR; + } + + ctx->Texture._TexGenEnabled |= ENABLE_TEXGEN(i); + ctx->Texture._GenFlags |= texUnit->_GenFlags; + } + + if (ctx->TextureMatrix[i].type != MATRIX_IDENTITY) + ctx->Texture._TexMatEnabled |= ENABLE_TEXMAT(i); + } + + if (ctx->Texture._GenFlags & TEXGEN_NEED_NORMALS) { + ctx->_NeedNormals |= NEED_NORMALS_TEXGEN; + ctx->_NeedEyeCoords |= NEED_EYE_TEXGEN; + } + + if (ctx->Texture._GenFlags & TEXGEN_NEED_EYE_COORD) { + ctx->_NeedEyeCoords |= NEED_EYE_TEXGEN; + } +} + + +/* + * If ctx->NewState is non-zero then this function MUST be called before + * rendering any primitive. Basically, function pointers and miscellaneous + * flags are updated to reflect the current state of the state machine. + * + * The above constraint is now maintained largely by the two Exec + * dispatch tables, which trigger the appropriate flush on transition + * between State and Geometry modes. + * + * Special care is taken with the derived value _NeedEyeCoords. This + * is a bitflag which is updated with information from a number of + * attribute groups (MODELVIEW, LIGHT, TEXTURE). A lot of derived + * state references this value, and must be treated with care to + * ensure that updates are done correctly. All state dependent on + * _NeedEyeCoords is calculated from within _mesa_update_tnl_spaces(), + * and from nowhere else. + */ +void _mesa_update_state( GLcontext *ctx ) +{ + const GLuint new_state = ctx->NewState; + const GLuint oldneedeyecoords = ctx->_NeedEyeCoords; + + if (MESA_VERBOSE & VERBOSE_STATE) + _mesa_print_state("", new_state); + + if (new_state & _NEW_MODELVIEW) + _math_matrix_analyse( &ctx->ModelView ); + + if (new_state & _NEW_PROJECTION) + update_projection( ctx ); + + if (new_state & _NEW_TEXTURE_MATRIX) + update_texture_matrices( ctx ); + + if (new_state & _NEW_COLOR_MATRIX) + _math_matrix_analyse( &ctx->ColorMatrix ); + + /* References ColorMatrix.type (derived above). + */ + if (new_state & _IMAGE_NEW_TRANSFER_STATE) + update_image_transfer_state(ctx); + + /* Contributes to NeedEyeCoords, NeedNormals. + */ + if (new_state & _NEW_TEXTURE) + update_texture_state( ctx ); + + if (new_state & (_NEW_BUFFERS|_NEW_SCISSOR)) + update_drawbuffer( ctx ); + + if (new_state & _NEW_POLYGON) + update_polygon( ctx ); + + /* Contributes to NeedEyeCoords, NeedNormals. + */ + if (new_state & _NEW_LIGHT) + _mesa_update_lighting( ctx ); + + /* We can light in object space if the modelview matrix preserves + * lengths and relative angles. + */ + if (new_state & (_NEW_MODELVIEW|_NEW_LIGHT)) { + ctx->_NeedEyeCoords &= ~NEED_EYE_LIGHT_MODELVIEW; + if (ctx->Light.Enabled && + !TEST_MAT_FLAGS( &ctx->ModelView, MAT_FLAGS_LENGTH_PRESERVING)) + ctx->_NeedEyeCoords |= NEED_EYE_LIGHT_MODELVIEW; + } + + + /* ctx->_NeedEyeCoords is now uptodate. + * + * If the truth value of this variable has changed, update for the + * new lighting space and recompute the positions of lights and the + * normal transform. + * + * If the lighting space hasn't changed, may still need to recompute + * light positions & normal transforms for other reasons. + */ + if (new_state & (_NEW_MODELVIEW | + _NEW_PROJECTION | + _NEW_LIGHT | + _MESA_NEW_NEED_EYE_COORDS)) + update_tnl_spaces( ctx, oldneedeyecoords ); + + /* + * Here the driver sets up all the ctx->Driver function pointers + * to it's specific, private functions, and performs any + * internal state management necessary, including invalidating + * state of active modules. + * + * Set ctx->NewState to zero to avoid recursion if + * Driver.UpdateState() has to call FLUSH_VERTICES(). (fixed?) + */ + ctx->NewState = 0; + ctx->Driver.UpdateState(ctx, new_state); + ctx->Array.NewState = 0; + + /* At this point we can do some assertions to be sure the required + * device driver function pointers are all initialized. + */ + ASSERT(ctx->Driver.GetString); + ASSERT(ctx->Driver.UpdateState); + ASSERT(ctx->Driver.Clear); + ASSERT(ctx->Driver.SetDrawBuffer); + ASSERT(ctx->Driver.GetBufferSize); + if (ctx->Visual.accumRedBits > 0) { + ASSERT(ctx->Driver.Accum); + } + ASSERT(ctx->Driver.DrawPixels); + ASSERT(ctx->Driver.ReadPixels); + ASSERT(ctx->Driver.CopyPixels); + ASSERT(ctx->Driver.Bitmap); + ASSERT(ctx->Driver.ResizeBuffersMESA); + ASSERT(ctx->Driver.TexImage1D); + ASSERT(ctx->Driver.TexImage2D); + ASSERT(ctx->Driver.TexImage3D); + ASSERT(ctx->Driver.TexSubImage1D); + ASSERT(ctx->Driver.TexSubImage2D); + ASSERT(ctx->Driver.TexSubImage3D); + ASSERT(ctx->Driver.CopyTexImage1D); + ASSERT(ctx->Driver.CopyTexImage2D); + ASSERT(ctx->Driver.CopyTexSubImage1D); + ASSERT(ctx->Driver.CopyTexSubImage2D); + ASSERT(ctx->Driver.CopyTexSubImage3D); + if (ctx->Extensions.ARB_texture_compression) { + ASSERT(ctx->Driver.BaseCompressedTexFormat); + ASSERT(ctx->Driver.CompressedTextureSize); + ASSERT(ctx->Driver.GetCompressedTexImage); +#if 0 /* HW drivers need these, but not SW rasterizers */ + ASSERT(ctx->Driver.CompressedTexImage1D); + ASSERT(ctx->Driver.CompressedTexImage2D); + ASSERT(ctx->Driver.CompressedTexImage3D); + ASSERT(ctx->Driver.CompressedTexSubImage1D); + ASSERT(ctx->Driver.CompressedTexSubImage2D); + ASSERT(ctx->Driver.CompressedTexSubImage3D); +#endif + } +} Index: dll/opengl/opengl32/mesa/state.h =================================================================== --- dll/opengl/opengl32/mesa/state.h (revision 0) +++ dll/opengl/opengl32/mesa/state.h (working copy) @@ -0,0 +1,50 @@ +/* $Id: state.h,v 1.7 2001/03/12 00:48:38 gareth Exp $ */ + +/* + * Mesa 3-D graphics library + * Version: 3.5 + * + * Copyright (C) 1999-2001 Brian Paul 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 + * BRIAN PAUL 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. + */ + + +#ifndef STATE_H +#define STATE_H + +#include "mtypes.h" + + +extern void +_mesa_init_no_op_table(struct _glapi_table *exec, GLuint tableSize); + +extern void +_mesa_init_exec_table(struct _glapi_table *exec, GLuint tableSize); + +extern void +_mesa_update_state( GLcontext *ctx ); + +extern void +_mesa_print_state( const char *msg, GLuint state ); + +extern void +_mesa_print_enable_flags( const char *msg, GLuint flags ); + + +#endif Index: dll/opengl/opengl32/mesa/stencil.c =================================================================== --- dll/opengl/opengl32/mesa/stencil.c (revision 0) +++ dll/opengl/opengl32/mesa/stencil.c (working copy) @@ -0,0 +1,198 @@ +/* $Id: stencil.c,v 1.27 2001/05/09 16:34:09 brianp Exp $ */ + +/* + * Mesa 3-D graphics library + * Version: 3.5 + * + * Copyright (C) 1999-2001 Brian Paul 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 + * BRIAN PAUL 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. + */ + + +#ifdef PC_HEADER +#include "all.h" +#else +#include "glheader.h" +#include "context.h" +#include "depth.h" +#include "macros.h" +#include "mem.h" +#include "stencil.h" +#include "mtypes.h" +#include "enable.h" +#endif + + + + +void +_mesa_ClearStencil( GLint s ) +{ + GET_CURRENT_CONTEXT(ctx); + ASSERT_OUTSIDE_BEGIN_END(ctx); + + if (ctx->Stencil.Clear == (GLstencil) s) + return; + + FLUSH_VERTICES(ctx, _NEW_STENCIL); + ctx->Stencil.Clear = (GLstencil) s; + + if (ctx->Driver.ClearStencil) { + (*ctx->Driver.ClearStencil)( ctx, s ); + } +} + + + +void +_mesa_StencilFunc( GLenum func, GLint ref, GLuint mask ) +{ + GET_CURRENT_CONTEXT(ctx); + GLint maxref; + ASSERT_OUTSIDE_BEGIN_END(ctx); + + switch (func) { + case GL_NEVER: + case GL_LESS: + case GL_LEQUAL: + case GL_GREATER: + case GL_GEQUAL: + case GL_EQUAL: + case GL_NOTEQUAL: + case GL_ALWAYS: + break; + default: + _mesa_error( ctx, GL_INVALID_ENUM, "glStencilFunc" ); + return; + } + + maxref = (1 << STENCIL_BITS) - 1; + ref = (GLstencil) CLAMP( ref, 0, maxref ); + + if (ctx->Stencil.Function == func && + ctx->Stencil.ValueMask == (GLstencil) mask && + ctx->Stencil.Ref == ref) + return; + + FLUSH_VERTICES(ctx, _NEW_STENCIL); + ctx->Stencil.Function = func; + ctx->Stencil.Ref = ref; + ctx->Stencil.ValueMask = (GLstencil) mask; + + if (ctx->Driver.StencilFunc) { + (*ctx->Driver.StencilFunc)( ctx, func, ctx->Stencil.Ref, mask ); + } +} + + + +void +_mesa_StencilMask( GLuint mask ) +{ + GET_CURRENT_CONTEXT(ctx); + ASSERT_OUTSIDE_BEGIN_END(ctx); + + if (ctx->Stencil.WriteMask == (GLstencil) mask) + return; + + FLUSH_VERTICES(ctx, _NEW_STENCIL); + ctx->Stencil.WriteMask = (GLstencil) mask; + + if (ctx->Driver.StencilMask) { + (*ctx->Driver.StencilMask)( ctx, mask ); + } +} + + + +void +_mesa_StencilOp(GLenum fail, GLenum zfail, GLenum zpass) +{ + GET_CURRENT_CONTEXT(ctx); + ASSERT_OUTSIDE_BEGIN_END(ctx); + + switch (fail) { + case GL_KEEP: + case GL_ZERO: + case GL_REPLACE: + case GL_INCR: + case GL_DECR: + case GL_INVERT: + break; + case GL_INCR_WRAP_EXT: + case GL_DECR_WRAP_EXT: + if (!ctx->Extensions.EXT_stencil_wrap) { + break; + } + /* FALL-THROUGH */ + default: + _mesa_error(ctx, GL_INVALID_ENUM, "glStencilOp"); + return; + } + switch (zfail) { + case GL_KEEP: + case GL_ZERO: + case GL_REPLACE: + case GL_INCR: + case GL_DECR: + case GL_INVERT: + break; + case GL_INCR_WRAP_EXT: + case GL_DECR_WRAP_EXT: + if (ctx->Extensions.EXT_stencil_wrap) { + break; + } + /* FALL-THROUGH */ + default: + _mesa_error(ctx, GL_INVALID_ENUM, "glStencilOp"); + return; + } + switch (zpass) { + case GL_KEEP: + case GL_ZERO: + case GL_REPLACE: + case GL_INCR: + case GL_DECR: + case GL_INVERT: + break; + case GL_INCR_WRAP_EXT: + case GL_DECR_WRAP_EXT: + if (ctx->Extensions.EXT_stencil_wrap) { + break; + } + /* FALL-THROUGH */ + default: + _mesa_error(ctx, GL_INVALID_ENUM, "glStencilOp"); + return; + } + + if (ctx->Stencil.ZFailFunc == zfail && + ctx->Stencil.ZPassFunc == zpass && + ctx->Stencil.FailFunc == fail) + return; + + FLUSH_VERTICES(ctx, _NEW_STENCIL); + ctx->Stencil.ZFailFunc = zfail; + ctx->Stencil.ZPassFunc = zpass; + ctx->Stencil.FailFunc = fail; + + if (ctx->Driver.StencilOp) { + (*ctx->Driver.StencilOp)(ctx, fail, zfail, zpass); + } +} Index: dll/opengl/opengl32/mesa/stencil.h =================================================================== --- dll/opengl/opengl32/mesa/stencil.h (revision 0) +++ dll/opengl/opengl32/mesa/stencil.h (working copy) @@ -0,0 +1,52 @@ +/* $Id: stencil.h,v 1.9 2001/03/12 00:48:38 gareth Exp $ */ + +/* + * Mesa 3-D graphics library + * Version: 3.5 + * + * Copyright (C) 1999-2001 Brian Paul 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 + * BRIAN PAUL 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. + */ + + +#ifndef STENCIL_H +#define STENCIL_H + + +#include "mtypes.h" + + +extern void +_mesa_ClearStencil( GLint s ); + + +extern void +_mesa_StencilFunc( GLenum func, GLint ref, GLuint mask ); + + +extern void +_mesa_StencilMask( GLuint mask ); + + +extern void +_mesa_StencilOp( GLenum fail, GLenum zfail, GLenum zpass ); + + + +#endif Index: dll/opengl/opengl32/mesa/swrast/s_aaline.c =================================================================== --- dll/opengl/opengl32/mesa/swrast/s_aaline.c (revision 0) +++ dll/opengl/opengl32/mesa/swrast/s_aaline.c (working copy) @@ -0,0 +1,533 @@ +/* $Id: s_aaline.c,v 1.11 2001/05/21 18:13:43 brianp Exp $ */ + +/* + * Mesa 3-D graphics library + * Version: 3.5 + * + * Copyright (C) 1999-2001 Brian Paul 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 + * BRIAN PAUL 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. + */ + + +#include "glheader.h" +#include "swrast/s_aaline.h" +#include "swrast/s_pb.h" +#include "swrast/s_context.h" +#include "swrast/swrast.h" +#include "mtypes.h" +#include "mmath.h" + + +#define SUB_PIXEL 4 + + +/* + * Info about the AA line we're rendering + */ +struct LineInfo +{ + GLfloat x0, y0; /* start */ + GLfloat x1, y1; /* end */ + GLfloat dx, dy; /* direction vector */ + GLfloat len; /* length */ + GLfloat halfWidth; /* half of line width */ + GLfloat xAdj, yAdj; /* X and Y adjustment for quad corners around line */ + /* for coverage computation */ + GLfloat qx0, qy0; /* quad vertices */ + GLfloat qx1, qy1; + GLfloat qx2, qy2; + GLfloat qx3, qy3; + GLfloat ex0, ey0; /* quad edge vectors */ + GLfloat ex1, ey1; + GLfloat ex2, ey2; + GLfloat ex3, ey3; + + /* DO_Z */ + GLfloat zPlane[4]; + /* DO_FOG */ + GLfloat fPlane[4]; + /* DO_RGBA */ + GLfloat rPlane[4], gPlane[4], bPlane[4], aPlane[4]; + /* DO_INDEX */ + GLfloat iPlane[4]; + /* DO_SPEC */ + GLfloat srPlane[4], sgPlane[4], sbPlane[4]; + /* DO_TEX or DO_MULTITEX */ + GLfloat sPlane[MAX_TEXTURE_UNITS][4]; + GLfloat tPlane[MAX_TEXTURE_UNITS][4]; + GLfloat uPlane[MAX_TEXTURE_UNITS][4]; + GLfloat vPlane[MAX_TEXTURE_UNITS][4]; + GLfloat lambda[MAX_TEXTURE_UNITS]; + GLfloat texWidth[MAX_TEXTURE_UNITS], texHeight[MAX_TEXTURE_UNITS]; +}; + + + +/* + * Compute the equation of a plane used to interpolate line fragment data + * such as color, Z, texture coords, etc. + * Input: (x0, y0) and (x1,y1) are the endpoints of the line. + * z0, and z1 are the end point values to interpolate. + * Output: plane - the plane equation. + * + * Note: we don't really have enough parameters to specify a plane. + * We take the endpoints of the line and compute a plane such that + * the cross product of the line vector and the plane normal is + * parallel to the projection plane. + */ +static void +compute_plane(GLfloat x0, GLfloat y0, GLfloat x1, GLfloat y1, + GLfloat z0, GLfloat z1, GLfloat plane[4]) +{ +#if 0 + /* original */ + const GLfloat px = x1 - x0; + const GLfloat py = y1 - y0; + const GLfloat pz = z1 - z0; + const GLfloat qx = -py; + const GLfloat qy = px; + const GLfloat qz = 0; + const GLfloat a = py * qz - pz * qy; + const GLfloat b = pz * qx - px * qz; + const GLfloat c = px * qy - py * qx; + const GLfloat d = -(a * x0 + b * y0 + c * z0); + plane[0] = a; + plane[1] = b; + plane[2] = c; + plane[3] = d; +#else + /* simplified */ + const GLfloat px = x1 - x0; + const GLfloat py = y1 - y0; + const GLfloat pz = z0 - z1; + const GLfloat a = pz * px; + const GLfloat b = pz * py; + const GLfloat c = px * px + py * py; + const GLfloat d = -(a * x0 + b * y0 + c * z0); + if (a == 0.0 && b == 0.0 && c == 0.0 && d == 0.0) { + plane[0] = 0.0; + plane[1] = 0.0; + plane[2] = 1.0; + plane[3] = 0.0; + } + else { + plane[0] = a; + plane[1] = b; + plane[2] = c; + plane[3] = d; + } +#endif +} + + +static INLINE void +constant_plane(GLfloat value, GLfloat plane[4]) +{ + plane[0] = 0.0; + plane[1] = 0.0; + plane[2] = -1.0; + plane[3] = value; +} + + +static INLINE GLfloat +solve_plane(GLfloat x, GLfloat y, const GLfloat plane[4]) +{ + const GLfloat z = (plane[3] + plane[0] * x + plane[1] * y) / -plane[2]; + return z; +} + +#define SOLVE_PLANE(X, Y, PLANE) \ + ((PLANE[3] + PLANE[0] * (X) + PLANE[1] * (Y)) / -PLANE[2]) + + +/* + * Return 1 / solve_plane(). + */ +static INLINE GLfloat +solve_plane_recip(GLfloat x, GLfloat y, const GLfloat plane[4]) +{ + const GLfloat denom = plane[3] + plane[0] * x + plane[1] * y; + if (denom == 0.0) + return 0.0; + else + return -plane[2] / denom; +} + + +/* + * Solve plane and return clamped GLchan value. + */ +static INLINE GLchan +solve_plane_chan(GLfloat x, GLfloat y, const GLfloat plane[4]) +{ + GLfloat z = (plane[3] + plane[0] * x + plane[1] * y) / -plane[2] + 0.5F; + if (z < 0.0F) + return 0; + else if (z > CHAN_MAXF) + return (GLchan) CHAN_MAXF; + return (GLchan) (GLint) z; +} + + +/* + * Compute mipmap level of detail. + */ +static INLINE GLfloat +compute_lambda(const GLfloat sPlane[4], const GLfloat tPlane[4], + GLfloat invQ, GLfloat width, GLfloat height) +{ + GLfloat dudx = sPlane[0] / sPlane[2] * invQ * width; + GLfloat dudy = sPlane[1] / sPlane[2] * invQ * width; + GLfloat dvdx = tPlane[0] / tPlane[2] * invQ * height; + GLfloat dvdy = tPlane[1] / tPlane[2] * invQ * height; + GLfloat r1 = dudx * dudx + dudy * dudy; + GLfloat r2 = dvdx * dvdx + dvdy * dvdy; + GLfloat rho2 = r1 + r2; + /* return log base 2 of rho */ + if (rho2 == 0.0F) + return 0.0; + else + return log(rho2) * 1.442695 * 0.5; /* 1.442695 = 1/log(2) */ +} + + + + +/* + * Fill in the samples[] array with the (x,y) subpixel positions of + * xSamples * ySamples sample positions. + * Note that the four corner samples are put into the first four + * positions of the array. This allows us to optimize for the common + * case of all samples being inside the polygon. + */ +static void +make_sample_table(GLint xSamples, GLint ySamples, GLfloat samples[][2]) +{ + const GLfloat dx = 1.0F / (GLfloat) xSamples; + const GLfloat dy = 1.0F / (GLfloat) ySamples; + GLint x, y; + GLint i; + + i = 4; + for (x = 0; x < xSamples; x++) { + for (y = 0; y < ySamples; y++) { + GLint j; + if (x == 0 && y == 0) { + /* lower left */ + j = 0; + } + else if (x == xSamples - 1 && y == 0) { + /* lower right */ + j = 1; + } + else if (x == 0 && y == ySamples - 1) { + /* upper left */ + j = 2; + } + else if (x == xSamples - 1 && y == ySamples - 1) { + /* upper right */ + j = 3; + } + else { + j = i++; + } + samples[j][0] = x * dx + 0.5 * dx; + samples[j][1] = y * dy + 0.5 * dy; + } + } +} + + + +/* + * Compute how much of the given pixel's area is inside the rectangle + * defined by vertices v0, v1, v2, v3. + * Vertices MUST be specified in counter-clockwise order. + * Return: coverage in [0, 1]. + */ +static GLfloat +compute_coveragef(const struct LineInfo *info, + GLint winx, GLint winy) +{ + static GLfloat samples[SUB_PIXEL * SUB_PIXEL][2]; + static GLboolean haveSamples = GL_FALSE; + const GLfloat x = (GLfloat) winx; + const GLfloat y = (GLfloat) winy; + GLint stop = 4, i; + GLfloat insideCount = SUB_PIXEL * SUB_PIXEL; + + if (!haveSamples) { + make_sample_table(SUB_PIXEL, SUB_PIXEL, samples); + haveSamples = GL_TRUE; + } + +#if 0 /*DEBUG*/ + { + const GLfloat area = dx0 * dy1 - dx1 * dy0; + assert(area >= 0.0); + } +#endif + + for (i = 0; i < stop; i++) { + const GLfloat sx = x + samples[i][0]; + const GLfloat sy = y + samples[i][1]; + const GLfloat fx0 = sx - info->qx0; + const GLfloat fy0 = sy - info->qy0; + const GLfloat fx1 = sx - info->qx1; + const GLfloat fy1 = sy - info->qy1; + const GLfloat fx2 = sx - info->qx2; + const GLfloat fy2 = sy - info->qy2; + const GLfloat fx3 = sx - info->qx3; + const GLfloat fy3 = sy - info->qy3; + /* cross product determines if sample is inside or outside each edge */ + GLfloat cross0 = (info->ex0 * fy0 - info->ey0 * fx0); + GLfloat cross1 = (info->ex1 * fy1 - info->ey1 * fx1); + GLfloat cross2 = (info->ex2 * fy2 - info->ey2 * fx2); + GLfloat cross3 = (info->ex3 * fy3 - info->ey3 * fx3); + /* Check if the sample is exactly on an edge. If so, let cross be a + * positive or negative value depending on the direction of the edge. + */ + if (cross0 == 0.0F) + cross0 = info->ex0 + info->ey0; + if (cross1 == 0.0F) + cross1 = info->ex1 + info->ey1; + if (cross2 == 0.0F) + cross2 = info->ex2 + info->ey2; + if (cross3 == 0.0F) + cross3 = info->ex3 + info->ey3; + if (cross0 < 0.0F || cross1 < 0.0F || cross2 < 0.0F || cross3 < 0.0F) { + /* point is outside quadrilateral */ + insideCount -= 1.0F; + stop = SUB_PIXEL * SUB_PIXEL; + } + } + if (stop == 4) + return 1.0F; + else + return insideCount * (1.0F / (SUB_PIXEL * SUB_PIXEL)); +} + + + +typedef void (*plot_func)(GLcontext *ctx, const struct LineInfo *line, + struct pixel_buffer *pb, int ix, int iy); + + +/* + * Draw an AA line segment (called many times per line when stippling) + */ +static void +segment(GLcontext *ctx, + struct LineInfo *line, + plot_func plot, + struct pixel_buffer *pb, + GLfloat t0, GLfloat t1) +{ + const GLfloat absDx = (line->dx < 0.0F) ? -line->dx : line->dx; + const GLfloat absDy = (line->dy < 0.0F) ? -line->dy : line->dy; + /* compute the actual segment's endpoints */ + const GLfloat x0 = line->x0 + t0 * line->dx; + const GLfloat y0 = line->y0 + t0 * line->dy; + const GLfloat x1 = line->x0 + t1 * line->dx; + const GLfloat y1 = line->y0 + t1 * line->dy; + + /* compute vertices of the line-aligned quadrilateral */ + line->qx0 = x0 - line->yAdj; + line->qy0 = y0 + line->xAdj; + line->qx1 = x0 + line->yAdj; + line->qy1 = y0 - line->xAdj; + line->qx2 = x1 + line->yAdj; + line->qy2 = y1 - line->xAdj; + line->qx3 = x1 - line->yAdj; + line->qy3 = y1 + line->xAdj; + /* compute the quad's edge vectors (for coverage calc) */ + line->ex0 = line->qx1 - line->qx0; + line->ey0 = line->qy1 - line->qy0; + line->ex1 = line->qx2 - line->qx1; + line->ey1 = line->qy2 - line->qy1; + line->ex2 = line->qx3 - line->qx2; + line->ey2 = line->qy3 - line->qy2; + line->ex3 = line->qx0 - line->qx3; + line->ey3 = line->qy0 - line->qy3; + + if (absDx > absDy) { + /* X-major line */ + GLfloat dydx = line->dy / line->dx; + GLfloat xLeft, xRight, yBot, yTop; + GLint ix, ixRight; + if (x0 < x1) { + xLeft = x0 - line->halfWidth; + xRight = x1 + line->halfWidth; + if (line->dy >= 0.0) { + yBot = y0 - 3.0 * line->halfWidth; + yTop = y0 + line->halfWidth; + } + else { + yBot = y0 - line->halfWidth; + yTop = y0 + 3.0 * line->halfWidth; + } + } + else { + xLeft = x1 - line->halfWidth; + xRight = x0 + line->halfWidth; + if (line->dy <= 0.0) { + yBot = y1 - 3.0 * line->halfWidth; + yTop = y1 + line->halfWidth; + } + else { + yBot = y1 - line->halfWidth; + yTop = y1 + 3.0 * line->halfWidth; + } + } + + /* scan along the line, left-to-right */ + ixRight = (GLint) (xRight + 1.0F); + + /*printf("avg span height: %g\n", yTop - yBot);*/ + for (ix = (GLint) xLeft; ix < ixRight; ix++) { + const GLint iyBot = (GLint) yBot; + const GLint iyTop = (GLint) (yTop + 1.0F); + GLint iy; + /* scan across the line, bottom-to-top */ + for (iy = iyBot; iy < iyTop; iy++) { + (*plot)(ctx, line, pb, ix, iy); + } + yBot += dydx; + yTop += dydx; + } + } + else { + /* Y-major line */ + GLfloat dxdy = line->dx / line->dy; + GLfloat yBot, yTop, xLeft, xRight; + GLint iy, iyTop; + if (y0 < y1) { + yBot = y0 - line->halfWidth; + yTop = y1 + line->halfWidth; + if (line->dx >= 0.0) { + xLeft = x0 - 3.0 * line->halfWidth; + xRight = x0 + line->halfWidth; + } + else { + xLeft = x0 - line->halfWidth; + xRight = x0 + 3.0 * line->halfWidth; + } + } + else { + yBot = y1 - line->halfWidth; + yTop = y0 + line->halfWidth; + if (line->dx <= 0.0) { + xLeft = x1 - 3.0 * line->halfWidth; + xRight = x1 + line->halfWidth; + } + else { + xLeft = x1 - line->halfWidth; + xRight = x1 + 3.0 * line->halfWidth; + } + } + + /* scan along the line, bottom-to-top */ + iyTop = (GLint) (yTop + 1.0F); + + /*printf("avg span width: %g\n", xRight - xLeft);*/ + for (iy = (GLint) yBot; iy < iyTop; iy++) { + const GLint ixLeft = (GLint) xLeft; + const GLint ixRight = (GLint) (xRight + 1.0F); + GLint ix; + /* scan across the line, left-to-right */ + for (ix = ixLeft; ix < ixRight; ix++) { + (*plot)(ctx, line, pb, ix, iy); + } + xLeft += dxdy; + xRight += dxdy; + } + } +} + + +#define NAME(x) aa_ci_##x +#define DO_Z +#define DO_FOG +#define DO_INDEX +#include "s_aalinetemp.h" + + +#define NAME(x) aa_rgba_##x +#define DO_Z +#define DO_FOG +#define DO_RGBA +#include "s_aalinetemp.h" + + +#define NAME(x) aa_tex_rgba_##x +#define DO_Z +#define DO_FOG +#define DO_RGBA +#define DO_TEX +#include "s_aalinetemp.h" + + +#define NAME(x) aa_multitex_rgba_##x +#define DO_Z +#define DO_RGBA +#define DO_MULTITEX +#include "s_aalinetemp.h" + + +#define NAME(x) aa_multitex_spec_##x +#define DO_Z +#define DO_RGBA +#define DO_MULTITEX +#define DO_SPEC +#include "s_aalinetemp.h" + + + +void +_swrast_choose_aa_line_function(GLcontext *ctx) +{ + SWcontext *swrast = SWRAST_CONTEXT(ctx); + + ASSERT(ctx->Line.SmoothFlag); + + if (ctx->Visual.rgbMode) { + /* RGBA */ + if (ctx->Texture._ReallyEnabled) { + if (ctx->Texture._ReallyEnabled > TEXTURE0_ANY) { + /* Multitextured! */ + if (ctx->Light.Model.ColorControl==GL_SEPARATE_SPECULAR_COLOR || + ctx->Fog.ColorSumEnabled) + swrast->Line = aa_multitex_spec_line; + else + swrast->Line = aa_multitex_rgba_line; + } + else { + swrast->Line = aa_tex_rgba_line; + } + } + else { + swrast->Line = aa_rgba_line; + } + } + else { + /* Color Index */ + swrast->Line = aa_ci_line; + } +} Index: dll/opengl/opengl32/mesa/swrast/s_aaline.h =================================================================== --- dll/opengl/opengl32/mesa/swrast/s_aaline.h (revision 0) +++ dll/opengl/opengl32/mesa/swrast/s_aaline.h (working copy) @@ -0,0 +1,40 @@ +/* $Id: s_aaline.h,v 1.3 2001/03/12 00:48:41 gareth Exp $ */ + +/* + * Mesa 3-D graphics library + * Version: 3.5 + * + * Copyright (C) 1999-2001 Brian Paul 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 + * BRIAN PAUL 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. + */ + + +#ifndef S_AALINE_H +#define S_AALINE_H + + +#include "mtypes.h" +#include "swrast.h" + + +extern void +_swrast_choose_aa_line_function(GLcontext *ctx); + + +#endif Index: dll/opengl/opengl32/mesa/swrast/s_aalinetemp.h =================================================================== --- dll/opengl/opengl32/mesa/swrast/s_aalinetemp.h (revision 0) +++ dll/opengl/opengl32/mesa/swrast/s_aalinetemp.h (working copy) @@ -0,0 +1,325 @@ +/* $Id: s_aalinetemp.h,v 1.12 2001/05/21 18:13:43 brianp Exp $ */ + +/* + * Mesa 3-D graphics library + * Version: 3.5 + * + * Copyright (C) 1999-2001 Brian Paul 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 + * BRIAN PAUL 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. + */ + + +/* + * Antialiased line template. + */ + + +/* + * Function to render each fragment in the AA line. + */ +static void +NAME(plot)(GLcontext *ctx, const struct LineInfo *line, + struct pixel_buffer *pb, int ix, int iy) +{ + const GLfloat fx = (GLfloat) ix; + const GLfloat fy = (GLfloat) iy; + const GLfloat coverage = compute_coveragef(line, ix, iy); + GLdepth z; + GLfloat fog; +#ifdef DO_RGBA + GLchan red, green, blue, alpha; +#else + GLint index; +#endif + GLchan specRed, specGreen, specBlue; + GLfloat tex[MAX_TEXTURE_UNITS][4], lambda[MAX_TEXTURE_UNITS]; + + if (coverage == 0.0) + return; + + /* + * Compute Z, color, texture coords, fog for the fragment by + * solving the plane equations at (ix,iy). + */ +#ifdef DO_Z + z = (GLdepth) solve_plane(fx, fy, line->zPlane); +#else + z = 0.0; +#endif +#ifdef DO_FOG + fog = solve_plane(fx, fy, line->fPlane); +#else + fog = 0.0; +#endif +#ifdef DO_RGBA + red = solve_plane_chan(fx, fy, line->rPlane); + green = solve_plane_chan(fx, fy, line->gPlane); + blue = solve_plane_chan(fx, fy, line->bPlane); + alpha = solve_plane_chan(fx, fy, line->aPlane); +#endif +#ifdef DO_INDEX + index = (GLint) solve_plane(fx, fy, line->iPlane); +#endif +#ifdef DO_SPEC + specRed = solve_plane_chan(fx, fy, line->srPlane); + specGreen = solve_plane_chan(fx, fy, line->sgPlane); + specBlue = solve_plane_chan(fx, fy, line->sbPlane); +#else + (void) specRed; + (void) specGreen; + (void) specBlue; +#endif +#ifdef DO_TEX + { + GLfloat invQ = solve_plane_recip(fx, fy, line->vPlane[0]); + tex[0][0] = solve_plane(fx, fy, line->sPlane[0]) * invQ; + tex[0][1] = solve_plane(fx, fy, line->tPlane[0]) * invQ; + tex[0][2] = solve_plane(fx, fy, line->uPlane[0]) * invQ; + lambda[0] = compute_lambda(line->sPlane[0], line->tPlane[0], invQ, + line->texWidth[0], line->texHeight[0]); + } +#elif defined(DO_MULTITEX) + { + GLuint unit; + for (unit = 0; unit < ctx->Const.MaxTextureUnits; unit++) { + if (ctx->Texture.Unit[unit]._ReallyEnabled) { + GLfloat invQ = solve_plane_recip(fx, fy, line->vPlane[unit]); + tex[unit][0] = solve_plane(fx, fy, line->sPlane[unit]) * invQ; + tex[unit][1] = solve_plane(fx, fy, line->tPlane[unit]) * invQ; + tex[unit][2] = solve_plane(fx, fy, line->uPlane[unit]) * invQ; + lambda[unit] = compute_lambda(line->sPlane[unit], + line->tPlane[unit], invQ, + line->texWidth[unit], line->texHeight[unit]); + } + } + } +#else + (void) tex[0][0]; + (void) lambda[0]; +#endif + + + PB_COVERAGE(pb, coverage); + +#if defined(DO_MULTITEX) +#if defined(DO_SPEC) + PB_WRITE_MULTITEX_SPEC_PIXEL(pb, ix, iy, z, fog, red, green, blue, alpha, + specRed, specGreen, specBlue, tex); +#else + PB_WRITE_MULTITEX_PIXEL(pb, ix, iy, z, fog, red, green, blue, alpha, tex); +#endif +#elif defined(DO_TEX) + PB_WRITE_TEX_PIXEL(pb, ix, iy, z, fog, red, green, blue, alpha, + tex[0][0], tex[0][1], tex[0][2]); +#elif defined(DO_RGBA) + PB_WRITE_RGBA_PIXEL(pb, ix, iy, z, fog, red, green, blue, alpha); +#elif defined(DO_INDEX) + PB_WRITE_CI_PIXEL(pb, ix, iy, z, fog, index); +#endif + + pb->haveCoverage = GL_TRUE; + PB_CHECK_FLUSH(ctx, pb); +} + + + +/* + * Line setup + */ +static void +NAME(line)(GLcontext *ctx, const SWvertex *v0, const SWvertex *v1) +{ + SWcontext *swrast = SWRAST_CONTEXT(ctx); + struct pixel_buffer *pb = SWRAST_CONTEXT(ctx)->PB; + GLfloat tStart, tEnd; /* segment start, end along line length */ + GLboolean inSegment; + GLint iLen, i; + + /* Init the LineInfo struct */ + struct LineInfo line; + line.x0 = v0->win[0]; + line.y0 = v0->win[1]; + line.x1 = v1->win[0]; + line.y1 = v1->win[1]; + line.dx = line.x1 - line.x0; + line.dy = line.y1 - line.y0; + line.len = sqrt(line.dx * line.dx + line.dy * line.dy); + line.halfWidth = 0.5F * ctx->Line.Width; + + if (line.len == 0.0) + return; + + line.xAdj = line.dx / line.len * line.halfWidth; + line.yAdj = line.dy / line.len * line.halfWidth; + +#ifdef DO_Z + compute_plane(line.x0, line.y0, line.x1, line.y1, + v0->win[2], v1->win[2], line.zPlane); +#endif +#ifdef DO_FOG + compute_plane(line.x0, line.y0, line.x1, line.y1, + v0->fog, v1->fog, line.fPlane); +#endif +#ifdef DO_RGBA + if (ctx->Light.ShadeModel == GL_SMOOTH) { + compute_plane(line.x0, line.y0, line.x1, line.y1, + v0->color[RCOMP], v1->color[RCOMP], line.rPlane); + compute_plane(line.x0, line.y0, line.x1, line.y1, + v0->color[GCOMP], v1->color[GCOMP], line.gPlane); + compute_plane(line.x0, line.y0, line.x1, line.y1, + v0->color[BCOMP], v1->color[BCOMP], line.bPlane); + compute_plane(line.x0, line.y0, line.x1, line.y1, + v0->color[ACOMP], v1->color[ACOMP], line.aPlane); + } + else { + constant_plane(v1->color[RCOMP], line.rPlane); + constant_plane(v1->color[GCOMP], line.gPlane); + constant_plane(v1->color[BCOMP], line.bPlane); + constant_plane(v1->color[ACOMP], line.aPlane); + } +#endif +#ifdef DO_SPEC + if (ctx->Light.ShadeModel == GL_SMOOTH) { + compute_plane(line.x0, line.y0, line.x1, line.y1, + v0->specular[RCOMP], v1->specular[RCOMP], line.srPlane); + compute_plane(line.x0, line.y0, line.x1, line.y1, + v0->specular[GCOMP], v1->specular[GCOMP], line.sgPlane); + compute_plane(line.x0, line.y0, line.x1, line.y1, + v0->specular[BCOMP], v1->specular[BCOMP], line.sbPlane); + } + else { + constant_plane(v1->specular[RCOMP], line.srPlane); + constant_plane(v1->specular[GCOMP], line.sgPlane); + constant_plane(v1->specular[BCOMP], line.sbPlane); + } +#endif +#ifdef DO_INDEX + if (ctx->Light.ShadeModel == GL_SMOOTH) { + compute_plane(line.x0, line.y0, line.x1, line.y1, + v0->index, v1->index, line.iPlane); + } + else { + constant_plane(v1->index, line.iPlane); + } +#endif +#ifdef DO_TEX + { + const struct gl_texture_object *obj = ctx->Texture.Unit[0]._Current; + const struct gl_texture_image *texImage = obj->Image[obj->BaseLevel]; + const GLfloat invW0 = v0->win[3]; + const GLfloat invW1 = v1->win[3]; + const GLfloat s0 = v0->texcoord[0][0] * invW0; + const GLfloat s1 = v1->texcoord[0][0] * invW1; + const GLfloat t0 = v0->texcoord[0][1] * invW0; + const GLfloat t1 = v1->texcoord[0][1] * invW0; + const GLfloat r0 = v0->texcoord[0][2] * invW0; + const GLfloat r1 = v1->texcoord[0][2] * invW0; + const GLfloat q0 = v0->texcoord[0][3] * invW0; + const GLfloat q1 = v1->texcoord[0][3] * invW0; + compute_plane(line.x0, line.y0, line.x1, line.y1, s0, s1, line.sPlane[0]); + compute_plane(line.x0, line.y0, line.x1, line.y1, t0, t1, line.tPlane[0]); + compute_plane(line.x0, line.y0, line.x1, line.y1, r0, r1, line.uPlane[0]); + compute_plane(line.x0, line.y0, line.x1, line.y1, q0, q1, line.vPlane[0]); + line.texWidth[0] = (GLfloat) texImage->Width; + line.texHeight[0] = (GLfloat) texImage->Height; + } +#elif defined(DO_MULTITEX) + { + GLuint u; + for (u = 0; u < ctx->Const.MaxTextureUnits; u++) { + if (ctx->Texture.Unit[u]._ReallyEnabled) { + const struct gl_texture_object *obj = ctx->Texture.Unit[u]._Current; + const struct gl_texture_image *texImage = obj->Image[obj->BaseLevel]; + const GLfloat invW0 = v0->win[3]; + const GLfloat invW1 = v1->win[3]; + const GLfloat s0 = v0->texcoord[u][0] * invW0; + const GLfloat s1 = v1->texcoord[u][0] * invW1; + const GLfloat t0 = v0->texcoord[u][1] * invW0; + const GLfloat t1 = v1->texcoord[u][1] * invW0; + const GLfloat r0 = v0->texcoord[u][2] * invW0; + const GLfloat r1 = v1->texcoord[u][2] * invW0; + const GLfloat q0 = v0->texcoord[u][3] * invW0; + const GLfloat q1 = v1->texcoord[u][3] * invW0; + compute_plane(line.x0, line.y0, line.x1, line.y1, s0, s1, line.sPlane[u]); + compute_plane(line.x0, line.y0, line.x1, line.y1, t0, t1, line.tPlane[u]); + compute_plane(line.x0, line.y0, line.x1, line.y1, r0, r1, line.uPlane[u]); + compute_plane(line.x0, line.y0, line.x1, line.y1, q0, q1, line.vPlane[u]); + line.texWidth[u] = (GLfloat) texImage->Width; + line.texHeight[u] = (GLfloat) texImage->Height; + } + } + } +#endif + + tStart = tEnd = 0.0; + inSegment = GL_FALSE; + iLen = (GLint) line.len; + + if (ctx->Line.StippleFlag) { + for (i = 0; i < iLen; i++) { + const GLuint bit = (swrast->StippleCounter / ctx->Line.StippleFactor) & 0xf; + if ((1 << bit) & ctx->Line.StipplePattern) { + /* stipple bit is on */ + const GLfloat t = (GLfloat) i / (GLfloat) line.len; + if (!inSegment) { + /* start new segment */ + inSegment = GL_TRUE; + tStart = t; + } + else { + /* still in the segment, extend it */ + tEnd = t; + } + } + else { + /* stipple bit is off */ + if (inSegment && (tEnd > tStart)) { + /* draw the segment */ + segment(ctx, &line, NAME(plot), pb, tStart, tEnd); + inSegment = GL_FALSE; + } + else { + /* still between segments, do nothing */ + } + } + swrast->StippleCounter++; + } + + if (inSegment) { + /* draw the final segment of the line */ + segment(ctx, &line, NAME(plot), pb, tStart, 1.0F); + } + } + else { + /* non-stippled */ + segment(ctx, &line, NAME(plot), pb, 0.0, 1.0); + } +} + + + + +#undef DO_Z +#undef DO_FOG +#undef DO_RGBA +#undef DO_INDEX +#undef DO_SPEC +#undef DO_TEX +#undef DO_MULTITEX +#undef NAME Index: dll/opengl/opengl32/mesa/swrast/s_aatriangle.c =================================================================== --- dll/opengl/opengl32/mesa/swrast/s_aatriangle.c (revision 0) +++ dll/opengl/opengl32/mesa/swrast/s_aatriangle.c (working copy) @@ -0,0 +1,446 @@ +/* $Id: s_aatriangle.c,v 1.18 2001/05/29 15:23:15 brianp Exp $ */ + +/* + * Mesa 3-D graphics library + * Version: 3.5 + * + * Copyright (C) 1999-2001 Brian Paul 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 + * BRIAN PAUL 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. + */ + + +/* + * Antialiased Triangle rasterizers + */ + + +#include "mem.h" +#include "mmath.h" +#include "s_aatriangle.h" +#include "s_context.h" +#include "s_span.h" + + +/* + * Compute coefficients of a plane using the X,Y coords of the v0, v1, v2 + * vertices and the given Z values. + */ +static INLINE void +compute_plane(const GLfloat v0[], const GLfloat v1[], const GLfloat v2[], + GLfloat z0, GLfloat z1, GLfloat z2, GLfloat plane[4]) +{ + const GLfloat px = v1[0] - v0[0]; + const GLfloat py = v1[1] - v0[1]; + const GLfloat pz = z1 - z0; + + const GLfloat qx = v2[0] - v0[0]; + const GLfloat qy = v2[1] - v0[1]; + const GLfloat qz = z2 - z0; + + const GLfloat a = py * qz - pz * qy; + const GLfloat b = pz * qx - px * qz; + const GLfloat c = px * qy - py * qx; + const GLfloat d = -(a * v0[0] + b * v0[1] + c * z0); + + plane[0] = a; + plane[1] = b; + plane[2] = c; + plane[3] = d; +} + + +/* + * Compute coefficients of a plane with a constant Z value. + */ +static INLINE void +constant_plane(GLfloat value, GLfloat plane[4]) +{ + plane[0] = 0.0; + plane[1] = 0.0; + plane[2] = -1.0; + plane[3] = value; +} + +#define CONSTANT_PLANE(VALUE, PLANE) \ +do { \ + PLANE[0] = 0.0F; \ + PLANE[1] = 0.0F; \ + PLANE[2] = -1.0F; \ + PLANE[3] = VALUE; \ +} while (0) + + + +/* + * Solve plane equation for Z at (X,Y). + */ +static INLINE GLfloat +solve_plane(GLfloat x, GLfloat y, const GLfloat plane[4]) +{ + const GLfloat z = (plane[3] + plane[0] * x + plane[1] * y) / -plane[2]; + return z; +} + + +#define SOLVE_PLANE(X, Y, PLANE) \ + ((PLANE[3] + PLANE[0] * (X) + PLANE[1] * (Y)) / -PLANE[2]) + + +/* + * Return 1 / solve_plane(). + */ +static INLINE GLfloat +solve_plane_recip(GLfloat x, GLfloat y, const GLfloat plane[4]) +{ + const GLfloat denom = plane[3] + plane[0] * x + plane[1] * y; + if (denom == 0.0F) + return 0.0F; + else + return -plane[2] / denom; +} + + + +/* + * Solve plane and return clamped GLchan value. + */ +static INLINE GLchan +solve_plane_chan(GLfloat x, GLfloat y, const GLfloat plane[4]) +{ + GLfloat z = (plane[3] + plane[0] * x + plane[1] * y) / -plane[2] + 0.5F; + if (z < 0.0F) + return 0; + else if (z > CHAN_MAXF) + return (GLchan) CHAN_MAXF; + return (GLchan) (GLint) z; +} + + + +/* + * Compute how much (area) of the given pixel is inside the triangle. + * Vertices MUST be specified in counter-clockwise order. + * Return: coverage in [0, 1]. + */ +static GLfloat +compute_coveragef(const GLfloat v0[3], const GLfloat v1[3], + const GLfloat v2[3], GLint winx, GLint winy) +{ +#define B 0.125 + static const GLfloat samples[16][2] = { + /* start with the four corners */ + { 0.00+B, 0.00+B }, + { 0.75+B, 0.00+B }, + { 0.00+B, 0.75+B }, + { 0.75+B, 0.75+B }, + /* continue with interior samples */ + { 0.25+B, 0.00+B }, + { 0.50+B, 0.00+B }, + { 0.00+B, 0.25+B }, + { 0.25+B, 0.25+B }, + { 0.50+B, 0.25+B }, + { 0.75+B, 0.25+B }, + { 0.00+B, 0.50+B }, + { 0.25+B, 0.50+B }, + { 0.50+B, 0.50+B }, + { 0.75+B, 0.50+B }, + { 0.25+B, 0.75+B }, + { 0.50+B, 0.75+B } + }; + const GLfloat x = (GLfloat) winx; + const GLfloat y = (GLfloat) winy; + const GLfloat dx0 = v1[0] - v0[0]; + const GLfloat dy0 = v1[1] - v0[1]; + const GLfloat dx1 = v2[0] - v1[0]; + const GLfloat dy1 = v2[1] - v1[1]; + const GLfloat dx2 = v0[0] - v2[0]; + const GLfloat dy2 = v0[1] - v2[1]; + GLint stop = 4, i; + GLfloat insideCount = 16.0F; + +#ifdef DEBUG + { + const GLfloat area = dx0 * dy1 - dx1 * dy0; + assert(area >= 0.0); + } +#endif + + for (i = 0; i < stop; i++) { + const GLfloat sx = x + samples[i][0]; + const GLfloat sy = y + samples[i][1]; + const GLfloat fx0 = sx - v0[0]; + const GLfloat fy0 = sy - v0[1]; + const GLfloat fx1 = sx - v1[0]; + const GLfloat fy1 = sy - v1[1]; + const GLfloat fx2 = sx - v2[0]; + const GLfloat fy2 = sy - v2[1]; + /* cross product determines if sample is inside or outside each edge */ + GLfloat cross0 = (dx0 * fy0 - dy0 * fx0); + GLfloat cross1 = (dx1 * fy1 - dy1 * fx1); + GLfloat cross2 = (dx2 * fy2 - dy2 * fx2); + /* Check if the sample is exactly on an edge. If so, let cross be a + * positive or negative value depending on the direction of the edge. + */ + if (cross0 == 0.0F) + cross0 = dx0 + dy0; + if (cross1 == 0.0F) + cross1 = dx1 + dy1; + if (cross2 == 0.0F) + cross2 = dx2 + dy2; + if (cross0 < 0.0F || cross1 < 0.0F || cross2 < 0.0F) { + /* point is outside triangle */ + insideCount -= 1.0F; + stop = 16; + } + } + if (stop == 4) + return 1.0F; + else + return insideCount * (1.0F / 16.0F); +} + + + +/* + * Compute how much (area) of the given pixel is inside the triangle. + * Vertices MUST be specified in counter-clockwise order. + * Return: coverage in [0, 15]. + */ +static GLint +compute_coveragei(const GLfloat v0[3], const GLfloat v1[3], + const GLfloat v2[3], GLint winx, GLint winy) +{ + /* NOTE: 15 samples instead of 16. + * A better sample distribution could be used. + */ + static const GLfloat samples[15][2] = { + /* start with the four corners */ + { 0.00+B, 0.00+B }, + { 0.75+B, 0.00+B }, + { 0.00+B, 0.75+B }, + { 0.75+B, 0.75+B }, + /* continue with interior samples */ + { 0.25+B, 0.00+B }, + { 0.50+B, 0.00+B }, + { 0.00+B, 0.25+B }, + { 0.25+B, 0.25+B }, + { 0.50+B, 0.25+B }, + { 0.75+B, 0.25+B }, + { 0.00+B, 0.50+B }, + { 0.25+B, 0.50+B }, + /*{ 0.50, 0.50 },*/ + { 0.75+B, 0.50+B }, + { 0.25+B, 0.75+B }, + { 0.50+B, 0.75+B } + }; + const GLfloat x = (GLfloat) winx; + const GLfloat y = (GLfloat) winy; + const GLfloat dx0 = v1[0] - v0[0]; + const GLfloat dy0 = v1[1] - v0[1]; + const GLfloat dx1 = v2[0] - v1[0]; + const GLfloat dy1 = v2[1] - v1[1]; + const GLfloat dx2 = v0[0] - v2[0]; + const GLfloat dy2 = v0[1] - v2[1]; + GLint stop = 4, i; + GLint insideCount = 15; + +#ifdef DEBUG + { + const GLfloat area = dx0 * dy1 - dx1 * dy0; + assert(area >= 0.0); + } +#endif + + for (i = 0; i < stop; i++) { + const GLfloat sx = x + samples[i][0]; + const GLfloat sy = y + samples[i][1]; + const GLfloat fx0 = sx - v0[0]; + const GLfloat fy0 = sy - v0[1]; + const GLfloat fx1 = sx - v1[0]; + const GLfloat fy1 = sy - v1[1]; + const GLfloat fx2 = sx - v2[0]; + const GLfloat fy2 = sy - v2[1]; + /* cross product determines if sample is inside or outside each edge */ + GLfloat cross0 = (dx0 * fy0 - dy0 * fx0); + GLfloat cross1 = (dx1 * fy1 - dy1 * fx1); + GLfloat cross2 = (dx2 * fy2 - dy2 * fx2); + /* Check if the sample is exactly on an edge. If so, let cross be a + * positive or negative value depending on the direction of the edge. + */ + if (cross0 == 0.0F) + cross0 = dx0 + dy0; + if (cross1 == 0.0F) + cross1 = dx1 + dy1; + if (cross2 == 0.0F) + cross2 = dx2 + dy2; + if (cross0 < 0.0F || cross1 < 0.0F || cross2 < 0.0F) { + /* point is outside triangle */ + insideCount--; + stop = 15; + } + } + if (stop == 4) + return 15; + else + return insideCount; +} + + + +static void +rgba_aa_tri(GLcontext *ctx, + const SWvertex *v0, + const SWvertex *v1, + const SWvertex *v2) +{ +#define DO_Z +#define DO_FOG +#define DO_RGBA +#include "s_aatritemp.h" +} + + +static void +index_aa_tri(GLcontext *ctx, + const SWvertex *v0, + const SWvertex *v1, + const SWvertex *v2) +{ +#define DO_Z +#define DO_FOG +#define DO_INDEX +#include "s_aatritemp.h" +} + + +/* + * Compute mipmap level of detail. + */ +static INLINE GLfloat +compute_lambda(const GLfloat sPlane[4], const GLfloat tPlane[4], + GLfloat invQ, GLfloat width, GLfloat height) +{ + GLfloat dudx = sPlane[0] / sPlane[2] * invQ * width; + GLfloat dudy = sPlane[1] / sPlane[2] * invQ * width; + GLfloat dvdx = tPlane[0] / tPlane[2] * invQ * height; + GLfloat dvdy = tPlane[1] / tPlane[2] * invQ * height; + GLfloat r1 = dudx * dudx + dudy * dudy; + GLfloat r2 = dvdx * dvdx + dvdy * dvdy; + GLfloat rho2 = r1 + r2; + /* return log base 2 of rho */ + if (rho2 == 0.0F) + return 0.0; + else + return log(rho2) * 1.442695 * 0.5; /* 1.442695 = 1/log(2) */ +} + + +static void +tex_aa_tri(GLcontext *ctx, + const SWvertex *v0, + const SWvertex *v1, + const SWvertex *v2) +{ +#define DO_Z +#define DO_FOG +#define DO_RGBA +#define DO_TEX +#include "s_aatritemp.h" +} + + +static void +spec_tex_aa_tri(GLcontext *ctx, + const SWvertex *v0, + const SWvertex *v1, + const SWvertex *v2) +{ +#define DO_Z +#define DO_FOG +#define DO_RGBA +#define DO_TEX +#define DO_SPEC +#include "s_aatritemp.h" +} + + +static void +multitex_aa_tri(GLcontext *ctx, + const SWvertex *v0, + const SWvertex *v1, + const SWvertex *v2) +{ +#define DO_Z +#define DO_FOG +#define DO_RGBA +#define DO_MULTITEX +#include "s_aatritemp.h" +} + +static void +spec_multitex_aa_tri(GLcontext *ctx, + const SWvertex *v0, + const SWvertex *v1, + const SWvertex *v2) +{ +#define DO_Z +#define DO_FOG +#define DO_RGBA +#define DO_MULTITEX +#define DO_SPEC +#include "s_aatritemp.h" +} + + +/* + * Examine GL state and set swrast->Triangle to an + * appropriate antialiased triangle rasterizer function. + */ +void +_mesa_set_aa_triangle_function(GLcontext *ctx) +{ + ASSERT(ctx->Polygon.SmoothFlag); + + if (ctx->Texture._ReallyEnabled) { + if (ctx->_TriangleCaps & DD_SEPARATE_SPECULAR) { + if (ctx->Texture._ReallyEnabled > TEXTURE0_ANY) { + SWRAST_CONTEXT(ctx)->Triangle = spec_multitex_aa_tri; + } + else { + SWRAST_CONTEXT(ctx)->Triangle = spec_tex_aa_tri; + } + } + else { + if (ctx->Texture._ReallyEnabled > TEXTURE0_ANY) { + SWRAST_CONTEXT(ctx)->Triangle = multitex_aa_tri; + } + else { + SWRAST_CONTEXT(ctx)->Triangle = tex_aa_tri; + } + } + } + else if (ctx->Visual.rgbMode) { + SWRAST_CONTEXT(ctx)->Triangle = rgba_aa_tri; + } + else { + SWRAST_CONTEXT(ctx)->Triangle = index_aa_tri; + } + + ASSERT(SWRAST_CONTEXT(ctx)->Triangle); +} Index: dll/opengl/opengl32/mesa/swrast/s_aatriangle.h =================================================================== --- dll/opengl/opengl32/mesa/swrast/s_aatriangle.h (revision 0) +++ dll/opengl/opengl32/mesa/swrast/s_aatriangle.h (working copy) @@ -0,0 +1,40 @@ +/* $Id: s_aatriangle.h,v 1.3 2001/03/12 00:48:41 gareth Exp $ */ + +/* + * Mesa 3-D graphics library + * Version: 3.5 + * + * Copyright (C) 1999-2001 Brian Paul 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 + * BRIAN PAUL 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. + */ + + +#ifndef S_AATRIANGLE_H +#define S_AATRIANGLE_H + + +#include "mtypes.h" +#include "swrast.h" + + +extern void +_mesa_set_aa_triangle_function(GLcontext *ctx); + + +#endif Index: dll/opengl/opengl32/mesa/swrast/s_aatritemp.h =================================================================== --- dll/opengl/opengl32/mesa/swrast/s_aatritemp.h (revision 0) +++ dll/opengl/opengl32/mesa/swrast/s_aatritemp.h (working copy) @@ -0,0 +1,595 @@ +/* $Id: s_aatritemp.h,v 1.18 2001/06/05 21:41:05 brianp Exp $ */ + +/* + * Mesa 3-D graphics library + * Version: 3.5 + * + * Copyright (C) 1999-2001 Brian Paul 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 + * BRIAN PAUL 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. + */ + + +/* + * Antialiased Triangle Rasterizer Template + * + * This file is #include'd to generate custom AA triangle rasterizers. + * NOTE: this code hasn't been optimized yet. That'll come after it + * works correctly. + * + * The following macros may be defined to indicate what auxillary information + * must be copmuted across the triangle: + * DO_Z - if defined, compute Z values + * DO_RGBA - if defined, compute RGBA values + * DO_INDEX - if defined, compute color index values + * DO_SPEC - if defined, compute specular RGB values + * DO_TEX - if defined, compute unit 0 STRQ texcoords + * DO_MULTITEX - if defined, compute all unit's STRQ texcoords + */ + +/*void triangle( GLcontext *ctx, GLuint v0, GLuint v1, GLuint v2, GLuint pv )*/ +{ + const GLfloat *p0 = v0->win; + const GLfloat *p1 = v1->win; + const GLfloat *p2 = v2->win; + const SWvertex *vMin, *vMid, *vMax; + GLint iyMin, iyMax; + GLfloat yMin, yMax; + GLboolean ltor; + GLfloat majDx, majDy; /* major (i.e. long) edge dx and dy */ + +#ifdef DO_Z + GLfloat zPlane[4]; + GLdepth z[MAX_WIDTH]; +#endif +#ifdef DO_FOG + GLfloat fogPlane[4]; + GLfloat fog[MAX_WIDTH]; +#else + GLfloat *fog = NULL; +#endif +#ifdef DO_RGBA + GLfloat rPlane[4], gPlane[4], bPlane[4], aPlane[4]; + DEFMARRAY(GLchan, rgba, MAX_WIDTH, 4); /* mac 32k limitation */ +#endif +#ifdef DO_INDEX + GLfloat iPlane[4]; + GLuint index[MAX_WIDTH]; + GLint icoverageSpan[MAX_WIDTH]; +#else + GLfloat coverageSpan[MAX_WIDTH]; +#endif +#ifdef DO_SPEC + GLfloat srPlane[4], sgPlane[4], sbPlane[4]; + DEFMARRAY(GLchan, spec, MAX_WIDTH, 4); +#endif +#ifdef DO_TEX + GLfloat sPlane[4], tPlane[4], uPlane[4], vPlane[4]; + GLfloat texWidth, texHeight; + DEFARRAY(GLfloat, s, MAX_WIDTH); /* mac 32k limitation */ + DEFARRAY(GLfloat, t, MAX_WIDTH); + DEFARRAY(GLfloat, u, MAX_WIDTH); + DEFARRAY(GLfloat, lambda, MAX_WIDTH); +#elif defined(DO_MULTITEX) + GLfloat sPlane[MAX_TEXTURE_UNITS][4]; + GLfloat tPlane[MAX_TEXTURE_UNITS][4]; + GLfloat uPlane[MAX_TEXTURE_UNITS][4]; + GLfloat vPlane[MAX_TEXTURE_UNITS][4]; + GLfloat texWidth[MAX_TEXTURE_UNITS], texHeight[MAX_TEXTURE_UNITS]; + DEFMARRAY(GLfloat, s, MAX_TEXTURE_UNITS, MAX_WIDTH); /* mac 32k limit */ + DEFMARRAY(GLfloat, t, MAX_TEXTURE_UNITS, MAX_WIDTH); + DEFMARRAY(GLfloat, u, MAX_TEXTURE_UNITS, MAX_WIDTH); + DEFMARRAY(GLfloat, lambda, MAX_TEXTURE_UNITS, MAX_WIDTH); +#endif + GLfloat bf = SWRAST_CONTEXT(ctx)->_backface_sign; + +#ifdef DO_RGBA + CHECKARRAY(rgba, return); /* mac 32k limitation */ +#endif +#ifdef DO_SPEC + CHECKARRAY(spec, return); +#endif +#if defined(DO_TEX) || defined(DO_MULTITEX) + CHECKARRAY(s, return); + CHECKARRAY(t, return); + CHECKARRAY(u, return); + CHECKARRAY(lambda, return); +#endif + + /* determine bottom to top order of vertices */ + { + GLfloat y0 = v0->win[1]; + GLfloat y1 = v1->win[1]; + GLfloat y2 = v2->win[1]; + if (y0 <= y1) { + if (y1 <= y2) { + vMin = v0; vMid = v1; vMax = v2; /* y0<=y1<=y2 */ + } + else if (y2 <= y0) { + vMin = v2; vMid = v0; vMax = v1; /* y2<=y0<=y1 */ + } + else { + vMin = v0; vMid = v2; vMax = v1; bf = -bf; /* y0<=y2<=y1 */ + } + } + else { + if (y0 <= y2) { + vMin = v1; vMid = v0; vMax = v2; bf = -bf; /* y1<=y0<=y2 */ + } + else if (y2 <= y1) { + vMin = v2; vMid = v1; vMax = v0; bf = -bf; /* y2<=y1<=y0 */ + } + else { + vMin = v1; vMid = v2; vMax = v0; /* y1<=y2<=y0 */ + } + } + } + + majDx = vMax->win[0] - vMin->win[0]; + majDy = vMax->win[1] - vMin->win[1]; + + { + const GLfloat botDx = vMid->win[0] - vMin->win[0]; + const GLfloat botDy = vMid->win[1] - vMin->win[1]; + const GLfloat area = majDx * botDy - botDx * majDy; + ltor = (GLboolean) (area < 0.0F); + /* Do backface culling */ + if (area * bf < 0 || area * area < .0025) + return; + } + +#ifndef DO_OCCLUSION_TEST + ctx->OcclusionResult = GL_TRUE; +#endif + + /* Plane equation setup: + * We evaluate plane equations at window (x,y) coordinates in order + * to compute color, Z, fog, texcoords, etc. This isn't terribly + * efficient but it's easy and reliable. + */ +#ifdef DO_Z + compute_plane(p0, p1, p2, p0[2], p1[2], p2[2], zPlane); +#endif +#ifdef DO_FOG + compute_plane(p0, p1, p2, v0->fog, v1->fog, v2->fog, fogPlane); +#endif +#ifdef DO_RGBA + if (ctx->Light.ShadeModel == GL_SMOOTH) { + compute_plane(p0, p1, p2, v0->color[0], v1->color[0], v2->color[0], rPlane); + compute_plane(p0, p1, p2, v0->color[1], v1->color[1], v2->color[1], gPlane); + compute_plane(p0, p1, p2, v0->color[2], v1->color[2], v2->color[2], bPlane); + compute_plane(p0, p1, p2, v0->color[3], v1->color[3], v2->color[3], aPlane); + } + else { + constant_plane(v2->color[RCOMP], rPlane); + constant_plane(v2->color[GCOMP], gPlane); + constant_plane(v2->color[BCOMP], bPlane); + constant_plane(v2->color[ACOMP], aPlane); + } +#endif +#ifdef DO_INDEX + if (ctx->Light.ShadeModel == GL_SMOOTH) { + compute_plane(p0, p1, p2, v0->index, + v1->index, v2->index, iPlane); + } + else { + constant_plane(v2->index, iPlane); + } +#endif +#ifdef DO_SPEC + if (ctx->Light.ShadeModel == GL_SMOOTH) { + compute_plane(p0, p1, p2, v0->specular[0], v1->specular[0], v2->specular[0],srPlane); + compute_plane(p0, p1, p2, v0->specular[1], v1->specular[1], v2->specular[1],sgPlane); + compute_plane(p0, p1, p2, v0->specular[2], v1->specular[2], v2->specular[2],sbPlane); + } + else { + constant_plane(v2->specular[RCOMP], srPlane); + constant_plane(v2->specular[GCOMP], sgPlane); + constant_plane(v2->specular[BCOMP], sbPlane); + } +#endif +#ifdef DO_TEX + { + const struct gl_texture_object *obj = ctx->Texture.Unit[0]._Current; + const struct gl_texture_image *texImage = obj->Image[obj->BaseLevel]; + const GLfloat invW0 = v0->win[3]; + const GLfloat invW1 = v1->win[3]; + const GLfloat invW2 = v2->win[3]; + const GLfloat s0 = v0->texcoord[0][0] * invW0; + const GLfloat s1 = v1->texcoord[0][0] * invW1; + const GLfloat s2 = v2->texcoord[0][0] * invW2; + const GLfloat t0 = v0->texcoord[0][1] * invW0; + const GLfloat t1 = v1->texcoord[0][1] * invW1; + const GLfloat t2 = v2->texcoord[0][1] * invW2; + const GLfloat r0 = v0->texcoord[0][2] * invW0; + const GLfloat r1 = v1->texcoord[0][2] * invW1; + const GLfloat r2 = v2->texcoord[0][2] * invW2; + const GLfloat q0 = v0->texcoord[0][3] * invW0; + const GLfloat q1 = v1->texcoord[0][3] * invW1; + const GLfloat q2 = v2->texcoord[0][3] * invW2; + compute_plane(p0, p1, p2, s0, s1, s2, sPlane); + compute_plane(p0, p1, p2, t0, t1, t2, tPlane); + compute_plane(p0, p1, p2, r0, r1, r2, uPlane); + compute_plane(p0, p1, p2, q0, q1, q2, vPlane); + texWidth = (GLfloat) texImage->Width; + texHeight = (GLfloat) texImage->Height; + } +#elif defined(DO_MULTITEX) + { + GLuint u; + for (u = 0; u < ctx->Const.MaxTextureUnits; u++) { + if (ctx->Texture.Unit[u]._ReallyEnabled) { + const struct gl_texture_object *obj = ctx->Texture.Unit[u]._Current; + const struct gl_texture_image *texImage = obj->Image[obj->BaseLevel]; + const GLfloat invW0 = v0->win[3]; + const GLfloat invW1 = v1->win[3]; + const GLfloat invW2 = v2->win[3]; + const GLfloat s0 = v0->texcoord[u][0] * invW0; + const GLfloat s1 = v1->texcoord[u][0] * invW1; + const GLfloat s2 = v2->texcoord[u][0] * invW2; + const GLfloat t0 = v0->texcoord[u][1] * invW0; + const GLfloat t1 = v1->texcoord[u][1] * invW1; + const GLfloat t2 = v2->texcoord[u][1] * invW2; + const GLfloat r0 = v0->texcoord[u][2] * invW0; + const GLfloat r1 = v1->texcoord[u][2] * invW1; + const GLfloat r2 = v2->texcoord[u][2] * invW2; + const GLfloat q0 = v0->texcoord[u][3] * invW0; + const GLfloat q1 = v1->texcoord[u][3] * invW1; + const GLfloat q2 = v2->texcoord[u][3] * invW2; + compute_plane(p0, p1, p2, s0, s1, s2, sPlane[u]); + compute_plane(p0, p1, p2, t0, t1, t2, tPlane[u]); + compute_plane(p0, p1, p2, r0, r1, r2, uPlane[u]); + compute_plane(p0, p1, p2, q0, q1, q2, vPlane[u]); + texWidth[u] = (GLfloat) texImage->Width; + texHeight[u] = (GLfloat) texImage->Height; + } + } + } +#endif + + /* Begin bottom-to-top scan over the triangle. + * The long edge will either be on the left or right side of the + * triangle. We always scan from the long edge toward the shorter + * edges, stopping when we find that coverage = 0. If the long edge + * is on the left we scan left-to-right. Else, we scan right-to-left. + */ + yMin = vMin->win[1]; + yMax = vMax->win[1]; + iyMin = (GLint) yMin; + iyMax = (GLint) yMax + 1; + + if (ltor) { + /* scan left to right */ + const GLfloat *pMin = vMin->win; + const GLfloat *pMid = vMid->win; + const GLfloat *pMax = vMax->win; + const GLfloat dxdy = majDx / majDy; + const GLfloat xAdj = dxdy < 0.0F ? -dxdy : 0.0F; + GLfloat x = pMin[0] - (yMin - iyMin) * dxdy; + GLint iy; + for (iy = iyMin; iy < iyMax; iy++, x += dxdy) { + GLint ix, startX = (GLint) (x - xAdj); + GLuint count, n; + GLfloat coverage = 0.0F; + /* skip over fragments with zero coverage */ + while (startX < MAX_WIDTH) { + coverage = compute_coveragef(pMin, pMid, pMax, startX, iy); + if (coverage > 0.0F) + break; + startX++; + } + + /* enter interior of triangle */ + ix = startX; + count = 0; + while (coverage > 0.0F) { + /* (cx,cy) = center of fragment */ + const GLfloat cx = ix + 0.5F, cy = iy + 0.5F; +#ifdef DO_INDEX + icoverageSpan[count] = compute_coveragei(pMin, pMid, pMax, ix, iy); +#else + coverageSpan[count] = coverage; +#endif +#ifdef DO_Z + z[count] = (GLdepth) solve_plane(cx, cy, zPlane); +#endif +#ifdef DO_FOG + fog[count] = solve_plane(cx, cy, fogPlane); +#endif +#ifdef DO_RGBA + rgba[count][RCOMP] = solve_plane_chan(cx, cy, rPlane); + rgba[count][GCOMP] = solve_plane_chan(cx, cy, gPlane); + rgba[count][BCOMP] = solve_plane_chan(cx, cy, bPlane); + rgba[count][ACOMP] = solve_plane_chan(cx, cy, aPlane); +#endif +#ifdef DO_INDEX + index[count] = (GLint) solve_plane(cx, cy, iPlane); +#endif +#ifdef DO_SPEC + spec[count][RCOMP] = solve_plane_chan(cx, cy, srPlane); + spec[count][GCOMP] = solve_plane_chan(cx, cy, sgPlane); + spec[count][BCOMP] = solve_plane_chan(cx, cy, sbPlane); +#endif +#ifdef DO_TEX + { + const GLfloat invQ = solve_plane_recip(cx, cy, vPlane); + s[count] = solve_plane(cx, cy, sPlane) * invQ; + t[count] = solve_plane(cx, cy, tPlane) * invQ; + u[count] = solve_plane(cx, cy, uPlane) * invQ; + lambda[count] = compute_lambda(sPlane, tPlane, invQ, + texWidth, texHeight); + } +#elif defined(DO_MULTITEX) + { + GLuint unit; + for (unit = 0; unit < ctx->Const.MaxTextureUnits; unit++) { + if (ctx->Texture.Unit[unit]._ReallyEnabled) { + GLfloat invQ = solve_plane_recip(cx, cy, vPlane[unit]); + s[unit][count] = solve_plane(cx, cy, sPlane[unit]) * invQ; + t[unit][count] = solve_plane(cx, cy, tPlane[unit]) * invQ; + u[unit][count] = solve_plane(cx, cy, uPlane[unit]) * invQ; + lambda[unit][count] = compute_lambda(sPlane[unit], + tPlane[unit], invQ, texWidth[unit], texHeight[unit]); + } + } + } +#endif + ix++; + count++; + coverage = compute_coveragef(pMin, pMid, pMax, ix, iy); + } + + if (ix <= startX) + continue; + + n = (GLuint) ix - (GLuint) startX; + +#ifdef DO_MULTITEX +# ifdef DO_SPEC + _mesa_write_multitexture_span(ctx, n, startX, iy, z, fog, + (const GLfloat (*)[MAX_WIDTH]) s, + (const GLfloat (*)[MAX_WIDTH]) t, + (const GLfloat (*)[MAX_WIDTH]) u, + (GLfloat (*)[MAX_WIDTH]) lambda, + rgba, (const GLchan (*)[4]) spec, + coverageSpan, GL_POLYGON); +# else + _mesa_write_multitexture_span(ctx, n, startX, iy, z, fog, + (const GLfloat (*)[MAX_WIDTH]) s, + (const GLfloat (*)[MAX_WIDTH]) t, + (const GLfloat (*)[MAX_WIDTH]) u, + lambda, rgba, NULL, coverageSpan, + GL_POLYGON); +# endif +#elif defined(DO_TEX) +# ifdef DO_SPEC + _mesa_write_texture_span(ctx, n, startX, iy, z, fog, + s, t, u, lambda, rgba, + (const GLchan (*)[4]) spec, + coverageSpan, GL_POLYGON); +# else + _mesa_write_texture_span(ctx, n, startX, iy, z, fog, + s, t, u, lambda, + rgba, NULL, coverageSpan, GL_POLYGON); +# endif +#elif defined(DO_RGBA) + _mesa_write_rgba_span(ctx, n, startX, iy, z, fog, rgba, + coverageSpan, GL_POLYGON); +#elif defined(DO_INDEX) + _mesa_write_index_span(ctx, n, startX, iy, z, fog, index, + icoverageSpan, GL_POLYGON); +#endif + } + } + else { + /* scan right to left */ + const GLfloat *pMin = vMin->win; + const GLfloat *pMid = vMid->win; + const GLfloat *pMax = vMax->win; + const GLfloat dxdy = majDx / majDy; + const GLfloat xAdj = dxdy > 0 ? dxdy : 0.0F; + GLfloat x = pMin[0] - (yMin - iyMin) * dxdy; + GLint iy; + for (iy = iyMin; iy < iyMax; iy++, x += dxdy) { + GLint ix, left, startX = (GLint) (x + xAdj); + GLuint count, n; + GLfloat coverage = 0.0F; + + /* make sure we're not past the window edge */ + if (startX >= ctx->DrawBuffer->_Xmax) { + startX = ctx->DrawBuffer->_Xmax - 1; + } + + /* skip fragments with zero coverage */ + while (startX >= 0) { + coverage = compute_coveragef(pMin, pMax, pMid, startX, iy); + if (coverage > 0.0F) + break; + startX--; + } + + /* enter interior of triangle */ + ix = startX; + count = 0; + while (coverage > 0.0F) { + /* (cx,cy) = center of fragment */ + const GLfloat cx = ix + 0.5F, cy = iy + 0.5F; +#ifdef DO_INDEX + icoverageSpan[ix] = compute_coveragei(pMin, pMid, pMax, ix, iy); +#else + coverageSpan[ix] = coverage; +#endif +#ifdef DO_Z + z[ix] = (GLdepth) solve_plane(cx, cy, zPlane); +#endif +#ifdef DO_FOG + fog[ix] = solve_plane(cx, cy, fogPlane); +#endif +#ifdef DO_RGBA + rgba[ix][RCOMP] = solve_plane_chan(cx, cy, rPlane); + rgba[ix][GCOMP] = solve_plane_chan(cx, cy, gPlane); + rgba[ix][BCOMP] = solve_plane_chan(cx, cy, bPlane); + rgba[ix][ACOMP] = solve_plane_chan(cx, cy, aPlane); +#endif +#ifdef DO_INDEX + index[ix] = (GLint) solve_plane(cx, cy, iPlane); +#endif +#ifdef DO_SPEC + spec[ix][RCOMP] = solve_plane_chan(cx, cy, srPlane); + spec[ix][GCOMP] = solve_plane_chan(cx, cy, sgPlane); + spec[ix][BCOMP] = solve_plane_chan(cx, cy, sbPlane); +#endif +#ifdef DO_TEX + { + const GLfloat invQ = solve_plane_recip(cx, cy, vPlane); + s[ix] = solve_plane(cx, cy, sPlane) * invQ; + t[ix] = solve_plane(cx, cy, tPlane) * invQ; + u[ix] = solve_plane(cx, cy, uPlane) * invQ; + lambda[ix] = compute_lambda(sPlane, tPlane, invQ, + texWidth, texHeight); + } +#elif defined(DO_MULTITEX) + { + GLuint unit; + for (unit = 0; unit < ctx->Const.MaxTextureUnits; unit++) { + if (ctx->Texture.Unit[unit]._ReallyEnabled) { + GLfloat invQ = solve_plane_recip(cx, cy, vPlane[unit]); + s[unit][ix] = solve_plane(cx, cy, sPlane[unit]) * invQ; + t[unit][ix] = solve_plane(cx, cy, tPlane[unit]) * invQ; + u[unit][ix] = solve_plane(cx, cy, uPlane[unit]) * invQ; + lambda[unit][ix] = compute_lambda(sPlane[unit], + tPlane[unit], invQ, texWidth[unit], texHeight[unit]); + } + } + } +#endif + ix--; + count++; + coverage = compute_coveragef(pMin, pMax, pMid, ix, iy); + } + + if (startX <= ix) + continue; + + n = (GLuint) startX - (GLuint) ix; + + left = ix + 1; +#ifdef DO_MULTITEX + { + GLuint unit; + for (unit = 0; unit < ctx->Const.MaxTextureUnits; unit++) { + if (ctx->Texture.Unit[unit]._ReallyEnabled) { + GLint j; + for (j = 0; j < (GLint) n; j++) { + s[unit][j] = s[unit][j + left]; + t[unit][j] = t[unit][j + left]; + u[unit][j] = u[unit][j + left]; + lambda[unit][j] = lambda[unit][j + left]; + } + } + } + } +# ifdef DO_SPEC + _mesa_write_multitexture_span(ctx, n, left, iy, z + left, fog + left, + (const GLfloat (*)[MAX_WIDTH]) s, + (const GLfloat (*)[MAX_WIDTH]) t, + (const GLfloat (*)[MAX_WIDTH]) u, + lambda, rgba + left, + (const GLchan (*)[4]) (spec + left), + coverageSpan + left, + GL_POLYGON); +# else + _mesa_write_multitexture_span(ctx, n, left, iy, z + left, fog + left, + (const GLfloat (*)[MAX_WIDTH]) s, + (const GLfloat (*)[MAX_WIDTH]) t, + (const GLfloat (*)[MAX_WIDTH]) u, + lambda, + rgba + left, NULL, coverageSpan + left, + GL_POLYGON); +# endif +#elif defined(DO_TEX) +# ifdef DO_SPEC + _mesa_write_texture_span(ctx, n, left, iy, z + left, fog + left, + s + left, t + left, u + left, + lambda + left, rgba + left, + (const GLchan (*)[4]) (spec + left), + coverageSpan + left, + GL_POLYGON); +# else + _mesa_write_texture_span(ctx, n, left, iy, z + left, fog + left, + s + left, t + left, + u + left, lambda + left, + rgba + left, NULL, + coverageSpan + left, GL_POLYGON); +# endif +#elif defined(DO_RGBA) + _mesa_write_rgba_span(ctx, n, left, iy, z + left, fog + left, + rgba + left, coverageSpan + left, GL_POLYGON); +#elif defined(DO_INDEX) + _mesa_write_index_span(ctx, n, left, iy, z + left, fog + left, + index + left, icoverageSpan + left, GL_POLYGON); +#endif + } + } + +#ifdef DO_RGBA + UNDEFARRAY(rgba); /* mac 32k limitation */ +#endif +#ifdef DO_SPEC + UNDEFARRAY(spec); +#endif +#if defined(DO_TEX) || defined(DO_MULTITEX) + UNDEFARRAY(s); + UNDEFARRAY(t); + UNDEFARRAY(u); + UNDEFARRAY(lambda); +#endif +} + + +#ifdef DO_Z +#undef DO_Z +#endif + +#ifdef DO_FOG +#undef DO_FOG +#endif + +#ifdef DO_RGBA +#undef DO_RGBA +#endif + +#ifdef DO_INDEX +#undef DO_INDEX +#endif + +#ifdef DO_SPEC +#undef DO_SPEC +#endif + +#ifdef DO_TEX +#undef DO_TEX +#endif + +#ifdef DO_MULTITEX +#undef DO_MULTITEX +#endif + +#ifdef DO_OCCLUSION_TEST +#undef DO_OCCLUSION_TEST +#endif Index: dll/opengl/opengl32/mesa/swrast/s_accum.c =================================================================== --- dll/opengl/opengl32/mesa/swrast/s_accum.c (revision 0) +++ dll/opengl/opengl32/mesa/swrast/s_accum.c (working copy) @@ -0,0 +1,524 @@ +/* $Id: s_accum.c,v 1.11 2001/04/20 19:21:41 brianp Exp $ */ + +/* + * Mesa 3-D graphics library + * Version: 3.5 + * + * Copyright (C) 1999-2001 Brian Paul 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 + * BRIAN PAUL 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. + */ + + +#include "glheader.h" +#include "context.h" +#include "macros.h" +#include "mmath.h" +#include "mem.h" + +#include "s_accum.h" +#include "s_alphabuf.h" +#include "s_context.h" +#include "s_masking.h" +#include "s_span.h" + + +/* + * Accumulation buffer notes + * + * Normally, accumulation buffer values are GLshorts with values in + * [-32767, 32767] which represent floating point colors in [-1, 1], + * as suggested by the OpenGL specification. + * + * We optimize for the common case used for full-scene antialiasing: + * // start with accum buffer cleared to zero + * glAccum(GL_LOAD, w); // or GL_ACCUM the first image + * glAccum(GL_ACCUM, w); + * ... + * glAccum(GL_ACCUM, w); + * glAccum(GL_RETURN, 1.0); + * That is, we start with an empty accumulation buffer and accumulate + * n images, each with weight w = 1/n. + * In this scenario, we can simply store unscaled integer values in + * the accum buffer instead of scaled integers. We'll also keep track + * of the w value so when we do GL_RETURN we simply divide the accumulated + * values by n (=1/w). + * This lets us avoid _many_ int->float->int conversions. + */ + + +#if CHAN_BITS == 8 +#define USE_OPTIMIZED_ACCUM /* enable the optimization */ +#endif + + + +void +_mesa_alloc_accum_buffer( GLcontext *ctx ) +{ + SWcontext *swrast = SWRAST_CONTEXT(ctx); + GLint n; + + if (ctx->DrawBuffer->Accum) { + FREE( ctx->DrawBuffer->Accum ); + ctx->DrawBuffer->Accum = NULL; + } + + /* allocate accumulation buffer if not already present */ + n = ctx->DrawBuffer->Width * ctx->DrawBuffer->Height * 4 * sizeof(GLaccum); + ctx->DrawBuffer->Accum = (GLaccum *) MALLOC( n ); + if (!ctx->DrawBuffer->Accum) { + /* unable to setup accumulation buffer */ + _mesa_error( ctx, GL_OUT_OF_MEMORY, "glAccum" ); + } +#ifdef USE_OPTIMIZED_ACCUM + swrast->_IntegerAccumMode = GL_TRUE; +#else + swrast->_IntegerAccumMode = GL_FALSE; +#endif + swrast->_IntegerAccumScaler = 0.0; +} + + + + + + +/* + * This is called when we fall out of optimized/unscaled accum buffer mode. + * That is, we convert each unscaled accum buffer value into a scaled value + * representing the range[-1, 1]. + */ +static void rescale_accum( GLcontext *ctx ) +{ + SWcontext *swrast = SWRAST_CONTEXT(ctx); + const GLuint n = ctx->DrawBuffer->Width * ctx->DrawBuffer->Height * 4; + const GLfloat fChanMax = (1 << (sizeof(GLchan) * 8)) - 1; + const GLfloat s = swrast->_IntegerAccumScaler * (32767.0 / fChanMax); + GLaccum *accum = ctx->DrawBuffer->Accum; + GLuint i; + + assert(swrast->_IntegerAccumMode); + assert(accum); + + for (i = 0; i < n; i++) { + accum[i] = (GLaccum) (accum[i] * s); + } + + swrast->_IntegerAccumMode = GL_FALSE; +} + + + + + + +/* + * Clear the accumulation Buffer. + */ +void +_mesa_clear_accum_buffer( GLcontext *ctx ) +{ + SWcontext *swrast = SWRAST_CONTEXT(ctx); + GLuint buffersize; + GLfloat acc_scale; + + if (ctx->Visual.accumRedBits==0) { + /* No accumulation buffer! */ + return; + } + + if (sizeof(GLaccum)==1) { + acc_scale = 127.0; + } + else if (sizeof(GLaccum)==2) { + acc_scale = 32767.0; + } + else { + /* sizeof(GLaccum) > 2 (Cray) */ + acc_scale = (float) SHRT_MAX; + } + + /* number of pixels */ + buffersize = ctx->DrawBuffer->Width * ctx->DrawBuffer->Height; + + if (!ctx->DrawBuffer->Accum) { + /* try to alloc accumulation buffer */ + ctx->DrawBuffer->Accum = (GLaccum *) + MALLOC( buffersize * 4 * sizeof(GLaccum) ); + } + + if (ctx->DrawBuffer->Accum) { + if (ctx->Scissor.Enabled) { + /* Limit clear to scissor box */ + GLaccum r, g, b, a; + GLint i, j; + GLint width, height; + GLaccum *row; + r = (GLaccum) (ctx->Accum.ClearColor[0] * acc_scale); + g = (GLaccum) (ctx->Accum.ClearColor[1] * acc_scale); + b = (GLaccum) (ctx->Accum.ClearColor[2] * acc_scale); + a = (GLaccum) (ctx->Accum.ClearColor[3] * acc_scale); + /* size of region to clear */ + width = 4 * (ctx->DrawBuffer->_Xmax - ctx->DrawBuffer->_Xmin); + height = ctx->DrawBuffer->_Ymax - ctx->DrawBuffer->_Ymin; + /* ptr to first element to clear */ + row = ctx->DrawBuffer->Accum + + 4 * (ctx->DrawBuffer->_Ymin * ctx->DrawBuffer->Width + + ctx->DrawBuffer->_Xmin); + for (j=0;jDrawBuffer->Width; + } + } + else { + /* clear whole buffer */ + if (ctx->Accum.ClearColor[0]==0.0 && + ctx->Accum.ClearColor[1]==0.0 && + ctx->Accum.ClearColor[2]==0.0 && + ctx->Accum.ClearColor[3]==0.0) { + /* Black */ + BZERO( ctx->DrawBuffer->Accum, buffersize * 4 * sizeof(GLaccum) ); + } + else { + /* Not black */ + GLaccum *acc, r, g, b, a; + GLuint i; + + acc = ctx->DrawBuffer->Accum; + r = (GLaccum) (ctx->Accum.ClearColor[0] * acc_scale); + g = (GLaccum) (ctx->Accum.ClearColor[1] * acc_scale); + b = (GLaccum) (ctx->Accum.ClearColor[2] * acc_scale); + a = (GLaccum) (ctx->Accum.ClearColor[3] * acc_scale); + for (i=0;iAccum.ClearColor[0] == 0.0 && ctx->Accum.ClearColor[1] == 0.0 && + ctx->Accum.ClearColor[2] == 0.0 && ctx->Accum.ClearColor[3] == 0.0) { +#ifdef USE_OPTIMIZED_ACCUM + swrast->_IntegerAccumMode = GL_TRUE; +#else + swrast->_IntegerAccumMode = GL_FALSE; +#endif + swrast->_IntegerAccumScaler = 0.0; /* denotes empty accum buffer */ + } + else { + swrast->_IntegerAccumMode = GL_FALSE; + } + } +} + + +void +_swrast_Accum( GLcontext *ctx, GLenum op, GLfloat value, + GLint xpos, GLint ypos, + GLint width, GLint height ) + +{ + SWcontext *swrast = SWRAST_CONTEXT(ctx); + GLuint width4; + GLfloat acc_scale; + GLchan rgba[MAX_WIDTH][4]; + const GLuint colorMask = *((GLuint *) &ctx->Color.ColorMask); + const GLint iChanMax = (1 << (sizeof(GLchan) * 8)) - 1; + const GLfloat fChanMax = (1 << (sizeof(GLchan) * 8)) - 1; + + + if (SWRAST_CONTEXT(ctx)->NewState) + _swrast_validate_derived( ctx ); + + if (!ctx->DrawBuffer->Accum) { + _mesa_warning(ctx, + "Calling glAccum() without an accumulation " + "buffer (low memory?)"); + return; + } + + if (sizeof(GLaccum)==1) { + acc_scale = 127.0; + } + else if (sizeof(GLaccum)==2) { + acc_scale = 32767.0; + } + else { + /* sizeof(GLaccum) > 2 (Cray) */ + acc_scale = (float) SHRT_MAX; + } + + width4 = 4 * width; + + switch (op) { + case GL_ADD: + if (value != 0.0F) { + const GLaccum intVal = (GLaccum) (value * acc_scale); + GLint j; + /* Leave optimized accum buffer mode */ + if (swrast->_IntegerAccumMode) + rescale_accum(ctx); + for (j = 0; j < height; j++) { + GLaccum * acc = ctx->DrawBuffer->Accum + ypos * width4 + 4 * xpos; + GLuint i; + for (i = 0; i < width4; i++) { + acc[i] += intVal; + } + ypos++; + } + } + break; + + case GL_MULT: + if (value != 1.0F) { + GLint j; + /* Leave optimized accum buffer mode */ + if (swrast->_IntegerAccumMode) + rescale_accum(ctx); + for (j = 0; j < height; j++) { + GLaccum *acc = ctx->DrawBuffer->Accum + ypos * width4 + 4 * xpos; + GLuint i; + for (i = 0; i < width4; i++) { + acc[i] = (GLaccum) ( (GLfloat) acc[i] * value ); + } + ypos++; + } + } + break; + + case GL_ACCUM: + if (value == 0.0F) + return; + + (*swrast->Driver.SetReadBuffer)( ctx, ctx->ReadBuffer, + ctx->Pixel.DriverReadBuffer ); + + /* May have to leave optimized accum buffer mode */ + if (swrast->_IntegerAccumScaler == 0.0 && value > 0.0 && value <= 1.0) + swrast->_IntegerAccumScaler = value; + if (swrast->_IntegerAccumMode && value != swrast->_IntegerAccumScaler) + rescale_accum(ctx); + + RENDER_START(swrast,ctx); + + if (swrast->_IntegerAccumMode) { + /* simply add integer color values into accum buffer */ + GLint j; + GLaccum *acc = ctx->DrawBuffer->Accum + ypos * width4 + xpos * 4; + assert(swrast->_IntegerAccumScaler > 0.0); + assert(swrast->_IntegerAccumScaler <= 1.0); + for (j = 0; j < height; j++) { + + GLint i, i4; + _mesa_read_rgba_span(ctx, ctx->DrawBuffer, width, xpos, ypos, rgba); + for (i = i4 = 0; i < width; i++, i4+=4) { + acc[i4+0] += rgba[i][RCOMP]; + acc[i4+1] += rgba[i][GCOMP]; + acc[i4+2] += rgba[i][BCOMP]; + acc[i4+3] += rgba[i][ACOMP]; + } + acc += width4; + ypos++; + } + } + else { + /* scaled integer accum buffer */ + const GLfloat rscale = value * acc_scale / fChanMax; + const GLfloat gscale = value * acc_scale / fChanMax; + const GLfloat bscale = value * acc_scale / fChanMax; + const GLfloat ascale = value * acc_scale / fChanMax; + GLint j; + for (j=0;jDrawBuffer->Accum + ypos * width4 + xpos * 4; + GLint i; + _mesa_read_rgba_span(ctx, ctx->DrawBuffer, width, xpos, ypos, rgba); + for (i=0;iDriver.SetReadBuffer)( ctx, ctx->DrawBuffer, + ctx->Color.DriverDrawBuffer ); + RENDER_FINISH(swrast,ctx); + break; + + case GL_LOAD: + (*swrast->Driver.SetReadBuffer)( ctx, ctx->ReadBuffer, + ctx->Pixel.DriverReadBuffer ); + + /* This is a change to go into optimized accum buffer mode */ + if (value > 0.0 && value <= 1.0) { +#ifdef USE_OPTIMIZED_ACCUM + swrast->_IntegerAccumMode = GL_TRUE; +#else + swrast->_IntegerAccumMode = GL_FALSE; +#endif + swrast->_IntegerAccumScaler = value; + } + else { + swrast->_IntegerAccumMode = GL_FALSE; + swrast->_IntegerAccumScaler = 0.0; + } + + RENDER_START(swrast,ctx); + if (swrast->_IntegerAccumMode) { + /* just copy values into accum buffer */ + GLint j; + GLaccum *acc = ctx->DrawBuffer->Accum + ypos * width4 + xpos * 4; + assert(swrast->_IntegerAccumScaler > 0.0); + assert(swrast->_IntegerAccumScaler <= 1.0); + for (j = 0; j < height; j++) { + GLint i, i4; + _mesa_read_rgba_span(ctx, ctx->DrawBuffer, width, xpos, ypos, rgba); + for (i = i4 = 0; i < width; i++, i4 += 4) { + acc[i4+0] = rgba[i][RCOMP]; + acc[i4+1] = rgba[i][GCOMP]; + acc[i4+2] = rgba[i][BCOMP]; + acc[i4+3] = rgba[i][ACOMP]; + } + acc += width4; + ypos++; + } + } + else { + /* scaled integer accum buffer */ + const GLfloat rscale = value * acc_scale / fChanMax; + const GLfloat gscale = value * acc_scale / fChanMax; + const GLfloat bscale = value * acc_scale / fChanMax; + const GLfloat ascale = value * acc_scale / fChanMax; + const GLfloat d = 3.0 / acc_scale; + GLint i, j; + for (j = 0; j < height; j++) { + GLaccum *acc = ctx->DrawBuffer->Accum + ypos * width4 + xpos * 4; + _mesa_read_rgba_span(ctx, ctx->DrawBuffer, width, xpos, ypos, rgba); + for (i=0;iDriver.SetReadBuffer)( ctx, ctx->DrawBuffer, + ctx->Color.DriverDrawBuffer ); + RENDER_FINISH(swrast,ctx); + break; + + case GL_RETURN: + /* May have to leave optimized accum buffer mode */ + if (swrast->_IntegerAccumMode && value != 1.0) + rescale_accum(ctx); + + RENDER_START(swrast,ctx); + if (swrast->_IntegerAccumMode && swrast->_IntegerAccumScaler > 0) { + /* build lookup table to avoid many floating point multiplies */ + static GLchan multTable[32768]; + static GLfloat prevMult = 0.0; + const GLfloat mult = swrast->_IntegerAccumScaler; + const GLint max = MIN2((GLint) (256 / mult), 32767); + GLint j; + if (mult != prevMult) { + for (j = 0; j < max; j++) + multTable[j] = IROUND((GLfloat) j * mult); + prevMult = mult; + } + + assert(swrast->_IntegerAccumScaler > 0.0); + assert(swrast->_IntegerAccumScaler <= 1.0); + for (j = 0; j < height; j++) { + const GLaccum *acc = ctx->DrawBuffer->Accum + ypos * width4 + xpos*4; + GLint i, i4; + for (i = i4 = 0; i < width; i++, i4 += 4) { + ASSERT(acc[i4+0] < max); + ASSERT(acc[i4+1] < max); + ASSERT(acc[i4+2] < max); + ASSERT(acc[i4+3] < max); + rgba[i][RCOMP] = multTable[acc[i4+0]]; + rgba[i][GCOMP] = multTable[acc[i4+1]]; + rgba[i][BCOMP] = multTable[acc[i4+2]]; + rgba[i][ACOMP] = multTable[acc[i4+3]]; + } + if (colorMask != 0xffffffff) { + _mesa_mask_rgba_span( ctx, width, xpos, ypos, rgba ); + } + (*swrast->Driver.WriteRGBASpan)( ctx, width, xpos, ypos, + (const GLchan (*)[4])rgba, NULL ); + if (ctx->DrawBuffer->UseSoftwareAlphaBuffers + && ctx->Color.ColorMask[ACOMP]) { + _mesa_write_alpha_span(ctx, width, xpos, ypos, + (CONST GLchan (*)[4]) rgba, NULL); + } + ypos++; + } + } + else { + const GLfloat rscale = value / acc_scale * fChanMax; + const GLfloat gscale = value / acc_scale * fChanMax; + const GLfloat bscale = value / acc_scale * fChanMax; + const GLfloat ascale = value / acc_scale * fChanMax; + GLint i, j; + for (j=0;jDrawBuffer->Accum + ypos * width4 + xpos*4; + for (i=0;iDriver.WriteRGBASpan)( ctx, width, xpos, ypos, + (const GLchan (*)[4])rgba, NULL ); + if (ctx->DrawBuffer->UseSoftwareAlphaBuffers + && ctx->Color.ColorMask[ACOMP]) { + _mesa_write_alpha_span(ctx, width, xpos, ypos, + (CONST GLchan (*)[4]) rgba, NULL); + } + ypos++; + } + } + RENDER_FINISH(swrast,ctx); + break; + + default: + _mesa_error( ctx, GL_INVALID_ENUM, "glAccum" ); + } +} Index: dll/opengl/opengl32/mesa/swrast/s_accum.h =================================================================== --- dll/opengl/opengl32/mesa/swrast/s_accum.h (revision 0) +++ dll/opengl/opengl32/mesa/swrast/s_accum.h (working copy) @@ -0,0 +1,45 @@ +/* $Id: s_accum.h,v 1.3 2001/03/12 00:48:41 gareth Exp $ */ + +/* + * Mesa 3-D graphics library + * Version: 3.5 + * + * Copyright (C) 1999-2001 Brian Paul 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 + * BRIAN PAUL 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. + */ + + +#ifndef S_ACCUM_H +#define S_ACCUM_H + + +#include "mtypes.h" +#include "swrast.h" + + +extern void +_mesa_alloc_accum_buffer( GLcontext *ctx ); + + +extern void +_mesa_clear_accum_buffer( GLcontext *ctx ); + + + +#endif Index: dll/opengl/opengl32/mesa/swrast/s_alpha.c =================================================================== --- dll/opengl/opengl32/mesa/swrast/s_alpha.c (revision 0) +++ dll/opengl/opengl32/mesa/swrast/s_alpha.c (working copy) @@ -0,0 +1,98 @@ +/* $Id: s_alpha.c,v 1.4 2001/03/12 00:48:41 gareth Exp $ */ + +/* + * Mesa 3-D graphics library + * Version: 3.5 + * + * Copyright (C) 1999-2001 Brian Paul 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 + * BRIAN PAUL 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. + */ + + +#include "glheader.h" +#include "context.h" +#include "colormac.h" +#include "macros.h" +#include "mmath.h" + +#include "s_alpha.h" + + + + + +/* + * Apply the alpha test to a span of pixels. + * In: rgba - array of pixels + * In/Out: mask - current pixel mask. Pixels which fail the alpha test + * will set the corresponding mask flag to 0. + * Return: 0 = all pixels in the span failed the alpha test. + * 1 = one or more pixels passed the alpha test. + */ +GLint +_mesa_alpha_test( const GLcontext *ctx, + GLuint n, CONST GLchan rgba[][4], GLubyte mask[] ) +{ + GLuint i; + GLchan ref = ctx->Color.AlphaRef; + + /* switch cases ordered from most frequent to less frequent */ + switch (ctx->Color.AlphaFunc) { + case GL_LESS: + for (i=0;i= ref); + } + return 1; + case GL_GREATER: + for (i=0;i ref); + } + return 1; + case GL_NOTEQUAL: + for (i=0;iDrawBuffer->Alpha + (Y) * ctx->DrawBuffer->Width + (X)) + +#define ALPHA_READ_ADDR(X,Y) \ + (ctx->ReadBuffer->Alpha + (Y) * ctx->ReadBuffer->Width + (X)) + + + +/* + * Allocate new front/back/left/right alpha buffers. + * Input: ctx - the context + * + */ +static void +alloc_alpha_buffers( GLcontext *ctx, GLframebuffer *buf ) +{ + GLint bytes = buf->Width * buf->Height * sizeof(GLchan); + + ASSERT(ctx->DrawBuffer->UseSoftwareAlphaBuffers); + + if (buf->FrontLeftAlpha) { + FREE( buf->FrontLeftAlpha ); + } + buf->FrontLeftAlpha = (GLchan *) MALLOC( bytes ); + if (!buf->FrontLeftAlpha) { + /* out of memory */ + _mesa_error( ctx, GL_OUT_OF_MEMORY, + "Couldn't allocate front-left alpha buffer" ); + } + + if (ctx->Visual.doubleBufferMode) { + if (buf->BackLeftAlpha) { + FREE( buf->BackLeftAlpha ); + } + buf->BackLeftAlpha = (GLchan *) MALLOC( bytes ); + if (!buf->BackLeftAlpha) { + /* out of memory */ + _mesa_error( ctx, GL_OUT_OF_MEMORY, + "Couldn't allocate back-left alpha buffer" ); + } + } + + if (ctx->Visual.stereoMode) { + if (buf->FrontRightAlpha) { + FREE( buf->FrontRightAlpha ); + } + buf->FrontRightAlpha = (GLchan *) MALLOC( bytes ); + if (!buf->FrontRightAlpha) { + /* out of memory */ + _mesa_error( ctx, GL_OUT_OF_MEMORY, + "Couldn't allocate front-right alpha buffer" ); + } + + if (ctx->Visual.doubleBufferMode) { + if (buf->BackRightAlpha) { + FREE( buf->BackRightAlpha ); + } + buf->BackRightAlpha = (GLchan *) MALLOC( bytes ); + if (!buf->BackRightAlpha) { + /* out of memory */ + _mesa_error( ctx, GL_OUT_OF_MEMORY, + "Couldn't allocate back-right alpha buffer" ); + } + } + } + + if (ctx->Color.DriverDrawBuffer == GL_FRONT_LEFT) + buf->Alpha = buf->FrontLeftAlpha; + else if (ctx->Color.DriverDrawBuffer == GL_BACK_LEFT) + buf->Alpha = buf->BackLeftAlpha; + else if (ctx->Color.DriverDrawBuffer == GL_FRONT_RIGHT) + buf->Alpha = buf->FrontRightAlpha; + else if (ctx->Color.DriverDrawBuffer == GL_BACK_RIGHT) + buf->Alpha = buf->BackRightAlpha; +} + + +/* + * Allocate a new front and back alpha buffer. + */ +void +_mesa_alloc_alpha_buffers( GLcontext *ctx ) +{ + alloc_alpha_buffers( ctx, ctx->DrawBuffer ); + if (ctx->ReadBuffer != ctx->DrawBuffer) { + alloc_alpha_buffers( ctx, ctx->ReadBuffer ); + } +} + + +/* + * Clear all the alpha buffers + */ +void +_mesa_clear_alpha_buffers( GLcontext *ctx ) +{ + const GLchan aclear = ctx->Color.ClearColor[3]; + GLuint bufferBit; + + ASSERT(ctx->DrawBuffer->UseSoftwareAlphaBuffers); + ASSERT(ctx->Color.ColorMask[ACOMP]); + + /* loop over four possible alpha buffers */ + for (bufferBit = 1; bufferBit <= 8; bufferBit = bufferBit << 1) { + if (bufferBit & ctx->Color.DrawDestMask) { + GLchan *buffer; + if (bufferBit == FRONT_LEFT_BIT) { + buffer = ctx->DrawBuffer->FrontLeftAlpha; + } + else if (bufferBit == FRONT_RIGHT_BIT) { + buffer = ctx->DrawBuffer->FrontRightAlpha; + } + else if (bufferBit == BACK_LEFT_BIT) { + buffer = ctx->DrawBuffer->BackLeftAlpha; + } + else { + buffer = ctx->DrawBuffer->BackRightAlpha; + } + + if (ctx->Scissor.Enabled) { + /* clear scissor region */ + GLint j; + GLint rowLen = ctx->DrawBuffer->_Xmax - ctx->DrawBuffer->_Xmin + 1; + GLint rows = ctx->DrawBuffer->_Ymax - ctx->DrawBuffer->_Ymin + 1; + GLint width = ctx->DrawBuffer->Width; + GLchan *aptr = buffer + + ctx->DrawBuffer->_Ymin * ctx->DrawBuffer->Width + + ctx->DrawBuffer->_Xmin; + for (j = 0; j < rows; j++) { +#if CHAN_BITS == 8 + MEMSET( aptr, aclear, rowLen ); +#elif CHAN_BITS == 16 + MEMSET16( aptr, aclear, rowLen ); +#else +#error unexpected CHAN_BITS value +#endif + aptr += width; + } + } + else { + /* clear whole buffer */ + GLuint pixels = ctx->DrawBuffer->Width * ctx->DrawBuffer->Height; +#if CHAN_BITS == 8 + MEMSET(buffer, aclear, pixels); +#elif CHAN_BITS == 16 + MEMSET16(buffer, aclear, pixels); +#else +#error unexpected CHAN_BITS value +#endif + } + } + } +} + + + +void +_mesa_write_alpha_span( GLcontext *ctx, GLuint n, GLint x, GLint y, + CONST GLchan rgba[][4], const GLubyte mask[] ) +{ + GLchan *aptr = ALPHA_DRAW_ADDR( x, y ); + GLuint i; + + if (mask) { + for (i=0;iPB; + GLint row, col; + GLdepth fragZ; + GLfloat fogCoord; + + ASSERT(ctx->RenderMode == GL_RENDER); + ASSERT(bitmap); + + RENDER_START(swrast,ctx); + + if (SWRAST_CONTEXT(ctx)->NewState) + _swrast_validate_derived( ctx ); + + /* Set bitmap drawing color */ + if (ctx->Visual.rgbMode) { + GLint r, g, b, a; + r = (GLint) (ctx->Current.RasterColor[0] * CHAN_MAXF); + g = (GLint) (ctx->Current.RasterColor[1] * CHAN_MAXF); + b = (GLint) (ctx->Current.RasterColor[2] * CHAN_MAXF); + a = (GLint) (ctx->Current.RasterColor[3] * CHAN_MAXF); + PB_SET_COLOR( PB, r, g, b, a ); + } + else { + PB_SET_INDEX( PB, ctx->Current.RasterIndex ); + } + + fragZ = (GLdepth) ( ctx->Current.RasterPos[2] * ctx->DepthMaxF); + + if (ctx->Fog.Enabled) { + if (ctx->Fog.FogCoordinateSource == GL_FOG_COORDINATE_EXT) { + fogCoord = ctx->Current.FogCoord; + } + else { + fogCoord = _mesa_z_to_fogfactor(ctx, ctx->Current.RasterDistance); + } + } + else { + fogCoord = 0.0; + } + + for (row=0; rowLsbFirst) { + /* Lsb first */ + GLubyte mask = 1U << (unpack->SkipPixels & 0x7); + for (col=0; col> (unpack->SkipPixels & 0x7); + for (col=0; col> 1; + } + } + + PB_CHECK_FLUSH( ctx, PB ); + + /* get ready for next row */ + if (mask != 128) + src++; + } + } + + _mesa_flush_pb(ctx); + + RENDER_FINISH(swrast,ctx); +} Index: dll/opengl/opengl32/mesa/swrast/s_blend.c =================================================================== --- dll/opengl/opengl32/mesa/swrast/s_blend.c (revision 0) +++ dll/opengl/opengl32/mesa/swrast/s_blend.c (working copy) @@ -0,0 +1,669 @@ +/* $Id: s_blend.c,v 1.7 2001/03/19 02:25:36 keithw Exp $ */ + +/* + * Mesa 3-D graphics library + * Version: 3.5 + * + * Copyright (C) 1999-2001 Brian Paul 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 + * BRIAN PAUL 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. + */ + + + +#include "glheader.h" +#include "context.h" +#include "macros.h" + +#include "s_alphabuf.h" +#include "s_blend.h" +#include "s_context.h" +#include "s_pb.h" +#include "s_span.h" + + +#if defined(USE_MMX_ASM) +#include "X86/mmx.h" +#include "X86/common_x86_asm.h" +#define _BLENDAPI _ASMAPI +#else +#define _BLENDAPI +#endif + + +/* + * Common transparency blending mode. + */ +static void _BLENDAPI +blend_transparency( GLcontext *ctx, GLuint n, const GLubyte mask[], + GLchan rgba[][4], CONST GLchan dest[][4] ) +{ + GLuint i; + ASSERT(ctx->Color.BlendEquation==GL_FUNC_ADD_EXT); + ASSERT(ctx->Color.BlendSrcRGB==GL_SRC_ALPHA); + ASSERT(ctx->Color.BlendDstRGB==GL_ONE_MINUS_SRC_ALPHA); + (void) ctx; + + for (i=0;i> 8; + const GLint g = (rgba[i][GCOMP] * t + dest[i][GCOMP] * s + 1) >> 8; + const GLint b = (rgba[i][BCOMP] * t + dest[i][BCOMP] * s + 1) >> 8; + const GLint a = (rgba[i][ACOMP] * t + dest[i][ACOMP] * s + 1) >> 8; +#elif 0 + /* This is slower but satisfies Glean */ + const GLint s = CHAN_MAX - t; + const GLint r = (rgba[i][RCOMP] * t + dest[i][RCOMP] * s) / 255; + const GLint g = (rgba[i][GCOMP] * t + dest[i][GCOMP] * s) / 255; + const GLint b = (rgba[i][BCOMP] * t + dest[i][BCOMP] * s) / 255; + const GLint a = (rgba[i][ACOMP] * t + dest[i][ACOMP] * s) / 255; +#else +#if CHAN_BITS == 8 + /* This satisfies Glean and should be reasonably fast */ + /* Contributed by Nathan Hand */ +#define DIV255(X) (((X) << 8) + (X) + 256) >> 16 + const GLint s = CHAN_MAX - t; + const GLint r = DIV255(rgba[i][RCOMP] * t + dest[i][RCOMP] * s); + const GLint g = DIV255(rgba[i][GCOMP] * t + dest[i][GCOMP] * s); + const GLint b = DIV255(rgba[i][BCOMP] * t + dest[i][BCOMP] * s); + const GLint a = DIV255(rgba[i][ACOMP] * t + dest[i][ACOMP] * s); +#undef DIV255 +#elif CHAN_BITS == 16 + const GLfloat tt = (GLfloat) t / CHAN_MAXF; + const GLfloat s = 1.0 - tt; + const GLint r = (GLint) (rgba[i][RCOMP] * tt + dest[i][RCOMP] * s); + const GLint g = (GLint) (rgba[i][GCOMP] * tt + dest[i][GCOMP] * s); + const GLint b = (GLint) (rgba[i][BCOMP] * tt + dest[i][BCOMP] * s); + const GLint a = (GLint) (rgba[i][ACOMP] * tt + dest[i][ACOMP] * s); +#else /* CHAN_BITS == 32 */ + const GLfloat tt = (GLfloat) t / CHAN_MAXF; + const GLfloat s = 1.0 - tt; + const GLfloat r = rgba[i][RCOMP] * tt + dest[i][RCOMP] * s; + const GLfloat g = rgba[i][GCOMP] * tt + dest[i][GCOMP] * s; + const GLfloat b = rgba[i][BCOMP] * tt + dest[i][BCOMP] * s; + const GLfloat a = rgba[i][ACOMP] * tt + dest[i][ACOMP] * s; +#endif +#endif + ASSERT(r <= CHAN_MAX); + ASSERT(g <= CHAN_MAX); + ASSERT(b <= CHAN_MAX); + ASSERT(a <= CHAN_MAX); + rgba[i][RCOMP] = (GLchan) r; + rgba[i][GCOMP] = (GLchan) g; + rgba[i][BCOMP] = (GLchan) b; + rgba[i][ACOMP] = (GLchan) a; + } + } + } +} + + + +/* + * Add src and dest. + */ +static void _BLENDAPI +blend_add( GLcontext *ctx, GLuint n, const GLubyte mask[], + GLchan rgba[][4], CONST GLchan dest[][4] ) +{ + GLuint i; + ASSERT(ctx->Color.BlendEquation==GL_FUNC_ADD_EXT); + ASSERT(ctx->Color.BlendSrcRGB==GL_ONE); + ASSERT(ctx->Color.BlendDstRGB==GL_ONE); + (void) ctx; + + for (i=0;iColor.BlendEquation==GL_MIN_EXT); + (void) ctx; + + for (i=0;iColor.BlendEquation==GL_MAX_EXT); + (void) ctx; + + for (i=0;i> 8; + GLint g = (rgba[i][GCOMP] * dest[i][GCOMP]) >> 8; + GLint b = (rgba[i][BCOMP] * dest[i][BCOMP]) >> 8; + GLint a = (rgba[i][ACOMP] * dest[i][ACOMP]) >> 8; + rgba[i][RCOMP] = (GLchan) r; + rgba[i][GCOMP] = (GLchan) g; + rgba[i][BCOMP] = (GLchan) b; + rgba[i][ACOMP] = (GLchan) a; + } + } +} + + + +/* + * General case blend pixels. + * Input: n - number of pixels + * mask - the usual write mask + * In/Out: rgba - the incoming and modified pixels + * Input: dest - the pixels from the dest color buffer + */ +static void _BLENDAPI +blend_general( GLcontext *ctx, GLuint n, const GLubyte mask[], + GLchan rgba[][4], CONST GLchan dest[][4] ) +{ + GLfloat rscale = 1.0F / CHAN_MAXF; + GLfloat gscale = 1.0F / CHAN_MAXF; + GLfloat bscale = 1.0F / CHAN_MAXF; + GLfloat ascale = 1.0F / CHAN_MAXF; + GLuint i; + + for (i=0;iColor.BlendSrcRGB) { + case GL_ZERO: + sR = sG = sB = 0.0F; + break; + case GL_ONE: + sR = sG = sB = 1.0F; + break; + case GL_DST_COLOR: + sR = (GLfloat) Rd * rscale; + sG = (GLfloat) Gd * gscale; + sB = (GLfloat) Bd * bscale; + break; + case GL_ONE_MINUS_DST_COLOR: + sR = 1.0F - (GLfloat) Rd * rscale; + sG = 1.0F - (GLfloat) Gd * gscale; + sB = 1.0F - (GLfloat) Bd * bscale; + break; + case GL_SRC_ALPHA: + sR = sG = sB = (GLfloat) As * ascale; + break; + case GL_ONE_MINUS_SRC_ALPHA: + sR = sG = sB = (GLfloat) 1.0F - (GLfloat) As * ascale; + break; + case GL_DST_ALPHA: + sR = sG = sB = (GLfloat) Ad * ascale; + break; + case GL_ONE_MINUS_DST_ALPHA: + sR = sG = sB = 1.0F - (GLfloat) Ad * ascale; + break; + case GL_SRC_ALPHA_SATURATE: + if (As < CHAN_MAX - Ad) { + sR = sG = sB = (GLfloat) As * ascale; + } + else { + sR = sG = sB = 1.0F - (GLfloat) Ad * ascale; + } + break; + case GL_CONSTANT_COLOR: + sR = ctx->Color.BlendColor[0]; + sG = ctx->Color.BlendColor[1]; + sB = ctx->Color.BlendColor[2]; + break; + case GL_ONE_MINUS_CONSTANT_COLOR: + sR = 1.0F - ctx->Color.BlendColor[0]; + sG = 1.0F - ctx->Color.BlendColor[1]; + sB = 1.0F - ctx->Color.BlendColor[2]; + break; + case GL_CONSTANT_ALPHA: + sR = sG = sB = ctx->Color.BlendColor[3]; + break; + case GL_ONE_MINUS_CONSTANT_ALPHA: + sR = sG = sB = 1.0F - ctx->Color.BlendColor[3]; + break; + case GL_SRC_COLOR: /* GL_NV_blend_square */ + sR = (GLfloat) Rs * rscale; + sG = (GLfloat) Gs * gscale; + sB = (GLfloat) Bs * bscale; + break; + case GL_ONE_MINUS_SRC_COLOR: /* GL_NV_blend_square */ + sR = 1.0F - (GLfloat) Rs * rscale; + sG = 1.0F - (GLfloat) Gs * gscale; + sB = 1.0F - (GLfloat) Bs * bscale; + break; + default: + /* this should never happen */ + _mesa_problem(ctx, "Bad blend source RGB factor in do_blend"); + return; + } + + /* Source Alpha factor */ + switch (ctx->Color.BlendSrcA) { + case GL_ZERO: + sA = 0.0F; + break; + case GL_ONE: + sA = 1.0F; + break; + case GL_DST_COLOR: + sA = (GLfloat) Ad * ascale; + break; + case GL_ONE_MINUS_DST_COLOR: + sA = 1.0F - (GLfloat) Ad * ascale; + break; + case GL_SRC_ALPHA: + sA = (GLfloat) As * ascale; + break; + case GL_ONE_MINUS_SRC_ALPHA: + sA = (GLfloat) 1.0F - (GLfloat) As * ascale; + break; + case GL_DST_ALPHA: + sA =(GLfloat) Ad * ascale; + break; + case GL_ONE_MINUS_DST_ALPHA: + sA = 1.0F - (GLfloat) Ad * ascale; + break; + case GL_SRC_ALPHA_SATURATE: + sA = 1.0; + break; + case GL_CONSTANT_COLOR: + sA = ctx->Color.BlendColor[3]; + break; + case GL_ONE_MINUS_CONSTANT_COLOR: + sA = 1.0F - ctx->Color.BlendColor[3]; + break; + case GL_CONSTANT_ALPHA: + sA = ctx->Color.BlendColor[3]; + break; + case GL_ONE_MINUS_CONSTANT_ALPHA: + sA = 1.0F - ctx->Color.BlendColor[3]; + break; + case GL_SRC_COLOR: /* GL_NV_blend_square */ + sA = (GLfloat) As * ascale; + break; + case GL_ONE_MINUS_SRC_COLOR: /* GL_NV_blend_square */ + sA = 1.0F - (GLfloat) As * ascale; + break; + default: + /* this should never happen */ + sA = 0.0F; + _mesa_problem(ctx, "Bad blend source A factor in do_blend"); + } + + /* Dest RGB factor */ + switch (ctx->Color.BlendDstRGB) { + case GL_ZERO: + dR = dG = dB = 0.0F; + break; + case GL_ONE: + dR = dG = dB = 1.0F; + break; + case GL_SRC_COLOR: + dR = (GLfloat) Rs * rscale; + dG = (GLfloat) Gs * gscale; + dB = (GLfloat) Bs * bscale; + break; + case GL_ONE_MINUS_SRC_COLOR: + dR = 1.0F - (GLfloat) Rs * rscale; + dG = 1.0F - (GLfloat) Gs * gscale; + dB = 1.0F - (GLfloat) Bs * bscale; + break; + case GL_SRC_ALPHA: + dR = dG = dB = (GLfloat) As * ascale; + break; + case GL_ONE_MINUS_SRC_ALPHA: + dR = dG = dB = (GLfloat) 1.0F - (GLfloat) As * ascale; + break; + case GL_DST_ALPHA: + dR = dG = dB = (GLfloat) Ad * ascale; + break; + case GL_ONE_MINUS_DST_ALPHA: + dR = dG = dB = 1.0F - (GLfloat) Ad * ascale; + break; + case GL_CONSTANT_COLOR: + dR = ctx->Color.BlendColor[0]; + dG = ctx->Color.BlendColor[1]; + dB = ctx->Color.BlendColor[2]; + break; + case GL_ONE_MINUS_CONSTANT_COLOR: + dR = 1.0F - ctx->Color.BlendColor[0]; + dG = 1.0F - ctx->Color.BlendColor[1]; + dB = 1.0F - ctx->Color.BlendColor[2]; + break; + case GL_CONSTANT_ALPHA: + dR = dG = dB = ctx->Color.BlendColor[3]; + break; + case GL_ONE_MINUS_CONSTANT_ALPHA: + dR = dG = dB = 1.0F - ctx->Color.BlendColor[3]; + break; + case GL_DST_COLOR: /* GL_NV_blend_square */ + dR = (GLfloat) Rd * rscale; + dG = (GLfloat) Gd * gscale; + dB = (GLfloat) Bd * bscale; + break; + case GL_ONE_MINUS_DST_COLOR: /* GL_NV_blend_square */ + dR = 1.0F - (GLfloat) Rd * rscale; + dG = 1.0F - (GLfloat) Gd * gscale; + dB = 1.0F - (GLfloat) Bd * bscale; + break; + default: + /* this should never happen */ + dR = dG = dB = 0.0F; + _mesa_problem(ctx, "Bad blend dest RGB factor in do_blend"); + } + + /* Dest Alpha factor */ + switch (ctx->Color.BlendDstA) { + case GL_ZERO: + dA = 0.0F; + break; + case GL_ONE: + dA = 1.0F; + break; + case GL_SRC_COLOR: + dA = (GLfloat) As * ascale; + break; + case GL_ONE_MINUS_SRC_COLOR: + dA = 1.0F - (GLfloat) As * ascale; + break; + case GL_SRC_ALPHA: + dA = (GLfloat) As * ascale; + break; + case GL_ONE_MINUS_SRC_ALPHA: + dA = (GLfloat) 1.0F - (GLfloat) As * ascale; + break; + case GL_DST_ALPHA: + dA = (GLfloat) Ad * ascale; + break; + case GL_ONE_MINUS_DST_ALPHA: + dA = 1.0F - (GLfloat) Ad * ascale; + break; + case GL_CONSTANT_COLOR: + dA = ctx->Color.BlendColor[3]; + break; + case GL_ONE_MINUS_CONSTANT_COLOR: + dA = 1.0F - ctx->Color.BlendColor[3]; + break; + case GL_CONSTANT_ALPHA: + dA = ctx->Color.BlendColor[3]; + break; + case GL_ONE_MINUS_CONSTANT_ALPHA: + dA = 1.0F - ctx->Color.BlendColor[3]; + break; + case GL_DST_COLOR: /* GL_NV_blend_square */ + dA = (GLfloat) Ad * ascale; + break; + case GL_ONE_MINUS_DST_COLOR: /* GL_NV_blend_square */ + dA = 1.0F - (GLfloat) Ad * ascale; + break; + default: + /* this should never happen */ + dA = 0.0F; + _mesa_problem(ctx, "Bad blend dest A factor in do_blend"); + return; + } + + /* Due to round-off problems we have to clamp against zero. */ + /* Optimization: we don't have to do this for all src & dst factors */ + if (dA < 0.0F) dA = 0.0F; + if (dR < 0.0F) dR = 0.0F; + if (dG < 0.0F) dG = 0.0F; + if (dB < 0.0F) dB = 0.0F; + if (sA < 0.0F) sA = 0.0F; + if (sR < 0.0F) sR = 0.0F; + if (sG < 0.0F) sG = 0.0F; + if (sB < 0.0F) sB = 0.0F; + + ASSERT( sR <= 1.0 ); + ASSERT( sG <= 1.0 ); + ASSERT( sB <= 1.0 ); + ASSERT( sA <= 1.0 ); + ASSERT( dR <= 1.0 ); + ASSERT( dG <= 1.0 ); + ASSERT( dB <= 1.0 ); + ASSERT( dA <= 1.0 ); + + /* compute blended color */ + if (ctx->Color.BlendEquation==GL_FUNC_ADD_EXT) { + r = Rs * sR + Rd * dR + 0.5F; + g = Gs * sG + Gd * dG + 0.5F; + b = Bs * sB + Bd * dB + 0.5F; + a = As * sA + Ad * dA + 0.5F; + } + else if (ctx->Color.BlendEquation==GL_FUNC_SUBTRACT_EXT) { + r = Rs * sR - Rd * dR + 0.5F; + g = Gs * sG - Gd * dG + 0.5F; + b = Bs * sB - Bd * dB + 0.5F; + a = As * sA - Ad * dA + 0.5F; + } + else if (ctx->Color.BlendEquation==GL_FUNC_REVERSE_SUBTRACT_EXT) { + r = Rd * dR - Rs * sR + 0.5F; + g = Gd * dG - Gs * sG + 0.5F; + b = Bd * dB - Bs * sB + 0.5F; + a = Ad * dA - As * sA + 0.5F; + } + else { + /* should never get here */ + r = g = b = a = 0.0F; /* silence uninitialized var warning */ + _mesa_problem(ctx, "unexpected BlendEquation in blend_general()"); + } + + /* final clamping */ + rgba[i][RCOMP] = (GLchan) (GLint) CLAMP( r, 0.0F, CHAN_MAXF ); + rgba[i][GCOMP] = (GLchan) (GLint) CLAMP( g, 0.0F, CHAN_MAXF ); + rgba[i][BCOMP] = (GLchan) (GLint) CLAMP( b, 0.0F, CHAN_MAXF ); + rgba[i][ACOMP] = (GLchan) (GLint) CLAMP( a, 0.0F, CHAN_MAXF ); + } + } +} + + + + + +/* + * Analyze current blending parameters to pick fastest blending function. + * Result: the ctx->Color.BlendFunc pointer is updated. + */ +void _swrast_choose_blend_func( GLcontext *ctx ) +{ + const GLenum eq = ctx->Color.BlendEquation; + const GLenum srcRGB = ctx->Color.BlendSrcRGB; + const GLenum dstRGB = ctx->Color.BlendDstRGB; + const GLenum srcA = ctx->Color.BlendSrcA; + const GLenum dstA = ctx->Color.BlendDstA; + + if (srcRGB != srcA || dstRGB != dstA) { + SWRAST_CONTEXT(ctx)->BlendFunc = blend_general; + } + else if (eq==GL_FUNC_ADD_EXT && srcRGB==GL_SRC_ALPHA + && dstRGB==GL_ONE_MINUS_SRC_ALPHA) + { +#if defined(USE_MMX_ASM) + if ( cpu_has_mmx ) { + SWRAST_CONTEXT(ctx)->BlendFunc = _mesa_mmx_blend_transparency; + } + else +#endif + SWRAST_CONTEXT(ctx)->BlendFunc = blend_transparency; + } + else if (eq==GL_FUNC_ADD_EXT && srcRGB==GL_ONE && dstRGB==GL_ONE) { + SWRAST_CONTEXT(ctx)->BlendFunc = blend_add; + } + else if (((eq==GL_FUNC_ADD_EXT || eq==GL_FUNC_REVERSE_SUBTRACT_EXT) + && (srcRGB==GL_ZERO && dstRGB==GL_SRC_COLOR)) + || + ((eq==GL_FUNC_ADD_EXT || eq==GL_FUNC_SUBTRACT_EXT) + && (srcRGB==GL_DST_COLOR && dstRGB==GL_ZERO))) { + SWRAST_CONTEXT(ctx)->BlendFunc = blend_modulate; + } + else if (eq==GL_MIN_EXT) { + SWRAST_CONTEXT(ctx)->BlendFunc = blend_min; + } + else if (eq==GL_MAX_EXT) { + SWRAST_CONTEXT(ctx)->BlendFunc = blend_max; + } + else { + SWRAST_CONTEXT(ctx)->BlendFunc = blend_general; + } +} + + + +/* + * Apply the blending operator to a span of pixels. + * Input: n - number of pixels in span + * x, y - location of leftmost pixel in span in window coords. + * mask - boolean mask indicating which pixels to blend. + * In/Out: rgba - pixel values + */ +void +_mesa_blend_span( GLcontext *ctx, GLuint n, GLint x, GLint y, + GLchan rgba[][4], const GLubyte mask[] ) +{ + GLchan dest[MAX_WIDTH][4]; + + /* Check if device driver can do the work */ + if (ctx->Color.BlendEquation==GL_LOGIC_OP && + !ctx->Color.ColorLogicOpEnabled) { + return; + } + + /* Read span of current frame buffer pixels */ + _mesa_read_rgba_span( ctx, ctx->DrawBuffer, n, x, y, dest ); + + SWRAST_CONTEXT(ctx)->BlendFunc( ctx, n, mask, rgba, + (const GLchan (*)[4]) dest ); +} + + + +/* + * Apply the blending operator to an array of pixels. + * Input: n - number of pixels in span + * x, y - array of pixel locations + * mask - boolean mask indicating which pixels to blend. + * In/Out: rgba - pixel values + */ +void +_mesa_blend_pixels( GLcontext *ctx, + GLuint n, const GLint x[], const GLint y[], + GLchan rgba[][4], const GLubyte mask[] ) +{ + SWcontext *swrast = SWRAST_CONTEXT(ctx); + GLchan dest[PB_SIZE][4]; + + /* Check if device driver can do the work */ + if (ctx->Color.BlendEquation==GL_LOGIC_OP && + !ctx->Color.ColorLogicOpEnabled) { + return; + } + + /* Read pixels from current color buffer */ + (*swrast->Driver.ReadRGBAPixels)( ctx, n, x, y, dest, mask ); + if (swrast->_RasterMask & ALPHABUF_BIT) { + _mesa_read_alpha_pixels( ctx, n, x, y, dest, mask ); + } + + swrast->BlendFunc( ctx, n, mask, rgba, (const GLchan (*)[4])dest ); +} Index: dll/opengl/opengl32/mesa/swrast/s_blend.h =================================================================== --- dll/opengl/opengl32/mesa/swrast/s_blend.h (revision 0) +++ dll/opengl/opengl32/mesa/swrast/s_blend.h (working copy) @@ -0,0 +1,51 @@ +/* $Id: s_blend.h,v 1.4 2001/03/12 00:48:41 gareth Exp $ */ + +/* + * Mesa 3-D graphics library + * Version: 3.5 + * + * Copyright (C) 1999-2001 Brian Paul 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 + * BRIAN PAUL 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. + */ + + +#ifndef S_BLEND_H +#define S_BLEND_H + + +#include "mtypes.h" +#include "swrast.h" + + + +extern void +_mesa_blend_span( GLcontext *ctx, GLuint n, GLint x, GLint y, + GLchan rgba[][4], const GLubyte mask[] ); + + +extern void +_mesa_blend_pixels( GLcontext *ctx, + GLuint n, const GLint x[], const GLint y[], + GLchan rgba[][4], const GLubyte mask[] ); + +extern void +_swrast_choose_blend_func( GLcontext *ctx ); + + +#endif Index: dll/opengl/opengl32/mesa/swrast/s_buffers.c =================================================================== --- dll/opengl/opengl32/mesa/swrast/s_buffers.c (revision 0) +++ dll/opengl/opengl32/mesa/swrast/s_buffers.c (working copy) @@ -0,0 +1,260 @@ +/* $Id: s_buffers.c,v 1.8 2001/03/19 02:25:36 keithw Exp $ */ + +/* + * Mesa 3-D graphics library + * Version: 3.5 + * + * Copyright (C) 1999-2001 Brian Paul 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 + * BRIAN PAUL 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. + */ + + +#include "glheader.h" +#include "macros.h" +#include "mem.h" + +#include "s_accum.h" +#include "s_alphabuf.h" +#include "s_context.h" +#include "s_depth.h" +#include "s_masking.h" +#include "s_stencil.h" + + + + +/* + * Clear the color buffer when glColorMask or glIndexMask is in effect. + */ +static void +clear_color_buffer_with_masking( GLcontext *ctx ) +{ + SWcontext *swrast = SWRAST_CONTEXT(ctx); + const GLint x = ctx->DrawBuffer->_Xmin; + const GLint y = ctx->DrawBuffer->_Ymin; + const GLint height = ctx->DrawBuffer->_Ymax - ctx->DrawBuffer->_Ymin; + const GLint width = ctx->DrawBuffer->_Xmax - ctx->DrawBuffer->_Xmin; + + if (ctx->Visual.rgbMode) { + /* RGBA mode */ + const GLchan r = ctx->Color.ClearColor[0]; + const GLchan g = ctx->Color.ClearColor[1]; + const GLchan b = ctx->Color.ClearColor[2]; + const GLchan a = ctx->Color.ClearColor[3]; + GLint i; + for (i = 0; i < height; i++) { + GLchan rgba[MAX_WIDTH][4]; + GLint j; + for (j = 0; j < width; j++) { + rgba[j][RCOMP] = r; + rgba[j][GCOMP] = g; + rgba[j][BCOMP] = b; + rgba[j][ACOMP] = a; + } + _mesa_mask_rgba_span( ctx, width, x, y + i, rgba ); + (*swrast->Driver.WriteRGBASpan)( ctx, width, x, y + i, + (CONST GLchan (*)[4]) rgba, NULL ); + } + } + else { + /* Color index mode */ + GLuint span[MAX_WIDTH]; + GLubyte mask[MAX_WIDTH]; + GLint i, j; + MEMSET( mask, 1, width ); + for (i=0;iColor.ClearIndex; + } + _mesa_mask_index_span( ctx, width, x, y + i, span ); + (*swrast->Driver.WriteCI32Span)( ctx, width, x, y + i, span, mask ); + } + } +} + + + +/* + * Clear a color buffer without index/channel masking. + */ +static void +clear_color_buffer(GLcontext *ctx) +{ + SWcontext *swrast = SWRAST_CONTEXT(ctx); + const GLint x = ctx->DrawBuffer->_Xmin; + const GLint y = ctx->DrawBuffer->_Ymin; + const GLint height = ctx->DrawBuffer->_Ymax - ctx->DrawBuffer->_Ymin; + const GLint width = ctx->DrawBuffer->_Xmax - ctx->DrawBuffer->_Xmin; + + if (ctx->Visual.rgbMode) { + /* RGBA mode */ + const GLchan r = ctx->Color.ClearColor[0]; + const GLchan g = ctx->Color.ClearColor[1]; + const GLchan b = ctx->Color.ClearColor[2]; + const GLchan a = ctx->Color.ClearColor[3]; + GLchan span[MAX_WIDTH][4]; + GLint i; + + ASSERT(*((GLuint *) &ctx->Color.ColorMask) == 0xffffffff); + + for (i = 0; i < width; i++) { + span[i][RCOMP] = r; + span[i][GCOMP] = g; + span[i][BCOMP] = b; + span[i][ACOMP] = a; + } + for (i = 0; i < height; i++) { + (*swrast->Driver.WriteRGBASpan)( ctx, width, x, y + i, + (CONST GLchan (*)[4]) span, NULL ); + } + } + else { + /* Color index mode */ + ASSERT((ctx->Color.IndexMask & ((1 << ctx->Visual.indexBits) - 1)) + == (GLuint) ((1 << ctx->Visual.indexBits) - 1)); + if (ctx->Visual.indexBits == 8) { + /* 8-bit clear */ + GLubyte span[MAX_WIDTH]; + GLint i; + MEMSET(span, ctx->Color.ClearIndex, width); + for (i = 0; i < height; i++) { + (*swrast->Driver.WriteCI8Span)( ctx, width, x, y + i, span, NULL ); + } + } + else { + /* non 8-bit clear */ + GLuint span[MAX_WIDTH]; + GLint i; + for (i = 0; i < width; i++) { + span[i] = ctx->Color.ClearIndex; + } + for (i = 0; i < height; i++) { + (*swrast->Driver.WriteCI32Span)( ctx, width, x, y + i, span, NULL ); + } + } + } +} + + + +/* + * Clear the front/back/left/right color buffers. + * This function is usually only called if we need to clear the + * buffers with masking. + */ +static void +clear_color_buffers(GLcontext *ctx) +{ + SWcontext *swrast = SWRAST_CONTEXT(ctx); + const GLuint colorMask = *((GLuint *) &ctx->Color.ColorMask); + GLuint bufferBit; + + /* loop over four possible dest color buffers */ + for (bufferBit = 1; bufferBit <= 8; bufferBit = bufferBit << 1) { + if (bufferBit & ctx->Color.DrawDestMask) { + if (bufferBit == FRONT_LEFT_BIT) { + (void) (*ctx->Driver.SetDrawBuffer)( ctx, GL_FRONT_LEFT); + (void) (*swrast->Driver.SetReadBuffer)( ctx, ctx->DrawBuffer, GL_FRONT_LEFT); + } + else if (bufferBit == FRONT_RIGHT_BIT) { + (void) (*ctx->Driver.SetDrawBuffer)( ctx, GL_FRONT_RIGHT); + (void) (*swrast->Driver.SetReadBuffer)( ctx, ctx->DrawBuffer, GL_FRONT_RIGHT); + } + else if (bufferBit == BACK_LEFT_BIT) { + (void) (*ctx->Driver.SetDrawBuffer)( ctx, GL_BACK_LEFT); + (void) (*swrast->Driver.SetReadBuffer)( ctx, ctx->DrawBuffer, GL_BACK_LEFT); + } + else { + (void) (*ctx->Driver.SetDrawBuffer)( ctx, GL_BACK_RIGHT); + (void) (*swrast->Driver.SetReadBuffer)( ctx, ctx->DrawBuffer, GL_BACK_RIGHT); + } + + if (colorMask != 0xffffffff) { + clear_color_buffer_with_masking(ctx); + } + else { + clear_color_buffer(ctx); + } + } + } + + /* restore default read/draw buffers */ + (void) (*ctx->Driver.SetDrawBuffer)( ctx, ctx->Color.DriverDrawBuffer ); + (void) (*swrast->Driver.SetReadBuffer)( ctx, ctx->ReadBuffer, ctx->Pixel.DriverReadBuffer ); +} + + + +void +_swrast_Clear( GLcontext *ctx, GLbitfield mask, + GLboolean all, + GLint x, GLint y, GLint width, GLint height ) +{ + SWcontext *swrast = SWRAST_CONTEXT(ctx); +#ifdef DEBUG + { + GLbitfield legalBits = DD_FRONT_LEFT_BIT | + DD_FRONT_RIGHT_BIT | + DD_BACK_LEFT_BIT | + DD_BACK_RIGHT_BIT | + DD_DEPTH_BIT | + DD_STENCIL_BIT | + DD_ACCUM_BIT; + assert((mask & (~legalBits)) == 0); + } +#endif + + RENDER_START(swrast,ctx); + + /* do software clearing here */ + if (mask) { + if (mask & ctx->Color.DrawDestMask) clear_color_buffers(ctx); + if (mask & GL_DEPTH_BUFFER_BIT) _mesa_clear_depth_buffer(ctx); + if (mask & GL_ACCUM_BUFFER_BIT) _mesa_clear_accum_buffer(ctx); + if (mask & GL_STENCIL_BUFFER_BIT) _mesa_clear_stencil_buffer(ctx); + } + + /* clear software-based alpha buffer(s) */ + if ( (mask & GL_COLOR_BUFFER_BIT) + && ctx->DrawBuffer->UseSoftwareAlphaBuffers + && ctx->Color.ColorMask[ACOMP]) { + _mesa_clear_alpha_buffers( ctx ); + } + + RENDER_FINISH(swrast,ctx); +} + + +void +_swrast_alloc_buffers( GLcontext *ctx ) +{ + /* Reallocate other buffers if needed. */ + if (ctx->DrawBuffer->UseSoftwareDepthBuffer) { + _mesa_alloc_depth_buffer( ctx ); + } + if (ctx->DrawBuffer->UseSoftwareStencilBuffer) { + _mesa_alloc_stencil_buffer( ctx ); + } + if (ctx->DrawBuffer->UseSoftwareAccumBuffer) { + _mesa_alloc_accum_buffer( ctx ); + } + if (ctx->DrawBuffer->UseSoftwareAlphaBuffers) { + _mesa_alloc_alpha_buffers( ctx ); + } +} Index: dll/opengl/opengl32/mesa/swrast/s_context.c =================================================================== --- dll/opengl/opengl32/mesa/swrast/s_context.c (revision 0) +++ dll/opengl/opengl32/mesa/swrast/s_context.c (working copy) @@ -0,0 +1,557 @@ +/* $Id: s_context.c,v 1.21 2001/05/17 09:32:17 keithw Exp $ */ + +/* + * Mesa 3-D graphics library + * Version: 3.5 + * + * Copyright (C) 1999-2001 Brian Paul 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 + * BRIAN PAUL 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. + * + * Authors: + * Keith Whitwell + */ + +#include "glheader.h" +#include "mtypes.h" +#include "mem.h" + +#include "s_pb.h" +#include "s_points.h" +#include "s_lines.h" +#include "s_triangle.h" +#include "s_blend.h" +#include "s_context.h" +#include "s_texture.h" + + + + + +/* + * Recompute the value of swrast->_RasterMask, etc. according to + * the current context. + */ +static void +_swrast_update_rasterflags( GLcontext *ctx ) +{ + GLuint RasterMask = 0; + + if (ctx->Color.AlphaEnabled) RasterMask |= ALPHATEST_BIT; + if (ctx->Color.BlendEnabled) RasterMask |= BLEND_BIT; + if (ctx->Depth.Test) RasterMask |= DEPTH_BIT; + if (ctx->Fog.Enabled) RasterMask |= FOG_BIT; + if (ctx->Scissor.Enabled) RasterMask |= SCISSOR_BIT; + if (ctx->Stencil.Enabled) RasterMask |= STENCIL_BIT; + if (ctx->Visual.rgbMode) { + const GLuint colorMask = *((GLuint *) &ctx->Color.ColorMask); + if (colorMask != 0xffffffff) RasterMask |= MASKING_BIT; + if (ctx->Color.ColorLogicOpEnabled) RasterMask |= LOGIC_OP_BIT; + if (ctx->Texture._ReallyEnabled) RasterMask |= TEXTURE_BIT; + } + else { + if (ctx->Color.IndexMask != 0xffffffff) RasterMask |= MASKING_BIT; + if (ctx->Color.IndexLogicOpEnabled) RasterMask |= LOGIC_OP_BIT; + } + + if (ctx->DrawBuffer->UseSoftwareAlphaBuffers + && ctx->Color.ColorMask[ACOMP] + && ctx->Color.DrawBuffer != GL_NONE) + RasterMask |= ALPHABUF_BIT; + + if ( ctx->Viewport.X < 0 + || ctx->Viewport.X + ctx->Viewport.Width > ctx->DrawBuffer->Width + || ctx->Viewport.Y < 0 + || ctx->Viewport.Y + ctx->Viewport.Height > ctx->DrawBuffer->Height) { + RasterMask |= WINCLIP_BIT; + } + + if (ctx->Depth.OcclusionTest) + RasterMask |= OCCLUSION_BIT; + + + /* If we're not drawing to exactly one color buffer set the + * MULTI_DRAW_BIT flag. Also set it if we're drawing to no + * buffers or the RGBA or CI mask disables all writes. + */ + if (ctx->Color.MultiDrawBuffer) { + RasterMask |= MULTI_DRAW_BIT; + } + else if (ctx->Color.DrawBuffer==GL_NONE) { + RasterMask |= MULTI_DRAW_BIT; + } + else if (ctx->Visual.rgbMode && *((GLuint *) ctx->Color.ColorMask) == 0) { + RasterMask |= MULTI_DRAW_BIT; /* all RGBA channels disabled */ + } + else if (!ctx->Visual.rgbMode && ctx->Color.IndexMask==0) { + RasterMask |= MULTI_DRAW_BIT; /* all color index bits disabled */ + } + + SWRAST_CONTEXT(ctx)->_RasterMask = RasterMask; +} + + +static void +_swrast_update_polygon( GLcontext *ctx ) +{ + GLfloat backface_sign = 1; + + if (ctx->Polygon.CullFlag) { + backface_sign = 1; + switch(ctx->Polygon.CullFaceMode) { + case GL_BACK: + if(ctx->Polygon.FrontFace==GL_CCW) + backface_sign = -1; + break; + case GL_FRONT: + if(ctx->Polygon.FrontFace!=GL_CCW) + backface_sign = -1; + break; + default: + case GL_FRONT_AND_BACK: + backface_sign = 0; + break; + } + } + else { + backface_sign = 0; + } + + SWRAST_CONTEXT(ctx)->_backface_sign = backface_sign; +} + + +static void +_swrast_update_hint( GLcontext *ctx ) +{ + SWcontext *swrast = SWRAST_CONTEXT(ctx); + swrast->_PreferPixelFog = (!swrast->AllowVertexFog || + (ctx->Hint.Fog == GL_NICEST && + swrast->AllowPixelFog)); +} + +#define _SWRAST_NEW_DERIVED (_SWRAST_NEW_RASTERMASK | \ + _NEW_TEXTURE | \ + _NEW_HINT | \ + _NEW_POLYGON ) + +/* State referenced by _swrast_choose_triangle, _swrast_choose_line. + */ +#define _SWRAST_NEW_TRIANGLE (_SWRAST_NEW_DERIVED | \ + _NEW_RENDERMODE| \ + _NEW_POLYGON| \ + _NEW_DEPTH| \ + _NEW_STENCIL| \ + _NEW_COLOR| \ + _NEW_TEXTURE| \ + _SWRAST_NEW_RASTERMASK| \ + _NEW_LIGHT| \ + _NEW_FOG | \ + _DD_NEW_SEPARATE_SPECULAR) + +#define _SWRAST_NEW_LINE (_SWRAST_NEW_DERIVED | \ + _NEW_RENDERMODE| \ + _NEW_LINE| \ + _NEW_TEXTURE| \ + _NEW_LIGHT| \ + _NEW_FOG| \ + _NEW_DEPTH | \ + _DD_NEW_SEPARATE_SPECULAR) + +#define _SWRAST_NEW_POINT (_SWRAST_NEW_DERIVED | \ + _NEW_RENDERMODE | \ + _NEW_POINT | \ + _NEW_TEXTURE | \ + _NEW_LIGHT | \ + _NEW_FOG | \ + _DD_NEW_SEPARATE_SPECULAR) + +#define _SWRAST_NEW_TEXTURE_SAMPLE_FUNC _NEW_TEXTURE + +#define _SWRAST_NEW_BLEND_FUNC _NEW_COLOR + + + +/* Stub for swrast->Triangle to select a true triangle function + * after a state change. + */ +static void +_swrast_validate_triangle( GLcontext *ctx, + const SWvertex *v0, + const SWvertex *v1, + const SWvertex *v2 ) +{ + SWcontext *swrast = SWRAST_CONTEXT(ctx); + + _swrast_validate_derived( ctx ); + swrast->choose_triangle( ctx ); + + if ((ctx->_TriangleCaps & DD_SEPARATE_SPECULAR) && + !ctx->Texture._ReallyEnabled) { + swrast->SpecTriangle = swrast->Triangle; + swrast->Triangle = _swrast_add_spec_terms_triangle; + } + + swrast->Triangle( ctx, v0, v1, v2 ); +} + +static void +_swrast_validate_line( GLcontext *ctx, const SWvertex *v0, const SWvertex *v1 ) +{ + SWcontext *swrast = SWRAST_CONTEXT(ctx); + + _swrast_validate_derived( ctx ); + swrast->choose_line( ctx ); + + if ((ctx->_TriangleCaps & DD_SEPARATE_SPECULAR) && + !ctx->Texture._ReallyEnabled) { + swrast->SpecLine = swrast->Line; + swrast->Line = _swrast_add_spec_terms_line; + } + + + swrast->Line( ctx, v0, v1 ); +} + +static void +_swrast_validate_point( GLcontext *ctx, const SWvertex *v0 ) +{ + SWcontext *swrast = SWRAST_CONTEXT(ctx); + + _swrast_validate_derived( ctx ); + swrast->choose_point( ctx ); + + if ((ctx->_TriangleCaps & DD_SEPARATE_SPECULAR) && + !ctx->Texture._ReallyEnabled) { + swrast->SpecPoint = swrast->Point; + swrast->Point = _swrast_add_spec_terms_point; + } + + swrast->Point( ctx, v0 ); +} + +static void +_swrast_validate_blend_func( GLcontext *ctx, GLuint n, + const GLubyte mask[], + GLchan src[][4], + CONST GLchan dst[][4] ) +{ + SWcontext *swrast = SWRAST_CONTEXT(ctx); + + _swrast_validate_derived( ctx ); + _swrast_choose_blend_func( ctx ); + + swrast->BlendFunc( ctx, n, mask, src, dst ); +} + + +static void +_swrast_validate_texture_sample( GLcontext *ctx, GLuint texUnit, + const struct gl_texture_object *tObj, + GLuint n, + const GLfloat s[], const GLfloat t[], + const GLfloat u[], const GLfloat lambda[], + GLchan rgba[][4] ) +{ + SWcontext *swrast = SWRAST_CONTEXT(ctx); + + _swrast_validate_derived( ctx ); + _swrast_choose_texture_sample_func( ctx, texUnit, tObj ); + + swrast->TextureSample[texUnit]( ctx, texUnit, tObj, n, s, t, u, + lambda, rgba ); +} + + +static void +_swrast_sleep( GLcontext *ctx, GLuint new_state ) +{ +} + + +static void +_swrast_invalidate_state( GLcontext *ctx, GLuint new_state ) +{ + SWcontext *swrast = SWRAST_CONTEXT(ctx); + GLuint i; + + swrast->NewState |= new_state; + + /* After 10 statechanges without any swrast functions being called, + * put the module to sleep. + */ + if (++swrast->StateChanges > 10) { + swrast->InvalidateState = _swrast_sleep; + swrast->NewState = ~0; + new_state = ~0; + } + + if (new_state & swrast->invalidate_triangle) + swrast->Triangle = _swrast_validate_triangle; + + if (new_state & swrast->invalidate_line) + swrast->Line = _swrast_validate_line; + + if (new_state & swrast->invalidate_point) + swrast->Point = _swrast_validate_point; + + if (new_state & _SWRAST_NEW_BLEND_FUNC) + swrast->BlendFunc = _swrast_validate_blend_func; + + if (new_state & _SWRAST_NEW_TEXTURE_SAMPLE_FUNC) + for (i = 0 ; i < ctx->Const.MaxTextureUnits ; i++) + swrast->TextureSample[i] = _swrast_validate_texture_sample; + + + if (ctx->Visual.rgbMode) { + ASSERT(swrast->Driver.WriteRGBASpan); + ASSERT(swrast->Driver.WriteRGBSpan); + ASSERT(swrast->Driver.WriteMonoRGBASpan); + ASSERT(swrast->Driver.WriteRGBAPixels); + ASSERT(swrast->Driver.WriteMonoRGBAPixels); + ASSERT(swrast->Driver.ReadRGBASpan); + ASSERT(swrast->Driver.ReadRGBAPixels); + } + else { + ASSERT(swrast->Driver.WriteCI32Span); + ASSERT(swrast->Driver.WriteCI8Span); + ASSERT(swrast->Driver.WriteMonoCISpan); + ASSERT(swrast->Driver.WriteCI32Pixels); + ASSERT(swrast->Driver.WriteMonoCIPixels); + ASSERT(swrast->Driver.ReadCI32Span); + ASSERT(swrast->Driver.ReadCI32Pixels); + } + +} + + + +void +_swrast_validate_derived( GLcontext *ctx ) +{ + SWcontext *swrast = SWRAST_CONTEXT(ctx); + + if (swrast->NewState) + { + if (swrast->NewState & _SWRAST_NEW_RASTERMASK) + _swrast_update_rasterflags( ctx ); + + if (swrast->NewState & _NEW_POLYGON) + _swrast_update_polygon( ctx ); + + if (swrast->NewState & _NEW_HINT) + _swrast_update_hint( ctx ); + + swrast->NewState = 0; + swrast->StateChanges = 0; + swrast->InvalidateState = _swrast_invalidate_state; + } +} + +#define SWRAST_DEBUG 0 + +/* Public entrypoints: See also s_accum.c, s_bitmap.c, etc. + */ +void +_swrast_Quad( GLcontext *ctx, + const SWvertex *v0, const SWvertex *v1, + const SWvertex *v2, const SWvertex *v3 ) +{ + if (SWRAST_DEBUG) { + fprintf(stderr, "_swrast_Quad\n"); + _swrast_print_vertex( ctx, v0 ); + _swrast_print_vertex( ctx, v1 ); + _swrast_print_vertex( ctx, v2 ); + _swrast_print_vertex( ctx, v3 ); + } + SWRAST_CONTEXT(ctx)->Triangle( ctx, v0, v1, v3 ); + SWRAST_CONTEXT(ctx)->Triangle( ctx, v1, v2, v3 ); +} + +void +_swrast_Triangle( GLcontext *ctx, const SWvertex *v0, + const SWvertex *v1, const SWvertex *v2 ) +{ + if (SWRAST_DEBUG) { + fprintf(stderr, "_swrast_Triangle\n"); + _swrast_print_vertex( ctx, v0 ); + _swrast_print_vertex( ctx, v1 ); + _swrast_print_vertex( ctx, v2 ); + } + SWRAST_CONTEXT(ctx)->Triangle( ctx, v0, v1, v2 ); +} + +void +_swrast_Line( GLcontext *ctx, const SWvertex *v0, const SWvertex *v1 ) +{ + if (SWRAST_DEBUG) { + fprintf(stderr, "_swrast_Line\n"); + _swrast_print_vertex( ctx, v0 ); + _swrast_print_vertex( ctx, v1 ); + } + SWRAST_CONTEXT(ctx)->Line( ctx, v0, v1 ); +} + +void +_swrast_Point( GLcontext *ctx, const SWvertex *v0 ) +{ + if (SWRAST_DEBUG) { + fprintf(stderr, "_swrast_Point\n"); + _swrast_print_vertex( ctx, v0 ); + } + SWRAST_CONTEXT(ctx)->Point( ctx, v0 ); +} + +void +_swrast_InvalidateState( GLcontext *ctx, GLuint new_state ) +{ + if (SWRAST_DEBUG) { + fprintf(stderr, "_swrast_InvalidateState\n"); + } + SWRAST_CONTEXT(ctx)->InvalidateState( ctx, new_state ); +} + +void +_swrast_ResetLineStipple( GLcontext *ctx ) +{ + if (SWRAST_DEBUG) { + fprintf(stderr, "_swrast_ResetLineStipple\n"); + } + SWRAST_CONTEXT(ctx)->StippleCounter = 0; +} + +void +_swrast_allow_vertex_fog( GLcontext *ctx, GLboolean value ) +{ + if (SWRAST_DEBUG) { + fprintf(stderr, "_swrast_allow_vertex_fog %d\n", value); + } + SWRAST_CONTEXT(ctx)->InvalidateState( ctx, _NEW_HINT ); + SWRAST_CONTEXT(ctx)->AllowVertexFog = value; +} + +void +_swrast_allow_pixel_fog( GLcontext *ctx, GLboolean value ) +{ + if (SWRAST_DEBUG) { + fprintf(stderr, "_swrast_allow_pixel_fog %d\n", value); + } + SWRAST_CONTEXT(ctx)->InvalidateState( ctx, _NEW_HINT ); + SWRAST_CONTEXT(ctx)->AllowPixelFog = value; +} + + +GLboolean +_swrast_CreateContext( GLcontext *ctx ) +{ + GLuint i; + SWcontext *swrast = (SWcontext *)CALLOC(sizeof(SWcontext)); + + if (SWRAST_DEBUG) { + fprintf(stderr, "_swrast_CreateContext\n"); + } + + if (!swrast) + return GL_FALSE; + + swrast->PB = _mesa_alloc_pb(); + if (!swrast->PB) { + FREE(swrast); + return GL_FALSE; + } + + swrast->NewState = ~0; + + swrast->choose_point = _swrast_choose_point; + swrast->choose_line = _swrast_choose_line; + swrast->choose_triangle = _swrast_choose_triangle; + + swrast->invalidate_point = _SWRAST_NEW_POINT; + swrast->invalidate_line = _SWRAST_NEW_LINE; + swrast->invalidate_triangle = _SWRAST_NEW_TRIANGLE; + + swrast->Point = _swrast_validate_point; + swrast->Line = _swrast_validate_line; + swrast->Triangle = _swrast_validate_triangle; + swrast->InvalidateState = _swrast_sleep; + swrast->BlendFunc = _swrast_validate_blend_func; + + swrast->AllowVertexFog = GL_TRUE; + swrast->AllowPixelFog = GL_TRUE; + + /* Optimized Accum buffer */ + swrast->_IntegerAccumMode = GL_TRUE; + swrast->_IntegerAccumScaler = 0.0; + + + for (i = 0 ; i < MAX_TEXTURE_UNITS ; i++) + swrast->TextureSample[i] = _swrast_validate_texture_sample; + + ctx->swrast_context = swrast; + return GL_TRUE; +} + +void +_swrast_DestroyContext( GLcontext *ctx ) +{ + SWcontext *swrast = SWRAST_CONTEXT(ctx); + + if (SWRAST_DEBUG) { + fprintf(stderr, "_swrast_DestroyContext\n"); + } + + FREE( swrast->PB ); + FREE( swrast ); + + ctx->swrast_context = 0; +} + + +struct swrast_device_driver * +_swrast_GetDeviceDriverReference( GLcontext *ctx ) +{ + SWcontext *swrast = SWRAST_CONTEXT(ctx); + return &swrast->Driver; +} + +#define SWRAST_DEBUG_VERTICES 0 + +void +_swrast_print_vertex( GLcontext *ctx, const SWvertex *v ) +{ + GLuint i; + + if (SWRAST_DEBUG_VERTICES) { + fprintf(stderr, "win %f %f %f %f\n", + v->win[0], v->win[1], v->win[2], v->win[3]); + + for (i = 0 ; i < ctx->Const.MaxTextureUnits ; i++) + fprintf(stderr, "texcoord[%d] %f %f %f %f\n", i, + v->texcoord[i][0], v->texcoord[i][1], + v->texcoord[i][2], v->texcoord[i][3]); + + fprintf(stderr, "color %d %d %d %d\n", + v->color[0], v->color[1], v->color[2], v->color[3]); + fprintf(stderr, "spec %d %d %d %d\n", + v->specular[0], v->specular[1], v->specular[2], v->specular[3]); + fprintf(stderr, "fog %f\n", v->fog); + fprintf(stderr, "index %d\n", v->index); + fprintf(stderr, "pointsize %f\n", v->pointSize); + fprintf(stderr, "\n"); + } +} Index: dll/opengl/opengl32/mesa/swrast/s_context.h =================================================================== --- dll/opengl/opengl32/mesa/swrast/s_context.h (revision 0) +++ dll/opengl/opengl32/mesa/swrast/s_context.h (working copy) @@ -0,0 +1,191 @@ +/* $Id: s_context.h,v 1.10 2001/05/17 09:32:17 keithw Exp $ */ + +/* + * Mesa 3-D graphics library + * Version: 3.5 + * + * Copyright (C) 1999-2001 Brian Paul 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 + * BRIAN PAUL 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. + * + * Authors: + * Keith Whitwell + */ + +#ifndef S_CONTEXT_H +#define S_CONTEXT_H + +#include "mtypes.h" +#include "swrast.h" + +/* + * For texture sampling: + */ +typedef void (*TextureSampleFunc)( GLcontext *ctx, GLuint texUnit, + const struct gl_texture_object *tObj, + GLuint n, + const GLfloat s[], const GLfloat t[], + const GLfloat u[], const GLfloat lambda[], + GLchan rgba[][4] ); + + + +/* + * Blending function + */ +#ifdef USE_MMX_ASM +typedef void (_ASMAPIP blend_func)( GLcontext *ctx, GLuint n, + const GLubyte mask[], + GLchan src[][4], CONST GLchan dst[][4] ); +#else +typedef void (*blend_func)( GLcontext *ctx, GLuint n, const GLubyte mask[], + GLchan src[][4], CONST GLchan dst[][4] ); +#endif + +typedef void (*swrast_point_func)( GLcontext *ctx, const SWvertex *); + +typedef void (*swrast_line_func)( GLcontext *ctx, + const SWvertex *, const SWvertex *); + +typedef void (*swrast_tri_func)( GLcontext *ctx, const SWvertex *, + const SWvertex *, const SWvertex *); + + + +/* + * Bitmasks to indicate which rasterization options are enabled (RasterMask) + */ +#define ALPHATEST_BIT 0x001 /* Alpha-test pixels */ +#define BLEND_BIT 0x002 /* Blend pixels */ +#define DEPTH_BIT 0x004 /* Depth-test pixels */ +#define FOG_BIT 0x008 /* Fog pixels */ +#define LOGIC_OP_BIT 0x010 /* Apply logic op in software */ +#define SCISSOR_BIT 0x020 /* Scissor pixels */ +#define STENCIL_BIT 0x040 /* Stencil pixels */ +#define MASKING_BIT 0x080 /* Do glColorMask or glIndexMask */ +#define ALPHABUF_BIT 0x100 /* Using software alpha buffer */ +#define WINCLIP_BIT 0x200 /* Clip pixels/primitives to window */ +#define MULTI_DRAW_BIT 0x400 /* Write to more than one color- */ + /* buffer or no buffers. */ +#define OCCLUSION_BIT 0x800 /* GL_HP_occlusion_test enabled */ +#define TEXTURE_BIT 0x1000 /* Texturing really enabled */ + + +#define _SWRAST_NEW_RASTERMASK (_NEW_BUFFERS| \ + _NEW_SCISSOR| \ + _NEW_COLOR| \ + _NEW_DEPTH| \ + _NEW_FOG| \ + _NEW_STENCIL| \ + _NEW_TEXTURE| \ + _NEW_VIEWPORT| \ + _NEW_DEPTH) + + + +typedef struct +{ + /* Driver interface: + */ + struct swrast_device_driver Driver; + + /* Configuration mechanisms to make software rasterizer match + * characteristics of the hardware rasterizer (if present): + */ + GLboolean AllowVertexFog; + GLboolean AllowPixelFog; + + /* Derived values, invalidated on statechanges, updated from + * _swrast_validate_derived(): + */ + GLuint _RasterMask; + GLfloat _MinMagThresh[MAX_TEXTURE_UNITS]; + GLfloat _backface_sign; + GLboolean _PreferPixelFog; + + /* Accum buffer temporaries. + */ + GLboolean _IntegerAccumMode; /* Storing unscaled integers? */ + GLfloat _IntegerAccumScaler; /* Implicit scale factor */ + + + /* Working values: + */ + struct pixel_buffer* PB; + GLuint StippleCounter; /* Line stipple counter */ + GLuint NewState; + GLuint StateChanges; + + /* Mechanism to allow driver (like X11) to register further + * software rasterization routines. + */ + void (*choose_point)( GLcontext * ); + void (*choose_line)( GLcontext * ); + void (*choose_triangle)( GLcontext * ); + + GLuint invalidate_point; + GLuint invalidate_line; + GLuint invalidate_triangle; + + + /* Function pointers for dispatch behind public entrypoints. + */ + void (*InvalidateState)( GLcontext *ctx, GLuint new_state ); + + swrast_point_func Point; + swrast_line_func Line; + swrast_tri_func Triangle; + + /* Placeholders for when separate specular (or secondary color) is + * enabled but texturing is not. + */ + swrast_point_func SpecPoint; + swrast_line_func SpecLine; + swrast_tri_func SpecTriangle; + + + /* Internal hooks, kept uptodate by the same mechanism as above. + */ + blend_func BlendFunc; + TextureSampleFunc TextureSample[MAX_TEXTURE_UNITS]; + +} SWcontext; + + +void +_swrast_validate_derived( GLcontext *ctx ); + + +#define SWRAST_CONTEXT(ctx) ((SWcontext *)ctx->swrast_context) + +#define RENDER_START(SWctx, GLctx) \ + do { \ + if ((SWctx)->Driver.SpanRenderStart) { \ + (*(SWctx)->Driver.SpanRenderStart)(GLctx); \ + } \ + } while (0) + +#define RENDER_FINISH(SWctx, GLctx) \ + do { \ + if ((SWctx)->Driver.SpanRenderFinish) { \ + (*(SWctx)->Driver.SpanRenderFinish)(GLctx); \ + } \ + } while (0) + + +#endif Index: dll/opengl/opengl32/mesa/swrast/s_copypix.c =================================================================== --- dll/opengl/opengl32/mesa/swrast/s_copypix.c (revision 0) +++ dll/opengl/opengl32/mesa/swrast/s_copypix.c (working copy) @@ -0,0 +1,962 @@ +/* $Id: s_copypix.c,v 1.20 2001/06/18 23:55:18 brianp Exp $ */ + +/* + * Mesa 3-D graphics library + * Version: 3.5 + * + * Copyright (C) 1999-2001 Brian Paul 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 + * BRIAN PAUL 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. + */ + + +#include "glheader.h" +#include "colormac.h" +#include "context.h" +#include "convolve.h" +#include "feedback.h" +#include "macros.h" +#include "mem.h" +#include "mmath.h" +#include "pixel.h" + +#include "s_context.h" +#include "s_depth.h" +#include "s_fog.h" +#include "s_histogram.h" +#include "s_pixeltex.h" +#include "s_span.h" +#include "s_stencil.h" +#include "s_texture.h" +#include "s_zoom.h" + + + +/* + * Determine if there's overlap in an image copy. + * This test also compensates for the fact that copies are done from + * bottom to top and overlaps can sometimes be handled correctly + * without making a temporary image copy. + */ +static GLboolean +regions_overlap(GLint srcx, GLint srcy, + GLint dstx, GLint dsty, + GLint width, GLint height, + GLfloat zoomX, GLfloat zoomY) +{ + if (zoomX == 1.0 && zoomY == 1.0) { + /* no zoom */ + if (srcx >= dstx + width || (srcx + width <= dstx)) { + return GL_FALSE; + } + else if (srcy < dsty) { /* this is OK */ + return GL_FALSE; + } + else { + return GL_TRUE; + } + } + else { + /* add one pixel of slop when zooming, just to be safe */ + if ((srcx > dstx + (width * zoomX) + 1) || (srcx + width + 1 < dstx)) { + return GL_FALSE; + } + else if ((srcy < dsty) && (srcy + height < dsty + (height * zoomY))) { + return GL_FALSE; + } + else if ((srcy > dsty) && (srcy + height > dsty + (height * zoomY))) { + return GL_FALSE; + } + else { + return GL_TRUE; + } + } +} + + + +/* + * RGBA copypixels with convolution. + */ +static void +copy_conv_rgba_pixels(GLcontext *ctx, GLint srcx, GLint srcy, + GLint width, GLint height, GLint destx, GLint desty) +{ + SWcontext *swrast = SWRAST_CONTEXT(ctx); + GLdepth zspan[MAX_WIDTH]; + GLfloat fogSpan[MAX_WIDTH]; + GLboolean quick_draw; + GLint row; + GLboolean changeBuffer; + GLchan *saveReadAlpha; + const GLboolean zoom = ctx->Pixel.ZoomX != 1.0F || ctx->Pixel.ZoomY != 1.0F; + const GLuint transferOps = ctx->_ImageTransferState; + GLfloat *dest, *tmpImage, *convImage; + + if (ctx->Depth.Test || ctx->Fog.Enabled) { + /* fill in array of z values */ + GLdepth z = (GLdepth) (ctx->Current.RasterPos[2] * ctx->DepthMax); + GLfloat fog; + GLint i; + + if (ctx->Fog.FogCoordinateSource == GL_FOG_COORDINATE_EXT) { + fog = ctx->Current.RasterFogCoord; + } + else { + fog = _mesa_z_to_fogfactor(ctx, ctx->Current.RasterDistance); + } + + for (i = 0; i < width; i++) { + zspan[i] = z; + fogSpan[i] = fog; + } + } + + if (SWRAST_CONTEXT(ctx)->_RasterMask == 0 + && !zoom + && destx >= 0 + && destx + width <= ctx->DrawBuffer->Width) { + quick_draw = GL_TRUE; + } + else { + quick_draw = GL_FALSE; + } + + /* If read and draw buffer are different we must do buffer switching */ + saveReadAlpha = ctx->ReadBuffer->Alpha; + changeBuffer = ctx->Pixel.ReadBuffer != ctx->Color.DrawBuffer + || ctx->DrawBuffer != ctx->ReadBuffer; + + + /* allocate space for GLfloat image */ + tmpImage = (GLfloat *) MALLOC(width * height * 4 * sizeof(GLfloat)); + if (!tmpImage) { + _mesa_error(ctx, GL_OUT_OF_MEMORY, "glCopyPixels"); + return; + } + convImage = (GLfloat *) MALLOC(width * height * 4 * sizeof(GLfloat)); + if (!convImage) { + FREE(tmpImage); + _mesa_error(ctx, GL_OUT_OF_MEMORY, "glCopyPixels"); + return; + } + + dest = tmpImage; + + if (changeBuffer) { + (*swrast->Driver.SetReadBuffer)( ctx, ctx->ReadBuffer, + ctx->Pixel.DriverReadBuffer ); + if (ctx->Pixel.DriverReadBuffer == GL_FRONT_LEFT) + ctx->ReadBuffer->Alpha = ctx->ReadBuffer->FrontLeftAlpha; + else if (ctx->Pixel.DriverReadBuffer == GL_BACK_LEFT) + ctx->ReadBuffer->Alpha = ctx->ReadBuffer->BackLeftAlpha; + else if (ctx->Pixel.DriverReadBuffer == GL_FRONT_RIGHT) + ctx->ReadBuffer->Alpha = ctx->ReadBuffer->FrontRightAlpha; + else + ctx->ReadBuffer->Alpha = ctx->ReadBuffer->BackRightAlpha; + } + + /* read source image */ + dest = tmpImage; + for (row = 0; row < height; row++) { + GLchan rgba[MAX_WIDTH][4]; + GLint i; + _mesa_read_rgba_span(ctx, ctx->ReadBuffer, width, srcx, srcy + row, rgba); + /* convert GLchan to GLfloat */ + for (i = 0; i < width; i++) { + *dest++ = (GLfloat) rgba[i][RCOMP] * (1.0F / CHAN_MAXF); + *dest++ = (GLfloat) rgba[i][GCOMP] * (1.0F / CHAN_MAXF); + *dest++ = (GLfloat) rgba[i][BCOMP] * (1.0F / CHAN_MAXF); + *dest++ = (GLfloat) rgba[i][ACOMP] * (1.0F / CHAN_MAXF); + } + } + + /* read from the draw buffer again (in case of blending) */ + if (changeBuffer) { + (*swrast->Driver.SetReadBuffer)( ctx, ctx->DrawBuffer, + ctx->Color.DriverDrawBuffer ); + ctx->ReadBuffer->Alpha = saveReadAlpha; + } + + /* do image transfer ops up until convolution */ + for (row = 0; row < height; row++) { + GLfloat (*rgba)[4] = (GLfloat (*)[4]) tmpImage + row * width * 4; + + /* scale & bias */ + if (transferOps & IMAGE_SCALE_BIAS_BIT) { + _mesa_scale_and_bias_rgba(ctx, width, rgba, + ctx->Pixel.RedScale, ctx->Pixel.GreenScale, + ctx->Pixel.BlueScale, ctx->Pixel.AlphaScale, + ctx->Pixel.RedBias, ctx->Pixel.GreenBias, + ctx->Pixel.BlueBias, ctx->Pixel.AlphaBias); + } + /* color map lookup */ + if (transferOps & IMAGE_MAP_COLOR_BIT) { + _mesa_map_rgba(ctx, width, rgba); + } + /* GL_COLOR_TABLE lookup */ + if (transferOps & IMAGE_COLOR_TABLE_BIT) { + _mesa_lookup_rgba(&ctx->ColorTable, width, rgba); + } + } + + /* do convolution */ + if (ctx->Pixel.Convolution2DEnabled) { + _mesa_convolve_2d_image(ctx, &width, &height, tmpImage, convImage); + } + else { + ASSERT(ctx->Pixel.Separable2DEnabled); + _mesa_convolve_sep_image(ctx, &width, &height, tmpImage, convImage); + } + FREE(tmpImage); + + /* do remaining image transfer ops */ + for (row = 0; row < height; row++) { + GLfloat (*rgba)[4] = (GLfloat (*)[4]) convImage + row * width * 4; + + /* GL_POST_CONVOLUTION_COLOR_TABLE lookup */ + if (transferOps & IMAGE_POST_CONVOLUTION_COLOR_TABLE_BIT) { + _mesa_lookup_rgba(&ctx->PostConvolutionColorTable, width, rgba); + } + /* color matrix */ + if (transferOps & IMAGE_COLOR_MATRIX_BIT) { + _mesa_transform_rgba(ctx, width, rgba); + } + /* GL_POST_COLOR_MATRIX_COLOR_TABLE lookup */ + if (transferOps & IMAGE_POST_COLOR_MATRIX_COLOR_TABLE_BIT) { + _mesa_lookup_rgba(&ctx->PostColorMatrixColorTable, width, rgba); + } + /* update histogram count */ + if (transferOps & IMAGE_HISTOGRAM_BIT) { + _mesa_update_histogram(ctx, width, (CONST GLfloat (*)[4]) rgba); + } + /* update min/max */ + if (transferOps & IMAGE_MIN_MAX_BIT) { + _mesa_update_minmax(ctx, width, (CONST GLfloat (*)[4]) rgba); + } + } + + for (row = 0; row < height; row++) { + const GLfloat *src = convImage + row * width * 4; + GLchan rgba[MAX_WIDTH][4]; + GLint i, dy; + + /* clamp to [0,1] and convert float back to chan */ + for (i = 0; i < width; i++) { + GLint r = (GLint) (src[i * 4 + RCOMP] * CHAN_MAXF); + GLint g = (GLint) (src[i * 4 + GCOMP] * CHAN_MAXF); + GLint b = (GLint) (src[i * 4 + BCOMP] * CHAN_MAXF); + GLint a = (GLint) (src[i * 4 + ACOMP] * CHAN_MAXF); + rgba[i][RCOMP] = (GLchan) CLAMP(r, 0, CHAN_MAX); + rgba[i][GCOMP] = (GLchan) CLAMP(g, 0, CHAN_MAX); + rgba[i][BCOMP] = (GLchan) CLAMP(b, 0, CHAN_MAX); + rgba[i][ACOMP] = (GLchan) CLAMP(a, 0, CHAN_MAX); + } + + if (ctx->Texture._ReallyEnabled && ctx->Pixel.PixelTextureEnabled) { + GLfloat s[MAX_WIDTH], t[MAX_WIDTH], r[MAX_WIDTH], q[MAX_WIDTH]; + GLchan primary_rgba[MAX_WIDTH][4]; + GLuint unit; + /* XXX not sure how multitexture is supposed to work here */ + + MEMCPY(primary_rgba, rgba, 4 * width * sizeof(GLchan)); + + for (unit = 0; unit < ctx->Const.MaxTextureUnits; unit++) { + _mesa_pixeltexgen(ctx, width, (const GLchan (*)[4]) rgba, + s, t, r, q); + _swrast_texture_fragments(ctx, unit, width, s, t, r, NULL, + (CONST GLchan (*)[4]) primary_rgba, + rgba); + } + } + + /* write row to framebuffer */ + + dy = desty + row; + if (quick_draw && dy >= 0 && dy < ctx->DrawBuffer->Height) { + (*swrast->Driver.WriteRGBASpan)( ctx, width, destx, dy, + (const GLchan (*)[4])rgba, NULL ); + } + else if (zoom) { + _mesa_write_zoomed_rgba_span( ctx, width, destx, dy, zspan, fogSpan, + (const GLchan (*)[4])rgba, desty); + } + else { + _mesa_write_rgba_span( ctx, width, destx, dy, zspan, fogSpan, rgba, + NULL, GL_BITMAP ); + } + } + + FREE(convImage); +} + + +/* + * RGBA copypixels + */ +static void +copy_rgba_pixels(GLcontext *ctx, GLint srcx, GLint srcy, + GLint width, GLint height, GLint destx, GLint desty) +{ + SWcontext *swrast = SWRAST_CONTEXT(ctx); + GLdepth zspan[MAX_WIDTH]; + GLfloat fogSpan[MAX_WIDTH]; + GLchan rgba[MAX_WIDTH][4]; + GLchan *tmpImage,*p; + GLboolean quick_draw; + GLint sy, dy, stepy; + GLint i, j; + GLboolean changeBuffer; + GLchan *saveReadAlpha; + const GLboolean zoom = ctx->Pixel.ZoomX != 1.0F || ctx->Pixel.ZoomY != 1.0F; + GLint overlapping; + const GLuint transferOps = ctx->_ImageTransferState; + + if (ctx->Pixel.Convolution2DEnabled || ctx->Pixel.Separable2DEnabled) { + copy_conv_rgba_pixels(ctx, srcx, srcy, width, height, destx, desty); + return; + } + + /* Determine if copy should be done bottom-to-top or top-to-bottom */ + if (srcy < desty) { + /* top-down max-to-min */ + sy = srcy + height - 1; + dy = desty + height - 1; + stepy = -1; + } + else { + /* bottom-up min-to-max */ + sy = srcy; + dy = desty; + stepy = 1; + } + + overlapping = regions_overlap(srcx, srcy, destx, desty, width, height, + ctx->Pixel.ZoomX, ctx->Pixel.ZoomY); + + if (ctx->Depth.Test || ctx->Fog.Enabled) { + /* fill in array of z values */ + GLdepth z = (GLdepth) (ctx->Current.RasterPos[2] * ctx->DepthMax); + GLfloat fog; + + if (ctx->Fog.FogCoordinateSource == GL_FOG_COORDINATE_EXT) { + fog = ctx->Current.RasterFogCoord; + } + else { + fog = _mesa_z_to_fogfactor(ctx, ctx->Current.RasterDistance); + } + + for (i=0;i_RasterMask == 0 + && !zoom + && destx >= 0 + && destx + width <= ctx->DrawBuffer->Width) { + quick_draw = GL_TRUE; + } + else { + quick_draw = GL_FALSE; + } + + /* If read and draw buffer are different we must do buffer switching */ + saveReadAlpha = ctx->ReadBuffer->Alpha; + changeBuffer = ctx->Pixel.ReadBuffer != ctx->Color.DrawBuffer + || ctx->DrawBuffer != ctx->ReadBuffer; + + (*swrast->Driver.SetReadBuffer)( ctx, ctx->ReadBuffer, + ctx->Pixel.DriverReadBuffer ); + + if (overlapping) { + GLint ssy = sy; + tmpImage = (GLchan *) MALLOC(width * height * sizeof(GLchan) * 4); + if (!tmpImage) { + _mesa_error( ctx, GL_OUT_OF_MEMORY, "glCopyPixels" ); + return; + } + p = tmpImage; + if (changeBuffer) { + (*swrast->Driver.SetReadBuffer)( ctx, ctx->ReadBuffer, + ctx->Pixel.DriverReadBuffer ); + if (ctx->Pixel.DriverReadBuffer == GL_FRONT_LEFT) + ctx->ReadBuffer->Alpha = ctx->ReadBuffer->FrontLeftAlpha; + else if (ctx->Pixel.DriverReadBuffer == GL_BACK_LEFT) + ctx->ReadBuffer->Alpha = ctx->ReadBuffer->BackLeftAlpha; + else if (ctx->Pixel.DriverReadBuffer == GL_FRONT_RIGHT) + ctx->ReadBuffer->Alpha = ctx->ReadBuffer->FrontRightAlpha; + else + ctx->ReadBuffer->Alpha = ctx->ReadBuffer->BackRightAlpha; + } + for (j = 0; j < height; j++, ssy += stepy) { + _mesa_read_rgba_span( ctx, ctx->ReadBuffer, width, srcx, ssy, + (GLchan (*)[4]) p ); + p += (width * sizeof(GLchan) * 4); + } + p = tmpImage; + } + else { + tmpImage = NULL; /* silence compiler warnings */ + p = NULL; + } + + for (j = 0; j < height; j++, sy += stepy, dy += stepy) { + /* Get source pixels */ + if (overlapping) { + /* get from buffered image */ + MEMCPY(rgba, p, width * sizeof(GLchan) * 4); + p += (width * sizeof(GLchan) * 4); + } + else { + /* get from framebuffer */ + if (changeBuffer) { + (*swrast->Driver.SetReadBuffer)( ctx, ctx->ReadBuffer, + ctx->Pixel.DriverReadBuffer ); + if (ctx->Pixel.DriverReadBuffer == GL_FRONT_LEFT) { + ctx->ReadBuffer->Alpha = ctx->ReadBuffer->FrontLeftAlpha; + } + else if (ctx->Pixel.DriverReadBuffer == GL_BACK_LEFT) { + ctx->ReadBuffer->Alpha = ctx->ReadBuffer->BackLeftAlpha; + } + else if (ctx->Pixel.DriverReadBuffer == GL_FRONT_RIGHT) { + ctx->ReadBuffer->Alpha = ctx->ReadBuffer->FrontRightAlpha; + } + else { + ctx->ReadBuffer->Alpha = ctx->ReadBuffer->BackRightAlpha; + } + } + _mesa_read_rgba_span( ctx, ctx->ReadBuffer, width, srcx, sy, rgba ); + } + + if (changeBuffer) { + /* read from the draw buffer again (in case of blending) */ + (*swrast->Driver.SetReadBuffer)( ctx, ctx->DrawBuffer, + ctx->Color.DriverDrawBuffer ); + ctx->ReadBuffer->Alpha = saveReadAlpha; + } + + if (transferOps) { + const GLfloat scale = (1.0F / CHAN_MAXF); + GLint k; + DEFMARRAY(GLfloat, rgbaFloat, MAX_WIDTH, 4); /* mac 32k limitation */ + CHECKARRAY(rgbaFloat, return); + + /* convert chan to float */ + for (k = 0; k < width; k++) { + rgbaFloat[k][RCOMP] = (GLfloat) rgba[k][RCOMP] * scale; + rgbaFloat[k][GCOMP] = (GLfloat) rgba[k][GCOMP] * scale; + rgbaFloat[k][BCOMP] = (GLfloat) rgba[k][BCOMP] * scale; + rgbaFloat[k][ACOMP] = (GLfloat) rgba[k][ACOMP] * scale; + } + /* scale & bias */ + if (transferOps & IMAGE_SCALE_BIAS_BIT) { + _mesa_scale_and_bias_rgba(ctx, width, rgbaFloat, + ctx->Pixel.RedScale, ctx->Pixel.GreenScale, + ctx->Pixel.BlueScale, ctx->Pixel.AlphaScale, + ctx->Pixel.RedBias, ctx->Pixel.GreenBias, + ctx->Pixel.BlueBias, ctx->Pixel.AlphaBias); + } + /* color map lookup */ + if (transferOps & IMAGE_MAP_COLOR_BIT) { + _mesa_map_rgba(ctx, width, rgbaFloat); + } + /* GL_COLOR_TABLE lookup */ + if (transferOps & IMAGE_COLOR_TABLE_BIT) { + _mesa_lookup_rgba(&ctx->ColorTable, width, rgbaFloat); + } + /* convolution */ + if (transferOps & IMAGE_CONVOLUTION_BIT) { + /* XXX to do */ + } + /* GL_POST_CONVOLUTION_RED/GREEN/BLUE/ALPHA_SCALE/BIAS */ + if (transferOps & IMAGE_POST_CONVOLUTION_SCALE_BIAS) { + _mesa_scale_and_bias_rgba(ctx, width, rgbaFloat, + ctx->Pixel.PostConvolutionScale[RCOMP], + ctx->Pixel.PostConvolutionScale[GCOMP], + ctx->Pixel.PostConvolutionScale[BCOMP], + ctx->Pixel.PostConvolutionScale[ACOMP], + ctx->Pixel.PostConvolutionBias[RCOMP], + ctx->Pixel.PostConvolutionBias[GCOMP], + ctx->Pixel.PostConvolutionBias[BCOMP], + ctx->Pixel.PostConvolutionBias[ACOMP]); + } + /* GL_POST_CONVOLUTION_COLOR_TABLE lookup */ + if (transferOps & IMAGE_POST_CONVOLUTION_COLOR_TABLE_BIT) { + _mesa_lookup_rgba(&ctx->PostConvolutionColorTable, width, rgbaFloat); + } + /* color matrix */ + if (transferOps & IMAGE_COLOR_MATRIX_BIT) { + _mesa_transform_rgba(ctx, width, rgbaFloat); + } + /* GL_POST_COLOR_MATRIX_COLOR_TABLE lookup */ + if (transferOps & IMAGE_POST_COLOR_MATRIX_COLOR_TABLE_BIT) { + _mesa_lookup_rgba(&ctx->PostColorMatrixColorTable, width, rgbaFloat); + } + /* update histogram count */ + if (transferOps & IMAGE_HISTOGRAM_BIT) { + _mesa_update_histogram(ctx, width, (CONST GLfloat (*)[4]) rgbaFloat); + } + /* update min/max */ + if (transferOps & IMAGE_MIN_MAX_BIT) { + _mesa_update_minmax(ctx, width, (CONST GLfloat (*)[4]) rgbaFloat); + } + /* clamp to [0,1] and convert float back to chan */ + for (k = 0; k < width; k++) { + GLint r = (GLint) (rgbaFloat[k][RCOMP] * CHAN_MAXF); + GLint g = (GLint) (rgbaFloat[k][GCOMP] * CHAN_MAXF); + GLint b = (GLint) (rgbaFloat[k][BCOMP] * CHAN_MAXF); + GLint a = (GLint) (rgbaFloat[k][ACOMP] * CHAN_MAXF); + rgba[k][RCOMP] = (GLchan) CLAMP(r, 0, CHAN_MAX); + rgba[k][GCOMP] = (GLchan) CLAMP(g, 0, CHAN_MAX); + rgba[k][BCOMP] = (GLchan) CLAMP(b, 0, CHAN_MAX); + rgba[k][ACOMP] = (GLchan) CLAMP(a, 0, CHAN_MAX); + } + UNDEFARRAY(rgbaFloat); /* mac 32k limitation */ + } + + if (ctx->Texture._ReallyEnabled && ctx->Pixel.PixelTextureEnabled) { + GLuint unit; + GLchan primary_rgba[MAX_WIDTH][4]; + DEFARRAY(GLfloat, s, MAX_WIDTH); /* mac 32k limitation */ + DEFARRAY(GLfloat, t, MAX_WIDTH); /* mac 32k limitation */ + DEFARRAY(GLfloat, r, MAX_WIDTH); /* mac 32k limitation */ + DEFARRAY(GLfloat, q, MAX_WIDTH); /* mac 32k limitation */ + CHECKARRAY(s, return); /* mac 32k limitation */ + CHECKARRAY(t, return); + CHECKARRAY(r, return); + CHECKARRAY(q, return); + + /* XXX not sure how multitexture is supposed to work here */ + MEMCPY(primary_rgba, rgba, 4 * width * sizeof(GLchan)); + + for (unit = 0; unit < ctx->Const.MaxTextureUnits; unit++) { + _mesa_pixeltexgen(ctx, width, (const GLchan (*)[4]) rgba, + s, t, r, q); + _swrast_texture_fragments(ctx, unit, width, s, t, r, NULL, + (CONST GLchan (*)[4]) primary_rgba, + rgba); + } + + UNDEFARRAY(s); /* mac 32k limitation */ + UNDEFARRAY(t); + UNDEFARRAY(r); + UNDEFARRAY(q); + } + + if (quick_draw && dy >= 0 && dy < ctx->DrawBuffer->Height) { + (*swrast->Driver.WriteRGBASpan)( ctx, width, destx, dy, + (const GLchan (*)[4])rgba, NULL ); + } + else if (zoom) { + _mesa_write_zoomed_rgba_span( ctx, width, destx, dy, zspan, fogSpan, + (const GLchan (*)[4])rgba, desty); + } + else { + _mesa_write_rgba_span( ctx, width, destx, dy, zspan, fogSpan, rgba, + NULL, GL_BITMAP ); + } + } + + /* Restore pixel source to be the draw buffer (for blending, etc) */ + (*swrast->Driver.SetReadBuffer)( ctx, ctx->DrawBuffer, + ctx->Color.DriverDrawBuffer ); + + if (overlapping) + FREE(tmpImage); +} + + +static void copy_ci_pixels( GLcontext *ctx, + GLint srcx, GLint srcy, GLint width, GLint height, + GLint destx, GLint desty ) +{ + SWcontext *swrast = SWRAST_CONTEXT(ctx); + GLdepth zspan[MAX_WIDTH]; + GLfloat fogSpan[MAX_WIDTH]; + GLuint *tmpImage,*p; + GLint sy, dy, stepy; + GLint i, j; + GLboolean changeBuffer; + const GLboolean zoom = ctx->Pixel.ZoomX != 1.0F || ctx->Pixel.ZoomY != 1.0F; + const GLboolean shift_or_offset = ctx->Pixel.IndexShift || ctx->Pixel.IndexOffset; + GLint overlapping; + + /* Determine if copy should be bottom-to-top or top-to-bottom */ + if (srcyPixel.ZoomX, ctx->Pixel.ZoomY); + + if (ctx->Depth.Test || ctx->Fog.Enabled) { + /* fill in array of z values */ + GLdepth z = (GLdepth) (ctx->Current.RasterPos[2] * ctx->DepthMax); + GLfloat fog; + + if (ctx->Fog.FogCoordinateSource == GL_FOG_COORDINATE_EXT) { + fog = ctx->Current.RasterFogCoord; + } + else { + fog = _mesa_z_to_fogfactor(ctx, ctx->Current.RasterDistance); + } + + for (i=0;iPixel.ReadBuffer != ctx->Color.DrawBuffer + || ctx->DrawBuffer != ctx->ReadBuffer; + + (*swrast->Driver.SetReadBuffer)( ctx, ctx->ReadBuffer, + ctx->Pixel.DriverReadBuffer ); + + if (overlapping) { + GLint ssy = sy; + tmpImage = (GLuint *) MALLOC(width * height * sizeof(GLuint)); + if (!tmpImage) { + _mesa_error( ctx, GL_OUT_OF_MEMORY, "glCopyPixels" ); + return; + } + p = tmpImage; + if (changeBuffer) { + (*swrast->Driver.SetReadBuffer)( ctx, ctx->ReadBuffer, + ctx->Pixel.DriverReadBuffer ); + } + for (j = 0; j < height; j++, ssy += stepy) { + _mesa_read_index_span( ctx, ctx->ReadBuffer, width, srcx, ssy, p ); + p += width; + } + p = tmpImage; + } + else { + tmpImage = NULL; /* silence compiler warning */ + p = NULL; + } + + for (j = 0; j < height; j++, sy += stepy, dy += stepy) { + GLuint indexes[MAX_WIDTH]; + if (overlapping) { + MEMCPY(indexes, p, width * sizeof(GLuint)); + p += width; + } + else { + if (changeBuffer) { + (*swrast->Driver.SetReadBuffer)( ctx, ctx->ReadBuffer, + ctx->Pixel.DriverReadBuffer ); + } + _mesa_read_index_span( ctx, ctx->ReadBuffer, width, srcx, sy, indexes ); + } + + if (changeBuffer) { + /* set read buffer back to draw buffer (in case of logicops) */ + (*swrast->Driver.SetReadBuffer)( ctx, ctx->DrawBuffer, + ctx->Color.DriverDrawBuffer ); + } + + if (shift_or_offset) { + _mesa_shift_and_offset_ci( ctx, width, indexes ); + } + if (ctx->Pixel.MapColorFlag) { + _mesa_map_ci( ctx, width, indexes ); + } + + if (zoom) { + _mesa_write_zoomed_index_span(ctx, width, destx, dy, zspan, fogSpan, + indexes, desty ); + } + else { + _mesa_write_index_span(ctx, width, destx, dy, zspan, fogSpan, indexes, + NULL, GL_BITMAP); + } + } + + /* Restore pixel source to be the draw buffer (for blending, etc) */ + (*swrast->Driver.SetReadBuffer)( ctx, ctx->DrawBuffer, + ctx->Color.DriverDrawBuffer ); + + if (overlapping) + FREE(tmpImage); +} + + + +/* + * TODO: Optimize!!!! + */ +static void copy_depth_pixels( GLcontext *ctx, GLint srcx, GLint srcy, + GLint width, GLint height, + GLint destx, GLint desty ) +{ + GLfloat depth[MAX_WIDTH]; + GLdepth zspan[MAX_WIDTH]; + GLfloat fogSpan[MAX_WIDTH]; + GLfloat *p, *tmpImage; + GLuint indexes[MAX_WIDTH]; + GLint sy, dy, stepy; + GLint i, j; + const GLboolean zoom = ctx->Pixel.ZoomX != 1.0F || ctx->Pixel.ZoomY != 1.0F; + GLint overlapping; + DEFMARRAY(GLubyte, rgba, MAX_WIDTH, 4); /* mac 32k limitation */ + CHECKARRAY(rgba, return); /* mac 32k limitation */ + + if (!ctx->Visual.depthBits) { + _mesa_error( ctx, GL_INVALID_OPERATION, "glCopyPixels" ); + UNDEFARRAY(rgba); /* mac 32k limitation */ + return; + } + + /* Determine if copy should be bottom-to-top or top-to-bottom */ + if (srcyPixel.ZoomX, ctx->Pixel.ZoomY); + + /* setup colors or indexes */ + if (ctx->Visual.rgbMode) { + GLuint *rgba32 = (GLuint *) rgba; + GLuint color = *(GLuint*)( ctx->Current.Color ); + for (i = 0; i < width; i++) { + rgba32[i] = color; + } + } + else { + for (i = 0; i < width; i++) { + indexes[i] = ctx->Current.Index; + } + } + + if (ctx->Fog.Enabled) { + GLfloat fog; + + if (ctx->Fog.FogCoordinateSource == GL_FOG_COORDINATE_EXT) { + fog = ctx->Current.RasterFogCoord; + } + else { + fog = _mesa_z_to_fogfactor(ctx, ctx->Current.RasterDistance); + } + + for (i = 0; i < width; i++) { + fogSpan[i] = fog; + } + } + + if (overlapping) { + GLint ssy = sy; + tmpImage = (GLfloat *) MALLOC(width * height * sizeof(GLfloat)); + if (!tmpImage) { + _mesa_error( ctx, GL_OUT_OF_MEMORY, "glCopyPixels" ); + UNDEFARRAY(rgba); /* mac 32k limitation */ + return; + } + p = tmpImage; + for (j = 0; j < height; j++, ssy += stepy) { + _mesa_read_depth_span_float(ctx, width, srcx, ssy, p); + p += width; + } + p = tmpImage; + } + else { + tmpImage = NULL; /* silence compiler warning */ + p = NULL; + } + + for (j = 0; j < height; j++, sy += stepy, dy += stepy) { + if (overlapping) { + MEMCPY(depth, p, width * sizeof(GLfloat)); + p += width; + } + else { + _mesa_read_depth_span_float(ctx, width, srcx, sy, depth); + } + + for (i = 0; i < width; i++) { + GLfloat d = depth[i] * ctx->Pixel.DepthScale + ctx->Pixel.DepthBias; + zspan[i] = (GLdepth) (CLAMP(d, 0.0F, 1.0F) * ctx->DepthMax); + } + + if (ctx->Visual.rgbMode) { + if (zoom) { + _mesa_write_zoomed_rgba_span( ctx, width, destx, dy, zspan, + fogSpan, (const GLchan (*)[4])rgba, desty ); + } + else { + _mesa_write_rgba_span( ctx, width, destx, dy, zspan, fogSpan, + rgba, NULL, GL_BITMAP); + } + } + else { + if (zoom) { + _mesa_write_zoomed_index_span( ctx, width, destx, dy, + zspan, fogSpan, indexes, desty ); + } + else { + _mesa_write_index_span( ctx, width, destx, dy, + zspan, fogSpan, indexes, NULL, GL_BITMAP ); + } + } + } + + UNDEFARRAY(rgba); /* mac 32k limitation */ + + if (overlapping) + FREE(tmpImage); +} + + + +static void copy_stencil_pixels( GLcontext *ctx, GLint srcx, GLint srcy, + GLint width, GLint height, + GLint destx, GLint desty ) +{ + GLint sy, dy, stepy; + GLint j; + GLstencil *p, *tmpImage; + const GLboolean zoom = ctx->Pixel.ZoomX != 1.0F || ctx->Pixel.ZoomY != 1.0F; + const GLboolean shift_or_offset = ctx->Pixel.IndexShift || ctx->Pixel.IndexOffset; + GLint overlapping; + + if (!ctx->Visual.stencilBits) { + _mesa_error( ctx, GL_INVALID_OPERATION, "glCopyPixels" ); + return; + } + + /* Determine if copy should be bottom-to-top or top-to-bottom */ + if (srcy < desty) { + /* top-down max-to-min */ + sy = srcy + height - 1; + dy = desty + height - 1; + stepy = -1; + } + else { + /* bottom-up min-to-max */ + sy = srcy; + dy = desty; + stepy = 1; + } + + overlapping = regions_overlap(srcx, srcy, destx, desty, width, height, + ctx->Pixel.ZoomX, ctx->Pixel.ZoomY); + + if (overlapping) { + GLint ssy = sy; + tmpImage = (GLstencil *) MALLOC(width * height * sizeof(GLstencil)); + if (!tmpImage) { + _mesa_error( ctx, GL_OUT_OF_MEMORY, "glCopyPixels" ); + return; + } + p = tmpImage; + for (j = 0; j < height; j++, ssy += stepy) { + _mesa_read_stencil_span( ctx, width, srcx, ssy, p ); + p += width; + } + p = tmpImage; + } + else { + tmpImage = NULL; /* silence compiler warning */ + p = NULL; + } + + for (j = 0; j < height; j++, sy += stepy, dy += stepy) { + GLstencil stencil[MAX_WIDTH]; + + if (overlapping) { + MEMCPY(stencil, p, width * sizeof(GLstencil)); + p += width; + } + else { + _mesa_read_stencil_span( ctx, width, srcx, sy, stencil ); + } + + if (shift_or_offset) { + _mesa_shift_and_offset_stencil( ctx, width, stencil ); + } + if (ctx->Pixel.MapStencilFlag) { + _mesa_map_stencil( ctx, width, stencil ); + } + + if (zoom) { + _mesa_write_zoomed_stencil_span( ctx, width, destx, dy, stencil, desty ); + } + else { + _mesa_write_stencil_span( ctx, width, destx, dy, stencil ); + } + } + + if (overlapping) + FREE(tmpImage); +} + + + + +void +_swrast_CopyPixels( GLcontext *ctx, + GLint srcx, GLint srcy, GLsizei width, GLsizei height, + GLint destx, GLint desty, + GLenum type ) +{ + SWcontext *swrast = SWRAST_CONTEXT(ctx); + RENDER_START(swrast,ctx); + + if (swrast->NewState) + _swrast_validate_derived( ctx ); + + if (type == GL_COLOR && ctx->Visual.rgbMode) { + copy_rgba_pixels( ctx, srcx, srcy, width, height, destx, desty ); + } + else if (type == GL_COLOR && !ctx->Visual.rgbMode) { + copy_ci_pixels( ctx, srcx, srcy, width, height, destx, desty ); + } + else if (type == GL_DEPTH) { + copy_depth_pixels( ctx, srcx, srcy, width, height, destx, desty ); + } + else if (type == GL_STENCIL) { + copy_stencil_pixels( ctx, srcx, srcy, width, height, destx, desty ); + } + else { + _mesa_error( ctx, GL_INVALID_ENUM, "glCopyPixels" ); + } + + RENDER_FINISH(swrast,ctx); +} Index: dll/opengl/opengl32/mesa/swrast/s_depth.c =================================================================== --- dll/opengl/opengl32/mesa/swrast/s_depth.c (revision 0) +++ dll/opengl/opengl32/mesa/swrast/s_depth.c (working copy) @@ -0,0 +1,1640 @@ +/* $Id: s_depth.c,v 1.9 2001/03/19 02:25:36 keithw Exp $ */ + +/* + * Mesa 3-D graphics library + * Version: 3.5 + * + * Copyright (C) 1999-2001 Brian Paul 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 + * BRIAN PAUL 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. + */ + + +#include "glheader.h" +#include "context.h" +#include "macros.h" +#include "mem.h" + +#include "s_depth.h" +#include "s_context.h" +#include "s_pb.h" + + + + +/* + * Return address of depth buffer value for given window coord. + */ +GLvoid * +_mesa_zbuffer_address(GLcontext *ctx, GLint x, GLint y) +{ + if (ctx->Visual.depthBits <= 16) + return (GLushort *) ctx->DrawBuffer->DepthBuffer + ctx->DrawBuffer->Width * y + x; + else + return (GLuint *) ctx->DrawBuffer->DepthBuffer + ctx->DrawBuffer->Width * y + x; +} + + +#define Z_ADDRESS16( CTX, X, Y ) \ + ( ((GLushort *) (CTX)->DrawBuffer->DepthBuffer) \ + + (CTX)->DrawBuffer->Width * (Y) + (X) ) + +#define Z_ADDRESS32( CTX, X, Y ) \ + ( ((GLuint *) (CTX)->DrawBuffer->DepthBuffer) \ + + (CTX)->DrawBuffer->Width * (Y) + (X) ) + + + +/**********************************************************************/ +/***** Depth Testing Functions *****/ +/**********************************************************************/ + + +/* + * Do depth test for an array of fragments. This is used both for + * software and hardware Z buffers. + * Input: zbuffer - array of z values in the zbuffer + * z - array of fragment z values + * Return: number of fragments which pass the test. + */ +static GLuint +depth_test_span16( GLcontext *ctx, GLuint n, GLint x, GLint y, + GLushort zbuffer[], const GLdepth z[], GLubyte mask[] ) +{ + GLuint passed = 0; + + /* switch cases ordered from most frequent to less frequent */ + switch (ctx->Depth.Func) { + case GL_LESS: + if (ctx->Depth.Mask) { + /* Update Z buffer */ + GLuint i; + for (i=0; iDepth.Mask) { + /* Update Z buffer */ + GLuint i; + for (i=0;iDepth.Mask) { + /* Update Z buffer */ + GLuint i; + for (i=0;i= zbuffer[i]) { + zbuffer[i] = z[i]; + passed++; + } + else { + mask[i] = 0; + } + } + } + } + else { + /* Don't update Z buffer */ + GLuint i; + for (i=0;i= zbuffer[i]) { + /* pass */ + passed++; + } + else { + mask[i] = 0; + } + } + } + } + break; + case GL_GREATER: + if (ctx->Depth.Mask) { + /* Update Z buffer */ + GLuint i; + for (i=0;i zbuffer[i]) { + zbuffer[i] = z[i]; + passed++; + } + else { + mask[i] = 0; + } + } + } + } + else { + /* Don't update Z buffer */ + GLuint i; + for (i=0;i zbuffer[i]) { + /* pass */ + passed++; + } + else { + mask[i] = 0; + } + } + } + } + break; + case GL_NOTEQUAL: + if (ctx->Depth.Mask) { + /* Update Z buffer */ + GLuint i; + for (i=0;iDepth.Mask) { + /* Update Z buffer */ + GLuint i; + for (i=0;iDepth.Mask) { + /* Update Z buffer */ + GLuint i; + for (i=0;iDepth.Func) { + case GL_LESS: + if (ctx->Depth.Mask) { + /* Update Z buffer */ + GLuint i; + for (i=0; iDepth.Mask) { + /* Update Z buffer */ + GLuint i; + for (i=0;iDepth.Mask) { + /* Update Z buffer */ + GLuint i; + for (i=0;i= zbuffer[i]) { + zbuffer[i] = z[i]; + passed++; + } + else { + mask[i] = 0; + } + } + } + } + else { + /* Don't update Z buffer */ + GLuint i; + for (i=0;i= zbuffer[i]) { + /* pass */ + passed++; + } + else { + mask[i] = 0; + } + } + } + } + break; + case GL_GREATER: + if (ctx->Depth.Mask) { + /* Update Z buffer */ + GLuint i; + for (i=0;i zbuffer[i]) { + zbuffer[i] = z[i]; + passed++; + } + else { + mask[i] = 0; + } + } + } + } + else { + /* Don't update Z buffer */ + GLuint i; + for (i=0;i zbuffer[i]) { + /* pass */ + passed++; + } + else { + mask[i] = 0; + } + } + } + } + break; + case GL_NOTEQUAL: + if (ctx->Depth.Mask) { + /* Update Z buffer */ + GLuint i; + for (i=0;iDepth.Mask) { + /* Update Z buffer */ + GLuint i; + for (i=0;iDepth.Mask) { + /* Update Z buffer */ + GLuint i; + for (i=0;iDriver.ReadDepthSpan) { + /* hardware-based depth buffer */ + GLdepth zbuffer[MAX_WIDTH]; + GLuint passed; + (*swrast->Driver.ReadDepthSpan)(ctx, n, x, y, zbuffer); + passed = depth_test_span32(ctx, n, x, y, zbuffer, z, mask); + assert(swrast->Driver.WriteDepthSpan); + (*swrast->Driver.WriteDepthSpan)(ctx, n, x, y, zbuffer, mask); + return passed; + } + else { + /* software depth buffer */ + if (ctx->Visual.depthBits <= 16) { + GLushort *zptr = (GLushort *) Z_ADDRESS16(ctx, x, y); + GLuint passed = depth_test_span16(ctx, n, x, y, zptr, z, mask); + return passed; + } + else { + GLuint *zptr = (GLuint *) Z_ADDRESS32(ctx, x, y); + GLuint passed = depth_test_span32(ctx, n, x, y, zptr, z, mask); + return passed; + } + } +} + + + + +/* + * Do depth testing for an array of fragments using software Z buffer. + */ +static void +software_depth_test_pixels16( GLcontext *ctx, GLuint n, + const GLint x[], const GLint y[], + const GLdepth z[], GLubyte mask[] ) +{ + /* switch cases ordered from most frequent to less frequent */ + switch (ctx->Depth.Func) { + case GL_LESS: + if (ctx->Depth.Mask) { + /* Update Z buffer */ + GLuint i; + for (i=0; iDepth.Mask) { + /* Update Z buffer */ + GLuint i; + for (i=0; iDepth.Mask) { + /* Update Z buffer */ + GLuint i; + for (i=0; i= *zptr) { + /* pass */ + *zptr = z[i]; + } + else { + /* fail */ + mask[i] = 0; + } + } + } + } + else { + /* Don't update Z buffer */ + GLuint i; + for (i=0; i= *zptr) { + /* pass */ + } + else { + /* fail */ + mask[i] = 0; + } + } + } + } + break; + case GL_GREATER: + if (ctx->Depth.Mask) { + /* Update Z buffer */ + GLuint i; + for (i=0; i *zptr) { + /* pass */ + *zptr = z[i]; + } + else { + /* fail */ + mask[i] = 0; + } + } + } + } + else { + /* Don't update Z buffer */ + GLuint i; + for (i=0; i *zptr) { + /* pass */ + } + else { + /* fail */ + mask[i] = 0; + } + } + } + } + break; + case GL_NOTEQUAL: + if (ctx->Depth.Mask) { + /* Update Z buffer */ + GLuint i; + for (i=0; iDepth.Mask) { + /* Update Z buffer */ + GLuint i; + for (i=0; iDepth.Mask) { + /* Update Z buffer */ + GLuint i; + for (i=0; iDepth.Func) { + case GL_LESS: + if (ctx->Depth.Mask) { + /* Update Z buffer */ + GLuint i; + for (i=0; iDepth.Mask) { + /* Update Z buffer */ + GLuint i; + for (i=0; iDepth.Mask) { + /* Update Z buffer */ + GLuint i; + for (i=0; i= *zptr) { + /* pass */ + *zptr = z[i]; + } + else { + /* fail */ + mask[i] = 0; + } + } + } + } + else { + /* Don't update Z buffer */ + GLuint i; + for (i=0; i= *zptr) { + /* pass */ + } + else { + /* fail */ + mask[i] = 0; + } + } + } + } + break; + case GL_GREATER: + if (ctx->Depth.Mask) { + /* Update Z buffer */ + GLuint i; + for (i=0; i *zptr) { + /* pass */ + *zptr = z[i]; + } + else { + /* fail */ + mask[i] = 0; + } + } + } + } + else { + /* Don't update Z buffer */ + GLuint i; + for (i=0; i *zptr) { + /* pass */ + } + else { + /* fail */ + mask[i] = 0; + } + } + } + } + break; + case GL_NOTEQUAL: + if (ctx->Depth.Mask) { + /* Update Z buffer */ + GLuint i; + for (i=0; iDepth.Mask) { + /* Update Z buffer */ + GLuint i; + for (i=0; iDepth.Mask) { + /* Update Z buffer */ + GLuint i; + for (i=0; iDepth.Func) { + case GL_LESS: + if (ctx->Depth.Mask) { + /* Update Z buffer */ + GLuint i; + for (i=0; iDepth.Mask) { + /* Update Z buffer */ + GLuint i; + for (i=0; iDepth.Mask) { + /* Update Z buffer */ + GLuint i; + for (i=0; i= zbuffer[i]) { + /* pass */ + zbuffer[i] = z[i]; + } + else { + /* fail */ + mask[i] = 0; + } + } + } + } + else { + /* Don't update Z buffer */ + GLuint i; + for (i=0; i= zbuffer[i]) { + /* pass */ + } + else { + /* fail */ + mask[i] = 0; + } + } + } + } + break; + case GL_GREATER: + if (ctx->Depth.Mask) { + /* Update Z buffer */ + GLuint i; + for (i=0; i zbuffer[i]) { + /* pass */ + zbuffer[i] = z[i]; + } + else { + /* fail */ + mask[i] = 0; + } + } + } + } + else { + /* Don't update Z buffer */ + GLuint i; + for (i=0; i zbuffer[i]) { + /* pass */ + } + else { + /* fail */ + mask[i] = 0; + } + } + } + } + break; + case GL_NOTEQUAL: + if (ctx->Depth.Mask) { + /* Update Z buffer */ + GLuint i; + for (i=0; iDepth.Mask) { + /* Update Z buffer */ + GLuint i; + for (i=0; iDepth.Mask) { + /* Update Z buffer */ + GLuint i; + for (i=0; iDriver.ReadDepthPixels) { + /* read depth values from hardware Z buffer */ + GLdepth zbuffer[PB_SIZE]; + (*swrast->Driver.ReadDepthPixels)(ctx, n, x, y, zbuffer); + + hardware_depth_test_pixels( ctx, n, zbuffer, z, mask ); + + /* update hardware Z buffer with new values */ + assert(swrast->Driver.WriteDepthPixels); + (*swrast->Driver.WriteDepthPixels)(ctx, n, x, y, zbuffer, mask ); + } + else { + /* software depth testing */ + if (ctx->Visual.depthBits <= 16) + software_depth_test_pixels16(ctx, n, x, y, z, mask); + else + software_depth_test_pixels32(ctx, n, x, y, z, mask); + } +} + + + + + +/**********************************************************************/ +/***** Read Depth Buffer *****/ +/**********************************************************************/ + + +/* + * Read a span of depth values from the depth buffer. + * This function does clipping before calling the device driver function. + */ +void +_mesa_read_depth_span( GLcontext *ctx, + GLint n, GLint x, GLint y, GLdepth depth[] ) +{ + SWcontext *swrast = SWRAST_CONTEXT(ctx); + + if (y < 0 || y >= ctx->DrawBuffer->Height || + x + (GLint) n <= 0 || x >= ctx->DrawBuffer->Width) { + /* span is completely outside framebuffer */ + GLint i; + for (i = 0; i < n; i++) + depth[i] = 0; + return; + } + + if (x < 0) { + GLint dx = -x; + GLint i; + for (i = 0; i < dx; i++) + depth[i] = 0; + x = 0; + n -= dx; + depth += dx; + } + if (x + n > ctx->DrawBuffer->Width) { + GLint dx = x + n - ctx->DrawBuffer->Width; + GLint i; + for (i = 0; i < dx; i++) + depth[n - i - 1] = 0; + n -= dx; + } + if (n <= 0) { + return; + } + + if (ctx->DrawBuffer->DepthBuffer) { + /* read from software depth buffer */ + if (ctx->Visual.depthBits <= 16) { + const GLushort *zptr = Z_ADDRESS16( ctx, x, y ); + GLint i; + for (i = 0; i < n; i++) { + depth[i] = zptr[i]; + } + } + else { + const GLuint *zptr = Z_ADDRESS32( ctx, x, y ); + GLint i; + for (i = 0; i < n; i++) { + depth[i] = zptr[i]; + } + } + } + else if (swrast->Driver.ReadDepthSpan) { + /* read from hardware depth buffer */ + (*swrast->Driver.ReadDepthSpan)( ctx, n, x, y, depth ); + } + else { + /* no depth buffer */ + BZERO(depth, n * sizeof(GLfloat)); + } + +} + + + + +/* + * Return a span of depth values from the depth buffer as floats in [0,1]. + * This is used for both hardware and software depth buffers. + * Input: n - how many pixels + * x,y - location of first pixel + * Output: depth - the array of depth values + */ +void +_mesa_read_depth_span_float( GLcontext *ctx, + GLint n, GLint x, GLint y, GLfloat depth[] ) +{ + SWcontext *swrast = SWRAST_CONTEXT(ctx); + const GLfloat scale = 1.0F / ctx->DepthMaxF; + + if (y < 0 || y >= ctx->DrawBuffer->Height || + x + (GLint) n <= 0 || x >= ctx->DrawBuffer->Width) { + /* span is completely outside framebuffer */ + GLint i; + for (i = 0; i < n; i++) + depth[i] = 0.0F; + return; + } + + if (x < 0) { + GLint dx = -x; + GLint i; + for (i = 0; i < dx; i++) + depth[i] = 0.0F; + n -= dx; + x = 0; + } + if (x + n > ctx->DrawBuffer->Width) { + GLint dx = x + n - ctx->DrawBuffer->Width; + GLint i; + for (i = 0; i < dx; i++) + depth[n - i - 1] = 0.0F; + n -= dx; + } + if (n <= 0) { + return; + } + + if (ctx->DrawBuffer->DepthBuffer) { + /* read from software depth buffer */ + if (ctx->Visual.depthBits <= 16) { + const GLushort *zptr = Z_ADDRESS16( ctx, x, y ); + GLint i; + for (i = 0; i < n; i++) { + depth[i] = (GLfloat) zptr[i] * scale; + } + } + else { + const GLuint *zptr = Z_ADDRESS32( ctx, x, y ); + GLint i; + for (i = 0; i < n; i++) { + depth[i] = (GLfloat) zptr[i] * scale; + } + } + } + else if (swrast->Driver.ReadDepthSpan) { + /* read from hardware depth buffer */ + GLdepth d[MAX_WIDTH]; + GLint i; + assert(n <= MAX_WIDTH); + (*swrast->Driver.ReadDepthSpan)( ctx, n, x, y, d ); + for (i = 0; i < n; i++) { + depth[i] = d[i] * scale; + } + } + else { + /* no depth buffer */ + BZERO(depth, n * sizeof(GLfloat)); + } +} + + + +/**********************************************************************/ +/***** Allocate and Clear Depth Buffer *****/ +/**********************************************************************/ + + + +/* + * Allocate a new depth buffer. If there's already a depth buffer allocated + * it will be free()'d. The new depth buffer will be uniniitalized. + * This function is only called through Driver.alloc_depth_buffer. + */ +void +_mesa_alloc_depth_buffer( GLcontext *ctx ) +{ + /* deallocate current depth buffer if present */ + if (ctx->DrawBuffer->UseSoftwareDepthBuffer) { + GLint bytesPerValue; + + if (ctx->DrawBuffer->DepthBuffer) { + FREE(ctx->DrawBuffer->DepthBuffer); + ctx->DrawBuffer->DepthBuffer = NULL; + } + + /* allocate new depth buffer, but don't initialize it */ + if (ctx->Visual.depthBits <= 16) + bytesPerValue = sizeof(GLushort); + else + bytesPerValue = sizeof(GLuint); + + ctx->DrawBuffer->DepthBuffer = MALLOC( ctx->DrawBuffer->Width + * ctx->DrawBuffer->Height + * bytesPerValue ); + + if (!ctx->DrawBuffer->DepthBuffer) { + /* out of memory */ + ctx->Depth.Test = GL_FALSE; + ctx->NewState |= _NEW_DEPTH; + _mesa_error( ctx, GL_OUT_OF_MEMORY, "Couldn't allocate depth buffer" ); + } + } +} + + + + +/* + * Clear the depth buffer. If the depth buffer doesn't exist yet we'll + * allocate it now. + * This function is only called through Driver.clear_depth_buffer. + */ +void +_mesa_clear_depth_buffer( GLcontext *ctx ) +{ + if (ctx->Visual.depthBits == 0 + || !ctx->DrawBuffer->DepthBuffer + || !ctx->Depth.Mask) { + /* no depth buffer, or writing to it is disabled */ + return; + } + + /* The loops in this function have been written so the IRIX 5.3 + * C compiler can unroll them. Hopefully other compilers can too! + */ + + if (ctx->Scissor.Enabled) { + /* only clear scissor region */ + if (ctx->Visual.depthBits <= 16) { + const GLushort clearValue = (GLushort) (ctx->Depth.Clear * ctx->DepthMax); + const GLint rows = ctx->DrawBuffer->_Ymax - ctx->DrawBuffer->_Ymin; + const GLint cols = ctx->DrawBuffer->_Xmax - ctx->DrawBuffer->_Xmin; + const GLint rowStride = ctx->DrawBuffer->Width; + GLushort *dRow = (GLushort *) ctx->DrawBuffer->DepthBuffer + + ctx->DrawBuffer->_Ymin * rowStride + ctx->DrawBuffer->_Xmin; + GLint i, j; + for (i = 0; i < rows; i++) { + for (j = 0; j < cols; j++) { + dRow[j] = clearValue; + } + dRow += rowStride; + } + } + else { + const GLuint clearValue = (GLuint) (ctx->Depth.Clear * ctx->DepthMax); + const GLint rows = ctx->DrawBuffer->_Ymax - ctx->DrawBuffer->_Ymin; + const GLint cols = ctx->DrawBuffer->_Xmax - ctx->DrawBuffer->_Xmin; + const GLint rowStride = ctx->DrawBuffer->Width; + GLuint *dRow = (GLuint *) ctx->DrawBuffer->DepthBuffer + + ctx->DrawBuffer->_Ymin * rowStride + ctx->DrawBuffer->_Xmin; + GLint i, j; + for (i = 0; i < rows; i++) { + for (j = 0; j < cols; j++) { + dRow[j] = clearValue; + } + dRow += rowStride; + } + } + } + else { + /* clear whole buffer */ + if (ctx->Visual.depthBits <= 16) { + const GLushort clearValue = (GLushort) (ctx->Depth.Clear * ctx->DepthMax); + if ((clearValue & 0xff) == (clearValue >> 8)) { + if (clearValue == 0) { + BZERO(ctx->DrawBuffer->DepthBuffer, + 2*ctx->DrawBuffer->Width*ctx->DrawBuffer->Height); + } + else { + /* lower and upper bytes of clear_value are same, use MEMSET */ + MEMSET( ctx->DrawBuffer->DepthBuffer, clearValue & 0xff, + 2 * ctx->DrawBuffer->Width * ctx->DrawBuffer->Height); + } + } + else { + GLushort *d = (GLushort *) ctx->DrawBuffer->DepthBuffer; + GLint n = ctx->DrawBuffer->Width * ctx->DrawBuffer->Height; + while (n >= 16) { + d[0] = clearValue; d[1] = clearValue; + d[2] = clearValue; d[3] = clearValue; + d[4] = clearValue; d[5] = clearValue; + d[6] = clearValue; d[7] = clearValue; + d[8] = clearValue; d[9] = clearValue; + d[10] = clearValue; d[11] = clearValue; + d[12] = clearValue; d[13] = clearValue; + d[14] = clearValue; d[15] = clearValue; + d += 16; + n -= 16; + } + while (n > 0) { + *d++ = clearValue; + n--; + } + } + } + else { + /* >16 bit depth buffer */ + const GLuint clearValue = (GLuint) (ctx->Depth.Clear * ctx->DepthMax); + if (clearValue == 0) { + BZERO(ctx->DrawBuffer->DepthBuffer, + ctx->DrawBuffer->Width*ctx->DrawBuffer->Height*sizeof(GLuint)); + } + else { + GLint n = ctx->DrawBuffer->Width * ctx->DrawBuffer->Height; + GLuint *d = (GLuint *) ctx->DrawBuffer->DepthBuffer; + while (n >= 16) { + d[0] = clearValue; d[1] = clearValue; + d[2] = clearValue; d[3] = clearValue; + d[4] = clearValue; d[5] = clearValue; + d[6] = clearValue; d[7] = clearValue; + d[8] = clearValue; d[9] = clearValue; + d[10] = clearValue; d[11] = clearValue; + d[12] = clearValue; d[13] = clearValue; + d[14] = clearValue; d[15] = clearValue; + d += 16; + n -= 16; + } + while (n > 0) { + *d++ = clearValue; + n--; + } + } + } + } +} Index: dll/opengl/opengl32/mesa/swrast/s_depth.h =================================================================== --- dll/opengl/opengl32/mesa/swrast/s_depth.h (revision 0) +++ dll/opengl/opengl32/mesa/swrast/s_depth.h (working copy) @@ -0,0 +1,69 @@ +/* $Id: s_depth.h,v 1.3 2001/03/12 00:48:41 gareth Exp $ */ + +/* + * Mesa 3-D graphics library + * Version: 3.5 + * + * Copyright (C) 1999-2001 Brian Paul 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 + * BRIAN PAUL 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. + */ + + +#ifndef S_DEPTH_H +#define S_DEPTH_H + + +#include "mtypes.h" +#include "swrast.h" + + +extern GLvoid * +_mesa_zbuffer_address(GLcontext *ctx, GLint x, GLint y); + + +extern GLuint +_mesa_depth_test_span( GLcontext *ctx, GLuint n, GLint x, GLint y, + const GLdepth z[], GLubyte mask[] ); + +extern void +_mesa_depth_test_pixels( GLcontext *ctx, + GLuint n, const GLint x[], const GLint y[], + const GLdepth z[], GLubyte mask[] ); + + +extern void +_mesa_read_depth_span( GLcontext *ctx, + GLint n, GLint x, GLint y, GLdepth depth[] ); + + +extern void +_mesa_read_depth_span_float( GLcontext *ctx, GLint n, GLint x, GLint y, + GLfloat depth[] ); + + +extern void +_mesa_alloc_depth_buffer( GLcontext* ctx ); + + +extern void +_mesa_clear_depth_buffer( GLcontext* ctx ); + + + +#endif Index: dll/opengl/opengl32/mesa/swrast/s_drawpix.c =================================================================== --- dll/opengl/opengl32/mesa/swrast/s_drawpix.c (revision 0) +++ dll/opengl/opengl32/mesa/swrast/s_drawpix.c (working copy) @@ -0,0 +1,946 @@ +/* $Id: s_drawpix.c,v 1.21 2001/06/18 23:55:18 brianp Exp $ */ + +/* + * Mesa 3-D graphics library + * Version: 3.5 + * + * Copyright (C) 1999-2001 Brian Paul 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 + * BRIAN PAUL 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. + */ + + +#include "glheader.h" +#include "colormac.h" +#include "context.h" +#include "convolve.h" +#include "image.h" +#include "macros.h" +#include "mem.h" +#include "mmath.h" +#include "pixel.h" + +#include "s_context.h" +#include "s_drawpix.h" +#include "s_fog.h" +#include "s_pixeltex.h" +#include "s_span.h" +#include "s_stencil.h" +#include "s_texture.h" +#include "s_zoom.h" + + + +/* + * Given the dest position, size and skipPixels and skipRows values + * for a glDrawPixels command, perform clipping of the image bounds + * so the result lies withing the context's buffer bounds. + * Return: GL_TRUE if image is ready for drawing + * GL_FALSE if image was completely clipped away (draw nothing) + */ +GLboolean +_mesa_clip_pixelrect(const GLcontext *ctx, + GLint *destX, GLint *destY, + GLsizei *width, GLsizei *height, + GLint *skipPixels, GLint *skipRows) +{ + const GLframebuffer *buffer = ctx->DrawBuffer; + + /* left clipping */ + if (*destX < buffer->_Xmin) { + *skipPixels += (buffer->_Xmin - *destX); + *width -= (buffer->_Xmin - *destX); + *destX = buffer->_Xmin; + } + /* right clipping */ + if (*destX + *width > buffer->_Xmax) + *width -= (*destX + *width - buffer->_Xmax); + + if (*width <= 0) + return GL_FALSE; + + /* bottom clipping */ + if (*destY < buffer->_Ymin) { + *skipRows += (buffer->_Ymin - *destY); + *height -= (buffer->_Ymin - *destY); + *destY = buffer->_Ymin; + } + /* top clipping */ + if (*destY + *height > buffer->_Ymax) + *height -= (*destY + *height - buffer->_Ymax); + + if (*height <= 0) + return GL_TRUE; + + return GL_TRUE; +} + + + +/* + * Try to do a fast and simple RGB(a) glDrawPixels. + * Return: GL_TRUE if success, GL_FALSE if slow path must be used instead + */ +static GLboolean +fast_draw_pixels(GLcontext *ctx, GLint x, GLint y, + GLsizei width, GLsizei height, + GLenum format, GLenum type, const GLvoid *pixels) +{ + SWcontext *swrast = SWRAST_CONTEXT(ctx); + const struct gl_pixelstore_attrib *unpack = &ctx->Unpack; + GLchan rgb[MAX_WIDTH][3]; + GLchan rgba[MAX_WIDTH][4]; + + if (!ctx->Current.RasterPosValid) { + return GL_TRUE; /* no-op */ + } + + if ((SWRAST_CONTEXT(ctx)->_RasterMask&(~(SCISSOR_BIT|WINCLIP_BIT)))==0 + && ctx->Texture._ReallyEnabled == 0 + && unpack->Alignment == 1 + && !unpack->SwapBytes + && !unpack->LsbFirst) { + + GLint destX = x; + GLint destY = y; + GLint drawWidth = width; /* actual width drawn */ + GLint drawHeight = height; /* actual height drawn */ + GLint skipPixels = unpack->SkipPixels; + GLint skipRows = unpack->SkipRows; + GLint rowLength; + GLdepth zSpan[MAX_WIDTH]; /* only used when zooming */ + GLint zoomY0 = 0; + + if (unpack->RowLength > 0) + rowLength = unpack->RowLength; + else + rowLength = width; + + /* If we're not using pixel zoom then do all clipping calculations + * now. Otherwise, we'll let the _mesa_write_zoomed_*_span() functions + * handle the clipping. + */ + if (ctx->Pixel.ZoomX==1.0F && ctx->Pixel.ZoomY==1.0F) { + /* horizontal clipping */ + if (destX < ctx->DrawBuffer->_Xmin) { + skipPixels += (ctx->DrawBuffer->_Xmin - destX); + drawWidth -= (ctx->DrawBuffer->_Xmin - destX); + destX = ctx->DrawBuffer->_Xmin; + } + if (destX + drawWidth > ctx->DrawBuffer->_Xmax) + drawWidth -= (destX + drawWidth - ctx->DrawBuffer->_Xmax); + if (drawWidth <= 0) + return GL_TRUE; + + /* vertical clipping */ + if (destY < ctx->DrawBuffer->_Ymin) { + skipRows += (ctx->DrawBuffer->_Ymin - destY); + drawHeight -= (ctx->DrawBuffer->_Ymin - destY); + destY = ctx->DrawBuffer->_Ymin; + } + if (destY + drawHeight > ctx->DrawBuffer->_Ymax) + drawHeight -= (destY + drawHeight - ctx->DrawBuffer->_Ymax); + if (drawHeight <= 0) + return GL_TRUE; + } + else if (ctx->Pixel.ZoomX==1.0F && ctx->Pixel.ZoomY==-1.0F) { + /* upside-down image */ + /* horizontal clipping */ + if (destX < ctx->DrawBuffer->_Xmin) { + skipPixels += (ctx->DrawBuffer->_Xmin - destX); + drawWidth -= (ctx->DrawBuffer->_Xmin - destX); + destX = ctx->DrawBuffer->_Xmin; + } + if (destX + drawWidth > ctx->DrawBuffer->_Xmax) + drawWidth -= (destX + drawWidth - ctx->DrawBuffer->_Xmax); + if (drawWidth <= 0) + return GL_TRUE; + + /* vertical clipping */ + if (destY > ctx->DrawBuffer->_Ymax) { + skipRows += (destY - ctx->DrawBuffer->_Ymax); + drawHeight -= (destY - ctx->DrawBuffer->_Ymax); + destY = ctx->DrawBuffer->_Ymax; + } + if (destY - drawHeight < ctx->DrawBuffer->_Ymin) + drawHeight -= (ctx->DrawBuffer->_Ymin - (destY - drawHeight)); + if (drawHeight <= 0) + return GL_TRUE; + } + else { + /* setup array of fragment Z value to pass to zoom function */ + GLdepth z = (GLdepth) (ctx->Current.RasterPos[2] * ctx->DepthMaxF); + GLint i; + ASSERT(drawWidth < MAX_WIDTH); + for (i=0; iCurrent.RasterPos[1]); + } + + + /* + * Ready to draw! + * The window region at (destX, destY) of size (drawWidth, drawHeight) + * will be written to. + * We'll take pixel data from buffer pointed to by "pixels" but we'll + * skip "skipRows" rows and skip "skipPixels" pixels/row. + */ + + if (format == GL_RGBA && type == CHAN_TYPE + && ctx->_ImageTransferState==0) { + if (ctx->Visual.rgbMode) { + GLchan *src = (GLchan *) pixels + + (skipRows * rowLength + skipPixels) * 4; + if (ctx->Pixel.ZoomX==1.0F && ctx->Pixel.ZoomY==1.0F) { + /* no zooming */ + GLint row; + for (row=0; rowDriver.WriteRGBASpan)(ctx, drawWidth, destX, destY, + (CONST GLchan (*)[4]) src, NULL); + src += rowLength * 4; + destY++; + } + } + else if (ctx->Pixel.ZoomX==1.0F && ctx->Pixel.ZoomY==-1.0F) { + /* upside-down */ + GLint row; + for (row=0; rowDriver.WriteRGBASpan)(ctx, drawWidth, destX, destY, + (CONST GLchan (*)[4]) src, NULL); + src += rowLength * 4; + } + } + else { + /* with zooming */ + GLint row; + for (row=0; row_ImageTransferState == 0) { + if (ctx->Visual.rgbMode) { + GLchan *src = (GLchan *) pixels + + (skipRows * rowLength + skipPixels) * 3; + if (ctx->Pixel.ZoomX==1.0F && ctx->Pixel.ZoomY==1.0F) { + GLint row; + for (row=0; rowDriver.WriteRGBSpan)(ctx, drawWidth, destX, destY, + (CONST GLchan (*)[3]) src, NULL); + src += rowLength * 3; + destY++; + } + } + else if (ctx->Pixel.ZoomX==1.0F && ctx->Pixel.ZoomY==-1.0F) { + /* upside-down */ + GLint row; + for (row=0; rowDriver.WriteRGBSpan)(ctx, drawWidth, destX, destY, + (CONST GLchan (*)[3]) src, NULL); + src += rowLength * 3; + } + } + else { + /* with zooming */ + GLint row; + for (row=0; row_ImageTransferState==0) { + if (ctx->Visual.rgbMode) { + GLchan *src = (GLchan *) pixels + + (skipRows * rowLength + skipPixels); + if (ctx->Pixel.ZoomX==1.0F && ctx->Pixel.ZoomY==1.0F) { + /* no zooming */ + GLint row; + ASSERT(drawWidth < MAX_WIDTH); + for (row=0; rowDriver.WriteRGBSpan)(ctx, drawWidth, destX, destY, + (CONST GLchan (*)[3]) rgb, NULL); + src += rowLength; + destY++; + } + } + else if (ctx->Pixel.ZoomX==1.0F && ctx->Pixel.ZoomY==-1.0F) { + /* upside-down */ + GLint row; + ASSERT(drawWidth < MAX_WIDTH); + for (row=0; rowDriver.WriteRGBSpan)(ctx, drawWidth, destX, destY, + (CONST GLchan (*)[3]) rgb, NULL); + src += rowLength; + } + } + else { + /* with zooming */ + GLint row; + ASSERT(drawWidth < MAX_WIDTH); + for (row=0; row_ImageTransferState == 0) { + if (ctx->Visual.rgbMode) { + GLchan *src = (GLchan *) pixels + + (skipRows * rowLength + skipPixels)*2; + if (ctx->Pixel.ZoomX==1.0F && ctx->Pixel.ZoomY==1.0F) { + /* no zooming */ + GLint row; + ASSERT(drawWidth < MAX_WIDTH); + for (row=0; rowDriver.WriteRGBASpan)(ctx, drawWidth, destX, destY, + (CONST GLchan (*)[4]) rgba, NULL); + src += rowLength*2; + destY++; + } + } + else if (ctx->Pixel.ZoomX==1.0F && ctx->Pixel.ZoomY==-1.0F) { + /* upside-down */ + GLint row; + ASSERT(drawWidth < MAX_WIDTH); + for (row=0; rowDriver.WriteRGBASpan)(ctx, drawWidth, destX, destY, + (CONST GLchan (*)[4]) rgba, NULL); + src += rowLength*2; + } + } + else { + /* with zooming */ + GLint row; + ASSERT(drawWidth < MAX_WIDTH); + for (row=0; rowVisual.rgbMode) { + /* convert CI data to RGBA */ + if (ctx->Pixel.ZoomX==1.0F && ctx->Pixel.ZoomY==1.0F) { + /* no zooming */ + GLint row; + for (row=0; rowDriver.WriteRGBASpan)(ctx, drawWidth, destX, destY, + (const GLchan (*)[4]) rgba, + NULL); + src += rowLength; + destY++; + } + return GL_TRUE; + } + else if (ctx->Pixel.ZoomX==1.0F && ctx->Pixel.ZoomY==-1.0F) { + /* upside-down */ + GLint row; + for (row=0; rowDriver.WriteRGBASpan)(ctx, drawWidth, destX, destY, + (CONST GLchan (*)[4]) rgba, + NULL); + src += rowLength; + } + return GL_TRUE; + } + else { + /* with zooming */ + GLint row; + for (row=0; row_ImageTransferState==0) { + /* write CI data to CI frame buffer */ + GLint row; + if (ctx->Pixel.ZoomX==1.0F && ctx->Pixel.ZoomY==1.0F) { + /* no zooming */ + for (row=0; rowDriver.WriteCI8Span)(ctx, drawWidth, destX, destY, + src, NULL); + src += rowLength; + destY++; + } + return GL_TRUE; + } + else { + /* with zooming */ + return GL_FALSE; + } + } + } + else { + /* can't handle this pixel format and/or data type here */ + return GL_FALSE; + } + } + + /* can't do a simple draw, have to use slow path */ + return GL_FALSE; +} + + + +/* + * Do glDrawPixels of index pixels. + */ +static void +draw_index_pixels( GLcontext *ctx, GLint x, GLint y, + GLsizei width, GLsizei height, + GLenum type, const GLvoid *pixels ) +{ + const GLboolean zoom = ctx->Pixel.ZoomX!=1.0 || ctx->Pixel.ZoomY!=1.0; + const GLint desty = y; + GLint row, drawWidth; + GLdepth zspan[MAX_WIDTH]; + GLfloat fogSpan[MAX_WIDTH]; + + drawWidth = (width > MAX_WIDTH) ? MAX_WIDTH : width; + + /* Fragment depth values */ + if (ctx->Depth.Test || ctx->Fog.Enabled) { + GLdepth zval = (GLdepth) (ctx->Current.RasterPos[2] * ctx->DepthMaxF); + GLfloat fog; + GLint i; + + if (ctx->Fog.FogCoordinateSource == GL_FOG_COORDINATE_EXT) { + fog = ctx->Current.RasterFogCoord; + } + else { + fog = _mesa_z_to_fogfactor(ctx, ctx->Current.RasterDistance); + } + + for (i = 0; i < drawWidth; i++) { + zspan[i] = zval; + fogSpan[i] = fog; + } + } + + /* + * General solution + */ + for (row = 0; row < height; row++, y++) { + GLuint indexes[MAX_WIDTH]; + const GLvoid *source = _mesa_image_address(&ctx->Unpack, + pixels, width, height, GL_COLOR_INDEX, type, 0, row, 0); + _mesa_unpack_index_span(ctx, drawWidth, GL_UNSIGNED_INT, indexes, + type, source, &ctx->Unpack, + ctx->_ImageTransferState); + if (zoom) { + _mesa_write_zoomed_index_span(ctx, drawWidth, x, y, zspan, fogSpan, + indexes, desty); + } + else { + _mesa_write_index_span(ctx, drawWidth, x, y, zspan, fogSpan, indexes, + NULL, GL_BITMAP); + } + } +} + + + +/* + * Do glDrawPixels of stencil image. The image datatype may either + * be GLubyte or GLbitmap. + */ +static void +draw_stencil_pixels( GLcontext *ctx, GLint x, GLint y, + GLsizei width, GLsizei height, + GLenum type, const GLvoid *pixels ) +{ + const GLboolean zoom = ctx->Pixel.ZoomX!=1.0 || ctx->Pixel.ZoomY!=1.0; + const GLint desty = y; + GLint row, drawWidth; + + if (type != GL_BYTE && + type != GL_UNSIGNED_BYTE && + type != GL_SHORT && + type != GL_UNSIGNED_SHORT && + type != GL_INT && + type != GL_UNSIGNED_INT && + type != GL_FLOAT && + type != GL_BITMAP) { + _mesa_error( ctx, GL_INVALID_ENUM, "glDrawPixels(stencil type)"); + return; + } + + drawWidth = (width > MAX_WIDTH) ? MAX_WIDTH : width; + + for (row = 0; row < height; row++, y++) { + GLstencil values[MAX_WIDTH]; + GLenum destType = (sizeof(GLstencil) == sizeof(GLubyte)) + ? GL_UNSIGNED_BYTE : GL_UNSIGNED_SHORT; + const GLvoid *source = _mesa_image_address(&ctx->Unpack, + pixels, width, height, GL_COLOR_INDEX, type, 0, row, 0); + _mesa_unpack_index_span(ctx, drawWidth, destType, values, + type, source, &ctx->Unpack, + ctx->_ImageTransferState); + if (ctx->_ImageTransferState & IMAGE_SHIFT_OFFSET_BIT) { + _mesa_shift_and_offset_stencil( ctx, drawWidth, values ); + } + if (ctx->Pixel.MapStencilFlag) { + _mesa_map_stencil( ctx, drawWidth, values ); + } + + if (zoom) { + _mesa_write_zoomed_stencil_span( ctx, (GLuint) drawWidth, x, y, + values, desty ); + } + else { + _mesa_write_stencil_span( ctx, (GLuint) drawWidth, x, y, values ); + } + } +} + + + +/* + * Do a glDrawPixels of depth values. + */ +static void +draw_depth_pixels( GLcontext *ctx, GLint x, GLint y, + GLsizei width, GLsizei height, + GLenum type, const GLvoid *pixels ) +{ + const GLboolean bias_or_scale = ctx->Pixel.DepthBias!=0.0 || ctx->Pixel.DepthScale!=1.0; + const GLboolean zoom = ctx->Pixel.ZoomX!=1.0 || ctx->Pixel.ZoomY!=1.0; + const GLint desty = y; + GLchan rgba[MAX_WIDTH][4]; + GLuint ispan[MAX_WIDTH]; + GLint drawWidth = (width > MAX_WIDTH) ? MAX_WIDTH : width; + + if (type != GL_BYTE + && type != GL_UNSIGNED_BYTE + && type != GL_SHORT + && type != GL_UNSIGNED_SHORT + && type != GL_INT + && type != GL_UNSIGNED_INT + && type != GL_FLOAT) { + _mesa_error(ctx, GL_INVALID_ENUM, "glDrawPixels(type)"); + return; + } + + /* Colors or indexes */ + if (ctx->Visual.rgbMode) { + GLint i; + GLint r, g, b, a; + UNCLAMPED_FLOAT_TO_CHAN(r, ctx->Current.RasterColor[0]); + UNCLAMPED_FLOAT_TO_CHAN(g, ctx->Current.RasterColor[1]); + UNCLAMPED_FLOAT_TO_CHAN(b, ctx->Current.RasterColor[2]); + UNCLAMPED_FLOAT_TO_CHAN(a, ctx->Current.RasterColor[3]); + for (i = 0; i < drawWidth; i++) { + rgba[i][RCOMP] = r; + rgba[i][GCOMP] = g; + rgba[i][BCOMP] = b; + rgba[i][ACOMP] = a; + } + } + else { + GLint i; + for (i = 0; i < drawWidth; i++) { + ispan[i] = ctx->Current.RasterIndex; + } + } + + if (type==GL_UNSIGNED_SHORT && sizeof(GLdepth)==sizeof(GLushort) + && !bias_or_scale && !zoom && ctx->Visual.rgbMode) { + /* Special case: directly write 16-bit depth values */ + GLint row; + for (row = 0; row < height; row++, y++) { + GLdepth zspan[MAX_WIDTH]; + const GLushort *zptr = (const GLushort *) + _mesa_image_address(&ctx->Unpack, pixels, width, height, + GL_DEPTH_COMPONENT, type, 0, row, 0); + GLint i; + for (i = 0; i < width; i++) + zspan[i] = zptr[i]; + _mesa_write_rgba_span(ctx, width, x, y, zspan, 0, rgba, + NULL, GL_BITMAP); + } + } + else if (type==GL_UNSIGNED_INT && ctx->Visual.depthBits == 32 + && !bias_or_scale && !zoom && ctx->Visual.rgbMode) { + /* Special case: directly write 32-bit depth values */ + GLint row; + for (row = 0; row < height; row++, y++) { + const GLuint *zptr = (const GLuint *) + _mesa_image_address(&ctx->Unpack, pixels, width, height, + GL_DEPTH_COMPONENT, type, 0, row, 0); + _mesa_write_rgba_span(ctx, width, x, y, zptr, 0, rgba, + NULL, GL_BITMAP); + } + } + else { + /* General case */ + GLint row; + for (row = 0; row < height; row++, y++) { + GLfloat fspan[MAX_WIDTH]; + GLdepth zspan[MAX_WIDTH]; + const GLvoid *src = _mesa_image_address(&ctx->Unpack, + pixels, width, height, GL_DEPTH_COMPONENT, type, 0, row, 0); + _mesa_unpack_depth_span( ctx, drawWidth, fspan, type, src, + &ctx->Unpack ); + /* clamp depth values to [0,1] and convert from floats to integers */ + { + const GLfloat zs = ctx->DepthMaxF; + GLint i; + for (i = 0; i < drawWidth; i++) { + zspan[i] = (GLdepth) (fspan[i] * zs); + } + } + + if (ctx->Visual.rgbMode) { + if (zoom) { + _mesa_write_zoomed_rgba_span(ctx, width, x, y, zspan, 0, + (const GLchan (*)[4]) rgba, desty); + } + else { + _mesa_write_rgba_span(ctx, width, x, y, zspan, 0, + rgba, NULL, GL_BITMAP); + } + } + else { + if (zoom) { + _mesa_write_zoomed_index_span(ctx, width, x, y, zspan, 0, + ispan, GL_BITMAP); + } + else { + _mesa_write_index_span(ctx, width, x, y, zspan, 0, + ispan, NULL, GL_BITMAP); + } + } + + } + } +} + + +/* + * Do glDrawPixels of RGBA pixels. + */ +static void +draw_rgba_pixels( GLcontext *ctx, GLint x, GLint y, + GLsizei width, GLsizei height, + GLenum format, GLenum type, const GLvoid *pixels ) +{ + SWcontext *swrast = SWRAST_CONTEXT(ctx); + const struct gl_pixelstore_attrib *unpack = &ctx->Unpack; + const GLboolean zoom = ctx->Pixel.ZoomX!=1.0 || ctx->Pixel.ZoomY!=1.0; + const GLint desty = y; + GLdepth zspan[MAX_WIDTH]; + GLfloat fogSpan[MAX_WIDTH]; + GLboolean quickDraw; + GLfloat *convImage = NULL; + GLuint transferOps = ctx->_ImageTransferState; + + if (!_mesa_is_legal_format_and_type(format, type)) { + _mesa_error(ctx, GL_INVALID_ENUM, "glDrawPixels(format or type)"); + return; + } + + /* Try an optimized glDrawPixels first */ + if (fast_draw_pixels(ctx, x, y, width, height, format, type, pixels)) + return; + + /* Fragment depth values */ + if (ctx->Depth.Test || ctx->Fog.Enabled) { + /* fill in array of z values */ + GLdepth z = (GLdepth) (ctx->Current.RasterPos[2] * ctx->DepthMaxF); + GLfloat fog; + GLint i; + + if (ctx->Fog.FogCoordinateSource == GL_FOG_COORDINATE_EXT) { + fog = ctx->Current.RasterFogCoord; + } + else { + fog = _mesa_z_to_fogfactor(ctx, ctx->Current.RasterDistance); + } + + for (i=0;i_RasterMask == 0 && !zoom && x >= 0 && y >= 0 + && x + width <= ctx->DrawBuffer->Width + && y + height <= ctx->DrawBuffer->Height) { + quickDraw = GL_TRUE; + } + else { + quickDraw = GL_FALSE; + } + + if (ctx->Pixel.Convolution2DEnabled || ctx->Pixel.Separable2DEnabled) { + /* Convolution has to be handled specially. We'll create an + * intermediate image, applying all pixel transfer operations + * up to convolution. Then we'll convolve the image. Then + * we'll proceed with the rest of the transfer operations and + * rasterize the image. + */ + GLint row; + GLfloat *dest, *tmpImage; + + tmpImage = (GLfloat *) MALLOC(width * height * 4 * sizeof(GLfloat)); + if (!tmpImage) { + _mesa_error(ctx, GL_OUT_OF_MEMORY, "glDrawPixels"); + return; + } + convImage = (GLfloat *) MALLOC(width * height * 4 * sizeof(GLfloat)); + if (!convImage) { + FREE(tmpImage); + _mesa_error(ctx, GL_OUT_OF_MEMORY, "glDrawPixels"); + return; + } + + /* Unpack the image and apply transfer ops up to convolution */ + dest = tmpImage; + for (row = 0; row < height; row++) { + const GLvoid *source = _mesa_image_address(unpack, + pixels, width, height, format, type, 0, row, 0); + _mesa_unpack_float_color_span(ctx, width, GL_RGBA, (GLfloat *) dest, + format, type, source, unpack, + transferOps & IMAGE_PRE_CONVOLUTION_BITS, + GL_FALSE); + dest += width * 4; + } + + /* do convolution */ + if (ctx->Pixel.Convolution2DEnabled) { + _mesa_convolve_2d_image(ctx, &width, &height, tmpImage, convImage); + } + else { + ASSERT(ctx->Pixel.Separable2DEnabled); + _mesa_convolve_sep_image(ctx, &width, &height, tmpImage, convImage); + } + FREE(tmpImage); + + /* continue transfer ops and draw the convolved image */ + unpack = &_mesa_native_packing; + pixels = convImage; + format = GL_RGBA; + type = GL_FLOAT; + transferOps &= IMAGE_POST_CONVOLUTION_BITS; + } + + /* + * General solution + */ + { + GLchan rgba[MAX_WIDTH][4]; + GLint row; + if (width > MAX_WIDTH) + width = MAX_WIDTH; + for (row = 0; row < height; row++, y++) { + const GLvoid *source = _mesa_image_address(unpack, + pixels, width, height, format, type, 0, row, 0); + _mesa_unpack_chan_color_span(ctx, width, GL_RGBA, (GLchan *) rgba, + format, type, source, unpack, + transferOps); + if ((ctx->Pixel.MinMaxEnabled && ctx->MinMax.Sink) || + (ctx->Pixel.HistogramEnabled && ctx->Histogram.Sink)) + continue; + + if (ctx->Texture._ReallyEnabled && ctx->Pixel.PixelTextureEnabled) { + GLchan primary_rgba[MAX_WIDTH][4]; + GLuint unit; + DEFARRAY(GLfloat, s, MAX_WIDTH); /* mac 32k limitation */ + DEFARRAY(GLfloat, t, MAX_WIDTH); + DEFARRAY(GLfloat, r, MAX_WIDTH); + DEFARRAY(GLfloat, q, MAX_WIDTH); + CHECKARRAY(s, return); /* mac 32k limitation */ + CHECKARRAY(t, return); + CHECKARRAY(r, return); + CHECKARRAY(q, return); + + /* XXX not sure how multitexture is supposed to work here */ + MEMCPY(primary_rgba, rgba, 4 * width * sizeof(GLchan)); + + for (unit = 0; unit < ctx->Const.MaxTextureUnits; unit++) { + if (ctx->Texture.Unit[unit]._ReallyEnabled) { + _mesa_pixeltexgen(ctx, width, (const GLchan (*)[4]) rgba, + s, t, r, q); + _swrast_texture_fragments(ctx, unit, width, s, t, r, NULL, + (CONST GLchan (*)[4]) primary_rgba, + rgba); + } + } + UNDEFARRAY(s); /* mac 32k limitation */ + UNDEFARRAY(t); + UNDEFARRAY(r); + UNDEFARRAY(q); + } + + if (quickDraw) { + (*swrast->Driver.WriteRGBASpan)(ctx, width, x, y, + (CONST GLchan (*)[4]) rgba, NULL); + } + else if (zoom) { + _mesa_write_zoomed_rgba_span(ctx, width, x, y, zspan, fogSpan, + (CONST GLchan (*)[4]) rgba, desty); + } + else { + _mesa_write_rgba_span(ctx, (GLuint) width, x, y, zspan, fogSpan, + rgba, NULL, GL_BITMAP); + } + } + } + + if (convImage) { + FREE(convImage); + } +} + + + +/* + * Execute glDrawPixels + */ +void +_swrast_DrawPixels( GLcontext *ctx, + GLint x, GLint y, + GLsizei width, GLsizei height, + GLenum format, GLenum type, + const struct gl_pixelstore_attrib *unpack, + const GLvoid *pixels ) +{ + SWcontext *swrast = SWRAST_CONTEXT(ctx); + (void) unpack; + + + if (swrast->NewState) + _swrast_validate_derived( ctx ); + + RENDER_START(swrast,ctx); + + switch (format) { + case GL_STENCIL_INDEX: + draw_stencil_pixels( ctx, x, y, width, height, type, pixels ); + break; + case GL_DEPTH_COMPONENT: + draw_depth_pixels( ctx, x, y, width, height, type, pixels ); + break; + case GL_COLOR_INDEX: + if (ctx->Visual.rgbMode) + draw_rgba_pixels(ctx, x,y, width, height, format, type, pixels); + else + draw_index_pixels(ctx, x, y, width, height, type, pixels); + break; + case GL_RED: + case GL_GREEN: + case GL_BLUE: + case GL_ALPHA: + case GL_LUMINANCE: + case GL_LUMINANCE_ALPHA: + case GL_RGB: + case GL_BGR: + case GL_RGBA: + case GL_BGRA: + case GL_ABGR_EXT: + draw_rgba_pixels(ctx, x, y, width, height, format, type, pixels); + break; + default: + _mesa_error( ctx, GL_INVALID_ENUM, "glDrawPixels(format)" ); + } + + RENDER_FINISH(swrast,ctx); +} Index: dll/opengl/opengl32/mesa/swrast/s_drawpix.h =================================================================== --- dll/opengl/opengl32/mesa/swrast/s_drawpix.h (revision 0) +++ dll/opengl/opengl32/mesa/swrast/s_drawpix.h (working copy) @@ -0,0 +1,42 @@ +/* $Id: s_drawpix.h,v 1.3 2001/03/12 00:48:42 gareth Exp $ */ + +/* + * Mesa 3-D graphics library + * Version: 3.5 + * + * Copyright (C) 1999-2001 Brian Paul 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 + * BRIAN PAUL 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. + */ + + +#ifndef S_DRAWPIXELS_H +#define S_DRAWPIXELS_H + + +#include "mtypes.h" +#include "swrast.h" + + +extern GLboolean +_mesa_clip_pixelrect(const GLcontext *ctx, + GLint *destX, GLint *destY, + GLsizei *width, GLsizei *height, + GLint *skipPixels, GLint *skipRows); + +#endif Index: dll/opengl/opengl32/mesa/swrast/s_feedback.c =================================================================== --- dll/opengl/opengl32/mesa/swrast/s_feedback.c (revision 0) +++ dll/opengl/opengl32/mesa/swrast/s_feedback.c (working copy) @@ -0,0 +1,167 @@ +/* $Id: s_feedback.c,v 1.8 2001/06/12 22:06:53 brianp Exp $ */ + +/* + * Mesa 3-D graphics library + * Version: 3.5 + * + * Copyright (C) 1999-2001 Brian Paul 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 + * BRIAN PAUL 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. + */ + +#include "glheader.h" +#include "colormac.h" +#include "context.h" +#include "enums.h" +#include "feedback.h" +#include "macros.h" +#include "mmath.h" + +#include "s_context.h" +#include "s_feedback.h" +#include "s_triangle.h" + + +#define FB_3D 0x01 +#define FB_4D 0x02 +#define FB_INDEX 0x04 +#define FB_COLOR 0x08 +#define FB_TEXTURE 0X10 + + + + +static void feedback_vertex( GLcontext *ctx, + const SWvertex *v, const SWvertex *pv ) +{ + const GLuint texUnit = 0; /* See section 5.3 of 1.2.1 spec */ + GLfloat win[4]; + GLfloat color[4]; + GLfloat tc[4]; + GLuint index; + + win[0] = v->win[0]; + win[1] = v->win[1]; + win[2] = v->win[2] / ctx->DepthMaxF; + win[3] = 1.0 / v->win[3]; + + color[0] = CHAN_TO_FLOAT(pv->color[0]); + color[1] = CHAN_TO_FLOAT(pv->color[1]); + color[2] = CHAN_TO_FLOAT(pv->color[2]); + color[3] = CHAN_TO_FLOAT(pv->color[3]); + + if (v->texcoord[texUnit][3] != 1.0 && + v->texcoord[texUnit][3] != 0.0) { + GLfloat invq = 1.0F / v->texcoord[texUnit][3]; + tc[0] = v->texcoord[texUnit][0] * invq; + tc[1] = v->texcoord[texUnit][1] * invq; + tc[2] = v->texcoord[texUnit][2] * invq; + tc[3] = v->texcoord[texUnit][3]; + } + else { + COPY_4V(tc, v->texcoord[texUnit]); + } + + index = v->index; + + _mesa_feedback_vertex( ctx, win, color, index, tc ); +} + + +/* + * Put triangle in feedback buffer. + */ +void _mesa_feedback_triangle( GLcontext *ctx, + const SWvertex *v0, + const SWvertex *v1, + const SWvertex *v2) +{ + if (_mesa_cull_triangle( ctx, v0, v1, v2 )) { + FEEDBACK_TOKEN( ctx, (GLfloat) (GLint) GL_POLYGON_TOKEN ); + FEEDBACK_TOKEN( ctx, (GLfloat) 3 ); /* three vertices */ + + if (ctx->Light.ShadeModel == GL_SMOOTH) { + feedback_vertex( ctx, v0, v0 ); + feedback_vertex( ctx, v1, v1 ); + feedback_vertex( ctx, v2, v2 ); + } else { + feedback_vertex( ctx, v0, v2 ); + feedback_vertex( ctx, v1, v2 ); + feedback_vertex( ctx, v2, v2 ); + } + } +} + + +void _mesa_feedback_line( GLcontext *ctx, const SWvertex *v0, const SWvertex *v1 ) +{ + GLenum token = GL_LINE_TOKEN; + SWcontext *swrast = SWRAST_CONTEXT(ctx); + + if (swrast->StippleCounter==0) + token = GL_LINE_RESET_TOKEN; + + FEEDBACK_TOKEN( ctx, (GLfloat) (GLint) token ); + + if (ctx->Light.ShadeModel == GL_SMOOTH) { + feedback_vertex( ctx, v0, v0 ); + feedback_vertex( ctx, v1, v1 ); + } else { + feedback_vertex( ctx, v0, v1 ); + feedback_vertex( ctx, v1, v1 ); + } + + swrast->StippleCounter++; +} + + +void _mesa_feedback_point( GLcontext *ctx, const SWvertex *v ) +{ + FEEDBACK_TOKEN( ctx, (GLfloat) (GLint) GL_POINT_TOKEN ); + feedback_vertex( ctx, v, v ); +} + + +void _mesa_select_triangle( GLcontext *ctx, + const SWvertex *v0, + const SWvertex *v1, + const SWvertex *v2) +{ + if (_mesa_cull_triangle( ctx, v0, v1, v2 )) { + const GLfloat zs = 1.0F / ctx->DepthMaxF; + + _mesa_update_hitflag( ctx, v0->win[2] * zs ); + _mesa_update_hitflag( ctx, v1->win[2] * zs ); + _mesa_update_hitflag( ctx, v2->win[2] * zs ); + } +} + + +void _mesa_select_line( GLcontext *ctx, const SWvertex *v0, const SWvertex *v1 ) +{ + const GLfloat zs = 1.0F / ctx->DepthMaxF; + _mesa_update_hitflag( ctx, v0->win[2] * zs ); + _mesa_update_hitflag( ctx, v1->win[2] * zs ); +} + + +void _mesa_select_point( GLcontext *ctx, const SWvertex *v ) +{ + const GLfloat zs = 1.0F / ctx->DepthMaxF; + _mesa_update_hitflag( ctx, v->win[2] * zs ); +} Index: dll/opengl/opengl32/mesa/swrast/s_feedback.h =================================================================== --- dll/opengl/opengl32/mesa/swrast/s_feedback.h (revision 0) +++ dll/opengl/opengl32/mesa/swrast/s_feedback.h (working copy) @@ -0,0 +1,52 @@ +/* $Id: s_feedback.h,v 1.5 2001/03/12 00:48:42 gareth Exp $ */ + +/* + * Mesa 3-D graphics library + * Version: 3.5 + * + * Copyright (C) 1999-2001 Brian Paul 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 + * BRIAN PAUL 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. + */ + + +#ifndef S_FEEDBACK_H +#define S_FEEDBACK_H + + +#include "mtypes.h" +#include "swrast.h" + + +extern void _mesa_feedback_point( GLcontext *ctx, const SWvertex *v ); + +extern void _mesa_feedback_line( GLcontext *ctx, + const SWvertex *v1, const SWvertex *v2 ); + +extern void _mesa_feedback_triangle( GLcontext *ctx, const SWvertex *v0, + const SWvertex *v1, const SWvertex *v2 ); + +extern void _mesa_select_point( GLcontext *ctx, const SWvertex *v ); + +extern void _mesa_select_line( GLcontext *ctx, + const SWvertex *v1, const SWvertex *v2 ); + +extern void _mesa_select_triangle( GLcontext *ctx, const SWvertex *v0, + const SWvertex *v1, const SWvertex *v2 ); + +#endif Index: dll/opengl/opengl32/mesa/swrast/s_fog.c =================================================================== --- dll/opengl/opengl32/mesa/swrast/s_fog.c (revision 0) +++ dll/opengl/opengl32/mesa/swrast/s_fog.c (working copy) @@ -0,0 +1,299 @@ +/* $Id: s_fog.c,v 1.13 2001/06/18 23:55:18 brianp Exp $ */ + +/* + * Mesa 3-D graphics library + * Version: 3.5 + * + * Copyright (C) 1999-2001 Brian Paul 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 + * BRIAN PAUL 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. + */ + + +#include "glheader.h" +#include "colormac.h" +#include "context.h" +#include "macros.h" +#include "mmath.h" + +#include "s_context.h" +#include "s_fog.h" +#include "s_pb.h" + + + + +/* + * Used to convert current raster distance to a fog factor in [0,1]. + */ +GLfloat +_mesa_z_to_fogfactor(GLcontext *ctx, GLfloat z) +{ + GLfloat d, f; + + switch (ctx->Fog.Mode) { + case GL_LINEAR: + if (ctx->Fog.Start == ctx->Fog.End) + d = 1.0F; + else + d = 1.0F / (ctx->Fog.End - ctx->Fog.Start); + f = (ctx->Fog.End - z) * d; + return CLAMP(f, 0.0F, 1.0F); + case GL_EXP: + d = ctx->Fog.Density; + f = exp(-d * z); + return f; + case GL_EXP2: + d = ctx->Fog.Density; + f = exp(-(d * d * z * z)); + return f; + default: + _mesa_problem(ctx, "Bad fog mode in make_fog_coord"); + return 0.0; + } +} + + + +/* + * Apply fog to an array of RGBA pixels. + * Input: n - number of pixels + * fog - array of fog factors in [0,1] + * red, green, blue, alpha - pixel colors + * Output: red, green, blue, alpha - fogged pixel colors + */ +void +_mesa_fog_rgba_pixels( const GLcontext *ctx, + GLuint n, + const GLfloat fog[], + GLchan rgba[][4] ) +{ + GLuint i; + GLchan rFog, gFog, bFog; + + UNCLAMPED_FLOAT_TO_CHAN(rFog, ctx->Fog.Color[RCOMP]); + UNCLAMPED_FLOAT_TO_CHAN(gFog, ctx->Fog.Color[GCOMP]); + UNCLAMPED_FLOAT_TO_CHAN(bFog, ctx->Fog.Color[BCOMP]); + + for (i = 0; i < n; i++) { + const GLfloat f = fog[i]; + const GLfloat g = 1.0 - f; + rgba[i][RCOMP] = f * rgba[i][RCOMP] + g * rFog; + rgba[i][GCOMP] = f * rgba[i][GCOMP] + g * gFog; + rgba[i][BCOMP] = f * rgba[i][BCOMP] + g * bFog; + } +} + + + +/* + * Apply fog to an array of color index pixels. + * Input: n - number of pixels + * fog - array of fog factors in [0,1] + * index - pixel color indexes + * Output: index - fogged pixel color indexes + */ +void +_mesa_fog_ci_pixels( const GLcontext *ctx, + GLuint n, const GLfloat fog[], GLuint index[] ) +{ + GLuint idx = (GLuint) ctx->Fog.Index; + GLuint i; + + for (i = 0; i < n; i++) { + const GLfloat f = CLAMP(fog[i], 0.0, 1.0); + index[i] = (GLuint) ((GLfloat) index[i] + (1.0F - f) * idx); + } +} + + + +/* + * Calculate fog factors (in [0,1]) from window z values + * Input: n - number of pixels + * z - array of integer depth values + * red, green, blue, alpha - pixel colors + * Output: red, green, blue, alpha - fogged pixel colors + * + * Use lookup table & interpolation? + */ +static void +compute_fog_factors_from_z( const GLcontext *ctx, + GLuint n, + const GLdepth z[], + GLfloat fogFact[] ) +{ + const GLboolean ortho = (ctx->ProjectionMatrix.m[15] != 0.0F); + const GLfloat p10 = ctx->ProjectionMatrix.m[10]; + const GLfloat p14 = ctx->ProjectionMatrix.m[14]; + const GLfloat tz = ctx->Viewport._WindowMap.m[MAT_TZ]; + GLfloat szInv; + GLuint i; + + if (ctx->Viewport._WindowMap.m[MAT_SZ] == 0.0) + szInv = 1.0F; + else + szInv = 1.0F / ctx->Viewport._WindowMap.m[MAT_SZ]; + + /* + * Note: to compute eyeZ from the ndcZ we have to solve the following: + * + * p[10] * eyeZ + p[14] * eyeW + * ndcZ = --------------------------- + * p[11] * eyeZ + p[15] * eyeW + * + * Thus: + * + * p[14] * eyeW - p[15] * eyeW * ndcZ + * eyeZ = ---------------------------------- + * p[11] * ndcZ - p[10] + * + * If we note: + * a) if using an orthographic projection, p[11] = 0 and p[15] = 1. + * b) if using a perspective projection, p[11] = -1 and p[15] = 0. + * c) we assume eyeW = 1 (not always true- glVertex4) + * + * Then we can simplify the calculation of eyeZ quite a bit. We do + * separate calculations for the orthographic and perspective cases below. + * Note that we drop a negative sign or two since they don't matter. + */ + + switch (ctx->Fog.Mode) { + case GL_LINEAR: + { + GLfloat fogEnd = ctx->Fog.End; + GLfloat fogScale; + if (ctx->Fog.Start == ctx->Fog.End) + fogScale = 1.0; + else + fogScale = 1.0F / (ctx->Fog.End - ctx->Fog.Start); + if (ortho) { + for (i=0;iFog.Density * eyez ); + } + } + else { + /* perspective */ + for (i=0;iFog.Density * eyez ); + } + } + break; + case GL_EXP2: + { + GLfloat negDensitySquared = -ctx->Fog.Density * ctx->Fog.Density; + if (ortho) { + for (i=0;iMinMax.Min[RCOMP]) + ctx->MinMax.Min[RCOMP] = rgba[i][RCOMP]; + if (rgba[i][GCOMP] < ctx->MinMax.Min[GCOMP]) + ctx->MinMax.Min[GCOMP] = rgba[i][GCOMP]; + if (rgba[i][BCOMP] < ctx->MinMax.Min[BCOMP]) + ctx->MinMax.Min[BCOMP] = rgba[i][BCOMP]; + if (rgba[i][ACOMP] < ctx->MinMax.Min[ACOMP]) + ctx->MinMax.Min[ACOMP] = rgba[i][ACOMP]; + + /* update maxs */ + if (rgba[i][RCOMP] > ctx->MinMax.Max[RCOMP]) + ctx->MinMax.Max[RCOMP] = rgba[i][RCOMP]; + if (rgba[i][GCOMP] > ctx->MinMax.Max[GCOMP]) + ctx->MinMax.Max[GCOMP] = rgba[i][GCOMP]; + if (rgba[i][BCOMP] > ctx->MinMax.Max[BCOMP]) + ctx->MinMax.Max[BCOMP] = rgba[i][BCOMP]; + if (rgba[i][ACOMP] > ctx->MinMax.Max[ACOMP]) + ctx->MinMax.Max[ACOMP] = rgba[i][ACOMP]; + } +} + + +/* + * Update the histogram values from an array of fragment colors. + */ +void +_mesa_update_histogram(GLcontext *ctx, GLuint n, const GLfloat rgba[][4]) +{ + const GLint max = ctx->Histogram.Width - 1; + GLfloat w = (GLfloat) max; + GLuint i; + + if (ctx->Histogram.Width == 0) + return; + + for (i = 0; i < n; i++) { + GLint ri = IROUND(rgba[i][RCOMP] * w); + GLint gi = IROUND(rgba[i][GCOMP] * w); + GLint bi = IROUND(rgba[i][BCOMP] * w); + GLint ai = IROUND(rgba[i][ACOMP] * w); + ri = CLAMP(ri, 0, max); + gi = CLAMP(gi, 0, max); + bi = CLAMP(bi, 0, max); + ai = CLAMP(ai, 0, max); + ctx->Histogram.Count[ri][RCOMP]++; + ctx->Histogram.Count[gi][GCOMP]++; + ctx->Histogram.Count[bi][BCOMP]++; + ctx->Histogram.Count[ai][ACOMP]++; + } +} Index: dll/opengl/opengl32/mesa/swrast/s_histogram.h =================================================================== --- dll/opengl/opengl32/mesa/swrast/s_histogram.h (revision 0) +++ dll/opengl/opengl32/mesa/swrast/s_histogram.h (working copy) @@ -0,0 +1,41 @@ +/* $Id: s_histogram.h,v 1.3 2001/03/12 00:48:42 gareth Exp $ */ + +/* + * Mesa 3-D graphics library + * Version: 3.5 + * + * Copyright (C) 1999-2001 Brian Paul 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 + * BRIAN PAUL 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. + */ + + +#ifndef S_HISTOGRAM_H +#define S_HISTOGRAM_H + +#include "mtypes.h" +#include "swrast.h" + +extern void +_mesa_update_minmax(GLcontext *ctx, GLuint n, const GLfloat rgba[][4]); + +extern void +_mesa_update_histogram(GLcontext *ctx, GLuint n, const GLfloat rgba[][4]); + + +#endif Index: dll/opengl/opengl32/mesa/swrast/s_imaging.c =================================================================== --- dll/opengl/opengl32/mesa/swrast/s_imaging.c (revision 0) +++ dll/opengl/opengl32/mesa/swrast/s_imaging.c (working copy) @@ -0,0 +1,150 @@ +/* $Id: s_imaging.c,v 1.4 2001/03/19 02:28:59 keithw Exp $ */ + +/* + * Mesa 3-D graphics library + * Version: 3.5 + * + * Copyright (C) 1999-2001 Brian Paul 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 + * BRIAN PAUL 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. + */ + +/* KW: Moved these here to remove knowledge of swrast from core mesa. + * Should probably pull the entire software implementation of these + * extensions into either swrast or a sister module. + */ + +#include "s_context.h" +#include "s_span.h" + +void +_swrast_CopyColorTable( GLcontext *ctx, + GLenum target, GLenum internalformat, + GLint x, GLint y, GLsizei width) +{ + SWcontext *swrast = SWRAST_CONTEXT(ctx); + GLchan data[MAX_WIDTH][4]; + + /* Select buffer to read from */ + (*swrast->Driver.SetReadBuffer)( ctx, ctx->ReadBuffer, + ctx->Pixel.DriverReadBuffer ); + + if (width > MAX_WIDTH) + width = MAX_WIDTH; + + /* read the data from framebuffer */ + _mesa_read_rgba_span( ctx, ctx->ReadBuffer, width, x, y, data ); + + /* Restore reading from draw buffer (the default) */ + (*swrast->Driver.SetReadBuffer)( ctx, ctx->DrawBuffer, + ctx->Color.DriverDrawBuffer ); + + glColorTable(target, internalformat, width, GL_RGBA, GL_UNSIGNED_BYTE, data); +} + +void +_swrast_CopyColorSubTable( GLcontext *ctx,GLenum target, GLsizei start, + GLint x, GLint y, GLsizei width) +{ + SWcontext *swrast = SWRAST_CONTEXT(ctx); + GLchan data[MAX_WIDTH][4]; + + /* Select buffer to read from */ + (*swrast->Driver.SetReadBuffer)( ctx, ctx->ReadBuffer, + ctx->Pixel.DriverReadBuffer ); + + if (width > MAX_WIDTH) + width = MAX_WIDTH; + + /* read the data from framebuffer */ + _mesa_read_rgba_span( ctx, ctx->ReadBuffer, width, x, y, data ); + + /* Restore reading from draw buffer (the default) */ + (*swrast->Driver.SetReadBuffer)( ctx, ctx->DrawBuffer, + ctx->Color.DriverDrawBuffer ); + + glColorSubTable(target, start, width, GL_RGBA, GL_UNSIGNED_BYTE, data); +} + + +void +_swrast_CopyConvolutionFilter1D(GLcontext *ctx, GLenum target, + GLenum internalFormat, + GLint x, GLint y, GLsizei width) +{ + SWcontext *swrast = SWRAST_CONTEXT(ctx); + GLchan rgba[MAX_CONVOLUTION_WIDTH][4]; + + RENDER_START( swrast, ctx ); + + /* read the data from framebuffer */ + _mesa_read_rgba_span( ctx, ctx->ReadBuffer, width, x, y, + (GLchan (*)[4]) rgba ); + + RENDER_FINISH( swrast, ctx ); + + /* store as convolution filter */ + glConvolutionFilter1D(target, internalFormat, width, + GL_RGBA, CHAN_TYPE, rgba); +} + + +void +_swrast_CopyConvolutionFilter2D(GLcontext *ctx, GLenum target, + GLenum internalFormat, + GLint x, GLint y, GLsizei width, GLsizei height) +{ + SWcontext *swrast = SWRAST_CONTEXT(ctx); + struct gl_pixelstore_attrib packSave; + GLchan rgba[MAX_CONVOLUTION_HEIGHT][MAX_CONVOLUTION_WIDTH][4]; + GLint i; + + RENDER_START(swrast,ctx); + + /* read pixels from framebuffer */ + for (i = 0; i < height; i++) { + _mesa_read_rgba_span( ctx, ctx->ReadBuffer, width, x, y + i, + (GLchan (*)[4]) rgba[i] ); + } + + RENDER_FINISH(swrast,ctx); + + /* + * HACK: save & restore context state so we can store this as a + * convolution filter via the GL api. Doesn't call any callbacks + * hanging off ctx->Unpack statechanges. + */ + + packSave = ctx->Unpack; /* save pixel packing params */ + + ctx->Unpack.Alignment = 1; + ctx->Unpack.RowLength = MAX_CONVOLUTION_WIDTH; + ctx->Unpack.SkipPixels = 0; + ctx->Unpack.SkipRows = 0; + ctx->Unpack.ImageHeight = 0; + ctx->Unpack.SkipImages = 0; + ctx->Unpack.SwapBytes = GL_FALSE; + ctx->Unpack.LsbFirst = GL_FALSE; + ctx->NewState |= _NEW_PACKUNPACK; + + glConvolutionFilter2D(target, internalFormat, width, height, + GL_RGBA, CHAN_TYPE, rgba); + + ctx->Unpack = packSave; /* restore pixel packing params */ + ctx->NewState |= _NEW_PACKUNPACK; +} Index: dll/opengl/opengl32/mesa/swrast/s_lines.c =================================================================== --- dll/opengl/opengl32/mesa/swrast/s_lines.c (revision 0) +++ dll/opengl/opengl32/mesa/swrast/s_lines.c (working copy) @@ -0,0 +1,1097 @@ +/* $Id: s_lines.c,v 1.19 2001/06/11 19:44:01 brianp Exp $ */ + +/* + * Mesa 3-D graphics library + * Version: 3.5 + * + * Copyright (C) 1999-2001 Brian Paul 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 + * BRIAN PAUL 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. + */ + + +#include "glheader.h" +#include "colormac.h" +#include "macros.h" +#include "mmath.h" +#include "s_aaline.h" +#include "s_pb.h" +#include "s_context.h" +#include "s_depth.h" +#include "s_lines.h" +#include "s_feedback.h" + + + +/**********************************************************************/ +/***** Rasterization *****/ +/**********************************************************************/ + + +/* + * There are 4 pairs (RGBA, CI) of line drawing functions: + * 1. simple: width=1 and no special rasterization functions (fastest) + * 2. flat: width=1, non-stippled, flat-shaded, any raster operations + * 3. smooth: width=1, non-stippled, smooth-shaded, any raster operations + * 4. general: any other kind of line (slowest) + */ + + +/* Flat, color index line */ +static void flat_ci_line( GLcontext *ctx, + const SWvertex *vert0, + const SWvertex *vert1 ) +{ + struct pixel_buffer *PB = SWRAST_CONTEXT(ctx)->PB; + + PB_SET_INDEX( PB, vert0->index ); + +#define INTERP_XY 1 +#define PLOT(X,Y) PB_WRITE_PIXEL(PB, X, Y, 0, 0); + +#include "s_linetemp.h" + + _mesa_flush_pb(ctx); +} + + + +/* Flat, color index line with Z interpolation/testing */ +static void flat_ci_z_line( GLcontext *ctx, + const SWvertex *vert0, + const SWvertex *vert1 ) +{ + struct pixel_buffer *PB = SWRAST_CONTEXT(ctx)->PB; + PB_SET_INDEX( PB, vert0->index ); + +#define INTERP_XY 1 +#define INTERP_Z 1 +#define INTERP_FOG 1 +#define PLOT(X,Y) PB_WRITE_PIXEL(PB, X, Y, Z, fog0); + +#include "s_linetemp.h" + + _mesa_flush_pb(ctx); +} + + + +/* Flat-shaded, RGBA line */ +static void flat_rgba_line( GLcontext *ctx, + const SWvertex *vert0, + const SWvertex *vert1 ) +{ + const GLchan *color = vert1->color; + struct pixel_buffer *PB = SWRAST_CONTEXT(ctx)->PB; + PB_SET_COLOR( PB, color[0], color[1], color[2], color[3] ); + +#define INTERP_XY 1 +#define PLOT(X,Y) PB_WRITE_PIXEL(PB, X, Y, 0, 0); + +#include "s_linetemp.h" + + _mesa_flush_pb(ctx); +} + + + +/* Flat-shaded, RGBA line with Z interpolation/testing */ +static void flat_rgba_z_line( GLcontext *ctx, + const SWvertex *vert0, + const SWvertex *vert1 ) +{ + const GLchan *color = vert1->color; + struct pixel_buffer *PB = SWRAST_CONTEXT(ctx)->PB; + PB_SET_COLOR( PB, color[0], color[1], color[2], color[3] ); + +#define INTERP_XY 1 +#define INTERP_Z 1 +#define INTERP_FOG 1 +#define PLOT(X,Y) PB_WRITE_PIXEL(PB, X, Y, Z, fog0); + +#include "s_linetemp.h" + + _mesa_flush_pb(ctx); +} + + + +/* Smooth shaded, color index line */ +static void smooth_ci_line( GLcontext *ctx, + const SWvertex *vert0, + const SWvertex *vert1 ) +{ + struct pixel_buffer *PB = SWRAST_CONTEXT(ctx)->PB; + GLint count = PB->count; + GLint *pbx = PB->x; + GLint *pby = PB->y; + GLuint *pbi = PB->index; + + PB->mono = GL_FALSE; + +#define INTERP_XY 1 +#define INTERP_INDEX 1 + +#define PLOT(X,Y) \ + pbx[count] = X; \ + pby[count] = Y; \ + pbi[count] = I; \ + count++; + +#include "s_linetemp.h" + + PB->count = count; + _mesa_flush_pb(ctx); +} + + + +/* Smooth shaded, color index line with Z interpolation/testing */ +static void smooth_ci_z_line( GLcontext *ctx, + const SWvertex *vert0, + const SWvertex *vert1 ) +{ + struct pixel_buffer *PB = SWRAST_CONTEXT(ctx)->PB; + GLint count = PB->count; + GLint *pbx = PB->x; + GLint *pby = PB->y; + GLdepth *pbz = PB->z; + GLuint *pbi = PB->index; + + PB->mono = GL_FALSE; + +#define INTERP_XY 1 +#define INTERP_Z 1 +#define INTERP_FOG 1 +#define INTERP_INDEX 1 + +#define PLOT(X,Y) \ + pbx[count] = X; \ + pby[count] = Y; \ + pbz[count] = Z; \ + pbi[count] = I; \ + count++; + +#include "s_linetemp.h" + + PB->count = count; + _mesa_flush_pb(ctx); +} + + + +/* Smooth-shaded, RGBA line */ +static void smooth_rgba_line( GLcontext *ctx, + const SWvertex *vert0, + const SWvertex *vert1 ) +{ + struct pixel_buffer *PB = SWRAST_CONTEXT(ctx)->PB; + GLint count = PB->count; + GLint *pbx = PB->x; + GLint *pby = PB->y; + GLchan (*pbrgba)[4] = PB->rgba; + + PB->mono = GL_FALSE; + +#define INTERP_XY 1 +#define INTERP_RGB 1 +#define INTERP_ALPHA 1 + +#define PLOT(X,Y) \ + pbx[count] = X; \ + pby[count] = Y; \ + pbrgba[count][RCOMP] = FixedToInt(r0); \ + pbrgba[count][GCOMP] = FixedToInt(g0); \ + pbrgba[count][BCOMP] = FixedToInt(b0); \ + pbrgba[count][ACOMP] = FixedToInt(a0); \ + count++; + +#include "s_linetemp.h" + + PB->count = count; + _mesa_flush_pb(ctx); +} + + + +/* Smooth-shaded, RGBA line with Z interpolation/testing */ +static void smooth_rgba_z_line( GLcontext *ctx, + const SWvertex *vert0, + const SWvertex *vert1 ) +{ + struct pixel_buffer *PB = SWRAST_CONTEXT(ctx)->PB; + GLint count = PB->count; + GLint *pbx = PB->x; + GLint *pby = PB->y; + GLdepth *pbz = PB->z; + GLfloat *pbfog = PB->fog; + GLchan (*pbrgba)[4] = PB->rgba; + + + PB->mono = GL_FALSE; + +#define INTERP_XY 1 +#define INTERP_Z 1 +#define INTERP_FOG 1 +#define INTERP_RGB 1 +#define INTERP_ALPHA 1 + +#define PLOT(X,Y) \ + pbx[count] = X; \ + pby[count] = Y; \ + pbz[count] = Z; \ + pbfog[count] = fog0; \ + pbrgba[count][RCOMP] = FixedToInt(r0); \ + pbrgba[count][GCOMP] = FixedToInt(g0); \ + pbrgba[count][BCOMP] = FixedToInt(b0); \ + pbrgba[count][ACOMP] = FixedToInt(a0); \ + count++; + +#include "s_linetemp.h" + + PB->count = count; + _mesa_flush_pb(ctx); +} + + +#define CHECK_FULL(count) \ + if (count >= PB_SIZE-MAX_WIDTH) { \ + PB->count = count; \ + _mesa_flush_pb(ctx); \ + count = PB->count; \ + } + + + +/* Smooth shaded, color index, any width, maybe stippled */ +static void general_smooth_ci_line( GLcontext *ctx, + const SWvertex *vert0, + const SWvertex *vert1 ) +{ + struct pixel_buffer *PB = SWRAST_CONTEXT(ctx)->PB; + GLint count = PB->count; + GLint *pbx = PB->x; + GLint *pby = PB->y; + GLdepth *pbz = PB->z; + GLfloat *pbfog = PB->fog; + GLuint *pbi = PB->index; + + PB->mono = GL_FALSE; + + if (ctx->Line.StippleFlag) { + /* stippled */ +#define INTERP_XY 1 +#define INTERP_Z 1 +#define INTERP_FOG 1 +#define INTERP_INDEX 1 +#define WIDE 1 +#define STIPPLE 1 +#define PLOT(X,Y) \ + pbx[count] = X; \ + pby[count] = Y; \ + pbz[count] = Z; \ + pbfog[count] = fog0; \ + pbi[count] = I; \ + count++; \ + CHECK_FULL(count); +#include "s_linetemp.h" + } + else { + /* unstippled */ + if (ctx->Line.Width==2.0F) { + /* special case: unstippled and width=2 */ +#define INTERP_XY 1 +#define INTERP_Z 1 +#define INTERP_FOG 1 +#define INTERP_INDEX 1 +#define XMAJOR_PLOT(X,Y) \ + pbx[count] = X; pbx[count+1] = X; \ + pby[count] = Y; pby[count+1] = Y+1; \ + pbz[count] = Z; pbz[count+1] = Z; \ + pbfog[count] = fog0; pbfog[count+1] = fog0; \ + pbi[count] = I; pbi[count+1] = I; \ + count += 2; \ + CHECK_FULL(count); +#define YMAJOR_PLOT(X,Y) \ + pbx[count] = X; pbx[count+1] = X+1; \ + pby[count] = Y; pby[count+1] = Y; \ + pbz[count] = Z; pbz[count+1] = Z; \ + pbfog[count] = fog0; pbfog[count+1] = fog0; \ + pbi[count] = I; pbi[count+1] = I; \ + count += 2; \ + CHECK_FULL(count); +#include "s_linetemp.h" + } + else { + /* unstippled, any width */ +#define INTERP_XY 1 +#define INTERP_Z 1 +#define INTERP_FOG 1 +#define INTERP_INDEX 1 +#define WIDE 1 +#define PLOT(X,Y) \ + pbx[count] = X; \ + pby[count] = Y; \ + pbz[count] = Z; \ + pbi[count] = I; \ + pbfog[count] = fog0; \ + count++; \ + CHECK_FULL(count); +#include "s_linetemp.h" + } + } + + PB->count = count; + _mesa_flush_pb(ctx); +} + + +/* Flat shaded, color index, any width, maybe stippled */ +static void general_flat_ci_line( GLcontext *ctx, + const SWvertex *vert0, + const SWvertex *vert1 ) +{ + struct pixel_buffer *PB = SWRAST_CONTEXT(ctx)->PB; + GLint count; + GLint *pbx = PB->x; + GLint *pby = PB->y; + GLdepth *pbz = PB->z; + GLfloat *pbfog = PB->fog; + PB_SET_INDEX( PB, vert0->index ); + count = PB->count; + + if (ctx->Line.StippleFlag) { + /* stippled, any width */ +#define INTERP_XY 1 +#define INTERP_Z 1 +#define INTERP_FOG 1 +#define WIDE 1 +#define STIPPLE 1 +#define PLOT(X,Y) \ + pbx[count] = X; \ + pby[count] = Y; \ + pbz[count] = Z; \ + pbfog[count] = fog0; \ + count++; \ + CHECK_FULL(count); +#include "s_linetemp.h" + } + else { + /* unstippled */ + if (ctx->Line.Width==2.0F) { + /* special case: unstippled and width=2 */ +#define INTERP_XY 1 +#define INTERP_Z 1 +#define INTERP_FOG 1 +#define XMAJOR_PLOT(X,Y) \ + pbx[count] = X; pbx[count+1] = X; \ + pby[count] = Y; pby[count+1] = Y+1; \ + pbz[count] = Z; pbz[count+1] = Z; \ + pbfog[count] = fog0; pbfog[count+1] = fog0; \ + count += 2; \ + CHECK_FULL(count); +#define YMAJOR_PLOT(X,Y) \ + pbx[count] = X; pbx[count+1] = X+1; \ + pby[count] = Y; pby[count+1] = Y; \ + pbz[count] = Z; pbz[count+1] = Z; \ + pbfog[count] = fog0; pbfog[count+1] = fog0; \ + count += 2; \ + CHECK_FULL(count); +#include "s_linetemp.h" + } + else { + /* unstippled, any width */ +#define INTERP_XY 1 +#define INTERP_Z 1 +#define INTERP_FOG 1 +#define WIDE 1 +#define PLOT(X,Y) \ + pbx[count] = X; \ + pby[count] = Y; \ + pbz[count] = Z; \ + pbfog[count] = fog0; \ + count++; \ + CHECK_FULL(count); +#include "s_linetemp.h" + } + } + + PB->count = count; + _mesa_flush_pb(ctx); +} + + + +static void general_smooth_rgba_line( GLcontext *ctx, + const SWvertex *vert0, + const SWvertex *vert1 ) +{ + struct pixel_buffer *PB = SWRAST_CONTEXT(ctx)->PB; + GLint count = PB->count; + GLint *pbx = PB->x; + GLint *pby = PB->y; + GLdepth *pbz = PB->z; + GLfloat *pbfog = PB->fog; + GLchan (*pbrgba)[4] = PB->rgba; + + PB->mono = GL_FALSE; + + if (ctx->Line.StippleFlag) { + /* stippled */ +#define INTERP_XY 1 +#define INTERP_Z 1 +#define INTERP_FOG 1 +#define INTERP_RGB 1 +#define INTERP_ALPHA 1 +#define WIDE 1 +#define STIPPLE 1 +#define PLOT(X,Y) \ + pbx[count] = X; \ + pby[count] = Y; \ + pbz[count] = Z; \ + pbfog[count] = fog0; \ + pbrgba[count][RCOMP] = FixedToInt(r0); \ + pbrgba[count][GCOMP] = FixedToInt(g0); \ + pbrgba[count][BCOMP] = FixedToInt(b0); \ + pbrgba[count][ACOMP] = FixedToInt(a0); \ + count++; \ + CHECK_FULL(count); +#include "s_linetemp.h" + } + else { + /* unstippled */ + if (ctx->Line.Width==2.0F) { + /* special case: unstippled and width=2 */ +#define INTERP_XY 1 +#define INTERP_Z 1 +#define INTERP_FOG 1 +#define INTERP_RGB 1 +#define INTERP_ALPHA 1 +#define XMAJOR_PLOT(X,Y) \ + pbx[count] = X; pbx[count+1] = X; \ + pby[count] = Y; pby[count+1] = Y+1; \ + pbz[count] = Z; pbz[count+1] = Z; \ + pbfog[count] = fog0; pbfog[count+1] = fog0; \ + pbrgba[count][RCOMP] = FixedToInt(r0); \ + pbrgba[count][GCOMP] = FixedToInt(g0); \ + pbrgba[count][BCOMP] = FixedToInt(b0); \ + pbrgba[count][ACOMP] = FixedToInt(a0); \ + pbrgba[count+1][RCOMP] = FixedToInt(r0); \ + pbrgba[count+1][GCOMP] = FixedToInt(g0); \ + pbrgba[count+1][BCOMP] = FixedToInt(b0); \ + pbrgba[count+1][ACOMP] = FixedToInt(a0); \ + count += 2; \ + CHECK_FULL(count); +#define YMAJOR_PLOT(X,Y) \ + pbx[count] = X; pbx[count+1] = X+1; \ + pby[count] = Y; pby[count+1] = Y; \ + pbz[count] = Z; pbz[count+1] = Z; \ + pbfog[count] = fog0; pbfog[count+1] = fog0; \ + pbrgba[count][RCOMP] = FixedToInt(r0); \ + pbrgba[count][GCOMP] = FixedToInt(g0); \ + pbrgba[count][BCOMP] = FixedToInt(b0); \ + pbrgba[count][ACOMP] = FixedToInt(a0); \ + pbrgba[count+1][RCOMP] = FixedToInt(r0); \ + pbrgba[count+1][GCOMP] = FixedToInt(g0); \ + pbrgba[count+1][BCOMP] = FixedToInt(b0); \ + pbrgba[count+1][ACOMP] = FixedToInt(a0); \ + count += 2; \ + CHECK_FULL(count); +#include "s_linetemp.h" + } + else { + /* unstippled, any width */ +#define INTERP_XY 1 +#define INTERP_Z 1 +#define INTERP_FOG 1 +#define INTERP_RGB 1 +#define INTERP_ALPHA 1 +#define WIDE 1 +#define PLOT(X,Y) \ + pbx[count] = X; \ + pby[count] = Y; \ + pbz[count] = Z; \ + pbfog[count] = fog0; \ + pbrgba[count][RCOMP] = FixedToInt(r0); \ + pbrgba[count][GCOMP] = FixedToInt(g0); \ + pbrgba[count][BCOMP] = FixedToInt(b0); \ + pbrgba[count][ACOMP] = FixedToInt(a0); \ + count++; \ + CHECK_FULL(count); +#include "s_linetemp.h" + } + } + + PB->count = count; + _mesa_flush_pb(ctx); +} + + +static void general_flat_rgba_line( GLcontext *ctx, + const SWvertex *vert0, + const SWvertex *vert1 ) +{ + struct pixel_buffer *PB = SWRAST_CONTEXT(ctx)->PB; + const GLchan *color = vert1->color; + GLuint count; + PB_SET_COLOR( PB, color[0], color[1], color[2], color[3] ); + + if (ctx->Line.StippleFlag) { + /* stippled */ +#define INTERP_XY 1 +#define INTERP_Z 1 +#define INTERP_FOG 1 +#define WIDE 1 +#define STIPPLE 1 +#define PLOT(X,Y) \ + PB_WRITE_PIXEL(PB, X, Y, Z, fog0); \ + count = PB->count; \ + CHECK_FULL(count); +#include "s_linetemp.h" + } + else { + /* unstippled */ + if (ctx->Line.Width==2.0F) { + /* special case: unstippled and width=2 */ +#define INTERP_XY 1 +#define INTERP_Z 1 +#define INTERP_FOG 1 +#define XMAJOR_PLOT(X,Y) PB_WRITE_PIXEL(PB, X, Y, Z, fog0); \ + PB_WRITE_PIXEL(PB, X, Y+1, Z, fog0); +#define YMAJOR_PLOT(X,Y) PB_WRITE_PIXEL(PB, X, Y, Z, fog0); \ + PB_WRITE_PIXEL(PB, X+1, Y, Z, fog0); +#include "s_linetemp.h" + } + else { + /* unstippled, any width */ +#define INTERP_XY 1 +#define INTERP_Z 1 +#define INTERP_FOG 1 +#define WIDE 1 +#define PLOT(X,Y) \ + PB_WRITE_PIXEL(PB, X, Y, Z, fog0); \ + count = PB->count; \ + CHECK_FULL(count); +#include "s_linetemp.h" + } + } + + _mesa_flush_pb(ctx); +} + + +/* Flat-shaded, textured, any width, maybe stippled */ +static void flat_textured_line( GLcontext *ctx, + const SWvertex *vert0, + const SWvertex *vert1 ) +{ + struct pixel_buffer *PB = SWRAST_CONTEXT(ctx)->PB; + GLint count; + GLint *pbx = PB->x; + GLint *pby = PB->y; + GLdepth *pbz = PB->z; + GLfloat *pbfog = PB->fog; + GLfloat *pbs = PB->s[0]; + GLfloat *pbt = PB->t[0]; + GLfloat *pbu = PB->u[0]; + GLchan *color = (GLchan*) vert1->color; + PB_SET_COLOR( PB, color[0], color[1], color[2], color[3] ); + count = PB->count; + + if (ctx->Line.StippleFlag) { + /* stippled */ +#define INTERP_XY 1 +#define INTERP_Z 1 +#define INTERP_FOG 1 +#define INTERP_TEX 1 +#define WIDE 1 +#define STIPPLE 1 +#define PLOT(X,Y) \ + { \ + pbx[count] = X; \ + pby[count] = Y; \ + pbz[count] = Z; \ + pbfog[count] = fog0; \ + pbs[count] = fragTexcoord[0];\ + pbt[count] = fragTexcoord[1];\ + pbu[count] = fragTexcoord[2];\ + count++; \ + CHECK_FULL(count); \ + } +#include "s_linetemp.h" + } + else { + /* unstippled */ +#define INTERP_XY 1 +#define INTERP_Z 1 +#define INTERP_FOG 1 +#define INTERP_TEX 1 +#define WIDE 1 +#define PLOT(X,Y) \ + { \ + pbx[count] = X; \ + pby[count] = Y; \ + pbz[count] = Z; \ + pbfog[count] = fog0; \ + pbs[count] = fragTexcoord[0];\ + pbt[count] = fragTexcoord[1];\ + pbu[count] = fragTexcoord[2];\ + count++; \ + CHECK_FULL(count); \ + } +#include "s_linetemp.h" + } + + PB->count = count; + _mesa_flush_pb(ctx); +} + + + +/* Smooth-shaded, textured, any width, maybe stippled */ +static void smooth_textured_line( GLcontext *ctx, + const SWvertex *vert0, + const SWvertex *vert1 ) +{ + struct pixel_buffer *PB = SWRAST_CONTEXT(ctx)->PB; + GLint count = PB->count; + GLint *pbx = PB->x; + GLint *pby = PB->y; + GLdepth *pbz = PB->z; + GLfloat *pbfog = PB->fog; + GLfloat *pbs = PB->s[0]; + GLfloat *pbt = PB->t[0]; + GLfloat *pbu = PB->u[0]; + GLchan (*pbrgba)[4] = PB->rgba; + + PB->mono = GL_FALSE; + + if (ctx->Line.StippleFlag) { + /* stippled */ +#define INTERP_XY 1 +#define INTERP_Z 1 +#define INTERP_FOG 1 +#define INTERP_RGB 1 +#define INTERP_ALPHA 1 +#define INTERP_TEX 1 +#define WIDE 1 +#define STIPPLE 1 +#define PLOT(X,Y) \ + { \ + pbx[count] = X; \ + pby[count] = Y; \ + pbz[count] = Z; \ + pbfog[count] = fog0; \ + pbs[count] = fragTexcoord[0]; \ + pbt[count] = fragTexcoord[1]; \ + pbu[count] = fragTexcoord[2]; \ + pbrgba[count][RCOMP] = FixedToInt(r0); \ + pbrgba[count][GCOMP] = FixedToInt(g0); \ + pbrgba[count][BCOMP] = FixedToInt(b0); \ + pbrgba[count][ACOMP] = FixedToInt(a0); \ + count++; \ + CHECK_FULL(count); \ + } +#include "s_linetemp.h" + } + else { + /* unstippled */ +#define INTERP_XY 1 +#define INTERP_Z 1 +#define INTERP_FOG 1 +#define INTERP_RGB 1 +#define INTERP_ALPHA 1 +#define INTERP_TEX 1 +#define WIDE 1 +#define PLOT(X,Y) \ + { \ + pbx[count] = X; \ + pby[count] = Y; \ + pbz[count] = Z; \ + pbfog[count] = fog0; \ + pbs[count] = fragTexcoord[0]; \ + pbt[count] = fragTexcoord[1]; \ + pbu[count] = fragTexcoord[2]; \ + pbrgba[count][RCOMP] = FixedToInt(r0); \ + pbrgba[count][GCOMP] = FixedToInt(g0); \ + pbrgba[count][BCOMP] = FixedToInt(b0); \ + pbrgba[count][ACOMP] = FixedToInt(a0); \ + count++; \ + CHECK_FULL(count); \ + } +#include "s_linetemp.h" + } + + PB->count = count; + _mesa_flush_pb(ctx); +} + + +/* Smooth-shaded, multitextured, any width, maybe stippled, separate specular + * color interpolation. + */ +static void smooth_multitextured_line( GLcontext *ctx, + const SWvertex *vert0, + const SWvertex *vert1 ) +{ + struct pixel_buffer *PB = SWRAST_CONTEXT(ctx)->PB; + GLint count = PB->count; + GLint *pbx = PB->x; + GLint *pby = PB->y; + GLdepth *pbz = PB->z; + GLfloat *pbfog = PB->fog; + GLchan (*pbrgba)[4] = PB->rgba; + GLchan (*pbspec)[3] = PB->spec; + + PB->mono = GL_FALSE; + + if (ctx->Line.StippleFlag) { + /* stippled */ +#define INTERP_XY 1 +#define INTERP_Z 1 +#define INTERP_FOG 1 +#define INTERP_RGB 1 +#define INTERP_SPEC 1 +#define INTERP_ALPHA 1 +#define INTERP_MULTITEX 1 +#define WIDE 1 +#define STIPPLE 1 +#define PLOT(X,Y) \ + { \ + GLuint u; \ + pbx[count] = X; \ + pby[count] = Y; \ + pbz[count] = Z; \ + pbfog[count] = fog0; \ + pbrgba[count][RCOMP] = FixedToInt(r0); \ + pbrgba[count][GCOMP] = FixedToInt(g0); \ + pbrgba[count][BCOMP] = FixedToInt(b0); \ + pbrgba[count][ACOMP] = FixedToInt(a0); \ + pbspec[count][RCOMP] = FixedToInt(sr0); \ + pbspec[count][GCOMP] = FixedToInt(sg0); \ + pbspec[count][BCOMP] = FixedToInt(sb0); \ + for (u = 0; u < ctx->Const.MaxTextureUnits; u++) { \ + if (ctx->Texture.Unit[u]._ReallyEnabled) { \ + PB->s[u][count] = fragTexcoord[u][0]; \ + PB->t[u][count] = fragTexcoord[u][1]; \ + PB->u[u][count] = fragTexcoord[u][2]; \ + } \ + } \ + count++; \ + CHECK_FULL(count); \ + } +#include "s_linetemp.h" + } + else { + /* unstippled */ +#define INTERP_XY 1 +#define INTERP_Z 1 +#define INTERP_FOG 1 +#define INTERP_RGB 1 +#define INTERP_SPEC 1 +#define INTERP_ALPHA 1 +#define INTERP_MULTITEX 1 +#define WIDE 1 +#define PLOT(X,Y) \ + { \ + GLuint u; \ + pbx[count] = X; \ + pby[count] = Y; \ + pbz[count] = Z; \ + pbfog[count] = fog0; \ + pbrgba[count][RCOMP] = FixedToInt(r0); \ + pbrgba[count][GCOMP] = FixedToInt(g0); \ + pbrgba[count][BCOMP] = FixedToInt(b0); \ + pbrgba[count][ACOMP] = FixedToInt(a0); \ + pbspec[count][RCOMP] = FixedToInt(sr0); \ + pbspec[count][GCOMP] = FixedToInt(sg0); \ + pbspec[count][BCOMP] = FixedToInt(sb0); \ + for (u = 0; u < ctx->Const.MaxTextureUnits; u++) { \ + if (ctx->Texture.Unit[u]._ReallyEnabled) { \ + PB->s[u][count] = fragTexcoord[u][0]; \ + PB->t[u][count] = fragTexcoord[u][1]; \ + PB->u[u][count] = fragTexcoord[u][2]; \ + } \ + } \ + count++; \ + CHECK_FULL(count); \ + } +#include "s_linetemp.h" + } + + PB->count = count; + _mesa_flush_pb(ctx); +} + + +/* Flat-shaded, multitextured, any width, maybe stippled, separate specular + * color interpolation. + */ +static void flat_multitextured_line( GLcontext *ctx, + const SWvertex *vert0, + const SWvertex *vert1 ) +{ + struct pixel_buffer *PB = SWRAST_CONTEXT(ctx)->PB; + GLint count = PB->count; + GLint *pbx = PB->x; + GLint *pby = PB->y; + GLdepth *pbz = PB->z; + GLfloat *pbfog = PB->fog; + GLchan (*pbrgba)[4] = PB->rgba; + GLchan (*pbspec)[3] = PB->spec; + GLchan *color = (GLchan*) vert1->color; + GLchan sRed = vert1->specular[0]; + GLchan sGreen = vert1->specular[1]; + GLchan sBlue = vert1->specular[2]; + + PB->mono = GL_FALSE; + + if (ctx->Line.StippleFlag) { + /* stippled */ +#define INTERP_XY 1 +#define INTERP_Z 1 +#define INTERP_FOG 1 +#define INTERP_ALPHA 1 +#define INTERP_MULTITEX 1 +#define WIDE 1 +#define STIPPLE 1 +#define PLOT(X,Y) \ + { \ + GLuint u; \ + pbx[count] = X; \ + pby[count] = Y; \ + pbz[count] = Z; \ + pbfog[count] = fog0; \ + pbrgba[count][RCOMP] = color[0]; \ + pbrgba[count][GCOMP] = color[1]; \ + pbrgba[count][BCOMP] = color[2]; \ + pbrgba[count][ACOMP] = color[3]; \ + pbspec[count][RCOMP] = sRed; \ + pbspec[count][GCOMP] = sGreen; \ + pbspec[count][BCOMP] = sBlue; \ + for (u = 0; u < ctx->Const.MaxTextureUnits; u++) { \ + if (ctx->Texture.Unit[u]._ReallyEnabled) { \ + PB->s[u][count] = fragTexcoord[u][0]; \ + PB->t[u][count] = fragTexcoord[u][1]; \ + PB->u[u][count] = fragTexcoord[u][2]; \ + } \ + } \ + count++; \ + CHECK_FULL(count); \ + } +#include "s_linetemp.h" + } + else { + /* unstippled */ +#define INTERP_XY 1 +#define INTERP_Z 1 +#define INTERP_FOG 1 +#define INTERP_ALPHA 1 +#define INTERP_MULTITEX 1 +#define WIDE 1 +#define PLOT(X,Y) \ + { \ + GLuint u; \ + pbx[count] = X; \ + pby[count] = Y; \ + pbz[count] = Z; \ + pbfog[count] = fog0; \ + pbrgba[count][RCOMP] = color[0]; \ + pbrgba[count][GCOMP] = color[1]; \ + pbrgba[count][BCOMP] = color[2]; \ + pbrgba[count][ACOMP] = color[3]; \ + pbspec[count][RCOMP] = sRed; \ + pbspec[count][GCOMP] = sGreen; \ + pbspec[count][BCOMP] = sBlue; \ + for (u = 0; u < ctx->Const.MaxTextureUnits; u++) { \ + if (ctx->Texture.Unit[u]._ReallyEnabled) { \ + PB->s[u][count] = fragTexcoord[u][0]; \ + PB->t[u][count] = fragTexcoord[u][1]; \ + PB->u[u][count] = fragTexcoord[u][2]; \ + } \ + } \ + count++; \ + CHECK_FULL(count); \ + } +#include "s_linetemp.h" + } + + PB->count = count; + _mesa_flush_pb(ctx); +} + + +void _swrast_add_spec_terms_line( GLcontext *ctx, + const SWvertex *v0, + const SWvertex *v1 ) +{ + SWvertex *ncv0 = (SWvertex *)v0; + SWvertex *ncv1 = (SWvertex *)v1; + GLchan c[2][4]; + COPY_CHAN4( c[0], ncv0->color ); + COPY_CHAN4( c[1], ncv1->color ); + ACC_3V( ncv0->color, ncv0->specular ); + ACC_3V( ncv1->color, ncv1->specular ); + SWRAST_CONTEXT(ctx)->SpecLine( ctx, ncv0, ncv1 ); + COPY_CHAN4( ncv0->color, c[0] ); + COPY_CHAN4( ncv1->color, c[1] ); +} + + +#ifdef DEBUG +extern void +_mesa_print_line_function(GLcontext *ctx); /* silence compiler warning */ +void +_mesa_print_line_function(GLcontext *ctx) +{ + SWcontext *swrast = SWRAST_CONTEXT(ctx); + + printf("Line Func == "); + if (swrast->Line == flat_ci_line) + printf("flat_ci_line\n"); + else if (swrast->Line == flat_ci_z_line) + printf("flat_ci_z_line\n"); + else if (swrast->Line == flat_rgba_line) + printf("flat_rgba_line\n"); + else if (swrast->Line == flat_rgba_z_line) + printf("flat_rgba_z_line\n"); + else if (swrast->Line == smooth_ci_line) + printf("smooth_ci_line\n"); + else if (swrast->Line == smooth_ci_z_line) + printf("smooth_ci_z_line\n"); + else if (swrast->Line == smooth_rgba_line) + printf("smooth_rgba_line\n"); + else if (swrast->Line == smooth_rgba_z_line) + printf("smooth_rgba_z_line\n"); + else if (swrast->Line == general_smooth_ci_line) + printf("general_smooth_ci_line\n"); + else if (swrast->Line == general_flat_ci_line) + printf("general_flat_ci_line\n"); + else if (swrast->Line == general_smooth_rgba_line) + printf("general_smooth_rgba_line\n"); + else if (swrast->Line == general_flat_rgba_line) + printf("general_flat_rgba_line\n"); + else if (swrast->Line == flat_textured_line) + printf("flat_textured_line\n"); + else if (swrast->Line == smooth_textured_line) + printf("smooth_textured_line\n"); + else if (swrast->Line == smooth_multitextured_line) + printf("smooth_multitextured_line\n"); + else if (swrast->Line == flat_multitextured_line) + printf("flat_multitextured_line\n"); + else + printf("Driver func %p\n", swrast->Line); +} +#endif + + + +/* + * Determine which line drawing function to use given the current + * rendering context. + * + * Please update the summary flag _SWRAST_NEW_LINE if you add or remove + * tests to this code. + */ +void +_swrast_choose_line( GLcontext *ctx ) +{ + SWcontext *swrast = SWRAST_CONTEXT(ctx); + const GLboolean rgbmode = ctx->Visual.rgbMode; + + if (ctx->RenderMode==GL_RENDER) { + if (ctx->Line.SmoothFlag) { + /* antialiased lines */ + _swrast_choose_aa_line_function(ctx); + ASSERT(swrast->Triangle); + } + else if (ctx->Texture._ReallyEnabled) { + if (ctx->Texture._ReallyEnabled > TEXTURE0_ANY || + (ctx->_TriangleCaps & DD_SEPARATE_SPECULAR)) { + /* multi-texture and/or separate specular color */ + if (ctx->Light.ShadeModel==GL_SMOOTH) + swrast->Line = smooth_multitextured_line; + else + swrast->Line = flat_multitextured_line; + } + else { + if (ctx->Light.ShadeModel==GL_SMOOTH) { + swrast->Line = smooth_textured_line; + } + else { + swrast->Line = flat_textured_line; + } + } + } + else if (ctx->Line.Width!=1.0 || ctx->Line.StippleFlag) { + if (ctx->Light.ShadeModel==GL_SMOOTH) { + if (rgbmode) + swrast->Line = general_smooth_rgba_line; + else + swrast->Line = general_smooth_ci_line; + } + else { + if (rgbmode) + swrast->Line = general_flat_rgba_line; + else + swrast->Line = general_flat_ci_line; + } + } + else { + if (ctx->Light.ShadeModel==GL_SMOOTH) { + /* Width==1, non-stippled, smooth-shaded */ + if (ctx->Depth.Test || ctx->Fog.Enabled) { + if (rgbmode) + swrast->Line = smooth_rgba_z_line; + else + swrast->Line = smooth_ci_z_line; + } + else { + if (rgbmode) + swrast->Line = smooth_rgba_line; + else + swrast->Line = smooth_ci_line; + } + } + else { + /* Width==1, non-stippled, flat-shaded */ + if (ctx->Depth.Test || ctx->Fog.Enabled) { + if (rgbmode) + swrast->Line = flat_rgba_z_line; + else + swrast->Line = flat_ci_z_line; + } + else { + if (rgbmode) + swrast->Line = flat_rgba_line; + else + swrast->Line = flat_ci_line; + } + } + } + } + else if (ctx->RenderMode==GL_FEEDBACK) { + swrast->Line = _mesa_feedback_line; + } + else { + /* GL_SELECT mode */ + swrast->Line = _mesa_select_line; + } + + /*_mesa_print_line_function(ctx);*/ +} Index: dll/opengl/opengl32/mesa/swrast/s_lines.h =================================================================== --- dll/opengl/opengl32/mesa/swrast/s_lines.h (revision 0) +++ dll/opengl/opengl32/mesa/swrast/s_lines.h (working copy) @@ -0,0 +1,42 @@ +/* $Id: s_lines.h,v 1.5 2001/03/12 00:48:42 gareth Exp $ */ + +/* + * Mesa 3-D graphics library + * Version: 3.5 + * + * Copyright (C) 1999-2001 Brian Paul 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 + * BRIAN PAUL 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. + */ + + +#ifndef S_LINES_H +#define S_LINES_H + +#include "mtypes.h" + +void +_swrast_choose_line( GLcontext *ctx ); + +void +_swrast_add_spec_terms_line( GLcontext *ctx, + const SWvertex *v0, + const SWvertex *v1 ); + + +#endif Index: dll/opengl/opengl32/mesa/swrast/s_linetemp.h =================================================================== --- dll/opengl/opengl32/mesa/swrast/s_linetemp.h (revision 0) +++ dll/opengl/opengl32/mesa/swrast/s_linetemp.h (working copy) @@ -0,0 +1,664 @@ +/* $Id: s_linetemp.h,v 1.8 2001/05/03 22:13:32 brianp Exp $ */ + +/* + * Mesa 3-D graphics library + * Version: 3.5 + * + * Copyright (C) 1999-2001 Brian Paul 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 + * BRIAN PAUL 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. + */ + + +/* + * Line Rasterizer Template + * + * This file is #include'd to generate custom line rasterizers. + * + * The following macros may be defined to indicate what auxillary information + * must be interplated along the line: + * INTERP_Z - if defined, interpolate Z values + * INTERP_FOG - if defined, interpolate FOG values + * INTERP_RGB - if defined, interpolate RGB values + * INTERP_SPEC - if defined, interpolate specular RGB values + * INTERP_ALPHA - if defined, interpolate Alpha values + * INTERP_INDEX - if defined, interpolate color index values + * INTERP_TEX - if defined, interpolate unit 0 texcoords + * INTERP_MULTITEX - if defined, interpolate multi-texcoords + * + * When one can directly address pixels in the color buffer the following + * macros can be defined and used to directly compute pixel addresses during + * rasterization (see pixelPtr): + * PIXEL_TYPE - the datatype of a pixel (GLubyte, GLushort, GLuint) + * BYTES_PER_ROW - number of bytes per row in the color buffer + * PIXEL_ADDRESS(X,Y) - returns the address of pixel at (X,Y) where + * Y==0 at bottom of screen and increases upward. + * + * Similarly, for direct depth buffer access, this type is used for depth + * buffer addressing: + * DEPTH_TYPE - either GLushort or GLuint + * + * Optionally, one may provide one-time setup code + * SETUP_CODE - code which is to be executed once per line + * + * To enable line stippling define STIPPLE = 1 + * To enable wide lines define WIDE = 1 + * + * To actually "plot" each pixel either the PLOT macro or + * (XMAJOR_PLOT and YMAJOR_PLOT macros) must be defined... + * PLOT(X,Y) - code to plot a pixel. Example: + * if (Z < *zPtr) { + * *zPtr = Z; + * color = pack_rgb( FixedToInt(r0), FixedToInt(g0), + * FixedToInt(b0) ); + * put_pixel( X, Y, color ); + * } + * + * This code was designed for the origin to be in the lower-left corner. + * + */ + + +/*void line( GLcontext *ctx, const SWvertex *vert0, const SWvertex *vert1 )*/ +{ + GLint x0 = (GLint) vert0->win[0]; + GLint x1 = (GLint) vert1->win[0]; + GLint y0 = (GLint) vert0->win[1]; + GLint y1 = (GLint) vert1->win[1]; + GLint dx, dy; +#ifdef INTERP_XY + GLint xstep, ystep; +#endif +#ifdef INTERP_Z + GLint z0, z1, dz; + const GLint depthBits = ctx->Visual.depthBits; + const GLint fixedToDepthShift = depthBits <= 16 ? FIXED_SHIFT : 0; +# define FixedToDepth(F) ((F) >> fixedToDepthShift) +# ifdef DEPTH_TYPE + GLint zPtrXstep, zPtrYstep; + DEPTH_TYPE *zPtr; +# endif +#endif +#ifdef INTERP_FOG + GLfloat fog0 = vert0->fog; + GLfloat dfog = vert1->fog - fog0; +#endif +#ifdef INTERP_RGB + GLfixed r0 = IntToFixed(vert0->color[0]); + GLfixed dr = IntToFixed(vert1->color[0]) - r0; + GLfixed g0 = IntToFixed(vert0->color[1]); + GLfixed dg = IntToFixed(vert1->color[1]) - g0; + GLfixed b0 = IntToFixed(vert0->color[2]); + GLfixed db = IntToFixed(vert1->color[2]) - b0; +#endif +#ifdef INTERP_SPEC + GLfixed sr0 = IntToFixed(vert0->specular[0]); + GLfixed dsr = IntToFixed(vert1->specular[0]) - sr0; + GLfixed sg0 = IntToFixed(vert0->specular[1]); + GLfixed dsg = IntToFixed(vert1->specular[1]) - sg0; + GLfixed sb0 = IntToFixed(vert0->specular[2]); + GLfixed dsb = IntToFixed(vert1->specular[2]) - sb0; +#endif +#ifdef INTERP_ALPHA + GLfixed a0 = IntToFixed(vert0->color[3]); + GLfixed da = IntToFixed(vert1->color[3]) - a0; +#endif +#ifdef INTERP_INDEX + GLint i0 = vert0->index << 8; + GLint di = (GLint) (vert1->index << 8) - i0; +#endif +#ifdef INTERP_TEX + const GLfloat invw0 = vert0->win[3]; + const GLfloat invw1 = vert1->win[3]; + GLfloat tex[4]; + GLfloat dtex[4]; + GLfloat fragTexcoord[4]; +#endif +#ifdef INTERP_MULTITEX + const GLfloat invw0 = vert0->win[3]; + const GLfloat invw1 = vert1->win[3]; + GLfloat tex[MAX_TEXTURE_UNITS][4]; + GLfloat dtex[MAX_TEXTURE_UNITS][4]; + GLfloat fragTexcoord[MAX_TEXTURE_UNITS][4]; +#endif +#ifdef PIXEL_ADDRESS + PIXEL_TYPE *pixelPtr; + GLint pixelXstep, pixelYstep; +#endif +#ifdef STIPPLE + SWcontext *swrast = SWRAST_CONTEXT(ctx); +#endif +#ifdef WIDE + /* for wide lines, draw all X in [x+min, x+max] or Y in [y+min, y+max] */ + GLint width, min, max; + width = (GLint) CLAMP( ctx->Line.Width, MIN_LINE_WIDTH, MAX_LINE_WIDTH ); + min = (width-1) / -2; + max = min + width - 1; +#endif +#ifdef INTERP_TEX + { + tex[0] = invw0 * vert0->texcoord[0][0]; + dtex[0] = invw1 * vert1->texcoord[0][0] - tex[0]; + tex[1] = invw0 * vert0->texcoord[0][1]; + dtex[1] = invw1 * vert1->texcoord[0][1] - tex[1]; + tex[2] = invw0 * vert0->texcoord[0][2]; + dtex[2] = invw1 * vert1->texcoord[0][2] - tex[2]; + tex[3] = invw0 * vert0->texcoord[0][3]; + dtex[3] = invw1 * vert1->texcoord[0][3] - tex[3]; + } +#endif +#ifdef INTERP_MULTITEX + { + GLuint u; + for (u = 0; u < ctx->Const.MaxTextureUnits; u++) { + if (ctx->Texture.Unit[u]._ReallyEnabled) { + tex[u][0] = invw0 * vert0->texcoord[u][0]; + dtex[u][0] = invw1 * vert1->texcoord[u][0] - tex[u][0]; + tex[u][1] = invw0 * vert0->texcoord[u][1]; + dtex[u][1] = invw1 * vert1->texcoord[u][1] - tex[u][1]; + tex[u][2] = invw0 * vert0->texcoord[u][2]; + dtex[u][2] = invw1 * vert1->texcoord[u][2] - tex[u][2]; + tex[u][3] = invw0 * vert0->texcoord[u][3]; + dtex[u][3] = invw1 * vert1->texcoord[u][3] - tex[u][3]; + } + } + } +#endif + + +/* + * Despite being clipped to the view volume, the line's window coordinates + * may just lie outside the window bounds. That is, if the legal window + * coordinates are [0,W-1][0,H-1], it's possible for x==W and/or y==H. + * This quick and dirty code nudges the endpoints inside the window if + * necessary. + */ +#ifdef CLIP_HACK + { + GLint w = ctx->DrawBuffer->Width; + GLint h = ctx->DrawBuffer->Height; + if ((x0==w) | (x1==w)) { + if ((x0==w) & (x1==w)) + return; + x0 -= x0==w; + x1 -= x1==w; + } + if ((y0==h) | (y1==h)) { + if ((y0==h) & (y1==h)) + return; + y0 -= y0==h; + y1 -= y1==h; + } + } +#endif + dx = x1 - x0; + dy = y1 - y0; + if (dx==0 && dy==0) { + return; + } + + /* + * Setup + */ +#ifdef SETUP_CODE + SETUP_CODE +#endif + +#ifdef INTERP_Z +# ifdef DEPTH_TYPE + zPtr = (DEPTH_TYPE *) _mesa_zbuffer_address(ctx, x0, y0); +# endif + if (depthBits <= 16) { + z0 = FloatToFixed(vert0->win[2]); + z1 = FloatToFixed(vert1->win[2]); + } + else { + z0 = (int) vert0->win[2]; + z1 = (int) vert1->win[2]; + } +#endif +#ifdef PIXEL_ADDRESS + pixelPtr = (PIXEL_TYPE *) PIXEL_ADDRESS(x0,y0); +#endif + + if (dx<0) { + dx = -dx; /* make positive */ +#ifdef INTERP_XY + xstep = -1; +#endif +#if defined(INTERP_Z) && defined(DEPTH_TYPE) + zPtrXstep = -((GLint)sizeof(DEPTH_TYPE)); +#endif +#ifdef PIXEL_ADDRESS + pixelXstep = -((GLint)sizeof(PIXEL_TYPE)); +#endif + } + else { +#ifdef INTERP_XY + xstep = 1; +#endif +#if defined(INTERP_Z) && defined(DEPTH_TYPE) + zPtrXstep = ((GLint)sizeof(DEPTH_TYPE)); +#endif +#ifdef PIXEL_ADDRESS + pixelXstep = ((GLint)sizeof(PIXEL_TYPE)); +#endif + } + + if (dy<0) { + dy = -dy; /* make positive */ +#ifdef INTERP_XY + ystep = -1; +#endif +#if defined(INTERP_Z) && defined(DEPTH_TYPE) + zPtrYstep = -ctx->DrawBuffer->Width * ((GLint)sizeof(DEPTH_TYPE)); +#endif +#ifdef PIXEL_ADDRESS + pixelYstep = BYTES_PER_ROW; +#endif + } + else { +#ifdef INTERP_XY + ystep = 1; +#endif +#if defined(INTERP_Z) && defined(DEPTH_TYPE) + zPtrYstep = ctx->DrawBuffer->Width * ((GLint)sizeof(DEPTH_TYPE)); +#endif +#ifdef PIXEL_ADDRESS + pixelYstep = -(BYTES_PER_ROW); +#endif + } + + /* + * Draw + */ + + if (dx>dy) { + /*** X-major line ***/ + GLint i; + GLint errorInc = dy+dy; + GLint error = errorInc-dx; + GLint errorDec = error-dx; +#ifdef INTERP_Z + dz = (z1-z0) / dx; +#endif +#ifdef INTERP_FOG + dfog /= dx; +#endif +#ifdef INTERP_RGB + dr /= dx; /* convert from whole line delta to per-pixel delta */ + dg /= dx; + db /= dx; +#endif +#ifdef INTERP_SPEC + dsr /= dx; /* convert from whole line delta to per-pixel delta */ + dsg /= dx; + dsb /= dx; +#endif +#ifdef INTERP_ALPHA + da /= dx; +#endif +#ifdef INTERP_INDEX + di /= dx; +#endif +#ifdef INTERP_TEX + { + const GLfloat invDx = 1.0F / (GLfloat) dx; + dtex[0] *= invDx; + dtex[1] *= invDx; + dtex[2] *= invDx; + dtex[3] *= invDx; + } +#endif +#ifdef INTERP_MULTITEX + { + const GLfloat invDx = 1.0F / (GLfloat) dx; + GLuint u; + for (u = 0; u < ctx->Const.MaxTextureUnits; u++) { + if (ctx->Texture.Unit[u]._ReallyEnabled) { + dtex[u][0] *= invDx; + dtex[u][1] *= invDx; + dtex[u][2] *= invDx; + dtex[u][3] *= invDx; + } + } + } +#endif + + for (i=0;iStippleCounter/ctx->Line.StippleFactor) & 0xf); + if (ctx->Line.StipplePattern & m) { +#endif +#ifdef INTERP_Z + GLdepth Z = FixedToDepth(z0); +#endif +#ifdef INTERP_INDEX + GLint I = i0 >> 8; +#endif +#ifdef INTERP_TEX + { + const GLfloat invQ = tex[3] ? (1.0F / tex[3]) : 1.0F; + fragTexcoord[0] = tex[0] * invQ; + fragTexcoord[1] = tex[1] * invQ; + fragTexcoord[2] = tex[2] * invQ; + fragTexcoord[3] = tex[3]; + } +#endif +#ifdef INTERP_MULTITEX + { + GLuint u; + for (u = 0; u < ctx->Const.MaxTextureUnits; u++) { + if (ctx->Texture.Unit[u]._ReallyEnabled) { + const GLfloat invQ = 1.0F / tex[u][3]; + fragTexcoord[u][0] = tex[u][0] * invQ; + fragTexcoord[u][1] = tex[u][1] * invQ; + fragTexcoord[u][2] = tex[u][2] * invQ; + fragTexcoord[u][3] = tex[u][3]; + } + } + } +#endif +#ifdef WIDE + { + GLint yy; + GLint ymin = y0 + min; + GLint ymax = y0 + max; + for (yy=ymin;yy<=ymax;yy++) { + PLOT( x0, yy ); + } + } +#else +# ifdef XMAJOR_PLOT + XMAJOR_PLOT( x0, y0 ); +# else + PLOT( x0, y0 ); +# endif +#endif /*WIDE*/ +#ifdef STIPPLE + } + swrast->StippleCounter++; +#endif +#ifdef INTERP_XY + x0 += xstep; +#endif +#ifdef INTERP_Z +# ifdef DEPTH_TYPE + zPtr = (DEPTH_TYPE *) ((GLubyte*) zPtr + zPtrXstep); +# endif + z0 += dz; +#endif +#ifdef INTERP_FOG + fog0 += dfog; +#endif +#ifdef INTERP_RGB + r0 += dr; + g0 += dg; + b0 += db; +#endif +#ifdef INTERP_SPEC + sr0 += dsr; + sg0 += dsg; + sb0 += dsb; +#endif +#ifdef INTERP_ALPHA + a0 += da; +#endif +#ifdef INTERP_INDEX + i0 += di; +#endif +#ifdef INTERP_TEX + tex[0] += dtex[0]; + tex[1] += dtex[1]; + tex[2] += dtex[2]; + tex[3] += dtex[3]; +#endif +#ifdef INTERP_MULTITEX + { + GLuint u; + for (u = 0; u < ctx->Const.MaxTextureUnits; u++) { + if (ctx->Texture.Unit[u]._ReallyEnabled) { + tex[u][0] += dtex[u][0]; + tex[u][1] += dtex[u][1]; + tex[u][2] += dtex[u][2]; + tex[u][3] += dtex[u][3]; + } + } + } +#endif + +#ifdef PIXEL_ADDRESS + pixelPtr = (PIXEL_TYPE*) ((GLubyte*) pixelPtr + pixelXstep); +#endif + if (error<0) { + error += errorInc; + } + else { + error += errorDec; +#ifdef INTERP_XY + y0 += ystep; +#endif +#if defined(INTERP_Z) && defined(DEPTH_TYPE) + zPtr = (DEPTH_TYPE *) ((GLubyte*) zPtr + zPtrYstep); +#endif +#ifdef PIXEL_ADDRESS + pixelPtr = (PIXEL_TYPE*) ((GLubyte*) pixelPtr + pixelYstep); +#endif + } + } + } + else { + /*** Y-major line ***/ + GLint i; + GLint errorInc = dx+dx; + GLint error = errorInc-dy; + GLint errorDec = error-dy; +#ifdef INTERP_Z + dz = (z1-z0) / dy; +#endif +#ifdef INTERP_FOG + dfog /= dy; +#endif +#ifdef INTERP_RGB + dr /= dy; /* convert from whole line delta to per-pixel delta */ + dg /= dy; + db /= dy; +#endif +#ifdef INTERP_SPEC + dsr /= dy; /* convert from whole line delta to per-pixel delta */ + dsg /= dy; + dsb /= dy; +#endif +#ifdef INTERP_ALPHA + da /= dy; +#endif +#ifdef INTERP_INDEX + di /= dy; +#endif +#ifdef INTERP_TEX + { + const GLfloat invDy = 1.0F / (GLfloat) dy; + dtex[0] *= invDy; + dtex[1] *= invDy; + dtex[2] *= invDy; + dtex[3] *= invDy; + } +#endif +#ifdef INTERP_MULTITEX + { + const GLfloat invDy = 1.0F / (GLfloat) dy; + GLuint u; + for (u = 0; u < ctx->Const.MaxTextureUnits; u++) { + if (ctx->Texture.Unit[u]._ReallyEnabled) { + dtex[u][0] *= invDy; + dtex[u][1] *= invDy; + dtex[u][2] *= invDy; + dtex[u][3] *= invDy; + } + } + } +#endif + + for (i=0;iStippleCounter/ctx->Line.StippleFactor) & 0xf); + if (ctx->Line.StipplePattern & m) { +#endif +#ifdef INTERP_Z + GLdepth Z = FixedToDepth(z0); +#endif +#ifdef INTERP_INDEX + GLint I = i0 >> 8; +#endif +#ifdef INTERP_TEX + { + const GLfloat invQ = tex[3] ? (1.0F / tex[3]) : 1.0F; + fragTexcoord[0] = tex[0] * invQ; + fragTexcoord[1] = tex[1] * invQ; + fragTexcoord[2] = tex[2] * invQ; + fragTexcoord[3] = tex[3]; + } +#endif +#ifdef INTERP_MULTITEX + { + GLuint u; + for (u = 0; u < ctx->Const.MaxTextureUnits; u++) { + if (ctx->Texture.Unit[u]._ReallyEnabled) { + const GLfloat invQ = 1.0F / tex[u][3]; + fragTexcoord[u][0] = tex[u][0] * invQ; + fragTexcoord[u][1] = tex[u][1] * invQ; + fragTexcoord[u][2] = tex[u][2] * invQ; + fragTexcoord[u][3] = tex[u][3]; + } + } + } +#endif +#ifdef WIDE + { + GLint xx; + GLint xmin = x0 + min; + GLint xmax = x0 + max; + for (xx=xmin;xx<=xmax;xx++) { + PLOT( xx, y0 ); + } + } +#else +# ifdef YMAJOR_PLOT + YMAJOR_PLOT( x0, y0 ); +# else + PLOT( x0, y0 ); +# endif +#endif /*WIDE*/ +#ifdef STIPPLE + } + swrast->StippleCounter++; +#endif +#ifdef INTERP_XY + y0 += ystep; +#endif +#ifdef INTERP_Z +# ifdef DEPTH_TYPE + zPtr = (DEPTH_TYPE *) ((GLubyte*) zPtr + zPtrYstep); +# endif + z0 += dz; +#endif +#ifdef INTERP_FOG + fog0 += dfog; +#endif +#ifdef INTERP_RGB + r0 += dr; + g0 += dg; + b0 += db; +#endif +#ifdef INTERP_SPEC + sr0 += dsr; + sg0 += dsg; + sb0 += dsb; +#endif +#ifdef INTERP_ALPHA + a0 += da; +#endif +#ifdef INTERP_INDEX + i0 += di; +#endif +#ifdef INTERP_TEX + tex[0] += dtex[0]; + tex[1] += dtex[1]; + tex[2] += dtex[2]; + tex[3] += dtex[3]; +#endif +#ifdef INTERP_MULTITEX + { + GLuint u; + for (u = 0; u < ctx->Const.MaxTextureUnits; u++) { + if (ctx->Texture.Unit[u]._ReallyEnabled) { + tex[u][0] += dtex[u][0]; + tex[u][1] += dtex[u][1]; + tex[u][2] += dtex[u][2]; + tex[u][3] += dtex[u][3]; + } + } + } +#endif +#ifdef PIXEL_ADDRESS + pixelPtr = (PIXEL_TYPE*) ((GLubyte*) pixelPtr + pixelYstep); +#endif + if (error<0) { + error += errorInc; + } + else { + error += errorDec; +#ifdef INTERP_XY + x0 += xstep; +#endif +#if defined(INTERP_Z) && defined(DEPTH_TYPE) + zPtr = (DEPTH_TYPE *) ((GLubyte*) zPtr + zPtrXstep); +#endif +#ifdef PIXEL_ADDRESS + pixelPtr = (PIXEL_TYPE*) ((GLubyte*) pixelPtr + pixelXstep); +#endif + } + } + } + +} + + +#undef INTERP_XY +#undef INTERP_Z +#undef INTERP_FOG +#undef INTERP_RGB +#undef INTERP_SPEC +#undef INTERP_ALPHA +#undef INTERP_TEX +#undef INTERP_MULTITEX +#undef INTERP_INDEX +#undef PIXEL_ADDRESS +#undef PIXEL_TYPE +#undef DEPTH_TYPE +#undef BYTES_PER_ROW +#undef SETUP_CODE +#undef PLOT +#undef XMAJOR_PLOT +#undef YMAJOR_PLOT +#undef CLIP_HACK +#undef STIPPLE +#undef WIDE +#undef FixedToDepth Index: dll/opengl/opengl32/mesa/swrast/s_logic.c =================================================================== --- dll/opengl/opengl32/mesa/swrast/s_logic.c (revision 0) +++ dll/opengl/opengl32/mesa/swrast/s_logic.c (working copy) @@ -0,0 +1,501 @@ +/* $Id: s_logic.c,v 1.7 2001/05/10 16:54:12 brianp Exp $ */ + +/* + * Mesa 3-D graphics library + * Version: 3.5 + * + * Copyright (C) 1999-2001 Brian Paul 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 + * BRIAN PAUL 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. + */ + + +#include "glheader.h" +#include "context.h" +#include "macros.h" + +#include "s_alphabuf.h" +#include "s_context.h" +#include "s_logic.h" +#include "s_pb.h" +#include "s_span.h" + + + +/* + * Apply logic op to array of CI pixels. + */ +static void index_logicop( GLcontext *ctx, GLuint n, + GLuint index[], const GLuint dest[], + const GLubyte mask[] ) +{ + GLuint i; + switch (ctx->Color.LogicOp) { + case GL_CLEAR: + for (i=0;iDriver.ReadCI32Span)( ctx, n, x, y, dest ); + index_logicop( ctx, n, index, dest, mask ); +} + + + +/* + * Apply the current logic operator to an array of CI pixels. This is only + * used if the device driver can't do logic ops. + */ +void +_mesa_logicop_ci_pixels( GLcontext *ctx, + GLuint n, const GLint x[], const GLint y[], + GLuint index[], const GLubyte mask[] ) +{ + SWcontext *swrast = SWRAST_CONTEXT(ctx); + GLuint dest[PB_SIZE]; + /* Read dest values from frame buffer */ + (*swrast->Driver.ReadCI32Pixels)( ctx, n, x, y, dest, mask ); + index_logicop( ctx, n, index, dest, mask ); +} + + + +/* + * Apply logic operator to rgba pixels. + * Input: ctx - the context + * n - number of pixels + * mask - pixel mask array + * In/Out: src - incoming pixels which will be modified + * Input: dest - frame buffer values + * + * Note: Since the R, G, B, and A channels are all treated the same we + * process them as 4-byte GLuints instead of four GLubytes. + */ +static void rgba_logicop_ui( const GLcontext *ctx, GLuint n, + const GLubyte mask[], + GLuint src[], const GLuint dest[] ) +{ + GLuint i; + switch (ctx->Color.LogicOp) { + case GL_CLEAR: + for (i=0;iColor.LogicOp) { + case GL_CLEAR: + for (i=0;iDrawBuffer, n, x, y, dest ); + if (sizeof(GLchan) * 4 == sizeof(GLuint)) { + rgba_logicop_ui(ctx, n, mask, (GLuint *) rgba, (const GLuint *) dest); + } + else { + rgba_logicop_chan(ctx, 4 * n, mask, + (GLchan *) rgba, (const GLchan *) dest); + } +} + + + +/* + * Apply the current logic operator to an array of RGBA pixels. + * This is only used if the device driver can't do logic ops. + */ +void +_mesa_logicop_rgba_pixels( GLcontext *ctx, + GLuint n, const GLint x[], const GLint y[], + GLchan rgba[][4], const GLubyte mask[] ) +{ + SWcontext *swrast = SWRAST_CONTEXT(ctx); + GLchan dest[PB_SIZE][4]; + (*swrast->Driver.ReadRGBAPixels)( ctx, n, x, y, dest, mask ); + if (SWRAST_CONTEXT(ctx)->_RasterMask & ALPHABUF_BIT) { + _mesa_read_alpha_pixels( ctx, n, x, y, dest, mask ); + } + if (sizeof(GLchan) * 4 == sizeof(GLuint)) { + rgba_logicop_ui(ctx, n, mask, (GLuint *) rgba, (const GLuint *) dest); + } + else { + rgba_logicop_chan(ctx, 4 * n, mask, + (GLchan *) rgba, (const GLchan *) dest); + } +} Index: dll/opengl/opengl32/mesa/swrast/s_logic.h =================================================================== --- dll/opengl/opengl32/mesa/swrast/s_logic.h (revision 0) +++ dll/opengl/opengl32/mesa/swrast/s_logic.h (working copy) @@ -0,0 +1,59 @@ +/* $Id: s_logic.h,v 1.3 2001/03/12 00:48:42 gareth Exp $ */ + +/* + * Mesa 3-D graphics library + * Version: 3.5 + * + * Copyright (C) 1999-2001 Brian Paul 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 + * BRIAN PAUL 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. + */ + + +#ifndef S_LOGIC_H +#define S_LOGIC_H + + +#include "mtypes.h" +#include "swrast.h" + + +extern void +_mesa_logicop_ci_span( GLcontext *ctx, + GLuint n, GLint x, GLint y, GLuint index[], + const GLubyte mask[] ); + + +extern void +_mesa_logicop_ci_pixels( GLcontext *ctx, + GLuint n, const GLint x[], const GLint y[], + GLuint index[], const GLubyte mask[] ); + + +extern void +_mesa_logicop_rgba_span( GLcontext *ctx, GLuint n, GLint x, GLint y, + GLchan rgba[][4], const GLubyte mask[] ); + + +extern void +_mesa_logicop_rgba_pixels( GLcontext *ctx, + GLuint n, const GLint x[], const GLint y[], + GLchan rgba[][4], const GLubyte mask[] ); + + +#endif Index: dll/opengl/opengl32/mesa/swrast/s_masking.c =================================================================== --- dll/opengl/opengl32/mesa/swrast/s_masking.c (revision 0) +++ dll/opengl/opengl32/mesa/swrast/s_masking.c (working copy) @@ -0,0 +1,182 @@ +/* $Id: s_masking.c,v 1.5 2001/03/19 02:25:36 keithw Exp $ */ + +/* + * Mesa 3-D graphics library + * Version: 3.5 + * + * Copyright (C) 1999-2001 Brian Paul 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 + * BRIAN PAUL 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. + */ + + +/* + * Implement the effect of glColorMask and glIndexMask in software. + */ + + +#include "glheader.h" +#include "enums.h" +#include "macros.h" + +#include "s_alphabuf.h" +#include "s_context.h" +#include "s_masking.h" +#include "s_pb.h" +#include "s_span.h" + + +/* + * Apply glColorMask to a span of RGBA pixels. + */ +void +_mesa_mask_rgba_span( GLcontext *ctx, + GLuint n, GLint x, GLint y, GLchan rgba[][4] ) +{ + GLchan dest[MAX_WIDTH][4]; + GLuint i; + +#if CHAN_BITS == 8 + + GLuint srcMask = *((GLuint*)ctx->Color.ColorMask); + GLuint dstMask = ~srcMask; + GLuint *rgba32 = (GLuint *) rgba; + GLuint *dest32 = (GLuint *) dest; + + _mesa_read_rgba_span( ctx, ctx->DrawBuffer, n, x, y, dest ); + for (i = 0; i < n; i++) { + rgba32[i] = (rgba32[i] & srcMask) | (dest32[i] & dstMask); + } + +#else + + const GLint rMask = ctx->Color.ColorMask[RCOMP]; + const GLint gMask = ctx->Color.ColorMask[GCOMP]; + const GLint bMask = ctx->Color.ColorMask[BCOMP]; + const GLint aMask = ctx->Color.ColorMask[ACOMP]; + + _mesa_read_rgba_span( ctx, ctx->DrawBuffer, n, x, y, dest ); + for (i = 0; i < n; i++) { + if (!rMask) rgba[i][RCOMP] = dest[i][RCOMP]; + if (!gMask) rgba[i][GCOMP] = dest[i][GCOMP]; + if (!bMask) rgba[i][BCOMP] = dest[i][BCOMP]; + if (!aMask) rgba[i][ACOMP] = dest[i][ACOMP]; + } + +#endif +} + + + +/* + * Apply glColorMask to an array of RGBA pixels. + */ +void +_mesa_mask_rgba_pixels( GLcontext *ctx, + GLuint n, const GLint x[], const GLint y[], + GLchan rgba[][4], const GLubyte mask[] ) +{ + SWcontext *swrast = SWRAST_CONTEXT(ctx); + GLchan dest[PB_SIZE][4]; + GLuint i; + +#if CHAN_BITS == 8 + + GLuint srcMask = *((GLuint*)ctx->Color.ColorMask); + GLuint dstMask = ~srcMask; + GLuint *rgba32 = (GLuint *) rgba; + GLuint *dest32 = (GLuint *) dest; + + (*swrast->Driver.ReadRGBAPixels)( ctx, n, x, y, dest, mask ); + if (SWRAST_CONTEXT(ctx)->_RasterMask & ALPHABUF_BIT) { + _mesa_read_alpha_pixels( ctx, n, x, y, dest, mask ); + } + + for (i=0; iColor.ColorMask[RCOMP]; + const GLint gMask = ctx->Color.ColorMask[GCOMP]; + const GLint bMask = ctx->Color.ColorMask[BCOMP]; + const GLint aMask = ctx->Color.ColorMask[ACOMP]; + + (*swrast->Driver.ReadRGBAPixels)( ctx, n, x, y, dest, mask ); + if (SWRAST_CONTEXT(ctx)->_RasterMask & ALPHABUF_BIT) { + _mesa_read_alpha_pixels( ctx, n, x, y, dest, mask ); + } + + for (i = 0; i < n; i++) { + if (!rMask) rgba[i][RCOMP] = dest[i][RCOMP]; + if (!gMask) rgba[i][GCOMP] = dest[i][GCOMP]; + if (!bMask) rgba[i][BCOMP] = dest[i][BCOMP]; + if (!aMask) rgba[i][ACOMP] = dest[i][ACOMP]; + } + +#endif +} + + + +/* + * Apply glIndexMask to a span of CI pixels. + */ +void +_mesa_mask_index_span( GLcontext *ctx, + GLuint n, GLint x, GLint y, GLuint index[] ) +{ + GLuint i; + GLuint fbindexes[MAX_WIDTH]; + GLuint msrc, mdest; + + _mesa_read_index_span( ctx, ctx->DrawBuffer, n, x, y, fbindexes ); + + msrc = ctx->Color.IndexMask; + mdest = ~msrc; + + for (i=0;iDriver.ReadCI32Pixels)( ctx, n, x, y, fbindexes, mask ); + + msrc = ctx->Color.IndexMask; + mdest = ~msrc; + + for (i=0;imono = GL_TRUE; + + /* Set all lambda values to 0.0 since we don't do mipmapping for + * points or lines and want to use the level 0 texture image. + */ + for (j=0;jlambda[j][i] = 0.0; + } + } + } + return pb; +} + + + +/* + * Draw to more than one color buffer (or none). + */ +static void multi_write_index_pixels( GLcontext *ctx, GLuint n, + const GLint x[], const GLint y[], + const GLuint indexes[], + const GLubyte mask[] ) +{ + SWcontext *swrast = SWRAST_CONTEXT(ctx); + GLuint bufferBit; + + if (ctx->Color.DrawBuffer == GL_NONE) + return; + + /* loop over four possible dest color buffers */ + for (bufferBit = 1; bufferBit <= 8; bufferBit = bufferBit << 1) { + if (bufferBit & ctx->Color.DrawDestMask) { + GLuint indexTmp[PB_SIZE]; + ASSERT(n < PB_SIZE); + + if (bufferBit == FRONT_LEFT_BIT) + (void) (*ctx->Driver.SetDrawBuffer)( ctx, GL_FRONT_LEFT); + else if (bufferBit == FRONT_RIGHT_BIT) + (void) (*ctx->Driver.SetDrawBuffer)( ctx, GL_FRONT_RIGHT); + else if (bufferBit == BACK_LEFT_BIT) + (void) (*ctx->Driver.SetDrawBuffer)( ctx, GL_BACK_LEFT); + else + (void) (*ctx->Driver.SetDrawBuffer)( ctx, GL_BACK_RIGHT); + + /* make copy of incoming indexes */ + MEMCPY( indexTmp, indexes, n * sizeof(GLuint) ); + if (ctx->Color.IndexLogicOpEnabled) { + _mesa_logicop_ci_pixels( ctx, n, x, y, indexTmp, mask ); + } + if (ctx->Color.IndexMask != 0xffffffff) { + _mesa_mask_index_pixels( ctx, n, x, y, indexTmp, mask ); + } + (*swrast->Driver.WriteCI32Pixels)( ctx, n, x, y, indexTmp, mask ); + } + } + + /* restore default dest buffer */ + (void) (*ctx->Driver.SetDrawBuffer)( ctx, ctx->Color.DriverDrawBuffer); +} + + + +/* + * Draw to more than one RGBA color buffer (or none). + */ +static void multi_write_rgba_pixels( GLcontext *ctx, GLuint n, + const GLint x[], const GLint y[], + CONST GLchan rgba[][4], + const GLubyte mask[] ) +{ + SWcontext *swrast = SWRAST_CONTEXT(ctx); + GLuint bufferBit; + + if (ctx->Color.DrawBuffer == GL_NONE) + return; + + /* loop over four possible dest color buffers */ + for (bufferBit = 1; bufferBit <= 8; bufferBit = bufferBit << 1) { + if (bufferBit & ctx->Color.DrawDestMask) { + GLchan rgbaTmp[PB_SIZE][4]; + ASSERT(n < PB_SIZE); + + if (bufferBit == FRONT_LEFT_BIT) { + (void) (*ctx->Driver.SetDrawBuffer)( ctx, GL_FRONT_LEFT); + ctx->DrawBuffer->Alpha = ctx->DrawBuffer->FrontLeftAlpha; + } + else if (bufferBit == FRONT_RIGHT_BIT) { + (void) (*ctx->Driver.SetDrawBuffer)( ctx, GL_FRONT_RIGHT); + ctx->DrawBuffer->Alpha = ctx->DrawBuffer->FrontRightAlpha; + } + else if (bufferBit == BACK_LEFT_BIT) { + (void) (*ctx->Driver.SetDrawBuffer)( ctx, GL_BACK_LEFT); + ctx->DrawBuffer->Alpha = ctx->DrawBuffer->BackLeftAlpha; + } + else { + (void) (*ctx->Driver.SetDrawBuffer)( ctx, GL_BACK_RIGHT); + ctx->DrawBuffer->Alpha = ctx->DrawBuffer->BackRightAlpha; + } + + /* make copy of incoming colors */ + MEMCPY( rgbaTmp, rgba, 4 * n * sizeof(GLchan) ); + + if (ctx->Color.ColorLogicOpEnabled) { + _mesa_logicop_rgba_pixels( ctx, n, x, y, rgbaTmp, mask ); + } + else if (ctx->Color.BlendEnabled) { + _mesa_blend_pixels( ctx, n, x, y, rgbaTmp, mask ); + } + if (*((GLuint *) &ctx->Color.ColorMask) != 0xffffffff) { + _mesa_mask_rgba_pixels( ctx, n, x, y, rgbaTmp, mask ); + } + + (*swrast->Driver.WriteRGBAPixels)( ctx, n, x, y, + (const GLchan (*)[4])rgbaTmp, mask ); + if (SWRAST_CONTEXT(ctx)->_RasterMask & ALPHABUF_BIT) { + _mesa_write_alpha_pixels( ctx, n, x, y, + (const GLchan (*)[4])rgbaTmp, mask ); + } + } + } + + /* restore default dest buffer */ + (void) (*ctx->Driver.SetDrawBuffer)( ctx, ctx->Color.DriverDrawBuffer); +} + + + +/* + * Add specular color to primary color. This is used only when + * GL_LIGHT_MODEL_COLOR_CONTROL = GL_SEPARATE_SPECULAR_COLOR. + */ +static void add_colors( GLuint n, GLchan rgba[][4], CONST GLchan spec[][3] ) +{ + GLuint i; + for (i=0; i_RasterMask; + + /* Pixel colors may be changed if any of these raster ops enabled */ + const GLuint modBits = FOG_BIT | TEXTURE_BIT | BLEND_BIT | + MASKING_BIT | LOGIC_OP_BIT; + struct pixel_buffer *PB = swrast->PB; + GLubyte mask[PB_SIZE]; + + if (PB->count == 0) + goto CleanUp; + + /* initialize mask array and clip pixels simultaneously */ + { + const GLint xmin = ctx->DrawBuffer->_Xmin; + const GLint xmax = ctx->DrawBuffer->_Xmax; + const GLint ymin = ctx->DrawBuffer->_Ymin; + const GLint ymax = ctx->DrawBuffer->_Ymax; + const GLuint n = PB->count; + GLint *x = PB->x; + GLint *y = PB->y; + GLuint i; + for (i = 0; i < n; i++) { + mask[i] = (x[i] >= xmin) & (x[i] < xmax) & (y[i] >= ymin) & (y[i] < ymax); + } + } + + if (ctx->Visual.rgbMode) { + /* + * RGBA COLOR PIXELS + */ + + /* If each pixel can be of a different color... */ + if ((RasterMask & modBits) || !PB->mono) { + + if (ctx->Texture._ReallyEnabled) { + GLchan primary_rgba[PB_SIZE][4]; + GLuint texUnit; + + /* must make a copy of primary colors since they may be modified */ + MEMCPY(primary_rgba, PB->rgba, 4 * PB->count * sizeof(GLchan)); + + for (texUnit = 0; texUnit < ctx->Const.MaxTextureUnits; texUnit++){ + _swrast_texture_fragments( ctx, texUnit, PB->count, + PB->s[texUnit], PB->t[texUnit], + PB->u[texUnit], PB->lambda[texUnit], + (CONST GLchan (*)[4]) primary_rgba, + PB->rgba ); + } + } + + if ((ctx->Fog.ColorSumEnabled || + (ctx->Light.Model.ColorControl == GL_SEPARATE_SPECULAR_COLOR + && ctx->Light.Enabled)) && PB->haveSpec) { + /* add specular color to primary color */ + add_colors( PB->count, PB->rgba, (const GLchan (*)[3]) PB->spec ); + } + + if (ctx->Fog.Enabled) { + if (swrast->_PreferPixelFog) + _mesa_depth_fog_rgba_pixels( ctx, PB->count, PB->z, PB->rgba ); + else + _mesa_fog_rgba_pixels( ctx, PB->count, PB->fog, PB->rgba ); + } + + /* Antialias coverage application */ + if (PB->haveCoverage) { + const GLuint n = PB->count; + GLuint i; + for (i = 0; i < n; i++) { + PB->rgba[i][ACOMP] = (GLchan) (PB->rgba[i][ACOMP] * PB->coverage[i]); + } + } + + /* Scissoring already done above */ + + if (ctx->Color.AlphaEnabled) { + if (_mesa_alpha_test( ctx, PB->count, + (const GLchan (*)[4]) PB->rgba, mask )==0) { + goto CleanUp; + } + } + + if (ctx->Stencil.Enabled) { + /* first stencil test */ + if (_mesa_stencil_and_ztest_pixels(ctx, PB->count, + PB->x, PB->y, PB->z, mask) == 0) { + goto CleanUp; + } + } + else if (ctx->Depth.Test) { + /* regular depth testing */ + _mesa_depth_test_pixels( ctx, PB->count, PB->x, PB->y, PB->z, mask ); + } + + + if (RasterMask & MULTI_DRAW_BIT) { + multi_write_rgba_pixels( ctx, PB->count, PB->x, PB->y, + (const GLchan (*)[4])PB->rgba, mask ); + } + else { + /* normal case: write to exactly one buffer */ + const GLuint colorMask = *((GLuint *) ctx->Color.ColorMask); + + if (ctx->Color.ColorLogicOpEnabled) { + _mesa_logicop_rgba_pixels( ctx, PB->count, PB->x, PB->y, + PB->rgba, mask); + } + else if (ctx->Color.BlendEnabled) { + _mesa_blend_pixels( ctx, PB->count, PB->x, PB->y, PB->rgba, mask); + } + if (colorMask == 0x0) { + goto CleanUp; + } + else if (colorMask != 0xffffffff) { + _mesa_mask_rgba_pixels(ctx, PB->count, PB->x, PB->y, PB->rgba, mask); + } + + (*swrast->Driver.WriteRGBAPixels)( ctx, PB->count, PB->x, PB->y, + (const GLchan (*)[4]) PB->rgba, + mask ); + if (RasterMask & ALPHABUF_BIT) { + _mesa_write_alpha_pixels( ctx, PB->count, PB->x, PB->y, + (const GLchan (*)[4]) PB->rgba, mask ); + } + } + } + else { + /* Same color for all pixels */ + + /* Scissoring already done above */ + + if (ctx->Color.AlphaEnabled) { + if (_mesa_alpha_test( ctx, PB->count, + (const GLchan (*)[4]) PB->rgba, mask )==0) { + goto CleanUp; + } + } + + if (ctx->Stencil.Enabled) { + /* first stencil test */ + if (_mesa_stencil_and_ztest_pixels(ctx, PB->count, + PB->x, PB->y, PB->z, mask) == 0) { + goto CleanUp; + } + } + else if (ctx->Depth.Test) { + /* regular depth testing */ + _mesa_depth_test_pixels( ctx, PB->count, PB->x, PB->y, PB->z, mask ); + } + + if (ctx->Color.DrawBuffer == GL_NONE) { + goto CleanUp; + } + + if (RasterMask & MULTI_DRAW_BIT) { + /* Copy mono color to all pixels */ + multi_write_rgba_pixels( ctx, PB->count, PB->x, PB->y, + (const GLchan (*)[4]) PB->rgba, mask ); + } + else { + /* normal case: write to exactly one buffer */ + (*swrast->Driver.WriteMonoRGBAPixels)( ctx, PB->count, PB->x, PB->y, + PB->currentColor, mask ); + if (RasterMask & ALPHABUF_BIT) { + _mesa_write_mono_alpha_pixels( ctx, PB->count, PB->x, PB->y, + PB->currentColor[ACOMP], mask ); + } + } + /*** ALL DONE ***/ + } + } + else { + /* + * COLOR INDEX PIXELS + */ + + /* If we may be writting pixels with different indexes... */ + if ((RasterMask & modBits) || !PB->mono) { + + if (PB->mono) { + GLuint i; + for (i = 0; i < PB->count; i++) { + PB->index[i] = PB->currentIndex; + } + } + if (ctx->Fog.Enabled) { + if (swrast->_PreferPixelFog) + _mesa_depth_fog_ci_pixels( ctx, PB->count, PB->z, PB->index ); + else + _mesa_fog_ci_pixels( ctx, PB->count, PB->fog, PB->index ); + } + + /* Antialias coverage application */ + if (PB->haveCoverage) { + const GLuint n = PB->count; + GLuint i; + for (i = 0; i < n; i++) { + GLint frac = (GLint) (15.0 * PB->coverage[i]); + PB->index[i] = (PB->index[i] & ~0xf) | frac; + } + } + + /* Scissoring already done above */ + + if (ctx->Stencil.Enabled) { + /* first stencil test */ + if (_mesa_stencil_and_ztest_pixels(ctx, PB->count, + PB->x, PB->y, PB->z, mask) == 0) { + goto CleanUp; + } + } + else if (ctx->Depth.Test) { + /* regular depth testing */ + _mesa_depth_test_pixels( ctx, PB->count, PB->x, PB->y, PB->z, mask ); + } + if (RasterMask & MULTI_DRAW_BIT) { + multi_write_index_pixels( ctx, PB->count, PB->x, PB->y, PB->index, mask ); + } + else { + /* normal case: write to exactly one buffer */ + + if (ctx->Color.IndexLogicOpEnabled) { + _mesa_logicop_ci_pixels(ctx, PB->count, PB->x, PB->y, + PB->index, mask); + } + if (ctx->Color.IndexMask != 0xffffffff) { + _mesa_mask_index_pixels(ctx, PB->count, PB->x, PB->y, + PB->index, mask); + } + (*swrast->Driver.WriteCI32Pixels)( ctx, PB->count, PB->x, PB->y, + PB->index, mask ); + } + + /*** ALL DONE ***/ + } + else { + /* Same color index for all pixels */ + + /* Scissoring already done above */ + + if (ctx->Stencil.Enabled) { + /* first stencil test */ + if (_mesa_stencil_and_ztest_pixels(ctx, PB->count, + PB->x, PB->y, PB->z, mask) == 0) { + goto CleanUp; + } + } + else if (ctx->Depth.Test) { + /* regular depth testing */ + _mesa_depth_test_pixels(ctx, PB->count, PB->x, PB->y, PB->z, mask); + } + + if (RasterMask & MULTI_DRAW_BIT) { + multi_write_index_pixels(ctx, PB->count, PB->x, PB->y, + PB->index, mask); + } + else { + /* normal case: write to exactly one buffer */ + (*swrast->Driver.WriteMonoCIPixels)(ctx, PB->count, PB->x, PB->y, + PB->currentIndex, mask); + } + } + } + +CleanUp: + PB->count = 0; + PB->mono = GL_TRUE; + PB->haveSpec = GL_FALSE; + PB->haveCoverage = GL_FALSE; +} + + +void +_swrast_flush( GLcontext *ctx ) +{ + if (SWRAST_CONTEXT(ctx)->PB->count > 0) + _mesa_flush_pb(ctx); +} Index: dll/opengl/opengl32/mesa/swrast/s_pb.h =================================================================== --- dll/opengl/opengl32/mesa/swrast/s_pb.h (revision 0) +++ dll/opengl/opengl32/mesa/swrast/s_pb.h (working copy) @@ -0,0 +1,244 @@ +/* $Id: s_pb.h,v 1.10 2001/05/15 21:30:27 brianp Exp $ */ + +/* + * Mesa 3-D graphics library + * Version: 3.5 + * + * Copyright (C) 1999-2001 Brian Paul 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 + * BRIAN PAUL 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. + */ + + +#ifndef PB_H +#define PB_H + + +#include "mtypes.h" +#include "swrast.h" +#include "colormac.h" + + +/* + * Pixel buffer size, must be larger than MAX_WIDTH. + */ +#define PB_SIZE (3*MAX_WIDTH) + + +struct pixel_buffer { + GLchan currentColor[4]; /* Current color, for subsequent pixels */ + GLuint currentIndex; /* Current index, for subsequent pixels */ + GLuint count; /* Number of pixels in buffer */ + GLboolean mono; /* Same color or index for all pixels? */ + GLboolean haveSpec; /* any specular colors? */ + GLboolean haveCoverage; /* apply AA coverage? */ + + GLint x[PB_SIZE]; /* X window coord in [0,MAX_WIDTH) */ + GLint y[PB_SIZE]; /* Y window coord in [0,MAX_HEIGHT) */ + GLdepth z[PB_SIZE]; /* Z window coord in [0,Visual.MaxDepth] */ + GLfloat fog[PB_SIZE]; /* Fog window coord in [0,1] */ + GLchan rgba[PB_SIZE][4]; /* Colors */ + GLchan spec[PB_SIZE][3]; /* Separate specular colors */ + GLuint index[PB_SIZE]; /* Color indexes */ + GLfloat coverage[PB_SIZE]; /* Antialiasing coverage in [0,1] */ + GLfloat s[MAX_TEXTURE_UNITS][PB_SIZE]; /* Texture S coordinates */ + GLfloat t[MAX_TEXTURE_UNITS][PB_SIZE]; /* Texture T coordinates */ + GLfloat u[MAX_TEXTURE_UNITS][PB_SIZE]; /* Texture R coordinates */ + GLfloat lambda[MAX_TEXTURE_UNITS][PB_SIZE]; /* Texture lambda values */ +}; + + + +/* + * Set the color used for all subsequent pixels in the buffer. + */ +#define PB_SET_COLOR( PB, R, G, B, A ) \ +do { \ + if ((PB)->count > 0) \ + (PB)->mono = GL_FALSE; \ + (PB)->currentColor[RCOMP] = (R); \ + (PB)->currentColor[GCOMP] = (G); \ + (PB)->currentColor[BCOMP] = (B); \ + (PB)->currentColor[ACOMP] = (A); \ +} while (0) + + +/* + * Set the color index used for all subsequent pixels in the buffer. + */ +#define PB_SET_INDEX( PB, I ) \ +do { \ + if ((PB)->count > 0) \ + (PB)->mono = GL_FALSE; \ + (PB)->currentIndex = (I); \ +} while (0) + + +/* + * "write" a pixel using current color or index + */ +#define PB_WRITE_PIXEL( PB, X, Y, Z, FOG ) \ +do { \ + GLuint count = (PB)->count; \ + (PB)->x[count] = X; \ + (PB)->y[count] = Y; \ + (PB)->z[count] = Z; \ + (PB)->fog[count] = FOG; \ + COPY_CHAN4((PB)->rgba[count], (PB)->currentColor); \ + (PB)->index[count] = (PB)->currentIndex; \ + (PB)->count++; \ +} while (0) + + +/* + * "write" an RGBA pixel + */ +#define PB_WRITE_RGBA_PIXEL( PB, X, Y, Z, FOG, R, G, B, A ) \ +do { \ + GLuint count = (PB)->count; \ + (PB)->x[count] = X; \ + (PB)->y[count] = Y; \ + (PB)->z[count] = Z; \ + (PB)->fog[count] = FOG; \ + (PB)->rgba[count][RCOMP] = R; \ + (PB)->rgba[count][GCOMP] = G; \ + (PB)->rgba[count][BCOMP] = B; \ + (PB)->rgba[count][ACOMP] = A; \ + (PB)->mono = GL_FALSE; \ + (PB)->count++; \ +} while (0) + + +/* + * "write" a color-index pixel + */ +#define PB_WRITE_CI_PIXEL( PB, X, Y, Z, FOG, I ) \ +do { \ + GLuint count = (PB)->count; \ + (PB)->x[count] = X; \ + (PB)->y[count] = Y; \ + (PB)->z[count] = Z; \ + (PB)->fog[count] = FOG; \ + (PB)->index[count] = I; \ + (PB)->mono = GL_FALSE; \ + (PB)->count++; \ +} while (0) + + + +/* + * "write" an RGBA pixel with texture coordinates + */ +#define PB_WRITE_TEX_PIXEL( PB, X, Y, Z, FOG, R, G, B, A, S, T, U ) \ +do { \ + GLuint count = (PB)->count; \ + (PB)->x[count] = X; \ + (PB)->y[count] = Y; \ + (PB)->z[count] = Z; \ + (PB)->fog[count] = FOG; \ + (PB)->rgba[count][RCOMP] = R; \ + (PB)->rgba[count][GCOMP] = G; \ + (PB)->rgba[count][BCOMP] = B; \ + (PB)->rgba[count][ACOMP] = A; \ + (PB)->s[0][count] = S; \ + (PB)->t[0][count] = T; \ + (PB)->u[0][count] = U; \ + (PB)->mono = GL_FALSE; \ + (PB)->count++; \ +} while (0) + + +/* + * "write" an RGBA pixel with multiple texture coordinates + */ +#define PB_WRITE_MULTITEX_PIXEL( PB, X, Y, Z, FOG, R, G, B, A, TEXCOORDS ) \ +do { \ + GLuint count = (PB)->count; \ + GLuint unit; \ + (PB)->x[count] = X; \ + (PB)->y[count] = Y; \ + (PB)->z[count] = Z; \ + (PB)->fog[count] = FOG; \ + (PB)->rgba[count][RCOMP] = R; \ + (PB)->rgba[count][GCOMP] = G; \ + (PB)->rgba[count][BCOMP] = B; \ + (PB)->rgba[count][ACOMP] = A; \ + for (unit = 0; unit < ctx->Const.MaxTextureUnits; unit++) { \ + if (ctx->Texture.Unit[unit]._ReallyEnabled) { \ + (PB)->s[unit][count] = TEXCOORDS[unit][0]; \ + (PB)->t[unit][count] = TEXCOORDS[unit][1]; \ + (PB)->u[unit][count] = TEXCOORDS[unit][2]; \ + } \ + } \ + (PB)->mono = GL_FALSE; \ + (PB)->count++; \ +} while (0) + + +/* + * "write" an RGBA pixel with multiple texture coordinates and specular color + */ +#define PB_WRITE_MULTITEX_SPEC_PIXEL( PB, X, Y, Z, FOG, R, G, B, A, SR, SG, SB, TEXCOORDS )\ +do { \ + GLuint count = (PB)->count; \ + GLuint unit; \ + (PB)->haveSpec = GL_TRUE; \ + (PB)->x[count] = X; \ + (PB)->y[count] = Y; \ + (PB)->z[count] = Z; \ + (PB)->fog[count] = FOG; \ + (PB)->rgba[count][RCOMP] = R; \ + (PB)->rgba[count][GCOMP] = G; \ + (PB)->rgba[count][BCOMP] = B; \ + (PB)->rgba[count][ACOMP] = A; \ + (PB)->spec[count][RCOMP] = SR; \ + (PB)->spec[count][GCOMP] = SG; \ + (PB)->spec[count][BCOMP] = SB; \ + for (unit = 0; unit < ctx->Const.MaxTextureUnits; unit++) { \ + if (ctx->Texture.Unit[unit]._ReallyEnabled) { \ + (PB)->s[unit][count] = TEXCOORDS[unit][0]; \ + (PB)->t[unit][count] = TEXCOORDS[unit][1]; \ + (PB)->u[unit][count] = TEXCOORDS[unit][2]; \ + } \ + } \ + (PB)->mono = GL_FALSE; \ + (PB)->count++; \ +} while (0) + + +#define PB_COVERAGE(PB, COVERAGE) \ + (PB)->coverage[(PB)->count] = COVERAGE; + + +/* + * Call this function at least every MAX_WIDTH pixels: + */ +#define PB_CHECK_FLUSH( CTX, PB ) \ +do { \ + if ((PB)->count >= PB_SIZE - MAX_WIDTH) { \ + _mesa_flush_pb( CTX ); \ + } \ +} while(0) + + +extern struct pixel_buffer *_mesa_alloc_pb(void); + +extern void _mesa_flush_pb( GLcontext *ctx ); + + +#endif Index: dll/opengl/opengl32/mesa/swrast/s_pixeltex.c =================================================================== --- dll/opengl/opengl32/mesa/swrast/s_pixeltex.c (revision 0) +++ dll/opengl/opengl32/mesa/swrast/s_pixeltex.c (working copy) @@ -0,0 +1,81 @@ +/* $Id: s_pixeltex.c,v 1.3 2001/03/12 00:48:42 gareth Exp $ */ + +/* + * Mesa 3-D graphics library + * Version: 3.5 + * + * Copyright (C) 1999-2001 Brian Paul 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 + * BRIAN PAUL 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. + */ + + +/* + * This file implements both the GL_SGIX_pixel_texture and + * GL_SIGS_pixel_texture extensions. Luckily, they pretty much + * overlap in functionality so we use the same state variables + * and execution code for both. + */ + + +#include "glheader.h" +#include "colormac.h" + +#include "s_context.h" +#include "s_pixeltex.h" + + +/* + * Convert RGBA values into strq texture coordinates. + */ +void +_mesa_pixeltexgen(GLcontext *ctx, GLuint n, const GLchan rgba[][4], + GLfloat s[], GLfloat t[], GLfloat r[], GLfloat q[]) +{ + if (ctx->Pixel.FragmentRgbSource == GL_CURRENT_RASTER_COLOR) { + GLuint i; + for (i = 0; i < n; i++) { + s[i] = ctx->Current.RasterColor[RCOMP]; + t[i] = ctx->Current.RasterColor[GCOMP]; + r[i] = ctx->Current.RasterColor[BCOMP]; + } + } + else { + GLuint i; + ASSERT(ctx->Pixel.FragmentRgbSource == GL_PIXEL_GROUP_COLOR_SGIS); + for (i = 0; i < n; i++) { + s[i] = CHAN_TO_FLOAT(rgba[i][RCOMP]); + t[i] = CHAN_TO_FLOAT(rgba[i][GCOMP]); + r[i] = CHAN_TO_FLOAT(rgba[i][BCOMP]); + } + } + + if (ctx->Pixel.FragmentAlphaSource == GL_CURRENT_RASTER_COLOR) { + GLuint i; + for (i = 0; i < n; i++) { + q[i] = ctx->Current.RasterColor[ACOMP]; + } + } + else { + GLuint i; + ASSERT(ctx->Pixel.FragmentAlphaSource == GL_PIXEL_GROUP_COLOR_SGIS); + for (i = 0; i < n; i++) { + q[i] = CHAN_TO_FLOAT(rgba[i][ACOMP]); + } + } +} Index: dll/opengl/opengl32/mesa/swrast/s_pixeltex.h =================================================================== --- dll/opengl/opengl32/mesa/swrast/s_pixeltex.h (revision 0) +++ dll/opengl/opengl32/mesa/swrast/s_pixeltex.h (working copy) @@ -0,0 +1,39 @@ +/* $Id: s_pixeltex.h,v 1.3 2001/03/12 00:48:42 gareth Exp $ */ + +/* + * Mesa 3-D graphics library + * Version: 3.5 + * + * Copyright (C) 1999-2001 Brian Paul 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 + * BRIAN PAUL 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. + */ + + +#ifndef S_PIXELTEX_H +#define S_PIXELTEX_H + +#include "mtypes.h" +#include "swrast.h" + +extern void +_mesa_pixeltexgen(GLcontext *ctx, GLuint n, const GLchan rgba[][4], + GLfloat s[], GLfloat t[], GLfloat r[], GLfloat q[]); + + +#endif Index: dll/opengl/opengl32/mesa/swrast/s_points.c =================================================================== --- dll/opengl/opengl32/mesa/swrast/s_points.c (revision 0) +++ dll/opengl/opengl32/mesa/swrast/s_points.c (working copy) @@ -0,0 +1,256 @@ +/* $Id: s_points.c,v 1.15 2001/03/12 00:48:42 gareth Exp $ */ + +/* + * Mesa 3-D graphics library + * Version: 3.5 + * + * Copyright (C) 1999-2001 Brian Paul 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 + * BRIAN PAUL 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. + */ + + +#include "glheader.h" +#include "colormac.h" +#include "context.h" +#include "macros.h" +#include "mmath.h" +#include "texstate.h" +#include "s_context.h" +#include "s_feedback.h" +#include "s_pb.h" +#include "s_points.h" +#include "s_span.h" + + + +#define INDEX 0x0 +#define RGBA 0x1 +#define SMOOTH 0x2 +#define TEXTURE 0x4 +#define SPECULAR 0x8 +#define LARGE 0x10 +#define ATTENUATE 0x20 +#define SPRITE 0x40 + + +/* + * CI points with size == 1.0 + */ +#define FLAGS (INDEX) +#define NAME size1_ci_point +#include "s_pointtemp.h" + + +/* + * General CI points. + */ +#define FLAGS (INDEX | LARGE) +#define NAME general_ci_point +#include "s_pointtemp.h" + + +/* + * Antialiased CI points. + */ +#define FLAGS (INDEX | SMOOTH) +#define NAME antialiased_ci_point +#include "s_pointtemp.h" + + +/* + * Distance attenuated, general CI points. + */ +#define FLAGS (INDEX | ATTENUATE) +#define NAME atten_general_ci_point +#include "s_pointtemp.h" + + +/* + * RGBA points with size == 1.0 + */ +#define FLAGS (RGBA) +#define NAME size1_rgba_point +#include "s_pointtemp.h" + + +/* + * General RGBA points. + */ +#define FLAGS (RGBA | LARGE) +#define NAME general_rgba_point +#include "s_pointtemp.h" + + +/* + * Antialiased RGBA points. + */ +#define FLAGS (RGBA | SMOOTH) +#define NAME antialiased_rgba_point +#include "s_pointtemp.h" + + +/* + * Textured RGBA points. + */ +#define FLAGS (RGBA | LARGE | TEXTURE | SPECULAR) +#define NAME textured_rgba_point +#include "s_pointtemp.h" + + +/* + * Antialiased points with texture mapping. + */ +#define FLAGS (RGBA | SMOOTH | TEXTURE | SPECULAR) +#define NAME antialiased_tex_rgba_point +#include "s_pointtemp.h" + + +/* + * Distance attenuated, general RGBA points. + */ +#define FLAGS (RGBA | ATTENUATE) +#define NAME atten_general_rgba_point +#include "s_pointtemp.h" + + +/* + * Distance attenuated, textured RGBA points. + */ +#define FLAGS (RGBA | ATTENUATE | TEXTURE | SPECULAR) +#define NAME atten_textured_rgba_point +#include "s_pointtemp.h" + + +/* + * Distance attenuated, antialiased points with or without texture mapping. + */ +#define FLAGS (RGBA | ATTENUATE | TEXTURE | SMOOTH) +#define NAME atten_antialiased_rgba_point +#include "s_pointtemp.h" + +void _swrast_add_spec_terms_point( GLcontext *ctx, + const SWvertex *v0 ) +{ + SWvertex *ncv0 = (SWvertex *)v0; + GLchan c[1][4]; + COPY_CHAN4( c[0], ncv0->color ); + ACC_3V( ncv0->color, ncv0->specular ); + SWRAST_CONTEXT(ctx)->SpecPoint( ctx, ncv0 ); + COPY_CHAN4( ncv0->color, c[0] ); +} + + + +/* record the current point function name */ +#ifdef DEBUG + +static const char *pntFuncName = NULL; + +#define USE(pntFunc) \ +do { \ + pntFuncName = #pntFunc; \ + /*printf("%s\n", pntFuncName);*/ \ + swrast->Point = pntFunc; \ +} while (0) + +#else + +#define USE(pntFunc) swrast->Point = pntFunc + +#endif + + +/* + * Examine the current context to determine which point drawing function + * should be used. + */ +void +_swrast_choose_point( GLcontext *ctx ) +{ + SWcontext *swrast = SWRAST_CONTEXT(ctx); + GLboolean rgbMode = ctx->Visual.rgbMode; + + if (ctx->RenderMode==GL_RENDER) { + if (ctx->Point.SmoothFlag) { + /* Smooth points */ + if (rgbMode) { + if (ctx->Point._Attenuated) { + USE(atten_antialiased_rgba_point); + } + else if (ctx->Texture._ReallyEnabled) { + USE(antialiased_tex_rgba_point); + } + else { + USE(antialiased_rgba_point); + } + } + else { + USE(antialiased_ci_point); + } + } + else if (ctx->Point._Attenuated) { + if (rgbMode) { + if (ctx->Texture._ReallyEnabled) { + if (ctx->Point.SmoothFlag) { + USE(atten_antialiased_rgba_point); + } + else { + USE(atten_textured_rgba_point); + } + } + else { + USE(atten_general_rgba_point); + } + } + else { + /* ci, atten */ + USE(atten_general_ci_point); + } + } + else if (ctx->Texture._ReallyEnabled && rgbMode) { + /* textured */ + USE(textured_rgba_point); + } + else if (ctx->Point.Size != 1.0) { + /* large points */ + if (rgbMode) { + USE(general_rgba_point); + } + else { + USE(general_ci_point); + } + } + else { + /* single pixel points */ + if (rgbMode) { + USE(size1_rgba_point); + } + else { + USE(size1_ci_point); + } + } + } + else if (ctx->RenderMode==GL_FEEDBACK) { + USE(_mesa_feedback_point); + } + else { + /* GL_SELECT mode */ + USE(_mesa_select_point); + } +} Index: dll/opengl/opengl32/mesa/swrast/s_points.h =================================================================== --- dll/opengl/opengl32/mesa/swrast/s_points.h (revision 0) +++ dll/opengl/opengl32/mesa/swrast/s_points.h (working copy) @@ -0,0 +1,40 @@ +/* $Id: s_points.h,v 1.5 2001/03/12 00:48:42 gareth Exp $ */ + +/* + * Mesa 3-D graphics library + * Version: 3.5 + * + * Copyright (C) 1999-2001 Brian Paul 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 + * BRIAN PAUL 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. + */ + + +#ifndef S_POINTS_H +#define S_POINTS_H + +#include "mtypes.h" + +void +_swrast_choose_point( GLcontext *ctx ); + +void +_swrast_add_spec_terms_point( GLcontext *ctx, + const SWvertex *v0 ); + +#endif Index: dll/opengl/opengl32/mesa/swrast/s_pointtemp.h =================================================================== --- dll/opengl/opengl32/mesa/swrast/s_pointtemp.h (revision 0) +++ dll/opengl/opengl32/mesa/swrast/s_pointtemp.h (working copy) @@ -0,0 +1,319 @@ +/* $Id: s_pointtemp.h,v 1.8 2001/05/17 09:32:17 keithw Exp $ */ + +/* + * Mesa 3-D graphics library + * Version: 3.5 + * + * Copyright (C) 1999-2001 Brian Paul 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 + * BRIAN PAUL 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. + */ + + +/* + * Point rendering template code. + * + * Set FLAGS = bitwise-OR of the following tokens: + * + * RGBA = do rgba instead of color index + * SMOOTH = do antialiasing + * TEXTURE = do texture coords + * SPECULAR = do separate specular color + * LARGE = do points with diameter > 1 pixel + * ATTENUATE = compute point size attenuation + * + * Notes: LARGE and ATTENUATE are exclusive of each other. + * TEXTURE requires RGBA + * SPECULAR requires TEXTURE + */ + + +/* + * NOTES on antialiased point rasterization: + * + * Let d = distance of fragment center from vertex. + * if d < rmin2 then + * fragment has 100% coverage + * else if d > rmax2 then + * fragment has 0% coverage + * else + * fragement has % coverage = (d - rmin2) / (rmax2 - rmin2) + */ + + + +static void +NAME ( GLcontext *ctx, const SWvertex *vert ) +{ + SWcontext *swrast = SWRAST_CONTEXT(ctx); + struct pixel_buffer *PB = swrast->PB; + + const GLint z = (GLint) (vert->win[2]); + +#if FLAGS & RGBA + const GLint red = vert->color[0]; + const GLint green = vert->color[1]; + const GLint blue = vert->color[2]; + GLint alpha = vert->color[3]; +#if FLAGS & SPECULAR + const GLint sRed = vert->specular[0]; + const GLint sGreen = vert->specular[1]; + const GLint sBlue = vert->specular[2]; +#endif +#else + GLint index = vert->index; +#endif +#if FLAGS & (ATTENUATE | LARGE | SMOOTH) + GLfloat size; +#endif +#if FLAGS & ATTENUATE + GLfloat alphaAtten; +#endif + +#if FLAGS & TEXTURE + GLfloat texcoord[MAX_TEXTURE_UNITS][4]; + GLuint u; + for (u = 0; u < ctx->Const.MaxTextureUnits; u++) { + if (ctx->Texture.Unit[u]._ReallyEnabled) { + if (vert->texcoord[u][3] != 1.0 && vert->texcoord[u][3] != 0.0) { + texcoord[u][0] = vert->texcoord[u][0] / vert->texcoord[u][3]; + texcoord[u][1] = vert->texcoord[u][1] / vert->texcoord[u][3]; + texcoord[u][2] = vert->texcoord[u][2] / vert->texcoord[u][3]; + } + else { + texcoord[u][0] = vert->texcoord[u][0]; + texcoord[u][1] = vert->texcoord[u][1]; + texcoord[u][2] = vert->texcoord[u][2]; + } + } + } +#endif + +#if FLAGS & ATTENUATE + if (vert->pointSize >= ctx->Point.Threshold) { + size = MIN2(vert->pointSize, ctx->Point.MaxSize); + alphaAtten = 1.0F; + } + else { + GLfloat dsize = vert->pointSize / ctx->Point.Threshold; + size = MAX2(ctx->Point.Threshold, ctx->Point.MinSize); + alphaAtten = dsize * dsize; + } +#elif FLAGS & (LARGE | SMOOTH) + size = ctx->Point._Size; +#endif + +#if FLAGS & SPRITE + { + SWcontext *swctx = SWRAST_CONTEXT(ctx); + const GLfloat radius = 0.5 * vert->pointSize; /* XXX threshold, alpha */ + SWvertex v0, v1, v2, v3; + GLuint unit; + + (void) red; + (void) green; + (void) blue; + (void) alpha; + (void) z; + + /* lower left corner */ + v0 = *vert; + v0.win[0] -= radius; + v0.win[1] -= radius; + + /* lower right corner */ + v1 = *vert; + v1.win[0] += radius; + v1.win[1] -= radius; + + /* upper right corner */ + v2 = *vert; + v2.win[0] += radius; + v2.win[1] += radius; + + /* upper left corner */ + v3 = *vert; + v3.win[0] -= radius; + v3.win[1] += radius; + + for (unit = 0; unit < ctx->Const.MaxTextureUnits; unit++) { + if (ctx->Texture.Unit[unit]._ReallyEnabled) { + v0.texcoord[unit][0] = 0.0; + v0.texcoord[unit][1] = 0.0; + v1.texcoord[unit][0] = 1.0; + v1.texcoord[unit][1] = 0.0; + v2.texcoord[unit][0] = 1.0; + v2.texcoord[unit][1] = 1.0; + v3.texcoord[unit][0] = 0.0; + v3.texcoord[unit][1] = 1.0; + } + } + + /* XXX if radius < threshold, attenuate alpha? */ + + /* XXX need to implement clipping!!! */ + + /* render */ + swctx->Triangle(ctx, &v0, &v1, &v2); + swctx->Triangle(ctx, &v0, &v2, &v3); + } + +#elif FLAGS & (LARGE | ATTENUATE | SMOOTH) + + { + GLint x, y; + const GLfloat radius = 0.5F * size; +#if FLAGS & SMOOTH + const GLfloat rmin = radius - 0.7071F; /* 0.7071 = sqrt(2)/2 */ + const GLfloat rmax = radius + 0.7071F; + const GLfloat rmin2 = MAX2(0.0, rmin * rmin); + const GLfloat rmax2 = rmax * rmax; + const GLfloat cscale = 1.0F / (rmax2 - rmin2); + const GLint xmin = (GLint) (vert->win[0] - radius); + const GLint xmax = (GLint) (vert->win[0] + radius); + const GLint ymin = (GLint) (vert->win[1] - radius); + const GLint ymax = (GLint) (vert->win[1] + radius); +#else + /* non-smooth */ + GLint xmin, xmax, ymin, ymax; + GLint iSize = (GLint) (size + 0.5F); + GLint iRadius; + iSize = MAX2(1, iSize); + iRadius = iSize / 2; + if (iSize & 1) { + /* odd size */ + xmin = (GLint) (vert->win[0] - iRadius); + xmax = (GLint) (vert->win[0] + iRadius); + ymin = (GLint) (vert->win[1] - iRadius); + ymax = (GLint) (vert->win[1] + iRadius); + } + else { + /* even size */ + xmin = (GLint) vert->win[0] - iRadius + 1; + xmax = xmin + iSize - 1; + ymin = (GLint) vert->win[1] - iRadius + 1; + ymax = ymin + iSize - 1; + } +#endif + (void) radius; + + for (y = ymin; y <= ymax; y++) { + for (x = xmin; x <= xmax; x++) { +#if FLAGS & SMOOTH + /* compute coverage */ + const GLfloat dx = x - vert->win[0] + 0.5F; + const GLfloat dy = y - vert->win[1] + 0.5F; + const GLfloat dist2 = dx * dx + dy * dy; + if (dist2 < rmax2) { +#if FLAGS & RGBA + alpha = vert->color[3]; +#endif + if (dist2 >= rmin2) { + /* compute partial coverage */ + PB_COVERAGE(PB, 1.0F - (dist2 - rmin2) * cscale); + } + else { + /* full coverage */ + PB_COVERAGE(PB, 1.0F); + } + +#endif /* SMOOTH */ + +#if ((FLAGS & (ATTENUATE | RGBA)) == (ATTENUATE | RGBA)) + alpha = (GLint) (alpha * alphaAtten); +#endif + +#if FLAGS & SPECULAR + PB_WRITE_MULTITEX_SPEC_PIXEL(PB, x, y, z, vert->fog, + red, green, blue, alpha, + sRed, sGreen, sBlue, + texcoord); +#elif FLAGS & TEXTURE + if (ctx->Texture._ReallyEnabled > TEXTURE0_ANY) { + PB_WRITE_MULTITEX_PIXEL(PB, x, y, z, vert->fog, + red, green, blue, alpha, + texcoord); + } + else if (ctx->Texture._ReallyEnabled) { + PB_WRITE_TEX_PIXEL(PB, x,y,z, vert->fog, + red, green, blue, alpha, + texcoord[0][0], + texcoord[0][1], + texcoord[0][2]); + } + else { + PB_WRITE_RGBA_PIXEL(PB, x, y, z, vert->fog, + red, green, blue, alpha); + } +#elif FLAGS & RGBA + PB_WRITE_RGBA_PIXEL(PB, x, y, z, vert->fog, + red, green, blue, alpha); +#else /* color index */ + PB_WRITE_CI_PIXEL(PB, x, y, z, vert->fog, index); +#endif +#if FLAGS & SMOOTH + } +#endif + } + } + +#if FLAGS & SMOOTH + PB->haveCoverage = GL_TRUE; +#endif + + PB_CHECK_FLUSH(ctx,PB); + } + +#else /* LARGE || ATTENUATE || SMOOTH*/ + + { + /* size == 1 */ + GLint x = (GLint) vert->win[0]; + GLint y = (GLint) vert->win[1]; +#if ((FLAGS & (SPECULAR | TEXTURE)) == (SPECULAR | TEXTURE)) + PB_WRITE_MULTITEX_SPEC_PIXEL(PB, x, y, z, vert->fog, + red, green, blue, alpha, + sRed, sGreen, sBlue, + texcoord); +#elif FLAGS & TEXTURE + if (ctx->Texture._ReallyEnabled > TEXTURE0_ANY) { + PB_WRITE_MULTITEX_PIXEL(PB, x, y, z, vert->fog, + red, green, blue, alpha, texcoord ); + } + else { + PB_WRITE_TEX_PIXEL(PB, x, y, z, vert->fog, + red, green, blue, alpha, + texcoord[0][0], texcoord[0][1], texcoord[0][2]); + } +#elif FLAGS & RGBA + /* rgba size 1 point */ + alpha = vert->color[3]; + PB_WRITE_RGBA_PIXEL(PB, x, y, z, vert->fog, red, green, blue, alpha); +#else + /* color index size 1 point */ + PB_WRITE_CI_PIXEL(PB, x, y, z, vert->fog, index); +#endif + } +#endif /* LARGE || ATTENUATE || SMOOTH */ + + PB_CHECK_FLUSH(ctx, PB); +} + + +#undef FLAGS +#undef NAME Index: dll/opengl/opengl32/mesa/swrast/s_readpix.c =================================================================== --- dll/opengl/opengl32/mesa/swrast/s_readpix.c (revision 0) +++ dll/opengl/opengl32/mesa/swrast/s_readpix.c (working copy) @@ -0,0 +1,522 @@ +/* $Id: s_readpix.c,v 1.12 2001/05/16 20:27:12 brianp Exp $ */ + +/* + * Mesa 3-D graphics library + * Version: 3.5 + * + * Copyright (C) 1999-2001 Brian Paul 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 + * BRIAN PAUL 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. + */ + + +#include "glheader.h" +#include "colormac.h" +#include "convolve.h" +#include "context.h" +#include "feedback.h" +#include "image.h" +#include "macros.h" +#include "mem.h" +#include "pixel.h" + +#include "s_alphabuf.h" +#include "s_context.h" +#include "s_depth.h" +#include "s_span.h" +#include "s_stencil.h" + + + +/* + * Read a block of color index pixels. + */ +static void +read_index_pixels( GLcontext *ctx, + GLint x, GLint y, + GLsizei width, GLsizei height, + GLenum type, GLvoid *pixels, + const struct gl_pixelstore_attrib *packing ) +{ + SWcontext *swrast = SWRAST_CONTEXT(ctx); + GLint i, readWidth; + + /* error checking */ + if (ctx->Visual.rgbMode) { + _mesa_error( ctx, GL_INVALID_OPERATION, "glReadPixels" ); + return; + } + + ASSERT(swrast->Driver.SetReadBuffer); + (*swrast->Driver.SetReadBuffer)(ctx, ctx->ReadBuffer, + ctx->Pixel.DriverReadBuffer); + + readWidth = (width > MAX_WIDTH) ? MAX_WIDTH : width; + + /* process image row by row */ + for (i = 0; i < height; i++) { + GLuint index[MAX_WIDTH]; + GLvoid *dest; + + (*swrast->Driver.ReadCI32Span)(ctx, readWidth, x, y + i, index); + + dest = _mesa_image_address(packing, pixels, width, height, + GL_COLOR_INDEX, type, 0, i, 0); + + _mesa_pack_index_span(ctx, readWidth, type, dest, index, + &ctx->Pack, ctx->_ImageTransferState); + } + + (*swrast->Driver.SetReadBuffer)(ctx, ctx->DrawBuffer, + ctx->Color.DriverDrawBuffer); +} + + + +static void +read_depth_pixels( GLcontext *ctx, + GLint x, GLint y, + GLsizei width, GLsizei height, + GLenum type, GLvoid *pixels, + const struct gl_pixelstore_attrib *packing ) +{ + GLint readWidth; + GLboolean bias_or_scale; + + /* Error checking */ + if (ctx->Visual.depthBits <= 0) { + /* No depth buffer */ + _mesa_error( ctx, GL_INVALID_OPERATION, "glReadPixels" ); + return; + } + + readWidth = (width > MAX_WIDTH) ? MAX_WIDTH : width; + + if (type != GL_BYTE && + type != GL_UNSIGNED_BYTE && + type != GL_SHORT && + type != GL_UNSIGNED_SHORT && + type != GL_INT && + type != GL_UNSIGNED_INT && + type != GL_FLOAT) { + _mesa_error( ctx, GL_INVALID_OPERATION, "glReadPixels(depth type)"); + return; + } + + bias_or_scale = ctx->Pixel.DepthBias!=0.0 || ctx->Pixel.DepthScale!=1.0; + + if (type==GL_UNSIGNED_SHORT && ctx->Visual.depthBits == 16 + && !bias_or_scale && !packing->SwapBytes) { + /* Special case: directly read 16-bit unsigned depth values. */ + GLint j; + for (j=0;jVisual.depthBits == 32 + && !bias_or_scale && !packing->SwapBytes) { + /* Special case: directly read 32-bit unsigned depth values. */ + GLint j; + for (j=0;jPack); + } + } +} + + + +static void +read_stencil_pixels( GLcontext *ctx, + GLint x, GLint y, + GLsizei width, GLsizei height, + GLenum type, GLvoid *pixels, + const struct gl_pixelstore_attrib *packing ) +{ + GLint j, readWidth; + + if (type != GL_BYTE && + type != GL_UNSIGNED_BYTE && + type != GL_SHORT && + type != GL_UNSIGNED_SHORT && + type != GL_INT && + type != GL_UNSIGNED_INT && + type != GL_FLOAT && + type != GL_BITMAP) { + _mesa_error( ctx, GL_INVALID_OPERATION, "glReadPixels(stencil type)"); + return; + } + + readWidth = (width > MAX_WIDTH) ? MAX_WIDTH : width; + + if (ctx->Visual.stencilBits <= 0) { + /* No stencil buffer */ + _mesa_error( ctx, GL_INVALID_OPERATION, "glReadPixels" ); + return; + } + + /* process image row by row */ + for (j=0;jPack); + } +} + + + +/* + * Optimized glReadPixels for particular pixel formats: + * GL_UNSIGNED_BYTE, GL_RGBA + * when pixel scaling, biasing and mapping are disabled. + */ +static GLboolean +read_fast_rgba_pixels( GLcontext *ctx, + GLint x, GLint y, + GLsizei width, GLsizei height, + GLenum format, GLenum type, + GLvoid *pixels, + const struct gl_pixelstore_attrib *packing ) +{ + SWcontext *swrast = SWRAST_CONTEXT(ctx); + /* can't do scale, bias, mapping, etc */ + if (ctx->_ImageTransferState) + return GL_FALSE; + + /* can't do fancy pixel packing */ + if (packing->Alignment != 1 || packing->SwapBytes || packing->LsbFirst) + return GL_FALSE; + + { + GLint srcX = x; + GLint srcY = y; + GLint readWidth = width; /* actual width read */ + GLint readHeight = height; /* actual height read */ + GLint skipPixels = packing->SkipPixels; + GLint skipRows = packing->SkipRows; + GLint rowLength; + + if (packing->RowLength > 0) + rowLength = packing->RowLength; + else + rowLength = width; + + /* horizontal clipping */ + if (srcX < ctx->ReadBuffer->_Xmin) { + skipPixels += (ctx->ReadBuffer->_Xmin - srcX); + readWidth -= (ctx->ReadBuffer->_Xmin - srcX); + srcX = ctx->ReadBuffer->_Xmin; + } + if (srcX + readWidth > ctx->ReadBuffer->_Xmax) + readWidth -= (srcX + readWidth - ctx->ReadBuffer->_Xmax); + if (readWidth <= 0) + return GL_TRUE; + + /* vertical clipping */ + if (srcY < ctx->ReadBuffer->_Ymin) { + skipRows += (ctx->ReadBuffer->_Ymin - srcY); + readHeight -= (ctx->ReadBuffer->_Ymin - srcY); + srcY = ctx->ReadBuffer->_Ymin; + } + if (srcY + readHeight > ctx->ReadBuffer->_Ymax) + readHeight -= (srcY + readHeight - ctx->ReadBuffer->_Ymax); + if (readHeight <= 0) + return GL_TRUE; + + /* + * Ready to read! + * The window region at (destX, destY) of size (readWidth, readHeight) + * will be read back. + * We'll write pixel data to buffer pointed to by "pixels" but we'll + * skip "skipRows" rows and skip "skipPixels" pixels/row. + */ +#if CHAN_BITS == 8 + if (format == GL_RGBA && type == GL_UNSIGNED_BYTE) { +#elif CHAN_BITS == 16 + if (format == GL_RGBA && type == GL_UNSIGNED_SHORT) { +#else + if (0) { +#endif + GLchan *dest = (GLchan *) pixels + + (skipRows * rowLength + skipPixels) * 4; + GLint row; + for (row=0; rowDriver.ReadRGBASpan)(ctx, readWidth, srcX, srcY, + (GLchan (*)[4]) dest); + if (ctx->DrawBuffer->UseSoftwareAlphaBuffers) { + _mesa_read_alpha_span(ctx, readWidth, srcX, srcY, + (GLchan (*)[4]) dest); + } + dest += rowLength * 4; + srcY++; + } + return GL_TRUE; + } + else { + /* can't do this format/type combination */ + return GL_FALSE; + } + } +} + + + +/* + * Read R, G, B, A, RGB, L, or LA pixels. + */ +static void +read_rgba_pixels( GLcontext *ctx, + GLint x, GLint y, + GLsizei width, GLsizei height, + GLenum format, GLenum type, GLvoid *pixels, + const struct gl_pixelstore_attrib *packing ) +{ + SWcontext *swrast = SWRAST_CONTEXT(ctx); + GLint readWidth; + + (*swrast->Driver.SetReadBuffer)(ctx, ctx->ReadBuffer, ctx->Pixel.DriverReadBuffer); + + /* Try optimized path first */ + if (read_fast_rgba_pixels( ctx, x, y, width, height, + format, type, pixels, packing )) { + + (*swrast->Driver.SetReadBuffer)(ctx, ctx->DrawBuffer, ctx->Color.DriverDrawBuffer); + return; /* done! */ + } + + readWidth = (width > MAX_WIDTH) ? MAX_WIDTH : width; + + /* do error checking on pixel type, format was already checked by caller */ + switch (type) { + case GL_UNSIGNED_BYTE: + case GL_BYTE: + case GL_UNSIGNED_SHORT: + case GL_SHORT: + case GL_UNSIGNED_INT: + case GL_INT: + case GL_FLOAT: + case GL_UNSIGNED_BYTE_3_3_2: + case GL_UNSIGNED_BYTE_2_3_3_REV: + case GL_UNSIGNED_SHORT_5_6_5: + case GL_UNSIGNED_SHORT_5_6_5_REV: + case GL_UNSIGNED_SHORT_4_4_4_4: + case GL_UNSIGNED_SHORT_4_4_4_4_REV: + case GL_UNSIGNED_SHORT_5_5_5_1: + case GL_UNSIGNED_SHORT_1_5_5_5_REV: + case GL_UNSIGNED_INT_8_8_8_8: + case GL_UNSIGNED_INT_8_8_8_8_REV: + case GL_UNSIGNED_INT_10_10_10_2: + case GL_UNSIGNED_INT_2_10_10_10_REV: + /* valid pixel type */ + break; + default: + _mesa_error( ctx, GL_INVALID_ENUM, "glReadPixels(type)" ); + return; + } + + if (!_mesa_is_legal_format_and_type(format, type) || + format == GL_INTENSITY) { + _mesa_error(ctx, GL_INVALID_OPERATION, "glReadPixels(format or type)"); + return; + } + + if (ctx->Pixel.Convolution2DEnabled || ctx->Pixel.Separable2DEnabled) { + const GLuint transferOps = ctx->_ImageTransferState; + GLfloat *dest, *src, *tmpImage, *convImage; + GLint row; + + tmpImage = (GLfloat *) MALLOC(width * height * 4 * sizeof(GLfloat)); + if (!tmpImage) { + _mesa_error(ctx, GL_OUT_OF_MEMORY, "glReadPixels"); + return; + } + convImage = (GLfloat *) MALLOC(width * height * 4 * sizeof(GLfloat)); + if (!convImage) { + FREE(tmpImage); + _mesa_error(ctx, GL_OUT_OF_MEMORY, "glReadPixels"); + return; + } + + /* read full RGBA, FLOAT image */ + dest = tmpImage; + for (row = 0; row < height; row++, y++) { + GLchan rgba[MAX_WIDTH][4]; + if (ctx->Visual.rgbMode) { + _mesa_read_rgba_span(ctx, ctx->ReadBuffer, readWidth, x, y, rgba); + } + else { + GLuint index[MAX_WIDTH]; + (*swrast->Driver.ReadCI32Span)(ctx, readWidth, x, y, index); + if (ctx->Pixel.IndexShift != 0 || ctx->Pixel.IndexOffset !=0 ) { + _mesa_map_ci(ctx, readWidth, index); + } + _mesa_map_ci_to_rgba_chan(ctx, readWidth, index, rgba); + } + _mesa_pack_rgba_span(ctx, readWidth, (const GLchan (*)[4]) rgba, + GL_RGBA, GL_FLOAT, dest, &_mesa_native_packing, + transferOps & IMAGE_PRE_CONVOLUTION_BITS); + dest += width * 4; + } + + /* do convolution */ + if (ctx->Pixel.Convolution2DEnabled) { + _mesa_convolve_2d_image(ctx, &readWidth, &height, tmpImage, convImage); + } + else { + ASSERT(ctx->Pixel.Separable2DEnabled); + _mesa_convolve_sep_image(ctx, &readWidth, &height, tmpImage, convImage); + } + FREE(tmpImage); + + /* finish transfer ops and pack the resulting image */ + src = convImage; + for (row = 0; row < height; row++) { + GLvoid *dest; + dest = _mesa_image_address(packing, pixels, readWidth, height, + format, type, 0, row, 0); + _mesa_pack_float_rgba_span(ctx, readWidth, + (const GLfloat (*)[4]) src, + format, type, dest, packing, + transferOps & IMAGE_POST_CONVOLUTION_BITS); + src += readWidth * 4; + } + } + else { + /* no convolution */ + GLint row; + for (row = 0; row < height; row++, y++) { + GLchan rgba[MAX_WIDTH][4]; + GLvoid *dst; + if (ctx->Visual.rgbMode) { + _mesa_read_rgba_span(ctx, ctx->ReadBuffer, readWidth, x, y, rgba); + } + else { + GLuint index[MAX_WIDTH]; + (*swrast->Driver.ReadCI32Span)(ctx, readWidth, x, y, index); + if (ctx->Pixel.IndexShift != 0 || ctx->Pixel.IndexOffset != 0) { + _mesa_map_ci(ctx, readWidth, index); + } + _mesa_map_ci_to_rgba_chan(ctx, readWidth, index, rgba); + } + dst = _mesa_image_address(packing, pixels, width, height, + format, type, 0, row, 0); + if (ctx->Visual.redBits < CHAN_BITS || + ctx->Visual.greenBits < CHAN_BITS || + ctx->Visual.blueBits < CHAN_BITS) { + /* Requantize the color values into floating point and go from + * there. This fixes conformance failures with 16-bit color + * buffers, for example. + */ + DEFMARRAY(GLfloat, rgbaf, MAX_WIDTH, 4); /* mac 32k limitation */ + CHECKARRAY(rgbaf, return); /* mac 32k limitation */ + _mesa_chan_to_float_span(ctx, readWidth, + (CONST GLchan (*)[4]) rgba, rgbaf); + _mesa_pack_float_rgba_span(ctx, readWidth, + (CONST GLfloat (*)[4]) rgbaf, + format, type, dst, packing, + ctx->_ImageTransferState); + UNDEFARRAY(rgbaf); /* mac 32k limitation */ + } + else { + /* GLubytes are fine */ + _mesa_pack_rgba_span(ctx, readWidth, (CONST GLchan (*)[4]) rgba, + format, type, dst, packing, + ctx->_ImageTransferState); + } + } + } + + (*swrast->Driver.SetReadBuffer)(ctx, ctx->DrawBuffer, ctx->Color.DriverDrawBuffer); +} + + + +void +_swrast_ReadPixels( GLcontext *ctx, + GLint x, GLint y, GLsizei width, GLsizei height, + GLenum format, GLenum type, + const struct gl_pixelstore_attrib *pack, + GLvoid *pixels ) +{ + SWcontext *swrast = SWRAST_CONTEXT(ctx); + (void) pack; + + if (swrast->NewState) + _swrast_validate_derived( ctx ); + + RENDER_START(swrast,ctx); + + switch (format) { + case GL_COLOR_INDEX: + read_index_pixels(ctx, x, y, width, height, type, pixels, &ctx->Pack); + break; + case GL_STENCIL_INDEX: + read_stencil_pixels(ctx, x,y, width,height, type, pixels, &ctx->Pack); + break; + case GL_DEPTH_COMPONENT: + read_depth_pixels(ctx, x, y, width, height, type, pixels, &ctx->Pack); + break; + case GL_RED: + case GL_GREEN: + case GL_BLUE: + case GL_ALPHA: + case GL_RGB: + case GL_LUMINANCE: + case GL_LUMINANCE_ALPHA: + case GL_RGBA: + case GL_BGR: + case GL_BGRA: + case GL_ABGR_EXT: + read_rgba_pixels(ctx, x, y, width, height, + format, type, pixels, &ctx->Pack); + break; + default: + _mesa_error( ctx, GL_INVALID_ENUM, "glReadPixels(format)" ); + } + + RENDER_FINISH(swrast,ctx); +} Index: dll/opengl/opengl32/mesa/swrast/s_scissor.c =================================================================== --- dll/opengl/opengl32/mesa/swrast/s_scissor.c (revision 0) +++ dll/opengl/opengl32/mesa/swrast/s_scissor.c (working copy) @@ -0,0 +1,64 @@ +/* $Id: s_scissor.c,v 1.6 2001/03/12 00:48:42 gareth Exp $ */ + +/* + * Mesa 3-D graphics library + * Version: 3.5 + * + * Copyright (C) 1999-2001 Brian Paul 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 + * BRIAN PAUL 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. + */ + + +#include "glheader.h" +#include "macros.h" +#include "mem.h" +#include "s_context.h" +#include "s_scissor.h" + + +/* + * Apply the scissor test to a span of pixels. + * Return: 0 = all pixels in the span are outside the scissor box. + * n = mask[n-1] is the last one to be visible + */ +GLuint +_mesa_scissor_span(GLcontext *ctx, GLuint n, GLint x, GLint y, GLubyte mask[]) +{ + /* first check if whole span is outside the scissor box */ + if (y < ctx->DrawBuffer->_Ymin + || y >= ctx->DrawBuffer->_Ymax + || x > ctx->DrawBuffer->_Xmax + || x + (GLint) n - 1 < ctx->DrawBuffer->_Xmin) { + return 0; + } + else { + const GLint xMin = ctx->DrawBuffer->_Xmin; + const GLint xMax = ctx->DrawBuffer->_Xmax; + + if (x < xMin) + BZERO(mask, (xMin-x) * sizeof(GLubyte)); + + if (x + (GLint) n > xMax) { + BZERO(mask + xMax - x, (n - (xMax - x)) * sizeof(GLubyte)); + return (GLuint) (xMax - x); + } + + return n; + } +} Index: dll/opengl/opengl32/mesa/swrast/s_scissor.h =================================================================== --- dll/opengl/opengl32/mesa/swrast/s_scissor.h (revision 0) +++ dll/opengl/opengl32/mesa/swrast/s_scissor.h (working copy) @@ -0,0 +1,40 @@ +/* $Id: s_scissor.h,v 1.3 2001/02/15 22:59:01 brianp Exp $ */ + +/* + * Mesa 3-D graphics library + * Version: 3.5 + * + * Copyright (C) 1999-2001 Brian Paul 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 + * BRIAN PAUL 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. + */ + + +#ifndef S_SCISSOR_H +#define S_SCISSOR_H + + +#include "mtypes.h" +#include "swrast.h" + + +extern GLuint +_mesa_scissor_span(GLcontext *ctx, GLuint n, GLint x, GLint y, GLubyte mask[]); + + +#endif Index: dll/opengl/opengl32/mesa/swrast/s_span.c =================================================================== --- dll/opengl/opengl32/mesa/swrast/s_span.c (revision 0) +++ dll/opengl/opengl32/mesa/swrast/s_span.c (working copy) @@ -0,0 +1,1211 @@ +/* $Id: s_span.c,v 1.15 2001/06/18 23:55:18 brianp Exp $ */ + +/* + * Mesa 3-D graphics library + * Version: 3.5 + * + * Copyright (C) 1999-2001 Brian Paul 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 + * BRIAN PAUL 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. + */ + + +/* + * pixel span rasterization: + * These functions implement the rasterization pipeline. + */ + + +#include "glheader.h" +#include "colormac.h" +#include "macros.h" +#include "mem.h" + +#include "s_alpha.h" +#include "s_alphabuf.h" +#include "s_blend.h" +#include "s_context.h" +#include "s_depth.h" +#include "s_fog.h" +#include "s_logic.h" +#include "s_masking.h" +#include "s_scissor.h" +#include "s_span.h" +#include "s_stencil.h" +#include "s_texture.h" + + + +/* + * Apply the current polygon stipple pattern to a span of pixels. + */ +static void +stipple_polygon_span( GLcontext *ctx, GLuint n, GLint x, GLint y, + GLubyte mask[] ) +{ + const GLuint highbit = 0x80000000; + GLuint i, m, stipple; + + stipple = ctx->PolygonStipple[y % 32]; + m = highbit >> (GLuint) (x % 32); + + for (i = 0; i < n; i++) { + if ((m & stipple) == 0) { + mask[i] = 0; + } + m = m >> 1; + if (m == 0) { + m = highbit; + } + } +} + + + +/* + * Clip a pixel span to the current buffer/window boundaries. + * Return: 'n' such that pixel 'n', 'n+1' etc. are clipped, + * as a special case: + * 0 = all pixels clipped + */ +static GLuint +clip_span( GLcontext *ctx, GLint n, GLint x, GLint y, GLubyte mask[] ) +{ + /* Clip to top and bottom */ + if (y < 0 || y >= ctx->DrawBuffer->Height) { + return 0; + } + + /* Clip to the left */ + if (x < 0) { + if (x + n <= 0) { + /* completely off left side */ + return 0; + } + else { + /* partially off left side */ + BZERO(mask, -x * sizeof(GLubyte)); + } + } + + /* Clip to right */ + if (x + n > ctx->DrawBuffer->Width) { + if (x >= ctx->DrawBuffer->Width) { + /* completely off right side */ + return 0; + } + else { + /* partially off right side */ + return ctx->DrawBuffer->Width - x; + } + } + + return n; +} + + + +/* + * Draw to more than one color buffer (or none). + */ +static void +multi_write_index_span( GLcontext *ctx, GLuint n, GLint x, GLint y, + const GLuint indexes[], const GLubyte mask[] ) +{ + SWcontext *swrast = SWRAST_CONTEXT(ctx); + GLuint bufferBit; + + if (ctx->Color.DrawBuffer == GL_NONE) + return; + + /* loop over four possible dest color buffers */ + for (bufferBit = 1; bufferBit <= 8; bufferBit = bufferBit << 1) { + if (bufferBit & ctx->Color.DrawDestMask) { + GLuint indexTmp[MAX_WIDTH]; + ASSERT(n < MAX_WIDTH); + + if (bufferBit == FRONT_LEFT_BIT) + (void) (*ctx->Driver.SetDrawBuffer)( ctx, GL_FRONT_LEFT); + else if (bufferBit == FRONT_RIGHT_BIT) + (void) (*ctx->Driver.SetDrawBuffer)( ctx, GL_FRONT_RIGHT); + else if (bufferBit == BACK_LEFT_BIT) + (void) (*ctx->Driver.SetDrawBuffer)( ctx, GL_BACK_LEFT); + else + (void) (*ctx->Driver.SetDrawBuffer)( ctx, GL_BACK_RIGHT); + + /* make copy of incoming indexes */ + MEMCPY( indexTmp, indexes, n * sizeof(GLuint) ); + if (ctx->Color.IndexLogicOpEnabled) { + _mesa_logicop_ci_span( ctx, n, x, y, indexTmp, mask ); + } + if (ctx->Color.IndexMask == 0) { + break; + } + else if (ctx->Color.IndexMask != 0xffffffff) { + _mesa_mask_index_span( ctx, n, x, y, indexTmp ); + } + (*swrast->Driver.WriteCI32Span)( ctx, n, x, y, indexTmp, mask ); + } + } + + /* restore default dest buffer */ + (void) (*ctx->Driver.SetDrawBuffer)( ctx, ctx->Color.DriverDrawBuffer); +} + + + +/* + * Write a horizontal span of color index pixels to the frame buffer. + * Stenciling, Depth-testing, etc. are done as needed. + * Input: n - number of pixels in the span + * x, y - location of leftmost pixel in the span + * z - array of [n] z-values + * fog - array of fog factor values in [0,1] + * index - array of [n] color indexes + * primitive - either GL_POINT, GL_LINE, GL_POLYGON, or GL_BITMAP + */ +void +_mesa_write_index_span( GLcontext *ctx, GLuint n, GLint x, GLint y, + const GLdepth z[], const GLfloat fog[], + GLuint indexIn[], const GLint coverage[], + GLenum primitive ) +{ + const GLuint modBits = FOG_BIT | BLEND_BIT | MASKING_BIT | LOGIC_OP_BIT; + GLubyte mask[MAX_WIDTH]; + GLuint indexBackup[MAX_WIDTH]; + GLuint *index; /* points to indexIn or indexBackup */ + SWcontext *swrast = SWRAST_CONTEXT(ctx); + + /* init mask to 1's (all pixels are to be written) */ + MEMSET(mask, 1, n); + + if ((swrast->_RasterMask & WINCLIP_BIT) || primitive==GL_BITMAP) { + if ((n = clip_span(ctx,n,x,y,mask)) == 0) { + return; + } + } + + if ((primitive==GL_BITMAP && (swrast->_RasterMask & modBits)) + || (swrast->_RasterMask & MULTI_DRAW_BIT)) { + /* Make copy of color indexes */ + MEMCPY( indexBackup, indexIn, n * sizeof(GLuint) ); + index = indexBackup; + } + else { + index = indexIn; + } + + + /* Do the scissor test */ + if (ctx->Scissor.Enabled) { + if ((n = _mesa_scissor_span( ctx, n, x, y, mask )) == 0) { + return; + } + } + + /* Polygon Stippling */ + if (ctx->Polygon.StippleFlag && primitive==GL_POLYGON) { + stipple_polygon_span( ctx, n, x, y, mask ); + } + + if (ctx->Stencil.Enabled) { + /* first stencil test */ + if (_mesa_stencil_and_ztest_span(ctx, n, x, y, z, mask) == GL_FALSE) { + return; + } + } + else if (ctx->Depth.Test) { + /* regular depth testing */ + if (_mesa_depth_test_span( ctx, n, x, y, z, mask ) == 0) + return; + } + + /* if we get here, something passed the depth test */ + ctx->OcclusionResult = GL_TRUE; + + /* Per-pixel fog */ + if (ctx->Fog.Enabled) { + if (fog && !swrast->_PreferPixelFog) + _mesa_fog_ci_pixels( ctx, n, fog, index ); + else + _mesa_depth_fog_ci_pixels( ctx, n, z, index ); + } + + /* Antialias coverage application */ + if (coverage) { + GLuint i; + for (i = 0; i < n; i++) { + ASSERT(coverage[i] < 16); + index[i] = (index[i] & ~0xf) | coverage[i]; + } + } + + if (swrast->_RasterMask & MULTI_DRAW_BIT) { + /* draw to zero or two or more buffers */ + multi_write_index_span( ctx, n, x, y, index, mask ); + } + else { + /* normal situation: draw to exactly one buffer */ + if (ctx->Color.IndexLogicOpEnabled) { + _mesa_logicop_ci_span( ctx, n, x, y, index, mask ); + } + + if (ctx->Color.IndexMask == 0) { + return; + } + else if (ctx->Color.IndexMask != 0xffffffff) { + _mesa_mask_index_span( ctx, n, x, y, index ); + } + + /* write pixels */ + (*swrast->Driver.WriteCI32Span)( ctx, n, x, y, index, mask ); + } +} + + + + +void +_mesa_write_monoindex_span( GLcontext *ctx, GLuint n, GLint x, GLint y, + const GLdepth z[], const GLfloat fog[], + GLuint index, const GLint coverage[], + GLenum primitive ) +{ + SWcontext *swrast = SWRAST_CONTEXT(ctx); + GLubyte mask[MAX_WIDTH]; + GLuint i; + + /* init mask to 1's (all pixels are to be written) */ + MEMSET(mask, 1, n); + + if ((swrast->_RasterMask & WINCLIP_BIT) || primitive==GL_BITMAP) { + if ((n = clip_span( ctx, n, x, y, mask)) == 0) { + return; + } + } + + /* Do the scissor test */ + if (ctx->Scissor.Enabled) { + if ((n = _mesa_scissor_span( ctx, n, x, y, mask )) == 0) { + return; + } + } + + /* Polygon Stippling */ + if (ctx->Polygon.StippleFlag && primitive==GL_POLYGON) { + stipple_polygon_span( ctx, n, x, y, mask ); + } + + if (ctx->Stencil.Enabled) { + /* first stencil test */ + if (_mesa_stencil_and_ztest_span(ctx, n, x, y, z, mask) == GL_FALSE) { + return; + } + } + else if (ctx->Depth.Test) { + /* regular depth testing */ + if (_mesa_depth_test_span( ctx, n, x, y, z, mask ) == 0) + return; + } + + /* if we get here, something passed the depth test */ + ctx->OcclusionResult = GL_TRUE; + + if (ctx->Color.DrawBuffer == GL_NONE) { + /* write no pixels */ + return; + } + + if (ctx->Fog.Enabled + || ctx->Color.IndexLogicOpEnabled + || ctx->Color.IndexMask != 0xffffffff + || coverage) { + /* different index per pixel */ + GLuint indexes[MAX_WIDTH]; + for (i = 0; i < n; i++) { + indexes[i] = index; + } + + if (ctx->Fog.Enabled) { + if (fog && !swrast->_PreferPixelFog) + _mesa_fog_ci_pixels( ctx, n, fog, indexes ); + else + _mesa_depth_fog_ci_pixels( ctx, n, z, indexes ); + } + + /* Antialias coverage application */ + if (coverage) { + GLuint i; + for (i = 0; i < n; i++) { + ASSERT(coverage[i] < 16); + indexes[i] = (indexes[i] & ~0xf) | coverage[i]; + } + } + + if (swrast->_RasterMask & MULTI_DRAW_BIT) { + /* draw to zero or two or more buffers */ + multi_write_index_span( ctx, n, x, y, indexes, mask ); + } + else { + /* normal situation: draw to exactly one buffer */ + if (ctx->Color.IndexLogicOpEnabled) { + _mesa_logicop_ci_span( ctx, n, x, y, indexes, mask ); + } + if (ctx->Color.IndexMask == 0) { + return; + } + else if (ctx->Color.IndexMask != 0xffffffff) { + _mesa_mask_index_span( ctx, n, x, y, indexes ); + } + (*swrast->Driver.WriteCI32Span)( ctx, n, x, y, indexes, mask ); + } + } + else { + /* same color index for all pixels */ + ASSERT(!ctx->Color.IndexLogicOpEnabled); + ASSERT(ctx->Color.IndexMask == 0xffffffff); + if (swrast->_RasterMask & MULTI_DRAW_BIT) { + /* draw to zero or two or more buffers */ + GLuint indexes[MAX_WIDTH]; + for (i = 0; i < n; i++) + indexes[i] = index; + multi_write_index_span( ctx, n, x, y, indexes, mask ); + } + else { + /* normal situation: draw to exactly one buffer */ + (*swrast->Driver.WriteMonoCISpan)( ctx, n, x, y, index, mask ); + } + } +} + + + +/* + * Draw to more than one RGBA color buffer (or none). + */ +static void +multi_write_rgba_span( GLcontext *ctx, GLuint n, GLint x, GLint y, + CONST GLchan rgba[][4], const GLubyte mask[] ) +{ + const GLuint colorMask = *((GLuint *) ctx->Color.ColorMask); + GLuint bufferBit; + SWcontext *swrast = SWRAST_CONTEXT(ctx); + + if (ctx->Color.DrawBuffer == GL_NONE) + return; + + /* loop over four possible dest color buffers */ + for (bufferBit = 1; bufferBit <= 8; bufferBit = bufferBit << 1) { + if (bufferBit & ctx->Color.DrawDestMask) { + GLchan rgbaTmp[MAX_WIDTH][4]; + ASSERT(n < MAX_WIDTH); + + if (bufferBit == FRONT_LEFT_BIT) { + (void) (*ctx->Driver.SetDrawBuffer)( ctx, GL_FRONT_LEFT); + ctx->DrawBuffer->Alpha = ctx->DrawBuffer->FrontLeftAlpha; + } + else if (bufferBit == FRONT_RIGHT_BIT) { + (void) (*ctx->Driver.SetDrawBuffer)( ctx, GL_FRONT_RIGHT); + ctx->DrawBuffer->Alpha = ctx->DrawBuffer->FrontRightAlpha; + } + else if (bufferBit == BACK_LEFT_BIT) { + (void) (*ctx->Driver.SetDrawBuffer)( ctx, GL_BACK_LEFT); + ctx->DrawBuffer->Alpha = ctx->DrawBuffer->BackLeftAlpha; + } + else { + (void) (*ctx->Driver.SetDrawBuffer)( ctx, GL_BACK_RIGHT); + ctx->DrawBuffer->Alpha = ctx->DrawBuffer->BackRightAlpha; + } + + /* make copy of incoming colors */ + MEMCPY( rgbaTmp, rgba, 4 * n * sizeof(GLchan) ); + + if (ctx->Color.ColorLogicOpEnabled) { + _mesa_logicop_rgba_span( ctx, n, x, y, rgbaTmp, mask ); + } + else if (ctx->Color.BlendEnabled) { + _mesa_blend_span( ctx, n, x, y, rgbaTmp, mask ); + } + if (colorMask == 0x0) { + break; + } + else if (colorMask != 0xffffffff) { + _mesa_mask_rgba_span( ctx, n, x, y, rgbaTmp ); + } + + (*swrast->Driver.WriteRGBASpan)( ctx, n, x, y, + (const GLchan (*)[4]) rgbaTmp, mask ); + if (swrast->_RasterMask & ALPHABUF_BIT) { + _mesa_write_alpha_span( ctx, n, x, y, + (const GLchan (*)[4])rgbaTmp, mask ); + } + } + } + + /* restore default dest buffer */ + (void) (*ctx->Driver.SetDrawBuffer)( ctx, ctx->Color.DriverDrawBuffer ); +} + + + +void +_mesa_write_rgba_span( GLcontext *ctx, GLuint n, GLint x, GLint y, + const GLdepth z[], const GLfloat fog[], + GLchan rgbaIn[][4], const GLfloat coverage[], + GLenum primitive ) +{ + const GLuint modBits = FOG_BIT | BLEND_BIT | MASKING_BIT | + LOGIC_OP_BIT | TEXTURE_BIT; + GLubyte mask[MAX_WIDTH]; + GLboolean write_all = GL_TRUE; + GLchan rgbaBackup[MAX_WIDTH][4]; + GLchan (*rgba)[4]; + const GLubyte *Null = 0; + SWcontext *swrast = SWRAST_CONTEXT(ctx); + + /* init mask to 1's (all pixels are to be written) */ + MEMSET(mask, 1, n); + + if ((swrast->_RasterMask & WINCLIP_BIT) || primitive==GL_BITMAP) { + if ((n = clip_span( ctx,n,x,y,mask)) == 0) { + return; + } + if (mask[0] == 0) + write_all = GL_FALSE; + } + + if ((primitive==GL_BITMAP && (swrast->_RasterMask & modBits)) + || (swrast->_RasterMask & MULTI_DRAW_BIT)) { + /* must make a copy of the colors since they may be modified */ + MEMCPY( rgbaBackup, rgbaIn, 4 * n * sizeof(GLchan) ); + rgba = rgbaBackup; + } + else { + rgba = rgbaIn; + } + + /* Do the scissor test */ + if (ctx->Scissor.Enabled) { + if ((n = _mesa_scissor_span( ctx, n, x, y, mask )) == 0) { + return; + } + if (mask[0] == 0) + write_all = GL_FALSE; + } + + /* Polygon Stippling */ + if (ctx->Polygon.StippleFlag && primitive==GL_POLYGON) { + stipple_polygon_span( ctx, n, x, y, mask ); + write_all = GL_FALSE; + } + + /* Do the alpha test */ + if (ctx->Color.AlphaEnabled) { + if (_mesa_alpha_test( ctx, n, (const GLchan (*)[4]) rgba, mask ) == 0) { + return; + } + write_all = GL_FALSE; + } + + if (ctx->Stencil.Enabled) { + /* first stencil test */ + if (_mesa_stencil_and_ztest_span(ctx, n, x, y, z, mask) == GL_FALSE) { + return; + } + write_all = GL_FALSE; + } + else if (ctx->Depth.Test) { + /* regular depth testing */ + GLuint m = _mesa_depth_test_span( ctx, n, x, y, z, mask ); + if (m == 0) { + return; + } + if (m < n) { + write_all = GL_FALSE; + } + } + + /* if we get here, something passed the depth test */ + ctx->OcclusionResult = GL_TRUE; + + /* Per-pixel fog */ + if (ctx->Fog.Enabled) { + if (fog && !swrast->_PreferPixelFog) + _mesa_fog_rgba_pixels( ctx, n, fog, rgba ); + else + _mesa_depth_fog_rgba_pixels( ctx, n, z, rgba ); + } + + /* Antialias coverage application */ + if (coverage) { + GLuint i; + for (i = 0; i < n; i++) { + rgba[i][ACOMP] = (GLchan) (rgba[i][ACOMP] * coverage[i]); + } + } + + if (swrast->_RasterMask & MULTI_DRAW_BIT) { + multi_write_rgba_span( ctx, n, x, y, (const GLchan (*)[4]) rgba, mask ); + } + else { + /* normal: write to exactly one buffer */ + /* logic op or blending */ + const GLuint colorMask = *((GLuint *) ctx->Color.ColorMask); + + if (ctx->Color.ColorLogicOpEnabled) { + _mesa_logicop_rgba_span( ctx, n, x, y, rgba, mask ); + } + else if (ctx->Color.BlendEnabled) { + _mesa_blend_span( ctx, n, x, y, rgba, mask ); + } + + /* Color component masking */ + if (colorMask == 0x0) { + return; + } + else if (colorMask != 0xffffffff) { + _mesa_mask_rgba_span( ctx, n, x, y, rgba ); + } + + /* write pixels */ + (*swrast->Driver.WriteRGBASpan)( ctx, n, x, y, + (const GLchan (*)[4]) rgba, + write_all ? Null : mask ); + + if (swrast->_RasterMask & ALPHABUF_BIT) { + _mesa_write_alpha_span( ctx, n, x, y, + (const GLchan (*)[4]) rgba, + write_all ? Null : mask ); + } + } +} + + + +/* + * Write a horizontal span of color pixels to the frame buffer. + * The color is initially constant for the whole span. + * Alpha-testing, stenciling, depth-testing, and blending are done as needed. + * Input: n - number of pixels in the span + * x, y - location of leftmost pixel in the span + * z - array of [n] z-values + * fog - array of fog factor values in [0,1] + * r, g, b, a - the color of the pixels + * primitive - either GL_POINT, GL_LINE, GL_POLYGON or GL_BITMAP. + */ +void +_mesa_write_monocolor_span( GLcontext *ctx, GLuint n, GLint x, GLint y, + const GLdepth z[], const GLfloat fog[], + const GLchan color[4], const GLfloat coverage[], + GLenum primitive ) +{ + const GLuint colorMask = *((GLuint *) ctx->Color.ColorMask); + GLuint i; + GLubyte mask[MAX_WIDTH]; + GLboolean write_all = GL_TRUE; + GLchan rgba[MAX_WIDTH][4]; + const GLubyte *Null = 0; + SWcontext *swrast = SWRAST_CONTEXT(ctx); + + /* init mask to 1's (all pixels are to be written) */ + MEMSET(mask, 1, n); + + if ((swrast->_RasterMask & WINCLIP_BIT) || primitive==GL_BITMAP) { + if ((n = clip_span( ctx,n,x,y,mask)) == 0) { + return; + } + if (mask[0] == 0) + write_all = GL_FALSE; + } + + /* Do the scissor test */ + if (ctx->Scissor.Enabled) { + if ((n = _mesa_scissor_span( ctx, n, x, y, mask )) == 0) { + return; + } + if (mask[0] == 0) + write_all = GL_FALSE; + } + + /* Polygon Stippling */ + if (ctx->Polygon.StippleFlag && primitive==GL_POLYGON) { + stipple_polygon_span( ctx, n, x, y, mask ); + write_all = GL_FALSE; + } + + /* Do the alpha test */ + if (ctx->Color.AlphaEnabled) { + for (i = 0; i < n; i++) { + rgba[i][ACOMP] = color[ACOMP]; + } + if (_mesa_alpha_test( ctx, n, (const GLchan (*)[4])rgba, mask ) == 0) { + return; + } + write_all = GL_FALSE; + } + + if (ctx->Stencil.Enabled) { + /* first stencil test */ + if (_mesa_stencil_and_ztest_span(ctx, n, x, y, z, mask) == GL_FALSE) { + return; + } + write_all = GL_FALSE; + } + else if (ctx->Depth.Test) { + /* regular depth testing */ + GLuint m = _mesa_depth_test_span( ctx, n, x, y, z, mask ); + if (m == 0) { + return; + } + if (m < n) { + write_all = GL_FALSE; + } + } + + /* if we get here, something passed the depth test */ + ctx->OcclusionResult = GL_TRUE; + + if (ctx->Color.DrawBuffer == GL_NONE) { + /* write no pixels */ + return; + } + + if (ctx->Color.ColorLogicOpEnabled || colorMask != 0xffffffff || + (swrast->_RasterMask & (BLEND_BIT | FOG_BIT)) || coverage) { + /* assign same color to each pixel */ + for (i = 0; i < n; i++) { + if (mask[i]) { + COPY_CHAN4(rgba[i], color); + } + } + + /* Per-pixel fog */ + if (ctx->Fog.Enabled) { + if (fog && !swrast->_PreferPixelFog) + _mesa_fog_rgba_pixels( ctx, n, fog, rgba ); + else + _mesa_depth_fog_rgba_pixels( ctx, n, z, rgba ); + } + + /* Antialias coverage application */ + if (coverage) { + GLuint i; + for (i = 0; i < n; i++) { + rgba[i][ACOMP] = (GLchan) (rgba[i][ACOMP] * coverage[i]); + } + } + + if (swrast->_RasterMask & MULTI_DRAW_BIT) { + multi_write_rgba_span( ctx, n, x, y, + (const GLchan (*)[4]) rgba, mask ); + } + else { + /* normal: write to exactly one buffer */ + if (ctx->Color.ColorLogicOpEnabled) { + _mesa_logicop_rgba_span( ctx, n, x, y, rgba, mask ); + } + else if (ctx->Color.BlendEnabled) { + _mesa_blend_span( ctx, n, x, y, rgba, mask ); + } + + /* Color component masking */ + if (colorMask == 0x0) { + return; + } + else if (colorMask != 0xffffffff) { + _mesa_mask_rgba_span( ctx, n, x, y, rgba ); + } + + /* write pixels */ + (*swrast->Driver.WriteRGBASpan)( ctx, n, x, y, + (const GLchan (*)[4]) rgba, + write_all ? Null : mask ); + if (swrast->_RasterMask & ALPHABUF_BIT) { + _mesa_write_alpha_span( ctx, n, x, y, + (const GLchan (*)[4]) rgba, + write_all ? Null : mask ); + } + } + } + else { + /* same color for all pixels */ + ASSERT(!ctx->Color.BlendEnabled); + ASSERT(!ctx->Color.ColorLogicOpEnabled); + + if (swrast->_RasterMask & MULTI_DRAW_BIT) { + for (i = 0; i < n; i++) { + if (mask[i]) { + COPY_CHAN4(rgba[i], color); + } + } + multi_write_rgba_span( ctx, n, x, y, + (const GLchan (*)[4]) rgba, mask ); + } + else { + (*swrast->Driver.WriteMonoRGBASpan)( ctx, n, x, y, color, mask ); + if (swrast->_RasterMask & ALPHABUF_BIT) { + _mesa_write_mono_alpha_span( ctx, n, x, y, (GLchan) color[ACOMP], + write_all ? Null : mask ); + } + } + } +} + + + +/* + * Add specular color to base color. This is used only when + * GL_LIGHT_MODEL_COLOR_CONTROL = GL_SEPARATE_SPECULAR_COLOR. + */ +static void +add_colors(GLuint n, GLchan rgba[][4], CONST GLchan specular[][4] ) +{ + GLuint i; + for (i = 0; i < n; i++) { + GLint r = rgba[i][RCOMP] + specular[i][RCOMP]; + GLint g = rgba[i][GCOMP] + specular[i][GCOMP]; + GLint b = rgba[i][BCOMP] + specular[i][BCOMP]; + rgba[i][RCOMP] = (GLchan) MIN2(r, CHAN_MAX); + rgba[i][GCOMP] = (GLchan) MIN2(g, CHAN_MAX); + rgba[i][BCOMP] = (GLchan) MIN2(b, CHAN_MAX); + } +} + + +/* + * Write a horizontal span of textured pixels to the frame buffer. + * The color of each pixel is different. + * Alpha-testing, stenciling, depth-testing, and blending are done + * as needed. + * Input: n - number of pixels in the span + * x, y - location of leftmost pixel in the span + * z - array of [n] z-values + * s, t - array of (s,t) texture coordinates for each pixel + * lambda - array of texture lambda values + * rgba - array of [n] color components + * primitive - either GL_POINT, GL_LINE, GL_POLYGON or GL_BITMAP. + */ +void +_mesa_write_texture_span( GLcontext *ctx, GLuint n, GLint x, GLint y, + const GLdepth z[], const GLfloat fog[], + const GLfloat s[], const GLfloat t[], + const GLfloat u[], GLfloat lambda[], + GLchan rgbaIn[][4], CONST GLchan spec[][4], + const GLfloat coverage[], GLenum primitive ) +{ + const GLuint colorMask = *((GLuint *) ctx->Color.ColorMask); + GLubyte mask[MAX_WIDTH]; + GLboolean write_all = GL_TRUE; + GLchan rgbaBackup[MAX_WIDTH][4]; + GLchan (*rgba)[4]; /* points to either rgbaIn or rgbaBackup */ + const GLubyte *Null = 0; + SWcontext *swrast = SWRAST_CONTEXT(ctx); + + /* init mask to 1's (all pixels are to be written) */ + MEMSET(mask, 1, n); + + if ((swrast->_RasterMask & WINCLIP_BIT) || primitive==GL_BITMAP) { + if ((n=clip_span(ctx, n, x, y, mask)) == 0) { + return; + } + if (mask[0] == 0) + write_all = GL_FALSE; + } + + + if (primitive==GL_BITMAP || (swrast->_RasterMask & MULTI_DRAW_BIT)) { + /* must make a copy of the colors since they may be modified */ + MEMCPY(rgbaBackup, rgbaIn, 4 * n * sizeof(GLchan)); + rgba = rgbaBackup; + } + else { + rgba = rgbaIn; + } + + /* Do the scissor test */ + if (ctx->Scissor.Enabled) { + if ((n = _mesa_scissor_span( ctx, n, x, y, mask )) == 0) { + return; + } + if (mask[0] == 0) + write_all = GL_FALSE; + } + + /* Polygon Stippling */ + if (ctx->Polygon.StippleFlag && primitive==GL_POLYGON) { + stipple_polygon_span( ctx, n, x, y, mask ); + write_all = GL_FALSE; + } + + /* Texture with alpha test*/ + if (ctx->Color.AlphaEnabled) { + /* Texturing without alpha is done after depth-testing which + gives a potential speed-up. */ + ASSERT(ctx->Texture._ReallyEnabled); + _swrast_texture_fragments( ctx, 0, n, s, t, u, lambda, + (CONST GLchan (*)[4]) rgba, rgba ); + + /* Do the alpha test */ + if (_mesa_alpha_test( ctx, n, (const GLchan (*)[4]) rgba, mask ) == 0) { + return; + } + write_all = GL_FALSE; + } + + if (ctx->Stencil.Enabled) { + /* first stencil test */ + if (_mesa_stencil_and_ztest_span(ctx, n, x, y, z, mask) == GL_FALSE) { + return; + } + write_all = GL_FALSE; + } + else if (ctx->Depth.Test) { + /* regular depth testing */ + GLuint m = _mesa_depth_test_span( ctx, n, x, y, z, mask ); + if (m == 0) { + return; + } + if (m < n) { + write_all = GL_FALSE; + } + } + + /* if we get here, something passed the depth test */ + ctx->OcclusionResult = GL_TRUE; + + /* Texture without alpha test */ + if (! ctx->Color.AlphaEnabled) { + ASSERT(ctx->Texture._ReallyEnabled); + _swrast_texture_fragments( ctx, 0, n, s, t, u, lambda, + (CONST GLchan (*)[4]) rgba, rgba ); + } + + /* Add base and specular colors */ + if (spec && + (ctx->Fog.ColorSumEnabled || + (ctx->Light.Enabled && + ctx->Light.Model.ColorControl == GL_SEPARATE_SPECULAR_COLOR))) + add_colors( n, rgba, spec ); /* rgba = rgba + spec */ + + /* Per-pixel fog */ + if (ctx->Fog.Enabled) { + if (fog && !swrast->_PreferPixelFog) + _mesa_fog_rgba_pixels( ctx, n, fog, rgba ); + else + _mesa_depth_fog_rgba_pixels( ctx, n, z, rgba ); + } + + /* Antialias coverage application */ + if (coverage) { + GLuint i; + for (i = 0; i < n; i++) { + rgba[i][ACOMP] = (GLchan) (rgba[i][ACOMP] * coverage[i]); + } + } + + if (swrast->_RasterMask & MULTI_DRAW_BIT) { + multi_write_rgba_span( ctx, n, x, y, (const GLchan (*)[4]) rgba, mask ); + } + else { + /* normal: write to exactly one buffer */ + if (ctx->Color.ColorLogicOpEnabled) { + _mesa_logicop_rgba_span( ctx, n, x, y, rgba, mask ); + } + else if (ctx->Color.BlendEnabled) { + _mesa_blend_span( ctx, n, x, y, rgba, mask ); + } + if (colorMask == 0x0) { + return; + } + else if (colorMask != 0xffffffff) { + _mesa_mask_rgba_span( ctx, n, x, y, rgba ); + } + + (*swrast->Driver.WriteRGBASpan)( ctx, n, x, y, (const GLchan (*)[4])rgba, + write_all ? Null : mask ); + if (swrast->_RasterMask & ALPHABUF_BIT) { + _mesa_write_alpha_span( ctx, n, x, y, (const GLchan (*)[4]) rgba, + write_all ? Null : mask ); + } + } +} + + + +/* + * As above but perform multiple stages of texture application. + */ +void +_mesa_write_multitexture_span( GLcontext *ctx, GLuint n, GLint x, GLint y, + const GLdepth z[], const GLfloat fog[], + CONST GLfloat s[MAX_TEXTURE_UNITS][MAX_WIDTH], + CONST GLfloat t[MAX_TEXTURE_UNITS][MAX_WIDTH], + CONST GLfloat u[MAX_TEXTURE_UNITS][MAX_WIDTH], + GLfloat lambda[][MAX_WIDTH], + GLchan rgbaIn[MAX_TEXTURE_UNITS][4], + CONST GLchan spec[MAX_TEXTURE_UNITS][4], + const GLfloat coverage[], + GLenum primitive ) +{ + GLubyte mask[MAX_WIDTH]; + GLboolean write_all = GL_TRUE; + GLchan rgbaBackup[MAX_WIDTH][4]; + GLchan (*rgba)[4]; /* points to either rgbaIn or rgbaBackup */ + GLuint i; + const GLubyte *Null = 0; + const GLuint texUnits = ctx->Const.MaxTextureUnits; + SWcontext *swrast = SWRAST_CONTEXT(ctx); + + /* init mask to 1's (all pixels are to be written) */ + MEMSET(mask, 1, n); + + if ((swrast->_RasterMask & WINCLIP_BIT) || primitive==GL_BITMAP) { + if ((n=clip_span(ctx, n, x, y, mask)) == 0) { + return; + } + if (mask[0] == 0) + write_all = GL_FALSE; + } + + + if (primitive==GL_BITMAP || (swrast->_RasterMask & MULTI_DRAW_BIT) + || texUnits > 1) { + /* must make a copy of the colors since they may be modified */ + MEMCPY(rgbaBackup, rgbaIn, 4 * n * sizeof(GLchan)); + rgba = rgbaBackup; + } + else { + rgba = rgbaIn; + } + + /* Do the scissor test */ + if (ctx->Scissor.Enabled) { + if ((n = _mesa_scissor_span( ctx, n, x, y, mask )) == 0) { + return; + } + if (mask[0] == 0) + write_all = GL_FALSE; + } + + /* Polygon Stippling */ + if (ctx->Polygon.StippleFlag && primitive==GL_POLYGON) { + stipple_polygon_span( ctx, n, x, y, mask ); + write_all = GL_FALSE; + } + + /* Texture with alpha test*/ + if (ctx->Color.AlphaEnabled) { + /* Texturing without alpha is done after depth-testing which + * gives a potential speed-up. + */ + ASSERT(ctx->Texture._ReallyEnabled); + for (i = 0; i < texUnits; i++) + _swrast_texture_fragments( ctx, i, n, s[i], t[i], u[i], lambda[i], + (CONST GLchan (*)[4]) rgbaIn, rgba ); + + /* Do the alpha test */ + if (_mesa_alpha_test( ctx, n, (const GLchan (*)[4])rgba, mask ) == 0) { + return; + } + write_all = GL_FALSE; + } + + if (ctx->Stencil.Enabled) { + /* first stencil test */ + if (_mesa_stencil_and_ztest_span(ctx, n, x, y, z, mask) == GL_FALSE) { + return; + } + write_all = GL_FALSE; + } + else if (ctx->Depth.Test) { + /* regular depth testing */ + GLuint m = _mesa_depth_test_span( ctx, n, x, y, z, mask ); + if (m == 0) { + return; + } + if (m < n) { + write_all = GL_FALSE; + } + } + + /* if we get here, something passed the depth test */ + ctx->OcclusionResult = GL_TRUE; + + /* Texture without alpha test */ + if (! ctx->Color.AlphaEnabled) { + ASSERT(ctx->Texture._ReallyEnabled); + for (i = 0; i < texUnits; i++) + _swrast_texture_fragments( ctx, i, n, s[i], t[i], u[i], lambda[i], + (CONST GLchan (*)[4]) rgbaIn, rgba ); + } + + /* Add base and specular colors */ + if (spec && + (ctx->Fog.ColorSumEnabled || + (ctx->Light.Enabled && + ctx->Light.Model.ColorControl == GL_SEPARATE_SPECULAR_COLOR))) + add_colors( n, rgba, spec ); /* rgba = rgba + spec */ + + /* Per-pixel fog */ + if (ctx->Fog.Enabled) { + if (fog && !swrast->_PreferPixelFog) + _mesa_fog_rgba_pixels( ctx, n, fog, rgba ); + else + _mesa_depth_fog_rgba_pixels( ctx, n, z, rgba ); + } + + /* Antialias coverage application */ + if (coverage) { + GLuint i; + for (i = 0; i < n; i++) { + rgba[i][ACOMP] = (GLchan) (rgba[i][ACOMP] * coverage[i]); + } + } + + if (swrast->_RasterMask & MULTI_DRAW_BIT) { + multi_write_rgba_span( ctx, n, x, y, (const GLchan (*)[4]) rgba, mask ); + } + else { + /* normal: write to exactly one buffer */ + const GLuint colorMask = *((GLuint *) ctx->Color.ColorMask); + + if (ctx->Color.ColorLogicOpEnabled) { + _mesa_logicop_rgba_span( ctx, n, x, y, rgba, mask ); + } + else if (ctx->Color.BlendEnabled) { + _mesa_blend_span( ctx, n, x, y, rgba, mask ); + } + + if (colorMask == 0x0) { + return; + } + else if (colorMask != 0xffffffff) { + _mesa_mask_rgba_span( ctx, n, x, y, rgba ); + } + + (*swrast->Driver.WriteRGBASpan)( ctx, n, x, y, (const GLchan (*)[4])rgba, + write_all ? Null : mask ); + if (swrast->_RasterMask & ALPHABUF_BIT) { + _mesa_write_alpha_span( ctx, n, x, y, (const GLchan (*)[4])rgba, + write_all ? Null : mask ); + } + } +} + + + +/* + * Read RGBA pixels from frame buffer. Clipping will be done to prevent + * reading ouside the buffer's boundaries. + */ +void +_mesa_read_rgba_span( GLcontext *ctx, GLframebuffer *buffer, + GLuint n, GLint x, GLint y, GLchan rgba[][4] ) +{ + SWcontext *swrast = SWRAST_CONTEXT(ctx); + if (y < 0 || y >= buffer->Height + || x + (GLint) n < 0 || x >= buffer->Width) { + /* completely above, below, or right */ + /* XXX maybe leave undefined? */ + BZERO(rgba, 4 * n * sizeof(GLchan)); + } + else { + GLint skip, length; + if (x < 0) { + /* left edge clippping */ + skip = -x; + length = (GLint) n - skip; + if (length < 0) { + /* completely left of window */ + return; + } + if (length > buffer->Width) { + length = buffer->Width; + } + } + else if ((GLint) (x + n) > buffer->Width) { + /* right edge clipping */ + skip = 0; + length = buffer->Width - x; + if (length < 0) { + /* completely to right of window */ + return; + } + } + else { + /* no clipping */ + skip = 0; + length = (GLint) n; + } + + (*swrast->Driver.ReadRGBASpan)( ctx, length, x + skip, y, rgba + skip ); + if (buffer->UseSoftwareAlphaBuffers) { + _mesa_read_alpha_span( ctx, length, x + skip, y, rgba + skip ); + } + } +} + + + + +/* + * Read CI pixels from frame buffer. Clipping will be done to prevent + * reading ouside the buffer's boundaries. + */ +void +_mesa_read_index_span( GLcontext *ctx, GLframebuffer *buffer, + GLuint n, GLint x, GLint y, GLuint indx[] ) +{ + SWcontext *swrast = SWRAST_CONTEXT(ctx); + if (y < 0 || y >= buffer->Height + || x + (GLint) n < 0 || x >= buffer->Width) { + /* completely above, below, or right */ + BZERO(indx, n * sizeof(GLuint)); + } + else { + GLint skip, length; + if (x < 0) { + /* left edge clippping */ + skip = -x; + length = (GLint) n - skip; + if (length < 0) { + /* completely left of window */ + return; + } + if (length > buffer->Width) { + length = buffer->Width; + } + } + else if ((GLint) (x + n) > buffer->Width) { + /* right edge clipping */ + skip = 0; + length = buffer->Width - x; + if (length < 0) { + /* completely to right of window */ + return; + } + } + else { + /* no clipping */ + skip = 0; + length = (GLint) n; + } + + (*swrast->Driver.ReadCI32Span)( ctx, length, skip + x, y, indx + skip ); + } +} Index: dll/opengl/opengl32/mesa/swrast/s_span.h =================================================================== --- dll/opengl/opengl32/mesa/swrast/s_span.h (revision 0) +++ dll/opengl/opengl32/mesa/swrast/s_span.h (working copy) @@ -0,0 +1,94 @@ +/* $Id: s_span.h,v 1.6 2001/05/15 21:30:27 brianp Exp $ */ + +/* + * Mesa 3-D graphics library + * Version: 3.5 + * + * Copyright (C) 1999-2001 Brian Paul 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 + * BRIAN PAUL 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. + */ + + +#ifndef S_SPAN_H +#define S_SPAN_H + + +#include "mtypes.h" +#include "swrast.h" + + +extern void +_mesa_write_index_span( GLcontext *ctx, GLuint n, GLint x, GLint y, + const GLdepth z[], const GLfloat fog[], + GLuint index[], const GLint coverage[], + GLenum primitive ); + + +extern void +_mesa_write_monoindex_span( GLcontext *ctx, GLuint n, GLint x, GLint y, + const GLdepth z[], const GLfloat fog[], + GLuint index, const GLint coverage[], + GLenum primitive ); + + +extern void +_mesa_write_rgba_span( GLcontext *ctx, GLuint n, GLint x, GLint y, + const GLdepth z[], const GLfloat fog[], + GLchan rgba[][4], const GLfloat coverage[], + GLenum primitive ); + + +extern void +_mesa_write_monocolor_span( GLcontext *ctx, GLuint n, GLint x, GLint y, + const GLdepth z[], const GLfloat fog[], + const GLchan color[4], const GLfloat coverage[], + GLenum primitive ); + + +extern void +_mesa_write_texture_span( GLcontext *ctx, GLuint n, GLint x, GLint y, + const GLdepth z[], const GLfloat fog[], + const GLfloat s[], const GLfloat t[], + const GLfloat u[], GLfloat lambda[], + GLchan rgba[][4], CONST GLchan spec[][4], + const GLfloat coverage[], GLenum primitive ); + + +extern void +_mesa_write_multitexture_span( GLcontext *ctx, GLuint n, GLint x, GLint y, + const GLdepth z[], const GLfloat fog[], + CONST GLfloat s[MAX_TEXTURE_UNITS][MAX_WIDTH], + CONST GLfloat t[MAX_TEXTURE_UNITS][MAX_WIDTH], + CONST GLfloat u[MAX_TEXTURE_UNITS][MAX_WIDTH], + GLfloat lambda[MAX_TEXTURE_UNITS][MAX_WIDTH], + GLchan rgba[][4], CONST GLchan spec[][4], + const GLfloat coverage[], GLenum primitive ); + + +extern void +_mesa_read_rgba_span( GLcontext *ctx, GLframebuffer *buffer, + GLuint n, GLint x, GLint y, GLchan rgba[][4] ); + + +extern void +_mesa_read_index_span( GLcontext *ctx, GLframebuffer *buffer, + GLuint n, GLint x, GLint y, GLuint indx[] ); + + +#endif Index: dll/opengl/opengl32/mesa/swrast/s_stencil.c =================================================================== --- dll/opengl/opengl32/mesa/swrast/s_stencil.c (revision 0) +++ dll/opengl/opengl32/mesa/swrast/s_stencil.c (working copy) @@ -0,0 +1,1309 @@ +/* $Id: s_stencil.c,v 1.12 2001/05/17 20:18:45 brianp Exp $ */ + +/* + * Mesa 3-D graphics library + * Version: 3.5 + * + * Copyright (C) 1999-2001 Brian Paul 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 + * BRIAN PAUL 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. + */ + + +#include "glheader.h" +#include "context.h" +#include "macros.h" +#include "mem.h" + +#include "s_context.h" +#include "s_depth.h" +#include "s_pb.h" +#include "s_stencil.h" + + + + + +/* Stencil Logic: + +IF stencil test fails THEN + Apply fail-op to stencil value + Don't write the pixel (RGBA,Z) +ELSE + IF doing depth test && depth test fails THEN + Apply zfail-op to stencil value + Write RGBA and Z to appropriate buffers + ELSE + Apply zpass-op to stencil value +ENDIF + +*/ + + + + +/* + * Return the address of a stencil buffer value given the window coords: + */ +#define STENCIL_ADDRESS(X,Y) \ + (ctx->DrawBuffer->Stencil + ctx->DrawBuffer->Width * (Y) + (X)) + + + +/* + * Apply the given stencil operator to the array of stencil values. + * Don't touch stencil[i] if mask[i] is zero. + * Input: n - size of stencil array + * oper - the stencil buffer operator + * stencil - array of stencil values + * mask - array [n] of flag: 1=apply operator, 0=don't apply operator + * Output: stencil - modified values + */ +static void apply_stencil_op( const GLcontext *ctx, GLenum oper, + GLuint n, GLstencil stencil[], + const GLubyte mask[] ) +{ + const GLstencil ref = ctx->Stencil.Ref; + const GLstencil wrtmask = ctx->Stencil.WriteMask; + const GLstencil invmask = (GLstencil) (~ctx->Stencil.WriteMask); + GLuint i; + + switch (oper) { + case GL_KEEP: + /* do nothing */ + break; + case GL_ZERO: + if (invmask==0) { + for (i=0;i0) { + stencil[i] = (GLstencil) (s-1); + } + } + } + } + else { + for (i=0;i0) { + stencil[i] = (GLstencil) ((invmask & s) | (wrtmask & (s-1))); + } + } + } + } + break; + case GL_INCR_WRAP_EXT: + if (invmask==0) { + for (i=0;iStencil.Function) { + case GL_NEVER: + /* always fail */ + for (i=0;iStencil.Ref & ctx->Stencil.ValueMask); + for (i=0;iStencil.ValueMask); + if (r < s) { + /* passed */ + fail[i] = 0; + } + else { + fail[i] = 1; + mask[i] = 0; + } + } + else { + fail[i] = 0; + } + } + break; + case GL_LEQUAL: + r = (GLstencil) (ctx->Stencil.Ref & ctx->Stencil.ValueMask); + for (i=0;iStencil.ValueMask); + if (r <= s) { + /* pass */ + fail[i] = 0; + } + else { + fail[i] = 1; + mask[i] = 0; + } + } + else { + fail[i] = 0; + } + } + break; + case GL_GREATER: + r = (GLstencil) (ctx->Stencil.Ref & ctx->Stencil.ValueMask); + for (i=0;iStencil.ValueMask); + if (r > s) { + /* passed */ + fail[i] = 0; + } + else { + fail[i] = 1; + mask[i] = 0; + } + } + else { + fail[i] = 0; + } + } + break; + case GL_GEQUAL: + r = (GLstencil) (ctx->Stencil.Ref & ctx->Stencil.ValueMask); + for (i=0;iStencil.ValueMask); + if (r >= s) { + /* passed */ + fail[i] = 0; + } + else { + fail[i] = 1; + mask[i] = 0; + } + } + else { + fail[i] = 0; + } + } + break; + case GL_EQUAL: + r = (GLstencil) (ctx->Stencil.Ref & ctx->Stencil.ValueMask); + for (i=0;iStencil.ValueMask); + if (r == s) { + /* passed */ + fail[i] = 0; + } + else { + fail[i] = 1; + mask[i] = 0; + } + } + else { + fail[i] = 0; + } + } + break; + case GL_NOTEQUAL: + r = (GLstencil) (ctx->Stencil.Ref & ctx->Stencil.ValueMask); + for (i=0;iStencil.ValueMask); + if (r != s) { + /* passed */ + fail[i] = 0; + } + else { + fail[i] = 1; + mask[i] = 0; + } + } + else { + fail[i] = 0; + } + } + break; + case GL_ALWAYS: + /* always pass */ + for (i=0;iStencil.FailFunc != GL_KEEP) { + apply_stencil_op( ctx, ctx->Stencil.FailFunc, n, stencil, fail ); + } + + return !allfail; +} + + + + +/* + * Apply stencil and depth testing to an array of pixels. + * Hardware or software stencil buffer acceptable. + * Input: n - number of pixels in the span + * z - array [n] of z values + * stencil - array [n] of stencil values + * mask - array [n] of flags (1=test this pixel, 0=skip the pixel) + * Output: stencil - modified stencil values + * mask - array [n] of flags (1=stencil and depth test passed) + * Return: GL_TRUE - all fragments failed the testing + * GL_FALSE - one or more fragments passed the testing + * + */ +static GLboolean +stencil_and_ztest_span( GLcontext *ctx, GLuint n, GLint x, GLint y, + const GLdepth z[], GLstencil stencil[], + GLubyte mask[] ) +{ + ASSERT(ctx->Stencil.Enabled); + ASSERT(n <= PB_SIZE); + + /* + * Apply the stencil test to the fragments. + * failMask[i] is 1 if the stencil test failed. + */ + if (do_stencil_test( ctx, n, stencil, mask ) == GL_FALSE) { + /* all fragments failed the stencil test, we're done. */ + return GL_FALSE; + } + + + /* + * Some fragments passed the stencil test, apply depth test to them + * and apply Zpass and Zfail stencil ops. + */ + if (ctx->Depth.Test==GL_FALSE) { + /* + * No depth buffer, just apply zpass stencil function to active pixels. + */ + apply_stencil_op( ctx, ctx->Stencil.ZPassFunc, n, stencil, mask ); + } + else { + /* + * Perform depth buffering, then apply zpass or zfail stencil function. + */ + GLubyte passmask[MAX_WIDTH], failmask[MAX_WIDTH], oldmask[MAX_WIDTH]; + GLuint i; + + /* save the current mask bits */ + MEMCPY(oldmask, mask, n * sizeof(GLubyte)); + + /* apply the depth test */ + _mesa_depth_test_span(ctx, n, x, y, z, mask); + + /* Set the stencil pass/fail flags according to result of depth testing. + * if oldmask[i] == 0 then + * Don't touch the stencil value + * else if oldmask[i] and newmask[i] then + * Depth test passed + * else + * assert(oldmask[i] && !newmask[i]) + * Depth test failed + * endif + */ + for (i=0;iStencil.ZFailFunc != GL_KEEP) { + apply_stencil_op( ctx, ctx->Stencil.ZFailFunc, n, stencil, failmask ); + } + if (ctx->Stencil.ZPassFunc != GL_KEEP) { + apply_stencil_op( ctx, ctx->Stencil.ZPassFunc, n, stencil, passmask ); + } + } + + return GL_TRUE; /* one or more fragments passed both tests */ +} + + + +/* + * Apply stencil and depth testing to the span of pixels. + * Both software and hardware stencil buffers are acceptable. + * Input: n - number of pixels in the span + * x, y - location of leftmost pixel in span + * z - array [n] of z values + * mask - array [n] of flags (1=test this pixel, 0=skip the pixel) + * Output: mask - array [n] of flags (1=stencil and depth test passed) + * Return: GL_TRUE - all fragments failed the testing + * GL_FALSE - one or more fragments passed the testing + * + */ +GLboolean +_mesa_stencil_and_ztest_span( GLcontext *ctx, GLuint n, GLint x, GLint y, + const GLdepth z[], GLubyte mask[] ) +{ + SWcontext *swrast = SWRAST_CONTEXT(ctx); + GLstencil stencilRow[MAX_WIDTH]; + GLstencil *stencil; + GLboolean result; + + ASSERT(ctx->Stencil.Enabled); + ASSERT(n <= MAX_WIDTH); + + /* Get initial stencil values */ + if (swrast->Driver.WriteStencilSpan) { + ASSERT(swrast->Driver.ReadStencilSpan); + /* Get stencil values from the hardware stencil buffer */ + (*swrast->Driver.ReadStencilSpan)(ctx, n, x, y, stencilRow); + stencil = stencilRow; + } + else { + /* software stencil buffer */ + stencil = STENCIL_ADDRESS(x, y); + } + + /* do all the stencil/depth testing/updating */ + result = stencil_and_ztest_span( ctx, n, x, y, z, stencil, mask ); + + if (swrast->Driver.WriteStencilSpan) { + /* Write updated stencil values into hardware stencil buffer */ + (swrast->Driver.WriteStencilSpan)(ctx, n, x, y, stencil, mask ); + } + + return result; +} + + + + +/* + * Apply the given stencil operator for each pixel in the array whose + * mask flag is set. This is for software stencil buffers only. + * Input: n - number of pixels in the span + * x, y - array of [n] pixels + * operator - the stencil buffer operator + * mask - array [n] of flag: 1=apply operator, 0=don't apply operator + */ +static void +apply_stencil_op_to_pixels( const GLcontext *ctx, + GLuint n, const GLint x[], const GLint y[], + GLenum oper, const GLubyte mask[] ) +{ + const GLstencil ref = ctx->Stencil.Ref; + const GLstencil wrtmask = ctx->Stencil.WriteMask; + const GLstencil invmask = (GLstencil) (~ctx->Stencil.WriteMask); + GLuint i; + + ASSERT(!SWRAST_CONTEXT(ctx)->Driver.WriteStencilSpan); /* software stencil buffer only! */ + + switch (oper) { + case GL_KEEP: + /* do nothing */ + break; + case GL_ZERO: + if (invmask==0) { + for (i=0;i0) { + *sptr = (GLstencil) (*sptr - 1); + } + } + } + } + else { + for (i=0;i0) { + *sptr = (GLstencil) ((invmask & *sptr) | (wrtmask & (*sptr-1))); + } + } + } + } + break; + case GL_INCR_WRAP_EXT: + if (invmask==0) { + for (i=0;iDriver.WriteStencilSpan); /* software stencil buffer only! */ + + /* + * Perform stencil test. The results of this operation are stored + * in the fail[] array: + * IF fail[i] is non-zero THEN + * the stencil fail operator is to be applied + * ELSE + * the stencil fail operator is not to be applied + * ENDIF + */ + + switch (ctx->Stencil.Function) { + case GL_NEVER: + /* always fail */ + for (i=0;iStencil.Ref & ctx->Stencil.ValueMask); + for (i=0;iStencil.ValueMask); + if (r < s) { + /* passed */ + fail[i] = 0; + } + else { + fail[i] = 1; + mask[i] = 0; + } + } + else { + fail[i] = 0; + } + } + break; + case GL_LEQUAL: + r = (GLstencil) (ctx->Stencil.Ref & ctx->Stencil.ValueMask); + for (i=0;iStencil.ValueMask); + if (r <= s) { + /* pass */ + fail[i] = 0; + } + else { + fail[i] = 1; + mask[i] = 0; + } + } + else { + fail[i] = 0; + } + } + break; + case GL_GREATER: + r = (GLstencil) (ctx->Stencil.Ref & ctx->Stencil.ValueMask); + for (i=0;iStencil.ValueMask); + if (r > s) { + /* passed */ + fail[i] = 0; + } + else { + fail[i] = 1; + mask[i] = 0; + } + } + else { + fail[i] = 0; + } + } + break; + case GL_GEQUAL: + r = (GLstencil) (ctx->Stencil.Ref & ctx->Stencil.ValueMask); + for (i=0;iStencil.ValueMask); + if (r >= s) { + /* passed */ + fail[i] = 0; + } + else { + fail[i] = 1; + mask[i] = 0; + } + } + else { + fail[i] = 0; + } + } + break; + case GL_EQUAL: + r = (GLstencil) (ctx->Stencil.Ref & ctx->Stencil.ValueMask); + for (i=0;iStencil.ValueMask); + if (r == s) { + /* passed */ + fail[i] = 0; + } + else { + fail[i] = 1; + mask[i] = 0; + } + } + else { + fail[i] = 0; + } + } + break; + case GL_NOTEQUAL: + r = (GLstencil) (ctx->Stencil.Ref & ctx->Stencil.ValueMask); + for (i=0;iStencil.ValueMask); + if (r != s) { + /* passed */ + fail[i] = 0; + } + else { + fail[i] = 1; + mask[i] = 0; + } + } + else { + fail[i] = 0; + } + } + break; + case GL_ALWAYS: + /* always pass */ + for (i=0;iStencil.FailFunc != GL_KEEP) { + apply_stencil_op_to_pixels( ctx, n, x, y, ctx->Stencil.FailFunc, fail ); + } + + return !allfail; +} + + + + +/* + * Apply stencil and depth testing to an array of pixels. + * This is used both for software and hardware stencil buffers. + * + * The comments in this function are a bit sparse but the code is + * almost identical to stencil_and_ztest_span(), which is well + * commented. + * + * Input: n - number of pixels in the array + * x, y - array of [n] pixel positions + * z - array [n] of z values + * mask - array [n] of flags (1=test this pixel, 0=skip the pixel) + * Output: mask - array [n] of flags (1=stencil and depth test passed) + * Return: GL_TRUE - all fragments failed the testing + * GL_FALSE - one or more fragments passed the testing + */ +GLboolean +_mesa_stencil_and_ztest_pixels( GLcontext *ctx, + GLuint n, const GLint x[], const GLint y[], + const GLdepth z[], GLubyte mask[] ) +{ + SWcontext *swrast = SWRAST_CONTEXT(ctx); + ASSERT(ctx->Stencil.Enabled); + ASSERT(n <= PB_SIZE); + + if (swrast->Driver.WriteStencilPixels) { + /*** Hardware stencil buffer ***/ + GLstencil stencil[PB_SIZE]; + GLubyte origMask[PB_SIZE]; + + ASSERT(swrast->Driver.ReadStencilPixels); + (*swrast->Driver.ReadStencilPixels)(ctx, n, x, y, stencil); + + MEMCPY(origMask, mask, n * sizeof(GLubyte)); + + (void) do_stencil_test(ctx, n, stencil, mask); + + if (ctx->Depth.Test == GL_FALSE) { + apply_stencil_op(ctx, ctx->Stencil.ZPassFunc, n, stencil, mask); + } + else { + _mesa_depth_test_pixels(ctx, n, x, y, z, mask); + + if (ctx->Stencil.ZFailFunc != GL_KEEP) { + GLubyte failmask[PB_SIZE]; + GLuint i; + for (i = 0; i < n; i++) { + ASSERT(mask[i] == 0 || mask[i] == 1); + failmask[i] = origMask[i] & (mask[i] ^ 1); + } + apply_stencil_op(ctx, ctx->Stencil.ZFailFunc, + n, stencil, failmask); + } + if (ctx->Stencil.ZPassFunc != GL_KEEP) { + GLubyte passmask[PB_SIZE]; + GLuint i; + for (i = 0; i < n; i++) { + ASSERT(mask[i] == 0 || mask[i] == 1); + passmask[i] = origMask[i] & mask[i]; + } + apply_stencil_op(ctx, ctx->Stencil.ZPassFunc, + n, stencil, passmask); + } + } + + /* Write updated stencil values into hardware stencil buffer */ + (swrast->Driver.WriteStencilPixels)(ctx, n, x, y, stencil, origMask); + + return GL_TRUE; + } + else { + /*** Software stencil buffer ***/ + + if (stencil_test_pixels(ctx, n, x, y, mask) == GL_FALSE) { + /* all fragments failed the stencil test, we're done. */ + return GL_FALSE; + } + + if (ctx->Depth.Test==GL_FALSE) { + apply_stencil_op_to_pixels(ctx, n, x, y, + ctx->Stencil.ZPassFunc, mask); + } + else { + GLubyte passmask[PB_SIZE], failmask[PB_SIZE], oldmask[PB_SIZE]; + GLuint i; + + MEMCPY(oldmask, mask, n * sizeof(GLubyte)); + + _mesa_depth_test_pixels(ctx, n, x, y, z, mask); + + for (i=0;iStencil.ZFailFunc != GL_KEEP) { + apply_stencil_op_to_pixels(ctx, n, x, y, + ctx->Stencil.ZFailFunc, failmask); + } + if (ctx->Stencil.ZPassFunc != GL_KEEP) { + apply_stencil_op_to_pixels(ctx, n, x, y, + ctx->Stencil.ZPassFunc, passmask); + } + } + + return GL_TRUE; /* one or more fragments passed both tests */ + } +} + + + +/* + * Return a span of stencil values from the stencil buffer. + * Used for glRead/CopyPixels + * Input: n - how many pixels + * x,y - location of first pixel + * Output: stencil - the array of stencil values + */ +void +_mesa_read_stencil_span( GLcontext *ctx, + GLint n, GLint x, GLint y, GLstencil stencil[] ) +{ + SWcontext *swrast = SWRAST_CONTEXT(ctx); + if (y < 0 || y >= ctx->DrawBuffer->Height || + x + n <= 0 || x >= ctx->DrawBuffer->Width) { + /* span is completely outside framebuffer */ + return; /* undefined values OK */ + } + + if (x < 0) { + GLint dx = -x; + x = 0; + n -= dx; + stencil += dx; + } + if (x + n > ctx->DrawBuffer->Width) { + GLint dx = x + n - ctx->DrawBuffer->Width; + n -= dx; + } + if (n <= 0) { + return; + } + + + ASSERT(n >= 0); + if (swrast->Driver.ReadStencilSpan) { + (*swrast->Driver.ReadStencilSpan)( ctx, (GLuint) n, x, y, stencil ); + } + else if (ctx->DrawBuffer->Stencil) { + const GLstencil *s = STENCIL_ADDRESS( x, y ); +#if STENCIL_BITS == 8 + MEMCPY( stencil, s, n * sizeof(GLstencil) ); +#else + GLuint i; + for (i=0;i= ctx->DrawBuffer->Height || + x + n <= 0 || x >= ctx->DrawBuffer->Width) { + /* span is completely outside framebuffer */ + return; /* undefined values OK */ + } + + if (x < 0) { + GLint dx = -x; + x = 0; + n -= dx; + stencil += dx; + } + if (x + n > ctx->DrawBuffer->Width) { + GLint dx = x + n - ctx->DrawBuffer->Width; + n -= dx; + } + if (n <= 0) { + return; + } + + if (swrast->Driver.WriteStencilSpan) { + (*swrast->Driver.WriteStencilSpan)( ctx, n, x, y, stencil, NULL ); + } + else if (ctx->DrawBuffer->Stencil) { + GLstencil *s = STENCIL_ADDRESS( x, y ); +#if STENCIL_BITS == 8 + MEMCPY( s, stencil, n * sizeof(GLstencil) ); +#else + GLuint i; + for (i=0;iDrawBuffer->Width * ctx->DrawBuffer->Height; + + /* deallocate current stencil buffer if present */ + if (ctx->DrawBuffer->Stencil) { + FREE(ctx->DrawBuffer->Stencil); + ctx->DrawBuffer->Stencil = NULL; + } + + /* allocate new stencil buffer */ + ctx->DrawBuffer->Stencil = (GLstencil *) MALLOC(buffersize * sizeof(GLstencil)); + if (!ctx->DrawBuffer->Stencil) { + /* out of memory */ +/* _mesa_set_enable( ctx, GL_STENCIL_TEST, GL_FALSE ); */ + _mesa_error( ctx, GL_OUT_OF_MEMORY, "_mesa_alloc_stencil_buffer" ); + } +} + + + +/* + * Clear the software (malloc'd) stencil buffer. + */ +static void +clear_software_stencil_buffer( GLcontext *ctx ) +{ + if (ctx->Visual.stencilBits==0 || !ctx->DrawBuffer->Stencil) { + /* no stencil buffer */ + return; + } + + if (ctx->Scissor.Enabled) { + /* clear scissor region only */ + const GLint width = ctx->DrawBuffer->_Xmax - ctx->DrawBuffer->_Xmin; + if (ctx->Stencil.WriteMask != STENCIL_MAX) { + /* must apply mask to the clear */ + GLint y; + for (y = ctx->DrawBuffer->_Ymin; y < ctx->DrawBuffer->_Ymax; y++) { + const GLstencil mask = ctx->Stencil.WriteMask; + const GLstencil invMask = ~mask; + const GLstencil clearVal = (ctx->Stencil.Clear & mask); + GLstencil *stencil = STENCIL_ADDRESS( ctx->DrawBuffer->_Xmin, y ); + GLint i; + for (i = 0; i < width; i++) { + stencil[i] = (stencil[i] & invMask) | clearVal; + } + } + } + else { + /* no masking */ + GLint y; + for (y = ctx->DrawBuffer->_Ymin; y < ctx->DrawBuffer->_Ymax; y++) { + GLstencil *stencil = STENCIL_ADDRESS( ctx->DrawBuffer->_Xmin, y ); +#if STENCIL_BITS==8 + MEMSET( stencil, ctx->Stencil.Clear, width * sizeof(GLstencil) ); +#else + GLint i; + for (i = 0; i < width; i++) + stencil[x] = ctx->Stencil.Clear; +#endif + } + } + } + else { + /* clear whole stencil buffer */ + if (ctx->Stencil.WriteMask != STENCIL_MAX) { + /* must apply mask to the clear */ + const GLuint n = ctx->DrawBuffer->Width * ctx->DrawBuffer->Height; + GLstencil *stencil = ctx->DrawBuffer->Stencil; + const GLstencil mask = ctx->Stencil.WriteMask; + const GLstencil invMask = ~mask; + const GLstencil clearVal = (ctx->Stencil.Clear & mask); + GLuint i; + for (i = 0; i < n; i++) { + stencil[i] = (stencil[i] & invMask) | clearVal; + } + } + else { + /* clear whole buffer without masking */ + const GLuint n = ctx->DrawBuffer->Width * ctx->DrawBuffer->Height; + GLstencil *stencil = ctx->DrawBuffer->Stencil; + +#if STENCIL_BITS==8 + MEMSET(stencil, ctx->Stencil.Clear, n * sizeof(GLstencil) ); +#else + GLuint i; + for (i = 0; i < n; i++) { + stencil[i] = ctx->Stencil.Clear; + } +#endif + } + } +} + + + +/* + * Clear the hardware (in graphics card) stencil buffer. + * This is done with the Driver.WriteStencilSpan() and Driver.ReadStencilSpan() + * functions. + * Actually, if there is a hardware stencil buffer it really should have + * been cleared in Driver.Clear()! However, if the hardware does not + * support scissored clears or masked clears (i.e. glStencilMask) then + * we have to use the span-based functions. + */ +static void +clear_hardware_stencil_buffer( GLcontext *ctx ) +{ + SWcontext *swrast = SWRAST_CONTEXT(ctx); + ASSERT(swrast->Driver.WriteStencilSpan); + ASSERT(swrast->Driver.ReadStencilSpan); + + if (ctx->Scissor.Enabled) { + /* clear scissor region only */ + const GLint x = ctx->DrawBuffer->_Xmin; + const GLint width = ctx->DrawBuffer->_Xmax - ctx->DrawBuffer->_Xmin; + if (ctx->Stencil.WriteMask != STENCIL_MAX) { + /* must apply mask to the clear */ + GLint y; + for (y = ctx->DrawBuffer->_Ymin; y < ctx->DrawBuffer->_Ymax; y++) { + const GLstencil mask = ctx->Stencil.WriteMask; + const GLstencil invMask = ~mask; + const GLstencil clearVal = (ctx->Stencil.Clear & mask); + GLstencil stencil[MAX_WIDTH]; + GLint i; + (*swrast->Driver.ReadStencilSpan)(ctx, width, x, y, stencil); + for (i = 0; i < width; i++) { + stencil[i] = (stencil[i] & invMask) | clearVal; + } + (*swrast->Driver.WriteStencilSpan)(ctx, width, x, y, stencil, NULL); + } + } + else { + /* no masking */ + GLstencil stencil[MAX_WIDTH]; + GLint y, i; + for (i = 0; i < width; i++) { + stencil[i] = ctx->Stencil.Clear; + } + for (y = ctx->DrawBuffer->_Ymin; y < ctx->DrawBuffer->_Ymax; y++) { + (*swrast->Driver.WriteStencilSpan)(ctx, width, x, y, stencil, NULL); + } + } + } + else { + /* clear whole stencil buffer */ + if (ctx->Stencil.WriteMask != STENCIL_MAX) { + /* must apply mask to the clear */ + const GLstencil mask = ctx->Stencil.WriteMask; + const GLstencil invMask = ~mask; + const GLstencil clearVal = (ctx->Stencil.Clear & mask); + const GLint width = ctx->DrawBuffer->Width; + const GLint height = ctx->DrawBuffer->Height; + const GLint x = ctx->DrawBuffer->_Xmin; + GLint y; + for (y = 0; y < height; y++) { + GLstencil stencil[MAX_WIDTH]; + GLint i; + (*swrast->Driver.ReadStencilSpan)(ctx, width, x, y, stencil); + for (i = 0; i < width; i++) { + stencil[i] = (stencil[i] & invMask) | clearVal; + } + (*swrast->Driver.WriteStencilSpan)(ctx, width, x, y, stencil, NULL); + } + } + else { + /* clear whole buffer without masking */ + const GLint width = ctx->DrawBuffer->Width; + const GLint height = ctx->DrawBuffer->Height; + const GLint x = ctx->DrawBuffer->_Xmin; + GLstencil stencil[MAX_WIDTH]; + GLint y, i; + for (i = 0; i < width; i++) { + stencil[i] = ctx->Stencil.Clear; + } + for (y = 0; y < height; y++) { + (*swrast->Driver.WriteStencilSpan)(ctx, width, x, y, stencil, NULL); + } + } + } +} + + + +/* + * Clear the stencil buffer. + */ +void +_mesa_clear_stencil_buffer( GLcontext *ctx ) +{ + SWcontext *swrast = SWRAST_CONTEXT(ctx); + if (swrast->Driver.WriteStencilSpan) { + ASSERT(swrast->Driver.ReadStencilSpan); + clear_hardware_stencil_buffer(ctx); + } + else { + clear_software_stencil_buffer(ctx); + } +} Index: dll/opengl/opengl32/mesa/swrast/s_stencil.h =================================================================== --- dll/opengl/opengl32/mesa/swrast/s_stencil.h (revision 0) +++ dll/opengl/opengl32/mesa/swrast/s_stencil.h (working copy) @@ -0,0 +1,64 @@ +/* $Id: s_stencil.h,v 1.3 2001/03/12 00:48:42 gareth Exp $ */ + +/* + * Mesa 3-D graphics library + * Version: 3.5 + * + * Copyright (C) 1999-2001 Brian Paul 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 + * BRIAN PAUL 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. + */ + + +#ifndef S_STENCIL_H +#define S_STENCIL_H + + +#include "mtypes.h" +#include "swrast.h" + + +extern GLboolean +_mesa_stencil_and_ztest_span( GLcontext *ctx, GLuint n, GLint x, GLint y, + const GLdepth z[], GLubyte mask[] ); + +extern GLboolean +_mesa_stencil_and_ztest_pixels( GLcontext *ctx, GLuint n, + const GLint x[], const GLint y[], + const GLdepth z[], GLubyte mask[] ); + + +extern void +_mesa_read_stencil_span( GLcontext *ctx, GLint n, GLint x, GLint y, + GLstencil stencil[] ); + + +extern void +_mesa_write_stencil_span( GLcontext *ctx, GLint n, GLint x, GLint y, + const GLstencil stencil[] ); + + +extern void +_mesa_alloc_stencil_buffer( GLcontext *ctx ); + + +extern void +_mesa_clear_stencil_buffer( GLcontext *ctx ); + + +#endif Index: dll/opengl/opengl32/mesa/swrast/s_texstore.c =================================================================== --- dll/opengl/opengl32/mesa/swrast/s_texstore.c (revision 0) +++ dll/opengl/opengl32/mesa/swrast/s_texstore.c (working copy) @@ -0,0 +1,481 @@ +/* $Id: s_texstore.c,v 1.5 2001/05/21 16:41:04 brianp Exp $ */ + +/* + * Mesa 3-D graphics library + * Version: 3.5 + * + * Copyright (C) 1999-2001 Brian Paul 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 + * BRIAN PAUL 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. + */ + +/* + * Authors: + * Brian Paul + */ + + +/* + * The functions in this file are mostly related to software texture fallbacks. + * This includes texture image transfer/packing and texel fetching. + * Hardware drivers will likely override most of this. + */ + + + +#include "colormac.h" +#include "context.h" +#include "convolve.h" +#include "image.h" +#include "macros.h" +#include "mem.h" +#include "texformat.h" +#include "teximage.h" +#include "texstore.h" + +#include "s_context.h" +#include "s_depth.h" +#include "s_span.h" + +/* + * Read an RGBA image from the frame buffer. + * This is used by glCopyTex[Sub]Image[12]D(). + * Input: ctx - the context + * x, y - lower left corner + * width, height - size of region to read + * Return: pointer to block of GL_RGBA, GLchan data. + */ +static GLchan * +read_color_image( GLcontext *ctx, GLint x, GLint y, + GLsizei width, GLsizei height ) +{ + SWcontext *swrast = SWRAST_CONTEXT(ctx); + GLint stride, i; + GLchan *image, *dst; + + image = (GLchan *) MALLOC(width * height * 4 * sizeof(GLchan)); + if (!image) + return NULL; + + /* Select buffer to read from */ + (*swrast->Driver.SetReadBuffer)( ctx, ctx->ReadBuffer, + ctx->Pixel.DriverReadBuffer ); + + RENDER_START(swrast,ctx); + + dst = image; + stride = width * 4; + for (i = 0; i < height; i++) { + _mesa_read_rgba_span( ctx, ctx->ReadBuffer, width, x, y + i, + (GLchan (*)[4]) dst ); + dst += stride; + } + + RENDER_FINISH(swrast,ctx); + + /* Read from draw buffer (the default) */ + (*swrast->Driver.SetReadBuffer)( ctx, ctx->DrawBuffer, + ctx->Color.DriverDrawBuffer ); + + return image; +} + + +/* + * As above, but read data from depth buffer. + */ +static GLfloat * +read_depth_image( GLcontext *ctx, GLint x, GLint y, + GLsizei width, GLsizei height ) +{ + SWcontext *swrast = SWRAST_CONTEXT(ctx); + GLfloat *image, *dst; + GLint i; + + image = (GLfloat *) MALLOC(width * height * sizeof(GLfloat)); + if (!image) + return NULL; + + RENDER_START(swrast,ctx); + + dst = image; + for (i = 0; i < height; i++) { + _mesa_read_depth_span_float(ctx, width, x, y + i, dst); + dst += width; + } + + RENDER_FINISH(swrast,ctx); + + return image; +} + + + +static GLboolean +is_depth_format(GLenum format) +{ + switch (format) { + case GL_DEPTH_COMPONENT: + case GL_DEPTH_COMPONENT16_SGIX: + case GL_DEPTH_COMPONENT24_SGIX: + case GL_DEPTH_COMPONENT32_SGIX: + return GL_TRUE; + default: + return GL_FALSE; + } +} + + +/* + * Fallback for Driver.CopyTexImage1D(). + */ +void +_swrast_copy_teximage1d( GLcontext *ctx, GLenum target, GLint level, + GLenum internalFormat, + GLint x, GLint y, GLsizei width, GLint border ) +{ + struct gl_texture_unit *texUnit; + struct gl_texture_object *texObj; + struct gl_texture_image *texImage; + + texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit]; + texObj = _mesa_select_tex_object(ctx, texUnit, target); + ASSERT(texObj); + texImage = _mesa_select_tex_image(ctx, texUnit, target, level); + ASSERT(texImage); + + ASSERT(ctx->Driver.TexImage1D); + + if (is_depth_format(internalFormat)) { + /* read depth image from framebuffer */ + GLfloat *image = read_depth_image(ctx, x, y, width, 1); + if (!image) { + _mesa_error(ctx, GL_OUT_OF_MEMORY, "glCopyTexImage1D"); + return; + } + + /* call glTexImage1D to redefine the texture */ + (*ctx->Driver.TexImage1D)(ctx, target, level, internalFormat, + width, border, + GL_DEPTH_COMPONENT, GL_FLOAT, image, + &_mesa_native_packing, texObj, texImage); + FREE(image); + } + else { + /* read RGBA image from framebuffer */ + GLchan *image = read_color_image(ctx, x, y, width, 1); + if (!image) { + _mesa_error(ctx, GL_OUT_OF_MEMORY, "glCopyTexImage1D"); + return; + } + + /* call glTexImage1D to redefine the texture */ + (*ctx->Driver.TexImage1D)(ctx, target, level, internalFormat, + width, border, + GL_RGBA, CHAN_TYPE, image, + &_mesa_native_packing, texObj, texImage); + FREE(image); + } + + /* GL_SGIS_generate_mipmap */ + if (level == texObj->BaseLevel && texObj->GenerateMipmap) { + _mesa_generate_mipmap(ctx, texUnit, texObj); + } +} + + +/* + * Fallback for Driver.CopyTexImage2D(). + */ +void +_swrast_copy_teximage2d( GLcontext *ctx, GLenum target, GLint level, + GLenum internalFormat, + GLint x, GLint y, GLsizei width, GLsizei height, + GLint border ) +{ + struct gl_texture_unit *texUnit; + struct gl_texture_object *texObj; + struct gl_texture_image *texImage; + + texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit]; + texObj = _mesa_select_tex_object(ctx, texUnit, target); + ASSERT(texObj); + texImage = _mesa_select_tex_image(ctx, texUnit, target, level); + ASSERT(texImage); + + ASSERT(ctx->Driver.TexImage2D); + + if (is_depth_format(internalFormat)) { + /* read depth image from framebuffer */ + GLfloat *image = read_depth_image(ctx, x, y, width, height); + if (!image) { + _mesa_error(ctx, GL_OUT_OF_MEMORY, "glCopyTexImage2D"); + return; + } + + /* call glTexImage2D to redefine the texture */ + (*ctx->Driver.TexImage2D)(ctx, target, level, internalFormat, + width, height, border, + GL_DEPTH_COMPONENT, GL_FLOAT, image, + &_mesa_native_packing, texObj, texImage); + FREE(image); + } + else { + /* read RGBA image from framebuffer */ + GLchan *image = read_color_image(ctx, x, y, width, height); + if (!image) { + _mesa_error(ctx, GL_OUT_OF_MEMORY, "glCopyTexImage2D"); + return; + } + + /* call glTexImage2D to redefine the texture */ + (*ctx->Driver.TexImage2D)(ctx, target, level, internalFormat, + width, height, border, + GL_RGBA, CHAN_TYPE, image, + &_mesa_native_packing, texObj, texImage); + FREE(image); + } + + /* GL_SGIS_generate_mipmap */ + if (level == texObj->BaseLevel && texObj->GenerateMipmap) { + _mesa_generate_mipmap(ctx, texUnit, texObj); + } +} + + +/* + * Fallback for Driver.CopyTexSubImage1D(). + */ +void +_swrast_copy_texsubimage1d(GLcontext *ctx, GLenum target, GLint level, + GLint xoffset, GLint x, GLint y, GLsizei width) +{ + struct gl_texture_unit *texUnit; + struct gl_texture_object *texObj; + struct gl_texture_image *texImage; + + texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit]; + texObj = _mesa_select_tex_object(ctx, texUnit, target); + ASSERT(texObj); + texImage = _mesa_select_tex_image(ctx, texUnit, target, level); + ASSERT(texImage); + + ASSERT(ctx->Driver.TexImage1D); + + if (texImage->Format != GL_DEPTH_COMPONENT) { + /* read RGBA image from framebuffer */ + GLchan *image = read_color_image(ctx, x, y, width, 1); + if (!image) { + _mesa_error( ctx, GL_OUT_OF_MEMORY, "glCopyTexSubImage1D" ); + return; + } + +#if 0 + /* + * XXX this is a bit of a hack. We need to be sure that the alpha + * channel is 1.0 if the internal texture format is not supposed to + * have an alpha channel. This is because some drivers may store + * RGB textures as RGBA and the texutil.c code isn't smart enough + * to set the alpha channel to 1.0 in this situation. + */ + if (texImage->Format == GL_LUMINANCE || + texImage->Format == GL_RGB) { + const GLuint n = width * 4; + GLuint i; + for (i = 0; i < n; i += 4) { + image[i + 3] = CHAN_MAX; + } + } +#endif + /* now call glTexSubImage1D to do the real work */ + (*ctx->Driver.TexSubImage1D)(ctx, target, level, xoffset, width, + GL_RGBA, CHAN_TYPE, image, + &_mesa_native_packing, texObj, texImage); + FREE(image); + } + else { + /* read depth image from framebuffer */ + GLfloat *image = read_depth_image(ctx, x, y, width, 1); + if (!image) { + _mesa_error(ctx, GL_OUT_OF_MEMORY, "glCopyTexSubImage1D"); + return; + } + + /* call glTexSubImage1D to redefine the texture */ + (*ctx->Driver.TexSubImage1D)(ctx, target, level, xoffset, width, + GL_DEPTH_COMPONENT, GL_FLOAT, image, + &_mesa_native_packing, texObj, texImage); + FREE(image); + } + + /* GL_SGIS_generate_mipmap */ + if (level == texObj->BaseLevel && texObj->GenerateMipmap) { + _mesa_generate_mipmap(ctx, texUnit, texObj); + } +} + + +/* + * Fallback for Driver.CopyTexSubImage2D(). + */ +void +_swrast_copy_texsubimage2d( GLcontext *ctx, + GLenum target, GLint level, + GLint xoffset, GLint yoffset, + GLint x, GLint y, GLsizei width, GLsizei height ) +{ + struct gl_texture_unit *texUnit; + struct gl_texture_object *texObj; + struct gl_texture_image *texImage; + + texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit]; + texObj = _mesa_select_tex_object(ctx, texUnit, target); + ASSERT(texObj); + texImage = _mesa_select_tex_image(ctx, texUnit, target, level); + ASSERT(texImage); + + ASSERT(ctx->Driver.TexImage2D); + + if (texImage->Format != GL_DEPTH_COMPONENT) { + /* read RGBA image from framebuffer */ + GLchan *image = read_color_image(ctx, x, y, width, height); + if (!image) { + _mesa_error( ctx, GL_OUT_OF_MEMORY, "glCopyTexSubImage2D" ); + return; + } + +#if 0 + /* + * XXX this is a bit of a hack. We need to be sure that the alpha + * channel is 1.0 if the internal texture format is not supposed to + * have an alpha channel. This is because some drivers may store + * RGB textures as RGBA and the texutil.c code isn't smart enough + * to set the alpha channel to 1.0 in this situation. + */ + if (texImage->Format == GL_LUMINANCE || + texImage->Format == GL_RGB) { + const GLuint n = width * height * 4; + GLuint i; + for (i = 0; i < n; i += 4) { + image[i + 3] = CHAN_MAX; + } + } +#endif + /* now call glTexSubImage2D to do the real work */ + (*ctx->Driver.TexSubImage2D)(ctx, target, level, + xoffset, yoffset, width, height, + GL_RGBA, CHAN_TYPE, image, + &_mesa_native_packing, texObj, texImage); + FREE(image); + } + else { + /* read depth image from framebuffer */ + GLfloat *image = read_depth_image(ctx, x, y, width, height); + if (!image) { + _mesa_error(ctx, GL_OUT_OF_MEMORY, "glCopyTexSubImage2D"); + return; + } + + /* call glTexImage1D to redefine the texture */ + (*ctx->Driver.TexSubImage2D)(ctx, target, level, + xoffset, yoffset, width, height, + GL_DEPTH_COMPONENT, GL_FLOAT, image, + &_mesa_native_packing, texObj, texImage); + FREE(image); + } + + /* GL_SGIS_generate_mipmap */ + if (level == texObj->BaseLevel && texObj->GenerateMipmap) { + _mesa_generate_mipmap(ctx, texUnit, texObj); + } +} + + +/* + * Fallback for Driver.CopyTexSubImage3D(). + */ +void +_swrast_copy_texsubimage3d( GLcontext *ctx, + GLenum target, GLint level, + GLint xoffset, GLint yoffset, GLint zoffset, + GLint x, GLint y, GLsizei width, GLsizei height ) +{ + struct gl_texture_unit *texUnit; + struct gl_texture_object *texObj; + struct gl_texture_image *texImage; + + texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit]; + texObj = _mesa_select_tex_object(ctx, texUnit, target); + ASSERT(texObj); + texImage = _mesa_select_tex_image(ctx, texUnit, target, level); + ASSERT(texImage); + + ASSERT(ctx->Driver.TexImage3D); + + if (texImage->Format != GL_DEPTH_COMPONENT) { + /* read RGBA image from framebuffer */ + GLchan *image = read_color_image(ctx, x, y, width, height); + if (!image) { + _mesa_error( ctx, GL_OUT_OF_MEMORY, "glCopyTexSubImage3D" ); + return; + } +#if 0 + /* + * XXX this is a bit of a hack. We need to be sure that the alpha + * channel is 1.0 if the internal texture format is not supposed to + * have an alpha channel. This is because some drivers may store + * RGB textures as RGBA and the texutil.c code isn't smart enough + * to set the alpha channel to 1.0 in this situation. + */ + if (texImage->Format == GL_LUMINANCE || + texImage->Format == GL_RGB) { + const GLuint n = width * height * 4; + GLuint i; + for (i = 0; i < n; i += 4) { + image[i + 3] = CHAN_MAX; + } + } +#endif + /* now call glTexSubImage3D to do the real work */ + (*ctx->Driver.TexSubImage3D)(ctx, target, level, + xoffset, yoffset, zoffset, width, height, 1, + GL_RGBA, CHAN_TYPE, image, + &_mesa_native_packing, texObj, texImage); + FREE(image); + } + else { + /* read depth image from framebuffer */ + GLfloat *image = read_depth_image(ctx, x, y, width, height); + if (!image) { + _mesa_error(ctx, GL_OUT_OF_MEMORY, "glCopyTexSubImage3D"); + return; + } + + /* call glTexImage1D to redefine the texture */ + (*ctx->Driver.TexSubImage3D)(ctx, target, level, + xoffset, yoffset, zoffset, width, height, 1, + GL_DEPTH_COMPONENT, GL_FLOAT, image, + &_mesa_native_packing, texObj, texImage); + FREE(image); + } + + /* GL_SGIS_generate_mipmap */ + if (level == texObj->BaseLevel && texObj->GenerateMipmap) { + _mesa_generate_mipmap(ctx, texUnit, texObj); + } +} Index: dll/opengl/opengl32/mesa/swrast/s_texture.c =================================================================== --- dll/opengl/opengl32/mesa/swrast/s_texture.c (revision 0) +++ dll/opengl/opengl32/mesa/swrast/s_texture.c (working copy) @@ -0,0 +1,2834 @@ +/* $Id: s_texture.c,v 1.32 2001/06/01 13:23:27 brianp Exp $ */ + +/* + * Mesa 3-D graphics library + * Version: 3.5 + * + * Copyright (C) 1999-2001 Brian Paul 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 + * BRIAN PAUL 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. + */ + + +#include "glheader.h" +#include "context.h" +#include "colormac.h" +#include "macros.h" +#include "mmath.h" +#include "mem.h" +#include "texformat.h" +#include "teximage.h" + +#include "s_context.h" +#include "s_pb.h" +#include "s_texture.h" + + +/* + * These values are used in the fixed-point arithmetic used + * for linear filtering. + */ +#define WEIGHT_SCALE 65536.0F +#define WEIGHT_SHIFT 16 + + +/* + * Used to compute texel locations for linear sampling. + * Input: + * wrapMode = GL_REPEAT, GL_CLAMP, GL_CLAMP_TO_EDGE, GL_CLAMP_TO_BORDER_ARB + * S = texcoord in [0,1] + * SIZE = width (or height or depth) of texture + * Output: + * U = texcoord in [0, width] + * I0, I1 = two nearest texel indexes + */ +#define COMPUTE_LINEAR_TEXEL_LOCATIONS(wrapMode, S, U, SIZE, I0, I1) \ +{ \ + if (wrapMode == GL_REPEAT) { \ + U = S * SIZE - 0.5F; \ + I0 = IFLOOR(U) & (SIZE - 1); \ + I1 = (I0 + 1) & (SIZE - 1); \ + } \ + else if (wrapMode == GL_CLAMP_TO_EDGE) { \ + if (S <= 0.0F) \ + U = 0.0F; \ + else if (S >= 1.0F) \ + U = SIZE; \ + else \ + U = S * SIZE; \ + U -= 0.5F; \ + I0 = IFLOOR(U); \ + I1 = I0 + 1; \ + if (I0 < 0) \ + I0 = 0; \ + if (I1 >= (GLint) SIZE) \ + I1 = SIZE - 1; \ + } \ + else if (wrapMode == GL_CLAMP_TO_BORDER_ARB) { \ + const GLfloat min = -1.0F / (2.0F * SIZE); \ + const GLfloat max = 1.0F - min; \ + if (S <= min) \ + U = min * SIZE; \ + else if (S >= max) \ + U = max * SIZE; \ + else \ + U = S * SIZE; \ + U -= 0.5F; \ + I0 = IFLOOR(U); \ + I1 = I0 + 1; \ + } \ + else { \ + ASSERT(wrapMode == GL_CLAMP); \ + if (S <= 0.0F) \ + U = 0.0F; \ + else if (S >= 1.0F) \ + U = SIZE; \ + else \ + U = S * SIZE; \ + U -= 0.5F; \ + I0 = IFLOOR(U); \ + I1 = I0 + 1; \ + } \ +} + + +/* + * Used to compute texel location for nearest sampling. + */ +#define COMPUTE_NEAREST_TEXEL_LOCATION(wrapMode, S, SIZE, I) \ +{ \ + if (wrapMode == GL_REPEAT) { \ + /* s limited to [0,1) */ \ + /* i limited to [0,size-1] */ \ + I = IFLOOR(S * SIZE); \ + I &= (SIZE - 1); \ + } \ + else if (wrapMode == GL_CLAMP_TO_EDGE) { \ + /* s limited to [min,max] */ \ + /* i limited to [0, size-1] */ \ + const GLfloat min = 1.0F / (2.0F * SIZE); \ + const GLfloat max = 1.0F - min; \ + if (S < min) \ + I = 0; \ + else if (S > max) \ + I = SIZE - 1; \ + else \ + I = IFLOOR(S * SIZE); \ + } \ + else if (wrapMode == GL_CLAMP_TO_BORDER_ARB) { \ + /* s limited to [min,max] */ \ + /* i limited to [-1, size] */ \ + const GLfloat min = -1.0F / (2.0F * SIZE); \ + const GLfloat max = 1.0F - min; \ + if (S <= min) \ + I = -1; \ + else if (S >= max) \ + I = SIZE; \ + else \ + I = IFLOOR(S * SIZE); \ + } \ + else { \ + ASSERT(wrapMode == GL_CLAMP); \ + /* s limited to [0,1] */ \ + /* i limited to [0,size-1] */ \ + if (S <= 0.0F) \ + I = 0; \ + else if (S >= 1.0F) \ + I = SIZE - 1; \ + else \ + I = IFLOOR(S * SIZE); \ + } \ +} + + +/* + * Compute linear mipmap levels for given lambda. + */ +#define COMPUTE_LINEAR_MIPMAP_LEVEL(tObj, lambda, level) \ +{ \ + if (lambda < 0.0F) \ + lambda = 0.0F; \ + else if (lambda > tObj->_MaxLambda) \ + lambda = tObj->_MaxLambda; \ + level = (GLint) (tObj->BaseLevel + lambda); \ +} + + +/* + * Compute nearest mipmap level for given lambda. + */ +#define COMPUTE_NEAREST_MIPMAP_LEVEL(tObj, lambda, level) \ +{ \ + if (lambda <= 0.5F) \ + lambda = 0.0F; \ + else if (lambda > tObj->_MaxLambda + 0.4999F) \ + lambda = tObj->_MaxLambda + 0.4999F; \ + level = (GLint) (tObj->BaseLevel + lambda + 0.5F); \ + if (level > tObj->_MaxLevel) \ + level = tObj->_MaxLevel; \ +} + + + +/* + * Note, the FRAC macro has to work perfectly. Otherwise you'll sometimes + * see 1-pixel bands of improperly weighted linear-sampled texels. The + * tests/texwrap.c demo is a good test. + * Also note, FRAC(x) doesn't truly return the fractional part of x for x < 0. + * Instead, if x < 0 then FRAC(x) = 1 - true_frac(x). + */ +#define FRAC(f) ((f) - IFLOOR(f)) + + + +/* + * Bitflags for texture border color sampling. + */ +#define I0BIT 1 +#define I1BIT 2 +#define J0BIT 4 +#define J1BIT 8 +#define K0BIT 16 +#define K1BIT 32 + + + +/* + * Get texture palette entry. + */ +static void +palette_sample(const GLcontext *ctx, + const struct gl_texture_object *tObj, + GLint index, GLchan rgba[4] ) +{ + const GLchan *palette; + GLenum format; + + if (ctx->Texture.SharedPalette) { + ASSERT(!ctx->Texture.Palette.FloatTable); + palette = (const GLchan *) ctx->Texture.Palette.Table; + format = ctx->Texture.Palette.Format; + } + else { + ASSERT(!tObj->Palette.FloatTable); + palette = (const GLchan *) tObj->Palette.Table; + format = tObj->Palette.Format; + } + + switch (format) { + case GL_ALPHA: + rgba[ACOMP] = palette[index]; + return; + case GL_LUMINANCE: + case GL_INTENSITY: + rgba[RCOMP] = palette[index]; + return; + case GL_LUMINANCE_ALPHA: + rgba[RCOMP] = palette[(index << 1) + 0]; + rgba[ACOMP] = palette[(index << 1) + 1]; + return; + case GL_RGB: + rgba[RCOMP] = palette[index * 3 + 0]; + rgba[GCOMP] = palette[index * 3 + 1]; + rgba[BCOMP] = palette[index * 3 + 2]; + return; + case GL_RGBA: + rgba[RCOMP] = palette[(index << 2) + 0]; + rgba[GCOMP] = palette[(index << 2) + 1]; + rgba[BCOMP] = palette[(index << 2) + 2]; + rgba[ACOMP] = palette[(index << 2) + 3]; + return; + default: + _mesa_problem(ctx, "Bad palette format in palette_sample"); + } +} + + + +/**********************************************************************/ +/* 1-D Texture Sampling Functions */ +/**********************************************************************/ + +/* + * Return the texture sample for coordinate (s) using GL_NEAREST filter. + */ +static void +sample_1d_nearest(GLcontext *ctx, + const struct gl_texture_object *tObj, + const struct gl_texture_image *img, + GLfloat s, GLchan rgba[4]) +{ + const GLint width = img->Width2; /* without border, power of two */ + GLint i; + + COMPUTE_NEAREST_TEXEL_LOCATION(tObj->WrapS, s, width, i); + + /* skip over the border, if any */ + i += img->Border; + + if (i < 0 || i >= (GLint) img->Width) { + /* Need this test for GL_CLAMP_TO_BORDER_ARB mode */ + COPY_CHAN4(rgba, tObj->BorderColor); + } + else { + (*img->FetchTexel)(img, i, 0, 0, (GLvoid *) rgba); + if (img->Format == GL_COLOR_INDEX) { + palette_sample(ctx, tObj, rgba[0], rgba); + } + } +} + + + +/* + * Return the texture sample for coordinate (s) using GL_LINEAR filter. + */ +static void +sample_1d_linear(GLcontext *ctx, + const struct gl_texture_object *tObj, + const struct gl_texture_image *img, + GLfloat s, GLchan rgba[4]) +{ + const GLint width = img->Width2; + GLint i0, i1; + GLfloat u; + GLuint useBorderColor; + + COMPUTE_LINEAR_TEXEL_LOCATIONS(tObj->WrapS, s, u, width, i0, i1); + + useBorderColor = 0; + if (img->Border) { + i0 += img->Border; + i1 += img->Border; + } + else { + if (i0 < 0 || i0 >= width) useBorderColor |= I0BIT; + if (i1 < 0 || i1 >= width) useBorderColor |= I1BIT; + } + + { + const GLfloat a = FRAC(u); + +#if CHAN_BITS == 32 + const GLfloat w0 = (1.0F-a); + const GLfloat w1 = a ; +#else /* CHAN_BITS == 8 || CHAN_BITS == 16 */ + /* compute sample weights in fixed point in [0,WEIGHT_SCALE] */ + const GLint w0 = IROUND_POS((1.0F - a) * WEIGHT_SCALE); + const GLint w1 = IROUND_POS( a * WEIGHT_SCALE); +#endif + + GLchan t0[4], t1[4]; /* texels */ + + if (useBorderColor & I0BIT) { + COPY_CHAN4(t0, tObj->BorderColor); + } + else { + (*img->FetchTexel)(img, i0, 0, 0, (GLvoid *) t0); + if (img->Format == GL_COLOR_INDEX) { + palette_sample(ctx, tObj, t0[0], t0); + } + } + if (useBorderColor & I1BIT) { + COPY_CHAN4(t1, tObj->BorderColor); + } + else { + (*img->FetchTexel)(img, i1, 0, 0, (GLvoid *) t1); + if (img->Format == GL_COLOR_INDEX) { + palette_sample(ctx, tObj, t1[0], t1); + } + } + +#if CHAN_BITS == 32 + rgba[0] = w0 * t0[0] + w1 * t1[0]; + rgba[1] = w0 * t0[1] + w1 * t1[1]; + rgba[2] = w0 * t0[2] + w1 * t1[2]; + rgba[3] = w0 * t0[3] + w1 * t1[3]; +#else /* CHAN_BITS == 8 || CHAN_BITS == 16 */ + rgba[0] = (GLchan) ((w0 * t0[0] + w1 * t1[0]) >> WEIGHT_SHIFT); + rgba[1] = (GLchan) ((w0 * t0[1] + w1 * t1[1]) >> WEIGHT_SHIFT); + rgba[2] = (GLchan) ((w0 * t0[2] + w1 * t1[2]) >> WEIGHT_SHIFT); + rgba[3] = (GLchan) ((w0 * t0[3] + w1 * t1[3]) >> WEIGHT_SHIFT); +#endif + + } +} + + +static void +sample_1d_nearest_mipmap_nearest(GLcontext *ctx, + const struct gl_texture_object *tObj, + GLfloat s, GLfloat lambda, + GLchan rgba[4]) +{ + GLint level; + COMPUTE_NEAREST_MIPMAP_LEVEL(tObj, lambda, level); + sample_1d_nearest(ctx, tObj, tObj->Image[level], s, rgba); +} + + +static void +sample_1d_linear_mipmap_nearest(GLcontext *ctx, + const struct gl_texture_object *tObj, + GLfloat s, GLfloat lambda, + GLchan rgba[4]) +{ + GLint level; + COMPUTE_NEAREST_MIPMAP_LEVEL(tObj, lambda, level); + sample_1d_linear(ctx, tObj, tObj->Image[level], s, rgba); +} + + + +static void +sample_1d_nearest_mipmap_linear(GLcontext *ctx, + const struct gl_texture_object *tObj, + GLfloat s, GLfloat lambda, + GLchan rgba[4]) +{ + GLint level; + + COMPUTE_LINEAR_MIPMAP_LEVEL(tObj, lambda, level); + + if (level >= tObj->_MaxLevel) { + sample_1d_nearest(ctx, tObj, tObj->Image[tObj->_MaxLevel], s, rgba); + } + else { + GLchan t0[4], t1[4]; + const GLfloat f = FRAC(lambda); + sample_1d_nearest(ctx, tObj, tObj->Image[level ], s, t0); + sample_1d_nearest(ctx, tObj, tObj->Image[level+1], s, t1); + rgba[RCOMP] = (GLchan) (GLint) ((1.0F-f) * t0[RCOMP] + f * t1[RCOMP]); + rgba[GCOMP] = (GLchan) (GLint) ((1.0F-f) * t0[GCOMP] + f * t1[GCOMP]); + rgba[BCOMP] = (GLchan) (GLint) ((1.0F-f) * t0[BCOMP] + f * t1[BCOMP]); + rgba[ACOMP] = (GLchan) (GLint) ((1.0F-f) * t0[ACOMP] + f * t1[ACOMP]); + } +} + + + +static void +sample_1d_linear_mipmap_linear(GLcontext *ctx, + const struct gl_texture_object *tObj, + GLfloat s, GLfloat lambda, + GLchan rgba[4]) +{ + GLint level; + + COMPUTE_LINEAR_MIPMAP_LEVEL(tObj, lambda, level); + + if (level >= tObj->_MaxLevel) { + sample_1d_linear(ctx, tObj, tObj->Image[tObj->_MaxLevel], s, rgba); + } + else { + GLchan t0[4], t1[4]; + const GLfloat f = FRAC(lambda); + sample_1d_linear(ctx, tObj, tObj->Image[level ], s, t0); + sample_1d_linear(ctx, tObj, tObj->Image[level+1], s, t1); + rgba[RCOMP] = (GLchan) (GLint) ((1.0F-f) * t0[RCOMP] + f * t1[RCOMP]); + rgba[GCOMP] = (GLchan) (GLint) ((1.0F-f) * t0[GCOMP] + f * t1[GCOMP]); + rgba[BCOMP] = (GLchan) (GLint) ((1.0F-f) * t0[BCOMP] + f * t1[BCOMP]); + rgba[ACOMP] = (GLchan) (GLint) ((1.0F-f) * t0[ACOMP] + f * t1[ACOMP]); + } +} + + + +static void +sample_nearest_1d( GLcontext *ctx, GLuint texUnit, + const struct gl_texture_object *tObj, GLuint n, + const GLfloat s[], const GLfloat t[], + const GLfloat u[], const GLfloat lambda[], + GLchan rgba[][4] ) +{ + GLuint i; + struct gl_texture_image *image = tObj->Image[tObj->BaseLevel]; + (void) t; + (void) u; + (void) lambda; + for (i=0;iImage[tObj->BaseLevel]; + (void) t; + (void) u; + (void) lambda; + for (i=0;i_MinMagThresh[texUnit]; + GLuint i; + + (void) t; + (void) u; + + for (i=0;i MinMagThresh) { + /* minification */ + switch (tObj->MinFilter) { + case GL_NEAREST: + sample_1d_nearest(ctx, tObj, tObj->Image[tObj->BaseLevel], + s[i], rgba[i]); + break; + case GL_LINEAR: + sample_1d_linear(ctx, tObj, tObj->Image[tObj->BaseLevel], + s[i], rgba[i]); + break; + case GL_NEAREST_MIPMAP_NEAREST: + sample_1d_nearest_mipmap_nearest(ctx, tObj, lambda[i], s[i], + rgba[i]); + break; + case GL_LINEAR_MIPMAP_NEAREST: + sample_1d_linear_mipmap_nearest(ctx, tObj, s[i], lambda[i], + rgba[i]); + break; + case GL_NEAREST_MIPMAP_LINEAR: + sample_1d_nearest_mipmap_linear(ctx, tObj, s[i], lambda[i], + rgba[i]); + break; + case GL_LINEAR_MIPMAP_LINEAR: + sample_1d_linear_mipmap_linear(ctx, tObj, s[i], lambda[i], + rgba[i]); + break; + default: + _mesa_problem(NULL, "Bad min filter in sample_1d_texture"); + return; + } + } + else { + /* magnification */ + switch (tObj->MagFilter) { + case GL_NEAREST: + sample_1d_nearest(ctx, tObj, tObj->Image[tObj->BaseLevel], + s[i], rgba[i]); + break; + case GL_LINEAR: + sample_1d_linear(ctx, tObj, tObj->Image[tObj->BaseLevel], + s[i], rgba[i]); + break; + default: + _mesa_problem(NULL, "Bad mag filter in sample_1d_texture"); + return; + } + } + } +} + + + + +/**********************************************************************/ +/* 2-D Texture Sampling Functions */ +/**********************************************************************/ + + +/* + * Return the texture sample for coordinate (s,t) using GL_NEAREST filter. + */ +static void +sample_2d_nearest(GLcontext *ctx, + const struct gl_texture_object *tObj, + const struct gl_texture_image *img, + GLfloat s, GLfloat t, + GLchan rgba[]) +{ + const GLint width = img->Width2; /* without border, power of two */ + const GLint height = img->Height2; /* without border, power of two */ + GLint i, j; + + COMPUTE_NEAREST_TEXEL_LOCATION(tObj->WrapS, s, width, i); + COMPUTE_NEAREST_TEXEL_LOCATION(tObj->WrapT, t, height, j); + + /* skip over the border, if any */ + i += img->Border; + j += img->Border; + + if (i < 0 || i >= (GLint) img->Width || j < 0 || j >= (GLint) img->Height) { + /* Need this test for GL_CLAMP_TO_BORDER_ARB mode */ + COPY_CHAN4(rgba, tObj->BorderColor); + } + else { + (*img->FetchTexel)(img, i, j, 0, (GLvoid *) rgba); + if (img->Format == GL_COLOR_INDEX) { + palette_sample(ctx, tObj, rgba[0], rgba); + } + } +} + + + +/* + * Return the texture sample for coordinate (s,t) using GL_LINEAR filter. + * New sampling code contributed by Lynn Quam . + */ +static void +sample_2d_linear(GLcontext *ctx, + const struct gl_texture_object *tObj, + const struct gl_texture_image *img, + GLfloat s, GLfloat t, + GLchan rgba[]) +{ + const GLint width = img->Width2; + const GLint height = img->Height2; + GLint i0, j0, i1, j1; + GLuint useBorderColor; + GLfloat u, v; + + COMPUTE_LINEAR_TEXEL_LOCATIONS(tObj->WrapS, s, u, width, i0, i1); + COMPUTE_LINEAR_TEXEL_LOCATIONS(tObj->WrapT, t, v, height, j0, j1); + + useBorderColor = 0; + if (img->Border) { + i0 += img->Border; + i1 += img->Border; + j0 += img->Border; + j1 += img->Border; + } + else { + if (i0 < 0 || i0 >= width) useBorderColor |= I0BIT; + if (i1 < 0 || i1 >= width) useBorderColor |= I1BIT; + if (j0 < 0 || j0 >= height) useBorderColor |= J0BIT; + if (j1 < 0 || j1 >= height) useBorderColor |= J1BIT; + } + + { + const GLfloat a = FRAC(u); + const GLfloat b = FRAC(v); + +#if CHAN_BITS == 32 + const GLfloat w00 = (1.0F-a) * (1.0F-b); + const GLfloat w10 = a * (1.0F-b); + const GLfloat w01 = (1.0F-a) * b ; + const GLfloat w11 = a * b ; +#else /* CHAN_BITS == 8 || CHAN_BITS == 16 */ + /* compute sample weights in fixed point in [0,WEIGHT_SCALE] */ + const GLint w00 = IROUND_POS((1.0F-a) * (1.0F-b) * WEIGHT_SCALE); + const GLint w10 = IROUND_POS( a * (1.0F-b) * WEIGHT_SCALE); + const GLint w01 = IROUND_POS((1.0F-a) * b * WEIGHT_SCALE); + const GLint w11 = IROUND_POS( a * b * WEIGHT_SCALE); +#endif + + GLchan t00[4]; + GLchan t10[4]; + GLchan t01[4]; + GLchan t11[4]; + + if (useBorderColor & (I0BIT | J0BIT)) { + COPY_CHAN4(t00, tObj->BorderColor); + } + else { + (*img->FetchTexel)(img, i0, j0, 0, (GLvoid *) t00); + if (img->Format == GL_COLOR_INDEX) { + palette_sample(ctx, tObj, t00[0], t00); + } + } + if (useBorderColor & (I1BIT | J0BIT)) { + COPY_CHAN4(t10, tObj->BorderColor); + } + else { + (*img->FetchTexel)(img, i1, j0, 0, (GLvoid *) t10); + if (img->Format == GL_COLOR_INDEX) { + palette_sample(ctx, tObj, t10[0], t10); + } + } + if (useBorderColor & (I0BIT | J1BIT)) { + COPY_CHAN4(t01, tObj->BorderColor); + } + else { + (*img->FetchTexel)(img, i0, j1, 0, (GLvoid *) t01); + if (img->Format == GL_COLOR_INDEX) { + palette_sample(ctx, tObj, t01[0], t01); + } + } + if (useBorderColor & (I1BIT | J1BIT)) { + COPY_CHAN4(t11, tObj->BorderColor); + } + else { + (*img->FetchTexel)(img, i1, j1, 0, (GLvoid *) t11); + if (img->Format == GL_COLOR_INDEX) { + palette_sample(ctx, tObj, t11[0], t11); + } + } +#if CHAN_BITS == 32 + rgba[0] = w00 * t00[0] + w10 * t10[0] + w01 * t01[0] + w11 * t11[0]; + rgba[1] = w00 * t00[1] + w10 * t10[1] + w01 * t01[1] + w11 * t11[1]; + rgba[2] = w00 * t00[2] + w10 * t10[2] + w01 * t01[2] + w11 * t11[2]; + rgba[3] = w00 * t00[3] + w10 * t10[3] + w01 * t01[3] + w11 * t11[3]; +#else /* CHAN_BITS == 8 || CHAN_BITS == 16 */ + rgba[0] = (GLchan) ((w00 * t00[0] + w10 * t10[0] + w01 * t01[0] + w11 * t11[0]) >> WEIGHT_SHIFT); + rgba[1] = (GLchan) ((w00 * t00[1] + w10 * t10[1] + w01 * t01[1] + w11 * t11[1]) >> WEIGHT_SHIFT); + rgba[2] = (GLchan) ((w00 * t00[2] + w10 * t10[2] + w01 * t01[2] + w11 * t11[2]) >> WEIGHT_SHIFT); + rgba[3] = (GLchan) ((w00 * t00[3] + w10 * t10[3] + w01 * t01[3] + w11 * t11[3]) >> WEIGHT_SHIFT); +#endif + + } + +} + + + +static void +sample_2d_nearest_mipmap_nearest(GLcontext *ctx, + const struct gl_texture_object *tObj, + GLfloat s, GLfloat t, GLfloat lambda, + GLchan rgba[4]) +{ + GLint level; + COMPUTE_NEAREST_MIPMAP_LEVEL(tObj, lambda, level); + sample_2d_nearest(ctx, tObj, tObj->Image[level], s, t, rgba); +} + + + +static void +sample_2d_linear_mipmap_nearest(GLcontext *ctx, + const struct gl_texture_object *tObj, + GLfloat s, GLfloat t, GLfloat lambda, + GLchan rgba[4]) +{ + GLint level; + COMPUTE_NEAREST_MIPMAP_LEVEL(tObj, lambda, level); + sample_2d_linear(ctx, tObj, tObj->Image[level], s, t, rgba); +} + + + +static void +sample_2d_nearest_mipmap_linear(GLcontext *ctx, + const struct gl_texture_object *tObj, + GLfloat s, GLfloat t, GLfloat lambda, + GLchan rgba[4]) +{ + GLint level; + + COMPUTE_LINEAR_MIPMAP_LEVEL(tObj, lambda, level); + + if (level >= tObj->_MaxLevel) { + sample_2d_nearest(ctx, tObj, tObj->Image[tObj->_MaxLevel], s, t, rgba); + } + else { + GLchan t0[4], t1[4]; /* texels */ + const GLfloat f = FRAC(lambda); + sample_2d_nearest(ctx, tObj, tObj->Image[level ], s, t, t0); + sample_2d_nearest(ctx, tObj, tObj->Image[level+1], s, t, t1); + rgba[RCOMP] = (GLchan) (GLint) ((1.0F-f) * t0[RCOMP] + f * t1[RCOMP]); + rgba[GCOMP] = (GLchan) (GLint) ((1.0F-f) * t0[GCOMP] + f * t1[GCOMP]); + rgba[BCOMP] = (GLchan) (GLint) ((1.0F-f) * t0[BCOMP] + f * t1[BCOMP]); + rgba[ACOMP] = (GLchan) (GLint) ((1.0F-f) * t0[ACOMP] + f * t1[ACOMP]); + } +} + + + +static void +sample_2d_linear_mipmap_linear(GLcontext *ctx, + const struct gl_texture_object *tObj, + GLfloat s, GLfloat t, GLfloat lambda, + GLchan rgba[4]) +{ + GLint level; + + COMPUTE_LINEAR_MIPMAP_LEVEL(tObj, lambda, level); + + if (level >= tObj->_MaxLevel) { + sample_2d_linear(ctx, tObj, tObj->Image[tObj->_MaxLevel], s, t, rgba); + } + else { + GLchan t0[4], t1[4]; /* texels */ + const GLfloat f = FRAC(lambda); + sample_2d_linear(ctx, tObj, tObj->Image[level ], s, t, t0); + sample_2d_linear(ctx, tObj, tObj->Image[level+1], s, t, t1); + rgba[RCOMP] = (GLchan) (GLint) ((1.0F-f) * t0[RCOMP] + f * t1[RCOMP]); + rgba[GCOMP] = (GLchan) (GLint) ((1.0F-f) * t0[GCOMP] + f * t1[GCOMP]); + rgba[BCOMP] = (GLchan) (GLint) ((1.0F-f) * t0[BCOMP] + f * t1[BCOMP]); + rgba[ACOMP] = (GLchan) (GLint) ((1.0F-f) * t0[ACOMP] + f * t1[ACOMP]); + } +} + + + +static void +sample_nearest_2d( GLcontext *ctx, GLuint texUnit, + const struct gl_texture_object *tObj, GLuint n, + const GLfloat s[], const GLfloat t[], + const GLfloat u[], const GLfloat lambda[], + GLchan rgba[][4] ) +{ + GLuint i; + struct gl_texture_image *image = tObj->Image[tObj->BaseLevel]; + (void) u; + (void) lambda; + for (i=0;iImage[tObj->BaseLevel]; + (void) u; + (void) lambda; + for (i=0;i_MinMagThresh[texUnit]; + GLuint i; + (void) u; + + /* since lambda is monotonous-array use this check first */ + if (lambda[0] <= minMagThresh && lambda[n-1] <= minMagThresh) { + /* magnification for whole span */ + switch (tObj->MagFilter) { + case GL_NEAREST: + sample_nearest_2d(ctx, texUnit, tObj, n, s, t, u, + lambda, rgba); + break; + case GL_LINEAR: + sample_linear_2d(ctx, texUnit, tObj, n, s, t, u, + lambda, rgba); + break; + default: + _mesa_problem(NULL, "Bad mag filter in sample_lambda_2d"); + } + } + else { + for (i = 0; i < n; i++) { + if (lambda[i] > minMagThresh) { + /* minification */ + switch (tObj->MinFilter) { + case GL_NEAREST: + sample_2d_nearest(ctx, tObj, tObj->Image[tObj->BaseLevel], + s[i], t[i], rgba[i]); + break; + case GL_LINEAR: + sample_2d_linear(ctx, tObj, tObj->Image[tObj->BaseLevel], + s[i], t[i], rgba[i]); + break; + case GL_NEAREST_MIPMAP_NEAREST: + sample_2d_nearest_mipmap_nearest(ctx, tObj, s[i], t[i], + lambda[i], rgba[i]); + break; + case GL_LINEAR_MIPMAP_NEAREST: + sample_2d_linear_mipmap_nearest(ctx,tObj, s[i], t[i], + lambda[i], rgba[i]); + break; + case GL_NEAREST_MIPMAP_LINEAR: + sample_2d_nearest_mipmap_linear(ctx,tObj, s[i], t[i], + lambda[i], rgba[i]); + break; + case GL_LINEAR_MIPMAP_LINEAR: + sample_2d_linear_mipmap_linear(ctx,tObj, s[i], t[i], + lambda[i], rgba[i] ); + break; + default: + _mesa_problem(NULL, "Bad min filter in sample_2d_texture"); + return; + } + } + else { + /* magnification */ + switch (tObj->MagFilter) { + case GL_NEAREST: + sample_2d_nearest(ctx, tObj, tObj->Image[tObj->BaseLevel], + s[i], t[i], rgba[i]); + break; + case GL_LINEAR: + sample_2d_linear(ctx, tObj, tObj->Image[tObj->BaseLevel], + s[i], t[i], rgba[i] ); + break; + default: + _mesa_problem(NULL, "Bad mag filter in sample_2d_texture"); + } + } + } + } +} + + +/* + * Optimized 2-D texture sampling: + * S and T wrap mode == GL_REPEAT + * GL_NEAREST min/mag filter + * No border + * Format = GL_RGB + */ +static void +opt_sample_rgb_2d( GLcontext *ctx, GLuint texUnit, + const struct gl_texture_object *tObj, + GLuint n, const GLfloat s[], const GLfloat t[], + const GLfloat u[], const GLfloat lambda[], + GLchan rgba[][4] ) +{ + const struct gl_texture_image *img = tObj->Image[tObj->BaseLevel]; + const GLfloat width = (GLfloat) img->Width; + const GLfloat height = (GLfloat) img->Height; + const GLint colMask = img->Width - 1; + const GLint rowMask = img->Height - 1; + const GLint shift = img->WidthLog2; + GLuint k; + (void) u; + (void) lambda; + ASSERT(tObj->WrapS==GL_REPEAT); + ASSERT(tObj->WrapT==GL_REPEAT); + ASSERT(tObj->MinFilter==GL_NEAREST); + ASSERT(tObj->MagFilter==GL_NEAREST); + ASSERT(img->Border==0); + ASSERT(img->Format==GL_RGB); + + /* NOTE: negative float->int doesn't floor, add 10000 as to work-around */ + for (k=0;kData) + pos + pos + pos; /* pos*3 */ + rgba[k][RCOMP] = texel[0]; + rgba[k][GCOMP] = texel[1]; + rgba[k][BCOMP] = texel[2]; + } +} + + +/* + * Optimized 2-D texture sampling: + * S and T wrap mode == GL_REPEAT + * GL_NEAREST min/mag filter + * No border + * Format = GL_RGBA + */ +static void +opt_sample_rgba_2d( GLcontext *ctx, GLuint texUnit, + const struct gl_texture_object *tObj, + GLuint n, const GLfloat s[], const GLfloat t[], + const GLfloat u[], const GLfloat lambda[], + GLchan rgba[][4] ) +{ + const struct gl_texture_image *img = tObj->Image[tObj->BaseLevel]; + const GLfloat width = (GLfloat) img->Width; + const GLfloat height = (GLfloat) img->Height; + const GLint colMask = img->Width - 1; + const GLint rowMask = img->Height - 1; + const GLint shift = img->WidthLog2; + GLuint k; + (void) u; + (void) lambda; + ASSERT(tObj->WrapS==GL_REPEAT); + ASSERT(tObj->WrapT==GL_REPEAT); + ASSERT(tObj->MinFilter==GL_NEAREST); + ASSERT(tObj->MagFilter==GL_NEAREST); + ASSERT(img->Border==0); + ASSERT(img->Format==GL_RGBA); + + /* NOTE: negative float->int doesn't floor, add 10000 as to work-around */ + for (k=0;kData) + (pos << 2); /* pos*4 */ + rgba[k][RCOMP] = texel[0]; + rgba[k][GCOMP] = texel[1]; + rgba[k][BCOMP] = texel[2]; + rgba[k][ACOMP] = texel[3]; + } +} + + + +/**********************************************************************/ +/* 3-D Texture Sampling Functions */ +/**********************************************************************/ + +/* + * Return the texture sample for coordinate (s,t,r) using GL_NEAREST filter. + */ +static void +sample_3d_nearest(GLcontext *ctx, + const struct gl_texture_object *tObj, + const struct gl_texture_image *img, + GLfloat s, GLfloat t, GLfloat r, + GLchan rgba[4]) +{ + const GLint width = img->Width2; /* without border, power of two */ + const GLint height = img->Height2; /* without border, power of two */ + const GLint depth = img->Depth2; /* without border, power of two */ + GLint i, j, k; + + COMPUTE_NEAREST_TEXEL_LOCATION(tObj->WrapS, s, width, i); + COMPUTE_NEAREST_TEXEL_LOCATION(tObj->WrapT, t, height, j); + COMPUTE_NEAREST_TEXEL_LOCATION(tObj->WrapR, r, depth, k); + + if (i < 0 || i >= (GLint) img->Width || + j < 0 || j >= (GLint) img->Height || + k < 0 || k >= (GLint) img->Depth) { + /* Need this test for GL_CLAMP_TO_BORDER_ARB mode */ + COPY_CHAN4(rgba, tObj->BorderColor); + } + else { + (*img->FetchTexel)(img, i, j, k, (GLvoid *) rgba); + if (img->Format == GL_COLOR_INDEX) { + palette_sample(ctx, tObj, rgba[0], rgba); + } + } +} + + + +/* + * Return the texture sample for coordinate (s,t,r) using GL_LINEAR filter. + */ +static void +sample_3d_linear(GLcontext *ctx, + const struct gl_texture_object *tObj, + const struct gl_texture_image *img, + GLfloat s, GLfloat t, GLfloat r, + GLchan rgba[4]) +{ + const GLint width = img->Width2; + const GLint height = img->Height2; + const GLint depth = img->Depth2; + GLint i0, j0, k0, i1, j1, k1; + GLuint useBorderColor; + GLfloat u, v, w; + + COMPUTE_LINEAR_TEXEL_LOCATIONS(tObj->WrapS, s, u, width, i0, i1); + COMPUTE_LINEAR_TEXEL_LOCATIONS(tObj->WrapT, t, v, height, j0, j1); + COMPUTE_LINEAR_TEXEL_LOCATIONS(tObj->WrapR, r, w, depth, k0, k1); + + useBorderColor = 0; + if (img->Border) { + i0 += img->Border; + i1 += img->Border; + j0 += img->Border; + j1 += img->Border; + k0 += img->Border; + k1 += img->Border; + } + else { + /* check if sampling texture border color */ + if (i0 < 0 || i0 >= width) useBorderColor |= I0BIT; + if (i1 < 0 || i1 >= width) useBorderColor |= I1BIT; + if (j0 < 0 || j0 >= height) useBorderColor |= J0BIT; + if (j1 < 0 || j1 >= height) useBorderColor |= J1BIT; + if (k0 < 0 || k0 >= depth) useBorderColor |= K0BIT; + if (k1 < 0 || k1 >= depth) useBorderColor |= K1BIT; + } + + { + const GLfloat a = FRAC(u); + const GLfloat b = FRAC(v); + const GLfloat c = FRAC(w); + +#if CHAN_BITS == 32 + /* compute sample weights in fixed point in [0,WEIGHT_SCALE] */ + GLfloat w000 = (1.0F-a) * (1.0F-b) * (1.0F-c); + GLfloat w100 = a * (1.0F-b) * (1.0F-c); + GLfloat w010 = (1.0F-a) * b * (1.0F-c); + GLfloat w110 = a * b * (1.0F-c); + GLfloat w001 = (1.0F-a) * (1.0F-b) * c ; + GLfloat w101 = a * (1.0F-b) * c ; + GLfloat w011 = (1.0F-a) * b * c ; + GLfloat w111 = a * b * c ; +#else /* CHAN_BITS == 8 || CHAN_BITS == 16 */ + /* compute sample weights in fixed point in [0,WEIGHT_SCALE] */ + GLint w000 = IROUND_POS((1.0F-a) * (1.0F-b) * (1.0F-c) * WEIGHT_SCALE); + GLint w100 = IROUND_POS( a * (1.0F-b) * (1.0F-c) * WEIGHT_SCALE); + GLint w010 = IROUND_POS((1.0F-a) * b * (1.0F-c) * WEIGHT_SCALE); + GLint w110 = IROUND_POS( a * b * (1.0F-c) * WEIGHT_SCALE); + GLint w001 = IROUND_POS((1.0F-a) * (1.0F-b) * c * WEIGHT_SCALE); + GLint w101 = IROUND_POS( a * (1.0F-b) * c * WEIGHT_SCALE); + GLint w011 = IROUND_POS((1.0F-a) * b * c * WEIGHT_SCALE); + GLint w111 = IROUND_POS( a * b * c * WEIGHT_SCALE); +#endif + + GLchan t000[4], t010[4], t001[4], t011[4]; + GLchan t100[4], t110[4], t101[4], t111[4]; + + if (useBorderColor & (I0BIT | J0BIT | K0BIT)) { + COPY_CHAN4(t000, tObj->BorderColor); + } + else { + (*img->FetchTexel)(img, i0, j0, k0, (GLvoid *) t000); + if (img->Format == GL_COLOR_INDEX) { + palette_sample(ctx, tObj, t000[0], t000); + } + } + if (useBorderColor & (I1BIT | J0BIT | K0BIT)) { + COPY_CHAN4(t100, tObj->BorderColor); + } + else { + (*img->FetchTexel)(img, i1, j0, k0, (GLvoid *) t100); + if (img->Format == GL_COLOR_INDEX) { + palette_sample(ctx, tObj, t100[0], t100); + } + } + if (useBorderColor & (I0BIT | J1BIT | K0BIT)) { + COPY_CHAN4(t010, tObj->BorderColor); + } + else { + (*img->FetchTexel)(img, i0, j1, k0, (GLvoid *) t010); + if (img->Format == GL_COLOR_INDEX) { + palette_sample(ctx, tObj, t010[0], t010); + } + } + if (useBorderColor & (I1BIT | J1BIT | K0BIT)) { + COPY_CHAN4(t110, tObj->BorderColor); + } + else { + (*img->FetchTexel)(img, i1, j1, k0, (GLvoid *) t110); + if (img->Format == GL_COLOR_INDEX) { + palette_sample(ctx, tObj, t110[0], t110); + } + } + + if (useBorderColor & (I0BIT | J0BIT | K1BIT)) { + COPY_CHAN4(t001, tObj->BorderColor); + } + else { + (*img->FetchTexel)(img, i0, j0, k1, (GLvoid *) t001); + if (img->Format == GL_COLOR_INDEX) { + palette_sample(ctx, tObj, t001[0], t001); + } + } + if (useBorderColor & (I1BIT | J0BIT | K1BIT)) { + COPY_CHAN4(t101, tObj->BorderColor); + } + else { + (*img->FetchTexel)(img, i1, j0, k1, (GLvoid *) t101); + if (img->Format == GL_COLOR_INDEX) { + palette_sample(ctx, tObj, t101[0], t101); + } + } + if (useBorderColor & (I0BIT | J1BIT | K1BIT)) { + COPY_CHAN4(t011, tObj->BorderColor); + } + else { + (*img->FetchTexel)(img, i0, j1, k1, (GLvoid *) t011); + if (img->Format == GL_COLOR_INDEX) { + palette_sample(ctx, tObj, t011[0], t011); + } + } + if (useBorderColor & (I1BIT | J1BIT | K1BIT)) { + COPY_CHAN4(t111, tObj->BorderColor); + } + else { + (*img->FetchTexel)(img, i1, j1, k1, (GLvoid *) t111); + if (img->Format == GL_COLOR_INDEX) { + palette_sample(ctx, tObj, t111[0], t111); + } + } + +#if CHAN_BITS == 32 + rgba[0] = w000*t000[0] + w010*t010[0] + w001*t001[0] + w011*t011[0] + + w100*t100[0] + w110*t110[0] + w101*t101[0] + w111*t111[0]; + rgba[1] = w000*t000[1] + w010*t010[1] + w001*t001[1] + w011*t011[1] + + w100*t100[1] + w110*t110[1] + w101*t101[1] + w111*t111[1]; + rgba[2] = w000*t000[2] + w010*t010[2] + w001*t001[2] + w011*t011[2] + + w100*t100[2] + w110*t110[2] + w101*t101[2] + w111*t111[2]; + rgba[3] = w000*t000[3] + w010*t010[3] + w001*t001[3] + w011*t011[3] + + w100*t100[3] + w110*t110[3] + w101*t101[3] + w111*t111[3]; +#else /* CHAN_BITS == 8 || CHAN_BITS == 16 */ + rgba[0] = (GLchan) ( + (w000*t000[0] + w010*t010[0] + w001*t001[0] + w011*t011[0] + + w100*t100[0] + w110*t110[0] + w101*t101[0] + w111*t111[0] ) + >> WEIGHT_SHIFT); + rgba[1] = (GLchan) ( + (w000*t000[1] + w010*t010[1] + w001*t001[1] + w011*t011[1] + + w100*t100[1] + w110*t110[1] + w101*t101[1] + w111*t111[1] ) + >> WEIGHT_SHIFT); + rgba[2] = (GLchan) ( + (w000*t000[2] + w010*t010[2] + w001*t001[2] + w011*t011[2] + + w100*t100[2] + w110*t110[2] + w101*t101[2] + w111*t111[2] ) + >> WEIGHT_SHIFT); + rgba[3] = (GLchan) ( + (w000*t000[3] + w010*t010[3] + w001*t001[3] + w011*t011[3] + + w100*t100[3] + w110*t110[3] + w101*t101[3] + w111*t111[3] ) + >> WEIGHT_SHIFT); +#endif + + } +} + + + +static void +sample_3d_nearest_mipmap_nearest(GLcontext *ctx, + const struct gl_texture_object *tObj, + GLfloat s, GLfloat t, GLfloat r, + GLfloat lambda, GLchan rgba[4] ) +{ + GLint level; + COMPUTE_NEAREST_MIPMAP_LEVEL(tObj, lambda, level); + sample_3d_nearest(ctx, tObj, tObj->Image[level], s, t, r, rgba); +} + + +static void +sample_3d_linear_mipmap_nearest(GLcontext *ctx, + const struct gl_texture_object *tObj, + GLfloat s, GLfloat t, GLfloat r, + GLfloat lambda, GLchan rgba[4]) +{ + GLint level; + COMPUTE_NEAREST_MIPMAP_LEVEL(tObj, lambda, level); + sample_3d_linear(ctx, tObj, tObj->Image[level], s, t, r, rgba); +} + + +static void +sample_3d_nearest_mipmap_linear(GLcontext *ctx, + const struct gl_texture_object *tObj, + GLfloat s, GLfloat t, GLfloat r, + GLfloat lambda, GLchan rgba[4]) +{ + GLint level; + + COMPUTE_LINEAR_MIPMAP_LEVEL(tObj, lambda, level); + + if (level >= tObj->_MaxLevel) { + sample_3d_nearest(ctx, tObj, tObj->Image[tObj->_MaxLevel], + s, t, r, rgba); + } + else { + GLchan t0[4], t1[4]; /* texels */ + const GLfloat f = FRAC(lambda); + sample_3d_nearest(ctx, tObj, tObj->Image[level ], s, t, r, t0); + sample_3d_nearest(ctx, tObj, tObj->Image[level+1], s, t, r, t1); + rgba[RCOMP] = (GLchan) (GLint) ((1.0F-f) * t0[RCOMP] + f * t1[RCOMP]); + rgba[GCOMP] = (GLchan) (GLint) ((1.0F-f) * t0[GCOMP] + f * t1[GCOMP]); + rgba[BCOMP] = (GLchan) (GLint) ((1.0F-f) * t0[BCOMP] + f * t1[BCOMP]); + rgba[ACOMP] = (GLchan) (GLint) ((1.0F-f) * t0[ACOMP] + f * t1[ACOMP]); + } +} + + +static void +sample_3d_linear_mipmap_linear(GLcontext *ctx, + const struct gl_texture_object *tObj, + GLfloat s, GLfloat t, GLfloat r, + GLfloat lambda, GLchan rgba[4] ) +{ + GLint level; + + COMPUTE_LINEAR_MIPMAP_LEVEL(tObj, lambda, level); + + if (level >= tObj->_MaxLevel) { + sample_3d_linear(ctx, tObj, tObj->Image[tObj->_MaxLevel], s, t, r, rgba); + } + else { + GLchan t0[4], t1[4]; /* texels */ + const GLfloat f = FRAC(lambda); + sample_3d_linear(ctx, tObj, tObj->Image[level ], s, t, r, t0); + sample_3d_linear(ctx, tObj, tObj->Image[level+1], s, t, r, t1); + rgba[RCOMP] = (GLchan) (GLint) ((1.0F-f) * t0[RCOMP] + f * t1[RCOMP]); + rgba[GCOMP] = (GLchan) (GLint) ((1.0F-f) * t0[GCOMP] + f * t1[GCOMP]); + rgba[BCOMP] = (GLchan) (GLint) ((1.0F-f) * t0[BCOMP] + f * t1[BCOMP]); + rgba[ACOMP] = (GLchan) (GLint) ((1.0F-f) * t0[ACOMP] + f * t1[ACOMP]); + } +} + + +static void +sample_nearest_3d(GLcontext *ctx, GLuint texUnit, + const struct gl_texture_object *tObj, GLuint n, + const GLfloat s[], const GLfloat t[], + const GLfloat u[], const GLfloat lambda[], + GLchan rgba[][4]) +{ + GLuint i; + struct gl_texture_image *image = tObj->Image[tObj->BaseLevel]; + (void) lambda; + for (i=0;iImage[tObj->BaseLevel]; + (void) lambda; + for (i=0;i_MinMagThresh[texUnit]; + + for (i=0;i MinMagThresh) { + /* minification */ + switch (tObj->MinFilter) { + case GL_NEAREST: + sample_3d_nearest(ctx, tObj, tObj->Image[tObj->BaseLevel], + s[i], t[i], u[i], rgba[i]); + break; + case GL_LINEAR: + sample_3d_linear(ctx, tObj, tObj->Image[tObj->BaseLevel], + s[i], t[i], u[i], rgba[i]); + break; + case GL_NEAREST_MIPMAP_NEAREST: + sample_3d_nearest_mipmap_nearest(ctx, tObj, s[i], t[i], u[i], + lambda[i], rgba[i]); + break; + case GL_LINEAR_MIPMAP_NEAREST: + sample_3d_linear_mipmap_nearest(ctx, tObj, s[i], t[i], u[i], + lambda[i], rgba[i]); + break; + case GL_NEAREST_MIPMAP_LINEAR: + sample_3d_nearest_mipmap_linear(ctx, tObj, s[i], t[i], u[i], + lambda[i], rgba[i]); + break; + case GL_LINEAR_MIPMAP_LINEAR: + sample_3d_linear_mipmap_linear(ctx, tObj, s[i], t[i], u[i], + lambda[i], rgba[i]); + break; + default: + _mesa_problem(NULL, "Bad min filterin sample_3d_texture"); + } + } + else { + /* magnification */ + switch (tObj->MagFilter) { + case GL_NEAREST: + sample_3d_nearest(ctx, tObj, tObj->Image[tObj->BaseLevel], + s[i], t[i], u[i], rgba[i]); + break; + case GL_LINEAR: + sample_3d_linear(ctx, tObj, tObj->Image[tObj->BaseLevel], + s[i], t[i], u[i], rgba[i]); + break; + default: + _mesa_problem(NULL, "Bad mag filter in sample_3d_texture"); + } + } + } +} + + +/**********************************************************************/ +/* Texture Cube Map Sampling Functions */ +/**********************************************************************/ + +/* + * Choose one of six sides of a texture cube map given the texture + * coord (rx,ry,rz). Return pointer to corresponding array of texture + * images. + */ +static const struct gl_texture_image ** +choose_cube_face(const struct gl_texture_object *texObj, + GLfloat rx, GLfloat ry, GLfloat rz, + GLfloat *newS, GLfloat *newT) +{ +/* + major axis + direction target sc tc ma + ---------- ------------------------------- --- --- --- + +rx TEXTURE_CUBE_MAP_POSITIVE_X_EXT -rz -ry rx + -rx TEXTURE_CUBE_MAP_NEGATIVE_X_EXT +rz -ry rx + +ry TEXTURE_CUBE_MAP_POSITIVE_Y_EXT +rx +rz ry + -ry TEXTURE_CUBE_MAP_NEGATIVE_Y_EXT +rx -rz ry + +rz TEXTURE_CUBE_MAP_POSITIVE_Z_EXT +rx -ry rz + -rz TEXTURE_CUBE_MAP_NEGATIVE_Z_EXT -rx -ry rz +*/ + const struct gl_texture_image **imgArray; + const GLfloat arx = ABSF(rx), ary = ABSF(ry), arz = ABSF(rz); + GLfloat sc, tc, ma; + + if (arx > ary && arx > arz) { + if (rx >= 0.0F) { + imgArray = (const struct gl_texture_image **) texObj->Image; + sc = -rz; + tc = -ry; + ma = arx; + } + else { + imgArray = (const struct gl_texture_image **) texObj->NegX; + sc = rz; + tc = -ry; + ma = arx; + } + } + else if (ary > arx && ary > arz) { + if (ry >= 0.0F) { + imgArray = (const struct gl_texture_image **) texObj->PosY; + sc = rx; + tc = rz; + ma = ary; + } + else { + imgArray = (const struct gl_texture_image **) texObj->NegY; + sc = rx; + tc = -rz; + ma = ary; + } + } + else { + if (rz > 0.0F) { + imgArray = (const struct gl_texture_image **) texObj->PosZ; + sc = rx; + tc = -ry; + ma = arz; + } + else { + imgArray = (const struct gl_texture_image **) texObj->NegZ; + sc = -rx; + tc = -ry; + ma = arz; + } + } + + *newS = ( sc / ma + 1.0F ) * 0.5F; + *newT = ( tc / ma + 1.0F ) * 0.5F; + return imgArray; +} + + +static void +sample_nearest_cube(GLcontext *ctx, GLuint texUnit, + const struct gl_texture_object *tObj, GLuint n, + const GLfloat s[], const GLfloat t[], + const GLfloat u[], const GLfloat lambda[], + GLchan rgba[][4]) +{ + GLuint i; + (void) lambda; + for (i = 0; i < n; i++) { + const struct gl_texture_image **images; + GLfloat newS, newT; + images = choose_cube_face(tObj, s[i], t[i], u[i], &newS, &newT); + sample_2d_nearest(ctx, tObj, images[tObj->BaseLevel], + newS, newT, rgba[i]); + } +} + + +static void +sample_linear_cube(GLcontext *ctx, GLuint texUnit, + const struct gl_texture_object *tObj, GLuint n, + const GLfloat s[], const GLfloat t[], + const GLfloat u[], const GLfloat lambda[], + GLchan rgba[][4]) +{ + GLuint i; + (void) lambda; + for (i = 0; i < n; i++) { + const struct gl_texture_image **images; + GLfloat newS, newT; + images = choose_cube_face(tObj, s[i], t[i], u[i], &newS, &newT); + sample_2d_linear(ctx, tObj, images[tObj->BaseLevel], + newS, newT, rgba[i]); + } +} + + +static void +sample_cube_nearest_mipmap_nearest(GLcontext *ctx, + const struct gl_texture_object *tObj, + GLfloat s, GLfloat t, GLfloat u, + GLfloat lambda, GLchan rgba[4]) +{ + const struct gl_texture_image **images; + GLfloat newS, newT; + GLint level; + + COMPUTE_NEAREST_MIPMAP_LEVEL(tObj, lambda, level); + + images = choose_cube_face(tObj, s, t, u, &newS, &newT); + sample_2d_nearest(ctx, tObj, images[level], newS, newT, rgba); +} + + +static void +sample_cube_linear_mipmap_nearest(GLcontext *ctx, + const struct gl_texture_object *tObj, + GLfloat s, GLfloat t, GLfloat u, + GLfloat lambda, GLchan rgba[4]) +{ + const struct gl_texture_image **images; + GLfloat newS, newT; + GLint level; + + COMPUTE_NEAREST_MIPMAP_LEVEL(tObj, lambda, level); + + images = choose_cube_face(tObj, s, t, u, &newS, &newT); + sample_2d_linear(ctx, tObj, images[level], newS, newT, rgba); +} + + +static void +sample_cube_nearest_mipmap_linear(GLcontext *ctx, + const struct gl_texture_object *tObj, + GLfloat s, GLfloat t, GLfloat u, + GLfloat lambda, GLchan rgba[4]) +{ + const struct gl_texture_image **images; + GLfloat newS, newT; + GLint level; + + COMPUTE_LINEAR_MIPMAP_LEVEL(tObj, lambda, level); + + images = choose_cube_face(tObj, s, t, u, &newS, &newT); + + if (level >= tObj->_MaxLevel) { + sample_2d_nearest(ctx, tObj, images[tObj->_MaxLevel], newS, newT, rgba); + } + else { + GLchan t0[4], t1[4]; /* texels */ + const GLfloat f = FRAC(lambda); + sample_2d_nearest(ctx, tObj, images[level ], newS, newT, t0); + sample_2d_nearest(ctx, tObj, images[level+1], newS, newT, t1); + rgba[RCOMP] = (GLchan) (GLint) ((1.0F-f) * t0[RCOMP] + f * t1[RCOMP]); + rgba[GCOMP] = (GLchan) (GLint) ((1.0F-f) * t0[GCOMP] + f * t1[GCOMP]); + rgba[BCOMP] = (GLchan) (GLint) ((1.0F-f) * t0[BCOMP] + f * t1[BCOMP]); + rgba[ACOMP] = (GLchan) (GLint) ((1.0F-f) * t0[ACOMP] + f * t1[ACOMP]); + } +} + + +static void +sample_cube_linear_mipmap_linear(GLcontext *ctx, + const struct gl_texture_object *tObj, + GLfloat s, GLfloat t, GLfloat u, + GLfloat lambda, GLchan rgba[4]) +{ + const struct gl_texture_image **images; + GLfloat newS, newT; + GLint level; + + COMPUTE_LINEAR_MIPMAP_LEVEL(tObj, lambda, level); + + images = choose_cube_face(tObj, s, t, u, &newS, &newT); + + if (level >= tObj->_MaxLevel) { + sample_2d_linear(ctx, tObj, images[tObj->_MaxLevel], newS, newT, rgba); + } + else { + GLchan t0[4], t1[4]; + const GLfloat f = FRAC(lambda); + sample_2d_linear(ctx, tObj, images[level ], newS, newT, t0); + sample_2d_linear(ctx, tObj, images[level+1], newS, newT, t1); + rgba[RCOMP] = (GLchan) (GLint) ((1.0F-f) * t0[RCOMP] + f * t1[RCOMP]); + rgba[GCOMP] = (GLchan) (GLint) ((1.0F-f) * t0[GCOMP] + f * t1[GCOMP]); + rgba[BCOMP] = (GLchan) (GLint) ((1.0F-f) * t0[BCOMP] + f * t1[BCOMP]); + rgba[ACOMP] = (GLchan) (GLint) ((1.0F-f) * t0[ACOMP] + f * t1[ACOMP]); + } +} + + +static void +sample_lambda_cube( GLcontext *ctx, GLuint texUnit, + const struct gl_texture_object *tObj, GLuint n, + const GLfloat s[], const GLfloat t[], + const GLfloat u[], const GLfloat lambda[], + GLchan rgba[][4]) +{ + GLfloat MinMagThresh = SWRAST_CONTEXT(ctx)->_MinMagThresh[texUnit]; + GLuint i; + + for (i = 0; i < n; i++) { + if (lambda[i] > MinMagThresh) { + /* minification */ + switch (tObj->MinFilter) { + case GL_NEAREST: + { + const struct gl_texture_image **images; + GLfloat newS, newT; + images = choose_cube_face(tObj, s[i], t[i], u[i], + &newS, &newT); + sample_2d_nearest(ctx, tObj, images[tObj->BaseLevel], + newS, newT, rgba[i]); + } + break; + case GL_LINEAR: + { + const struct gl_texture_image **images; + GLfloat newS, newT; + images = choose_cube_face(tObj, s[i], t[i], u[i], + &newS, &newT); + sample_2d_linear(ctx, tObj, images[tObj->BaseLevel], + newS, newT, rgba[i]); + } + break; + case GL_NEAREST_MIPMAP_NEAREST: + sample_cube_nearest_mipmap_nearest(ctx, tObj, s[i], t[i], u[i], + lambda[i], rgba[i]); + break; + case GL_LINEAR_MIPMAP_NEAREST: + sample_cube_linear_mipmap_nearest(ctx, tObj, s[i], t[i], u[i], + lambda[i], rgba[i]); + break; + case GL_NEAREST_MIPMAP_LINEAR: + sample_cube_nearest_mipmap_linear(ctx, tObj, s[i], t[i], u[i], + lambda[i], rgba[i]); + break; + case GL_LINEAR_MIPMAP_LINEAR: + sample_cube_linear_mipmap_linear(ctx, tObj, s[i], t[i], u[i], + lambda[i], rgba[i]); + break; + default: + _mesa_problem(NULL, "Bad min filter in sample_lambda_cube"); + } + } + else { + /* magnification */ + const struct gl_texture_image **images; + GLfloat newS, newT; + images = choose_cube_face(tObj, s[i], t[i], u[i], + &newS, &newT); + switch (tObj->MagFilter) { + case GL_NEAREST: + sample_2d_nearest(ctx, tObj, images[tObj->BaseLevel], + newS, newT, rgba[i]); + break; + case GL_LINEAR: + sample_2d_linear(ctx, tObj, images[tObj->BaseLevel], + newS, newT, rgba[i]); + break; + default: + _mesa_problem(NULL, "Bad mag filter in sample_lambda_cube"); + } + } + } +} + +static void +null_sample_func( GLcontext *ctx, GLuint texUnit, + const struct gl_texture_object *tObj, GLuint n, + const GLfloat s[], const GLfloat t[], + const GLfloat u[], const GLfloat lambda[], + GLchan rgba[][4]) +{ +} + +/**********************************************************************/ +/* Texture Sampling Setup */ +/**********************************************************************/ + + +/* + * Setup the texture sampling function for this texture object. + */ +void +_swrast_choose_texture_sample_func( GLcontext *ctx, GLuint texUnit, + const struct gl_texture_object *t ) +{ + SWcontext *swrast = SWRAST_CONTEXT(ctx); + + if (!t->Complete) { + swrast->TextureSample[texUnit] = null_sample_func; + } + else { + GLboolean needLambda = (GLboolean) (t->MinFilter != t->MagFilter); + + if (needLambda) { + /* Compute min/mag filter threshold */ + if (t->MagFilter == GL_LINEAR + && (t->MinFilter == GL_NEAREST_MIPMAP_NEAREST || + t->MinFilter == GL_NEAREST_MIPMAP_LINEAR)) { + swrast->_MinMagThresh[texUnit] = 0.5F; + } + else { + swrast->_MinMagThresh[texUnit] = 0.0F; + } + } + + switch (t->Dimensions) { + case 1: + if (needLambda) { + swrast->TextureSample[texUnit] = sample_lambda_1d; + } + else if (t->MinFilter==GL_LINEAR) { + swrast->TextureSample[texUnit] = sample_linear_1d; + } + else { + ASSERT(t->MinFilter==GL_NEAREST); + swrast->TextureSample[texUnit] = sample_nearest_1d; + } + break; + case 2: + if (needLambda) { + swrast->TextureSample[texUnit] = sample_lambda_2d; + } + else if (t->MinFilter==GL_LINEAR) { + swrast->TextureSample[texUnit] = sample_linear_2d; + } + else { + GLint baseLevel = t->BaseLevel; + ASSERT(t->MinFilter==GL_NEAREST); + if (t->WrapS == GL_REPEAT && + t->WrapT == GL_REPEAT && + t->Image[baseLevel]->Border == 0 && + t->Image[baseLevel]->TexFormat->MesaFormat == MESA_FORMAT_RGB) { + swrast->TextureSample[texUnit] = opt_sample_rgb_2d; + } + else if (t->WrapS == GL_REPEAT && + t->WrapT == GL_REPEAT && + t->Image[baseLevel]->Border == 0 && + t->Image[baseLevel]->TexFormat->MesaFormat == MESA_FORMAT_RGBA) { + swrast->TextureSample[texUnit] = opt_sample_rgba_2d; + } + else + swrast->TextureSample[texUnit] = sample_nearest_2d; + } + break; + case 3: + if (needLambda) { + swrast->TextureSample[texUnit] = sample_lambda_3d; + } + else if (t->MinFilter==GL_LINEAR) { + swrast->TextureSample[texUnit] = sample_linear_3d; + } + else { + ASSERT(t->MinFilter==GL_NEAREST); + swrast->TextureSample[texUnit] = sample_nearest_3d; + } + break; + case 6: /* cube map */ + if (needLambda) { + swrast->TextureSample[texUnit] = sample_lambda_cube; + } + else if (t->MinFilter==GL_LINEAR) { + swrast->TextureSample[texUnit] = sample_linear_cube; + } + else { + ASSERT(t->MinFilter==GL_NEAREST); + swrast->TextureSample[texUnit] = sample_nearest_cube; + } + break; + default: + _mesa_problem(NULL, "invalid dimensions in _mesa_set_texture_sampler"); + } + } +} + + +#define PROD(A,B) ( (GLuint)(A) * ((GLuint)(B)+1) ) +#define S_PROD(A,B) ( (GLint)(A) * ((GLint)(B)+1) ) + +static INLINE void +texture_combine(const GLcontext *ctx, + const struct gl_texture_unit *textureUnit, + GLuint n, + CONST GLchan (*primary_rgba)[4], + CONST GLchan (*texel)[4], + GLchan (*rgba)[4]) +{ + const GLchan (*argRGB [3])[4]; + const GLchan (*argA [3])[4]; + GLuint i, j; + const GLuint RGBshift = textureUnit->CombineScaleShiftRGB; + const GLuint Ashift = textureUnit->CombineScaleShiftA; + DEFMNARRAY(GLchan, ccolor, 3, 3 * MAX_WIDTH, 4); /* mac 32k limitation */ + CHECKARRAY(ccolor, return); /* mac 32k limitation */ + + ASSERT(ctx->Extensions.EXT_texture_env_combine || + ctx->Extensions.ARB_texture_env_combine); + + /* + * Do operand setup for up to 3 operands. Loop over the terms. + */ + for (j = 0; j < 3; j++) { + switch (textureUnit->CombineSourceA[j]) { + case GL_TEXTURE: + argA[j] = texel; + break; + case GL_PRIMARY_COLOR_EXT: + argA[j] = primary_rgba; + break; + case GL_PREVIOUS_EXT: + argA[j] = (const GLchan (*)[4]) rgba; + break; + case GL_CONSTANT_EXT: + { + GLchan alpha, (*c)[4] = ccolor[j]; + UNCLAMPED_FLOAT_TO_CHAN(alpha, textureUnit->EnvColor[3]); + for (i = 0; i < n; i++) + c[i][ACOMP] = alpha; + argA[j] = (const GLchan (*)[4]) ccolor[j]; + } + break; + default: + _mesa_problem(NULL, "invalid combine source"); + } + + switch (textureUnit->CombineSourceRGB[j]) { + case GL_TEXTURE: + argRGB[j] = texel; + break; + case GL_PRIMARY_COLOR_EXT: + argRGB[j] = primary_rgba; + break; + case GL_PREVIOUS_EXT: + argRGB[j] = (const GLchan (*)[4]) rgba; + break; + case GL_CONSTANT_EXT: + { + GLchan (*c)[4] = ccolor[j]; + GLchan red, green, blue, alpha; + UNCLAMPED_FLOAT_TO_CHAN(red, textureUnit->EnvColor[0]); + UNCLAMPED_FLOAT_TO_CHAN(green, textureUnit->EnvColor[1]); + UNCLAMPED_FLOAT_TO_CHAN(blue, textureUnit->EnvColor[2]); + UNCLAMPED_FLOAT_TO_CHAN(alpha, textureUnit->EnvColor[3]); + for (i = 0; i < n; i++) { + c[i][RCOMP] = red; + c[i][GCOMP] = green; + c[i][BCOMP] = blue; + c[i][ACOMP] = alpha; + } + argRGB[j] = (const GLchan (*)[4]) ccolor[j]; + } + break; + default: + _mesa_problem(NULL, "invalid combine source"); + } + + if (textureUnit->CombineOperandRGB[j] != GL_SRC_COLOR) { + const GLchan (*src)[4] = argRGB[j]; + GLchan (*dst)[4] = ccolor[j]; + + /* point to new arg[j] storage */ + argRGB[j] = (const GLchan (*)[4]) ccolor[j]; + + if (textureUnit->CombineOperandRGB[j] == GL_ONE_MINUS_SRC_COLOR) { + for (i = 0; i < n; i++) { + dst[i][RCOMP] = CHAN_MAX - src[i][RCOMP]; + dst[i][GCOMP] = CHAN_MAX - src[i][GCOMP]; + dst[i][BCOMP] = CHAN_MAX - src[i][BCOMP]; + } + } + else if (textureUnit->CombineOperandRGB[j] == GL_SRC_ALPHA) { + for (i = 0; i < n; i++) { + dst[i][RCOMP] = src[i][ACOMP]; + dst[i][GCOMP] = src[i][ACOMP]; + dst[i][BCOMP] = src[i][ACOMP]; + } + } + else { + ASSERT(textureUnit->CombineOperandRGB[j] ==GL_ONE_MINUS_SRC_ALPHA); + for (i = 0; i < n; i++) { + dst[i][RCOMP] = CHAN_MAX - src[i][ACOMP]; + dst[i][GCOMP] = CHAN_MAX - src[i][ACOMP]; + dst[i][BCOMP] = CHAN_MAX - src[i][ACOMP]; + } + } + } + + if (textureUnit->CombineOperandA[j] == GL_ONE_MINUS_SRC_ALPHA) { + const GLchan (*src)[4] = argA[j]; + GLchan (*dst)[4] = ccolor[j]; + argA[j] = (const GLchan (*)[4]) ccolor[j]; + for (i = 0; i < n; i++) { + dst[i][ACOMP] = CHAN_MAX - src[i][ACOMP]; + } + } + + if (textureUnit->CombineModeRGB == GL_REPLACE && + textureUnit->CombineModeA == GL_REPLACE) { + break; /* done, we need only arg0 */ + } + + if (j == 1 && + textureUnit->CombineModeRGB != GL_INTERPOLATE_EXT && + textureUnit->CombineModeA != GL_INTERPOLATE_EXT) { + break; /* arg0 and arg1 are done. we don't need arg2. */ + } + } + + /* + * Do the texture combine. + */ + switch (textureUnit->CombineModeRGB) { + case GL_REPLACE: + { + const GLchan (*arg0)[4] = (const GLchan (*)[4]) argRGB[0]; + if (RGBshift) { + for (i = 0; i < n; i++) { + GLuint r = (GLuint) arg0[i][RCOMP] << RGBshift; + GLuint g = (GLuint) arg0[i][GCOMP] << RGBshift; + GLuint b = (GLuint) arg0[i][BCOMP] << RGBshift; + rgba[i][RCOMP] = MIN2(r, CHAN_MAX); + rgba[i][GCOMP] = MIN2(g, CHAN_MAX); + rgba[i][BCOMP] = MIN2(b, CHAN_MAX); + } + } + else { + for (i = 0; i < n; i++) { + rgba[i][RCOMP] = arg0[i][RCOMP]; + rgba[i][GCOMP] = arg0[i][GCOMP]; + rgba[i][BCOMP] = arg0[i][BCOMP]; + } + } + } + break; + case GL_MODULATE: + { + const GLchan (*arg0)[4] = (const GLchan (*)[4]) argRGB[0]; + const GLchan (*arg1)[4] = (const GLchan (*)[4]) argRGB[1]; + const GLint shift = 8 - RGBshift; + for (i = 0; i < n; i++) { + GLuint r = PROD(arg0[i][0], arg1[i][RCOMP]) >> shift; + GLuint g = PROD(arg0[i][1], arg1[i][GCOMP]) >> shift; + GLuint b = PROD(arg0[i][2], arg1[i][BCOMP]) >> shift; + rgba[i][RCOMP] = (GLchan) MIN2(r, CHAN_MAX); + rgba[i][GCOMP] = (GLchan) MIN2(g, CHAN_MAX); + rgba[i][BCOMP] = (GLchan) MIN2(b, CHAN_MAX); + } + } + break; + case GL_ADD: + { + const GLchan (*arg0)[4] = (const GLchan (*)[4]) argRGB[0]; + const GLchan (*arg1)[4] = (const GLchan (*)[4]) argRGB[1]; + for (i = 0; i < n; i++) { + GLint r = ((GLint) arg0[i][RCOMP] + (GLint) arg1[i][RCOMP]) << RGBshift; + GLint g = ((GLint) arg0[i][GCOMP] + (GLint) arg1[i][GCOMP]) << RGBshift; + GLint b = ((GLint) arg0[i][BCOMP] + (GLint) arg1[i][BCOMP]) << RGBshift; + rgba[i][RCOMP] = (GLchan) MIN2(r, CHAN_MAX); + rgba[i][GCOMP] = (GLchan) MIN2(g, CHAN_MAX); + rgba[i][BCOMP] = (GLchan) MIN2(b, CHAN_MAX); + } + } + break; + case GL_ADD_SIGNED_EXT: + { + const GLchan (*arg0)[4] = (const GLchan (*)[4]) argRGB[0]; + const GLchan (*arg1)[4] = (const GLchan (*)[4]) argRGB[1]; + for (i = 0; i < n; i++) { + GLint r = (GLint) arg0[i][RCOMP] + (GLint) arg1[i][RCOMP] - 128; + GLint g = (GLint) arg0[i][GCOMP] + (GLint) arg1[i][GCOMP] - 128; + GLint b = (GLint) arg0[i][BCOMP] + (GLint) arg1[i][BCOMP] - 128; + r = (r < 0) ? 0 : r << RGBshift; + g = (g < 0) ? 0 : g << RGBshift; + b = (b < 0) ? 0 : b << RGBshift; + rgba[i][RCOMP] = (GLchan) MIN2(r, CHAN_MAX); + rgba[i][GCOMP] = (GLchan) MIN2(g, CHAN_MAX); + rgba[i][BCOMP] = (GLchan) MIN2(b, CHAN_MAX); + } + } + break; + case GL_INTERPOLATE_EXT: + { + const GLchan (*arg0)[4] = (const GLchan (*)[4]) argRGB[0]; + const GLchan (*arg1)[4] = (const GLchan (*)[4]) argRGB[1]; + const GLchan (*arg2)[4] = (const GLchan (*)[4]) argRGB[2]; + const GLint shift = 8 - RGBshift; + for (i = 0; i < n; i++) { + GLuint r = (PROD(arg0[i][RCOMP], arg2[i][RCOMP]) + + PROD(arg1[i][RCOMP], CHAN_MAX - arg2[i][RCOMP])) + >> shift; + GLuint g = (PROD(arg0[i][GCOMP], arg2[i][GCOMP]) + + PROD(arg1[i][GCOMP], CHAN_MAX - arg2[i][GCOMP])) + >> shift; + GLuint b = (PROD(arg0[i][BCOMP], arg2[i][BCOMP]) + + PROD(arg1[i][BCOMP], CHAN_MAX - arg2[i][BCOMP])) + >> shift; + rgba[i][RCOMP] = (GLchan) MIN2(r, CHAN_MAX); + rgba[i][GCOMP] = (GLchan) MIN2(g, CHAN_MAX); + rgba[i][BCOMP] = (GLchan) MIN2(b, CHAN_MAX); + } + } + break; + case GL_SUBTRACT_ARB: + { + const GLchan (*arg0)[4] = (const GLchan (*)[4]) argRGB[0]; + const GLchan (*arg1)[4] = (const GLchan (*)[4]) argRGB[1]; + for (i = 0; i < n; i++) { + GLint r = ((GLint) arg0[i][RCOMP] - (GLint) arg1[i][RCOMP]) << RGBshift; + GLint g = ((GLint) arg0[i][GCOMP] - (GLint) arg1[i][GCOMP]) << RGBshift; + GLint b = ((GLint) arg0[i][BCOMP] - (GLint) arg1[i][BCOMP]) << RGBshift; + rgba[i][RCOMP] = (GLchan) CLAMP(r, 0, CHAN_MAX); + rgba[i][GCOMP] = (GLchan) CLAMP(g, 0, CHAN_MAX); + rgba[i][BCOMP] = (GLchan) CLAMP(b, 0, CHAN_MAX); + } + } + break; + case GL_DOT3_RGB_EXT: + case GL_DOT3_RGBA_EXT: + case GL_DOT3_RGB_ARB: + case GL_DOT3_RGBA_ARB: + { + const GLchan (*arg0)[4] = (const GLchan (*)[4]) argRGB[0]; + const GLchan (*arg1)[4] = (const GLchan (*)[4]) argRGB[1]; + /* ATI's EXT extension has a constant scale by 4. The ARB + * one will likely remove this restriction, and we should + * drop the EXT extension in favour of the ARB one. + */ + for (i = 0; i < n; i++) { + GLint dot = (S_PROD((GLint)arg0[i][RCOMP] - 128, + (GLint)arg1[i][RCOMP] - 128) + + S_PROD((GLint)arg0[i][GCOMP] - 128, + (GLint)arg1[i][GCOMP] - 128) + + S_PROD((GLint)arg0[i][BCOMP] - 128, + (GLint)arg1[i][BCOMP] - 128)) >> 6; + dot = CLAMP(dot, 0, 255); + rgba[i][RCOMP] = rgba[i][GCOMP] = rgba[i][BCOMP] = (GLchan) dot; + } + } + break; + default: + _mesa_problem(NULL, "invalid combine mode"); + } + + switch (textureUnit->CombineModeA) { + case GL_REPLACE: + { + const GLchan (*arg0)[4] = (const GLchan (*)[4]) argA[0]; + if (Ashift) { + for (i = 0; i < n; i++) { + GLuint a = (GLuint) arg0[i][ACOMP] << Ashift; + rgba[i][ACOMP] = (GLchan) MIN2(a, CHAN_MAX); + } + } + else { + for (i = 0; i < n; i++) { + rgba[i][ACOMP] = arg0[i][ACOMP]; + } + } + } + break; + case GL_MODULATE: + { + const GLchan (*arg0)[4] = (const GLchan (*)[4]) argA[0]; + const GLchan (*arg1)[4] = (const GLchan (*)[4]) argA[1]; + const GLint shift = 8 - Ashift; + for (i = 0; i < n; i++) { + GLuint a = (PROD(arg0[i][ACOMP], arg1[i][ACOMP]) >> shift); + rgba[i][ACOMP] = (GLchan) MIN2(a, CHAN_MAX); + } + } + break; + case GL_ADD: + { + const GLchan (*arg0)[4] = (const GLchan (*)[4]) argA[0]; + const GLchan (*arg1)[4] = (const GLchan (*)[4]) argA[1]; + for (i = 0; i < n; i++) { + GLint a = ((GLint) arg0[i][ACOMP] + arg1[i][ACOMP]) << Ashift; + rgba[i][ACOMP] = (GLchan) MIN2(a, CHAN_MAX); + } + } + break; + case GL_ADD_SIGNED_EXT: + { + const GLchan (*arg0)[4] = (const GLchan (*)[4]) argA[0]; + const GLchan (*arg1)[4] = (const GLchan (*)[4]) argA[1]; + for (i = 0; i < n; i++) { + GLint a = (GLint) arg0[i][ACOMP] + (GLint) arg1[i][ACOMP] - 128; + a = (a < 0) ? 0 : a << Ashift; + rgba[i][ACOMP] = (GLchan) MIN2(a, CHAN_MAX); + } + } + break; + case GL_INTERPOLATE_EXT: + { + const GLchan (*arg0)[4] = (const GLchan (*)[4]) argA[0]; + const GLchan (*arg1)[4] = (const GLchan (*)[4]) argA[1]; + const GLchan (*arg2)[4] = (const GLchan (*)[4]) argA[2]; + const GLint shift = 8 - Ashift; + for (i=0; i> shift; + rgba[i][ACOMP] = (GLchan) MIN2(a, CHAN_MAX); + } + } + break; + case GL_SUBTRACT_ARB: + { + const GLchan (*arg0)[4] = (const GLchan (*)[4]) argRGB[0]; + const GLchan (*arg1)[4] = (const GLchan (*)[4]) argRGB[1]; + for (i = 0; i < n; i++) { + GLint a = ((GLint) arg0[i][ACOMP] - (GLint) arg1[i][ACOMP]) << RGBshift; + rgba[i][ACOMP] = (GLchan) CLAMP(a, 0, CHAN_MAX); + } + } + break; + + default: + _mesa_problem(NULL, "invalid combine mode"); + } + + /* Fix the alpha component for GL_DOT3_RGBA_EXT combining. + */ + if (textureUnit->CombineModeRGB == GL_DOT3_RGBA_EXT || + textureUnit->CombineModeRGB == GL_DOT3_RGBA_ARB) { + for (i = 0; i < n; i++) { + rgba[i][ACOMP] = rgba[i][RCOMP]; + } + } + UNDEFARRAY(ccolor); /* mac 32k limitation */ +} +#undef PROD + + + +/**********************************************************************/ +/* Texture Application */ +/**********************************************************************/ + + +/* + * Combine incoming fragment color with texel color to produce output color. + * Input: textureUnit - pointer to texture unit to apply + * format - base internal texture format + * n - number of fragments + * primary_rgba - primary colors (may alias rgba for single texture) + * texels - array of texel colors + * InOut: rgba - incoming fragment colors modified by texel colors + * according to the texture environment mode. + */ +static void +apply_texture( const GLcontext *ctx, + const struct gl_texture_unit *texUnit, + GLuint n, + CONST GLchan primary_rgba[][4], CONST GLchan texel[][4], + GLchan rgba[][4] ) +{ + GLint baseLevel; + GLuint i; + GLint Rc, Gc, Bc, Ac; + GLenum format; + + ASSERT(texUnit); + ASSERT(texUnit->_Current); + + baseLevel = texUnit->_Current->BaseLevel; + ASSERT(texUnit->_Current->Image[baseLevel]); + + format = texUnit->_Current->Image[baseLevel]->Format; + + if (format==GL_COLOR_INDEX || format==GL_DEPTH_COMPONENT) { + format = GL_RGBA; /* XXXX a hack! */ + } + + switch (texUnit->EnvMode) { + case GL_REPLACE: + switch (format) { + case GL_ALPHA: + for (i=0;iEnvColor[0] * CHAN_MAXF); + Gc = (GLint) (texUnit->EnvColor[1] * CHAN_MAXF); + Bc = (GLint) (texUnit->EnvColor[2] * CHAN_MAXF); + Ac = (GLint) (texUnit->EnvColor[3] * CHAN_MAXF); + switch (format) { + case GL_ALPHA: + for (i=0;i_Current; + const GLint baseLevel = texObj->BaseLevel; + const struct gl_texture_image *texImage = texObj->Image[baseLevel]; + const GLuint width = texImage->Width; + const GLuint height = texImage->Height; + const GLchan ambient = texObj->ShadowAmbient; + GLboolean lequal, gequal; + + if (texObj->Dimensions != 2) { + _mesa_problem(ctx, "only 2-D depth textures supported at this time"); + return; + } + + if (texObj->MinFilter != texObj->MagFilter) { + _mesa_problem(ctx, "mipmapped depth textures not supported at this time"); + return; + } + + /* XXX the GL_SGIX_shadow extension spec doesn't say what to do if + * GL_TEXTURE_COMPARE_SGIX == GL_TRUE but the current texture object + * isn't a depth texture. + */ + if (texImage->Format != GL_DEPTH_COMPONENT) { + _mesa_problem(ctx,"GL_TEXTURE_COMPARE_SGIX enabled with non-depth texture"); + return; + } + + if (texObj->CompareOperator == GL_TEXTURE_LEQUAL_R_SGIX) { + lequal = GL_TRUE; + gequal = GL_FALSE; + } + else { + lequal = GL_FALSE; + gequal = GL_TRUE; + } + + if (texObj->MagFilter == GL_NEAREST) { + GLuint i; + for (i = 0; i < n; i++) { + GLfloat depthSample; + GLint col, row; + COMPUTE_NEAREST_TEXEL_LOCATION(texObj->WrapS, s[i], width, col); + COMPUTE_NEAREST_TEXEL_LOCATION(texObj->WrapT, t[i], height, row); + depthSample = *((const GLfloat *) texImage->Data + row * width + col); + if ((r[i] <= depthSample && lequal) || + (r[i] >= depthSample && gequal)) { + texel[i][RCOMP] = CHAN_MAX; + texel[i][GCOMP] = CHAN_MAX; + texel[i][BCOMP] = CHAN_MAX; + texel[i][ACOMP] = CHAN_MAX; + } + else { + texel[i][RCOMP] = ambient; + texel[i][GCOMP] = ambient; + texel[i][BCOMP] = ambient; + texel[i][ACOMP] = CHAN_MAX; + } + } + } + else { + GLuint i; + ASSERT(texObj->MagFilter == GL_LINEAR); + for (i = 0; i < n; i++) { + GLfloat depth00, depth01, depth10, depth11; + GLint i0, i1, j0, j1; + GLfloat u, v; + GLuint useBorderTexel; + + COMPUTE_LINEAR_TEXEL_LOCATIONS(texObj->WrapS, s[i], u, width, i0, i1); + COMPUTE_LINEAR_TEXEL_LOCATIONS(texObj->WrapT, t[i], v, height,j0, j1); + + useBorderTexel = 0; + if (texImage->Border) { + i0 += texImage->Border; + i1 += texImage->Border; + j0 += texImage->Border; + j1 += texImage->Border; + } + else { + if (i0 < 0 || i0 >= (GLint) width) useBorderTexel |= I0BIT; + if (i1 < 0 || i1 >= (GLint) width) useBorderTexel |= I1BIT; + if (j0 < 0 || j0 >= (GLint) height) useBorderTexel |= J0BIT; + if (j1 < 0 || j1 >= (GLint) height) useBorderTexel |= J1BIT; + } + + /* get four depth samples from the texture */ + if (useBorderTexel & (I0BIT | J0BIT)) { + depth00 = 1.0; + } + else { + depth00 = *((const GLfloat *) texImage->Data + j0 * width + i0); + } + if (useBorderTexel & (I1BIT | J0BIT)) { + depth10 = 1.0; + } + else { + depth10 = *((const GLfloat *) texImage->Data + j0 * width + i1); + } + if (useBorderTexel & (I0BIT | J1BIT)) { + depth01 = 1.0; + } + else { + depth01 = *((const GLfloat *) texImage->Data + j1 * width + i0); + } + if (useBorderTexel & (I1BIT | J1BIT)) { + depth11 = 1.0; + } + else { + depth11 = *((const GLfloat *) texImage->Data + j1 * width + i1); + } + + if (0) { + /* compute a single weighted depth sample and do one comparison */ + const GLfloat a = FRAC(u + 1.0F); + const GLfloat b = FRAC(v + 1.0F); + const GLfloat w00 = (1.0F - a) * (1.0F - b); + const GLfloat w10 = ( a) * (1.0F - b); + const GLfloat w01 = (1.0F - a) * ( b); + const GLfloat w11 = ( a) * ( b); + const GLfloat depthSample = w00 * depth00 + w10 * depth10 + + w01 * depth01 + w11 * depth11; + if ((depthSample <= r[i] && lequal) || + (depthSample >= r[i] && gequal)) { + texel[i][RCOMP] = ambient; + texel[i][GCOMP] = ambient; + texel[i][BCOMP] = ambient; + texel[i][ACOMP] = CHAN_MAX; + } + else { + texel[i][RCOMP] = CHAN_MAX; + texel[i][GCOMP] = CHAN_MAX; + texel[i][BCOMP] = CHAN_MAX; + texel[i][ACOMP] = CHAN_MAX; + } + } + else { + /* Do four depth/R comparisons and compute a weighted result. + * If this touches on somebody's I.P., I'll remove this code + * upon request. + */ + const GLfloat d = (CHAN_MAXF - (GLfloat) ambient) * 0.25F; + GLfloat luminance = CHAN_MAXF; + GLchan lum; + if (lequal) { + if (depth00 <= r[i]) luminance -= d; + if (depth01 <= r[i]) luminance -= d; + if (depth10 <= r[i]) luminance -= d; + if (depth11 <= r[i]) luminance -= d; + } + else { + if (depth00 >= r[i]) luminance -= d; + if (depth01 >= r[i]) luminance -= d; + if (depth10 >= r[i]) luminance -= d; + if (depth11 >= r[i]) luminance -= d; + } + lum = (GLchan) luminance; + texel[i][RCOMP] = lum; + texel[i][GCOMP] = lum; + texel[i][BCOMP] = lum; + texel[i][ACOMP] = CHAN_MAX; + } + } + } +} + + +#if 0 +/* + * Experimental depth texture sampling function. + */ +static void +sample_depth_texture2(const GLcontext *ctx, + const struct gl_texture_unit *texUnit, + GLuint n, + const GLfloat s[], const GLfloat t[], const GLfloat r[], + GLchan texel[][4]) +{ + const struct gl_texture_object *texObj = texUnit->_Current; + const GLint baseLevel = texObj->BaseLevel; + const struct gl_texture_image *texImage = texObj->Image[baseLevel]; + const GLuint width = texImage->Width; + const GLuint height = texImage->Height; + const GLchan ambient = texObj->ShadowAmbient; + GLboolean lequal, gequal; + + if (texObj->Dimensions != 2) { + _mesa_problem(ctx, "only 2-D depth textures supported at this time"); + return; + } + + if (texObj->MinFilter != texObj->MagFilter) { + _mesa_problem(ctx, "mipmapped depth textures not supported at this time"); + return; + } + + /* XXX the GL_SGIX_shadow extension spec doesn't say what to do if + * GL_TEXTURE_COMPARE_SGIX == GL_TRUE but the current texture object + * isn't a depth texture. + */ + if (texImage->Format != GL_DEPTH_COMPONENT) { + _mesa_problem(ctx,"GL_TEXTURE_COMPARE_SGIX enabled with non-depth texture"); + return; + } + + if (texObj->CompareOperator == GL_TEXTURE_LEQUAL_R_SGIX) { + lequal = GL_TRUE; + gequal = GL_FALSE; + } + else { + lequal = GL_FALSE; + gequal = GL_TRUE; + } + + { + GLuint i; + for (i = 0; i < n; i++) { + const GLint K = 3; + GLint col, row, ii, jj, imin, imax, jmin, jmax, samples, count; + GLfloat w; + GLchan lum; + COMPUTE_NEAREST_TEXEL_LOCATION(texObj->WrapS, s[i], width, col); + COMPUTE_NEAREST_TEXEL_LOCATION(texObj->WrapT, t[i], height, row); + + imin = col - K; + imax = col + K; + jmin = row - K; + jmax = row + K; + + if (imin < 0) imin = 0; + if (imax >= width) imax = width - 1; + if (jmin < 0) jmin = 0; + if (jmax >= height) jmax = height - 1; + + samples = (imax - imin + 1) * (jmax - jmin + 1); + count = 0; + for (jj = jmin; jj <= jmax; jj++) { + for (ii = imin; ii <= imax; ii++) { + GLfloat depthSample = *((const GLfloat *) texImage->Data + + jj * width + ii); + if ((depthSample <= r[i] && lequal) || + (depthSample >= r[i] && gequal)) { + count++; + } + } + } + + w = (GLfloat) count / (GLfloat) samples; + w = CHAN_MAXF - w * (CHAN_MAXF - (GLfloat) ambient); + lum = (GLint) w; + + texel[i][RCOMP] = lum; + texel[i][GCOMP] = lum; + texel[i][BCOMP] = lum; + texel[i][ACOMP] = CHAN_MAX; + } + } +} +#endif + + +/* + * Apply a unit of texture mapping to the incoming fragments. + */ +void +_swrast_texture_fragments( GLcontext *ctx, GLuint texUnit, GLuint n, + const GLfloat s[], const GLfloat t[], + const GLfloat r[], GLfloat lambda[], + CONST GLchan primary_rgba[][4], GLchan rgba[][4] ) +{ + const GLuint mask = TEXTURE0_ANY << (texUnit * 4); + + if (ctx->Texture._ReallyEnabled & mask) { + const struct gl_texture_unit *textureUnit = &ctx->Texture.Unit[texUnit]; + + if (textureUnit->_Current) { /* XXX need this? */ + GLchan texel[PB_SIZE][4]; + + if (textureUnit->LodBias != 0.0F) { + /* apply LOD bias, but don't clamp yet */ + GLuint i; + for (i=0;iLodBias; + } + } + + if ((textureUnit->_Current->MinLod != -1000.0 + || textureUnit->_Current->MaxLod != 1000.0) + && lambda) { + /* apply LOD clamping to lambda */ + const GLfloat min = textureUnit->_Current->MinLod; + const GLfloat max = textureUnit->_Current->MaxLod; + GLuint i; + for (i=0;i_Current->CompareFlag) { + /* depth texture */ + sample_depth_texture(ctx, textureUnit, n, s, t, r, texel); + } + else { + /* color texture */ + SWRAST_CONTEXT(ctx)->TextureSample[texUnit]( ctx, texUnit, + textureUnit->_Current, + n, s, t, r, + lambda, texel ); + } + apply_texture( ctx, textureUnit, n, primary_rgba, + (const GLchan (*)[4]) texel, rgba ); + } + } +} Index: dll/opengl/opengl32/mesa/swrast/s_texture.h =================================================================== --- dll/opengl/opengl32/mesa/swrast/s_texture.h (revision 0) +++ dll/opengl/opengl32/mesa/swrast/s_texture.h (working copy) @@ -0,0 +1,49 @@ +/* $Id: s_texture.h,v 1.6 2001/03/12 00:48:42 gareth Exp $ */ + +/* + * Mesa 3-D graphics library + * Version: 3.5 + * + * Copyright (C) 1999-2001 Brian Paul 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 + * BRIAN PAUL 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. + */ + + +#ifndef S_TEXTURE_H +#define S_TEXTURE_H + + +#include "mtypes.h" +#include "swrast.h" + + +extern void +_swrast_choose_texture_sample_func( GLcontext *ctx, + GLuint texUnit, + const struct gl_texture_object *tObj ); + + +extern void +_swrast_texture_fragments( GLcontext *ctx, GLuint texSet, GLuint n, + const GLfloat s[], const GLfloat t[], + const GLfloat r[], GLfloat lambda[], + CONST GLchan primary_rgba[][4], GLchan rgba[][4] ); + + +#endif Index: dll/opengl/opengl32/mesa/swrast/s_triangle.c =================================================================== --- dll/opengl/opengl32/mesa/swrast/s_triangle.c (revision 0) +++ dll/opengl/opengl32/mesa/swrast/s_triangle.c (working copy) @@ -0,0 +1,2431 @@ +/* $Id: s_triangle.c,v 1.29 2001/05/17 09:32:17 keithw Exp $ */ + +/* + * Mesa 3-D graphics library + * Version: 3.5 + * + * Copyright (C) 1999-2001 Brian Paul 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 + * BRIAN PAUL 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. + */ + + +/* + * When the device driver doesn't implement triangle rasterization it + * can hook in _swrast_Triangle, which eventually calls one of these + * functions to draw triangles. + */ + +#include "glheader.h" +#include "context.h" +#include "colormac.h" +#include "macros.h" +#include "mem.h" +#include "mmath.h" +#include "texformat.h" +#include "teximage.h" +#include "texstate.h" + +#include "s_aatriangle.h" +#include "s_context.h" +#include "s_depth.h" +#include "s_feedback.h" +#include "s_span.h" +#include "s_triangle.h" +#include "s_trispan.h" + + + +GLboolean _mesa_cull_triangle( GLcontext *ctx, + const SWvertex *v0, + const SWvertex *v1, + const SWvertex *v2 ) +{ + GLfloat ex = v1->win[0] - v0->win[0]; + GLfloat ey = v1->win[1] - v0->win[1]; + GLfloat fx = v2->win[0] - v0->win[0]; + GLfloat fy = v2->win[1] - v0->win[1]; + GLfloat c = ex*fy-ey*fx; + + if (c * SWRAST_CONTEXT(ctx)->_backface_sign > 0) + return 0; + + return 1; +} + + + +/* + * Render a flat-shaded color index triangle. + */ +static void flat_ci_triangle( GLcontext *ctx, + const SWvertex *v0, + const SWvertex *v1, + const SWvertex *v2 ) +{ +#define INTERP_Z 1 +#define INTERP_FOG 1 + +#define RENDER_SPAN( span ) \ + GLdepth zSpan[MAX_WIDTH]; \ + GLfloat fogSpan[MAX_WIDTH]; \ + GLuint i; \ + for (i = 0; i < span.count; i++) { \ + zSpan[i] = FixedToDepth(span.z); \ + span.z += span.zStep; \ + fogSpan[i] = span.fog; \ + span.fog += span.fogStep; \ + } \ + _mesa_write_monoindex_span(ctx, span.count, span.x, span.y, \ + zSpan, fogSpan, v0->index, NULL, GL_POLYGON ); + +#include "s_tritemp.h" +} + + + +/* + * Render a smooth-shaded color index triangle. + */ +static void smooth_ci_triangle( GLcontext *ctx, + const SWvertex *v0, + const SWvertex *v1, + const SWvertex *v2 ) +{ +#define INTERP_Z 1 +#define INTERP_FOG 1 +#define INTERP_INDEX 1 + +#define RENDER_SPAN( span ) \ + GLdepth zSpan[MAX_WIDTH]; \ + GLfloat fogSpan[MAX_WIDTH]; \ + GLuint indexSpan[MAX_WIDTH]; \ + GLuint i; \ + for (i = 0; i < span.count; i++) { \ + zSpan[i] = FixedToDepth(span.z); \ + span.z += span.zStep; \ + indexSpan[i] = FixedToInt(span.index); \ + span.index += span.indexStep; \ + fogSpan[i] = span.fog; \ + span.fog += span.fogStep; \ + } \ + _mesa_write_index_span(ctx, span.count, span.x, span.y, \ + zSpan, fogSpan, indexSpan, NULL, GL_POLYGON); + +#include "s_tritemp.h" +} + + + +/* + * Render a flat-shaded RGBA triangle. + */ +static void flat_rgba_triangle( GLcontext *ctx, + const SWvertex *v0, + const SWvertex *v1, + const SWvertex *v2 ) +{ +#define INTERP_Z 1 +#define INTERP_FOG 1 +#define DEPTH_TYPE DEFAULT_SOFTWARE_DEPTH_TYPE + +#define RENDER_SPAN( span ) \ + GLdepth zSpan[MAX_WIDTH]; \ + GLfloat fogSpan[MAX_WIDTH]; \ + GLuint i; \ + for (i = 0; i < span.count; i++) { \ + zSpan[i] = FixedToDepth(span.z); \ + span.z += span.zStep; \ + fogSpan[i] = span.fog; \ + span.fog += span.fogStep; \ + } \ + _mesa_write_monocolor_span(ctx, span.count, span.x, span.y, zSpan, \ + fogSpan, v2->color, NULL, GL_POLYGON ); + +#include "s_tritemp.h" + + ASSERT(!ctx->Texture._ReallyEnabled); /* texturing must be off */ + ASSERT(ctx->Light.ShadeModel==GL_FLAT); +} + + + +/* + * Render a smooth-shaded RGBA triangle. + */ +static void smooth_rgba_triangle( GLcontext *ctx, + const SWvertex *v0, + const SWvertex *v1, + const SWvertex *v2 ) +{ + +#define INTERP_Z 1 +#define INTERP_FOG 1 +#define DEPTH_TYPE DEFAULT_SOFTWARE_DEPTH_TYPE +#define INTERP_RGB 1 +#define INTERP_ALPHA 1 + +#define RENDER_SPAN( span ) \ + GLdepth zSpan[MAX_WIDTH]; \ + GLchan rgbaSpan[MAX_WIDTH][4]; \ + GLfloat fogSpan[MAX_WIDTH]; \ + GLuint i; \ + for (i = 0; i < span.count; i++) { \ + rgbaSpan[i][RCOMP] = FixedToInt(span.red); \ + rgbaSpan[i][GCOMP] = FixedToInt(span.green); \ + rgbaSpan[i][BCOMP] = FixedToInt(span.blue); \ + rgbaSpan[i][ACOMP] = FixedToInt(span.alpha); \ + span.red += span.redStep; \ + span.green += span.greenStep; \ + span.blue += span.blueStep; \ + span.alpha += span.alphaStep; \ + zSpan[i] = FixedToDepth(span.z); \ + span.z += span.zStep; \ + fogSpan[i] = span.fog; \ + span.fog += span.fogStep; \ + } \ + _mesa_write_rgba_span(ctx, span.count, span.x, span.y, \ + (CONST GLdepth *) zSpan, \ + fogSpan, rgbaSpan, NULL, GL_POLYGON); + +#include "s_tritemp.h" + + ASSERT(!ctx->Texture._ReallyEnabled); /* texturing must be off */ + ASSERT(ctx->Light.ShadeModel==GL_SMOOTH); +} + + +/* + * Render an RGB, GL_DECAL, textured triangle. + * Interpolate S,T only w/out mipmapping or perspective correction. + * + * No fog. + */ +static void simple_textured_triangle( GLcontext *ctx, + const SWvertex *v0, + const SWvertex *v1, + const SWvertex *v2 ) +{ +#define INTERP_INT_TEX 1 +#define S_SCALE twidth +#define T_SCALE theight + +#define SETUP_CODE \ + SWcontext *swrast = SWRAST_CONTEXT(ctx); \ + struct gl_texture_object *obj = ctx->Texture.Unit[0].Current2D; \ + GLint b = obj->BaseLevel; \ + const GLfloat twidth = (GLfloat) obj->Image[b]->Width; \ + const GLfloat theight = (GLfloat) obj->Image[b]->Height; \ + const GLint twidth_log2 = obj->Image[b]->WidthLog2; \ + const GLchan *texture = (const GLchan *) obj->Image[b]->Data; \ + const GLint smask = obj->Image[b]->Width - 1; \ + const GLint tmask = obj->Image[b]->Height - 1; \ + if (!texture) { \ + /* this shouldn't happen */ \ + return; \ + } + +#define RENDER_SPAN( span ) \ + GLchan rgbSpan[MAX_WIDTH][3]; \ + GLuint i; \ + span.intTex[0] -= FIXED_HALF; /* off-by-one error? */ \ + span.intTex[1] -= FIXED_HALF; \ + for (i = 0; i < span.count; i++) { \ + GLint s = FixedToInt(span.intTex[0]) & smask; \ + GLint t = FixedToInt(span.intTex[1]) & tmask; \ + GLint pos = (t << twidth_log2) + s; \ + pos = pos + pos + pos; /* multiply by 3 */ \ + rgbSpan[i][RCOMP] = texture[pos]; \ + rgbSpan[i][GCOMP] = texture[pos+1]; \ + rgbSpan[i][BCOMP] = texture[pos+2]; \ + span.intTex[0] += span.intTexStep[0]; \ + span.intTex[1] += span.intTexStep[1]; \ + } \ + (*swrast->Driver.WriteRGBSpan)(ctx, span.count, span.x, span.y, \ + (CONST GLchan (*)[3]) rgbSpan, NULL ); + +#include "s_tritemp.h" +} + + +/* + * Render an RGB, GL_DECAL, textured triangle. + * Interpolate S,T, GL_LESS depth test, w/out mipmapping or + * perspective correction. + * + * No fog. + */ +static void simple_z_textured_triangle( GLcontext *ctx, + const SWvertex *v0, + const SWvertex *v1, + const SWvertex *v2 ) +{ +#define INTERP_Z 1 +#define DEPTH_TYPE DEFAULT_SOFTWARE_DEPTH_TYPE +#define INTERP_INT_TEX 1 +#define S_SCALE twidth +#define T_SCALE theight + +#define SETUP_CODE \ + SWcontext *swrast = SWRAST_CONTEXT(ctx); \ + struct gl_texture_object *obj = ctx->Texture.Unit[0].Current2D; \ + GLint b = obj->BaseLevel; \ + GLfloat twidth = (GLfloat) obj->Image[b]->Width; \ + GLfloat theight = (GLfloat) obj->Image[b]->Height; \ + GLint twidth_log2 = obj->Image[b]->WidthLog2; \ + const GLchan *texture = (const GLchan *) obj->Image[b]->Data; \ + GLint smask = obj->Image[b]->Width - 1; \ + GLint tmask = obj->Image[b]->Height - 1; \ + if (!texture) { \ + /* this shouldn't happen */ \ + return; \ + } + +#define RENDER_SPAN( span ) \ + GLchan rgbSpan[MAX_WIDTH][3]; \ + GLubyte mask[MAX_WIDTH]; \ + GLuint i; \ + span.intTex[0] -= FIXED_HALF; /* off-by-one error? */ \ + span.intTex[1] -= FIXED_HALF; \ + for (i = 0; i < span.count; i++) { \ + const GLdepth z = FixedToDepth(span.z); \ + if (z < zRow[i]) { \ + GLint s = FixedToInt(span.intTex[0]) & smask; \ + GLint t = FixedToInt(span.intTex[1]) & tmask; \ + GLint pos = (t << twidth_log2) + s; \ + pos = pos + pos + pos; /* multiply by 3 */ \ + rgbSpan[i][RCOMP] = texture[pos]; \ + rgbSpan[i][GCOMP] = texture[pos+1]; \ + rgbSpan[i][BCOMP] = texture[pos+2]; \ + zRow[i] = z; \ + mask[i] = 1; \ + } \ + else { \ + mask[i] = 0; \ + } \ + span.intTex[0] += span.intTexStep[0]; \ + span.intTex[1] += span.intTexStep[1]; \ + span.z += span.zStep; \ + } \ + (*swrast->Driver.WriteRGBSpan)(ctx, span.count, span.x, span.y, \ + (CONST GLchan (*)[3]) rgbSpan, mask ); + +#include "s_tritemp.h" +} + + + +struct affine_info +{ + GLenum filter; + GLenum format; + GLenum envmode; + GLint smask, tmask; + GLint twidth_log2; + const GLchan *texture; + GLchan er, eg, eb, ea; + GLint tbytesline, tsize; + GLint fixedToDepthShift; +}; + +static void +affine_span(GLcontext *ctx, struct triangle_span *span, + struct affine_info *info) +{ + GLint tr, tg, tb, ta; + + /* Instead of defining a function for each mode, a test is done + * between the outer and inner loops. This is to reduce code size + * and complexity. Observe that an optimizing compiler kills + * unused variables (for instance tf,sf,ti,si in case of GL_NEAREST). + */ + +#define NEAREST_RGB \ + tr = tex00[RCOMP]; \ + tg = tex00[GCOMP]; \ + tb = tex00[BCOMP]; \ + ta = 0xff + +#define LINEAR_RGB \ + tr = (ti * (si * tex00[0] + sf * tex01[0]) + \ + tf * (si * tex10[0] + sf * tex11[0])) >> 2 * FIXED_SHIFT; \ + tg = (ti * (si * tex00[1] + sf * tex01[1]) + \ + tf * (si * tex10[1] + sf * tex11[1])) >> 2 * FIXED_SHIFT; \ + tb = (ti * (si * tex00[2] + sf * tex01[2]) + \ + tf * (si * tex10[2] + sf * tex11[2])) >> 2 * FIXED_SHIFT; \ + ta = 0xff + +#define NEAREST_RGBA \ + tr = tex00[RCOMP]; \ + tg = tex00[GCOMP]; \ + tb = tex00[BCOMP]; \ + ta = tex00[ACOMP] + +#define LINEAR_RGBA \ + tr = (ti * (si * tex00[0] + sf * tex01[0]) + \ + tf * (si * tex10[0] + sf * tex11[0])) >> 2 * FIXED_SHIFT; \ + tg = (ti * (si * tex00[1] + sf * tex01[1]) + \ + tf * (si * tex10[1] + sf * tex11[1])) >> 2 * FIXED_SHIFT; \ + tb = (ti * (si * tex00[2] + sf * tex01[2]) + \ + tf * (si * tex10[2] + sf * tex11[2])) >> 2 * FIXED_SHIFT; \ + ta = (ti * (si * tex00[3] + sf * tex01[3]) + \ + tf * (si * tex10[3] + sf * tex11[3])) >> 2 * FIXED_SHIFT + +#define MODULATE \ + dest[RCOMP] = span->red * (tr + 1) >> (FIXED_SHIFT + 8); \ + dest[GCOMP] = span->green * (tg + 1) >> (FIXED_SHIFT + 8); \ + dest[BCOMP] = span->blue * (tb + 1) >> (FIXED_SHIFT + 8); \ + dest[ACOMP] = span->alpha * (ta + 1) >> (FIXED_SHIFT + 8) + +#define DECAL \ + dest[RCOMP] = ((0xff - ta) * span->red \ + + ((ta + 1) * tr << FIXED_SHIFT)) >> (FIXED_SHIFT + 8); \ + dest[GCOMP] = ((0xff - ta) * span->green \ + + ((ta + 1) * tg << FIXED_SHIFT)) >> (FIXED_SHIFT + 8); \ + dest[BCOMP] = ((0xff - ta) * span->blue \ + + ((ta + 1) * tb << FIXED_SHIFT)) >> (FIXED_SHIFT + 8); \ + dest[ACOMP] = FixedToInt(span->alpha) + +#define BLEND \ + dest[RCOMP] = ((0xff - tr) * span->red \ + + (tr + 1) * info->er) >> (FIXED_SHIFT + 8); \ + dest[GCOMP] = ((0xff - tg) * span->green \ + + (tg + 1) * info->eg) >> (FIXED_SHIFT + 8); \ + dest[BCOMP] = ((0xff - tb) * span->blue \ + + (tb + 1) * info->eb) >> (FIXED_SHIFT + 8); \ + dest[ACOMP] = span->alpha * (ta + 1) >> (FIXED_SHIFT + 8) + +#define REPLACE \ + dest[RCOMP] = tr; \ + dest[GCOMP] = tg; \ + dest[BCOMP] = tb; \ + dest[ACOMP] = ta + +#define ADD \ + dest[RCOMP] = ((span->red << 8) \ + + (tr + 1) * info->er) >> (FIXED_SHIFT + 8); \ + dest[GCOMP] = ((span->green << 8) \ + + (tg + 1) * info->eg) >> (FIXED_SHIFT + 8); \ + dest[BCOMP] = ((span->blue << 8) \ + + (tb + 1) * info->eb) >> (FIXED_SHIFT + 8); \ + dest[ACOMP] = span->alpha * (ta + 1) >> (FIXED_SHIFT + 8) + +/* shortcuts */ + +#define NEAREST_RGB_REPLACE NEAREST_RGB;REPLACE + +#define NEAREST_RGBA_REPLACE *(GLint *)dest = *(GLint *)tex00 + +#define SPAN1(DO_TEX,COMP) \ + for (i = 0; i < span->count; i++) { \ + GLint s = FixedToInt(span->intTex[0]) & info->smask; \ + GLint t = FixedToInt(span->intTex[1]) & info->tmask; \ + GLint pos = (t << info->twidth_log2) + s; \ + const GLchan *tex00 = info->texture + COMP * pos; \ + zspan[i] = FixedToDepth(span->z); \ + fogspan[i] = span->fog; \ + DO_TEX; \ + span->fog += span->fogStep; \ + span->z += span->zStep; \ + span->red += span->redStep; \ + span->green += span->greenStep; \ + span->blue += span->blueStep; \ + span->alpha += span->alphaStep; \ + span->intTex[0] += span->intTexStep[0]; \ + span->intTex[1] += span->intTexStep[1]; \ + dest += 4; \ + } + +#define SPAN2(DO_TEX,COMP) \ + for (i = 0; i < span->count; i++) { \ + GLint s = FixedToInt(span->intTex[0]) & info->smask; \ + GLint t = FixedToInt(span->intTex[1]) & info->tmask; \ + GLint sf = span->intTex[0] & FIXED_FRAC_MASK; \ + GLint tf = span->intTex[1] & FIXED_FRAC_MASK; \ + GLint si = FIXED_FRAC_MASK - sf; \ + GLint ti = FIXED_FRAC_MASK - tf; \ + GLint pos = (t << info->twidth_log2) + s; \ + const GLchan *tex00 = info->texture + COMP * pos; \ + const GLchan *tex10 = tex00 + info->tbytesline; \ + const GLchan *tex01 = tex00 + COMP; \ + const GLchan *tex11 = tex10 + COMP; \ + (void) ti; \ + (void) si; \ + if (t == info->tmask) { \ + tex10 -= info->tsize; \ + tex11 -= info->tsize; \ + } \ + if (s == info->smask) { \ + tex01 -= info->tbytesline; \ + tex11 -= info->tbytesline; \ + } \ + zspan[i] = FixedToDepth(span->z); \ + fogspan[i] = span->fog; \ + DO_TEX; \ + span->fog += span->fogStep; \ + span->z += span->zStep; \ + span->red += span->redStep; \ + span->green += span->greenStep; \ + span->blue += span->blueStep; \ + span->alpha += span->alphaStep; \ + span->intTex[0] += span->intTexStep[0]; \ + span->intTex[1] += span->intTexStep[1]; \ + dest += 4; \ + } + +#define FixedToDepth(F) ((F) >> fixedToDepthShift) + + GLuint i; + GLdepth zspan[MAX_WIDTH]; + GLfloat fogspan[MAX_WIDTH]; + GLchan rgba[MAX_WIDTH][4]; + GLchan *dest = rgba[0]; + const GLint fixedToDepthShift = info->fixedToDepthShift; + + span->intTex[0] -= FIXED_HALF; + span->intTex[1] -= FIXED_HALF; + switch (info->filter) { + case GL_NEAREST: + switch (info->format) { + case GL_RGB: + switch (info->envmode) { + case GL_MODULATE: + SPAN1(NEAREST_RGB;MODULATE,3); + break; + case GL_DECAL: + case GL_REPLACE: + SPAN1(NEAREST_RGB_REPLACE,3); + break; + case GL_BLEND: + SPAN1(NEAREST_RGB;BLEND,3); + break; + case GL_ADD: + SPAN1(NEAREST_RGB;ADD,3); + break; + default: + abort(); + } + break; + case GL_RGBA: + switch(info->envmode) { + case GL_MODULATE: + SPAN1(NEAREST_RGBA;MODULATE,4); + break; + case GL_DECAL: + SPAN1(NEAREST_RGBA;DECAL,4); + break; + case GL_BLEND: + SPAN1(NEAREST_RGBA;BLEND,4); + break; + case GL_ADD: + SPAN1(NEAREST_RGBA;ADD,4); + break; + case GL_REPLACE: + SPAN1(NEAREST_RGBA_REPLACE,4); + break; + default: + abort(); + } + break; + } + break; + + case GL_LINEAR: + span->intTex[0] -= FIXED_HALF; + span->intTex[1] -= FIXED_HALF; + switch (info->format) { + case GL_RGB: + switch (info->envmode) { + case GL_MODULATE: + SPAN2(LINEAR_RGB;MODULATE,3); + break; + case GL_DECAL: + case GL_REPLACE: + SPAN2(LINEAR_RGB;REPLACE,3); + break; + case GL_BLEND: + SPAN2(LINEAR_RGB;BLEND,3); + break; + case GL_ADD: + SPAN2(LINEAR_RGB;ADD,3); + break; + default: + abort(); + } + break; + case GL_RGBA: + switch (info->envmode) { + case GL_MODULATE: + SPAN2(LINEAR_RGBA;MODULATE,4); + break; + case GL_DECAL: + SPAN2(LINEAR_RGBA;DECAL,4); + break; + case GL_BLEND: + SPAN2(LINEAR_RGBA;BLEND,4); + break; + case GL_ADD: + SPAN2(LINEAR_RGBA;ADD,4); + break; + case GL_REPLACE: + SPAN2(LINEAR_RGBA;REPLACE,4); + break; + default: + abort(); + } break; + } + break; + } + _mesa_write_rgba_span(ctx, span->count, span->x, span->y, + zspan, fogspan, rgba, NULL, GL_POLYGON); + +#undef SPAN1 +#undef SPAN2 +#undef FixedToDepth +} + + + +/* + * Render an RGB/RGBA textured triangle without perspective correction. + */ +static void affine_textured_triangle( GLcontext *ctx, + const SWvertex *v0, + const SWvertex *v1, + const SWvertex *v2 ) +{ +#define INTERP_Z 1 +#define INTERP_FOG 1 +#define DEPTH_TYPE DEFAULT_SOFTWARE_DEPTH_TYPE +#define INTERP_RGB 1 +#define INTERP_ALPHA 1 +#define INTERP_INT_TEX 1 +#define S_SCALE twidth +#define T_SCALE theight + +#define SETUP_CODE + struct affine_info info; + struct gl_texture_unit *unit = ctx->Texture.Unit+0; \ + struct gl_texture_object *obj = unit->Current2D; \ + GLint b = obj->BaseLevel; \ + GLfloat twidth = (GLfloat) obj->Image[b]->Width; \ + GLfloat theight = (GLfloat) obj->Image[b]->Height; \ + info.fixedToDepthShift = ctx->Visual.depthBits <= 16 ? FIXED_SHIFT : 0;\ + info.texture = (const GLchan *) obj->Image[b]->Data; \ + info.twidth_log2 = obj->Image[b]->WidthLog2; \ + info.smask = obj->Image[b]->Width - 1; \ + info.tmask = obj->Image[b]->Height - 1; \ + info.format = obj->Image[b]->Format; \ + info.filter = obj->MinFilter; \ + info.envmode = unit->EnvMode; \ + \ + if (info.envmode == GL_BLEND) { \ + /* potential off-by-one error here? (1.0f -> 2048 -> 0) */ \ + info.er = FloatToFixed(unit->EnvColor[RCOMP]); \ + info.eg = FloatToFixed(unit->EnvColor[GCOMP]); \ + info.eb = FloatToFixed(unit->EnvColor[BCOMP]); \ + info.ea = FloatToFixed(unit->EnvColor[ACOMP]); \ + } \ + if (!info.texture) { \ + /* this shouldn't happen */ \ + return; \ + } \ + \ + switch (info.format) { \ + case GL_ALPHA: \ + case GL_LUMINANCE: \ + case GL_INTENSITY: \ + info.tbytesline = obj->Image[b]->Width; \ + break; \ + case GL_LUMINANCE_ALPHA: \ + info.tbytesline = obj->Image[b]->Width * 2; \ + break; \ + case GL_RGB: \ + info.tbytesline = obj->Image[b]->Width * 3; \ + break; \ + case GL_RGBA: \ + info.tbytesline = obj->Image[b]->Width * 4; \ + break; \ + default: \ + _mesa_problem(NULL, "Bad texture format in affine_texture_triangle");\ + return; \ + } \ + info.tsize = obj->Image[b]->Height * info.tbytesline; + +#define RENDER_SPAN( span ) \ + affine_span(ctx, &span, &info); + +#include "s_tritemp.h" + +} + + +#if 0 /* XXX disabled because of texcoord interpolation errors */ +/* + * Render an perspective corrected RGB/RGBA textured triangle. + * The Q (aka V in Mesa) coordinate must be zero such that the divide + * by interpolated Q/W comes out right. + * + * This function only renders textured triangles that use GL_NEAREST. + * Perspective correction works right. + * + * This function written by Klaus Niederkrueger + * Send all questions and bug reports to him. + */ +static void near_persp_textured_triangle(GLcontext *ctx, + const SWvertex *v0, + const SWvertex *v1, + const SWvertex *v2 ) +{ +/* The BIAS value is used to shift negative values into positive values. + * Without this, negative texture values don't GL_REPEAT correctly at just + * below zero, because (int)-0.5 = 0 = (int)0.5. We're not going to worry + * about texture coords less than -BIAS. This could be fixed by using + * FLOORF etc. instead, but this is slower... + */ +#define BIAS 4096.0F + +#define INTERP_Z 1 +#define INTERP_FOG 1 +#define DEPTH_TYPE DEFAULT_SOFTWARE_DEPTH_TYPE +#define INTERP_RGB 1 +#define INTERP_ALPHA 1 +#define INTERP_TEX 1 + +#define SETUP_CODE \ + struct gl_texture_unit *unit = ctx->Texture.Unit+0; \ + struct gl_texture_object *obj = unit->Current2D; \ + const GLint b = obj->BaseLevel; \ + const GLfloat twidth = (GLfloat) obj->Image[b]->Width; \ + const GLfloat theight = (GLfloat) obj->Image[b]->Height; \ + const GLint twidth_log2 = obj->Image[b]->WidthLog2; \ + const GLchan *texture = (const GLchan *) obj->Image[b]->Data; \ + const GLint smask = (obj->Image[b]->Width - 1); \ + const GLint tmask = (obj->Image[b]->Height - 1); \ + const GLint format = obj->Image[b]->Format; \ + const GLint envmode = unit->EnvMode; \ + GLfloat sscale, tscale; \ + GLfixed er, eg, eb, ea; \ + GLint tr, tg, tb, ta; \ + if (!texture) { \ + /* this shouldn't happen */ \ + return; \ + } \ + if (envmode == GL_BLEND || envmode == GL_ADD) { \ + er = FloatToFixed(unit->EnvColor[RCOMP]); \ + eg = FloatToFixed(unit->EnvColor[GCOMP]); \ + eb = FloatToFixed(unit->EnvColor[BCOMP]); \ + ea = FloatToFixed(unit->EnvColor[ACOMP]); \ + } \ + sscale = twidth; \ + tscale = theight; \ + + +#define OLD_SPAN(DO_TEX,COMP) \ + for (i=0;in || j<-100000) \ + j = n; \ + while (i 0) { \ + GLchan *dest = rgba[0]; \ + GLfloat SS = ss * sscale; \ + GLfloat TT = tt * tscale; \ + GLfloat dSdx = dsdx * sscale; \ + GLfloat dTdx = dtdx * tscale; \ + GLfloat x_tex; \ + GLfloat y_tex; \ + GLfloat dx_tex; \ + GLfloat dy_tex; \ + if (n<5) /* When line very short, setup-time > speed-gain. */ \ + goto old_span; /* So: take old method */ \ + x_tex = SS / vv, \ + y_tex = TT / vv; \ + dx_tex = (SS + n * dSdx) / (vv + n * dvdx) - x_tex, \ + dy_tex = (TT + n * dTdx) / (vv + n * dvdx) - y_tex; \ + /* Choose between walking over texture or over pixelline: */ \ + /* If there are few texels, walk over texture otherwise */ \ + /* walk over pixelarray. The quotient on the right side */ \ + /* should give the timeratio needed to draw one texel in */ \ + /* comparison to one pixel. Depends on CPU. */ \ + if (dx_tex*dx_tex + dy_tex*dy_tex < (n*n)/16) { \ + x_tex += BIAS; \ + y_tex += BIAS; \ + if (dx_tex*dx_tex > dy_tex*dy_tex) { \ + /* if (FABSF(dx_tex) > FABSF(dy_tex)) */ \ + GLfloat nominator = - SS - vv * BIAS; \ + GLfloat denominator = dvdx * BIAS + dSdx; \ + GLfloat dy_dx; \ + GLfloat dx_dy; \ + if (dy_tex != 0.0f) { \ + dy_dx = dy_tex / dx_tex; \ + dx_dy = 1.0f/dy_dx; \ + } \ + else \ + dy_dx = 0.0f; \ + if (dx_tex > 0.0f) { \ + if (dy_tex > 0.0f) { \ + switch (format) { \ + case GL_RGB: \ + switch (envmode) { \ + case GL_MODULATE: \ + SPAN1(NEAREST_RGB;MODULATE,3, Y_X_TEX_COORD);\ + break; \ + case GL_DECAL: \ + case GL_REPLACE: \ + SPAN1(NEAREST_RGB_REPLACE,3, Y_X_TEX_COORD); \ + break; \ + case GL_BLEND: \ + SPAN1(NEAREST_RGB;BLEND,3, Y_X_TEX_COORD); \ + break; \ + case GL_ADD: \ + SPAN1(NEAREST_RGB;ADD,3, Y_X_TEX_COORD); \ + break; \ + default: /* unexpected env mode */ \ + abort(); \ + } \ + break; \ + case GL_RGBA: \ + switch(envmode) { \ + case GL_MODULATE: \ + SPAN1(NEAREST_RGBA;MODULATE,4, Y_X_TEX_COORD);\ + break; \ + case GL_DECAL: \ + SPAN1(NEAREST_RGBA;DECAL,4, Y_X_TEX_COORD); \ + break; \ + case GL_BLEND: \ + SPAN1(NEAREST_RGBA;BLEND,4, Y_X_TEX_COORD); \ + break; \ + case GL_ADD: \ + SPAN1(NEAREST_RGBA;ADD,4, Y_X_TEX_COORD); \ + break; \ + case GL_REPLACE: \ + SPAN1(NEAREST_RGBA_REPLACE,4, Y_X_TEX_COORD);\ + break; \ + default: /* unexpected env mode */ \ + abort(); \ + } \ + break; \ + } \ + } \ + else { /* dy_tex <= 0.0f */ \ + switch (format) { \ + case GL_RGB: \ + switch (envmode) { \ + case GL_MODULATE: \ + SPAN2(NEAREST_RGB;MODULATE,3, Y_X_TEX_COORD);\ + break; \ + case GL_DECAL: \ + case GL_REPLACE: \ + SPAN2(NEAREST_RGB_REPLACE,3, Y_X_TEX_COORD); \ + break; \ + case GL_BLEND: \ + SPAN2(NEAREST_RGB;BLEND,3, Y_X_TEX_COORD); \ + break; \ + case GL_ADD: \ + SPAN2(NEAREST_RGB;ADD,3, Y_X_TEX_COORD); \ + break; \ + default: /* unexpected env mode */ \ + abort(); \ + } \ + break; \ + case GL_RGBA: \ + switch(envmode) { \ + case GL_MODULATE: \ + SPAN2(NEAREST_RGBA;MODULATE,4, Y_X_TEX_COORD);\ + break; \ + case GL_DECAL: \ + SPAN2(NEAREST_RGBA;DECAL,4, Y_X_TEX_COORD); \ + break; \ + case GL_BLEND: \ + SPAN2(NEAREST_RGBA;BLEND,4, Y_X_TEX_COORD); \ + break; \ + case GL_ADD: \ + SPAN2(NEAREST_RGBA;ADD,4, Y_X_TEX_COORD); \ + break; \ + case GL_REPLACE: \ + SPAN2(NEAREST_RGBA_REPLACE,4, Y_X_TEX_COORD);\ + break; \ + default: /* unexpected env mode */ \ + abort(); \ + } \ + break; \ + } \ + } \ + } \ + else { /* dx_tex < 0.0f */ \ + if (dy_tex > 0.0f) { \ + switch (format) { \ + case GL_RGB: \ + switch (envmode) { \ + case GL_MODULATE: \ + SPAN3(NEAREST_RGB;MODULATE,3, Y_X_TEX_COORD);\ + break; \ + case GL_DECAL: \ + case GL_REPLACE: \ + SPAN3(NEAREST_RGB_REPLACE,3, Y_X_TEX_COORD); \ + break; \ + case GL_BLEND: \ + SPAN3(NEAREST_RGB;BLEND,3, Y_X_TEX_COORD); \ + break; \ + case GL_ADD: \ + SPAN3(NEAREST_RGB;ADD,3, Y_X_TEX_COORD); \ + break; \ + default: /* unexpected env mode */ \ + abort(); \ + } \ + break; \ + case GL_RGBA: \ + switch(envmode) { \ + case GL_MODULATE: \ + SPAN3(NEAREST_RGBA;MODULATE,4, Y_X_TEX_COORD);\ + break; \ + case GL_DECAL: \ + SPAN3(NEAREST_RGBA;DECAL,4, Y_X_TEX_COORD); \ + break; \ + case GL_BLEND: \ + SPAN3(NEAREST_RGBA;BLEND,4, Y_X_TEX_COORD); \ + break; \ + case GL_ADD: \ + SPAN3(NEAREST_RGBA;ADD,4, Y_X_TEX_COORD); \ + break; \ + case GL_REPLACE: \ + SPAN3(NEAREST_RGBA_REPLACE,4, Y_X_TEX_COORD);\ + break; \ + default: /* unexpected env mode */ \ + abort(); \ + } \ + break; \ + } \ + } \ + else { /* dy_tex <= 0.0f */ \ + switch (format) { \ + case GL_RGB: \ + switch (envmode) { \ + case GL_MODULATE: \ + SPAN4(NEAREST_RGB;MODULATE,3, Y_X_TEX_COORD);\ + break; \ + case GL_DECAL: \ + case GL_REPLACE: \ + SPAN4(NEAREST_RGB_REPLACE,3, Y_X_TEX_COORD); \ + break; \ + case GL_BLEND: \ + SPAN4(NEAREST_RGB;BLEND,3, Y_X_TEX_COORD); \ + break; \ + case GL_ADD: \ + SPAN4(NEAREST_RGB;ADD,3, Y_X_TEX_COORD); \ + break; \ + default: \ + abort(); \ + } \ + break; \ + case GL_RGBA: \ + switch(envmode) { \ + case GL_MODULATE: \ + SPAN4(NEAREST_RGBA;MODULATE,4, Y_X_TEX_COORD);\ + break; \ + case GL_DECAL: \ + SPAN4(NEAREST_RGBA;DECAL,4, Y_X_TEX_COORD); \ + break; \ + case GL_BLEND: \ + SPAN4(NEAREST_RGBA;BLEND,4, Y_X_TEX_COORD); \ + break; \ + case GL_ADD: \ + SPAN4(NEAREST_RGBA;ADD,4, Y_X_TEX_COORD); \ + break; \ + case GL_REPLACE: \ + SPAN4(NEAREST_RGBA_REPLACE,4, Y_X_TEX_COORD);\ + break; \ + default: /* unexpected env mode */ \ + abort(); \ + } \ + break; \ + } \ + } \ + } \ + } \ + else { /* FABSF(dx_tex) > FABSF(dy_tex) */ \ + GLfloat swap; \ + GLfloat dy_dx; \ + GLfloat dx_dy; \ + GLfloat nominator, denominator; \ + if (dx_tex == 0.0f /* && dy_tex == 0.0f*/) \ + goto old_span; /* case so special, that use old */ \ + /* swap some x-values and y-values */ \ + SS = TT; \ + dSdx = dTdx; \ + swap = x_tex, x_tex = y_tex, y_tex = swap; \ + swap = dx_tex, dx_tex = dy_tex, dy_tex = swap; \ + nominator = - SS - vv * BIAS; \ + denominator = dvdx * BIAS + dSdx; \ + if (dy_tex != 0.0f) { \ + dy_dx = dy_tex / dx_tex; \ + dx_dy = 1.0f/dy_dx; \ + } \ + else \ + dy_dx = 0.0f; \ + if (dx_tex > 0.0f) { \ + if (dy_tex > 0.0f) { \ + switch (format) { \ + case GL_RGB: \ + switch (envmode) { \ + case GL_MODULATE: \ + SPAN1(NEAREST_RGB;MODULATE,3, X_Y_TEX_COORD);\ + break; \ + case GL_DECAL: \ + case GL_REPLACE: \ + SPAN1(NEAREST_RGB_REPLACE,3, X_Y_TEX_COORD); \ + break; \ + case GL_BLEND: \ + SPAN1(NEAREST_RGB;BLEND,3, X_Y_TEX_COORD); \ + break; \ + case GL_ADD: \ + SPAN1(NEAREST_RGB;ADD,3, X_Y_TEX_COORD); \ + break; \ + default: /* unexpected env mode */ \ + abort(); \ + } \ + break; \ + case GL_RGBA: \ + switch(envmode) { \ + case GL_MODULATE: \ + SPAN1(NEAREST_RGBA;MODULATE,4, X_Y_TEX_COORD);\ + break; \ + case GL_DECAL: \ + SPAN1(NEAREST_RGBA;DECAL,4, X_Y_TEX_COORD); \ + break; \ + case GL_BLEND: \ + SPAN1(NEAREST_RGBA;BLEND,4, X_Y_TEX_COORD); \ + break; \ + case GL_ADD: \ + SPAN1(NEAREST_RGBA;ADD,4, X_Y_TEX_COORD); \ + break; \ + case GL_REPLACE: \ + SPAN1(NEAREST_RGBA_REPLACE,4, X_Y_TEX_COORD);\ + break; \ + default: \ + abort(); \ + } \ + break; \ + } \ + } \ + else { /* dy_tex <= 0.0f */ \ + switch (format) { \ + case GL_RGB: \ + switch (envmode) { \ + case GL_MODULATE: \ + SPAN2(NEAREST_RGB;MODULATE,3, X_Y_TEX_COORD);\ + break; \ + case GL_DECAL: \ + case GL_REPLACE: \ + SPAN2(NEAREST_RGB_REPLACE,3, X_Y_TEX_COORD); \ + break; \ + case GL_BLEND: \ + SPAN2(NEAREST_RGB;BLEND,3, X_Y_TEX_COORD); \ + break; \ + case GL_ADD: \ + SPAN2(NEAREST_RGB;ADD,3, X_Y_TEX_COORD); \ + break; \ + default: \ + abort(); \ + } \ + break; \ + case GL_RGBA: \ + switch(envmode) { \ + case GL_MODULATE: \ + SPAN2(NEAREST_RGBA;MODULATE,4, X_Y_TEX_COORD);\ + break; \ + case GL_DECAL: \ + SPAN2(NEAREST_RGBA;DECAL,4, X_Y_TEX_COORD); \ + break; \ + case GL_BLEND: \ + SPAN2(NEAREST_RGBA;BLEND,4, X_Y_TEX_COORD); \ + break; \ + case GL_ADD: \ + SPAN2(NEAREST_RGBA;ADD,4, X_Y_TEX_COORD); \ + break; \ + case GL_REPLACE: \ + SPAN2(NEAREST_RGBA_REPLACE,4, X_Y_TEX_COORD);\ + break; \ + default: \ + abort(); \ + } \ + break; \ + } \ + } \ + } \ + else { /* dx_tex < 0.0f */ \ + if (dy_tex > 0.0f) { \ + switch (format) { \ + case GL_RGB: \ + switch (envmode) { \ + case GL_MODULATE: \ + SPAN3(NEAREST_RGB;MODULATE,3, X_Y_TEX_COORD);\ + break; \ + case GL_DECAL: \ + case GL_REPLACE: \ + SPAN3(NEAREST_RGB_REPLACE,3, X_Y_TEX_COORD); \ + break; \ + case GL_BLEND: \ + SPAN3(NEAREST_RGB;BLEND,3, X_Y_TEX_COORD); \ + break; \ + case GL_ADD: \ + SPAN3(NEAREST_RGB;ADD,3, X_Y_TEX_COORD); \ + break; \ + default: \ + abort(); \ + } \ + break; \ + case GL_RGBA: \ + switch(envmode) { \ + case GL_MODULATE: \ + SPAN3(NEAREST_RGBA;MODULATE,4, X_Y_TEX_COORD);\ + break; \ + case GL_DECAL: \ + SPAN3(NEAREST_RGBA;DECAL,4, X_Y_TEX_COORD); \ + break; \ + case GL_BLEND: \ + SPAN3(NEAREST_RGBA;BLEND,4, X_Y_TEX_COORD); \ + break; \ + case GL_ADD: \ + SPAN3(NEAREST_RGBA;ADD,4, X_Y_TEX_COORD); \ + break; \ + case GL_REPLACE: \ + SPAN3(NEAREST_RGBA_REPLACE,4, X_Y_TEX_COORD);\ + break; \ + default: \ + abort(); \ + } \ + break; \ + } \ + } \ + else { /* dy_tex <= 0.0f */ \ + switch (format) { \ + case GL_RGB: \ + switch (envmode) { \ + case GL_MODULATE: \ + SPAN4(NEAREST_RGB;MODULATE,3, X_Y_TEX_COORD);\ + break; \ + case GL_DECAL: \ + case GL_REPLACE: \ + SPAN4(NEAREST_RGB_REPLACE,3, X_Y_TEX_COORD); \ + break; \ + case GL_BLEND: \ + SPAN4(NEAREST_RGB;BLEND,3, X_Y_TEX_COORD); \ + break; \ + case GL_ADD: \ + SPAN4(NEAREST_RGB;ADD,3, X_Y_TEX_COORD); \ + break; \ + default: \ + abort(); \ + } \ + break; \ + case GL_RGBA: \ + switch(envmode) { \ + case GL_MODULATE: \ + SPAN4(NEAREST_RGBA;MODULATE,4, X_Y_TEX_COORD);\ + break; \ + case GL_DECAL: \ + SPAN4(NEAREST_RGBA;DECAL,4, X_Y_TEX_COORD); \ + break; \ + case GL_BLEND: \ + SPAN4(NEAREST_RGBA;BLEND,4, X_Y_TEX_COORD); \ + break; \ + case GL_ADD: \ + SPAN4(NEAREST_RGBA;ADD,4, X_Y_TEX_COORD); \ + break; \ + case GL_REPLACE: \ + SPAN4(NEAREST_RGBA_REPLACE,4, X_Y_TEX_COORD);\ + break; \ + default: \ + abort(); \ + } \ + break; \ + } \ + } \ + } \ + } \ + } \ + else { \ + old_span: \ + switch (format) { \ + case GL_RGB: \ + switch (envmode) { \ + case GL_MODULATE: \ + OLD_SPAN(NEAREST_RGB;MODULATE,3); \ + break; \ + case GL_DECAL: \ + case GL_REPLACE: \ + OLD_SPAN(NEAREST_RGB_REPLACE,3); \ + break; \ + case GL_BLEND: \ + OLD_SPAN(NEAREST_RGB;BLEND,3); \ + break; \ + case GL_ADD: \ + OLD_SPAN(NEAREST_RGB;ADD,3); \ + break; \ + default: \ + abort(); \ + } \ + break; \ + case GL_RGBA: \ + switch(envmode) { \ + case GL_MODULATE: \ + OLD_SPAN(NEAREST_RGBA;MODULATE,4); \ + break; \ + case GL_DECAL: \ + OLD_SPAN(NEAREST_RGBA;DECAL,4); \ + break; \ + case GL_BLEND: \ + OLD_SPAN(NEAREST_RGBA;BLEND,4); \ + break; \ + case GL_ADD: \ + OLD_SPAN(NEAREST_RGBA;ADD,4); \ + break; \ + case GL_REPLACE: \ + OLD_SPAN(NEAREST_RGBA_REPLACE,4); \ + break; \ + default: \ + abort(); \ + } \ + break; \ + } \ + } \ + _mesa_write_rgba_span( ctx, n, LEFT, Y, zspan, \ + fogspan, rgba, NULL, GL_POLYGON); \ + span.red = span.green = span.blue = span.alpha = 0; \ + } \ + } \ + +#include "s_tritemp.h" +#undef OLD_SPAN +#undef SPAN1 +#undef SPAN2 +#undef SPAN3 +#undef SPAN4 +#undef X_Y_TEX_COORD +#undef Y_X_TEX_COORD +#undef DRAW_LINE +#undef BIAS +} +#endif + + +#if 0 /* XXX disabled because of texcoord interpolation errors */ +/* + * Render an perspective corrected RGB/RGBA textured triangle. + * The Q (aka V in Mesa) coordinate must be zero such that the divide + * by interpolated Q/W comes out right. + * + * This function written by Klaus Niederkrueger + * Send all questions and bug reports to him. + */ +static void lin_persp_textured_triangle( GLcontext *ctx, + const SWvertex *v0, + const SWvertex *v1, + const SWvertex *v2 ) +{ +#define INTERP_Z 1 +#define INTERP_FOG 1 +#define DEPTH_TYPE DEFAULT_SOFTWARE_DEPTH_TYPE +#define INTERP_RGB 1 +#define INTERP_ALPHA 1 +#define INTERP_TEX 1 + +#define SETUP_CODE \ + struct gl_texture_unit *unit = ctx->Texture.Unit+0; \ + struct gl_texture_object *obj = unit->Current2D; \ + const GLint b = obj->BaseLevel; \ + const GLfloat twidth = (GLfloat) obj->Image[b]->Width; \ + const GLfloat theight = (GLfloat) obj->Image[b]->Height; \ + const GLint twidth_log2 = obj->Image[b]->WidthLog2; \ + GLchan *texture = obj->Image[b]->Data; \ + const GLint smask = (obj->Image[b]->Width - 1); \ + const GLint tmask = (obj->Image[b]->Height - 1); \ + const GLint format = obj->Image[b]->Format; \ + const GLint envmode = unit->EnvMode; \ + GLfloat sscale, tscale; \ + GLint comp, tbytesline, tsize; \ + GLfixed er, eg, eb, ea; \ + GLint tr, tg, tb, ta; \ + if (!texture) { \ + return; \ + } \ + if (envmode == GL_BLEND || envmode == GL_ADD) { \ + er = FloatToFixed(unit->EnvColor[RCOMP]); \ + eg = FloatToFixed(unit->EnvColor[GCOMP]); \ + eb = FloatToFixed(unit->EnvColor[BCOMP]); \ + ea = FloatToFixed(unit->EnvColor[ACOMP]); \ + } \ + switch (format) { \ + case GL_ALPHA: \ + case GL_LUMINANCE: \ + case GL_INTENSITY: \ + comp = 1; \ + break; \ + case GL_LUMINANCE_ALPHA: \ + comp = 2; \ + break; \ + case GL_RGB: \ + comp = 3; \ + break; \ + case GL_RGBA: \ + comp = 4; \ + break; \ + default: \ + _mesa_problem(NULL, "Bad texture format in lin_persp_texture_triangle"); \ + return; \ + } \ + sscale = FIXED_SCALE * twidth; \ + tscale = FIXED_SCALE * theight; \ + tbytesline = obj->Image[b]->Width * comp; \ + tsize = theight * tbytesline; + + +#define SPAN(DO_TEX,COMP) \ + for (i=0;i 0) { \ + GLfloat SS = ss * sscale; \ + GLfloat TT = tt * tscale; \ + GLfloat dSdx = dsdx * sscale; \ + GLfloat dTdx = dtdx * tscale; \ + GLchan *dest = rgba[0]; \ + SS -= 0.5f * FIXED_SCALE * vv; \ + TT -= 0.5f * FIXED_SCALE * vv; \ + switch (format) { \ + case GL_RGB: \ + switch (envmode) { \ + case GL_MODULATE: \ + SPAN(LINEAR_RGB;MODULATE,3); \ + break; \ + case GL_DECAL: \ + case GL_REPLACE: \ + SPAN(LINEAR_RGB;REPLACE,3); \ + break; \ + case GL_BLEND: \ + SPAN(LINEAR_RGB;BLEND,3); \ + break; \ + case GL_ADD: \ + SPAN(LINEAR_RGB;ADD,3); \ + break; \ + default: \ + abort(); \ + } \ + break; \ + case GL_RGBA: \ + switch (envmode) { \ + case GL_MODULATE: \ + SPAN(LINEAR_RGBA;MODULATE,4); \ + break; \ + case GL_DECAL: \ + SPAN(LINEAR_RGBA;DECAL,4); \ + break; \ + case GL_BLEND: \ + SPAN(LINEAR_RGBA;BLEND,4); \ + break; \ + case GL_REPLACE: \ + SPAN(LINEAR_RGBA;REPLACE,4); \ + break; \ + case GL_ADD: \ + SPAN(LINEAR_RGBA;ADD,4); \ + break; \ + default: /* unexpected env mode */ \ + abort(); \ + } \ + } \ + _mesa_write_rgba_span(ctx, n, LEFT, Y, zspan, \ + fogspan, rgba, NULL, \ + GL_POLYGON); \ + } \ + } + +#include "s_tritemp.h" +#undef SPAN +} +#endif + + +/* + * Generate arrays of fragment colors, z, fog, texcoords, etc from a + * triangle span object. Then call the span/fragment processsing + * functions in s_span.[ch]. + */ +static void +rasterize_span(GLcontext *ctx, const struct triangle_span *span) +{ + DEFMARRAY(GLchan, rgba, MAX_WIDTH, 4); + DEFMARRAY(GLchan, spec, MAX_WIDTH, 4); + DEFARRAY(GLuint, index, MAX_WIDTH); + DEFARRAY(GLuint, z, MAX_WIDTH); + DEFARRAY(GLfloat, fog, MAX_WIDTH); + DEFARRAY(GLfloat, sTex, MAX_WIDTH); + DEFARRAY(GLfloat, tTex, MAX_WIDTH); + DEFARRAY(GLfloat, rTex, MAX_WIDTH); + DEFARRAY(GLfloat, lambda, MAX_WIDTH); + DEFMARRAY(GLfloat, msTex, MAX_TEXTURE_UNITS, MAX_WIDTH); + DEFMARRAY(GLfloat, mtTex, MAX_TEXTURE_UNITS, MAX_WIDTH); + DEFMARRAY(GLfloat, mrTex, MAX_TEXTURE_UNITS, MAX_WIDTH); + DEFMARRAY(GLfloat, mLambda, MAX_TEXTURE_UNITS, MAX_WIDTH); + + CHECKARRAY(rgba, return); + CHECKARRAY(spec, return); + CHECKARRAY(index, return); + CHECKARRAY(z, return); + CHECKARRAY(fog, return); + CHECKARRAY(sTex, return); + CHECKARRAY(tTex, return); + CHECKARRAY(rTex, return); + CHECKARRAY(lambda, return); + CHECKARRAY(msTex, return); + CHECKARRAY(mtTex, return); + CHECKARRAY(mrTex, return); + CHECKARRAY(mLambda, return); + + if (span->activeMask & SPAN_RGBA) { + GLfixed r = span->red; + GLfixed g = span->green; + GLfixed b = span->blue; + GLfixed a = span->alpha; + GLuint i; + for (i = 0; i < span->count; i++) { + rgba[i][RCOMP] = FixedToInt(r); + rgba[i][GCOMP] = FixedToInt(g); + rgba[i][BCOMP] = FixedToInt(b); + rgba[i][ACOMP] = FixedToInt(a); + r += span->redStep; + g += span->greenStep; + b += span->blueStep; + a += span->alphaStep; + } + } + if (span->activeMask & SPAN_SPEC) { + GLfixed r = span->specRed; + GLfixed g = span->specGreen; + GLfixed b = span->specBlue; + GLuint i; + for (i = 0; i < span->count; i++) { + spec[i][RCOMP] = FixedToInt(r); + spec[i][GCOMP] = FixedToInt(g); + spec[i][BCOMP] = FixedToInt(b); + r += span->specRedStep; + g += span->specGreenStep; + b += span->specBlueStep; + } + } + if (span->activeMask & SPAN_INDEX) { + GLuint i; + GLfixed ind = span->index; + for (i = 0; i < span->count; i++) { + index[i] = FixedToInt(ind); + ind += span->indexStep; + } + } + if (span->activeMask & SPAN_Z) { + if (ctx->Visual.depthBits <= 16) { + GLuint i; + GLfixed zval = span->z; + for (i = 0; i < span->count; i++) { + z[i] = FixedToInt(zval); + zval += span->zStep; + } + } + else { + /* Deep Z buffer, no fixed->int shift */ + GLuint i; + GLfixed zval = span->z; + for (i = 0; i < span->count; i++) { + z[i] = zval; + zval += span->zStep; + } + } + } + if (span->activeMask & SPAN_FOG) { + GLuint i; + GLfloat f = span->fog; + for (i = 0; i < span->count; i++) { + fog[i] = f; + f += span->fogStep; + } + } + if (span->activeMask & SPAN_TEXTURE) { + if (ctx->Texture._ReallyEnabled & ~TEXTURE0_ANY) { + /* multitexture */ + if (span->activeMask & SPAN_LAMBDA) { + /* with lambda */ + GLuint u; + for (u = 0; u < MAX_TEXTURE_UNITS; u++) { + if (ctx->Texture.Unit[u]._ReallyEnabled) { + GLfloat s = span->tex[u][0]; + GLfloat t = span->tex[u][1]; + GLfloat r = span->tex[u][2]; + GLfloat q = span->tex[u][3]; + GLuint i; + for (i = 0; i < span->count; i++) { + const GLfloat invQ = (q == 0.0F) ? 1.0 : (1.0F / q); + msTex[u][i] = s * invQ; + mtTex[u][i] = t * invQ; + mrTex[u][i] = r * invQ; + mLambda[u][i] = log(span->rho[u] * invQ * invQ) * 1.442695F * 0.5F; + s += span->texStep[u][0]; + t += span->texStep[u][1]; + r += span->texStep[u][2]; + q += span->texStep[u][3]; + } + } + } + } + else { + /* without lambda */ + GLuint u; + for (u = 0; u < MAX_TEXTURE_UNITS; u++) { + if (ctx->Texture.Unit[u]._ReallyEnabled) { + GLfloat s = span->tex[u][0]; + GLfloat t = span->tex[u][1]; + GLfloat r = span->tex[u][2]; + GLfloat q = span->tex[u][3]; + GLuint i; + for (i = 0; i < span->count; i++) { + const GLfloat invQ = (q == 0.0F) ? 1.0 : (1.0F / q); + msTex[u][i] = s * invQ; + mtTex[u][i] = t * invQ; + mrTex[u][i] = r * invQ; + s += span->texStep[u][0]; + t += span->texStep[u][1]; + r += span->texStep[u][2]; + q += span->texStep[u][3]; + } + } + } + } + } + else { + /* just texture unit 0 */ + if (span->activeMask & SPAN_LAMBDA) { + /* with lambda */ + GLfloat s = span->tex[0][0]; + GLfloat t = span->tex[0][1]; + GLfloat r = span->tex[0][2]; + GLfloat q = span->tex[0][3]; + GLuint i; + for (i = 0; i < span->count; i++) { + const GLfloat invQ = (q == 0.0F) ? 1.0 : (1.0F / q); + sTex[i] = s * invQ; + tTex[i] = t * invQ; + rTex[i] = r * invQ; + lambda[i] = log(span->rho[0] * invQ * invQ) * 1.442695F * 0.5F; + s += span->texStep[0][0]; + t += span->texStep[0][1]; + r += span->texStep[0][2]; + q += span->texStep[0][3]; + } + } + else { + /* without lambda */ + GLfloat s = span->tex[0][0]; + GLfloat t = span->tex[0][1]; + GLfloat r = span->tex[0][2]; + GLfloat q = span->tex[0][3]; + GLuint i; + for (i = 0; i < span->count; i++) { + const GLfloat invQ = (q == 0.0F) ? 1.0 : (1.0F / q); + sTex[i] = s * invQ; + tTex[i] = t * invQ; + rTex[i] = r * invQ; + s += span->texStep[0][0]; + t += span->texStep[0][1]; + r += span->texStep[0][2]; + q += span->texStep[0][3]; + } + } + } + } + /* XXX keep this? */ + if (span->activeMask & SPAN_INT_TEXTURE) { + GLint intTexcoord[MAX_WIDTH][2]; + GLfixed s = span->intTex[0]; + GLfixed t = span->intTex[1]; + GLuint i; + for (i = 0; i < span->count; i++) { + intTexcoord[i][0] = FixedToInt(s); + intTexcoord[i][1] = FixedToInt(t); + s += span->intTexStep[0]; + t += span->intTexStep[1]; + } + } + + /* examine activeMask and call a s_span.c function */ + if (span->activeMask & SPAN_TEXTURE) { + const GLfloat *fogPtr; + if (span->activeMask & SPAN_FOG) + fogPtr = fog; + else + fogPtr = NULL; + + if (ctx->Texture._ReallyEnabled & ~TEXTURE0_ANY) { + if (span->activeMask & SPAN_SPEC) { + _mesa_write_multitexture_span(ctx, span->count, span->x, span->y, + z, fogPtr, + (const GLfloat (*)[MAX_WIDTH]) msTex, + (const GLfloat (*)[MAX_WIDTH]) mtTex, + (const GLfloat (*)[MAX_WIDTH]) mrTex, + (GLfloat (*)[MAX_WIDTH]) mLambda, + rgba, (CONST GLchan (*)[4]) spec, + NULL, GL_POLYGON ); + } + else { + _mesa_write_multitexture_span(ctx, span->count, span->x, span->y, + z, fogPtr, + (const GLfloat (*)[MAX_WIDTH]) msTex, + (const GLfloat (*)[MAX_WIDTH]) mtTex, + (const GLfloat (*)[MAX_WIDTH]) mrTex, + (GLfloat (*)[MAX_WIDTH]) mLambda, + rgba, NULL, NULL, GL_POLYGON); + } + } + else { + /* single texture */ + if (span->activeMask & SPAN_SPEC) { + _mesa_write_texture_span(ctx, span->count, span->x, span->y, + z, fogPtr, sTex, tTex, rTex, lambda, + rgba, (CONST GLchan (*)[4]) spec, + NULL, GL_POLYGON); + } + else { + _mesa_write_texture_span(ctx, span->count, span->x, span->y, + z, fogPtr, sTex, tTex, rTex, lambda, + rgba, NULL, NULL, GL_POLYGON); + } + } + } + else { + _mesa_problem(ctx, "rasterize_span() should only be used for texturing"); + } + + UNDEFARRAY(rgba); + UNDEFARRAY(spec); + UNDEFARRAY(index); + UNDEFARRAY(z); + UNDEFARRAY(fog); + UNDEFARRAY(sTex); + UNDEFARRAY(tTex); + UNDEFARRAY(rTex); + UNDEFARRAY(lambda); + UNDEFARRAY(msTex); + UNDEFARRAY(mtTex); + UNDEFARRAY(mrTex); + UNDEFARRAY(mLambda); +} + + + + +/* + * Render a smooth-shaded, textured, RGBA triangle. + * Interpolate S,T,R with perspective correction, w/out mipmapping. + */ +static void general_textured_triangle( GLcontext *ctx, + const SWvertex *v0, + const SWvertex *v1, + const SWvertex *v2 ) +{ +#define INTERP_Z 1 +#define INTERP_FOG 1 +#define DEPTH_TYPE DEFAULT_SOFTWARE_DEPTH_TYPE +#define INTERP_RGB 1 +#define INTERP_ALPHA 1 +#define INTERP_TEX 1 + +#define SETUP_CODE \ + const struct gl_texture_object *obj = ctx->Texture.Unit[0]._Current; \ + const struct gl_texture_image *texImage = obj->Image[obj->BaseLevel];\ + const GLboolean flatShade = (ctx->Light.ShadeModel==GL_FLAT); \ + GLfixed rFlat, gFlat, bFlat, aFlat; \ + DEFARRAY(GLfloat, sSpan, MAX_WIDTH); /* mac 32k limitation */ \ + DEFARRAY(GLfloat, tSpan, MAX_WIDTH); /* mac 32k limitation */ \ + DEFARRAY(GLfloat, uSpan, MAX_WIDTH); /* mac 32k limitation */ \ + CHECKARRAY(sSpan, return); /* mac 32k limitation */ \ + CHECKARRAY(tSpan, return); /* mac 32k limitation */ \ + CHECKARRAY(uSpan, return); /* mac 32k limitation */ \ + if (flatShade) { \ + rFlat = IntToFixed(v2->color[RCOMP]); \ + gFlat = IntToFixed(v2->color[GCOMP]); \ + bFlat = IntToFixed(v2->color[BCOMP]); \ + aFlat = IntToFixed(v2->color[ACOMP]); \ + } \ + span.texWidth[0] = (GLfloat) texImage->Width; \ + span.texHeight[0] = (GLfloat) texImage->Height; \ + (void) fixedToDepthShift; + +#define RENDER_SPAN( span ) \ + GLdepth zSpan[MAX_WIDTH]; \ + GLfloat fogSpan[MAX_WIDTH]; \ + GLchan rgbaSpan[MAX_WIDTH][4]; \ + GLuint i; \ + if (flatShade) { \ + span.red = rFlat; span.redStep = 0; \ + span.green = gFlat; span.greenStep = 0; \ + span.blue = bFlat; span.blueStep = 0; \ + span.alpha = aFlat; span.alphaStep = 0; \ + } \ + /* NOTE: we could just call rasterize_span() here instead */ \ + for (i = 0; i < span.count; i++) { \ + GLdouble invQ = span.tex[0][3] ? (1.0 / span.tex[0][3]) : 1.0; \ + zSpan[i] = FixedToDepth(span.z); \ + span.z += span.zStep; \ + fogSpan[i] = span.fog; \ + span.fog += span.fogStep; \ + rgbaSpan[i][RCOMP] = FixedToInt(span.red); \ + rgbaSpan[i][GCOMP] = FixedToInt(span.green); \ + rgbaSpan[i][BCOMP] = FixedToInt(span.blue); \ + rgbaSpan[i][ACOMP] = FixedToInt(span.alpha); \ + span.red += span.redStep; \ + span.green += span.greenStep; \ + span.blue += span.blueStep; \ + span.alpha += span.alphaStep; \ + sSpan[i] = span.tex[0][0] * invQ; \ + tSpan[i] = span.tex[0][1] * invQ; \ + uSpan[i] = span.tex[0][2] * invQ; \ + span.tex[0][0] += span.texStep[0][0]; \ + span.tex[0][1] += span.texStep[0][1]; \ + span.tex[0][2] += span.texStep[0][2]; \ + span.tex[0][3] += span.texStep[0][3]; \ + } \ + _mesa_write_texture_span(ctx, span.count, span.x, span.y, \ + zSpan, fogSpan, sSpan, tSpan, uSpan, \ + NULL, rgbaSpan, NULL, NULL, GL_POLYGON ); + +#define CLEANUP_CODE \ + UNDEFARRAY(sSpan); /* mac 32k limitation */ \ + UNDEFARRAY(tSpan); \ + UNDEFARRAY(uSpan); + +#include "s_tritemp.h" +} + + +/* + * Render a smooth-shaded, textured, RGBA triangle with separate specular + * color interpolation. + * Interpolate texcoords with perspective correction, w/out mipmapping. + */ +static void general_textured_spec_triangle( GLcontext *ctx, + const SWvertex *v0, + const SWvertex *v1, + const SWvertex *v2 ) +{ +#define INTERP_Z 1 +#define INTERP_FOG 1 +#define DEPTH_TYPE DEFAULT_SOFTWARE_DEPTH_TYPE +#define INTERP_RGB 1 +#define INTERP_SPEC 1 +#define INTERP_ALPHA 1 +#define INTERP_TEX 1 + +#define SETUP_CODE \ + const struct gl_texture_object *obj = ctx->Texture.Unit[0]._Current; \ + const struct gl_texture_image *texImage = obj->Image[obj->BaseLevel];\ + const GLboolean flatShade = (ctx->Light.ShadeModel == GL_FLAT); \ + GLfixed rFlat, gFlat, bFlat, aFlat; \ + GLfixed srFlat, sgFlat, sbFlat; \ + if (flatShade) { \ + rFlat = IntToFixed(v2->color[RCOMP]); \ + gFlat = IntToFixed(v2->color[GCOMP]); \ + bFlat = IntToFixed(v2->color[BCOMP]); \ + aFlat = IntToFixed(v2->color[ACOMP]); \ + srFlat = IntToFixed(v2->specular[RCOMP]); \ + sgFlat = IntToFixed(v2->specular[GCOMP]); \ + sbFlat = IntToFixed(v2->specular[BCOMP]); \ + } \ + span.texWidth[0] = (GLfloat) texImage->Width; \ + span.texHeight[0] = (GLfloat) texImage->Height; \ + (void) fixedToDepthShift; + +#define RENDER_SPAN( span ) \ + if (flatShade) { \ + span.red = rFlat; span.redStep = 0; \ + span.green = gFlat; span.greenStep = 0; \ + span.blue = bFlat; span.blueStep = 0; \ + span.alpha = aFlat; span.alphaStep = 0; \ + span.specRed = srFlat; span.specRedStep = 0; \ + span.specGreen = sgFlat; span.specGreenStep = 0; \ + span.specBlue = sbFlat; span.specBlueStep = 0; \ + } \ + rasterize_span(ctx, &span); + +#include "s_tritemp.h" +} + + +/* + * Render a smooth-shaded, textured, RGBA triangle. + * Interpolate S,T,R with perspective correction and compute lambda for + * each fragment. Lambda is used to determine whether to use the + * minification or magnification filter. If minification and using + * mipmaps, lambda is also used to select the texture level of detail. + */ +static void lambda_textured_triangle( GLcontext *ctx, + const SWvertex *v0, + const SWvertex *v1, + const SWvertex *v2 ) +{ +#define INTERP_Z 1 +#define INTERP_FOG 1 +#define DEPTH_TYPE DEFAULT_SOFTWARE_DEPTH_TYPE +#define INTERP_RGB 1 +#define INTERP_ALPHA 1 +#define INTERP_TEX 1 +#define INTERP_LAMBDA 1 + +#define SETUP_CODE \ + const struct gl_texture_object *obj = ctx->Texture.Unit[0]._Current; \ + const struct gl_texture_image *texImage = obj->Image[obj->BaseLevel];\ + const GLboolean flatShade = (ctx->Light.ShadeModel==GL_FLAT); \ + GLfixed rFlat, gFlat, bFlat, aFlat; \ + GLfixed srFlat, sgFlat, sbFlat; \ + if (flatShade) { \ + rFlat = IntToFixed(v2->color[RCOMP]); \ + gFlat = IntToFixed(v2->color[GCOMP]); \ + bFlat = IntToFixed(v2->color[BCOMP]); \ + aFlat = IntToFixed(v2->color[ACOMP]); \ + srFlat = IntToFixed(v2->specular[RCOMP]); \ + sgFlat = IntToFixed(v2->specular[GCOMP]); \ + sbFlat = IntToFixed(v2->specular[BCOMP]); \ + } \ + span.texWidth[0] = (GLfloat) texImage->Width; \ + span.texHeight[0] = (GLfloat) texImage->Height; \ + (void) fixedToDepthShift; + +#define RENDER_SPAN( span ) \ + if (flatShade) { \ + span.red = rFlat; span.redStep = 0; \ + span.green = gFlat; span.greenStep = 0; \ + span.blue = bFlat; span.blueStep = 0; \ + span.alpha = aFlat; span.alphaStep = 0; \ + span.specRed = srFlat; span.specRedStep = 0; \ + span.specGreen = sgFlat; span.specGreenStep = 0; \ + span.specBlue = sbFlat; span.specBlueStep = 0; \ + } \ + rasterize_span(ctx, &span); + +#include "s_tritemp.h" +} + + +/* + * Render a smooth-shaded, textured, RGBA triangle with separate specular + * interpolation. + * Interpolate S,T,R with perspective correction and compute lambda for + * each fragment. Lambda is used to determine whether to use the + * minification or magnification filter. If minification and using + * mipmaps, lambda is also used to select the texture level of detail. + */ +static void lambda_textured_spec_triangle( GLcontext *ctx, + const SWvertex *v0, + const SWvertex *v1, + const SWvertex *v2 ) +{ +#define INTERP_Z 1 +#define INTERP_FOG 1 +#define DEPTH_TYPE DEFAULT_SOFTWARE_DEPTH_TYPE +#define INTERP_RGB 1 +#define INTERP_SPEC 1 +#define INTERP_ALPHA 1 +#define INTERP_TEX 1 +#define INTERP_LAMBDA 1 + +#define SETUP_CODE \ + const struct gl_texture_object *obj = ctx->Texture.Unit[0]._Current; \ + const struct gl_texture_image *texImage = obj->Image[obj->BaseLevel];\ + const GLboolean flatShade = (ctx->Light.ShadeModel == GL_FLAT); \ + GLfixed rFlat, gFlat, bFlat, aFlat; \ + GLfixed srFlat, sgFlat, sbFlat; \ + if (flatShade) { \ + rFlat = IntToFixed(v2->color[RCOMP]); \ + gFlat = IntToFixed(v2->color[GCOMP]); \ + bFlat = IntToFixed(v2->color[BCOMP]); \ + aFlat = IntToFixed(v2->color[ACOMP]); \ + srFlat = IntToFixed(v2->specular[RCOMP]); \ + sgFlat = IntToFixed(v2->specular[GCOMP]); \ + sbFlat = IntToFixed(v2->specular[BCOMP]); \ + } \ + span.texWidth[0] = (GLfloat) texImage->Width; \ + span.texHeight[0] = (GLfloat) texImage->Height; \ + (void) fixedToDepthShift; + +#define RENDER_SPAN( span ) \ + if (flatShade) { \ + span.red = rFlat; span.redStep = 0; \ + span.green = gFlat; span.greenStep = 0; \ + span.blue = bFlat; span.blueStep = 0; \ + span.alpha = aFlat; span.alphaStep = 0; \ + span.specRed = srFlat; span.specRedStep = 0; \ + span.specGreen = sgFlat; span.specGreenStep = 0; \ + span.specBlue = sbFlat; span.specBlueStep = 0; \ + } \ + rasterize_span(ctx, &span); + +#include "s_tritemp.h" +} + + +/* + * This is the big one! + * Interpolate Z, RGB, Alpha, specular, fog, and N sets of texture coordinates + * with lambda (LOD). + * Yup, it's slow. + */ +static void +lambda_multitextured_triangle( GLcontext *ctx, + const SWvertex *v0, + const SWvertex *v1, + const SWvertex *v2 ) +{ + +#define INTERP_Z 1 +#define INTERP_FOG 1 +#define DEPTH_TYPE DEFAULT_SOFTWARE_DEPTH_TYPE +#define INTERP_RGB 1 +#define INTERP_ALPHA 1 +#define INTERP_SPEC 1 +#define INTERP_MULTITEX 1 +#define INTERP_LAMBDA 1 + +#define SETUP_CODE \ + const GLboolean flatShade = (ctx->Light.ShadeModel == GL_FLAT); \ + GLfixed rFlat, gFlat, bFlat, aFlat; \ + GLfixed srFlat, sgFlat, sbFlat; \ + GLuint u; \ + if (flatShade) { \ + rFlat = IntToFixed(v2->color[RCOMP]); \ + gFlat = IntToFixed(v2->color[GCOMP]); \ + bFlat = IntToFixed(v2->color[BCOMP]); \ + aFlat = IntToFixed(v2->color[ACOMP]); \ + srFlat = IntToFixed(v2->specular[RCOMP]); \ + sgFlat = IntToFixed(v2->specular[GCOMP]); \ + sbFlat = IntToFixed(v2->specular[BCOMP]); \ + } \ + for (u = 0; u < ctx->Const.MaxTextureUnits; u++) { \ + if (ctx->Texture.Unit[u]._ReallyEnabled) { \ + const struct gl_texture_object *texObj; \ + const struct gl_texture_image *texImage; \ + texObj = ctx->Texture.Unit[u]._Current; \ + texImage = texObj->Image[texObj->BaseLevel]; \ + span.texWidth[u] = (GLfloat) texImage->Width; \ + span.texHeight[u] = (GLfloat) texImage->Height; \ + } \ + } \ + (void) fixedToDepthShift; + +#define RENDER_SPAN( span ) \ + if (flatShade) { \ + span.red = rFlat; span.redStep = 0; \ + span.green = gFlat; span.greenStep = 0; \ + span.blue = bFlat; span.blueStep = 0; \ + span.alpha = aFlat; span.alphaStep = 0; \ + span.specRed = srFlat; span.specRedStep = 0; \ + span.specGreen = sgFlat; span.specGreenStep = 0; \ + span.specBlue = sbFlat; span.specBlueStep = 0; \ + } \ + rasterize_span(ctx, &span); + +#include "s_tritemp.h" + +} + + +static void occlusion_zless_triangle( GLcontext *ctx, + const SWvertex *v0, + const SWvertex *v1, + const SWvertex *v2 ) +{ + if (ctx->OcclusionResult) { + return; + } + +#define DO_OCCLUSION_TEST +#define INTERP_Z 1 +#define DEPTH_TYPE DEFAULT_SOFTWARE_DEPTH_TYPE + +#define RENDER_SPAN( span ) \ + GLuint i; \ + for (i = 0; i < span.count; i++) { \ + GLdepth z = FixedToDepth(span.z); \ + if (z < zRow[i]) { \ + ctx->OcclusionResult = GL_TRUE; \ + return; \ + } \ + span.z += span.zStep; \ + } + +#include "s_tritemp.h" +} + +static void nodraw_triangle( GLcontext *ctx, + const SWvertex *v0, + const SWvertex *v1, + const SWvertex *v2 ) +{ + (void) (ctx && v0 && v1 && v2); +} + +void _swrast_add_spec_terms_triangle( GLcontext *ctx, + const SWvertex *v0, + const SWvertex *v1, + const SWvertex *v2 ) +{ + SWvertex *ncv0 = (SWvertex *)v0; /* drop const qualifier */ + SWvertex *ncv1 = (SWvertex *)v1; + SWvertex *ncv2 = (SWvertex *)v2; + GLchan c[3][4]; + COPY_CHAN4( c[0], ncv0->color ); + COPY_CHAN4( c[1], ncv1->color ); + COPY_CHAN4( c[2], ncv2->color ); + ACC_3V( ncv0->color, ncv0->specular ); + ACC_3V( ncv1->color, ncv1->specular ); + ACC_3V( ncv2->color, ncv2->specular ); + SWRAST_CONTEXT(ctx)->SpecTriangle( ctx, ncv0, ncv1, ncv2 ); + COPY_CHAN4( ncv0->color, c[0] ); + COPY_CHAN4( ncv1->color, c[1] ); + COPY_CHAN4( ncv2->color, c[2] ); +} + + + +#ifdef DEBUG + +/* record the current triangle function name */ +static const char *triFuncName = NULL; + +#define USE(triFunc) \ +do { \ + triFuncName = #triFunc; \ + /*printf("%s\n", triFuncName);*/ \ + swrast->Triangle = triFunc; \ +} while (0) + +#else + +#define USE(triFunc) swrast->Triangle = triFunc; + +#endif + + + + +/* + * Determine which triangle rendering function to use given the current + * rendering context. + * + * Please update the summary flag _SWRAST_NEW_TRIANGLE if you add or + * remove tests to this code. + */ +void +_swrast_choose_triangle( GLcontext *ctx ) +{ + SWcontext *swrast = SWRAST_CONTEXT(ctx); + const GLboolean rgbmode = ctx->Visual.rgbMode; + + if (ctx->Polygon.CullFlag && + ctx->Polygon.CullFaceMode == GL_FRONT_AND_BACK) { + USE(nodraw_triangle); + return; + } + + if (ctx->RenderMode==GL_RENDER) { + + if (ctx->Polygon.SmoothFlag) { + _mesa_set_aa_triangle_function(ctx); + ASSERT(swrast->Triangle); + return; + } + + if (ctx->Depth.OcclusionTest && + ctx->Depth.Test && + ctx->Depth.Mask == GL_FALSE && + ctx->Depth.Func == GL_LESS && + !ctx->Stencil.Enabled) { + if ((rgbmode && + ctx->Color.ColorMask[0] == 0 && + ctx->Color.ColorMask[1] == 0 && + ctx->Color.ColorMask[2] == 0 && + ctx->Color.ColorMask[3] == 0) + || + (!rgbmode && ctx->Color.IndexMask == 0)) { + USE(occlusion_zless_triangle); + return; + } + } + + if (ctx->Texture._ReallyEnabled) { + /* Ugh, we do a _lot_ of tests to pick the best textured tri func */ + const struct gl_texture_object *texObj2D; + const struct gl_texture_image *texImg; + GLenum minFilter, magFilter, envMode; + GLint format; + texObj2D = ctx->Texture.Unit[0].Current2D; + texImg = texObj2D ? texObj2D->Image[texObj2D->BaseLevel] : NULL; + format = texImg ? texImg->TexFormat->MesaFormat : -1; + minFilter = texObj2D ? texObj2D->MinFilter : (GLenum) 0; + magFilter = texObj2D ? texObj2D->MagFilter : (GLenum) 0; + envMode = ctx->Texture.Unit[0].EnvMode; + + /* First see if we can used an optimized 2-D texture function */ + if (ctx->Texture._ReallyEnabled==TEXTURE0_2D + && texObj2D->WrapS==GL_REPEAT + && texObj2D->WrapT==GL_REPEAT + && texImg->Border==0 + && (format == MESA_FORMAT_RGB || format == MESA_FORMAT_RGBA) + && minFilter == magFilter + && ctx->Light.Model.ColorControl == GL_SINGLE_COLOR + && ctx->Texture.Unit[0].EnvMode != GL_COMBINE_EXT) { + if (ctx->Hint.PerspectiveCorrection==GL_FASTEST) { + if (minFilter == GL_NEAREST + && format == MESA_FORMAT_RGB + && (envMode == GL_REPLACE || envMode == GL_DECAL) + && ((swrast->_RasterMask == (DEPTH_BIT | TEXTURE_BIT) + && ctx->Depth.Func == GL_LESS + && ctx->Depth.Mask == GL_TRUE) + || swrast->_RasterMask == TEXTURE_BIT) + && ctx->Polygon.StippleFlag == GL_FALSE) { + if (swrast->_RasterMask == (DEPTH_BIT | TEXTURE_BIT)) { + USE(simple_z_textured_triangle); + } + else { + USE(simple_textured_triangle); + } + } + else { + if (ctx->Texture.Unit[0].EnvMode==GL_ADD) { + USE(general_textured_triangle); + } + else { + USE(affine_textured_triangle); + } + } + } + else { +#if 00 /* XXX these function have problems with texture coord interpolation */ + if (filter==GL_NEAREST) { + USE(near_persp_textured_triangle); + } + else { + USE(lin_persp_textured_triangle); + } +#endif + USE(general_textured_triangle); + } + } + else { + /* More complicated textures (mipmap, multi-tex, sep specular) */ + GLboolean needLambda; + /* if mag filter != min filter we need to compute lambda */ + const struct gl_texture_object *obj = ctx->Texture.Unit[0]._Current; + if (obj && obj->MinFilter != obj->MagFilter) + needLambda = GL_TRUE; + else + needLambda = GL_FALSE; + if (ctx->Texture._ReallyEnabled > TEXTURE0_ANY) { + USE(lambda_multitextured_triangle); + } + else if (ctx->_TriangleCaps & DD_SEPARATE_SPECULAR) { + /* separate specular color interpolation */ + if (needLambda) { + USE(lambda_textured_spec_triangle); + } + else { + USE(general_textured_spec_triangle); + } + } + else { + if (needLambda) { + USE(lambda_textured_triangle); + } + else { + USE(general_textured_triangle); + } + } + } + } + else { + ASSERT(!ctx->Texture._ReallyEnabled); + if (ctx->Light.ShadeModel==GL_SMOOTH) { + /* smooth shaded, no texturing, stippled or some raster ops */ + if (rgbmode) { + USE(smooth_rgba_triangle); + } + else { + USE(smooth_ci_triangle); + } + } + else { + /* flat shaded, no texturing, stippled or some raster ops */ + if (rgbmode) { + USE(flat_rgba_triangle); + } + else { + USE(flat_ci_triangle); + } + } + } + } + else if (ctx->RenderMode==GL_FEEDBACK) { + USE(_mesa_feedback_triangle); + } + else { + /* GL_SELECT mode */ + USE(_mesa_select_triangle); + } +} Index: dll/opengl/opengl32/mesa/swrast/s_triangle.h =================================================================== --- dll/opengl/opengl32/mesa/swrast/s_triangle.h (revision 0) +++ dll/opengl/opengl32/mesa/swrast/s_triangle.h (working copy) @@ -0,0 +1,55 @@ +/* $Id: s_triangle.h,v 1.7 2001/03/12 00:48:42 gareth Exp $ */ + +/* + * Mesa 3-D graphics library + * Version: 3.5 + * + * Copyright (C) 1999-2001 Brian Paul 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 + * BRIAN PAUL 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. + */ + + + + + +#ifndef S_TRIANGLES_H +#define S_TRIANGLES_H + + +#include "mtypes.h" +#include "swrast.h" + + +GLboolean _mesa_cull_triangle( GLcontext *ctx, + const SWvertex *v0, + const SWvertex *v1, + const SWvertex *v2); + + +void +_swrast_choose_triangle( GLcontext *ctx ); + +void +_swrast_add_spec_terms_triangle( GLcontext *ctx, + const SWvertex *v0, + const SWvertex *v1, + const SWvertex *v2 ); + + +#endif Index: dll/opengl/opengl32/mesa/swrast/s_trispan.h =================================================================== --- dll/opengl/opengl32/mesa/swrast/s_trispan.h (revision 0) +++ dll/opengl/opengl32/mesa/swrast/s_trispan.h (working copy) @@ -0,0 +1,79 @@ +/* $Id: s_trispan.h,v 1.1 2001/05/14 16:23:04 brianp Exp $ */ + +/* + * Mesa 3-D graphics library + * Version: 3.5 + * + * Copyright (C) 1999-2001 Brian Paul 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 + * BRIAN PAUL 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. + */ + + +#ifndef S_TRISPAN_H +#define S_TRISPAN_H + + +/* + * The triangle_span structure is used by the triangle template code in + * s_tritemp.h. It describes how colors, Z, texcoords, etc are to be + * interpolated across each scanline of triangle. + * With this structure it's easy to hand-off span rasterization to a + * subroutine instead of doing it all inline like we used to do. + * It also cleans up the local variable namespace a great deal. + * + * It would be interesting to experiment with multiprocessor rasterization + * with this structure. The triangle rasterizer could simply emit a + * stream of these structures which would be consumed by one or more + * span-processing threads which could run in parallel. + */ + + +#define SPAN_RGBA 0x01 +#define SPAN_SPEC 0x02 +#define SPAN_INDEX 0x04 +#define SPAN_Z 0x08 +#define SPAN_FOG 0x10 +#define SPAN_TEXTURE 0x20 +#define SPAN_INT_TEXTURE 0x40 +#define SPAN_LAMBDA 0x80 + + +struct triangle_span { + GLint x, y; + GLuint count; + GLuint activeMask; /* OR of the SPAN_* flags */ + GLfixed red, redStep; + GLfixed green, greenStep; + GLfixed blue, blueStep; + GLfixed alpha, alphaStep; + GLfixed specRed, specRedStep; + GLfixed specGreen, specGreenStep; + GLfixed specBlue, specBlueStep; + GLfixed index, indexStep; + GLfixed z, zStep; + GLfloat fog, fogStep; + GLfloat tex[MAX_TEXTURE_UNITS][4], texStep[MAX_TEXTURE_UNITS][4]; + GLfixed intTex[2], intTexStep[2]; + /* Needed for texture lambda (LOD) computation */ + GLfloat rho[MAX_TEXTURE_UNITS]; + GLfloat texWidth[MAX_TEXTURE_UNITS], texHeight[MAX_TEXTURE_UNITS]; +}; + + +#endif /* S_TRISPAN_H */ Index: dll/opengl/opengl32/mesa/swrast/s_tritemp.h =================================================================== --- dll/opengl/opengl32/mesa/swrast/s_tritemp.h (revision 0) +++ dll/opengl/opengl32/mesa/swrast/s_tritemp.h (working copy) @@ -0,0 +1,1242 @@ +/* $Id: s_tritemp.h,v 1.19 2001/06/13 14:53:52 brianp Exp $ */ + +/* + * Mesa 3-D graphics library + * Version: 3.5 + * + * Copyright (C) 1999-2001 Brian Paul 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 + * BRIAN PAUL 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. + */ + + +/* + * Triangle Rasterizer Template + * + * This file is #include'd to generate custom triangle rasterizers. + * + * The following macros may be defined to indicate what auxillary information + * must be interplated across the triangle: + * INTERP_Z - if defined, interpolate Z values + * INTERP_FOG - if defined, interpolate fog values + * INTERP_RGB - if defined, interpolate RGB values + * INTERP_ALPHA - if defined, interpolate Alpha values + * INTERP_SPEC - if defined, interpolate specular RGB values + * INTERP_INDEX - if defined, interpolate color index values + * INTERP_INT_TEX - if defined, interpolate integer ST texcoords + * (fast, simple 2-D texture mapping) + * INTERP_TEX - if defined, interpolate set 0 float STRQ texcoords + * NOTE: OpenGL STRQ = Mesa STUV (R was taken for red) + * INTERP_MULTITEX - if defined, interpolate N units of STRQ texcoords + * INTERP_LAMBDA - if defined, compute lambda value (for mipmapping) + * a lambda value for every texture unit + * + * When one can directly address pixels in the color buffer the following + * macros can be defined and used to compute pixel addresses during + * rasterization (see pRow): + * PIXEL_TYPE - the datatype of a pixel (GLubyte, GLushort, GLuint) + * BYTES_PER_ROW - number of bytes per row in the color buffer + * PIXEL_ADDRESS(X,Y) - returns the address of pixel at (X,Y) where + * Y==0 at bottom of screen and increases upward. + * + * Similarly, for direct depth buffer access, this type is used for depth + * buffer addressing: + * DEPTH_TYPE - either GLushort or GLuint + * + * Optionally, one may provide one-time setup code per triangle: + * SETUP_CODE - code which is to be executed once per triangle + * CLEANUP_CODE - code to execute at end of triangle + * + * The following macro MUST be defined: + * RENDER_SPAN(span) - code to write a span of pixels. + * + * This code was designed for the origin to be in the lower-left corner. + * + * Inspired by triangle rasterizer code written by Allen Akin. Thanks Allen! + */ + +/*void triangle( GLcontext *ctx, SWvertex *v0, SWvertex *v1, SWvertex *v2 )*/ +{ + typedef struct { + const SWvertex *v0, *v1; /* Y(v0) < Y(v1) */ + GLfloat dx; /* X(v1) - X(v0) */ + GLfloat dy; /* Y(v1) - Y(v0) */ + GLfixed fdxdy; /* dx/dy in fixed-point */ + GLfixed fsx; /* first sample point x coord */ + GLfixed fsy; + GLfloat adjy; /* adjust from v[0]->fy to fsy, scaled */ + GLint lines; /* number of lines to be sampled on this edge */ + GLfixed fx0; /* fixed pt X of lower endpoint */ + } EdgeT; + +#ifdef INTERP_Z + const GLint depthBits = ctx->Visual.depthBits; + const GLint fixedToDepthShift = depthBits <= 16 ? FIXED_SHIFT : 0; + const GLfloat maxDepth = ctx->DepthMaxF; +#define FixedToDepth(F) ((F) >> fixedToDepthShift) +#endif + EdgeT eMaj, eTop, eBot; + GLfloat oneOverArea; + const SWvertex *vMin, *vMid, *vMax; /* Y(vMin)<=Y(vMid)<=Y(vMax) */ + float bf = SWRAST_CONTEXT(ctx)->_backface_sign; + GLboolean tiny; + const GLint snapMask = ~((FIXED_ONE / 16) - 1); /* for x/y coord snapping */ + GLfixed vMin_fx, vMin_fy, vMid_fx, vMid_fy, vMax_fx, vMax_fy; + + struct triangle_span span; + +#ifdef INTERP_Z + (void) fixedToDepthShift; +#endif + + /* Compute fixed point x,y coords w/ half-pixel offsets and snapping. + * And find the order of the 3 vertices along the Y axis. + */ + { + const GLfixed fy0 = FloatToFixed(v0->win[1] - 0.5F) & snapMask; + const GLfixed fy1 = FloatToFixed(v1->win[1] - 0.5F) & snapMask; + const GLfixed fy2 = FloatToFixed(v2->win[1] - 0.5F) & snapMask; + + if (fy0 <= fy1) { + if (fy1 <= fy2) { + /* y0 <= y1 <= y2 */ + vMin = v0; vMid = v1; vMax = v2; + vMin_fy = fy0; vMid_fy = fy1; vMax_fy = fy2; + } + else if (fy2 <= fy0) { + /* y2 <= y0 <= y1 */ + vMin = v2; vMid = v0; vMax = v1; + vMin_fy = fy2; vMid_fy = fy0; vMax_fy = fy1; + } + else { + /* y0 <= y2 <= y1 */ + vMin = v0; vMid = v2; vMax = v1; + vMin_fy = fy0; vMid_fy = fy2; vMax_fy = fy1; + bf = -bf; + } + } + else { + if (fy0 <= fy2) { + /* y1 <= y0 <= y2 */ + vMin = v1; vMid = v0; vMax = v2; + vMin_fy = fy1; vMid_fy = fy0; vMax_fy = fy2; + bf = -bf; + } + else if (fy2 <= fy1) { + /* y2 <= y1 <= y0 */ + vMin = v2; vMid = v1; vMax = v0; + vMin_fy = fy2; vMid_fy = fy1; vMax_fy = fy0; + bf = -bf; + } + else { + /* y1 <= y2 <= y0 */ + vMin = v1; vMid = v2; vMax = v0; + vMin_fy = fy1; vMid_fy = fy2; vMax_fy = fy0; + } + } + + /* fixed point X coords */ + vMin_fx = FloatToFixed(vMin->win[0] + 0.5F) & snapMask; + vMid_fx = FloatToFixed(vMid->win[0] + 0.5F) & snapMask; + vMax_fx = FloatToFixed(vMax->win[0] + 0.5F) & snapMask; + } + + /* vertex/edge relationship */ + eMaj.v0 = vMin; eMaj.v1 = vMax; /*TODO: .v1's not needed */ + eTop.v0 = vMid; eTop.v1 = vMax; + eBot.v0 = vMin; eBot.v1 = vMid; + + /* compute deltas for each edge: vertex[upper] - vertex[lower] */ + eMaj.dx = FixedToFloat(vMax_fx - vMin_fx); + eMaj.dy = FixedToFloat(vMax_fy - vMin_fy); + eTop.dx = FixedToFloat(vMax_fx - vMid_fx); + eTop.dy = FixedToFloat(vMax_fy - vMid_fy); + eBot.dx = FixedToFloat(vMid_fx - vMin_fx); + eBot.dy = FixedToFloat(vMid_fy - vMin_fy); + + /* compute area, oneOverArea and perform backface culling */ + { + const GLfloat area = eMaj.dx * eBot.dy - eBot.dx * eMaj.dy; + + /* Do backface culling */ + if (area * bf < 0.0) + return; + + if (area == 0.0F) + return; + + /* This may not be needed anymore. Let's see if anyone reports a problem. */ +#if 0 + /* check for very tiny triangle */ + if (area * area < (0.001F * 0.001F)) { /* square to ensure positive value */ + oneOverArea = 1.0F / 0.001F; /* a close-enough value */ + tiny = GL_TRUE; + } + else +#endif + { + oneOverArea = 1.0F / area; + tiny = GL_FALSE; + } + } + +#ifndef DO_OCCLUSION_TEST + ctx->OcclusionResult = GL_TRUE; +#endif + + /* Edge setup. For a triangle strip these could be reused... */ + { + eMaj.fsy = FixedCeil(vMin_fy); + eMaj.lines = FixedToInt(FixedCeil(vMax_fy - eMaj.fsy)); + if (eMaj.lines > 0) { + GLfloat dxdy = eMaj.dx / eMaj.dy; + eMaj.fdxdy = SignedFloatToFixed(dxdy); + eMaj.adjy = (GLfloat) (eMaj.fsy - vMin_fy); /* SCALED! */ + eMaj.fx0 = vMin_fx; + eMaj.fsx = eMaj.fx0 + (GLfixed) (eMaj.adjy * dxdy); + } + else { + return; /*CULLED*/ + } + + eTop.fsy = FixedCeil(vMid_fy); + eTop.lines = FixedToInt(FixedCeil(vMax_fy - eTop.fsy)); + if (eTop.lines > 0) { + GLfloat dxdy = eTop.dx / eTop.dy; + eTop.fdxdy = SignedFloatToFixed(dxdy); + eTop.adjy = (GLfloat) (eTop.fsy - vMid_fy); /* SCALED! */ + eTop.fx0 = vMid_fx; + eTop.fsx = eTop.fx0 + (GLfixed) (eTop.adjy * dxdy); + } + + eBot.fsy = FixedCeil(vMin_fy); + eBot.lines = FixedToInt(FixedCeil(vMid_fy - eBot.fsy)); + if (eBot.lines > 0) { + GLfloat dxdy = eBot.dx / eBot.dy; + eBot.fdxdy = SignedFloatToFixed(dxdy); + eBot.adjy = (GLfloat) (eBot.fsy - vMin_fy); /* SCALED! */ + eBot.fx0 = vMin_fx; + eBot.fsx = eBot.fx0 + (GLfixed) (eBot.adjy * dxdy); + } + } + + /* + * Conceptually, we view a triangle as two subtriangles + * separated by a perfectly horizontal line. The edge that is + * intersected by this line is one with maximal absolute dy; we + * call it a ``major'' edge. The other two edges are the + * ``top'' edge (for the upper subtriangle) and the ``bottom'' + * edge (for the lower subtriangle). If either of these two + * edges is horizontal or very close to horizontal, the + * corresponding subtriangle might cover zero sample points; + * we take care to handle such cases, for performance as well + * as correctness. + * + * By stepping rasterization parameters along the major edge, + * we can avoid recomputing them at the discontinuity where + * the top and bottom edges meet. However, this forces us to + * be able to scan both left-to-right and right-to-left. + * Also, we must determine whether the major edge is at the + * left or right side of the triangle. We do this by + * computing the magnitude of the cross-product of the major + * and top edges. Since this magnitude depends on the sine of + * the angle between the two edges, its sign tells us whether + * we turn to the left or to the right when travelling along + * the major edge to the top edge, and from this we infer + * whether the major edge is on the left or the right. + * + * Serendipitously, this cross-product magnitude is also a + * value we need to compute the iteration parameter + * derivatives for the triangle, and it can be used to perform + * backface culling because its sign tells us whether the + * triangle is clockwise or counterclockwise. In this code we + * refer to it as ``area'' because it's also proportional to + * the pixel area of the triangle. + */ + + { + GLint ltor; /* true if scanning left-to-right */ +#ifdef INTERP_Z + GLfloat dzdx, dzdy; +#endif +#ifdef INTERP_FOG + GLfloat dfogdy; +#endif +#ifdef INTERP_RGB + GLfloat drdx, drdy; + GLfloat dgdx, dgdy; + GLfloat dbdx, dbdy; +#endif +#ifdef INTERP_ALPHA + GLfloat dadx, dady; +#endif +#ifdef INTERP_SPEC + GLfloat dsrdx, dsrdy; + GLfloat dsgdx, dsgdy; + GLfloat dsbdx, dsbdy; +#endif +#ifdef INTERP_INDEX + GLfloat didx, didy; +#endif +#ifdef INTERP_INT_TEX + GLfloat dsdx, dsdy; + GLfloat dtdx, dtdy; +#endif +#ifdef INTERP_TEX + GLfloat dsdy; + GLfloat dtdy; + GLfloat dudy; + GLfloat dvdy; +#endif +#ifdef INTERP_MULTITEX + GLfloat dsdy[MAX_TEXTURE_UNITS]; + GLfloat dtdy[MAX_TEXTURE_UNITS]; + GLfloat dudy[MAX_TEXTURE_UNITS]; + GLfloat dvdy[MAX_TEXTURE_UNITS]; +#endif + +#if defined(INTERP_LAMBDA) && !defined(INTERP_TEX) && !defined(INTERP_MULTITEX) +#error "Mipmapping without texturing doesn't make sense." +#endif + + /* + * Execute user-supplied setup code + */ +#ifdef SETUP_CODE + SETUP_CODE +#endif + + ltor = (oneOverArea < 0.0F); + + span.activeMask = 0; + + /* compute d?/dx and d?/dy derivatives */ +#ifdef INTERP_Z + span.activeMask |= SPAN_Z; + { + GLfloat eMaj_dz, eBot_dz; + eMaj_dz = vMax->win[2] - vMin->win[2]; + eBot_dz = vMid->win[2] - vMin->win[2]; + dzdx = oneOverArea * (eMaj_dz * eBot.dy - eMaj.dy * eBot_dz); + if (dzdx > maxDepth || dzdx < -maxDepth) { + /* probably a sliver triangle */ + dzdx = 0.0; + dzdy = 0.0; + } + else { + dzdy = oneOverArea * (eMaj.dx * eBot_dz - eMaj_dz * eBot.dx); + } + if (depthBits <= 16) + span.zStep = SignedFloatToFixed(dzdx); + else + span.zStep = (GLint) dzdx; + } +#endif +#ifdef INTERP_FOG + span.activeMask |= SPAN_FOG; + { + const GLfloat eMaj_dfog = vMax->fog - vMin->fog; + const GLfloat eBot_dfog = vMid->fog - vMin->fog; + span.fogStep = oneOverArea * (eMaj_dfog * eBot.dy - eMaj.dy * eBot_dfog); + dfogdy = oneOverArea * (eMaj.dx * eBot_dfog - eMaj_dfog * eBot.dx); + } +#endif +#ifdef INTERP_RGB + span.activeMask |= SPAN_RGBA; + if (tiny) { + /* This is kind of a hack to eliminate RGB color over/underflow + * problems when rendering very tiny triangles. We're not doing + * anything with alpha or specular color at this time. + */ + drdx = drdy = 0.0; span.redStep = 0; + dgdx = dgdy = 0.0; span.greenStep = 0; + dbdx = dbdy = 0.0; span.blueStep = 0; + } + else { + GLfloat eMaj_dr, eBot_dr; + GLfloat eMaj_dg, eBot_dg; + GLfloat eMaj_db, eBot_db; + eMaj_dr = (GLint) vMax->color[0] - (GLint) vMin->color[0]; + eBot_dr = (GLint) vMid->color[0] - (GLint) vMin->color[0]; + drdx = oneOverArea * (eMaj_dr * eBot.dy - eMaj.dy * eBot_dr); + span.redStep = SignedFloatToFixed(drdx); + drdy = oneOverArea * (eMaj.dx * eBot_dr - eMaj_dr * eBot.dx); + eMaj_dg = (GLint) vMax->color[1] - (GLint) vMin->color[1]; + eBot_dg = (GLint) vMid->color[1] - (GLint) vMin->color[1]; + dgdx = oneOverArea * (eMaj_dg * eBot.dy - eMaj.dy * eBot_dg); + span.greenStep = SignedFloatToFixed(dgdx); + dgdy = oneOverArea * (eMaj.dx * eBot_dg - eMaj_dg * eBot.dx); + eMaj_db = (GLint) vMax->color[2] - (GLint) vMin->color[2]; + eBot_db = (GLint) vMid->color[2] - (GLint) vMin->color[2]; + dbdx = oneOverArea * (eMaj_db * eBot.dy - eMaj.dy * eBot_db); + span.blueStep = SignedFloatToFixed(dbdx); + dbdy = oneOverArea * (eMaj.dx * eBot_db - eMaj_db * eBot.dx); + } +#endif +#ifdef INTERP_ALPHA + { + GLfloat eMaj_da, eBot_da; + eMaj_da = (GLint) vMax->color[3] - (GLint) vMin->color[3]; + eBot_da = (GLint) vMid->color[3] - (GLint) vMin->color[3]; + dadx = oneOverArea * (eMaj_da * eBot.dy - eMaj.dy * eBot_da); + span.alphaStep = SignedFloatToFixed(dadx); + dady = oneOverArea * (eMaj.dx * eBot_da - eMaj_da * eBot.dx); + } +#endif +#ifdef INTERP_SPEC + span.activeMask |= SPAN_SPEC; + { + GLfloat eMaj_dsr, eBot_dsr; + eMaj_dsr = (GLint) vMax->specular[0] - (GLint) vMin->specular[0]; + eBot_dsr = (GLint) vMid->specular[0] - (GLint) vMin->specular[0]; + dsrdx = oneOverArea * (eMaj_dsr * eBot.dy - eMaj.dy * eBot_dsr); + span.specRedStep = SignedFloatToFixed(dsrdx); + dsrdy = oneOverArea * (eMaj.dx * eBot_dsr - eMaj_dsr * eBot.dx); + } + { + GLfloat eMaj_dsg, eBot_dsg; + eMaj_dsg = (GLint) vMax->specular[1] - (GLint) vMin->specular[1]; + eBot_dsg = (GLint) vMid->specular[1] - (GLint) vMin->specular[1]; + dsgdx = oneOverArea * (eMaj_dsg * eBot.dy - eMaj.dy * eBot_dsg); + span.specGreenStep = SignedFloatToFixed(dsgdx); + dsgdy = oneOverArea * (eMaj.dx * eBot_dsg - eMaj_dsg * eBot.dx); + } + { + GLfloat eMaj_dsb, eBot_dsb; + eMaj_dsb = (GLint) vMax->specular[2] - (GLint) vMin->specular[2]; + eBot_dsb = (GLint) vMid->specular[2] - (GLint) vMin->specular[2]; + dsbdx = oneOverArea * (eMaj_dsb * eBot.dy - eMaj.dy * eBot_dsb); + span.specBlueStep = SignedFloatToFixed(dsbdx); + dsbdy = oneOverArea * (eMaj.dx * eBot_dsb - eMaj_dsb * eBot.dx); + } +#endif +#ifdef INTERP_INDEX + span.activeMask |= SPAN_INDEX; + { + GLfloat eMaj_di, eBot_di; + eMaj_di = (GLint) vMax->index - (GLint) vMin->index; + eBot_di = (GLint) vMid->index - (GLint) vMin->index; + didx = oneOverArea * (eMaj_di * eBot.dy - eMaj.dy * eBot_di); + span.indexStep = SignedFloatToFixed(didx); + didy = oneOverArea * (eMaj.dx * eBot_di - eMaj_di * eBot.dx); + } +#endif +#ifdef INTERP_INT_TEX + span.activeMask |= SPAN_INT_TEXTURE; + { + GLfloat eMaj_ds, eBot_ds; + eMaj_ds = (vMax->texcoord[0][0] - vMin->texcoord[0][0]) * S_SCALE; + eBot_ds = (vMid->texcoord[0][0] - vMin->texcoord[0][0]) * S_SCALE; + dsdx = oneOverArea * (eMaj_ds * eBot.dy - eMaj.dy * eBot_ds); + span.intTexStep[0] = SignedFloatToFixed(dsdx); + dsdy = oneOverArea * (eMaj.dx * eBot_ds - eMaj_ds * eBot.dx); + } + { + GLfloat eMaj_dt, eBot_dt; + eMaj_dt = (vMax->texcoord[0][1] - vMin->texcoord[0][1]) * T_SCALE; + eBot_dt = (vMid->texcoord[0][1] - vMin->texcoord[0][1]) * T_SCALE; + dtdx = oneOverArea * (eMaj_dt * eBot.dy - eMaj.dy * eBot_dt); + span.intTexStep[1] = SignedFloatToFixed(dtdx); + dtdy = oneOverArea * (eMaj.dx * eBot_dt - eMaj_dt * eBot.dx); + } + +#endif + +#ifdef INTERP_TEX + span.activeMask |= SPAN_TEXTURE; + { + GLfloat wMax = vMax->win[3]; + GLfloat wMin = vMin->win[3]; + GLfloat wMid = vMid->win[3]; + GLfloat eMaj_ds, eBot_ds; + GLfloat eMaj_dt, eBot_dt; + GLfloat eMaj_du, eBot_du; + GLfloat eMaj_dv, eBot_dv; + + eMaj_ds = vMax->texcoord[0][0] * wMax - vMin->texcoord[0][0] * wMin; + eBot_ds = vMid->texcoord[0][0] * wMid - vMin->texcoord[0][0] * wMin; + span.texStep[0][0] = oneOverArea * (eMaj_ds * eBot.dy + - eMaj.dy * eBot_ds); + dsdy = oneOverArea * (eMaj.dx * eBot_ds - eMaj_ds * eBot.dx); + + eMaj_dt = vMax->texcoord[0][1] * wMax - vMin->texcoord[0][1] * wMin; + eBot_dt = vMid->texcoord[0][1] * wMid - vMin->texcoord[0][1] * wMin; + span.texStep[0][1] = oneOverArea * (eMaj_dt * eBot.dy + - eMaj.dy * eBot_dt); + dtdy = oneOverArea * (eMaj.dx * eBot_dt - eMaj_dt * eBot.dx); + + eMaj_du = vMax->texcoord[0][2] * wMax - vMin->texcoord[0][2] * wMin; + eBot_du = vMid->texcoord[0][2] * wMid - vMin->texcoord[0][2] * wMin; + span.texStep[0][2] = oneOverArea * (eMaj_du * eBot.dy + - eMaj.dy * eBot_du); + dudy = oneOverArea * (eMaj.dx * eBot_du - eMaj_du * eBot.dx); + + eMaj_dv = vMax->texcoord[0][3] * wMax - vMin->texcoord[0][3] * wMin; + eBot_dv = vMid->texcoord[0][3] * wMid - vMin->texcoord[0][3] * wMin; + span.texStep[0][3] = oneOverArea * (eMaj_dv * eBot.dy + - eMaj.dy * eBot_dv); + dvdy = oneOverArea * (eMaj.dx * eBot_dv - eMaj_dv * eBot.dx); + } +# ifdef INTERP_LAMBDA + { + GLfloat dudx = span.texStep[0][0] * span.texWidth[0]; + GLfloat dudy = dsdy * span.texWidth[0]; + GLfloat dvdx = span.texStep[0][1] * span.texHeight[0]; + GLfloat dvdy = dtdy * span.texHeight[0]; + GLfloat r1 = dudx * dudx + dudy * dudy; + GLfloat r2 = dvdx * dvdx + dvdy * dvdy; + span.rho[0] = r1 + r2; /* was rho2 = MAX2(r1,r2) */ + span.activeMask |= SPAN_LAMBDA; + } +# endif +#endif + +#ifdef INTERP_MULTITEX + span.activeMask |= SPAN_TEXTURE; +# ifdef INTERP_LAMBDA + span.activeMask |= SPAN_LAMBDA; +# endif + { + GLfloat wMax = vMax->win[3]; + GLfloat wMin = vMin->win[3]; + GLfloat wMid = vMid->win[3]; + GLuint u; + for (u = 0; u < ctx->Const.MaxTextureUnits; u++) { + if (ctx->Texture.Unit[u]._ReallyEnabled) { + GLfloat eMaj_ds, eBot_ds; + GLfloat eMaj_dt, eBot_dt; + GLfloat eMaj_du, eBot_du; + GLfloat eMaj_dv, eBot_dv; + eMaj_ds = vMax->texcoord[u][0] * wMax + - vMin->texcoord[u][0] * wMin; + eBot_ds = vMid->texcoord[u][0] * wMid + - vMin->texcoord[u][0] * wMin; + span.texStep[u][0] = oneOverArea * (eMaj_ds * eBot.dy + - eMaj.dy * eBot_ds); + dsdy[u] = oneOverArea * (eMaj.dx * eBot_ds - eMaj_ds * eBot.dx); + + eMaj_dt = vMax->texcoord[u][1] * wMax + - vMin->texcoord[u][1] * wMin; + eBot_dt = vMid->texcoord[u][1] * wMid + - vMin->texcoord[u][1] * wMin; + span.texStep[u][1] = oneOverArea * (eMaj_dt * eBot.dy + - eMaj.dy * eBot_dt); + dtdy[u] = oneOverArea * (eMaj.dx * eBot_dt - eMaj_dt * eBot.dx); + + eMaj_du = vMax->texcoord[u][2] * wMax + - vMin->texcoord[u][2] * wMin; + eBot_du = vMid->texcoord[u][2] * wMid + - vMin->texcoord[u][2] * wMin; + span.texStep[u][2] = oneOverArea * (eMaj_du * eBot.dy + - eMaj.dy * eBot_du); + dudy[u] = oneOverArea * (eMaj.dx * eBot_du - eMaj_du * eBot.dx); + + eMaj_dv = vMax->texcoord[u][3] * wMax + - vMin->texcoord[u][3] * wMin; + eBot_dv = vMid->texcoord[u][3] * wMid + - vMin->texcoord[u][3] * wMin; + span.texStep[u][3] = oneOverArea * (eMaj_dv * eBot.dy + - eMaj.dy * eBot_dv); + dvdy[u] = oneOverArea * (eMaj.dx * eBot_dv - eMaj_dv * eBot.dx); +# ifdef INTERP_LAMBDA + { + GLfloat dudx = span.texStep[u][0] * span.texWidth[u]; + GLfloat dudy = dsdy[u] * span.texWidth[u]; + GLfloat dvdx = span.texStep[u][1] * span.texHeight[u]; + GLfloat dvdy = dtdy[u] * span.texHeight[u]; + GLfloat r1 = dudx * dudx + dudy * dudy; + GLfloat r2 = dvdx * dvdx + dvdy * dvdy; + span.rho[u] = r1 + r2; /* was rho2 = MAX2(r1,r2) */ + } +# endif + } + } + } +#endif + + /* + * We always sample at pixel centers. However, we avoid + * explicit half-pixel offsets in this code by incorporating + * the proper offset in each of x and y during the + * transformation to window coordinates. + * + * We also apply the usual rasterization rules to prevent + * cracks and overlaps. A pixel is considered inside a + * subtriangle if it meets all of four conditions: it is on or + * to the right of the left edge, strictly to the left of the + * right edge, on or below the top edge, and strictly above + * the bottom edge. (Some edges may be degenerate.) + * + * The following discussion assumes left-to-right scanning + * (that is, the major edge is on the left); the right-to-left + * case is a straightforward variation. + * + * We start by finding the half-integral y coordinate that is + * at or below the top of the triangle. This gives us the + * first scan line that could possibly contain pixels that are + * inside the triangle. + * + * Next we creep down the major edge until we reach that y, + * and compute the corresponding x coordinate on the edge. + * Then we find the half-integral x that lies on or just + * inside the edge. This is the first pixel that might lie in + * the interior of the triangle. (We won't know for sure + * until we check the other edges.) + * + * As we rasterize the triangle, we'll step down the major + * edge. For each step in y, we'll move an integer number + * of steps in x. There are two possible x step sizes, which + * we'll call the ``inner'' step (guaranteed to land on the + * edge or inside it) and the ``outer'' step (guaranteed to + * land on the edge or outside it). The inner and outer steps + * differ by one. During rasterization we maintain an error + * term that indicates our distance from the true edge, and + * select either the inner step or the outer step, whichever + * gets us to the first pixel that falls inside the triangle. + * + * All parameters (z, red, etc.) as well as the buffer + * addresses for color and z have inner and outer step values, + * so that we can increment them appropriately. This method + * eliminates the need to adjust parameters by creeping a + * sub-pixel amount into the triangle at each scanline. + */ + + { + int subTriangle; + GLfixed fx; + GLfixed fxLeftEdge, fxRightEdge, fdxLeftEdge, fdxRightEdge; + GLfixed fdxOuter; + int idxOuter; + float dxOuter; + GLfixed fError, fdError; + float adjx, adjy; + GLfixed fy; +#ifdef PIXEL_ADDRESS + PIXEL_TYPE *pRow; + int dPRowOuter, dPRowInner; /* offset in bytes */ +#endif +#ifdef INTERP_Z +# ifdef DEPTH_TYPE + DEPTH_TYPE *zRow; + int dZRowOuter, dZRowInner; /* offset in bytes */ +# endif + GLfixed fz, fdzOuter, fdzInner; +#endif +#ifdef INTERP_FOG + GLfloat fogLeft, dfogOuter, dfogInner; +#endif +#ifdef INTERP_RGB + GLfixed fr, fdrOuter, fdrInner; + GLfixed fg, fdgOuter, fdgInner; + GLfixed fb, fdbOuter, fdbInner; +#endif +#ifdef INTERP_ALPHA + GLfixed fa=0, fdaOuter=0, fdaInner; +#endif +#ifdef INTERP_SPEC + GLfixed fsr=0, fdsrOuter=0, fdsrInner; + GLfixed fsg=0, fdsgOuter=0, fdsgInner; + GLfixed fsb=0, fdsbOuter=0, fdsbInner; +#endif +#ifdef INTERP_INDEX + GLfixed fi=0, fdiOuter=0, fdiInner; +#endif +#ifdef INTERP_INT_TEX + GLfixed fs=0, fdsOuter=0, fdsInner; + GLfixed ft=0, fdtOuter=0, fdtInner; +#endif +#ifdef INTERP_TEX + GLfloat sLeft=0, dsOuter=0, dsInner; + GLfloat tLeft=0, dtOuter=0, dtInner; + GLfloat uLeft=0, duOuter=0, duInner; + GLfloat vLeft=0, dvOuter=0, dvInner; +#endif +#ifdef INTERP_MULTITEX + GLfloat sLeft[MAX_TEXTURE_UNITS]; + GLfloat tLeft[MAX_TEXTURE_UNITS]; + GLfloat uLeft[MAX_TEXTURE_UNITS]; + GLfloat vLeft[MAX_TEXTURE_UNITS]; + GLfloat dsOuter[MAX_TEXTURE_UNITS], dsInner[MAX_TEXTURE_UNITS]; + GLfloat dtOuter[MAX_TEXTURE_UNITS], dtInner[MAX_TEXTURE_UNITS]; + GLfloat duOuter[MAX_TEXTURE_UNITS], duInner[MAX_TEXTURE_UNITS]; + GLfloat dvOuter[MAX_TEXTURE_UNITS], dvInner[MAX_TEXTURE_UNITS]; +#endif + + for (subTriangle=0; subTriangle<=1; subTriangle++) { + EdgeT *eLeft, *eRight; + int setupLeft, setupRight; + int lines; + + if (subTriangle==0) { + /* bottom half */ + if (ltor) { + eLeft = &eMaj; + eRight = &eBot; + lines = eRight->lines; + setupLeft = 1; + setupRight = 1; + } + else { + eLeft = &eBot; + eRight = &eMaj; + lines = eLeft->lines; + setupLeft = 1; + setupRight = 1; + } + } + else { + /* top half */ + if (ltor) { + eLeft = &eMaj; + eRight = &eTop; + lines = eRight->lines; + setupLeft = 0; + setupRight = 1; + } + else { + eLeft = &eTop; + eRight = &eMaj; + lines = eLeft->lines; + setupLeft = 1; + setupRight = 0; + } + if (lines == 0) + return; + } + + if (setupLeft && eLeft->lines > 0) { + const SWvertex *vLower; + GLfixed fsx = eLeft->fsx; + fx = FixedCeil(fsx); + fError = fx - fsx - FIXED_ONE; + fxLeftEdge = fsx - FIXED_EPSILON; + fdxLeftEdge = eLeft->fdxdy; + fdxOuter = FixedFloor(fdxLeftEdge - FIXED_EPSILON); + fdError = fdxOuter - fdxLeftEdge + FIXED_ONE; + idxOuter = FixedToInt(fdxOuter); + dxOuter = (float) idxOuter; + (void) dxOuter; + + fy = eLeft->fsy; + span.y = FixedToInt(fy); + + adjx = (float)(fx - eLeft->fx0); /* SCALED! */ + adjy = eLeft->adjy; /* SCALED! */ + (void) adjx; /* silence compiler warnings */ + (void) adjy; /* silence compiler warnings */ + + vLower = eLeft->v0; + (void) vLower; /* silence compiler warnings */ + +#ifdef PIXEL_ADDRESS + { + pRow = (PIXEL_TYPE *) PIXEL_ADDRESS(FixedToInt(fxLeftEdge), span.y); + dPRowOuter = -((int)BYTES_PER_ROW) + idxOuter * sizeof(PIXEL_TYPE); + /* negative because Y=0 at bottom and increases upward */ + } +#endif + /* + * Now we need the set of parameter (z, color, etc.) values at + * the point (fx, fy). This gives us properly-sampled parameter + * values that we can step from pixel to pixel. Furthermore, + * although we might have intermediate results that overflow + * the normal parameter range when we step temporarily outside + * the triangle, we shouldn't overflow or underflow for any + * pixel that's actually inside the triangle. + */ + +#ifdef INTERP_Z + { + GLfloat z0 = vLower->win[2]; + if (depthBits <= 16) { + /* interpolate fixed-pt values */ + GLfloat tmp = (z0 * FIXED_SCALE + + dzdx * adjx + dzdy * adjy) + FIXED_HALF; + if (tmp < MAX_GLUINT / 2) + fz = (GLfixed) tmp; + else + fz = MAX_GLUINT / 2; + fdzOuter = SignedFloatToFixed(dzdy + dxOuter * dzdx); + } + else { + /* interpolate depth values exactly */ + fz = (GLint) (z0 + dzdx * FixedToFloat(adjx) + + dzdy * FixedToFloat(adjy)); + fdzOuter = (GLint) (dzdy + dxOuter * dzdx); + } +# ifdef DEPTH_TYPE + zRow = (DEPTH_TYPE *) + _mesa_zbuffer_address(ctx, FixedToInt(fxLeftEdge), span.y); + dZRowOuter = (ctx->DrawBuffer->Width + idxOuter) * sizeof(DEPTH_TYPE); +# endif + } +#endif +#ifdef INTERP_FOG + fogLeft = vLower->fog + (span.fogStep * adjx + dfogdy * adjy) + * (1.0F/FIXED_SCALE); + dfogOuter = dfogdy + dxOuter * span.fogStep; +#endif +#ifdef INTERP_RGB + fr = (GLfixed)(IntToFixed(vLower->color[0]) + + drdx * adjx + drdy * adjy) + FIXED_HALF; + fdrOuter = SignedFloatToFixed(drdy + dxOuter * drdx); + + fg = (GLfixed)(IntToFixed(vLower->color[1]) + + dgdx * adjx + dgdy * adjy) + FIXED_HALF; + fdgOuter = SignedFloatToFixed(dgdy + dxOuter * dgdx); + + fb = (GLfixed)(IntToFixed(vLower->color[2]) + + dbdx * adjx + dbdy * adjy) + FIXED_HALF; + fdbOuter = SignedFloatToFixed(dbdy + dxOuter * dbdx); +#endif +#ifdef INTERP_ALPHA + fa = (GLfixed)(IntToFixed(vLower->color[3]) + + dadx * adjx + dady * adjy) + FIXED_HALF; + fdaOuter = SignedFloatToFixed(dady + dxOuter * dadx); +#endif +#ifdef INTERP_SPEC + fsr = (GLfixed)(IntToFixed(vLower->specular[0]) + + dsrdx * adjx + dsrdy * adjy) + FIXED_HALF; + fdsrOuter = SignedFloatToFixed(dsrdy + dxOuter * dsrdx); + + fsg = (GLfixed)(IntToFixed(vLower->specular[1]) + + dsgdx * adjx + dsgdy * adjy) + FIXED_HALF; + fdsgOuter = SignedFloatToFixed(dsgdy + dxOuter * dsgdx); + + fsb = (GLfixed)(IntToFixed(vLower->specular[2]) + + dsbdx * adjx + dsbdy * adjy) + FIXED_HALF; + fdsbOuter = SignedFloatToFixed(dsbdy + dxOuter * dsbdx); +#endif +#ifdef INTERP_INDEX + fi = (GLfixed)(vLower->index * FIXED_SCALE + + didx * adjx + didy * adjy) + FIXED_HALF; + fdiOuter = SignedFloatToFixed(didy + dxOuter * didx); +#endif +#ifdef INTERP_INT_TEX + { + GLfloat s0, t0; + s0 = vLower->texcoord[0][0] * S_SCALE; + fs = (GLfixed)(s0 * FIXED_SCALE + dsdx * adjx + + dsdy * adjy) + FIXED_HALF; + fdsOuter = SignedFloatToFixed(dsdy + dxOuter * dsdx); + + t0 = vLower->texcoord[0][1] * T_SCALE; + ft = (GLfixed)(t0 * FIXED_SCALE + dtdx * adjx + + dtdy * adjy) + FIXED_HALF; + fdtOuter = SignedFloatToFixed(dtdy + dxOuter * dtdx); + } +#endif +#ifdef INTERP_TEX + { + GLfloat invW = vLower->win[3]; + GLfloat s0, t0, u0, v0; + s0 = vLower->texcoord[0][0] * invW; + sLeft = s0 + (span.texStep[0][0] * adjx + dsdy * adjy) + * (1.0F/FIXED_SCALE); + dsOuter = dsdy + dxOuter * span.texStep[0][0]; + t0 = vLower->texcoord[0][1] * invW; + tLeft = t0 + (span.texStep[0][1] * adjx + dtdy * adjy) + * (1.0F/FIXED_SCALE); + dtOuter = dtdy + dxOuter * span.texStep[0][1]; + u0 = vLower->texcoord[0][2] * invW; + uLeft = u0 + (span.texStep[0][2] * adjx + dudy * adjy) + * (1.0F/FIXED_SCALE); + duOuter = dudy + dxOuter * span.texStep[0][2]; + v0 = vLower->texcoord[0][3] * invW; + vLeft = v0 + (span.texStep[0][3] * adjx + dvdy * adjy) + * (1.0F/FIXED_SCALE); + dvOuter = dvdy + dxOuter * span.texStep[0][3]; + } +#endif +#ifdef INTERP_MULTITEX + { + GLuint u; + for (u = 0; u < ctx->Const.MaxTextureUnits; u++) { + if (ctx->Texture.Unit[u]._ReallyEnabled) { + GLfloat invW = vLower->win[3]; + GLfloat s0, t0, u0, v0; + s0 = vLower->texcoord[u][0] * invW; + sLeft[u] = s0 + (span.texStep[u][0] * adjx + dsdy[u] + * adjy) * (1.0F/FIXED_SCALE); + dsOuter[u] = dsdy[u] + dxOuter * span.texStep[u][0]; + t0 = vLower->texcoord[u][1] * invW; + tLeft[u] = t0 + (span.texStep[u][1] * adjx + dtdy[u] + * adjy) * (1.0F/FIXED_SCALE); + dtOuter[u] = dtdy[u] + dxOuter * span.texStep[u][1]; + u0 = vLower->texcoord[u][2] * invW; + uLeft[u] = u0 + (span.texStep[u][2] * adjx + dudy[u] + * adjy) * (1.0F/FIXED_SCALE); + duOuter[u] = dudy[u] + dxOuter * span.texStep[u][2]; + v0 = vLower->texcoord[u][3] * invW; + vLeft[u] = v0 + (span.texStep[u][3] * adjx + dvdy[u] + * adjy) * (1.0F/FIXED_SCALE); + dvOuter[u] = dvdy[u] + dxOuter * span.texStep[u][3]; + } + } + } +#endif + + } /*if setupLeft*/ + + + if (setupRight && eRight->lines>0) { + fxRightEdge = eRight->fsx - FIXED_EPSILON; + fdxRightEdge = eRight->fdxdy; + } + + if (lines==0) { + continue; + } + + + /* Rasterize setup */ +#ifdef PIXEL_ADDRESS + dPRowInner = dPRowOuter + sizeof(PIXEL_TYPE); +#endif +#ifdef INTERP_Z +# ifdef DEPTH_TYPE + dZRowInner = dZRowOuter + sizeof(DEPTH_TYPE); +# endif + fdzInner = fdzOuter + span.zStep; +#endif +#ifdef INTERP_FOG + dfogInner = dfogOuter + span.fogStep; +#endif +#ifdef INTERP_RGB + fdrInner = fdrOuter + span.redStep; + fdgInner = fdgOuter + span.greenStep; + fdbInner = fdbOuter + span.blueStep; +#endif +#ifdef INTERP_ALPHA + fdaInner = fdaOuter + span.alphaStep; +#endif +#ifdef INTERP_SPEC + fdsrInner = fdsrOuter + span.specRedStep; + fdsgInner = fdsgOuter + span.specGreenStep; + fdsbInner = fdsbOuter + span.specBlueStep; +#endif +#ifdef INTERP_INDEX + fdiInner = fdiOuter + span.indexStep; +#endif +#ifdef INTERP_INT_TEX + fdsInner = fdsOuter + span.intTexStep[0]; + fdtInner = fdtOuter + span.intTexStep[1]; +#endif +#ifdef INTERP_TEX + dsInner = dsOuter + span.texStep[0][0]; + dtInner = dtOuter + span.texStep[0][1]; + duInner = duOuter + span.texStep[0][2]; + dvInner = dvOuter + span.texStep[0][3]; +#endif +#ifdef INTERP_MULTITEX + { + GLuint u; + for (u = 0; u < ctx->Const.MaxTextureUnits; u++) { + if (ctx->Texture.Unit[u]._ReallyEnabled) { + dsInner[u] = dsOuter[u] + span.texStep[u][0]; + dtInner[u] = dtOuter[u] + span.texStep[u][1]; + duInner[u] = duOuter[u] + span.texStep[u][2]; + dvInner[u] = dvOuter[u] + span.texStep[u][3]; + } + } + } +#endif + + while (lines > 0) { + /* initialize the span interpolants to the leftmost value */ + /* ff = fixed-pt fragment */ + const GLint right = FixedToInt(fxRightEdge); + span.x = FixedToInt(fxLeftEdge); + if (right <= span.x) + span.count = 0; + else + span.count = right - span.x; + +#ifdef INTERP_Z + span.z = fz; +#endif +#ifdef INTERP_FOG + span.fog = fogLeft; +#endif +#ifdef INTERP_RGB + span.red = fr; + span.green = fg; + span.blue = fb; +#endif +#ifdef INTERP_ALPHA + span.alpha = fa; +#endif +#ifdef INTERP_SPEC + span.specRed = fsr; + span.specGreen = fsg; + span.specBlue = fsb; +#endif +#ifdef INTERP_INDEX + span.index = fi; +#endif +#ifdef INTERP_INT_TEX + span.intTex[0] = fs; + span.intTex[1] = ft; +#endif + +#ifdef INTERP_TEX + span.tex[0][0] = sLeft; + span.tex[0][1] = tLeft; + span.tex[0][2] = uLeft; + span.tex[0][3] = vLeft; +#endif + +#ifdef INTERP_MULTITEX + { + GLuint u; + for (u = 0; u < ctx->Const.MaxTextureUnits; u++) { + if (ctx->Texture.Unit[u]._ReallyEnabled) { + span.tex[u][0] = sLeft[u]; + span.tex[u][1] = tLeft[u]; + span.tex[u][2] = uLeft[u]; + span.tex[u][3] = vLeft[u]; + } + } + } +#endif + +#ifdef INTERP_RGB + { + /* need this to accomodate round-off errors */ + const GLint len = right - span.x - 1; + GLfixed ffrend = span.red + len * span.redStep; + GLfixed ffgend = span.green + len * span.greenStep; + GLfixed ffbend = span.blue + len * span.blueStep; + if (ffrend < 0) { + span.red -= ffrend; + if (span.red < 0) + span.red = 0; + } + if (ffgend < 0) { + span.green -= ffgend; + if (span.green < 0) + span.green = 0; + } + if (ffbend < 0) { + span.blue -= ffbend; + if (span.blue < 0) + span.blue = 0; + } + } +#endif +#ifdef INTERP_ALPHA + { + const GLint len = right - span.x - 1; + GLfixed ffaend = span.alpha + len * span.alphaStep; + if (ffaend < 0) { + span.alpha -= ffaend; + if (span.alpha < 0) + span.alpha = 0; + } + } +#endif +#ifdef INTERP_SPEC + { + /* need this to accomodate round-off errors */ + const GLint len = right - span.x - 1; + GLfixed ffsrend = span.specRed + len * span.specRedStep; + GLfixed ffsgend = span.specGreen + len * span.specGreenStep; + GLfixed ffsbend = span.specBlue + len * span.specBlueStep; + if (ffsrend < 0) { + span.specRed -= ffsrend; + if (span.specRed < 0) + span.specRed = 0; + } + if (ffsgend < 0) { + span.specGreen -= ffsgend; + if (span.specGreen < 0) + span.specGreen = 0; + } + if (ffsbend < 0) { + span.specBlue -= ffsbend; + if (span.specBlue < 0) + span.specBlue = 0; + } + } +#endif +#ifdef INTERP_INDEX + if (span.index < 0) span.index = 0; +#endif + + /* This is where we actually generate fragments */ + if (span.count > 0) { + RENDER_SPAN( span ); + } + + /* + * Advance to the next scan line. Compute the + * new edge coordinates, and adjust the + * pixel-center x coordinate so that it stays + * on or inside the major edge. + */ + span.y++; + lines--; + + fxLeftEdge += fdxLeftEdge; + fxRightEdge += fdxRightEdge; + + + fError += fdError; + if (fError >= 0) { + fError -= FIXED_ONE; +#ifdef PIXEL_ADDRESS + pRow = (PIXEL_TYPE *) ((GLubyte *) pRow + dPRowOuter); +#endif +#ifdef INTERP_Z +# ifdef DEPTH_TYPE + zRow = (DEPTH_TYPE *) ((GLubyte *) zRow + dZRowOuter); +# endif + fz += fdzOuter; +#endif +#ifdef INTERP_FOG + fogLeft += dfogOuter; +#endif +#ifdef INTERP_RGB + fr += fdrOuter; + fg += fdgOuter; + fb += fdbOuter; +#endif +#ifdef INTERP_ALPHA + fa += fdaOuter; +#endif +#ifdef INTERP_SPEC + fsr += fdsrOuter; + fsg += fdsgOuter; + fsb += fdsbOuter; +#endif +#ifdef INTERP_INDEX + fi += fdiOuter; +#endif +#ifdef INTERP_INT_TEX + fs += fdsOuter; + ft += fdtOuter; +#endif +#ifdef INTERP_TEX + sLeft += dsOuter; + tLeft += dtOuter; + uLeft += duOuter; + vLeft += dvOuter; +#endif +#ifdef INTERP_MULTITEX + { + GLuint u; + for (u = 0; u < ctx->Const.MaxTextureUnits; u++) { + if (ctx->Texture.Unit[u]._ReallyEnabled) { + sLeft[u] += dsOuter[u]; + tLeft[u] += dtOuter[u]; + uLeft[u] += duOuter[u]; + vLeft[u] += dvOuter[u]; + } + } + } +#endif + } + else { +#ifdef PIXEL_ADDRESS + pRow = (PIXEL_TYPE *) ((GLubyte *) pRow + dPRowInner); +#endif +#ifdef INTERP_Z +# ifdef DEPTH_TYPE + zRow = (DEPTH_TYPE *) ((GLubyte *) zRow + dZRowInner); +# endif + fz += fdzInner; +#endif +#ifdef INTERP_FOG + fogLeft += dfogInner; +#endif +#ifdef INTERP_RGB + fr += fdrInner; + fg += fdgInner; + fb += fdbInner; +#endif +#ifdef INTERP_ALPHA + fa += fdaInner; +#endif +#ifdef INTERP_SPEC + fsr += fdsrInner; + fsg += fdsgInner; + fsb += fdsbInner; +#endif +#ifdef INTERP_INDEX + fi += fdiInner; +#endif +#ifdef INTERP_INT_TEX + fs += fdsInner; + ft += fdtInner; +#endif +#ifdef INTERP_TEX + sLeft += dsInner; + tLeft += dtInner; + uLeft += duInner; + vLeft += dvInner; +#endif +#ifdef INTERP_MULTITEX + { + GLuint u; + for (u = 0; u < ctx->Const.MaxTextureUnits; u++) { + if (ctx->Texture.Unit[u]._ReallyEnabled) { + sLeft[u] += dsInner[u]; + tLeft[u] += dtInner[u]; + uLeft[u] += duInner[u]; + vLeft[u] += dvInner[u]; + } + } + } +#endif + } + } /*while lines>0*/ + + } /* for subTriangle */ + + } +#ifdef CLEANUP_CODE + CLEANUP_CODE +#endif + } +} + +#undef SETUP_CODE +#undef CLEANUP_CODE +#undef RENDER_SPAN + +#undef PIXEL_TYPE +#undef BYTES_PER_ROW +#undef PIXEL_ADDRESS + +#undef INTERP_Z +#undef INTERP_FOG +#undef INTERP_RGB +#undef INTERP_ALPHA +#undef INTERP_SPEC +#undef INTERP_INDEX +#undef INTERP_INT_TEX +#undef INTERP_TEX +#undef INTERP_MULTITEX +#undef INTERP_LAMBDA + +#undef S_SCALE +#undef T_SCALE + +#undef FixedToDepth + +#undef DO_OCCLUSION_TEST Index: dll/opengl/opengl32/mesa/swrast/s_zoom.c =================================================================== --- dll/opengl/opengl32/mesa/swrast/s_zoom.c (revision 0) +++ dll/opengl/opengl32/mesa/swrast/s_zoom.c (working copy) @@ -0,0 +1,453 @@ +/* $Id: s_zoom.c,v 1.6 2001/05/15 21:30:27 brianp Exp $ */ + +/* + * Mesa 3-D graphics library + * Version: 3.5 + * + * Copyright (C) 1999-2001 Brian Paul 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 + * BRIAN PAUL 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. + */ + +#include "glheader.h" +#include "macros.h" + +#include "s_context.h" +#include "s_span.h" +#include "s_stencil.h" +#include "s_zoom.h" + + + +/* + * Write a span of pixels to the frame buffer while applying a pixel zoom. + * This is only used by glDrawPixels and glCopyPixels. + * Input: n - number of pixels in input row + * x, y - destination of the span + * z - depth values for the span + * red, green, blue, alpha - array of colors + * y0 - location of first row in the image we're drawing. + */ +void +_mesa_write_zoomed_rgba_span( GLcontext *ctx, + GLuint n, GLint x, GLint y, const GLdepth z[], + const GLfloat *fog, + CONST GLchan rgba[][4], GLint y0 ) +{ + GLint m; + GLint r0, r1, row, r; + GLint i, j, skipcol; + GLchan zrgba[MAX_WIDTH][4]; /* zoomed pixel colors */ + GLdepth zdepth[MAX_WIDTH]; /* zoomed depth values */ + GLfloat zfog[MAX_WIDTH]; /* zoomed fog values */ + GLint maxwidth = MIN2( ctx->DrawBuffer->Width, MAX_WIDTH ); + const GLuint *srcRGBA32 = (const GLuint *) rgba; + GLuint *dstRGBA32 = (GLuint *) zrgba; + + /* compute width of output row */ + m = (GLint) ABSF( n * ctx->Pixel.ZoomX ); + if (m==0) { + return; + } + if (ctx->Pixel.ZoomX<0.0) { + /* adjust x coordinate for left/right mirroring */ + x = x - m; + } + + /* compute which rows to draw */ + row = y-y0; + r0 = y0 + (GLint) (row * ctx->Pixel.ZoomY); + r1 = y0 + (GLint) ((row+1) * ctx->Pixel.ZoomY); + if (r0==r1) { + return; + } + else if (r1=ctx->DrawBuffer->Height && r1>=ctx->DrawBuffer->Height) { + /* above window */ + return; + } + + /* check if left edge is outside window */ + skipcol = 0; + if (x<0) { + skipcol = -x; + m += x; + } + /* make sure span isn't too long or short */ + if (m>maxwidth) { + m = maxwidth; + } + else if (m<=0) { + return; + } + + assert( m <= MAX_WIDTH ); + + /* zoom the span horizontally */ + if (ctx->Pixel.ZoomX==-1.0F) { + /* n==m */ + for (j=0;jFog.Enabled) { + for (j=0;jPixel.ZoomX; + for (j=0;jFog.Enabled) { + for (j=0;jDrawBuffer->Width, MAX_WIDTH ); + + /* compute width of output row */ + m = (GLint) ABSF( n * ctx->Pixel.ZoomX ); + if (m==0) { + return; + } + if (ctx->Pixel.ZoomX<0.0) { + /* adjust x coordinate for left/right mirroring */ + x = x - m; + } + + /* compute which rows to draw */ + row = y-y0; + r0 = y0 + (GLint) (row * ctx->Pixel.ZoomY); + r1 = y0 + (GLint) ((row+1) * ctx->Pixel.ZoomY); + if (r0==r1) { + return; + } + else if (r1=ctx->DrawBuffer->Height && r1>=ctx->DrawBuffer->Height) { + /* above window */ + return; + } + + /* check if left edge is outside window */ + skipcol = 0; + if (x<0) { + skipcol = -x; + m += x; + } + /* make sure span isn't too long or short */ + if (m>maxwidth) { + m = maxwidth; + } + else if (m<=0) { + return; + } + + assert( m <= MAX_WIDTH ); + + /* zoom the span horizontally */ + if (ctx->Pixel.ZoomX==-1.0F) { + /* n==m */ + for (j=0;jFog.Enabled) { + for (j=0;jPixel.ZoomX; + for (j=0;jFog.Enabled) { + for (j=0;jDrawBuffer->Width, MAX_WIDTH ); + + /* compute width of output row */ + m = (GLint) ABSF( n * ctx->Pixel.ZoomX ); + if (m==0) { + return; + } + if (ctx->Pixel.ZoomX<0.0) { + /* adjust x coordinate for left/right mirroring */ + x = x - m; + } + + /* compute which rows to draw */ + row = y-y0; + r0 = y0 + (GLint) (row * ctx->Pixel.ZoomY); + r1 = y0 + (GLint) ((row+1) * ctx->Pixel.ZoomY); + if (r0==r1) { + return; + } + else if (r1=ctx->DrawBuffer->Height && r1>=ctx->DrawBuffer->Height) { + /* above window */ + return; + } + + /* check if left edge is outside window */ + skipcol = 0; + if (x<0) { + skipcol = -x; + m += x; + } + /* make sure span isn't too long or short */ + if (m>maxwidth) { + m = maxwidth; + } + else if (m<=0) { + return; + } + + assert( m <= MAX_WIDTH ); + + /* zoom the span horizontally */ + if (ctx->Pixel.ZoomX==-1.0F) { + /* n==m */ + for (j=0;jFog.Enabled) { + for (j=0;jPixel.ZoomX; + for (j=0;jFog.Enabled) { + for (j=0;jDrawBuffer->Width, MAX_WIDTH ); + + /* compute width of output row */ + m = (GLint) ABSF( n * ctx->Pixel.ZoomX ); + if (m==0) { + return; + } + if (ctx->Pixel.ZoomX<0.0) { + /* adjust x coordinate for left/right mirroring */ + x = x - m; + } + + /* compute which rows to draw */ + row = y-y0; + r0 = y0 + (GLint) (row * ctx->Pixel.ZoomY); + r1 = y0 + (GLint) ((row+1) * ctx->Pixel.ZoomY); + if (r0==r1) { + return; + } + else if (r1=ctx->DrawBuffer->Height && r1>=ctx->DrawBuffer->Height) { + /* above window */ + return; + } + + /* check if left edge is outside window */ + skipcol = 0; + if (x<0) { + skipcol = -x; + m += x; + } + /* make sure span isn't too long or short */ + if (m>maxwidth) { + m = maxwidth; + } + else if (m<=0) { + return; + } + + assert( m <= MAX_WIDTH ); + + /* zoom the span horizontally */ + if (ctx->Pixel.ZoomX==-1.0F) { + /* n==m */ + for (j=0;jPixel.ZoomX; + for (j=0;j + */ + +#ifndef SWRAST_H +#define SWRAST_H + +#include "mtypes.h" + + + +/* The software rasterizer now uses this format for vertices. Thus a + * 'RasterSetup' stage or other translation is required between the + * tnl module and the swrast rasterization functions. This serves to + * isolate the swrast module from the internals of the tnl module, and + * improve its usefulness as a fallback mechanism for hardware + * drivers. + * + * Full software drivers: + * - Register the rastersetup and triangle functions from + * utils/software_helper. + * - On statechange, update the rasterization pointers in that module. + * + * Rasterization hardware drivers: + * - Keep native rastersetup. + * - Implement native twoside,offset and unfilled triangle setup. + * - Implement a translator from native vertices to swrast vertices. + * - On partial fallback (mix of accelerated and unaccelerated + * prims), call a pass-through function which translates native + * vertices to SWvertices and calls the appropriate swrast function. + * - On total fallback (vertex format insufficient for state or all + * primitives unaccelerated), hook in swrast_setup instead. + */ +typedef struct { + GLfloat win[4]; + GLfloat texcoord[MAX_TEXTURE_UNITS][4]; + GLchan color[4]; + GLchan specular[4]; + GLfloat fog; + GLuint index; + GLfloat pointSize; +} SWvertex; + + +struct swrast_device_driver; + + +/* These are the public-access functions exported from swrast. + */ +extern void +_swrast_alloc_buffers( GLcontext *ctx ); + +extern GLboolean +_swrast_CreateContext( GLcontext *ctx ); + +extern void +_swrast_DestroyContext( GLcontext *ctx ); + +/* Get a (non-const) reference to the device driver struct for swrast. + */ +extern struct swrast_device_driver * +_swrast_GetDeviceDriverReference( GLcontext *ctx ); + +extern void +_swrast_Bitmap( GLcontext *ctx, + GLint px, GLint py, + GLsizei width, GLsizei height, + const struct gl_pixelstore_attrib *unpack, + const GLubyte *bitmap ); + +extern void +_swrast_CopyPixels( GLcontext *ctx, + GLint srcx, GLint srcy, + GLint destx, GLint desty, + GLsizei width, GLsizei height, + GLenum type ); + +extern void +_swrast_DrawPixels( GLcontext *ctx, + GLint x, GLint y, + GLsizei width, GLsizei height, + GLenum format, GLenum type, + const struct gl_pixelstore_attrib *unpack, + const GLvoid *pixels ); + +extern void +_swrast_ReadPixels( GLcontext *ctx, + GLint x, GLint y, GLsizei width, GLsizei height, + GLenum format, GLenum type, + const struct gl_pixelstore_attrib *unpack, + GLvoid *pixels ); + +extern void +_swrast_Clear( GLcontext *ctx, GLbitfield mask, GLboolean all, + GLint x, GLint y, GLint width, GLint height ); + +extern void +_swrast_Accum( GLcontext *ctx, GLenum op, + GLfloat value, GLint xpos, GLint ypos, + GLint width, GLint height ); + + +/* Reset the stipple counter + */ +extern void +_swrast_ResetLineStipple( GLcontext *ctx ); + +/* These will always render the correct point/line/triangle for the + * current state. + * + * For flatshaded primitives, the provoking vertex is the final one. + */ +extern void +_swrast_Point( GLcontext *ctx, const SWvertex *v ); + +extern void +_swrast_Line( GLcontext *ctx, const SWvertex *v0, const SWvertex *v1 ); + +extern void +_swrast_Triangle( GLcontext *ctx, const SWvertex *v0, + const SWvertex *v1, const SWvertex *v2 ); + +extern void +_swrast_Quad( GLcontext *ctx, + const SWvertex *v0, const SWvertex *v1, + const SWvertex *v2, const SWvertex *v3); + +extern void +_swrast_flush( GLcontext *ctx ); + + +/* Tell the software rasterizer about core state changes. + */ +extern void +_swrast_InvalidateState( GLcontext *ctx, GLuint new_state ); + +/* Configure software rasterizer to match hardware rasterizer characteristics: + */ +extern void +_swrast_allow_vertex_fog( GLcontext *ctx, GLboolean value ); + +extern void +_swrast_allow_pixel_fog( GLcontext *ctx, GLboolean value ); + +/* Debug: + */ +extern void +_swrast_print_vertex( GLcontext *ctx, const SWvertex *v ); + + +/* + * Imaging fallbacks (a better solution should be found, perhaps + * moving all the imaging fallback code to a new module) + */ +void +_swrast_CopyConvolutionFilter2D(GLcontext *ctx, GLenum target, + GLenum internalFormat, + GLint x, GLint y, GLsizei width, + GLsizei height); +void +_swrast_CopyConvolutionFilter1D(GLcontext *ctx, GLenum target, + GLenum internalFormat, + GLint x, GLint y, GLsizei width); +void +_swrast_CopyColorSubTable( GLcontext *ctx,GLenum target, GLsizei start, + GLint x, GLint y, GLsizei width); +void +_swrast_CopyColorTable( GLcontext *ctx, + GLenum target, GLenum internalformat, + GLint x, GLint y, GLsizei width); + + +/* + * Texture fallbacks, Brian Paul. Could also live in a new module + * with the rest of the texture store fallbacks? + */ +extern void +_swrast_copy_teximage1d(GLcontext *ctx, GLenum target, GLint level, + GLenum internalFormat, + GLint x, GLint y, GLsizei width, GLint border); + +extern void +_swrast_copy_teximage2d(GLcontext *ctx, GLenum target, GLint level, + GLenum internalFormat, + GLint x, GLint y, GLsizei width, GLsizei height, + GLint border); + + +extern void +_swrast_copy_texsubimage1d(GLcontext *ctx, GLenum target, GLint level, + GLint xoffset, GLint x, GLint y, GLsizei width); + +extern void +_swrast_copy_texsubimage2d(GLcontext *ctx, + GLenum target, GLint level, + GLint xoffset, GLint yoffset, + GLint x, GLint y, GLsizei width, GLsizei height); + +extern void +_swrast_copy_texsubimage3d(GLcontext *ctx, + GLenum target, GLint level, + GLint xoffset, GLint yoffset, GLint zoffset, + GLint x, GLint y, GLsizei width, GLsizei height); + + + +/* The driver interface for the software rasterizer. Unless otherwise + * noted, all functions are mandatory. + */ +struct swrast_device_driver { + + void (*SetReadBuffer)( GLcontext *ctx, GLframebuffer *colorBuffer, + GLenum buffer ); + /* + * Specifies the current buffer for span/pixel reading. + * colorBuffer will be one of: + * GL_FRONT_LEFT - this buffer always exists + * GL_BACK_LEFT - when double buffering + * GL_FRONT_RIGHT - when using stereo + * GL_BACK_RIGHT - when using stereo and double buffering + */ + + + /*** + *** Functions for synchronizing access to the framebuffer: + ***/ + + void (*SpanRenderStart)(GLcontext *ctx); + void (*SpanRenderFinish)(GLcontext *ctx); + /* OPTIONAL. + * + * Called before and after all rendering operations, including DrawPixels, + * ReadPixels, Bitmap, span functions, and CopyTexImage, etc commands. + * These are a suitable place for grabbing/releasing hardware locks. + * + * NOTE: The swrast triangle/line/point routines *DO NOT* call + * these functions. Locking in that case must be organized by the + * driver by other mechanisms. + */ + + /*** + *** Functions for writing pixels to the frame buffer: + ***/ + + void (*WriteRGBASpan)( const GLcontext *ctx, + GLuint n, GLint x, GLint y, + CONST GLchan rgba[][4], const GLubyte mask[] ); + void (*WriteRGBSpan)( const GLcontext *ctx, + GLuint n, GLint x, GLint y, + CONST GLchan rgb[][3], const GLubyte mask[] ); + /* Write a horizontal run of RGBA or RGB pixels. + * If mask is NULL, draw all pixels. + * If mask is not null, only draw pixel [i] when mask [i] is true. + */ + + void (*WriteMonoRGBASpan)( const GLcontext *ctx, GLuint n, GLint x, GLint y, + const GLchan color[4], const GLubyte mask[] ); + /* Write a horizontal run of RGBA pixels all with the same color. + */ + + void (*WriteRGBAPixels)( const GLcontext *ctx, + GLuint n, const GLint x[], const GLint y[], + CONST GLchan rgba[][4], const GLubyte mask[] ); + /* Write array of RGBA pixels at random locations. + */ + + void (*WriteMonoRGBAPixels)( const GLcontext *ctx, + GLuint n, const GLint x[], const GLint y[], + const GLchan color[4], const GLubyte mask[] ); + /* Write an array of mono-RGBA pixels at random locations. + */ + + void (*WriteCI32Span)( const GLcontext *ctx, GLuint n, GLint x, GLint y, + const GLuint index[], const GLubyte mask[] ); + void (*WriteCI8Span)( const GLcontext *ctx, GLuint n, GLint x, GLint y, + const GLubyte index[], const GLubyte mask[] ); + /* Write a horizontal run of CI pixels. One function is for 32bpp + * indexes and the other for 8bpp pixels (the common case). You mus + * implement both for color index mode. + */ + + void (*WriteMonoCISpan)( const GLcontext *ctx, GLuint n, GLint x, GLint y, + GLuint colorIndex, const GLubyte mask[] ); + /* Write a horizontal run of color index pixels using the color index + * last specified by the Index() function. + */ + + void (*WriteCI32Pixels)( const GLcontext *ctx, + GLuint n, const GLint x[], const GLint y[], + const GLuint index[], const GLubyte mask[] ); + /* + * Write a random array of CI pixels. + */ + + void (*WriteMonoCIPixels)( const GLcontext *ctx, + GLuint n, const GLint x[], const GLint y[], + GLuint colorIndex, const GLubyte mask[] ); + /* Write a random array of color index pixels using the color index + * last specified by the Index() function. + */ + + + /*** + *** Functions to read pixels from frame buffer: + ***/ + + void (*ReadCI32Span)( const GLcontext *ctx, + GLuint n, GLint x, GLint y, GLuint index[] ); + /* Read a horizontal run of color index pixels. + */ + + void (*ReadRGBASpan)( const GLcontext *ctx, GLuint n, GLint x, GLint y, + GLchan rgba[][4] ); + /* Read a horizontal run of RGBA pixels. + */ + + void (*ReadCI32Pixels)( const GLcontext *ctx, + GLuint n, const GLint x[], const GLint y[], + GLuint indx[], const GLubyte mask[] ); + /* Read a random array of CI pixels. + */ + + void (*ReadRGBAPixels)( const GLcontext *ctx, + GLuint n, const GLint x[], const GLint y[], + GLchan rgba[][4], const GLubyte mask[] ); + /* Read a random array of RGBA pixels. + */ + + + + /*** + *** For supporting hardware Z buffers: + *** Either ALL or NONE of these functions must be implemented! + *** NOTE that Each depth value is a 32-bit GLuint. If the depth + *** buffer is less than 32 bits deep then the extra upperbits are zero. + ***/ + + void (*WriteDepthSpan)( GLcontext *ctx, GLuint n, GLint x, GLint y, + const GLdepth depth[], const GLubyte mask[] ); + /* Write a horizontal span of values into the depth buffer. Only write + * depth[i] value if mask[i] is nonzero. + */ + + void (*ReadDepthSpan)( GLcontext *ctx, GLuint n, GLint x, GLint y, + GLdepth depth[] ); + /* Read a horizontal span of values from the depth buffer. + */ + + + void (*WriteDepthPixels)( GLcontext *ctx, GLuint n, + const GLint x[], const GLint y[], + const GLdepth depth[], const GLubyte mask[] ); + /* Write an array of randomly positioned depth values into the + * depth buffer. Only write depth[i] value if mask[i] is nonzero. + */ + + void (*ReadDepthPixels)( GLcontext *ctx, GLuint n, + const GLint x[], const GLint y[], + GLdepth depth[] ); + /* Read an array of randomly positioned depth values from the depth buffer. + */ + + + + /*** + *** For supporting hardware stencil buffers: + *** Either ALL or NONE of these functions must be implemented! + ***/ + + void (*WriteStencilSpan)( GLcontext *ctx, GLuint n, GLint x, GLint y, + const GLstencil stencil[], const GLubyte mask[] ); + /* Write a horizontal span of stencil values into the stencil buffer. + * If mask is NULL, write all stencil values. + * Else, only write stencil[i] if mask[i] is non-zero. + */ + + void (*ReadStencilSpan)( GLcontext *ctx, GLuint n, GLint x, GLint y, + GLstencil stencil[] ); + /* Read a horizontal span of stencil values from the stencil buffer. + */ + + void (*WriteStencilPixels)( GLcontext *ctx, GLuint n, + const GLint x[], const GLint y[], + const GLstencil stencil[], + const GLubyte mask[] ); + /* Write an array of stencil values into the stencil buffer. + * If mask is NULL, write all stencil values. + * Else, only write stencil[i] if mask[i] is non-zero. + */ + + void (*ReadStencilPixels)( GLcontext *ctx, GLuint n, + const GLint x[], const GLint y[], + GLstencil stencil[] ); + /* Read an array of stencil values from the stencil buffer. + */ +}; + + + +#endif Index: dll/opengl/opengl32/mesa/swrast_setup/ss_context.c =================================================================== --- dll/opengl/opengl32/mesa/swrast_setup/ss_context.c (revision 0) +++ dll/opengl/opengl32/mesa/swrast_setup/ss_context.c (working copy) @@ -0,0 +1,188 @@ +/* $Id: ss_context.c,v 1.13 2001/03/12 00:48:43 gareth Exp $ */ + +/* + * Mesa 3-D graphics library + * Version: 3.5 + * + * Copyright (C) 1999-2001 Brian Paul 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 + * BRIAN PAUL 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. + * + * Authors: + * Keith Whitwell + */ + +#include "glheader.h" +#include "mem.h" +#include "ss_context.h" +#include "ss_triangle.h" +#include "ss_vb.h" +#include "ss_interp.h" +#include "swrast_setup.h" +#include "tnl/t_context.h" + + +#define _SWSETUP_NEW_VERTS (_NEW_RENDERMODE| \ + _NEW_LIGHT| \ + _NEW_TEXTURE| \ + _NEW_COLOR| \ + _NEW_FOG| \ + _NEW_POINT) + +#define _SWSETUP_NEW_RENDERINDEX (_NEW_POLYGON|_NEW_LIGHT) + + +/* Dispatch from these fixed entrypoints to the state-dependent + * functions. + * + * The design of swsetup suggests that we could really program + * ctx->Driver.TriangleFunc directly from _swsetup_RenderStart, and + * avoid this second level of indirection. However, this is more + * convient for fallback cases in hardware rasterization drivers. + */ +void +_swsetup_Quad( GLcontext *ctx, GLuint v0, GLuint v1, + GLuint v2, GLuint v3 ) +{ + SWSETUP_CONTEXT(ctx)->Quad( ctx, v0, v1, v2, v3 ); +} + +void +_swsetup_Triangle( GLcontext *ctx, GLuint v0, GLuint v1, + GLuint v2 ) +{ + SWSETUP_CONTEXT(ctx)->Triangle( ctx, v0, v1, v2 ); +} + +void +_swsetup_Line( GLcontext *ctx, GLuint v0, GLuint v1 ) +{ + SWSETUP_CONTEXT(ctx)->Line( ctx, v0, v1 ); +} + +void +_swsetup_Points( GLcontext *ctx, GLuint first, GLuint last ) +{ + SWSETUP_CONTEXT(ctx)->Points( ctx, first, last ); +} + +void +_swsetup_BuildProjectedVertices( GLcontext *ctx, GLuint start, GLuint end, + GLuint new_inputs ) +{ + SWSETUP_CONTEXT(ctx)->BuildProjVerts( ctx, start, end, new_inputs ); +} + + +GLboolean +_swsetup_CreateContext( GLcontext *ctx ) +{ + TNLcontext *tnl = TNL_CONTEXT(ctx); + SScontext *swsetup = (SScontext *)CALLOC(sizeof(SScontext)); + + if (!swsetup) + return GL_FALSE; + + swsetup->verts = (SWvertex *) ALIGN_MALLOC( sizeof(SWvertex) * tnl->vb.Size, 32); + if (!swsetup->verts) { + FREE(swsetup); + return GL_FALSE; + } + + ctx->swsetup_context = swsetup; + + swsetup->NewState = ~0; + _swsetup_vb_init( ctx ); + _swsetup_interp_init( ctx ); + _swsetup_trifuncs_init( ctx ); + + return GL_TRUE; +} + +void +_swsetup_DestroyContext( GLcontext *ctx ) +{ + if (SWSETUP_CONTEXT(ctx)) { + if (SWSETUP_CONTEXT(ctx)->verts) + ALIGN_FREE(SWSETUP_CONTEXT(ctx)->verts); + + FREE(SWSETUP_CONTEXT(ctx)); + ctx->swsetup_context = 0; + } +} + +void +_swsetup_RenderPrimitive( GLcontext *ctx, GLenum mode ) +{ + SWSETUP_CONTEXT(ctx)->render_prim = mode; +} + +void +_swsetup_RenderStart( GLcontext *ctx ) +{ + SScontext *swsetup = SWSETUP_CONTEXT(ctx); + struct vertex_buffer *VB = &TNL_CONTEXT(ctx)->vb; + GLuint new_state = swsetup->NewState; + + if (new_state & _SWSETUP_NEW_RENDERINDEX) { + _swsetup_choose_trifuncs( ctx ); + } + + if (new_state & _SWSETUP_NEW_VERTS) { + _swsetup_choose_rastersetup_func( ctx ); + } + + swsetup->NewState = 0; + + if (VB->ClipMask && VB->importable_data) + VB->import_data( ctx, + VB->importable_data, + VEC_NOT_WRITEABLE|VEC_BAD_STRIDE); +} + +void +_swsetup_RenderFinish( GLcontext *ctx ) +{ + _swrast_flush( ctx ); +} + +void +_swsetup_InvalidateState( GLcontext *ctx, GLuint new_state ) +{ + SScontext *swsetup = SWSETUP_CONTEXT(ctx); + swsetup->NewState |= new_state; + + if (new_state & _SWSETUP_NEW_INTERP) { + swsetup->RenderInterp = _swsetup_validate_interp; + swsetup->RenderCopyPV = _swsetup_validate_copypv; + } +} + +void +_swsetup_RenderInterp( GLcontext *ctx, GLfloat t, + GLuint dst, GLuint out, GLuint in, + GLboolean force_boundary ) +{ + SWSETUP_CONTEXT(ctx)->RenderInterp( ctx, t, dst, out, in, force_boundary ); +} + +void +_swsetup_RenderCopyPV( GLcontext *ctx, GLuint dst, GLuint src ) +{ + SWSETUP_CONTEXT(ctx)->RenderCopyPV( ctx, dst, src ); +} Index: dll/opengl/opengl32/mesa/swrast_setup/ss_context.h =================================================================== --- dll/opengl/opengl32/mesa/swrast_setup/ss_context.h (revision 0) +++ dll/opengl/opengl32/mesa/swrast_setup/ss_context.h (working copy) @@ -0,0 +1,72 @@ +/* $Id: ss_context.h,v 1.7 2001/03/12 00:48:43 gareth Exp $ */ + +/* + * Mesa 3-D graphics library + * Version: 3.5 + * + * Copyright (C) 1999-2001 Brian Paul 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 + * BRIAN PAUL 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. + * + * Authors: + * Keith Whitwell + */ + +#ifndef SS_CONTEXT_H +#define SS_CONTEXT_H + +#include "mtypes.h" +#include "swrast/swrast.h" +#include "swrast_setup.h" + +typedef struct { + GLuint NewState; + GLuint StateChanges; + + /* Function hooks, trigger lazy state updates. + */ + void (*InvalidateState)( GLcontext *ctx, GLuint new_state ); + + void (*BuildProjVerts)( GLcontext *ctx, + GLuint start, GLuint end, GLuint new_inputs ); + + void (*Quad)( GLcontext *ctx, GLuint v0, GLuint v1, + GLuint v2, GLuint v3 ); + + void (*Triangle)( GLcontext *ctx, GLuint v0, GLuint v1, + GLuint v2 ); + + void (*Line)( GLcontext *ctx, GLuint v0, GLuint v1 ); + + void (*Points)( GLcontext *ctx, GLuint first, GLuint last ); + + void (*RenderCopyPV)( GLcontext *ctx, GLuint dst, GLuint src ); + + void (*RenderInterp)( GLcontext *ctx, GLfloat t, + GLuint dst, GLuint out, GLuint in, + GLboolean force_boundary ); + + + SWvertex *verts; + GLenum render_prim; + +} SScontext; + +#define SWSETUP_CONTEXT(ctx) ((SScontext *)ctx->swsetup_context) + +#endif Index: dll/opengl/opengl32/mesa/swrast_setup/ss_copytmp.h =================================================================== --- dll/opengl/opengl32/mesa/swrast_setup/ss_copytmp.h (revision 0) +++ dll/opengl/opengl32/mesa/swrast_setup/ss_copytmp.h (working copy) @@ -0,0 +1,70 @@ +/* $Id: ss_copytmp.h,v 1.4 2001/04/28 08:39:18 keithw Exp $ */ + +/* + * Mesa 3-D graphics library + * Version: 3.5 + * + * Copyright (C) 1999-2001 Brian Paul 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 + * BRIAN PAUL 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. + * + * Authors: + * Keith Whitwell + */ + + +static void NAME( GLcontext *ctx, GLuint dst, GLuint src ) +{ + struct vertex_buffer *VB = &TNL_CONTEXT(ctx)->vb; + + /* For flatshading, copy the 'out' values to the new vertex. This + * guarentees that if the pv is clipped away, its colors are copied + * to any vertex that replaces it. + */ + if (IND & INTERP_RGBA) { + COPY_4FV( GET_COLOR(VB->ColorPtr[0], dst), + GET_COLOR(VB->ColorPtr[0], src) ); + + if (VB->ColorPtr[1]) { + COPY_4FV( GET_COLOR(VB->ColorPtr[1], dst), + GET_COLOR(VB->ColorPtr[1], src) ); + } + } + + if (IND & INTERP_SPEC) { + COPY_4FV( GET_COLOR(VB->SecondaryColorPtr[0], dst), + GET_COLOR(VB->SecondaryColorPtr[0], src) ); + + if (VB->SecondaryColorPtr[1]) { + COPY_4FV( GET_COLOR(VB->SecondaryColorPtr[1], dst), + GET_COLOR(VB->SecondaryColorPtr[1], src) ); + } + } + + if (IND & INTERP_INDEX) { + VB->IndexPtr[0]->data[dst] = VB->IndexPtr[0]->data[src]; + + if (VB->IndexPtr[1]) + VB->IndexPtr[1]->data[dst] = VB->IndexPtr[1]->data[src]; + } + +} + + +#undef IND +#undef NAME Index: dll/opengl/opengl32/mesa/swrast_setup/ss_interp.c =================================================================== --- dll/opengl/opengl32/mesa/swrast_setup/ss_interp.c (revision 0) +++ dll/opengl/opengl32/mesa/swrast_setup/ss_interp.c (working copy) @@ -0,0 +1,405 @@ +/* $Id: ss_interp.c,v 1.6 2001/04/28 08:39:18 keithw Exp $ */ + +/* + * Mesa 3-D graphics library + * Version: 3.5 + * + * Copyright (C) 1999-2001 Brian Paul 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 + * BRIAN PAUL 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. + */ + +#include "glheader.h" +#include "context.h" +#include "colormac.h" +#include "macros.h" +#include "mem.h" +#include "mtypes.h" +#include "mmath.h" + +#include "tnl/t_context.h" +#include "swrast_setup/ss_context.h" +#include "swrast_setup/ss_interp.h" + +/**********************************************************************/ +/* Interpolate between pairs of vertices */ +/**********************************************************************/ + + +#define GET_COLOR(ptr, idx) (((GLfloat (*)[4])((ptr)->Ptr))[idx]) + + + +#define INTERP_RGBA 0x1 +#define INTERP_TEX 0x2 +#define INTERP_INDEX 0x4 +#define INTERP_SPEC 0x8 +#define INTERP_FOG 0x10 +#define INTERP_EDGE 0x20 +#define MAX_INTERP 0x40 + +static interp_func interp_tab[MAX_INTERP]; +static copy_pv_func copy_tab[MAX_INTERP]; + + +#define IND (0) +#define NAME interp_none +#include "ss_interptmp.h" + +#define IND (INTERP_FOG) +#define NAME interp_FOG +#include "ss_interptmp.h" + +#define IND (INTERP_TEX) +#define NAME interp_TEX +#include "ss_interptmp.h" + +#define IND (INTERP_FOG|INTERP_TEX) +#define NAME interp_FOG_TEX +#include "ss_interptmp.h" + +#define IND (INTERP_EDGE) +#define NAME interp_EDGE +#include "ss_interptmp.h" + +#define IND (INTERP_FOG|INTERP_EDGE) +#define NAME interp_FOG_EDGE +#include "ss_interptmp.h" + +#define IND (INTERP_TEX|INTERP_EDGE) +#define NAME interp_TEX_EDGE +#include "ss_interptmp.h" + +#define IND (INTERP_FOG|INTERP_TEX|INTERP_EDGE) +#define NAME interp_FOG_TEX_EDGE +#include "ss_interptmp.h" + +#define IND (INTERP_RGBA) +#define NAME interp_RGBA +#include "ss_interptmp.h" + +#define IND (INTERP_RGBA|INTERP_SPEC) +#define NAME interp_RGBA_SPEC +#include "ss_interptmp.h" + +#define IND (INTERP_RGBA|INTERP_FOG) +#define NAME interp_RGBA_FOG +#include "ss_interptmp.h" + +#define IND (INTERP_RGBA|INTERP_SPEC|INTERP_FOG) +#define NAME interp_RGBA_SPEC_FOG +#include "ss_interptmp.h" + +#define IND (INTERP_RGBA|INTERP_TEX) +#define NAME interp_RGBA_TEX +#include "ss_interptmp.h" + +#define IND (INTERP_RGBA|INTERP_SPEC|INTERP_TEX) +#define NAME interp_RGBA_SPEC_TEX +#include "ss_interptmp.h" + +#define IND (INTERP_RGBA|INTERP_FOG|INTERP_TEX) +#define NAME interp_RGBA_FOG_TEX +#include "ss_interptmp.h" + +#define IND (INTERP_RGBA|INTERP_SPEC|INTERP_FOG|INTERP_TEX) +#define NAME interp_RGBA_SPEC_FOG_TEX +#include "ss_interptmp.h" + +#define IND (INTERP_INDEX) +#define NAME interp_INDEX +#include "ss_interptmp.h" + +#define IND (INTERP_FOG|INTERP_INDEX) +#define NAME interp_FOG_INDEX +#include "ss_interptmp.h" + +#define IND (INTERP_TEX|INTERP_INDEX) +#define NAME interp_TEX_INDEX +#include "ss_interptmp.h" + +#define IND (INTERP_FOG|INTERP_TEX|INTERP_INDEX) +#define NAME interp_FOG_TEX_INDEX +#include "ss_interptmp.h" + +#define IND (INTERP_RGBA|INTERP_EDGE) +#define NAME interp_RGBA_EDGE +#include "ss_interptmp.h" + +#define IND (INTERP_RGBA|INTERP_SPEC|INTERP_EDGE) +#define NAME interp_RGBA_SPEC_EDGE +#include "ss_interptmp.h" + +#define IND (INTERP_RGBA|INTERP_FOG|INTERP_EDGE) +#define NAME interp_RGBA_FOG_EDGE +#include "ss_interptmp.h" + +#define IND (INTERP_RGBA|INTERP_SPEC|INTERP_FOG|INTERP_EDGE) +#define NAME interp_RGBA_SPEC_FOG_EDGE +#include "ss_interptmp.h" + +#define IND (INTERP_RGBA|INTERP_TEX|INTERP_EDGE) +#define NAME interp_RGBA_TEX_EDGE +#include "ss_interptmp.h" + +#define IND (INTERP_RGBA|INTERP_SPEC|INTERP_TEX|INTERP_EDGE) +#define NAME interp_RGBA_SPEC_TEX_EDGE +#include "ss_interptmp.h" + +#define IND (INTERP_RGBA|INTERP_FOG|INTERP_TEX|INTERP_EDGE) +#define NAME interp_RGBA_FOG_TEX_EDGE +#include "ss_interptmp.h" + +#define IND (INTERP_RGBA|INTERP_SPEC|INTERP_FOG|INTERP_TEX|INTERP_EDGE) +#define NAME interp_RGBA_SPEC_FOG_TEX_EDGE +#include "ss_interptmp.h" + +#define IND (INTERP_INDEX|INTERP_EDGE) +#define NAME interp_INDEX_EDGE +#include "ss_interptmp.h" + +#define IND (INTERP_FOG|INTERP_INDEX|INTERP_EDGE) +#define NAME interp_FOG_INDEX_EDGE +#include "ss_interptmp.h" + +#define IND (INTERP_TEX|INTERP_INDEX|INTERP_EDGE) +#define NAME interp_TEX_INDEX_EDGE +#include "ss_interptmp.h" + +#define IND (INTERP_FOG|INTERP_TEX|INTERP_INDEX|INTERP_EDGE) +#define NAME interp_FOG_TEX_INDEX_EDGE +#include "ss_interptmp.h" + + +#define IND (INTERP_RGBA) +#define NAME copy_RGBA +#include "ss_copytmp.h" + +#define IND (INTERP_RGBA|INTERP_SPEC) +#define NAME copy_RGBA_SPEC +#include "ss_copytmp.h" + +#define IND (INTERP_INDEX) +#define NAME copy_INDEX +#include "ss_copytmp.h" + + + + +static void interp_invalid( GLcontext *ctx, + GLfloat t, + GLuint dst, GLuint in, GLuint out, + GLboolean boundary ) +{ + (void)(ctx && t && in && out && boundary); + fprintf(stderr, "Invalid interpolation function in t_vbrender.c\n"); +} + +static void copy_invalid( GLcontext *ctx, GLuint dst, GLuint src ) +{ + (void)(ctx && dst && src); + fprintf(stderr, "Invalid copy function in t_vbrender.c\n"); +} + + +void _swsetup_interp_init( GLcontext *ctx ) +{ + static int firsttime = 1; + GLuint i; + + SWSETUP_CONTEXT(ctx)->RenderInterp = _swsetup_validate_interp; + SWSETUP_CONTEXT(ctx)->RenderCopyPV = _swsetup_validate_copypv; + + if (firsttime == 0) + return; + firsttime = 0; + + /* Use the maximal function as the default. I don't believe any of + * the non-implemented combinations are reachable, but this gives + * some safety from crashes. + */ + for (i = 0 ; i < Elements(interp_tab) ; i++) { + interp_tab[i] = interp_invalid; + copy_tab[i] = copy_invalid; + } + + interp_tab[0] = interp_none; + interp_tab[INTERP_FOG] = interp_FOG; + interp_tab[INTERP_TEX] = interp_TEX; + interp_tab[INTERP_FOG|INTERP_TEX] = interp_FOG_TEX; + interp_tab[INTERP_EDGE] = interp_EDGE; + interp_tab[INTERP_FOG|INTERP_EDGE] = interp_FOG_EDGE; + interp_tab[INTERP_TEX|INTERP_EDGE] = interp_TEX_EDGE; + interp_tab[INTERP_FOG|INTERP_TEX|INTERP_EDGE] = interp_FOG_TEX_EDGE; + + interp_tab[INTERP_RGBA] = interp_RGBA; + interp_tab[INTERP_RGBA|INTERP_SPEC] = interp_RGBA_SPEC; + interp_tab[INTERP_RGBA|INTERP_FOG] = interp_RGBA_FOG; + interp_tab[INTERP_RGBA|INTERP_SPEC|INTERP_FOG] = interp_RGBA_SPEC_FOG; + interp_tab[INTERP_RGBA|INTERP_TEX] = interp_RGBA_TEX; + interp_tab[INTERP_RGBA|INTERP_SPEC|INTERP_TEX] = interp_RGBA_SPEC_TEX; + interp_tab[INTERP_RGBA|INTERP_FOG|INTERP_TEX] = interp_RGBA_FOG_TEX; + interp_tab[INTERP_RGBA|INTERP_SPEC|INTERP_FOG|INTERP_TEX] = + interp_RGBA_SPEC_FOG_TEX; + interp_tab[INTERP_INDEX] = interp_INDEX; + interp_tab[INTERP_FOG|INTERP_INDEX] = interp_FOG_INDEX; + interp_tab[INTERP_TEX|INTERP_INDEX] = interp_TEX_INDEX; + interp_tab[INTERP_FOG|INTERP_TEX|INTERP_INDEX] = interp_FOG_TEX_INDEX; + interp_tab[INTERP_RGBA|INTERP_EDGE] = interp_RGBA_EDGE; + interp_tab[INTERP_RGBA|INTERP_SPEC|INTERP_EDGE] = interp_RGBA_SPEC_EDGE; + interp_tab[INTERP_RGBA|INTERP_FOG|INTERP_EDGE] = interp_RGBA_FOG_EDGE; + interp_tab[INTERP_RGBA|INTERP_SPEC|INTERP_FOG|INTERP_EDGE] = + interp_RGBA_SPEC_FOG_EDGE; + interp_tab[INTERP_RGBA|INTERP_TEX|INTERP_EDGE] = interp_RGBA_TEX_EDGE; + interp_tab[INTERP_RGBA|INTERP_SPEC|INTERP_TEX|INTERP_EDGE] = + interp_RGBA_SPEC_TEX_EDGE; + interp_tab[INTERP_RGBA|INTERP_FOG|INTERP_TEX|INTERP_EDGE] = + interp_RGBA_FOG_TEX_EDGE; + interp_tab[INTERP_RGBA|INTERP_SPEC|INTERP_FOG|INTERP_TEX|INTERP_EDGE] = + interp_RGBA_SPEC_FOG_TEX_EDGE; + interp_tab[INTERP_INDEX|INTERP_EDGE] = interp_INDEX_EDGE; + interp_tab[INTERP_FOG|INTERP_INDEX|INTERP_EDGE] = interp_FOG_INDEX_EDGE; + interp_tab[INTERP_TEX|INTERP_INDEX|INTERP_EDGE] = interp_TEX_INDEX_EDGE; + interp_tab[INTERP_FOG|INTERP_TEX|INTERP_INDEX|INTERP_EDGE] = + interp_FOG_TEX_INDEX_EDGE; + + + copy_tab[INTERP_RGBA] = copy_RGBA; + copy_tab[INTERP_RGBA|INTERP_SPEC] = copy_RGBA_SPEC; + copy_tab[INTERP_INDEX] = copy_INDEX; +} + +static void choose_copy_interp( GLcontext *ctx ) +{ + GLuint interp = 0; + GLuint copy = 0; + + if (ctx->Visual.rgbMode) + { + interp |= INTERP_RGBA; + + if (ctx->_TriangleCaps & DD_SEPARATE_SPECULAR) { + interp |= INTERP_SPEC; + } + + if (ctx->Texture._ReallyEnabled) { + interp |= INTERP_TEX; + } + } + else { + interp |= INTERP_INDEX; + } + + if (ctx->Fog.Enabled) { + interp |= INTERP_FOG; + } + + if (ctx->_TriangleCaps & DD_TRI_UNFILLED) { + interp |= INTERP_EDGE; + } + + if (ctx->RenderMode==GL_FEEDBACK) { + interp |= INTERP_TEX; + } + + if (ctx->_TriangleCaps & DD_FLATSHADE) { + copy = interp & (INTERP_RGBA|INTERP_SPEC|INTERP_INDEX); + interp &= ~copy; + } + + SWSETUP_CONTEXT(ctx)->RenderCopyPV = copy_tab[copy]; + SWSETUP_CONTEXT(ctx)->RenderInterp = interp_tab[interp]; +} + + +void _swsetup_validate_interp( GLcontext *ctx, GLfloat t, + GLuint dst, GLuint out, GLuint in, + GLboolean force_boundary ) +{ + choose_copy_interp( ctx ); + SWSETUP_CONTEXT(ctx)->RenderInterp( ctx, t, dst, out, in, force_boundary ); +} + +void _swsetup_validate_copypv( GLcontext *ctx, GLuint dst, GLuint src ) +{ + choose_copy_interp( ctx ); + SWSETUP_CONTEXT(ctx)->RenderCopyPV( ctx, dst, src ); +} + +void _swsetup_RenderProjectInterpVerts( GLcontext *ctx ) +{ + TNLcontext *tnl = TNL_CONTEXT(ctx); + struct vertex_buffer *VB = &tnl->vb; + + + /* Populate VB->ProjectedClipPtr if necessary. + */ + if (VB->ProjectedClipPtr) { + GLfloat (*clip)[4] = VB->ClipPtr->data; + GLfloat (*proj)[4] = VB->ProjectedClipPtr->data; + GLuint last = VB->LastClipped; + GLuint size = VB->ClipPtr->size; + GLuint i; + + if (size == 4) { + for (i = VB->FirstClipped; i < last; i++) { + if (VB->ClipMask[i] == 0 && clip[i][3] != 0.0F) { + GLfloat wInv = 1.0F / clip[i][3]; + proj[i][0] = clip[i][0] * wInv; + proj[i][1] = clip[i][1] * wInv; + proj[i][2] = clip[i][2] * wInv; + proj[i][3] = wInv; + } + } + } else if (VB->ClipPtr != VB->ProjectedClipPtr) { + for (i = VB->FirstClipped; i < last; i++) { + COPY_4FV( proj[i], clip[i] ); + } + } + } + + tnl->Driver.BuildProjectedVertices(ctx, + VB->FirstClipped, + VB->LastClipped, + ~0); +} + +void _swsetup_RenderClippedPolygon( GLcontext *ctx, const GLuint *elts, + GLuint n ) +{ + TNLcontext *tnl = TNL_CONTEXT(ctx); + struct vertex_buffer *VB = &tnl->vb; + + _swsetup_RenderProjectInterpVerts( ctx ); + + /* Render the new vertices as an unclipped polygon. + */ + { + GLuint *tmp = VB->Elts; + VB->Elts = (GLuint *)elts; + tnl->Driver.RenderTabElts[GL_POLYGON]( ctx, 0, n, PRIM_BEGIN|PRIM_END ); + VB->Elts = tmp; + } +} + +void _swsetup_RenderClippedLine( GLcontext *ctx, GLuint ii, GLuint jj ) +{ + TNLcontext *tnl = TNL_CONTEXT(ctx); + _swsetup_RenderProjectInterpVerts( ctx ); + tnl->Driver.LineFunc( ctx, ii, jj ); +} Index: dll/opengl/opengl32/mesa/swrast_setup/ss_interp.h =================================================================== --- dll/opengl/opengl32/mesa/swrast_setup/ss_interp.h (revision 0) +++ dll/opengl/opengl32/mesa/swrast_setup/ss_interp.h (working copy) @@ -0,0 +1,53 @@ +/* $Id: ss_interp.h,v 1.3 2001/03/29 16:50:33 brianp Exp $ */ + +/* + * Mesa 3-D graphics library + * Version: 3.5 + * + * Copyright (C) 1999-2001 Brian Paul 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 + * BRIAN PAUL 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. + * + * Authors: + * Keith Whitwell + */ + +#ifndef SS_INTERP_H +#define SS_INTERP_H + +#include "mtypes.h" +#include "swrast_setup.h" + +void _swsetup_interp_init( GLcontext *ctx ); + +#define _SWSETUP_NEW_INTERP (_NEW_BUFFERS | \ + _DD_NEW_SEPARATE_SPECULAR | \ + _NEW_TEXTURE| \ + _NEW_FOG| \ + _DD_NEW_TRI_UNFILLED | \ + _NEW_RENDERMODE | \ + _DD_NEW_FLATSHADE) + +void _swsetup_validate_interp( GLcontext *ctx, GLfloat t, + GLuint dst, GLuint out, GLuint in, + GLboolean force_boundary ); + +void _swsetup_validate_copypv( GLcontext *ctx, GLuint dst, GLuint src ); + + +#endif Index: dll/opengl/opengl32/mesa/swrast_setup/ss_interptmp.h =================================================================== --- dll/opengl/opengl32/mesa/swrast_setup/ss_interptmp.h (revision 0) +++ dll/opengl/opengl32/mesa/swrast_setup/ss_interptmp.h (working copy) @@ -0,0 +1,106 @@ +/* $Id: ss_interptmp.h,v 1.3 2001/04/28 08:39:18 keithw Exp $ */ + +/* + * Mesa 3-D graphics library + * Version: 3.5 + * + * Copyright (C) 1999-2001 Brian Paul 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 + * BRIAN PAUL 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. + * + * Authors: + * Keith Whitwell + */ + +static void NAME( GLcontext *ctx, + GLfloat t, + GLuint dst, GLuint out, GLuint in, + GLboolean force_boundary ) +{ + struct vertex_buffer *VB = &TNL_CONTEXT(ctx)->vb; + + if (IND & INTERP_RGBA) { + ASSERT(VB->ColorPtr[0]->Ptr != ctx->Array.Color.Ptr); + INTERP_4F( t, + GET_COLOR(VB->ColorPtr[0], dst), + GET_COLOR(VB->ColorPtr[0], out), + GET_COLOR(VB->ColorPtr[0], in) ); + + if (ctx->_TriangleCaps & DD_TRI_LIGHT_TWOSIDE) { + INTERP_4F( t, + GET_COLOR(VB->ColorPtr[1], dst), + GET_COLOR(VB->ColorPtr[1], out), + GET_COLOR(VB->ColorPtr[1], in) ); + } + + if (IND & INTERP_SPEC) { + INTERP_3F( t, + GET_COLOR(VB->SecondaryColorPtr[0], dst), + GET_COLOR(VB->SecondaryColorPtr[0], out), + GET_COLOR(VB->SecondaryColorPtr[0], in) ); + + if (ctx->_TriangleCaps & DD_TRI_LIGHT_TWOSIDE) { + INTERP_3F( t, + GET_COLOR(VB->SecondaryColorPtr[1], dst), + GET_COLOR(VB->SecondaryColorPtr[1], out), + GET_COLOR(VB->SecondaryColorPtr[1], in) ); + } + } + } + + if (IND & INTERP_INDEX) { + VB->IndexPtr[0]->data[dst] = (GLuint) (GLint) + LINTERP( t, + (GLfloat) VB->IndexPtr[0]->data[out], + (GLfloat) VB->IndexPtr[0]->data[in] ); + + if (ctx->_TriangleCaps & DD_TRI_LIGHT_TWOSIDE) + VB->IndexPtr[1]->data[dst] = (GLuint) (GLint) + LINTERP( t, + (GLfloat) VB->IndexPtr[1]->data[out], + (GLfloat) VB->IndexPtr[1]->data[in] ); + } + + if (IND & INTERP_TEX) { + GLuint i; + for (i = 0 ; i < ctx->Const.MaxTextureUnits ; i++) { + if (ctx->Texture.Unit[i]._ReallyEnabled) { + INTERP_SZ( t, + VB->TexCoordPtr[i]->data, + dst, out, in, + VB->TexCoordPtr[i]->size ); + } + } + } + + if (IND & INTERP_FOG) { + VB->FogCoordPtr->data[dst] = + LINTERP( t, + VB->FogCoordPtr->data[out], + VB->FogCoordPtr->data[in] ); + } + + + if (IND & INTERP_EDGE) { + VB->EdgeFlag[dst] = VB->EdgeFlag[out] || force_boundary; + } +} + + +#undef IND +#undef NAME Index: dll/opengl/opengl32/mesa/swrast_setup/ss_triangle.c =================================================================== --- dll/opengl/opengl32/mesa/swrast_setup/ss_triangle.c (revision 0) +++ dll/opengl/opengl32/mesa/swrast_setup/ss_triangle.c (working copy) @@ -0,0 +1,284 @@ +/* $Id: ss_triangle.c,v 1.13 2001/04/28 08:39:18 keithw Exp $ */ + +/* + * Mesa 3-D graphics library + * Version: 3.5 + * + * Copyright (C) 1999-2001 Brian Paul 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 + * BRIAN PAUL 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. + * + * Authors: + * Keith Whitwell + */ + +#include "glheader.h" +#include "colormac.h" +#include "macros.h" +#include "mtypes.h" + +#include "tnl/t_context.h" + +#include "ss_triangle.h" +#include "ss_context.h" + +#define SS_RGBA_BIT 0x1 +#define SS_OFFSET_BIT 0x2 +#define SS_TWOSIDE_BIT 0x4 +#define SS_UNFILLED_BIT 0x8 +#define SS_MAX_TRIFUNC 0x10 + +static triangle_func tri_tab[SS_MAX_TRIFUNC]; +static quad_func quad_tab[SS_MAX_TRIFUNC]; + + +static void _swsetup_render_line_tri( GLcontext *ctx, + GLuint e0, GLuint e1, GLuint e2 ) +{ + SScontext *swsetup = SWSETUP_CONTEXT(ctx); + struct vertex_buffer *VB = &TNL_CONTEXT(ctx)->vb; + GLubyte *ef = VB->EdgeFlag; + SWvertex *verts = swsetup->verts; + SWvertex *v0 = &verts[e0]; + SWvertex *v1 = &verts[e1]; + SWvertex *v2 = &verts[e2]; + GLchan c[2][4]; + GLchan s[2][4]; + GLuint i[2]; + + if (ctx->_TriangleCaps & DD_FLATSHADE) { + COPY_CHAN4(c[0], v0->color); + COPY_CHAN4(c[1], v1->color); + COPY_CHAN4(s[0], v0->specular); + COPY_CHAN4(s[1], v1->specular); + i[0] = v0->index; + i[1] = v1->index; + + COPY_CHAN4(v0->color, v2->color); + COPY_CHAN4(v1->color, v2->color); + COPY_CHAN4(v0->specular, v2->specular); + COPY_CHAN4(v1->specular, v2->specular); + v0->index = v2->index; + v1->index = v2->index; + } + + if (swsetup->render_prim == GL_POLYGON) { + if (ef[e2]) _swrast_Line( ctx, v2, v0 ); + if (ef[e0]) _swrast_Line( ctx, v0, v1 ); + if (ef[e1]) _swrast_Line( ctx, v1, v2 ); + } else { + if (ef[e0]) _swrast_Line( ctx, v0, v1 ); + if (ef[e1]) _swrast_Line( ctx, v1, v2 ); + if (ef[e2]) _swrast_Line( ctx, v2, v0 ); + } + + if (ctx->_TriangleCaps & DD_FLATSHADE) { + COPY_CHAN4(v0->color, c[0]); + COPY_CHAN4(v1->color, c[1]); + COPY_CHAN4(v0->specular, s[0]); + COPY_CHAN4(v1->specular, s[1]); + v0->index = i[0]; + v1->index = i[1]; + } +} + +static void _swsetup_render_point_tri( GLcontext *ctx, + GLuint e0, GLuint e1, GLuint e2 ) +{ + SScontext *swsetup = SWSETUP_CONTEXT(ctx); + struct vertex_buffer *VB = &TNL_CONTEXT(ctx)->vb; + GLubyte *ef = VB->EdgeFlag; + SWvertex *verts = swsetup->verts; + SWvertex *v0 = &verts[e0]; + SWvertex *v1 = &verts[e1]; + SWvertex *v2 = &verts[e2]; + GLchan c[2][4]; + GLchan s[2][4]; + GLuint i[2]; + + if (ctx->_TriangleCaps & DD_FLATSHADE) { + COPY_CHAN4(c[0], v0->color); + COPY_CHAN4(c[1], v1->color); + COPY_CHAN4(s[0], v0->specular); + COPY_CHAN4(s[1], v1->specular); + i[0] = v0->index; + i[1] = v1->index; + + COPY_CHAN4(v0->color, v2->color); + COPY_CHAN4(v1->color, v2->color); + COPY_CHAN4(v0->specular, v2->specular); + COPY_CHAN4(v1->specular, v2->specular); + v0->index = v2->index; + v1->index = v2->index; + } + + if (ef[e0]) _swrast_Point( ctx, v0 ); + if (ef[e1]) _swrast_Point( ctx, v1 ); + if (ef[e2]) _swrast_Point( ctx, v2 ); + + if (ctx->_TriangleCaps & DD_FLATSHADE) { + COPY_CHAN4(v0->color, c[0]); + COPY_CHAN4(v1->color, c[1]); + COPY_CHAN4(v0->specular, s[0]); + COPY_CHAN4(v1->specular, s[1]); + v0->index = i[0]; + v1->index = i[1]; + } +} + +#define SS_COLOR(a,b) UNCLAMPED_FLOAT_TO_RGBA_CHAN(a,b) +#define SS_SPEC(a,b) UNCLAMPED_FLOAT_TO_RGB_CHAN(a,b) +#define SS_IND(a,b) (a = b) + +#define IND (0) +#define TAG(x) x +#include "ss_tritmp.h" + +#define IND (SS_OFFSET_BIT) +#define TAG(x) x##_offset +#include "ss_tritmp.h" + +#define IND (SS_TWOSIDE_BIT) +#define TAG(x) x##_twoside +#include "ss_tritmp.h" + +#define IND (SS_OFFSET_BIT|SS_TWOSIDE_BIT) +#define TAG(x) x##_offset_twoside +#include "ss_tritmp.h" + +#define IND (SS_UNFILLED_BIT) +#define TAG(x) x##_unfilled +#include "ss_tritmp.h" + +#define IND (SS_OFFSET_BIT|SS_UNFILLED_BIT) +#define TAG(x) x##_offset_unfilled +#include "ss_tritmp.h" + +#define IND (SS_TWOSIDE_BIT|SS_UNFILLED_BIT) +#define TAG(x) x##_twoside_unfilled +#include "ss_tritmp.h" + +#define IND (SS_OFFSET_BIT|SS_TWOSIDE_BIT|SS_UNFILLED_BIT) +#define TAG(x) x##_offset_twoside_unfilled +#include "ss_tritmp.h" + +#define IND (0|SS_RGBA_BIT) +#define TAG(x) x##_rgba +#include "ss_tritmp.h" + +#define IND (SS_OFFSET_BIT|SS_RGBA_BIT) +#define TAG(x) x##_offset_rgba +#include "ss_tritmp.h" + +#define IND (SS_TWOSIDE_BIT|SS_RGBA_BIT) +#define TAG(x) x##_twoside_rgba +#include "ss_tritmp.h" + +#define IND (SS_OFFSET_BIT|SS_TWOSIDE_BIT|SS_RGBA_BIT) +#define TAG(x) x##_offset_twoside_rgba +#include "ss_tritmp.h" + +#define IND (SS_UNFILLED_BIT|SS_RGBA_BIT) +#define TAG(x) x##_unfilled_rgba +#include "ss_tritmp.h" + +#define IND (SS_OFFSET_BIT|SS_UNFILLED_BIT|SS_RGBA_BIT) +#define TAG(x) x##_offset_unfilled_rgba +#include "ss_tritmp.h" + +#define IND (SS_TWOSIDE_BIT|SS_UNFILLED_BIT|SS_RGBA_BIT) +#define TAG(x) x##_twoside_unfilled_rgba +#include "ss_tritmp.h" + +#define IND (SS_OFFSET_BIT|SS_TWOSIDE_BIT|SS_UNFILLED_BIT|SS_RGBA_BIT) +#define TAG(x) x##_offset_twoside_unfilled_rgba +#include "ss_tritmp.h" + + +void _swsetup_trifuncs_init( GLcontext *ctx ) +{ + (void) ctx; + + init(); + init_offset(); + init_twoside(); + init_offset_twoside(); + init_unfilled(); + init_offset_unfilled(); + init_twoside_unfilled(); + init_offset_twoside_unfilled(); + + init_rgba(); + init_offset_rgba(); + init_twoside_rgba(); + init_offset_twoside_rgba(); + init_unfilled_rgba(); + init_offset_unfilled_rgba(); + init_twoside_unfilled_rgba(); + init_offset_twoside_unfilled_rgba(); +} + + +static void swsetup_points( GLcontext *ctx, GLuint first, GLuint last ) +{ + struct vertex_buffer *VB = &TNL_CONTEXT(ctx)->vb; + SWvertex *verts = SWSETUP_CONTEXT(ctx)->verts; + GLuint i; + + if (VB->Elts) { + for (i = first; i < last; i++) + if (VB->ClipMask[VB->Elts[i]] == 0) + _swrast_Point( ctx, &verts[VB->Elts[i]] ); + } + else { + for (i = first; i < last; i++) + if (VB->ClipMask[i] == 0) + _swrast_Point( ctx, &verts[i] ); + } +} + +static void swsetup_line( GLcontext *ctx, GLuint v0, GLuint v1 ) +{ + SWvertex *verts = SWSETUP_CONTEXT(ctx)->verts; + _swrast_Line( ctx, &verts[v0], &verts[v1] ); +} + + + +void _swsetup_choose_trifuncs( GLcontext *ctx ) +{ + SScontext *swsetup = SWSETUP_CONTEXT(ctx); + GLuint ind = 0; + + if (ctx->Polygon._OffsetAny) + ind |= SS_OFFSET_BIT; + + if (ctx->Light.Enabled && ctx->Light.Model.TwoSide) + ind |= SS_TWOSIDE_BIT; + + if (ctx->_TriangleCaps & DD_TRI_UNFILLED) + ind |= SS_UNFILLED_BIT; + + if (ctx->Visual.rgbMode) + ind |= SS_RGBA_BIT; + + swsetup->Triangle = tri_tab[ind]; + swsetup->Quad = quad_tab[ind]; + swsetup->Line = swsetup_line; + swsetup->Points = swsetup_points; +} Index: dll/opengl/opengl32/mesa/swrast_setup/ss_triangle.h =================================================================== --- dll/opengl/opengl32/mesa/swrast_setup/ss_triangle.h (revision 0) +++ dll/opengl/opengl32/mesa/swrast_setup/ss_triangle.h (working copy) @@ -0,0 +1,40 @@ +/* $Id: ss_triangle.h,v 1.3 2001/03/12 00:48:43 gareth Exp $ */ + +/* + * Mesa 3-D graphics library + * Version: 3.5 + * + * Copyright (C) 1999-2001 Brian Paul 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 + * BRIAN PAUL 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. + * + * Authors: + * Keith Whitwell + */ + +#ifndef SS_TRIANGLE_H +#define SS_TRIANGLE_H + +#include "mtypes.h" +#include "ss_context.h" + + +void _swsetup_trifuncs_init( GLcontext *ctx ); +void _swsetup_choose_trifuncs( GLcontext *ctx ); + +#endif Index: dll/opengl/opengl32/mesa/swrast_setup/ss_tritmp.h =================================================================== --- dll/opengl/opengl32/mesa/swrast_setup/ss_tritmp.h (revision 0) +++ dll/opengl/opengl32/mesa/swrast_setup/ss_tritmp.h (working copy) @@ -0,0 +1,189 @@ +/* $Id: ss_tritmp.h,v 1.12 2001/04/28 08:39:18 keithw Exp $ */ + +/* + * Mesa 3-D graphics library + * Version: 3.5 + * + * Copyright (C) 1999-2001 Brian Paul 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 + * BRIAN PAUL 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. + * + * Authors: + * Keith Whitwell + */ + + +static void TAG(triangle)(GLcontext *ctx, GLuint e0, GLuint e1, GLuint e2 ) +{ + struct vertex_buffer *VB = &TNL_CONTEXT(ctx)->vb; + SWvertex *verts = SWSETUP_CONTEXT(ctx)->verts; + SWvertex *v[3]; + GLfloat z[3]; + GLfloat offset; + GLenum mode = GL_FILL; + GLuint facing; + + v[0] = &verts[e0]; + v[1] = &verts[e1]; + v[2] = &verts[e2]; + + + if (IND & (SS_TWOSIDE_BIT | SS_OFFSET_BIT | SS_UNFILLED_BIT)) + { + GLfloat ex = v[0]->win[0] - v[2]->win[0]; + GLfloat ey = v[0]->win[1] - v[2]->win[1]; + GLfloat fx = v[1]->win[0] - v[2]->win[0]; + GLfloat fy = v[1]->win[1] - v[2]->win[1]; + GLfloat cc = ex*fy - ey*fx; + + if (IND & (SS_TWOSIDE_BIT | SS_UNFILLED_BIT)) + { + facing = (cc < 0.0) ^ ctx->Polygon._FrontBit; + + if (IND & SS_UNFILLED_BIT) + mode = facing ? ctx->Polygon.BackMode : ctx->Polygon.FrontMode; + + if (facing == 1) { + if (IND & SS_TWOSIDE_BIT) { + if (IND & SS_RGBA_BIT) { + GLfloat (*vbcolor)[4] = (GLfloat (*)[4])VB->ColorPtr[1]->Ptr; + GLfloat (*vbspec)[4] = (GLfloat (*)[4])VB->SecondaryColorPtr[1]->Ptr; + SS_COLOR(v[0]->color, vbcolor[e0]); + SS_COLOR(v[1]->color, vbcolor[e1]); + SS_COLOR(v[2]->color, vbcolor[e2]); + SS_SPEC(v[0]->specular, vbspec[e0]); + SS_SPEC(v[1]->specular, vbspec[e1]); + SS_SPEC(v[2]->specular, vbspec[e2]); + } else { + GLuint *vbindex = VB->IndexPtr[1]->data; + SS_IND(v[0]->index, vbindex[e0]); + SS_IND(v[1]->index, vbindex[e1]); + SS_IND(v[2]->index, vbindex[e2]); + } + } + } + } + + if (IND & SS_OFFSET_BIT) + { + offset = ctx->Polygon.OffsetUnits; + z[0] = v[0]->win[2]; + z[1] = v[1]->win[2]; + z[2] = v[2]->win[2]; + if (cc * cc > 1e-16) { + GLfloat ez = z[0] - z[2]; + GLfloat fz = z[1] - z[2]; + GLfloat a = ey*fz - ez*fy; + GLfloat b = ez*fx - ex*fz; + GLfloat ic = 1.0 / cc; + GLfloat ac = a * ic; + GLfloat bc = b * ic; + if (ac < 0.0f) ac = -ac; + if (bc < 0.0f) bc = -bc; + offset += MAX2(ac, bc) * ctx->Polygon.OffsetFactor; + } + offset *= ctx->MRD; + /*printf("offset %g\n", offset);*/ + } + } + + if (mode == GL_POINT) { + if ((IND & SS_OFFSET_BIT) && ctx->Polygon.OffsetPoint) { + v[0]->win[2] += offset; + v[1]->win[2] += offset; + v[2]->win[2] += offset; + } + _swsetup_render_point_tri( ctx, e0, e1, e2 ); + } else if (mode == GL_LINE) { + if ((IND & SS_OFFSET_BIT) && ctx->Polygon.OffsetLine) { + v[0]->win[2] += offset; + v[1]->win[2] += offset; + v[2]->win[2] += offset; + } + _swsetup_render_line_tri( ctx, e0, e1, e2 ); + } else { + if ((IND & SS_OFFSET_BIT) && ctx->Polygon.OffsetFill) { + v[0]->win[2] += offset; + v[1]->win[2] += offset; + v[2]->win[2] += offset; + } + _swrast_Triangle( ctx, v[0], v[1], v[2] ); + } + + if (IND & SS_OFFSET_BIT) { + v[0]->win[2] = z[0]; + v[1]->win[2] = z[1]; + v[2]->win[2] = z[2]; + } + + if (IND & SS_TWOSIDE_BIT) { + if (facing == 1) { + if (IND & SS_RGBA_BIT) { + GLfloat (*vbcolor)[4] = (GLfloat (*)[4])VB->ColorPtr[0]->Ptr; + GLfloat (*vbspec)[4] = (GLfloat (*)[4])VB->SecondaryColorPtr[0]->Ptr; + SS_COLOR(v[0]->color, vbcolor[e0]); + SS_COLOR(v[1]->color, vbcolor[e1]); + SS_COLOR(v[2]->color, vbcolor[e2]); + SS_SPEC(v[0]->specular, vbspec[e0]); + SS_SPEC(v[1]->specular, vbspec[e1]); + SS_SPEC(v[2]->specular, vbspec[e2]); + } else { + GLuint *vbindex = VB->IndexPtr[0]->data; + SS_IND(v[0]->index, vbindex[e0]); + SS_IND(v[1]->index, vbindex[e1]); + SS_IND(v[2]->index, vbindex[e2]); + } + } + } +} + + + +/* Need to fixup edgeflags when decomposing to triangles: + */ +static void TAG(quadfunc)( GLcontext *ctx, GLuint v0, + GLuint v1, GLuint v2, GLuint v3 ) +{ + if (IND & SS_UNFILLED_BIT) { + struct vertex_buffer *VB = &TNL_CONTEXT(ctx)->vb; + GLubyte ef1 = VB->EdgeFlag[v1]; + GLubyte ef3 = VB->EdgeFlag[v3]; + VB->EdgeFlag[v1] = 0; + TAG(triangle)( ctx, v0, v1, v3 ); + VB->EdgeFlag[v1] = ef1; + VB->EdgeFlag[v3] = 0; + TAG(triangle)( ctx, v1, v2, v3 ); + VB->EdgeFlag[v3] = ef3; + } else { + TAG(triangle)( ctx, v0, v1, v3 ); + TAG(triangle)( ctx, v1, v2, v3 ); + } +} + + + + +static void TAG(init)( void ) +{ + tri_tab[IND] = TAG(triangle); + quad_tab[IND] = TAG(quadfunc); +} + + +#undef IND +#undef TAG Index: dll/opengl/opengl32/mesa/swrast_setup/ss_vb.c =================================================================== --- dll/opengl/opengl32/mesa/swrast_setup/ss_vb.c (revision 0) +++ dll/opengl/opengl32/mesa/swrast_setup/ss_vb.c (working copy) @@ -0,0 +1,304 @@ +/* $Id: ss_vb.c,v 1.12 2001/03/29 21:16:26 keithw Exp $ */ + +/* + * Mesa 3-D graphics library + * Version: 3.5 + * + * Copyright (C) 1999-2001 Brian Paul 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 + * BRIAN PAUL 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. + * + * Authors: + * Keith Whitwell + */ + +#include "glheader.h" +#include "colormac.h" +#include "macros.h" + +#include "swrast/swrast.h" + +#include "tnl/t_context.h" + +#include "math/m_vector.h" +#include "ss_context.h" +#include "ss_vb.h" + + + +/* Provides a RasterSetup function which prebuilds vertices for the + * software rasterizer. This is required for the triangle functions + * in this module, but not the rest of the swrast module. + */ + +typedef void (*SetupFunc)( GLcontext *ctx, + GLuint start, GLuint end, GLuint newinputs ); + +#define COLOR 0x1 +#define INDEX 0x2 +#define TEX0 0x4 +#define MULTITEX 0x8 +#define SPEC 0x10 +#define FOG 0x20 +#define POINT 0x40 +#define MAX_SETUPFUNC 0x80 + +static SetupFunc setup_func[MAX_SETUPFUNC]; + + +#define IND (0) +#define TAG(x) x##_none +#include "ss_vbtmp.h" + +#define IND (COLOR) +#define TAG(x) x##_color +#include "ss_vbtmp.h" + +#define IND (COLOR|SPEC) +#define TAG(x) x##_color_spec +#include "ss_vbtmp.h" + +#define IND (COLOR|FOG) +#define TAG(x) x##_color_fog +#include "ss_vbtmp.h" + +#define IND (COLOR|SPEC|FOG) +#define TAG(x) x##_color_spec_fog +#include "ss_vbtmp.h" + +#define IND (COLOR|TEX0) +#define TAG(x) x##_color_tex0 +#include "ss_vbtmp.h" + +#define IND (COLOR|TEX0|SPEC) +#define TAG(x) x##_color_tex0_spec +#include "ss_vbtmp.h" + +#define IND (COLOR|TEX0|FOG) +#define TAG(x) x##_color_tex0_fog +#include "ss_vbtmp.h" + +#define IND (COLOR|TEX0|SPEC|FOG) +#define TAG(x) x##_color_tex0_spec_fog +#include "ss_vbtmp.h" + +#define IND (COLOR|MULTITEX) +#define TAG(x) x##_color_multitex +#include "ss_vbtmp.h" + +#define IND (COLOR|MULTITEX|SPEC) +#define TAG(x) x##_color_multitex_spec +#include "ss_vbtmp.h" + +#define IND (COLOR|MULTITEX|FOG) +#define TAG(x) x##_color_multitex_fog +#include "ss_vbtmp.h" + +#define IND (COLOR|MULTITEX|SPEC|FOG) +#define TAG(x) x##_color_multitex_spec_fog +#include "ss_vbtmp.h" + +#define IND (COLOR|POINT) +#define TAG(x) x##_color_point +#include "ss_vbtmp.h" + +#define IND (COLOR|SPEC|POINT) +#define TAG(x) x##_color_spec_point +#include "ss_vbtmp.h" + +#define IND (COLOR|FOG|POINT) +#define TAG(x) x##_color_fog_point +#include "ss_vbtmp.h" + +#define IND (COLOR|SPEC|FOG|POINT) +#define TAG(x) x##_color_spec_fog_point +#include "ss_vbtmp.h" + +#define IND (COLOR|TEX0|POINT) +#define TAG(x) x##_color_tex0_point +#include "ss_vbtmp.h" + +#define IND (COLOR|TEX0|SPEC|POINT) +#define TAG(x) x##_color_tex0_spec_point +#include "ss_vbtmp.h" + +#define IND (COLOR|TEX0|FOG|POINT) +#define TAG(x) x##_color_tex0_fog_point +#include "ss_vbtmp.h" + +#define IND (COLOR|TEX0|SPEC|FOG|POINT) +#define TAG(x) x##_color_tex0_spec_fog_point +#include "ss_vbtmp.h" + +#define IND (COLOR|MULTITEX|POINT) +#define TAG(x) x##_color_multitex_point +#include "ss_vbtmp.h" + +#define IND (COLOR|MULTITEX|SPEC|POINT) +#define TAG(x) x##_color_multitex_spec_point +#include "ss_vbtmp.h" + +#define IND (COLOR|MULTITEX|FOG|POINT) +#define TAG(x) x##_color_multitex_fog_point +#include "ss_vbtmp.h" + +#define IND (COLOR|MULTITEX|SPEC|FOG|POINT) +#define TAG(x) x##_color_multitex_spec_fog_point +#include "ss_vbtmp.h" + +#define IND (INDEX) +#define TAG(x) x##_index +#include "ss_vbtmp.h" + +#define IND (INDEX|TEX0) +#define TAG(x) x##_index_tex0 +#include "ss_vbtmp.h" + +#define IND (INDEX|FOG) +#define TAG(x) x##_index_fog +#include "ss_vbtmp.h" + +#define IND (INDEX|TEX0|FOG) +#define TAG(x) x##_index_tex0_fog +#include "ss_vbtmp.h" + +#define IND (INDEX|POINT) +#define TAG(x) x##_index_point +#include "ss_vbtmp.h" + +#define IND (INDEX|TEX0|POINT) +#define TAG(x) x##_index_tex0_point +#include "ss_vbtmp.h" + +#define IND (INDEX|FOG|POINT) +#define TAG(x) x##_index_fog_point +#include "ss_vbtmp.h" + +#define IND (INDEX|TEX0|FOG|POINT) +#define TAG(x) x##_index_tex0_fog_point +#include "ss_vbtmp.h" + + +static void +rs_invalid( GLcontext *ctx, GLuint start, GLuint end, GLuint newinputs ) +{ + fprintf(stderr, "swrast_setup: invalid setup function\n"); + (void) (ctx && start && end && newinputs); +} + +void +_swsetup_vb_init( GLcontext *ctx ) +{ + GLuint i; + (void) ctx; + + for (i = 0 ; i < Elements(setup_func) ; i++) + setup_func[i] = rs_invalid; + + setup_func[0] = rs_none; + setup_func[COLOR] = rs_color; + setup_func[COLOR|SPEC] = rs_color_spec; + setup_func[COLOR|FOG] = rs_color_fog; + setup_func[COLOR|SPEC|FOG] = rs_color_spec_fog; + setup_func[COLOR|TEX0] = rs_color_tex0; + setup_func[COLOR|TEX0|SPEC] = rs_color_tex0_spec; + setup_func[COLOR|TEX0|FOG] = rs_color_tex0_fog; + setup_func[COLOR|TEX0|SPEC|FOG] = rs_color_tex0_spec_fog; + setup_func[COLOR|MULTITEX] = rs_color_multitex; + setup_func[COLOR|MULTITEX|SPEC] = rs_color_multitex_spec; + setup_func[COLOR|MULTITEX|FOG] = rs_color_multitex_fog; + setup_func[COLOR|MULTITEX|SPEC|FOG] = rs_color_multitex_spec_fog; + setup_func[COLOR|POINT] = rs_color_point; + setup_func[COLOR|SPEC|POINT] = rs_color_spec_point; + setup_func[COLOR|FOG|POINT] = rs_color_fog_point; + setup_func[COLOR|SPEC|FOG|POINT] = rs_color_spec_fog_point; + setup_func[COLOR|TEX0|POINT] = rs_color_tex0_point; + setup_func[COLOR|TEX0|SPEC|POINT] = rs_color_tex0_spec_point; + setup_func[COLOR|TEX0|FOG|POINT] = rs_color_tex0_fog_point; + setup_func[COLOR|TEX0|SPEC|FOG|POINT] = rs_color_tex0_spec_fog_point; + setup_func[COLOR|MULTITEX|POINT] = rs_color_multitex_point; + setup_func[COLOR|MULTITEX|SPEC|POINT] = rs_color_multitex_spec_point; + setup_func[COLOR|MULTITEX|FOG|POINT] = rs_color_multitex_fog_point; + setup_func[COLOR|MULTITEX|SPEC|FOG|POINT] = rs_color_multitex_spec_fog_point; + setup_func[INDEX] = rs_index; + setup_func[INDEX|TEX0] = rs_index_tex0; + setup_func[INDEX|FOG] = rs_index_fog; + setup_func[INDEX|TEX0|FOG] = rs_index_tex0_fog; + setup_func[INDEX|POINT] = rs_index_point; + setup_func[INDEX|TEX0|POINT] = rs_index_tex0_point; + setup_func[INDEX|FOG|POINT] = rs_index_fog_point; + setup_func[INDEX|TEX0|FOG|POINT] = rs_index_tex0_fog_point; +} + +static void printSetupFlags(char *msg, GLuint flags ) +{ + fprintf(stderr, "%s(%x): %s%s%s%s%s%s%s\n", + msg, + (int)flags, + (flags & COLOR) ? "color, " : "", + (flags & INDEX) ? "index, " : "", + (flags & TEX0) ? "tex0, " : "", + (flags & MULTITEX) ? "multitex, " : "", + (flags & SPEC) ? "spec, " : "", + (flags & FOG) ? "fog, " : "", + (flags & POINT) ? "point, " : ""); +} + + +void +_swsetup_choose_rastersetup_func(GLcontext *ctx) +{ + SScontext *swsetup = SWSETUP_CONTEXT(ctx); + int funcindex = 0; + + if (ctx->RenderMode == GL_RENDER) { + if (ctx->Visual.rgbMode) { + funcindex = COLOR; + + if (ctx->Texture._ReallyEnabled & ~0xf) + funcindex |= MULTITEX; + else if (ctx->Texture._ReallyEnabled & 0xf) + funcindex |= TEX0; + + if (ctx->Light.Model.ColorControl == GL_SEPARATE_SPECULAR_COLOR || + ctx->Fog.ColorSumEnabled) + funcindex |= SPEC; + } + else { + funcindex = INDEX; + } + + if (ctx->Point._Attenuated) + funcindex |= POINT; + + if (ctx->Fog.Enabled) + funcindex |= FOG; + } + else if (ctx->RenderMode == GL_FEEDBACK) { + if (ctx->Visual.rgbMode) + funcindex = (COLOR | TEX0); /* is feedback color subject to fogging? */ + else + funcindex = (INDEX | TEX0); + } + else + funcindex = 0; + + if (0) printSetupFlags("software setup func", funcindex); + swsetup->BuildProjVerts = setup_func[funcindex]; + ASSERT(setup_func[funcindex] != rs_invalid); +} Index: dll/opengl/opengl32/mesa/swrast_setup/ss_vb.h =================================================================== --- dll/opengl/opengl32/mesa/swrast_setup/ss_vb.h (revision 0) +++ dll/opengl/opengl32/mesa/swrast_setup/ss_vb.h (working copy) @@ -0,0 +1,39 @@ +/* $Id: ss_vb.h,v 1.3 2001/03/12 00:48:43 gareth Exp $ */ + +/* + * Mesa 3-D graphics library + * Version: 3.5 + * + * Copyright (C) 1999-2001 Brian Paul 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 + * BRIAN PAUL 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. + * + * Authors: + * Keith Whitwell + */ + +#ifndef SS_VB_H +#define SS_VB_H + +#include "mtypes.h" +#include "swrast_setup.h" + +void _swsetup_vb_init( GLcontext *ctx ); +void _swsetup_choose_rastersetup_func( GLcontext *ctx ); + +#endif Index: dll/opengl/opengl32/mesa/swrast_setup/ss_vbtmp.h =================================================================== --- dll/opengl/opengl32/mesa/swrast_setup/ss_vbtmp.h (revision 0) +++ dll/opengl/opengl32/mesa/swrast_setup/ss_vbtmp.h (working copy) @@ -0,0 +1,146 @@ +/* $Id: ss_vbtmp.h,v 1.15 2001/04/30 09:04:00 keithw Exp $ */ + +/* + * Mesa 3-D graphics library + * Version: 3.5 + * + * Copyright (C) 1999-2001 Brian Paul 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 + * BRIAN PAUL 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. + * + * Authors: + * Keith Whitwell + */ + + +static void TAG(rs)(GLcontext *ctx, GLuint start, GLuint end, GLuint newinputs ) +{ + TNLcontext *tnl = TNL_CONTEXT(ctx); + struct vertex_buffer *VB = &tnl->vb; + SWvertex *v; + GLfloat (*proj)[4]; /* projected clip coordinates */ + GLfloat (*tc[MAX_TEXTURE_UNITS])[4]; + GLfloat (*color)[4]; + GLfloat (*spec)[4]; + GLuint *index; + GLfloat *fog; + GLfloat *pointSize; + GLuint tsz[MAX_TEXTURE_UNITS]; + GLuint i; + GLfloat *m = ctx->Viewport._WindowMap.m; + const GLfloat sx = m[0]; + const GLfloat sy = m[5]; + const GLfloat sz = m[10]; + const GLfloat tx = m[12]; + const GLfloat ty = m[13]; + const GLfloat tz = m[14]; + GLuint maxtex = 0; + + /* Only the most basic optimization for cva: + */ + if (!newinputs) + return; + + /* TODO: Get import_client_data to pad vectors out to 4 cleanly. + * + * NOTE: This has the effect of converting any remaining ubyte + * colors to floats... As they're already there 90% of the + * time, this isn't a bad thing. + */ + if (VB->importable_data) + VB->import_data( ctx, VB->importable_data & newinputs, + (VB->ClipOrMask + ? VEC_NOT_WRITEABLE|VEC_BAD_STRIDE + : VEC_BAD_STRIDE)); + + if (IND & TEX0) { + tc[0] = VB->TexCoordPtr[0]->data; + tsz[0] = VB->TexCoordPtr[0]->size; + } + + if (IND & MULTITEX) { + for (i = 0 ; i < ctx->Const.MaxTextureUnits ; i++) { + if (VB->TexCoordPtr[i]) { + maxtex = i+1; + tc[i] = VB->TexCoordPtr[i]->data; + tsz[i] = VB->TexCoordPtr[i]->size; + } + else tc[i] = 0; + } + } + + /* Tie up some dangling pointers for flat/twoside code in ss_tritmp.h + */ + if ((ctx->_TriangleCaps & DD_SEPARATE_SPECULAR) == 0) { + VB->SecondaryColorPtr[0] = VB->ColorPtr[0]; + VB->SecondaryColorPtr[1] = VB->ColorPtr[1]; + } + + + proj = VB->ProjectedClipPtr->data; + if (IND & FOG) + fog = VB->FogCoordPtr->data; + if (IND & COLOR) + color = (GLfloat (*)[4])VB->ColorPtr[0]->Ptr; + if (IND & SPEC) + spec = (GLfloat (*)[4])VB->SecondaryColorPtr[0]->Ptr; + if (IND & INDEX) + index = VB->IndexPtr[0]->data; + if (IND & POINT) + pointSize = VB->PointSizePtr->data; + + v = &(SWSETUP_CONTEXT(ctx)->verts[start]); + + for (i=start; i < end; i++, v++) { + if (VB->ClipMask[i] == 0) { + v->win[0] = sx * proj[i][0] + tx; + v->win[1] = sy * proj[i][1] + ty; + v->win[2] = sz * proj[i][2] + tz; + v->win[3] = proj[i][3]; + + if (IND & TEX0) + COPY_CLEAN_4V( v->texcoord[0], tsz[0], tc[0][i] ); + + if (IND & MULTITEX) { + GLuint u; + for (u = 0 ; u < maxtex ; u++) + if (tc[u]) + COPY_CLEAN_4V( v->texcoord[u], tsz[u], tc[u][i] ); + } + + if (IND & COLOR) + UNCLAMPED_FLOAT_TO_RGBA_CHAN(v->color, color[i]); + + if (IND & SPEC) + UNCLAMPED_FLOAT_TO_RGBA_CHAN(v->specular, spec[i]); + + if (IND & FOG) + v->fog = fog[i]; + + if (IND & INDEX) + v->index = index[i]; + + if (IND & POINT) + v->pointSize = pointSize[i]; + } + } +} + +#undef TAG +#undef IND +#undef SETUP_FLAGS Index: dll/opengl/opengl32/mesa/swrast_setup/swrast_setup.h =================================================================== --- dll/opengl/opengl32/mesa/swrast_setup/swrast_setup.h (revision 0) +++ dll/opengl/opengl32/mesa/swrast_setup/swrast_setup.h (working copy) @@ -0,0 +1,92 @@ +/* $Id: swrast_setup.h,v 1.8 2001/03/12 00:48:43 gareth Exp $ */ + +/* + * Mesa 3-D graphics library + * Version: 3.5 + * + * Copyright (C) 1999-2001 Brian Paul 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 + * BRIAN PAUL 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. + * + * Authors: + * Keith Whitwell + */ + +/* Public interface to the swrast_setup module. This module provides + * an implementation of the driver interface to t_vb_render.c, and uses + * the software rasterizer (swrast) to perform actual rasterization. + */ + +#ifndef SWRAST_SETUP_H +#define SWRAST_SETUP_H + +extern GLboolean +_swsetup_CreateContext( GLcontext *ctx ); + +extern void +_swsetup_DestroyContext( GLcontext *ctx ); + +extern void +_swsetup_InvalidateState( GLcontext *ctx, GLuint new_state ); + +extern void +_swsetup_BuildProjectedVertices( GLcontext *ctx, + GLuint start, + GLuint end, + GLuint new_inputs ); + +extern void +_swsetup_Quad( GLcontext *ctx, GLuint v0, GLuint v1, GLuint v2, GLuint v3 ); + +extern void +_swsetup_Triangle( GLcontext *ctx, GLuint v0, GLuint v1, GLuint v2 ); + +extern void +_swsetup_Line( GLcontext *ctx, GLuint v0, GLuint v1 ); + +extern void +_swsetup_Points( GLcontext *ctx, GLuint first, GLuint last ); + +extern void +_swsetup_RenderPrimitive( GLcontext *ctx, GLenum mode ); + +extern void +_swsetup_RenderStart( GLcontext *ctx ); + +extern void +_swsetup_RenderFinish( GLcontext *ctx ); + +extern void +_swsetup_RenderProjectInterpVerts( GLcontext *ctx ); + +extern void +_swsetup_RenderInterp( GLcontext *ctx, GLfloat t, + GLuint dst, GLuint out, GLuint in, + GLboolean force_boundary ); +extern void +_swsetup_RenderCopyPV( GLcontext *ctx, GLuint dst, GLuint src ); + +extern void +_swsetup_RenderClippedPolygon( GLcontext *ctx, const GLuint *elts, GLuint n ); + +extern void +_swsetup_RenderClippedLine( GLcontext *ctx, GLuint ii, GLuint jj ); + + + +#endif Index: dll/opengl/opengl32/mesa/texformat.c =================================================================== --- dll/opengl/opengl32/mesa/texformat.c (revision 0) +++ dll/opengl/opengl32/mesa/texformat.c (working copy) @@ -0,0 +1,649 @@ +/* $Id: texformat.c,v 1.11 2001/06/15 14:18:46 brianp Exp $ */ + +/* + * Mesa 3-D graphics library + * Version: 3.5 + * + * Copyright (C) 1999-2001 Brian Paul 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 + * BRIAN PAUL 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. + * + * Author: + * Gareth Hughes + */ + +#ifdef PC_HEADER +#include "all.h" +#else +#include "glheader.h" +#include "colormac.h" +#include "context.h" +#include "image.h" +#include "mem.h" +#include "mmath.h" +#include "mtypes.h" +#include "texformat.h" +#include "teximage.h" +#include "texstate.h" +#include "swrast/s_span.h" +#endif + + +/* Texel fetch routines for all supported formats: + */ +#define DIM 1 +#include "texformat_tmp.h" + +#define DIM 2 +#include "texformat_tmp.h" + +#define DIM 3 +#include "texformat_tmp.h" + +/* Have to have this so the FetchTexel function pointer is never NULL. + */ +static void fetch_null_texel( const struct gl_texture_image *texImage, + GLint i, GLint j, GLint k, GLvoid *texel ) +{ + GLchan *rgba = (GLchan *) texel; + rgba[RCOMP] = 0; + rgba[GCOMP] = 0; + rgba[BCOMP] = 0; + rgba[ACOMP] = 0; +} + + +/* ============================================================= + * Default GLchan-based formats: + */ + +const struct gl_texture_format _mesa_texformat_rgba = { + MESA_FORMAT_RGBA, /* MesaFormat */ + GL_RGBA, /* BaseFormat */ + CHAN_TYPE, /* Type */ + CHAN_BITS, /* RedBits */ + CHAN_BITS, /* GreenBits */ + CHAN_BITS, /* BlueBits */ + CHAN_BITS, /* AlphaBits */ + 0, /* LuminanceBits */ + 0, /* IntensityBits */ + 0, /* IndexBits */ + 0, /* DepthBits */ + 4 * CHAN_BITS / 8, /* TexelBytes */ + fetch_1d_texel_rgba, /* FetchTexel1D */ + fetch_2d_texel_rgba, /* FetchTexel2D */ + fetch_3d_texel_rgba, /* FetchTexel3D */ +}; + +const struct gl_texture_format _mesa_texformat_rgb = { + MESA_FORMAT_RGB, /* MesaFormat */ + GL_RGB, /* BaseFormat */ + CHAN_TYPE, /* Type */ + CHAN_BITS, /* RedBits */ + CHAN_BITS, /* GreenBits */ + CHAN_BITS, /* BlueBits */ + 0, /* AlphaBits */ + 0, /* LuminanceBits */ + 0, /* IntensityBits */ + 0, /* IndexBits */ + 0, /* DepthBits */ + 3 * CHAN_BITS / 8, /* TexelBytes */ + fetch_1d_texel_rgb, /* FetchTexel1D */ + fetch_2d_texel_rgb, /* FetchTexel2D */ + fetch_3d_texel_rgb, /* FetchTexel3D */ +}; + +const struct gl_texture_format _mesa_texformat_alpha = { + MESA_FORMAT_ALPHA, /* MesaFormat */ + GL_ALPHA, /* BaseFormat */ + CHAN_TYPE, /* Type */ + 0, /* RedBits */ + 0, /* GreenBits */ + 0, /* BlueBits */ + CHAN_BITS, /* AlphaBits */ + 0, /* LuminanceBits */ + 0, /* IntensityBits */ + 0, /* IndexBits */ + 0, /* DepthBits */ + CHAN_BITS / 8, /* TexelBytes */ + fetch_1d_texel_alpha, /* FetchTexel1D */ + fetch_2d_texel_alpha, /* FetchTexel2D */ + fetch_3d_texel_alpha, /* FetchTexel3D */ +}; + +const struct gl_texture_format _mesa_texformat_luminance = { + MESA_FORMAT_LUMINANCE, /* MesaFormat */ + GL_LUMINANCE, /* BaseFormat */ + CHAN_TYPE, /* Type */ + 0, /* RedBits */ + 0, /* GreenBits */ + 0, /* BlueBits */ + 0, /* AlphaBits */ + CHAN_BITS, /* LuminanceBits */ + 0, /* IntensityBits */ + 0, /* IndexBits */ + 0, /* DepthBits */ + CHAN_BITS / 8, /* TexelBytes */ + fetch_1d_texel_luminance, /* FetchTexel1D */ + fetch_2d_texel_luminance, /* FetchTexel2D */ + fetch_3d_texel_luminance, /* FetchTexel3D */ +}; + +const struct gl_texture_format _mesa_texformat_luminance_alpha = { + MESA_FORMAT_LUMINANCE_ALPHA, /* MesaFormat */ + GL_LUMINANCE_ALPHA, /* BaseFormat */ + CHAN_TYPE, /* Type */ + 0, /* RedBits */ + 0, /* GreenBits */ + 0, /* BlueBits */ + CHAN_BITS, /* AlphaBits */ + CHAN_BITS, /* LuminanceBits */ + 0, /* IntensityBits */ + 0, /* IndexBits */ + 0, /* DepthBits */ + 2 * CHAN_BITS / 8, /* TexelBytes */ + fetch_1d_texel_luminance_alpha, /* FetchTexel1D */ + fetch_2d_texel_luminance_alpha, /* FetchTexel2D */ + fetch_3d_texel_luminance_alpha, /* FetchTexel3D */ +}; + +const struct gl_texture_format _mesa_texformat_intensity = { + MESA_FORMAT_INTENSITY, /* MesaFormat */ + GL_INTENSITY, /* BaseFormat */ + CHAN_TYPE, /* Type */ + 0, /* RedBits */ + 0, /* GreenBits */ + 0, /* BlueBits */ + 0, /* AlphaBits */ + 0, /* LuminanceBits */ + CHAN_BITS, /* IntensityBits */ + 0, /* IndexBits */ + 0, /* DepthBits */ + CHAN_BITS / 8, /* TexelBytes */ + fetch_1d_texel_intensity, /* FetchTexel1D */ + fetch_2d_texel_intensity, /* FetchTexel2D */ + fetch_3d_texel_intensity, /* FetchTexel3D */ +}; + +const struct gl_texture_format _mesa_texformat_color_index = { + MESA_FORMAT_COLOR_INDEX, /* MesaFormat */ + GL_COLOR_INDEX, /* BaseFormat */ + CHAN_TYPE, /* Type */ + 0, /* RedBits */ + 0, /* GreenBits */ + 0, /* BlueBits */ + 0, /* AlphaBits */ + 0, /* LuminanceBits */ + 0, /* IntensityBits */ + CHAN_BITS, /* IndexBits */ + 0, /* DepthBits */ + CHAN_BITS / 8, /* TexelBytes */ + fetch_1d_texel_color_index, /* FetchTexel1D */ + fetch_2d_texel_color_index, /* FetchTexel2D */ + fetch_3d_texel_color_index, /* FetchTexel3D */ +}; + +const struct gl_texture_format _mesa_texformat_depth_component = { + MESA_FORMAT_DEPTH_COMPONENT, /* MesaFormat */ + GL_DEPTH_COMPONENT, /* BaseFormat */ + GL_FLOAT, /* Type */ + 0, /* RedBits */ + 0, /* GreenBits */ + 0, /* BlueBits */ + 0, /* AlphaBits */ + 0, /* LuminanceBits */ + 0, /* IntensityBits */ + 0, /* IndexBits */ + sizeof(GLfloat) * 8, /* DepthBits */ + sizeof(GLfloat), /* TexelBytes */ + fetch_1d_texel_depth_component, /* FetchTexel1D */ + fetch_2d_texel_depth_component, /* FetchTexel2D */ + fetch_3d_texel_depth_component, /* FetchTexel3D */ +}; + + +/* ============================================================= + * Hardware formats: + */ + +const struct gl_texture_format _mesa_texformat_rgba8888 = { + MESA_FORMAT_RGBA8888, /* MesaFormat */ + GL_RGBA, /* BaseFormat */ + GL_UNSIGNED_INT_8_8_8_8, /* Type */ + 8, /* RedBits */ + 8, /* GreenBits */ + 8, /* BlueBits */ + 8, /* AlphaBits */ + 0, /* LuminanceBits */ + 0, /* IntensityBits */ + 0, /* IndexBits */ + 0, /* DepthBits */ + 4, /* TexelBytes */ + fetch_1d_texel_rgba8888, /* FetchTexel1D */ + fetch_2d_texel_rgba8888, /* FetchTexel2D */ + fetch_3d_texel_rgba8888, /* FetchTexel3D */ +}; + +const struct gl_texture_format _mesa_texformat_argb8888 = { + MESA_FORMAT_ARGB8888, /* MesaFormat */ + GL_RGBA, /* BaseFormat */ + GL_UNSIGNED_INT_8_8_8_8_REV, /* Type */ + 8, /* RedBits */ + 8, /* GreenBits */ + 8, /* BlueBits */ + 8, /* AlphaBits */ + 0, /* LuminanceBits */ + 0, /* IntensityBits */ + 0, /* IndexBits */ + 0, /* DepthBits */ + 4, /* TexelBytes */ + fetch_1d_texel_argb8888, /* FetchTexel1D */ + fetch_2d_texel_argb8888, /* FetchTexel2D */ + fetch_3d_texel_argb8888, /* FetchTexel3D */ +}; + +const struct gl_texture_format _mesa_texformat_rgb888 = { + MESA_FORMAT_RGB888, /* MesaFormat */ + GL_RGB, /* BaseFormat */ + GL_UNSIGNED_BYTE, /* Type */ + 8, /* RedBits */ + 8, /* GreenBits */ + 8, /* BlueBits */ + 0, /* AlphaBits */ + 0, /* LuminanceBits */ + 0, /* IntensityBits */ + 0, /* IndexBits */ + 0, /* DepthBits */ + 3, /* TexelBytes */ + fetch_1d_texel_rgb888, /* FetchTexel1D */ + fetch_2d_texel_rgb888, /* FetchTexel2D */ + fetch_3d_texel_rgb888, /* FetchTexel3D */ +}; + +const struct gl_texture_format _mesa_texformat_rgb565 = { + MESA_FORMAT_RGB565, /* MesaFormat */ + GL_RGB, /* BaseFormat */ + GL_UNSIGNED_SHORT_5_6_5, /* Type */ + 5, /* RedBits */ + 6, /* GreenBits */ + 5, /* BlueBits */ + 0, /* AlphaBits */ + 0, /* LuminanceBits */ + 0, /* IntensityBits */ + 0, /* IndexBits */ + 0, /* DepthBits */ + 2, /* TexelBytes */ + fetch_1d_texel_rgb565, /* FetchTexel1D */ + fetch_2d_texel_rgb565, /* FetchTexel2D */ + fetch_3d_texel_rgb565, /* FetchTexel3D */ +}; + +const struct gl_texture_format _mesa_texformat_argb4444 = { + MESA_FORMAT_ARGB4444, /* MesaFormat */ + GL_RGBA, /* BaseFormat */ + GL_UNSIGNED_SHORT_4_4_4_4_REV, /* Type */ + 4, /* RedBits */ + 4, /* GreenBits */ + 4, /* BlueBits */ + 4, /* AlphaBits */ + 0, /* LuminanceBits */ + 0, /* IntensityBits */ + 0, /* IndexBits */ + 0, /* DepthBits */ + 2, /* TexelBytes */ + fetch_1d_texel_argb4444, /* FetchTexel1D */ + fetch_2d_texel_argb4444, /* FetchTexel2D */ + fetch_3d_texel_argb4444, /* FetchTexel3D */ +}; + +const struct gl_texture_format _mesa_texformat_argb1555 = { + MESA_FORMAT_ARGB1555, /* MesaFormat */ + GL_RGBA, /* BaseFormat */ + GL_UNSIGNED_SHORT_1_5_5_5_REV, /* Type */ + 5, /* RedBits */ + 5, /* GreenBits */ + 5, /* BlueBits */ + 1, /* AlphaBits */ + 0, /* LuminanceBits */ + 0, /* IntensityBits */ + 0, /* IndexBits */ + 0, /* DepthBits */ + 2, /* TexelBytes */ + fetch_1d_texel_argb1555, /* FetchTexel1D */ + fetch_2d_texel_argb1555, /* FetchTexel2D */ + fetch_3d_texel_argb1555, /* FetchTexel3D */ +}; + +const struct gl_texture_format _mesa_texformat_al88 = { + MESA_FORMAT_AL88, /* MesaFormat */ + GL_LUMINANCE_ALPHA, /* BaseFormat */ + GL_UNSIGNED_BYTE, /* Type */ + 0, /* RedBits */ + 0, /* GreenBits */ + 0, /* BlueBits */ + 8, /* AlphaBits */ + 8, /* LuminanceBits */ + 0, /* IntensityBits */ + 0, /* IndexBits */ + 0, /* DepthBits */ + 2, /* TexelBytes */ + fetch_1d_texel_al88, /* FetchTexel1D */ + fetch_2d_texel_al88, /* FetchTexel2D */ + fetch_3d_texel_al88, /* FetchTexel3D */ +}; + +const struct gl_texture_format _mesa_texformat_rgb332 = { + MESA_FORMAT_RGB332, /* MesaFormat */ + GL_RGB, /* BaseFormat */ + GL_UNSIGNED_BYTE_3_3_2, /* Type */ + 3, /* RedBits */ + 3, /* GreenBits */ + 2, /* BlueBits */ + 0, /* AlphaBits */ + 0, /* LuminanceBits */ + 0, /* IntensityBits */ + 0, /* IndexBits */ + 0, /* DepthBits */ + 1, /* TexelBytes */ + fetch_1d_texel_rgb332, /* FetchTexel1D */ + fetch_2d_texel_rgb332, /* FetchTexel2D */ + fetch_3d_texel_rgb332, /* FetchTexel3D */ +}; + +const struct gl_texture_format _mesa_texformat_a8 = { + MESA_FORMAT_A8, /* MesaFormat */ + GL_ALPHA, /* BaseFormat */ + GL_UNSIGNED_BYTE, /* Type */ + 0, /* RedBits */ + 0, /* GreenBits */ + 0, /* BlueBits */ + 8, /* AlphaBits */ + 0, /* LuminanceBits */ + 0, /* IntensityBits */ + 0, /* IndexBits */ + 0, /* DepthBits */ + 1, /* TexelBytes */ + fetch_1d_texel_a8, /* FetchTexel1D */ + fetch_2d_texel_a8, /* FetchTexel2D */ + fetch_3d_texel_a8, /* FetchTexel3D */ +}; + +const struct gl_texture_format _mesa_texformat_l8 = { + MESA_FORMAT_L8, /* MesaFormat */ + GL_LUMINANCE, /* BaseFormat */ + GL_UNSIGNED_BYTE, /* Type */ + 0, /* RedBits */ + 0, /* GreenBits */ + 0, /* BlueBits */ + 0, /* AlphaBits */ + 8, /* LuminanceBits */ + 0, /* IntensityBits */ + 0, /* IndexBits */ + 0, /* DepthBits */ + 1, /* TexelBytes */ + fetch_1d_texel_l8, /* FetchTexel1D */ + fetch_2d_texel_l8, /* FetchTexel2D */ + fetch_3d_texel_l8, /* FetchTexel3D */ +}; + +const struct gl_texture_format _mesa_texformat_i8 = { + MESA_FORMAT_I8, /* MesaFormat */ + GL_INTENSITY, /* BaseFormat */ + GL_UNSIGNED_BYTE, /* Type */ + 0, /* RedBits */ + 0, /* GreenBits */ + 0, /* BlueBits */ + 0, /* AlphaBits */ + 0, /* LuminanceBits */ + 8, /* IntensityBits */ + 0, /* IndexBits */ + 0, /* DepthBits */ + 1, /* TexelBytes */ + fetch_1d_texel_i8, /* FetchTexel1D */ + fetch_2d_texel_i8, /* FetchTexel2D */ + fetch_3d_texel_i8, /* FetchTexel3D */ +}; + +const struct gl_texture_format _mesa_texformat_ci8 = { + MESA_FORMAT_CI8, /* MesaFormat */ + GL_COLOR_INDEX, /* BaseFormat */ + GL_UNSIGNED_BYTE, /* Type */ + 0, /* RedBits */ + 0, /* GreenBits */ + 0, /* BlueBits */ + 0, /* AlphaBits */ + 0, /* LuminanceBits */ + 0, /* IntensityBits */ + 8, /* IndexBits */ + 0, /* DepthBits */ + 1, /* TexelBytes */ + fetch_1d_texel_ci8, /* FetchTexel1D */ + fetch_2d_texel_ci8, /* FetchTexel2D */ + fetch_3d_texel_ci8, /* FetchTexel3D */ +}; + + +/* ============================================================= + * Null format: + */ + +const struct gl_texture_format _mesa_null_texformat = { + -1, /* MesaFormat */ + 0, /* BaseFormat */ + 0, /* Type */ + 0, /* RedBits */ + 0, /* GreenBits */ + 0, /* BlueBits */ + 0, /* AlphaBits */ + 0, /* LuminanceBits */ + 0, /* IntensityBits */ + 0, /* IndexBits */ + 0, /* DepthBits */ + 0, /* TexelBytes */ + fetch_null_texel, /* FetchTexel1D */ + fetch_null_texel, /* FetchTexel2D */ + fetch_null_texel, /* FetchTexel3D */ +}; + + + +GLboolean +_mesa_is_hardware_tex_format( const struct gl_texture_format *format ) +{ + return (format->MesaFormat < MESA_FORMAT_RGBA); +} + + +/* Given an internal texture format (or 1, 2, 3, 4) return a pointer + * to a gl_texture_format which which to store the texture. + * This is called via ctx->Driver.ChooseTextureFormat(). + * Hardware drivers should not use this function, but instead a + * specialized function. + */ +const struct gl_texture_format * +_mesa_choose_tex_format( GLcontext *ctx, GLint internalFormat, + GLenum format, GLenum type ) +{ + (void) format; + (void) type; + + switch ( internalFormat ) { + /* GH: Bias towards GL_RGB, GL_RGBA texture formats. This has + * got to be better than sticking them way down the end of this + * huge list. + */ + case 4: /* Quake3 uses this... */ + case GL_RGBA: + return &_mesa_texformat_rgba; + + case 3: /* ... and this. */ + case GL_RGB: + return &_mesa_texformat_rgb; + + /* GH: Okay, keep checking as normal. Still test for GL_RGB, + * GL_RGBA formats first. + */ + case GL_RGBA2: + case GL_RGBA4: + case GL_RGB5_A1: + case GL_RGBA8: + case GL_RGB10_A2: + case GL_RGBA12: + case GL_RGBA16: + return &_mesa_texformat_rgba; + + case GL_R3_G3_B2: + case GL_RGB4: + case GL_RGB5: + case GL_RGB8: + case GL_RGB10: + case GL_RGB12: + case GL_RGB16: + return &_mesa_texformat_rgb; + + case GL_ALPHA: + case GL_ALPHA4: + case GL_ALPHA8: + case GL_ALPHA12: + case GL_ALPHA16: + return &_mesa_texformat_alpha; + + case 1: + case GL_LUMINANCE: + case GL_LUMINANCE4: + case GL_LUMINANCE8: + case GL_LUMINANCE12: + case GL_LUMINANCE16: + return &_mesa_texformat_luminance; + + case 2: + case GL_LUMINANCE_ALPHA: + case GL_LUMINANCE4_ALPHA4: + case GL_LUMINANCE6_ALPHA2: + case GL_LUMINANCE8_ALPHA8: + case GL_LUMINANCE12_ALPHA4: + case GL_LUMINANCE12_ALPHA12: + case GL_LUMINANCE16_ALPHA16: + return &_mesa_texformat_luminance_alpha; + + case GL_INTENSITY: + case GL_INTENSITY4: + case GL_INTENSITY8: + case GL_INTENSITY12: + case GL_INTENSITY16: + return &_mesa_texformat_intensity; + + case GL_COLOR_INDEX: + case GL_COLOR_INDEX1_EXT: + case GL_COLOR_INDEX2_EXT: + case GL_COLOR_INDEX4_EXT: + case GL_COLOR_INDEX8_EXT: + case GL_COLOR_INDEX12_EXT: + case GL_COLOR_INDEX16_EXT: + return &_mesa_texformat_color_index; + + case GL_DEPTH_COMPONENT: + case GL_DEPTH_COMPONENT16_SGIX: + case GL_DEPTH_COMPONENT24_SGIX: + case GL_DEPTH_COMPONENT32_SGIX: + if (!ctx->Extensions.SGIX_depth_texture) + _mesa_problem(ctx, "depth format without GL_SGIX_depth_texture"); + return &_mesa_texformat_depth_component; + + case GL_COMPRESSED_ALPHA_ARB: + if (!ctx->Extensions.ARB_texture_compression) + _mesa_problem(ctx, "texture compression extension not enabled"); + return &_mesa_texformat_alpha; + case GL_COMPRESSED_LUMINANCE_ARB: + if (!ctx->Extensions.ARB_texture_compression) + _mesa_problem(ctx, "texture compression extension not enabled"); + return &_mesa_texformat_luminance; + case GL_COMPRESSED_LUMINANCE_ALPHA_ARB: + if (!ctx->Extensions.ARB_texture_compression) + _mesa_problem(ctx, "texture compression extension not enabled"); + return &_mesa_texformat_luminance_alpha; + case GL_COMPRESSED_INTENSITY_ARB: + if (!ctx->Extensions.ARB_texture_compression) + _mesa_problem(ctx, "texture compression extension not enabled"); + return &_mesa_texformat_intensity; + case GL_COMPRESSED_RGB_ARB: + if (!ctx->Extensions.ARB_texture_compression) + _mesa_problem(ctx, "texture compression extension not enabled"); + return &_mesa_texformat_rgb; + case GL_COMPRESSED_RGBA_ARB: + if (!ctx->Extensions.ARB_texture_compression) + _mesa_problem(ctx, "texture compression extension not enabled"); + return &_mesa_texformat_rgba; + + default: + _mesa_problem(ctx, "unexpected format in _mesa_choose_tex_format()"); + printf("intformat = %d %x\n", internalFormat, internalFormat); + return NULL; + } +} + + + + +/* + * Return the base texture format for the given compressed format + * Called via ctx->Driver.BaseCompressedTexFormat(). + * This function is used by software rasterizers. Hardware drivers + * which support texture compression should not use this function but + * a specialized function instead. + */ +GLint +_mesa_base_compressed_texformat(GLcontext *ctx, GLint intFormat) +{ + switch (intFormat) { + case GL_COMPRESSED_ALPHA_ARB: + return GL_ALPHA; + case GL_COMPRESSED_LUMINANCE_ARB: + return GL_LUMINANCE; + case GL_COMPRESSED_LUMINANCE_ALPHA_ARB: + return GL_LUMINANCE_ALPHA; + case GL_COMPRESSED_INTENSITY_ARB: + return GL_INTENSITY; + case GL_COMPRESSED_RGB_ARB: + return GL_RGB; + case GL_COMPRESSED_RGBA_ARB: + return GL_RGBA; + default: + return -1; /* not a recognized compressed format */ + } +} + + +/* + * Called via ctx->Driver.CompressedTextureSize(). + * This function is only used by software rasterizers. + * Hardware drivers will have to implement a specialized function. + */ +GLint +_mesa_compressed_texture_size(GLcontext *ctx, + const struct gl_texture_image *texImage) +{ + GLint b; + assert(texImage); + assert(texImage->TexFormat); + + b = texImage->Width * texImage->Height * texImage->Depth * + texImage->TexFormat->TexelBytes; + assert(b > 0); + return b; +} Index: dll/opengl/opengl32/mesa/texformat.h =================================================================== --- dll/opengl/opengl32/mesa/texformat.h (revision 0) +++ dll/opengl/opengl32/mesa/texformat.h (working copy) @@ -0,0 +1,131 @@ +/* $Id: texformat.h,v 1.7 2001/06/15 14:18:46 brianp Exp $ */ + +/* + * Mesa 3-D graphics library + * Version: 3.5 + * + * Copyright (C) 1999-2001 Brian Paul 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 + * BRIAN PAUL 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. + * + * Author: + * Gareth Hughes + */ + +#ifndef TEXFORMAT_H +#define TEXFORMAT_H + +#include "mtypes.h" + + +/* The Mesa internal texture image types. These will be set to their + * default value, but may be changed by drivers as required. + */ +enum _format { + /* Hardware-friendly formats. Drivers can override the default + * formats and convert texture images to one of these as required. + * These formats are all little endian, as shown below. They will be + * most useful for x86-based PC graphics card drivers. + * + * NOTE: In the default case, some of these formats will be + * duplicates of the default formats listed above. However, these + * formats guarantee their internal component sizes, while GLchan may + * vary betwen GLubyte, GLushort and GLfloat. + */ + /* msb <------ TEXEL BITS -----------> lsb */ + /* ---- ---- ---- ---- ---- ---- ---- ---- */ + MESA_FORMAT_RGBA8888, /* RRRR RRRR GGGG GGGG BBBB BBBB AAAA AAAA */ + MESA_FORMAT_ARGB8888, /* AAAA AAAA RRRR RRRR GGGG GGGG BBBB BBBB */ + MESA_FORMAT_RGB888, /* RRRR RRRR GGGG GGGG BBBB BBBB */ + MESA_FORMAT_RGB565, /* RRRR RGGG GGGB BBBB */ + MESA_FORMAT_ARGB4444, /* AAAA RRRR GGGG BBBB */ + MESA_FORMAT_ARGB1555, /* ARRR RRGG GGGB BBBB */ + MESA_FORMAT_AL88, /* AAAA AAAA LLLL LLLL */ + MESA_FORMAT_RGB332, /* RRRG GGBB */ + MESA_FORMAT_A8, /* AAAA AAAA */ + MESA_FORMAT_L8, /* LLLL LLLL */ + MESA_FORMAT_I8, /* IIII IIII */ + MESA_FORMAT_CI8, /* CCCC CCCC */ + + /* Generic GLchan-based formats. These are the default formats used + * by the software rasterizer and, unless the driver overrides the + * texture image functions, incoming images will be converted to one + * of these formats. Components are arrays of GLchan values, so + * there will be no big/little endian issues. + * + * NOTE: Because these are based on the GLchan datatype, one cannot + * assume 8 bits per channel with these formats. If you require + * GLubyte per channel, use one of the hardware formats below. + */ + MESA_FORMAT_RGBA, + MESA_FORMAT_RGB, + MESA_FORMAT_ALPHA, + MESA_FORMAT_LUMINANCE, + MESA_FORMAT_LUMINANCE_ALPHA, + MESA_FORMAT_INTENSITY, + MESA_FORMAT_COLOR_INDEX, + MESA_FORMAT_DEPTH_COMPONENT +}; + + +extern GLboolean +_mesa_is_hardware_tex_format( const struct gl_texture_format *format ); + +extern const struct gl_texture_format * +_mesa_choose_tex_format( GLcontext *ctx, GLint internalFormat, + GLenum format, GLenum type ); + +extern GLint +_mesa_base_compressed_texformat(GLcontext *ctx, GLint intFormat); + +extern GLint +_mesa_compressed_texture_size(GLcontext *ctx, + const struct gl_texture_image *texImage); + + +/* The default formats, GLchan per component: + */ +extern const struct gl_texture_format _mesa_texformat_rgba; +extern const struct gl_texture_format _mesa_texformat_rgb; +extern const struct gl_texture_format _mesa_texformat_alpha; +extern const struct gl_texture_format _mesa_texformat_luminance; +extern const struct gl_texture_format _mesa_texformat_luminance_alpha; +extern const struct gl_texture_format _mesa_texformat_intensity; +extern const struct gl_texture_format _mesa_texformat_color_index; +extern const struct gl_texture_format _mesa_texformat_depth_component; + +/* The hardware-friendly formats: + */ +extern const struct gl_texture_format _mesa_texformat_rgba8888; +extern const struct gl_texture_format _mesa_texformat_argb8888; +extern const struct gl_texture_format _mesa_texformat_rgb888; +extern const struct gl_texture_format _mesa_texformat_rgb565; +extern const struct gl_texture_format _mesa_texformat_argb4444; +extern const struct gl_texture_format _mesa_texformat_argb1555; +extern const struct gl_texture_format _mesa_texformat_al88; +extern const struct gl_texture_format _mesa_texformat_rgb332; +extern const struct gl_texture_format _mesa_texformat_a8; +extern const struct gl_texture_format _mesa_texformat_l8; +extern const struct gl_texture_format _mesa_texformat_i8; +extern const struct gl_texture_format _mesa_texformat_ci8; + +/* The null format: + */ +extern const struct gl_texture_format _mesa_null_texformat; + +#endif Index: dll/opengl/opengl32/mesa/texformat_tmp.h =================================================================== --- dll/opengl/opengl32/mesa/texformat_tmp.h (revision 0) +++ dll/opengl/opengl32/mesa/texformat_tmp.h (working copy) @@ -0,0 +1,292 @@ +/* $Id: texformat_tmp.h,v 1.3 2001/03/18 13:37:18 gareth Exp $ */ + +/* + * Mesa 3-D graphics library + * Version: 3.5 + * + * Copyright (C) 1999-2001 Brian Paul 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 + * BRIAN PAUL 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. + * + * Author: + * Gareth Hughes + */ + +#if DIM == 1 + +#define CHAN_SRC( t, i, j, k, sz ) \ + ((GLchan *)(t)->Data + (i) * (sz)) +#define UBYTE_SRC( t, i, j, k, sz ) \ + ((GLubyte *)(t)->Data + (i) * (sz)) +#define USHORT_SRC( t, i, j, k ) \ + ((GLushort *)(t)->Data + (i)) +#define FLOAT_SRC( t, i, j, k ) \ + ((GLfloat *)(t)->Data + (i)) + +#define FETCH(x) fetch_1d_texel_##x + +#elif DIM == 2 + +#define CHAN_SRC( t, i, j, k, sz ) \ + ((GLchan *)(t)->Data + ((t)->Width * (j) + (i)) * (sz)) +#define UBYTE_SRC( t, i, j, k, sz ) \ + ((GLubyte *)(t)->Data + ((t)->Width * (j) + (i)) * (sz)) +#define USHORT_SRC( t, i, j, k ) \ + ((GLushort *)(t)->Data + ((t)->Width * (j) + (i))) +#define FLOAT_SRC( t, i, j, k ) \ + ((GLfloat *)(t)->Data + ((t)->Width * (j) + (i))) + +#define FETCH(x) fetch_2d_texel_##x + +#elif DIM == 3 + +#define CHAN_SRC( t, i, j, k, sz ) \ + (GLchan *)(t)->Data + (((t)->Height * (k) + (j)) * \ + (t)->Width + (i)) * (sz) +#define UBYTE_SRC( t, i, j, k, sz ) \ + ((GLubyte *)(t)->Data + (((t)->Height * (k) + (j)) * \ + (t)->Width + (i)) * (sz)) +#define USHORT_SRC( t, i, j, k ) \ + ((GLushort *)(t)->Data + (((t)->Height * (k) + (j)) * \ + (t)->Width + (i))) +#define FLOAT_SRC( t, i, j, k ) \ + ((GLfloat *)(t)->Data + (((t)->Height * (k) + (j)) * \ + (t)->Width + (i))) + +#define FETCH(x) fetch_3d_texel_##x + +#else +#error illegal number of texture dimensions +#endif + + +static void FETCH(rgba)( const struct gl_texture_image *texImage, + GLint i, GLint j, GLint k, GLvoid *texel ) +{ + const GLchan *src = CHAN_SRC( texImage, i, j, k, 4 ); + GLchan *rgba = (GLchan *) texel; + COPY_CHAN4( rgba, src ); +} + +static void FETCH(rgb)( const struct gl_texture_image *texImage, + GLint i, GLint j, GLint k, GLvoid *texel ) +{ + const GLchan *src = CHAN_SRC( texImage, i, j, k, 3 ); + GLchan *rgba = (GLchan *) texel; + rgba[RCOMP] = src[0]; + rgba[GCOMP] = src[1]; + rgba[BCOMP] = src[2]; + rgba[ACOMP] = CHAN_MAX; +} + +static void FETCH(alpha)( const struct gl_texture_image *texImage, + GLint i, GLint j, GLint k, GLvoid *texel ) +{ + const GLchan *src = CHAN_SRC( texImage, i, j, k, 1 ); + GLchan *rgba = (GLchan *) texel; + rgba[RCOMP] = 0; + rgba[GCOMP] = 0; + rgba[BCOMP] = 0; + rgba[ACOMP] = src[0]; +} + +static void FETCH(luminance)( const struct gl_texture_image *texImage, + GLint i, GLint j, GLint k, GLvoid *texel ) +{ + const GLchan *src = CHAN_SRC( texImage, i, j, k, 1 ); + GLchan *rgba = (GLchan *) texel; + rgba[RCOMP] = src[0]; + rgba[GCOMP] = src[0]; + rgba[BCOMP] = src[0]; + rgba[ACOMP] = CHAN_MAX; +} + +static void FETCH(luminance_alpha)( const struct gl_texture_image *texImage, + GLint i, GLint j, GLint k, GLvoid *texel ) +{ + const GLchan *src = CHAN_SRC( texImage, i, j, k, 2 ); + GLchan *rgba = (GLchan *) texel; + rgba[RCOMP] = src[0]; + rgba[GCOMP] = src[0]; + rgba[BCOMP] = src[0]; + rgba[ACOMP] = src[1]; +} + +static void FETCH(intensity)( const struct gl_texture_image *texImage, + GLint i, GLint j, GLint k, GLvoid *texel ) +{ + const GLchan *src = CHAN_SRC( texImage, i, j, k, 1 ); + GLchan *rgba = (GLchan *) texel; + rgba[RCOMP] = src[0]; + rgba[GCOMP] = src[0]; + rgba[BCOMP] = src[0]; + rgba[ACOMP] = src[0]; +} + +static void FETCH(color_index)( const struct gl_texture_image *texImage, + GLint i, GLint j, GLint k, GLvoid *texel ) +{ + const GLchan *src = CHAN_SRC( texImage, i, j, k, 1 ); + GLchan *index = (GLchan *) texel; + *index = *src; +} + +static void FETCH(depth_component)( const struct gl_texture_image *texImage, + GLint i, GLint j, GLint k, GLvoid *texel ) +{ + const GLfloat *src = FLOAT_SRC( texImage, i, j, k ); + GLfloat *depth = (GLfloat *) texel; + *depth = *src; +} + +static void FETCH(rgba8888)( const struct gl_texture_image *texImage, + GLint i, GLint j, GLint k, GLvoid *texel ) +{ + const GLubyte *src = UBYTE_SRC( texImage, i, j, k, 4 ); + GLchan *rgba = (GLchan *) texel; + rgba[RCOMP] = UBYTE_TO_CHAN( src[3] ); + rgba[GCOMP] = UBYTE_TO_CHAN( src[2] ); + rgba[BCOMP] = UBYTE_TO_CHAN( src[1] ); + rgba[ACOMP] = UBYTE_TO_CHAN( src[0] ); +} + +static void FETCH(argb8888)( const struct gl_texture_image *texImage, + GLint i, GLint j, GLint k, GLvoid *texel ) +{ + const GLubyte *src = UBYTE_SRC( texImage, i, j, k, 4 ); + GLchan *rgba = (GLchan *) texel; + rgba[RCOMP] = UBYTE_TO_CHAN( src[2] ); + rgba[GCOMP] = UBYTE_TO_CHAN( src[1] ); + rgba[BCOMP] = UBYTE_TO_CHAN( src[0] ); + rgba[ACOMP] = UBYTE_TO_CHAN( src[3] ); +} + +static void FETCH(rgb888)( const struct gl_texture_image *texImage, + GLint i, GLint j, GLint k, GLvoid *texel ) +{ + const GLubyte *src = UBYTE_SRC( texImage, i, j, k, 3 ); + GLchan *rgba = (GLchan *) texel; + rgba[RCOMP] = UBYTE_TO_CHAN( src[2] ); + rgba[GCOMP] = UBYTE_TO_CHAN( src[1] ); + rgba[BCOMP] = UBYTE_TO_CHAN( src[0] ); + rgba[ACOMP] = CHAN_MAX; +} + +static void FETCH(rgb565)( const struct gl_texture_image *texImage, + GLint i, GLint j, GLint k, GLvoid *texel ) +{ + const GLushort *src = USHORT_SRC( texImage, i, j, k ); + GLchan *rgba = (GLchan *) texel; GLushort s = *src; + rgba[RCOMP] = UBYTE_TO_CHAN( ((s >> 8) & 0xf8) * 255 / 0xf8 ); + rgba[GCOMP] = UBYTE_TO_CHAN( ((s >> 3) & 0xfc) * 255 / 0xfc ); + rgba[BCOMP] = UBYTE_TO_CHAN( ((s << 3) & 0xf8) * 255 / 0xf8 ); + rgba[ACOMP] = CHAN_MAX; +} + +static void FETCH(argb4444)( const struct gl_texture_image *texImage, + GLint i, GLint j, GLint k, GLvoid *texel ) +{ + const GLushort *src = USHORT_SRC( texImage, i, j, k ); + GLchan *rgba = (GLchan *) texel; GLushort s = *src; + rgba[RCOMP] = UBYTE_TO_CHAN( ((s >> 8) & 0xf) * 255 / 0xf ); + rgba[GCOMP] = UBYTE_TO_CHAN( ((s >> 4) & 0xf) * 255 / 0xf ); + rgba[BCOMP] = UBYTE_TO_CHAN( ((s ) & 0xf) * 255 / 0xf ); + rgba[ACOMP] = UBYTE_TO_CHAN( ((s >> 12) & 0xf) * 255 / 0xf ); +} + +static void FETCH(argb1555)( const struct gl_texture_image *texImage, + GLint i, GLint j, GLint k, GLvoid *texel ) +{ + const GLushort *src = USHORT_SRC( texImage, i, j, k ); + GLchan *rgba = (GLchan *) texel; GLushort s = *src; + rgba[RCOMP] = UBYTE_TO_CHAN( ((s >> 10) & 0xf8) * 255 / 0xf8 ); + rgba[GCOMP] = UBYTE_TO_CHAN( ((s >> 5) & 0xf8) * 255 / 0xf8 ); + rgba[BCOMP] = UBYTE_TO_CHAN( ((s ) & 0xf8) * 255 / 0xf8 ); + rgba[ACOMP] = UBYTE_TO_CHAN( ((s >> 15) & 0x01) * 255 ); +} + +static void FETCH(al88)( const struct gl_texture_image *texImage, + GLint i, GLint j, GLint k, GLvoid *texel ) +{ + const GLubyte *src = UBYTE_SRC( texImage, i, j, k, 2 ); + GLchan *rgba = (GLchan *) texel; + rgba[RCOMP] = UBYTE_TO_CHAN( src[0] ); + rgba[GCOMP] = UBYTE_TO_CHAN( src[0] ); + rgba[BCOMP] = UBYTE_TO_CHAN( src[0] ); + rgba[ACOMP] = UBYTE_TO_CHAN( src[1] ); +} + +static void FETCH(rgb332)( const struct gl_texture_image *texImage, + GLint i, GLint j, GLint k, GLvoid *texel ) +{ + const GLubyte *src = UBYTE_SRC( texImage, i, j, k, 1 ); + GLchan *rgba = (GLchan *) texel; GLubyte s = *src; + rgba[RCOMP] = UBYTE_TO_CHAN( ((s ) & 0xe0) * 255 / 0xe0 ); + rgba[GCOMP] = UBYTE_TO_CHAN( ((s << 3) & 0xe0) * 255 / 0xe0 ); + rgba[BCOMP] = UBYTE_TO_CHAN( ((s << 5) & 0xc0) * 255 / 0xc0 ); + rgba[ACOMP] = CHAN_MAX; +} + +static void FETCH(a8)( const struct gl_texture_image *texImage, + GLint i, GLint j, GLint k, GLvoid *texel ) +{ + const GLubyte *src = UBYTE_SRC( texImage, i, j, k, 1 ); + GLchan *rgba = (GLchan *) texel; + rgba[RCOMP] = 0; + rgba[GCOMP] = 0; + rgba[BCOMP] = 0; + rgba[ACOMP] = UBYTE_TO_CHAN( src[0] ); +} + +static void FETCH(l8)( const struct gl_texture_image *texImage, + GLint i, GLint j, GLint k, GLvoid *texel ) +{ + const GLubyte *src = UBYTE_SRC( texImage, i, j, k, 1 ); + GLchan *rgba = (GLchan *) texel; + rgba[RCOMP] = UBYTE_TO_CHAN( src[0] ); + rgba[GCOMP] = UBYTE_TO_CHAN( src[0] ); + rgba[BCOMP] = UBYTE_TO_CHAN( src[0] ); + rgba[ACOMP] = CHAN_MAX; +} + +static void FETCH(i8)( const struct gl_texture_image *texImage, + GLint i, GLint j, GLint k, GLvoid *texel ) +{ + const GLubyte *src = UBYTE_SRC( texImage, i, j, k, 1 ); + GLchan *rgba = (GLchan *) texel; + rgba[RCOMP] = UBYTE_TO_CHAN( src[0] ); + rgba[GCOMP] = UBYTE_TO_CHAN( src[0] ); + rgba[BCOMP] = UBYTE_TO_CHAN( src[0] ); + rgba[ACOMP] = UBYTE_TO_CHAN( src[0] ); +} + +static void FETCH(ci8)( const struct gl_texture_image *texImage, + GLint i, GLint j, GLint k, GLvoid *texel ) +{ + const GLubyte *src = UBYTE_SRC( texImage, i, j, k, 1 ); + GLchan *index = (GLchan *) texel; + *index = UBYTE_TO_CHAN( *src ); +} + + +#undef CHAN_SRC +#undef UBYTE_SRC +#undef USHORT_SRC +#undef FLOAT_SRC +#undef FETCH +#undef DIM Index: dll/opengl/opengl32/mesa/teximage.c =================================================================== --- dll/opengl/opengl32/mesa/teximage.c (revision 0) +++ dll/opengl/opengl32/mesa/teximage.c (working copy) @@ -0,0 +1,2496 @@ +/* $Id: teximage.c,v 1.98 2001/06/15 14:18:46 brianp Exp $ */ + +/* + * Mesa 3-D graphics library + * Version: 3.5 + * + * Copyright (C) 1999-2001 Brian Paul 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 + * BRIAN PAUL 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. + */ + + +#ifdef PC_HEADER +#include "all.h" +#else +#include "glheader.h" +#include "context.h" +#include "convolve.h" +#include "image.h" +#include "macros.h" +#include "mem.h" +#include "mmath.h" +#include "state.h" +#include "texformat.h" +#include "teximage.h" +#include "texstate.h" +#include "texstore.h" +#include "mtypes.h" +#include "swrast/s_span.h" /* XXX SWRAST hack */ +#endif + + +/* + * NOTES: + * + * Mesa's native texture datatype is GLchan. Native formats are + * GL_ALPHA, GL_LUMINANCE, GL_LUMANCE_ALPHA, GL_INTENSITY, GL_RGB, GL_RGBA, + * and GL_COLOR_INDEX. + * Device drivers are free to implement any internal format they want. + */ + + +#ifdef DEBUG +static void PrintTexture(const struct gl_texture_image *img) +{ + GLuint i, j, c; + const GLchan *data = (const GLchan *) img->Data; + + if (!data) { + printf("No texture data\n"); + return; + } + + switch (img->Format) { + case GL_ALPHA: + case GL_LUMINANCE: + case GL_INTENSITY: + case GL_COLOR_INDEX: + c = 1; + break; + case GL_LUMINANCE_ALPHA: + c = 2; + break; + case GL_RGB: + c = 3; + break; + case GL_RGBA: + c = 4; + break; + default: + _mesa_problem(NULL, "error in PrintTexture\n"); + return; + } + + for (i = 0; i < img->Height; i++) { + for (j = 0; j < img->Width; j++) { + if (c==1) + printf("%02x ", data[0]); + else if (c==2) + printf("%02x%02x ", data[0], data[1]); + else if (c==3) + printf("%02x%02x%02x ", data[0], data[1], data[2]); + else if (c==4) + printf("%02x%02x%02x%02x ", data[0], data[1], data[2], data[3]); + data += c; + } + printf("\n"); + } +} +#endif + + + +/* + * Compute log base 2 of n. + * If n isn't an exact power of two return -1. + * If n < 0 return -1. + */ +static int +logbase2( int n ) +{ + GLint i = 1; + GLint log2 = 0; + + if (n < 0) { + return -1; + } + + while ( n > i ) { + i *= 2; + log2++; + } + if (i != n) { + return -1; + } + else { + return log2; + } +} + + + +/* + * Given an internal texture format enum or 1, 2, 3, 4 return the + * corresponding _base_ internal format: GL_ALPHA, GL_LUMINANCE, + * GL_LUMANCE_ALPHA, GL_INTENSITY, GL_RGB, or GL_RGBA. + * Return -1 if invalid enum. + */ +GLint +_mesa_base_tex_format( GLcontext *ctx, GLint format ) +{ + /* + * Ask the driver for the base format, if it doesn't + * know, it will return -1; + */ + if (ctx->Driver.BaseCompressedTexFormat) { + GLint ifmt = (*ctx->Driver.BaseCompressedTexFormat)(ctx, format); + if (ifmt >= 0) { + return ifmt; + } + } + switch (format) { + case GL_ALPHA: + case GL_ALPHA4: + case GL_ALPHA8: + case GL_ALPHA12: + case GL_ALPHA16: + return GL_ALPHA; + case 1: + case GL_LUMINANCE: + case GL_LUMINANCE4: + case GL_LUMINANCE8: + case GL_LUMINANCE12: + case GL_LUMINANCE16: + return GL_LUMINANCE; + case 2: + case GL_LUMINANCE_ALPHA: + case GL_LUMINANCE4_ALPHA4: + case GL_LUMINANCE6_ALPHA2: + case GL_LUMINANCE8_ALPHA8: + case GL_LUMINANCE12_ALPHA4: + case GL_LUMINANCE12_ALPHA12: + case GL_LUMINANCE16_ALPHA16: + return GL_LUMINANCE_ALPHA; + case GL_INTENSITY: + case GL_INTENSITY4: + case GL_INTENSITY8: + case GL_INTENSITY12: + case GL_INTENSITY16: + return GL_INTENSITY; + case 3: + case GL_RGB: + case GL_R3_G3_B2: + case GL_RGB4: + case GL_RGB5: + case GL_RGB8: + case GL_RGB10: + case GL_RGB12: + case GL_RGB16: + return GL_RGB; + case 4: + case GL_RGBA: + case GL_RGBA2: + case GL_RGBA4: + case GL_RGB5_A1: + case GL_RGBA8: + case GL_RGB10_A2: + case GL_RGBA12: + case GL_RGBA16: + return GL_RGBA; + case GL_COLOR_INDEX: + case GL_COLOR_INDEX1_EXT: + case GL_COLOR_INDEX2_EXT: + case GL_COLOR_INDEX4_EXT: + case GL_COLOR_INDEX8_EXT: + case GL_COLOR_INDEX12_EXT: + case GL_COLOR_INDEX16_EXT: + return GL_COLOR_INDEX; + case GL_DEPTH_COMPONENT: + case GL_DEPTH_COMPONENT16_SGIX: + case GL_DEPTH_COMPONENT24_SGIX: + case GL_DEPTH_COMPONENT32_SGIX: + if (ctx->Extensions.SGIX_depth_texture) + return GL_DEPTH_COMPONENT; + else + return -1; + default: + return -1; /* error */ + } +} + + +/* + * Test if the given image format is a color/rgba format. That is, + * not color index, depth, stencil, etc. + */ +static GLboolean +is_color_format(GLenum format) +{ + switch (format) { + case GL_ALPHA: + case GL_ALPHA4: + case GL_ALPHA8: + case GL_ALPHA12: + case GL_ALPHA16: + case 1: + case GL_LUMINANCE: + case GL_LUMINANCE4: + case GL_LUMINANCE8: + case GL_LUMINANCE12: + case GL_LUMINANCE16: + case 2: + case GL_LUMINANCE_ALPHA: + case GL_LUMINANCE4_ALPHA4: + case GL_LUMINANCE6_ALPHA2: + case GL_LUMINANCE8_ALPHA8: + case GL_LUMINANCE12_ALPHA4: + case GL_LUMINANCE12_ALPHA12: + case GL_LUMINANCE16_ALPHA16: + case GL_INTENSITY: + case GL_INTENSITY4: + case GL_INTENSITY8: + case GL_INTENSITY12: + case GL_INTENSITY16: + case 3: + case GL_RGB: + case GL_R3_G3_B2: + case GL_RGB4: + case GL_RGB5: + case GL_RGB8: + case GL_RGB10: + case GL_RGB12: + case GL_RGB16: + case 4: + case GL_RGBA: + case GL_RGBA2: + case GL_RGBA4: + case GL_RGB5_A1: + case GL_RGBA8: + case GL_RGB10_A2: + case GL_RGBA12: + case GL_RGBA16: + return GL_TRUE; + default: + return GL_FALSE; + } +} + + +static GLboolean +is_index_format(GLenum format) +{ + switch (format) { + case GL_COLOR_INDEX: + case GL_COLOR_INDEX1_EXT: + case GL_COLOR_INDEX2_EXT: + case GL_COLOR_INDEX4_EXT: + case GL_COLOR_INDEX8_EXT: + case GL_COLOR_INDEX12_EXT: + case GL_COLOR_INDEX16_EXT: + return GL_TRUE; + default: + return GL_FALSE; + } +} + + +/* + * Return GL_TRUE if internalFormat is a compressed format, return GL_FALSE + * otherwise. + */ +static GLboolean +is_compressed_format(GLcontext *ctx, GLenum internalFormat) +{ + if (ctx->Driver.BaseCompressedTexFormat) { + GLint b = (*ctx->Driver.BaseCompressedTexFormat)(ctx, internalFormat); + if (b > 0) + return GL_TRUE; + else + return GL_FALSE; + } + return GL_FALSE; +} + + + +/* + * Store a gl_texture_image pointer in a gl_texture_object structure + * according to the target and level parameters. + * This was basically prompted by the introduction of cube maps. + */ +void +_mesa_set_tex_image(struct gl_texture_object *tObj, + GLenum target, GLint level, + struct gl_texture_image *texImage) +{ + ASSERT(tObj); + ASSERT(texImage); + switch (target) { + case GL_TEXTURE_1D: + case GL_TEXTURE_2D: + case GL_TEXTURE_3D: + tObj->Image[level] = texImage; + return; + case GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB: + tObj->Image[level] = texImage; + return; + case GL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB: + tObj->NegX[level] = texImage; + return; + case GL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB: + tObj->PosY[level] = texImage; + return; + case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_ARB: + tObj->NegY[level] = texImage; + return; + case GL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB: + tObj->PosZ[level] = texImage; + return; + case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB: + tObj->NegZ[level] = texImage; + return; + default: + _mesa_problem(NULL, "bad target in _mesa_set_tex_image()"); + return; + } +} + + + +/* + * Return new gl_texture_image struct with all fields initialized to zero. + */ +struct gl_texture_image * +_mesa_alloc_texture_image( void ) +{ + return CALLOC_STRUCT(gl_texture_image); +} + + + +void +_mesa_free_texture_image( struct gl_texture_image *teximage ) +{ + if (teximage->Data) { + FREE( teximage->Data ); + teximage->Data = NULL; + } + FREE( teximage ); +} + + +/* + * Return GL_TRUE if the target is a proxy target. + */ +static GLboolean +is_proxy_target(GLenum target) +{ + return (target == GL_PROXY_TEXTURE_1D || + target == GL_PROXY_TEXTURE_2D || + target == GL_PROXY_TEXTURE_3D || + target == GL_PROXY_TEXTURE_CUBE_MAP_ARB); +} + + +/* + * Given a texture unit and a texture target, return the corresponding + * texture object. + */ +struct gl_texture_object * +_mesa_select_tex_object(GLcontext *ctx, const struct gl_texture_unit *texUnit, + GLenum target) +{ + switch (target) { + case GL_TEXTURE_1D: + return texUnit->Current1D; + case GL_PROXY_TEXTURE_1D: + return ctx->Texture.Proxy1D; + case GL_TEXTURE_2D: + return texUnit->Current2D; + case GL_PROXY_TEXTURE_2D: + return ctx->Texture.Proxy2D; + case GL_TEXTURE_3D: + return texUnit->Current3D; + case GL_PROXY_TEXTURE_3D: + return ctx->Texture.Proxy3D; + case GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB: + case GL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB: + case GL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB: + case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_ARB: + case GL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB: + case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB: + case GL_TEXTURE_CUBE_MAP_ARB: + return ctx->Extensions.ARB_texture_cube_map + ? texUnit->CurrentCubeMap : NULL; + case GL_PROXY_TEXTURE_CUBE_MAP_ARB: + return ctx->Extensions.ARB_texture_cube_map + ? ctx->Texture.ProxyCubeMap : NULL; + default: + _mesa_problem(NULL, "bad target in _mesa_select_tex_object()"); + return NULL; + } +} + + +/* + * Return the texture image struct which corresponds to target and level + * for the given texture unit. + */ +struct gl_texture_image * +_mesa_select_tex_image(GLcontext *ctx, const struct gl_texture_unit *texUnit, + GLenum target, GLint level) +{ + ASSERT(texUnit); + ASSERT(level < MAX_TEXTURE_LEVELS); + switch (target) { + case GL_TEXTURE_1D: + return texUnit->Current1D->Image[level]; + case GL_PROXY_TEXTURE_1D: + return ctx->Texture.Proxy1D->Image[level]; + case GL_TEXTURE_2D: + return texUnit->Current2D->Image[level]; + case GL_PROXY_TEXTURE_2D: + return ctx->Texture.Proxy2D->Image[level]; + case GL_TEXTURE_3D: + return texUnit->Current3D->Image[level]; + case GL_PROXY_TEXTURE_3D: + return ctx->Texture.Proxy3D->Image[level]; + case GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB: + if (ctx->Extensions.ARB_texture_cube_map) + return texUnit->CurrentCubeMap->Image[level]; + else + return NULL; + case GL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB: + if (ctx->Extensions.ARB_texture_cube_map) + return texUnit->CurrentCubeMap->NegX[level]; + else + return NULL; + case GL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB: + if (ctx->Extensions.ARB_texture_cube_map) + return texUnit->CurrentCubeMap->PosY[level]; + else + return NULL; + case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_ARB: + if (ctx->Extensions.ARB_texture_cube_map) + return texUnit->CurrentCubeMap->NegY[level]; + else + return NULL; + case GL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB: + if (ctx->Extensions.ARB_texture_cube_map) + return texUnit->CurrentCubeMap->PosZ[level]; + else + return NULL; + case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB: + if (ctx->Extensions.ARB_texture_cube_map) + return texUnit->CurrentCubeMap->NegZ[level]; + else + return NULL; + case GL_PROXY_TEXTURE_CUBE_MAP_ARB: + if (ctx->Extensions.ARB_texture_cube_map) + return ctx->Texture.ProxyCubeMap->Image[level]; + else + return NULL; + default: + _mesa_problem(ctx, "bad target in _mesa_select_tex_image()"); + return NULL; + } +} + + + +/* + * glTexImage[123]D can accept a NULL image pointer. In this case we + * create a texture image with unspecified image contents per the OpenGL + * spec. + */ +static GLubyte * +make_null_texture(GLint width, GLint height, GLint depth, GLenum format) +{ + const GLint components = _mesa_components_in_format(format); + const GLint numPixels = width * height * depth; + GLubyte *data = (GLubyte *) MALLOC(numPixels * components * sizeof(GLubyte)); + + /* + * Let's see if anyone finds this. If glTexImage2D() is called with + * a NULL image pointer then load the texture image with something + * interesting instead of leaving it indeterminate. + */ + if (data) { + static const char message[8][32] = { + " X X XXXXX XXX X ", + " XX XX X X X X X ", + " X X X X X X X ", + " X X XXXX XXX XXXXX ", + " X X X X X X ", + " X X X X X X X ", + " X X XXXXX XXX X X ", + " " + }; + + GLubyte *imgPtr = data; + GLint h, i, j, k; + for (h = 0; h < depth; h++) { + for (i = 0; i < height; i++) { + GLint srcRow = 7 - (i % 8); + for (j = 0; j < width; j++) { + GLint srcCol = j % 32; + GLubyte texel = (message[srcRow][srcCol]=='X') ? 255 : 70; + for (k = 0; k < components; k++) { + *imgPtr++ = texel; + } + } + } + } + } + + return data; +} + + + +/* + * Reset the fields of a gl_texture_image struct to zero. + * This is called when a proxy texture test fails, we set all the + * image members (except DriverData) to zero. + * It's also used in glTexImage[123]D as a safeguard to be sure all + * required fields get initialized properly by the Driver.TexImage[123]D + * functions. + */ +static void +clear_teximage_fields(struct gl_texture_image *img) +{ + ASSERT(img); + img->Format = 0; + img->IntFormat = 0; + img->Border = 0; + img->Width = 0; + img->Height = 0; + img->Depth = 0; + img->Width2 = 0; + img->Height2 = 0; + img->Depth2 = 0; + img->WidthLog2 = 0; + img->HeightLog2 = 0; + img->DepthLog2 = 0; + img->Data = NULL; + img->TexFormat = &_mesa_null_texformat; + img->FetchTexel = NULL; + img->IsCompressed = 0; + img->CompressedSize = 0; +} + + +/* + * Initialize basic fields of the gl_texture_image struct. + */ +void +_mesa_init_teximage_fields(GLcontext *ctx, + struct gl_texture_image *img, + GLsizei width, GLsizei height, GLsizei depth, + GLint border, GLenum internalFormat) +{ + ASSERT(img); + img->Format = _mesa_base_tex_format( ctx, internalFormat ); + ASSERT(img->Format > 0); + img->IntFormat = internalFormat; + img->Border = border; + img->Width = width; + img->Height = height; + img->Depth = depth; + img->WidthLog2 = logbase2(width - 2 * border); + if (height == 1) /* 1-D texture */ + img->HeightLog2 = 0; + else + img->HeightLog2 = logbase2(height - 2 * border); + if (depth == 1) /* 2-D texture */ + img->DepthLog2 = 0; + else + img->DepthLog2 = logbase2(depth - 2 * border); + img->Width2 = 1 << img->WidthLog2; + img->Height2 = 1 << img->HeightLog2; + img->Depth2 = 1 << img->DepthLog2; + img->MaxLog2 = MAX2(img->WidthLog2, img->HeightLog2); + img->IsCompressed = is_compressed_format(ctx, internalFormat); +} + + + +/* + * Test glTexImage[123]D() parameters for errors. + * Input: + * dimensions - must be 1 or 2 or 3 + * Return: GL_TRUE = an error was detected, GL_FALSE = no errors + */ +static GLboolean +texture_error_check( GLcontext *ctx, GLenum target, + GLint level, GLint internalFormat, + GLenum format, GLenum type, + GLuint dimensions, + GLint width, GLint height, + GLint depth, GLint border ) +{ + GLboolean isProxy; + GLint iformat; + GLint maxLevels = 0, maxTextureSize; + + if (dimensions == 1) { + isProxy = (GLboolean) (target == GL_PROXY_TEXTURE_1D); + if (target != GL_TEXTURE_1D && !isProxy) { + _mesa_error( ctx, GL_INVALID_ENUM, "glTexImage1D(target)" ); + return GL_TRUE; + } + maxLevels = ctx->Const.MaxTextureLevels; + } + else if (dimensions == 2) { + isProxy = (GLboolean) (target == GL_PROXY_TEXTURE_2D || + target == GL_PROXY_TEXTURE_CUBE_MAP_ARB); + if (target != GL_TEXTURE_2D && !isProxy && + !(ctx->Extensions.ARB_texture_cube_map && + target >= GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB && + target <= GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB)) { + _mesa_error( ctx, GL_INVALID_ENUM, "glTexImage2D(target)" ); + return GL_TRUE; + } + if (target == GL_PROXY_TEXTURE_2D && target == GL_TEXTURE_2D) + maxLevels = ctx->Const.MaxTextureLevels; + else + maxLevels = ctx->Const.MaxCubeTextureLevels; + } + else if (dimensions == 3) { + isProxy = (GLboolean) (target == GL_PROXY_TEXTURE_3D); + if (target != GL_TEXTURE_3D && !isProxy) { + _mesa_error( ctx, GL_INVALID_ENUM, "glTexImage3D(target)" ); + return GL_TRUE; + } + maxLevels = ctx->Const.Max3DTextureLevels; + } + else { + _mesa_problem( ctx, "bad dims in texture_error_check" ); + return GL_TRUE; + } + + ASSERT(maxLevels > 0); + maxTextureSize = 1 << (maxLevels - 1); + + /* Border */ + if (border != 0 && border != 1) { + if (!isProxy) { + char message[100]; + sprintf(message, "glTexImage%dD(border=%d)", dimensions, border); + _mesa_error(ctx, GL_INVALID_VALUE, message); + } + return GL_TRUE; + } + + /* Width */ + if (width < 2 * border || width > 2 + maxTextureSize + || logbase2( width - 2 * border ) < 0) { + if (!isProxy) { + char message[100]; + sprintf(message, "glTexImage%dD(width=%d)", dimensions, width); + _mesa_error(ctx, GL_INVALID_VALUE, message); + } + return GL_TRUE; + } + + /* Height */ + if (dimensions >= 2) { + if (height < 2 * border || height > 2 + maxTextureSize + || logbase2( height - 2 * border ) < 0) { + if (!isProxy) { + char message[100]; + sprintf(message, "glTexImage%dD(height=%d)", dimensions, height); + _mesa_error(ctx, GL_INVALID_VALUE, message); + } + return GL_TRUE; + } + } + + /* For cube map, width must equal height */ + if (target >= GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB && + target <= GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB) { + if (width != height) { + if (!isProxy) { + _mesa_error(ctx, GL_INVALID_VALUE, "glTexImage2D(width != height)"); + } + return GL_TRUE; + } + } + + /* Depth */ + if (dimensions >= 3) { + if (depth < 2 * border || depth > 2 + maxTextureSize + || logbase2( depth - 2 * border ) < 0) { + if (!isProxy) { + char message[100]; + sprintf(message, "glTexImage3D(depth=%d)", depth ); + _mesa_error( ctx, GL_INVALID_VALUE, message ); + } + return GL_TRUE; + } + } + + /* Level */ + if (level < 0 || level >= maxLevels) { + if (!isProxy) { + char message[100]; + sprintf(message, "glTexImage%dD(level=%d)", dimensions, level); + _mesa_error(ctx, GL_INVALID_VALUE, message); + } + return GL_TRUE; + } + + /* For cube map, width must equal height */ + if (target >= GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB && + target <= GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB) { + if (width != height) { + _mesa_error(ctx, GL_INVALID_VALUE, "glTexImage2D(width != height)"); + return GL_TRUE; + } + } + + iformat = _mesa_base_tex_format( ctx, internalFormat ); + if (iformat < 0) { + if (!isProxy) { + char message[100]; + sprintf(message, "glTexImage%dD(internalFormat=0x%x)", dimensions, + internalFormat); + _mesa_error(ctx, GL_INVALID_VALUE, message); + } + return GL_TRUE; + } + + ASSERT(iformat > 0); + + if (!is_compressed_format( ctx, internalFormat ) && + !_mesa_is_legal_format_and_type( format, type )) { + /* Yes, generate GL_INVALID_OPERATION, not GL_INVALID_ENUM, if there + * is a type/format mismatch. See 1.2 spec page 94, sec 3.6.4. + */ + if (!isProxy) { + char message[100]; + sprintf(message, "glTexImage%dD(format or type)", dimensions); + _mesa_error(ctx, GL_INVALID_OPERATION, message); + } + return GL_TRUE; + } + + /* if we get here, the parameters are OK */ + return GL_FALSE; +} + + + +/* + * Test glTexSubImage[123]D() parameters for errors. + * Input: + * dimensions - must be 1 or 2 or 3 + * Return: GL_TRUE = an error was detected, GL_FALSE = no errors + */ +static GLboolean +subtexture_error_check( GLcontext *ctx, GLuint dimensions, + GLenum target, GLint level, + GLint xoffset, GLint yoffset, GLint zoffset, + GLint width, GLint height, GLint depth, + GLenum format, GLenum type ) +{ + struct gl_texture_unit *texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit]; + struct gl_texture_image *destTex; + GLint maxLevels = 0; + GLboolean compressed; + + if (dimensions == 1) { + if (target != GL_TEXTURE_1D) { + _mesa_error( ctx, GL_INVALID_ENUM, "glTexSubImage1D(target)" ); + return GL_TRUE; + } + maxLevels = ctx->Const.MaxTextureLevels; + } + else if (dimensions == 2) { + if (ctx->Extensions.ARB_texture_cube_map) { + if ((target < GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB || + target > GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB) && + target != GL_TEXTURE_2D) { + _mesa_error( ctx, GL_INVALID_ENUM, "glTexSubImage2D(target)" ); + return GL_TRUE; + } + } + else if (target != GL_TEXTURE_2D) { + _mesa_error( ctx, GL_INVALID_ENUM, "glTexSubImage2D(target)" ); + return GL_TRUE; + } + if (target == GL_PROXY_TEXTURE_2D && target == GL_TEXTURE_2D) + maxLevels = ctx->Const.MaxTextureLevels; + else + maxLevels = ctx->Const.MaxCubeTextureLevels; + } + else if (dimensions == 3) { + if (target != GL_TEXTURE_3D) { + _mesa_error( ctx, GL_INVALID_ENUM, "glTexSubImage3D(target)" ); + return GL_TRUE; + } + maxLevels = ctx->Const.Max3DTextureLevels; + } + else { + _mesa_problem( ctx, "bad dims in texture_error_check" ); + return GL_TRUE; + } + + ASSERT(maxLevels > 0); + + if (level < 0 || level >= maxLevels) { + char message[100]; + sprintf(message, "glTexSubImage2D(level=%d)", level); + _mesa_error(ctx, GL_INVALID_ENUM, message); + return GL_TRUE; + } + + if (width < 0) { + char message[100]; + sprintf(message, "glTexSubImage%dD(width=%d)", dimensions, width); + _mesa_error(ctx, GL_INVALID_VALUE, message); + return GL_TRUE; + } + if (height < 0 && dimensions > 1) { + char message[100]; + sprintf(message, "glTexSubImage%dD(height=%d)", dimensions, height); + _mesa_error(ctx, GL_INVALID_VALUE, message); + return GL_TRUE; + } + if (depth < 0 && dimensions > 2) { + char message[100]; + sprintf(message, "glTexSubImage%dD(depth=%d)", dimensions, depth); + _mesa_error(ctx, GL_INVALID_VALUE, message); + return GL_TRUE; + } + + destTex = _mesa_select_tex_image(ctx, texUnit, target, level); + + if (!destTex) { + _mesa_error(ctx, GL_INVALID_OPERATION, "glTexSubImage2D"); + return GL_TRUE; + } + + if (xoffset < -((GLint)destTex->Border)) { + _mesa_error(ctx, GL_INVALID_VALUE, "glTexSubImage1/2/3D(xoffset)"); + return GL_TRUE; + } + if (xoffset + width > (GLint) (destTex->Width + destTex->Border)) { + _mesa_error(ctx, GL_INVALID_VALUE, "glTexSubImage1/2/3D(xoffset+width)"); + return GL_TRUE; + } + if (dimensions > 1) { + if (yoffset < -((GLint)destTex->Border)) { + _mesa_error(ctx, GL_INVALID_VALUE, "glTexSubImage2/3D(yoffset)"); + return GL_TRUE; + } + if (yoffset + height > (GLint) (destTex->Height + destTex->Border)) { + _mesa_error(ctx, GL_INVALID_VALUE, "glTexSubImage2/3D(yoffset+height)"); + return GL_TRUE; + } + } + if (dimensions > 2) { + if (zoffset < -((GLint)destTex->Border)) { + _mesa_error(ctx, GL_INVALID_VALUE, "glTexSubImage3D(zoffset)"); + return GL_TRUE; + } + if (zoffset + depth > (GLint) (destTex->Depth + destTex->Border)) { + _mesa_error(ctx, GL_INVALID_VALUE, "glTexSubImage3D(zoffset+depth)"); + return GL_TRUE; + } + } + + compressed = is_compressed_format(ctx, destTex->IntFormat); + + if (!compressed && !_mesa_is_legal_format_and_type(format, type)) { + char message[100]; + sprintf(message, "glTexSubImage%dD(format or type)", dimensions); + _mesa_error(ctx, GL_INVALID_ENUM, message); + return GL_TRUE; + } + + if (compressed) { + if (xoffset != -destTex->Border) { + _mesa_error(ctx, GL_INVALID_OPERATION, + "glTexSubImage1/2/3D(xoffset != -border"); + return GL_TRUE; + } + if (dimensions > 1 && yoffset != -destTex->Border) { + _mesa_error(ctx, GL_INVALID_OPERATION, + "glTexSubImage2/3D(yoffset != -border"); + return GL_TRUE; + } + if (dimensions > 2 && zoffset != -destTex->Border) { + _mesa_error(ctx, GL_INVALID_OPERATION, + "glTexSubImage3D(zoffset != -border"); + return GL_TRUE; + } + } + + return GL_FALSE; +} + + +/* + * Test glCopyTexImage[12]D() parameters for errors. + * Input: dimensions - must be 1 or 2 or 3 + * Return: GL_TRUE = an error was detected, GL_FALSE = no errors + */ +static GLboolean +copytexture_error_check( GLcontext *ctx, GLuint dimensions, + GLenum target, GLint level, GLint internalFormat, + GLint width, GLint height, GLint border ) +{ + GLint iformat; + GLint maxLevels = 0, maxTextureSize; + + if (dimensions == 1) { + if (target != GL_TEXTURE_1D) { + _mesa_error( ctx, GL_INVALID_ENUM, "glCopyTexImage1D(target)" ); + return GL_TRUE; + } + maxLevels = ctx->Const.MaxTextureLevels; + } + else if (dimensions == 2) { + if (ctx->Extensions.ARB_texture_cube_map) { + if ((target < GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB || + target > GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB) && + target != GL_TEXTURE_2D) { + _mesa_error( ctx, GL_INVALID_ENUM, "glCopyTexImage2D(target)" ); + return GL_TRUE; + } + } + else if (target != GL_TEXTURE_2D) { + _mesa_error( ctx, GL_INVALID_ENUM, "glCopyTexImage2D(target)" ); + return GL_TRUE; + } + if (target == GL_PROXY_TEXTURE_2D && target == GL_TEXTURE_2D) + maxLevels = ctx->Const.MaxTextureLevels; + else + maxLevels = ctx->Const.MaxCubeTextureLevels; + } + + ASSERT(maxLevels > 0); + maxTextureSize = 1 << (maxLevels - 1); + + /* Border */ + if (border != 0 && border != 1) { + char message[100]; + sprintf(message, "glCopyTexImage%dD(border)", dimensions); + _mesa_error(ctx, GL_INVALID_VALUE, message); + return GL_TRUE; + } + + /* Width */ + if (width < 2 * border || width > 2 + maxTextureSize + || logbase2( width - 2 * border ) < 0) { + char message[100]; + sprintf(message, "glCopyTexImage%dD(width=%d)", dimensions, width); + _mesa_error(ctx, GL_INVALID_VALUE, message); + return GL_TRUE; + } + + /* Height */ + if (dimensions >= 2) { + if (height < 2 * border || height > 2 + maxTextureSize + || logbase2( height - 2 * border ) < 0) { + char message[100]; + sprintf(message, "glCopyTexImage%dD(height=%d)", dimensions, height); + _mesa_error(ctx, GL_INVALID_VALUE, message); + return GL_TRUE; + } + } + + /* For cube map, width must equal height */ + if (target >= GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB && + target <= GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB) { + if (width != height) { + _mesa_error(ctx, GL_INVALID_VALUE, "glCopyTexImage2D(width != height)"); + return GL_TRUE; + } + } + + /* Level */ + if (level < 0 || level >= maxLevels) { + char message[100]; + sprintf(message, "glCopyTexImage%dD(level=%d)", dimensions, level); + _mesa_error(ctx, GL_INVALID_VALUE, message); + return GL_TRUE; + } + + iformat = _mesa_base_tex_format(ctx, internalFormat); + if (iformat < 0) { + char message[100]; + sprintf(message, "glCopyTexImage%dD(internalFormat)", dimensions); + _mesa_error(ctx, GL_INVALID_VALUE, message); + return GL_TRUE; + } + + /* if we get here, the parameters are OK */ + return GL_FALSE; +} + + +static GLboolean +copytexsubimage_error_check( GLcontext *ctx, GLuint dimensions, + GLenum target, GLint level, + GLint xoffset, GLint yoffset, GLint zoffset, + GLsizei width, GLsizei height ) +{ + struct gl_texture_unit *texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit]; + struct gl_texture_image *teximage; + GLint maxLevels = 0; + GLboolean compressed; + + if (dimensions == 1) { + if (target != GL_TEXTURE_1D) { + _mesa_error( ctx, GL_INVALID_ENUM, "glCopyTexSubImage1D(target)" ); + return GL_TRUE; + } + maxLevels = ctx->Const.MaxTextureLevels; + } + else if (dimensions == 2) { + if (ctx->Extensions.ARB_texture_cube_map) { + if ((target < GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB || + target > GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB) && + target != GL_TEXTURE_2D) { + _mesa_error( ctx, GL_INVALID_ENUM, "glCopyTexSubImage2D(target)" ); + return GL_TRUE; + } + } + else if (target != GL_TEXTURE_2D) { + _mesa_error( ctx, GL_INVALID_ENUM, "glCopyTexSubImage2D(target)" ); + return GL_TRUE; + } + if (target == GL_PROXY_TEXTURE_2D && target == GL_TEXTURE_2D) + maxLevels = ctx->Const.MaxTextureLevels; + else + maxLevels = ctx->Const.MaxCubeTextureLevels; + } + else if (dimensions == 3) { + if (target != GL_TEXTURE_3D) { + _mesa_error( ctx, GL_INVALID_ENUM, "glCopyTexSubImage3D(target)" ); + return GL_TRUE; + } + maxLevels = ctx->Const.Max3DTextureLevels; + } + + ASSERT(maxLevels > 0); + + if (level < 0 || level >= maxLevels) { + char message[100]; + sprintf(message, "glCopyTexSubImage%dD(level=%d)", dimensions, level); + _mesa_error(ctx, GL_INVALID_VALUE, message); + return GL_TRUE; + } + + if (width < 0) { + char message[100]; + sprintf(message, "glCopyTexSubImage%dD(width=%d)", dimensions, width); + _mesa_error(ctx, GL_INVALID_VALUE, message); + return GL_TRUE; + } + if (dimensions > 1 && height < 0) { + char message[100]; + sprintf(message, "glCopyTexSubImage%dD(height=%d)", dimensions, height); + _mesa_error(ctx, GL_INVALID_VALUE, message); + return GL_TRUE; + } + + teximage = _mesa_select_tex_image(ctx, texUnit, target, level); + if (!teximage) { + char message[100]; + sprintf(message, "glCopyTexSubImage%dD(undefined texture)", dimensions); + _mesa_error(ctx, GL_INVALID_OPERATION, message); + return GL_TRUE; + } + + if (xoffset < -((GLint)teximage->Border)) { + char message[100]; + sprintf(message, "glCopyTexSubImage%dD(xoffset=%d)", dimensions, xoffset); + _mesa_error(ctx, GL_INVALID_VALUE, message); + return GL_TRUE; + } + if (xoffset + width > (GLint) (teximage->Width + teximage->Border)) { + char message[100]; + sprintf(message, "glCopyTexSubImage%dD(xoffset+width)", dimensions); + _mesa_error(ctx, GL_INVALID_VALUE, message); + return GL_TRUE; + } + if (dimensions > 1) { + if (yoffset < -((GLint)teximage->Border)) { + char message[100]; + sprintf(message, "glCopyTexSubImage%dD(yoffset=%d)", dimensions, yoffset); + _mesa_error(ctx, GL_INVALID_VALUE, message); + return GL_TRUE; + } + /* NOTE: we're adding the border here, not subtracting! */ + if (yoffset + height > (GLint) (teximage->Height + teximage->Border)) { + char message[100]; + sprintf(message, "glCopyTexSubImage%dD(yoffset+height)", dimensions); + _mesa_error(ctx, GL_INVALID_VALUE, message); + return GL_TRUE; + } + } + + if (dimensions > 2) { + if (zoffset < -((GLint)teximage->Border)) { + char message[100]; + sprintf(message, "glCopyTexSubImage%dD(zoffset)", dimensions); + _mesa_error(ctx, GL_INVALID_VALUE, message); + return GL_TRUE; + } + if (zoffset > (GLint) (teximage->Depth + teximage->Border)) { + char message[100]; + sprintf(message, "glCopyTexSubImage%dD(zoffset+depth)", dimensions); + _mesa_error(ctx, GL_INVALID_VALUE, message); + return GL_TRUE; + } + } + + compressed = is_compressed_format(ctx, teximage->IntFormat); + if (compressed) { + if (xoffset != -teximage->Border) { + _mesa_error(ctx, GL_INVALID_OPERATION, + "glCopyTexSubImage1/2/3D(xoffset != -border"); + return GL_TRUE; + } + if (dimensions > 1 && yoffset != -teximage->Border) { + _mesa_error(ctx, GL_INVALID_OPERATION, + "glCopyTexSubImage2/3D(yoffset != -border"); + return GL_TRUE; + } + if (dimensions > 2 && zoffset != -teximage->Border) { + _mesa_error(ctx, GL_INVALID_OPERATION, + "glCopyTexSubImage3D(zoffset != -border"); + return GL_TRUE; + } + } + + /* if we get here, the parameters are OK */ + return GL_FALSE; +} + + + +void +_mesa_GetTexImage( GLenum target, GLint level, GLenum format, + GLenum type, GLvoid *pixels ) +{ + const struct gl_texture_unit *texUnit; + const struct gl_texture_object *texObj; + struct gl_texture_image *texImage; + GLint maxLevels = 0; + GET_CURRENT_CONTEXT(ctx); + ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx); + + texUnit = &(ctx->Texture.Unit[ctx->Texture.CurrentUnit]); + texObj = _mesa_select_tex_object(ctx, texUnit, target); + if (!texObj || is_proxy_target(target)) { + _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexImage(target)"); + return; + } + + if (target == GL_TEXTURE_1D || target == GL_TEXTURE_2D) { + maxLevels = ctx->Const.MaxTextureLevels; + } + else if (target == GL_TEXTURE_3D) { + maxLevels = ctx->Const.Max3DTextureLevels; + } + else { + maxLevels = ctx->Const.MaxCubeTextureLevels; + } + + ASSERT(maxLevels > 0); + + if (level < 0 || level >= maxLevels) { + _mesa_error( ctx, GL_INVALID_VALUE, "glGetTexImage(level)" ); + return; + } + + if (_mesa_sizeof_type(type) <= 0) { + _mesa_error( ctx, GL_INVALID_ENUM, "glGetTexImage(type)" ); + return; + } + + if (_mesa_components_in_format(format) <= 0 || + format == GL_STENCIL_INDEX) { + _mesa_error( ctx, GL_INVALID_ENUM, "glGetTexImage(format)" ); + return; + } + + if (!ctx->Extensions.EXT_paletted_texture && is_index_format(format)) { + _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexImage(format)"); + } + + if (!ctx->Extensions.SGIX_depth_texture && format == GL_DEPTH_COMPONENT) { + _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexImage(format)"); + } + + /* XXX what if format/type doesn't match texture format/type? */ + + if (!pixels) + return; + + texImage = _mesa_select_tex_image(ctx, texUnit, target, level); + if (!texImage) { + /* invalid mipmap level, not an error */ + return; + } + + if (!texImage->Data) { + /* no image data, not an error */ + return; + } + + { + const GLint width = texImage->Width; + const GLint height = texImage->Height; + const GLint depth = texImage->Depth; + GLint img, row; + for (img = 0; img < depth; img++) { + for (row = 0; row < height; row++) { + /* compute destination address in client memory */ + GLvoid *dest = _mesa_image_address( &ctx->Unpack, pixels, + width, height, format, type, + img, row, 0); + assert(dest); + + if (format == GL_COLOR_INDEX) { + GLuint indexRow[MAX_WIDTH]; + GLint col; + for (col = 0; col < width; col++) { + (*texImage->FetchTexel)(texImage, col, row, img, + (GLvoid *) &indexRow[col]); + } + _mesa_pack_index_span(ctx, width, type, dest, + indexRow, &ctx->Pack, + 0 /* no image transfer */); + } + else if (format == GL_DEPTH_COMPONENT) { + GLfloat depthRow[MAX_WIDTH]; + GLint col; + for (col = 0; col < width; col++) { + (*texImage->FetchTexel)(texImage, col, row, img, + (GLvoid *) &depthRow[col]); + } + _mesa_pack_depth_span(ctx, width, dest, type, + depthRow, &ctx->Pack); + } + else { + /* general case: convert row to RGBA format */ + GLchan rgba[MAX_WIDTH][4]; + GLint col; + for (col = 0; col < width; col++) { + (*texImage->FetchTexel)(texImage, col, row, img, + (GLvoid *) rgba[col]); + } + _mesa_pack_rgba_span(ctx, width, (const GLchan (*)[4])rgba, + format, type, dest, &ctx->Pack, + 0 /* no image transfer */); + } /* format */ + } /* row */ + } /* img */ + } +} + + + +/* + * Called from the API. Note that width includes the border. + */ +void +_mesa_TexImage1D( GLenum target, GLint level, GLint internalFormat, + GLsizei width, GLint border, GLenum format, + GLenum type, const GLvoid *pixels ) +{ + GLsizei postConvWidth = width; + GET_CURRENT_CONTEXT(ctx); + ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx); + + if (is_color_format(internalFormat)) { + _mesa_adjust_image_for_convolution(ctx, 1, &postConvWidth, NULL); + } + + if (target == GL_TEXTURE_1D) { + struct gl_texture_unit *texUnit; + struct gl_texture_object *texObj; + struct gl_texture_image *texImage; + + if (texture_error_check(ctx, target, level, internalFormat, + format, type, 1, postConvWidth, 1, 1, border)) { + return; /* error was recorded */ + } + + texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit]; + texObj = _mesa_select_tex_object(ctx, texUnit, target); + texImage = _mesa_select_tex_image(ctx, texUnit, target, level); + + if (!texImage) { + texImage = _mesa_alloc_texture_image(); + texObj->Image[level] = texImage; + if (!texImage) { + _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage1D"); + return; + } + } + else if (texImage->Data) { + /* free the old texture data */ + FREE(texImage->Data); + texImage->Data = NULL; + } + clear_teximage_fields(texImage); /* not really needed, but helpful */ + _mesa_init_teximage_fields(ctx, texImage, postConvWidth, 1, 1, + border, internalFormat); + + if (ctx->NewState & _NEW_PIXEL) + _mesa_update_state(ctx); + + ASSERT(ctx->Driver.TexImage1D); + if (pixels) { + (*ctx->Driver.TexImage1D)(ctx, target, level, internalFormat, + width, border, format, type, pixels, + &ctx->Unpack, texObj, texImage); + } + else { + GLubyte *dummy = make_null_texture(width, 1, 1, format); + if (dummy) { + (*ctx->Driver.TexImage1D)(ctx, target, level, internalFormat, + width, border, + format, GL_UNSIGNED_BYTE, dummy, + &_mesa_native_packing, texObj, texImage); + FREE(dummy); + } + } + + ASSERT(texImage->TexFormat); + if (!texImage->FetchTexel) { + /* If driver didn't explicitly set this, use the default */ + texImage->FetchTexel = texImage->TexFormat->FetchTexel1D; + } + ASSERT(texImage->FetchTexel); + + if (texImage->IsCompressed) { + ASSERT(texImage->CompressedSize > 0); + } + + /* state update */ + texObj->Complete = GL_FALSE; + ctx->NewState |= _NEW_TEXTURE; + } + else if (target == GL_PROXY_TEXTURE_1D) { + /* Proxy texture: check for errors and update proxy state */ + GLenum error = texture_error_check(ctx, target, level, internalFormat, + format, type, 1, + postConvWidth, 1, 1, border); + if (!error) { + struct gl_texture_unit *texUnit; + struct gl_texture_image *texImage; + texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit]; + texImage = _mesa_select_tex_image(ctx, texUnit, target, level); + _mesa_init_teximage_fields(ctx, texImage, postConvWidth, 1, 1, + border, internalFormat); + ASSERT(ctx->Driver.TestProxyTexImage); + error = !(*ctx->Driver.TestProxyTexImage)(ctx, target, level, + internalFormat, format, type, + postConvWidth, 1, 1, border); + } + if (error) { + /* if error, clear all proxy texture image parameters */ + if (level >= 0 && level < ctx->Const.MaxTextureLevels) { + clear_teximage_fields(ctx->Texture.Proxy1D->Image[level]); + } + } + } + else { + _mesa_error( ctx, GL_INVALID_ENUM, "glTexImage1D(target)" ); + return; + } +} + + +void +_mesa_TexImage2D( GLenum target, GLint level, GLint internalFormat, + GLsizei width, GLsizei height, GLint border, + GLenum format, GLenum type, + const GLvoid *pixels ) +{ + GLsizei postConvWidth = width, postConvHeight = height; + GET_CURRENT_CONTEXT(ctx); + ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx); + + if (is_color_format(internalFormat)) { + _mesa_adjust_image_for_convolution(ctx, 2, &postConvWidth, + &postConvHeight); + } + + if (target == GL_TEXTURE_2D || + (ctx->Extensions.ARB_texture_cube_map && + target >= GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB && + target <= GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB)) { + /* non-proxy target */ + struct gl_texture_unit *texUnit; + struct gl_texture_object *texObj; + struct gl_texture_image *texImage; + + if (texture_error_check(ctx, target, level, internalFormat, + format, type, 2, postConvWidth, postConvHeight, + 1, border)) { + return; /* error was recorded */ + } + + texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit]; + texObj = _mesa_select_tex_object(ctx, texUnit, target); + texImage = _mesa_select_tex_image(ctx, texUnit, target, level); + + if (!texImage) { + texImage = _mesa_alloc_texture_image(); + _mesa_set_tex_image(texObj, target, level, texImage); + if (!texImage) { + _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage2D"); + return; + } + } + else if (texImage->Data) { + /* free the old texture data */ + FREE(texImage->Data); + texImage->Data = NULL; + } + clear_teximage_fields(texImage); /* not really needed, but helpful */ + _mesa_init_teximage_fields(ctx, texImage, postConvWidth, postConvHeight, + 1, border, internalFormat); + + if (ctx->NewState & _NEW_PIXEL) + _mesa_update_state(ctx); + + ASSERT(ctx->Driver.TexImage2D); + if (pixels) { + (*ctx->Driver.TexImage2D)(ctx, target, level, internalFormat, + width, height, border, format, type, pixels, + &ctx->Unpack, texObj, texImage); + } + else { + GLubyte *dummy = make_null_texture(width, height, 1, format); + if (dummy) { + (*ctx->Driver.TexImage2D)(ctx, target, level, internalFormat, + width, height, border, + format, GL_UNSIGNED_BYTE, dummy, + &_mesa_native_packing, texObj, texImage); + FREE(dummy); + } + } + + ASSERT(texImage->TexFormat); + if (!texImage->FetchTexel) { + /* If driver didn't explicitly set this, use the default */ + texImage->FetchTexel = texImage->TexFormat->FetchTexel2D; + } + ASSERT(texImage->FetchTexel); + + if (texImage->IsCompressed) { + ASSERT(texImage->CompressedSize > 0); + } + + /* state update */ + texObj->Complete = GL_FALSE; + ctx->NewState |= _NEW_TEXTURE; + } + else if (target == GL_PROXY_TEXTURE_2D) { + /* Proxy texture: check for errors and update proxy state */ + GLenum error = texture_error_check(ctx, target, level, internalFormat, + format, type, 2, + postConvWidth, postConvHeight, 1, border); + if (!error) { + struct gl_texture_unit *texUnit; + struct gl_texture_image *texImage; + texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit]; + texImage = _mesa_select_tex_image(ctx, texUnit, target, level); + _mesa_init_teximage_fields(ctx, texImage, postConvWidth, + postConvHeight, 1, border, internalFormat); + ASSERT(ctx->Driver.TestProxyTexImage); + error = !(*ctx->Driver.TestProxyTexImage)(ctx, target, level, + internalFormat, format, type, + postConvWidth, postConvHeight, 1, border); + } + if (error) { + /* if error, clear all proxy texture image parameters */ + const GLint maxLevels = (target == GL_PROXY_TEXTURE_2D) ? + ctx->Const.MaxTextureLevels : ctx->Const.MaxCubeTextureLevels; + if (level >= 0 && level < maxLevels) { + clear_teximage_fields(ctx->Texture.Proxy2D->Image[level]); + } + } + } + else { + _mesa_error( ctx, GL_INVALID_ENUM, "glTexImage2D(target)" ); + return; + } +} + + +/* + * Called by the API or display list executor. + * Note that width and height include the border. + */ +void +_mesa_TexImage3D( GLenum target, GLint level, GLenum internalFormat, + GLsizei width, GLsizei height, GLsizei depth, + GLint border, GLenum format, GLenum type, + const GLvoid *pixels ) +{ + GET_CURRENT_CONTEXT(ctx); + ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx); + + if (target == GL_TEXTURE_3D) { + struct gl_texture_unit *texUnit; + struct gl_texture_object *texObj; + struct gl_texture_image *texImage; + + if (texture_error_check(ctx, target, level, (GLint) internalFormat, + format, type, 3, width, height, depth, border)) { + return; /* error was recorded */ + } + + texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit]; + texObj = _mesa_select_tex_object(ctx, texUnit, target); + texImage = _mesa_select_tex_image(ctx, texUnit, target, level); + + if (!texImage) { + texImage = _mesa_alloc_texture_image(); + texObj->Image[level] = texImage; + if (!texImage) { + _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage3D"); + return; + } + } + else if (texImage->Data) { + FREE(texImage->Data); + texImage->Data = NULL; + } + clear_teximage_fields(texImage); /* not really needed, but helpful */ + _mesa_init_teximage_fields(ctx, texImage, width, height, depth, border, + internalFormat); + + if (ctx->NewState & _NEW_PIXEL) + _mesa_update_state(ctx); + + ASSERT(ctx->Driver.TexImage3D); + if (pixels) { + (*ctx->Driver.TexImage3D)(ctx, target, level, (GLint) internalFormat, + width, height, depth, border, + format, type, pixels, + &ctx->Unpack, texObj, texImage); + } + else { + GLubyte *dummy = make_null_texture(width, height, depth, format); + if (dummy) { + (*ctx->Driver.TexImage3D)(ctx, target, level, + (GLint) internalFormat, + width, height, depth, border, + format, GL_UNSIGNED_BYTE, dummy, + &_mesa_native_packing, texObj, texImage); + FREE(dummy); + } + } + + ASSERT(texImage->TexFormat); + if (!texImage->FetchTexel) { + /* If driver didn't explicitly set this, use the default */ + texImage->FetchTexel = texImage->TexFormat->FetchTexel3D; + } + ASSERT(texImage->FetchTexel); + + if (texImage->IsCompressed) { + ASSERT(texImage->CompressedSize > 0); + } + + /* state update */ + texObj->Complete = GL_FALSE; + ctx->NewState |= _NEW_TEXTURE; + } + else if (target == GL_PROXY_TEXTURE_3D) { + /* Proxy texture: check for errors and update proxy state */ + GLenum error = texture_error_check(ctx, target, level, internalFormat, + format, type, 3, width, height, depth, border); + if (!error) { + struct gl_texture_unit *texUnit; + struct gl_texture_image *texImage; + texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit]; + texImage = _mesa_select_tex_image(ctx, texUnit, target, level); + _mesa_init_teximage_fields(ctx, texImage, width, height, 1, + border, internalFormat); + ASSERT(ctx->Driver.TestProxyTexImage); + error = !(*ctx->Driver.TestProxyTexImage)(ctx, target, level, + internalFormat, format, type, + width, height, depth, border); + } + if (error) { + /* if error, clear all proxy texture image parameters */ + if (level >= 0 && level < ctx->Const.Max3DTextureLevels) { + clear_teximage_fields(ctx->Texture.Proxy3D->Image[level]); + } + } + } + else { + _mesa_error( ctx, GL_INVALID_ENUM, "glTexImage3D(target)" ); + return; + } +} + + +void +_mesa_TexImage3DEXT( GLenum target, GLint level, GLenum internalFormat, + GLsizei width, GLsizei height, GLsizei depth, + GLint border, GLenum format, GLenum type, + const GLvoid *pixels ) +{ + _mesa_TexImage3D(target, level, internalFormat, width, height, + depth, border, format, type, pixels); +} + + + +void +_mesa_TexSubImage1D( GLenum target, GLint level, + GLint xoffset, GLsizei width, + GLenum format, GLenum type, + const GLvoid *pixels ) +{ + GLsizei postConvWidth = width; + struct gl_texture_unit *texUnit; + struct gl_texture_object *texObj; + struct gl_texture_image *texImage; + GET_CURRENT_CONTEXT(ctx); + ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx); + + if (ctx->NewState & _NEW_PIXEL) + _mesa_update_state(ctx); + + /* XXX should test internal format */ + if (is_color_format(format)) { + _mesa_adjust_image_for_convolution(ctx, 1, &postConvWidth, NULL); + } + + if (subtexture_error_check(ctx, 1, target, level, xoffset, 0, 0, + postConvWidth, 1, 1, format, type)) { + return; /* error was detected */ + } + + texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit]; + texObj = _mesa_select_tex_object(ctx, texUnit, target); + texImage = _mesa_select_tex_image(ctx, texUnit, target, level); + assert(texImage); + + if (width == 0 || !pixels) + return; /* no-op, not an error */ + + /* If we have a border, xoffset=-1 is legal. Bias by border width */ + xoffset += texImage->Border; + + ASSERT(ctx->Driver.TexSubImage1D); + (*ctx->Driver.TexSubImage1D)(ctx, target, level, xoffset, width, + format, type, pixels, &ctx->Unpack, + texObj, texImage); + ctx->NewState |= _NEW_TEXTURE; +} + + +void +_mesa_TexSubImage2D( GLenum target, GLint level, + GLint xoffset, GLint yoffset, + GLsizei width, GLsizei height, + GLenum format, GLenum type, + const GLvoid *pixels ) +{ + GLsizei postConvWidth = width, postConvHeight = height; + struct gl_texture_unit *texUnit; + struct gl_texture_object *texObj; + struct gl_texture_image *texImage; + GET_CURRENT_CONTEXT(ctx); + ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx); + + if (ctx->NewState & _NEW_PIXEL) + _mesa_update_state(ctx); + + /* XXX should test internal format */ + if (is_color_format(format)) { + _mesa_adjust_image_for_convolution(ctx, 2, &postConvWidth, + &postConvHeight); + } + + if (subtexture_error_check(ctx, 2, target, level, xoffset, yoffset, 0, + postConvWidth, postConvHeight, 1, format, type)) { + return; /* error was detected */ + } + + texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit]; + texObj = _mesa_select_tex_object(ctx, texUnit, target); + texImage = _mesa_select_tex_image(ctx, texUnit, target, level); + assert(texImage); + + if (width == 0 || height == 0 || !pixels) + return; /* no-op, not an error */ + + /* If we have a border, xoffset=-1 is legal. Bias by border width */ + xoffset += texImage->Border; + yoffset += texImage->Border; + + ASSERT(ctx->Driver.TexSubImage2D); + (*ctx->Driver.TexSubImage2D)(ctx, target, level, xoffset, yoffset, + width, height, format, type, pixels, + &ctx->Unpack, texObj, texImage); + ctx->NewState |= _NEW_TEXTURE; +} + + + +void +_mesa_TexSubImage3D( GLenum target, GLint level, + GLint xoffset, GLint yoffset, GLint zoffset, + GLsizei width, GLsizei height, GLsizei depth, + GLenum format, GLenum type, + const GLvoid *pixels ) +{ + struct gl_texture_unit *texUnit; + struct gl_texture_object *texObj; + struct gl_texture_image *texImage; + GET_CURRENT_CONTEXT(ctx); + ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx); + + if (ctx->NewState & _NEW_PIXEL) + _mesa_update_state(ctx); + + if (subtexture_error_check(ctx, 3, target, level, xoffset, yoffset, zoffset, + width, height, depth, format, type)) { + return; /* error was detected */ + } + + texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit]; + texObj = _mesa_select_tex_object(ctx, texUnit, target); + texImage = _mesa_select_tex_image(ctx, texUnit, target, level); + assert(texImage); + + if (width == 0 || height == 0 || height == 0 || !pixels) + return; /* no-op, not an error */ + + /* If we have a border, xoffset=-1 is legal. Bias by border width */ + xoffset += texImage->Border; + yoffset += texImage->Border; + zoffset += texImage->Border; + + ASSERT(ctx->Driver.TexSubImage3D); + (*ctx->Driver.TexSubImage3D)(ctx, target, level, + xoffset, yoffset, zoffset, + width, height, depth, + format, type, pixels, + &ctx->Unpack, texObj, texImage ); + ctx->NewState |= _NEW_TEXTURE; +} + + + +void +_mesa_CopyTexImage1D( GLenum target, GLint level, + GLenum internalFormat, + GLint x, GLint y, + GLsizei width, GLint border ) +{ + struct gl_texture_unit *texUnit; + struct gl_texture_object *texObj; + struct gl_texture_image *texImage; + GLsizei postConvWidth = width; + GET_CURRENT_CONTEXT(ctx); + ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx); + + if (ctx->NewState & _NEW_PIXEL) + _mesa_update_state(ctx); + + if (is_color_format(internalFormat)) { + _mesa_adjust_image_for_convolution(ctx, 1, &postConvWidth, NULL); + } + + if (copytexture_error_check(ctx, 1, target, level, internalFormat, + postConvWidth, 1, border)) + return; + + texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit]; + texObj = _mesa_select_tex_object(ctx, texUnit, target); + texImage = _mesa_select_tex_image(ctx, texUnit, target, level); + if (!texImage) { + texImage = _mesa_alloc_texture_image(); + _mesa_set_tex_image(texObj, target, level, texImage); + if (!texImage) { + _mesa_error(ctx, GL_OUT_OF_MEMORY, "glCopyTexImage1D"); + return; + } + } + else if (texImage->Data) { + /* free the old texture data */ + FREE(texImage->Data); + texImage->Data = NULL; + } + + clear_teximage_fields(texImage); /* not really needed, but helpful */ + _mesa_init_teximage_fields(ctx, texImage, postConvWidth, 1, 1, + border, internalFormat); + + + ASSERT(ctx->Driver.CopyTexImage1D); + (*ctx->Driver.CopyTexImage1D)(ctx, target, level, internalFormat, + x, y, width, border); + + ASSERT(texImage->TexFormat); + if (!texImage->FetchTexel) { + /* If driver didn't explicitly set this, use the default */ + texImage->FetchTexel = texImage->TexFormat->FetchTexel1D; + } + ASSERT(texImage->FetchTexel); + + /* state update */ + texObj->Complete = GL_FALSE; + ctx->NewState |= _NEW_TEXTURE; +} + + + +void +_mesa_CopyTexImage2D( GLenum target, GLint level, GLenum internalFormat, + GLint x, GLint y, GLsizei width, GLsizei height, + GLint border ) +{ + struct gl_texture_unit *texUnit; + struct gl_texture_object *texObj; + struct gl_texture_image *texImage; + GLsizei postConvWidth = width, postConvHeight = height; + GET_CURRENT_CONTEXT(ctx); + ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx); + + if (ctx->NewState & _NEW_PIXEL) + _mesa_update_state(ctx); + + if (is_color_format(internalFormat)) { + _mesa_adjust_image_for_convolution(ctx, 2, &postConvWidth, + &postConvHeight); + } + + if (copytexture_error_check(ctx, 2, target, level, internalFormat, + postConvWidth, postConvHeight, border)) + return; + + texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit]; + texObj = _mesa_select_tex_object(ctx, texUnit, target); + texImage = _mesa_select_tex_image(ctx, texUnit, target, level); + if (!texImage) { + texImage = _mesa_alloc_texture_image(); + _mesa_set_tex_image(texObj, target, level, texImage); + if (!texImage) { + _mesa_error(ctx, GL_OUT_OF_MEMORY, "glCopyTexImage2D"); + return; + } + } + else if (texImage->Data) { + /* free the old texture data */ + FREE(texImage->Data); + texImage->Data = NULL; + } + + clear_teximage_fields(texImage); /* not really needed, but helpful */ + _mesa_init_teximage_fields(ctx, texImage, postConvWidth, postConvHeight, 1, + border, internalFormat); + + ASSERT(ctx->Driver.CopyTexImage2D); + (*ctx->Driver.CopyTexImage2D)(ctx, target, level, internalFormat, + x, y, width, height, border); + + ASSERT(texImage->TexFormat); + if (!texImage->FetchTexel) { + /* If driver didn't explicitly set this, use the default */ + texImage->FetchTexel = texImage->TexFormat->FetchTexel2D; + } + ASSERT(texImage->FetchTexel); + + /* state update */ + texObj->Complete = GL_FALSE; + ctx->NewState |= _NEW_TEXTURE; +} + + + +void +_mesa_CopyTexSubImage1D( GLenum target, GLint level, + GLint xoffset, GLint x, GLint y, GLsizei width ) +{ + struct gl_texture_unit *texUnit; + struct gl_texture_object *texObj; + struct gl_texture_image *texImage; + GLsizei postConvWidth = width; + GET_CURRENT_CONTEXT(ctx); + ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx); + + if (ctx->NewState & _NEW_PIXEL) + _mesa_update_state(ctx); + + /* XXX should test internal format */ + _mesa_adjust_image_for_convolution(ctx, 1, &postConvWidth, NULL); + + if (copytexsubimage_error_check(ctx, 1, target, level, + xoffset, 0, 0, postConvWidth, 1)) + return; + + texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit]; + texObj = _mesa_select_tex_object(ctx, texUnit, target); + texImage = _mesa_select_tex_image(ctx, texUnit, target, level); + + /* If we have a border, xoffset=-1 is legal. Bias by border width */ + xoffset += texImage->Border; + + ASSERT(ctx->Driver.CopyTexSubImage1D); + (*ctx->Driver.CopyTexSubImage1D)(ctx, target, level, xoffset, x, y, width); + ctx->NewState |= _NEW_TEXTURE; +} + + + +void +_mesa_CopyTexSubImage2D( GLenum target, GLint level, + GLint xoffset, GLint yoffset, + GLint x, GLint y, GLsizei width, GLsizei height ) +{ + struct gl_texture_unit *texUnit; + struct gl_texture_object *texObj; + struct gl_texture_image *texImage; + GLsizei postConvWidth = width, postConvHeight = height; + GET_CURRENT_CONTEXT(ctx); + ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx); + + if (ctx->NewState & _NEW_PIXEL) + _mesa_update_state(ctx); + + /* XXX should test internal format */ + _mesa_adjust_image_for_convolution(ctx, 2, &postConvWidth, &postConvHeight); + + if (copytexsubimage_error_check(ctx, 2, target, level, xoffset, yoffset, 0, + postConvWidth, postConvHeight)) + return; + + texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit]; + texObj = _mesa_select_tex_object(ctx, texUnit, target); + texImage = _mesa_select_tex_image(ctx, texUnit, target, level); + + /* If we have a border, xoffset=-1 is legal. Bias by border width */ + xoffset += texImage->Border; + yoffset += texImage->Border; + + ASSERT(ctx->Driver.CopyTexSubImage2D); + (*ctx->Driver.CopyTexSubImage2D)(ctx, target, level, + xoffset, yoffset, x, y, width, height); + ctx->NewState |= _NEW_TEXTURE; +} + + + +void +_mesa_CopyTexSubImage3D( GLenum target, GLint level, + GLint xoffset, GLint yoffset, GLint zoffset, + GLint x, GLint y, GLsizei width, GLsizei height ) +{ + struct gl_texture_unit *texUnit; + struct gl_texture_object *texObj; + struct gl_texture_image *texImage; + GLsizei postConvWidth = width, postConvHeight = height; + GET_CURRENT_CONTEXT(ctx); + ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx); + + if (ctx->NewState & _NEW_PIXEL) + _mesa_update_state(ctx); + + /* XXX should test internal format */ + _mesa_adjust_image_for_convolution(ctx, 2, &postConvWidth, &postConvHeight); + + if (copytexsubimage_error_check(ctx, 3, target, level, xoffset, yoffset, + zoffset, postConvWidth, postConvHeight)) + return; + + texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit]; + texObj = _mesa_select_tex_object(ctx, texUnit, target); + texImage = _mesa_select_tex_image(ctx, texUnit, target, level); + + /* If we have a border, xoffset=-1 is legal. Bias by border width */ + xoffset += texImage->Border; + yoffset += texImage->Border; + zoffset += texImage->Border; + + ASSERT(ctx->Driver.CopyTexSubImage3D); + (*ctx->Driver.CopyTexSubImage3D)(ctx, target, level, + xoffset, yoffset, zoffset, + x, y, width, height); + ctx->NewState |= _NEW_TEXTURE; +} + + + +void +_mesa_CompressedTexImage1DARB(GLenum target, GLint level, + GLenum internalFormat, GLsizei width, + GLint border, GLsizei imageSize, + const GLvoid *data) +{ + GET_CURRENT_CONTEXT(ctx); + ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx); + + switch (internalFormat) { + case GL_COMPRESSED_ALPHA_ARB: + case GL_COMPRESSED_LUMINANCE_ARB: + case GL_COMPRESSED_LUMINANCE_ALPHA_ARB: + case GL_COMPRESSED_INTENSITY_ARB: + case GL_COMPRESSED_RGB_ARB: + case GL_COMPRESSED_RGBA_ARB: + _mesa_error(ctx, GL_INVALID_ENUM, "glCompressedTexImage1DARB"); + return; + default: + /* silence compiler warning */ + ; + } + + if (target == GL_TEXTURE_1D) { + struct gl_texture_unit *texUnit; + struct gl_texture_object *texObj; + struct gl_texture_image *texImage; + + if (texture_error_check(ctx, target, level, internalFormat, + GL_NONE, GL_NONE, 1, width, 1, 1, border)) { + return; /* error in texture image was detected */ + } + + texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit]; + texObj = _mesa_select_tex_object(ctx, texUnit, target); + texImage = _mesa_select_tex_image(ctx, texUnit, target, level); + + if (!texImage) { + texImage = _mesa_alloc_texture_image(); + texObj->Image[level] = texImage; + if (!texImage) { + _mesa_error(ctx, GL_OUT_OF_MEMORY, "glCompressedTexImage1DARB"); + return; + } + } + else if (texImage->Data) { + FREE(texImage->Data); + texImage->Data = NULL; + } + + _mesa_init_teximage_fields(ctx, texImage, width, 1, 1, + border, internalFormat); + + if (ctx->Extensions.ARB_texture_compression) { + ASSERT(ctx->Driver.CompressedTexImage1D); + (*ctx->Driver.CompressedTexImage1D)(ctx, target, level, + internalFormat, width, border, + imageSize, data, + texObj, texImage); + ASSERT(texImage->CompressedSize > 0); /* sanity */ + } + + /* state update */ + texObj->Complete = GL_FALSE; + ctx->NewState |= _NEW_TEXTURE; + } + else if (target == GL_PROXY_TEXTURE_1D) { + /* Proxy texture: check for errors and update proxy state */ + GLenum error = texture_error_check(ctx, target, level, internalFormat, + GL_NONE, GL_NONE, 1, width, 1, 1, border); + if (!error) { + struct gl_texture_unit *texUnit; + struct gl_texture_image *texImage; + texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit]; + texImage = _mesa_select_tex_image(ctx, texUnit, target, level); + _mesa_init_teximage_fields(ctx, texImage, width, 1, 1, + border, internalFormat); + ASSERT(ctx->Driver.TestProxyTexImage); + error = !(*ctx->Driver.TestProxyTexImage)(ctx, target, level, + internalFormat, GL_NONE, GL_NONE, + width, 1, 1, border); + } + if (error) { + /* if error, clear all proxy texture image parameters */ + if (level >= 0 && level < ctx->Const.MaxTextureLevels) { + clear_teximage_fields(ctx->Texture.Proxy1D->Image[level]); + } + } + } + else { + _mesa_error(ctx, GL_INVALID_ENUM, "glCompressedTexImage1DARB(target)"); + return; + } +} + + +void +_mesa_CompressedTexImage2DARB(GLenum target, GLint level, + GLenum internalFormat, GLsizei width, + GLsizei height, GLint border, GLsizei imageSize, + const GLvoid *data) +{ + GET_CURRENT_CONTEXT(ctx); + ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx); + + switch (internalFormat) { + case GL_COMPRESSED_ALPHA_ARB: + case GL_COMPRESSED_LUMINANCE_ARB: + case GL_COMPRESSED_LUMINANCE_ALPHA_ARB: + case GL_COMPRESSED_INTENSITY_ARB: + case GL_COMPRESSED_RGB_ARB: + case GL_COMPRESSED_RGBA_ARB: + _mesa_error(ctx, GL_INVALID_ENUM, "glCompressedTexImage2DARB"); + return; + default: + /* silence compiler warning */ + ; + } + + if (target == GL_TEXTURE_2D || + (ctx->Extensions.ARB_texture_cube_map && + target >= GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB && + target <= GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB)) { + struct gl_texture_unit *texUnit; + struct gl_texture_object *texObj; + struct gl_texture_image *texImage; + + if (texture_error_check(ctx, target, level, internalFormat, + GL_NONE, GL_NONE, 1, width, height, 1, border)) { + return; /* error in texture image was detected */ + } + + texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit]; + texObj = _mesa_select_tex_object(ctx, texUnit, target); + texImage = _mesa_select_tex_image(ctx, texUnit, target, level); + + if (!texImage) { + texImage = _mesa_alloc_texture_image(); + texObj->Image[level] = texImage; + if (!texImage) { + _mesa_error(ctx, GL_OUT_OF_MEMORY, "glCompressedTexImage2DARB"); + return; + } + } + else if (texImage->Data) { + FREE(texImage->Data); + texImage->Data = NULL; + } + + _mesa_init_teximage_fields(ctx, texImage, width, height, 1, border, + internalFormat); + + if (ctx->Extensions.ARB_texture_compression) { + ASSERT(ctx->Driver.CompressedTexImage2D); + (*ctx->Driver.CompressedTexImage2D)(ctx, target, level, + internalFormat, width, height, + border, imageSize, data, + texObj, texImage); + ASSERT(texImage->CompressedSize > 0); /* sanity */ + } + + /* state update */ + texObj->Complete = GL_FALSE; + ctx->NewState |= _NEW_TEXTURE; + } + else if (target == GL_PROXY_TEXTURE_2D) { + /* Proxy texture: check for errors and update proxy state */ + GLenum error = texture_error_check(ctx, target, level, internalFormat, + GL_NONE, GL_NONE, 2, width, height, 1, border); + if (!error) { + struct gl_texture_unit *texUnit; + struct gl_texture_image *texImage; + texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit]; + texImage = _mesa_select_tex_image(ctx, texUnit, target, level); + _mesa_init_teximage_fields(ctx, texImage, width, height, 1, + border, internalFormat); + ASSERT(ctx->Driver.TestProxyTexImage); + error = !(*ctx->Driver.TestProxyTexImage)(ctx, target, level, + internalFormat, GL_NONE, GL_NONE, + width, height, 1, border); + } + if (error) { + /* if error, clear all proxy texture image parameters */ + const GLint maxLevels = (target == GL_PROXY_TEXTURE_2D) ? + ctx->Const.MaxTextureLevels : ctx->Const.MaxCubeTextureLevels; + if (level >= 0 && level < maxLevels) { + clear_teximage_fields(ctx->Texture.Proxy2D->Image[level]); + } + } + } + else { + _mesa_error(ctx, GL_INVALID_ENUM, "glCompressedTexImage2DARB(target)"); + return; + } +} + + +void +_mesa_CompressedTexImage3DARB(GLenum target, GLint level, + GLenum internalFormat, GLsizei width, + GLsizei height, GLsizei depth, GLint border, + GLsizei imageSize, const GLvoid *data) +{ + GET_CURRENT_CONTEXT(ctx); + ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx); + + switch (internalFormat) { + case GL_COMPRESSED_ALPHA_ARB: + case GL_COMPRESSED_LUMINANCE_ARB: + case GL_COMPRESSED_LUMINANCE_ALPHA_ARB: + case GL_COMPRESSED_INTENSITY_ARB: + case GL_COMPRESSED_RGB_ARB: + case GL_COMPRESSED_RGBA_ARB: + _mesa_error(ctx, GL_INVALID_ENUM, "glCompressedTexImage3DARB"); + return; + default: + /* silence compiler warning */ + ; + } + + if (target == GL_TEXTURE_3D) { + struct gl_texture_unit *texUnit; + struct gl_texture_object *texObj; + struct gl_texture_image *texImage; + + if (texture_error_check(ctx, target, level, internalFormat, + GL_NONE, GL_NONE, 1, width, height, depth, border)) { + return; /* error in texture image was detected */ + } + + texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit]; + texObj = _mesa_select_tex_object(ctx, texUnit, target); + texImage = _mesa_select_tex_image(ctx, texUnit, target, level); + + if (!texImage) { + texImage = _mesa_alloc_texture_image(); + texObj->Image[level] = texImage; + if (!texImage) { + _mesa_error(ctx, GL_OUT_OF_MEMORY, "glCompressedTexImage3DARB"); + return; + } + } + else if (texImage->Data) { + FREE(texImage->Data); + texImage->Data = NULL; + } + + _mesa_init_teximage_fields(ctx, texImage, width, height, depth, border, + internalFormat); + + if (ctx->Extensions.ARB_texture_compression) { + ASSERT(ctx->Driver.CompressedTexImage3D); + (*ctx->Driver.CompressedTexImage3D)(ctx, target, level, + internalFormat, + width, height, depth, + border, imageSize, data, + texObj, texImage); + ASSERT(texImage->CompressedSize > 0); /* sanity */ + } + + /* state update */ + texObj->Complete = GL_FALSE; + ctx->NewState |= _NEW_TEXTURE; + } + else if (target == GL_PROXY_TEXTURE_3D) { + /* Proxy texture: check for errors and update proxy state */ + GLenum error = texture_error_check(ctx, target, level, internalFormat, + GL_NONE, GL_NONE, 1, width, height, depth, border); + if (!error) { + struct gl_texture_unit *texUnit; + struct gl_texture_image *texImage; + texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit]; + texImage = _mesa_select_tex_image(ctx, texUnit, target, level); + _mesa_init_teximage_fields(ctx, texImage, width, height, depth, + border, internalFormat); + ASSERT(ctx->Driver.TestProxyTexImage); + error = !(*ctx->Driver.TestProxyTexImage)(ctx, target, level, + internalFormat, GL_NONE, GL_NONE, + width, height, depth, border); + } + if (error) { + /* if error, clear all proxy texture image parameters */ + if (level >= 0 && level < ctx->Const.Max3DTextureLevels) { + clear_teximage_fields(ctx->Texture.Proxy3D->Image[level]); + } + } + } + else { + _mesa_error(ctx, GL_INVALID_ENUM, "glCompressedTexImage3DARB(target)"); + return; + } +} + + +void +_mesa_CompressedTexSubImage1DARB(GLenum target, GLint level, GLint xoffset, + GLsizei width, GLenum format, + GLsizei imageSize, const GLvoid *data) +{ + struct gl_texture_unit *texUnit; + struct gl_texture_object *texObj; + struct gl_texture_image *texImage; + GET_CURRENT_CONTEXT(ctx); + ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx); + + if (subtexture_error_check(ctx, 1, target, level, xoffset, 0, 0, + width, 1, 1, format, GL_NONE)) { + return; /* error was detected */ + } + + texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit]; + texObj = _mesa_select_tex_object(ctx, texUnit, target); + texImage = _mesa_select_tex_image(ctx, texUnit, target, level); + assert(texImage); + + if (width == 0 || !data) + return; /* no-op, not an error */ + + if (ctx->Driver.CompressedTexSubImage1D) { + (*ctx->Driver.CompressedTexSubImage1D)(ctx, target, level, + xoffset, width, + format, imageSize, data, + texObj, texImage); + } + ctx->NewState |= _NEW_TEXTURE; +} + + +void +_mesa_CompressedTexSubImage2DARB(GLenum target, GLint level, GLint xoffset, + GLint yoffset, GLsizei width, GLsizei height, + GLenum format, GLsizei imageSize, + const GLvoid *data) +{ + struct gl_texture_unit *texUnit; + struct gl_texture_object *texObj; + struct gl_texture_image *texImage; + GET_CURRENT_CONTEXT(ctx); + ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx); + + if (subtexture_error_check(ctx, 2, target, level, xoffset, yoffset, 0, + width, height, 1, format, GL_NONE)) { + return; /* error was detected */ + } + + texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit]; + texObj = _mesa_select_tex_object(ctx, texUnit, target); + texImage = _mesa_select_tex_image(ctx, texUnit, target, level); + assert(texImage); + + if (width == 0 || height == 0 || !data) + return; /* no-op, not an error */ + + if (ctx->Driver.CompressedTexSubImage2D) { + (*ctx->Driver.CompressedTexSubImage2D)(ctx, target, level, + xoffset, yoffset, width, height, + format, imageSize, data, + texObj, texImage); + } + ctx->NewState |= _NEW_TEXTURE; +} + + +void +_mesa_CompressedTexSubImage3DARB(GLenum target, GLint level, GLint xoffset, + GLint yoffset, GLint zoffset, GLsizei width, + GLsizei height, GLsizei depth, GLenum format, + GLsizei imageSize, const GLvoid *data) +{ + struct gl_texture_unit *texUnit; + struct gl_texture_object *texObj; + struct gl_texture_image *texImage; + GET_CURRENT_CONTEXT(ctx); + ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx); + + if (subtexture_error_check(ctx, 3, target, level, xoffset, yoffset, zoffset, + width, height, depth, format, GL_NONE)) { + return; /* error was detected */ + } + + texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit]; + texObj = _mesa_select_tex_object(ctx, texUnit, target); + texImage = _mesa_select_tex_image(ctx, texUnit, target, level); + assert(texImage); + + if (width == 0 || height == 0 || depth == 0 || !data) + return; /* no-op, not an error */ + + if (ctx->Driver.CompressedTexSubImage3D) { + (*ctx->Driver.CompressedTexSubImage3D)(ctx, target, level, + xoffset, yoffset, zoffset, + width, height, depth, + format, imageSize, data, + texObj, texImage); + } + ctx->NewState |= _NEW_TEXTURE; +} + + +void +_mesa_GetCompressedTexImageARB(GLenum target, GLint level, GLvoid *img) +{ + const struct gl_texture_unit *texUnit; + const struct gl_texture_object *texObj; + struct gl_texture_image *texImage; + GLint maxLevels; + GET_CURRENT_CONTEXT(ctx); + ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx); + + texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit]; + texObj = _mesa_select_tex_object(ctx, texUnit, target); + if (!texObj) { + _mesa_error(ctx, GL_INVALID_ENUM, "glGetCompressedTexImageARB"); + return; + } + + if (target == GL_TEXTURE_1D || target == GL_TEXTURE_2D) { + maxLevels = ctx->Const.MaxTextureLevels; + } + else if (target == GL_TEXTURE_3D) { + maxLevels = ctx->Const.Max3DTextureLevels; + } + else { + maxLevels = ctx->Const.MaxCubeTextureLevels; + } + + ASSERT(maxLevels > 0); + + if (level < 0 || level >= maxLevels) { + _mesa_error(ctx, GL_INVALID_VALUE, "glGetCompressedTexImageARB(level)"); + return; + } + + if (is_proxy_target(target)) { + _mesa_error(ctx, GL_INVALID_ENUM, "glGetCompressedTexImageARB(target)"); + return; + } + + texImage = _mesa_select_tex_image(ctx, texUnit, target, level); + if (!texImage) { + /* probably invalid mipmap level */ + _mesa_error(ctx, GL_INVALID_VALUE, "glGetCompressedTexImageARB(level)"); + return; + } + + if (!texImage->IsCompressed) { + _mesa_error(ctx, GL_INVALID_OPERATION, "glGetCompressedTexImageARB"); + return; + } + + if (!img) + return; + + if (ctx->Extensions.ARB_texture_compression) { + ASSERT(ctx->Driver.GetCompressedTexImage); + (*ctx->Driver.GetCompressedTexImage)(ctx, target, level, img, texObj, + texImage); + } +} Index: dll/opengl/opengl32/mesa/teximage.h =================================================================== --- dll/opengl/opengl32/mesa/teximage.h (revision 0) +++ dll/opengl/opengl32/mesa/teximage.h (working copy) @@ -0,0 +1,203 @@ +/* $Id: teximage.h,v 1.19 2001/05/21 16:41:03 brianp Exp $ */ + +/* + * Mesa 3-D graphics library + * Version: 3.5 + * + * Copyright (C) 1999-2001 Brian Paul 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 + * BRIAN PAUL 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. + */ + + +#ifndef TEXIMAGE_H +#define TEXIMAGE_H + + +#include "mtypes.h" + + +/*** Internal functions ***/ + + +extern GLint +_mesa_base_tex_format( GLcontext *ctx, GLint format ); + + +extern struct gl_texture_image * +_mesa_alloc_texture_image( void ); + + +extern void +_mesa_free_texture_image( struct gl_texture_image *teximage ); + + +extern void +_mesa_init_teximage_fields(GLcontext *ctx, + struct gl_texture_image *img, + GLsizei width, GLsizei height, GLsizei depth, + GLint border, GLenum internalFormat); + + +extern void +_mesa_set_tex_image(struct gl_texture_object *tObj, + GLenum target, GLint level, + struct gl_texture_image *texImage); + + +extern struct gl_texture_object * +_mesa_select_tex_object(GLcontext *ctx, const struct gl_texture_unit *texUnit, + GLenum target); + + +extern struct gl_texture_image * +_mesa_select_tex_image(GLcontext *ctx, const struct gl_texture_unit *texUnit, + GLenum target, GLint level); + + + +/*** API entry point functions ***/ + + +extern void +_mesa_TexImage1D( GLenum target, GLint level, GLint internalformat, + GLsizei width, GLint border, + GLenum format, GLenum type, const GLvoid *pixels ); + + +extern void +_mesa_TexImage2D( GLenum target, GLint level, GLint internalformat, + GLsizei width, GLsizei height, GLint border, + GLenum format, GLenum type, const GLvoid *pixels ); + + +extern void +_mesa_TexImage3D( GLenum target, GLint level, GLenum internalformat, + GLsizei width, GLsizei height, GLsizei depth, GLint border, + GLenum format, GLenum type, const GLvoid *pixels ); + + +extern void +_mesa_TexImage3DEXT( GLenum target, GLint level, GLenum internalformat, + GLsizei width, GLsizei height, GLsizei depth, + GLint border, GLenum format, GLenum type, + const GLvoid *pixels ); + + +extern void +_mesa_GetTexImage( GLenum target, GLint level, + GLenum format, GLenum type, GLvoid *pixels ); + + +extern void +_mesa_TexSubImage1D( GLenum target, GLint level, GLint xoffset, + GLsizei width, + GLenum format, GLenum type, + const GLvoid *pixels ); + + +extern void +_mesa_TexSubImage2D( GLenum target, GLint level, + GLint xoffset, GLint yoffset, + GLsizei width, GLsizei height, + GLenum format, GLenum type, + const GLvoid *pixels ); + + +extern void +_mesa_TexSubImage3D( GLenum target, GLint level, + GLint xoffset, GLint yoffset, GLint zoffset, + GLsizei width, GLsizei height, GLsizei depth, + GLenum format, GLenum type, + const GLvoid *pixels ); + + +extern void +_mesa_CopyTexImage1D( GLenum target, GLint level, GLenum internalformat, + GLint x, GLint y, GLsizei width, GLint border ); + + +extern void +_mesa_CopyTexImage2D( GLenum target, GLint level, + GLenum internalformat, GLint x, GLint y, + GLsizei width, GLsizei height, GLint border ); + + +extern void +_mesa_CopyTexSubImage1D( GLenum target, GLint level, GLint xoffset, + GLint x, GLint y, GLsizei width ); + + +extern void +_mesa_CopyTexSubImage2D( GLenum target, GLint level, + GLint xoffset, GLint yoffset, + GLint x, GLint y, GLsizei width, GLsizei height ); + + +extern void +_mesa_CopyTexSubImage3D( GLenum target, GLint level, + GLint xoffset, GLint yoffset, GLint zoffset, + GLint x, GLint y, GLsizei width, GLsizei height ); + + + +extern void +_mesa_CompressedTexImage1DARB(GLenum target, GLint level, + GLenum internalformat, GLsizei width, + GLint border, GLsizei imageSize, + const GLvoid *data); + +extern void +_mesa_CompressedTexImage2DARB(GLenum target, GLint level, + GLenum internalformat, GLsizei width, + GLsizei height, GLint border, GLsizei imageSize, + const GLvoid *data); + +extern void +_mesa_CompressedTexImage3DARB(GLenum target, GLint level, + GLenum internalformat, GLsizei width, + GLsizei height, GLsizei depth, GLint border, + GLsizei imageSize, const GLvoid *data); + +#ifdef VMS +#define _mesa_CompressedTexSubImage1DARB _mesa_CompressedTexSubImage1DAR +#define _mesa_CompressedTexSubImage2DARB _mesa_CompressedTexSubImage2DAR +#define _mesa_CompressedTexSubImage3DARB _mesa_CompressedTexSubImage3DAR +#endif +extern void +_mesa_CompressedTexSubImage1DARB(GLenum target, GLint level, GLint xoffset, + GLsizei width, GLenum format, + GLsizei imageSize, const GLvoid *data); + +extern void +_mesa_CompressedTexSubImage2DARB(GLenum target, GLint level, GLint xoffset, + GLint yoffset, GLsizei width, GLsizei height, + GLenum format, GLsizei imageSize, + const GLvoid *data); + +extern void +_mesa_CompressedTexSubImage3DARB(GLenum target, GLint level, GLint xoffset, + GLint yoffset, GLint zoffset, GLsizei width, + GLsizei height, GLsizei depth, GLenum format, + GLsizei imageSize, const GLvoid *data); + +extern void +_mesa_GetCompressedTexImageARB(GLenum target, GLint lod, GLvoid *img); + + +#endif Index: dll/opengl/opengl32/mesa/texobj.c =================================================================== --- dll/opengl/opengl32/mesa/texobj.c (revision 0) +++ dll/opengl/opengl32/mesa/texobj.c (working copy) @@ -0,0 +1,757 @@ +/* $Id: texobj.c,v 1.49 2001/06/13 14:56:14 brianp Exp $ */ + +/* + * Mesa 3-D graphics library + * Version: 3.5 + * + * Copyright (C) 1999-2001 Brian Paul 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 + * BRIAN PAUL 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. + */ + + +#ifdef PC_HEADER +#include "all.h" +#else +#include "glheader.h" +#include "colortab.h" +#include "context.h" +#include "enums.h" +#include "hash.h" +#include "macros.h" +#include "mem.h" +#include "teximage.h" +#include "texstate.h" +#include "texobj.h" +#include "mtypes.h" +#endif + + + +/* + * Allocate a new texture object and add it to the linked list of texture + * objects. If name>0 then also insert the new texture object into the hash + * table. + * Input: shared - the shared GL state structure to contain the texture object + * name - integer name for the texture object + * dimensions - either 1, 2, 3 or 6 (cube map) + * zero is ok for the sake of GenTextures() + * Return: pointer to new texture object + */ +struct gl_texture_object * +_mesa_alloc_texture_object( struct gl_shared_state *shared, + GLuint name, GLuint dimensions ) +{ + struct gl_texture_object *obj; + + ASSERT(dimensions <= 3 || dimensions == 6); + + obj = CALLOC_STRUCT(gl_texture_object); + + if (obj) { + /* init the non-zero fields */ + _glthread_INIT_MUTEX(obj->Mutex); + obj->RefCount = 1; + obj->Name = name; + obj->Dimensions = dimensions; + obj->Priority = 1.0F; + obj->WrapS = GL_REPEAT; + obj->WrapT = GL_REPEAT; + obj->WrapR = GL_REPEAT; + obj->MinFilter = GL_NEAREST_MIPMAP_LINEAR; + obj->MagFilter = GL_LINEAR; + obj->MinLod = -1000.0; + obj->MaxLod = 1000.0; + obj->BaseLevel = 0; + obj->MaxLevel = 1000; + obj->MaxAnisotropy = 1.0; + obj->CompareFlag = GL_FALSE; + obj->CompareOperator = GL_TEXTURE_LEQUAL_R_SGIX; + obj->ShadowAmbient = 0; + _mesa_init_colortable(&obj->Palette); + + /* insert into linked list */ + if (shared) { + _glthread_LOCK_MUTEX(shared->Mutex); + obj->Next = shared->TexObjectList; + shared->TexObjectList = obj; + _glthread_UNLOCK_MUTEX(shared->Mutex); + } + + if (name > 0) { + /* insert into hash table */ + _mesa_HashInsert(shared->TexObjects, name, obj); + } + } + return obj; +} + + +/* + * Deallocate a texture object struct and remove it from the given + * shared GL state. + * Input: shared - the shared GL state to which the object belongs + * t - the texture object to delete + */ +void _mesa_free_texture_object( struct gl_shared_state *shared, + struct gl_texture_object *t ) +{ + struct gl_texture_object *tprev, *tcurr; + + assert(t); + + /* unlink t from the linked list */ + if (shared) { + _glthread_LOCK_MUTEX(shared->Mutex); + tprev = NULL; + tcurr = shared->TexObjectList; + while (tcurr) { + if (tcurr==t) { + if (tprev) { + tprev->Next = t->Next; + } + else { + shared->TexObjectList = t->Next; + } + break; + } + tprev = tcurr; + tcurr = tcurr->Next; + } + _glthread_UNLOCK_MUTEX(shared->Mutex); + } + + if (t->Name) { + /* remove from hash table */ + _mesa_HashRemove(shared->TexObjects, t->Name); + } + + _mesa_free_colortable_data(&t->Palette); + + /* free the texture images */ + { + GLuint i; + for (i=0;iImage[i]) { + _mesa_free_texture_image( t->Image[i] ); + } + } + } + + /* free this object */ + FREE( t ); +} + + +/* + * Report why a texture object is incomplete. (for debug only) + */ +#if 0 +static void +incomplete(const struct gl_texture_object *t, const char *why) +{ + printf("Texture Obj %d incomplete because: %s\n", t->Name, why); +} +#else +#define incomplete(a, b) +#endif + + +/* + * Examine a texture object to determine if it is complete. + * The t->Complete flag will be set to GL_TRUE or GL_FALSE accordingly. + */ +void +_mesa_test_texobj_completeness( const GLcontext *ctx, + struct gl_texture_object *t ) +{ + const GLint baseLevel = t->BaseLevel; + GLint maxLog2 = 0, maxLevels = 0; + + t->Complete = GL_TRUE; /* be optimistic */ + + /* Always need the base level image */ + if (!t->Image[baseLevel]) { + incomplete(t, "Image[baseLevel] == NULL"); + t->Complete = GL_FALSE; + return; + } + + /* Compute _MaxLevel */ + if (t->Dimensions == 1) { + maxLog2 = t->Image[baseLevel]->WidthLog2; + maxLevels = ctx->Const.MaxTextureLevels; + } + else if (t->Dimensions == 2 || t->Dimensions == 6) { + maxLog2 = MAX2(t->Image[baseLevel]->WidthLog2, + t->Image[baseLevel]->HeightLog2); + maxLevels = (t->Dimensions == 2) ? + ctx->Const.MaxTextureLevels : ctx->Const.MaxCubeTextureLevels; + } + else if (t->Dimensions == 3) { + GLint max = MAX2(t->Image[baseLevel]->WidthLog2, + t->Image[baseLevel]->HeightLog2); + maxLog2 = MAX2(max, (GLint)(t->Image[baseLevel]->DepthLog2)); + maxLevels = ctx->Const.Max3DTextureLevels; + } + else { + _mesa_problem(ctx, "Bad t->Dimension in _mesa_test_texobj_completeness"); + return; + } + + ASSERT(maxLevels > 0); + + t->_MaxLevel = baseLevel + maxLog2; + t->_MaxLevel = MIN2(t->_MaxLevel, t->MaxLevel); + t->_MaxLevel = MIN2(t->_MaxLevel, maxLevels - 1); + + /* Compute _MaxLambda = q - b (see the 1.2 spec) used during mipmapping */ + t->_MaxLambda = (GLfloat) (t->_MaxLevel - t->BaseLevel); + + if (t->Dimensions == 6) { + /* make sure that all six cube map level 0 images are the same size */ + const GLuint w = t->Image[baseLevel]->Width2; + const GLuint h = t->Image[baseLevel]->Height2; + if (!t->NegX[baseLevel] || + t->NegX[baseLevel]->Width2 != w || + t->NegX[baseLevel]->Height2 != h || + !t->PosY[baseLevel] || + t->PosY[baseLevel]->Width2 != w || + t->PosY[baseLevel]->Height2 != h || + !t->NegY[baseLevel] || + t->NegY[baseLevel]->Width2 != w || + t->NegY[baseLevel]->Height2 != h || + !t->PosZ[baseLevel] || + t->PosZ[baseLevel]->Width2 != w || + t->PosZ[baseLevel]->Height2 != h || + !t->NegZ[baseLevel] || + t->NegZ[baseLevel]->Width2 != w || + t->NegZ[baseLevel]->Height2 != h) { + t->Complete = GL_FALSE; + incomplete(t, "Non-quare cubemap image"); + return; + } + } + + if (t->MinFilter != GL_NEAREST && t->MinFilter != GL_LINEAR) { + /* + * Mipmapping: determine if we have a complete set of mipmaps + */ + GLint i; + GLint minLevel = baseLevel; + GLint maxLevel = t->_MaxLevel; + + if (minLevel > maxLevel) { + t->Complete = GL_FALSE; + incomplete(t, "minLevel > maxLevel"); + return; + } + + /* Test dimension-independent attributes */ + for (i = minLevel; i <= maxLevel; i++) { + if (t->Image[i]) { + if (t->Image[i]->TexFormat != t->Image[baseLevel]->TexFormat) { + t->Complete = GL_FALSE; + incomplete(t, "Format[i] != Format[baseLevel]"); + return; + } + if (t->Image[i]->Border != t->Image[baseLevel]->Border) { + t->Complete = GL_FALSE; + incomplete(t, "Border[i] != Border[baseLevel]"); + return; + } + } + } + + /* Test things which depend on number of texture image dimensions */ + if (t->Dimensions == 1) { + /* Test 1-D mipmaps */ + GLuint width = t->Image[baseLevel]->Width2; + for (i = baseLevel + 1; i < maxLevels; i++) { + if (width > 1) { + width /= 2; + } + if (i >= minLevel && i <= maxLevel) { + if (!t->Image[i]) { + t->Complete = GL_FALSE; + incomplete(t, "1D Image[i] == NULL"); + return; + } + if (t->Image[i]->Width2 != width ) { + t->Complete = GL_FALSE; + incomplete(t, "1D Image[i] bad width"); + return; + } + } + if (width == 1) { + return; /* found smallest needed mipmap, all done! */ + } + } + } + else if (t->Dimensions == 2) { + /* Test 2-D mipmaps */ + GLuint width = t->Image[baseLevel]->Width2; + GLuint height = t->Image[baseLevel]->Height2; + for (i = baseLevel + 1; i < maxLevels; i++) { + if (width > 1) { + width /= 2; + } + if (height > 1) { + height /= 2; + } + if (i >= minLevel && i <= maxLevel) { + if (!t->Image[i]) { + t->Complete = GL_FALSE; + incomplete(t, "2D Image[i] == NULL"); + return; + } + if (t->Image[i]->Width2 != width) { + t->Complete = GL_FALSE; + incomplete(t, "2D Image[i] bad width"); + return; + } + if (t->Image[i]->Height2 != height) { + t->Complete = GL_FALSE; + incomplete(t, "2D Image[i] bad height"); + return; + } + if (width==1 && height==1) { + return; /* found smallest needed mipmap, all done! */ + } + } + } + } + else if (t->Dimensions == 3) { + /* Test 3-D mipmaps */ + GLuint width = t->Image[baseLevel]->Width2; + GLuint height = t->Image[baseLevel]->Height2; + GLuint depth = t->Image[baseLevel]->Depth2; + for (i = baseLevel + 1; i < maxLevels; i++) { + if (width > 1) { + width /= 2; + } + if (height > 1) { + height /= 2; + } + if (depth > 1) { + depth /= 2; + } + if (i >= minLevel && i <= maxLevel) { + if (!t->Image[i]) { + incomplete(t, "3D Image[i] == NULL"); + t->Complete = GL_FALSE; + return; + } + if (t->Image[i]->Width2 != width) { + t->Complete = GL_FALSE; + incomplete(t, "3D Image[i] bad width"); + return; + } + if (t->Image[i]->Height2 != height) { + t->Complete = GL_FALSE; + incomplete(t, "3D Image[i] bad height"); + return; + } + if (t->Image[i]->Depth2 != depth) { + t->Complete = GL_FALSE; + incomplete(t, "3D Image[i] bad depth"); + return; + } + } + if (width == 1 && height == 1 && depth == 1) { + return; /* found smallest needed mipmap, all done! */ + } + } + } + else if (t->Dimensions == 6) { + /* make sure 6 cube faces are consistant */ + GLuint width = t->Image[baseLevel]->Width2; + GLuint height = t->Image[baseLevel]->Height2; + for (i = baseLevel + 1; i < maxLevels; i++) { + if (width > 1) { + width /= 2; + } + if (height > 1) { + height /= 2; + } + if (i >= minLevel && i <= maxLevel) { + /* check that we have images defined */ + if (!t->Image[i] || !t->NegX[i] || + !t->PosY[i] || !t->NegY[i] || + !t->PosZ[i] || !t->NegZ[i]) { + t->Complete = GL_FALSE; + incomplete(t, "CubeMap Image[i] == NULL"); + return; + } + /* check that all six images have same size */ + if (t->NegX[i]->Width2!=width || t->NegX[i]->Height2!=height || + t->PosY[i]->Width2!=width || t->PosY[i]->Height2!=height || + t->NegY[i]->Width2!=width || t->NegY[i]->Height2!=height || + t->PosZ[i]->Width2!=width || t->PosZ[i]->Height2!=height || + t->NegZ[i]->Width2!=width || t->NegZ[i]->Height2!=height) { + t->Complete = GL_FALSE; + incomplete(t, "CubeMap Image[i] bad size"); + return; + } + } + if (width == 1 && height == 1) { + return; /* found smallest needed mipmap, all done! */ + } + } + } + else { + /* Dimensions = ??? */ + _mesa_problem(ctx, "Bug in gl_test_texture_object_completeness\n"); + } + } +} + + +_glthread_DECLARE_STATIC_MUTEX(GenTexturesLock); + + +/* + * Execute glGenTextures + */ +void +_mesa_GenTextures( GLsizei n, GLuint *texName ) +{ + GET_CURRENT_CONTEXT(ctx); + GLuint first; + GLint i; + ASSERT_OUTSIDE_BEGIN_END(ctx); + + if (n < 0) { + _mesa_error( ctx, GL_INVALID_VALUE, "glGenTextures" ); + return; + } + + if (!texName) + return; + + /* + * This must be atomic (generation and allocation of texture IDs) + */ + _glthread_LOCK_MUTEX(GenTexturesLock); + + first = _mesa_HashFindFreeKeyBlock(ctx->Shared->TexObjects, n); + + /* Return the texture names */ + for (i=0;iShared, name, dims); + } + + _glthread_UNLOCK_MUTEX(GenTexturesLock); +} + + + +/* + * Execute glDeleteTextures + */ +void +_mesa_DeleteTextures( GLsizei n, const GLuint *texName) +{ + GET_CURRENT_CONTEXT(ctx); + GLint i; + ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx); /* too complex */ + + if (!texName) + return; + + for (i=0;i 0) { + struct gl_texture_object *delObj = (struct gl_texture_object *) + _mesa_HashLookup(ctx->Shared->TexObjects, texName[i]); + if (delObj) { + /* First check if this texture is currently bound. + * If so, unbind it and decrement the reference count. + */ + GLuint u; + for (u = 0; u < MAX_TEXTURE_UNITS; u++) { + struct gl_texture_unit *unit = &ctx->Texture.Unit[u]; + if (delObj == unit->Current1D) { + unit->Current1D = ctx->Shared->Default1D; + ctx->Shared->Default1D->RefCount++; + } + else if (delObj == unit->Current2D) { + unit->Current2D = ctx->Shared->Default2D; + ctx->Shared->Default2D->RefCount++; + } + else if (delObj == unit->Current3D) { + unit->Current3D = ctx->Shared->Default3D; + ctx->Shared->Default3D->RefCount++; + } + else if (delObj == unit->CurrentCubeMap) { + unit->CurrentCubeMap = ctx->Shared->DefaultCubeMap; + ctx->Shared->DefaultCubeMap->RefCount++; + } + } + ctx->NewState |= _NEW_TEXTURE; + + /* Decrement reference count and delete if zero */ + delObj->RefCount--; + ASSERT(delObj->RefCount >= 0); + + if (delObj->RefCount == 0) { + ASSERT(delObj->Name != 0); + if (ctx->Driver.DeleteTexture) + (*ctx->Driver.DeleteTexture)( ctx, delObj ); + _mesa_free_texture_object(ctx->Shared, delObj); + } + } + } + } +} + + + +/* + * Execute glBindTexture + */ +void +_mesa_BindTexture( GLenum target, GLuint texName ) +{ + GET_CURRENT_CONTEXT(ctx); + GLuint unit = ctx->Texture.CurrentUnit; + struct gl_texture_unit *texUnit = &ctx->Texture.Unit[unit]; + struct gl_texture_object *oldTexObj; + struct gl_texture_object *newTexObj = 0; + GLuint targetDim; + ASSERT_OUTSIDE_BEGIN_END(ctx); + + if (MESA_VERBOSE & (VERBOSE_API|VERBOSE_TEXTURE)) + fprintf(stderr, "glBindTexture %s %d\n", + _mesa_lookup_enum_by_nr(target), (GLint) texName); + + switch (target) { + case GL_TEXTURE_1D: + targetDim = 1; + oldTexObj = texUnit->Current1D; + break; + case GL_TEXTURE_2D: + targetDim = 2; + oldTexObj = texUnit->Current2D; + break; + case GL_TEXTURE_3D: + targetDim = 3; + oldTexObj = texUnit->Current3D; + break; + case GL_TEXTURE_CUBE_MAP_ARB: + if (ctx->Extensions.ARB_texture_cube_map) { + targetDim = 6; + oldTexObj = texUnit->CurrentCubeMap; + break; + } + /* fallthrough */ + default: + _mesa_error( ctx, GL_INVALID_ENUM, "glBindTexture(target)" ); + return; + } + + if (oldTexObj->Name == texName) + return; /* rebinding the same texture- no change */ + + /* + * Get pointer to new texture object (newTexObj) + */ + if (texName == 0) { + /* newTexObj = a default texture object */ + switch (target) { + case GL_TEXTURE_1D: + newTexObj = ctx->Shared->Default1D; + break; + case GL_TEXTURE_2D: + newTexObj = ctx->Shared->Default2D; + break; + case GL_TEXTURE_3D: + newTexObj = ctx->Shared->Default3D; + break; + case GL_TEXTURE_CUBE_MAP_ARB: + newTexObj = ctx->Shared->DefaultCubeMap; + break; + default: + ; /* Bad targets are caught above */ + } + } + else { + /* non-default texture object */ + const struct _mesa_HashTable *hash = ctx->Shared->TexObjects; + newTexObj = (struct gl_texture_object *) _mesa_HashLookup(hash, texName); + if (newTexObj) { + /* error checking */ + if (newTexObj->Dimensions > 0 && newTexObj->Dimensions != targetDim) { + /* the named texture object's dimensions don't match the target */ + _mesa_error( ctx, GL_INVALID_OPERATION, + "glBindTexture(wrong dimensionality)" ); + return; + } + } + else { + /* if this is a new texture id, allocate a texture object now */ + newTexObj = _mesa_alloc_texture_object( ctx->Shared, texName, + targetDim); + if (!newTexObj) { + _mesa_error(ctx, GL_OUT_OF_MEMORY, "glBindTexture"); + return; + } + } + newTexObj->Dimensions = targetDim; + } + + newTexObj->RefCount++; + + /* do the actual binding, but first flush outstanding vertices: + */ + FLUSH_VERTICES(ctx, _NEW_TEXTURE); + + switch (target) { + case GL_TEXTURE_1D: + texUnit->Current1D = newTexObj; + break; + case GL_TEXTURE_2D: + texUnit->Current2D = newTexObj; + break; + case GL_TEXTURE_3D: + texUnit->Current3D = newTexObj; + break; + case GL_TEXTURE_CUBE_MAP_ARB: + texUnit->CurrentCubeMap = newTexObj; + break; + default: + _mesa_problem(ctx, "bad target in BindTexture"); + } + + /* Pass BindTexture call to device driver */ + if (ctx->Driver.BindTexture) + (*ctx->Driver.BindTexture)( ctx, target, newTexObj ); + + oldTexObj->RefCount--; + assert(oldTexObj->RefCount >= 0); + if (oldTexObj->RefCount == 0) { + assert(oldTexObj->Name != 0); + if (ctx->Driver.DeleteTexture) { + (*ctx->Driver.DeleteTexture)( ctx, oldTexObj ); + } + _mesa_free_texture_object(ctx->Shared, oldTexObj); + } +} + + + +/* + * Execute glPrioritizeTextures + */ +void +_mesa_PrioritizeTextures( GLsizei n, const GLuint *texName, + const GLclampf *priorities ) +{ + GET_CURRENT_CONTEXT(ctx); + GLint i; + ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx); + + if (n < 0) { + _mesa_error( ctx, GL_INVALID_VALUE, "glPrioritizeTextures" ); + return; + } + + if (!priorities) + return; + + for (i = 0; i < n; i++) { + if (texName[i] > 0) { + struct gl_texture_object *t = (struct gl_texture_object *) + _mesa_HashLookup(ctx->Shared->TexObjects, texName[i]); + if (t) { + t->Priority = CLAMP( priorities[i], 0.0F, 1.0F ); + if (ctx->Driver.PrioritizeTexture) + ctx->Driver.PrioritizeTexture( ctx, t, t->Priority ); + } + } + } + + ctx->NewState |= _NEW_TEXTURE; +} + + + +/* + * Execute glAreTexturesResident + */ +GLboolean +_mesa_AreTexturesResident(GLsizei n, const GLuint *texName, + GLboolean *residences) +{ + GET_CURRENT_CONTEXT(ctx); + GLboolean allResident = GL_TRUE; + GLint i; + ASSERT_OUTSIDE_BEGIN_END_WITH_RETVAL(ctx, GL_FALSE); + + if (n < 0) { + _mesa_error(ctx, GL_INVALID_VALUE, "glAreTexturesResident(n)"); + return GL_FALSE; + } + + if (!texName || !residences) + return GL_FALSE; + + for (i = 0; i < n; i++) { + struct gl_texture_object *t; + if (texName[i] == 0) { + _mesa_error(ctx, GL_INVALID_VALUE, "glAreTexturesResident(textures)"); + return GL_FALSE; + } + t = (struct gl_texture_object *) + _mesa_HashLookup(ctx->Shared->TexObjects, texName[i]); + if (t) { + if (ctx->Driver.IsTextureResident) { + residences[i] = ctx->Driver.IsTextureResident(ctx, t); + if (!residences[i]) + allResident = GL_FALSE; + } + else { + residences[i] = GL_TRUE; + } + } + else { + _mesa_error(ctx, GL_INVALID_VALUE, "glAreTexturesResident(textures)"); + return GL_FALSE; + } + } + return allResident; +} + + + +/* + * Execute glIsTexture + */ +GLboolean +_mesa_IsTexture( GLuint texture ) +{ + GET_CURRENT_CONTEXT(ctx); + ASSERT_OUTSIDE_BEGIN_END_WITH_RETVAL(ctx, GL_FALSE); + return texture > 0 && _mesa_HashLookup(ctx->Shared->TexObjects, texture); +} Index: dll/opengl/opengl32/mesa/texobj.h =================================================================== --- dll/opengl/opengl32/mesa/texobj.h (revision 0) +++ dll/opengl/opengl32/mesa/texobj.h (working copy) @@ -0,0 +1,85 @@ +/* $Id: texobj.h,v 1.6 2001/03/12 00:48:39 gareth Exp $ */ + +/* + * Mesa 3-D graphics library + * Version: 3.5 + * + * Copyright (C) 1999-2001 Brian Paul 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 + * BRIAN PAUL 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. + */ + + +#ifndef TEXTOBJ_H +#define TEXTOBJ_H + + +#include "mtypes.h" + + + +/* + * Internal functions + */ + +extern struct gl_texture_object * +_mesa_alloc_texture_object( struct gl_shared_state *shared, GLuint name, + GLuint dimensions ); + + +extern void +_mesa_free_texture_object( struct gl_shared_state *shared, + struct gl_texture_object *t ); + + +extern void +_mesa_test_texobj_completeness( const GLcontext *ctx, + struct gl_texture_object *t ); + + +/* + * API functions + */ + +extern void +_mesa_GenTextures( GLsizei n, GLuint *textures ); + + +extern void +_mesa_DeleteTextures( GLsizei n, const GLuint *textures ); + + +extern void +_mesa_BindTexture( GLenum target, GLuint texture ); + + +extern void +_mesa_PrioritizeTextures( GLsizei n, const GLuint *textures, + const GLclampf *priorities ); + + +extern GLboolean +_mesa_AreTexturesResident( GLsizei n, const GLuint *textures, + GLboolean *residences ); + + +extern GLboolean +_mesa_IsTexture( GLuint texture ); + + +#endif Index: dll/opengl/opengl32/mesa/texstate.c =================================================================== --- dll/opengl/opengl32/mesa/texstate.c (revision 0) +++ dll/opengl/opengl32/mesa/texstate.c (working copy) @@ -0,0 +1,2196 @@ +/* $Id: texstate.c,v 1.54 2001/06/18 17:26:08 brianp Exp $ */ + +/* + * Mesa 3-D graphics library + * Version: 3.5 + * + * Copyright (C) 1999-2001 Brian Paul 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 + * BRIAN PAUL 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. + */ + + +#ifdef PC_HEADER +#include "all.h" +#else +#include "glheader.h" +#include "colormac.h" +#include "context.h" +#include "enums.h" +#include "extensions.h" +#include "macros.h" +#include "texobj.h" +#include "teximage.h" +#include "texstate.h" +#include "mtypes.h" +#include "math/m_xform.h" +#include "math/m_matrix.h" +#endif + + + +#ifdef SPECIALCAST +/* Needed for an Amiga compiler */ +#define ENUM_TO_FLOAT(X) ((GLfloat)(GLint)(X)) +#define ENUM_TO_DOUBLE(X) ((GLdouble)(GLint)(X)) +#else +/* all other compilers */ +#define ENUM_TO_FLOAT(X) ((GLfloat)(X)) +#define ENUM_TO_DOUBLE(X) ((GLdouble)(X)) +#endif + + + +/**********************************************************************/ +/* Texture Environment */ +/**********************************************************************/ + + +void +_mesa_TexEnvfv( GLenum target, GLenum pname, const GLfloat *param ) +{ + GET_CURRENT_CONTEXT(ctx); + struct gl_texture_unit *texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit]; + ASSERT_OUTSIDE_BEGIN_END(ctx); + +#define ERROR(errCode, msg, value) \ + { \ + char s[100]; \ + sprintf(s, msg, _mesa_lookup_enum_by_nr(value)); \ + _mesa_error(ctx, errCode, s); \ + } + + if (target==GL_TEXTURE_ENV) { + switch (pname) { + case GL_TEXTURE_ENV_MODE: { + GLenum mode = (GLenum) (GLint) *param; + + switch (mode) { + case GL_ADD: + if (!ctx->Extensions.EXT_texture_env_add) { + ERROR(GL_INVALID_ENUM, "glTexEnv(param=%s)", mode); + return; + } + break; + case GL_COMBINE_EXT: + if (!ctx->Extensions.EXT_texture_env_combine && + !ctx->Extensions.ARB_texture_env_combine) { + ERROR(GL_INVALID_ENUM, "glTexEnv(param=%s)", mode); + return; + } + break; + case GL_MODULATE: + case GL_BLEND: + case GL_DECAL: + case GL_REPLACE: + break; + default: + ERROR(GL_INVALID_ENUM, "glTexEnv(param=%s)", mode); + return; + } + + if (texUnit->EnvMode == mode) + return; + FLUSH_VERTICES(ctx, _NEW_TEXTURE); + texUnit->EnvMode = mode; + break; + } + case GL_TEXTURE_ENV_COLOR: { + GLfloat tmp[4]; + tmp[0] = CLAMP( param[0], 0.0F, 1.0F ); + tmp[1] = CLAMP( param[1], 0.0F, 1.0F ); + tmp[2] = CLAMP( param[2], 0.0F, 1.0F ); + tmp[3] = CLAMP( param[3], 0.0F, 1.0F ); + if (TEST_EQ_4V(tmp, texUnit->EnvColor)) + return; + FLUSH_VERTICES(ctx, _NEW_TEXTURE); + COPY_4FV(texUnit->EnvColor, tmp); + break; + } + case GL_COMBINE_RGB_EXT: + if (ctx->Extensions.EXT_texture_env_combine || + ctx->Extensions.ARB_texture_env_combine) { + const GLenum mode = (GLenum) (GLint) *param; + switch (mode) { + case GL_REPLACE: + case GL_MODULATE: + case GL_ADD: + case GL_ADD_SIGNED_EXT: + case GL_INTERPOLATE_EXT: + /* OK */ + break; + case GL_SUBTRACT_ARB: + if (!ctx->Extensions.ARB_texture_env_combine) { + ERROR(GL_INVALID_ENUM, "glTexEnv(param=%s)", mode); + return; + } + break; + case GL_DOT3_RGB_EXT: + case GL_DOT3_RGBA_EXT: + if (!ctx->Extensions.EXT_texture_env_dot3) { + ERROR(GL_INVALID_ENUM, "glTexEnv(param=%s)", mode); + return; + } + break; + case GL_DOT3_RGB_ARB: + case GL_DOT3_RGBA_ARB: + if (!ctx->Extensions.ARB_texture_env_dot3) { + ERROR(GL_INVALID_ENUM, "glTexEnv(param=%s)", mode); + return; + } + break; + default: + ERROR(GL_INVALID_ENUM, "glTexEnv(param=%s)", mode); + return; + } + if (texUnit->CombineModeRGB == mode) + return; + FLUSH_VERTICES(ctx, _NEW_TEXTURE); + texUnit->CombineModeRGB = mode; + } + else { + ERROR(GL_INVALID_ENUM, "glTexEnv(pname=%s)", pname); + return; + } + break; + case GL_COMBINE_ALPHA_EXT: + if (ctx->Extensions.EXT_texture_env_combine || + ctx->Extensions.ARB_texture_env_combine) { + const GLenum mode = (GLenum) (GLint) *param; + switch (mode) { + case GL_REPLACE: + case GL_MODULATE: + case GL_ADD: + case GL_ADD_SIGNED_EXT: + case GL_INTERPOLATE_EXT: + /* OK */ + break; + case GL_SUBTRACT_ARB: + if (!ctx->Extensions.ARB_texture_env_combine) { + ERROR(GL_INVALID_ENUM, "glTexEnv(param=%s)", mode); + return; + } + break; + default: + ERROR(GL_INVALID_ENUM, "glTexEnv(param=%s)", mode); + return; + } + if (texUnit->CombineModeA == mode) + return; + FLUSH_VERTICES(ctx, _NEW_TEXTURE); + texUnit->CombineModeA = mode; + } + else { + ERROR(GL_INVALID_ENUM, "glTexEnv(pname=%s)", pname); + return; + } + break; + case GL_SOURCE0_RGB_EXT: + case GL_SOURCE1_RGB_EXT: + case GL_SOURCE2_RGB_EXT: + if (ctx->Extensions.EXT_texture_env_combine || + ctx->Extensions.ARB_texture_env_combine) { + GLenum source = (GLenum) (GLint) *param; + GLuint s = pname - GL_SOURCE0_RGB_EXT; + switch (source) { + case GL_TEXTURE: + case GL_CONSTANT_EXT: + case GL_PRIMARY_COLOR_EXT: + case GL_PREVIOUS_EXT: + if (texUnit->CombineSourceRGB[s] == source) + return; + FLUSH_VERTICES(ctx, _NEW_TEXTURE); + texUnit->CombineSourceRGB[s] = source; + break; + default: + ERROR(GL_INVALID_ENUM, "glTexEnv(param=%s)", source); + return; + } + } + else { + ERROR(GL_INVALID_ENUM, "glTexEnv(pname=%s)", pname); + return; + } + break; + case GL_SOURCE0_ALPHA_EXT: + case GL_SOURCE1_ALPHA_EXT: + case GL_SOURCE2_ALPHA_EXT: + if (ctx->Extensions.EXT_texture_env_combine || + ctx->Extensions.ARB_texture_env_combine) { + GLenum source = (GLenum) (GLint) *param; + GLuint s = pname - GL_SOURCE0_ALPHA_EXT; + switch (source) { + case GL_TEXTURE: + case GL_CONSTANT_EXT: + case GL_PRIMARY_COLOR_EXT: + case GL_PREVIOUS_EXT: + if (texUnit->CombineSourceA[s] == source) return; + FLUSH_VERTICES(ctx, _NEW_TEXTURE); + texUnit->CombineSourceA[s] = source; + break; + default: + ERROR(GL_INVALID_ENUM, "glTexEnv(param=%s)", source); + return; + } + } + else { + ERROR(GL_INVALID_ENUM, "glTexEnv(pname=%s)", pname); + return; + } + break; + case GL_OPERAND0_RGB_EXT: + case GL_OPERAND1_RGB_EXT: + if (ctx->Extensions.EXT_texture_env_combine || + ctx->Extensions.ARB_texture_env_combine) { + GLenum operand = (GLenum) (GLint) *param; + GLuint s = pname - GL_OPERAND0_RGB_EXT; + switch (operand) { + case GL_SRC_COLOR: + case GL_ONE_MINUS_SRC_COLOR: + case GL_SRC_ALPHA: + case GL_ONE_MINUS_SRC_ALPHA: + if (texUnit->CombineOperandRGB[s] == operand) + return; + FLUSH_VERTICES(ctx, _NEW_TEXTURE); + texUnit->CombineOperandRGB[s] = operand; + break; + default: + ERROR(GL_INVALID_ENUM, "glTexEnv(param=%s)", operand); + return; + } + } + else { + ERROR(GL_INVALID_ENUM, "glTexEnv(pname=%s)", pname); + return; + } + break; + case GL_OPERAND0_ALPHA_EXT: + case GL_OPERAND1_ALPHA_EXT: + if (ctx->Extensions.EXT_texture_env_combine || + ctx->Extensions.ARB_texture_env_combine) { + GLenum operand = (GLenum) (GLint) *param; + switch (operand) { + case GL_SRC_ALPHA: + case GL_ONE_MINUS_SRC_ALPHA: + if (texUnit->CombineOperandA[pname-GL_OPERAND0_ALPHA_EXT] == + operand) + return; + FLUSH_VERTICES(ctx, _NEW_TEXTURE); + texUnit->CombineOperandA[pname-GL_OPERAND0_ALPHA_EXT] = operand; + break; + default: + ERROR(GL_INVALID_ENUM, "glTexEnv(param=%s)", operand); + return; + } + } + else { + ERROR(GL_INVALID_ENUM, "glTexEnv(pname=%s)", pname); + return; + } + break; + case GL_OPERAND2_RGB_EXT: + if (ctx->Extensions.EXT_texture_env_combine || + ctx->Extensions.ARB_texture_env_combine) { + GLenum operand = (GLenum) (GLint) *param; + switch (operand) { + case GL_SRC_COLOR: /* ARB combine only */ + case GL_ONE_MINUS_SRC_COLOR: /* ARB combine only */ + case GL_SRC_ALPHA: + case GL_ONE_MINUS_SRC_ALPHA: /* ARB combine only */ + if (texUnit->CombineOperandRGB[2] == operand) + return; + FLUSH_VERTICES(ctx, _NEW_TEXTURE); + texUnit->CombineOperandRGB[2] = operand; + default: + ERROR(GL_INVALID_ENUM, "glTexEnv(param=%s)", operand); + return; + } + } + else { + ERROR(GL_INVALID_ENUM, "glTexEnv(pname=%s)", pname); + return; + } + break; + case GL_OPERAND2_ALPHA_EXT: + if (ctx->Extensions.EXT_texture_env_combine || + ctx->Extensions.ARB_texture_env_combine) { + GLenum operand = (GLenum) (GLint) *param; + switch (operand) { + case GL_SRC_ALPHA: + case GL_ONE_MINUS_SRC_ALPHA: /* ARB combine only */ + if (texUnit->CombineOperandA[2] == operand) + return; + FLUSH_VERTICES(ctx, _NEW_TEXTURE); + texUnit->CombineOperandA[2] = operand; + break; + default: + ERROR(GL_INVALID_ENUM, "glTexEnv(param=%s)", operand); + return; + } + } + else { + ERROR(GL_INVALID_ENUM, "glTexEnv(pname=%s)", pname); + return; + } + break; + case GL_RGB_SCALE_EXT: + if (ctx->Extensions.EXT_texture_env_combine || + ctx->Extensions.ARB_texture_env_combine) { + GLuint newshift; + if (*param == 1.0) { + newshift = 0; + } + else if (*param == 2.0) { + newshift = 1; + } + else if (*param == 4.0) { + newshift = 2; + } + else { + _mesa_error( ctx, GL_INVALID_VALUE, + "glTexEnv(GL_RGB_SCALE not 1, 2 or 4)" ); + return; + } + if (texUnit->CombineScaleShiftRGB == newshift) + return; + FLUSH_VERTICES(ctx, _NEW_TEXTURE); + texUnit->CombineScaleShiftRGB = newshift; + } + else { + ERROR(GL_INVALID_ENUM, "glTexEnv(pname=%s)", pname); + return; + } + break; + case GL_ALPHA_SCALE: + if (ctx->Extensions.EXT_texture_env_combine || + ctx->Extensions.ARB_texture_env_combine) { + GLuint newshift; + if (*param == 1.0) { + newshift = 0; + } + else if (*param == 2.0) { + newshift = 1; + } + else if (*param == 4.0) { + newshift = 2; + } + else { + _mesa_error( ctx, GL_INVALID_VALUE, + "glTexEnv(GL_ALPHA_SCALE not 1, 2 or 4)" ); + return; + } + if (texUnit->CombineScaleShiftA == newshift) + return; + FLUSH_VERTICES(ctx, _NEW_TEXTURE); + texUnit->CombineScaleShiftA = newshift; + } + else { + ERROR(GL_INVALID_ENUM, "glTexEnv(pname=%s)", pname); + return; + } + break; + default: + _mesa_error( ctx, GL_INVALID_ENUM, "glTexEnv(pname)" ); + return; + } + } + else if (target==GL_TEXTURE_FILTER_CONTROL_EXT) { + if (!ctx->Extensions.EXT_texture_lod_bias) { + _mesa_error( ctx, GL_INVALID_ENUM, "glTexEnv(param)" ); + return; + } + switch (pname) { + case GL_TEXTURE_LOD_BIAS_EXT: + if (texUnit->LodBias == param[0]) + return; + FLUSH_VERTICES(ctx, _NEW_TEXTURE); + texUnit->LodBias = param[0]; + break; + default: + ERROR(GL_INVALID_ENUM, "glTexEnv(pname=%s)", pname); + return; + } + } + else { + _mesa_error( ctx, GL_INVALID_ENUM, "glTexEnv(target)" ); + return; + } + + if (MESA_VERBOSE&(VERBOSE_API|VERBOSE_TEXTURE)) + fprintf(stderr, "glTexEnv %s %s %.1f(%s) ...\n", + _mesa_lookup_enum_by_nr(target), + _mesa_lookup_enum_by_nr(pname), + *param, + _mesa_lookup_enum_by_nr((GLenum) (GLint) *param)); + + /* Tell device driver about the new texture environment */ + if (ctx->Driver.TexEnv) { + (*ctx->Driver.TexEnv)( ctx, target, pname, param ); + } +} + + +void +_mesa_TexEnvf( GLenum target, GLenum pname, GLfloat param ) +{ + _mesa_TexEnvfv( target, pname, ¶m ); +} + + + +void +_mesa_TexEnvi( GLenum target, GLenum pname, GLint param ) +{ + GLfloat p[4]; + p[0] = (GLfloat) param; + p[1] = p[2] = p[3] = 0.0; + _mesa_TexEnvfv( target, pname, p ); +} + + +void +_mesa_TexEnviv( GLenum target, GLenum pname, const GLint *param ) +{ + GLfloat p[4]; + p[0] = INT_TO_FLOAT( param[0] ); + p[1] = INT_TO_FLOAT( param[1] ); + p[2] = INT_TO_FLOAT( param[2] ); + p[3] = INT_TO_FLOAT( param[3] ); + _mesa_TexEnvfv( target, pname, p ); +} + + +void +_mesa_GetTexEnvfv( GLenum target, GLenum pname, GLfloat *params ) +{ + GET_CURRENT_CONTEXT(ctx); + const struct gl_texture_unit *texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit]; + ASSERT_OUTSIDE_BEGIN_END(ctx); + + if (target!=GL_TEXTURE_ENV) { + _mesa_error( ctx, GL_INVALID_ENUM, "glGetTexEnvfv(target)" ); + return; + } + + switch (pname) { + case GL_TEXTURE_ENV_MODE: + *params = ENUM_TO_FLOAT(texUnit->EnvMode); + break; + case GL_TEXTURE_ENV_COLOR: + COPY_4FV( params, texUnit->EnvColor ); + break; + case GL_COMBINE_RGB_EXT: + if (ctx->Extensions.EXT_texture_env_combine || + ctx->Extensions.ARB_texture_env_combine) { + *params = (GLfloat) texUnit->CombineModeRGB; + } + else { + _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexEnvfv(pname)"); + } + break; + case GL_COMBINE_ALPHA_EXT: + if (ctx->Extensions.EXT_texture_env_combine || + ctx->Extensions.ARB_texture_env_combine) { + *params = (GLfloat) texUnit->CombineModeA; + } + else { + _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexEnvfv(pname)"); + } + break; + case GL_SOURCE0_RGB_EXT: + if (ctx->Extensions.EXT_texture_env_combine || + ctx->Extensions.ARB_texture_env_combine) { + *params = (GLfloat) texUnit->CombineSourceRGB[0]; + } + else { + _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexEnvfv(pname)"); + } + break; + case GL_SOURCE1_RGB_EXT: + if (ctx->Extensions.EXT_texture_env_combine || + ctx->Extensions.ARB_texture_env_combine) { + *params = (GLfloat) texUnit->CombineSourceRGB[1]; + } + else { + _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexEnvfv(pname)"); + } + break; + case GL_SOURCE2_RGB_EXT: + if (ctx->Extensions.EXT_texture_env_combine || + ctx->Extensions.ARB_texture_env_combine) { + *params = (GLfloat) texUnit->CombineSourceRGB[2]; + } + else { + _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexEnvfv(pname)"); + } + break; + case GL_SOURCE0_ALPHA_EXT: + if (ctx->Extensions.EXT_texture_env_combine || + ctx->Extensions.ARB_texture_env_combine) { + *params = (GLfloat) texUnit->CombineSourceA[0]; + } + else { + _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexEnvfv(pname)"); + } + break; + case GL_SOURCE1_ALPHA_EXT: + if (ctx->Extensions.EXT_texture_env_combine || + ctx->Extensions.ARB_texture_env_combine) { + *params = (GLfloat) texUnit->CombineSourceA[1]; + } + else { + _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexEnvfv(pname)"); + } + break; + case GL_SOURCE2_ALPHA_EXT: + if (ctx->Extensions.EXT_texture_env_combine || + ctx->Extensions.ARB_texture_env_combine) { + *params = (GLfloat) texUnit->CombineSourceA[2]; + } + else { + _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexEnvfv(pname)"); + } + break; + case GL_OPERAND0_RGB_EXT: + if (ctx->Extensions.EXT_texture_env_combine || + ctx->Extensions.ARB_texture_env_combine) { + *params = (GLfloat) texUnit->CombineOperandRGB[0]; + } + else { + _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexEnvfv(pname)"); + } + break; + case GL_OPERAND1_RGB_EXT: + if (ctx->Extensions.EXT_texture_env_combine || + ctx->Extensions.ARB_texture_env_combine) { + *params = (GLfloat) texUnit->CombineOperandRGB[1]; + } + else { + _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexEnvfv(pname)"); + } + break; + case GL_OPERAND2_RGB_EXT: + if (ctx->Extensions.EXT_texture_env_combine || + ctx->Extensions.ARB_texture_env_combine) { + *params = (GLfloat) texUnit->CombineOperandRGB[2]; + } + else { + _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexEnvfv(pname)"); + } + break; + case GL_OPERAND0_ALPHA_EXT: + if (ctx->Extensions.EXT_texture_env_combine || + ctx->Extensions.ARB_texture_env_combine) { + *params = (GLfloat) texUnit->CombineOperandA[0]; + } + else { + _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexEnvfv(pname)"); + } + break; + case GL_OPERAND1_ALPHA_EXT: + if (ctx->Extensions.EXT_texture_env_combine || + ctx->Extensions.ARB_texture_env_combine) { + *params = (GLfloat) texUnit->CombineOperandA[1]; + } + else { + _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexEnvfv(pname)"); + } + break; + case GL_OPERAND2_ALPHA_EXT: + if (ctx->Extensions.EXT_texture_env_combine || + ctx->Extensions.ARB_texture_env_combine) { + *params = (GLfloat) texUnit->CombineOperandA[2]; + } + else { + _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexEnvfv(pname)"); + } + break; + case GL_RGB_SCALE_EXT: + if (ctx->Extensions.EXT_texture_env_combine || + ctx->Extensions.ARB_texture_env_combine) { + if (texUnit->CombineScaleShiftRGB == 0) + *params = 1.0; + else if (texUnit->CombineScaleShiftRGB == 1) + *params = 2.0; + else + *params = 4.0; + } + else { + _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexEnvfv(pname)"); + return; + } + break; + case GL_ALPHA_SCALE: + if (ctx->Extensions.EXT_texture_env_combine || + ctx->Extensions.ARB_texture_env_combine) { + if (texUnit->CombineScaleShiftA == 0) + *params = 1.0; + else if (texUnit->CombineScaleShiftA == 1) + *params = 2.0; + else + *params = 4.0; + } + else { + _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexEnvfv(pname)"); + return; + } + break; + default: + _mesa_error( ctx, GL_INVALID_ENUM, "glGetTexEnvfv(pname)" ); + } +} + + +void +_mesa_GetTexEnviv( GLenum target, GLenum pname, GLint *params ) +{ + GET_CURRENT_CONTEXT(ctx); + const struct gl_texture_unit *texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit]; + ASSERT_OUTSIDE_BEGIN_END(ctx); + + if (target != GL_TEXTURE_ENV) { + _mesa_error( ctx, GL_INVALID_ENUM, "glGetTexEnviv(target)" ); + return; + } + + switch (pname) { + case GL_TEXTURE_ENV_MODE: + *params = (GLint) texUnit->EnvMode; + break; + case GL_TEXTURE_ENV_COLOR: + params[0] = FLOAT_TO_INT( texUnit->EnvColor[0] ); + params[1] = FLOAT_TO_INT( texUnit->EnvColor[1] ); + params[2] = FLOAT_TO_INT( texUnit->EnvColor[2] ); + params[3] = FLOAT_TO_INT( texUnit->EnvColor[3] ); + break; + case GL_COMBINE_RGB_EXT: + if (ctx->Extensions.EXT_texture_env_combine || + ctx->Extensions.ARB_texture_env_combine) { + *params = (GLint) texUnit->CombineModeRGB; + } + else { + _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexEnviv(pname)"); + } + break; + case GL_COMBINE_ALPHA_EXT: + if (ctx->Extensions.EXT_texture_env_combine || + ctx->Extensions.ARB_texture_env_combine) { + *params = (GLint) texUnit->CombineModeA; + } + else { + _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexEnviv(pname)"); + } + break; + case GL_SOURCE0_RGB_EXT: + if (ctx->Extensions.EXT_texture_env_combine || + ctx->Extensions.ARB_texture_env_combine) { + *params = (GLint) texUnit->CombineSourceRGB[0]; + } + else { + _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexEnviv(pname)"); + } + break; + case GL_SOURCE1_RGB_EXT: + if (ctx->Extensions.EXT_texture_env_combine || + ctx->Extensions.ARB_texture_env_combine) { + *params = (GLint) texUnit->CombineSourceRGB[1]; + } + else { + _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexEnviv(pname)"); + } + break; + case GL_SOURCE2_RGB_EXT: + if (ctx->Extensions.EXT_texture_env_combine || + ctx->Extensions.ARB_texture_env_combine) { + *params = (GLint) texUnit->CombineSourceRGB[2]; + } + else { + _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexEnviv(pname)"); + } + break; + case GL_SOURCE0_ALPHA_EXT: + if (ctx->Extensions.EXT_texture_env_combine || + ctx->Extensions.ARB_texture_env_combine) { + *params = (GLint) texUnit->CombineSourceA[0]; + } + else { + _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexEnviv(pname)"); + } + break; + case GL_SOURCE1_ALPHA_EXT: + if (ctx->Extensions.EXT_texture_env_combine || + ctx->Extensions.ARB_texture_env_combine) { + *params = (GLint) texUnit->CombineSourceA[1]; + } + else { + _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexEnviv(pname)"); + } + break; + case GL_SOURCE2_ALPHA_EXT: + if (ctx->Extensions.EXT_texture_env_combine || + ctx->Extensions.ARB_texture_env_combine) { + *params = (GLint) texUnit->CombineSourceA[2]; + } + else { + _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexEnviv(pname)"); + } + break; + case GL_OPERAND0_RGB_EXT: + if (ctx->Extensions.EXT_texture_env_combine || + ctx->Extensions.ARB_texture_env_combine) { + *params = (GLint) texUnit->CombineOperandRGB[0]; + } + else { + _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexEnviv(pname)"); + } + break; + case GL_OPERAND1_RGB_EXT: + if (ctx->Extensions.EXT_texture_env_combine || + ctx->Extensions.ARB_texture_env_combine) { + *params = (GLint) texUnit->CombineOperandRGB[1]; + } + else { + _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexEnviv(pname)"); + } + break; + case GL_OPERAND2_RGB_EXT: + if (ctx->Extensions.EXT_texture_env_combine || + ctx->Extensions.ARB_texture_env_combine) { + *params = (GLint) texUnit->CombineOperandRGB[2]; + } + else { + _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexEnviv(pname)"); + } + break; + case GL_OPERAND0_ALPHA_EXT: + if (ctx->Extensions.EXT_texture_env_combine || + ctx->Extensions.ARB_texture_env_combine) { + *params = (GLint) texUnit->CombineOperandA[0]; + } + else { + _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexEnviv(pname)"); + } + break; + case GL_OPERAND1_ALPHA_EXT: + if (ctx->Extensions.EXT_texture_env_combine || + ctx->Extensions.ARB_texture_env_combine) { + *params = (GLint) texUnit->CombineOperandA[1]; + } + else { + _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexEnviv(pname)"); + } + break; + case GL_OPERAND2_ALPHA_EXT: + if (ctx->Extensions.EXT_texture_env_combine || + ctx->Extensions.ARB_texture_env_combine) { + *params = (GLint) texUnit->CombineOperandA[2]; + } + else { + _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexEnviv(pname)"); + } + break; + case GL_RGB_SCALE_EXT: + if (ctx->Extensions.EXT_texture_env_combine || + ctx->Extensions.ARB_texture_env_combine) { + if (texUnit->CombineScaleShiftRGB == 0) + *params = 1; + else if (texUnit->CombineScaleShiftRGB == 1) + *params = 2; + else + *params = 4; + } + else { + _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexEnviv(pname)"); + return; + } + break; + case GL_ALPHA_SCALE: + if (ctx->Extensions.EXT_texture_env_combine || + ctx->Extensions.ARB_texture_env_combine) { + if (texUnit->CombineScaleShiftA == 0) + *params = 1; + else if (texUnit->CombineScaleShiftA == 1) + *params = 2; + else + *params = 4; + } + else { + _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexEnviv(pname)"); + return; + } + break; + default: + _mesa_error( ctx, GL_INVALID_ENUM, "glGetTexEnviv(pname)" ); + } +} + + + + +/**********************************************************************/ +/* Texture Parameters */ +/**********************************************************************/ + + +void +_mesa_TexParameterf( GLenum target, GLenum pname, GLfloat param ) +{ + _mesa_TexParameterfv(target, pname, ¶m); +} + + +void +_mesa_TexParameterfv( GLenum target, GLenum pname, const GLfloat *params ) +{ + GET_CURRENT_CONTEXT(ctx); + struct gl_texture_unit *texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit]; + GLenum eparam = (GLenum) (GLint) params[0]; + struct gl_texture_object *texObj; + ASSERT_OUTSIDE_BEGIN_END(ctx); + + if (MESA_VERBOSE&(VERBOSE_API|VERBOSE_TEXTURE)) + fprintf(stderr, "texPARAM %s %s %d...\n", + _mesa_lookup_enum_by_nr(target), + _mesa_lookup_enum_by_nr(pname), + eparam); + + + switch (target) { + case GL_TEXTURE_1D: + texObj = texUnit->Current1D; + break; + case GL_TEXTURE_2D: + texObj = texUnit->Current2D; + break; + case GL_TEXTURE_3D_EXT: + texObj = texUnit->Current3D; + break; + case GL_TEXTURE_CUBE_MAP_ARB: + if (ctx->Extensions.ARB_texture_cube_map) { + texObj = texUnit->CurrentCubeMap; + break; + } + /* fallthrough */ + default: + _mesa_error( ctx, GL_INVALID_ENUM, "glTexParameter(target)" ); + return; + } + + switch (pname) { + case GL_TEXTURE_MIN_FILTER: + /* A small optimization */ + if (texObj->MinFilter == eparam) + return; + + if (eparam==GL_NEAREST || eparam==GL_LINEAR + || eparam==GL_NEAREST_MIPMAP_NEAREST + || eparam==GL_LINEAR_MIPMAP_NEAREST + || eparam==GL_NEAREST_MIPMAP_LINEAR + || eparam==GL_LINEAR_MIPMAP_LINEAR) { + texObj->MinFilter = eparam; + } + else { + _mesa_error( ctx, GL_INVALID_VALUE, "glTexParameter(param)" ); + return; + } + break; + case GL_TEXTURE_MAG_FILTER: + /* A small optimization */ + if (texObj->MagFilter == eparam) + return; + + if (eparam==GL_NEAREST || eparam==GL_LINEAR) { + texObj->MagFilter = eparam; + } + else { + _mesa_error( ctx, GL_INVALID_VALUE, "glTexParameter(param)" ); + return; + } + break; + case GL_TEXTURE_WRAP_S: + if (texObj->WrapS == eparam) + return; + if (eparam==GL_CLAMP || + eparam==GL_REPEAT || + eparam==GL_CLAMP_TO_EDGE || + (eparam == GL_CLAMP_TO_BORDER_ARB && + ctx->Extensions.ARB_texture_border_clamp)) { + texObj->WrapS = eparam; + } + else { + _mesa_error( ctx, GL_INVALID_VALUE, "glTexParameter(param)" ); + return; + } + break; + case GL_TEXTURE_WRAP_T: + if (texObj->WrapT == eparam) + return; + if (eparam==GL_CLAMP || + eparam==GL_REPEAT || + eparam==GL_CLAMP_TO_EDGE || + (eparam == GL_CLAMP_TO_BORDER_ARB && + ctx->Extensions.ARB_texture_border_clamp)) { + texObj->WrapT = eparam; + } + else { + _mesa_error( ctx, GL_INVALID_VALUE, "glTexParameter(param)" ); + return; + } + break; + case GL_TEXTURE_WRAP_R_EXT: + if (texObj->WrapR == eparam) + return; + if (eparam==GL_CLAMP || + eparam==GL_REPEAT || + eparam==GL_CLAMP_TO_EDGE || + (eparam == GL_CLAMP_TO_BORDER_ARB && + ctx->Extensions.ARB_texture_border_clamp)) { + texObj->WrapR = eparam; + } + else { + _mesa_error( ctx, GL_INVALID_VALUE, "glTexParameter(param)" ); + } + break; + case GL_TEXTURE_BORDER_COLOR: + UNCLAMPED_FLOAT_TO_CHAN(texObj->BorderColor[0], params[0]); + UNCLAMPED_FLOAT_TO_CHAN(texObj->BorderColor[1], params[1]); + UNCLAMPED_FLOAT_TO_CHAN(texObj->BorderColor[2], params[2]); + UNCLAMPED_FLOAT_TO_CHAN(texObj->BorderColor[3], params[3]); + break; + case GL_TEXTURE_MIN_LOD: + texObj->MinLod = params[0]; + break; + case GL_TEXTURE_MAX_LOD: + texObj->MaxLod = params[0]; + break; + case GL_TEXTURE_BASE_LEVEL: + if (params[0] < 0.0) { + _mesa_error(ctx, GL_INVALID_VALUE, "glTexParameter(param)" ); + return; + } + texObj->BaseLevel = (GLint) params[0]; + break; + case GL_TEXTURE_MAX_LEVEL: + if (params[0] < 0.0) { + _mesa_error(ctx, GL_INVALID_VALUE, "glTexParameter(param)" ); + return; + } + texObj->MaxLevel = (GLint) params[0]; + break; + case GL_TEXTURE_PRIORITY: + /* (keithh@netcomuk.co.uk) */ + texObj->Priority = CLAMP( params[0], 0.0F, 1.0F ); + break; + case GL_TEXTURE_MAX_ANISOTROPY_EXT: + if (ctx->Extensions.EXT_texture_filter_anisotropic) { + if (params[0] < 1.0) { + _mesa_error(ctx, GL_INVALID_VALUE, "glTexParameter(param)" ); + return; + } + texObj->MaxAnisotropy = params[0]; + } + else { + _mesa_error(ctx, GL_INVALID_ENUM, "glTexParameter(pname)"); + return; + } + break; + case GL_TEXTURE_COMPARE_SGIX: + if (ctx->Extensions.SGIX_shadow) { + texObj->CompareFlag = params[0] ? GL_TRUE : GL_FALSE; + } + else { + _mesa_error(ctx, GL_INVALID_ENUM, "glTexParameter(pname)"); + return; + } + break; + case GL_TEXTURE_COMPARE_OPERATOR_SGIX: + if (ctx->Extensions.SGIX_shadow) { + GLenum op = (GLenum) params[0]; + if (op == GL_TEXTURE_LEQUAL_R_SGIX || + op == GL_TEXTURE_GEQUAL_R_SGIX) { + texObj->CompareOperator = op; + } + else { + _mesa_error(ctx, GL_INVALID_ENUM, "glTexParameter(param)"); + } + } + else { + _mesa_error(ctx, GL_INVALID_ENUM, "glTexParameter(pname)"); + return; + } + break; + case GL_SHADOW_AMBIENT_SGIX: + if (ctx->Extensions.SGIX_shadow_ambient) { + UNCLAMPED_FLOAT_TO_CHAN(texObj->ShadowAmbient, params[0]); + } + else { + _mesa_error(ctx, GL_INVALID_ENUM, "glTexParameter(pname)"); + return; + } + break; + case GL_GENERATE_MIPMAP_SGIS: + if (ctx->Extensions.SGIS_generate_mipmap) { + texObj->GenerateMipmap = params[0] ? GL_TRUE : GL_FALSE; + } + else { + _mesa_error(ctx, GL_INVALID_ENUM, "glTexParameter(pname)"); + return; + } + break; + default: + _mesa_error( ctx, GL_INVALID_ENUM, "glTexParameter(pname)" ); + return; + } + + ctx->NewState |= _NEW_TEXTURE; + texObj->Complete = GL_FALSE; + + if (ctx->Driver.TexParameter) { + (*ctx->Driver.TexParameter)( ctx, target, texObj, pname, params ); + } +} + + +void +_mesa_TexParameteri( GLenum target, GLenum pname, GLint param ) +{ + GLfloat fparam[4]; + fparam[0] = (GLfloat) param; + fparam[1] = fparam[2] = fparam[3] = 0.0; + _mesa_TexParameterfv(target, pname, fparam); +} + +void +_mesa_TexParameteriv( GLenum target, GLenum pname, const GLint *params ) +{ + GLfloat fparam[4]; + fparam[0] = (GLfloat) params[0]; + fparam[1] = fparam[2] = fparam[3] = 0.0; + _mesa_TexParameterfv(target, pname, fparam); +} + + +void +_mesa_GetTexLevelParameterfv( GLenum target, GLint level, + GLenum pname, GLfloat *params ) +{ + GLint iparam; + _mesa_GetTexLevelParameteriv( target, level, pname, &iparam ); + *params = (GLfloat) iparam; +} + + +static GLuint +tex_image_dimensions(GLcontext *ctx, GLenum target) +{ + switch (target) { + case GL_TEXTURE_1D: + case GL_PROXY_TEXTURE_1D: + return 1; + case GL_TEXTURE_2D: + case GL_PROXY_TEXTURE_2D: + return 2; + case GL_TEXTURE_3D: + case GL_PROXY_TEXTURE_3D: + return 3; + case GL_TEXTURE_CUBE_MAP_ARB: + case GL_PROXY_TEXTURE_CUBE_MAP_ARB: + case GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB: + case GL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB: + case GL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB: + case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_ARB: + case GL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB: + case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB: + return ctx->Extensions.ARB_texture_cube_map ? 2 : 0; + default: + _mesa_problem(ctx, "bad target in _mesa_tex_target_dimensions()"); + return 0; + } +} + + +void +_mesa_GetTexLevelParameteriv( GLenum target, GLint level, + GLenum pname, GLint *params ) +{ + GET_CURRENT_CONTEXT(ctx); + const struct gl_texture_unit *texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit]; + const struct gl_texture_image *img = NULL; + GLuint dimensions; + GLboolean isProxy; + GLint maxLevels; + ASSERT_OUTSIDE_BEGIN_END(ctx); + + dimensions = tex_image_dimensions(ctx, target); /* 1, 2 or 3 */ + if (dimensions == 0) { + _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexLevelParameter[if]v(target)"); + return; + } + + switch (target) { + case GL_TEXTURE_1D: + case GL_PROXY_TEXTURE_1D: + case GL_TEXTURE_2D: + case GL_PROXY_TEXTURE_2D: + maxLevels = ctx->Const.MaxTextureLevels; + break; + case GL_TEXTURE_3D: + case GL_PROXY_TEXTURE_3D: + maxLevels = ctx->Const.Max3DTextureLevels; + break; + default: + maxLevels = ctx->Const.MaxCubeTextureLevels; + break; + } + + if (level < 0 || level >= maxLevels) { + _mesa_error( ctx, GL_INVALID_VALUE, "glGetTexLevelParameter[if]v" ); + return; + } + + img = _mesa_select_tex_image(ctx, texUnit, target, level); + if (!img || !img->TexFormat) { + /* undefined texture image */ + if (pname == GL_TEXTURE_COMPONENTS) + *params = 1; + else + *params = 0; + return; + } + + isProxy = (target == GL_PROXY_TEXTURE_1D) || + (target == GL_PROXY_TEXTURE_2D) || + (target == GL_PROXY_TEXTURE_3D) || + (target == GL_PROXY_TEXTURE_CUBE_MAP_ARB); + + switch (pname) { + case GL_TEXTURE_WIDTH: + *params = img->Width; + return; + case GL_TEXTURE_HEIGHT: + *params = img->Height; + return; + case GL_TEXTURE_DEPTH: + *params = img->Depth; + return; + case GL_TEXTURE_INTERNAL_FORMAT: + *params = img->IntFormat; + return; + case GL_TEXTURE_BORDER: + *params = img->Border; + return; + case GL_TEXTURE_RED_SIZE: + if (img->Format == GL_RGB || img->Format == GL_RGBA) + *params = img->TexFormat->RedBits; + else + *params = 0; + return; + case GL_TEXTURE_GREEN_SIZE: + if (img->Format == GL_RGB || img->Format == GL_RGBA) + *params = img->TexFormat->GreenBits; + else + *params = 0; + return; + case GL_TEXTURE_BLUE_SIZE: + if (img->Format == GL_RGB || img->Format == GL_RGBA) + *params = img->TexFormat->BlueBits; + else + *params = 0; + return; + case GL_TEXTURE_ALPHA_SIZE: + if (img->Format == GL_ALPHA || img->Format == GL_LUMINANCE_ALPHA || + img->Format == GL_RGBA) + *params = img->TexFormat->AlphaBits; + else + *params = 0; + return; + case GL_TEXTURE_INTENSITY_SIZE: + if (img->Format != GL_INTENSITY) + *params = 0; + else if (img->TexFormat->IntensityBits > 0) + *params = img->TexFormat->IntensityBits; + else /* intensity probably stored as rgb texture */ + *params = MIN2(img->TexFormat->RedBits, img->TexFormat->GreenBits); + return; + case GL_TEXTURE_LUMINANCE_SIZE: + if (img->Format != GL_LUMINANCE && + img->Format != GL_LUMINANCE_ALPHA) + *params = 0; + else if (img->TexFormat->LuminanceBits > 0) + *params = img->TexFormat->LuminanceBits; + else /* luminance probably stored as rgb texture */ + *params = MIN2(img->TexFormat->RedBits, img->TexFormat->GreenBits); + return; + case GL_TEXTURE_INDEX_SIZE_EXT: + if (img->Format == GL_COLOR_INDEX) + *params = img->TexFormat->IndexBits; + else + *params = 0; + return; + case GL_DEPTH_BITS: + /* XXX this isn't in the GL_SGIX_depth_texture spec + * but seems appropriate. + */ + if (ctx->Extensions.SGIX_depth_texture) + *params = img->TexFormat->DepthBits; + else + _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexLevelParameter[if]v(pname)"); + return; + + /* GL_ARB_texture_compression */ + case GL_TEXTURE_COMPRESSED_IMAGE_SIZE_ARB: + if (ctx->Extensions.ARB_texture_compression) { + if (img->IsCompressed && !isProxy) + *params = img->CompressedSize; + else + _mesa_error(ctx, GL_INVALID_OPERATION, + "glGetTexLevelParameter[if]v(pname)"); + } + else { + _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexLevelParameter[if]v(pname)"); + } + return; + case GL_TEXTURE_COMPRESSED_ARB: + if (ctx->Extensions.ARB_texture_compression) { + *params = (GLint) img->IsCompressed; + } + else { + _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexLevelParameter[if]v(pname)"); + } + return; + + default: + _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexLevelParameter[if]v(pname)"); + } +} + + + +void +_mesa_GetTexParameterfv( GLenum target, GLenum pname, GLfloat *params ) +{ + GET_CURRENT_CONTEXT(ctx); + struct gl_texture_unit *texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit]; + struct gl_texture_object *obj; + ASSERT_OUTSIDE_BEGIN_END(ctx); + + obj = _mesa_select_tex_object(ctx, texUnit, target); + if (!obj) { + _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexParameterfv(target)"); + return; + } + + switch (pname) { + case GL_TEXTURE_MAG_FILTER: + *params = ENUM_TO_FLOAT(obj->MagFilter); + return; + case GL_TEXTURE_MIN_FILTER: + *params = ENUM_TO_FLOAT(obj->MinFilter); + return; + case GL_TEXTURE_WRAP_S: + *params = ENUM_TO_FLOAT(obj->WrapS); + return; + case GL_TEXTURE_WRAP_T: + *params = ENUM_TO_FLOAT(obj->WrapT); + return; + case GL_TEXTURE_WRAP_R_EXT: + *params = ENUM_TO_FLOAT(obj->WrapR); + return; + case GL_TEXTURE_BORDER_COLOR: + params[0] = obj->BorderColor[0] / CHAN_MAXF; + params[1] = obj->BorderColor[1] / CHAN_MAXF; + params[2] = obj->BorderColor[2] / CHAN_MAXF; + params[3] = obj->BorderColor[3] / CHAN_MAXF; + return; + case GL_TEXTURE_RESIDENT: + { + GLboolean resident; + if (ctx->Driver.IsTextureResident) + resident = ctx->Driver.IsTextureResident(ctx, obj); + else + resident = GL_TRUE; + *params = ENUM_TO_FLOAT(resident); + } + return; + case GL_TEXTURE_PRIORITY: + *params = obj->Priority; + return; + case GL_TEXTURE_MIN_LOD: + *params = obj->MinLod; + return; + case GL_TEXTURE_MAX_LOD: + *params = obj->MaxLod; + return; + case GL_TEXTURE_BASE_LEVEL: + *params = (GLfloat) obj->BaseLevel; + return; + case GL_TEXTURE_MAX_LEVEL: + *params = (GLfloat) obj->MaxLevel; + return; + case GL_TEXTURE_COMPARE_SGIX: + if (ctx->Extensions.SGIX_shadow) { + *params = (GLfloat) obj->CompareFlag; + return; + } + break; + case GL_TEXTURE_COMPARE_OPERATOR_SGIX: + if (ctx->Extensions.SGIX_shadow) { + *params = (GLfloat) obj->CompareOperator; + return; + } + break; + case GL_SHADOW_AMBIENT_SGIX: + if (ctx->Extensions.SGIX_shadow_ambient) { + *params = CHAN_TO_FLOAT(obj->ShadowAmbient); + return; + } + break; + case GL_GENERATE_MIPMAP_SGIS: + if (ctx->Extensions.SGIS_generate_mipmap) { + *params = (GLfloat) obj->GenerateMipmap; + return; + } + break; + default: + ; /* silence warnings */ + } + /* If we get here, pname was an unrecognized enum */ + _mesa_error( ctx, GL_INVALID_ENUM, "glGetTexParameterfv(pname)" ); +} + + +void +_mesa_GetTexParameteriv( GLenum target, GLenum pname, GLint *params ) +{ + GET_CURRENT_CONTEXT(ctx); + struct gl_texture_unit *texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit]; + struct gl_texture_object *obj; + ASSERT_OUTSIDE_BEGIN_END(ctx); + + obj = _mesa_select_tex_object(ctx, texUnit, target); + if (!obj) { + _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexParameteriv(target)"); + return; + } + + switch (pname) { + case GL_TEXTURE_MAG_FILTER: + *params = (GLint) obj->MagFilter; + return; + case GL_TEXTURE_MIN_FILTER: + *params = (GLint) obj->MinFilter; + return; + case GL_TEXTURE_WRAP_S: + *params = (GLint) obj->WrapS; + return; + case GL_TEXTURE_WRAP_T: + *params = (GLint) obj->WrapT; + return; + case GL_TEXTURE_WRAP_R_EXT: + *params = (GLint) obj->WrapR; + return; + case GL_TEXTURE_BORDER_COLOR: + { + GLfloat color[4]; + color[0] = obj->BorderColor[0] / CHAN_MAXF; + color[1] = obj->BorderColor[1] / CHAN_MAXF; + color[2] = obj->BorderColor[2] / CHAN_MAXF; + color[3] = obj->BorderColor[3] / CHAN_MAXF; + params[0] = FLOAT_TO_INT( color[0] ); + params[1] = FLOAT_TO_INT( color[1] ); + params[2] = FLOAT_TO_INT( color[2] ); + params[3] = FLOAT_TO_INT( color[3] ); + } + return; + case GL_TEXTURE_RESIDENT: + { + GLboolean resident; + if (ctx->Driver.IsTextureResident) + resident = ctx->Driver.IsTextureResident(ctx, obj); + else + resident = GL_TRUE; + *params = (GLint) resident; + } + return; + case GL_TEXTURE_PRIORITY: + *params = (GLint) obj->Priority; + return; + case GL_TEXTURE_MIN_LOD: + *params = (GLint) obj->MinLod; + return; + case GL_TEXTURE_MAX_LOD: + *params = (GLint) obj->MaxLod; + return; + case GL_TEXTURE_BASE_LEVEL: + *params = obj->BaseLevel; + return; + case GL_TEXTURE_MAX_LEVEL: + *params = obj->MaxLevel; + return; + case GL_TEXTURE_COMPARE_SGIX: + if (ctx->Extensions.SGIX_shadow) { + *params = (GLint) obj->CompareFlag; + return; + } + break; + case GL_TEXTURE_COMPARE_OPERATOR_SGIX: + if (ctx->Extensions.SGIX_shadow) { + *params = (GLint) obj->CompareOperator; + return; + } + break; + case GL_SHADOW_AMBIENT_SGIX: + if (ctx->Extensions.SGIX_shadow_ambient) { + /* XXX range? */ + *params = (GLint) CHAN_TO_FLOAT(obj->ShadowAmbient); + return; + } + break; + case GL_GENERATE_MIPMAP_SGIS: + if (ctx->Extensions.SGIS_generate_mipmap) { + *params = (GLint) obj->GenerateMipmap; + return; + } + break; + default: + ; /* silence warnings */ + } + /* If we get here, pname was an unrecognized enum */ + _mesa_error( ctx, GL_INVALID_ENUM, "glGetTexParameteriv(pname)" ); +} + + + + +/**********************************************************************/ +/* Texture Coord Generation */ +/**********************************************************************/ + + +void +_mesa_TexGenfv( GLenum coord, GLenum pname, const GLfloat *params ) +{ + GET_CURRENT_CONTEXT(ctx); + GLuint tUnit = ctx->Texture.CurrentUnit; + struct gl_texture_unit *texUnit = &ctx->Texture.Unit[tUnit]; + ASSERT_OUTSIDE_BEGIN_END(ctx); + + if (MESA_VERBOSE&(VERBOSE_API|VERBOSE_TEXTURE)) + fprintf(stderr, "texGEN %s %s %x...\n", + _mesa_lookup_enum_by_nr(coord), + _mesa_lookup_enum_by_nr(pname), + *(int *)params); + + switch (coord) { + case GL_S: + if (pname==GL_TEXTURE_GEN_MODE) { + GLenum mode = (GLenum) (GLint) *params; + GLuint bits; + switch (mode) { + case GL_OBJECT_LINEAR: + bits = TEXGEN_OBJ_LINEAR; + break; + case GL_EYE_LINEAR: + bits = TEXGEN_EYE_LINEAR; + break; + case GL_REFLECTION_MAP_NV: + bits = TEXGEN_REFLECTION_MAP_NV; + break; + case GL_NORMAL_MAP_NV: + bits = TEXGEN_NORMAL_MAP_NV; + break; + case GL_SPHERE_MAP: + bits = TEXGEN_SPHERE_MAP; + break; + default: + _mesa_error( ctx, GL_INVALID_ENUM, "glTexGenfv(param)" ); + return; + } + if (texUnit->GenModeS == mode) + return; + FLUSH_VERTICES(ctx, _NEW_TEXTURE); + texUnit->GenModeS = mode; + texUnit->_GenBitS = bits; + } + else if (pname==GL_OBJECT_PLANE) { + if (TEST_EQ_4V(texUnit->ObjectPlaneS, params)) + return; + FLUSH_VERTICES(ctx, _NEW_TEXTURE); + texUnit->ObjectPlaneS[0] = params[0]; + texUnit->ObjectPlaneS[1] = params[1]; + texUnit->ObjectPlaneS[2] = params[2]; + texUnit->ObjectPlaneS[3] = params[3]; + } + else if (pname==GL_EYE_PLANE) { + GLfloat tmp[4]; + + /* Transform plane equation by the inverse modelview matrix */ + if (ctx->ModelView.flags & MAT_DIRTY_INVERSE) { + _math_matrix_analyse( &ctx->ModelView ); + } + _mesa_transform_vector( tmp, params, ctx->ModelView.inv ); + if (TEST_EQ_4V(texUnit->EyePlaneS, tmp)) + return; + FLUSH_VERTICES(ctx, _NEW_TEXTURE); + COPY_4FV(texUnit->EyePlaneS, tmp); + } + else { + _mesa_error( ctx, GL_INVALID_ENUM, "glTexGenfv(pname)" ); + return; + } + break; + case GL_T: + if (pname==GL_TEXTURE_GEN_MODE) { + GLenum mode = (GLenum) (GLint) *params; + GLuint bitt; + switch (mode) { + case GL_OBJECT_LINEAR: + bitt = TEXGEN_OBJ_LINEAR; + break; + case GL_EYE_LINEAR: + bitt = TEXGEN_EYE_LINEAR; + break; + case GL_REFLECTION_MAP_NV: + bitt = TEXGEN_REFLECTION_MAP_NV; + break; + case GL_NORMAL_MAP_NV: + bitt = TEXGEN_NORMAL_MAP_NV; + break; + case GL_SPHERE_MAP: + bitt = TEXGEN_SPHERE_MAP; + break; + default: + _mesa_error( ctx, GL_INVALID_ENUM, "glTexGenfv(param)" ); + return; + } + if (texUnit->GenModeT == mode) + return; + FLUSH_VERTICES(ctx, _NEW_TEXTURE); + texUnit->GenModeT = mode; + texUnit->_GenBitT = bitt; + } + else if (pname==GL_OBJECT_PLANE) { + if (TEST_EQ_4V(texUnit->ObjectPlaneT, params)) + return; + FLUSH_VERTICES(ctx, _NEW_TEXTURE); + texUnit->ObjectPlaneT[0] = params[0]; + texUnit->ObjectPlaneT[1] = params[1]; + texUnit->ObjectPlaneT[2] = params[2]; + texUnit->ObjectPlaneT[3] = params[3]; + } + else if (pname==GL_EYE_PLANE) { + GLfloat tmp[4]; + /* Transform plane equation by the inverse modelview matrix */ + if (ctx->ModelView.flags & MAT_DIRTY_INVERSE) { + _math_matrix_analyse( &ctx->ModelView ); + } + _mesa_transform_vector( tmp, params, ctx->ModelView.inv ); + if (TEST_EQ_4V(texUnit->EyePlaneT, tmp)) + return; + FLUSH_VERTICES(ctx, _NEW_TEXTURE); + COPY_4FV(texUnit->EyePlaneT, tmp); + } + else { + _mesa_error( ctx, GL_INVALID_ENUM, "glTexGenfv(pname)" ); + return; + } + break; + case GL_R: + if (pname==GL_TEXTURE_GEN_MODE) { + GLenum mode = (GLenum) (GLint) *params; + GLuint bitr; + switch (mode) { + case GL_OBJECT_LINEAR: + bitr = TEXGEN_OBJ_LINEAR; + break; + case GL_REFLECTION_MAP_NV: + bitr = TEXGEN_REFLECTION_MAP_NV; + break; + case GL_NORMAL_MAP_NV: + bitr = TEXGEN_NORMAL_MAP_NV; + break; + case GL_EYE_LINEAR: + bitr = TEXGEN_EYE_LINEAR; + break; + default: + _mesa_error( ctx, GL_INVALID_ENUM, "glTexGenfv(param)" ); + return; + } + if (texUnit->GenModeR == mode) + return; + FLUSH_VERTICES(ctx, _NEW_TEXTURE); + texUnit->GenModeR = mode; + texUnit->_GenBitR = bitr; + } + else if (pname==GL_OBJECT_PLANE) { + if (TEST_EQ_4V(texUnit->ObjectPlaneR, params)) + return; + FLUSH_VERTICES(ctx, _NEW_TEXTURE); + texUnit->ObjectPlaneR[0] = params[0]; + texUnit->ObjectPlaneR[1] = params[1]; + texUnit->ObjectPlaneR[2] = params[2]; + texUnit->ObjectPlaneR[3] = params[3]; + } + else if (pname==GL_EYE_PLANE) { + GLfloat tmp[4]; + /* Transform plane equation by the inverse modelview matrix */ + if (ctx->ModelView.flags & MAT_DIRTY_INVERSE) { + _math_matrix_analyse( &ctx->ModelView ); + } + _mesa_transform_vector( tmp, params, ctx->ModelView.inv ); + if (TEST_EQ_4V(texUnit->EyePlaneR, tmp)) + return; + FLUSH_VERTICES(ctx, _NEW_TEXTURE); + COPY_4FV(texUnit->EyePlaneR, tmp); + } + else { + _mesa_error( ctx, GL_INVALID_ENUM, "glTexGenfv(pname)" ); + return; + } + break; + case GL_Q: + if (pname==GL_TEXTURE_GEN_MODE) { + GLenum mode = (GLenum) (GLint) *params; + GLuint bitq; + switch (mode) { + case GL_OBJECT_LINEAR: + bitq = TEXGEN_OBJ_LINEAR; + break; + case GL_EYE_LINEAR: + bitq = TEXGEN_EYE_LINEAR; + break; + default: + _mesa_error( ctx, GL_INVALID_ENUM, "glTexGenfv(param)" ); + return; + } + if (texUnit->GenModeQ == mode) + return; + FLUSH_VERTICES(ctx, _NEW_TEXTURE); + texUnit->GenModeQ = mode; + texUnit->_GenBitQ = bitq; + } + else if (pname==GL_OBJECT_PLANE) { + if (TEST_EQ_4V(texUnit->ObjectPlaneQ, params)) + return; + FLUSH_VERTICES(ctx, _NEW_TEXTURE); + texUnit->ObjectPlaneQ[0] = params[0]; + texUnit->ObjectPlaneQ[1] = params[1]; + texUnit->ObjectPlaneQ[2] = params[2]; + texUnit->ObjectPlaneQ[3] = params[3]; + } + else if (pname==GL_EYE_PLANE) { + GLfloat tmp[4]; + /* Transform plane equation by the inverse modelview matrix */ + if (ctx->ModelView.flags & MAT_DIRTY_INVERSE) { + _math_matrix_analyse( &ctx->ModelView ); + } + _mesa_transform_vector( tmp, params, ctx->ModelView.inv ); + if (TEST_EQ_4V(texUnit->EyePlaneQ, tmp)) + return; + FLUSH_VERTICES(ctx, _NEW_TEXTURE); + COPY_4FV(texUnit->EyePlaneQ, tmp); + } + else { + _mesa_error( ctx, GL_INVALID_ENUM, "glTexGenfv(pname)" ); + return; + } + break; + default: + _mesa_error( ctx, GL_INVALID_ENUM, "glTexGenfv(coord)" ); + return; + } + + if (ctx->Driver.TexGen) + ctx->Driver.TexGen( ctx, coord, pname, params ); +} + + +void +_mesa_TexGeniv(GLenum coord, GLenum pname, const GLint *params ) +{ + GLfloat p[4]; + p[0] = params[0]; + p[1] = params[1]; + p[2] = params[2]; + p[3] = params[3]; + _mesa_TexGenfv(coord, pname, p); +} + + +void +_mesa_TexGend(GLenum coord, GLenum pname, GLdouble param ) +{ + GLfloat p = (GLfloat) param; + _mesa_TexGenfv( coord, pname, &p ); +} + + +void +_mesa_TexGendv(GLenum coord, GLenum pname, const GLdouble *params ) +{ + GLfloat p[4]; + p[0] = params[0]; + p[1] = params[1]; + p[2] = params[2]; + p[3] = params[3]; + _mesa_TexGenfv( coord, pname, p ); +} + + +void +_mesa_TexGenf( GLenum coord, GLenum pname, GLfloat param ) +{ + _mesa_TexGenfv(coord, pname, ¶m); +} + + +void +_mesa_TexGeni( GLenum coord, GLenum pname, GLint param ) +{ + _mesa_TexGeniv( coord, pname, ¶m ); +} + + + +void +_mesa_GetTexGendv( GLenum coord, GLenum pname, GLdouble *params ) +{ + GET_CURRENT_CONTEXT(ctx); + GLuint tUnit = ctx->Texture.CurrentUnit; + struct gl_texture_unit *texUnit = &ctx->Texture.Unit[tUnit]; + ASSERT_OUTSIDE_BEGIN_END(ctx); + + switch (coord) { + case GL_S: + if (pname==GL_TEXTURE_GEN_MODE) { + params[0] = ENUM_TO_DOUBLE(texUnit->GenModeS); + } + else if (pname==GL_OBJECT_PLANE) { + COPY_4V( params, texUnit->ObjectPlaneS ); + } + else if (pname==GL_EYE_PLANE) { + COPY_4V( params, texUnit->EyePlaneS ); + } + else { + _mesa_error( ctx, GL_INVALID_ENUM, "glGetTexGendv(pname)" ); + return; + } + break; + case GL_T: + if (pname==GL_TEXTURE_GEN_MODE) { + params[0] = ENUM_TO_DOUBLE(texUnit->GenModeT); + } + else if (pname==GL_OBJECT_PLANE) { + COPY_4V( params, texUnit->ObjectPlaneT ); + } + else if (pname==GL_EYE_PLANE) { + COPY_4V( params, texUnit->EyePlaneT ); + } + else { + _mesa_error( ctx, GL_INVALID_ENUM, "glGetTexGendv(pname)" ); + return; + } + break; + case GL_R: + if (pname==GL_TEXTURE_GEN_MODE) { + params[0] = ENUM_TO_DOUBLE(texUnit->GenModeR); + } + else if (pname==GL_OBJECT_PLANE) { + COPY_4V( params, texUnit->ObjectPlaneR ); + } + else if (pname==GL_EYE_PLANE) { + COPY_4V( params, texUnit->EyePlaneR ); + } + else { + _mesa_error( ctx, GL_INVALID_ENUM, "glGetTexGendv(pname)" ); + return; + } + break; + case GL_Q: + if (pname==GL_TEXTURE_GEN_MODE) { + params[0] = ENUM_TO_DOUBLE(texUnit->GenModeQ); + } + else if (pname==GL_OBJECT_PLANE) { + COPY_4V( params, texUnit->ObjectPlaneQ ); + } + else if (pname==GL_EYE_PLANE) { + COPY_4V( params, texUnit->EyePlaneQ ); + } + else { + _mesa_error( ctx, GL_INVALID_ENUM, "glGetTexGendv(pname)" ); + return; + } + break; + default: + _mesa_error( ctx, GL_INVALID_ENUM, "glGetTexGendv(coord)" ); + return; + } +} + + + +void +_mesa_GetTexGenfv( GLenum coord, GLenum pname, GLfloat *params ) +{ + GET_CURRENT_CONTEXT(ctx); + GLuint tUnit = ctx->Texture.CurrentUnit; + struct gl_texture_unit *texUnit = &ctx->Texture.Unit[tUnit]; + ASSERT_OUTSIDE_BEGIN_END(ctx); + + switch (coord) { + case GL_S: + if (pname==GL_TEXTURE_GEN_MODE) { + params[0] = ENUM_TO_FLOAT(texUnit->GenModeS); + } + else if (pname==GL_OBJECT_PLANE) { + COPY_4V( params, texUnit->ObjectPlaneS ); + } + else if (pname==GL_EYE_PLANE) { + COPY_4V( params, texUnit->EyePlaneS ); + } + else { + _mesa_error( ctx, GL_INVALID_ENUM, "glGetTexGenfv(pname)" ); + return; + } + break; + case GL_T: + if (pname==GL_TEXTURE_GEN_MODE) { + params[0] = ENUM_TO_FLOAT(texUnit->GenModeT); + } + else if (pname==GL_OBJECT_PLANE) { + COPY_4V( params, texUnit->ObjectPlaneT ); + } + else if (pname==GL_EYE_PLANE) { + COPY_4V( params, texUnit->EyePlaneT ); + } + else { + _mesa_error( ctx, GL_INVALID_ENUM, "glGetTexGenfv(pname)" ); + return; + } + break; + case GL_R: + if (pname==GL_TEXTURE_GEN_MODE) { + params[0] = ENUM_TO_FLOAT(texUnit->GenModeR); + } + else if (pname==GL_OBJECT_PLANE) { + COPY_4V( params, texUnit->ObjectPlaneR ); + } + else if (pname==GL_EYE_PLANE) { + COPY_4V( params, texUnit->EyePlaneR ); + } + else { + _mesa_error( ctx, GL_INVALID_ENUM, "glGetTexGenfv(pname)" ); + return; + } + break; + case GL_Q: + if (pname==GL_TEXTURE_GEN_MODE) { + params[0] = ENUM_TO_FLOAT(texUnit->GenModeQ); + } + else if (pname==GL_OBJECT_PLANE) { + COPY_4V( params, texUnit->ObjectPlaneQ ); + } + else if (pname==GL_EYE_PLANE) { + COPY_4V( params, texUnit->EyePlaneQ ); + } + else { + _mesa_error( ctx, GL_INVALID_ENUM, "glGetTexGenfv(pname)" ); + return; + } + break; + default: + _mesa_error( ctx, GL_INVALID_ENUM, "glGetTexGenfv(coord)" ); + return; + } +} + + + +void +_mesa_GetTexGeniv( GLenum coord, GLenum pname, GLint *params ) +{ + GET_CURRENT_CONTEXT(ctx); + GLuint tUnit = ctx->Texture.CurrentUnit; + struct gl_texture_unit *texUnit = &ctx->Texture.Unit[tUnit]; + ASSERT_OUTSIDE_BEGIN_END(ctx); + + switch (coord) { + case GL_S: + if (pname==GL_TEXTURE_GEN_MODE) { + params[0] = texUnit->GenModeS; + } + else if (pname==GL_OBJECT_PLANE) { + params[0] = (GLint) texUnit->ObjectPlaneS[0]; + params[1] = (GLint) texUnit->ObjectPlaneS[1]; + params[2] = (GLint) texUnit->ObjectPlaneS[2]; + params[3] = (GLint) texUnit->ObjectPlaneS[3]; + } + else if (pname==GL_EYE_PLANE) { + params[0] = (GLint) texUnit->EyePlaneS[0]; + params[1] = (GLint) texUnit->EyePlaneS[1]; + params[2] = (GLint) texUnit->EyePlaneS[2]; + params[3] = (GLint) texUnit->EyePlaneS[3]; + } + else { + _mesa_error( ctx, GL_INVALID_ENUM, "glGetTexGeniv(pname)" ); + return; + } + break; + case GL_T: + if (pname==GL_TEXTURE_GEN_MODE) { + params[0] = texUnit->GenModeT; + } + else if (pname==GL_OBJECT_PLANE) { + params[0] = (GLint) texUnit->ObjectPlaneT[0]; + params[1] = (GLint) texUnit->ObjectPlaneT[1]; + params[2] = (GLint) texUnit->ObjectPlaneT[2]; + params[3] = (GLint) texUnit->ObjectPlaneT[3]; + } + else if (pname==GL_EYE_PLANE) { + params[0] = (GLint) texUnit->EyePlaneT[0]; + params[1] = (GLint) texUnit->EyePlaneT[1]; + params[2] = (GLint) texUnit->EyePlaneT[2]; + params[3] = (GLint) texUnit->EyePlaneT[3]; + } + else { + _mesa_error( ctx, GL_INVALID_ENUM, "glGetTexGeniv(pname)" ); + return; + } + break; + case GL_R: + if (pname==GL_TEXTURE_GEN_MODE) { + params[0] = texUnit->GenModeR; + } + else if (pname==GL_OBJECT_PLANE) { + params[0] = (GLint) texUnit->ObjectPlaneR[0]; + params[1] = (GLint) texUnit->ObjectPlaneR[1]; + params[2] = (GLint) texUnit->ObjectPlaneR[2]; + params[3] = (GLint) texUnit->ObjectPlaneR[3]; + } + else if (pname==GL_EYE_PLANE) { + params[0] = (GLint) texUnit->EyePlaneR[0]; + params[1] = (GLint) texUnit->EyePlaneR[1]; + params[2] = (GLint) texUnit->EyePlaneR[2]; + params[3] = (GLint) texUnit->EyePlaneR[3]; + } + else { + _mesa_error( ctx, GL_INVALID_ENUM, "glGetTexGeniv(pname)" ); + return; + } + break; + case GL_Q: + if (pname==GL_TEXTURE_GEN_MODE) { + params[0] = texUnit->GenModeQ; + } + else if (pname==GL_OBJECT_PLANE) { + params[0] = (GLint) texUnit->ObjectPlaneQ[0]; + params[1] = (GLint) texUnit->ObjectPlaneQ[1]; + params[2] = (GLint) texUnit->ObjectPlaneQ[2]; + params[3] = (GLint) texUnit->ObjectPlaneQ[3]; + } + else if (pname==GL_EYE_PLANE) { + params[0] = (GLint) texUnit->EyePlaneQ[0]; + params[1] = (GLint) texUnit->EyePlaneQ[1]; + params[2] = (GLint) texUnit->EyePlaneQ[2]; + params[3] = (GLint) texUnit->EyePlaneQ[3]; + } + else { + _mesa_error( ctx, GL_INVALID_ENUM, "glGetTexGeniv(pname)" ); + return; + } + break; + default: + _mesa_error( ctx, GL_INVALID_ENUM, "glGetTexGeniv(coord)" ); + return; + } +} + + +/* GL_ARB_multitexture */ +void +_mesa_ActiveTextureARB( GLenum target ) +{ + GET_CURRENT_CONTEXT(ctx); + GLuint texUnit = target - GL_TEXTURE0_ARB; + ASSERT_OUTSIDE_BEGIN_END(ctx); + + if (MESA_VERBOSE & (VERBOSE_API|VERBOSE_TEXTURE)) + fprintf(stderr, "glActiveTexture %s\n", + _mesa_lookup_enum_by_nr(target)); + + if (texUnit > ctx->Const.MaxTextureUnits) { + _mesa_error(ctx, GL_INVALID_ENUM, "glActiveTextureARB(target)"); + return; + } + + FLUSH_VERTICES(ctx, _NEW_TEXTURE); + ctx->Texture.CurrentUnit = texUnit; + if (ctx->Driver.ActiveTexture) { + (*ctx->Driver.ActiveTexture)( ctx, (GLuint) texUnit ); + } +} + + +/* GL_ARB_multitexture */ +void +_mesa_ClientActiveTextureARB( GLenum target ) +{ + GET_CURRENT_CONTEXT(ctx); + GLuint texUnit = target - GL_TEXTURE0_ARB; + ASSERT_OUTSIDE_BEGIN_END(ctx); + + if (texUnit > ctx->Const.MaxTextureUnits) { + _mesa_error(ctx, GL_INVALID_ENUM, "glClientActiveTextureARB(target)"); + return; + } + + FLUSH_VERTICES(ctx, _NEW_ARRAY); + ctx->Array.ActiveTexture = texUnit; +} + + + +/**********************************************************************/ +/* Pixel Texgen Extensions */ +/**********************************************************************/ + +void +_mesa_PixelTexGenSGIX(GLenum mode) +{ + GLenum newRgbSource, newAlphaSource; + GET_CURRENT_CONTEXT(ctx); + ASSERT_OUTSIDE_BEGIN_END(ctx); + + switch (mode) { + case GL_NONE: + newRgbSource = GL_PIXEL_GROUP_COLOR_SGIS; + newAlphaSource = GL_PIXEL_GROUP_COLOR_SGIS; + break; + case GL_ALPHA: + newRgbSource = GL_PIXEL_GROUP_COLOR_SGIS; + newAlphaSource = GL_CURRENT_RASTER_COLOR; + break; + case GL_RGB: + newRgbSource = GL_CURRENT_RASTER_COLOR; + newAlphaSource = GL_PIXEL_GROUP_COLOR_SGIS; + break; + case GL_RGBA: + newRgbSource = GL_CURRENT_RASTER_COLOR; + newAlphaSource = GL_CURRENT_RASTER_COLOR; + break; + default: + _mesa_error(ctx, GL_INVALID_ENUM, "glPixelTexGenSGIX(mode)"); + return; + } + + if (newRgbSource == ctx->Pixel.FragmentRgbSource && + newAlphaSource == ctx->Pixel.FragmentAlphaSource) + return; + + FLUSH_VERTICES(ctx, _NEW_PIXEL); + ctx->Pixel.FragmentRgbSource = newRgbSource; + ctx->Pixel.FragmentAlphaSource = newAlphaSource; +} + + +void +_mesa_PixelTexGenParameterfSGIS(GLenum target, GLfloat value) +{ + _mesa_PixelTexGenParameteriSGIS(target, (GLint) value); +} + + +void +_mesa_PixelTexGenParameterfvSGIS(GLenum target, const GLfloat *value) +{ + _mesa_PixelTexGenParameteriSGIS(target, (GLint) *value); +} + + +void +_mesa_PixelTexGenParameteriSGIS(GLenum target, GLint value) +{ + GET_CURRENT_CONTEXT(ctx); + ASSERT_OUTSIDE_BEGIN_END(ctx); + + if (value != GL_CURRENT_RASTER_COLOR && value != GL_PIXEL_GROUP_COLOR_SGIS) { + _mesa_error(ctx, GL_INVALID_ENUM, "glPixelTexGenParameterSGIS(value)"); + return; + } + + switch (target) { + case GL_PIXEL_FRAGMENT_RGB_SOURCE_SGIS: + if (ctx->Pixel.FragmentRgbSource == (GLenum) value) + return; + FLUSH_VERTICES(ctx, _NEW_PIXEL); + ctx->Pixel.FragmentRgbSource = (GLenum) value; + break; + case GL_PIXEL_FRAGMENT_ALPHA_SOURCE_SGIS: + if (ctx->Pixel.FragmentAlphaSource == (GLenum) value) + return; + FLUSH_VERTICES(ctx, _NEW_PIXEL); + ctx->Pixel.FragmentAlphaSource = (GLenum) value; + break; + default: + _mesa_error(ctx, GL_INVALID_ENUM, "glPixelTexGenParameterSGIS(target)"); + return; + } +} + + +void +_mesa_PixelTexGenParameterivSGIS(GLenum target, const GLint *value) +{ + _mesa_PixelTexGenParameteriSGIS(target, *value); +} + + +void +_mesa_GetPixelTexGenParameterfvSGIS(GLenum target, GLfloat *value) +{ + GET_CURRENT_CONTEXT(ctx); + ASSERT_OUTSIDE_BEGIN_END(ctx); + + if (target == GL_PIXEL_FRAGMENT_RGB_SOURCE_SGIS) { + *value = (GLfloat) ctx->Pixel.FragmentRgbSource; + } + else if (target == GL_PIXEL_FRAGMENT_ALPHA_SOURCE_SGIS) { + *value = (GLfloat) ctx->Pixel.FragmentAlphaSource; + } + else { + _mesa_error(ctx, GL_INVALID_ENUM, "glGetPixelTexGenParameterfvSGIS(target)"); + } +} + + +void +_mesa_GetPixelTexGenParameterivSGIS(GLenum target, GLint *value) +{ + GET_CURRENT_CONTEXT(ctx); + ASSERT_OUTSIDE_BEGIN_END(ctx); + + if (target == GL_PIXEL_FRAGMENT_RGB_SOURCE_SGIS) { + *value = (GLint) ctx->Pixel.FragmentRgbSource; + } + else if (target == GL_PIXEL_FRAGMENT_ALPHA_SOURCE_SGIS) { + *value = (GLint) ctx->Pixel.FragmentAlphaSource; + } + else { + _mesa_error(ctx, GL_INVALID_ENUM, "glGetPixelTexGenParameterivSGIS(target)"); + } +} Index: dll/opengl/opengl32/mesa/texstate.h =================================================================== --- dll/opengl/opengl32/mesa/texstate.h (revision 0) +++ dll/opengl/opengl32/mesa/texstate.h (working copy) @@ -0,0 +1,163 @@ +/* $Id: texstate.h,v 1.8 2001/06/18 17:26:08 brianp Exp $ */ + +/* + * Mesa 3-D graphics library + * Version: 3.5 + * + * Copyright (C) 1999-2001 Brian Paul 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 + * BRIAN PAUL 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. + */ + + +#ifndef TEXSTATE_H +#define TEXSTATE_H + + +#include "mtypes.h" + + +/*** Called from API ***/ + +extern void +_mesa_GetTexEnvfv( GLenum target, GLenum pname, GLfloat *params ); + +extern void +_mesa_GetTexEnviv( GLenum target, GLenum pname, GLint *params ); + +extern void +_mesa_GetTexGendv( GLenum coord, GLenum pname, GLdouble *params ); + +extern void +_mesa_GetTexGenfv( GLenum coord, GLenum pname, GLfloat *params ); + +extern void +_mesa_GetTexGeniv( GLenum coord, GLenum pname, GLint *params ); + +extern void +_mesa_GetTexLevelParameterfv( GLenum target, GLint level, + GLenum pname, GLfloat *params ); + +extern void +_mesa_GetTexLevelParameteriv( GLenum target, GLint level, + GLenum pname, GLint *params ); + +extern void +_mesa_GetTexParameterfv( GLenum target, GLenum pname, GLfloat *params ); + +extern void +_mesa_GetTexParameteriv( GLenum target, GLenum pname, GLint *params ); + + +extern void +_mesa_TexEnvf( GLenum target, GLenum pname, GLfloat param ); + +extern void +_mesa_TexEnvfv( GLenum target, GLenum pname, const GLfloat *param ); + +extern void +_mesa_TexEnvi( GLenum target, GLenum pname, GLint param ); + +extern void +_mesa_TexEnviv( GLenum target, GLenum pname, const GLint *param ); + + +extern void +_mesa_TexParameterfv( GLenum target, GLenum pname, const GLfloat *params ); + +extern void +_mesa_TexParameterf( GLenum target, GLenum pname, GLfloat param ); + + +extern void +_mesa_TexParameteri( GLenum target, GLenum pname, GLint param ); + +extern void +_mesa_TexParameteriv( GLenum target, GLenum pname, const GLint *params ); + + +extern void +_mesa_TexGend( GLenum coord, GLenum pname, GLdouble param ); + +extern void +_mesa_TexGendv( GLenum coord, GLenum pname, const GLdouble *params ); + +extern void +_mesa_TexGenf( GLenum coord, GLenum pname, GLfloat param ); + +extern void +_mesa_TexGenfv( GLenum coord, GLenum pname, const GLfloat *params ); + +extern void +_mesa_TexGeni( GLenum coord, GLenum pname, GLint param ); + +extern void +_mesa_TexGeniv( GLenum coord, GLenum pname, const GLint *params ); + + + + +/* + * GL_ARB_multitexture + */ +extern void +_mesa_ActiveTextureARB( GLenum target ); + +extern void +_mesa_ClientActiveTextureARB( GLenum target ); + + +/* + * Pixel Texture Extensions + */ + +extern void +_mesa_PixelTexGenSGIX(GLenum mode); + +extern void +_mesa_PixelTexGenParameterfSGIS(GLenum target, GLfloat value); + +#ifdef VMS +#define _mesa_PixelTexGenParameterfvSGIS _mesa_PixelTexGenParameterfv +#endif +extern void +_mesa_PixelTexGenParameterfvSGIS(GLenum target, const GLfloat *value); + +extern void +_mesa_PixelTexGenParameteriSGIS(GLenum target, GLint value); + +#ifdef VMS +#define _mesa_PixelTexGenParameterivSGIS _mesa_PixelTexGenParameteriv +#endif +extern void +_mesa_PixelTexGenParameterivSGIS(GLenum target, const GLint *value); + +#ifdef VMS +#define _mesa_GetPixelTexGenParameterfvSGIS _mesa_GetPixelTexGenParameterfv +#endif +extern void +_mesa_GetPixelTexGenParameterfvSGIS(GLenum target, GLfloat *value); + +#ifdef VMS +#define _mesa_GetPixelTexGenParameterivSGIS _mesa_GetPixelTexGenParameteriv +#endif +extern void +_mesa_GetPixelTexGenParameterivSGIS(GLenum target, GLint *value); + + +#endif Index: dll/opengl/opengl32/mesa/texstore.c =================================================================== --- dll/opengl/opengl32/mesa/texstore.c (revision 0) +++ dll/opengl/opengl32/mesa/texstore.c (working copy) @@ -0,0 +1,1741 @@ +/* $Id: texstore.c,v 1.29 2001/06/15 14:18:46 brianp Exp $ */ + +/* + * Mesa 3-D graphics library + * Version: 3.5 + * + * Copyright (C) 1999-2001 Brian Paul 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 + * BRIAN PAUL 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. + */ + +/* + * Authors: + * Brian Paul + */ + +#include "colormac.h" +#include "context.h" +#include "convolve.h" +#include "image.h" +#include "macros.h" +#include "mem.h" +#include "texformat.h" +#include "teximage.h" +#include "texstore.h" +#include "texutil.h" + + +/* + * Given an internal texture format enum or 1, 2, 3, 4 return the + * corresponding _base_ internal format: GL_ALPHA, GL_LUMINANCE, + * GL_LUMANCE_ALPHA, GL_INTENSITY, GL_RGB, or GL_RGBA. Return the + * number of components for the format. Return -1 if invalid enum. + * + * GH: Do we really need this? We have the number of bytes per texel + * in the texture format structures, so why don't we just use that? + */ +static GLint +components_in_intformat( GLint format ) +{ + switch (format) { + case GL_ALPHA: + case GL_ALPHA4: + case GL_ALPHA8: + case GL_ALPHA12: + case GL_ALPHA16: + return 1; + case 1: + case GL_LUMINANCE: + case GL_LUMINANCE4: + case GL_LUMINANCE8: + case GL_LUMINANCE12: + case GL_LUMINANCE16: + return 1; + case 2: + case GL_LUMINANCE_ALPHA: + case GL_LUMINANCE4_ALPHA4: + case GL_LUMINANCE6_ALPHA2: + case GL_LUMINANCE8_ALPHA8: + case GL_LUMINANCE12_ALPHA4: + case GL_LUMINANCE12_ALPHA12: + case GL_LUMINANCE16_ALPHA16: + return 2; + case GL_INTENSITY: + case GL_INTENSITY4: + case GL_INTENSITY8: + case GL_INTENSITY12: + case GL_INTENSITY16: + return 1; + case 3: + case GL_RGB: + case GL_R3_G3_B2: + case GL_RGB4: + case GL_RGB5: + case GL_RGB8: + case GL_RGB10: + case GL_RGB12: + case GL_RGB16: + return 3; + case 4: + case GL_RGBA: + case GL_RGBA2: + case GL_RGBA4: + case GL_RGB5_A1: + case GL_RGBA8: + case GL_RGB10_A2: + case GL_RGBA12: + case GL_RGBA16: + return 4; + case GL_COLOR_INDEX: + case GL_COLOR_INDEX1_EXT: + case GL_COLOR_INDEX2_EXT: + case GL_COLOR_INDEX4_EXT: + case GL_COLOR_INDEX8_EXT: + case GL_COLOR_INDEX12_EXT: + case GL_COLOR_INDEX16_EXT: + return 1; + case GL_DEPTH_COMPONENT: + case GL_DEPTH_COMPONENT16_SGIX: + case GL_DEPTH_COMPONENT24_SGIX: + case GL_DEPTH_COMPONENT32_SGIX: + return 1; + default: + return -1; /* error */ + } +} + + +/* + * This function is used to transfer the user's image data into a texture + * image buffer. We handle both full texture images and subtexture images. + * We also take care of all image transfer operations here, including + * convolution, scale/bias, colortables, etc. + * + * The destination texel channel type is always GLchan. + * + * A hardware driver may use this as a helper routine to unpack and + * apply pixel transfer ops into a temporary image buffer. Then, + * convert the temporary image into the special hardware format. + * + * Input: + * dimensions - 1, 2, or 3 + * texFormat - GL_LUMINANCE, GL_INTENSITY, GL_LUMINANCE_ALPHA, GL_ALPHA, + * GL_RGB or GL_RGBA + * texDestAddr - destination image address + * srcWidth, srcHeight, srcDepth - size (in pixels) of src and dest images + * dstXoffset, dstYoffset, dstZoffset - position to store the image within + * the destination 3D texture + * dstRowStride, dstImageStride - dest image strides in bytes + * srcFormat - source image format (GL_ALPHA, GL_RED, GL_RGB, etc) + * srcType - GL_UNSIGNED_BYTE, GL_UNSIGNED_SHORT_5_6_5, GL_FLOAT, etc + * srcPacking - describes packing of incoming image. + * transferOps - mask of pixel transfer operations + */ +static void +transfer_teximage(GLcontext *ctx, GLuint dimensions, + GLenum texDestFormat, GLvoid *texDestAddr, + GLint srcWidth, GLint srcHeight, GLint srcDepth, + GLint dstXoffset, GLint dstYoffset, GLint dstZoffset, + GLint dstRowStride, GLint dstImageStride, + GLenum srcFormat, GLenum srcType, + const GLvoid *srcAddr, + const struct gl_pixelstore_attrib *srcPacking, + GLuint transferOps) +{ + GLint texComponents; + + ASSERT(ctx); + ASSERT(dimensions >= 1 && dimensions <= 3); + ASSERT(texDestAddr); + ASSERT(srcWidth >= 1); + ASSERT(srcHeight >= 1); + ASSERT(srcDepth >= 1); + ASSERT(dstXoffset >= 0); + ASSERT(dstYoffset >= 0); + ASSERT(dstZoffset >= 0); + ASSERT(dstRowStride >= 0); + ASSERT(dstImageStride >= 0); + ASSERT(srcAddr); + ASSERT(srcPacking); + + texComponents = components_in_intformat(texDestFormat); + + /* try common 2D texture cases first */ + if (!transferOps && dimensions == 2 && srcType == CHAN_TYPE) { + + if (srcFormat == texDestFormat) { + /* This will cover the common GL_RGB, GL_RGBA, GL_ALPHA, + * GL_LUMINANCE_ALPHA, etc. texture formats. Use memcpy(). + */ + const GLchan *src = (const GLchan *) _mesa_image_address( + srcPacking, srcAddr, srcWidth, srcHeight, + srcFormat, srcType, 0, 0, 0); + const GLint srcRowStride = _mesa_image_row_stride(srcPacking, + srcWidth, srcFormat, srcType); + const GLint widthInBytes = srcWidth * texComponents * sizeof(GLchan); + GLchan *dst = (GLchan *) texDestAddr + dstYoffset * dstRowStride + + dstXoffset * texComponents; + if (srcRowStride == widthInBytes && dstRowStride == widthInBytes) { + MEMCPY(dst, src, srcHeight * widthInBytes); + } + else { + GLint i; + for (i = 0; i < srcHeight; i++) { + MEMCPY(dst, src, widthInBytes); + src += srcRowStride; + dst += dstRowStride; + } + } + return; /* all done */ + } + else if (srcFormat == GL_RGBA && texDestFormat == GL_RGB) { + /* commonly used by Quake */ + const GLchan *src = (const GLchan *) _mesa_image_address( + srcPacking, srcAddr, srcWidth, srcHeight, + srcFormat, srcType, 0, 0, 0); + const GLint srcRowStride = _mesa_image_row_stride(srcPacking, + srcWidth, srcFormat, srcType); + GLchan *dst = (GLchan *) texDestAddr + dstYoffset * dstRowStride + + dstXoffset * texComponents; + GLint i, j; + for (i = 0; i < srcHeight; i++) { + const GLchan *s = src; + GLchan *d = dst; + for (j = 0; j < srcWidth; j++) { + *d++ = *s++; /*red*/ + *d++ = *s++; /*green*/ + *d++ = *s++; /*blue*/ + s++; /*alpha*/ + } + src += srcRowStride; + dst += dstRowStride; + } + return; /* all done */ + } + } + + /* + * General case solutions + */ + if (texDestFormat == GL_COLOR_INDEX) { + /* color index texture */ + const GLenum texType = CHAN_TYPE; + GLint img, row; + GLchan *dest = (GLchan *) texDestAddr + dstZoffset * dstImageStride + + dstYoffset * dstRowStride + + dstXoffset * texComponents; + for (img = 0; img < srcDepth; img++) { + GLchan *destRow = dest; + for (row = 0; row < srcHeight; row++) { + const GLvoid *src = _mesa_image_address(srcPacking, + srcAddr, srcWidth, srcHeight, srcFormat, srcType, img, row, 0); + _mesa_unpack_index_span(ctx, srcWidth, texType, destRow, + srcType, src, srcPacking, transferOps); + destRow += dstRowStride; + } + dest += dstImageStride; + } + } + else if (texDestFormat == GL_DEPTH_COMPONENT) { + /* Depth texture (shadow maps) */ + GLint img, row; + GLubyte *dest = (GLubyte *) texDestAddr + + dstZoffset * dstImageStride + + dstYoffset * dstRowStride + + dstXoffset * texComponents; + for (img = 0; img < srcDepth; img++) { + GLubyte *destRow = dest; + for (row = 0; row < srcHeight; row++) { + const GLvoid *src = _mesa_image_address(srcPacking, + srcAddr, srcWidth, srcHeight, srcFormat, srcType, img, row, 0); + _mesa_unpack_depth_span(ctx, srcWidth, (GLfloat *) destRow, + srcType, src, srcPacking); + destRow += dstRowStride; + } + dest += dstImageStride; + } + } + else { + /* regular, color texture */ + if ((dimensions == 1 && ctx->Pixel.Convolution1DEnabled) || + (dimensions >= 2 && ctx->Pixel.Convolution2DEnabled) || + (dimensions >= 2 && ctx->Pixel.Separable2DEnabled)) { + /* + * Fill texture image with convolution + */ + GLint img, row; + GLint convWidth = srcWidth, convHeight = srcHeight; + GLfloat *tmpImage, *convImage; + tmpImage = (GLfloat *) MALLOC(srcWidth * srcHeight * 4 * sizeof(GLfloat)); + if (!tmpImage) { + _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage"); + return; + } + convImage = (GLfloat *) MALLOC(srcWidth * srcHeight * 4 * sizeof(GLfloat)); + if (!convImage) { + _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage"); + FREE(tmpImage); + return; + } + + for (img = 0; img < srcDepth; img++) { + const GLfloat *srcf; + GLfloat *dstf = tmpImage; + GLchan *dest; + + /* unpack and do transfer ops up to convolution */ + for (row = 0; row < srcHeight; row++) { + const GLvoid *src = _mesa_image_address(srcPacking, + srcAddr, srcWidth, srcHeight, + srcFormat, srcType, img, row, 0); + _mesa_unpack_float_color_span(ctx, srcWidth, GL_RGBA, dstf, + srcFormat, srcType, src, srcPacking, + transferOps & IMAGE_PRE_CONVOLUTION_BITS, + GL_TRUE); + dstf += srcWidth * 4; + } + + /* convolve */ + if (dimensions == 1) { + ASSERT(ctx->Pixel.Convolution1DEnabled); + _mesa_convolve_1d_image(ctx, &convWidth, tmpImage, convImage); + } + else { + if (ctx->Pixel.Convolution2DEnabled) { + _mesa_convolve_2d_image(ctx, &convWidth, &convHeight, + tmpImage, convImage); + } + else { + ASSERT(ctx->Pixel.Separable2DEnabled); + _mesa_convolve_sep_image(ctx, &convWidth, &convHeight, + tmpImage, convImage); + } + } + + /* packing and transfer ops after convolution */ + srcf = convImage; + dest = (GLchan *) texDestAddr + (dstZoffset + img) * dstImageStride + + dstYoffset * dstRowStride; + for (row = 0; row < convHeight; row++) { + _mesa_pack_float_rgba_span(ctx, convWidth, + (const GLfloat (*)[4]) srcf, + texDestFormat, CHAN_TYPE, + dest, &_mesa_native_packing, + transferOps + & IMAGE_POST_CONVOLUTION_BITS); + srcf += convWidth * 4; + dest += dstRowStride; + } + } + + FREE(convImage); + FREE(tmpImage); + } + else { + /* + * no convolution + */ + GLint img, row; + GLchan *dest = (GLchan *) texDestAddr + dstZoffset * dstImageStride + + dstYoffset * dstRowStride + + dstXoffset * texComponents; + for (img = 0; img < srcDepth; img++) { + GLchan *destRow = dest; + for (row = 0; row < srcHeight; row++) { + const GLvoid *srcRow = _mesa_image_address(srcPacking, + srcAddr, srcWidth, srcHeight, + srcFormat, srcType, img, row, 0); + _mesa_unpack_chan_color_span(ctx, srcWidth, texDestFormat, + destRow, srcFormat, srcType, srcRow, + srcPacking, transferOps); + destRow += dstRowStride; + } + dest += dstImageStride; + } + } + } +} + + + +/* + * Transfer a texture image from user space to applying all + * needed image transfer operations and storing the result in the format + * specified by . may be any format from texformat.h. + * Input: + * dimensions - 1, 2 or 3 + * baseInternalFormat - base format of the internal texture format + * specified by the user. This is very important, see below. + * dstFormat - destination image format + * dstAddr - destination address + * srcWidth, srcHeight, srcDepth - size of source iamge + * dstX/Y/Zoffset - as specified by glTexSubImage + * dstRowStride - stride between dest rows in bytes + * dstImagetride - stride between dest images in bytes + * srcFormat, srcType - incoming image format and datatype + * srcAddr - source image address + * srcPacking - packing params of source image + * + * XXX this function is a bit more complicated than it should be. If + * _mesa_convert_texsubimage[123]d could handle any dest/source formats + * or if transfer_teximage() could store in any MESA_FORMAT_* format, we + * could simplify things here. + */ +void +_mesa_transfer_teximage(GLcontext *ctx, GLuint dimensions, + GLenum baseInternalFormat, + const struct gl_texture_format *dstFormat, + GLvoid *dstAddr, + GLint srcWidth, GLint srcHeight, GLint srcDepth, + GLint dstXoffset, GLint dstYoffset, GLint dstZoffset, + GLint dstRowStride, GLint dstImageStride, + GLenum srcFormat, GLenum srcType, + const GLvoid *srcAddr, + const struct gl_pixelstore_attrib *srcPacking) +{ + const GLint dstRowStridePixels = dstRowStride / dstFormat->TexelBytes; + const GLint dstImageStridePixels = dstImageStride / dstFormat->TexelBytes; + GLboolean makeTemp; + GLuint transferOps = ctx->_ImageTransferState; + GLboolean freeSourceData = GL_FALSE; + GLint postConvWidth = srcWidth, postConvHeight = srcHeight; + + assert(baseInternalFormat > 0); + + if (transferOps & IMAGE_CONVOLUTION_BIT) { + _mesa_adjust_image_for_convolution(ctx, dimensions, &postConvWidth, + &postConvHeight); + } + + /* + * Consider this scenario: The user's source image is GL_RGB and the + * requested internal format is GL_LUMINANCE. Now suppose the device + * driver doesn't support GL_LUMINANCE and instead uses RGB16 as the + * texture format. In that case we still need to do an intermediate + * conversion to luminance format so that the incoming red channel gets + * replicated into the dest red, green and blue channels. The following + * code takes care of that. + */ + if (dstFormat->BaseFormat != baseInternalFormat) { + /* Allocate storage for temporary image in the baseInternalFormat */ + const GLint texelSize = _mesa_components_in_format(baseInternalFormat) + * sizeof(GLchan); + const GLint bytes = texelSize * postConvWidth * postConvHeight *srcDepth; + const GLint tmpRowStride = texelSize * postConvWidth; + const GLint tmpImgStride = texelSize * postConvWidth * postConvHeight; + GLvoid *tmpImage = MALLOC(bytes); + if (!tmpImage) + return; + transfer_teximage(ctx, dimensions, baseInternalFormat, tmpImage, + srcWidth, srcHeight, srcDepth, + 0, 0, 0, /* x/y/zoffset */ + tmpRowStride, tmpImgStride, + srcFormat, srcType, srcAddr, srcPacking, transferOps); + + /* this is our new source image */ + srcWidth = postConvWidth; + srcHeight = postConvHeight; + srcFormat = baseInternalFormat; + srcType = CHAN_TYPE; + srcAddr = tmpImage; + srcPacking = &_mesa_native_packing; + freeSourceData = GL_TRUE; + transferOps = 0; /* image transfer ops were completed */ + } + + /* Let the optimized tex conversion functions take a crack at the + * image conversion if the dest format is a h/w format. + */ + if (_mesa_is_hardware_tex_format(dstFormat)) { + if (transferOps) { + makeTemp = GL_TRUE; + } + else { + if (dimensions == 1) { + makeTemp = !_mesa_convert_texsubimage1d(dstFormat->MesaFormat, + dstXoffset, + srcWidth, + srcFormat, srcType, + srcPacking, srcAddr, + dstAddr); + } + else if (dimensions == 2) { + makeTemp = !_mesa_convert_texsubimage2d(dstFormat->MesaFormat, + dstXoffset, dstYoffset, + srcWidth, srcHeight, + dstRowStridePixels, + srcFormat, srcType, + srcPacking, srcAddr, + dstAddr); + } + else { + assert(dimensions == 3); + makeTemp = !_mesa_convert_texsubimage3d(dstFormat->MesaFormat, + dstXoffset, dstYoffset, dstZoffset, + srcWidth, srcHeight, srcDepth, + dstRowStridePixels, dstImageStridePixels, + srcFormat, srcType, + srcPacking, srcAddr, dstAddr); + } + if (!makeTemp) { + /* all done! */ + if (freeSourceData) + FREE((void *) srcAddr); + return; + } + } + } + else { + /* software texture format */ + makeTemp = GL_FALSE; + } + + if (makeTemp) { + GLint postConvWidth = srcWidth, postConvHeight = srcHeight; + GLenum tmpFormat; + GLuint tmpComps, tmpTexelSize; + GLint tmpRowStride, tmpImageStride; + GLubyte *tmpImage; + + if (transferOps & IMAGE_CONVOLUTION_BIT) { + _mesa_adjust_image_for_convolution(ctx, dimensions, &postConvWidth, + &postConvHeight); + } + + tmpFormat = dstFormat->BaseFormat; + tmpComps = _mesa_components_in_format(tmpFormat); + tmpTexelSize = tmpComps * sizeof(GLchan); + tmpRowStride = postConvWidth * tmpTexelSize; + tmpImageStride = postConvWidth * postConvHeight * tmpTexelSize; + tmpImage = (GLubyte *) MALLOC(postConvWidth * postConvHeight * + srcDepth * tmpTexelSize); + if (!tmpImage) { + if (freeSourceData) + FREE((void *) srcAddr); + return; + } + + transfer_teximage(ctx, dimensions, tmpFormat, tmpImage, + srcWidth, srcHeight, srcDepth, + 0, 0, 0, /* x/y/zoffset */ + tmpRowStride, tmpImageStride, + srcFormat, srcType, srcAddr, srcPacking, transferOps); + + if (freeSourceData) + FREE((void *) srcAddr); + + /* the temp image is our new source image */ + srcWidth = postConvWidth; + srcHeight = postConvHeight; + srcFormat = tmpFormat; + srcType = CHAN_TYPE; + srcAddr = tmpImage; + srcPacking = &_mesa_native_packing; + freeSourceData = GL_TRUE; + } + + if (_mesa_is_hardware_tex_format(dstFormat)) { + assert(makeTemp); + if (dimensions == 1) { + GLboolean b; + b = _mesa_convert_texsubimage1d(dstFormat->MesaFormat, + dstXoffset, + srcWidth, + srcFormat, srcType, + srcPacking, srcAddr, + dstAddr); + assert(b); + } + else if (dimensions == 2) { + GLboolean b; + b = _mesa_convert_texsubimage2d(dstFormat->MesaFormat, + dstXoffset, dstYoffset, + srcWidth, srcHeight, + dstRowStridePixels, + srcFormat, srcType, + srcPacking, srcAddr, + dstAddr); + assert(b); + } + else { + GLboolean b; + b = _mesa_convert_texsubimage3d(dstFormat->MesaFormat, + dstXoffset, dstYoffset, dstZoffset, + srcWidth, srcHeight, srcDepth, + dstRowStridePixels, dstImageStridePixels, + srcFormat, srcType, + srcPacking, srcAddr, dstAddr); + assert(b); + } + } + else { + /* software format */ + assert(!makeTemp); + transfer_teximage(ctx, dimensions, dstFormat->BaseFormat, dstAddr, + srcWidth, srcHeight, srcDepth, + dstXoffset, dstYoffset, dstZoffset, + dstRowStride, dstImageStride, + srcFormat, srcType, srcAddr, srcPacking, transferOps); + } + + if (freeSourceData) + FREE((void *) srcAddr); /* the temp image */ +} + + +/* + * This is the software fallback for Driver.TexImage1D(). + * The texture image type will be GLchan. + * The texture image format will be GL_COLOR_INDEX, GL_INTENSITY, + * GL_LUMINANCE, GL_LUMINANCE_ALPHA, GL_ALPHA, GL_RGB or GL_RGBA. + * + */ +void +_mesa_store_teximage1d(GLcontext *ctx, GLenum target, GLint level, + GLint internalFormat, + GLint width, GLint border, + GLenum format, GLenum type, const GLvoid *pixels, + const struct gl_pixelstore_attrib *packing, + struct gl_texture_object *texObj, + struct gl_texture_image *texImage) +{ + GLint postConvWidth = width; + GLint texelBytes, sizeInBytes; + + if (ctx->_ImageTransferState & IMAGE_CONVOLUTION_BIT) { + _mesa_adjust_image_for_convolution(ctx, 1, &postConvWidth, NULL); + } + + /* choose the texture format */ + assert(ctx->Driver.ChooseTextureFormat); + texImage->TexFormat = (*ctx->Driver.ChooseTextureFormat)(ctx, + internalFormat, format, type); + assert(texImage->TexFormat); + texImage->FetchTexel = texImage->TexFormat->FetchTexel1D; + + texelBytes = texImage->TexFormat->TexelBytes; + + /* Compute image size, in bytes */ + if (texImage->IsCompressed) { + assert(ctx->Driver.CompressedTextureSize); + sizeInBytes = ctx->Driver.CompressedTextureSize(ctx, texImage); + assert(sizeInBytes > 0); + texImage->CompressedSize = sizeInBytes; + } + else { + sizeInBytes = postConvWidth * texelBytes; + } + + /* allocate memory */ + texImage->Data = MALLOC(sizeInBytes); + if (!texImage->Data) { + _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage1D"); + return; + } + + /* unpack image, apply transfer ops and store in texImage->Data */ + _mesa_transfer_teximage(ctx, 1, _mesa_base_tex_format(ctx, internalFormat), + texImage->TexFormat, texImage->Data, + width, 1, 1, 0, 0, 0, + 0, /* dstRowStride */ + 0, /* dstImageStride */ + format, type, pixels, packing); + + /* GL_SGIS_generate_mipmap */ + if (level == texObj->BaseLevel && texObj->GenerateMipmap) { + _mesa_generate_mipmap(ctx, &ctx->Texture.Unit[ctx->Texture.CurrentUnit], + texObj); + } +} + + +/* + * This is the software fallback for Driver.TexImage2D(). + * The texture image type will be GLchan. + * The texture image format will be GL_COLOR_INDEX, GL_INTENSITY, + * GL_LUMINANCE, GL_LUMINANCE_ALPHA, GL_ALPHA, GL_RGB or GL_RGBA. + * + * NOTE: if real texture compression is supported, this whole function + * will need to be overridden. + */ +void +_mesa_store_teximage2d(GLcontext *ctx, GLenum target, GLint level, + GLint internalFormat, + GLint width, GLint height, GLint border, + GLenum format, GLenum type, const void *pixels, + const struct gl_pixelstore_attrib *packing, + struct gl_texture_object *texObj, + struct gl_texture_image *texImage) +{ + GLint postConvWidth = width, postConvHeight = height; + GLint texelBytes, sizeInBytes; + + if (ctx->_ImageTransferState & IMAGE_CONVOLUTION_BIT) { + _mesa_adjust_image_for_convolution(ctx, 2, &postConvWidth, + &postConvHeight); + } + + /* choose the texture format */ + assert(ctx->Driver.ChooseTextureFormat); + texImage->TexFormat = (*ctx->Driver.ChooseTextureFormat)(ctx, + internalFormat, format, type); + assert(texImage->TexFormat); + texImage->FetchTexel = texImage->TexFormat->FetchTexel2D; + + texelBytes = texImage->TexFormat->TexelBytes; + + /* Compute image size, in bytes */ + if (texImage->IsCompressed) { + assert(ctx->Driver.CompressedTextureSize); + sizeInBytes = ctx->Driver.CompressedTextureSize(ctx, texImage); + assert(sizeInBytes > 0); + texImage->CompressedSize = sizeInBytes; + } + else { + sizeInBytes = postConvWidth * postConvHeight * texelBytes; + } + + /* allocate memory */ + texImage->Data = MALLOC(sizeInBytes); + if (!texImage->Data) { + _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage2D"); + return; + } + + /* unpack image, apply transfer ops and store in texImage->Data */ + _mesa_transfer_teximage(ctx, 2, _mesa_base_tex_format(ctx, internalFormat), + texImage->TexFormat, texImage->Data, + width, height, 1, 0, 0, 0, + texImage->Width * texelBytes, + 0, /* dstImageStride */ + format, type, pixels, packing); + + /* GL_SGIS_generate_mipmap */ + if (level == texObj->BaseLevel && texObj->GenerateMipmap) { + _mesa_generate_mipmap(ctx, &ctx->Texture.Unit[ctx->Texture.CurrentUnit], + texObj); + } +} + + + +/* + * This is the software fallback for Driver.TexImage3D(). + * The texture image type will be GLchan. + * The texture image format will be GL_COLOR_INDEX, GL_INTENSITY, + * GL_LUMINANCE, GL_LUMINANCE_ALPHA, GL_ALPHA, GL_RGB or GL_RGBA. + * + */ +void +_mesa_store_teximage3d(GLcontext *ctx, GLenum target, GLint level, + GLint internalFormat, + GLint width, GLint height, GLint depth, GLint border, + GLenum format, GLenum type, const void *pixels, + const struct gl_pixelstore_attrib *packing, + struct gl_texture_object *texObj, + struct gl_texture_image *texImage) +{ + GLint texelBytes, sizeInBytes; + + /* choose the texture format */ + assert(ctx->Driver.ChooseTextureFormat); + texImage->TexFormat = (*ctx->Driver.ChooseTextureFormat)(ctx, + internalFormat, format, type); + assert(texImage->TexFormat); + texImage->FetchTexel = texImage->TexFormat->FetchTexel3D; + + texelBytes = texImage->TexFormat->TexelBytes; + + /* Compute image size, in bytes */ + if (texImage->IsCompressed) { + assert(ctx->Driver.CompressedTextureSize); + sizeInBytes = ctx->Driver.CompressedTextureSize(ctx, texImage); + assert(sizeInBytes > 0); + texImage->CompressedSize = sizeInBytes; + } + else { + sizeInBytes = width * height * depth * texelBytes; + } + + /* allocate memory */ + texImage->Data = MALLOC(sizeInBytes); + if (!texImage->Data) { + _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage3D"); + return; + } + + /* unpack image, apply transfer ops and store in texImage->Data */ + _mesa_transfer_teximage(ctx, 3, _mesa_base_tex_format(ctx, internalFormat), + texImage->TexFormat, texImage->Data, + width, height, depth, 0, 0, 0, + texImage->Width * texelBytes, + texImage->Width * texImage->Height * texelBytes, + format, type, pixels, packing); + + /* GL_SGIS_generate_mipmap */ + if (level == texObj->BaseLevel && texObj->GenerateMipmap) { + _mesa_generate_mipmap(ctx, &ctx->Texture.Unit[ctx->Texture.CurrentUnit], + texObj); + } +} + + + + +/* + * This is the software fallback for Driver.TexSubImage1D(). + */ +void +_mesa_store_texsubimage1d(GLcontext *ctx, GLenum target, GLint level, + GLint xoffset, GLint width, + GLenum format, GLenum type, const void *pixels, + const struct gl_pixelstore_attrib *packing, + struct gl_texture_object *texObj, + struct gl_texture_image *texImage) +{ + _mesa_transfer_teximage(ctx, 1, + _mesa_base_tex_format(ctx, texImage->IntFormat), + texImage->TexFormat, texImage->Data, + width, 1, 1, /* src size */ + xoffset, 0, 0, /* dest offsets */ + 0, /* dstRowStride */ + 0, /* dstImageStride */ + format, type, pixels, packing); + + /* GL_SGIS_generate_mipmap */ + if (level == texObj->BaseLevel && texObj->GenerateMipmap) { + _mesa_generate_mipmap(ctx, &ctx->Texture.Unit[ctx->Texture.CurrentUnit], + texObj); + } +} + + +/* + * This is the software fallback for Driver.TexSubImage2D(). + */ +void +_mesa_store_texsubimage2d(GLcontext *ctx, GLenum target, GLint level, + GLint xoffset, GLint yoffset, + GLint width, GLint height, + GLenum format, GLenum type, const void *pixels, + const struct gl_pixelstore_attrib *packing, + struct gl_texture_object *texObj, + struct gl_texture_image *texImage) +{ + _mesa_transfer_teximage(ctx, 2, + _mesa_base_tex_format(ctx, texImage->IntFormat), + texImage->TexFormat, texImage->Data, + width, height, 1, /* src size */ + xoffset, yoffset, 0, /* dest offsets */ + texImage->Width * texImage->TexFormat->TexelBytes, + 0, /* dstImageStride */ + format, type, pixels, packing); + + /* GL_SGIS_generate_mipmap */ + if (level == texObj->BaseLevel && texObj->GenerateMipmap) { + _mesa_generate_mipmap(ctx, &ctx->Texture.Unit[ctx->Texture.CurrentUnit], + texObj); + } +} + + +/* + * This is the software fallback for Driver.TexSubImage3D(). + */ +void +_mesa_store_texsubimage3d(GLcontext *ctx, GLenum target, GLint level, + GLint xoffset, GLint yoffset, GLint zoffset, + GLint width, GLint height, GLint depth, + GLenum format, GLenum type, const void *pixels, + const struct gl_pixelstore_attrib *packing, + struct gl_texture_object *texObj, + struct gl_texture_image *texImage) +{ + const GLint texelBytes = texImage->TexFormat->TexelBytes; + _mesa_transfer_teximage(ctx, 3, + _mesa_base_tex_format(ctx, texImage->IntFormat), + texImage->TexFormat, texImage->Data, + width, height, depth, /* src size */ + xoffset, yoffset, xoffset, /* dest offsets */ + texImage->Width * texelBytes, + texImage->Width * texImage->Height * texelBytes, + format, type, pixels, packing); + /* GL_SGIS_generate_mipmap */ + if (level == texObj->BaseLevel && texObj->GenerateMipmap) { + _mesa_generate_mipmap(ctx, &ctx->Texture.Unit[ctx->Texture.CurrentUnit], + texObj); + } +} + + + + +/* + * Fallback for Driver.CompressedTexImage1D() + */ +void +_mesa_store_compressed_teximage1d(GLcontext *ctx, GLenum target, GLint level, + GLint internalFormat, + GLint width, GLint border, + GLsizei imageSize, const GLvoid *data, + struct gl_texture_object *texObj, + struct gl_texture_image *texImage) +{ + /* Nothing here. + * The device driver has to do it all. + */ +} + + + +/* + * Fallback for Driver.CompressedTexImage2D() + */ +void +_mesa_store_compressed_teximage2d(GLcontext *ctx, GLenum target, GLint level, + GLint internalFormat, + GLint width, GLint height, GLint border, + GLsizei imageSize, const GLvoid *data, + struct gl_texture_object *texObj, + struct gl_texture_image *texImage) +{ + /* Nothing here. + * The device driver has to do it all. + */ +} + + + +/* + * Fallback for Driver.CompressedTexImage3D() + */ +void +_mesa_store_compressed_teximage3d(GLcontext *ctx, GLenum target, GLint level, + GLint internalFormat, + GLint width, GLint height, GLint depth, + GLint border, + GLsizei imageSize, const GLvoid *data, + struct gl_texture_object *texObj, + struct gl_texture_image *texImage) +{ + /* Nothing here. + * The device driver has to do it all. + */ +} + + + +/* + * Fallback for Driver.GetCompressedTexImage3D() + * This will probably work find for hardware drivers. That is, hardware + * drivers won't have to override this function, unless the compressed + * texture must first be fetched from the TRAM. + */ +void +_mesa_get_compressed_teximage(GLcontext *ctx, GLenum target, + GLint level, void *image, + const struct gl_texture_object *texObj, + struct gl_texture_image *texImage) +{ + assert(texImage->IsCompressed); + assert(texImage->CompressedSize > 0); + MEMCPY(image, texImage->Data, texImage->CompressedSize); +} + + + +/* + * This is the fallback for Driver.TestProxyTexImage(). + */ +GLboolean +_mesa_test_proxy_teximage(GLcontext *ctx, GLenum target, GLint level, + GLint internalFormat, GLenum format, GLenum type, + GLint width, GLint height, GLint depth, GLint border) +{ + struct gl_texture_unit *texUnit; + struct gl_texture_object *texObj; + struct gl_texture_image *texImage; + + (void) format; + (void) type; + + texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit]; + texObj = _mesa_select_tex_object(ctx, texUnit, target); + texImage = _mesa_select_tex_image(ctx, texUnit, target, level); + + /* We always pass. + * The core Mesa code will have already tested the image size, etc. + * If a driver has more stringent texture limits to enforce it will + * have to override this function. + */ + /* choose the texture format */ + assert(ctx->Driver.ChooseTextureFormat); + texImage->TexFormat = (*ctx->Driver.ChooseTextureFormat)(ctx, + internalFormat, format, type); + assert(texImage->TexFormat); + + return GL_TRUE; +} + + + +/* + * Average together two rows of a source image to produce a single new + * row in the dest image. It's legal for the two source rows to point + * to the same data. The source width must be equal to either the + * dest width or two times the dest width. + */ +static void +do_row(const struct gl_texture_format *format, GLint srcWidth, + const GLvoid *srcRowA, const GLvoid *srcRowB, + GLint dstWidth, GLvoid *dstRow) +{ + const GLuint k0 = (srcWidth == dstWidth) ? 0 : 1; + const GLuint colStride = (srcWidth == dstWidth) ? 1 : 2; + + assert(srcWidth == dstWidth || srcWidth == 2 * dstWidth); + + switch (format->MesaFormat) { + case MESA_FORMAT_RGBA: + { + GLuint i, j, k; + const GLchan (*rowA)[4] = (const GLchan (*)[4]) srcRowA; + const GLchan (*rowB)[4] = (const GLchan (*)[4]) srcRowB; + GLchan (*dst)[4] = (GLchan (*)[4]) dstRow; + for (i = j = 0, k = k0; i < dstWidth; + i++, j += colStride, k += colStride) { + dst[i][0] = (rowA[j][0] + rowA[k][0] + + rowB[j][0] + rowB[k][0]) >> 2; + dst[i][1] = (rowA[j][1] + rowA[k][1] + + rowB[j][1] + rowB[k][1]) >> 2; + dst[i][2] = (rowA[j][2] + rowA[k][2] + + rowB[j][2] + rowB[k][2]) >> 2; + dst[i][3] = (rowA[j][3] + rowA[k][3] + + rowB[j][3] + rowB[k][3]) >> 2; + } + } + return; + case MESA_FORMAT_RGB: + { + GLuint i, j, k; + const GLchan (*rowA)[3] = (const GLchan (*)[3]) srcRowA; + const GLchan (*rowB)[3] = (const GLchan (*)[3]) srcRowB; + GLchan (*dst)[3] = (GLchan (*)[3]) dstRow; + for (i = j = 0, k = k0; i < dstWidth; + i++, j += colStride, k += colStride) { + dst[i][0] = (rowA[j][0] + rowA[k][0] + + rowB[j][0] + rowB[k][0]) >> 2; + dst[i][1] = (rowA[j][1] + rowA[k][1] + + rowB[j][1] + rowB[k][1]) >> 2; + dst[i][2] = (rowA[j][2] + rowA[k][2] + + rowB[j][2] + rowB[k][2]) >> 2; + } + } + return; + case MESA_FORMAT_ALPHA: + case MESA_FORMAT_LUMINANCE: + case MESA_FORMAT_INTENSITY: + case MESA_FORMAT_COLOR_INDEX: + { + GLuint i, j, k; + const GLchan *rowA = (const GLchan *) srcRowA; + const GLchan *rowB = (const GLchan *) srcRowB; + GLchan *dst = (GLchan *) dstRow; + for (i = j = 0, k = k0; i < dstWidth; + i++, j += colStride, k += colStride) { + dst[i] = (rowA[j] + rowA[k] + rowB[j] + rowB[k]) >> 2; + } + } + return; + case MESA_FORMAT_LUMINANCE_ALPHA: + { + GLuint i, j, k; + const GLchan (*rowA)[2] = (const GLchan (*)[2]) srcRowA; + const GLchan (*rowB)[2] = (const GLchan (*)[2]) srcRowB; + GLchan (*dst)[2] = (GLchan (*)[2]) dstRow; + for (i = j = 0, k = k0; i < dstWidth; + i++, j += colStride, k += colStride) { + dst[i][0] = (rowA[j][0] + rowA[k][0] + + rowB[j][0] + rowB[k][0]) >> 2; + dst[i][1] = (rowA[j][1] + rowA[k][1] + + rowB[j][1] + rowB[k][1]) >> 2; + } + } + return; + case MESA_FORMAT_DEPTH_COMPONENT: + { + GLuint i, j, k; + const GLfloat *rowA = (const GLfloat *) srcRowA; + const GLfloat *rowB = (const GLfloat *) srcRowB; + GLfloat *dst = (GLfloat *) dstRow; + for (i = j = 0, k = k0; i < dstWidth; + i++, j += colStride, k += colStride) { + dst[i] = (rowA[j] + rowA[k] + rowB[j] + rowB[k]) * 0.25F; + } + } + return; + /* Begin hardware formats */ + case MESA_FORMAT_RGBA8888: + case MESA_FORMAT_ARGB8888: + { + GLuint i, j, k; + const GLubyte (*rowA)[4] = (const GLubyte (*)[4]) srcRowA; + const GLubyte (*rowB)[4] = (const GLubyte (*)[4]) srcRowB; + GLubyte (*dst)[4] = (GLubyte (*)[4]) dstRow; + for (i = j = 0, k = k0; i < dstWidth; + i++, j += colStride, k += colStride) { + dst[i][0] = (rowA[j][0] + rowA[k][0] + + rowB[j][0] + rowB[k][0]) >> 2; + dst[i][1] = (rowA[j][1] + rowA[k][1] + + rowB[j][1] + rowB[k][1]) >> 2; + dst[i][2] = (rowA[j][2] + rowA[k][2] + + rowB[j][2] + rowB[k][2]) >> 2; + dst[i][3] = (rowA[j][3] + rowA[k][3] + + rowB[j][3] + rowB[k][3]) >> 2; + } + } + return; + case MESA_FORMAT_RGB888: + { + GLuint i, j, k; + const GLubyte (*rowA)[3] = (const GLubyte (*)[3]) srcRowA; + const GLubyte (*rowB)[3] = (const GLubyte (*)[3]) srcRowB; + GLubyte (*dst)[3] = (GLubyte (*)[3]) dstRow; + for (i = j = 0, k = k0; i < dstWidth; + i++, j += colStride, k += colStride) { + dst[i][0] = (rowA[j][0] + rowA[k][0] + + rowB[j][0] + rowB[k][0]) >> 2; + dst[i][1] = (rowA[j][1] + rowA[k][1] + + rowB[j][1] + rowB[k][1]) >> 2; + dst[i][2] = (rowA[j][2] + rowA[k][2] + + rowB[j][2] + rowB[k][2]) >> 2; + } + } + return; + case MESA_FORMAT_RGB565: + { + GLuint i, j, k; + const GLushort *rowA = (const GLushort *) srcRowA; + const GLushort *rowB = (const GLushort *) srcRowB; + GLushort *dst = (GLushort *) dstRow; + for (i = j = 0, k = k0; i < dstWidth; + i++, j += colStride, k += colStride) { + const GLint rowAr0 = rowA[j] & 0x1f; + const GLint rowAr1 = rowA[k] & 0x1f; + const GLint rowBr0 = rowB[j] & 0x1f; + const GLint rowBr1 = rowB[k] & 0x1f; + const GLint rowAg0 = (rowA[j] >> 5) & 0x3f; + const GLint rowAg1 = (rowA[k] >> 5) & 0x3f; + const GLint rowBg0 = (rowB[j] >> 5) & 0x3f; + const GLint rowBg1 = (rowB[k] >> 5) & 0x3f; + const GLint rowAb0 = (rowA[j] >> 11) & 0x1f; + const GLint rowAb1 = (rowA[k] >> 11) & 0x1f; + const GLint rowBb0 = (rowB[j] >> 11) & 0x1f; + const GLint rowBb1 = (rowB[k] >> 11) & 0x1f; + const GLint red = (rowAr0 + rowAr1 + rowBr0 + rowBr1) >> 4; + const GLint green = (rowAg0 + rowAg1 + rowBg0 + rowBg1) >> 4; + const GLint blue = (rowAb0 + rowAb1 + rowBb0 + rowBb1) >> 4; + dst[i] = (blue << 11) | (green << 5) | red; + } + } + return; + case MESA_FORMAT_ARGB4444: + { + GLuint i, j, k; + const GLushort *rowA = (const GLushort *) srcRowA; + const GLushort *rowB = (const GLushort *) srcRowB; + GLushort *dst = (GLushort *) dstRow; + for (i = j = 0, k = k0; i < dstWidth; + i++, j += colStride, k += colStride) { + const GLint rowAr0 = rowA[j] & 0xf; + const GLint rowAr1 = rowA[k] & 0xf; + const GLint rowBr0 = rowB[j] & 0xf; + const GLint rowBr1 = rowB[k] & 0xf; + const GLint rowAg0 = (rowA[j] >> 4) & 0xf; + const GLint rowAg1 = (rowA[k] >> 4) & 0xf; + const GLint rowBg0 = (rowB[j] >> 4) & 0xf; + const GLint rowBg1 = (rowB[k] >> 4) & 0xf; + const GLint rowAb0 = (rowA[j] >> 8) & 0xf; + const GLint rowAb1 = (rowA[k] >> 8) & 0xf; + const GLint rowBb0 = (rowB[j] >> 8) & 0xf; + const GLint rowBb1 = (rowB[k] >> 8) & 0xf; + const GLint rowAa0 = (rowA[j] >> 12) & 0xf; + const GLint rowAa1 = (rowA[k] >> 12) & 0xf; + const GLint rowBa0 = (rowB[j] >> 12) & 0xf; + const GLint rowBa1 = (rowB[k] >> 12) & 0xf; + const GLint red = (rowAr0 + rowAr1 + rowBr0 + rowBr1) >> 4; + const GLint green = (rowAg0 + rowAg1 + rowBg0 + rowBg1) >> 4; + const GLint blue = (rowAb0 + rowAb1 + rowBb0 + rowBb1) >> 4; + const GLint alpha = (rowAa0 + rowAa1 + rowBa0 + rowBa1) >> 4; + dst[i] = (alpha << 12) | (blue << 8) | (green << 4) | red; + } + } + return; + case MESA_FORMAT_ARGB1555: + { + GLuint i, j, k; + const GLushort *rowA = (const GLushort *) srcRowA; + const GLushort *rowB = (const GLushort *) srcRowB; + GLushort *dst = (GLushort *) dstRow; + for (i = j = 0, k = k0; i < dstWidth; + i++, j += colStride, k += colStride) { + const GLint rowAr0 = rowA[j] & 0x1f; + const GLint rowAr1 = rowA[k] & 0x1f; + const GLint rowBr0 = rowB[j] & 0x1f; + const GLint rowBr1 = rowB[k] & 0xf; + const GLint rowAg0 = (rowA[j] >> 5) & 0x1f; + const GLint rowAg1 = (rowA[k] >> 5) & 0x1f; + const GLint rowBg0 = (rowB[j] >> 5) & 0x1f; + const GLint rowBg1 = (rowB[k] >> 5) & 0x1f; + const GLint rowAb0 = (rowA[j] >> 10) & 0x1f; + const GLint rowAb1 = (rowA[k] >> 10) & 0x1f; + const GLint rowBb0 = (rowB[j] >> 10) & 0x1f; + const GLint rowBb1 = (rowB[k] >> 10) & 0x1f; + const GLint rowAa0 = (rowA[j] >> 15) & 0x1; + const GLint rowAa1 = (rowA[k] >> 15) & 0x1; + const GLint rowBa0 = (rowB[j] >> 15) & 0x1; + const GLint rowBa1 = (rowB[k] >> 15) & 0x1; + const GLint red = (rowAr0 + rowAr1 + rowBr0 + rowBr1) >> 4; + const GLint green = (rowAg0 + rowAg1 + rowBg0 + rowBg1) >> 4; + const GLint blue = (rowAb0 + rowAb1 + rowBb0 + rowBb1) >> 4; + const GLint alpha = (rowAa0 + rowAa1 + rowBa0 + rowBa1) >> 4; + dst[i] = (alpha << 15) | (blue << 10) | (green << 5) | red; + } + } + return; + case MESA_FORMAT_AL88: + { + GLuint i, j, k; + const GLubyte (*rowA)[2] = (const GLubyte (*)[2]) srcRowA; + const GLubyte (*rowB)[2] = (const GLubyte (*)[2]) srcRowB; + GLubyte (*dst)[2] = (GLubyte (*)[2]) dstRow; + for (i = j = 0, k = k0; i < dstWidth; + i++, j += colStride, k += colStride) { + dst[i][0] = (rowA[j][0] + rowA[k][0] + + rowB[j][0] + rowB[k][0]) >> 2; + dst[i][1] = (rowA[j][1] + rowA[k][1] + + rowB[j][1] + rowB[k][1]) >> 2; + } + } + return; + case MESA_FORMAT_RGB332: + { + GLuint i, j, k; + const GLubyte *rowA = (const GLubyte *) srcRowA; + const GLubyte *rowB = (const GLubyte *) srcRowB; + GLubyte *dst = (GLubyte *) dstRow; + for (i = j = 0, k = k0; i < dstWidth; + i++, j += colStride, k += colStride) { + const GLint rowAr0 = rowA[j] & 0x3; + const GLint rowAr1 = rowA[k] & 0x3; + const GLint rowBr0 = rowB[j] & 0x3; + const GLint rowBr1 = rowB[k] & 0x3; + const GLint rowAg0 = (rowA[j] >> 2) & 0x7; + const GLint rowAg1 = (rowA[k] >> 2) & 0x7; + const GLint rowBg0 = (rowB[j] >> 2) & 0x7; + const GLint rowBg1 = (rowB[k] >> 2) & 0x7; + const GLint rowAb0 = (rowA[j] >> 5) & 0x7; + const GLint rowAb1 = (rowA[k] >> 5) & 0x7; + const GLint rowBb0 = (rowB[j] >> 5) & 0x7; + const GLint rowBb1 = (rowB[k] >> 5) & 0x7; + const GLint red = (rowAr0 + rowAr1 + rowBr0 + rowBr1) >> 4; + const GLint green = (rowAg0 + rowAg1 + rowBg0 + rowBg1) >> 4; + const GLint blue = (rowAb0 + rowAb1 + rowBb0 + rowBb1) >> 4; + dst[i] = (blue << 5) | (green << 2) | red; + } + } + return; + case MESA_FORMAT_A8: + case MESA_FORMAT_L8: + case MESA_FORMAT_I8: + case MESA_FORMAT_CI8: + { + GLuint i, j, k; + const GLubyte *rowA = (const GLubyte *) srcRowA; + const GLubyte *rowB = (const GLubyte *) srcRowB; + GLubyte *dst = (GLubyte *) dstRow; + for (i = j = 0, k = k0; i < dstWidth; + i++, j += colStride, k += colStride) { + dst[i] = (rowA[j] + rowA[k] + rowB[j] + rowB[k]) >> 2; + } + } + return; + default: + _mesa_problem(NULL, "bad format in do_row()"); + } +} + + +/* + * These functions generate a 1/2-size mipmap image from a source image. + * Texture borders are handled by copying or averaging the source image's + * border texels, depending on the scale-down factor. + */ + +static void +make_1d_mipmap(const struct gl_texture_format *format, GLint border, + GLint srcWidth, const GLubyte *srcPtr, + GLint dstWidth, GLubyte *dstPtr) +{ + const GLint bpt = format->TexelBytes; + const GLubyte *src; + GLubyte *dst; + + /* skip the border pixel, if any */ + src = srcPtr + border * bpt; + dst = dstPtr + border * bpt; + + /* we just duplicate the input row, kind of hack, saves code */ + do_row(format, srcWidth - 2 * border, src, src, + dstWidth - 2 * border, dst); + + if (border) { + /* copy left-most pixel from source */ + MEMCPY(dstPtr, srcPtr, bpt); + /* copy right-most pixel from source */ + MEMCPY(dstPtr + (dstWidth - 1) * bpt, + srcPtr + (srcWidth - 1) * bpt, + bpt); + } +} + + +static void +make_2d_mipmap(const struct gl_texture_format *format, GLint border, + GLint srcWidth, GLint srcHeight, const GLubyte *srcPtr, + GLint dstWidth, GLint dstHeight, GLubyte *dstPtr) +{ + const GLint bpt = format->TexelBytes; + const GLint srcWidthNB = srcWidth - 2 * border; /* sizes w/out border */ + const GLint dstWidthNB = dstWidth - 2 * border; + const GLint dstHeightNB = dstHeight - 2 * border; + const GLint srcRowStride = bpt * srcWidth; + const GLint dstRowStride = bpt * dstWidth; + const GLubyte *srcA, *srcB; + GLubyte *dst; + GLint row, colStride; + + colStride = (srcWidth == dstWidth) ? 1 : 2; + + /* Compute src and dst pointers, skipping any border */ + srcA = srcPtr + border * ((srcWidth + 1) * bpt); + if (srcHeight > 1) + srcB = srcA + srcRowStride; + else + srcB = srcA; + dst = dstPtr + border * ((dstWidth + 1) * bpt); + + for (row = 0; row < dstHeightNB; row++) { + do_row(format, srcWidthNB, srcA, srcB, + dstWidthNB, dst); + srcA += 2 * srcRowStride; + srcB += 2 * srcRowStride; + dst += dstRowStride; + } + + /* This is ugly but probably won't be used much */ + if (border > 0) { + /* fill in dest border */ + /* lower-left border pixel */ + MEMCPY(dstPtr, srcPtr, bpt); + /* lower-right border pixel */ + MEMCPY(dstPtr + (dstWidth - 1) * bpt, + srcPtr + (srcWidth - 1) * bpt, bpt); + /* upper-left border pixel */ + MEMCPY(dstPtr + dstWidth * (dstHeight - 1) * bpt, + srcPtr + srcWidth * (srcHeight - 1) * bpt, bpt); + /* upper-right border pixel */ + MEMCPY(dstPtr + (dstWidth * dstHeight - 1) * bpt, + srcPtr + (srcWidth * srcHeight - 1) * bpt, bpt); + /* lower border */ + do_row(format, srcWidthNB, + srcPtr + bpt, + srcPtr + bpt, + dstWidthNB, dstPtr + bpt); + /* upper border */ + do_row(format, srcWidthNB, + srcPtr + (srcWidth * (srcHeight - 1) + 1) * bpt, + srcPtr + (srcWidth * (srcHeight - 1) + 1) * bpt, + dstWidthNB, + dstPtr + (dstWidth * (dstHeight - 1) + 1) * bpt); + /* left and right borders */ + if (srcHeight == dstHeight) { + /* copy border pixel from src to dst */ + for (row = 1; row < srcHeight; row++) { + MEMCPY(dstPtr + dstWidth * row * bpt, + srcPtr + srcWidth * row * bpt, bpt); + MEMCPY(dstPtr + (dstWidth * row + dstWidth - 1) * bpt, + srcPtr + (srcWidth * row + srcWidth - 1) * bpt, bpt); + } + } + else { + /* average two src pixels each dest pixel */ + for (row = 0; row < dstHeightNB; row += 2) { + do_row(format, 1, + srcPtr + (srcWidth * (row * 2 + 1)) * bpt, + srcPtr + (srcWidth * (row * 2 + 2)) * bpt, + 1, dstPtr + (dstWidth * row + 1) * bpt); + do_row(format, 1, + srcPtr + (srcWidth * (row * 2 + 1) + srcWidth - 1) * bpt, + srcPtr + (srcWidth * (row * 2 + 2) + srcWidth - 1) * bpt, + 1, dstPtr + (dstWidth * row + 1 + dstWidth - 1) * bpt); + } + } + } +} + + +static void +make_3d_mipmap(const struct gl_texture_format *format, GLint border, + GLint srcWidth, GLint srcHeight, GLint srcDepth, + const GLubyte *srcPtr, + GLint dstWidth, GLint dstHeight, GLint dstDepth, + GLubyte *dstPtr) +{ + const GLint bpt = format->TexelBytes; + const GLint srcWidthNB = srcWidth - 2 * border; /* sizes w/out border */ +#ifdef DEBUG + const GLint srcDepthNB = srcDepth - 2 * border; +#endif + const GLint dstWidthNB = dstWidth - 2 * border; + const GLint dstHeightNB = dstHeight - 2 * border; + const GLint dstDepthNB = dstDepth - 2 * border; + GLvoid *tmpRowA, *tmpRowB; + GLint img, row; + GLint bytesPerSrcImage, bytesPerDstImage; + GLint bytesPerSrcRow, bytesPerDstRow; + GLint srcImageOffset, srcRowOffset; + + /* Need two temporary row buffers */ + tmpRowA = MALLOC(srcWidth * bpt); + if (!tmpRowA) + return; + tmpRowB = MALLOC(srcWidth * bpt); + if (!tmpRowB) { + FREE(tmpRowA); + return; + } + + bytesPerSrcImage = srcWidth * srcHeight * bpt; + bytesPerDstImage = dstWidth * dstHeight * bpt; + + bytesPerSrcRow = srcWidth * bpt; + bytesPerDstRow = dstWidth * bpt; + + /* Offset between adjacent src images to be averaged together */ + srcImageOffset = (srcDepth == dstDepth) ? 0 : bytesPerSrcImage; + + /* Offset between adjacent src rows to be averaged together */ + srcRowOffset = (srcHeight == dstHeight) ? 0 : srcWidth * bpt; + + /* + * Need to average together up to 8 src pixels for each dest pixel. + * Break that down into 3 operations: + * 1. take two rows from source image and average them together. + * 2. take two rows from next source image and average them together. + * 3. take the two averaged rows and average them for the final dst row. + */ + + /* + printf("mip3d %d x %d x %d -> %d x %d x %d\n", + srcWidth, srcHeight, srcDepth, dstWidth, dstHeight, dstDepth); + */ + + for (img = 0; img < dstDepthNB; img++) { + /* first source image pointer, skipping border */ + const GLubyte *imgSrcA = srcPtr + + (bytesPerSrcImage + bytesPerSrcRow + border) * bpt * border + + img * (bytesPerSrcImage + srcImageOffset); + /* second source image pointer, skipping border */ + const GLubyte *imgSrcB = imgSrcA + srcImageOffset; + /* address of the dest image, skipping border */ + GLubyte *imgDst = dstPtr + + (bytesPerDstImage + bytesPerDstRow + border) * bpt * border + + img * bytesPerDstImage; + + /* setup the four source row pointers and the dest row pointer */ + const GLubyte *srcImgARowA = imgSrcA; + const GLubyte *srcImgARowB = imgSrcA + srcRowOffset; + const GLubyte *srcImgBRowA = imgSrcB; + const GLubyte *srcImgBRowB = imgSrcB + srcRowOffset; + GLubyte *dstImgRow = imgDst; + + for (row = 0; row < dstHeightNB; row++) { + /* Average together two rows from first src image */ + do_row(format, srcWidthNB, srcImgARowA, srcImgARowB, + srcWidthNB, tmpRowA); + /* Average together two rows from second src image */ + do_row(format, srcWidthNB, srcImgBRowA, srcImgBRowB, + srcWidthNB, tmpRowB); + /* Average together the temp rows to make the final row */ + do_row(format, srcWidthNB, tmpRowA, tmpRowB, + dstWidthNB, dstImgRow); + /* advance to next rows */ + srcImgARowA += bytesPerSrcRow + srcRowOffset; + srcImgARowB += bytesPerSrcRow + srcRowOffset; + srcImgBRowA += bytesPerSrcRow + srcRowOffset; + srcImgBRowB += bytesPerSrcRow + srcRowOffset; + dstImgRow += bytesPerDstRow; + } + } + + FREE(tmpRowA); + FREE(tmpRowB); + + /* Luckily we can leverage the make_2d_mipmap() function here! */ + if (border > 0) { + /* do front border image */ + make_2d_mipmap(format, 1, srcWidth, srcHeight, srcPtr, + dstWidth, dstHeight, dstPtr); + /* do back border image */ + make_2d_mipmap(format, 1, srcWidth, srcHeight, + srcPtr + bytesPerSrcImage * (srcDepth - 1), + dstWidth, dstHeight, + dstPtr + bytesPerDstImage * (dstDepth - 1)); + /* do four remaining border edges that span the image slices */ + if (srcDepth == dstDepth) { + /* just copy border pixels from src to dst */ + for (img = 0; img < dstDepthNB; img++) { + const GLubyte *src; + GLubyte *dst; + + /* do border along [img][row=0][col=0] */ + src = srcPtr + (img + 1) * bytesPerSrcImage; + dst = dstPtr + (img + 1) * bytesPerDstImage; + MEMCPY(dst, src, bpt); + + /* do border along [img][row=dstHeight-1][col=0] */ + src = srcPtr + (img * 2 + 1) * bytesPerSrcImage + + (srcHeight - 1) * bytesPerSrcRow; + dst = dstPtr + (img + 1) * bytesPerDstImage + + (dstHeight - 1) * bytesPerDstRow; + MEMCPY(dst, src, bpt); + + /* do border along [img][row=0][col=dstWidth-1] */ + src = srcPtr + (img * 2 + 1) * bytesPerSrcImage + + (srcWidth - 1) * bpt; + dst = dstPtr + (img + 1) * bytesPerDstImage + + (dstWidth - 1) * bpt; + MEMCPY(dst, src, bpt); + + /* do border along [img][row=dstHeight-1][col=dstWidth-1] */ + src = srcPtr + (img * 2 + 1) * bytesPerSrcImage + + (bytesPerSrcImage - bpt); + dst = dstPtr + (img + 1) * bytesPerDstImage + + (bytesPerDstImage - bpt); + MEMCPY(dst, src, bpt); + } + } + else { + /* average border pixels from adjacent src image pairs */ + ASSERT(srcDepthNB == 2 * dstDepthNB); + for (img = 0; img < dstDepthNB; img++) { + const GLubyte *src; + GLubyte *dst; + + /* do border along [img][row=0][col=0] */ + src = srcPtr + (img * 2 + 1) * bytesPerSrcImage; + dst = dstPtr + (img + 1) * bytesPerDstImage; + do_row(format, 1, src, src + srcImageOffset, 1, dst); + + /* do border along [img][row=dstHeight-1][col=0] */ + src = srcPtr + (img * 2 + 1) * bytesPerSrcImage + + (srcHeight - 1) * bytesPerSrcRow; + dst = dstPtr + (img + 1) * bytesPerDstImage + + (dstHeight - 1) * bytesPerDstRow; + do_row(format, 1, src, src + srcImageOffset, 1, dst); + + /* do border along [img][row=0][col=dstWidth-1] */ + src = srcPtr + (img * 2 + 1) * bytesPerSrcImage + + (srcWidth - 1) * bpt; + dst = dstPtr + (img + 1) * bytesPerDstImage + + (dstWidth - 1) * bpt; + do_row(format, 1, src, src + srcImageOffset, 1, dst); + + /* do border along [img][row=dstHeight-1][col=dstWidth-1] */ + src = srcPtr + (img * 2 + 1) * bytesPerSrcImage + + (bytesPerSrcImage - bpt); + dst = dstPtr + (img + 1) * bytesPerDstImage + + (bytesPerDstImage - bpt); + do_row(format, 1, src, src + srcImageOffset, 1, dst); + } + } + } +} + + +/* + * For GL_SGIX_generate_mipmap: + * Generate a complete set of mipmaps from texObj's base-level image. + * Stop at texObj's MaxLevel or when we get to the 1x1 texture. + */ +void +_mesa_generate_mipmap(GLcontext *ctx, + const struct gl_texture_unit *texUnit, + struct gl_texture_object *texObj) +{ + const GLenum targets1D[] = { GL_TEXTURE_1D, 0 }; + const GLenum targets2D[] = { GL_TEXTURE_2D, 0 }; + const GLenum targets3D[] = { GL_TEXTURE_3D, 0 }; + const GLenum targetsCube[] = { GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB, + GL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB, + GL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB, + GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_ARB, + GL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB, + GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB, + 0 }; + const GLenum *targets; + GLuint level; + GLint maxLevels = 0; + + ASSERT(texObj); + ASSERT(texObj->Image[texObj->BaseLevel]); + + switch (texObj->Dimensions) { + case 1: + targets = targets1D; + maxLevels = ctx->Const.MaxTextureLevels; + break; + case 2: + targets = targets2D; + maxLevels = ctx->Const.MaxTextureLevels; + break; + case 3: + targets = targets3D; + maxLevels = ctx->Const.Max3DTextureLevels; + break; + case 6: + targets = targetsCube; + maxLevels = ctx->Const.MaxCubeTextureLevels; + break; + default: + _mesa_problem(ctx, + "Bad texture object dimension in _mesa_generate_mipmaps"); + return; + } + + for (level = texObj->BaseLevel; level < texObj->MaxLevel + && level < maxLevels - 1; level++) { + /* generate image[level+1] from image[level] */ + const struct gl_texture_image *srcImage; + struct gl_texture_image *dstImage; + GLint srcWidth, srcHeight, srcDepth; + GLint dstWidth, dstHeight, dstDepth; + GLint border, bytesPerTexel; + GLint t; + + srcImage = texObj->Image[level]; + ASSERT(srcImage); + srcWidth = srcImage->Width; + srcHeight = srcImage->Height; + srcDepth = srcImage->Depth; + border = srcImage->Border; + bytesPerTexel = srcImage->TexFormat->TexelBytes; + + /* compute next (level+1) image size */ + if (srcWidth - 2 * border > 1) { + dstWidth = (srcWidth - 2 * border) / 2 + 2 * border; + } + else { + dstWidth = srcWidth; /* can't go smaller */ + } + if (srcHeight - 2 * border > 1) { + dstHeight = (srcHeight - 2 * border) / 2 + 2 * border; + } + else { + dstHeight = srcHeight; /* can't go smaller */ + } + if (srcDepth - 2 * border > 1) { + dstDepth = (srcDepth - 2 * border) / 2 + 2 * border; + } + else { + dstDepth = srcDepth; /* can't go smaller */ + } + + if (dstWidth == srcWidth && + dstHeight == srcHeight && + dstDepth == srcDepth) { + /* all done */ + return; + } + + /* Need this loop just because of cubemaps */ + for (t = 0; targets[t]; t++) { + ASSERT(t < 6); + + dstImage = _mesa_select_tex_image(ctx, texUnit, targets[t], level+1); + if (!dstImage) { + dstImage = _mesa_alloc_texture_image(); + if (!dstImage) { + _mesa_error(ctx, GL_OUT_OF_MEMORY, "generating mipmaps"); + return; + } + _mesa_set_tex_image(texObj, targets[t], level + 1, dstImage); + } + + /* Free old image data */ + if (dstImage->Data) + FREE(dstImage->Data); + + /* initialize new image */ + _mesa_init_teximage_fields(ctx, dstImage, dstWidth, dstHeight, + dstDepth, border, srcImage->Format); + dstImage->DriverData = NULL; + dstImage->TexFormat = srcImage->TexFormat; + dstImage->FetchTexel = srcImage->FetchTexel; + ASSERT(dstImage->TexFormat); + ASSERT(dstImage->FetchTexel); + + ASSERT(dstWidth * dstHeight * dstDepth * bytesPerTexel > 0); + + /* alloc new image buffer */ + dstImage->Data = MALLOC(dstWidth * dstHeight * dstDepth + * bytesPerTexel); + if (!dstImage->Data) { + _mesa_error(ctx, GL_OUT_OF_MEMORY, "generating mipmaps"); + return; + } + + /* + * We use simple 2x2 averaging to compute the next mipmap level. + */ + switch (texObj->Dimensions) { + case 1: + make_1d_mipmap(srcImage->TexFormat, border, + srcWidth, (const GLubyte *) srcImage->Data, + dstWidth, (GLubyte *) dstImage->Data); + break; + case 2: + case 6: + make_2d_mipmap(srcImage->TexFormat, border, + srcWidth, srcHeight, (const GLubyte *) srcImage->Data, + dstWidth, dstHeight, (GLubyte *) dstImage->Data); + break; + case 3: + make_3d_mipmap(srcImage->TexFormat, border, + srcWidth, srcHeight, srcDepth, (const GLubyte *) srcImage->Data, + dstWidth, dstHeight, dstDepth, (GLubyte *) dstImage->Data); + break; + default: + _mesa_problem(ctx, "bad dimensions in _mesa_generate_mipmaps"); + return; + } + } /* loop over tex image targets */ + } /* loop over tex levels */ +} Index: dll/opengl/opengl32/mesa/texstore.h =================================================================== --- dll/opengl/opengl32/mesa/texstore.h (revision 0) +++ dll/opengl/opengl32/mesa/texstore.h (working copy) @@ -0,0 +1,156 @@ +/* $Id: texstore.h,v 1.9 2001/06/15 14:18:46 brianp Exp $ */ + +/* + * Mesa 3-D graphics library + * Version: 3.5 + * + * Copyright (C) 1999-2001 Brian Paul 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 + * BRIAN PAUL 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. + */ + +/* + * Authors: + * Brian Paul + */ + + +#ifndef TEXSTORE_H +#define TEXSTORE_H + + +#include "mtypes.h" + + +extern void +_mesa_transfer_teximage(GLcontext *ctx, GLuint dimensions, + GLenum baseInternalFormat, + const struct gl_texture_format *texDestFormat, + GLvoid *texDestAddr, + GLint srcWidth, GLint srcHeight, GLint srcDepth, + GLint dstXoffset, GLint dstYoffset, GLint dstZoffset, + GLint dstRowStride, GLint dstImageStride, + GLenum srcFormat, GLenum srcType, + const GLvoid *srcAddr, + const struct gl_pixelstore_attrib *srcPacking); + + +extern void +_mesa_store_teximage1d(GLcontext *ctx, GLenum target, GLint level, + GLint internalFormat, + GLint width, GLint border, + GLenum format, GLenum type, const GLvoid *pixels, + const struct gl_pixelstore_attrib *packing, + struct gl_texture_object *texObj, + struct gl_texture_image *texImage); + + +extern void +_mesa_store_teximage2d(GLcontext *ctx, GLenum target, GLint level, + GLint internalFormat, + GLint width, GLint height, GLint border, + GLenum format, GLenum type, const void *pixels, + const struct gl_pixelstore_attrib *packing, + struct gl_texture_object *texObj, + struct gl_texture_image *texImage); + + +extern void +_mesa_store_teximage3d(GLcontext *ctx, GLenum target, GLint level, + GLint internalFormat, + GLint width, GLint height, GLint depth, GLint border, + GLenum format, GLenum type, const void *pixels, + const struct gl_pixelstore_attrib *packing, + struct gl_texture_object *texObj, + struct gl_texture_image *texImage); + + +extern void +_mesa_store_texsubimage1d(GLcontext *ctx, GLenum target, GLint level, + GLint xoffset, GLint width, + GLenum format, GLenum type, const void *pixels, + const struct gl_pixelstore_attrib *packing, + struct gl_texture_object *texObj, + struct gl_texture_image *texImage); + + +extern void +_mesa_store_texsubimage2d(GLcontext *ctx, GLenum target, GLint level, + GLint xoffset, GLint yoffset, + GLint width, GLint height, + GLenum format, GLenum type, const void *pixels, + const struct gl_pixelstore_attrib *packing, + struct gl_texture_object *texObj, + struct gl_texture_image *texImage); + + +extern void +_mesa_store_texsubimage3d(GLcontext *ctx, GLenum target, GLint level, + GLint xoffset, GLint yoffset, GLint zoffset, + GLint width, GLint height, GLint depth, + GLenum format, GLenum type, const void *pixels, + const struct gl_pixelstore_attrib *packing, + struct gl_texture_object *texObj, + struct gl_texture_image *texImage); + + +extern void +_mesa_store_compressed_teximage1d(GLcontext *ctx, GLenum target, GLint level, + GLint internalFormat, + GLint width, GLint border, + GLsizei imageSize, const GLvoid *data, + struct gl_texture_object *texObj, + struct gl_texture_image *texImage); + +extern void +_mesa_store_compressed_teximage2d(GLcontext *ctx, GLenum target, GLint level, + GLint internalFormat, + GLint width, GLint height, GLint border, + GLsizei imageSize, const GLvoid *data, + struct gl_texture_object *texObj, + struct gl_texture_image *texImage); + +extern void +_mesa_store_compressed_teximage3d(GLcontext *ctx, GLenum target, GLint level, + GLint internalFormat, + GLint width, GLint height, GLint depth, + GLint border, + GLsizei imageSize, const GLvoid *data, + struct gl_texture_object *texObj, + struct gl_texture_image *texImage); + + +extern void +_mesa_get_compressed_teximage(GLcontext *ctx, GLenum target, + GLint level, void *image, + const struct gl_texture_object *texObj, + struct gl_texture_image *texImage); + + +extern GLboolean +_mesa_test_proxy_teximage(GLcontext *ctx, GLenum target, GLint level, + GLint internalFormat, GLenum format, GLenum type, + GLint width, GLint height, GLint depth, GLint border); + + +extern void +_mesa_generate_mipmap(GLcontext *ctx, + const struct gl_texture_unit *texUnit, + struct gl_texture_object *texObj); + +#endif Index: dll/opengl/opengl32/mesa/texutil.c =================================================================== --- dll/opengl/opengl32/mesa/texutil.c (revision 0) +++ dll/opengl/opengl32/mesa/texutil.c (working copy) @@ -0,0 +1,925 @@ +/* $Id: texutil.c,v 1.25 2001/06/15 15:22:08 brianp Exp $ */ + +/* + * Mesa 3-D graphics library + * Version: 3.5 + * + * Copyright (C) 1999-2001 Brian Paul 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 + * BRIAN PAUL 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. + * + * Authors: + * Gareth Hughes + */ + +#ifdef PC_HEADER +#include "all.h" +#else +#include "glheader.h" +#include "context.h" +#include "enums.h" +#include "image.h" +#include "macros.h" +#include "mem.h" +#include "mtypes.h" +#include "texformat.h" +#include "texutil.h" +#endif + +#define DEBUG_TEXUTIL 0 + + +struct gl_texture_convert { + GLint xoffset, yoffset, zoffset; /* Subimage offset */ + GLint width, height, depth; /* Subimage region */ + + GLint dstImageWidth, dstImageHeight; /* Dest image size */ + /* Needed for subimage replacement */ + GLenum format, type; /* Source (user) format and type */ + + const struct gl_pixelstore_attrib *packing; + + const GLvoid *srcImage; + GLvoid *dstImage; + + GLint index; +}; + +typedef GLboolean (*convert_func)( struct gl_texture_convert *convert ); + +#define CONVERT_STRIDE_BIT 0x1 +#define CONVERT_PACKING_BIT 0x2 + + + +/* ============================================================= + * RGBA8888 textures: + */ + +#define DST_TYPE GLuint +#define DST_TEXELS_PER_DWORD 1 + +#define CONVERT_TEXEL( dst, src ) \ + dst = PACK_COLOR_8888( src[3], src[2], src[1], src[0] ) + +#define CONVERT_DIRECT + +#define SRC_TEXEL_BYTES 4 + +#define TAG(x) x##_rgba8888_direct +#define PRESERVE_DST_TYPE +#include "texutil_tmp.h" + + +#define CONVERT_TEXEL( dst, src ) \ + dst = PACK_COLOR_8888( src[0], src[1], src[2], src[3] ) + +#define CONVERT_TEXEL_DWORD( dst, src ) CONVERT_TEXEL( dst, src ) + +#define SRC_TEXEL_BYTES 4 + +#define TAG(x) x##_abgr8888_to_rgba8888 +#define PRESERVE_DST_TYPE +#include "texutil_tmp.h" + + +#define CONVERT_TEXEL( dst, src ) \ + dst = PACK_COLOR_8888( src[0], src[1], src[2], 0xff ) + +#define CONVERT_TEXEL_DWORD( dst, src ) CONVERT_TEXEL( dst, src ) + +#define SRC_TEXEL_BYTES 3 + +#define TAG(x) x##_bgr888_to_rgba8888 +#include "texutil_tmp.h" + + +#define CONVERT_RGBA8888( name ) \ +static GLboolean \ +convert_##name##_rgba8888( struct gl_texture_convert *convert ) \ +{ \ + convert_func *tab; \ + GLint index = convert->index; \ + \ + if ( convert->format == GL_ABGR_EXT && \ + convert->type == GL_UNSIGNED_INT_8_8_8_8_REV ) \ + { \ + tab = name##_tab_rgba8888_direct; \ + } \ + else if ( convert->format == GL_RGBA && \ + ( convert->type == GL_UNSIGNED_BYTE || \ + convert->type == GL_UNSIGNED_INT_8_8_8_8 ) ) \ + { \ + tab = name##_tab_abgr8888_to_rgba8888; \ + } \ + else if ( convert->format == GL_RGB && \ + convert->type == GL_UNSIGNED_BYTE ) \ + { \ + tab = name##_tab_bgr888_to_rgba8888; \ + } \ + else \ + { \ + /* Can't handle this source format/type combination */ \ + return GL_FALSE; \ + } \ + \ + return tab[index]( convert ); \ +} + +CONVERT_RGBA8888( texsubimage2d ) +CONVERT_RGBA8888( texsubimage3d ) + + + +/* ============================================================= + * ARGB8888 textures: + */ + +#define DST_TYPE GLuint +#define DST_TEXELS_PER_DWORD 1 + +#define CONVERT_TEXEL( dst, src ) \ + dst = PACK_COLOR_8888( src[3], src[2], src[1], src[0] ) + +#define CONVERT_DIRECT + +#define SRC_TEXEL_BYTES 4 + +#define TAG(x) x##_argb8888_direct +#define PRESERVE_DST_TYPE +#include "texutil_tmp.h" + + +#define CONVERT_TEXEL( dst, src ) \ + dst = PACK_COLOR_8888( src[3], src[0], src[1], src[2] ) + +#define CONVERT_TEXEL_DWORD( dst, src ) CONVERT_TEXEL( dst, src ) + +#define SRC_TEXEL_BYTES 4 + +#define TAG(x) x##_abgr8888_to_argb8888 +#define PRESERVE_DST_TYPE +#include "texutil_tmp.h" + + +#define CONVERT_TEXEL( dst, src ) \ + dst = PACK_COLOR_8888( 0xff, src[0], src[1], src[2] ) + +#define CONVERT_TEXEL_DWORD( dst, src ) CONVERT_TEXEL( dst, src ) + +#define SRC_TEXEL_BYTES 3 + +#define TAG(x) x##_bgr888_to_argb8888 +#include "texutil_tmp.h" + + +#define CONVERT_ARGB8888( name ) \ +static GLboolean \ +convert_##name##_argb8888( struct gl_texture_convert *convert ) \ +{ \ + convert_func *tab; \ + GLint index = convert->index; \ + \ + if ( convert->format == GL_BGRA && \ + convert->type == GL_UNSIGNED_INT_8_8_8_8_REV ) \ + { \ + tab = name##_tab_argb8888_direct; \ + } \ + else if ( convert->format == GL_RGBA && \ + convert->type == GL_UNSIGNED_BYTE ) \ + { \ + tab = name##_tab_abgr8888_to_argb8888; \ + } \ + else if ( convert->format == GL_RGB && \ + convert->type == GL_UNSIGNED_BYTE ) \ + { \ + tab = name##_tab_bgr888_to_argb8888; \ + } \ + else \ + { \ + /* Can't handle this source format/type combination */ \ + return GL_FALSE; \ + } \ + \ + return tab[index]( convert ); \ +} + +CONVERT_ARGB8888( texsubimage2d ) +CONVERT_ARGB8888( texsubimage3d ) + + + +/* ============================================================= + * RGB888 textures: + */ + +static GLboolean +convert_texsubimage2d_rgb888( struct gl_texture_convert *convert ) +{ + /* This is a placeholder for now... + */ + return GL_FALSE; +} + +static GLboolean +convert_texsubimage3d_rgb888( struct gl_texture_convert *convert ) +{ + /* This is a placeholder for now... + */ + return GL_FALSE; +} + + + +/* ============================================================= + * RGB565 textures: + */ + +#define DST_TYPE GLushort +#define DST_TEXELS_PER_DWORD 2 + +#define CONVERT_TEXEL( dst, src ) \ + dst = PACK_COLOR_565( src[0], src[1], src[2] ) + +#define CONVERT_DIRECT + +#define SRC_TEXEL_BYTES 2 + +#define TAG(x) x##_rgb565_direct +#define PRESERVE_DST_TYPE +#include "texutil_tmp.h" + + +#define CONVERT_TEXEL( dst, src ) \ + dst = PACK_COLOR_565( src[0], src[1], src[2] ) + +#define CONVERT_TEXEL_DWORD( dst, src ) \ + dst = ((PACK_COLOR_565( src[0], src[1], src[2] )) | \ + (PACK_COLOR_565( src[3], src[4], src[5] ) << 16)) + +#define SRC_TEXEL_BYTES 3 + +#define TAG(x) x##_bgr888_to_rgb565 +#define PRESERVE_DST_TYPE +#include "texutil_tmp.h" + + +#define CONVERT_TEXEL( dst, src ) \ + dst = PACK_COLOR_565( src[0], src[1], src[2] ) + +#define CONVERT_TEXEL_DWORD( dst, src ) \ + dst = ((PACK_COLOR_565( src[0], src[1], src[2] )) | \ + (PACK_COLOR_565( src[4], src[5], src[6] ) << 16)) + +#define SRC_TEXEL_BYTES 4 + +#define TAG(x) x##_abgr8888_to_rgb565 +#include "texutil_tmp.h" + + +#define CONVERT_RGB565( name ) \ +static GLboolean \ +convert_##name##_rgb565( struct gl_texture_convert *convert ) \ +{ \ + convert_func *tab; \ + GLint index = convert->index; \ + \ + if ( convert->format == GL_RGB && \ + convert->type == GL_UNSIGNED_SHORT_5_6_5 ) \ + { \ + tab = name##_tab_rgb565_direct; \ + } \ + else if ( convert->format == GL_RGB && \ + convert->type == GL_UNSIGNED_BYTE ) \ + { \ + tab = name##_tab_bgr888_to_rgb565; \ + } \ + else if ( convert->format == GL_RGBA && \ + convert->type == GL_UNSIGNED_BYTE ) \ + { \ + tab = name##_tab_abgr8888_to_rgb565; \ + } \ + else \ + { \ + /* Can't handle this source format/type combination */ \ + return GL_FALSE; \ + } \ + \ + return tab[index]( convert ); \ +} + +CONVERT_RGB565( texsubimage2d ) +CONVERT_RGB565( texsubimage3d ) + + + +/* ============================================================= + * ARGB4444 textures: + */ + +#define DST_TYPE GLushort +#define DST_TEXELS_PER_DWORD 2 + +#define CONVERT_TEXEL( dst, src ) \ + dst = PACK_COLOR_4444( src[3], src[0], src[1], src[2] ) + +#define CONVERT_DIRECT + +#define SRC_TEXEL_BYTES 2 + +#define TAG(x) x##_argb4444_direct +#define PRESERVE_DST_TYPE +#include "texutil_tmp.h" + + +#define CONVERT_TEXEL( dst, src ) \ + dst = PACK_COLOR_4444( src[3], src[0], src[1], src[2] ) + +#define CONVERT_TEXEL_DWORD( dst, src ) \ + dst = ((PACK_COLOR_4444( src[3], src[0], src[1], src[2] )) | \ + (PACK_COLOR_4444( src[7], src[4], src[5], src[6] ) << 16)) + +#define SRC_TEXEL_BYTES 4 + +#define TAG(x) x##_abgr8888_to_argb4444 +#include "texutil_tmp.h" + + +#define CONVERT_ARGB4444( name ) \ +static GLboolean \ +convert_##name##_argb4444( struct gl_texture_convert *convert ) \ +{ \ + convert_func *tab; \ + GLint index = convert->index; \ + \ + if ( convert->format == GL_BGRA && \ + convert->type == GL_UNSIGNED_SHORT_4_4_4_4_REV ) \ + { \ + tab = name##_tab_argb4444_direct; \ + } \ + else if ( convert->format == GL_RGBA && \ + convert->type == GL_UNSIGNED_BYTE ) \ + { \ + tab = name##_tab_abgr8888_to_argb4444; \ + } \ + else \ + { \ + /* Can't handle this source format/type combination */ \ + return GL_FALSE; \ + } \ + \ + return tab[index]( convert ); \ +} + +CONVERT_ARGB4444( texsubimage2d ) +CONVERT_ARGB4444( texsubimage3d ) + + + +/* ============================================================= + * ARGB1555 textures: + */ + +#define DST_TYPE GLushort +#define DST_TEXELS_PER_DWORD 2 + +#define CONVERT_TEXEL( dst, src ) \ + dst = PACK_COLOR_1555( src[3], src[0], src[1], src[2] ) + +#define CONVERT_DIRECT + +#define SRC_TEXEL_BYTES 2 + +#define TAG(x) x##_argb1555_direct +#define PRESERVE_DST_TYPE +#include "texutil_tmp.h" + + +#define CONVERT_TEXEL( dst, src ) \ + { const GLushort s = *(GLushort *)src; \ + dst = (s >> 1) | ((s & 1) << 15); } + +#define CONVERT_TEXEL_DWORD( dst, src ) \ + { const GLuint s = ((fi_type *)src)->i; \ + dst = (((s & 0xfffefffe) >> 1) | \ + ((s & 0x00010001) << 15)); } + +#define SRC_TEXEL_BYTES 2 + +#define TAG(x) x##_rgba5551_to_argb1555 +#define PRESERVE_DST_TYPE +#include "texutil_tmp.h" + + +#define CONVERT_TEXEL( dst, src ) \ + dst = PACK_COLOR_1555( src[3], src[0], src[1], src[2] ) + +#define CONVERT_TEXEL_DWORD( dst, src ) \ + dst = ((PACK_COLOR_1555( src[3], src[0], src[1], src[2] )) | \ + (PACK_COLOR_1555( src[7], src[4], src[5], src[6] ) << 16)) + +#define SRC_TEXEL_BYTES 4 + +#define TAG(x) x##_abgr8888_to_argb1555 +#include "texutil_tmp.h" + + +#define CONVERT_ARGB1555( name ) \ +static GLboolean \ +convert_##name##_argb1555( struct gl_texture_convert *convert ) \ +{ \ + convert_func *tab; \ + GLint index = convert->index; \ + \ + if ( convert->format == GL_BGRA && \ + convert->type == GL_UNSIGNED_SHORT_1_5_5_5_REV ) \ + { \ + tab = name##_tab_argb1555_direct; \ + } \ + else if ( convert->format == GL_RGBA && \ + convert->type == GL_UNSIGNED_SHORT_5_5_5_1 ) \ + { \ + tab = name##_tab_rgba5551_to_argb1555; \ + } \ + else if ( convert->format == GL_RGBA && \ + convert->type == GL_UNSIGNED_BYTE ) \ + { \ + tab = name##_tab_abgr8888_to_argb1555; \ + } \ + else \ + { \ + /* Can't handle this source format/type combination */ \ + return GL_FALSE; \ + } \ + \ + return tab[index]( convert ); \ +} + +CONVERT_ARGB1555( texsubimage2d ) +CONVERT_ARGB1555( texsubimage3d ) + + + +/* ============================================================= + * AL88 textures: + */ + +#define DST_TYPE GLushort +#define DST_TEXELS_PER_DWORD 2 + +#define CONVERT_TEXEL( dst, src ) \ + dst = PACK_COLOR_88( src[0], src[1] ) + +#define CONVERT_DIRECT + +#define SRC_TEXEL_BYTES 2 + +#define TAG(x) x##_al88_direct +#define PRESERVE_DST_TYPE +#include "texutil_tmp.h" + + +#define CONVERT_TEXEL( dst, src ) \ + dst = PACK_COLOR_88( src[0], 0x00 ) + +#define CONVERT_TEXEL_DWORD( dst, src ) \ + dst = ((PACK_COLOR_88( src[0], 0x00 )) | \ + (PACK_COLOR_88( src[1], 0x00 ) << 16)) + +#define SRC_TEXEL_BYTES 1 + +#define TAG(x) x##_a8_to_al88 +#define PRESERVE_DST_TYPE +#include "texutil_tmp.h" + + +#define CONVERT_TEXEL( dst, src ) \ + dst = PACK_COLOR_88( 0xff, src[0] ) + +#define CONVERT_TEXEL_DWORD( dst, src ) \ + dst = ((PACK_COLOR_88( 0xff, src[0] )) | \ + (PACK_COLOR_88( 0xff, src[1] ) << 16)) + +#define SRC_TEXEL_BYTES 1 + +#define TAG(x) x##_l8_to_al88 +#define PRESERVE_DST_TYPE +#include "texutil_tmp.h" + + +#define CONVERT_TEXEL( dst, src ) \ + dst = PACK_COLOR_88( src[3], src[0] ) + +#define CONVERT_TEXEL_DWORD( dst, src ) \ + dst = ((PACK_COLOR_88( src[3], src[0] )) | \ + (PACK_COLOR_88( src[7], src[1] ) << 16)) + +#define SRC_TEXEL_BYTES 4 + +#define TAG(x) x##_abgr8888_to_al88 +#include "texutil_tmp.h" + + +#define CONVERT_AL88( name ) \ +static GLboolean \ +convert_##name##_al88( struct gl_texture_convert *convert ) \ +{ \ + convert_func *tab; \ + GLint index = convert->index; \ + \ + if ( convert->format == GL_LUMINANCE_ALPHA && \ + convert->type == GL_UNSIGNED_BYTE ) \ + { \ + tab = name##_tab_al88_direct; \ + } \ + else if ( convert->format == GL_ALPHA && \ + convert->type == GL_UNSIGNED_BYTE ) \ + { \ + tab = name##_tab_a8_to_al88; \ + } \ + else if ( convert->format == GL_LUMINANCE && \ + convert->type == GL_UNSIGNED_BYTE ) \ + { \ + tab = name##_tab_l8_to_al88; \ + } \ + else if ( convert->format == GL_RGBA && \ + convert->type == GL_UNSIGNED_BYTE ) \ + { \ + tab = name##_tab_abgr8888_to_al88; \ + } \ + else \ + { \ + /* Can't handle this source format/type combination */ \ + return GL_FALSE; \ + } \ + \ + return tab[index]( convert ); \ +} + +CONVERT_AL88( texsubimage2d ) +CONVERT_AL88( texsubimage3d ) + + + +/* ============================================================= + * RGB332 textures: + */ + +static GLboolean +convert_texsubimage2d_rgb332( struct gl_texture_convert *convert ) +{ + /* This is a placeholder for now... + */ + return GL_FALSE; +} + +static GLboolean +convert_texsubimage3d_rgb332( struct gl_texture_convert *convert ) +{ + /* This is a placeholder for now... + */ + return GL_FALSE; +} + + + +/* ============================================================= + * CI8 (and all other single-byte texel) textures: + */ + +#define DST_TYPE GLubyte +#define DST_TEXELS_PER_DWORD 4 + +#define CONVERT_TEXEL( dst, src ) dst = src[0] + +#define CONVERT_DIRECT + +#define SRC_TEXEL_BYTES 1 + +#define TAG(x) x##_ci8_direct +#include "texutil_tmp.h" + + +#define CONVERT_CI8( name ) \ +static GLboolean \ +convert_##name##_ci8( struct gl_texture_convert *convert ) \ +{ \ + convert_func *tab; \ + GLint index = convert->index; \ + \ + if ( ( convert->format == GL_ALPHA || \ + convert->format == GL_LUMINANCE || \ + convert->format == GL_INTENSITY || \ + convert->format == GL_COLOR_INDEX ) && \ + convert->type == GL_UNSIGNED_BYTE ) \ + { \ + tab = name##_tab_ci8_direct; \ + } \ + else \ + { \ + /* Can't handle this source format/type combination */ \ + return GL_FALSE; \ + } \ + \ + return tab[index]( convert ); \ +} + +CONVERT_CI8( texsubimage2d ) +CONVERT_CI8( texsubimage3d ) + + + +/* ============================================================= + * Global entry points + */ + +static convert_func gl_convert_texsubimage2d_tab[] = { + convert_texsubimage2d_rgba8888, + convert_texsubimage2d_argb8888, + convert_texsubimage2d_rgb888, + convert_texsubimage2d_rgb565, + convert_texsubimage2d_argb4444, + convert_texsubimage2d_argb1555, + convert_texsubimage2d_al88, + convert_texsubimage2d_rgb332, + convert_texsubimage2d_ci8, /* These are all the same... */ + convert_texsubimage2d_ci8, + convert_texsubimage2d_ci8, + convert_texsubimage2d_ci8, +}; + +static convert_func gl_convert_texsubimage3d_tab[] = { + convert_texsubimage3d_rgba8888, + convert_texsubimage3d_argb8888, + convert_texsubimage3d_rgb888, + convert_texsubimage3d_rgb565, + convert_texsubimage3d_argb4444, + convert_texsubimage3d_argb1555, + convert_texsubimage3d_al88, + convert_texsubimage3d_rgb332, + convert_texsubimage3d_ci8, /* These are all the same... */ + convert_texsubimage3d_ci8, + convert_texsubimage3d_ci8, + convert_texsubimage3d_ci8, +}; + + +/* See if we need to care about the pixel store attributes when we're + * converting the texture image. This should be stored as + * packing->_SomeBoolean and updated when the values change, to avoid + * testing every time... + */ +static INLINE GLboolean +convert_needs_packing( const struct gl_pixelstore_attrib *packing, + GLenum format, GLenum type ) +{ + if ( ( packing->Alignment == 1 || + ( packing->Alignment == 4 && /* Pick up the common Q3A case... */ + format == GL_RGBA && type == GL_UNSIGNED_BYTE ) ) && + packing->RowLength == 0 && + packing->SkipPixels == 0 && + packing->SkipRows == 0 && + packing->ImageHeight == 0 && + packing->SkipImages == 0 && + packing->SwapBytes == GL_FALSE && + packing->LsbFirst == GL_FALSE ) { + return GL_FALSE; + } else { + return GL_TRUE; + } +} + + +GLboolean +_mesa_convert_texsubimage1d( GLint mesaFormat, + GLint xoffset, + GLint width, + GLenum format, GLenum type, + const struct gl_pixelstore_attrib *packing, + const GLvoid *srcImage, GLvoid *dstImage ) +{ + struct gl_texture_convert convert; + + ASSERT( packing ); + ASSERT( srcImage ); + ASSERT( dstImage ); + + ASSERT( mesaFormat >= MESA_FORMAT_RGBA8888 ); + ASSERT( mesaFormat <= MESA_FORMAT_CI8 ); + + /* Make it easier to pass all the parameters around. + */ + convert.xoffset = xoffset; + convert.yoffset = 0; + convert.width = width; + convert.height = 1; + convert.format = format; + convert.type = type; + convert.packing = packing; + convert.srcImage = srcImage; + convert.dstImage = dstImage; + + convert.index = 0; + + if ( convert_needs_packing( packing, format, type ) ) + convert.index |= CONVERT_PACKING_BIT; + + return gl_convert_texsubimage2d_tab[mesaFormat]( &convert ); +} + + +/* Convert a user's 2D image into a texture image. This basically + * repacks pixel data into the special texture formats used by core Mesa + * and the DRI drivers. This function can do full images or subimages. + * + * We return a boolean because this function may not accept some kinds + * of source image formats and/or types. For example, if the incoming + * format/type = GL_BGR, GL_UNSIGNED_INT this function probably won't + * be able to do the conversion. + * + * In that case, the incoming image should first be simplified to one of + * the "canonical" formats (GL_ALPHA, GL_LUMINANCE, GL_LUMINANCE_ALPHA, + * GL_INTENSITY, GL_RGB, GL_RGBA) and types (GL_CHAN). We can do that + * with the _mesa_transfer_teximage() function. That function will also + * do image transfer operations such as scale/bias and convolution. + * + * Input: + * mesaFormat - one of the MESA_FORMAT_* values from texformat.h + * xoffset, yoffset - position in dest image to put data + * width, height - incoming image size, also size of dest region. + * dstImageWidth - width (row stride) of dest image in pixels + * format, type - incoming image format and type + * packing - describes incoming image packing + * srcImage - pointer to source image + * destImage - pointer to dest image + */ +GLboolean +_mesa_convert_texsubimage2d( GLint mesaFormat, + GLint xoffset, GLint yoffset, + GLint width, GLint height, + GLint destImageWidth, + GLenum format, GLenum type, + const struct gl_pixelstore_attrib *packing, + const GLvoid *srcImage, GLvoid *dstImage ) +{ + struct gl_texture_convert convert; + + ASSERT( packing ); + ASSERT( srcImage ); + ASSERT( dstImage ); + + ASSERT( mesaFormat >= MESA_FORMAT_RGBA8888 ); + ASSERT( mesaFormat <= MESA_FORMAT_CI8 ); + + /* Make it easier to pass all the parameters around. + */ + convert.xoffset = xoffset; + convert.yoffset = yoffset; + convert.width = width; + convert.height = height; + convert.dstImageWidth = destImageWidth; + convert.format = format; + convert.type = type; + convert.packing = packing; + convert.srcImage = srcImage; + convert.dstImage = dstImage; + + convert.index = 0; + + if ( convert_needs_packing( packing, format, type ) ) + convert.index |= CONVERT_PACKING_BIT; + + if ( width != destImageWidth ) + convert.index |= CONVERT_STRIDE_BIT; + + return gl_convert_texsubimage2d_tab[mesaFormat]( &convert ); +} + +GLboolean +_mesa_convert_texsubimage3d( GLint mesaFormat, + GLint xoffset, GLint yoffset, GLint zoffset, + GLint width, GLint height, GLint depth, + GLint dstImageWidth, GLint dstImageHeight, + GLenum format, GLenum type, + const struct gl_pixelstore_attrib *packing, + const GLvoid *srcImage, GLvoid *dstImage ) +{ + struct gl_texture_convert convert; + + ASSERT( packing ); + ASSERT( srcImage ); + ASSERT( dstImage ); + + ASSERT( mesaFormat >= MESA_FORMAT_RGBA8888 ); + ASSERT( mesaFormat <= MESA_FORMAT_CI8 ); + + /* Make it easier to pass all the parameters around. + */ + convert.xoffset = xoffset; + convert.yoffset = yoffset; + convert.zoffset = zoffset; + convert.width = width; + convert.height = height; + convert.depth = depth; + convert.dstImageWidth = dstImageWidth; + convert.dstImageHeight = dstImageHeight; + convert.format = format; + convert.type = type; + convert.packing = packing; + convert.srcImage = srcImage; + convert.dstImage = dstImage; + + convert.index = 0; + + if ( convert_needs_packing( packing, format, type ) ) + convert.index |= CONVERT_PACKING_BIT; + + if ( width != dstImageWidth || height != dstImageHeight ) + convert.index |= CONVERT_STRIDE_BIT; + + return gl_convert_texsubimage3d_tab[mesaFormat]( &convert ); +} + + + +/* Nearest filtering only (for broken hardware that can't support + * all aspect ratios). This can be made a lot faster, but I don't + * really care enough... + */ +void _mesa_rescale_teximage2d( GLuint bytesPerPixel, GLuint dstRowStride, + GLint srcWidth, GLint srcHeight, + GLint dstWidth, GLint dstHeight, + const GLvoid *srcImage, GLvoid *dstImage ) +{ + GLint row, col; + +#define INNER_LOOP( TYPE, HOP, WOP ) \ + for ( row = 0 ; row < dstHeight ; row++ ) { \ + GLint srcRow = row HOP hScale; \ + for ( col = 0 ; col < dstWidth ; col++ ) { \ + GLint srcCol = col WOP wScale; \ + dst[col] = src[srcRow * srcWidth + srcCol]; \ + } \ + dst = (TYPE *) ((GLubyte *) dst + dstRowStride); \ + } \ + +#define RESCALE_IMAGE( TYPE ) \ +do { \ + const TYPE *src = (const TYPE *)srcImage; \ + TYPE *dst = (TYPE *)dstImage; \ + \ + if ( srcHeight <= dstHeight ) { \ + const GLint hScale = dstHeight / srcHeight; \ + if ( srcWidth <= dstWidth ) { \ + const GLint wScale = dstWidth / srcWidth; \ + INNER_LOOP( TYPE, /, / ); \ + } \ + else { \ + const GLint wScale = srcWidth / dstWidth; \ + INNER_LOOP( TYPE, /, * ); \ + } \ + } \ + else { \ + const GLint hScale = srcHeight / dstHeight; \ + if ( srcWidth <= dstWidth ) { \ + const GLint wScale = dstWidth / srcWidth; \ + INNER_LOOP( TYPE, *, / ); \ + } \ + else { \ + const GLint wScale = srcWidth / dstWidth; \ + INNER_LOOP( TYPE, *, * ); \ + } \ + } \ +} while (0) + + switch ( bytesPerPixel ) { + case 4: + RESCALE_IMAGE( GLuint ); + break; + + case 2: + RESCALE_IMAGE( GLushort ); + break; + + case 1: + RESCALE_IMAGE( GLubyte ); + break; + default: + _mesa_problem(NULL,"unexpected bytes/pixel in _mesa_rescale_teximage2d"); + } +} Index: dll/opengl/opengl32/mesa/texutil.h =================================================================== --- dll/opengl/opengl32/mesa/texutil.h (revision 0) +++ dll/opengl/opengl32/mesa/texutil.h (working copy) @@ -0,0 +1,73 @@ +/* $Id: texutil.h,v 1.10 2001/05/02 21:02:38 brianp Exp $ */ + +/* + * Mesa 3-D graphics library + * Version: 3.5 + * + * Copyright (C) 1999-2001 Brian Paul 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 + * BRIAN PAUL 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. + * + * Authors: + * Gareth Hughes + */ + + +#ifndef TEXUTIL_H +#define TEXUTIL_H + +#include "mtypes.h" +#include "texformat.h" + +extern GLboolean +_mesa_convert_texsubimage1d( GLint mesaFormat, + GLint xoffset, + GLint width, + GLenum format, GLenum type, + const struct gl_pixelstore_attrib *packing, + const GLvoid *srcImage, GLvoid *dstImage ); + +extern GLboolean +_mesa_convert_texsubimage2d( GLint mesaFormat, + GLint xoffset, GLint yoffset, + GLint width, GLint height, + GLint imageWidth, + GLenum format, GLenum type, + const struct gl_pixelstore_attrib *packing, + const GLvoid *srcImage, GLvoid *dstImage ); + +extern GLboolean +_mesa_convert_texsubimage3d( GLint mesaFormat, + GLint xoffset, GLint yoffset, GLint zoffset, + GLint width, GLint height, GLint depth, + GLint imageWidth, GLint imageHeight, + GLenum format, GLenum type, + const struct gl_pixelstore_attrib *packing, + const GLvoid *srcImage, GLvoid *dstImage ); + +/* Nearest filtering only (for broken hardware that can't support + * all aspect ratios). FIXME: Make this a subimage update as well... + */ +extern void +_mesa_rescale_teximage2d( GLuint bytesPerPixel, GLuint dstRowStride, + GLint srcWidth, GLint srcHeight, + GLint dstWidth, GLint dstHeight, + const GLvoid *srcImage, GLvoid *dstImage ); + + +#endif Index: dll/opengl/opengl32/mesa/texutil_tmp.h =================================================================== --- dll/opengl/opengl32/mesa/texutil_tmp.h (revision 0) +++ dll/opengl/opengl32/mesa/texutil_tmp.h (working copy) @@ -0,0 +1,409 @@ +/* $Id: texutil_tmp.h,v 1.8 2001/04/20 19:21:41 brianp Exp $ */ + +/* + * Mesa 3-D graphics library + * Version: 3.5 + * + * Copyright (C) 1999-2001 Brian Paul 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 + * BRIAN PAUL 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. + * + * Author: + * Gareth Hughes + */ + +/* + * NOTE: All 3D teximage code is untested and most definitely broken... + */ + + +#define DST_TEXEL_BYTES (4 / DST_TEXELS_PER_DWORD) +#define DST_ROW_WIDTH (convert->width * DST_TEXEL_BYTES) +#define DST_ROW_STRIDE (convert->dstImageWidth * DST_TEXEL_BYTES) +#define DST_IMG_STRIDE (convert->dstImageWidth * \ + convert->dstImageHeight * DST_TEXEL_BYTES) + + +/* ============================================================= + * PRE: No pixelstore attribs, width == dstImageWidth. + */ +static GLboolean +TAG(texsubimage2d)( struct gl_texture_convert *convert ) +{ + const GLubyte *src = (const GLubyte *)convert->srcImage; + GLuint *dst = (GLuint *)((GLubyte *)convert->dstImage + + (convert->yoffset * convert->dstImageWidth + + convert->xoffset) * DST_TEXEL_BYTES); + GLint dwords, i; + (void) dwords; (void) i; + +#if DEBUG_TEXUTIL + fprintf( stderr, __FUNCTION__ "\n" ); +#endif + +#ifdef CONVERT_DIRECT + MEMCPY( dst, src, convert->height * DST_ROW_WIDTH ); +#else + dwords = (convert->width * convert->height + + DST_TEXELS_PER_DWORD - 1) / DST_TEXELS_PER_DWORD; + + for ( i = 0 ; i < dwords ; i++ ) { + CONVERT_TEXEL_DWORD( *dst++, src ); + src += SRC_TEXEL_BYTES * DST_TEXELS_PER_DWORD; + } +#endif + + return GL_TRUE; +} + +/* PRE: As above, height == dstImageHeight also. + */ +static GLboolean +TAG(texsubimage3d)( struct gl_texture_convert *convert ) +{ + const GLubyte *src = (const GLubyte *)convert->srcImage; + GLuint *dst = (GLuint *)((GLubyte *)convert->dstImage + + ((convert->zoffset * convert->height + + convert->yoffset) * convert->width + + convert->xoffset) * DST_TEXEL_BYTES); + GLint dwords, i; + (void) dwords; (void) i; + +#if DEBUG_TEXUTIL + fprintf( stderr, __FUNCTION__ "\n" ); +#endif + +#ifdef CONVERT_DIRECT + MEMCPY( dst, src, convert->depth * convert->height * DST_ROW_WIDTH ); +#else + dwords = (convert->width * convert->height * convert->depth + + DST_TEXELS_PER_DWORD - 1) / DST_TEXELS_PER_DWORD; + + for ( i = 0 ; i < dwords ; i++ ) { + CONVERT_TEXEL_DWORD( *dst++, src ); + src += SRC_TEXEL_BYTES * DST_TEXELS_PER_DWORD; + } +#endif + + return GL_TRUE; +} + + + +/* ============================================================= + * PRE: No pixelstore attribs, width != dstImageWidth. + */ +static GLboolean +TAG(texsubimage2d_stride)( struct gl_texture_convert *convert ) +{ + const GLubyte *src = (const GLubyte *)convert->srcImage; + DST_TYPE *dst = (DST_TYPE *)((GLubyte *)convert->dstImage + + (convert->yoffset * convert->dstImageWidth + + convert->xoffset) * DST_TEXEL_BYTES); + GLint adjust; + GLint row, col; + + adjust = convert->dstImageWidth - convert->width; + +#if DEBUG_TEXUTIL + fprintf( stderr, __FUNCTION__ ":\n" ); + fprintf( stderr, " x=%d y=%d w=%d h=%d s=%d\n", + convert->xoffset, convert->yoffset, convert->width, + convert->height, convert->dstImageWidth ); + fprintf( stderr, " adjust=%d\n", adjust ); +#endif + + for ( row = 0 ; row < convert->height ; row++ ) { + for ( col = 0 ; col < convert->width ; col++ ) { + CONVERT_TEXEL( *dst++, src ); + src += SRC_TEXEL_BYTES; + } + dst += adjust; + } + + return GL_TRUE; +} + +/* PRE: As above, or height != dstImageHeight also. + */ +static GLboolean +TAG(texsubimage3d_stride)( struct gl_texture_convert *convert ) +{ + const GLubyte *src = (const GLubyte *)convert->srcImage; + DST_TYPE *dst = (DST_TYPE *)((GLubyte *)convert->dstImage + + ((convert->zoffset * convert->dstImageHeight + + convert->yoffset) * convert->dstImageWidth + + convert->xoffset) * DST_TEXEL_BYTES); + GLint adjust; + GLint row, col, img; + + adjust = convert->dstImageWidth - convert->width; + +#if DEBUG_TEXUTIL + fprintf( stderr, __FUNCTION__ ":\n" ); + fprintf( stderr, " x=%d y=%d w=%d h=%d s=%d\n", + convert->xoffset, convert->yoffset, convert->width, + convert->height, convert->dstImageWidth ); + fprintf( stderr, " adjust=%d\n", adjust ); +#endif + + for ( img = 0 ; img < convert->depth ; img++ ) { + for ( row = 0 ; row < convert->height ; row++ ) { + for ( col = 0 ; col < convert->width ; col++ ) { + CONVERT_TEXEL( *dst++, src ); + src += SRC_TEXEL_BYTES; + } + dst += adjust; + } + /* FIXME: ... */ + } + + return GL_TRUE; +} + + + +/* ============================================================= + * PRE: Require pixelstore attribs, width == dstImageWidth. + */ +static GLboolean +TAG(texsubimage2d_pack)( struct gl_texture_convert *convert ) +{ + const GLubyte *src = (const GLubyte *) + _mesa_image_address( convert->packing, convert->srcImage, + convert->width, convert->height, + convert->format, convert->type, 0, 0, 0 ); + const GLint srcRowStride = + _mesa_image_row_stride( convert->packing, convert->width, + convert->format, convert->type ); + GLuint *dst = (GLuint *)((GLubyte *)convert->dstImage + + (convert->yoffset * convert->width + + convert->xoffset) * DST_TEXEL_BYTES); + GLint width; + GLint row, col; + (void) col; + +#if DEBUG_TEXUTIL + fprintf( stderr, __FUNCTION__ "\n" ); +#endif + + width = ((convert->width + DST_TEXELS_PER_DWORD - 1) + & ~(DST_TEXELS_PER_DWORD - 1)); + + for ( row = 0 ; row < convert->height ; row++ ) { +#ifdef CONVERT_DIRECT + MEMCPY( dst, src, DST_ROW_STRIDE ); + src += srcRowStride; + dst = (GLuint *)((GLubyte *)dst + DST_ROW_STRIDE); +#else + const GLubyte *srcRow = src; + for ( col = width / DST_TEXELS_PER_DWORD ; col ; col-- ) { + CONVERT_TEXEL_DWORD( *dst++, src ); + src += SRC_TEXEL_BYTES * DST_TEXELS_PER_DWORD; + } + src = srcRow + srcRowStride; +#endif + } + + return GL_TRUE; +} + +/* PRE: as above, height == dstImageHeight also. + */ +static GLboolean +TAG(texsubimage3d_pack)( struct gl_texture_convert *convert ) +{ + const GLubyte *src = (const GLubyte *) + _mesa_image_address( convert->packing, convert->srcImage, + convert->width, convert->height, + convert->format, convert->type, 0, 0, 0 ); + const GLint srcRowStride = + _mesa_image_row_stride( convert->packing, convert->width, + convert->format, convert->type ); + GLuint *dst = (GLuint *)((GLubyte *)convert->dstImage + + ((convert->zoffset * convert->height + + convert->yoffset) * convert->width + + convert->xoffset) * DST_TEXEL_BYTES); + GLint width; + GLint row, col, img; + (void) col; + +#if DEBUG_TEXUTIL + fprintf( stderr, __FUNCTION__ "\n" ); +#endif + + width = ((convert->width + DST_TEXELS_PER_DWORD - 1) + & ~(DST_TEXELS_PER_DWORD - 1)); + + for ( img = 0 ; img < convert->depth ; img++ ) { + for ( row = 0 ; row < convert->height ; row++ ) { +#ifdef CONVERT_DIRECT + MEMCPY( dst, src, DST_ROW_STRIDE ); + src += srcRowStride; + dst = (GLuint *)((GLubyte *)dst + DST_ROW_STRIDE); +#else + const GLubyte *srcRow = src; + for ( col = width / DST_TEXELS_PER_DWORD ; col ; col-- ) { + CONVERT_TEXEL_DWORD( *dst++, src ); + src += SRC_TEXEL_BYTES * DST_TEXELS_PER_DWORD; + } + src = srcRow + srcRowStride; +#endif + } + } + + return GL_TRUE; +} + + + +/* ============================================================= + * PRE: Require pixelstore attribs, width != dstImageWidth. + */ +static GLboolean +TAG(texsubimage2d_stride_pack)( struct gl_texture_convert *convert ) +{ + const GLubyte *src = (const GLubyte *) + _mesa_image_address( convert->packing, convert->srcImage, + convert->width, convert->height, + convert->format, convert->type, 0, 0, 0 ); + const GLint srcRowStride = + _mesa_image_row_stride( convert->packing, convert->width, + convert->format, convert->type ); + DST_TYPE *dst = (DST_TYPE *)((GLubyte *)convert->dstImage + + (convert->yoffset * convert->dstImageWidth + + convert->xoffset) * DST_TEXEL_BYTES); + GLint adjust; + GLint row, col; + (void) col; + + adjust = convert->dstImageWidth - convert->width; + +#if DEBUG_TEXUTIL + fprintf( stderr, __FUNCTION__ ":\n" ); + fprintf( stderr, " x=%d y=%d w=%d h=%d s=%d\n", + convert->xoffset, convert->yoffset, convert->width, + convert->height, convert->dstImageWidth ); + fprintf( stderr, " adjust=%d\n", adjust ); +#endif + + for ( row = 0 ; row < convert->height ; row++ ) { +#ifdef CONVERT_DIRECT + MEMCPY( dst, src, DST_ROW_WIDTH ); + src += srcRowStride; + dst += convert->dstImageWidth; +#else + const GLubyte *srcRow = src; + for ( col = 0 ; col < convert->width ; col++ ) { + CONVERT_TEXEL( *dst++, src ); + src += SRC_TEXEL_BYTES; + } + src = srcRow + srcRowStride; + dst += adjust; +#endif + } + + return GL_TRUE; +} + +/* PRE: As above, or height != dstImageHeight also. + */ +static GLboolean +TAG(texsubimage3d_stride_pack)( struct gl_texture_convert *convert ) +{ + const GLubyte *src = (const GLubyte *) + _mesa_image_address( convert->packing, convert->srcImage, + convert->width, convert->height, + convert->format, convert->type, 0, 0, 0 ); + const GLint srcRowStride = + _mesa_image_row_stride( convert->packing, convert->width, + convert->format, convert->type ); + DST_TYPE *dst = (DST_TYPE *)((GLubyte *)convert->dstImage + + ((convert->zoffset * convert->dstImageHeight + + convert->yoffset) * convert->dstImageWidth + + convert->xoffset) * DST_TEXEL_BYTES); + GLint adjust; + GLint row, col, img; + (void) col; + + adjust = convert->dstImageWidth - convert->width; + +#if DEBUG_TEXUTIL + fprintf( stderr, __FUNCTION__ ":\n" ); + fprintf( stderr, " x=%d y=%d w=%d h=%d s=%d\n", + convert->xoffset, convert->yoffset, convert->width, + convert->height, convert->dstImageWidth ); + fprintf( stderr, " adjust=%d\n", adjust ); +#endif + + for ( img = 0 ; img < convert->depth ; img++ ) { + for ( row = 0 ; row < convert->height ; row++ ) { +#ifdef CONVERT_DIRECT + MEMCPY( dst, src, DST_ROW_WIDTH ); + src += srcRowStride; + dst += convert->dstImageWidth; +#else + const GLubyte *srcRow = src; + for ( col = 0 ; col < convert->width ; col++ ) { + CONVERT_TEXEL( *dst++, src ); + src += SRC_TEXEL_BYTES; + } + src = srcRow + srcRowStride; + dst += adjust; +#endif + } + /* FIXME: ... */ + } + + return GL_TRUE; +} + + + +static convert_func TAG(texsubimage2d_tab)[] = { + TAG(texsubimage2d), + TAG(texsubimage2d_stride), + TAG(texsubimage2d_pack), + TAG(texsubimage2d_stride_pack), +}; + +static convert_func TAG(texsubimage3d_tab)[] = { + TAG(texsubimage3d), + TAG(texsubimage3d_stride), + TAG(texsubimage3d_pack), + TAG(texsubimage3d_stride_pack), +}; + + +#ifndef PRESERVE_DST_TYPE +#undef DST_TYPE +#undef DST_TEXELS_PER_DWORD +#endif + +#undef SRC_TEXEL_BYTES +#undef DST_TEXEL_BYTES +#undef DST_ROW_WIDTH +#undef DST_ROW_STRIDE + +#undef CONVERT_TEXEL +#undef CONVERT_TEXEL_DWORD +#undef CONVERT_DIRECT + +#undef TAG + +#undef PRESERVE_DST_TYPE Index: dll/opengl/opengl32/mesa/tnl/t_array_api.c =================================================================== --- dll/opengl/opengl32/mesa/tnl/t_array_api.c (revision 0) +++ dll/opengl/opengl32/mesa/tnl/t_array_api.c (working copy) @@ -0,0 +1,448 @@ +/* $Id: t_array_api.c,v 1.15 2001/05/11 15:53:06 keithw Exp $ */ + +/* + * Mesa 3-D graphics library + * Version: 3.5 + * + * Copyright (C) 1999-2001 Brian Paul 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 + * BRIAN PAUL 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. + * + * Authors: + * Keith Whitwell + */ + +#include "glheader.h" +#include "api_validate.h" +#include "context.h" +#include "macros.h" +#include "mmath.h" +#include "mem.h" +#include "state.h" +#include "mtypes.h" + +#include "array_cache/acache.h" + +#include "t_array_api.h" +#include "t_array_import.h" +#include "t_imm_api.h" +#include "t_imm_exec.h" +#include "t_context.h" +#include "t_pipeline.h" + +static void fallback_drawarrays( GLcontext *ctx, GLenum mode, GLint start, + GLsizei count ) +{ +/* fprintf(stderr, "%s\n", __FUNCTION__); */ + + /* Need to produce immediate structs, either for compiling or + * because the array range is too large to process in a single + * VB. In GL_EXECUTE mode, this introduces two redundant + * operations: producing the flag array and computing the orflag + * of the flag array. + */ +#if 1 + if (_tnl_hard_begin( ctx, mode )) { + GLint i; + for (i = 0 ; i < count ; ) { + struct immediate *IM = TNL_CURRENT_IM(ctx); + GLuint start = IM->Start; + GLuint nr = MIN2( IMM_MAXDATA - start, (GLuint) (count - i) ); + + _tnl_fill_immediate_drawarrays( ctx, IM, i, i+nr ); + + IM->Count = start + nr; + i += nr; + + if (i == count) + _tnl_end( ctx ); + + _tnl_flush_immediate( IM ); + } + } +#else + /* Simple alternative to above code. + */ + if (_tnl_hard_begin( ctx, mode )) + { + GLuint i; + for (i=start;iStart; + GLint end = MIN2( IMM_MAXDATA, (count - i) + start); + GLuint sf = IM->Flag[start]; + IM->FlushElt = IM->ArrayEltFlush; + + for (j = start ; j < end ; j++) { + IM->Elt[j] = (GLuint) *indices++; + IM->Flag[j] = VERT_ELT; + } + + IM->Flag[start] |= (sf & IM->ArrayEltFlags); + IM->Count = end; + i += end - start; + + if (i == count) + _tnl_end( ctx ); + + _tnl_flush_immediate( IM ); + } + } +#else + /* Simple version of the above code. + */ + if (_tnl_hard_begin(ctx, mode)) { + GLuint i; + for (i = 0 ; i < count ; i++) + _tnl_array_element( ctx, indices[i] ); + _tnl_end( ctx ); + } +#endif +} + + +static void _tnl_draw_range_elements( GLcontext *ctx, GLenum mode, + GLuint start, GLuint end, + GLsizei count, const GLuint *indices ) + +{ + TNLcontext *tnl = TNL_CONTEXT(ctx); + FLUSH_CURRENT( ctx, 0 ); + + _tnl_vb_bind_arrays( ctx, start, end ); + + tnl->vb.FirstPrimitive = 0; + tnl->vb.Primitive[0] = mode | PRIM_BEGIN | PRIM_END | PRIM_LAST; + tnl->vb.PrimitiveLength[0] = count; + tnl->vb.Elts = (GLuint *)indices; + + if (ctx->Array.LockCount) + tnl->Driver.RunPipeline( ctx ); + else { + /* Note that arrays may have changed before/after execution. + */ + tnl->pipeline.run_input_changes |= ctx->Array._Enabled; + tnl->Driver.RunPipeline( ctx ); + tnl->pipeline.run_input_changes |= ctx->Array._Enabled; + } +} + + + + +void +_tnl_DrawArrays(GLenum mode, GLint start, GLsizei count) +{ + GET_CURRENT_CONTEXT(ctx); + TNLcontext *tnl = TNL_CONTEXT(ctx); + struct vertex_buffer *VB = &tnl->vb; + +/* fprintf(stderr, "%s\n", __FUNCTION__); */ + + /* Check arguments, etc. + */ + if (!_mesa_validate_DrawArrays( ctx, mode, start, count )) + return; + + if (tnl->pipeline.build_state_changes) + _tnl_validate_pipeline( ctx ); + + if (ctx->CompileFlag) { + fallback_drawarrays( ctx, mode, start, count ); + } + else if (count - start < (GLint) ctx->Const.MaxArrayLockSize) { + + /* Small primitives which can fit in a single vertex buffer: + */ + FLUSH_CURRENT( ctx, 0 ); + + if (ctx->Array.LockCount) + { + if (start < (GLint) ctx->Array.LockFirst) + start = ctx->Array.LockFirst; + if (count > (GLint) ctx->Array.LockCount) + count = ctx->Array.LockCount; + if (start >= count) + return; + + /* Locked drawarrays. Reuse any previously transformed data. + */ + _tnl_vb_bind_arrays( ctx, ctx->Array.LockFirst, ctx->Array.LockCount ); + VB->FirstPrimitive = start; + VB->Primitive[start] = mode | PRIM_BEGIN | PRIM_END | PRIM_LAST; + VB->PrimitiveLength[start] = count - start; + tnl->Driver.RunPipeline( ctx ); + } else { + /* The arrays are small enough to fit in a single VB; just bind + * them and go. Any untransformed data will be copied on + * clipping. + * + * Invalidate any cached data dependent on these arrays. + */ + _tnl_vb_bind_arrays( ctx, start, count ); + VB->FirstPrimitive = 0; + VB->Primitive[0] = mode | PRIM_BEGIN | PRIM_END | PRIM_LAST; + VB->PrimitiveLength[0] = count - start; + tnl->pipeline.run_input_changes |= ctx->Array._Enabled; + tnl->Driver.RunPipeline( ctx ); + tnl->pipeline.run_input_changes |= ctx->Array._Enabled; + } + } + else { + int bufsz = (ctx->Const.MaxArrayLockSize - 4) & ~3; + int j, nr; + int minimum, modulo, skip; + + /* Large primitives requiring decomposition to multiple vertex + * buffers: + */ + switch (mode) { + case GL_POINTS: + minimum = 0; + modulo = 1; + skip = 0; + case GL_LINES: + minimum = 1; + modulo = 2; + skip = 1; + case GL_LINE_STRIP: + minimum = 1; + modulo = 1; + skip = 0; + break; + case GL_TRIANGLES: + minimum = 2; + modulo = 3; + skip = 2; + break; + case GL_TRIANGLE_STRIP: + minimum = 2; + modulo = 1; + skip = 0; + break; + case GL_QUADS: + minimum = 3; + modulo = 4; + skip = 3; + break; + case GL_QUAD_STRIP: + minimum = 3; + modulo = 2; + skip = 0; + break; + case GL_LINE_LOOP: + case GL_TRIANGLE_FAN: + case GL_POLYGON: + default: + /* Primitives requiring a copied vertex (fan-like primitives) + * must use the slow path: + */ + fallback_drawarrays( ctx, mode, start, count ); + return; + } + + FLUSH_CURRENT( ctx, 0 ); + +/* fprintf(stderr, "start %d count %d min %d modulo %d skip %d\n", */ +/* start, count, minimum, modulo, skip); */ + + + bufsz -= bufsz % modulo; + bufsz -= minimum; + + for (j = start + minimum ; j < count ; j += nr + skip ) { + + nr = MIN2( bufsz, count - j ); + +/* fprintf(stderr, "%d..%d\n", j - minimum, j+nr); */ + + _tnl_vb_bind_arrays( ctx, j - minimum, j + nr ); + + VB->FirstPrimitive = 0; + VB->Primitive[0] = mode | PRIM_BEGIN | PRIM_END | PRIM_LAST; + VB->PrimitiveLength[0] = nr + minimum; + tnl->pipeline.run_input_changes |= ctx->Array._Enabled; + tnl->Driver.RunPipeline( ctx ); + tnl->pipeline.run_input_changes |= ctx->Array._Enabled; + } + } +} + + +void +_tnl_DrawRangeElements(GLenum mode, + GLuint start, GLuint end, + GLsizei count, GLenum type, const GLvoid *indices) +{ + GET_CURRENT_CONTEXT(ctx); + TNLcontext *tnl = TNL_CONTEXT(ctx); + GLuint *ui_indices; + +/* fprintf(stderr, "%s\n", __FUNCTION__); */ + + /* Check arguments, etc. + */ + if (!_mesa_validate_DrawRangeElements( ctx, mode, start, end, count, + type, indices )) + return; + + if (tnl->pipeline.build_state_changes) + _tnl_validate_pipeline( ctx ); + + ui_indices = (GLuint *)_ac_import_elements( ctx, GL_UNSIGNED_INT, + count, type, indices ); + + + if (ctx->Array.LockCount) { + /* Are the arrays already locked? If so we currently have to look + * at the whole locked range. + */ + if (start >= ctx->Array.LockFirst && end <= ctx->Array.LockCount) + _tnl_draw_range_elements( ctx, mode, + ctx->Array.LockFirst, + ctx->Array.LockCount, + count, ui_indices ); + else { + /* The spec says referencing elements outside the locked + * range is undefined. I'm going to make it a noop this time + * round, maybe come up with something beter before 3.6. + * + * May be able to get away with just setting LockCount==0, + * though this raises the problems of dependent state. May + * have to call glUnlockArrays() directly? + * + * Or scan the list and replace bad indices? + */ + _mesa_problem( ctx, + "DrawRangeElements references " + "elements outside locked range."); + } + } + else if (end + 1 - start < ctx->Const.MaxArrayLockSize) { + /* The arrays aren't locked but we can still fit them inside a + * single vertexbuffer. + */ + _tnl_draw_range_elements( ctx, mode, start, end + 1, count, ui_indices ); + } else { + /* Range is too big to optimize: + */ + fallback_drawelements( ctx, mode, count, ui_indices ); + } +} + + + +void +_tnl_DrawElements(GLenum mode, GLsizei count, GLenum type, + const GLvoid *indices) +{ + GET_CURRENT_CONTEXT(ctx); + TNLcontext *tnl = TNL_CONTEXT(ctx); + GLuint *ui_indices; + +/* fprintf(stderr, "%s\n", __FUNCTION__); */ + + /* Check arguments, etc. + */ + if (!_mesa_validate_DrawElements( ctx, mode, count, type, indices )) + return; + + if (tnl->pipeline.build_state_changes) + _tnl_validate_pipeline( ctx ); + + ui_indices = (GLuint *)_ac_import_elements( ctx, GL_UNSIGNED_INT, + count, type, indices ); + + if (ctx->Array.LockCount) { + _tnl_draw_range_elements( ctx, mode, + ctx->Array.LockFirst, + ctx->Array.LockCount, + count, ui_indices ); + } + else { + /* Scan the index list and see if we can use the locked path anyway. + */ + GLuint max_elt = 0; + GLint i; + + for (i = 0 ; i < count ; i++) + if (ui_indices[i] > max_elt) + max_elt = ui_indices[i]; + + if (max_elt < ctx->Const.MaxArrayLockSize && /* can we use it? */ + max_elt < (GLuint) count) /* do we want to use it? */ + _tnl_draw_range_elements( ctx, mode, 0, max_elt+1, count, ui_indices ); + else + fallback_drawelements( ctx, mode, count, ui_indices ); + } +} + + +void _tnl_array_init( GLcontext *ctx ) +{ + TNLcontext *tnl = TNL_CONTEXT(ctx); + struct vertex_arrays *tmp = &tnl->array_inputs; + GLvertexformat *vfmt = &(TNL_CONTEXT(ctx)->vtxfmt); + GLuint i; + + vfmt->DrawArrays = _tnl_DrawArrays; + vfmt->DrawElements = _tnl_DrawElements; + vfmt->DrawRangeElements = _tnl_DrawRangeElements; + + /* Setup vector pointers that will be used to bind arrays to VB's. + */ + _mesa_vector4f_init( &tmp->Obj, 0, 0 ); + _mesa_vector3f_init( &tmp->Normal, 0, 0 ); + _mesa_vector1f_init( &tmp->FogCoord, 0, 0 ); + _mesa_vector1ui_init( &tmp->Index, 0, 0 ); + _mesa_vector1ub_init( &tmp->EdgeFlag, 0, 0 ); + + for (i = 0; i < ctx->Const.MaxTextureUnits; i++) + _mesa_vector4f_init( &tmp->TexCoord[i], 0, 0); + + tnl->tmp_primitive = (GLuint *)MALLOC(sizeof(GLuint)*tnl->vb.Size); + tnl->tmp_primitive_length = (GLuint *)MALLOC(sizeof(GLuint)*tnl->vb.Size); +} + + +void _tnl_array_destroy( GLcontext *ctx ) +{ + TNLcontext *tnl = TNL_CONTEXT(ctx); + if (tnl->tmp_primitive_length) FREE(tnl->tmp_primitive_length); + if (tnl->tmp_primitive) FREE(tnl->tmp_primitive); +} Index: dll/opengl/opengl32/mesa/tnl/t_array_api.h =================================================================== --- dll/opengl/opengl32/mesa/tnl/t_array_api.h (revision 0) +++ dll/opengl/opengl32/mesa/tnl/t_array_api.h (working copy) @@ -0,0 +1,47 @@ +/* $Id: t_array_api.h,v 1.2 2001/03/12 00:48:43 gareth Exp $ */ + +/* + * Mesa 3-D graphics library + * Version: 3.5 + * + * Copyright (C) 1999-2001 Brian Paul 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 + * BRIAN PAUL 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. + */ + +#ifndef _T_VARRAY_H +#define _T_VARRAY_H + +#include "mtypes.h" +#include "t_context.h" + + +extern void _tnl_DrawArrays(GLenum mode, GLint first, GLsizei count); + +extern void _tnl_DrawElements(GLenum mode, GLsizei count, GLenum type, + const GLvoid *indices); + +extern void _tnl_DrawRangeElements(GLenum mode, GLuint start, + GLuint end, GLsizei count, GLenum type, + const GLvoid *indices); + + +extern void _tnl_array_init( GLcontext *ctx ); +extern void _tnl_array_destroy( GLcontext *ctx ); + +#endif Index: dll/opengl/opengl32/mesa/tnl/t_array_import.c =================================================================== --- dll/opengl/opengl32/mesa/tnl/t_array_import.c (revision 0) +++ dll/opengl/opengl32/mesa/tnl/t_array_import.c (working copy) @@ -0,0 +1,497 @@ +/* $Id: t_array_import.c,v 1.17 2001/05/17 11:33:33 keithw Exp $ */ + +/* + * Mesa 3-D graphics library + * Version: 3.5 + * + * Copyright (C) 1999-2001 Brian Paul 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 + * BRIAN PAUL 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. + * + * Authors: + * Keith Whitwell + */ + +#include "glheader.h" +#include "context.h" +#include "macros.h" +#include "mem.h" +#include "mmath.h" +#include "state.h" +#include "mtypes.h" + +#include "array_cache/acache.h" +#include "math/m_translate.h" + +#include "t_array_import.h" +#include "t_context.h" +#include "t_imm_debug.h" + + +static void _tnl_import_vertex( GLcontext *ctx, + GLboolean writeable, + GLboolean stride ) +{ + struct gl_client_array *tmp; + GLboolean is_writeable = 0; + struct vertex_arrays *inputs = &TNL_CONTEXT(ctx)->array_inputs; + + tmp = _ac_import_vertex(ctx, + GL_FLOAT, + stride ? 4*sizeof(GLfloat) : 0, + 0, + writeable, + &is_writeable); + + inputs->Obj.data = (GLfloat (*)[4]) tmp->Ptr; + inputs->Obj.start = (GLfloat *) tmp->Ptr; + inputs->Obj.stride = tmp->StrideB; + inputs->Obj.size = tmp->Size; + inputs->Obj.flags &= ~(VEC_BAD_STRIDE|VEC_NOT_WRITEABLE); + if (inputs->Obj.stride != 4*sizeof(GLfloat)) + inputs->Obj.flags |= VEC_BAD_STRIDE; + if (!is_writeable) + inputs->Obj.flags |= VEC_NOT_WRITEABLE; +} + +static void _tnl_import_normal( GLcontext *ctx, + GLboolean writeable, + GLboolean stride ) +{ + struct gl_client_array *tmp; + GLboolean is_writeable = 0; + struct vertex_arrays *inputs = &TNL_CONTEXT(ctx)->array_inputs; + + tmp = _ac_import_normal(ctx, GL_FLOAT, + stride ? 3*sizeof(GLfloat) : 0, writeable, + &is_writeable); + + inputs->Normal.data = (GLfloat (*)[3]) tmp->Ptr; + inputs->Normal.start = (GLfloat *) tmp->Ptr; + inputs->Normal.stride = tmp->StrideB; + inputs->Normal.flags &= ~(VEC_BAD_STRIDE|VEC_NOT_WRITEABLE); + if (inputs->Normal.stride != 3*sizeof(GLfloat)) + inputs->Normal.flags |= VEC_BAD_STRIDE; + if (!is_writeable) + inputs->Normal.flags |= VEC_NOT_WRITEABLE; +} + + +static void _tnl_import_color( GLcontext *ctx, + GLenum type, + GLboolean writeable, + GLboolean stride ) +{ + struct gl_client_array *tmp; + GLboolean is_writeable = 0; + struct vertex_arrays *inputs = &TNL_CONTEXT(ctx)->array_inputs; + + tmp = _ac_import_color(ctx, + type, + stride ? 4*sizeof(GLfloat) : 0, + 4, + writeable, + &is_writeable); + + inputs->Color = *tmp; +} + + +static void _tnl_import_secondarycolor( GLcontext *ctx, + GLenum type, + GLboolean writeable, + GLboolean stride ) +{ + struct gl_client_array *tmp; + GLboolean is_writeable = 0; + struct vertex_arrays *inputs = &TNL_CONTEXT(ctx)->array_inputs; + + tmp = _ac_import_secondarycolor(ctx, + type, + stride ? 4*sizeof(GLfloat) : 0, + 4, + writeable, + &is_writeable); + + inputs->SecondaryColor = *tmp; +} + +static void _tnl_import_fogcoord( GLcontext *ctx, + GLboolean writeable, + GLboolean stride ) +{ + struct vertex_arrays *inputs = &TNL_CONTEXT(ctx)->array_inputs; + struct gl_client_array *tmp; + GLboolean is_writeable = 0; + + tmp = _ac_import_fogcoord(ctx, GL_FLOAT, + stride ? sizeof(GLfloat) : 0, writeable, + &is_writeable); + + inputs->FogCoord.data = (GLfloat *) tmp->Ptr; + inputs->FogCoord.start = (GLfloat *) tmp->Ptr; + inputs->FogCoord.stride = tmp->StrideB; + inputs->FogCoord.flags &= ~(VEC_BAD_STRIDE|VEC_NOT_WRITEABLE); + if (inputs->FogCoord.stride != sizeof(GLfloat)) + inputs->FogCoord.flags |= VEC_BAD_STRIDE; + if (!is_writeable) + inputs->FogCoord.flags |= VEC_NOT_WRITEABLE; +} + +static void _tnl_import_index( GLcontext *ctx, + GLboolean writeable, + GLboolean stride ) +{ + struct vertex_arrays *inputs = &TNL_CONTEXT(ctx)->array_inputs; + struct gl_client_array *tmp; + GLboolean is_writeable = 0; + + tmp = _ac_import_index(ctx, GL_UNSIGNED_INT, + stride ? sizeof(GLuint) : 0, writeable, + &is_writeable); + + inputs->Index.data = (GLuint *) tmp->Ptr; + inputs->Index.start = (GLuint *) tmp->Ptr; + inputs->Index.stride = tmp->StrideB; + inputs->Index.flags &= ~(VEC_BAD_STRIDE|VEC_NOT_WRITEABLE); + if (inputs->Index.stride != sizeof(GLuint)) + inputs->Index.flags |= VEC_BAD_STRIDE; + if (!is_writeable) + inputs->Index.flags |= VEC_NOT_WRITEABLE; +} + + +static void _tnl_import_texcoord( GLcontext *ctx, + GLuint i, + GLboolean writeable, + GLboolean stride ) +{ + struct vertex_arrays *inputs = &TNL_CONTEXT(ctx)->array_inputs; + struct gl_client_array *tmp; + GLboolean is_writeable = 0; + + tmp = _ac_import_texcoord(ctx, i, GL_FLOAT, + stride ? 4*sizeof(GLfloat) : 0, + 0, + writeable, + &is_writeable); + + inputs->TexCoord[i].data = (GLfloat (*)[4]) tmp->Ptr; + inputs->TexCoord[i].start = (GLfloat *) tmp->Ptr; + inputs->TexCoord[i].stride = tmp->StrideB; + inputs->TexCoord[i].size = tmp->Size; + inputs->TexCoord[i].flags &= ~(VEC_BAD_STRIDE|VEC_NOT_WRITEABLE); + if (inputs->TexCoord[i].stride != 4*sizeof(GLfloat)) + inputs->TexCoord[i].flags |= VEC_BAD_STRIDE; + if (!is_writeable) + inputs->TexCoord[i].flags |= VEC_NOT_WRITEABLE; +} + + +static void _tnl_import_edgeflag( GLcontext *ctx, + GLboolean writeable, + GLboolean stride ) +{ + struct vertex_arrays *inputs = &TNL_CONTEXT(ctx)->array_inputs; + struct gl_client_array *tmp; + GLboolean is_writeable = 0; + + tmp = _ac_import_edgeflag(ctx, GL_UNSIGNED_BYTE, + stride ? sizeof(GLubyte) : 0, + 0, + &is_writeable); + + inputs->EdgeFlag.data = (GLubyte *) tmp->Ptr; + inputs->EdgeFlag.start = (GLubyte *) tmp->Ptr; + inputs->EdgeFlag.stride = tmp->StrideB; + inputs->EdgeFlag.flags &= ~(VEC_BAD_STRIDE|VEC_NOT_WRITEABLE); + if (inputs->EdgeFlag.stride != sizeof(GLubyte)) + inputs->EdgeFlag.flags |= VEC_BAD_STRIDE; + if (!is_writeable) + inputs->EdgeFlag.flags |= VEC_NOT_WRITEABLE; +} + + + +/* Callback for VB stages that need to improve the quality of arrays + * bound to the VB. This is only necessary for client arrays which + * have not been transformed at any point in the pipeline. + */ +static void _tnl_upgrade_client_data( GLcontext *ctx, + GLuint required, + GLuint flags ) +{ + GLuint i; + struct vertex_buffer *VB = &TNL_CONTEXT(ctx)->vb; + GLboolean writeable = (flags & VEC_NOT_WRITEABLE) != 0; + GLboolean stride = (flags & VEC_BAD_STRIDE) != 0; + struct vertex_arrays *inputs = &TNL_CONTEXT(ctx)->array_inputs; + GLuint ca_flags = 0; + (void) inputs; + + if (writeable || stride) ca_flags |= CA_CLIENT_DATA; + + if ((required & VERT_CLIP) && VB->ClipPtr == VB->ObjPtr) + required |= VERT_OBJ; + +/* _tnl_print_vert_flags("_tnl_upgrade_client_data", required); */ + + if ((required & VERT_OBJ) && (VB->ObjPtr->flags & flags)) { + ASSERT(VB->ObjPtr == &inputs->Obj); + _tnl_import_vertex( ctx, writeable, stride ); + VB->importable_data &= ~(VERT_OBJ|VERT_CLIP); + } + + if ((required & VERT_NORM) && (VB->NormalPtr->flags & flags)) { + ASSERT(VB->NormalPtr == &inputs->Normal); + _tnl_import_normal( ctx, writeable, stride ); + VB->importable_data &= ~VERT_NORM; + } + + if ((required & VERT_RGBA) && (VB->ColorPtr[0]->Flags & ca_flags)) { + ASSERT(VB->ColorPtr[0] == &inputs->Color); + _tnl_import_color( ctx, GL_FLOAT, writeable, stride ); + VB->importable_data &= ~VERT_RGBA; + } + + if ((required & VERT_SPEC_RGB) && + (VB->SecondaryColorPtr[0]->Flags & ca_flags)) { + ASSERT(VB->SecondaryColorPtr[0] == &inputs->SecondaryColor); + _tnl_import_secondarycolor( ctx, GL_FLOAT, writeable, stride ); + VB->importable_data &= ~VERT_SPEC_RGB; + } + + if ((required & VERT_FOG_COORD) && (VB->FogCoordPtr->flags & flags)) { + ASSERT(VB->FogCoordPtr == &inputs->FogCoord); + _tnl_import_fogcoord( ctx, writeable, stride ); + VB->importable_data &= ~VERT_FOG_COORD; + } + + if ((required & VERT_INDEX) && (VB->IndexPtr[0]->flags & flags)) { + ASSERT(VB->IndexPtr[0] == &inputs->Index); + _tnl_import_index( ctx, writeable, stride ); + VB->importable_data &= ~VERT_INDEX; + } + + if (required & VERT_TEX_ANY) + for (i = 0 ; i < ctx->Const.MaxTextureUnits ; i++) + if ((required & VERT_TEX(i)) && (VB->TexCoordPtr[i]->flags & flags)) { + ASSERT(VB->TexCoordPtr[i] == &inputs->TexCoord[i]); + _tnl_import_texcoord( ctx, i, writeable, stride ); + VB->importable_data &= ~VERT_TEX(i); + } + +} + + + +void _tnl_vb_bind_arrays( GLcontext *ctx, GLint start, GLsizei count ) +{ + TNLcontext *tnl = TNL_CONTEXT(ctx); + struct vertex_buffer *VB = &tnl->vb; + GLuint inputs = tnl->pipeline.inputs; + struct vertex_arrays *tmp = &tnl->array_inputs; + GLuint i; + +/* fprintf(stderr, "%s %d..%d // %d..%d\n", __FUNCTION__, */ +/* start, count, ctx->Array.LockFirst, ctx->Array.LockCount); */ +/* _tnl_print_vert_flags(" inputs", inputs); */ +/* _tnl_print_vert_flags(" _Enabled", ctx->Array._Enabled); */ +/* _tnl_print_vert_flags(" importable", inputs & VERT_FIXUP); */ + + VB->Count = count - start; + VB->FirstClipped = VB->Count; + VB->Elts = 0; + VB->MaterialMask = 0; + VB->Material = 0; + VB->Flag = 0; + VB->Primitive = tnl->tmp_primitive; + VB->PrimitiveLength = tnl->tmp_primitive_length; + VB->import_data = _tnl_upgrade_client_data; + VB->importable_data = inputs & VERT_FIXUP; + + if (ctx->Array.LockCount) { + ASSERT(start == (GLint) ctx->Array.LockFirst); + ASSERT(count == (GLint) ctx->Array.LockCount); + } + + _ac_import_range( ctx, start, count ); + + if (inputs & VERT_OBJ) { + _tnl_import_vertex( ctx, 0, 0 ); + tmp->Obj.count = VB->Count; + VB->ObjPtr = &tmp->Obj; + } + + if (inputs & VERT_NORM) { + _tnl_import_normal( ctx, 0, 0 ); + tmp->Normal.count = VB->Count; + VB->NormalPtr = &tmp->Normal; + } + + if (inputs & VERT_RGBA) { + _tnl_import_color( ctx, 0, 0, 0 ); + VB->ColorPtr[0] = &tmp->Color; + VB->ColorPtr[1] = 0; + } + + if (inputs & VERT_TEX_ANY) { + for (i = 0; i < ctx->Const.MaxTextureUnits ; i++) { + if (inputs & VERT_TEX(i)) { + _tnl_import_texcoord( ctx, i, 0, 0 ); + tmp->TexCoord[i].count = VB->Count; + VB->TexCoordPtr[i] = &tmp->TexCoord[i]; + } + } + } + + if (inputs & (VERT_INDEX|VERT_FOG_COORD|VERT_EDGE|VERT_SPEC_RGB)) { + if (inputs & VERT_INDEX) { + _tnl_import_index( ctx, 0, 0 ); + tmp->Index.count = VB->Count; + VB->IndexPtr[0] = &tmp->Index; + VB->IndexPtr[1] = 0; + } + + if (inputs & VERT_FOG_COORD) { + _tnl_import_fogcoord( ctx, 0, 0 ); + tmp->FogCoord.count = VB->Count; + VB->FogCoordPtr = &tmp->FogCoord; + } + + if (inputs & VERT_EDGE) { + _tnl_import_edgeflag( ctx, GL_TRUE, sizeof(GLboolean) ); + VB->EdgeFlag = (GLboolean *) tmp->EdgeFlag.data; + } + + if (inputs & VERT_SPEC_RGB) { + _tnl_import_secondarycolor( ctx, 0, 0, 0 ); + VB->SecondaryColorPtr[0] = &tmp->SecondaryColor; + VB->SecondaryColorPtr[1] = 0; + } + } +} + + + + +/* Function to fill an immediate struct with the effects of + * consecutive calls to ArrayElement with consecutive indices. Used + * for display lists and very large fan-like primitives only. + */ +void _tnl_fill_immediate_drawarrays( GLcontext *ctx, struct immediate *IM, + GLuint start, GLuint count ) +{ + TNLcontext *tnl = TNL_CONTEXT(ctx); + GLuint required = ctx->Array._Enabled; + GLuint n = count - start; + GLuint i; + + if (!ctx->CompileFlag) + required &= tnl->pipeline.inputs; + + if (MESA_VERBOSE&VERBOSE_IMMEDIATE) + fprintf(stderr, "exec_full_array_elements %d .. %d\n", start, count); + + _math_trans_4f( IM->Obj + IM->Start, + ctx->Array.Vertex.Ptr, + ctx->Array.Vertex.StrideB, + ctx->Array.Vertex.Type, + ctx->Array.Vertex.Size, + start, n ); + + if (ctx->Array.Vertex.Size == 4) + required |= VERT_OBJ_234; + else if (ctx->Array.Vertex.Size == 3) + required |= VERT_OBJ_23; + + + if (required & VERT_NORM) { + _math_trans_3f( IM->Normal + IM->Start, + ctx->Array.Normal.Ptr, + ctx->Array.Normal.StrideB, + ctx->Array.Normal.Type, + start, n ); + } + + if (required & VERT_EDGE) { + _math_trans_1ub( IM->EdgeFlag + IM->Start, + ctx->Array.EdgeFlag.Ptr, + ctx->Array.EdgeFlag.StrideB, + ctx->Array.EdgeFlag.Type, + start, n ); + } + + if (required & VERT_RGBA) { + _math_trans_4f( IM->Color + IM->Start, + ctx->Array.Color.Ptr, + ctx->Array.Color.StrideB, + ctx->Array.Color.Type, + ctx->Array.Color.Size, + start, n ); + } + + if (required & VERT_SPEC_RGB) { + _math_trans_4f( IM->SecondaryColor + IM->Start, + ctx->Array.SecondaryColor.Ptr, + ctx->Array.SecondaryColor.StrideB, + ctx->Array.SecondaryColor.Type, + ctx->Array.SecondaryColor.Size, + start, n ); + } + + if (required & VERT_FOG_COORD) { + _math_trans_1f( IM->FogCoord + IM->Start, + ctx->Array.FogCoord.Ptr, + ctx->Array.FogCoord.StrideB, + ctx->Array.FogCoord.Type, + start, n ); + } + + if (required & VERT_INDEX) { + _math_trans_1ui( IM->Index + IM->Start, + ctx->Array.Index.Ptr, + ctx->Array.Index.StrideB, + ctx->Array.Index.Type, + start, n ); + } + + if (required & VERT_TEX_ANY) { + for (i = 0 ; i < ctx->Const.MaxTextureUnits ; i++) { + if (required & VERT_TEX(i)) { + _math_trans_4f( IM->TexCoord[i] + IM->Start, + ctx->Array.TexCoord[i].Ptr, + ctx->Array.TexCoord[i].StrideB, + ctx->Array.TexCoord[i].Type, + ctx->Array.TexCoord[i].Size, + start, n ); + + if (ctx->Array.TexCoord[i].Size == 4) + IM->TexSize |= TEX_SIZE_4(i); + else if (ctx->Array.TexCoord[i].Size == 3) + IM->TexSize |= TEX_SIZE_3(i); + } + } + } + + IM->Count = IM->Start + n; + IM->Flag[IM->Start] &= IM->ArrayEltFlags; + IM->Flag[IM->Start] |= required; + for (i = IM->Start+1 ; i < IM->Count ; i++) + IM->Flag[i] = required; +} Index: dll/opengl/opengl32/mesa/tnl/t_array_import.h =================================================================== --- dll/opengl/opengl32/mesa/tnl/t_array_import.h (revision 0) +++ dll/opengl/opengl32/mesa/tnl/t_array_import.h (working copy) @@ -0,0 +1,41 @@ +/* $Id: t_array_import.h,v 1.3 2001/04/28 08:39:18 keithw Exp $ */ + +/* + * Mesa 3-D graphics library + * Version: 3.5 + * + * Copyright (C) 1999-2001 Brian Paul 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 + * BRIAN PAUL 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. + */ + +#ifndef _T_ARRAY_IMPORT_H +#define _T_ARRAY_IMPORT_H + +#include "mtypes.h" +#include "t_context.h" + +extern void _tnl_vb_bind_arrays( GLcontext *ctx, GLint start, GLsizei count ); + +extern void _tnl_fill_immediate_drawarrays( GLcontext *ctx, + struct immediate *IM, + GLuint start, GLuint count ) ; + +extern void _tnl_array_import_init( GLcontext *ctx ); + +#endif Index: dll/opengl/opengl32/mesa/tnl/t_context.c =================================================================== --- dll/opengl/opengl32/mesa/tnl/t_context.c (revision 0) +++ dll/opengl/opengl32/mesa/tnl/t_context.c (working copy) @@ -0,0 +1,224 @@ +/* $Id: t_context.c,v 1.19 2001/06/04 16:09:28 keithw Exp $ */ + +/* + * Mesa 3-D graphics library + * Version: 3.5 + * + * Copyright (C) 1999-2001 Brian Paul 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 + * BRIAN PAUL 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. + * + * Authors: + * Keith Whitwell + */ + + +#include "glheader.h" +#include "macros.h" +#include "mtypes.h" +#include "mem.h" +#include "dlist.h" +#include "vtxfmt.h" + +#include "t_context.h" +#include "t_array_api.h" +#include "t_eval_api.h" +#include "t_imm_alloc.h" +#include "t_imm_api.h" +#include "t_imm_exec.h" +#include "t_imm_dlist.h" +#include "t_pipeline.h" +#include "tnl.h" + +#ifndef THREADS +struct immediate *_tnl_CurrentInput = NULL; +#endif + + +void +_tnl_MakeCurrent( GLcontext *ctx, + GLframebuffer *drawBuffer, + GLframebuffer *readBuffer ) +{ +#ifndef THREADS + SET_IMMEDIATE( ctx, TNL_CURRENT_IM(ctx) ); +#endif +} + + +static void +install_driver_callbacks( GLcontext *ctx ) +{ + ctx->Driver.NewList = _tnl_NewList; + ctx->Driver.EndList = _tnl_EndList; + ctx->Driver.FlushVertices = _tnl_flush_vertices; + ctx->Driver.MakeCurrent = _tnl_MakeCurrent; + ctx->Driver.BeginCallList = _tnl_BeginCallList; + ctx->Driver.EndCallList = _tnl_EndCallList; +} + + + +GLboolean +_tnl_CreateContext( GLcontext *ctx ) +{ + TNLcontext *tnl; + + /* Create the TNLcontext structure + */ + ctx->swtnl_context = tnl = (TNLcontext *) CALLOC( sizeof(TNLcontext) ); + + if (!tnl) { + return GL_FALSE; + } + + /* Initialize the VB. + */ + tnl->vb.Size = MAX2( IMM_SIZE, + ctx->Const.MaxArrayLockSize + MAX_CLIPPED_VERTICES); + + + /* Initialize tnl state and tnl->vtxfmt. + */ + _tnl_dlist_init( ctx ); + _tnl_array_init( ctx ); + _tnl_imm_init( ctx ); + _tnl_eval_init( ctx ); + _tnl_install_pipeline( ctx, _tnl_default_pipeline ); + + + tnl->NeedProjCoords = GL_TRUE; + tnl->LoopbackDListCassettes = GL_FALSE; + + /* Hook our functions into exec and compile dispatch tables. + */ + _mesa_install_exec_vtxfmt( ctx, &tnl->vtxfmt ); + _mesa_install_save_vtxfmt( ctx, &tnl->vtxfmt ); + ctx->Save->CallList = _mesa_save_CallList; + ctx->Save->CallLists = _mesa_save_CallLists; + ctx->Save->EvalMesh1 = _mesa_save_EvalMesh1; + ctx->Save->EvalMesh2 = _mesa_save_EvalMesh2; + ctx->Save->Begin = _tnl_save_Begin; + + /* Set a few default values in the driver struct. + */ + install_driver_callbacks(ctx); + ctx->Driver.NeedFlush = FLUSH_UPDATE_CURRENT; + ctx->Driver.CurrentExecPrimitive = PRIM_OUTSIDE_BEGIN_END; + ctx->Driver.CurrentSavePrimitive = PRIM_UNKNOWN; + + tnl->Driver.RenderTabElts = _tnl_render_tab_elts; + tnl->Driver.RenderTabVerts = _tnl_render_tab_verts; + + + return GL_TRUE; +} + + +void +_tnl_DestroyContext( GLcontext *ctx ) +{ + TNLcontext *tnl = TNL_CONTEXT(ctx); + + _tnl_array_destroy( ctx ); + _tnl_imm_destroy( ctx ); + _tnl_destroy_pipeline( ctx ); + + FREE(tnl); + ctx->swtnl_context = 0; +} + + +void +_tnl_InvalidateState( GLcontext *ctx, GLuint new_state ) +{ + TNLcontext *tnl = TNL_CONTEXT(ctx); + + if (new_state & _NEW_ARRAY) { + struct immediate *IM = TNL_CURRENT_IM(ctx); + IM->ArrayEltFlags = ~ctx->Array._Enabled; + IM->ArrayEltFlush = (ctx->Array.LockCount + ? FLUSH_ELT_LAZY : FLUSH_ELT_EAGER); + IM->ArrayEltIncr = ctx->Array.Vertex.Enabled ? 1 : 0; + tnl->pipeline.run_input_changes |= ctx->Array.NewState; /* overkill */ + } + + tnl->pipeline.run_state_changes |= new_state; + tnl->pipeline.build_state_changes |= (new_state & + tnl->pipeline.build_state_trigger); + + tnl->eval.EvalNewState |= new_state; +} + + +void +_tnl_wakeup_exec( GLcontext *ctx ) +{ + TNLcontext *tnl = TNL_CONTEXT(ctx); + + install_driver_callbacks(ctx); + ctx->Driver.NeedFlush |= FLUSH_UPDATE_CURRENT; + + /* Hook our functions into exec and compile dispatch tables. + */ + _mesa_install_exec_vtxfmt( ctx, &tnl->vtxfmt ); + + /* Call all appropriate driver callbacks to revive state. + */ + _tnl_MakeCurrent( ctx, ctx->DrawBuffer, ctx->ReadBuffer ); + + /* Assume we haven't been getting state updates either: + */ + _tnl_InvalidateState( ctx, ~0 ); + tnl->pipeline.run_input_changes = ~0; +} + + +void +_tnl_wakeup_save_exec( GLcontext *ctx ) +{ + TNLcontext *tnl = TNL_CONTEXT(ctx); + + _tnl_wakeup_exec( ctx ); + _mesa_install_save_vtxfmt( ctx, &tnl->vtxfmt ); + ctx->Save->CallList = _mesa_save_CallList; /* fixme */ + ctx->Save->CallLists = _mesa_save_CallLists; + ctx->Save->EvalMesh1 = _mesa_save_EvalMesh1; /* fixme */ + ctx->Save->EvalMesh2 = _mesa_save_EvalMesh2; + ctx->Save->Begin = _tnl_save_Begin; +} + + +void +_tnl_need_projected_coords( GLcontext *ctx, GLboolean mode ) +{ + TNLcontext *tnl = TNL_CONTEXT(ctx); + if (tnl->NeedProjCoords != mode) { + tnl->NeedProjCoords = mode; + _tnl_InvalidateState( ctx, _NEW_PROJECTION ); + } +} + +void +_tnl_need_dlist_loopback( GLcontext *ctx, GLboolean mode ) +{ + TNLcontext *tnl = TNL_CONTEXT(ctx); + if (tnl->LoopbackDListCassettes != mode) { + tnl->LoopbackDListCassettes = mode; + } +} Index: dll/opengl/opengl32/mesa/tnl/t_context.h =================================================================== --- dll/opengl/opengl32/mesa/tnl/t_context.h (revision 0) +++ dll/opengl/opengl32/mesa/tnl/t_context.h (working copy) @@ -0,0 +1,570 @@ +/* $Id: t_context.h,v 1.28 2001/06/04 16:09:28 keithw Exp $ */ + +/* + * Mesa 3-D graphics library + * Version: 3.5 + * + * Copyright (C) 1999-2001 Brian Paul 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 + * BRIAN PAUL 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. + * + * Author: + * Keith Whitwell + */ + +#ifndef _T_CONTEXT_H +#define _T_CONTEXT_H + +#include "glheader.h" +#include "mtypes.h" + +#include "math/m_matrix.h" +#include "math/m_vector.h" +#include "math/m_xform.h" + + +#define MAX_PIPELINE_STAGES 30 + + +/* Numbers for sizing immediate structs. + */ +#define IMM_MAX_COPIED_VERTS 3 +#define IMM_MAXDATA (216 + IMM_MAX_COPIED_VERTS) +#define IMM_SIZE (IMM_MAXDATA + MAX_CLIPPED_VERTICES) + + +/* Values for IM->BeginState + */ +#define VERT_BEGIN_0 0x1 /* glBegin (if initially inside beg/end) */ +#define VERT_BEGIN_1 0x2 /* glBegin (if initially outside beg/end) */ +#define VERT_ERROR_0 0x4 /* invalid_operation in initial state 0 */ +#define VERT_ERROR_1 0x8 /* invalid_operation in initial state 1 */ + + +/* Flags to be added to the primitive enum in VB->Primitive. + */ +#define PRIM_MODE_MASK 0xff /* Extract the actual primitive */ +#define PRIM_BEGIN 0x100 /* The prim starts here (not wrapped) */ +#define PRIM_END 0x200 /* The prim ends in this VB (does not wrap) */ +#define PRIM_PARITY 0x400 /* The prim wrapped on an odd number of verts */ +#define PRIM_LAST 0x800 /* No more prims in the VB */ + + +/* Flags that describe the inputs and outputs of pipeline stages, and + * the contents of a vertex-cassette. + * + * 5 spare flags, rearrangement of eval flags can secure at least 3 + * more. + */ +#define VERT_OBJ _NEW_ARRAY_VERTEX +#define VERT_RGBA _NEW_ARRAY_COLOR +#define VERT_NORM _NEW_ARRAY_NORMAL +#define VERT_INDEX _NEW_ARRAY_INDEX +#define VERT_EDGE _NEW_ARRAY_EDGEFLAG +#define VERT_SPEC_RGB _NEW_ARRAY_SECONDARYCOLOR +#define VERT_FOG_COORD _NEW_ARRAY_FOGCOORD +#define VERT_TEX0 _NEW_ARRAY_TEXCOORD_0 +#define VERT_TEX1 _NEW_ARRAY_TEXCOORD_1 +#define VERT_TEX2 _NEW_ARRAY_TEXCOORD_2 +#define VERT_TEX3 _NEW_ARRAY_TEXCOORD_3 +#define VERT_TEX4 _NEW_ARRAY_TEXCOORD_4 +#define VERT_TEX5 _NEW_ARRAY_TEXCOORD_5 +#define VERT_TEX6 _NEW_ARRAY_TEXCOORD_6 +#define VERT_TEX7 _NEW_ARRAY_TEXCOORD_7 +#define VERT_EVAL_C1 0x8000 /* imm only */ +#define VERT_EVAL_C2 0x10000 /* imm only */ +#define VERT_EVAL_P1 0x20000 /* imm only */ +#define VERT_EVAL_P2 0x40000 /* imm only */ +#define VERT_OBJ_3 0x80000 /* imm only */ +#define VERT_OBJ_4 0x100000 /* imm only */ +#define VERT_MATERIAL 0x200000 /* imm only, but tested in vb code */ +#define VERT_ELT 0x400000 /* imm only */ +#define VERT_BEGIN 0x800000 /* imm only, but tested in vb code */ +#define VERT_END 0x1000000 /* imm only, but tested in vb code */ +#define VERT_END_VB 0x2000000 /* imm only, but tested in vb code */ +#define VERT_POINT_SIZE 0x4000000 /* vb only, could reuse a bit */ +#define VERT_EYE VERT_BEGIN /* vb only, reuse imm bit */ +#define VERT_CLIP VERT_END /* vb only, reuse imm bit*/ + + +/* Flags for IM->TexCoordSize. Enough flags for 16 units. + */ +#define TEX_0_SIZE_3 0x1 +#define TEX_0_SIZE_4 0x1001 +#define TEX_SIZE_3(unit) (TEX_0_SIZE_3< vertices whose indexes are in the + * array. + */ + + void (*RenderClippedLine)( GLcontext *ctx, GLuint v0, GLuint v1 ); + /* Render a line between the two vertices given by indexes v0 and v1. */ + + points_func PointsFunc; /* must now respect vb->elts */ + line_func LineFunc; + triangle_func TriangleFunc; + quad_func QuadFunc; + /* These functions are called in order to render points, lines, + * triangles and quads. These are only called via the T&L module. + */ + + render_func *RenderTabVerts; + render_func *RenderTabElts; + /* Render whole unclipped primitives (points, lines, linestrips, + * lineloops, etc). The tables are indexed by the GL enum of the + * primitive to be rendered. RenderTabVerts is used for non-indexed + * arrays of vertices. RenderTabElts is used for indexed arrays of + * vertices. + */ + + void (*ResetLineStipple)( GLcontext *ctx ); + /* Reset the hardware's line stipple counter. + */ + + void (*BuildProjectedVertices)( GLcontext *ctx, + GLuint start, GLuint end, + GLuint new_inputs); + /* This function is called whenever new vertices are required for + * rendering. The vertices in question are those n such that start + * <= n < end. The new_inputs parameter indicates those fields of + * the vertex which need to be updated, if only a partial repair of + * the vertex is required. + * + * This function is called only from _tnl_render_stage in tnl/t_render.c. + */ + + + GLboolean (*MultipassFunc)( GLcontext *ctx, GLuint passno ); + /* Driver may request additional render passes by returning GL_TRUE + * when this function is called. This function will be called + * after the first pass, and passes will be made until the function + * returns GL_FALSE. If no function is registered, only one pass + * is made. + * + * This function will be first invoked with passno == 1. + */ +}; + + +typedef struct { + + /* Driver interface. + */ + struct tnl_device_driver Driver; + + /* Track whether the module is active. + */ + GLboolean bound_exec; + + /* Display list extensions + */ + GLuint opcode_vertex_cassette; + + /* Pipeline + */ + struct gl_pipeline pipeline; + struct vertex_buffer vb; + + /* GLvectors for binding to vb: + */ + struct vertex_arrays imm_inputs; + struct vertex_arrays array_inputs; + GLuint *tmp_primitive; + GLuint *tmp_primitive_length; + + /* Set when executing an internally generated begin/end object. If + * such an object is encountered in a display list, it will be + * replayed only if the list is outside any existing begin/end + * objects. + */ + GLboolean ReplayHardBeginEnd; + + /* Note which vertices need copying over succesive immediates. + * Will add save versions to precompute vertex copying where + * possible. + */ + struct immediate *ExecCopySource; + GLuint ExecCopyCount; + GLuint ExecCopyElts[IMM_MAX_COPIED_VERTS]; + GLuint ExecCopyTexSize; + GLuint ExecParity; + + GLuint DlistPrimitive; + GLuint DlistPrimitiveLength; + GLuint DlistLastPrimitive; + + /* Cache a single free immediate (refcount == 0) + */ + struct immediate *freed_immediate; + + /* Probably need a better configuration mechanism: + */ + GLboolean NeedProjCoords; + GLboolean LoopbackDListCassettes; + + /* Derived state and storage for _tnl_eval_vb: + */ + struct tnl_eval_store eval; + + /* Functions to be plugged into dispatch when tnl is active. + */ + GLvertexformat vtxfmt; + +} TNLcontext; + + + +#define TNL_CONTEXT(ctx) ((TNLcontext *)(ctx->swtnl_context)) +#define TNL_CURRENT_IM(ctx) ((struct immediate *)(ctx->swtnl_im)) + + +#define TYPE_IDX(t) ((t) & 0xf) +#define MAX_TYPES TYPE_IDX(GL_DOUBLE)+1 /* 0xa + 1 */ + +extern void _tnl_MakeCurrent( GLcontext *ctx, + GLframebuffer *drawBuffer, + GLframebuffer *readBuffer ); + + +/* + * Macros for fetching current input buffer. + */ +#ifdef THREADS +#define GET_IMMEDIATE struct immediate *IM = TNL_CURRENT_IM(((GLcontext *) (_glapi_Context ? _glapi_Context : _glapi_get_context()))) +#define SET_IMMEDIATE(ctx, im) ctx->swtnl_im = (void *)im +#else +extern struct immediate *_tnl_CurrentInput; +#define GET_IMMEDIATE struct immediate *IM = _tnl_CurrentInput +#define SET_IMMEDIATE(ctx, im) \ +do { \ + ctx->swtnl_im = (void *)im; \ + _tnl_CurrentInput = im; \ +} while (0) +#endif + + +#endif Index: dll/opengl/opengl32/mesa/tnl/t_eval_api.c =================================================================== --- dll/opengl/opengl32/mesa/tnl/t_eval_api.c (revision 0) +++ dll/opengl/opengl32/mesa/tnl/t_eval_api.c (working copy) @@ -0,0 +1,231 @@ +/* $Id: t_eval_api.c,v 1.7 2001/05/14 09:00:51 keithw Exp $ */ + +/* + * Mesa 3-D graphics library + * Version: 3.5 + * + * Copyright (C) 1999-2001 Brian Paul 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 + * BRIAN PAUL 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. + */ + + +#include "glheader.h" +#include "colormac.h" +#include "context.h" +#include "macros.h" +#include "mem.h" +#include "mmath.h" +#include "mtypes.h" +#include "math/m_eval.h" + +#include "t_eval_api.h" +#include "t_imm_api.h" +#include "t_imm_alloc.h" +#include "t_imm_exec.h" + + + + + +/* KW: If are compiling, we don't know whether eval will produce a + * vertex when it is run in the future. If this is pure immediate + * mode, eval is a noop if neither vertex map is enabled. + * + * Thus we need to have a check in the display list code or + * elsewhere for eval(1,2) vertices in the case where + * map(1,2)_vertex is disabled, and to purge those vertices from + * the vb. + */ +void +_tnl_exec_EvalMesh1( GLenum mode, GLint i1, GLint i2 ) +{ + GET_CURRENT_CONTEXT(ctx); + GLint i; + GLfloat u, du; + GLenum prim; + ASSERT_OUTSIDE_BEGIN_END(ctx); + +/* fprintf(stderr, "%s\n", __FUNCTION__); */ + + switch (mode) { + case GL_POINT: + prim = GL_POINTS; + break; + case GL_LINE: + prim = GL_LINE_STRIP; + break; + default: + _mesa_error( ctx, GL_INVALID_ENUM, "glEvalMesh1(mode)" ); + return; + } + + /* No effect if vertex maps disabled. + */ + if (!ctx->Eval.Map1Vertex4 && !ctx->Eval.Map1Vertex3) + return; + + du = ctx->Eval.MapGrid1du; + u = ctx->Eval.MapGrid1u1 + i1 * du; + + /* Need to turn off compilation -- this is already saved, and the + * coordinates generated and the test above depend on state that + * may change before the list is executed. + * + * TODO: Anaylse display lists to determine if this state is + * constant. + * + * State to watch: + * - enabled maps + * - map state for each enabled map, including control points + * - grid state + * + * Could alternatively cache individual maps in arrays, rather than + * building immediates. + */ + { + GLboolean compiling = ctx->CompileFlag; + struct immediate *im = TNL_CURRENT_IM(ctx); + + if (compiling) { + FLUSH_VERTICES( ctx, 0 ); + SET_IMMEDIATE( ctx, _tnl_alloc_immediate( ctx ) ); + TNL_CURRENT_IM(ctx)->ref_count++; + ctx->CompileFlag = GL_FALSE; + } + + _tnl_hard_begin( ctx, prim ); + for (i=i1;i<=i2;i++,u+=du) { + _tnl_eval_coord1f( ctx, u ); + } + _tnl_end(ctx); + + /* Need this for replay *and* compile: + */ + FLUSH_VERTICES( ctx, 0 ); + + if (compiling) { + TNL_CURRENT_IM(ctx)->ref_count--; + ASSERT( TNL_CURRENT_IM(ctx)->ref_count == 0 ); + _tnl_free_immediate( TNL_CURRENT_IM(ctx) ); + SET_IMMEDIATE( ctx, im ); + ctx->CompileFlag = GL_TRUE; + } + } +} + + + +void +_tnl_exec_EvalMesh2( GLenum mode, GLint i1, GLint i2, GLint j1, GLint j2 ) +{ + GET_CURRENT_CONTEXT(ctx); + GLint i, j; + GLfloat u, du, v, dv, v1, u1; + ASSERT_OUTSIDE_BEGIN_END(ctx); + +/* fprintf(stderr, "%s\n", __FUNCTION__); */ + + /* No effect if vertex maps disabled. + */ + if (!ctx->Eval.Map2Vertex4 && !ctx->Eval.Map2Vertex3) + return; + + + du = ctx->Eval.MapGrid2du; + dv = ctx->Eval.MapGrid2dv; + v1 = ctx->Eval.MapGrid2v1 + j1 * dv; + u1 = ctx->Eval.MapGrid2u1 + i1 * du; + + /* Need to turn off compilation -- this is already saved, and the + * coordinates generated and the test above depend on state that + * may change before the list is executed. + */ + { + GLboolean compiling = ctx->CompileFlag; + struct immediate *im = TNL_CURRENT_IM(ctx); + + if (compiling) { + FLUSH_VERTICES( ctx, 0 ); + SET_IMMEDIATE( ctx, _tnl_alloc_immediate( ctx ) ); + TNL_CURRENT_IM(ctx)->ref_count++; + ctx->CompileFlag = GL_FALSE; + } + + switch (mode) { + case GL_POINT: + _tnl_hard_begin( ctx, GL_POINTS ); + for (v=v1,j=j1;j<=j2;j++,v+=dv) { + for (u=u1,i=i1;i<=i2;i++,u+=du) { + _tnl_eval_coord2f( ctx, u, v ); + } + } + _tnl_end(ctx); + break; + case GL_LINE: + for (v=v1,j=j1;j<=j2;j++,v+=dv) { + _tnl_hard_begin( ctx, GL_LINE_STRIP ); + for (u=u1,i=i1;i<=i2;i++,u+=du) { + _tnl_eval_coord2f( ctx, u, v ); + } + _tnl_end(ctx); + } + for (u=u1,i=i1;i<=i2;i++,u+=du) { + _tnl_hard_begin( ctx, GL_LINE_STRIP ); + for (v=v1,j=j1;j<=j2;j++,v+=dv) { + _tnl_eval_coord2f( ctx, u, v ); + } + _tnl_end(ctx); + } + break; + case GL_FILL: + for (v=v1,j=j1;jref_count--; + _tnl_free_immediate( TNL_CURRENT_IM( ctx ) ); + SET_IMMEDIATE( ctx, im ); + ctx->CompileFlag = GL_TRUE; + } + } +} + + + +void _tnl_eval_init( GLcontext *ctx ) +{ + GLvertexformat *vfmt = &(TNL_CONTEXT(ctx)->vtxfmt); + vfmt->EvalMesh1 = _tnl_exec_EvalMesh1; + vfmt->EvalMesh2 = _tnl_exec_EvalMesh2; +} Index: dll/opengl/opengl32/mesa/tnl/t_eval_api.h =================================================================== --- dll/opengl/opengl32/mesa/tnl/t_eval_api.h (revision 0) +++ dll/opengl/opengl32/mesa/tnl/t_eval_api.h (working copy) @@ -0,0 +1,44 @@ +/* $Id: t_eval_api.h,v 1.2 2001/03/12 00:48:43 gareth Exp $ */ + +/* + * Mesa 3-D graphics library + * Version: 3.5 + * + * Copyright (C) 1999-2001 Brian Paul 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 + * BRIAN PAUL 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. + */ + + +#ifndef _T_EVAL_H +#define _T_EVAL_H + + +#include "mtypes.h" +#include "t_context.h" + +/* Use _mesa_save_EvalMesh{1,2} to save these to display lists. + */ +extern void _tnl_exec_EvalMesh1( GLenum mode, GLint i1, GLint i2 ); + +extern void _tnl_exec_EvalMesh2( GLenum mode, GLint i1, GLint i2, + GLint j1, GLint j2 ); + +void _tnl_eval_init( GLcontext *ctx ); + +#endif Index: dll/opengl/opengl32/mesa/tnl/t_imm_alloc.c =================================================================== --- dll/opengl/opengl32/mesa/tnl/t_imm_alloc.c (revision 0) +++ dll/opengl/opengl32/mesa/tnl/t_imm_alloc.c (working copy) @@ -0,0 +1,138 @@ +/* $Id: t_imm_alloc.c,v 1.8 2001/05/09 13:53:36 keithw Exp $ */ + +/* + * Mesa 3-D graphics library + * Version: 3.5 + * + * Copyright (C) 1999-2001 Brian Paul 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 + * BRIAN PAUL 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. + * + * Authors: + * Keith Whitwell + */ + +#include "glheader.h" +#include "mem.h" +#include "mtypes.h" + +#include "t_imm_alloc.h" + + + static int id = 0; + +static struct immediate *real_alloc_immediate( GLcontext *ctx ) +{ + struct immediate *IM = ALIGN_MALLOC_STRUCT( immediate, 32 ); + GLuint j; + + if (!IM) + return 0; + +/* memset(IM, 0, sizeof(*IM)); */ + + IM->id = id++; + IM->ref_count = 0; + IM->backref = ctx; + IM->FlushElt = 0; + IM->LastPrimitive = IMM_MAX_COPIED_VERTS; + IM->Count = IMM_MAX_COPIED_VERTS; + IM->Start = IMM_MAX_COPIED_VERTS; + IM->Material = 0; + IM->MaterialMask = 0; + IM->MaxTextureUnits = ctx->Const.MaxTextureUnits; + IM->TexSize = 0; + + IM->CopyTexSize = 0; + IM->CopyStart = IM->Start; + + + /* TexCoord0 is special. + */ + IM->TexCoord[0] = IM->TexCoord0; + + for (j = 1; j < ctx->Const.MaxTextureUnits; j++) { + IM->TexCoord[j] = (GLfloat (*)[4]) + ALIGN_MALLOC( IMM_SIZE * sizeof(GLfloat) * 4, 32 ); + } + + /* KW: Removed initialization of normals as these are now treated + * identically to all other data types. + */ + + MEMSET(IM->Flag, 0, sizeof(IM->Flag)); + + return IM; +} + + +static void real_free_immediate( struct immediate *IM ) +{ + static int freed = 0; + GLuint j; + + if (IM->Material) { + FREE( IM->Material ); + FREE( IM->MaterialMask ); + IM->Material = 0; + IM->MaterialMask = 0; + } + + for (j = 1; j < IM->MaxTextureUnits; j++) + ALIGN_FREE( IM->TexCoord[j] ); + + + ALIGN_FREE( IM ); + freed++; +/* printf("outstanding %d\n", id - freed); */ +} + + +/* Cache a single allocated immediate struct. + */ +struct immediate *_tnl_alloc_immediate( GLcontext *ctx ) +{ + TNLcontext *tnl = TNL_CONTEXT(ctx); + struct immediate *tmp = tnl->freed_immediate; + + if (tmp) { + tnl->freed_immediate = 0; + return tmp; + } + else + return real_alloc_immediate( ctx ); +} + +/* May be called after tnl is destroyed. + */ +void _tnl_free_immediate( struct immediate *IM ) +{ + TNLcontext *tnl = TNL_CONTEXT(IM->backref); + + ASSERT(IM->ref_count == 0); + + if (!tnl) { + real_free_immediate( IM ); + } + else { + if (tnl->freed_immediate) + real_free_immediate( tnl->freed_immediate ); + + tnl->freed_immediate = IM; + } +} Index: dll/opengl/opengl32/mesa/tnl/t_imm_alloc.h =================================================================== --- dll/opengl/opengl32/mesa/tnl/t_imm_alloc.h (revision 0) +++ dll/opengl/opengl32/mesa/tnl/t_imm_alloc.h (working copy) @@ -0,0 +1,40 @@ +/* $Id: t_imm_alloc.h,v 1.2 2001/03/12 00:48:43 gareth Exp $ */ + +/* + * Mesa 3-D graphics library + * Version: 3.5 + * + * Copyright (C) 1999-2001 Brian Paul 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 + * BRIAN PAUL 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. + */ + + +#ifndef _T_IMM_ALLOC_H +#define _T_IMM_ALLOC_H + +#include "mtypes.h" +#include "t_context.h" + + +extern struct immediate *_tnl_alloc_immediate( GLcontext *ctx ); + +extern void _tnl_free_immediate( struct immediate *im ); + + +#endif Index: dll/opengl/opengl32/mesa/tnl/t_imm_api.c =================================================================== --- dll/opengl/opengl32/mesa/tnl/t_imm_api.c (revision 0) +++ dll/opengl/opengl32/mesa/tnl/t_imm_api.c (working copy) @@ -0,0 +1,1273 @@ +/* $Id: t_imm_api.c,v 1.16 2001/06/15 15:22:08 brianp Exp $ */ + +/* + * Mesa 3-D graphics library + * Version: 3.5 + * + * Copyright (C) 1999-2001 Brian Paul 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 + * BRIAN PAUL 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. + * + * Authors: + * Keith Whitwell + */ + + + +#include "glheader.h" +#include "context.h" +#include "dlist.h" +#include "enums.h" +#include "light.h" +#include "mem.h" +#include "state.h" +#include "colormac.h" +#include "macros.h" + +#include "t_context.h" +#include "t_imm_api.h" +#include "t_imm_elt.h" +#include "t_imm_exec.h" +#include "t_imm_dlist.h" + + +/* A cassette is full or flushed on a statechange. + */ +void _tnl_flush_immediate( struct immediate *IM ) +{ + GLcontext *ctx = IM->backref; + + if (IM->FlushElt == FLUSH_ELT_EAGER) { + _tnl_translate_array_elts( ctx, IM, IM->LastPrimitive, IM->Count ); + } + + /* Mark the last primitive: + */ + IM->PrimitiveLength[IM->LastPrimitive] = IM->Count - IM->LastPrimitive; + IM->Primitive[IM->LastPrimitive] |= PRIM_LAST; + + if (ctx->CompileFlag) + _tnl_compile_cassette( ctx, IM ); + else + _tnl_execute_cassette( ctx, IM ); +} + + +void _tnl_flush_vertices( GLcontext *ctx, GLuint flags ) +{ + struct immediate *IM = TNL_CURRENT_IM(ctx); + + if (IM->Flag[IM->Start]) + if ((flags & FLUSH_UPDATE_CURRENT) || IM->Count > IM->Start) + _tnl_flush_immediate( IM ); +} + + + + +/* Note the ctx argument. This function called only by _tnl_Begin, + * _tnl_save_Begin and _tnl_hard_begin() in this file. + */ +static void +_tnl_begin( GLcontext *ctx, GLenum p ) +{ + struct immediate *IM = TNL_CURRENT_IM(ctx); + GLuint inflags, state; + + if (MESA_VERBOSE&VERBOSE_API) + fprintf(stderr, "glBegin(IM %d) %s\n", IM->id, + _mesa_lookup_enum_by_nr(p)); + + if (ctx->NewState) + _mesa_update_state(ctx); + + /* if only a very few slots left, might as well flush now + */ + if (IM->Count > IMM_MAXDATA-8) { + _tnl_flush_immediate( IM ); + IM = TNL_CURRENT_IM(ctx); + } + + /* Check for and flush buffered vertices from internal operations. + */ + if (IM->SavedBeginState) { + _tnl_flush_immediate( IM ); + IM = TNL_CURRENT_IM(ctx); + IM->BeginState = IM->SavedBeginState; + IM->SavedBeginState = 0; + } + + state = IM->BeginState; + inflags = state & (VERT_BEGIN_0|VERT_BEGIN_1); + state |= inflags << 2; /* set error conditions */ + + if (inflags != (VERT_BEGIN_0|VERT_BEGIN_1)) + { + GLuint count = IM->Count; + GLuint last = IM->LastPrimitive; + + state |= (VERT_BEGIN_0|VERT_BEGIN_1); + IM->Flag[count] |= VERT_BEGIN; + IM->Primitive[count] = p | PRIM_BEGIN; + IM->PrimitiveLength[IM->LastPrimitive] = count - IM->LastPrimitive; + IM->LastPrimitive = count; + + /* Not quite right. Need to use the fallback '_aa_ArrayElement' + * when not known to be inside begin/end and arrays are + * unlocked. + */ + if (IM->FlushElt == FLUSH_ELT_EAGER) { + _tnl_translate_array_elts( ctx, IM, last, count ); + } + } + + ctx->Driver.NeedFlush |= FLUSH_STORED_VERTICES; + IM->BeginState = state; +} + + +void +_tnl_save_Begin( GLenum mode ) +{ + GET_CURRENT_CONTEXT(ctx); + + if (mode > GL_POLYGON) { + _mesa_compile_error( ctx, GL_INVALID_ENUM, "glBegin" ); + return; + } + + _tnl_begin( ctx, mode ); + + /* Update save_primitive now. + */ + if (ctx->Driver.CurrentSavePrimitive == PRIM_UNKNOWN) + ctx->Driver.CurrentSavePrimitive = PRIM_INSIDE_UNKNOWN_PRIM; + else if (ctx->Driver.CurrentSavePrimitive == PRIM_OUTSIDE_BEGIN_END) + ctx->Driver.CurrentSavePrimitive = mode; +} + +static void +_tnl_Begin( GLenum mode ) +{ + GET_CURRENT_CONTEXT(ctx); + + if (mode > GL_POLYGON) { + _mesa_compile_error( ctx, GL_INVALID_ENUM, "glBegin" ); + return; + } + + _tnl_begin(ctx, mode); + + /* Update exec_primitive now. + */ + ASSERT (!ctx->CompileFlag); + if (ctx->Driver.CurrentExecPrimitive == PRIM_OUTSIDE_BEGIN_END) { + ctx->Driver.CurrentExecPrimitive = mode; + } +} + + +/* Function which allows operations like 'glRectf' to decompose to a + * begin/end object and vertices without worrying about what happens + * with display lists. + */ +GLboolean +_tnl_hard_begin( GLcontext *ctx, GLenum p ) +{ + if (!ctx->CompileFlag) { + /* If not compiling, treat as a normal begin(). + */ + _tnl_begin( ctx, p ); + ASSERT(ctx->Driver.CurrentExecPrimitive == PRIM_OUTSIDE_BEGIN_END); + ctx->Driver.CurrentExecPrimitive = p; + return GL_TRUE; + } + else { + /* Otherwise, need to do special processing to preserve the + * condition that these vertices will only be replayed outside + * future begin/end objects. + */ + struct immediate *IM = TNL_CURRENT_IM(ctx); + + if (ctx->NewState) + _mesa_update_state(ctx); + + if (IM->Count > IMM_MAXDATA-8) { + _tnl_flush_immediate( IM ); + IM = TNL_CURRENT_IM(ctx); + } + + /* A lot depends on the degree to which the display list has + * constrained the possible begin/end states at this point: + */ + switch (IM->BeginState & (VERT_BEGIN_0|VERT_BEGIN_1)) { + case VERT_BEGIN_0|VERT_BEGIN_1: + /* This is an immediate known to be inside a begin/end object. + */ + ASSERT(ctx->Driver.CurrentSavePrimitive <= GL_POLYGON); + IM->BeginState |= (VERT_ERROR_1|VERT_ERROR_0); + return GL_FALSE; + + case VERT_BEGIN_0: + case VERT_BEGIN_1: + /* This is a display-list immediate in an unknown begin/end + * state. Assert it is empty and convert it to a 'hard' one. + */ + ASSERT(IM->SavedBeginState == 0); + ASSERT(ctx->Driver.CurrentSavePrimitive == PRIM_UNKNOWN); + + /* Push current beginstate, to be restored later. Don't worry + * about raising errors. + */ + IM->SavedBeginState = IM->BeginState; + + /* FALLTHROUGH */ + + case 0: + /* Unless we have fallen through, this is an immediate known to + * be outside begin/end objects. + */ + ASSERT(ctx->Driver.CurrentSavePrimitive == PRIM_UNKNOWN || + ctx->Driver.CurrentSavePrimitive == PRIM_OUTSIDE_BEGIN_END); + ASSERT (IM->FlushElt != FLUSH_ELT_EAGER); + + IM->BeginState |= VERT_BEGIN_0|VERT_BEGIN_1; + IM->Flag[IM->Count] |= VERT_BEGIN; + IM->Primitive[IM->Count] = p | PRIM_BEGIN; + IM->PrimitiveLength[IM->LastPrimitive] = IM->Count - IM->LastPrimitive; + IM->LastPrimitive = IM->Count; + + /* This is necessary as this immediate will not be flushed in + * _tnl_end() -- we leave it active, hoping to pick up more + * vertices before the next state change. + */ + ctx->Driver.NeedFlush |= FLUSH_STORED_VERTICES; + return GL_TRUE; + + default: + ASSERT (0); + return GL_TRUE; + } + } +} + + + + + + +/* Both streams now outside begin/end. + * + * Leave SavedBeginState untouched -- attempt to gather several + * rects/arrays together in a single immediate struct. + */ +void +_tnl_end( GLcontext *ctx ) +{ + struct immediate *IM = TNL_CURRENT_IM(ctx); + GLuint state = IM->BeginState; + GLuint inflags = (~state) & (VERT_BEGIN_0|VERT_BEGIN_1); + + state |= inflags << 2; /* errors */ + + if (inflags != (VERT_BEGIN_0|VERT_BEGIN_1)) + { + GLuint count = IM->Count; + GLuint last = IM->LastPrimitive; + + state &= ~(VERT_BEGIN_0|VERT_BEGIN_1); /* update state */ + IM->Flag[count] |= VERT_END; + IM->Primitive[last] |= PRIM_END; + IM->PrimitiveLength[last] = count - last; + IM->Primitive[count] = PRIM_OUTSIDE_BEGIN_END; /* removes PRIM_BEGIN + * flag if length == 0 + */ + IM->LastPrimitive = count; + + if (IM->FlushElt == FLUSH_ELT_EAGER) { + _tnl_translate_array_elts( ctx, IM, last, count ); + } + } + + IM->BeginState = state; + + if (!ctx->CompileFlag) { + ctx->Driver.CurrentExecPrimitive = PRIM_OUTSIDE_BEGIN_END; + } + + /* You can set this flag to get the old 'flush_vb on glEnd()' + * behaviour. + */ + if ((MESA_DEBUG_FLAGS&DEBUG_ALWAYS_FLUSH)) + _tnl_flush_immediate( IM ); +} + +static void +_tnl_End(void) +{ + GET_CURRENT_CONTEXT(ctx); + _tnl_end( ctx ); + + /* Need to keep save primitive uptodate in COMPILE and + * COMPILE_AND_EXEC modes, need to keep exec primitive uptodate + * otherwise. + */ + if (ctx->CompileFlag) + ctx->Driver.CurrentSavePrimitive = PRIM_OUTSIDE_BEGIN_END; +} + + +#define COLOR( IM, r, g, b, a ) \ +{ \ + GLuint count = IM->Count; \ + IM->Flag[count] |= VERT_RGBA; \ + IM->Color[count][0] = r; \ + IM->Color[count][1] = g; \ + IM->Color[count][2] = b; \ + IM->Color[count][3] = a; \ +} + +static void +_tnl_Color3f( GLfloat red, GLfloat green, GLfloat blue ) +{ + GET_IMMEDIATE; + COLOR( IM, red, green, blue, 1.0 ); +} + +static void +_tnl_Color3ub( GLubyte red, GLubyte green, GLubyte blue ) +{ + GET_IMMEDIATE; + COLOR(IM, + UBYTE_TO_FLOAT(red), + UBYTE_TO_FLOAT(green), + UBYTE_TO_FLOAT(blue), + 1.0); +} + +static void +_tnl_Color4f( GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha ) +{ + GET_IMMEDIATE; + COLOR( IM, red, green, blue, alpha ); +} + +static void +_tnl_Color4ub( GLubyte red, GLubyte green, GLubyte blue, GLubyte alpha ) +{ + GET_IMMEDIATE; + COLOR(IM, + UBYTE_TO_FLOAT(red), + UBYTE_TO_FLOAT(green), + UBYTE_TO_FLOAT(blue), + UBYTE_TO_FLOAT(alpha)); +} + +static void +_tnl_Color3fv( const GLfloat *v ) +{ + GET_IMMEDIATE; + COLOR( IM, v[0], v[1], v[2], 1.0 ); +} + +static void +_tnl_Color3ubv( const GLubyte *v ) +{ + GET_IMMEDIATE; + COLOR(IM, + UBYTE_TO_FLOAT(v[0]), + UBYTE_TO_FLOAT(v[1]), + UBYTE_TO_FLOAT(v[2]), + 1.0 ); +} + +static void +_tnl_Color4fv( const GLfloat *v ) +{ + GET_IMMEDIATE; + COLOR( IM, v[0], v[1], v[2], v[3] ); +} + +static void +_tnl_Color4ubv( const GLubyte *v) +{ + GET_IMMEDIATE; + COLOR(IM, + UBYTE_TO_FLOAT(v[0]), + UBYTE_TO_FLOAT(v[1]), + UBYTE_TO_FLOAT(v[2]), + UBYTE_TO_FLOAT(v[3])); +} + + + + +#define SECONDARY_COLOR( IM, r, g, b ) \ +{ \ + GLuint count = IM->Count; \ + IM->Flag[count] |= VERT_SPEC_RGB; \ + IM->SecondaryColor[count][0] = r; \ + IM->SecondaryColor[count][1] = g; \ + IM->SecondaryColor[count][2] = b; \ +} + +static void +_tnl_SecondaryColor3fEXT( GLfloat red, GLfloat green, GLfloat blue ) +{ + GET_IMMEDIATE; + SECONDARY_COLOR( IM, red, green, blue ); +} + +static void +_tnl_SecondaryColor3ubEXT( GLubyte red, GLubyte green, GLubyte blue ) +{ + GET_IMMEDIATE; + SECONDARY_COLOR(IM, + UBYTE_TO_FLOAT(red), + UBYTE_TO_FLOAT(green), + UBYTE_TO_FLOAT(blue)); +} + +static void +_tnl_SecondaryColor3fvEXT( const GLfloat *v ) +{ + GET_IMMEDIATE; + SECONDARY_COLOR( IM, v[0], v[1], v[2] ); +} + +static void +_tnl_SecondaryColor3ubvEXT( const GLubyte *v ) +{ + GET_IMMEDIATE; + SECONDARY_COLOR(IM, + UBYTE_TO_FLOAT(v[0]), + UBYTE_TO_FLOAT(v[1]), + UBYTE_TO_FLOAT(v[2])); +} + + + + +static void +_tnl_EdgeFlag( GLboolean flag ) +{ + GLuint count; + GET_IMMEDIATE; + count = IM->Count; + IM->EdgeFlag[count] = flag; + IM->Flag[count] |= VERT_EDGE; +} + + +static void +_tnl_EdgeFlagv( const GLboolean *flag ) +{ + GLuint count; + GET_IMMEDIATE; + count = IM->Count; + IM->EdgeFlag[count] = *flag; + IM->Flag[count] |= VERT_EDGE; +} + + +static void +_tnl_FogCoordfEXT( GLfloat f ) +{ + GLuint count; + GET_IMMEDIATE; + count = IM->Count; + IM->FogCoord[count] = f; + IM->Flag[count] |= VERT_FOG_COORD; +} + +static void +_tnl_FogCoordfvEXT( const GLfloat *v ) +{ + GLuint count; + GET_IMMEDIATE; + count = IM->Count; + IM->FogCoord[count] = v[0]; + IM->Flag[count] |= VERT_FOG_COORD; +} + + +static void +_tnl_Indexi( GLint c ) +{ + GLuint count; + GET_IMMEDIATE; + count = IM->Count; + IM->Index[count] = c; + IM->Flag[count] |= VERT_INDEX; +} + + +static void +_tnl_Indexiv( const GLint *c ) +{ + GLuint count; + GET_IMMEDIATE; + count = IM->Count; + IM->Index[count] = *c; + IM->Flag[count] |= VERT_INDEX; +} + + +#define NORMAL( x, y, z ) \ +{ \ + GLuint count; \ + GLfloat *normal; \ + GET_IMMEDIATE; \ + count = IM->Count; \ + IM->Flag[count] |= VERT_NORM; \ + normal = IM->Normal[count]; \ + ASSIGN_3V(normal, x,y,z); \ +} + +#if defined(USE_IEEE) +#define NORMALF( x, y, z ) \ +{ \ + GLuint count; \ + fi_type *normal; \ + GET_IMMEDIATE; \ + count = IM->Count; \ + IM->Flag[count] |= VERT_NORM; \ + normal = (fi_type *)IM->Normal[count]; \ + normal[0].i = ((fi_type *)&(x))->i; \ + normal[1].i = ((fi_type *)&(y))->i; \ + normal[2].i = ((fi_type *)&(z))->i; \ +} +#else +#define NORMALF NORMAL +#endif + +static void +_tnl_Normal3f( GLfloat nx, GLfloat ny, GLfloat nz ) +{ + NORMALF(nx, ny, nz); +} + + +static void +_tnl_Normal3fv( const GLfloat *v ) +{ + NORMALF( v[0], v[1], v[2] ); +} + + + +#define TEXCOORD1(s) \ +{ \ + GLuint count; \ + GLfloat *tc; \ + GET_IMMEDIATE; \ + count = IM->Count; \ + IM->Flag[count] |= VERT_TEX0; \ + tc = IM->TexCoord0[count]; \ + ASSIGN_4V(tc,s,0,0,1); \ +} + +#define TEXCOORD2(s,t) \ +{ \ + GLuint count; \ + GLfloat *tc; \ + GET_IMMEDIATE; \ + count = IM->Count; \ + IM->Flag[count] |= VERT_TEX0; \ + tc = IM->TexCoord0[count]; \ + ASSIGN_4V(tc, s,t,0,1); \ +} + +#define TEXCOORD3(s,t,u) \ +{ \ + GLuint count; \ + GLfloat *tc; \ + GET_IMMEDIATE; \ + count = IM->Count; \ + IM->Flag[count] |= VERT_TEX0; \ + IM->TexSize |= TEX_0_SIZE_3; \ + tc = IM->TexCoord0[count]; \ + ASSIGN_4V(tc, s,t,u,1); \ +} + +#define TEXCOORD4(s,t,u,v) \ +{ \ + GLuint count; \ + GLfloat *tc; \ + GET_IMMEDIATE; \ + count = IM->Count; \ + IM->Flag[count] |= VERT_TEX0; \ + IM->TexSize |= TEX_0_SIZE_4; \ + tc = IM->TexCoord0[count]; \ + ASSIGN_4V(tc, s,t,u,v); \ +} + +#if defined(USE_IEEE) +#define TEXCOORD2F(s,t) \ +{ \ + GLuint count; \ + fi_type *tc; \ + GET_IMMEDIATE; \ + count = IM->Count; \ + IM->Flag[count] |= VERT_TEX0; \ + tc = (fi_type *)IM->TexCoord0[count]; \ + tc[0].i = ((fi_type *)&(s))->i; \ + tc[1].i = ((fi_type *)&(t))->i; \ + tc[2].i = 0; \ + tc[3].i = IEEE_ONE; \ +} +#else +#define TEXCOORD2F TEXCOORD2 +#endif + +static void +_tnl_TexCoord1f( GLfloat s ) +{ + TEXCOORD1(s); +} + + +static void +_tnl_TexCoord2f( GLfloat s, GLfloat t ) +{ + TEXCOORD2F(s,t); +} + + +static void +_tnl_TexCoord3f( GLfloat s, GLfloat t, GLfloat r ) +{ + TEXCOORD3(s,t,r); +} + +static void +_tnl_TexCoord4f( GLfloat s, GLfloat t, GLfloat r, GLfloat q ) +{ + TEXCOORD4(s,t,r,q) +} + +static void +_tnl_TexCoord1fv( const GLfloat *v ) +{ + TEXCOORD1(v[0]); +} + +static void +_tnl_TexCoord2fv( const GLfloat *v ) +{ + TEXCOORD2F(v[0],v[1]); +} + +static void +_tnl_TexCoord3fv( const GLfloat *v ) +{ + TEXCOORD3(v[0],v[1],v[2]); +} + +static void +_tnl_TexCoord4fv( const GLfloat *v ) +{ + TEXCOORD4(v[0],v[1],v[2],v[3]); +} + + + +/* KW: Run into bad problems in vertex copying if we don't fully pad + * the incoming vertices. + */ +#define VERTEX2(IM, x,y) \ +{ \ + GLuint count = IM->Count++; \ + GLfloat *dest = IM->Obj[count]; \ + IM->Flag[count] |= VERT_OBJ; \ + ASSIGN_4V(dest, x, y, 0, 1); \ +/* ASSERT(IM->Flag[IM->Count]==0); */\ + if (count == IMM_MAXDATA - 1) \ + _tnl_flush_immediate( IM ); \ +} + +#define VERTEX3(IM,x,y,z) \ +{ \ + GLuint count = IM->Count++; \ + GLfloat *dest = IM->Obj[count]; \ + IM->Flag[count] |= VERT_OBJ_23; \ + ASSIGN_4V(dest, x, y, z, 1); \ +/* ASSERT(IM->Flag[IM->Count]==0); */ \ + if (count == IMM_MAXDATA - 1) \ + _tnl_flush_immediate( IM ); \ +} + +#define VERTEX4(IM, x,y,z,w) \ +{ \ + GLuint count = IM->Count++; \ + GLfloat *dest = IM->Obj[count]; \ + IM->Flag[count] |= VERT_OBJ_234; \ + ASSIGN_4V(dest, x, y, z, w); \ + if (count == IMM_MAXDATA - 1) \ + _tnl_flush_immediate( IM ); \ +} + +#if defined(USE_IEEE) +#define VERTEX2F(IM, x, y) \ +{ \ + GLuint count = IM->Count++; \ + fi_type *dest = (fi_type *)IM->Obj[count]; \ + IM->Flag[count] |= VERT_OBJ; \ + dest[0].i = ((fi_type *)&(x))->i; \ + dest[1].i = ((fi_type *)&(y))->i; \ + dest[2].i = 0; \ + dest[3].i = IEEE_ONE; \ +/* ASSERT(IM->Flag[IM->Count]==0); */ \ + if (count == IMM_MAXDATA - 1) \ + _tnl_flush_immediate( IM ); \ +} +#else +#define VERTEX2F VERTEX2 +#endif + +#if defined(USE_IEEE) +#define VERTEX3F(IM, x, y, z) \ +{ \ + GLuint count = IM->Count++; \ + fi_type *dest = (fi_type *)IM->Obj[count]; \ + IM->Flag[count] |= VERT_OBJ_23; \ + dest[0].i = ((fi_type *)&(x))->i; \ + dest[1].i = ((fi_type *)&(y))->i; \ + dest[2].i = ((fi_type *)&(z))->i; \ + dest[3].i = IEEE_ONE; \ +/* ASSERT(IM->Flag[IM->Count]==0); */ \ + if (count == IMM_MAXDATA - 1) \ + _tnl_flush_immediate( IM ); \ +} +#else +#define VERTEX3F VERTEX3 +#endif + +#if defined(USE_IEEE) +#define VERTEX4F(IM, x, y, z, w) \ +{ \ + GLuint count = IM->Count++; \ + fi_type *dest = (fi_type *)IM->Obj[count]; \ + IM->Flag[count] |= VERT_OBJ_234; \ + dest[0].i = ((fi_type *)&(x))->i; \ + dest[1].i = ((fi_type *)&(y))->i; \ + dest[2].i = ((fi_type *)&(z))->i; \ + dest[3].i = ((fi_type *)&(w))->i; \ + if (count == IMM_MAXDATA - 1) \ + _tnl_flush_immediate( IM ); \ +} +#else +#define VERTEX4F VERTEX4 +#endif + + + +static void +_tnl_Vertex2f( GLfloat x, GLfloat y ) +{ + GET_IMMEDIATE; + VERTEX2F( IM, x, y ); +} + +static void +_tnl_Vertex3f( GLfloat x, GLfloat y, GLfloat z ) +{ + GET_IMMEDIATE; + VERTEX3F( IM, x, y, z ); +} +static void +_tnl_Vertex4f( GLfloat x, GLfloat y, GLfloat z, GLfloat w ) +{ + GET_IMMEDIATE; + VERTEX4F( IM, x, y, z, w ); +} + +static void +_tnl_Vertex2fv( const GLfloat *v ) +{ + GET_IMMEDIATE; + VERTEX2F( IM, v[0], v[1] ); +} + +static void +_tnl_Vertex3fv( const GLfloat *v ) +{ + GET_IMMEDIATE; + VERTEX3F( IM, v[0], v[1], v[2] ); +} + +static void +_tnl_Vertex4fv( const GLfloat *v ) +{ + GET_IMMEDIATE; + VERTEX4F( IM, v[0], v[1], v[2], v[3] ); +} + + + + +/* + * GL_ARB_multitexture + * + * Note: the multitexture spec says that specifying an invalid target + * has undefined results and does not have to generate an error. Just + * don't crash. We no-op on invalid targets. + */ + +#define MAX_TARGET (GL_TEXTURE0_ARB + MAX_TEXTURE_UNITS) + +#define MULTI_TEXCOORD1(target, s) \ +{ \ + GET_IMMEDIATE; \ + GLuint texunit = target - GL_TEXTURE0_ARB; \ + if (texunit < IM->MaxTextureUnits) { \ + GLuint count = IM->Count; \ + GLfloat *tc = IM->TexCoord[texunit][count]; \ + ASSIGN_4V(tc, s, 0.0F, 0.0F, 1.0F); \ + IM->Flag[count] |= VERT_TEX(texunit); \ + } \ +} + +#define MULTI_TEXCOORD2(target, s, t) \ +{ \ + GET_IMMEDIATE; \ + GLuint texunit = target - GL_TEXTURE0_ARB; \ + if (texunit < IM->MaxTextureUnits) { \ + GLuint count = IM->Count; \ + GLfloat *tc = IM->TexCoord[texunit][count]; \ + ASSIGN_4V(tc, s, t, 0.0F, 1.0F); \ + IM->Flag[count] |= VERT_TEX(texunit); \ + } \ +} + +#define MULTI_TEXCOORD3(target, s, t, u) \ +{ \ + GET_IMMEDIATE; \ + GLuint texunit = target - GL_TEXTURE0_ARB; \ + if (texunit < IM->MaxTextureUnits) { \ + GLuint count = IM->Count; \ + GLfloat *tc = IM->TexCoord[texunit][count]; \ + ASSIGN_4V(tc, s, t, u, 1.0F); \ + IM->Flag[count] |= VERT_TEX(texunit); \ + IM->TexSize |= TEX_SIZE_3(texunit); \ + } \ +} + +#define MULTI_TEXCOORD4(target, s, t, u, v) \ +{ \ + GET_IMMEDIATE; \ + GLuint texunit = target - GL_TEXTURE0_ARB; \ + if (texunit < IM->MaxTextureUnits) { \ + GLuint count = IM->Count; \ + GLfloat *tc = IM->TexCoord[texunit][count]; \ + ASSIGN_4V(tc, s, t, u, v); \ + IM->Flag[count] |= VERT_TEX(texunit); \ + IM->TexSize |= TEX_SIZE_4(texunit); \ + } \ +} + +#if defined(USE_IEEE) +#define MULTI_TEXCOORD2F(target, s, t) \ +{ \ + GET_IMMEDIATE; \ + GLuint texunit = target - GL_TEXTURE0_ARB; \ + if (texunit < IM->MaxTextureUnits) { \ + GLuint count = IM->Count; \ + fi_type *tc = (fi_type *)IM->TexCoord[texunit][count]; \ + IM->Flag[count] |= VERT_TEX(texunit); \ + tc[0].i = ((fi_type *)&(s))->i; \ + tc[1].i = ((fi_type *)&(t))->i; \ + tc[2].i = 0; \ + tc[3].i = IEEE_ONE; \ + } \ +} +#else +#define MULTI_TEXCOORD2F MULTI_TEXCOORD2 +#endif + +static void +_tnl_MultiTexCoord1fARB(GLenum target, GLfloat s) +{ + MULTI_TEXCOORD1( target, s ); +} + +static void +_tnl_MultiTexCoord1fvARB(GLenum target, const GLfloat *v) +{ + MULTI_TEXCOORD1( target, v[0] ); +} + +static void +_tnl_MultiTexCoord2fARB(GLenum target, GLfloat s, GLfloat t) +{ + MULTI_TEXCOORD2F( target, s, t ); +} + +static void +_tnl_MultiTexCoord2fvARB(GLenum target, const GLfloat *v) +{ + MULTI_TEXCOORD2F( target, v[0], v[1] ); +} + +static void +_tnl_MultiTexCoord3fARB(GLenum target, GLfloat s, GLfloat t, GLfloat r) +{ + MULTI_TEXCOORD3( target, s, t, r ); +} + +static void +_tnl_MultiTexCoord3fvARB(GLenum target, const GLfloat *v) +{ + MULTI_TEXCOORD3( target, v[0], v[1], v[2] ); +} + +static void +_tnl_MultiTexCoord4fARB(GLenum target, GLfloat s, GLfloat t, GLfloat r, GLfloat q) +{ + MULTI_TEXCOORD4( target, s, t, r, q ); +} + +static void +_tnl_MultiTexCoord4fvARB(GLenum target, const GLfloat *v) +{ + MULTI_TEXCOORD4( target, v[0], v[1], v[2], v[3] ); +} + + + +/* KW: Because the eval values don't become 'current', fixup will flow + * through these vertices, and then evaluation will write on top + * of the fixup results. + * + * Note: using Obj to hold eval coord data. + */ +#define EVALCOORD1(IM, x) \ +{ \ + GLuint count = IM->Count++; \ + IM->Flag[count] |= VERT_EVAL_C1; \ + ASSIGN_4V(IM->Obj[count], x, 0, 0, 1); \ + if (count == IMM_MAXDATA-1) \ + _tnl_flush_immediate( IM ); \ +} + +#define EVALCOORD2(IM, x, y) \ +{ \ + GLuint count = IM->Count++; \ + IM->Flag[count] |= VERT_EVAL_C2; \ + ASSIGN_4V(IM->Obj[count], x, y, 0, 1); \ + if (count == IMM_MAXDATA-1) \ + _tnl_flush_immediate( IM ); \ +} + +#define EVALPOINT1(IM, x) \ +{ \ + GLuint count = IM->Count++; \ + IM->Flag[count] |= VERT_EVAL_P1; \ + ASSIGN_4V(IM->Obj[count], x, 0, 0, 1); \ + if (count == IMM_MAXDATA-1) \ + _tnl_flush_immediate( IM ); \ +} + +#define EVALPOINT2(IM, x, y) \ +{ \ + GLuint count = IM->Count++; \ + IM->Flag[count] |= VERT_EVAL_P2; \ + ASSIGN_4V(IM->Obj[count], x, y, 0, 1); \ + if (count == IMM_MAXDATA-1) \ + _tnl_flush_immediate( IM ); \ +} + +static void +_tnl_EvalCoord1f( GLfloat u ) +{ + GET_IMMEDIATE; + EVALCOORD1( IM, u ); +} + +static void +_tnl_EvalCoord1fv( const GLfloat *u ) +{ + GET_IMMEDIATE; + EVALCOORD1( IM, (GLfloat) *u ); +} + +static void +_tnl_EvalCoord2f( GLfloat u, GLfloat v ) +{ + GET_IMMEDIATE; + EVALCOORD2( IM, u, v ); +} + +static void +_tnl_EvalCoord2fv( const GLfloat *u ) +{ + GET_IMMEDIATE; + EVALCOORD2( IM, u[0], u[1] ); +} + + +static void +_tnl_EvalPoint1( GLint i ) +{ + GET_IMMEDIATE; + EVALPOINT1( IM, i ); +} + + +static void +_tnl_EvalPoint2( GLint i, GLint j ) +{ + GET_IMMEDIATE; + EVALPOINT2( IM, i, j ); +} + + +/* Need to use the default array-elt outside begin/end for strict + * conformance. + */ +#define ARRAY_ELT( IM, i ) \ +{ \ + GLuint count = IM->Count; \ + IM->Elt[count] = i; \ + IM->Flag[count] &= IM->ArrayEltFlags; \ + IM->Flag[count] |= VERT_ELT; \ + IM->FlushElt = IM->ArrayEltFlush; \ + IM->Count += IM->ArrayEltIncr; \ + if (IM->Count == IMM_MAXDATA) \ + _tnl_flush_immediate( IM ); \ +} + + +static void +_tnl_ArrayElement( GLint i ) +{ + GET_IMMEDIATE; + ARRAY_ELT( IM, i ); +} + + +/* Internal functions. These are safe to use providing either: + * + * - It is determined that a display list is not being compiled, or + * if so that these commands won't be compiled into the list (see + * t_eval.c for an example). + * + * - _tnl_hard_begin() is used instead of _tnl_[bB]egin, and tested + * for a GL_TRUE return value. See _tnl_Rectf, below. + */ +void +_tnl_eval_coord1f( GLcontext *CC, GLfloat u ) +{ + struct immediate *i = TNL_CURRENT_IM(CC); + EVALCOORD1( i, u ); +} + +void +_tnl_eval_coord2f( GLcontext *CC, GLfloat u, GLfloat v ) +{ + struct immediate *i = TNL_CURRENT_IM(CC); + EVALCOORD2( i, u, v ); +} + +void +_tnl_array_element( GLcontext *CC, GLint i ) +{ + struct immediate *im = TNL_CURRENT_IM(CC); + ARRAY_ELT( im, i ); +} + +void +_tnl_vertex2f( GLcontext *ctx, GLfloat x, GLfloat y ) +{ + struct immediate *im = TNL_CURRENT_IM(ctx); + VERTEX2( im, x, y ); +} + + + + + +/* Execute a glRectf() function. _tnl_hard_begin() ensures the check + * on outside_begin_end is executed even in compiled lists. These + * vertices can now participate in the same immediate as regular ones, + * even in most display lists. + */ +static void +_tnl_Rectf( GLfloat x1, GLfloat y1, GLfloat x2, GLfloat y2 ) +{ + GET_CURRENT_CONTEXT(ctx); + +/* fprintf(stderr, "%s\n", __FUNCTION__); */ + + if (_tnl_hard_begin( ctx, GL_QUADS )) { + _tnl_vertex2f( ctx, x1, y1 ); + _tnl_vertex2f( ctx, x2, y1 ); + _tnl_vertex2f( ctx, x2, y2 ); + _tnl_vertex2f( ctx, x1, y2 ); + _tnl_end( ctx ); + } +} + +static void +_tnl_Materialfv( GLenum face, GLenum pname, const GLfloat *params ) +{ + GET_CURRENT_CONTEXT(ctx); + struct immediate *IM = TNL_CURRENT_IM(ctx); + GLuint count = IM->Count; + struct gl_material *mat; + GLuint bitmask = _mesa_material_bitmask(ctx, face, pname, ~0, "Materialfv"); + + if (bitmask == 0) + return; + + if (!(IM->Flag[count] & VERT_MATERIAL)) { + if (!IM->Material) { + IM->Material = (GLmaterial (*)[2]) MALLOC( sizeof(GLmaterial) * + IMM_SIZE * 2 ); + IM->MaterialMask = (GLuint *) MALLOC( sizeof(GLuint) * IMM_SIZE ); + IM->MaterialMask[IM->LastMaterial] = 0; + } + else if (IM->MaterialOrMask & ~bitmask) { + _mesa_copy_material_pairs( IM->Material[count], + IM->Material[IM->LastMaterial], + IM->MaterialOrMask & ~bitmask ); + } + + IM->Flag[count] |= VERT_MATERIAL; + IM->MaterialMask[count] = 0; + IM->MaterialAndMask &= IM->MaterialMask[IM->LastMaterial]; + IM->LastMaterial = count; + } + + IM->MaterialOrMask |= bitmask; + IM->MaterialMask[count] |= bitmask; + mat = IM->Material[count]; + + if (bitmask & FRONT_AMBIENT_BIT) { + COPY_4FV( mat[0].Ambient, params ); + } + if (bitmask & BACK_AMBIENT_BIT) { + COPY_4FV( mat[1].Ambient, params ); + } + if (bitmask & FRONT_DIFFUSE_BIT) { + COPY_4FV( mat[0].Diffuse, params ); + } + if (bitmask & BACK_DIFFUSE_BIT) { + COPY_4FV( mat[1].Diffuse, params ); + } + if (bitmask & FRONT_SPECULAR_BIT) { + COPY_4FV( mat[0].Specular, params ); + } + if (bitmask & BACK_SPECULAR_BIT) { + COPY_4FV( mat[1].Specular, params ); + } + if (bitmask & FRONT_EMISSION_BIT) { + COPY_4FV( mat[0].Emission, params ); + } + if (bitmask & BACK_EMISSION_BIT) { + COPY_4FV( mat[1].Emission, params ); + } + if (bitmask & FRONT_SHININESS_BIT) { + GLfloat shininess = CLAMP( params[0], 0.0F, 128.0F ); + mat[0].Shininess = shininess; + } + if (bitmask & BACK_SHININESS_BIT) { + GLfloat shininess = CLAMP( params[0], 0.0F, 128.0F ); + mat[1].Shininess = shininess; + } + if (bitmask & FRONT_INDEXES_BIT) { + mat[0].AmbientIndex = params[0]; + mat[0].DiffuseIndex = params[1]; + mat[0].SpecularIndex = params[2]; + } + if (bitmask & BACK_INDEXES_BIT) { + mat[1].AmbientIndex = params[0]; + mat[1].DiffuseIndex = params[1]; + mat[1].SpecularIndex = params[2]; + } +} + +void _tnl_imm_vtxfmt_init( GLcontext *ctx ) +{ + GLvertexformat *vfmt = &(TNL_CONTEXT(ctx)->vtxfmt); + + /* All begin/end operations are handled by this vertex format: + */ + vfmt->ArrayElement = _tnl_ArrayElement; + vfmt->Begin = _tnl_Begin; + vfmt->Color3f = _tnl_Color3f; + vfmt->Color3fv = _tnl_Color3fv; + vfmt->Color3ub = _tnl_Color3ub; + vfmt->Color3ubv = _tnl_Color3ubv; + vfmt->Color4f = _tnl_Color4f; + vfmt->Color4fv = _tnl_Color4fv; + vfmt->Color4ub = _tnl_Color4ub; + vfmt->Color4ubv = _tnl_Color4ubv; + vfmt->EdgeFlag = _tnl_EdgeFlag; + vfmt->EdgeFlagv = _tnl_EdgeFlagv; + vfmt->End = _tnl_End; + vfmt->EvalCoord1f = _tnl_EvalCoord1f; + vfmt->EvalCoord1fv = _tnl_EvalCoord1fv; + vfmt->EvalCoord2f = _tnl_EvalCoord2f; + vfmt->EvalCoord2fv = _tnl_EvalCoord2fv; + vfmt->EvalPoint1 = _tnl_EvalPoint1; + vfmt->EvalPoint2 = _tnl_EvalPoint2; + vfmt->FogCoordfEXT = _tnl_FogCoordfEXT; + vfmt->FogCoordfvEXT = _tnl_FogCoordfvEXT; + vfmt->Indexi = _tnl_Indexi; + vfmt->Indexiv = _tnl_Indexiv; + vfmt->Materialfv = _tnl_Materialfv; + vfmt->MultiTexCoord1fARB = _tnl_MultiTexCoord1fARB; + vfmt->MultiTexCoord1fvARB = _tnl_MultiTexCoord1fvARB; + vfmt->MultiTexCoord2fARB = _tnl_MultiTexCoord2fARB; + vfmt->MultiTexCoord2fvARB = _tnl_MultiTexCoord2fvARB; + vfmt->MultiTexCoord3fARB = _tnl_MultiTexCoord3fARB; + vfmt->MultiTexCoord3fvARB = _tnl_MultiTexCoord3fvARB; + vfmt->MultiTexCoord4fARB = _tnl_MultiTexCoord4fARB; + vfmt->MultiTexCoord4fvARB = _tnl_MultiTexCoord4fvARB; + vfmt->Normal3f = _tnl_Normal3f; + vfmt->Normal3fv = _tnl_Normal3fv; + vfmt->SecondaryColor3fEXT = _tnl_SecondaryColor3fEXT; + vfmt->SecondaryColor3fvEXT = _tnl_SecondaryColor3fvEXT; + vfmt->SecondaryColor3ubEXT = _tnl_SecondaryColor3ubEXT; + vfmt->SecondaryColor3ubvEXT = _tnl_SecondaryColor3ubvEXT; + vfmt->TexCoord1f = _tnl_TexCoord1f; + vfmt->TexCoord1fv = _tnl_TexCoord1fv; + vfmt->TexCoord2f = _tnl_TexCoord2f; + vfmt->TexCoord2fv = _tnl_TexCoord2fv; + vfmt->TexCoord3f = _tnl_TexCoord3f; + vfmt->TexCoord3fv = _tnl_TexCoord3fv; + vfmt->TexCoord4f = _tnl_TexCoord4f; + vfmt->TexCoord4fv = _tnl_TexCoord4fv; + vfmt->Vertex2f = _tnl_Vertex2f; + vfmt->Vertex2fv = _tnl_Vertex2fv; + vfmt->Vertex3f = _tnl_Vertex3f; + vfmt->Vertex3fv = _tnl_Vertex3fv; + vfmt->Vertex4f = _tnl_Vertex4f; + vfmt->Vertex4fv = _tnl_Vertex4fv; + + /* Outside begin/end functions (from t_varray.c, t_eval.c, ...): + */ + vfmt->Rectf = _tnl_Rectf; + + /* Just use the core function: + */ + vfmt->CallList = _mesa_CallList; + + vfmt->prefer_float_colors = GL_FALSE; +} Index: dll/opengl/opengl32/mesa/tnl/t_imm_api.h =================================================================== --- dll/opengl/opengl32/mesa/tnl/t_imm_api.h (revision 0) +++ dll/opengl/opengl32/mesa/tnl/t_imm_api.h (working copy) @@ -0,0 +1,51 @@ +/* $Id: t_imm_api.h,v 1.3 2001/03/12 00:48:43 gareth Exp $ */ + +/* + * Mesa 3-D graphics library + * Version: 3.5 + * + * Copyright (C) 1999-2001 Brian Paul 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 + * BRIAN PAUL 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. + */ + + +#ifndef _T_VTXFMT_H +#define _T_VTXFMT_H + +#include "mtypes.h" +#include "t_context.h" + + +extern void _tnl_save_Begin( GLenum mode ); + +/* TNL-private internal functions for building higher-level operations: + */ +extern GLboolean _tnl_hard_begin( GLcontext *ctx, GLenum p ); +extern void _tnl_end( GLcontext *ctx ); +extern void _tnl_vertex2f( GLcontext *ctx, GLfloat x, GLfloat y ); +extern void _tnl_eval_coord1f( GLcontext *CC, GLfloat u ); +extern void _tnl_eval_coord2f( GLcontext *CC, GLfloat u, GLfloat v ); +extern void _tnl_array_element( GLcontext *CC, GLint i ); + +/* Initialize our part of the vtxfmt struct: + */ +extern void _tnl_imm_vtxfmt_init( GLcontext *ctx ); + + +#endif Index: dll/opengl/opengl32/mesa/tnl/t_imm_debug.c =================================================================== --- dll/opengl/opengl32/mesa/tnl/t_imm_debug.c (revision 0) +++ dll/opengl/opengl32/mesa/tnl/t_imm_debug.c (working copy) @@ -0,0 +1,166 @@ +/* $Id: t_imm_debug.c,v 1.3 2001/04/28 08:39:18 keithw Exp $ */ + +/* + * Mesa 3-D graphics library + * Version: 3.5 + * + * Copyright (C) 1999-2001 Brian Paul 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 + * BRIAN PAUL 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. + */ + +#include "mtypes.h" +#include "t_context.h" +#include "t_imm_debug.h" + +void _tnl_print_vert_flags( const char *name, GLuint flags ) +{ + fprintf(stderr, + "%s: (0x%x) %s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s\n", + name, + flags, + (flags & VERT_CLIP) ? "clip/proj-clip/glend, " : "", + (flags & VERT_EDGE) ? "edgeflag, " : "", + (flags & VERT_ELT) ? "array-elt, " : "", + (flags & VERT_END_VB) ? "end-vb, " : "", + (flags & VERT_EVAL_ANY) ? "eval-coord, " : "", + (flags & VERT_EYE) ? "eye/glbegin, " : "", + (flags & VERT_FOG_COORD) ? "fog-coord, " : "", + (flags & VERT_INDEX) ? "index, " : "", + (flags & VERT_MATERIAL) ? "material, " : "", + (flags & VERT_NORM) ? "normals, " : "", + (flags & VERT_OBJ) ? "obj, " : "", + (flags & VERT_OBJ_3) ? "obj-3, " : "", + (flags & VERT_OBJ_4) ? "obj-4, " : "", + (flags & VERT_POINT_SIZE) ? "point-size, " : "", + (flags & VERT_RGBA) ? "colors, " : "", + (flags & VERT_SPEC_RGB) ? "specular, " : "", + (flags & VERT_TEX0) ? "texcoord0, " : "", + (flags & VERT_TEX1) ? "texcoord1, " : "", + (flags & VERT_TEX2) ? "texcoord2, " : "", + (flags & VERT_TEX3) ? "texcoord3, " : "", + (flags & VERT_TEX4) ? "texcoord4, " : "", + (flags & VERT_TEX5) ? "texcoord5, " : "", + (flags & VERT_TEX6) ? "texcoord6, " : "", + (flags & VERT_TEX7) ? "texcoord7, " : "" + ); +} + +void _tnl_print_cassette( struct immediate *IM ) +{ + GLuint i; + GLuint *flags = IM->Flag; + GLuint andflag = IM->CopyAndFlag; + GLuint orflag = IM->CopyOrFlag; + GLuint state = IM->BeginState; + GLuint req = ~0; + + fprintf(stderr, "Cassette id %d, %u rows.\n", IM->id, + IM->Count - IM->CopyStart); + + _tnl_print_vert_flags("Contains at least one", orflag); + + if (IM->Count != IM->CopyStart) + { + _tnl_print_vert_flags("Contains a full complement of", andflag); + + fprintf(stderr, "Final begin/end state %s/%s, errors %s/%s\n", + (state & VERT_BEGIN_0) ? "in" : "out", + (state & VERT_BEGIN_1) ? "in" : "out", + (state & VERT_ERROR_0) ? "y" : "n", + (state & VERT_ERROR_1) ? "y" : "n"); + + } + + for (i = IM->CopyStart ; i <= IM->Count ; i++) { + fprintf(stderr, "%u: ", i); + if (req & VERT_OBJ_234) { + if (flags[i] & VERT_EVAL_C1) + fprintf(stderr, "EvalCoord %f ", IM->Obj[i][0]); + else if (flags[i] & VERT_EVAL_P1) + fprintf(stderr, "EvalPoint %.0f ", IM->Obj[i][0]); + else if (flags[i] & VERT_EVAL_C2) + fprintf(stderr, "EvalCoord %f %f ", IM->Obj[i][0], IM->Obj[i][1]); + else if (flags[i] & VERT_EVAL_P2) + fprintf(stderr, "EvalPoint %.0f %.0f ", IM->Obj[i][0], IM->Obj[i][1]); + else if (i < IM->Count && (flags[i]&VERT_OBJ_234)) { + fprintf(stderr, "Obj %f %f %f %f", + IM->Obj[i][0], IM->Obj[i][1], IM->Obj[i][2], IM->Obj[i][3]); + } + } + + if (req & flags[i] & VERT_ELT) + fprintf(stderr, " Elt %u\t", IM->Elt[i]); + + if (req & flags[i] & VERT_NORM) + fprintf(stderr, " Norm %f %f %f ", + IM->Normal[i][0], IM->Normal[i][1], IM->Normal[i][2]); + + if (req & flags[i] & VERT_TEX_ANY) { + GLuint j; + for (j = 0 ; j < MAX_TEXTURE_UNITS ; j++) { + if (req & flags[i] & VERT_TEX(j)) { + fprintf(stderr, + "TC%d %f %f %f %f", + j, + IM->TexCoord[j][i][0], IM->TexCoord[j][i][1], + IM->TexCoord[j][i][2], IM->TexCoord[j][i][2]); + } + } + } + + if (req & flags[i] & VERT_RGBA) + fprintf(stderr, " Rgba %f %f %f %f ", + IM->Color[i][0], IM->Color[i][1], + IM->Color[i][2], IM->Color[i][3]); + + if (req & flags[i] & VERT_SPEC_RGB) + fprintf(stderr, " Spec %f %f %f ", + IM->SecondaryColor[i][0], IM->SecondaryColor[i][1], + IM->SecondaryColor[i][2]); + + if (req & flags[i] & VERT_FOG_COORD) + fprintf(stderr, " Fog %f ", IM->FogCoord[i]); + + if (req & flags[i] & VERT_INDEX) + fprintf(stderr, " Index %u ", IM->Index[i]); + + if (req & flags[i] & VERT_EDGE) + fprintf(stderr, " Edgeflag %d ", IM->EdgeFlag[i]); + + if (req & flags[i] & VERT_MATERIAL) + fprintf(stderr, " Material "); + + + /* The order of these two is not easily knowable, but this is + * the usually correct way to look at them. + */ + if (req & flags[i] & VERT_END) + fprintf(stderr, " END "); + + if (req & flags[i] & VERT_BEGIN) + fprintf(stderr, " BEGIN(%s) (%s%s%s%s)", + _mesa_prim_name[IM->Primitive[i] & PRIM_MODE_MASK], + (IM->Primitive[i] & PRIM_LAST) ? "LAST," : "", + (IM->Primitive[i] & PRIM_BEGIN) ? "BEGIN," : "", + (IM->Primitive[i] & PRIM_END) ? "END," : "", + (IM->Primitive[i] & PRIM_PARITY) ? "PARITY," : ""); + + fprintf(stderr, "\n"); + } +} Index: dll/opengl/opengl32/mesa/tnl/t_imm_debug.h =================================================================== --- dll/opengl/opengl32/mesa/tnl/t_imm_debug.h (revision 0) +++ dll/opengl/opengl32/mesa/tnl/t_imm_debug.h (working copy) @@ -0,0 +1,39 @@ +/* $Id: t_imm_debug.h,v 1.2 2001/03/12 00:48:43 gareth Exp $ */ + +/* + * Mesa 3-D graphics library + * Version: 3.5 + * + * Copyright (C) 1999-2001 Brian Paul 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 + * BRIAN PAUL 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. + * + * Authors: + * Keith Whitwell + */ + +#ifndef _T_DEBUG_H +#define _T_DEBUG_H + +#include "mtypes.h" +#include "t_context.h" + +void _tnl_print_cassette( struct immediate *IM ); +void _tnl_print_vert_flags( const char *name, GLuint flags ); + +#endif Index: dll/opengl/opengl32/mesa/tnl/t_imm_dlist.c =================================================================== --- dll/opengl/opengl32/mesa/tnl/t_imm_dlist.c (revision 0) +++ dll/opengl/opengl32/mesa/tnl/t_imm_dlist.c (working copy) @@ -0,0 +1,589 @@ +/* $Id: t_imm_dlist.c,v 1.20 2001/06/04 16:09:28 keithw Exp $ */ + +/* + * Mesa 3-D graphics library + * Version: 3.5 + * + * Copyright (C) 1999-2001 Brian Paul 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 + * BRIAN PAUL 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. + * + * Authors: + * Keith Whitwell + */ + + +#include "glheader.h" +#include "context.h" +#include "dlist.h" +#include "debug.h" +#include "mmath.h" +#include "mem.h" +#include "state.h" + +#include "t_context.h" +#include "t_imm_api.h" +#include "t_imm_elt.h" +#include "t_imm_alloc.h" +#include "t_imm_dlist.h" +#include "t_imm_debug.h" +#include "t_imm_exec.h" +#include "t_imm_fixup.h" +#include "t_pipeline.h" + +typedef struct { + struct immediate *IM; + GLuint Start; + GLuint Count; + GLuint BeginState; + GLuint SavedBeginState; + GLuint OrFlag; + GLuint AndFlag; + GLuint TexSize; + GLuint LastData; + GLuint LastPrimitive; + GLuint LastMaterial; + GLuint MaterialOrMask; + GLuint MaterialAndMask; +} TNLvertexcassette; + +static void execute_compiled_cassette( GLcontext *ctx, void *data ); +static void loopback_compiled_cassette( GLcontext *ctx, struct immediate *IM ); + + +/* Insert the active immediate struct onto the display list currently + * being built. + */ +void +_tnl_compile_cassette( GLcontext *ctx, struct immediate *IM ) +{ + struct immediate *im = TNL_CURRENT_IM(ctx); + TNLcontext *tnl = TNL_CONTEXT(ctx); + TNLvertexcassette *node; + GLuint new_beginstate; + + if (IM->FlushElt) { + ASSERT (IM->FlushElt == FLUSH_ELT_LAZY); + _tnl_translate_array_elts( ctx, IM, IM->Start, IM->Count ); + } + + _tnl_compute_orflag( IM, IM->Start ); + + /* Need to clear this flag, or fixup gets confused. (The elements + * have been translated away by now.) + */ + IM->OrFlag &= ~VERT_ELT; + IM->AndFlag &= ~VERT_ELT; + + _tnl_fixup_input( ctx, IM ); +/* _tnl_print_cassette( IM ); */ + + node = (TNLvertexcassette *) + _mesa_alloc_instruction(ctx, + tnl->opcode_vertex_cassette, + sizeof(TNLvertexcassette)); + if (!node) + return; + + node->IM = im; im->ref_count++; + node->Start = im->Start; + node->Count = im->Count; + node->BeginState = im->BeginState; + node->SavedBeginState = im->SavedBeginState; + node->OrFlag = im->OrFlag; + node->TexSize = im->TexSize; + node->AndFlag = im->AndFlag; + node->LastData = im->LastData; + node->LastPrimitive = im->LastPrimitive; + node->LastMaterial = im->LastMaterial; + node->MaterialOrMask = im->MaterialOrMask; + node->MaterialAndMask = im->MaterialAndMask; + + if (ctx->ExecuteFlag) { + execute_compiled_cassette( ctx, (void *)node ); + } + + /* Discard any errors raised in the last cassette. + */ + new_beginstate = node->BeginState & (VERT_BEGIN_0|VERT_BEGIN_1); + + /* Decide whether this immediate struct is full, or can be used for + * the next batch of vertices as well. + */ + if (im->Count > IMM_MAXDATA - 16) { + /* Call it full... + */ + struct immediate *new_im = _tnl_alloc_immediate(ctx); + new_im->ref_count++; + im->ref_count--; /* remove CURRENT_IM reference */ + ASSERT(im->ref_count > 0); /* it is compiled into a display list */ + SET_IMMEDIATE( ctx, new_im ); + _tnl_reset_compile_input( ctx, IMM_MAX_COPIED_VERTS, + new_beginstate, node->SavedBeginState ); + } else { + /* Still some room in the current immediate. + */ + _tnl_reset_compile_input( ctx, im->Count+1+IMM_MAX_COPIED_VERTS, + new_beginstate, node->SavedBeginState); + } +} + + +static void fixup_compiled_primitives( GLcontext *ctx, struct immediate *IM ) +{ + TNLcontext *tnl = TNL_CONTEXT(ctx); + + /* Can potentially overwrite primitive details - need to save the + * first slot: + */ + tnl->DlistPrimitive = IM->Primitive[IM->Start]; + tnl->DlistPrimitiveLength = IM->PrimitiveLength[IM->Start]; + tnl->DlistLastPrimitive = IM->LastPrimitive; + + /* The first primitive may be different from what was recorded in + * the immediate struct. Consider an immediate that starts with a + * glBegin, compiled in a display list, which is called from within + * an existing Begin/End object. + */ + if (ctx->Driver.CurrentExecPrimitive == GL_POLYGON+1) { + GLuint i; + + if (IM->BeginState & VERT_ERROR_1) + _mesa_error( ctx, GL_INVALID_OPERATION, "glBegin/glEnd"); + + for (i = IM->Start ; i <= IM->Count ; i += IM->PrimitiveLength[i]) + if (IM->Flag[i] & (VERT_BEGIN|VERT_END_VB)) + break; + + /* Would like to just ignore vertices upto this point. Can't + * set copystart because it might skip materials? + */ + ASSERT(IM->Start == IM->CopyStart); + if (i > IM->CopyStart) { + IM->Primitive[IM->CopyStart] = GL_POLYGON+1; + IM->PrimitiveLength[IM->CopyStart] = i - IM->CopyStart; + if (IM->Flag[i] & VERT_END_VB) { + IM->Primitive[IM->CopyStart] |= PRIM_LAST; + IM->LastPrimitive = IM->CopyStart; + } + } + } else { + GLuint i; + + if (IM->BeginState & VERT_ERROR_0) + _mesa_error( ctx, GL_INVALID_OPERATION, "glBegin/glEnd"); + + if (IM->CopyStart == IM->Start && + IM->Flag[IM->Start] & (VERT_END|VERT_END_VB)) + { + } + else + { + IM->Primitive[IM->CopyStart] = ctx->Driver.CurrentExecPrimitive; + if (tnl->ExecParity) + IM->Primitive[IM->CopyStart] |= PRIM_PARITY; + + /* one of these should be true, else we'll be in an infinite loop + */ + ASSERT(IM->PrimitiveLength[IM->Start] > 0 || + IM->Flag[IM->Start] & (VERT_END|VERT_END_VB)); + + for (i = IM->Start ; i <= IM->Count ; i += IM->PrimitiveLength[i]) + if (IM->Flag[i] & (VERT_END|VERT_END_VB)) { + IM->PrimitiveLength[IM->CopyStart] = i - IM->CopyStart; + if (IM->Flag[i] & VERT_END_VB) { + IM->Primitive[IM->CopyStart] |= PRIM_LAST; + IM->LastPrimitive = IM->CopyStart; + } + if (IM->Flag[i] & VERT_END) { + IM->Primitive[IM->CopyStart] |= PRIM_END; + } + break; + } + } + } +} + +/* Undo any changes potentially made to the immediate in the range + * IM->Start..IM->Count above. + */ +static void restore_compiled_primitives( GLcontext *ctx, struct immediate *IM ) +{ + TNLcontext *tnl = TNL_CONTEXT(ctx); + IM->Primitive[IM->Start] = tnl->DlistPrimitive; + IM->PrimitiveLength[IM->Start] = tnl->DlistPrimitiveLength; +} + + + +static void +execute_compiled_cassette( GLcontext *ctx, void *data ) +{ + TNLcontext *tnl = TNL_CONTEXT(ctx); + TNLvertexcassette *node = (TNLvertexcassette *)data; + struct immediate *IM = node->IM; + +/* fprintf(stderr, "%s\n", __FUNCTION__); */ + + IM->Start = node->Start; + IM->CopyStart = node->Start; + IM->Count = node->Count; + IM->BeginState = node->BeginState; + IM->SavedBeginState = node->SavedBeginState; + IM->OrFlag = node->OrFlag; + IM->TexSize = node->TexSize; + IM->AndFlag = node->AndFlag; + IM->LastData = node->LastData; + IM->LastPrimitive = node->LastPrimitive; + IM->LastMaterial = node->LastMaterial; + IM->MaterialOrMask = node->MaterialOrMask; + IM->MaterialAndMask = node->MaterialAndMask; + + if ((MESA_VERBOSE & VERBOSE_DISPLAY_LIST) && + (MESA_VERBOSE & VERBOSE_IMMEDIATE)) + _tnl_print_cassette( IM ); + + if (MESA_VERBOSE & VERBOSE_DISPLAY_LIST) { + fprintf(stderr, "Run cassette %d, rows %d..%d, beginstate %x ", + IM->id, + IM->Start, IM->Count, IM->BeginState); + _tnl_print_vert_flags("orflag", IM->OrFlag); + } + + + /* Need to respect 'HardBeginEnd' even if the commands are looped + * back to a driver tnl module. + */ + if (IM->SavedBeginState) { + if (ctx->Driver.CurrentExecPrimitive == GL_POLYGON+1) + tnl->ReplayHardBeginEnd = 1; + if (!tnl->ReplayHardBeginEnd) { + /* This is a user error. Whatever operation (like glRectf) + * decomposed to this hard begin/end pair is now being run + * inside a begin/end object -- illegally. Reject it and + * raise an error. + */ + _mesa_error(ctx, GL_INVALID_OPERATION, "hard replay"); + return; + } + } + + if (tnl->LoopbackDListCassettes) { + fixup_compiled_primitives( ctx, IM ); + loopback_compiled_cassette( ctx, IM ); + restore_compiled_primitives( ctx, IM ); + } + else if (IM->Count == IM->Start) { + _tnl_copy_to_current( ctx, IM, IM->OrFlag ); + } + else { + if (ctx->NewState) + _mesa_update_state(ctx); + + if (tnl->pipeline.build_state_changes) + _tnl_validate_pipeline( ctx ); + + _tnl_fixup_compiled_cassette( ctx, IM ); + fixup_compiled_primitives( ctx, IM ); + + if (IM->Primitive[IM->LastPrimitive] & PRIM_END) + ctx->Driver.CurrentExecPrimitive = GL_POLYGON+1; + else + ctx->Driver.CurrentExecPrimitive = + IM->Primitive[IM->LastPrimitive] & PRIM_MODE_MASK; + + _tnl_get_exec_copy_verts( ctx, IM ); + _tnl_run_cassette( ctx, IM ); + + restore_compiled_primitives( ctx, IM ); + } + + if (ctx->Driver.CurrentExecPrimitive == GL_POLYGON+1) + tnl->ReplayHardBeginEnd = 0; +} + +static void +destroy_compiled_cassette( GLcontext *ctx, void *data ) +{ + TNLvertexcassette *node = (TNLvertexcassette *)data; + + if ( --node->IM->ref_count == 0 ) + _tnl_free_immediate( node->IM ); +} + + +static void +print_compiled_cassette( GLcontext *ctx, void *data ) +{ + TNLvertexcassette *node = (TNLvertexcassette *)data; + struct immediate *IM = node->IM; + + fprintf(stderr, "TNL-VERTEX-CASSETTE, id %u, rows %u..%u\n", + node->IM->id, node->Start, node->Count); + + IM->Start = node->Start; + IM->Count = node->Count; + IM->BeginState = node->BeginState; + IM->OrFlag = node->OrFlag; + IM->TexSize = node->TexSize; + IM->AndFlag = node->AndFlag; + IM->LastData = node->LastData; + IM->LastPrimitive = node->LastPrimitive; + IM->LastMaterial = node->LastMaterial; + IM->MaterialOrMask = node->MaterialOrMask; + IM->MaterialAndMask = node->MaterialAndMask; + + _tnl_print_cassette( node->IM ); +} + +void +_tnl_BeginCallList( GLcontext *ctx, GLuint list ) +{ + (void) ctx; + (void) list; + FLUSH_CURRENT(ctx, 0); +} + + +/* Called at the tail of a CallList. Nothing to do. + */ +void +_tnl_EndCallList( GLcontext *ctx ) +{ +} + + +void +_tnl_EndList( GLcontext *ctx ) +{ + struct immediate *IM = TNL_CURRENT_IM(ctx); + + ctx->swtnl_im = 0; + IM->ref_count--; + + /* outside begin/end, even in COMPILE_AND_EXEC, + * so no vertices to copy, right? + */ + ASSERT(TNL_CONTEXT(ctx)->ExecCopyCount == 0); + + /* If this one isn't free, get a clean one. (Otherwise we'll be + * using one that's already half full). + */ + if (IM->ref_count != 0) + IM = _tnl_alloc_immediate( ctx ); + + ASSERT(IM->ref_count == 0); + + SET_IMMEDIATE( ctx, IM ); + IM->ref_count++; + + _tnl_reset_exec_input( ctx, IMM_MAX_COPIED_VERTS, 0, 0 ); +} + + +void +_tnl_NewList( GLcontext *ctx, GLuint list, GLenum mode ) +{ + struct immediate *IM = TNL_CURRENT_IM(ctx); + + /* Use the installed immediate struct. No vertices in the current + * immediate, no copied vertices in the system. + */ + ASSERT(TNL_CURRENT_IM(ctx)); + ASSERT(TNL_CURRENT_IM(ctx)->Start == IMM_MAX_COPIED_VERTS); + ASSERT(TNL_CURRENT_IM(ctx)->Start == TNL_CURRENT_IM(ctx)->Count); + ASSERT(TNL_CONTEXT(ctx)->ExecCopyCount == 0); + + /* Set current Begin/End state to unknown: + */ + IM->BeginState = VERT_BEGIN_0; + ctx->Driver.CurrentSavePrimitive = PRIM_UNKNOWN; +} + + +void +_tnl_dlist_init( GLcontext *ctx ) +{ + TNLcontext *tnl = TNL_CONTEXT(ctx); + + tnl->opcode_vertex_cassette = + _mesa_alloc_opcode( ctx, + sizeof(TNLvertexcassette), + execute_compiled_cassette, + destroy_compiled_cassette, + print_compiled_cassette ); +} + + +static void emit_material( struct gl_material *src, GLuint bitmask ) +{ + if (bitmask & FRONT_EMISSION_BIT) + glMaterialfv( GL_FRONT, GL_EMISSION, src[0].Emission ); + + if (bitmask & BACK_EMISSION_BIT) + glMaterialfv( GL_BACK, GL_EMISSION, src[1].Emission ); + + if (bitmask & FRONT_AMBIENT_BIT) + glMaterialfv( GL_FRONT, GL_AMBIENT, src[0].Ambient ); + + if (bitmask & BACK_AMBIENT_BIT) + glMaterialfv( GL_BACK, GL_AMBIENT, src[1].Ambient ); + + if (bitmask & FRONT_DIFFUSE_BIT) + glMaterialfv( GL_FRONT, GL_DIFFUSE, src[0].Diffuse ); + + if (bitmask & BACK_DIFFUSE_BIT) + glMaterialfv( GL_BACK, GL_DIFFUSE, src[1].Diffuse ); + + if (bitmask & FRONT_SPECULAR_BIT) + glMaterialfv( GL_FRONT, GL_SPECULAR, src[0].Specular ); + + if (bitmask & BACK_SPECULAR_BIT) + glMaterialfv( GL_BACK, GL_SPECULAR, src[1].Specular ); + + if (bitmask & FRONT_SHININESS_BIT) + glMaterialfv( GL_FRONT, GL_SHININESS, &src[0].Shininess ); + + if (bitmask & BACK_SHININESS_BIT) + glMaterialfv( GL_BACK, GL_SHININESS, &src[1].Shininess ); + + if (bitmask & FRONT_INDEXES_BIT) { + GLfloat ind[3]; + ind[0] = src[0].AmbientIndex; + ind[1] = src[0].DiffuseIndex; + ind[2] = src[0].SpecularIndex; + glMaterialfv( GL_FRONT, GL_COLOR_INDEXES, ind ); + } + + if (bitmask & BACK_INDEXES_BIT) { + GLfloat ind[3]; + ind[0] = src[1].AmbientIndex; + ind[1] = src[1].DiffuseIndex; + ind[2] = src[1].SpecularIndex; + glMaterialfv( GL_BACK, GL_COLOR_INDEXES, ind ); + } +} + + +/* Low-performance helper function to allow driver-supplied tnl + * modules to process tnl display lists. This is primarily supplied + * to avoid fallbacks if CallList is invoked inside a Begin/End pair. + * For higher performance, drivers should fallback to tnl (if outside + * begin/end), or (for tnl hardware) implement their own display list + * mechanism. + */ +static void loopback_compiled_cassette( GLcontext *ctx, struct immediate *IM ) +{ + GLuint i; + GLuint *flags = IM->Flag; + GLuint orflag = IM->OrFlag; + GLuint j; + void (GLAPIENTRY *vertex)( const GLfloat * ); + void (GLAPIENTRY *texcoordfv[MAX_TEXTURE_UNITS])( GLuint, const GLfloat * ); + GLuint maxtex = 0; + GLuint p, length, prim = 0; + + if (orflag & VERT_OBJ_234) + vertex = glVertex4fv; + else + vertex = glVertex3fv; + + if (orflag & VERT_TEX_ANY) { + for (j = 0 ; j < ctx->Const.MaxTextureUnits ; j++) { + if (orflag & VERT_TEX(j)) { + maxtex = j+1; + if ((IM->TexSize & TEX_SIZE_4(j)) == TEX_SIZE_4(j)) + texcoordfv[j] = glMultiTexCoord4fvARB; + else if (IM->TexSize & TEX_SIZE_3(j)) + texcoordfv[j] = glMultiTexCoord3fvARB; + else + texcoordfv[j] = glMultiTexCoord2fvARB; + } + } + } + + for (p = IM->Start ; !(prim & PRIM_LAST) ; p += length) + { + prim = IM->Primitive[p]; + length= IM->PrimitiveLength[p]; + ASSERT(length || (prim & PRIM_LAST)); + ASSERT((prim & PRIM_MODE_MASK) <= GL_POLYGON+1); + + if (prim & PRIM_BEGIN) { +/* fprintf(stderr, "begin %s\n", _mesa_prim_name[prim&PRIM_MODE_MASK]); */ + glBegin(prim & PRIM_MODE_MASK); + } + + for ( i = p ; i <= p+length ; i++) { + if (flags[i] & VERT_TEX_ANY) { + GLuint k; + for (k = 0 ; k < maxtex ; k++) { + if (flags[i] & VERT_TEX(k)) { + texcoordfv[k]( GL_TEXTURE0_ARB + k, IM->TexCoord[k][i] ); + } + } + } + + if (flags[i] & VERT_NORM) { +/* fprintf(stderr, "normal %d: %f %f %f\n", i, */ +/* IM->Normal[i][0], IM->Normal[i][1], IM->Normal[i][2]); */ + glNormal3fv(IM->Normal[i]); + } + + if (flags[i] & VERT_RGBA) { +/* fprintf(stderr, "color %d: %f %f %f\n", i, */ +/* IM->Color[i][0], IM->Color[i][1], IM->Color[i][2]); */ + glColor4fv( IM->Color[i] ); + } + + if (flags[i] & VERT_SPEC_RGB) + glSecondaryColor3fvEXT( IM->SecondaryColor[i] ); + + if (flags[i] & VERT_FOG_COORD) + glFogCoordfEXT( IM->FogCoord[i] ); + + if (flags[i] & VERT_INDEX) + glIndexi( IM->Index[i] ); + + if (flags[i] & VERT_EDGE) + glEdgeFlag( IM->EdgeFlag[i] ); + + if (flags[i] & VERT_MATERIAL) + emit_material( IM->Material[i], IM->MaterialMask[i] ); + + if (flags[i]&VERT_OBJ_234) { +/* fprintf(stderr, "vertex %d: %f %f %f\n", i, */ +/* IM->Obj[i][0], IM->Obj[i][1], IM->Obj[i][2]); */ + vertex( IM->Obj[i] ); + } + else if (flags[i] & VERT_EVAL_C1) + glEvalCoord1f(IM->Obj[i][0]); + else if (flags[i] & VERT_EVAL_P1) + glEvalPoint1(IM->Obj[i][0]); + else if (flags[i] & VERT_EVAL_C2) + glEvalCoord2f( IM->Obj[i][0], IM->Obj[i][1]); + else if (flags[i] & VERT_EVAL_P2) + glEvalPoint2( IM->Obj[i][0], IM->Obj[i][1]); + } + + if (prim & PRIM_END) { +/* fprintf(stderr, "end\n"); */ + glEnd(); + } + } +} Index: dll/opengl/opengl32/mesa/tnl/t_imm_dlist.h =================================================================== --- dll/opengl/opengl32/mesa/tnl/t_imm_dlist.h (revision 0) +++ dll/opengl/opengl32/mesa/tnl/t_imm_dlist.h (working copy) @@ -0,0 +1,45 @@ +/* $Id: t_imm_dlist.h,v 1.3 2001/03/12 00:48:43 gareth Exp $ */ + +/* + * Mesa 3-D graphics library + * Version: 3.5 + * + * Copyright (C) 1999-2001 Brian Paul 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 + * BRIAN PAUL 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. + * + * Authors: + * Keith Whitwell + */ + +#ifndef _T_DLIST_H +#define _T_DLIST_H + +#include "mtypes.h" +#include "t_context.h" + +extern void _tnl_dlist_init( GLcontext *ctx ); + +extern void _tnl_compile_cassette( GLcontext *ctx, struct immediate *IM ); +extern void _tnl_EndList( GLcontext *ctx ); +extern void _tnl_NewList( GLcontext *ctx, GLuint list, GLenum mode ); + +extern void _tnl_EndCallList( GLcontext *ctx ); +extern void _tnl_BeginCallList( GLcontext *ctx, GLuint list ); + +#endif Index: dll/opengl/opengl32/mesa/tnl/t_imm_elt.c =================================================================== --- dll/opengl/opengl32/mesa/tnl/t_imm_elt.c (revision 0) +++ dll/opengl/opengl32/mesa/tnl/t_imm_elt.c (working copy) @@ -0,0 +1,830 @@ +/* $Id: t_imm_elt.c,v 1.11 2001/05/11 08:11:31 keithw Exp $ */ + +/* + * Mesa 3-D graphics library + * Version: 3.5 + * + * Copyright (C) 1999-2001 Brian Paul 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 + * BRIAN PAUL 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. + * + * Authors: + * Keith Whitwell + */ + +#include "glheader.h" +#include "colormac.h" +#include "mem.h" +#include "mmath.h" +#include "mtypes.h" + +#include "math/m_translate.h" + +#include "t_context.h" +#include "t_imm_elt.h" + + + +typedef void (*trans_elt_1f_func)(GLfloat *to, + CONST void *ptr, + GLuint stride, + GLuint *flags, + GLuint *elts, + GLuint match, + GLuint start, + GLuint n ); + +typedef void (*trans_elt_1ui_func)(GLuint *to, + CONST void *ptr, + GLuint stride, + GLuint *flags, + GLuint *elts, + GLuint match, + GLuint start, + GLuint n ); + +typedef void (*trans_elt_1ub_func)(GLubyte *to, + CONST void *ptr, + GLuint stride, + GLuint *flags, + GLuint *elts, + GLuint match, + GLuint start, + GLuint n ); + +typedef void (*trans_elt_4ub_func)(GLubyte (*to)[4], + CONST void *ptr, + GLuint stride, + GLuint *flags, + GLuint *elts, + GLuint match, + GLuint start, + GLuint n ); + +typedef void (*trans_elt_4us_func)(GLushort (*to)[4], + CONST void *ptr, + GLuint stride, + GLuint *flags, + GLuint *elts, + GLuint match, + GLuint start, + GLuint n ); + +typedef void (*trans_elt_4f_func)(GLfloat (*to)[4], + CONST void *ptr, + GLuint stride, + GLuint *flags, + GLuint *elts, + GLuint match, + GLuint start, + GLuint n ); + +typedef void (*trans_elt_3f_func)(GLfloat (*to)[3], + CONST void *ptr, + GLuint stride, + GLuint *flags, + GLuint *elts, + GLuint match, + GLuint start, + GLuint n ); + + + + +static trans_elt_1f_func _tnl_trans_elt_1f_tab[MAX_TYPES]; +static trans_elt_1ui_func _tnl_trans_elt_1ui_tab[MAX_TYPES]; +static trans_elt_1ub_func _tnl_trans_elt_1ub_tab[MAX_TYPES]; +static trans_elt_3f_func _tnl_trans_elt_3f_tab[MAX_TYPES]; +static trans_elt_4ub_func _tnl_trans_elt_4ub_tab[5][MAX_TYPES]; +static trans_elt_4us_func _tnl_trans_elt_4us_tab[5][MAX_TYPES]; +static trans_elt_4f_func _tnl_trans_elt_4f_tab[5][MAX_TYPES]; + + +#define PTR_ELT(ptr, elt) (((SRC *)ptr)[elt]) + + + + + +/* Code specific to array element implementation. There is a small + * subtlety in the bits CHECK() tests, and the way bits are set in + * glArrayElement which ensures that if, eg, in the case that the + * vertex array is disabled and normal array is enabled, and we get + * either sequence: + * + * ArrayElement() OR Normal() + * Normal() ArrayElement() + * Vertex() Vertex() + * + * That the correct value for normal is used. + */ +#define TAB(x) _tnl_trans_elt##x##_tab +#define ARGS GLuint *flags, GLuint *elts, GLuint match, \ + GLuint start, GLuint n +#define SRC_START 0 +#define DST_START start +#define CHECK if ((flags[i]&match) == VERT_ELT) +#define NEXT_F (void)1 +#define NEXT_F2 f = first + elts[i] * stride; + + +/* GL_BYTE + */ +#define SRC GLbyte +#define SRC_IDX TYPE_IDX(GL_BYTE) +#define TRX_3F(f,n) BYTE_TO_FLOAT( PTR_ELT(f,n) ) +#define TRX_4F(f,n) BYTE_TO_FLOAT( PTR_ELT(f,n) ) +#define TRX_UB(ub, f,n) ub = BYTE_TO_UBYTE( PTR_ELT(f,n) ) +#define TRX_US(us, f,n) us = BYTE_TO_USHORT( PTR_ELT(f,n) ) +#define TRX_UI(f,n) (PTR_ELT(f,n) < 0 ? 0 : (GLuint) PTR_ELT(f,n)) + + +#define SZ 4 +#define INIT init_trans_4_GLbyte_elt +#define DEST_4F trans_4_GLbyte_4f_elt +#define DEST_4UB trans_4_GLbyte_4ub_elt +#define DEST_4US trans_4_GLbyte_4us_elt +#include "math/m_trans_tmp.h" + +#define SZ 3 +#define INIT init_trans_3_GLbyte_elt +#define DEST_4F trans_3_GLbyte_4f_elt +#define DEST_4UB trans_3_GLbyte_4ub_elt +#define DEST_4US trans_3_GLbyte_4us_elt +#define DEST_3F trans_3_GLbyte_3f_elt +#include "math/m_trans_tmp.h" + +#define SZ 2 +#define INIT init_trans_2_GLbyte_elt +#define DEST_4F trans_2_GLbyte_4f_elt +#include "math/m_trans_tmp.h" + +#define SZ 1 +#define INIT init_trans_1_GLbyte_elt +#define DEST_4F trans_1_GLbyte_4f_elt +#define DEST_1UB trans_1_GLbyte_1ub_elt +#define DEST_1UI trans_1_GLbyte_1ui_elt +#include "math/m_trans_tmp.h" + +#undef SRC +#undef TRX_3F +#undef TRX_4F +#undef TRX_UB +#undef TRX_US +#undef TRX_UI +#undef SRC_IDX + +/* GL_UNSIGNED_BYTE + */ +#define SRC GLubyte +#define SRC_IDX TYPE_IDX(GL_UNSIGNED_BYTE) +#define TRX_3F(f,n) UBYTE_TO_FLOAT( PTR_ELT(f,n) ) +#define TRX_4F(f,n) UBYTE_TO_FLOAT( PTR_ELT(f,n) ) +#define TRX_UB(ub, f,n) ub = PTR_ELT(f,n) +#define TRX_US(us, f,n) us = PTR_ELT(f,n) +#define TRX_UI(f,n) (GLuint)PTR_ELT(f,n) + +/* 4ub->4ub handled in special case below. + */ +#define SZ 4 +#define INIT init_trans_4_GLubyte_elt +#define DEST_4F trans_4_GLubyte_4f_elt +#define DEST_4US trans_4_GLubyte_4us_elt +#include "math/m_trans_tmp.h" + +#define SZ 3 +#define INIT init_trans_3_GLubyte_elt +#define DEST_4F trans_3_GLubyte_4f_elt +#define DEST_3F trans_3_GLubyte_3f_elt +#define DEST_4UB trans_3_GLubyte_4ub_elt +#define DEST_4US trans_3_GLubyte_4us_elt +#include "math/m_trans_tmp.h" + + +#define SZ 1 +#define INIT init_trans_1_GLubyte_elt +#define DEST_1UI trans_1_GLubyte_1ui_elt +#define DEST_1UB trans_1_GLubyte_1ub_elt +#include "math/m_trans_tmp.h" + +#undef SRC +#undef SRC_IDX +#undef TRX_3F +#undef TRX_4F +#undef TRX_UB +#undef TRX_US +#undef TRX_UI + + +/* GL_SHORT + */ +#define SRC GLshort +#define SRC_IDX TYPE_IDX(GL_SHORT) +#define TRX_3F(f,n) SHORT_TO_FLOAT( PTR_ELT(f,n) ) +#define TRX_4F(f,n) (GLfloat)( PTR_ELT(f,n) ) +#define TRX_UB(ub, f,n) ub = SHORT_TO_UBYTE(PTR_ELT(f,n)) +#define TRX_US(us, f,n) us = SHORT_TO_USHORT(PTR_ELT(f,n)) +#define TRX_UI(f,n) (PTR_ELT(f,n) < 0 ? 0 : (GLuint) PTR_ELT(f,n)) + + +#define SZ 4 +#define INIT init_trans_4_GLshort_elt +#define DEST_4F trans_4_GLshort_4f_elt +#define DEST_4UB trans_4_GLshort_4ub_elt +#define DEST_4US trans_4_GLshort_4us_elt +#include "math/m_trans_tmp.h" + +#define SZ 3 +#define INIT init_trans_3_GLshort_elt +#define DEST_4F trans_3_GLshort_4f_elt +#define DEST_4UB trans_3_GLshort_4ub_elt +#define DEST_4US trans_3_GLshort_4us_elt +#define DEST_3F trans_3_GLshort_3f_elt +#include "math/m_trans_tmp.h" + +#define SZ 2 +#define INIT init_trans_2_GLshort_elt +#define DEST_4F trans_2_GLshort_4f_elt +#include "math/m_trans_tmp.h" + +#define SZ 1 +#define INIT init_trans_1_GLshort_elt +#define DEST_4F trans_1_GLshort_4f_elt +#define DEST_1UB trans_1_GLshort_1ub_elt +#define DEST_1UI trans_1_GLshort_1ui_elt +#include "math/m_trans_tmp.h" + + +#undef SRC +#undef SRC_IDX +#undef TRX_3F +#undef TRX_4F +#undef TRX_UB +#undef TRX_US +#undef TRX_UI + + +/* GL_UNSIGNED_SHORT + */ +#define SRC GLushort +#define SRC_IDX TYPE_IDX(GL_UNSIGNED_SHORT) +#define TRX_3F(f,n) USHORT_TO_FLOAT( PTR_ELT(f,n) ) +#define TRX_4F(f,n) (GLfloat)( PTR_ELT(f,n) ) +#define TRX_UB(ub,f,n) ub = (GLubyte) (PTR_ELT(f,n) >> 8) +#define TRX_US(us,f,n) us = PTR_ELT(f,n) +#define TRX_UI(f,n) (GLuint) PTR_ELT(f,n) + + +#define SZ 4 +#define INIT init_trans_4_GLushort_elt +#define DEST_4F trans_4_GLushort_4f_elt +#define DEST_4UB trans_4_GLushort_4ub_elt +#define DEST_4US trans_4_GLushort_4us_elt +#include "math/m_trans_tmp.h" + +#define SZ 3 +#define INIT init_trans_3_GLushort_elt +#define DEST_4F trans_3_GLushort_4f_elt +#define DEST_4UB trans_3_GLushort_4ub_elt +#define DEST_4US trans_3_GLushort_4us_elt +#define DEST_3F trans_3_GLushort_3f_elt +#include "math/m_trans_tmp.h" + +#define SZ 2 +#define INIT init_trans_2_GLushort_elt +#define DEST_4F trans_2_GLushort_4f_elt +#include "math/m_trans_tmp.h" + +#define SZ 1 +#define INIT init_trans_1_GLushort_elt +#define DEST_4F trans_1_GLushort_4f_elt +#define DEST_1UB trans_1_GLushort_1ub_elt +#define DEST_1UI trans_1_GLushort_1ui_elt +#include "math/m_trans_tmp.h" + +#undef SRC +#undef SRC_IDX +#undef TRX_3F +#undef TRX_4F +#undef TRX_UB +#undef TRX_US +#undef TRX_UI + + +/* GL_INT + */ +#define SRC GLint +#define SRC_IDX TYPE_IDX(GL_INT) +#define TRX_3F(f,n) INT_TO_FLOAT( PTR_ELT(f,n) ) +#define TRX_4F(f,n) (GLfloat)( PTR_ELT(f,n) ) +#define TRX_UB(ub, f,n) ub = INT_TO_UBYTE(PTR_ELT(f,n)) +#define TRX_US(us, f,n) us = INT_TO_USHORT(PTR_ELT(f,n)) +#define TRX_UI(f,n) (PTR_ELT(f,n) < 0 ? 0 : (GLuint) PTR_ELT(f,n)) + + +#define SZ 4 +#define INIT init_trans_4_GLint_elt +#define DEST_4F trans_4_GLint_4f_elt +#define DEST_4UB trans_4_GLint_4ub_elt +#define DEST_4US trans_4_GLint_4us_elt +#include "math/m_trans_tmp.h" + +#define SZ 3 +#define INIT init_trans_3_GLint_elt +#define DEST_4F trans_3_GLint_4f_elt +#define DEST_4UB trans_3_GLint_4ub_elt +#define DEST_4US trans_3_GLint_4us_elt +#define DEST_3F trans_3_GLint_3f_elt +#include "math/m_trans_tmp.h" + +#define SZ 2 +#define INIT init_trans_2_GLint_elt +#define DEST_4F trans_2_GLint_4f_elt +#include "math/m_trans_tmp.h" + +#define SZ 1 +#define INIT init_trans_1_GLint_elt +#define DEST_4F trans_1_GLint_4f_elt +#define DEST_1UB trans_1_GLint_1ub_elt +#define DEST_1UI trans_1_GLint_1ui_elt +#include "math/m_trans_tmp.h" + + +#undef SRC +#undef SRC_IDX +#undef TRX_3F +#undef TRX_4F +#undef TRX_UB +#undef TRX_US +#undef TRX_UI + + +/* GL_UNSIGNED_INT + */ +#define SRC GLuint +#define SRC_IDX TYPE_IDX(GL_UNSIGNED_INT) +#define TRX_3F(f,n) UINT_TO_FLOAT( PTR_ELT(f,n) ) +#define TRX_4F(f,n) (GLfloat)( PTR_ELT(f,n) ) +#define TRX_UB(ub, f,n) ub = (GLubyte) (PTR_ELT(f,n) >> 24) +#define TRX_US(us, f,n) us = (GLushort) (PTR_ELT(f,n) >> 16) +#define TRX_UI(f,n) PTR_ELT(f,n) + + +#define SZ 4 +#define INIT init_trans_4_GLuint_elt +#define DEST_4F trans_4_GLuint_4f_elt +#define DEST_4UB trans_4_GLuint_4ub_elt +#define DEST_4US trans_4_GLuint_4us_elt +#include "math/m_trans_tmp.h" + +#define SZ 3 +#define INIT init_trans_3_GLuint_elt +#define DEST_4F trans_3_GLuint_4f_elt +#define DEST_4UB trans_3_GLuint_4ub_elt +#define DEST_4US trans_3_GLuint_4us_elt +#define DEST_3F trans_3_GLuint_3f_elt +#include "math/m_trans_tmp.h" + +#define SZ 2 +#define INIT init_trans_2_GLuint_elt +#define DEST_4F trans_2_GLuint_4f_elt +#include "math/m_trans_tmp.h" + +#define SZ 1 +#define INIT init_trans_1_GLuint_elt +#define DEST_4F trans_1_GLuint_4f_elt +#define DEST_1UB trans_1_GLuint_1ub_elt +#define DEST_1UI trans_1_GLuint_1ui_elt +#include "math/m_trans_tmp.h" + +#undef SRC +#undef SRC_IDX +#undef TRX_3F +#undef TRX_4F +#undef TRX_UB +#undef TRX_US +#undef TRX_UI + + +/* GL_DOUBLE + */ +#define SRC GLdouble +#define SRC_IDX TYPE_IDX(GL_DOUBLE) +#define TRX_3F(f,n) PTR_ELT(f,n) +#define TRX_4F(f,n) PTR_ELT(f,n) +#define TRX_UB(ub,f,n) UNCLAMPED_FLOAT_TO_UBYTE(ub, PTR_ELT(f,n)) +#define TRX_US(us,f,n) UNCLAMPED_FLOAT_TO_USHORT(us, PTR_ELT(f,n)) +#define TRX_UI(f,n) (GLuint) (GLint) PTR_ELT(f,n) +#define TRX_1F(f,n) PTR_ELT(f,n) + + +#define SZ 4 +#define INIT init_trans_4_GLdouble_elt +#define DEST_4F trans_4_GLdouble_4f_elt +#define DEST_4UB trans_4_GLdouble_4ub_elt +#define DEST_4US trans_4_GLdouble_4us_elt +#include "math/m_trans_tmp.h" + +#define SZ 3 +#define INIT init_trans_3_GLdouble_elt +#define DEST_4F trans_3_GLdouble_4f_elt +#define DEST_4UB trans_3_GLdouble_4ub_elt +#define DEST_4US trans_3_GLdouble_4us_elt +#define DEST_3F trans_3_GLdouble_3f_elt +#include "math/m_trans_tmp.h" + +#define SZ 2 +#define INIT init_trans_2_GLdouble_elt +#define DEST_4F trans_2_GLdouble_4f_elt +#include "math/m_trans_tmp.h" + +#define SZ 1 +#define INIT init_trans_1_GLdouble_elt +#define DEST_4F trans_1_GLdouble_4f_elt +#define DEST_1UB trans_1_GLdouble_1ub_elt +#define DEST_1UI trans_1_GLdouble_1ui_elt +#define DEST_1F trans_1_GLdouble_1f_elt +#include "math/m_trans_tmp.h" + +#undef SRC +#undef SRC_IDX + +/* GL_FLOAT + */ +#define SRC GLfloat +#define SRC_IDX TYPE_IDX(GL_FLOAT) +#define SZ 4 +#define INIT init_trans_4_GLfloat_elt +#define DEST_4UB trans_4_GLfloat_4ub_elt +#define DEST_4US trans_4_GLfloat_4us_elt +#define DEST_4F trans_4_GLfloat_4f_elt +#include "math/m_trans_tmp.h" + +#define SZ 3 +#define INIT init_trans_3_GLfloat_elt +#define DEST_4F trans_3_GLfloat_4f_elt +#define DEST_4UB trans_3_GLfloat_4ub_elt +#define DEST_4US trans_3_GLfloat_4us_elt +#define DEST_3F trans_3_GLfloat_3f_elt +#include "math/m_trans_tmp.h" + +#define SZ 2 +#define INIT init_trans_2_GLfloat_elt +#define DEST_4F trans_2_GLfloat_4f_elt +#include "math/m_trans_tmp.h" + +#define SZ 1 +#define INIT init_trans_1_GLfloat_elt +#define DEST_4F trans_1_GLfloat_3f_elt +#define DEST_1UB trans_1_GLfloat_1ub_elt +#define DEST_1UI trans_1_GLfloat_1ui_elt +#define DEST_1F trans_1_GLfloat_1f_elt +#include "math/m_trans_tmp.h" + +#undef SRC +#undef SRC_IDX +#undef TRX_3F +#undef TRX_4F +#undef TRX_UB +#undef TRX_US +#undef TRX_UI + + +static void trans_4_GLubyte_4ub(GLubyte (*t)[4], + CONST void *Ptr, + GLuint stride, + ARGS ) +{ + const GLubyte *f = (GLubyte *) Ptr + SRC_START * stride; + const GLubyte *first = f; + GLuint i; + (void) start; + if (((((long) f | (long) stride)) & 3L) == 0L) { + /* Aligned. + */ + for (i = DST_START ; i < n ; i++, NEXT_F) { + CHECK { + NEXT_F2; + COPY_4UBV( t[i], f ); + } + } + } else { + for (i = DST_START ; i < n ; i++, NEXT_F) { + CHECK { + NEXT_F2; + t[i][0] = f[0]; + t[i][1] = f[1]; + t[i][2] = f[2]; + t[i][3] = f[3]; + } + } + } +} + + +static void init_translate_elt(void) +{ + MEMSET( TAB(_1ui), 0, sizeof(TAB(_1ui)) ); + MEMSET( TAB(_1ub), 0, sizeof(TAB(_1ub)) ); + MEMSET( TAB(_3f), 0, sizeof(TAB(_3f)) ); + MEMSET( TAB(_4ub), 0, sizeof(TAB(_4ub)) ); + MEMSET( TAB(_4us), 0, sizeof(TAB(_4us)) ); + MEMSET( TAB(_4f), 0, sizeof(TAB(_4f)) ); + + TAB(_4ub)[4][TYPE_IDX(GL_UNSIGNED_BYTE)] = trans_4_GLubyte_4ub; + + init_trans_4_GLbyte_elt(); + init_trans_3_GLbyte_elt(); + init_trans_2_GLbyte_elt(); + init_trans_1_GLbyte_elt(); + init_trans_1_GLubyte_elt(); + init_trans_3_GLubyte_elt(); + init_trans_4_GLubyte_elt(); + init_trans_4_GLshort_elt(); + init_trans_3_GLshort_elt(); + init_trans_2_GLshort_elt(); + init_trans_1_GLshort_elt(); + init_trans_4_GLushort_elt(); + init_trans_3_GLushort_elt(); + init_trans_2_GLushort_elt(); + init_trans_1_GLushort_elt(); + init_trans_4_GLint_elt(); + init_trans_3_GLint_elt(); + init_trans_2_GLint_elt(); + init_trans_1_GLint_elt(); + init_trans_4_GLuint_elt(); + init_trans_3_GLuint_elt(); + init_trans_2_GLuint_elt(); + init_trans_1_GLuint_elt(); + init_trans_4_GLdouble_elt(); + init_trans_3_GLdouble_elt(); + init_trans_2_GLdouble_elt(); + init_trans_1_GLdouble_elt(); + init_trans_4_GLfloat_elt(); + init_trans_3_GLfloat_elt(); + init_trans_2_GLfloat_elt(); + init_trans_1_GLfloat_elt(); +} + + +#undef TAB +#undef CLASS +#undef ARGS +#undef CHECK +#undef START + + + + +void _tnl_imm_elt_init( void ) +{ + init_translate_elt(); +} + + +static void _tnl_trans_elt_1f(GLfloat *to, + const struct gl_client_array *from, + GLuint *flags, + GLuint *elts, + GLuint match, + GLuint start, + GLuint n ) +{ + _tnl_trans_elt_1f_tab[TYPE_IDX(from->Type)]( to, + from->Ptr, + from->StrideB, + flags, + elts, + match, + start, + n ); + +} + +static void _tnl_trans_elt_1ui(GLuint *to, + const struct gl_client_array *from, + GLuint *flags, + GLuint *elts, + GLuint match, + GLuint start, + GLuint n ) +{ + _tnl_trans_elt_1ui_tab[TYPE_IDX(from->Type)]( to, + from->Ptr, + from->StrideB, + flags, + elts, + match, + start, + n ); + +} + + +static void _tnl_trans_elt_1ub(GLubyte *to, + const struct gl_client_array *from, + GLuint *flags, + GLuint *elts, + GLuint match, + GLuint start, + GLuint n ) +{ + _tnl_trans_elt_1ub_tab[TYPE_IDX(from->Type)]( to, + from->Ptr, + from->StrideB, + flags, + elts, + match, + start, + n ); + +} + + +#if 0 +static void _tnl_trans_elt_4ub(GLubyte (*to)[4], + const struct gl_client_array *from, + GLuint *flags, + GLuint *elts, + GLuint match, + GLuint start, + GLuint n ) +{ + _tnl_trans_elt_4ub_tab[from->Size][TYPE_IDX(from->Type)]( to, + from->Ptr, + from->StrideB, + flags, + elts, + match, + start, + n ); + +} +#endif + +#if 0 +static void _tnl_trans_elt_4us(GLushort (*to)[4], + const struct gl_client_array *from, + GLuint *flags, + GLuint *elts, + GLuint match, + GLuint start, + GLuint n ) +{ + _tnl_trans_elt_4us_tab[from->Size][TYPE_IDX(from->Type)]( to, + from->Ptr, + from->StrideB, + flags, + elts, + match, + start, + n ); + +} +#endif + +static void _tnl_trans_elt_4f(GLfloat (*to)[4], + const struct gl_client_array *from, + GLuint *flags, + GLuint *elts, + GLuint match, + GLuint start, + GLuint n ) +{ + _tnl_trans_elt_4f_tab[from->Size][TYPE_IDX(from->Type)]( to, + from->Ptr, + from->StrideB, + flags, + elts, + match, + start, + n ); + +} + + + +static void _tnl_trans_elt_3f(GLfloat (*to)[3], + const struct gl_client_array *from, + GLuint *flags, + GLuint *elts, + GLuint match, + GLuint start, + GLuint n ) +{ + _tnl_trans_elt_3f_tab[TYPE_IDX(from->Type)]( to, + from->Ptr, + from->StrideB, + flags, + elts, + match, + start, + n ); +} + + + + +/* Batch function to translate away all the array elements in the + * input buffer prior to transform. Done only the first time a vertex + * buffer is executed or compiled. + * + * KW: Have to do this after each glEnd if arrays aren't locked. + */ +void _tnl_translate_array_elts( GLcontext *ctx, struct immediate *IM, + GLuint start, GLuint count ) +{ + GLuint *flags = IM->Flag; + GLuint *elts = IM->Elt; + GLuint translate = ctx->Array._Enabled; + GLuint i; + + if (MESA_VERBOSE&VERBOSE_IMMEDIATE) + fprintf(stderr, "exec_array_elements %d .. %d\n", start, count); + + if (translate & VERT_OBJ) { + _tnl_trans_elt_4f( IM->Obj, + &ctx->Array.Vertex, + flags, elts, (VERT_ELT|VERT_OBJ), + start, count); + + if (ctx->Array.Vertex.Size == 4) + translate |= VERT_OBJ_234; + else if (ctx->Array.Vertex.Size == 3) + translate |= VERT_OBJ_23; + } + + + if (translate & VERT_NORM) + _tnl_trans_elt_3f( IM->Normal, + &ctx->Array.Normal, + flags, elts, (VERT_ELT|VERT_NORM), + start, count); + + if (translate & VERT_EDGE) + _tnl_trans_elt_1ub( IM->EdgeFlag, + &ctx->Array.EdgeFlag, + flags, elts, (VERT_ELT|VERT_EDGE), + start, count); + + if (translate & VERT_RGBA) { + _tnl_trans_elt_4f( IM->Color, + &ctx->Array.Color, + flags, elts, (VERT_ELT|VERT_RGBA), + start, count); + } + + if (translate & VERT_SPEC_RGB) { + _tnl_trans_elt_4f( IM->SecondaryColor, + &ctx->Array.SecondaryColor, + flags, elts, (VERT_ELT|VERT_SPEC_RGB), + start, count); + } + + if (translate & VERT_FOG_COORD) + _tnl_trans_elt_1f( IM->FogCoord, + &ctx->Array.FogCoord, + flags, elts, (VERT_ELT|VERT_FOG_COORD), + start, count); + + if (translate & VERT_INDEX) + _tnl_trans_elt_1ui( IM->Index, + &ctx->Array.Index, + flags, elts, (VERT_ELT|VERT_INDEX), + start, count); + + if (translate & VERT_TEX_ANY) { + for (i = 0 ; i < ctx->Const.MaxTextureUnits ; i++) + if (translate & VERT_TEX(i)) { + _tnl_trans_elt_4f( IM->TexCoord[i], + &ctx->Array.TexCoord[i], + flags, elts, (VERT_ELT|VERT_TEX(i)), + start, count); + + if (ctx->Array.TexCoord[i].Size == 4) + IM->TexSize |= TEX_SIZE_4(i); + else if (ctx->Array.TexCoord[i].Size == 3) + IM->TexSize |= TEX_SIZE_3(i); + } + } + + for (i = start ; i < count ; i++) + if (flags[i] & VERT_ELT) flags[i] |= translate; + + IM->FlushElt = 0; +} Index: dll/opengl/opengl32/mesa/tnl/t_imm_elt.h =================================================================== --- dll/opengl/opengl32/mesa/tnl/t_imm_elt.h (revision 0) +++ dll/opengl/opengl32/mesa/tnl/t_imm_elt.h (working copy) @@ -0,0 +1,46 @@ +/* $Id: t_imm_elt.h,v 1.2 2001/03/12 00:48:43 gareth Exp $ */ + +/* + * Mesa 3-D graphics library + * Version: 3.5 + * + * Copyright (C) 1999-2001 Brian Paul 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 + * BRIAN PAUL 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. + * + * Authors: + * Keith Whitwell + */ + + +#ifndef _T_IMM_ELT_H_ +#define _T_IMM_ELT_H_ + +#include "mtypes.h" +#include "t_context.h" + + +extern void _tnl_imm_elt_init( void ); + +extern void _tnl_translate_array_elts( GLcontext *ctx, + struct immediate *IM, + GLuint start, + GLuint end ); + + +#endif Index: dll/opengl/opengl32/mesa/tnl/t_imm_eval.c =================================================================== --- dll/opengl/opengl32/mesa/tnl/t_imm_eval.c (revision 0) +++ dll/opengl/opengl32/mesa/tnl/t_imm_eval.c (working copy) @@ -0,0 +1,768 @@ +/* $Id: t_imm_eval.c,v 1.13 2001/05/14 09:00:51 keithw Exp $ */ + +/* + * Mesa 3-D graphics library + * Version: 3.5 + * + * Copyright (C) 1999-2001 Brian Paul 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 + * BRIAN PAUL 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. + * + * Authors: + * Keith Whitwell + * + */ + + +#include "glheader.h" +#include "colormac.h" +#include "context.h" +#include "macros.h" +#include "mem.h" +#include "mmath.h" +#include "mtypes.h" +#include "math/m_eval.h" + +#include "t_context.h" +#include "t_imm_debug.h" +#include "t_imm_eval.h" +#include "t_imm_exec.h" +#include "t_imm_fixup.h" +#include "t_imm_alloc.h" + + +static void eval_points1( GLfloat outcoord[][4], + GLfloat coord[][4], + const GLuint *flags, + GLfloat du, GLfloat u1 ) +{ + GLuint i; + for (i = 0 ; !(flags[i] & VERT_END_VB) ; i++) + if (flags[i] & VERT_EVAL_ANY) { + outcoord[i][0] = coord[i][0]; + outcoord[i][1] = coord[i][1]; + if (flags[i] & VERT_EVAL_P1) + outcoord[i][0] = coord[i][0] * du + u1; + } +} + +static void eval_points2( GLfloat outcoord[][4], + GLfloat coord[][4], + const GLuint *flags, + GLfloat du, GLfloat u1, + GLfloat dv, GLfloat v1 ) +{ + GLuint i; + for (i = 0 ; !(flags[i] & VERT_END_VB) ; i++) { + if (flags[i] & VERT_EVAL_ANY) { + outcoord[i][0] = coord[i][0]; + outcoord[i][1] = coord[i][1]; + if (flags[i] & VERT_EVAL_P2) { + outcoord[i][0] = coord[i][0] * du + u1; + outcoord[i][1] = coord[i][1] * dv + v1; + } + } + } +} + +static const GLubyte dirty_flags[5] = { + 0, /* not possible */ + VEC_DIRTY_0, + VEC_DIRTY_1, + VEC_DIRTY_2, + VEC_DIRTY_3 +}; + + +static void eval1_4f( GLvector4f *dest, + GLfloat coord[][4], + const GLuint *flags, + GLuint dimension, + struct gl_1d_map *map ) +{ + const GLfloat u1 = map->u1; + const GLfloat du = map->du; + GLfloat (*to)[4] = dest->data; + GLuint i; + + for (i = 0 ; !(flags[i] & VERT_END_VB) ; i++) + if (flags[i] & (VERT_EVAL_C1|VERT_EVAL_P1)) { + GLfloat u = (coord[i][0] - u1) * du; + ASSIGN_4V(to[i], 0,0,0,1); + _math_horner_bezier_curve(map->Points, to[i], u, + dimension, map->Order); + } + + dest->size = MAX2(dest->size, dimension); + dest->flags |= dirty_flags[dimension]; +} + +static void eval1_4f_ca( struct gl_client_array *dest, + GLfloat coord[][4], + const GLuint *flags, + GLuint dimension, + struct gl_1d_map *map ) +{ + const GLfloat u1 = map->u1; + const GLfloat du = map->du; + GLfloat (*to)[4] = (GLfloat (*)[4])dest->Ptr; + GLuint i; + + ASSERT(dest->Type == GL_FLOAT); + ASSERT(dest->StrideB == 4 * sizeof(GLfloat)); + + for (i = 0 ; !(flags[i] & VERT_END_VB) ; i++) + if (flags[i] & (VERT_EVAL_C1|VERT_EVAL_P1)) { + GLfloat u = (coord[i][0] - u1) * du; + ASSIGN_4V(to[i], 0,0,0,1); + _math_horner_bezier_curve(map->Points, to[i], u, + dimension, map->Order); + } + + dest->Size = MAX2(dest->Size, (GLint) dimension); +} + + +static void eval1_1ui( GLvector1ui *dest, + GLfloat coord[][4], + const GLuint *flags, + struct gl_1d_map *map ) +{ + const GLfloat u1 = map->u1; + const GLfloat du = map->du; + GLuint *to = dest->data; + GLuint i; + + for (i = 0 ; !(flags[i] & VERT_END_VB) ; i++) + if (flags[i] & (VERT_EVAL_C1|VERT_EVAL_P1)) { + GLfloat u = (coord[i][0] - u1) * du; + GLfloat tmp; + _math_horner_bezier_curve(map->Points, &tmp, u, 1, map->Order); + to[i] = (GLuint) (GLint) tmp; + } + +} + +static void eval1_norm( GLvector3f *dest, + GLfloat coord[][4], + const GLuint *flags, + struct gl_1d_map *map ) +{ + const GLfloat u1 = map->u1; + const GLfloat du = map->du; + GLfloat (*to)[3] = dest->data; + GLuint i; + + for (i = 0 ; !(flags[i] & VERT_END_VB) ; i++) + if (flags[i] & (VERT_EVAL_C1|VERT_EVAL_P1)) { + GLfloat u = (coord[i][0] - u1) * du; + _math_horner_bezier_curve(map->Points, to[i], u, 3, map->Order); + } +} + + + + + +static void eval2_obj_norm( GLvector4f *obj_ptr, + GLvector3f *norm_ptr, + GLfloat coord[][4], + GLuint *flags, + GLuint dimension, + struct gl_2d_map *map ) +{ + const GLfloat u1 = map->u1; + const GLfloat du = map->du; + const GLfloat v1 = map->v1; + const GLfloat dv = map->dv; + GLfloat (*obj)[4] = obj_ptr->data; + GLfloat (*normal)[3] = norm_ptr->data; + GLuint i; + +/* fprintf(stderr, "%s\n", __FUNCTION__); */ + + for (i = 0 ; !(flags[i] & VERT_END_VB) ; i++) + if (flags[i] & (VERT_EVAL_C2|VERT_EVAL_P2)) { + GLfloat u = (coord[i][0] - u1) * du; + GLfloat v = (coord[i][1] - v1) * dv; + GLfloat du[4], dv[4]; + + ASSIGN_4V(obj[i], 0,0,0,1); + _math_de_casteljau_surf(map->Points, obj[i], du, dv, u, v, dimension, + map->Uorder, map->Vorder); + + CROSS3(normal[i], du, dv); + NORMALIZE_3FV(normal[i]); + } + + obj_ptr->size = MAX2(obj_ptr->size, dimension); + obj_ptr->flags |= dirty_flags[dimension]; +} + + +static void eval2_4f( GLvector4f *dest, + GLfloat coord[][4], + const GLuint *flags, + GLuint dimension, + struct gl_2d_map *map ) +{ + const GLfloat u1 = map->u1; + const GLfloat du = map->du; + const GLfloat v1 = map->v1; + const GLfloat dv = map->dv; + GLfloat (*to)[4] = dest->data; + GLuint i; + + for (i = 0 ; !(flags[i] & VERT_END_VB) ; i++) + if (flags[i] & (VERT_EVAL_C2|VERT_EVAL_P2)) { + GLfloat u = (coord[i][0] - u1) * du; + GLfloat v = (coord[i][1] - v1) * dv; +/* fprintf(stderr, "coord %d: %f %f\n", i, coord[i][0], coord[i][1]); */ + + _math_horner_bezier_surf(map->Points, to[i], u, v, dimension, + map->Uorder, map->Vorder); + } + + dest->size = MAX2(dest->size, dimension); + dest->flags |= dirty_flags[dimension]; +} + +static void eval2_4f_ca( struct gl_client_array *dest, + GLfloat coord[][4], + const GLuint *flags, + GLuint dimension, + struct gl_2d_map *map ) +{ + const GLfloat u1 = map->u1; + const GLfloat du = map->du; + const GLfloat v1 = map->v1; + const GLfloat dv = map->dv; + GLfloat (*to)[4] = (GLfloat (*)[4])dest->Ptr; + GLuint i; + + ASSERT(dest->Type == GL_FLOAT); + ASSERT(dest->StrideB == 4 * sizeof(GLfloat)); + + for (i = 0 ; !(flags[i] & VERT_END_VB) ; i++) + if (flags[i] & (VERT_EVAL_C2|VERT_EVAL_P2)) { + GLfloat u = (coord[i][0] - u1) * du; + GLfloat v = (coord[i][1] - v1) * dv; + _math_horner_bezier_surf(map->Points, to[i], u, v, dimension, + map->Uorder, map->Vorder); + } + + dest->Size = MAX2(dest->Size, (GLint) dimension); +} + + +static void eval2_norm( GLvector3f *dest, + GLfloat coord[][4], + GLuint *flags, + struct gl_2d_map *map ) +{ + const GLfloat u1 = map->u1; + const GLfloat du = map->du; + const GLfloat v1 = map->v1; + const GLfloat dv = map->dv; + GLfloat (*to)[3] = dest->data; + GLuint i; + + for (i = 0 ; !(flags[i] & VERT_END_VB) ; i++) + if (flags[i] & (VERT_EVAL_C2|VERT_EVAL_P2)) { + GLfloat u = (coord[i][0] - u1) * du; + GLfloat v = (coord[i][1] - v1) * dv; + _math_horner_bezier_surf(map->Points, to[i], u, v, 3, + map->Uorder, map->Vorder); + } + +} + + +static void eval2_1ui( GLvector1ui *dest, + GLfloat coord[][4], + const GLuint *flags, + struct gl_2d_map *map ) +{ + const GLfloat u1 = map->u1; + const GLfloat du = map->du; + const GLfloat v1 = map->v1; + const GLfloat dv = map->dv; + GLuint *to = dest->data; + GLuint i; + + for (i = 0 ; !(flags[i] & VERT_END_VB) ; i++) + if (flags[i] & (VERT_EVAL_C2|VERT_EVAL_P2)) { + GLfloat u = (coord[i][0] - u1) * du; + GLfloat v = (coord[i][1] - v1) * dv; + GLfloat tmp; + _math_horner_bezier_surf(map->Points, &tmp, u, v, 1, + map->Uorder, map->Vorder); + + to[i] = (GLuint) (GLint) tmp; + } +} + + + + + + +static void copy_4f( GLfloat to[][4], GLfloat from[][4], GLuint count ) +{ + MEMCPY( to, from, count * sizeof(to[0])); +} + +static void copy_4f_stride( GLfloat to[][4], GLfloat *from, + GLuint stride, GLuint count ) +{ + if (stride == 4 * sizeof(GLfloat)) + MEMCPY( to, from, count * sizeof(to[0])); + else { + GLuint i; +/* fprintf(stderr, "%s stride %d count %d\n", __FUNCTION__, */ +/* stride, count); */ + for (i = 0 ; i < count ; i++, STRIDE_F(from, stride)) + COPY_4FV( to[i], from ); + } +} + +static void copy_3f( GLfloat to[][3], GLfloat from[][3], GLuint count ) +{ + MEMCPY( to, from, (count) * sizeof(to[0])); +} + + +static void copy_1ui( GLuint to[], GLuint from[], GLuint count ) +{ + MEMCPY( to, from, (count) * sizeof(to[0])); +} + + + +/* Translate eval enabled flags to VERT_* flags. + */ +static void update_eval( GLcontext *ctx ) +{ + TNLcontext *tnl = TNL_CONTEXT(ctx); + GLuint eval1 = 0, eval2 = 0; + + if (ctx->Eval.Map1Index) + eval1 |= VERT_INDEX; + + if (ctx->Eval.Map2Index) + eval2 |= VERT_INDEX; + + if (ctx->Eval.Map1Color4) + eval1 |= VERT_RGBA; + + if (ctx->Eval.Map2Color4) + eval2 |= VERT_RGBA; + + if (ctx->Eval.Map1Normal) + eval1 |= VERT_NORM; + + if (ctx->Eval.Map2Normal) + eval2 |= VERT_NORM; + + if (ctx->Eval.Map1TextureCoord4 || + ctx->Eval.Map1TextureCoord3 || + ctx->Eval.Map1TextureCoord2 || + ctx->Eval.Map1TextureCoord1) + eval1 |= VERT_TEX0; + + if (ctx->Eval.Map2TextureCoord4 || + ctx->Eval.Map2TextureCoord3 || + ctx->Eval.Map2TextureCoord2 || + ctx->Eval.Map2TextureCoord1) + eval2 |= VERT_TEX0; + + if (ctx->Eval.Map1Vertex4) + eval1 |= VERT_OBJ_234; + + if (ctx->Eval.Map1Vertex3) + eval1 |= VERT_OBJ_23; + + if (ctx->Eval.Map2Vertex4) { + if (ctx->Eval.AutoNormal) + eval2 |= VERT_OBJ_234 | VERT_NORM; + else + eval2 |= VERT_OBJ_234; + } + else if (ctx->Eval.Map2Vertex3) { + if (ctx->Eval.AutoNormal) + eval2 |= VERT_OBJ_23 | VERT_NORM; + else + eval2 |= VERT_OBJ_23; + } + + tnl->eval.EvalMap1Flags = eval1; + tnl->eval.EvalMap2Flags = eval2; + tnl->eval.EvalNewState = 0; +} + + +/* This looks a lot like a pipeline stage, but for various reasons is + * better handled outside the pipeline, and considered the final stage + * of fixing up an immediate struct for execution. + * + * Really want to cache the results of this function in display lists, + * at least for EvalMesh commands. + */ +void _tnl_eval_immediate( GLcontext *ctx, struct immediate *IM ) +{ + TNLcontext *tnl = TNL_CONTEXT(ctx); + struct vertex_arrays *tmp = &tnl->imm_inputs; + struct immediate *store = tnl->eval.im; + GLuint *flags = IM->Flag + IM->CopyStart; + GLuint copycount; + GLuint orflag = IM->OrFlag; + GLuint any_eval1 = orflag & (VERT_EVAL_C1|VERT_EVAL_P1); + GLuint any_eval2 = orflag & (VERT_EVAL_C2|VERT_EVAL_P2); + GLuint req = 0; + GLuint purge_flags = 0; + GLfloat (*coord)[4] = IM->Obj + IM->CopyStart; + + if (IM->AndFlag & VERT_EVAL_ANY) + copycount = IM->Start - IM->CopyStart; /* just copy copied vertices */ + else + copycount = IM->Count - IM->CopyStart; /* copy all vertices */ + +/* fprintf(stderr, "%s copystart %d start %d count %d copycount %d\n", */ +/* __FUNCTION__, IM->CopyStart, IM->Start, IM->Count, copycount); */ + + if (!store) + store = tnl->eval.im = _tnl_alloc_immediate( ctx ); + + if (tnl->eval.EvalNewState & _NEW_EVAL) + update_eval( ctx ); + + if (any_eval1) { + req |= tnl->pipeline.inputs & tnl->eval.EvalMap1Flags; + + if (!ctx->Eval.Map1Vertex4 && !ctx->Eval.Map1Vertex3) + purge_flags = (VERT_EVAL_P1|VERT_EVAL_C1); + + if (orflag & VERT_EVAL_P1) { + eval_points1( store->Obj + IM->CopyStart, + coord, flags, + ctx->Eval.MapGrid1du, + ctx->Eval.MapGrid1u1); + + coord = store->Obj + IM->CopyStart; + } + } + + if (any_eval2) { + req |= tnl->pipeline.inputs & tnl->eval.EvalMap2Flags; + + if (!ctx->Eval.Map2Vertex4 && !ctx->Eval.Map2Vertex3) + purge_flags |= (VERT_EVAL_P2|VERT_EVAL_C2); + + if (orflag & VERT_EVAL_P2) { + eval_points2( store->Obj + IM->CopyStart, + coord, flags, + ctx->Eval.MapGrid2du, + ctx->Eval.MapGrid2u1, + ctx->Eval.MapGrid2dv, + ctx->Eval.MapGrid2v1 ); + + coord = store->Obj + IM->CopyStart; + } + } + + +/* _tnl_print_vert_flags(__FUNCTION__, req); */ + + /* Perform the evaluations on active data elements. + */ + if (req & VERT_INDEX) + { + GLuint generated = 0; + + if (copycount) + copy_1ui( store->Index + IM->CopyStart, tmp->Index.data, copycount ); + + tmp->Index.data = store->Index + IM->CopyStart; + tmp->Index.start = store->Index + IM->CopyStart; + + if (ctx->Eval.Map1Index && any_eval1) { + eval1_1ui( &tmp->Index, coord, flags, &ctx->EvalMap.Map1Index ); + generated |= VERT_EVAL_C1|VERT_EVAL_P1; + } + + if (ctx->Eval.Map2Index && any_eval2) { + eval2_1ui( &tmp->Index, coord, flags, &ctx->EvalMap.Map2Index ); + generated |= VERT_EVAL_C2|VERT_EVAL_P2; + } + + /* Propogate values to generate correct vertices when vertex + * maps are disabled. + */ + if (purge_flags & generated) + _tnl_fixup_1ui( tmp->Index.data, flags, 0, + VERT_INDEX| + VERT_OBJ| + generated| + (VERT_EVAL_ANY&~purge_flags) ); + } + + if (req & VERT_RGBA) + { + GLuint generated = 0; + + if (copycount) + copy_4f_stride( store->Color + IM->CopyStart, + (GLfloat *)tmp->Color.Ptr, + tmp->Color.StrideB, + copycount ); + + tmp->Color.Ptr = store->Color + IM->CopyStart; + tmp->Color.StrideB = 4 * sizeof(GLfloat); + tmp->Color.Flags = 0; + tnl->vb.importable_data &= ~VERT_RGBA; + + if (ctx->Eval.Map1Color4 && any_eval1) { + eval1_4f_ca( &tmp->Color, coord, flags, 4, &ctx->EvalMap.Map1Color4 ); + generated |= VERT_EVAL_C1|VERT_EVAL_P1; + } + + if (ctx->Eval.Map2Color4 && any_eval2) { + eval2_4f_ca( &tmp->Color, coord, flags, 4, &ctx->EvalMap.Map2Color4 ); + generated |= VERT_EVAL_C2|VERT_EVAL_P2; + } + + /* Propogate values to generate correct vertices when vertex + * maps are disabled. + */ + if (purge_flags & generated) + _tnl_fixup_4f( store->Color + IM->CopyStart, + flags, 0, + VERT_RGBA| + VERT_OBJ| + generated| + (VERT_EVAL_ANY&~purge_flags) ); + } + + + if (req & VERT_TEX(0)) + { + GLuint generated = 0; + + if (copycount) + copy_4f( store->TexCoord[0] + IM->CopyStart, + tmp->TexCoord[0].data, copycount ); + else + tmp->TexCoord[0].size = 0; + + tmp->TexCoord[0].data = store->TexCoord[0] + IM->CopyStart; + tmp->TexCoord[0].start = (GLfloat *)tmp->TexCoord[0].data; + + if (any_eval1) { + if (ctx->Eval.Map1TextureCoord4) { + eval1_4f( &tmp->TexCoord[0], coord, flags, 4, + &ctx->EvalMap.Map1Texture4 ); + generated |= VERT_EVAL_C1|VERT_EVAL_P1; + } + else if (ctx->Eval.Map1TextureCoord3) { + eval1_4f( &tmp->TexCoord[0], coord, flags, 3, + &ctx->EvalMap.Map1Texture3 ); + generated |= VERT_EVAL_C1|VERT_EVAL_P1; + } + else if (ctx->Eval.Map1TextureCoord2) { + eval1_4f( &tmp->TexCoord[0], coord, flags, 2, + &ctx->EvalMap.Map1Texture2 ); + generated |= VERT_EVAL_C1|VERT_EVAL_P1; + } + else if (ctx->Eval.Map1TextureCoord1) { + eval1_4f( &tmp->TexCoord[0], coord, flags, 1, + &ctx->EvalMap.Map1Texture1 ); + generated |= VERT_EVAL_C1|VERT_EVAL_P1; + } + } + + if (any_eval2) { + if (ctx->Eval.Map2TextureCoord4) { + eval2_4f( &tmp->TexCoord[0], coord, flags, 4, + &ctx->EvalMap.Map2Texture4 ); + generated |= VERT_EVAL_C2|VERT_EVAL_P2; + } + else if (ctx->Eval.Map2TextureCoord3) { + eval2_4f( &tmp->TexCoord[0], coord, flags, 3, + &ctx->EvalMap.Map2Texture3 ); + generated |= VERT_EVAL_C2|VERT_EVAL_P2; + } + else if (ctx->Eval.Map2TextureCoord2) { + eval2_4f( &tmp->TexCoord[0], coord, flags, 2, + &ctx->EvalMap.Map2Texture2 ); + generated |= VERT_EVAL_C2|VERT_EVAL_P2; + } + else if (ctx->Eval.Map2TextureCoord1) { + eval2_4f( &tmp->TexCoord[0], coord, flags, 1, + &ctx->EvalMap.Map2Texture1 ); + generated |= VERT_EVAL_C2|VERT_EVAL_P2; + } + } + + /* Propogate values to generate correct vertices when vertex + * maps are disabled. + */ + if (purge_flags & generated) + _tnl_fixup_4f( tmp->TexCoord[0].data, flags, 0, + VERT_TEX0| + VERT_OBJ| + generated| + (VERT_EVAL_ANY&~purge_flags) ); + } + + + if (req & VERT_NORM) + { + GLuint generated = 0; + + if (copycount) { +/* fprintf(stderr, "%s: Copy normals\n", __FUNCTION__); */ + copy_3f( store->Normal + IM->CopyStart, tmp->Normal.data, + copycount ); + } + + tmp->Normal.data = store->Normal + IM->CopyStart; + tmp->Normal.start = (GLfloat *)tmp->Normal.data; + + if (ctx->Eval.Map1Normal && any_eval1) { + eval1_norm( &tmp->Normal, coord, flags, + &ctx->EvalMap.Map1Normal ); + generated |= VERT_EVAL_C1|VERT_EVAL_P1; + } + + if (ctx->Eval.Map2Normal && any_eval2) { + eval2_norm( &tmp->Normal, coord, flags, + &ctx->EvalMap.Map2Normal ); + generated |= VERT_EVAL_C2|VERT_EVAL_P2; + } + + /* Propogate values to generate correct vertices when vertex + * maps are disabled. + */ + if (purge_flags & generated) + _tnl_fixup_3f( tmp->Normal.data, flags, 0, + VERT_NORM| + VERT_OBJ| + generated| + (VERT_EVAL_ANY&~purge_flags) ); + } + + + + /* In the AutoNormal case, the copy and assignment of tmp->NormalPtr + * are done above. + */ + if (req & VERT_OBJ) + { + if (copycount) { + /* This copy may already have occurred when eliminating + * glEvalPoint calls: + */ + if (coord != store->Obj + IM->CopyStart) + copy_4f( store->Obj + IM->CopyStart, tmp->Obj.data, copycount ); + } else + tmp->Obj.size = 0; + + tmp->Obj.data = store->Obj + IM->CopyStart; + tmp->Obj.start = (GLfloat *)tmp->Obj.data; + + /* Note: Normal data is already prepared above. + */ + + if (any_eval1) { + if (ctx->Eval.Map1Vertex4) { + eval1_4f( &tmp->Obj, coord, flags, 4, + &ctx->EvalMap.Map1Vertex4 ); + } + else if (ctx->Eval.Map1Vertex3) { + eval1_4f( &tmp->Obj, coord, flags, 3, + &ctx->EvalMap.Map1Vertex3 ); + } + } + + if (any_eval2) { + if (ctx->Eval.Map2Vertex4) + { + if (ctx->Eval.AutoNormal && (req & VERT_NORM)) + eval2_obj_norm( &tmp->Obj, &tmp->Normal, coord, flags, 4, + &ctx->EvalMap.Map2Vertex4 ); + else + eval2_4f( &tmp->Obj, coord, flags, 4, + &ctx->EvalMap.Map2Vertex4 ); + } + else if (ctx->Eval.Map2Vertex3) + { + if (ctx->Eval.AutoNormal && (req & VERT_NORM)) + eval2_obj_norm( &tmp->Obj, &tmp->Normal, coord, flags, 3, + &ctx->EvalMap.Map2Vertex3 ); + else + eval2_4f( &tmp->Obj, coord, flags, 3, + &ctx->EvalMap.Map2Vertex3 ); + } + } + } + + + /* Calculate new IM->Elts, IM->Primitive, IM->PrimitiveLength for + * the case where vertex maps are not enabled for some received eval + * coordinates. + */ + if (purge_flags) { + GLuint vertex = VERT_OBJ|(VERT_EVAL_ANY & ~purge_flags); + GLuint last_new_prim = 0; + GLuint new_prim_length = 0; + GLuint next_old_prim = 0; + struct vertex_buffer *VB = &tnl->vb; + GLuint i,j,count = VB->Count; + +/* fprintf(stderr, "PURGING\n"); */ + + for (i = 0, j = 0 ; i < count ; i++) { + if (flags[i] & vertex) { + store->Elt[j++] = i; + new_prim_length++; + } + if (i == next_old_prim) { + next_old_prim += VB->PrimitiveLength[i]; + VB->PrimitiveLength[last_new_prim] = new_prim_length; + VB->Primitive[j] = VB->Primitive[i]; + last_new_prim = j; + } + } + + VB->Elts = store->Elt; + _tnl_get_purged_copy_verts( ctx, store ); + } + + /* Produce new flags array: + */ + { + GLuint i; + GLuint count = tnl->vb.Count + 1; + + copy_1ui( store->Flag, flags, count ); + tnl->vb.Flag = store->Flag; + for (i = 0 ; i < count ; i++) + store->Flag[i] |= req; + IM->CopyOrFlag |= req; /* hack for copying. */ + } +} Index: dll/opengl/opengl32/mesa/tnl/t_imm_eval.h =================================================================== --- dll/opengl/opengl32/mesa/tnl/t_imm_eval.h (revision 0) +++ dll/opengl/opengl32/mesa/tnl/t_imm_eval.h (working copy) @@ -0,0 +1,39 @@ +/* $Id: t_imm_eval.h,v 1.3 2001/04/30 21:08:52 keithw Exp $ */ + +/* + * Mesa 3-D graphics library + * Version: 3.5 + * + * Copyright (C) 1999-2001 Brian Paul 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 + * BRIAN PAUL 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. + */ + + +#ifndef _T_IMM_EVAL_H +#define _T_IMM_EVAL_H + + +#include "mtypes.h" +#include "t_context.h" + +extern void _tnl_eval_init( void ); + +extern void _tnl_eval_immediate( GLcontext *ctx, struct immediate *IM ); + +#endif Index: dll/opengl/opengl32/mesa/tnl/t_imm_exec.c =================================================================== --- dll/opengl/opengl32/mesa/tnl/t_imm_exec.c (revision 0) +++ dll/opengl/opengl32/mesa/tnl/t_imm_exec.c (working copy) @@ -0,0 +1,551 @@ +/* $Id: t_imm_exec.c,v 1.26 2001/05/16 09:28:32 keithw Exp $ */ + +/* + * Mesa 3-D graphics library + * Version: 3.5 + * + * Copyright (C) 1999-2001 Brian Paul 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 + * BRIAN PAUL 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. + * + * Authors: + * Keith Whitwell + */ + + +#include "glheader.h" +#include "colormac.h" +#include "context.h" +#include "enums.h" +#include "dlist.h" +#include "macros.h" +#include "mem.h" +#include "mmath.h" +#include "light.h" +#include "state.h" +#include "mtypes.h" + +#include "math/m_matrix.h" +#include "math/m_xform.h" + +#include "t_context.h" +#include "t_array_import.h" +#include "t_imm_alloc.h" +#include "t_imm_api.h" +#include "t_imm_debug.h" +#include "t_imm_dlist.h" +#include "t_imm_eval.h" +#include "t_imm_elt.h" +#include "t_imm_exec.h" +#include "t_imm_fixup.h" +#include "t_pipeline.h" + + + +static void reset_input( GLcontext *ctx, + GLuint start, + GLuint beginstate, + GLuint savedbeginstate ) +{ + struct immediate *IM = TNL_CURRENT_IM(ctx); + + /* Clear the dirty part of the flag array. + */ + if (start < IM->Count+2) + MEMSET(IM->Flag + start, 0, sizeof(GLuint) * (IM->Count+2-start)); + + IM->Start = start; + IM->Count = start; + IM->LastMaterial = start; + IM->BeginState = beginstate; + IM->SavedBeginState = savedbeginstate; + IM->TexSize = 0; + IM->MaterialOrMask = 0; + + if (IM->MaterialMask) + IM->MaterialMask[IM->Start] = 0; + + IM->ArrayEltFlags = ~ctx->Array._Enabled; + IM->ArrayEltIncr = ctx->Array.Vertex.Enabled ? 1 : 0; + IM->ArrayEltFlush = ctx->Array.LockCount ? FLUSH_ELT_LAZY : FLUSH_ELT_EAGER; +} + +void _tnl_reset_exec_input( GLcontext *ctx, + GLuint start, + GLuint beginstate, + GLuint savedbeginstate ) +{ + TNLcontext *tnl = TNL_CONTEXT(ctx); + struct immediate *IM = TNL_CURRENT_IM(ctx); + + reset_input( ctx, start, beginstate, savedbeginstate ); + + IM->CopyStart = start - tnl->ExecCopyCount; + IM->Primitive[IM->CopyStart] = ctx->Driver.CurrentExecPrimitive; + if (tnl->ExecParity) + IM->Primitive[IM->CopyStart] |= PRIM_PARITY; + + IM->LastPrimitive = IM->CopyStart; +} + + +void _tnl_reset_compile_input( GLcontext *ctx, + GLuint start, + GLuint beginstate, + GLuint savedbeginstate ) +{ + struct immediate *IM = TNL_CURRENT_IM(ctx); + + reset_input( ctx, start, beginstate, savedbeginstate ); + IM->CopyStart = start; + IM->LastPrimitive = IM->Start; +} + + +void _tnl_copy_to_current( GLcontext *ctx, struct immediate *IM, + GLuint flag ) +{ + GLuint count = IM->LastData; + + if (MESA_VERBOSE&VERBOSE_IMMEDIATE) + _tnl_print_vert_flags("copy to current", flag); + + if (flag & VERT_NORM) + COPY_3FV( ctx->Current.Normal, IM->Normal[count]); + + if (flag & VERT_INDEX) + ctx->Current.Index = IM->Index[count]; + + if (flag & VERT_EDGE) + ctx->Current.EdgeFlag = IM->EdgeFlag[count]; + + if (flag & VERT_RGBA) { + COPY_4FV(ctx->Current.Color, IM->Color[count]); + if (ctx->Light.ColorMaterialEnabled) { + _mesa_update_color_material( ctx, ctx->Current.Color ); + _mesa_validate_all_lighting_tables( ctx ); + } + } + + if (flag & VERT_SPEC_RGB) + COPY_4FV(ctx->Current.SecondaryColor, IM->SecondaryColor[count]); + + if (flag & VERT_FOG_COORD) + ctx->Current.FogCoord = IM->FogCoord[count]; + + if (flag & VERT_TEX_ANY) { + GLuint i; + for (i = 0 ; i < ctx->Const.MaxTextureUnits ; i++) { + if (flag & VERT_TEX(i)) { + COPY_4FV( ctx->Current.Texcoord[0], IM->TexCoord[0][count]); + } + } + } + + if (flag & VERT_MATERIAL) { + _mesa_update_material( ctx, + IM->Material[IM->LastMaterial], + IM->MaterialOrMask ); + + _mesa_validate_all_lighting_tables( ctx ); + } +} + + + +void _tnl_compute_orflag( struct immediate *IM, GLuint start ) +{ + GLuint count = IM->Count; + GLuint orflag = 0; + GLuint andflag = ~0U; + GLuint i; + + IM->LastData = count-1; + + + /* Compute the flags for the whole buffer. + */ + for (i = start ; i < count ; i++) { + andflag &= IM->Flag[i]; + orflag |= IM->Flag[i]; + } + + /* It is possible there will be data in the buffer arising from + * calls like 'glNormal', 'glMaterial' that occur after the final + * glVertex, glEval, etc. Additionally, a buffer can consist of + * eg. a single glMaterial call, in which case IM->Start == + * IM->Count, but the buffer is definitely not empty. + */ + if (IM->Flag[i] & VERT_DATA) { + IM->LastData++; + orflag |= IM->Flag[i]; + } + + IM->Flag[IM->LastData+1] |= VERT_END_VB; + IM->CopyAndFlag = IM->AndFlag = andflag; + IM->CopyOrFlag = IM->OrFlag = orflag; +} + + + + + + + + +/* Note: The 'start' member of the GLvector structs is now redundant + * because we always re-transform copied vertices, and the vectors + * below are set up so that the first copied vertex (if any) appears + * at position zero. + */ +static void _tnl_vb_bind_immediate( GLcontext *ctx, struct immediate *IM ) +{ + TNLcontext *tnl = TNL_CONTEXT(ctx); + struct vertex_buffer *VB = &tnl->vb; + struct vertex_arrays *tmp = &tnl->imm_inputs; + GLuint inputs = tnl->pipeline.inputs; /* for copy-to-current */ + GLuint start = IM->CopyStart; + GLuint count = IM->Count - start; + + /* TODO: optimize the case where nothing has changed. (Just bind + * tmp to vb). + */ + + /* Setup constant data in the VB. + */ + VB->Count = count; + VB->FirstClipped = IMM_MAXDATA - IM->CopyStart; + VB->import_data = 0; + VB->importable_data = 0; + + /* Need an IM->FirstPrimitive? + */ + VB->Primitive = IM->Primitive + IM->CopyStart; + VB->PrimitiveLength = IM->PrimitiveLength + IM->CopyStart; + VB->FirstPrimitive = 0; + + VB->Flag = IM->Flag + start; + + /* TexCoordPtr's are zeroed in loop below. + */ + VB->NormalPtr = 0; + VB->FogCoordPtr = 0; + VB->EdgeFlag = 0; + VB->IndexPtr[0] = 0; + VB->IndexPtr[1] = 0; + VB->ColorPtr[0] = 0; + VB->ColorPtr[1] = 0; + VB->SecondaryColorPtr[0] = 0; + VB->SecondaryColorPtr[1] = 0; + VB->Elts = 0; + VB->MaterialMask = 0; + VB->Material = 0; + +/* _tnl_print_vert_flags("copy-orflag", IM->CopyOrFlag); */ +/* _tnl_print_vert_flags("orflag", IM->OrFlag); */ +/* _tnl_print_vert_flags("inputs", inputs); */ + + /* Setup the initial values of array pointers in the vb. + */ + if (inputs & VERT_OBJ) { + tmp->Obj.data = IM->Obj + start; + tmp->Obj.start = (GLfloat *)(IM->Obj + start); + tmp->Obj.count = count; + VB->ObjPtr = &tmp->Obj; + if ((IM->CopyOrFlag & VERT_OBJ_234) == VERT_OBJ_234) + tmp->Obj.size = 4; + else if ((IM->CopyOrFlag & VERT_OBJ_234) == VERT_OBJ_23) + tmp->Obj.size = 3; + else + tmp->Obj.size = 2; + } + + if (inputs & VERT_NORM) { + tmp->Normal.data = IM->Normal + start; + tmp->Normal.start = (GLfloat *)(IM->Normal + start); + tmp->Normal.count = count; + VB->NormalPtr = &tmp->Normal; + } + + if (inputs & VERT_INDEX) { + tmp->Index.count = count; + tmp->Index.data = IM->Index + start; + tmp->Index.start = IM->Index + start; + VB->IndexPtr[0] = &tmp->Index; + } + + if (inputs & VERT_FOG_COORD) { + tmp->FogCoord.data = IM->FogCoord + start; + tmp->FogCoord.start = IM->FogCoord + start; + tmp->FogCoord.count = count; + VB->FogCoordPtr = &tmp->FogCoord; + } + + if (inputs & VERT_SPEC_RGB) { + tmp->SecondaryColor.Ptr = IM->SecondaryColor + start; + VB->SecondaryColorPtr[0] = &tmp->SecondaryColor; + } + + if (inputs & VERT_EDGE) { + VB->EdgeFlag = IM->EdgeFlag + start; + } + + if (inputs & VERT_RGBA) { + if (IM->CopyOrFlag & VERT_RGBA) { + tmp->Color.Ptr = IM->Color + start; + tmp->Color.StrideB = 4 * sizeof(GLfloat); + tmp->Color.Flags = 0; + } else { + tmp->Color.Ptr = ctx->Current.Color; + tmp->Color.StrideB = 0; + tmp->Color.Flags = CA_CLIENT_DATA; /* hack */ + VB->import_source = IM; + VB->importable_data |= VERT_RGBA; + VB->import_data = _tnl_upgrade_current_data; + } + VB->ColorPtr[0] = &tmp->Color; + } + + if (inputs & VERT_TEX_ANY) { + GLuint i; + for (i = 0; i < ctx->Const.MaxTextureUnits; i++) { + VB->TexCoordPtr[i] = 0; + if (inputs & VERT_TEX(i)) { + tmp->TexCoord[i].count = count; + tmp->TexCoord[i].data = IM->TexCoord[i] + start; + tmp->TexCoord[i].start = (GLfloat *)(IM->TexCoord[i] + start); + tmp->TexCoord[i].size = 2; + if (IM->TexSize & TEX_SIZE_3(i)) { + tmp->TexCoord[i].size = 3; + if (IM->TexSize & TEX_SIZE_4(i)) + tmp->TexCoord[i].size = 4; + } + VB->TexCoordPtr[i] = &tmp->TexCoord[i]; + } + } + } + + if ((inputs & VERT_MATERIAL) && IM->Material) { + VB->MaterialMask = IM->MaterialMask + start; + VB->Material = IM->Material + start; + } +} + + + + +/* Called by exec_vert_cassette, execute_compiled_cassette, but not + * exec_elt_cassette. + */ +void _tnl_run_cassette( GLcontext *ctx, struct immediate *IM ) +{ + TNLcontext *tnl = TNL_CONTEXT(ctx); + + _tnl_vb_bind_immediate( ctx, IM ); + + if (IM->CopyOrFlag & VERT_EVAL_ANY) + _tnl_eval_immediate( ctx, IM ); + + /* Invalidate all stored data before and after run: + */ + tnl->pipeline.run_input_changes |= tnl->pipeline.inputs; + tnl->Driver.RunPipeline( ctx ); + tnl->pipeline.run_input_changes |= tnl->pipeline.inputs; + + _tnl_copy_to_current( ctx, IM, IM->OrFlag ); +} + + +/* Called for regular vertex cassettes. + */ +static void exec_vert_cassette( GLcontext *ctx, struct immediate *IM ) +{ + if (IM->FlushElt) { + /* Orflag is computed twice, but only reach this code if app is + * using a mixture of glArrayElement() and glVertex() while + * arrays are locked (else would be in exec_elt_cassette now). + */ + ASSERT(ctx->Array.LockCount); + ASSERT(IM->FlushElt == FLUSH_ELT_LAZY); + _tnl_translate_array_elts( ctx, IM, IM->CopyStart, IM->Count ); + _tnl_compute_orflag( IM, IM->CopyStart ); + } + + _tnl_fixup_input( ctx, IM ); +/* _tnl_print_cassette( IM ); */ + _tnl_run_cassette( ctx, IM ); +} + + +/* Called for pure, locked VERT_ELT cassettes instead of + * _tnl_run_cassette. + */ +static void exec_elt_cassette( GLcontext *ctx, struct immediate *IM ) +{ + TNLcontext *tnl = TNL_CONTEXT(ctx); + struct vertex_buffer *VB = &tnl->vb; + + _tnl_vb_bind_arrays( ctx, ctx->Array.LockFirst, ctx->Array.LockCount ); + + /* Take only elements and primitive information from the immediate: + */ + VB->Elts = IM->Elt + IM->CopyStart; + VB->Primitive = IM->Primitive + IM->CopyStart; + VB->PrimitiveLength = IM->PrimitiveLength + IM->CopyStart; + VB->FirstPrimitive = 0; + + /* Run the pipeline. No input changes as a result of this action. + */ + tnl->Driver.RunPipeline( ctx ); + + /* Still need to update current values: + */ + if (ctx->Driver.CurrentExecPrimitive == GL_POLYGON+1) { + _tnl_translate_array_elts( ctx, IM, IM->LastData, IM->LastData ); + _tnl_copy_to_current( ctx, IM, ctx->Array._Enabled ); + } +} + + +static void +exec_empty_cassette( GLcontext *ctx, struct immediate *IM ) +{ + if (IM->FlushElt) + _tnl_translate_array_elts( ctx, IM, IM->CopyStart, IM->CopyStart ); + + _tnl_copy_to_current( ctx, IM, IM->OrFlag ); +} + + + +/* Called for all cassettes when not compiling or playing a display + * list. + */ +void _tnl_execute_cassette( GLcontext *ctx, struct immediate *IM ) +{ + TNLcontext *tnl = TNL_CONTEXT(ctx); + + _tnl_compute_orflag( IM, IM->Start ); + _tnl_copy_immediate_vertices( ctx, IM ); + _tnl_get_exec_copy_verts( ctx, IM ); + + if (tnl->pipeline.build_state_changes) + _tnl_validate_pipeline( ctx ); + + if (IM->CopyStart == IM->Count) { + exec_empty_cassette( ctx, IM ); + } + else if ((IM->CopyOrFlag & VERT_DATA) == VERT_ELT && + ctx->Array.LockCount && + ctx->Array.Vertex.Enabled) { + exec_elt_cassette( ctx, IM ); + } + else { + exec_vert_cassette( ctx, IM ); + } + + /* Only reuse the immediate if there are no copied vertices living + * inside it: + */ + { + GLuint begin_state = IM->BeginState & (VERT_BEGIN_0|VERT_BEGIN_1); + GLuint saved_begin_state = IM->SavedBeginState; + + if (--IM->ref_count != 0) { + IM = _tnl_alloc_immediate( ctx ); + SET_IMMEDIATE( ctx, IM ); + } + + IM->ref_count++; + + _tnl_reset_exec_input( ctx, IMM_MAX_COPIED_VERTS, + begin_state, saved_begin_state ); + } + + if (ctx->Driver.CurrentExecPrimitive == GL_POLYGON+1) + ctx->Driver.NeedFlush &= ~FLUSH_STORED_VERTICES; +} + + + + +/* Setup vector pointers that will be used to bind immediates to VB's. + */ +void _tnl_imm_init( GLcontext *ctx ) +{ + TNLcontext *tnl = TNL_CONTEXT(ctx); + struct vertex_arrays *tmp = &tnl->imm_inputs; + GLuint i; + static int firsttime = 1; + + if (firsttime) { + firsttime = 0; + _tnl_imm_elt_init(); + } + + ctx->swtnl_im = _tnl_alloc_immediate( ctx ); + TNL_CURRENT_IM(ctx)->ref_count++; + + tnl->ExecCopyTexSize = 0; + tnl->ExecCopyCount = 0; + tnl->ExecCopySource = 0; + + TNL_CURRENT_IM(ctx)->CopyStart = IMM_MAX_COPIED_VERTS; + + _mesa_vector4f_init( &tmp->Obj, 0, 0 ); + _mesa_vector3f_init( &tmp->Normal, 0, 0 ); + + tmp->Color.Ptr = 0; + tmp->Color.Type = GL_FLOAT; + tmp->Color.Size = 4; + tmp->Color.Stride = 0; + tmp->Color.StrideB = 4 * sizeof(GLfloat); + tmp->Color.Flags = 0; + + tmp->SecondaryColor.Ptr = 0; + tmp->SecondaryColor.Type = GL_FLOAT; + tmp->SecondaryColor.Size = 4; + tmp->SecondaryColor.Stride = 0; + tmp->SecondaryColor.StrideB = 4 * sizeof(GLfloat); + tmp->SecondaryColor.Flags = 0; + + _mesa_vector1f_init( &tmp->FogCoord, 0, 0 ); + _mesa_vector1ui_init( &tmp->Index, 0, 0 ); + _mesa_vector1ub_init( &tmp->EdgeFlag, 0, 0 ); + + for (i = 0; i < ctx->Const.MaxTextureUnits; i++) + _mesa_vector4f_init( &tmp->TexCoord[i], 0, 0); + + /* Install the first immediate. Intially outside begin/end. + */ + _tnl_reset_exec_input( ctx, IMM_MAX_COPIED_VERTS, 0, 0 ); + tnl->ReplayHardBeginEnd = 0; + + _tnl_imm_vtxfmt_init( ctx ); +} + + +void _tnl_imm_destroy( GLcontext *ctx ) +{ + if (TNL_CURRENT_IM(ctx)) { + TNL_CURRENT_IM(ctx)->ref_count--; + if (TNL_CURRENT_IM(ctx)->ref_count == 0) + _tnl_free_immediate( TNL_CURRENT_IM(ctx) ); + SET_IMMEDIATE(ctx, 0); + } +} Index: dll/opengl/opengl32/mesa/tnl/t_imm_exec.h =================================================================== --- dll/opengl/opengl32/mesa/tnl/t_imm_exec.h (revision 0) +++ dll/opengl/opengl32/mesa/tnl/t_imm_exec.h (working copy) @@ -0,0 +1,70 @@ +/* $Id: t_imm_exec.h,v 1.6 2001/05/11 08:11:31 keithw Exp $ */ + +/* + * Mesa 3-D graphics library + * Version: 3.5 + * + * Copyright (C) 1999-2001 Brian Paul 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 + * BRIAN PAUL 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. + */ + + +#ifndef _T_VBXFORM_H +#define _T_VBXFORM_H + +#include "mtypes.h" +#include "t_context.h" + + +/* Hook for ctx->Driver.FlushVertices: + */ +extern void _tnl_flush_vertices( GLcontext *ctx, GLuint flush_flags ); + +/* Called from imm_api.c and _tnl_flush_vertices: + */ +extern void _tnl_flush_immediate( struct immediate *IM ); + +/* Called from imm_dlist.c and _tnl_flush_immediate: + */ +extern void _tnl_run_cassette( GLcontext *ctx, struct immediate *IM ); +extern void _tnl_copy_to_current( GLcontext *ctx, struct immediate *IM, + GLuint flag ); + +/* Initialize some stuff: + */ +extern void _tnl_imm_init( GLcontext *ctx ); + +extern void _tnl_imm_destroy( GLcontext *ctx ); + +extern void _tnl_reset_exec_input( GLcontext *ctx, + GLuint start, + GLuint beginstate, + GLuint savedbeginstate ); + +extern void _tnl_reset_compile_input( GLcontext *ctx, + GLuint start, + GLuint beginstate, + GLuint savedbeginstate ); + +extern void _tnl_compute_orflag( struct immediate *IM, GLuint start ); +extern void _tnl_execute_cassette( GLcontext *ctx, struct immediate *IM ); + + + +#endif Index: dll/opengl/opengl32/mesa/tnl/t_imm_fixup.c =================================================================== --- dll/opengl/opengl32/mesa/tnl/t_imm_fixup.c (revision 0) +++ dll/opengl/opengl32/mesa/tnl/t_imm_fixup.c (working copy) @@ -0,0 +1,767 @@ +/* $Id: t_imm_fixup.c,v 1.21 2001/06/13 14:57:55 brianp Exp $ */ + +/* + * Mesa 3-D graphics library + * Version: 3.5 + * + * Copyright (C) 1999-2001 Brian Paul 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 + * BRIAN PAUL 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. + */ + +/* + * Authors: + * Keith Whitwell + */ + + +#include "glheader.h" +#include "context.h" +#include "enums.h" +#include "dlist.h" +#include "colormac.h" +#include "light.h" +#include "macros.h" +#include "mem.h" +#include "mmath.h" +#include "state.h" +#include "mtypes.h" + +#include "math/m_matrix.h" +#include "math/m_xform.h" + +#include "t_context.h" +#include "t_imm_alloc.h" +#include "t_imm_debug.h" +#include "t_imm_elt.h" +#include "t_imm_fixup.h" +#include "t_pipeline.h" + + +static const GLuint increment[GL_POLYGON+2] = { 1,2,1,1,3,1,1,4,2,1,1 }; +static const GLuint intro[GL_POLYGON+2] = { 0,0,2,2,0,2,2,0,2,2,0 }; + +void +_tnl_fixup_4f( GLfloat data[][4], GLuint flag[], GLuint start, GLuint match ) +{ + GLuint i = start; + + for (;;) { + if ((flag[++i] & match) == 0) { + COPY_4FV(data[i], data[i-1]); + if (flag[i] & VERT_END_VB) break; + } + } +} + +void +_tnl_fixup_3f( float data[][3], GLuint flag[], GLuint start, GLuint match ) +{ + GLuint i = start; + + for (;;) { + if ((flag[++i] & match) == 0) { + COPY_3V(data[i], data[i-1]); + if (flag[i] & VERT_END_VB) break; + } + } +} + + +void +_tnl_fixup_1ui( GLuint *data, GLuint flag[], GLuint start, GLuint match ) +{ + GLuint i = start; + + for (;;) { + if ((flag[++i] & match) == 0) { + data[i] = data[i-1]; + if (flag[i] & VERT_END_VB) break; + } + } + flag[i] |= match; +} + + +void +_tnl_fixup_1f( GLfloat *data, GLuint flag[], GLuint start, GLuint match ) +{ + GLuint i = start; + + for (;;) { + if ((flag[++i] & match) == 0) { + data[i] = data[i-1]; + if (flag[i] & VERT_END_VB) break; + } + } + flag[i] |= match; +} + +void +_tnl_fixup_1ub( GLubyte *data, GLuint flag[], GLuint start, GLuint match ) +{ + GLuint i = start; + + for (;;) { + if ((flag[++i] & match) == 0) { + data[i] = data[i-1]; + if (flag[i] & VERT_END_VB) break; + } + } + flag[i] |= match; +} + + +static void +fixup_first_4f( GLfloat data[][4], GLuint flag[], GLuint match, + GLuint start, GLfloat *dflt ) +{ + GLuint i = start-1; + match |= VERT_END_VB; + + while ((flag[++i]&match) == 0) + COPY_4FV(data[i], dflt); +} + +static void +fixup_first_3f( GLfloat data[][3], GLuint flag[], GLuint match, + GLuint start, GLfloat *dflt ) +{ + GLuint i = start-1; + match |= VERT_END_VB; + + while ((flag[++i]&match) == 0) + COPY_3FV(data[i], dflt); +} + + +static void +fixup_first_1ui( GLuint data[], GLuint flag[], GLuint match, + GLuint start, GLuint dflt ) +{ + GLuint i = start-1; + match |= VERT_END_VB; + + while ((flag[++i]&match) == 0) + data[i] = dflt; +} + +static void +fixup_first_1f( GLfloat data[], GLuint flag[], GLuint match, + GLuint start, GLfloat dflt ) +{ + GLuint i = start-1; + match |= VERT_END_VB; + + while ((flag[++i]&match) == 0) + data[i] = dflt; +} + + +static void +fixup_first_1ub( GLubyte data[], GLuint flag[], GLuint match, + GLuint start, GLubyte dflt ) +{ + GLuint i = start-1; + match |= VERT_END_VB; + + while ((flag[++i]&match) == 0) + data[i] = dflt; +} + + +void _tnl_fixup_input( GLcontext *ctx, struct immediate *IM ) +{ + TNLcontext *tnl = TNL_CONTEXT(ctx); + GLuint start = IM->CopyStart; + GLuint andflag = IM->CopyAndFlag; + GLuint orflag = IM->CopyOrFlag; + GLuint fixup; + + IM->CopyTexSize = IM->TexSize; + +/* fprintf(stderr, "Fixup input, Start: %u Count: %u LastData: %u\n", */ +/* IM->Start, IM->Count, IM->LastData); */ +/* _tnl_print_vert_flags("Orflag", orflag); */ +/* _tnl_print_vert_flags("Andflag", andflag); */ + + + fixup = ~andflag & VERT_FIXUP; + + if (!ctx->CompileFlag) + fixup &= tnl->pipeline.inputs; + + if (!ctx->ExecuteFlag) + fixup &= orflag; + + if ((orflag & (VERT_OBJ|VERT_EVAL_ANY)) == 0) + fixup = 0; + + if (fixup) { + GLuint copy = fixup & ~IM->Flag[start]; + + + /* Equivalent to a lazy copy-from-current when setting up the + * immediate. + */ + if (ctx->ExecuteFlag && copy) { + + if (MESA_VERBOSE&VERBOSE_IMMEDIATE) + _tnl_print_vert_flags("copy from current", copy); + + if (copy & VERT_NORM) { + COPY_3V( IM->Normal[start], ctx->Current.Normal ); + } + + if (copy & VERT_RGBA) { + COPY_4FV( IM->Color[start], ctx->Current.Color); + } + + if (copy & VERT_SPEC_RGB) + COPY_4FV( IM->SecondaryColor[start], ctx->Current.SecondaryColor); + + if (copy & VERT_FOG_COORD) + IM->FogCoord[start] = ctx->Current.FogCoord; + + if (copy & VERT_INDEX) + IM->Index[start] = ctx->Current.Index; + + if (copy & VERT_EDGE) + IM->EdgeFlag[start] = ctx->Current.EdgeFlag; + + if (copy & VERT_TEX_ANY) { + GLuint i; + for (i = 0 ; i < ctx->Const.MaxTextureUnits ; i++) { + if (copy & VERT_TEX(i)) + COPY_4FV( IM->TexCoord[i][start], ctx->Current.Texcoord[i] ); + } + } + } + + if (MESA_VERBOSE&VERBOSE_IMMEDIATE) + _tnl_print_vert_flags("fixup", fixup); + + if (fixup & VERT_TEX_ANY) { + GLuint i; + for (i = 0 ; i < ctx->Const.MaxTextureUnits ; i++) { + if (fixup & VERT_TEX(i)) { + if (orflag & VERT_TEX(i)) + _tnl_fixup_4f( IM->TexCoord[i], IM->Flag, start, + VERT_TEX(i) ); + else + fixup_first_4f( IM->TexCoord[i], IM->Flag, VERT_END_VB, start, + IM->TexCoord[i][start]); + } + } + } + + + if (fixup & VERT_EDGE) { + if (orflag & VERT_EDGE) + _tnl_fixup_1ub( IM->EdgeFlag, IM->Flag, start, VERT_EDGE ); + else + fixup_first_1ub( IM->EdgeFlag, IM->Flag, VERT_END_VB, start, + IM->EdgeFlag[start] ); + } + + if (fixup & VERT_INDEX) { + if (orflag & VERT_INDEX) + _tnl_fixup_1ui( IM->Index, IM->Flag, start, VERT_INDEX ); + else + fixup_first_1ui( IM->Index, IM->Flag, VERT_END_VB, start, + IM->Index[start] ); + } + + if (fixup & VERT_RGBA) { + if (orflag & VERT_RGBA) + _tnl_fixup_4f( IM->Color, IM->Flag, start, VERT_RGBA ); + /* No need for else case as the drivers understand stride + * zero here. (TODO - propogate this) + */ + } + + if (fixup & VERT_SPEC_RGB) { + if (orflag & VERT_SPEC_RGB) + _tnl_fixup_4f( IM->SecondaryColor, IM->Flag, start, + VERT_SPEC_RGB ); + else + fixup_first_4f( IM->SecondaryColor, IM->Flag, VERT_END_VB, start, + IM->SecondaryColor[start] ); + } + + if (fixup & VERT_FOG_COORD) { + if (orflag & VERT_FOG_COORD) + _tnl_fixup_1f( IM->FogCoord, IM->Flag, start, VERT_FOG_COORD ); + else + fixup_first_1f( IM->FogCoord, IM->Flag, VERT_END_VB, start, + IM->FogCoord[start] ); + } + + if (fixup & VERT_NORM) { + if (orflag & VERT_NORM) + _tnl_fixup_3f( IM->Normal, IM->Flag, start, VERT_NORM ); + else + fixup_first_3f( IM->Normal, IM->Flag, VERT_END_VB, start, + IM->Normal[start] ); + } + } + + /* Prune possible half-filled slot. + */ + IM->Flag[IM->LastData+1] &= ~VERT_END_VB; + IM->Flag[IM->Count] |= VERT_END_VB; + + + /* Materials: + */ + if (IM->MaterialOrMask & ~IM->MaterialAndMask) { + GLuint vulnerable = IM->MaterialOrMask & IM->MaterialAndMask; + GLuint i = IM->Start; + + do { + while (!(IM->Flag[i] & VERT_MATERIAL)) + i++; + + vulnerable &= ~IM->MaterialMask[i]; + _mesa_copy_material_pairs( IM->Material[i], + ctx->Light.Material, + vulnerable ); + + + } while (vulnerable); + } +} + + + + +static void copy_material( struct immediate *next, + struct immediate *prev, + GLuint dst, GLuint src ) +{ + if (next->Material == 0) { + next->Material = (GLmaterial (*)[2]) MALLOC( sizeof(GLmaterial) * + IMM_SIZE * 2 ); + next->MaterialMask = (GLuint *) MALLOC( sizeof(GLuint) * IMM_SIZE ); + } + + next->MaterialMask[dst] = prev->MaterialOrMask; + MEMCPY(next->Material[dst], prev->Material[src], 2*sizeof(GLmaterial)); +} + +static GLboolean is_fan_like[GL_POLYGON+1] = { + GL_FALSE, + GL_FALSE, + GL_TRUE, /* line loop */ + GL_FALSE, + GL_FALSE, + GL_FALSE, + GL_TRUE, /* tri fan */ + GL_FALSE, + GL_FALSE, + GL_TRUE /* polygon */ +}; + + +/* Copy the untransformed data from the shared vertices of a primitive + * that wraps over two immediate structs. This is done prior to + * set_immediate so that prev and next may point to the same + * structure. In general it's difficult to avoid this copy on long + * primitives. + * + * Have to be careful with the transitions between display list + * replay, compile and normal execute modes. + */ +void _tnl_copy_immediate_vertices( GLcontext *ctx, struct immediate *next ) +{ + TNLcontext *tnl = TNL_CONTEXT(ctx); + struct immediate *prev = tnl->ExecCopySource; + struct vertex_arrays *inputs = &tnl->imm_inputs; + GLuint count = tnl->ExecCopyCount; + GLuint *elts = tnl->ExecCopyElts; + GLuint offset = IMM_MAX_COPIED_VERTS - count; + GLuint i; + + if (!prev) { + ASSERT(tnl->ExecCopyCount == 0); + return; + } + + next->CopyStart = next->Start - count; + + if ((prev->CopyOrFlag & VERT_DATA) == VERT_ELT && + ctx->Array.LockCount && + ctx->Array.Vertex.Enabled) + { + /* Copy Elt values only + */ + for (i = 0 ; i < count ; i++) + { + GLuint src = elts[i+offset]; + GLuint dst = next->CopyStart+i; + next->Elt[dst] = prev->Elt[src]; + next->Flag[dst] = VERT_ELT; + } + next->CopyOrFlag |= VERT_ELT; + next->CopyAndFlag &= VERT_ELT; + } + else { + /* prev->CopyOrFlag is hacked to include values generated by eval: + */ + GLuint copy = tnl->pipeline.inputs & prev->CopyOrFlag; + GLuint flag; + + if (is_fan_like[ctx->Driver.CurrentExecPrimitive]) { + next->TexSize |= tnl->ExecCopyTexSize; + next->CopyOrFlag |= (prev->CopyOrFlag & VERT_FIXUP); + next->CopyAndFlag &= (prev->CopyOrFlag & VERT_FIXUP); + flag = (prev->CopyOrFlag & VERT_FIXUP); + } + else { + /* Don't let an early 'glColor', etc. poison the elt path. + */ + next->CopyAndFlag &= (prev->OrFlag & VERT_FIXUP); + flag = (prev->OrFlag & VERT_FIXUP); + } + + + /* Copy whole vertices + */ + for (i = 0 ; i < count ; i++) + { + GLuint src = elts[i+offset]; + GLuint isrc = src - prev->CopyStart; + GLuint dst = next->CopyStart+i; + + /* Values subject to eval must be copied out of the 'inputs' + * struct. (Copied rows should not be evaluated twice). + * + * Note these pointers are null when inactive. + */ + COPY_4FV( next->Obj[dst], inputs->Obj.data[isrc] ); + + if (copy & VERT_NORM) + COPY_3FV( next->Normal[dst], inputs->Normal.data[isrc] ); + + if (copy & VERT_RGBA) + COPY_4FV( next->Color[dst], + ((GLfloat (*)[4])inputs->Color.Ptr)[isrc] ); + + if (copy & VERT_INDEX) + next->Index[dst] = inputs->Index.data[isrc]; + + if (copy & VERT_TEX_ANY) { + GLuint i; + for (i = 0 ; i < prev->MaxTextureUnits ; i++) { + if (copy & VERT_TEX(i)) + COPY_4FV( next->TexCoord[i][dst], + inputs->TexCoord[i].data[isrc] ); + } + } + + /* Remaining values should be the same in the 'input' struct and the + * original immediate. + */ + if (copy & (VERT_ELT|VERT_EDGE|VERT_SPEC_RGB|VERT_FOG_COORD| + VERT_MATERIAL)) { + + if (prev->Flag[src] & VERT_MATERIAL) + copy_material(next, prev, dst, src); + + next->Elt[dst] = prev->Elt[src]; + next->EdgeFlag[dst] = prev->EdgeFlag[src]; + COPY_4FV( next->SecondaryColor[dst], prev->SecondaryColor[src] ); + next->FogCoord[dst] = prev->FogCoord[src]; + } + + next->Flag[dst] = flag; + next->OrFlag |= prev->Flag[src]; /* for non-fanlike prims, + otherwise redundant */ + } + } + + if (--tnl->ExecCopySource->ref_count == 0) + _tnl_free_immediate( tnl->ExecCopySource ); + + tnl->ExecCopySource = 0; + tnl->ExecCopyCount = 0; +} + + +/* Revive a compiled immediate struct - propogate new 'Current' + * values. Often this is redundant because the current values were + * known and fixed up at compile time. + */ +void _tnl_fixup_compiled_cassette( GLcontext *ctx, struct immediate *IM ) +{ + TNLcontext *tnl = TNL_CONTEXT(ctx); + GLuint fixup; + GLuint count = IM->Count; + GLuint start = IM->Start; + + if (count == start) + return; + + IM->CopyOrFlag = IM->OrFlag; + IM->CopyAndFlag = IM->AndFlag; + IM->CopyTexSize = IM->TexSize | tnl->ExecCopyTexSize; + + _tnl_copy_immediate_vertices( ctx, IM ); + + if (ctx->Driver.CurrentExecPrimitive == GL_POLYGON+1) { + ASSERT(IM->CopyStart == IM->Start); + } + + /* Naked array elements can be copied into the first cassette in a + * display list. Need to translate them away: + */ + if (IM->CopyOrFlag & VERT_ELT) { + ASSERT(IM->CopyStart < IM->Start); + _tnl_translate_array_elts( ctx, IM, IM->CopyStart, IM->Start ); + } + + fixup = tnl->pipeline.inputs & ~IM->Flag[start] & VERT_FIXUP; + + if (fixup) { + if (fixup & VERT_TEX_ANY) { + GLuint i; + for (i = 0 ; i < ctx->Const.MaxTextureUnits ; i++) { + if (fixup & VERT_TEX(i)) + fixup_first_4f( IM->TexCoord[i], IM->Flag, VERT_TEX(i), start, + ctx->Current.Texcoord[i] ); + } + } + + if (fixup & VERT_EDGE) + fixup_first_1ub(IM->EdgeFlag, IM->Flag, VERT_EDGE, start, + ctx->Current.EdgeFlag ); + + if (fixup & VERT_INDEX) + fixup_first_1ui(IM->Index, IM->Flag, VERT_INDEX, start, + ctx->Current.Index ); + + if (fixup & VERT_RGBA) + if (IM->CopyOrFlag & VERT_RGBA) + fixup_first_4f(IM->Color, IM->Flag, VERT_RGBA, start, + ctx->Current.Color ); + + if (fixup & VERT_SPEC_RGB) + fixup_first_4f(IM->SecondaryColor, IM->Flag, VERT_SPEC_RGB, start, + ctx->Current.SecondaryColor ); + + if (fixup & VERT_FOG_COORD) + fixup_first_1f(IM->FogCoord, IM->Flag, VERT_FOG_COORD, start, + ctx->Current.FogCoord ); + + if (fixup & VERT_NORM) { + fixup_first_3f(IM->Normal, IM->Flag, VERT_NORM, start, + ctx->Current.Normal ); + } + } + + /* Materials: + */ + if (IM->MaterialOrMask & ~IM->MaterialAndMask) { + GLuint vulnerable = IM->MaterialOrMask; + GLuint i = IM->Start; + + do { + while (!(IM->Flag[i] & VERT_MATERIAL)) + i++; + + vulnerable &= ~IM->MaterialMask[i]; + _mesa_copy_material_pairs( IM->Material[i], + ctx->Light.Material, + vulnerable ); + + + } while (vulnerable); + } +} + + + + + + +static void copy_none( TNLcontext *tnl, GLuint start, GLuint count, GLuint ovf) +{ + (void) (start && ovf && tnl && count); +} + +static void copy_last( TNLcontext *tnl, GLuint start, GLuint count, GLuint ovf) +{ + (void) start; (void) ovf; + tnl->ExecCopyCount = 1; + tnl->ExecCopyElts[2] = count-1; +} + +static void copy_first_and_last( TNLcontext *tnl, GLuint start, GLuint count, + GLuint ovf) +{ + (void) ovf; + tnl->ExecCopyCount = 2; + tnl->ExecCopyElts[1] = start; + tnl->ExecCopyElts[2] = count-1; +} + +static void copy_last_two( TNLcontext *tnl, GLuint start, GLuint count, + GLuint ovf ) +{ + (void) start; + tnl->ExecCopyCount = 2+ovf; + tnl->ExecCopyElts[0] = count-3; + tnl->ExecCopyElts[1] = count-2; + tnl->ExecCopyElts[2] = count-1; +} + +static void copy_overflow( TNLcontext *tnl, GLuint start, GLuint count, + GLuint ovf ) +{ + (void) start; + tnl->ExecCopyCount = ovf; + tnl->ExecCopyElts[0] = count-3; + tnl->ExecCopyElts[1] = count-2; + tnl->ExecCopyElts[2] = count-1; +} + + +typedef void (*copy_func)( TNLcontext *tnl, GLuint start, GLuint count, + GLuint ovf ); + +static copy_func copy_tab[GL_POLYGON+2] = +{ + copy_none, + copy_overflow, + copy_first_and_last, + copy_last, + copy_overflow, + copy_last_two, + copy_first_and_last, + copy_overflow, + copy_last_two, + copy_first_and_last, + copy_none +}; + + + + + +/* Figure out what vertices need to be copied next time. + */ +void +_tnl_get_exec_copy_verts( GLcontext *ctx, struct immediate *IM ) +{ + + TNLcontext *tnl = TNL_CONTEXT(ctx); + GLuint last = IM->LastPrimitive; + GLuint prim = ctx->Driver.CurrentExecPrimitive; + GLuint pincr = increment[prim]; + GLuint pintro = intro[prim]; + GLuint ovf = 0; + +/* fprintf(stderr, "_tnl_get_exec_copy_verts %s\n", */ +/* _mesa_lookup_enum_by_nr(prim)); */ + + ASSERT(tnl->ExecCopySource == 0); + + if (prim == GL_POLYGON+1) { + tnl->ExecCopyCount = 0; + tnl->ExecCopyTexSize = 0; + tnl->ExecParity = 0; + } else { + /* Remember this immediate as the one to copy from. + */ + IM->ref_count++; + tnl->ExecCopySource = IM; + tnl->ExecCopyCount = 0; + tnl->ExecCopyTexSize = IM->CopyTexSize; + tnl->ExecParity = IM->PrimitiveLength[IM->LastPrimitive] & 1; + + if (pincr != 1 && (IM->Count - last - pintro)) + ovf = (IM->Count - last - pintro) % pincr; + + if (last < IM->Count) + copy_tab[prim]( tnl, last, IM->Count, ovf ); + } +} + + +/* Recalculate ExecCopyElts, ExecParity, etc. + */ +void +_tnl_get_purged_copy_verts( GLcontext *ctx, struct immediate *IM ) +{ + TNLcontext *tnl = TNL_CONTEXT(ctx); + + if (ctx->Driver.CurrentExecPrimitive != GL_POLYGON+1) { + GLuint last = IM->LastPrimitive; + GLenum prim = IM->Primitive[last]; + GLuint pincr = increment[prim]; + GLuint pintro = intro[prim]; + GLuint ovf = 0, i; + + tnl->ExecCopyCount = 0; + tnl->ExecParity = IM->PrimitiveLength[last] & 1; + + if (pincr != 1 && (IM->Count - last - pintro)) + ovf = (IM->Count - last - pintro) % pincr; + + if (last < IM->Count) + copy_tab[prim]( tnl, last, IM->Count, ovf ); + + for (i = 0 ; i < tnl->ExecCopyCount ; i++) + tnl->ExecCopyElts[i] = IM->Elt[tnl->ExecCopyElts[i]]; + } +} + + +void _tnl_upgrade_current_data( GLcontext *ctx, + GLuint required, + GLuint flags ) +{ + TNLcontext *tnl = TNL_CONTEXT(ctx); + struct vertex_buffer *VB = &tnl->vb; + struct immediate *IM = (struct immediate *)VB->import_source; + + ASSERT(IM); + +/* _tnl_print_vert_flags("_tnl_upgrade_client_data", required); */ + + if ((required & VERT_RGBA) && (VB->ColorPtr[0]->Flags & CA_CLIENT_DATA)) { + struct gl_client_array *tmp = &tnl->imm_inputs.Color; + GLuint start = IM->CopyStart; + + tmp->Ptr = IM->Color + start; + tmp->StrideB = 4 * sizeof(GLfloat); + tmp->Flags = 0; + + COPY_4FV( IM->Color[start], ctx->Current.Color); + + /* + ASSERT(IM->Flag[IM->LastData+1] & VERT_END_VB); + */ + + fixup_first_4f( IM->Color, IM->Flag, VERT_END_VB, start, + IM->Color[start] ); + + VB->importable_data &= ~VERT_RGBA; + } +} + Index: dll/opengl/opengl32/mesa/tnl/t_imm_fixup.h =================================================================== --- dll/opengl/opengl32/mesa/tnl/t_imm_fixup.h (revision 0) +++ dll/opengl/opengl32/mesa/tnl/t_imm_fixup.h (working copy) @@ -0,0 +1,64 @@ +/* $Id: t_imm_fixup.h,v 1.6 2001/06/04 16:09:28 keithw Exp $ */ + +/* + * Mesa 3-D graphics library + * Version: 3.5 + * + * Copyright (C) 1999-2001 Brian Paul 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 + * BRIAN PAUL 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. + */ + + +#ifndef _T_IMM_FIXUP_H +#define _T_IMM_FIXUP_H + +#include "mtypes.h" +#include "t_context.h" + +extern void _tnl_fixup_1ub( GLubyte *data, GLuint flag[], + GLuint start, GLuint match ); + +extern void _tnl_fixup_1f( GLfloat *data, GLuint flag[], + GLuint start, GLuint match ); + +extern void _tnl_fixup_1ui( GLuint *data, GLuint flag[], + GLuint start, GLuint match ); + +extern void _tnl_fixup_3f( float data[][3], GLuint flag[], + GLuint start, GLuint match ); + +extern void _tnl_fixup_4f( GLfloat data[][4], GLuint flag[], + GLuint start, GLuint match ); + +extern void _tnl_fixup_input( GLcontext *ctx, struct immediate *IM ); + +extern void _tnl_fixup_compiled_cassette( GLcontext *ctx, + struct immediate *IM ); + +extern void _tnl_copy_immediate_vertices( GLcontext *ctx, + struct immediate *IM ); + +extern void _tnl_get_purged_copy_verts( GLcontext *ctx, struct immediate *IM ); + +extern void _tnl_get_exec_copy_verts( GLcontext *ctx, struct immediate *IM ); + +extern void _tnl_upgrade_current_data( GLcontext *ctx, GLuint required, + GLuint flags ); + +#endif Index: dll/opengl/opengl32/mesa/tnl/t_pipeline.c =================================================================== --- dll/opengl/opengl32/mesa/tnl/t_pipeline.c (revision 0) +++ dll/opengl/opengl32/mesa/tnl/t_pipeline.c (working copy) @@ -0,0 +1,208 @@ +/* $Id: t_pipeline.c,v 1.19 2001/05/21 16:33:41 gareth Exp $ */ + +/* + * Mesa 3-D graphics library + * Version: 3.5 + * + * Copyright (C) 1999-2001 Brian Paul 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 + * BRIAN PAUL 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. + * + * Authors: + * Keith Whitwell + */ + +#include "glheader.h" +#include "context.h" +#include "mem.h" +#include "mmath.h" +#include "state.h" +#include "mtypes.h" + +#include "math/m_translate.h" +#include "math/m_xform.h" + +#include "t_context.h" +#include "t_pipeline.h" + + +void _tnl_install_pipeline( GLcontext *ctx, + const struct gl_pipeline_stage **stages ) +{ + TNLcontext *tnl = TNL_CONTEXT(ctx); + struct gl_pipeline *pipe = &tnl->pipeline; + GLuint i; + + ASSERT(pipe->nr_stages == 0); + + pipe->run_state_changes = ~0; + pipe->run_input_changes = ~0; + pipe->build_state_changes = ~0; + pipe->build_state_trigger = 0; + pipe->inputs = 0; + + /* Create a writeable copy of each stage. + */ + for (i = 0 ; i < MAX_PIPELINE_STAGES && stages[i] ; i++) { + MEMCPY( &pipe->stages[i], stages[i], sizeof( **stages )); + pipe->build_state_trigger |= pipe->stages[i].check_state; + } + + MEMSET( &pipe->stages[i], 0, sizeof( **stages )); + + pipe->nr_stages = i; +} + +void _tnl_destroy_pipeline( GLcontext *ctx ) +{ + TNLcontext *tnl = TNL_CONTEXT(ctx); + GLuint i; + + for (i = 0 ; i < tnl->pipeline.nr_stages ; i++) + tnl->pipeline.stages[i].destroy( &tnl->pipeline.stages[i] ); + + tnl->pipeline.nr_stages = 0; +} + +/* TODO: merge validate with run. + */ +void _tnl_validate_pipeline( GLcontext *ctx ) +{ + TNLcontext *tnl = TNL_CONTEXT(ctx); + struct gl_pipeline *pipe = &tnl->pipeline; + struct gl_pipeline_stage *s = pipe->stages; + GLuint newstate = pipe->build_state_changes; + GLuint generated = 0; + GLuint changed_inputs = 0; + + pipe->inputs = 0; + pipe->build_state_changes = 0; + + for ( ; s->check ; s++) { + + s->changed_inputs |= s->inputs & changed_inputs; + + if (s->check_state & newstate) { + if (s->active) { + GLuint old_outputs = s->outputs; + s->check(ctx, s); + if (!s->active) + changed_inputs |= old_outputs; + } + else + s->check(ctx, s); + } + + if (s->active) { + pipe->inputs |= s->inputs & ~generated; + generated |= s->outputs; + } + } +} + + + +void _tnl_run_pipeline( GLcontext *ctx ) +{ + TNLcontext *tnl = TNL_CONTEXT(ctx); + struct vertex_buffer *VB = &tnl->vb; + struct gl_pipeline *pipe = &tnl->pipeline; + struct gl_pipeline_stage *s = pipe->stages; + GLuint changed_state = pipe->run_state_changes; + GLuint changed_inputs = pipe->run_input_changes; + GLboolean running = GL_TRUE; + unsigned short __tmp; + + pipe->run_state_changes = 0; + pipe->run_input_changes = 0; + + /* Done elsewhere. + */ + ASSERT(pipe->build_state_changes == 0); + + START_FAST_MATH(__tmp); + + /* If something changes in the pipeline, tag all subsequent stages + * using this value for recalculation. Inactive stages have their + * state and inputs examined to try to keep cached data alive over + * state-changes. + */ + for ( ; s->run ; s++) { + s->changed_inputs |= s->inputs & changed_inputs; + + if (s->run_state & changed_state) + s->changed_inputs = s->inputs; + + if (s->active && running) { + if (s->changed_inputs) + changed_inputs |= s->outputs; + + running = s->run( ctx, s ); + + s->changed_inputs = 0; + VB->importable_data &= ~s->outputs; + } + } + + END_FAST_MATH(__tmp); +} + + + +/* The default pipeline. This is useful for software rasterizers, and + * simple hardware rasterizers. For customization, I don't recommend + * tampering with the internals of these stages in the way that + * drivers did in Mesa 3.4. These stages are basically black boxes, + * and should be left intact. + * + * To customize the pipeline, consider: + * + * - removing redundant stages (making sure that the software rasterizer + * can cope with this on fallback paths). An example is fog + * coordinate generation, which is not required in the FX driver. + * + * - replacing general-purpose machine-independent stages with + * general-purpose machine-specific stages. There is no example of + * this to date, though it must be borne in mind that all subsequent + * stages that reference the output of the new stage must cope with + * any machine-specific data introduced. This may not be easy + * unless there are no such stages (ie the new stage is the last in + * the pipe). + * + * - inserting optimized (but specialized) stages ahead of the + * general-purpose fallback implementation. For example, the old + * fastpath mechanism, which only works when the VERT_ELT input is + * available, can be duplicated by placing the fastpath stage at the + * head of this pipeline. Such specialized stages are currently + * constrained to have no outputs (ie. they must either finish the * + * pipeline by returning GL_FALSE from run(), or do nothing). + * + * Some work can be done to lift some of the restrictions in the final + * case, if it becomes necessary to do so. + */ +const struct gl_pipeline_stage *_tnl_default_pipeline[] = { + &_tnl_vertex_transform_stage, + &_tnl_normal_transform_stage, + &_tnl_lighting_stage, + &_tnl_fog_coordinate_stage, + &_tnl_texgen_stage, + &_tnl_texture_transform_stage, + &_tnl_point_attenuation_stage, + &_tnl_render_stage, + 0 +}; Index: dll/opengl/opengl32/mesa/tnl/t_pipeline.h =================================================================== --- dll/opengl/opengl32/mesa/tnl/t_pipeline.h (revision 0) +++ dll/opengl/opengl32/mesa/tnl/t_pipeline.h (working copy) @@ -0,0 +1,69 @@ +/* $Id: t_pipeline.h,v 1.7 2001/03/12 00:48:43 gareth Exp $ */ + +/* + * Mesa 3-D graphics library + * Version: 3.5 + * + * Copyright (C) 1999-2001 Brian Paul 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 + * BRIAN PAUL 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. + * + * Authors: + * Keith Whitwell + */ + + + +#ifndef _T_PIPELINE_H_ +#define _T_PIPELINE_H_ + +#include "mtypes.h" +#include "t_context.h" + +extern void _tnl_run_pipeline( GLcontext *ctx ); + +extern void _tnl_validate_pipeline( GLcontext *ctx ); + +extern void _tnl_destroy_pipeline( GLcontext *ctx ); + +extern void _tnl_install_pipeline( GLcontext *ctx, + const struct gl_pipeline_stage **stages ); + + +/* These are implemented in the t_vb_*.c files: + */ +extern const struct gl_pipeline_stage _tnl_vertex_transform_stage; +extern const struct gl_pipeline_stage _tnl_normal_transform_stage; +extern const struct gl_pipeline_stage _tnl_lighting_stage; +extern const struct gl_pipeline_stage _tnl_fog_coordinate_stage; +extern const struct gl_pipeline_stage _tnl_texgen_stage; +extern const struct gl_pipeline_stage _tnl_texture_transform_stage; +extern const struct gl_pipeline_stage _tnl_point_attenuation_stage; +extern const struct gl_pipeline_stage _tnl_render_stage; + +/* Shorthand to plug in the default pipeline: + */ +extern const struct gl_pipeline_stage *_tnl_default_pipeline[]; + + +/* Convenience routines provided by t_vb_render.c: + */ +extern render_func _tnl_render_tab_elts[]; +extern render_func _tnl_render_tab_verts[]; + +#endif Index: dll/opengl/opengl32/mesa/tnl/t_vb_cliptmp.h =================================================================== --- dll/opengl/opengl32/mesa/tnl/t_vb_cliptmp.h (revision 0) +++ dll/opengl/opengl32/mesa/tnl/t_vb_cliptmp.h (working copy) @@ -0,0 +1,273 @@ +/* $Id: t_vb_cliptmp.h,v 1.12 2001/05/09 12:25:40 keithw Exp $ */ + +/* + * Mesa 3-D graphics library + * Version: 3.5 + * + * Copyright (C) 1999-2001 Brian Paul 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 + * BRIAN PAUL 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. + * + * Authors: + * Keith Whitwell + */ + + +#define CLIP_DOTPROD(K, A, B, C, D) X(K)*A + Y(K)*B + Z(K)*C + W(K)*D + +#define POLY_CLIP( PLANE, A, B, C, D ) \ +do { \ + if (mask & PLANE) { \ + GLuint idxPrev = inlist[0]; \ + GLfloat dpPrev = CLIP_DOTPROD(idxPrev, A, B, C, D ); \ + GLuint outcount = 0; \ + GLuint i; \ + \ + inlist[n] = inlist[0]; /* prevent rotation of vertices */ \ + for (i = 1; i <= n; i++) { \ + GLuint idx = inlist[i]; \ + GLfloat dp = CLIP_DOTPROD(idx, A, B, C, D ); \ + \ + clipmask[idxPrev] |= PLANE; \ + if (!NEGATIVE(dpPrev)) { \ + outlist[outcount++] = idxPrev; \ + clipmask[idxPrev] &= ~PLANE; \ + } \ + \ + if (DIFFERENT_SIGNS(dp, dpPrev)) { \ + GLuint newvert = VB->LastClipped++; \ + VB->ClipMask[newvert] = 0; \ + outlist[outcount++] = newvert; \ + if (NEGATIVE(dp)) { \ + /* Going out of bounds. Avoid division by zero as we \ + * know dp != dpPrev from DIFFERENT_SIGNS, above. \ + */ \ + GLfloat t = dp / (dp - dpPrev); \ + INTERP_4F( t, coord[newvert], coord[idx], coord[idxPrev]); \ + interp( ctx, t, newvert, idx, idxPrev, GL_TRUE ); \ + } else { \ + /* Coming back in. \ + */ \ + GLfloat t = dpPrev / (dpPrev - dp); \ + INTERP_4F( t, coord[newvert], coord[idxPrev], coord[idx]); \ + interp( ctx, t, newvert, idxPrev, idx, GL_FALSE ); \ + } \ + } \ + \ + idxPrev = idx; \ + dpPrev = dp; \ + } \ + \ + if (outcount < 3) \ + return; \ + \ + { \ + GLuint *tmp = inlist; \ + inlist = outlist; \ + outlist = tmp; \ + n = outcount; \ + } \ + } \ +} while (0) + + +#define LINE_CLIP(PLANE, A, B, C, D ) \ +do { \ + if (mask & PLANE) { \ + GLfloat dpI = CLIP_DOTPROD( ii, A, B, C, D ); \ + GLfloat dpJ = CLIP_DOTPROD( jj, A, B, C, D ); \ + \ + if (DIFFERENT_SIGNS(dpI, dpJ)) { \ + GLuint newvert = VB->LastClipped++; \ + VB->ClipMask[newvert] = 0; \ + if (NEGATIVE(dpJ)) { \ + GLfloat t = dpI / (dpI - dpJ); \ + VB->ClipMask[jj] |= PLANE; \ + INTERP_4F( t, coord[newvert], coord[ii], coord[jj] ); \ + interp( ctx, t, newvert, ii, jj, GL_FALSE ); \ + jj = newvert; \ + } else { \ + GLfloat t = dpJ / (dpJ - dpI); \ + VB->ClipMask[ii] |= PLANE; \ + INTERP_4F( t, coord[newvert], coord[jj], coord[ii] ); \ + interp( ctx, t, newvert, jj, ii, GL_FALSE ); \ + ii = newvert; \ + } \ + } \ + else if (NEGATIVE(dpI)) \ + return; \ + } \ +} while (0) + + + +/* Clip a line against the viewport and user clip planes. + */ +static __inline void TAG(clip_line)( GLcontext *ctx, + GLuint i, GLuint j, + GLubyte mask ) +{ + TNLcontext *tnl = TNL_CONTEXT(ctx); + struct vertex_buffer *VB = &tnl->vb; + interp_func interp = tnl->Driver.RenderInterp; + GLfloat (*coord)[4] = VB->ClipPtr->data; + GLuint ii = i, jj = j, p; + + VB->LastClipped = VB->FirstClipped; + + if (mask & 0x3f) { + LINE_CLIP( CLIP_RIGHT_BIT, -1, 0, 0, 1 ); + LINE_CLIP( CLIP_LEFT_BIT, 1, 0, 0, 1 ); + LINE_CLIP( CLIP_TOP_BIT, 0, -1, 0, 1 ); + LINE_CLIP( CLIP_BOTTOM_BIT, 0, 1, 0, 1 ); + LINE_CLIP( CLIP_FAR_BIT, 0, 0, -1, 1 ); + LINE_CLIP( CLIP_NEAR_BIT, 0, 0, 1, 1 ); + } + + if (mask & CLIP_USER_BIT) { + for (p=0;pTransform.ClipEnabled[p]) { + GLfloat a = ctx->Transform._ClipUserPlane[p][0]; + GLfloat b = ctx->Transform._ClipUserPlane[p][1]; + GLfloat c = ctx->Transform._ClipUserPlane[p][2]; + GLfloat d = ctx->Transform._ClipUserPlane[p][3]; + LINE_CLIP( CLIP_USER_BIT, a, b, c, d ); + } + } + } + + if ((ctx->_TriangleCaps & DD_FLATSHADE) && j != jj) + tnl->Driver.RenderCopyPV( ctx, jj, j ); + + tnl->Driver.RenderClippedLine( ctx, ii, jj ); +} + + +/* Clip a triangle against the viewport and user clip planes. + */ +static __inline void TAG(clip_tri)( GLcontext *ctx, + GLuint v0, GLuint v1, GLuint v2, + GLubyte mask ) +{ + TNLcontext *tnl = TNL_CONTEXT(ctx); + struct vertex_buffer *VB = &tnl->vb; + interp_func interp = tnl->Driver.RenderInterp; + GLfloat (*coord)[4] = VB->ClipPtr->data; + GLuint pv = v2; + GLuint vlist[2][MAX_CLIPPED_VERTICES]; + GLuint *inlist = vlist[0], *outlist = vlist[1]; + GLuint p; + GLubyte *clipmask = VB->ClipMask; + GLuint n = 3; + + ASSIGN_3V(inlist, v2, v0, v1 ); /* pv rotated to slot zero */ + + VB->LastClipped = VB->FirstClipped; + + if (mask & 0x3f) { + POLY_CLIP( CLIP_RIGHT_BIT, -1, 0, 0, 1 ); + POLY_CLIP( CLIP_LEFT_BIT, 1, 0, 0, 1 ); + POLY_CLIP( CLIP_TOP_BIT, 0, -1, 0, 1 ); + POLY_CLIP( CLIP_BOTTOM_BIT, 0, 1, 0, 1 ); + POLY_CLIP( CLIP_FAR_BIT, 0, 0, -1, 1 ); + POLY_CLIP( CLIP_NEAR_BIT, 0, 0, 1, 1 ); + } + + if (mask & CLIP_USER_BIT) { + for (p=0;pTransform.ClipEnabled[p]) { + GLfloat a = ctx->Transform._ClipUserPlane[p][0]; + GLfloat b = ctx->Transform._ClipUserPlane[p][1]; + GLfloat c = ctx->Transform._ClipUserPlane[p][2]; + GLfloat d = ctx->Transform._ClipUserPlane[p][3]; + POLY_CLIP( CLIP_USER_BIT, a, b, c, d ); + } + } + } + + if (ctx->_TriangleCaps & DD_FLATSHADE) { + if (pv != inlist[0]) { + ASSERT( inlist[0] >= VB->FirstClipped ); + tnl->Driver.RenderCopyPV( ctx, inlist[0], pv ); + } + } + + tnl->Driver.RenderClippedPolygon( ctx, inlist, n ); +} + + +/* Clip a quad against the viewport and user clip planes. + */ +static __inline void TAG(clip_quad)( GLcontext *ctx, + GLuint v0, GLuint v1, GLuint v2, GLuint v3, + GLubyte mask ) +{ + TNLcontext *tnl = TNL_CONTEXT(ctx); + struct vertex_buffer *VB = &tnl->vb; + interp_func interp = tnl->Driver.RenderInterp; + GLfloat (*coord)[4] = VB->ClipPtr->data; + GLuint pv = v3; + GLuint vlist[2][MAX_CLIPPED_VERTICES]; + GLuint *inlist = vlist[0], *outlist = vlist[1]; + GLuint p; + GLubyte *clipmask = VB->ClipMask; + GLuint n = 4; + + ASSIGN_4V(inlist, v3, v0, v1, v2 ); /* pv rotated to slot zero */ + + VB->LastClipped = VB->FirstClipped; + + if (mask & 0x3f) { + POLY_CLIP( CLIP_RIGHT_BIT, -1, 0, 0, 1 ); + POLY_CLIP( CLIP_LEFT_BIT, 1, 0, 0, 1 ); + POLY_CLIP( CLIP_TOP_BIT, 0, -1, 0, 1 ); + POLY_CLIP( CLIP_BOTTOM_BIT, 0, 1, 0, 1 ); + POLY_CLIP( CLIP_FAR_BIT, 0, 0, -1, 1 ); + POLY_CLIP( CLIP_NEAR_BIT, 0, 0, 1, 1 ); + } + + if (mask & CLIP_USER_BIT) { + for (p=0;pTransform.ClipEnabled[p]) { + GLfloat a = ctx->Transform._ClipUserPlane[p][0]; + GLfloat b = ctx->Transform._ClipUserPlane[p][1]; + GLfloat c = ctx->Transform._ClipUserPlane[p][2]; + GLfloat d = ctx->Transform._ClipUserPlane[p][3]; + POLY_CLIP( CLIP_USER_BIT, a, b, c, d ); + } + } + } + + if (ctx->_TriangleCaps & DD_FLATSHADE) { + if (pv != inlist[0]) { + ASSERT( inlist[0] >= VB->FirstClipped ); + tnl->Driver.RenderCopyPV( ctx, inlist[0], pv ); + } + } + + tnl->Driver.RenderClippedPolygon( ctx, inlist, n ); +} + +#undef W +#undef Z +#undef Y +#undef X +#undef SIZE +#undef TAG +#undef POLY_CLIP +#undef LINE_CLIP Index: dll/opengl/opengl32/mesa/tnl/t_vb_fog.c =================================================================== --- dll/opengl/opengl32/mesa/tnl/t_vb_fog.c (revision 0) +++ dll/opengl/opengl32/mesa/tnl/t_vb_fog.c (working copy) @@ -0,0 +1,250 @@ +/* $Id: t_vb_fog.c,v 1.11 2001/05/15 20:52:51 brianp Exp $ */ + +/* + * Mesa 3-D graphics library + * Version: 3.5 + * + * Copyright (C) 1999-2001 Brian Paul 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 + * BRIAN PAUL 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. + * + * Authors: + * Keith Whitwell + */ + + +#include "glheader.h" +#include "colormac.h" +#include "context.h" +#include "macros.h" +#include "mem.h" +#include "mmath.h" +#include "mtypes.h" + +#include "math/m_xform.h" + +#include "t_context.h" +#include "t_pipeline.h" + + +struct fog_stage_data { + GLvector1f fogcoord; /* has actual storage allocated */ + GLvector1f input; /* points into VB->EyePtr Z values */ +}; + +#define FOG_STAGE_DATA(stage) ((struct fog_stage_data *)stage->privatePtr) + +#define FOG_EXP_TABLE_SIZE 256 +#define FOG_MAX (10.0) +#define EXP_FOG_MAX .0006595 +#define FOG_INCR (FOG_MAX/FOG_EXP_TABLE_SIZE) +static GLfloat exp_table[FOG_EXP_TABLE_SIZE]; +static GLfloat inited = 0; + +#if 1 +#define NEG_EXP( result, narg ) \ +do { \ + float f = (narg * (1.0/FOG_INCR)); \ + int k = (int) f; \ + if (k > FOG_EXP_TABLE_SIZE-2) \ + result = EXP_FOG_MAX; \ + else \ + result = exp_table[k] + (f-k)*(exp_table[k+1]-exp_table[k]); \ +} while (0) +#else +#define NEG_EXP( result, narg ) \ +do { \ + result = exp(-narg); \ +} while (0) +#endif + + +static void init_static_data( void ) +{ + float f = 0; + int i = 0; + for ( ; i < FOG_EXP_TABLE_SIZE ; i++, f += FOG_INCR) { + exp_table[i] = exp(-f); + } + inited = 1; +} + + +static void make_win_fog_coords( GLcontext *ctx, GLvector1f *out, + const GLvector1f *in ) +{ + GLfloat end = ctx->Fog.End; + GLfloat *v = in->start; + GLuint stride = in->stride; + GLuint n = in->count; + GLfloat *data = out->data; + GLfloat d; + GLuint i; + + out->count = in->count; + + switch (ctx->Fog.Mode) { + case GL_LINEAR: + if (ctx->Fog.Start == ctx->Fog.End) + d = 1.0F; + else + d = 1.0F / (ctx->Fog.End - ctx->Fog.Start); + for ( i = 0 ; i < n ; i++, STRIDE_F(v, stride)) { + GLfloat f = (end - ABSF(*v)) * d; + data[i] = CLAMP(f, 0.0F, 1.0F); + } + break; + case GL_EXP: + d = ctx->Fog.Density; + for ( i = 0 ; i < n ; i++, STRIDE_F(v,stride)) + NEG_EXP( data[i], d * ABSF(*v) ); + break; + case GL_EXP2: + d = ctx->Fog.Density*ctx->Fog.Density; + for ( i = 0 ; i < n ; i++, STRIDE_F(v, stride)) { + GLfloat z = *v; + NEG_EXP( data[i], d * z * z ); + } + break; + default: + _mesa_problem(ctx, "Bad fog mode in make_fog_coord"); + return; + } +} + + +static GLboolean run_fog_stage( GLcontext *ctx, + struct gl_pipeline_stage *stage ) +{ + struct vertex_buffer *VB = &TNL_CONTEXT(ctx)->vb; + struct fog_stage_data *store = FOG_STAGE_DATA(stage); + GLvector1f *input; + + if (stage->changed_inputs == 0) + return GL_TRUE; + + if (ctx->Fog.FogCoordinateSource == GL_FRAGMENT_DEPTH_EXT) { + /* fog computed from Z depth */ + /* source = VB->ObjPtr or VB->EyePtr coords */ + /* dest = VB->FogCoordPtr = fog stage private storage */ + VB->FogCoordPtr = &store->fogcoord; + + if (!ctx->_NeedEyeCoords) { + GLfloat *m = ctx->ModelView.m; + GLfloat plane[4]; + + /* Use this to store calculated eye z values: + */ + input = &store->fogcoord; + + plane[0] = m[2]; + plane[1] = m[6]; + plane[2] = m[10]; + plane[3] = m[14]; + + /* Full eye coords weren't required, just calculate the + * eye Z values. + */ + _mesa_dotprod_tab[VB->ObjPtr->size]( input->data, + sizeof(GLfloat), + VB->ObjPtr, plane ); + + input->count = VB->ObjPtr->count; + } + else + { + input = &store->input; + + if (VB->EyePtr->size < 2) + _mesa_vector4f_clean_elem( VB->EyePtr, VB->Count, 2 ); + + input->data = &(VB->EyePtr->data[0][2]); + input->start = VB->EyePtr->start+2; + input->stride = VB->EyePtr->stride; + input->count = VB->EyePtr->count; + } + } else { + /* use glFogCoord() coordinates */ + /* source = VB->FogCoordPtr */ + input = VB->FogCoordPtr; + /* dest = fog stage private storage */ + VB->FogCoordPtr = &store->fogcoord; + } + + make_win_fog_coords( ctx, VB->FogCoordPtr, input ); + return GL_TRUE; +} + +static void check_fog_stage( GLcontext *ctx, struct gl_pipeline_stage *stage ) +{ + stage->active = ctx->Fog.Enabled; + + if (ctx->Fog.FogCoordinateSource == GL_FRAGMENT_DEPTH_EXT) + stage->inputs = VERT_EYE; + else + stage->inputs = VERT_FOG_COORD; +} + + +/* Called the first time stage->run() is invoked. + */ +static GLboolean alloc_fog_data( GLcontext *ctx, + struct gl_pipeline_stage *stage ) +{ + TNLcontext *tnl = TNL_CONTEXT(ctx); + struct fog_stage_data *store; + stage->privatePtr = MALLOC(sizeof(*store)); + store = FOG_STAGE_DATA(stage); + if (!store) + return GL_FALSE; + + _mesa_vector1f_alloc( &store->fogcoord, 0, tnl->vb.Size, 32 ); + _mesa_vector1f_init( &store->input, 0, 0 ); + + if (!inited) + init_static_data(); + + /* Now run the stage. + */ + stage->run = run_fog_stage; + return stage->run( ctx, stage ); +} + + +static void free_fog_data( struct gl_pipeline_stage *stage ) +{ + struct fog_stage_data *store = FOG_STAGE_DATA(stage); + if (store) { + _mesa_vector1f_free( &store->fogcoord ); + FREE( store ); + stage->privatePtr = NULL; + } +} + + +const struct gl_pipeline_stage _tnl_fog_coordinate_stage = +{ + "build fog coordinates", + _NEW_FOG, + _NEW_FOG, + 0, 0, VERT_FOG_COORD, /* active, inputs, outputs */ + 0, 0, /* changed_inputs, private_data */ + free_fog_data, /* dtr */ + check_fog_stage, /* check */ + alloc_fog_data /* run -- initially set to init. */ +}; Index: dll/opengl/opengl32/mesa/tnl/t_vb_light.c =================================================================== --- dll/opengl/opengl32/mesa/tnl/t_vb_light.c (revision 0) +++ dll/opengl/opengl32/mesa/tnl/t_vb_light.c (working copy) @@ -0,0 +1,306 @@ +/* $Id: t_vb_light.c,v 1.14 2001/04/28 08:39:18 keithw Exp $ */ + +/* + * Mesa 3-D graphics library + * Version: 3.5 + * + * Copyright (C) 1999-2001 Brian Paul 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 + * BRIAN PAUL 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. + */ + + + +#include "glheader.h" +#include "colormac.h" +#include "light.h" +#include "macros.h" +#include "mem.h" +#include "mmath.h" +#include "simple_list.h" +#include "mtypes.h" + +#include "t_context.h" +#include "t_pipeline.h" + +#define LIGHT_FLAGS 0x1 /* must be first */ +#define LIGHT_TWOSIDE 0x2 +#define LIGHT_COLORMATERIAL 0x4 +#define MAX_LIGHT_FUNC 0x8 + +typedef void (*light_func)( GLcontext *ctx, + struct vertex_buffer *VB, + struct gl_pipeline_stage *stage, + GLvector4f *input ); + +struct light_stage_data { + struct gl_client_array LitColor[2]; + struct gl_client_array LitSecondary[2]; + GLvector1ui LitIndex[2]; + light_func *light_func_tab; +}; + +#define LIGHT_STAGE_DATA(stage) ((struct light_stage_data *)(stage->privatePtr)) + +/* Tables for all the shading functions. + */ +static light_func _tnl_light_tab[MAX_LIGHT_FUNC]; +static light_func _tnl_light_fast_tab[MAX_LIGHT_FUNC]; +static light_func _tnl_light_fast_single_tab[MAX_LIGHT_FUNC]; +static light_func _tnl_light_spec_tab[MAX_LIGHT_FUNC]; +static light_func _tnl_light_ci_tab[MAX_LIGHT_FUNC]; + +#define TAG(x) x +#define IDX (0) +#include "t_vb_lighttmp.h" + +#define TAG(x) x##_tw +#define IDX (LIGHT_TWOSIDE) +#include "t_vb_lighttmp.h" + +#define TAG(x) x##_fl +#define IDX (LIGHT_FLAGS) +#include "t_vb_lighttmp.h" + +#define TAG(x) x##_tw_fl +#define IDX (LIGHT_FLAGS|LIGHT_TWOSIDE) +#include "t_vb_lighttmp.h" + +#define TAG(x) x##_cm +#define IDX (LIGHT_COLORMATERIAL) +#include "t_vb_lighttmp.h" + +#define TAG(x) x##_tw_cm +#define IDX (LIGHT_TWOSIDE|LIGHT_COLORMATERIAL) +#include "t_vb_lighttmp.h" + +#define TAG(x) x##_fl_cm +#define IDX (LIGHT_FLAGS|LIGHT_COLORMATERIAL) +#include "t_vb_lighttmp.h" + +#define TAG(x) x##_tw_fl_cm +#define IDX (LIGHT_FLAGS|LIGHT_TWOSIDE|LIGHT_COLORMATERIAL) +#include "t_vb_lighttmp.h" + + +static void init_lighting( void ) +{ + static int done; + + if (!done) { + init_light_tab(); + init_light_tab_tw(); + init_light_tab_fl(); + init_light_tab_tw_fl(); + init_light_tab_cm(); + init_light_tab_tw_cm(); + init_light_tab_fl_cm(); + init_light_tab_tw_fl_cm(); + done = 1; + } +} + + +static GLboolean run_lighting( GLcontext *ctx, struct gl_pipeline_stage *stage ) +{ + struct light_stage_data *store = LIGHT_STAGE_DATA(stage); + TNLcontext *tnl = TNL_CONTEXT(ctx); + struct vertex_buffer *VB = &tnl->vb; + GLvector4f *input = ctx->_NeedEyeCoords ? VB->EyePtr : VB->ObjPtr; + GLuint ind; + +/* _tnl_print_vert_flags( __FUNCTION__, stage->changed_inputs ); */ + + /* Make sure we can talk about elements 0..2 in the vector we are + * lighting. + */ + if (stage->changed_inputs & (VERT_EYE|VERT_OBJ)) { + if (input->size <= 2) { + if (input->flags & VEC_NOT_WRITEABLE) { + ASSERT(VB->importable_data & VERT_OBJ); + + VB->import_data( ctx, VERT_OBJ, VEC_NOT_WRITEABLE ); + input = ctx->_NeedEyeCoords ? VB->EyePtr : VB->ObjPtr; + + ASSERT((input->flags & VEC_NOT_WRITEABLE) == 0); + } + + _mesa_vector4f_clean_elem(input, VB->Count, 2); + } + } + + if (VB->Flag) + ind = LIGHT_FLAGS; + else + ind = 0; + + /* The individual functions know about replaying side-effects + * vs. full re-execution. + */ + store->light_func_tab[ind]( ctx, VB, stage, input ); + + return GL_TRUE; +} + + +/* Called in place of do_lighting when the light table may have changed. + */ +static GLboolean run_validate_lighting( GLcontext *ctx, + struct gl_pipeline_stage *stage ) +{ + GLuint ind = 0; + light_func *tab; + + if (ctx->Visual.rgbMode) { + if (ctx->Light._NeedVertices) { + if (ctx->Light.Model.ColorControl == GL_SEPARATE_SPECULAR_COLOR) + tab = _tnl_light_spec_tab; + else + tab = _tnl_light_tab; + } + else { + if (ctx->Light.EnabledList.next == ctx->Light.EnabledList.prev) + tab = _tnl_light_fast_single_tab; + else + tab = _tnl_light_fast_tab; + } + } + else + tab = _tnl_light_ci_tab; + + if (ctx->Light.ColorMaterialEnabled) + ind |= LIGHT_COLORMATERIAL; + + if (ctx->Light.Model.TwoSide) + ind |= LIGHT_TWOSIDE; + + LIGHT_STAGE_DATA(stage)->light_func_tab = &tab[ind]; + + /* This and the above should only be done on _NEW_LIGHT: + */ + _mesa_validate_all_lighting_tables( ctx ); + + /* Now run the stage... + */ + stage->run = run_lighting; + return stage->run( ctx, stage ); +} + +static void alloc_4f( struct gl_client_array *a, GLuint sz ) +{ + a->Ptr = ALIGN_MALLOC( sz * sizeof(GLfloat) * 4, 32 ); + a->Size = 4; + a->Type = GL_FLOAT; + a->Stride = 0; + a->StrideB = sizeof(GLfloat) * 4; + a->Enabled = 0; + a->Flags = 0; +} + +static void free_4f( struct gl_client_array *a ) +{ + ALIGN_FREE( a->Ptr ); +} + +/* Called the first time stage->run is called. In effect, don't + * allocate data until the first time the stage is run. + */ +static GLboolean run_init_lighting( GLcontext *ctx, + struct gl_pipeline_stage *stage ) +{ + TNLcontext *tnl = TNL_CONTEXT(ctx); + struct light_stage_data *store; + GLuint size = tnl->vb.Size; + + stage->privatePtr = MALLOC(sizeof(*store)); + store = LIGHT_STAGE_DATA(stage); + if (!store) + return GL_FALSE; + + /* Do onetime init. + */ + init_lighting(); + + alloc_4f( &store->LitColor[0], size ); + alloc_4f( &store->LitColor[1], size ); + alloc_4f( &store->LitSecondary[0], size ); + alloc_4f( &store->LitSecondary[1], size ); + + _mesa_vector1ui_alloc( &store->LitIndex[0], 0, size, 32 ); + _mesa_vector1ui_alloc( &store->LitIndex[1], 0, size, 32 ); + + /* Now validate the stage derived data... + */ + stage->run = run_validate_lighting; + return stage->run( ctx, stage ); +} + + + +/* + * Check if lighting is enabled. If so, configure the pipeline stage's + * type, inputs, and outputs. + */ +static void check_lighting( GLcontext *ctx, struct gl_pipeline_stage *stage ) +{ + stage->active = ctx->Light.Enabled; + if (stage->active) { + if (stage->privatePtr) + stage->run = run_validate_lighting; + stage->inputs = VERT_NORM|VERT_MATERIAL; + if (ctx->Light._NeedVertices) + stage->inputs |= VERT_EYE; /* effectively, even when lighting in obj */ + if (ctx->Light.ColorMaterialEnabled) + stage->inputs |= VERT_RGBA; + + stage->outputs = VERT_RGBA; + if (ctx->Light.Model.ColorControl == GL_SEPARATE_SPECULAR_COLOR) + stage->outputs |= VERT_SPEC_RGB; + } +} + + +static void dtr( struct gl_pipeline_stage *stage ) +{ + struct light_stage_data *store = LIGHT_STAGE_DATA(stage); + + if (store) { + free_4f( &store->LitColor[0] ); + free_4f( &store->LitColor[1] ); + free_4f( &store->LitSecondary[0] ); + free_4f( &store->LitSecondary[1] ); + _mesa_vector1ui_free( &store->LitIndex[0] ); + _mesa_vector1ui_free( &store->LitIndex[1] ); + FREE( store ); + stage->privatePtr = 0; + } +} + +const struct gl_pipeline_stage _tnl_lighting_stage = +{ + "lighting", + _NEW_LIGHT, /* recheck */ + _NEW_LIGHT|_NEW_MODELVIEW, /* recalc -- modelview dependency + * otherwise not captured by inputs + * (which may be VERT_OBJ) */ + 0,0,0, /* active, inputs, outputs */ + 0,0, /* changed_inputs, private_data */ + dtr, /* destroy */ + check_lighting, /* check */ + run_init_lighting /* run -- initially set to ctr */ +}; Index: dll/opengl/opengl32/mesa/tnl/t_vb_lighttmp.h =================================================================== --- dll/opengl/opengl32/mesa/tnl/t_vb_lighttmp.h (revision 0) +++ dll/opengl/opengl32/mesa/tnl/t_vb_lighttmp.h (working copy) @@ -0,0 +1,932 @@ +/* $Id: t_vb_lighttmp.h,v 1.12 2001/04/28 08:39:18 keithw Exp $ */ + +/* + * Mesa 3-D graphics library + * Version: 3.5 + * + * Copyright (C) 1999-2001 Brian Paul 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 + * BRIAN PAUL 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. + * + * + * Authors: + * Brian Paul + * Keith Whitwell + */ + + +#if (IDX & LIGHT_FLAGS) +# define VSTRIDE (4 * sizeof(GLfloat)) +# define NSTRIDE (3 * sizeof(GLfloat)) +# define CHECK_MATERIAL(x) (flags[x] & VERT_MATERIAL) +# define CHECK_END_VB(x) (flags[x] & VERT_END_VB) +# if (IDX & LIGHT_COLORMATERIAL) +# define CMSTRIDE STRIDE_F(CMcolor, (4 * sizeof(GLfloat))) +# define CHECK_COLOR_MATERIAL(x) (flags[x] & VERT_RGBA) +# define CHECK_VALIDATE(x) (flags[x] & (VERT_RGBA|VERT_MATERIAL)) +# define DO_ANOTHER_NORMAL(x) \ + ((flags[x] & (VERT_RGBA|VERT_NORM|VERT_END_VB|VERT_MATERIAL)) == VERT_NORM) +# define REUSE_LIGHT_RESULTS(x) \ + ((flags[x] & (VERT_RGBA|VERT_NORM|VERT_END_VB|VERT_MATERIAL)) == 0) +# else +# define CMSTRIDE (void)0 +# define CHECK_COLOR_MATERIAL(x) 0 +# define CHECK_VALIDATE(x) (flags[x] & (VERT_MATERIAL)) +# define DO_ANOTHER_NORMAL(x) \ + ((flags[x] & (VERT_NORM|VERT_END_VB|VERT_MATERIAL)) == VERT_NORM) +# define REUSE_LIGHT_RESULTS(x) \ + ((flags[x] & (VERT_NORM|VERT_END_VB|VERT_MATERIAL)) == 0) +# endif +#else +# define VSTRIDE vstride +# define NSTRIDE nstride +# define CHECK_MATERIAL(x) 0 /* no materials on array paths */ +# define CHECK_END_VB(XX) (XX >= nr) +# if (IDX & LIGHT_COLORMATERIAL) +# define CMSTRIDE STRIDE_F(CMcolor, CMstride) +# define CHECK_COLOR_MATERIAL(x) (x < nr) /* always have colormaterial */ +# define CHECK_VALIDATE(x) (x < nr) +# define DO_ANOTHER_NORMAL(x) 0 /* always stop to recalc colormat */ +# else +# define CMSTRIDE (void)0 +# define CHECK_COLOR_MATERIAL(x) 0 /* no colormaterial */ +# define CHECK_VALIDATE(x) (0) +# define DO_ANOTHER_NORMAL(XX) (XX < nr) /* keep going to end of vb */ +# endif +# define REUSE_LIGHT_RESULTS(x) 0 /* always have a new normal */ +#endif + + + +#if (IDX & LIGHT_TWOSIDE) +# define NR_SIDES 2 +#else +# define NR_SIDES 1 +#endif + + + +static void TAG(light_rgba_spec)( GLcontext *ctx, + struct vertex_buffer *VB, + struct gl_pipeline_stage *stage, + GLvector4f *input ) +{ + struct light_stage_data *store = LIGHT_STAGE_DATA(stage); + GLfloat (*base)[3] = ctx->Light._BaseColor; + const GLfloat *sumA = ctx->Light._BaseAlpha; + + GLuint j; + + GLuint vstride = input->stride; + const GLfloat *vertex = (GLfloat *)input->data; + GLuint nstride = VB->NormalPtr->stride; + const GLfloat *normal = (GLfloat *)VB->NormalPtr->data; + + GLfloat *CMcolor; + GLuint CMstride; + + GLfloat (*Fcolor)[4] = (GLfloat (*)[4]) store->LitColor[0].Ptr; + GLfloat (*Bcolor)[4] = (GLfloat (*)[4]) store->LitColor[1].Ptr; + GLfloat (*Fspec)[4] = (GLfloat (*)[4]) store->LitSecondary[0].Ptr; + GLfloat (*Bspec)[4] = (GLfloat (*)[4]) store->LitSecondary[1].Ptr; + GLfloat (*spec[2])[4]; + + GLuint nr = VB->Count; + GLuint *flags = VB->Flag; + struct gl_material (*new_material)[2] = VB->Material; + GLuint *new_material_mask = VB->MaterialMask; + + (void) flags; + (void) nstride; + (void) vstride; + + +/* fprintf(stderr, "%s\n", __FUNCTION__ ); */ + + spec[0] = Fspec; + spec[1] = Bspec; + + if (IDX & LIGHT_COLORMATERIAL) { + if (VB->ColorPtr[0]->Type != GL_FLOAT) + VB->import_data( ctx, VERT_RGBA, ~0 ); + + CMcolor = (GLfloat *) VB->ColorPtr[0]->Ptr; + CMstride = VB->ColorPtr[0]->StrideB; + } + + VB->ColorPtr[0] = &store->LitColor[0]; + VB->SecondaryColorPtr[0] = &store->LitSecondary[0]; + + if (IDX & LIGHT_TWOSIDE) { + VB->ColorPtr[1] = &store->LitColor[1]; + VB->SecondaryColorPtr[1] = &store->LitSecondary[1]; + } + + /* Side-effects done, can we finish now? + */ + if (stage->changed_inputs == 0) + return; + + for ( j=0 ; + jLight.EnabledList) { + GLfloat n_dot_h; + GLfloat correction; + GLint side; + GLfloat contrib[3]; + GLfloat attenuation; + GLfloat VP[3]; /* unit vector from vertex to light */ + GLfloat n_dot_VP; /* n dot VP */ + GLfloat *h; + + /* compute VP and attenuation */ + if (!(light->_Flags & LIGHT_POSITIONAL)) { + /* directional light */ + COPY_3V(VP, light->_VP_inf_norm); + attenuation = light->_VP_inf_spot_attenuation; + } + else { + GLfloat d; /* distance from vertex to light */ + + SUB_3V(VP, light->_Position, vertex); + + d = (GLfloat) LEN_3FV( VP ); + + if (d > 1e-6) { + GLfloat invd = 1.0F / d; + SELF_SCALE_SCALAR_3V(VP, invd); + } + + attenuation = 1.0F / (light->ConstantAttenuation + d * + (light->LinearAttenuation + d * + light->QuadraticAttenuation)); + + /* spotlight attenuation */ + if (light->_Flags & LIGHT_SPOT) { + GLfloat PV_dot_dir = - DOT3(VP, light->_NormDirection); + + if (PV_dot_dir_CosCutoff) { + continue; /* this light makes no contribution */ + } + else { + double x = PV_dot_dir * (EXP_TABLE_SIZE-1); + int k = (int) x; + GLfloat spot = (GLfloat) (light->_SpotExpTable[k][0] + + (x-k)*light->_SpotExpTable[k][1]); + attenuation *= spot; + } + } + } + + + if (attenuation < 1e-3) + continue; /* this light makes no contribution */ + + /* Compute dot product or normal and vector from V to light pos */ + n_dot_VP = DOT3( normal, VP ); + + /* Which side gets the diffuse & specular terms? */ + if (n_dot_VP < 0.0F) { + ACC_SCALE_SCALAR_3V(Fcolor[j], attenuation, light->_MatAmbient[0]); + if (!(IDX & LIGHT_TWOSIDE)) { + continue; + } + /* diffuse term */ + COPY_3V(contrib, light->_MatAmbient[1]); + ACC_SCALE_SCALAR_3V(contrib, -n_dot_VP, light->_MatDiffuse[1]); + ACC_SCALE_SCALAR_3V(Bcolor[j], attenuation, contrib ); + correction = -1; + side = 1; + } + else { + if (IDX & LIGHT_TWOSIDE) { + ACC_SCALE_SCALAR_3V( Bcolor[j], attenuation, + light->_MatAmbient[1]); + } + /* diffuse term */ + COPY_3V(contrib, light->_MatAmbient[0]); + ACC_SCALE_SCALAR_3V(contrib, n_dot_VP, light->_MatDiffuse[0]); + ACC_SCALE_SCALAR_3V(Fcolor[j], attenuation, contrib ); + correction = 1; + side = 0; + } + + /* specular term - cannibalize VP... */ + if (ctx->Light.Model.LocalViewer) { + GLfloat v[3]; + COPY_3V(v, vertex); + NORMALIZE_3FV(v); + SUB_3V(VP, VP, v); /* h = VP + VPe */ + h = VP; + NORMALIZE_3FV(h); + } + else if (light->_Flags & LIGHT_POSITIONAL) { + h = VP; + ACC_3V(h, ctx->_EyeZDir); + NORMALIZE_3FV(h); + } + else { + h = light->_h_inf_norm; + } + + n_dot_h = correction * DOT3(normal, h); + + if (n_dot_h > 0.0F) { + GLfloat spec_coef; + struct gl_shine_tab *tab = ctx->_ShineTable[side]; + GET_SHINE_TAB_ENTRY( tab, n_dot_h, spec_coef ); + + if (spec_coef > 1.0e-10) { + spec_coef *= attenuation; + ACC_SCALE_SCALAR_3V( spec[side][j], spec_coef, + light->_MatSpecular[side]); + } + } + } /*loop over lights*/ + } +} + + +static void TAG(light_rgba)( GLcontext *ctx, + struct vertex_buffer *VB, + struct gl_pipeline_stage *stage, + GLvector4f *input ) +{ + struct light_stage_data *store = LIGHT_STAGE_DATA(stage); + GLuint j; + + GLfloat (*base)[3] = ctx->Light._BaseColor; + const GLfloat *sumA = ctx->Light._BaseAlpha; + + GLuint vstride = input->stride; + const GLfloat *vertex = (GLfloat *) input->data; + GLuint nstride = VB->NormalPtr->stride; + const GLfloat *normal = (GLfloat *)VB->NormalPtr->data; + + GLfloat *CMcolor; + GLuint CMstride; + + GLfloat (*Fcolor)[4] = (GLfloat (*)[4]) store->LitColor[0].Ptr; + GLfloat (*Bcolor)[4] = (GLfloat (*)[4]) store->LitColor[1].Ptr; + GLfloat (*color[2])[4]; + GLuint *flags = VB->Flag; + + struct gl_material (*new_material)[2] = VB->Material; + GLuint *new_material_mask = VB->MaterialMask; + GLuint nr = VB->Count; + +/* fprintf(stderr, "%s\n", __FUNCTION__ ); */ + (void) flags; + (void) nstride; + (void) vstride; + + color[0] = Fcolor; + color[1] = Bcolor; + + if (IDX & LIGHT_COLORMATERIAL) { + if (VB->ColorPtr[0]->Type != GL_FLOAT) + VB->import_data( ctx, VERT_RGBA, ~0 ); + + CMcolor = (GLfloat *)VB->ColorPtr[0]->Ptr; + CMstride = VB->ColorPtr[0]->StrideB; + } + + VB->ColorPtr[0] = &store->LitColor[0]; + if (IDX & LIGHT_TWOSIDE) + VB->ColorPtr[1] = &store->LitColor[1]; + + if (stage->changed_inputs == 0) + return; + + for ( j=0 ; + jLight.EnabledList) { + + GLfloat n_dot_h; + GLfloat correction; + GLint side; + GLfloat contrib[3]; + GLfloat attenuation = 1.0; + GLfloat VP[3]; /* unit vector from vertex to light */ + GLfloat n_dot_VP; /* n dot VP */ + GLfloat *h; + + /* compute VP and attenuation */ + if (!(light->_Flags & LIGHT_POSITIONAL)) { + /* directional light */ + COPY_3V(VP, light->_VP_inf_norm); + attenuation = light->_VP_inf_spot_attenuation; + } + else { + GLfloat d; /* distance from vertex to light */ + + + SUB_3V(VP, light->_Position, vertex); + + d = LEN_3FV( VP ); + + if ( d > 1e-6) { + GLfloat invd = 1.0F / d; + SELF_SCALE_SCALAR_3V(VP, invd); + } + + attenuation = 1.0F / (light->ConstantAttenuation + d * + (light->LinearAttenuation + d * + light->QuadraticAttenuation)); + + /* spotlight attenuation */ + if (light->_Flags & LIGHT_SPOT) { + GLfloat PV_dot_dir = - DOT3(VP, light->_NormDirection); + + if (PV_dot_dir_CosCutoff) { + continue; /* this light makes no contribution */ + } + else { + double x = PV_dot_dir * (EXP_TABLE_SIZE-1); + int k = (int) x; + GLfloat spot = (light->_SpotExpTable[k][0] + + (x-k)*light->_SpotExpTable[k][1]); + attenuation *= spot; + } + } + } + + + if (attenuation < 1e-3) + continue; /* this light makes no contribution */ + + + /* Compute dot product or normal and vector from V to light pos */ + n_dot_VP = DOT3( normal, VP ); + + /* which side are we lighting? */ + if (n_dot_VP < 0.0F) { + ACC_SCALE_SCALAR_3V(Fcolor[j], attenuation, light->_MatAmbient[0]); + + if (!(IDX & LIGHT_TWOSIDE)) + continue; + + side = 1; + correction = -1; + n_dot_VP = -n_dot_VP; + } + else { + if (IDX & LIGHT_TWOSIDE) { + ACC_SCALE_SCALAR_3V(Bcolor[j], attenuation, + light->_MatAmbient[1]); + } + side = 0; + correction = 1; + } + + COPY_3V(contrib, light->_MatAmbient[side]); + + /* diffuse term */ + ACC_SCALE_SCALAR_3V(contrib, n_dot_VP, light->_MatDiffuse[side]); + + /* specular term - cannibalize VP... */ + { + if (ctx->Light.Model.LocalViewer) { + GLfloat v[3]; + COPY_3V(v, vertex); + NORMALIZE_3FV(v); + SUB_3V(VP, VP, v); /* h = VP + VPe */ + h = VP; + NORMALIZE_3FV(h); + } + else if (light->_Flags & LIGHT_POSITIONAL) { + h = VP; + ACC_3V(h, ctx->_EyeZDir); + NORMALIZE_3FV(h); + } + else { + h = light->_h_inf_norm; + } + + n_dot_h = correction * DOT3(normal, h); + + if (n_dot_h > 0.0F) + { + GLfloat spec_coef; + struct gl_shine_tab *tab = ctx->_ShineTable[side]; + + GET_SHINE_TAB_ENTRY( tab, n_dot_h, spec_coef ); + + ACC_SCALE_SCALAR_3V( contrib, spec_coef, + light->_MatSpecular[side]); + } + } + + + ACC_SCALE_SCALAR_3V( color[side][j], attenuation, contrib ); + } + } +} + + + + +/* As below, but with just a single light. + */ +static void TAG(light_fast_rgba_single)( GLcontext *ctx, + struct vertex_buffer *VB, + struct gl_pipeline_stage *stage, + GLvector4f *input ) + +{ + struct light_stage_data *store = LIGHT_STAGE_DATA(stage); + GLuint nstride = VB->NormalPtr->stride; + const GLfloat *normal = (GLfloat *)VB->NormalPtr->data; + GLfloat *CMcolor; + GLuint CMstride; + GLfloat (*Fcolor)[4] = (GLfloat (*)[4]) store->LitColor[0].Ptr; + GLfloat (*Bcolor)[4] = (GLfloat (*)[4]) store->LitColor[1].Ptr; + struct gl_light *light = ctx->Light.EnabledList.next; + GLuint *flags = VB->Flag; + GLuint j = 0; + struct gl_material (*new_material)[2] = VB->Material; + GLuint *new_material_mask = VB->MaterialMask; + GLfloat base[2][4]; + GLuint nr = VB->Count; + +/* fprintf(stderr, "%s\n", __FUNCTION__ ); */ + (void) input; /* doesn't refer to Eye or Obj */ + (void) flags; + (void) nr; + (void) nstride; + + if (IDX & LIGHT_COLORMATERIAL) { + if (VB->ColorPtr[0]->Type != GL_FLOAT) + VB->import_data( ctx, VERT_RGBA, ~0 ); + + CMcolor = (GLfloat *)VB->ColorPtr[0]->Ptr; + CMstride = VB->ColorPtr[0]->StrideB; + } + + VB->ColorPtr[0] = &store->LitColor[0]; + if (IDX & LIGHT_TWOSIDE) + VB->ColorPtr[1] = &store->LitColor[1]; + + if (stage->changed_inputs == 0) + return; + + do { + + if ( CHECK_COLOR_MATERIAL(j) ) + _mesa_update_color_material( ctx, CMcolor ); + + if ( CHECK_MATERIAL(j) ) + _mesa_update_material( ctx, new_material[j], new_material_mask[j] ); + + if ( CHECK_VALIDATE(j) ) + _mesa_validate_all_lighting_tables( ctx ); + + + COPY_3V(base[0], light->_MatAmbient[0]); + ACC_3V(base[0], ctx->Light._BaseColor[0] ); + base[0][3] = ctx->Light._BaseAlpha[0]; + + if (IDX & LIGHT_TWOSIDE) { + COPY_3V(base[1], light->_MatAmbient[1]); + ACC_3V(base[1], ctx->Light._BaseColor[1]); + base[1][3] = ctx->Light._BaseAlpha[1]; + } + + do { + GLfloat n_dot_VP; + + COPY_4FV(Fcolor[j], base[0]); + if (IDX & LIGHT_TWOSIDE) COPY_4FV(Bcolor[j], base[1]); + + n_dot_VP = DOT3(normal, light->_VP_inf_norm); + + if (n_dot_VP > 0.0F) { + GLfloat n_dot_h = DOT3(normal, light->_h_inf_norm); + ACC_SCALE_SCALAR_3V(Fcolor[j], n_dot_VP, light->_MatDiffuse[0]); + if (n_dot_h > 0.0F) { + GLfloat spec; + GET_SHINE_TAB_ENTRY( ctx->_ShineTable[0], n_dot_h, spec ); + ACC_SCALE_SCALAR_3V( Fcolor[j], spec, light->_MatSpecular[0]); + } + } + else if (IDX & LIGHT_TWOSIDE) { + GLfloat n_dot_h = -DOT3(normal, light->_h_inf_norm); + ACC_SCALE_SCALAR_3V(Bcolor[j], -n_dot_VP, light->_MatDiffuse[1]); + if (n_dot_h > 0.0F) { + GLfloat spec; + GET_SHINE_TAB_ENTRY( ctx->_ShineTable[1], n_dot_h, spec ); + ACC_SCALE_SCALAR_3V( Bcolor[j], spec, light->_MatSpecular[1]); + } + } + + j++; + CMSTRIDE; + STRIDE_F(normal, NSTRIDE); + } while (DO_ANOTHER_NORMAL(j)); + + + for ( ; REUSE_LIGHT_RESULTS(j) ; j++, CMSTRIDE, STRIDE_F(normal,NSTRIDE)) + { + COPY_4FV(Fcolor[j], Fcolor[j-1]); + if (IDX & LIGHT_TWOSIDE) + COPY_4FV(Bcolor[j], Bcolor[j-1]); + } + + } while (!CHECK_END_VB(j)); +} + + +/* Light infinite lights + */ +static void TAG(light_fast_rgba)( GLcontext *ctx, + struct vertex_buffer *VB, + struct gl_pipeline_stage *stage, + GLvector4f *input ) +{ + struct light_stage_data *store = LIGHT_STAGE_DATA(stage); + const GLfloat *sumA = ctx->Light._BaseAlpha; + GLuint nstride = VB->NormalPtr->stride; + const GLfloat *normal = (GLfloat *)VB->NormalPtr->data; + GLfloat *CMcolor; + GLuint CMstride; + GLfloat (*Fcolor)[4] = (GLfloat (*)[4]) store->LitColor[0].Ptr; + GLfloat (*Bcolor)[4] = (GLfloat (*)[4]) store->LitColor[1].Ptr; + GLuint *flags = VB->Flag; + GLuint j = 0; + struct gl_material (*new_material)[2] = VB->Material; + GLuint *new_material_mask = VB->MaterialMask; + GLuint nr = VB->Count; + struct gl_light *light; + +/* fprintf(stderr, "%s\n", __FUNCTION__ ); */ + (void) flags; + (void) input; + (void) nr; + (void) nstride; + + if (IDX & LIGHT_COLORMATERIAL) { + if (VB->ColorPtr[0]->Type != GL_FLOAT) + VB->import_data( ctx, VERT_RGBA, ~0 ); + + CMcolor = (GLfloat *)VB->ColorPtr[0]->Ptr; + CMstride = VB->ColorPtr[0]->StrideB; + } + + VB->ColorPtr[0] = &store->LitColor[0]; + if (IDX & LIGHT_TWOSIDE) + VB->ColorPtr[1] = &store->LitColor[1]; + + if (stage->changed_inputs == 0) + return; + + do { + do { + if ( CHECK_COLOR_MATERIAL(j) ) + _mesa_update_color_material( ctx, CMcolor ); + + if ( CHECK_MATERIAL(j) ) + _mesa_update_material( ctx, new_material[j], new_material_mask[j] ); + + if ( CHECK_VALIDATE(j) ) + _mesa_validate_all_lighting_tables( ctx ); + + + COPY_3V(Fcolor[j], ctx->Light._BaseColor[0]); + Fcolor[j][3] = sumA[0]; + + if (IDX & LIGHT_TWOSIDE) { + COPY_3V(Bcolor[j], ctx->Light._BaseColor[1]); + Bcolor[j][3] = sumA[1]; + } + + foreach (light, &ctx->Light.EnabledList) { + GLfloat n_dot_h, n_dot_VP, spec; + + ACC_3V(Fcolor[j], light->_MatAmbient[0]); + if (IDX & LIGHT_TWOSIDE) + ACC_3V(Bcolor[j], light->_MatAmbient[1]); + + n_dot_VP = DOT3(normal, light->_VP_inf_norm); + + if (n_dot_VP > 0.0F) { + ACC_SCALE_SCALAR_3V(Fcolor[j], n_dot_VP, light->_MatDiffuse[0]); + n_dot_h = DOT3(normal, light->_h_inf_norm); + if (n_dot_h > 0.0F) { + struct gl_shine_tab *tab = ctx->_ShineTable[0]; + GET_SHINE_TAB_ENTRY( tab, n_dot_h, spec ); + ACC_SCALE_SCALAR_3V( Fcolor[j], spec, + light->_MatSpecular[0]); + } + } + else if (IDX & LIGHT_TWOSIDE) { + ACC_SCALE_SCALAR_3V(Bcolor[j], -n_dot_VP, light->_MatDiffuse[1]); + n_dot_h = -DOT3(normal, light->_h_inf_norm); + if (n_dot_h > 0.0F) { + struct gl_shine_tab *tab = ctx->_ShineTable[1]; + GET_SHINE_TAB_ENTRY( tab, n_dot_h, spec ); + ACC_SCALE_SCALAR_3V( Bcolor[j], spec, + light->_MatSpecular[1]); + } + } + } + + j++; + CMSTRIDE; + STRIDE_F(normal, NSTRIDE); + } while (DO_ANOTHER_NORMAL(j)); + + /* Reuse the shading results while there is no change to + * normal or material values. + */ + for ( ; REUSE_LIGHT_RESULTS(j) ; j++, CMSTRIDE, STRIDE_F(normal, NSTRIDE)) + { + COPY_4FV(Fcolor[j], Fcolor[j-1]); + if (IDX & LIGHT_TWOSIDE) + COPY_4FV(Bcolor[j], Bcolor[j-1]); + } + + } while (!CHECK_END_VB(j)); +} + + + + + +/* + * Use current lighting/material settings to compute the color indexes + * for an array of vertices. + * Input: n - number of vertices to light + * side - 0=use front material, 1=use back material + * vertex - array of [n] vertex position in eye coordinates + * normal - array of [n] surface normal vector + * Output: indexResult - resulting array of [n] color indexes + */ +static void TAG(light_ci)( GLcontext *ctx, + struct vertex_buffer *VB, + struct gl_pipeline_stage *stage, + GLvector4f *input ) +{ + struct light_stage_data *store = LIGHT_STAGE_DATA(stage); + GLuint j; + GLuint vstride = input->stride; + const GLfloat *vertex = (GLfloat *) input->data; + GLuint nstride = VB->NormalPtr->stride; + const GLfloat *normal = (GLfloat *)VB->NormalPtr->data; + GLfloat *CMcolor; + GLuint CMstride; + GLuint *flags = VB->Flag; + GLuint *indexResult[2]; + struct gl_material (*new_material)[2] = VB->Material; + GLuint *new_material_mask = VB->MaterialMask; + GLuint nr = VB->Count; + +/* fprintf(stderr, "%s\n", __FUNCTION__ ); */ + (void) flags; + (void) nstride; + (void) vstride; + + VB->IndexPtr[0] = &store->LitIndex[0]; + if (IDX & LIGHT_TWOSIDE) + VB->IndexPtr[1] = &store->LitIndex[1]; + + if (stage->changed_inputs == 0) + return; + + indexResult[0] = VB->IndexPtr[0]->data; + if (IDX & LIGHT_TWOSIDE) + indexResult[1] = VB->IndexPtr[1]->data; + + if (IDX & LIGHT_COLORMATERIAL) { + if (VB->ColorPtr[0]->Type != GL_FLOAT) + VB->import_data( ctx, VERT_RGBA, ~0 ); + + CMcolor = (GLfloat *)VB->ColorPtr[0]->Ptr; + CMstride = VB->ColorPtr[0]->StrideB; + } + + /* loop over vertices */ + for ( j=0 ; + jLight.EnabledList) { + + GLfloat attenuation = 1.0F; + GLfloat VP[3]; /* unit vector from vertex to light */ + GLfloat n_dot_VP; /* dot product of l and n */ + GLfloat *h, n_dot_h, correction = 1.0; + + /* compute l and attenuation */ + if (!(light->_Flags & LIGHT_POSITIONAL)) { + /* directional light */ + COPY_3V(VP, light->_VP_inf_norm); + } + else { + GLfloat d; /* distance from vertex to light */ + + SUB_3V(VP, light->_Position, vertex); + + d = LEN_3FV( VP ); + if ( d > 1e-6) { + GLfloat invd = 1.0F / d; + SELF_SCALE_SCALAR_3V(VP, invd); + } + + attenuation = 1.0F / (light->ConstantAttenuation + d * + (light->LinearAttenuation + d * + light->QuadraticAttenuation)); + + /* spotlight attenuation */ + if (light->_Flags & LIGHT_SPOT) { + GLfloat PV_dot_dir = - DOT3(VP, light->_NormDirection); + if (PV_dot_dir < light->_CosCutoff) { + continue; /* this light makes no contribution */ + } + else { + double x = PV_dot_dir * (EXP_TABLE_SIZE-1); + int k = (int) x; + GLfloat spot = (light->_SpotExpTable[k][0] + + (x-k)*light->_SpotExpTable[k][1]); + attenuation *= spot; + } + } + } + + if (attenuation < 1e-3) + continue; /* this light makes no contribution */ + + n_dot_VP = DOT3( normal, VP ); + + /* which side are we lighting? */ + if (n_dot_VP < 0.0F) { + if (!(IDX & LIGHT_TWOSIDE)) + continue; + side = 1; + correction = -1; + n_dot_VP = -n_dot_VP; + } + + /* accumulate diffuse term */ + diffuse[side] += n_dot_VP * light->_dli * attenuation; + + /* specular term */ + if (ctx->Light.Model.LocalViewer) { + GLfloat v[3]; + COPY_3V(v, vertex); + NORMALIZE_3FV(v); + SUB_3V(VP, VP, v); /* h = VP + VPe */ + h = VP; + NORMALIZE_3FV(h); + } + else if (light->_Flags & LIGHT_POSITIONAL) { + h = VP; + /* Strangely, disabling this addition fixes a conformance + * problem. If this code is enabled, l_sed.c fails. + */ + /*ACC_3V(h, ctx->_EyeZDir);*/ + NORMALIZE_3FV(h); + } + else { + h = light->_h_inf_norm; + } + + n_dot_h = correction * DOT3(normal, h); + if (n_dot_h > 0.0F) { + GLfloat spec_coef; + struct gl_shine_tab *tab = ctx->_ShineTable[side]; + GET_SHINE_TAB_ENTRY( tab, n_dot_h, spec_coef); + specular[side] += spec_coef * light->_sli * attenuation; + } + } /*loop over lights*/ + + /* Now compute final color index */ + for (side = 0 ; side < NR_SIDES ; side++) { + struct gl_material *mat = &ctx->Light.Material[side]; + GLfloat index; + + if (specular[side] > 1.0F) { + index = mat->SpecularIndex; + } + else { + GLfloat d_a = mat->DiffuseIndex - mat->AmbientIndex; + GLfloat s_a = mat->SpecularIndex - mat->AmbientIndex; + + index = mat->AmbientIndex + + diffuse[side] * (1.0F-specular[side]) * d_a + + specular[side] * s_a; + + if (index > mat->SpecularIndex) { + index = mat->SpecularIndex; + } + } + indexResult[side][j] = (GLuint) (GLint) index; + } + } /*for vertex*/ +} + + + +static void TAG(init_light_tab)( void ) +{ + _tnl_light_tab[IDX] = TAG(light_rgba); + _tnl_light_fast_tab[IDX] = TAG(light_fast_rgba); + _tnl_light_fast_single_tab[IDX] = TAG(light_fast_rgba_single); + _tnl_light_spec_tab[IDX] = TAG(light_rgba_spec); + _tnl_light_ci_tab[IDX] = TAG(light_ci); +} + + +#undef TAG +#undef IDX +#undef NR_SIDES +#undef NSTRIDE +#undef VSTRIDE +#undef CHECK_MATERIAL +#undef CHECK_END_VB +#undef DO_ANOTHER_NORMAL +#undef REUSE_LIGHT_RESULTS +#undef CMSTRIDE +#undef CHECK_COLOR_MATERIAL +#undef CHECK_VALIDATE Index: dll/opengl/opengl32/mesa/tnl/t_vb_normals.c =================================================================== --- dll/opengl/opengl32/mesa/tnl/t_vb_normals.c (revision 0) +++ dll/opengl/opengl32/mesa/tnl/t_vb_normals.c (working copy) @@ -0,0 +1,185 @@ +/* $Id: t_vb_normals.c,v 1.8 2001/03/30 14:44:44 gareth Exp $ */ + +/* + * Mesa 3-D graphics library + * Version: 3.5 + * + * Copyright (C) 1999-2001 Brian Paul 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 + * BRIAN PAUL 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. + * + * Authors: + * Keith Whitwell + */ + + +#include "glheader.h" +#include "colormac.h" +#include "context.h" +#include "macros.h" +#include "mem.h" +#include "mmath.h" +#include "mtypes.h" + +#include "math/m_xform.h" + +#include "t_context.h" +#include "t_pipeline.h" + + + +struct normal_stage_data { + normal_func NormalTransform; + GLvector3f normal; +}; + +#define NORMAL_STAGE_DATA(stage) ((struct normal_stage_data *)stage->privatePtr) + + + + +static GLboolean run_normal_stage( GLcontext *ctx, + struct gl_pipeline_stage *stage ) +{ + struct normal_stage_data *store = NORMAL_STAGE_DATA(stage); + struct vertex_buffer *VB = &TNL_CONTEXT(ctx)->vb; + + ASSERT(store->NormalTransform); + + if (stage->changed_inputs) + store->NormalTransform( &ctx->ModelView, + ctx->_ModelViewInvScale, + VB->NormalPtr, + 0, + &store->normal ); + + VB->NormalPtr = &store->normal; + return GL_TRUE; +} + + +static GLboolean run_validate_normal_stage( GLcontext *ctx, + struct gl_pipeline_stage *stage ) +{ + struct normal_stage_data *store = NORMAL_STAGE_DATA(stage); + + ASSERT(ctx->_NeedNormals); + + if (ctx->_NeedEyeCoords) { + GLuint transform = NORM_TRANSFORM_NO_ROT; + + if (ctx->ModelView.flags & (MAT_FLAG_GENERAL | + MAT_FLAG_ROTATION | + MAT_FLAG_GENERAL_3D | + MAT_FLAG_PERSPECTIVE)) + transform = NORM_TRANSFORM; + + + if (ctx->Transform.Normalize) { + store->NormalTransform = _mesa_normal_tab[transform | NORM_NORMALIZE]; + } + else if (ctx->Transform.RescaleNormals && + ctx->_ModelViewInvScale != 1.0) { + store->NormalTransform = _mesa_normal_tab[transform | NORM_RESCALE]; + } + else { + store->NormalTransform = _mesa_normal_tab[transform]; + } + } + else { + if (ctx->Transform.Normalize) { + store->NormalTransform = _mesa_normal_tab[NORM_NORMALIZE]; + } + else if (!ctx->Transform.RescaleNormals && + ctx->_ModelViewInvScale != 1.0) { + store->NormalTransform = _mesa_normal_tab[NORM_RESCALE]; + } + else { + store->NormalTransform = 0; + } + } + + if (store->NormalTransform) { + stage->run = run_normal_stage; + return stage->run( ctx, stage ); + } else { + stage->active = GL_FALSE; /* !!! */ + return GL_TRUE; + } +} + + +static void check_normal_transform( GLcontext *ctx, + struct gl_pipeline_stage *stage ) +{ + stage->active = ctx->_NeedNormals; + /* Don't clobber the initialize function: + */ + if (stage->privatePtr) + stage->run = run_validate_normal_stage; +} + + +static GLboolean alloc_normal_data( GLcontext *ctx, + struct gl_pipeline_stage *stage ) +{ + TNLcontext *tnl = TNL_CONTEXT(ctx); + struct normal_stage_data *store; + stage->privatePtr = MALLOC(sizeof(*store)); + store = NORMAL_STAGE_DATA(stage); + if (!store) + return GL_FALSE; + + _mesa_vector3f_alloc( &store->normal, 0, tnl->vb.Size, 32 ); + + /* Now run the stage. + */ + stage->run = run_validate_normal_stage; + return stage->run( ctx, stage ); +} + + + +static void free_normal_data( struct gl_pipeline_stage *stage ) +{ + struct normal_stage_data *store = NORMAL_STAGE_DATA(stage); + if (store) { + _mesa_vector3f_free( &store->normal ); + FREE( store ); + stage->privatePtr = NULL; + } +} + +#define _TNL_NEW_NORMAL_TRANSFORM (_NEW_MODELVIEW| \ + _NEW_TRANSFORM| \ + _MESA_NEW_NEED_NORMALS| \ + _MESA_NEW_NEED_EYE_COORDS) + + + +const struct gl_pipeline_stage _tnl_normal_transform_stage = +{ + "normal transform", + _TNL_NEW_NORMAL_TRANSFORM, /* re-check */ + _TNL_NEW_NORMAL_TRANSFORM, /* re-run */ + 0,VERT_NORM,VERT_NORM, /* active, inputs, outputs */ + 0, 0, /* changed_inputs, private */ + free_normal_data, /* destructor */ + check_normal_transform, /* check */ + alloc_normal_data /* run -- initially set to alloc */ +}; Index: dll/opengl/opengl32/mesa/tnl/t_vb_points.c =================================================================== --- dll/opengl/opengl32/mesa/tnl/t_vb_points.c (revision 0) +++ dll/opengl/opengl32/mesa/tnl/t_vb_points.c (working copy) @@ -0,0 +1,124 @@ +/* $Id: t_vb_points.c,v 1.4 2001/03/12 00:48:44 gareth Exp $ */ + +/* + * Mesa 3-D graphics library + * Version: 3.5 + * + * Copyright (C) 1999-2001 Brian Paul 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 + * BRIAN PAUL 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. + * + * Authors: + * Brian Paul + */ + +#include "mtypes.h" +#include "mem.h" +#include "t_context.h" +#include "t_pipeline.h" + + +struct point_stage_data { + GLvector1f PointSize; +}; + +#define POINT_STAGE_DATA(stage) ((struct point_stage_data *)stage->privatePtr) + + +/* + * Compute attenuated point sizes + */ +static GLboolean run_point_stage( GLcontext *ctx, + struct gl_pipeline_stage *stage ) +{ + struct point_stage_data *store = POINT_STAGE_DATA(stage); + struct vertex_buffer *VB = &TNL_CONTEXT(ctx)->vb; + const GLfloat (*eye)[4] = (const GLfloat (*)[4]) VB->EyePtr->data; + const GLfloat p0 = ctx->Point.Params[0]; + const GLfloat p1 = ctx->Point.Params[1]; + const GLfloat p2 = ctx->Point.Params[2]; + const GLfloat pointSize = ctx->Point._Size; + GLfloat *size = store->PointSize.data; + GLuint i; + + if (stage->changed_inputs) { + /* XXX do threshold and min/max clamping here? */ + for (i = 0; i < VB->Count; i++) { + const GLfloat dist = -eye[i][2]; + /* GLfloat dist = GL_SQRT(pos[0]*pos[0]+pos[1]*pos[1]+pos[2]*pos[2]);*/ + size[i] = pointSize / (p0 + dist * (p1 + dist * p2)); + } + } + + VB->PointSizePtr = &store->PointSize; + + return GL_TRUE; +} + + +/* If point size attenuation is on we'll compute the point size for + * each vertex in a special pipeline stage. + */ +static void check_point_size( GLcontext *ctx, struct gl_pipeline_stage *d ) +{ + d->active = ctx->Point._Attenuated; +} + +static GLboolean alloc_point_data( GLcontext *ctx, + struct gl_pipeline_stage *stage ) +{ + struct vertex_buffer *VB = &TNL_CONTEXT(ctx)->vb; + struct point_stage_data *store; + stage->privatePtr = MALLOC(sizeof(*store)); + store = POINT_STAGE_DATA(stage); + if (!store) + return GL_FALSE; + + _mesa_vector1f_alloc( &store->PointSize, 0, VB->Size, 32 ); + + /* Now run the stage. + */ + stage->run = run_point_stage; + return stage->run( ctx, stage ); +} + + +static void free_point_data( struct gl_pipeline_stage *stage ) +{ + struct point_stage_data *store = POINT_STAGE_DATA(stage); + if (store) { + _mesa_vector1f_free( &store->PointSize ); + FREE( store ); + stage->privatePtr = 0; + } +} + +const struct gl_pipeline_stage _tnl_point_attenuation_stage = +{ + "point size attenuation", /* name */ + _NEW_POINT, /* build_state_change */ + _NEW_POINT, /* run_state_change */ + 0, /* active */ + VERT_EYE, /* inputs */ + VERT_POINT_SIZE, /* outputs */ + 0, /* changed_inputs (temporary value) */ + 0, /* stage private data */ + free_point_data, /* destructor */ + check_point_size, /* check */ + alloc_point_data /* run -- initially set to alloc data */ +}; Index: dll/opengl/opengl32/mesa/tnl/t_vb_render.c =================================================================== --- dll/opengl/opengl32/mesa/tnl/t_vb_render.c (revision 0) +++ dll/opengl/opengl32/mesa/tnl/t_vb_render.c (working copy) @@ -0,0 +1,402 @@ +/* $Id: t_vb_render.c,v 1.21 2001/06/15 15:22:08 brianp Exp $ */ + +/* + * Mesa 3-D graphics library + * Version: 3.5 + * + * Copyright (C) 1999-2001 Brian Paul 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 + * BRIAN PAUL 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. + * + * Authors: + * Keith Whitwell + */ + + +/* + * Render whole vertex buffers, including projection of vertices from + * clip space and clipping of primitives. + * + * This file makes calls to project vertices and to the point, line + * and triangle rasterizers via the function pointers: + * + * context->Driver.BuildProjectedVertices() + * + * context->Driver.PointsFunc() + * context->Driver.LineFunc() + * context->Driver.TriangleFunc() + * context->Driver.QuadFunc() + * + * context->Driver.RenderTabVerts[] + * context->Driver.RenderTabElts[] + * + * None of these may be null. + */ + + +#include "glheader.h" +#include "context.h" +#include "macros.h" +#include "mem.h" +#include "mtypes.h" +#include "mmath.h" + +#include "math/m_matrix.h" +#include "math/m_xform.h" + +#include "t_pipeline.h" + + + +/**********************************************************************/ +/* Clip single primitives */ +/**********************************************************************/ + + +#if defined(USE_IEEE) +#define NEGATIVE(x) (GET_FLOAT_BITS(x) & (1<<31)) +#define DIFFERENT_SIGNS(x,y) ((GET_FLOAT_BITS(x) ^ GET_FLOAT_BITS(y)) & (1<<31)) +#else +#define NEGATIVE(x) (x < 0) +#define DIFFERENT_SIGNS(x,y) (x * y <= 0 && x - y != 0) +/* Could just use (x*y<0) except for the flatshading requirements. + * Maybe there's a better way? + */ +#endif + + +#define W(i) coord[i][3] +#define Z(i) coord[i][2] +#define Y(i) coord[i][1] +#define X(i) coord[i][0] +#define SIZE 4 +#define TAG(x) x##_4 +#include "t_vb_cliptmp.h" + + + +/**********************************************************************/ +/* Clip and render whole begin/end objects */ +/**********************************************************************/ + +#define NEED_EDGEFLAG_SETUP (ctx->_TriangleCaps & DD_TRI_UNFILLED) +#define EDGEFLAG_GET(idx) VB->EdgeFlag[idx] +#define EDGEFLAG_SET(idx, val) VB->EdgeFlag[idx] = val + + +/* Vertices, with the possibility of clipping. + */ +#define RENDER_POINTS( start, count ) \ + tnl->Driver.PointsFunc( ctx, start, count ) + +#define RENDER_LINE( v1, v2 ) \ +do { \ + GLubyte c1 = mask[v1], c2 = mask[v2]; \ + GLubyte ormask = c1|c2; \ + if (!ormask) \ + LineFunc( ctx, v1, v2 ); \ + else if (!(c1 & c2 & 0x3f)) \ + clip_line_4( ctx, v1, v2, ormask ); \ +} while (0) + +#define RENDER_TRI( v1, v2, v3 ) \ +do { \ + GLubyte c1 = mask[v1], c2 = mask[v2], c3 = mask[v3]; \ + GLubyte ormask = c1|c2|c3; \ + if (!ormask) \ + TriangleFunc( ctx, v1, v2, v3 ); \ + else if (!(c1 & c2 & c3 & 0x3f)) \ + clip_tri_4( ctx, v1, v2, v3, ormask ); \ +} while (0) + +#define RENDER_QUAD( v1, v2, v3, v4 ) \ +do { \ + GLubyte c1 = mask[v1], c2 = mask[v2]; \ + GLubyte c3 = mask[v3], c4 = mask[v4]; \ + GLubyte ormask = c1|c2|c3|c4; \ + if (!ormask) \ + QuadFunc( ctx, v1, v2, v3, v4 ); \ + else if (!(c1 & c2 & c3 & c4 & 0x3f)) \ + clip_quad_4( ctx, v1, v2, v3, v4, ormask ); \ +} while (0) + + +#define LOCAL_VARS \ + TNLcontext *tnl = TNL_CONTEXT(ctx); \ + struct vertex_buffer *VB = &tnl->vb; \ + const GLuint * const elt = VB->Elts; \ + const GLubyte *mask = VB->ClipMask; \ + const GLuint sz = VB->ClipPtr->size; \ + const line_func LineFunc = tnl->Driver.LineFunc; \ + const triangle_func TriangleFunc = tnl->Driver.TriangleFunc; \ + const quad_func QuadFunc = tnl->Driver.QuadFunc; \ + const GLboolean stipple = ctx->Line.StippleFlag; \ + (void) (LineFunc && TriangleFunc && QuadFunc); \ + (void) elt; (void) mask; (void) sz; (void) stipple; + +#define TAG(x) clip_##x##_verts +#define INIT(x) tnl->Driver.RenderPrimitive( ctx, x ) +#define RESET_STIPPLE if (stipple) tnl->Driver.ResetLineStipple( ctx ) +#define RESET_OCCLUSION ctx->OcclusionResult = GL_TRUE +#define PRESERVE_VB_DEFS +#include "t_vb_rendertmp.h" + + + +/* Elts, with the possibility of clipping. + */ +#undef ELT +#undef TAG +#define ELT(x) elt[x] +#define TAG(x) clip_##x##_elts +#include "t_vb_rendertmp.h" + +/* TODO: do this for all primitives, verts and elts: + */ +static void clip_elt_triangles( GLcontext *ctx, + GLuint start, + GLuint count, + GLuint flags ) +{ + TNLcontext *tnl = TNL_CONTEXT(ctx); + render_func render_tris = tnl->Driver.RenderTabElts[GL_TRIANGLES]; + struct vertex_buffer *VB = &tnl->vb; + const GLuint * const elt = VB->Elts; + GLubyte *mask = VB->ClipMask; + GLuint last = count-2; + GLuint j; + (void) flags; + + tnl->Driver.RenderPrimitive( ctx, GL_TRIANGLES ); + + for (j=start; j < last; j+=3 ) { + GLubyte c1 = mask[elt[j]]; + GLubyte c2 = mask[elt[j+1]]; + GLubyte c3 = mask[elt[j+2]]; + GLubyte ormask = c1|c2|c3; + if (ormask) { + if (start < j) + render_tris( ctx, start, j, 0 ); + if (!(c1&c2&c3&0x3f)) + clip_tri_4( ctx, elt[j], elt[j+1], elt[j+2], ormask ); + start = j+3; + } + } + + if (start < j) + render_tris( ctx, start, j, 0 ); +} + +/**********************************************************************/ +/* Render whole begin/end objects */ +/**********************************************************************/ + +#define NEED_EDGEFLAG_SETUP (ctx->_TriangleCaps & DD_TRI_UNFILLED) +#define EDGEFLAG_GET(idx) VB->EdgeFlag[idx] +#define EDGEFLAG_SET(idx, val) VB->EdgeFlag[idx] = val + + +/* Vertices, no clipping. + */ +#define RENDER_POINTS( start, count ) \ + tnl->Driver.PointsFunc( ctx, start, count ) + +#define RENDER_LINE( v1, v2 ) \ + LineFunc( ctx, v1, v2 ) + +#define RENDER_TRI( v1, v2, v3 ) \ + TriangleFunc( ctx, v1, v2, v3 ) + +#define RENDER_QUAD( v1, v2, v3, v4 ) \ + QuadFunc( ctx, v1, v2, v3, v4 ) + +#define TAG(x) _tnl_##x##_verts + +#define LOCAL_VARS \ + TNLcontext *tnl = TNL_CONTEXT(ctx); \ + struct vertex_buffer *VB = &tnl->vb; \ + const GLuint * const elt = VB->Elts; \ + const line_func LineFunc = tnl->Driver.LineFunc; \ + const triangle_func TriangleFunc = tnl->Driver.TriangleFunc; \ + const quad_func QuadFunc = tnl->Driver.QuadFunc; \ + (void) (LineFunc && TriangleFunc && QuadFunc); \ + (void) elt; + +#define RESET_STIPPLE tnl->Driver.ResetLineStipple( ctx ) +#define RESET_OCCLUSION ctx->OcclusionResult = GL_TRUE +#define INIT(x) tnl->Driver.RenderPrimitive( ctx, x ) +#define RENDER_TAB_QUALIFIER +#define PRESERVE_VB_DEFS +#include "t_vb_rendertmp.h" + + +/* Elts, no clipping. + */ +#undef ELT +#define TAG(x) _tnl_##x##_elts +#define ELT(x) elt[x] +#include "t_vb_rendertmp.h" + + + + +/**********************************************************************/ +/* Clip and render whole vertex buffers */ +/**********************************************************************/ + + +static GLboolean run_render( GLcontext *ctx, + struct gl_pipeline_stage *stage ) +{ + TNLcontext *tnl = TNL_CONTEXT(ctx); + struct vertex_buffer *VB = &tnl->vb; + GLuint new_inputs = stage->changed_inputs; + render_func *tab; + GLint pass = 0; + + + /* Allow the drivers to lock before projected verts are built so + * that window coordinates are guarenteed not to change before + * rendering. + */ + ASSERT(tnl->Driver.RenderStart); + + tnl->Driver.RenderStart( ctx ); + + ASSERT(tnl->Driver.BuildProjectedVertices); + ASSERT(tnl->Driver.RenderPrimitive); + ASSERT(tnl->Driver.PointsFunc); + ASSERT(tnl->Driver.LineFunc); + ASSERT(tnl->Driver.TriangleFunc); + ASSERT(tnl->Driver.QuadFunc); + ASSERT(tnl->Driver.ResetLineStipple); + ASSERT(tnl->Driver.RenderInterp); + ASSERT(tnl->Driver.RenderCopyPV); + ASSERT(tnl->Driver.RenderClippedLine); + ASSERT(tnl->Driver.RenderClippedPolygon); + ASSERT(tnl->Driver.RenderFinish); + + tnl->Driver.BuildProjectedVertices( ctx, 0, VB->Count, new_inputs ); + + if (VB->ClipOrMask) { + tab = VB->Elts ? clip_render_tab_elts : clip_render_tab_verts; + clip_render_tab_elts[GL_TRIANGLES] = clip_elt_triangles; + } + else { + tab = VB->Elts ? tnl->Driver.RenderTabElts : tnl->Driver.RenderTabVerts; + } + + do + { + GLuint i, length, flags = 0; + for (i = 0 ; !(flags & PRIM_LAST) ; i += length) + { + flags = VB->Primitive[i]; + length= VB->PrimitiveLength[i]; + ASSERT(length || (flags & PRIM_LAST)); + ASSERT((flags & PRIM_MODE_MASK) <= GL_POLYGON+1); + if (length) + tab[flags & PRIM_MODE_MASK]( ctx, i, i + length, flags ); + } + } while (tnl->Driver.MultipassFunc && + tnl->Driver.MultipassFunc( ctx, ++pass )); + + + tnl->Driver.RenderFinish( ctx ); +/* _swrast_flush(ctx); */ +/* usleep(1000000); */ + return GL_FALSE; /* finished the pipe */ +} + + +/**********************************************************************/ +/* Render pipeline stage */ +/**********************************************************************/ + + + +/* Quite a bit of work involved in finding out the inputs for the + * render stage. + */ +static void check_render( GLcontext *ctx, struct gl_pipeline_stage *stage ) +{ + GLuint inputs = VERT_CLIP; + GLuint i; + + if (ctx->Visual.rgbMode) { + inputs |= VERT_RGBA; + + if (ctx->_TriangleCaps & DD_SEPARATE_SPECULAR) + inputs |= VERT_SPEC_RGB; + + if (ctx->Texture._ReallyEnabled) { + for (i = 0 ; i < ctx->Const.MaxTextureUnits ; i++) { + if (ctx->Texture.Unit[i]._ReallyEnabled) + inputs |= VERT_TEX(i); + } + } + } + else { + inputs |= VERT_INDEX; + } + + if (ctx->Point._Attenuated) + inputs |= VERT_POINT_SIZE; + + /* How do drivers turn this off? + */ + if (ctx->Fog.Enabled) + inputs |= VERT_FOG_COORD; + + if (ctx->_TriangleCaps & DD_TRI_UNFILLED) + inputs |= VERT_EDGE; + + if (ctx->RenderMode==GL_FEEDBACK) + inputs |= VERT_TEX_ANY; + + stage->inputs = inputs; +} + + + + +static void dtr( struct gl_pipeline_stage *stage ) +{ +} + + +const struct gl_pipeline_stage _tnl_render_stage = +{ + "render", + (_NEW_BUFFERS | + _DD_NEW_SEPARATE_SPECULAR | + _DD_NEW_FLATSHADE | + _NEW_TEXTURE| + _NEW_LIGHT| + _NEW_POINT| + _NEW_FOG| + _DD_NEW_TRI_UNFILLED | + _NEW_RENDERMODE), /* re-check (new inputs, interp function) */ + 0, /* re-run (always runs) */ + GL_TRUE, /* active */ + 0, 0, /* inputs (set in check_render), outputs */ + 0, 0, /* changed_inputs, private */ + dtr, /* destructor */ + check_render, /* check */ + run_render /* run */ +}; Index: dll/opengl/opengl32/mesa/tnl/t_vb_rendertmp.h =================================================================== --- dll/opengl/opengl32/mesa/tnl/t_vb_rendertmp.h (revision 0) +++ dll/opengl/opengl32/mesa/tnl/t_vb_rendertmp.h (working copy) @@ -0,0 +1,438 @@ +/* $Id: t_vb_rendertmp.h,v 1.8 2001/03/12 00:48:44 gareth Exp $ */ + +/* + * Mesa 3-D graphics library + * Version: 3.5 + * + * Copyright (C) 1999-2001 Brian Paul 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 + * BRIAN PAUL 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. + * + * Authors: + * Keith Whitwell + */ + + +#ifndef POSTFIX +#define POSTFIX +#endif + +#ifndef INIT +#define INIT(x) +#endif + +#ifndef NEED_EDGEFLAG_SETUP +#define NEED_EDGEFLAG_SETUP 0 +#define EDGEFLAG_GET(a) 0 +#define EDGEFLAG_SET(a,b) (void)b +#endif + +#ifndef RESET_STIPPLE +#define RESET_STIPPLE +#endif + +#ifndef RESET_OCCLUSION +#define RESET_OCCLUSION +#endif + +#ifndef TEST_PRIM_END +#define TEST_PRIM_END(flags) (flags & PRIM_END) +#define TEST_PRIM_BEGIN(flags) (flags & PRIM_BEGIN) +#define TEST_PRIM_PARITY(flags) (flags & PRIM_PARITY) +#endif + +#ifndef ELT +#define ELT(x) x +#endif + +#ifndef RENDER_TAB_QUALIFIER +#define RENDER_TAB_QUALIFIER static +#endif + +static void TAG(render_points)( GLcontext *ctx, + GLuint start, + GLuint count, + GLuint flags ) +{ + LOCAL_VARS; + (void) flags; + + RESET_OCCLUSION; + INIT(GL_POINTS); + RENDER_POINTS( start, count ); + POSTFIX; +} + +static void TAG(render_lines)( GLcontext *ctx, + GLuint start, + GLuint count, + GLuint flags ) +{ + GLuint j; + LOCAL_VARS; + (void) flags; + + RESET_OCCLUSION; + INIT(GL_LINES); + for (j=start+1; j + * Keith Whitwell + */ + + +#include "glheader.h" +#include "colormac.h" +#include "context.h" +#include "macros.h" +#include "mmath.h" +#include "mem.h" +#include "mtypes.h" + +#include "math/m_xform.h" + +#include "t_context.h" +#include "t_pipeline.h" + + +/*********************************************************************** + * Automatic texture coordinate generation (texgen) code. + */ + + +struct texgen_stage_data; + +typedef void (*texgen_func)( GLcontext *ctx, + struct texgen_stage_data *store, + GLuint unit); + + +struct texgen_stage_data { + + /* Per-texunit derived state. + */ + GLuint TexgenSize[MAX_TEXTURE_UNITS]; + GLuint TexgenHoles[MAX_TEXTURE_UNITS]; + texgen_func TexgenFunc[MAX_TEXTURE_UNITS]; + + /* Temporary values used in texgen. + */ + GLfloat (*tmp_f)[3]; + GLfloat *tmp_m; + + /* Buffered outputs of the stage. + */ + GLvector4f texcoord[MAX_TEXTURE_UNITS]; +}; + + +#define TEXGEN_STAGE_DATA(stage) ((struct texgen_stage_data *)stage->privatePtr) + + + +static GLuint all_bits[5] = { + 0, + VEC_SIZE_1, + VEC_SIZE_2, + VEC_SIZE_3, + VEC_SIZE_4, +}; + +#define VEC_SIZE_FLAGS (VEC_SIZE_1|VEC_SIZE_2|VEC_SIZE_3|VEC_SIZE_4) + +#define TEXGEN_NEED_M (TEXGEN_SPHERE_MAP) +#define TEXGEN_NEED_F (TEXGEN_SPHERE_MAP | \ + TEXGEN_REFLECTION_MAP_NV) + + + +static void build_m3( GLfloat f[][3], GLfloat m[], + const GLvector3f *normal, + const GLvector4f *eye ) +{ + GLuint stride = eye->stride; + GLfloat *coord = (GLfloat *)eye->start; + GLuint count = eye->count; + const GLfloat *norm = normal->start; + GLuint i; + + for (i=0;istride)) { + GLfloat u[3], two_nu, fx, fy, fz; + COPY_3V( u, coord ); + NORMALIZE_3FV( u ); + two_nu = 2.0F * DOT3(norm,u); + fx = f[i][0] = u[0] - norm[0] * two_nu; + fy = f[i][1] = u[1] - norm[1] * two_nu; + fz = f[i][2] = u[2] - norm[2] * two_nu; + m[i] = fx * fx + fy * fy + (fz + 1.0F) * (fz + 1.0F); + if (m[i] != 0.0F) { + m[i] = 0.5F / (GLfloat) GL_SQRT(m[i]); + } + } +} + + + +static void build_m2( GLfloat f[][3], GLfloat m[], + const GLvector3f *normal, + const GLvector4f *eye ) +{ + GLuint stride = eye->stride; + GLfloat *coord = eye->start; + GLuint count = eye->count; + + GLfloat *norm = normal->start; + GLuint i; + + for (i=0;istride)) { + GLfloat u[3], two_nu, fx, fy, fz; + COPY_2V( u, coord ); + u[2] = 0; + NORMALIZE_3FV( u ); + two_nu = 2.0F * DOT3(norm,u); + fx = f[i][0] = u[0] - norm[0] * two_nu; + fy = f[i][1] = u[1] - norm[1] * two_nu; + fz = f[i][2] = u[2] - norm[2] * two_nu; + m[i] = fx * fx + fy * fy + (fz + 1.0F) * (fz + 1.0F); + if (m[i] != 0.0F) { + m[i] = 0.5F / (GLfloat) GL_SQRT(m[i]); + } + } +} + + + +typedef void (*build_m_func)( GLfloat f[][3], + GLfloat m[], + const GLvector3f *normal, + const GLvector4f *eye ); + + +static build_m_func build_m_tab[5] = { + 0, + 0, + build_m2, + build_m3, + build_m3 +}; + + +/* This is unusual in that we respect the stride of the output vector + * (f). This allows us to pass in either a texcoord vector4f, or a + * temporary vector3f. + */ +static void build_f3( GLfloat *f, + GLuint fstride, + const GLvector3f *normal, + const GLvector4f *eye ) +{ + GLuint stride = eye->stride; + GLfloat *coord = eye->start; + GLuint count = eye->count; + + GLfloat *norm = normal->start; + GLuint i; + + for (i=0;istride); + } +} + + +static void build_f2( GLfloat *f, + GLuint fstride, + const GLvector3f *normal, + const GLvector4f *eye ) +{ + GLuint stride = eye->stride; + GLfloat *coord = eye->start; + GLuint count = eye->count; + GLfloat *norm = normal->start; + GLuint i; + + for (i=0;istride); + } +} + +typedef void (*build_f_func)( GLfloat *f, + GLuint fstride, + const GLvector3f *normal_vec, + const GLvector4f *eye ); + + + +/* Just treat 4-vectors as 3-vectors. + */ +static build_f_func build_f_tab[5] = { + 0, + 0, + build_f2, + build_f3, + build_f3 +}; + + +/* Special case texgen functions. + */ +static void texgen_reflection_map_nv( GLcontext *ctx, + struct texgen_stage_data *store, + GLuint unit ) +{ + struct vertex_buffer *VB = &TNL_CONTEXT(ctx)->vb; + GLvector4f *in = VB->TexCoordPtr[unit]; + GLvector4f *out = &store->texcoord[unit]; + + build_f_tab[VB->EyePtr->size]( out->start, + out->stride, + VB->NormalPtr, + VB->EyePtr ); + + if (in) { + out->flags |= (in->flags & VEC_SIZE_FLAGS) | VEC_SIZE_3; + out->count = in->count; + out->size = MAX2(in->size, 3); + if (in->size == 4) + _mesa_copy_tab[0x8]( out, in ); + } + else { + out->flags |= VEC_SIZE_3; + out->size = 3; + out->count = in->count; + } + +} + + + +static void texgen_normal_map_nv( GLcontext *ctx, + struct texgen_stage_data *store, + GLuint unit ) +{ + struct vertex_buffer *VB = &TNL_CONTEXT(ctx)->vb; + GLvector4f *in = VB->TexCoordPtr[unit]; + GLvector4f *out = &store->texcoord[unit]; + GLvector3f *normal = VB->NormalPtr; + GLfloat (*texcoord)[4] = (GLfloat (*)[4])out->start; + GLuint count = VB->Count; + GLuint i; + const GLfloat *norm = normal->start; + + for (i=0;istride)) { + texcoord[i][0] = norm[0]; + texcoord[i][1] = norm[1]; + texcoord[i][2] = norm[2]; + } + + + if (in) { + out->flags |= (in->flags & VEC_SIZE_FLAGS) | VEC_SIZE_3; + out->count = in->count; + out->size = MAX2(in->size, 3); + if (in->size == 4) + _mesa_copy_tab[0x8]( out, in ); + } + else { + out->flags |= VEC_SIZE_3; + out->size = 3; + out->count = in->count; + } +} + + +static void texgen_sphere_map( GLcontext *ctx, + struct texgen_stage_data *store, + GLuint unit ) +{ + struct vertex_buffer *VB = &TNL_CONTEXT(ctx)->vb; + GLvector4f *in = VB->TexCoordPtr[unit]; + GLvector4f *out = &store->texcoord[unit]; + GLfloat (*texcoord)[4] = (GLfloat (*)[4]) out->start; + GLuint count = VB->Count; + GLuint i; + GLfloat (*f)[3] = store->tmp_f; + GLfloat *m = store->tmp_m; + +/* fprintf(stderr, "%s normstride %d eyestride %d\n", */ +/* __FUNCTION__, VB->NormalPtr->stride, */ +/* VB->EyePtr->stride); */ + + (build_m_tab[VB->EyePtr->size])( store->tmp_f, + store->tmp_m, + VB->NormalPtr, + VB->EyePtr ); + + for (i=0;isize = MAX2(in->size,2); + out->count = in->count; + out->flags |= (in->flags & VEC_SIZE_FLAGS) | VEC_SIZE_2; + if (in->size > 2) + _mesa_copy_tab[all_bits[in->size] & ~0x3]( out, in ); + } else { + out->size = 2; + out->flags |= VEC_SIZE_2; + out->count = in->count; + } +} + + + +static void texgen( GLcontext *ctx, + struct texgen_stage_data *store, + GLuint unit ) +{ + TNLcontext *tnl = TNL_CONTEXT(ctx); + struct vertex_buffer *VB = &tnl->vb; + GLvector4f *in = VB->TexCoordPtr[unit]; + GLvector4f *out = &store->texcoord[unit]; + struct gl_texture_unit *texUnit = &ctx->Texture.Unit[unit]; + const GLvector4f *obj = VB->ObjPtr; + const GLvector4f *eye = VB->EyePtr; + const GLvector3f *normal = VB->NormalPtr; + GLfloat (*texcoord)[4] = (GLfloat (*)[4])out->data; + GLfloat *indata; + GLuint count = VB->Count; + GLfloat (*f)[3] = store->tmp_f; + GLfloat *m = store->tmp_m; + GLuint holes = 0; + + + if (texUnit->_GenFlags & TEXGEN_NEED_M) { + build_m_tab[in->size]( store->tmp_f, store->tmp_m, normal, eye ); + } else if (texUnit->_GenFlags & TEXGEN_NEED_F) { + build_f_tab[in->size]( (GLfloat *)store->tmp_f, 3, normal, eye ); + } + + if (!in) { + ASSERT(0); + in = out; + in->count = VB->Count; + + out->size = store->TexgenSize[unit]; + out->flags |= texUnit->TexGenEnabled; + out->count = VB->Count; + holes = store->TexgenHoles[unit]; + } + else { + GLuint copy = (all_bits[in->size] & ~texUnit->TexGenEnabled); + if (copy) + _mesa_copy_tab[copy]( out, in ); + + out->size = MAX2(in->size, store->TexgenSize[unit]); + out->flags |= (in->flags & VEC_SIZE_FLAGS) | texUnit->TexGenEnabled; + out->count = in->count; + + holes = ~all_bits[in->size] & store->TexgenHoles[unit]; + } + + if (holes) { + if (holes & VEC_DIRTY_2) _mesa_vector4f_clean_elem(out, count, 2); + if (holes & VEC_DIRTY_1) _mesa_vector4f_clean_elem(out, count, 1); + if (holes & VEC_DIRTY_0) _mesa_vector4f_clean_elem(out, count, 0); + } + + if (texUnit->TexGenEnabled & S_BIT) { + GLuint i; + switch (texUnit->GenModeS) { + case GL_OBJECT_LINEAR: + _mesa_dotprod_tab[obj->size]( (GLfloat *)out->data, + sizeof(out->data[0]), obj, + texUnit->ObjectPlaneS ); + break; + case GL_EYE_LINEAR: + _mesa_dotprod_tab[eye->size]( (GLfloat *)out->data, + sizeof(out->data[0]), eye, + texUnit->EyePlaneS ); + break; + case GL_SPHERE_MAP: + for (indata=in->start,i=0 ; istride)) + texcoord[i][0] = indata[0] * m[i] + 0.5F; + break; + case GL_REFLECTION_MAP_NV: + for (i=0;istart; + for (i=0;istride)) { + texcoord[i][0] = norm[0]; + } + break; + } + default: + _mesa_problem(ctx, "Bad S texgen"); + } + } + + if (texUnit->TexGenEnabled & T_BIT) { + GLuint i; + switch (texUnit->GenModeT) { + case GL_OBJECT_LINEAR: + _mesa_dotprod_tab[obj->size]( &(out->data[0][1]), + sizeof(out->data[0]), obj, + texUnit->ObjectPlaneT ); + break; + case GL_EYE_LINEAR: + _mesa_dotprod_tab[eye->size]( &(out->data[0][1]), + sizeof(out->data[0]), eye, + texUnit->EyePlaneT ); + break; + case GL_SPHERE_MAP: + for (indata=in->start,i=0; istride)) + texcoord[i][1] = indata[1] * m[i] + 0.5F; + break; + case GL_REFLECTION_MAP_NV: + for (i=0;istart; + for (i=0;istride)) { + texcoord[i][1] = norm[1]; + } + break; + } + default: + _mesa_problem(ctx, "Bad T texgen"); + } + } + + if (texUnit->TexGenEnabled & R_BIT) { + GLuint i; + switch (texUnit->GenModeR) { + case GL_OBJECT_LINEAR: + _mesa_dotprod_tab[obj->size]( &(out->data[0][2]), + sizeof(out->data[0]), obj, + texUnit->ObjectPlaneR ); + break; + case GL_EYE_LINEAR: + _mesa_dotprod_tab[eye->size]( &(out->data[0][2]), + sizeof(out->data[0]), eye, + texUnit->EyePlaneR ); + break; + case GL_REFLECTION_MAP_NV: + for (i=0;istart; + for (i=0;istride)) { + texcoord[i][2] = norm[2]; + } + break; + } + default: + _mesa_problem(ctx, "Bad R texgen"); + } + } + + if (texUnit->TexGenEnabled & Q_BIT) { + switch (texUnit->GenModeQ) { + case GL_OBJECT_LINEAR: + _mesa_dotprod_tab[obj->size]( &(out->data[0][3]), + sizeof(out->data[0]), obj, + texUnit->ObjectPlaneQ ); + break; + case GL_EYE_LINEAR: + _mesa_dotprod_tab[eye->size]( &(out->data[0][3]), + sizeof(out->data[0]), eye, + texUnit->EyePlaneQ ); + break; + default: + _mesa_problem(ctx, "Bad Q texgen"); + } + } +} + + + +static GLboolean run_texgen_stage( GLcontext *ctx, + struct gl_pipeline_stage *stage ) +{ + struct vertex_buffer *VB = &TNL_CONTEXT(ctx)->vb; + struct texgen_stage_data *store = TEXGEN_STAGE_DATA( stage ); + GLuint i; + + for (i = 0 ; i < ctx->Const.MaxTextureUnits ; i++) + if (ctx->Texture._TexGenEnabled & ENABLE_TEXGEN(i)) { + if (stage->changed_inputs & (VERT_EYE | VERT_NORM | VERT_TEX(i))) + store->TexgenFunc[i]( ctx, store, i ); + + VB->TexCoordPtr[i] = &store->texcoord[i]; + } + + return GL_TRUE; +} + + + + +static GLboolean run_validate_texgen_stage( GLcontext *ctx, + struct gl_pipeline_stage *stage ) +{ + struct texgen_stage_data *store = TEXGEN_STAGE_DATA(stage); + GLuint i; + + for (i = 0 ; i < ctx->Const.MaxTextureUnits ; i++) { + struct gl_texture_unit *texUnit = &ctx->Texture.Unit[i]; + + if (texUnit->TexGenEnabled) { + GLuint sz; + + if (texUnit->TexGenEnabled & R_BIT) + sz = 4; + else if (texUnit->TexGenEnabled & Q_BIT) + sz = 3; + else if (texUnit->TexGenEnabled & T_BIT) + sz = 2; + else + sz = 1; + + store->TexgenSize[i] = sz; + store->TexgenHoles[i] = (all_bits[sz] & ~texUnit->TexGenEnabled); + store->TexgenFunc[i] = texgen; + + if (texUnit->TexGenEnabled == (S_BIT|T_BIT|R_BIT)) { + if (texUnit->_GenFlags == TEXGEN_REFLECTION_MAP_NV) { + store->TexgenFunc[i] = texgen_reflection_map_nv; + } + else if (texUnit->_GenFlags == TEXGEN_NORMAL_MAP_NV) { + store->TexgenFunc[i] = texgen_normal_map_nv; + } + } + else if (texUnit->TexGenEnabled == (S_BIT|T_BIT) && + texUnit->_GenFlags == TEXGEN_SPHERE_MAP) { + store->TexgenFunc[i] = texgen_sphere_map; + } + } + } + + stage->run = run_texgen_stage; + return stage->run( ctx, stage ); +} + + +static void check_texgen( GLcontext *ctx, struct gl_pipeline_stage *stage ) +{ + GLuint i; + stage->active = 0; + + if (ctx->Texture._TexGenEnabled) { + GLuint inputs = 0; + GLuint outputs = 0; + + if (ctx->Texture._GenFlags & TEXGEN_OBJ_LINEAR) + inputs |= VERT_OBJ; + + if (ctx->Texture._GenFlags & TEXGEN_NEED_EYE_COORD) + inputs |= VERT_EYE; + + if (ctx->Texture._GenFlags & TEXGEN_NEED_NORMALS) + inputs |= VERT_NORM; + + for (i = 0 ; i < ctx->Const.MaxTextureUnits ; i++) + if (ctx->Texture._TexGenEnabled & ENABLE_TEXGEN(i)) + { + outputs |= VERT_TEX(i); + + /* Need the original input in case it contains a Q coord: + * (sigh) + */ + inputs |= VERT_TEX(i); + + /* Something for Feedback? */ + } + + if (stage->privatePtr) + stage->run = run_validate_texgen_stage; + stage->active = 1; + stage->inputs = inputs; + stage->outputs = outputs; + } +} + + + + +/* Called the first time stage->run() is invoked. + */ +static GLboolean alloc_texgen_data( GLcontext *ctx, + struct gl_pipeline_stage *stage ) +{ + struct vertex_buffer *VB = &TNL_CONTEXT(ctx)->vb; + struct texgen_stage_data *store; + GLuint i; + + stage->privatePtr = CALLOC(sizeof(*store)); + store = TEXGEN_STAGE_DATA(stage); + if (!store) + return GL_FALSE; + + for (i = 0 ; i < ctx->Const.MaxTextureUnits ; i++) + _mesa_vector4f_alloc( &store->texcoord[i], 0, VB->Size, 32 ); + + store->tmp_f = (GLfloat (*)[3]) MALLOC(VB->Size * sizeof(GLfloat) * 3); + store->tmp_m = (GLfloat *) MALLOC(VB->Size * sizeof(GLfloat)); + + /* Now validate and run the stage. + */ + stage->run = run_validate_texgen_stage; + return stage->run( ctx, stage ); +} + + +static void free_texgen_data( struct gl_pipeline_stage *stage ) + +{ + struct texgen_stage_data *store = TEXGEN_STAGE_DATA(stage); + GLuint i; + + if (store) { + for (i = 0 ; i < MAX_TEXTURE_UNITS ; i++) + if (store->texcoord[i].data) + _mesa_vector4f_free( &store->texcoord[i] ); + + + if (store->tmp_f) FREE( store->tmp_f ); + if (store->tmp_m) FREE( store->tmp_m ); + FREE( store ); + stage->privatePtr = NULL; + } +} + + + +const struct gl_pipeline_stage _tnl_texgen_stage = +{ + "texgen", + _NEW_TEXTURE, /* when to call check() */ + _NEW_TEXTURE, /* when to invalidate stored data */ + 0,0,0, /* active, inputs, outputs */ + 0,0, /* changed_inputs, private */ + free_texgen_data, /* destructor */ + check_texgen, /* check */ + alloc_texgen_data /* run -- initially set to alloc data */ +}; Index: dll/opengl/opengl32/mesa/tnl/t_vb_texmat.c =================================================================== --- dll/opengl/opengl32/mesa/tnl/t_vb_texmat.c (revision 0) +++ dll/opengl/opengl32/mesa/tnl/t_vb_texmat.c (working copy) @@ -0,0 +1,148 @@ +/* $Id: t_vb_texmat.c,v 1.5 2001/03/29 21:16:26 keithw Exp $ */ + +/* + * Mesa 3-D graphics library + * Version: 3.5 + * + * Copyright (C) 1999-2001 Brian Paul 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 + * BRIAN PAUL 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. + * + * Authors: + * Keith Whitwell + */ + + +#include "glheader.h" +#include "colormac.h" +#include "context.h" +#include "macros.h" +#include "mem.h" +#include "mmath.h" +#include "mtypes.h" + +#include "math/m_xform.h" + +#include "t_context.h" +#include "t_pipeline.h" + +/* Is there any real benefit seperating texmat from texgen? It means + * we need two lots of intermediate storage. Any changes to + * _NEW_TEXTURE will invalidate both sets -- it's only on changes to + * *only* _NEW_TEXTURE_MATRIX that texgen survives but texmat doesn't. + * + * However, the seperation of this code from the complex texgen stuff + * is very appealing. + */ +struct texmat_stage_data { + GLvector4f texcoord[MAX_TEXTURE_UNITS]; +}; + +#define TEXMAT_STAGE_DATA(stage) ((struct texmat_stage_data *)stage->privatePtr) + +static void check_texmat( GLcontext *ctx, struct gl_pipeline_stage *stage ) +{ + GLuint i; + stage->active = 0; + + if (ctx->Texture._TexMatEnabled) { + GLuint flags = 0; + + for (i = 0 ; i < ctx->Const.MaxTextureUnits ; i++) + if (ctx->Texture._TexMatEnabled & ENABLE_TEXMAT(i)) + flags |= VERT_TEX(i); + + stage->active = 1; + stage->inputs = flags; + stage->outputs = flags; + } +} + +static GLboolean run_texmat_stage( GLcontext *ctx, + struct gl_pipeline_stage *stage ) +{ + struct texmat_stage_data *store = TEXMAT_STAGE_DATA(stage); + struct vertex_buffer *VB = &TNL_CONTEXT(ctx)->vb; + GLuint i; + + /* ENABLE_TEXMAT implies that the texture matrix is not the + * identity, so we don't have to check that here. + */ + for (i = 0 ; i < ctx->Const.MaxTextureUnits ; i++) + if (ctx->Texture._TexMatEnabled & ENABLE_TEXMAT(i)) { + if (stage->changed_inputs & VERT_TEX(i)) + (void) TransformRaw( &store->texcoord[i], &ctx->TextureMatrix[i], + VB->TexCoordPtr[i]); + + VB->TexCoordPtr[i] = &store->texcoord[i]; + } + return GL_TRUE; +} + + +/* Called the first time stage->run() is invoked. + */ +static GLboolean alloc_texmat_data( GLcontext *ctx, + struct gl_pipeline_stage *stage ) +{ + struct vertex_buffer *VB = &TNL_CONTEXT(ctx)->vb; + struct texmat_stage_data *store; + GLuint i; + + stage->privatePtr = CALLOC(sizeof(*store)); + store = TEXMAT_STAGE_DATA(stage); + if (!store) + return GL_FALSE; + + for (i = 0 ; i < ctx->Const.MaxTextureUnits ; i++) + _mesa_vector4f_alloc( &store->texcoord[i], 0, VB->Size, 32 ); + + /* Now run the stage. + */ + stage->run = run_texmat_stage; + return stage->run( ctx, stage ); +} + + +static void free_texmat_data( struct gl_pipeline_stage *stage ) +{ + struct texmat_stage_data *store = TEXMAT_STAGE_DATA(stage); + GLuint i; + + if (store) { + for (i = 0 ; i < MAX_TEXTURE_UNITS ; i++) + if (store->texcoord[i].data) + _mesa_vector4f_free( &store->texcoord[i] ); + FREE( store ); + stage->privatePtr = 0; + } +} + + + +const struct gl_pipeline_stage _tnl_texture_transform_stage = +{ + "texture transform", + _NEW_TEXTURE|_NEW_TEXTURE_MATRIX, + _NEW_TEXTURE|_NEW_TEXTURE_MATRIX, + 0,0,0, /* active, inputs, outputs */ + 0,0, /* changed_inputs, private */ + free_texmat_data, /* destructor */ + check_texmat, /* check */ + alloc_texmat_data, /* run -- initially set to init */ +}; Index: dll/opengl/opengl32/mesa/tnl/t_vb_vertex.c =================================================================== --- dll/opengl/opengl32/mesa/tnl/t_vb_vertex.c (revision 0) +++ dll/opengl/opengl32/mesa/tnl/t_vb_vertex.c (working copy) @@ -0,0 +1,317 @@ +/* $Id: t_vb_vertex.c,v 1.9 2001/05/30 10:01:41 keithw Exp $ */ + +/* + * Mesa 3-D graphics library + * Version: 3.5 + * + * Copyright (C) 1999-2001 Brian Paul 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 + * BRIAN PAUL 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. + * + * Authors: + * Keith Whitwell + */ + + +#include "glheader.h" +#include "colormac.h" +#include "context.h" +#include "macros.h" +#include "mem.h" +#include "mmath.h" +#include "mtypes.h" + +#include "math/m_xform.h" + +#include "t_context.h" +#include "t_pipeline.h" + + + +struct vertex_stage_data { + GLvector4f eye; + GLvector4f clip; + GLvector4f proj; + GLubyte *clipmask; + GLubyte ormask; + GLubyte andmask; + + + /* Need these because it's difficult to replay the sideeffects + * analytically. + */ + GLvector4f *save_eyeptr; + GLvector4f *save_clipptr; + GLvector4f *save_projptr; +}; + +#define VERTEX_STAGE_DATA(stage) ((struct vertex_stage_data *)stage->privatePtr) + + + + +/* This function implements cliptesting for user-defined clip planes. + * The clipping of primitives to these planes is implemented in + * t_render_clip.h. + */ +#define USER_CLIPTEST(NAME, SZ) \ +static void NAME( GLcontext *ctx, \ + GLvector4f *clip, \ + GLubyte *clipmask, \ + GLubyte *clipormask, \ + GLubyte *clipandmask ) \ +{ \ + GLuint p; \ + \ + for (p = 0; p < ctx->Const.MaxClipPlanes; p++) \ + if (ctx->Transform.ClipEnabled[p]) { \ + GLuint nr, i; \ + const GLfloat a = ctx->Transform._ClipUserPlane[p][0]; \ + const GLfloat b = ctx->Transform._ClipUserPlane[p][1]; \ + const GLfloat c = ctx->Transform._ClipUserPlane[p][2]; \ + const GLfloat d = ctx->Transform._ClipUserPlane[p][3]; \ + GLfloat *coord = (GLfloat *)clip->data; \ + GLuint stride = clip->stride; \ + GLuint count = clip->count; \ + \ + for (nr = 0, i = 0 ; i < count ; i++) { \ + GLfloat dp = coord[0] * a + coord[1] * b; \ + if (SZ > 2) dp += coord[2] * c; \ + if (SZ > 3) dp += coord[3] * d; else dp += d; \ + \ + if (dp < 0) { \ + nr++; \ + clipmask[i] |= CLIP_USER_BIT; \ + } \ + \ + STRIDE_F(coord, stride); \ + } \ + \ + if (nr > 0) { \ + *clipormask |= CLIP_USER_BIT; \ + if (nr == count) { \ + *clipandmask |= CLIP_USER_BIT; \ + return; \ + } \ + } \ + } \ +} + + +USER_CLIPTEST(userclip2, 2) +USER_CLIPTEST(userclip3, 3) +USER_CLIPTEST(userclip4, 4) + +static void (*(usercliptab[5]))( GLcontext *, + GLvector4f *, GLubyte *, + GLubyte *, GLubyte * ) = +{ + 0, + 0, + userclip2, + userclip3, + userclip4 +}; + + + +static GLboolean run_vertex_stage( GLcontext *ctx, + struct gl_pipeline_stage *stage ) +{ + struct vertex_stage_data *store = (struct vertex_stage_data *)stage->privatePtr; + TNLcontext *tnl = TNL_CONTEXT(ctx); + struct vertex_buffer *VB = &tnl->vb; + + if (stage->changed_inputs) { + + if (ctx->_NeedEyeCoords) { + /* Separate modelview and project transformations: + */ + if (ctx->ModelView.type == MATRIX_IDENTITY) + VB->EyePtr = VB->ObjPtr; + else + VB->EyePtr = TransformRaw( &store->eye, &ctx->ModelView, + VB->ObjPtr); + + if (ctx->ProjectionMatrix.type == MATRIX_IDENTITY) + VB->ClipPtr = VB->EyePtr; + else + VB->ClipPtr = TransformRaw( &store->clip, &ctx->ProjectionMatrix, + VB->EyePtr ); + } + else { + /* Combined modelviewproject transform: + */ + if (ctx->_ModelProjectMatrix.type == MATRIX_IDENTITY) + VB->ClipPtr = VB->ObjPtr; + else + VB->ClipPtr = TransformRaw( &store->clip, + &ctx->_ModelProjectMatrix, + VB->ObjPtr ); + } + + /* Drivers expect this to be clean to element 4... + */ + if (VB->ClipPtr->size < 4) { + if (VB->ClipPtr->flags & VEC_NOT_WRITEABLE) { + ASSERT(VB->ClipPtr == VB->ObjPtr); + VB->import_data( ctx, VERT_OBJ, VEC_NOT_WRITEABLE ); + VB->ClipPtr = VB->ObjPtr; + } + if (VB->ClipPtr->size == 2) + _mesa_vector4f_clean_elem( VB->ClipPtr, VB->Count, 2 ); + _mesa_vector4f_clean_elem( VB->ClipPtr, VB->Count, 3 ); + } + + /* Cliptest and perspective divide. Clip functions must clear + * the clipmask. + */ + store->ormask = 0; + store->andmask = CLIP_ALL_BITS; + + if (tnl->NeedProjCoords) { + VB->ProjectedClipPtr = + _mesa_clip_tab[VB->ClipPtr->size]( VB->ClipPtr, + &store->proj, + store->clipmask, + &store->ormask, + &store->andmask ); + + } else { + VB->ProjectedClipPtr = 0; + _mesa_clip_np_tab[VB->ClipPtr->size]( VB->ClipPtr, + 0, + store->clipmask, + &store->ormask, + &store->andmask ); + } + + if (store->andmask) + return GL_FALSE; + + + /* Test userclip planes. This contributes to VB->ClipMask, so + * is essentially required to be in this stage. + */ + if (ctx->Transform._AnyClip) { + usercliptab[VB->ClipPtr->size]( ctx, + VB->ClipPtr, + store->clipmask, + &store->ormask, + &store->andmask ); + + if (store->andmask) + return GL_FALSE; + } + + VB->ClipOrMask = store->ormask; + VB->ClipMask = store->clipmask; + + if (VB->ClipPtr == VB->ObjPtr && (VB->importable_data & VERT_OBJ)) + VB->importable_data |= VERT_CLIP; + + store->save_eyeptr = VB->EyePtr; + store->save_clipptr = VB->ClipPtr; + store->save_projptr = VB->ProjectedClipPtr; + } + else { + /* Replay the sideeffects. + */ + VB->EyePtr = store->save_eyeptr; + VB->ClipPtr = store->save_clipptr; + VB->ProjectedClipPtr = store->save_projptr; + VB->ClipMask = store->clipmask; + VB->ClipOrMask = store->ormask; + if (VB->ClipPtr == VB->ObjPtr && (VB->importable_data & VERT_OBJ)) + VB->importable_data |= VERT_CLIP; + if (store->andmask) + return GL_FALSE; + } + + return GL_TRUE; +} + + +static void check_vertex( GLcontext *ctx, struct gl_pipeline_stage *stage ) +{ + (void) ctx; + (void) stage; +} + +static GLboolean init_vertex_stage( GLcontext *ctx, + struct gl_pipeline_stage *stage ) +{ + struct vertex_buffer *VB = &TNL_CONTEXT(ctx)->vb; + struct vertex_stage_data *store; + GLuint size = VB->Size; + + stage->privatePtr = CALLOC(sizeof(*store)); + store = VERTEX_STAGE_DATA(stage); + if (!store) + return GL_FALSE; + + _mesa_vector4f_alloc( &store->eye, 0, size, 32 ); + _mesa_vector4f_alloc( &store->clip, 0, size, 32 ); + _mesa_vector4f_alloc( &store->proj, 0, size, 32 ); + + store->clipmask = (GLubyte *) ALIGN_MALLOC(sizeof(GLubyte)*size, 32 ); + + if (!store->clipmask || + !store->eye.data || + !store->clip.data || + !store->proj.data) + return GL_FALSE; + + /* Now run the stage. + */ + stage->run = run_vertex_stage; + return stage->run( ctx, stage ); +} + +static void dtr( struct gl_pipeline_stage *stage ) +{ + struct vertex_stage_data *store = VERTEX_STAGE_DATA(stage); + + if (store) { + _mesa_vector4f_free( &store->eye ); + _mesa_vector4f_free( &store->clip ); + _mesa_vector4f_free( &store->proj ); + ALIGN_FREE( store->clipmask ); + FREE(store); + stage->privatePtr = NULL; + stage->run = init_vertex_stage; + } +} + + +const struct gl_pipeline_stage _tnl_vertex_transform_stage = +{ + "modelview/project/cliptest/divide", + 0, /* re-check -- always on */ + _MESA_NEW_NEED_EYE_COORDS | + _NEW_MODELVIEW| + _NEW_PROJECTION| + _NEW_TRANSFORM, /* re-run */ + GL_TRUE, /* active */ + VERT_OBJ, /* inputs */ + VERT_EYE|VERT_CLIP, /* outputs */ + 0, 0, /* changed_inputs, private */ + dtr, /* destructor */ + check_vertex, /* check */ + init_vertex_stage /* run -- initially set to init */ +}; Index: dll/opengl/opengl32/mesa/tnl/tnl.h =================================================================== --- dll/opengl/opengl32/mesa/tnl/tnl.h (revision 0) +++ dll/opengl/opengl32/mesa/tnl/tnl.h (working copy) @@ -0,0 +1,70 @@ +/* $Id: tnl.h,v 1.7 2001/06/04 16:09:28 keithw Exp $ */ + +/* + * Mesa 3-D graphics library + * Version: 3.5 + * + * Copyright (C) 1999-2001 Brian Paul 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 + * BRIAN PAUL 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. + * + * Authors: + * Keith Whitwell + */ + +#ifndef _TNL_H +#define _TNL_H + +#include "mtypes.h" + + + +/* These are the public-access functions exported from tnl. (A few + * more are currently hooked into dispatch directly by the module + * itself.) + */ +extern GLboolean +_tnl_CreateContext( GLcontext *ctx ); + +extern void +_tnl_DestroyContext( GLcontext *ctx ); + +extern void +_tnl_InvalidateState( GLcontext *ctx, GLuint new_state ); + +/* Functions to revive the tnl module after being unhooked from + * dispatch and/or driver callbacks. + */ + +/* Restore just the ctx->Exec table: + */ +extern void +_tnl_wakeup_exec( GLcontext *ctx ); + +/* Restore both ctx->Exec and ctx->Save: + */ +extern void +_tnl_wakeup_save_exec( GLcontext *ctx ); + +extern void +_tnl_need_projected_coords( GLcontext *ctx, GLboolean flag ); + +extern void +_tnl_need_dlist_loopback( GLcontext *ctx, GLboolean flag ); + +#endif Index: dll/opengl/opengl32/mesa/varray.c =================================================================== --- dll/opengl/opengl32/mesa/varray.c (revision 0) +++ dll/opengl/opengl32/mesa/varray.c (working copy) @@ -0,0 +1,744 @@ +/* $Id: varray.c,v 1.39 2001/03/12 00:48:39 gareth Exp $ */ + +/* + * Mesa 3-D graphics library + * Version: 3.5 + * + * Copyright (C) 1999-2001 Brian Paul 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 + * BRIAN PAUL 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. + */ + +#ifdef PC_HEADER +#include "all.h" +#else +#include "glheader.h" +#include "context.h" +#include "enable.h" +#include "enums.h" +#include "dlist.h" +#include "light.h" +#include "macros.h" +#include "mmath.h" +#include "state.h" +#include "texstate.h" +#include "mtypes.h" +#include "varray.h" +#include "math/m_translate.h" +#endif + + + +void +_mesa_VertexPointer(GLint size, GLenum type, GLsizei stride, const GLvoid *ptr) +{ + GET_CURRENT_CONTEXT(ctx); + ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx); + + if (size<2 || size>4) { + _mesa_error( ctx, GL_INVALID_VALUE, "glVertexPointer(size)" ); + return; + } + if (stride<0) { + _mesa_error( ctx, GL_INVALID_VALUE, "glVertexPointer(stride)" ); + return; + } + + if (MESA_VERBOSE&(VERBOSE_VARRAY|VERBOSE_API)) + fprintf(stderr, "glVertexPointer( sz %d type %s stride %d )\n", size, + _mesa_lookup_enum_by_nr( type ), + stride); + + ctx->Array.Vertex.StrideB = stride; + if (!stride) { + switch (type) { + case GL_SHORT: + ctx->Array.Vertex.StrideB = size*sizeof(GLshort); + break; + case GL_INT: + ctx->Array.Vertex.StrideB = size*sizeof(GLint); + break; + case GL_FLOAT: + ctx->Array.Vertex.StrideB = size*sizeof(GLfloat); + break; + case GL_DOUBLE: + ctx->Array.Vertex.StrideB = size*sizeof(GLdouble); + break; + default: + _mesa_error( ctx, GL_INVALID_ENUM, "glVertexPointer(type)" ); + return; + } + } + ctx->Array.Vertex.Size = size; + ctx->Array.Vertex.Type = type; + ctx->Array.Vertex.Stride = stride; + ctx->Array.Vertex.Ptr = (void *) ptr; + ctx->NewState |= _NEW_ARRAY; + ctx->Array.NewState |= _NEW_ARRAY_VERTEX; + + if (ctx->Driver.VertexPointer) + ctx->Driver.VertexPointer( ctx, size, type, stride, ptr ); +} + + + + +void +_mesa_NormalPointer(GLenum type, GLsizei stride, const GLvoid *ptr ) +{ + GET_CURRENT_CONTEXT(ctx); + ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx); + + if (stride<0) { + _mesa_error( ctx, GL_INVALID_VALUE, "glNormalPointer(stride)" ); + return; + } + + if (MESA_VERBOSE&(VERBOSE_VARRAY|VERBOSE_API)) + fprintf(stderr, "glNormalPointer( type %s stride %d )\n", + _mesa_lookup_enum_by_nr( type ), + stride); + + ctx->Array.Normal.StrideB = stride; + if (!stride) { + switch (type) { + case GL_BYTE: + ctx->Array.Normal.StrideB = 3*sizeof(GLbyte); + break; + case GL_SHORT: + ctx->Array.Normal.StrideB = 3*sizeof(GLshort); + break; + case GL_INT: + ctx->Array.Normal.StrideB = 3*sizeof(GLint); + break; + case GL_FLOAT: + ctx->Array.Normal.StrideB = 3*sizeof(GLfloat); + break; + case GL_DOUBLE: + ctx->Array.Normal.StrideB = 3*sizeof(GLdouble); + break; + default: + _mesa_error( ctx, GL_INVALID_ENUM, "glNormalPointer(type)" ); + return; + } + } + ctx->Array.Normal.Type = type; + ctx->Array.Normal.Stride = stride; + ctx->Array.Normal.Ptr = (void *) ptr; + ctx->NewState |= _NEW_ARRAY; + ctx->Array.NewState |= _NEW_ARRAY_VERTEX; + + if (ctx->Driver.NormalPointer) + ctx->Driver.NormalPointer( ctx, type, stride, ptr ); +} + + + +void +_mesa_ColorPointer(GLint size, GLenum type, GLsizei stride, const GLvoid *ptr) +{ + GET_CURRENT_CONTEXT(ctx); + ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx); + + if (size<3 || size>4) { + _mesa_error( ctx, GL_INVALID_VALUE, "glColorPointer(size)" ); + return; + } + if (stride<0) { + _mesa_error( ctx, GL_INVALID_VALUE, "glColorPointer(stride)" ); + return; + } + + if (MESA_VERBOSE&(VERBOSE_VARRAY|VERBOSE_API)) + fprintf(stderr, "glColorPointer( sz %d type %s stride %d )\n", size, + _mesa_lookup_enum_by_nr( type ), + stride); + + ctx->Array.Color.StrideB = stride; + if (!stride) { + switch (type) { + case GL_BYTE: + ctx->Array.Color.StrideB = size*sizeof(GLbyte); + break; + case GL_UNSIGNED_BYTE: + ctx->Array.Color.StrideB = size*sizeof(GLubyte); + break; + case GL_SHORT: + ctx->Array.Color.StrideB = size*sizeof(GLshort); + break; + case GL_UNSIGNED_SHORT: + ctx->Array.Color.StrideB = size*sizeof(GLushort); + break; + case GL_INT: + ctx->Array.Color.StrideB = size*sizeof(GLint); + break; + case GL_UNSIGNED_INT: + ctx->Array.Color.StrideB = size*sizeof(GLuint); + break; + case GL_FLOAT: + ctx->Array.Color.StrideB = size*sizeof(GLfloat); + break; + case GL_DOUBLE: + ctx->Array.Color.StrideB = size*sizeof(GLdouble); + break; + default: + _mesa_error( ctx, GL_INVALID_ENUM, "glColorPointer(type)" ); + return; + } + } + ctx->Array.Color.Size = size; + ctx->Array.Color.Type = type; + ctx->Array.Color.Stride = stride; + ctx->Array.Color.Ptr = (void *) ptr; + ctx->NewState |= _NEW_ARRAY; + ctx->Array.NewState |= _NEW_ARRAY_VERTEX; + + if (ctx->Driver.ColorPointer) + ctx->Driver.ColorPointer( ctx, size, type, stride, ptr ); +} + + + +void +_mesa_FogCoordPointerEXT(GLenum type, GLsizei stride, const GLvoid *ptr) +{ + GET_CURRENT_CONTEXT(ctx); + ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx); + + if (stride<0) { + _mesa_error( ctx, GL_INVALID_VALUE, "glFogCoordPointer(stride)" ); + return; + } + + ctx->Array.FogCoord.StrideB = stride; + if (!stride) { + switch (type) { + case GL_FLOAT: + ctx->Array.FogCoord.StrideB = sizeof(GLfloat); + break; + case GL_DOUBLE: + ctx->Array.FogCoord.StrideB = sizeof(GLdouble); + break; + default: + _mesa_error( ctx, GL_INVALID_ENUM, "glFogCoordPointer(type)" ); + return; + } + } + ctx->Array.FogCoord.Type = type; + ctx->Array.FogCoord.Stride = stride; + ctx->Array.FogCoord.Ptr = (void *) ptr; + ctx->NewState |= _NEW_ARRAY; + ctx->Array.NewState |= _NEW_ARRAY_VERTEX; + + if (ctx->Driver.FogCoordPointer) + ctx->Driver.FogCoordPointer( ctx, type, stride, ptr ); +} + + +void +_mesa_IndexPointer(GLenum type, GLsizei stride, const GLvoid *ptr) +{ + GET_CURRENT_CONTEXT(ctx); + ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx); + + if (stride<0) { + _mesa_error( ctx, GL_INVALID_VALUE, "glIndexPointer(stride)" ); + return; + } + + ctx->Array.Index.StrideB = stride; + if (!stride) { + switch (type) { + case GL_UNSIGNED_BYTE: + ctx->Array.Index.StrideB = sizeof(GLubyte); + break; + case GL_SHORT: + ctx->Array.Index.StrideB = sizeof(GLshort); + break; + case GL_INT: + ctx->Array.Index.StrideB = sizeof(GLint); + break; + case GL_FLOAT: + ctx->Array.Index.StrideB = sizeof(GLfloat); + break; + case GL_DOUBLE: + ctx->Array.Index.StrideB = sizeof(GLdouble); + break; + default: + _mesa_error( ctx, GL_INVALID_ENUM, "glIndexPointer(type)" ); + return; + } + } + ctx->Array.Index.Type = type; + ctx->Array.Index.Stride = stride; + ctx->Array.Index.Ptr = (void *) ptr; + ctx->NewState |= _NEW_ARRAY; + ctx->Array.NewState |= _NEW_ARRAY_VERTEX; + + if (ctx->Driver.IndexPointer) + ctx->Driver.IndexPointer( ctx, type, stride, ptr ); +} + + +void +_mesa_SecondaryColorPointerEXT(GLint size, GLenum type, + GLsizei stride, const GLvoid *ptr) +{ + GET_CURRENT_CONTEXT(ctx); + ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx); + + if (size != 3 && size != 4) { + _mesa_error( ctx, GL_INVALID_VALUE, "glColorPointer(size)" ); + return; + } + if (stride<0) { + _mesa_error( ctx, GL_INVALID_VALUE, "glColorPointer(stride)" ); + return; + } + + if (MESA_VERBOSE&(VERBOSE_VARRAY|VERBOSE_API)) + fprintf(stderr, "glColorPointer( sz %d type %s stride %d )\n", size, + _mesa_lookup_enum_by_nr( type ), + stride); + + ctx->Array.SecondaryColor.StrideB = stride; + if (!stride) { + switch (type) { + case GL_BYTE: + ctx->Array.SecondaryColor.StrideB = size*sizeof(GLbyte); + break; + case GL_UNSIGNED_BYTE: + ctx->Array.SecondaryColor.StrideB = size*sizeof(GLubyte); + break; + case GL_SHORT: + ctx->Array.SecondaryColor.StrideB = size*sizeof(GLshort); + break; + case GL_UNSIGNED_SHORT: + ctx->Array.SecondaryColor.StrideB = size*sizeof(GLushort); + break; + case GL_INT: + ctx->Array.SecondaryColor.StrideB = size*sizeof(GLint); + break; + case GL_UNSIGNED_INT: + ctx->Array.SecondaryColor.StrideB = size*sizeof(GLuint); + break; + case GL_FLOAT: + ctx->Array.SecondaryColor.StrideB = size*sizeof(GLfloat); + break; + case GL_DOUBLE: + ctx->Array.SecondaryColor.StrideB = size*sizeof(GLdouble); + break; + default: + _mesa_error( ctx, GL_INVALID_ENUM, "glSecondaryColorPointer(type)" ); + return; + } + } + ctx->Array.SecondaryColor.Size = 3; /* hardwire */ + ctx->Array.SecondaryColor.Type = type; + ctx->Array.SecondaryColor.Stride = stride; + ctx->Array.SecondaryColor.Ptr = (void *) ptr; + ctx->NewState |= _NEW_ARRAY; + ctx->Array.NewState |= _NEW_ARRAY_VERTEX; + + if (ctx->Driver.SecondaryColorPointer) + ctx->Driver.SecondaryColorPointer( ctx, size, type, stride, ptr ); +} + + + +void +_mesa_TexCoordPointer(GLint size, GLenum type, GLsizei stride, const GLvoid *ptr) +{ + GET_CURRENT_CONTEXT(ctx); + GLuint texUnit = ctx->Array.ActiveTexture; + ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx); + + if (size<1 || size>4) { + _mesa_error( ctx, GL_INVALID_VALUE, "glTexCoordPointer(size)" ); + return; + } + if (stride<0) { + _mesa_error( ctx, GL_INVALID_VALUE, "glTexCoordPointer(stride)" ); + return; + } + + if (MESA_VERBOSE&(VERBOSE_VARRAY|VERBOSE_API)) + fprintf(stderr, "glTexCoordPointer( unit %u sz %d type %s stride %d )\n", + texUnit, + size, + _mesa_lookup_enum_by_nr( type ), + stride); + + ctx->Array.TexCoord[texUnit].StrideB = stride; + if (!stride) { + switch (type) { + case GL_SHORT: + ctx->Array.TexCoord[texUnit].StrideB = size*sizeof(GLshort); + break; + case GL_INT: + ctx->Array.TexCoord[texUnit].StrideB = size*sizeof(GLint); + break; + case GL_FLOAT: + ctx->Array.TexCoord[texUnit].StrideB = size*sizeof(GLfloat); + break; + case GL_DOUBLE: + ctx->Array.TexCoord[texUnit].StrideB = size*sizeof(GLdouble); + break; + default: + _mesa_error( ctx, GL_INVALID_ENUM, "glTexCoordPointer(type)" ); + return; + } + } + ctx->Array.TexCoord[texUnit].Size = size; + ctx->Array.TexCoord[texUnit].Type = type; + ctx->Array.TexCoord[texUnit].Stride = stride; + ctx->Array.TexCoord[texUnit].Ptr = (void *) ptr; + ctx->NewState |= _NEW_ARRAY; + ctx->Array.NewState |= _NEW_ARRAY_VERTEX; + +/* fprintf(stderr, "%s ptr %p\n", __FUNCTION__, ptr); */ + + if (ctx->Driver.TexCoordPointer) + ctx->Driver.TexCoordPointer( ctx, size, type, stride, ptr ); +} + + + + +void +_mesa_EdgeFlagPointer(GLsizei stride, const void *vptr) +{ + GET_CURRENT_CONTEXT(ctx); + const GLboolean *ptr = (GLboolean *)vptr; + ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx); + + if (stride<0) { + _mesa_error( ctx, GL_INVALID_VALUE, "glEdgeFlagPointer(stride)" ); + return; + } + ctx->Array.EdgeFlag.Stride = stride; + ctx->Array.EdgeFlag.StrideB = stride ? stride : sizeof(GLboolean); + ctx->Array.EdgeFlag.Ptr = (GLboolean *) ptr; + ctx->NewState |= _NEW_ARRAY; + ctx->Array.NewState |= _NEW_ARRAY_VERTEX; + + if (ctx->Driver.EdgeFlagPointer) + ctx->Driver.EdgeFlagPointer( ctx, stride, ptr ); +} + + + + + +void +_mesa_VertexPointerEXT(GLint size, GLenum type, GLsizei stride, + GLsizei count, const GLvoid *ptr) +{ + (void) count; + _mesa_VertexPointer(size, type, stride, ptr); +} + + +void +_mesa_NormalPointerEXT(GLenum type, GLsizei stride, GLsizei count, + const GLvoid *ptr) +{ + (void) count; + _mesa_NormalPointer(type, stride, ptr); +} + + +void +_mesa_ColorPointerEXT(GLint size, GLenum type, GLsizei stride, GLsizei count, + const GLvoid *ptr) +{ + (void) count; + _mesa_ColorPointer(size, type, stride, ptr); +} + + +void +_mesa_IndexPointerEXT(GLenum type, GLsizei stride, GLsizei count, + const GLvoid *ptr) +{ + (void) count; + _mesa_IndexPointer(type, stride, ptr); +} + + +void +_mesa_TexCoordPointerEXT(GLint size, GLenum type, GLsizei stride, + GLsizei count, const GLvoid *ptr) +{ + (void) count; + _mesa_TexCoordPointer(size, type, stride, ptr); +} + + +void +_mesa_EdgeFlagPointerEXT(GLsizei stride, GLsizei count, const GLboolean *ptr) +{ + (void) count; + _mesa_EdgeFlagPointer(stride, ptr); +} + + + + + + +void +_mesa_InterleavedArrays(GLenum format, GLsizei stride, const GLvoid *pointer) +{ + GET_CURRENT_CONTEXT(ctx); + GLboolean tflag, cflag, nflag; /* enable/disable flags */ + GLint tcomps, ccomps, vcomps; /* components per texcoord, color, vertex */ + + GLenum ctype = 0; /* color type */ + GLint coffset = 0, noffset = 0, voffset;/* color, normal, vertex offsets */ + GLint defstride; /* default stride */ + GLint c, f; + GLint coordUnitSave; + + ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx); + + f = sizeof(GLfloat); + c = f * ((4*sizeof(GLubyte) + (f-1)) / f); + + if (stride<0) { + _mesa_error( ctx, GL_INVALID_VALUE, "glInterleavedArrays(stride)" ); + return; + } + + switch (format) { + case GL_V2F: + tflag = GL_FALSE; cflag = GL_FALSE; nflag = GL_FALSE; + tcomps = 0; ccomps = 0; vcomps = 2; + voffset = 0; + defstride = 2*f; + break; + case GL_V3F: + tflag = GL_FALSE; cflag = GL_FALSE; nflag = GL_FALSE; + tcomps = 0; ccomps = 0; vcomps = 3; + voffset = 0; + defstride = 3*f; + break; + case GL_C4UB_V2F: + tflag = GL_FALSE; cflag = GL_TRUE; nflag = GL_FALSE; + tcomps = 0; ccomps = 4; vcomps = 2; + ctype = GL_UNSIGNED_BYTE; + coffset = 0; + voffset = c; + defstride = c + 2*f; + break; + case GL_C4UB_V3F: + tflag = GL_FALSE; cflag = GL_TRUE; nflag = GL_FALSE; + tcomps = 0; ccomps = 4; vcomps = 3; + ctype = GL_UNSIGNED_BYTE; + coffset = 0; + voffset = c; + defstride = c + 3*f; + break; + case GL_C3F_V3F: + tflag = GL_FALSE; cflag = GL_TRUE; nflag = GL_FALSE; + tcomps = 0; ccomps = 3; vcomps = 3; + ctype = GL_FLOAT; + coffset = 0; + voffset = 3*f; + defstride = 6*f; + break; + case GL_N3F_V3F: + tflag = GL_FALSE; cflag = GL_FALSE; nflag = GL_TRUE; + tcomps = 0; ccomps = 0; vcomps = 3; + noffset = 0; + voffset = 3*f; + defstride = 6*f; + break; + case GL_C4F_N3F_V3F: + tflag = GL_FALSE; cflag = GL_TRUE; nflag = GL_TRUE; + tcomps = 0; ccomps = 4; vcomps = 3; + ctype = GL_FLOAT; + coffset = 0; + noffset = 4*f; + voffset = 7*f; + defstride = 10*f; + break; + case GL_T2F_V3F: + tflag = GL_TRUE; cflag = GL_FALSE; nflag = GL_FALSE; + tcomps = 2; ccomps = 0; vcomps = 3; + voffset = 2*f; + defstride = 5*f; + break; + case GL_T4F_V4F: + tflag = GL_TRUE; cflag = GL_FALSE; nflag = GL_FALSE; + tcomps = 4; ccomps = 0; vcomps = 4; + voffset = 4*f; + defstride = 8*f; + break; + case GL_T2F_C4UB_V3F: + tflag = GL_TRUE; cflag = GL_TRUE; nflag = GL_FALSE; + tcomps = 2; ccomps = 4; vcomps = 3; + ctype = GL_UNSIGNED_BYTE; + coffset = 2*f; + voffset = c+2*f; + defstride = c+5*f; + break; + case GL_T2F_C3F_V3F: + tflag = GL_TRUE; cflag = GL_TRUE; nflag = GL_FALSE; + tcomps = 2; ccomps = 3; vcomps = 3; + ctype = GL_FLOAT; + coffset = 2*f; + voffset = 5*f; + defstride = 8*f; + break; + case GL_T2F_N3F_V3F: + tflag = GL_TRUE; cflag = GL_FALSE; nflag = GL_TRUE; + tcomps = 2; ccomps = 0; vcomps = 3; + noffset = 2*f; + voffset = 5*f; + defstride = 8*f; + break; + case GL_T2F_C4F_N3F_V3F: + tflag = GL_TRUE; cflag = GL_TRUE; nflag = GL_TRUE; + tcomps = 2; ccomps = 4; vcomps = 3; + ctype = GL_FLOAT; + coffset = 2*f; + noffset = 6*f; + voffset = 9*f; + defstride = 12*f; + break; + case GL_T4F_C4F_N3F_V4F: + tflag = GL_TRUE; cflag = GL_TRUE; nflag = GL_TRUE; + tcomps = 4; ccomps = 4; vcomps = 4; + ctype = GL_FLOAT; + coffset = 4*f; + noffset = 8*f; + voffset = 11*f; + defstride = 15*f; + break; + default: + _mesa_error( ctx, GL_INVALID_ENUM, "glInterleavedArrays(format)" ); + return; + } + + if (stride==0) { + stride = defstride; + } + + _mesa_DisableClientState( GL_EDGE_FLAG_ARRAY ); + _mesa_DisableClientState( GL_INDEX_ARRAY ); + + /* Texcoords */ + coordUnitSave = ctx->Array.ActiveTexture; + if (tflag) { + GLint i; + GLint factor = ctx->Array.TexCoordInterleaveFactor; + for (i = 0; i < factor; i++) { + _mesa_ClientActiveTextureARB( (GLenum) (GL_TEXTURE0_ARB + i) ); + _mesa_EnableClientState( GL_TEXTURE_COORD_ARRAY ); + _mesa_TexCoordPointer( tcomps, GL_FLOAT, stride, + (GLubyte *) pointer + i * coffset ); + } + for (i = factor; i < (GLint) ctx->Const.MaxTextureUnits; i++) { + _mesa_ClientActiveTextureARB( (GLenum) (GL_TEXTURE0_ARB + i) ); + _mesa_DisableClientState( GL_TEXTURE_COORD_ARRAY ); + } + } + else { + GLint i; + for (i = 0; i < (GLint) ctx->Const.MaxTextureUnits; i++) { + _mesa_ClientActiveTextureARB( (GLenum) (GL_TEXTURE0_ARB + i) ); + _mesa_DisableClientState( GL_TEXTURE_COORD_ARRAY ); + } + } + /* Restore texture coordinate unit index */ + _mesa_ClientActiveTextureARB( (GLenum) (GL_TEXTURE0_ARB + coordUnitSave) ); + + + /* Color */ + if (cflag) { + _mesa_EnableClientState( GL_COLOR_ARRAY ); + _mesa_ColorPointer( ccomps, ctype, stride, + (GLubyte*) pointer + coffset ); + } + else { + _mesa_DisableClientState( GL_COLOR_ARRAY ); + } + + + /* Normals */ + if (nflag) { + _mesa_EnableClientState( GL_NORMAL_ARRAY ); + _mesa_NormalPointer( GL_FLOAT, stride, + (GLubyte*) pointer + noffset ); + } + else { + _mesa_DisableClientState( GL_NORMAL_ARRAY ); + } + + _mesa_EnableClientState( GL_VERTEX_ARRAY ); + _mesa_VertexPointer( vcomps, GL_FLOAT, stride, + (GLubyte *) pointer + voffset ); +} + + + +void +_mesa_LockArraysEXT(GLint first, GLsizei count) +{ + GET_CURRENT_CONTEXT(ctx); + ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx); + + if (MESA_VERBOSE & VERBOSE_API) + fprintf(stderr, "glLockArrays %d %d\n", first, count); + + if (first == 0 && count > 0 && + count <= (GLint) ctx->Const.MaxArrayLockSize) { + ctx->Array.LockFirst = first; + ctx->Array.LockCount = count; + } + else { + ctx->Array.LockFirst = 0; + ctx->Array.LockCount = 0; + } + + ctx->NewState |= _NEW_ARRAY; + ctx->Array.NewState |= _NEW_ARRAY_ALL; + + if (ctx->Driver.LockArraysEXT) + ctx->Driver.LockArraysEXT( ctx, first, count ); +} + + +void +_mesa_UnlockArraysEXT( void ) +{ + GET_CURRENT_CONTEXT(ctx); + ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx); + + if (MESA_VERBOSE & VERBOSE_API) + fprintf(stderr, "glUnlockArrays\n"); + + ctx->Array.LockFirst = 0; + ctx->Array.LockCount = 0; + ctx->NewState |= _NEW_ARRAY; + ctx->Array.NewState |= _NEW_ARRAY_ALL; + + if (ctx->Driver.UnlockArraysEXT) + ctx->Driver.UnlockArraysEXT( ctx ); +} Index: dll/opengl/opengl32/mesa/varray.h =================================================================== --- dll/opengl/opengl32/mesa/varray.h (revision 0) +++ dll/opengl/opengl32/mesa/varray.h (working copy) @@ -0,0 +1,109 @@ +/* $Id: varray.h,v 1.12 2001/03/12 00:48:39 gareth Exp $ */ + +/* + * Mesa 3-D graphics library + * Version: 3.5 + * + * Copyright (C) 1999-2001 Brian Paul 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 + * BRIAN PAUL 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. + */ + + +#ifndef VARRAY_H +#define VARRAY_H + + +#include "mtypes.h" + + +extern void +_mesa_VertexPointer(GLint size, GLenum type, GLsizei stride, + const GLvoid *ptr); + +extern void +_mesa_UnlockArraysEXT( void ); + +extern void +_mesa_LockArraysEXT(GLint first, GLsizei count); + + +extern void +_mesa_NormalPointer(GLenum type, GLsizei stride, const GLvoid *ptr); + + +extern void +_mesa_ColorPointer(GLint size, GLenum type, GLsizei stride, const GLvoid *ptr); + + +extern void +_mesa_IndexPointer(GLenum type, GLsizei stride, const GLvoid *ptr); + + +extern void +_mesa_TexCoordPointer(GLint size, GLenum type, GLsizei stride, + const GLvoid *ptr); + + +extern void +_mesa_EdgeFlagPointer(GLsizei stride, const GLvoid *ptr); + + +extern void +_mesa_VertexPointerEXT(GLint size, GLenum type, GLsizei stride, + GLsizei count, const GLvoid *ptr); + + +extern void +_mesa_NormalPointerEXT(GLenum type, GLsizei stride, GLsizei count, + const GLvoid *ptr); + + +extern void +_mesa_ColorPointerEXT(GLint size, GLenum type, GLsizei stride, GLsizei count, + const GLvoid *ptr); + + +extern void +_mesa_IndexPointerEXT(GLenum type, GLsizei stride, GLsizei count, + const GLvoid *ptr); + + +extern void +_mesa_TexCoordPointerEXT(GLint size, GLenum type, GLsizei stride, + GLsizei count, const GLvoid *ptr); + + +extern void +_mesa_EdgeFlagPointerEXT(GLsizei stride, GLsizei count, const GLboolean *ptr); + + +extern void +_mesa_FogCoordPointerEXT(GLenum type, GLsizei stride, const GLvoid *ptr); + +extern void +_mesa_SecondaryColorPointerEXT(GLint size, GLenum type, + GLsizei stride, const GLvoid *ptr); + + +extern void +_mesa_InterleavedArrays(GLenum format, GLsizei stride, const GLvoid *pointer); + + + +#endif Index: dll/opengl/opengl32/mesa/vtxfmt.c =================================================================== --- dll/opengl/opengl32/mesa/vtxfmt.c (revision 0) +++ dll/opengl/opengl32/mesa/vtxfmt.c (working copy) @@ -0,0 +1,187 @@ +/* $Id: vtxfmt.c,v 1.6 2001/03/12 01:06:44 gareth Exp $ */ + +/* + * Mesa 3-D graphics library + * Version: 3.5 + * + * Copyright (C) 1999-2001 Brian Paul 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 + * BRIAN PAUL 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. + * + * Authors: + * Keith Whitwell + * Gareth Hughes + */ + +#include "glheader.h" +#include "api_loopback.h" +#include "context.h" +#include "mtypes.h" +#include "state.h" +#include "vtxfmt.h" + + +/* The neutral vertex format. This wraps all tnl module functions, + * verifying that the currently-installed module is valid and then + * installing the function pointers in a lazy fashion. It records the + * function pointers that have been swapped out, which allows a fast + * restoration of the neutral module in almost all cases -- a typical + * app might only require 4-6 functions to be modified from the neutral + * baseline, and only restoring these is certainly preferable to doing + * the entire module's 60 or so function pointers. + */ + +#define PRE_LOOPBACK( FUNC ) \ +{ \ + GET_CURRENT_CONTEXT(ctx); \ + struct gl_tnl_module *tnl = &(ctx->TnlModule); \ + const GLuint new_state = ctx->NewState; \ + \ + if ( new_state ) \ + _mesa_update_state( ctx ); \ + \ + /* Validate the current tnl module. \ + */ \ + if ( new_state & ctx->Driver.NeedValidate ) \ + ctx->Driver.ValidateTnlModule( ctx, new_state ); \ + \ + ASSERT( tnl->Current ); \ + ASSERT( tnl->SwapCount < NUM_VERTEX_FORMAT_ENTRIES ); \ + \ + /* Save the swapped function's dispatch entry so it can be \ + * restored later. \ + */ \ + tnl->Swapped[tnl->SwapCount][0] = (void *)&(ctx->Exec->FUNC); \ + tnl->Swapped[tnl->SwapCount][1] = (void *)TAG(FUNC); \ + tnl->SwapCount++; \ + \ + if ( 0 ) \ + fprintf( stderr, " swapping gl" #FUNC"...\n" ); \ + \ + /* Install the tnl function pointer. \ + */ \ + ctx->Exec->FUNC = tnl->Current->FUNC; \ +} + +#define TAG(x) neutral_##x +#include "vtxfmt_tmp.h" + + + +static void install_vtxfmt( struct _glapi_table *tab, GLvertexformat *vfmt ) +{ + tab->ArrayElement = vfmt->ArrayElement; + tab->Color3f = vfmt->Color3f; + tab->Color3fv = vfmt->Color3fv; + tab->Color3ub = vfmt->Color3ub; + tab->Color3ubv = vfmt->Color3ubv; + tab->Color4f = vfmt->Color4f; + tab->Color4fv = vfmt->Color4fv; + tab->Color4ub = vfmt->Color4ub; + tab->Color4ubv = vfmt->Color4ubv; + tab->EdgeFlag = vfmt->EdgeFlag; + tab->EdgeFlagv = vfmt->EdgeFlagv; + tab->EvalCoord1f = vfmt->EvalCoord1f; + tab->EvalCoord1fv = vfmt->EvalCoord1fv; + tab->EvalCoord2f = vfmt->EvalCoord2f; + tab->EvalCoord2fv = vfmt->EvalCoord2fv; + tab->EvalPoint1 = vfmt->EvalPoint1; + tab->EvalPoint2 = vfmt->EvalPoint2; + tab->FogCoordfEXT = vfmt->FogCoordfEXT; + tab->FogCoordfvEXT = vfmt->FogCoordfvEXT; + tab->Indexi = vfmt->Indexi; + tab->Indexiv = vfmt->Indexiv; + tab->Materialfv = vfmt->Materialfv; + tab->MultiTexCoord1fARB = vfmt->MultiTexCoord1fARB; + tab->MultiTexCoord1fvARB = vfmt->MultiTexCoord1fvARB; + tab->MultiTexCoord2fARB = vfmt->MultiTexCoord2fARB; + tab->MultiTexCoord2fvARB = vfmt->MultiTexCoord2fvARB; + tab->MultiTexCoord3fARB = vfmt->MultiTexCoord3fARB; + tab->MultiTexCoord3fvARB = vfmt->MultiTexCoord3fvARB; + tab->MultiTexCoord4fARB = vfmt->MultiTexCoord4fARB; + tab->MultiTexCoord4fvARB = vfmt->MultiTexCoord4fvARB; + tab->Normal3f = vfmt->Normal3f; + tab->Normal3fv = vfmt->Normal3fv; + tab->SecondaryColor3fEXT = vfmt->SecondaryColor3fEXT; + tab->SecondaryColor3fvEXT = vfmt->SecondaryColor3fvEXT; + tab->SecondaryColor3ubEXT = vfmt->SecondaryColor3ubEXT; + tab->SecondaryColor3ubvEXT = vfmt->SecondaryColor3ubvEXT; + tab->TexCoord1f = vfmt->TexCoord1f; + tab->TexCoord1fv = vfmt->TexCoord1fv; + tab->TexCoord2f = vfmt->TexCoord2f; + tab->TexCoord2fv = vfmt->TexCoord2fv; + tab->TexCoord3f = vfmt->TexCoord3f; + tab->TexCoord3fv = vfmt->TexCoord3fv; + tab->TexCoord4f = vfmt->TexCoord4f; + tab->TexCoord4fv = vfmt->TexCoord4fv; + tab->Vertex2f = vfmt->Vertex2f; + tab->Vertex2fv = vfmt->Vertex2fv; + tab->Vertex3f = vfmt->Vertex3f; + tab->Vertex3fv = vfmt->Vertex3fv; + tab->Vertex4f = vfmt->Vertex4f; + tab->Vertex4fv = vfmt->Vertex4fv; + tab->Begin = vfmt->Begin; + tab->End = vfmt->End; + +/* tab->NewList = vfmt->NewList; */ + tab->CallList = vfmt->CallList; + + tab->Rectf = vfmt->Rectf; + tab->DrawArrays = vfmt->DrawArrays; + tab->DrawElements = vfmt->DrawElements; + tab->DrawRangeElements = vfmt->DrawRangeElements; + tab->EvalMesh1 = vfmt->EvalMesh1; + tab->EvalMesh2 = vfmt->EvalMesh2; +} + + +void _mesa_init_exec_vtxfmt( GLcontext *ctx ) +{ + install_vtxfmt( ctx->Exec, &neutral_vtxfmt ); +} + + +void _mesa_install_exec_vtxfmt( GLcontext *ctx, GLvertexformat *vfmt ) +{ + ctx->TnlModule.Current = vfmt; + _mesa_restore_exec_vtxfmt( ctx ); + if ( ctx->ExecPrefersFloat != vfmt->prefer_float_colors ) + _mesa_loopback_prefer_float( ctx->Exec, vfmt->prefer_float_colors ); +} + +void _mesa_install_save_vtxfmt( GLcontext *ctx, GLvertexformat *vfmt ) +{ + install_vtxfmt( ctx->Save, vfmt ); + if ( ctx->SavePrefersFloat != vfmt->prefer_float_colors ) + _mesa_loopback_prefer_float( ctx->Save, vfmt->prefer_float_colors ); +} + + +void _mesa_restore_exec_vtxfmt( GLcontext *ctx ) +{ + struct gl_tnl_module *tnl = &(ctx->TnlModule); + GLuint i; + + /* Restore the neutral tnl module wrapper. + */ + for ( i = 0 ; i < tnl->SwapCount ; i++ ) { + *(void **)tnl->Swapped[i][0] = tnl->Swapped[i][1]; + } + + tnl->SwapCount = 0; +} Index: dll/opengl/opengl32/mesa/vtxfmt.h =================================================================== --- dll/opengl/opengl32/mesa/vtxfmt.h (revision 0) +++ dll/opengl/opengl32/mesa/vtxfmt.h (working copy) @@ -0,0 +1,41 @@ +/* $Id: vtxfmt.h,v 1.4 2001/03/12 00:48:39 gareth Exp $ */ + +/* + * Mesa 3-D graphics library + * Version: 3.5 + * + * Copyright (C) 1999-2001 Brian Paul 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 + * BRIAN PAUL 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. + * + * Authors: + * Keith Whitwell + * Gareth Hughes + */ + +#ifndef _VTXFMT_H_ +#define _VTXFMT_H_ + +extern void _mesa_init_exec_vtxfmt( GLcontext *ctx ); + +extern void _mesa_install_exec_vtxfmt( GLcontext *ctx, GLvertexformat *vfmt ); +extern void _mesa_install_save_vtxfmt( GLcontext *ctx, GLvertexformat *vfmt ); + +extern void _mesa_restore_exec_vtxfmt( GLcontext *ctx ); + +#endif Index: dll/opengl/opengl32/mesa/vtxfmt_tmp.h =================================================================== --- dll/opengl/opengl32/mesa/vtxfmt_tmp.h (revision 0) +++ dll/opengl/opengl32/mesa/vtxfmt_tmp.h (working copy) @@ -0,0 +1,458 @@ +/* $Id: vtxfmt_tmp.h,v 1.4 2001/03/12 00:48:39 gareth Exp $ */ + +/* + * Mesa 3-D graphics library + * Version: 3.5 + * + * Copyright (C) 1999-2001 Brian Paul 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 + * BRIAN PAUL 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. + * + * Authors: + * Gareth Hughes + */ + +#ifndef PRE_LOOPBACK +#define PRE_LOOPBACK( FUNC ) +#endif + +static void TAG(ArrayElement)( GLint i ) +{ + PRE_LOOPBACK( ArrayElement ); + glArrayElement( i ); +} + +static void TAG(Color3f)( GLfloat a, GLfloat b, GLfloat c ) +{ + PRE_LOOPBACK( Color3f ); + glColor3f( a, b, c ); +} + +static void TAG(Color3fv)( const GLfloat *v ) +{ + PRE_LOOPBACK( Color3fv ); + glColor3fv( v ); +} + +static void TAG(Color3ub)( GLubyte a, GLubyte b, GLubyte c ) +{ + PRE_LOOPBACK( Color3ub ); + glColor3ub( a, b, c ); +} + +static void TAG(Color3ubv)( const GLubyte *v ) +{ + PRE_LOOPBACK( Color3ubv ); + glColor3ubv( v ); +} + +static void TAG(Color4f)( GLfloat a, GLfloat b, GLfloat c, GLfloat d ) +{ + PRE_LOOPBACK( Color4f ); + glColor4f( a, b, c, d ); +} + +static void TAG(Color4fv)( const GLfloat *v ) +{ + PRE_LOOPBACK( Color4fv ); + glColor4fv( v ); +} + +static void TAG(Color4ub)( GLubyte a, GLubyte b, GLubyte c, GLubyte d ) +{ + PRE_LOOPBACK( Color4ub ); + glColor4ub( a, b, c, d ); +} + +static void TAG(Color4ubv)( const GLubyte *v ) +{ + PRE_LOOPBACK( Color4ubv ); + glColor4ubv( v ); +} + +static void TAG(EdgeFlag)( GLboolean a ) +{ + PRE_LOOPBACK( EdgeFlag ); + glEdgeFlag( a ); +} + +static void TAG(EdgeFlagv)( const GLboolean *v ) +{ + PRE_LOOPBACK( EdgeFlagv ); + glEdgeFlagv( v ); +} + +static void TAG(EvalCoord1f)( GLfloat a ) +{ + PRE_LOOPBACK( EvalCoord1f ); + glEvalCoord1f( a ); +} + +static void TAG(EvalCoord1fv)( const GLfloat *v ) +{ + PRE_LOOPBACK( EvalCoord1fv ); + glEvalCoord1fv( v ); +} + +static void TAG(EvalCoord2f)( GLfloat a, GLfloat b ) +{ + PRE_LOOPBACK( EvalCoord2f ); + glEvalCoord2f( a, b ); +} + +static void TAG(EvalCoord2fv)( const GLfloat *v ) +{ + PRE_LOOPBACK( EvalCoord2fv ); + glEvalCoord2fv( v ); +} + +static void TAG(EvalPoint1)( GLint a ) +{ + PRE_LOOPBACK( EvalPoint1 ); + glEvalPoint1( a ); +} + +static void TAG(EvalPoint2)( GLint a, GLint b ) +{ + PRE_LOOPBACK( EvalPoint2 ); + glEvalPoint2( a, b ); +} + +static void TAG(FogCoordfEXT)( GLfloat a ) +{ + PRE_LOOPBACK( FogCoordfEXT ); + glFogCoordfEXT( a ); +} + +static void TAG(FogCoordfvEXT)( const GLfloat *v ) +{ + PRE_LOOPBACK( FogCoordfvEXT ); + glFogCoordfvEXT( v ); +} + +static void TAG(Indexi)( GLint a ) +{ + PRE_LOOPBACK( Indexi ); + glIndexi( a ); +} + +static void TAG(Indexiv)( const GLint *v ) +{ + PRE_LOOPBACK( Indexiv ); + glIndexiv( v ); +} + +static void TAG(Materialfv)( GLenum face, GLenum pname, const GLfloat *v ) +{ + PRE_LOOPBACK( Materialfv ); + glMaterialfv( face, pname, v ); +} + +static void TAG(MultiTexCoord1fARB)( GLenum target, GLfloat a ) +{ + PRE_LOOPBACK( MultiTexCoord1fARB ); + glMultiTexCoord1fARB( target, a ); +} + +static void TAG(MultiTexCoord1fvARB)( GLenum target, const GLfloat *tc ) +{ + PRE_LOOPBACK( MultiTexCoord1fvARB ); + glMultiTexCoord1fvARB( target, tc ); +} + +static void TAG(MultiTexCoord2fARB)( GLenum target, GLfloat a, GLfloat b ) +{ + PRE_LOOPBACK( MultiTexCoord2fARB ); + glMultiTexCoord2fARB( target, a, b ); +} + +static void TAG(MultiTexCoord2fvARB)( GLenum target, const GLfloat *tc ) +{ + PRE_LOOPBACK( MultiTexCoord2fvARB ); + glMultiTexCoord2fvARB( target, tc ); +} + +static void TAG(MultiTexCoord3fARB)( GLenum target, GLfloat a, + GLfloat b, GLfloat c ) +{ + PRE_LOOPBACK( MultiTexCoord3fARB ); + glMultiTexCoord3fARB( target, a, b, c ); +} + +static void TAG(MultiTexCoord3fvARB)( GLenum target, const GLfloat *tc ) +{ + PRE_LOOPBACK( MultiTexCoord3fvARB ); + glMultiTexCoord3fvARB( target, tc ); +} + +static void TAG(MultiTexCoord4fARB)( GLenum target, GLfloat a, + GLfloat b, GLfloat c, GLfloat d ) +{ + PRE_LOOPBACK( MultiTexCoord4fARB ); + glMultiTexCoord4fARB( target, a, b, c, d ); +} + +static void TAG(MultiTexCoord4fvARB)( GLenum target, const GLfloat *tc ) +{ + PRE_LOOPBACK( MultiTexCoord4fvARB ); + glMultiTexCoord4fvARB( target, tc ); +} + +static void TAG(Normal3f)( GLfloat a, GLfloat b, GLfloat c ) +{ + PRE_LOOPBACK( Normal3f ); + glNormal3f( a, b, c ); +} + +static void TAG(Normal3fv)( const GLfloat *v ) +{ + PRE_LOOPBACK( Normal3fv ); + glNormal3fv( v ); +} + +static void TAG(SecondaryColor3fEXT)( GLfloat a, GLfloat b, GLfloat c ) +{ + PRE_LOOPBACK( SecondaryColor3fEXT ); + glSecondaryColor3fEXT( a, b, c ); +} + +static void TAG(SecondaryColor3fvEXT)( const GLfloat *v ) +{ + PRE_LOOPBACK( SecondaryColor3fvEXT ); + glSecondaryColor3fvEXT( v ); +} + +static void TAG(SecondaryColor3ubEXT)( GLubyte a, GLubyte b, GLubyte c ) +{ + PRE_LOOPBACK( SecondaryColor3ubEXT ); + glSecondaryColor3ubEXT( a, b, c ); +} + +static void TAG(SecondaryColor3ubvEXT)( const GLubyte *v ) +{ + PRE_LOOPBACK( SecondaryColor3ubvEXT ); + glSecondaryColor3ubvEXT( v ); +} + +static void TAG(TexCoord1f)( GLfloat a ) +{ + PRE_LOOPBACK( TexCoord1f ); + glTexCoord1f( a ); +} + +static void TAG(TexCoord1fv)( const GLfloat *tc ) +{ + PRE_LOOPBACK( TexCoord1fv ); + glTexCoord1fv( tc ); +} + +static void TAG(TexCoord2f)( GLfloat a, GLfloat b ) +{ + PRE_LOOPBACK( TexCoord2f ); + glTexCoord2f( a, b ); +} + +static void TAG(TexCoord2fv)( const GLfloat *tc ) +{ + PRE_LOOPBACK( TexCoord2fv ); + glTexCoord2fv( tc ); +} + +static void TAG(TexCoord3f)( GLfloat a, GLfloat b, GLfloat c ) +{ + PRE_LOOPBACK( TexCoord3f ); + glTexCoord3f( a, b, c ); +} + +static void TAG(TexCoord3fv)( const GLfloat *tc ) +{ + PRE_LOOPBACK( TexCoord3fv ); + glTexCoord3fv( tc ); +} + +static void TAG(TexCoord4f)( GLfloat a, GLfloat b, GLfloat c, GLfloat d ) +{ + PRE_LOOPBACK( TexCoord4f ); + glTexCoord4f( a, b, c, d ); +} + +static void TAG(TexCoord4fv)( const GLfloat *tc ) +{ + PRE_LOOPBACK( TexCoord4fv ); + glTexCoord4fv( tc ); +} + +static void TAG(Vertex2f)( GLfloat a, GLfloat b ) +{ + PRE_LOOPBACK( Vertex2f ); + glVertex2f( a, b ); +} + +static void TAG(Vertex2fv)( const GLfloat *obj ) +{ + PRE_LOOPBACK( Vertex2fv ); + glVertex2fv( obj ); +} + +static void TAG(Vertex3f)( GLfloat a, GLfloat b, GLfloat c ) +{ + PRE_LOOPBACK( Vertex3f ); + glVertex3f( a, b, c ); +} + +static void TAG(Vertex3fv)( const GLfloat *obj ) +{ + PRE_LOOPBACK( Vertex3fv ); + glVertex3fv( obj ); +} + +static void TAG(Vertex4f)( GLfloat a, GLfloat b, GLfloat c, GLfloat d ) +{ + PRE_LOOPBACK( Vertex4f ); + glVertex4f( a, b, c, d ); +} + +static void TAG(Vertex4fv)( const GLfloat *obj ) +{ + PRE_LOOPBACK( Vertex4fv ); + glVertex4fv( obj ); +} + +static void TAG(CallList)( GLuint i ) +{ + PRE_LOOPBACK( CallList ); + glCallList( i ); +} + +static void TAG(Begin)( GLenum mode ) +{ + PRE_LOOPBACK( Begin ); + glBegin( mode ); +} + +static void TAG(End)( void ) +{ + PRE_LOOPBACK( End ); + glEnd(); +} + +static void TAG(Rectf)( GLfloat x1, GLfloat y1, GLfloat x2, GLfloat y2 ) +{ + PRE_LOOPBACK( Rectf ); + glRectf( x1, y1, x2, y2 ); +} + +static void TAG(DrawArrays)( GLenum mode, GLint start, GLsizei count ) +{ + PRE_LOOPBACK( DrawArrays ); + glDrawArrays( mode, start, count ); +} + +static void TAG(DrawElements)( GLenum mode, GLsizei count, GLenum type, + const void *indices ) +{ + PRE_LOOPBACK( DrawElements ); + glDrawElements( mode, count, type, indices ); +} + +static void TAG(DrawRangeElements)( GLenum mode, GLuint start, + GLuint end, GLsizei count, + GLenum type, const void *indices ) +{ + PRE_LOOPBACK( DrawRangeElements ); + glDrawRangeElements( mode, start, end, count, type, indices ); +} + +static void TAG(EvalMesh1)( GLenum mode, GLint i1, GLint i2 ) +{ + PRE_LOOPBACK( EvalMesh1 ); + glEvalMesh1( mode, i1, i2 ); +} + +static void TAG(EvalMesh2)( GLenum mode, GLint i1, GLint i2, + GLint j1, GLint j2 ) +{ + PRE_LOOPBACK( EvalMesh2 ); + glEvalMesh2( mode, i1, i2, j1, j2 ); +} + + +static GLvertexformat TAG(vtxfmt) = { + TAG(ArrayElement), + TAG(Color3f), + TAG(Color3fv), + TAG(Color3ub), + TAG(Color3ubv), + TAG(Color4f), + TAG(Color4fv), + TAG(Color4ub), + TAG(Color4ubv), + TAG(EdgeFlag), + TAG(EdgeFlagv), + TAG(EvalCoord1f), + TAG(EvalCoord1fv), + TAG(EvalCoord2f), + TAG(EvalCoord2fv), + TAG(EvalPoint1), + TAG(EvalPoint2), + TAG(FogCoordfEXT), + TAG(FogCoordfvEXT), + TAG(Indexi), + TAG(Indexiv), + TAG(Materialfv), + TAG(MultiTexCoord1fARB), + TAG(MultiTexCoord1fvARB), + TAG(MultiTexCoord2fARB), + TAG(MultiTexCoord2fvARB), + TAG(MultiTexCoord3fARB), + TAG(MultiTexCoord3fvARB), + TAG(MultiTexCoord4fARB), + TAG(MultiTexCoord4fvARB), + TAG(Normal3f), + TAG(Normal3fv), + TAG(SecondaryColor3fEXT), + TAG(SecondaryColor3fvEXT), + TAG(SecondaryColor3ubEXT), + TAG(SecondaryColor3ubvEXT), + TAG(TexCoord1f), + TAG(TexCoord1fv), + TAG(TexCoord2f), + TAG(TexCoord2fv), + TAG(TexCoord3f), + TAG(TexCoord3fv), + TAG(TexCoord4f), + TAG(TexCoord4fv), + TAG(Vertex2f), + TAG(Vertex2fv), + TAG(Vertex3f), + TAG(Vertex3fv), + TAG(Vertex4f), + TAG(Vertex4fv), + TAG(CallList), + TAG(Begin), + TAG(End), + TAG(Rectf), + TAG(DrawArrays), + TAG(DrawElements), + TAG(DrawRangeElements), + TAG(EvalMesh1), + TAG(EvalMesh2), +}; + +#undef TAG +#undef PRE_LOOPBACK Index: dll/opengl/opengl32/opengl32.h =================================================================== --- dll/opengl/opengl32/opengl32.h (revision 58564) +++ dll/opengl/opengl32/opengl32.h (working copy) @@ -135,7 +135,7 @@ BOOL (WINAPI *DrvRealizeLayerPalette)( HDC, int, BOOL ); PICDTable (WINAPI *DrvSetContext)( HDC hdc, HGLRC hglrc, SetContextCallBack callback ); int (WINAPI *DrvSetLayerPaletteEntries)( HDC, int, int, int, CONST COLORREF * ); - BOOL (WINAPI *DrvSetPixelFormat)( IN HDC, IN int, const PIXELFORMATDESCRIPTOR * ); + BOOL (WINAPI *DrvSetPixelFormat)( IN HDC, IN int); BOOL (WINAPI *DrvShareLists)( HGLRC, HGLRC ); BOOL (WINAPI *DrvSwapBuffers)( HDC ); BOOL (WINAPI *DrvSwapLayerBuffers)( HDC, UINT ); @@ -144,6 +144,8 @@ struct tagGLDRIVERDATA *next; /* next ICD -- linked list */ } GLDRIVERDATA; +extern GLDRIVERDATA ICD_software; + /* Our private OpenGL context (stored in TLS) */ typedef struct tagGLRC { @@ -185,14 +187,6 @@ GLDRIVERDATA *OPENGL32_LoadICD( LPCWSTR driver ); BOOL OPENGL32_UnloadICD( GLDRIVERDATA *icd ); BOOL APIENTRY rosglMakeCurrent( HDC hdc, HGLRC hglrc ); -BOOL APIENTRY IntUseFontBitmapsA( HDC hDC, DWORD first, DWORD count, DWORD listBase ); -BOOL APIENTRY IntUseFontBitmapsW( HDC hDC, DWORD first, DWORD count, DWORD listBase ); -BOOL APIENTRY IntUseFontOutlinesA( HDC hDC, DWORD first, DWORD count, DWORD listBase, - FLOAT chordalDeviation, FLOAT extrusion, INT format, - GLYPHMETRICSFLOAT *glyphMetricsFloatArray ); -BOOL APIENTRY IntUseFontOutlinesW( HDC hDC, DWORD first, DWORD count, DWORD listBase, - FLOAT chordalDeviation, FLOAT extrusion, INT format, - GLYPHMETRICSFLOAT *glyphMetricsFloatArray ); /* empty gl functions from gl.c */ int WINAPI glEmptyFunc0( void ); @@ -225,6 +219,19 @@ #endif /* OPENGL32_GL_FUNC_PROTOTYPES */ +FORCEINLINE GLRC* oglGetCurrentContext() +{ + return (GLRC*)NtCurrentTeb()->glCurrentRC; +} + +FORCEINLINE HGLRC oglGetCurrentContextICD() +{ + GLRC* glrc = oglGetCurrentContext(); + if(!glrc) + return NULL; + return glrc->hglrc; +} + #ifdef __cplusplus }; /* extern "C" */ #endif /* __cplusplus */ Index: dll/opengl/opengl32/opengl32.spec =================================================================== --- dll/opengl/opengl32/opengl32.spec (revision 58564) +++ dll/opengl/opengl32/opengl32.spec (working copy) @@ -363,7 +363,7 @@ @ stdcall wglSwapBuffers(long) rosglSwapBuffers @ stdcall wglSwapLayerBuffers(long long) rosglSwapLayerBuffers @ stub wglSwapMultipleBuffers -@ stdcall wglUseFontBitmapsA(long long long long) rosglUseFontBitmapsA -@ stdcall wglUseFontBitmapsW(long long long long) rosglUseFontBitmapsW -@ stdcall wglUseFontOutlinesA(long long long long long long long ptr) rosglUseFontOutlinesA -@ stdcall wglUseFontOutlinesW(long long long long long long long ptr) rosglUseFontOutlinesW +@ stdcall wglUseFontBitmapsA(long long long long) +@ stdcall wglUseFontBitmapsW(long long long long) +@ stdcall wglUseFontOutlinesA(long long long long long long long ptr) +@ stdcall wglUseFontOutlinesW(long long long long long long long ptr) Index: dll/opengl/opengl32/sw_mesa.c =================================================================== --- dll/opengl/opengl32/sw_mesa.c (revision 0) +++ dll/opengl/opengl32/sw_mesa.c (working copy) @@ -0,0 +1,1851 @@ +/* +* COPYRIGHT: See COPYING in the top level directory +* PROJECT: ReactOS +* FILE: dll/opengl32/sw_mesa.c +* PURPOSE: OpenGL32 lib, software implementation +*/ + +#include "sw_mesa.h" + +#include "wine/debug.h" +WINE_DEFAULT_DEBUG_CHANNEL(wgl); + +#define SW_NEW_LINE (_NEW_LINE | \ + _NEW_TEXTURE | \ + _NEW_LIGHT | \ + _NEW_DEPTH | \ + _NEW_RENDERMODE | \ + _SWRAST_NEW_RASTERMASK) + +static void WINAPI mglUnused(void) { } +extern void GLAPIENTRY mglSamplePassARB(GLenum pass); + +#define NO_FUNCTIONS +#define DISPATCH_TABLE_NAME mgl_dispatch_table +#define TABLE_ENTRY(x) mgl ## x +#include "glapitemp.h" + +static SW_DC_Data* dcDataList = NULL; + +static SW_DC_Data* get_dc_data(HDC hdc) +{ + SW_DC_Data* data; + HANDLE hUnique = WindowFromDC(hdc); + if(!hUnique) + hUnique = hdc; + /* Run through the list and find it */ + for(data = dcDataList; data != NULL; data = data->next) + { + if(data->hUnique == hUnique) + return data; + } + + return NULL; +} + +static void get_pixelformat(HDC hdc, int format, LPPIXELFORMATDESCRIPTOR pfd); +static void sw_register_swrast_functions( GLcontext *ctx ); + +BOOL WINAPI swCopyContext(HGLRC hglrcSrc, HGLRC hglrcDst, UINT mask) +{ + SW_Context* ctx_src = (SW_Context*)hglrcSrc; + SW_Context* ctx_dst= (SW_Context*)hglrcDst; + _mesa_copy_context(ctx_src->gl_context, ctx_dst->gl_context, mask); + return TRUE; +} + +HGLRC WINAPI swCreateLayerContext(HDC hdc, int layer) +{ + /* Unsupported */ + UNREFERENCED_PARAMETER(hdc); + UNREFERENCED_PARAMETER(layer); + + return NULL; +} + +HGLRC WINAPI swCreateContext(HDC hdc) +{ + PIXELFORMATDESCRIPTOR pfd; + SW_Context* ctx; + SW_DC_Data* dcData = get_dc_data(hdc); + if(!dcData) + return NULL; + ctx = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, FIELD_OFFSET(SW_Context, bmi.bmiColors[3])); + if(!ctx) + return NULL; + get_pixelformat(hdc, dcData->pixelformat, &pfd); + /* Create the mesa objects */ + ctx->gl_visual = _mesa_create_visual( + pfd.iPixelType == PFD_TYPE_RGBA, + !!(pfd.dwFlags & PFD_DOUBLEBUFFER), + GL_FALSE, + pfd.cRedBits, + pfd.cGreenBits, + pfd.cBlueBits, + pfd.cAlphaBits, + (pfd.iPixelType == PFD_TYPE_COLORINDEX) ? pfd.cColorBits : 0, + pfd.cDepthBits, + pfd.cStencilBits, + pfd.cAccumRedBits, + pfd.cAccumGreenBits, + pfd.cAccumBlueBits, + pfd.cAccumAlphaBits, + 0); + if(ctx->gl_visual == NULL) + { + HeapFree(GetProcessHeap(), 0, ctx); + return NULL; + } + ctx->gl_framebuffer = _mesa_create_framebuffer( + ctx->gl_visual, + pfd.cDepthBits != 0, + pfd.cStencilBits != 0, + pfd.cAccumBits != 0, + pfd.cAlphaBits != 0); + if(!ctx->gl_framebuffer) + { + _mesa_destroy_visual(ctx->gl_visual); + HeapFree(GetProcessHeap(), 0, ctx); + return NULL; + } + ctx->gl_context = _mesa_create_context( + ctx->gl_visual, + NULL, + (void*)ctx, + GL_TRUE); + if(!ctx->gl_context) + { + _mesa_destroy_framebuffer(ctx->gl_framebuffer); + _mesa_destroy_visual(ctx->gl_visual); + HeapFree(GetProcessHeap(), 0, ctx); + return NULL; + } + + _mesa_enable_sw_extensions(ctx->gl_context); + + /* We will need this later*/ + ctx->pixel_type = pfd.iPixelType; + ctx->bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER); + ctx->bmi.bmiHeader.biWidth = 0; + ctx->bmi.bmiHeader.biHeight = 0; + ctx->bmi.bmiHeader.biPlanes = 1; + ctx->bmi.bmiHeader.biCompression = BI_RGB; + ctx->bmi.bmiHeader.biSizeImage = 0; + + if(ctx->pixel_type == PFD_TYPE_RGBA) + { + *((ULONG*)&ctx->bmi.bmiColors[0]) = 0xFF000000; + *((ULONG*)&ctx->bmi.bmiColors[1]) = 0x00FF0000; + *((ULONG*)&ctx->bmi.bmiColors[2]) = 0x0000FF00; + ctx->bmi.bmiHeader.biBitCount = 32; + ctx->bmi.bmiHeader.biClrUsed = 0; + ctx->bmi.bmiHeader.biClrImportant = 0; + } + else + { + int i; + WORD* indices; + ctx = HeapReAlloc(GetProcessHeap(), 0, ctx, + FIELD_OFFSET(SW_Context, bmi.bmiColors[256*sizeof(WORD)/sizeof(RGBQUAD)])); + indices = (WORD*)&ctx->bmi.bmiColors; + for(i=0; i<256; i++) + indices[i] = i; + ctx->bmi.bmiHeader.biBitCount = 8; + ctx->bmi.bmiHeader.biClrUsed = 256; + ctx->bmi.bmiHeader.biClrImportant = 256; + } + + /* Initialize implementation contexts */ + _swrast_CreateContext( ctx->gl_context ); + _ac_CreateContext( ctx->gl_context ); + _tnl_CreateContext( ctx->gl_context ); + _swsetup_CreateContext( ctx->gl_context ); + + sw_register_swrast_functions( ctx->gl_context ); + + return (HGLRC)ctx; +} + +BOOL WINAPI swDeleteContext(HGLRC hglrc) +{ + SW_Context* ctx = (SW_Context*)hglrc; + + _swsetup_DestroyContext(ctx->gl_context); + _tnl_DestroyContext( ctx->gl_context); + _ac_DestroyContext(ctx->gl_context); + _swrast_DestroyContext(ctx->gl_context); + + _mesa_destroy_framebuffer(ctx->gl_framebuffer); + _mesa_destroy_context(ctx->gl_context); + _mesa_destroy_visual(ctx->gl_visual); + HeapFree(GetProcessHeap(), 0, ctx); + return TRUE; +} + +BOOL WINAPI swDescribeLayerPlane(HDC hdc, + int iPixelFormat, + int iLayerPlane, + UINT size, + LPLAYERPLANEDESCRIPTOR plpd) +{ + /* We don't support overlays/underlays */ + UNREFERENCED_PARAMETER(hdc); + UNREFERENCED_PARAMETER(iPixelFormat); + UNREFERENCED_PARAMETER(iLayerPlane); + UNREFERENCED_PARAMETER(plpd); + return FALSE; +} + +static const struct pf_color_info +{ + BYTE colorBits; + BYTE accumBits; + struct + { + BYTE red; + BYTE green; + BYTE blue; + } bits; + struct + { + BYTE red; + BYTE green; + BYTE blue; + } shift; +} pf_colors[] = +{ + {32, 64, {8, 8, 8}, {16, 8, 0}}, + {24, 64, {8, 8, 8}, {16, 8, 0}}, + {16, 32, {5, 5, 5}, {10, 5, 0}}, + {8, 32, {3, 3, 2}, {0, 3, 6}}, + {4, 16, {1, 1, 1}, {0, 1, 2}} +}; + +static const struct pf_type_info +{ + BYTE pixel_type; + BYTE alpha_bits; + BYTE alpha_shift; +} pf_types[] = +{ + {PFD_TYPE_COLORINDEX, 0, 0}, /* color index */ + {PFD_TYPE_RGBA, 8, 0}, /* RGBA */ + {PFD_TYPE_RGBA, 0, 0} /* RGB */ +}; + +static int get_pixelformat_count(HDC hdc) +{ + int count = _countof(pf_colors) * _countof(pf_types); + /* Add the potentially double buffered formats, only for direct DCs */ + if(WindowFromDC(hdc) != NULL) + { + int i; + for(i=0; i<_countof(pf_colors); i++) + { + if(pf_colors[i].colorBits == GetDeviceCaps(hdc, BITSPIXEL)) + count += _countof(pf_types); + } + } + + return count; +} + +static void get_pixelformat(HDC hdc, int format, LPPIXELFORMATDESCRIPTOR pfd) +{ + int pf_color_index, pf_type_index; + BOOL directDC = (WindowFromDC(hdc) != NULL); + /* Things we don't support */ + pfd->cAuxBuffers = 0; + pfd->iLayerType = 0; + pfd->bReserved = 0; + pfd->dwLayerMask = 0; + pfd->dwVisibleMask = 0; + pfd->dwDamageMask = 0; + /* Things that are always the same */ + pfd->nSize = sizeof(*pfd); + pfd->nVersion = 1; + pfd->dwFlags = PFD_SUPPORT_OPENGL | PFD_GENERIC_FORMAT; + pfd->cStencilBits = 8; + + if(directDC) + { + /* The first pixel formats are for double buffering */ + if(format <= (get_pixelformat_count(hdc) - (_countof(pf_types) * _countof(pf_colors)))) + { + int i; + /* Filter out all formats with the same bit depth as the front buffer */ + for(i=0; i<_countof(pf_colors); i++) + { + if(pf_colors[i].colorBits == GetDeviceCaps(hdc, BITSPIXEL)) + { + if(format >= _countof(pf_types)) + { + format -= _countof(pf_types); + } + else + break; + } + } + format = (format - 1) * _countof(pf_colors) + i + 1; + pfd->dwFlags |= PFD_DOUBLEBUFFER; + } + else + pfd->dwFlags |= PFD_SUPPORT_GDI; + } + else + { + /* All other format can draw to bitmap */ + pfd->dwFlags |= PFD_DRAW_TO_BITMAP | PFD_SUPPORT_GDI; + } + + /* Get the indices */ + format--; + pf_color_index = format % _countof(pf_colors); + format /= _countof(pf_colors); + pf_type_index = format % _countof(pf_types); + + /* Complete our PFD */ + pfd->iPixelType = pf_types[pf_type_index].pixel_type; + pfd->cColorBits = pf_colors[pf_color_index].colorBits; + pfd->cRedBits = pf_colors[pf_color_index].bits.red; + pfd->cRedShift = pf_colors[pf_color_index].shift.red; + pfd->cGreenBits = pf_colors[pf_color_index].bits.green; + pfd->cGreenShift = pf_colors[pf_color_index].shift.green; + pfd->cBlueBits = pf_colors[pf_color_index].bits.blue; + pfd->cBlueShift = pf_colors[pf_color_index].shift.blue; + pfd->cAlphaBits = pf_types[pf_type_index].alpha_bits; + pfd->cAlphaShift = pf_types[pf_type_index].alpha_shift; + /* COLORINDEX format can't have an accumulation buffer */ + pfd->cAccumBits = (pfd->iPixelType == PFD_TYPE_RGBA) ? pf_colors[pf_color_index].accumBits : 0; + /* Give as much precision as possible to the accumulation buffer */ + switch(pfd->cAccumBits) + { + case 64: + pfd->cAccumRedBits = pfd->cAccumGreenBits = pfd->cAccumBlueBits = 16; + pfd->cAccumAlphaBits = pfd->cAlphaBits ? 16 : 0; + break; + case 32: + if(pfd->cAlphaBits) + { + pfd->cAccumRedBits = pfd->cAccumGreenBits = pfd->cAccumBlueBits + = pfd->cAccumAlphaBits = 8; + } + else + { + pfd->cAccumRedBits = pfd->cAccumGreenBits = 11; + pfd->cAccumBlueBits = 10; + pfd->cAccumAlphaBits = 0; + } + break; + case 16: + if(pfd->cAlphaBits) + { + pfd->cAccumRedBits = pfd->cAccumGreenBits = pfd->cAccumBlueBits + = pfd->cAccumAlphaBits = 4; + } + else + { + pfd->cAccumRedBits = 5; + pfd->cAccumGreenBits = 6; + pfd->cAccumBlueBits = 5; + pfd->cAccumAlphaBits = 0; + } + break; + default: + pfd->cAccumRedBits = 0; + pfd->cAccumGreenBits = 0; + pfd->cAccumBlueBits = 0; + pfd->cAccumAlphaBits = 0; + } + pfd->cDepthBits = DEFAULT_SOFTWARE_DEPTH_BITS; + if(directDC && (GetDeviceCaps(hdc, BITSPIXEL) == pfd->cColorBits)) + pfd->dwFlags |= PFD_DRAW_TO_WINDOW; +} + +int WINAPI swDescribePixelFormat(HDC hdc, int format, UINT size, LPPIXELFORMATDESCRIPTOR ppfd) +{ + int count = get_pixelformat_count(hdc); + if(ppfd == NULL) + return count; + if (format > count || size != sizeof( PIXELFORMATDESCRIPTOR )) + return 0; + + get_pixelformat(hdc, format, ppfd); + + return count; +} + +int WINAPI swGetLayerPaletteEntries(HDC hdc, + int iLayerPlane, + int iStart, + int cEntries, + COLORREF * pcr) +{ + /* Unsupported */ + UNREFERENCED_PARAMETER(hdc); + UNREFERENCED_PARAMETER(iLayerPlane); + UNREFERENCED_PARAMETER(iStart); + UNREFERENCED_PARAMETER(cEntries); + UNREFERENCED_PARAMETER(pcr); + return 0; +} + +PROC WINAPI swGetProcAddress(LPCSTR lpProcName) +{ + GLint offset = _glapi_get_proc_offset(lpProcName); + if(offset < 0) + return NULL; + /* Core 1.0/1.1 functions should return NULL */ + if(offset < 336) + return NULL; + return *((PROC*)mgl_dispatch_table + offset); +} + +void WINAPI swReleaseContext(HGLRC hglrc) +{ + SW_Context* ctx = (SW_Context*)hglrc; + _mesa_make_current(NULL, NULL); + if(ctx->backbuffer) + { + HeapFree(GetProcessHeap(), 0, ctx->backbuffer); + ctx->backbuffer = NULL; + } +} + +BOOL WINAPI swRealizeLayerPalette(HDC hdc, + int iLayerPlane, + BOOL bRealize) +{ + /* Unsupported */ + UNREFERENCED_PARAMETER(hdc); + UNREFERENCED_PARAMETER(iLayerPlane); + UNREFERENCED_PARAMETER(bRealize); + return FALSE; +} + +static const GLubyte *get_string( GLcontext *gl_context, GLenum name ) +{ + UNREFERENCED_PARAMETER(gl_context); + if(name == GL_RENDERER) + return (const GLubyte*)"ReactOS Software Renderer"; + return NULL; +} + +static void set_read_buffer( GLcontext *gl_context, GLframebuffer *buffer, GLenum mode) +{ + SW_Context* ctx = (SW_Context*)gl_context->DriverCtx; + + /* separate read buffer not supported */ + ASSERT(buffer == gl_context->DrawBuffer); + + switch(mode) + { + case GL_BACK_LEFT: + if(!ctx->backbuffer) + return; + case GL_FRONT_LEFT: + ctx->readMode = mode; + } +} + +static GLboolean set_draw_buffer( GLcontext *gl_context, GLenum mode ) +{ + SW_Context* ctx = (SW_Context*)gl_context->DriverCtx; + + switch(mode) + { + case GL_BACK_LEFT: + if(!ctx->backbuffer) + return GL_FALSE; + case GL_FRONT_LEFT: + ctx->drawMode = mode; + return GL_TRUE; + } + return GL_FALSE; +} + +static void buffer_size( GLcontext *gl_context, GLuint *width, GLuint *height ) +{ + SW_Context* ctx = (SW_Context*)gl_context->DriverCtx; + *width = ctx->width; + *height = ctx->height; +} + +C_ASSERT(sizeof(GLchan) == sizeof(BYTE)); +/* Write RGBA pixels to an RGBA (or permuted) buffer. */ +static void +write_rgba_span( + const GLcontext *gl_context, + GLuint n, + GLint x, + GLint y, + const GLchan rgba[][4], + const GLubyte mask[]) +{ + const SW_Context* ctx = (SW_Context*)gl_context->DriverCtx; + + if(ctx->drawMode == GL_FRONT_LEFT) + { + if(mask == NULL) + { + static char* buffer[sizeof(BITMAPINFOHEADER) + sizeof(RGBQUAD)*3]; + static BITMAPINFO* lpbmi = (BITMAPINFO*)buffer; + int ret; + lpbmi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER); + lpbmi->bmiHeader.biWidth = n; + lpbmi->bmiHeader.biHeight = 1; + lpbmi->bmiHeader.biPlanes = 1; + lpbmi->bmiHeader.biBitCount = 32; + lpbmi->bmiHeader.biCompression = BI_RGB; + lpbmi->bmiHeader.biSizeImage = 0; + lpbmi->bmiHeader.biClrUsed = 0; + lpbmi->bmiHeader.biClrImportant = 0; + *((ULONG*)&lpbmi->bmiColors[0]) = 0xFF000000; + *((ULONG*)&lpbmi->bmiColors[1]) = 0x00FF0000; + *((ULONG*)&lpbmi->bmiColors[2]) = 0x0000FF00; + ret = SetDIBitsToDevice(ctx->frontbuffer, x, ctx->height - y, n, 0, 0, 0, 0, 1, rgba, lpbmi, DIB_RGB_COLORS); + TRACE("SetDIBitsToDevice : ret = %i.\n", ret); + } + else + { + unsigned int i; + for(i=0; ifrontbuffer, x + i, ctx->height - y, RGB(rgba[i][RCOMP], rgba[i][GCOMP], rgba[i][BCOMP])); + } + } + } + return; + } + /* Draw to the back buffer */ + if(mask == NULL) + { + ULONG* ptr = (ULONG*)ctx->backbuffer + (y*ctx->width + x); + CopyMemory(ptr, rgba, n*sizeof(ULONG)); + } + else + { + unsigned int i; + ULONG* ptr = (ULONG*)ctx->backbuffer + (y*ctx->width + x); + for(i=0; iDriverCtx; + + if(ctx->drawMode == GL_FRONT_LEFT) + { + if(mask == NULL) + { + static char* buffer[sizeof(BITMAPINFOHEADER) + 3* sizeof(RGBQUAD)]; + static BITMAPINFO* lpbmi = (BITMAPINFO*)buffer; + int ret; + lpbmi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER); + lpbmi->bmiHeader.biWidth = n; + lpbmi->bmiHeader.biHeight = 1; + lpbmi->bmiHeader.biPlanes = 1; + lpbmi->bmiHeader.biBitCount = 24; + lpbmi->bmiHeader.biCompression = BI_RGB; + lpbmi->bmiHeader.biSizeImage = 0; + lpbmi->bmiHeader.biClrUsed = 0; + lpbmi->bmiHeader.biClrImportant = 0; + *((ULONG*)&lpbmi->bmiColors[0]) = 0x00FF0000; + *((ULONG*)&lpbmi->bmiColors[1]) = 0x0000FF00; + *((ULONG*)&lpbmi->bmiColors[2]) = 0x000000FF; + ret = SetDIBitsToDevice(ctx->frontbuffer, x, ctx->height - y, n, 0, 0, 0, 0, 1, rgb, lpbmi, DIB_RGB_COLORS); + TRACE("SetDIBitsToDevice : ret = %i.\n", ret); + } + else + { + unsigned int i; + for(i=0; ifrontbuffer, x + i, ctx->height - y, RGB(rgb[i][RCOMP], rgb[i][GCOMP], rgb[i][BCOMP])); + } + } + } + return; + } + /* Draw to the back buffer */ + { + unsigned int i; + ULONG* ptr = (ULONG*)ctx->backbuffer + (y*ctx->width + x)*4; + for(i=0; iDriverCtx; + + if(ctx->drawMode == GL_FRONT_LEFT) + { + if(mask == NULL) + { + HBRUSH brush = CreateSolidBrush(RGB(color[RCOMP], color[GCOMP], color[BCOMP])); + HBRUSH oldBrush; + if(!brush) + return; + oldBrush = SelectObject(ctx->frontbuffer, brush); + if(!oldBrush) + { + DeleteObject(brush); + return; + } + PatBlt(ctx->frontbuffer, x, ctx->height - y, n, 0, PATCOPY); + SelectObject(ctx->frontbuffer, oldBrush); + DeleteObject(brush); + } + else + { + unsigned int i; + for(i=0; ifrontbuffer, x + i, ctx->height - y, RGB(color[RCOMP], color[GCOMP], color[BCOMP])); + } + } + } + return; + } + /* Draw to the back buffer */ + if(!mask) + { + ULONG* ptr = (ULONG*)ctx->backbuffer + (y*ctx->width + x)*4; + unsigned int i; + for(i=0; ibackbuffer + (y*ctx->width + x)*4; + unsigned int i; + for(i=0; iDriverCtx; + unsigned int i; + + if(ctx->drawMode == GL_FRONT_LEFT) + { + for(i=0; ifrontbuffer, x[i], ctx->height - y[i], RGB(rgba[i][RCOMP], rgba[i][GCOMP], rgba[i][BCOMP])); + } + return; + } + /* Draw to the back buffer */ + for(i=0; ibackbuffer + y[i]*ctx->width + x[i]; + *ptr = *((ULONG*)rgba[i]); + } + } +} + +static void +write_monocolor_pixels( + const GLcontext* gl_context, + GLuint n, + const GLint x[], + const GLint y[], + CONST GLchan color[4], + const GLubyte mask[]) +{ + const SW_Context* ctx = (SW_Context*)gl_context->DriverCtx; + unsigned int i; + + if(ctx->drawMode == GL_FRONT_LEFT) + { + for(i=0; ifrontbuffer, x[i], ctx->height - y[i], RGB(color[RCOMP], color[GCOMP], color[BCOMP])); + } + return; + } + /* Draw to the back buffer */ + for(i=0; ibackbuffer + y[i]*ctx->width + x[i]; + *ptr = *((ULONG*)color); + } + } +} + +static void +read_rgba_span( + const GLcontext* gl_context, + GLuint n, + GLint x, + GLint y, + GLchan rgba[][4]) +{ + const SW_Context* ctx = (SW_Context*)gl_context->DriverCtx; + ULONG *ptr; + + if(ctx->readMode == GL_FRONT_LEFT) + { + static char* buffer[sizeof(BITMAPINFOHEADER) + 3*sizeof(RGBQUAD)]; + static BITMAPINFO* lpbmi = (BITMAPINFO*)buffer; + HBITMAP dib, oldBMP; + HDC memDC; + PVOID DIBits; + lpbmi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER); + lpbmi->bmiHeader.biWidth = n; + lpbmi->bmiHeader.biHeight = 1; + lpbmi->bmiHeader.biPlanes = 1; + lpbmi->bmiHeader.biBitCount = 32; + lpbmi->bmiHeader.biCompression = BI_RGB; + lpbmi->bmiHeader.biSizeImage = 0; + lpbmi->bmiHeader.biClrUsed = 0; + lpbmi->bmiHeader.biClrImportant = 0; + *((ULONG*)&lpbmi->bmiColors[0]) = 0xFF000000; + *((ULONG*)&lpbmi->bmiColors[1]) = 0x00FF0000; + *((ULONG*)&lpbmi->bmiColors[2]) = 0x0000FF00; + dib = CreateDIBSection(ctx->frontbuffer, lpbmi, DIB_RGB_COLORS, &DIBits, 0, 0); + if(!dib) + return; + memDC = CreateCompatibleDC(ctx->frontbuffer); + if(!memDC) + { + DeleteObject(dib); + return; + } + oldBMP = SelectObject(memDC, dib); + if(!oldBMP) + { + DeleteDC(memDC); + DeleteObject(dib); + return; + } + BitBlt(memDC, 0, 0, n, 0, ctx->frontbuffer, x, ctx->height - y, SRCCOPY); + CopyMemory(rgba, DIBits, n*4*sizeof(GLchan)); + SelectObject(memDC, oldBMP); + DeleteObject(dib); + DeleteDC(memDC); + + return; + } + /* Copy from the backbuffer */ + ptr = (ULONG*)ctx->backbuffer + y*ctx->width + x; + CopyMemory(rgba, ptr, n*4*sizeof(GLchan)); +} + +static void +read_rgba_pixels( + const GLcontext* gl_context, + GLuint n, + const GLint x[], + const GLint y[], + GLchan rgba[][4], + const GLubyte mask[]) +{ + SW_Context* ctx = (SW_Context*)gl_context->DriverCtx; + unsigned int i; + + if(ctx->readMode == GL_FRONT_LEFT) + { + COLORREF color; + for(i = 0; ifrontbuffer, x[i], ctx->height - y[i]); + rgba[i][RCOMP] = GetRValue(color); + rgba[i][GCOMP] = GetGValue(color); + rgba[i][BCOMP] = GetBValue(color);; + rgba[i][ACOMP] = 0xFF; + } + } + return; + } + /* Read from backbuffer */ + for(i=0; ibackbuffer + y[i]*ctx->width + x[i]; + *((ULONG*)rgba[i]) = *ptr; + } + } +} + +/* Write 32-bit color index to buffer */ +static void +write_index32_span( + const GLcontext *gl_context, + GLuint n, + GLint x, + GLint y, + const GLuint index[], + const GLubyte mask[] ) +{ + const SW_Context* ctx = (SW_Context*)gl_context->DriverCtx; + unsigned int i; + + if(ctx->drawMode == GL_FRONT_LEFT) + { + for(i=0; ifrontbuffer, x + i, ctx->height - y, PALETTEINDEX(index[i] & 0xFF)); + } + } + } + else + { + char* ptr = (char*)ctx->backbuffer + y*ctx->width + x; + for(i=0; iDriverCtx; + + if(ctx->drawMode == GL_FRONT_LEFT) + { + if(mask == NULL) + { + static char* buffer[sizeof(BITMAPINFOHEADER) + 256*sizeof(WORD)/sizeof(RGBQUAD)]; + static BITMAPINFO* lpbmi = (BITMAPINFO*)buffer; + static BOOL bSet = FALSE; + int ret; + if(!bSet) + { + unsigned int i; + WORD* indices = (WORD*)&lpbmi->bmiColors; + lpbmi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER); + lpbmi->bmiHeader.biHeight = 1; + lpbmi->bmiHeader.biPlanes = 1; + lpbmi->bmiHeader.biBitCount = 8; + lpbmi->bmiHeader.biCompression = BI_RGB; + lpbmi->bmiHeader.biSizeImage = 0; + lpbmi->bmiHeader.biClrUsed = 256; + lpbmi->bmiHeader.biClrImportant = 256; + for(i=0; i<256; i++) + indices[i] = i; + bSet = TRUE; + } + lpbmi->bmiHeader.biWidth = n; + ret = SetDIBitsToDevice(ctx->frontbuffer, x, ctx->height - y, n, 0, 0, 0, 0, 1, index, lpbmi, DIB_PAL_COLORS); + TRACE("SetDIBitsToDevice : ret = %i.\n", ret); + } + else + { + int i; + for(i=0; ifrontbuffer, x + i, ctx->height - y, PALETTEINDEX(index[i])); + } + } + } + return; + } + else + { + /* Draw to the backbuffer */ + char* ptr = (char*)ctx->backbuffer + y*ctx->width + x; + if(!mask) + { + CopyMemory(ptr, index, n*sizeof(GLubyte)); + } + else + { + unsigned int i; + for(i=0; iDriverCtx; + unsigned int i; + + if(ctx->drawMode == GL_FRONT_LEFT) + { + for(i=0; ifrontbuffer, x[i], ctx->height - y[i], PALETTEINDEX(index[i] & 0xFF)); + } + } + } + else + { + for(i=0; ibackbuffer + y[i]*ctx->width + x[i]; + *ptr = index[i] & 0xFF; + } + } + } +} + +static void +write_monoindex_pixels( + const GLcontext* gl_context, + GLuint n, + const GLint x[], + const GLint y[], + const GLuint index, + const GLubyte mask[]) +{ + const SW_Context* ctx = (SW_Context*)gl_context->DriverCtx; + unsigned int i; + + if(ctx->drawMode == GL_FRONT_LEFT) + { + for(i=0; ifrontbuffer, x[i], ctx->height - y[i], PALETTEINDEX(index & 0xFF)); + } + } + } + else + { + for(i=0; ibackbuffer + y[i]*ctx->width + x[i]; + *ptr = index & 0xFF; + } + } + } +} + +static void +read_index_span( + const GLcontext *gl_context, + GLuint n, + GLint x, + GLint y, + GLuint index[]) +{ + const SW_Context* ctx = (SW_Context*)gl_context->DriverCtx; + char* ptr; + unsigned int i; + + if(ctx->readMode == GL_FRONT_LEFT) + { + static char* buffer[sizeof(BITMAPINFOHEADER) + 256*sizeof(WORD)/sizeof(RGBQUAD)]; + static BITMAPINFO* lpbmi = (BITMAPINFO*)buffer; + static BOOL bSet = FALSE; + HBITMAP dib, oldBMP; + HDC memDC; + char* DIBits; + if(!bSet) + { + WORD* indices = (WORD*)&lpbmi->bmiColors; + lpbmi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER); + lpbmi->bmiHeader.biHeight = 1; + lpbmi->bmiHeader.biPlanes = 1; + lpbmi->bmiHeader.biBitCount = 8; + lpbmi->bmiHeader.biCompression = BI_RGB; + lpbmi->bmiHeader.biSizeImage = 0; + lpbmi->bmiHeader.biClrUsed = 256; + lpbmi->bmiHeader.biClrImportant = 256; + for(i=0; i<256; i++) + indices[i] = i; + bSet = TRUE; + } + lpbmi->bmiHeader.biWidth = n; + dib = CreateDIBSection(ctx->frontbuffer, lpbmi, DIB_PAL_COLORS, (void**)&DIBits, 0, 0); + if(!dib) + return; + memDC = CreateCompatibleDC(ctx->frontbuffer); + if(!memDC) + { + DeleteObject(dib); + return; + } + oldBMP = SelectObject(memDC, dib); + if(!oldBMP) + { + DeleteDC(memDC); + DeleteObject(dib); + return; + } + BitBlt(memDC, 0, 0, n, 0, ctx->frontbuffer, x, ctx->height - y, SRCCOPY); + for(i=0; ibackbuffer + y*ctx->width + x; + for(i=0; i<256; i++) + index[i] = ptr[i]; +} + +static void +read_index_pixels( + const GLcontext *gl_context, + GLuint n, + const GLint x[], + const GLint y[], + GLuint index[], + const GLubyte mask[] ) +{ + const SW_Context* ctx = (SW_Context*)gl_context->DriverCtx; + unsigned int i; + + if(ctx->readMode == GL_FRONT_LEFT) + { + HPALETTE palette = GetCurrentObject(ctx->frontbuffer, OBJ_PAL); + if(!palette) + return; + for(i=0; ifrontbuffer, x[i], ctx->height - y[i]); + index[i] = GetNearestPaletteIndex(palette, color & 0xFFFFFF); + } + } + return; + } + /* Read from the back buffer */ + for(i=0; ibackbuffer + ctx->width *y[i] + x[i]; + index[i] = *ptr; + } + } +} + +static void clear( + GLcontext* gl_context, + GLbitfield mask, + GLboolean all, + GLint x, + GLint y, + GLint width, + GLint height) +{ + const SW_Context* ctx = (SW_Context*)gl_context->DriverCtx; + + if(all) + { + x = y = 0; + width = ctx->width; + height = ctx->height; + } + + if (mask & DD_FRONT_LEFT_BIT) + { + HBRUSH brush; + RECT rc= {x, y, x + width, y + height}; + + if(ctx->pixel_type == PFD_TYPE_COLORINDEX) + { + brush = CreateSolidBrush(PALETTEINDEX(gl_context->Color.ClearIndex)); + } + else + { + brush = CreateSolidBrush( + RGB(gl_context->Color.ClearColor[RCOMP], + gl_context->Color.ClearColor[GCOMP], + gl_context->Color.ClearColor[BCOMP])); + } + if(!brush) + { + ERR("Could not create the solid brush!\n"); + return; + } + FillRect(ctx->frontbuffer, &rc, brush); + DeleteObject(brush); + mask &= ~DD_FRONT_LEFT_BIT; + } + if(mask & DD_BACK_LEFT_BIT) + { + if(ctx->pixel_type == PFD_TYPE_COLORINDEX) + { + char* ptr = (char*)ctx->backbuffer + y*ctx->width + x; + if((width == ctx->width) && (x == 0)) + { + memset(ptr, gl_context->Color.ClearIndex, height * ctx->width); + } + else + { + int i; + for(i=0; iColor.ClearIndex, width); + ptr += ctx->width; + } + } + } + else + { + ULONG* ptr = (ULONG*)ctx->backbuffer + y*ctx->width + x; + int i, j; + for(i=0; iColor.ClearColor; + } + ptr += ctx->width; + } + } + mask &= ~DD_BACK_LEFT_BIT; + } + + if(mask) + _swrast_Clear(gl_context, mask, all, x, y, width, height); +} + +static void set_pixel_frontbuffer(const SW_Context* ctx, GLint x, GLint y, const GLchan color[4]) +{ + SetPixel(ctx->frontbuffer, x, y, RGB(color[RCOMP], color[GCOMP], color[BCOMP])); +} + +static void set_pixel_backbuffer(const SW_Context* ctx, GLint x, GLint y, const GLchan color[4]) +{ + ULONG* ptr = (ULONG*)ctx->backbuffer + y*ctx->width + x; + *ptr = *((ULONG*)color); +} + +/* + * Draw a flat-shaded, RGB line + */ +static void +flat_rgba_line(GLcontext *ctx, const SWvertex *vert0, const SWvertex *vert1 ) +{ + const SW_Context* sw_ctx = (SW_Context*)ctx->DriverCtx; + const GLchan *color = vert0->color; + void (*set_pixel_func)(const SW_Context*, GLint, GLint, const GLchan[4]); + + if(sw_ctx->drawMode == GL_FRONT_LEFT) + set_pixel_func = set_pixel_frontbuffer; + else + set_pixel_func = set_pixel_backbuffer; + +#define INTERP_XY 1 +#define CLIP_HACK 1 +#define PLOT(X, Y) \ +do { \ + set_pixel_func(sw_ctx, X, Y, color); \ +} while (0) + +#include "swrast/s_linetemp.h" +} + +/* + * Draw a flat-shaded, Z-less RGB line + */ +static void +flat_rgba_z_line(GLcontext *ctx, const SWvertex *vert0, const SWvertex *vert1) +{ + const SW_Context* sw_ctx = (SW_Context*)ctx->DriverCtx; + const GLchan *color = vert0->color; + void (*set_pixel_func)(const SW_Context*, GLint, GLint, const GLchan[4]); + + if(sw_ctx->drawMode == GL_FRONT_LEFT) + set_pixel_func = set_pixel_frontbuffer; + else + set_pixel_func = set_pixel_backbuffer; + +#define INTERP_XY 1 +#define INTERP_Z 1 +#define DEPTH_TYPE DEFAULT_SOFTWARE_DEPTH_TYPE +#define CLIP_HACK 1 +#define PLOT(X, Y) \ +do { \ + if (Z < *zPtr) { \ + set_pixel_func(sw_ctx, X, Y, color); \ + *zPtr = Z; \ + } \ +} while (0) + +#include "swrast/s_linetemp.h" +} + +/* + * Draw a flat-shaded, alpha-blended, RGB line + * XXX update for GLchan + */ +static void +flat_blend_rgba_line( GLcontext *ctx, + const SWvertex *vert0, const SWvertex *vert1 ) +{ + const SW_Context* sw_ctx = (SW_Context*)ctx->DriverCtx; + const GLint avalue = vert0->color[ACOMP]; + const GLint msavalue = CHAN_MAX - avalue; + const GLint rvalue = vert0->color[RCOMP]*avalue; + const GLint gvalue = vert0->color[GCOMP]*avalue; + const GLint bvalue = vert0->color[BCOMP]*avalue; + + if(sw_ctx->drawMode == GL_FRONT_LEFT) + { + /* Use default implementation for single buffered mode */ + SWcontext *swrast = SWRAST_CONTEXT(ctx); + _swrast_choose_line(ctx); + swrast->Line( ctx, vert0, vert1 ); + return; + } + + +#define INTERP_XY 1 +#define CLIP_HACK 1 +#define PLOT(X,Y) \ +do{ \ + GLchan* pixel = (GLchan*)sw_ctx->backbuffer + (Y*sw_ctx->width + X)*4; \ + *(pixel + RCOMP) = *((pixel + RCOMP))*msavalue + rvalue; \ + *(pixel + GCOMP) = *((pixel + GCOMP))*msavalue + gvalue; \ + *(pixel + BCOMP) = *((pixel + BCOMP))*msavalue + bvalue; \ +} while(0) + +#include "swrast/s_linetemp.h" +} + +/* + * Draw a flat-shaded, Z-less, alpha-blended, RGB line into an osmesa buffer. + * XXX update for GLchan + */ +static void +flat_blend_rgba_z_line( GLcontext *ctx, + const SWvertex *vert0, const SWvertex *vert1 ) +{ + const SW_Context* sw_ctx = (SW_Context*)ctx->DriverCtx; + const GLint avalue = vert0->color[ACOMP]; + const GLint msavalue = 256 - avalue; + const GLint rvalue = vert0->color[RCOMP]*avalue; + const GLint gvalue = vert0->color[GCOMP]*avalue; + const GLint bvalue = vert0->color[BCOMP]*avalue; + + if(sw_ctx->drawMode == GL_FRONT_LEFT) + { + /* Use default implementation for single buffered mode */ + SWcontext *swrast = SWRAST_CONTEXT(ctx); + _swrast_choose_line(ctx); + swrast->Line( ctx, vert0, vert1 ); + return; + } + +#define INTERP_XY 1 +#define INTERP_Z 1 +#define DEPTH_TYPE DEFAULT_SOFTWARE_DEPTH_TYPE +#define CLIP_HACK 1 +#define PLOT(X,Y) \ +do{ \ + if (Z < *zPtr) { \ + GLchan* pixel = (GLchan*)sw_ctx->backbuffer + (Y*sw_ctx->width + X)*4; \ + *(pixel + RCOMP) = *((pixel + RCOMP))*msavalue + rvalue; \ + *(pixel + GCOMP) = *((pixel + GCOMP))*msavalue + gvalue; \ + *(pixel + BCOMP) = *((pixel + BCOMP))*msavalue + bvalue; \ + } \ +} while(0) +#include "swrast/s_linetemp.h" +} + + +/* + * Draw a flat-shaded, Z-less, alpha-blended, RGB line into an osmesa buffer. + * XXX update for GLchan + */ +static void +flat_blend_rgba_z_line_write( GLcontext *ctx, + const SWvertex *vert0, const SWvertex *vert1 ) +{ + const SW_Context* sw_ctx = (SW_Context*)ctx->DriverCtx; + const GLint avalue = vert0->color[3]; + const GLint msavalue = 256 - avalue; + const GLint rvalue = vert0->color[0]*avalue; + const GLint gvalue = vert0->color[1]*avalue; + const GLint bvalue = vert0->color[2]*avalue; + + if(sw_ctx->drawMode == GL_FRONT_LEFT) + { + /* Use default implementation for single buffered mode */ + SWcontext *swrast = SWRAST_CONTEXT(ctx); + _swrast_choose_line(ctx); + swrast->Line( ctx, vert0, vert1 ); + return; + } + + +#define INTERP_XY 1 +#define INTERP_Z 1 +#define DEPTH_TYPE DEFAULT_SOFTWARE_DEPTH_TYPE +#define CLIP_HACK 1 +#define PLOT(X,Y) \ +do{ \ + if (Z < *zPtr) { \ + GLchan* pixel = (GLchan*)sw_ctx->backbuffer + (Y*sw_ctx->width + X)*4; \ + *(pixel + RCOMP) = *((pixel + RCOMP))*msavalue + rvalue; \ + *(pixel + GCOMP) = *((pixel + GCOMP))*msavalue + gvalue; \ + *(pixel + BCOMP) = *((pixel + BCOMP))*msavalue + bvalue; \ + *zPtr = Z; \ + } \ +} while(0) + +#include "swrast/s_linetemp.h" +} + +/* + * Analyze context state to see if we can provide a fast line drawing + * function, like those in lines.c. Otherwise, return NULL. + */ +static swrast_line_func +sw_choose_line_function( GLcontext *ctx ) +{ + const SWcontext *swrast = SWRAST_CONTEXT(ctx); + + if (CHAN_BITS != 8) return NULL; + if (ctx->RenderMode != GL_RENDER) return NULL; + if (ctx->Line.SmoothFlag) return NULL; + if (ctx->Texture._ReallyEnabled) return NULL; + if (ctx->Light.ShadeModel != GL_FLAT) return NULL; + if (ctx->Line.Width != 1.0F) return NULL; + if (ctx->Line.StippleFlag) return NULL; + if (ctx->Line.SmoothFlag) return NULL; + + if (swrast->_RasterMask==DEPTH_BIT + && ctx->Depth.Func==GL_LESS + && ctx->Depth.Mask==GL_TRUE + && ctx->Visual.depthBits == DEFAULT_SOFTWARE_DEPTH_BITS) { + return flat_rgba_z_line; + } + + if (swrast->_RasterMask == 0) { + return flat_rgba_line; + } + + if (swrast->_RasterMask==(DEPTH_BIT|BLEND_BIT) + && ctx->Depth.Func==GL_LESS + && ctx->Depth.Mask==GL_TRUE + && ctx->Visual.depthBits == DEFAULT_SOFTWARE_DEPTH_BITS + && ctx->Color.BlendSrcRGB==GL_SRC_ALPHA + && ctx->Color.BlendDstRGB==GL_ONE_MINUS_SRC_ALPHA + && ctx->Color.BlendSrcA==GL_SRC_ALPHA + && ctx->Color.BlendDstA==GL_ONE_MINUS_SRC_ALPHA + && ctx->Color.BlendEquation==GL_FUNC_ADD_EXT) { + return flat_blend_rgba_z_line_write; + } + + if (swrast->_RasterMask==(DEPTH_BIT|BLEND_BIT) + && ctx->Depth.Func==GL_LESS + && ctx->Depth.Mask==GL_FALSE + && ctx->Visual.depthBits == DEFAULT_SOFTWARE_DEPTH_BITS + && ctx->Color.BlendSrcRGB==GL_SRC_ALPHA + && ctx->Color.BlendDstRGB==GL_ONE_MINUS_SRC_ALPHA + && ctx->Color.BlendSrcA==GL_SRC_ALPHA + && ctx->Color.BlendDstA==GL_ONE_MINUS_SRC_ALPHA + && ctx->Color.BlendEquation==GL_FUNC_ADD_EXT) { + return flat_blend_rgba_z_line; + } + + if (swrast->_RasterMask==BLEND_BIT + && ctx->Color.BlendSrcRGB==GL_SRC_ALPHA + && ctx->Color.BlendDstRGB==GL_ONE_MINUS_SRC_ALPHA + && ctx->Color.BlendSrcA==GL_SRC_ALPHA + && ctx->Color.BlendDstA==GL_ONE_MINUS_SRC_ALPHA + && ctx->Color.BlendEquation==GL_FUNC_ADD_EXT) { + return flat_blend_rgba_line; + } + + return NULL; +} + +static void sw_choose_line( GLcontext *ctx ) +{ + SWcontext *swrast = SWRAST_CONTEXT(ctx); + + swrast->Line = sw_choose_line_function( ctx ); + if (!swrast->Line) + _swrast_choose_line( ctx ); +} + +/* Extend the software rasterizer with our line and triangle + * functions. + */ +static void sw_register_swrast_functions( GLcontext *ctx ) +{ + SWcontext *swrast = SWRAST_CONTEXT( ctx ); + + swrast->choose_line = sw_choose_line; + + swrast->invalidate_line |= SW_NEW_LINE; +} + +static void update_mesa_state(GLcontext* gl_context, GLuint new_state) +{ + struct swrast_device_driver *swdd = _swrast_GetDeviceDriverReference( gl_context ); + TNLcontext *tnl = TNL_CONTEXT(gl_context); + + /* + * XXX these function pointers could be initialized just once during + * context creation since they don't depend on any state changes. + */ + + gl_context->Driver.GetString = get_string; + gl_context->Driver.UpdateState = update_mesa_state; + gl_context->Driver.SetDrawBuffer = set_draw_buffer; + gl_context->Driver.ResizeBuffersMESA = _swrast_alloc_buffers; + gl_context->Driver.GetBufferSize = buffer_size; + + gl_context->Driver.Accum = _swrast_Accum; + gl_context->Driver.Bitmap = _swrast_Bitmap; + gl_context->Driver.Clear = clear; + gl_context->Driver.CopyPixels = _swrast_CopyPixels; + gl_context->Driver.DrawPixels = _swrast_DrawPixels; + gl_context->Driver.ReadPixels = _swrast_ReadPixels; + + gl_context->Driver.ChooseTextureFormat = _mesa_choose_tex_format; + gl_context->Driver.TexImage1D = _mesa_store_teximage1d; + gl_context->Driver.TexImage2D = _mesa_store_teximage2d; + gl_context->Driver.TexImage3D = _mesa_store_teximage3d; + gl_context->Driver.TexSubImage1D = _mesa_store_texsubimage1d; + gl_context->Driver.TexSubImage2D = _mesa_store_texsubimage2d; + gl_context->Driver.TexSubImage3D = _mesa_store_texsubimage3d; + gl_context->Driver.TestProxyTexImage = _mesa_test_proxy_teximage; + + gl_context->Driver.CopyTexImage1D = _swrast_copy_teximage1d; + gl_context->Driver.CopyTexImage2D = _swrast_copy_teximage2d; + gl_context->Driver.CopyTexSubImage1D = _swrast_copy_texsubimage1d; + gl_context->Driver.CopyTexSubImage2D = _swrast_copy_texsubimage2d; + gl_context->Driver.CopyTexSubImage3D = _swrast_copy_texsubimage3d; + gl_context->Driver.CopyColorTable = _swrast_CopyColorTable; + gl_context->Driver.CopyColorSubTable = _swrast_CopyColorSubTable; + gl_context->Driver.CopyConvolutionFilter1D = _swrast_CopyConvolutionFilter1D; + gl_context->Driver.CopyConvolutionFilter2D = _swrast_CopyConvolutionFilter2D; + + + /* RGB(A) span/pixel functions */ + swdd->WriteRGBASpan = write_rgba_span; + swdd->WriteRGBSpan = write_rgb_span; + swdd->WriteMonoRGBASpan = write_monocolor_span; + swdd->WriteRGBAPixels = write_rgba_pixels; + swdd->WriteMonoRGBAPixels = write_monocolor_pixels; + swdd->ReadRGBASpan = read_rgba_span; + swdd->ReadRGBAPixels = read_rgba_pixels; + + /* CI span/pixel functions */ + swdd->WriteCI32Span = write_index32_span; + swdd->WriteCI8Span = write_index8_span; + swdd->WriteMonoCISpan = write_monoindex_span; + swdd->WriteCI32Pixels = write_index_pixels; + swdd->WriteMonoCIPixels = write_monoindex_pixels; + swdd->ReadCI32Span = read_index_span; + swdd->ReadCI32Pixels = read_index_pixels; + + swdd->SetReadBuffer = set_read_buffer; + + tnl->Driver.RunPipeline = _tnl_run_pipeline; + tnl->Driver.RenderStart = _swsetup_RenderStart; + tnl->Driver.RenderFinish = _swsetup_RenderFinish; + tnl->Driver.BuildProjectedVertices = _swsetup_BuildProjectedVertices; + tnl->Driver.RenderPrimitive = _swsetup_RenderPrimitive; + tnl->Driver.PointsFunc = _swsetup_Points; + tnl->Driver.LineFunc = _swsetup_Line; + tnl->Driver.TriangleFunc = _swsetup_Triangle; + tnl->Driver.QuadFunc = _swsetup_Quad; + tnl->Driver.ResetLineStipple = _swrast_ResetLineStipple; + tnl->Driver.RenderInterp = _swsetup_RenderInterp; + tnl->Driver.RenderCopyPV = _swsetup_RenderCopyPV; + tnl->Driver.RenderClippedLine = _swsetup_RenderClippedLine; + tnl->Driver.RenderClippedPolygon = _swsetup_RenderClippedPolygon; + + + _swrast_InvalidateState( gl_context, new_state ); + _swsetup_InvalidateState( gl_context, new_state ); + _ac_InvalidateState( gl_context, new_state ); + _tnl_InvalidateState( gl_context, new_state ); +} + +static +LRESULT CALLBACK +sw_call_window_proc( + int nCode, + WPARAM wParam, + LPARAM lParam ) +{ + PCWPSTRUCT pParams = (PCWPSTRUCT)lParam; + + if(!NtCurrentTeb()->glReserved2) + return 0; + + if (nCode < 0) + return CallNextHookEx(NtCurrentTeb()->glReserved2, nCode, wParam, lParam); + + if (pParams->message == WM_WINDOWPOSCHANGED) + { + /* We handle WM_WINDOWPOSCHANGED instead of WM_SIZE because according to + * http://blogs.msdn.com/oldnewthing/archive/2008/01/15/7113860.aspx + * WM_SIZE is generated from WM_WINDOWPOSCHANGED by DefWindowProc so it + * can be masked out by the application. */ + LPWINDOWPOS lpWindowPos = (LPWINDOWPOS)pParams->lParam; + if((lpWindowPos->flags & SWP_SHOWWINDOW) || + !(lpWindowPos->flags & SWP_NOMOVE) || + !(lpWindowPos->flags & SWP_NOSIZE)) + { + /* We must update the context data if the current context is for this window */ + SW_Context* ctx = (SW_Context*)oglGetCurrentContextICD(); + if(ctx && (pParams->hwnd == WindowFromDC(ctx->frontbuffer))) + { + RECT rc; + GetClientRect(pParams->hwnd, &rc); + ctx->width = rc.right - rc.left; + ctx->height = rc.bottom - rc.top; + ctx->bmi.bmiHeader.biWidth = ctx->width; + ctx->bmi.bmiHeader.biHeight = ctx->height; + if(ctx->backbuffer) + { + /* Re-allocate the back buffer */ + size_t size = ctx->height * ctx->width; + if(ctx->pixel_type == PFD_TYPE_RGBA) + size*= 4; + ctx->backbuffer = HeapReAlloc(GetProcessHeap(), 0, ctx->backbuffer, size); + } + } + } + } + + return CallNextHookEx(NtCurrentTeb()->glReserved2, nCode, wParam, lParam); +} + +PICDTable WINAPI swSetContext(HDC hdc, HGLRC hglrc, SetContextCallBack callback) +{ + static BOOL bSet = FALSE; + static ICDTable table; + SW_DC_Data* dcData = get_dc_data(hdc); + SW_Context* ctx = (SW_Context*)hglrc; + HWND hwnd; + + TRACE("Setting software context %p\n", ctx); + + if(!dcData) + return NULL; + if(!bSet) + { + /* Set the dispatch table up */ + table.num_funcs = _countof(mgl_dispatch_table); + CopyMemory(table.dispatch_table, mgl_dispatch_table, + min(sizeof(mgl_dispatch_table), sizeof(table.dispatch_table))); + bSet = TRUE; + } + if(!NtCurrentTeb()->glReserved2) + { + NtCurrentTeb()->glReserved2 = SetWindowsHookEx(WH_CALLWNDPROC, + sw_call_window_proc, + NULL, + GetCurrentThreadId()); + if(!NtCurrentTeb()->glReserved2) + return NULL; + } + hwnd = WindowFromDC(hdc); + if(hwnd) + { + RECT rc; + GetClientRect(hwnd, &rc); + ctx->width = rc.right - rc.left; + ctx->height = rc.bottom - rc.top; + } + else + { + HBITMAP bmp; + BITMAP bm; + bmp = GetCurrentObject(hdc, OBJ_BITMAP); + if(!bmp) + return NULL; + if(!GetObject(bmp, sizeof(bm), &bm)) + return NULL; + ctx->width = bm.bmWidth; + ctx->height = bm.bmHeight; + } + + ctx->bmi.bmiHeader.biWidth = ctx->width; + ctx->bmi.bmiHeader.biHeight = -ctx->height; + ctx->frontbuffer = hdc; + if (ctx->gl_visual->doubleBufferMode) + { + ERR("DOUBLE BUFFERED!\n"); + size_t size = ctx->width * ctx->height; + /* We use only 8 bits for color index mode, 32 for RGBA */ + if(ctx->gl_visual->rgbMode) + size *= 4; + ctx->backbuffer = HeapAlloc(GetProcessHeap(), 0, size); + if(!ctx->backbuffer) + return NULL; + ctx->readMode = ctx->drawMode = GL_BACK_LEFT; + } + else + { + ERR("SINGLE BUFFERED!\n"); + ctx->readMode = ctx->drawMode = GL_FRONT_LEFT; + } + + update_mesa_state(ctx->gl_context, 0); + _mesa_make_current(ctx->gl_context, ctx->gl_framebuffer); + /* init viewport */ + if (ctx->gl_context->Viewport.Width==0) { + /* initialize viewport and scissor box to buffer size */ + _mesa_Viewport( 0, 0, ctx->width, ctx->height ); + ctx->gl_context->Scissor.Width = ctx->width; + ctx->gl_context->Scissor.Height = ctx->height; + } + return &table; +} + +int WINAPI swSetLayerPaletteEntries(HDC hdc, + int iLayerPlane, + int iStart, + int cEntries, + const COLORREF* pcr) +{ + /* Unsupported */ + UNREFERENCED_PARAMETER(hdc); + UNREFERENCED_PARAMETER(iLayerPlane); + UNREFERENCED_PARAMETER(iStart); + UNREFERENCED_PARAMETER(cEntries); + UNREFERENCED_PARAMETER(pcr); + return 0; +} + +BOOL WINAPI swSetPixelFormat(HDC hdc, int format) +{ + SW_DC_Data* dcData; + + /* See if we already set it */ + dcData = get_dc_data(hdc); + if(dcData) + return FALSE; + + dcData = HeapAlloc(GetProcessHeap(), 0, sizeof(*dcData)); + if(!dcData) + return FALSE; + + /* Set data */ + dcData->hUnique = WindowFromDC(hdc); + if(!dcData->hUnique) + dcData->hUnique = hdc; + dcData->pixelformat = format; + + /* Set it as the head of the list */ + dcData->next = InterlockedExchangePointer(&dcDataList, dcData); + + return TRUE; +} + +BOOL WINAPI swShareLists(HGLRC rcsrc, HGLRC rcdst) +{ + return FALSE; +} + +BOOL WINAPI swSwapBuffers(HDC hdc) +{ + GLRC* glrc = (GLRC*)NtCurrentTeb()->glCurrentRC; + SW_Context* ctx = (SW_Context*)glrc->hglrc; + int ret; + + _mesa_swapbuffers(ctx->gl_context); + + if(!ctx->backbuffer) + return TRUE; + + ret = SetDIBitsToDevice(ctx->frontbuffer, 0, 0, ctx->width, ctx->height, + 0, 0, 0, ctx->height, ctx->backbuffer, &ctx->bmi, ctx->pixel_type == PFD_TYPE_COLORINDEX ? DIB_PAL_COLORS : DIB_RGB_COLORS); + TRACE("SetDIBitsToDevice : ret = %i\n", ret); + return ret != 0; +} + +BOOL WINAPI swSwapLayerBuffers(HDC hdc, UINT fuPlanes) +{ + if(fuPlanes == WGL_SWAP_MAIN_PLANE) + return swSwapBuffers(hdc); + return FALSE; +} + +/* Glue code for MESA thread safety */ +#define INIT_MAGIC 0xff8adc98 +void +_glthread_InitTSD(_glthread_TSD *tsd) +{ + tsd->key = TlsAlloc(); + if (tsd->key == 0xffffffff) { + exit(-1); + } + tsd->initMagic = INIT_MAGIC; +} + + +void * +_glthread_GetTSD(_glthread_TSD *tsd) +{ + if (tsd->initMagic != INIT_MAGIC) { + _glthread_InitTSD(tsd); + } + return TlsGetValue(tsd->key); +} + + +void +_glthread_SetTSD(_glthread_TSD *tsd, void *ptr) +{ + /* the following code assumes that the _glthread_TSD has been initialized + to zero at creation */ + if (tsd->initMagic != INIT_MAGIC) { + _glthread_InitTSD(tsd); + } + if (TlsSetValue(tsd->key, ptr) == 0) { + exit(-1); + } +} + +unsigned long _glthread_GetID(void) +{ + return GetCurrentThreadId(); +} + +GLDRIVERDATA ICD_software = +{ + NULL, /* DLL modeule */ + 0, + L"sw_icd", + L"opengl32.dll", + 1, + 1, + 0, + + swCopyContext, + swCreateContext, + swCreateLayerContext, + swDeleteContext, + swDescribeLayerPlane, + swDescribePixelFormat, + swGetLayerPaletteEntries, + swGetProcAddress, + swReleaseContext, + swRealizeLayerPalette, + swSetContext, + swSetLayerPaletteEntries, + swSetPixelFormat, + swShareLists, + swSwapBuffers, + swSwapLayerBuffers, + NULL, + + NULL +}; Index: dll/opengl/opengl32/sw_mesa.h =================================================================== --- dll/opengl/opengl32/sw_mesa.h (revision 0) +++ dll/opengl/opengl32/sw_mesa.h (working copy) @@ -0,0 +1,55 @@ + +#pragma once + +#define WIN32_NO_STATUS +#include "glheader.h" +#include "context.h" +#include "extensions.h" +#include "glapi.h" +#include "glthread.h" +#include "matrix.h" +#include "mmath.h" +#include "texformat.h" +#include "texstore.h" +#include "array_cache/acache.h" +#include "tnl/tnl.h" +#include "tnl/t_context.h" +#include "tnl/t_pipeline.h" +#include "swrast/s_context.h" +#include "swrast/s_depth.h" +#include "swrast/s_lines.h" +#include "swrast_setup/swrast_setup.h" + +#include "opengl32.h" + +typedef struct tagSW_DC_Data +{ + HANDLE hUnique; + int pixelformat; + + struct tagSW_DC_Data* next; +}SW_DC_Data; + +typedef struct tagSW_Context +{ + GLcontext* gl_context; + GLvisual* gl_visual; + GLframebuffer* gl_framebuffer; + + /* The back and front buffer */ + void* backbuffer; + HDC frontbuffer; + + /* GL_FRONT_LEFT or GL_BACK_LEFT */ + GLenum readMode; + GLenum drawMode; + + /* Height, width */ + GLuint width, height; + + /* Pixel format data */ + BYTE pixel_type; + + /* For DIB->device transfers */ + BITMAPINFO bmi; +} SW_Context; \ No newline at end of file Index: dll/opengl/opengl32/wgl.c =================================================================== --- dll/opengl/opengl32/wgl.c (revision 58564) +++ dll/opengl/opengl32/wgl.c (working copy) @@ -11,6 +11,9 @@ #define OPENGL32_GL_FUNC_PROTOTYPES #include "opengl32.h" +#include "wine/debug.h" +WINE_DEFAULT_DEBUG_CHANNEL(wgl); + #ifdef __cplusplus extern "C" { #endif /* __cplusplus */ @@ -19,7 +22,12 @@ # define UNIMPLEMENTED DBGPRINT( "UNIMPLEMENTED" ) #endif +int +APIENTRY +rosglDescribePixelFormat( HDC hdc, int iFormat, UINT nBytes, + LPPIXELFORMATDESCRIPTOR pfd ); + typedef struct _OPENGL_INFO { DWORD Version; /*!< Driver interface version */ @@ -550,92 +558,164 @@ int APIENTRY -rosglChoosePixelFormat( HDC hdc, CONST PIXELFORMATDESCRIPTOR *pfd ) +rosglChoosePixelFormat( HDC hdc, CONST PIXELFORMATDESCRIPTOR *ppfd ) { - GLDRIVERDATA *icd; - PIXELFORMATDESCRIPTOR icdPfd; - int i; - int best = 0; - int score, bestScore = 0x7fff; /* used to choose a pfd if no exact match */ - int icdNumFormats; + PIXELFORMATDESCRIPTOR format, best; + int i, count, best_format; + int bestDBuffer = -1, bestStereo = -1; - DBGTRACE( "Called!" ); + TRACE_(wgl)( "%p %p: size %u version %u flags %u type %u color %u %u,%u,%u,%u " + "accum %u depth %u stencil %u aux %u\n", + hdc, ppfd, ppfd->nSize, ppfd->nVersion, ppfd->dwFlags, ppfd->iPixelType, + ppfd->cColorBits, ppfd->cRedBits, ppfd->cGreenBits, ppfd->cBlueBits, ppfd->cAlphaBits, + ppfd->cAccumBits, ppfd->cDepthBits, ppfd->cStencilBits, ppfd->cAuxBuffers ); - /* load ICD */ - icd = ROSGL_ICDForHDC( hdc ); - if (icd == NULL) - return 0; + count = rosglDescribePixelFormat( hdc, 0, 0, NULL ); + if (!count) return 0; - /* check input */ - if (pfd->nSize != sizeof (PIXELFORMATDESCRIPTOR) || pfd->nVersion != 1) - { - SetLastError( ERROR_INVALID_PARAMETER ); - return 0; - } + best_format = 0; + best.dwFlags = 0; + best.cAlphaBits = -1; + best.cColorBits = -1; + best.cDepthBits = -1; + best.cStencilBits = -1; + best.cAuxBuffers = -1; - /* get number of formats */ - icdNumFormats = icd->DrvDescribePixelFormat( hdc, 1, - sizeof (PIXELFORMATDESCRIPTOR), &icdPfd ); - if (icdNumFormats == 0) + for (i = 1; i <= count; i++) { - DBGPRINT( "Error: DrvDescribePixelFormat failed (%d)", GetLastError() ); - return 0; - } - DBGPRINT( "Info: Enumerating %d pixelformats", icdNumFormats ); + if (!rosglDescribePixelFormat( hdc, i, sizeof(format), &format )) continue; - /* try to find best format */ - for (i = 0; i < icdNumFormats; i++) - { - if (icd->DrvDescribePixelFormat( hdc, i + 1, - sizeof (PIXELFORMATDESCRIPTOR), &icdPfd ) == 0) + if (ppfd->iPixelType != format.iPixelType) { - DBGPRINT( "Warning: DrvDescribePixelFormat failed (%d)", - GetLastError() ); - break; + TRACE( "pixel type mismatch for iPixelFormat=%d\n", i ); + continue; } - if ((pfd->dwFlags & PFD_GENERIC_ACCELERATED) != 0) /* we do not support such kind of drivers */ + /* only use bitmap capable for formats for bitmap rendering */ + if( (ppfd->dwFlags & PFD_DRAW_TO_BITMAP) != (format.dwFlags & PFD_DRAW_TO_BITMAP)) { + TRACE( "PFD_DRAW_TO_BITMAP mismatch for iPixelFormat=%d\n", i ); continue; } - score = 0; /* higher is worse */ + /* The behavior of PDF_STEREO/PFD_STEREO_DONTCARE and PFD_DOUBLEBUFFER / PFD_DOUBLEBUFFER_DONTCARE + * is not very clear on MSDN. They specify that ChoosePixelFormat tries to match pixel formats + * with the flag (PFD_STEREO / PFD_DOUBLEBUFFERING) set. Otherwise it says that it tries to match + * formats without the given flag set. + * A test on Windows using a Radeon 9500pro on WinXP (the driver doesn't support Stereo) + * has indicated that a format without stereo is returned when stereo is unavailable. + * So in case PFD_STEREO is set, formats that support it should have priority above formats + * without. In case PFD_STEREO_DONTCARE is set, stereo is ignored. + * + * To summarize the following is most likely the correct behavior: + * stereo not set -> prefer non-stereo formats, but also accept stereo formats + * stereo set -> prefer stereo formats, but also accept non-stereo formats + * stereo don't care -> it doesn't matter whether we get stereo or not + * + * In Wine we will treat non-stereo the same way as don't care because it makes + * format selection even more complicated and second drivers with Stereo advertise + * each format twice anyway. + */ - /* compare flags */ - score += FLAG_SCORE(pfd->dwFlags, icdPfd.dwFlags, PFD_DRAW_TO_WINDOW); - score += FLAG_SCORE(pfd->dwFlags, icdPfd.dwFlags, PFD_DRAW_TO_BITMAP); - score += FLAG_SCORE(pfd->dwFlags, icdPfd.dwFlags, PFD_SUPPORT_GDI); - score += FLAG_SCORE(pfd->dwFlags, icdPfd.dwFlags, PFD_SUPPORT_OPENGL); - score += FLAG_SCORE_DONTCARE(pfd->dwFlags, icdPfd.dwFlags, PFD_DOUBLEBUFFER); - score += FLAG_SCORE_DONTCARE(pfd->dwFlags, icdPfd.dwFlags, PFD_STEREO); + /* Doublebuffer, see the comments above */ + if (!(ppfd->dwFlags & PFD_DOUBLEBUFFER_DONTCARE)) + { + if (((ppfd->dwFlags & PFD_DOUBLEBUFFER) != bestDBuffer) && + ((format.dwFlags & PFD_DOUBLEBUFFER) == (ppfd->dwFlags & PFD_DOUBLEBUFFER))) + goto found; - /* check other attribs */ - if (pfd->iPixelType != icdPfd.iPixelType) - score += 5; /* this is really bad i think */ - if (pfd->iLayerType != icdPfd.iLayerType) - score += 15; /* this is very very bad ;) */ + if (bestDBuffer != -1 && (format.dwFlags & PFD_DOUBLEBUFFER) != bestDBuffer) continue; + } - score += BUFFERDEPTH_SCORE(pfd->cAlphaBits, icdPfd.cAlphaBits); - score += BUFFERDEPTH_SCORE(pfd->cAccumBits, icdPfd.cAccumBits); - score += BUFFERDEPTH_SCORE(pfd->cDepthBits, icdPfd.cDepthBits); - score += BUFFERDEPTH_SCORE(pfd->cStencilBits, icdPfd.cStencilBits); - score += BUFFERDEPTH_SCORE(pfd->cAuxBuffers, icdPfd.cAuxBuffers); + /* Stereo, see the comments above. */ + if (!(ppfd->dwFlags & PFD_STEREO_DONTCARE)) + { + if (((ppfd->dwFlags & PFD_STEREO) != bestStereo) && + ((format.dwFlags & PFD_STEREO) == (ppfd->dwFlags & PFD_STEREO))) + goto found; - /* check score */ - if (score < bestScore) + if (bestStereo != -1 && (format.dwFlags & PFD_STEREO) != bestStereo) continue; + } + + /* Below we will do a number of checks to select the 'best' pixelformat. + * We assume the precedence cColorBits > cAlphaBits > cDepthBits > cStencilBits -> cAuxBuffers. + * The code works by trying to match the most important options as close as possible. + * When a reasonable format is found, we will try to match more options. + * It appears (see the opengl32 test) that Windows opengl drivers ignore options + * like cColorBits, cAlphaBits and friends if they are set to 0, so they are considered + * as DONTCARE. At least Serious Sam TSE relies on this behavior. */ + + if (ppfd->cColorBits) { - bestScore = score; - best = i + 1; - if (bestScore == 0) - break; + if (((ppfd->cColorBits > best.cColorBits) && (format.cColorBits > best.cColorBits)) || + ((format.cColorBits >= ppfd->cColorBits) && (format.cColorBits < best.cColorBits))) + goto found; + + if (best.cColorBits != format.cColorBits) /* Do further checks if the format is compatible */ + { + TRACE( "color mismatch for iPixelFormat=%d\n", i ); + continue; + } } + if (ppfd->cAlphaBits) + { + if (((ppfd->cAlphaBits > best.cAlphaBits) && (format.cAlphaBits > best.cAlphaBits)) || + ((format.cAlphaBits >= ppfd->cAlphaBits) && (format.cAlphaBits < best.cAlphaBits))) + goto found; + + if (best.cAlphaBits != format.cAlphaBits) + { + TRACE( "alpha mismatch for iPixelFormat=%d\n", i ); + continue; + } + } + if (ppfd->cDepthBits) + { + if (((ppfd->cDepthBits > best.cDepthBits) && (format.cDepthBits > best.cDepthBits)) || + ((format.cDepthBits >= ppfd->cDepthBits) && (format.cDepthBits < best.cDepthBits))) + goto found; + + if (best.cDepthBits != format.cDepthBits) + { + TRACE( "depth mismatch for iPixelFormat=%d\n", i ); + continue; + } + } + if (ppfd->cStencilBits) + { + if (((ppfd->cStencilBits > best.cStencilBits) && (format.cStencilBits > best.cStencilBits)) || + ((format.cStencilBits >= ppfd->cStencilBits) && (format.cStencilBits < best.cStencilBits))) + goto found; + + if (best.cStencilBits != format.cStencilBits) + { + TRACE( "stencil mismatch for iPixelFormat=%d\n", i ); + continue; + } + } + if (ppfd->cAuxBuffers) + { + if (((ppfd->cAuxBuffers > best.cAuxBuffers) && (format.cAuxBuffers > best.cAuxBuffers)) || + ((format.cAuxBuffers >= ppfd->cAuxBuffers) && (format.cAuxBuffers < best.cAuxBuffers))) + goto found; + + if (best.cAuxBuffers != format.cAuxBuffers) + { + TRACE( "aux mismatch for iPixelFormat=%d\n", i ); + continue; + } + } + continue; + + found: + best_format = i; + best = format; + bestDBuffer = format.dwFlags & PFD_DOUBLEBUFFER; + bestStereo = format.dwFlags & PFD_STEREO; } - if (best == 0) - SetLastError( 0 ); /* FIXME: set appropriate error */ - - DBGPRINT( "Info: Suggesting pixelformat %d", best ); - return best; + TRACE( "returning %u\n", best_format ); + return best_format; } @@ -713,8 +793,10 @@ icd = ROSGL_ICDForHDC( hdc ); if (icd == NULL) { - DBGPRINT( "Couldn't get ICD by HDC :-(" ); - /* FIXME: fallback? */ + /* icd == NULL, means software implmentation only is available. + * Getting NULL here means no pixel format was set + */ + SetLastError(ERROR_INVALID_PIXEL_FORMAT); return NULL; } @@ -805,7 +887,7 @@ if(glrc->thread_id != GetCurrentThreadId()) { DBGPRINT( "Error: GLRC is current for DC 0x%08x", glrc->hdc ); - SetLastError( ERROR_INVALID_FUNCTION ); + SetLastError( ERROR_BUSY ); return FALSE; } /* Unset it before going further */ @@ -858,14 +940,23 @@ if (icd != NULL) { - ret = icd->DrvDescribePixelFormat( hdc, iFormat, nBytes, pfd ); + int icd_num_formats = icd->DrvDescribePixelFormat(hdc, 0, 0, NULL); + if(iFormat <= icd_num_formats) + { + ret = icd->DrvDescribePixelFormat( hdc, iFormat, nBytes, pfd ); + /* Just add the number of software formats to result, + * that is a blank call to DrvDescribePixelFormat */ + iFormat = 0; + nBytes = 0; + pfd = NULL; + } + else + iFormat -= icd_num_formats; if (ret == 0) DBGPRINT( "Error: DrvDescribePixelFormat(format=%d) failed (%d)", iFormat, GetLastError() ); } - else - { - SetLastError( ERROR_INVALID_FUNCTION ); - } + /* Call the software implementation */ + ret += ICD_software.DrvDescribePixelFormat(hdc, iFormat, nBytes, pfd); return ret; } @@ -1017,7 +1108,7 @@ if (glrc->is_current && glrc->thread_id != GetCurrentThreadId()) /* used by another thread */ { DBGPRINT( "Error: hglrc is current for thread 0x%08x", glrc->thread_id ); - SetLastError( ERROR_INVALID_HANDLE ); + SetLastError( ERROR_BUSY ); return FALSE; } @@ -1122,6 +1213,7 @@ { GLDCDATA *dcdata; GLDRIVERDATA* icd; + int icd_format = iFormat; DBGTRACE( "Called!" ); @@ -1136,17 +1228,28 @@ if(dcdata->pixel_format) return dcdata->pixel_format == iFormat; icd = ROSGL_ICDForHDC(hdc); - if(icd == NULL) - return 0; + if (icd != NULL) + { + int icd_num_formats = icd->DrvDescribePixelFormat(hdc, 0, 0, NULL); + if(iFormat > icd_num_formats) + { + icd = &ICD_software; + icd_format -= icd_num_formats; + } + } + else + icd = &ICD_software; /* Call ICD function */ - if (!icd->DrvSetPixelFormat( hdc, iFormat, pfd )) + if (!icd->DrvSetPixelFormat( hdc, icd_format)) { DBGPRINT( "Warning: DrvSetPixelFormat(format=%d) failed (%d)", iFormat, GetLastError() ); return FALSE; } + /* Choosing a pixel format is like choosing an ICD */ dcdata->pixel_format = iFormat; + dcdata->icd = icd; return TRUE; } @@ -1241,41 +1344,6 @@ return ret; } - -BOOL -APIENTRY -rosglUseFontBitmapsA( HDC hdc, DWORD first, DWORD count, DWORD listBase ) -{ - return IntUseFontBitmapsA(hdc, first, count, listBase); -} - - -BOOL -APIENTRY -rosglUseFontBitmapsW( HDC hdc, DWORD first, DWORD count, DWORD listBase ) -{ - return IntUseFontBitmapsW(hdc, first, count, listBase); -} - -BOOL -APIENTRY -rosglUseFontOutlinesA( HDC hdc, DWORD first, DWORD count, DWORD listBase, - FLOAT deviation, FLOAT extrusion, int format, - GLYPHMETRICSFLOAT *pgmf ) -{ - return IntUseFontOutlinesA(hdc, first, count, listBase, deviation, extrusion, format, pgmf); -} - - -BOOL -APIENTRY -rosglUseFontOutlinesW( HDC hdc, DWORD first, DWORD count, DWORD listBase, - FLOAT deviation, FLOAT extrusion, int format, - GLYPHMETRICSFLOAT *pgmf ) -{ - return IntUseFontOutlinesW(hdc, first, count, listBase, deviation, extrusion, format, pgmf); -} - #ifdef __cplusplus }; /* extern "C" */ #endif /* __cplusplus */ Index: include/GL/gl_mangle.h =================================================================== --- include/GL/gl_mangle.h (revision 0) +++ include/GL/gl_mangle.h (working copy) @@ -0,0 +1,2312 @@ + +#if 0 +#define GL_MANGLE_C1 "DO NOT EDIT!!! - TO REGENERATE from gl.h, EXECUTE THIS FILE IN SHELL (/bin/sh) and save the output" +#define GL_MANGLE_C2 "This file is used to create GL function protypes and aliases for the function names" + files="gl.h glext.h" +#define GL_MANGLE_C3 "get regeneration header - copy everything in this file above the 'REGENERATE_TO_END' line" + awk '!done; /^\/\*REGENERATE_TO_END/ {done=1}' $0 + echo "" +#define GL_MANGLE_C4 get aliases + grep '^GLAPI' $files | sed -e 's/.*ENTRY gl\([^( ]*\).*$/#define gl\1 MANGLE(\1)/' | sort | uniq + echo "" + echo "#endif /* GL_MANGLE_H */" + exit +#endif /* REGENERATION */ + +/* + * If you compile Mesa with USE_MGL_NAMESPACE defined then you can link + * your application both with OpenGL and Mesa. The Mesa functions will + * be redefined so they are prefixed with "mgl" instead of "gl". + * Mgl contributed by Randy Frank (rfrank@rsinc.com) + * Regneration code contributed by Ray Tice (rayt@ma.ultra.net) + */ + +#ifndef GL_MANGLE_H +#define GL_MANGLE_H + +#ifndef MANGLE +#define MANGLE(x) mgl##x +#endif /*MANGLE*/ + +/*REGENERATE_TO_END-----------ALL LINES BELOW HERE GET REPLACED ON REGENERATION */ + +#define glAccum MANGLE(Accum) +#define glActiveProgramEXT MANGLE(ActiveProgramEXT) +#define glActiveShaderProgram MANGLE(ActiveShaderProgram) +#define glActiveStencilFaceEXT MANGLE(ActiveStencilFaceEXT) +#define glActiveTextureARB MANGLE(ActiveTextureARB) +#define glActiveTexture MANGLE(ActiveTexture) +#define glActiveVaryingNV MANGLE(ActiveVaryingNV) +#define glAlphaFragmentOp1ATI MANGLE(AlphaFragmentOp1ATI) +#define glAlphaFragmentOp2ATI MANGLE(AlphaFragmentOp2ATI) +#define glAlphaFragmentOp3ATI MANGLE(AlphaFragmentOp3ATI) +#define glAlphaFunc MANGLE(AlphaFunc) +#define glApplyTextureEXT MANGLE(ApplyTextureEXT) +#define glAreProgramsResidentNV MANGLE(AreProgramsResidentNV) +#define glAreTexturesResidentEXT MANGLE(AreTexturesResidentEXT) +#define glAreTexturesResident MANGLE(AreTexturesResident) +#define glArrayElementEXT MANGLE(ArrayElementEXT) +#define glArrayElement MANGLE(ArrayElement) +#define glArrayObjectATI MANGLE(ArrayObjectATI) +#define glAsyncMarkerSGIX MANGLE(AsyncMarkerSGIX) +#define glAttachObjectARB MANGLE(AttachObjectARB) +#define glAttachShader MANGLE(AttachShader) +#define glBeginConditionalRender MANGLE(BeginConditionalRender) +#define glBeginConditionalRenderNV MANGLE(BeginConditionalRenderNV) +#define glBeginFragmentShaderATI MANGLE(BeginFragmentShaderATI) +#define glBegin MANGLE(Begin) +#define glBeginOcclusionQueryNV MANGLE(BeginOcclusionQueryNV) +#define glBeginPerfMonitorAMD MANGLE(BeginPerfMonitorAMD) +#define glBeginQueryARB MANGLE(BeginQueryARB) +#define glBeginQueryIndexed MANGLE(BeginQueryIndexed) +#define glBeginQuery MANGLE(BeginQuery) +#define glBeginTransformFeedbackEXT MANGLE(BeginTransformFeedbackEXT) +#define glBeginTransformFeedback MANGLE(BeginTransformFeedback) +#define glBeginTransformFeedbackNV MANGLE(BeginTransformFeedbackNV) +#define glBeginVertexShaderEXT MANGLE(BeginVertexShaderEXT) +#define glBeginVideoCaptureNV MANGLE(BeginVideoCaptureNV) +#define glBindAttribLocationARB MANGLE(BindAttribLocationARB) +#define glBindAttribLocation MANGLE(BindAttribLocation) +#define glBindBufferARB MANGLE(BindBufferARB) +#define glBindBufferBaseEXT MANGLE(BindBufferBaseEXT) +#define glBindBufferBase MANGLE(BindBufferBase) +#define glBindBufferBaseNV MANGLE(BindBufferBaseNV) +#define glBindBuffer MANGLE(BindBuffer) +#define glBindBufferOffsetEXT MANGLE(BindBufferOffsetEXT) +#define glBindBufferOffsetNV MANGLE(BindBufferOffsetNV) +#define glBindBufferRangeEXT MANGLE(BindBufferRangeEXT) +#define glBindBufferRange MANGLE(BindBufferRange) +#define glBindBufferRangeNV MANGLE(BindBufferRangeNV) +#define glBindFragDataLocationEXT MANGLE(BindFragDataLocationEXT) +#define glBindFragDataLocationIndexed MANGLE(BindFragDataLocationIndexed) +#define glBindFragDataLocation MANGLE(BindFragDataLocation) +#define glBindFragmentShaderATI MANGLE(BindFragmentShaderATI) +#define glBindFramebufferEXT MANGLE(BindFramebufferEXT) +#define glBindFramebuffer MANGLE(BindFramebuffer) +#define glBindImageTextureEXT MANGLE(BindImageTextureEXT) +#define glBindLightParameterEXT MANGLE(BindLightParameterEXT) +#define glBindMaterialParameterEXT MANGLE(BindMaterialParameterEXT) +#define glBindMultiTextureEXT MANGLE(BindMultiTextureEXT) +#define glBindParameterEXT MANGLE(BindParameterEXT) +#define glBindProgramARB MANGLE(BindProgramARB) +#define glBindProgramNV MANGLE(BindProgramNV) +#define glBindProgramPipeline MANGLE(BindProgramPipeline) +#define glBindRenderbufferEXT MANGLE(BindRenderbufferEXT) +#define glBindRenderbuffer MANGLE(BindRenderbuffer) +#define glBindSampler MANGLE(BindSampler) +#define glBindTexGenParameterEXT MANGLE(BindTexGenParameterEXT) +#define glBindTextureEXT MANGLE(BindTextureEXT) +#define glBindTexture MANGLE(BindTexture) +#define glBindTextureUnitParameterEXT MANGLE(BindTextureUnitParameterEXT) +#define glBindTransformFeedback MANGLE(BindTransformFeedback) +#define glBindTransformFeedbackNV MANGLE(BindTransformFeedbackNV) +#define glBindVertexArrayAPPLE MANGLE(BindVertexArrayAPPLE) +#define glBindVertexArray MANGLE(BindVertexArray) +#define glBindVertexShaderEXT MANGLE(BindVertexShaderEXT) +#define glBindVideoCaptureStreamBufferNV MANGLE(BindVideoCaptureStreamBufferNV) +#define glBindVideoCaptureStreamTextureNV MANGLE(BindVideoCaptureStreamTextureNV) +#define glBinormal3bEXT MANGLE(Binormal3bEXT) +#define glBinormal3bvEXT MANGLE(Binormal3bvEXT) +#define glBinormal3dEXT MANGLE(Binormal3dEXT) +#define glBinormal3dvEXT MANGLE(Binormal3dvEXT) +#define glBinormal3fEXT MANGLE(Binormal3fEXT) +#define glBinormal3fvEXT MANGLE(Binormal3fvEXT) +#define glBinormal3iEXT MANGLE(Binormal3iEXT) +#define glBinormal3ivEXT MANGLE(Binormal3ivEXT) +#define glBinormal3sEXT MANGLE(Binormal3sEXT) +#define glBinormal3svEXT MANGLE(Binormal3svEXT) +#define glBinormalPointerEXT MANGLE(BinormalPointerEXT) +#define glBitmap MANGLE(Bitmap) +#define glBlendColorEXT MANGLE(BlendColorEXT) +#define glBlendColor MANGLE(BlendColor) +#define glBlendEquationEXT MANGLE(BlendEquationEXT) +#define glBlendEquationiARB MANGLE(BlendEquationiARB) +#define glBlendEquationi MANGLE(BlendEquationi) +#define glBlendEquationIndexedAMD MANGLE(BlendEquationIndexedAMD) +#define glBlendEquation MANGLE(BlendEquation) +#define glBlendEquationSeparateATI MANGLE(BlendEquationSeparateATI) +#define glBlendEquationSeparateEXT MANGLE(BlendEquationSeparateEXT) +#define glBlendEquationSeparateiARB MANGLE(BlendEquationSeparateiARB) +#define glBlendEquationSeparatei MANGLE(BlendEquationSeparatei) +#define glBlendEquationSeparateIndexedAMD MANGLE(BlendEquationSeparateIndexedAMD) +#define glBlendEquationSeparate MANGLE(BlendEquationSeparate) +#define glBlendFunciARB MANGLE(BlendFunciARB) +#define glBlendFunci MANGLE(BlendFunci) +#define glBlendFuncIndexedAMD MANGLE(BlendFuncIndexedAMD) +#define glBlendFunc MANGLE(BlendFunc) +#define glBlendFuncSeparateEXT MANGLE(BlendFuncSeparateEXT) +#define glBlendFuncSeparateiARB MANGLE(BlendFuncSeparateiARB) +#define glBlendFuncSeparatei MANGLE(BlendFuncSeparatei) +#define glBlendFuncSeparateIndexedAMD MANGLE(BlendFuncSeparateIndexedAMD) +#define glBlendFuncSeparateINGR MANGLE(BlendFuncSeparateINGR) +#define glBlendFuncSeparate MANGLE(BlendFuncSeparate) +#define glBlitFramebufferEXT MANGLE(BlitFramebufferEXT) +#define glBlitFramebuffer MANGLE(BlitFramebuffer) +#define glBufferAddressRangeNV MANGLE(BufferAddressRangeNV) +#define glBufferDataARB MANGLE(BufferDataARB) +#define glBufferData MANGLE(BufferData) +#define glBufferParameteriAPPLE MANGLE(BufferParameteriAPPLE) +#define glBufferSubDataARB MANGLE(BufferSubDataARB) +#define glBufferSubData MANGLE(BufferSubData) +#define glCallList MANGLE(CallList) +#define glCallLists MANGLE(CallLists) +#define glCheckFramebufferStatusEXT MANGLE(CheckFramebufferStatusEXT) +#define glCheckFramebufferStatus MANGLE(CheckFramebufferStatus) +#define glCheckNamedFramebufferStatusEXT MANGLE(CheckNamedFramebufferStatusEXT) +#define glClampColorARB MANGLE(ClampColorARB) +#define glClampColor MANGLE(ClampColor) +#define glClearAccum MANGLE(ClearAccum) +#define glClearBufferfi MANGLE(ClearBufferfi) +#define glClearBufferfv MANGLE(ClearBufferfv) +#define glClearBufferiv MANGLE(ClearBufferiv) +#define glClearBufferuiv MANGLE(ClearBufferuiv) +#define glClearColorIiEXT MANGLE(ClearColorIiEXT) +#define glClearColorIuiEXT MANGLE(ClearColorIuiEXT) +#define glClearColor MANGLE(ClearColor) +#define glClearDebugLogMESA MANGLE(ClearDebugLogMESA) +#define glClearDepthdNV MANGLE(ClearDepthdNV) +#define glClearDepthf MANGLE(ClearDepthf) +#define glClearDepth MANGLE(ClearDepth) +#define glClearIndex MANGLE(ClearIndex) +#define glClear MANGLE(Clear) +#define glClearStencil MANGLE(ClearStencil) +#define glClientActiveTextureARB MANGLE(ClientActiveTextureARB) +#define glClientActiveTexture MANGLE(ClientActiveTexture) +#define glClientActiveVertexStreamATI MANGLE(ClientActiveVertexStreamATI) +#define glClientAttribDefaultEXT MANGLE(ClientAttribDefaultEXT) +#define glClientWaitSync MANGLE(ClientWaitSync) +#define glClipPlane MANGLE(ClipPlane) +#define glColor3b MANGLE(Color3b) +#define glColor3bv MANGLE(Color3bv) +#define glColor3d MANGLE(Color3d) +#define glColor3dv MANGLE(Color3dv) +#define glColor3f MANGLE(Color3f) +#define glColor3fVertex3fSUN MANGLE(Color3fVertex3fSUN) +#define glColor3fVertex3fvSUN MANGLE(Color3fVertex3fvSUN) +#define glColor3fv MANGLE(Color3fv) +#define glColor3hNV MANGLE(Color3hNV) +#define glColor3hvNV MANGLE(Color3hvNV) +#define glColor3i MANGLE(Color3i) +#define glColor3iv MANGLE(Color3iv) +#define glColor3s MANGLE(Color3s) +#define glColor3sv MANGLE(Color3sv) +#define glColor3ub MANGLE(Color3ub) +#define glColor3ubv MANGLE(Color3ubv) +#define glColor3ui MANGLE(Color3ui) +#define glColor3uiv MANGLE(Color3uiv) +#define glColor3us MANGLE(Color3us) +#define glColor3usv MANGLE(Color3usv) +#define glColor4b MANGLE(Color4b) +#define glColor4bv MANGLE(Color4bv) +#define glColor4d MANGLE(Color4d) +#define glColor4dv MANGLE(Color4dv) +#define glColor4f MANGLE(Color4f) +#define glColor4fNormal3fVertex3fSUN MANGLE(Color4fNormal3fVertex3fSUN) +#define glColor4fNormal3fVertex3fvSUN MANGLE(Color4fNormal3fVertex3fvSUN) +#define glColor4fv MANGLE(Color4fv) +#define glColor4hNV MANGLE(Color4hNV) +#define glColor4hvNV MANGLE(Color4hvNV) +#define glColor4i MANGLE(Color4i) +#define glColor4iv MANGLE(Color4iv) +#define glColor4s MANGLE(Color4s) +#define glColor4sv MANGLE(Color4sv) +#define glColor4ub MANGLE(Color4ub) +#define glColor4ubVertex2fSUN MANGLE(Color4ubVertex2fSUN) +#define glColor4ubVertex2fvSUN MANGLE(Color4ubVertex2fvSUN) +#define glColor4ubVertex3fSUN MANGLE(Color4ubVertex3fSUN) +#define glColor4ubVertex3fvSUN MANGLE(Color4ubVertex3fvSUN) +#define glColor4ubv MANGLE(Color4ubv) +#define glColor4ui MANGLE(Color4ui) +#define glColor4uiv MANGLE(Color4uiv) +#define glColor4us MANGLE(Color4us) +#define glColor4usv MANGLE(Color4usv) +#define glColorFormatNV MANGLE(ColorFormatNV) +#define glColorFragmentOp1ATI MANGLE(ColorFragmentOp1ATI) +#define glColorFragmentOp2ATI MANGLE(ColorFragmentOp2ATI) +#define glColorFragmentOp3ATI MANGLE(ColorFragmentOp3ATI) +#define glColorMaski MANGLE(ColorMaski) +#define glColorMaskIndexedEXT MANGLE(ColorMaskIndexedEXT) +#define glColorMask MANGLE(ColorMask) +#define glColorMaterial MANGLE(ColorMaterial) +#define glColorP3ui MANGLE(ColorP3ui) +#define glColorP3uiv MANGLE(ColorP3uiv) +#define glColorP4ui MANGLE(ColorP4ui) +#define glColorP4uiv MANGLE(ColorP4uiv) +#define glColorPointerEXT MANGLE(ColorPointerEXT) +#define glColorPointerListIBM MANGLE(ColorPointerListIBM) +#define glColorPointer MANGLE(ColorPointer) +#define glColorPointervINTEL MANGLE(ColorPointervINTEL) +#define glColorSubTableEXT MANGLE(ColorSubTableEXT) +#define glColorSubTable MANGLE(ColorSubTable) +#define glColorTableEXT MANGLE(ColorTableEXT) +#define glColorTable MANGLE(ColorTable) +#define glColorTableParameterfv MANGLE(ColorTableParameterfv) +#define glColorTableParameterfvSGI MANGLE(ColorTableParameterfvSGI) +#define glColorTableParameteriv MANGLE(ColorTableParameteriv) +#define glColorTableParameterivSGI MANGLE(ColorTableParameterivSGI) +#define glColorTableSGI MANGLE(ColorTableSGI) +#define glCombinerInputNV MANGLE(CombinerInputNV) +#define glCombinerOutputNV MANGLE(CombinerOutputNV) +#define glCombinerParameterfNV MANGLE(CombinerParameterfNV) +#define glCombinerParameterfvNV MANGLE(CombinerParameterfvNV) +#define glCombinerParameteriNV MANGLE(CombinerParameteriNV) +#define glCombinerParameterivNV MANGLE(CombinerParameterivNV) +#define glCombinerStageParameterfvNV MANGLE(CombinerStageParameterfvNV) +#define glCompileShaderARB MANGLE(CompileShaderARB) +#define glCompileShaderIncludeARB MANGLE(CompileShaderIncludeARB) +#define glCompileShader MANGLE(CompileShader) +#define glCompressedMultiTexImage1DEXT MANGLE(CompressedMultiTexImage1DEXT) +#define glCompressedMultiTexImage2DEXT MANGLE(CompressedMultiTexImage2DEXT) +#define glCompressedMultiTexImage3DEXT MANGLE(CompressedMultiTexImage3DEXT) +#define glCompressedMultiTexSubImage1DEXT MANGLE(CompressedMultiTexSubImage1DEXT) +#define glCompressedMultiTexSubImage2DEXT MANGLE(CompressedMultiTexSubImage2DEXT) +#define glCompressedMultiTexSubImage3DEXT MANGLE(CompressedMultiTexSubImage3DEXT) +#define glCompressedTexImage1DARB MANGLE(CompressedTexImage1DARB) +#define glCompressedTexImage1D MANGLE(CompressedTexImage1D) +#define glCompressedTexImage2DARB MANGLE(CompressedTexImage2DARB) +#define glCompressedTexImage2D MANGLE(CompressedTexImage2D) +#define glCompressedTexImage3DARB MANGLE(CompressedTexImage3DARB) +#define glCompressedTexImage3D MANGLE(CompressedTexImage3D) +#define glCompressedTexSubImage1DARB MANGLE(CompressedTexSubImage1DARB) +#define glCompressedTexSubImage1D MANGLE(CompressedTexSubImage1D) +#define glCompressedTexSubImage2DARB MANGLE(CompressedTexSubImage2DARB) +#define glCompressedTexSubImage2D MANGLE(CompressedTexSubImage2D) +#define glCompressedTexSubImage3DARB MANGLE(CompressedTexSubImage3DARB) +#define glCompressedTexSubImage3D MANGLE(CompressedTexSubImage3D) +#define glCompressedTextureImage1DEXT MANGLE(CompressedTextureImage1DEXT) +#define glCompressedTextureImage2DEXT MANGLE(CompressedTextureImage2DEXT) +#define glCompressedTextureImage3DEXT MANGLE(CompressedTextureImage3DEXT) +#define glCompressedTextureSubImage1DEXT MANGLE(CompressedTextureSubImage1DEXT) +#define glCompressedTextureSubImage2DEXT MANGLE(CompressedTextureSubImage2DEXT) +#define glCompressedTextureSubImage3DEXT MANGLE(CompressedTextureSubImage3DEXT) +#define glConvolutionFilter1DEXT MANGLE(ConvolutionFilter1DEXT) +#define glConvolutionFilter1D MANGLE(ConvolutionFilter1D) +#define glConvolutionFilter2DEXT MANGLE(ConvolutionFilter2DEXT) +#define glConvolutionFilter2D MANGLE(ConvolutionFilter2D) +#define glConvolutionParameterfEXT MANGLE(ConvolutionParameterfEXT) +#define glConvolutionParameterf MANGLE(ConvolutionParameterf) +#define glConvolutionParameterfvEXT MANGLE(ConvolutionParameterfvEXT) +#define glConvolutionParameterfv MANGLE(ConvolutionParameterfv) +#define glConvolutionParameteriEXT MANGLE(ConvolutionParameteriEXT) +#define glConvolutionParameteri MANGLE(ConvolutionParameteri) +#define glConvolutionParameterivEXT MANGLE(ConvolutionParameterivEXT) +#define glConvolutionParameteriv MANGLE(ConvolutionParameteriv) +#define glCopyBufferSubData MANGLE(CopyBufferSubData) +#define glCopyColorSubTableEXT MANGLE(CopyColorSubTableEXT) +#define glCopyColorSubTable MANGLE(CopyColorSubTable) +#define glCopyColorTable MANGLE(CopyColorTable) +#define glCopyColorTableSGI MANGLE(CopyColorTableSGI) +#define glCopyConvolutionFilter1DEXT MANGLE(CopyConvolutionFilter1DEXT) +#define glCopyConvolutionFilter1D MANGLE(CopyConvolutionFilter1D) +#define glCopyConvolutionFilter2DEXT MANGLE(CopyConvolutionFilter2DEXT) +#define glCopyConvolutionFilter2D MANGLE(CopyConvolutionFilter2D) +#define glCopyImageSubDataNV MANGLE(CopyImageSubDataNV) +#define glCopyMultiTexImage1DEXT MANGLE(CopyMultiTexImage1DEXT) +#define glCopyMultiTexImage2DEXT MANGLE(CopyMultiTexImage2DEXT) +#define glCopyMultiTexSubImage1DEXT MANGLE(CopyMultiTexSubImage1DEXT) +#define glCopyMultiTexSubImage2DEXT MANGLE(CopyMultiTexSubImage2DEXT) +#define glCopyMultiTexSubImage3DEXT MANGLE(CopyMultiTexSubImage3DEXT) +#define glCopyPixels MANGLE(CopyPixels) +#define glCopyTexImage1DEXT MANGLE(CopyTexImage1DEXT) +#define glCopyTexImage1D MANGLE(CopyTexImage1D) +#define glCopyTexImage2DEXT MANGLE(CopyTexImage2DEXT) +#define glCopyTexImage2D MANGLE(CopyTexImage2D) +#define glCopyTexSubImage1DEXT MANGLE(CopyTexSubImage1DEXT) +#define glCopyTexSubImage1D MANGLE(CopyTexSubImage1D) +#define glCopyTexSubImage2DEXT MANGLE(CopyTexSubImage2DEXT) +#define glCopyTexSubImage2D MANGLE(CopyTexSubImage2D) +#define glCopyTexSubImage3DEXT MANGLE(CopyTexSubImage3DEXT) +#define glCopyTexSubImage3D MANGLE(CopyTexSubImage3D) +#define glCopyTextureImage1DEXT MANGLE(CopyTextureImage1DEXT) +#define glCopyTextureImage2DEXT MANGLE(CopyTextureImage2DEXT) +#define glCopyTextureSubImage1DEXT MANGLE(CopyTextureSubImage1DEXT) +#define glCopyTextureSubImage2DEXT MANGLE(CopyTextureSubImage2DEXT) +#define glCopyTextureSubImage3DEXT MANGLE(CopyTextureSubImage3DEXT) +#define glCreateDebugObjectMESA MANGLE(CreateDebugObjectMESA) +#define glCreateProgram MANGLE(CreateProgram) +#define glCreateProgramObjectARB MANGLE(CreateProgramObjectARB) +#define glCreateShader MANGLE(CreateShader) +#define glCreateShaderObjectARB MANGLE(CreateShaderObjectARB) +#define glCreateShaderProgramEXT MANGLE(CreateShaderProgramEXT) +#define glCreateShaderProgramv MANGLE(CreateShaderProgramv) +#define glCreateSyncFromCLeventARB MANGLE(CreateSyncFromCLeventARB) +#define glCullFace MANGLE(CullFace) +#define glCullParameterdvEXT MANGLE(CullParameterdvEXT) +#define glCullParameterfvEXT MANGLE(CullParameterfvEXT) +#define glCurrentPaletteMatrixARB MANGLE(CurrentPaletteMatrixARB) +#define glDebugMessageCallbackAMD MANGLE(DebugMessageCallbackAMD) +#define glDebugMessageCallbackARB MANGLE(DebugMessageCallbackARB) +#define glDebugMessageControlARB MANGLE(DebugMessageControlARB) +#define glDebugMessageEnableAMD MANGLE(DebugMessageEnableAMD) +#define glDebugMessageInsertAMD MANGLE(DebugMessageInsertAMD) +#define glDebugMessageInsertARB MANGLE(DebugMessageInsertARB) +#define glDeformationMap3dSGIX MANGLE(DeformationMap3dSGIX) +#define glDeformationMap3fSGIX MANGLE(DeformationMap3fSGIX) +#define glDeformSGIX MANGLE(DeformSGIX) +#define glDeleteAsyncMarkersSGIX MANGLE(DeleteAsyncMarkersSGIX) +#define glDeleteBuffersARB MANGLE(DeleteBuffersARB) +#define glDeleteBuffers MANGLE(DeleteBuffers) +#define glDeleteFencesAPPLE MANGLE(DeleteFencesAPPLE) +#define glDeleteFencesNV MANGLE(DeleteFencesNV) +#define glDeleteFragmentShaderATI MANGLE(DeleteFragmentShaderATI) +#define glDeleteFramebuffersEXT MANGLE(DeleteFramebuffersEXT) +#define glDeleteFramebuffers MANGLE(DeleteFramebuffers) +#define glDeleteLists MANGLE(DeleteLists) +#define glDeleteNamedStringARB MANGLE(DeleteNamedStringARB) +#define glDeleteNamesAMD MANGLE(DeleteNamesAMD) +#define glDeleteObjectARB MANGLE(DeleteObjectARB) +#define glDeleteOcclusionQueriesNV MANGLE(DeleteOcclusionQueriesNV) +#define glDeletePerfMonitorsAMD MANGLE(DeletePerfMonitorsAMD) +#define glDeleteProgram MANGLE(DeleteProgram) +#define glDeleteProgramPipelines MANGLE(DeleteProgramPipelines) +#define glDeleteProgramsARB MANGLE(DeleteProgramsARB) +#define glDeleteProgramsNV MANGLE(DeleteProgramsNV) +#define glDeleteQueriesARB MANGLE(DeleteQueriesARB) +#define glDeleteQueries MANGLE(DeleteQueries) +#define glDeleteRenderbuffersEXT MANGLE(DeleteRenderbuffersEXT) +#define glDeleteRenderbuffers MANGLE(DeleteRenderbuffers) +#define glDeleteSamplers MANGLE(DeleteSamplers) +#define glDeleteShader MANGLE(DeleteShader) +#define glDeleteSync MANGLE(DeleteSync) +#define glDeleteTexturesEXT MANGLE(DeleteTexturesEXT) +#define glDeleteTextures MANGLE(DeleteTextures) +#define glDeleteTransformFeedbacks MANGLE(DeleteTransformFeedbacks) +#define glDeleteTransformFeedbacksNV MANGLE(DeleteTransformFeedbacksNV) +#define glDeleteVertexArraysAPPLE MANGLE(DeleteVertexArraysAPPLE) +#define glDeleteVertexArrays MANGLE(DeleteVertexArrays) +#define glDeleteVertexShaderEXT MANGLE(DeleteVertexShaderEXT) +#define glDepthBoundsdNV MANGLE(DepthBoundsdNV) +#define glDepthBoundsEXT MANGLE(DepthBoundsEXT) +#define glDepthFunc MANGLE(DepthFunc) +#define glDepthMask MANGLE(DepthMask) +#define glDepthRangeArrayv MANGLE(DepthRangeArrayv) +#define glDepthRangedNV MANGLE(DepthRangedNV) +#define glDepthRangef MANGLE(DepthRangef) +#define glDepthRangeIndexed MANGLE(DepthRangeIndexed) +#define glDepthRange MANGLE(DepthRange) +#define glDetachObjectARB MANGLE(DetachObjectARB) +#define glDetachShader MANGLE(DetachShader) +#define glDetailTexFuncSGIS MANGLE(DetailTexFuncSGIS) +#define glDisableClientStateIndexedEXT MANGLE(DisableClientStateIndexedEXT) +#define glDisableClientState MANGLE(DisableClientState) +#define glDisablei MANGLE(Disablei) +#define glDisableIndexedEXT MANGLE(DisableIndexedEXT) +#define glDisable MANGLE(Disable) +#define glDisableVariantClientStateEXT MANGLE(DisableVariantClientStateEXT) +#define glDisableVertexAttribAPPLE MANGLE(DisableVertexAttribAPPLE) +#define glDisableVertexAttribArrayARB MANGLE(DisableVertexAttribArrayARB) +#define glDisableVertexAttribArray MANGLE(DisableVertexAttribArray) +#define glDrawArraysEXT MANGLE(DrawArraysEXT) +#define glDrawArraysIndirect MANGLE(DrawArraysIndirect) +#define glDrawArraysInstancedARB MANGLE(DrawArraysInstancedARB) +#define glDrawArraysInstancedEXT MANGLE(DrawArraysInstancedEXT) +#define glDrawArraysInstanced MANGLE(DrawArraysInstanced) +#define glDrawArrays MANGLE(DrawArrays) +#define glDrawBuffer MANGLE(DrawBuffer) +#define glDrawBuffersARB MANGLE(DrawBuffersARB) +#define glDrawBuffersATI MANGLE(DrawBuffersATI) +#define glDrawBuffers MANGLE(DrawBuffers) +#define glDrawElementArrayAPPLE MANGLE(DrawElementArrayAPPLE) +#define glDrawElementArrayATI MANGLE(DrawElementArrayATI) +#define glDrawElementsBaseVertex MANGLE(DrawElementsBaseVertex) +#define glDrawElementsIndirect MANGLE(DrawElementsIndirect) +#define glDrawElementsInstancedARB MANGLE(DrawElementsInstancedARB) +#define glDrawElementsInstancedBaseVertex MANGLE(DrawElementsInstancedBaseVertex) +#define glDrawElementsInstancedEXT MANGLE(DrawElementsInstancedEXT) +#define glDrawElementsInstanced MANGLE(DrawElementsInstanced) +#define glDrawElements MANGLE(DrawElements) +#define glDrawMeshArraysSUN MANGLE(DrawMeshArraysSUN) +#define glDrawPixels MANGLE(DrawPixels) +#define glDrawRangeElementArrayAPPLE MANGLE(DrawRangeElementArrayAPPLE) +#define glDrawRangeElementArrayATI MANGLE(DrawRangeElementArrayATI) +#define glDrawRangeElementsBaseVertex MANGLE(DrawRangeElementsBaseVertex) +#define glDrawRangeElementsEXT MANGLE(DrawRangeElementsEXT) +#define glDrawRangeElements MANGLE(DrawRangeElements) +#define glDrawTransformFeedback MANGLE(DrawTransformFeedback) +#define glDrawTransformFeedbackNV MANGLE(DrawTransformFeedbackNV) +#define glDrawTransformFeedbackStream MANGLE(DrawTransformFeedbackStream) +#define glEdgeFlagFormatNV MANGLE(EdgeFlagFormatNV) +#define glEdgeFlag MANGLE(EdgeFlag) +#define glEdgeFlagPointerEXT MANGLE(EdgeFlagPointerEXT) +#define glEdgeFlagPointerListIBM MANGLE(EdgeFlagPointerListIBM) +#define glEdgeFlagPointer MANGLE(EdgeFlagPointer) +#define glEdgeFlagv MANGLE(EdgeFlagv) +#define glEGLImageTargetRenderbufferStorageOES MANGLE(EGLImageTargetRenderbufferStorageOES) +#define glEGLImageTargetTexture2DOES MANGLE(EGLImageTargetTexture2DOES) +#define glElementPointerAPPLE MANGLE(ElementPointerAPPLE) +#define glElementPointerATI MANGLE(ElementPointerATI) +#define glEnableClientStateIndexedEXT MANGLE(EnableClientStateIndexedEXT) +#define glEnableClientState MANGLE(EnableClientState) +#define glEnablei MANGLE(Enablei) +#define glEnableIndexedEXT MANGLE(EnableIndexedEXT) +#define glEnable MANGLE(Enable) +#define glEnableVariantClientStateEXT MANGLE(EnableVariantClientStateEXT) +#define glEnableVertexAttribAPPLE MANGLE(EnableVertexAttribAPPLE) +#define glEnableVertexAttribArrayARB MANGLE(EnableVertexAttribArrayARB) +#define glEnableVertexAttribArray MANGLE(EnableVertexAttribArray) +#define glEndConditionalRender MANGLE(EndConditionalRender) +#define glEndConditionalRenderNV MANGLE(EndConditionalRenderNV) +#define glEndFragmentShaderATI MANGLE(EndFragmentShaderATI) +#define glEndList MANGLE(EndList) +#define glEnd MANGLE(End) +#define glEndOcclusionQueryNV MANGLE(EndOcclusionQueryNV) +#define glEndPerfMonitorAMD MANGLE(EndPerfMonitorAMD) +#define glEndQueryARB MANGLE(EndQueryARB) +#define glEndQueryIndexed MANGLE(EndQueryIndexed) +#define glEndQuery MANGLE(EndQuery) +#define glEndTransformFeedbackEXT MANGLE(EndTransformFeedbackEXT) +#define glEndTransformFeedback MANGLE(EndTransformFeedback) +#define glEndTransformFeedbackNV MANGLE(EndTransformFeedbackNV) +#define glEndVertexShaderEXT MANGLE(EndVertexShaderEXT) +#define glEndVideoCaptureNV MANGLE(EndVideoCaptureNV) +#define glEvalCoord1d MANGLE(EvalCoord1d) +#define glEvalCoord1dv MANGLE(EvalCoord1dv) +#define glEvalCoord1f MANGLE(EvalCoord1f) +#define glEvalCoord1fv MANGLE(EvalCoord1fv) +#define glEvalCoord2d MANGLE(EvalCoord2d) +#define glEvalCoord2dv MANGLE(EvalCoord2dv) +#define glEvalCoord2f MANGLE(EvalCoord2f) +#define glEvalCoord2fv MANGLE(EvalCoord2fv) +#define glEvalMapsNV MANGLE(EvalMapsNV) +#define glEvalMesh1 MANGLE(EvalMesh1) +#define glEvalMesh2 MANGLE(EvalMesh2) +#define glEvalPoint1 MANGLE(EvalPoint1) +#define glEvalPoint2 MANGLE(EvalPoint2) +#define glExecuteProgramNV MANGLE(ExecuteProgramNV) +#define glExtractComponentEXT MANGLE(ExtractComponentEXT) +#define glFeedbackBuffer MANGLE(FeedbackBuffer) +#define glFenceSync MANGLE(FenceSync) +#define glFinalCombinerInputNV MANGLE(FinalCombinerInputNV) +#define glFinishAsyncSGIX MANGLE(FinishAsyncSGIX) +#define glFinishFenceAPPLE MANGLE(FinishFenceAPPLE) +#define glFinishFenceNV MANGLE(FinishFenceNV) +#define glFinish MANGLE(Finish) +#define glFinishObjectAPPLE MANGLE(FinishObjectAPPLE) +#define glFinishTextureSUNX MANGLE(FinishTextureSUNX) +#define glFlush MANGLE(Flush) +#define glFlushMappedBufferRangeAPPLE MANGLE(FlushMappedBufferRangeAPPLE) +#define glFlushMappedBufferRange MANGLE(FlushMappedBufferRange) +#define glFlushMappedNamedBufferRangeEXT MANGLE(FlushMappedNamedBufferRangeEXT) +#define glFlushPixelDataRangeNV MANGLE(FlushPixelDataRangeNV) +#define glFlushRasterSGIX MANGLE(FlushRasterSGIX) +#define glFlushVertexArrayRangeAPPLE MANGLE(FlushVertexArrayRangeAPPLE) +#define glFlushVertexArrayRangeNV MANGLE(FlushVertexArrayRangeNV) +#define glFogCoorddEXT MANGLE(FogCoorddEXT) +#define glFogCoordd MANGLE(FogCoordd) +#define glFogCoorddvEXT MANGLE(FogCoorddvEXT) +#define glFogCoorddv MANGLE(FogCoorddv) +#define glFogCoordfEXT MANGLE(FogCoordfEXT) +#define glFogCoordf MANGLE(FogCoordf) +#define glFogCoordFormatNV MANGLE(FogCoordFormatNV) +#define glFogCoordfvEXT MANGLE(FogCoordfvEXT) +#define glFogCoordfv MANGLE(FogCoordfv) +#define glFogCoordhNV MANGLE(FogCoordhNV) +#define glFogCoordhvNV MANGLE(FogCoordhvNV) +#define glFogCoordPointerEXT MANGLE(FogCoordPointerEXT) +#define glFogCoordPointerListIBM MANGLE(FogCoordPointerListIBM) +#define glFogCoordPointer MANGLE(FogCoordPointer) +#define glFogf MANGLE(Fogf) +#define glFogFuncSGIS MANGLE(FogFuncSGIS) +#define glFogfv MANGLE(Fogfv) +#define glFogi MANGLE(Fogi) +#define glFogiv MANGLE(Fogiv) +#define glFragmentColorMaterialSGIX MANGLE(FragmentColorMaterialSGIX) +#define glFragmentLightfSGIX MANGLE(FragmentLightfSGIX) +#define glFragmentLightfvSGIX MANGLE(FragmentLightfvSGIX) +#define glFragmentLightiSGIX MANGLE(FragmentLightiSGIX) +#define glFragmentLightivSGIX MANGLE(FragmentLightivSGIX) +#define glFragmentLightModelfSGIX MANGLE(FragmentLightModelfSGIX) +#define glFragmentLightModelfvSGIX MANGLE(FragmentLightModelfvSGIX) +#define glFragmentLightModeliSGIX MANGLE(FragmentLightModeliSGIX) +#define glFragmentLightModelivSGIX MANGLE(FragmentLightModelivSGIX) +#define glFragmentMaterialfSGIX MANGLE(FragmentMaterialfSGIX) +#define glFragmentMaterialfvSGIX MANGLE(FragmentMaterialfvSGIX) +#define glFragmentMaterialiSGIX MANGLE(FragmentMaterialiSGIX) +#define glFragmentMaterialivSGIX MANGLE(FragmentMaterialivSGIX) +#define glFramebufferDrawBufferEXT MANGLE(FramebufferDrawBufferEXT) +#define glFramebufferDrawBuffersEXT MANGLE(FramebufferDrawBuffersEXT) +#define glFramebufferReadBufferEXT MANGLE(FramebufferReadBufferEXT) +#define glFramebufferRenderbufferEXT MANGLE(FramebufferRenderbufferEXT) +#define glFramebufferRenderbuffer MANGLE(FramebufferRenderbuffer) +#define glFramebufferTexture1DEXT MANGLE(FramebufferTexture1DEXT) +#define glFramebufferTexture1D MANGLE(FramebufferTexture1D) +#define glFramebufferTexture2DEXT MANGLE(FramebufferTexture2DEXT) +#define glFramebufferTexture2D MANGLE(FramebufferTexture2D) +#define glFramebufferTexture3DEXT MANGLE(FramebufferTexture3DEXT) +#define glFramebufferTexture3D MANGLE(FramebufferTexture3D) +#define glFramebufferTextureARB MANGLE(FramebufferTextureARB) +#define glFramebufferTextureEXT MANGLE(FramebufferTextureEXT) +#define glFramebufferTextureFaceARB MANGLE(FramebufferTextureFaceARB) +#define glFramebufferTextureFaceEXT MANGLE(FramebufferTextureFaceEXT) +#define glFramebufferTextureLayerARB MANGLE(FramebufferTextureLayerARB) +#define glFramebufferTextureLayerEXT MANGLE(FramebufferTextureLayerEXT) +#define glFramebufferTextureLayer MANGLE(FramebufferTextureLayer) +#define glFramebufferTexture MANGLE(FramebufferTexture) +#define glFrameTerminatorGREMEDY MANGLE(FrameTerminatorGREMEDY) +#define glFrameZoomSGIX MANGLE(FrameZoomSGIX) +#define glFreeObjectBufferATI MANGLE(FreeObjectBufferATI) +#define glFrontFace MANGLE(FrontFace) +#define glFrustum MANGLE(Frustum) +#define glGenAsyncMarkersSGIX MANGLE(GenAsyncMarkersSGIX) +#define glGenBuffersARB MANGLE(GenBuffersARB) +#define glGenBuffers MANGLE(GenBuffers) +#define glGenerateMipmapEXT MANGLE(GenerateMipmapEXT) +#define glGenerateMipmap MANGLE(GenerateMipmap) +#define glGenerateMultiTexMipmapEXT MANGLE(GenerateMultiTexMipmapEXT) +#define glGenerateTextureMipmapEXT MANGLE(GenerateTextureMipmapEXT) +#define glGenFencesAPPLE MANGLE(GenFencesAPPLE) +#define glGenFencesNV MANGLE(GenFencesNV) +#define glGenFragmentShadersATI MANGLE(GenFragmentShadersATI) +#define glGenFramebuffersEXT MANGLE(GenFramebuffersEXT) +#define glGenFramebuffers MANGLE(GenFramebuffers) +#define glGenLists MANGLE(GenLists) +#define glGenNamesAMD MANGLE(GenNamesAMD) +#define glGenOcclusionQueriesNV MANGLE(GenOcclusionQueriesNV) +#define glGenPerfMonitorsAMD MANGLE(GenPerfMonitorsAMD) +#define glGenProgramPipelines MANGLE(GenProgramPipelines) +#define glGenProgramsARB MANGLE(GenProgramsARB) +#define glGenProgramsNV MANGLE(GenProgramsNV) +#define glGenQueriesARB MANGLE(GenQueriesARB) +#define glGenQueries MANGLE(GenQueries) +#define glGenRenderbuffersEXT MANGLE(GenRenderbuffersEXT) +#define glGenRenderbuffers MANGLE(GenRenderbuffers) +#define glGenSamplers MANGLE(GenSamplers) +#define glGenSymbolsEXT MANGLE(GenSymbolsEXT) +#define glGenTexturesEXT MANGLE(GenTexturesEXT) +#define glGenTextures MANGLE(GenTextures) +#define glGenTransformFeedbacks MANGLE(GenTransformFeedbacks) +#define glGenTransformFeedbacksNV MANGLE(GenTransformFeedbacksNV) +#define glGenVertexArraysAPPLE MANGLE(GenVertexArraysAPPLE) +#define glGenVertexArrays MANGLE(GenVertexArrays) +#define glGenVertexShadersEXT MANGLE(GenVertexShadersEXT) +#define glGetActiveAttribARB MANGLE(GetActiveAttribARB) +#define glGetActiveAttrib MANGLE(GetActiveAttrib) +#define glGetActiveSubroutineName MANGLE(GetActiveSubroutineName) +#define glGetActiveSubroutineUniformiv MANGLE(GetActiveSubroutineUniformiv) +#define glGetActiveSubroutineUniformName MANGLE(GetActiveSubroutineUniformName) +#define glGetActiveUniformARB MANGLE(GetActiveUniformARB) +#define glGetActiveUniformBlockiv MANGLE(GetActiveUniformBlockiv) +#define glGetActiveUniformBlockName MANGLE(GetActiveUniformBlockName) +#define glGetActiveUniform MANGLE(GetActiveUniform) +#define glGetActiveUniformName MANGLE(GetActiveUniformName) +#define glGetActiveUniformsiv MANGLE(GetActiveUniformsiv) +#define glGetActiveVaryingNV MANGLE(GetActiveVaryingNV) +#define glGetArrayObjectfvATI MANGLE(GetArrayObjectfvATI) +#define glGetArrayObjectivATI MANGLE(GetArrayObjectivATI) +#define glGetAttachedObjectsARB MANGLE(GetAttachedObjectsARB) +#define glGetAttachedShaders MANGLE(GetAttachedShaders) +#define glGetAttribLocationARB MANGLE(GetAttribLocationARB) +#define glGetAttribLocation MANGLE(GetAttribLocation) +#define glGetBooleanIndexedvEXT MANGLE(GetBooleanIndexedvEXT) +#define glGetBooleani_v MANGLE(GetBooleani_v) +#define glGetBooleanv MANGLE(GetBooleanv) +#define glGetBufferParameteri64v MANGLE(GetBufferParameteri64v) +#define glGetBufferParameterivARB MANGLE(GetBufferParameterivARB) +#define glGetBufferParameteriv MANGLE(GetBufferParameteriv) +#define glGetBufferParameterui64vNV MANGLE(GetBufferParameterui64vNV) +#define glGetBufferPointervARB MANGLE(GetBufferPointervARB) +#define glGetBufferPointerv MANGLE(GetBufferPointerv) +#define glGetBufferSubDataARB MANGLE(GetBufferSubDataARB) +#define glGetBufferSubData MANGLE(GetBufferSubData) +#define glGetClipPlane MANGLE(GetClipPlane) +#define glGetColorTableEXT MANGLE(GetColorTableEXT) +#define glGetColorTable MANGLE(GetColorTable) +#define glGetColorTableParameterfvEXT MANGLE(GetColorTableParameterfvEXT) +#define glGetColorTableParameterfv MANGLE(GetColorTableParameterfv) +#define glGetColorTableParameterfvSGI MANGLE(GetColorTableParameterfvSGI) +#define glGetColorTableParameterivEXT MANGLE(GetColorTableParameterivEXT) +#define glGetColorTableParameteriv MANGLE(GetColorTableParameteriv) +#define glGetColorTableParameterivSGI MANGLE(GetColorTableParameterivSGI) +#define glGetColorTableSGI MANGLE(GetColorTableSGI) +#define glGetCombinerInputParameterfvNV MANGLE(GetCombinerInputParameterfvNV) +#define glGetCombinerInputParameterivNV MANGLE(GetCombinerInputParameterivNV) +#define glGetCombinerOutputParameterfvNV MANGLE(GetCombinerOutputParameterfvNV) +#define glGetCombinerOutputParameterivNV MANGLE(GetCombinerOutputParameterivNV) +#define glGetCombinerStageParameterfvNV MANGLE(GetCombinerStageParameterfvNV) +#define glGetCompressedMultiTexImageEXT MANGLE(GetCompressedMultiTexImageEXT) +#define glGetCompressedTexImageARB MANGLE(GetCompressedTexImageARB) +#define glGetCompressedTexImage MANGLE(GetCompressedTexImage) +#define glGetCompressedTextureImageEXT MANGLE(GetCompressedTextureImageEXT) +#define glGetConvolutionFilterEXT MANGLE(GetConvolutionFilterEXT) +#define glGetConvolutionFilter MANGLE(GetConvolutionFilter) +#define glGetConvolutionParameterfvEXT MANGLE(GetConvolutionParameterfvEXT) +#define glGetConvolutionParameterfv MANGLE(GetConvolutionParameterfv) +#define glGetConvolutionParameterivEXT MANGLE(GetConvolutionParameterivEXT) +#define glGetConvolutionParameteriv MANGLE(GetConvolutionParameteriv) +#define glGetDebugLogLengthMESA MANGLE(GetDebugLogLengthMESA) +#define glGetDebugLogMESA MANGLE(GetDebugLogMESA) +#define glGetDebugMessageLogAMD MANGLE(GetDebugMessageLogAMD) +#define glGetDebugMessageLogARB MANGLE(GetDebugMessageLogARB) +#define glGetDetailTexFuncSGIS MANGLE(GetDetailTexFuncSGIS) +#define glGetDoubleIndexedvEXT MANGLE(GetDoubleIndexedvEXT) +#define glGetDoublei_v MANGLE(GetDoublei_v) +#define glGetDoublev MANGLE(GetDoublev) +#define glGetError MANGLE(GetError) +#define glGetFenceivNV MANGLE(GetFenceivNV) +#define glGetFinalCombinerInputParameterfvNV MANGLE(GetFinalCombinerInputParameterfvNV) +#define glGetFinalCombinerInputParameterivNV MANGLE(GetFinalCombinerInputParameterivNV) +#define glGetFloatIndexedvEXT MANGLE(GetFloatIndexedvEXT) +#define glGetFloati_v MANGLE(GetFloati_v) +#define glGetFloatv MANGLE(GetFloatv) +#define glGetFogFuncSGIS MANGLE(GetFogFuncSGIS) +#define glGetFragDataIndex MANGLE(GetFragDataIndex) +#define glGetFragDataLocationEXT MANGLE(GetFragDataLocationEXT) +#define glGetFragDataLocation MANGLE(GetFragDataLocation) +#define glGetFragmentLightfvSGIX MANGLE(GetFragmentLightfvSGIX) +#define glGetFragmentLightivSGIX MANGLE(GetFragmentLightivSGIX) +#define glGetFragmentMaterialfvSGIX MANGLE(GetFragmentMaterialfvSGIX) +#define glGetFragmentMaterialivSGIX MANGLE(GetFragmentMaterialivSGIX) +#define glGetFramebufferAttachmentParameterivEXT MANGLE(GetFramebufferAttachmentParameterivEXT) +#define glGetFramebufferAttachmentParameteriv MANGLE(GetFramebufferAttachmentParameteriv) +#define glGetFramebufferParameterivEXT MANGLE(GetFramebufferParameterivEXT) +#define glGetGraphicsResetStatusARB MANGLE(GetGraphicsResetStatusARB) +#define glGetHandleARB MANGLE(GetHandleARB) +#define glGetHistogramEXT MANGLE(GetHistogramEXT) +#define glGetHistogram MANGLE(GetHistogram) +#define glGetHistogramParameterfvEXT MANGLE(GetHistogramParameterfvEXT) +#define glGetHistogramParameterfv MANGLE(GetHistogramParameterfv) +#define glGetHistogramParameterivEXT MANGLE(GetHistogramParameterivEXT) +#define glGetHistogramParameteriv MANGLE(GetHistogramParameteriv) +#define glGetImageTransformParameterfvHP MANGLE(GetImageTransformParameterfvHP) +#define glGetImageTransformParameterivHP MANGLE(GetImageTransformParameterivHP) +#define glGetInfoLogARB MANGLE(GetInfoLogARB) +#define glGetInstrumentsSGIX MANGLE(GetInstrumentsSGIX) +#define glGetInteger64i_v MANGLE(GetInteger64i_v) +#define glGetInteger64v MANGLE(GetInteger64v) +#define glGetIntegerIndexedvEXT MANGLE(GetIntegerIndexedvEXT) +#define glGetIntegeri_v MANGLE(GetIntegeri_v) +#define glGetIntegerui64i_vNV MANGLE(GetIntegerui64i_vNV) +#define glGetIntegerui64vNV MANGLE(GetIntegerui64vNV) +#define glGetIntegerv MANGLE(GetIntegerv) +#define glGetInvariantBooleanvEXT MANGLE(GetInvariantBooleanvEXT) +#define glGetInvariantFloatvEXT MANGLE(GetInvariantFloatvEXT) +#define glGetInvariantIntegervEXT MANGLE(GetInvariantIntegervEXT) +#define glGetLightfv MANGLE(GetLightfv) +#define glGetLightiv MANGLE(GetLightiv) +#define glGetListParameterfvSGIX MANGLE(GetListParameterfvSGIX) +#define glGetListParameterivSGIX MANGLE(GetListParameterivSGIX) +#define glGetLocalConstantBooleanvEXT MANGLE(GetLocalConstantBooleanvEXT) +#define glGetLocalConstantFloatvEXT MANGLE(GetLocalConstantFloatvEXT) +#define glGetLocalConstantIntegervEXT MANGLE(GetLocalConstantIntegervEXT) +#define glGetMapAttribParameterfvNV MANGLE(GetMapAttribParameterfvNV) +#define glGetMapAttribParameterivNV MANGLE(GetMapAttribParameterivNV) +#define glGetMapControlPointsNV MANGLE(GetMapControlPointsNV) +#define glGetMapdv MANGLE(GetMapdv) +#define glGetMapfv MANGLE(GetMapfv) +#define glGetMapiv MANGLE(GetMapiv) +#define glGetMapParameterfvNV MANGLE(GetMapParameterfvNV) +#define glGetMapParameterivNV MANGLE(GetMapParameterivNV) +#define glGetMaterialfv MANGLE(GetMaterialfv) +#define glGetMaterialiv MANGLE(GetMaterialiv) +#define glGetMinmaxEXT MANGLE(GetMinmaxEXT) +#define glGetMinmax MANGLE(GetMinmax) +#define glGetMinmaxParameterfvEXT MANGLE(GetMinmaxParameterfvEXT) +#define glGetMinmaxParameterfv MANGLE(GetMinmaxParameterfv) +#define glGetMinmaxParameterivEXT MANGLE(GetMinmaxParameterivEXT) +#define glGetMinmaxParameteriv MANGLE(GetMinmaxParameteriv) +#define glGetMultisamplefv MANGLE(GetMultisamplefv) +#define glGetMultisamplefvNV MANGLE(GetMultisamplefvNV) +#define glGetMultiTexEnvfvEXT MANGLE(GetMultiTexEnvfvEXT) +#define glGetMultiTexEnvivEXT MANGLE(GetMultiTexEnvivEXT) +#define glGetMultiTexGendvEXT MANGLE(GetMultiTexGendvEXT) +#define glGetMultiTexGenfvEXT MANGLE(GetMultiTexGenfvEXT) +#define glGetMultiTexGenivEXT MANGLE(GetMultiTexGenivEXT) +#define glGetMultiTexImageEXT MANGLE(GetMultiTexImageEXT) +#define glGetMultiTexLevelParameterfvEXT MANGLE(GetMultiTexLevelParameterfvEXT) +#define glGetMultiTexLevelParameterivEXT MANGLE(GetMultiTexLevelParameterivEXT) +#define glGetMultiTexParameterfvEXT MANGLE(GetMultiTexParameterfvEXT) +#define glGetMultiTexParameterIivEXT MANGLE(GetMultiTexParameterIivEXT) +#define glGetMultiTexParameterIuivEXT MANGLE(GetMultiTexParameterIuivEXT) +#define glGetMultiTexParameterivEXT MANGLE(GetMultiTexParameterivEXT) +#define glGetNamedBufferParameterivEXT MANGLE(GetNamedBufferParameterivEXT) +#define glGetNamedBufferParameterui64vNV MANGLE(GetNamedBufferParameterui64vNV) +#define glGetNamedBufferPointervEXT MANGLE(GetNamedBufferPointervEXT) +#define glGetNamedBufferSubDataEXT MANGLE(GetNamedBufferSubDataEXT) +#define glGetNamedFramebufferAttachmentParameterivEXT MANGLE(GetNamedFramebufferAttachmentParameterivEXT) +#define glGetNamedProgramivEXT MANGLE(GetNamedProgramivEXT) +#define glGetNamedProgramLocalParameterdvEXT MANGLE(GetNamedProgramLocalParameterdvEXT) +#define glGetNamedProgramLocalParameterfvEXT MANGLE(GetNamedProgramLocalParameterfvEXT) +#define glGetNamedProgramLocalParameterIivEXT MANGLE(GetNamedProgramLocalParameterIivEXT) +#define glGetNamedProgramLocalParameterIuivEXT MANGLE(GetNamedProgramLocalParameterIuivEXT) +#define glGetNamedProgramStringEXT MANGLE(GetNamedProgramStringEXT) +#define glGetNamedRenderbufferParameterivEXT MANGLE(GetNamedRenderbufferParameterivEXT) +#define glGetNamedStringARB MANGLE(GetNamedStringARB) +#define glGetNamedStringivARB MANGLE(GetNamedStringivARB) +#define glGetnColorTableARB MANGLE(GetnColorTableARB) +#define glGetnCompressedTexImageARB MANGLE(GetnCompressedTexImageARB) +#define glGetnConvolutionFilterARB MANGLE(GetnConvolutionFilterARB) +#define glGetnHistogramARB MANGLE(GetnHistogramARB) +#define glGetnMapdvARB MANGLE(GetnMapdvARB) +#define glGetnMapfvARB MANGLE(GetnMapfvARB) +#define glGetnMapivARB MANGLE(GetnMapivARB) +#define glGetnMinmaxARB MANGLE(GetnMinmaxARB) +#define glGetnPixelMapfvARB MANGLE(GetnPixelMapfvARB) +#define glGetnPixelMapuivARB MANGLE(GetnPixelMapuivARB) +#define glGetnPixelMapusvARB MANGLE(GetnPixelMapusvARB) +#define glGetnPolygonStippleARB MANGLE(GetnPolygonStippleARB) +#define glGetnSeparableFilterARB MANGLE(GetnSeparableFilterARB) +#define glGetnTexImageARB MANGLE(GetnTexImageARB) +#define glGetnUniformdvARB MANGLE(GetnUniformdvARB) +#define glGetnUniformfvARB MANGLE(GetnUniformfvARB) +#define glGetnUniformivARB MANGLE(GetnUniformivARB) +#define glGetnUniformuivARB MANGLE(GetnUniformuivARB) +#define glGetObjectBufferfvATI MANGLE(GetObjectBufferfvATI) +#define glGetObjectBufferivATI MANGLE(GetObjectBufferivATI) +#define glGetObjectParameterfvARB MANGLE(GetObjectParameterfvARB) +#define glGetObjectParameterivAPPLE MANGLE(GetObjectParameterivAPPLE) +#define glGetObjectParameterivARB MANGLE(GetObjectParameterivARB) +#define glGetOcclusionQueryivNV MANGLE(GetOcclusionQueryivNV) +#define glGetOcclusionQueryuivNV MANGLE(GetOcclusionQueryuivNV) +#define glGetPerfMonitorCounterDataAMD MANGLE(GetPerfMonitorCounterDataAMD) +#define glGetPerfMonitorCounterInfoAMD MANGLE(GetPerfMonitorCounterInfoAMD) +#define glGetPerfMonitorCountersAMD MANGLE(GetPerfMonitorCountersAMD) +#define glGetPerfMonitorCounterStringAMD MANGLE(GetPerfMonitorCounterStringAMD) +#define glGetPerfMonitorGroupsAMD MANGLE(GetPerfMonitorGroupsAMD) +#define glGetPerfMonitorGroupStringAMD MANGLE(GetPerfMonitorGroupStringAMD) +#define glGetPixelMapfv MANGLE(GetPixelMapfv) +#define glGetPixelMapuiv MANGLE(GetPixelMapuiv) +#define glGetPixelMapusv MANGLE(GetPixelMapusv) +#define glGetPixelTexGenParameterfvSGIS MANGLE(GetPixelTexGenParameterfvSGIS) +#define glGetPixelTexGenParameterivSGIS MANGLE(GetPixelTexGenParameterivSGIS) +#define glGetPointerIndexedvEXT MANGLE(GetPointerIndexedvEXT) +#define glGetPointervEXT MANGLE(GetPointervEXT) +#define glGetPointerv MANGLE(GetPointerv) +#define glGetPolygonStipple MANGLE(GetPolygonStipple) +#define glGetProgramBinary MANGLE(GetProgramBinary) +#define glGetProgramEnvParameterdvARB MANGLE(GetProgramEnvParameterdvARB) +#define glGetProgramEnvParameterfvARB MANGLE(GetProgramEnvParameterfvARB) +#define glGetProgramEnvParameterIivNV MANGLE(GetProgramEnvParameterIivNV) +#define glGetProgramEnvParameterIuivNV MANGLE(GetProgramEnvParameterIuivNV) +#define glGetProgramInfoLog MANGLE(GetProgramInfoLog) +#define glGetProgramivARB MANGLE(GetProgramivARB) +#define glGetProgramiv MANGLE(GetProgramiv) +#define glGetProgramivNV MANGLE(GetProgramivNV) +#define glGetProgramLocalParameterdvARB MANGLE(GetProgramLocalParameterdvARB) +#define glGetProgramLocalParameterfvARB MANGLE(GetProgramLocalParameterfvARB) +#define glGetProgramLocalParameterIivNV MANGLE(GetProgramLocalParameterIivNV) +#define glGetProgramLocalParameterIuivNV MANGLE(GetProgramLocalParameterIuivNV) +#define glGetProgramNamedParameterdvNV MANGLE(GetProgramNamedParameterdvNV) +#define glGetProgramNamedParameterfvNV MANGLE(GetProgramNamedParameterfvNV) +#define glGetProgramParameterdvNV MANGLE(GetProgramParameterdvNV) +#define glGetProgramParameterfvNV MANGLE(GetProgramParameterfvNV) +#define glGetProgramPipelineInfoLog MANGLE(GetProgramPipelineInfoLog) +#define glGetProgramPipelineiv MANGLE(GetProgramPipelineiv) +#define glGetProgramRegisterfvMESA MANGLE(GetProgramRegisterfvMESA) +#define glGetProgramStageiv MANGLE(GetProgramStageiv) +#define glGetProgramStringARB MANGLE(GetProgramStringARB) +#define glGetProgramStringNV MANGLE(GetProgramStringNV) +#define glGetProgramSubroutineParameteruivNV MANGLE(GetProgramSubroutineParameteruivNV) +#define glGetQueryIndexediv MANGLE(GetQueryIndexediv) +#define glGetQueryivARB MANGLE(GetQueryivARB) +#define glGetQueryiv MANGLE(GetQueryiv) +#define glGetQueryObjecti64vEXT MANGLE(GetQueryObjecti64vEXT) +#define glGetQueryObjecti64v MANGLE(GetQueryObjecti64v) +#define glGetQueryObjectivARB MANGLE(GetQueryObjectivARB) +#define glGetQueryObjectiv MANGLE(GetQueryObjectiv) +#define glGetQueryObjectui64vEXT MANGLE(GetQueryObjectui64vEXT) +#define glGetQueryObjectui64v MANGLE(GetQueryObjectui64v) +#define glGetQueryObjectuivARB MANGLE(GetQueryObjectuivARB) +#define glGetQueryObjectuiv MANGLE(GetQueryObjectuiv) +#define glGetRenderbufferParameterivEXT MANGLE(GetRenderbufferParameterivEXT) +#define glGetRenderbufferParameteriv MANGLE(GetRenderbufferParameteriv) +#define glGetSamplerParameterfv MANGLE(GetSamplerParameterfv) +#define glGetSamplerParameterIiv MANGLE(GetSamplerParameterIiv) +#define glGetSamplerParameterIuiv MANGLE(GetSamplerParameterIuiv) +#define glGetSamplerParameteriv MANGLE(GetSamplerParameteriv) +#define glGetSeparableFilterEXT MANGLE(GetSeparableFilterEXT) +#define glGetSeparableFilter MANGLE(GetSeparableFilter) +#define glGetShaderInfoLog MANGLE(GetShaderInfoLog) +#define glGetShaderiv MANGLE(GetShaderiv) +#define glGetShaderPrecisionFormat MANGLE(GetShaderPrecisionFormat) +#define glGetShaderSourceARB MANGLE(GetShaderSourceARB) +#define glGetShaderSource MANGLE(GetShaderSource) +#define glGetSharpenTexFuncSGIS MANGLE(GetSharpenTexFuncSGIS) +#define glGetStringi MANGLE(GetStringi) +#define glGetString MANGLE(GetString) +#define glGetSubroutineIndex MANGLE(GetSubroutineIndex) +#define glGetSubroutineUniformLocation MANGLE(GetSubroutineUniformLocation) +#define glGetSynciv MANGLE(GetSynciv) +#define glGetTexBumpParameterfvATI MANGLE(GetTexBumpParameterfvATI) +#define glGetTexBumpParameterivATI MANGLE(GetTexBumpParameterivATI) +#define glGetTexEnvfv MANGLE(GetTexEnvfv) +#define glGetTexEnviv MANGLE(GetTexEnviv) +#define glGetTexFilterFuncSGIS MANGLE(GetTexFilterFuncSGIS) +#define glGetTexGendv MANGLE(GetTexGendv) +#define glGetTexGenfv MANGLE(GetTexGenfv) +#define glGetTexGeniv MANGLE(GetTexGeniv) +#define glGetTexImage MANGLE(GetTexImage) +#define glGetTexLevelParameterfv MANGLE(GetTexLevelParameterfv) +#define glGetTexLevelParameteriv MANGLE(GetTexLevelParameteriv) +#define glGetTexParameterfv MANGLE(GetTexParameterfv) +#define glGetTexParameterIivEXT MANGLE(GetTexParameterIivEXT) +#define glGetTexParameterIiv MANGLE(GetTexParameterIiv) +#define glGetTexParameterIuivEXT MANGLE(GetTexParameterIuivEXT) +#define glGetTexParameterIuiv MANGLE(GetTexParameterIuiv) +#define glGetTexParameteriv MANGLE(GetTexParameteriv) +#define glGetTexParameterPointervAPPLE MANGLE(GetTexParameterPointervAPPLE) +#define glGetTextureImageEXT MANGLE(GetTextureImageEXT) +#define glGetTextureLevelParameterfvEXT MANGLE(GetTextureLevelParameterfvEXT) +#define glGetTextureLevelParameterivEXT MANGLE(GetTextureLevelParameterivEXT) +#define glGetTextureParameterfvEXT MANGLE(GetTextureParameterfvEXT) +#define glGetTextureParameterIivEXT MANGLE(GetTextureParameterIivEXT) +#define glGetTextureParameterIuivEXT MANGLE(GetTextureParameterIuivEXT) +#define glGetTextureParameterivEXT MANGLE(GetTextureParameterivEXT) +#define glGetTrackMatrixivNV MANGLE(GetTrackMatrixivNV) +#define glGetTransformFeedbackVaryingEXT MANGLE(GetTransformFeedbackVaryingEXT) +#define glGetTransformFeedbackVarying MANGLE(GetTransformFeedbackVarying) +#define glGetTransformFeedbackVaryingNV MANGLE(GetTransformFeedbackVaryingNV) +#define glGetUniformBlockIndex MANGLE(GetUniformBlockIndex) +#define glGetUniformBufferSizeEXT MANGLE(GetUniformBufferSizeEXT) +#define glGetUniformdv MANGLE(GetUniformdv) +#define glGetUniformfvARB MANGLE(GetUniformfvARB) +#define glGetUniformfv MANGLE(GetUniformfv) +#define glGetUniformi64vNV MANGLE(GetUniformi64vNV) +#define glGetUniformIndices MANGLE(GetUniformIndices) +#define glGetUniformivARB MANGLE(GetUniformivARB) +#define glGetUniformiv MANGLE(GetUniformiv) +#define glGetUniformLocationARB MANGLE(GetUniformLocationARB) +#define glGetUniformLocation MANGLE(GetUniformLocation) +#define glGetUniformOffsetEXT MANGLE(GetUniformOffsetEXT) +#define glGetUniformSubroutineuiv MANGLE(GetUniformSubroutineuiv) +#define glGetUniformui64vNV MANGLE(GetUniformui64vNV) +#define glGetUniformuivEXT MANGLE(GetUniformuivEXT) +#define glGetUniformuiv MANGLE(GetUniformuiv) +#define glGetVariantArrayObjectfvATI MANGLE(GetVariantArrayObjectfvATI) +#define glGetVariantArrayObjectivATI MANGLE(GetVariantArrayObjectivATI) +#define glGetVariantBooleanvEXT MANGLE(GetVariantBooleanvEXT) +#define glGetVariantFloatvEXT MANGLE(GetVariantFloatvEXT) +#define glGetVariantIntegervEXT MANGLE(GetVariantIntegervEXT) +#define glGetVariantPointervEXT MANGLE(GetVariantPointervEXT) +#define glGetVaryingLocationNV MANGLE(GetVaryingLocationNV) +#define glGetVertexAttribArrayObjectfvATI MANGLE(GetVertexAttribArrayObjectfvATI) +#define glGetVertexAttribArrayObjectivATI MANGLE(GetVertexAttribArrayObjectivATI) +#define glGetVertexAttribdvARB MANGLE(GetVertexAttribdvARB) +#define glGetVertexAttribdv MANGLE(GetVertexAttribdv) +#define glGetVertexAttribdvNV MANGLE(GetVertexAttribdvNV) +#define glGetVertexAttribfvARB MANGLE(GetVertexAttribfvARB) +#define glGetVertexAttribfv MANGLE(GetVertexAttribfv) +#define glGetVertexAttribfvNV MANGLE(GetVertexAttribfvNV) +#define glGetVertexAttribIivEXT MANGLE(GetVertexAttribIivEXT) +#define glGetVertexAttribIiv MANGLE(GetVertexAttribIiv) +#define glGetVertexAttribIuivEXT MANGLE(GetVertexAttribIuivEXT) +#define glGetVertexAttribIuiv MANGLE(GetVertexAttribIuiv) +#define glGetVertexAttribivARB MANGLE(GetVertexAttribivARB) +#define glGetVertexAttribiv MANGLE(GetVertexAttribiv) +#define glGetVertexAttribivNV MANGLE(GetVertexAttribivNV) +#define glGetVertexAttribLdvEXT MANGLE(GetVertexAttribLdvEXT) +#define glGetVertexAttribLdv MANGLE(GetVertexAttribLdv) +#define glGetVertexAttribLi64vNV MANGLE(GetVertexAttribLi64vNV) +#define glGetVertexAttribLui64vNV MANGLE(GetVertexAttribLui64vNV) +#define glGetVertexAttribPointervARB MANGLE(GetVertexAttribPointervARB) +#define glGetVertexAttribPointerv MANGLE(GetVertexAttribPointerv) +#define glGetVertexAttribPointervNV MANGLE(GetVertexAttribPointervNV) +#define glGetVideoCaptureivNV MANGLE(GetVideoCaptureivNV) +#define glGetVideoCaptureStreamdvNV MANGLE(GetVideoCaptureStreamdvNV) +#define glGetVideoCaptureStreamfvNV MANGLE(GetVideoCaptureStreamfvNV) +#define glGetVideoCaptureStreamivNV MANGLE(GetVideoCaptureStreamivNV) +#define glGetVideoi64vNV MANGLE(GetVideoi64vNV) +#define glGetVideoivNV MANGLE(GetVideoivNV) +#define glGetVideoui64vNV MANGLE(GetVideoui64vNV) +#define glGetVideouivNV MANGLE(GetVideouivNV) +#define glGlobalAlphaFactorbSUN MANGLE(GlobalAlphaFactorbSUN) +#define glGlobalAlphaFactordSUN MANGLE(GlobalAlphaFactordSUN) +#define glGlobalAlphaFactorfSUN MANGLE(GlobalAlphaFactorfSUN) +#define glGlobalAlphaFactoriSUN MANGLE(GlobalAlphaFactoriSUN) +#define glGlobalAlphaFactorsSUN MANGLE(GlobalAlphaFactorsSUN) +#define glGlobalAlphaFactorubSUN MANGLE(GlobalAlphaFactorubSUN) +#define glGlobalAlphaFactoruiSUN MANGLE(GlobalAlphaFactoruiSUN) +#define glGlobalAlphaFactorusSUN MANGLE(GlobalAlphaFactorusSUN) +#define glHint MANGLE(Hint) +#define glHintPGI MANGLE(HintPGI) +#define glHistogramEXT MANGLE(HistogramEXT) +#define glHistogram MANGLE(Histogram) +#define glIglooInterfaceSGIX MANGLE(IglooInterfaceSGIX) +#define glImageTransformParameterfHP MANGLE(ImageTransformParameterfHP) +#define glImageTransformParameterfvHP MANGLE(ImageTransformParameterfvHP) +#define glImageTransformParameteriHP MANGLE(ImageTransformParameteriHP) +#define glImageTransformParameterivHP MANGLE(ImageTransformParameterivHP) +#define glIndexd MANGLE(Indexd) +#define glIndexdv MANGLE(Indexdv) +#define glIndexf MANGLE(Indexf) +#define glIndexFormatNV MANGLE(IndexFormatNV) +#define glIndexFuncEXT MANGLE(IndexFuncEXT) +#define glIndexfv MANGLE(Indexfv) +#define glIndexi MANGLE(Indexi) +#define glIndexiv MANGLE(Indexiv) +#define glIndexMask MANGLE(IndexMask) +#define glIndexMaterialEXT MANGLE(IndexMaterialEXT) +#define glIndexPointerEXT MANGLE(IndexPointerEXT) +#define glIndexPointerListIBM MANGLE(IndexPointerListIBM) +#define glIndexPointer MANGLE(IndexPointer) +#define glIndexs MANGLE(Indexs) +#define glIndexsv MANGLE(Indexsv) +#define glIndexub MANGLE(Indexub) +#define glIndexubv MANGLE(Indexubv) +#define glInitNames MANGLE(InitNames) +#define glInsertComponentEXT MANGLE(InsertComponentEXT) +#define glInstrumentsBufferSGIX MANGLE(InstrumentsBufferSGIX) +#define glInterleavedArrays MANGLE(InterleavedArrays) +#define glIsAsyncMarkerSGIX MANGLE(IsAsyncMarkerSGIX) +#define glIsBufferARB MANGLE(IsBufferARB) +#define glIsBuffer MANGLE(IsBuffer) +#define glIsBufferResidentNV MANGLE(IsBufferResidentNV) +#define glIsEnabledi MANGLE(IsEnabledi) +#define glIsEnabledIndexedEXT MANGLE(IsEnabledIndexedEXT) +#define glIsEnabled MANGLE(IsEnabled) +#define glIsFenceAPPLE MANGLE(IsFenceAPPLE) +#define glIsFenceNV MANGLE(IsFenceNV) +#define glIsFramebufferEXT MANGLE(IsFramebufferEXT) +#define glIsFramebuffer MANGLE(IsFramebuffer) +#define glIsList MANGLE(IsList) +#define glIsNameAMD MANGLE(IsNameAMD) +#define glIsNamedBufferResidentNV MANGLE(IsNamedBufferResidentNV) +#define glIsNamedStringARB MANGLE(IsNamedStringARB) +#define glIsObjectBufferATI MANGLE(IsObjectBufferATI) +#define glIsOcclusionQueryNV MANGLE(IsOcclusionQueryNV) +#define glIsProgramARB MANGLE(IsProgramARB) +#define glIsProgram MANGLE(IsProgram) +#define glIsProgramNV MANGLE(IsProgramNV) +#define glIsProgramPipeline MANGLE(IsProgramPipeline) +#define glIsQueryARB MANGLE(IsQueryARB) +#define glIsQuery MANGLE(IsQuery) +#define glIsRenderbufferEXT MANGLE(IsRenderbufferEXT) +#define glIsRenderbuffer MANGLE(IsRenderbuffer) +#define glIsSampler MANGLE(IsSampler) +#define glIsShader MANGLE(IsShader) +#define glIsSync MANGLE(IsSync) +#define glIsTextureEXT MANGLE(IsTextureEXT) +#define glIsTexture MANGLE(IsTexture) +#define glIsTransformFeedback MANGLE(IsTransformFeedback) +#define glIsTransformFeedbackNV MANGLE(IsTransformFeedbackNV) +#define glIsVariantEnabledEXT MANGLE(IsVariantEnabledEXT) +#define glIsVertexArrayAPPLE MANGLE(IsVertexArrayAPPLE) +#define glIsVertexArray MANGLE(IsVertexArray) +#define glIsVertexAttribEnabledAPPLE MANGLE(IsVertexAttribEnabledAPPLE) +#define glLightEnviSGIX MANGLE(LightEnviSGIX) +#define glLightf MANGLE(Lightf) +#define glLightfv MANGLE(Lightfv) +#define glLighti MANGLE(Lighti) +#define glLightiv MANGLE(Lightiv) +#define glLightModelf MANGLE(LightModelf) +#define glLightModelfv MANGLE(LightModelfv) +#define glLightModeli MANGLE(LightModeli) +#define glLightModeliv MANGLE(LightModeliv) +#define glLineStipple MANGLE(LineStipple) +#define glLineWidth MANGLE(LineWidth) +#define glLinkProgramARB MANGLE(LinkProgramARB) +#define glLinkProgram MANGLE(LinkProgram) +#define glListBase MANGLE(ListBase) +#define glListParameterfSGIX MANGLE(ListParameterfSGIX) +#define glListParameterfvSGIX MANGLE(ListParameterfvSGIX) +#define glListParameteriSGIX MANGLE(ListParameteriSGIX) +#define glListParameterivSGIX MANGLE(ListParameterivSGIX) +#define glLoadIdentityDeformationMapSGIX MANGLE(LoadIdentityDeformationMapSGIX) +#define glLoadIdentity MANGLE(LoadIdentity) +#define glLoadMatrixd MANGLE(LoadMatrixd) +#define glLoadMatrixf MANGLE(LoadMatrixf) +#define glLoadName MANGLE(LoadName) +#define glLoadProgramNV MANGLE(LoadProgramNV) +#define glLoadTransposeMatrixdARB MANGLE(LoadTransposeMatrixdARB) +#define glLoadTransposeMatrixd MANGLE(LoadTransposeMatrixd) +#define glLoadTransposeMatrixfARB MANGLE(LoadTransposeMatrixfARB) +#define glLoadTransposeMatrixf MANGLE(LoadTransposeMatrixf) +#define glLockArraysEXT MANGLE(LockArraysEXT) +#define glLogicOp MANGLE(LogicOp) +#define glMakeBufferNonResidentNV MANGLE(MakeBufferNonResidentNV) +#define glMakeBufferResidentNV MANGLE(MakeBufferResidentNV) +#define glMakeNamedBufferNonResidentNV MANGLE(MakeNamedBufferNonResidentNV) +#define glMakeNamedBufferResidentNV MANGLE(MakeNamedBufferResidentNV) +#define glMap1d MANGLE(Map1d) +#define glMap1f MANGLE(Map1f) +#define glMap2d MANGLE(Map2d) +#define glMap2f MANGLE(Map2f) +#define glMapBufferARB MANGLE(MapBufferARB) +#define glMapBuffer MANGLE(MapBuffer) +#define glMapBufferRange MANGLE(MapBufferRange) +#define glMapControlPointsNV MANGLE(MapControlPointsNV) +#define glMapGrid1d MANGLE(MapGrid1d) +#define glMapGrid1f MANGLE(MapGrid1f) +#define glMapGrid2d MANGLE(MapGrid2d) +#define glMapGrid2f MANGLE(MapGrid2f) +#define glMapNamedBufferEXT MANGLE(MapNamedBufferEXT) +#define glMapNamedBufferRangeEXT MANGLE(MapNamedBufferRangeEXT) +#define glMapObjectBufferATI MANGLE(MapObjectBufferATI) +#define glMapParameterfvNV MANGLE(MapParameterfvNV) +#define glMapParameterivNV MANGLE(MapParameterivNV) +#define glMapVertexAttrib1dAPPLE MANGLE(MapVertexAttrib1dAPPLE) +#define glMapVertexAttrib1fAPPLE MANGLE(MapVertexAttrib1fAPPLE) +#define glMapVertexAttrib2dAPPLE MANGLE(MapVertexAttrib2dAPPLE) +#define glMapVertexAttrib2fAPPLE MANGLE(MapVertexAttrib2fAPPLE) +#define glMaterialf MANGLE(Materialf) +#define glMaterialfv MANGLE(Materialfv) +#define glMateriali MANGLE(Materiali) +#define glMaterialiv MANGLE(Materialiv) +#define glMatrixFrustumEXT MANGLE(MatrixFrustumEXT) +#define glMatrixIndexPointerARB MANGLE(MatrixIndexPointerARB) +#define glMatrixIndexubvARB MANGLE(MatrixIndexubvARB) +#define glMatrixIndexuivARB MANGLE(MatrixIndexuivARB) +#define glMatrixIndexusvARB MANGLE(MatrixIndexusvARB) +#define glMatrixLoaddEXT MANGLE(MatrixLoaddEXT) +#define glMatrixLoadfEXT MANGLE(MatrixLoadfEXT) +#define glMatrixLoadIdentityEXT MANGLE(MatrixLoadIdentityEXT) +#define glMatrixLoadTransposedEXT MANGLE(MatrixLoadTransposedEXT) +#define glMatrixLoadTransposefEXT MANGLE(MatrixLoadTransposefEXT) +#define glMatrixMode MANGLE(MatrixMode) +#define glMatrixMultdEXT MANGLE(MatrixMultdEXT) +#define glMatrixMultfEXT MANGLE(MatrixMultfEXT) +#define glMatrixMultTransposedEXT MANGLE(MatrixMultTransposedEXT) +#define glMatrixMultTransposefEXT MANGLE(MatrixMultTransposefEXT) +#define glMatrixOrthoEXT MANGLE(MatrixOrthoEXT) +#define glMatrixPopEXT MANGLE(MatrixPopEXT) +#define glMatrixPushEXT MANGLE(MatrixPushEXT) +#define glMatrixRotatedEXT MANGLE(MatrixRotatedEXT) +#define glMatrixRotatefEXT MANGLE(MatrixRotatefEXT) +#define glMatrixScaledEXT MANGLE(MatrixScaledEXT) +#define glMatrixScalefEXT MANGLE(MatrixScalefEXT) +#define glMatrixTranslatedEXT MANGLE(MatrixTranslatedEXT) +#define glMatrixTranslatefEXT MANGLE(MatrixTranslatefEXT) +#define glMemoryBarrierEXT MANGLE(MemoryBarrierEXT) +#define glMinmaxEXT MANGLE(MinmaxEXT) +#define glMinmax MANGLE(Minmax) +#define glMinSampleShadingARB MANGLE(MinSampleShadingARB) +#define glMinSampleShading MANGLE(MinSampleShading) +#define glMultiDrawArraysEXT MANGLE(MultiDrawArraysEXT) +#define glMultiDrawArrays MANGLE(MultiDrawArrays) +#define glMultiDrawElementArrayAPPLE MANGLE(MultiDrawElementArrayAPPLE) +#define glMultiDrawElementsBaseVertex MANGLE(MultiDrawElementsBaseVertex) +#define glMultiDrawElementsEXT MANGLE(MultiDrawElementsEXT) +#define glMultiDrawElements MANGLE(MultiDrawElements) +#define glMultiDrawRangeElementArrayAPPLE MANGLE(MultiDrawRangeElementArrayAPPLE) +#define glMultiModeDrawArraysIBM MANGLE(MultiModeDrawArraysIBM) +#define glMultiModeDrawElementsIBM MANGLE(MultiModeDrawElementsIBM) +#define glMultiTexBufferEXT MANGLE(MultiTexBufferEXT) +#define glMultiTexCoord1dARB MANGLE(MultiTexCoord1dARB) +#define glMultiTexCoord1d MANGLE(MultiTexCoord1d) +#define glMultiTexCoord1dvARB MANGLE(MultiTexCoord1dvARB) +#define glMultiTexCoord1dv MANGLE(MultiTexCoord1dv) +#define glMultiTexCoord1fARB MANGLE(MultiTexCoord1fARB) +#define glMultiTexCoord1f MANGLE(MultiTexCoord1f) +#define glMultiTexCoord1fvARB MANGLE(MultiTexCoord1fvARB) +#define glMultiTexCoord1fv MANGLE(MultiTexCoord1fv) +#define glMultiTexCoord1hNV MANGLE(MultiTexCoord1hNV) +#define glMultiTexCoord1hvNV MANGLE(MultiTexCoord1hvNV) +#define glMultiTexCoord1iARB MANGLE(MultiTexCoord1iARB) +#define glMultiTexCoord1i MANGLE(MultiTexCoord1i) +#define glMultiTexCoord1ivARB MANGLE(MultiTexCoord1ivARB) +#define glMultiTexCoord1iv MANGLE(MultiTexCoord1iv) +#define glMultiTexCoord1sARB MANGLE(MultiTexCoord1sARB) +#define glMultiTexCoord1s MANGLE(MultiTexCoord1s) +#define glMultiTexCoord1svARB MANGLE(MultiTexCoord1svARB) +#define glMultiTexCoord1sv MANGLE(MultiTexCoord1sv) +#define glMultiTexCoord2dARB MANGLE(MultiTexCoord2dARB) +#define glMultiTexCoord2d MANGLE(MultiTexCoord2d) +#define glMultiTexCoord2dvARB MANGLE(MultiTexCoord2dvARB) +#define glMultiTexCoord2dv MANGLE(MultiTexCoord2dv) +#define glMultiTexCoord2fARB MANGLE(MultiTexCoord2fARB) +#define glMultiTexCoord2f MANGLE(MultiTexCoord2f) +#define glMultiTexCoord2fvARB MANGLE(MultiTexCoord2fvARB) +#define glMultiTexCoord2fv MANGLE(MultiTexCoord2fv) +#define glMultiTexCoord2hNV MANGLE(MultiTexCoord2hNV) +#define glMultiTexCoord2hvNV MANGLE(MultiTexCoord2hvNV) +#define glMultiTexCoord2iARB MANGLE(MultiTexCoord2iARB) +#define glMultiTexCoord2i MANGLE(MultiTexCoord2i) +#define glMultiTexCoord2ivARB MANGLE(MultiTexCoord2ivARB) +#define glMultiTexCoord2iv MANGLE(MultiTexCoord2iv) +#define glMultiTexCoord2sARB MANGLE(MultiTexCoord2sARB) +#define glMultiTexCoord2s MANGLE(MultiTexCoord2s) +#define glMultiTexCoord2svARB MANGLE(MultiTexCoord2svARB) +#define glMultiTexCoord2sv MANGLE(MultiTexCoord2sv) +#define glMultiTexCoord3dARB MANGLE(MultiTexCoord3dARB) +#define glMultiTexCoord3d MANGLE(MultiTexCoord3d) +#define glMultiTexCoord3dvARB MANGLE(MultiTexCoord3dvARB) +#define glMultiTexCoord3dv MANGLE(MultiTexCoord3dv) +#define glMultiTexCoord3fARB MANGLE(MultiTexCoord3fARB) +#define glMultiTexCoord3f MANGLE(MultiTexCoord3f) +#define glMultiTexCoord3fvARB MANGLE(MultiTexCoord3fvARB) +#define glMultiTexCoord3fv MANGLE(MultiTexCoord3fv) +#define glMultiTexCoord3hNV MANGLE(MultiTexCoord3hNV) +#define glMultiTexCoord3hvNV MANGLE(MultiTexCoord3hvNV) +#define glMultiTexCoord3iARB MANGLE(MultiTexCoord3iARB) +#define glMultiTexCoord3i MANGLE(MultiTexCoord3i) +#define glMultiTexCoord3ivARB MANGLE(MultiTexCoord3ivARB) +#define glMultiTexCoord3iv MANGLE(MultiTexCoord3iv) +#define glMultiTexCoord3sARB MANGLE(MultiTexCoord3sARB) +#define glMultiTexCoord3s MANGLE(MultiTexCoord3s) +#define glMultiTexCoord3svARB MANGLE(MultiTexCoord3svARB) +#define glMultiTexCoord3sv MANGLE(MultiTexCoord3sv) +#define glMultiTexCoord4dARB MANGLE(MultiTexCoord4dARB) +#define glMultiTexCoord4d MANGLE(MultiTexCoord4d) +#define glMultiTexCoord4dvARB MANGLE(MultiTexCoord4dvARB) +#define glMultiTexCoord4dv MANGLE(MultiTexCoord4dv) +#define glMultiTexCoord4fARB MANGLE(MultiTexCoord4fARB) +#define glMultiTexCoord4f MANGLE(MultiTexCoord4f) +#define glMultiTexCoord4fvARB MANGLE(MultiTexCoord4fvARB) +#define glMultiTexCoord4fv MANGLE(MultiTexCoord4fv) +#define glMultiTexCoord4hNV MANGLE(MultiTexCoord4hNV) +#define glMultiTexCoord4hvNV MANGLE(MultiTexCoord4hvNV) +#define glMultiTexCoord4iARB MANGLE(MultiTexCoord4iARB) +#define glMultiTexCoord4i MANGLE(MultiTexCoord4i) +#define glMultiTexCoord4ivARB MANGLE(MultiTexCoord4ivARB) +#define glMultiTexCoord4iv MANGLE(MultiTexCoord4iv) +#define glMultiTexCoord4sARB MANGLE(MultiTexCoord4sARB) +#define glMultiTexCoord4s MANGLE(MultiTexCoord4s) +#define glMultiTexCoord4svARB MANGLE(MultiTexCoord4svARB) +#define glMultiTexCoord4sv MANGLE(MultiTexCoord4sv) +#define glMultiTexCoordP1ui MANGLE(MultiTexCoordP1ui) +#define glMultiTexCoordP1uiv MANGLE(MultiTexCoordP1uiv) +#define glMultiTexCoordP2ui MANGLE(MultiTexCoordP2ui) +#define glMultiTexCoordP2uiv MANGLE(MultiTexCoordP2uiv) +#define glMultiTexCoordP3ui MANGLE(MultiTexCoordP3ui) +#define glMultiTexCoordP3uiv MANGLE(MultiTexCoordP3uiv) +#define glMultiTexCoordP4ui MANGLE(MultiTexCoordP4ui) +#define glMultiTexCoordP4uiv MANGLE(MultiTexCoordP4uiv) +#define glMultiTexCoordPointerEXT MANGLE(MultiTexCoordPointerEXT) +#define glMultiTexEnvfEXT MANGLE(MultiTexEnvfEXT) +#define glMultiTexEnvfvEXT MANGLE(MultiTexEnvfvEXT) +#define glMultiTexEnviEXT MANGLE(MultiTexEnviEXT) +#define glMultiTexEnvivEXT MANGLE(MultiTexEnvivEXT) +#define glMultiTexGendEXT MANGLE(MultiTexGendEXT) +#define glMultiTexGendvEXT MANGLE(MultiTexGendvEXT) +#define glMultiTexGenfEXT MANGLE(MultiTexGenfEXT) +#define glMultiTexGenfvEXT MANGLE(MultiTexGenfvEXT) +#define glMultiTexGeniEXT MANGLE(MultiTexGeniEXT) +#define glMultiTexGenivEXT MANGLE(MultiTexGenivEXT) +#define glMultiTexImage1DEXT MANGLE(MultiTexImage1DEXT) +#define glMultiTexImage2DEXT MANGLE(MultiTexImage2DEXT) +#define glMultiTexImage3DEXT MANGLE(MultiTexImage3DEXT) +#define glMultiTexParameterfEXT MANGLE(MultiTexParameterfEXT) +#define glMultiTexParameterfvEXT MANGLE(MultiTexParameterfvEXT) +#define glMultiTexParameteriEXT MANGLE(MultiTexParameteriEXT) +#define glMultiTexParameterIivEXT MANGLE(MultiTexParameterIivEXT) +#define glMultiTexParameterIuivEXT MANGLE(MultiTexParameterIuivEXT) +#define glMultiTexParameterivEXT MANGLE(MultiTexParameterivEXT) +#define glMultiTexRenderbufferEXT MANGLE(MultiTexRenderbufferEXT) +#define glMultiTexSubImage1DEXT MANGLE(MultiTexSubImage1DEXT) +#define glMultiTexSubImage2DEXT MANGLE(MultiTexSubImage2DEXT) +#define glMultiTexSubImage3DEXT MANGLE(MultiTexSubImage3DEXT) +#define glMultMatrixd MANGLE(MultMatrixd) +#define glMultMatrixf MANGLE(MultMatrixf) +#define glMultTransposeMatrixdARB MANGLE(MultTransposeMatrixdARB) +#define glMultTransposeMatrixd MANGLE(MultTransposeMatrixd) +#define glMultTransposeMatrixfARB MANGLE(MultTransposeMatrixfARB) +#define glMultTransposeMatrixf MANGLE(MultTransposeMatrixf) +#define glNamedBufferDataEXT MANGLE(NamedBufferDataEXT) +#define glNamedBufferSubDataEXT MANGLE(NamedBufferSubDataEXT) +#define glNamedCopyBufferSubDataEXT MANGLE(NamedCopyBufferSubDataEXT) +#define glNamedFramebufferRenderbufferEXT MANGLE(NamedFramebufferRenderbufferEXT) +#define glNamedFramebufferTexture1DEXT MANGLE(NamedFramebufferTexture1DEXT) +#define glNamedFramebufferTexture2DEXT MANGLE(NamedFramebufferTexture2DEXT) +#define glNamedFramebufferTexture3DEXT MANGLE(NamedFramebufferTexture3DEXT) +#define glNamedFramebufferTextureEXT MANGLE(NamedFramebufferTextureEXT) +#define glNamedFramebufferTextureFaceEXT MANGLE(NamedFramebufferTextureFaceEXT) +#define glNamedFramebufferTextureLayerEXT MANGLE(NamedFramebufferTextureLayerEXT) +#define glNamedProgramLocalParameter4dEXT MANGLE(NamedProgramLocalParameter4dEXT) +#define glNamedProgramLocalParameter4dvEXT MANGLE(NamedProgramLocalParameter4dvEXT) +#define glNamedProgramLocalParameter4fEXT MANGLE(NamedProgramLocalParameter4fEXT) +#define glNamedProgramLocalParameter4fvEXT MANGLE(NamedProgramLocalParameter4fvEXT) +#define glNamedProgramLocalParameterI4iEXT MANGLE(NamedProgramLocalParameterI4iEXT) +#define glNamedProgramLocalParameterI4ivEXT MANGLE(NamedProgramLocalParameterI4ivEXT) +#define glNamedProgramLocalParameterI4uiEXT MANGLE(NamedProgramLocalParameterI4uiEXT) +#define glNamedProgramLocalParameterI4uivEXT MANGLE(NamedProgramLocalParameterI4uivEXT) +#define glNamedProgramLocalParameters4fvEXT MANGLE(NamedProgramLocalParameters4fvEXT) +#define glNamedProgramLocalParametersI4ivEXT MANGLE(NamedProgramLocalParametersI4ivEXT) +#define glNamedProgramLocalParametersI4uivEXT MANGLE(NamedProgramLocalParametersI4uivEXT) +#define glNamedProgramStringEXT MANGLE(NamedProgramStringEXT) +#define glNamedRenderbufferStorageEXT MANGLE(NamedRenderbufferStorageEXT) +#define glNamedRenderbufferStorageMultisampleCoverageEXT MANGLE(NamedRenderbufferStorageMultisampleCoverageEXT) +#define glNamedRenderbufferStorageMultisampleEXT MANGLE(NamedRenderbufferStorageMultisampleEXT) +#define glNamedStringARB MANGLE(NamedStringARB) +#define glNewList MANGLE(NewList) +#define glNewObjectBufferATI MANGLE(NewObjectBufferATI) +#define glNormal3b MANGLE(Normal3b) +#define glNormal3bv MANGLE(Normal3bv) +#define glNormal3d MANGLE(Normal3d) +#define glNormal3dv MANGLE(Normal3dv) +#define glNormal3f MANGLE(Normal3f) +#define glNormal3fVertex3fSUN MANGLE(Normal3fVertex3fSUN) +#define glNormal3fVertex3fvSUN MANGLE(Normal3fVertex3fvSUN) +#define glNormal3fv MANGLE(Normal3fv) +#define glNormal3hNV MANGLE(Normal3hNV) +#define glNormal3hvNV MANGLE(Normal3hvNV) +#define glNormal3i MANGLE(Normal3i) +#define glNormal3iv MANGLE(Normal3iv) +#define glNormal3s MANGLE(Normal3s) +#define glNormal3sv MANGLE(Normal3sv) +#define glNormalFormatNV MANGLE(NormalFormatNV) +#define glNormalP3ui MANGLE(NormalP3ui) +#define glNormalP3uiv MANGLE(NormalP3uiv) +#define glNormalPointerEXT MANGLE(NormalPointerEXT) +#define glNormalPointerListIBM MANGLE(NormalPointerListIBM) +#define glNormalPointer MANGLE(NormalPointer) +#define glNormalPointervINTEL MANGLE(NormalPointervINTEL) +#define glNormalStream3bATI MANGLE(NormalStream3bATI) +#define glNormalStream3bvATI MANGLE(NormalStream3bvATI) +#define glNormalStream3dATI MANGLE(NormalStream3dATI) +#define glNormalStream3dvATI MANGLE(NormalStream3dvATI) +#define glNormalStream3fATI MANGLE(NormalStream3fATI) +#define glNormalStream3fvATI MANGLE(NormalStream3fvATI) +#define glNormalStream3iATI MANGLE(NormalStream3iATI) +#define glNormalStream3ivATI MANGLE(NormalStream3ivATI) +#define glNormalStream3sATI MANGLE(NormalStream3sATI) +#define glNormalStream3svATI MANGLE(NormalStream3svATI) +#define glObjectPurgeableAPPLE MANGLE(ObjectPurgeableAPPLE) +#define glObjectUnpurgeableAPPLE MANGLE(ObjectUnpurgeableAPPLE) +#define glOrtho MANGLE(Ortho) +#define glPassTexCoordATI MANGLE(PassTexCoordATI) +#define glPassThrough MANGLE(PassThrough) +#define glPatchParameterfv MANGLE(PatchParameterfv) +#define glPatchParameteri MANGLE(PatchParameteri) +#define glPauseTransformFeedback MANGLE(PauseTransformFeedback) +#define glPauseTransformFeedbackNV MANGLE(PauseTransformFeedbackNV) +#define glPixelDataRangeNV MANGLE(PixelDataRangeNV) +#define glPixelMapfv MANGLE(PixelMapfv) +#define glPixelMapuiv MANGLE(PixelMapuiv) +#define glPixelMapusv MANGLE(PixelMapusv) +#define glPixelStoref MANGLE(PixelStoref) +#define glPixelStorei MANGLE(PixelStorei) +#define glPixelTexGenParameterfSGIS MANGLE(PixelTexGenParameterfSGIS) +#define glPixelTexGenParameterfvSGIS MANGLE(PixelTexGenParameterfvSGIS) +#define glPixelTexGenParameteriSGIS MANGLE(PixelTexGenParameteriSGIS) +#define glPixelTexGenParameterivSGIS MANGLE(PixelTexGenParameterivSGIS) +#define glPixelTexGenSGIX MANGLE(PixelTexGenSGIX) +#define glPixelTransferf MANGLE(PixelTransferf) +#define glPixelTransferi MANGLE(PixelTransferi) +#define glPixelTransformParameterfEXT MANGLE(PixelTransformParameterfEXT) +#define glPixelTransformParameterfvEXT MANGLE(PixelTransformParameterfvEXT) +#define glPixelTransformParameteriEXT MANGLE(PixelTransformParameteriEXT) +#define glPixelTransformParameterivEXT MANGLE(PixelTransformParameterivEXT) +#define glPixelZoom MANGLE(PixelZoom) +#define glPNTrianglesfATI MANGLE(PNTrianglesfATI) +#define glPNTrianglesiATI MANGLE(PNTrianglesiATI) +#define glPointParameterfARB MANGLE(PointParameterfARB) +#define glPointParameterfEXT MANGLE(PointParameterfEXT) +#define glPointParameterf MANGLE(PointParameterf) +#define glPointParameterfSGIS MANGLE(PointParameterfSGIS) +#define glPointParameterfvARB MANGLE(PointParameterfvARB) +#define glPointParameterfvEXT MANGLE(PointParameterfvEXT) +#define glPointParameterfv MANGLE(PointParameterfv) +#define glPointParameterfvSGIS MANGLE(PointParameterfvSGIS) +#define glPointParameteri MANGLE(PointParameteri) +#define glPointParameteriNV MANGLE(PointParameteriNV) +#define glPointParameteriv MANGLE(PointParameteriv) +#define glPointParameterivNV MANGLE(PointParameterivNV) +#define glPointSize MANGLE(PointSize) +#define glPollAsyncSGIX MANGLE(PollAsyncSGIX) +#define glPollInstrumentsSGIX MANGLE(PollInstrumentsSGIX) +#define glPolygonMode MANGLE(PolygonMode) +#define glPolygonOffsetEXT MANGLE(PolygonOffsetEXT) +#define glPolygonOffset MANGLE(PolygonOffset) +#define glPolygonStipple MANGLE(PolygonStipple) +#define glPopAttrib MANGLE(PopAttrib) +#define glPopClientAttrib MANGLE(PopClientAttrib) +#define glPopMatrix MANGLE(PopMatrix) +#define glPopName MANGLE(PopName) +#define glPresentFrameDualFillNV MANGLE(PresentFrameDualFillNV) +#define glPresentFrameKeyedNV MANGLE(PresentFrameKeyedNV) +#define glPrimitiveRestartIndex MANGLE(PrimitiveRestartIndex) +#define glPrimitiveRestartIndexNV MANGLE(PrimitiveRestartIndexNV) +#define glPrimitiveRestartNV MANGLE(PrimitiveRestartNV) +#define glPrioritizeTexturesEXT MANGLE(PrioritizeTexturesEXT) +#define glPrioritizeTextures MANGLE(PrioritizeTextures) +#define glProgramBinary MANGLE(ProgramBinary) +#define glProgramBufferParametersfvNV MANGLE(ProgramBufferParametersfvNV) +#define glProgramBufferParametersIivNV MANGLE(ProgramBufferParametersIivNV) +#define glProgramBufferParametersIuivNV MANGLE(ProgramBufferParametersIuivNV) +#define glProgramCallbackMESA MANGLE(ProgramCallbackMESA) +#define glProgramEnvParameter4dARB MANGLE(ProgramEnvParameter4dARB) +#define glProgramEnvParameter4dvARB MANGLE(ProgramEnvParameter4dvARB) +#define glProgramEnvParameter4fARB MANGLE(ProgramEnvParameter4fARB) +#define glProgramEnvParameter4fvARB MANGLE(ProgramEnvParameter4fvARB) +#define glProgramEnvParameterI4iNV MANGLE(ProgramEnvParameterI4iNV) +#define glProgramEnvParameterI4ivNV MANGLE(ProgramEnvParameterI4ivNV) +#define glProgramEnvParameterI4uiNV MANGLE(ProgramEnvParameterI4uiNV) +#define glProgramEnvParameterI4uivNV MANGLE(ProgramEnvParameterI4uivNV) +#define glProgramEnvParameters4fvEXT MANGLE(ProgramEnvParameters4fvEXT) +#define glProgramEnvParametersI4ivNV MANGLE(ProgramEnvParametersI4ivNV) +#define glProgramEnvParametersI4uivNV MANGLE(ProgramEnvParametersI4uivNV) +#define glProgramLocalParameter4dARB MANGLE(ProgramLocalParameter4dARB) +#define glProgramLocalParameter4dvARB MANGLE(ProgramLocalParameter4dvARB) +#define glProgramLocalParameter4fARB MANGLE(ProgramLocalParameter4fARB) +#define glProgramLocalParameter4fvARB MANGLE(ProgramLocalParameter4fvARB) +#define glProgramLocalParameterI4iNV MANGLE(ProgramLocalParameterI4iNV) +#define glProgramLocalParameterI4ivNV MANGLE(ProgramLocalParameterI4ivNV) +#define glProgramLocalParameterI4uiNV MANGLE(ProgramLocalParameterI4uiNV) +#define glProgramLocalParameterI4uivNV MANGLE(ProgramLocalParameterI4uivNV) +#define glProgramLocalParameters4fvEXT MANGLE(ProgramLocalParameters4fvEXT) +#define glProgramLocalParametersI4ivNV MANGLE(ProgramLocalParametersI4ivNV) +#define glProgramLocalParametersI4uivNV MANGLE(ProgramLocalParametersI4uivNV) +#define glProgramNamedParameter4dNV MANGLE(ProgramNamedParameter4dNV) +#define glProgramNamedParameter4dvNV MANGLE(ProgramNamedParameter4dvNV) +#define glProgramNamedParameter4fNV MANGLE(ProgramNamedParameter4fNV) +#define glProgramNamedParameter4fvNV MANGLE(ProgramNamedParameter4fvNV) +#define glProgramParameter4dNV MANGLE(ProgramParameter4dNV) +#define glProgramParameter4dvNV MANGLE(ProgramParameter4dvNV) +#define glProgramParameter4fNV MANGLE(ProgramParameter4fNV) +#define glProgramParameter4fvNV MANGLE(ProgramParameter4fvNV) +#define glProgramParameteriARB MANGLE(ProgramParameteriARB) +#define glProgramParameteriEXT MANGLE(ProgramParameteriEXT) +#define glProgramParameteri MANGLE(ProgramParameteri) +#define glProgramParameters4dvNV MANGLE(ProgramParameters4dvNV) +#define glProgramParameters4fvNV MANGLE(ProgramParameters4fvNV) +#define glProgramStringARB MANGLE(ProgramStringARB) +#define glProgramSubroutineParametersuivNV MANGLE(ProgramSubroutineParametersuivNV) +#define glProgramUniform1dEXT MANGLE(ProgramUniform1dEXT) +#define glProgramUniform1d MANGLE(ProgramUniform1d) +#define glProgramUniform1dvEXT MANGLE(ProgramUniform1dvEXT) +#define glProgramUniform1dv MANGLE(ProgramUniform1dv) +#define glProgramUniform1fEXT MANGLE(ProgramUniform1fEXT) +#define glProgramUniform1f MANGLE(ProgramUniform1f) +#define glProgramUniform1fvEXT MANGLE(ProgramUniform1fvEXT) +#define glProgramUniform1fv MANGLE(ProgramUniform1fv) +#define glProgramUniform1i64NV MANGLE(ProgramUniform1i64NV) +#define glProgramUniform1i64vNV MANGLE(ProgramUniform1i64vNV) +#define glProgramUniform1iEXT MANGLE(ProgramUniform1iEXT) +#define glProgramUniform1i MANGLE(ProgramUniform1i) +#define glProgramUniform1ivEXT MANGLE(ProgramUniform1ivEXT) +#define glProgramUniform1iv MANGLE(ProgramUniform1iv) +#define glProgramUniform1ui64NV MANGLE(ProgramUniform1ui64NV) +#define glProgramUniform1ui64vNV MANGLE(ProgramUniform1ui64vNV) +#define glProgramUniform1uiEXT MANGLE(ProgramUniform1uiEXT) +#define glProgramUniform1ui MANGLE(ProgramUniform1ui) +#define glProgramUniform1uivEXT MANGLE(ProgramUniform1uivEXT) +#define glProgramUniform1uiv MANGLE(ProgramUniform1uiv) +#define glProgramUniform2dEXT MANGLE(ProgramUniform2dEXT) +#define glProgramUniform2d MANGLE(ProgramUniform2d) +#define glProgramUniform2dvEXT MANGLE(ProgramUniform2dvEXT) +#define glProgramUniform2dv MANGLE(ProgramUniform2dv) +#define glProgramUniform2fEXT MANGLE(ProgramUniform2fEXT) +#define glProgramUniform2f MANGLE(ProgramUniform2f) +#define glProgramUniform2fvEXT MANGLE(ProgramUniform2fvEXT) +#define glProgramUniform2fv MANGLE(ProgramUniform2fv) +#define glProgramUniform2i64NV MANGLE(ProgramUniform2i64NV) +#define glProgramUniform2i64vNV MANGLE(ProgramUniform2i64vNV) +#define glProgramUniform2iEXT MANGLE(ProgramUniform2iEXT) +#define glProgramUniform2i MANGLE(ProgramUniform2i) +#define glProgramUniform2ivEXT MANGLE(ProgramUniform2ivEXT) +#define glProgramUniform2iv MANGLE(ProgramUniform2iv) +#define glProgramUniform2ui64NV MANGLE(ProgramUniform2ui64NV) +#define glProgramUniform2ui64vNV MANGLE(ProgramUniform2ui64vNV) +#define glProgramUniform2uiEXT MANGLE(ProgramUniform2uiEXT) +#define glProgramUniform2ui MANGLE(ProgramUniform2ui) +#define glProgramUniform2uivEXT MANGLE(ProgramUniform2uivEXT) +#define glProgramUniform2uiv MANGLE(ProgramUniform2uiv) +#define glProgramUniform3dEXT MANGLE(ProgramUniform3dEXT) +#define glProgramUniform3d MANGLE(ProgramUniform3d) +#define glProgramUniform3dvEXT MANGLE(ProgramUniform3dvEXT) +#define glProgramUniform3dv MANGLE(ProgramUniform3dv) +#define glProgramUniform3fEXT MANGLE(ProgramUniform3fEXT) +#define glProgramUniform3f MANGLE(ProgramUniform3f) +#define glProgramUniform3fvEXT MANGLE(ProgramUniform3fvEXT) +#define glProgramUniform3fv MANGLE(ProgramUniform3fv) +#define glProgramUniform3i64NV MANGLE(ProgramUniform3i64NV) +#define glProgramUniform3i64vNV MANGLE(ProgramUniform3i64vNV) +#define glProgramUniform3iEXT MANGLE(ProgramUniform3iEXT) +#define glProgramUniform3i MANGLE(ProgramUniform3i) +#define glProgramUniform3ivEXT MANGLE(ProgramUniform3ivEXT) +#define glProgramUniform3iv MANGLE(ProgramUniform3iv) +#define glProgramUniform3ui64NV MANGLE(ProgramUniform3ui64NV) +#define glProgramUniform3ui64vNV MANGLE(ProgramUniform3ui64vNV) +#define glProgramUniform3uiEXT MANGLE(ProgramUniform3uiEXT) +#define glProgramUniform3ui MANGLE(ProgramUniform3ui) +#define glProgramUniform3uivEXT MANGLE(ProgramUniform3uivEXT) +#define glProgramUniform3uiv MANGLE(ProgramUniform3uiv) +#define glProgramUniform4dEXT MANGLE(ProgramUniform4dEXT) +#define glProgramUniform4d MANGLE(ProgramUniform4d) +#define glProgramUniform4dvEXT MANGLE(ProgramUniform4dvEXT) +#define glProgramUniform4dv MANGLE(ProgramUniform4dv) +#define glProgramUniform4fEXT MANGLE(ProgramUniform4fEXT) +#define glProgramUniform4f MANGLE(ProgramUniform4f) +#define glProgramUniform4fvEXT MANGLE(ProgramUniform4fvEXT) +#define glProgramUniform4fv MANGLE(ProgramUniform4fv) +#define glProgramUniform4i64NV MANGLE(ProgramUniform4i64NV) +#define glProgramUniform4i64vNV MANGLE(ProgramUniform4i64vNV) +#define glProgramUniform4iEXT MANGLE(ProgramUniform4iEXT) +#define glProgramUniform4i MANGLE(ProgramUniform4i) +#define glProgramUniform4ivEXT MANGLE(ProgramUniform4ivEXT) +#define glProgramUniform4iv MANGLE(ProgramUniform4iv) +#define glProgramUniform4ui64NV MANGLE(ProgramUniform4ui64NV) +#define glProgramUniform4ui64vNV MANGLE(ProgramUniform4ui64vNV) +#define glProgramUniform4uiEXT MANGLE(ProgramUniform4uiEXT) +#define glProgramUniform4ui MANGLE(ProgramUniform4ui) +#define glProgramUniform4uivEXT MANGLE(ProgramUniform4uivEXT) +#define glProgramUniform4uiv MANGLE(ProgramUniform4uiv) +#define glProgramUniformMatrix2dvEXT MANGLE(ProgramUniformMatrix2dvEXT) +#define glProgramUniformMatrix2dv MANGLE(ProgramUniformMatrix2dv) +#define glProgramUniformMatrix2fvEXT MANGLE(ProgramUniformMatrix2fvEXT) +#define glProgramUniformMatrix2fv MANGLE(ProgramUniformMatrix2fv) +#define glProgramUniformMatrix2x3dvEXT MANGLE(ProgramUniformMatrix2x3dvEXT) +#define glProgramUniformMatrix2x3dv MANGLE(ProgramUniformMatrix2x3dv) +#define glProgramUniformMatrix2x3fvEXT MANGLE(ProgramUniformMatrix2x3fvEXT) +#define glProgramUniformMatrix2x3fv MANGLE(ProgramUniformMatrix2x3fv) +#define glProgramUniformMatrix2x4dvEXT MANGLE(ProgramUniformMatrix2x4dvEXT) +#define glProgramUniformMatrix2x4dv MANGLE(ProgramUniformMatrix2x4dv) +#define glProgramUniformMatrix2x4fvEXT MANGLE(ProgramUniformMatrix2x4fvEXT) +#define glProgramUniformMatrix2x4fv MANGLE(ProgramUniformMatrix2x4fv) +#define glProgramUniformMatrix3dvEXT MANGLE(ProgramUniformMatrix3dvEXT) +#define glProgramUniformMatrix3dv MANGLE(ProgramUniformMatrix3dv) +#define glProgramUniformMatrix3fvEXT MANGLE(ProgramUniformMatrix3fvEXT) +#define glProgramUniformMatrix3fv MANGLE(ProgramUniformMatrix3fv) +#define glProgramUniformMatrix3x2dvEXT MANGLE(ProgramUniformMatrix3x2dvEXT) +#define glProgramUniformMatrix3x2dv MANGLE(ProgramUniformMatrix3x2dv) +#define glProgramUniformMatrix3x2fvEXT MANGLE(ProgramUniformMatrix3x2fvEXT) +#define glProgramUniformMatrix3x2fv MANGLE(ProgramUniformMatrix3x2fv) +#define glProgramUniformMatrix3x4dvEXT MANGLE(ProgramUniformMatrix3x4dvEXT) +#define glProgramUniformMatrix3x4dv MANGLE(ProgramUniformMatrix3x4dv) +#define glProgramUniformMatrix3x4fvEXT MANGLE(ProgramUniformMatrix3x4fvEXT) +#define glProgramUniformMatrix3x4fv MANGLE(ProgramUniformMatrix3x4fv) +#define glProgramUniformMatrix4dvEXT MANGLE(ProgramUniformMatrix4dvEXT) +#define glProgramUniformMatrix4dv MANGLE(ProgramUniformMatrix4dv) +#define glProgramUniformMatrix4fvEXT MANGLE(ProgramUniformMatrix4fvEXT) +#define glProgramUniformMatrix4fv MANGLE(ProgramUniformMatrix4fv) +#define glProgramUniformMatrix4x2dvEXT MANGLE(ProgramUniformMatrix4x2dvEXT) +#define glProgramUniformMatrix4x2dv MANGLE(ProgramUniformMatrix4x2dv) +#define glProgramUniformMatrix4x2fvEXT MANGLE(ProgramUniformMatrix4x2fvEXT) +#define glProgramUniformMatrix4x2fv MANGLE(ProgramUniformMatrix4x2fv) +#define glProgramUniformMatrix4x3dvEXT MANGLE(ProgramUniformMatrix4x3dvEXT) +#define glProgramUniformMatrix4x3dv MANGLE(ProgramUniformMatrix4x3dv) +#define glProgramUniformMatrix4x3fvEXT MANGLE(ProgramUniformMatrix4x3fvEXT) +#define glProgramUniformMatrix4x3fv MANGLE(ProgramUniformMatrix4x3fv) +#define glProgramUniformui64NV MANGLE(ProgramUniformui64NV) +#define glProgramUniformui64vNV MANGLE(ProgramUniformui64vNV) +#define glProgramVertexLimitNV MANGLE(ProgramVertexLimitNV) +#define glProvokingVertexEXT MANGLE(ProvokingVertexEXT) +#define glProvokingVertex MANGLE(ProvokingVertex) +#define glPushAttrib MANGLE(PushAttrib) +#define glPushClientAttribDefaultEXT MANGLE(PushClientAttribDefaultEXT) +#define glPushClientAttrib MANGLE(PushClientAttrib) +#define glPushMatrix MANGLE(PushMatrix) +#define glPushName MANGLE(PushName) +#define glQueryCounter MANGLE(QueryCounter) +#define glRasterPos2d MANGLE(RasterPos2d) +#define glRasterPos2dv MANGLE(RasterPos2dv) +#define glRasterPos2f MANGLE(RasterPos2f) +#define glRasterPos2fv MANGLE(RasterPos2fv) +#define glRasterPos2i MANGLE(RasterPos2i) +#define glRasterPos2iv MANGLE(RasterPos2iv) +#define glRasterPos2s MANGLE(RasterPos2s) +#define glRasterPos2sv MANGLE(RasterPos2sv) +#define glRasterPos3d MANGLE(RasterPos3d) +#define glRasterPos3dv MANGLE(RasterPos3dv) +#define glRasterPos3f MANGLE(RasterPos3f) +#define glRasterPos3fv MANGLE(RasterPos3fv) +#define glRasterPos3i MANGLE(RasterPos3i) +#define glRasterPos3iv MANGLE(RasterPos3iv) +#define glRasterPos3s MANGLE(RasterPos3s) +#define glRasterPos3sv MANGLE(RasterPos3sv) +#define glRasterPos4d MANGLE(RasterPos4d) +#define glRasterPos4dv MANGLE(RasterPos4dv) +#define glRasterPos4f MANGLE(RasterPos4f) +#define glRasterPos4fv MANGLE(RasterPos4fv) +#define glRasterPos4i MANGLE(RasterPos4i) +#define glRasterPos4iv MANGLE(RasterPos4iv) +#define glRasterPos4s MANGLE(RasterPos4s) +#define glRasterPos4sv MANGLE(RasterPos4sv) +#define glReadBuffer MANGLE(ReadBuffer) +#define glReadInstrumentsSGIX MANGLE(ReadInstrumentsSGIX) +#define glReadnPixelsARB MANGLE(ReadnPixelsARB) +#define glReadPixels MANGLE(ReadPixels) +#define glRectd MANGLE(Rectd) +#define glRectdv MANGLE(Rectdv) +#define glRectf MANGLE(Rectf) +#define glRectfv MANGLE(Rectfv) +#define glRecti MANGLE(Recti) +#define glRectiv MANGLE(Rectiv) +#define glRects MANGLE(Rects) +#define glRectsv MANGLE(Rectsv) +#define glReferencePlaneSGIX MANGLE(ReferencePlaneSGIX) +#define glReleaseShaderCompiler MANGLE(ReleaseShaderCompiler) +#define glRenderbufferStorageEXT MANGLE(RenderbufferStorageEXT) +#define glRenderbufferStorage MANGLE(RenderbufferStorage) +#define glRenderbufferStorageMultisampleCoverageNV MANGLE(RenderbufferStorageMultisampleCoverageNV) +#define glRenderbufferStorageMultisampleEXT MANGLE(RenderbufferStorageMultisampleEXT) +#define glRenderbufferStorageMultisample MANGLE(RenderbufferStorageMultisample) +#define glRenderMode MANGLE(RenderMode) +#define glReplacementCodePointerSUN MANGLE(ReplacementCodePointerSUN) +#define glReplacementCodeubSUN MANGLE(ReplacementCodeubSUN) +#define glReplacementCodeubvSUN MANGLE(ReplacementCodeubvSUN) +#define glReplacementCodeuiColor3fVertex3fSUN MANGLE(ReplacementCodeuiColor3fVertex3fSUN) +#define glReplacementCodeuiColor3fVertex3fvSUN MANGLE(ReplacementCodeuiColor3fVertex3fvSUN) +#define glReplacementCodeuiColor4fNormal3fVertex3fSUN MANGLE(ReplacementCodeuiColor4fNormal3fVertex3fSUN) +#define glReplacementCodeuiColor4fNormal3fVertex3fvSUN MANGLE(ReplacementCodeuiColor4fNormal3fVertex3fvSUN) +#define glReplacementCodeuiColor4ubVertex3fSUN MANGLE(ReplacementCodeuiColor4ubVertex3fSUN) +#define glReplacementCodeuiColor4ubVertex3fvSUN MANGLE(ReplacementCodeuiColor4ubVertex3fvSUN) +#define glReplacementCodeuiNormal3fVertex3fSUN MANGLE(ReplacementCodeuiNormal3fVertex3fSUN) +#define glReplacementCodeuiNormal3fVertex3fvSUN MANGLE(ReplacementCodeuiNormal3fVertex3fvSUN) +#define glReplacementCodeuiSUN MANGLE(ReplacementCodeuiSUN) +#define glReplacementCodeuiTexCoord2fColor4fNormal3fVertex3fSUN MANGLE(ReplacementCodeuiTexCoord2fColor4fNormal3fVertex3fSUN) +#define glReplacementCodeuiTexCoord2fColor4fNormal3fVertex3fvSUN MANGLE(ReplacementCodeuiTexCoord2fColor4fNormal3fVertex3fvSUN) +#define glReplacementCodeuiTexCoord2fNormal3fVertex3fSUN MANGLE(ReplacementCodeuiTexCoord2fNormal3fVertex3fSUN) +#define glReplacementCodeuiTexCoord2fNormal3fVertex3fvSUN MANGLE(ReplacementCodeuiTexCoord2fNormal3fVertex3fvSUN) +#define glReplacementCodeuiTexCoord2fVertex3fSUN MANGLE(ReplacementCodeuiTexCoord2fVertex3fSUN) +#define glReplacementCodeuiTexCoord2fVertex3fvSUN MANGLE(ReplacementCodeuiTexCoord2fVertex3fvSUN) +#define glReplacementCodeuiVertex3fSUN MANGLE(ReplacementCodeuiVertex3fSUN) +#define glReplacementCodeuiVertex3fvSUN MANGLE(ReplacementCodeuiVertex3fvSUN) +#define glReplacementCodeuivSUN MANGLE(ReplacementCodeuivSUN) +#define glReplacementCodeusSUN MANGLE(ReplacementCodeusSUN) +#define glReplacementCodeusvSUN MANGLE(ReplacementCodeusvSUN) +#define glRequestResidentProgramsNV MANGLE(RequestResidentProgramsNV) +#define glResetHistogramEXT MANGLE(ResetHistogramEXT) +#define glResetHistogram MANGLE(ResetHistogram) +#define glResetMinmaxEXT MANGLE(ResetMinmaxEXT) +#define glResetMinmax MANGLE(ResetMinmax) +#define glResizeBuffersMESA MANGLE(ResizeBuffersMESA) +#define glResumeTransformFeedback MANGLE(ResumeTransformFeedback) +#define glResumeTransformFeedbackNV MANGLE(ResumeTransformFeedbackNV) +#define glRotated MANGLE(Rotated) +#define glRotatef MANGLE(Rotatef) +#define glSampleCoverageARB MANGLE(SampleCoverageARB) +#define glSampleCoverage MANGLE(SampleCoverage) +#define glSampleMapATI MANGLE(SampleMapATI) +#define glSampleMaskEXT MANGLE(SampleMaskEXT) +#define glSampleMaski MANGLE(SampleMaski) +#define glSampleMaskIndexedNV MANGLE(SampleMaskIndexedNV) +#define glSampleMaskSGIS MANGLE(SampleMaskSGIS) +#define glSamplePatternEXT MANGLE(SamplePatternEXT) +#define glSamplePatternSGIS MANGLE(SamplePatternSGIS) +#define glSamplerParameterf MANGLE(SamplerParameterf) +#define glSamplerParameterfv MANGLE(SamplerParameterfv) +#define glSamplerParameterIiv MANGLE(SamplerParameterIiv) +#define glSamplerParameteri MANGLE(SamplerParameteri) +#define glSamplerParameterIuiv MANGLE(SamplerParameterIuiv) +#define glSamplerParameteriv MANGLE(SamplerParameteriv) +#define glScaled MANGLE(Scaled) +#define glScalef MANGLE(Scalef) +#define glScissorArrayv MANGLE(ScissorArrayv) +#define glScissorIndexed MANGLE(ScissorIndexed) +#define glScissorIndexedv MANGLE(ScissorIndexedv) +#define glScissor MANGLE(Scissor) +#define glSecondaryColor3bEXT MANGLE(SecondaryColor3bEXT) +#define glSecondaryColor3b MANGLE(SecondaryColor3b) +#define glSecondaryColor3bvEXT MANGLE(SecondaryColor3bvEXT) +#define glSecondaryColor3bv MANGLE(SecondaryColor3bv) +#define glSecondaryColor3dEXT MANGLE(SecondaryColor3dEXT) +#define glSecondaryColor3d MANGLE(SecondaryColor3d) +#define glSecondaryColor3dvEXT MANGLE(SecondaryColor3dvEXT) +#define glSecondaryColor3dv MANGLE(SecondaryColor3dv) +#define glSecondaryColor3fEXT MANGLE(SecondaryColor3fEXT) +#define glSecondaryColor3f MANGLE(SecondaryColor3f) +#define glSecondaryColor3fvEXT MANGLE(SecondaryColor3fvEXT) +#define glSecondaryColor3fv MANGLE(SecondaryColor3fv) +#define glSecondaryColor3hNV MANGLE(SecondaryColor3hNV) +#define glSecondaryColor3hvNV MANGLE(SecondaryColor3hvNV) +#define glSecondaryColor3iEXT MANGLE(SecondaryColor3iEXT) +#define glSecondaryColor3i MANGLE(SecondaryColor3i) +#define glSecondaryColor3ivEXT MANGLE(SecondaryColor3ivEXT) +#define glSecondaryColor3iv MANGLE(SecondaryColor3iv) +#define glSecondaryColor3sEXT MANGLE(SecondaryColor3sEXT) +#define glSecondaryColor3s MANGLE(SecondaryColor3s) +#define glSecondaryColor3svEXT MANGLE(SecondaryColor3svEXT) +#define glSecondaryColor3sv MANGLE(SecondaryColor3sv) +#define glSecondaryColor3ubEXT MANGLE(SecondaryColor3ubEXT) +#define glSecondaryColor3ub MANGLE(SecondaryColor3ub) +#define glSecondaryColor3ubvEXT MANGLE(SecondaryColor3ubvEXT) +#define glSecondaryColor3ubv MANGLE(SecondaryColor3ubv) +#define glSecondaryColor3uiEXT MANGLE(SecondaryColor3uiEXT) +#define glSecondaryColor3ui MANGLE(SecondaryColor3ui) +#define glSecondaryColor3uivEXT MANGLE(SecondaryColor3uivEXT) +#define glSecondaryColor3uiv MANGLE(SecondaryColor3uiv) +#define glSecondaryColor3usEXT MANGLE(SecondaryColor3usEXT) +#define glSecondaryColor3us MANGLE(SecondaryColor3us) +#define glSecondaryColor3usvEXT MANGLE(SecondaryColor3usvEXT) +#define glSecondaryColor3usv MANGLE(SecondaryColor3usv) +#define glSecondaryColorFormatNV MANGLE(SecondaryColorFormatNV) +#define glSecondaryColorP3ui MANGLE(SecondaryColorP3ui) +#define glSecondaryColorP3uiv MANGLE(SecondaryColorP3uiv) +#define glSecondaryColorPointerEXT MANGLE(SecondaryColorPointerEXT) +#define glSecondaryColorPointerListIBM MANGLE(SecondaryColorPointerListIBM) +#define glSecondaryColorPointer MANGLE(SecondaryColorPointer) +#define glSelectBuffer MANGLE(SelectBuffer) +#define glSelectPerfMonitorCountersAMD MANGLE(SelectPerfMonitorCountersAMD) +#define glSeparableFilter2DEXT MANGLE(SeparableFilter2DEXT) +#define glSeparableFilter2D MANGLE(SeparableFilter2D) +#define glSetFenceAPPLE MANGLE(SetFenceAPPLE) +#define glSetFenceNV MANGLE(SetFenceNV) +#define glSetFragmentShaderConstantATI MANGLE(SetFragmentShaderConstantATI) +#define glSetInvariantEXT MANGLE(SetInvariantEXT) +#define glSetLocalConstantEXT MANGLE(SetLocalConstantEXT) +#define glShadeModel MANGLE(ShadeModel) +#define glShaderBinary MANGLE(ShaderBinary) +#define glShaderOp1EXT MANGLE(ShaderOp1EXT) +#define glShaderOp2EXT MANGLE(ShaderOp2EXT) +#define glShaderOp3EXT MANGLE(ShaderOp3EXT) +#define glShaderSourceARB MANGLE(ShaderSourceARB) +#define glShaderSource MANGLE(ShaderSource) +#define glSharpenTexFuncSGIS MANGLE(SharpenTexFuncSGIS) +#define glSpriteParameterfSGIX MANGLE(SpriteParameterfSGIX) +#define glSpriteParameterfvSGIX MANGLE(SpriteParameterfvSGIX) +#define glSpriteParameteriSGIX MANGLE(SpriteParameteriSGIX) +#define glSpriteParameterivSGIX MANGLE(SpriteParameterivSGIX) +#define glStartInstrumentsSGIX MANGLE(StartInstrumentsSGIX) +#define glStencilClearTagEXT MANGLE(StencilClearTagEXT) +#define glStencilFunc MANGLE(StencilFunc) +#define glStencilFuncSeparateATI MANGLE(StencilFuncSeparateATI) +#define glStencilFuncSeparate MANGLE(StencilFuncSeparate) +#define glStencilMask MANGLE(StencilMask) +#define glStencilMaskSeparate MANGLE(StencilMaskSeparate) +#define glStencilOp MANGLE(StencilOp) +#define glStencilOpSeparateATI MANGLE(StencilOpSeparateATI) +#define glStencilOpSeparate MANGLE(StencilOpSeparate) +#define glStopInstrumentsSGIX MANGLE(StopInstrumentsSGIX) +#define glStringMarkerGREMEDY MANGLE(StringMarkerGREMEDY) +#define glSwizzleEXT MANGLE(SwizzleEXT) +#define glTagSampleBufferSGIX MANGLE(TagSampleBufferSGIX) +#define glTangent3bEXT MANGLE(Tangent3bEXT) +#define glTangent3bvEXT MANGLE(Tangent3bvEXT) +#define glTangent3dEXT MANGLE(Tangent3dEXT) +#define glTangent3dvEXT MANGLE(Tangent3dvEXT) +#define glTangent3fEXT MANGLE(Tangent3fEXT) +#define glTangent3fvEXT MANGLE(Tangent3fvEXT) +#define glTangent3iEXT MANGLE(Tangent3iEXT) +#define glTangent3ivEXT MANGLE(Tangent3ivEXT) +#define glTangent3sEXT MANGLE(Tangent3sEXT) +#define glTangent3svEXT MANGLE(Tangent3svEXT) +#define glTangentPointerEXT MANGLE(TangentPointerEXT) +#define glTbufferMask3DFX MANGLE(TbufferMask3DFX) +#define glTessellationFactorAMD MANGLE(TessellationFactorAMD) +#define glTessellationModeAMD MANGLE(TessellationModeAMD) +#define glTestFenceAPPLE MANGLE(TestFenceAPPLE) +#define glTestFenceNV MANGLE(TestFenceNV) +#define glTestObjectAPPLE MANGLE(TestObjectAPPLE) +#define glTexBufferARB MANGLE(TexBufferARB) +#define glTexBufferEXT MANGLE(TexBufferEXT) +#define glTexBuffer MANGLE(TexBuffer) +#define glTexBumpParameterfvATI MANGLE(TexBumpParameterfvATI) +#define glTexBumpParameterivATI MANGLE(TexBumpParameterivATI) +#define glTexCoord1d MANGLE(TexCoord1d) +#define glTexCoord1dv MANGLE(TexCoord1dv) +#define glTexCoord1f MANGLE(TexCoord1f) +#define glTexCoord1fv MANGLE(TexCoord1fv) +#define glTexCoord1hNV MANGLE(TexCoord1hNV) +#define glTexCoord1hvNV MANGLE(TexCoord1hvNV) +#define glTexCoord1i MANGLE(TexCoord1i) +#define glTexCoord1iv MANGLE(TexCoord1iv) +#define glTexCoord1s MANGLE(TexCoord1s) +#define glTexCoord1sv MANGLE(TexCoord1sv) +#define glTexCoord2d MANGLE(TexCoord2d) +#define glTexCoord2dv MANGLE(TexCoord2dv) +#define glTexCoord2fColor3fVertex3fSUN MANGLE(TexCoord2fColor3fVertex3fSUN) +#define glTexCoord2fColor3fVertex3fvSUN MANGLE(TexCoord2fColor3fVertex3fvSUN) +#define glTexCoord2fColor4fNormal3fVertex3fSUN MANGLE(TexCoord2fColor4fNormal3fVertex3fSUN) +#define glTexCoord2fColor4fNormal3fVertex3fvSUN MANGLE(TexCoord2fColor4fNormal3fVertex3fvSUN) +#define glTexCoord2fColor4ubVertex3fSUN MANGLE(TexCoord2fColor4ubVertex3fSUN) +#define glTexCoord2fColor4ubVertex3fvSUN MANGLE(TexCoord2fColor4ubVertex3fvSUN) +#define glTexCoord2f MANGLE(TexCoord2f) +#define glTexCoord2fNormal3fVertex3fSUN MANGLE(TexCoord2fNormal3fVertex3fSUN) +#define glTexCoord2fNormal3fVertex3fvSUN MANGLE(TexCoord2fNormal3fVertex3fvSUN) +#define glTexCoord2fVertex3fSUN MANGLE(TexCoord2fVertex3fSUN) +#define glTexCoord2fVertex3fvSUN MANGLE(TexCoord2fVertex3fvSUN) +#define glTexCoord2fv MANGLE(TexCoord2fv) +#define glTexCoord2hNV MANGLE(TexCoord2hNV) +#define glTexCoord2hvNV MANGLE(TexCoord2hvNV) +#define glTexCoord2i MANGLE(TexCoord2i) +#define glTexCoord2iv MANGLE(TexCoord2iv) +#define glTexCoord2s MANGLE(TexCoord2s) +#define glTexCoord2sv MANGLE(TexCoord2sv) +#define glTexCoord3d MANGLE(TexCoord3d) +#define glTexCoord3dv MANGLE(TexCoord3dv) +#define glTexCoord3f MANGLE(TexCoord3f) +#define glTexCoord3fv MANGLE(TexCoord3fv) +#define glTexCoord3hNV MANGLE(TexCoord3hNV) +#define glTexCoord3hvNV MANGLE(TexCoord3hvNV) +#define glTexCoord3i MANGLE(TexCoord3i) +#define glTexCoord3iv MANGLE(TexCoord3iv) +#define glTexCoord3s MANGLE(TexCoord3s) +#define glTexCoord3sv MANGLE(TexCoord3sv) +#define glTexCoord4d MANGLE(TexCoord4d) +#define glTexCoord4dv MANGLE(TexCoord4dv) +#define glTexCoord4fColor4fNormal3fVertex4fSUN MANGLE(TexCoord4fColor4fNormal3fVertex4fSUN) +#define glTexCoord4fColor4fNormal3fVertex4fvSUN MANGLE(TexCoord4fColor4fNormal3fVertex4fvSUN) +#define glTexCoord4f MANGLE(TexCoord4f) +#define glTexCoord4fVertex4fSUN MANGLE(TexCoord4fVertex4fSUN) +#define glTexCoord4fVertex4fvSUN MANGLE(TexCoord4fVertex4fvSUN) +#define glTexCoord4fv MANGLE(TexCoord4fv) +#define glTexCoord4hNV MANGLE(TexCoord4hNV) +#define glTexCoord4hvNV MANGLE(TexCoord4hvNV) +#define glTexCoord4i MANGLE(TexCoord4i) +#define glTexCoord4iv MANGLE(TexCoord4iv) +#define glTexCoord4s MANGLE(TexCoord4s) +#define glTexCoord4sv MANGLE(TexCoord4sv) +#define glTexCoordFormatNV MANGLE(TexCoordFormatNV) +#define glTexCoordP1ui MANGLE(TexCoordP1ui) +#define glTexCoordP1uiv MANGLE(TexCoordP1uiv) +#define glTexCoordP2ui MANGLE(TexCoordP2ui) +#define glTexCoordP2uiv MANGLE(TexCoordP2uiv) +#define glTexCoordP3ui MANGLE(TexCoordP3ui) +#define glTexCoordP3uiv MANGLE(TexCoordP3uiv) +#define glTexCoordP4ui MANGLE(TexCoordP4ui) +#define glTexCoordP4uiv MANGLE(TexCoordP4uiv) +#define glTexCoordPointerEXT MANGLE(TexCoordPointerEXT) +#define glTexCoordPointerListIBM MANGLE(TexCoordPointerListIBM) +#define glTexCoordPointer MANGLE(TexCoordPointer) +#define glTexCoordPointervINTEL MANGLE(TexCoordPointervINTEL) +#define glTexEnvf MANGLE(TexEnvf) +#define glTexEnvfv MANGLE(TexEnvfv) +#define glTexEnvi MANGLE(TexEnvi) +#define glTexEnviv MANGLE(TexEnviv) +#define glTexFilterFuncSGIS MANGLE(TexFilterFuncSGIS) +#define glTexGend MANGLE(TexGend) +#define glTexGendv MANGLE(TexGendv) +#define glTexGenf MANGLE(TexGenf) +#define glTexGenfv MANGLE(TexGenfv) +#define glTexGeni MANGLE(TexGeni) +#define glTexGeniv MANGLE(TexGeniv) +#define glTexImage1D MANGLE(TexImage1D) +#define glTexImage2D MANGLE(TexImage2D) +#define glTexImage2DMultisample MANGLE(TexImage2DMultisample) +#define glTexImage3DEXT MANGLE(TexImage3DEXT) +#define glTexImage3D MANGLE(TexImage3D) +#define glTexImage3DMultisample MANGLE(TexImage3DMultisample) +#define glTexImage4DSGIS MANGLE(TexImage4DSGIS) +#define glTexParameterf MANGLE(TexParameterf) +#define glTexParameterfv MANGLE(TexParameterfv) +#define glTexParameterIivEXT MANGLE(TexParameterIivEXT) +#define glTexParameterIiv MANGLE(TexParameterIiv) +#define glTexParameteri MANGLE(TexParameteri) +#define glTexParameterIuivEXT MANGLE(TexParameterIuivEXT) +#define glTexParameterIuiv MANGLE(TexParameterIuiv) +#define glTexParameteriv MANGLE(TexParameteriv) +#define glTexRenderbufferNV MANGLE(TexRenderbufferNV) +#define glTexSubImage1DEXT MANGLE(TexSubImage1DEXT) +#define glTexSubImage1D MANGLE(TexSubImage1D) +#define glTexSubImage2DEXT MANGLE(TexSubImage2DEXT) +#define glTexSubImage2D MANGLE(TexSubImage2D) +#define glTexSubImage3DEXT MANGLE(TexSubImage3DEXT) +#define glTexSubImage3D MANGLE(TexSubImage3D) +#define glTexSubImage4DSGIS MANGLE(TexSubImage4DSGIS) +#define glTextureBarrierNV MANGLE(TextureBarrierNV) +#define glTextureBufferEXT MANGLE(TextureBufferEXT) +#define glTextureColorMaskSGIS MANGLE(TextureColorMaskSGIS) +#define glTextureImage1DEXT MANGLE(TextureImage1DEXT) +#define glTextureImage2DEXT MANGLE(TextureImage2DEXT) +#define glTextureImage3DEXT MANGLE(TextureImage3DEXT) +#define glTextureLightEXT MANGLE(TextureLightEXT) +#define glTextureMaterialEXT MANGLE(TextureMaterialEXT) +#define glTextureNormalEXT MANGLE(TextureNormalEXT) +#define glTextureParameterfEXT MANGLE(TextureParameterfEXT) +#define glTextureParameterfvEXT MANGLE(TextureParameterfvEXT) +#define glTextureParameteriEXT MANGLE(TextureParameteriEXT) +#define glTextureParameterIivEXT MANGLE(TextureParameterIivEXT) +#define glTextureParameterIuivEXT MANGLE(TextureParameterIuivEXT) +#define glTextureParameterivEXT MANGLE(TextureParameterivEXT) +#define glTextureRangeAPPLE MANGLE(TextureRangeAPPLE) +#define glTextureRenderbufferEXT MANGLE(TextureRenderbufferEXT) +#define glTextureSubImage1DEXT MANGLE(TextureSubImage1DEXT) +#define glTextureSubImage2DEXT MANGLE(TextureSubImage2DEXT) +#define glTextureSubImage3DEXT MANGLE(TextureSubImage3DEXT) +#define glTrackMatrixNV MANGLE(TrackMatrixNV) +#define glTransformFeedbackAttribsNV MANGLE(TransformFeedbackAttribsNV) +#define glTransformFeedbackStreamAttribsNV MANGLE(TransformFeedbackStreamAttribsNV) +#define glTransformFeedbackVaryingsEXT MANGLE(TransformFeedbackVaryingsEXT) +#define glTransformFeedbackVaryings MANGLE(TransformFeedbackVaryings) +#define glTransformFeedbackVaryingsNV MANGLE(TransformFeedbackVaryingsNV) +#define glTranslated MANGLE(Translated) +#define glTranslatef MANGLE(Translatef) +#define glUniform1d MANGLE(Uniform1d) +#define glUniform1dv MANGLE(Uniform1dv) +#define glUniform1fARB MANGLE(Uniform1fARB) +#define glUniform1f MANGLE(Uniform1f) +#define glUniform1fvARB MANGLE(Uniform1fvARB) +#define glUniform1fv MANGLE(Uniform1fv) +#define glUniform1i64NV MANGLE(Uniform1i64NV) +#define glUniform1i64vNV MANGLE(Uniform1i64vNV) +#define glUniform1iARB MANGLE(Uniform1iARB) +#define glUniform1i MANGLE(Uniform1i) +#define glUniform1ivARB MANGLE(Uniform1ivARB) +#define glUniform1iv MANGLE(Uniform1iv) +#define glUniform1ui64NV MANGLE(Uniform1ui64NV) +#define glUniform1ui64vNV MANGLE(Uniform1ui64vNV) +#define glUniform1uiEXT MANGLE(Uniform1uiEXT) +#define glUniform1ui MANGLE(Uniform1ui) +#define glUniform1uivEXT MANGLE(Uniform1uivEXT) +#define glUniform1uiv MANGLE(Uniform1uiv) +#define glUniform2d MANGLE(Uniform2d) +#define glUniform2dv MANGLE(Uniform2dv) +#define glUniform2fARB MANGLE(Uniform2fARB) +#define glUniform2f MANGLE(Uniform2f) +#define glUniform2fvARB MANGLE(Uniform2fvARB) +#define glUniform2fv MANGLE(Uniform2fv) +#define glUniform2i64NV MANGLE(Uniform2i64NV) +#define glUniform2i64vNV MANGLE(Uniform2i64vNV) +#define glUniform2iARB MANGLE(Uniform2iARB) +#define glUniform2i MANGLE(Uniform2i) +#define glUniform2ivARB MANGLE(Uniform2ivARB) +#define glUniform2iv MANGLE(Uniform2iv) +#define glUniform2ui64NV MANGLE(Uniform2ui64NV) +#define glUniform2ui64vNV MANGLE(Uniform2ui64vNV) +#define glUniform2uiEXT MANGLE(Uniform2uiEXT) +#define glUniform2ui MANGLE(Uniform2ui) +#define glUniform2uivEXT MANGLE(Uniform2uivEXT) +#define glUniform2uiv MANGLE(Uniform2uiv) +#define glUniform3d MANGLE(Uniform3d) +#define glUniform3dv MANGLE(Uniform3dv) +#define glUniform3fARB MANGLE(Uniform3fARB) +#define glUniform3f MANGLE(Uniform3f) +#define glUniform3fvARB MANGLE(Uniform3fvARB) +#define glUniform3fv MANGLE(Uniform3fv) +#define glUniform3i64NV MANGLE(Uniform3i64NV) +#define glUniform3i64vNV MANGLE(Uniform3i64vNV) +#define glUniform3iARB MANGLE(Uniform3iARB) +#define glUniform3i MANGLE(Uniform3i) +#define glUniform3ivARB MANGLE(Uniform3ivARB) +#define glUniform3iv MANGLE(Uniform3iv) +#define glUniform3ui64NV MANGLE(Uniform3ui64NV) +#define glUniform3ui64vNV MANGLE(Uniform3ui64vNV) +#define glUniform3uiEXT MANGLE(Uniform3uiEXT) +#define glUniform3ui MANGLE(Uniform3ui) +#define glUniform3uivEXT MANGLE(Uniform3uivEXT) +#define glUniform3uiv MANGLE(Uniform3uiv) +#define glUniform4d MANGLE(Uniform4d) +#define glUniform4dv MANGLE(Uniform4dv) +#define glUniform4fARB MANGLE(Uniform4fARB) +#define glUniform4f MANGLE(Uniform4f) +#define glUniform4fvARB MANGLE(Uniform4fvARB) +#define glUniform4fv MANGLE(Uniform4fv) +#define glUniform4i64NV MANGLE(Uniform4i64NV) +#define glUniform4i64vNV MANGLE(Uniform4i64vNV) +#define glUniform4iARB MANGLE(Uniform4iARB) +#define glUniform4i MANGLE(Uniform4i) +#define glUniform4ivARB MANGLE(Uniform4ivARB) +#define glUniform4iv MANGLE(Uniform4iv) +#define glUniform4ui64NV MANGLE(Uniform4ui64NV) +#define glUniform4ui64vNV MANGLE(Uniform4ui64vNV) +#define glUniform4uiEXT MANGLE(Uniform4uiEXT) +#define glUniform4ui MANGLE(Uniform4ui) +#define glUniform4uivEXT MANGLE(Uniform4uivEXT) +#define glUniform4uiv MANGLE(Uniform4uiv) +#define glUniformBlockBinding MANGLE(UniformBlockBinding) +#define glUniformBufferEXT MANGLE(UniformBufferEXT) +#define glUniformMatrix2dv MANGLE(UniformMatrix2dv) +#define glUniformMatrix2fvARB MANGLE(UniformMatrix2fvARB) +#define glUniformMatrix2fv MANGLE(UniformMatrix2fv) +#define glUniformMatrix2x3dv MANGLE(UniformMatrix2x3dv) +#define glUniformMatrix2x3fv MANGLE(UniformMatrix2x3fv) +#define glUniformMatrix2x4dv MANGLE(UniformMatrix2x4dv) +#define glUniformMatrix2x4fv MANGLE(UniformMatrix2x4fv) +#define glUniformMatrix3dv MANGLE(UniformMatrix3dv) +#define glUniformMatrix3fvARB MANGLE(UniformMatrix3fvARB) +#define glUniformMatrix3fv MANGLE(UniformMatrix3fv) +#define glUniformMatrix3x2dv MANGLE(UniformMatrix3x2dv) +#define glUniformMatrix3x2fv MANGLE(UniformMatrix3x2fv) +#define glUniformMatrix3x4dv MANGLE(UniformMatrix3x4dv) +#define glUniformMatrix3x4fv MANGLE(UniformMatrix3x4fv) +#define glUniformMatrix4dv MANGLE(UniformMatrix4dv) +#define glUniformMatrix4fvARB MANGLE(UniformMatrix4fvARB) +#define glUniformMatrix4fv MANGLE(UniformMatrix4fv) +#define glUniformMatrix4x2dv MANGLE(UniformMatrix4x2dv) +#define glUniformMatrix4x2fv MANGLE(UniformMatrix4x2fv) +#define glUniformMatrix4x3dv MANGLE(UniformMatrix4x3dv) +#define glUniformMatrix4x3fv MANGLE(UniformMatrix4x3fv) +#define glUniformSubroutinesuiv MANGLE(UniformSubroutinesuiv) +#define glUniformui64NV MANGLE(Uniformui64NV) +#define glUniformui64vNV MANGLE(Uniformui64vNV) +#define glUnlockArraysEXT MANGLE(UnlockArraysEXT) +#define glUnmapBufferARB MANGLE(UnmapBufferARB) +#define glUnmapBuffer MANGLE(UnmapBuffer) +#define glUnmapNamedBufferEXT MANGLE(UnmapNamedBufferEXT) +#define glUnmapObjectBufferATI MANGLE(UnmapObjectBufferATI) +#define glUpdateObjectBufferATI MANGLE(UpdateObjectBufferATI) +#define glUseProgram MANGLE(UseProgram) +#define glUseProgramObjectARB MANGLE(UseProgramObjectARB) +#define glUseProgramStages MANGLE(UseProgramStages) +#define glUseShaderProgramEXT MANGLE(UseShaderProgramEXT) +#define glValidateProgramARB MANGLE(ValidateProgramARB) +#define glValidateProgram MANGLE(ValidateProgram) +#define glValidateProgramPipeline MANGLE(ValidateProgramPipeline) +#define glVariantArrayObjectATI MANGLE(VariantArrayObjectATI) +#define glVariantbvEXT MANGLE(VariantbvEXT) +#define glVariantdvEXT MANGLE(VariantdvEXT) +#define glVariantfvEXT MANGLE(VariantfvEXT) +#define glVariantivEXT MANGLE(VariantivEXT) +#define glVariantPointerEXT MANGLE(VariantPointerEXT) +#define glVariantsvEXT MANGLE(VariantsvEXT) +#define glVariantubvEXT MANGLE(VariantubvEXT) +#define glVariantuivEXT MANGLE(VariantuivEXT) +#define glVariantusvEXT MANGLE(VariantusvEXT) +#define glVDPAUFiniNV MANGLE(VDPAUFiniNV) +#define glVDPAUGetSurfaceivNV MANGLE(VDPAUGetSurfaceivNV) +#define glVDPAUInitNV MANGLE(VDPAUInitNV) +#define glVDPAUIsSurfaceNV MANGLE(VDPAUIsSurfaceNV) +#define glVDPAUMapSurfacesNV MANGLE(VDPAUMapSurfacesNV) +#define glVDPAURegisterOutputSurfaceNV MANGLE(VDPAURegisterOutputSurfaceNV) +#define glVDPAURegisterVideoSurfaceNV MANGLE(VDPAURegisterVideoSurfaceNV) +#define glVDPAUSurfaceAccessNV MANGLE(VDPAUSurfaceAccessNV) +#define glVDPAUUnmapSurfacesNV MANGLE(VDPAUUnmapSurfacesNV) +#define glVDPAUUnregisterSurfaceNV MANGLE(VDPAUUnregisterSurfaceNV) +#define glVertex2d MANGLE(Vertex2d) +#define glVertex2dv MANGLE(Vertex2dv) +#define glVertex2f MANGLE(Vertex2f) +#define glVertex2fv MANGLE(Vertex2fv) +#define glVertex2hNV MANGLE(Vertex2hNV) +#define glVertex2hvNV MANGLE(Vertex2hvNV) +#define glVertex2i MANGLE(Vertex2i) +#define glVertex2iv MANGLE(Vertex2iv) +#define glVertex2s MANGLE(Vertex2s) +#define glVertex2sv MANGLE(Vertex2sv) +#define glVertex3d MANGLE(Vertex3d) +#define glVertex3dv MANGLE(Vertex3dv) +#define glVertex3f MANGLE(Vertex3f) +#define glVertex3fv MANGLE(Vertex3fv) +#define glVertex3hNV MANGLE(Vertex3hNV) +#define glVertex3hvNV MANGLE(Vertex3hvNV) +#define glVertex3i MANGLE(Vertex3i) +#define glVertex3iv MANGLE(Vertex3iv) +#define glVertex3s MANGLE(Vertex3s) +#define glVertex3sv MANGLE(Vertex3sv) +#define glVertex4d MANGLE(Vertex4d) +#define glVertex4dv MANGLE(Vertex4dv) +#define glVertex4f MANGLE(Vertex4f) +#define glVertex4fv MANGLE(Vertex4fv) +#define glVertex4hNV MANGLE(Vertex4hNV) +#define glVertex4hvNV MANGLE(Vertex4hvNV) +#define glVertex4i MANGLE(Vertex4i) +#define glVertex4iv MANGLE(Vertex4iv) +#define glVertex4s MANGLE(Vertex4s) +#define glVertex4sv MANGLE(Vertex4sv) +#define glVertexArrayParameteriAPPLE MANGLE(VertexArrayParameteriAPPLE) +#define glVertexArrayRangeAPPLE MANGLE(VertexArrayRangeAPPLE) +#define glVertexArrayRangeNV MANGLE(VertexArrayRangeNV) +#define glVertexArrayVertexAttribLOffsetEXT MANGLE(VertexArrayVertexAttribLOffsetEXT) +#define glVertexAttrib1dARB MANGLE(VertexAttrib1dARB) +#define glVertexAttrib1d MANGLE(VertexAttrib1d) +#define glVertexAttrib1dNV MANGLE(VertexAttrib1dNV) +#define glVertexAttrib1dvARB MANGLE(VertexAttrib1dvARB) +#define glVertexAttrib1dv MANGLE(VertexAttrib1dv) +#define glVertexAttrib1dvNV MANGLE(VertexAttrib1dvNV) +#define glVertexAttrib1fARB MANGLE(VertexAttrib1fARB) +#define glVertexAttrib1f MANGLE(VertexAttrib1f) +#define glVertexAttrib1fNV MANGLE(VertexAttrib1fNV) +#define glVertexAttrib1fvARB MANGLE(VertexAttrib1fvARB) +#define glVertexAttrib1fv MANGLE(VertexAttrib1fv) +#define glVertexAttrib1fvNV MANGLE(VertexAttrib1fvNV) +#define glVertexAttrib1hNV MANGLE(VertexAttrib1hNV) +#define glVertexAttrib1hvNV MANGLE(VertexAttrib1hvNV) +#define glVertexAttrib1sARB MANGLE(VertexAttrib1sARB) +#define glVertexAttrib1s MANGLE(VertexAttrib1s) +#define glVertexAttrib1sNV MANGLE(VertexAttrib1sNV) +#define glVertexAttrib1svARB MANGLE(VertexAttrib1svARB) +#define glVertexAttrib1sv MANGLE(VertexAttrib1sv) +#define glVertexAttrib1svNV MANGLE(VertexAttrib1svNV) +#define glVertexAttrib2dARB MANGLE(VertexAttrib2dARB) +#define glVertexAttrib2d MANGLE(VertexAttrib2d) +#define glVertexAttrib2dNV MANGLE(VertexAttrib2dNV) +#define glVertexAttrib2dvARB MANGLE(VertexAttrib2dvARB) +#define glVertexAttrib2dv MANGLE(VertexAttrib2dv) +#define glVertexAttrib2dvNV MANGLE(VertexAttrib2dvNV) +#define glVertexAttrib2fARB MANGLE(VertexAttrib2fARB) +#define glVertexAttrib2f MANGLE(VertexAttrib2f) +#define glVertexAttrib2fNV MANGLE(VertexAttrib2fNV) +#define glVertexAttrib2fvARB MANGLE(VertexAttrib2fvARB) +#define glVertexAttrib2fv MANGLE(VertexAttrib2fv) +#define glVertexAttrib2fvNV MANGLE(VertexAttrib2fvNV) +#define glVertexAttrib2hNV MANGLE(VertexAttrib2hNV) +#define glVertexAttrib2hvNV MANGLE(VertexAttrib2hvNV) +#define glVertexAttrib2sARB MANGLE(VertexAttrib2sARB) +#define glVertexAttrib2s MANGLE(VertexAttrib2s) +#define glVertexAttrib2sNV MANGLE(VertexAttrib2sNV) +#define glVertexAttrib2svARB MANGLE(VertexAttrib2svARB) +#define glVertexAttrib2sv MANGLE(VertexAttrib2sv) +#define glVertexAttrib2svNV MANGLE(VertexAttrib2svNV) +#define glVertexAttrib3dARB MANGLE(VertexAttrib3dARB) +#define glVertexAttrib3d MANGLE(VertexAttrib3d) +#define glVertexAttrib3dNV MANGLE(VertexAttrib3dNV) +#define glVertexAttrib3dvARB MANGLE(VertexAttrib3dvARB) +#define glVertexAttrib3dv MANGLE(VertexAttrib3dv) +#define glVertexAttrib3dvNV MANGLE(VertexAttrib3dvNV) +#define glVertexAttrib3fARB MANGLE(VertexAttrib3fARB) +#define glVertexAttrib3f MANGLE(VertexAttrib3f) +#define glVertexAttrib3fNV MANGLE(VertexAttrib3fNV) +#define glVertexAttrib3fvARB MANGLE(VertexAttrib3fvARB) +#define glVertexAttrib3fv MANGLE(VertexAttrib3fv) +#define glVertexAttrib3fvNV MANGLE(VertexAttrib3fvNV) +#define glVertexAttrib3hNV MANGLE(VertexAttrib3hNV) +#define glVertexAttrib3hvNV MANGLE(VertexAttrib3hvNV) +#define glVertexAttrib3sARB MANGLE(VertexAttrib3sARB) +#define glVertexAttrib3s MANGLE(VertexAttrib3s) +#define glVertexAttrib3sNV MANGLE(VertexAttrib3sNV) +#define glVertexAttrib3svARB MANGLE(VertexAttrib3svARB) +#define glVertexAttrib3sv MANGLE(VertexAttrib3sv) +#define glVertexAttrib3svNV MANGLE(VertexAttrib3svNV) +#define glVertexAttrib4bvARB MANGLE(VertexAttrib4bvARB) +#define glVertexAttrib4bv MANGLE(VertexAttrib4bv) +#define glVertexAttrib4dARB MANGLE(VertexAttrib4dARB) +#define glVertexAttrib4d MANGLE(VertexAttrib4d) +#define glVertexAttrib4dNV MANGLE(VertexAttrib4dNV) +#define glVertexAttrib4dvARB MANGLE(VertexAttrib4dvARB) +#define glVertexAttrib4dv MANGLE(VertexAttrib4dv) +#define glVertexAttrib4dvNV MANGLE(VertexAttrib4dvNV) +#define glVertexAttrib4fARB MANGLE(VertexAttrib4fARB) +#define glVertexAttrib4f MANGLE(VertexAttrib4f) +#define glVertexAttrib4fNV MANGLE(VertexAttrib4fNV) +#define glVertexAttrib4fvARB MANGLE(VertexAttrib4fvARB) +#define glVertexAttrib4fv MANGLE(VertexAttrib4fv) +#define glVertexAttrib4fvNV MANGLE(VertexAttrib4fvNV) +#define glVertexAttrib4hNV MANGLE(VertexAttrib4hNV) +#define glVertexAttrib4hvNV MANGLE(VertexAttrib4hvNV) +#define glVertexAttrib4ivARB MANGLE(VertexAttrib4ivARB) +#define glVertexAttrib4iv MANGLE(VertexAttrib4iv) +#define glVertexAttrib4NbvARB MANGLE(VertexAttrib4NbvARB) +#define glVertexAttrib4Nbv MANGLE(VertexAttrib4Nbv) +#define glVertexAttrib4NivARB MANGLE(VertexAttrib4NivARB) +#define glVertexAttrib4Niv MANGLE(VertexAttrib4Niv) +#define glVertexAttrib4NsvARB MANGLE(VertexAttrib4NsvARB) +#define glVertexAttrib4Nsv MANGLE(VertexAttrib4Nsv) +#define glVertexAttrib4NubARB MANGLE(VertexAttrib4NubARB) +#define glVertexAttrib4Nub MANGLE(VertexAttrib4Nub) +#define glVertexAttrib4NubvARB MANGLE(VertexAttrib4NubvARB) +#define glVertexAttrib4Nubv MANGLE(VertexAttrib4Nubv) +#define glVertexAttrib4NuivARB MANGLE(VertexAttrib4NuivARB) +#define glVertexAttrib4Nuiv MANGLE(VertexAttrib4Nuiv) +#define glVertexAttrib4NusvARB MANGLE(VertexAttrib4NusvARB) +#define glVertexAttrib4Nusv MANGLE(VertexAttrib4Nusv) +#define glVertexAttrib4sARB MANGLE(VertexAttrib4sARB) +#define glVertexAttrib4s MANGLE(VertexAttrib4s) +#define glVertexAttrib4sNV MANGLE(VertexAttrib4sNV) +#define glVertexAttrib4svARB MANGLE(VertexAttrib4svARB) +#define glVertexAttrib4sv MANGLE(VertexAttrib4sv) +#define glVertexAttrib4svNV MANGLE(VertexAttrib4svNV) +#define glVertexAttrib4ubNV MANGLE(VertexAttrib4ubNV) +#define glVertexAttrib4ubvARB MANGLE(VertexAttrib4ubvARB) +#define glVertexAttrib4ubv MANGLE(VertexAttrib4ubv) +#define glVertexAttrib4ubvNV MANGLE(VertexAttrib4ubvNV) +#define glVertexAttrib4uivARB MANGLE(VertexAttrib4uivARB) +#define glVertexAttrib4uiv MANGLE(VertexAttrib4uiv) +#define glVertexAttrib4usvARB MANGLE(VertexAttrib4usvARB) +#define glVertexAttrib4usv MANGLE(VertexAttrib4usv) +#define glVertexAttribArrayObjectATI MANGLE(VertexAttribArrayObjectATI) +#define glVertexAttribDivisorARB MANGLE(VertexAttribDivisorARB) +#define glVertexAttribDivisor MANGLE(VertexAttribDivisor) +#define glVertexAttribFormatNV MANGLE(VertexAttribFormatNV) +#define glVertexAttribI1iEXT MANGLE(VertexAttribI1iEXT) +#define glVertexAttribI1i MANGLE(VertexAttribI1i) +#define glVertexAttribI1ivEXT MANGLE(VertexAttribI1ivEXT) +#define glVertexAttribI1iv MANGLE(VertexAttribI1iv) +#define glVertexAttribI1uiEXT MANGLE(VertexAttribI1uiEXT) +#define glVertexAttribI1ui MANGLE(VertexAttribI1ui) +#define glVertexAttribI1uivEXT MANGLE(VertexAttribI1uivEXT) +#define glVertexAttribI1uiv MANGLE(VertexAttribI1uiv) +#define glVertexAttribI2iEXT MANGLE(VertexAttribI2iEXT) +#define glVertexAttribI2i MANGLE(VertexAttribI2i) +#define glVertexAttribI2ivEXT MANGLE(VertexAttribI2ivEXT) +#define glVertexAttribI2iv MANGLE(VertexAttribI2iv) +#define glVertexAttribI2uiEXT MANGLE(VertexAttribI2uiEXT) +#define glVertexAttribI2ui MANGLE(VertexAttribI2ui) +#define glVertexAttribI2uivEXT MANGLE(VertexAttribI2uivEXT) +#define glVertexAttribI2uiv MANGLE(VertexAttribI2uiv) +#define glVertexAttribI3iEXT MANGLE(VertexAttribI3iEXT) +#define glVertexAttribI3i MANGLE(VertexAttribI3i) +#define glVertexAttribI3ivEXT MANGLE(VertexAttribI3ivEXT) +#define glVertexAttribI3iv MANGLE(VertexAttribI3iv) +#define glVertexAttribI3uiEXT MANGLE(VertexAttribI3uiEXT) +#define glVertexAttribI3ui MANGLE(VertexAttribI3ui) +#define glVertexAttribI3uivEXT MANGLE(VertexAttribI3uivEXT) +#define glVertexAttribI3uiv MANGLE(VertexAttribI3uiv) +#define glVertexAttribI4bvEXT MANGLE(VertexAttribI4bvEXT) +#define glVertexAttribI4bv MANGLE(VertexAttribI4bv) +#define glVertexAttribI4iEXT MANGLE(VertexAttribI4iEXT) +#define glVertexAttribI4i MANGLE(VertexAttribI4i) +#define glVertexAttribI4ivEXT MANGLE(VertexAttribI4ivEXT) +#define glVertexAttribI4iv MANGLE(VertexAttribI4iv) +#define glVertexAttribI4svEXT MANGLE(VertexAttribI4svEXT) +#define glVertexAttribI4sv MANGLE(VertexAttribI4sv) +#define glVertexAttribI4ubvEXT MANGLE(VertexAttribI4ubvEXT) +#define glVertexAttribI4ubv MANGLE(VertexAttribI4ubv) +#define glVertexAttribI4uiEXT MANGLE(VertexAttribI4uiEXT) +#define glVertexAttribI4ui MANGLE(VertexAttribI4ui) +#define glVertexAttribI4uivEXT MANGLE(VertexAttribI4uivEXT) +#define glVertexAttribI4uiv MANGLE(VertexAttribI4uiv) +#define glVertexAttribI4usvEXT MANGLE(VertexAttribI4usvEXT) +#define glVertexAttribI4usv MANGLE(VertexAttribI4usv) +#define glVertexAttribIFormatNV MANGLE(VertexAttribIFormatNV) +#define glVertexAttribIPointerEXT MANGLE(VertexAttribIPointerEXT) +#define glVertexAttribIPointer MANGLE(VertexAttribIPointer) +#define glVertexAttribL1dEXT MANGLE(VertexAttribL1dEXT) +#define glVertexAttribL1d MANGLE(VertexAttribL1d) +#define glVertexAttribL1dvEXT MANGLE(VertexAttribL1dvEXT) +#define glVertexAttribL1dv MANGLE(VertexAttribL1dv) +#define glVertexAttribL1i64NV MANGLE(VertexAttribL1i64NV) +#define glVertexAttribL1i64vNV MANGLE(VertexAttribL1i64vNV) +#define glVertexAttribL1ui64NV MANGLE(VertexAttribL1ui64NV) +#define glVertexAttribL1ui64vNV MANGLE(VertexAttribL1ui64vNV) +#define glVertexAttribL2dEXT MANGLE(VertexAttribL2dEXT) +#define glVertexAttribL2d MANGLE(VertexAttribL2d) +#define glVertexAttribL2dvEXT MANGLE(VertexAttribL2dvEXT) +#define glVertexAttribL2dv MANGLE(VertexAttribL2dv) +#define glVertexAttribL2i64NV MANGLE(VertexAttribL2i64NV) +#define glVertexAttribL2i64vNV MANGLE(VertexAttribL2i64vNV) +#define glVertexAttribL2ui64NV MANGLE(VertexAttribL2ui64NV) +#define glVertexAttribL2ui64vNV MANGLE(VertexAttribL2ui64vNV) +#define glVertexAttribL3dEXT MANGLE(VertexAttribL3dEXT) +#define glVertexAttribL3d MANGLE(VertexAttribL3d) +#define glVertexAttribL3dvEXT MANGLE(VertexAttribL3dvEXT) +#define glVertexAttribL3dv MANGLE(VertexAttribL3dv) +#define glVertexAttribL3i64NV MANGLE(VertexAttribL3i64NV) +#define glVertexAttribL3i64vNV MANGLE(VertexAttribL3i64vNV) +#define glVertexAttribL3ui64NV MANGLE(VertexAttribL3ui64NV) +#define glVertexAttribL3ui64vNV MANGLE(VertexAttribL3ui64vNV) +#define glVertexAttribL4dEXT MANGLE(VertexAttribL4dEXT) +#define glVertexAttribL4d MANGLE(VertexAttribL4d) +#define glVertexAttribL4dvEXT MANGLE(VertexAttribL4dvEXT) +#define glVertexAttribL4dv MANGLE(VertexAttribL4dv) +#define glVertexAttribL4i64NV MANGLE(VertexAttribL4i64NV) +#define glVertexAttribL4i64vNV MANGLE(VertexAttribL4i64vNV) +#define glVertexAttribL4ui64NV MANGLE(VertexAttribL4ui64NV) +#define glVertexAttribL4ui64vNV MANGLE(VertexAttribL4ui64vNV) +#define glVertexAttribLFormatNV MANGLE(VertexAttribLFormatNV) +#define glVertexAttribLPointerEXT MANGLE(VertexAttribLPointerEXT) +#define glVertexAttribLPointer MANGLE(VertexAttribLPointer) +#define glVertexAttribP1ui MANGLE(VertexAttribP1ui) +#define glVertexAttribP1uiv MANGLE(VertexAttribP1uiv) +#define glVertexAttribP2ui MANGLE(VertexAttribP2ui) +#define glVertexAttribP2uiv MANGLE(VertexAttribP2uiv) +#define glVertexAttribP3ui MANGLE(VertexAttribP3ui) +#define glVertexAttribP3uiv MANGLE(VertexAttribP3uiv) +#define glVertexAttribP4ui MANGLE(VertexAttribP4ui) +#define glVertexAttribP4uiv MANGLE(VertexAttribP4uiv) +#define glVertexAttribPointerARB MANGLE(VertexAttribPointerARB) +#define glVertexAttribPointer MANGLE(VertexAttribPointer) +#define glVertexAttribPointerNV MANGLE(VertexAttribPointerNV) +#define glVertexAttribs1dvNV MANGLE(VertexAttribs1dvNV) +#define glVertexAttribs1fvNV MANGLE(VertexAttribs1fvNV) +#define glVertexAttribs1hvNV MANGLE(VertexAttribs1hvNV) +#define glVertexAttribs1svNV MANGLE(VertexAttribs1svNV) +#define glVertexAttribs2dvNV MANGLE(VertexAttribs2dvNV) +#define glVertexAttribs2fvNV MANGLE(VertexAttribs2fvNV) +#define glVertexAttribs2hvNV MANGLE(VertexAttribs2hvNV) +#define glVertexAttribs2svNV MANGLE(VertexAttribs2svNV) +#define glVertexAttribs3dvNV MANGLE(VertexAttribs3dvNV) +#define glVertexAttribs3fvNV MANGLE(VertexAttribs3fvNV) +#define glVertexAttribs3hvNV MANGLE(VertexAttribs3hvNV) +#define glVertexAttribs3svNV MANGLE(VertexAttribs3svNV) +#define glVertexAttribs4dvNV MANGLE(VertexAttribs4dvNV) +#define glVertexAttribs4fvNV MANGLE(VertexAttribs4fvNV) +#define glVertexAttribs4hvNV MANGLE(VertexAttribs4hvNV) +#define glVertexAttribs4svNV MANGLE(VertexAttribs4svNV) +#define glVertexAttribs4ubvNV MANGLE(VertexAttribs4ubvNV) +#define glVertexBlendARB MANGLE(VertexBlendARB) +#define glVertexBlendEnvfATI MANGLE(VertexBlendEnvfATI) +#define glVertexBlendEnviATI MANGLE(VertexBlendEnviATI) +#define glVertexFormatNV MANGLE(VertexFormatNV) +#define glVertexP2ui MANGLE(VertexP2ui) +#define glVertexP2uiv MANGLE(VertexP2uiv) +#define glVertexP3ui MANGLE(VertexP3ui) +#define glVertexP3uiv MANGLE(VertexP3uiv) +#define glVertexP4ui MANGLE(VertexP4ui) +#define glVertexP4uiv MANGLE(VertexP4uiv) +#define glVertexPointerEXT MANGLE(VertexPointerEXT) +#define glVertexPointerListIBM MANGLE(VertexPointerListIBM) +#define glVertexPointer MANGLE(VertexPointer) +#define glVertexPointervINTEL MANGLE(VertexPointervINTEL) +#define glVertexStream1dATI MANGLE(VertexStream1dATI) +#define glVertexStream1dvATI MANGLE(VertexStream1dvATI) +#define glVertexStream1fATI MANGLE(VertexStream1fATI) +#define glVertexStream1fvATI MANGLE(VertexStream1fvATI) +#define glVertexStream1iATI MANGLE(VertexStream1iATI) +#define glVertexStream1ivATI MANGLE(VertexStream1ivATI) +#define glVertexStream1sATI MANGLE(VertexStream1sATI) +#define glVertexStream1svATI MANGLE(VertexStream1svATI) +#define glVertexStream2dATI MANGLE(VertexStream2dATI) +#define glVertexStream2dvATI MANGLE(VertexStream2dvATI) +#define glVertexStream2fATI MANGLE(VertexStream2fATI) +#define glVertexStream2fvATI MANGLE(VertexStream2fvATI) +#define glVertexStream2iATI MANGLE(VertexStream2iATI) +#define glVertexStream2ivATI MANGLE(VertexStream2ivATI) +#define glVertexStream2sATI MANGLE(VertexStream2sATI) +#define glVertexStream2svATI MANGLE(VertexStream2svATI) +#define glVertexStream3dATI MANGLE(VertexStream3dATI) +#define glVertexStream3dvATI MANGLE(VertexStream3dvATI) +#define glVertexStream3fATI MANGLE(VertexStream3fATI) +#define glVertexStream3fvATI MANGLE(VertexStream3fvATI) +#define glVertexStream3iATI MANGLE(VertexStream3iATI) +#define glVertexStream3ivATI MANGLE(VertexStream3ivATI) +#define glVertexStream3sATI MANGLE(VertexStream3sATI) +#define glVertexStream3svATI MANGLE(VertexStream3svATI) +#define glVertexStream4dATI MANGLE(VertexStream4dATI) +#define glVertexStream4dvATI MANGLE(VertexStream4dvATI) +#define glVertexStream4fATI MANGLE(VertexStream4fATI) +#define glVertexStream4fvATI MANGLE(VertexStream4fvATI) +#define glVertexStream4iATI MANGLE(VertexStream4iATI) +#define glVertexStream4ivATI MANGLE(VertexStream4ivATI) +#define glVertexStream4sATI MANGLE(VertexStream4sATI) +#define glVertexStream4svATI MANGLE(VertexStream4svATI) +#define glVertexWeightfEXT MANGLE(VertexWeightfEXT) +#define glVertexWeightfvEXT MANGLE(VertexWeightfvEXT) +#define glVertexWeighthNV MANGLE(VertexWeighthNV) +#define glVertexWeighthvNV MANGLE(VertexWeighthvNV) +#define glVertexWeightPointerEXT MANGLE(VertexWeightPointerEXT) +#define glVideoCaptureNV MANGLE(VideoCaptureNV) +#define glVideoCaptureStreamParameterdvNV MANGLE(VideoCaptureStreamParameterdvNV) +#define glVideoCaptureStreamParameterfvNV MANGLE(VideoCaptureStreamParameterfvNV) +#define glVideoCaptureStreamParameterivNV MANGLE(VideoCaptureStreamParameterivNV) +#define glViewportArrayv MANGLE(ViewportArrayv) +#define glViewportIndexedf MANGLE(ViewportIndexedf) +#define glViewportIndexedfv MANGLE(ViewportIndexedfv) +#define glViewport MANGLE(Viewport) +#define glWaitSync MANGLE(WaitSync) +#define glWeightbvARB MANGLE(WeightbvARB) +#define glWeightdvARB MANGLE(WeightdvARB) +#define glWeightfvARB MANGLE(WeightfvARB) +#define glWeightivARB MANGLE(WeightivARB) +#define glWeightPointerARB MANGLE(WeightPointerARB) +#define glWeightsvARB MANGLE(WeightsvARB) +#define glWeightubvARB MANGLE(WeightubvARB) +#define glWeightuivARB MANGLE(WeightuivARB) +#define glWeightusvARB MANGLE(WeightusvARB) +#define glWindowPos2dARB MANGLE(WindowPos2dARB) +#define glWindowPos2d MANGLE(WindowPos2d) +#define glWindowPos2dMESA MANGLE(WindowPos2dMESA) +#define glWindowPos2dvARB MANGLE(WindowPos2dvARB) +#define glWindowPos2dv MANGLE(WindowPos2dv) +#define glWindowPos2dvMESA MANGLE(WindowPos2dvMESA) +#define glWindowPos2fARB MANGLE(WindowPos2fARB) +#define glWindowPos2f MANGLE(WindowPos2f) +#define glWindowPos2fMESA MANGLE(WindowPos2fMESA) +#define glWindowPos2fvARB MANGLE(WindowPos2fvARB) +#define glWindowPos2fv MANGLE(WindowPos2fv) +#define glWindowPos2fvMESA MANGLE(WindowPos2fvMESA) +#define glWindowPos2iARB MANGLE(WindowPos2iARB) +#define glWindowPos2i MANGLE(WindowPos2i) +#define glWindowPos2iMESA MANGLE(WindowPos2iMESA) +#define glWindowPos2ivARB MANGLE(WindowPos2ivARB) +#define glWindowPos2iv MANGLE(WindowPos2iv) +#define glWindowPos2ivMESA MANGLE(WindowPos2ivMESA) +#define glWindowPos2sARB MANGLE(WindowPos2sARB) +#define glWindowPos2s MANGLE(WindowPos2s) +#define glWindowPos2sMESA MANGLE(WindowPos2sMESA) +#define glWindowPos2svARB MANGLE(WindowPos2svARB) +#define glWindowPos2sv MANGLE(WindowPos2sv) +#define glWindowPos2svMESA MANGLE(WindowPos2svMESA) +#define glWindowPos3dARB MANGLE(WindowPos3dARB) +#define glWindowPos3d MANGLE(WindowPos3d) +#define glWindowPos3dMESA MANGLE(WindowPos3dMESA) +#define glWindowPos3dvARB MANGLE(WindowPos3dvARB) +#define glWindowPos3dv MANGLE(WindowPos3dv) +#define glWindowPos3dvMESA MANGLE(WindowPos3dvMESA) +#define glWindowPos3fARB MANGLE(WindowPos3fARB) +#define glWindowPos3f MANGLE(WindowPos3f) +#define glWindowPos3fMESA MANGLE(WindowPos3fMESA) +#define glWindowPos3fvARB MANGLE(WindowPos3fvARB) +#define glWindowPos3fv MANGLE(WindowPos3fv) +#define glWindowPos3fvMESA MANGLE(WindowPos3fvMESA) +#define glWindowPos3iARB MANGLE(WindowPos3iARB) +#define glWindowPos3i MANGLE(WindowPos3i) +#define glWindowPos3iMESA MANGLE(WindowPos3iMESA) +#define glWindowPos3ivARB MANGLE(WindowPos3ivARB) +#define glWindowPos3iv MANGLE(WindowPos3iv) +#define glWindowPos3ivMESA MANGLE(WindowPos3ivMESA) +#define glWindowPos3sARB MANGLE(WindowPos3sARB) +#define glWindowPos3s MANGLE(WindowPos3s) +#define glWindowPos3sMESA MANGLE(WindowPos3sMESA) +#define glWindowPos3svARB MANGLE(WindowPos3svARB) +#define glWindowPos3sv MANGLE(WindowPos3sv) +#define glWindowPos3svMESA MANGLE(WindowPos3svMESA) +#define glWindowPos4dMESA MANGLE(WindowPos4dMESA) +#define glWindowPos4dvMESA MANGLE(WindowPos4dvMESA) +#define glWindowPos4fMESA MANGLE(WindowPos4fMESA) +#define glWindowPos4fvMESA MANGLE(WindowPos4fvMESA) +#define glWindowPos4iMESA MANGLE(WindowPos4iMESA) +#define glWindowPos4ivMESA MANGLE(WindowPos4ivMESA) +#define glWindowPos4sMESA MANGLE(WindowPos4sMESA) +#define glWindowPos4svMESA MANGLE(WindowPos4svMESA) +#define glWriteMaskEXT MANGLE(WriteMaskEXT) + +#endif /* GL_MANGLE_H */