Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
150 views
in Technique[技术] by (71.8m points)

c++ - OpenGL - Render to single channel texture?

I'm trying to render to a single channel texture attached to a framebuffer but its not working. I create the texture using a sized format:

glCreateTextures(GL_TEXTURE_2D, 1, &entityTexture);
glTextureStorage2D(entityTexture, 1, GL_R32F, viewport.size.x, viewport.size.y);
glTextureParameteri(entityTexture, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTextureParameteri(entityTexture, GL_TEXTURE_MAG_FILTER, GL_NEAREST);

UPDATE: I then attach it to my framebuffer together with some others:

std::array<GLenum, 4> colorAttachments = { 
    GL_COLOR_ATTACHMENT0, 
    GL_COLOR_ATTACHMENT1, 
    GL_COLOR_ATTACHMENT2, 
    GL_COLOR_ATTACHMENT3,
};

glNamedFramebufferDrawBuffers(GBuffer, static_cast<GLsizei>(colorAttachments.size()), colorAttachments.data());

Inside the shader I write up top:

layout(location = 0) out vec4 gNormal;
layout(location = 1) out vec4 gColor;
layout(location = 2) out vec4 gMetallicRoughness;
layout(location = 3) out float gEntityID;

And then write some random test value to it in the fragment shader (drawing a bunch of meshes):

gEntityID = 12.3;

When I check in RenderDoc the image turns up black with a value of 0. Does all this check out in terms of API usage?

question from:https://stackoverflow.com/questions/65557538/opengl-render-to-single-channel-texture

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

This has nothing to do with rendering to a single-channel texture. Your code for routing color outputs to buffers is non-functional.

glNamedFramebufferDrawBuffers(GBuffer, 1, GL_COLOR_ATTACHMENT3);

That's not how glDrawBuffers or its DSA equivalent work. Indeed, you should have gotten a compile error, because you tried to pass a prvalue integer literal (GL_COLOR_ATTACHMENT3) to a function that takes a pointer.

Even if we fix your function so that it passes a single-element array:

GLenum attachments[1] = {GL_COLOR_ATTACHMENT3};
glNamedFramebufferDrawBuffers(GBuffer, 1, attachments);

That still doesn't work.

You pass glDrawBuffers an array. The indices of this array are the color numbers you set into your fragment shader. So location = 3 on the fragment shader output means to look at the 4th element of the array passed to glDrawBuffers to figure out which attachment binding point gets used. You only passed one element, since the size you gave was 1. The other elements of the array are set to GL_NONE.

So nothing gets written to.

What you (maybe?) want is this:

GLenum attachments[4] = {<attach>, <attach>, <attach>, GL_COLOR_ATTACHMENT3};
glNamedFramebufferDrawBuffers(GBuffer, 4, attachments);

Where <attach> are the first three attachment points.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...