我正在使用带有GLSL 1.5的OpenGL 3.2上下文,并且由于某种原因,整数属性(类型为int,uint,ivecX或uvecX)在顶点着色器中始终被读取为0.我宣布他们使用:
in int name;
Run Code Online (Sandbox Code Playgroud)
我使用glVertexAttribIPointer绑定属性(注意I),而不是glVertexAttribPointer(但是那个也不起作用).如果我将它们改为浮点数而不是它们完全正常 - 唯一的代码区别是顶点结构中的类型,GLSL中的类型,以及IPointer函数调用而不仅仅是指针.我没有得到任何错误或任何东西,他们只是全部0.如果我硬编码整数值而不是它工作正常,整数制服工作正常.此外,像gl_VertexID这样的内置整数可以完美地工作,而自定义的整数则不然.我正在运行ATI Mobility Radeon HD 5870.我尝试了另一台具有不同GPU的计算机(不幸的是我不确定GPU是什么,但它与我的不同)具有相同的结果.任何想法为什么会出现这种情况?谢谢.
编辑:实际上看起来它们不是0,更可能是随机大的未初始化值...很难说,因为我找不到任何调试GLSL着色器的方法.无论如何,还有一些信息.这是我的顶点结构:
struct TileVertex {
float pos[2];
float uv[2];
float width;
float pad;
int animFrames;
int animFrameLength;
};
Run Code Online (Sandbox Code Playgroud)
animFrames和animFrameLength是我试图发送到着色器的两个整数值.我对animFrames的glVertexAttribIPointer的调用如下:
glVertexAttribIPointer( attribute.location, attribute.typeSize, attribute.baseType, (GLsizei)stride, bufferOffset( bufOffset + attribOffset ) );
Run Code Online (Sandbox Code Playgroud)
哪里:
attribute.location = 1 (as determined by OpenGL)
attribute.typeSize = 1 (since it's a single int, not a vector)
attribute.baseType = 5124, which is GL_INT
stride = 32, which is sizeof( TileVertex )
bufferOffset() converts to a void …
Run Code Online (Sandbox Code Playgroud) 我不确定这是否可行,但值得一试.我正在使用模板缓冲区来减少使用此算法的延迟渲染器中的光量过度绘制(当摄像机位于卷外时):
这将仅导致光量内的像素被着色.绘制多个灯时会出现问题.首先,由于状态变化很昂贵,因此对于每种灯光反复在廉价和昂贵的着色器之间切换可能不是最佳选择.理想情况下,我想利用模板缓冲区的所有8位,通过使用廉价着色器渲染8个轻量级,然后使用昂贵的着色器渲染8个轻量级.但是,当灯光重叠时会出现问题,因为无法分辨哪些像素属于哪些灯光.
想到的解决方案是每个灯在模板缓冲区中使用1位.因此,对于光n,在廉价通道中标记模板缓冲区中的第n位,然后在昂贵的通过期间仅渲染具有该位的像素.
我之前没有使用模板缓冲区,但从我正在阅读的内容看起来似乎不太可能.为此,我必须使用按位OR设置模板缓冲区,并且模板函数必须是按位AND.但是,我可以看到的模板缓冲区上的唯一操作是:KEEP,ZERO,REPLACE,INCR,DECR和INVERT,唯一的功能是:NEVER,ALWAYS,LESS,EQUAL,LEQUAL,GEQUAL,GREATER和NOTEQUAL.
有没有办法以某种方式使用模板缓冲区获得此OR和AND行为?如果没有,是否有另一种方法可以有效地渲染光量?
我有一个理想情况下应如下所示的函数:
\ntemplate<typename... t_buffers, t_function function>\nvoid iterate_buffers(t_buffers &&... buffers, t_function &&function);\n
Run Code Online (Sandbox Code Playgroud)\n但是,除非参数包类型位于最后,否则无法推断出参数包类型,因此我的函数签名如下:
\ntemplate<typename... t_buffers_and_function>\nvoid iterate_bufferes(t_buffers_and_function &&... buffers_and_function);\n
Run Code Online (Sandbox Code Playgroud)\n然后参数会被重新排列,以便函数排在第一位。为了执行此改组,我使用了此处描述的技术,但在尝试转发元组时遇到了问题。
\n这是一个存在问题的简化示例:
\ntemplate<typename... t_args>\nvoid inner(std::tuple<t_args &&...> args) {};\n\ntemplate<typename... t_args>\nvoid outer(t_args &&... args) {\n inner(std::forward_as_tuple(std::forward<t_args>(args)...));\n}\n
Run Code Online (Sandbox Code Playgroud)\n如果我传递右值(例如通过调用outer(1, 2);
),它会按预期工作。但是,如果我传递左值 ( int x = 1; int y = 2; outer(x, y);
),则会出现以下语法错误:
error: could not convert \xe2\x80\x98std::forward_as_tuple(_Elements&& ...) [with _Elements = {int&, int&}]((* & std::forward<int&>((* & args#1))))\xe2\x80\x99 from \xe2\x80\x98std::tuple<int&, int&>\xe2\x80\x99 to \xe2\x80\x98std::tuple<int&&, int&&>\xe2\x80\x99\ninner(std::forward_as_tuple(std::forward<t_args>(args)...));\n~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n
Run Code Online (Sandbox Code Playgroud)\n因此forward_as_tuple …
c++ tuples variadic-templates perfect-forwarding forwarding-reference