2013-05-12 5 views
1

블렌더에서 내 보낸 obj 모델을로드하는 데 객체 로더를 사용하고 있습니다. 모델을로드 할 수는 있지만 텍스처가로드되지 않고 이유를 모르겠습니다. 기본 클래스에서 모델을 렌더링 할 때로드해야합니까? 아니면 모델을 렌더링 할뿐만 아니라 텍스처를로드해야합니까?텍스처가있는 OpenGL obj 객체 로더

objloader.cpp

/************************************************************ 
*Loads obj file - limited to vertices, faces, normals, texture maps 
*loads to object structure as defined in .h file 
************************************************************/ 

#include <stdio.h> 
#include <iostream> 
#include <io.h> 
#include <stdlib.h> 
#include "glut.h" 

#include "objloader.h" 

using namespace std; 

void object_type::render() 
{ 
    glBegin(GL_TRIANGLES); // glBegin and glEnd delimit the vertices that define a primitive (in our case triangles) 

    for (int j=0;j<polygons_qty;j++) 
    { 
     //----------------- FIRST VERTEX ----------------- 
     //Normal coordinates of the first vertex 
     glNormal3f(normcoord[ polygon[j].n[0] - 1 ].i, 
       normcoord[ polygon[j].n[0] - 1 ].j, 
       normcoord[ polygon[j].n[0] - 1 ].k); 
     // Texture coordinates of the first vertex 
      glTexCoord2f(mapcoord[ polygon[j].t[0] - 1 ].u, 
        mapcoord[ polygon[j].t[0] - 1 ].v); 
     // Coordinates of the first vertex 
     glVertex3f(vertex[ polygon[j].v[0] - 1].x, 
       vertex[ polygon[j].v[0] - 1].y, 
       vertex[ polygon[j].v[0] - 1].z); 

     //----------------- SECOND VERTEX ----------------- 
     //Normal coordinates of the first vertex 
     glNormal3f(normcoord[ polygon[j].n[1] - 1 ].i, 
       normcoord[ polygon[j].n[1] - 1 ].j, 
       normcoord[ polygon[j].n[1] - 1 ].k); 
     // Texture coordinates of the first vertex 
     glTexCoord2f(mapcoord[ polygon[j].t[1] - 1 ].u, 
        mapcoord[ polygon[j].t[1] - 1 ].v); 
     // Coordinates of the first vertex 
     glVertex3f(vertex[ polygon[j].v[1] - 1].x, 
       vertex[ polygon[j].v[1] - 1].y, 
       vertex[ polygon[j].v[1] - 1].z); 

     //----------------- THIRD VERTEX ----------------- 
     //Normal coordinates of the first vertex 
     glNormal3f(normcoord[ polygon[j].n[2] - 1 ].i, 
       normcoord[ polygon[j].n[2] - 1 ].j, 
       normcoord[ polygon[j].n[2] - 1 ].k); 
     // Texture coordinates of the first vertex 
     glTexCoord2f(mapcoord[ polygon[j].t[2] - 1 ].u, 
        mapcoord[ polygon[j].t[2] - 1 ].v); 
     // Coordinates of the first vertex 
     glVertex3f(vertex[ polygon[j].v[2] - 1].x, 
       vertex[ polygon[j].v[2] - 1].y, 
       vertex[ polygon[j].v[2] - 1].z); 
    } 
    glEnd(); 
} 


/* 
vertex_type vertex[MAX_VERTICES]; 
mapcoord_type mapcoord[MAX_VERTICES]; 
normcoord_type normcoord[MAX_NORMALS]; 
polygon_type polygon[MAX_POLYGONS]; 
int id_texture 
*/ 


int object_type::objdatadisplay() 
{ 
    int i; 
    printf("VERTICES: %d\n",vertices_qty); 
for (i =0;i<vertices_qty;i++) 
{ 
    printf("%f %f %f\n",vertex[i].x,vertex[i].y,vertex[i].z); 
} 

    printf("NORMALS: %d\n",normcoord_qty); 
for (i =0;i<normcoord_qty;i++) 
{ 
    printf("%f %f %f\n",normcoord[i].i,normcoord[i].j,normcoord[i].k); 
} 
    printf("MAP COORDS: %d\n",mapcoord_qty); 
for (i =0;i<mapcoord_qty;i++) 
{ 
    printf("%f %f\n",mapcoord[i].u,mapcoord[i].v); 
} 
    printf("POLYGONS: %d\n",polygons_qty); 
for (i=0;i<polygons_qty;i++) //for each vertex of polygon (triangle) 
{ 
    for (int j = 0;j<3;j++) 
    { 
      printf("%d::%d/%d/%d\n",i,polygon[i].v[j],polygon[i].t[j],polygon[i].n[j]); 
    } 
} 
return 1; 
} 


int object_type::objloader(char *p_filename) 
{ 
    int ivertex=0; //Index variable 
    int inormal =0; 
    int ipolygon=0; 
    int imap=0; 
    char string[256]; 
FILE *l_file; //File pointer 

char l_char; //Char variable 

unsigned short l_face_flags; //Flag that stores some face information 

if ((l_file=fopen (p_filename, "rt"))== NULL) return 0; //Open the file 


while (!feof(l_file)) //Loop to scan the whole file 
{ 
    fscanf(l_file,"%c",&l_char); 
    if(l_char=='\n')//read char if'/n' -skip to next and read 
     fscanf(l_file,"%c",&l_char); 
    switch (l_char) //parse 
    { 
    default: fgets(string,256,l_file); 
     break; 
    case 'v': //a vertex or a normal or a text co-ord 
     fscanf(l_file,"%c",&l_char); 
     switch (l_char) 
     { 
     case ' ': //a vertex -expect and so read 3 floats next 
       fscanf(l_file,"%f %f %f",&vertex[ivertex].x, &vertex[ivertex].y,&vertex[ivertex].z); 


       ivertex++; 
       break; 
     case 'n': //a normal -expect and so read 3 floats next 
       fscanf(l_file,"%f %f %f",&normcoord[inormal].i, &normcoord[inormal].j,&normcoord[inormal].k); 
       inormal++; 
       break; 
     case 't': //a texture map coord-expect and so read 2 floats next 
       fscanf(l_file,"%f %f",&mapcoord[imap].u, &mapcoord[imap].v); 
       imap++; 
       break; 
     } //end switch 
     break; 
    case 'f': //a face read next assume format is -> f 1/1/1 2/2/2 3/3/3 
     for (int i=0;i<3;i++) //for each vertex of polygon (triangle) 
     { 
      fscanf(l_file,"%c",&l_char); //read space char - ignore this 
      fscanf(l_file,"%d",&polygon[ipolygon].v[i]); //read vertex. 
      fscanf(l_file,"%c",&l_char); //read space char - ignore this 
      fscanf(l_file,"%d",&polygon[ipolygon].t[i]); //read text coord. 
      fscanf(l_file,"%c",&l_char); //read space char - ignore this 
      fscanf(l_file,"%d",&polygon[ipolygon].n[i]); //read normal. 
     } 
     ipolygon++; 
     break; 

    } //end switch 
} 

fclose (l_file); // Closes the file stream 
vertices_qty = ivertex; 
polygons_qty = ipolygon; 
mapcoord_qty = imap; 
normcoord_qty = inormal; 

return 1; //if successful  
} 

objloader.h

#ifndef OBJLOAD 
#define OBJLOAD 

/************************************************ 
*Loads obj file - limited to vertices, faces, normals, texture maps 
*loads to object structure as defined in .h file 
****************************************************/ 


#define MAX_VERTICES 8000 // Max number of vertices (for each object) 
#define MAX_POLYGONS 8000 // Max number of polygons (for each object) 
#define MAX_NORMALS 8000 // Max number of polygons (for each object) 

// Our vertex type 
typedef struct{ 
float x,y,z; 
}vertex_type; 

// Our normal type 
typedef struct{ 
float i,j,k; 
}normcoord_type; 

// The polygon (triangle), 3 numbers that aim 3 vertices 
typedef struct{ 
int v[3],t[3],n[3]; 
}polygon_type; 

// The mapcoord type, 2 texture coordinates for each vertex 
typedef struct{ 
float u,v; 
}mapcoord_type; 

// The object type 
class object_type{ 
public: 
int id_texture; 
object_type(){} 
~object_type(){} 
int objloader(char *p_filename); 
int objdatadisplay(); 
void render(); 

private: 
char name[20]; 
int vertices_qty; 
int polygons_qty; 
int mapcoord_qty; 
int normcoord_qty; 

vertex_type vertex[MAX_VERTICES]; 
mapcoord_type mapcoord[MAX_VERTICES]; 
normcoord_type normcoord[MAX_NORMALS]; 
polygon_type polygon[MAX_POLYGONS]; 

}; 
#endif 

MAIN.CPP

#include "objloader.h" 
#include <stdio.h> 
#include <stdlib.h> 
#include <math.h> 
#include <GL/glew.h> 

#ifdef __WIN32__ 
#include <windows.h> 
#endif 

#include "glut.h" //glut has all ogl relevant .h files included 

int screen_width=800; 
int screen_height=600; 

//angle of rotation 
float xpos = 0, ypos = 0, zpos = 0, xrot = 0, yrot = 0, angle=0.0; 

float cRadius = 10.0f; // our radius distance from our character 

float lastx, lasty; 

object_type *objarray[2]; //objects container for our world. Used throughout so global 

//Lights settings 
GLfloat light_ambient[]= { 0.1f, 0.1f, 0.1f, 0.1f }; 
GLfloat light_diffuse[]= { 1.0f, 1.0f, 1.0f, 0.0f }; 
GLfloat light_specular[]= { 1.0f, 1.0f, 1.0f, 0.0f }; 
GLfloat light_position[]= { 100.0f, 0.0f, -10.0f, 1.0f }; 

//Materials settings 
GLfloat mat_ambient[]= { 0.5f, 0.5f, 0.0f, 0.0f }; 
GLfloat mat_diffuse[]= { 0.5f, 0.5f, 0.0f, 0.0f }; 
GLfloat mat_specular[]= { 1.0f, 1.0f, 1.0f, 0.0f }; 
GLfloat mat_shininess[]= { 1.0f }; 


/************************************ 
* 
* SUBROUTINE init(void) 
* 
* Used to initialize OpenGL and to setup our world 
* 
************************************/ 

void init(void) 
{ 
    glClearColor(0.0, 0.0, 0.0, 0.0); // Clear background color to black 

    // Viewport transformation 
    glViewport(0,0,screen_width,screen_height); 

    // Projection transformation 
    glMatrixMode(GL_PROJECTION); // Specifies which matrix stack is the target for matrix operations 
    glLoadIdentity(); // We initialize the projection matrix as identity 
    gluPerspective(45.0f,(GLfloat)screen_width/(GLfloat)screen_height,5.0f,10000.0f);  


//Lights initialization and activation 
    glLightfv (GL_LIGHT1, GL_AMBIENT, light_ambient); 
    glLightfv (GL_LIGHT1, GL_DIFFUSE, light_diffuse); 
    glLightfv (GL_LIGHT1, GL_DIFFUSE, light_specular); 
    glLightfv (GL_LIGHT1, GL_POSITION, light_position);  
    glEnable (GL_LIGHT1); 
    glEnable (GL_LIGHTING); 

    //Materials initialization and activation 
glMaterialfv (GL_FRONT, GL_AMBIENT, mat_ambient); 
    glMaterialfv (GL_FRONT, GL_DIFFUSE, mat_diffuse); 
    glMaterialfv (GL_FRONT, GL_DIFFUSE, mat_specular); 
    glMaterialfv (GL_FRONT, GL_POSITION, mat_shininess);  

//Other initializations 
    glShadeModel(GL_SMOOTH); // Type of shading for the polygons 
glHint (GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST); // Texture mapping perspective correction 
    glEnable(GL_TEXTURE_2D); // Texture mapping ON 
    glPolygonMode (GL_FRONT_AND_BACK, GL_FILL); // Polygon rasterization mode (polygon filled) 
glEnable(GL_CULL_FACE); // Enable the back face culling 
    glEnable(GL_DEPTH_TEST); // Enable the depth test 

glTranslatef(0.0f, 0.0f, -cRadius); 
    glRotatef(xrot,1.0,0.0,0.0); 

angle++; //increase the angle 

for (int i=0;i<2;i++) 
{ 
printf("*************\n"); 
    objarray[i] = new (object_type); 
    objarray[i]->objloader("C:/3dModels/Museum.obj"); 
    objarray[i]->objdatadisplay();  
} 

} 


/********************************************************** 
* 
* SUBROUTINE resize(int p_width, int p_height) 
* 
* This routine must be called everytime we resize our window. 
* 
* Input parameters: p_width = width in pixels of our viewport 
*     p_height = height in pixels of our viewport 
* 
*********************************************************/ 

void resize (int p_width, int p_height) 
{ 
if (screen_width==0 && screen_height==0) exit(0); 
    screen_width=p_width; // We obtain the new screen width values and store it 
    screen_height=p_height; // Height value 

    glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // We clear both the color and the depth buffer so to draw the next frame 
    glViewport(0,0,screen_width,screen_height); // Viewport transformation 

    glMatrixMode(GL_PROJECTION); // Projection transformation 
    glLoadIdentity(); // We initialize the projection matrix as identity 
    gluPerspective(45.0f,(GLfloat)screen_width/(GLfloat)screen_height,5.0f,10000.0f); 

    glutPostRedisplay(); // This command redraw the scene (it calls the same routine of glutDisplayFunc) 
} 

/********************************************************** 
* 
* SUBROUTINE keyboard(void) 
* 
* Subroutine to handle keyboard input 
* 
*********************************************************/ 


void keyboard (unsigned char key, int x, int y) { 
    if (key=='q') 
    { 
    xrot += 1; 
    if (xrot >360) xrot -= 360; 
    } 

    if (key=='z') 
    { 
    xrot -= 1; 

if (xrot < -360) xrot += 360; 
    } 

    if (key=='w') 
    { 
    float xrotrad, yrotrad; 
    yrotrad = (yrot/180 * 3.141592654f); 
    xrotrad = (xrot/180 * 3.141592654f); 
    xpos += float(sin(yrotrad)); 
    zpos -= float(cos(yrotrad)); 
    ypos -= float(sin(xrotrad)); 
    } 

    if (key=='s') 
    { 
    float xrotrad, yrotrad; 
    yrotrad = (yrot/180 * 3.141592654f); 
    xrotrad = (xrot/180 * 3.141592654f); 
    xpos -= float(sin(yrotrad)); 
    zpos += float(cos(yrotrad)); 
    ypos += float(sin(xrotrad)); 
    } 

    if (key=='d') 
    { 
    float yrotrad; 
    yrotrad = (yrot/180 * 3.141592654f); 
    xpos += float(cos(yrotrad)) * 0.2; 
    zpos += float(sin(yrotrad)) * 0.2; 
    } 

    if (key=='a') 
    { 
    float yrotrad; 
    yrotrad = (yrot/180 * 3.141592654f); 
    xpos -= float(cos(yrotrad)) * 0.2; 
    zpos -= float(sin(yrotrad)) * 0.2; 
    } 

    if (key==27) 
    { 
    exit(0); 
    } 
} 

/********************************************************** 
* 
* SUBROUTINE mouseMovement(void) 
* 
* Subroutine to handle mouse input 
* 
*********************************************************/ 

void mouseMovement(int x, int y) { 
int diffx=x-lastx; //check the difference between the current x and the last x position 
int diffy=y-lasty; //check the difference between the current y and the last y position 
lastx=x; //set lastx to the current x position 
lasty=y; //set lasty to the current y position 
xrot += (float) diffy; //set the xrot to xrot with the addition of the difference in the y position 
yrot += (float) diffx; //set the xrot to yrot with the addition of the difference in the x position 
} 


/********************************************************** 
* 
* SUBROUTINE display(void) 
* 
* This is our main rendering subroutine, called each frame 
* 
*********************************************************/ 

void display(void) 
{ 

    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // This clear the background color to dark blue 
    glMatrixMode(GL_MODELVIEW); // Modeling transformation 
    glPushMatrix(); 
glLoadIdentity(); // Initialize the model matrix as identity 

    glTranslatef(0.0f, 0.0f, -cRadius); // We move the object forward (the model matrix is multiplied by the translation matrix) 
    glRotatef(xrot,1.0,0.0,0.0); // Rotations of the object (the model matrix is multiplied by the rotation matrices) 

    glRotatef(yrot,0.0,1.0,0.0); 

glTranslated(-xpos,0.0f,-zpos); //translate the screen to the position of our camera 


if (objarray[0]->id_texture!=-1) 
{ 
    glBindTexture(GL_TEXTURE_2D, objarray[0]->id_texture); // We set the active texture 
    glEnable(GL_TEXTURE_2D); // Texture mapping ON 
    printf("Txt map ON"); 
} 
else 
    glDisable(GL_TEXTURE_2D); // Texture mapping OFF 


objarray[0]->render(); 
glPopMatrix(); 
glPushMatrix(); 
glTranslatef(5.0,0.0,-20.0); 
glFlush(); // This force the execution of OpenGL commands 
glutSwapBuffers(); // In double buffered mode we invert the positions of the visible buffer and the writing buffer 
} 



/********************************************************** 
* 
* The main routine 
* 
*********************************************************/ 


int main(int argc, char **argv) 
{ 
    // We use the GLUT utility to initialize the window, to handle the input and to interact with the windows system 
    glutInit(&argc, argv);  
    glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH); 
    glutInitWindowSize(screen_width,screen_height); 
    glutInitWindowPosition(0,0); 
    glutCreateWindow("Demo 1: To exit press ESC");  
    glutDisplayFunc(display); 
    glutIdleFunc(display); 
    glutReshapeFunc (resize); 

glutPassiveMotionFunc(mouseMovement); //check for mouse movement 
glutKeyboardFunc (keyboard); 

init(); 
    glutMainLoop(); 

    return(0);  
} 

예 OBJ 블렌더에서 cube.obj :

# Blender v2.66 (sub 1) OBJ File: 'cube.blend' 
# www.blender.org 
mtllib cube.mtl 
g Cube 
v 1.000000 0.665869 -1.000000 
v 1.000000 0.665869 1.000000 
v -1.000000 0.665869 1.000000 
v -1.000000 0.665869 -1.000000 
v 1.000000 2.665869 -0.999999 
v 0.999999 2.665869 1.000001 
v -1.000000 2.665869 1.000000 
v -1.000000 2.665869 -1.000000 
vt 0.000000 0.334353 
vt 0.332314 0.333333 
vt 0.333333 0.665647 
vt 1.000000 0.001019 
vt 0.998981 0.333333 
vt 0.666667 0.332314 
vt 1.000000 0.665647 
vt 0.667686 0.666667 
vt 0.334353 0.666667 
vt 0.333333 0.334353 
vt 0.666667 0.665647 
vt 0.333333 0.332314 
vt 0.001020 0.333333 
vt 0.332314 0.000000 
vt 0.333333 0.001019 
vt 0.665647 0.000000 
vt 0.001019 0.666667 
vt 0.667686 0.000000 
vt 0.666667 0.334353 
vt 0.665647 0.333333 
vt 0.000000 0.001020 
vt 0.334353 0.333333 
vn 0.000000 -1.000000 0.000000 
vn -0.000000 1.000000 0.000000 
vn 1.000000 -0.000000 0.000001 
vn -0.000000 -0.000000 1.000000 
vn -1.000000 -0.000000 -0.000000 
vn 0.000000 0.000000 -1.000000 
vn 1.000000 0.000000 -0.000000 
usemtl Material 
s off 
f 1/1/1 2/2/1 3/3/1 
f 5/4/2 8/5/2 7/6/2 
f 1/5/3 5/7/3 6/8/3 
f 2/9/4 6/10/4 3/11/4 
f 3/12/5 7/13/5 4/14/5 
f 5/15/6 1/16/6 4/6/6 
f 4/17/1 1/1/1 3/3/1 
f 6/18/2 5/4/2 7/6/2 
f 2/19/7 1/5/7 6/8/7 
f 6/10/4 7/20/4 3/11/4 
f 7/13/5 8/21/5 4/14/5 
f 8/22/6 5/15/6 4/6/6 
+0

MTL 파서는 어디에 있습니까? 왜'glTexImage2D()'호출을 가지지 않는가? – genpfault

+0

안녕하세요, 답장을 보내 주셔서 감사합니다. 전에는 객체 파서를 사용하지 않았기 때문에이 모든 것이 새로운 것입니다. 나는 OpenGL 프로그래밍을 일주일 만에하고있다. 개체 로더가 mtl 파일도 처리한다고 생각했습니다. –

답변

3

귀하의 OBJ 로더는 심지어 MTL 파일을 구문 분석하려고하지 않습니다.

직접 MTL 처리를 추가해야합니다.

아마도 map_Kd을 지원하고 싶을 것입니다.

Good luck.

+1

오, 알았어. 조언 감사합니다. 내가 여기 걸을 수 있기 전에 내가 도망 가고있는 것처럼 보입니다. –

관련 문제