Jogl, creating only red channel u16 but getting “Texture type and format combination is not valid”

ぐ巨炮叔叔 提交于 2020-01-06 04:54:17

问题


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 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

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);

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)

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 is not yet taken in account at the moment

And here the FS:

#version 330

uniform uint id;

out vec4 outputColor;

void main() {

    outputColor = vec4(id, 0, 0, 1);
}

Using shorts is feasible?

Jogl, Opengl 3.3

Edit: it looks now I solved that part with

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());

Error

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]

The uniform location seems correct since it is not -1 (1 actually)...

So how could I upload a short?


回答1:


Most of your problems are related to the fact that OpenGL isn't as gracious with conversions as you might expect it to be.

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:

GL_INVALID_OPERATION is generated if one of the signed integer variants of this function is used to load a uniform variable of type unsigned int, uvec2, uvec3, uvec4, or an array of these.

Thus you have to use glUniform1ui instead (mind the u!) if your id variable is a uint.


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;

or maybe

out ivec4 outputID;

if neccessary (or with a "u" if using GL_R16UI of course).


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);

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.



来源:https://stackoverflow.com/questions/21625709/jogl-creating-only-red-channel-u16-but-getting-texture-type-and-format-combina

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!