OpenGl неправильно отображает файлы .obj

Мне дали задание импортировать файл obj и загрузить его на С++.

Он правильно загружает файл, но неправильно его отображает. Может ли кто-нибудь увидеть что-то не так с моей настройкой 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;
}

person Sean Hansford    schedule 21.09.2012    source источник
comment
Я не вижу картинку... и как узнать, что объект загружен правильно?   -  person codeling    schedule 21.09.2012
comment
Упс забыл прикрепить. Я распечатываю массив файла obj именно таким, каким он должен быть.   -  person Sean Hansford    schedule 21.09.2012
comment
Я добавил изображение, извините :)   -  person Sean Hansford    schedule 21.09.2012
comment
это определенно не похоже на неправильные настройки рендеринга, но как будто координаты какие-то неправильные...   -  person codeling    schedule 21.09.2012
comment
Должен ли я также добавить код конвертера? Для obj-файла   -  person Sean Hansford    schedule 21.09.2012
comment
Разместите свой код на github или аналогичном ресурсе, чтобы люди могли скачать проект и посмотреть на него вместо вас. Немного сложно определить, что может быть не так с проектом, если мы не можем запустить IDE и быстро запустить его.   -  person fishfood    schedule 21.09.2012
comment
Возможно, будет проще использовать какой-нибудь API с поддержкой OBJ, например, Qt3D.   -  person dtech    schedule 21.09.2012
comment
Я должен использовать этот API в соответствии со спецификацией, которую мне дали.   -  person Sean Hansford    schedule 21.09.2012
comment
Вы (или ваш синтаксический анализатор) не забыли вычесть 1 из всех индексов OBJ?   -  person Tim    schedule 22.09.2012
comment
@SeanHansford: Вы пытались импортировать простой куб, чтобы проверить, в порядке ли ваш парсер?   -  person Fabien R    schedule 29.09.2012
comment
@ Тим, нет, зачем мне это делать? плохо попробую сейчас.   -  person Sean Hansford    schedule 01.10.2012
comment
@FabienR Я пробовал простые формы и плоскости :(   -  person Sean Hansford    schedule 01.10.2012
comment
@SeanHansford - потому что индексы .obj начинаются с 1 (первая вершина - #1), а OpenGL (и все остальное в мире) начинает считать вершины с 0. Если вы просто используете индексы obj как есть, OpenGL будет ссылаться на все неправильные вершины.   -  person Tim    schedule 01.10.2012
comment
Еще одна вещь, которую следует учитывать, - это наматывание вершин, то есть, если вершины определены по часовой стрелке или против часовой стрелки. Если модель obj была экспортирована из инструмента, где некоторые грани имеют перевернутые нормали, то вершины будут иметь несогласованную обмотку.   -  person Man Vs Code    schedule 03.10.2012
comment
@SeanHansford: Можете ли вы показать OBJ, который вы импортировали для куба?   -  person Fabien R    schedule 06.10.2012


Ответы (1)


Индексы вершин граней в файле .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++);

person Johan Rende    schedule 08.10.2012
comment
Это помогло, но оно по-прежнему отображается неправильно, должно быть более одной ошибки. Обновлю пост новыми картинками - person Sean Hansford; 24.10.2012
comment
На самом деле это и комбинация того, что я не определил правильное количество вершин, были проблемой Thanzx mate - person Sean Hansford; 24.10.2012