我试图通过统一变量将screenWidth和screenHeight放入我的片段着色器中 . 这是我的main.cpp,罪犯在哪里,我可以得到位置(非-1)但是当它实际上设置统一变量时,我是段错误 .
#include <GL/glew.h>
#include <GL/freeglut.h>
#include <stdio.h>
#include "math_3d.h"
#include "shader.h"
// Global
GLuint VBO;
static void RenderSceneCB()
{
glClear(GL_COLOR_BUFFER_BIT);
glEnableVertexAttribArray(0);
glBindBuffer(GL_ARRAY_BUFFER, VBO);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, 0);
glDrawArrays(GL_TRIANGLES, 0, 3);
glDisableVertexAttribArray(0);
glutSwapBuffers();
}
static void CreateVertexBuffer()
{
Vector3f Verticies[3];
Verticies[0] = Vector3f(-1.0f, -1.0f, 0.0f);
Verticies[1] = Vector3f(1.0f, -1.0f, 0.0f);
Verticies[2] = Vector3f(0.0f, 1.0f, 0.0f);
glGenBuffers(1, &VBO);
glBindBuffer(GL_ARRAY_BUFFER, VBO);
glBufferData(GL_ARRAY_BUFFER, sizeof(Verticies), Verticies, GL_STATIC_DRAW);
}
int main(int argc, char** argv)
{
const int SCREEN_WIDTH = 800, SCREEN_HEIGHT = 600;
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DOUBLE|GLUT_RGBA);
glutInitWindowSize(SCREEN_WIDTH, SCREEN_HEIGHT);
glutInitWindowPosition(100, 100);
glutCreateWindow("Test Window");
glutDisplayFunc(RenderSceneCB);
GLenum res = glewInit();
if(res != GLEW_OK)
{
fprintf(stderr, "Error: '%s'\n", glewGetErrorString(res));
return 1;
}
const GLubyte* renderer = glGetString(GL_RENDERER);
const GLubyte* version = glGetString(GL_VERSION);
printf("Renderer: %s\n", renderer);
printf("Version: %s\n", version);
Shader vertexShader(GL_VERTEX_SHADER, "shader.vs");
Shader fragShader(GL_FRAGMENT_SHADER, "shader.fs");
GLuint program = glCreateProgram();
glAttachShader(program, vertexShader.shader);
glAttachShader(program, fragShader.shader);
glLinkProgram(program);
GLint status;
glGetProgramiv(program, GL_LINK_STATUS, &status);
if (status == GL_FALSE)
{
printf("No link\n");
}
glValidateProgram(program);
glGetProgramiv(program, GL_VALIDATE_STATUS, &status);
if (status == GL_FALSE)
{
printf("No validate\n");
}
glUseProgram(program);
printf("UNIFORM\n");
// Set uniform variables
GLint location = glGetUniformLocation(program, "screenWidth");
printf("loc: %d\n", location);
glProgramUniform1i(program, location, 800);
/*
GLint location2 = glGetUniformLocation(program, "screenHeight");
printf("loc: %d\n", location2);
glProgramUniform1i(program, location2, 600);
printf("uniform done\n");
*/
glClearColor(1.0f, 1.0f, 1.0f, 0.0f);
glPointSize(10.0f);
CreateVertexBuffer();
glutMainLoop();
return 0;
}
着色器看起来像这样:
#version 130
uniform int screenWidth = 800;
uniform int screenHeight = 600;
out vec4 FragColor;
void main()
{
FragColor = vec4(gl_FragCoord.x/screenWidth, gl_FragCoord.y/screenHeight, 0.0, 1.0);
}
2 回答
你的问题实际上是
glProgramUniform1i (...)
相对较新 . 你还没有明确地说出你的OpenGL版本,但是你的着色器针对的是GLSL 1.30(OpenGL 3.0),所以很有可能你的实现不能理解这个功能 .该函数在Direct State Access扩展名(
GL_EXT_direct_state_access
)中开始生效,其名称为glProgramUniform1iEXT (...)
,当Separate Shader Objects为(GL 4.1)时被提升为 core .两个函数(
glUniform1i (...)
和glProgramUniform1i{EXT} (...)
)之间的唯一区别是,一个使用当前绑定的程序对象,另一个允许您传递所需的函数 .改变了我如何将统一变量设置为这个并且一切都解决了 . 我将glProgramUniform1i更改为glUniform1i并取消了程序参数 .
这是最后的main.cpp,查找统一部分以查看我的更改 .