Фрагментный шейдер OpenGL, рисующий только белый треугольник. Как это исправить? - PullRequest
0 голосов
/ 08 апреля 2020

Мой шейдер OpenGL Game Engine Fragment показывает только белый цвет, я попробовал все, но не смог найти решение Пожалуйста, помогите мне решить эту проблему, Вот код:

Треугольник. cpp

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

#include "Triangle.h"

const char* TriangleVS = "#version 400\n"
"layout(location = 0) in vec3 Pos;"
"void main()"
"{"
"   gl_Position.xyz = Pos;"
"   gl_Position.w = 1.0;"
"}";

const char* TriangleFS = "#version 400\n"
"out vec4 Color;"
"void main()"
"{"
"   Color = vec4(0.0f, 1.0f, 0.0f, 1.0f);"
"   "
"}";

void Shapes::B_Triangle()
{
    GLuint Program = Shader::B_Shader(TriangleVS, TriangleFS);

    glEnable(GL_DEPTH_TEST);
    glDepthFunc(GL_LESS);

    glMatrixMode(GL_PROJECTION);
    glMatrixMode(GL_MODELVIEW);

    glEnable(GL_CULL_FACE);
    glCullFace(GL_CCW);

    glEnable(GL_BLEND);
    glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
    glBlendEquation(GL_FUNC_ADD);

    glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);

    float TriangleVers[] = {
        -0.5f, -0.5f, 0.0f,
         0.5f, -0.5f, 0.0f,
         0.0f,  0.5f, 0.0f
    };

    unsigned int VAO, VBO;

    glGenVertexArrays(1, &VAO);
    glBindVertexArray(VAO);

    glGenBuffers(1, &VBO);
    glBindBuffer(GL_ARRAY_BUFFER, VBO);
    glBufferData(GL_ARRAY_BUFFER, sizeof(TriangleVers), TriangleVers, GL_STATIC_DRAW);

    //Pos
    glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 12, (void*)0);
    glEnableVertexAttribArray(0);

    glUseProgram(Program);
    glBindVertexArray(VAO);
    glDrawArrays(GL_TRIANGLES, 0, 3);

    //Free Up The Memory
    glDeleteVertexArrays(1, &VAO);
    glDeleteBuffers(1, &VBO);
    glDeleteProgram(Program);
}

Шейдер. cpp

Я не вижу здесь ничего плохого, но на всякий случай просто кидаю.

#include "Shader_Program.h"

unsigned int VS;
unsigned int FS;
unsigned int B_ShaderProgram;
//Error Handler
int Working;
GLchar Lines[512];

bool Shader::B_Shader(const GLchar* Vertex, const GLchar* Fragment)
{
    //Vertex Shader
    VS = glCreateShader(GL_VERTEX_SHADER);
    glShaderSource(VS, 1, &Vertex, NULL); 
    glCompileShader(VS);
    glGetShaderiv(VS, GL_COMPILE_STATUS, &Working);
    if (!Working)
    {
        glGetShaderInfoLog(VS, 512, NULL, Lines);
        Log::B_ErrorGLInfoLog("OpenGL Shader 'VS' Error: ", Lines);
        glDeleteShader(VS);

        return 1;
    }

    //Fragment Shader
    FS = glCreateShader(GL_FRAGMENT_SHADER);
    glShaderSource(FS, 1, &Fragment, NULL);
    glCompileShader(FS);
    glGetShaderiv(FS, GL_COMPILE_STATUS, &Working);
    if (!Working)
    {
        glGetShaderInfoLog(FS, 512, NULL, Lines);
        Log::B_ErrorGLInfoLog("OpenGL Shader 'FS' Error: ", Lines);
        glDeleteShader(FS);

        return 1;
    }

    //Shader Program
    B_ShaderProgram = glCreateProgram();
    glAttachShader(B_ShaderProgram, FS);
    glAttachShader(B_ShaderProgram, VS);
    glLinkProgram(B_ShaderProgram);
    glValidateProgram(B_ShaderProgram);
    glGetProgramiv(B_ShaderProgram, GL_LINK_STATUS, &Working);
    if (!Working)
    {
        glGetProgramInfoLog(B_ShaderProgram, 512, NULL, Lines);
        Log::B_ErrorGLInfoLog("OpenGL B_ShaderProgram Error: ", Lines);
        glDeleteProgram(B_ShaderProgram);

        return 1;
    }

    //Free Up The Memory
    glDeleteShader(VS);
    glDeleteShader(FS);
    glDeleteProgram(B_ShaderProgram);

    return 0;
}

1 Ответ

0 голосов
/ 08 апреля 2020

Есть две проблемы:

  1. Ваш Shader::B_Shader возвращает bool, но при вызове вы ожидаете, что он вернет программу:

    GLuint Program = Shader::B_Shader(TriangleVS, TriangleFS);
    
  2. Ваш Shader::B_shader удаляет только что созданную программу:

    glDeleteProgram(B_ShaderProgram);
    

Неудивительно, что это не работает. Измените Shader::B_shader, чтобы вернуть B_ShaderProgram как GLuint и , не удаляйте его перед использованием:

// VVVVV return GLuint instead of bool
GLuint Shader::B_Shader(const GLchar* Vertex, const GLchar* Fragment) {
    ...
    if (!Working){
        ...
        return 0; // return zero to indicate an error
    }

    //Free Up The Memory
    glDeleteShader(VS);
    glDeleteShader(FS);
    // ---- DON'T delete the program ----
    return B_ShaderProgram; // <----- return the compiled program
}

В Shapes::B_Triangle() нет ничего плохого само по себе, но вы должны рассмотреть возможность кэширования скомпилированной программы, а не компилировать и удалять ее каждый раз, когда вы рисуете треугольник.

...