为什么纹理(GL_TEXTURE_2D)无法与(VertexArray)VAO一起使用

时间:2014-10-29 13:40:58

标签: opengl texture2d vao

我正在开发一个带有openGL部分的项目。 scenegraph部分基于核心OpenGL1.0,仍然使用glBegin和glEnd。 现在我在其上添加新内容并且必须使用VAO。我是初学者并使用QOpenGLFunctions_3_0,因为我无法从openGL注册表中找到gl3.h 现在的问题是我使用GL_TEXTURE_2D glBegin(GL_QUADS),它有效, 我画单glDrawElements( GL_QUADS, 4, GL_UNSIGNED_BYTE, 0);它也有效。 但是当我使用GL_TEXTURE_2DglDrawElements( GL_QUADS...时,纹理不会正确生成。请告诉我使用它的正确方法。 这是代码

/** draws Texture */

class TextureNode
    : public Node
{

public:

TextureNode( const cv::Mat& mat )
{
    m_mat = mat;
}
TextureNode( const std::string& id, const cv::Mat& mat )
    : Node( id )
{
    m_mat = mat;
}

~TextureNode()
{
    //glDeleteTextures( 1, &m_texture[0] );
}

void init( TraversalContext& context )
{
    initializeOpenGLFunctions();


    struct Vertex {
      GLfloat position[3];
      GLfloat texcoord[2];
      GLfloat normal[3];
    };
    const int NUM_VERTS = 4;
    const int NUM_INDICES = 4;
    Vertex vertexdata[NUM_VERTS] = {
        {{0,    0,  0},         {0,0},  {0,0,1}},
        {{0,    100,    0},     {0,1},  {0,0,1}},
        {{100,  100,    0},     {1,1},  {0,0,1}},
        {{100,  0,  0},         {1,0},  {0,0,1}},
    };
    GLubyte indexdata[NUM_INDICES] = { 0, 1, 2, 3 };

            // Create and bind a VAO
    glGenVertexArrays(1, &m_quadVAO);
    glBindVertexArray(m_quadVAO);

    glGenBuffers(1, &m_quadPositionVBO);
    glBindBuffer(GL_ARRAY_BUFFER, m_quadPositionVBO);

    // copy data into the buffer object
    glBufferData(GL_ARRAY_BUFFER, NUM_VERTS * sizeof(Vertex), vertexdata, GL_STATIC_DRAW);


    glEnableVertexAttribArray(0);
    glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), (void*)offsetof(Vertex, position));
    glEnableVertexAttribArray(1);
    glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, sizeof(Vertex), (void*)offsetof(Vertex, texcoord));
    glEnableVertexAttribArray(2);
    glVertexAttribPointer(2, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), (void*)offsetof(Vertex, normal));

    glGenBuffers(1, &m_quadIndexVBO);
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_quadIndexVBO);

    // copy data into the buffer object
    glBufferData(GL_ELEMENT_ARRAY_BUFFER, NUM_INDICES * sizeof(GLubyte), indexdata, GL_STATIC_DRAW);


    // Create and bind a texture

    glGenTextures(1, &m_texture);                 // Create The Texture
    glBindTexture(GL_TEXTURE_2D, m_texture); 
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, m_mat.cols, m_mat.rows, 0, GL_BGR, GL_UNSIGNED_BYTE,  m_mat.data);

    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
    glTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_NEAREST); 
    glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_S,GL_CLAMP);
    glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_T,GL_CLAMP);

    //////// At this point the VAO is set up with two vertex attributes
    //////// referencing the same buffer object, and another buffer object
    //////// as source for index data. We can now unbind the VAO, go do
    //////// something else, and bind it again later when we want to render
    //////// with it.

    glBindTexture(GL_TEXTURE_2D, 0); 
    glBindVertexArray(NULL);    

    //////glBindBuffer(GL_ARRAY_BUFFER, NULL);  
    //glBindTexture( GL_TEXTURE_2D, NULL );
    //////glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, NULL); 


}

/** apply transformation */
void doWork( TraversalContext& context )
{

//QTime time;
//time.start();
    initializeOpenGLFunctions();
    glDisable( GL_LIGHTING );

    glEnable(GL_TEXTURE_2D);
    glBindVertexArray( m_quadVAO );



    //glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);



    glActiveTexture(GL_TEXTURE0 + m_texture - 1 );
    glBindTexture(GL_TEXTURE_2D, m_texture);
    glDrawElements( GL_QUADS, 4, GL_UNSIGNED_BYTE, 0);

    //glBegin(GL_QUADS);
    //  glColor3d( 0,0,0 );
    //  glTexCoord2f(1.0f, 0.0f); glVertex2d( 0, 0 );
    //  glTexCoord2f(1.0f, 1.0f); glVertex2d( 0, m_mat.rows );
    //  glTexCoord2f(0.0f, 1.0f); glVertex2d( m_mat.cols, m_mat.rows );
    //  glTexCoord2f(0.0f, 0.0f); glVertex2d( m_mat.cols, 0 );
    //glEnd();

    glBindTexture(GL_TEXTURE_2D, 0);
    glDisable(GL_TEXTURE_2D);


    glBindVertexArray(0);
    glEnable( GL_LIGHTING );
}
void destroy( TraversalContext& context )
{

    glDeleteVertexArrays( 1, &m_quadVAO );
    glDeleteTextures(1,&m_texture);
    glDeleteBuffers(1, &m_quadPositionVBO);
    glDeleteBuffers(1, &m_quadTexcoordVBO);
    glDeleteBuffers(1, &m_quadIndexVBO);
}


protected:

GLuint m_quadVAO;
GLuint m_quadPositionVBO;
GLuint m_quadTexcoordVBO;
GLuint m_quadIndexVBO;
GLuint m_texture;
///** list of vertices */
GLfloat m_vertices[4][2];
cv::Mat m_mat;
};

1 个答案:

答案 0 :(得分:0)

glEnableVertexAttribArray(0);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), (void*)offsetof(Vertex, position));
glEnableVertexAttribArray(1);
glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, sizeof(Vertex), (void*)offsetof(Vertex, texcoord));
glEnableVertexAttribArray(2);
glVertexAttribPointer(2, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), (void*)offsetof(Vertex, normal));

这是使用通用顶点属性,但这只有在使用共享器时才有意义,并且afaik不能使用固定功能管道。创建着色器以使用它们,或者使用glVertexPointerglTexCoordPointer和/或glNormalPointer代替。

glActiveTexture(GL_TEXTURE0 + m_texture - 1 );

这是不正确的。 glActiveTexture选择要绑定的纹理单元;它根本不使用纹理名称。由于您不使用着色器,因此应该只有glActiveTexture(GL_TEXTURE0)

附注:您不需要使用索引缓冲区来绘制单个四边形;您可以改为使用glDrawArrays