/* * $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 "minigl_vectors.c" static char rcsid[] UNUSED = "$Id$"; // 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); #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); if(dl_IsDLActive(Self)){ dl_save_Scissor(Self, x, y, width, height); if(!dl_CompileAndExecuteMode(Self)){ return; } } 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); if(dl_IsDLActive(Self)){ dl_save_ClearStencil(Self, s); if(!dl_CompileAndExecuteMode(Self)){ return; } } context->stencil_buffer.ClearStencil = s; } void cgl_GLClearColor(struct GLContextIFace *Self, GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha) { GLcontext context = GET_INSTANCE(Self); if(dl_IsDLActive(Self)){ dl_save_ClearColor(Self, red, green, blue, alpha); if(!dl_CompileAndExecuteMode(Self)){ return; } } 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); if(dl_IsDLActive(Self)){ dl_save_DepthMask(Self, flag); if(!dl_CompileAndExecuteMode(Self)){ return; } } 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); if(dl_IsDLActive(Self)){ dl_save_DepthFunc(Self, func); if(!dl_CompileAndExecuteMode(Self)){ return; } } ULONG wFunc = W3D_Z_LESS; switch(func) { case GL_NEVER: wFunc = W3D_Z_NEVER; break; case GL_LESS: wFunc = W3D_Z_LESS; break; case GL_EQUAL: wFunc = W3D_Z_EQUAL; break; case GL_LEQUAL: wFunc = W3D_Z_LEQUAL; break; case GL_GREATER: wFunc = W3D_Z_GREATER; break; case GL_NOTEQUAL: wFunc = W3D_Z_NOTEQUAL; break; case GL_GEQUAL: wFunc = W3D_Z_GEQUAL; break; case GL_ALWAYS: wFunc = W3D_Z_ALWAYS; break; default: GLFlagError(context, 1, GL_INVALID_ENUM); break; } IWarp3D->W3D_SetZCompareMode(context->w3dContext, wFunc); context->depth_buffer.DepthFunc = func; } void cgl_GLClearDepth(struct GLContextIFace *Self, GLclampd depth) { GLcontext context = GET_INSTANCE(Self); if(dl_IsDLActive(Self)){ dl_save_ClearDepth(Self, depth); if(!dl_CompileAndExecuteMode(Self)){ return; } } context->depth_buffer.ClearDepth = (W3D_Double)depth; } void cgl_GLClear(struct GLContextIFace *Self, GLbitfield mask) { GLcontext context = GET_INSTANCE(Self); if(dl_IsDLActive(Self)){ dl_save_Clear(Self, mask); if(!dl_CompileAndExecuteMode(Self)){ return; } } 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) { ULONG 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)); IExec->FreeVec(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 = IExec->AllocVec(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 = IExec->AllocVec(sizeof(GLuint) * context->Params.newVertexBufferSize, MEMF_ANY); if (!context->IndexBuffer) return GL_FALSE; context->DisplayListArray = IExec->AllocVec(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 = IExec->AllocVec(sizeof(GLubyte) * context->Params.newTextureBufferSize, MEMF_ANY); if (!context->GeneratedTextures) return GL_FALSE; context->w3dTextures = IExec->AllocVec(sizeof(MGLTexture) * context->Params.newTextureBufferSize, MEMF_ANY); if (!context->w3dTextures) return GL_FALSE; for (i=0; iParams.newTextureBufferSize; i++) { context->w3dTextures[i].texObj = NULL; context->w3dTextures[i].texData = NULL; context->GeneratedTextures[i] = 0; } context->NumTextureUnits = IWarp3D->W3D_Query(context->w3dContext, W3D_Q_NUM_TMU, 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->enable.TexGenS[i] = GL_FALSE; context->enable.TexGenT[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.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; context->smartLock = smartlock_new(DEF_MAXLOCKTIME, context); if (!context->smartLock){ context->LockMode = MGL_LOCK_AUTOMATIC; } #endif context->NoMipMapping = context->Params.newNoMipMapping; context->NoFallbackAlpha = GL_FALSE; //newNoFallbackAlpha; context->color_buffer.BlendSrc = W3D_ONE; // Shouldn't that be GL_ONE and GL_ZERO? context->color_buffer.BlendDst = W3D_ZERO; context->color_buffer.LogicOpMode = GL_COPY; context->AlphaFellBack = GL_FALSE; context->WOne_Hint = GL_FALSE; context->PaletteData = IExec->AllocVec(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, 10, 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); return GL_TRUE; } void cgl_DeleteContext(struct GLContextIFace *Self) { GLcontext context = GET_INSTANCE(Self); dprintf("In cgl_DeleteContext\n"); eval_TermEvaluator(context); vid_CloseCurrentDisplay(context); vid_DestroyWarp3DContext(context); if (context->VertexBuffer) IExec->FreeVec(context->VertexBuffer); if (context->IndexBuffer) IExec->FreeVec(context->IndexBuffer); if (context->w3dTextures) IExec->FreeVec(context->w3dTextures); if (context->GeneratedTextures) IExec->FreeVec(context->GeneratedTextures); if (context->ConvertBuffer) IExec->FreeVec(context->ConvertBuffer); if (context->extensionString) IExec->FreeVec(context->extensionString); if (context->CurrentBitmapBackingStore) IExec->FreeVec(context->CurrentBitmapBackingStore); if (context->PaletteData) IExec->FreeVec(context->PaletteData); if(context->DisplayListArray) { cgl_GLDeleteLists(Self, 1, context->DisplayListArraySize); IExec->FreeVec(context->DisplayListArray); context->DisplayListArray = 0; } if(context->smartLock) { smartlock_free(context->smartLock); context->smartLock = 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 w,h,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); w = IP96->p96GetBitMapAttr(context->currentFrontBuffer.bitMap, P96BMA_WIDTH); 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 *mgl_CreateContext(struct MiniGLIFace *IMiniGL, struct TagItem *tagList) { GLcontext context; BOOL bWindowMode; BOOL privateBuffers = FALSE; void *pBitmap; void *pFrontBuffer; void *pBackBuffer; int width, height, left, top, offx, offy; uint32 mode; struct GLContextIFace *IGL; int i; /* First of all, create the interface */ IGL = (struct GLContextIFace *)IExec->MakeInterfaceTags(IMiniGL->Data.LibBase, MIT_VectorTable, miniglcontext_vectors, MIT_DataSize, sizeof(struct GLcontext_t), MIT_Flags, IFLF_NONE, MIT_Version, 1, MIT_Name, "MiniGLContext", TAG_DONE); if (!IGL) return 0; context = (GLcontext)GET_INSTANCE(IGL); IUtility->ClearMem(context, sizeof(struct GLcontext_t)); width = (int32)IUtility->GetTagData(MGLCC_Width, (uint32)-1, tagList); height = (int32)IUtility->GetTagData(MGLCC_Height, (uint32)-1, tagList); left = (int32)IUtility->GetTagData(MGLCC_WindowLeft, 30, tagList); top = (int32)IUtility->GetTagData(MGLCC_WindowTop, 30, tagList); offx = (int32)IUtility->GetTagData(MGLCC_OffsetX, 0, tagList); offy = (int32)IUtility->GetTagData(MGLCC_OffsetY, 0, tagList); bWindowMode = (BOOL)IUtility->GetTagData(MGLCC_Windowed, (uint32)FALSE, tagList); pBitmap = (void *)IUtility->GetTagData(MGLCC_Bitmap, 0, tagList); mode = IUtility->GetTagData(MGLCC_ScreenMode, MGL_SM_BESTMODE, tagList); privateBuffers = (int)IUtility->GetTagData(MGLCC_PrivateBuffers,0,tagList); pFrontBuffer = (void *)IUtility->GetTagData(MGLCC_FrontBuffer,0,tagList); pBackBuffer = (void *)IUtility->GetTagData(MGLCC_BackBuffer,0,tagList); context->fbDirtyHook = (void (*)(void *, void *))IUtility->GetTagData(MGLCC_FBDirtyHook,0,tagList); context->fbDirtyHookData = (void *)IUtility->GetTagData(MGLCC_FBDirtyHookData,0,tagList); dprintf("width = %ld, height = %ld, offx = %ld, offy = %ld\n", width, height, offx, offy); context->Params.newVertexBufferSize = IUtility->GetTagData(MGLCC_VertexBufferSize, 8192, tagList); context->Params.newTextureBufferSize = IUtility->GetTagData(MGLCC_TextureBufferSize, 8192, tagList); context->Params.newDisplayListArraySize = IUtility->GetTagData(MGLCC_DisplayListArraySize, 8192, tagList); context->Params.maxDisplayListNesting = IUtility->GetTagData(MGLCC_MaxDisplayListNesting, 64, tagList); context->Params.newNumberOfBuffers = IUtility->GetTagData(MGLCC_Buffers, 3, tagList); context->Params.newPixelDepth = IUtility->GetTagData(MGLCC_PixelDepth, 16, tagList); context->Params.newWindowMode = bWindowMode; context->Params.clw = (GLboolean)IUtility->GetTagData(MGLCC_CloseWorkbench, GL_FALSE, tagList); context->Params.newNoMipMapping = (GLboolean)IUtility->GetTagData(MGLCC_NoMipMapping, GL_FALSE, tagList); context->Params.newCloseGadget = (GLboolean)IUtility->GetTagData(MGLCC_CloseGadget, GL_FALSE, tagList); context->Params.newStencilBuffer = (GLboolean)IUtility->GetTagData(MGLCC_StencilBuffer, GL_FALSE, tagList); context->Params.newSizeGadget = (GLboolean)IUtility->GetTagData(MGLCC_SizeGadget, GL_FALSE, tagList); context->nameStackPointer = NAMESTACK_EMPTY; context->selectionBuffer = NULL; context->selectionBufferPointer = 0; context->selectionBufferOverflow = FALSE; context->selectionBufferSize = 0; context->renderMode = GL_RENDER; context->Self = IGL; /* Initialize buffers. The vid_Open* or vid_SetBitmap functions will set * those */ buf_InitBuffer(context, &context->currentBackBuffer); buf_InitBuffer(context, &context->currentFrontBuffer); for (i = 0; i < MGL_MAX_AUX_BUFFERS; i++) buf_InitBuffer(context, &context->currentAuxBuffer[i]); dprintf("%ld screen buffers\n", context->Params.newNumberOfBuffers); GLboolean bRes; /* Setup primary display */ if (pBitmap) // old style private { bRes = vid_SetBitmap(context, pBitmap, &width, &height); context->priv = 1; context->NumBuffers = 1; } else if (privateBuffers) { if(privateBuffers == 1 && pFrontBuffer) { /* try the next just for testing */ bRes = vid_SetBitmap(context,pFrontBuffer, &width, &height); context->priv = 1; /* Single Buffered Application Private Buffers*/ context->NumBuffers = 1; } else if(privateBuffers == 2 && pFrontBuffer && pBackBuffer) { width = IP96->p96GetBitMapAttr(pFrontBuffer, P96BMA_WIDTH); height= IP96->p96GetBitMapAttr(pBackBuffer, P96BMA_WIDTH); buf_SetFrontBuffer(context,pFrontBuffer,GL_FALSE); buf_SetBackBuffer(context,pBackBuffer,GL_FALSE); context->priv = 2; /* Double Buffered Application Provided buffers */ /* these two lines come from vid_SetBitmap not sure if they are needed here or not ANDY*/ context->BufNr = 0; // The drawing buffer context->DoSync = GL_TRUE; // Enable sync'ing context->NumBuffers = 2; bRes = GL_TRUE; } else bRes = GL_FALSE; } else if (bWindowMode || mode == MGL_SM_WINDOWMODE) bRes = vid_OpenWindow(context, width, height, left, top); else bRes = vid_OpenDisplay(context, width, height, mode); if (!bRes) { IExec->DeleteInterface((struct Interface *)IGL); return NULL; } /* Set draw and read buffers */ if (context->NumBuffers == 1) { context->drawBuffer = &context->currentFrontBuffer; context->readBuffer = &context->currentFrontBuffer; context->color_buffer.DrawBuffer = GL_FRONT; context->color_buffer.ReadBuffer = GL_FRONT; } else { context->drawBuffer = &context->currentBackBuffer; context->readBuffer = &context->currentFrontBuffer; context->color_buffer.DrawBuffer = GL_BACK; context->color_buffer.ReadBuffer = GL_BACK; } context->color_buffer.WriteMaskRed = GL_TRUE; context->color_buffer.WriteMaskGreen = GL_TRUE; context->color_buffer.WriteMaskBlue = GL_TRUE; context->color_buffer.WriteMaskAlpha = GL_TRUE; /* Create the Warp3D context */ if (!vid_CreateWarp3DContext(context)) { vid_CloseCurrentDisplay(context); IExec->DeleteInterface((struct Interface *)IGL); return NULL; } /* Allocate stencil buffer and depth buffer if necessary */ if (!vid_AllocDepthStencil(context, GL_TRUE)) { vid_DestroyWarp3DContext(context); vid_CloseCurrentDisplay(context); IExec->DeleteInterface((struct Interface *)IGL); return NULL; } vid_SetDefaultStates(context); switch(context->w3dContext->CurrentChip) { case W3D_CHIP_RADEON: case W3D_CHIP_RADEON_R200: case W3D_CHIP_RADEON_R300: context->UseZFog = GL_TRUE; break; default: context->UseZFog = GL_FALSE; } dprintf("Initializing context\n"); /* Initialize the context */ if (GL_FALSE == MGLInitContext(context)) { dprintf("Error: Can't initialize context\n"); IGL->DeleteContext(); return NULL; } dprintf("Setting up default parameters\n"); IGL->GLScissor(0, 0, width, height); IGL->GLDepthRange(0.0, 1.0); IGL->GLViewport(offx, offy, width, height); IGL->GLClearColor(0.0, 0.0, 0.0, 1.0); IGL->GLColor4f(1.0, 1.0, 1.0, 1.0); #ifndef GLNDEBUG dprintf("Lockmode = "); 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 dprintf("Done\n"); return (void *)IGL; } 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) { /* 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 }