00001
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025 #include "stdopengl.h"
00026
00027 #include "driver_opengl.h"
00028 #include "nel/3d/index_buffer.h"
00029 #include "driver_opengl_vertex_buffer_hard.h"
00030
00031
00032
00033
00034 using namespace std;
00035 using namespace NLMISC;
00036
00037
00038
00039
00040
00041
00042 #define NL3D_DRV_SOFTSKIN_VNEEDCOMPUTE 3
00043 #define NL3D_DRV_SOFTSKIN_VMUSTCOMPUTE 1
00044 #define NL3D_DRV_SOFTSKIN_VCOMPUTED 0
00045
00046
00047
00048
00049
00050
00051 #define NL3D_DRV_VERTEXARRAY_MINIMUM_SIZE (512*1024)
00052
00053
00054
00055
00056
00057 namespace NL3D
00058 {
00059
00060
00061
00062
00063
00064
00065
00066
00067 CVBDrvInfosGL::CVBDrvInfosGL(CDriverGL *drv, ItVBDrvInfoPtrList it, CVertexBuffer *vb) : IVBDrvInfos(drv, it, vb)
00068 {
00069 H_AUTO_OGL(CVBDrvInfosGL_CVBDrvInfosGL)
00070 _DriverGL = drv;
00071 _VBHard = NULL;
00072 _SystemMemory = NULL;
00073 }
00074
00075
00076
00077 CVBDrvInfosGL::~CVBDrvInfosGL()
00078 {
00079 H_AUTO_OGL(CVBDrvInfosGL_CVBDrvInfosGLDtor)
00080
00081 if (VertexBufferPtr)
00082 {
00083 VertexBufferPtr->setLocation(CVertexBuffer::NotResident);
00084 VertexBufferPtr = NULL;
00085 }
00086
00087 if (_VBHard)
00088 {
00089 _VBHard->disable();
00090 _DriverGL->_VertexBufferHardSet.erase(_VBHard);
00091 }
00092 if (_SystemMemory)
00093 {
00094 delete [] _SystemMemory;
00095 }
00096 _SystemMemory = NULL;
00097 _VBHard = NULL;
00098 }
00099
00100
00101 uint8 *CVBDrvInfosGL::lock (uint , uint , bool )
00102 {
00103 H_AUTO_OGL(CVBDrvInfosGL_lock)
00104 if (_VBHard)
00105 {
00106 return (uint8*)_VBHard->lock ();
00107 }
00108 else
00109 {
00110
00111 nlassert (_SystemMemory);
00112 return _SystemMemory;
00113 }
00114 }
00115
00116
00117 void CVBDrvInfosGL::unlock (uint first, uint last)
00118 {
00119 H_AUTO_OGL(CVBDrvInfosGL_unlock)
00120 if (_VBHard)
00121 {
00122 _VBHard->unlock(first, last);
00123 }
00124 else
00125 {
00126
00127 nlassert (_SystemMemory);
00128 }
00129 }
00130
00131
00132 bool CDriverGL::setupVertexBuffer(CVertexBuffer& VB)
00133 {
00134 H_AUTO_OGL(CDriverGL_setupVertexBuffer)
00135
00136
00137 const bool touched = (VB.getTouchFlags() & (CVertexBuffer::TouchedReserve|CVertexBuffer::TouchedVertexFormat)) != 0;
00138 if( touched || (VB.DrvInfos == NULL))
00139 {
00140
00141 if(VB.DrvInfos)
00142 delete VB.DrvInfos;
00143 VB.DrvInfos = NULL;
00144
00145
00146 if(VB.getNumVertices())
00147 {
00148
00149
00150
00151 ItVBDrvInfoPtrList it= _VBDrvInfos.insert(_VBDrvInfos.end(), NULL);
00152
00153 CVBDrvInfosGL *info = new CVBDrvInfosGL(this, it, &VB);
00154 *it= VB.DrvInfos = info;
00155
00156
00157 CVertexBuffer::TPreferredMemory preferred = VB.getPreferredMemory ();
00158 if ((preferred == CVertexBuffer::RAMVolatile) || (preferred == CVertexBuffer::AGPVolatile))
00159 preferred = CVertexBuffer::RAMPreferred;
00160 const uint size = VB.capacity()*VB.getVertexSize();
00161 uint preferredMemory = _Extensions.DisableHardwareVertexArrayAGP ? CVertexBuffer::RAMPreferred : preferred;
00162 while (preferredMemory != CVertexBuffer::RAMPreferred)
00163 {
00164
00165 info->_VBHard = createVertexBufferHard(size, VB.capacity(), (CVertexBuffer::TPreferredMemory)preferredMemory, &VB);
00166 if (info->_VBHard)
00167 break;
00168 preferredMemory--;
00169 }
00170
00171
00172 if (info->_VBHard == NULL)
00173 {
00174 nlassert (info->_SystemMemory == NULL);
00175 info->_SystemMemory = new uint8[size];
00176 }
00177
00178
00179 VB.setLocation ((CVertexBuffer::TLocation)preferredMemory);
00180 }
00181 }
00182
00183 return true;
00184 }
00185
00186
00187
00188 bool CDriverGL::activeVertexBuffer(CVertexBuffer& VB)
00189 {
00190 H_AUTO_OGL(CDriverGL_activeVertexBuffer)
00191
00192 uint32 flags;
00193
00194
00195 _LastVertexSetupIsLightMap= false;
00196
00197
00198 if (!setupVertexBuffer(VB))
00199 return false;
00200
00201 if (VB.getNumVertices()==0)
00202 return true;
00203
00204
00205 VB.fillBuffer ();
00206
00207
00208 flags=VB.getVertexFormat();
00209
00210
00211
00212
00213
00214 CVertexBufferInfo::TVBMode lastVBMode = _LastVB.VBMode;
00215 CVBDrvInfosGL *info= safe_cast<CVBDrvInfosGL*>((IVBDrvInfos*)VB.DrvInfos);
00216 if (!info->_VBHard || (info->_VBHard && !info->_VBHard->isInvalid()))
00217 {
00218 _LastVB.setupVertexBuffer(VB);
00219 if (lastVBMode == CVertexBufferInfo::HwARB && _LastVB.VBMode != CVertexBufferInfo::HwARB)
00220 {
00221 _DriverGLStates.bindARBVertexBuffer(0);
00222 }
00223 }
00224 if (info->_VBHard == NULL)
00225 {
00226
00227 fenceOnCurVBHardIfNeeded(NULL);
00228
00229
00230 if(_CurrentVertexBufferHard)
00231 _CurrentVertexBufferHard->disable();
00232 }
00233 else
00234 {
00235
00236
00237
00238
00239 fenceOnCurVBHardIfNeeded(info->_VBHard);
00240
00241
00242 info->_VBHard->enable();
00243 }
00244 if (!info->_VBHard || (info->_VBHard && !info->_VBHard->isInvalid()))
00245 {
00246 setupGlArrays(_LastVB);
00247 }
00248 return true;
00249 }
00250
00251
00252 bool CDriverGL::activeIndexBuffer(CIndexBuffer& IB)
00253 {
00254 H_AUTO_OGL(CDriverGL_activeIndexBuffer)
00255 _LastIB.setupIndexBuffer(IB);
00256 return true;
00257 }
00258
00259
00260
00261 bool CDriverGL::renderLines(CMaterial& mat, uint32 firstIndex, uint32 nlines)
00262 {
00263 H_AUTO_OGL(CDriverGL_renderLines)
00264
00265 refreshRenderSetup();
00266
00267
00268 if ( !setupMaterial(mat) || _LastIB._Values == NULL )
00269 return false;
00270
00271 if (_CurrentVertexBufferHard && _CurrentVertexBufferHard->isInvalid()) return true;
00272
00273
00274
00275 uint nPass;
00276 nPass= beginMultiPass();
00277
00278 for(uint pass=0;pass<nPass; pass++)
00279 {
00280
00281 setupPass(pass);
00282
00283 if(nlines)
00284 {
00285 if (_LastIB._Format == CIndexBuffer::Indices16)
00286 {
00287 glDrawElements(GL_LINES,2*nlines,GL_UNSIGNED_SHORT,((uint16 *) _LastIB._Values)+firstIndex);
00288 }
00289 else
00290 {
00291 nlassert(_LastIB._Format == CIndexBuffer::Indices32);
00292 glDrawElements(GL_LINES,2*nlines,GL_UNSIGNED_INT,((uint32 *) _LastIB._Values)+firstIndex);
00293 }
00294 }
00295 }
00296
00297 endMultiPass();
00298
00299
00300
00301 _PrimitiveProfileIn.NLines+= nlines;
00302 _PrimitiveProfileOut.NLines+= nlines;
00303
00304
00305 if(_CurrentVertexBufferHard)
00306 _CurrentVertexBufferHard->GPURenderingAfterFence= true;
00307 return true;
00308 }
00309
00310
00311
00312 bool CDriverGL::renderTriangles(CMaterial& mat, uint32 firstIndex, uint32 ntris)
00313 {
00314 H_AUTO_OGL(CDriverGL_renderTriangles)
00315
00316 refreshRenderSetup();
00317
00318 if ( !setupMaterial(mat) || _LastIB._Values == NULL )
00319 return false;
00320
00321 if (_CurrentVertexBufferHard && _CurrentVertexBufferHard->isInvalid()) return true;
00322
00323
00324
00325
00326 uint nPass;
00327
00328 nPass= beginMultiPass();
00329
00330
00331 for(uint pass=0;pass<nPass; pass++)
00332 {
00333
00334 setupPass(pass);
00335
00336
00337 if(ntris)
00338 {
00339 if (_LastIB._Format == CIndexBuffer::Indices16)
00340 {
00341 glDrawElements(GL_TRIANGLES,3*ntris,GL_UNSIGNED_SHORT, ((uint16 *) _LastIB._Values)+firstIndex);
00342 }
00343 else
00344 {
00345 nlassert(_LastIB._Format == CIndexBuffer::Indices32);
00346 glDrawElements(GL_TRIANGLES,3*ntris,GL_UNSIGNED_INT, ((uint32 *) _LastIB._Values)+firstIndex);
00347 }
00348 }
00349 }
00350
00351 endMultiPass();
00352
00353
00354
00355 _PrimitiveProfileIn.NTriangles+= ntris;
00356 _PrimitiveProfileOut.NTriangles+= ntris * nPass;
00357
00358
00359 if(_CurrentVertexBufferHard)
00360 _CurrentVertexBufferHard->GPURenderingAfterFence= true;
00361 return true;
00362 }
00363
00364
00365
00366 bool CDriverGL::renderSimpleTriangles(uint32 firstTri, uint32 ntris)
00367 {
00368 H_AUTO_OGL(CDriverGL_renderSimpleTriangles)
00369 nlassert(ntris>0);
00370
00371
00372 refreshRenderSetup();
00373
00374
00375 if (_CurrentVertexBufferHard && _CurrentVertexBufferHard->isInvalid()) return true;
00376
00377
00378
00379
00380
00381
00382
00383 if (_LastIB._Format == CIndexBuffer::Indices16)
00384 {
00385 glDrawElements(GL_TRIANGLES,3*ntris,GL_UNSIGNED_SHORT, ((uint16 *) _LastIB._Values)+firstTri);
00386 }
00387 else
00388 {
00389 nlassert(_LastIB._Format == CIndexBuffer::Indices32);
00390 glDrawElements(GL_TRIANGLES,3*ntris,GL_UNSIGNED_INT, ((uint32 *) _LastIB._Values)+firstTri);
00391 }
00392
00393
00394 _PrimitiveProfileIn.NTriangles+= ntris;
00395 _PrimitiveProfileOut.NTriangles+= ntris;
00396
00397
00398 if(_CurrentVertexBufferHard)
00399 _CurrentVertexBufferHard->GPURenderingAfterFence= true;
00400 return true;
00401 }
00402
00403
00404
00405 bool CDriverGL::renderRawPoints(CMaterial& mat, uint32 startIndex, uint32 numPoints)
00406 {
00407 H_AUTO_OGL(CDriverGL_renderRawPoints)
00408
00409 refreshRenderSetup();
00410
00411
00412 if ( !setupMaterial(mat) )
00413 return false;
00414
00415 if (_CurrentVertexBufferHard && _CurrentVertexBufferHard->isInvalid()) return true;
00416
00417
00418
00419 uint nPass;
00420 nPass= beginMultiPass();
00421
00422 for(uint pass=0;pass<nPass; pass++)
00423 {
00424
00425 setupPass(pass);
00426
00427 if(numPoints)
00428 glDrawArrays(GL_POINTS, startIndex, numPoints);
00429 }
00430
00431 endMultiPass();
00432
00433
00434
00435 _PrimitiveProfileIn.NPoints+= numPoints;
00436 _PrimitiveProfileOut.NPoints+= numPoints * nPass;
00437
00438
00439 if(_CurrentVertexBufferHard)
00440 _CurrentVertexBufferHard->GPURenderingAfterFence= true;
00441 return true;
00442 }
00443
00444
00445
00446 bool CDriverGL::renderRawLines(CMaterial& mat, uint32 startIndex, uint32 numLines)
00447 {
00448 H_AUTO_OGL(CDriverGL_renderRawLines)
00449
00450 refreshRenderSetup();
00451
00452
00453 if ( !setupMaterial(mat) )
00454 return false;
00455
00456 if (_CurrentVertexBufferHard && _CurrentVertexBufferHard->isInvalid()) return true;
00457
00458
00459
00460 uint nPass;
00461 nPass= beginMultiPass();
00462
00463 for(uint pass=0;pass<nPass; pass++)
00464 {
00465
00466 setupPass(pass);
00467
00468 if(numLines)
00469 glDrawArrays(GL_LINES, startIndex << 1, numLines << 1);
00470 }
00471
00472 endMultiPass();
00473
00474
00475
00476 _PrimitiveProfileIn.NLines += numLines ;
00477 _PrimitiveProfileOut.NLines += numLines * nPass;
00478
00479
00480 if(_CurrentVertexBufferHard)
00481 _CurrentVertexBufferHard->GPURenderingAfterFence= true;
00482 return true;
00483 }
00484
00485
00486
00487 bool CDriverGL::renderRawTriangles(CMaterial& mat, uint32 startIndex, uint32 numTris)
00488 {
00489 H_AUTO_OGL(CDriverGL_renderRawTriangles)
00490
00491 refreshRenderSetup();
00492
00493
00494 if ( !setupMaterial(mat) )
00495 return false;
00496
00497 if (_CurrentVertexBufferHard && _CurrentVertexBufferHard->isInvalid()) return true;
00498
00499
00500
00501 uint nPass;
00502 nPass= beginMultiPass();
00503
00504 for(uint pass=0;pass<nPass; pass++)
00505 {
00506
00507 setupPass(pass);
00508
00509 if(numTris)
00510 {
00511 glDrawArrays(GL_TRIANGLES, startIndex*3, numTris*3);
00512 }
00513 }
00514
00515 endMultiPass();
00516
00517
00518
00519 _PrimitiveProfileIn.NTriangles += numTris ;
00520 _PrimitiveProfileOut.NTriangles += numTris * nPass;
00521
00522
00523 if(_CurrentVertexBufferHard)
00524 _CurrentVertexBufferHard->GPURenderingAfterFence= true;
00525 return true;
00526 }
00527
00528
00529
00530 bool CDriverGL::renderRawQuads(CMaterial& mat, uint32 startIndex, uint32 numQuads)
00531 {
00532 H_AUTO_OGL(CDriverGL_renderRawQuads)
00533 if (!numQuads) return true;
00534
00535 refreshRenderSetup();
00536
00537
00538 if ( !setupMaterial(mat) )
00539 return false;
00540
00541 if (_CurrentVertexBufferHard && _CurrentVertexBufferHard->isInvalid()) return true;
00542
00543 const uint32 QUAD_BATCH_SIZE = 2048;
00544 static GLshort defaultIndices[QUAD_BATCH_SIZE * 6];
00545 static bool init = false;
00546 if (!init)
00547 {
00548
00549 for(uint k = 0; k < QUAD_BATCH_SIZE; ++k)
00550 {
00551
00552 defaultIndices[k * 6] = (GLshort) (k * 4);
00553 defaultIndices[k * 6 + 1] = (GLshort) (k * 4 + 1);
00554 defaultIndices[k * 6 + 2] = (GLshort) (k * 4 + 2);
00555
00556 defaultIndices[k * 6 + 3] = (GLshort) (k * 4);
00557 defaultIndices[k * 6 + 4] = (GLshort) (k * 4 + 2);
00558 defaultIndices[k * 6 + 5] = (GLshort) (k * 4 + 3);
00559
00560 }
00561 init = true;
00562 }
00563
00564
00565
00566
00567 uint nPass;
00568 nPass= beginMultiPass();
00569
00570 for(uint pass=0;pass<nPass; pass++)
00571 {
00572
00573 setupPass(pass);
00574
00575 uint32 currIndex = startIndex;
00576 uint32 numLeftQuads = numQuads;
00577
00578
00579 if (startIndex < QUAD_BATCH_SIZE)
00580 {
00581
00582 uint numQuadsToDraw = std::min(QUAD_BATCH_SIZE - startIndex, numQuads);
00583 glDrawElements(GL_TRIANGLES, 6 * numQuadsToDraw, GL_UNSIGNED_SHORT, defaultIndices + 6 * startIndex);
00584 numLeftQuads -= numQuadsToDraw;
00585 currIndex += 4 * numQuadsToDraw;
00586 }
00587
00588
00589 while (numLeftQuads)
00590 {
00591
00592 uint32 numQuadsToDraw = std::min(numLeftQuads, QUAD_BATCH_SIZE);
00593
00594 if (4 * numQuadsToDraw + currIndex <= (1 << 16))
00595 {
00596
00597 GLshort indices[QUAD_BATCH_SIZE * 6];
00598 GLshort *curr = indices;
00599 GLshort *end = indices + 6 * numQuadsToDraw;
00600 uint16 vertexIndex = (uint16) currIndex;
00601 do
00602 {
00603 *curr++ = vertexIndex;
00604 *curr++ = vertexIndex + 1;
00605 *curr++ = vertexIndex + 2;
00606 *curr++ = vertexIndex;
00607 *curr++ = vertexIndex + 2;
00608 *curr++ = vertexIndex + 3;
00609 vertexIndex += 4;
00610 }
00611 while(curr != end);
00612 glDrawElements(GL_TRIANGLES, 6 * numQuadsToDraw, GL_UNSIGNED_SHORT, indices);
00613 }
00614 else
00615 {
00616
00617 GLint indices[QUAD_BATCH_SIZE];
00618 GLint *curr = indices;
00619 GLint *end = indices + 6 * numQuadsToDraw;
00620 uint32 vertexIndex = currIndex;
00621 do
00622 {
00623 *curr++ = vertexIndex;
00624 *curr++ = vertexIndex + 1;
00625 *curr++ = vertexIndex + 2;
00626 *curr++ = vertexIndex;
00627 *curr++ = vertexIndex + 2;
00628 *curr++ = vertexIndex + 3;
00629 vertexIndex += 4;
00630 }
00631 while(curr != end);
00632 glDrawElements(GL_TRIANGLES, 6 * numQuadsToDraw, GL_UNSIGNED_INT, indices);
00633 }
00634 numLeftQuads -= numQuadsToDraw;
00635 currIndex += 4 * numQuadsToDraw;
00636 }
00637 }
00638
00639 endMultiPass();
00640
00641
00642
00643 _PrimitiveProfileIn.NQuads += numQuads ;
00644 _PrimitiveProfileOut.NQuads += numQuads * nPass;
00645
00646
00647 if(_CurrentVertexBufferHard)
00648 _CurrentVertexBufferHard->GPURenderingAfterFence= true;
00649 return true;
00650 }
00651
00652
00653
00654 void CDriverGL::setupUVPtr(uint stage, CVertexBufferInfo &VB, uint uvId)
00655 {
00656 H_AUTO_OGL(CDriverGL_setupUVPtr)
00657
00658 nlassert(!_LastSetupGLArrayVertexProgram);
00659
00660 _DriverGLStates.clientActiveTextureARB(stage);
00661 if (VB.VertexFormat & (CVertexBuffer::TexCoord0Flag<<uvId))
00662 {
00663
00664 CVertexBuffer::TType uvType = VB.Type[CVertexBuffer::TexCoord0+uvId];
00665 if (uvType == CVertexBuffer::Float2 ||
00666 uvType == CVertexBuffer::Float3)
00667 {
00668 _DriverGLStates.enableTexCoordArray(true);
00669 uint numTexCoord = (uvType == CVertexBuffer::Float2) ? 2 : 3;
00670
00671 switch(VB.VBMode)
00672 {
00673 case CVertexBufferInfo::HwATI:
00674 nglArrayObjectATI(GL_TEXTURE_COORD_ARRAY, numTexCoord, GL_FLOAT, VB.VertexSize, VB.VertexObjectId,
00675 (ptrdiff_t) VB.ValuePtr[CVertexBuffer::TexCoord0+uvId]);
00676 break;
00677 case CVertexBufferInfo::HwARB:
00678 _DriverGLStates.bindARBVertexBuffer(VB.VertexObjectId);
00679
00680 glTexCoordPointer(numTexCoord,GL_FLOAT,VB.VertexSize, VB.ValuePtr[CVertexBuffer::TexCoord0+uvId]);
00681 break;
00682 case CVertexBufferInfo::SysMem:
00683 case CVertexBufferInfo::HwNVIDIA:
00684 glTexCoordPointer(numTexCoord,GL_FLOAT,VB.VertexSize, VB.ValuePtr[CVertexBuffer::TexCoord0+uvId]);
00685 break;
00686 default:
00687 break;
00688 }
00689 }
00690 else
00691 {
00692 _DriverGLStates.enableTexCoordArray(false);
00693 }
00694 }
00695 else
00696 _DriverGLStates.enableTexCoordArray(false);
00697 }
00698
00699
00700
00701 void CDriverGL::mapTextureStageToUV(uint stage, uint uv)
00702 {
00703 H_AUTO_OGL(CDriverGL_mapTextureStageToUV)
00704
00705 setupUVPtr(stage, _LastVB, uv);
00706 }
00707
00708
00709
00710
00711
00712
00713
00714
00715
00716
00717
00718 bool CDriverGL::supportVertexBufferHard() const
00719 {
00720 H_AUTO_OGL(CDriverGL_supportVertexBufferHard)
00721 return _SupportVBHard;
00722 }
00723
00724
00725 bool CDriverGL::supportVolatileVertexBuffer() const
00726 {
00727 H_AUTO_OGL(CDriverGL_supportVolatileVertexBuffer)
00728 return false;
00729 }
00730
00731
00732
00733
00734 bool CDriverGL::slowUnlockVertexBufferHard() const
00735 {
00736 H_AUTO_OGL(CDriverGL_slowUnlockVertexBufferHard)
00737 return _SlowUnlockVBHard;
00738 }
00739
00740
00741
00742 uint CDriverGL::getMaxVerticesByVertexBufferHard() const
00743 {
00744 H_AUTO_OGL(CDriverGL_getMaxVerticesByVertexBufferHard)
00745 return _MaxVerticesByVBHard;
00746 }
00747
00748
00749
00750 IVertexBufferHardGL *CDriverGL::createVertexBufferHard(uint size, uint numVertices, CVertexBuffer::TPreferredMemory vbType, CVertexBuffer *vb)
00751 {
00752 H_AUTO_OGL(CDriverGL_createVertexBufferHard)
00753
00754 IVertexArrayRange *vertexArrayRange= NULL;
00755 switch(vbType)
00756 {
00757 case CVertexBuffer::AGPPreferred:
00758 vertexArrayRange= _AGPVertexArrayRange;
00759 break;
00760 case CVertexBuffer::StaticPreferred:
00761 if (getStaticMemoryToVRAM())
00762 vertexArrayRange= _VRAMVertexArrayRange;
00763 else
00764 vertexArrayRange= _AGPVertexArrayRange;
00765 break;
00766 default:
00767 break;
00768 };
00769
00770
00771 if( !vertexArrayRange )
00772 return NULL;
00773 else
00774 {
00775
00776 if(numVertices > _MaxVerticesByVBHard)
00777 return NULL;
00778
00779
00780 IVertexBufferHardGL *vbHard;
00781
00782 vbHard= vertexArrayRange->createVBHardGL(size, vb);
00783
00784 if(!vbHard)
00785 {
00786 return NULL;
00787 }
00788 else
00789 {
00790
00791 return _VertexBufferHardSet.insert(vbHard);
00792 }
00793 }
00794 }
00795
00796
00797
00798 const uint CDriverGL::NumCoordinatesType[CVertexBuffer::NumType]=
00799 {
00800 1,
00801 1,
00802 1,
00803 2,
00804 2,
00805 2,
00806 3,
00807 3,
00808 3,
00809 4,
00810 4,
00811 4,
00812 4
00813 };
00814
00815
00816
00817 const uint CDriverGL::GLType[CVertexBuffer::NumType]=
00818 {
00819 GL_DOUBLE,
00820 GL_FLOAT,
00821 GL_SHORT,
00822 GL_DOUBLE,
00823 GL_FLOAT,
00824 GL_SHORT,
00825 GL_DOUBLE,
00826 GL_FLOAT,
00827 GL_SHORT,
00828 GL_DOUBLE,
00829 GL_FLOAT,
00830 GL_SHORT,
00831 GL_UNSIGNED_BYTE
00832 };
00833
00834
00835 const bool CDriverGL::GLTypeIsIntegral[CVertexBuffer::NumType] =
00836 {
00837 false,
00838 false,
00839 true,
00840 false,
00841 false,
00842 true,
00843 false,
00844 false,
00845 true,
00846 false,
00847 false,
00848 true,
00849 true
00850 };
00851
00852
00853
00854
00855 const uint CDriverGL::GLVertexAttribIndex[CVertexBuffer::NumValue]=
00856 {
00857 0,
00858 2,
00859 8,
00860 9,
00861 10,
00862 11,
00863 12,
00864 13,
00865 14,
00866 15,
00867 3,
00868 4,
00869 1,
00870 6,
00871 5,
00872 7,
00873 };
00874
00875
00876
00877
00878 void CDriverGL::setupGlArraysStd(CVertexBufferInfo &vb)
00879 {
00880 H_AUTO_OGL(CDriverGL_setupGlArraysStd)
00881 uint32 flags= vb.VertexFormat;
00882
00883 if (vb.VBMode == CVertexBufferInfo::HwARB)
00884 {
00885 _DriverGLStates.bindARBVertexBuffer(vb.VertexObjectId);
00886 }
00887
00888 switch(vb.VBMode)
00889 {
00890 case CVertexBufferInfo::SysMem:
00891 case CVertexBufferInfo::HwNVIDIA:
00892 case CVertexBufferInfo::HwARB:
00893 {
00894
00895
00896
00897 uint numVertexCoord = CVertexBuffer::NumComponentsType[vb.Type[CVertexBuffer::Position]];
00898 nlassert (numVertexCoord >= 2);
00899 _DriverGLStates.enableVertexArray(true);
00900 glVertexPointer(numVertexCoord, GL_FLOAT, vb.VertexSize, vb.ValuePtr[CVertexBuffer::Position]);
00901
00902
00903
00904 if (flags & CVertexBuffer::NormalFlag)
00905 {
00906
00907 nlassert (vb.Type[CVertexBuffer::Normal]==CVertexBuffer::Float3);
00908
00909 _DriverGLStates.enableNormalArray(true);
00910 glNormalPointer(GL_FLOAT, vb.VertexSize, vb.ValuePtr[CVertexBuffer::Normal]);
00911 }
00912 else
00913 {
00914 _DriverGLStates.enableNormalArray(false);
00915 }
00916
00917
00918
00919 if (flags & CVertexBuffer::PrimaryColorFlag)
00920 {
00921
00922 nlassert (vb.Type[CVertexBuffer::PrimaryColor]==CVertexBuffer::UChar4);
00923 _DriverGLStates.enableColorArray(true);
00924
00925 glColorPointer(4,GL_UNSIGNED_BYTE, vb.VertexSize, vb.ValuePtr[CVertexBuffer::PrimaryColor]);
00926 }
00927 else
00928 _DriverGLStates.enableColorArray(false);
00929 }
00930 break;
00931 case CVertexBufferInfo::HwATI:
00932 {
00933
00934
00935 uint numVertexCoord = CVertexBuffer::NumComponentsType[vb.Type[CVertexBuffer::Position]];
00936 nlassert (numVertexCoord >= 2);
00937
00938 _DriverGLStates.enableVertexArray(true);
00939 nglArrayObjectATI(GL_VERTEX_ARRAY, numVertexCoord, GL_FLOAT, vb.VertexSize, vb.VertexObjectId, (ptrdiff_t) vb.ValuePtr[CVertexBuffer::Position]);
00940
00941
00942
00943 if (flags & CVertexBuffer::NormalFlag)
00944 {
00945
00946 nlassert (vb.Type[CVertexBuffer::Normal]==CVertexBuffer::Float3);
00947 _DriverGLStates.enableNormalArray(true);
00948 nglArrayObjectATI(GL_NORMAL_ARRAY, 3, GL_FLOAT, vb.VertexSize, vb.VertexObjectId, (ptrdiff_t) vb.ValuePtr[CVertexBuffer::Normal]);
00949 }
00950 else
00951 {
00952 _DriverGLStates.enableNormalArray(false);
00953 }
00954
00955
00956
00957
00958
00959 if (flags & CVertexBuffer::PrimaryColorFlag)
00960 {
00961
00962 nlassert (vb.Type[CVertexBuffer::PrimaryColor]==CVertexBuffer::UChar4);
00963
00964 _DriverGLStates.enableColorArray(true);
00965 nglArrayObjectATI(GL_COLOR_ARRAY, 4, GL_UNSIGNED_BYTE, vb.VertexSize, vb.VertexObjectId, (ptrdiff_t) vb.ValuePtr[CVertexBuffer::PrimaryColor]);
00966 }
00967 else
00968 _DriverGLStates.enableColorArray(false);
00969 }
00970 break;
00971 default:
00972 nlassert(0);
00973 break;
00974 }
00975
00976
00977
00978
00979 for(uint i=0; i<inlGetNumTextStages(); i++)
00980 {
00981
00982 setupUVPtr(i, vb, vb.UVRouting[i]);
00983 }
00984
00985
00986 }
00987
00988
00989
00990 void CDriverGL::toggleGlArraysForNVVertexProgram()
00991 {
00992 H_AUTO_OGL(CDriverGL_toggleGlArraysForNVVertexProgram)
00993
00994
00995
00996
00997 if( _LastSetupGLArrayVertexProgram && !isVertexProgramEnabled () )
00998 {
00999
01000
01001 for (uint value=0; value<CVertexBuffer::NumValue; value++)
01002 {
01003
01004 uint glIndex=GLVertexAttribIndex[value];
01005 _DriverGLStates.enableVertexAttribArray(glIndex, false);
01006 }
01007 _DriverGLStates.enableColorArray(false);
01008 _DriverGLStates.enableSecondaryColorArray(false);
01009
01010
01011 _LastSetupGLArrayVertexProgram= false;
01012 }
01013
01014
01015 if( !_LastSetupGLArrayVertexProgram && isVertexProgramEnabled () )
01016 {
01017
01018 _DriverGLStates.enableVertexArray(false);
01019 _DriverGLStates.enableNormalArray(false);
01020 _DriverGLStates.enableColorArray(false);
01021 for(uint i=0; i<inlGetNumTextStages(); i++)
01022 {
01023 _DriverGLStates.clientActiveTextureARB(i);
01024 _DriverGLStates.enableTexCoordArray(false);
01025 }
01026
01027
01028
01029 _LastSetupGLArrayVertexProgram= true;
01030 }
01031 }
01032
01033
01034 void CDriverGL::toggleGlArraysForARBVertexProgram()
01035 {
01036 H_AUTO_OGL(CDriverGL_toggleGlArraysForARBVertexProgram)
01037
01038
01039
01040
01041 if( _LastSetupGLArrayVertexProgram && !isVertexProgramEnabled () )
01042 {
01043 if (_Extensions.ATITextureEnvCombine3)
01044 {
01045
01046
01047 ITexture *oldTex[IDRV_MAT_MAXTEXTURES];
01048 for(uint stage=0 ; stage < inlGetNumTextStages() ; stage++)
01049 {
01050 oldTex[stage] = _CurrentTexture[stage];
01051
01052 activateTexture(stage, NULL);
01053 }
01054 glBegin(GL_QUADS);
01055 glVertex4f(0.f, 0.f, 0.f, 1.f);
01056 glVertex4f(0.f, 0.f, 0.f, 1.f);
01057 glVertex4f(0.f, 0.f, 0.f, 1.f);
01058 glVertex4f(0.f, 0.f, 0.f, 1.f);
01059 glEnd();
01060 for(uint stage=0 ; stage<inlGetNumTextStages() ; stage++)
01061 {
01062
01063 activateTexture(stage, oldTex[stage]);
01064 }
01065 }
01066
01067
01068 for (uint value=0; value<CVertexBuffer::NumValue; value++)
01069 {
01070
01071 uint glIndex=GLVertexAttribIndex[value];
01072 _DriverGLStates.enableVertexAttribArrayARB(glIndex, false);
01073 }
01074
01075 _LastSetupGLArrayVertexProgram= false;
01076 }
01077
01078
01079 if( !_LastSetupGLArrayVertexProgram && isVertexProgramEnabled () )
01080 {
01081
01082 _DriverGLStates.enableVertexArray(false);
01083 _DriverGLStates.enableNormalArray(false);
01084 _DriverGLStates.enableColorArray(false);
01085 _DriverGLStates.enableSecondaryColorArray(false);
01086 for(uint i=0; i<inlGetNumTextStages(); i++)
01087 {
01088 _DriverGLStates.clientActiveTextureARB(i);
01089 _DriverGLStates.enableTexCoordArray(false);
01090 }
01091
01092 _LastSetupGLArrayVertexProgram= true;
01093 }
01094 }
01095
01096
01097
01098
01099 void CDriverGL::toggleGlArraysForEXTVertexShader()
01100 {
01101 H_AUTO_OGL(CDriverGL_toggleGlArraysForEXTVertexShader)
01102
01103
01104
01105
01106
01107 if( _LastSetupGLArrayVertexProgram && !isVertexProgramEnabled () )
01108 {
01109 CVertexProgram *vp = _LastSetuppedVP;
01110 if (vp)
01111 {
01112 CVertexProgamDrvInfosGL *drvInfo = NLMISC::safe_cast<CVertexProgamDrvInfosGL *>((IVertexProgramDrvInfos *) vp->_DrvInfo);
01113 if (drvInfo)
01114 {
01115
01116 for (uint value=0; value<CVertexBuffer::NumValue; value++)
01117 {
01118 _DriverGLStates.enableVertexAttribArrayForEXTVertexShader(value, false, drvInfo->Variants);
01119 }
01120 }
01121 }
01122
01123 _LastSetupGLArrayVertexProgram= false;
01124 }
01125
01126
01127 if( !_LastSetupGLArrayVertexProgram && isVertexProgramEnabled () )
01128 {
01129
01130 _DriverGLStates.enableVertexArray(false);
01131 _DriverGLStates.enableNormalArray(false);
01132 _DriverGLStates.enableColorArray(false);
01133 _DriverGLStates.enableSecondaryColorArray(false);
01134 for(uint i=0; i<inlGetNumTextStages(); i++)
01135 {
01136 _DriverGLStates.clientActiveTextureARB(i);
01137 _DriverGLStates.enableTexCoordArray(false);
01138 }
01139
01140
01141
01142 _LastSetupGLArrayVertexProgram= true;
01143 }
01144 }
01145
01146
01147 void CDriverGL::setupGlArraysForNVVertexProgram(CVertexBufferInfo &vb)
01148 {
01149 H_AUTO_OGL(CDriverGL_setupGlArraysForNVVertexProgram)
01150 uint16 flags= vb.VertexFormat;
01151
01152 if (vb.VBMode == CVertexBufferInfo::HwARB)
01153 _DriverGLStates.bindARBVertexBuffer(vb.VertexObjectId);
01154
01155
01156 for (uint value=0; value<CVertexBuffer::NumValue; value++)
01157 {
01158
01159
01160 uint16 flag=1<<value;
01161
01162
01163 CVertexBuffer::TType type=vb.Type[value];
01164
01165
01166 uint glIndex=GLVertexAttribIndex[value];
01167
01168
01169 if (flags & flag)
01170 {
01171
01172
01173
01174
01175 if( (glIndex==3 || glIndex==4) )
01176 {
01177 if( type == CVertexBuffer::UChar4 )
01178 {
01179
01180 _DriverGLStates.enableVertexAttribArray(glIndex, false);
01181
01182
01183 if(glIndex==3)
01184 {
01185
01186 _DriverGLStates.enableColorArray(true);
01187 glColorPointer(4,GL_UNSIGNED_BYTE, vb.VertexSize, vb.ValuePtr[value]);
01188 }
01189 else
01190 {
01191
01192 _DriverGLStates.enableSecondaryColorArray(true);
01193 nglSecondaryColorPointerEXT(4,GL_UNSIGNED_BYTE, vb.VertexSize, vb.ValuePtr[value]);
01194 }
01195 }
01196 else
01197 {
01198
01199
01200 if(glIndex==3)
01201 _DriverGLStates.enableColorArray(false);
01202 else
01203 _DriverGLStates.enableSecondaryColorArray(false);
01204
01205
01206 _DriverGLStates.enableVertexAttribArray(glIndex, true);
01207 nglVertexAttribPointerNV (glIndex, NumCoordinatesType[type], GLType[type], vb.VertexSize, vb.ValuePtr[value]);
01208 }
01209 }
01210
01211 else
01212 {
01213
01214 _DriverGLStates.enableVertexAttribArray(glIndex, true);
01215 nglVertexAttribPointerNV (glIndex, NumCoordinatesType[type], GLType[type], vb.VertexSize, vb.ValuePtr[value]);
01216 }
01217 }
01218 else
01219 {
01220 _DriverGLStates.enableVertexAttribArray(glIndex, false);
01221
01222
01223
01224 if(glIndex==3)
01225 _DriverGLStates.enableColorArray(false);
01226 else if(glIndex==4)
01227 _DriverGLStates.enableSecondaryColorArray(false);
01228 }
01229 }
01230
01231 if (vb.VBMode == CVertexBufferInfo::HwARB)
01232 _DriverGLStates.bindARBVertexBuffer(0);
01233
01234 }
01235
01236
01237 static const GLboolean ARBVertexProgramMustNormalizeAttrib[] =
01238 {
01239 GL_FALSE,
01240 GL_TRUE,
01241 GL_FALSE,
01242 GL_FALSE,
01243 GL_FALSE,
01244 GL_FALSE,
01245 GL_FALSE,
01246 GL_FALSE,
01247 GL_FALSE,
01248 GL_FALSE,
01249 GL_TRUE,
01250 GL_TRUE,
01251 GL_TRUE,
01252 GL_FALSE,
01253 GL_FALSE,
01254 GL_FALSE,
01255 };
01256
01257
01258 void CDriverGL::setupGlArraysForARBVertexProgram(CVertexBufferInfo &vb)
01259 {
01260 H_AUTO_OGL(CDriverGL_setupGlArraysForARBVertexProgram)
01261
01262 uint32 flags= vb.VertexFormat;
01263
01264 nlctassert(CVertexBuffer::NumValue == sizeof(ARBVertexProgramMustNormalizeAttrib) / sizeof(ARBVertexProgramMustNormalizeAttrib[0]));
01265
01266 if (vb.VBMode == CVertexBufferInfo::HwARB)
01267 {
01268 _DriverGLStates.bindARBVertexBuffer(vb.VertexObjectId);
01269 }
01270
01271
01272 if (vb.VBMode == CVertexBufferInfo::HwATI)
01273 {
01274
01275 for (uint value=0; value<CVertexBuffer::NumValue; value++)
01276 {
01277
01278 uint16 flag=1<<value;
01279
01280
01281 CVertexBuffer::TType type=vb.Type[value];
01282 {
01283
01284 uint glIndex=GLVertexAttribIndex[value];
01285
01286 if (flags & flag)
01287 {
01288 _DriverGLStates.enableVertexAttribArrayARB(glIndex, true);
01289 GLboolean mustNormalize = GL_FALSE;
01290 if (GLTypeIsIntegral[type])
01291 {
01292 mustNormalize = ARBVertexProgramMustNormalizeAttrib[value];
01293 }
01294 nglVertexAttribArrayObjectATI(glIndex, NumCoordinatesType[type], GLType[type], mustNormalize, vb.VertexSize, vb.VertexObjectId, (ptrdiff_t) vb.ValuePtr[value]);
01295 }
01296 else
01297 {
01298 _DriverGLStates.enableVertexAttribArrayARB(glIndex, false);
01299 }
01300 }
01301 }
01302 }
01303 else
01304 {
01305
01306 for (uint value=0; value<CVertexBuffer::NumValue; value++)
01307 {
01308
01309 uint16 flag=1<<value;
01310
01311
01312 CVertexBuffer::TType type=vb.Type[value];
01313 {
01314
01315 uint glIndex=GLVertexAttribIndex[value];
01316
01317 if (flags & flag)
01318 {
01319 _DriverGLStates.enableVertexAttribArrayARB(glIndex, true);
01320 GLboolean mustNormalize = GL_FALSE;
01321 if (GLTypeIsIntegral[type])
01322 {
01323 mustNormalize = ARBVertexProgramMustNormalizeAttrib[value];
01324 }
01325 nglVertexAttribPointerARB(glIndex, NumCoordinatesType[type], GLType[type], mustNormalize, vb.VertexSize, vb.ValuePtr[value]);
01326 }
01327 else
01328 {
01329 _DriverGLStates.enableVertexAttribArrayARB(glIndex, false);
01330 }
01331 }
01332 }
01333 }
01334 }
01335
01336
01337
01338
01339 void CDriverGL::setupGlArraysForEXTVertexShader(CVertexBufferInfo &vb)
01340 {
01341 H_AUTO_OGL(CDriverGL_setupGlArraysForEXTVertexShader)
01342
01343
01344 CVertexProgram *vp = _LastSetuppedVP;
01345 if (!vp) return;
01346 CVertexProgamDrvInfosGL *drvInfo = NLMISC::safe_cast<CVertexProgamDrvInfosGL *>((IVertexProgramDrvInfos *) vp->_DrvInfo);
01347 if (!drvInfo) return;
01348
01349 uint32 flags= vb.VertexFormat;
01350
01351
01352 if (vb.VBMode == CVertexBufferInfo::HwARB)
01353 {
01354 _DriverGLStates.bindARBVertexBuffer(vb.VertexObjectId);
01355 }
01356
01357
01358 for (uint value=0; value<CVertexBuffer::NumValue; value++)
01359 {
01360
01361 uint16 flag=1<<value;
01362
01363
01364 CVertexBuffer::TType type=vb.Type[value];
01365
01366
01367 uint glIndex=GLVertexAttribIndex[value];
01368
01369
01370 if (flags & flag & drvInfo->UsedVertexComponents)
01371 {
01372 _DriverGLStates.enableVertexAttribArrayForEXTVertexShader(glIndex, true, drvInfo->Variants);
01373
01374 if (vb.VBMode == CVertexBufferInfo::HwATI)
01375 {
01376 switch(value)
01377 {
01378 case CVertexBuffer::Position:
01379 {
01380 nlassert(NumCoordinatesType[type] >= 2);
01381 nglArrayObjectATI(GL_VERTEX_ARRAY, NumCoordinatesType[type], GLType[type], vb.VertexSize, vb.VertexObjectId, (ptrdiff_t) vb.ValuePtr[CVertexBuffer::Position]);
01382 }
01383 break;
01384 case CVertexBuffer::Weight:
01385 {
01386 nlassert(NumCoordinatesType[type] == 4);
01387 nglVariantArrayObjectATI(drvInfo->Variants[CDriverGL::EVSSkinWeightVariant], GLType[type], vb.VertexSize, vb.VertexObjectId, (ptrdiff_t) vb.ValuePtr[CVertexBuffer::Weight]);
01388 }
01389 break;
01390 case CVertexBuffer::Normal:
01391 {
01392 nlassert(NumCoordinatesType[type] == 3);
01393 nglArrayObjectATI(GL_NORMAL_ARRAY, 3, GLType[type], vb.VertexSize, vb.VertexObjectId, (ptrdiff_t) vb.ValuePtr[value]);
01394 }
01395 break;
01396 case CVertexBuffer::PrimaryColor:
01397 {
01398 nlassert(NumCoordinatesType[type] >= 3);
01399 nglArrayObjectATI(GL_COLOR_ARRAY, NumCoordinatesType[type], GLType[type], vb.VertexSize, vb.VertexObjectId, (ptrdiff_t) vb.ValuePtr[CVertexBuffer::PrimaryColor]);
01400 }
01401 break;
01402 case CVertexBuffer::SecondaryColor:
01403 {
01404
01405 nlassert(NumCoordinatesType[type] == 4);
01406 nglVariantArrayObjectATI(drvInfo->Variants[CDriverGL::EVSSecondaryColorVariant], GLType[type], vb.VertexSize, vb.VertexObjectId, (ptrdiff_t) vb.ValuePtr[CVertexBuffer::SecondaryColor]);
01407 }
01408 break;
01409 case CVertexBuffer::Fog:
01410 {
01411
01412 nlassert(NumCoordinatesType[type] == 4);
01413 nglVariantArrayObjectATI(drvInfo->Variants[CDriverGL::EVSFogCoordsVariant], GLType[type], vb.VertexSize, vb.VertexObjectId, (ptrdiff_t) vb.ValuePtr[CVertexBuffer::Fog]);
01414 }
01415 break;
01416 case CVertexBuffer::PaletteSkin:
01417 {
01418
01419 nlassert(NumCoordinatesType[type] == 4);
01420 nglVariantArrayObjectATI(drvInfo->Variants[CDriverGL::EVSPaletteSkinVariant], GLType[type], vb.VertexSize, vb.VertexObjectId, (ptrdiff_t) vb.ValuePtr[CVertexBuffer::PaletteSkin]);
01421 }
01422 break;
01423 case CVertexBuffer::Empty:
01424 nlstop
01425 break;
01426 case CVertexBuffer::TexCoord0:
01427 case CVertexBuffer::TexCoord1:
01428 case CVertexBuffer::TexCoord2:
01429 case CVertexBuffer::TexCoord3:
01430 case CVertexBuffer::TexCoord4:
01431 case CVertexBuffer::TexCoord5:
01432 case CVertexBuffer::TexCoord6:
01433 case CVertexBuffer::TexCoord7:
01434 {
01435 _DriverGLStates.clientActiveTextureARB(value - CVertexBuffer::TexCoord0);
01436 nglArrayObjectATI(GL_TEXTURE_COORD_ARRAY, NumCoordinatesType[type], GLType[type], vb.VertexSize, vb.VertexObjectId, (ptrdiff_t) vb.ValuePtr[value]);
01437 }
01438 break;
01439 default:
01440 nlstop;
01441 break;
01442 }
01443 }
01444 else
01445 {
01446 switch(value)
01447 {
01448 case CVertexBuffer::Position:
01449 {
01450 nlassert(NumCoordinatesType[type] >= 2);
01451 glVertexPointer(NumCoordinatesType[type], GLType[type], vb.VertexSize, vb.ValuePtr[value]);
01452 }
01453 break;
01454 case CVertexBuffer::Weight:
01455 {
01456 nlassert(NumCoordinatesType[type] == 4);
01457 nglVariantPointerEXT(drvInfo->Variants[CDriverGL::EVSSkinWeightVariant], GLType[type], vb.VertexSize, vb.ValuePtr[value]);
01458 }
01459 break;
01460 case CVertexBuffer::Normal:
01461 {
01462 nlassert(NumCoordinatesType[type] == 3);
01463 glNormalPointer(GLType[type], vb.VertexSize, vb.ValuePtr[CVertexBuffer::Normal]);
01464 }
01465 break;
01466 case CVertexBuffer::PrimaryColor:
01467 {
01468 nlassert(NumCoordinatesType[type] >= 3);
01469 glColorPointer(NumCoordinatesType[type], GLType[type], vb.VertexSize, vb.ValuePtr[value]);
01470 }
01471 break;
01472 case CVertexBuffer::SecondaryColor:
01473 {
01474
01475 nlassert(NumCoordinatesType[type] == 4);
01476 nglVariantPointerEXT(drvInfo->Variants[CDriverGL::EVSSecondaryColorVariant], GLType[type], vb.VertexSize, vb.ValuePtr[value]);
01477 }
01478 break;
01479 case CVertexBuffer::Fog:
01480 {
01481
01482 nlassert(NumCoordinatesType[type] == 4);
01483 nglVariantPointerEXT(drvInfo->Variants[CDriverGL::EVSFogCoordsVariant], GLType[type], vb.VertexSize, vb.ValuePtr[value]);
01484 }
01485 break;
01486 case CVertexBuffer::PaletteSkin:
01487 {
01488
01489 nlassert(NumCoordinatesType[type] == 4);
01490 nglVariantPointerEXT(drvInfo->Variants[CDriverGL::EVSPaletteSkinVariant], GLType[type], vb.VertexSize, vb.ValuePtr[value]);
01491 }
01492 break;
01493 case CVertexBuffer::Empty:
01494 nlstop
01495 break;
01496 case CVertexBuffer::TexCoord0:
01497 case CVertexBuffer::TexCoord1:
01498 case CVertexBuffer::TexCoord2:
01499 case CVertexBuffer::TexCoord3:
01500 case CVertexBuffer::TexCoord4:
01501 case CVertexBuffer::TexCoord5:
01502 case CVertexBuffer::TexCoord6:
01503 case CVertexBuffer::TexCoord7:
01504 {
01505 _DriverGLStates.clientActiveTextureARB(value - CVertexBuffer::TexCoord0);
01506 nglArrayObjectATI(GL_TEXTURE_COORD_ARRAY, NumCoordinatesType[type], GLType[type], vb.VertexSize, vb.VertexObjectId, (ptrdiff_t) vb.ValuePtr[value]);
01507 }
01508 break;
01509 default:
01510 nlstop;
01511 break;
01512 }
01513 }
01514 }
01515 else
01516 {
01517 _DriverGLStates.enableVertexAttribArrayForEXTVertexShader(glIndex, false, drvInfo->Variants);
01518 }
01519 }
01520 }
01521
01522
01523
01524
01525 void CDriverGL::setupGlArrays(CVertexBufferInfo &vb)
01526 {
01527 H_AUTO_OGL(CDriverGL_setupGlArrays)
01528
01529
01530 if (_Extensions.NVVertexProgram)
01531 {
01532 toggleGlArraysForNVVertexProgram();
01533
01534 if (!isVertexProgramEnabled ())
01535 {
01536 setupGlArraysStd(vb);
01537 }
01538 else
01539 {
01540 setupGlArraysForNVVertexProgram(vb);
01541 }
01542 }
01543 else if (_Extensions.ARBVertexProgram)
01544 {
01545 toggleGlArraysForARBVertexProgram();
01546
01547 if (!isVertexProgramEnabled ())
01548 {
01549 setupGlArraysStd(vb);
01550 }
01551 else
01552 {
01553 setupGlArraysForARBVertexProgram(vb);
01554 }
01555 }
01556 else if (_Extensions.EXTVertexShader)
01557 {
01558 toggleGlArraysForEXTVertexShader();
01559
01560 if (!isVertexProgramEnabled ())
01561 {
01562 setupGlArraysStd(vb);
01563 }
01564 else
01565 {
01566 setupGlArraysForEXTVertexShader(vb);
01567 }
01568 }
01569 else
01570 {
01571
01572 setupGlArraysStd(vb);
01573 }
01574 }
01575
01576
01577
01578 void CVertexBufferInfo::setupVertexBuffer(CVertexBuffer &vb)
01579 {
01580 H_AUTO_OGL(CDriverGL_setupVertexBuffer)
01581 sint i;
01582 VertexFormat= vb.getVertexFormat();
01583 VertexSize= vb.getVertexSize();
01584 NumVertices= vb.getNumVertices();
01585
01586
01587 CVertexBufferReadWrite access;
01588 uint8 *ptr;
01589 CVBDrvInfosGL *info= safe_cast<CVBDrvInfosGL*>((IVBDrvInfos*)vb.DrvInfos);
01590 nlassert (info);
01591 if (info->_VBHard)
01592 {
01593 ptr = (uint8*)info->_VBHard->getPointer();
01594 info->_VBHard->setupVBInfos(*this);
01595 }
01596 else
01597 {
01598 nlassert (info->_SystemMemory);
01599 ptr = info->_SystemMemory;
01600 VBMode = SysMem;
01601 }
01602
01603
01604 for (i=0; i<CVertexBuffer::NumValue; i++)
01605 {
01606
01607 if (VertexFormat&(1<<i))
01608 {
01609
01610 ValuePtr[i]= ptr+vb.getValueOffEx((CVertexBuffer::TValue)i);
01611
01612
01613 Type[i]=vb.getValueType (i);
01614 }
01615 }
01616
01617
01618 const uint8 *uvRouting = vb.getUVRouting();
01619 for (i=0; i<CVertexBuffer::MaxStage; i++)
01620 {
01621 UVRouting[i] = uvRouting[i];
01622 }
01623 }
01624
01625
01626
01627 void CDriverGL::resetVertexArrayRange()
01628 {
01629 H_AUTO_OGL(CDriverGL_resetVertexArrayRange)
01630 if(_CurrentVertexBufferHard)
01631 {
01632
01633 _CurrentVertexBufferHard->lock();
01634 _CurrentVertexBufferHard->unlock();
01635
01636 _CurrentVertexBufferHard->disable();
01637 }
01638
01639 _VertexBufferHardSet.clear();
01640
01641
01642 if(_AGPVertexArrayRange)
01643 _AGPVertexArrayRange->free();
01644 if(_VRAMVertexArrayRange)
01645 _VRAMVertexArrayRange->free();
01646 }
01647
01648
01649
01650 bool CDriverGL::initVertexBufferHard(uint agpMem, uint vramMem)
01651 {
01652 H_AUTO_OGL(CDriverGL_initVertexBufferHard)
01653 if(!supportVertexBufferHard())
01654 return false;
01655
01656
01657 if(!_AGPVertexArrayRange || !_VRAMVertexArrayRange)
01658 return false;
01659
01660
01661 resetVertexArrayRange();
01662 bool ok= true;
01663
01664
01665 if(agpMem>0)
01666 {
01667 agpMem&= ~15;
01668 agpMem= max(agpMem, (uint)NL3D_DRV_VERTEXARRAY_MINIMUM_SIZE);
01669 while(agpMem>= NL3D_DRV_VERTEXARRAY_MINIMUM_SIZE)
01670 {
01671 if(_AGPVertexArrayRange->allocate(agpMem, CVertexBuffer::AGPPreferred))
01672 {
01673 nlinfo("3D: %.u vertices supported", _MaxVerticesByVBHard);
01674 nlinfo("3D: Success to allocate %.1f Mo of AGP VAR Ram", agpMem / 1000000.f);
01675 break;
01676 }
01677 else
01678 {
01679 agpMem/=2;
01680 agpMem &=~15;
01681 }
01682 }
01683
01684 if(agpMem< NL3D_DRV_VERTEXARRAY_MINIMUM_SIZE)
01685 {
01686 nlinfo("3D: %.u vertices supported", _MaxVerticesByVBHard);
01687 nlinfo("3D: Failed to allocate %.1f Mo of AGP VAR Ram", NL3D_DRV_VERTEXARRAY_MINIMUM_SIZE / 1000000.f);
01688 ok= false;
01689 }
01690 }
01691
01692
01693
01694 if(vramMem>0)
01695 {
01696 vramMem&= ~15;
01697 vramMem= max(vramMem, (uint)NL3D_DRV_VERTEXARRAY_MINIMUM_SIZE);
01698 while(vramMem>= NL3D_DRV_VERTEXARRAY_MINIMUM_SIZE)
01699 {
01700 if(_VRAMVertexArrayRange->allocate(vramMem, CVertexBuffer::StaticPreferred))
01701 break;
01702 else
01703 {
01704 vramMem/=2;
01705 vramMem &=~15;
01706 }
01707 }
01708
01709 if(vramMem< NL3D_DRV_VERTEXARRAY_MINIMUM_SIZE)
01710 {
01711 ok= false;
01712 }
01713 }
01714
01715
01716 return ok;
01717 }
01718
01719
01720
01721 uint32 CDriverGL::getAvailableVertexAGPMemory ()
01722 {
01723 H_AUTO_OGL(CDriverGL_getAvailableVertexAGPMemory )
01724 if (_AGPVertexArrayRange)
01725 return _AGPVertexArrayRange->sizeAllocated();
01726 else
01727 return 0;
01728 }
01729
01730
01731
01732 uint32 CDriverGL::getAvailableVertexVRAMMemory ()
01733 {
01734 H_AUTO_OGL(CDriverGL_getAvailableVertexVRAMMemory )
01735 if (_VRAMVertexArrayRange)
01736 return _VRAMVertexArrayRange->sizeAllocated();
01737 else
01738 return 0;
01739 }
01740
01741
01742
01743 void CDriverGL::fenceOnCurVBHardIfNeeded(IVertexBufferHardGL *newVBHard)
01744 {
01745 H_AUTO_OGL(CDriverGL_fenceOnCurVBHardIfNeeded)
01746
01747 if( _CurrentVertexBufferHard==NULL || !_CurrentVertexBufferHard->VBType == IVertexBufferHardGL::NVidiaVB)
01748 return;
01749
01750
01751 if(_CurrentVertexBufferHard!=newVBHard)
01752 {
01753
01754 CVertexBufferHardGLNVidia *vbHardNV= static_cast<CVertexBufferHardGLNVidia*>(_CurrentVertexBufferHard);
01755
01756
01757 if( vbHardNV->GPURenderingAfterFence )
01758 {
01759
01760
01761
01762
01763
01764
01765
01766
01767
01768 if( !vbHardNV->getLockHintStatic() )
01769 vbHardNV->setFence();
01770
01771 vbHardNV->GPURenderingAfterFence= false;
01772 }
01773 }
01774 }
01775
01776
01777
01778 CIndexBufferInfo::CIndexBufferInfo()
01779 {
01780 H_AUTO_OGL(CIndexBufferInfo_CIndexBufferInfo)
01781 _Values = NULL;
01782 }
01783
01784
01785
01786 void CIndexBufferInfo::setupIndexBuffer(CIndexBuffer &ib)
01787 {
01788 H_AUTO_OGL(CIndexBufferInfo_setupIndexBuffer)
01789 CIndexBufferReadWrite access;
01790 ib.lock (access);
01791 _Values = access.getPtr();
01792 _Format = access.getFormat();
01793 }
01794
01795
01796
01797 }