00001
00007 00008 00009 00010 00011 00012 00013 00014 00015 00016 00017 00018 00019 00020 00021 00022 00023 00024
00025
00026 #include "nel/misc/types_nl.h"
00027
00028 #include "nel/3d/dru.h"
00029 #include "nel/3d/driver.h"
00030 #include "nel/3d/material.h"
00031 #include "nel/3d/vertex_buffer.h"
00032 #include "nel/3d/primitive_block.h"
00033
00034
00035 #ifdef NL_OS_WINDOWS
00036
00037 #include <windows.h>
00038
00039 #else // NL_OS_WINDOWS
00040
00041 #include <dlfcn.h>
00042
00043 #endif // NL_OS_WINDOWS
00044
00045 namespace NL3D
00046 {
00047
00048
00049 typedef IDriver* (*IDRV_CREATE_PROC)(void);
00050 const char *IDRV_CREATE_PROC_NAME = "NL3D_createIDriverInstance";
00051
00052 typedef uint32 (*IDRV_VERSION_PROC)(void);
00053 const char *IDRV_VERSION_PROC_NAME = "NL3D_interfaceVersion";
00054
00055
00056
00057 IDriver *CDRU::createGlDriver() throw (EDru)
00058 {
00059 IDRV_CREATE_PROC createDriver = NULL;
00060 IDRV_VERSION_PROC versionDriver = NULL;
00061
00062 #ifdef NL_OS_WINDOWS
00063
00064
00065 HINSTANCE hInst;
00066
00067 hInst=LoadLibrary(NL3D_DLL_NAME);
00068
00069 if (!hInst)
00070 {
00071 throw EDruOpenglDriverNotFound();
00072 }
00073
00074 createDriver = (IDRV_CREATE_PROC) GetProcAddress (hInst, IDRV_CREATE_PROC_NAME);
00075 if (createDriver == NULL)
00076 {
00077 throw EDruOpenglDriverCorrupted();
00078 }
00079
00080 versionDriver = (IDRV_VERSION_PROC) GetProcAddress (hInst, IDRV_VERSION_PROC_NAME);
00081 if (versionDriver != NULL)
00082 {
00083 if (versionDriver()<IDriver::InterfaceVersion)
00084 throw EDruOpenglDriverOldVersion();
00085 else if (versionDriver()>IDriver::InterfaceVersion)
00086 throw EDruOpenglDriverUnknownVersion();
00087 }
00088
00089 #elif defined (NL_OS_UNIX)
00090
00091 void *handle = dlopen(NL3D_DLL_NAME, RTLD_NOW);
00092
00093 if (handle == NULL)
00094 {
00095 nlwarning ("when loading dynamic library '%s': %s", NL3D_DLL_NAME, dlerror());
00096 throw EDruOpenglDriverNotFound();
00097 }
00098
00099
00100 createDriver = (IDRV_CREATE_PROC) dlsym (handle, IDRV_CREATE_PROC_NAME);
00101 if (createDriver == NULL)
00102 {
00103 nlwarning ("when getting function in dynamic library '%s': %s", NL3D_DLL_NAME, dlerror());
00104 throw EDruOpenglDriverCorrupted();
00105 }
00106
00107 versionDriver = (IDRV_VERSION_PROC) dlsym (handle, IDRV_VERSION_PROC_NAME);
00108 if (versionDriver != NULL)
00109 {
00110 if (versionDriver()<IDriver::InterfaceVersion)
00111 throw EDruOpenglDriverOldVersion();
00112 else if (versionDriver()>IDriver::InterfaceVersion)
00113 throw EDruOpenglDriverUnknownVersion();
00114 }
00115
00116 #else // NL_OS_LINUX
00117 #error "Dynamic DLL loading not implemented!"
00118 #endif // NL_OS_LINUX
00119
00120 IDriver *ret= createDriver();
00121 if (ret == NULL)
00122 {
00123 throw EDruOpenglDriverCantCreateDriver();
00124 }
00125 return ret;
00126 }
00127
00128
00129
00130 void CDRU::drawBitmap (float x, float y, float width, float height, ITexture& texture, IDriver& driver, CViewport viewport, bool blend)
00131 {
00132 CMatrix mtx;
00133 mtx.identity();
00134 driver.setupViewport (viewport);
00135 driver.setupViewMatrix (mtx);
00136 driver.setupModelMatrix (mtx);
00137 driver.setFrustum (0.f, 1.f, 0.f, 1.f, -1.f, 1.f, false);
00138
00139 static CMaterial mat;
00140 mat.initUnlit ();
00141 mat.setTexture (0, &texture);
00142 mat.setBlend(blend);
00143
00144 static CVertexBuffer vb;
00145 vb.setVertexFormat (IDRV_VF_XYZ|IDRV_VF_UV[0]);
00146 vb.setNumVertices (4);
00147 vb.setVertexCoord (0, CVector (x, 0, y));
00148 vb.setVertexCoord (1, CVector (x+width, 0, y));
00149 vb.setVertexCoord (2, CVector (x+width, 0, y+height));
00150 vb.setVertexCoord (3, CVector (x, 0, y+height));
00151 vb.setTexCoord (0, 0, 0.f, 1.f);
00152 vb.setTexCoord (1, 0, 1.f, 1.f);
00153 vb.setTexCoord (2, 0, 1.f, 0.f);
00154 vb.setTexCoord (3, 0, 0.f, 0.f);
00155 driver.activeVertexBuffer(vb);
00156
00157 CPrimitiveBlock pb;
00158 pb.setNumQuad (1);
00159 pb.setQuad (0, 0, 1, 2, 3);
00160
00161 driver.render(pb, mat);
00162 }
00163
00164
00165
00166 void CDRU::drawLine (float x0, float y0, float x1, float y1, IDriver& driver, CRGBA col, CViewport viewport)
00167 {
00168 CMatrix mtx;
00169 mtx.identity();
00170 driver.setupViewport (viewport);
00171 driver.setupViewMatrix (mtx);
00172 driver.setupModelMatrix (mtx);
00173 driver.setFrustum (0.f, 1.f, 0.f, 1.f, -1.f, 1.f, false);
00174
00175 static CMaterial mat;
00176 mat.initUnlit ();
00177 mat.setSrcBlend(CMaterial::srcalpha);
00178 mat.setDstBlend(CMaterial::invsrcalpha);
00179 mat.setBlend(true);
00180 mat.setColor(col);
00181
00182 static CVertexBuffer vb;
00183 vb.setVertexFormat (IDRV_VF_XYZ);
00184 vb.setNumVertices (2);
00185 vb.setVertexCoord (0, CVector (x0, 0, y0));
00186 vb.setVertexCoord (1, CVector (x1, 0, y1));
00187 driver.activeVertexBuffer(vb);
00188
00189 CPrimitiveBlock pb;
00190 pb.setNumLine (1);
00191 pb.setLine (0, 0, 1);
00192
00193 driver.render(pb, mat);
00194 }
00195
00196
00197
00198 void CDRU::drawTriangle (float x0, float y0, float x1, float y1, float x2, float y2, IDriver& driver, CRGBA col, CViewport viewport)
00199 {
00200 CMatrix mtx;
00201 mtx.identity();
00202 driver.setupViewport (viewport);
00203 driver.setupViewMatrix (mtx);
00204 driver.setupModelMatrix (mtx);
00205 driver.setFrustum (0.f, 1.f, 0.f, 1.f, -1.f, 1.f, false);
00206
00207 static CMaterial mat;
00208 mat.initUnlit();
00209 mat.setSrcBlend(CMaterial::srcalpha);
00210 mat.setDstBlend(CMaterial::invsrcalpha);
00211 mat.setBlend(true);
00212 mat.setColor(col);
00213
00214 static CVertexBuffer vb;
00215 vb.setVertexFormat (IDRV_VF_XYZ);
00216 vb.setNumVertices (3);
00217 vb.setVertexCoord (0, CVector (x0, 0, y0));
00218 vb.setVertexCoord (1, CVector (x1, 0, y1));
00219 vb.setVertexCoord (2, CVector (x2, 0, y2));
00220 driver.activeVertexBuffer(vb);
00221
00222 CPrimitiveBlock pb;
00223 pb.setNumTri (1);
00224 pb.setTri (0, 0, 1, 2);
00225
00226 driver.render(pb, mat);
00227 }
00228
00229
00230
00231
00232 void CDRU::drawQuad (float x0, float y0, float x1, float y1, IDriver& driver, CRGBA col, CViewport viewport)
00233 {
00234 CMatrix mtx;
00235 mtx.identity();
00236 driver.setupViewport (viewport);
00237 driver.setupViewMatrix (mtx);
00238 driver.setupModelMatrix (mtx);
00239 driver.setFrustum (0.f, 1.f, 0.f, 1.f, -1.f, 1.f, false);
00240
00241 static CMaterial mat;
00242 mat.initUnlit();
00243 mat.setSrcBlend(CMaterial::srcalpha);
00244 mat.setDstBlend(CMaterial::invsrcalpha);
00245 mat.setBlend(true);
00246 mat.setColor(col);
00247
00248 static CVertexBuffer vb;
00249 vb.setVertexFormat (IDRV_VF_XYZ);
00250 vb.setNumVertices (4);
00251 vb.setVertexCoord (0, CVector (x0, 0, y0));
00252 vb.setVertexCoord (1, CVector (x1, 0, y0));
00253 vb.setVertexCoord (2, CVector (x1, 0, y1));
00254 vb.setVertexCoord (3, CVector (x0, 0, y1));
00255
00256 driver.activeVertexBuffer(vb);
00257
00258 CPrimitiveBlock pb;
00259 pb.setNumQuad (1);
00260 pb.setQuad (0, 0, 1, 2, 3);
00261
00262 driver.render(pb, mat);
00263 }
00264
00265
00266
00267 void CDRU::drawQuad (float xcenter, float ycenter, float radius, IDriver& driver, CRGBA col, CViewport viewport)
00268 {
00269 CMatrix mtx;
00270 mtx.identity();
00271 driver.setupViewport (viewport);
00272 driver.setupViewMatrix (mtx);
00273 driver.setupModelMatrix (mtx);
00274 driver.setFrustum (0.f, 1.f, 0.f, 1.f, -1.f, 1.f, false);
00275
00276 static CMaterial mat;
00277 mat.initUnlit();
00278 mat.setSrcBlend(CMaterial::srcalpha);
00279 mat.setDstBlend(CMaterial::invsrcalpha);
00280 mat.setBlend(true);
00281 mat.setColor(col);
00282
00283 static CVertexBuffer vb;
00284 vb.setVertexFormat (IDRV_VF_XYZ);
00285 vb.setNumVertices (4);
00286 vb.setVertexCoord (0, CVector (xcenter-radius, 0, ycenter-radius));
00287 vb.setVertexCoord (1, CVector (xcenter+radius, 0, ycenter-radius));
00288 vb.setVertexCoord (2, CVector (xcenter+radius, 0, ycenter+radius));
00289 vb.setVertexCoord (3, CVector (xcenter-radius, 0, ycenter+radius));
00290
00291 driver.activeVertexBuffer(vb);
00292
00293 CPrimitiveBlock pb;
00294 pb.setNumQuad (1);
00295 pb.setQuad (0, 0, 1, 2, 3);
00296
00297 driver.render(pb, mat);
00298 }
00299
00300
00301
00302 void CDRU::drawWiredQuad (float x0, float y0, float x1, float y1, IDriver& driver, CRGBA col, CViewport viewport)
00303 {
00304
00305 CDRU::drawLine(x0,y0,x0,y1 ,driver,col,viewport);
00306
00307 CDRU::drawLine(x1,y0,x1,y1 ,driver,col,viewport);
00308
00309 CDRU::drawLine(x0,y1,x1,y1,driver,col,viewport);
00310
00311 CDRU::drawLine(x0,y0,x1,y0,driver,col,viewport);
00312 }
00313
00314
00315
00316 void CDRU::drawWiredQuad (float xcenter, float ycenter, float radius, IDriver& driver, CRGBA col, CViewport viewport)
00317 {
00318
00319 CDRU::drawLine(xcenter-radius,ycenter-radius,xcenter-radius,ycenter+radius,driver,col,viewport);
00320
00321 CDRU::drawLine(xcenter+radius,ycenter-radius,xcenter+radius,ycenter+radius,driver,col,viewport);
00322
00323 CDRU::drawLine(xcenter-radius,ycenter+radius,xcenter+radius,ycenter+radius,driver,col,viewport);
00324
00325 CDRU::drawLine(xcenter-radius,ycenter-radius,xcenter+radius,ycenter-radius,driver,col,viewport);
00326 }
00327
00328
00329
00330 void CDRU::drawTrianglesUnlit(const NLMISC::CTriangleUV *trilist, sint ntris, CMaterial &mat, IDriver& driver)
00331 {
00332 static CVertexBuffer vb;
00333 vb.setVertexFormat (IDRV_VF_XYZ | IDRV_VF_UV[0]);
00334 vb.setNumVertices (ntris*3);
00335
00336 static CPrimitiveBlock pb;
00337 pb.setNumTri(ntris);
00338
00339 for(sint i=0;i<ntris;i++)
00340 {
00341 vb.setVertexCoord (i*3+0, trilist[i].V0);
00342 vb.setVertexCoord (i*3+1, trilist[i].V1);
00343 vb.setVertexCoord (i*3+2, trilist[i].V2);
00344 vb.setTexCoord (i*3+0, 0, trilist[i].Uv0);
00345 vb.setTexCoord (i*3+1, 0, trilist[i].Uv1);
00346 vb.setTexCoord (i*3+2, 0, trilist[i].Uv2);
00347 pb.setTri(i, i*3+0, i*3+1, i*3+2);
00348 }
00349
00350 driver.activeVertexBuffer(vb);
00351 driver.render(pb, mat);
00352 }
00353
00354
00355
00356 void CDRU::drawTrianglesUnlit(const std::vector<NLMISC::CTriangleUV> &trilist, CMaterial &mat, IDriver& driver)
00357 {
00358 if(trilist.size()==0)
00359 return;
00360
00361 CDRU::drawTrianglesUnlit( &(*trilist.begin()), trilist.size(), mat, driver);
00362 }
00363
00364
00365
00366 void CDRU::drawLinesUnlit(const NLMISC::CLine *linelist, sint nlines, CMaterial &mat, IDriver& driver)
00367 {
00368 static CVertexBuffer vb;
00369 vb.setVertexFormat (IDRV_VF_XYZ);
00370 vb.setNumVertices (nlines*2);
00371
00372 static CPrimitiveBlock pb;
00373 pb.setNumLine(nlines);
00374
00375 for(sint i=0;i<nlines;i++)
00376 {
00377 vb.setVertexCoord (i*2+0, linelist[i].V0);
00378 vb.setVertexCoord (i*2+1, linelist[i].V1);
00379 pb.setLine(i, i*2+0, i*2+1);
00380 }
00381
00382 driver.activeVertexBuffer(vb);
00383 driver.render(pb, mat);
00384 }
00385
00386 void CDRU::drawLinesUnlit(const std::vector<NLMISC::CLine> &linelist, CMaterial &mat, IDriver& driver)
00387 {
00388 if(linelist.size()==0)
00389 return;
00390 CDRU::drawLinesUnlit( &(*linelist.begin()), linelist.size(), mat, driver);
00391 }
00392
00393 void CDRU::drawLine(const CVector &a, const CVector &b, CRGBA color, IDriver& driver)
00394 {
00395 static NLMISC::CLine line;
00396 static CMaterial mat;
00397 static bool inited= false;
00398
00399
00400 if(!inited)
00401 {
00402 inited= true;
00403 mat.initUnlit();
00404 }
00405 mat.setColor(color);
00406
00407
00408 line.V0= a;
00409 line.V1= b;
00410 CDRU::drawLinesUnlit(&line, 1, mat, driver);
00411 }
00412
00413 void CDRU::drawQuad (float x0, float y0, float x1, float y1, CRGBA col0, CRGBA col1, CRGBA col2, CRGBA col3, IDriver& driver, CViewport viewport)
00414 {
00415 CMatrix mtx;
00416 mtx.identity();
00417 driver.setupViewport (viewport);
00418 driver.setupViewMatrix (mtx);
00419 driver.setupModelMatrix (mtx);
00420 driver.setFrustum (0.f, 1.f, 0.f, 1.f, -1.f, 1.f, false);
00421
00422 static CMaterial mat;
00423 mat.initUnlit();
00424 mat.setSrcBlend(CMaterial::srcalpha);
00425 mat.setDstBlend(CMaterial::invsrcalpha);
00426 mat.setBlend(true);
00427
00428 static CVertexBuffer vb;
00429 vb.setVertexFormat (IDRV_VF_XYZ|IDRV_VF_COLOR);
00430 vb.setNumVertices (4);
00431 vb.setVertexCoord (0, CVector (x0, 0, y0));
00432 vb.setColor (0, col0);
00433 vb.setVertexCoord (1, CVector (x1, 0, y0));
00434 vb.setColor (1, col1);
00435 vb.setVertexCoord (2, CVector (x1, 0, y1));
00436 vb.setColor (2, col2);
00437 vb.setVertexCoord (3, CVector (x0, 0, y1));
00438 vb.setColor (3, col3);
00439
00440 driver.activeVertexBuffer(vb);
00441
00442 CPrimitiveBlock pb;
00443 pb.setNumQuad (1);
00444 pb.setQuad (0, 0, 1, 2, 3);
00445
00446 driver.render(pb, mat);
00447 }
00448
00449
00450
00451 }
00452