Examples: DirectX10, DirectX11, OpenGL2, OpenGL3: Added support for io.DisplayPos.

This commit is contained in:
omar 2018-02-18 21:09:28 +01:00
parent 45cbebad64
commit 3bd3693fb7
4 changed files with 73 additions and 27 deletions

View File

@ -10,6 +10,7 @@
// CHANGELOG // CHANGELOG
// (minor and older changes stripped away, please see git history for details) // (minor and older changes stripped away, please see git history for details)
// 2018-XX-XX: Draw: Offset projection matrix and clipping rectangle by io.DisplayPos (which will be non-zero for multi-viewport applications).
// 2018-02-16: Misc: Obsoleted the io.RenderDrawListsFn callback and exposed ImGui_ImplDX10_RenderDrawData() in the .h file so you can call it yourself. // 2018-02-16: Misc: Obsoleted the io.RenderDrawListsFn callback and exposed ImGui_ImplDX10_RenderDrawData() in the .h file so you can call it yourself.
// 2018-02-06: Misc: Removed call to ImGui::Shutdown() which is not available from 1.60 WIP, user needs to call CreateContext/DestroyContext themselves. // 2018-02-06: Misc: Removed call to ImGui::Shutdown() which is not available from 1.60 WIP, user needs to call CreateContext/DestroyContext themselves.
// 2018-02-06: Inputs: Added mapping for ImGuiKey_Space. // 2018-02-06: Inputs: Added mapping for ImGuiKey_Space.
@ -105,15 +106,17 @@ void ImGui_ImplDX10_RenderDrawData(ImDrawData* draw_data)
g_pIB->Unmap(); g_pIB->Unmap();
// Setup orthographic projection matrix into our constant buffer // Setup orthographic projection matrix into our constant buffer
// Our visible imgui space lies from io.DisplayPos (top left) to io.DisplayPos+io.DisplaySize (bottom right). io.DisplayPos is typically (0,0) for single viewport applications.
ImGuiIO& io = ImGui::GetIO();
{ {
void* mapped_resource; void* mapped_resource;
if (g_pVertexConstantBuffer->Map(D3D10_MAP_WRITE_DISCARD, 0, &mapped_resource) != S_OK) if (g_pVertexConstantBuffer->Map(D3D10_MAP_WRITE_DISCARD, 0, &mapped_resource) != S_OK)
return; return;
VERTEX_CONSTANT_BUFFER* constant_buffer = (VERTEX_CONSTANT_BUFFER*)mapped_resource; VERTEX_CONSTANT_BUFFER* constant_buffer = (VERTEX_CONSTANT_BUFFER*)mapped_resource;
float L = 0.0f; float L = io.DisplayPos.x;
float R = ImGui::GetIO().DisplaySize.x; float R = io.DisplayPos.x + io.DisplaySize.x;
float B = ImGui::GetIO().DisplaySize.y; float T = io.DisplayPos.y;
float T = 0.0f; float B = io.DisplayPos.y + io.DisplaySize.y;
float mvp[4][4] = float mvp[4][4] =
{ {
{ 2.0f/(R-L), 0.0f, 0.0f, 0.0f }, { 2.0f/(R-L), 0.0f, 0.0f, 0.0f },
@ -167,8 +170,8 @@ void ImGui_ImplDX10_RenderDrawData(ImDrawData* draw_data)
// Setup viewport // Setup viewport
D3D10_VIEWPORT vp; D3D10_VIEWPORT vp;
memset(&vp, 0, sizeof(D3D10_VIEWPORT)); memset(&vp, 0, sizeof(D3D10_VIEWPORT));
vp.Width = (UINT)ImGui::GetIO().DisplaySize.x; vp.Width = (UINT)io.DisplaySize.x;
vp.Height = (UINT)ImGui::GetIO().DisplaySize.y; vp.Height = (UINT)io.DisplaySize.y;
vp.MinDepth = 0.0f; vp.MinDepth = 0.0f;
vp.MaxDepth = 1.0f; vp.MaxDepth = 1.0f;
vp.TopLeftX = vp.TopLeftY = 0; vp.TopLeftX = vp.TopLeftY = 0;
@ -203,13 +206,18 @@ void ImGui_ImplDX10_RenderDrawData(ImDrawData* draw_data)
const ImDrawCmd* pcmd = &cmd_list->CmdBuffer[cmd_i]; const ImDrawCmd* pcmd = &cmd_list->CmdBuffer[cmd_i];
if (pcmd->UserCallback) if (pcmd->UserCallback)
{ {
// User callback (registered via ImDrawList::AddCallback)
pcmd->UserCallback(cmd_list, pcmd); pcmd->UserCallback(cmd_list, pcmd);
} }
else else
{ {
const D3D10_RECT r = { (LONG)pcmd->ClipRect.x, (LONG)pcmd->ClipRect.y, (LONG)pcmd->ClipRect.z, (LONG)pcmd->ClipRect.w }; // Apply scissor/clipping rectangle
const ImVec4 clip_rect = ImVec4(pcmd->ClipRect.x - io.DisplayPos.x, pcmd->ClipRect.y - io.DisplayPos.y, pcmd->ClipRect.z - io.DisplayPos.x, pcmd->ClipRect.w - io.DisplayPos.y);
const D3D10_RECT clip_rect_dx = { (LONG)clip_rect.x, (LONG)clip_rect.y, (LONG)clip_rect.z, (LONG)clip_rect.w };
ctx->RSSetScissorRects(1, &clip_rect_dx);
// Bind texture, Draw
ctx->PSSetShaderResources(0, 1, (ID3D10ShaderResourceView**)&pcmd->TextureId); ctx->PSSetShaderResources(0, 1, (ID3D10ShaderResourceView**)&pcmd->TextureId);
ctx->RSSetScissorRects(1, &r);
ctx->DrawIndexed(pcmd->ElemCount, idx_offset, vtx_offset); ctx->DrawIndexed(pcmd->ElemCount, idx_offset, vtx_offset);
} }
idx_offset += pcmd->ElemCount; idx_offset += pcmd->ElemCount;

View File

@ -10,6 +10,7 @@
// CHANGELOG // CHANGELOG
// (minor and older changes stripped away, please see git history for details) // (minor and older changes stripped away, please see git history for details)
// 2018-XX-XX: Draw: Offset projection matrix and clipping rectangle by io.DisplayPos (which will be non-zero for multi-viewport applications).
// 2018-02-16: Misc: Obsoleted the io.RenderDrawListsFn callback and exposed ImGui_ImplDX11_RenderDrawData() in the .h file so you can call it yourself. // 2018-02-16: Misc: Obsoleted the io.RenderDrawListsFn callback and exposed ImGui_ImplDX11_RenderDrawData() in the .h file so you can call it yourself.
// 2018-02-06: Misc: Removed call to ImGui::Shutdown() which is not available from 1.60 WIP, user needs to call CreateContext/DestroyContext themselves. // 2018-02-06: Misc: Removed call to ImGui::Shutdown() which is not available from 1.60 WIP, user needs to call CreateContext/DestroyContext themselves.
// 2018-02-06: Inputs: Added mapping for ImGuiKey_Space. // 2018-02-06: Inputs: Added mapping for ImGuiKey_Space.
@ -107,15 +108,17 @@ void ImGui_ImplDX11_RenderDrawData(ImDrawData* draw_data)
ctx->Unmap(g_pIB, 0); ctx->Unmap(g_pIB, 0);
// Setup orthographic projection matrix into our constant buffer // Setup orthographic projection matrix into our constant buffer
// Our visible imgui space lies from io.DisplayPos (top left) to io.DisplayPos+io.DisplaySize (bottom right). io.DisplayPos is typically (0,0) for single viewport applications.
ImGuiIO& io = ImGui::GetIO();
{ {
D3D11_MAPPED_SUBRESOURCE mapped_resource; D3D11_MAPPED_SUBRESOURCE mapped_resource;
if (ctx->Map(g_pVertexConstantBuffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &mapped_resource) != S_OK) if (ctx->Map(g_pVertexConstantBuffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &mapped_resource) != S_OK)
return; return;
VERTEX_CONSTANT_BUFFER* constant_buffer = (VERTEX_CONSTANT_BUFFER*)mapped_resource.pData; VERTEX_CONSTANT_BUFFER* constant_buffer = (VERTEX_CONSTANT_BUFFER*)mapped_resource.pData;
float L = 0.0f; float L = io.DisplayPos.x;
float R = ImGui::GetIO().DisplaySize.x; float R = io.DisplayPos.x + io.DisplaySize.x;
float B = ImGui::GetIO().DisplaySize.y; float T = io.DisplayPos.y;
float T = 0.0f; float B = io.DisplayPos.y + io.DisplaySize.y;
float mvp[4][4] = float mvp[4][4] =
{ {
{ 2.0f/(R-L), 0.0f, 0.0f, 0.0f }, { 2.0f/(R-L), 0.0f, 0.0f, 0.0f },
@ -172,8 +175,8 @@ void ImGui_ImplDX11_RenderDrawData(ImDrawData* draw_data)
// Setup viewport // Setup viewport
D3D11_VIEWPORT vp; D3D11_VIEWPORT vp;
memset(&vp, 0, sizeof(D3D11_VIEWPORT)); memset(&vp, 0, sizeof(D3D11_VIEWPORT));
vp.Width = ImGui::GetIO().DisplaySize.x; vp.Width = io.DisplaySize.x;
vp.Height = ImGui::GetIO().DisplaySize.y; vp.Height = io.DisplaySize.y;
vp.MinDepth = 0.0f; vp.MinDepth = 0.0f;
vp.MaxDepth = 1.0f; vp.MaxDepth = 1.0f;
vp.TopLeftX = vp.TopLeftY = 0; vp.TopLeftX = vp.TopLeftY = 0;
@ -208,13 +211,18 @@ void ImGui_ImplDX11_RenderDrawData(ImDrawData* draw_data)
const ImDrawCmd* pcmd = &cmd_list->CmdBuffer[cmd_i]; const ImDrawCmd* pcmd = &cmd_list->CmdBuffer[cmd_i];
if (pcmd->UserCallback) if (pcmd->UserCallback)
{ {
// User callback (registered via ImDrawList::AddCallback)
pcmd->UserCallback(cmd_list, pcmd); pcmd->UserCallback(cmd_list, pcmd);
} }
else else
{ {
const D3D11_RECT r = { (LONG)pcmd->ClipRect.x, (LONG)pcmd->ClipRect.y, (LONG)pcmd->ClipRect.z, (LONG)pcmd->ClipRect.w }; // Apply scissor/clipping rectangle
const ImVec4 clip_rect = ImVec4(pcmd->ClipRect.x - io.DisplayPos.x, pcmd->ClipRect.y - io.DisplayPos.y, pcmd->ClipRect.z - io.DisplayPos.x, pcmd->ClipRect.w - io.DisplayPos.y);
const D3D11_RECT clip_rect_dx = { (LONG)clip_rect.x, (LONG)clip_rect.y, (LONG)clip_rect.z, (LONG)clip_rect.w };
ctx->RSSetScissorRects(1, &clip_rect_dx);
// Bind texture, Draw
ctx->PSSetShaderResources(0, 1, (ID3D11ShaderResourceView**)&pcmd->TextureId); ctx->PSSetShaderResources(0, 1, (ID3D11ShaderResourceView**)&pcmd->TextureId);
ctx->RSSetScissorRects(1, &r);
ctx->DrawIndexed(pcmd->ElemCount, idx_offset, vtx_offset); ctx->DrawIndexed(pcmd->ElemCount, idx_offset, vtx_offset);
} }
idx_offset += pcmd->ElemCount; idx_offset += pcmd->ElemCount;

View File

@ -6,6 +6,10 @@
// confuse your GPU driver. // confuse your GPU driver.
// The GL2 code is unable to reset attributes or even call e.g. "glUseProgram(0)" because they don't exist in that API. // The GL2 code is unable to reset attributes or even call e.g. "glUseProgram(0)" because they don't exist in that API.
// CHANGELOG
// (minor and older changes stripped away, please see git history for details)
// 2018-XX-XX: Draw: Offset projection matrix and clipping rectangle by io.DisplayPos (which will be non-zero for multi-viewport applications).
#include "imgui.h" #include "imgui.h"
#include "imgui_impl_opengl2.h" #include "imgui_impl_opengl2.h"
@ -75,11 +79,12 @@ void ImGui_ImplOpenGL2_RenderDrawData(ImDrawData* draw_data)
//glUseProgram(0); // You may want this if using this code in an OpenGL 3+ context where shaders may be bound //glUseProgram(0); // You may want this if using this code in an OpenGL 3+ context where shaders may be bound
// Setup viewport, orthographic projection matrix // Setup viewport, orthographic projection matrix
// Our visible imgui space lies from io.DisplayPos (top left) to io.DisplayPos+io.DisplaySize (bottom right). io.DisplayPos is typically (0,0) for single viewport applications.
glViewport(0, 0, (GLsizei)fb_width, (GLsizei)fb_height); glViewport(0, 0, (GLsizei)fb_width, (GLsizei)fb_height);
glMatrixMode(GL_PROJECTION); glMatrixMode(GL_PROJECTION);
glPushMatrix(); glPushMatrix();
glLoadIdentity(); glLoadIdentity();
glOrtho(0.0f, io.DisplaySize.x, io.DisplaySize.y, 0.0f, -1.0f, +1.0f); glOrtho(io.DisplayPos.x, io.DisplayPos.x + io.DisplaySize.x, io.DisplayPos.y + io.DisplaySize.y, io.DisplayPos.y, -1.0f, +1.0f);
glMatrixMode(GL_MODELVIEW); glMatrixMode(GL_MODELVIEW);
glPushMatrix(); glPushMatrix();
glLoadIdentity(); glLoadIdentity();
@ -99,13 +104,21 @@ void ImGui_ImplOpenGL2_RenderDrawData(ImDrawData* draw_data)
const ImDrawCmd* pcmd = &cmd_list->CmdBuffer[cmd_i]; const ImDrawCmd* pcmd = &cmd_list->CmdBuffer[cmd_i];
if (pcmd->UserCallback) if (pcmd->UserCallback)
{ {
// User callback (registered via ImDrawList::AddCallback)
pcmd->UserCallback(cmd_list, pcmd); pcmd->UserCallback(cmd_list, pcmd);
} }
else else
{ {
glBindTexture(GL_TEXTURE_2D, (GLuint)(intptr_t)pcmd->TextureId); ImVec4 clip_rect = ImVec4(pcmd->ClipRect.x - io.DisplayPos.x, pcmd->ClipRect.y - io.DisplayPos.y, pcmd->ClipRect.z - io.DisplayPos.x, pcmd->ClipRect.w - io.DisplayPos.y);
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)); if (clip_rect.x < fb_width && clip_rect.y < fb_height && clip_rect.z >= 0.0f && clip_rect.w >= 0.0f)
glDrawElements(GL_TRIANGLES, (GLsizei)pcmd->ElemCount, sizeof(ImDrawIdx) == 2 ? GL_UNSIGNED_SHORT : GL_UNSIGNED_INT, idx_buffer); {
// Apply scissor/clipping rectangle
glScissor((int)clip_rect.x, (int)(fb_height - clip_rect.w), (int)(clip_rect.z - clip_rect.x), (int)(clip_rect.w - clip_rect.y));
// Bind texture, Draw
glBindTexture(GL_TEXTURE_2D, (GLuint)(intptr_t)pcmd->TextureId);
glDrawElements(GL_TRIANGLES, (GLsizei)pcmd->ElemCount, sizeof(ImDrawIdx) == 2 ? GL_UNSIGNED_SHORT : GL_UNSIGNED_INT, idx_buffer);
}
} }
idx_buffer += pcmd->ElemCount; idx_buffer += pcmd->ElemCount;
} }

View File

@ -1,3 +1,7 @@
// CHANGELOG
// (minor and older changes stripped away, please see git history for details)
// 2018-XX-XX: Draw: Offset projection matrix and clipping rectangle by io.DisplayPos (which will be non-zero for multi-viewport applications).
#include "imgui.h" #include "imgui.h"
#include "imgui_impl_opengl3.h" #include "imgui_impl_opengl3.h"
#include <GL/gl3w.h> // This example is using gl3w to access OpenGL functions (because it is small). You may use glew/glad/glLoadGen/etc. whatever already works for you. #include <GL/gl3w.h> // This example is using gl3w to access OpenGL functions (because it is small). You may use glew/glad/glLoadGen/etc. whatever already works for you.
@ -72,13 +76,18 @@ void ImGui_ImplOpenGL3_RenderDrawData(ImDrawData* draw_data)
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
// Setup viewport, orthographic projection matrix // Setup viewport, orthographic projection matrix
// Our visible imgui space lies from io.DisplayPos (top left) to io.DisplayPos+io.DisplaySize (bottom right). io.DisplayPos is typically (0,0) for single viewport applications.
glViewport(0, 0, (GLsizei)fb_width, (GLsizei)fb_height); glViewport(0, 0, (GLsizei)fb_width, (GLsizei)fb_height);
float L = io.DisplayPos.x;
float R = io.DisplayPos.x + io.DisplaySize.x;
float T = io.DisplayPos.y;
float B = io.DisplayPos.y + io.DisplaySize.y;
const float ortho_projection[4][4] = const float ortho_projection[4][4] =
{ {
{ 2.0f/io.DisplaySize.x, 0.0f, 0.0f, 0.0f }, { 2.0f/(R-L), 0.0f, 0.0f, 0.0f },
{ 0.0f, 2.0f/-io.DisplaySize.y, 0.0f, 0.0f }, { 0.0f, 2.0f/(T-B), 0.0f, 0.0f },
{ 0.0f, 0.0f, -1.0f, 0.0f }, { 0.0f, 0.0f, -1.0f, 0.0f },
{ -1.0f, 1.0f, 0.0f, 1.0f }, { (R+L)/(L-R), (T+B)/(B-T), 0.0f, 1.0f },
}; };
glUseProgram(g_ShaderHandle); glUseProgram(g_ShaderHandle);
glUniform1i(g_AttribLocationTex, 0); glUniform1i(g_AttribLocationTex, 0);
@ -102,13 +111,21 @@ void ImGui_ImplOpenGL3_RenderDrawData(ImDrawData* draw_data)
const ImDrawCmd* pcmd = &cmd_list->CmdBuffer[cmd_i]; const ImDrawCmd* pcmd = &cmd_list->CmdBuffer[cmd_i];
if (pcmd->UserCallback) if (pcmd->UserCallback)
{ {
// User callback (registered via ImDrawList::AddCallback)
pcmd->UserCallback(cmd_list, pcmd); pcmd->UserCallback(cmd_list, pcmd);
} }
else else
{ {
glBindTexture(GL_TEXTURE_2D, (GLuint)(intptr_t)pcmd->TextureId); ImVec4 clip_rect = ImVec4(pcmd->ClipRect.x - io.DisplayPos.x, pcmd->ClipRect.y - io.DisplayPos.y, pcmd->ClipRect.z - io.DisplayPos.x, pcmd->ClipRect.w - io.DisplayPos.y);
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)); if (clip_rect.x < fb_width && clip_rect.y < fb_height && clip_rect.z >= 0.0f && clip_rect.w >= 0.0f)
glDrawElements(GL_TRIANGLES, (GLsizei)pcmd->ElemCount, sizeof(ImDrawIdx) == 2 ? GL_UNSIGNED_SHORT : GL_UNSIGNED_INT, idx_buffer_offset); {
// Apply scissor/clipping rectangle
glScissor((int)clip_rect.x, (int)(fb_height - clip_rect.w), (int)(clip_rect.z - clip_rect.x), (int)(clip_rect.w - clip_rect.y));
// Bind texture, Draw
glBindTexture(GL_TEXTURE_2D, (GLuint)(intptr_t)pcmd->TextureId);
glDrawElements(GL_TRIANGLES, (GLsizei)pcmd->ElemCount, sizeof(ImDrawIdx) == 2 ? GL_UNSIGNED_SHORT : GL_UNSIGNED_INT, idx_buffer_offset);
}
} }
idx_buffer_offset += pcmd->ElemCount; idx_buffer_offset += pcmd->ElemCount;
} }