Destroyed Getting Started (markdown)
parent
3b42dcabbf
commit
0e3d63e9b3
@ -1,325 +0,0 @@
|
|||||||
** THIS PAGE WAS A PROPOSAL AND HAS NEVER BEEN UPDATED, PREFER REFERRING TO EXAMPLES/ **
|
|
||||||
|
|
||||||
\* **This page is a proposal that has been given up on** \*
|
|
||||||
\* Please refer to imgui.cpp and regular examples/ for up to date instructions \*
|
|
||||||
|
|
||||||
This article will guide you through getting up and running using GLFW with as many assumptions about your system as possible. ImGui is completely hardware/library agnostic and runs on everything, you only need to feed it with inputs and render textured triangles as output. As such, GLFW is merely used a convenient example because it is simple to use and popular.
|
|
||||||
|
|
||||||
![image](https://cloud.githubusercontent.com/assets/2152766/14699172/7591cd04-078d-11e6-83ca-7f95977dd4e8.png)
|
|
||||||
|
|
||||||
**You will learn**
|
|
||||||
|
|
||||||
- How this project is organised
|
|
||||||
- How to open a window using GLFW
|
|
||||||
- How to render an ImGui window into the GLFW window
|
|
||||||
- How to render text into the ImGui window
|
|
||||||
|
|
||||||
**You are**
|
|
||||||
|
|
||||||
- On Linux
|
|
||||||
- Using C++11
|
|
||||||
- Using OpenGL 3.3 or above, core profile
|
|
||||||
- Using clang 3.4 or above
|
|
||||||
- Using glfw 3.0 or above
|
|
||||||
|
|
||||||
<br>
|
|
||||||
<br>
|
|
||||||
<br>
|
|
||||||
|
|
||||||
### Organisation
|
|
||||||
|
|
||||||
```
|
|
||||||
| File | Description
|
|
||||||
|--------------------|--------------------
|
|
||||||
| imgui/ |
|
|
||||||
| examples/ | Some examples for various backends and windowing libraries
|
|
||||||
| extra_fonts/ | Optional assets
|
|
||||||
| imconfig.h | Configuration file
|
|
||||||
| imgui.cpp |
|
|
||||||
| imgui.h |
|
|
||||||
| imgui_demo.cpp | Demonstration code, useful to keep around, run and learn about imgui
|
|
||||||
| imgui_draw.cpp |
|
|
||||||
| imgui_internal.h | Internal details, without guarantee of backward compatibility
|
|
||||||
| stb_* | External library
|
|
||||||
```
|
|
||||||
|
|
||||||
<br>
|
|
||||||
<br>
|
|
||||||
<br>
|
|
||||||
|
|
||||||
### Layout
|
|
||||||
|
|
||||||
This is the layout of your code.
|
|
||||||
|
|
||||||
```
|
|
||||||
| Directory | Description
|
|
||||||
|---------------------|----------------------------------
|
|
||||||
| myproject/ |
|
|
||||||
| build/ | Output goes here
|
|
||||||
| include/ | Any include files you may eventually have
|
|
||||||
| ext/ | External projects
|
|
||||||
| glfw/ |
|
|
||||||
| imgui/ |
|
|
||||||
| src/ |
|
|
||||||
| main.cpp | Your single source file
|
|
||||||
| build.sh | Your build script
|
|
||||||
```
|
|
||||||
|
|
||||||
```bash
|
|
||||||
$ cd myproject/ext
|
|
||||||
$ git clone https://github.com/ocornut/imgui.git
|
|
||||||
$ git clone https://github.com/glfw/glfw.git
|
|
||||||
```
|
|
||||||
<br>
|
|
||||||
<br>
|
|
||||||
<br>
|
|
||||||
|
|
||||||
### Build
|
|
||||||
|
|
||||||
Here is how your code will be built.
|
|
||||||
|
|
||||||
```bash
|
|
||||||
$ cd myproject
|
|
||||||
$ ./build.sh
|
|
||||||
```
|
|
||||||
|
|
||||||
**build.sh**
|
|
||||||
|
|
||||||
```bash
|
|
||||||
#!/usr/bin/env bash
|
|
||||||
|
|
||||||
mkdir -p build && \
|
|
||||||
pushd build && \
|
|
||||||
clang++ \
|
|
||||||
-o main \
|
|
||||||
../ext/imgui/imgui.cpp \
|
|
||||||
../ext/imgui/imgui_draw.cpp \
|
|
||||||
../src/main.cpp \
|
|
||||||
-Wall \
|
|
||||||
-g `# Generate complete debug info` \
|
|
||||||
-std=c++11 \
|
|
||||||
-I ../include \
|
|
||||||
-I ../ext/glfw/include \
|
|
||||||
-I ../ext/imgui \
|
|
||||||
-L ../lib \
|
|
||||||
-lglfw3 \
|
|
||||||
-lGL \
|
|
||||||
-lGLU \
|
|
||||||
-lX11 \
|
|
||||||
-lXxf86vm \
|
|
||||||
-lXrandr \
|
|
||||||
-lpthread \
|
|
||||||
-lXi \
|
|
||||||
-lXinerama \
|
|
||||||
-lXcursor && \
|
|
||||||
popd || exit 1
|
|
||||||
```
|
|
||||||
|
|
||||||
<br>
|
|
||||||
<br>
|
|
||||||
<br>
|
|
||||||
|
|
||||||
### Source
|
|
||||||
|
|
||||||
Here is the source.
|
|
||||||
|
|
||||||
**main.cpp**
|
|
||||||
|
|
||||||
```cpp
|
|
||||||
// dear imgui minimal example.
|
|
||||||
|
|
||||||
#include <cstdlib>
|
|
||||||
#include "GLFW/glfw3.h"
|
|
||||||
#include "imgui.h"
|
|
||||||
|
|
||||||
void setup(GLFWwindow* window);
|
|
||||||
void renderer(ImDrawData* draw_data);
|
|
||||||
|
|
||||||
int main(void)
|
|
||||||
{
|
|
||||||
if (!glfwInit())
|
|
||||||
{
|
|
||||||
exit(EXIT_FAILURE);
|
|
||||||
}
|
|
||||||
|
|
||||||
static GLFWwindow* window {
|
|
||||||
glfwCreateWindow(320, 240, "Simple example", NULL, NULL)
|
|
||||||
};
|
|
||||||
|
|
||||||
if (!window)
|
|
||||||
{
|
|
||||||
glfwTerminate();
|
|
||||||
exit(EXIT_FAILURE);
|
|
||||||
}
|
|
||||||
|
|
||||||
glfwMakeContextCurrent(window);
|
|
||||||
|
|
||||||
// Close window on pressing ESC
|
|
||||||
glfwSetKeyCallback(window, [](GLFWwindow* window, int key, int scancode, int action, int mods) {
|
|
||||||
if (key == GLFW_KEY_ESCAPE && action == GLFW_PRESS)
|
|
||||||
glfwSetWindowShouldClose(window, GL_TRUE);
|
|
||||||
});
|
|
||||||
|
|
||||||
setup(window);
|
|
||||||
|
|
||||||
glClearColor(0.1f, 0.1f, 0.1f, 1.0f);
|
|
||||||
while (!glfwWindowShouldClose(window))
|
|
||||||
{
|
|
||||||
glClear(GL_COLOR_BUFFER_BIT);
|
|
||||||
|
|
||||||
glfwPollEvents();
|
|
||||||
|
|
||||||
// Use ImGui functions between here and Render()
|
|
||||||
ImGui::NewFrame();
|
|
||||||
|
|
||||||
// This creates a window
|
|
||||||
ImGui::Begin("Window Title Here");
|
|
||||||
ImGui::Text("Hello, world!");
|
|
||||||
ImGui::End();
|
|
||||||
|
|
||||||
// ImGui functions end here
|
|
||||||
ImGui::Render();
|
|
||||||
|
|
||||||
glfwSwapBuffers(window);
|
|
||||||
}
|
|
||||||
|
|
||||||
glfwDestroyWindow(window);
|
|
||||||
glfwTerminate();
|
|
||||||
|
|
||||||
exit(EXIT_SUCCESS);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*! /brief Initialise the ImGuiIO struct.
|
|
||||||
*
|
|
||||||
* The ImGuiIO struct is the main configuration and
|
|
||||||
* I/O between your application and ImGui.
|
|
||||||
*/
|
|
||||||
void setup(GLFWwindow* window)
|
|
||||||
{
|
|
||||||
unsigned char* pixels;
|
|
||||||
int width,
|
|
||||||
height,
|
|
||||||
display_width,
|
|
||||||
display_height;
|
|
||||||
GLuint g_FontTexture;
|
|
||||||
ImGui::CreateContext();
|
|
||||||
ImGuiIO& io { ImGui::GetIO() };
|
|
||||||
|
|
||||||
io.Fonts->GetTexDataAsAlpha8(&pixels, &width, &height);
|
|
||||||
|
|
||||||
// Upload texture to graphics system
|
|
||||||
GLint last_texture;
|
|
||||||
glGetIntegerv(GL_TEXTURE_BINDING_2D, &last_texture);
|
|
||||||
glGenTextures(1, &g_FontTexture);
|
|
||||||
glBindTexture(GL_TEXTURE_2D, g_FontTexture);
|
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
|
||||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, width, height, 0, GL_ALPHA, GL_UNSIGNED_BYTE, pixels);
|
|
||||||
|
|
||||||
// Get display size
|
|
||||||
glfwGetWindowSize(window, &width, &height);
|
|
||||||
glfwGetFramebufferSize(window, &display_width, &display_height);
|
|
||||||
|
|
||||||
io.DisplaySize = ImVec2((float)width, (float)height);
|
|
||||||
io.RenderDrawListsFn = renderer;
|
|
||||||
io.Fonts->TexID = (void *)(intptr_t)g_FontTexture;
|
|
||||||
|
|
||||||
// Restore state
|
|
||||||
glBindTexture(GL_TEXTURE_2D, last_texture);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*! /brief Boilerplate function for OpenGL 2.0 rendering.
|
|
||||||
*
|
|
||||||
* This function isn't written by us, but is mandatory
|
|
||||||
* boilerplate from the library. It can be copy/pasted
|
|
||||||
* into your projects, but should really be part of the
|
|
||||||
* library itself?
|
|
||||||
*/
|
|
||||||
void renderer(ImDrawData* draw_data)
|
|
||||||
{
|
|
||||||
ImGuiIO& io { ImGui::GetIO() };
|
|
||||||
int fb_width { (int)(io.DisplaySize.x * io.DisplayFramebufferScale.x) };
|
|
||||||
int fb_height { (int)(io.DisplaySize.y * io.DisplayFramebufferScale.y) };
|
|
||||||
|
|
||||||
draw_data->ScaleClipRects(io.DisplayFramebufferScale);
|
|
||||||
|
|
||||||
GLint last_texture; glGetIntegerv(GL_TEXTURE_BINDING_2D, &last_texture);
|
|
||||||
GLint last_viewport[4]; glGetIntegerv(GL_VIEWPORT, last_viewport);
|
|
||||||
glPushAttrib(GL_ENABLE_BIT | GL_COLOR_BUFFER_BIT | GL_TRANSFORM_BIT);
|
|
||||||
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);
|
|
||||||
glEnable(GL_TEXTURE_2D);
|
|
||||||
|
|
||||||
// Setup viewport, orthographic projection matrix
|
|
||||||
glViewport(0, 0, (GLsizei)fb_width, (GLsizei)fb_height);
|
|
||||||
glMatrixMode(GL_PROJECTION);
|
|
||||||
glPushMatrix();
|
|
||||||
glLoadIdentity();
|
|
||||||
glOrtho(0.0f, io.DisplaySize.x, io.DisplaySize.y, 0.0f, -1.0f, +1.0f);
|
|
||||||
glMatrixMode(GL_MODELVIEW);
|
|
||||||
glPushMatrix();
|
|
||||||
glLoadIdentity();
|
|
||||||
|
|
||||||
// Render command lists
|
|
||||||
#define OFFSETOF(TYPE, ELEMENT) ((size_t)&(((TYPE *)0)->ELEMENT))
|
|
||||||
for (int n = 0; n < draw_data->CmdListsCount; n++)
|
|
||||||
{
|
|
||||||
const ImDrawList* cmd_list = draw_data->CmdLists[n];
|
|
||||||
const unsigned char* vtx_buffer = (const unsigned char*)&cmd_list->VtxBuffer.front();
|
|
||||||
const ImDrawIdx* idx_buffer = &cmd_list->IdxBuffer.front();
|
|
||||||
glVertexPointer(2, GL_FLOAT, sizeof(ImDrawVert), (void*)(vtx_buffer + OFFSETOF(ImDrawVert, pos)));
|
|
||||||
glTexCoordPointer(2, GL_FLOAT, sizeof(ImDrawVert), (void*)(vtx_buffer + OFFSETOF(ImDrawVert, uv)));
|
|
||||||
glColorPointer(4, GL_UNSIGNED_BYTE, sizeof(ImDrawVert), (void*)(vtx_buffer + OFFSETOF(ImDrawVert, col)));
|
|
||||||
|
|
||||||
for (int cmd_i = 0; cmd_i < cmd_list->CmdBuffer.size(); cmd_i++)
|
|
||||||
{
|
|
||||||
const ImDrawCmd* pcmd = &cmd_list->CmdBuffer[cmd_i];
|
|
||||||
if (pcmd->UserCallback)
|
|
||||||
{
|
|
||||||
pcmd->UserCallback(cmd_list, pcmd);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
glBindTexture(GL_TEXTURE_2D, (GLuint)(intptr_t)pcmd->TextureId);
|
|
||||||
glScissor((int)pcmd->ClipRect.x, (int)(fb_height - pcmd->ClipRect.w), (int)(pcmd->ClipRect.z - pcmd->ClipRect.x), (int)(pcmd->ClipRect.w - pcmd->ClipRect.y));
|
|
||||||
glDrawElements(GL_TRIANGLES, (GLsizei)pcmd->ElemCount, sizeof(ImDrawIdx) == 2 ? GL_UNSIGNED_SHORT : GL_UNSIGNED_INT, idx_buffer);
|
|
||||||
}
|
|
||||||
idx_buffer += pcmd->ElemCount;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#undef OFFSETOF
|
|
||||||
|
|
||||||
// Restore modified state
|
|
||||||
glDisableClientState(GL_COLOR_ARRAY);
|
|
||||||
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
|
|
||||||
glDisableClientState(GL_VERTEX_ARRAY);
|
|
||||||
glBindTexture(GL_TEXTURE_2D, last_texture);
|
|
||||||
glMatrixMode(GL_MODELVIEW);
|
|
||||||
glPopMatrix();
|
|
||||||
glMatrixMode(GL_PROJECTION);
|
|
||||||
glPopMatrix();
|
|
||||||
glPopAttrib();
|
|
||||||
glViewport(last_viewport[0], last_viewport[1], (GLsizei)last_viewport[2], (GLsizei)last_viewport[3]);
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
<br>
|
|
||||||
<br>
|
|
||||||
<br>
|
|
||||||
|
|
||||||
#### TODO
|
|
||||||
|
|
||||||
Here are some ideas for how to improve and shorten this article.
|
|
||||||
|
|
||||||
- Add screenshot of result
|
|
||||||
- Reduce requirements, such as C++11
|
|
||||||
- Increase compatibility, such as including a cl.exe build script.
|
|
||||||
- Remove lines that aren't absolutely critical
|
|
||||||
- Remove `renderer()` - Seems unnecessary and better included with ImGui?
|
|
||||||
- Remove need to manually upload texture to GPU in `setup()`, can/should be included in ImGui?
|
|
Loading…
Reference in New Issue
Block a user