c++ - 无法获得简单的 2D 着色器以在 C++ openGL 中绘制红色三角形(无编译器错误)

标签 c++ opengl glsl shader

我使用了 openGL、GLEW 和 GLFW3。在 openGl 3.0 mesa 中,使用了默认着色器并绘制了一个白色三角形。在 4.2 中,屏幕保持黑色。没有生成错误消息。

该问题不是由于将片段着色器错误标记为顶点着色器,反之亦然。

该程序包含3个功能:

(1) compileShader,它应该将着色器类型和源代码作为 std::string 并返回带有编译代码的着色器 ID。

(2) createProgram,获取顶点着色器和片段着色器的源代码,并返回编译和附加着色器的程序ID。

(3) 和 main,其中两个着色器源代码都定义为字符串。

对不起,谢谢。

#include <GL/glew.h>
#include <GLFW/glfw3.h>

#include <iostream>
#include <string>

static unsigned int compileShader(unsigned int type, std::string const& sourceCode){
    unsigned int shaderId = glCreateShader(type);
    const char* source = sourceCode.c_str();
    glShaderSource(shaderId, 1, &source, nullptr);
    glCompileShader(shaderId);

    int result;
    glGetShaderiv(shaderId, GL_COMPILE_STATUS, &result);
    if (result == GL_FALSE){

        if (type == GL_FRAGMENT_SHADER) std::cout<<"Fragment\n";
        else std::cout<<"Vertex";
        std::cout<<"SHADER COMPILATION FAILED!"<<std::endl;
        int logLength;
        glGetShaderiv(shaderId, GL_INFO_LOG_LENGTH, &logLength);
        char* infoLog = new char[logLength];
        glGetShaderInfoLog(shaderId, logLength, NULL, infoLog);
        std::cout<<infoLog<<std::endl;
        delete[] infoLog;

        glDeleteShader(shaderId);
        return 0;
    }

    return shaderId;
}

static unsigned int createProgram(std::string const& vertexCode, std::string const& fragmentCode){
    unsigned int vsId = compileShader(GL_VERTEX_SHADER, vertexCode);
    unsigned int fsId = compileShader(GL_FRAGMENT_SHADER, fragmentCode);

    unsigned int programId = glCreateProgram();
    glAttachShader(programId, vsId);
    glAttachShader(programId, fsId);
    glLinkProgram(programId);
    glValidateProgram(programId);

    glDeleteShader(vsId);
    glDeleteShader(fsId);
    return programId;
}

int main()
{

    GLFWwindow* window;

    if (!glfwInit())
    {
        std::cout<<"GLFW initialization failed";
        return -1;
    }

    ///switches to opengl 4.2!
    glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 4);
    glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 2);
    glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);

    /* Create a windowed mode window and its OpenGL context */
    window = glfwCreateWindow(640, 480, "Hello World", NULL, NULL);
    if (!window)
    {
        glfwTerminate();
        return -1;
    }

    /* Make the window's context current */
    glfwMakeContextCurrent(window);
    glewInit();

    std::cout << "OpenGL " << glGetString(GL_VERSION) << "\n" << std::endl;
    float positions[6] = {
        0.5f, 0.5f,
        -0.5f, 0.5f,
        0.0f, 0.0f
    };

    unsigned int buffer = 1;
    glGenBuffers(1, &buffer);
    glBindBuffer(GL_ARRAY_BUFFER, buffer);
    glBufferData(GL_ARRAY_BUFFER, 6 * sizeof(float), positions, GL_STATIC_DRAW);

    glEnableVertexAttribArray(0);                                        //enables the xy attrib of position
    glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 2*sizeof(float), 0); //specifies layout of xy attrib

    std::string vertexSource =   R"(
#version 330 core
layout(location=0) in vec4 position;

void main(){
    gl_Position = position;
}
)";
    std::string fragmentSource = R"(
#version 330 core

layout(location=0) out vec4 color;

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

    unsigned int programId = createProgram(vertexSource, fragmentSource);
    glUseProgram(programId);

    /* Loop until the user closes the window */
    while (!glfwWindowShouldClose(window))
    {
        /* Render here */
        glClear(GL_COLOR_BUFFER_BIT);

        glDrawArrays(GL_TRIANGLES, 0, 3);

        /* Swap front and back buffers */
        glfwSwapBuffers(window);

        /* Poll for and process events */
        glfwPollEvents();
    }

    glfwTerminate();
    return 0;
}

最佳答案

问题不在于着色器程序,而是您使用的是核心配置文件 OpenGL Context (GLFW_OPENGL_CORE_PROFILE)。因此,您必须创建一个名为 Vertex Array Object .默认 VAO (0) 在核心配置文件上下文中无效。

通过 glGenVertexArrays 生成顶点数组对象名并通过 glBindVertexArray 创建和绑定(bind)对象:

unsigned int vao;
glGenVertexArrays(1, &vao);
glBindVertexArray(vao);

unsigned int buffer;
glGenBuffers(1, &buffer);
glBindBuffer(GL_ARRAY_BUFFER, buffer);
glBufferData(GL_ARRAY_BUFFER, 6 * sizeof(float), positions, GL_STATIC_DRAW);

glEnableVertexAttribArray(0);                                        //enables the xy attrib of position
glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 2*sizeof(float), 0); //specifies layout of xy attrib

关于c++ - 无法获得简单的 2D 着色器以在 C++ openGL 中绘制红色三角形(无编译器错误),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61442520/

相关文章:

c++ - OpenGL 库

c++ - 在 OpenGL 中绘制有限 segmentation 的贝塞尔曲线

c++ - 使用几何着色器创建新的图元类型

performance - 函数调用与内联之间的 GLSL 性能差异

c++ - vector 或 map ,使用哪一个?

c++ - std::move 如何使原始变量的值无效?

c++ - OpenGL 主循环绘制巨大的点 vector

c++ - GLM 如何处理翻译

c++ - 创建一个开箱即用的可移植、跨平台、开源 C++ GUI 应用程序?

c++ - 将 vector 迭代器存储在另一个 vector 中