Skip to content

Instantly share code, notes, and snippets.

@wsphillips
Last active July 7, 2020 21:54
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save wsphillips/1948b31ff23b00a303112e60ea518545 to your computer and use it in GitHub Desktop.
Save wsphillips/1948b31ff23b00a303112e60ea518545 to your computer and use it in GitHub Desktop.
CImGui.jl : Attempt to load and display a random array of numbers as an image
using CImGui
using CImGui.CSyntax
using CImGui.CSyntax.CStatic
using CImGui.GLFWBackend
using CImGui.OpenGLBackend
using CImGui.GLFWBackend.GLFW
using CImGui.OpenGLBackend.ModernGL
using Printf
import CImGui.OpenGLBackend.ModernGL: glGenTextures
import CImGui: ImVec2, ImVec4, ImTextureID
# Extra dispatch for GenTextures for convenience (as in GLExtendedFunctions.jl)
function glGenTextures()
result = UInt32[0]
glGenTextures(1, result)
id = result[1]
if id <= 0
error("glGenTextures returned invalid id. OpenGL Context active?")
end
return id
end
# image loading similar to imgui example for OpenGL
function load_texture(tex_id, img::AbstractArray{UInt16,2})
height::Cint = size(img, 1)
width::Cint = size(img, 2)
glBindTexture(GL_TEXTURE_2D, tex_id)
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR)
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR)
glPixelStorei(GL_UNPACK_ROW_LENGTH, 0)
# Here we are loading a single pixel value image so GL_R16 = UInt16 (common grayscale
# format)
glTexImage2D(GL_TEXTURE_2D, GLint(0), GL_RGBA, width, height,
GLint(0), GL_RED, GL_UNSIGNED_SHORT, img)
end
# OpenGL 3.0 + GLSL 130
const glsl_version = 130
GLFW.WindowHint(GLFW.CONTEXT_VERSION_MAJOR, 3)
GLFW.WindowHint(GLFW.CONTEXT_VERSION_MINOR, 0)
# setup GLFW error callback
error_callback(err::GLFW.GLFWError) = @error "GLFW ERROR: code $(err.code) msg: $(err.description)"
GLFW.SetErrorCallback(error_callback)
# create window
window = GLFW.CreateWindow(1280, 720, "Image Demo")
@assert window != C_NULL
GLFW.MakeContextCurrent(window)
GLFW.SwapInterval(0) # enable vsync
# setup Dear ImGui context
ctx = CImGui.CreateContext()
# setup Dear ImGui style
CImGui.StyleColorsDark()
# load Fonts
fonts_dir = joinpath(@__DIR__, "..", "fonts")
fonts = CImGui.GetIO().Fonts
CImGui.AddFontFromFileTTF(fonts, joinpath(fonts_dir, "Roboto-Medium.ttf"), 16)
# setup Platform/Renderer bindings
ImGui_ImplGlfw_InitForOpenGL(window, true)
ImGui_ImplOpenGL3_Init(glsl_version)
try
show_image_window = false
clear_color = Cfloat[0.45, 0.55, 0.60, 1.00]
img = rand(UInt16, 700, 700)
img_tex_id = glGenTextures()
while !GLFW.WindowShouldClose(window)
GLFW.PollEvents()
# start the Dear ImGui frame
ImGui_ImplOpenGL3_NewFrame()
ImGui_ImplGlfw_NewFrame()
CImGui.NewFrame()
# we use a Begin/End pair to created a named window.
@cstatic f=Cfloat(0.0) counter=Cint(0) begin
CImGui.Begin("Hello, world!") # create a window called "Hello, world!" and append into it.
CImGui.Text("Click to stream images.") # display some text
@c CImGui.Checkbox("Image Window", &show_image_window)
CImGui.Text(@sprintf("Application average %.3f ms/frame (%.1f FPS)", 1000 / CImGui.GetIO().Framerate, CImGui.GetIO().Framerate))
CImGui.End()
end
# show another simple window.
if show_image_window
@c CImGui.Begin("Image Window", &show_image_window)
img .= rand(UInt16, 700, 700)
load_texture(img_tex_id, img)
CImGui.Image(ImTextureID(Int(img_tex_id)), ImVec2(700,700),ImVec2(0,0), ImVec2(1,1), ImVec4(255,255,255,255), ImVec4(255,255,255,128))
CImGui.End()
end
# rendering
CImGui.Render()
GLFW.MakeContextCurrent(window)
display_w, display_h = GLFW.GetFramebufferSize(window)
glViewport(0, 0, display_w, display_h)
glClearColor(clear_color...)
glClear(GL_COLOR_BUFFER_BIT)
ImGui_ImplOpenGL3_RenderDrawData(CImGui.GetDrawData())
GLFW.MakeContextCurrent(window)
GLFW.SwapBuffers(window)
end
catch e
@error "Error in renderloop!" exception=e
Base.show_backtrace(stderr, catch_backtrace())
finally
ImGui_ImplOpenGL3_Shutdown()
ImGui_ImplGlfw_Shutdown()
CImGui.DestroyContext(ctx)
GLFW.DestroyWindow(window)
end
@wsphillips
Copy link
Author

This works, but I have a feeling I am quickly filling VRAM via not freeing textures or re-using the initial texture ID. Comments appreciated!

@wsphillips
Copy link
Author

Works now! With some added code for handling different image types and pixel swizzling/color mapping this could be really neat! (I intend to use for streaming monochrome camera video.)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment