/* * $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 static char rcsid[] UNUSED = "$Id$"; void cgl_GLLineWidth(struct GLContextIFace *Self, GLfloat lineWidth) { GLcontext context = GET_INSTANCE(Self); if(dl_IsDLActive(Self)){ dl_save_LineWidth(Self, lineWidth); if(!dl_CompileAndExecuteMode(Self)){ return; } } context->line.LineWidth = lineWidth; #ifdef MGL_NEW_WARP3D IWarp3D->W3D_SetParameter(context->w3dContext, W3D_LINE_WIDTH, &context->line.LineWidth); #endif } void cgl_GLPointSize(struct GLContextIFace *Self, GLfloat size) { GLcontext context = GET_INSTANCE(Self); if(dl_IsDLActive(Self)){ dl_save_PointSize(Self, size); if(!dl_CompileAndExecuteMode(Self)){ return; } } context->point.PointSize = size; #ifdef MGL_NEW_WARP3D IWarp3D->W3D_SetParameter(context->w3dContext, W3D_POINT_SIZE, &context->point.PointSize); #endif } void cgl_GLLineStipple(struct GLContextIFace *Self, GLint factor, GLushort pattern) { #ifdef MGL_NEW_WARP3D GLcontext context = GET_INSTANCE(Self); if(dl_IsDLActive(Self)){ dl_save_LineStipple(Self, factor, pattern); if(!dl_CompileAndExecuteMode(Self)){ return; } } /* FIXME: Add states to context */ IWarp3D->W3D_SetParameter(context->w3dContext, W3D_STIPPLE_LINE, &pattern); IWarp3D->W3D_SetParameter(context->w3dContext, W3D_STIPPLE_LINE_FACTOR, &factor); #endif } void cgl_GLPolygonStipple(struct GLContextIFace *Self, GLubyte *pattern) { #ifdef MGL_NEW_WARP3D GLcontext context = GET_INSTANCE(Self); if(dl_IsDLActive(Self)){ dl_save_PolygonStipple(Self, pattern); if(!dl_CompileAndExecuteMode(Self)){ return; } } memcpy(context->polygon_stipple.pattern, pattern, 128); IWarp3D->W3D_SetParameter(context->w3dContext, W3D_STIPPLE_POLYGON, &pattern); #endif } void cgl_GLPolygonOffset(struct GLContextIFace *Self, GLfloat factor, GLfloat units) { GLcontext context = GET_INSTANCE(Self); if(dl_IsDLActive(Self)){ dl_save_PolygonOffset(Self, factor, units); if(!dl_CompileAndExecuteMode(Self)){ return; } } dprintf("factor: %f, units: %f\n", factor, units); context->polygon.PolygonOffsetFactor = factor; context->polygon.PolygonOffsetUnits = units; } void cgl_GLAlphaFunc(struct GLContextIFace *Self, GLenum func, GLclampf ref) { GLcontext context = GET_INSTANCE(Self); if(dl_IsDLActive(Self)){ dl_save_AlphaFunc(Self, func, ref); if(!dl_CompileAndExecuteMode(Self)){ return; } } dprintf("func: %x ref: %f\n", func, ref); ULONG w3dmode; W3D_Float refvalue = (W3D_Float)ref; GLFlagError(context, context->CurrentPrimitive != GL_BASE, GL_INVALID_OPERATION); context->color_buffer.AlphaTestFunc = func; context->color_buffer.AlphaTestRef = ref; switch(func) { case GL_NEVER: w3dmode = W3D_A_NEVER; break; case GL_LESS: w3dmode = W3D_A_LESS; break; case GL_EQUAL: w3dmode = W3D_A_EQUAL; break; case GL_LEQUAL: w3dmode = W3D_A_LEQUAL; break; case GL_GREATER: w3dmode = W3D_A_GREATER; break; case GL_NOTEQUAL: w3dmode = W3D_A_NOTEQUAL; break; case GL_GEQUAL: w3dmode = W3D_A_GEQUAL; break; case GL_ALWAYS: w3dmode = W3D_A_ALWAYS; break; default: GLFlagError(context, 1, GL_INVALID_ENUM); break; } IWarp3D->W3D_SetAlphaMode(context->w3dContext, w3dmode, &refvalue); } void cgl_GLPolygonMode(struct GLContextIFace *Self, GLenum face, GLenum mode) { GLcontext context = GET_INSTANCE(Self); if(dl_IsDLActive(Self)){ dl_save_PolygonMode(Self, face, mode); if(!dl_CompileAndExecuteMode(Self)){ return; } } switch(face) { case GL_FRONT: context->polygon.PolygonModeFront = mode; break; case GL_BACK: context->polygon.PolygonModeBack = mode; break; case GL_FRONT_AND_BACK: context->polygon.PolygonModeFront = mode; context->polygon.PolygonModeBack = mode; break; } return ; } void cgl_GLShadeModel(struct GLContextIFace *Self, GLenum mode) { GLcontext context = GET_INSTANCE(Self); if(dl_IsDLActive(Self)){ dl_save_ShadeModel(Self, mode); if(!dl_CompileAndExecuteMode(Self)){ return; } } context->lighting.ShadeModel = mode ; if (mode == GL_FLAT) IWarp3D->W3D_SetState(context->w3dContext, W3D_GOURAUD, W3D_DISABLE); else if (mode == GL_SMOOTH) IWarp3D->W3D_SetState(context->w3dContext, W3D_GOURAUD, W3D_ENABLE); } #define BLS(X) case GL_##X: src=W3D_##X; break #define BLD(X) case GL_##X: dest=W3D_##X; break void cgl_GLBlendFunc(struct GLContextIFace *Self, GLenum sfactor, GLenum dfactor) { GLcontext context = GET_INSTANCE(Self); if(dl_IsDLActive(Self)){ dl_save_BlendFunc(Self, sfactor, dfactor); if(!dl_CompileAndExecuteMode(Self)){ return; } } dprintf("sfactor: %x, dfactor: %x\n", sfactor, dfactor); ULONG src = 0, dest = 0; switch(sfactor) { BLS(ZERO); BLS(ONE); BLS(DST_COLOR); BLS(ONE_MINUS_DST_COLOR); BLS(SRC_ALPHA); BLS(ONE_MINUS_SRC_ALPHA); BLS(DST_ALPHA); BLS(ONE_MINUS_DST_ALPHA); BLS(SRC_ALPHA_SATURATE); default: GLFlagError(context, 1, GL_INVALID_ENUM); } switch(dfactor) { BLD(ZERO); BLD(ONE); BLD(SRC_COLOR); BLD(ONE_MINUS_SRC_COLOR); BLD(SRC_ALPHA); BLD(ONE_MINUS_SRC_ALPHA); BLD(DST_ALPHA); BLD(ONE_MINUS_DST_ALPHA); } // Try to set the mode, if unavailable, switch to // (SRC_ALPHA, ONE_MINUS_SRC_ALPHA) which is supported // by almost all Amiga supported graphics cards if (IWarp3D->W3D_SetBlendMode(context->w3dContext, src, dest) == W3D_UNSUPPORTEDBLEND) { dprintf("Blend mode not supported by hardware\n"); if (context->NoFallbackAlpha == GL_FALSE) { IWarp3D->W3D_SetBlendMode(context->w3dContext, W3D_SRC_ALPHA, W3D_ONE_MINUS_SRC_ALPHA); context->AlphaFellBack = GL_TRUE; } else { context->AlphaFellBack = GL_FALSE; } } else { context->AlphaFellBack = GL_FALSE; } context->color_buffer.BlendSrc = sfactor; context->color_buffer.BlendDst = dfactor; } void cgl_GLStencilFunc(struct GLContextIFace *Self, GLenum func, GLint ref, GLint mask) { GLcontext context = GET_INSTANCE(Self); if(dl_IsDLActive(Self)){ dl_save_StencilFunc(Self, func, ref, mask); if(!dl_CompileAndExecuteMode(Self)){ return; } } uint32 f = W3D_ST_NEVER; switch (func) { case GL_NEVER: f = W3D_ST_NEVER; break; case GL_ALWAYS: f = W3D_ST_ALWAYS; break; case GL_LESS: f = W3D_ST_LESS; break; case GL_LEQUAL: f = W3D_ST_LEQUAL; break; case GL_EQUAL: f = W3D_ST_EQUAL; break; case GL_GEQUAL: f = W3D_ST_GEQUAL; break; case GL_GREATER: f = W3D_ST_GREATER; break; case GL_NOTEQUAL: f = W3D_ST_NOTEQUAL; break; } IWarp3D->W3D_SetStencilFunc(context->w3dContext, f, ref, mask); } static uint32 MapOp(GLenum op) { switch(op) { case GL_KEEP: return W3D_ST_KEEP; case GL_ZERO: return W3D_ST_ZERO; case GL_REPLACE: return W3D_ST_REPLACE; case GL_INCR: return W3D_ST_INCR; case GL_DECR: return W3D_ST_DECR; case GL_INVERT: return W3D_ST_INVERT; default: return 0; } } void cgl_GLStencilOp(struct GLContextIFace *Self, GLenum sfail, GLenum dpfail, GLenum dppass) { GLcontext context = GET_INSTANCE(Self); if(dl_IsDLActive(Self)){ dl_save_StencilOp(Self, sfail, dpfail, dppass); if(!dl_CompileAndExecuteMode(Self)){ return; } } uint32 sf = MapOp(sfail), dpf = MapOp(dpfail), dpp = MapOp(dppass); IWarp3D->W3D_SetStencilOp(context->w3dContext, sf, dpf, dpp); } void cgl_GLStencilMask(struct GLContextIFace *Self, GLuint mask) { GLcontext context = GET_INSTANCE(Self); if(dl_IsDLActive(Self)){ dl_save_StencilMask(Self, mask); if(!dl_CompileAndExecuteMode(Self)){ return; } } IWarp3D->W3D_SetWriteMask(context->w3dContext, mask); } void cgl_GLColorMask(struct GLContextIFace *Self, GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha) { GLcontext context = GET_INSTANCE(Self); dprintf("called\n"); if(dl_IsDLActive(Self)){ dl_save_ColorMask(Self, red, green, blue, alpha); if(!dl_CompileAndExecuteMode(Self)){ return; } } context->color_buffer.WriteMaskRed = red; context->color_buffer.WriteMaskGreen = green; context->color_buffer.WriteMaskBlue = blue; context->color_buffer.WriteMaskAlpha = alpha; IWarp3D->W3D_SetColorMask(context->w3dContext, red, green, blue, alpha); } void cgl_GLHint(struct GLContextIFace *Self, GLenum target, GLenum mode) { GLcontext context = GET_INSTANCE(Self); if(dl_IsDLActive(Self)){ dl_save_Hint(Self, target, mode); if(!dl_CompileAndExecuteMode(Self)){ return; } } ULONG hint = W3D_H_AVERAGE; switch(mode) { case GL_FASTEST: hint = W3D_H_FAST; break; case GL_NICEST: hint = W3D_H_NICE; break; case GL_DONT_CARE: hint = W3D_H_AVERAGE; break; default: // GLFlagError(context, 1, GL_INVALID_ENUM); break; } switch(target) { case GL_FOG_HINT: IWarp3D->W3D_Hint(context->w3dContext, W3D_H_FOGGING, hint); break; case GL_PERSPECTIVE_CORRECTION_HINT: IWarp3D->W3D_Hint(context->w3dContext, W3D_H_PERSPECTIVE, hint); break; case MGL_W_ONE_HINT: if (mode == GL_FASTEST) context->WOne_Hint = GL_TRUE; else context->WOne_Hint = GL_FALSE; break; case MGL_TEXTURE_QUALITY_HINT: if (mode == GL_FASTEST) context->ConvertTo16Bit = GL_TRUE; else context->ConvertTo16Bit = GL_FALSE; break; default: // GLFlagError(context, 1, GL_INVALID_ENUM); break; } } static void BuildExtensionString(GLcontext context) { #define DEFAULT_EXT "GL_MGL_packed_pixels GL_EXT_packed_pixels GL_EXT_bgra GL_EXT_color_table GL_EXT_vertex_array GL_NV_texgen_reflection" uint32 size; uint32 env_combine = IWarp3D->W3D_Query(context->w3dContext, W3D_Q_ENV_COMBINE, 0); uint32 env_crossbar = IWarp3D->W3D_Query(context->w3dContext, W3D_Q_ENV_CROSSBAR, 0); uint32 env_add = IWarp3D->W3D_Query(context->w3dContext, W3D_Q_ENV_ADD, 0); size = strlen(DEFAULT_EXT) + 1; if (context->NumTextureUnits > 1) size += strlen(" GL_ARB_multitexture"); #ifdef MGL_COMPILED_VERTEX_ARRAYS size +=strlen(" GL_EXT_compiled_vertex_arrays"); #endif size += strlen(" GL_EXT_draw_range_elements"); if (env_combine != W3D_NOT_SUPPORTED) size += strlen(" GL_ARB_texture_env_combine"); if (env_crossbar != W3D_NOT_SUPPORTED) size += strlen(" GL_ARB_texture_env_crossbar"); if (env_add != W3D_NOT_SUPPORTED) size += strlen(" GL_ARB_texture_env_add GL_EXT_texture_env_add"); context->extensionString = IExec->AllocVec(size, MEMF_ANY); if (!context->extensionString) return; strcpy(context->extensionString, DEFAULT_EXT); if (context->NumTextureUnits > 1) strcat(context->extensionString, " GL_ARB_multitexture"); #ifdef MGL_COMPILED_VERTEX_ARRAYS strcat(context->extensionString, " GL_EXT_compiled_vertex_arrays"); #endif strcat(context->extensionString, " GL_EXT_draw_range_elements"); if (env_combine != W3D_NOT_SUPPORTED) strcat(context->extensionString, " GL_ARB_texture_env_combine"); if (env_crossbar != W3D_NOT_SUPPORTED) strcat(context->extensionString, " GL_ARB_texture_env_crossbar"); if (env_add != W3D_NOT_SUPPORTED) strcat(context->extensionString, " GL_ARB_texture_env_add GL_EXT_texture_env_add"); } const GLubyte * cgl_GLGetString(struct GLContextIFace *Self, GLenum name) { GLcontext context = GET_INSTANCE(Self); switch(name) { case GL_RENDERER: if (context->w3dContext) { switch(context->w3dContext->CurrentChip) { case W3D_CHIP_VIRGE: return (GLubyte *)"MiniGL/Warp3D S3 ViRGE (virge)"; case W3D_CHIP_PERMEDIA2: return (GLubyte *)"MiniGL/Warp3D 3DLabs Permedia 2 (permedia)"; case W3D_CHIP_VOODOO1: return (GLubyte *)"MiniGL/Warp3D 3DFX Voodoo 1 (voodoo)"; case W3D_CHIP_AVENGER: return (GLubyte *)"MiniGL/Warp3D 3DFX Voodoo 3 (voodoo avenger)"; case W3D_CHIP_RADEON: return (GLubyte *)"MiniGL/Warp3D ATI Radeon (radeon)"; case W3D_CHIP_RADEON_R200: return (GLubyte *)"MiniGL/Warp3D ATI Radeon (radeon r200)"; case W3D_CHIP_NAPALM: return (GLubyte *)"MiniGL/Warp3D 3DFX Voodoo 4 (voodoo napalm)"; case W3D_CHIP_UNKNOWN: return (GLubyte *)"MiniGL/Warp3D Unknown graphics chip"; default: return (GLubyte *)"MiniGL/Warp3D"; } } else { return (GLubyte *)"MiniGL/Warp3D"; } case GL_VENDOR: return (GLubyte *)"The MiniGL Team"; case GL_VERSION: return (GLubyte *)"1.3"; case GL_EXTENSIONS: if (!context->extensionString) BuildExtensionString(context); if (context->extensionString) return (GLubyte *)context->extensionString; return (GLubyte *)DEFAULT_EXT; default: return (GLubyte *)"Huh?"; } } GLenum cgl_GLGetError(struct GLContextIFace *Self) { GLcontext context = GET_INSTANCE(Self); GLenum ret = context->CurrentError; context->CurrentError = GL_NO_ERROR; return ret; } void cgl_GLGetPointerv(struct GLContextIFace *Self, GLenum pname, GLvoid **params) { GLcontext context = GET_INSTANCE(Self); switch(pname) { case GL_COLOR_ARRAY_POINTER: *params = context->vertex_array.ColorArray.pointer; return; case GL_EDGE_FLAG_ARRAY_POINTER: *params = NULL; // Not supported at the moment return; case GL_FOG_COORD_ARRAY_POINTER: *params = NULL; // Not supported at the moment return; case GL_FEEDBACK_BUFFER_POINTER: *params = NULL; // Not supported at the moment return; case GL_INDEX_ARRAY_POINTER: *params = NULL; // Not supported at the moment return; case GL_NORMAL_ARRAY_POINTER: *params = context->vertex_array.NormalArray.pointer; return; case GL_SECONDARY_COLOR_ARRAY_POINTER: *params = NULL; // Not supported at the moment return; case GL_SELECTION_BUFFER_POINTER: *params = context->selectionBuffer; return; case GL_TEXTURE_COORD_ARRAY_POINTER: *params = context->vertex_array.TexCoordArray[context->texture.ActiveTexture].pointer; return; case GL_VERTEX_ARRAY_POINTER: *params = context->vertex_array.VertexArray.pointer; return; default: dprintf("Invalid pname passed to %s\n", __func__); *params = NULL; return; } } void cgl_SetZOffset(struct GLContextIFace *Self, GLfloat offset) { GLcontext context = GET_INSTANCE(Self); if(dl_IsDLActive(Self)){ dl_save_SetZOffset(Self, offset); if(!dl_CompileAndExecuteMode(Self)){ return; } } context->depth_buffer.ZOffset = offset; } void cgl_PinTexture(struct GLContextIFace *Self, GLuint texnum) { GLcontext context = GET_INSTANCE(Self); if(dl_IsDLActive(Self)){ dl_save_PinTexture(Self, texnum); if(!dl_CompileAndExecuteMode(Self)){ return; } } #if 0 W3D_Texture *tex = context->w3dTextures[texnum].texObj; if (tex) IWarp3D->W3D_PinTexture(context->w3dContext, tex, TRUE); else #endif GLFlagError(context, 1, GL_INVALID_OPERATION); } void cgl_UnpinTexture(struct GLContextIFace *Self, GLuint texnum) { GLcontext context = GET_INSTANCE(Self); if(dl_IsDLActive(Self)){ dl_save_UnpinTexture(Self, texnum); if(!dl_CompileAndExecuteMode(Self)){ return; } } #if 0 W3D_Texture *tex = context->w3dTextures[texnum].texObj; if (tex) IWarp3D->W3D_PinTexture(context->w3dContext, tex, FALSE); else #endif GLFlagError(context, 1, GL_INVALID_OPERATION); } void cgl_SetTextureRenderTarget(struct GLContextIFace *Self, GLuint texnum) { GLcontext context = GET_INSTANCE(Self); if(dl_IsDLActive(Self)){ dl_save_SetTextureRenderTarget(Self, texnum); if(!dl_CompileAndExecuteMode(Self)){ return; } } #if 0 if (texnum != 0) { W3D_Texture *tex = context->w3dTextures[texnum].texObj; if (tex) { context->backupScissor = context->w3dScissor; context->w3dScissor.left = 0; context->w3dScissor.top = 0; context->w3dScissor.width = tex->texwidth; context->w3dScissor.height = tex->texheight; context->textureRenderTarget = texnum; if (IWarp3D->W3D_SetDrawRegionTexture(context->w3dContext, tex, &context->w3dScissor) != W3D_SUCCESS) { GLFlagError(context, 1, GL_INVALID_OPERATION); } } else GLFlagError(context, 1, GL_INVALID_OPERATION); } else { context->textureRenderTarget = 0; context->w3dScissor = context->backupScissor; IWarp3D->W3D_SetDrawRegionTexture(context->w3dContext, NULL, NULL); } #else GLFlagError(context, 1, GL_INVALID_OPERATION); #endif } void cgl_GLLogicOp(struct GLContextIFace *Self, GLenum op) { GLcontext context = GET_INSTANCE(Self); if(dl_IsDLActive(Self)){ dl_save_LogicOp(Self, op); if(!dl_CompileAndExecuteMode(Self)){ return; } } context->color_buffer.LogicOpMode = op; #define LOP(X) case GL_##X: lop = W3D_LO_##X; break; uint32 lop = W3D_LO_COPY; switch(context->color_buffer.LogicOpMode) { LOP(CLEAR); LOP(AND); LOP(AND_REVERSE); LOP(COPY); LOP(AND_INVERTED); LOP(NOOP); LOP(XOR); LOP(OR); LOP(NOR); LOP(EQUIV); LOP(INVERT); LOP(OR_REVERSE); LOP(COPY_INVERTED); LOP(OR_INVERTED); LOP(NAND); LOP(SET); } IWarp3D->W3D_SetLogicOp(context->w3dContext, lop); }