Part of the Khronos Group
OpenGL.org

The Industry's Foundation for High Performance Graphics

from games to virtual reality, mobile phones to supercomputers

Page 2 of 3 FirstFirst 123 LastLast
Results 11 to 20 of 21

Thread: Texture doesn't appear properly

  1. #11
    Junior Member Newbie
    Join Date
    Dec 2012
    Posts
    8
    Quote Originally Posted by Power2012 View Post
    I did a test, which shows that you could just use one texture unit, such as GL_TEXTURE0.

    and it seems quite a few things are not quite right in your source code.
    What is wrong exactly? Here is the whole class with the init method to get a clearer picture of my code:

    Code :
    #include "global.h"
    #include "CModel.h"
    #include "CModelLoader.h"
    #include "CShaderLoader.h"
     
    CModel::CModel(){}
     
    CModel::~CModel()
    {
        // TODO free memory
    }
     
    /** @brief Load mbm file
      *
      * @fileName: mdm model file name we want to load and draw
      */
    void CModel::init(char *fileName)
    {
        CModelLoader   loader;
        CShaderLoader  shaders;
     
        loader.loadData(fileName);
     
        loader.createDataArray( m_dataArray,
                                m_dataArraySizes,
                                m_numObjects,
                                m_numElements,
                                m_textureIDs );
     
        glGenVertexArrays(1, &m_vertexArrayID);
        glBindVertexArray(m_vertexArrayID);
     
        glEnableVertexAttribArray(0);
        glEnableVertexAttribArray(1);
     
        m_programID      = shaders.loadShaders("vertexshader.vert", "fragmentshader.frag");
     
        //m_matrixUniform  = glGetUniformLocation(m_programID, "MVP");
        //m_textureUniform = glGetUniformLocation(m_programID, "myTextureSampler");
     
        m_bufferIDs      = new unsigned int[m_numObjects];
     
        glGenBuffers(m_numObjects, m_bufferIDs);
        for(unsigned int i=0; i<m_numObjects; i++)
        {
            glBindBuffer(GL_ARRAY_BUFFER, m_bufferIDs[i]);
            glBufferData(GL_ARRAY_BUFFER, sizeof(float)*m_dataArraySizes[i], m_dataArray[i], GL_STATIC_DRAW);
            glBindBuffer(GL_ARRAY_BUFFER, 0);
        }
     
    }
     
    void CModel::draw(glm::mat4 &MVP)
    {
        glActiveTexture(GL_TEXTURE0);
     
        for(unsigned int i=0; i<m_numObjects; i++)
        {
            glUseProgram(m_programID);
     
            unsigned int matrixUniform  = glGetUniformLocation(m_programID, "MVP");
            unsigned int textureUniform = glGetUniformLocation(m_programID, "myTextureSampler");
     
            glUniformMatrix4fv(matrixUniform, 1, GL_FALSE, &MVP[0][0]);
     
            glBindTexture(GL_TEXTURE_2D, m_textureIDs[i]);
     
            glUniform1i(textureUniform, 0);
     
            glBindBuffer(GL_ARRAY_BUFFER, m_bufferIDs[i]);
            // vertices
            glEnableVertexAttribArray(0);
            glVertexAttribPointer(
                    0,                  // must match the layout in the shader.
                    3,                  // size
                    GL_FLOAT,           // type
                    GL_FALSE,           // normalized?
                    sizeof(float)*8,    // stride
                    (void*)0            // array buffer offset
            );
     
            // UVs
            glEnableVertexAttribArray(1);
            glVertexAttribPointer(
                    1,
                    2,
                    GL_FLOAT,
                    GL_FALSE,
                    sizeof(float)*8,
                    (void*)6
            );
     
            glDrawArrays(GL_TRIANGLES, 0, m_numElements[i]);
     
            glDisableVertexAttribArray(0);
            glDisableVertexAttribArray(1);
     
            glUseProgram(0);
        }
     
        //glDisable(GL_TEXTURE_2D);
    }
     
        glUseProgram(0);
        //glDisable(GL_TEXTURE_2D);
    }

  2. #12
    Junior Member Newbie
    Join Date
    Dec 2012
    Posts
    12
    could you try to draw only the first object please, to do so just modify the for loop to for(unsigned int i=0; i<1; i++), see what if you get the texture right or not.

  3. #13
    Junior Member Newbie
    Join Date
    Dec 2012
    Posts
    8
    I tried, draw only the first, then I draw only the second. The texture was the same noisy image.

  4. #14
    Junior Member Newbie
    Join Date
    Dec 2012
    Posts
    12
    you have 2 objects, 2 VBOs, and 1 VAO. I'd suggest to create 2 VAOs rather than just 1

  5. #15
    Junior Member Newbie
    Join Date
    Dec 2012
    Posts
    12
    also could you remove these from the draw() function, and put them into init() function:

    glUniform1i(textureUniform, 0);

    glBindBuffer(GL_ARRAY_BUFFER, m_bufferIDs[i]);
    // vertices
    glEnableVertexAttribArray(0);
    glVertexAttribPointer(
    0, // must match the layout in the shader.
    3, // size
    GL_FLOAT, // type
    GL_FALSE, // normalized?
    sizeof(float)*8, // stride
    (void*)0 // array buffer offset
    );

    // UVs
    glEnableVertexAttribArray(1);
    glVertexAttribPointer(
    1,
    2,
    GL_FLOAT,
    GL_FALSE,
    sizeof(float)*8,
    (void*)6
    );

    glDrawArrays(GL_TRIANGLES, 0, m_numElements[i]);

    glDisableVertexAttribArray(0);
    glDisableVertexAttribArray(1);

    and use 2 VAOs in init(), register these 2 VBOs to the 2 VAOs respectively.

    and in the draw() function, call glBindVertexArray() with proper VAO handle, before the glDrawArray command.

  6. #16
    Junior Member Newbie
    Join Date
    Dec 2012
    Posts
    12
    this is part of my program, hopefully it helps
    Code :
            ///////////////////////////////
    	// texture 1
    	const char *texName ="marble.jpg";
    	QImage timg = QGLWidget::convertToGLFormat(QImage(texName, "JPG"));
    	glActiveTexture(GL_TEXTURE0);
    	//GLuint tid;
    	glGenTextures(1, &tid);
    	glBindTexture(GL_TEXTURE_2D, tid);
    	glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, timg.width(), timg.height(), 0, GL_RGBA, GL_UNSIGNED_BYTE, timg.bits());
    	glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
    	glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
    	int loc = program.index("Tex1", UNIFORM);
    	glUniform1i(loc, 0);
    	///////////////////////////////
    	// texture 2
    	const char *texName2 = "pattern.jpg";
    	QImage timg2 = QGLWidget::convertToGLFormat(QImage(texName2, "JPG"));
    	glActiveTexture(GL_TEXTURE0);
    	//GLuint tid2;
    	glGenTextures(1, &tid2);
    	glBindTexture(GL_TEXTURE_2D, tid2);
    	glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, timg2.width(), timg2.height(), 0, GL_RGBA, GL_UNSIGNED_BYTE, timg2.bits());
    	glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
    	glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
    	int loc2 = program.index("Tex2", UNIFORM);
    	glUniform1i(loc2, 0);
    	///////////////////////////////
    	// generate vertices data
    	tor = new torus(300, 300, 0.3, 1.0);	
    	tor->setMaterials(program, vec3(0.3, 0.3, 0.3), vec3(0.9, 0.9, 0.9), vec3(0.8, 0.8, 0.8), 250.0);
    	///////////////////////////////
    	// create 3 VBOs
    	vertexBufferObj VBOs[3];
    	tor->setVBO(VBOs[0], VERTEX);
    	tor->setVBO(VBOs[1], NORMAL);
    	tor->setVBO(VBOs[2], TEXTURE);
    	///////////////////////////////
    	// create one vertex array object -- VAO, for 3 VBOs
    	vertexArrayObj VAO;
    	tor->registerVAO(VAO.handle());
    	VAO.enable();
    	VAO.enableGenericAttrib(program.index("VertexPosition", GENERIC));
    	VAO.enableGenericAttrib(program.index("VertexNormal",   GENERIC));	
    	VAO.enableGenericAttrib(program.index("VertexTexCoord", GENERIC));
    	tor->setVAO(program, VBOs[0], VERTEX);
    	tor->setVAO(program, VBOs[1], NORMAL);
    	tor->setVAO(program, VBOs[2], TEXTURE);
    	///////////////////////////////
    	// generate a box
    	bx = new box(8.0, 6.0, 16.0);
    	bx->setMaterials(program, vec3(0.3, 0.3, 0.3), vec3(0.9, 0.9, 0.9), vec3(0.8, 0.8, 0.8), 250.0);
    	vertexBufferObj boxVBOs[3];
    	bx->setVBO(boxVBOs[0], VERTEX);
    	bx->setVBO(boxVBOs[1], NORMAL);
    	bx->setVBO(boxVBOs[2], TEXTURE);
    	// vao for box
    	vertexArrayObj boxVAO;
    	bx->registerVAO(boxVAO.handle());
    	boxVAO.enable();
    	boxVAO.enableGenericAttrib(program.index("VertexPosition", GENERIC));
    	boxVAO.enableGenericAttrib(program.index("VertexNormal",   GENERIC));	
    	boxVAO.enableGenericAttrib(program.index("VertexTexCoord", GENERIC));
    	bx->setVAO(program, boxVBOs[0], VERTEX);
    	bx->setVAO(program, boxVBOs[1], NORMAL);
    	bx->setVAO(program, boxVBOs[2], TEXTURE);

    and this is what I get
    Click image for larger version. 

Name:	Untitled.jpg 
Views:	65 
Size:	17.2 KB 
ID:	915

  7. #17
    Junior Member Newbie
    Join Date
    Dec 2012
    Posts
    8
    Thanks for the help. I've never used VAO so it is a bit confusing. I know what it is used for, but I don't really understand what should I put in the init and put in the draw.
    For example the glBindTexture, where does it go? And the uniforms:
    glUniformMatrix4fv(matrixUniform, 1, GL_FALSE, &MVP[0][0]);
    glUniform1i(textureUniform, 0);
    Are these also going to the init()?

  8. #18
    Junior Member Newbie
    Join Date
    Dec 2012
    Posts
    12
    here is a tutorial about VAO which might help

    http://programming4.us/multimedia/8300.aspx

  9. #19
    Junior Member Newbie
    Join Date
    Dec 2012
    Posts
    12
    if you are using 1 texture unit (such as GL_TEXTURE0), then before you draw an object you need to bind the appropriate texture, so glBindTexture will go in the draw();

    you don't need to call glUniform1i(textureUniform, 0) multiple times, so it's better in init();

    if MVP is changing every time, for example, the object is rotating then you need to update MVP, in this case glUniformMatrix4fv(matrixUniform, 1, GL_FALSE, &MVP[0][0]) will be in the draw(), otherwise put it in init()

  10. #20
    Junior Member Newbie
    Join Date
    Dec 2012
    Posts
    8
    I changed my code, I'm suing VAO and I put the glUniform1i in the init. The result is still the same. Maybe the problem is somewhere else? I'm suing SDL for handling the window and load images.
    I'm going to sleep. Thanks for your help, I'll be back tomorrow and continue to fixing this issue.
    Here is the code as I changed based on your tips:

    Code :
    #include "global.h"
    #include "CModel.h"
    #include "CModelLoader.h"
    #include "CShaderLoader.h"
     
    CModel::CModel(){}
     
    CModel::~CModel()
    {
        // TODO free memory
    }
     
    /** @brief Load mbm file
      *
      * @fileName: mdm model file name we want to load and draw
      */
    void CModel::init(char *fileName)
    {
        CModelLoader   loader;
        CShaderLoader  shaders;
     
        loader.loadData(fileName);
     
        loader.createDataArray( m_dataArray,
                                m_dataArraySizes,
                                m_numObjects,
                                m_numElements,
                                m_textureIDs );
     
        m_programID      = shaders.loadShaders("vertexshader.vert", "fragmentshader.frag");
     
        m_textureUniform = glGetUniformLocation(m_programID, "myTextureSampler");
     
        m_bufferIDs      = new unsigned int[m_numObjects];
        m_VAOIDs         = new unsigned int[m_numObjects];
     
        glGenBuffers(m_numObjects,      m_bufferIDs);
        glGenVertexArrays(m_numObjects, m_VAOIDs);
     
        for(unsigned int i=0; i<m_numObjects; i++)
        {
            glBindBuffer(GL_ARRAY_BUFFER, m_bufferIDs[i]);
            glBufferData(GL_ARRAY_BUFFER, sizeof(float)*m_dataArraySizes[i], m_dataArray[i], GL_STATIC_DRAW);
            glBindBuffer(GL_ARRAY_BUFFER, 0);
     
        }
     
        for(unsigned int i=0; i<m_numObjects; i++)
        {
            glBindVertexArray(m_VAOIDs[i]);
            glBindBuffer(GL_ARRAY_BUFFER, m_bufferIDs[i]);
     
            glBindBuffer(GL_ARRAY_BUFFER, m_bufferIDs[i]);
     
            glUniform1i(m_textureUniform, 0);
     
            // vertices
            glEnableVertexAttribArray(0);
            glVertexAttribPointer(
                    0,                  // must match the layout in the shader.
                    3,                  // size
                    GL_FLOAT,           // type
                    GL_FALSE,           // normalized?
                    sizeof(float)*8,    // stride
                    (void*)0            // array buffer offset
            );
     
            // UVs
            glEnableVertexAttribArray(1);
            glVertexAttribPointer(
                    1,
                    2,
                    GL_FLOAT,
                    GL_FALSE,
                    sizeof(float)*8,
                    (void*)6
            );
     
            glBindVertexArray(0);
        }
     
    }
     
    /** @brief Drawing the mdm model
      *
      */
    void CModel::draw(glm::mat4 &MVP)
    {
        glActiveTexture(GL_TEXTURE0);
     
        for(unsigned int i=0; i<m_numObjects; i++)
        {
            glUseProgram(m_programID);
     
            unsigned int matrixUniform  = glGetUniformLocation(m_programID, "MVP");
     
            glBindVertexArray(m_VAOIDs[i]);
     
            glUniformMatrix4fv(matrixUniform, 1, GL_FALSE, &MVP[0][0]);
     
            glBindTexture(GL_TEXTURE_2D, m_textureIDs[i]);
     
            glDrawArrays(GL_TRIANGLES, 0, m_numElements[i]);
     
            //glDisableVertexAttribArray(0);
            //glDisableVertexAttribArray(1);
     
            //glBindBuffer(GL_ARRAY_BUFFER, 0);
     
            glBindVertexArray(0);
     
            glUseProgram(0);
        }
     
    }

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •