OpenGL 着色器不绘制任何东西:/

OpenGL shaders not drawing a thing :/

好吧,正如标题中的那样,着色器没有做他们应该画一个点的事情,但它没有出现在屏幕上:/。我一直在检查解决方案,但似乎它们不起作用。 glfw 和 glew 也正在初始化,并且出现了红色。

#include <GL/glew.h>
#define GLFW_DLL
#include <GLFW/glfw3.h> 
#include <stdio.h>
#include <iostream> 
#include "jelly/lua_manager.h"
#include "jelly/keysManager.h"

jelly::keys_buttons::KeysManager km; 

GLuint vertex_array_obj;
GLuint program;

GLuint startRender(GLFWwindow* window)
{
    GLuint vertexShader = glCreateShader(GL_VERTEX_SHADER);
    GLuint fragmentShader = glCreateShader(GL_FRAGMENT_SHADER);

    std::cout << "ASD" << std::endl;

    static const GLchar * vertexShader_src[] =
    {
        "#version 430 core                                                      \n"
        "                                                                       \n"
        "void main(void)                                                        \n"
        "{                                                                      \n"
        "   gl_Position = vec4(0, 0.5, 0.0, 1);                                 \n"
        "}                                                                      \n"
    };

    static const GLchar * fragmentShader_src[] =
    {
        "#version 430 core                          \n"
        "                                           \n"
        "out vec4 color;                            \n"
        "                                           \n"
        "void main(void)                            \n"
        "{                                          \n"
        "   color = vec4(0.0, 0.8, 1.0, 1.0);       \n"
        "}                                          \n"
    };

    glShaderSource(vertexShader, 1, vertexShader_src, NULL);
    glCompileShader(vertexShader);

    glShaderSource(fragmentShader, 1, fragmentShader_src, NULL);
    glCompileShader(fragmentShader);

    GLuint tprogram = glCreateProgram();
    glAttachShader(tprogram, vertexShader);
    glAttachShader(tprogram, fragmentShader);
    glLinkProgram(tprogram);
    glValidateProgram(tprogram);

    glDeleteShader(vertexShader);
    glDeleteShader(fragmentShader);

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

    return tprogram;
}

void render(GLFWwindow* window)
{
    glClearColor(1.0f, 0.0f, 0.0f, 0.0f);
    glClear(GL_COLOR_BUFFER_BIT);
    glDrawArrays(GL_POINTS, 0, 1);
}

void mouseCallback(GLFWwindow* window, int button, int action, int mods)
{
    km.mouseClick(button, action, mods);
}

void keyCallback(GLFWwindow* window, int key, int scancode, int action, int mods)
{
    km.keyPressed(key, action, mods);
}

int main()
{
    jelly::lua::LuaManager lm;

    // 0 = Build | 1 = Release | 2 = Alpha | 3 = Beta
    int buildType = 0;

    std::string title = "Relieved";

    if (buildType != 1)
    {
        switch (buildType) {
            case 0 :
                title += " | Build Version";
            break;
            case 2 :
                title += " | Alpha Version";
            break;
            case 3 :
                title += " | Beta Version";
            break;
            default :
            break;
        }
    }

    GLFWwindow* window;

    if (!glfwInit()) {
        glfwTerminate();
        return -1;
    }

    window = glfwCreateWindow(640, 400, title.c_str(), NULL, NULL);

    if (!window) {
        glfwTerminate();  
        return -1;
    }

    glfwMakeContextCurrent(window);

    glewExperimental = GL_TRUE;
    GLenum err = glewInit();
    if (GLEW_OK != err)
    {
      fprintf(stderr, "Error: %s\n", glewGetErrorString(err));  
    }

    glLoadIdentity();

    program = startRender(window);
    glUseProgram(program);

    glfwSetKeyCallback(window, keyCallback);
    glfwSetMouseButtonCallback(window, mouseCallback);

    while(!glfwWindowShouldClose(window))
    {
        render(window);
        glfwSwapBuffers(window);
        glfwPollEvents();
    }

    glDeleteVertexArrays(1, &vertex_array_obj);
    glDeleteProgram(program);
    glDeleteVertexArrays(1, &vertex_array_obj);

    glfwTerminate();    

    return 0;
}

您正在创建顶点数组

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

但是里面没有数据。您需要添加一些数据以便触发着色器(即使该值在顶点着色器中被硬编码,就像您的情况一样)

因此,像这样向顶点数组添加一些顶点:

std::vector<float> v({0.0f,0.0f,0.0f}); 

GLuint buffer;
glGenBuffers(1, &buffer);
glBindBuffer(GL_ARRAY_BUFFER, buffer);
glBufferData(GL_ARRAY_BUFFER, v.size() *sizeof(float), &v[0], GL_STATIC_DRAW); //v is a std::vector<float>, it size is the size of the data (buffer), and &v[0] gives the pointer of the data

glEnableVertexAttribArray(0);       //layout 0. In this example, position
glBindBuffer(GL_ARRAY_BUFFER, buffer);
glVertexAttribPointer(
0,                  // layout in shader
3,                  // number of elements
GL_FLOAT,           // type
GL_FALSE,           // normalized?
0,                  
reinterpret_cast<void*>(0)
);

发送数据的一个好方法是将所有内容打包在一个 std::vector 中,然后只安排布局

GLuint buffer;
glGenBuffers(1, &buffer);
glBindBuffer(GL_ARRAY_BUFFER, buffer);
glBufferData(GL_ARRAY_BUFFER, v.size() *sizeof(float), &v[0], GL_STATIC_DRAW); //v is a std::vector<float>, it size is the size of the data (buffer), and &v[0] gives the pointer of the data

const int s[] = { 3, 3, 2 };        //size of data, in my case 3 floats for position, 3 for normals and 2 for texture coordinates
size_t accum = 0;
for (int z = 0; z < 3; ++z){
glEnableVertexAttribArray(z);
glBindBuffer(GL_ARRAY_BUFFER, buffer);
glVertexAttribPointer(
z,                  // layout in shader
s[z],                  // number of elements
GL_FLOAT,           // type
GL_FALSE,           // normalized?
8 * sizeof(float),                  // stride (3+3+2)
reinterpret_cast<void*>(accum*sizeof(float))    //shift from the previous data [3,3,2]
);
accum += s[z];
}

在此处阅读有关顶点数组的信息: