Jump to content
  • Advertisement
Sign in to follow this  
Zarathustra

OBJ loader

This topic is 3661 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

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?

Share this post


Link to post
Share on other sites
Advertisement
You obvioulsly also have to pass some normal vectors and maybe also texture coordinates!

Share this post


Link to post
Share on other sites
thanks :)

but now I implemented this


// OBJ loader
string 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 ?

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites
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]

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

Participate in the game development conversation and more when you create an account on GameDev.net!

Sign me up!