问题描述
因此,我正在尝试实现ID识别.这意味着,对于每个drawArray,都会将不同的唯一ID设置为统一的,并保存在纹理的红色组件中.
So, I am trying to implement the picking through id. This means with every drawArray a different unique id will be set as uniform and saved in the red component on a texture.
16位足够了(65k个元素),所以我选择使用短裤,我知道统一变量只能是ui,但是我还是决定尝试一下
16 bits are more than enough (65k elements), so I choose to use shorts, I know that uniform variable can be only ui, but I decided to gave it a try anyway
我还发现了另一个问题,此处,其中的答案包含一个带短裤的小例子
I also found another question, here, where the answer contains a small example with shorts
但是在这里,我的代码初始化了帧缓冲区和两个纹理,一个用于深度,一个用于color_attachment0,只有红色成分为16
However here my code to initialize the framebuffer and two textures, one for the depth and one for the color_attachment0 with just the red component with 16
textures = new int[2];
fbo = new int[1];
gl3.glGenTextures(2, textures, 0);
gl3.glGenFramebuffers(1, fbo, 0);
/**
* Depth.
*/
gl3.glBindTexture(GL3.GL_TEXTURE_RECTANGLE, textures[depth]);
gl3.glTexParameteri(GL3.GL_TEXTURE_RECTANGLE, GL3.GL_TEXTURE_WRAP_S, GL3.GL_CLAMP_TO_EDGE);
gl3.glTexParameteri(GL3.GL_TEXTURE_RECTANGLE, GL3.GL_TEXTURE_WRAP_T, GL3.GL_CLAMP_TO_EDGE);
gl3.glTexParameteri(GL3.GL_TEXTURE_RECTANGLE, GL3.GL_TEXTURE_MIN_FILTER, GL3.GL_NEAREST);
gl3.glTexParameteri(GL3.GL_TEXTURE_RECTANGLE, GL3.GL_TEXTURE_MAG_FILTER, GL3.GL_NEAREST);
gl3.glTexImage2D(GL3.GL_TEXTURE_RECTANGLE, 0, GL3.GL_DEPTH_COMPONENT32F, width, height, 0, GL3.GL_DEPTH_COMPONENT, GL3.GL_FLOAT, null);
/**
* IDs.
*/
gl3.glBindTexture(GL3.GL_TEXTURE_RECTANGLE, textures[id]);
gl3.glTexParameteri(GL3.GL_TEXTURE_RECTANGLE, GL3.GL_TEXTURE_WRAP_S, GL3.GL_CLAMP_TO_EDGE);
gl3.glTexParameteri(GL3.GL_TEXTURE_RECTANGLE, GL3.GL_TEXTURE_WRAP_T, GL3.GL_CLAMP_TO_EDGE);
gl3.glTexParameteri(GL3.GL_TEXTURE_RECTANGLE, GL3.GL_TEXTURE_MIN_FILTER, GL3.GL_NEAREST);
gl3.glTexParameteri(GL3.GL_TEXTURE_RECTANGLE, GL3.GL_TEXTURE_MAG_FILTER, GL3.GL_NEAREST);
gl3.glTexImage2D(GL3.GL_TEXTURE_RECTANGLE, 0, GL3.GL_R16UI, width, height, 0, GL3.GL_RED, GL3.GL_UNSIGNED_SHORT, null);
/**
* FBO.
*/
gl3.glBindFramebuffer(GL3.GL_FRAMEBUFFER, fbo[0]);
gl3.glFramebufferTexture2D(GL3.GL_FRAMEBUFFER, GL3.GL_DEPTH_ATTACHMENT, GL3.GL_TEXTURE_RECTANGLE, textures[depth], 0);
gl3.glFramebufferTexture2D(GL3.GL_FRAMEBUFFER, GL3.GL_COLOR_ATTACHMENT0, GL3.GL_TEXTURE_RECTANGLE, textures[id], 0);
在id-glTexImage2D处出现以下错误
I get the following error at the id-glTexImage2D
GLDebugEvent[ id 0x502
type Error
severity High: dangerous undefined behavior
source GL API
msg GL_INVALID_OPERATION error generated. Texture type and format combination is not valid.
when 1391769197680
source 4.4 (Compat profile, arb, debug, ES2 compat, ES3 compat, FBO, hardware) - 4.4.0 - hash 0x1c19b340]
java.lang.Exception: Stack trace
at java.lang.Thread.dumpStack(Thread.java:1364)
at jogamp.opengl.GLDebugMessageHandler$StdErrGLDebugListener.messageSent(GLDebugMessageHandler.java:308)
at jogamp.opengl.GLDebugMessageHandler.sendMessage(GLDebugMessageHandler.java:293)
at jogamp.opengl.GLDebugMessageHandler.glDebugMessageARB(GLDebugMessageHandler.java:319)
at jogamp.opengl.gl4.GL4bcImpl.dispatch_glTexImage2D1(Native Method)
at jogamp.opengl.gl4.GL4bcImpl.glTexImage2D(GL4bcImpl.java:27313)
at javax.media.opengl.DebugGL4bc.glTexImage2D(DebugGL4bc.java:19874)
at ec.rendering.input.picking.EC_Picking.initRenderingTargets(EC_Picking.java:107)
为完整起见,这里是VS:
For completeness, here the VS:
#version 330
layout (location = 0) in vec3 position;
uniform mat4 modelToWorldMatrix;
layout(std140) uniform GlobalMatrices {
mat4 worldToCameraMatrix;
mat4 cameraToClipMatrix;
};
void main() {
gl_Position = cameraToClipMatrix * (worldToCameraMatrix * vec4(position, 1.0));
}
目前尚未考虑
modelToWorldMatrix
modelToWorldMatrix is not yet taken in account at the moment
这里是FS:
#version 330
uniform uint id;
out vec4 outputColor;
void main() {
outputColor = vec4(id, 0, 0, 1);
}
使用短裤可行吗?
Jogl,Opengl 3.3
Jogl, Opengl 3.3
现在看来我已经用
gl3.glTexImage2D(GL3.GL_TEXTURE_RECTANGLE, 0, GL3.GL_R16I, width, height, 0, GL3.GL_RED_INTEGER, GL3.GL_SHORT, null);
但是现在当我尝试设置较短的统一值时出现错误
but now I get an error when I try to set the short uniform value
gl3.glUniform1i(pickModel.getIdUL(), (int)mesh.getId());
错误
GLDebugEvent[ id 0x502
type Error
severity High: dangerous undefined behavior
source GL API
msg GL_INVALID_OPERATION error generated. Wrong component type or count.
when 1391779682993
source 4.4 (Compat profile, arb, debug, ES2 compat, ES3 compat, FBO, hardware) - 4.4.0 - hash 0x5ee072e3]
统一位置似乎正确,因为它不是-1(实际上是1)...
The uniform location seems correct since it is not -1 (1 actually)...
那我怎么上传短片呢?
推荐答案
您的大多数问题都与OpenGL不像您期望的那样吸引人的事实有关.
Most of your problems are related to the fact that OpenGL isn't as gracious with conversions as you might expect it to be.
首先对于glUniform
调用,统一变量的类型和大小必须与函数完全匹配.具体来说,文档说:
First of all for a glUniform
call the type and size of the uniform variable has to match the function exactly. Specifically, the documentation says:
因此,如果您的id
变量是uint
,则必须使用glUniform1ui
代替(注意 u !).
Thus you have to use glUniform1ui
instead (mind the u!) if your id
variable is a uint
.
除此之外,帧缓冲区的输出格式和着色器的输出格式之间也存在不匹配.如果要写入整数纹理,则需要从着色器写入实际的整数,因此将outputColor
更改为
Other than that there's also a mismatch between your framebuffer's output format and your shader's output format. If you want to write into an integer texture, you need to write actual integers from your shader, thus change your outputColor
to
out int outputID;
或者也许
out ivec4 outputID;
(如果需要)(或者,如果使用GL_R16UI
,则带有"u").
if neccessary (or with a "u" if using GL_R16UI
of course).
顺便说一句,您确定需要带符号的整数纹理(因为对于您的用例而言,无符号的更为自然)?您说将glTexImage2D
调用更改为
And by the way, are you sure you need a signed integer texture (as unsigned would be much more natural for your use case)? You say that changing the glTexImage2D
call to
gl3.glTexImage2D(GL3.GL_TEXTURE_RECTANGLE, 0, GL3.GL_R16I, width, height, 0, GL3.GL_RED_INTEGER, GL3.GL_SHORT, null);
使纹理错误消失,但这很可能是因为使用了GL_RED_INTEGER
而不是仅仅使用GL_RED
,而不一定是因为使用了带符号格式.因此,GL_R16UI
与GL_UNSIGNED_SHORT
和GL_RED_INTEGER
(当然对于输出变量是uint
或uvec4
)一起值得尝试.
made the texture error disappear, but this may very well have been because of the use of GL_RED_INTEGER
instead of just GL_RED
and not necessarily because of the use of a signed format. So GL_R16UI
together with GL_UNSIGNED_SHORT
and GL_RED_INTEGER
(and of course a uint
or uvec4
for the output variable) would be worth a try.
请记住,类型必须始终匹配.
Just keep in mind that the types always have to match.
这篇关于Jogl,仅创建红色通道u16,但获得“纹理类型和格式组合无效".的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!