Compare commits
177 Commits
Author | SHA1 | Date | |
---|---|---|---|
bd762b559c | |||
e6b9950645 | |||
b4fd216bd2 | |||
0730ec7577 | |||
0e6f288a2f | |||
7f804d3d64 | |||
de44af5227 | |||
0f29cd7a14 | |||
a5a84a9b69 | |||
197b2763fc | |||
df00fa8113 | |||
e835ef1d90 | |||
ae75553ba1 | |||
2e576de9ca | |||
9e16317382 | |||
b5acb16378 | |||
38164a410d | |||
214c967df8 | |||
31654958f9 | |||
a31e44b99a | |||
54ea495207 | |||
eb789c0288 | |||
e9aead09cb | |||
e4a79e9fc8 | |||
e27eddfbd2 | |||
311a2f8328 | |||
df2ad5e899 | |||
07a6ba8aaf | |||
16d6561aba | |||
abe45e9976 | |||
c0999495e7 | |||
b9118750ae | |||
7f6453ca70 | |||
24a9d32531 | |||
ec4b510775 | |||
1484799b18 | |||
895f93f694 | |||
49defcf083 | |||
e78c47961e | |||
8c4fcf1359 | |||
2322318cac | |||
5f8175abaa | |||
ab4f5e6862 | |||
075fe0220e | |||
cf037b4769 | |||
97192606a6 | |||
e90984f638 | |||
366516c154 | |||
a6e0d182b0 | |||
3572b04c69 | |||
fd8752df8d | |||
f1dcd72e9f | |||
2aee4419e3 | |||
9f2545e6bb | |||
f3bd033b6d | |||
b15532345b | |||
15436b46e8 | |||
b01adf16de | |||
428c4d4ece | |||
172ff0a262 | |||
c6f3d0924e | |||
ac40284536 | |||
191e17eaf8 | |||
616668dac3 | |||
36e52167da | |||
3f85fe2fe7 | |||
447cc88e04 | |||
9c707b6d8f | |||
9b5493d1d9 | |||
8a65d97bf0 | |||
be93b842c1 | |||
7961c53145 | |||
d3bc92a674 | |||
4205241e86 | |||
c97636aef4 | |||
ee3355fe8e | |||
1e30400f80 | |||
3a64c77826 | |||
e19f0d370a | |||
6c192f3221 | |||
78645a7dba | |||
74363c5a43 | |||
0b10cf4bd7 | |||
3d84858755 | |||
fad5e45d2c | |||
05a3a9b962 | |||
85eee4a4c5 | |||
4c4798546e | |||
f768579377 | |||
e6eafd6fa8 | |||
1037bacc4b | |||
89a412690c | |||
af37fb1ee7 | |||
9f05a2bb16 | |||
48a944813c | |||
1d9a4748de | |||
36212b9ad9 | |||
bebadb9012 | |||
530e746daa | |||
ce481ec702 | |||
f1ea630dd0 | |||
ffc8264e9d | |||
ec625b7c49 | |||
f86286548e | |||
7751ce0a69 | |||
9bb95db68a | |||
0a8acf241c | |||
c388c7e6eb | |||
088df3d1ba | |||
09fae1c209 | |||
016dbb7472 | |||
6ec65c46aa | |||
0fa3d6e25f | |||
f898e658bb | |||
22fe7f23b1 | |||
b756510f21 | |||
b6ac371496 | |||
81b9480413 | |||
b9d9f62ae3 | |||
4b94454fb4 | |||
b86505bf2f | |||
df1c056c88 | |||
eb1b9d4521 | |||
d35ceb793e | |||
a61b92f362 | |||
51bbe1d961 | |||
e4d4dae3bf | |||
bd3c53754d | |||
a1162ac001 | |||
618a42acf8 | |||
3cd1b8a37b | |||
746951691a | |||
8eafb373f7 | |||
fec4232c79 | |||
85672fec2e | |||
d5ed586d70 | |||
d58a029285 | |||
6e039c8b7d | |||
05a42ba3a6 | |||
da2ccf0a78 | |||
3e647d86aa | |||
0e0cd5e705 | |||
8d32fcb7d4 | |||
4ea2af7ea5 | |||
3773fb4117 | |||
24028911e3 | |||
3fd68c3a31 | |||
1cf4b313e2 | |||
2e85dce1ee | |||
62d233aaab | |||
3cdb4fa456 | |||
7439df0ba1 | |||
ad42787543 | |||
91059da1a5 | |||
b420a51541 | |||
c07ab1b56a | |||
22a9555a99 | |||
25080d53e5 | |||
43448d9c89 | |||
e20077fbd0 | |||
2c677c45c7 | |||
3b339efeb2 | |||
8fc50f5ed3 | |||
dd5d251273 | |||
2fb63b6068 | |||
aa7fc37b37 | |||
c13c2449bb | |||
c2cb727ac9 | |||
47fd8431c1 | |||
ef628a0a9d | |||
df5a06f119 | |||
e9b697698a | |||
5240013c90 | |||
1956703c42 | |||
6d6ee4e1f1 | |||
e9b0a61f48 | |||
e3001fb986 |
6
.gitignore
vendored
@ -1,7 +1,13 @@
|
||||
## Visual Studio files
|
||||
examples/Debug/*
|
||||
examples/Release/*
|
||||
examples/ipch/*
|
||||
examples/directx9_example/Debug/*
|
||||
examples/directx9_example/Release/*
|
||||
examples/directx9_example/ipch/*
|
||||
examples/directx11_example/Debug/*
|
||||
examples/directx11_example/Release/*
|
||||
examples/directx11_example/ipch/*
|
||||
examples/opengl_example/Debug/*
|
||||
examples/opengl_example/Release/*
|
||||
examples/opengl_example/ipch/*
|
||||
|
48
README.md
@ -1,9 +1,9 @@
|
||||
ImGui
|
||||
=====
|
||||
|
||||
ImGui is a bloat-free graphical user interface library for C++. It outputs vertex buffers that you can render in your 3D-pipeline enabled application. It is portable, renderer agnostic and carries minimal amount of dependencies (only 3 files are needed). It is based on an "immediate" graphical user interface paradigm which allows you to build simple user interfaces with ease.
|
||||
ImGui is a bloat-free graphical user interface library for C++. It outputs vertex buffers that you can render in your 3D-pipeline enabled application. It is portable, renderer agnostic and carries minimal amount of dependencies (only 3 files are needed). It is based on an "immediate" graphical user interface paradigm which allows you to build user interfaces with ease.
|
||||
|
||||
ImGui is designed to enable fast iteration and allow programmers to create "content creation" or "debug" tools (as opposed to tools for the average end-user). It favors simplicity and thus lacks certain features normally found in more high-level libraries, such as string localisation.
|
||||
ImGui is designed to enable fast iteration and allow programmers to create "content creation" or "debug" tools (as opposed to UI for the average end-user). It favors simplicity and productivity toward this goal, and thus lacks certain features normally found in more high-level libraries.
|
||||
|
||||
ImGui is particularly suited to integration in 3D applications, fullscreen applications, embedded applications, games, or any applications on consoles platforms where operating system features are non-standard.
|
||||
|
||||
@ -13,6 +13,8 @@ After ImGui is setup in your engine, you can use it like in this example:
|
||||
|
||||
ImGui outputs vertex buffers and simple command-lists that you can render in your application. Because it doesn't know or touch graphics state directly, you can call ImGui commands anywhere in your code (e.g. in the middle of a running algorithm, or in the middle of your own rendering process). Refer to the sample applications in the examples/ folder for instructions on how to integrate ImGui with your existing codebase.
|
||||
|
||||
ImGui allows you create elaborate tools as well as very short-lived ones. On the extreme side of short-liveness: using the Edit&Continue feature of compilers you can add a few widgets to tweaks variables while your application is running, and remove the code a minute later! ImGui is not just for tweaking values. You can use it to trace a running algorithm by just emitting text commands. You can use it along with your own reflection data to browse your dataset live. You can use it to expose the internals of a subsystem in your engine, to create a logger, an inspection tool, a profiler, a debugger, etc.
|
||||
|
||||
Gallery
|
||||
-------
|
||||
|
||||
@ -21,6 +23,10 @@ Gallery
|
||||

|
||||

|
||||
|
||||
UTF-8 is supported for text display and input. Here using M+ font to display Japanese:
|
||||
|
||||

|
||||
|
||||
References
|
||||
----------
|
||||
|
||||
@ -32,9 +38,10 @@ The Immediate Mode GUI paradigm may at first appear unusual to some users. This
|
||||
|
||||
Frequently Asked Question
|
||||
-------------------------
|
||||
<b>How do you use ImGui on a platform that may not have a mouse and keyboard?</b>
|
||||
|
||||
I recommend using [Synergy](http://synergy-project.org) and the uSynergy.c micro client to share your mouse and keyboard. This way you can seemingly use your PC input devices on a video game console or a tablet. ImGui was also designed to function with touch inputs if you increase the padding of widgets to compensate for the lack of precision of touch devices, but it is recommended you use a mouse to allow optimising for screen real-estate.
|
||||
<b>How do you use ImGui on a platform that may not have a mouse or keyboard?</b>
|
||||
|
||||
I recommend using [Synergy](http://synergy-project.org). With the uSynergy.c micro client running you can seamlessly use your PC input devices from a video game console or a tablet. ImGui was also designed to function with touch inputs if you increase the padding of widgets to compensate for the lack of precision of touch devices, but it is recommended you use a mouse to allow optimising for screen real-estate.
|
||||
|
||||
<b>I integrated ImGui in my engine and the text or lines are blurry..</b>
|
||||
|
||||
@ -45,19 +52,48 @@ I recommend using [Synergy](http://synergy-project.org) and the uSynergy.c micro
|
||||
|
||||
Yes. I have written data browsers, debuggers, profilers and all sort of non-trivial tools with the library. There's no reason you cannot, and in my experience the simplicity of the API is very empowering. However note that ImGui is programmer centric and the immediate-mode GUI paradigm might requires a bit of adaptation before you can realize its full potential.
|
||||
|
||||
<b>Is ImGui fast?</b>
|
||||
|
||||
Down the fundation of its visual design, ImGui is engineered to be fairly performant both in term of CPU and GPU usage. Running elaborate code and creating elaborate UI will of course have a cost but ImGui aims to minimize it.
|
||||
|
||||
Mileage may vary but the following screenshot should give you an idea of the cost of running and rendering UI code (In the case of a trivial demo application like this one, your driver/os setup may be a bottleneck and cause higher variation or throttled framerate. Testing performance as part of a real application is recommended).
|
||||
|
||||

|
||||
|
||||
This is showing framerate on my 2011 iMac running Windows 7, OpenGL, AMD Radeon HD 6700M. ([click here for the full-size picture](/web/performance_01.png)).
|
||||
In contrast, librairies featuring higher-quality rendering and layouting techniques may have a higher resources footprint.
|
||||
|
||||
<b>Can you reskin the look of ImGui?</b>
|
||||
|
||||
Yes, you can alter the look of the interface to some degree: changing colors, sizes and padding, font. However, as ImGui is designed and optimised to create debug tools, the amount of skinning you can apply is limited. There is only so much you can stray away from the default look and feel of the interface. The example below uses modified settings to create a more compact UI with different colors:
|
||||
Yes, you can alter the look of the interface to some degree: changing colors, sizes and padding, font. However, as ImGui is designed and optimised to create debug tools, the amount of skinning you can apply is limited. There is only so much you can stray away from the default look and feel of the interface. The example below uses modified settings to create a very compact UI with different colors:
|
||||
|
||||

|
||||
|
||||
<b>Why using C++ (as opposed to C)?</b>
|
||||
|
||||
ImGui takes advantage of a few C++ features for convenience but nothing in the realm of Boost-insanity/quagmire. In particular, function overloading and default parameters are used to make the API easier to use and code more terse. Doing so I believe the API is sitting on a sweet spot and giving up on those features would make the API more cumbersome. Other features such as namespace, constructors and templates (in the case of the ImVector<> class) are also relied on as a convenience but could be removed.
|
||||
|
||||
Shall someone wants to use ImGui from another language, it should be possible to wrap ImGui to be used from a raw C API in the future.
|
||||
|
||||
Support
|
||||
-------
|
||||
|
||||
<b>Can you develop features xxxx for ImGui?</b>
|
||||
|
||||
Please use GitHub 'Issues' facilities to suggest and discuss improvements. Your questions are often helpul to the community of users. If you represent an organization and would like specific non-trivial features to be implemented, I am available for hire to work on or with ImGui.
|
||||
|
||||
<b>Can I donate to support the development of ImGui?</b>
|
||||
|
||||
If you have the mean to help, I have setup a [**Patreon page**](http://www.patreon.com/imgui) to enable me to spend more time on the development of the library. One-off donations are also greatly appreciated. Thanks!
|
||||
|
||||
Credits
|
||||
-------
|
||||
|
||||
Developed by [Omar Cornut](http://www.miracleworld.net). The library was developed with the support of [Media Molecule](http://www.mediamolecule.com) and first used internally on the game [Tearaway](http://tearaway.mediamolecule.com).
|
||||
|
||||
Embeds [proggy_clean](http://upperbounds.net) font by Tristan Grimmer (also MIT license).
|
||||
Embeds [proggy_clean](http://upperbounds.net) font by Tristan Grimmer (MIT license).
|
||||
Embeds [M+ fonts](http://mplus-fonts.sourceforge.jp/mplus-outline-fonts/index-en.html) font by Coji Morishita (free software license).
|
||||
Embeds [stb_textedit.h](https://github.com/nothings/stb/) by Sean Barrett.
|
||||
|
||||
Inspiration, feedback, and testing: Casey Muratori, Atman Binstock, Mikko Mononen, Emmanuel Briney, Stefan Kamoda, Anton Mikhailov, Matt Willis. Thanks!
|
||||
|
||||
|
84
examples/directx11_example/directx11_example.vcxproj
Normal file
@ -0,0 +1,84 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup Label="ProjectConfigurations">
|
||||
<ProjectConfiguration Include="Debug|Win32">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|Win32">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
</ItemGroup>
|
||||
<PropertyGroup Label="Globals">
|
||||
<ProjectGuid>{9F316E83-5AE5-4939-A723-305A94F48005}</ProjectGuid>
|
||||
<RootNamespace>directx11_example</RootNamespace>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<CharacterSet>MultiByte</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<CharacterSet>MultiByte</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
||||
<ImportGroup Label="ExtensionSettings">
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<PropertyGroup Label="UserMacros" />
|
||||
<PropertyGroup />
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<Optimization>Disabled</Optimization>
|
||||
<AdditionalIncludeDirectories>$(DXSDK_DIR)/Include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<AdditionalDependencies>d3d11.lib;d3dcompiler.lib;dxgi.lib;imm32.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<AdditionalLibraryDirectories>$(DXSDK_DIR)/Lib/x86;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<Optimization>MaxSpeed</Optimization>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<AdditionalIncludeDirectories>$(DXSDK_DIR)/Include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
<AdditionalDependencies>d3d11.lib;d3dcompiler.lib;dxgi.lib;imm32.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<AdditionalLibraryDirectories>$(DXSDK_DIR)/Lib/x86;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="..\..\imconfig.h" />
|
||||
<ClInclude Include="..\..\imgui.h" />
|
||||
<ClInclude Include="..\..\stb_textedit.h" />
|
||||
<ClInclude Include="..\shared\stb_image.h" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="..\..\imgui.cpp" />
|
||||
<ClCompile Include="main.cpp" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="..\..\LICENSE" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
</ImportGroup>
|
||||
</Project>
|
38
examples/directx11_example/directx11_example.vcxproj.filters
Normal file
@ -0,0 +1,38 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup>
|
||||
<Filter Include="imgui">
|
||||
<UniqueIdentifier>{0587d7a3-f2ce-4d56-b84f-a0005d3bfce6}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="sources">
|
||||
<UniqueIdentifier>{08e36723-ce4f-4cff-9662-c40801cf1acf}</UniqueIdentifier>
|
||||
</Filter>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="..\..\imconfig.h">
|
||||
<Filter>imgui</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\imgui.h">
|
||||
<Filter>imgui</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\stb_textedit.h">
|
||||
<Filter>imgui</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\shared\stb_image.h">
|
||||
<Filter>sources</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="..\..\imgui.cpp">
|
||||
<Filter>imgui</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="main.cpp">
|
||||
<Filter>sources</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="..\..\LICENSE">
|
||||
<Filter>imgui</Filter>
|
||||
</None>
|
||||
</ItemGroup>
|
||||
</Project>
|
607
examples/directx11_example/main.cpp
Normal file
@ -0,0 +1,607 @@
|
||||
#include <windows.h>
|
||||
#define STB_IMAGE_IMPLEMENTATION
|
||||
#include "../shared/stb_image.h" // for .png loading
|
||||
#include "../../imgui.h"
|
||||
|
||||
// DirectX 11
|
||||
#include <d3d11.h>
|
||||
#include <d3dcompiler.h>
|
||||
#define DIRECTINPUT_VERSION 0x0800
|
||||
#include <dinput.h>
|
||||
|
||||
#pragma warning (disable: 4996) // 'This function or variable may be unsafe': strdup
|
||||
|
||||
extern const char* vertexShader; // Implemented at the bottom
|
||||
extern const char* pixelShader;
|
||||
|
||||
static HWND hWnd;
|
||||
static ID3D11Device* g_pd3dDevice = NULL;
|
||||
static ID3D11DeviceContext* g_pd3dDeviceImmediateContext = NULL;
|
||||
static IDXGISwapChain* g_pSwapChain = NULL;
|
||||
static ID3D11Buffer* g_pVB = NULL;
|
||||
static ID3D11RenderTargetView* g_mainRenderTargetView;
|
||||
|
||||
static ID3D10Blob * g_pVertexShaderBlob = NULL;
|
||||
static ID3D11VertexShader* g_pVertexShader = NULL;
|
||||
static ID3D11InputLayout* g_pInputLayout = NULL;
|
||||
static ID3D11Buffer* g_pVertexConstantBuffer = NULL;
|
||||
|
||||
static ID3D10Blob * g_pPixelShaderBlob = NULL;
|
||||
static ID3D11PixelShader* g_pPixelShader = NULL;
|
||||
|
||||
static ID3D11ShaderResourceView*g_pFontTextureView = NULL;
|
||||
static ID3D11SamplerState* g_pFontSampler = NULL;
|
||||
static ID3D11BlendState* g_blendState = NULL;
|
||||
|
||||
struct CUSTOMVERTEX
|
||||
{
|
||||
float pos[2];
|
||||
float uv[2];
|
||||
unsigned int col;
|
||||
};
|
||||
|
||||
struct VERTEX_CONSTANT_BUFFER
|
||||
{
|
||||
float mvp[4][4];
|
||||
};
|
||||
|
||||
// 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)
|
||||
{
|
||||
size_t total_vtx_count = 0;
|
||||
for (int n = 0; n < cmd_lists_count; n++)
|
||||
total_vtx_count += cmd_lists[n]->vtx_buffer.size();
|
||||
if (total_vtx_count == 0)
|
||||
return;
|
||||
|
||||
// Copy and convert all vertices into a single contiguous buffer
|
||||
D3D11_MAPPED_SUBRESOURCE mappedResource;
|
||||
if (g_pd3dDeviceImmediateContext->Map(g_pVB, 0, D3D11_MAP_WRITE_DISCARD, 0, &mappedResource) != S_OK)
|
||||
return;
|
||||
CUSTOMVERTEX* vtx_dst = (CUSTOMVERTEX*)mappedResource.pData;
|
||||
for (int n = 0; n < cmd_lists_count; n++)
|
||||
{
|
||||
const ImDrawList* cmd_list = cmd_lists[n];
|
||||
const ImDrawVert* vtx_src = &cmd_list->vtx_buffer[0];
|
||||
for (size_t i = 0; i < cmd_list->vtx_buffer.size(); i++)
|
||||
{
|
||||
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_pd3dDeviceImmediateContext->Unmap(g_pVB, 0);
|
||||
|
||||
// Setup orthographic projection matrix into our constant buffer
|
||||
{
|
||||
D3D11_MAPPED_SUBRESOURCE mappedResource;
|
||||
if (g_pd3dDeviceImmediateContext->Map(g_pVertexConstantBuffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &mappedResource) != S_OK)
|
||||
return;
|
||||
|
||||
VERTEX_CONSTANT_BUFFER* pConstantBuffer = (VERTEX_CONSTANT_BUFFER*)mappedResource.pData;
|
||||
const float L = 0.0f;
|
||||
const float R = ImGui::GetIO().DisplaySize.x;
|
||||
const float B = ImGui::GetIO().DisplaySize.y;
|
||||
const float T = 0.0f;
|
||||
const float mvp[4][4] =
|
||||
{
|
||||
{ 2.0f/(R-L), 0.0f, 0.0f, 0.0f},
|
||||
{ 0.0f, 2.0f/(T-B), 0.0f, 0.0f,},
|
||||
{ 0.0f, 0.0f, 0.5f, 0.0f },
|
||||
{ (R+L)/(L-R), (T+B)/(B-T), 0.5f, 1.0f },
|
||||
};
|
||||
memcpy(&pConstantBuffer->mvp, mvp, sizeof(mvp));
|
||||
g_pd3dDeviceImmediateContext->Unmap(g_pVertexConstantBuffer, 0);
|
||||
}
|
||||
|
||||
// Setup viewport
|
||||
{
|
||||
D3D11_VIEWPORT vp;
|
||||
memset(&vp, 0, sizeof(D3D11_VIEWPORT));
|
||||
vp.Width = ImGui::GetIO().DisplaySize.x;
|
||||
vp.Height = ImGui::GetIO().DisplaySize.y;
|
||||
vp.MinDepth = 0.0f;
|
||||
vp.MaxDepth = 1.0f;
|
||||
vp.TopLeftX = 0;
|
||||
vp.TopLeftY = 0;
|
||||
g_pd3dDeviceImmediateContext->RSSetViewports(1, &vp);
|
||||
}
|
||||
|
||||
// Bind shader and vertex buffers
|
||||
unsigned int stride = sizeof(CUSTOMVERTEX);
|
||||
unsigned int offset = 0;
|
||||
g_pd3dDeviceImmediateContext->IASetInputLayout(g_pInputLayout);
|
||||
g_pd3dDeviceImmediateContext->IASetVertexBuffers(0, 1, &g_pVB, &stride, &offset);
|
||||
g_pd3dDeviceImmediateContext->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
|
||||
|
||||
g_pd3dDeviceImmediateContext->VSSetShader(g_pVertexShader, NULL, 0);
|
||||
g_pd3dDeviceImmediateContext->VSSetConstantBuffers(0, 1, &g_pVertexConstantBuffer);
|
||||
|
||||
g_pd3dDeviceImmediateContext->PSSetShader(g_pPixelShader, NULL, 0);
|
||||
g_pd3dDeviceImmediateContext->PSSetShaderResources(0, 1, &g_pFontTextureView);
|
||||
g_pd3dDeviceImmediateContext->PSSetSamplers(0, 1, &g_pFontSampler);
|
||||
|
||||
// Setup render state
|
||||
const float blendFactor[4] = { 0.f, 0.f, 0.f, 0.f };
|
||||
g_pd3dDeviceImmediateContext->OMSetBlendState(g_blendState, blendFactor, 0xffffffff);
|
||||
|
||||
// Render command lists
|
||||
int vtx_offset = 0;
|
||||
for (int n = 0; n < cmd_lists_count; n++)
|
||||
{
|
||||
// Render command list
|
||||
const ImDrawList* cmd_list = cmd_lists[n];
|
||||
for (size_t cmd_i = 0; cmd_i < cmd_list->commands.size(); cmd_i++)
|
||||
{
|
||||
const ImDrawCmd* pcmd = &cmd_list->commands[cmd_i];
|
||||
const D3D11_RECT r = { (LONG)pcmd->clip_rect.x, (LONG)pcmd->clip_rect.y, (LONG)pcmd->clip_rect.z, (LONG)pcmd->clip_rect.w };
|
||||
g_pd3dDeviceImmediateContext->RSSetScissorRects(1, &r);
|
||||
g_pd3dDeviceImmediateContext->Draw(pcmd->vtx_count, vtx_offset);
|
||||
vtx_offset += pcmd->vtx_count;
|
||||
}
|
||||
}
|
||||
|
||||
// Restore modified state
|
||||
g_pd3dDeviceImmediateContext->IASetInputLayout(NULL);
|
||||
g_pd3dDeviceImmediateContext->PSSetShader(NULL, NULL, 0);
|
||||
g_pd3dDeviceImmediateContext->VSSetShader(NULL, NULL, 0);
|
||||
}
|
||||
|
||||
HRESULT InitDeviceD3D(HWND hWnd)
|
||||
{
|
||||
// Setup swap chain
|
||||
DXGI_SWAP_CHAIN_DESC sd;
|
||||
{
|
||||
ZeroMemory(&sd, sizeof(sd));
|
||||
sd.BufferCount = 2;
|
||||
sd.BufferDesc.Width = (UINT)ImGui::GetIO().DisplaySize.x;
|
||||
sd.BufferDesc.Height = (UINT)ImGui::GetIO().DisplaySize.y;
|
||||
sd.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
|
||||
sd.BufferDesc.RefreshRate.Numerator = 60;
|
||||
sd.BufferDesc.RefreshRate.Denominator = 1;
|
||||
sd.Flags = DXGI_SWAP_CHAIN_FLAG_ALLOW_MODE_SWITCH;
|
||||
sd.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
|
||||
sd.OutputWindow = hWnd;
|
||||
sd.SampleDesc.Count = 1;
|
||||
sd.SampleDesc.Quality = 0;
|
||||
sd.Windowed = TRUE;
|
||||
sd.SwapEffect = DXGI_SWAP_EFFECT_DISCARD;
|
||||
}
|
||||
|
||||
UINT createDeviceFlags = 0;
|
||||
#ifdef _DEBUG
|
||||
createDeviceFlags |= D3D11_CREATE_DEVICE_DEBUG;
|
||||
#endif
|
||||
D3D_FEATURE_LEVEL featureLevel;
|
||||
const D3D_FEATURE_LEVEL featureLevelArray[1] = { D3D_FEATURE_LEVEL_11_0, };
|
||||
if (D3D11CreateDeviceAndSwapChain(NULL, D3D_DRIVER_TYPE_HARDWARE, NULL, createDeviceFlags, featureLevelArray, 1, D3D11_SDK_VERSION, &sd, &g_pSwapChain, &g_pd3dDevice, &featureLevel, &g_pd3dDeviceImmediateContext) != S_OK)
|
||||
return E_FAIL;
|
||||
|
||||
// Setup rasterizer
|
||||
{
|
||||
D3D11_RASTERIZER_DESC RSDesc;
|
||||
memset(&RSDesc, 0, sizeof(D3D11_RASTERIZER_DESC));
|
||||
RSDesc.FillMode = D3D11_FILL_SOLID;
|
||||
RSDesc.CullMode = D3D11_CULL_NONE;
|
||||
RSDesc.FrontCounterClockwise = FALSE;
|
||||
RSDesc.DepthBias = 0;
|
||||
RSDesc.SlopeScaledDepthBias = 0.0f;
|
||||
RSDesc.DepthBiasClamp = 0;
|
||||
RSDesc.DepthClipEnable = TRUE;
|
||||
RSDesc.ScissorEnable = TRUE;
|
||||
RSDesc.AntialiasedLineEnable = FALSE;
|
||||
RSDesc.MultisampleEnable = (sd.SampleDesc.Count > 1) ? TRUE : FALSE;
|
||||
|
||||
ID3D11RasterizerState* pRState = NULL;
|
||||
g_pd3dDevice->CreateRasterizerState(&RSDesc, &pRState);
|
||||
g_pd3dDeviceImmediateContext->RSSetState(pRState);
|
||||
pRState->Release();
|
||||
}
|
||||
|
||||
// Create the render target
|
||||
{
|
||||
ID3D11Texture2D* pBackBuffer;
|
||||
D3D11_RENDER_TARGET_VIEW_DESC render_target_view_desc;
|
||||
ZeroMemory(&render_target_view_desc, sizeof(render_target_view_desc));
|
||||
render_target_view_desc.Format = sd.BufferDesc.Format;
|
||||
render_target_view_desc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2D;
|
||||
g_pSwapChain->GetBuffer(0, __uuidof(ID3D11Texture2D), (LPVOID*)&pBackBuffer);
|
||||
g_pd3dDevice->CreateRenderTargetView(pBackBuffer, &render_target_view_desc, &g_mainRenderTargetView);
|
||||
g_pd3dDeviceImmediateContext->OMSetRenderTargets(1, &g_mainRenderTargetView, NULL);
|
||||
pBackBuffer->Release();
|
||||
}
|
||||
|
||||
// Create the vertex shader
|
||||
{
|
||||
D3DCompile(vertexShader, strlen(vertexShader), NULL, NULL, NULL, "main", "vs_5_0", 0, 0, &g_pVertexShaderBlob, NULL);
|
||||
if (g_pVertexShaderBlob == NULL) // NB: Pass ID3D10Blob* pErrorBlob to D3DCompile() to get error showing in (const char*)pErrorBlob->GetBufferPointer(). Make sure to Release() the blob!
|
||||
return E_FAIL;
|
||||
if (g_pd3dDevice->CreateVertexShader((DWORD*)g_pVertexShaderBlob->GetBufferPointer(), g_pVertexShaderBlob->GetBufferSize(), NULL, &g_pVertexShader) != S_OK)
|
||||
return E_FAIL;
|
||||
|
||||
// Create the input layout
|
||||
D3D11_INPUT_ELEMENT_DESC localLayout[] = {
|
||||
{ "POSITION", 0, DXGI_FORMAT_R32G32B32A32_FLOAT, 0, (size_t)(&((CUSTOMVERTEX*)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)(&((CUSTOMVERTEX*)0)->uv), D3D11_INPUT_PER_VERTEX_DATA, 0 },
|
||||
};
|
||||
|
||||
if (g_pd3dDevice->CreateInputLayout(localLayout, 3, g_pVertexShaderBlob->GetBufferPointer(), g_pVertexShaderBlob->GetBufferSize(), &g_pInputLayout) != S_OK)
|
||||
return E_FAIL;
|
||||
|
||||
// Create the constant buffer
|
||||
{
|
||||
D3D11_BUFFER_DESC cbDesc;
|
||||
cbDesc.ByteWidth = sizeof(VERTEX_CONSTANT_BUFFER);
|
||||
cbDesc.Usage = D3D11_USAGE_DYNAMIC;
|
||||
cbDesc.BindFlags = D3D11_BIND_CONSTANT_BUFFER;
|
||||
cbDesc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
|
||||
cbDesc.MiscFlags = 0;
|
||||
g_pd3dDevice->CreateBuffer(&cbDesc, NULL, &g_pVertexConstantBuffer);
|
||||
}
|
||||
}
|
||||
|
||||
// Create the pixel shader
|
||||
{
|
||||
D3DCompile(pixelShader, strlen(pixelShader), NULL, NULL, NULL, "main", "ps_5_0", 0, 0, &g_pPixelShaderBlob, NULL);
|
||||
if (g_pPixelShaderBlob == NULL) // NB: Pass ID3D10Blob* pErrorBlob to D3DCompile() to get error showing in (const char*)pErrorBlob->GetBufferPointer(). Make sure to Release() the blob!
|
||||
return E_FAIL;
|
||||
if (g_pd3dDevice->CreatePixelShader((DWORD*)g_pPixelShaderBlob->GetBufferPointer(), g_pPixelShaderBlob->GetBufferSize(), NULL, &g_pPixelShader) != S_OK)
|
||||
return E_FAIL;
|
||||
}
|
||||
|
||||
// Create the blending setup
|
||||
{
|
||||
D3D11_BLEND_DESC desc;
|
||||
ZeroMemory(&desc, sizeof(desc));
|
||||
desc.AlphaToCoverageEnable = false;
|
||||
desc.RenderTarget[0].BlendEnable = true;
|
||||
desc.RenderTarget[0].SrcBlend = D3D11_BLEND_SRC_ALPHA;
|
||||
desc.RenderTarget[0].DestBlend = D3D11_BLEND_INV_SRC_ALPHA;
|
||||
desc.RenderTarget[0].BlendOp = D3D11_BLEND_OP_ADD;
|
||||
desc.RenderTarget[0].SrcBlendAlpha = D3D11_BLEND_INV_SRC_ALPHA;
|
||||
desc.RenderTarget[0].DestBlendAlpha = D3D11_BLEND_ZERO;
|
||||
desc.RenderTarget[0].BlendOpAlpha = D3D11_BLEND_OP_ADD;
|
||||
desc.RenderTarget[0].RenderTargetWriteMask = D3D11_COLOR_WRITE_ENABLE_ALL;
|
||||
g_pd3dDevice->CreateBlendState(&desc, &g_blendState);
|
||||
}
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
void CleanupDevice()
|
||||
{
|
||||
if (g_pd3dDeviceImmediateContext) g_pd3dDeviceImmediateContext->ClearState();
|
||||
|
||||
// InitImGui
|
||||
if (g_pFontSampler) g_pFontSampler->Release();
|
||||
if (g_pFontTextureView) g_pFontTextureView->Release();
|
||||
if (g_pVB) g_pVB->Release();
|
||||
|
||||
// InitDeviceD3D
|
||||
if (g_blendState) g_blendState->Release();
|
||||
if (g_pPixelShader) g_pPixelShader->Release();
|
||||
if (g_pPixelShaderBlob) g_pPixelShaderBlob->Release();
|
||||
if (g_pVertexConstantBuffer) g_pVertexConstantBuffer->Release();
|
||||
if (g_pInputLayout) g_pInputLayout->Release();
|
||||
if (g_pVertexShader) g_pVertexShader->Release();
|
||||
if (g_pVertexShaderBlob) g_pVertexShaderBlob->Release();
|
||||
if (g_mainRenderTargetView) g_mainRenderTargetView->Release();
|
||||
if (g_pSwapChain) g_pSwapChain->Release();
|
||||
if (g_pd3dDeviceImmediateContext) g_pd3dDeviceImmediateContext->Release();
|
||||
if (g_pd3dDevice) g_pd3dDevice->Release();
|
||||
}
|
||||
|
||||
LRESULT WINAPI WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
|
||||
{
|
||||
ImGuiIO& io = ImGui::GetIO();
|
||||
switch (msg)
|
||||
{
|
||||
case WM_LBUTTONDOWN:
|
||||
io.MouseDown[0] = true;
|
||||
return true;
|
||||
case WM_LBUTTONUP:
|
||||
io.MouseDown[0] = false;
|
||||
return true;
|
||||
case WM_RBUTTONDOWN:
|
||||
io.MouseDown[1] = true;
|
||||
return true;
|
||||
case WM_RBUTTONUP:
|
||||
io.MouseDown[1] = false;
|
||||
return true;
|
||||
case WM_MOUSEWHEEL:
|
||||
io.MouseWheel += GET_WHEEL_DELTA_WPARAM(wParam) > 0 ? +1.0f : -1.0f;
|
||||
return true;
|
||||
case WM_MOUSEMOVE:
|
||||
// Mouse position, in pixels (set to -1,-1 if no mouse / on another screen, etc.)
|
||||
io.MousePos.x = (signed short)(lParam);
|
||||
io.MousePos.y = (signed short)(lParam >> 16);
|
||||
return true;
|
||||
case WM_CHAR:
|
||||
// You can also use ToAscii()+GetKeyboardState() to retrieve characters.
|
||||
if (wParam > 0 && wParam < 0x10000)
|
||||
io.AddInputCharacter((unsigned short)wParam);
|
||||
return true;
|
||||
case WM_DESTROY:
|
||||
CleanupDevice();
|
||||
PostQuitMessage(0);
|
||||
return 0;
|
||||
}
|
||||
return DefWindowProc(hWnd, msg, wParam, lParam);
|
||||
}
|
||||
|
||||
void InitImGui()
|
||||
{
|
||||
RECT rect;
|
||||
GetClientRect(hWnd, &rect);
|
||||
int display_w = (int)(rect.right - rect.left);
|
||||
int display_h = (int)(rect.bottom - rect.top);
|
||||
|
||||
ImGuiIO& io = ImGui::GetIO();
|
||||
io.DisplaySize = ImVec2((float)display_w, (float)display_h); // Display size, in pixels. For clamping windows positions.
|
||||
io.DeltaTime = 1.0f/60.0f; // Time elapsed since last frame, in seconds (in this sample app we'll override this every frame because our time step is variable)
|
||||
io.PixelCenterOffset = 0.0f; // Align Direct3D Texels
|
||||
io.KeyMap[ImGuiKey_Tab] = VK_TAB; // Keyboard mapping. ImGui will use those indices to peek into the io.KeyDown[] array that we will update during the application lifetime.
|
||||
io.KeyMap[ImGuiKey_LeftArrow] = VK_LEFT;
|
||||
io.KeyMap[ImGuiKey_RightArrow] = VK_RIGHT;
|
||||
io.KeyMap[ImGuiKey_UpArrow] = VK_UP;
|
||||
io.KeyMap[ImGuiKey_DownArrow] = VK_UP;
|
||||
io.KeyMap[ImGuiKey_Home] = VK_HOME;
|
||||
io.KeyMap[ImGuiKey_End] = VK_END;
|
||||
io.KeyMap[ImGuiKey_Delete] = VK_DELETE;
|
||||
io.KeyMap[ImGuiKey_Backspace] = VK_BACK;
|
||||
io.KeyMap[ImGuiKey_Enter] = VK_RETURN;
|
||||
io.KeyMap[ImGuiKey_Escape] = VK_ESCAPE;
|
||||
io.KeyMap[ImGuiKey_A] = 'A';
|
||||
io.KeyMap[ImGuiKey_C] = 'C';
|
||||
io.KeyMap[ImGuiKey_V] = 'V';
|
||||
io.KeyMap[ImGuiKey_X] = 'X';
|
||||
io.KeyMap[ImGuiKey_Y] = 'Y';
|
||||
io.KeyMap[ImGuiKey_Z] = 'Z';
|
||||
io.RenderDrawListsFn = ImImpl_RenderDrawLists;
|
||||
|
||||
// Create the vertex buffer
|
||||
{
|
||||
D3D11_BUFFER_DESC bufferDesc;
|
||||
memset(&bufferDesc, 0, sizeof(D3D11_BUFFER_DESC));
|
||||
bufferDesc.Usage = D3D11_USAGE_DYNAMIC;
|
||||
bufferDesc.ByteWidth = 10000 * sizeof(CUSTOMVERTEX);
|
||||
bufferDesc.BindFlags = D3D11_BIND_VERTEX_BUFFER;
|
||||
bufferDesc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
|
||||
bufferDesc.MiscFlags = 0;
|
||||
if (g_pd3dDevice->CreateBuffer(&bufferDesc, NULL, &g_pVB) < 0)
|
||||
{
|
||||
IM_ASSERT(0);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// Load font texture
|
||||
// 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);
|
||||
|
||||
{
|
||||
D3D11_TEXTURE2D_DESC desc;
|
||||
ZeroMemory(&desc, sizeof(desc));
|
||||
desc.Width = tex_x;
|
||||
desc.Height = tex_y;
|
||||
desc.MipLevels = 1;
|
||||
desc.ArraySize = 1;
|
||||
desc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
|
||||
desc.SampleDesc.Count = 1;
|
||||
desc.Usage = D3D11_USAGE_DEFAULT;
|
||||
desc.BindFlags = D3D11_BIND_SHADER_RESOURCE;
|
||||
desc.CPUAccessFlags = 0;
|
||||
|
||||
ID3D11Texture2D *pTexture = NULL;
|
||||
D3D11_SUBRESOURCE_DATA subResource;
|
||||
subResource.pSysMem = tex_data;
|
||||
subResource.SysMemPitch = tex_x * 4;
|
||||
subResource.SysMemSlicePitch = 0;
|
||||
g_pd3dDevice->CreateTexture2D(&desc, &subResource, &pTexture);
|
||||
|
||||
// Create texture view
|
||||
D3D11_SHADER_RESOURCE_VIEW_DESC srvDesc;
|
||||
ZeroMemory(&srvDesc, sizeof(srvDesc));
|
||||
srvDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
|
||||
srvDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2D;
|
||||
srvDesc.Texture2D.MipLevels = desc.MipLevels;
|
||||
srvDesc.Texture2D.MostDetailedMip = 0;
|
||||
g_pd3dDevice->CreateShaderResourceView(pTexture, &srvDesc, &g_pFontTextureView);
|
||||
pTexture->Release();
|
||||
}
|
||||
|
||||
// Create texture sampler
|
||||
{
|
||||
D3D11_SAMPLER_DESC desc;
|
||||
ZeroMemory(&desc, sizeof(desc));
|
||||
desc.Filter = D3D11_FILTER_MIN_MAG_MIP_POINT;
|
||||
desc.AddressU = D3D11_TEXTURE_ADDRESS_WRAP;
|
||||
desc.AddressV = D3D11_TEXTURE_ADDRESS_WRAP;
|
||||
desc.AddressW = D3D11_TEXTURE_ADDRESS_WRAP;
|
||||
desc.MipLODBias = 0.f;
|
||||
desc.ComparisonFunc = D3D11_COMPARISON_ALWAYS;
|
||||
desc.MinLOD = 0.f;
|
||||
desc.MaxLOD = 0.f;
|
||||
g_pd3dDevice->CreateSamplerState(&desc, &g_pFontSampler);
|
||||
}
|
||||
}
|
||||
|
||||
INT64 ticks_per_second = 0;
|
||||
INT64 last_time = 0;
|
||||
|
||||
void UpdateImGui()
|
||||
{
|
||||
ImGuiIO& io = ImGui::GetIO();
|
||||
|
||||
// Setup time step
|
||||
INT64 current_time;
|
||||
QueryPerformanceCounter((LARGE_INTEGER *)¤t_time);
|
||||
io.DeltaTime = (float)(current_time - last_time) / ticks_per_second;
|
||||
last_time = current_time;
|
||||
|
||||
// Setup inputs
|
||||
// (we already got mouse position, buttons, wheel from the window message callback)
|
||||
BYTE keystate[256];
|
||||
GetKeyboardState(keystate);
|
||||
for (int i = 0; i < 256; i++)
|
||||
io.KeysDown[i] = (keystate[i] & 0x80) != 0;
|
||||
io.KeyCtrl = (keystate[VK_CONTROL] & 0x80) != 0;
|
||||
io.KeyShift = (keystate[VK_SHIFT] & 0x80) != 0;
|
||||
// io.MousePos : filled by WM_MOUSEMOVE event
|
||||
// io.MouseDown : filled by WM_*BUTTON* events
|
||||
// io.MouseWheel : filled by WM_MOUSEWHEEL events
|
||||
|
||||
// Start the frame
|
||||
ImGui::NewFrame();
|
||||
}
|
||||
|
||||
int WINAPI wWinMain(HINSTANCE hInst, HINSTANCE, LPWSTR, int)
|
||||
{
|
||||
// Register the window class
|
||||
WNDCLASSEX wc = { sizeof(WNDCLASSEX), CS_CLASSDC, WndProc, 0L, 0L, GetModuleHandle(NULL), NULL, LoadCursor(NULL, IDC_ARROW), NULL, NULL, "ImGui Example", NULL };
|
||||
RegisterClassEx(&wc);
|
||||
|
||||
// Create the application's window
|
||||
hWnd = CreateWindow("ImGui Example", "ImGui DirectX11 Example", WS_OVERLAPPEDWINDOW, 100, 100, 1280, 800, NULL, NULL, wc.hInstance, NULL);
|
||||
|
||||
if (!QueryPerformanceFrequency((LARGE_INTEGER *)&ticks_per_second))
|
||||
return 1;
|
||||
if (!QueryPerformanceCounter((LARGE_INTEGER *)&last_time))
|
||||
return 1;
|
||||
|
||||
// Initialize Direct3D
|
||||
if (InitDeviceD3D(hWnd) < 0)
|
||||
{
|
||||
CleanupDevice();
|
||||
UnregisterClass("ImGui Example", wc.hInstance);
|
||||
return 1;
|
||||
}
|
||||
|
||||
// Show the window
|
||||
ShowWindow(hWnd, SW_SHOWDEFAULT);
|
||||
UpdateWindow(hWnd);
|
||||
|
||||
InitImGui();
|
||||
|
||||
// Enter the message loop
|
||||
MSG msg;
|
||||
ZeroMemory(&msg, sizeof(msg));
|
||||
while (msg.message != WM_QUIT)
|
||||
{
|
||||
if (PeekMessage(&msg, NULL, 0U, 0U, PM_REMOVE))
|
||||
{
|
||||
TranslateMessage(&msg);
|
||||
DispatchMessage(&msg);
|
||||
continue;
|
||||
}
|
||||
|
||||
UpdateImGui();
|
||||
|
||||
static bool show_test_window = true;
|
||||
static bool show_another_window = false;
|
||||
|
||||
// 1. Show a simple window
|
||||
// Tip: if we don't call ImGui::Begin()/ImGui::End() the widgets appears in a window automatically called "Debug"
|
||||
{
|
||||
static float f;
|
||||
ImGui::Text("Hello, world!");
|
||||
ImGui::SliderFloat("float", &f, 0.0f, 1.0f);
|
||||
show_test_window ^= ImGui::Button("Test Window");
|
||||
show_another_window ^= ImGui::Button("Another Window");
|
||||
|
||||
// Calculate and show frame rate
|
||||
static float ms_per_frame[120] = { 0 };
|
||||
static int ms_per_frame_idx = 0;
|
||||
static float ms_per_frame_accum = 0.0f;
|
||||
ms_per_frame_accum -= ms_per_frame[ms_per_frame_idx];
|
||||
ms_per_frame[ms_per_frame_idx] = ImGui::GetIO().DeltaTime * 1000.0f;
|
||||
ms_per_frame_accum += ms_per_frame[ms_per_frame_idx];
|
||||
ms_per_frame_idx = (ms_per_frame_idx + 1) % 120;
|
||||
const float ms_per_frame_avg = ms_per_frame_accum / 120;
|
||||
ImGui::Text("Application average %.3f ms/frame (%.1f FPS)", ms_per_frame_avg, 1000.0f / ms_per_frame_avg);
|
||||
}
|
||||
|
||||
// 2. Show another simple window, this time using an explicit Begin/End pair
|
||||
if (show_another_window)
|
||||
{
|
||||
ImGui::Begin("Another Window", &show_another_window, ImVec2(200,100));
|
||||
ImGui::Text("Hello");
|
||||
ImGui::End();
|
||||
}
|
||||
|
||||
// 3. Show the ImGui test window. Most of the sample code is in ImGui::ShowTestWindow()
|
||||
if (show_test_window)
|
||||
{
|
||||
ImGui::SetNewWindowDefaultPos(ImVec2(650, 20)); // Normally user code doesn't need/want to call it because positions are saved in .ini file anyway. Here we just want to make the demo initial state a bit more friendly!
|
||||
ImGui::ShowTestWindow(&show_test_window);
|
||||
}
|
||||
|
||||
// Rendering
|
||||
float clearColor[4] = { 204 / 255.f, 153 / 255.f, 153 / 255.f };
|
||||
g_pd3dDeviceImmediateContext->ClearRenderTargetView(g_mainRenderTargetView, clearColor);
|
||||
ImGui::Render();
|
||||
g_pSwapChain->Present(0, 0);
|
||||
}
|
||||
|
||||
ImGui::Shutdown();
|
||||
UnregisterClass("ImGui Example", wc.hInstance);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const char* vertexShader = "\
|
||||
cbuffer vertexBuffer : register(c0) \
|
||||
{\
|
||||
float4x4 ProjectionMatrix; \
|
||||
};\
|
||||
struct VS_INPUT\
|
||||
{\
|
||||
float2 pos : POSITION;\
|
||||
float4 col : COLOR0;\
|
||||
float2 uv : TEXCOORD0;\
|
||||
};\
|
||||
\
|
||||
struct PS_INPUT\
|
||||
{\
|
||||
float4 pos : SV_POSITION;\
|
||||
float4 col : COLOR0;\
|
||||
float2 uv : TEXCOORD0;\
|
||||
};\
|
||||
\
|
||||
PS_INPUT main(VS_INPUT input)\
|
||||
{\
|
||||
PS_INPUT output;\
|
||||
output.pos = mul( ProjectionMatrix, float4(input.pos.xy, 0.f, 1.f));\
|
||||
output.col = input.col;\
|
||||
output.uv = input.uv;\
|
||||
return output;\
|
||||
}";
|
||||
|
||||
static const char* pixelShader = "\
|
||||
struct PS_INPUT\
|
||||
{\
|
||||
float4 pos : SV_POSITION;\
|
||||
float4 col : COLOR0;\
|
||||
float2 uv : TEXCOORD0;\
|
||||
};\
|
||||
sampler sampler0;\
|
||||
Texture2D texture0;\
|
||||
\
|
||||
float4 main(PS_INPUT input) : SV_Target\
|
||||
{\
|
||||
float4 out_col = texture0.Sample(sampler0, input.uv);\
|
||||
return input.col * out_col;\
|
||||
}";
|
@ -1,20 +0,0 @@
|
||||
|
||||
Microsoft Visual Studio Solution File, Format Version 11.00
|
||||
# Visual Studio 2010
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "directx9_example", "directx9_example.vcxproj", "{4165A294-21F2-44CA-9B38-E3F935ABADF5}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Win32 = Debug|Win32
|
||||
Release|Win32 = Release|Win32
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||
{4165A294-21F2-44CA-9B38-E3F935ABADF5}.Debug|Win32.ActiveCfg = Debug|Win32
|
||||
{4165A294-21F2-44CA-9B38-E3F935ABADF5}.Debug|Win32.Build.0 = Debug|Win32
|
||||
{4165A294-21F2-44CA-9B38-E3F935ABADF5}.Release|Win32.ActiveCfg = Release|Win32
|
||||
{4165A294-21F2-44CA-9B38-E3F935ABADF5}.Release|Win32.Build.0 = Release|Win32
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
EndGlobalSection
|
||||
EndGlobal
|
@ -46,7 +46,7 @@
|
||||
<Link>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<AdditionalLibraryDirectories>$(DXSDK_DIR)Lib\x86;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
||||
<AdditionalDependencies>d3d9.lib;d3dx9d.lib;dxerr.lib;dxguid.lib;winmm.lib;comctl32.lib;gdi32.lib;user32.lib</AdditionalDependencies>
|
||||
<AdditionalDependencies>d3d9.lib;d3dx9d.lib;dxerr.lib;dxguid.lib;imm32.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<SubSystem>
|
||||
</SubSystem>
|
||||
</Link>
|
||||
@ -64,7 +64,7 @@
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
<AdditionalLibraryDirectories>$(DXSDK_DIR)Lib\x86;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
||||
<AdditionalDependencies>d3d9.lib;d3dx9d.lib;dxerr.lib;dxguid.lib;winmm.lib;comctl32.lib;gdi32.lib;user32.lib</AdditionalDependencies>
|
||||
<AdditionalDependencies>d3d9.lib;d3dx9d.lib;dxerr.lib;dxguid.lib;imm32.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<SubSystem>
|
||||
</SubSystem>
|
||||
</Link>
|
||||
|
@ -1,22 +1,23 @@
|
||||
#include <windows.h>
|
||||
#include <mmsystem.h>
|
||||
#include "../../imgui.h"
|
||||
|
||||
// DirectX 9
|
||||
#include <d3dx9.h>
|
||||
#define DIRECTINPUT_VERSION 0x0800
|
||||
#include <dinput.h>
|
||||
#include "../../imgui.h"
|
||||
|
||||
#pragma warning (disable: 4996) // 'This function or variable may be unsafe': strdup
|
||||
|
||||
static HWND hWnd;
|
||||
static HWND hWnd;
|
||||
static LPDIRECT3D9 g_pD3D = NULL; // Used to create the D3DDevice
|
||||
static LPDIRECT3DDEVICE9 g_pd3dDevice = NULL; // Our rendering device
|
||||
static LPDIRECT3DVERTEXBUFFER9 g_pVB = NULL; // Buffer to hold vertices
|
||||
static LPDIRECT3DTEXTURE9 g_pTexture = NULL; // Our texture
|
||||
struct CUSTOMVERTEX
|
||||
{
|
||||
D3DXVECTOR3 position;
|
||||
D3DCOLOR color;
|
||||
float tu, tv;
|
||||
D3DXVECTOR3 pos;
|
||||
D3DCOLOR col;
|
||||
D3DXVECTOR2 uv;
|
||||
};
|
||||
#define D3DFVF_CUSTOMVERTEX (D3DFVF_XYZ|D3DFVF_DIFFUSE|D3DFVF_TEX1)
|
||||
|
||||
@ -42,12 +43,12 @@ static void ImImpl_RenderDrawLists(ImDrawList** const cmd_lists, int cmd_lists_c
|
||||
const ImDrawVert* vtx_src = &cmd_list->vtx_buffer[0];
|
||||
for (size_t i = 0; i < cmd_list->vtx_buffer.size(); i++)
|
||||
{
|
||||
vtx_dst->position.x = vtx_src->pos.x;
|
||||
vtx_dst->position.y = vtx_src->pos.y;
|
||||
vtx_dst->position.z = 0.0f;
|
||||
vtx_dst->color = (vtx_src->col & 0xFF00FF00) | ((vtx_src->col & 0xFF0000)>>16) | ((vtx_src->col & 0xFF) << 16); // RGBA --> ARGB for DirectX9
|
||||
vtx_dst->tu = vtx_src->uv.x;
|
||||
vtx_dst->tv = vtx_src->uv.y;
|
||||
vtx_dst->pos.x = vtx_src->pos.x;
|
||||
vtx_dst->pos.y = vtx_src->pos.y;
|
||||
vtx_dst->pos.z = 0.0f;
|
||||
vtx_dst->col = (vtx_src->col & 0xFF00FF00) | ((vtx_src->col & 0xFF0000)>>16) | ((vtx_src->col & 0xFF) << 16); // RGBA --> ARGB for DirectX9
|
||||
vtx_dst->uv.x = vtx_src->uv.x;
|
||||
vtx_dst->uv.y = vtx_src->uv.y;
|
||||
vtx_dst++;
|
||||
vtx_src++;
|
||||
}
|
||||
@ -91,9 +92,9 @@ static void ImImpl_RenderDrawLists(ImDrawList** const cmd_lists, int cmd_lists_c
|
||||
{
|
||||
// Render command list
|
||||
const ImDrawList* cmd_list = cmd_lists[n];
|
||||
const ImDrawCmd* pcmd_end = cmd_list->commands.end();
|
||||
for (const ImDrawCmd* pcmd = cmd_list->commands.begin(); pcmd != pcmd_end; pcmd++)
|
||||
for (size_t cmd_i = 0; cmd_i < cmd_list->commands.size(); cmd_i++)
|
||||
{
|
||||
const ImDrawCmd* pcmd = &cmd_list->commands[cmd_i];
|
||||
const RECT r = { (LONG)pcmd->clip_rect.x, (LONG)pcmd->clip_rect.y, (LONG)pcmd->clip_rect.z, (LONG)pcmd->clip_rect.w };
|
||||
g_pd3dDevice->SetScissorRect(&r);
|
||||
g_pd3dDevice->DrawPrimitive(D3DPT_TRIANGLELIST, vtx_offset, pcmd->vtx_count/3);
|
||||
@ -102,7 +103,7 @@ static void ImImpl_RenderDrawLists(ImDrawList** const cmd_lists, int cmd_lists_c
|
||||
}
|
||||
}
|
||||
|
||||
HRESULT InitD3D(HWND hWnd)
|
||||
HRESULT InitDeviceD3D(HWND hWnd)
|
||||
{
|
||||
if (NULL == (g_pD3D = Direct3DCreate9(D3D_SDK_VERSION)))
|
||||
return E_FAIL;
|
||||
@ -123,19 +124,18 @@ HRESULT InitD3D(HWND hWnd)
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
void Cleanup()
|
||||
void CleanupDevice()
|
||||
{
|
||||
if (g_pTexture != NULL)
|
||||
g_pTexture->Release();
|
||||
// InitImGui
|
||||
if (g_pVB) g_pVB->Release();
|
||||
|
||||
if (g_pd3dDevice != NULL)
|
||||
g_pd3dDevice->Release();
|
||||
|
||||
if (g_pD3D != NULL)
|
||||
g_pD3D->Release();
|
||||
// InitDeviceD3D
|
||||
if (g_pTexture) g_pTexture->Release();
|
||||
if (g_pd3dDevice) g_pd3dDevice->Release();
|
||||
if (g_pD3D) g_pD3D->Release();
|
||||
}
|
||||
|
||||
LRESULT WINAPI MsgProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
|
||||
LRESULT WINAPI WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
|
||||
{
|
||||
ImGuiIO& io = ImGui::GetIO();
|
||||
switch (msg)
|
||||
@ -153,8 +153,7 @@ LRESULT WINAPI MsgProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
|
||||
io.MouseDown[1] = false;
|
||||
return true;
|
||||
case WM_MOUSEWHEEL:
|
||||
// Mouse wheel: -1,0,+1
|
||||
io.MouseWheel = GET_WHEEL_DELTA_WPARAM(wParam) > 0 ? +1 : -1;
|
||||
io.MouseWheel += GET_WHEEL_DELTA_WPARAM(wParam) > 0 ? +1.0f : -1.0f;
|
||||
return true;
|
||||
case WM_MOUSEMOVE:
|
||||
// Mouse position, in pixels (set to -1,-1 if no mouse / on another screen, etc.)
|
||||
@ -163,15 +162,13 @@ LRESULT WINAPI MsgProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
|
||||
return true;
|
||||
case WM_CHAR:
|
||||
// You can also use ToAscii()+GetKeyboardState() to retrieve characters.
|
||||
if (wParam > 1 && wParam < 256)
|
||||
io.AddInputCharacter((char)wParam);
|
||||
if (wParam > 0 && wParam < 0x10000)
|
||||
io.AddInputCharacter((unsigned short)wParam);
|
||||
return true;
|
||||
case WM_DESTROY:
|
||||
{
|
||||
Cleanup();
|
||||
PostQuitMessage(0);
|
||||
return 0;
|
||||
}
|
||||
CleanupDevice();
|
||||
PostQuitMessage(0);
|
||||
return 0;
|
||||
}
|
||||
return DefWindowProc(hWnd, msg, wParam, lParam);
|
||||
}
|
||||
@ -180,12 +177,14 @@ void InitImGui()
|
||||
{
|
||||
RECT rect;
|
||||
GetClientRect(hWnd, &rect);
|
||||
int display_w = (int)(rect.right - rect.left);
|
||||
int display_h = (int)(rect.bottom - rect.top);
|
||||
|
||||
ImGuiIO& io = ImGui::GetIO();
|
||||
io.DisplaySize = ImVec2((float)(rect.right - rect.left), (float)(rect.bottom - rect.top)); // Display size, in pixels. For clamping windows positions.
|
||||
io.DeltaTime = 1.0f/60.0f; // Time elapsed since last frame, in seconds (in this sample app we'll override this every frame because our timestep is variable)
|
||||
io.PixelCenterOffset = 0.0f; // Align Direct3D Texels
|
||||
io.KeyMap[ImGuiKey_Tab] = VK_TAB; // Keyboard mapping. ImGui will use those indices to peek into the io.KeyDown[] array that we will update during the application lifetime.
|
||||
io.DisplaySize = ImVec2((float)display_w, (float)display_h); // Display size, in pixels. For clamping windows positions.
|
||||
io.DeltaTime = 1.0f/60.0f; // Time elapsed since last frame, in seconds (in this sample app we'll override this every frame because our time step is variable)
|
||||
io.PixelCenterOffset = 0.0f; // Align Direct3D Texels
|
||||
io.KeyMap[ImGuiKey_Tab] = VK_TAB; // Keyboard mapping. ImGui will use those indices to peek into the io.KeyDown[] array that we will update during the application lifetime.
|
||||
io.KeyMap[ImGuiKey_LeftArrow] = VK_LEFT;
|
||||
io.KeyMap[ImGuiKey_RightArrow] = VK_RIGHT;
|
||||
io.KeyMap[ImGuiKey_UpArrow] = VK_UP;
|
||||
@ -224,17 +223,17 @@ void InitImGui()
|
||||
}
|
||||
|
||||
INT64 ticks_per_second = 0;
|
||||
INT64 time = 0;
|
||||
INT64 last_time = 0;
|
||||
|
||||
void UpdateImGui()
|
||||
{
|
||||
ImGuiIO& io = ImGui::GetIO();
|
||||
|
||||
// Setup timestep
|
||||
// Setup time step
|
||||
INT64 current_time;
|
||||
QueryPerformanceCounter((LARGE_INTEGER *)¤t_time);
|
||||
io.DeltaTime = (float)(current_time - time) / ticks_per_second;
|
||||
time = current_time;
|
||||
io.DeltaTime = (float)(current_time - last_time) / ticks_per_second;
|
||||
last_time = current_time;
|
||||
|
||||
// Setup inputs
|
||||
// (we already got mouse position, buttons, wheel from the window message callback)
|
||||
@ -255,7 +254,7 @@ void UpdateImGui()
|
||||
int WINAPI wWinMain(HINSTANCE hInst, HINSTANCE, LPWSTR, int)
|
||||
{
|
||||
// Register the window class
|
||||
WNDCLASSEX wc = { sizeof(WNDCLASSEX), CS_CLASSDC, MsgProc, 0L, 0L, GetModuleHandle(NULL), NULL, NULL, NULL, NULL, L"ImGui Example", NULL };
|
||||
WNDCLASSEX wc = { sizeof(WNDCLASSEX), CS_CLASSDC, WndProc, 0L, 0L, GetModuleHandle(NULL), NULL, LoadCursor(NULL, IDC_ARROW), NULL, NULL, L"ImGui Example", NULL };
|
||||
RegisterClassEx(&wc);
|
||||
|
||||
// Create the application's window
|
||||
@ -263,14 +262,13 @@ int WINAPI wWinMain(HINSTANCE hInst, HINSTANCE, LPWSTR, int)
|
||||
|
||||
if (!QueryPerformanceFrequency((LARGE_INTEGER *)&ticks_per_second))
|
||||
return 1;
|
||||
if (!QueryPerformanceCounter((LARGE_INTEGER *)&time))
|
||||
if (!QueryPerformanceCounter((LARGE_INTEGER *)&last_time))
|
||||
return 1;
|
||||
|
||||
// Initialize Direct3D
|
||||
if (InitD3D(hWnd) < 0)
|
||||
if (InitDeviceD3D(hWnd) < 0)
|
||||
{
|
||||
if (g_pVB)
|
||||
g_pVB->Release();
|
||||
CleanupDevice();
|
||||
UnregisterClass(L"ImGui Example", wc.hInstance);
|
||||
return 1;
|
||||
}
|
||||
@ -295,36 +293,31 @@ int WINAPI wWinMain(HINSTANCE hInst, HINSTANCE, LPWSTR, int)
|
||||
|
||||
UpdateImGui();
|
||||
|
||||
// Create a simple window
|
||||
// Tip: if we don't call ImGui::Begin()/ImGui::End() the widgets appears in a window automatically called "Debug"
|
||||
static bool show_test_window = true;
|
||||
static bool show_another_window = false;
|
||||
static float f;
|
||||
ImGui::Text("Hello, world!");
|
||||
ImGui::SliderFloat("float", &f, 0.0f, 1.0f);
|
||||
show_test_window ^= ImGui::Button("Test Window");
|
||||
show_another_window ^= ImGui::Button("Another Window");
|
||||
|
||||
// Calculate and show framerate
|
||||
static float ms_per_frame[120] = { 0 };
|
||||
static int ms_per_frame_idx = 0;
|
||||
static float ms_per_frame_accum = 0.0f;
|
||||
ms_per_frame_accum -= ms_per_frame[ms_per_frame_idx];
|
||||
ms_per_frame[ms_per_frame_idx] = ImGui::GetIO().DeltaTime * 1000.0f;
|
||||
ms_per_frame_accum += ms_per_frame[ms_per_frame_idx];
|
||||
ms_per_frame_idx = (ms_per_frame_idx + 1) % 120;
|
||||
const float ms_per_frame_avg = ms_per_frame_accum / 120;
|
||||
ImGui::Text("Application average %.3f ms/frame (%.1f FPS)", ms_per_frame_avg, 1000.0f / ms_per_frame_avg);
|
||||
|
||||
// Show the ImGui test window
|
||||
// Most of user example code is in ImGui::ShowTestWindow()
|
||||
if (show_test_window)
|
||||
// 1. Show a simple window
|
||||
// Tip: if we don't call ImGui::Begin()/ImGui::End() the widgets appears in a window automatically called "Debug"
|
||||
{
|
||||
ImGui::SetNewWindowDefaultPos(ImVec2(650, 20)); // Normally user code doesn't need/want to call it because positions are saved in .ini file anyway. Here we just want to make the demo initial state a bit more friendly!
|
||||
ImGui::ShowTestWindow(&show_test_window);
|
||||
static float f;
|
||||
ImGui::Text("Hello, world!");
|
||||
ImGui::SliderFloat("float", &f, 0.0f, 1.0f);
|
||||
show_test_window ^= ImGui::Button("Test Window");
|
||||
show_another_window ^= ImGui::Button("Another Window");
|
||||
|
||||
// Calculate and show frame rate
|
||||
static float ms_per_frame[120] = { 0 };
|
||||
static int ms_per_frame_idx = 0;
|
||||
static float ms_per_frame_accum = 0.0f;
|
||||
ms_per_frame_accum -= ms_per_frame[ms_per_frame_idx];
|
||||
ms_per_frame[ms_per_frame_idx] = ImGui::GetIO().DeltaTime * 1000.0f;
|
||||
ms_per_frame_accum += ms_per_frame[ms_per_frame_idx];
|
||||
ms_per_frame_idx = (ms_per_frame_idx + 1) % 120;
|
||||
const float ms_per_frame_avg = ms_per_frame_accum / 120;
|
||||
ImGui::Text("Application average %.3f ms/frame (%.1f FPS)", ms_per_frame_avg, 1000.0f / ms_per_frame_avg);
|
||||
}
|
||||
|
||||
// Show another simple window
|
||||
// 2. Show another simple window, this time using an explicit Begin/End pair
|
||||
if (show_another_window)
|
||||
{
|
||||
ImGui::Begin("Another Window", &show_another_window, ImVec2(200,100));
|
||||
@ -332,6 +325,13 @@ int WINAPI wWinMain(HINSTANCE hInst, HINSTANCE, LPWSTR, int)
|
||||
ImGui::End();
|
||||
}
|
||||
|
||||
// 3. Show the ImGui test window. Most of the sample code is in ImGui::ShowTestWindow()
|
||||
if (show_test_window)
|
||||
{
|
||||
ImGui::SetNewWindowDefaultPos(ImVec2(650, 20)); // Normally user code doesn't need/want to call it because positions are saved in .ini file anyway. Here we just want to make the demo initial state a bit more friendly!
|
||||
ImGui::ShowTestWindow(&show_test_window);
|
||||
}
|
||||
|
||||
// Rendering
|
||||
g_pd3dDevice->SetRenderState(D3DRS_ZENABLE, false);
|
||||
g_pd3dDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, false);
|
||||
@ -347,9 +347,6 @@ int WINAPI wWinMain(HINSTANCE hInst, HINSTANCE, LPWSTR, int)
|
||||
|
||||
ImGui::Shutdown();
|
||||
|
||||
if (g_pVB)
|
||||
g_pVB->Release();
|
||||
|
||||
UnregisterClass(L"ImGui Example", wc.hInstance);
|
||||
return 0;
|
||||
}
|
||||
|
32
examples/imgui_examples_msvc2010.sln
Normal file
@ -0,0 +1,32 @@
|
||||
|
||||
Microsoft Visual Studio Solution File, Format Version 11.00
|
||||
# Visual Studio 2010
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "opengl_example", "opengl_example\opengl_example.vcxproj", "{9CDA7840-B7A5-496D-A527-E95571496D18}"
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "directx9_example", "directx9_example\directx9_example.vcxproj", "{4165A294-21F2-44CA-9B38-E3F935ABADF5}"
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "directx11_example", "directx11_example\directx11_example.vcxproj", "{9F316E83-5AE5-4939-A723-305A94F48005}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Win32 = Debug|Win32
|
||||
Release|Win32 = Release|Win32
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||
{9CDA7840-B7A5-496D-A527-E95571496D18}.Debug|Win32.ActiveCfg = Debug|Win32
|
||||
{9CDA7840-B7A5-496D-A527-E95571496D18}.Debug|Win32.Build.0 = Debug|Win32
|
||||
{9CDA7840-B7A5-496D-A527-E95571496D18}.Release|Win32.ActiveCfg = Release|Win32
|
||||
{9CDA7840-B7A5-496D-A527-E95571496D18}.Release|Win32.Build.0 = Release|Win32
|
||||
{4165A294-21F2-44CA-9B38-E3F935ABADF5}.Debug|Win32.ActiveCfg = Debug|Win32
|
||||
{4165A294-21F2-44CA-9B38-E3F935ABADF5}.Debug|Win32.Build.0 = Debug|Win32
|
||||
{4165A294-21F2-44CA-9B38-E3F935ABADF5}.Release|Win32.ActiveCfg = Release|Win32
|
||||
{4165A294-21F2-44CA-9B38-E3F935ABADF5}.Release|Win32.Build.0 = Release|Win32
|
||||
{9F316E83-5AE5-4939-A723-305A94F48005}.Debug|Win32.ActiveCfg = Debug|Win32
|
||||
{9F316E83-5AE5-4939-A723-305A94F48005}.Debug|Win32.Build.0 = Debug|Win32
|
||||
{9F316E83-5AE5-4939-A723-305A94F48005}.Release|Win32.ActiveCfg = Release|Win32
|
||||
{9F316E83-5AE5-4939-A723-305A94F48005}.Release|Win32.Build.0 = Release|Win32
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
EndGlobalSection
|
||||
EndGlobal
|
53
examples/opengl_example/Makefile
Normal file
@ -0,0 +1,53 @@
|
||||
#
|
||||
# Cross Platform Make file
|
||||
#
|
||||
# Compatible with Ubuntu 14.04.1 and Mac OS X
|
||||
#
|
||||
#
|
||||
# if you using Mac OS X:
|
||||
# You should install glew via homebrew
|
||||
# brew install glew
|
||||
# Also you'll need glfw
|
||||
# http://www.glfw.org
|
||||
#
|
||||
|
||||
CXX = g++
|
||||
|
||||
OBJS = main.o
|
||||
OBJS += ../../imgui.o
|
||||
|
||||
UNAME_S := $(shell uname -s)
|
||||
|
||||
|
||||
ifeq ($(UNAME_S), Linux) #LINUX
|
||||
ECHO_MESSAGE = "Linux"
|
||||
CXXFLAGS = -I../../ `pkg-config --cflags glfw3`
|
||||
LIBS = `pkg-config --static --libs glfw3` -lGLEW
|
||||
endif
|
||||
|
||||
ifeq ($(UNAME_S), Darwin) #APPLE
|
||||
ECHO_MESSAGE = "Mac OS X"
|
||||
|
||||
LIBS = -framework OpenGL -framework Cocoa -framework IOKit -framework CoreVideo
|
||||
LIBS += -L/usr/local/Cellar/glew/1.10.0/lib -L/usr/local/lib
|
||||
LIBS += -lglew -lglfw3
|
||||
|
||||
CXXFLAGS = -I/usr/local/Cellar/glew/1.10.0/include -I/usr/local/include
|
||||
CXXFLAGS += -I../../
|
||||
|
||||
# CXXFLAGS += -D__APPLE__
|
||||
|
||||
endif
|
||||
|
||||
.cpp.o:
|
||||
$(CXX) $(CXXFLAGS) -c -o $@ $<
|
||||
|
||||
all:imgui_example
|
||||
@echo Build complete for $(ECHO_MESSAGE)
|
||||
|
||||
imgui_example:$(OBJS)
|
||||
$(CXX) -o imgui_example $(OBJS) $(CXXFLAGS) $(LIBS)
|
||||
|
||||
clean:
|
||||
rm $(OBJS)
|
||||
|
@ -1,18 +0,0 @@
|
||||
#
|
||||
# Quick and dirty makefile to build on Linux
|
||||
# tested on Ubuntu 14.04.1 32bit
|
||||
#
|
||||
|
||||
SRC = main.cpp ../../imgui.cpp
|
||||
|
||||
OBJ = $(SRC:.cpp=.o)
|
||||
|
||||
CXXFLAGS = -I../../ `pkg-config --cflags glfw3`
|
||||
|
||||
LIBS = `pkg-config --static --libs glfw3` -lGLEW
|
||||
|
||||
all: $(OBJ)
|
||||
$(CXX) $(OBJ) $(LIBS)
|
||||
|
||||
clean:
|
||||
$(RM) -f $(OBJ)
|
@ -1,18 +0,0 @@
|
||||
# This makefile currently only works for mac os
|
||||
# You should install via homebrew:
|
||||
# brew install glew
|
||||
# brew install glfw3
|
||||
#
|
||||
|
||||
CXXFLAGS=-framework OpenGL -framework Cocoa -framework IOKit
|
||||
CXXFLAGS+=-I/usr/local/Cellar/glew/1.10.0/include -I/usr/local/Cellar/glfw3/3.0.4/include
|
||||
CXXFLAGS+=-L/usr/local/Cellar/glew/1.10.0/lib -L/usr/local/Cellar/glfw3/3.0.4/lib
|
||||
CXXFLAGS+=-lglew -lglfw3
|
||||
CXXFLAGS+=-I../../
|
||||
CXXFLAGS+= -D__APPLE__
|
||||
|
||||
main: main.cpp ../../imgui.cpp
|
||||
$(CXX) $(CXXFLAGS) -o $@ $^
|
||||
|
||||
clean:
|
||||
rm main
|
@ -1,15 +1,25 @@
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning (disable: 4996) // 'This function or variable may be unsafe': strcpy, strdup, sprintf, vsnprintf, sscanf, fopen
|
||||
#include <Windows.h>
|
||||
#endif
|
||||
#define STB_IMAGE_IMPLEMENTATION
|
||||
#include "../shared/stb_image.h" // for .png loading
|
||||
#include "../../imgui.h"
|
||||
|
||||
// glew & glfw
|
||||
#define GLEW_STATIC
|
||||
#include <GL/glew.h>
|
||||
#include <GLFW/glfw3.h>
|
||||
#define STB_IMAGE_IMPLEMENTATION
|
||||
#include "stb_image.h" // for .png loading
|
||||
#include "../../imgui.h"
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning (disable: 4996) // 'This function or variable may be unsafe': strcpy, strdup, sprintf, vsnprintf, sscanf, fopen
|
||||
#define GLFW_EXPOSE_NATIVE_WIN32
|
||||
#define GLFW_EXPOSE_NATIVE_WGL
|
||||
#include <GLFW/glfw3native.h>
|
||||
#endif
|
||||
|
||||
static GLFWwindow* window;
|
||||
static GLuint fontTex;
|
||||
static bool mousePressed[2] = { 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:
|
||||
@ -23,6 +33,7 @@ static void ImImpl_RenderDrawLists(ImDrawList** const cmd_lists, int cmd_lists_c
|
||||
// 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.
|
||||
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);
|
||||
@ -40,72 +51,70 @@ static void ImImpl_RenderDrawLists(ImDrawList** const cmd_lists, int cmd_lists_c
|
||||
const float width = ImGui::GetIO().DisplaySize.x;
|
||||
const float height = ImGui::GetIO().DisplaySize.y;
|
||||
glMatrixMode(GL_PROJECTION);
|
||||
glPushMatrix();
|
||||
glLoadIdentity();
|
||||
glOrtho(0.0f, width, height, 0.0f, -1.0f, +1.0f);
|
||||
glMatrixMode(GL_MODELVIEW);
|
||||
glPushMatrix();
|
||||
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));
|
||||
const unsigned char* vtx_buffer = (const unsigned char*)&cmd_list->vtx_buffer.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)));
|
||||
|
||||
int vtx_offset = 0;
|
||||
const ImDrawCmd* pcmd_end = cmd_list->commands.end();
|
||||
for (const ImDrawCmd* pcmd = cmd_list->commands.begin(); pcmd != pcmd_end; pcmd++)
|
||||
for (size_t cmd_i = 0; cmd_i < cmd_list->commands.size(); cmd_i++)
|
||||
{
|
||||
const ImDrawCmd* pcmd = &cmd_list->commands[cmd_i];
|
||||
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);
|
||||
|
||||
// Restore modified state
|
||||
glDisableClientState(GL_COLOR_ARRAY);
|
||||
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
|
||||
glDisableClientState(GL_VERTEX_ARRAY);
|
||||
glMatrixMode(GL_MODELVIEW);
|
||||
glPopMatrix();
|
||||
glMatrixMode(GL_PROJECTION);
|
||||
glPopMatrix();
|
||||
glPopAttrib();
|
||||
}
|
||||
|
||||
// NB: ImGui already provide OS clipboard support for Windows so this isn't needed if you are using Windows only.
|
||||
static const char* ImImpl_GetClipboardTextFn()
|
||||
{
|
||||
return glfwGetClipboardString(window);
|
||||
}
|
||||
|
||||
static void ImImpl_SetClipboardTextFn(const char* text, const char* text_end)
|
||||
static void ImImpl_SetClipboardTextFn(const char* text)
|
||||
{
|
||||
if (!text_end)
|
||||
text_end = text + strlen(text);
|
||||
|
||||
if (*text_end == 0)
|
||||
{
|
||||
// Already got a zero-terminator at 'text_end', we don't need to add one
|
||||
glfwSetClipboardString(window, text);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Add a zero-terminator because glfw function doesn't take a size
|
||||
char* buf = (char*)malloc(text_end - text + 1);
|
||||
memcpy(buf, text, text_end-text);
|
||||
buf[text_end-text] = '\0';
|
||||
glfwSetClipboardString(window, buf);
|
||||
free(buf);
|
||||
}
|
||||
glfwSetClipboardString(window, text);
|
||||
}
|
||||
|
||||
|
||||
// GLFW callbacks to get events
|
||||
static void glfw_error_callback(int error, const char* description)
|
||||
{
|
||||
fputs(description, stderr);
|
||||
}
|
||||
|
||||
static void glfw_mouse_button_callback(GLFWwindow* window, int button, int action, int mods)
|
||||
{
|
||||
if (action == GLFW_PRESS && button >= 0 && button < 2)
|
||||
mousePressed[button] = true;
|
||||
}
|
||||
|
||||
static void glfw_scroll_callback(GLFWwindow* window, double xoffset, double yoffset)
|
||||
{
|
||||
ImGuiIO& io = ImGui::GetIO();
|
||||
io.MouseWheel = (yoffset != 0.0f) ? yoffset > 0.0f ? 1 : - 1 : 0; // Mouse wheel: -1,0,+1
|
||||
io.MouseWheel += (float)yoffset; // Use fractional mouse wheel, 1.0 unit 5 lines.
|
||||
}
|
||||
|
||||
static void glfw_key_callback(GLFWwindow* window, int key, int scancode, int action, int mods)
|
||||
@ -121,8 +130,8 @@ static void glfw_key_callback(GLFWwindow* window, int key, int scancode, int act
|
||||
|
||||
static void glfw_char_callback(GLFWwindow* window, unsigned int c)
|
||||
{
|
||||
if (c > 0 && c <= 255)
|
||||
ImGui::GetIO().AddInputCharacter((char)c);
|
||||
if (c > 0 && c < 0x10000)
|
||||
ImGui::GetIO().AddInputCharacter((unsigned short)c);
|
||||
}
|
||||
|
||||
// OpenGL code based on http://open.gl tutorials
|
||||
@ -137,6 +146,7 @@ void InitGL()
|
||||
window = glfwCreateWindow(1280, 720, "ImGui OpenGL example", NULL, NULL);
|
||||
glfwMakeContextCurrent(window);
|
||||
glfwSetKeyCallback(window, glfw_key_callback);
|
||||
glfwSetMouseButtonCallback(window, glfw_mouse_button_callback);
|
||||
glfwSetScrollCallback(window, glfw_scroll_callback);
|
||||
glfwSetCharCallback(window, glfw_char_callback);
|
||||
|
||||
@ -146,13 +156,17 @@ void InitGL()
|
||||
void InitImGui()
|
||||
{
|
||||
int w, h;
|
||||
int display_w, display_h;
|
||||
glfwGetWindowSize(window, &w, &h);
|
||||
glfwGetFramebufferSize(window, &display_w, &display_h);
|
||||
mousePosScale.x = (float)display_w / w; // Some screens e.g. Retina display have framebuffer size != from window size, and mouse inputs are given in window/screen coordinates.
|
||||
mousePosScale.y = (float)display_h / h;
|
||||
|
||||
ImGuiIO& io = ImGui::GetIO();
|
||||
io.DisplaySize = ImVec2((float)w, (float)h); // Display size, in pixels. For clamping windows positions.
|
||||
io.DeltaTime = 1.0f/60.0f; // Time elapsed since last frame, in seconds (in this sample app we'll override this every frame because our timestep is variable)
|
||||
io.PixelCenterOffset = 0.0f; // Align OpenGL texels
|
||||
io.KeyMap[ImGuiKey_Tab] = GLFW_KEY_TAB; // Keyboard mapping. ImGui will use those indices to peek into the io.KeyDown[] array.
|
||||
io.DisplaySize = ImVec2((float)display_w, (float)display_h); // Display size, in pixels. For clamping windows positions.
|
||||
io.DeltaTime = 1.0f/60.0f; // Time elapsed since last frame, in seconds (in this sample app we'll override this every frame because our time step is variable)
|
||||
io.PixelCenterOffset = 0.0f; // Align OpenGL texels
|
||||
io.KeyMap[ImGuiKey_Tab] = GLFW_KEY_TAB; // Keyboard mapping. ImGui will use those indices to peek into the io.KeyDown[] array.
|
||||
io.KeyMap[ImGuiKey_LeftArrow] = GLFW_KEY_LEFT;
|
||||
io.KeyMap[ImGuiKey_RightArrow] = GLFW_KEY_RIGHT;
|
||||
io.KeyMap[ImGuiKey_UpArrow] = GLFW_KEY_UP;
|
||||
@ -179,11 +193,35 @@ void InitImGui()
|
||||
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);
|
||||
|
||||
#if 1
|
||||
// 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);
|
||||
#else
|
||||
// Custom font from filesystem
|
||||
io.Font = new ImFont();
|
||||
io.Font->LoadFromFile("../../extra_fonts/mplus-2m-medium_18.fnt");
|
||||
IM_ASSERT(io.Font->IsLoaded());
|
||||
|
||||
int tex_x, tex_y, tex_comp;
|
||||
void* tex_data = stbi_load("../../extra_fonts/mplus-2m-medium_18.png", &tex_x, &tex_y, &tex_comp, 0);
|
||||
IM_ASSERT(tex_data != NULL);
|
||||
|
||||
// Automatically find white pixel from the texture we just loaded
|
||||
// (io.Font->TexUvForWhite needs to contains UV coordinates pointing to a white pixel in order to render solid objects)
|
||||
for (int tex_data_off = 0; tex_data_off < tex_x*tex_y; tex_data_off++)
|
||||
if (((unsigned int*)tex_data)[tex_data_off] == 0xffffffff)
|
||||
{
|
||||
io.Font->TexUvForWhite = ImVec2((float)(tex_data_off % tex_x)/(tex_x), (float)(tex_data_off / tex_x)/(tex_y));
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, tex_x, tex_y, 0, GL_RGBA, GL_UNSIGNED_BYTE, tex_data);
|
||||
stbi_image_free(tex_data);
|
||||
}
|
||||
@ -192,7 +230,7 @@ void UpdateImGui()
|
||||
{
|
||||
ImGuiIO& io = ImGui::GetIO();
|
||||
|
||||
// Setup timestep
|
||||
// Setup time step
|
||||
static double time = 0.0f;
|
||||
const double current_time = glfwGetTime();
|
||||
io.DeltaTime = (float)(current_time - time);
|
||||
@ -202,9 +240,9 @@ void UpdateImGui()
|
||||
// (we already got mouse wheel, keyboard keys & characters from glfw callbacks polled in glfwPollEvents())
|
||||
double mouse_x, mouse_y;
|
||||
glfwGetCursorPos(window, &mouse_x, &mouse_y);
|
||||
io.MousePos = ImVec2((float)mouse_x, (float)mouse_y); // Mouse position, in pixels (set to -1,-1 if no mouse / on another screen, etc.)
|
||||
io.MouseDown[0] = glfwGetMouseButton(window, GLFW_MOUSE_BUTTON_LEFT) != 0;
|
||||
io.MouseDown[1] = glfwGetMouseButton(window, GLFW_MOUSE_BUTTON_RIGHT) != 0;
|
||||
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] || glfwGetMouseButton(window, GLFW_MOUSE_BUTTON_LEFT) != 0; // If a mouse press event came, always pass it as "mouse held this frame", so we don't miss click-release events that are shorter than 1 frame.
|
||||
io.MouseDown[1] = mousePressed[1] || glfwGetMouseButton(window, GLFW_MOUSE_BUTTON_RIGHT) != 0;
|
||||
|
||||
// Start the frame
|
||||
ImGui::NewFrame();
|
||||
@ -219,40 +257,35 @@ int main(int argc, char** argv)
|
||||
while (!glfwWindowShouldClose(window))
|
||||
{
|
||||
ImGuiIO& io = ImGui::GetIO();
|
||||
io.MouseWheel = 0;
|
||||
mousePressed[0] = mousePressed[1] = false;
|
||||
glfwPollEvents();
|
||||
UpdateImGui();
|
||||
|
||||
// Create a simple window
|
||||
// Tip: if we don't call ImGui::Begin()/ImGui::End() the widgets appears in a window automatically called "Debug"
|
||||
static bool show_test_window = true;
|
||||
static bool show_another_window = false;
|
||||
static float f;
|
||||
ImGui::Text("Hello, world!");
|
||||
ImGui::SliderFloat("float", &f, 0.0f, 1.0f);
|
||||
show_test_window ^= ImGui::Button("Test Window");
|
||||
show_another_window ^= ImGui::Button("Another Window");
|
||||
|
||||
// Calculate and show framerate
|
||||
static float ms_per_frame[120] = { 0 };
|
||||
static int ms_per_frame_idx = 0;
|
||||
static float ms_per_frame_accum = 0.0f;
|
||||
ms_per_frame_accum -= ms_per_frame[ms_per_frame_idx];
|
||||
ms_per_frame[ms_per_frame_idx] = ImGui::GetIO().DeltaTime * 1000.0f;
|
||||
ms_per_frame_accum += ms_per_frame[ms_per_frame_idx];
|
||||
ms_per_frame_idx = (ms_per_frame_idx + 1) % 120;
|
||||
const float ms_per_frame_avg = ms_per_frame_accum / 120;
|
||||
ImGui::Text("Application average %.3f ms/frame (%.1f FPS)", ms_per_frame_avg, 1000.0f / ms_per_frame_avg);
|
||||
|
||||
// Show the ImGui test window
|
||||
// Most of user example code is in ImGui::ShowTestWindow()
|
||||
if (show_test_window)
|
||||
// 1. Show a simple window
|
||||
// Tip: if we don't call ImGui::Begin()/ImGui::End() the widgets appears in a window automatically called "Debug"
|
||||
{
|
||||
ImGui::SetNewWindowDefaultPos(ImVec2(650, 20)); // Normally user code doesn't need/want to call it because positions are saved in .ini file anyway. Here we just want to make the demo initial state a bit more friendly!
|
||||
ImGui::ShowTestWindow(&show_test_window);
|
||||
static float f;
|
||||
ImGui::Text("Hello, world!");
|
||||
ImGui::SliderFloat("float", &f, 0.0f, 1.0f);
|
||||
show_test_window ^= ImGui::Button("Test Window");
|
||||
show_another_window ^= ImGui::Button("Another Window");
|
||||
|
||||
// Calculate and show frame rate
|
||||
static float ms_per_frame[120] = { 0 };
|
||||
static int ms_per_frame_idx = 0;
|
||||
static float ms_per_frame_accum = 0.0f;
|
||||
ms_per_frame_accum -= ms_per_frame[ms_per_frame_idx];
|
||||
ms_per_frame[ms_per_frame_idx] = ImGui::GetIO().DeltaTime * 1000.0f;
|
||||
ms_per_frame_accum += ms_per_frame[ms_per_frame_idx];
|
||||
ms_per_frame_idx = (ms_per_frame_idx + 1) % 120;
|
||||
const float ms_per_frame_avg = ms_per_frame_accum / 120;
|
||||
ImGui::Text("Application average %.3f ms/frame (%.1f FPS)", ms_per_frame_avg, 1000.0f / ms_per_frame_avg);
|
||||
}
|
||||
|
||||
// Show another simple window
|
||||
// 2. Show another simple window, this time using an explicit Begin/End pair
|
||||
if (show_another_window)
|
||||
{
|
||||
ImGui::Begin("Another Window", &show_another_window, ImVec2(200,100));
|
||||
@ -260,6 +293,13 @@ int main(int argc, char** argv)
|
||||
ImGui::End();
|
||||
}
|
||||
|
||||
// 3. Show the ImGui test window. Most of the sample code is in ImGui::ShowTestWindow()
|
||||
if (show_test_window)
|
||||
{
|
||||
ImGui::SetNewWindowDefaultPos(ImVec2(650, 20)); // Normally user code doesn't need/want to call this, because positions are saved in .ini file. Here we just want to make the demo initial state a bit more friendly!
|
||||
ImGui::ShowTestWindow(&show_test_window);
|
||||
}
|
||||
|
||||
// Rendering
|
||||
glViewport(0, 0, (int)io.DisplaySize.x, (int)io.DisplaySize.y);
|
||||
glClearColor(0.8f, 0.6f, 0.6f, 1.0f);
|
||||
|
@ -1,20 +0,0 @@
|
||||
|
||||
Microsoft Visual Studio Solution File, Format Version 11.00
|
||||
# Visual Studio 2010
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "opengl_example", "opengl_example.vcxproj", "{9CDA7840-B7A5-496D-A527-E95571496D18}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Win32 = Debug|Win32
|
||||
Release|Win32 = Release|Win32
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||
{9CDA7840-B7A5-496D-A527-E95571496D18}.Debug|Win32.ActiveCfg = Debug|Win32
|
||||
{9CDA7840-B7A5-496D-A527-E95571496D18}.Debug|Win32.Build.0 = Debug|Win32
|
||||
{9CDA7840-B7A5-496D-A527-E95571496D18}.Release|Win32.ActiveCfg = Release|Win32
|
||||
{9CDA7840-B7A5-496D-A527-E95571496D18}.Release|Win32.Build.0 = Release|Win32
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
EndGlobalSection
|
||||
EndGlobal
|
@ -46,7 +46,7 @@
|
||||
<Link>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<AdditionalLibraryDirectories>$(SolutionDir)\glfw\lib-msvc100;$(SolutionDir)\glew\lib\Release\Win32;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
||||
<AdditionalDependencies>opengl32.lib;glfw3.lib;glew32s.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<AdditionalDependencies>opengl32.lib;imm32.lib;glfw3.lib;glew32s.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<SubSystem>NotSet</SubSystem>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
@ -63,7 +63,7 @@
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
<AdditionalLibraryDirectories>$(SolutionDir)\glfw\lib-msvc100;$(SolutionDir)\glew\lib\Release\Win32;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
||||
<AdditionalDependencies>opengl32.lib;glfw3.lib;glew32s.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<AdditionalDependencies>opengl32.lib;imm32.lib;glfw3.lib;glew32s.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<SubSystem>NotSet</SubSystem>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
@ -75,7 +75,7 @@
|
||||
<ClInclude Include="..\..\imconfig.h" />
|
||||
<ClInclude Include="..\..\imgui.h" />
|
||||
<ClInclude Include="..\..\stb_textedit.h" />
|
||||
<ClInclude Include="stb_image.h" />
|
||||
<ClInclude Include="..\shared\stb_image.h" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="..\..\LICENSE" />
|
||||
|
@ -18,9 +18,6 @@
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="stb_image.h">
|
||||
<Filter>sources</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\imconfig.h">
|
||||
<Filter>imgui</Filter>
|
||||
</ClInclude>
|
||||
@ -30,6 +27,9 @@
|
||||
<ClInclude Include="..\..\stb_textedit.h">
|
||||
<Filter>imgui</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\shared\stb_image.h">
|
||||
<Filter>sources</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="..\..\LICENSE">
|
||||
|
3
examples/shared/README.txt
Normal file
@ -0,0 +1,3 @@
|
||||
stb_image.h is used to load the PNG texture data by
|
||||
opengl_example
|
||||
directx11_example
|
@ -1,4 +1,4 @@
|
||||
/* stb_image - v1.43 - public domain JPEG/PNG reader - http://nothings.org/stb_image.c
|
||||
/* stb_image - v1.46 - public domain JPEG/PNG reader - http://nothings.org/stb_image.c
|
||||
when you control the images you're loading
|
||||
no warranty implied; use at your own risk
|
||||
|
||||
@ -13,7 +13,7 @@
|
||||
avoid problematic images and only need the trivial interface
|
||||
|
||||
JPEG baseline (no JPEG progressive)
|
||||
PNG 8-bit-per-channel only
|
||||
PNG 1/2/4/8-bit-per-channel (16 bpc not supported)
|
||||
|
||||
TGA (not sure what subset, if a subset)
|
||||
BMP non-1bpp, non-RLE
|
||||
@ -28,11 +28,15 @@
|
||||
- overridable dequantizing-IDCT, YCbCr-to-RGB conversion (define STBI_SIMD)
|
||||
|
||||
Latest revisions:
|
||||
1.xx (2014-09-26) 1/2/4-bit PNG support (both grayscale and paletted)
|
||||
1.46 (2014-08-26) fix broken tRNS chunk in non-paletted PNG
|
||||
1.45 (2014-08-16) workaround MSVC-ARM internal compiler error by wrapping malloc
|
||||
1.44 (2014-08-07) warnings
|
||||
1.43 (2014-07-15) fix MSVC-only bug in 1.42
|
||||
1.42 (2014-07-09) no _CRT_SECURE_NO_WARNINGS; error-path fixes; STBI_ASSERT
|
||||
1.41 (2014-06-25) fix search&replace that messed up comments/error messages
|
||||
1.40 (2014-06-22) gcc warning
|
||||
1.39 (2014-06-15) TGA optimization fix, multiple BMP fixes
|
||||
1.39 (2014-06-15) TGA optimization bugfix, multiple BMP fixes
|
||||
1.38 (2014-06-06) suppress MSVC run-time warnings, fix accidental rename of 'skip'
|
||||
1.37 (2014-06-04) remove duplicate typedef
|
||||
1.36 (2014-06-03) converted to header file, allow reading incorrect iphoned-images without iphone flag
|
||||
@ -60,17 +64,19 @@
|
||||
James "moose2000" Brown (iPhone PNG) David Woo
|
||||
Ben "Disch" Wenger (io callbacks) Roy Eltham
|
||||
Martin "SpartanJ" Golini Luke Graham
|
||||
Thomas Ruf
|
||||
Omar Cornut (1/2/4-bit png) Thomas Ruf
|
||||
John Bartholomew
|
||||
Optimizations & bugfixes Ken Hamada
|
||||
Fabian "ryg" Giesen Cort Stratton
|
||||
Arseny Kapoulkine Blazej Dariusz Roszkowski
|
||||
Thibault Reuille
|
||||
If your name should be here but Paul Du Bois
|
||||
isn't, let Sean know. Guillaume George
|
||||
Paul Du Bois
|
||||
Guillaume George
|
||||
Jerry Jansson
|
||||
Hayaki Saito
|
||||
Johan Duparc
|
||||
If your name should be here but Hayaki Saito
|
||||
isn't, let Sean know. Johan Duparc
|
||||
Ronny Chevalier
|
||||
Michal Cichon
|
||||
*/
|
||||
|
||||
#ifndef STBI_INCLUDE_STB_IMAGE_H
|
||||
@ -525,6 +531,11 @@ static int stbi__err(const char *str)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void *stbi__malloc(size_t size)
|
||||
{
|
||||
return malloc(size);
|
||||
}
|
||||
|
||||
// stbi__err - error
|
||||
// stbi__errpf - error returning pointer to float
|
||||
// stbi__errpuc - error returning pointer to unsigned char
|
||||
@ -577,11 +588,11 @@ static unsigned char *stbi_load_main(stbi__context *s, int *x, int *y, int *comp
|
||||
FILE *stbi__fopen(char const *filename, char const *mode)
|
||||
{
|
||||
FILE *f;
|
||||
#if _MSC_VER >= 1400
|
||||
if (0 != fopen_s(&f, filename, "rb"))
|
||||
#if defined(_MSC_VER) && _MSC_VER >= 1400
|
||||
if (0 != fopen_s(&f, filename, mode))
|
||||
f=0;
|
||||
#else
|
||||
f = fopen(filename, "rb");
|
||||
f = fopen(filename, mode);
|
||||
#endif
|
||||
return f;
|
||||
}
|
||||
@ -756,7 +767,7 @@ static void stbi__refill_buffer(stbi__context *s)
|
||||
int n = (s->io.read)(s->io_user_data,(char*)s->buffer_start,s->buflen);
|
||||
if (n == 0) {
|
||||
// at end of file, treat same as if from memory, but need to handle case
|
||||
// where s->img_buffer isn't pointing to safe memory, stbi__err.g. 0-byte file
|
||||
// where s->img_buffer isn't pointing to safe memory, e.g. 0-byte file
|
||||
s->read_from_callbacks = 0;
|
||||
s->img_buffer = s->buffer_start;
|
||||
s->img_buffer_end = s->buffer_start+1;
|
||||
@ -854,7 +865,7 @@ static stbi__uint32 stbi__get32le(stbi__context *s)
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// generic converter from built-in img_n to req_comp
|
||||
// individual types do this automatically as much as possible (stbi__err.g. jpeg
|
||||
// individual types do this automatically as much as possible (e.g. jpeg
|
||||
// does all cases internally since it needs to colorspace convert anyway,
|
||||
// and it never has alpha, so very few cases ). png can automatically
|
||||
// interleave an alpha=255 channel, but falls back to this for other cases
|
||||
@ -875,7 +886,7 @@ static unsigned char *stbi__convert_format(unsigned char *data, int img_n, int r
|
||||
if (req_comp == img_n) return data;
|
||||
STBI_ASSERT(req_comp >= 1 && req_comp <= 4);
|
||||
|
||||
good = (unsigned char *) malloc(req_comp * x * y);
|
||||
good = (unsigned char *) stbi__malloc(req_comp * x * y);
|
||||
if (good == NULL) {
|
||||
free(data);
|
||||
return stbi__errpuc("outofmem", "Out of memory");
|
||||
@ -915,7 +926,7 @@ static unsigned char *stbi__convert_format(unsigned char *data, int img_n, int r
|
||||
static float *stbi__ldr_to_hdr(stbi_uc *data, int x, int y, int comp)
|
||||
{
|
||||
int i,k,n;
|
||||
float *output = (float *) malloc(x * y * comp * sizeof(float));
|
||||
float *output = (float *) stbi__malloc(x * y * comp * sizeof(float));
|
||||
if (output == NULL) { free(data); return stbi__errpf("outofmem", "Out of memory"); }
|
||||
// compute number of non-alpha components
|
||||
if (comp & 1) n = comp; else n = comp-1;
|
||||
@ -933,7 +944,7 @@ static float *stbi__ldr_to_hdr(stbi_uc *data, int x, int y, int comp)
|
||||
static stbi_uc *stbi__hdr_to_ldr(float *data, int x, int y, int comp)
|
||||
{
|
||||
int i,k,n;
|
||||
stbi_uc *output = (stbi_uc *) malloc(x * y * comp);
|
||||
stbi_uc *output = (stbi_uc *) stbi__malloc(x * y * comp);
|
||||
if (output == NULL) { free(data); return stbi__errpuc("outofmem", "Out of memory"); }
|
||||
// compute number of non-alpha components
|
||||
if (comp & 1) n = comp; else n = comp-1;
|
||||
@ -1601,16 +1612,16 @@ static int stbi__process_frame_header(stbi__jpeg *z, int scan)
|
||||
z->img_mcu_y = (s->img_y + z->img_mcu_h-1) / z->img_mcu_h;
|
||||
|
||||
for (i=0; i < s->img_n; ++i) {
|
||||
// number of effective pixels (stbi__err.g. for non-interleaved MCU)
|
||||
// number of effective pixels (e.g. for non-interleaved MCU)
|
||||
z->img_comp[i].x = (s->img_x * z->img_comp[i].h + h_max-1) / h_max;
|
||||
z->img_comp[i].y = (s->img_y * z->img_comp[i].v + v_max-1) / v_max;
|
||||
// to simplify generation, we'll allocate enough memory to decode
|
||||
// the bogus oversized data from using interleaved MCUs and their
|
||||
// big blocks (stbi__err.g. a 16x16 iMCU on an image of width 33); we won't
|
||||
// big blocks (e.g. a 16x16 iMCU on an image of width 33); we won't
|
||||
// discard the extra data until colorspace conversion
|
||||
z->img_comp[i].w2 = z->img_mcu_x * z->img_comp[i].h * 8;
|
||||
z->img_comp[i].h2 = z->img_mcu_y * z->img_comp[i].v * 8;
|
||||
z->img_comp[i].raw_data = malloc(z->img_comp[i].w2 * z->img_comp[i].h2+15);
|
||||
z->img_comp[i].raw_data = stbi__malloc(z->img_comp[i].w2 * z->img_comp[i].h2+15);
|
||||
if (z->img_comp[i].raw_data == NULL) {
|
||||
for(--i; i >= 0; --i) {
|
||||
free(z->img_comp[i].raw_data);
|
||||
@ -1626,7 +1637,7 @@ static int stbi__process_frame_header(stbi__jpeg *z, int scan)
|
||||
return 1;
|
||||
}
|
||||
|
||||
// use comparisons since in some cases we handle more than one case (stbi__err.g. stbi__SOF)
|
||||
// use comparisons since in some cases we handle more than one case (e.g. stbi__SOF)
|
||||
#define stbi__DNL(x) ((x) == 0xdc)
|
||||
#define stbi__SOI(x) ((x) == 0xd8)
|
||||
#define stbi__EOI(x) ((x) == 0xd9)
|
||||
@ -1875,7 +1886,7 @@ static stbi_uc *load_jpeg_image(stbi__jpeg *z, int *out_x, int *out_y, int *comp
|
||||
|
||||
// allocate line buffer big enough for upsampling off the edges
|
||||
// with upsample factor of 4
|
||||
z->img_comp[k].linebuf = (stbi_uc *) malloc(z->s->img_x + 3);
|
||||
z->img_comp[k].linebuf = (stbi_uc *) stbi__malloc(z->s->img_x + 3);
|
||||
if (!z->img_comp[k].linebuf) { stbi__cleanup_jpeg(z); return stbi__errpuc("outofmem", "Out of memory"); }
|
||||
|
||||
r->hs = z->img_h_max / z->img_comp[k].h;
|
||||
@ -1893,7 +1904,7 @@ static stbi_uc *load_jpeg_image(stbi__jpeg *z, int *out_x, int *out_y, int *comp
|
||||
}
|
||||
|
||||
// can't error after this so, this is safe
|
||||
output = (stbi_uc *) malloc(n * z->s->img_x * z->s->img_y + 1);
|
||||
output = (stbi_uc *) stbi__malloc(n * z->s->img_x * z->s->img_y + 1);
|
||||
if (!output) { stbi__cleanup_jpeg(z); return stbi__errpuc("outofmem", "Out of memory"); }
|
||||
|
||||
// now go ahead and resample
|
||||
@ -2015,7 +2026,7 @@ stbi_inline static int stbi__bit_reverse(int v, int bits)
|
||||
{
|
||||
STBI_ASSERT(bits <= 16);
|
||||
// to bit reverse n bits, reverse 16 and shift
|
||||
// stbi__err.g. 11 bits, bit reverse and shift away 5
|
||||
// e.g. 11 bits, bit reverse and shift away 5
|
||||
return stbi__bitreverse16(v) >> (16-bits);
|
||||
}
|
||||
|
||||
@ -2338,7 +2349,7 @@ static int stbi__do_zlib(stbi__zbuf *a, char *obuf, int olen, int exp, int parse
|
||||
STBIDEF char *stbi_zlib_decode_malloc_guesssize(const char *buffer, int len, int initial_size, int *outlen)
|
||||
{
|
||||
stbi__zbuf a;
|
||||
char *p = (char *) malloc(initial_size);
|
||||
char *p = (char *) stbi__malloc(initial_size);
|
||||
if (p == NULL) return NULL;
|
||||
a.zbuffer = (stbi_uc *) buffer;
|
||||
a.zbuffer_end = (stbi_uc *) buffer + len;
|
||||
@ -2359,7 +2370,7 @@ STBIDEF char *stbi_zlib_decode_malloc(char const *buffer, int len, int *outlen)
|
||||
STBIDEF char *stbi_zlib_decode_malloc_guesssize_headerflag(const char *buffer, int len, int initial_size, int *outlen, int parse_header)
|
||||
{
|
||||
stbi__zbuf a;
|
||||
char *p = (char *) malloc(initial_size);
|
||||
char *p = (char *) stbi__malloc(initial_size);
|
||||
if (p == NULL) return NULL;
|
||||
a.zbuffer = (stbi_uc *) buffer;
|
||||
a.zbuffer_end = (stbi_uc *) buffer + len;
|
||||
@ -2386,7 +2397,7 @@ STBIDEF int stbi_zlib_decode_buffer(char *obuffer, int olen, char const *ibuffer
|
||||
STBIDEF char *stbi_zlib_decode_noheader_malloc(char const *buffer, int len, int *outlen)
|
||||
{
|
||||
stbi__zbuf a;
|
||||
char *p = (char *) malloc(16384);
|
||||
char *p = (char *) stbi__malloc(16384);
|
||||
if (p == NULL) return NULL;
|
||||
a.zbuffer = (stbi_uc *) buffer;
|
||||
a.zbuffer_end = (stbi_uc *) buffer+len;
|
||||
@ -2477,89 +2488,144 @@ static int stbi__paeth(int a, int b, int c)
|
||||
#define STBI__BYTECAST(x) ((stbi_uc) ((x) & 255)) // truncate int to byte without warnings
|
||||
|
||||
// create the png data from post-deflated data
|
||||
static int stbi__create_png_image_raw(stbi__png *a, stbi_uc *raw, stbi__uint32 raw_len, int out_n, stbi__uint32 x, stbi__uint32 y)
|
||||
static int stbi__create_png_image_raw(stbi__png *a, stbi_uc *raw, stbi__uint32 raw_len, int out_n, stbi__uint32 x, stbi__uint32 y, int depth, int color)
|
||||
{
|
||||
stbi__context *s = a->s;
|
||||
stbi__uint32 i,j,stride = x*out_n;
|
||||
stbi__uint32 img_len;
|
||||
int k;
|
||||
int img_n = s->img_n; // copy it into a local for later
|
||||
stbi_uc* line8 = NULL; // point into raw when depth==8 else temporary local buffer
|
||||
|
||||
STBI_ASSERT(out_n == s->img_n || out_n == s->img_n+1);
|
||||
a->out = (stbi_uc *) malloc(x * y * out_n);
|
||||
a->out = (stbi_uc *) stbi__malloc(x * y * out_n);
|
||||
if (!a->out) return stbi__err("outofmem", "Out of memory");
|
||||
|
||||
img_len = ((((img_n * x * depth) + 7) >> 3) + 1) * y;
|
||||
if (s->img_x == x && s->img_y == y) {
|
||||
if (raw_len != (img_n * x + 1) * y) return stbi__err("not enough pixels","Corrupt PNG");
|
||||
if (raw_len != img_len) return stbi__err("not enough pixels","Corrupt PNG");
|
||||
} else { // interlaced:
|
||||
if (raw_len < (img_n * x + 1) * y) return stbi__err("not enough pixels","Corrupt PNG");
|
||||
if (raw_len < img_len) return stbi__err("not enough pixels","Corrupt PNG");
|
||||
}
|
||||
|
||||
if (depth != 8) {
|
||||
line8 = (stbi_uc *) stbi__malloc((x+7) * out_n); // allocate buffer for one scanline
|
||||
if (!line8) return stbi__err("outofmem", "Out of memory");
|
||||
}
|
||||
|
||||
for (j=0; j < y; ++j) {
|
||||
stbi_uc *in;
|
||||
stbi_uc *cur = a->out + stride*j;
|
||||
stbi_uc *prior = cur - stride;
|
||||
int filter = *raw++;
|
||||
if (filter > 4) return stbi__err("invalid filter","Corrupt PNG");
|
||||
if (filter > 4) {
|
||||
if (depth != 8) free(line8);
|
||||
return stbi__err("invalid filter","Corrupt PNG");
|
||||
}
|
||||
|
||||
if (depth == 8) {
|
||||
in = raw;
|
||||
raw += x*img_n;
|
||||
}
|
||||
else {
|
||||
// unpack 1/2/4-bit into a 8-bit buffer. allows us to keep the common 8-bit path optimal at minimal cost for 1/2/4-bit
|
||||
// png guarante byte alignment, if width is not multiple of 8/4/2 we'll decode dummy trailing data that will be skipped in the later loop
|
||||
in = line8;
|
||||
stbi_uc* decode_out = line8;
|
||||
stbi_uc scale = (color == 0) ? 0xFF/((1<<depth)-1) : 1; // scale grayscale values to 0..255 range
|
||||
if (depth == 4) {
|
||||
for (k=x*img_n; k >= 1; k-=2, raw++) {
|
||||
*decode_out++ = scale * ((*raw >> 4) );
|
||||
*decode_out++ = scale * ((*raw ) & 0x0f);
|
||||
}
|
||||
} else if (depth == 2) {
|
||||
for (k=x*img_n; k >= 1; k-=4, raw++) {
|
||||
*decode_out++ = scale * ((*raw >> 6) );
|
||||
*decode_out++ = scale * ((*raw >> 4) & 0x03);
|
||||
*decode_out++ = scale * ((*raw >> 2) & 0x03);
|
||||
*decode_out++ = scale * ((*raw ) & 0x03);
|
||||
}
|
||||
} else if (depth == 1) {
|
||||
for (k=x*img_n; k >= 1; k-=8, raw++) {
|
||||
*decode_out++ = scale * ((*raw >> 7) );
|
||||
*decode_out++ = scale * ((*raw >> 6) & 0x01);
|
||||
*decode_out++ = scale * ((*raw >> 5) & 0x01);
|
||||
*decode_out++ = scale * ((*raw >> 4) & 0x01);
|
||||
*decode_out++ = scale * ((*raw >> 3) & 0x01);
|
||||
*decode_out++ = scale * ((*raw >> 2) & 0x01);
|
||||
*decode_out++ = scale * ((*raw >> 1) & 0x01);
|
||||
*decode_out++ = scale * ((*raw ) & 0x01);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// if first row, use special filter that doesn't sample previous row
|
||||
if (j == 0) filter = first_row_filter[filter];
|
||||
|
||||
// handle first pixel explicitly
|
||||
for (k=0; k < img_n; ++k) {
|
||||
switch (filter) {
|
||||
case STBI__F_none : cur[k] = raw[k]; break;
|
||||
case STBI__F_sub : cur[k] = raw[k]; break;
|
||||
case STBI__F_up : cur[k] = STBI__BYTECAST(raw[k] + prior[k]); break;
|
||||
case STBI__F_avg : cur[k] = STBI__BYTECAST(raw[k] + (prior[k]>>1)); break;
|
||||
case STBI__F_paeth : cur[k] = STBI__BYTECAST(raw[k] + stbi__paeth(0,prior[k],0)); break;
|
||||
case STBI__F_avg_first : cur[k] = raw[k]; break;
|
||||
case STBI__F_paeth_first: cur[k] = raw[k]; break;
|
||||
case STBI__F_none : cur[k] = in[k]; break;
|
||||
case STBI__F_sub : cur[k] = in[k]; break;
|
||||
case STBI__F_up : cur[k] = STBI__BYTECAST(in[k] + prior[k]); break;
|
||||
case STBI__F_avg : cur[k] = STBI__BYTECAST(in[k] + (prior[k]>>1)); break;
|
||||
case STBI__F_paeth : cur[k] = STBI__BYTECAST(in[k] + stbi__paeth(0,prior[k],0)); break;
|
||||
case STBI__F_avg_first : cur[k] = in[k]; break;
|
||||
case STBI__F_paeth_first: cur[k] = in[k]; break;
|
||||
}
|
||||
}
|
||||
if (img_n != out_n) cur[img_n] = 255;
|
||||
raw += img_n;
|
||||
in += img_n;
|
||||
cur += out_n;
|
||||
prior += out_n;
|
||||
// this is a little gross, so that we don't switch per-pixel or per-component
|
||||
if (img_n == out_n) {
|
||||
#define CASE(f) \
|
||||
case f: \
|
||||
for (i=x-1; i >= 1; --i, raw+=img_n,cur+=img_n,prior+=img_n) \
|
||||
for (i=x-1; i >= 1; --i, in+=img_n,cur+=img_n,prior+=img_n) \
|
||||
for (k=0; k < img_n; ++k)
|
||||
switch (filter) {
|
||||
CASE(STBI__F_none) cur[k] = raw[k]; break;
|
||||
CASE(STBI__F_sub) cur[k] = STBI__BYTECAST(raw[k] + cur[k-img_n]); break;
|
||||
CASE(STBI__F_up) cur[k] = STBI__BYTECAST(raw[k] + prior[k]); break;
|
||||
CASE(STBI__F_avg) cur[k] = STBI__BYTECAST(raw[k] + ((prior[k] + cur[k-img_n])>>1)); break;
|
||||
CASE(STBI__F_paeth) cur[k] = STBI__BYTECAST(raw[k] + stbi__paeth(cur[k-img_n],prior[k],prior[k-img_n])); break;
|
||||
CASE(STBI__F_avg_first) cur[k] = STBI__BYTECAST(raw[k] + (cur[k-img_n] >> 1)); break;
|
||||
CASE(STBI__F_paeth_first) cur[k] = STBI__BYTECAST(raw[k] + stbi__paeth(cur[k-img_n],0,0)); break;
|
||||
CASE(STBI__F_none) cur[k] = in[k]; break;
|
||||
CASE(STBI__F_sub) cur[k] = STBI__BYTECAST(in[k] + cur[k-img_n]); break;
|
||||
CASE(STBI__F_up) cur[k] = STBI__BYTECAST(in[k] + prior[k]); break;
|
||||
CASE(STBI__F_avg) cur[k] = STBI__BYTECAST(in[k] + ((prior[k] + cur[k-img_n])>>1)); break;
|
||||
CASE(STBI__F_paeth) cur[k] = STBI__BYTECAST(in[k] + stbi__paeth(cur[k-img_n],prior[k],prior[k-img_n])); break;
|
||||
CASE(STBI__F_avg_first) cur[k] = STBI__BYTECAST(in[k] + (cur[k-img_n] >> 1)); break;
|
||||
CASE(STBI__F_paeth_first) cur[k] = STBI__BYTECAST(in[k] + stbi__paeth(cur[k-img_n],0,0)); break;
|
||||
}
|
||||
#undef CASE
|
||||
} else {
|
||||
STBI_ASSERT(img_n+1 == out_n);
|
||||
#define CASE(f) \
|
||||
case f: \
|
||||
for (i=x-1; i >= 1; --i, cur[img_n]=255,raw+=img_n,cur+=out_n,prior+=out_n) \
|
||||
for (i=x-1; i >= 1; --i, cur[img_n]=255,in+=img_n,cur+=out_n,prior+=out_n) \
|
||||
for (k=0; k < img_n; ++k)
|
||||
switch (filter) {
|
||||
CASE(STBI__F_none) cur[k] = raw[k]; break;
|
||||
CASE(STBI__F_sub) cur[k] = STBI__BYTECAST(raw[k] + cur[k-out_n]); break;
|
||||
CASE(STBI__F_up) cur[k] = STBI__BYTECAST(raw[k] + prior[k]); break;
|
||||
CASE(STBI__F_avg) cur[k] = STBI__BYTECAST(raw[k] + ((prior[k] + cur[k-out_n])>>1)); break;
|
||||
CASE(STBI__F_paeth) cur[k] = STBI__BYTECAST(raw[k] + stbi__paeth(cur[k-out_n],prior[k],prior[k-out_n])); break;
|
||||
CASE(STBI__F_avg_first) cur[k] = STBI__BYTECAST(raw[k] + (cur[k-out_n] >> 1)); break;
|
||||
CASE(STBI__F_paeth_first) cur[k] = STBI__BYTECAST(raw[k] + stbi__paeth(cur[k-out_n],0,0)); break;
|
||||
CASE(STBI__F_none) cur[k] = in[k]; break;
|
||||
CASE(STBI__F_sub) cur[k] = STBI__BYTECAST(in[k] + cur[k-out_n]); break;
|
||||
CASE(STBI__F_up) cur[k] = STBI__BYTECAST(in[k] + prior[k]); break;
|
||||
CASE(STBI__F_avg) cur[k] = STBI__BYTECAST(in[k] + ((prior[k] + cur[k-out_n])>>1)); break;
|
||||
CASE(STBI__F_paeth) cur[k] = STBI__BYTECAST(in[k] + stbi__paeth(cur[k-out_n],prior[k],prior[k-out_n])); break;
|
||||
CASE(STBI__F_avg_first) cur[k] = STBI__BYTECAST(in[k] + (cur[k-out_n] >> 1)); break;
|
||||
CASE(STBI__F_paeth_first) cur[k] = STBI__BYTECAST(in[k] + stbi__paeth(cur[k-out_n],0,0)); break;
|
||||
}
|
||||
#undef CASE
|
||||
}
|
||||
}
|
||||
|
||||
if (depth != 8) free(line8);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int stbi__create_png_image(stbi__png *a, stbi_uc *raw, stbi__uint32 raw_len, int out_n, int interlaced)
|
||||
static int stbi__create_png_image(stbi__png *a, stbi_uc *raw, stbi__uint32 raw_len, int out_n, int depth, int color, int interlaced)
|
||||
{
|
||||
stbi_uc *final;
|
||||
int p;
|
||||
if (!interlaced)
|
||||
return stbi__create_png_image_raw(a, raw, raw_len, out_n, a->s->img_x, a->s->img_y);
|
||||
return stbi__create_png_image_raw(a, raw, raw_len, out_n, a->s->img_x, a->s->img_y, depth, color);
|
||||
|
||||
// de-interlacing
|
||||
final = (stbi_uc *) malloc(a->s->img_x * a->s->img_y * out_n);
|
||||
final = (stbi_uc *) stbi__malloc(a->s->img_x * a->s->img_y * out_n);
|
||||
for (p=0; p < 7; ++p) {
|
||||
int xorig[] = { 0,4,0,2,0,1,0 };
|
||||
int yorig[] = { 0,0,4,0,2,0,1 };
|
||||
@ -2570,7 +2636,8 @@ static int stbi__create_png_image(stbi__png *a, stbi_uc *raw, stbi__uint32 raw_l
|
||||
x = (a->s->img_x - xorig[p] + xspc[p]-1) / xspc[p];
|
||||
y = (a->s->img_y - yorig[p] + yspc[p]-1) / yspc[p];
|
||||
if (x && y) {
|
||||
if (!stbi__create_png_image_raw(a, raw, raw_len, out_n, x, y)) {
|
||||
stbi__uint32 img_len = ((((out_n * x * depth) + 7) >> 3) + 1) * y;
|
||||
if (!stbi__create_png_image_raw(a, raw, raw_len, out_n, x, y, depth, color)) {
|
||||
free(final);
|
||||
return 0;
|
||||
}
|
||||
@ -2579,8 +2646,8 @@ static int stbi__create_png_image(stbi__png *a, stbi_uc *raw, stbi__uint32 raw_l
|
||||
memcpy(final + (j*yspc[p]+yorig[p])*a->s->img_x*out_n + (i*xspc[p]+xorig[p])*out_n,
|
||||
a->out + (j*x+i)*out_n, out_n);
|
||||
free(a->out);
|
||||
raw += (x*out_n+1)*y;
|
||||
raw_len -= (x*out_n+1)*y;
|
||||
raw += img_len;
|
||||
raw_len -= img_len;
|
||||
}
|
||||
}
|
||||
a->out = final;
|
||||
@ -2618,7 +2685,7 @@ static int stbi__expand_png_palette(stbi__png *a, stbi_uc *palette, int len, int
|
||||
stbi__uint32 i, pixel_count = a->s->img_x * a->s->img_y;
|
||||
stbi_uc *p, *temp_out, *orig = a->out;
|
||||
|
||||
p = (stbi_uc *) malloc(pixel_count * pal_img_n);
|
||||
p = (stbi_uc *) stbi__malloc(pixel_count * pal_img_n);
|
||||
if (p == NULL) return stbi__err("outofmem", "Out of memory");
|
||||
|
||||
// between here and free(out) below, exitting would leak
|
||||
@ -2710,7 +2777,7 @@ static int stbi__parse_png_file(stbi__png *z, int scan, int req_comp)
|
||||
stbi_uc palette[1024], pal_img_n=0;
|
||||
stbi_uc has_trans=0, tc[3];
|
||||
stbi__uint32 ioff=0, idata_limit=0, i, pal_len=0;
|
||||
int first=1,k,interlace=0, is_iphone=0;
|
||||
int first=1,k,interlace=0, color=0, depth=0, is_iphone=0;
|
||||
stbi__context *s = z->s;
|
||||
|
||||
z->expanded = NULL;
|
||||
@ -2729,13 +2796,13 @@ static int stbi__parse_png_file(stbi__png *z, int scan, int req_comp)
|
||||
stbi__skip(s, c.length);
|
||||
break;
|
||||
case PNG_TYPE('I','H','D','R'): {
|
||||
int depth,color,comp,filter;
|
||||
int comp,filter;
|
||||
if (!first) return stbi__err("multiple IHDR","Corrupt PNG");
|
||||
first = 0;
|
||||
if (c.length != 13) return stbi__err("bad IHDR len","Corrupt PNG");
|
||||
s->img_x = stbi__get32be(s); if (s->img_x > (1 << 24)) return stbi__err("too large","Very large image (corrupt?)");
|
||||
s->img_y = stbi__get32be(s); if (s->img_y > (1 << 24)) return stbi__err("too large","Very large image (corrupt?)");
|
||||
depth = stbi__get8(s); if (depth != 8) return stbi__err("8bit only","PNG not supported: 8-bit only");
|
||||
depth = stbi__get8(s); if (depth != 1 && depth != 2 && depth != 4 && depth != 8) return stbi__err("1/2/4/8-bit only","PNG not supported: 1/2/4/8-bit only");
|
||||
color = stbi__get8(s); if (color > 6) return stbi__err("bad ctype","Corrupt PNG");
|
||||
if (color == 3) pal_img_n = 3; else if (color & 1) return stbi__err("bad ctype","Corrupt PNG");
|
||||
comp = stbi__get8(s); if (comp) return stbi__err("bad comp method","Corrupt PNG");
|
||||
@ -2819,7 +2886,7 @@ static int stbi__parse_png_file(stbi__png *z, int scan, int req_comp)
|
||||
s->img_out_n = s->img_n+1;
|
||||
else
|
||||
s->img_out_n = s->img_n;
|
||||
if (!stbi__create_png_image(z, z->expanded, raw_len, s->img_out_n, interlace)) return 0;
|
||||
if (!stbi__create_png_image(z, z->expanded, raw_len, s->img_out_n, depth, color, interlace)) return 0;
|
||||
if (has_trans)
|
||||
if (!stbi__compute_transparency(z, tc, s->img_out_n)) return 0;
|
||||
if (is_iphone && stbi__de_iphone_flag && s->img_out_n > 2)
|
||||
@ -2872,7 +2939,7 @@ static unsigned char *stbi__do_png(stbi__png *p, int *x, int *y, int *n, int req
|
||||
}
|
||||
*x = p->s->img_x;
|
||||
*y = p->s->img_y;
|
||||
if (n) *n = p->s->img_n;
|
||||
if (n) *n = p->s->img_out_n;
|
||||
}
|
||||
free(p->out); p->out = NULL;
|
||||
free(p->expanded); p->expanded = NULL;
|
||||
@ -3074,7 +3141,7 @@ static stbi_uc *stbi__bmp_load(stbi__context *s, int *x, int *y, int *comp, int
|
||||
target = req_comp;
|
||||
else
|
||||
target = s->img_n; // if they want monochrome, we'll post-convert
|
||||
out = (stbi_uc *) malloc(target * s->img_x * s->img_y);
|
||||
out = (stbi_uc *) stbi__malloc(target * s->img_x * s->img_y);
|
||||
if (!out) return stbi__errpuc("outofmem", "Out of memory");
|
||||
if (bpp < 16) {
|
||||
int z=0;
|
||||
@ -3303,7 +3370,7 @@ static stbi_uc *stbi__tga_load(stbi__context *s, int *x, int *y, int *comp, int
|
||||
*y = tga_height;
|
||||
if (comp) *comp = tga_comp;
|
||||
|
||||
tga_data = (unsigned char*)malloc( tga_width * tga_height * tga_comp );
|
||||
tga_data = (unsigned char*)stbi__malloc( tga_width * tga_height * tga_comp );
|
||||
if (!tga_data) return stbi__errpuc("outofmem", "Out of memory");
|
||||
|
||||
// skip to the data's starting position (offset usually = 0)
|
||||
@ -3322,7 +3389,7 @@ static stbi_uc *stbi__tga_load(stbi__context *s, int *x, int *y, int *comp, int
|
||||
// any data to skip? (offset usually = 0)
|
||||
stbi__skip(s, tga_palette_start );
|
||||
// load the palette
|
||||
tga_palette = (unsigned char*)malloc( tga_palette_len * tga_palette_bits / 8 );
|
||||
tga_palette = (unsigned char*)stbi__malloc( tga_palette_len * tga_palette_bits / 8 );
|
||||
if (!tga_palette) {
|
||||
free(tga_data);
|
||||
return stbi__errpuc("outofmem", "Out of memory");
|
||||
@ -3513,7 +3580,7 @@ static stbi_uc *stbi__psd_load(stbi__context *s, int *x, int *y, int *comp, int
|
||||
return stbi__errpuc("bad compression", "PSD has an unknown compression format");
|
||||
|
||||
// Create the destination image.
|
||||
out = (stbi_uc *) malloc(4 * w*h);
|
||||
out = (stbi_uc *) stbi__malloc(4 * w*h);
|
||||
if (!out) return stbi__errpuc("outofmem", "Out of memory");
|
||||
pixelCount = w*h;
|
||||
|
||||
@ -3798,7 +3865,7 @@ static stbi_uc *stbi__pic_load(stbi__context *s,int *px,int *py,int *comp,int re
|
||||
stbi__get16be(s); //skip `pad'
|
||||
|
||||
// intermediate buffer is RGBA
|
||||
result = (stbi_uc *) malloc(x*y*4);
|
||||
result = (stbi_uc *) stbi__malloc(x*y*4);
|
||||
memset(result, 0xff, x*y*4);
|
||||
|
||||
if (!stbi__pic_load_core(s,x,y,comp, result)) {
|
||||
@ -4049,14 +4116,14 @@ static stbi_uc *stbi__gif_load_next(stbi__context *s, stbi__gif *g, int *comp, i
|
||||
|
||||
if (g->out == 0) {
|
||||
if (!stbi__gif_header(s, g, comp,0)) return 0; // stbi__g_failure_reason set by stbi__gif_header
|
||||
g->out = (stbi_uc *) malloc(4 * g->w * g->h);
|
||||
g->out = (stbi_uc *) stbi__malloc(4 * g->w * g->h);
|
||||
if (g->out == 0) return stbi__errpuc("outofmem", "Out of memory");
|
||||
stbi__fill_gif_background(g);
|
||||
} else {
|
||||
// animated-gif-only path
|
||||
if (((g->eflags & 0x1C) >> 2) == 3) {
|
||||
old_out = g->out;
|
||||
g->out = (stbi_uc *) malloc(4 * g->w * g->h);
|
||||
g->out = (stbi_uc *) stbi__malloc(4 * g->w * g->h);
|
||||
if (g->out == 0) return stbi__errpuc("outofmem", "Out of memory");
|
||||
memcpy(g->out, old_out, g->w*g->h*4);
|
||||
}
|
||||
@ -4279,7 +4346,7 @@ static float *stbi__hdr_load(stbi__context *s, int *x, int *y, int *comp, int re
|
||||
if (req_comp == 0) req_comp = 3;
|
||||
|
||||
// Read data
|
||||
hdr_data = (float *) malloc(height * width * req_comp * sizeof(float));
|
||||
hdr_data = (float *) stbi__malloc(height * width * req_comp * sizeof(float));
|
||||
|
||||
// Load image data
|
||||
// image data is stored as some number of sca
|
||||
@ -4318,7 +4385,7 @@ static float *stbi__hdr_load(stbi__context *s, int *x, int *y, int *comp, int re
|
||||
len <<= 8;
|
||||
len |= stbi__get8(s);
|
||||
if (len != width) { free(hdr_data); free(scanline); return stbi__errpf("invalid decoded scanline length", "corrupt HDR"); }
|
||||
if (scanline == NULL) scanline = (stbi_uc *) malloc(width * 4);
|
||||
if (scanline == NULL) scanline = (stbi_uc *) stbi__malloc(width * 4);
|
||||
|
||||
for (k = 0; k < 4; ++k) {
|
||||
i = 0;
|
||||
@ -4555,6 +4622,12 @@ STBIDEF int stbi_info_from_callbacks(stbi_io_callbacks const *c, void *user, int
|
||||
|
||||
/*
|
||||
revision history:
|
||||
1.46 (2014-08-26)
|
||||
fix broken tRNS chunk (colorkey-style transparency) in non-paletted PNG
|
||||
1.45 (2014-08-16)
|
||||
fix MSVC-ARM internal compiler error by wrapping malloc
|
||||
1.44 (2014-08-07)
|
||||
various warning fixes from Ronny Chevalier
|
||||
1.43 (2014-07-15)
|
||||
fix MSVC-only compiler problem in code changed in 1.42
|
||||
1.42 (2014-07-09)
|
BIN
extra_fonts/ProggyClean.zip
Normal file
BIN
extra_fonts/ProggySmall.zip
Normal file
100
extra_fonts/README.txt
Normal file
@ -0,0 +1,100 @@
|
||||
|
||||
Extra fonts for ImGui.
|
||||
THOSE FONTS ARE OPTIONAL.
|
||||
|
||||
ImGui embeds a copy of 'proggy_clean' that you can use without any external files.
|
||||
Export your own font with bmfont (www.angelcode.com/products/bmfont).
|
||||
|
||||
bmfont reads fonts (.ttf, .fon, etc.) and output a .fnt file and a texture file, e.g:
|
||||
|
||||
proggy_clean.fon --> [bmfont] ---> proggy_clean_13.fnt
|
||||
proggy_clean_13.png
|
||||
|
||||
If you need a free font that supports chinese/japanese characters, you can use the M+ fonts.
|
||||
TTF and sources are availables at http://mplus-fonts.sourceforge.jp/mplus-outline-fonts.
|
||||
This directory include some of the M+ fonts converted by bmfont.
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
Configure bmfont:
|
||||
|
||||
- Export .fnt as Binary
|
||||
- Output .png, 32-bits (or whatever is suitable for your loader/renderer)
|
||||
- Tip: uncheck "Render from TrueType outline" and "Font Smoothing" for best result with non-anti-aliased type fonts.
|
||||
But you can experiment with other settings if you want anti-aliased fonts.
|
||||
- Tip: use pngout.exe (http://advsys.net/ken/utils.htm) to further reduce the file size of .png files
|
||||
All files in this folder have been optimised with pngout.exe
|
||||
|
||||
-----------------------------------------------------------------------------
|
||||
|
||||
(A) Use font data embedded in ImGui
|
||||
|
||||
// Access embedded font data
|
||||
const void* fnt_data; // pointer to FNT data
|
||||
unsigned fnt_size; // size of FNT data
|
||||
const void* png_data; // pointer to PNG data
|
||||
unsigned int png_size; // size of PNG data
|
||||
ImGui::GetDefaultFontData(&fnt_data, &fnt_size, &png_data, &png_size);
|
||||
|
||||
1. Load the .FNT data from 'fnt_data' (NB: this is done for you by default if you don't do anything)
|
||||
|
||||
ImGuiIO& io = ImGui::GetIO();
|
||||
io.Font = new ImFont();
|
||||
io.Font->LoadFromMemory(fnt_data, fnt_size);
|
||||
|
||||
2. Load the .PNG data from 'png_data' into a texture
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
(B) Use fonts from external files
|
||||
|
||||
You need to set io.Font->TexUvForWhite to UV coordinates pointing to a white pixel in the texture.
|
||||
You can either locate a white pixel manually or use code at runtime to find or write one.
|
||||
The OpenGL example include sample code to find a white pixel given an uncompressed 32-bits texture:
|
||||
|
||||
// Automatically find white pixel from the texture we just loaded
|
||||
// (io.Font->TexUvForWhite needs to contains UV coordinates pointing to a white pixel in order to render solid objects)
|
||||
for (int tex_data_off = 0; tex_data_off < tex_x*tex_y; tex_data_off++)
|
||||
if (((unsigned int*)tex_data)[tex_data_off] == 0xffffffff)
|
||||
{
|
||||
io.Font->TexUvForWhite = ImVec2((float)(tex_data_off % tex_x)/(tex_x), (float)(tex_data_off / tex_x)/(tex_y));
|
||||
break;
|
||||
}
|
||||
|
||||
1. Load the .FNT data, e.g.
|
||||
|
||||
ImGuiIO& io = ImGui::GetIO();
|
||||
|
||||
// proggy_clean_13 [default]
|
||||
io.Font = new ImFont();
|
||||
io.Font->LoadFromFile("proggy_clean_13.fnt");
|
||||
IM_ASSERT(io.Font->IsLoaded());
|
||||
io.Font->TexUvForWhite = ImVec2(0.0f/256.0f,0.0f/128);
|
||||
io.Font->DisplayOffset = ImVec2(0.0f, +1.0f);
|
||||
|
||||
// proggy_small_12
|
||||
io.Font = new ImFont();
|
||||
io.Font->LoadFromFile("proggy_small_12.fnt");
|
||||
IM_ASSERT(io.Font->IsLoaded());
|
||||
io.Font->TexUvForWhite = ImVec2(84.0f/256.0f,20.0f/64);
|
||||
io.Font->DisplayOffset = ImVec2(0.0f, +2.0f);
|
||||
|
||||
// proggy_small_14
|
||||
io.Font = new ImFont();
|
||||
io.Font->LoadFromFile("proggy_small_14.fnt");
|
||||
IM_ASSERT(io.Font->IsLoaded());
|
||||
io.Font->TexUvForWhite = ImVec2(84.0f/256.0f,20.0f/64);
|
||||
io.Font->DisplayOffset = ImVec2(0.0f, +3.0f);
|
||||
|
||||
// courier_new_16
|
||||
io.Font->LoadFromFile("courier_new_16.fnt");
|
||||
io.Font->TexUvForWhite = ImVec2(1.0f/256.0f,4.0f/128);
|
||||
|
||||
// courier_new_18
|
||||
io.Font->LoadFromFile("courier_new_18.fnt");
|
||||
io.Font->TexUvForWhite = ImVec2(4.0f/256.0f,5.0f/256);
|
||||
|
||||
|
||||
2. Load the matching .PNG data into a texture
|
||||
|
||||
//-----------------------------------------------------------------------------
|
BIN
extra_fonts/courier_new_16.fnt
Normal file
After Width: | Height: | Size: 3.8 KiB |
BIN
extra_fonts/courier_new_16.png
Normal file
After Width: | Height: | Size: 1.4 KiB |
BIN
extra_fonts/courier_new_18.fnt
Normal file
After Width: | Height: | Size: 3.8 KiB |
BIN
extra_fonts/courier_new_18.png
Normal file
After Width: | Height: | Size: 2.6 KiB |
BIN
extra_fonts/mplus-2m-medium_18.fnt
Normal file
After Width: | Height: | Size: 117 KiB |
BIN
extra_fonts/mplus-2m-medium_18.png
Normal file
After Width: | Height: | Size: 284 KiB |
BIN
extra_fonts/proggy_clean_13.fnt
Normal file
After Width: | Height: | Size: 4.5 KiB |
BIN
extra_fonts/proggy_clean_13.png
Normal file
After Width: | Height: | Size: 1.5 KiB |
BIN
extra_fonts/proggy_small_12.fnt
Normal file
After Width: | Height: | Size: 4.5 KiB |
BIN
extra_fonts/proggy_small_12.png
Normal file
After Width: | Height: | Size: 949 B |
BIN
extra_fonts/proggy_small_14.fnt
Normal file
After Width: | Height: | Size: 4.5 KiB |
BIN
extra_fonts/proggy_small_14.png
Normal file
After Width: | Height: | Size: 949 B |
11
imconfig.h
@ -1,5 +1,7 @@
|
||||
//-----------------------------------------------------------------------------
|
||||
// USER IMPLEMENTATION
|
||||
// This file contains compile-time options for ImGui.
|
||||
// Other options (memory allocation overrides, callbacks, etc.) can be set at runtime via the ImGuiIO structure - ImGui::GetIO().
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#pragma once
|
||||
@ -12,9 +14,12 @@
|
||||
//---- Define assertion handler. Defaults to calling assert().
|
||||
//#define IM_ASSERT(_EXPR) MyAssert(_EXPR)
|
||||
|
||||
//---- Don't implement default clipboard handlers for Windows (so as not to link with OpenClipboard(), etc.)
|
||||
//---- Don't implement default clipboard handlers for Windows (so as not to link with OpenClipboard() and others Win32 functions)
|
||||
//#define IMGUI_DISABLE_WIN32_DEFAULT_CLIPBOARD_FUNCS
|
||||
|
||||
//---- Include imgui_user.inl at the end of imgui.cpp so you can include code that extends ImGui using its private data/functions.
|
||||
//#define IMGUI_INCLUDE_IMGUI_USER_INL
|
||||
|
||||
//---- Define implicit cast operators to convert back<>forth from your math types and ImVec2/ImVec4.
|
||||
/*
|
||||
#define IM_VEC2_CLASS_EXTRA \
|
||||
@ -27,11 +32,13 @@
|
||||
*/
|
||||
|
||||
//---- Freely implement extra functions within the ImGui:: namespace.
|
||||
//---- Declare helpers or widgets implemented in imgui_user.inl or elsewhere, so end-user doesn't need to include multiple files.
|
||||
//---- e.g. you can create variants of the ImGui::Value() helper for your low-level math types.
|
||||
/*
|
||||
namespace ImGui
|
||||
{
|
||||
void Value(const char* prefix, const MyVec2& v, const char* float_format = NULL);
|
||||
void Value(const char* prefix, const MyVec4& v, const char* float_format = NULL);
|
||||
};
|
||||
}
|
||||
*/
|
||||
|
||||
|
615
imgui.h
@ -1,4 +1,4 @@
|
||||
// ImGui library
|
||||
// ImGui library v1.17 wip
|
||||
// See .cpp file for commentary.
|
||||
// See ImGui::ShowTestWindow() for sample code.
|
||||
// Read 'Programmer guide' in .cpp for notes on how to setup ImGui in your codebase.
|
||||
@ -7,7 +7,7 @@
|
||||
#pragma once
|
||||
|
||||
struct ImDrawList;
|
||||
struct ImBitmapFont;
|
||||
struct ImFont;
|
||||
struct ImGuiAabb;
|
||||
struct ImGuiIO;
|
||||
struct ImGuiStorage;
|
||||
@ -17,21 +17,28 @@ struct ImGuiWindow;
|
||||
#include "imconfig.h"
|
||||
#include <float.h> // FLT_MAX
|
||||
#include <stdarg.h> // va_list
|
||||
#include <stdlib.h> // NULL
|
||||
#include <stddef.h> // ptrdiff_t
|
||||
#include <stdlib.h> // NULL, malloc
|
||||
|
||||
#ifndef IM_ASSERT
|
||||
#include <assert.h>
|
||||
#define IM_ASSERT(_EXPR) assert(_EXPR)
|
||||
#endif
|
||||
|
||||
#ifndef IMGUI_API
|
||||
#define IMGUI_API
|
||||
#endif
|
||||
|
||||
typedef unsigned int ImU32;
|
||||
typedef ImU32 ImGuiID;
|
||||
typedef unsigned short ImWchar; // hold a character for display
|
||||
typedef ImU32 ImGuiID; // hold widget unique ID
|
||||
typedef int ImGuiCol; // enum ImGuiCol_
|
||||
typedef int ImGuiStyleVar; // enum ImGuiStyleVar_
|
||||
typedef int ImGuiKey; // enum ImGuiKey_
|
||||
typedef int ImGuiColorEditMode; // enum ImGuiColorEditMode_
|
||||
typedef int ImGuiWindowFlags; // enum ImGuiWindowFlags_
|
||||
typedef int ImGuiInputTextFlags; // enum ImGuiInputTextFlags_
|
||||
typedef ImBitmapFont* ImFont;
|
||||
struct ImGuiTextEditCallbackData;
|
||||
|
||||
struct ImVec2
|
||||
{
|
||||
@ -55,8 +62,17 @@ struct ImVec4
|
||||
#endif
|
||||
};
|
||||
|
||||
namespace ImGui
|
||||
{
|
||||
// Proxy functions to access the MemAllocFn/MemFreeFn/MemReallocFn pointers in ImGui::GetIO(). The only reason they exist here is to allow ImVector<> to compile inline.
|
||||
IMGUI_API void* MemAlloc(size_t sz);
|
||||
IMGUI_API void MemFree(void* ptr);
|
||||
IMGUI_API void* MemRealloc(void* ptr, size_t sz);
|
||||
}
|
||||
|
||||
// std::vector<> like class to avoid dragging dependencies (also: windows implementation of STL with debug enabled is absurdly slow, so let's bypass it so our code runs fast in debug).
|
||||
// this implementation does NOT call c++ constructors! we don't need them! also only provide the minimum functionalities we need.
|
||||
// Use '#define ImVector std::vector' if you want to use the STL type or your own type.
|
||||
// Our implementation does NOT call c++ constructors! because the data types we use don't need them (but that could be added as well). Only provide the minimum functionalities we need.
|
||||
#ifndef ImVector
|
||||
template<typename T>
|
||||
class ImVector
|
||||
@ -72,7 +88,7 @@ public:
|
||||
typedef const value_type* const_iterator;
|
||||
|
||||
ImVector() { Size = Capacity = 0; Data = NULL; }
|
||||
~ImVector() { if (Data) free(Data); }
|
||||
~ImVector() { if (Data) ImGui::MemFree(Data); }
|
||||
|
||||
inline bool empty() const { return Size == 0; }
|
||||
inline size_t size() const { return Size; }
|
||||
@ -83,7 +99,7 @@ public:
|
||||
inline value_type& operator[](size_t i) { IM_ASSERT(i < Size); return Data[i]; }
|
||||
inline const value_type& operator[](size_t i) const { IM_ASSERT(i < Size); return Data[i]; }
|
||||
|
||||
inline void clear() { if (Data) { Size = Capacity = 0; free(Data); Data = NULL; } }
|
||||
inline void clear() { if (Data) { Size = Capacity = 0; ImGui::MemFree(Data); Data = NULL; } }
|
||||
inline iterator begin() { return Data; }
|
||||
inline const_iterator begin() const { return Data; }
|
||||
inline iterator end() { return Data + Size; }
|
||||
@ -94,19 +110,19 @@ public:
|
||||
inline const value_type& back() const { IM_ASSERT(Size > 0); return at(Size-1); }
|
||||
inline void swap(ImVector<T>& rhs) { const size_t rhs_size = rhs.Size; rhs.Size = Size; Size = rhs_size; const size_t rhs_cap = rhs.Capacity; rhs.Capacity = Capacity; Capacity = rhs_cap; value_type* rhs_data = rhs.Data; rhs.Data = Data; Data = rhs_data; }
|
||||
|
||||
inline void reserve(size_t new_capacity) { Data = (value_type*)realloc(Data, new_capacity * sizeof(value_type)); Capacity = new_capacity; }
|
||||
inline void reserve(size_t new_capacity) { Data = (value_type*)ImGui::MemRealloc(Data, new_capacity * sizeof(value_type)); Capacity = new_capacity; }
|
||||
inline void resize(size_t new_size) { if (new_size > Capacity) reserve(new_size); Size = new_size; }
|
||||
|
||||
inline void push_back(const value_type& v) { if (Size == Capacity) reserve(Capacity ? Capacity * 2 : 4); Data[Size++] = v; }
|
||||
inline void pop_back() { IM_ASSERT(Size > 0); Size--; }
|
||||
|
||||
inline iterator erase(const_iterator it) { IM_ASSERT(it >= begin() && it < end()); const int off = it - begin(); memmove(Data + off, Data + off + 1, (Size - off - 1) * sizeof(value_type)); Size--; return Data + off; }
|
||||
inline void insert(const_iterator it, const value_type& v) { IM_ASSERT(it >= begin() && it <= end()); const int off = it - begin(); if (Size == Capacity) reserve(Capacity ? Capacity * 2 : 4); if (off < (int)Size) memmove(Data + off + 1, Data + off, (Size - off) * sizeof(value_type)); Data[off] = v; Size++; }
|
||||
inline iterator erase(const_iterator it) { IM_ASSERT(it >= begin() && it < end()); const ptrdiff_t off = it - begin(); memmove(Data + off, Data + off + 1, (Size - (size_t)off - 1) * sizeof(value_type)); Size--; return Data + off; }
|
||||
inline void insert(const_iterator it, const value_type& v) { IM_ASSERT(it >= begin() && it <= end()); const ptrdiff_t off = it - begin(); if (Size == Capacity) reserve(Capacity ? Capacity * 2 : 4); if (off < (int)Size) memmove(Data + off + 1, Data + off, (Size - (size_t)off) * sizeof(value_type)); Data[off] = v; Size++; }
|
||||
};
|
||||
#endif // #ifndef ImVector
|
||||
|
||||
// Helpers at bottom of the file:
|
||||
// - if (IMGUI_ONCE_UPON_A_FRAME) // Execute a block of code once per frame only
|
||||
// - IMGUI_ONCE_UPON_A_FRAME // Execute a block of code once per frame only (convenient for creating UI within deep-nested code that runs multiple times)
|
||||
// - struct ImGuiTextFilter // Parse and apply text filters. In format "aaaaa[,bbbb][,ccccc]"
|
||||
// - struct ImGuiTextBuffer // Text buffer for logging/accumulating text
|
||||
// - struct ImGuiStorage // Custom key value storage (if you need to alter open/close states manually)
|
||||
@ -118,143 +134,170 @@ public:
|
||||
namespace ImGui
|
||||
{
|
||||
// Main
|
||||
ImGuiIO& GetIO();
|
||||
ImGuiStyle& GetStyle();
|
||||
void NewFrame();
|
||||
void Render();
|
||||
void Shutdown();
|
||||
void ShowUserGuide();
|
||||
void ShowStyleEditor(ImGuiStyle* ref = NULL);
|
||||
void ShowTestWindow(bool* open = NULL);
|
||||
IMGUI_API ImGuiIO& GetIO();
|
||||
IMGUI_API ImGuiStyle& GetStyle();
|
||||
IMGUI_API void NewFrame();
|
||||
IMGUI_API void Render();
|
||||
IMGUI_API void Shutdown();
|
||||
IMGUI_API void ShowUserGuide();
|
||||
IMGUI_API void ShowStyleEditor(ImGuiStyle* ref = NULL);
|
||||
IMGUI_API void ShowTestWindow(bool* open = NULL);
|
||||
|
||||
// Window
|
||||
bool Begin(const char* name = "Debug", bool* open = NULL, ImVec2 size = ImVec2(0,0), float fill_alpha = -1.0f, ImGuiWindowFlags flags = 0);
|
||||
void End();
|
||||
void BeginChild(const char* str_id, ImVec2 size = ImVec2(0,0), bool border = false, ImGuiWindowFlags extra_flags = 0);
|
||||
void EndChild();
|
||||
bool GetWindowIsFocused();
|
||||
float GetWindowWidth();
|
||||
ImVec2 GetWindowPos(); // you should rarely need/care about the window position, but it can be useful if you want to use your own drawing
|
||||
void SetWindowPos(const ImVec2& pos); // set current window pos
|
||||
ImVec2 GetWindowSize();
|
||||
ImVec2 GetWindowContentRegionMin();
|
||||
ImVec2 GetWindowContentRegionMax();
|
||||
ImDrawList* GetWindowDrawList();
|
||||
void SetFontScale(float scale);
|
||||
void SetScrollPosHere();
|
||||
void SetTreeStateStorage(ImGuiStorage* tree);
|
||||
ImGuiStorage* GetTreeStateStorage();
|
||||
void PushItemWidth(float item_width);
|
||||
void PopItemWidth();
|
||||
float GetItemWidth();
|
||||
void PushAllowKeyboardFocus(bool v);
|
||||
void PopAllowKeyboardFocus();
|
||||
void PushStyleColor(ImGuiCol idx, const ImVec4& col);
|
||||
void PopStyleColor();
|
||||
IMGUI_API bool Begin(const char* name = "Debug", bool* open = NULL, ImVec2 size = ImVec2(0,0), float fill_alpha = -1.0f, ImGuiWindowFlags flags = 0); // return false when window is collapsed, so you can early out in your code.
|
||||
IMGUI_API void End();
|
||||
IMGUI_API void BeginChild(const char* str_id, ImVec2 size = ImVec2(0,0), bool border = false, ImGuiWindowFlags extra_flags = 0); // size==0.0f: use remaining window size, size<0.0f: use remaining window size minus abs(size). on each axis.
|
||||
IMGUI_API void EndChild();
|
||||
IMGUI_API bool GetWindowIsFocused();
|
||||
IMGUI_API ImVec2 GetWindowSize();
|
||||
IMGUI_API float GetWindowWidth();
|
||||
IMGUI_API void SetWindowSize(const ImVec2& size); // set to ImVec2(0,0) to force an auto-fit
|
||||
IMGUI_API ImVec2 GetWindowPos(); // you should rarely need/care about the window position, but it can be useful if you want to use your own drawing.
|
||||
IMGUI_API void SetWindowPos(const ImVec2& pos); // set current window pos.
|
||||
IMGUI_API ImVec2 GetContentRegionMax(); // window or current column boundaries
|
||||
IMGUI_API ImVec2 GetWindowContentRegionMin(); // window boundaries
|
||||
IMGUI_API ImVec2 GetWindowContentRegionMax();
|
||||
IMGUI_API ImDrawList* GetWindowDrawList(); // get rendering command-list if you want to append your own draw primitives.
|
||||
IMGUI_API ImFont* GetWindowFont();
|
||||
IMGUI_API float GetWindowFontSize();
|
||||
IMGUI_API void SetWindowFontScale(float scale); // per-window font scale. Adjust IO.FontGlobalScale if you want to scale all windows.
|
||||
IMGUI_API void SetScrollPosHere(); // adjust scrolling position to center into the current cursor position.
|
||||
IMGUI_API void SetKeyboardFocusHere(int offset = 0); // focus keyboard on the next widget. Use 'offset' to access sub components of a multiple component widget.
|
||||
IMGUI_API void SetTreeStateStorage(ImGuiStorage* tree); // replace tree state storage with our own (if you want to manipulate it yourself, typically clear subsection of it).
|
||||
IMGUI_API ImGuiStorage* GetTreeStateStorage();
|
||||
|
||||
IMGUI_API void PushItemWidth(float item_width); // width of items for the common item+label case. default to ~2/3 of windows width.
|
||||
IMGUI_API void PopItemWidth();
|
||||
IMGUI_API float GetItemWidth();
|
||||
IMGUI_API void PushAllowKeyboardFocus(bool v); // allow focusing using TAB/Shift-TAB, enabled by default but you can disable it for certain widgets.
|
||||
IMGUI_API void PopAllowKeyboardFocus();
|
||||
IMGUI_API void PushStyleColor(ImGuiCol idx, const ImVec4& col);
|
||||
IMGUI_API void PopStyleColor(int count = 1);
|
||||
IMGUI_API void PushStyleVar(ImGuiStyleVar idx, float val);
|
||||
IMGUI_API void PushStyleVar(ImGuiStyleVar idx, const ImVec2& val);
|
||||
IMGUI_API void PopStyleVar(int count = 1);
|
||||
IMGUI_API void PushTextWrapPos(float wrap_pos_x = 0.0f); // word-wrapping for Text*() commands. < 0.0f: no wrapping; 0.0f: wrap to end of window (or column); > 0.0f: wrap at 'wrap_pos_x' position in window local space.
|
||||
IMGUI_API void PopTextWrapPos();
|
||||
|
||||
// Tooltip
|
||||
void SetTooltip(const char* fmt, ...); // set tooltip under mouse-cursor, typically use with ImGui::IsHovered(). last call wins.
|
||||
void BeginTooltip(); // use to create full-featured tooltip windows that aren't just text.
|
||||
void EndTooltip();
|
||||
IMGUI_API void SetTooltip(const char* fmt, ...); // set tooltip under mouse-cursor, typically use with ImGui::IsHovered(). last call wins.
|
||||
IMGUI_API void SetTooltipV(const char* fmt, va_list args);
|
||||
IMGUI_API void BeginTooltip(); // use to create full-featured tooltip windows that aren't just text.
|
||||
IMGUI_API void EndTooltip();
|
||||
|
||||
// Layout
|
||||
void Separator(); // horizontal line
|
||||
void SameLine(int column_x = 0, int spacing_w = -1); // call between widgets to layout them horizontally
|
||||
void Spacing();
|
||||
void Columns(int count = 1, const char* id = NULL, bool border=true); // setup number of columns
|
||||
void NextColumn(); // next column
|
||||
float GetColumnOffset(int column_index = -1);
|
||||
void SetColumnOffset(int column_index, float offset);
|
||||
float GetColumnWidth(int column_index = -1);
|
||||
ImVec2 GetCursorPos(); // cursor position relative to window position
|
||||
void SetCursorPos(const ImVec2& pos); // "
|
||||
ImVec2 GetCursorScreenPos(); // cursor position in screen space
|
||||
void AlignFirstTextHeightToWidgets(); // call once if the first item on the line is a Text() item and you want to vertically lower it to match higher widgets.
|
||||
float GetTextLineSpacing();
|
||||
float GetTextLineHeight();
|
||||
IMGUI_API void Separator(); // horizontal line
|
||||
IMGUI_API void SameLine(int column_x = 0, int spacing_w = -1); // call between widgets to layout them horizontally
|
||||
IMGUI_API void Spacing();
|
||||
IMGUI_API void Columns(int count = 1, const char* id = NULL, bool border=true); // setup number of columns
|
||||
IMGUI_API void NextColumn(); // next column
|
||||
IMGUI_API float GetColumnOffset(int column_index = -1);
|
||||
IMGUI_API void SetColumnOffset(int column_index, float offset);
|
||||
IMGUI_API float GetColumnWidth(int column_index = -1);
|
||||
IMGUI_API ImVec2 GetCursorPos(); // cursor position is relative to window position
|
||||
IMGUI_API void SetCursorPos(const ImVec2& pos); // "
|
||||
IMGUI_API void SetCursorPosX(float x); // "
|
||||
IMGUI_API void SetCursorPosY(float y); // "
|
||||
IMGUI_API ImVec2 GetCursorScreenPos(); // cursor position in screen space
|
||||
IMGUI_API void AlignFirstTextHeightToWidgets(); // call once if the first item on the line is a Text() item and you want to vertically lower it to match subsequent (bigger) widgets.
|
||||
IMGUI_API float GetTextLineSpacing();
|
||||
IMGUI_API float GetTextLineHeight();
|
||||
|
||||
// ID scopes
|
||||
void PushID(const char* str_id);
|
||||
void PushID(const void* ptr_id);
|
||||
void PushID(const int int_id);
|
||||
void PopID();
|
||||
IMGUI_API void PushID(const char* str_id);
|
||||
IMGUI_API void PushID(const void* ptr_id);
|
||||
IMGUI_API void PushID(const int int_id);
|
||||
IMGUI_API void PopID();
|
||||
|
||||
// Widgets
|
||||
void Text(const char* fmt, ...);
|
||||
void TextV(const char* fmt, va_list args);
|
||||
void TextColored(const ImVec4& col, const char* fmt, ...); // shortcut to doing PushStyleColor(ImGuiCol_Text, col); Text(fmt, ...); PopStyleColor();
|
||||
void TextUnformatted(const char* text, const char* text_end = NULL); // doesn't require null terminated string if 'text_end' is specified. no copy done to any bounded stack buffer, better for long chunks of text.
|
||||
void LabelText(const char* label, const char* fmt, ...);
|
||||
void BulletText(const char* fmt, ...);
|
||||
bool Button(const char* label, ImVec2 size = ImVec2(0,0), bool repeat_when_held = false);
|
||||
bool SmallButton(const char* label);
|
||||
bool CollapsingHeader(const char* label, const char* str_id = NULL, const bool display_frame = true, const bool default_open = false);
|
||||
bool SliderFloat(const char* label, float* v, float v_min, float v_max, const char* display_format = "%.3f", float power = 1.0f);
|
||||
bool SliderFloat2(const char* label, float v[2], float v_min, float v_max, const char* display_format = "%.3f", float power = 1.0f);
|
||||
bool SliderFloat3(const char* label, float v[3], float v_min, float v_max, const char* display_format = "%.3f", float power = 1.0f);
|
||||
bool SliderFloat4(const char* label, float v[3], float v_min, float v_max, const char* display_format = "%.3f", float power = 1.0f);
|
||||
bool SliderAngle(const char* label, float* v, float v_degrees_min = -360.0f, float v_degrees_max = +360.0f); // *v in radians
|
||||
bool SliderInt(const char* label, int* v, int v_min, int v_max, const char* display_format = "%.0f");
|
||||
void PlotLines(const char* label, const float* values, int values_count, int values_offset = 0, const char* overlay_text = NULL, float scale_min = FLT_MAX, float scale_max = FLT_MAX, ImVec2 graph_size = ImVec2(0,0), size_t stride = sizeof(float));
|
||||
void PlotHistogram(const char* label, const float* values, int values_count, int values_offset = 0, const char* overlay_text = NULL, float scale_min = FLT_MAX, float scale_max = FLT_MAX, ImVec2 graph_size = ImVec2(0,0), size_t stride = sizeof(float));
|
||||
void Checkbox(const char* label, bool* v);
|
||||
void CheckboxFlags(const char* label, unsigned int* flags, unsigned int flags_value);
|
||||
bool RadioButton(const char* label, bool active);
|
||||
bool RadioButton(const char* label, int* v, int v_button);
|
||||
bool InputFloat(const char* label, float* v, float step = 0.0f, float step_fast = 0.0f, int decimal_precision = -1);
|
||||
bool InputFloat2(const char* label, float v[2], int decimal_precision = -1);
|
||||
bool InputFloat3(const char* label, float v[3], int decimal_precision = -1);
|
||||
bool InputFloat4(const char* label, float v[4], int decimal_precision = -1);
|
||||
bool InputInt(const char* label, int* v, int step = 1, int step_fast = 100);
|
||||
bool InputText(const char* label, char* buf, size_t buf_size, ImGuiInputTextFlags flags = 0);
|
||||
bool Combo(const char* label, int* current_item, const char** items, int items_count, int popup_height_items = 7);
|
||||
bool Combo(const char* label, int* current_item, const char* items_separated_by_zeros, int popup_height_items = 7); // Separate items with \0, end item-list with \0\0
|
||||
bool Combo(const char* label, int* current_item, bool (*items_getter)(void* data, int idx, const char** out_text), void* data, int items_count, int popup_height_items = 7);
|
||||
bool ColorButton(const ImVec4& col, bool small_height = false, bool outline_border = true);
|
||||
bool ColorEdit3(const char* label, float col[3]);
|
||||
bool ColorEdit4(const char* label, float col[4], bool show_alpha = true);
|
||||
void ColorEditMode(ImGuiColorEditMode mode);
|
||||
bool TreeNode(const char* str_label_id); // if returning 'true' the user is responsible for calling TreePop
|
||||
bool TreeNode(const char* str_id, const char* fmt, ...); // "
|
||||
bool TreeNode(const void* ptr_id, const char* fmt, ...); // "
|
||||
void TreePush(const char* str_id = NULL); // already called by TreeNode(), but you can call Push/Pop yourself for layout purpose
|
||||
void TreePush(const void* ptr_id = NULL); // "
|
||||
void TreePop();
|
||||
void OpenNextNode(bool open); // force open/close the next TreeNode or CollapsingHeader
|
||||
IMGUI_API void Text(const char* fmt, ...);
|
||||
IMGUI_API void TextV(const char* fmt, va_list args);
|
||||
IMGUI_API void TextColored(const ImVec4& col, const char* fmt, ...); // shortcut for PushStyleColor(ImGuiCol_Text, col); Text(fmt, ...); PopStyleColor();
|
||||
IMGUI_API void TextColoredV(const ImVec4& col, const char* fmt, va_list args);
|
||||
IMGUI_API void TextWrapped(const char* fmt, ...); // shortcut for PushTextWrapPos(0.0f); Text(fmt, ...); PopTextWrapPos();
|
||||
IMGUI_API void TextWrappedV(const char* fmt, va_list args);
|
||||
IMGUI_API void TextUnformatted(const char* text, const char* text_end = NULL); // doesn't require null terminated string if 'text_end' is specified. no copy done to any bounded stack buffer, recommended for long chunks of text.
|
||||
IMGUI_API void LabelText(const char* label, const char* fmt, ...); // display text+label aligned the same way as value+label widgets
|
||||
IMGUI_API void LabelTextV(const char* label, const char* fmt, va_list args);
|
||||
IMGUI_API void BulletText(const char* fmt, ...);
|
||||
IMGUI_API void BulletTextV(const char* fmt, va_list args);
|
||||
IMGUI_API bool Button(const char* label, ImVec2 size = ImVec2(0,0), bool repeat_when_held = false);
|
||||
IMGUI_API bool SmallButton(const char* label);
|
||||
IMGUI_API bool CollapsingHeader(const char* label, const char* str_id = NULL, const bool display_frame = true, const bool default_open = false);
|
||||
IMGUI_API bool SliderFloat(const char* label, float* v, float v_min, float v_max, const char* display_format = "%.3f", float power = 1.0f); // adjust display_format to decorate the value with a prefix or a suffix. Use power!=1.0 for logarithmic sliders.
|
||||
IMGUI_API bool SliderFloat2(const char* label, float v[2], float v_min, float v_max, const char* display_format = "%.3f", float power = 1.0f);
|
||||
IMGUI_API bool SliderFloat3(const char* label, float v[3], float v_min, float v_max, const char* display_format = "%.3f", float power = 1.0f);
|
||||
IMGUI_API bool SliderFloat4(const char* label, float v[4], float v_min, float v_max, const char* display_format = "%.3f", float power = 1.0f);
|
||||
IMGUI_API bool SliderAngle(const char* label, float* v, float v_degrees_min = -360.0f, float v_degrees_max = +360.0f); // *v in radians
|
||||
IMGUI_API bool SliderInt(const char* label, int* v, int v_min, int v_max, const char* display_format = "%.0f");
|
||||
IMGUI_API void PlotLines(const char* label, const float* values, int values_count, int values_offset = 0, const char* overlay_text = NULL, float scale_min = FLT_MAX, float scale_max = FLT_MAX, ImVec2 graph_size = ImVec2(0,0), size_t stride = sizeof(float));
|
||||
IMGUI_API void PlotLines(const char* label, float (*values_getter)(void* data, int idx), void* data, int values_count, int values_offset = 0, const char* overlay_text = NULL, float scale_min = FLT_MAX, float scale_max = FLT_MAX, ImVec2 graph_size = ImVec2(0,0));
|
||||
IMGUI_API void PlotHistogram(const char* label, const float* values, int values_count, int values_offset = 0, const char* overlay_text = NULL, float scale_min = FLT_MAX, float scale_max = FLT_MAX, ImVec2 graph_size = ImVec2(0,0), size_t stride = sizeof(float));
|
||||
IMGUI_API void PlotHistogram(const char* label, float (*values_getter)(void* data, int idx), void* data, int values_count, int values_offset = 0, const char* overlay_text = NULL, float scale_min = FLT_MAX, float scale_max = FLT_MAX, ImVec2 graph_size = ImVec2(0,0));
|
||||
IMGUI_API bool Checkbox(const char* label, bool* v);
|
||||
IMGUI_API bool CheckboxFlags(const char* label, unsigned int* flags, unsigned int flags_value);
|
||||
IMGUI_API bool RadioButton(const char* label, bool active);
|
||||
IMGUI_API bool RadioButton(const char* label, int* v, int v_button);
|
||||
IMGUI_API bool InputText(const char* label, char* buf, size_t buf_size, ImGuiInputTextFlags flags = 0, void (*callback)(ImGuiTextEditCallbackData*) = NULL, void* user_data = NULL);
|
||||
IMGUI_API bool InputFloat(const char* label, float* v, float step = 0.0f, float step_fast = 0.0f, int decimal_precision = -1, ImGuiInputTextFlags extra_flags = 0);
|
||||
IMGUI_API bool InputFloat2(const char* label, float v[2], int decimal_precision = -1);
|
||||
IMGUI_API bool InputFloat3(const char* label, float v[3], int decimal_precision = -1);
|
||||
IMGUI_API bool InputFloat4(const char* label, float v[4], int decimal_precision = -1);
|
||||
IMGUI_API bool InputInt(const char* label, int* v, int step = 1, int step_fast = 100, ImGuiInputTextFlags extra_flags = 0);
|
||||
IMGUI_API bool Combo(const char* label, int* current_item, const char** items, int items_count, int popup_height_items = 7);
|
||||
IMGUI_API bool Combo(const char* label, int* current_item, const char* items_separated_by_zeros, int popup_height_items = 7); // separate items with \0, end item-list with \0\0
|
||||
IMGUI_API bool Combo(const char* label, int* current_item, bool (*items_getter)(void* data, int idx, const char** out_text), void* data, int items_count, int popup_height_items = 7);
|
||||
IMGUI_API bool ColorButton(const ImVec4& col, bool small_height = false, bool outline_border = true);
|
||||
IMGUI_API bool ColorEdit3(const char* label, float col[3]);
|
||||
IMGUI_API bool ColorEdit4(const char* label, float col[4], bool show_alpha = true);
|
||||
IMGUI_API void ColorEditMode(ImGuiColorEditMode mode);
|
||||
IMGUI_API bool TreeNode(const char* str_label_id); // if returning 'true' the node is open and the user is responsible for calling TreePop
|
||||
IMGUI_API bool TreeNode(const char* str_id, const char* fmt, ...); // "
|
||||
IMGUI_API bool TreeNode(const void* ptr_id, const char* fmt, ...); // "
|
||||
IMGUI_API bool TreeNodeV(const char* str_id, const char* fmt, va_list args); // "
|
||||
IMGUI_API bool TreeNodeV(const void* ptr_id, const char* fmt, va_list args); // "
|
||||
IMGUI_API void TreePush(const char* str_id = NULL); // already called by TreeNode(), but you can call Push/Pop yourself for layouting purpose
|
||||
IMGUI_API void TreePush(const void* ptr_id = NULL); // "
|
||||
IMGUI_API void TreePop();
|
||||
IMGUI_API void OpenNextNode(bool open); // force open/close the next TreeNode or CollapsingHeader
|
||||
|
||||
// Value helper output "name: value"
|
||||
// Freely declare your own in the ImGui namespace.
|
||||
void Value(const char* prefix, bool b);
|
||||
void Value(const char* prefix, int v);
|
||||
void Value(const char* prefix, unsigned int v);
|
||||
void Value(const char* prefix, float v, const char* float_format = NULL);
|
||||
void Color(const char* prefix, const ImVec4& v);
|
||||
void Color(const char* prefix, unsigned int v);
|
||||
IMGUI_API void Value(const char* prefix, bool b);
|
||||
IMGUI_API void Value(const char* prefix, int v);
|
||||
IMGUI_API void Value(const char* prefix, unsigned int v);
|
||||
IMGUI_API void Value(const char* prefix, float v, const char* float_format = NULL);
|
||||
IMGUI_API void Color(const char* prefix, const ImVec4& v);
|
||||
IMGUI_API void Color(const char* prefix, unsigned int v);
|
||||
|
||||
// Logging
|
||||
void LogButtons();
|
||||
void LogToTTY(int max_depth = -1);
|
||||
void LogToFile(int max_depth = -1, const char* filename = NULL);
|
||||
void LogToClipboard(int max_depth = -1);
|
||||
IMGUI_API void LogButtons();
|
||||
IMGUI_API void LogToTTY(int max_depth = -1);
|
||||
IMGUI_API void LogToFile(int max_depth = -1, const char* filename = NULL);
|
||||
IMGUI_API void LogToClipboard(int max_depth = -1);
|
||||
|
||||
// Utilities
|
||||
void SetNewWindowDefaultPos(const ImVec2& pos); // set position of window that do
|
||||
bool IsHovered(); // was the last item active area hovered by mouse?
|
||||
ImVec2 GetItemBoxMin(); // get bounding box of last item
|
||||
ImVec2 GetItemBoxMax(); // get bounding box of last item
|
||||
bool IsClipped(const ImVec2& item_size); // to perform coarse clipping on user's side (as an optimisation)
|
||||
bool IsKeyPressed(int key_index, bool repeat = true); // key_index into the keys_down[512] array, imgui doesn't know the semantic of each entry
|
||||
bool IsMouseClicked(int button, bool repeat = false);
|
||||
bool IsMouseDoubleClicked(int button);
|
||||
bool IsMouseHoveringBox(const ImVec2& box_min, const ImVec2& box_max);
|
||||
ImVec2 GetMousePos();
|
||||
float GetTime();
|
||||
int GetFrameCount();
|
||||
const char* GetStyleColorName(ImGuiCol idx);
|
||||
void GetDefaultFontData(const void** fnt_data, unsigned int* fnt_size, const void** png_data, unsigned int* png_size);
|
||||
ImVec2 CalcTextSize(const char* text, const char* text_end = NULL, const bool hide_text_after_hash = true);
|
||||
IMGUI_API void SetNewWindowDefaultPos(const ImVec2& pos); // set position of window that do
|
||||
IMGUI_API bool IsItemHovered(); // was the last item active area hovered by mouse?
|
||||
IMGUI_API bool IsItemFocused(); // was the last item focused for keyboard input?
|
||||
IMGUI_API ImVec2 GetItemBoxMin(); // get bounding box of last item
|
||||
IMGUI_API ImVec2 GetItemBoxMax(); // get bounding box of last item
|
||||
IMGUI_API bool IsClipped(const ImVec2& item_size); // to perform coarse clipping on user's side (as an optimization)
|
||||
IMGUI_API bool IsKeyPressed(int key_index, bool repeat = true); // key_index into the keys_down[512] array, imgui doesn't know the semantic of each entry
|
||||
IMGUI_API bool IsMouseClicked(int button, bool repeat = false);
|
||||
IMGUI_API bool IsMouseDoubleClicked(int button);
|
||||
IMGUI_API bool IsMouseHoveringWindow(); // is mouse hovering current window ("window" in API names always refer to current window)
|
||||
IMGUI_API bool IsMouseHoveringAnyWindow(); // is mouse hovering any active imgui window
|
||||
IMGUI_API bool IsMouseHoveringBox(const ImVec2& box_min, const ImVec2& box_max); // is mouse hovering given bounding box
|
||||
IMGUI_API bool IsPosHoveringAnyWindow(const ImVec2& pos); // is given position hovering any active imgui window
|
||||
IMGUI_API ImVec2 GetMousePos(); // shortcut to ImGui::GetIO().MousePos provided by user, to be consistent with other calls
|
||||
IMGUI_API float GetTime();
|
||||
IMGUI_API int GetFrameCount();
|
||||
IMGUI_API const char* GetStyleColorName(ImGuiCol idx);
|
||||
IMGUI_API void GetDefaultFontData(const void** fnt_data, unsigned int* fnt_size, const void** png_data, unsigned int* png_size);
|
||||
IMGUI_API ImVec2 CalcTextSize(const char* text, const char* text_end = NULL, bool hide_text_after_double_hash = true, float wrap_width = -1.0f);
|
||||
|
||||
}; // namespace ImGui
|
||||
} // namespace ImGui
|
||||
|
||||
// Flags for ImGui::Begin()
|
||||
enum ImGuiWindowFlags_
|
||||
@ -265,21 +308,26 @@ enum ImGuiWindowFlags_
|
||||
ImGuiWindowFlags_NoResize = 1 << 2,
|
||||
ImGuiWindowFlags_NoMove = 1 << 3,
|
||||
ImGuiWindowFlags_NoScrollbar = 1 << 4,
|
||||
ImGuiWindowFlags_ChildWindow = 1 << 5, // For internal use by BeginChild()
|
||||
ImGuiWindowFlags_ChildWindowAutoFitX = 1 << 6, // For internal use by BeginChild()
|
||||
ImGuiWindowFlags_ChildWindowAutoFitY = 1 << 7, // For internal use by BeginChild()
|
||||
ImGuiWindowFlags_ComboBox = 1 << 8, // For internal use by ComboBox()
|
||||
ImGuiWindowFlags_Tooltip = 1 << 9, // For internal use by Render() when using Tooltip
|
||||
ImGuiWindowFlags_AlwaysAutoResize = 1 << 5,
|
||||
ImGuiWindowFlags_ChildWindow = 1 << 6, // For internal use by BeginChild()
|
||||
ImGuiWindowFlags_ChildWindowAutoFitX = 1 << 7, // For internal use by BeginChild()
|
||||
ImGuiWindowFlags_ChildWindowAutoFitY = 1 << 8, // For internal use by BeginChild()
|
||||
ImGuiWindowFlags_ComboBox = 1 << 9, // For internal use by ComboBox()
|
||||
ImGuiWindowFlags_Tooltip = 1 << 10 // For internal use by Render() when using Tooltip
|
||||
};
|
||||
|
||||
// Flags for ImGui::InputText()
|
||||
enum ImGuiInputTextFlags_
|
||||
{
|
||||
// Default: 0
|
||||
ImGuiInputTextFlags_CharsDecimal = 1 << 0,
|
||||
ImGuiInputTextFlags_CharsHexadecimal = 1 << 1,
|
||||
ImGuiInputTextFlags_AutoSelectAll = 1 << 2,
|
||||
ImGuiInputTextFlags_AlignCenter = 1 << 3,
|
||||
ImGuiInputTextFlags_CharsDecimal = 1 << 0, // Allow 0123456789.+-*/
|
||||
ImGuiInputTextFlags_CharsHexadecimal = 1 << 1, // Allow 0123456789ABCDEFabcdef
|
||||
ImGuiInputTextFlags_AutoSelectAll = 1 << 2, // Select entire text when first taking focus
|
||||
ImGuiInputTextFlags_EnterReturnsTrue = 1 << 3, // Return 'true' when Enter is pressed (as opposed to when the value was modified)
|
||||
ImGuiInputTextFlags_CallbackCompletion = 1 << 4, // Call user function on pressing TAB (for completion handling)
|
||||
ImGuiInputTextFlags_CallbackHistory = 1 << 5, // Call user function on pressing Up/Down arrows (for history handling)
|
||||
ImGuiInputTextFlags_CallbackAlways = 1 << 6 // Call user function every frame
|
||||
//ImGuiInputTextFlags_AlignCenter = 1 << 6,
|
||||
};
|
||||
|
||||
// User fill ImGuiIO.KeyMap[] array with indices into the ImGuiIO.KeysDown[512] array
|
||||
@ -302,9 +350,10 @@ enum ImGuiKey_
|
||||
ImGuiKey_X, // for CTRL+X: cut
|
||||
ImGuiKey_Y, // for CTRL+Y: redo
|
||||
ImGuiKey_Z, // for CTRL+Z: undo
|
||||
ImGuiKey_COUNT,
|
||||
ImGuiKey_COUNT
|
||||
};
|
||||
|
||||
// Enumeration for PushStyleColor() / PopStyleColor()
|
||||
enum ImGuiCol_
|
||||
{
|
||||
ImGuiCol_Text,
|
||||
@ -344,15 +393,29 @@ enum ImGuiCol_
|
||||
ImGuiCol_PlotHistogramHovered,
|
||||
ImGuiCol_TextSelectedBg,
|
||||
ImGuiCol_TooltipBg,
|
||||
ImGuiCol_COUNT,
|
||||
ImGuiCol_COUNT
|
||||
};
|
||||
|
||||
// Enumeration for PushStyleVar() / PopStyleVar()
|
||||
// NB: the enum only refers to fields of ImGuiStyle() which makes sense to be pushed/poped in UI code. Feel free to add others.
|
||||
enum ImGuiStyleVar_
|
||||
{
|
||||
ImGuiStyleVar_Alpha, // float
|
||||
ImGuiStyleVar_WindowPadding, // ImVec2
|
||||
ImGuiStyleVar_FramePadding, // ImVec2
|
||||
ImGuiStyleVar_ItemSpacing, // ImVec2
|
||||
ImGuiStyleVar_ItemInnerSpacing, // ImVec2
|
||||
ImGuiStyleVar_TreeNodeSpacing, // float
|
||||
ImGuiStyleVar_ColumnsMinSpacing // float
|
||||
};
|
||||
|
||||
// Enumeration for ColorEditMode()
|
||||
enum ImGuiColorEditMode_
|
||||
{
|
||||
ImGuiColorEditMode_UserSelect = -1,
|
||||
ImGuiColorEditMode_RGB = 0,
|
||||
ImGuiColorEditMode_HSV = 1,
|
||||
ImGuiColorEditMode_HEX = 2,
|
||||
ImGuiColorEditMode_HEX = 2
|
||||
};
|
||||
|
||||
struct ImGuiStyle
|
||||
@ -372,14 +435,17 @@ struct ImGuiStyle
|
||||
float ScrollBarWidth; // Width of the vertical scroll bar
|
||||
ImVec4 Colors[ImGuiCol_COUNT];
|
||||
|
||||
ImGuiStyle();
|
||||
IMGUI_API ImGuiStyle();
|
||||
};
|
||||
|
||||
// This is where your app communicate with ImGui. Call ImGui::GetIO() to access.
|
||||
// Read 'Programmer guide' section in .cpp file for general usage.
|
||||
struct ImGuiIO
|
||||
{
|
||||
//------------------------------------------------------------------
|
||||
// Settings (fill once) // Default value:
|
||||
//------------------------------------------------------------------
|
||||
|
||||
ImVec2 DisplaySize; // <unset> // Display size, in pixels. For clamping windows positions.
|
||||
float DeltaTime; // = 1.0f/60.0f // Time elapsed since last frame, in seconds.
|
||||
float IniSavingRate; // = 5.0f // Maximum time between saving .ini file, in seconds. Set to a negative value to disable .ini saving.
|
||||
@ -388,40 +454,60 @@ struct ImGuiIO
|
||||
float MouseDoubleClickTime; // = 0.30f // Time for a double-click, in seconds.
|
||||
float MouseDoubleClickMaxDist; // = 6.0f // Distance threshold to stay in to validate a double-click, in pixels.
|
||||
int KeyMap[ImGuiKey_COUNT]; // <unset> // Map of indices into the KeysDown[512] entries array
|
||||
ImFont Font; // <auto> // Gets passed to text functions. Typedef ImFont to the type you want (ImBitmapFont* or your own font).
|
||||
float FontHeight; // <auto> // Default font height, must be the vertical distance between two lines of text, aka == CalcTextSize(" ").y
|
||||
ImVec2 FontTexUvForWhite; // = (0.0f,0.0f) // Font texture must have a white pixel at this UV coordinate. Adjust if you are using custom texture.
|
||||
bool FontAllowScaling; // = false // Set to allow scaling text with CTRL+Wheel.
|
||||
ImFont* Font; // <auto> // Font (also see 'Settings' fields inside ImFont structure for details)
|
||||
float FontGlobalScale; // = 1.0f // Global scale all fonts
|
||||
bool FontAllowUserScaling; // = false // Allow user scaling text of individual window with CTRL+Wheel.
|
||||
float PixelCenterOffset; // = 0.0f // Try to set to 0.5f or 0.375f if rendering is blurry
|
||||
|
||||
// Settings - Rendering function (REQUIRED)
|
||||
void* UserData; // = NULL // Store your own data for retrieval by callbacks.
|
||||
|
||||
//------------------------------------------------------------------
|
||||
// User Functions
|
||||
//------------------------------------------------------------------
|
||||
|
||||
// REQUIRED: rendering function.
|
||||
// See example code if you are unsure of how to implement this.
|
||||
void (*RenderDrawListsFn)(ImDrawList** const draw_lists, int count);
|
||||
void (*RenderDrawListsFn)(ImDrawList** const draw_lists, int count);
|
||||
|
||||
// Settings - Clipboard Support
|
||||
// Override to provide your clipboard handlers.
|
||||
// On Windows architecture, defaults to use the native Win32 clipboard, otherwise default to use a ImGui private clipboard.
|
||||
// NB- for SetClipboardTextFn, the string is *NOT* zero-terminated at 'text_end'
|
||||
const char* (*GetClipboardTextFn)();
|
||||
void (*SetClipboardTextFn)(const char* text, const char* text_end);
|
||||
// Optional: access OS clipboard (default to use native Win32 clipboard on Windows, otherwise use a ImGui private clipboard)
|
||||
// Override to access OS clipboard on other architectures.
|
||||
const char* (*GetClipboardTextFn)();
|
||||
void (*SetClipboardTextFn)(const char* text);
|
||||
|
||||
// Optional: override memory allocations (default to posix malloc/realloc/free)
|
||||
void* (*MemAllocFn)(size_t sz);
|
||||
void* (*MemReallocFn)(void* ptr, size_t sz);
|
||||
void (*MemFreeFn)(void* ptr);
|
||||
|
||||
// Optional: notify OS Input Method Editor of text input position (e.g. when using Japanese/Chinese inputs, otherwise this isn't needed)
|
||||
void (*ImeSetInputScreenPosFn)(int x, int y);
|
||||
|
||||
//------------------------------------------------------------------
|
||||
// Input - Fill before calling NewFrame()
|
||||
//------------------------------------------------------------------
|
||||
|
||||
ImVec2 MousePos; // Mouse position, in pixels (set to -1,-1 if no mouse / on another screen, etc.)
|
||||
bool MouseDown[5]; // Mouse buttons. ImGui itself only uses button 0 (left button) but you can use others as storage for convenience.
|
||||
int MouseWheel; // Mouse wheel: -1,0,+1
|
||||
float MouseWheel; // Mouse wheel: 1 unit scrolls about 5 lines text.
|
||||
bool KeyCtrl; // Keyboard modifier pressed: Control
|
||||
bool KeyShift; // Keyboard modifier pressed: Shift
|
||||
bool KeysDown[512]; // Keyboard keys that are pressed (in whatever order user naturally has access to keyboard data)
|
||||
char InputCharacters[16]; // List of characters input (translated by user from keypress+keyboard state). Fill using AddInputCharacter() helper.
|
||||
|
||||
// Output - Retrieve after calling NewFrame(), you can use them to discard inputs or hide them from the rest of your application
|
||||
bool WantCaptureMouse; // ImGui is using your mouse input (= window is being hovered or widget is active).
|
||||
bool WantCaptureKeyboard; // imGui is using your keyboard input (= widget is active).
|
||||
ImWchar InputCharacters[16+1]; // List of characters input (translated by user from keypress+keyboard state). Fill using AddInputCharacter() helper.
|
||||
|
||||
// Function
|
||||
void AddInputCharacter(char c); // Helper to add a new character into InputCharacters[]
|
||||
IMGUI_API void AddInputCharacter(ImWchar c); // Helper to add a new character into InputCharacters[]
|
||||
|
||||
//------------------------------------------------------------------
|
||||
// Output - Retrieve after calling NewFrame(), you can use them to discard inputs or hide them from the rest of your application
|
||||
//------------------------------------------------------------------
|
||||
|
||||
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)
|
||||
|
||||
//------------------------------------------------------------------
|
||||
// [Internal] ImGui will maintain those fields for you
|
||||
//------------------------------------------------------------------
|
||||
|
||||
ImVec2 MousePosPrev;
|
||||
ImVec2 MouseDelta;
|
||||
bool MouseClicked[5];
|
||||
@ -431,7 +517,7 @@ struct ImGuiIO
|
||||
float MouseDownTime[5];
|
||||
float KeysDownTime[512];
|
||||
|
||||
ImGuiIO();
|
||||
IMGUI_API ImGuiIO();
|
||||
};
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
@ -439,23 +525,27 @@ struct ImGuiIO
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
// Helper: execute a block of code once a frame only
|
||||
// Usage: if (IMGUI_ONCE_UPON_A_FRAME) {/*do something once a frame*/)
|
||||
#define IMGUI_ONCE_UPON_A_FRAME static ImGuiOncePerFrame im = ImGuiOncePerFrame()
|
||||
struct ImGuiOncePerFrame
|
||||
// Convenient if you want to quickly create an UI within deep-nested code that runs multiple times every frame.
|
||||
// Usage:
|
||||
// IMGUI_ONCE_UPON_A_FRAME
|
||||
// {
|
||||
// // code block will be executed one per frame
|
||||
// }
|
||||
// Attention! the macro expands into 2 statement so make sure you don't use it within e.g. an if() statement without curly braces.
|
||||
#define IMGUI_ONCE_UPON_A_FRAME static ImGuiOnceUponAFrame imgui_oaf##__LINE__; if (imgui_oaf##__LINE__)
|
||||
struct ImGuiOnceUponAFrame
|
||||
{
|
||||
ImGuiOncePerFrame() : LastFrame(-1) {}
|
||||
operator bool() const { return TryIsNewFrame(); }
|
||||
private:
|
||||
mutable int LastFrame;
|
||||
bool TryIsNewFrame() const { const int current_frame = ImGui::GetFrameCount(); if (LastFrame == current_frame) return false; LastFrame = current_frame; return true; }
|
||||
ImGuiOnceUponAFrame() { RefFrame = -1; }
|
||||
mutable int RefFrame;
|
||||
operator bool() const { const int current_frame = ImGui::GetFrameCount(); if (RefFrame == current_frame) return false; RefFrame = current_frame; return true; }
|
||||
};
|
||||
|
||||
// Helper: Parse and apply text filters. In format "aaaaa[,bbbb][,ccccc]"
|
||||
struct ImGuiTextFilter
|
||||
{
|
||||
struct TextRange
|
||||
{
|
||||
const char* b;
|
||||
struct TextRange
|
||||
{
|
||||
const char* b;
|
||||
const char* e;
|
||||
|
||||
TextRange() { b = e = NULL; }
|
||||
@ -464,9 +554,9 @@ struct ImGuiTextFilter
|
||||
const char* end() const { return e; }
|
||||
bool empty() const { return b == e; }
|
||||
char front() const { return *b; }
|
||||
static bool isblank(char c) { return c == ' ' || c == '\t'; }
|
||||
static bool isblank(char c) { return c == ' ' || c == '\t'; }
|
||||
void trim_blanks() { while (b < e && isblank(*b)) b++; while (e > b && isblank(*(e-1))) e--; }
|
||||
void split(char separator, ImVector<TextRange>& out);
|
||||
IMGUI_API void split(char separator, ImVector<TextRange>& out);
|
||||
};
|
||||
|
||||
char InputBuf[256];
|
||||
@ -478,7 +568,7 @@ struct ImGuiTextFilter
|
||||
void Draw(const char* label = "Filter (inc,-exc)", float width = -1.0f); // Helper calling InputText+Build
|
||||
bool PassFilter(const char* val) const;
|
||||
bool IsActive() const { return !Filters.empty(); }
|
||||
void Build();
|
||||
IMGUI_API void Build();
|
||||
};
|
||||
|
||||
// Helper: Text buffer for logging/accumulating text
|
||||
@ -487,12 +577,13 @@ struct ImGuiTextBuffer
|
||||
ImVector<char> Buf;
|
||||
|
||||
ImGuiTextBuffer() { Buf.push_back(0); }
|
||||
const char* begin() const { return Buf.begin(); }
|
||||
const char* end() const { return Buf.end()-1; }
|
||||
~ImGuiTextBuffer() { clear(); }
|
||||
const char* begin() const { return &Buf.front(); }
|
||||
const char* end() const { return &Buf.back(); } // Buf is zero-terminated, so end() will point on the zero-terminator
|
||||
size_t size() const { return Buf.size()-1; }
|
||||
bool empty() { return Buf.empty(); }
|
||||
void clear() { Buf.clear(); Buf.push_back(0); }
|
||||
void append(const char* fmt, ...);
|
||||
IMGUI_API void append(const char* fmt, ...);
|
||||
};
|
||||
|
||||
// Helper: Key->value storage
|
||||
@ -503,15 +594,33 @@ struct ImGuiTextBuffer
|
||||
struct ImGuiStorage
|
||||
{
|
||||
struct Pair { ImU32 key; int val; };
|
||||
ImVector<Pair> Data;
|
||||
ImVector<Pair> Data;
|
||||
|
||||
void Clear();
|
||||
int GetInt(ImU32 key, int default_val = 0);
|
||||
void SetInt(ImU32 key, int val);
|
||||
void SetAllInt(int val);
|
||||
IMGUI_API void Clear();
|
||||
IMGUI_API int GetInt(ImU32 key, int default_val = 0);
|
||||
IMGUI_API void SetInt(ImU32 key, int val);
|
||||
IMGUI_API void SetAllInt(int val);
|
||||
|
||||
int* Find(ImU32 key);
|
||||
void Insert(ImU32 key, int val);
|
||||
IMGUI_API int* Find(ImU32 key);
|
||||
IMGUI_API void Insert(ImU32 key, int val);
|
||||
};
|
||||
|
||||
// Shared state of InputText(), passed to callback when a ImGuiInputTextFlags_Callback* flag is used.
|
||||
struct ImGuiTextEditCallbackData
|
||||
{
|
||||
ImGuiKey EventKey; // Key pressed (Up/Down/TAB) // Read-only
|
||||
char* Buf; // Current text // Read-write (pointed data only)
|
||||
size_t BufSize; // // Read-only
|
||||
bool BufDirty; // Set if you modify Buf directly // Write
|
||||
ImGuiInputTextFlags Flags; // What user passed to InputText() // Read-only
|
||||
int CursorPos; // // Read-write
|
||||
int SelectionStart; // // Read-write (== to SelectionEnd when no selection)
|
||||
int SelectionEnd; // // Read-write
|
||||
void* UserData; // What user passed to InputText()
|
||||
|
||||
// NB: calling those function loses selection.
|
||||
void DeleteChars(int pos, int bytes_count);
|
||||
void InsertChars(int pos, const char* text, const char* text_end = NULL);
|
||||
};
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
@ -525,16 +634,27 @@ struct ImDrawCmd
|
||||
ImVec4 clip_rect;
|
||||
};
|
||||
|
||||
// sizeof() == 20
|
||||
#ifndef IMGUI_OVERRIDE_DRAWVERT_STRUCT_LAYOUT
|
||||
// Default vertex layout
|
||||
struct ImDrawVert
|
||||
{
|
||||
ImVec2 pos;
|
||||
ImVec2 uv;
|
||||
ImU32 col;
|
||||
};
|
||||
#else
|
||||
// You can change the vertex format layout by defining IMGUI_OVERRIDE_DRAWVERT_STRUCT_LAYOUT.
|
||||
// The code expect ImVec2 pos (8 bytes), ImVec2 uv (8 bytes), ImU32 col (4 bytes), but you can re-order them or add other fields as needed to simplify integration in your engine.
|
||||
// The type has to be described by the #define (you can either declare the struct or use a typedef)
|
||||
IMGUI_OVERRIDE_DRAWVERT_STRUCT_LAYOUT;
|
||||
#endif
|
||||
|
||||
// Draw command list
|
||||
// User is responsible for providing a renderer for this in ImGuiIO::RenderDrawListFn
|
||||
// This is the low-level list of polygon that ImGui:: functions are filling. At the end of the frame, all command lists are passed to your ImGuiIO::RenderDrawListFn function for rendering.
|
||||
// Each ImGui window contains its own ImDrawList.
|
||||
// If you want to add custom rendering within a window, you can use ImGui::GetWindowDrawList() to access the current draw list and add your own primitives.
|
||||
// You can interleave normal ImGui:: calls and adding primitives to the current draw list.
|
||||
// Note that this only gives you access to rendering polygons. If your intent is to create custom widgets and the publicly exposed functions/data aren't sufficient, you can add code in imgui_user.inl
|
||||
struct ImDrawList
|
||||
{
|
||||
// This is what you have to render
|
||||
@ -547,34 +667,76 @@ struct ImDrawList
|
||||
|
||||
ImDrawList() { Clear(); }
|
||||
|
||||
void Clear();
|
||||
void PushClipRect(const ImVec4& clip_rect);
|
||||
void PopClipRect();
|
||||
void ReserveVertices(unsigned int vtx_count);
|
||||
void AddVtx(const ImVec2& pos, ImU32 col);
|
||||
void AddVtxLine(const ImVec2& a, const ImVec2& b, ImU32 col);
|
||||
IMGUI_API void Clear();
|
||||
IMGUI_API void PushClipRect(const ImVec4& clip_rect);
|
||||
IMGUI_API void PopClipRect();
|
||||
IMGUI_API void ReserveVertices(unsigned int vtx_count);
|
||||
IMGUI_API void AddVtx(const ImVec2& pos, ImU32 col);
|
||||
IMGUI_API void AddVtxLine(const ImVec2& a, const ImVec2& b, ImU32 col);
|
||||
|
||||
// Primitives
|
||||
void AddLine(const ImVec2& a, const ImVec2& b, ImU32 col);
|
||||
void AddRect(const ImVec2& a, const ImVec2& b, ImU32 col, float rounding = 0.0f, int rounding_corners=0x0F);
|
||||
void AddRectFilled(const ImVec2& a, const ImVec2& b, ImU32 col, float rounding = 0.0f, int rounding_corners=0x0F);
|
||||
void AddTriangleFilled(const ImVec2& a, const ImVec2& b, const ImVec2& c, ImU32 col);
|
||||
void AddCircle(const ImVec2& centre, float radius, ImU32 col, int num_segments = 12);
|
||||
void AddCircleFilled(const ImVec2& centre, float radius, ImU32 col, int num_segments = 12);
|
||||
void AddArc(const ImVec2& center, float rad, ImU32 col, int a_min, int a_max, bool tris=false, const ImVec2& third_point_offset = ImVec2(0,0));
|
||||
void AddText(ImFont font, float font_size, const ImVec2& pos, ImU32 col, const char* text_begin, const char* text_end);
|
||||
// Primitives
|
||||
IMGUI_API void AddLine(const ImVec2& a, const ImVec2& b, ImU32 col);
|
||||
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 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 AddCircleFilled(const ImVec2& centre, float radius, ImU32 col, int num_segments = 12);
|
||||
IMGUI_API void AddArc(const ImVec2& center, float rad, ImU32 col, int a_min, int a_max, bool tris = false, const ImVec2& third_point_offset = ImVec2(0,0));
|
||||
IMGUI_API void AddText(ImFont* font, float font_size, const ImVec2& pos, ImU32 col, const char* text_begin, const char* text_end = NULL, float wrap_width = 0.0f);
|
||||
};
|
||||
|
||||
// Optional bitmap font data loader & renderer into vertices
|
||||
// #define ImFont to ImBitmapFont to use
|
||||
// Using the .fnt format exported by BMFont
|
||||
// - tool: http://www.angelcode.com/products/bmfont
|
||||
// - file-format: http://www.angelcode.com/products/bmfont/doc/file_format.html
|
||||
// Assume valid file data (won't handle invalid/malicious data)
|
||||
// Handle a subset of parameters.
|
||||
// - kerning pair are not supported (because ImGui code does per-character CalcTextSize calls, need to turn it into something more stateful to allow kerning)
|
||||
struct ImBitmapFont
|
||||
// Handle a subset of the options, namely:
|
||||
// - kerning pair are not supported (because some ImGui code does per-character CalcTextSize calls, need to turn it into something more state-ful to allow for kerning)
|
||||
struct ImFont
|
||||
{
|
||||
struct FntInfo;
|
||||
struct FntCommon;
|
||||
struct FntGlyph;
|
||||
struct FntKerning;
|
||||
|
||||
// Settings
|
||||
float Scale; // = 1.0f // Base font scale, multiplied by the per-window font scale which you can adjust with SetFontScale()
|
||||
ImVec2 DisplayOffset; // = (0.0f,0.0f // Offset font rendering by xx pixels
|
||||
ImVec2 TexUvForWhite; // = (0.0f,0.0f) // Font texture must have a white pixel at this UV coordinate. Adjust if you are using custom texture.
|
||||
ImWchar FallbackChar; // = '?' // Replacement glyph is one isn't found.
|
||||
|
||||
// Data
|
||||
unsigned char* Data; // Raw data, content of .fnt file
|
||||
size_t DataSize; //
|
||||
bool DataOwned; //
|
||||
const FntInfo* Info; // (point into raw data)
|
||||
const FntCommon* Common; // (point into raw data)
|
||||
const FntGlyph* Glyphs; // (point into raw data)
|
||||
size_t GlyphsCount; //
|
||||
const FntKerning* Kerning; // (point into raw data) - NB: kerning is unsupported
|
||||
size_t KerningCount; //
|
||||
ImVector<const char*> Filenames; // (point into raw data)
|
||||
ImVector<int> IndexLookup; // (built)
|
||||
const FntGlyph* FallbackGlyph; // == FindGlyph(FontFallbackChar)
|
||||
|
||||
IMGUI_API ImFont();
|
||||
IMGUI_API ~ImFont() { Clear(); }
|
||||
|
||||
IMGUI_API bool LoadFromMemory(const void* data, size_t data_size);
|
||||
IMGUI_API bool LoadFromFile(const char* filename);
|
||||
IMGUI_API void Clear();
|
||||
IMGUI_API void BuildLookupTable();
|
||||
IMGUI_API const FntGlyph* FindGlyph(unsigned short c) const;
|
||||
IMGUI_API bool IsLoaded() const { return Info != NULL && Common != NULL && Glyphs != NULL; }
|
||||
|
||||
// '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.
|
||||
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 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;
|
||||
|
||||
IMGUI_API const char* CalcWordWrapPositionA(float scale, const char* text, const char* text_end, float wrap_width) const;
|
||||
|
||||
#pragma pack(push, 1)
|
||||
struct FntInfo
|
||||
{
|
||||
@ -584,15 +746,13 @@ struct ImBitmapFont
|
||||
unsigned short StretchH;
|
||||
unsigned char AA;
|
||||
unsigned char PaddingUp, PaddingRight, PaddingDown, PaddingLeft;
|
||||
unsigned char SpacingHoriz, SpacingVert;
|
||||
unsigned char Outline;
|
||||
unsigned char SpacingHoriz, SpacingVert, Outline;
|
||||
//char FontName[];
|
||||
};
|
||||
|
||||
struct FntCommon
|
||||
{
|
||||
unsigned short LineHeight;
|
||||
unsigned short Base;
|
||||
unsigned short LineHeight, Base;
|
||||
unsigned short ScaleW, ScaleH;
|
||||
unsigned short Pages;
|
||||
unsigned char BitField;
|
||||
@ -602,8 +762,7 @@ struct ImBitmapFont
|
||||
struct FntGlyph
|
||||
{
|
||||
unsigned int Id;
|
||||
unsigned short X, Y;
|
||||
unsigned short Width, Height;
|
||||
unsigned short X, Y, Width, Height;
|
||||
signed short XOffset, YOffset;
|
||||
signed short XAdvance;
|
||||
unsigned char Page;
|
||||
@ -617,30 +776,4 @@ struct ImBitmapFont
|
||||
signed short Amount;
|
||||
};
|
||||
#pragma pack(pop)
|
||||
|
||||
unsigned char* Data; // Raw data, content of .fnt file
|
||||
size_t DataSize; //
|
||||
bool DataOwned; //
|
||||
const FntInfo* Info; // (point into raw data)
|
||||
const FntCommon* Common; // (point into raw data)
|
||||
const FntGlyph* Glyphs; // (point into raw data)
|
||||
size_t GlyphsCount; //
|
||||
const FntKerning* Kerning; // (point into raw data)
|
||||
size_t KerningCount; //
|
||||
int TabCount; // FIXME: mishandled (add fixed amount instead of aligning to column)
|
||||
ImVector<const char*> Filenames; // (point into raw data)
|
||||
ImVector<int> IndexLookup; // (built)
|
||||
|
||||
ImBitmapFont();
|
||||
~ImBitmapFont() { Clear(); }
|
||||
|
||||
bool LoadFromMemory(const void* data, size_t data_size);
|
||||
bool LoadFromFile(const char* filename);
|
||||
void Clear();
|
||||
void BuildLookupTable();
|
||||
const FntGlyph * FindGlyph(unsigned short c) const;
|
||||
float GetFontSize() const { return (float)Info->FontSize; }
|
||||
|
||||
ImVec2 CalcTextSize(float size, float max_width, const char* text_begin, const char* text_end, const char** remaining = NULL) const;
|
||||
void RenderText(float size, ImVec2 pos, ImU32 col, const ImVec4& clip_rect, const char* text_begin, const char* text_end, ImDrawVert*& out_vertices) const;
|
||||
};
|
||||
|
@ -1008,13 +1008,13 @@ static void stb_textedit_discard_undo(StbUndoState *state)
|
||||
int n = state->undo_rec[0].insert_length, i;
|
||||
// delete n characters from all other records
|
||||
state->undo_char_point = state->undo_char_point - (short) n; // vsnet05
|
||||
memmove(state->undo_char, state->undo_char + n, (size_t) (state->undo_char_point*sizeof(STB_TEXTEDIT_CHARTYPE)));
|
||||
memmove(state->undo_char, state->undo_char + n, (size_t) ((size_t)state->undo_char_point*sizeof(STB_TEXTEDIT_CHARTYPE)));
|
||||
for (i=0; i < state->undo_point; ++i)
|
||||
if (state->undo_rec[i].char_storage >= 0)
|
||||
state->undo_rec[i].char_storage = state->undo_rec[i].char_storage - (short) n; // vsnet05 // @OPTIMIZE: get rid of char_storage and infer it
|
||||
}
|
||||
--state->undo_point;
|
||||
memmove(state->undo_rec, state->undo_rec+1, (size_t) (state->undo_point*sizeof(state->undo_rec[0])));
|
||||
memmove(state->undo_rec, state->undo_rec+1, (size_t) ((size_t)state->undo_point*sizeof(state->undo_rec[0])));
|
||||
}
|
||||
}
|
||||
|
||||
@ -1032,13 +1032,13 @@ static void stb_textedit_discard_redo(StbUndoState *state)
|
||||
int n = state->undo_rec[k].insert_length, i;
|
||||
// delete n characters from all other records
|
||||
state->redo_char_point = state->redo_char_point + (short) n; // vsnet05
|
||||
memmove(state->undo_char + state->redo_char_point, state->undo_char + state->redo_char_point-n, (size_t) ((STB_TEXTEDIT_UNDOSTATECOUNT - state->redo_char_point)*sizeof(STB_TEXTEDIT_CHARTYPE)));
|
||||
memmove(state->undo_char + state->redo_char_point, state->undo_char + state->redo_char_point-n, (size_t) ((size_t)(STB_TEXTEDIT_UNDOSTATECOUNT - state->redo_char_point)*sizeof(STB_TEXTEDIT_CHARTYPE)));
|
||||
for (i=state->redo_point; i < k; ++i)
|
||||
if (state->undo_rec[i].char_storage >= 0)
|
||||
state->undo_rec[i].char_storage = state->undo_rec[i].char_storage + (short) n; // vsnet05
|
||||
}
|
||||
++state->redo_point;
|
||||
memmove(state->undo_rec + state->redo_point-1, state->undo_rec + state->redo_point, (size_t) ((STB_TEXTEDIT_UNDOSTATECOUNT - state->redo_point)*sizeof(state->undo_rec[0])));
|
||||
memmove(state->undo_rec + state->redo_point-1, state->undo_rec + state->redo_point, (size_t) ((size_t)(STB_TEXTEDIT_UNDOSTATECOUNT - state->redo_point)*sizeof(state->undo_rec[0])));
|
||||
}
|
||||
}
|
||||
|
||||
|
BIN
web/performance_01.png
Normal file
After Width: | Height: | Size: 14 KiB |
BIN
web/performance_01_close_up.png
Normal file
After Width: | Height: | Size: 7.8 KiB |
Before Width: | Height: | Size: 18 KiB After Width: | Height: | Size: 7.1 KiB |
BIN
web/utf8_sample_01.png
Normal file
After Width: | Height: | Size: 5.4 KiB |