Merge remote-tracking branch 'origin' into 2015-03-antialiased-primitives

Conflicts:
	imgui.cpp
	imgui.h
This commit is contained in:
ocornut 2015-04-09 21:38:30 +01:00
commit 39445cf23a
4 changed files with 131 additions and 105 deletions

View File

@ -29,13 +29,6 @@ static ID3D11ShaderResourceView*g_pFontTextureView = NULL;
static ID3D11BlendState* g_blendState = NULL; static ID3D11BlendState* g_blendState = NULL;
static int VERTEX_BUFFER_SIZE = 30000; // TODO: Make vertex buffer smaller and grow dynamically as needed. static int VERTEX_BUFFER_SIZE = 30000; // TODO: Make vertex buffer smaller and grow dynamically as needed.
struct CUSTOMVERTEX
{
float pos[2];
float uv[2];
unsigned int col;
};
struct VERTEX_CONSTANT_BUFFER struct VERTEX_CONSTANT_BUFFER
{ {
float mvp[4][4]; float mvp[4][4];
@ -50,21 +43,13 @@ static void ImGui_ImplDX11_RenderDrawLists(ImDrawList** const cmd_lists, int cmd
D3D11_MAPPED_SUBRESOURCE mappedResource; D3D11_MAPPED_SUBRESOURCE mappedResource;
if (g_pd3dDeviceContext->Map(g_pVB, 0, D3D11_MAP_WRITE_DISCARD, 0, &mappedResource) != S_OK) if (g_pd3dDeviceContext->Map(g_pVB, 0, D3D11_MAP_WRITE_DISCARD, 0, &mappedResource) != S_OK)
return; return;
CUSTOMVERTEX* vtx_dst = (CUSTOMVERTEX*)mappedResource.pData; ImDrawVert* vtx_dst = (ImDrawVert*)mappedResource.pData;
for (int n = 0; n < cmd_lists_count; n++) for (int n = 0; n < cmd_lists_count; n++)
{ {
const ImDrawList* cmd_list = cmd_lists[n]; const ImDrawList* cmd_list = cmd_lists[n];
const ImDrawVert* vtx_src = &cmd_list->vtx_buffer[0]; const ImDrawVert* vtx_src = &cmd_list->vtx_buffer[0];
for (size_t i = 0; i < cmd_list->vtx_buffer.size(); i++) memcpy(vtx_dst, vtx_src, cmd_list->vtx_buffer.size() * sizeof(ImDrawVert));
{ vtx_dst += cmd_list->vtx_buffer.size();
vtx_dst->pos[0] = vtx_src->pos.x;
vtx_dst->pos[1] = vtx_src->pos.y;
vtx_dst->uv[0] = vtx_src->uv.x;
vtx_dst->uv[1] = vtx_src->uv.y;
vtx_dst->col = vtx_src->col;
vtx_dst++;
vtx_src++;
}
} }
g_pd3dDeviceContext->Unmap(g_pVB, 0); g_pd3dDeviceContext->Unmap(g_pVB, 0);
@ -104,7 +89,7 @@ static void ImGui_ImplDX11_RenderDrawLists(ImDrawList** const cmd_lists, int cmd
} }
// Bind shader and vertex buffers // Bind shader and vertex buffers
unsigned int stride = sizeof(CUSTOMVERTEX); unsigned int stride = sizeof(ImDrawVert);
unsigned int offset = 0; unsigned int offset = 0;
g_pd3dDeviceContext->IASetInputLayout(g_pInputLayout); g_pd3dDeviceContext->IASetInputLayout(g_pInputLayout);
g_pd3dDeviceContext->IASetVertexBuffers(0, 1, &g_pVB, &stride, &offset); g_pd3dDeviceContext->IASetVertexBuffers(0, 1, &g_pVB, &stride, &offset);
@ -293,9 +278,9 @@ bool ImGui_ImplDX11_CreateDeviceObjects()
// Create the input layout // Create the input layout
D3D11_INPUT_ELEMENT_DESC localLayout[] = { D3D11_INPUT_ELEMENT_DESC localLayout[] = {
{ "POSITION", 0, DXGI_FORMAT_R32G32B32A32_FLOAT, 0, (size_t)(&((CUSTOMVERTEX*)0)->pos), D3D11_INPUT_PER_VERTEX_DATA, 0 }, { "POSITION", 0, DXGI_FORMAT_R32G32B32A32_FLOAT, 0, (size_t)(&((ImDrawVert*)0)->pos), D3D11_INPUT_PER_VERTEX_DATA, 0 },
{ "COLOR", 0, DXGI_FORMAT_R8G8B8A8_UNORM, 0, (size_t)(&((CUSTOMVERTEX*)0)->col), D3D11_INPUT_PER_VERTEX_DATA, 0 }, { "TEXCOORD", 0, DXGI_FORMAT_R32G32_FLOAT, 0, (size_t)(&((ImDrawVert*)0)->uv), D3D11_INPUT_PER_VERTEX_DATA, 0 },
{ "TEXCOORD", 0, DXGI_FORMAT_R32G32_FLOAT, 0, (size_t)(&((CUSTOMVERTEX*)0)->uv), D3D11_INPUT_PER_VERTEX_DATA, 0 }, { "COLOR", 0, DXGI_FORMAT_R8G8B8A8_UNORM, 0, (size_t)(&((ImDrawVert*)0)->col), D3D11_INPUT_PER_VERTEX_DATA, 0 },
}; };
if (g_pd3dDevice->CreateInputLayout(localLayout, 3, g_pVertexShaderBlob->GetBufferPointer(), g_pVertexShaderBlob->GetBufferSize(), &g_pInputLayout) != S_OK) if (g_pd3dDevice->CreateInputLayout(localLayout, 3, g_pVertexShaderBlob->GetBufferPointer(), g_pVertexShaderBlob->GetBufferSize(), &g_pInputLayout) != S_OK)
@ -359,7 +344,7 @@ bool ImGui_ImplDX11_CreateDeviceObjects()
D3D11_BUFFER_DESC bufferDesc; D3D11_BUFFER_DESC bufferDesc;
memset(&bufferDesc, 0, sizeof(D3D11_BUFFER_DESC)); memset(&bufferDesc, 0, sizeof(D3D11_BUFFER_DESC));
bufferDesc.Usage = D3D11_USAGE_DYNAMIC; bufferDesc.Usage = D3D11_USAGE_DYNAMIC;
bufferDesc.ByteWidth = VERTEX_BUFFER_SIZE * sizeof(CUSTOMVERTEX); bufferDesc.ByteWidth = VERTEX_BUFFER_SIZE * sizeof(ImDrawVert);
bufferDesc.BindFlags = D3D11_BIND_VERTEX_BUFFER; bufferDesc.BindFlags = D3D11_BIND_VERTEX_BUFFER;
bufferDesc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE; bufferDesc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
bufferDesc.MiscFlags = 0; bufferDesc.MiscFlags = 0;

View File

@ -23,7 +23,7 @@ static GLuint g_FontTexture = 0;
static int g_ShaderHandle = 0, g_VertHandle = 0, g_FragHandle = 0; static int g_ShaderHandle = 0, g_VertHandle = 0, g_FragHandle = 0;
static int g_AttribLocationTex = 0, g_AttribLocationProjMtx = 0; static int g_AttribLocationTex = 0, g_AttribLocationProjMtx = 0;
static int g_AttribLocationPosition = 0, g_AttribLocationUV = 0, g_AttribLocationColor = 0; static int g_AttribLocationPosition = 0, g_AttribLocationUV = 0, g_AttribLocationColor = 0;
static size_t g_VboMaxSize = 20000; static size_t g_VboSize = 0;
static unsigned int g_VboHandle = 0, g_VaoHandle = 0; static unsigned int g_VboHandle = 0, g_VaoHandle = 0;
// This is the main rendering function that you have to implement and provide to ImGui (via setting up 'RenderDrawListsFn' in the ImGuiIO structure) // This is the main rendering function that you have to implement and provide to ImGui (via setting up 'RenderDrawListsFn' in the ImGuiIO structure)
@ -62,11 +62,11 @@ static void ImGui_ImplGlfwGL3_RenderDrawLists(ImDrawList** const cmd_lists, int
for (int n = 0; n < cmd_lists_count; n++) for (int n = 0; n < cmd_lists_count; n++)
total_vtx_count += cmd_lists[n]->vtx_buffer.size(); total_vtx_count += cmd_lists[n]->vtx_buffer.size();
glBindBuffer(GL_ARRAY_BUFFER, g_VboHandle); glBindBuffer(GL_ARRAY_BUFFER, g_VboHandle);
size_t neededBufferSize = total_vtx_count * sizeof(ImDrawVert); size_t needed_vtx_size = total_vtx_count * sizeof(ImDrawVert);
if (neededBufferSize > g_VboMaxSize) if (g_VboSize < needed_vtx_size)
{ {
g_VboMaxSize = neededBufferSize + 5000; // Grow buffer g_VboSize = needed_vtx_size + 5000 * sizeof(ImDrawVert); // Grow buffer
glBufferData(GL_ARRAY_BUFFER, g_VboMaxSize, NULL, GL_STREAM_DRAW); glBufferData(GL_ARRAY_BUFFER, g_VboSize, NULL, GL_STREAM_DRAW);
} }
// Copy and convert all vertices into a single contiguous buffer // Copy and convert all vertices into a single contiguous buffer
@ -217,8 +217,6 @@ bool ImGui_ImplGlfwGL3_CreateDeviceObjects()
g_AttribLocationColor = glGetAttribLocation(g_ShaderHandle, "Color"); g_AttribLocationColor = glGetAttribLocation(g_ShaderHandle, "Color");
glGenBuffers(1, &g_VboHandle); glGenBuffers(1, &g_VboHandle);
glBindBuffer(GL_ARRAY_BUFFER, g_VboHandle);
glBufferData(GL_ARRAY_BUFFER, g_VboMaxSize, NULL, GL_DYNAMIC_DRAW);
glGenVertexArrays(1, &g_VaoHandle); glGenVertexArrays(1, &g_VaoHandle);
glBindVertexArray(g_VaoHandle); glBindVertexArray(g_VaoHandle);

153
imgui.cpp
View File

@ -142,6 +142,7 @@
Occasionally introducing changes that are breaking the API. The breakage are generally minor and easy to fix. Occasionally introducing changes that are breaking the API. The breakage are generally minor and easy to fix.
Here is a change-log of API breaking changes, if you are using one of the functions listed, expect to have to fix some code. Here is a change-log of API breaking changes, if you are using one of the functions listed, expect to have to fix some code.
- 2015/04/09 (1.38) - renamed ImDrawList::AddArc() to ImDrawList::AddArcFast() for compatibility with future API
- 2015/04/03 (1.38) - removed ImGuiCol_CheckHovered, ImGuiCol_CheckActive, replaced with the more general ImGuiCol_FrameBgHovered, ImGuiCol_FrameBgActive. - 2015/04/03 (1.38) - removed ImGuiCol_CheckHovered, ImGuiCol_CheckActive, replaced with the more general ImGuiCol_FrameBgHovered, ImGuiCol_FrameBgActive.
- 2014/04/03 (1.38) - removed support for passing -FLT_MAX..+FLT_MAX as the range for a SliderFloat(). Use DragFloat() or Inputfloat() instead. - 2014/04/03 (1.38) - removed support for passing -FLT_MAX..+FLT_MAX as the range for a SliderFloat(). Use DragFloat() or Inputfloat() instead.
- 2015/03/17 (1.36) - renamed GetItemRectMin()/GetItemRectMax()/IsMouseHoveringBox() to GetItemRectMin()/GetItemRectMax()/IsMouseHoveringRect(). Kept inline redirection function (will obsolete). - 2015/03/17 (1.36) - renamed GetItemRectMin()/GetItemRectMax()/IsMouseHoveringBox() to GetItemRectMin()/GetItemRectMax()/IsMouseHoveringRect(). Kept inline redirection function (will obsolete).
@ -1678,7 +1679,7 @@ static inline void AddDrawListToRenderList(ImVector<ImDrawList*>& out_render_lis
if (draw_list->commands.back().vtx_count == 0) if (draw_list->commands.back().vtx_count == 0)
draw_list->commands.pop_back(); draw_list->commands.pop_back();
out_render_list.push_back(draw_list); out_render_list.push_back(draw_list);
GImGui->IO.MetricsVertices += (int)draw_list->vtx_buffer.size(); GImGui->IO.MetricsRenderVertices += (int)draw_list->vtx_buffer.size();
} }
} }
@ -2212,7 +2213,7 @@ void ImGui::Render()
} }
// Gather windows to render // Gather windows to render
g.IO.MetricsVertices = 0; g.IO.MetricsRenderVertices = 0;
for (size_t i = 0; i < IM_ARRAYSIZE(g.RenderDrawLists); i++) for (size_t i = 0; i < IM_ARRAYSIZE(g.RenderDrawLists); i++)
g.RenderDrawLists[i].resize(0); g.RenderDrawLists[i].resize(0);
for (size_t i = 0; i != g.Windows.size(); i++) for (size_t i = 0; i != g.Windows.size(); i++)
@ -7697,31 +7698,64 @@ void ImDrawList::PopTextureID()
UpdateTextureID(); UpdateTextureID();
} }
void ImDrawList::ReserveVertices(unsigned int vtx_count) void ImDrawList::PrimReserve(unsigned int vtx_count)
{ {
if (vtx_count > 0) ImDrawCmd& draw_cmd = commands.back();
{ draw_cmd.vtx_count += vtx_count;
ImDrawCmd& draw_cmd = commands.back();
draw_cmd.vtx_count += vtx_count; size_t vtx_buffer_size = vtx_buffer.size();
vtx_buffer.resize(vtx_buffer.size() + vtx_count); vtx_buffer.resize(vtx_buffer_size + vtx_count);
vtx_write = &vtx_buffer[vtx_buffer.size() - vtx_count]; vtx_write = &vtx_buffer[vtx_buffer_size];
}
} }
void ImDrawList::AddVtx(const ImVec2& pos, ImU32 col) void ImDrawList::PrimTriangle(const ImVec2& a, const ImVec2& b, const ImVec2& c, ImU32 col)
{ {
vtx_write->pos = pos; const ImVec2 uv = GImGui->FontTexUvWhitePixel;
vtx_write->col = col; vtx_write[0].pos = a; vtx_write[0].uv = uv; vtx_write[0].col = col;
vtx_write->uv = GImGui->FontTexUvWhitePixel; vtx_write[1].pos = b; vtx_write[1].uv = uv; vtx_write[1].col = col;
vtx_write++; vtx_write[2].pos = c; vtx_write[2].uv = uv; vtx_write[2].col = col;
vtx_write += 3;
} }
void ImDrawList::AddVtxUV(const ImVec2& pos, ImU32 col, const ImVec2& uv) void ImDrawList::PrimRect(const ImVec2& a, const ImVec2& c, ImU32 col)
{ {
vtx_write->pos = pos; const ImVec2 uv = GImGui->FontTexUvWhitePixel;
vtx_write->col = col; const ImVec2 b(c.x, a.y);
vtx_write->uv = uv; const ImVec2 d(a.x, c.y);
vtx_write++; vtx_write[0].pos = a; vtx_write[0].uv = uv; vtx_write[0].col = col;
vtx_write[1].pos = b; vtx_write[1].uv = uv; vtx_write[1].col = col;
vtx_write[2].pos = c; vtx_write[2].uv = uv; vtx_write[2].col = col;
vtx_write[3].pos = a; vtx_write[3].uv = uv; vtx_write[3].col = col;
vtx_write[4].pos = c; vtx_write[4].uv = uv; vtx_write[4].col = col;
vtx_write[5].pos = d; vtx_write[5].uv = uv; vtx_write[5].col = col;
vtx_write += 6;
}
void ImDrawList::PrimRectUV(const ImVec2& a, const ImVec2& c, const ImVec2& uv_a, const ImVec2& uv_c, ImU32 col)
{
const ImVec2 b(c.x, a.y);
const ImVec2 d(a.x, c.y);
const ImVec2 uv_b(uv_c.x, uv_a.y);
const ImVec2 uv_d(uv_a.x, uv_c.y);
vtx_write[0].pos = a; vtx_write[0].uv = uv_a; vtx_write[0].col = col;
vtx_write[1].pos = b; vtx_write[1].uv = uv_b; vtx_write[1].col = col;
vtx_write[2].pos = c; vtx_write[2].uv = uv_c; vtx_write[2].col = col;
vtx_write[3].pos = a; vtx_write[3].uv = uv_a; vtx_write[3].col = col;
vtx_write[4].pos = c; vtx_write[4].uv = uv_c; vtx_write[4].col = col;
vtx_write[5].pos = d; vtx_write[5].uv = uv_d; vtx_write[5].col = col;
vtx_write += 6;
}
void ImDrawList::PrimQuad(const ImVec2& a, const ImVec2& b, const ImVec2& c, const ImVec2& d, ImU32 col)
{
const ImVec2 uv = GImGui->FontTexUvWhitePixel;
vtx_write[0].pos = a; vtx_write[0].uv = uv; vtx_write[0].col = col;
vtx_write[1].pos = b; vtx_write[1].uv = uv; vtx_write[1].col = col;
vtx_write[2].pos = c; vtx_write[2].uv = uv; vtx_write[2].col = col;
vtx_write[3].pos = a; vtx_write[3].uv = uv; vtx_write[3].col = col;
vtx_write[4].pos = c; vtx_write[4].uv = uv; vtx_write[4].col = col;
vtx_write[5].pos = d; vtx_write[5].uv = uv; vtx_write[5].col = col;
vtx_write += 6;
} }
static ImVector<ImVec2> GTempPolyData; static ImVector<ImVec2> GTempPolyData;
@ -7787,29 +7821,30 @@ void ImDrawList::AddPolyline(const ImVec2* points, const int points_count, ImU32
} }
const ImU32 col_trans = col & 0x00ffffff; const ImU32 col_trans = col & 0x00ffffff;
const ImVec2 uv = GImGui->FontTexUvWhitePixel;
int vertex_count = count*12; const int vertex_count = count*12;
ReserveVertices(vertex_count); PrimReserve(vertex_count);
// Stroke // Stroke
for (int i = 0; i < count; i++) for (int i = 0; i < count; i++)
{ {
const int ni = (i+1) < points_count ? i+1 : 0; const int ni = (i+1) < points_count ? i+1 : 0;
AddVtx(points[ni], col); PrimVtx(points[ni], uv, col);
AddVtx(points[i], col); PrimVtx(points[i], uv, col);
AddVtx(temp_outer[i], col_trans); PrimVtx(temp_outer[i], uv, col_trans);
AddVtx(temp_outer[i], col_trans); PrimVtx(temp_outer[i], uv, col_trans);
AddVtx(temp_outer[ni], col_trans); PrimVtx(temp_outer[ni], uv, col_trans);
AddVtx(points[ni], col); PrimVtx(points[ni], uv, col);
AddVtx(temp_inner[ni], col_trans); PrimVtx(temp_inner[ni], uv, col_trans);
AddVtx(temp_inner[i], col_trans); PrimVtx(temp_inner[i], uv, col_trans);
AddVtx(points[i], col); PrimVtx(points[i], uv, col);
AddVtx(points[i], col); PrimVtx(points[i], uv, col);
AddVtx(points[ni], col); PrimVtx(points[ni], uv, col);
AddVtx(temp_inner[ni], col_trans); PrimVtx(temp_inner[ni], uv, col_trans);
} }
} }
@ -7852,28 +7887,29 @@ void ImDrawList::AddConvexPolyFilled(const ImVec2* points, const int points_coun
} }
const ImU32 col_trans = col & 0x00ffffff; const ImU32 col_trans = col & 0x00ffffff;
const ImVec2 uv = GImGui->FontTexUvWhitePixel;
int vertex_count = (points_count-2)*3 + points_count*6; int vertex_count = (points_count-2)*3 + points_count*6;
ReserveVertices(vertex_count); PrimReserve(vertex_count);
// Fill // Fill
for (int i = 2; i < points_count; i++) for (int i = 2; i < points_count; i++)
{ {
AddVtx(temp_inner[0], col); PrimVtx(temp_inner[0], uv, col);
AddVtx(temp_inner[i-1], col); PrimVtx(temp_inner[i-1], uv, col);
AddVtx(temp_inner[i], col); PrimVtx(temp_inner[i], uv, col);
} }
// AA fringe // AA fringe
for (int i = 0, j = points_count-1; i < points_count; j=i++) for (int i = 0, j = points_count-1; i < points_count; j=i++)
{ {
AddVtx(temp_inner[i], col); PrimVtx(temp_inner[i], uv, col);
AddVtx(temp_inner[j], col); PrimVtx(temp_inner[j], uv, col);
AddVtx(temp_outer[j], col_trans); PrimVtx(temp_outer[j], uv, col_trans);
AddVtx(temp_outer[j], col_trans); PrimVtx(temp_outer[j], uv, col_trans);
AddVtx(temp_outer[i], col_trans); PrimVtx(temp_outer[i], uv, col_trans);
AddVtx(temp_inner[i], col); PrimVtx(temp_inner[i], uv, col);
} }
} }
@ -7891,7 +7927,7 @@ void ImDrawList::ArcToFast(const ImVec2& centre, float radius, int amin, int ama
{ {
static ImVec2 circle_vtx[12]; static ImVec2 circle_vtx[12];
static bool circle_vtx_builds = false; static bool circle_vtx_builds = false;
static const int circle_vtx_count = IM_ARRAYSIZE(circle_vtx); const int circle_vtx_count = IM_ARRAYSIZE(circle_vtx);
if (!circle_vtx_builds) if (!circle_vtx_builds)
{ {
for (int i = 0; i < circle_vtx_count; i++) for (int i = 0; i < circle_vtx_count; i++)
@ -7902,6 +7938,7 @@ void ImDrawList::ArcToFast(const ImVec2& centre, float radius, int amin, int ama
} }
circle_vtx_builds = true; circle_vtx_builds = true;
} }
if (amin > amax) return; if (amin > amax) return;
if (radius == 0.0f) if (radius == 0.0f)
@ -7947,6 +7984,7 @@ void ImDrawList::Rect(const ImVec2& a, const ImVec2& b, float rounding, int roun
r = ImMin(r, fabsf(b.x-a.x) * ( ((rounding_corners&(1|2))==(1|2)) || ((rounding_corners&(4|8))==(4|8)) ? 0.5f : 1.0f ) - 1.0f); r = ImMin(r, fabsf(b.x-a.x) * ( ((rounding_corners&(1|2))==(1|2)) || ((rounding_corners&(4|8))==(4|8)) ? 0.5f : 1.0f ) - 1.0f);
r = ImMin(r, fabsf(b.y-a.y) * ( ((rounding_corners&(1|8))==(1|8)) || ((rounding_corners&(2|4))==(2|4)) ? 0.5f : 1.0f ) - 1.0f); r = ImMin(r, fabsf(b.y-a.y) * ( ((rounding_corners&(1|8))==(1|8)) || ((rounding_corners&(2|4))==(2|4)) ? 0.5f : 1.0f ) - 1.0f);
const ImVec2 uv = GImGui->FontTexUvWhitePixel;
if (r == 0.0f || rounding_corners == 0) if (r == 0.0f || rounding_corners == 0)
{ {
LineTo(ImVec2(a.x,a.y)); LineTo(ImVec2(a.x,a.y));
@ -8026,6 +8064,8 @@ void ImDrawList::AddText(const ImFont* font, float font_size, const ImVec2& pos,
if (text_end == NULL) if (text_end == NULL)
text_end = text_begin + strlen(text_begin); text_end = text_begin + strlen(text_begin);
if (text_begin == text_end)
return;
IM_ASSERT(font->ContainerAtlas->TexID == texture_id_stack.back()); // Use high-level ImGui::PushFont() or low-level ImDrawList::PushTextureId() to change font. IM_ASSERT(font->ContainerAtlas->TexID == texture_id_stack.back()); // Use high-level ImGui::PushFont() or low-level ImDrawList::PushTextureId() to change font.
@ -8033,9 +8073,9 @@ void ImDrawList::AddText(const ImFont* font, float font_size, const ImVec2& pos,
const unsigned int char_count = (unsigned int)(text_end - text_begin); const unsigned int char_count = (unsigned int)(text_end - text_begin);
const unsigned int vtx_count_max = char_count * 6; const unsigned int vtx_count_max = char_count * 6;
const size_t vtx_begin = vtx_buffer.size(); const size_t vtx_begin = vtx_buffer.size();
ReserveVertices(vtx_count_max); PrimReserve(vtx_count_max);
font->RenderText(font_size, pos, col, clip_rect_stack.back(), text_begin, text_end, vtx_write, wrap_width, cpu_clip_max); font->RenderText(font_size, pos, col, clip_rect_stack.back(), text_begin, text_end, this, wrap_width, cpu_clip_max);
// give back unused vertices // give back unused vertices
vtx_buffer.resize((size_t)(vtx_write - &vtx_buffer.front())); vtx_buffer.resize((size_t)(vtx_write - &vtx_buffer.front()));
@ -8054,13 +8094,8 @@ void ImDrawList::AddImage(ImTextureID user_texture_id, const ImVec2& a, const Im
if (push_texture_id) if (push_texture_id)
PushTextureID(user_texture_id); PushTextureID(user_texture_id);
ReserveVertices(6); PrimReserve(6);
AddVtxUV(ImVec2(a.x,a.y), col, uv0); PrimRectUV(a, b, uv0, uv1, col);
AddVtxUV(ImVec2(b.x,a.y), col, ImVec2(uv1.x,uv0.y));
AddVtxUV(ImVec2(b.x,b.y), col, uv1);
AddVtxUV(ImVec2(a.x,a.y), col, ImVec2(uv0.x,uv0.y));
AddVtxUV(ImVec2(b.x,b.y), col, uv1);
AddVtxUV(ImVec2(a.x,b.y), col, ImVec2(uv0.x,uv1.y));
if (push_texture_id) if (push_texture_id)
PopTextureID(); PopTextureID();
@ -9076,7 +9111,7 @@ ImVec2 ImFont::CalcTextSizeW(float size, float max_width, const ImWchar* text_be
return text_size; return text_size;
} }
void ImFont::RenderText(float size, ImVec2 pos, ImU32 col, const ImVec4& clip_rect_ref, const char* text_begin, const char* text_end, ImDrawVert*& out_vertices, float wrap_width, const ImVec2* cpu_clip_max) const void ImFont::RenderText(float size, ImVec2 pos, ImU32 col, const ImVec4& clip_rect_ref, const char* text_begin, const char* text_end, ImDrawList* draw_list, float wrap_width, const ImVec2* cpu_clip_max) const
{ {
if (!text_end) if (!text_end)
text_end = text_begin + strlen(text_begin); text_end = text_begin + strlen(text_begin);
@ -9100,6 +9135,8 @@ void ImFont::RenderText(float size, ImVec2 pos, ImU32 col, const ImVec4& clip_re
float x = pos.x; float x = pos.x;
float y = pos.y; float y = pos.y;
ImDrawVert* out_vertices = draw_list->vtx_write;
const char* s = text_begin; const char* s = text_begin;
while (s < text_end) while (s < text_end)
{ {
@ -9187,6 +9224,7 @@ void ImFont::RenderText(float size, ImVec2 pos, ImU32 col, const ImVec4& clip_re
} }
} }
// NB: we are not calling PrimRectUV() here because non-inlined causes too much overhead in a debug build.
out_vertices[0].pos = ImVec2(x1, y1); out_vertices[0].pos = ImVec2(x1, y1);
out_vertices[0].uv = ImVec2(u1, v1); out_vertices[0].uv = ImVec2(u1, v1);
out_vertices[0].col = col; out_vertices[0].col = col;
@ -9214,6 +9252,8 @@ void ImFont::RenderText(float size, ImVec2 pos, ImU32 col, const ImVec4& clip_re
x += char_width; x += char_width;
} }
draw_list->vtx_write = out_vertices;
} }
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
@ -9886,7 +9926,6 @@ void ImGui::ShowTestWindow(bool* opened)
static float f1=1.123f; static float f1=1.123f;
static float f2=0; static float f2=0;
static float f3=123456789.0f;
ImGui::SliderFloat("slider float", &f1, 0.0f, 2.0f); ImGui::SliderFloat("slider float", &f1, 0.0f, 2.0f);
ImGui::SliderFloat("slider log float", &f2, -10.0f, 10.0f, "%.4f", 3.0f); ImGui::SliderFloat("slider log float", &f2, -10.0f, 10.0f, "%.4f", 3.0f);
static float angle = 0.0f; static float angle = 0.0f;
@ -10496,7 +10535,7 @@ void ImGui::ShowMetricsWindow(bool* opened)
{ {
ImGui::Text("ImGui %s", ImGui::GetVersion()); ImGui::Text("ImGui %s", ImGui::GetVersion());
ImGui::Text("Application average %.3f ms/frame (%.1f FPS)", 1000.0f / ImGui::GetIO().Framerate, ImGui::GetIO().Framerate); ImGui::Text("Application average %.3f ms/frame (%.1f FPS)", 1000.0f / ImGui::GetIO().Framerate, ImGui::GetIO().Framerate);
ImGui::Text("%d vertices", ImGui::GetIO().MetricsVertices); ImGui::Text("%d vertices", ImGui::GetIO().MetricsRenderVertices);
ImGui::Separator(); ImGui::Separator();
struct Funcs struct Funcs

40
imgui.h
View File

@ -317,7 +317,7 @@ namespace ImGui
// Widgets: Drags (tip: ctrl+click on a drag box to input text) // Widgets: Drags (tip: ctrl+click on a drag box to input text)
// ImGui 1.38+ work-in-progress, may change name or API. // ImGui 1.38+ work-in-progress, may change name or API.
IMGUI_API bool DragFloat(const char* label, float* v, float v_step = 1.0f, float v_min = 0.0f, float v_max = 0.0f, const char* display_format = "%.3f"); // If v_max >= v_max we have no bound IMGUI_API bool DragFloat(const char* label, float* v, float v_step = 1.0f, float v_min = 0.0f, float v_max = 0.0f, const char* display_format = "%.3f"); // If v_max >= v_max we have no bound
IMGUI_API bool DragInt(const char* label, int* v, int v_step = 1, int v_min = 0.0f, int v_max = 0.0f, const char* display_format = "%.0f"); // If v_max >= v_max we have no bound IMGUI_API bool DragInt(const char* label, int* v, int v_step = 1, int v_min = 0, int v_max = 0, const char* display_format = "%.0f"); // If v_max >= v_max we have no bound
// Widgets: Input // Widgets: Input
IMGUI_API bool InputText(const char* label, char* buf, size_t buf_size, ImGuiInputTextFlags flags = 0, ImGuiTextEditCallback callback = NULL, void* user_data = NULL); IMGUI_API bool InputText(const char* label, char* buf, size_t buf_size, ImGuiInputTextFlags flags = 0, ImGuiTextEditCallback callback = NULL, void* user_data = NULL);
@ -670,7 +670,7 @@ struct ImGuiIO
bool WantCaptureMouse; // Mouse is hovering a window or widget is active (= ImGui will use your mouse input) bool WantCaptureMouse; // Mouse is hovering a window or widget is active (= ImGui will use your mouse input)
bool WantCaptureKeyboard; // Widget is active (= ImGui will use your keyboard input) bool WantCaptureKeyboard; // Widget is active (= ImGui will use your keyboard input)
float Framerate; // Framerate estimation, in frame per second. Rolling average estimation based on IO.DeltaTime over 120 frames float Framerate; // Framerate estimation, in frame per second. Rolling average estimation based on IO.DeltaTime over 120 frames
int MetricsVertices; // Vertices processed during last call to Render() int MetricsRenderVertices; // Vertices processed during last call to Render()
//------------------------------------------------------------------ //------------------------------------------------------------------
// [Internal] ImGui will maintain those fields for you // [Internal] ImGui will maintain those fields for you
@ -918,8 +918,8 @@ struct ImDrawList
// Primitives // Primitives
IMGUI_API void AddLine(const ImVec2& a, const ImVec2& b, ImU32 col, float thickness = 1.0f); IMGUI_API void AddLine(const ImVec2& a, const ImVec2& b, ImU32 col, float thickness = 1.0f);
IMGUI_API void AddRect(const ImVec2& a, const ImVec2& b, ImU32 col, float rounding = 0.0f, int rounding_corners=0x0F); IMGUI_API void AddRect(const ImVec2& a, const ImVec2& b, ImU32 col, float rounding = 0.0f, int rounding_corners = 0x0F);
IMGUI_API void AddRectFilled(const ImVec2& a, const ImVec2& b, ImU32 col, float rounding = 0.0f, int rounding_corners=0x0F); IMGUI_API void AddRectFilled(const ImVec2& a, const ImVec2& b, ImU32 col, float rounding = 0.0f, int rounding_corners = 0x0F);
IMGUI_API void AddTriangleFilled(const ImVec2& a, const ImVec2& b, const ImVec2& c, ImU32 col); IMGUI_API void AddTriangleFilled(const ImVec2& a, const ImVec2& b, const ImVec2& c, ImU32 col);
IMGUI_API void AddCircle(const ImVec2& centre, float radius, ImU32 col, int num_segments = 12); IMGUI_API void AddCircle(const ImVec2& centre, float radius, ImU32 col, int num_segments = 12);
IMGUI_API void AddCircleFilled(const ImVec2& centre, float radius, ImU32 col, int num_segments = 12); IMGUI_API void AddCircleFilled(const ImVec2& centre, float radius, ImU32 col, int num_segments = 12);
@ -929,15 +929,19 @@ struct ImDrawList
IMGUI_API void AddConvexPolyFilled(const ImVec2* points, const int num_points, ImU32 col); IMGUI_API void AddConvexPolyFilled(const ImVec2* points, const int num_points, ImU32 col);
// Advanced // Advanced
IMGUI_API void AddCallback(ImDrawCallback callback, void* callback_data); // Your rendering function must check for 'user_callback' in ImDrawCmd and call the function instead of rendering triangles. IMGUI_API void AddCallback(ImDrawCallback callback, void* callback_data); // Your rendering function must check for 'user_callback' in ImDrawCmd and call the function instead of rendering triangles.
IMGUI_API void AddDrawCmd(); // This is useful if you need to forcefully create a new draw call (to allow for dependent rendering / blending). Otherwise primitives are merged into the same draw-call as much as possible IMGUI_API void AddDrawCmd(); // This is useful if you need to forcefully create a new draw call (to allow for dependent rendering / blending). Otherwise primitives are merged into the same draw-call as much as possible
// Internal helpers // Internal helpers
IMGUI_API void ReserveVertices(unsigned int vtx_count); IMGUI_API void PrimReserve(unsigned int vtx_count);
IMGUI_API void AddVtx(const ImVec2& pos, ImU32 col); IMGUI_API void PrimTriangle(const ImVec2& a, const ImVec2& b, const ImVec2& c, ImU32 col);
IMGUI_API void AddVtxUV(const ImVec2& pos, ImU32 col, const ImVec2& uv); IMGUI_API void PrimRect(const ImVec2& a, const ImVec2& b, ImU32 col);
IMGUI_API void PrimRectUV(const ImVec2& a, const ImVec2& b, const ImVec2& uv_a, const ImVec2& uv_b, ImU32 col);
IMGUI_API void PrimQuad(const ImVec2& a, const ImVec2& b, const ImVec2& c, const ImVec2& d, ImU32 col);
IMGUI_API void PrimLine(const ImVec2& a, const ImVec2& b, ImU32 col, float thickness = 1.0f);
IMGUI_API void UpdateClipRect(); IMGUI_API void UpdateClipRect();
IMGUI_API void UpdateTextureID(); IMGUI_API void UpdateTextureID();
IMGUI_API void PrimVtx(const ImVec2& pos, const ImVec2& uv, ImU32 col) { vtx_write->pos = pos; vtx_write->uv = uv; vtx_write->col = col; vtx_write++; }
}; };
// Load and rasterize multiple TTF fonts into a same texture. // Load and rasterize multiple TTF fonts into a same texture.
@ -1021,18 +1025,18 @@ struct ImFont
// Methods // Methods
IMGUI_API ImFont(); IMGUI_API ImFont();
IMGUI_API ~ImFont(); IMGUI_API ~ImFont();
IMGUI_API void Clear(); IMGUI_API void Clear();
IMGUI_API void BuildLookupTable(); IMGUI_API void BuildLookupTable();
IMGUI_API const Glyph* FindGlyph(unsigned short c) const; IMGUI_API const Glyph* FindGlyph(unsigned short c) const;
IMGUI_API void SetFallbackChar(ImWchar c); IMGUI_API void SetFallbackChar(ImWchar c);
IMGUI_API bool IsLoaded() const { return ContainerAtlas != NULL; } IMGUI_API bool IsLoaded() const { return ContainerAtlas != NULL; }
// 'max_width' stops rendering after a certain width (could be turned into a 2d size). FLT_MAX to disable. // 'max_width' stops rendering after a certain width (could be turned into a 2d size). FLT_MAX to disable.
// 'wrap_width' enable automatic word-wrapping across multiple lines to fit into given width. 0.0f to disable. // 'wrap_width' enable automatic word-wrapping across multiple lines to fit into given width. 0.0f to disable.
IMGUI_API ImVec2 CalcTextSizeA(float size, float max_width, float wrap_width, const char* text_begin, const char* text_end = NULL, const char** remaining = NULL) const; // utf8 IMGUI_API ImVec2 CalcTextSizeA(float size, float max_width, float wrap_width, const char* text_begin, const char* text_end = NULL, const char** remaining = NULL) const; // utf8
IMGUI_API ImVec2 CalcTextSizeW(float size, float max_width, const ImWchar* text_begin, const ImWchar* text_end, const ImWchar** remaining = NULL) const; // wchar IMGUI_API ImVec2 CalcTextSizeW(float size, float max_width, const ImWchar* text_begin, const ImWchar* text_end, const ImWchar** remaining = NULL) const; // wchar
IMGUI_API void RenderText(float size, ImVec2 pos, ImU32 col, const ImVec4& clip_rect, const char* text_begin, const char* text_end, ImDrawVert*& out_vertices, float wrap_width = 0.0f, const ImVec2* cpu_clip_max = NULL) const; IMGUI_API void RenderText(float size, ImVec2 pos, ImU32 col, const ImVec4& clip_rect, const char* text_begin, const char* text_end, ImDrawList* draw_list, float wrap_width = 0.0f, const ImVec2* cpu_clip_max = NULL) const;
IMGUI_API const char* CalcWordWrapPositionA(float scale, const char* text, const char* text_end, float wrap_width) const; IMGUI_API const char* CalcWordWrapPositionA(float scale, const char* text, const char* text_end, float wrap_width) const;
}; };
//---- Include imgui_user.h at the end of imgui.h //---- Include imgui_user.h at the end of imgui.h