-1

I am working on a project with openGL part. The scenegraph part is based on core OpenGL1.0 and still use glBegin and glEnd. Now I am adding new stuff on it and has to use VAO. I am a beginner and use QOpenGLFunctions_3_0 because I cannot find gl3.h from openGL registry The problem is now that I use GL_TEXTURE_2D with glBegin(GL_QUADS), it works, and I draw single glDrawElements( GL_QUADS, 4, GL_UNSIGNED_BYTE, 0); it works too. But when I use GL_TEXTURE_2D and glDrawElements( GL_QUADS... , the texture is not generated correctly. Please tell me the right way to use it. Here is thd code

/** 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;
};
Colonel Thirty Two
  • 23,953
  • 8
  • 45
  • 85
  • There is no such thing as `gl3.h`, at least not in vanilla OpenGL. You have to load the extension functions, either manually or by using something like `GLEW`. – Colonel Thirty Two Oct 29 '14 at 14:10
  • @ColonelThirtyTwo That's only true on Windows. On other platforms, you simply include the OpenGL headers, and call the functions. – Reto Koradi Oct 29 '14 at 14:16
  • It's also true on many platforms that use GLX (e.g. Linux). OS X is really the oddball among OpenGL implementations, since the library you link to at build-time contains all of the symbols regardless what hardware driver is installed. In any case, `OpenGL/gl3.h` is kind of an Apple construct; if you want the equivalent from the OpenGL registry, it would be `GL/glcorearb.h` – Andon M. Coleman Oct 29 '14 at 16:21

1 Answers1

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));

This is using the generic vertex attributes, but that only makes sense when using sharers, and afaik don't work with the fixed-function pipeline. Either create a shader to use them, or use glVertexPointer, glTexCoordPointer, and/or glNormalPointer instead.

glActiveTexture(GL_TEXTURE0 + m_texture - 1 );

This is incorrect. glActiveTexture selects which texture unit to bind to; it does not use texture names at all. Since you're not using shaders, this should just be glActiveTexture(GL_TEXTURE0).

Side note: You don't need to use an index buffer for drawing a single quad; you can use glDrawArrays instead.

Colonel Thirty Two
  • 23,953
  • 8
  • 45
  • 85
  • I tried glActiveTexture(GL_TEXTURE0), it is the same result. And, I also tried glDrawArrays(GL_QUADS, 0, 4 ); it is still the same, only one color, no texture – langbeibei Oct 29 '14 at 14:18
  • the last parameter is how many vertices are to be drawn you should use `glDrawArrays(GL_QUADS, 0, 4 );` – ratchet freak Oct 29 '14 at 14:23
  • now i use { glVertexPointer(3, GL_FLOAT, sizeof(Vertex), (void*)offsetof(Vertex, position)); glTexCoordPointer( 2, GL_FLOAT, sizeof(Vertex), (void*)offsetof(Vertex, texcoord)); glNormalPointer( GL_FLOAT, sizeof(Vertex), (void*)offsetof(Vertex, normal)); } and dann glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D, m_texture); glDrawArrays(GL_QUADS, 0, 4 ); then I cannot saw the quard at all – langbeibei Oct 29 '14 at 14:35
  • it seems that glVertexPointer doesnot work, if I use glVertexAttribPointer, at least I have a quad, although the texture is not shown, but if I use glVertexPointer, I got nothing at all. – langbeibei Oct 29 '14 at 14:50
  • @langbeibei: If you're going to use `glVertexPointer` and friends, you need to enable the client states such as `GL_VERTEX_ARRAY` instead of using `glEnableVertexAttribArray (...)`. Generic attribute arrays are not supposed to alias to the client arrays in _modern_ (GLSL-based) OpenGL, but in older GL implementations it was understood that generic attribute **0** aliased to `glVertexPointer`, for example; avoid that and write standard compliant code by not mixing and matching the two things. – Andon M. Coleman Oct 29 '14 at 22:26