2017-01-16 7 views
0

Vorhand, Entschuldigung für eine Menge von geposteten Code. Ich werde versuchen, so einfach wie möglich zu sein.Textur Mapping Ergebnisse in einfarbig von 1 Pixel aus Textur

Meine Textur ist 4x4 Textur Bild im BMP-Format (wenn jemand hier interessiert ist ->4x4 texture image). Und als Ergebnis des Mappings erhalte ich die Farbe des oberen linken Pixels (0.0, 1.0) (ich habe es überprüft, es ist immer die Farbe des oberen linken Pixels) und meine Dreiecksfarbe ergibt die Farbe dieses Pixels, was weiß ist. enter image description here Ich versuchte GL_NEAREST-GL_LINEAR in GL_TEXTURE_MAG_FILTER

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

ändern und i rechte untere Pixel erhalten (1,0, 0,0), die eine Art von grün ist: enter image description here I Textur mit stb_image bin Laden. Also in meinem 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); 
} 

In meinem Vertex-Shader:

#version 150 

in vec3 position; 
in vec2 texCoord; 

out vec2 texCoord0; 

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

In meinem Fragment-Shader:

#version 150 

in vec2 textCoord0; 
uniform sampler2D texture; 

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

In meinem 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; 
} 

In Mesh.cpp i am Aufspalten Vertices Attribute (GLM :: vec3 _position und GLM :: vec2 _texture) in 2 stl Vektoren und unter Verwendung von 2 Puffer ("0" - für die Position des Eckpunkts und „1 "- für Textur):

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

In Shader.cpp i binded atributes wie folgt aus:

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

------------------ ---------- EDI T --------------------------------- Nach Vertex-Shader zu ändernden:

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

Fragment und Shader zu:

#version 330 core 
in vec2 TexCoord; 

out vec4 color; 

uniform sampler2D ourTexture; 

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

Textur ist korrekt zugeordnet.

Aber ich möchte immer noch wissen, warum meine erste Lösung nicht funktioniert.

+0

Es scheint mir, dass Ihr zweiter 'glVertexAttribPointer'-Aufruf einen Offset (den letzten Parameter), den die UV-Daten nach den Positionsdaten haben, nicht enthält. Wenn ich recht habe, liest du die posisiton.xy als UVs. (Sie können versuchen, dies in renderdoc auszuführen, um zu sehen, was aus dem Vertex-Shader kommt und meine Diagnose bestätigt/durchbricht) – Borgleader

+0

@Borgleader Ich dachte, die Idee, mehr als einen Puffer zu verwenden, besteht darin, Daten zu teilen und dann portionsweise an die GPU zu senden. Oder irre ich mich und es funktioniert nicht so? Denn dann weiß ich nicht, welchen Offset ich setzen sollte. Nach Ihrer Bearbeitung werde ich versuchen, renderdoc jetzt zu verwenden und Sie über meine Ergebnisse zu informieren. –

+0

Oh nvm, ich habe diesen Teil verpasst, ich sah Ihre erste Anordnung von Vertices und verpasste die beiden std :: vectors. (Nach [dieser Antwort] (http://stackoverflow.com/a/14249893/583833) scheint die Initialisierung Ihres VAO korrekt) – Borgleader

Antwort

1

Aber ich möchte immer noch wissen, warum meine erste Lösung nicht funktioniert.

Weil du

#version 330 core 

und texture2D verwendet, ist 130

Der Shader-Compiler darüber veraltet haben sollte, da Version gewarnt oder fehlerhaft. Überprüfen Sie Ihre Shader-Protokolle über glGetShaderInfoLog und glGetProgramInfoLog.

+0

Eigentlich habe ich '#version 150' benutzt, aber trotzdem hast du Recht. –