OpenGL着色器没有绘制东西:/

时间:2015-12-27 20:09:48

标签: c++ opengl glsl glfw

好吧,正如在标题中,着色器没有做任何事情,他们应该画一个点,但它没有出现在屏幕上:/。我一直在检查解决方案,但看起来它们不起作用。 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;
}

1 个答案:

答案 0 :(得分:1)

您正在创建顶点阵列

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];
}

在这里阅读顶点数组: https://stackoverflow.com/a/17517103/5729376