# Home    # nevrax.com   
Nevrax
Nevrax.org
#News
#Mailing-list
#Documentation
#CVS
#Bugs
#License
Docs
 
Documentation  
Main Page   Namespace List   Class Hierarchy   Alphabetical List   Compound List   File List   Namespace Members   Compound Members   File Members   Related Pages   Search  

dru.cpp

Go to the documentation of this file.
00001 
00007 /* Copyright, 2000 Nevrax Ltd.
00008  *
00009  * This file is part of NEVRAX NEL.
00010  * NEVRAX NEL is free software; you can redistribute it and/or modify
00011  * it under the terms of the GNU General Public License as published by
00012  * the Free Software Foundation; either version 2, or (at your option)
00013  * any later version.
00014 
00015  * NEVRAX NEL is distributed in the hope that it will be useful, but
00016  * WITHOUT ANY WARRANTY; without even the implied warranty of
00017  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
00018  * General Public License for more details.
00019 
00020  * You should have received a copy of the GNU General Public License
00021  * along with NEVRAX NEL; see the file COPYING. If not, write to the
00022  * Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
00023  * MA 02111-1307, USA.
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         // WINDOWS code.
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         /* Not ANSI. Might produce a warning */
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         // v-left
00305         CDRU::drawLine(x0,y0,x0,y1 ,driver,col,viewport);       
00306         // v-right
00307         CDRU::drawLine(x1,y0,x1,y1 ,driver,col,viewport);       
00308         // h-up
00309         CDRU::drawLine(x0,y1,x1,y1,driver,col,viewport);        
00310         // h-bottom
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         // v-left
00319         CDRU::drawLine(xcenter-radius,ycenter-radius,xcenter-radius,ycenter+radius,driver,col,viewport);        
00320         // v-right
00321         CDRU::drawLine(xcenter+radius,ycenter-radius,xcenter+radius,ycenter+radius,driver,col,viewport);        
00322         // h-up
00323         CDRU::drawLine(xcenter-radius,ycenter+radius,xcenter+radius,ycenter+radius,driver,col,viewport);        
00324         // h-bottom
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         // Setup material.
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 } // NL3D
00452