Closed MubinMuhammad closed 5 hours ago
Since there is no code, I can only guess that you switched shaders, called ImGui::Image()
and switched shaders back. That doesn't work since the function doesn't issue a draw command directly. It just constructs draw data that is rendered later. To switch shaders at the right time, you need to inject that shader switch into the draw commands. You can do that with ImDrawList::AddCallback()
.
Thanks, for clarity, a pseudo code for the problem output will be:
...
const char *vertex_shader = R"
#version 330
// take input for color, texture_coords, colors
out vec2 v_tex_coords
void main() {
v_texture_coords = texture_coords;
}
"
const char *fragment_shader = R"
#version 330
out vec4 out_color;
uniform sampler2D tex;
in vec4 v_tex_coords;
void main() {
// calculate grayscale
vec4 _o = texture(tex, v_tex_coords);
float y = (_o.x + _o.y + _o.z) / 3;
out_color = vec4(y, y, y, _o.w);
}
"
vertices[] = {
//colors // texture coords // colors
{{}, {0.0f, 1.0f}, {}},
{{}, {0.0f, 0.0f}, {}},
{{}, {1.0f, 0.0f}, {}},
{{}, {1.0f, 1.0f}, {}},
}
shader = shaderInit(vertex_shader, fragment_shader);
buffer = sendBufferToGPU(vertices);
unsigned int tex_id = textureInit("path/to/image.jpg");
while (window_is_open) {
...
bindBuffer(buffer.vao);
bindTexture(tex_id);
bindShader(shader);
ImGui::Image(tex_id, {tex_width, tex_height));
...
}
...
As I could find any helpful info on ImDrawList::AddCallback()
, it will be helpful if you can provide me a pseudo code or a good resource.
Since, my last comment, I have tested with many stuff and ended up using a framebuffer to store texture data, change the texture in the viewport and render that in the ImGui::Image()
.
Though it's solvable I will still keep this issue open. Just because to know if there any other(better) solutions exist. Thanks.
The other solution is already outlined in Daniel’s answer, it is to use AddCallback() to change the render state or shader for a given render.
The callback is then called in the actual render loop, and you can call bindShader() in the callback. If you search for AddCallback() in this repo you’ll find many references.
Calling bindShader() before ImGui::Image() has no effect since all rendering commands are queued and processed in the RenderDrawData() call.
Version/Branch of Dear ImGui:
Version 1.91.5, Branch: master
Back-ends:
imgui_impl_glfw.cpp
+imgui_impl_opengl3.cpp
Compiler, OS:
archlinux 6.6.56-1-lts
+g++ 14.2.1
Full config/build information:
Used python script to build the project.
Details:
Is there a way to add shader effect to a texture who's ID is passed to
ImGui::Image()
? I've tried this by creating vertex shader who doesn't do anything and fragment shader which changes the pixel to be grayscale. The result is there is no change to Image displayed byImGui::Image()
.Then, I added a vertex buffer, made changes to vertex shader and displayed the image on to the OpenGL viewport, and I see that the image is grayscale. So, my question is why doesn't the image get changed in the
ImGui::Image()
? Tough they are using the same Texture ID.How do add post-processing effects to image shown by
ImGui::Image()
?Thanks.
Screenshots/Video:
Minimal, Complete and Verifiable Example code:
Requires a lot of code.