C++ 由glUniformMatrix4fv创建时,统一mat4具有未知值

C++ 由glUniformMatrix4fv创建时,统一mat4具有未知值,c++,opengl,glsl,shader,glm-math,C++,Opengl,Glsl,Shader,Glm Math,我有一个基于OpenGL的非常基本的引擎,可以将任何颜色的多边形渲染到可调整大小的窗口。我现在正试图通过我的着色器将模型、透视图和视图矩阵作为统一体来实现着色器的矩阵。在添加制服之前,一切正常,我甚至可以在鼠标位置通过制服vec2来模拟光源。统一的mat4s不如vec2s工作 出于调试的目的,我只渲染了屏幕中央的一个黄色正方形。当不穿制服时,正方形如预期所示。我现在尝试传入一个设置为身份矩阵的mat4。在顶点着色器中,我将gl\u位置乘以我统一的单位矩阵。当我运行程序时,它只显示一个黑色窗口 我

我有一个基于OpenGL的非常基本的引擎,可以将任何颜色的多边形渲染到可调整大小的窗口。我现在正试图通过我的着色器将模型、透视图和视图矩阵作为统一体来实现着色器的矩阵。在添加制服之前,一切正常,我甚至可以在鼠标位置通过制服
vec2
来模拟光源。统一的
mat4
s不如
vec2
s工作

出于调试的目的,我只渲染了屏幕中央的一个黄色正方形。当不穿制服时,正方形如预期所示。我现在尝试传入一个设置为身份矩阵的
mat4
。在顶点着色器中,我将
gl\u位置
乘以我统一的单位矩阵。当我运行程序时,它只显示一个黑色窗口

我已经尝试在顶点着色器中手动创建一个单位矩阵,并将
gl\u Position
乘以该矩阵,而不是统一的矩阵。当我这样做时,我的黄色方块显示正常。这让我相信统一的
mat4
没有得到正确的值,但是,我不知道在着色器中使用矩阵时如何检查矩阵的值

这是我的顶点着色器的外观:

#version 430 core

layout (location = 0) in vec3 position;
layout (location = 1) in vec4 color;

out vec4 Color;

uniform mat4 model;
uniform mat4 view;
uniform mat4 project;

void main()
{
    mat4 id;
    id[0] = vec4(1.0, 0.0, 0.0, 0.0);
    id[1] = vec4(0.0, 1.0, 0.0, 0.0);
    id[2] = vec4(0.0, 0.0, 1.0, 0.0);
    id[3] = vec4(0.0, 0.0, 0.0, 1.0);
    Color = color;
    gl_Position = id * vec4(position, 1.0);
}
#version 430 core

in vec4 Color;

out vec4 outColor;

void main()
{
    outColor = Color;
}
mat4 id
是手动创建的标识矩阵,当将
id*
更改为
model*
时,我会看到黑色窗口

这是我的片段着色器的外观:

#version 430 core

layout (location = 0) in vec3 position;
layout (location = 1) in vec4 color;

out vec4 Color;

uniform mat4 model;
uniform mat4 view;
uniform mat4 project;

void main()
{
    mat4 id;
    id[0] = vec4(1.0, 0.0, 0.0, 0.0);
    id[1] = vec4(0.0, 1.0, 0.0, 0.0);
    id[2] = vec4(0.0, 0.0, 1.0, 0.0);
    id[3] = vec4(0.0, 0.0, 0.0, 1.0);
    Color = color;
    gl_Position = id * vec4(position, 1.0);
}
#version 430 core

in vec4 Color;

out vec4 outColor;

void main()
{
    outColor = Color;
}
着色器由以下代码初始化:

m_shaderID = glCreateProgram();

const char* vertexSource = ReadFile::readFile(vertpath);
const char* fragmentSource = ReadFile::readFile(fragpath);

GLint status;

// Vertex Shader
GLuint vertexShader = glCreateShader(GL_VERTEX_SHADER);
glShaderSource(vertexShader, 1, &vertexSource, NULL);
glCompileShader(vertexShader);
glGetShaderiv(vertexShader, GL_COMPILE_STATUS, &status);
if (status != GL_TRUE)
{
    std::cout << "Failed to compile vertex shader!\nInfo log: " << std::endl;
    char buffer[512];
    glGetShaderInfoLog(vertexShader, 512, NULL, buffer);
    std::cout << buffer << std::endl;
    glDeleteShader(vertexShader);
}

// Fragment Shader
GLuint fragmentShader = glCreateShader(GL_FRAGMENT_SHADER);
glShaderSource(fragmentShader, 1, &fragmentSource, NULL);
glCompileShader(fragmentShader);
glGetShaderiv(fragmentShader, GL_COMPILE_STATUS, &status);
if (status != GL_TRUE)
{
    std::cout << "Failed to compile fragment shader!\nInfo log: " << std::endl;
    char buffer[512];
    glGetShaderInfoLog(fragmentShader, 512, NULL, buffer);
    std::cout << buffer << std::endl;
    glDeleteShader(fragmentShader);
}

// Shader program
glAttachShader(m_shaderID, vertexShader);
glAttachShader(m_shaderID, fragmentShader);
glLinkProgram(m_shaderID);
glValidateProgram(m_shaderID);

glDeleteShader(vertexShader);
glDeleteShader(fragmentShader);
void Shader::setUniformmat4(const GLchar* name, glm::mat4 matrix)
{
    for (int i = 0; i <= 3; i++)
        printf("%f, %f, %f, %f\n", matrix[i].x, matrix[i].y, matrix[i].z, matrix[i].w);
    glUniformMatrix4fv(glGetUniformLocation(m_shaderID, name), 1, GL_FALSE, glm::value_ptr(matrix));
}
glm::mat4 model = glm::mat4(1.0);
shader.setUniformmat4("model", model);
创建照明效果时,我通过调用以下函数创建制服:

void Shader::setUniformvec2(const GLchar* name, glm::vec2 vector)
{
    glUniform2f(glGetUniformLocation(m_shaderID, name), vector.x, vector.y);
}
通过这段代码:

shader.setUniformvec2("light_pos", glm::vec2((x / window.getWidth()) * 2.0 - 1.0, 1.0 - 2.0 * (y / window.getHeight())));
其中
x
y
是鼠标坐标。然后我添加行

uniform vec2 light_pos;
到片段着色器。这工作没有问题,而且它可以完美地跟踪鼠标。用于设置统一的
mat4
的函数与设置统一的
vec2
的函数看起来相同,唯一的区别是
mat4
的4fv和
vec2
的2f

如你所见,我对矩阵和向量使用glm

我的主要功能如下所示:

    Window window(720, 720, "Window");

    Shader shader("shader.vert", "shader.frag");

    glm::mat4 model = glm::mat4(1.0);
    shader.setUniformmat4("model", model);

    Renderer* renderer = new Renderer();

    std::vector<StaticSprite*> sprites;

    sprites.push_back(new StaticSprite(-0.5, -0.5, 0.0, 1.0, 1.0, glm::vec4(1.0, 1.0, 0.0, 1.0), &shader));

    while (!window.closed())
    {
        window.clear();
        shader.enable();
        double x, y;
        window.getMousePosition(x, y);
        shader.setUniformvec2("light_pos", glm::vec2((x / window.getWidth()) * 2.0 - 1.0, 1.0 - 2.0 * (y / window.getHeight())));

        for (StaticSprite* sprite : sprites)
            renderer->submit(sprite);
        renderer->flush();

        shader.disable();
        window.update();
    }
    return 0;
窗口窗口(720720,“窗口”);
着色器(“Shader.vert”、“Shader.frag”);
glm::mat4模型=glm::mat4(1.0);
setUniformmat4(“模型”,模型);
渲染器*渲染器=新渲染器();
矢量精灵;
sprites.push_back(新的StaticSprite(-0.5,-0.5,0.0,1.0,1.0,glm::vec4(1.0,1.0,0.0,1.0),&shader));
而(!window.closed())
{
window.clear();
enable();
双x,y;
window.getMousePosition(x,y);
setUniformvec2(“light_pos”,glm::vec2((x/window.getWidth())*2.0-1.0,1.0-2.0*(y/window.getHeight()));
用于(静态精灵*精灵:精灵)
渲染器->提交(精灵);
渲染器->刷新();
shader.disable();
window.update();
}
返回0;
我总结的问题基本上是,为什么统一mat4的值不正确,有没有办法找出这些值是什么,我应该在代码中更改什么以使统一mat4正常工作

请询问回答问题所需的任何其他信息,我很乐意提供我忘记包含的任何内容。

为当前程序对象指定统一变量的值。这意味着程序必须在以下时间之前安装:

Shader着色器(“Shader.vert”、“Shader.frag”);

shader.enable();//矩阵统一是在着色器程序安装后设置的(在
glUseProgram
之后),不是吗?当然,我会添加main函数,以便您可以看到调用所有程序的顺序。glUseProgram在窗口循环的shader.enable()中调用。不,您没有<代码>着色器.setUniformmat4(“模型”,模型)必须在
着色器.enable()之后执行!哇,太谢谢你了。真不敢相信我错过了。。。