4
\$\begingroup\$

In my shader program, I have my attributes and uniforms added to a map for each. What I have displayed is a heightmap, but cant seem to connect the graphic texture to display.

mUniformList (std::string, GLuint) contains all the uniforms added from my shader (8 total). The problem is that retrieving and connecting the sampler2D named "groundTexture."

void Terrain::init()
{
    ....
    ....

    // VAO 
    glGenVertexArrays(1, &mVAO);
    glBindVertexArray(mVAO);

    // VBO
    glGenBuffers(1, &mVBO);
    glBindBuffer(GL_ARRAY_BUFFER, mVBO);
    glBufferData(GL_ARRAY_BUFFER, sizeof(mVertices), &mVertices[0], GL_STATIC_DRAW);
    glEnableVertexAttribArray(shader["position"]);
    glVertexAttribPointer(shader["position"], 3, GL_FLOAT, GL_FALSE, 0, (void*)0);

    // IBO
    glGenBuffers(1, &mIBO);
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, mIBO);
    glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(mIndices), &mIndices[0], GL_STATIC_DRAW);

    // Load Heightmap texture
    mTexture.loadTexture(heightMapFilePath, mHeightMapTextureID, 0);

    // Texture coordinates
    glGenBuffers(1, &mTexCoordID);
    glBindBuffer(GL_ARRAY_BUFFER, mTexCoordID);
    glBufferData(GL_ARRAY_BUFFER, sizeof(mTexCoords), &mTexCoords[0], GL_STATIC_DRAW);
    glEnableVertexAttribArray(shader["texCoord"]);
    glVertexAttribPointer(shader["texCoord"], 2, GL_FLOAT, GL_FALSE, 0, (void*)0);

    // load ground texture
    mTexture.loadTexture(groundTextureFilePath, mTextureID, 0);

    shader.connectTexture(mTextureID);
}

With connectTexture being:

void TerrainShader::connectTexture(GLuint id)
{
    glActiveTexture(GL_TEXTURE0);
    glBindTexture(GL_TEXTURE_2D, id);
    glUniform1i(mUniformList["backgroundTexture"], 0);
    glBindBuffer(GL_ARRAY_BUFFER, 0);
}

UPDATE Fixed dereferencable error pertaining to the mUniformList. No errors of any kind whatsoever, but still nothing displayed.

terrainfrag.glsl

#version 330 core

layout (location = 0) out vec4 color;

smooth in vec2 TexCoord;
smooth in vec3 Normal;

uniform sampler2D backgroundTexture;

void main()
{
    vec3 normalized = normalize(Normal);

    color = texture(backgroundTexture, TexCoord);
    color += vec4(1, 1, 1, 1);
}

enter image description here

enter image description here

\$\endgroup\$
  • \$\begingroup\$ Can you post the variable declarations of the vertex shader as-well? \$\endgroup\$ – mythos Dec 28 '15 at 6:10
  • \$\begingroup\$ The only thing pertaining to my problem in my vertex shader is passing the texCoord from there to the fragment shader. \$\endgroup\$ – ChocoMan Dec 28 '15 at 6:29
  • \$\begingroup\$ You have color += vec4(1,1,1,1); is that meant to be there just to see the terrain white for the bottom image? \$\endgroup\$ – mythos Dec 28 '15 at 6:43
  • \$\begingroup\$ Yes its just for showing that the heightmap is actually there \$\endgroup\$ – ChocoMan Dec 28 '15 at 7:44
  • \$\begingroup\$ This might be more relevant to Computer Graphics StackExchange \$\endgroup\$ – Archmede May 28 '17 at 16:54
1
\$\begingroup\$

To be able to debug OpenGL errors I highly suggest you use a CheckGLError function to check for errors after OpenGL calls.

My assumption is that you are getting an OpenGL error before your call to connectTexture. I believe that error is because you are not setting a proper offset when passing texCoord data to OpenGL. When you are setting 0 as the offset, and passing vec2 instead of the expected vec3 for position. You want to have an offset for the texCoords. (With the assumption that position is at location 0, and texCoords are at location 1)

To load a model with texture coordinates into OpenGL you want to use code similar to this:

glVertexAttribPointer(shader.texCoord, // index
                      2,               // size [ Use 4 if you can ]
                      GL_FLOAT,        // type
                      GL_FALSE,        // normalized
                      bytesInOneVertex,// stride [ sizeof( Vertex_p3t2 ) ]
                      (GLvoid*)byteOffsetToUVCoords );  // You are missing this?
// Check for OpenGL error

To send a texture to your glsl shader you want to use code similar to this:

glActiveTexture(texNameID);
glBindTexture(GL_TEXTURE_2D, texID);
glUniform1i(textureUniformLocation, texID/*-1*/); // might need to -1 for proper id.
// Check for OpenGL error


For future consideration

Using shader["..."] and find("....") uses a string comparision which will take up a lot of computation time and will slow your program down when you start to have a lot more calls to it. I suggest you change it to direct variables from an array or object instead.
Also I suggest to take advantage of OpenGL by passing vertices of size 4 instead of 3 or 2.

Resources

glVertexAttribPointer: https://www.opengl.org/sdk/docs/man/html/glVertexAttribPointer.xhtml
CheckGLError: glDrawElements Crash

UPDATE

In your connectTexture method try changing it to glUniform1i(mUniformList["backgroundTexture"], id);. Also try id-1 if that doesn't work. Your texture id's start at 1, and 2. So if it is using "2" it won't be reading it from "0".

Edit #2 Here is more detailed code for your reference: Terrain shader from heightmap opengl GLSL

\$\endgroup\$
  • \$\begingroup\$ Thanks for the reply. I was calling mUniform the wrong way in the connectTexture function. Furthermore, I dont have any gl errors flagging. My vertices, indices and texCoords are stored separately, so there is no need for stride. I even converted my array of vec2 texture coords into a single float array, but nothing happened. My first guess is that something has to do with the connectTexture function. my heightmapTexture location has a value of 0, where my backgroundTexture location has a value of 7. Dont know if that means much of anything. \$\endgroup\$ – ChocoMan Dec 28 '15 at 5:32

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.