/* * $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 "selection.h" #include "smartlock.h" #include "sysinc.h" #include #include #include #include #include #include "util.h" static char rcsid[] UNUSED = "$Id$"; #ifndef MIN #define MIN(a, b) ((a) < (b) ? (a) : (b)) #endif // The default maximum lock time for smart-locking #define DEF_MAXLOCKTIME 50000 extern void EstablishCullState(); extern void GLMatrixInit(GLcontext context); GLboolean MGLInitContext(GLcontext context); extern void RebindTextures(GLcontext context); extern void DisableBlendStage(GLcontext context, uint32 stage); extern void SetBlendStageState(GLcontext context, uint32 stage); extern void light_Init(GLcontext context); extern void light_Recalculate(GLcontext context, GLuint light); extern GLboolean MGLAllocVertexBuffer(GLcontext context, GLuint size); extern void eval_InitEvaluator(GLcontext context); extern void eval_TermEvaluator(GLcontext context); extern void tex_FreeTextures(GLcontext context); extern void buf_InitBuffer(GLcontext, GLbuffer *); extern GLboolean vid_SetBitmap(GLcontext context, struct BitMap *pBitmap, int *width, int *height); extern GLboolean vid_OpenWindow(GLcontext context, int width, int height, int left, int top); extern GLboolean vid_OpenDisplay(GLcontext context, int width, int height, uint32 mode); extern GLboolean vid_CreateWarp3DContext(GLcontext context); extern GLboolean vid_AllocDepthStencil(GLcontext context, GLboolean setstate); extern void vid_SetDefaultStates(GLcontext context); extern void vid_DestroyWarp3DContext(GLcontext context); extern void vid_CloseCurrentDisplay(GLcontext context); extern void buf_SetFrontBuffer(GLcontext context, void *bitmap, GLboolean free); extern void buf_SetBackBuffer(GLcontext context, void *bitmap, GLboolean free); extern int32 mapMGLZTestToW3D(int32 mglZ, int32 defZ); int strcasecmp(const char *s1, const char *s2); void cgl_GLDeleteLists(struct GLContextIFace *Self, GLuint list, GLsizei range); #define DEBUG(x) IExec->DebugPrintF(x) void cgl_GLScissor(struct GLContextIFace *Self, GLint x, GLint y, GLsizei width, GLsizei height) { GLcontext context = GET_INSTANCE(Self); DL_CHECK(Scissor(Self, x, y, width, height)); context->scissor.x = x; context->scissor.y = y; context->scissor.w = width; context->scissor.h = height; if (y < 0) { height += y; y = 0; } if (x < 0) { width += x; x = 0; } if ((height + y) > context->w3dContext->height) { height = context->w3dContext->height - y; } if ((width + x) > context->w3dContext->width) { width = context->w3dContext->width - x; } context->w3dScissor.left = x; context->w3dScissor.top = context->w3dContext->height-y-height; context->w3dScissor.width = width; context->w3dScissor.height = height; if (context->enable.ScissorTest) { IWarp3D->W3D_SetScissor(context->w3dContext, &(context->w3dScissor)); } } void cgl_GLClearStencil(struct GLContextIFace *Self, GLint s) { GLcontext context = GET_INSTANCE(Self); DL_CHECK(ClearStencil(Self, s)); context->stencil_buffer.ClearStencil = s; } void cgl_GLClearColor(struct GLContextIFace *Self, GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha) { GLcontext context = GET_INSTANCE(Self); DL_CHECK(ClearColor(Self, red, green, blue, alpha)); context->color_buffer.ClearColorRec.r = red; context->color_buffer.ClearColorRec.g = green; context->color_buffer.ClearColorRec.b = blue; context->color_buffer.ClearColorRec.a = alpha; #if 0 red *= 255.0; green *= 255.0; blue *= 255.0; alpha *= 255.0; context->ClearColor = ((GLubyte)(alpha)<<24) | ((GLubyte)(red)<<16) | ((GLubyte)(green)<<8) | ((GLubyte)(blue)); #endif } void cgl_GLDepthMask(struct GLContextIFace *Self, GLboolean flag) { GLcontext context = GET_INSTANCE(Self); DL_CHECK(DepthMask(Self, flag)); if (flag == GL_FALSE) { IWarp3D->W3D_SetState(context->w3dContext, W3D_ZBUFFERUPDATE, W3D_DISABLE); } else { IWarp3D->W3D_SetState(context->w3dContext, W3D_ZBUFFERUPDATE, W3D_ENABLE); } context->depth_buffer.DepthWriteMask = flag; } void cgl_GLDepthFunc(struct GLContextIFace *Self, GLenum func) { GLcontext context = GET_INSTANCE(Self); DL_CHECK(DepthFunc(Self, func)); int32 w3dmode = mapMGLZTestToW3D(func, W3D_ILLEGALINPUT); // This assertion may be compiled away GLFlagError(context, (w3dmode==W3D_ILLEGALINPUT), GL_INVALID_ENUM); if (w3dmode != W3D_ILLEGALINPUT) { IWarp3D->W3D_SetZCompareMode(context->w3dContext, w3dmode); context->depth_buffer.DepthFunc = func; } } void cgl_GLClearDepth(struct GLContextIFace *Self, GLclampd depth) { GLcontext context = GET_INSTANCE(Self); DL_CHECK(ClearDepth(Self, depth)); context->depth_buffer.ClearDepth = (W3D_Double)depth; } void cgl_GLClear(struct GLContextIFace *Self, GLbitfield mask) { GLcontext context = GET_INSTANCE(Self); DL_CHECK(Clear(Self, mask)); GLboolean unlock = GL_FALSE; if (context->LockMode == MGL_LOCK_SMART) { if (context->w3dLocked == GL_FALSE) { unlock = GL_TRUE; } smartlock_beginDraw(context->smartLock); } else if (context->w3dLocked == GL_FALSE) { IWarp3D->W3D_LockHardware(context->w3dContext); } W3D_Color *color = NULL; W3D_Double *depth = NULL; uint32 *stencil = NULL; if (mask & GL_COLOR_BUFFER_BIT) { color = &(context->color_buffer.ClearColorRec); } if (mask & GL_DEPTH_BUFFER_BIT) { depth = &(context->depth_buffer.ClearDepth); } if (mask & GL_STENCIL_BUFFER_BIT) { stencil = (uint32 *)&(context->stencil_buffer.ClearStencil); } IWarp3D->W3D_ClearBuffers(context->w3dContext, color, depth, stencil); if (context->LockMode == MGL_LOCK_SMART) { smartlock_endDraw(context->smartLock); if (unlock) { // This helps reduce audio stuttering smartlock_forceUnlock(context->smartLock); } } else if (context->w3dLocked == GL_FALSE) { IWarp3D->W3D_UnLockHardware(context->w3dContext); } context->fbDirty = GL_TRUE; } #ifdef AUTOMATIC_LOCKING_ENABLE void cgl_LockMode(struct GLContextIFace *Self, GLenum lockMode) { GLcontext context = GET_INSTANCE(Self); context->LockMode = lockMode; if (context->LockMode == MGL_LOCK_SMART && !context->smartLock){ // Smart locking unavailable context->LockMode = MGL_LOCK_AUTOMATIC; } #ifndef GLNDEBUG dprintf("Lockmode set to "); if (context->LockMode == MGL_LOCK_MANUAL) { kprintf("MGL_LOCK_MANUAL\n"); } else if (context->LockMode == MGL_LOCK_AUTOMATIC) { kprintf("MGL_LOCK_AUTOMATIC\n"); } else if (context->LockMode == MGL_LOCK_SMART) { kprintf("MGL_LOCK_SMART\n"); } else { kprintf("unknown\n"); } #endif } #endif GLboolean cgl_LockDisplay(struct GLContextIFace *Self) { uint32 error; GLcontext context = GET_INSTANCE(Self); if (context->w3dLocked == GL_TRUE) { return GL_TRUE; // nothing to do if we are already locked } context->fbDirty = GL_TRUE; switch(context->LockMode) { case MGL_LOCK_MANUAL: error = IWarp3D->W3D_LockHardware(context->w3dContext); if (error == W3D_SUCCESS) { context->w3dLocked = GL_TRUE; return GL_TRUE; } break; case MGL_LOCK_AUTOMATIC: // These modes do not require the lock right here. case MGL_LOCK_SMART: return GL_TRUE; break; } dprintf("[MGLLockDisplay] Unable to lock\n"); return GL_FALSE; // If we got here, there was an error } void cgl_UnlockDisplay(struct GLContextIFace *Self) { GLcontext context = GET_INSTANCE(Self); if (context->w3dLocked == GL_FALSE) { return; } switch (context->LockMode) { case MGL_LOCK_AUTOMATIC: break; case MGL_LOCK_SMART: smartlock_forceUnlock(context->smartLock); break; case MGL_LOCK_MANUAL: IWarp3D->W3D_UnLockHardware(context->w3dContext); context->w3dLocked = GL_FALSE; break; } } void cgl_EnableSync(struct GLContextIFace *Self, GLboolean enable) { GLcontext context = GET_INSTANCE(Self); context->DoSync = enable; } GLboolean MGLEnsureVertexBufferSize(GLcontext context, GLuint size) { void *oldvb; uint32 oldSize; if (size <= context->VertexBufferSize) { return GL_TRUE; } /* Need to enlarge */ oldvb = context->VertexBuffer; oldSize = context->VertexBufferSize; if (MGLAllocVertexBuffer(context, size)) { /* Got a new one, copy the old one */ memcpy(context->VertexBuffer, oldvb, oldSize * sizeof(MGLVertex)); FreeVecInternal(oldvb); return GL_TRUE; } /* If we get here, it didn'T work. Put the old one back */ context->VertexBuffer = oldvb; context->VertexBufferSize = oldSize; return GL_FALSE; } GLboolean MGLAllocVertexBuffer(GLcontext context, GLuint size) { int i; context->VertexBuffer = AllocVecInternal(sizeof(MGLVertex)*size, MEMF_ANY); if (!context->VertexBuffer) { return GL_FALSE; } context->VertexBufferSize = (GLuint)size; context->VertexBufferPointer= 0; /* Set frame codes */ for (i = 0; i < context->VertexBufferSize; i++) { context->VertexBuffer[i].frame_code = 0xffffffff; context->VertexBuffer[i].tex_frame_code = 0xffffffff; } return GL_TRUE; } GLboolean MGLInitContext(GLcontext context) { int i; char buffer[10]; GLuint clipMask; context->GrabMouse = GL_FALSE; context->CurrentPrimitive = GL_BASE; context->CurrentError = GL_NO_ERROR; if (!MGLAllocVertexBuffer(context, context->Params.newVertexBufferSize)) { return GL_FALSE; } context->UseVertexResidue = GL_FALSE; context->IndexBuffer = AllocVecInternal(sizeof(GLuint) * context->Params.newVertexBufferSize, MEMF_ANY); if (!context->IndexBuffer) { return GL_FALSE; } context->DisplayListArray = AllocVecInternal( sizeof(void*) * context->Params.newDisplayListArraySize, MEMF_ANY | MEMF_CLEAR ); if (!context->DisplayListArray){ return GL_FALSE; } context->TargetDisplayListStart = 0; context->TargetDisplayListEnd = 0; context->DisplayListCompileError = 0; context->MaxDisplayListNesting = context->Params.maxDisplayListNesting; context->DisplayListNestingLevel = 0; context->DisplayListBaseOffset = 0; context->DisplayListArraySize = context->Params.newDisplayListArraySize; context->TexBufferSize = context->Params.newTextureBufferSize; context->GeneratedTextures = AllocVecInternal(sizeof(GLubyte) * context->Params.newTextureBufferSize, MEMF_ANY); context->LargePolygon = (MGLPolygon*) AllocVecInternal( sizeof(MGLPolygon) + (MGL_MAXVERTS * sizeof (GLint)), MEMF_CLEAR ); if (!context->LargePolygon) { return GL_FALSE; } context->LargePolygonOut = (MGLPolygon*) AllocVecInternal( sizeof(MGLPolygon) + (2 * MGL_MAXVERTS * sizeof (GLint)), MEMF_CLEAR ); if (!context->LargePolygonOut) { return GL_FALSE; } if (!context->GeneratedTextures) { return GL_FALSE; } context->w3dTextures = AllocVecInternal(sizeof(MGLTexture) * context->Params.newTextureBufferSize, MEMF_ANY); if (!context->w3dTextures) { return GL_FALSE; } context->NumTextureUnits = IWarp3D->W3D_Query(context->w3dContext, W3D_Q_NUM_TMU, 0); context->NumTextureUnits = MIN(context->NumTextureUnits, MAX_TEXTURE_UNITS); // Can't have more texture units, even if the driver supports it for (i=0; iParams.newTextureBufferSize; i++) { context->w3dTextures[i].texObj = NULL; context->w3dTextures[i].texData = NULL; context->GeneratedTextures[i] = 0; } for (i = 0; i < context->NumTextureUnits; i++) { context->current.CurTexS[i] = 0.0; context->current.CurTexT[i] = 0.0; context->current.CurTexQ[i] = 1.0; context->current.CurTexQValid[i] = GL_FALSE; context->enable.Texture1D[i] = GL_FALSE; context->enable.Texture2D[i] = GL_FALSE; context->texture.TexGenS[i].mode = GL_EYE_LINEAR; context->texture.TexGenT[i].mode = GL_EYE_LINEAR; context->texture.TexGenQ[i].mode = GL_EYE_LINEAR; context->enable.TexGenS[i] = GL_FALSE; context->enable.TexGenT[i] = GL_FALSE; context->enable.TexGenQ[i] = GL_FALSE; context->texture.TexGenS[i].objectPlane[0] = 1.0; context->texture.TexGenS[i].objectPlane[1] = 0.0; context->texture.TexGenS[i].objectPlane[2] = 0.0; context->texture.TexGenS[i].objectPlane[3] = 0.0; context->texture.TexGenT[i].objectPlane[0] = 0.0; context->texture.TexGenT[i].objectPlane[1] = 1.0; context->texture.TexGenT[i].objectPlane[2] = 0.0; context->texture.TexGenT[i].objectPlane[3] = 0.0; context->texture.TexGenQ[i].objectPlane[0] = 0.0; context->texture.TexGenQ[i].objectPlane[1] = 0.0; context->texture.TexGenQ[i].objectPlane[2] = 0.0; context->texture.TexGenQ[i].objectPlane[3] = 0.0; context->texture.TexGenS[i].eyePlane[0] = 1.0; context->texture.TexGenS[i].eyePlane[1] = 0.0; context->texture.TexGenS[i].eyePlane[2] = 0.0; context->texture.TexGenS[i].eyePlane[3] = 0.0; context->texture.TexGenT[i].eyePlane[0] = 0.0; context->texture.TexGenT[i].eyePlane[1] = 1.0; context->texture.TexGenT[i].eyePlane[2] = 0.0; context->texture.TexGenT[i].eyePlane[3] = 0.0; context->texture.TexGenQ[i].eyePlane[0] = 0.0; context->texture.TexGenQ[i].eyePlane[1] = 0.0; context->texture.TexGenQ[i].eyePlane[2] = 0.0; context->texture.TexGenQ[i].eyePlane[3] = 0.0; context->texture.TextureEnv[i] = GL_MODULATE; context->texture.CurrentBinding[i] = 0; IWarp3D->W3D_SetTextureBlendTags( context->w3dContext, W3D_BLEND_STAGE, i, W3D_ENV_MODE, W3D_OFF, TAG_DONE ); } context->texture.MinFilter = GL_NEAREST; context->texture.MagFilter = GL_NEAREST; context->texture.WrapS = GL_REPEAT; context->texture.WrapT = GL_REPEAT; /* Multitexturing */ context->texture.ActiveTexture = 0; context->texture.MaxTextureUnit = -1; /* Initialize texture env combine values */ for (i=0; icombineDirty[i] = GL_TRUE; context->texture.colorCombine[i] = GL_MODULATE; context->texture.alphaCombine[i] = GL_MODULATE; context->texture.colorSource[0][i] = GL_TEXTURE; context->texture.colorSource[1][i] = GL_PREVIOUS; context->texture.colorSource[2][i] = GL_CONSTANT; context->texture.alphaSource[0][i] = GL_TEXTURE; context->texture.alphaSource[1][i] = GL_PREVIOUS; context->texture.alphaSource[2][i] = GL_CONSTANT; context->texture.colorOperand[0][i] = GL_SRC_COLOR; context->texture.colorOperand[1][i] = GL_SRC_COLOR; context->texture.colorOperand[2][i] = GL_SRC_ALPHA; context->texture.alphaOperand[0][i] = GL_SRC_ALPHA; context->texture.alphaOperand[1][i] = GL_SRC_ALPHA; context->texture.alphaOperand[2][i] = GL_SRC_ALPHA; context->texture.envColor[i].r = 0.0f; context->texture.envColor[i].g = 0.0f; context->texture.envColor[i].b = 0.0f; context->texture.envColor[i].a = 0.0f; context->texture.colorScale[i] = 1; context->texture.alphaScale[i] = 1; } context->ConvertTo16Bit = GL_FALSE; context->ConvertBuffer = 0; context->ConvertBufferSize = 0; context->FogDirty = GL_FALSE; context->current.CurrentFogDepth = 1.0; context->fog.CurrentFogSource = GL_FRAGMENT_DEPTH; context->fog.FogStart = 1.0; context->fog.FogEnd = 0.0; context->w3dFog.fog_start = 1.0; context->w3dFog.fog_end = 0.1; context->w3dFog.fog_density = 1.0; context->w3dFog.fog_color.r = 0.0; context->w3dFog.fog_color.g = 0.0; context->w3dFog.fog_color.b = 0.0; context->FogRange = 1.0; context->enable.AlphaTest = GL_FALSE; context->enable.Blend = GL_FALSE; context->enable.Fog = GL_FALSE; context->enable.ScissorTest = GL_FALSE; context->enable.CullFace = GL_FALSE; context->enable.DepthTest = GL_FALSE; context->enable.PointSmooth = GL_FALSE; context->enable.Dither = GL_TRUE; context->enable.ZOffset = GL_FALSE; context->enable.PolygonOffsetFill = GL_FALSE; context->enable.ColorLogicOp = GL_FALSE; context->polygon.CullFace = GL_BACK; context->polygon.FrontFace = GL_CCW; context->polygon.PolygonOffsetFactor = 0.0; context->polygon.PolygonOffsetUnits = 0.0; context->lighting.ShadeModel = GL_SMOOTH; context->depth_buffer.DepthWriteMask = GL_TRUE; context->depth_buffer.ClearDepth = 1.0; context->depth_buffer.ZOffset = 0.0; context->color_buffer.DrawBuffer = GL_BACK; #ifdef AUTOMATIC_LOCKING_ENABLE context->LockMode = MGL_LOCK_SMART; #if PREFER_SMART_LOCK == 1 context->smartLock = smartlock_new(DEF_MAXLOCKTIME, context); #else context->smartLock = 0; #endif if (!context->smartLock){ context->LockMode = MGL_LOCK_AUTOMATIC; } #endif /* Determine the limits to anisotropy */ if (IWarp3D->W3D_Query(context->w3dContext, W3D_Q_ANISOTROPICFILTER, 0) != W3D_NOT_SUPPORTED && LIB_IS_AT_LEAST(Warp3DBase, 53, 21)) { uint32 w3dMaxAnisotropy = IWarp3D->W3D_Query(context->w3dContext, W3D_Q_MAXANISOTROPY, 0); context->MaxAnisotropy = 1 << (w3dMaxAnisotropy - 1); } else { context->MaxAnisotropy = 1; } /* Disable Mip Mapping if the driver doesn't support it */ if (IWarp3D->W3D_Query(context->w3dContext, W3D_Q_MIPMAPPING, 0) == W3D_NOT_SUPPORTED) { context->NoMipMapping = GL_TRUE; } else { context->NoMipMapping = context->Params.newNoMipMapping; } context->NoMipMapping = context->Params.newNoMipMapping; context->NoFallbackAlpha = GL_FALSE; //newNoFallbackAlpha; context->color_buffer.BlendSrc = GL_ONE; context->color_buffer.BlendDst = GL_ZERO; context->color_buffer.LogicOpMode = GL_COPY; context->AlphaFellBack = GL_FALSE; context->WOne_Hint = GL_FALSE; context->PaletteData = AllocVecInternal(4*256, MEMF_ANY); context->PaletteSize = 0; context->PaletteFormat = 0; context->polygon.PolygonModeFront = GL_FILL; context->polygon.PolygonModeBack = GL_FILL; context->pixel_store.pack.swap_bytes = GL_FALSE; context->pixel_store.pack.lsb_first = GL_FALSE; context->pixel_store.pack.row_length = 0; context->pixel_store.pack.skip_rows = 0; context->pixel_store.pack.skip_pixels = 0; context->pixel_store.pack.alignment = 4; context->pixel_store.unpack.swap_bytes = GL_FALSE; context->pixel_store.unpack.lsb_first = GL_FALSE; context->pixel_store.unpack.row_length = 0; context->pixel_store.unpack.skip_rows = 0; context->pixel_store.unpack.skip_pixels = 0; context->pixel_store.unpack.alignment = 4; context->pixel.map_color = GL_FALSE; context->pixel.map_stencil = GL_FALSE; context->pixel.alpha_scale = 1.0; context->pixel.blue_scale = 1.0; context->pixel.green_scale = 1.0; context->pixel.red_scale = 1.0; context->pixel.depth_scale = 1.0; context->pixel.alpha_bias = 0.0; context->pixel.blue_bias = 0.0; context->pixel.green_bias = 0.0; context->pixel.red_bias = 0.0; context->pixel.depth_bias = 0.0; context->pixel.zoom_x = 1.0; context->pixel.zoom_y = 1.0; context->pixel.pixel_state_neutral = GL_TRUE; /* Vertex array stuff */ context->vertex_array.ClientState = 0; context->vertex_array.DrawElementsHook = 0; context->vertex_array.DrawArraysHook = 0; context->vertex_array.ClientActiveTexture= 0; context->ClientAttribStackPointer = 0; /* Area: All triangles smaller than this will not be drawn */ context->MinTriArea = 0.5f; context->VertexFormat = W3D_VFORMAT_FOG | W3D_VFORMAT_COLOR | W3D_VFORMAT_SCOLOR | W3D_VFORMAT_TCOORD_0 | W3D_VFORMAT_TCOORD_1 | W3D_VFORMAT_TCOORD_2; context->FrameCode = 0; context->TexFrameCode = 0; context->statFrame = 0; context->currentFPS = 0.0; context->averageFPS = 0.0; context->accumulatedFPS = 0.0; context->currentFrameTime = 0.0; context->averageFrameTime = 0.0; context->accumulatedFrameTime = 0.0; context->currentSwapTime = 0.0; context->averageSwapTime = 0.0; context->accumulatedSwapTime = 0.0; IDOS->GetVar("MiniGL/FrameStats", buffer, sizeof(buffer), 0); if (strcmp(buffer, "1") == 0 || strcasecmp(buffer, "on") == 0) { dprintf("Showing frame statistics\n"); context->enableFPS = GL_TRUE; } else { dprintf("Suppressing frame statistics\n"); context->enableFPS = GL_FALSE; } GLMatrixInit(context); light_Init(context); eval_InitEvaluator(context); if ( IWarp3D->W3D_Query(context->w3dContext, W3D_Q_ENV_COMBINE, 0) == W3D_NOT_SUPPORTED ) { context->envCombineSupported = GL_FALSE; } else { context->envCombineSupported = GL_TRUE; } context->extensionString = 0; /* FIXME: Find a way to really determine this */ context->DepthBufferUnit = 1/65536.0; context->LockArraysFirst = 0; context->LockArraysCount = 0; context->LockedArrays = 0; context->TransformFrameCode = 0; /* Initialize clipplane states */ context->transform.MaxClipPlane = -1; clipMask = MGL_CLIP_USER0; for (i = 0; i < MGL_MAX_CLIPPLANES; i++) { context->enable.ClipPlane[i] = GL_FALSE; context->transform.UserClipPlane[i].outcode = clipMask; clipMask <<= 1; } context->line.LineWidth = 1.0f; context->point.PointSize = 1.0f; /* Initialize raster position */ context->current.RasterPos.x = 0.0f; context->current.RasterPos.y = 0.0f; context->current.RasterPos.z = 0.0f; context->current.RasterPos.w = 1.0f; context->current.RasterDistance = 0.0f; context->current.RasterColor.r = 1.0f; context->current.RasterColor.g = 1.0f; context->current.RasterColor.b = 1.0f; context->current.RasterColor.a = 1.0f; for (i = 0; i < MAX_TEXTURE_UNITS; i++) { context->current.RasterTexCoords[i].u = 0.0; context->current.RasterTexCoords[i].v = 0.0; context->current.RasterTexCoords[i].w = 1.0; context->current.RasterRhwValid[i] = GL_TRUE; } context->current.RasterPosValid = GL_TRUE; /* glBitmap texture backing store */ context->CurrentBitmapBackingStoreSize = 0; context->CurrentBitmapBackingStore = 0; /* Texture Render Target */ context->textureRenderTarget = 0; context->NeedEye = GL_FALSE; context->NeedEyeNormal = GL_FALSE; context->Normalize = GL_FALSE; context->fbDirty = GL_FALSE; for (i = 1; i <= W3D_COMPRESSED_A8R5G6B5; i++) { context->textureSupport[i] = IWarp3D->W3D_GetTexFmtInfo(context->w3dContext, i, W3D_FMT_A8R8G8B8); } /* Vertex Buffer Objects */ context->VBOSize = context->Params.newVBOSize; context->GeneratedVBOs = (GLubyte*)AllocVecInternal(context->VBOSize,MEMF_SHARED|MEMF_CLEAR); if (!context->GeneratedVBOs) { return GL_FALSE; } context->VBOs = (GLVBO*)AllocVecInternal(context->VBOSize * sizeof(GLVBO),MEMF_SHARED|MEMF_CLEAR); if (!context->VBOs) { return GL_FALSE; } context->boundVertexVBO = 0; context->boundElementVBO = 0; return GL_TRUE; } void cgl_DeleteContext(struct GLContextIFace *Self) { GLcontext context = GET_INSTANCE(Self); dprintf("In cgl_DeleteContext\n"); LOG_PROFILE() DESTROY_PROFILE() eval_TermEvaluator(context); vid_CloseCurrentDisplay(context); vid_DestroyWarp3DContext(context); FreeVecInternalCheckAndClear((void**)&context->VertexBuffer); FreeVecInternalCheckAndClear((void**)&context->IndexBuffer); FreeVecInternalCheckAndClear((void**)&context->LargePolygon); FreeVecInternalCheckAndClear((void**)&context->LargePolygonOut); FreeVecInternalCheckAndClear((void**)&context->w3dTextures); FreeVecInternalCheckAndClear((void**)&context->GeneratedTextures); FreeVecInternalCheckAndClear((void**)&context->ConvertBuffer); FreeVecInternalCheckAndClear((void**)&context->extensionString); FreeVecInternalCheckAndClear((void**)&context->CurrentBitmapBackingStore); FreeVecInternalCheckAndClear((void**)&context->PaletteData); if (context->DisplayListArray) { cgl_GLDeleteLists(Self, 1, context->DisplayListArraySize); FreeVecInternal(context->DisplayListArray); context->DisplayListArray = 0; } if (context->smartLock) { smartlock_free(context->smartLock); context->smartLock = NULL; } FreeVecInternalCheckAndClear((void**)&context->rendererName); FreeVecInternalCheckAndClear((void**)&context->GeneratedVBOs); if (context->VBOs) { int i; for (i = 0; i < context->VBOSize; i++) { FreeVecInternalCheckAndClear((void**)&context->VBOs[i].data); } FreeVecInternal(context->VBOs); context->VBOs = NULL; } IExec->DeleteInterface((struct Interface *)Self); } void cgl_UpdateContext(struct GLContextIFace *IGL, struct TagItem *tagList) { /* Handle context updates including change of private buffers etc */ GLcontext context; struct BitMap *newFront, *newBack, *newSingle; int wnew,hnew;; context = (GLcontext)GET_INSTANCE(IGL); newFront = (struct BitMap *)IUtility->GetTagData(MGLCC_FrontBuffer,0,tagList); newBack = (struct BitMap *)IUtility->GetTagData(MGLCC_BackBuffer,0,tagList); newSingle = (struct BitMap *)IUtility->GetTagData(MGLCC_Bitmap,0,tagList); /* int w = IP96->p96GetBitMapAttr(context->currentFrontBuffer.bitMap, P96BMA_WIDTH); int h = IP96->p96GetBitMapAttr(context->currentFrontBuffer.bitMap, P96BMA_HEIGHT); */ if (context->priv == 1) { if (newSingle) { buf_SetFrontBuffer(context,newSingle,GL_FALSE); buf_SetBackBuffer(context,newSingle,GL_FALSE); } else if (newFront) { buf_SetFrontBuffer(context,newFront,GL_FALSE); buf_SetBackBuffer(context,newFront,GL_FALSE); } } else if (context->priv == 2) { buf_SetFrontBuffer(context,newFront,GL_FALSE); buf_SetBackBuffer(context,newBack,GL_FALSE); } wnew = IP96->p96GetBitMapAttr(context->currentFrontBuffer.bitMap, P96BMA_WIDTH); hnew = IP96->p96GetBitMapAttr(context->currentFrontBuffer.bitMap, P96BMA_HEIGHT); IGL->GLScissor(0, 0, wnew, hnew); } void cgl_MinTriArea(struct GLContextIFace *Self, GLfloat area) { GLcontext context = GET_INSTANCE(Self); context->MinTriArea = area; } /* ************************************************************************** */ GLint mgl_GetSupportedScreenModes(struct MiniGLIFace *IMiniGL, MGLScreenModeCallback CallbackFn) { W3D_ScreenMode *Modes = IWarp3D->W3D_GetScreenmodeList(); W3D_ScreenMode *Cursor; MGLScreenMode sMode; GLboolean retval; if (Modes == NULL) { return MGL_SM_BESTMODE; } Cursor = Modes; while (Cursor) { sMode.id = (GLint)Cursor->ModeID; sMode.width = (GLint)Cursor->Width; sMode.height = (GLint)Cursor->Height; sMode.bit_depth = (GLint)Cursor->Depth; strncpy(sMode.mode_name, Cursor->DisplayName, MGL_MAX_MODE); retval = CallbackFn(&sMode); if (retval == GL_TRUE) { IWarp3D->W3D_FreeScreenmodeList(Modes); return sMode.id; } Cursor = Cursor->Next; } IWarp3D->W3D_FreeScreenmodeList(Modes); return MGL_SM_BESTMODE; } GLboolean mgl_ScreenModeIsSupported(struct MiniGLIFace *Self, GLsizei width, GLsizei height, GLint depth) { W3D_ScreenMode *Modes = IWarp3D->W3D_GetScreenmodeList(); W3D_ScreenMode *Cursor; if (Modes == NULL) { return GL_FALSE; } Cursor = Modes; while (Cursor) { if ( (GLsizei)Cursor->Width == width && (GLsizei)Cursor->Height == height && (GLint)Cursor->Depth == depth ) { IWarp3D->W3D_FreeScreenmodeList(Modes); return GL_TRUE; } Cursor = Cursor->Next; } IWarp3D->W3D_FreeScreenmodeList(Modes); return GL_FALSE; } void checkNeedEye(GLcontext context) { int i; context->NeedEye = GL_FALSE; context->NeedEyeNormal = GL_FALSE; /* Check if we need eye coordinates and eye normals * * Currently, this is true when the following is true: * - lighting is enabled * - texture coordinate generation is enabled for modes that need eye * coordinates * - User clip planes are enabled (coordinates only) */ if (context->enable.Lighting == GL_TRUE) { context->NeedEye = GL_TRUE; context->NeedEyeNormal = GL_TRUE; return; } for (i = 0; i <= context->texture.MaxTextureUnit; i++) { if ( context->enable.TexGenT[i] == GL_TRUE || context->enable.TexGenS[i] == GL_TRUE || context->enable.TexGenQ[i] == GL_TRUE ) { /* FIXME: Check for mode */ context->NeedEye = GL_TRUE; context->NeedEyeNormal = GL_TRUE; return; } } for (i = 0; i <= context->transform.MaxClipPlane; i++) { if (context->enable.ClipPlane[i]) { context->NeedEye = GL_TRUE; return; } } #if 1 // TODO: This should not be needed, since only the eyez is required for // fogging. Try to pull this out. if (context->enable.Fog == GL_TRUE) { context->NeedEye = GL_TRUE; } #endif }