2 Pluspunkte 0 Minuspunkte

Wie kann ich mit OpenGL eine .obj Datei laden?

#include<GL/freeglut.h>
#include<GL/gl.h>
#include<stdio.h>

void drawTriangle()
{
    glBegin(GL_TRIANGLES);
        glVertex3f(0.0, 1.0, -5.0);
        glVertex3f(-1.0, -1.0, -5.0);
        glVertex3f(1.0, -1.0, -5.0);
    glEnd();
}

void drawCircle()
{
    int numSegments = 100;
    GLfloat radius = 0.5;
    
    glBegin(GL_TRIANGLE_FAN);
        for (int i = 0; i <= numSegments; i++) {
            float theta = 2.0f * M_PI * (i / (float)numSegments);
            float x = radius * cosf(theta);
            float y = radius * sinf(theta);
            glVertex3f(x, y, -5.0);
        }
    glEnd();
}

void drawSquare()
{
    glBegin(GL_QUADS);
        glVertex3f(-0.5, 0.5, -5.0);
        glVertex3f(0.5, 0.5, -5.0);
        glVertex3f(0.5, -0.5, -5.0);
        glVertex3f(-0.5, -0.5, -5.0);
    glEnd();
}

void reshape(int w,int h)
{    
    glViewport(0,0,w,h);
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    
    gluPerspective (60, (GLfloat)w / (GLfloat)h, 1.0, 100.0);
    //glOrtho(-25,25,-2,2,0.1,100);   
    
    glMatrixMode(GL_MODELVIEW);
}

void display(void)
{  
       glClearColor (0.0,0.0,0.0,1.0);
       glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
       glLoadIdentity();
    
    //drawCircle();
    //drawTriangle();
    //drawSquare();
    
    // .obj Datei laden und Objekt anzeigen
    
    glutSwapBuffers();

}

int main(int argc,char **argv)
{
    glutInit(&argc,argv);
    glutInitDisplayMode(GLUT_DOUBLE|GLUT_RGB|GLUT_DEPTH);
    glutInitWindowSize(800,450);
    glutInitWindowPosition(20,20);
    glutCreateWindow("ObjLoader");
    glutReshapeFunc(reshape);
    glutDisplayFunc(display);
    glutIdleFunc(display);
    glutMainLoop();
    return 0;
}
von  

1 Antwort

0 Pluspunkte 0 Minuspunkte

Ich würde dir empfehlen eine Bibliothek wie z.B Assimp zu benutzen. Du kannst die Datei auch auf die Harte Tour einlesen und das 3D Modell selbst parsen aber das  ist alles andere als einfach. Nehmen wir diese Datei.

# Blender3D v249 OBJ File: untitled.blend
# www.blender3d.org
mtllib test.mtl
v 1.000000 -1.000000 -1.000000
v 1.000000 -1.000000 1.000000
v -1.000000 -1.000000 1.000000
v -1.000000 -1.000000 -1.000000
v 1.000000 1.000000 -1.000000
v 0.999999 1.000000 1.000001
v -1.000000 1.000000 1.000000
v -1.000000 1.000000 -1.000000
vt 0.748573 0.750412
vt 0.749279 0.501284
vt 0.999110 0.501077
vt 0.999455 0.750380
vt 0.250471 0.500702
vt 0.249682 0.749677
vt 0.001085 0.750380
vt 0.001517 0.499994
vt 0.499422 0.500239
vt 0.500149 0.750166
vt 0.748355 0.998230
vt 0.500193 0.998728
vt 0.498993 0.250415
vt 0.748953 0.250920
vn 0.000000 0.000000 -1.000000
vn -1.000000 -0.000000 -0.000000
vn -0.000000 -0.000000 1.000000
vn -0.000001 0.000000 1.000000
vn 1.000000 -0.000000 0.000000
vn 1.000000 0.000000 0.000001
vn 0.000000 1.000000 -0.000000
vn -0.000000 -1.000000 0.000000
usemtl mat.png
s off
f 5/1/1 1/2/1 4/3/1
f 5/1/1 4/3/1 8/4/1
f 3/5/2 7/6/2 8/7/2
f 3/5/2 8/7/2 4/8/2
f 2/9/3 6/10/3 3/5/3
f 6/10/4 7/6/4 3/5/4
f 1/2/5 5/1/5 2/9/5
f 5/1/6 6/10/6 2/9/6
f 5/1/7 8/11/7 6/10/7
f 8/11/7 7/12/7 6/10/7
f 1/2/8 2/9/8 3/13/8
f 1/2/8 3/13/8 4/14/8

Das erste Wort am Anfang jeder Zeile besagt was für Informationen in der Zeile dargestellt sind. Am wichtigsten sind:

  • v - Diese Zeilen definieren die Eckpunkte (Vertices) des 3D-Modells. Jede Zeile enthält die x, y und z Koordinaten eines Eckpunktes im Raum.
  • vt - Hier werden die Texturkoordinaten (Texture Vertices) für die Eckpunkte definiert. Texturkoordinaten bestimmen, wie eine Textur auf die Oberfläche des Modells aufgetragen wird. Jede Zeile enthält die u und v Koordinaten der Textur.
  • vn - Dies sind die Normalenvektoren (Normals), die für die Beleuchtung und Schattierung des Modells verwendet werden. Jede Zeile enthält die x, y und z Komponenten des Normalenvektors.

Hier ist ein Beispiel um alle Vertices der Reihe nach zu zeichnen.

#include<GL/freeglut.h>
#include<GL/gl.h>
#include<stdio.h>
#include <math.h>

GLuint obj;
float color;
char ch;
int read;

void loadObj(char *fname)
{
    int read;
    FILE *fp;
    GLfloat x, y, z;
    obj = glGenLists(1);
    fp = fopen(fname,"r");
    if(!fp) exit(1);
    glPointSize(2.0);
    glNewList(obj, GL_COMPILE);
    glPushMatrix();
    glBegin(GL_POINTS);
    while(!(feof(fp))) {
        read=fscanf(fp,"%c %f %f %f",&ch,&x,&y,&z);
        if(read==4 && ch=='v') glVertex3f(x,y,z);
    }
    glEnd();
    glPopMatrix();
    glEndList();
    fclose(fp);
}

void drawObj()
{
     glPushMatrix();
     glTranslatef(0,0,-20.0);
     glColor3f(1.0,0.23,0.27);
     glScalef(1,1,1);
     glRotatef(color,0,1,1);
     glCallList(obj);
     glPopMatrix();
     color+=0.6;
     if(color>360)color-=360;
}

void drawTriangle()
{
    glBegin(GL_TRIANGLES);
        glVertex3f(0.0, 1.0, -5.0);
        glVertex3f(-1.0, -1.0, -5.0);
        glVertex3f(1.0, -1.0, -5.0);
    glEnd();
}

void drawCircle()
{
    int numSegments = 100;
    GLfloat radius = 0.5;
    
    glBegin(GL_TRIANGLE_FAN);
        for (int i = 0; i <= numSegments; i++) {
            float theta = 2.0f * M_PI * (i / (float)numSegments);
            float x = radius * cosf(theta);
            float y = radius * sinf(theta);
            glVertex3f(x, y, -5.0);
        }
    glEnd();
}

void drawSquare()
{
    glBegin(GL_QUADS);
        glVertex3f(-0.5, 0.5, -5.0);
        glVertex3f(0.5, 0.5, -5.0);
        glVertex3f(0.5, -0.5, -5.0);
        glVertex3f(-0.5, -0.5, -5.0);
    glEnd();
}

void reshape(int w,int h)
{    
    glViewport(0,0,w,h);
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    
    gluPerspective (60, (GLfloat)w / (GLfloat)h, 1.0, 100.0);
    //glOrtho(-25,25,-2,2,0.1,100);   
    
    glMatrixMode(GL_MODELVIEW);
}

void display(void)
{  
       glClearColor (0.0,0.0,0.0,1.0);
       glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
       glLoadIdentity();
    
    //drawCircle();
    //drawTriangle();
    //drawSquare();
    
    glutSwapBuffers();

}

int main(int argc,char **argv)
{
    glutInit(&argc,argv);
    glutInitDisplayMode(GLUT_DOUBLE|GLUT_RGB|GLUT_DEPTH);
    glutInitWindowSize(800,450);
    glutInitWindowPosition(20,20);
    glutCreateWindow("ObjLoader");
    glutReshapeFunc(reshape);
    glutDisplayFunc(display);
    glutIdleFunc(display);
    glutMainLoop();
    return 0;
}
von (716 Punkte)