Skip to main content
gamedev.net
🔒 Locked

rendering a model/mesh

Started by ninmonkeys 4 replies 1.1k views
Original Post
ninmonkeys
ninmonkeys
Hello. I've been through some nehe tutorials, but I still consider myself really new to OpenGL. I'm loading a 3d model/mesh and rendering it in OpenGL. I'm using the .obj loader I found by justinrwalsh in this thread: justinrwalsh's source code from that thread The cube mesh is also from that thread(in the zip). The penguin is a mesh I created, and exported to .obj format. 1) I'm not sure how I should be rendering the mesh. I think I just use a list of vertices (multiples of 3) using GL_TRIANGLES, but it's not working. So far only the point rendering mode is appearing right. All of my attempts to use GL_TRIANGLES, or anything besides points all render incorrectly. I think I'm using the wrong vertices order, but how do I figure out the right order? I think if it did render 'correct' , it would be the silloute of the mesh in white based on my current settings. ModeTriangles_Group *appears* to be rendering the cube correctly, it has a sillouete of the cube. But with the penguin mesh, this renders nothing in this mode! ModeTriangles_Broke is used in the screenshot. It looks as if it's not using vertices that make a face, but almost random vertices. ModePoints Correct, but it should be since it doesn't matter what order the vertices are in for this mode? If the below images don't work, here's another url: mesh problems penguin. (I tested regular and triangulate ) justinwalsh's cube: This is my rendering code:

void renderGL(void)
{
    //clear the screen and the depth buffer
    glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );

    //reset the view
    glLoadIdentity();


    //translate world
    glTranslatef( 0.0f, 0.0f, world_z ); //default: -12ish

    //rotate y-axis
    glRotatef(world_rotate_y, 0.0f, 1.0f, 0.0f);//rotate on y-axis

    //rotate x-axis
    glRotatef(world_rotate_x, 1.0f, 0.0f, 0.0f);//rotate on x-axis

    if(render_mode == ModeTriangles_Broke)
    {

        //render mesh using triangles but it's not right
            //both wrong, must need to draw GL_TRIANGLES using every 3 verts ?
        glBegin( GL_TRIANGLES );
        //glBegin( GL_POLYGON ); or GL_TRIANGLES?
            for( int i = 0; i < Modeldata.NumVertex; i++ )
            {
                glVertex3f(
                    Modeldata.VertexArray.X,
                    Modeldata.VertexArray.Y,
                    Modeldata.VertexArray.Z );
            }
        glEnd();
    }else if ( render_mode == ModeTriangles_Group)
    {
        glBegin( GL_TRIANGLES );
        //render mesh using triangles, or faces
        for(int i = 0; i < Modeldata.NumTriangle; i++)
        {
            /*
            glVertex3f(
                Modeldata.TriangleArray.Vertex[0],
                Modeldata.TriangleArray.Vertex[1],
                Modeldata.TriangleArray.Vertex[2] ); */

            glVertex3f(
                Modeldata.VertexArray[Modeldata.TriangleArray.Vertex[0]].X,
                Modeldata.VertexArray[Modeldata.TriangleArray.Vertex[0]].Y,
                Modeldata.VertexArray[Modeldata.TriangleArray.Vertex[0]].Z );

            glVertex3f(
                Modeldata.VertexArray[Modeldata.TriangleArray.Vertex[1]].X,
                Modeldata.VertexArray[Modeldata.TriangleArray.Vertex[1]].Y,
                Modeldata.VertexArray[Modeldata.TriangleArray.Vertex[1]].Z );

            glVertex3f(
                Modeldata.VertexArray[Modeldata.TriangleArray.Vertex[2]].X,
                Modeldata.VertexArray[Modeldata.TriangleArray.Vertex[2]].Y,
                Modeldata.VertexArray[Modeldata.TriangleArray.Vertex[2]].Z );

        }
        glEnd();

    } else if (render_mode == ModePoints)
    {
        //render mesh using points
        glBegin( GL_POINTS );
            for( int i = 0; i < Modeldata.NumVertex; i++ )
            {
                glVertex3f(
                    Modeldata.VertexArray.X,
                    Modeldata.VertexArray.Y,
                    Modeldata.VertexArray.Z );
            }
        glEnd();

    }
    SDL_GL_SwapBuffers();
}


2) A strange thing when running this program, if I click on other windows I loose all my icons on windows, System tray's window list has no icons, window titlebars have strange colors. The title bars even became partly transparent, then stopped updating. (Meaning the titlebars have artifacts on them ) Note: this only happened when I used glBegin( GL_TRIANGLES ); and not glBegin( GL_POLYGON ); I found out I can 'fix' the icons/etc. if I run the program again, don't change model, and quit. The problem only happens if change the model, while using GL_TRIANGLES. ( ModeTriangles_Broke ) Does that mean there's some pointer clean up issue in the code? Looking at the code, I think it cleans up correctly if LoadObj() is called repeatedly? Even with a pointer problem, I thought that would cause a crash, and not be able to mess with the OS's icons and drawing on objects that I had no control over. Here's what I'm using to switch models:
                   //load: his cube
                    case SDLK_1:
                        //load model:
                        ModelLoader.LoadObj("ObjLoader/customCube.obj");
                        Modeldata = ModelLoader.ReturnObj();
                        break;

                    //load: my penguin
                    case SDLK_2:
                        ModelLoader.LoadObj("jake/penguin.obj");
                        Modeldata = ModelLoader.ReturnObj();
                        break;



-- thanks
6
6
First off, it looks like you penguin is made of quads. If you use the triangle strip method then only 3 of your 4 vertices are going to be rendered and thats why there are gaps. Change your model to be composed just of triangles and then load it into your app again.
----------------------------------------------------
Check out my casual TBS game blog
----------------------------------------------------
Winterhell
Winterhell
the model is already triangulated,see the lightning;
maybe the issue is the following-in the obj file the face indexes start with 1,2,3, ,and you use 0,1,2,3, in the game,so the problem.you have several solutions if this is the case: the loop for loading verts starts with for(i=1;... ,or ,which i prefer more,during loading faces indices,reduce all of them with one.
As i see from your post,you dont use faces list,only the vertex list.The face list contains 3 integers per face(a,b,c) ,which shows which vertices are together. The same way the vertex list contains 3 floats(x,y,z)
ninmonkeys
ninmonkeys
Quote:
6: First off, it looks like you penguin is made of quads. If you use the triangle strip method then only 3 of your 4 vertices are going to be rendered and thats why there are gaps. Change your model to be composed just of triangles and then load it into your app again.
My code loads two versions of my penguin that I can switch through, one of them is the regular export (quads) and the other I used triangulate should remove quads.

Quote:
Original post by Winterhell
the model is already triangulated,see the lightning;
maybe the issue is the following-in the obj file the face indexes start with 1,2,3, ,and you use 0,1,2,3, in the game,so the problem.you have several solutions if this is the case: the loop for loading verts starts with for(i=1;... ,or ,which i prefer more,during loading faces indices,reduce all of them with one.
As i see from your post,you dont use faces list,only the vertex list.The face list contains 3 integers per face(a,b,c) ,which shows which vertices are together. The same way the vertex list contains 3 floats(x,y,z)
How do I use the face list? In his code I think he's showing an example of this, but when I tried to iterate through it didn't work.

(snippit of his code, using a face list? )
	ObjModel data;	ObjLoader LoaderClass;	LoaderClass.LoadObj("customCube.obj");	data = LoaderClass.ReturnObj();	cout << "Object Model has: " << data.NumTriangle << " faces! \n";	for(int i = 0; i < data.NumVertex; i++)  {		cout << data.VertexArray.X			 << " "			 << data.VertexArray.Y			 << " "			 << data.VertexArray.Z			 << "\n";	}	for(i = 0; i < data.NumTriangle; i++)  {		cout << "Indacies into faces:\n";		cout << data.TriangleArray.Vertex[0]			 << " "			 << data.TriangleArray.Vertex[1]			 << " "			 << data.TriangleArray.Vertex[2]			 << "\n";	}	cout << "Vertex from triangle info]:\n";	cout << data.VertexArray[data.TriangleArray[1].Vertex[0]].X		 << " "		 << data.VertexArray[data.TriangleArray[1].Vertex[0]].Y		 << " "		 << data.VertexArray[data.TriangleArray[1].Vertex[0]].Z		 << "\n"		 << data.VertexArray[data.TriangleArray[1].Vertex[1]].X		 << " "		 << data.VertexArray[data.TriangleArray[1].Vertex[1]].Y		 << " "		 << data.VertexArray[data.TriangleArray[1].Vertex[1]].Z		 << "\n"		 << data.VertexArray[data.TriangleArray[1].Vertex[2]].X		 << " "		 << data.VertexArray[data.TriangleArray[1].Vertex[2]].Y		 << " "		 << data.VertexArray[data.TriangleArray[1].Vertex[2]].Z		 << "\n";

I tried to iterate like the example in the code render_mode == ModeTriangles_Group, which appears render the cube correctly. But the penquin (both versions) render nothing. So maybe that code is correct, or near correct and I need to change more options on exporting?
Shabadoo
Shabadoo
Quote:
My code loads two versions of my penguin that I can switch through, one of them is the regular export (quads) and the other I used triangulate should remove quads.


Umm.. this may be a stupid question, but if you're rendering a model you have exported as quads, why doesn't your renderGL() method have a call to glBegin(GL_QUADS)?

From what it looks like in your images you're either trying to render quads as triangles so the vertex indices get messed up or you aren't referencing the correct vertex when you're creating your faces.


ninmonkeys
ninmonkeys
Quote:
Original post by Shabadoo
From what it looks like in your images you're either trying to render quads as triangles so the vertex indices get messed up or you aren't referencing the correct vertex when you're creating your faces.
I had GL_QUADS at one point while I've been trying to figure this out.

If I'm going to render quads, would I be iterating through groups of 4 vertices that share the same face? And the same for triangles only groups of 3? Because right now I'm not sure how to get 3 coordinates from the triangles list, it looks like there's only one coordinate per triangle?)

How should I be iterating through the list? Here's the header file showing what information and lists it has:
/*-----------------------------------------------------------------//// April 10, 2005                                                  ////                                Copyright (C) 2005  Justin Walsh ////                                                                 ////  This code is Released Under the GNU GPL                        ////       http://www.gnu.org/copyleft/gpl.html                      ////                                                                 ////  Shout out to GDNet+ member: Ranger_One                         ////-----------------------------------------------------------------*/#ifndef OBJLOADER_H#define OBJLOADER_H#include <fstream>#include <string>#include <sstream>using namespace std;/*-----------------------------------------------------------------////Here we have our data types our loader class will need and use...////                                                                 */	struct ObjVertex{		 float X, Y, Z;	};	struct ObjNormal{		 float X, Y, Z;	};	struct ObjTexCoord{		 float U, V;	};	struct ObjTriangle{		int Vertex[3];		int Normal[3];		int TexCoord[3];	};	class ObjModel {		public:			ObjModel();			~ObjModel();			ObjModel(const ObjModel& copy);			ObjModel& operator=(const ObjModel& right);			int NumVertex, NumNormal, NumTexCoord, NumTriangle;			ObjVertex *VertexArray;			ObjNormal *NormalArray;			ObjTexCoord *TexCoordArray;			ObjTriangle *TriangleArray;	};/*                                                                 ////-----------------------------------------------------------------*//*-----------------------------------------------------------------////     The meat of the sandwitch, the class to load .obj files     ////                                                                 */	class ObjLoader  {		public:			ObjLoader();			~ObjLoader();			ObjLoader(string file);			void LoadObj(string file);			void FreeObj(void);			ObjModel ReturnObj(void);		protected:			string *fileName;			ObjModel *theObj;			void ReadData(void);	};/*                                                                 ////-----------------------------------------------------------------*/#endif

I read through the loading code again, and tried to iterate through faces, rendering each triangle. I thought I would get 3 vertices for each face, but I either am using it wrong, or there's just one? Here's what I came up with:
         glBegin( GL_TRIANGLES );        //test iterate through each face, based on the loading code:            // theObj->TriangleArray[fC].Vertex[0] = atoi(temp.c_str()) - 1;            for( int i = 0; i < Modeldata.NumTriangle; i++ )            {                glVertex3f(                    Modeldata.TriangleArray.Vertex[0],                    Modeldata.TriangleArray.Vertex[1],                    Modeldata.TriangleArray.Vertex[2] );            }        glEnd();

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.