Прозрачные детали OpenGL становятся чёрными - PullRequest
2 голосов
/ 15 октября 2019

Я тоже хочу визуализировать текстуру с прозрачными частями на моем экране с помощью OpenGL, но прозрачные части почему-то кажутся черными.

Текстура:

Снимок экрана:

Код:

#define STB_IMAGE_IMPLEMENTATION
#include <stdio.h>
#include "stdlib.h"
#include "GLFW/glfw3.h"
#include "GL/gl.h"
#include "stb_image.h"

int windowheight;
int windowwidth;

void camera();
void program();

void rendertex(int x, int y, int w, int h)
{
    glColor4d(255,255,255,255);
    glDisable(GL_COLOR_MATERIAL);
    glEnable(GL_TEXTURE_2D);
    glShadeModel(GL_SMOOTH);
    int width,height,channel;
    auto *data = stbi_load("../textures/isaac.png",&width,&height,&channel,0);
    GLuint texture;
    glGenTextures(1,&texture);
    glBindTexture(GL_TEXTURE_2D,texture);;
    glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
    glTexImage2D(GL_TEXTURE_2D,0,GL_RGBA, width,height,0,GL_RGBA,GL_UNSIGNED_BYTE,data);

    stbi_image_free(data);

    printf("%d\n",width);
    printf("%d\n",height);
    printf("%d\n",channel);

    glBegin(GL_QUADS);
    glTexCoord2d(0,0);
    glVertex2d(x,y);
    glTexCoord2d(0,1);
    glVertex2d(x,y + h);
    glTexCoord2d(1,1);
    glVertex2d(x + w, y + h);
    glTexCoord2d(1,0);
    glVertex2d(x + w, y);
    glEnd();

    glDisable(GL_TEXTURE_2D);
}
static void key(GLFWwindow* window, int key, int scancode, int action, int mods)
{
    switch (key)
    {
        case GLFW_KEY_ESCAPE:
            exit(0);
        case GLFW_KEY_UP:
            break;
    }
}

int main()
{
    glfwInit();
    GLFWwindow* window = glfwCreateWindow(800,800,"t", nullptr, nullptr);
    glfwMakeContextCurrent(window);
    glfwSetKeyCallback(window,key);
    glfwSwapInterval(1);
    glfwGetFramebufferSize(window,&windowwidth,&windowheight);
    glfwWindowHint(GLFW_RESIZABLE, GL_FALSE);

    while (!glfwWindowShouldClose(window))
    {
        glfwSwapBuffers(window);
        glfwGetFramebufferSize(window,&windowwidth,&windowheight);
        program();
        camera();
        glfwPollEvents();
    }
}

void program()
{
    glClearColor(255,255,255,255);
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    glBegin(GL_LINES);
    glColor4d(255,0,0,0);
    glVertex2d(0,0);
    glVertex2d(windowwidth,windowheight);
    glEnd();
    glFlush();


    rendertex(20,20,400,500);
}

void camera()
{
    glViewport(0,0,windowwidth,windowheight);
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    glOrtho(0,windowwidth,windowheight,0,0,1);
    glMatrixMode(GL_MODELVIEW);
}

Я уже пытался комментировать некоторые строкивне, но не повезло. Я использую Linux, если это имеет значение

РЕДАКТИРОВАТЬ: cmakelist.txt

cmake_minimum_required(VERSION 3.15)
project(t)

set(CMAKE_CXX_STANDARD 17)

add_executable(t main.cpp)

target_link_libraries(t GL glfw)

1 Ответ

2 голосов
/ 15 октября 2019

Вы должны включить Смешивание . При смешивании цвет фрагмента смешивается с текущим цветом кадрового буфера, прежде чем он будет записан в кадровый буфер.
Способ смешивания цветов зависит от формулы, которую можно настроить.

Включитьсмешивая и укажите, что цвета смешиваются в зависимости от цветового канала цвета фрагмента:

glEnable(GL_BLEND); 
glBlendEquation(GL_FUNC_ADD); // this is default
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);  

Обратите внимание на приведенные выше виды кода для следующей функции смешивания (D означает цвет кадрового буфера и C фрагментцвет):

D_rgba = C_rgba * C_alpha - D_rgba * (1 - C_alpha)

См. также LearnOpenGL - Смешивание .


Включить смешивание перед рендерингом текстуры и отключить его после:

void rendertex(int x, int y, int w, int h)
{
    // [...]


    glEnable(GL_BLEND); 
    glBlendEquation(GL_FUNC_ADD); // this is default
    glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
    glEnable(GL_TEXTURE_2D);

    glBegin(GL_QUADS);
    glTexCoord2d(0,0);
    glVertex2d(x,y);
    glTexCoord2d(0,1);
    glVertex2d(x,y + h);
    glTexCoord2d(1,1);
    glVertex2d(x + w, y + h);
    glTexCoord2d(1,0);
    glVertex2d(x + w, y);
    glEnd();

    glDisable(GL_TEXTURE_2D);
}
...