mirror of
https://github.com/ocornut/imgui.git
synced 2026-01-12 00:14:20 +00:00
201 lines
6.4 KiB
C++
201 lines
6.4 KiB
C++
#define STB_IMAGE_IMPLEMENTATION
|
|
#include "stb_image.h" // for .png loading
|
|
#include "../../../imgui.h"
|
|
|
|
// glew & glfw
|
|
//#define GLEW_STATIC
|
|
#include <GL/glew.h>
|
|
#include <SDL2/SDL.h>
|
|
|
|
#include <iostream>
|
|
|
|
static SDL_Window* window;
|
|
static SDL_GLContext context;
|
|
static GLuint fontTex;
|
|
static bool mousePressed[4] = { false, false };
|
|
static ImVec2 mousePosScale(1.0f, 1.0f);
|
|
|
|
// This is the main rendering function that you have to implement and provide to ImGui (via setting up 'RenderDrawListsFn' in the ImGuiIO structure)
|
|
// If text or lines are blurry when integrating ImGui in your engine:
|
|
// - in your Render function, try translating your projection matrix by (0.5f,0.5f) or (0.375f,0.375f)
|
|
// - try adjusting ImGui::GetIO().PixelCenterOffset to 0.5f or 0.375f
|
|
static void ImImpl_RenderDrawLists(ImDrawList** const cmd_lists, int cmd_lists_count)
|
|
{
|
|
if (cmd_lists_count == 0)
|
|
return;
|
|
|
|
// We are using the OpenGL fixed pipeline to make the example code simpler to read!
|
|
// A probable faster way to render would be to collate all vertices from all cmd_lists into a single vertex buffer.
|
|
// Setup render state: alpha-blending enabled, no face culling, no depth testing, scissor enabled, vertex/texcoord/color pointers.
|
|
glEnable(GL_BLEND);
|
|
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
|
glDisable(GL_CULL_FACE);
|
|
glDisable(GL_DEPTH_TEST);
|
|
glEnable(GL_SCISSOR_TEST);
|
|
glEnableClientState(GL_VERTEX_ARRAY);
|
|
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
|
|
glEnableClientState(GL_COLOR_ARRAY);
|
|
|
|
// Setup texture
|
|
glBindTexture(GL_TEXTURE_2D, fontTex);
|
|
glEnable(GL_TEXTURE_2D);
|
|
|
|
// Setup orthographic projection matrix
|
|
const float width = ImGui::GetIO().DisplaySize.x;
|
|
const float height = ImGui::GetIO().DisplaySize.y;
|
|
glMatrixMode(GL_PROJECTION);
|
|
glLoadIdentity();
|
|
glOrtho(0.0f, width, height, 0.0f, -1.0f, +1.0f);
|
|
glMatrixMode(GL_MODELVIEW);
|
|
glLoadIdentity();
|
|
|
|
// Render command lists
|
|
for (int n = 0; n < cmd_lists_count; n++)
|
|
{
|
|
const ImDrawList* cmd_list = cmd_lists[n];
|
|
const unsigned char* vtx_buffer = (const unsigned char*)cmd_list->vtx_buffer.begin();
|
|
glVertexPointer(2, GL_FLOAT, sizeof(ImDrawVert), (void*)(vtx_buffer));
|
|
glTexCoordPointer(2, GL_FLOAT, sizeof(ImDrawVert), (void*)(vtx_buffer+8));
|
|
glColorPointer(4, GL_UNSIGNED_BYTE, sizeof(ImDrawVert), (void*)(vtx_buffer+16));
|
|
|
|
int vtx_offset = 0;
|
|
const ImDrawCmd* pcmd_end = cmd_list->commands.end();
|
|
for (const ImDrawCmd* pcmd = cmd_list->commands.begin(); pcmd != pcmd_end; pcmd++)
|
|
{
|
|
glScissor((int)pcmd->clip_rect.x, (int)(height - pcmd->clip_rect.w), (int)(pcmd->clip_rect.z - pcmd->clip_rect.x), (int)(pcmd->clip_rect.w - pcmd->clip_rect.y));
|
|
glDrawArrays(GL_TRIANGLES, vtx_offset, pcmd->vtx_count);
|
|
vtx_offset += pcmd->vtx_count;
|
|
}
|
|
}
|
|
glDisable(GL_SCISSOR_TEST);
|
|
glDisableClientState(GL_COLOR_ARRAY);
|
|
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
|
|
glDisableClientState(GL_VERTEX_ARRAY);
|
|
}
|
|
|
|
void InitGL()
|
|
{
|
|
SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 8);
|
|
SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, 8);
|
|
SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 8);
|
|
SDL_GL_SetAttribute(SDL_GL_ALPHA_SIZE, 8);
|
|
SDL_GL_SetAttribute(SDL_GL_BUFFER_SIZE, 32);
|
|
SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
|
|
SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK,
|
|
SDL_GL_CONTEXT_PROFILE_CORE);
|
|
|
|
SDL_Init(SDL_INIT_EVERYTHING);
|
|
|
|
window = SDL_CreateWindow("SDL IMGui Example.",
|
|
SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, 1280, 720,
|
|
SDL_WINDOW_OPENGL);
|
|
context = SDL_GL_CreateContext(window);
|
|
|
|
glewExperimental = GL_TRUE;
|
|
GLenum status = glewInit();
|
|
if (status != GLEW_OK) {
|
|
printf("Could not initialize GLEW!\n");
|
|
}
|
|
}
|
|
|
|
void InitImGui()
|
|
{
|
|
int w, h;
|
|
int fb_w, fb_h;
|
|
SDL_GetWindowSize(window, &w, &h);
|
|
SDL_GetWindowSize(window, &fb_w, &fb_h); // Needs to be corrected for SDL Framebuffer
|
|
mousePosScale.x = (float)fb_w / w;
|
|
mousePosScale.y = (float)fb_h / h;
|
|
|
|
ImGuiIO& io = ImGui::GetIO();
|
|
io.DisplaySize = ImVec2((float)fb_w, (float)fb_h); // Display size, in pixels. For clamping windows positions.
|
|
io.PixelCenterOffset = 0.0f; // Align OpenGL texels
|
|
|
|
io.RenderDrawListsFn = ImImpl_RenderDrawLists;
|
|
|
|
// Load font texture
|
|
glGenTextures(1, &fontTex);
|
|
glBindTexture(GL_TEXTURE_2D, fontTex);
|
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
|
|
|
// Default font (embedded in code)
|
|
const void* png_data;
|
|
unsigned int png_size;
|
|
ImGui::GetDefaultFontData(NULL, NULL, &png_data, &png_size);
|
|
int tex_x, tex_y, tex_comp;
|
|
void* tex_data = stbi_load_from_memory((const unsigned char*)png_data, (int)png_size, &tex_x, &tex_y, &tex_comp, 0);
|
|
IM_ASSERT(tex_data != NULL);
|
|
|
|
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, tex_x, tex_y, 0, GL_RGBA, GL_UNSIGNED_BYTE, tex_data);
|
|
stbi_image_free(tex_data);
|
|
}
|
|
|
|
void UpdateImGui()
|
|
{
|
|
ImGuiIO& io = ImGui::GetIO();
|
|
|
|
SDL_PumpEvents();
|
|
|
|
// Setup inputs
|
|
// (we already got mouse wheel, keyboard keys & characters from glfw callbacks polled in glfwPollEvents())
|
|
int mouse_x, mouse_y;
|
|
SDL_GetMouseState(&mouse_x, &mouse_y);
|
|
|
|
io.MousePos = ImVec2((float)mouse_x * mousePosScale.x, (float)mouse_y * mousePosScale.y); // Mouse position, in pixels (set to -1,-1 if no mouse / on another screen, etc.)
|
|
|
|
io.MouseDown[0] = mousePressed[0] || (SDL_GetMouseState(NULL, NULL) & SDL_BUTTON(SDL_BUTTON_LEFT));
|
|
io.MouseDown[1] = mousePressed[1] || (SDL_GetMouseState(NULL, NULL) & SDL_BUTTON(SDL_BUTTON_RIGHT));
|
|
|
|
// Start the frame
|
|
ImGui::NewFrame();
|
|
}
|
|
|
|
// Application code
|
|
int main(int argc, char** argv)
|
|
{
|
|
InitGL();
|
|
InitImGui();
|
|
|
|
bool running = true;
|
|
while (running) {
|
|
ImGuiIO& io = ImGui::GetIO();
|
|
mousePressed[0] = mousePressed[1] = false;
|
|
io.MouseWheel = 0;
|
|
|
|
SDL_Event event;
|
|
while (SDL_PollEvent(&event)) {
|
|
if (event.type == SDL_QUIT) {
|
|
running = false;
|
|
}
|
|
}
|
|
|
|
UpdateImGui();
|
|
|
|
ImGui::Begin("Debug");
|
|
ImGui::Text("Hello, world %d", 123);
|
|
if (ImGui::Button("OK")) {
|
|
std::cout << "Button clicked!\n";
|
|
}
|
|
ImGui::End();
|
|
|
|
// Rendering
|
|
glClearColor(0.8f, 0.6f, 0.6f, 1.0f);
|
|
glClear(GL_COLOR_BUFFER_BIT);
|
|
|
|
ImGui::Render();
|
|
|
|
GLenum error = glGetError();
|
|
if (error != GL_NO_ERROR) {
|
|
std::cout << gluErrorString(error) << std::endl;
|
|
}
|
|
|
|
SDL_GL_SwapWindow(window);
|
|
}
|
|
|
|
ImGui::Shutdown();
|
|
SDL_GL_DeleteContext(context);
|
|
SDL_DestroyWindow(window);
|
|
SDL_Quit();
|
|
return 0;
|
|
}
|