为什么我的GLSL转换没有渲染?

时间:2017-01-25 19:09:09

标签: c++ opengl glsl shader

所以我正在学习OpenGL和GLSL(显然)。我在矩阵变换上遵循了几个关于宗教的教程,但我无法弄清楚为什么正方形没有渲染。我通过反复试验弄清楚我的渲染代码很好,就在我在顶点着色器中进行“转换* vec4(...)”时程序搞砸了。我检查了glGetUniformLocation的返回值,得到的返回值为0,所以它得到了统一的位置。我环顾四周,找不到解决办法。

#include <stdio.h>
#include <memory.h>
#include <stdlib.h>
#define GLEW_STATIC
#include <glew.h>
#include <SDL.h>
#include <math.h>
#include <glm/glm.hpp>
#include <glm/gtc/type_ptr.hpp>
#include <glm/gtc/matrix_transform.hpp>

const GLchar* VertShaderCode = "\
#version 330 core\n\
layout (location = 0) in vec2 position;\n\
uniform mat4 transformation;\n\
void main ()\n\
{\n\
    vec4 lol = transformation * vec4(position.xy, 0, 1);\n\
    gl_Position = lol;\n\
}\n\
";

const GLchar* FragShaderCode = "\
#version 330 core\n\
void main ()\n\
{\n\
    gl_FragColor = vec4(1, 0, 1, 1);\n\
}\n\
";

#define SDL_main main

#define scuffed !SDL_QuitRequested()

int main()
{
    if (SDL_Init(SDL_INIT_EVERYTHING))
    {
        printf("Could not initialize SDL!\n");
        return -4;
    };

    SDL_Window* window = SDL_CreateWindow("Testing Window", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, 420, 420, SDL_WINDOW_OPENGL);
    if (!window)
    {
        printf("Could not create window!\n");
        return -5;
    };

    SDL_GLContext context = SDL_GL_CreateContext(window);
    if (!context)
    {
        printf("Could not create context!\n");
        return -7;
    };

    if (glewInit() != GLEW_OK)
    {
        printf("Could not initialize GLEW!\n");
        return -6;
    };

    GLint err;
    char* log = NULL;

    //printf("Vertex Shader Source: \n%s\n",VertShaderCode);
    GLuint VertShader = glCreateShader(GL_VERTEX_SHADER);
    glShaderSource(VertShader,1,&VertShaderCode,NULL);
    glCompileShader(VertShader);
    glGetShaderiv(VertShader,GL_COMPILE_STATUS,&err);
    if (err == GL_FALSE)
    {
        // Shader didn't compile.
        glGetShaderiv(VertShader, GL_INFO_LOG_LENGTH, &err);
        log = (char*)malloc(err);
        glGetShaderInfoLog(VertShader,err,NULL,log);
        printf("Vertex shader could not be compiled!\n\n%s\n\n",log);
        return -1;
    };

    //printf("Fragment Shader Source: \n%s\n", FragShaderCode);
    GLuint FragShader = glCreateShader(GL_FRAGMENT_SHADER);
    glShaderSource(FragShader, 1, &FragShaderCode, NULL);
    glCompileShader(FragShader);
    glGetShaderiv(FragShader, GL_COMPILE_STATUS, &err);
    if (err == GL_FALSE)
    {
        // Shader didn't compile.
        glGetShaderiv(FragShader, GL_INFO_LOG_LENGTH, &err);
        log = (char*)malloc(err);
        glGetShaderInfoLog(FragShader, err, NULL, log);
        printf("Fragment shader could not be compiled!\n\n%s\n\n", log);
        return -2;
    };

    GLuint Program = glCreateProgram();
    glAttachShader(Program,VertShader);
    glAttachShader(Program,FragShader);
    glLinkProgram(Program);
    glGetProgramiv(Program,GL_LINK_STATUS,&err);
    if (err == GL_FALSE)
    {
        // Program didn't link.
        glGetProgramiv(Program,GL_INFO_LOG_LENGTH,&err);
        log = (char*)malloc(err);
        glGetProgramInfoLog(Program,err,NULL,log);
        printf("Program could not be linked!\n\n%s\n\n",log);
        return -3;
    };

    glUseProgram(Program);

    GLuint vertBuff = 0, arrayBuff = 0, elementBuff = 0;
    glGenVertexArrays(1, &arrayBuff);
    glGenBuffers(1, &vertBuff);
    glGenBuffers(1, &elementBuff);
    glBindVertexArray(arrayBuff);
    glBindBuffer(GL_ARRAY_BUFFER, vertBuff);
    //glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, elementBuff);

    GLfloat vertices[] =
    {
        -0.5,  0.5,
        -0.5, -0.5,
         0.5, -0.5,

         0.5, -0.5,
        -0.5,  0.5,
         0.5,  0.5,
    };
    GLubyte colors[] =
    {
        255,0,0,
        0,255,0,
        0,0,255
    };

    GLuint indicies[] =
    {
        0, 1, 2,
        2, 0, 3,
    };

    glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);

    glEnableVertexAttribArray(0);

    glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 0, NULL);

    glm::mat4 mat = glm::scale(mat, glm::vec3(2, .5, 0));
    glUniformMatrix4fv(glGetUniformLocation(Program, "transformation"), 1, GL_FALSE, glm::value_ptr(mat));

    while (scuffed)
    {
        glClear(GL_COLOR_BUFFER_BIT);

        glDrawArrays(GL_TRIANGLES, 0, 6);

        SDL_GL_SwapWindow(window);
    }

    glDeleteVertexArrays(1, &arrayBuff);
    glDeleteBuffers(1, &vertBuff);
    //glDeleteBuffers(1, &elementBuff);

    SDL_GL_DeleteContext(context);
    SDL_DestroyWindow(window);
    SDL_Quit();

    return 0;
}

1 个答案:

答案 0 :(得分:2)

问题不在于着色器中的代码,而是传递给transformation的数据:

glm::mat4 mat = glm::scale(mat, glm::vec3(2, .5, 0));

glm::scale function将新的缩放功能与您传入的mat相乘。问题是,当您将mat传递给scale时,glm::mat4 mat; mat = glm::scale(mat, glm::vec3(2, .5, 0)); 未初始化只是一些随意的垃圾。你真正想要的是首先初始化矩阵(作为一个单位矩阵,但这是默认行为),然后将其传递给它:

mat

请注意,这两个版本在c ++中并不相同,因为第一个版本在将onsubmit的构造函数传递给函数之前不会调用它。