簡體   English   中英

使用紋理,法線和索引列表從VBO繪制OpenGL對象時出現問題

[英]Problems with drawing OpenGL objects from VBO using textures,normals & indexlist

我希望這看起來不會太多代碼轉儲,但是我真的不知道為什么它不起作用。 我嘗試過從glGetError()獲取錯誤,並且似乎總是返回0。我嘗試僅包含我認為會影響該問題的代碼,因為在我使用過的大多數其他情況下,其他代碼也能正常工作。

無論如何,先編碼:

這是我的主要渲染循環:

float rotate = 0.0f;
void Render(SDL_Window *window)
{
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

    glLoadIdentity();

    gluLookAt(-2,-2,-10,   0,0,0,   0,1,0);

    glRotatef(rotate, 0, 1, 0);
    // Start drawing
    glUseProgramObjectARB( *shader->GetShaderProgram() );
    texture->EnableTexture( *shader->GetShaderProgram(),"tex" );
    cube->Render();
    SDL_GL_SwapWindow(window);
    rotate = rotate+1;
    glUseProgramObjectARB(0);
}

這是我的對象render(cube-> Render()):

void Object3DVBO::Render()
{

    //Bind the buffers and tell OpenGL to use the Vertex Buffer Objects (VBO's), which we already prepared earlier
    glBindBufferARB(GL_ARRAY_BUFFER_ARB, vboID); 
    glBindBufferARB(GL_ARRAY_BUFFER_ARB, texcoordsID);
    glBindBufferARB(GL_ARRAY_BUFFER_ARB, normalID);
    glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, indiceID);

    //Enable states, and render (as if using vertex arrays directly)
    glEnableClientState(GL_VERTEX_ARRAY);
    glEnableClientState(GL_TEXTURE_COORD_ARRAY);
    glEnableClientState(GL_NORMAL_ARRAY);

    glTexCoordPointer(2, GL_FLOAT, 0, 0);
    glNormalPointer(GL_FLOAT, 0, 0);
    glVertexPointer(3, GL_FLOAT, 0,  0);

    if(textureid > 0) {
        glEnable(GL_TEXTURE_2D);      // Turn on Texturing
        //glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
        glBindTexture(GL_TEXTURE_2D, textureid);
    }

    //Draw the thing!
    glDrawElements(GL_TRIANGLES, indexCount, GL_UNSIGNED_BYTE, 0);
    //restore the GL state back
    glDisableClientState(GL_NORMAL_ARRAY);
    glDisableClientState(GL_TEXTURE_COORD_ARRAY);
    glDisableClientState(GL_VERTEX_ARRAY);
    if(textureid > 0) {
        glDisable(GL_TEXTURE_2D);      // Turn off Texturing
        glBindTexture(GL_TEXTURE_2D, textureid);
    }

    glBindBufferARB(GL_ARRAY_BUFFER_ARB, 0); //Restore non VBO mode
    glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, 0);
};

這是初始化VBO的代碼:

void Object3DVBO::SetVBO()
{
    // Vertices:
    glGenBuffersARB(1, &vboID);
    glBindBufferARB( GL_ARRAY_BUFFER_ARB, vboID);
    glBufferDataARB( GL_ARRAY_BUFFER_ARB, sizeof(GLfloat)*vertices.size(), &vertices, GL_STATIC_DRAW_ARB );

    // Vertices:
    glGenBuffersARB(1, &indiceID);
    glBindBufferARB( GL_ELEMENT_ARRAY_BUFFER_ARB, indiceID);
    glBufferDataARB( GL_ELEMENT_ARRAY_BUFFER_ARB, sizeof(GLubyte)*indices.size(), &indices, GL_STATIC_DRAW_ARB );

    // Normals:
    glGenBuffersARB(1, &normalID);
    glBindBufferARB( GL_ARRAY_BUFFER_ARB, normalID);
    glBufferDataARB( GL_ARRAY_BUFFER_ARB, sizeof(GLfloat)*normals.size(), &normals, GL_STATIC_DRAW_ARB );

    // Texture coordinates:
    glGenBuffersARB(1, &texcoordsID);
    glBindBufferARB( GL_ARRAY_BUFFER_ARB, texcoordsID);
    glBufferDataARB( GL_ARRAY_BUFFER_ARB, sizeof(GLfloat)*texCoords.size(), &texCoords, GL_STATIC_DRAW_ARB );

    vertices.clear();
    normals.clear();
    texCoords.clear();
    indices.clear();
}

最后是Ive在文本文件中創建的最簡單模型:

mesh:
-0.5 -0.5 0.0
0.5 -0.5 0.0
0.5 0.5 0.0
-0.5 0.5 0.0
normals:
0 0 -1
0 0 -1
0 0 -1
0 0 -1
texcoords:
0.0 0
1.0 0
1.0 1.0
0.0 1.0
indices:
0 0 0 1 1 1 2 2 2 0 0 0 2 2 2 3 3 3
end:

除此之外,還需要讀取文本文件並將其存儲到函數的向量中。 這是對象的頭文件:

class Object3DVBO
{
public:
    Object3DVBO(const char* objectfilename, GLuint textureid);
    ~Object3DVBO();
    void Render();
private:
    GLuint  vboID, 
            texcoordsID, 
            normalID, 
            textureid,
            indiceID;
    int     vertCount,
            indexCount;
    std::vector<GLfloat> vertices;
    std::vector<GLfloat> normals;
    std::vector<GLfloat> texCoords;
    std::vector<GLubyte> indices;

    void ConvertToReadable( std::vector<GLfloat> v, std::vector<GLfloat> n, std::vector<GLfloat> tc, std::vector<GLint> i);
    void ReadObjectData( const char* objectfilename);
    void SetVBO();
};

其他部分基本上是對着色器對和紋理執行相同的操作,它們似乎工作正常(Shader目前僅適用於120版,因此使用ftransform()等)。

我遇到的問題是,當我使用此代碼和使用帶有索引的glDrawElements時,出現黑屏(任何地方都沒有錯誤),然后如果我切換到glDrawArrays,它就會起作用(或者至少我看到了東西。我已經閱讀了很多教程,示例和其他SO帖子試圖找到Im在做什么,但是到目前為止,所有解決方案/教程都沒有任何改變。

我這樣做是出於教育目的,因此我確實需要使用glDrawElements和索引。 任何幫助將不勝感激!

PS。 如果有人想知道SDL版本,那就是它的SDL2。

這是您問題的症結所在:

//Bind the buffers and tell OpenGL to use the Vertex Buffer Objects (VBO's), which we already prepared earlier
glBindBufferARB(GL_ARRAY_BUFFER_ARB, vboID);          // 1
glBindBufferARB(GL_ARRAY_BUFFER_ARB, texcoordsID);    // 2
glBindBufferARB(GL_ARRAY_BUFFER_ARB, normalID);       // 3
glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, indiceID);

//Enable states, and render (as if using vertex arrays directly)
glEnableClientState(GL_VERTEX_ARRAY);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
glEnableClientState(GL_NORMAL_ARRAY);

glTexCoordPointer(2, GL_FLOAT, 0, 0);                 // 2
glNormalPointer(GL_FLOAT, 0, 0);                      // 3
glVertexPointer(3, GL_FLOAT, 0,  0);                  // 1

標有1、2和3的線必須成對出現。 就是說,由於一次只能綁定一個VBO,並且它提供了例如調用glTexCoordPointer (...)的上下文,因此需要在綁定適當的VBO時設置指針。

您可以這樣解決:

//Bind the buffers and tell OpenGL to use the Vertex Buffer Objects (VBO's), which we already prepared earlier
glBindBufferARB(GL_ARRAY_BUFFER_ARB, vboID);          // 1
glVertexPointer(3, GL_FLOAT, 0,  0);                  // 1

glBindBufferARB(GL_ARRAY_BUFFER_ARB, texcoordsID);    // 2
glTexCoordPointer(2, GL_FLOAT, 0, 0);                 // 2

glBindBufferARB(GL_ARRAY_BUFFER_ARB, normalID);       // 3
glNormalPointer(GL_FLOAT, 0, 0);                      // 3


glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, indiceID);

//Enable states, and render (as if using vertex arrays directly)
glEnableClientState(GL_VERTEX_ARRAY);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
glEnableClientState(GL_NORMAL_ARRAY);

您還有一個問題,這實際上不是錯誤,而是性能問題。 GL_UNSIGNED_BYTE不是硬件支持的頂點索引類型。 驅動程序必須將索引數組轉換為16位類型,硬件才能使用它,因此將8位索引存儲在VBO中時,使用8位索引並沒有實際好處。 如果您嘗試執行此操作,則大多數啟用了調試輸出的OpenGL分析器和驅動程序都會生成性能警告。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM