0

現時点では、割り当てに glut などを使用しており、3ds max の obj ファイルからすべての頂点をインポートしています。三角形のように:

画像

#include <windows.h>
#include <GL/gl.h>
#include <GL/glu.h>
#include "glut.h"
#include <istream>
#include <iostream>
#include <fstream>
#include <string>
#include <sstream>
#include <vector>


using namespace std;

// structs for arrays
struct point3D
{
float x;
float y;
float z;
};
//camera structs
struct camera 
{
point3D pos;
point3D lookAt;
point3D up;

};

//global variables
camera cam = {0, 0, 5, 0, 0, 0, 0, 1, 0};

int mousex = 0;
int mousey = 0;
bool mouseDown=false;


point3D v[8] = {};
point3D vn[6] = {};
point3D vt[4] = {};
point3D f[12][3] = {};

void init()
{
glClearColor(0.5, 0.7, 0.0, 1.0);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glFrustum(-1.0, 1.0, -1.0, 1.0, 1.0, 1000);
glEnable(GL_CULL_FACE);
glCullFace(GL_BACK);


}

void display() 
{
    glClear(GL_COLOR_BUFFER_BIT );
glMatrixMode(GL_MODELVIEW); 
glLoadIdentity(); // reset the matrix

gluLookAt(cam.pos.x, cam.pos.y, cam.pos.z,
  cam.lookAt.x, cam.lookAt.y, cam.lookAt.z, 
  cam.up.x, cam.up.y, cam.up.z); // sets camera position.

glColor3f(1.0, 0.0, 0.0);
    glTranslatef(0.0f, 0.0f, -15.0f);


for(int i = 0; i < 8; i++)//reads coords for verts from global arrays.
{
    glBegin(GL_TRIANGLES);
        int one = f[i][0].x;
        int two = f[i][1].x;
        int three = f[i][2].x;

        glVertex3fv(&(v[one].x));
        glVertex3fv(&(v[two].x));
        glVertex3fv(&(v[three].x));
    glEnd();
}


glFlush();
}

void drawAxes() {
glBegin(GL_LINES);
    glVertex3f(0, 0, 0);
    glVertex3f(10, 0, 0);
    glVertex3f(0, 0, 0);
    glVertex3f(0, 10, 0);
    glVertex3f(0, 0, 0);
    glVertex3f(0, 0, 10);
glEnd();// draws a axis to show scene
}

void passiveMouseFunc(int x, int y )
{
if (mouseDown == true)
{
if (x > mousex)
cam.lookAt.x+= 0.5;
if (x < mousex)
cam.lookAt.x-= 0.5;
if (y > mousey)
cam.lookAt.y-= 0.5;
if (y < mousey)
cam.lookAt.y+= 0.5;


mousex = x;
mousey = y;
glutPostRedisplay();
}
else
{
if (x > mousex)
cam.lookAt.x+= 0.0;
if (x < mousex)
cam.lookAt.x-= 0.0;
if (y > mousey)
cam.lookAt.y-= 0.0;
if (y < mousey)
cam.lookAt.y+= 0.0;


mousex = x;
mousey = y;
glutPostRedisplay(); //redraws scene

}
}
void glutMouseFunc(int button, int state, int x, int y)
{
switch (button)
{
case GLUT_LEFT_BUTTON: //makes it so i have to click to move cam
     mouseDown = true;
     break;
case GLUT_RIGHT_BUTTON:
    mouseDown = false;
    break;
}
}


void specialKeyboard(int key, int x, int y) // methods used for moving cam
{
   switch (key)
   {
     case GLUT_KEY_RIGHT:
    cam.pos.x+=0.2;
    break;
    case GLUT_KEY_LEFT:
     cam.pos.x-=0.2;
    break;
   case GLUT_KEY_UP:
   cam.pos.y+=0.2;
  break;
  case GLUT_KEY_DOWN:
   cam.pos.y-=0.2;
   break;
  case GLUT_KEY_PAGE_UP:
   cam.pos.z+=0.2;
    break;
  case GLUT_KEY_PAGE_DOWN:
   cam.pos.z-=0.2;
    break;
}

   glutPostRedisplay();

}

void ObjloaderSpaceship () // loads a cube from .obj file
{
int numVert = 0;
int numNormals= 0;
int numcoords = 0;
int numFaces = 0;
int ammount = 0;
string test;
ifstream inputFile;
inputFile.open("cube.obj");

if (!inputFile.good())
    cout << "Problem with Input File";
else
{
    while(!inputFile.eof())
    {

        inputFile >> test;

        if (test == "v")
        {
            inputFile >> v[numVert].x;
            inputFile >> v[numVert].y;
            inputFile >> v[numVert].z;
            numVert++;
        }

        else if(test == "vn")
        {

            inputFile >> vn[numNormals].x;
            inputFile >> vn[numNormals].y;
            inputFile >> vn[numNormals].z;
            numNormals++;
        }
        else if(test == "vt")
        {
            inputFile >> vt[numcoords].x;
            inputFile >> vt[numcoords].y;
            inputFile >> vt[numcoords].z;
            numcoords++;
        }
        else if(test == "f")
        {


            string temp;

            for(int count = 0; count < 3; count++)
            {   

                inputFile >> temp;
                stringstream stream(temp);

                f[numFaces][count].x -= 1;

                getline(stream, temp, '/'); 
                f[numFaces][count].x = atof(temp.c_str());
                getline(stream, temp, '/'); 
                f[numFaces][count].y = atof(temp.c_str());
                getline(stream, temp, '/'); 
                f[numFaces][count].z = atof(temp.c_str());
            }

            numFaces++;
        }


    }


}
}

//void normalKeyboard(unsigned char key, int x, int y) {
//   switch (key)
//   {

//   case 'w' :
//     cam.lookAt.y+=0.5;
//     break;
//   case 'a' :
//     cam.lookAt.y-=0.5;
//     break;
//   case 's' :
//     cam.lookAt.x-=0.5;
//     break;
//   case 'd' :
//     cam.lookAt.x+=0.5;
//     break;
//   }
    //  
//   glutPostRedisplay();

//}




int main(int argc, char* argv[]) 
{

    glutInit(&argc, argv);
    glutCreateWindow("C++ Assignment");
    drawAxes();
    glutMouseFunc(glutMouseFunc);
    glutPassiveMotionFunc(passiveMouseFunc);
    ObjloaderSpaceship();
    glutDisplayFunc(display);
    glutSpecialFunc(specialKeyboard);
//  glutKeyboardFunc(normalKeyboard);

    init();
    glutMainLoop();


}

ここにobjファイルがあります。

# 3ds Max Wavefront OBJ Exporter v0.97b - (c)2007 guruware
# File Created: 23.04.2013 13:50:59

mtllib cube.mtl

#
# object Box001
#

v  2.2289 0.0000 -1.5936
v  2.2289 0.0000 -30.3830
v  31.1072 0.0000 -30.3830
v  31.1072 0.0000 -1.5936
v  2.2289 29.4346 -1.5936
v  31.1072 29.4346 -1.5936
v  31.1072 29.4346 -30.3830
v  2.2289 29.4346 -30.3830
# 8 vertices

vn 0.0000 -1.0000 -0.0000
vn 0.0000 1.0000 -0.0000
vn 0.0000 0.0000 1.0000
vn 1.0000 0.0000 -0.0000
vn 0.0000 0.0000 -1.0000
vn -1.0000 0.0000 -0.0000
# 6 vertex normals

vt 1.0000 0.0000 0.0000
vt 1.0000 1.0000 0.0000
vt 0.0000 1.0000 0.0000
vt 0.0000 0.0000 0.0000
# 4 texture coords

g Box001
usemtl wire_006135006
f 1/1/1 2/2/1 3/3/1 
f 3/3/1 4/4/1 1/1/1 
f 5/4/2 6/1/2 7/2/2 
f 7/2/2 8/3/2 5/4/2 
f 1/4/3 4/1/3 6/2/3 
f 6/2/3 5/3/3 1/4/3 
f 4/4/4 3/1/4 7/2/4 
f 7/2/4 6/3/4 4/4/4 
f 3/4/5 2/1/5 8/2/5 
f 8/2/5 7/3/5 3/4/5 
f 2/4/6 1/1/6 5/2/6 
f 5/2/6 8/3/6 2/4/6 
# 12 faces
4

1 に答える 1

3

This code is crude and has many pitfalls based on assumptions on the input data. But that is your problem to solve and not part of the question.

The important bit of information you probably missed, is that the OBJ format specifies the anything with 1 based indexes. But in C/C++ the indexes are 0 based. You either fix that in the reading routine or the rendering routine. (I would go for reading, since that enables you to read other formats and not alter the rendering code.)

So at line 219 you change the code to be:

    else if(test == "f")
    {
        string temp;
        for(int count = 0; count < 3; count++)
        {   
            inputFile >> temp;
            stringstream stream(temp);

            getline(stream, temp, '/'); 
            f[numFaces][count].x = atoi(temp.c_str()) - 1;
            getline(stream, temp, '/'); 
            f[numFaces][count].y = atoi(temp.c_str()) - 1;
            getline(stream, temp, '/'); 
            f[numFaces][count].z = atoi(temp.c_str()) - 1;
        }

        numFaces++;
    }

You also definitely want tho change your face format to be integer and not floats. I can totally imagine that the values drift.

Also you need to capture the cases where:

  • there is only one vertex (1)
  • a vertex and a texture cord (1/1)
  • a vertex and normal (1//1)
  • the face is not a triangle (more than 3 vertices)
于 2013-04-23T14:15:14.153 に答える