home *** CD-ROM | disk | FTP | other *** search
/ AmigActive 10 / AACD 10.iso / AACD / Programming / MiniGL / src / vertexbuffer.c < prev   
Encoding:
C/C++ Source or Header  |  2000-04-11  |  12.8 KB  |  435 lines

  1. /*
  2.  * $Id: vertexbuffer.c,v 1.1.1.1 2000/04/07 19:44:51 hfrieden Exp $
  3.  *
  4.  * $Date: 2000/04/07 19:44:51 $
  5.  * $Revision: 1.1.1.1 $
  6.  *
  7.  * (C) 1999 by Hyperion
  8.  * All rights reserved
  9.  *
  10.  * This file is part of the MiniGL library project
  11.  * See the file Licence.txt for more details
  12.  *
  13.  */
  14.  
  15. #include "sysinc.h"
  16. #include <stdio.h>
  17.  
  18. static char rcsid[] = "$Id: vertexbuffer.c,v 1.1.1.1 2000/04/07 19:44:51 hfrieden Exp $";
  19.  
  20.  
  21. extern void d_DrawPoints        (struct GLcontext_t);
  22. extern void d_DrawLines         (struct GLcontext_t);
  23. extern void d_DrawLineStrip     (struct GLcontext_t);
  24. extern void d_DrawTriangles     (struct GLcontext_t);
  25. extern void d_DrawTriangleFan   (struct GLcontext_t);
  26. extern void d_DrawTriangleStrip (struct GLcontext_t);
  27. extern void d_DrawQuads         (struct GLcontext_t);
  28. extern void d_DrawPolygon       (struct GLcontext_t);
  29. extern void d_DrawFlatFan       (struct GLcontext_t);
  30. extern void d_DrawQuadStrip     (struct GLcontext_t);
  31.  
  32. extern void tex_ConvertTexture  (GLcontext);
  33. extern void fog_Set             (GLcontext);
  34.  
  35. static struct Device *TimerBase;
  36.  
  37. void TMA_Start(LockTimeHandle *handle);
  38. GLboolean TMA_Check(LockTimeHandle *handle);
  39.  
  40. /*
  41. Timer based locking stuff.
  42.  
  43. TMA_Start starts the time measuring for the lock time. The 68k uses the ReadEClock
  44. function due to its low overhead. PPC will use GetSysTimePPC for the same reasons.
  45.  
  46. The EClock version reads the eclock and stores the current values in the handle.
  47. It then calculates a maximum lock time based on the assumption that the lock
  48. should be unlocked after 0.05 seconds (i.e. twenty times per second).
  49.  
  50. TMA_Check checks if the specified time has expired. If it returns GL_FALSE,
  51. the lock may be kept alive. On return of GL_TRUE, the lock must be released.
  52.  
  53. Note that this routine handles the case where the ev_hi values has changed, i.e.
  54. the eV_lo value had an overrun. This code also assumes, however, that the difference
  55. between the current and former ev_hi is no more than 1. This is, however, a very
  56. safe assumption; It takes approx. 100 minutes for the ev_hi field to increment,
  57. and it is extremely unlikely that the ev_hi field overruns - this will happen after
  58. approx. 820,000 years uptime (of course, a reliable system should be prepared for
  59. this)
  60.  
  61. */
  62.  
  63. #ifndef __PPC__
  64. void TMA_Start(LockTimeHandle *handle)
  65. {
  66.     struct EClockVal eval;
  67.     extern struct ExecBase *SysBase;
  68.     if (!TimerBase)
  69.     {
  70.         TimerBase = (struct Device *)FindName(&SysBase->DeviceList, "timer.device");
  71.     }
  72.  
  73.     handle->e_freq = ReadEClock(&eval);
  74.     handle->s_hi = eval.ev_hi;
  75.     handle->s_lo = eval.ev_lo;
  76.     handle->e_freq /= 20;
  77. }
  78.  
  79. GLboolean TMA_Check(LockTimeHandle *handle)
  80. {
  81.     struct EClockVal eval;
  82.     ULONG ticks;
  83.  
  84.     ReadEClock(&eval);
  85.  
  86.     if (eval.ev_hi == handle->s_hi)
  87.     {
  88.         ticks = eval.ev_lo - handle->s_lo;
  89.     }
  90.     else
  91.     {
  92.         ticks = (~0)-handle->s_lo + eval.ev_lo;
  93.     }
  94.  
  95.     if (ticks > handle->e_freq) return GL_TRUE;
  96.     else return GL_FALSE;
  97. }
  98.  
  99. #else
  100. void TMA_Start(LockTimeHandle *handle)
  101. {
  102.     GetSysTimePPC(&(handle->StartTime));
  103. }
  104.  
  105. GLboolean TMA_Check(LockTimeHandle *handle)
  106. {
  107.     struct timeval curTime;
  108.  
  109.     GetSysTimePPC(&curTime);
  110.     SubTimePPC(&curTime, &(handle->StartTime));
  111.     if (curTime.tv_secs) return GL_TRUE;
  112.     if (curTime.tv_micro > 50000) return GL_TRUE;
  113.     return GL_FALSE;
  114. }
  115. #endif
  116.  
  117. void GLBegin(GLcontext context, GLenum mode)
  118. {
  119. //    GLFlagError(context, context->CurrentPrimitive != GL_BASE, GL_INVALID_OPERATION);
  120.  
  121.     context->VertexBufferPointer = 0;
  122.     switch((int)mode)
  123.     {
  124.         case GL_POINTS:
  125.             //LOG(1, glBegin, "GL_POINTS");
  126.             context->CurrentPrimitive = mode;
  127.             context->CurrentDraw = (DrawFn)d_DrawPoints;
  128.             break;
  129.         case GL_LINES:
  130.             //LOG(1, glBegin, "GL_LINES");
  131.             context->CurrentPrimitive = mode;
  132.             context->CurrentDraw = (DrawFn)d_DrawLines;
  133.             break;
  134.         case GL_LINE_STRIP:
  135.             //LOG(1, glBegin, "GL_LINE_STRIP");
  136.             context->CurrentPrimitive = mode;
  137.             context->CurrentDraw = (DrawFn)d_DrawLineStrip;
  138.             break;
  139.         case GL_LINE_LOOP:
  140.             //LOG(1, glBegin, "GL_LINE_LOOP");
  141.             context->CurrentPrimitive = mode;
  142.             context->CurrentDraw = (DrawFn)d_DrawLineStrip;
  143.             break;
  144.         case GL_TRIANGLES:
  145.             //LOG(1, glBegin, "GL_TRIANLES");
  146.             context->CurrentPrimitive = mode;
  147.             context->CurrentDraw = (DrawFn)d_DrawTriangles;
  148.             break;
  149.         case GL_TRIANGLE_STRIP:
  150.             //LOG(1, glBegin, "GL_TRIANGLE_STRIP");
  151.             context->CurrentPrimitive = mode;
  152.             context->CurrentDraw = (DrawFn)d_DrawTriangleStrip;
  153.             break;
  154.         case GL_TRIANGLE_FAN:
  155.             //LOG(1, glBegin, "GL_TRIANGLE_FAN");
  156.             context->CurrentPrimitive = mode;
  157.             context->CurrentDraw = (DrawFn)d_DrawTriangleFan;
  158.             break;
  159.         case GL_QUADS:
  160.             //LOG(1, glBegin, "GL_QUADS");
  161.             context->CurrentPrimitive = mode;
  162.             context->CurrentDraw = (DrawFn)d_DrawQuads;
  163.             break;
  164.         case GL_QUAD_STRIP:
  165.             //LOG(1, glBegin, "GL_QUAD_STRIP");
  166.             context->CurrentPrimitive = mode;
  167.             context->CurrentDraw = (DrawFn)d_DrawQuadStrip;
  168.             break;
  169.         case GL_POLYGON:
  170.             //LOG(1, glBegin, "GL_POLYGON");
  171.             context->CurrentPrimitive = mode;
  172.             context->CurrentDraw = (DrawFn)d_DrawPolygon;
  173.             break;
  174.         case MGL_FLATFAN:
  175.             //LOG(1, glBegin, "MGL_FLATFAN");
  176.             context->CurrentPrimitive = mode;
  177.             context->CurrentDraw = (DrawFn)d_DrawFlatFan;
  178.             break;
  179.         default:
  180.             //LOG(1, glBegin, "Error GL_INVALID_OPERATION");
  181.             GLFlagError (context, 1, GL_INVALID_OPERATION);
  182.             break;
  183.     }
  184. }
  185.  
  186. void GLColor4f(GLcontext context, GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha)
  187. {
  188.     //LOG(2, glColor4f, "%f %f %f %f", red, green, blue, alpha);
  189.     context->CurrentColor.r = red;
  190.     context->CurrentColor.g = green;
  191.     context->CurrentColor.b = blue;
  192.     context->CurrentColor.a = alpha;
  193. }
  194.  
  195. void GLColor4fv(GLcontext context, GLfloat *v)
  196. {
  197.     //LOG(2, glColor4fv, "%f %f %f %f", v[0], v[1], v[2], v[3]);
  198.     context->CurrentColor.r = v[0];
  199.     context->CurrentColor.g = v[1];
  200.     context->CurrentColor.b = v[2];
  201.     context->CurrentColor.a = v[3];
  202. }
  203.  
  204. void GLColor3fv(GLcontext context, GLfloat *v)
  205. {
  206.     //LOG(2, glColor3fv, "%f %f %f", v[0], v[1], v[2]);
  207.     context->CurrentColor.r = v[0];
  208.     context->CurrentColor.g = v[1];
  209.     context->CurrentColor.b = v[2];
  210.     context->CurrentColor.a = 1.0;
  211. }
  212.  
  213. void GLColor4ub(GLcontext context, GLubyte red, GLubyte green, GLubyte blue, GLubyte alpha)
  214. {
  215.     register float f = 1/255.0;
  216.     //LOG(2, glColor4ub, "%f %f %f %f", red*f, green*f, blue*f, alpha*f);
  217.     context->CurrentColor.r = (GLfloat)red*f;
  218.     context->CurrentColor.g = (GLfloat)green*f;
  219.     context->CurrentColor.b = (GLfloat)blue*f;
  220.     context->CurrentColor.a = (GLfloat)alpha*f;
  221. }
  222.  
  223. void GLColor4ubv(GLcontext context, GLubyte *v)
  224. {
  225.     register float f = 1/255.0;
  226.     //LOG(2, glColor4ubv, "%f %f %f %f", v[0]*f, v[1]*f, v[2]*f, v[3]*f);
  227.     context->CurrentColor.r = (GLfloat)v[0]*f;
  228.     context->CurrentColor.g = (GLfloat)v[1]*f;
  229.     context->CurrentColor.b = (GLfloat)v[2]*f;
  230.     context->CurrentColor.a = (GLfloat)v[3]*f;
  231. }
  232.  
  233. void GLColor3ubv(GLcontext context, GLubyte *v)
  234. {
  235.     register float f = 1/255.0;
  236.     //LOG(2, glColor3ubv, "%f %f %f", v[0]*f, v[1]*f, v[2]*f);
  237.     context->CurrentColor.r = (GLfloat)v[0]*f;
  238.     context->CurrentColor.g = (GLfloat)v[1]*f;
  239.     context->CurrentColor.b = (GLfloat)v[2]*f;
  240.     context->CurrentColor.a = (GLfloat)1.0;
  241. }
  242.  
  243. #ifndef __STORM__
  244. static
  245. #endif
  246. inline W3D_Float CLAMPF(GLfloat x)
  247. {
  248.     if (x>=0.f && x<=1.f) return x;
  249.     else if (x<=0.f)      return 0.f;
  250.     else                  return 1.f;
  251. }
  252.  
  253. void GLVertex4f(GLcontext context, GLfloat x, GLfloat y, GLfloat z, GLfloat w)
  254. {
  255.     //LOG(1, glVertex4f, "%f %f %f %f", x,y,z,w);
  256.     #define thisvertex context->VertexBuffer[context->VertexBufferPointer]
  257.     thisvertex.bx = x;
  258.     thisvertex.by = y;
  259.     thisvertex.bz = z;
  260.     thisvertex.bw = w;
  261.  
  262.     /*
  263.     ** Current texture coordinates are s/t resp. This means
  264.     ** that texture wrap occurs at 0 and 1, not at 0 and width/height.
  265.     */
  266.     if (context->Texture2D_State == GL_TRUE)
  267.     {
  268.     thisvertex.v.u = context->CurrentTexS;
  269.     thisvertex.v.v = context->CurrentTexT;
  270.     if (context->w3dTexBuffer[context->CurrentBinding])
  271.     {
  272.         if (context->w3dChipID == W3D_CHIP_VIRGE)
  273.         {
  274.         thisvertex.v.u *= (context->w3dTexBuffer[context->CurrentBinding]->texwidth-1);
  275.         thisvertex.v.v *= (context->w3dTexBuffer[context->CurrentBinding]->texheight-1);
  276.         }
  277.         else
  278.         {
  279.         thisvertex.v.u *= context->w3dTexBuffer[context->CurrentBinding]->texwidth;
  280.         thisvertex.v.v *= context->w3dTexBuffer[context->CurrentBinding]->texheight;
  281.         }
  282.     }
  283.     }
  284.  
  285.     thisvertex.v.color.r = CLAMPF(context->CurrentColor.r);
  286.     thisvertex.v.color.g = CLAMPF(context->CurrentColor.g);
  287.     thisvertex.v.color.b = CLAMPF(context->CurrentColor.b);
  288.     thisvertex.v.color.a = CLAMPF(context->CurrentColor.a);
  289.  
  290.     thisvertex.Normal.x  = context->CurrentNormal.x;
  291.     thisvertex.Normal.y  = context->CurrentNormal.y;
  292.     thisvertex.Normal.z  = context->CurrentNormal.z;
  293.  
  294.     thisvertex.outcode = 0;
  295.     thisvertex.inview  = GL_FALSE;
  296.  
  297.     context->VertexBufferPointer ++;
  298.     #undef thisvertex
  299. }
  300.  
  301. void GLVertex4fv(GLcontext context, GLfloat *v)
  302. {
  303.     GLVertex4f(context, v[0], v[1], v[2], v[3]);
  304. }
  305.  
  306. void GLVertex3fv(GLcontext context, GLfloat *v)
  307. {
  308.     GLVertex4f(context, v[0], v[1], v[2], 1.0);
  309. }
  310.  
  311. void GLNormal3f(GLcontext context, GLfloat x, GLfloat y, GLfloat z)
  312. {
  313.     //LOG(2, glNormal3f, "%f %f %f", x,y,z);
  314.     context->CurrentNormal.x = x;
  315.     context->CurrentNormal.y = y;
  316.     context->CurrentNormal.z = z;
  317. }
  318.  
  319. void GLTexCoord2f(GLcontext context, GLfloat s, GLfloat t)
  320. {
  321.     //LOG(2, glTexCoord2f, "%f %f", s,t);
  322.     context->CurrentTexS = s;
  323.     context->CurrentTexT = t;
  324. }
  325.  
  326. void GLTexCoord2fv(GLcontext context, GLfloat *v)
  327. {
  328.     //LOG(2, glTexCoord2fv, "%f %f", v[0], v[1]);
  329.     context->CurrentTexS = v[0];
  330.     context->CurrentTexT = v[1];
  331. }
  332.  
  333. void GLDepthRange(GLcontext context, GLclampd n, GLclampd f)
  334. {
  335.     //LOG(2, glDepthRange, "%f %f", n, f);
  336.     context->near = n;
  337.     context->far  = f;
  338.     context->sz = (f-n)*0.5;
  339.     context->az = (n+f)*0.5;
  340. }
  341.  
  342. void GLViewport(GLcontext context, GLint x, GLint y, GLsizei w, GLsizei h)
  343. {
  344.     //LOG(2, glViewPort, "%d %d %d %d", x,y,w,h);
  345.     context->ax = (double)x + (double)w*0.5;
  346.     context->ay = (double)y + (double)h*0.5;
  347.     context->sx = (double)w * 0.5;
  348.     context->sy = (double)h * 0.5;
  349. }
  350.  
  351. void GLEnd(GLcontext context)
  352. {
  353.     //LOG(1, glEnd, "");
  354.  
  355.     if (context->FogDirty && context->Fog_State)
  356.     {
  357.         fog_Set(context);
  358.         context->FogDirty = GL_FALSE;
  359.     }
  360.  
  361.     if (context->ShadeModel == GL_FLAT)
  362.     {
  363.         static W3D_Color color;
  364.         color.r = CLAMPF(context->CurrentColor.r);
  365.         color.g = CLAMPF(context->CurrentColor.g);
  366.         color.b = CLAMPF(context->CurrentColor.b);
  367.         color.a = CLAMPF(context->CurrentColor.a);
  368.         W3D_SetCurrentColor(context->w3dContext, &color);
  369.     }
  370.  
  371.     // Check for blending inconsistancy
  372.     if (context->AlphaFellBack && (context->SrcAlpha == GL_ONE || context->DstAlpha == GL_ONE)
  373.         && context->Blend_State == GL_TRUE)
  374.     {
  375.         tex_ConvertTexture(context);
  376.     }
  377.  
  378.  
  379. #ifdef AUTOMATIC_LOCKING_ENABLE
  380.     if (context->LockMode == MGL_LOCK_AUTOMATIC) // Automatic: Lock per primitive
  381.     {
  382.         if (W3D_SUCCESS == W3D_LockHardware(context->w3dContext))
  383.         {
  384.             context->w3dLocked = GL_TRUE;
  385.             context->CurrentDraw(context);
  386.             W3D_UnLockHardware(context->w3dContext);
  387.             context->w3dLocked = GL_FALSE;
  388.         }
  389.         else
  390.         {
  391.             printf("Error during LockHardware\n");
  392.         }
  393.     }
  394.     else if (context->LockMode == MGL_LOCK_MANUAL) // Manual: Lock manually
  395.     {
  396.         context->CurrentDraw(context);
  397.     }
  398.     else // Smart: Lock timer based
  399.     {
  400.         if (context->w3dLocked == GL_FALSE)
  401.         {
  402.             if (W3D_SUCCESS != W3D_LockHardware(context->w3dContext))
  403.             {
  404.                 printf("[glEnd] Error during W3D_LockHardware()\n");
  405.                 return; // give up
  406.             }
  407.             context->w3dLocked = GL_TRUE;
  408.             TMA_Start(&(context->LockTime));
  409.         }
  410.         context->CurrentDraw(context);  // Draw!
  411.         if (TMA_Check(&(context->LockTime)) == GL_TRUE)
  412.         {
  413.             // Time to unlock
  414.             W3D_UnLockHardware(context->w3dContext);
  415.             context->w3dLocked = GL_FALSE;
  416.         }
  417.     }
  418. #else
  419.     context->CurrentDraw(context);
  420. #endif
  421.     context->CurrentPrimitive = GL_BASE;
  422. }
  423.  
  424. void GLFinish(GLcontext context)
  425. {
  426.     //LOG(2, glFinish, "");
  427.     GLFlush(context);
  428.     W3D_WaitIdle(context->w3dContext);
  429. }
  430.  
  431. void GLFlush(GLcontext context)
  432. {
  433.     //LOG(2, glFlush, "");
  434. }
  435.