OBJ loader

Started by
3 comments, last by Zarathustra 15 years, 10 months ago
So in my display function I have this code

void display()
{

//Basic rendering to FBO 1
	glMatrixMode(GL_MODELVIEW);
	glLoadIdentity();
	gluLookAt(d*sqrt3,d*sqrt3,d*sqrt3,
		0.0,0.0,0.0,
		0.0,1.0,0.0);
	glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fb[0].fbobj);

	glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT);
	glEnable(GL_DEPTH_TEST);
	

	bindCgPrograms();
	
	glPushMatrix();
	glRotatef(angle,0.0,1.0,0.0);
	glRotatef(angleZ,1.0,0.0,0.0);

	glFrontFace(GL_CW);
	glutSolidTeapot(1.0);
	glFrontFace(GL_CCW);

	glPopMatrix();

	unBindCgPrograms();

	glDisable(GL_DEPTH_TEST);

..

which gives me my image of teapot but the glut teapot has some flaws so I wanted to read in an .obj file. Which results in this code

// OBJ loader
struct Triangle {
       
       int v1;
       int v2;
       int v3;
       
};

struct Vertex {
      
      float x;
      float y;
      float z;
            
};

Vertex v[50000];
Triangle t[50000];
    
int vertexCount = 0;
int triangleCount = 0;

void loadOBJ(){
	cout<<"Load obj file"<<endl;
	char line[100];
    
    FILE *fp = fopen("cone.obj","r");
    cout<<"tree.obj open"<<endl;
    if (fp != NULL)
    {
        while (fgets(line, 99, fp))
        {
              if (line[0] == 'v')
              {
                  sscanf(line, "%*c %f %f %f", &v[vertexCount].x, &v[vertexCount].y, &v[vertexCount].z);                  
                  vertexCount++;
              } 
              else if (line[0] == 'f')
              {
                  sscanf(line, "%*c %d %d %d", &t[triangleCount].v1, &t[triangleCount].v2, &t[triangleCount].v3);
                  triangleCount++;
              }   
        }   
	}else{
		cout<<"file not found!"<<endl;
	}
    
    fclose(fp);
}
// end OBJ loader

and this code in the display function

void display()
{

//Basic rendering to FBO 1
	glMatrixMode(GL_MODELVIEW);
	glLoadIdentity();
	gluLookAt(d*sqrt3,d*sqrt3,d*sqrt3,
		0.0,0.0,0.0,
		0.0,1.0,0.0);
	glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fb[0].fbobj);

	glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT);
	glEnable(GL_DEPTH_TEST);
	

	bindCgPrograms();
	
	glPushMatrix();
	glRotatef(angle,0.0,1.0,0.0);
	glRotatef(angleZ,1.0,0.0,0.0);

	glBegin(GL_TRIANGLES);
    
    for (int i=0; i<triangleCount; i++)
        {
            glVertex3f(v[t.v1-1].x * 0.25, v[t.v1-1].y * 0.25, v[t.v1-1].z * 0.25);
            glVertex3f(v[t.v2-1].x * 0.25, v[t.v2-1].y * 0.25, v[t.v2-1].z * 0.25);
            glVertex3f(v[t.v3-1].x * 0.25, v[t.v3-1].y * 0.25, v[t.v3-1].z * 0.25);
        }
	glEnd();

	glPopMatrix();

	unBindCgPrograms();

	glDisable(GL_DEPTH_TEST);


Now I get the object I want but it's just white whereas when I use the glutsolids my cg shaders are being used as expected and I get some nice realtime env mapping. Can anyone tell me what I'm doing wrong?
Advertisement
You obvioulsly also have to pass some normal vectors and maybe also texture coordinates!
thanks :)

but now I implemented this

// OBJ loaderstring getWord(string Line, int Pos){    vector<string> Vec;    stringstream ss(Line);    string Word, a;    while(ss >> Word)    Vec.push_back(Word);    if(Pos > Vec.size()-1) //Check whether it's in range        return "";    else    {        try { a = Vec.at(Pos); } //Just to be safe        catch(...) { a = ""; } //I'm not sure what to catch        return a; //Return the word    }}int convertToInt(string Num){    istringstream i(Num);    int x;    if(!(i >> x))        throw 0;    return x;}float convertToFloat(string Num){    istringstream i(Num);    float x;    if(!(i >> x))        throw 0;    return x;}struct Vector {    float x, y, z;};struct Vertex {    Vector Pos;    Vector Normal;};struct Triangle {    int v1, v2, v3; //One for each of our corners!};class Model{	private: //So we can't change them willy nilly        Triangle Triangles[50000]; //As .obj files don't tell us how many faces                                   //we have, we have to take a guess, feel free to change the amount for                                  //bigger models, the most I've come across is 130k        Vertex Verticies[50000];  //Same as above        int TriangleCount; //Keep track of the amount of triangles we have        int VertexCount; //Keep track of the amount of Vertices we have        int NormalCount; //Keep track of the amount of normals we have        bool Loaded; //So we know whether it's been loaded of not		public: //So we can access the functions        Model(){			VertexCount = 1; //Start on 1			TriangleCount = 1; //Start on 1			NormalCount = 1; //Start on 1			Loaded = false; //We haven't loaded a model yet!		}		int Load(const char* Filename){			ifstream F; //Our file			string Line; //The current line of the file			F.open(Filename, ios::in);			if(F.fail()){				cout << "Error opening \"" << Filename << "\"" << endl; //Send an error message				return 0; //Exit the function			}			if(Loaded){ //If loaded is true				VertexCount = 1; //Reset				TriangleCount = 1; //Reset				NormalCount = 1; //Reset			}			while(!F.eof()){				getline(F, Line);				if(getWord(Line, 0) == "v") //If the first word is v				{					if(VertexCount > 50000) break; //If we're exceeding our 50000 we'd better stop					Verticies[VertexCount].Pos.x = convertToFloat(getWord(Line, 1)); //Set our x location to the second word of the line.					Verticies[VertexCount].Pos.y = convertToFloat(getWord(Line, 2)); //Set our y variable to the thrid word of the line.					Verticies[VertexCount].Pos.z = convertToFloat(getWord(Line, 3)); //Set our z variable to the fourth word of the line.					VertexCount++; //Next vertex please!					}			else if(getWord(Line, 0) == "vn") //If it wasn't v is it vn?			{				if(NormalCount > 50000) break; //Are we about to exceed the limit?				Verticies[NormalCount].Normal.x = convertToFloat(getWord(Line, 1));				Verticies[NormalCount].Normal.y = convertToFloat(getWord(Line, 2));				Verticies[NormalCount].Normal.z = convertToFloat(getWord(Line, 3));				NormalCount++; //Next Normal Please!			}			else if(getWord(Line, 0) == "f") //If it wasn't v or vn then is it a face?			{				if(TriangleCount > 50000) break; //Check to see if we're exceeding limit again				Triangles[TriangleCount].v1 = convertToInt(getWord(Line, 1));				Triangles[TriangleCount].v2 = convertToInt(getWord(Line, 2));				Triangles[TriangleCount].v3 = convertToInt(getWord(Line, 3));				TriangleCount++; //Next triangle please!			}	} //Close while Loop!	F.close();	Loaded = true;	cout << "Triangles: " << TriangleCount-1 << endl;	cout << "Vertecies: " << VertexCount-1 << endl;	cout << "Normals: " << NormalCount-1 << endl;	}		void Draw(void){			if(Loaded){				glBegin(GL_TRIANGLES); //Say we're using triangles!				 for(int i = 1; i < TriangleCount; i++) //For each face					{					glNormal3f(Verticies[Triangles.v1].Normal.x, Verticies[Triangles.v1].Normal.y, Verticies[Triangles.v1].Normal.z);					glVertex3f(Verticies[Triangles.v1].Pos.x, Verticies[Triangles.v1].Pos.y, Verticies[Triangles.v1].Pos.z);		            					glNormal3f(Verticies[Triangles.v2].Normal.x, Verticies[Triangles.v2].Normal.y, Verticies[Triangles.v2].Normal.z);					glVertex3f(Verticies[Triangles.v2].Pos.x, Verticies[Triangles.v2].Pos.y, Verticies[Triangles.v2].Pos.z);		            					glNormal3f(Verticies[Triangles.v3].Normal.x, Verticies[Triangles.v3].Normal.y, Verticies[Triangles.v3].Normal.z);					glVertex3f(Verticies[Triangles.v3].Pos.x, Verticies[Triangles.v3].Pos.y,Verticies[Triangles.v3].Pos.z);					}				glEnd(); //Stop drawing!			}		}};// end OBJ loader



the problem is that my textures are oriented ok on my glutSolidTeapot, but on the obj models I load they seem to be turned 90°. I can't really figure out why this is :/ any help ?
In case the texture coordinates are wrong I would have guessed the images would appear flipped in the y direction which then may be due to the way you load the textures. But as a workaround you could try to simply rotate the texture coordinates 90° back?

Also, how do you see the texture coordinates are off when you don't even send them to the OpenGL API? There should be glTexCoord* calls in there.
well, I don't really texture the object actually

what I did with the glut teapot is I render it like this

bindCgPrograms();		glPushMatrix();	glRotatef(angle,0.0,1.0,0.0);	glRotatef(angleZ,1.0,0.0,0.0);	glutSolidTeapot(1.0);	glPopMatrix();	unBindCgPrograms();

and the I uploaded a texture to the shader which does some freaky stuff with it but it textures based on the angle the reflect vector makes.. so I don't use texture coördinates


edit: and to illustrate

object loader
glut

nothing changed to the program except in the first one I use the obj loader, in the second the glut teapot

[Edited by - Zarathustra on June 16, 2008 12:15:37 PM]

This topic is closed to new replies.

Advertisement