00001
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028 #include "stdopengl.h"
00029
00030 #include "3d/primitive_block.h"
00031 #include "driver_opengl_vertex_buffer_hard.h"
00032
00033
00034 using namespace std;
00035 using namespace NLMISC;
00036
00037
00038
00039
00040
00041 #define NL3D_DRV_SOFTSKIN_VNEEDCOMPUTE 3
00042 #define NL3D_DRV_SOFTSKIN_VMUSTCOMPUTE 1
00043 #define NL3D_DRV_SOFTSKIN_VCOMPUTED 0
00044
00045
00046
00047
00048
00049
00050 #define NL3D_DRV_VERTEXARRAY_MINIMUM_SIZE (512*1024)
00051
00052
00053
00054 namespace NL3D
00055 {
00056
00057
00058
00059
00060 bool CDriverGL::setupVertexBuffer(CVertexBuffer& VB)
00061 {
00062
00063
00064 if (!VB.DrvInfos)
00065 {
00066
00067 ItVBDrvInfoPtrList it= _VBDrvInfos.insert(_VBDrvInfos.end());
00068
00069 *it= VB.DrvInfos= new CVBDrvInfosGL(this, it);
00070 }
00071
00072
00073
00074 if( VB.getTouchFlags()!=0 )
00075 {
00076
00077
00078 VB.resetTouchFlags();
00079 }
00080
00081
00082 return true;
00083 }
00084
00085
00086
00087 bool CDriverGL::activeVertexBuffer(CVertexBuffer& VB, uint first, uint end)
00088 {
00089
00090
00091 uint32 flags;
00092
00093 if (!setupVertexBuffer(VB))
00094 return false;
00095
00096 if (VB.getNumVertices()==0)
00097 return true;
00098
00099 nlassert(end<=VB.getNumVertices());
00100 nlassert(first<=end);
00101
00102
00103 flags=VB.getVertexFormat();
00104
00105
00106
00107
00108
00109
00110 fenceOnCurVBHardIfNeeded(NULL);
00111
00112
00113 _LastVB.setupVertexBuffer(VB);
00114
00115
00116 if(_CurrentVertexBufferHard)
00117 _CurrentVertexBufferHard->disable();
00118
00119
00120 setupGlArrays(_LastVB);
00121
00122
00123 return true;
00124 }
00125
00126
00127
00128 bool CDriverGL::activeVertexBuffer(CVertexBuffer& VB)
00129 {
00130 return activeVertexBuffer(VB, 0, VB.getNumVertices());
00131 }
00132
00133
00134
00135 bool CDriverGL::render(CPrimitiveBlock& PB, CMaterial& Mat)
00136 {
00137
00138 refreshRenderSetup();
00139
00140
00141 if ( !setupMaterial(Mat) )
00142 return false;
00143
00144
00145
00146
00147
00148 uint nPass;
00149 nPass= beginMultiPass();
00150
00151 for(uint pass=0;pass<nPass; pass++)
00152 {
00153
00154 setupPass(pass);
00155
00156 if(PB.getNumTri()!=0)
00157 glDrawElements(GL_TRIANGLES,3*PB.getNumTri(),GL_UNSIGNED_INT,PB.getTriPointer());
00158 if(PB.getNumQuad()!=0)
00159 glDrawElements(GL_QUADS,4*PB.getNumQuad(),GL_UNSIGNED_INT,PB.getQuadPointer());
00160 if(PB.getNumLine()!=0)
00161 glDrawElements(GL_LINES,2*PB.getNumLine(),GL_UNSIGNED_INT,PB.getLinePointer());
00162 }
00163
00164 endMultiPass();
00165
00166
00167
00168 _PrimitiveProfileIn.NLines+= PB.getNumLine();
00169 _PrimitiveProfileIn.NTriangles+= PB.getNumTri();
00170 _PrimitiveProfileIn.NQuads+= PB.getNumQuad();
00171 _PrimitiveProfileOut.NLines+= PB.getNumLine() * nPass;
00172 _PrimitiveProfileOut.NTriangles+= PB.getNumTri() * nPass;
00173 _PrimitiveProfileOut.NQuads+= PB.getNumQuad() * nPass;
00174
00175
00176 if(_CurrentVertexBufferHard)
00177 _CurrentVertexBufferHard->GPURenderingAfterFence= true;
00178
00179 return true;
00180
00181
00182 }
00183
00184
00185
00186 void CDriverGL::renderTriangles(CMaterial& Mat, uint32 *tri, uint32 ntris)
00187 {
00188
00189 refreshRenderSetup();
00190
00191
00192 if ( !setupMaterial(Mat) )
00193 return;
00194
00195
00196
00197
00198
00199 uint nPass;
00200 nPass= beginMultiPass();
00201
00202 for(uint pass=0;pass<nPass; pass++)
00203 {
00204
00205 setupPass(pass);
00206
00207 if(ntris!=0)
00208 glDrawElements(GL_TRIANGLES,3*ntris,GL_UNSIGNED_INT, tri);
00209 }
00210
00211 endMultiPass();
00212
00213
00214
00215 _PrimitiveProfileIn.NTriangles+= ntris;
00216 _PrimitiveProfileOut.NTriangles+= ntris * nPass;
00217
00218
00219 if(_CurrentVertexBufferHard)
00220 _CurrentVertexBufferHard->GPURenderingAfterFence= true;
00221 }
00222
00223
00224
00225 void CDriverGL::renderSimpleTriangles(uint32 *tri, uint32 ntris)
00226 {
00227 nlassert(ntris>0);
00228
00229
00230 refreshRenderSetup();
00231
00232
00233
00234
00235
00236
00237
00238
00239 glDrawElements(GL_TRIANGLES,3*ntris,GL_UNSIGNED_INT, tri);
00240
00241
00242 _PrimitiveProfileIn.NTriangles+= ntris;
00243 _PrimitiveProfileOut.NTriangles+= ntris;
00244
00245
00246 if(_CurrentVertexBufferHard)
00247 _CurrentVertexBufferHard->GPURenderingAfterFence= true;
00248 }
00249
00250
00251
00252 void CDriverGL::renderPoints(CMaterial& Mat, uint32 numPoints)
00253 {
00254
00255 refreshRenderSetup();
00256
00257
00258 if ( !setupMaterial(Mat) )
00259 return;
00260
00261
00262
00263
00264
00265 uint nPass;
00266 nPass= beginMultiPass();
00267
00268 for(uint pass=0;pass<nPass; pass++)
00269 {
00270
00271 setupPass(pass);
00272
00273 if(numPoints)
00274 glDrawArrays(GL_POINTS,0, numPoints);
00275 }
00276
00277 endMultiPass();
00278
00279
00280
00281 _PrimitiveProfileIn.NPoints+= numPoints;
00282 _PrimitiveProfileOut.NPoints+= numPoints * nPass;
00283
00284
00285 if(_CurrentVertexBufferHard)
00286 _CurrentVertexBufferHard->GPURenderingAfterFence= true;
00287 }
00288
00289
00290
00291
00292
00293 void CDriverGL::renderQuads(CMaterial& Mat, uint32 startIndex, uint32 numQuads)
00294 {
00295
00296 refreshRenderSetup();
00297
00298
00299 if ( !setupMaterial(Mat) )
00300 return;
00301
00302
00303
00304
00305
00306 uint nPass;
00307 nPass= beginMultiPass();
00308
00309 for(uint pass=0;pass<nPass; pass++)
00310 {
00311
00312 setupPass(pass);
00313
00314 if(numQuads)
00315 glDrawArrays(GL_QUADS, startIndex << 2, numQuads << 2) ;
00316 }
00317
00318 endMultiPass();
00319
00320
00321
00322 _PrimitiveProfileIn.NQuads += numQuads ;
00323 _PrimitiveProfileOut.NQuads += numQuads * nPass;
00324
00325
00326 if(_CurrentVertexBufferHard)
00327 _CurrentVertexBufferHard->GPURenderingAfterFence= true;
00328 }
00329
00330
00331
00332 void CDriverGL::setupUVPtr(uint stage, CVertexBufferInfo &VB, uint uvId)
00333 {
00334
00335 nlassert(!_LastSetupGLArrayVertexProgram);
00336
00337 _DriverGLStates.clientActiveTextureARB(stage);
00338 if (VB.VertexFormat & (CVertexBuffer::TexCoord0Flag<<uvId))
00339 {
00340
00341 if (VB.Type[CVertexBuffer::TexCoord0+uvId]==CVertexBuffer::Float2)
00342 {
00343 _DriverGLStates.enableTexCoordArray(true);
00344
00345 if(VB.ATIVBHardMode)
00346 nglArrayObjectATI(GL_TEXTURE_COORD_ARRAY, 2, GL_FLOAT, VB.VertexSize,
00347 VB.ATIVertexObjectId, VB.ATIValueOffset[CVertexBuffer::TexCoord0+uvId]);
00348 else
00349 glTexCoordPointer(2,GL_FLOAT,VB.VertexSize,VB.ValuePtr[CVertexBuffer::TexCoord0+uvId]);
00350 }
00351 else
00352 {
00353 _DriverGLStates.enableTexCoordArray(false);
00354 }
00355 }
00356 else
00357 _DriverGLStates.enableTexCoordArray(false);
00358 }
00359
00360
00361
00362 void CDriverGL::mapTextureStageToUV(uint stage, uint uv)
00363 {
00364
00365 setupUVPtr(stage, _LastVB, uv);
00366 }
00367
00368
00369
00370
00371
00372
00373
00374
00375
00376
00377
00378 bool CDriverGL::supportVertexBufferHard() const
00379 {
00380 return _SupportVBHard;
00381 }
00382
00383
00384
00385 bool CDriverGL::slowUnlockVertexBufferHard() const
00386 {
00387 return _SlowUnlockVBHard;
00388 }
00389
00390
00391
00392 uint CDriverGL::getMaxVerticesByVertexBufferHard() const
00393 {
00394 return _MaxVerticesByVBHard;
00395 }
00396
00397
00398
00399 IVertexBufferHard *CDriverGL::createVertexBufferHard(uint16 vertexFormat, const uint8 *typeArray, uint32 numVertices, IDriver::TVBHardType vbType)
00400 {
00401
00402 IVertexArrayRange *vertexArrayRange= NULL;
00403 switch(vbType)
00404 {
00405 case IDriver::VBHardAGP:
00406 vertexArrayRange= _AGPVertexArrayRange;
00407 break;
00408 case IDriver::VBHardVRAM:
00409 vertexArrayRange= _VRAMVertexArrayRange;
00410 break;
00411 };
00412
00413
00414 if( !vertexArrayRange )
00415 return NULL;
00416 else
00417 {
00418
00419 if(numVertices > _MaxVerticesByVBHard)
00420 return NULL;
00421
00422
00423 IVertexBufferHardGL *vb;
00424
00425 vb= vertexArrayRange->createVBHardGL(vertexFormat, typeArray, numVertices);
00426
00427 if(!vb)
00428 {
00429 return NULL;
00430 }
00431 else
00432 {
00433
00434 return _VertexBufferHardSet.insert(vb);
00435 }
00436 }
00437 }
00438
00439
00440
00441 void CDriverGL::deleteVertexBufferHard(IVertexBufferHard *VB)
00442 {
00443
00444
00445
00446
00447 if(_CurrentVertexBufferHard)
00448 {
00449
00450 _CurrentVertexBufferHard->lock();
00451 _CurrentVertexBufferHard->unlock();
00452
00453 _CurrentVertexBufferHard->disable();
00454 }
00455
00456
00457 _VertexBufferHardSet.erase(safe_cast<IVertexBufferHardGL*>(VB));
00458 }
00459
00460
00461
00462
00463 void CDriverGL::activeVertexBufferHard(IVertexBufferHard *iVB)
00464 {
00465
00466
00467 nlassert(iVB);
00468 IVertexBufferHardGL *VB= safe_cast<IVertexBufferHardGL*>(iVB);
00469
00470 uint32 flags;
00471
00472 if (VB->getNumVertices()==0)
00473 return;
00474
00475
00476 flags=VB->getVertexFormat();
00477
00478
00479
00480
00481
00482
00483 fenceOnCurVBHardIfNeeded(VB);
00484
00485
00486 _LastVB.setupVertexBufferHard(*VB);
00487
00488
00489 VB->enable();
00490
00491
00492 setupGlArrays(_LastVB);
00493
00494 }
00495
00496
00497
00498 const uint CDriverGL::NumCoordinatesType[CVertexBuffer::NumType]=
00499 {
00500 1,
00501 1,
00502 1,
00503 2,
00504 2,
00505 2,
00506 3,
00507 3,
00508 3,
00509 4,
00510 4,
00511 4,
00512 4
00513 };
00514
00515
00516
00517 const uint CDriverGL::GLType[CVertexBuffer::NumType]=
00518 {
00519 GL_DOUBLE,
00520 GL_FLOAT,
00521 GL_SHORT,
00522 GL_DOUBLE,
00523 GL_FLOAT,
00524 GL_SHORT,
00525 GL_DOUBLE,
00526 GL_FLOAT,
00527 GL_SHORT,
00528 GL_DOUBLE,
00529 GL_FLOAT,
00530 GL_SHORT,
00531 GL_UNSIGNED_BYTE
00532 };
00533
00534
00535
00536 const uint CDriverGL::GLVertexAttribIndex[CVertexBuffer::NumValue]=
00537 {
00538 0,
00539 2,
00540 8,
00541 9,
00542 10,
00543 11,
00544 12,
00545 13,
00546 14,
00547 15,
00548 3,
00549 4,
00550 1,
00551 6,
00552 5,
00553 7,
00554 };
00555
00556
00557
00558
00559 void CDriverGL::setupGlArraysStd(CVertexBufferInfo &vb)
00560 {
00561 uint32 flags= vb.VertexFormat;
00562
00563
00564 uint numVertexCoord = CVertexBuffer::NumComponentsType[vb.Type[CVertexBuffer::Position]];
00565 nlassert (numVertexCoord >= 2);
00566
00567 _DriverGLStates.enableVertexArray(true);
00568
00569 if(vb.ATIVBHardMode)
00570 nglArrayObjectATI(GL_VERTEX_ARRAY, numVertexCoord, GL_FLOAT, vb.VertexSize,
00571 vb.ATIVertexObjectId, vb.ATIValueOffset[CVertexBuffer::Position]);
00572 else
00573 glVertexPointer(numVertexCoord, GL_FLOAT, vb.VertexSize, vb.ValuePtr[CVertexBuffer::Position]);
00574
00575
00576
00577
00578
00579 if (flags & CVertexBuffer::NormalFlag)
00580 {
00581
00582 nlassert (vb.Type[CVertexBuffer::Normal]==CVertexBuffer::Float3);
00583
00584 _DriverGLStates.enableNormalArray(true);
00585
00586 if(vb.ATIVBHardMode)
00587 nglArrayObjectATI(GL_NORMAL_ARRAY, 3, GL_FLOAT, vb.VertexSize,
00588 vb.ATIVertexObjectId, vb.ATIValueOffset[CVertexBuffer::Normal]);
00589 else
00590 glNormalPointer(GL_FLOAT, vb.VertexSize, vb.ValuePtr[CVertexBuffer::Normal]);
00591 }
00592 else
00593 {
00594 _DriverGLStates.enableNormalArray(false);
00595 }
00596
00597
00598
00599
00600
00601 if (flags & CVertexBuffer::PrimaryColorFlag)
00602 {
00603
00604 nlassert (vb.Type[CVertexBuffer::PrimaryColor]==CVertexBuffer::UChar4);
00605
00606 _DriverGLStates.enableColorArray(true);
00607
00608 if(vb.ATIVBHardMode)
00609 nglArrayObjectATI(GL_COLOR_ARRAY, 4, GL_UNSIGNED_BYTE, vb.VertexSize,
00610 vb.ATIVertexObjectId, vb.ATIValueOffset[CVertexBuffer::PrimaryColor]);
00611 else
00612 glColorPointer(4,GL_UNSIGNED_BYTE, vb.VertexSize, vb.ValuePtr[CVertexBuffer::PrimaryColor]);
00613 }
00614 else
00615 _DriverGLStates.enableColorArray(false);
00616
00617
00618
00619
00620 for(sint i=0; i<inlGetNumTextStages(); i++)
00621 {
00622
00623 setupUVPtr(i, vb, i);
00624 }
00625 }
00626
00627
00628
00629
00630 void CDriverGL::toggleGlArraysForNVVertexProgram()
00631 {
00632
00633
00634
00635
00636 if( _LastSetupGLArrayVertexProgram && !isVertexProgramEnabled () )
00637 {
00638
00639
00640 for (uint value=0; value<CVertexBuffer::NumValue; value++)
00641 {
00642
00643 uint glIndex=GLVertexAttribIndex[value];
00644 _DriverGLStates.enableVertexAttribArray(glIndex, false);
00645 }
00646 _DriverGLStates.enableColorArray(false);
00647 _DriverGLStates.enableSecondaryColorArray(false);
00648
00649
00650 _LastSetupGLArrayVertexProgram= false;
00651 }
00652
00653
00654 if( !_LastSetupGLArrayVertexProgram && isVertexProgramEnabled () )
00655 {
00656
00657 _DriverGLStates.enableVertexArray(false);
00658 _DriverGLStates.enableNormalArray(false);
00659 _DriverGLStates.enableColorArray(false);
00660 for(sint i=0; i<inlGetNumTextStages(); i++)
00661 {
00662 _DriverGLStates.clientActiveTextureARB(i);
00663 _DriverGLStates.enableTexCoordArray(false);
00664 }
00665
00666
00667
00668 _LastSetupGLArrayVertexProgram= true;
00669 }
00670 }
00671
00672
00673
00674 void CDriverGL::toggleGlArraysForEXTVertexShader()
00675 {
00676
00677
00678
00679
00680
00681 if( _LastSetupGLArrayVertexProgram && !isVertexProgramEnabled () )
00682 {
00683 CVertexProgram *vp = _LastSetuppedVP;
00684 if (vp)
00685 {
00686 CVertexProgamDrvInfosGL *drvInfo = NLMISC::safe_cast<CVertexProgamDrvInfosGL *>((IVertexProgramDrvInfos *) vp->_DrvInfo);
00687 if (drvInfo)
00688 {
00689
00690 for (uint value=0; value<CVertexBuffer::NumValue; value++)
00691 {
00692 _DriverGLStates.enableVertexAttribArrayForEXTVertexShader(value, false, drvInfo->Variants);
00693 }
00694 }
00695 }
00696
00697 _LastSetupGLArrayVertexProgram= false;
00698 }
00699
00700
00701 if( !_LastSetupGLArrayVertexProgram && isVertexProgramEnabled () )
00702 {
00703
00704 _DriverGLStates.enableVertexArray(false);
00705 _DriverGLStates.enableNormalArray(false);
00706 _DriverGLStates.enableColorArray(false);
00707 for(sint i=0; i<inlGetNumTextStages(); i++)
00708 {
00709 _DriverGLStates.clientActiveTextureARB(i);
00710 _DriverGLStates.enableTexCoordArray(false);
00711 }
00712
00713
00714
00715 _LastSetupGLArrayVertexProgram= true;
00716 }
00717 }
00718
00719
00720 void CDriverGL::setupGlArraysForNVVertexProgram(CVertexBufferInfo &vb)
00721 {
00722 uint32 flags= vb.VertexFormat;
00723
00724
00725 for (uint value=0; value<CVertexBuffer::NumValue; value++)
00726 {
00727
00728 uint16 flag=1<<value;
00729
00730
00731 CVertexBuffer::TType type=vb.Type[value];
00732
00733
00734 uint glIndex=GLVertexAttribIndex[value];
00735
00736
00737 if (flags & flag)
00738 {
00739
00740
00741
00742
00743 if( (glIndex==3 || glIndex==4) )
00744 {
00745 if( type == CVertexBuffer::UChar4 )
00746 {
00747
00748 _DriverGLStates.enableVertexAttribArray(glIndex, false);
00749
00750
00751 if(glIndex==3)
00752 {
00753
00754 _DriverGLStates.enableColorArray(true);
00755 glColorPointer(4,GL_UNSIGNED_BYTE, vb.VertexSize, vb.ValuePtr[value]);
00756 }
00757 else
00758 {
00759
00760 _DriverGLStates.enableSecondaryColorArray(true);
00761 nglSecondaryColorPointerEXT(4,GL_UNSIGNED_BYTE, vb.VertexSize, vb.ValuePtr[value]);
00762 }
00763 }
00764 else
00765 {
00766
00767
00768 if(glIndex==3)
00769 _DriverGLStates.enableColorArray(false);
00770 else
00771 _DriverGLStates.enableSecondaryColorArray(false);
00772
00773
00774 _DriverGLStates.enableVertexAttribArray(glIndex, true);
00775 nglVertexAttribPointerNV (glIndex, NumCoordinatesType[type], GLType[type], vb.VertexSize, vb.ValuePtr[value]);
00776 }
00777 }
00778
00779 else
00780 {
00781
00782 _DriverGLStates.enableVertexAttribArray(glIndex, true);
00783 nglVertexAttribPointerNV (glIndex, NumCoordinatesType[type], GLType[type], vb.VertexSize, vb.ValuePtr[value]);
00784 }
00785 }
00786 else
00787 {
00788 _DriverGLStates.enableVertexAttribArray(glIndex, false);
00789
00790
00791
00792 if(glIndex==3)
00793 _DriverGLStates.enableColorArray(false);
00794 else if(glIndex==4)
00795 _DriverGLStates.enableSecondaryColorArray(false);
00796 }
00797 }
00798 }
00799
00800
00801
00802 void CDriverGL::setupGlArraysForEXTVertexShader(CVertexBufferInfo &vb)
00803 {
00804
00805 CVertexProgram *vp = _LastSetuppedVP;
00806 if (!vp) return;
00807 CVertexProgamDrvInfosGL *drvInfo = NLMISC::safe_cast<CVertexProgamDrvInfosGL *>((IVertexProgramDrvInfos *) vp->_DrvInfo);
00808 if (!drvInfo) return;
00809
00810 uint32 flags= vb.VertexFormat;
00811
00812
00813 for (uint value=0; value<CVertexBuffer::NumValue; value++)
00814 {
00815
00816 uint16 flag=1<<value;
00817
00818
00819 CVertexBuffer::TType type=vb.Type[value];
00820
00821
00822 uint glIndex=GLVertexAttribIndex[value];
00823
00824
00825 if (flags & flag & drvInfo->UsedVertexComponents)
00826 {
00827 _DriverGLStates.enableVertexAttribArrayForEXTVertexShader(glIndex, true, drvInfo->Variants);
00828
00829 switch(value)
00830 {
00831 case CVertexBuffer::Position:
00832 {
00833 nlassert(NumCoordinatesType[type] >= 2);
00834 if(vb.ATIVBHardMode) nglArrayObjectATI(GL_VERTEX_ARRAY, NumCoordinatesType[type], GLType[type], vb.VertexSize, vb.ATIVertexObjectId, vb.ATIValueOffset[CVertexBuffer::Position]);
00835 else glVertexPointer(NumCoordinatesType[type], GLType[type], vb.VertexSize, vb.ValuePtr[value]);
00836 }
00837 break;
00838 case CVertexBuffer::Weight:
00839 {
00840 nlassert(NumCoordinatesType[type] == 4);
00841 if(vb.ATIVBHardMode) nglVariantArrayObjectATI(drvInfo->Variants[CDriverGL::EVSSkinWeightVariant], GLType[type], vb.VertexSize, vb.ATIVertexObjectId, vb.ATIValueOffset[CVertexBuffer::Weight]);
00842 else nglVariantPointerEXT(drvInfo->Variants[CDriverGL::EVSSkinWeightVariant], GLType[type], vb.VertexSize, vb.ValuePtr[value]);
00843 }
00844 break;
00845 case CVertexBuffer::Normal:
00846 {
00847 nlassert(NumCoordinatesType[type] == 3);
00848 if(vb.ATIVBHardMode) nglArrayObjectATI(GL_NORMAL_ARRAY, 3, GLType[type], vb.VertexSize, vb.ATIVertexObjectId, vb.ATIValueOffset[value]);
00849 else glNormalPointer(GLType[type], vb.VertexSize, vb.ValuePtr[CVertexBuffer::Normal]);
00850 }
00851 break;
00852 case CVertexBuffer::PrimaryColor:
00853 {
00854 nlassert(NumCoordinatesType[type] >= 3);
00855 if(vb.ATIVBHardMode) nglArrayObjectATI(GL_COLOR_ARRAY, NumCoordinatesType[type], GLType[type], vb.VertexSize, vb.ATIVertexObjectId, vb.ATIValueOffset[CVertexBuffer::PrimaryColor]);
00856 else glColorPointer(NumCoordinatesType[type], GLType[type], vb.VertexSize, vb.ValuePtr[value]);
00857 }
00858 break;
00859 case CVertexBuffer::SecondaryColor:
00860 {
00861
00862 nlassert(NumCoordinatesType[type] == 4);
00863 if(vb.ATIVBHardMode) nglVariantArrayObjectATI(drvInfo->Variants[CDriverGL::EVSSecondaryColorVariant], GLType[type], vb.VertexSize, vb.ATIVertexObjectId, vb.ATIValueOffset[CVertexBuffer::SecondaryColor]);
00864 else nglVariantPointerEXT(drvInfo->Variants[CDriverGL::EVSSecondaryColorVariant], GLType[type], vb.VertexSize, vb.ValuePtr[value]);
00865 }
00866 break;
00867 case CVertexBuffer::Fog:
00868 {
00869
00870 nlassert(NumCoordinatesType[type] == 4);
00871 if(vb.ATIVBHardMode) nglVariantArrayObjectATI(drvInfo->Variants[CDriverGL::EVSFogCoordsVariant], GLType[type], vb.VertexSize, vb.ATIVertexObjectId, vb.ATIValueOffset[CVertexBuffer::Fog]);
00872 else nglVariantPointerEXT(drvInfo->Variants[CDriverGL::EVSFogCoordsVariant], GLType[type], vb.VertexSize, vb.ValuePtr[value]);
00873 }
00874 break;
00875 case CVertexBuffer::PaletteSkin:
00876 {
00877
00878 nlassert(NumCoordinatesType[type] == 4);
00879 if(vb.ATIVBHardMode) nglVariantArrayObjectATI(drvInfo->Variants[CDriverGL::EVSPaletteSkinVariant], GLType[type], vb.VertexSize, vb.ATIVertexObjectId, vb.ATIValueOffset[CVertexBuffer::PaletteSkin]);
00880 else nglVariantPointerEXT(drvInfo->Variants[CDriverGL::EVSPaletteSkinVariant], GLType[type], vb.VertexSize, vb.ValuePtr[value]);
00881 }
00882 break;
00883 case CVertexBuffer::Empty:
00884 nlstop
00885 break;
00886 case CVertexBuffer::TexCoord0:
00887 case CVertexBuffer::TexCoord1:
00888 case CVertexBuffer::TexCoord2:
00889 case CVertexBuffer::TexCoord3:
00890 case CVertexBuffer::TexCoord4:
00891 case CVertexBuffer::TexCoord5:
00892 case CVertexBuffer::TexCoord6:
00893 case CVertexBuffer::TexCoord7:
00894 {
00895 _DriverGLStates.clientActiveTextureARB(value - CVertexBuffer::TexCoord0);
00896 if(vb.ATIVBHardMode) nglArrayObjectATI(GL_TEXTURE_COORD_ARRAY, NumCoordinatesType[type], GLType[type], vb.VertexSize, vb.ATIVertexObjectId, vb.ATIValueOffset[value]);
00897 else glTexCoordPointer(NumCoordinatesType[type], GLType[type], vb.VertexSize, vb.ValuePtr[value ]);
00898 }
00899 break;
00900 default:
00901 nlstop;
00902 break;
00903 }
00904 }
00905 else
00906 {
00907 _DriverGLStates.enableVertexAttribArrayForEXTVertexShader(glIndex, false, drvInfo->Variants);
00908 }
00909 }
00910 }
00911
00912
00913
00914
00915 void CDriverGL::setupGlArrays(CVertexBufferInfo &vb)
00916 {
00917 uint32 flags= vb.VertexFormat;
00918
00923
00924 if (_Extensions.NVVertexProgram || !_Extensions.EXTVertexShader)
00925 {
00926 toggleGlArraysForNVVertexProgram();
00927
00928 if (!isVertexProgramEnabled ())
00929 {
00930 setupGlArraysStd(vb);
00931 }
00932 else
00933 {
00934 setupGlArraysForNVVertexProgram(vb);
00935 }
00936 }
00937 else
00938 {
00939 toggleGlArraysForEXTVertexShader();
00940
00941 if (!isVertexProgramEnabled ())
00942 {
00943 setupGlArraysStd(vb);
00944 }
00945 else
00946 {
00947 setupGlArraysForEXTVertexShader(vb);
00948 }
00949 }
00950
00951
00952 _LastVertexSetupIsLightMap= false;
00953 }
00954
00955
00956
00957 void CVertexBufferInfo::setupVertexBuffer(CVertexBuffer &vb)
00958 {
00959 sint i;
00960 uint flags= vb.getVertexFormat();
00961 VertexFormat= flags;
00962 VertexSize= vb.getVertexSize();
00963 NumVertices= vb.getNumVertices();
00964 NumWeight= vb.getNumWeight();
00965
00966
00967 ATIVBHardMode= false;
00968
00969
00970 for (i=0; i<CVertexBuffer::NumValue; i++)
00971 {
00972
00973 if (VertexFormat&(1<<i))
00974 {
00975
00976 ValuePtr[i]=vb.getValueEx ((CVertexBuffer::TValue)i);
00977
00978
00979 Type[i]=vb.getValueType (i);
00980 }
00981 }
00982 }
00983
00984
00985
00986 void CVertexBufferInfo::setupVertexBufferHard(IVertexBufferHardGL &vb)
00987 {
00988 sint i;
00989 uint flags= vb.getVertexFormat();
00990 VertexFormat= flags;
00991 VertexSize= vb.getVertexSize();
00992 NumVertices= vb.getNumVertices();
00993 NumWeight= vb.getNumWeight();
00994
00995
00996 ATIVBHardMode= false;
00997
00998
00999 if(vb.NVidiaVertexBufferHard)
01000 {
01001 CVertexBufferHardGLNVidia &vbHardNV= static_cast<CVertexBufferHardGLNVidia&>(vb);
01002
01003
01004 for (i=0; i<CVertexBuffer::NumValue; i++)
01005 {
01006
01007 if (VertexFormat&(1<<i))
01008 {
01009
01010 ValuePtr[i]= vbHardNV.getNVidiaValueEx(i);
01011
01012
01013 Type[i]= vbHardNV.getValueType (i);
01014 }
01015 }
01016 }
01017 else
01018 {
01019 nlassert(vb.ATIVertexBufferHard);
01020 CVertexBufferHardGLATI &vbHardATI= static_cast<CVertexBufferHardGLATI&>(vb);
01021
01022
01023 ATIVBHardMode= true;
01024
01025
01026 ATIVertexObjectId= vbHardATI.getATIVertexObjectId();
01027
01028
01029 for (i=0; i<CVertexBuffer::NumValue; i++)
01030 {
01031
01032 if (VertexFormat&(1<<i))
01033 {
01034
01035 ATIValueOffset[i]= vbHardATI.getATIValueOffset(i);
01036
01037
01038 Type[i]= vbHardATI.getValueType (i);
01039 }
01040 }
01041 }
01042 }
01043
01044
01045
01046
01047 void CDriverGL::resetVertexArrayRange()
01048 {
01049 if(_CurrentVertexBufferHard)
01050 {
01051
01052 _CurrentVertexBufferHard->lock();
01053 _CurrentVertexBufferHard->unlock();
01054
01055 _CurrentVertexBufferHard->disable();
01056 }
01057
01058 _VertexBufferHardSet.clear();
01059
01060
01061 if(_AGPVertexArrayRange)
01062 _AGPVertexArrayRange->free();
01063 if(_VRAMVertexArrayRange)
01064 _VRAMVertexArrayRange->free();
01065 }
01066
01067
01068
01069 bool CDriverGL::initVertexArrayRange(uint agpMem, uint vramMem)
01070 {
01071 if(!supportVertexBufferHard())
01072 return false;
01073
01074
01075 if(!_AGPVertexArrayRange || !_VRAMVertexArrayRange)
01076 return false;
01077
01078
01079 resetVertexArrayRange();
01080 bool ok= true;
01081
01082
01083 if(agpMem>0)
01084 {
01085 agpMem&= ~15;
01086 agpMem= max(agpMem, (uint)NL3D_DRV_VERTEXARRAY_MINIMUM_SIZE);
01087 while(agpMem>= NL3D_DRV_VERTEXARRAY_MINIMUM_SIZE)
01088 {
01089 if(_AGPVertexArrayRange->allocate(agpMem, IDriver::VBHardAGP))
01090 {
01091 nlinfo("VAR: %.d vertices supported", _MaxVerticesByVBHard);
01092 nlinfo("VAR: Success to allocate %.1f Mo of AGP VAR Ram", agpMem / 1000000.f);
01093 break;
01094 }
01095 else
01096 {
01097 agpMem/=2;
01098 agpMem &=~15;
01099 }
01100 }
01101
01102 if(agpMem< NL3D_DRV_VERTEXARRAY_MINIMUM_SIZE)
01103 {
01104 nlinfo("VAR: %.d vertices supported", _MaxVerticesByVBHard);
01105 nlinfo("VAR: Failed to allocate %.1f Mo of AGP VAR Ram", NL3D_DRV_VERTEXARRAY_MINIMUM_SIZE / 1000000.f);
01106 ok= false;
01107 }
01108 }
01109
01110
01111
01112 if(vramMem>0)
01113 {
01114 vramMem&= ~15;
01115 vramMem= max(vramMem, (uint)NL3D_DRV_VERTEXARRAY_MINIMUM_SIZE);
01116 while(vramMem>= NL3D_DRV_VERTEXARRAY_MINIMUM_SIZE)
01117 {
01118 if(_VRAMVertexArrayRange->allocate(vramMem, IDriver::VBHardVRAM))
01119 break;
01120 else
01121 {
01122 vramMem/=2;
01123 vramMem &=~15;
01124 }
01125 }
01126
01127 if(vramMem< NL3D_DRV_VERTEXARRAY_MINIMUM_SIZE)
01128 {
01129 ok= false;
01130 }
01131 }
01132
01133
01134 return ok;
01135 }
01136
01137
01138
01139 void CDriverGL::fenceOnCurVBHardIfNeeded(IVertexBufferHardGL *newVBHard)
01140 {
01141
01142 if( _CurrentVertexBufferHard==NULL || !_CurrentVertexBufferHard->NVidiaVertexBufferHard )
01143 return;
01144
01145
01146 if(_CurrentVertexBufferHard!=newVBHard)
01147 {
01148
01149 CVertexBufferHardGLNVidia *vbHardNV= static_cast<CVertexBufferHardGLNVidia*>(_CurrentVertexBufferHard);
01150
01151
01152 if( vbHardNV->GPURenderingAfterFence )
01153 {
01154
01155
01156
01157
01158
01159
01160
01161
01162 vbHardNV->finishFence();
01163
01164 vbHardNV->setFence();
01165 vbHardNV->GPURenderingAfterFence= false;
01166 }
01167 }
01168 }
01169
01170
01171 }