Skip to content

Commit

Permalink
blarg
Browse files Browse the repository at this point in the history
  • Loading branch information
ChrisLundquist committed Jun 14, 2011
1 parent 75a0796 commit 28ba3fd
Show file tree
Hide file tree
Showing 8 changed files with 200 additions and 94 deletions.
56 changes: 46 additions & 10 deletions Driver.cpp
Expand Up @@ -3,6 +3,7 @@
#endif #endif
#include <GL/gl.h> #include <GL/gl.h>
#include <GL/glu.h> #include <GL/glu.h>
#include <GL/glut.h>
#include "Model.h" #include "Model.h"
#include "Obj.h" #include "Obj.h"


Expand All @@ -11,35 +12,70 @@ void usage(){
} }


void draw(Model::Model* model){ void draw(Model::Model* model){
glEnable(GL_TEXTURE_2D); //glEnable(GL_TEXTURE_2D);
// glBindTexture(GL_TEXTURE_2D, texturen[0]); // glBindTexture(GL_TEXTURE_2D, texturen[0]);


// glutSolidTeapot(1);
glEnableClientState(GL_VERTEX_ARRAY); glEnableClientState(GL_VERTEX_ARRAY);
glEnableClientState(GL_TEXTURE_COORD_ARRAY); //glEnableClientState(GL_TEXTURE_COORD_ARRAY);
glEnableClientState(GL_NORMAL_ARRAY); glEnableClientState(GL_NORMAL_ARRAY);
glNormalPointer(GL_FLOAT, 0, model->normals); // glNormalPointer(GL_FLOAT, 0, model->normals);


glTexCoordPointer(2,GL_FLOAT,0, model->textures ); // glTexCoordPointer(2,GL_FLOAT,0, model->textureCoordinates );
glVertexPointer(3,GL_FLOAT, 0,model->triangles); glVertexPointer(3,GL_FLOAT, 0,model->triangles);
glDrawArrays(GL_TRIANGLES, 0, model->totalConnectedTriangles); glDrawArrays(GL_TRIANGLES, 0, model->totalConnectedTriangles);


glDisableClientState(GL_NORMAL_ARRAY); glDisableClientState(GL_NORMAL_ARRAY);
glDisableClientState(GL_VERTEX_ARRAY); glDisableClientState(GL_VERTEX_ARRAY);
glDisableClientState(GL_TEXTURE_COORD_ARRAY); // glDisableClientState(GL_TEXTURE_COORD_ARRAY);


glDisable(GL_TEXTURE_2D); //glDisable(GL_TEXTURE_2D);
}

void reshape(GLint width, GLint height) {
glViewport(0, 0, width, height);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(65.0, (float)width / height, 1, 100);
glMatrixMode(GL_MODELVIEW);
}

void keyboard(unsigned char key, int x, int y){

}
Model::Obj m = Model::Obj();
void display(void) {
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glLoadIdentity();
glTranslatef(0, 0, -6);
glColor3f(1,1,1);
draw(&m);
glutSwapBuffers();
int i;
if(i = glGetError())
std::cerr << "OpenGL Error" << std::endl;
} }


void main(int argc, char** argv){ void main(int argc, char** argv){
glutInit (&argc, argv);
glutInitWindowSize (800, 600);
glutInitDisplayMode ( GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH);
glutCreateWindow ("Model Loader Example");
glutReshapeFunc (reshape);
glutKeyboardFunc (keyboard);
glutDisplayFunc (display);
glShadeModel(GL_SMOOTH); // Enable Smooth Shading
glClearColor(0.0f, 0.0f, 0.0f, 1.0f); // Black Background
glClearDepth(1.0f); // Depth Buffer Setup
glEnable(GL_DEPTH_TEST); // Enables Depth Testing
glDepthFunc(GL_LEQUAL); // The Type Of Depth Testing To Do
/* /*
//TODO, parse argv //TODO, parse argv
if(argc < 1){ if(argc < 1){
usage(); usage();
return; return;
} }
*/ */

m.load("cube.obj");
Model::Model* m = new Model::Obj(); glutMainLoop ();
m->load("cube.obj");

} }
5 changes: 5 additions & 0 deletions Model.cpp
Expand Up @@ -3,6 +3,11 @@ namespace Model {
Model::Model(){ Model::Model(){
totalConnectedTriangles = 0; totalConnectedTriangles = 0;
totalConnectedPoints = 0; totalConnectedPoints = 0;

vertices = new std::vector<float>();
triangles = new std::vector<float>();
normals = new std::vector<float>();
textureCoordinates = new std::vector<float>();
} }


float* Model::calculateNormal(float* coord1, float* coord2, float* coord3){ float* Model::calculateNormal(float* coord1, float* coord2, float* coord3){
Expand Down
17 changes: 13 additions & 4 deletions Model.h
Expand Up @@ -12,6 +12,7 @@
#include <string> #include <string>
#include <vector> #include <vector>
#include <cmath> #include <cmath>
#include <vector>
namespace Model { namespace Model {
#define POINTS_PER_VERTEX 3 #define POINTS_PER_VERTEX 3
#define TOTAL_FLOATS_IN_TRIANGLE 9 #define TOTAL_FLOATS_IN_TRIANGLE 9
Expand All @@ -23,13 +24,21 @@ namespace Model {
virtual bool Model::load(char *filename) = 0; virtual bool Model::load(char *filename) = 0;
virtual void Model::release() = 0; virtual void Model::release() = 0;


float* normals; std::vector<float>* normals;
float* triangles; std::vector<float>* triangles;
float* vertices; std::vector<float>* vertices;
float* textures; std::vector<float>* textureCoordinates;
long totalConnectedPoints; long totalConnectedPoints;
long totalConnectedTriangles; long totalConnectedTriangles;
}; };
template <class T>
bool from_string(T& t,
const std::string& s,
std::ios_base& (*f)(std::ios_base&))
{
std::istringstream iss(s);
return !(iss >> f >> t).fail();
}
} }


#endif // Model_h__ #endif // Model_h__
132 changes: 57 additions & 75 deletions Obj.cpp
@@ -1,93 +1,75 @@
#include "Obj.h" #include "Obj.h"
#include "Tokenizer.h"


namespace Model { namespace Model {
bool Obj::load(char* filename) { bool Obj::load(char* filename) {
std::string line; std::string line;
std::ifstream objFile (filename); std::ifstream objFile(filename);
if (objFile.is_open() == false) // we could not open the file if (objFile.is_open() == false)
return false; return false;


objFile.seekg (0, std::ios::end); // Go to end of the file, objFile.seekg (0, std::ios::end);
long fileSize = objFile.tellg(); // get file size long fileSize = objFile.tellg();
objFile.seekg (0, std::ios::beg); // we'll use this to register memory for our 3d model objFile.seekg (0, std::ios::beg);


vertices = new float[fileSize]; // Allocate memory for the vertices // TODO make a better guess
triangles = new float[fileSize]; // Allocate memory for the triangles vertices->reserve(fileSize);
normals = new float[fileSize]; // Allocate memory for the normals normals->reserve(fileSize);

triangles->reserve(fileSize);
int triangle_index = 0; // Set triangle index to zero
int normal_index = 0; // Set normal index to zero int triangle_index = 0;

int normal_index = 0;
while (! objFile.eof() ) // Start reading file data
{ while (! objFile.eof() ) {
getline (objFile,line); // Get line from file getline (objFile,line);

Tokenizer tokenizer(line," ");
if (line.c_str()[0] == 'v') // The first character is a v: on this line is a vertex stored. while(tokenizer.NextToken()){
{ std::string lineType = tokenizer.GetToken();
line[0] = ' '; // Set first character to 0. This will allow us to use sscanf if(lineType == "v"){

parseVertex(tokenizer);
sscanf(line.c_str(),"%f %f %f ", // Read floats from the line: v X Y Z } else if (lineType == "f"){
&vertices[totalConnectedPoints], parseFace(tokenizer);
&vertices[totalConnectedPoints+1], totalConnectedTriangles++;
&vertices[totalConnectedPoints+2]); } else if (lineType == "#") {
// Line is a comment
} else {
std::cout << "Unhandled line: " << line << std::endl;
}


totalConnectedPoints += POINTS_PER_VERTEX; // Add 3 to the total connected points break;
} }
else if (line.c_str()[0] == 'f') // The first character is an 'f': on this line is a point stored
{
line[0] = ' '; // Set first character to 0. This will allow us to use sscanf

int vertexNumber[4] = { 0, 0, 0 };
sscanf(line.c_str(),"%i%i%i", // Read integers from the line: f 1 2 3
&vertexNumber[0], // First point of our triangle. This is an
&vertexNumber[1], // pointer to our vertices list
&vertexNumber[2] ); // each point represents an X,Y,Z.

vertexNumber[0] -= 1; // OBJ file starts counting from 1
vertexNumber[1] -= 1; // OBJ file starts counting from 1
vertexNumber[2] -= 1; // OBJ file starts counting from 1


/********************************************************************
* Create triangles (f 1 2 3) from points: (v X Y Z) (v X Y Z) (v X Y Z).
* The vertices contains all verteces
* The triangles will be created using the verteces we read previously
*/


int tCounter = 0; }
for (int i = 0; i < POINTS_PER_VERTEX; i++) { objFile.close();
triangles[triangle_index + tCounter ] = vertices[3*vertexNumber[i] ]; triangles->resize(triangles->size());
triangles[triangle_index + tCounter +1 ] = vertices[3*vertexNumber[i]+1 ]; normals->resize(normals->size());
triangles[triangle_index + tCounter +2 ] = vertices[3*vertexNumber[i]+2 ]; textureCoordinates->resize(textureCoordinates->size());
tCounter += POINTS_PER_VERTEX;
}


/********************************************************************* return true;
* Calculate all normals, used for lighting }
*/
float coord1[3] = { triangles[triangle_index], triangles[triangle_index+1],triangles[triangle_index+2]};
float coord2[3] = {triangles[triangle_index+3],triangles[triangle_index+4],triangles[triangle_index+5]};
float coord3[3] = {triangles[triangle_index+6],triangles[triangle_index+7],triangles[triangle_index+8]};
float *norm = calculateNormal( coord1, coord2, coord3 );


tCounter = 0; void Obj::parseVertex(Tokenizer& tokenizer){
for (int i = 0; i < POINTS_PER_VERTEX; i++) { float f;
normals[normal_index + tCounter ] = norm[0]; while(tokenizer.NextToken()){
normals[normal_index + tCounter +1] = norm[1]; if(from_string<float>(f,tokenizer.GetToken(),std::dec))
normals[normal_index + tCounter +2] = norm[2]; vertices->push_back(f);
tCounter += POINTS_PER_VERTEX; else
} std::cerr << "Error parsing token into vertex component: " << tokenizer.GetToken() << std::endl;
}
totalConnectedPoints += POINTS_PER_VERTEX;
}


triangle_index += TOTAL_FLOATS_IN_TRIANGLE; void Obj::parseFace(Tokenizer& tokenizer){
normal_index += TOTAL_FLOATS_IN_TRIANGLE; int vertexNumber[3] = { 0, 0, 0 };
totalConnectedTriangles += TOTAL_FLOATS_IN_TRIANGLE;
} else { for(int i = 0; i < 3; ++i){
std::cout << "Unhandled line: " << line << std::endl; tokenizer.NextToken();
if(from_string<int>(vertexNumber[i],tokenizer.GetToken(),std::dec)){
triangles->push_back(vertices->at( vertexNumber[i]- 1));
} }
else
std::cerr << "Error parsing token into face component: " << tokenizer.GetToken() << std::endl;
} }
objFile.close(); // Close OBJ file

return true;
} }


void Obj::release() { void Obj::release() {
Expand Down
5 changes: 5 additions & 0 deletions Obj.h
Expand Up @@ -10,12 +10,17 @@
*/ */


#include "Model.h" #include "Model.h"
#include "Tokenizer.h"


namespace Model { namespace Model {
class Obj : public Model { class Obj : public Model {
public: public:
bool Obj::load(char *filename); // Loads the model bool Obj::load(char *filename); // Loads the model
void Obj::release(); // Release the model void Obj::release(); // Release the model

private:
void parseVertex(Tokenizer& tokenizer);
void parseFace(Tokenizer& tokenizer);
}; };
} }


Expand Down
10 changes: 5 additions & 5 deletions Ply.cpp
Expand Up @@ -31,16 +31,16 @@ namespace Model {
long fileSize = ftell(file); long fileSize = ftell(file);


try { try {
vertices = (float*) malloc (ftell(file)); // vertices = (float*) malloc (ftell(file));
} }
catch (char* ) { catch (char* ) {
return false; return false;
} }
if (vertices == NULL) return -1; if (vertices == NULL) return -1;
fseek(file,0,SEEK_SET); fseek(file,0,SEEK_SET);


triangles = (float*) malloc(fileSize*sizeof(float)); // triangles = (float*) malloc(fileSize*sizeof(float));
normals = (float*) malloc(fileSize*sizeof(float)); // normals = (float*) malloc(fileSize*sizeof(float));


int i = 0; int i = 0;
int temp = 0; int temp = 0;
Expand Down Expand Up @@ -124,7 +124,7 @@ namespace Model {
triangles[triangle_index+6] = vertices[3*vertex3]; triangles[triangle_index+6] = vertices[3*vertex3];
triangles[triangle_index+7] = vertices[3*vertex3+1]; triangles[triangle_index+7] = vertices[3*vertex3+1];
triangles[triangle_index+8] = vertices[3*vertex3+2]; triangles[triangle_index+8] = vertices[3*vertex3+2];

/*
float coord1[3] = { triangles[triangle_index], triangles[triangle_index+1],triangles[triangle_index+2]}; float coord1[3] = { triangles[triangle_index], triangles[triangle_index+1],triangles[triangle_index+2]};
float coord2[3] = {triangles[triangle_index+3],triangles[triangle_index+4],triangles[triangle_index+5]}; float coord2[3] = {triangles[triangle_index+3],triangles[triangle_index+4],triangles[triangle_index+5]};
float coord3[3] = {triangles[triangle_index+6],triangles[triangle_index+7],triangles[triangle_index+8]}; float coord3[3] = {triangles[triangle_index+6],triangles[triangle_index+7],triangles[triangle_index+8]};
Expand All @@ -139,7 +139,7 @@ namespace Model {
normals[normal_index+6] = norm[0]; normals[normal_index+6] = norm[0];
normals[normal_index+7] = norm[1]; normals[normal_index+7] = norm[1];
normals[normal_index+8] = norm[2]; normals[normal_index+8] = norm[2];

*/
normal_index += 9; normal_index += 9;


triangle_index += 9; triangle_index += 9;
Expand Down
47 changes: 47 additions & 0 deletions Tokenizer.cpp
@@ -0,0 +1,47 @@
#include "Tokenizer.h"
// From user vzczc
// post http://stackoverflow.com/questions/53849/how-do-i-tokenize-a-string-in-c


const std::string Tokenizer::DELIMITERS(" \t\n\r");

Tokenizer::Tokenizer(const std::string& s) :
m_string(s),
m_offset(0),
m_delimiters(DELIMITERS) {}

Tokenizer::Tokenizer(const std::string& s, const std::string& delimiters) :
m_string(s),
m_offset(0),
m_delimiters(delimiters) {}

bool Tokenizer::NextToken()
{
return NextToken(m_delimiters);
}

const std::string Tokenizer::GetToken() const{
return m_token;
}

bool Tokenizer::NextToken(const std::string& delimiters)
{
size_t i = m_string.find_first_not_of(delimiters, m_offset);
if (std::string::npos == i)
{
m_offset = m_string.length();
return false;
}

size_t j = m_string.find_first_of(delimiters, i);
if (std::string::npos == j)
{
m_token = m_string.substr(i);
m_offset = m_string.length();
return true;
}

m_token = m_string.substr(i, j - i);
m_offset = j;
return true;
}

0 comments on commit 28ba3fd

Please sign in to comment.