00001
00002
00003
00004
00005
00006 #include "RAS_OpenGLRasterizer.h"
00007
00008 #ifdef WIN32
00009 #define __EXPERIMENTAL_EXTENSION
00010 #include <windows.h>
00011 #endif // WIN32
00012 #include "GL/gl.h"
00013
00014
00015 #include "StdString.h"
00016
00017
00018 #include "RAS_TexVert.h"
00019 #include "KX_Matrix4x4.h"
00020 #include "RAS_IRenderTools.h"
00021
00022 RAS_OpenGLRasterizer::RAS_OpenGLRasterizer(RAS_ICanvas* canvas)
00023 :RAS_IRasterizer(canvas),
00024 m_2DCanvas(canvas),
00025 m_fogenabled(false)
00026 {
00027 m_viewmatrix.Identity();
00028 }
00029
00030
00031
00032 RAS_OpenGLRasterizer::~RAS_OpenGLRasterizer()
00033 {
00034 }
00035
00036
00037 #ifdef WIN32
00038 typedef void (APIENTRY *GLLOCKARRAYSEXTPTR)(GLint first,GLsizei count);
00039 typedef void (APIENTRY *GLUNLOCKARRAYSEXTPTR)(void);
00040 void APIENTRY RAS_lockfunc(GLint first,GLsizei count) {};
00041 void APIENTRY RAS_unlockfunc() {};
00042 GLLOCKARRAYSEXTPTR glLockArraysEXT=RAS_lockfunc;
00043 GLUNLOCKARRAYSEXTPTR glUnlockArraysEXT=RAS_unlockfunc;
00044 #endif //WIN32
00045
00046 bool RAS_OpenGLRasterizer::Init()
00047 {
00048
00049 m_redback = 0.4375;
00050 m_greenback=0.4375;
00051 m_blueback = 0.4375;
00052 m_alphaback = 0.0;
00053
00054 #ifdef __EXPERIMENTAL_EXTENSION
00055
00056 CCString extensions = (char*)glGetString(GL_EXTENSIONS);
00057 m_bEXT_compiled_vertex_array = false;
00058
00059
00060
00061
00062
00063 #ifdef WIN32
00064 if (extensions.Find("GL_EXT_compiled_vertex_array"))
00065 {
00066 m_bEXT_compiled_vertex_array = true;
00067 glUnlockArraysEXT = reinterpret_cast<GLUNLOCKARRAYSEXTPTR>(wglGetProcAddress("glUnlockArraysEXT"));
00068 glLockArraysEXT = reinterpret_cast<GLLOCKARRAYSEXTPTR>(wglGetProcAddress("glLockArraysEXT"));
00069 }
00070 #endif //WIN32
00071
00072 #endif //__EXPERIMENTAL_EXTENSION
00073
00074
00075
00076
00077
00078
00079
00080
00081 glEnable(GL_COLOR_MATERIAL);
00082
00083 #ifdef SLOWPAINT
00084 glDisableClientState(GL_VERTEX_ARRAY);
00085 #else
00086 glEnableClientState(GL_VERTEX_ARRAY);
00087 #endif //SLOWPAINT
00088
00089 glDisableClientState(GL_TEXTURE_COORD_ARRAY);
00090 glDisableClientState(GL_NORMAL_ARRAY);
00091 glDisableClientState(GL_COLOR_ARRAY);
00092
00093
00094
00095 glClearColor(m_redback,m_greenback,m_blueback,m_alphaback);
00096
00097 switch (m_drawingmode)
00098 {
00099 case KX_BOUNDINGBOX:
00100 {
00101 }
00102 case KX_WIREFRAME:
00103 {
00104 glDisable (GL_CULL_FACE);
00105 glClear(GL_COLOR_BUFFER_BIT);
00106
00107 break;
00108 }
00109
00110
00111 case KX_TEXTURED:
00112 {
00113
00114 }
00115
00116 case KX_SHADED:
00117 {
00118
00119 glEnableClientState(GL_COLOR_ARRAY);
00120 }
00121 case KX_SOLID:
00122 {
00123 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
00124 break;
00125 }
00126
00127 default:
00128 {
00129 }
00130 }
00131
00132
00133
00134
00135
00136 glShadeModel(GL_SMOOTH);
00137
00138 return true;
00139 }
00140
00141 void RAS_OpenGLRasterizer::SetBackColor(float red,float green,float blue,float alpha)
00142 {
00143 m_redback= red;
00144 m_greenback= green;
00145 m_blueback= blue;
00146 m_alphaback= alpha;
00147
00148
00149 }
00150 void RAS_OpenGLRasterizer::SetFog(float start,float dist,float r,float g,float b)
00151 {
00152 m_fogstart = start;
00153 m_fogdist = dist;
00154 m_fogr= r;
00155 m_fogg=g;
00156 m_fogb = b;
00157 m_fogenabled = true;
00158 }
00159
00160 void RAS_OpenGLRasterizer::DisplayFog()
00161 {
00162 if (m_fogenabled)
00163 {
00164 float params[5];
00165 glFogi(GL_FOG_MODE, GL_LINEAR);
00166 glFogf(GL_FOG_DENSITY, 0.1f);
00167 glFogf(GL_FOG_START, m_fogstart);
00168 glFogf(GL_FOG_END, m_fogstart + m_fogdist);
00169 params[0]= m_fogr;
00170 params[1]= m_fogg;
00171 params[2]= m_fogb;
00172 params[3]= 0.0;
00173 glFogfv(GL_FOG_COLOR, params);
00174 glEnable(GL_FOG);
00175 }
00176 }
00177
00178 void RAS_OpenGLRasterizer::SetMaterial(const RAS_IPolyMaterial& mat)
00179 {
00180 }
00181
00182 void RAS_OpenGLRasterizer::Exit()
00183 {
00184
00185 glEnable (GL_CULL_FACE);
00186 glEnable(GL_DEPTH_TEST);
00187 glClearDepth(1.0);
00188 glClearColor(m_redback,m_greenback,m_blueback,m_alphaback);
00189 glClear(GL_ALL_ATTRIB_BITS);
00190 glDepthMask (GL_TRUE);
00191 glDepthFunc(GL_LEQUAL);
00192 glBlendFunc(GL_ONE, GL_ZERO);
00193 glDisableClientState(GL_VERTEX_ARRAY);
00194 glDisableClientState(GL_TEXTURE_COORD_ARRAY);
00195 glDisableClientState(GL_COLOR_ARRAY);
00196 glDisableClientState(GL_NORMAL_ARRAY);
00197 glDisable(GL_COLOR_MATERIAL);
00198
00199 glDisable(GL_LIGHTING);
00200
00201
00202 EndFrame();
00203
00204 }
00205
00206
00207
00208 bool RAS_OpenGLRasterizer::BeginFrame()
00209 {
00210 m_2DCanvas->BeginFrame();
00211
00212 m_2DCanvas->ClearColor(m_redback,m_greenback,m_blueback,m_alphaback);
00213
00214
00215 if (m_drawingmode < KX_SOLID)
00216 {
00217 m_2DCanvas->ClearBuffer(RAS_ICanvas::COLOR_BUFFER);
00218 } else
00219 {
00220 m_2DCanvas->ClearBuffer(RAS_ICanvas::COLOR_BUFFER | RAS_ICanvas::DEPTH_BUFFER);
00221 DisplayFog();
00222 }
00223
00224
00225 if (m_drawingmode < KX_SOLID)
00226 {
00227 glDisable (GL_CULL_FACE);
00228 glDisable (GL_DEPTH_TEST);
00229 } else
00230 {
00231 glEnable(GL_DEPTH_TEST);
00232 glEnable (GL_CULL_FACE);
00233 }
00234
00235
00236
00237 glShadeModel(GL_SMOOTH);
00238
00239
00240 return true;
00241 }
00242
00243 void RAS_OpenGLRasterizer::SetDepthMask(int depthmask)
00244 {
00245 switch (depthmask)
00246 {
00247 case KX_DEPTHMASK_ENABLED: {
00248 glDepthMask(GL_TRUE);
00249 break;
00250 };
00251 case KX_DEPTHMASK_DISABLED: {
00252 glDepthMask(GL_FALSE);
00253 break;
00254 };
00255 default:{
00256
00257 exit(0);
00258 }
00259
00260 }
00261
00262
00263 }
00264 void RAS_OpenGLRasterizer::EndFrame()
00265 {
00266 m_2DCanvas->EndFrame();
00267 }
00268
00269 void RAS_OpenGLRasterizer::SwapBuffers()
00270 {
00271 m_2DCanvas->SwapBuffers();
00272 }
00273
00274
00275
00276
00277 void RAS_OpenGLRasterizer::IndexPrimitives(const vecVertexArray & vertexarrays,
00278 const vecIndexArrays & indexarrays,
00279 int mode,
00280 class RAS_IPolyMaterial* polymat,
00281 class RAS_IRenderTools* rendertools)
00282 {
00283
00284
00285 int polymatmode = polymat->GetDrawingMode();
00286
00287 unsigned char* mypointer=NULL;
00288 static const GLsizei vtxstride = sizeof(RAS_TexVert);
00289 GLenum drawmode;
00290 switch (mode)
00291 {
00292 case 0:
00293 drawmode = GL_TRIANGLES;
00294 break;
00295 case 1:
00296 drawmode = GL_LINES;
00297 break;
00298 case 2:
00299 drawmode = GL_QUADS;
00300 break;
00301 default:
00302 drawmode = GL_LINES;
00303 break;
00304 }
00305
00306 const RAS_TexVert* vertexarray ;
00307
00308 int numindices ;
00309 int vt;
00310
00311
00312 if (polymatmode & 16384)
00313 {
00314 for (vt=0;vt<vertexarrays.size();vt++)
00315 {
00316 vertexarray = &((*vertexarrays[vt]) [0]);
00317 const KX_IndexArray & indexarray = (*indexarrays[vt]);
00318
00319 numindices = indexarray.size();
00320
00321
00322
00323 int numverts = vertexarrays[vt]->size();
00324
00325 if (!numindices)
00326 break;
00327
00328 mypointer = (unsigned char*)(vertexarray);
00329 glVertexPointer(3,GL_FLOAT,vtxstride,mypointer);
00330 mypointer+= 3*sizeof(float);
00331 glTexCoordPointer(2,GL_FLOAT,vtxstride,mypointer);
00332 mypointer+= 2*sizeof(float);
00333 glColorPointer(4,GL_UNSIGNED_BYTE,vtxstride,mypointer);
00334 mypointer += sizeof(int);
00335 glNormalPointer(GL_SHORT,vtxstride,mypointer);
00336
00337 int vindex=0;
00338 switch (mode)
00339 {
00340
00341 case 1:
00342 {
00343 glBegin(GL_LINES);
00344 vindex=0;
00345 for (int i=0;i<numindices;i+=2)
00346 {
00347 glVertex3fv(vertexarray[(indexarray[vindex++])].getLocalXYZ());
00348 glVertex3fv(vertexarray[(indexarray[vindex++])].getLocalXYZ());
00349 }
00350 glEnd();
00351 }
00352 break;
00353 case 2:
00354 {
00355
00356 vindex=0;
00357 for (int i=0;i<numindices;i+=4)
00358 {
00359 float v1[3],v2[3],v3[3],v4[3];
00360
00361 char *cp= (char *)&(vertexarray[(indexarray[vindex])].getRGBA());
00362 v1[0] = vertexarray[(indexarray[vindex])].getLocalXYZ()[0];
00363 v1[1] = vertexarray[(indexarray[vindex])].getLocalXYZ()[1];
00364 v1[2] = vertexarray[(indexarray[vindex])].getLocalXYZ()[2];
00365 vindex++;
00366
00367 cp= (char *)&(vertexarray[(indexarray[vindex])].getRGBA());
00368 v2[0] = vertexarray[(indexarray[vindex])].getLocalXYZ()[0];
00369 v2[1] = vertexarray[(indexarray[vindex])].getLocalXYZ()[1];
00370 v2[2] = vertexarray[(indexarray[vindex])].getLocalXYZ()[2];
00371 vindex++;
00372
00373 cp= (char *)&(vertexarray[(indexarray[vindex])].getRGBA());
00374 v3[0] = vertexarray[(indexarray[vindex])].getLocalXYZ()[0];
00375 v3[1] = vertexarray[(indexarray[vindex])].getLocalXYZ()[1];
00376 v3[2] = vertexarray[(indexarray[vindex])].getLocalXYZ()[2];
00377 vindex++;
00378
00379 cp= (char *)&(vertexarray[(indexarray[vindex])].getRGBA());
00380 v4[0] = vertexarray[(indexarray[vindex])].getLocalXYZ()[0];
00381 v4[1] = vertexarray[(indexarray[vindex])].getLocalXYZ()[1];
00382 v4[2] = vertexarray[(indexarray[vindex])].getLocalXYZ()[2];
00383
00384 vindex++;
00385
00386 rendertools->RenderText(polymat->GetDrawingMode(),polymat,v1,v2,v3,v4);
00387
00388
00389 }
00390
00391 break;
00392
00393 }
00394 case 0:
00395 {
00396
00397 glBegin(GL_TRIANGLES);
00398 vindex=0;
00399 for (int i=0;i<numindices;i+=3)
00400 {
00401 float v1[3],v2[3],v3[3];
00402
00403 v1[0] = vertexarray[(indexarray[vindex])].getLocalXYZ()[0];
00404 v1[1] = vertexarray[(indexarray[vindex])].getLocalXYZ()[1];
00405 v1[2] = vertexarray[(indexarray[vindex])].getLocalXYZ()[2];
00406 vindex++;
00407
00408 v2[0] = vertexarray[(indexarray[vindex])].getLocalXYZ()[0];
00409 v2[1] = vertexarray[(indexarray[vindex])].getLocalXYZ()[1];
00410 v2[2] = vertexarray[(indexarray[vindex])].getLocalXYZ()[2];
00411 vindex++;
00412
00413 v3[0] = vertexarray[(indexarray[vindex])].getLocalXYZ()[0];
00414 v3[1] = vertexarray[(indexarray[vindex])].getLocalXYZ()[1];
00415 v3[2] = vertexarray[(indexarray[vindex])].getLocalXYZ()[2];
00416 vindex++;
00417
00418 rendertools->RenderText(polymat->GetDrawingMode(),polymat,v1,v2,v3,NULL);
00419
00420 }
00421 glEnd();
00422 break;
00423 }
00424 default:
00425 {
00426 }
00427
00428 }
00429
00430 }
00431
00432 } else
00433 {
00434
00435 for (vt=0;vt<vertexarrays.size();vt++)
00436 {
00437 vertexarray = &((*vertexarrays[vt]) [0]);
00438 const KX_IndexArray & indexarray = (*indexarrays[vt]);
00439
00440 numindices = indexarray.size();
00441
00442
00443
00444 int numverts = vertexarrays[vt]->size();
00445
00446 if (!numindices)
00447 break;
00448
00449
00450 mypointer = (unsigned char*)(vertexarray);
00451 glVertexPointer(3,GL_FLOAT,vtxstride,mypointer);
00452 mypointer+= 3*sizeof(float);
00453 glTexCoordPointer(2,GL_FLOAT,vtxstride,mypointer);
00454 mypointer+= 2*sizeof(float);
00455 glColorPointer(4,GL_UNSIGNED_BYTE,vtxstride,mypointer);
00456 mypointer += sizeof(int);
00457 glNormalPointer(GL_SHORT,vtxstride,mypointer);
00458
00459
00460
00461
00462 #ifndef SLOWPAINT
00463
00464 #ifdef __EXPERIMENTAL_EXTENSION
00465 glLockArraysEXT(0,numverts);
00466 #endif //__EXPERIMENTAL_EXTENSION
00467
00468
00469 glDrawElements(drawmode,numindices,GL_UNSIGNED_INT,&(indexarray[0]));
00470
00471
00472 #ifdef __EXPERIMENTAL_EXTENSION
00473 glUnlockArraysEXT();
00474 #endif //__EXPERIMENTAL_EXTENSION
00475
00476 #else
00477
00478
00479 int vindex=0;
00480 switch (mode)
00481 {
00482
00483 case 1:
00484 {
00485 glBegin(GL_LINES);
00486 vindex=0;
00487 for (int i=0;i<numindices;i+=2)
00488 {
00489 glVertex3fv(vertexarray[(indexarray[vindex++])].getLocalXYZ());
00490 glVertex3fv(vertexarray[(indexarray[vindex++])].getLocalXYZ());
00491 }
00492 glEnd();
00493 }
00494 break;
00495 case 2:
00496 {
00497 glBegin(GL_QUADS);
00498 vindex=0;
00499 for (int i=0;i<numindices;i+=4)
00500 {
00501
00502
00503 char *cp= (char *)&(vertexarray[(indexarray[vindex])].getRGBA());
00504 glColor3ub(cp[0], cp[1], cp[2]);
00505 glNormal3sv(vertexarray[(indexarray[vindex])].getNormal());
00506 glTexCoord2fv(vertexarray[(indexarray[vindex])].getUV1());
00507 glVertex3fv(vertexarray[(indexarray[vindex])].getLocalXYZ());
00508 vindex++;
00509
00510 cp= (char *)&(vertexarray[(indexarray[vindex])].getRGBA());
00511 glColor3ub(cp[0], cp[1], cp[2]);
00512 glNormal3sv(vertexarray[(indexarray[vindex])].getNormal());
00513 glTexCoord2fv(vertexarray[(indexarray[vindex])].getUV1());
00514 glVertex3fv(vertexarray[(indexarray[vindex])].getLocalXYZ());
00515 vindex++;
00516
00517 cp= (char *)&(vertexarray[(indexarray[vindex])].getRGBA());
00518 glColor3ub(cp[0], cp[1], cp[2]);
00519 glNormal3sv(vertexarray[(indexarray[vindex])].getNormal());
00520 glTexCoord2fv(vertexarray[(indexarray[vindex])].getUV1());
00521 glVertex3fv(vertexarray[(indexarray[vindex])].getLocalXYZ());
00522 vindex++;
00523
00524 cp= (char *)&(vertexarray[(indexarray[vindex])].getRGBA());
00525 glColor3ub(cp[0], cp[1], cp[2]);
00526 glNormal3sv(vertexarray[(indexarray[vindex])].getNormal());
00527 glTexCoord2fv(vertexarray[(indexarray[vindex])].getUV1());
00528 glVertex3fv(vertexarray[(indexarray[vindex])].getLocalXYZ());
00529 vindex++;
00530 }
00531 glEnd();
00532 break;
00533
00534 }
00535 case 0:
00536 {
00537
00538 glBegin(GL_TRIANGLES);
00539 vindex=0;
00540 for (int i=0;i<numindices;i+=3)
00541 {
00542 char *cp= (char *)&(vertexarray[(indexarray[vindex])].getRGBA());
00543 glColor3ub(cp[0], cp[1], cp[2]);
00544 glNormal3sv(vertexarray[(indexarray[vindex])].getNormal());
00545 glTexCoord2fv(vertexarray[(indexarray[vindex])].getUV1());
00546 glVertex3fv(vertexarray[(indexarray[vindex])].getLocalXYZ());
00547 vindex++;
00548
00549 cp= (char *)&(vertexarray[(indexarray[vindex])].getRGBA());
00550 glColor3ub(cp[0], cp[1], cp[2]);
00551 glNormal3sv(vertexarray[(indexarray[vindex])].getNormal());
00552 glTexCoord2fv(vertexarray[(indexarray[vindex])].getUV1());
00553 glVertex3fv(vertexarray[(indexarray[vindex])].getLocalXYZ());
00554 vindex++;
00555
00556 cp= (char *)&(vertexarray[(indexarray[vindex])].getRGBA());
00557 glColor3ub(cp[0], cp[1], cp[2]);
00558 glNormal3sv(vertexarray[(indexarray[vindex])].getNormal());
00559 glTexCoord2fv(vertexarray[(indexarray[vindex])].getUV1());
00560 glVertex3fv(vertexarray[(indexarray[vindex])].getLocalXYZ());
00561 vindex++;
00562
00563 }
00564 glEnd();
00565 break;
00566 }
00567 default:
00568 {
00569 }
00570
00571 }
00572 #endif
00573
00574 }
00575 }
00576
00577
00578 }
00579
00580 void RAS_OpenGLRasterizer::SetProjectionMatrix(CMatrix4x4 &mat)
00581 {
00582 glMatrixMode(GL_PROJECTION);
00583 double* matrix = &mat(0,0);
00584 glLoadMatrixd(matrix);
00585 }
00586
00587
00588 void RAS_OpenGLRasterizer::SetViewMatrix(CMatrix4x4 &mat,const MT_Vector3& campos)
00589 {
00590 glMatrixMode(GL_MODELVIEW);
00591 m_viewmatrix = CMatrix4x4(&mat(0,0));
00592 glLoadMatrixd(&m_viewmatrix(0,0));
00593 m_campos = campos;
00594 }
00595
00596 const MT_Point3& RAS_OpenGLRasterizer::GetCameraPosition()
00597 {
00598 return m_campos;
00599 }
00600 void RAS_OpenGLRasterizer::LoadViewMatrix()
00601 {
00602 glLoadMatrixd(&m_viewmatrix(0,0));
00603 }
00604
00605 void RAS_OpenGLRasterizer::EnableTextures(bool enable)
00606 {
00607 if (enable)
00608 glEnableClientState(GL_TEXTURE_COORD_ARRAY);
00609 else
00610 glDisableClientState(GL_TEXTURE_COORD_ARRAY);
00611 }
00612
00613 void RAS_OpenGLRasterizer::SetCullFace(bool enable)
00614 {
00615 if (enable)
00616 glEnable(GL_CULL_FACE);
00617 else
00618 glDisable(GL_CULL_FACE);
00619 }
00620