home *** CD-ROM | disk | FTP | other *** search
- /*
- * $Id: vertexbuffer.c,v 1.1.1.1 2000/04/07 19:44:51 hfrieden Exp $
- *
- * $Date: 2000/04/07 19:44:51 $
- * $Revision: 1.1.1.1 $
- *
- * (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 "sysinc.h"
- #include <stdio.h>
-
- static char rcsid[] = "$Id: vertexbuffer.c,v 1.1.1.1 2000/04/07 19:44:51 hfrieden Exp $";
-
-
- extern void d_DrawPoints (struct GLcontext_t);
- extern void d_DrawLines (struct GLcontext_t);
- extern void d_DrawLineStrip (struct GLcontext_t);
- extern void d_DrawTriangles (struct GLcontext_t);
- extern void d_DrawTriangleFan (struct GLcontext_t);
- extern void d_DrawTriangleStrip (struct GLcontext_t);
- extern void d_DrawQuads (struct GLcontext_t);
- extern void d_DrawPolygon (struct GLcontext_t);
- extern void d_DrawFlatFan (struct GLcontext_t);
- extern void d_DrawQuadStrip (struct GLcontext_t);
-
- extern void tex_ConvertTexture (GLcontext);
- extern void fog_Set (GLcontext);
-
- static struct Device *TimerBase;
-
- void TMA_Start(LockTimeHandle *handle);
- GLboolean TMA_Check(LockTimeHandle *handle);
-
- /*
- Timer based locking stuff.
-
- TMA_Start starts the time measuring for the lock time. The 68k uses the ReadEClock
- function due to its low overhead. PPC will use GetSysTimePPC for the same reasons.
-
- The EClock version reads the eclock and stores the current values in the handle.
- It then calculates a maximum lock time based on the assumption that the lock
- should be unlocked after 0.05 seconds (i.e. twenty times per second).
-
- TMA_Check checks if the specified time has expired. If it returns GL_FALSE,
- the lock may be kept alive. On return of GL_TRUE, the lock must be released.
-
- Note that this routine handles the case where the ev_hi values has changed, i.e.
- the eV_lo value had an overrun. This code also assumes, however, that the difference
- between the current and former ev_hi is no more than 1. This is, however, a very
- safe assumption; It takes approx. 100 minutes for the ev_hi field to increment,
- and it is extremely unlikely that the ev_hi field overruns - this will happen after
- approx. 820,000 years uptime (of course, a reliable system should be prepared for
- this)
-
- */
-
- #ifndef __PPC__
- void TMA_Start(LockTimeHandle *handle)
- {
- struct EClockVal eval;
- extern struct ExecBase *SysBase;
- if (!TimerBase)
- {
- TimerBase = (struct Device *)FindName(&SysBase->DeviceList, "timer.device");
- }
-
- handle->e_freq = ReadEClock(&eval);
- handle->s_hi = eval.ev_hi;
- handle->s_lo = eval.ev_lo;
- handle->e_freq /= 20;
- }
-
- GLboolean TMA_Check(LockTimeHandle *handle)
- {
- struct EClockVal eval;
- ULONG ticks;
-
- ReadEClock(&eval);
-
- if (eval.ev_hi == handle->s_hi)
- {
- ticks = eval.ev_lo - handle->s_lo;
- }
- else
- {
- ticks = (~0)-handle->s_lo + eval.ev_lo;
- }
-
- if (ticks > handle->e_freq) return GL_TRUE;
- else return GL_FALSE;
- }
-
- #else
- void TMA_Start(LockTimeHandle *handle)
- {
- GetSysTimePPC(&(handle->StartTime));
- }
-
- GLboolean TMA_Check(LockTimeHandle *handle)
- {
- struct timeval curTime;
-
- GetSysTimePPC(&curTime);
- SubTimePPC(&curTime, &(handle->StartTime));
- if (curTime.tv_secs) return GL_TRUE;
- if (curTime.tv_micro > 50000) return GL_TRUE;
- return GL_FALSE;
- }
- #endif
-
- void GLBegin(GLcontext context, GLenum mode)
- {
- // GLFlagError(context, context->CurrentPrimitive != GL_BASE, GL_INVALID_OPERATION);
-
- context->VertexBufferPointer = 0;
- switch((int)mode)
- {
- case GL_POINTS:
- //LOG(1, glBegin, "GL_POINTS");
- context->CurrentPrimitive = mode;
- context->CurrentDraw = (DrawFn)d_DrawPoints;
- break;
- case GL_LINES:
- //LOG(1, glBegin, "GL_LINES");
- context->CurrentPrimitive = mode;
- context->CurrentDraw = (DrawFn)d_DrawLines;
- break;
- case GL_LINE_STRIP:
- //LOG(1, glBegin, "GL_LINE_STRIP");
- context->CurrentPrimitive = mode;
- context->CurrentDraw = (DrawFn)d_DrawLineStrip;
- break;
- case GL_LINE_LOOP:
- //LOG(1, glBegin, "GL_LINE_LOOP");
- context->CurrentPrimitive = mode;
- context->CurrentDraw = (DrawFn)d_DrawLineStrip;
- break;
- case GL_TRIANGLES:
- //LOG(1, glBegin, "GL_TRIANLES");
- context->CurrentPrimitive = mode;
- context->CurrentDraw = (DrawFn)d_DrawTriangles;
- break;
- case GL_TRIANGLE_STRIP:
- //LOG(1, glBegin, "GL_TRIANGLE_STRIP");
- context->CurrentPrimitive = mode;
- context->CurrentDraw = (DrawFn)d_DrawTriangleStrip;
- break;
- case GL_TRIANGLE_FAN:
- //LOG(1, glBegin, "GL_TRIANGLE_FAN");
- context->CurrentPrimitive = mode;
- context->CurrentDraw = (DrawFn)d_DrawTriangleFan;
- break;
- case GL_QUADS:
- //LOG(1, glBegin, "GL_QUADS");
- context->CurrentPrimitive = mode;
- context->CurrentDraw = (DrawFn)d_DrawQuads;
- break;
- case GL_QUAD_STRIP:
- //LOG(1, glBegin, "GL_QUAD_STRIP");
- context->CurrentPrimitive = mode;
- context->CurrentDraw = (DrawFn)d_DrawQuadStrip;
- break;
- case GL_POLYGON:
- //LOG(1, glBegin, "GL_POLYGON");
- context->CurrentPrimitive = mode;
- context->CurrentDraw = (DrawFn)d_DrawPolygon;
- break;
- case MGL_FLATFAN:
- //LOG(1, glBegin, "MGL_FLATFAN");
- context->CurrentPrimitive = mode;
- context->CurrentDraw = (DrawFn)d_DrawFlatFan;
- break;
- default:
- //LOG(1, glBegin, "Error GL_INVALID_OPERATION");
- GLFlagError (context, 1, GL_INVALID_OPERATION);
- break;
- }
- }
-
- void GLColor4f(GLcontext context, GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha)
- {
- //LOG(2, glColor4f, "%f %f %f %f", red, green, blue, alpha);
- context->CurrentColor.r = red;
- context->CurrentColor.g = green;
- context->CurrentColor.b = blue;
- context->CurrentColor.a = alpha;
- }
-
- void GLColor4fv(GLcontext context, GLfloat *v)
- {
- //LOG(2, glColor4fv, "%f %f %f %f", v[0], v[1], v[2], v[3]);
- context->CurrentColor.r = v[0];
- context->CurrentColor.g = v[1];
- context->CurrentColor.b = v[2];
- context->CurrentColor.a = v[3];
- }
-
- void GLColor3fv(GLcontext context, GLfloat *v)
- {
- //LOG(2, glColor3fv, "%f %f %f", v[0], v[1], v[2]);
- context->CurrentColor.r = v[0];
- context->CurrentColor.g = v[1];
- context->CurrentColor.b = v[2];
- context->CurrentColor.a = 1.0;
- }
-
- void GLColor4ub(GLcontext context, GLubyte red, GLubyte green, GLubyte blue, GLubyte alpha)
- {
- register float f = 1/255.0;
- //LOG(2, glColor4ub, "%f %f %f %f", red*f, green*f, blue*f, alpha*f);
- context->CurrentColor.r = (GLfloat)red*f;
- context->CurrentColor.g = (GLfloat)green*f;
- context->CurrentColor.b = (GLfloat)blue*f;
- context->CurrentColor.a = (GLfloat)alpha*f;
- }
-
- void GLColor4ubv(GLcontext context, GLubyte *v)
- {
- register float f = 1/255.0;
- //LOG(2, glColor4ubv, "%f %f %f %f", v[0]*f, v[1]*f, v[2]*f, v[3]*f);
- context->CurrentColor.r = (GLfloat)v[0]*f;
- context->CurrentColor.g = (GLfloat)v[1]*f;
- context->CurrentColor.b = (GLfloat)v[2]*f;
- context->CurrentColor.a = (GLfloat)v[3]*f;
- }
-
- void GLColor3ubv(GLcontext context, GLubyte *v)
- {
- register float f = 1/255.0;
- //LOG(2, glColor3ubv, "%f %f %f", v[0]*f, v[1]*f, v[2]*f);
- context->CurrentColor.r = (GLfloat)v[0]*f;
- context->CurrentColor.g = (GLfloat)v[1]*f;
- context->CurrentColor.b = (GLfloat)v[2]*f;
- context->CurrentColor.a = (GLfloat)1.0;
- }
-
- #ifndef __STORM__
- static
- #endif
- inline W3D_Float CLAMPF(GLfloat x)
- {
- if (x>=0.f && x<=1.f) return x;
- else if (x<=0.f) return 0.f;
- else return 1.f;
- }
-
- void GLVertex4f(GLcontext context, GLfloat x, GLfloat y, GLfloat z, GLfloat w)
- {
- //LOG(1, glVertex4f, "%f %f %f %f", x,y,z,w);
- #define thisvertex context->VertexBuffer[context->VertexBufferPointer]
- thisvertex.bx = x;
- thisvertex.by = y;
- thisvertex.bz = z;
- thisvertex.bw = w;
-
- /*
- ** Current texture coordinates are s/t resp. This means
- ** that texture wrap occurs at 0 and 1, not at 0 and width/height.
- */
- if (context->Texture2D_State == GL_TRUE)
- {
- thisvertex.v.u = context->CurrentTexS;
- thisvertex.v.v = context->CurrentTexT;
- if (context->w3dTexBuffer[context->CurrentBinding])
- {
- if (context->w3dChipID == W3D_CHIP_VIRGE)
- {
- thisvertex.v.u *= (context->w3dTexBuffer[context->CurrentBinding]->texwidth-1);
- thisvertex.v.v *= (context->w3dTexBuffer[context->CurrentBinding]->texheight-1);
- }
- else
- {
- thisvertex.v.u *= context->w3dTexBuffer[context->CurrentBinding]->texwidth;
- thisvertex.v.v *= context->w3dTexBuffer[context->CurrentBinding]->texheight;
- }
- }
- }
-
- thisvertex.v.color.r = CLAMPF(context->CurrentColor.r);
- thisvertex.v.color.g = CLAMPF(context->CurrentColor.g);
- thisvertex.v.color.b = CLAMPF(context->CurrentColor.b);
- thisvertex.v.color.a = CLAMPF(context->CurrentColor.a);
-
- thisvertex.Normal.x = context->CurrentNormal.x;
- thisvertex.Normal.y = context->CurrentNormal.y;
- thisvertex.Normal.z = context->CurrentNormal.z;
-
- thisvertex.outcode = 0;
- thisvertex.inview = GL_FALSE;
-
- context->VertexBufferPointer ++;
- #undef thisvertex
- }
-
- void GLVertex4fv(GLcontext context, GLfloat *v)
- {
- GLVertex4f(context, v[0], v[1], v[2], v[3]);
- }
-
- void GLVertex3fv(GLcontext context, GLfloat *v)
- {
- GLVertex4f(context, v[0], v[1], v[2], 1.0);
- }
-
- void GLNormal3f(GLcontext context, GLfloat x, GLfloat y, GLfloat z)
- {
- //LOG(2, glNormal3f, "%f %f %f", x,y,z);
- context->CurrentNormal.x = x;
- context->CurrentNormal.y = y;
- context->CurrentNormal.z = z;
- }
-
- void GLTexCoord2f(GLcontext context, GLfloat s, GLfloat t)
- {
- //LOG(2, glTexCoord2f, "%f %f", s,t);
- context->CurrentTexS = s;
- context->CurrentTexT = t;
- }
-
- void GLTexCoord2fv(GLcontext context, GLfloat *v)
- {
- //LOG(2, glTexCoord2fv, "%f %f", v[0], v[1]);
- context->CurrentTexS = v[0];
- context->CurrentTexT = v[1];
- }
-
- void GLDepthRange(GLcontext context, GLclampd n, GLclampd f)
- {
- //LOG(2, glDepthRange, "%f %f", n, f);
- context->near = n;
- context->far = f;
- context->sz = (f-n)*0.5;
- context->az = (n+f)*0.5;
- }
-
- void GLViewport(GLcontext context, GLint x, GLint y, GLsizei w, GLsizei h)
- {
- //LOG(2, glViewPort, "%d %d %d %d", x,y,w,h);
- context->ax = (double)x + (double)w*0.5;
- context->ay = (double)y + (double)h*0.5;
- context->sx = (double)w * 0.5;
- context->sy = (double)h * 0.5;
- }
-
- void GLEnd(GLcontext context)
- {
- //LOG(1, glEnd, "");
-
- if (context->FogDirty && context->Fog_State)
- {
- fog_Set(context);
- context->FogDirty = GL_FALSE;
- }
-
- if (context->ShadeModel == GL_FLAT)
- {
- static W3D_Color color;
- color.r = CLAMPF(context->CurrentColor.r);
- color.g = CLAMPF(context->CurrentColor.g);
- color.b = CLAMPF(context->CurrentColor.b);
- color.a = CLAMPF(context->CurrentColor.a);
- W3D_SetCurrentColor(context->w3dContext, &color);
- }
-
- // Check for blending inconsistancy
- if (context->AlphaFellBack && (context->SrcAlpha == GL_ONE || context->DstAlpha == GL_ONE)
- && context->Blend_State == GL_TRUE)
- {
- tex_ConvertTexture(context);
- }
-
-
- #ifdef AUTOMATIC_LOCKING_ENABLE
- if (context->LockMode == MGL_LOCK_AUTOMATIC) // Automatic: Lock per primitive
- {
- if (W3D_SUCCESS == W3D_LockHardware(context->w3dContext))
- {
- context->w3dLocked = GL_TRUE;
- context->CurrentDraw(context);
- W3D_UnLockHardware(context->w3dContext);
- context->w3dLocked = GL_FALSE;
- }
- else
- {
- printf("Error during LockHardware\n");
- }
- }
- else if (context->LockMode == MGL_LOCK_MANUAL) // Manual: Lock manually
- {
- context->CurrentDraw(context);
- }
- else // Smart: Lock timer based
- {
- if (context->w3dLocked == GL_FALSE)
- {
- if (W3D_SUCCESS != W3D_LockHardware(context->w3dContext))
- {
- printf("[glEnd] Error during W3D_LockHardware()\n");
- return; // give up
- }
- context->w3dLocked = GL_TRUE;
- TMA_Start(&(context->LockTime));
- }
- context->CurrentDraw(context); // Draw!
- if (TMA_Check(&(context->LockTime)) == GL_TRUE)
- {
- // Time to unlock
- W3D_UnLockHardware(context->w3dContext);
- context->w3dLocked = GL_FALSE;
- }
- }
- #else
- context->CurrentDraw(context);
- #endif
- context->CurrentPrimitive = GL_BASE;
- }
-
- void GLFinish(GLcontext context)
- {
- //LOG(2, glFinish, "");
- GLFlush(context);
- W3D_WaitIdle(context->w3dContext);
- }
-
- void GLFlush(GLcontext context)
- {
- //LOG(2, glFlush, "");
- }
-