This section of the archives stores flipcode's complete Developer Toolbox collection, featuring a variety of mini-articles and source code contributions from our readers.

 

  Render System Framework
  Submitted by



This material is intended to provide a sample framework for beginners that would start to develop a render system capable of supporting various 3DApi (Direct X, OpenGL are included). This sample render system should give a starting point to those who are still wondering how to design this, and also provide the base to add other features that are not yet implemented here (as you can see, the goal was not to provide a complete render system but to present how it should be layed out according to me). I would be glad to ear from experienced people about this approach as this is the first time I give a try to designing such a renderer. Of course, as "educational" material, I am sure that a lot of improvements/optimisations can be implemented, starting with adding decent math library, using vertex array range in the OpenGL implementation of static vertex buffers, ... Feel free to suggest me other ideas or report any bug (about the render system, not about the sample app, I already know this one is crappy :)

More information about the framework and how it was designed can be found in the readme.txt file. Vincent

Currently browsing [RenderSystem.zip] (241,705 bytes) - [Sources/RenderSystem/OpenGLRenderDevice.cpp] - (6,818 bytes)

#ifdef COMPILE_OPENGL_IMPLEMENTATION

#include "OpenGLRenderDevice.h" #include "OpenGLVertexBuffer.h"

OpenGLRenderDevice::OpenGLRenderDevice( HWND hwnd, DWORD width, DWORD height ) : RenderDeviceImplementor() { // Init some member values //-- m_baseApi = RSAPI_OPENGL; m_hWnd = hwnd; // Fill in the pixel format descriptor. // PIXELFORMATDESCRIPTOR pfd ; memset(&pfd, 0, sizeof(PIXELFORMATDESCRIPTOR)); pfd.nSize = sizeof(PIXELFORMATDESCRIPTOR); pfd.nVersion = 1; pfd.dwFlags = PFD_DOUBLEBUFFER | PFD_SUPPORT_OPENGL | PFD_DRAW_TO_WINDOW ; pfd.iPixelType = PFD_TYPE_RGBA; pfd.cColorBits = 32; pfd.cDepthBits = 16; pfd.iLayerType = PFD_MAIN_PLANE;

HDC hdc = ::GetDC( m_hWnd );

// Choose pixel format //-- int nPixelFormat = ChoosePixelFormat( hdc, &pfd ); if (nPixelFormat == 0) { ::OutputDebugString( "ChoosePixelFormat Failed\n" ) ; } else { // Set pixel format //-- BOOL bResult = SetPixelFormat ( hdc, nPixelFormat, &pfd ); if (!bResult) { ::OutputDebugString( "SetPixelFormat Failed\n" ) ; } else { // Create a rendering context. //-- m_hrc = wglCreateContext( hdc ); if ( !m_hrc ) { ::OutputDebugString( "wglCreateContext Failed\n" ) ; } else { // Set it as the current context //-- if ( !wglMakeCurrent( hdc, m_hrc ) ) { ::OutputDebugString( "wglMakeCurrent Failed\n" ) ; } } } }

// Set a default viewport //-- glEnable( GL_SCISSOR_TEST ); SetViewport( 0, 0, width, height );

SetBackgroundColor( 1, 0, 0, 0 ); SetDepthClearValue( 1.0f ); SetStencilClearValue( 0 ); }

OpenGLRenderDevice::~OpenGLRenderDevice() { Release(); }



void OpenGLRenderDevice::Release() { wglDeleteContext( m_hrc ); }

//------------------------------------------------------------------ // Tranformation functions //-- void OpenGLRenderDevice::MatrixModeSet(RS_MATRIXMODE mode) { m_matrixMode = mode;

if ( m_matrixMode==RSMM_PROJECTION ) glMatrixMode( GL_PROJECTION ); else glMatrixMode( GL_MODELVIEW ); }

const RS_MATRIXMODE OpenGLRenderDevice::MatrixModeGet() const { return m_matrixMode; }

void OpenGLRenderDevice::MatrixLoadIdentity() { glLoadIdentity(); }

void OpenGLRenderDevice::MatrixLoad( const Matrix4x4& mat ) { Matrix4x4 m = mat.GetTranspose(); glLoadMatrixf( (float*)(m.m_Mat) ); }

void OpenGLRenderDevice::MatrixPush() { glPushMatrix(); }

void OpenGLRenderDevice::MatrixPop() { glPopMatrix(); }

void OpenGLRenderDevice::MatrixScale( float x, float y, float z ) { glScalef( x, y, z ); }

void OpenGLRenderDevice::MatrixTranslation( float x, float y, float z ) { glTranslatef( x, y, z ); }

void OpenGLRenderDevice::MatrixRotation( float angle, float x, float y, float z ) { glRotatef( angle, x, y, z ); }

void OpenGLRenderDevice::MatrixMultiply(const Matrix4x4& m) { Matrix4x4 mat=m.GetTranspose(); glMultMatrixf( (float*)(m.m_Mat) ); }

Matrix4x4 OpenGLRenderDevice::MatrixGet() { Matrix4x4 rv;

if ( m_matrixMode==RSMM_PROJECTION ) glGetFloatv(GL_PROJECTION_MATRIX, (float *) rv.m_Mat); else glGetFloatv(GL_MODELVIEW_MATRIX, (float *) rv.m_Mat); return rv.GetTranspose(); }

//------------------------------------------------------------------ // Rendering functions //-- void OpenGLRenderDevice::BeginRendering() { }

void OpenGLRenderDevice::EndRendering() { }

void OpenGLRenderDevice::SwapBuffers() { HDC hdc = ::GetDC( m_hWnd ); ::SwapBuffers( hdc ); }

bool OpenGLRenderDevice::DrawPrimitives( RS_PRIMITIVETYPE primitiveType, VertexBuffer* pVB, DWORD baseVertex, DWORD primitiveCount )

{ if ( pVB==NULL ) return 0;

// Convert primitive type //-- GLenum PT; DWORD count; if ( !GetOpenGLPrimitiveType( primitiveType, primitiveCount, &PT, &count ) ) return 0;

// Say that the VB will be the source for our draw primitive calls //-- if ( !pVB->PrepareForDrawing() ) return 0;

// Draw primitives //-- glDrawArrays( PT, baseVertex, count ); return (GL_NO_ERROR == glGetError()); }

void OpenGLRenderDevice::UseTexture( Texture* pTex ) { pTex->Use(); }

//------------------------------------------------------------------ // Render state switches functions //-- bool OpenGLRenderDevice::SetRenderState( RS_RENDERSTATETYPE state, DWORD value ) { switch (state) { case RSRS_ZENABLE: if (value==1) glEnable(GL_DEPTH_TEST); else glDisable(GL_DEPTH_TEST); break;

case RSRS_LIGHTINGENABLE: if (value==1) glEnable(GL_LIGHTING); else glDisable(GL_LIGHTING); break;

case RSRS_CULLINGENABLE: switch (value) { case 0: glDisable(GL_CULL_FACE); break;

case 1: glEnable(GL_CULL_FACE); break;

default: return false; }; break;

case RSRS_FILLMODE: switch (value) { case RSFILL_WIREFRAME: glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); break;

case RSFILL_SOLID: glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); break;

default: return false; }; break;

default: return false; } return false; }

DWORD OpenGLRenderDevice::GetRenderState( RS_RENDERSTATETYPE state ) { GLint rv= 0;

switch (state) { case RSRS_ZENABLE: glGetIntegerv(GL_DEPTH_TEST, &rv); return rv;

case RSRS_LIGHTINGENABLE: glGetIntegerv(GL_LIGHTING, &rv); return rv;

case RSRS_CULLINGENABLE: glGetIntegerv(GL_CULL_FACE, &rv); return rv;

case RSRS_FILLMODE: glGetIntegerv(GL_POLYGON_MODE, &rv); if ( rv == GL_LINE ) return RSFILL_WIREFRAME; else return RSFILL_SOLID; } return 0; }

//------------------------------------------------------------------ // Other functions //-- void OpenGLRenderDevice::SetBackgroundColor( float a, float r, float g, float b ) { glClearColor( r, g, b, a ); }

void OpenGLRenderDevice::SetDepthClearValue( float z ) { glClearDepth( z ); }

void OpenGLRenderDevice::SetStencilClearValue( DWORD s ) { glClearStencil( s ); }

void OpenGLRenderDevice::Clear( DWORD flags ) { GLbitfield glFlags = 0;

if ( flags & RSCLR_COLOR ) glFlags |= GL_COLOR_BUFFER_BIT;

if ( flags & RSCLR_ZBUFFER ) glFlags |= GL_DEPTH_BUFFER_BIT;

if ( flags & RSCLR_STENCIL ) glFlags |= GL_STENCIL_BUFFER_BIT;

glClear( glFlags ); }

bool OpenGLRenderDevice::SetViewport( int x, int y, int w, int h ) { if ( (w==0) || (h==0) ) return false;

glViewport( x, h-y, w, h ); if (GL_NO_ERROR != glGetError()) return false;

glScissor( x, h-y, w, h ); if (GL_NO_ERROR != glGetError()) return false;

return true; }

#endif

Currently browsing [RenderSystem.zip] (241,705 bytes) - [Sources/RenderSystem/Matrix4x4.cpp] - (2,854 bytes)

#include <math.h>
#include <memory.h>
#include "Matrix4x4.h"

Matrix4x4::Matrix4x4() { SetIdentity(); }

Matrix4x4::Matrix4x4(const Matrix4x4& mat) { memcpy( m_Mat, mat.m_Mat, 16*sizeof(float) ); }

Matrix4x4& Matrix4x4::operator=(const Matrix4x4& mat) { memcpy( m_Mat, mat.m_Mat, 16*sizeof(float) ); return *this; }

Matrix4x4::~Matrix4x4() { }

void Matrix4x4::SetIdentity(void) { m_Mat[0][0]= 1; m_Mat[1][0]= 0; m_Mat[2][0]= 0; m_Mat[3][0]= 0; m_Mat[0][1]= 0; m_Mat[1][1]= 1; m_Mat[2][1]= 0; m_Mat[3][1]= 0; m_Mat[0][2]= 0; m_Mat[1][2]= 0; m_Mat[2][2]= 1; m_Mat[3][2]= 0; m_Mat[0][3]= 0; m_Mat[1][3]= 0; m_Mat[2][3]= 0; m_Mat[3][3]= 1; }

void Matrix4x4::SetPerspective(float ncp, float fcp, float fov, float aspect) { float c,s,Q; c= (float) cos( 0.5f*RS_DEGTORAD(fov) ); s= (float) sin( 0.5f*RS_DEGTORAD(fov) ); Q= s/(1.0f-ncp/fcp); m_Mat[0][0]= c/(aspect*Q*ncp); m_Mat[1][0]= 0; m_Mat[2][0]= 0; m_Mat[3][0]= 0; m_Mat[0][1]= 0; m_Mat[1][1]= c/(Q*ncp); m_Mat[2][1]= 0; m_Mat[3][1]= 0; m_Mat[0][2]= 0; m_Mat[1][2]= 0; m_Mat[2][2]= -1/ncp; m_Mat[3][2]= -s/(Q*ncp); m_Mat[0][3]= 0; m_Mat[1][3]= 0; m_Mat[2][3]= -1; m_Mat[3][3]= 0; }

void Matrix4x4::SetRotation(float angle, float x, float y, float z) { float length; float c,s,t; float theta = RS_DEGTORAD(angle); // normalize //-- length = sqrtf(x*x + y*y + z*z); // too close to 0, can't make a normalized vector //-- if (length < 0.000001f) return; x /= length; y /= length; z /= length; // do the trig //-- c = cosf(theta); s = sinf(theta); t = 1-c; // build the rotation matrix //-- m_Mat[0][0] = t*x*x + c; m_Mat[0][1] = t*x*y - s*z; m_Mat[0][2] = t*x*z + s*y; m_Mat[0][3] = 0; m_Mat[1][0] = t*x*y + s*z; m_Mat[1][1] = t*y*y + c; m_Mat[1][2] = t*y*z - s*x; m_Mat[1][3] = 0; m_Mat[2][0] = t*x*z - s*y; m_Mat[2][1] = t*y*z + s*x; m_Mat[2][2] = t*z*z + c; m_Mat[2][3] = 0; m_Mat[3][0] = 0; m_Mat[3][1] = 0; m_Mat[3][2] = 0; m_Mat[3][3] = 1; }

void Matrix4x4::SetTranslation(float x, float y, float z) { m_Mat[0][3] = x; m_Mat[1][3] = y; m_Mat[2][3] = z; }

void Matrix4x4::SetScale(float x, float y, float z) { m_Mat[0][0] = x; m_Mat[1][1] = y; m_Mat[2][2] = z; }

void Matrix4x4::Multiply(const Matrix4x4& mat) { Matrix4x4 res; int i,j,k; for (i=0; i<4; i++) { for (j=0; j<4; j++) { res.m_Mat[i][j] = 0.0; for (k=0; k<4; k++) { res.m_Mat[i][j] += m_Mat[i][k]*mat.m_Mat[k][j]; } } }

*this = res; }

Matrix4x4 Matrix4x4::GetTranspose(void) const { Matrix4x4 rv; int i,j; for (i=0; i<4; i++) { for (j=0; j<4; j++) { rv.m_Mat[i][j]= m_Mat[j][i]; } }

return rv; }

Currently browsing [RenderSystem.zip] (241,705 bytes) - [Sources/RenderSystem/RenderTypeDefs.h] - (3,100 bytes)

#ifndef _RENDERTYPEDEFS_H_INCLUDED_
#define _RENDERTYPEDEFS_H_INCLUDED_

#include <windows.h> #include <windef.h>

/** * Base Api used to render primitives */ typedef enum _BASE_API { RSAPI_DIRECT3D, /** Direct3D is used as the base API */ RSAPI_OPENGL, /** OpenGL is used as the base API */ } RS_BASEAPI;

/** * Formats to use for surfaces */ typedef enum _PIXELFORMAT { RSFMT_A8R8G8B8, /** 32 bits per pixel (ARGB) */ } RS_FORMAT;

/** * Current matrix mode in the render device (indicate which * matrix is modified by matrix function calls). */ typedef enum _MATRIX_MODE { RSMM_PROJECTION = 0, /** Projection matrix mode */ RSMM_MODELVIEW = 1, /** Model-view matrix mode */ } RS_MATRIXMODE;

/** * Fill mode used to render primitives on screen */ typedef enum _FILLMODE { RSFILL_WIREFRAME = 0x0000, /** Render primitives using wireframe mode */ RSFILL_SOLID = 0x0001, /** Render filled primitives */ } RS_FILLMODE;

/** * List of the render states that can be set on a device. */ typedef enum _RENDERSTATETYPE { RSRS_FILLMODE, /** Set to one of the _FILLMODE values */ RSRS_ZENABLE, /** Enable z-buffer testing. Set to 1 (True) or 0 (False) */ RSRS_CULLINGENABLE, /** Enable CCW backface culling. Set to 1 (True) or 0 (False) */ RSRS_LIGHTINGENABLE, /** Enable lighting. Set to 1 (True) or 0 (False) */ } RS_RENDERSTATETYPE;

/** * Flags used to describe the format of a vertex in a vertex buffer */ typedef enum __VERTEXFORMATFLAGS { RSVF_XYZ = 0x0001, /** Untransformed XYZ value set. */ RSVF_XYZRHW = 0x0002, /** transformed XYZRHW value set. */ RSVF_NORMAL = 0x0004, /** XYZ normal value set */ RSVF_DIFFUSE = 0x0008, /** RGBA diffuse color value set */ RSVF_TEXCOORD = 0x0010, /** Texture vertex flag. */ } RS_VERTEXFORMATFLAGS;

/** * Supported primitive types */ typedef enum __PRIMITIVETYPE { RSPT_POINTLIST, /** Specifies a point list */ RSPT_LINELIST, /** Specifies a line list */ RSPT_LINESTRIP, /** Specifies a line strip */ RSPT_TRIANGLELIST, /** Specifies a triangle list */ RSPT_TRIANGLESTRIP, /** Specifies a triangle strip */ RSPT_TRIANGLEFAN, /** Specifies a triangle fan */ } RS_PRIMITIVETYPE;

/** * Valid clear flags */ typedef enum _CLEAR_FLAG { RSCLR_COLOR = 0x0001, /** Clear color buffer */ RSCLR_ZBUFFER = 0x0002, /** Clear z-buffer */ RSCLR_STENCIL = 0x0004, /** Clear stencil buffer */ } RS_CLEAR_FLAG;

/** * A handy macro to release a pointer */ #ifndef SAFE_RELEASE #define SAFE_RELEASE( ptr ) { if (ptr!=NULL) { ptr->Release(); ptr = NULL; } } #endif

/** * A handy macro to delete a pointer */ #ifndef SAFE_DELETE #define SAFE_DELETE( ptr ) { if (ptr!=NULL) { delete ptr; ptr = NULL; } } #endif

/** * A handy macro to delete a pointer to an array */ #ifndef SAFE_DELETEARRAY #define SAFE_DELETEARRAY( ptr ) { if (ptr!=NULL) { delete [] ptr; ptr = NULL; } } #endif

#endif

Currently browsing [RenderSystem.zip] (241,705 bytes) - [Sources/RenderSystem/Matrix4x4.h] - (4,188 bytes)

#ifndef _Matrix4x4_h_
#define _Matrix4x4_h_

#define RS_DEGTORAD(X) ((X)*3.1415926f/180.0f) #define RS_RADTODEG(X) ((X)*180.0f/3.1415926f)

class Matrix4x4 { public: Matrix4x4(); Matrix4x4(const Matrix4x4& mat); Matrix4x4& operator=(const Matrix4x4& mat); ~Matrix4x4();

void SetIdentity(); void SetTranslation(float x, float y, float z); void SetRotation(float angle, float x, float y, float z); void SetScale(float x, float y, float z); void SetPerspective(float ncp, float fcp, float fov, float aspect); void Multiply(const Matrix4x4& mat); Matrix4x4 GetTranspose (void) const;

public: float m_Mat[4][4]; };

#endif





























////////////////////////////////////////////////////////////////////////////////// #if 0 class Matrix4x4 { public: Matrix4x4 (); ~Matrix(); Matrix4x4 (Double a11, Double a12, Double a13, Double a14, Double a21, Double a22, Double a23, Double a24, Double a31, Double a32, Double a33, Double a34, Double a41, Double a42, Double a43, Double a44 ); Matrix4x4 (const Matrix4x4 &m );

void setValue ( const Matrix4x4 &m ); void getValue ( Matrix4x4 &m ) const; const Matrix4x4& getValue () const;

void makeIdentity (); static Matrix4x4 identity ();

void setRotate (const RotationEuler &q ); void setRotate (const Quaternion &q ); void setScale ( Double s ); void setScale ( const Vec3f &s ); void setTranslate ( const Vec3f &t ); Matrix4x4 inverse (void) const; Matrix4x4 transpose (void) const; Matrix4x4& multRight ( const Matrix4x4 &m ); Matrix4x4& multLeft ( const Matrix4x4 &m ); void multMatrixVec( const Vec3f &src, Vec3f &dst ) const; void multVecMatrix( const Vec3f &src, Vec3f &dst ) const; void multDirMatrix( const Vec3f &src, Vec3f &dst ) const; void multLineMatrix( const Line &src, Line &dst ) const;

void print(void) const;

operator Double*(); operator Matrix4x4&();

Double* operator [] ( int i ); const Double* operator[] ( int i ) const;

Matrix4x4& operator = ( const Matrix4x4 &m ); Matrix4x4& operator = ( const Matrix4x4 &m ); Matrix4x4& operator = ( const RotationXYZ &q ); Matrix4x4& operator = ( const RotationQuat &q );

Matrix4x4& operator *= ( const Matrix4x4 &m ); friend Matrix4x4 operator *( const Matrix4x4 &m1, const Matrix4x4 &m2 ); friend bool operator == ( const Matrix4x4 & m1, const Matrix4x4 &m2 ); friend bool operator != ( const Matrix4x4 & m1, const Matrix4x4 &m2 ); bool equals( const Matrix4x4 &m, Double tolerance ) const;

Double _mat[4][4]; }; void Matrix4x4::setRotation(const RotationEuler &euler ) { float cosroll,sinroll,cospitch,sinpitch,cosyaw,sinyaw; float sinyawcosroll,sinyawsinroll;

/* Convert to radians */ float roll,pitch,yaw; euler.getRPY(roll,pitch,yaw); roll*=_PI_OVER_180; pitch*=_PI_OVER_180; yaw*=_PI_OVER_180;

/* Calculate trig functions */ cosroll=cos(euler.roll()); sinroll=sin(euler.roll()); cospitch=cos(euler.pitch()); sinpitch=sin(euler.pitch()); cosyaw=cos(euler.yaw()); sinyaw=sin(euler.yaw()); sinyawcosroll=sinyaw*cosroll; sinyawsinroll=sinyaw*sinroll;

/* Form the matrix */

_mat[0][0] = cosyaw*cosroll; //XX _mat[0][1] = sinpitch*sinyawcosroll - cospitch*sinroll; //YX _mat[0][2] = cospitch*sinyawcosroll + sinpitch*sinroll; //ZX _mat[1][0] = cosyaw*sinroll; //XY _mat[1][1] = sinpitch*sinyawsinroll + cospitch*cosroll; //YY _mat[1][2] = cospitch*sinyawsinroll - sinpitch*cosroll; //ZY _mat[2][0] = -sinyaw; //XZ _mat[2][1] = cosyaw*sinpitch; //YZ _mat[2][2] = cosyaw*cospitch; //ZZ } void Matrix4x4::setRotate(const Quaternion &q ) { float sqw = q._angle*q._angle; float sqx = q._x*q._x; float sqy = q._y*q._y; float sqz = q._z*q._z;

float heading = atan(2.0* ((q._x*q._y + q._z*q._angle)/(sqx-sqy-sqz+sqw)));

float bank = atan(2.0* ((q._y*q._z + q._x*q._angle)/(-sqx-sqy+sqz+sqw)));

float attitude = asin(-2.0*(q._x*q._z + q._y*q._angle));

RotationEuler rot(heading,bank,attitude); setRotation(rot); }

#endif

Currently browsing [RenderSystem.zip] (241,705 bytes) - [Sources/RenderSystem/MatrixStack.h] - (4,240 bytes)

#ifndef _MatrixStack_h_
#define _MatrixStack_h_

#include "Matrix4x4.h" #include <list>

class MatrixStack { private: // The stack, represented by a STL container: list //-- std::list< Matrix4x4 > stack;

public: // Constructor //-- MatrixStack() { // Empty the stack //-- stack.clear(); }

// Destruction //-- ~MatrixStack() { stack.clear(); }

// Push currentMatrix on the stack //-- void push( const Matrix4x4& m ) { stack.push_back( m ); }

// Remove the top-most matrix from the stack //-- void pop() { stack.pop_back(); }

// Get top most matrix //-- const Matrix4x4& getCurrent() const { return stack.back(); } };

#endif





























////////////////////////////////////////////////////////////////////////////////// #if 0 class Matrix4x4 { public: Matrix4x4 (); ~Matrix(); Matrix4x4 (Double a11, Double a12, Double a13, Double a14, Double a21, Double a22, Double a23, Double a24, Double a31, Double a32, Double a33, Double a34, Double a41, Double a42, Double a43, Double a44 ); Matrix4x4 (const Matrix4x4 &m );

void setValue ( const Matrix4x4 &m ); void getValue ( Matrix4x4 &m ) const; const Matrix4x4& getValue () const;

void makeIdentity (); static Matrix4x4 identity ();

void setRotate (const RotationEuler &q ); void setRotate (const Quaternion &q ); void setScale ( Double s ); void setScale ( const Vec3f &s ); void setTranslate ( const Vec3f &t ); Matrix4x4 inverse (void) const; Matrix4x4 transpose (void) const; Matrix4x4& multRight ( const Matrix4x4 &m ); Matrix4x4& multLeft ( const Matrix4x4 &m ); void multMatrixVec( const Vec3f &src, Vec3f &dst ) const; void multVecMatrix( const Vec3f &src, Vec3f &dst ) const; void multDirMatrix( const Vec3f &src, Vec3f &dst ) const; void multLineMatrix( const Line &src, Line &dst ) const;

void print(void) const;

operator Double*(); operator Matrix4x4&();

Double* operator [] ( int i ); const Double* operator[] ( int i ) const;

Matrix4x4& operator = ( const Matrix4x4 &m ); Matrix4x4& operator = ( const Matrix4x4 &m ); Matrix4x4& operator = ( const RotationXYZ &q ); Matrix4x4& operator = ( const RotationQuat &q );

Matrix4x4& operator *= ( const Matrix4x4 &m ); friend Matrix4x4 operator *( const Matrix4x4 &m1, const Matrix4x4 &m2 ); friend bool operator == ( const Matrix4x4 & m1, const Matrix4x4 &m2 ); friend bool operator != ( const Matrix4x4 & m1, const Matrix4x4 &m2 ); bool equals( const Matrix4x4 &m, Double tolerance ) const;

Double _mat[4][4]; }; void Matrix4x4::setRotation(const RotationEuler &euler ) { float cosroll,sinroll,cospitch,sinpitch,cosyaw,sinyaw; float sinyawcosroll,sinyawsinroll;

/* Convert to radians */ float roll,pitch,yaw; euler.getRPY(roll,pitch,yaw); roll*=_PI_OVER_180; pitch*=_PI_OVER_180; yaw*=_PI_OVER_180;

/* Calculate trig functions */ cosroll=cos(euler.roll()); sinroll=sin(euler.roll()); cospitch=cos(euler.pitch()); sinpitch=sin(euler.pitch()); cosyaw=cos(euler.yaw()); sinyaw=sin(euler.yaw()); sinyawcosroll=sinyaw*cosroll; sinyawsinroll=sinyaw*sinroll;

/* Form the matrix */

_mat[0][0] = cosyaw*cosroll; //XX _mat[0][1] = sinpitch*sinyawcosroll - cospitch*sinroll; //YX _mat[0][2] = cospitch*sinyawcosroll + sinpitch*sinroll; //ZX _mat[1][0] = cosyaw*sinroll; //XY _mat[1][1] = sinpitch*sinyawsinroll + cospitch*cosroll; //YY _mat[1][2] = cospitch*sinyawsinroll - sinpitch*cosroll; //ZY _mat[2][0] = -sinyaw; //XZ _mat[2][1] = cosyaw*sinpitch; //YZ _mat[2][2] = cosyaw*cospitch; //ZZ } void Matrix4x4::setRotate(const Quaternion &q ) { float sqw = q._angle*q._angle; float sqx = q._x*q._x; float sqy = q._y*q._y; float sqz = q._z*q._z;

float heading = atan(2.0* ((q._x*q._y + q._z*q._angle)/(sqx-sqy-sqz+sqw)));

float bank = atan(2.0* ((q._y*q._z + q._x*q._angle)/(-sqx-sqy+sqz+sqw)));

float attitude = asin(-2.0*(q._x*q._z + q._y*q._angle));

RotationEuler rot(heading,bank,attitude); setRotation(rot); }

#endif

Currently browsing [RenderSystem.zip] (241,705 bytes) - [Sources/RenderSystem/D3DTexture.h] - (4,140 bytes)

#ifndef _D3DTEXTURE_H_INCLUDED_
#define _D3DTEXTURE_H_INCLUDED_

#include "Texture.h" #include <d3d9.h>

/** * This is Direct3D 9 implementation of Texture. * * Inspired by the work of Tobin Schwaiger-Hastanan */ class D3DTexture : public Texture { protected: /// disable default constructor //-- D3DTexture(); /// disable copy constructor //-- D3DTexture( const D3DTexture& ); /// disable assignment operator //-- D3DTexture& operator =( const D3DTexture& );

public: /** * Constructor used to create vertex buffer. * @param pD3DDevice Direct 3D Device * @param Width width of the texture * @param Height height of the texture * @param format format of the texture * @param isDynamic specifies that texture is dynamic. [default: false] * @param dwMipMaLevels Number of mipmap levels to generate. Value of * 0 will generate all the levels till 1x1. [default: 0] */ D3DTexture( LPDIRECT3DDEVICE9 pD3DDevice, DWORD Width, DWORD Height, RS_FORMAT format, bool isDynamic = false, DWORD dwMipMapLevelNum = 0 );

/// destructor //-- ~D3DTexture(); /// for the following methods, see Texture //-- bool Use();

bool Lock(); bool Unlock(); const bool IsLocked() const { return m_bIsLocked; }

void* GetData(); const DWORD GetWidth() const { return m_dwWidth; } const DWORD GetHeight() const { return m_dwHeight; } const DWORD GetPitch() const { return m_dwPitch; } const RS_FORMAT GetFormat() const { return m_Format; } const DWORD GetMipMapLevelsNum() const { return m_dwMipMapLevelNum; }

inline void SetPixel4f( float a, float r, float g, float b ); inline void SetPixel4uc( unsigned char a, unsigned char r, unsigned char g, unsigned char b );

//---------------------------------------------------------------------- // D3D related methods //-- /** * Returns the D3D Vertex buffer created by this class. * This is a D3DTexture specific method. * * @return pointer to a Direct 3D Vertex Buffer. */ const LPDIRECT3DTEXTURE9 GetD3DTexture() const { return m_pD3DTexture; }

/** * Returns the D3D texture format. * This is a D3DTexture specific method. * * @return The format of the texture in D3D type */ const D3DFORMAT GetD3DFormat() const { return m_FMT; }

//---------------------------------------------------------------------- // Private members and accessors //-- private: RS_FORMAT m_Format; /// format of the texture DWORD m_dwMipMapLevelNum; /// number of mipmap levels DWORD m_dwWidth; /// texture width DWORD m_dwHeight; /// texture height DWORD m_dwPitch; /// pitch of the texture bool m_bIsLocked; /// flag to specify if buffer is locked bool m_bIsDynamic; /// flag to specify if buffer is holding dynamic data void* m_pBuffer; /// pointer to vertex data unsigned char* m_pCurrentPixel;

//---------------------------------------------------------------------- // D3D related members //-- LPDIRECT3DDEVICE9 m_pD3DDevice; /// d3d device LPDIRECT3DTEXTURE9 m_pD3DTexture; /// d3d texture LPDIRECT3DTEXTURE9 m_pD3DRamTexture; /// d3d texture used when locking static texture D3DFORMAT m_FMT; /// d3d format };

inline void D3DTexture::SetPixel4f( float a, float r, float g, float b ) { if ( m_Format==RSFMT_A8R8G8B8 ) { m_pCurrentPixel[0] = (unsigned char)(255.0f*b); m_pCurrentPixel[1] = (unsigned char)(255.0f*g); m_pCurrentPixel[2] = (unsigned char)(255.0f*r); m_pCurrentPixel[3] = (unsigned char)(255.0f*a); m_pCurrentPixel+=4; } }

inline void D3DTexture::SetPixel4uc( unsigned char a, unsigned char r, unsigned char g, unsigned char b ) { if ( m_Format==RSFMT_A8R8G8B8 ) { m_pCurrentPixel[0] = b; m_pCurrentPixel[1] = g; m_pCurrentPixel[2] = r; m_pCurrentPixel[3] = a; m_pCurrentPixel+=4; } }





#endif

Currently browsing [RenderSystem.zip] (241,705 bytes) - [Sources/RenderSystem/Texture.h] - (2,281 bytes)

#ifndef _TEXTURE_H_INCLUDED_
#define _TEXTURE_H_INCLUDED_

#include "RenderTypeDefs.h"

/** * This is an abstract class that provides an interface on top of various * implementations of textures. * */ class Texture { public: virtual ~Texture() {} /** * Locks the texture (usually for writing)... * @return True if the lock request succeeded. False else. */ virtual bool Lock() = 0;

/** * Unlocks the texture * @return True if the unlock request succeeded. False else. */ virtual bool Unlock() = 0;

/** * Determines if the texture is locked or not. * @return boolean value specifying if texture is locked or not. */ virtual const bool IsLocked() const = 0;

/** * Returns a pointer to the raw texture data. * This should only be called when texture is locked. * @return pointer to raw vertex data. */ virtual void* GetData() = 0; /** * Get width of the texture */ virtual const DWORD GetWidth() const = 0;

/** * Get height of the texture */ virtual const DWORD GetHeight() const = 0; /** * Get pitch of the texture (length of a row of pixels) * This might differ from the width of the texture. For instance, a * non-power of two texture might have a width of 120 and a pitch of * 128. */ virtual const DWORD GetPitch() const = 0;

/** * returns the format of the texture. (see RS_PIXELFORMAT type) * @return Pixel format of the texture. */ virtual const RS_FORMAT GetFormat() const = 0;

/** * This method is called to activate the texture before rendering * textured primitives. */ virtual bool Use() = 0;

/** * Use this to set current pixel in the texture (helps to solve * Api dependant ordering of rgba components) */ virtual void SetPixel4f( float a, float r, float g, float b ) = 0;

/** * Use this to set current pixel in the texture (helps to solve * Api dependant ordering of rgba components) */ virtual void SetPixel4uc( unsigned char a, unsigned char r, unsigned char g, unsigned char b ) = 0; };

#endif

Currently browsing [RenderSystem.zip] (241,705 bytes) - [Sources/RenderSystem/RenderObjectFactory.h] - (1,907 bytes)

#ifndef _RENDEROBJECTFACTORY_H_INCLUDED_
#define _RENDEROBJECTFACTORY_H_INCLUDED_

#include "VertexBuffer.h" #include "Texture.h"

/** * This is an abstract class that provides an interface on top of various * implementations of render object (textures, vertex buffers, ...) * factories. * * @author Vincent Prat */ class RenderObjectFactory { //---------------------------------------------------------------------- // Public methods //-- public:

/** * Default object constructor */ RenderObjectFactory() {}

/** * Object destructor */ virtual ~RenderObjectFactory() {}

//------------------------------------------------------------------ // Object creation functions //-- /** * This function should be used to allocate memory for a new vertex * buffer. * @param count Number of vertex to be created * @param format Format of vertex buffer ( See format flags in VertexBuffer) * @param isDynamic Specifies that vertex buffer is dynamic. [default: true] * @return A pointer to the new vertex buffer or NULL if it could not be created. */ virtual VertexBuffer* CreateVertexBuffer( int count, DWORD format, bool isDynamic = true ) = 0;

/** * This function should be used to allocate memory for a new texture * @param Width width of the texture * @param Height height of the texture * @param format format of the texture * @param isDynamic specifies that texture is dynamic. [default: false] * @param dwMipMaLevels Number of mipmap levels to generate. Value of * 0 will generate all the levels till 1x1. [default: 0] * @return A pointer to the new texture or NULL if it could not be created. */ virtual Texture* CreateTexture( DWORD Width, DWORD Height, RS_FORMAT format, bool isDynamic = false, DWORD dwMipMapLevelNum = 0 ) = 0; };

#endif

Currently browsing [RenderSystem.zip] (241,705 bytes) - [Sources/RenderSystem/Sphere.h] - (555 bytes)

#ifndef _Sphere_h_
#define _Sphere_h_

#include "RenderDevice.h" #include "VertexBuffer.h"

/// This class is only a helper to fill a vertex buffer. In a real engine, /// your sphere class could have many other responsabilities such as to render /// by itself, its own transformation matrix, ... class Sphere { public: Sphere( RenderDevice* pRenderDevice, float radius, DWORD slices ); ~Sphere(); void Draw( RenderDevice* pRenderDevice );

public: VertexBuffer* m_pVertexBuffer; float m_fRadius; DWORD m_dwSlices; };

#endif

Currently browsing [RenderSystem.zip] (241,705 bytes) - [Sources/RenderSystem/OpenGLVertexBuffer.cpp] - (4,186 bytes)

#ifdef COMPILE_OPENGL_IMPLEMENTATION

#include "OpenGLVertexBuffer.h"

OpenGLVertexBuffer::OpenGLVertexBuffer( int count, DWORD format, bool isDynamic ) : VertexBuffer() { DWORD size = 0; m_dwFormat = format; m_dwVertexCount = count;

if( format & RSVF_XYZ ) { m_dwVertexCoordNum = 3; size += sizeof( float ) * 3; } else if( format & RSVF_XYZRHW ) { m_dwVertexCoordNum = 4; size += sizeof( float ) * 4; }

if( format & RSVF_NORMAL ) { size += sizeof( float ) * 3; }

if( format & RSVF_DIFFUSE ) { size += sizeof( DWORD ); }

if( format & RSVF_TEXCOORD ) { size += sizeof( float ) * 2; } m_dwStrideVertex = size; m_bIsDynamic = isDynamic; m_bIsLocked = false;

m_pVertex = NULL; m_pColor = NULL; m_pNormal = NULL; m_pTexCoord = NULL;

m_pGLVertices = NULL; m_pGLNormals = NULL; m_pGLColors = NULL; m_pGLTexCoords = NULL;

// Allocate memory for vertex data //-- if ( (m_dwFormat & RSVF_XYZ) || (m_dwFormat & RSVF_XYZRHW) ) m_pGLVertices = new float[ m_dwVertexCoordNum*m_dwVertexCount ];

if ( m_dwFormat & RSVF_NORMAL ) m_pGLNormals = new float[ 3*m_dwVertexCount ];

if ( m_dwFormat & RSVF_DIFFUSE ) m_pGLColors = new float[ 4*m_dwVertexCount ];

if ( m_dwFormat & RSVF_TEXCOORD ) m_pGLTexCoords= new float[ 2*m_dwVertexCount ]; }

OpenGLVertexBuffer::~OpenGLVertexBuffer() { if ( m_pGLVertices != NULL ) { delete [] m_pGLVertices; m_pGLVertices = NULL; }

if ( m_pGLNormals != NULL ) { delete [] m_pGLNormals; m_pGLNormals = NULL; }

if ( m_pGLColors != NULL ) { delete [] m_pGLColors; m_pGLColors = NULL; }

if ( m_pGLTexCoords != NULL ) { delete [] m_pGLTexCoords; m_pGLTexCoords = NULL; } }

bool OpenGLVertexBuffer::Lock() { m_bIsLocked = true;

m_pVertex = m_pGLVertices; m_pColor = m_pGLColors; m_pNormal = m_pGLNormals; m_pTexCoord = m_pGLTexCoords;

return true; }

bool OpenGLVertexBuffer::Unlock() { m_bIsLocked = false;

m_pVertex = NULL; m_pColor = NULL; m_pNormal = NULL; m_pTexCoord = NULL;

return true; }

void* OpenGLVertexBuffer::GetVertexData() { return NULL; }

void OpenGLVertexBuffer::Vertex( float x, float y, float z ) { m_pVertex[ 0 ] = x; m_pVertex[ 1 ] = y; m_pVertex[ 2 ] = z;

m_pVertex += 3; }

void OpenGLVertexBuffer::Vertex( float x, float y, float z, float w ) { m_pVertex[ 0 ] = x; m_pVertex[ 1 ] = y; m_pVertex[ 2 ] = z; m_pVertex[ 3 ] = w;

m_pVertex += 4; }

void OpenGLVertexBuffer::Normal( float x, float y, float z ) { m_pNormal[ 0 ] = x; m_pNormal[ 1 ] = y; m_pNormal[ 2 ] = z;

m_pNormal += 3; }

void OpenGLVertexBuffer::Diffuse( float r, float g, float b, float a ) { m_pColor[ 0 ] = r; m_pColor[ 1 ] = g; m_pColor[ 2 ] = b; m_pColor[ 3 ] = a;

m_pColor += 4; }

void OpenGLVertexBuffer::TexVertex( float u, float v ) { m_pTexCoord[ 0 ] = u; m_pTexCoord[ 1 ] = v;

m_pTexCoord += 2; }

bool OpenGLVertexBuffer::PrepareForDrawing() { // Set pointers to arrays //-- if ( m_pGLVertices != NULL ) { glEnableClientState(GL_VERTEX_ARRAY); glVertexPointer( m_dwVertexCoordNum, GL_FLOAT, 0, m_pGLVertices ); } else { glDisableClientState(GL_VERTEX_ARRAY); }

if ( m_pGLNormals != NULL ) { glEnableClientState(GL_NORMAL_ARRAY); glNormalPointer( GL_FLOAT, 0, m_pGLNormals ); } else { glDisableClientState(GL_NORMAL_ARRAY); }

if ( m_pGLColors != NULL ) { glEnableClientState(GL_COLOR_ARRAY); glColorPointer( 4, GL_FLOAT, 0, m_pGLColors ); } else { glDisableClientState(GL_COLOR_ARRAY); }

if ( m_pGLTexCoords != NULL ) { glEnableClientState(GL_TEXTURE_COORD_ARRAY); glTexCoordPointer( 2, GL_FLOAT, 0, m_pGLTexCoords ); } else { glDisableClientState(GL_TEXTURE_COORD_ARRAY); }

return ( GL_NO_ERROR == glGetError() ); }

#endif

Currently browsing [RenderSystem.zip] (241,705 bytes) - [Sources/RenderSystem/Sphere.cpp] - (2,227 bytes)

#include <math.h>
#include "Sphere.h"

Sphere::Sphere( RenderDevice* pRenderDevice, float radius, DWORD slices ) { m_dwSlices = slices; m_fRadius = radius;

// Create VB //-- m_pVertexBuffer = pRenderDevice->CreateVertexBuffer( 2*(m_dwSlices+1)*m_dwSlices, RSVF_XYZ | RSVF_TEXCOORD | RSVF_NORMAL, false );

// Fill VB (build triangle stripes) // I know we could use fans at the poles to reduce // vertex count but I don't care for this sample. //-- DWORD i=0, j=0; float Phi=0, Theta=2*3.1415926f; float PhiInc = 3.1415926f/m_dwSlices; float ThetaInc = -2*3.1415926f/m_dwSlices; float Pos[3]; // Position of current point float Norm; // Norm of position vector (used to compute normal) m_pVertexBuffer->Lock();

for ( i=0; i<m_dwSlices; i++ ) { Theta = 0;

for ( j=0; j<=m_dwSlices; j++ ) { // Position and normal computation for 1st point of strip //-- Pos[0] = radius*cosf(Theta)*sinf(Phi); Pos[1] = radius*cosf(Phi); Pos[2] = radius*sinf(Theta)*sinf(Phi); Norm = sqrtf( Pos[0]*Pos[0] + Pos[1]*Pos[1] + Pos[2]*Pos[2] );

m_pVertexBuffer->Normal( Pos[0]/Norm, Pos[1]/Norm, Pos[2]/Norm ); m_pVertexBuffer->TexVertex( Theta/(2*3.1415926f), Phi/3.1415926f ); m_pVertexBuffer->Vertex( Pos[0], Pos[1], Pos[2] );

// Position and normal computation for 2nd point of strip //-- Pos[0] = radius*cosf(Theta)*sinf(Phi+PhiInc); Pos[1] = radius*cosf(Phi+PhiInc); Pos[2] = radius*sinf(Theta)*sinf(Phi+PhiInc); Norm = sqrtf( Pos[0]*Pos[0] + Pos[1]*Pos[1] + Pos[2]*Pos[2] );

m_pVertexBuffer->Normal( Pos[0]/Norm, Pos[1]/Norm, Pos[2]/Norm ); m_pVertexBuffer->TexVertex( Theta/(2*3.1415926f), (Phi+PhiInc)/3.1415926f ); m_pVertexBuffer->Vertex( Pos[0], Pos[1], Pos[2] );

Theta += ThetaInc; }

Phi += PhiInc; }

m_pVertexBuffer->Unlock(); }

Sphere::~Sphere() { // Release VB memory //-- SAFE_DELETE( m_pVertexBuffer ); }

void Sphere::Draw( RenderDevice* pRenderDevice ) { DWORD i=0; for ( i=0; i<m_dwSlices; i++ ) { pRenderDevice->DrawPrimitives( RSPT_TRIANGLESTRIP, m_pVertexBuffer, i*2*(m_dwSlices+1), 2*m_dwSlices ); }

}

Currently browsing [RenderSystem.zip] (241,705 bytes) - [Sources/RenderSystem/VertexBuffer.h] - (3,935 bytes)

#ifndef _VERTEXBUFFER_H_INCLUDED_
#define _VERTEXBUFFER_H_INCLUDED_

#include "RenderTypeDefs.h"

/** * This is an abstract class that provides an interface on top of various * implementations of vertex buffers or similar structures. * * Inspired by the work of Tobin Schwaiger-Hastanan */ class VertexBuffer { public: virtual ~VertexBuffer() {} /** * Locks the vertex buffer (usually for writing)... * @return True if the lock request succeeded. False else. */ virtual bool Lock() = 0;

/** * Unlocks the vertex buffer. * @return True if the unlock request succeeded. False else. */ virtual bool Unlock() = 0;

/** * Determines if the vertex buffer is locked or not. * @return boolean value specifying if vertex buffer is locked or not. */ virtual const bool IsLocked() const = 0;

/** * Returns a pointer to the raw vertex data. * This should only be called when vertex buffer is locked. * @return pointer to raw vertex data. */ virtual void* GetVertexData() = 0; /** * returns the number of vertex currently in the vertex buffer * @return number of vertex in vertex buffer. */ virtual const DWORD GetVertexCount() const = 0;

/** * returns the vertex format of the vertex buffer. (see _VERTEXFORMATFLAGS type) * @return vertex format of the vertex buffer. */ virtual const DWORD GetVertexFormat() const = 0;

/** * returns the width in bytes of a single vertex described by the format. * @return width in bytes of a single vertex described by the format. */ virtual const DWORD GetVertexStride() const = 0;

/** * Specifies untransformed vertex data. Should be last call * for each vertex. That is after the normal, color, and * texture coordinate calls are made for the vertex. * Note: should be used when format includes FORMAT_XYZ * * @param x x coordinate. * @param y y coordinate. * @param z z coordinate. */ virtual void Vertex( float x, float y, float z ) = 0;

/** * Specifies transformed vertex data. Should be last call * for each vertex. That is after the normal, color, and * texture coordinate calls are made for the vertex. * Note: should be used when format includes FORMAT_XYZRHW * * @param x x coordinate. * @param y y coordinate. * @param z z coordinate. * @param w w coordinate. */ virtual void Vertex( float x, float y, float z, float w ) = 0;

/** * Specifies vertex normal data. * Note: should be used when format includes FORMAT_NORMAL * * @param x Normal x value. * @param y Normal y value. * @param z Normal z value. */ virtual void Normal( float x, float y, float z ) = 0;

/** * Specifies diffuse color data. * Note: should be used when format includes FORMAT_DIFFUSE * * @param r Red color value. * @param g Green color value. * @param b Blue color value. * @param a Alpha color value. */ virtual void Diffuse( float r, float g, float b, float a = 1.0f ) = 0;

/** * Specifies texture vertex. Successive calls should be made to this * method if more than one set of texture coordinates need to be * specified. * Note: should be used when format includes FORMAT_TEXTUREFLAG * * @param u U texture coordinate. * @param v V texture coordinate. */ virtual void TexVertex( float u, float v ) = 0;

/** * This method is called to setup the vertex buffer just before a call * to render primitives */ virtual bool PrepareForDrawing() = 0; };

#endif

Currently browsing [RenderSystem.zip] (241,705 bytes) - [Sources/RenderSystem/RenderDevice.h] - (7,909 bytes)

#ifndef _RENDERDEVICE_H_INCLUDED_
#define _RENDERDEVICE_H_INCLUDED_

#include "RenderTypeDefs.h" #include "Matrix4x4.h"

#include "RenderDeviceImplementor.h" #include "RenderObjectFactory.h"

/** * This is a class that is the base of the bridge pattern used to * design our renderer system. * * @author Vincent Prat * @remark Instead of the two functions "UseD3D" and "UseOpenGL", * we could define two derived classes to extend this base class * and that would initialise the factory and the renderDevice * with the relevant implementations. */ class RenderDevice { //---------------------------------------------------------------------- // Public methods //-- public:

/** * Default object constructor * @param hWnd Handle of the window associated to this device */ RenderDevice();

/** * Object destructor */ virtual ~RenderDevice();

/** * Release the implementors */ void Release();

/** * Use D3D implementation */ #ifdef COMPILE_DIRECT3D_IMPLEMENTATION void UseD3D( HWND hWnd, DWORD width, DWORD height ); #endif

/** * Use OpenGL implementation */ #ifdef COMPILE_OPENGL_IMPLEMENTATION void UseOpenGL( HWND hWnd, DWORD width, DWORD height ); #endif

//------------------------------------------------------------------ // Object creation functions //-- /** * This function should be used to allocate memory for a new vertex * buffer. * @param count Number of vertex to be created * @param format Format of vertex buffer ( See format flags in VertexBuffer) * @param isDynamic Specifies that vertex buffer is dynamic. [default: true] * @return A pointer to the new vertex buffer or NULL if it could not be created. */ VertexBuffer* CreateVertexBuffer( int count, DWORD format, bool isDynamic = true ) { return m_pObjectFactory->CreateVertexBuffer( count, format, isDynamic ); }

/** * This function should be used to allocate memory for a new texture * @param Width width of the texture * @param Height height of the texture * @param format format of the texture * @param isDynamic specifies that texture is dynamic. [default: false] * @param dwMipMaLevels Number of mipmap levels to generate. Value of * 0 will generate all the levels till 1x1. [default: 0] * @return A pointer to the new texture or NULL if it could not be created. */ Texture* CreateTexture( DWORD Width, DWORD Height, RS_FORMAT format, bool isDynamic = false, DWORD dwMipMapLevelNum = 0 ) { return m_pObjectFactory->CreateTexture( Width, Height, format, isDynamic, dwMipMapLevelNum ); }

//------------------------------------------------------------------ // Render state switches functions //-- /** * Set a given render state to some value. */ bool SetRenderState( _RENDERSTATETYPE state, DWORD value ) { return m_pRenderDevice->SetRenderState( state, value ); }

/** * Get a render state value */ DWORD GetRenderState( _RENDERSTATETYPE state ) { return m_pRenderDevice->GetRenderState( state ); }

//------------------------------------------------------------------ // Rendering functions //-- /** * Indicate that we are about to begin rendering our scene. */ void BeginRendering() { m_pRenderDevice->BeginRendering(); }

/** * Indicate we have finished to describe what we want to render */ void EndRendering() { m_pRenderDevice->EndRendering(); }

/** * This function should be used to allocate memory for a new vertex * buffer. * @param primitiveType Type of primitives to render * @param pVB Pointer to the buffer holding vertex data * @param baseVertex Index of the vertex from which to begin primitive reading * @param primitiveCount Number of primitives to draw * @return true if it succeeded, false else. */ bool DrawPrimitives( RS_PRIMITIVETYPE primitiveType, VertexBuffer* pVB, DWORD baseVertex, DWORD primitiveCount ) { return m_pRenderDevice->DrawPrimitives( primitiveType, pVB, baseVertex, primitiveCount ); } /** * Display the content of the active backbuffer on screen */ void SwapBuffers() { m_pRenderDevice->SwapBuffers(); }

/** * Say that we will use this texture for following draw primitive * calls that need a texture. */ void UseTexture( Texture* pTex ) { m_pRenderDevice->UseTexture( pTex ); }

//------------------------------------------------------------------ // Tranformation functions //-- /** * Set current matrix mode */ void MatrixModeSet( RS_MATRIXMODE mode ) { m_pRenderDevice->MatrixModeSet(mode); }

/** * Get current matrix mode */ const RS_MATRIXMODE MatrixModeGet() const { return m_pRenderDevice->MatrixModeGet(); }

/** * Set current matrix to identity matrix */ void MatrixLoadIdentity() { m_pRenderDevice->MatrixLoadIdentity(); }

/** * Set current matrix to given matrix */ void MatrixLoad(const Matrix4x4& m) { m_pRenderDevice->MatrixLoad(m); }

/** * Push current matrix on the stack */ void MatrixPush() { m_pRenderDevice->MatrixPush(); }

/** * Remove last matrix from the stack */ void MatrixPop() { m_pRenderDevice->MatrixPop(); }

/** * Multiply current matrix by the matrix corresponding to * provided scale values. */ void MatrixScale( float x, float y, float z ) { m_pRenderDevice->MatrixScale( x, y, z ); }

/** * Multiply current matrix by the matrix corresponding to * provided translation values. */ void MatrixTranslation( float x, float y, float z ) { m_pRenderDevice->MatrixTranslation( x, y, z ); }

/** * Multiply current matrix by the matrix corresponding to * provided rotation angle (in degrees) and axis. */ void MatrixRotation( float angle, float x, float y, float z ) { m_pRenderDevice->MatrixRotation( angle, x, y, z ); }

/** * Multiply current transformation matric by given matrix */ void MatrixMultiply(const Matrix4x4& m) { m_pRenderDevice->MatrixMultiply(m); }

/** * Get current tranformation matrix */ Matrix4x4 MatrixGet() { return m_pRenderDevice->MatrixGet(); }

//------------------------------------------------------------------ // Other functions //-- /** * Set clear values */ void SetBackgroundColor( float a, float r, float g, float b ) { m_pRenderDevice->SetBackgroundColor( a, r, g, b ); }

void SetDepthClearValue( float z ) { m_pRenderDevice->SetDepthClearValue(z); }

void SetStencilClearValue( DWORD s ) { m_pRenderDevice->SetStencilClearValue(s); }

/** * Clears the backbuffer, Z-Buffer and stencil buffer to given * values if relevant flags are set. * @param flags A combination of any of the CLEARFLAG */ void Clear( DWORD flags ) { m_pRenderDevice->Clear(flags); }

/** * Set viewport area */ bool SetViewport( int x, int y, int w, int h ) { return m_pRenderDevice->SetViewport( x, y, w, h ); }

//---------------------------------------------------------------------- // Typedefs, public members and accessors //-- public: const RS_BASEAPI GetBaseApi() const { return m_pRenderDevice->GetBaseApi(); }

//---------------------------------------------------------------------- // Protected member functions //-- protected:

//---------------------------------------------------------------------- // Protected members and accessors //-- protected: /** * Pointer to an implementation of render device */ RenderDeviceImplementor* m_pRenderDevice;

/** * Pointer to an implementation of factory */ RenderObjectFactory* m_pObjectFactory; };

#endif

Currently browsing [RenderSystem.zip] (241,705 bytes) - [Sources/RenderSystem/RenderDevice.cpp] - (1,207 bytes)

#include "RenderDevice.h"

#ifdef COMPILE_DIRECT3D_IMPLEMENTATION #include "D3DRenderDevice.h" #include "D3DRenderObjectFactory.h" #endif

#ifdef COMPILE_OPENGL_IMPLEMENTATION #include "OpenGLRenderDevice.h" #include "OpenGLRenderObjectFactory.h" #endif

RenderDevice::RenderDevice() { m_pRenderDevice = NULL; m_pObjectFactory = NULL; }

RenderDevice::~RenderDevice() { Release(); }

void RenderDevice::Release() { if ( m_pRenderDevice!=NULL ) { delete m_pRenderDevice; m_pRenderDevice = NULL; }

if ( m_pObjectFactory!=NULL ) { delete m_pObjectFactory; m_pObjectFactory = NULL; } }

#ifdef COMPILE_OPENGL_IMPLEMENTATION void RenderDevice::UseOpenGL( HWND hWnd, DWORD width, DWORD height ) { m_pRenderDevice = new OpenGLRenderDevice( hWnd, width, height ); m_pObjectFactory = new OpenGLRenderObjectFactory(); } #endif

#ifdef COMPILE_DIRECT3D_IMPLEMENTATION void RenderDevice::UseD3D( HWND hWnd, DWORD width, DWORD height ) { D3DRenderDevice* pRenderDevice = new D3DRenderDevice( hWnd, width, height ); m_pObjectFactory = new D3DRenderObjectFactory( pRenderDevice->GetD3DDevice() ); m_pRenderDevice = pRenderDevice; } #endif

Currently browsing [RenderSystem.zip] (241,705 bytes) - [Sources/RenderSystem/D3DRenderDevice.h] - (6,319 bytes)

#ifndef _D3DRENDERDEVICE_H_INCLUDED_
#define _D3DRENDERDEVICE_H_INCLUDED_

#include "RenderDeviceImplementor.h" #include "MatrixStack.h"

#include <d3d9.h> #include <d3dx9.h>

/** * This is the implementation of the D3D version of render devices * * @author Vincent Prat */ class D3DRenderDevice : public RenderDeviceImplementor { //---------------------------------------------------------------------- // Public methods //-- public:

/** * Default object constructor * @param hWnd Handle of the window associated to this device */ D3DRenderDevice( HWND hWnd, DWORD width, DWORD height );

/** * Object destructor */ ~D3DRenderDevice();

//------------------------------------------------------------------ // Rendering functions (see base class documentation for this) //-- void SwapBuffers(); void BeginRendering(); void EndRendering(); bool DrawPrimitives( RS_PRIMITIVETYPE primitiveType, VertexBuffer* pVB, DWORD baseVertex, DWORD primitiveCount ); void UseTexture( Texture* pTex );

//------------------------------------------------------------------ // Render state switches functions (see base class documentation // for this) //-- bool SetRenderState( RS_RENDERSTATETYPE state, DWORD value ); DWORD GetRenderState( RS_RENDERSTATETYPE state );

//------------------------------------------------------------------ // Tranformation functions (see base class documentation for this) //-- void MatrixModeSet(RS_MATRIXMODE mode); const RS_MATRIXMODE MatrixModeGet() const; void MatrixLoadIdentity(); void MatrixLoad(const Matrix4x4& m); void MatrixPush(); void MatrixPop(); void MatrixMultiply(const Matrix4x4& m); void MatrixScale( float x, float y, float z ); void MatrixTranslation( float x, float y, float z ); void MatrixRotation( float angle, float x, float y, float z ); Matrix4x4 MatrixGet(); //------------------------------------------------------------------ // Other functions (see base class documentation for this) //-- void SetBackgroundColor( float a, float r, float g, float b ); void SetDepthClearValue( float z ); void SetStencilClearValue( DWORD s ); void Clear( DWORD flags ); bool SetViewport( int x, int y, int w, int h );

//------------------------------------------------------------------ // D3D specific //-- LPDIRECT3DDEVICE9 GetD3DDevice() { return m_pD3DDevice; }

//---------------------------------------------------------------------- // Protected member functions //-- protected: /** * Open the Direct3D DLL to retrieve function pointers * @return True if functions could be retrieved. */ bool OpenD3DDLL();

/** * Close the Direct3D DLL and free function pointers */ void CloseD3DDLL();

/** * Create the D3D device object * @return True if device could be created. */ bool CreateD3DDevice( HWND hWnd, DWORD width, DWORD height );

// Overloaded functions //-- void Release();

//---------------------------------------------------------------------- // Protected members and accessors //-- protected: /** * Pointer to the function to create the Direct3D object. Because * we are using dynamic linking to Direct X */ HMODULE D3D9DLL; HMODULE D3DX9DLL; typedef IDirect3D9* LPDIRECT3D9; typedef LPDIRECT3D9 (__stdcall *LPDIRECT3DCREATE9)(UINT); LPDIRECT3DCREATE9 myDirect3DCreate9;

/** * Pointer to the D3D Object used to create the D3D device */ IDirect3D9* m_pD3D;

/** * Pointer to the D3D device */ IDirect3DDevice9* m_pD3DDevice;

/** * Caps of selected device */ D3DCAPS9 m_D3DCaps;

/** * Return corresponding D3D primitive type */ inline D3DPRIMITIVETYPE GetD3DPrimitiveType( RS_PRIMITIVETYPE pt );

/** * Useful stuff for matrices */

// Our matrix stack to emulate OpenGL internal one MatrixStack m_matrixStack; // The projection and the modelview matrices Matrix4x4 m_projectionMatrix; Matrix4x4 m_modelviewMatrix;

inline void MatrixToD3D( const Matrix4x4* Mat, D3DMATRIX *d3dMat ); inline void MatrixD3DTo( const D3DMATRIX *d3dMat, Matrix4x4* Mat );

/** * Clear values */ D3DCOLOR m_backgroundColor; float m_depthClearValue; DWORD m_stencilClearValue; };



inline D3DPRIMITIVETYPE D3DRenderDevice::GetD3DPrimitiveType( RS_PRIMITIVETYPE pt ) { switch (pt) { case RSPT_POINTLIST: return D3DPT_POINTLIST;

case RSPT_LINELIST: return D3DPT_LINELIST;

case RSPT_LINESTRIP: return D3DPT_LINESTRIP;

case RSPT_TRIANGLELIST: return D3DPT_TRIANGLELIST;

case RSPT_TRIANGLESTRIP: return D3DPT_TRIANGLESTRIP;

case RSPT_TRIANGLEFAN: return D3DPT_TRIANGLEFAN;

default: return D3DPT_POINTLIST; } }

inline void D3DRenderDevice::MatrixToD3D( const Matrix4x4* Mat, D3DMATRIX *d3dMat ) { // Unrolled version for speed d3dMat->m[0][0] = Mat->m_Mat[0][0]; d3dMat->m[0][1] = Mat->m_Mat[1][0]; d3dMat->m[0][2] = Mat->m_Mat[2][0]; d3dMat->m[0][3] = Mat->m_Mat[3][0]; d3dMat->m[1][0] = Mat->m_Mat[0][1]; d3dMat->m[1][1] = Mat->m_Mat[1][1]; d3dMat->m[1][2] = Mat->m_Mat[2][1]; d3dMat->m[1][3] = Mat->m_Mat[3][1]; d3dMat->m[2][0] = Mat->m_Mat[0][2]; d3dMat->m[2][1] = Mat->m_Mat[1][2]; d3dMat->m[2][2] = Mat->m_Mat[2][2]; d3dMat->m[2][3] = Mat->m_Mat[3][2]; d3dMat->m[3][0] = Mat->m_Mat[0][3]; d3dMat->m[3][1] = Mat->m_Mat[1][3]; d3dMat->m[3][2] = Mat->m_Mat[2][3]; d3dMat->m[3][3] = Mat->m_Mat[3][3]; }

inline void D3DRenderDevice::MatrixD3DTo( const D3DMATRIX *d3dMat, Matrix4x4* Mat ) { // Unrolled version for speed Mat->m_Mat[0][0] = d3dMat->m[0][0]; Mat->m_Mat[1][0] = d3dMat->m[0][1]; Mat->m_Mat[2][0] = d3dMat->m[0][2]; Mat->m_Mat[3][0] = d3dMat->m[0][3]; Mat->m_Mat[0][1] = d3dMat->m[1][0]; Mat->m_Mat[1][1] = d3dMat->m[1][1]; Mat->m_Mat[2][1] = d3dMat->m[1][2]; Mat->m_Mat[3][1] = d3dMat->m[1][3]; Mat->m_Mat[0][2] = d3dMat->m[2][0]; Mat->m_Mat[1][2] = d3dMat->m[2][1]; Mat->m_Mat[2][2] = d3dMat->m[2][2]; Mat->m_Mat[3][2] = d3dMat->m[2][3]; Mat->m_Mat[0][3] = d3dMat->m[3][0]; Mat->m_Mat[1][3] = d3dMat->m[3][1]; Mat->m_Mat[2][3] = d3dMat->m[3][2]; Mat->m_Mat[3][3] = d3dMat->m[3][3]; }

#endif

Currently browsing [RenderSystem.zip] (241,705 bytes) - [Sources/RenderSystem/RenderDeviceImplementor.h] - (5,198 bytes)

#ifndef _RENDERDEVICEIMPLEMENTOR_H_INCLUDED_
#define _RENDERDEVICEIMPLEMENTOR_H_INCLUDED_

#include "VertexBuffer.h" #include "Texture.h" #include "RenderTypeDefs.h" #include "Matrix4x4.h"

/** * This is an abstract class that provides an interface on top of various * implementations of render devices (capable of rendering primitives to * screen. * * @author Vincent Prat */ class RenderDeviceImplementor { //---------------------------------------------------------------------- // Public methods //-- public:

/** * Default object constructor */ RenderDeviceImplementor() { }

/** * Object destructor */ virtual ~RenderDeviceImplementor() {}

//------------------------------------------------------------------ // Render state switches functions //-- /** * Set a given render state to some value. */ virtual bool SetRenderState( RS_RENDERSTATETYPE state, DWORD value ) = 0;

/** * Get a render state value */ virtual DWORD GetRenderState( RS_RENDERSTATETYPE state ) = 0;

//------------------------------------------------------------------ // Rendering functions //-- /** * Indicate that we are about to begin rendering our scene. */ virtual void BeginRendering() = 0;

/** * Indicate we have finished to describe what we want to render */ virtual void EndRendering() = 0;

/** * This function should be used to allocate memory for a new vertex * buffer. * @param primitiveType Type of primitives to render * @param pVB Pointer to the buffer holding vertex data * @param baseVertex Index of the vertex from which to begin primitive reading * @param primitiveCount Number of primitives to draw * @return true if it succeeded, false else. */ virtual bool DrawPrimitives( RS_PRIMITIVETYPE primitiveType, VertexBuffer* pVB, DWORD baseVertex, DWORD primitiveCount ) = 0; /** * Display the content of the active backbuffer on screen */ virtual void SwapBuffers() = 0;

/** * Say that we will use this texture for following draw primitive * calls that need a texture. */ virtual void UseTexture( Texture* pTex ) = 0;

//------------------------------------------------------------------ // Tranformation functions //-- /** * Set current matrix mode */ virtual void MatrixModeSet(RS_MATRIXMODE mode) = 0;

/** * Get current matrix mode */ virtual const RS_MATRIXMODE MatrixModeGet() const = 0;

/** * Set current matrix to identity matrix */ virtual void MatrixLoadIdentity() = 0;

/** * Set current matrix to given matrix */ virtual void MatrixLoad(const Matrix4x4& m) = 0;

/** * Push current matrix on the stack */ virtual void MatrixPush() = 0;

/** * Remove last matrix from the stack */ virtual void MatrixPop() = 0;

/** * Multiply current matrix by the matrix corresponding to * provided scale values. */ virtual void MatrixScale( float x, float y, float z ) = 0;

/** * Multiply current matrix by the matrix corresponding to * provided translation values. */ virtual void MatrixTranslation( float x, float y, float z ) = 0;

/** * Multiply current matrix by the matrix corresponding to * provided rotation angle (in degrees) and axis. */ virtual void MatrixRotation( float angle, float x, float y, float z ) = 0;

/** * Multiply current transformation matric by given matrix */ virtual void MatrixMultiply(const Matrix4x4& m) = 0;

/** * Get current tranformation matrix */ virtual Matrix4x4 MatrixGet() = 0;

//------------------------------------------------------------------ // Other functions //-- /** * Set clear values */ virtual void SetBackgroundColor( float a, float r, float g, float b ) = 0; virtual void SetDepthClearValue( float z ) = 0; virtual void SetStencilClearValue( DWORD s ) = 0;

/** * Clears the backbuffer, Z-Buffer and stencil buffer to given * values if relevant flags are set. * @param flags A combination of any of the CLEARFLAG */ virtual void Clear( DWORD flags ) = 0;

/** * Set viewport area */ virtual bool SetViewport( int x, int y, int w, int h ) = 0;

//---------------------------------------------------------------------- // Typedefs, public members and accessors //-- public: const RS_BASEAPI GetBaseApi() const { return m_baseApi; }

//---------------------------------------------------------------------- // Protected member functions //-- protected: /** * This function will release all the memory that was dynamically * allocated for the device's internal members. */ virtual void Release() = 0;

//---------------------------------------------------------------------- // Protected members and accessors //-- protected: /** * Base 3D API that is currently used to render primitives */ RS_BASEAPI m_baseApi;

/** * Matrix affected by the matrix function calls (projection or * model-view) */ RS_MATRIXMODE m_matrixMode; };

#endif

Currently browsing [RenderSystem.zip] (241,705 bytes) - [Sources/RenderSystem/OpenGLRenderObjectFactory.h] - (876 bytes)

#ifndef _OPENGLRENDEROBJECTFACTORY_H_INCLUDED_
#define _OPENGLRENDEROBJECTFACTORY_H_INCLUDED_

#include "RenderObjectFactory.h"

/** * This is the implementation of the OpenGL version of render object * factory * * @author Vincent Prat */ class OpenGLRenderObjectFactory : public RenderObjectFactory { //---------------------------------------------------------------------- // Public methods //-- public:

OpenGLRenderObjectFactory(); ~OpenGLRenderObjectFactory();

//------------------------------------------------------------------ // Object creation functions (see base class documentation for this) //-- VertexBuffer* CreateVertexBuffer( int count, DWORD format, bool isDynamic = true ); Texture* CreateTexture( DWORD Width, DWORD Height, RS_FORMAT format, bool isDynamic = false, DWORD dwMipMapLevelNum = 0 ); };



#endif

Currently browsing [RenderSystem.zip] (241,705 bytes) - [Sources/RenderSystem/D3DVertexBuffer.cpp] - (4,156 bytes)

#ifdef COMPILE_DIRECT3D_IMPLEMENTATION

#include "D3DVertexBuffer.h" #include <d3d9.h>

D3DVertexBuffer::D3DVertexBuffer( LPDIRECT3DDEVICE9 pD3DDevice, int count, DWORD format, bool isDynamic ) : VertexBuffer() { DWORD size = 0; m_pD3DDevice = pD3DDevice; m_pD3DVertexBuffer = NULL;

m_FVF = 0; m_dwFormat = format; m_dwVertexCount = count;

if( format & RSVF_XYZ ) { m_FVF |= D3DFVF_XYZ; size += sizeof( float ) * 3; m_dwOffsetVertex = 0; } else if( format & RSVF_XYZRHW ) { m_FVF |= D3DFVF_XYZRHW; size += sizeof( float ) * 4; m_dwOffsetVertex = 0; }

if( format & RSVF_NORMAL ) { m_FVF |= D3DFVF_NORMAL; m_dwOffsetNormal = size; size += sizeof( float ) * 3; }

if( format & RSVF_DIFFUSE ) { m_FVF |= D3DFVF_DIFFUSE; m_dwOffsetDiffuse = size; size += sizeof( DWORD ); }

if( format & RSVF_TEXCOORD ) { m_FVF |= D3DFVF_TEX1; m_dwOffsetTexCoord = size; size += sizeof( float ) * 2; } m_dwStrideVertex = size; m_bIsDynamic = isDynamic; m_bIsLocked = false; m_pVertex = NULL; m_pBuffer = NULL;

HRESULT hRes;

if (m_bIsDynamic) { hRes = m_pD3DDevice->CreateVertexBuffer( m_dwStrideVertex * count, D3DUSAGE_WRITEONLY | D3DUSAGE_DYNAMIC, m_FVF, D3DPOOL_DEFAULT, &m_pD3DVertexBuffer, NULL ); } else { hRes = m_pD3DDevice->CreateVertexBuffer( m_dwStrideVertex * count, D3DUSAGE_WRITEONLY, m_FVF, D3DPOOL_MANAGED, &m_pD3DVertexBuffer, NULL ); }

if( FAILED(hRes) ) ::OutputDebugString( "D3DVertexBuffer::D3DVertexBuffer() --> creation of D3D vertex buffer failed !"); }

D3DVertexBuffer::~D3DVertexBuffer() { if( m_pD3DVertexBuffer != NULL ) { m_pD3DVertexBuffer->Release(); m_pD3DVertexBuffer = NULL; } }

bool D3DVertexBuffer::Lock() { HRESULT hRes = m_pD3DVertexBuffer->Lock( 0, 0, &m_pBuffer, (m_bIsDynamic?D3DLOCK_DISCARD:0) );

if ( FAILED(hRes) ) ::OutputDebugString( "D3DVertexBuffer::lock() --> Unable to lock D3D Vertex Buffer." );

m_bIsLocked = true; m_pVertex = (BYTE*)m_pBuffer;

return (!FAILED(hRes)); }

bool D3DVertexBuffer::Unlock() { HRESULT hRes = m_pD3DVertexBuffer->Unlock();

if ( FAILED(hRes) ) ::OutputDebugString( "D3DVertexBuffer::unlock() --> Unable to unlock D3D Vertex Buffer." );

m_bIsLocked = false; m_pVertex = NULL; m_pBuffer = NULL;

return (!FAILED(hRes)); }

void* D3DVertexBuffer::GetVertexData() { return m_pBuffer; }

void D3DVertexBuffer::Vertex( float x, float y, float z ) { float* vertex = (float*)(m_pVertex + m_dwOffsetVertex);

vertex[ 0 ] = x; vertex[ 1 ] = y; vertex[ 2 ] = z;

m_pVertex += m_dwStrideVertex; }

void D3DVertexBuffer::Vertex( float x, float y, float z, float w ) { float* vertex = (float*)(m_pVertex + m_dwOffsetVertex);

vertex[ 0 ] = x; vertex[ 1 ] = y; vertex[ 2 ] = z; vertex[ 3 ] = w;

m_pVertex += m_dwStrideVertex; }

void D3DVertexBuffer::Normal( float x, float y, float z ) { float* normal = (float*)( m_pVertex + m_dwOffsetNormal );

normal[ 0 ] = x; normal[ 1 ] = y; normal[ 2 ] = z; }

void D3DVertexBuffer::Diffuse( float r, float g, float b, float a ) { DWORD* diffuse = (DWORD*)( m_pVertex + m_dwOffsetDiffuse ); *diffuse = D3DCOLOR_COLORVALUE( r, g, b, a ); }

void D3DVertexBuffer::TexVertex( float u, float v ) { float* texcoord = (float*)( m_pVertex + m_dwOffsetTexCoord );

texcoord[ 0 ] = u; texcoord[ 1 ] = v; }

bool D3DVertexBuffer::PrepareForDrawing() { HRESULT hRes;

hRes = m_pD3DDevice->SetStreamSource( 0, m_pD3DVertexBuffer, 0, m_dwStrideVertex ); if (FAILED(hRes)) return 0; hRes = m_pD3DDevice->SetFVF( m_FVF ); if (FAILED(hRes)) return 0; return true; }

#endif

Currently browsing [RenderSystem.zip] (241,705 bytes) - [Sources/RenderSystem/D3DTexture.cpp] - (4,767 bytes)

#ifdef COMPILE_DIRECT3D_IMPLEMENTATION

#include "D3DTexture.h" #include <d3d9.h>

D3DTexture::D3DTexture( LPDIRECT3DDEVICE9 pD3DDevice, DWORD Width, DWORD Height, RS_FORMAT format, bool isDynamic, DWORD dwMipMapLevelNum ) : Texture() { m_pD3DDevice = pD3DDevice; m_pD3DTexture = NULL;

m_dwWidth = Width; m_dwHeight = Height; m_Format = format; m_dwMipMapLevelNum = dwMipMapLevelNum;

if( format == RSFMT_A8R8G8B8 ) { m_FMT = D3DFMT_A8R8G8B8; } else { m_FMT = D3DFMT_A8R8G8B8; ::OutputDebugString( "D3DTexture::D3DTexture() --> Invalid texture format (reverting to default 32 BPP) !\n"); } m_bIsDynamic = isDynamic; m_bIsLocked = false; m_pBuffer = NULL; m_pCurrentPixel= NULL;

HRESULT hRes;

if (m_bIsDynamic) { hRes = m_pD3DDevice->CreateTexture( m_dwWidth, m_dwHeight, m_dwMipMapLevelNum, D3DUSAGE_DYNAMIC, m_FMT, D3DPOOL_DEFAULT, &m_pD3DTexture, NULL ); } else { hRes = m_pD3DDevice->CreateTexture( m_dwWidth, m_dwHeight, m_dwMipMapLevelNum, 0, m_FMT, D3DPOOL_DEFAULT, &m_pD3DTexture, NULL ); }

if( FAILED(hRes) ) ::OutputDebugString( "D3DTexture::D3DTexture() --> creation of D3D texture failed !\n"); }

D3DTexture::~D3DTexture() { if( m_pD3DTexture != NULL ) { m_pD3DTexture->Release(); m_pD3DTexture = NULL; } }

bool D3DTexture::Lock() { HRESULT hRes; D3DLOCKED_RECT rect;

if ( m_bIsDynamic ) { // Dynamic textures can be locked directly //-- if ( FAILED( m_pD3DTexture->LockRect( 0, &rect, NULL, D3DLOCK_DISCARD ) ) ) { ::OutputDebugString( "D3DTexture::Lock() --> Unable to lock D3D Texture.\n" ); m_pBuffer = NULL; m_pCurrentPixel= NULL; m_bIsLocked = false; return false; } } else { // Static textures require us to first create a dynamic texture //-- hRes = m_pD3DDevice->CreateTexture( m_dwWidth, m_dwHeight, m_dwMipMapLevelNum, D3DUSAGE_DYNAMIC, m_FMT, D3DPOOL_SYSTEMMEM, &m_pD3DRamTexture, NULL );

if ( FAILED(hRes) ) { ::OutputDebugString( "D3DTexture::Lock() --> Failed to create temp texture.\n" ); m_pBuffer = NULL; m_pCurrentPixel= NULL; m_pD3DRamTexture=NULL; m_bIsLocked = false; return false; }

// Then lock this one and work with it //-- hRes = m_pD3DRamTexture->LockRect( 0, &rect, NULL, D3DLOCK_DISCARD ); if ( FAILED(hRes) ) { ::OutputDebugString( "D3DTexture::Lock() --> Failed to lock temp texture.\n" );

// Don't forget to release temp texture ! //-- m_pD3DRamTexture->Release(); m_pD3DRamTexture=NULL;

m_pBuffer = NULL; m_pCurrentPixel= NULL; m_bIsLocked = false;

return false; } }

m_dwPitch = rect.Pitch; m_pBuffer = rect.pBits; m_pCurrentPixel= (