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