www.pudn.com > tristripper-1.1.0-beta-5.zip > gl_renderer.cpp



#include "stdafx.h"
#include "gl_renderer.h"

#include "gl_model.h"
#include "high_res_timer.h"



//////////////////////////////////////////////////////////////////////
// Static object
//////////////////////////////////////////////////////////////////////

gl_renderer::model s_Model = gl_renderer::SKULL;

gl_model gl_renderer::m_TestModel;
size_t gl_renderer::m_NbFrames = 0;
high_res_timer gl_renderer::m_Timer;



//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////

gl_renderer::gl_renderer()
{
	using namespace std;

	atexit(AtExit);

	glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGBA | GLUT_DEPTH);
	glutInitWindowSize(320, 240);
	glutInitWindowPosition(100, 50);
	glutCreateWindow("Triangle Stripper Test");

	cout << "VENDOR: " << glGetString(GL_VENDOR) << endl;
	cout << "RENDERER: " << glGetString(GL_RENDERER) << endl;
	cout << "VERSION: " << glGetString(GL_VERSION) << endl;
	cout << endl;

	InitStates();
	InitScene();

	glutDisplayFunc(Display);
	glutReshapeFunc(Reshape);
	glutMainLoop();
}



gl_renderer::~gl_renderer()
{

}



//////////////////////////////////////////////////////////////////////
// Members Functions
//////////////////////////////////////////////////////////////////////

void gl_renderer::Display()
{
	// Benchmark part
	if (m_NbFrames == 0)
		m_Timer.Reset();

	++m_NbFrames;

	// Draw the test model
	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

	glLoadIdentity();
	glTranslatef(0.0, 0.5, -13.0);
	glRotatef((m_Timer.ElapsedTime() * 1000.0 / 20.0), 0.0, 1.0, 0.0);
//	glRotatef(145.0, 0.0, 1.0, 0.0);

//	glRotatef(-45.0, 1.0, 0.0, 0.0);	// Starship model test
//	glScalef(0.05, 0.05, 0.05);			// Starship model test

	m_TestModel.ExecuteAllMeshes();

	glFlush();
	glutSwapBuffers();

	// Ask for a redraw
	glutPostRedisplay();
}



void gl_renderer::AtExit()
{
	using namespace std;

	const float Time = m_Timer.ElapsedTime();

	// Check Display GL Error
	cout << "Display OpenGL Error: ";
	if (! PrintGLError(cout))
		cout << "-NONE-" << endl;

	cout << endl;

	cout << "Number of frames: " << static_cast(m_NbFrames) << "." << endl;
	cout << "Time taken to render: " << Time << " seconds." << endl;
	cout << "Average speed: " << float(m_NbFrames) / Time << " fps." << endl;

	cout << endl;
}



void gl_renderer::Reshape(int Width, int Height)
{
	glViewport(0, 0, (GLsizei) Width, (GLsizei) Height);
	glMatrixMode(GL_PROJECTION);
	glLoadIdentity();
	gluPerspective(45, ((GLdouble) Width) / ((GLdouble) Height), 1.0, 100.0);
	glMatrixMode(GL_MODELVIEW);
}



void gl_renderer::InitStates()
{
	// Various GL setting
	glClearColor(0.0, 0.0, 0.0, 0.0);
	glDepthFunc(GL_LESS);
	glShadeModel(GL_SMOOTH);

//	glPolygonMode(GL_FRONT, GL_LINE);
//	glPolygonMode(GL_BACK, GL_LINE);
//	glCullFace(GL_FRONT);
	glEnable(GL_CULL_FACE);
	glEnable(GL_DEPTH_TEST);
	glEnable(GL_LIGHTING);
	glEnable(GL_COLOR_MATERIAL);
	glEnable(GL_NORMALIZE);
	glEnable(GL_TEXTURE_2D);
	glEnableClientState(GL_VERTEX_ARRAY);
	glEnableClientState(GL_NORMAL_ARRAY);
	
	// Hints
	glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);

	// Assume tightly packed textures
	glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
	glPixelStorei(GL_PACK_ALIGNMENT, 1);

	// Check Init GL Error
	std::cout << "Init State OpenGL Error: ";
	if (! PrintGLError(std::cout))
		std::cout << "-NONE-" << std::endl;
}



void gl_renderer::InitScene()
{
	const bool SimpleLight = gl_mesh::s_ViewStrips;

	std::cout << std::endl;

	if (SimpleLight) {

		const GLfloat LightAmbient[]= { 0.5, 0.5, 0.5, 0.0 };
		const GLfloat LightDiffuse[]= { 1.0, 1.0, 1.0, 1.0 };
		const GLfloat LightPosition[]= { 10.0, 0.0, 10.0, 0.0 };

		glLightfv(GL_LIGHT0, GL_AMBIENT, LightAmbient);	
		glLightfv(GL_LIGHT0, GL_DIFFUSE, LightDiffuse);
		glLightfv(GL_LIGHT0, GL_POSITION, LightPosition);
		glEnable(GL_LIGHT0);

	} else {

		const float ModelAmbient[] = { 0.1, 0.1, 0.1, 1.0 };

		const float MaterialAmbient[] = { 0.0, 0.0, 0.0, 1.0 };
		const float MaterialDiffuse[] = { 1.0, 1.0, 1.0, 1.0 };
		const float MaterialSpecular[] = { 0.35, 0.35, 0.35, 1.0 };
		const float MaterialEmission[] = { 0.0, 0.0, 0.0, 1.0 };

		const size_t NbLights = 3;

		const float LightsSpecular[NbLights][4] = {
			{ 1.0, 1.0, 1.0, 1.0 },
			{ 1.0, 1.0, 1.0, 1.0 },
			{ 1.0, 1.0, 0.5, 1.0 }
		};

		const float LightsDiffuse[NbLights][4] = {
			{ 1.0, 0.2, 0.2, 1.0 },
			{ 0.2, 1.0, 0.2, 1.0 },
			{ 0.2, 0.2, 1.0, 1.0 }
		};

		const float LightsPosition[NbLights][4] = {
			{   0.0, -40.0, 40.0, 1.0 },
			{ -40.0,  40.0,  0.0, 1.0 },
			{  40.0,   0.0, 40.0, 1.0 }
		};

		glMaterialf(GL_FRONT, GL_SHININESS, 10.0);
		glMaterialfv(GL_FRONT, GL_AMBIENT, MaterialAmbient);
		glMaterialfv(GL_FRONT, GL_DIFFUSE, MaterialDiffuse);
		glMaterialfv(GL_FRONT, GL_SPECULAR, MaterialSpecular);
		glMaterialfv(GL_FRONT, GL_EMISSION, MaterialEmission);

		glLightModelfv(GL_LIGHT_MODEL_AMBIENT, ModelAmbient);
		glLightModelf(GL_LIGHT_MODEL_LOCAL_VIEWER, GL_TRUE);
		glLightModelf(GL_LIGHT_MODEL_TWO_SIDE, GL_FALSE);

		for (GLenum i = 0; i < NbLights; ++i) {
			glLightf((GL_LIGHT0 + i), GL_CONSTANT_ATTENUATION, 0.0);
			glLightf((GL_LIGHT0 + i), GL_LINEAR_ATTENUATION, 0.02);
			glLightf((GL_LIGHT0 + i), GL_QUADRATIC_ATTENUATION, 0.0);
			glLightfv((GL_LIGHT0 + i), GL_SPECULAR, LightsSpecular[i]);
			glLightfv((GL_LIGHT0 + i), GL_POSITION, LightsPosition[i]);
			glLightfv((GL_LIGHT0 + i), GL_DIFFUSE, LightsDiffuse[i]);
			glEnable(GL_LIGHT0 + i);
		}
	}

	// Load 3D Test Model
	std::cout << "Loading model... " << std::flush;

	if (! LoadTestModel())
		throw("Couldn't load test model");

	std::cout << "Model loaded." << std::endl;
	std::cout << std::endl;

	m_TestModel.CompileAllMeshes();

	// Check Init GL Error
	std::cout << "Init Scene OpenGL Error: ";
	if (! PrintGLError(std::cout))
		std::cout << "-NONE-" << std::endl;
}



bool gl_renderer::LoadTestModel()
{
	const char ModelPath[] = "models/skull.vxo";/*"models/starship.vxo";*/

	std::ifstream File(ModelPath, std::ios::binary);

	if (! File)
		return false;

	return (m_TestModel.LoadFromVXO(File));
}



bool gl_renderer::PrintGLError(std::ostream & Out)
{
	GLenum errCode;

	if ((errCode = glGetError()) != GL_NO_ERROR) {
		Out << gluErrorString(errCode) << std::endl;
		return true;
	} else
		return false;
}