Hi, i'm working on a multithreaded procedural model generator but though development of it with multi-threading and timing the performance I'm getting near the same result/performance loss of thread use, I've been thinking over the problem and believe that it could be due to there being too many threads running at the same time ( usually over 100 for performance testing ) I was wanting to make a form of queue for the threads so that only a certain number can run at any concurrent time with the use of Semaphores but I'm not entirely sure about how to correctly use them apart from as a protection of variables. please could someone help me usnderstand how I'm supposed to properly use Semaphores in the instance of the problem presented?
Thank you.
Dave
Multi-Threading - performance issue
Page 1 of 12 Replies - 851 Views - Last Post: 18 May 2011 - 05:36 PM
Replies To: Multi-Threading - performance issue
#2
Re: Multi-Threading - performance issue
Posted 18 May 2011 - 05:22 PM
code? it's hard to know what your doing wrong without seeing what your doing.
also, if you have more software threads than your processors has threads(each core typically has 4) then your not really going to gain a speed boost of any kind as your just reusing up more threads. the main reason to use more than 8 threads is so that things can run interdependently. for instance, it's nice to have the GUI run in another thread so it doesn't lock up while while your program is doing some complex calculation.
also, if you have more software threads than your processors has threads(each core typically has 4) then your not really going to gain a speed boost of any kind as your just reusing up more threads. the main reason to use more than 8 threads is so that things can run interdependently. for instance, it's nice to have the GUI run in another thread so it doesn't lock up while while your program is doing some complex calculation.
This post has been edited by ishkabible: 18 May 2011 - 05:27 PM
#3
Re: Multi-Threading - performance issue
Posted 18 May 2011 - 05:36 PM
Thanks for the reply, I'm under the impression that you issue you stated is what i'm comming across as more than not i'm loosing performance with the multi-threaded version to the normal. My Code is as follows in my main application class and mesh class with the threading:
/* misAppli.h */
#ifndef __MISAPPLI_H__
#define __MISAPPLI_H__
/* Include required header files for this header file */
#include <Windows.h>
#include "glee/glee.h"
#include <gl/gl.h>
#include <gl/glu.h>
#include "ModelLoader/milkshape/tex.h"
#include "ModelLoader/milkshape/MilkshapeModel.h"
#include "input/directinput.h"
#include "object lib/Text.h"
/* Our misAppli class */
class C_MisAppli
{
public:
C_MisAppli(); // default contructor
~C_MisAppli(){} // default destructor
bool Initialize( void );
void Render( float elapsedtime );
bool ShutDown( void );
void SceneResize( int Width, int Height );
void GetHDC( HDC* dc ){ m_hDC = dc; }
private:
enum SceneState{ LOADING = 0, CONVERT, RENDER }; // enum for the current scene status
SceneState m_CurrentStatus; // keeps track of the current scene status
void PrepareProceduralModels( void );
void Prepare( float dt );
void RenderLoadingScreen( void );
void RenderScene( void );
void ConvertGL();
MilkshapeModel* pModel;
DirectInput* _Input;
int mx, my;
float x, y;
HANDLE LoadingHandle;
unsigned int listbase;
cGL_Text GL_Text;
HDC* m_hDC;
friend unsigned __stdcall LoadingThread( void *pVoid );
};
#endif
/* misAppli.cpp */
/* Include the complementrary header file */
#include "misAppli.h"
#include "glut/glut.h"
#include "imageloader.h"
#include "cPrimitives.h"
#include "object lib/ProcedureModels.h"
#include "camera/FPSCam.h"
#include "object lib/material.h"
#include "modelloader/objloader/NewOBJLoader.h"
#include <ctime>
/*
clock_t start( clock() );
PrepareProceduralModels();
clock_t finish( clock() );
char times[256];
sprintf( times, "Time taken for Terrain Generation was %d ms", ( finish - start ));
MessageBox( NULL, times, "Times taken", MB_OK );
*/
TargaImage m_skyTexture;
GLuint m_skyTexID;
TargaImage m_grassTexture;
GLuint m_grassTexID;
CSphere MySphere( 10.0, 50, 50 );
CCylinder MyCylinder( 10.0, 50, 50 );
CSphere MySphere2( 10000.0, 250, 250 );
CTerrain MyTerrain( Gen, 128, 520, 8000 );
CFPS_CAM Player( 165.0 );
MATERIAL SkyMat;
MATERIAL GroundMat;
MATERIAL WoodMat;
OBJ MyObject;
HANDLE LoadingHandle; // Handle for the Object loading thread
unsigned __stdcall LoadingThread( void *pVoid )
{
/* First convert our Arguments back to the class it originated */
C_MisAppli *args = (C_MisAppli*)pVoid;
/* Now call our class member function for the texture coordinate generator */
args->PrepareProceduralModels();
#define NumObj 10
/* Perfromance testing */
CTerrain *Testt[NumObj];
CSphere *Tests[NumObj];
CCylinder *Testc[NumObj];
for( int i = 0; i < NumObj; ++i )
{
Testt[i] = new CTerrain( Gen, 64, 50, 1000 );
Tests[i] = new CSphere( 50.0, 50, 50 );
Testc[i] = new CCylinder( 50.0, 50, 50 );
}
clock_t start( clock() );
{
for( int i = 0; i < NumObj; ++i )
{
Testt[i]->Generate();
Tests[i]->Generate();
Testc[i]->Generate();
}
}
clock_t finish( clock() );
for( int i = 0; i < NumObj; ++i )
{
Testt[i]->CleanUp();
Tests[i]->CleanUp();
Testc[i]->CleanUp();
delete Testt[i];
delete Tests[i];
delete Testc[i];
Testt[i] = NULL;
Tests[i] = NULL;
Testc[i] = NULL;
}
char times[256];
sprintf( times, "Time taken for Terrain Generation was %d ms", ( finish - start ));
MessageBox( NULL, times, "Times taken", MB_OK );
return 0;
}
/* Start our misAppli class function definitions */
C_MisAppli::C_MisAppli() : m_CurrentStatus(LOADING)
{
_Input = new DirectInput;
x = y = mx = my = 0;
// Empty for the now
} // end of contructor
bool C_MisAppli::Initialize( void )
{
/* Initialize the keyboard and mouse for use */
_Input->InitKeyboard();
_Input->InitMouse();
GL_Text.GetHDC( m_hDC );
listbase = GL_Text.CreateOutlineFont("Segoe Print", 10, 0.25f );
/* Use VBO support if the system has it */
MySphere.useVBO( true );
MyCylinder.useVBO( true );
MySphere2.useVBO( true );
MyTerrain.useVBO( true );
/* SetUp some of OpenGL's States */
glClearColor( 0.0f, 0.0f, 0.0f, 1.0f );
glEnable( GL_DEPTH_TEST ); // enable depth testing
glDepthFunc(GL_LEQUAL); // The Type Of Depth Testing To Do
glClearDepth(1.0f); // Depth Buffer Setup
glEnable( GL_CULL_FACE );
glEnable( GL_TEXTURE_2D );
glCullFace( GL_BACK );
glFrontFace( GL_CCW );
glShadeModel(GL_SMOOTH); // Enable Smooth Shading
glEnable( GL_POLYGON_SMOOTH );
glHint( GL_NICEST, GL_POLYGON_SMOOTH_HINT );
glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
glEnable( GL_LIGHTING );
glEnable( GL_LIGHT0 );
MySphere2.AssignMaterial(&SkyMat);
MySphere2.RefreshMaterialTexture();
MyTerrain.AssignMaterial(&GroundMat);
MyTerrain.RefreshMaterialTexture();
MySphere.AssignMaterial(&WoodMat);
MySphere.RefreshMaterialTexture();
LoadingHandle = (HANDLE)_beginthreadex(NULL, 0, LoadingThread, (PVOID)this, 0, NULL );
return true;
} // End of initialize
void C_MisAppli::PrepareProceduralModels( void )
{
SkyMat.SetAmbient( 1.0, 0.0, 1.0, 1.0 );
SkyMat.SetDiffuse( 1.0, 0.0, 1.0, 1.0 );
SkyMat.SetEmissive( 1.0, 0.0, 1.0, 1.0 );
SkyMat.SetShininess( 100.0 );
if( !SkyMat.LoadTGATexture("Space.tga" ) )
MessageBox( NULL, "Where is the Texture?", "ERROR", MB_OK );
GroundMat.SetAmbient( 0.23125, 0.23125, 0.23125, 0.23125 );
GroundMat.SetDiffuse( 0.2775, 0.2775, 0.2775, 1.0 );
//GroundMat.SetEmissive( 1.0, 1.0, 1.0, 0.0 );
GroundMat.SetSpecular( 0.773911, 0.773911, 0.773911, 1.0 );
GroundMat.SetShininess(50.0 );
GroundMat.LoadTGATexture("grass.tga" );
WoodMat.SetAmbient( 0.33, 0.22, 0.03, 1.0 );
WoodMat.SetDiffuse( 0.78, 0.57, 0.11, 1.0 );
WoodMat.SetSpecular( 0.99, 0.91, 0.81, 1.0 );
WoodMat.SetShininess( 27.8 );
WoodMat.LoadTGATexture("wood.tga" );
pModel = new MilkshapeModel();
if ( pModel->loadModelData( "pg.ms3d" ) == false )
{
MessageBox( NULL, "Couldn't load the model data/model.ms3d", "Error", MB_OK | MB_IConerror );
}
if( !MyObject.Load( "PG.obj" ) )
MessageBox( NULL, "Where is the portal gun.", "Error", MB_OK );
MySphere.Generate();
MyCylinder.Generate();
MySphere2.Generate();
MyTerrain.Generate();
m_CurrentStatus = CONVERT; // Once the models are generated change status to convert
}
void C_MisAppli::ConvertGL()
{
/* Activate our textures */
SkyMat.TextureActive();
GroundMat.TextureActive();
WoodMat.TextureActive();
/* Wait for the Loading handle to finish and close the thread */
WaitForSingleObject( LoadingHandle, INFINITE );
CloseHandle( LoadingHandle );
pModel->reloadTextures();
/* Convert our models for use in OpenGL */
MySphere.ConvertToGL();
MyCylinder.ConvertToGL();
MySphere2.ConvertToGL();
MyTerrain.ConvertToGL();
m_CurrentStatus = RENDER; // once all the models have been initialized for GL change status to render
}
void C_MisAppli::Prepare( float dt )
{
/* assign any values here */
/* If deling with such as velocity */
/* Multiply by dt for constance rate */
/* Between different systems */
_Input->Update();
glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
glLoadIdentity();
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glFrontFace( GL_CCW );
_Input->mGetMovement( mx, my );
if( _Input->mButtonDown(1) )
{
Player.SetCameraMode( Zoom );
}
if( _Input->mButtonUp(1) )
{
Player.SetCameraMode( Normal );
Player.Reset();
}
if( Player.CameraMode() == Normal )
y -= my;
if( Player.CameraMode() == Zoom )
Player.Zoom( my );
x += mx;
const float Const_Spd = 45.0;
float Spd = Const_Spd;
//sample input setup.
if (_Input->KeyDown(DIK_W))
Player.MoveCamera( Spd );
if (_Input->KeyDown(DIK_S))
Player.MoveCamera( -Spd );
if (_Input->KeyDown(DIK_A))
Player.StrafeCamera( -Spd );
if (_Input->KeyDown(DIK_D))
Player.StrafeCamera( Spd );
if (_Input->KeyDown(DIK_Z))
Player.ElevateCamera( Spd );
if (_Input->KeyDown(DIK_X))
Player.ElevateCamera( -Spd );
static bool wire = false;
static bool lighting = false;
static bool FlatShading = false;
if( _Input->KeyDown( DIK_F1 ) )
wire = !wire;
if( _Input->KeyDown( DIK_F2 ) )
lighting = !lighting;
if( _Input->KeyDown( DIK_F3 ) )
FlatShading = !FlatShading;
if( lighting )
{
glEnable( GL_LIGHTING );
glEnable( GL_LIGHT0 );
}
else
{
glDisable( GL_LIGHTING );
glDisable( GL_LIGHT0 );
}
if( FlatShading )
glShadeModel( GL_FLAT );
else
glShadeModel( GL_SMOOTH );
if( wire )
{
glPolygonMode( GL_FRONT_AND_BACK, GL_LINE );
}
else
{
glPolygonMode( GL_FRONT_AND_BACK, GL_FILL );
}
Player.SetHeight( 46+MyTerrain.GetHeight( Player.GetXPos(), Player.GetZPos() ) );
/* Our camera restriants */
/* We will use the equation of a circle to stop the player going out of terrain bounds */
float LHS = sqrt((( Player.GetXPos() - 0 )*( Player.GetXPos() - 0 )) + (( Player.GetZPos() - 0 )*( Player.GetZPos() - 0 )));
float RHS = (128.0*25)*(128.0*25);
vec2 BoundPos( Player.GetXPos() , Player.GetZPos() );
if( LHS >= RHS )
Player.CameraPosition( BoundPos.GetX(), 46+MyTerrain.GetHeight( Player.GetXPos(), Player.GetZPos() ), BoundPos.GetY() );
Player.Update( x, y, 0.0);
} // end of prepare
void C_MisAppli::Render( float elapsedtime )
{
switch( m_CurrentStatus )
{
case LOADING:
RenderLoadingScreen();
break;
case CONVERT:
ConvertGL();
// fall through
case RENDER:
Prepare( elapsedtime );
RenderScene();
break;
}
}
void C_MisAppli::RenderScene( void )
{
glPushMatrix();
// set light position
GLfloat lightPos[]={0.0,4880.0,0.0,1.0};
glLightfv(GL_LIGHT0,GL_POSITION,lightPos);
// set spot light parameters
GLfloat spotDir[]={-1.0,-1.0,0.0}; // define spot direction
glLightfv(GL_LIGHT0, GL_SPOT_DIRECTION, spotDir);
glLightf(GL_LIGHT0, GL_SPOT_CUTOFF,45.0); // set cutoff angle
glLightf(GL_LIGHT0, GL_SPOT_EXPONENT,5.0); // set focusing strength*/
glLightf(GL_LIGHT0, GL_CONSTANT_ATTENUATION,0.00002);
//glLightf(GL_LIGHT0, GL_LINEAR_ATTENUATION,0.0002);
// glLightf(GL_LIGHT0, GL_QUADRATIC_ATTENUATION,0.2);
glEnable( GL_NORMALIZE );
glPopMatrix();
glPushMatrix();
glScalef( 50.0, 50.0, 50.0 );
MyTerrain.RefreshMaterialTexture();
MyTerrain.Render();
//MyTerrain.DrawPoints();
glPopMatrix();
//glTranslatef( 0.0, 0.0, -15.0 );
glPushMatrix();
glTranslatef( 10.0, 1550.0, 0.0 );
glutSolidSphere( 55.0, 15.0, 15.0 );
glPopMatrix();
glPushMatrix();
glLoadIdentity();
glScalef(0.125, 0.125, 0.125);
glTranslatef(5.0f, -55.0, -25.5f);
glRotatef( 180, 0.0, 1.0, 0.0 );
glRotatef( -90.0, 1.0, 0.0, 0.0 );
pModel->draw();
glPopMatrix();
glPushMatrix();
MyCylinder.Render();
glPopMatrix();
glPushMatrix();
glTranslatef( -15.0, 0.0, 0.0 );
MySphere.RefreshMaterialTexture();
MySphere.Render();
glPopMatrix();
static float ang = 0.0f;
ang += 0.1f;
glPushMatrix();
//glLoadIdentity();
glFrontFace( GL_CW );
glDisable( GL_LIGHTING );
glDisable( GL_LIGHT0 );
glRotatef( ang, 0.0, 1.0, 0.0 );
MySphere2.RefreshMaterialTexture();
MySphere2.Render();
glEnable( GL_LIGHTING );
glEnable( GL_LIGHT0 );
glPopMatrix();
} // end of Render
void C_MisAppli::RenderLoadingScreen( void )
{
glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
glLoadIdentity();
//gluLookAt(0, 0, 16, 0, 0, 0, 0, 1, 0); //Where we are, What we look at, and which way is up
glDisable( GL_LIGHTING );
glDisable( GL_LIGHT0 );
glDisable( GL_NORMALIZE );
glDisable( GL_TEXTURE_2D );
glTranslatef( 0.0, 0.0, -6.0 );
glPushAttrib(GL_CURRENT_BIT);
static float alph = 0.0;
static bool change = false;
if( change )
alph -= 0.01;
else
alph += 0.01;
if( alph > 1.0 )
change = true;
if( alph < 0.0 )
change = false;
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glPushMatrix();
glPushMatrix();
glColor4f( 0.0, 1.0, 0.0, -alph +1.0);
GL_Text.PrintString( listbase, "...Loading..." );
glPopMatrix();
glPushMatrix();
glTranslatef( 0.0, -1.0, 0.0 );
glColor4f( 1.0, 0.0, 0.0, alph );
GL_Text.PrintString( listbase, "Please Wait" );
glPopMatrix();
glPopMatrix();
glPopAttrib();
glDisable(GL_BLEND);
glEnable( GL_LIGHTING );
glEnable( GL_LIGHT0 );
glEnable( GL_NORMALIZE );
glEnable( GL_TEXTURE_2D );
}
bool C_MisAppli::ShutDown( void )
{
// delete pModel;
pModel = NULL;
MySphere.CleanUp();
MyCylinder.CleanUp();
MySphere2.CleanUp();
MyTerrain.Clean();
_Input->ShutDown();
delete _Input;
_Input = NULL;
//MyTerrain.CleanUp();
return true;
} // end of ShutDown
void C_MisAppli::SceneResize( int Width, int Height )
{
glViewport( 0, 0, Width, Height );
glMatrixMode( GL_PROJECTION );
glLoadIdentity();
gluPerspective( 45.0f, float(Width)/float(Height), 1.0f, 15000.0f );
glMatrixMode( GL_MODELVIEW );
glLoadIdentity();
} // end of SceneResize
/* Mesh.h */
#ifndef __MESH_H__
#define __MESH_H__
/* Includes for this header file */
#include <process.h> // for our multithreading
#include "..\VBOSupport.h"
#include <vector>
#include "..\Maths lib\math.h"
#include "Material.h"
using namespace std;
typedef unsigned int UINT;
/* Our mesh class */
class MESH
{
public:
MESH() : m_Position(0.0, 0.0, 0.0), VBO(0), NBO(0), TBO(0), IBO(0), m_UseVBO(false) {} // default constructor... Base class MESH only requires a basic constructor
virtual ~MESH(){} // default deconstructor
virtual void GenVertices() = 0; // Our Abstract Verteice Generation Function
virtual void GenIndices() = 0; // our Abstract Indices Generation Function
virtual void GenNormals() = 0; // Our Abstract Normal Generation Function
virtual void GenColors() = 0; // Our Abstract vec4 Generation Function
virtual void GenTexCoords() = 0; // Our Abstract Texture Coordinate Generation Function
virtual void Generate() = 0; // Generate our Primitive
void ConvertToGL( void );
virtual void AssignMaterial( MATERIAL* mat ) = 0; // Assign a material to the mesh
void RefreshMaterialTexture(); // Refresh and apply material ( Not virtual, can be coded for the base class )
vector<vec3>* GetVertices(){ return &m_vData; } // Returns a pointer to the vertex data
vector<vec3>* GetNormals(){ return &m_nData; } // Returns a pointer to the normal data
vector<unsigned int>* GetIndices(){ return &m_iData; } // Returns a pointer to the vertice indices
vector<vec4>* GetColors(){ return &m_cData; } // Returns a pointer to the Vertex color Data
vector<vec2>* GetTexCoords(){ return &m_tData; } // Returns a pointer to the mesh texture coordinates
UINT* GetVBO(){ return &VBO; } // Returns a pointer to the mesh vertex buffer object
UINT* GetIBO(){ return &IBO; } // Returns a pointer to the Index buffer object
UINT* GetNBO(){ return &NBO; } // Returns a pointer to the Normal buffer object
UINT* GetCBO(){ return &CBO; } // Return a pointer to the Color buffer object
UINT* GetTBO(){ return &TBO; } // Returns a pointer to the Texture buffer object
void useVBO( bool useVBO ); // Set the state of the render method
bool VBO_Active(){ return m_UseVBO; } // Returns wether VBO is on or off
void Render(); // Our render method
void RenderVBO(); // this is just to test that the code works before moving it into a more cross api platform library
void RenderVA(); // Again another test but so i can include rendering for none VBO supporting PC's
//virtual void Render() = 0; // Our Render Function
void CleanUp() { m_vData.clear();
m_iData.clear();
m_nData.clear();
m_cData.clear();
m_tData.clear(); }
private:
protected:
bool m_UseVBO; // will this object render using VBO's
vec3 m_Position; // Mesh Position in world space
vector<vec3> m_vData; // vec3 Data
vector<vec3> m_nData; // vec3 Normal Data
vector<UINT> m_iData; // Index Data
vector<vec4> m_cData; // vec4 Data
vector<vec2> m_tData; // Texture Data
MATERIAL* m_Material; // Mesh material ( includes texture for the object )
UINT VBO; // vec3 Buffer Object
UINT IBO; // Index Buffer Object
UINT NBO; // Normal buffer Object
UINT CBO; // vec4 Buffer Object
UINT TBO; // Texture Buffer Object
/* Slow way of handling multi-threading */
HANDLE VertexHandle; // Our handle for vertex generation
HANDLE NormalHandle; // our handle for the normal generation
HANDLE ColorHandle; // our handle for the color generation
HANDLE IndexHandle; // our handle of the indices generation
HANDLE TexCoordHandle; // our handle for our texcoord generation
/* Hopefully faster this way */
HANDLE GenerationHandle; // Handle for the generation thread
};
/* Slow slow slow */
unsigned __stdcall VertexThread( void *pVoid ); // Thread for handling the vertex data generation
unsigned __stdcall NormalThread( void *pVoid ); // Thread for handling the Normal data generation
unsigned __stdcall ColorThread( void *pVoid ); // Thread for handling the Color data generation
unsigned __stdcall IndexThread( void *pVoid ); // Thread for handling the Index data generation
unsigned __stdcall TexCoordThread( void *pVoid ); // Thread for handling the TexCoord data generation
/* Fast */
unsigned __stdcall GenerationThread( void *pVoid );
#endif
/* Mesh.cpp */
/* Include complementrary header file */
#include "Mesh.h"
/* Start of the MESH class function definitions */
void MESH::useVBO( bool useVBO )
{
m_UseVBO = isExtensionSupported("GL_ARB_vertex_buffer_object");
}
void MESH::RefreshMaterialTexture()
{
float Spec[] = { m_Material->GetSpecular().GetX(), m_Material->GetSpecular().GetY(), m_Material->GetSpecular().GetZ(), m_Material->GetSpecular().GetW() };
float Diff[] = { m_Material->GetDiffuse().GetX(), m_Material->GetDiffuse().GetY(), m_Material->GetDiffuse().GetZ(), m_Material->GetDiffuse().GetW() };
float Ambi[] = { m_Material->GetAmbient().GetX(), m_Material->GetAmbient().GetY(), m_Material->GetAmbient().GetZ(), m_Material->GetAmbient().GetW() };
float Emis[] = { m_Material->GetEmissive().GetX(), m_Material->GetEmissive().GetY(), m_Material->GetEmissive().GetZ(), m_Material->GetEmissive().GetW() };
glMaterialfv( GL_FRONT, GL_SPECULAR, Spec );
glMaterialfv( GL_FRONT, GL_AMBIENT, Ambi );
glMaterialfv( GL_FRONT, GL_DIFFUSE, Diff );
glMaterialfv( GL_FRONT, GL_EMISSION, Emis );
glMaterialf( GL_FRONT, GL_SHININESS, m_Material->GetShininess() );
this->m_Material->AssignTexture();
}
/* Our multithreading process functions */
unsigned __stdcall VertexThread( void *pVoid )
{
/* First convert our Arguments back to the class it originated */
MESH *args = (MESH*)pVoid;
/* Now call our class member function for the vertex data */
args->GenVertices();
return 0;
}
unsigned __stdcall NormalThread( void *pVoid )
{
/* First convert our Arguments back to the class it originated */
MESH *args = (MESH*)pVoid;
/* Now call our class member function for cvalculating the normals */
args->GenNormals();
return 0;
}
unsigned __stdcall ColorThread( void *pVoid )
{
/* First convert our Arguments back to the class it originated */
MESH *args = (MESH*)pVoid;
/* Now call our class member function for cvalculating the normals */
args->GenColors();
return 0;
}
unsigned __stdcall IndexThread( void *pVoid )
{
/* First convert our Arguments back to the class it originated */
MESH *args = (MESH*)pVoid;
/* Now call our class member function for generating the indices */
args->GenIndices();
return 0;
}
unsigned __stdcall TexCoordThread( void *pVoid )
{
/* First convert our Arguments back to the class it originated */
MESH *args = (MESH*)pVoid;
/* Now call our class member function for the texture coordinate generator */
args->GenTexCoords();
return 0;
}
/* ******************************** */
/* Generation Thread */
/* ******************************** */
unsigned __stdcall GenerationThread( void *pVoid )
{
MESH *args = (MESH*)pVoid; // Convert the argument back to it's original format
args->GenVertices();
args->GenColors();
args->GenTexCoords();
args->GenIndices();
args->GenNormals();
return 0;
}
void MESH::ConvertToGL( void )
{
if( QueryExtension( "GL_ARB_vertex_buffer_object" ) == true ) // change this to QueryExtension( "GL_ARB_VERTEX_BUFFER_OBJECT" );
{
/* Gen Vertex Buffer */
glGenBuffers( 1, &VBO );
glBindBuffer(GL_ARRAY_BUFFER, VBO); //Bind the vec3 buffer
glBufferData(GL_ARRAY_BUFFER, sizeof( GLfloat ) * m_vData.size() * 3, &m_vData[0], GL_STATIC_DRAW); //Send the data to OpenGL
/* Gen Index Buffer */
glGenBuffers(1, &IBO);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, IBO);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(UINT) * m_iData.size(), &m_iData[0], GL_STATIC_DRAW);
/* Gen Color Buffer */
glGenBuffers(1, &CBO);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, CBO);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(GLfloat) * m_cData.size() * 4, &m_cData[0], GL_STATIC_DRAW);
/* Gen Normal Buffer */
glGenBuffers(1, &NBO);
glBindBuffer(GL_ARRAY_BUFFER, NBO); //Bind the vec3 buffer
glBufferData(GL_ARRAY_BUFFER, sizeof(GLfloat) * m_nData.size() * 3, &m_nData[0], GL_STATIC_DRAW); //Send the data to OpenGL
/* Gen Color Buffer */
/*glGenBuffers(1, &CBO);
glBindBuffer(GL_ARRAY_BUFFER, CBO); //Bind the vec3 buffer
glBufferData(GL_ARRAY_BUFFER, sizeof(GLfloat) * m_cData.size() * 4, &m_cData[0], GL_STATIC_DRAW); //Send the data to OpenGL
/* Gen Texture buffer */
glGenBuffers(1, &TBO);
glBindBuffer(GL_ARRAY_BUFFER, TBO); //Bind the vec3 buffer
glBufferData(GL_ARRAY_BUFFER, sizeof(GLfloat) * m_tData.size() * 2, &m_tData[0], GL_STATIC_DRAW); //Send the data to OpenGL
}
}
void MESH::Render()
{
if( QueryExtension( "GL_ARB_vertex_buffer_object" ) == true )
this->RenderVBO();
else
this->RenderVA();
}
void MESH::RenderVBO()
{
//Bind the vec3 array and set the vec3 pointer to point at it
glEnableClientState( GL_VERTEX_ARRAY );
glBindBuffer(GL_ARRAY_BUFFER, VBO);
glVertexPointer(3, GL_FLOAT, 0, 0);
//glvec3AttribPointer((GLint)0, 3, GL_FLOAT, GL_FALSE, 0, BUFFER_OFFSET(0));
glEnableClientState( GL_COLOR_ARRAY );
glBindBuffer( GL_ARRAY_BUFFER, CBO );
glColorPointer( 4, GL_FLOAT, 0, 0);
glEnableClientState( GL_TEXTURE_COORD_ARRAY );
glBindBuffer(GL_ARRAY_BUFFER, TBO);
glTexCoordPointer( 2, GL_FLOAT, 0, 0 );
//glvec3AttribPointer((GLint)1, 2, GL_FLOAT, GL_FALSE, 0, BUFFER_OFFSET(0));
glEnableClientState( GL_NORMAL_ARRAY );
glBindBuffer(GL_ARRAY_BUFFER, NBO);
glNormalPointer( GL_FLOAT, 0, 0 );
//glvec3AttribPointer((GLint)2, 3, GL_FLOAT, GL_FALSE, 0, BUFFER_OFFSET(0));
//Bind the index array
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, IBO);
//Draw the triangles
glDrawElements(GL_TRIANGLES, m_iData.size(), GL_UNSIGNED_INT, BUFFER_OFFSET(0));
glDisableClientState( GL_VERTEX_ARRAY );
glDisableClientState( GL_COLOR_ARRAY );
glDisableClientState( GL_TEXTURE_COORD_ARRAY );
glDisableClientState( GL_NORMAL_ARRAY );
}
void MESH::RenderVA()
{
//Bind the vec3 array and set the vec3 pointer to point at it
glEnableClientState( GL_VERTEX_ARRAY );
glVertexPointer(3, GL_FLOAT, 0, &m_vData[0]);
//glvec3AttribPointer((GLint)0, 3, GL_FLOAT, GL_FALSE, 0, BUFFER_OFFSET(0));
glEnableClientState( GL_COLOR_ARRAY );
glColorPointer( 4, GL_FLOAT, 0, &m_cData[0] );
//glBindBuffer( GL_ARRAY_BUFFER, Sphere_CBO );
//glvec4Pointer( 4, GL_FLOAT, 0, BUFFER_OFFSET(0));
glEnableClientState( GL_TEXTURE_COORD_ARRAY );
glTexCoordPointer( 2, GL_FLOAT, 0, &m_tData[0] );
//glvec3AttribPointer((GLint)1, 2, GL_FLOAT, GL_FALSE, 0, BUFFER_OFFSET(0));
glEnableClientState( GL_NORMAL_ARRAY );
glNormalPointer( GL_FLOAT, 0, &m_nData[0] );
//glvec3AttribPointer((GLint)2, 3, GL_FLOAT, GL_FALSE, 0, BUFFER_OFFSET(0));
//Draw the triangles
glDrawElements(GL_TRIANGLES, m_iData.size(), GL_UNSIGNED_INT, &m_iData[0]);
glDisableClientState( GL_VERTEX_ARRAY );
glDisableClientState( GL_COLOR_ARRAY );
glDisableClientState( GL_TEXTURE_COORD_ARRAY );
glDisableClientState( GL_NORMAL_ARRAY );
}
Page 1 of 1
|
|

New Topic/Question
Reply




MultiQuote







|