added imgui support

This commit is contained in:
Anselme 2017-04-08 11:29:17 +02:00
parent 24611e0e56
commit 1f22f90342
5 changed files with 222 additions and 1 deletions

View File

@ -16,6 +16,7 @@ file(GLOB LIB_HEAD_LIST src/*.h)
#set compilation option
set(IS_LIBRARY True)
set(USE_IMGUI True)
set(USE_OPENGL True)
add_definitions(-Wno-comment)

View File

@ -8,6 +8,7 @@
#include "shadersource.h"
#include "phongmaterial.h"
#include "camera.h"
#include "guimesh.h"
#include <resource.h>
#include <algorithm>
@ -94,6 +95,8 @@ DeferredPipeline::DeferredPipeline() :
std::string vertSource = shaderMap["shaders/posteffects.vert.glsl"];
std::string fragSource = shaderMap["shaders/posteffects.frag.glsl"];
m_postEffectsShader = new Shader(vertSource, fragSource);
m_guiMesh = new GuiMesh();
m_guiMesh->initGL();
}
bool depthCompare(const GeometryNode* firstElem, const GeometryNode* secondElem) {
@ -214,6 +217,9 @@ void DeferredPipeline::renderGL(Scene *scene)
// draw geometry
node->mesh->draw(shader);
}
// IMGUI PASS
gui.drawGL();
}
void DeferredPipeline::resizeGL(int w, int h)
@ -231,6 +237,7 @@ void DeferredPipeline::resizeGL(int w, int h)
m_gBuffer = new GBuffer(w, h);
m_lightingBuffer = new LightingBuffer(w, h);
m_orthoMatrix = glm::ortho(0.f, float(m_width), float(m_height), 0.f);
m_guiMesh->resizeGL(w, h);
}
void DeferredPipeline::setSources(ShaderSource *gBufferSource, ShaderSource *lightingSource, ShaderSource *guiSource, Shader *postEffectsShader)

View File

@ -8,6 +8,7 @@
class Shader;
class Camera;
class GuiMesh;
class GBuffer : public FrameBuffer
{
@ -45,7 +46,9 @@ class DeferredPipeline : public Pipeline
ShaderSource *m_lightingSource;
ShaderSource *m_mesh2DSource;
Shader *m_postEffectsShader; // TODELETE
GuiMesh * m_guiMesh;
// framebuffers
GBuffer *m_gBuffer;
LightingBuffer *m_lightingBuffer;

184
src/guimesh.cpp Normal file
View File

@ -0,0 +1,184 @@
#include "guimesh.h"
#include "opengl.h"
#include "imgui/imgui.h"
void GuiMesh::initGL()
{
const GLchar *vertex_shader =
"#version 330\n"
"uniform mat4 ProjMtx;\n"
"layout(location = 0)in vec2 Position;\n"
"layout(location = 1)in vec2 UV;\n"
"layout(location = 2)in vec4 Color;\n"
"out vec2 Frag_UV;\n"
"out vec4 Frag_Color;\n"
"void main()\n"
"{\n"
" Frag_UV = UV;\n"
" Frag_Color = Color;\n"
" gl_Position = ProjMtx * vec4(Position.xy,0,1);\n"
"}\n";
const GLchar* fragment_shader =
"#version 330\n"
"uniform sampler2D Texture;\n"
"in vec2 Frag_UV;\n"
"in vec4 Frag_Color;\n"
"out vec4 Out_Color;\n"
"void main()\n"
"{\n"
" Out_Color = Frag_Color * texture( Texture, Frag_UV.st);\n"
"}\n";
ShaderHandle = glCreateProgram();
VertHandle = glCreateShader(GL_VERTEX_SHADER);
FragHandle = glCreateShader(GL_FRAGMENT_SHADER);
glShaderSource(VertHandle, 1, &vertex_shader, 0);
glShaderSource(FragHandle, 1, &fragment_shader, 0);
glCompileShader(VertHandle);
glCompileShader(FragHandle);
glAttachShader(ShaderHandle, VertHandle);
glAttachShader(ShaderHandle, FragHandle);
glLinkProgram(ShaderHandle);
AttribLocationTex = glGetUniformLocation(ShaderHandle, "Texture");
AttribLocationProjMtx = glGetUniformLocation(ShaderHandle, "ProjMtx");
glGenBuffers(1, &VboHandle);
glGenBuffers(1, &ElementsHandle);
glGenVertexArrays(1, &VaoHandle);
glBindVertexArray(VaoHandle);
glBindBuffer(GL_ARRAY_BUFFER, VboHandle);
#define OFFSETOF(TYPE, ELEMENT) ((size_t)&(((TYPE *)0)->ELEMENT))
glEnableVertexAttribArray(0);
glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, sizeof(ImDrawVert), (GLvoid*)OFFSETOF(ImDrawVert, pos));
glEnableVertexAttribArray(1);
glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, sizeof(ImDrawVert), (GLvoid*)OFFSETOF(ImDrawVert, uv));
glEnableVertexAttribArray(2);
glVertexAttribPointer(2, 4, GL_UNSIGNED_BYTE, GL_TRUE, sizeof(ImDrawVert), (GLvoid*)OFFSETOF(ImDrawVert, col));
#undef OFFSETOF
// Build texture atlas
ImGuiIO& io = ImGui::GetIO();
unsigned char* pixels;
int width, height;
io.Fonts->GetTexDataAsRGBA32(&pixels, &width, &height); // Load as RGBA 32-bits (75% of the memory is wasted, but default font is so small) because it is more likely to be compatible with user's existing shaders. If your ImTextureId represent a higher-level concept than just a GL texture id, consider calling GetTexDataAsAlpha8() instead to save on GPU memory.
// Upload texture to graphics system
glGenTextures(1, &FontTexture);
glBindTexture(GL_TEXTURE_2D, 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_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixels);
// Store our identifier
io.Fonts->TexID = (void *)(intptr_t)FontTexture;
}
void GuiMesh::drawGL()
{
ImGui::Render();
ImDrawData* draw_data = ImGui::GetDrawData();
ImGuiIO& io = ImGui::GetIO();
int fb_width = (int)(io.DisplaySize.x * io.DisplayFramebufferScale.x);
int fb_height = (int)(io.DisplaySize.y * io.DisplayFramebufferScale.y);
if (fb_width == 0 || fb_height == 0)
return;
draw_data->ScaleClipRects(io.DisplayFramebufferScale);
// Setup render state: alpha-blending enabled, no face culling, no depth testing, scissor enabled
glEnable(GL_BLEND);
glBlendEquation(GL_FUNC_ADD);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glDisable(GL_CULL_FACE);
glDisable(GL_DEPTH_TEST);
glEnable(GL_SCISSOR_TEST);
glActiveTexture(GL_TEXTURE0);
// Setup viewport, orthographic projection matrix
glViewport(0, 0, (GLsizei)fb_width, (GLsizei)fb_height);
const float ortho_projection[4][4] =
{
{ 2.0f/io.DisplaySize.x, 0.0f, 0.0f, 0.0f },
{ 0.0f, 2.0f/-io.DisplaySize.y, 0.0f, 0.0f },
{ 0.0f, 0.0f, -1.0f, 0.0f },
{-1.0f, 1.0f, 0.0f, 1.0f },
};
glUseProgram(ShaderHandle);
glUniform1i(AttribLocationTex, 0);
glUniformMatrix4fv(AttribLocationProjMtx, 1, GL_FALSE, &ortho_projection[0][0]);
glBindVertexArray(VaoHandle);
for (int n = 0; n < draw_data->CmdListsCount; n++)
{
const ImDrawList* cmd_list = draw_data->CmdLists[n];
const ImDrawIdx* idx_buffer_offset = 0;
glBindBuffer(GL_ARRAY_BUFFER, VboHandle);
glBufferData(GL_ARRAY_BUFFER, (GLsizeiptr)cmd_list->VtxBuffer.Size * sizeof(ImDrawVert), (const GLvoid*)cmd_list->VtxBuffer.Data, GL_STREAM_DRAW);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ElementsHandle);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, (GLsizeiptr)cmd_list->IdxBuffer.Size * sizeof(ImDrawIdx), (const GLvoid*)cmd_list->IdxBuffer.Data, GL_STREAM_DRAW);
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_offset);
}
idx_buffer_offset += pcmd->ElemCount;
}
}
glDisable(GL_BLEND);
glEnable(GL_DEPTH_TEST);
glDisable(GL_SCISSOR_TEST);
}
void GuiMesh::resizeGL(int w, int h)
{
ImGuiIO& io = ImGui::GetIO();
width = w;
height = h;
io.DisplaySize = ImVec2(w, h);
}
void GuiMesh::destroyGL()
{
if (VaoHandle) glDeleteVertexArrays(1, &VaoHandle);
if (VboHandle) glDeleteBuffers(1, &VboHandle);
if (ElementsHandle) glDeleteBuffers(1, &ElementsHandle);
VaoHandle = VboHandle = ElementsHandle = 0;
if (ShaderHandle && VertHandle) glDetachShader(ShaderHandle, VertHandle);
if (VertHandle) glDeleteShader(VertHandle);
VertHandle = 0;
if (ShaderHandle && FragHandle) glDetachShader(ShaderHandle, FragHandle);
if (FragHandle) glDeleteShader(FragHandle);
FragHandle = 0;
if (ShaderHandle) glDeleteProgram(ShaderHandle);
ShaderHandle = 0;
if (FontTexture)
{
glDeleteTextures(1, &FontTexture);
ImGui::GetIO().Fonts->TexID = 0;
FontTexture = 0;
}
}

26
src/guimesh.h Normal file
View File

@ -0,0 +1,26 @@
#ifndef GUIMESH_H
#define GUIMESH_H
class GuiMesh
{
int ShaderHandle = 0;
int VertHandle = 0;
int FragHandle = 0;
int AttribLocationTex = 0;
int AttribLocationProjMtx = 0;
unsigned int VboHandle = 0;
unsigned int VaoHandle = 0;
unsigned int ElementsHandle = 0;
unsigned int FontTexture = 0;
unsigned int width;
unsigned int height;
public:
void initGL();
void drawGL();
void resizeGL(int w, int h);
void destroyGL();
};
#endif // GUIMESH_H