在OpenGL 4.5中迭代自定义结构unifrom数组
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了在OpenGL 4.5中迭代自定义结构unifrom数组相关的知识,希望对你有一定的参考价值。
我试图在OpenGL 4.5中迭代一系列自定义结构的统一数组,但我的应用程序崩溃了一个无效的操作枚举器。
我的片段着色器看起来像:
#version 450
struct Light
{
vec4 position;//intensity here as well
vec4 color;
};
in vec3 normal;//Normal to the vertex
in vec3 vertexPos;//True position of the vertex (i.e it's location in space)
in vec2 texture_coord;
out vec4 outColor;//Final color of the pixel
uniform sampler2D text;
uniform samplerCubeArray depth_maps;
uniform Light lights[];
uniform vec4 color = vec4(1);//Default color
//TODO: make this an array
//uniform vec3 lum = vec3(100,90,15); vec3(80,70,10);//A unique light position
uniform vec3 lums[2] = {vec3(80,70,10), vec3(100,90,15)};
uniform vec3 cameraPos = vec3(0);//The position of the camera in the world
uniform vec3 cameraDir = vec3(0);
void main()
{
outColor = vec4(0);
for(uint i=0 ; i<2; i++)
{
vec4 color = vec4(0);
vec3 lum = lights[i].position.xyz;
vec3 l = vec3(lum-vertexPos);
if(length(l)>0)
l = normalize(l);
vec3 c = vec3(texture(text,abs(texture_coord)));
vec3 n = normalize(normal);
vec3 e = cameraPos-vertexPos;
e = normalize(e);
vec3 h = normalize(e+l);
color = vec4(c*(vec3(0.5)+0.5*max(0,dot(n,l))) +
vec3(0.1)*max(0,pow(dot(h,n), 100)), 1);
vec3 temp = vertexPos-lum;
float test = texture(depth_maps, vec4(temp, 1)).r;
double d = length(temp);
if(d>test*256 + 0.5)
color = vec4(test/2);
outColor += color;
}
outColor = outColor/2.f;
}
如果将赋值运算符中的索引替换为常量,即编写vec3 lum = lights[0].position.xyz;
或vec3 lum = lights[1].position.xyz;
没有错误(但当然最终的图像是错误的)。
但是,如果相反,我尝试将其动态设置为vec3数组,即我写:
vec3 lum = lums[i];
事情按预期工作。
为什么我不能遍历我的Light数组?是因为它是一个自定义结构?
编辑:
添加cpp代码,根据请求设置阴影贴图
绘制阴影贴图
void Renderer::draw_shadow_maps(vector<Light> &lights)
{
current_program = shading_programs[SHADER_DEPTH].programID;
glUseProgram(current_program);
//shadow_maps.resize(lights.size());
glViewport(0, 0, 2048, 2048);
glBindFramebuffer(GL_FRAMEBUFFER, FBOs[FBO_SHADOW_MAP]);
for(uint i=0; i<lights.size(); i++)
{
glFramebufferTexture(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, shadow_maps[0].textureID, 0);
load_uniform((int)i, "map_index");
glDrawBuffer(GL_NONE);
glReadBuffer(GL_NONE);
if(glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE)
{
if(glCheckFramebufferStatus(GL_FRAMEBUFFER)==GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT)
cerr << "shadow map was not initialized properly" << endl;
exit(0);
}
glClear(GL_DEPTH_BUFFER_BIT);
setup_light_perspectives(current_program, lights[i]);
draw();
}
}
创建阴影贴图:
Shadow_Map::Shadow_Map()
{
glGenTextures(1, &textureID);
glBindTexture(GL_TEXTURE_CUBE_MAP_ARRAY, textureID);
glTexStorage3D(GL_TEXTURE_CUBE_MAP_ARRAY,1, GL_DEPTH_COMPONENT32F, 2048, 2048, 6*10);
glTexParameteri(GL_TEXTURE_CUBE_MAP_ARRAY, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_CUBE_MAP_ARRAY, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_CUBE_MAP_ARRAY, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_CUBE_MAP_ARRAY, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_CUBE_MAP_ARRAY, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
glBindTexture(GL_TEXTURE_CUBE_MAP, 0);
openGLerror();
}
将信息传递给GPU:
void Shadow_Map::load_to_GPU(GLuint program)
{
glUseProgram(program);
glActiveTexture(GL_TEXTURE1);
glBindTexture(GL_TEXTURE_CUBE_MAP_ARRAY, textureID);
string name = "depth_maps";
GLint loc = glGetUniformLocation(program, name.c_str());
if(loc == GL_INVALID_VALUE || loc==GL_INVALID_OPERATION)
{
cerr << "Error returned when trying to find depth_map uniform."
<< "
uniform: " << name
<< "
Error num: " << loc
<< endl;
return;
}
glUniform1i(loc,1);
}
答案
uniform Light lights[];
Arrays in GLSL几乎总是必须有一个静态定义的大小。以下是例外情况:
- 您可以转发声明没有大小的数组,但前提是您稍后使用大小重新声明它。
- 变量是last member of a shader storage block。
- 变量(或接口块)是着色器阶段输入/输出限定变量/块,并且该阶段的输入/输出被排列。
以上是关于在OpenGL 4.5中迭代自定义结构unifrom数组的主要内容,如果未能解决你的问题,请参考以下文章
Windows 上没有 GLUT 的 OpenGL 4.5 简单教程 [关闭]