As a part of my project i need to draw some 3d models.
dont have time to learn about 3ds files and how to load them, which looks to me pretty complicated, so i found functions on the web, but the object wont render (or maybe render but not seen).
here is the relevant source code :
void initGL(int *argc, char **argv)
{
glutInit(argc, argv);
glutInitDisplayMode(GLUT_RGB | GLUT_DEPTH | GLUT_DOUBLE);
glutInitWindowSize(width, height);
glutCreateWindow("CUDA Particle System");
GLenum err = glewInit();
if (GLEW_OK != err)
{
printf ("Error: openGL is not supported");
exit (0);
}
glEnable(GL_DEPTH_TEST);
glEnable (GL_CULL_FACE);
glCullFace(GL_FRONT);
glClearColor( 0.7, 0.7 , 0.9 , 0 );
glutReportErrors();
glFrustum(-1,1,-1,1,0.3,100);
Chesspawn.load( &chesspawn ,"chesspawn.3DS");
/*glClear (GL_COLOR_BUFFER_BIT);
glColor3f ( 0.7, 0.7 , 0.9 );
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(-1,1,-1,1,-1,1);
gluLookAt(0,0,0,0,0,-100,0,1,0);
glViewport (250, 250, width, height);*/
}
void display()
{
sdkStartTimer(&timer.timer);
p_system->update(time_Step);
//set Positions vbo
renderer->setVertexBuffer(p_system->getPosVbo(),p_system->getNumParticles());
//render
glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
// view transform
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glGetFloatv(GL_MODELVIEW_MATRIX, modelView);
gluLookAt (Params_Camera[CAMERA_X], Params_Camera[CAMERA_Y], Params_Camera[CAMERA_Z], // camera
Params_Camera[CAMERA_X] + Params_Camera[DIR_X], Params_Camera[CAMERA_Y] , Params_Camera[CAMERA_Z] + Params_Camera[DIR_Z], // center
0, 1, 0 // up
);
renderer->display();
drawFloor();
glScaled (0.001,0.001,1);
Chesspawn.render(&chesspawn);
//glutSolidSphere (0.5,50,50);
/*glTranslated (0,0,-10);
glutSolidSphere(0.1,20,20);*/
sdkStopTimer(&timer.timer);
glutSwapBuffers();
glutReportErrors();
char sFps[256];
fps = timer.computeFps();
sprintf(sFps, " %s: %d particles %3.1f fps",proc, numParticles, fps);
if (fps <24.0)
printf ("Slow fps : %f \n", fps);
glutSetWindowTitle(sFps);
}
and this is the load and render functions:
static char C_3dsObject::load (obj_type_ptr p_object, char *p_filename)
{
int i; //Index variable
int File_Length = 0;
FILE *l_file; //File pointer
unsigned short l_chunk_id; //Chunk identifier
unsigned int l_chunk_lenght; //Chunk lenght
unsigned char l_char; //Char variable
unsigned short l_qty; //Number of elements in each chunk
unsigned short l_face_flags; //Flag that stores some face information
if ((l_file=fopen (p_filename, "rb"))== NULL)
return 0; //Open the file
fseek (l_file, 0, SEEK_END); // get file length
File_Length = ftell (l_file);
fseek(l_file, 0L, SEEK_SET);
while (ftell (l_file) < File_Length ) //Loop to scan the whole file
{
//getche(); //Insert this command for debug (to wait for keypress for each chuck reading)
fread (&l_chunk_id, 2, 1, l_file); //Read the chunk header
//printf("ChunkID: %x\n",l_chunk_id);
fread (&l_chunk_lenght, 4, 1, l_file); //Read the lenght of the chunk
//printf("ChunkLenght: %x\n",l_chunk_lenght);
switch (l_chunk_id)
{
//----------------- MAIN3DS -----------------
// Description: Main chunk, contains all the other chunks
// Chunk ID: 4d4d
// Chunk Lenght: 0 + sub chunks
//-------------------------------------------
case 0x4d4d:
break;
//----------------- EDIT3DS -----------------
// Description: 3D Editor chunk, objects layout info
// Chunk ID: 3d3d (hex)
// Chunk Lenght: 0 + sub chunks
//-------------------------------------------
case 0x3d3d:
break;
//--------------- EDIT_OBJECT ---------------
// Description: Object block, info for each object
// Chunk ID: 4000 (hex)
// Chunk Lenght: len(object name) + sub chunks
//-------------------------------------------
case 0x4000:
i=0;
do
{
fread (&l_char, 1, 1, l_file);
p_object->name[i]=l_char;
i++;
}while(l_char != '\0' && i<20);
break;
//--------------- OBJ_TRIMESH ---------------
// Description: Triangular mesh, contains chunks for 3d mesh info
// Chunk ID: 4100 (hex)
// Chunk Lenght: 0 + sub chunks
//-------------------------------------------
case 0x4100:
break;
//--------------- TRI_VERTEXL ---------------
// Description: Vertices list
// Chunk ID: 4110 (hex)
// Chunk Lenght: 1 x unsigned short (number of vertices)
// + 3 x float (vertex coordinates) x (number of vertices)
// + sub chunks
//-------------------------------------------
case 0x4110:
fread (&l_qty, sizeof (unsigned short), 1, l_file);
p_object->vertices_qty = l_qty;
//printf("Number of vertices: %d\n",l_qty);
for (i=0; i<l_qty; i++)
{
fread (&p_object->vertex[i].x, sizeof(float), 1, l_file);
//printf("Vertices list x: %f\n",p_object->vertex[i].x);
fread (&p_object->vertex[i].y, sizeof(float), 1, l_file);
//printf("Vertices list y: %f\n",p_object->vertex[i].y);
fread (&p_object->vertex[i].z, sizeof(float), 1, l_file);
//printf("Vertices list z: %f\n",p_object->vertex[i].z);
//Insert into the database
}
break;
//--------------- TRI_FACEL1 ----------------
// Description: Polygons (faces) list
// Chunk ID: 4120 (hex)
// Chunk Lenght: 1 x unsigned short (number of polygons)
// + 3 x unsigned short (polygon points) x (number of polygons)
// + sub chunks
//-------------------------------------------
case 0x4120:
fread (&l_qty, sizeof (unsigned short), 1, l_file);
p_object->polygons_qty = l_qty;
//printf("Number of polygons: %d\n",l_qty);
for (i=0; i<l_qty; i++)
{
fread (&p_object->polygon[i].a, sizeof (unsigned short), 1, l_file);
//printf("Polygon point a: %d\n",p_object->polygon[i].a);
fread (&p_object->polygon[i].b, sizeof (unsigned short), 1, l_file);
//printf("Polygon point b: %d\n",p_object->polygon[i].b);
fread (&p_object->polygon[i].c, sizeof (unsigned short), 1, l_file);
//printf("Polygon point c: %d\n",p_object->polygon[i].c);
fread (&l_face_flags, sizeof (unsigned short), 1, l_file);
//printf("Face flags: %x\n",l_face_flags);
}
break;
//------------- TRI_MAPPINGCOORS ------------
// Description: Vertices list
// Chunk ID: 4140 (hex)
// Chunk Lenght: 1 x unsigned short (number of mapping points)
// + 2 x float (mapping coordinates) x (number of mapping points)
// + sub chunks
//-------------------------------------------
//----------- Skip unknow chunks ------------
//We need to skip all the chunks that currently we don't use
//We use the chunk lenght information to set the file pointer
//to the same level next chunk
//-------------------------------------------
default:
fseek(l_file, l_chunk_lenght-6, SEEK_CUR);
}
}
fclose (l_file); // Closes the file stream
return (1); // Returns ok
}
void render (obj_type_ptr object)
{
int l_index;
//glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
//glMatrixMode(GL_MODELVIEW); // Modeling transformation
glLoadIdentity();
//glTranslatef(0.0,0.0,-500.0);
glColor3d(1,1,0);
// Rotations of the object (the model matrix is multiplied by the rotation matrices)
glRotatef(rotation_x,1.0,0.0,0.0);
glRotatef(rotation_y,0.0,1.0,0.0);
glRotatef(rotation_z,0.0,0.0,1.0);
// TODO: Add your message handler code here
//rotation_x = rotation_x + rotation_x_increment; /////
//rotation_y = rotation_y + rotation_y_increment;
//rotation_z = rotation_z + rotation_z_increment;
if (rotation_x > 359) rotation_x = 0;
if (rotation_y > 359) rotation_y = 0;
if (rotation_z > 359) rotation_z = 0;
// glBegin and glEnd delimit the vertices that define a primitive (in our case triangles)
glBegin(GL_TRIANGLES);
for (l_index=0;l_index < object->polygons_qty;l_index++)
{
//----------------- FIRST VERTEX -----------------
// Coordinates of the first vertex
glVertex3f( object->vertex[ object->polygon[l_index].a ].x,
object->vertex[ object->polygon[l_index].a ].y,
object->vertex[ object->polygon[l_index].a ].z);
//Vertex definition
//----------------- SECOND VERTEX -----------------
// Coordinates of the second vertex
//float x= object.vertex[ object.polygon[l_index].b ].x;
glVertex3f( object->vertex[ object->polygon[l_index].b ].x,
object->vertex[ object->polygon[l_index].b ].y,
object->vertex[ object->polygon[l_index].b ].z);
//----------------- THIRD VERTEX -----------------
// Coordinates of the Third vertex
glVertex3f( object->vertex[ object->polygon[l_index].c ].x,
object->vertex[ object->polygon[l_index].c ].y,
object->vertex[ object->polygon[l_index].c ].z);
}
glEnd();
glutSwapBuffers();
}
what i tried so far:
- debuging & checking if the vertices have a valid values:
for the 3ds file that was attached to the code - seems that yes for other 3ds files i found - no.
trying to scale the object up and down - no result
replacing all the code inside render() with glutSolidSphere(0.5,50,50) - the sphere is visible
as you see in render() i disabled glClear() and glMatrixMode() thats because i think they not needed, if enabled they make all other object disapear without seeing the 3ds object.
my questions are:
is load() looks correct?
are there other vertions of 3ds file which not "feet" for this load()?
is there any setting to openGL which i can try to change in order to see the object?
do you know other 3d model format which is simpler to load and yet well distribution and easy to find, as 3ds is?
do you know other 3d model format which is simpler to load and yet well distribution and easy to find, as 3ds is?
To load objects from 3d studio max, you can try using the obj wavefront format, (there is an option in 3ds max to import in obj format) It is human readable format with triplets of vertex, vertex normals, and vertex textures, which can be easily parsed and passed to glut for rendering.
I wrote some code for loading 3d models, source available here
It parses the obj files and stores the vertices, texture coordinates and normals in arrays which are passed to glut function for rendering
More about the obj format here