2017-01-16 204 views
0

先前,很抱歉發佈了大量代碼。我會盡可能地簡單明瞭。紋理映射會導致紋理中的1個像素的純色

我的紋理是bmp格式的4x4紋理圖像(如果有人在這裏感興趣的話 - >4x4 texture image)。作爲映射的結果,我得到頂部左像素(0.0,1.0)的顏色(我檢查了它,它總是左上像素的顏色),而我的三角形顏色導致該像素的顏色爲白色。 enter image description here 我試着在GL_TEXTURE_MAG_FILTER

glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); 
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); 

改變GL_NEARESTGL_LINEAR,我也得到右下角的像素(1.0,0.0),這是某種形式的綠色: enter image description here 我使用stb_image加載質感。所以在我的Texture.cpp

Texture::Texture(const std::string& fileName) 
{ 
    int width, height, numComponents; 
    unsigned char* imageData = stbi_load(fileName.c_str(), &width, &height, &numComponents, 4); 
    if (imageData == NULL) 
    { 
     std::cerr << "Error: Texture load failed for texture: " << fileName << std::endl; 
    } 

    glEnable(GL_TEXTURE_2D); 
    glGenTextures(1, &_texture); 

    glBindTexture(GL_TEXTURE_2D, _texture); 

    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); 
    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); 
    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); 
    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); 

    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, imageData); 

    stbi_image_free(imageData); 
} 
Texture::~Texture(void) 
{ 
    glDeleteTextures(1, &_texture); 
} 

void Texture::Bind(unsigned int unit) 
{ 
    assert(unit >= 0 && unit <= 31); 
    glActiveTexture(GL_TEXTURE0 + unit); 
    glBindTexture(GL_TEXTURE_2D, _texture); 
} 

在我頂點着色器

#version 150 

in vec3 position; 
in vec2 texCoord; 

out vec2 texCoord0; 

void main(void) 
{ 
    texCoord0 = texCoord; 
    gl_Position = vec4(position, 1.0); 
} 

在我片段着色器

#version 150 

in vec2 textCoord0; 
uniform sampler2D texture; 

void main(void) 
{ 
    gl_FragColor = texture2D(texture, textCoord0); 
} 

在我的main.cpp

#include <iostream> 
#include <GL/glew.h> 
#include "Display.h" 
#include "Shader.h" 
#include "Mesh.h" 
#include "Texture.h" 
int main(int argc, char** argv) 
{ 
    Display display(800, 600, " "); 
    display.Clear(0.0f, 0.15f, 0.3f, 1.0f); 
    Vertex vertices[] = { 
          Vertex(glm::vec3(-1.0f, -1.0f, 0.0f), glm::vec2(0.0f, 0.0f)), 
          Vertex(glm::vec3(0.0f, 1.0f, 0.0f), glm::vec2(0.5f, 1.0f)), 
          Vertex(glm::vec3(1.0f, -1.0f, 0.0f), glm::vec2(1.0f, 0.0f)) 
    }; 
    Texture texture("./res/a.bmp"); 
    Shader shader("./res/testShader"); 
    Mesh mesh(vertices, sizeof(vertices)/sizeof(vertices[0])); 
    while (display.IsClosed() != true) 
    { 
     shader.Bind(); 
     texture.Bind(0); 
     mesh.Draw(); 
     display.Update(); 
    } 
    return 0; 
} 

Mesh.cpp我是分裂的頂點屬性(GLM :: VEC3 _position和GLM :: VEC2 _texture)到2個STL矢量,並使用2個緩衝器( 「0」 - 1頂點的位置,並且」 「 - 紋理):

Mesh::Mesh(Vertex* vertices, unsigned int numVertices, GLenum usage) 
{ 
    _drawCount = numVertices; 

    glGenVertexArrays(1, &_vertexArrayObject); 

    glBindVertexArray(_vertexArrayObject); 

    std::vector<glm::vec3> positions; 
    std::vector<glm::vec2> texCoords; 

    positions.reserve(numVertices); 
    texCoords.reserve(numVertices); 

    for (unsigned int i = 0; i < numVertices; ++i) 
    { 
     positions.push_back(*vertices[i].Position()); 
     texCoords.push_back(*vertices[i].TexCoord()); 
    } 
    glGenBuffers(NUM_BUFFERS, _vertexArrayBuffers); 


    glBindBuffer(GL_ARRAY_BUFFER, _vertexArrayBuffers[POSITION_VB]); 
    glBufferData(GL_ARRAY_BUFFER, numVertices * sizeof(positions[0]), positions.data(), usage); 

    glEnableVertexAttribArray(0); 
    glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, 0); 


    glBindBuffer(GL_ARRAY_BUFFER, _vertexArrayBuffers[TEXCOORD_VB]); 
    glBufferData(GL_ARRAY_BUFFER, numVertices * sizeof(texCoords[0]), texCoords.data(), usage); 

    glEnableVertexAttribArray(1); 
    glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 0, 0); 


    glBindVertexArray(0); 
} 


Mesh::~Mesh(void) 
{ 
    glDeleteVertexArrays(1, &_vertexArrayObject); 
} 

void Mesh::Draw(GLenum mode) 
{ 
    glBindVertexArray(_vertexArrayObject); 
    glDrawArrays(mode, 0, _drawCount); 
    glBindVertexArray(0); 
} 

Shader.cpp我綁定atributes這樣的:

glBindAttribLocation(_program, 0, "position"); 
glBindAttribLocation(_program, 1, "texCoord"); 

------------------ ---------- EDI Ť--------------------------------- 改變頂點着色後:

#version 330 core 

layout (location = 0) in vec3 position; 
layout (location = 1) in vec2 texCoord; 

out vec2 TexCoord; 

void main() 
{ 
    gl_Position = vec4(position, 1.0f); 
    TexCoord = texCoord; 
} 

和片段着色器到:

#version 330 core 
in vec2 TexCoord; 

out vec4 color; 

uniform sampler2D ourTexture; 

void main() 
{ 
    color = texture(ourTexture, TexCoord); 
} 

紋理映射正確。

但我仍然想知道爲什麼我的第一個解決方案不起作用。

+0

在我看來你的第二個'glVertexAttribPointer'調用缺少位置數據之後的UV數據的偏移量(最後一個參數)。如果我是對的,你就像UV一樣讀取posisiton.xy。 (您可以嘗試在renderdoc中運行此命令以查看頂點着色器中出現的內容,並確認/弱化我的診斷) – Borgleader

+0

@Borgleader我認爲使用多於一個緩衝區的想法是分割數據,然後將它們按部分發送到GPU?或者我錯了,它不工作?因爲那時我不知道我應該設置什麼膠印。 編輯完成後,我會嘗試使用renderdoc,並讓你知道我的結果 –

+0

哦nvm,我錯過了那部分,我看到了你的初始頂點數組,並且錯過了兩個std :: vectors。 (根據[這個答案](http://stackoverflow.com/a/14249893/583833)你的VAO的初始化似乎是正確的) – Borgleader

回答

1

但我仍然想知道爲什麼我的第一個解決方案不起作用。

因爲你使用

#version 330 core 

texture2D過時因爲版本130

着色器編譯器應該已經警告或出錯有關。通過glGetShaderInfoLogglGetProgramInfoLog查看着色器日誌。

+0

其實我用'#version 150',但你仍然是對的。 –