2017-08-17 13 views
5

Ich versuche OpenGL (C++) zu verwenden, um zwei Texturen auf einem Rechteck zu rendern. Ich habe ein paar Probleme, die beiden zu vermischen.OpenGL Blending erstellt weißen Rahmen um Texturen

Das erste Bild stammt aus einer JPG-Datei (https://learnopengl.com/img/textures/container.jpg). Dieses Bild hat keinen Alpha-Kanal.

Das zweite Bild stammt aus einer .png-Datei (https://learnopengl.com/img/textures/awesomeface.png) und hat einen Alpha-Kanal.

Das Problem ist, wenn ich versuche, die beiden Bilder zu mischen, erstellt es einen weißen Rahmen um das transparente Bild.

Ich habe ein paar verschiedene Mischmodi ausprobiert (wie vom OP in dieser Frage empfohlen: Alpha blending with multiple textures leaves colored border), aber keiner von ihnen scheint zu funktionieren.

Mein Fragment-Shader sieht wie folgt aus:

#version 330 core 
out vec4 FragColor; 

in vec3 ourColor; 
in vec2 TexCoord; 

// texture samplers 
uniform sampler2D texture1; 
uniform sampler2D texture2; 

void main() 
{ 
    // linearly interpolate between both textures 
    FragColor = mix(texture(texture1, TexCoord), texture(texture2, TexCoord), 0.5); 
} 

Ich habe eine gründlichere Prüfung aktiviert ist (scheint keine Wirkung zu haben) und ich bin mit dem folgenden Code für meine Mischung einrichten:

glEnable(GL_DEPTH_TEST); 
glEnable(GL_BLEND); 
glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA); 

Das ist mein Haupt machen Schleife:

Rendering::Pipeline pipeline = Rendering::Pipeline("src/GLSL/vertex.glsl", "src/GLSL/fragment.glsl"); 
pipeline.load(); 

//      Position,    Color,     Texture Coord. 
//      (X Y Z)     (R G B)     (S T) 
float vertices [32] = { 0.5f, 0.5f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, // top right 
         0.5f, -0.5f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f, // bottom right 
         -0.5f, -0.5f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, // bottom left 
         -0.5f, 0.5f, 0.0f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f };// top left 

unsigned int vertexIndices [6] = { 3, 2, 0, 
            2, 1, 0 }; 


unsigned int vbo; 
unsigned int vao; 
unsigned int ebo; 

glGenVertexArrays(1, &vao); 
glGenBuffers(1, &vbo); 
glGenBuffers(1, &ebo); 

glBindVertexArray(vao); 

glBindBuffer(GL_ARRAY_BUFFER, vbo); 
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW); 

glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ebo); 
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(vertexIndices), vertexIndices, GL_STATIC_DRAW); 

glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 8 * sizeof(float), (void*) 0); 
glEnableVertexAttribArray(0); 

glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 8 * sizeof(float), (void*) (3 * sizeof(float))); 
glEnableVertexAttribArray(1); 

glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, 8 * sizeof(float), (void*) (6 * sizeof(float))); 
glEnableVertexAttribArray(2); 

unsigned int texture1; 
unsigned int texture2; 
int width; 
int height; 
int numChannels; 
unsigned char* data; 

glGenTextures(1, &texture1); 
glBindTexture(GL_TEXTURE_2D, texture1); 

glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); 
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); 

glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); 
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); 

data = stbi_load("res/jpg/container.jpg", &width, &height, &numChannels, STBI_rgb); 

if (data) 
{ 
    lTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, data); 
    glGenerateMipmap(GL_TEXTURE_2D); 
} 

stbi_image_free(data); 

glGenTextures(1, &texture2); 
glBindTexture(GL_TEXTURE_2D, texture2); 

glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); 
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); 

glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); 
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); 

stbi_set_flip_vertically_on_load(true); 

data = stbi_load("res/png/awesomeface.png", &width, &height, &numChannels, STBI_rgb_alpha); 

if (data) 
{ 
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, data); 
    glGenerateMipmap(GL_TEXTURE_2D); 
} 

stbi_image_free(data); 

glUseProgram(pipeline.getProgramId()); 
glUniform1i(glGetUniformLocation(pipeline.getProgramId(), "texture1"), 0); 
glUniform1i(glGetUniformLocation(pipeline.getProgramId(), "texture2"), 1); 

while (!this->mQuit) 
{ 
    this->counter.start(); 

    InputProcessor::getInstance().processInputs(); 

    if (this->debugOverlay) 
    { 
     glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); 
    } 
    else 
    { 
     glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); 
    } 

    glClearColor(0.2f, 0.3f, 0.3f, 1.0f); 
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); 

    glActiveTexture(GL_TEXTURE0); 
    glBindTexture(GL_TEXTURE_2D, texture1); 

    glActiveTexture(GL_TEXTURE1); 
    glBindTexture(GL_TEXTURE_2D, texture2); 

    pipeline.use(); 
    glBindVertexArray(vao); 
    glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0); 

    SDL_GL_SwapWindow(this->sdlWindow); 

    this->counter.stop(); 
    this->deltaTime = this->counter.getDelta(); 
} 

    this->quit(); 

Die Frage ist am einfachsten zu beobachten, wenn übergibt 0,5 als Parameter an die Funktion mix() im Fragment-Shader. Bei Verwendung von 0.0 oder 1.0 bekomme ich (wie erwartet) nur eine der Texturen.

Antwort

3

Das Problem könnte mit der Textur selbst sein. Wenn Sie die semitransparente Textur bei Pixeln untersuchen, die von Alpha Near Border gelöscht wurden, welche RGB-Werte sind dann? Einige Editoren (zutiefst Photoshop) füllen den transparenten Bereich mit weißer Farbe (oder mit Standardfarbe), was dazu führen kann, dass diese während des Überblendens eingerahmt werden.

Antialise oder Interpolation würde dazu führen, dass Weiß in den sichtbaren Bereich kriecht.

Ich habe dieses Problem aus der Sicht der Softwareentwickler nicht behandelt, sondern wurde von ihm mehr als einmal als Inhaltsentwickler behandelt (es ist die Geißel eines Novizen in SecondLife zum Beispiel).

+1

Vielen Dank! Das war die Lösung, ich öffnete meine transparente Textur in GIMP und exportierte sie, ohne die Option "Hintergrundfarbe speichern" zu aktivieren, danach wurde die Textur so gemischt, wie sie sollte! – shmoo6000