【问题标题】:OpenGL Shader failed to workOpenGL 着色器无法工作
【发布时间】:2024-01-16 03:56:01
【问题描述】:

我尝试在我的 OpenGL 项目中使用我自己的顶点着色器和片段着色器。 程序本身和着色器程序都已成功编译和链接,但顶点着色器和片段着色器都不起作用。我设法对着色器代码进行了一些更改,但什么也没发生,两个着色器仍然拒绝参与渲染过程。 下面是我的代码:

#include<GL\glew.h>
#include<GL\freeglut.h>
#include<iostream>
#include<fstream>
#include<string>
#include<assert.h>
using namespace std;
static GLuint VBO_handle = 0;
static GLfloat val = 1.5f;
static GLuint Unif_handle = 0;
static GLuint Program_handle = 0;
static GLuint Shader_handle = 0;
static GLuint Shader_handle2 = 0;
void init()
{
    glGenBuffers(1, &VBO_handle);
    glBindBuffer(GL_ARRAY_BUFFER, VBO_handle);
    GLfloat vertices[] = { 0.0f, 0.8f, 0.0f, -0.8f, -0.8f, 0.0f, 0.8f, -0.8f, 0.0f };
    glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
}
void Rendering();
void callback_register()
{
    glutDisplayFunc(Rendering); 
    glutIdleFunc(Rendering);
}
void Rendering()
{
    glClear(GL_COLOR_BUFFER_BIT);
    glUniform1f(Unif_handle, val);
    glEnableVertexAttribArray(0);
    glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, 0);
    glDrawArrays(GL_TRIANGLES, 0, 3);
    glDisableVertexAttribArray(0);
    glutSwapBuffers();
}
void ShaderReading()
{
    Program_handle = glCreateProgram();
    Shader_handle = glCreateShader(GL_VERTEX_SHADER);
    std::fstream fin("vertex.vert", std::ios::in);
    std::string temp;
    while (fin.good())
    {
        string templine;
        getline(fin, templine);
        temp += templine;
        temp.push_back('\n');
    }
    fin.close();
    const GLchar* p[1];
    p[0] = temp.c_str();
    GLint Lengths[1];
    Lengths[0] = temp.size();
    glShaderSource(Shader_handle, 1, p, Lengths);
    glCompileShader(Shader_handle);
    GLint success;
    glGetShaderiv(Shader_handle, GL_COMPILE_STATUS, &success);
    if (!success) {
        GLchar InfoLog[1024];
        glGetShaderInfoLog(Shader_handle, 1024, NULL, InfoLog);
        fprintf(stderr, "Error compiling shader type %d: '%s'\n", GL_VERTEX_SHADER, InfoLog);
        exit(1);
    }
    glAttachShader(Program_handle, Shader_handle);
    GLint Success = 0;
    GLchar ErrorLog[1024] = { 0 };

    Shader_handle2 = glCreateShader(GL_FRAGMENT_SHADER);
    fin.open("fragment.frag", std::ios::in);
    temp.clear();
    while (fin.good())
    {
        string templine;
        getline(fin, templine);
        temp += templine;
        temp.push_back('\n');
    }
    fin.close();
    p[0] = temp.c_str();
    Lengths[0] = temp.size();
    glShaderSource(Shader_handle2, 1, p, Lengths);
    glCompileShader(Shader_handle2);
    glGetShaderiv(Shader_handle2, GL_COMPILE_STATUS, &success);
    if (!success) {
        GLchar InfoLog[1024];
        glGetShaderInfoLog(Shader_handle2, 1024, NULL, InfoLog);
        fprintf(stderr, "Error compiling shader type %d: '%s'\n", GL_VERTEX_SHADER, InfoLog);
        exit(1);
    }
    glAttachShader(Program_handle, Shader_handle2);
    Success = 0;

    glLinkProgram(Program_handle);
    glGetProgramiv(Program_handle, GL_LINK_STATUS, &Success);
    if (Success == 0) {
        glGetProgramInfoLog(Program_handle, sizeof(ErrorLog), NULL, ErrorLog);
        fprintf(stderr, "Error linking shader program: '%s'\n", ErrorLog);
        exit(1);
    }

    glValidateProgram(Program_handle);
    glGetProgramiv(Program_handle, GL_VALIDATE_STATUS, &Success);
    if (!Success) {
        glGetProgramInfoLog(Program_handle, sizeof(ErrorLog), NULL, ErrorLog);
        fprintf(stderr, "Invalid shader program: '%s'\n", ErrorLog);
        exit(1);
    }

    glUseProgram(Shader_handle);
}
int main(int argc, char** argv)
{
    glutInit(&argc, argv);
    glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE);
    glutInitWindowSize(600, 600);
    glutInitWindowPosition(100, 100);
    glutCreateWindow("6666");
    callback_register();
    GLenum res = glewInit();
    if (res != GLEW_OK) {
        fprintf(stderr, "Error: '%s'\n", glewGetErrorString(res));
        return 1;
    }
    glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
    init();
    ShaderReading();
    glutMainLoop();
    return 0;
}

这是下面的着色器程序,确实非常简单:( 顶点着色器:

#version 330

layout (location = 0) in vec3 Position;

uniform float gScale;

void main()
{
    gl_Position = vec4(gScale*Position.x, Position.y, Position.z, 1.0);
}

片段着色器: #版本 330

out vec4 FragColor;

void main()
{
    FragColor = vec4(1.0, 0.0, 0.0, 1.0);
}

【问题讨论】:

  • 请同时发布着色器。
  • 着色器现已发布。
  • 他们什么“不起作用”?
  • 您的代码从不查询gScale 值的位置。有可能保持默认值 0。
  • 嗯,事实上我只是想让我的第一个着色器工作,你可以看到我想要的输出应该是一个红色三角形,gScale 改变了它的顶点坐标。但实际上我只得到了一个白色三角形,所有 3 个顶点都未触及。它们的坐标与顶点缓冲区中的坐标相同。无论我如何尝试更改着色器代码,输出仍然相同。顶点着色器和片段着色器都不起作用。

标签: c++ opengl fragment-shader vertex-shader


【解决方案1】:

你这里有一些小错误:

glUseProgram(Shader_handle);

这实际上应该是 Program_handle。上面的代码应该只是产生一些 GL 错误并且没有效果。由于您处于兼容性/旧版配置文件中,因此您将使用固定功能管道进行绘制,并且属性 0 将为顶点位置设置别名。默认颜色为白色,这就是您看到白色三角形的原因。

正如我在 cmets 中已经指出的那样,您也永远不会查询制服的位置并假设它为零。由于您只使用一种制服,这有点可能 - 但是,GL 规范根本无法保证。您还应该添加它。

【讨论】:

  • 这个解决方案很受欢迎!我确实错误地将着色器句柄传递给了程序。
最近更新 更多