2013-05-28 100 views
2

我試圖用GLSL版本330GLSL紋理映射不起作用

這裏將紋理映射的對象是一些代碼,我幫你理解我的問題

片段着色器:

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

加載Mesh和紋理的OpenGL
紋理座標將利用vertexAttribPointer到位置2被boudn(0是位置和1個是正常的)

創建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; 
} 

渲染場景

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

渲染網狀

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

畢竟這段代碼現在是我的問題的簡短描述: 在我的着色器中,我目前正在檢查texCoord是否正確傳遞給着色器,但它始終保持(0,0)。 上傳紋理座標時問題在哪裏?相同的技術被用於vertexPosition和頂點正常工作正常...

回答

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

嘗試傳遞紋理單元索引(texUnit)代替紋理對象ID(texObj,從glGenTextures()呼叫)。

一般:

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

正是你的意思與 「紋理單元指數」 是什麼? – glethien

+3

您的GL實現具有紋理對象可以綁定到的['GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS'紋理單位](http://www.opengl.org/wiki/Texture#Texture_image_units)。你將你想要的紋理對象綁定到活動紋理單元,然後將紋理單元作爲「sampler2D」制服傳入。 – genpfault

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

+0

程序啓動時完成: TextureData textureData; glEnable(GL_TEXTURE_2D); textureData = loadTextureData(「垃圾桶。PNG「); glGenTextures(1,&textureTrash); glBindTexture(GL_TEXTURE_2D,textureTrash); glTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR_MIPMAP_NEAREST); glTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR); glTexImage2D(GL_TEXTURE_2D,0,3,textureData .width,textureData.height,0,GL_BGR,GL_FLOAT,&textureData.data); – glethien