/* * $Id$ * * $Date$ * $Revision$ * * (C) 1999 by Hyperion * All rights reserved * * This file is part of the MiniGL library project * See the file Licence.txt for more details * */ #include "displaylists.h" #include "sysinc.h" #include #include #include #include "util.h" static char rcsid[] UNUSED = "$Id$"; extern uint32 client_texture_state[]; extern int eval_TargetToIndex(GLenum target); /* To be read as 0.0f - 1.0f */ #define READ_COLOR(n) \ float32* cdata = (float32*)data; \ *type = GL_COLOR; \ res = (n); #define READ_FLOAT(n) \ float32* fdata = (float32*)data; \ *type = GL_FLOAT; \ res = (n); #define READ_BOOL(n) \ uint8* bdata = (uint8*)data; \ *type = GL_UNSIGNED_BYTE; \ res = (n); #define READ_INT(n) \ int32* idata = (int32*)data; \ *type = GL_INT; \ res = (n); #define READ_FLOAT1(x) \ *((float32*)data) = (x); \ *type = GL_FLOAT; #define READ_BOOL1(x) \ *((uint8*)data) = (x); \ *type = GL_UNSIGNED_BYTE; #define READ_INT1(x) \ *((int32*)data) = (x); \ *type = GL_INT; static void transferMatrix(float32* fdata, Matrix* m) { *fdata++ = (m->v[OF_11]); *fdata++ = (m->v[OF_21]); *fdata++ = (m->v[OF_31]); *fdata++ = (m->v[OF_41]); *fdata++ = (m->v[OF_12]); *fdata++ = (m->v[OF_22]); *fdata++ = (m->v[OF_32]); *fdata++ = (m->v[OF_42]); *fdata++ = (m->v[OF_13]); *fdata++ = (m->v[OF_23]); *fdata++ = (m->v[OF_33]); *fdata++ = (m->v[OF_43]); *fdata++ = (m->v[OF_14]); *fdata++ = (m->v[OF_24]); *fdata++ = (m->v[OF_34]); *fdata = (m->v[OF_44]); } static void transferMatrixTransposed(float32* fdata, Matrix* m) { *fdata++ = (m->v[OF_11]); *fdata++ = (m->v[OF_12]); *fdata++ = (m->v[OF_13]); *fdata++ = (m->v[OF_14]); *fdata++ = (m->v[OF_21]); *fdata++ = (m->v[OF_22]); *fdata++ = (m->v[OF_23]); *fdata++ = (m->v[OF_24]); *fdata++ = (m->v[OF_31]); *fdata++ = (m->v[OF_32]); *fdata++ = (m->v[OF_33]); *fdata++ = (m->v[OF_34]); *fdata++ = (m->v[OF_41]); *fdata++ = (m->v[OF_42]); *fdata++ = (m->v[OF_43]); *fdata = (m->v[OF_44]); } /** * mglInternalStateGet * * Generic internal implementation to be used by GLGetFloat/Integer/Boolean and friends. * Acceots the queried value enum and populates a region of memory directly with the native * representation of the data, indicating how many entries were written and what kind. * * @param GLcontext* context pointer to the GLcontext instance * @param void* data pointer to raw memory for transfer * @param int* type pointer to an integer which will hold the resulting type info * @param GLenum value the property inspected * @return int32 total number of entries of type transferred */ int32 mglInternalStateGet(GLcontext context, void *data, int32* type, GLenum value) { int32 res = 1; uint32 tmu = context->texture.ActiveTexture; uint32 ctmu = context->vertex_array.ClientActiveTexture; /* dprintf( "mglInternalStateGet(%p, %p, %p, %04X)\n", context, data, type, (unsigned)value ); */ switch (value) { case GL_CURRENT_COLOR: { READ_COLOR(4); *cdata++ = context->current.CurrentColor.r; *cdata++ = context->current.CurrentColor.g; *cdata++ = context->current.CurrentColor.b; *cdata = context->current.CurrentColor.a; break; } case GL_CURRENT_TEXTURE_COORDS: { READ_FLOAT(4); *fdata++ = context->current.CurTexS[tmu]; *fdata++ = context->current.CurTexT[tmu]; *fdata++ = 0.0f; /* Always 0 */ if (context->current.CurTexQValid[tmu]) { *fdata = context->current.CurTexQ[tmu]; } else { *fdata = 1.0f; } break; } case GL_CURRENT_NORMAL: { READ_FLOAT(3); *fdata++ = context->current.CurrentNormal.x; *fdata++ = context->current.CurrentNormal.y; *fdata = context->current.CurrentNormal.z; break; } case GL_CURRENT_FOG_COORD: { READ_FLOAT(1); *fdata = context->current.CurrentFogDepth; break; } case GL_CURRENT_RASTER_POSITION: { READ_FLOAT(4); *fdata++ = context->current.RasterPos.x; *fdata++ = context->current.RasterPos.y; *fdata++ = context->current.RasterPos.z; *fdata = context->current.RasterPos.w; break; } case GL_CURRENT_RASTER_DISTANCE: READ_FLOAT1(context->current.RasterDistance); break; case GL_CURRENT_RASTER_COLOR: { READ_FLOAT(4); *fdata++ = context->current.RasterColor.r; *fdata++ = context->current.RasterColor.g; *fdata++ = context->current.RasterColor.b; *fdata = context->current.RasterColor.a; break; } case GL_CURRENT_RASTER_TEXTURE_COORDS: { READ_FLOAT(4); *fdata++ = context->current.RasterTexCoords[tmu].u; *fdata++ = context->current.RasterTexCoords[tmu].v; *fdata++ = 0.0f; /* Always 0 */ *fdata = context->current.RasterTexCoords[tmu].w; break; } case GL_CURRENT_RASTER_POSITION_VALID: READ_BOOL1(context->current.RasterPosValid); break; case GL_CLIENT_ACTIVE_TEXTURE: READ_INT1(context->vertex_array.ClientActiveTexture); break; case GL_VERTEX_ARRAY: READ_BOOL1(context->vertex_array.ClientState & GLCS_VERTEX ? GL_TRUE : GL_FALSE); break; case GL_VERTEX_ARRAY_SIZE: READ_INT1(context->vertex_array.VertexArray.size); break; case GL_VERTEX_ARRAY_TYPE: READ_INT1(context->vertex_array.VertexArray.type); break; case GL_VERTEX_ARRAY_STRIDE: READ_INT1(context->vertex_array.VertexArray.stride); break; case GL_VERTEX_ARRAY_POINTER: READ_INT1((GLint)context->vertex_array.VertexArray.pointer); break; case GL_NORMAL_ARRAY: READ_BOOL1(context->vertex_array.ClientState & GLCS_NORMAL ? GL_TRUE : GL_FALSE); break; case GL_NORMAL_ARRAY_TYPE: READ_INT1(context->vertex_array.NormalArray.type); break; case GL_NORMAL_ARRAY_STRIDE: READ_INT1(context->vertex_array.NormalArray.stride); break; case GL_NORMAL_ARRAY_POINTER: READ_INT1((GLint)context->vertex_array.NormalArray.pointer); break; case GL_COLOR_ARRAY: READ_BOOL1(context->vertex_array.ClientState & GLCS_COLOR ? GL_TRUE : GL_FALSE); break; case GL_COLOR_ARRAY_SIZE: READ_INT1(context->vertex_array.ColorArray.size); break; case GL_COLOR_ARRAY_TYPE: READ_INT1(context->vertex_array.ColorArray.type); break; case GL_COLOR_ARRAY_STRIDE: READ_INT1(context->vertex_array.ColorArray.stride); break; case GL_COLOR_ARRAY_POINTER: READ_INT1((GLint)context->vertex_array.ColorArray.pointer); break; case GL_LIST_BASE: READ_INT1((GLint)context->DisplayListBaseOffset); break; case GL_MAX_LIST_NESTING: READ_INT1(context->MaxDisplayListNesting); break; case GL_TEXTURE_COORD_ARRAY: READ_BOOL1((context->vertex_array.ClientState & client_texture_state[ctmu]) ? GL_TRUE : GL_FALSE); break; case GL_TEXTURE_COORD_ARRAY_SIZE: READ_INT1(context->vertex_array.TexCoordArray[tmu].size); break; case GL_TEXTURE_COORD_ARRAY_TYPE: READ_INT1(context->vertex_array.TexCoordArray[tmu].type); break; case GL_TEXTURE_COORD_ARRAY_STRIDE: READ_INT1(context->vertex_array.TexCoordArray[tmu].stride); break; case GL_TEXTURE_COORD_ARRAY_POINTER: READ_INT1((GLint)context->vertex_array.TexCoordArray[tmu].pointer); break; case GL_SELECTION_BUFFER_POINTER: READ_INT1((GLint)context->selectionBuffer); break; case GL_MODELVIEW_MATRIX: { READ_FLOAT(16); transferMatrix(fdata, CurrentMV); break; } case GL_TRANSPOSE_MODELVIEW_MATRIX: { READ_FLOAT(16); transferMatrixTransposed(fdata, CurrentMV); break; } case GL_PROJECTION_MATRIX: { READ_FLOAT(16); transferMatrix(fdata, CurrentP); break; } case GL_TRANSPOSE_PROJECTION_MATRIX: { READ_FLOAT(16); transferMatrixTransposed(fdata, CurrentP); break; } case GL_TEXTURE_MATRIX: { READ_FLOAT(16); transferMatrix(fdata, CurrentT); break; } case GL_TRANSPOSE_TEXTURE_MATRIX: { READ_FLOAT(16); transferMatrixTransposed(fdata, CurrentT); break; } case GL_VIEWPORT: { READ_INT(4); *idata++ = (context->viewport.x); *idata++ = (context->viewport.y); *idata++ = (context->viewport.w); *idata = (context->viewport.h); break; } case GL_DEPTH_RANGE: { READ_FLOAT(2); *fdata++ = (context->viewport.near); *fdata = (context->viewport.far); break; } case GL_MODELVIEW_STACK_DEPTH: READ_INT1(context->ModelViewStackPointer); break; case GL_PROJECTION_STACK_DEPTH: READ_INT1(context->ProjectionStackPointer); break; case GL_TEXTURE_STACK_DEPTH: READ_INT1(context->TextureStackPointer[tmu]); break; case GL_MATRIX_MODE: READ_INT1(context->transform.CurrentMatrixMode); break; case GL_NORMALIZE: READ_BOOL1(context->Normalize); 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: READ_BOOL1(context->enable.ClipPlane[value-GL_CLIP_PLANE0]); break; case GL_FOG_COLOR: { READ_COLOR(4); *cdata++ = (context->fog.FogColor.r); *cdata++ = (context->fog.FogColor.g); *cdata++ = (context->fog.FogColor.b); *cdata = (context->fog.FogColor.a); break; } case GL_FOG_INDEX: res = 0; break; /* No index mode */ case GL_FOG_DENSITY: READ_FLOAT1(context->fog.FogDensity); break; case GL_FOG_START: READ_FLOAT1(context->fog.FogStart); break; case GL_FOG_END: READ_FLOAT1(context->fog.FogEnd); break; case GL_FOG_MODE: READ_FLOAT1(context->fog.FogMode); break; case GL_FOG: READ_BOOL1(context->enable.Fog); break; case GL_COLOR_SUM: res = 0; break; /* FIXME */ case GL_SHADE_MODEL: READ_INT1(context->lighting.ShadeModel); break; case GL_LIGHTING: READ_BOOL1(context->enable.Lighting); break; case GL_COLOR_MATERIAL: READ_BOOL1(context->enable.ColorMaterial); break; case GL_COLOR_MATERIAL_PARAMETER: READ_INT1(context->lighting.ColorMaterialParameter); break; case GL_COLOR_MATERIAL_FACE: READ_INT1(context->lighting.ColorMaterialFace); break; case GL_LIGHT_MODEL_AMBIENT: { READ_COLOR(4); *cdata++ = (context->lighting.LightModelAmbient.r); *cdata++ = (context->lighting.LightModelAmbient.g); *cdata++ = (context->lighting.LightModelAmbient.b); *cdata = (context->lighting.LightModelAmbient.a); break; } case GL_LIGHT_MODEL_LOCAL_VIEWER: READ_BOOL1(context->lighting.LightModelLocalViewer); break; case GL_LIGHT_MODEL_TWO_SIDE: READ_BOOL1(context->lighting.LightModelTwoSide); break; case GL_LIGHT_MODEL_COLOR_CONTROL: READ_INT1(context->lighting.LightModelColorControl); 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: READ_BOOL1(context->enable.Light[value-GL_LIGHT0]); break; case GL_MAX_LIGHTS: READ_INT1(MGL_MAX_LIGHTS); break; case GL_NAME_STACK_DEPTH: READ_INT1(context->nameStackPointer + 1); break; case GL_MAX_NAME_STACK_DEPTH: READ_INT1(NAME_STACK_SIZE); break; case GL_RENDER_MODE: READ_INT1(context->renderMode); break; // ? was missing with no fall through case GL_POINT_SIZE: READ_FLOAT1(context->point.PointSize); break; case GL_POINT_SMOOTH: READ_BOOL1(context->enable.PointSmooth); break; case GL_POINT_SIZE_MIN: READ_FLOAT1(0.0f); break; /* FIXME */ case GL_POINT_SIZE_MAX: READ_FLOAT1(8.0f); break; /* FIXME */ case GL_POINT_SIZE_RANGE: { READ_FLOAT(2); *fdata++ = 0.0f; *fdata = 8.0f; break; } case GL_PACK_SWAP_BYTES: READ_BOOL1(context->pixel_store.pack.swap_bytes); break; case GL_PACK_LSB_FIRST: READ_BOOL1(context->pixel_store.pack.lsb_first); break; case GL_PACK_ROW_LENGTH: READ_INT1(context->pixel_store.pack.row_length); break; case GL_PACK_SKIP_ROWS: READ_INT1(context->pixel_store.pack.skip_rows); break; case GL_PACK_SKIP_PIXELS: READ_INT1(context->pixel_store.pack.skip_pixels); break; case GL_PACK_ALIGNMENT: READ_INT1(context->pixel_store.pack.alignment); break; case GL_UNPACK_SWAP_BYTES: READ_BOOL1(context->pixel_store.unpack.swap_bytes); break; case GL_UNPACK_LSB_FIRST: READ_BOOL1(context->pixel_store.unpack.lsb_first); break; case GL_UNPACK_ROW_LENGTH: READ_INT1(context->pixel_store.unpack.row_length); break; case GL_UNPACK_SKIP_ROWS: READ_INT1(context->pixel_store.unpack.skip_rows); break; case GL_UNPACK_SKIP_PIXELS: READ_INT1(context->pixel_store.unpack.skip_pixels); break; case GL_UNPACK_ALIGNMENT: READ_INT1(context->pixel_store.unpack.alignment); break; case GL_MAP_COLOR: READ_BOOL1(context->pixel.map_color); break; case GL_MAP_STENCIL: READ_BOOL1(context->pixel.map_stencil); break; case GL_ALPHA_SCALE: READ_FLOAT1(context->pixel.alpha_scale); break; case GL_BLUE_SCALE: READ_FLOAT1(context->pixel.blue_scale); break; case GL_GREEN_SCALE: READ_FLOAT1(context->pixel.green_scale); break; case GL_RED_SCALE: READ_FLOAT1(context->pixel.red_scale); break; case GL_DEPTH_SCALE: READ_FLOAT1(context->pixel.depth_scale); break; case GL_ALPHA_BIAS: READ_FLOAT1(context->pixel.alpha_bias); break; case GL_BLUE_BIAS: READ_FLOAT1(context->pixel.blue_bias); break; case GL_GREEN_BIAS: READ_FLOAT1(context->pixel.green_bias); break; case GL_RED_BIAS: READ_FLOAT1(context->pixel.red_bias); break; case GL_DEPTH_BIAS: READ_FLOAT1(context->pixel.depth_bias); break; case GL_READ_BUFFER: READ_INT1(context->color_buffer.ReadBuffer); break; case GL_DRAW_BUFFER: READ_INT1(context->color_buffer.DrawBuffer); break; case GL_ZOOM_X: READ_FLOAT1(context->pixel.zoom_x); break; case GL_ZOOM_Y: READ_FLOAT1(context->pixel.zoom_y); break; case GL_MAX_TEXTURE_UNITS: READ_INT1(context->NumTextureUnits); break; case GL_MAX_TEXTURE_SIZE: READ_INT1( (int32)(IWarp3D->W3D_Query(context->w3dContext, W3D_Q_MAXTEXWIDTH, 0)) ); break; case GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT: READ_INT1(context->MaxAnisotropy); break; case GL_MAP1_GRID_DOMAIN: { READ_INT(2) *idata++ = (context->evaluator.u1.start); *idata = (context->evaluator.u1.end); break; } case GL_MAP2_GRID_DOMAIN: { READ_INT(4); *idata++ = (context->evaluator.u2.start); *idata++ = (context->evaluator.u2.end); *idata++ = (context->evaluator.v2.start); *idata = (context->evaluator.v2.end); break; } case GL_MAP1_GRID_SEGMENTS: READ_INT1(context->evaluator.u1.num); break; case GL_MAP2_GRID_SEGMENTS: { READ_INT(2); *idata++ = (context->evaluator.u2.num); *idata = (context->evaluator.v2.num); break; } case GL_ALPHA_TEST_FUNC: READ_INT1(context->color_buffer.AlphaTestFunc); break; case GL_ALPHA_TEST_REF: READ_FLOAT1(context->color_buffer.AlphaTestRef); break; case GL_SCISSOR_BOX: { READ_INT(4); *idata++ = (context->scissor.x); *idata++ = (context->scissor.y); *idata++ = (context->scissor.w); *idata = (context->scissor.h); break; } case GL_BLEND_DST: READ_INT1(context->color_buffer.BlendDst); break; case GL_BLEND_SRC: READ_INT1(context->color_buffer.BlendSrc); break; case GL_COLOR_CLEAR_VALUE: { READ_COLOR(4); *cdata++ = context->color_buffer.ClearColorRec.r; *cdata++ = context->color_buffer.ClearColorRec.g; *cdata++ = context->color_buffer.ClearColorRec.b; *cdata = context->color_buffer.ClearColorRec.a; break; } case GL_STENCIL_BITS: READ_INT1((context->Params.newStencilBuffer == GL_TRUE) ? 8 : 0); break; /* FIXME: assumes 8-bit stencil */ #ifdef MGL_TEXTURE_COMPRESSION case GL_COMPRESSED_TEXTURE_FORMATS_ARB: { READ_INT(0); if (context->textureSupport[W3D_COMPRESSED_R5G6B5] & W3D_TEXFMT_FAST) { *idata++ = GL_RGB_S3TC; *idata++ = GL_RGB4_S3TC; *idata++ = GL_COMPRESSED_RGB_ARB; *idata++ = GL_COMPRESSED_RGB_S3TC_DXT1_EXT; *idata++ = GL_COMPRESSED_RGBA_S3TC_DXT1_EXT; res += 5; } if (context->textureSupport[W3D_A4_COMPRESSED_R5G6B5] & W3D_TEXFMT_FAST) { *idata++ = GL_RGBA_S3TC; *idata++ = GL_RGBA4_S3TC; *idata++ = GL_COMPRESSED_RGBA_ARB; *idata++ = GL_COMPRESSED_RGBA_S3TC_DXT3_EXT; res += 4; } if (context->textureSupport[W3D_COMPRESSED_A8R5G6B5] & W3D_TEXFMT_FAST) { *idata++ = GL_COMPRESSED_RGBA_S3TC_DXT5_EXT; res += 1; } break; } case GL_NUM_COMPRESSED_TEXTURE_FORMATS_ARB: { int32 numformats = 0; if (context->textureSupport[W3D_COMPRESSED_R5G6B5] & W3D_TEXFMT_FAST) { numformats += 5; } if (context->textureSupport[W3D_A4_COMPRESSED_R5G6B5] & W3D_TEXFMT_FAST) { numformats += 4; } if (context->textureSupport[W3D_COMPRESSED_A8R5G6B5] & W3D_TEXFMT_FAST) { numformats += 1; } READ_INT1(numformats); break; } #endif /* -------------- ONLY ENABLES BEYOND THIS POINT ---------------------- */ /* FIXME: Add other state not required for second milestone */ case GL_MAP1_TEXTURE_COORD_1: case GL_MAP1_TEXTURE_COORD_2: case GL_MAP1_TEXTURE_COORD_3: case GL_MAP1_TEXTURE_COORD_4: case GL_MAP1_VERTEX_3: case GL_MAP1_VERTEX_4: case GL_MAP1_NORMAL: case GL_MAP1_COLOR_4: { READ_BOOL1(context->enable.Map1[eval_TargetToIndex(value)]); break; } case GL_MAP2_TEXTURE_COORD_1: case GL_MAP2_TEXTURE_COORD_2: case GL_MAP2_TEXTURE_COORD_3: case GL_MAP2_TEXTURE_COORD_4: case GL_MAP2_VERTEX_3: case GL_MAP2_VERTEX_4: case GL_MAP2_NORMAL: case GL_MAP2_COLOR_4: { READ_BOOL1(context->enable.Map1[eval_TargetToIndex(value)]); break; } case GL_AUTO_NORMAL: READ_BOOL1(context->enable.AutoNormal); break; case GL_LINE_SMOOTH: READ_BOOL1(context->enable.LineSmooth); break; case GL_LINE_STIPPLE: READ_BOOL1(context->enable.LineStipple); break; case GL_CULL_FACE: READ_BOOL1(context->enable.CullFace); break; case GL_POLYGON_SMOOTH: READ_BOOL1(context->enable.PolygonSmooth); break; case GL_POLYGON_OFFSET_FILL: READ_BOOL1(context->enable.PolygonOffsetFill); break; case GL_POLYGON_STIPPLE: READ_BOOL1(context->enable.PolygonStipple); break; case GL_TEXTURE_1D: READ_BOOL1(context->enable.Texture1D[tmu]); break; case GL_TEXTURE_2D: READ_BOOL1(context->enable.Texture2D[tmu]); break; case GL_TEXTURE_GEN_S: READ_BOOL1(context->enable.TexGenS[tmu]); break; case GL_TEXTURE_GEN_T: READ_BOOL1(context->enable.TexGenT[tmu]); break; case GL_TEXTURE_GEN_Q: READ_BOOL1(context->enable.TexGenQ[tmu]); break; case GL_SCISSOR_TEST: READ_BOOL1(context->enable.ScissorTest); break; case GL_ALPHA_TEST: READ_BOOL1(context->enable.AlphaTest); break; case GL_STENCIL_TEST: READ_BOOL1(context->enable.StencilTest); break; case GL_DEPTH_TEST: READ_BOOL1(context->enable.DepthTest); break; case GL_BLEND: READ_BOOL1(context->enable.Blend); break; case GL_DITHER: READ_BOOL1(context->enable.Dither); break; /* THESE NEED ATTENTION */ case GL_CURRENT_SECONDARY_COLOR: case GL_CURRENT_INDEX: case GL_CURRENT_RASTER_INDEX: res = 0; break; /* FIXME */ case GL_EDGE_FLAG: case GL_FOG_COORD_ARRAY: case GL_FOG_COORD_ARRAY_TYPE: case GL_FOG_COORD_ARRAY_STRIDE: case GL_FOG_COORD_ARRAY_POINTER: case GL_SECONDARY_COLOR_ARRAY: case GL_SECONDARY_COLOR_ARRAY_SIZE: case GL_SECONDARY_COLOR_ARRAY_TYPE: case GL_SECONDARY_COLOR_ARRAY_STRIDE: case GL_SECONDARY_COLOR_ARRAY_POINTER: case GL_INDEX_ARRAY: case GL_INDEX_ARRAY_TYPE: case GL_INDEX_ARRAY_STRIDE: case GL_INDEX_ARRAY_POINTER: case GL_EDGE_FLAG_ARRAY: case GL_EDGE_FLAG_ARRAY_STRIDE: case GL_EDGE_FLAG_ARRAY_POINTER: case GL_RESCALE_NORMAL: case GL_POLYGON_OFFSET_POINT: case GL_POLYGON_OFFSET_LINE: case GL_TEXTURE_CUBE_MAP: case GL_TEXTURE_GEN_R: READ_BOOL1(GL_FALSE); break; /* FIXME */ default: /* dprintf("Unsupported glGet %04X\n", value); */ res = 0; break; } return res; }