GLSL纹理映射不起作用

时间:2022-09-10 18:49:29

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

我正在尝试使用GLSL版本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)

将网格和纹理加载到OpenGL纹理坐标将使用vertexAttribPointer到位置2(0是位置,1是正常)

Creating the MeshObj

创建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...

在所有这些代码之后,现在我的问题的简短描述:在我的着色器中,我正在检查texCoord是否正确传递到着色器,但它始终保持(0,0)。上传纹理坐标时问题出在哪里?相同的技术适用于vertexPosition和顶点法线...

2 个解决方案

#1


3  

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

Try passing in the texture unit index (texUnit) instead of the texture object ID (texObj, from a glGenTextures() call).

尝试传入纹理单元索引(texUnit)而不是纹理对象ID(texObj,来自glGenTextures()调用)。

Generally:

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

In your case:

在你的情况下:

glActiveTexture( GL_TEXTURE0 );
...
glBindTexture( GL_TEXTURE_2D, objLoader->getMeshObj("trashbin")->getTexttureID() );
glUniform1i( glGetUniformLocation( shaderProgram, "texture" ), 0 );

#2


1  

You don't give the image to OpenGL at any point with glTexImage2D

您不能使用glTexImage2D随时将图像提供给OpenGL

Add this below your bind texture in order to give OpenGL your texture

在绑定纹理下面添加这个,以便为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);

Reference to glTexImage2D:

参考glTexImage2D:

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

#1


3  

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

Try passing in the texture unit index (texUnit) instead of the texture object ID (texObj, from a glGenTextures() call).

尝试传入纹理单元索引(texUnit)而不是纹理对象ID(texObj,来自glGenTextures()调用)。

Generally:

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

In your case:

在你的情况下:

glActiveTexture( GL_TEXTURE0 );
...
glBindTexture( GL_TEXTURE_2D, objLoader->getMeshObj("trashbin")->getTexttureID() );
glUniform1i( glGetUniformLocation( shaderProgram, "texture" ), 0 );

#2


1  

You don't give the image to OpenGL at any point with glTexImage2D

您不能使用glTexImage2D随时将图像提供给OpenGL

Add this below your bind texture in order to give OpenGL your texture

在绑定纹理下面添加这个,以便为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);

Reference to glTexImage2D:

参考glTexImage2D:

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