-
-
Notifications
You must be signed in to change notification settings - Fork 89
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Bug: OpenGL Rendering in Imgui #200
Labels
question
Further information is requested
Comments
SpaiR
added
question
Further information is requested
and removed
bug
Something isn't working
labels
Sep 29, 2023
You can render your scene onto ImGui using ImGui.Image(); this requires a Frame Buffer which takes in the texture ID of your Frame Buffer as the first argument ImGui.image(framebuffer.getTextureId(), regionAvail.x, regionAvail.y, 0, 1, 1, 0); you can dig around my code below for a better example |
Here's how I did it for threekt: package com.displee.imgui.threekt.texture
import org.lwjgl.opengl.GL30.*
import org.lwjgl.opengl.GL32.GL_PROGRAM_POINT_SIZE
import java.nio.ByteBuffer
class ThreeKtTexture {
var texture_id = -1
var FBO = -1
var RBO = -1
var width = 0
var height = 0
fun create_framebuffer(width: Int, height: Int)
{
this.width = width
this.height = height
// threekt defaults
glEnable(GL_PROGRAM_POINT_SIZE)
glEnable(GL_POINT_SPRITE)
FBO = glGenFramebuffers()
glBindFramebuffer(GL_FRAMEBUFFER, FBO)
texture_id = glGenTextures()
glBindTexture(GL_TEXTURE_2D, texture_id)
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, null as ByteBuffer?)
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR)
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR)
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture_id, 0)
RBO = glGenRenderbuffers()
glBindRenderbuffer(GL_RENDERBUFFER, RBO)
glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8, width, height)
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_RENDERBUFFER, RBO)
// if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE)
// std::cout << "ERROR::FRAMEBUFFER:: Framebuffer is not complete!\n";
glBindFramebuffer(GL_FRAMEBUFFER, 0)
glBindTexture(GL_TEXTURE_2D, 0)
glBindRenderbuffer(GL_RENDERBUFFER, 0)
}
// here we bind our framebuffer
fun bind_framebuffer()
{
glBindFramebuffer(GL_FRAMEBUFFER, FBO)
}
// here we unbind our framebuffer
fun unbind_framebuffer()
{
glBindFramebuffer(GL_FRAMEBUFFER, 0)
}
// and we rescale the buffer, so we're able to resize the window
fun rescale_framebuffer(width: Int, height: Int)
{
this.width = width
this.height = height
glBindTexture(GL_TEXTURE_2D, texture_id)
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, null as ByteBuffer?)
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR)
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR)
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture_id, 0)
glBindRenderbuffer(GL_RENDERBUFFER, RBO)
glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8, width, height)
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_RENDERBUFFER, RBO)
}
} Then in your ImGui window: ImGui.text("This a demo for ImGui Canvas editor")
ImGui.sameLine()
ImGui.text("Mouse Left: drag to add lines,\nMouse Right: drag to scroll, click for context menu.")
if (firstFrame) {
initThreeKt()
firstFrame = false
}
ImGui.image(threektTexture.texture_id, threektTexture.width.toFloat(), threektTexture.height.toFloat(), 0F, 1F, 1F, 0F)
controlsEventSource.handleMouseEvents()
val windowSize = ImGui.getWindowSize()
ImGui.end()
threektTexture.bind_framebuffer()
// threekt clear is called once and while imgui calls it every frame, so we have to call it ourselves
val bg = Color(Color.skyblue)
GL32.glClearColor(bg.r, bg.g, bg.b, 1F)
GL32.glClear(GL32.GL_COLOR_BUFFER_BIT or GL32.GL_DEPTH_BUFFER_BIT)
onResizeThreeKt(windowSize)
val dt = clock.getDelta()
box.rotation.x += 0.5f * dt
box.rotation.y += 0.5f * dt
renderer.render(scene, camera)
threektTexture.unbind_framebuffer() Init OpenGL/threekt and only resize if needed private fun initThreeKt() {
val imguiWindowSize = ImGui.getWindowSize()
val windowSize = WindowSize(imguiWindowSize.x.toInt(), imguiWindowSize.y.toInt())
camera = PerspectiveCamera(75, windowSize.aspect, 0.1, 1000).also {
it.translateZ(10f)
}
controlsEventSource = ImGuiEventSource(windowSize)
controls = OrbitControls(camera, controlsEventSource)
renderer = GLRenderer(windowSize)
threektTexture.create_framebuffer(imguiWindowSize.x.toInt(), imguiWindowSize.y.toInt())
}
private fun onResizeThreeKt(windowSize: ImVec2) {
val width = windowSize.x.toInt()
val height = windowSize.y.toInt()
if (width == lastWidth && height == lastHeight) {
return
}
camera.aspect = width.toFloat() / height.toFloat()
camera.updateProjectionMatrix()
camera.updateWorldMatrix()
renderer.setSize(width, height)
threektTexture.rescale_framebuffer(width, height)
lastWidth = width
lastHeight = height
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Version
1.86.4
What happened?
I am trying to render an OpenGL scene into an ImGui Window. How would I achieve this as there seems to be no documentation on this repository? I have only seen C++ examples to implement this.
Reproduction
No Documentation
Relevant log output
No response
The text was updated successfully, but these errors were encountered: