c++ - OpenGl 无法正确呈现 .obj 文件

标签 c++ opengl glut wavefront

我的任务是导入一个 obj 文件并用 C++ 加载它。

它正确加载文件但显示不正确。有人能看出我的 opengl 设置有什么问题吗? :)

这是一张渲染图看起来像 atm

#define _USE_MATH_DEFINES
#include<stdio.h>
#include <GL/glew.h>
#include <GL/glut.h>
#include "InitShader.h"
#include <math.h>
#include "MatrixStack.h"
#include "Object.h"
#include <time.h>

#define BUFFER_OFFSET( offset )   ((GLvoid*) (offset))
float x = 1.0;
const int NumVertices = 144;
const int NumIndicies = 104;
GLfloat  vertices[NumVertices];

// RGBA olors
GLfloat vertexColours[NumVertices];

// each entry is an index into the vertices matrix
GLint vertexIndicies[NumIndicies];


//GLfloat vertices2[NumVertices];

// RGBA olors
//GLfloat vertexColours2[NumVertices];

// each entry is an index into the vertices matrix
//GLint vertexIndicies2[NumIndicies];

GLuint vao;
GLuint program;
GLuint buffers[2];
GLfloat radius = 1.0;

GLfloat theta = 0.0;
GLfloat phi = 0.0;

const GLfloat  dr = 5.0 * M_PI/180.0;

// Projection transformation parameters

GLfloat  left2 = -1.0, right2 = 1.0;
GLfloat  bottom = -1.0, top = 1.0;
GLfloat  zNear = 0.5, zFar = 3.0;

GLuint  modelView;  // model-view matrix uniform shader variable location
GLuint  projection; // projection matrix uniform shader variable location

MatrixStack modelViewStack(5);
MatrixStack projectionStack(5);
// OpenGL initialization
void
init()
{
        srand ( time(NULL) );
        Object myst("assignment1.obj");
        float *tempFloat = myst.verts();
        float *tempFloat2 = myst.indis();
        for (unsigned int i=0; i<NumVertices; vertices[i]=tempFloat[i],i++);
        for (unsigned int i=0; i<NumIndicies; vertexIndicies[i]=tempFloat2[i],i++);
        for (unsigned int i=0; i<NumVertices;i++){
            float a = (float)(rand()%10);
            a = a/10;
            cout << a;
            vertexColours[i]=a;
        }
        for (unsigned int i=0; i<NumVertices; cout << vertices[i] << endl ,i++);
        for (unsigned int i=0; i<NumIndicies; cout << vertexIndicies[i] << endl ,i++);
        glEnable( GL_DEPTH_TEST );
        //make background yerpul in colour
        glClearColor( 0.235,  0.194,  0.314, 1.0 );

        // Load shaders and use the resulting shader program
        program = InitShader( "vshader41.glsl", "fshader41.glsl" );
        glUseProgram( program );

        // Create a vertex array object
        glGenVertexArrays( 1, &vao );
        glBindVertexArray( vao );

        // Create and initialize two buffer objects
        glGenBuffers( 2, buffers);

        //one buffer for the vertices and colours
        glBindBuffer( GL_ARRAY_BUFFER, buffers[0]);
        glBufferData( GL_ARRAY_BUFFER, sizeof(vertices) + sizeof(vertexColours),NULL, GL_STATIC_DRAW );
        glBufferSubData( GL_ARRAY_BUFFER, 0, sizeof(vertices), vertices );
        glBufferSubData( GL_ARRAY_BUFFER, sizeof(vertices), sizeof(vertexColours), vertexColours);

        //one buffer for the indices
        glBindBuffer( GL_ELEMENT_ARRAY_BUFFER, buffers[1]);
        glBufferData( GL_ELEMENT_ARRAY_BUFFER, sizeof(vertexIndicies),vertexIndicies, GL_STATIC_DRAW );

        // set up vertex arrays
        GLuint vPosition = glGetAttribLocation( program, "vPosition" );
        glEnableVertexAttribArray( vPosition );
        glVertexAttribPointer( vPosition, 4, GL_FLOAT, GL_FALSE, 0, BUFFER_OFFSET(0) );

        GLuint vColor = glGetAttribLocation( program, "vColor" );
        glEnableVertexAttribArray( vColor );
        glVertexAttribPointer( vColor, 4, GL_FLOAT, GL_FALSE, 0, BUFFER_OFFSET(sizeof(vertices)) );

        modelView = glGetUniformLocation( program, "model_view" );
        projection = glGetUniformLocation( program, "projection" );

        glBindBuffer(GL_ARRAY_BUFFER, 0);
        glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
        glBindVertexArray(0);
        }

//----------------------------------------------------------------------------

void
display( void )
{
    glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
    modelViewStack.loadIdentity();
    modelViewStack.lookAt(radius*sin(theta)*cos(phi),
            radius*sin(theta)*sin(phi),
            radius*cos(theta),
            0.0,0.0,0.0,
            0.0,1.0,0.0);

    glUniformMatrix4fv(modelView, 1, GL_FALSE, modelViewStack.getMatrixf());

    projectionStack.loadIdentity();
    projectionStack.ortho(left2,right2,bottom,top,zNear,zFar);

    glUniformMatrix4fv(projection, 1, GL_FALSE, projectionStack.getMatrixf());

    glBindVertexArray(vao);
    glBindBuffer(GL_ARRAY_BUFFER, buffers[0]);
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, buffers[1]);
    //Indexing into vertices we need to use glDrawElements
    glDrawElements (GL_TRIANGLES, NumIndicies, GL_UNSIGNED_INT, 0);
    glutSwapBuffers();
}

//----------------------------------------------------------------------------

void keyboard( unsigned char key, int x, int y )
{
    switch( key ) {
        case 033: // Escape Key
        case 'q': case 'Q':
        exit( EXIT_SUCCESS );
        break;

        case 'x': left2 *= 1.1; right2 *= 1.1; break;
        case 'X': left2 *= 0.9; right2 *= 0.9; break;
        case 'y': bottom *= 1.1; top *= 1.1; break;
        case 'Y': bottom *= 0.9; top *= 0.9; break;
        case 'z': zNear  *= 0.9; zFar *= 1.1; break;
        case 'Z': if (zNear<zFar){zNear *= 1.1; zFar *= 0.9;} break;
        case 'r': radius *= 2.0; break;
        case 'R': radius *= 0.5; break;
        case 'o': theta += dr; break;
        case 'O': theta -= dr; break;
        case 'p': phi += dr; break;
        case 'P': phi -= dr; break;

        case ' ':  // reset values to their defaults
        left2 = -1.0;
        right2 = 1.0;
        bottom = -1.0;
        top = 1.0;
        zNear = -1.0;
        zFar = 1.0;

        radius = 1.0;
        theta  = 0.0;
        phi    = 0.0;
        break;
  }

  glutPostRedisplay();
}
//----------------------------------------------------------------------------
void idle(){
    theta += .001;

    left2 += .0001;

    glutPostRedisplay();
}
//----------------------------------------------------------------------------
void
reshape( int width, int height )
{
    glViewport( 0, 0, width, height );
}

//----------------------------------------------------------------------------


int
main( int argc, char **argv )
{
    glutInit( &argc, argv );
    glutInitDisplayMode( GLUT_RGBA | GLUT_DOUBLE | GLUT_DEPTH );
    glutInitWindowSize( 512, 512 );
    glutCreateWindow( "Orbit the Color Cube - Orthographic" );

    glewInit();

    init();
    glutIdleFunc(idle);
    glutDisplayFunc( display );
    glutKeyboardFunc( keyboard );
    glutReshapeFunc( reshape );

    glutMainLoop();
    return 0;
}

最佳答案

.obj 文件中面的顶点索引从 1 开始,而不是预期的 0。加载文件时尝试将每个索引减少 1。如果我没看错你的代码,这一行:

for (unsigned int i=0; i<NumIndicies; vertexIndicies[i]=tempFloat2[i],i++);

应该是

for (unsigned int i=0; i<NumIndicies; vertexIndicies[i]=tempFloat2[i] - 1,i++);

关于c++ - OpenGl 无法正确呈现 .obj 文件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12526165/

相关文章:

c++ - 将链表存储为数组 C++ 中的索引

c++ - 地址运算符 (&) 与引用运算符 (&)

OpenGL状态冗余消除树,渲染状态优先级

c - OpenGL函数不输出任何错误但不起作用

opengl - 使用GLUT位图字体

c++ - 在 C++ 中重写 operator=

c++ - 相机校准结果 : why it is similar to input?

c++ - 在 OpenGl 中渲染 mandelbrot 集

java - 将多边形分割成多个部分

c++ - 包含 glew c++ 后不能使用 glut 函数