2

I am trying to map a texture to objects using GLSL version 330

Here is some code that my help you understanding my problem

Fragment Shader:

#version 330
layout(location = 0) in vec3 vertex;
layout(location = 1) in vec3 vertex_normal;
layout(location = 2) in vec2 texCoord;

out vec2 tCoord;

uniform mat4 modelview;
uniform mat4 projection;

void main() {

  gl_Position = projection * modelview * vec4(vertex, 1.0);
  tCoord = texCoord;

}

Vertex Shader

#version 330

in vec2 tCoord;

uniform sampler2D texture;

out vec4 color;

void main() {
  if(tCoord == vec2(0,0))
    color = vec4(1.0,0.0,0.0,1.0);
  else
    color = vec4(0.0,1.0,0.0,1.0);
}

Loading the Mesh and texture to OpenGL
texture coordinates will be boudn using vertexAttribPointer to position 2 (0 is position and 1 is normal)

Creating the MeshObj

void MeshObj::setData(const MeshData &meshData) {
  mIndexCount = meshData.indices.size();

  // TODO: extend this method to upload texture coordinates as another VBO //
  // - texture coordinates are at location 2 within the shader code


  // create local storage arrays for vertices, normals and indices //
  unsigned int vertexDataSize = meshData.vertex_position.size();
  unsigned int vertexNormalSize = meshData.vertex_normal.size();
  unsigned int vertexTexcoordSize = meshData.vertex_texcoord.size();

  GLfloat *vertex_position = new GLfloat[vertexDataSize]();
  std::copy(meshData.vertex_position.begin(), meshData.vertex_position.end(), vertex_position);
  GLfloat *vertex_normal = NULL;
  if (vertexNormalSize > 0) {
    vertex_normal = new GLfloat[vertexNormalSize]();
    std::copy(meshData.vertex_normal.begin(), meshData.vertex_normal.end(), vertex_normal);
  }
  GLfloat *vertex_texcoord = NULL;
  if (vertexTexcoordSize > 0) {
    vertex_texcoord = new GLfloat[vertexTexcoordSize]();
    std::copy(meshData.vertex_texcoord.begin(), meshData.vertex_texcoord.end(), vertex_texcoord);
  }
  GLuint *indices = new GLuint[mIndexCount]();
  std::copy(meshData.indices.begin(), meshData.indices.end(), indices);

  // create VAO //
  if (mVAO == 0) {
    glGenVertexArrays(1, &mVAO);
  }
  glBindVertexArray(mVAO);

  // create and bind VBOs and upload data (one VBO per available vertex attribute -> position, normal) //
  if (mVBO_position == 0) {
    glGenBuffers(1, &mVBO_position);
  }
  glBindBuffer(GL_ARRAY_BUFFER, mVBO_position);
  glBufferData(GL_ARRAY_BUFFER, vertexDataSize * sizeof(GLfloat), &vertex_position[0], GL_STATIC_DRAW);
  glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, (void*)0);
  glEnableVertexAttribArray(0);

  if (vertexNormalSize > 0) {
    if (mVBO_normal == 0) {
      glGenBuffers(1, &mVBO_normal);
    }
    glBindBuffer(GL_ARRAY_BUFFER, mVBO_normal);
    glBufferData(GL_ARRAY_BUFFER, vertexNormalSize * sizeof(GLfloat), &vertex_normal[0], GL_STATIC_DRAW);
    glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 0, (void*)0);
    glEnableVertexAttribArray(1);
  }

  if (vertexTexcoordSize > 0) {
    if (mVBO_texcoord == 0) {
      glGenBuffers(1, &mVBO_texcoord);
    }
    std::cout << "Texture stuff set" << std::endl;
    glBindBuffer(GL_ARRAY_BUFFER, mVBO_texcoord);
    glBufferData(GL_ARRAY_BUFFER, vertexTexcoordSize * sizeof(GLfloat), &vertex_texcoord[0], GL_STATIC_DRAW);
    glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, 0, (void*)0);
    glEnableVertexAttribArray(2);
  }

  // init and bind a IBO //
  if (mIBO == 0) {
    glGenBuffers(1, &mIBO);
  }
  glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, mIBO);
  glBufferData(GL_ELEMENT_ARRAY_BUFFER, mIndexCount * sizeof(GLuint), &indices[0], GL_STATIC_DRAW);

  // unbind buffers //
  glBindVertexArray(0);

  // make sure to clean up temporarily allocated data, if neccessary //
  delete[] vertex_position;
  if (vertexNormalSize > 0) {
    delete[] vertex_normal;
  }
  if (vertexTexcoordSize > 0) {
    delete[] vertex_texcoord;
  }
  delete[] indices;
}

Render the Scene

  glm_ModelViewMatrix.push(glm_ModelViewMatrix.top());
  glActiveTexture(GL_TEXTURE0);

  glm_ModelViewMatrix.top() = glm::translate(glm_ModelViewMatrix.top(),0.0f,-13.0f,-10.0f);
  glUniformMatrix4fv(uniformLocations["modelview"], 1, false, glm::value_ptr(glm_ModelViewMatrix.top()));

  glBindTexture(GL_TEXTURE_2D, objLoader->getMeshObj("trashbin")->getTexttureID());
  glUniform1i(glGetUniformLocation(shaderProgram,"texture"), objLoader->getMeshObj("trashbin")->getTexttureID());
  objLoader->getMeshObj("trashbin")->render();



  glm_ModelViewMatrix.top() = glm::translate(glm_ModelViewMatrix.top(),-9.0f,-13.0f,-10.0f);
  glm_ModelViewMatrix.top() = glm::scale(glm_ModelViewMatrix.top(), 1.5f,1.5f,1.5f);
  glUniformMatrix4fv(uniformLocations["modelview"], 1, false, glm::value_ptr(glm_ModelViewMatrix.top()));

  glBindTexture(GL_TEXTURE_2D, objLoader->getMeshObj("ball")->getTexttureID());
  glUniform1i(glGetUniformLocation(shaderProgram,"texture"), objLoader->getMeshObj("ball")->getTexttureID());
  objLoader->getMeshObj("ball")->render();

  // restore scene graph to previous state //
  glm_ModelViewMatrix.pop();

Render the mesh

void MeshObj::render(void) {
  // render your VAO //
  if (mVAO != 0) {
    glBindVertexArray(mVAO);
    glDrawElements(GL_TRIANGLES, mIndexCount, GL_UNSIGNED_INT, (void*)0);
    glBindVertexArray(0);
  }
}

After all this code, now a short description of my problem: In my shaders I am currently checking if the texCoord is passed correctly to the shader, but it always stays (0,0). Where is the problem when uploading the texture coordinates? The same technique is working fine for the vertexPosition and the vertex normal...

4

2 に答える 2

3
glUniform1i(glGetUniformLocation(shaderProgram,"texture"), objLoader->getMeshObj("trashbin")->getTexttureID());

テクスチャ オブジェクト ID ( 、呼び出しからtexUnit) の代わりに、テクスチャ ユニット インデックス ( ) を渡してみてください。texObjglGenTextures()

一般的:

unsigned int texUnit = 0;
glActiveTexture​( GL_TEXTURE0​ + texUnit );
glBindTexture​( GL_TEXTURE_2D, texObj );
glUniform1i( ..., texUnit );

あなたの場合:

glActiveTexture( GL_TEXTURE0 );
...
glBindTexture( GL_TEXTURE_2D, objLoader->getMeshObj("trashbin")->getTexttureID() );
glUniform1i( glGetUniformLocation( shaderProgram, "texture" ), 0 );
于 2013-05-28T16:27:19.790 に答える
1

どの時点でもOpenGLに画像を渡さないでくださいglTexImage2D

これをバインド テクスチャの下に追加して、テクスチャを OpenGL にします。

//example parameters, substitute with your own.    
glTexImage2D(GL_TEXTURE_2D, 0,GL_RGB, width, height, 0, GL_BGR, GL_UNSIGNED_BYTE, data);
//just parameters for texture(optional)
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);

glTexImage2D への参照:

http://www.opengl.org/sdk/docs/man/xhtml/glTexImage2D.xml

于 2013-05-28T16:34:40.330 に答える