2 Replies - 851 Views - Last Post: 18 May 2011 - 05:36 PM Rate Topic: -----

#1 Kain6622  Icon User is offline

  • D.I.C Head

Reputation: 14
  • View blog
  • Posts: 248
  • Joined: 18-March 10

Multi-Threading - performance issue

Posted 18 May 2011 - 05:19 PM

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

Is This A Good Question/Topic? 0
  • +

Replies To: Multi-Threading - performance issue

#2 ishkabible  Icon User is offline

  • spelling expret
  • member icon





Reputation: 1530
  • View blog
  • Posts: 5,518
  • Joined: 03-August 09

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.

This post has been edited by ishkabible: 18 May 2011 - 05:27 PM

Was This Post Helpful? 0
  • +
  • -

#3 Kain6622  Icon User is offline

  • D.I.C Head

Reputation: 14
  • View blog
  • Posts: 248
  • Joined: 18-March 10

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 );
}


Was This Post Helpful? 0
  • +
  • -

Page 1 of 1