【问题标题】:Why is my GLSL transformation not rendering?为什么我的 GLSL 转换不呈现?
【发布时间】:2026-02-08 07:20:02
【问题描述】:

所以我正在学习 OpenGL 和 GLSL(显然)。我已经认真地学习了几个关于矩阵变换的教程,但我不知道为什么正方形没有渲染。我通过反复试验发现我的渲染代码很好,只是当我在顶点着色器中执行“transformation * 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;
}

【问题讨论】:

    标签: c++ opengl glsl shader


    【解决方案1】:

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

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

    glm::scale function 将一个新的缩放函数与您传入的 mat 相乘。问题是,当您将 mat 传递给 scale 时,它没有被初始化,并且只包含一些随机垃圾。您真正想要的是首先初始化矩阵(作为单位矩阵,但这是默认行为),然后将其传递给 scale:

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

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

    【讨论】:

    • 谢谢。我测试了它,这似乎有效。我回去查看教程,它说当其他人没有时就这样做。猜猜有些人不检查他们的代码是否有效并且不如他们声称的那么好。谢谢!
    最近更新 更多