diff --git a/examples/README.txt b/examples/README.txt index df2e86d..5a1c8df 100644 --- a/examples/README.txt +++ b/examples/README.txt @@ -8,11 +8,13 @@ TL;DR; - Newcomers, read 'PROGRAMMER GUIDE' in imgui.cpp for notes on how to setup ImGui in your codebase. - - Refer to 'opengl_example' to understand how the library is setup, it is the simplest one. + - Refer to 'opengl2_example' to LEARN how the library is setup, it is the simplest one. The other examples requires more boilerplate and are harder to read. + - If you are using OpenGL in your application, probably use an opengl3_xxx backend. + Mixing old fixed pipeline OpenGL2 and programmable pipeline OpenGL3+ isn't well supported by drivers. - If you are using of the backend provided here, so you can copy the imgui_impl_xxx.cpp/h files to your project and use them unmodified. - - If you have your own engine, you probably want to start from 'opengl_example' and adapt it to + - If you have your own engine, you probably want to start from one of the OpenGL example and adapt it to your engine, but you can read the other examples as well. ImGui is highly portable and only requires a few things to run: @@ -41,15 +43,14 @@ Also note that some setup or GPU drivers may be causing extra lag (possibly by enforcing triple buffering), leaving you with no option but sadness/anger (Intel GPU drivers were reported as such). -opengl_example/ - OpenGL example, using GLFW + fixed pipeline. - This is simple and should work for all OpenGL enabled applications. - Prefer following this example to learn how ImGui works! - (You can use this code in a GL3/GL4 context but make sure you disable the programmable pipeline - by calling "glUseProgram(0)" before ImGui::Render.) +opengl2_example/ + GLFW + OpenGL example (old fixed pipeline). + This is simple to read. Prefer following this example to learn how ImGui works! + (You might be able to use this code in a GL3/GL4 context but make sure you disable the programmable + pipeline by calling "glUseProgram(0)" before ImGui::Render.) opengl3_example/ - OpenGL example, using GLFW/GL3W + programmable pipeline. + GLFW + OpenGL example (programmable pipeline, binding modern functions with GL3W). This uses more modern OpenGL calls and custom shaders. It's more messy. directx9_example/ @@ -68,8 +69,8 @@ On iOS, Using Synergy to access keyboard/mouse data from server computer. Synergy keyboard integration is rather hacky. -sdl_opengl_example/ - SDL2 + OpenGL example. +sdl_opengl2_example/ + SDL2 + OpenGL example (old fixed pipeline). sdl_opengl3_example/ SDL2 + OpenGL3 example. diff --git a/examples/README.txt b/examples/README.txt index df2e86d..5a1c8df 100644 --- a/examples/README.txt +++ b/examples/README.txt @@ -8,11 +8,13 @@ TL;DR; - Newcomers, read 'PROGRAMMER GUIDE' in imgui.cpp for notes on how to setup ImGui in your codebase. - - Refer to 'opengl_example' to understand how the library is setup, it is the simplest one. + - Refer to 'opengl2_example' to LEARN how the library is setup, it is the simplest one. The other examples requires more boilerplate and are harder to read. + - If you are using OpenGL in your application, probably use an opengl3_xxx backend. + Mixing old fixed pipeline OpenGL2 and programmable pipeline OpenGL3+ isn't well supported by drivers. - If you are using of the backend provided here, so you can copy the imgui_impl_xxx.cpp/h files to your project and use them unmodified. - - If you have your own engine, you probably want to start from 'opengl_example' and adapt it to + - If you have your own engine, you probably want to start from one of the OpenGL example and adapt it to your engine, but you can read the other examples as well. ImGui is highly portable and only requires a few things to run: @@ -41,15 +43,14 @@ Also note that some setup or GPU drivers may be causing extra lag (possibly by enforcing triple buffering), leaving you with no option but sadness/anger (Intel GPU drivers were reported as such). -opengl_example/ - OpenGL example, using GLFW + fixed pipeline. - This is simple and should work for all OpenGL enabled applications. - Prefer following this example to learn how ImGui works! - (You can use this code in a GL3/GL4 context but make sure you disable the programmable pipeline - by calling "glUseProgram(0)" before ImGui::Render.) +opengl2_example/ + GLFW + OpenGL example (old fixed pipeline). + This is simple to read. Prefer following this example to learn how ImGui works! + (You might be able to use this code in a GL3/GL4 context but make sure you disable the programmable + pipeline by calling "glUseProgram(0)" before ImGui::Render.) opengl3_example/ - OpenGL example, using GLFW/GL3W + programmable pipeline. + GLFW + OpenGL example (programmable pipeline, binding modern functions with GL3W). This uses more modern OpenGL calls and custom shaders. It's more messy. directx9_example/ @@ -68,8 +69,8 @@ On iOS, Using Synergy to access keyboard/mouse data from server computer. Synergy keyboard integration is rather hacky. -sdl_opengl_example/ - SDL2 + OpenGL example. +sdl_opengl2_example/ + SDL2 + OpenGL example (old fixed pipeline). sdl_opengl3_example/ SDL2 + OpenGL3 example. diff --git a/examples/imgui_examples_msvc2010.sln b/examples/imgui_examples_msvc2010.sln index b7e6a25..16f0d60 100644 --- a/examples/imgui_examples_msvc2010.sln +++ b/examples/imgui_examples_msvc2010.sln @@ -1,7 +1,7 @@  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}" +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "opengl2_example", "opengl_example\opengl2_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 diff --git a/examples/README.txt b/examples/README.txt index df2e86d..5a1c8df 100644 --- a/examples/README.txt +++ b/examples/README.txt @@ -8,11 +8,13 @@ TL;DR; - Newcomers, read 'PROGRAMMER GUIDE' in imgui.cpp for notes on how to setup ImGui in your codebase. - - Refer to 'opengl_example' to understand how the library is setup, it is the simplest one. + - Refer to 'opengl2_example' to LEARN how the library is setup, it is the simplest one. The other examples requires more boilerplate and are harder to read. + - If you are using OpenGL in your application, probably use an opengl3_xxx backend. + Mixing old fixed pipeline OpenGL2 and programmable pipeline OpenGL3+ isn't well supported by drivers. - If you are using of the backend provided here, so you can copy the imgui_impl_xxx.cpp/h files to your project and use them unmodified. - - If you have your own engine, you probably want to start from 'opengl_example' and adapt it to + - If you have your own engine, you probably want to start from one of the OpenGL example and adapt it to your engine, but you can read the other examples as well. ImGui is highly portable and only requires a few things to run: @@ -41,15 +43,14 @@ Also note that some setup or GPU drivers may be causing extra lag (possibly by enforcing triple buffering), leaving you with no option but sadness/anger (Intel GPU drivers were reported as such). -opengl_example/ - OpenGL example, using GLFW + fixed pipeline. - This is simple and should work for all OpenGL enabled applications. - Prefer following this example to learn how ImGui works! - (You can use this code in a GL3/GL4 context but make sure you disable the programmable pipeline - by calling "glUseProgram(0)" before ImGui::Render.) +opengl2_example/ + GLFW + OpenGL example (old fixed pipeline). + This is simple to read. Prefer following this example to learn how ImGui works! + (You might be able to use this code in a GL3/GL4 context but make sure you disable the programmable + pipeline by calling "glUseProgram(0)" before ImGui::Render.) opengl3_example/ - OpenGL example, using GLFW/GL3W + programmable pipeline. + GLFW + OpenGL example (programmable pipeline, binding modern functions with GL3W). This uses more modern OpenGL calls and custom shaders. It's more messy. directx9_example/ @@ -68,8 +69,8 @@ On iOS, Using Synergy to access keyboard/mouse data from server computer. Synergy keyboard integration is rather hacky. -sdl_opengl_example/ - SDL2 + OpenGL example. +sdl_opengl2_example/ + SDL2 + OpenGL example (old fixed pipeline). sdl_opengl3_example/ SDL2 + OpenGL3 example. diff --git a/examples/imgui_examples_msvc2010.sln b/examples/imgui_examples_msvc2010.sln index b7e6a25..16f0d60 100644 --- a/examples/imgui_examples_msvc2010.sln +++ b/examples/imgui_examples_msvc2010.sln @@ -1,7 +1,7 @@  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}" +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "opengl2_example", "opengl_example\opengl2_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 diff --git a/examples/opengl2_example/Makefile b/examples/opengl2_example/Makefile new file mode 100644 index 0000000..bd79d1b --- /dev/null +++ b/examples/opengl2_example/Makefile @@ -0,0 +1,60 @@ +# +# Cross Platform Makefile +# Compatible with Ubuntu 14.04.1 and Mac OS X +# +# +# if you using Mac OS X: +# You'll need glfw +# http://www.glfw.org +# + +#CXX = g++ + +EXE = opengl2_example +OBJS = main.o imgui_impl_glfw.o +OBJS += ../../imgui.o ../../imgui_demo.o ../../imgui_draw.o + +UNAME_S := $(shell uname -s) + + +ifeq ($(UNAME_S), Linux) #LINUX + ECHO_MESSAGE = "Linux" + LIBS = -lGL `pkg-config --static --libs glfw3` + + CXXFLAGS = -I../../ `pkg-config --cflags glfw3` + CXXFLAGS += -Wall -Wformat + CFLAGS = $(CXXFLAGS) +endif + +ifeq ($(UNAME_S), Darwin) #APPLE + ECHO_MESSAGE = "Mac OS X" + LIBS = -framework OpenGL -framework Cocoa -framework IOKit -framework CoreVideo + LIBS += -L/usr/local/lib -lglfw3 + + CXXFLAGS = -I../../ -I/usr/local/include + CXXFLAGS += -Wall -Wformat +# CXXFLAGS += -D__APPLE__ + CFLAGS = $(CXXFLAGS) +endif + +ifeq ($(UNAME_S), MINGW64_NT-6.3) + ECHO_MESSAGE = "Windows" + LIBS = -lglfw3 -lgdi32 -lopengl32 -limm32 + + CXXFLAGS = -I../../ -I../libs/gl3w `pkg-config --cflags glfw3` + CXXFLAGS += -Wall -Wformat + CFLAGS = $(CXXFLAGS) +endif + +.cpp.o: + $(CXX) $(CXXFLAGS) -c -o $@ $< + +all: $(EXE) + @echo Build complete for $(ECHO_MESSAGE) + +$(EXE): $(OBJS) + $(CXX) -o $(EXE) $(OBJS) $(CXXFLAGS) $(LIBS) + +clean: + rm $(EXE) $(OBJS) + diff --git a/examples/README.txt b/examples/README.txt index df2e86d..5a1c8df 100644 --- a/examples/README.txt +++ b/examples/README.txt @@ -8,11 +8,13 @@ TL;DR; - Newcomers, read 'PROGRAMMER GUIDE' in imgui.cpp for notes on how to setup ImGui in your codebase. - - Refer to 'opengl_example' to understand how the library is setup, it is the simplest one. + - Refer to 'opengl2_example' to LEARN how the library is setup, it is the simplest one. The other examples requires more boilerplate and are harder to read. + - If you are using OpenGL in your application, probably use an opengl3_xxx backend. + Mixing old fixed pipeline OpenGL2 and programmable pipeline OpenGL3+ isn't well supported by drivers. - If you are using of the backend provided here, so you can copy the imgui_impl_xxx.cpp/h files to your project and use them unmodified. - - If you have your own engine, you probably want to start from 'opengl_example' and adapt it to + - If you have your own engine, you probably want to start from one of the OpenGL example and adapt it to your engine, but you can read the other examples as well. ImGui is highly portable and only requires a few things to run: @@ -41,15 +43,14 @@ Also note that some setup or GPU drivers may be causing extra lag (possibly by enforcing triple buffering), leaving you with no option but sadness/anger (Intel GPU drivers were reported as such). -opengl_example/ - OpenGL example, using GLFW + fixed pipeline. - This is simple and should work for all OpenGL enabled applications. - Prefer following this example to learn how ImGui works! - (You can use this code in a GL3/GL4 context but make sure you disable the programmable pipeline - by calling "glUseProgram(0)" before ImGui::Render.) +opengl2_example/ + GLFW + OpenGL example (old fixed pipeline). + This is simple to read. Prefer following this example to learn how ImGui works! + (You might be able to use this code in a GL3/GL4 context but make sure you disable the programmable + pipeline by calling "glUseProgram(0)" before ImGui::Render.) opengl3_example/ - OpenGL example, using GLFW/GL3W + programmable pipeline. + GLFW + OpenGL example (programmable pipeline, binding modern functions with GL3W). This uses more modern OpenGL calls and custom shaders. It's more messy. directx9_example/ @@ -68,8 +69,8 @@ On iOS, Using Synergy to access keyboard/mouse data from server computer. Synergy keyboard integration is rather hacky. -sdl_opengl_example/ - SDL2 + OpenGL example. +sdl_opengl2_example/ + SDL2 + OpenGL example (old fixed pipeline). sdl_opengl3_example/ SDL2 + OpenGL3 example. diff --git a/examples/imgui_examples_msvc2010.sln b/examples/imgui_examples_msvc2010.sln index b7e6a25..16f0d60 100644 --- a/examples/imgui_examples_msvc2010.sln +++ b/examples/imgui_examples_msvc2010.sln @@ -1,7 +1,7 @@  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}" +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "opengl2_example", "opengl_example\opengl2_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 diff --git a/examples/opengl2_example/Makefile b/examples/opengl2_example/Makefile new file mode 100644 index 0000000..bd79d1b --- /dev/null +++ b/examples/opengl2_example/Makefile @@ -0,0 +1,60 @@ +# +# Cross Platform Makefile +# Compatible with Ubuntu 14.04.1 and Mac OS X +# +# +# if you using Mac OS X: +# You'll need glfw +# http://www.glfw.org +# + +#CXX = g++ + +EXE = opengl2_example +OBJS = main.o imgui_impl_glfw.o +OBJS += ../../imgui.o ../../imgui_demo.o ../../imgui_draw.o + +UNAME_S := $(shell uname -s) + + +ifeq ($(UNAME_S), Linux) #LINUX + ECHO_MESSAGE = "Linux" + LIBS = -lGL `pkg-config --static --libs glfw3` + + CXXFLAGS = -I../../ `pkg-config --cflags glfw3` + CXXFLAGS += -Wall -Wformat + CFLAGS = $(CXXFLAGS) +endif + +ifeq ($(UNAME_S), Darwin) #APPLE + ECHO_MESSAGE = "Mac OS X" + LIBS = -framework OpenGL -framework Cocoa -framework IOKit -framework CoreVideo + LIBS += -L/usr/local/lib -lglfw3 + + CXXFLAGS = -I../../ -I/usr/local/include + CXXFLAGS += -Wall -Wformat +# CXXFLAGS += -D__APPLE__ + CFLAGS = $(CXXFLAGS) +endif + +ifeq ($(UNAME_S), MINGW64_NT-6.3) + ECHO_MESSAGE = "Windows" + LIBS = -lglfw3 -lgdi32 -lopengl32 -limm32 + + CXXFLAGS = -I../../ -I../libs/gl3w `pkg-config --cflags glfw3` + CXXFLAGS += -Wall -Wformat + CFLAGS = $(CXXFLAGS) +endif + +.cpp.o: + $(CXX) $(CXXFLAGS) -c -o $@ $< + +all: $(EXE) + @echo Build complete for $(ECHO_MESSAGE) + +$(EXE): $(OBJS) + $(CXX) -o $(EXE) $(OBJS) $(CXXFLAGS) $(LIBS) + +clean: + rm $(EXE) $(OBJS) + diff --git a/examples/opengl2_example/build_win32.bat b/examples/opengl2_example/build_win32.bat new file mode 100644 index 0000000..278381c --- /dev/null +++ b/examples/opengl2_example/build_win32.bat @@ -0,0 +1,3 @@ +@REM Build for Visual Studio compiler. Run your copy of vcvars32.bat or vcvarsall.bat to setup command-line compiler. +mkdir Debug +cl /nologo /Zi /MD /I ..\.. /I ..\libs\glfw\include *.cpp ..\..\*.cpp /FeDebug/opengl_example.exe /FoDebug/ /link /LIBPATH:..\libs\glfw\lib-vc2010-32 glfw3.lib opengl32.lib gdi32.lib shell32.lib diff --git a/examples/README.txt b/examples/README.txt index df2e86d..5a1c8df 100644 --- a/examples/README.txt +++ b/examples/README.txt @@ -8,11 +8,13 @@ TL;DR; - Newcomers, read 'PROGRAMMER GUIDE' in imgui.cpp for notes on how to setup ImGui in your codebase. - - Refer to 'opengl_example' to understand how the library is setup, it is the simplest one. + - Refer to 'opengl2_example' to LEARN how the library is setup, it is the simplest one. The other examples requires more boilerplate and are harder to read. + - If you are using OpenGL in your application, probably use an opengl3_xxx backend. + Mixing old fixed pipeline OpenGL2 and programmable pipeline OpenGL3+ isn't well supported by drivers. - If you are using of the backend provided here, so you can copy the imgui_impl_xxx.cpp/h files to your project and use them unmodified. - - If you have your own engine, you probably want to start from 'opengl_example' and adapt it to + - If you have your own engine, you probably want to start from one of the OpenGL example and adapt it to your engine, but you can read the other examples as well. ImGui is highly portable and only requires a few things to run: @@ -41,15 +43,14 @@ Also note that some setup or GPU drivers may be causing extra lag (possibly by enforcing triple buffering), leaving you with no option but sadness/anger (Intel GPU drivers were reported as such). -opengl_example/ - OpenGL example, using GLFW + fixed pipeline. - This is simple and should work for all OpenGL enabled applications. - Prefer following this example to learn how ImGui works! - (You can use this code in a GL3/GL4 context but make sure you disable the programmable pipeline - by calling "glUseProgram(0)" before ImGui::Render.) +opengl2_example/ + GLFW + OpenGL example (old fixed pipeline). + This is simple to read. Prefer following this example to learn how ImGui works! + (You might be able to use this code in a GL3/GL4 context but make sure you disable the programmable + pipeline by calling "glUseProgram(0)" before ImGui::Render.) opengl3_example/ - OpenGL example, using GLFW/GL3W + programmable pipeline. + GLFW + OpenGL example (programmable pipeline, binding modern functions with GL3W). This uses more modern OpenGL calls and custom shaders. It's more messy. directx9_example/ @@ -68,8 +69,8 @@ On iOS, Using Synergy to access keyboard/mouse data from server computer. Synergy keyboard integration is rather hacky. -sdl_opengl_example/ - SDL2 + OpenGL example. +sdl_opengl2_example/ + SDL2 + OpenGL example (old fixed pipeline). sdl_opengl3_example/ SDL2 + OpenGL3 example. diff --git a/examples/imgui_examples_msvc2010.sln b/examples/imgui_examples_msvc2010.sln index b7e6a25..16f0d60 100644 --- a/examples/imgui_examples_msvc2010.sln +++ b/examples/imgui_examples_msvc2010.sln @@ -1,7 +1,7 @@  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}" +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "opengl2_example", "opengl_example\opengl2_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 diff --git a/examples/opengl2_example/Makefile b/examples/opengl2_example/Makefile new file mode 100644 index 0000000..bd79d1b --- /dev/null +++ b/examples/opengl2_example/Makefile @@ -0,0 +1,60 @@ +# +# Cross Platform Makefile +# Compatible with Ubuntu 14.04.1 and Mac OS X +# +# +# if you using Mac OS X: +# You'll need glfw +# http://www.glfw.org +# + +#CXX = g++ + +EXE = opengl2_example +OBJS = main.o imgui_impl_glfw.o +OBJS += ../../imgui.o ../../imgui_demo.o ../../imgui_draw.o + +UNAME_S := $(shell uname -s) + + +ifeq ($(UNAME_S), Linux) #LINUX + ECHO_MESSAGE = "Linux" + LIBS = -lGL `pkg-config --static --libs glfw3` + + CXXFLAGS = -I../../ `pkg-config --cflags glfw3` + CXXFLAGS += -Wall -Wformat + CFLAGS = $(CXXFLAGS) +endif + +ifeq ($(UNAME_S), Darwin) #APPLE + ECHO_MESSAGE = "Mac OS X" + LIBS = -framework OpenGL -framework Cocoa -framework IOKit -framework CoreVideo + LIBS += -L/usr/local/lib -lglfw3 + + CXXFLAGS = -I../../ -I/usr/local/include + CXXFLAGS += -Wall -Wformat +# CXXFLAGS += -D__APPLE__ + CFLAGS = $(CXXFLAGS) +endif + +ifeq ($(UNAME_S), MINGW64_NT-6.3) + ECHO_MESSAGE = "Windows" + LIBS = -lglfw3 -lgdi32 -lopengl32 -limm32 + + CXXFLAGS = -I../../ -I../libs/gl3w `pkg-config --cflags glfw3` + CXXFLAGS += -Wall -Wformat + CFLAGS = $(CXXFLAGS) +endif + +.cpp.o: + $(CXX) $(CXXFLAGS) -c -o $@ $< + +all: $(EXE) + @echo Build complete for $(ECHO_MESSAGE) + +$(EXE): $(OBJS) + $(CXX) -o $(EXE) $(OBJS) $(CXXFLAGS) $(LIBS) + +clean: + rm $(EXE) $(OBJS) + diff --git a/examples/opengl2_example/build_win32.bat b/examples/opengl2_example/build_win32.bat new file mode 100644 index 0000000..278381c --- /dev/null +++ b/examples/opengl2_example/build_win32.bat @@ -0,0 +1,3 @@ +@REM Build for Visual Studio compiler. Run your copy of vcvars32.bat or vcvarsall.bat to setup command-line compiler. +mkdir Debug +cl /nologo /Zi /MD /I ..\.. /I ..\libs\glfw\include *.cpp ..\..\*.cpp /FeDebug/opengl_example.exe /FoDebug/ /link /LIBPATH:..\libs\glfw\lib-vc2010-32 glfw3.lib opengl32.lib gdi32.lib shell32.lib diff --git a/examples/opengl2_example/imgui_impl_glfw.cpp b/examples/opengl2_example/imgui_impl_glfw.cpp new file mode 100644 index 0000000..2d1f5c1 --- /dev/null +++ b/examples/opengl2_example/imgui_impl_glfw.cpp @@ -0,0 +1,288 @@ +// ImGui GLFW binding with OpenGL +// In this binding, ImTextureID is used to store an OpenGL 'GLuint' texture identifier. Read the FAQ about ImTextureID in imgui.cpp. + +// If your context is GL3/GL3 then prefer using the code in opengl3_example. +// You *might* use this code with a GL3/GL4 context but make sure you disable the programmable pipeline by calling "glUseProgram(0)" before ImGui::Render(). +// We cannot do that from GL2 code because the function doesn't exist. + +// You can copy and use unmodified imgui_impl_* files in your project. See main.cpp for an example of using this. +// If you use this binding you'll need to call 4 functions: ImGui_ImplXXXX_Init(), ImGui_ImplXXXX_NewFrame(), ImGui::Render() and ImGui_ImplXXXX_Shutdown(). +// If you are new to ImGui, see examples/README.txt and documentation at the top of imgui.cpp. +// https://github.com/ocornut/imgui + +#include +#include "imgui_impl_glfw.h" + +// GLFW +#include +#ifdef _WIN32 +#undef APIENTRY +#define GLFW_EXPOSE_NATIVE_WIN32 +#define GLFW_EXPOSE_NATIVE_WGL +#include +#endif + +// Data +static GLFWwindow* g_Window = NULL; +static double g_Time = 0.0f; +static bool g_MousePressed[3] = { false, false, false }; +static float g_MouseWheel = 0.0f; +static GLuint g_FontTexture = 0; + +// 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) +void ImGui_ImplGlfw_RenderDrawLists(ImDrawData* draw_data) +{ + // Avoid rendering when minimized, scale coordinates for retina displays (screen coordinates != framebuffer coordinates) + ImGuiIO& io = ImGui::GetIO(); + int fb_width = (int)(io.DisplaySize.x * io.DisplayFramebufferScale.x); + int fb_height = (int)(io.DisplaySize.y * io.DisplayFramebufferScale.y); + if (fb_width == 0 || fb_height == 0) + return; + draw_data->ScaleClipRects(io.DisplayFramebufferScale); + + // We are using the OpenGL fixed pipeline to make the example code simpler to read! + // Setup render state: alpha-blending enabled, no face culling, no depth testing, scissor enabled, vertex/texcoord/color pointers. + GLint last_texture; glGetIntegerv(GL_TEXTURE_BINDING_2D, &last_texture); + GLint last_viewport[4]; glGetIntegerv(GL_VIEWPORT, last_viewport); + glPushAttrib(GL_ENABLE_BIT | GL_COLOR_BUFFER_BIT | GL_TRANSFORM_BIT); + glEnable(GL_BLEND); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + glDisable(GL_CULL_FACE); + glDisable(GL_DEPTH_TEST); + glEnable(GL_SCISSOR_TEST); + glEnableClientState(GL_VERTEX_ARRAY); + glEnableClientState(GL_TEXTURE_COORD_ARRAY); + glEnableClientState(GL_COLOR_ARRAY); + glEnable(GL_TEXTURE_2D); + //glUseProgram(0); // You may want this if using this code in an OpenGL 3+ context + + // Setup viewport, orthographic projection matrix + glViewport(0, 0, (GLsizei)fb_width, (GLsizei)fb_height); + glMatrixMode(GL_PROJECTION); + glPushMatrix(); + glLoadIdentity(); + glOrtho(0.0f, io.DisplaySize.x, io.DisplaySize.y, 0.0f, -1.0f, +1.0f); + glMatrixMode(GL_MODELVIEW); + glPushMatrix(); + glLoadIdentity(); + + // Render command lists + #define OFFSETOF(TYPE, ELEMENT) ((size_t)&(((TYPE *)0)->ELEMENT)) + for (int n = 0; n < draw_data->CmdListsCount; n++) + { + const ImDrawList* cmd_list = draw_data->CmdLists[n]; + const unsigned char* vtx_buffer = (const unsigned char*)&cmd_list->VtxBuffer.front(); + const ImDrawIdx* idx_buffer = &cmd_list->IdxBuffer.front(); + glVertexPointer(2, GL_FLOAT, sizeof(ImDrawVert), (void*)(vtx_buffer + OFFSETOF(ImDrawVert, pos))); + glTexCoordPointer(2, GL_FLOAT, sizeof(ImDrawVert), (void*)(vtx_buffer + OFFSETOF(ImDrawVert, uv))); + glColorPointer(4, GL_UNSIGNED_BYTE, sizeof(ImDrawVert), (void*)(vtx_buffer + OFFSETOF(ImDrawVert, col))); + + for (int cmd_i = 0; cmd_i < cmd_list->CmdBuffer.size(); cmd_i++) + { + const ImDrawCmd* pcmd = &cmd_list->CmdBuffer[cmd_i]; + if (pcmd->UserCallback) + { + pcmd->UserCallback(cmd_list, pcmd); + } + else + { + glBindTexture(GL_TEXTURE_2D, (GLuint)(intptr_t)pcmd->TextureId); + glScissor((int)pcmd->ClipRect.x, (int)(fb_height - pcmd->ClipRect.w), (int)(pcmd->ClipRect.z - pcmd->ClipRect.x), (int)(pcmd->ClipRect.w - pcmd->ClipRect.y)); + glDrawElements(GL_TRIANGLES, (GLsizei)pcmd->ElemCount, sizeof(ImDrawIdx) == 2 ? GL_UNSIGNED_SHORT : GL_UNSIGNED_INT, idx_buffer); + } + idx_buffer += pcmd->ElemCount; + } + } + #undef OFFSETOF + + // Restore modified state + glDisableClientState(GL_COLOR_ARRAY); + glDisableClientState(GL_TEXTURE_COORD_ARRAY); + glDisableClientState(GL_VERTEX_ARRAY); + glBindTexture(GL_TEXTURE_2D, (GLuint)last_texture); + glMatrixMode(GL_MODELVIEW); + glPopMatrix(); + glMatrixMode(GL_PROJECTION); + glPopMatrix(); + glPopAttrib(); + glViewport(last_viewport[0], last_viewport[1], (GLsizei)last_viewport[2], (GLsizei)last_viewport[3]); +} + +static const char* ImGui_ImplGlfw_GetClipboardText() +{ + return glfwGetClipboardString(g_Window); +} + +static void ImGui_ImplGlfw_SetClipboardText(const char* text) +{ + glfwSetClipboardString(g_Window, text); +} + +void ImGui_ImplGlfw_MouseButtonCallback(GLFWwindow*, int button, int action, int /*mods*/) +{ + if (action == GLFW_PRESS && button >= 0 && button < 3) + g_MousePressed[button] = true; +} + +void ImGui_ImplGlfw_ScrollCallback(GLFWwindow*, double /*xoffset*/, double yoffset) +{ + g_MouseWheel += (float)yoffset; // Use fractional mouse wheel, 1.0 unit 5 lines. +} + +void ImGui_ImplGlFw_KeyCallback(GLFWwindow*, int key, int, int action, int mods) +{ + ImGuiIO& io = ImGui::GetIO(); + if (action == GLFW_PRESS) + io.KeysDown[key] = true; + if (action == GLFW_RELEASE) + io.KeysDown[key] = false; + + (void)mods; // Modifiers are not reliable across systems + io.KeyCtrl = io.KeysDown[GLFW_KEY_LEFT_CONTROL] || io.KeysDown[GLFW_KEY_RIGHT_CONTROL]; + io.KeyShift = io.KeysDown[GLFW_KEY_LEFT_SHIFT] || io.KeysDown[GLFW_KEY_RIGHT_SHIFT]; + io.KeyAlt = io.KeysDown[GLFW_KEY_LEFT_ALT] || io.KeysDown[GLFW_KEY_RIGHT_ALT]; + io.KeySuper = io.KeysDown[GLFW_KEY_LEFT_SUPER] || io.KeysDown[GLFW_KEY_RIGHT_SUPER]; +} + +void ImGui_ImplGlfw_CharCallback(GLFWwindow*, unsigned int c) +{ + ImGuiIO& io = ImGui::GetIO(); + if (c > 0 && c < 0x10000) + io.AddInputCharacter((unsigned short)c); +} + +bool ImGui_ImplGlfw_CreateDeviceObjects() +{ + // Build texture atlas + ImGuiIO& io = ImGui::GetIO(); + unsigned char* pixels; + int width, height; + io.Fonts->GetTexDataAsAlpha8(&pixels, &width, &height); + + // Upload texture to graphics system + GLint last_texture; + glGetIntegerv(GL_TEXTURE_BINDING_2D, &last_texture); + glGenTextures(1, &g_FontTexture); + glBindTexture(GL_TEXTURE_2D, g_FontTexture); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, width, height, 0, GL_ALPHA, GL_UNSIGNED_BYTE, pixels); + + // Store our identifier + io.Fonts->TexID = (void *)(intptr_t)g_FontTexture; + + // Restore state + glBindTexture(GL_TEXTURE_2D, last_texture); + + return true; +} + +void ImGui_ImplGlfw_InvalidateDeviceObjects() +{ + if (g_FontTexture) + { + glDeleteTextures(1, &g_FontTexture); + ImGui::GetIO().Fonts->TexID = 0; + g_FontTexture = 0; + } +} + +bool ImGui_ImplGlfw_Init(GLFWwindow* window, bool install_callbacks) +{ + g_Window = window; + + ImGuiIO& io = ImGui::GetIO(); + 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; + io.KeyMap[ImGuiKey_DownArrow] = GLFW_KEY_DOWN; + io.KeyMap[ImGuiKey_PageUp] = GLFW_KEY_PAGE_UP; + io.KeyMap[ImGuiKey_PageDown] = GLFW_KEY_PAGE_DOWN; + io.KeyMap[ImGuiKey_Home] = GLFW_KEY_HOME; + io.KeyMap[ImGuiKey_End] = GLFW_KEY_END; + io.KeyMap[ImGuiKey_Delete] = GLFW_KEY_DELETE; + io.KeyMap[ImGuiKey_Backspace] = GLFW_KEY_BACKSPACE; + io.KeyMap[ImGuiKey_Enter] = GLFW_KEY_ENTER; + io.KeyMap[ImGuiKey_Escape] = GLFW_KEY_ESCAPE; + io.KeyMap[ImGuiKey_A] = GLFW_KEY_A; + io.KeyMap[ImGuiKey_C] = GLFW_KEY_C; + io.KeyMap[ImGuiKey_V] = GLFW_KEY_V; + io.KeyMap[ImGuiKey_X] = GLFW_KEY_X; + io.KeyMap[ImGuiKey_Y] = GLFW_KEY_Y; + io.KeyMap[ImGuiKey_Z] = GLFW_KEY_Z; + + io.RenderDrawListsFn = ImGui_ImplGlfw_RenderDrawLists; // Alternatively you can set this to NULL and call ImGui::GetDrawData() after ImGui::Render() to get the same ImDrawData pointer. + io.SetClipboardTextFn = ImGui_ImplGlfw_SetClipboardText; + io.GetClipboardTextFn = ImGui_ImplGlfw_GetClipboardText; +#ifdef _WIN32 + io.ImeWindowHandle = glfwGetWin32Window(g_Window); +#endif + + if (install_callbacks) + { + glfwSetMouseButtonCallback(window, ImGui_ImplGlfw_MouseButtonCallback); + glfwSetScrollCallback(window, ImGui_ImplGlfw_ScrollCallback); + glfwSetKeyCallback(window, ImGui_ImplGlFw_KeyCallback); + glfwSetCharCallback(window, ImGui_ImplGlfw_CharCallback); + } + + return true; +} + +void ImGui_ImplGlfw_Shutdown() +{ + ImGui_ImplGlfw_InvalidateDeviceObjects(); + ImGui::Shutdown(); +} + +void ImGui_ImplGlfw_NewFrame() +{ + if (!g_FontTexture) + ImGui_ImplGlfw_CreateDeviceObjects(); + + ImGuiIO& io = ImGui::GetIO(); + + // Setup display size (every frame to accommodate for window resizing) + int w, h; + int display_w, display_h; + glfwGetWindowSize(g_Window, &w, &h); + glfwGetFramebufferSize(g_Window, &display_w, &display_h); + io.DisplaySize = ImVec2((float)w, (float)h); + io.DisplayFramebufferScale = ImVec2(w > 0 ? ((float)display_w / w) : 0, h > 0 ? ((float)display_h / h) : 0); + + // Setup time step + double current_time = glfwGetTime(); + io.DeltaTime = g_Time > 0.0 ? (float)(current_time - g_Time) : (float)(1.0f/60.0f); + g_Time = current_time; + + // Setup inputs + // (we already got mouse wheel, keyboard keys & characters from glfw callbacks polled in glfwPollEvents()) + if (glfwGetWindowAttrib(g_Window, GLFW_FOCUSED)) + { + double mouse_x, mouse_y; + glfwGetCursorPos(g_Window, &mouse_x, &mouse_y); + io.MousePos = ImVec2((float)mouse_x, (float)mouse_y); // Mouse position in screen coordinates (set to -1,-1 if no mouse / on another screen, etc.) + } + else + { + io.MousePos = ImVec2(-1,-1); + } + + for (int i = 0; i < 3; i++) + { + io.MouseDown[i] = g_MousePressed[i] || glfwGetMouseButton(g_Window, i) != 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. + g_MousePressed[i] = false; + } + + io.MouseWheel = g_MouseWheel; + g_MouseWheel = 0.0f; + + // Hide OS mouse cursor if ImGui is drawing it + glfwSetInputMode(g_Window, GLFW_CURSOR, io.MouseDrawCursor ? GLFW_CURSOR_HIDDEN : GLFW_CURSOR_NORMAL); + + // Start the frame + ImGui::NewFrame(); +} diff --git a/examples/README.txt b/examples/README.txt index df2e86d..5a1c8df 100644 --- a/examples/README.txt +++ b/examples/README.txt @@ -8,11 +8,13 @@ TL;DR; - Newcomers, read 'PROGRAMMER GUIDE' in imgui.cpp for notes on how to setup ImGui in your codebase. - - Refer to 'opengl_example' to understand how the library is setup, it is the simplest one. + - Refer to 'opengl2_example' to LEARN how the library is setup, it is the simplest one. The other examples requires more boilerplate and are harder to read. + - If you are using OpenGL in your application, probably use an opengl3_xxx backend. + Mixing old fixed pipeline OpenGL2 and programmable pipeline OpenGL3+ isn't well supported by drivers. - If you are using of the backend provided here, so you can copy the imgui_impl_xxx.cpp/h files to your project and use them unmodified. - - If you have your own engine, you probably want to start from 'opengl_example' and adapt it to + - If you have your own engine, you probably want to start from one of the OpenGL example and adapt it to your engine, but you can read the other examples as well. ImGui is highly portable and only requires a few things to run: @@ -41,15 +43,14 @@ Also note that some setup or GPU drivers may be causing extra lag (possibly by enforcing triple buffering), leaving you with no option but sadness/anger (Intel GPU drivers were reported as such). -opengl_example/ - OpenGL example, using GLFW + fixed pipeline. - This is simple and should work for all OpenGL enabled applications. - Prefer following this example to learn how ImGui works! - (You can use this code in a GL3/GL4 context but make sure you disable the programmable pipeline - by calling "glUseProgram(0)" before ImGui::Render.) +opengl2_example/ + GLFW + OpenGL example (old fixed pipeline). + This is simple to read. Prefer following this example to learn how ImGui works! + (You might be able to use this code in a GL3/GL4 context but make sure you disable the programmable + pipeline by calling "glUseProgram(0)" before ImGui::Render.) opengl3_example/ - OpenGL example, using GLFW/GL3W + programmable pipeline. + GLFW + OpenGL example (programmable pipeline, binding modern functions with GL3W). This uses more modern OpenGL calls and custom shaders. It's more messy. directx9_example/ @@ -68,8 +69,8 @@ On iOS, Using Synergy to access keyboard/mouse data from server computer. Synergy keyboard integration is rather hacky. -sdl_opengl_example/ - SDL2 + OpenGL example. +sdl_opengl2_example/ + SDL2 + OpenGL example (old fixed pipeline). sdl_opengl3_example/ SDL2 + OpenGL3 example. diff --git a/examples/imgui_examples_msvc2010.sln b/examples/imgui_examples_msvc2010.sln index b7e6a25..16f0d60 100644 --- a/examples/imgui_examples_msvc2010.sln +++ b/examples/imgui_examples_msvc2010.sln @@ -1,7 +1,7 @@  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}" +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "opengl2_example", "opengl_example\opengl2_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 diff --git a/examples/opengl2_example/Makefile b/examples/opengl2_example/Makefile new file mode 100644 index 0000000..bd79d1b --- /dev/null +++ b/examples/opengl2_example/Makefile @@ -0,0 +1,60 @@ +# +# Cross Platform Makefile +# Compatible with Ubuntu 14.04.1 and Mac OS X +# +# +# if you using Mac OS X: +# You'll need glfw +# http://www.glfw.org +# + +#CXX = g++ + +EXE = opengl2_example +OBJS = main.o imgui_impl_glfw.o +OBJS += ../../imgui.o ../../imgui_demo.o ../../imgui_draw.o + +UNAME_S := $(shell uname -s) + + +ifeq ($(UNAME_S), Linux) #LINUX + ECHO_MESSAGE = "Linux" + LIBS = -lGL `pkg-config --static --libs glfw3` + + CXXFLAGS = -I../../ `pkg-config --cflags glfw3` + CXXFLAGS += -Wall -Wformat + CFLAGS = $(CXXFLAGS) +endif + +ifeq ($(UNAME_S), Darwin) #APPLE + ECHO_MESSAGE = "Mac OS X" + LIBS = -framework OpenGL -framework Cocoa -framework IOKit -framework CoreVideo + LIBS += -L/usr/local/lib -lglfw3 + + CXXFLAGS = -I../../ -I/usr/local/include + CXXFLAGS += -Wall -Wformat +# CXXFLAGS += -D__APPLE__ + CFLAGS = $(CXXFLAGS) +endif + +ifeq ($(UNAME_S), MINGW64_NT-6.3) + ECHO_MESSAGE = "Windows" + LIBS = -lglfw3 -lgdi32 -lopengl32 -limm32 + + CXXFLAGS = -I../../ -I../libs/gl3w `pkg-config --cflags glfw3` + CXXFLAGS += -Wall -Wformat + CFLAGS = $(CXXFLAGS) +endif + +.cpp.o: + $(CXX) $(CXXFLAGS) -c -o $@ $< + +all: $(EXE) + @echo Build complete for $(ECHO_MESSAGE) + +$(EXE): $(OBJS) + $(CXX) -o $(EXE) $(OBJS) $(CXXFLAGS) $(LIBS) + +clean: + rm $(EXE) $(OBJS) + diff --git a/examples/opengl2_example/build_win32.bat b/examples/opengl2_example/build_win32.bat new file mode 100644 index 0000000..278381c --- /dev/null +++ b/examples/opengl2_example/build_win32.bat @@ -0,0 +1,3 @@ +@REM Build for Visual Studio compiler. Run your copy of vcvars32.bat or vcvarsall.bat to setup command-line compiler. +mkdir Debug +cl /nologo /Zi /MD /I ..\.. /I ..\libs\glfw\include *.cpp ..\..\*.cpp /FeDebug/opengl_example.exe /FoDebug/ /link /LIBPATH:..\libs\glfw\lib-vc2010-32 glfw3.lib opengl32.lib gdi32.lib shell32.lib diff --git a/examples/opengl2_example/imgui_impl_glfw.cpp b/examples/opengl2_example/imgui_impl_glfw.cpp new file mode 100644 index 0000000..2d1f5c1 --- /dev/null +++ b/examples/opengl2_example/imgui_impl_glfw.cpp @@ -0,0 +1,288 @@ +// ImGui GLFW binding with OpenGL +// In this binding, ImTextureID is used to store an OpenGL 'GLuint' texture identifier. Read the FAQ about ImTextureID in imgui.cpp. + +// If your context is GL3/GL3 then prefer using the code in opengl3_example. +// You *might* use this code with a GL3/GL4 context but make sure you disable the programmable pipeline by calling "glUseProgram(0)" before ImGui::Render(). +// We cannot do that from GL2 code because the function doesn't exist. + +// You can copy and use unmodified imgui_impl_* files in your project. See main.cpp for an example of using this. +// If you use this binding you'll need to call 4 functions: ImGui_ImplXXXX_Init(), ImGui_ImplXXXX_NewFrame(), ImGui::Render() and ImGui_ImplXXXX_Shutdown(). +// If you are new to ImGui, see examples/README.txt and documentation at the top of imgui.cpp. +// https://github.com/ocornut/imgui + +#include +#include "imgui_impl_glfw.h" + +// GLFW +#include +#ifdef _WIN32 +#undef APIENTRY +#define GLFW_EXPOSE_NATIVE_WIN32 +#define GLFW_EXPOSE_NATIVE_WGL +#include +#endif + +// Data +static GLFWwindow* g_Window = NULL; +static double g_Time = 0.0f; +static bool g_MousePressed[3] = { false, false, false }; +static float g_MouseWheel = 0.0f; +static GLuint g_FontTexture = 0; + +// 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) +void ImGui_ImplGlfw_RenderDrawLists(ImDrawData* draw_data) +{ + // Avoid rendering when minimized, scale coordinates for retina displays (screen coordinates != framebuffer coordinates) + ImGuiIO& io = ImGui::GetIO(); + int fb_width = (int)(io.DisplaySize.x * io.DisplayFramebufferScale.x); + int fb_height = (int)(io.DisplaySize.y * io.DisplayFramebufferScale.y); + if (fb_width == 0 || fb_height == 0) + return; + draw_data->ScaleClipRects(io.DisplayFramebufferScale); + + // We are using the OpenGL fixed pipeline to make the example code simpler to read! + // Setup render state: alpha-blending enabled, no face culling, no depth testing, scissor enabled, vertex/texcoord/color pointers. + GLint last_texture; glGetIntegerv(GL_TEXTURE_BINDING_2D, &last_texture); + GLint last_viewport[4]; glGetIntegerv(GL_VIEWPORT, last_viewport); + glPushAttrib(GL_ENABLE_BIT | GL_COLOR_BUFFER_BIT | GL_TRANSFORM_BIT); + glEnable(GL_BLEND); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + glDisable(GL_CULL_FACE); + glDisable(GL_DEPTH_TEST); + glEnable(GL_SCISSOR_TEST); + glEnableClientState(GL_VERTEX_ARRAY); + glEnableClientState(GL_TEXTURE_COORD_ARRAY); + glEnableClientState(GL_COLOR_ARRAY); + glEnable(GL_TEXTURE_2D); + //glUseProgram(0); // You may want this if using this code in an OpenGL 3+ context + + // Setup viewport, orthographic projection matrix + glViewport(0, 0, (GLsizei)fb_width, (GLsizei)fb_height); + glMatrixMode(GL_PROJECTION); + glPushMatrix(); + glLoadIdentity(); + glOrtho(0.0f, io.DisplaySize.x, io.DisplaySize.y, 0.0f, -1.0f, +1.0f); + glMatrixMode(GL_MODELVIEW); + glPushMatrix(); + glLoadIdentity(); + + // Render command lists + #define OFFSETOF(TYPE, ELEMENT) ((size_t)&(((TYPE *)0)->ELEMENT)) + for (int n = 0; n < draw_data->CmdListsCount; n++) + { + const ImDrawList* cmd_list = draw_data->CmdLists[n]; + const unsigned char* vtx_buffer = (const unsigned char*)&cmd_list->VtxBuffer.front(); + const ImDrawIdx* idx_buffer = &cmd_list->IdxBuffer.front(); + glVertexPointer(2, GL_FLOAT, sizeof(ImDrawVert), (void*)(vtx_buffer + OFFSETOF(ImDrawVert, pos))); + glTexCoordPointer(2, GL_FLOAT, sizeof(ImDrawVert), (void*)(vtx_buffer + OFFSETOF(ImDrawVert, uv))); + glColorPointer(4, GL_UNSIGNED_BYTE, sizeof(ImDrawVert), (void*)(vtx_buffer + OFFSETOF(ImDrawVert, col))); + + for (int cmd_i = 0; cmd_i < cmd_list->CmdBuffer.size(); cmd_i++) + { + const ImDrawCmd* pcmd = &cmd_list->CmdBuffer[cmd_i]; + if (pcmd->UserCallback) + { + pcmd->UserCallback(cmd_list, pcmd); + } + else + { + glBindTexture(GL_TEXTURE_2D, (GLuint)(intptr_t)pcmd->TextureId); + glScissor((int)pcmd->ClipRect.x, (int)(fb_height - pcmd->ClipRect.w), (int)(pcmd->ClipRect.z - pcmd->ClipRect.x), (int)(pcmd->ClipRect.w - pcmd->ClipRect.y)); + glDrawElements(GL_TRIANGLES, (GLsizei)pcmd->ElemCount, sizeof(ImDrawIdx) == 2 ? GL_UNSIGNED_SHORT : GL_UNSIGNED_INT, idx_buffer); + } + idx_buffer += pcmd->ElemCount; + } + } + #undef OFFSETOF + + // Restore modified state + glDisableClientState(GL_COLOR_ARRAY); + glDisableClientState(GL_TEXTURE_COORD_ARRAY); + glDisableClientState(GL_VERTEX_ARRAY); + glBindTexture(GL_TEXTURE_2D, (GLuint)last_texture); + glMatrixMode(GL_MODELVIEW); + glPopMatrix(); + glMatrixMode(GL_PROJECTION); + glPopMatrix(); + glPopAttrib(); + glViewport(last_viewport[0], last_viewport[1], (GLsizei)last_viewport[2], (GLsizei)last_viewport[3]); +} + +static const char* ImGui_ImplGlfw_GetClipboardText() +{ + return glfwGetClipboardString(g_Window); +} + +static void ImGui_ImplGlfw_SetClipboardText(const char* text) +{ + glfwSetClipboardString(g_Window, text); +} + +void ImGui_ImplGlfw_MouseButtonCallback(GLFWwindow*, int button, int action, int /*mods*/) +{ + if (action == GLFW_PRESS && button >= 0 && button < 3) + g_MousePressed[button] = true; +} + +void ImGui_ImplGlfw_ScrollCallback(GLFWwindow*, double /*xoffset*/, double yoffset) +{ + g_MouseWheel += (float)yoffset; // Use fractional mouse wheel, 1.0 unit 5 lines. +} + +void ImGui_ImplGlFw_KeyCallback(GLFWwindow*, int key, int, int action, int mods) +{ + ImGuiIO& io = ImGui::GetIO(); + if (action == GLFW_PRESS) + io.KeysDown[key] = true; + if (action == GLFW_RELEASE) + io.KeysDown[key] = false; + + (void)mods; // Modifiers are not reliable across systems + io.KeyCtrl = io.KeysDown[GLFW_KEY_LEFT_CONTROL] || io.KeysDown[GLFW_KEY_RIGHT_CONTROL]; + io.KeyShift = io.KeysDown[GLFW_KEY_LEFT_SHIFT] || io.KeysDown[GLFW_KEY_RIGHT_SHIFT]; + io.KeyAlt = io.KeysDown[GLFW_KEY_LEFT_ALT] || io.KeysDown[GLFW_KEY_RIGHT_ALT]; + io.KeySuper = io.KeysDown[GLFW_KEY_LEFT_SUPER] || io.KeysDown[GLFW_KEY_RIGHT_SUPER]; +} + +void ImGui_ImplGlfw_CharCallback(GLFWwindow*, unsigned int c) +{ + ImGuiIO& io = ImGui::GetIO(); + if (c > 0 && c < 0x10000) + io.AddInputCharacter((unsigned short)c); +} + +bool ImGui_ImplGlfw_CreateDeviceObjects() +{ + // Build texture atlas + ImGuiIO& io = ImGui::GetIO(); + unsigned char* pixels; + int width, height; + io.Fonts->GetTexDataAsAlpha8(&pixels, &width, &height); + + // Upload texture to graphics system + GLint last_texture; + glGetIntegerv(GL_TEXTURE_BINDING_2D, &last_texture); + glGenTextures(1, &g_FontTexture); + glBindTexture(GL_TEXTURE_2D, g_FontTexture); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, width, height, 0, GL_ALPHA, GL_UNSIGNED_BYTE, pixels); + + // Store our identifier + io.Fonts->TexID = (void *)(intptr_t)g_FontTexture; + + // Restore state + glBindTexture(GL_TEXTURE_2D, last_texture); + + return true; +} + +void ImGui_ImplGlfw_InvalidateDeviceObjects() +{ + if (g_FontTexture) + { + glDeleteTextures(1, &g_FontTexture); + ImGui::GetIO().Fonts->TexID = 0; + g_FontTexture = 0; + } +} + +bool ImGui_ImplGlfw_Init(GLFWwindow* window, bool install_callbacks) +{ + g_Window = window; + + ImGuiIO& io = ImGui::GetIO(); + 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; + io.KeyMap[ImGuiKey_DownArrow] = GLFW_KEY_DOWN; + io.KeyMap[ImGuiKey_PageUp] = GLFW_KEY_PAGE_UP; + io.KeyMap[ImGuiKey_PageDown] = GLFW_KEY_PAGE_DOWN; + io.KeyMap[ImGuiKey_Home] = GLFW_KEY_HOME; + io.KeyMap[ImGuiKey_End] = GLFW_KEY_END; + io.KeyMap[ImGuiKey_Delete] = GLFW_KEY_DELETE; + io.KeyMap[ImGuiKey_Backspace] = GLFW_KEY_BACKSPACE; + io.KeyMap[ImGuiKey_Enter] = GLFW_KEY_ENTER; + io.KeyMap[ImGuiKey_Escape] = GLFW_KEY_ESCAPE; + io.KeyMap[ImGuiKey_A] = GLFW_KEY_A; + io.KeyMap[ImGuiKey_C] = GLFW_KEY_C; + io.KeyMap[ImGuiKey_V] = GLFW_KEY_V; + io.KeyMap[ImGuiKey_X] = GLFW_KEY_X; + io.KeyMap[ImGuiKey_Y] = GLFW_KEY_Y; + io.KeyMap[ImGuiKey_Z] = GLFW_KEY_Z; + + io.RenderDrawListsFn = ImGui_ImplGlfw_RenderDrawLists; // Alternatively you can set this to NULL and call ImGui::GetDrawData() after ImGui::Render() to get the same ImDrawData pointer. + io.SetClipboardTextFn = ImGui_ImplGlfw_SetClipboardText; + io.GetClipboardTextFn = ImGui_ImplGlfw_GetClipboardText; +#ifdef _WIN32 + io.ImeWindowHandle = glfwGetWin32Window(g_Window); +#endif + + if (install_callbacks) + { + glfwSetMouseButtonCallback(window, ImGui_ImplGlfw_MouseButtonCallback); + glfwSetScrollCallback(window, ImGui_ImplGlfw_ScrollCallback); + glfwSetKeyCallback(window, ImGui_ImplGlFw_KeyCallback); + glfwSetCharCallback(window, ImGui_ImplGlfw_CharCallback); + } + + return true; +} + +void ImGui_ImplGlfw_Shutdown() +{ + ImGui_ImplGlfw_InvalidateDeviceObjects(); + ImGui::Shutdown(); +} + +void ImGui_ImplGlfw_NewFrame() +{ + if (!g_FontTexture) + ImGui_ImplGlfw_CreateDeviceObjects(); + + ImGuiIO& io = ImGui::GetIO(); + + // Setup display size (every frame to accommodate for window resizing) + int w, h; + int display_w, display_h; + glfwGetWindowSize(g_Window, &w, &h); + glfwGetFramebufferSize(g_Window, &display_w, &display_h); + io.DisplaySize = ImVec2((float)w, (float)h); + io.DisplayFramebufferScale = ImVec2(w > 0 ? ((float)display_w / w) : 0, h > 0 ? ((float)display_h / h) : 0); + + // Setup time step + double current_time = glfwGetTime(); + io.DeltaTime = g_Time > 0.0 ? (float)(current_time - g_Time) : (float)(1.0f/60.0f); + g_Time = current_time; + + // Setup inputs + // (we already got mouse wheel, keyboard keys & characters from glfw callbacks polled in glfwPollEvents()) + if (glfwGetWindowAttrib(g_Window, GLFW_FOCUSED)) + { + double mouse_x, mouse_y; + glfwGetCursorPos(g_Window, &mouse_x, &mouse_y); + io.MousePos = ImVec2((float)mouse_x, (float)mouse_y); // Mouse position in screen coordinates (set to -1,-1 if no mouse / on another screen, etc.) + } + else + { + io.MousePos = ImVec2(-1,-1); + } + + for (int i = 0; i < 3; i++) + { + io.MouseDown[i] = g_MousePressed[i] || glfwGetMouseButton(g_Window, i) != 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. + g_MousePressed[i] = false; + } + + io.MouseWheel = g_MouseWheel; + g_MouseWheel = 0.0f; + + // Hide OS mouse cursor if ImGui is drawing it + glfwSetInputMode(g_Window, GLFW_CURSOR, io.MouseDrawCursor ? GLFW_CURSOR_HIDDEN : GLFW_CURSOR_NORMAL); + + // Start the frame + ImGui::NewFrame(); +} diff --git a/examples/opengl2_example/imgui_impl_glfw.h b/examples/opengl2_example/imgui_impl_glfw.h new file mode 100644 index 0000000..07dd96f --- /dev/null +++ b/examples/opengl2_example/imgui_impl_glfw.h @@ -0,0 +1,29 @@ +// ImGui GLFW binding with OpenGL +// In this binding, ImTextureID is used to store an OpenGL 'GLuint' texture identifier. Read the FAQ about ImTextureID in imgui.cpp. + +// If your context is GL3/GL3 then prefer using the code in opengl3_example. +// You *might* use this code with a GL3/GL4 context but make sure you disable the programmable pipeline by calling "glUseProgram(0)" before ImGui::Render(). +// We cannot do that from GL2 code because the function doesn't exist. + +// You can copy and use unmodified imgui_impl_* files in your project. See main.cpp for an example of using this. +// If you use this binding you'll need to call 4 functions: ImGui_ImplXXXX_Init(), ImGui_ImplXXXX_NewFrame(), ImGui::Render() and ImGui_ImplXXXX_Shutdown(). +// If you are new to ImGui, see examples/README.txt and documentation at the top of imgui.cpp. +// https://github.com/ocornut/imgui + +struct GLFWwindow; + +IMGUI_API bool ImGui_ImplGlfw_Init(GLFWwindow* window, bool install_callbacks); +IMGUI_API void ImGui_ImplGlfw_Shutdown(); +IMGUI_API void ImGui_ImplGlfw_NewFrame(); + +// Use if you want to reset your rendering device without losing ImGui state. +IMGUI_API void ImGui_ImplGlfw_InvalidateDeviceObjects(); +IMGUI_API bool ImGui_ImplGlfw_CreateDeviceObjects(); + +// GLFW callbacks (installed by default if you enable 'install_callbacks' during initialization) +// Provided here if you want to chain callbacks. +// You can also handle inputs yourself and use those as a reference. +IMGUI_API void ImGui_ImplGlfw_MouseButtonCallback(GLFWwindow* window, int button, int action, int mods); +IMGUI_API void ImGui_ImplGlfw_ScrollCallback(GLFWwindow* window, double xoffset, double yoffset); +IMGUI_API void ImGui_ImplGlFw_KeyCallback(GLFWwindow* window, int key, int scancode, int action, int mods); +IMGUI_API void ImGui_ImplGlfw_CharCallback(GLFWwindow* window, unsigned int c); diff --git a/examples/README.txt b/examples/README.txt index df2e86d..5a1c8df 100644 --- a/examples/README.txt +++ b/examples/README.txt @@ -8,11 +8,13 @@ TL;DR; - Newcomers, read 'PROGRAMMER GUIDE' in imgui.cpp for notes on how to setup ImGui in your codebase. - - Refer to 'opengl_example' to understand how the library is setup, it is the simplest one. + - Refer to 'opengl2_example' to LEARN how the library is setup, it is the simplest one. The other examples requires more boilerplate and are harder to read. + - If you are using OpenGL in your application, probably use an opengl3_xxx backend. + Mixing old fixed pipeline OpenGL2 and programmable pipeline OpenGL3+ isn't well supported by drivers. - If you are using of the backend provided here, so you can copy the imgui_impl_xxx.cpp/h files to your project and use them unmodified. - - If you have your own engine, you probably want to start from 'opengl_example' and adapt it to + - If you have your own engine, you probably want to start from one of the OpenGL example and adapt it to your engine, but you can read the other examples as well. ImGui is highly portable and only requires a few things to run: @@ -41,15 +43,14 @@ Also note that some setup or GPU drivers may be causing extra lag (possibly by enforcing triple buffering), leaving you with no option but sadness/anger (Intel GPU drivers were reported as such). -opengl_example/ - OpenGL example, using GLFW + fixed pipeline. - This is simple and should work for all OpenGL enabled applications. - Prefer following this example to learn how ImGui works! - (You can use this code in a GL3/GL4 context but make sure you disable the programmable pipeline - by calling "glUseProgram(0)" before ImGui::Render.) +opengl2_example/ + GLFW + OpenGL example (old fixed pipeline). + This is simple to read. Prefer following this example to learn how ImGui works! + (You might be able to use this code in a GL3/GL4 context but make sure you disable the programmable + pipeline by calling "glUseProgram(0)" before ImGui::Render.) opengl3_example/ - OpenGL example, using GLFW/GL3W + programmable pipeline. + GLFW + OpenGL example (programmable pipeline, binding modern functions with GL3W). This uses more modern OpenGL calls and custom shaders. It's more messy. directx9_example/ @@ -68,8 +69,8 @@ On iOS, Using Synergy to access keyboard/mouse data from server computer. Synergy keyboard integration is rather hacky. -sdl_opengl_example/ - SDL2 + OpenGL example. +sdl_opengl2_example/ + SDL2 + OpenGL example (old fixed pipeline). sdl_opengl3_example/ SDL2 + OpenGL3 example. diff --git a/examples/imgui_examples_msvc2010.sln b/examples/imgui_examples_msvc2010.sln index b7e6a25..16f0d60 100644 --- a/examples/imgui_examples_msvc2010.sln +++ b/examples/imgui_examples_msvc2010.sln @@ -1,7 +1,7 @@  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}" +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "opengl2_example", "opengl_example\opengl2_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 diff --git a/examples/opengl2_example/Makefile b/examples/opengl2_example/Makefile new file mode 100644 index 0000000..bd79d1b --- /dev/null +++ b/examples/opengl2_example/Makefile @@ -0,0 +1,60 @@ +# +# Cross Platform Makefile +# Compatible with Ubuntu 14.04.1 and Mac OS X +# +# +# if you using Mac OS X: +# You'll need glfw +# http://www.glfw.org +# + +#CXX = g++ + +EXE = opengl2_example +OBJS = main.o imgui_impl_glfw.o +OBJS += ../../imgui.o ../../imgui_demo.o ../../imgui_draw.o + +UNAME_S := $(shell uname -s) + + +ifeq ($(UNAME_S), Linux) #LINUX + ECHO_MESSAGE = "Linux" + LIBS = -lGL `pkg-config --static --libs glfw3` + + CXXFLAGS = -I../../ `pkg-config --cflags glfw3` + CXXFLAGS += -Wall -Wformat + CFLAGS = $(CXXFLAGS) +endif + +ifeq ($(UNAME_S), Darwin) #APPLE + ECHO_MESSAGE = "Mac OS X" + LIBS = -framework OpenGL -framework Cocoa -framework IOKit -framework CoreVideo + LIBS += -L/usr/local/lib -lglfw3 + + CXXFLAGS = -I../../ -I/usr/local/include + CXXFLAGS += -Wall -Wformat +# CXXFLAGS += -D__APPLE__ + CFLAGS = $(CXXFLAGS) +endif + +ifeq ($(UNAME_S), MINGW64_NT-6.3) + ECHO_MESSAGE = "Windows" + LIBS = -lglfw3 -lgdi32 -lopengl32 -limm32 + + CXXFLAGS = -I../../ -I../libs/gl3w `pkg-config --cflags glfw3` + CXXFLAGS += -Wall -Wformat + CFLAGS = $(CXXFLAGS) +endif + +.cpp.o: + $(CXX) $(CXXFLAGS) -c -o $@ $< + +all: $(EXE) + @echo Build complete for $(ECHO_MESSAGE) + +$(EXE): $(OBJS) + $(CXX) -o $(EXE) $(OBJS) $(CXXFLAGS) $(LIBS) + +clean: + rm $(EXE) $(OBJS) + diff --git a/examples/opengl2_example/build_win32.bat b/examples/opengl2_example/build_win32.bat new file mode 100644 index 0000000..278381c --- /dev/null +++ b/examples/opengl2_example/build_win32.bat @@ -0,0 +1,3 @@ +@REM Build for Visual Studio compiler. Run your copy of vcvars32.bat or vcvarsall.bat to setup command-line compiler. +mkdir Debug +cl /nologo /Zi /MD /I ..\.. /I ..\libs\glfw\include *.cpp ..\..\*.cpp /FeDebug/opengl_example.exe /FoDebug/ /link /LIBPATH:..\libs\glfw\lib-vc2010-32 glfw3.lib opengl32.lib gdi32.lib shell32.lib diff --git a/examples/opengl2_example/imgui_impl_glfw.cpp b/examples/opengl2_example/imgui_impl_glfw.cpp new file mode 100644 index 0000000..2d1f5c1 --- /dev/null +++ b/examples/opengl2_example/imgui_impl_glfw.cpp @@ -0,0 +1,288 @@ +// ImGui GLFW binding with OpenGL +// In this binding, ImTextureID is used to store an OpenGL 'GLuint' texture identifier. Read the FAQ about ImTextureID in imgui.cpp. + +// If your context is GL3/GL3 then prefer using the code in opengl3_example. +// You *might* use this code with a GL3/GL4 context but make sure you disable the programmable pipeline by calling "glUseProgram(0)" before ImGui::Render(). +// We cannot do that from GL2 code because the function doesn't exist. + +// You can copy and use unmodified imgui_impl_* files in your project. See main.cpp for an example of using this. +// If you use this binding you'll need to call 4 functions: ImGui_ImplXXXX_Init(), ImGui_ImplXXXX_NewFrame(), ImGui::Render() and ImGui_ImplXXXX_Shutdown(). +// If you are new to ImGui, see examples/README.txt and documentation at the top of imgui.cpp. +// https://github.com/ocornut/imgui + +#include +#include "imgui_impl_glfw.h" + +// GLFW +#include +#ifdef _WIN32 +#undef APIENTRY +#define GLFW_EXPOSE_NATIVE_WIN32 +#define GLFW_EXPOSE_NATIVE_WGL +#include +#endif + +// Data +static GLFWwindow* g_Window = NULL; +static double g_Time = 0.0f; +static bool g_MousePressed[3] = { false, false, false }; +static float g_MouseWheel = 0.0f; +static GLuint g_FontTexture = 0; + +// 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) +void ImGui_ImplGlfw_RenderDrawLists(ImDrawData* draw_data) +{ + // Avoid rendering when minimized, scale coordinates for retina displays (screen coordinates != framebuffer coordinates) + ImGuiIO& io = ImGui::GetIO(); + int fb_width = (int)(io.DisplaySize.x * io.DisplayFramebufferScale.x); + int fb_height = (int)(io.DisplaySize.y * io.DisplayFramebufferScale.y); + if (fb_width == 0 || fb_height == 0) + return; + draw_data->ScaleClipRects(io.DisplayFramebufferScale); + + // We are using the OpenGL fixed pipeline to make the example code simpler to read! + // Setup render state: alpha-blending enabled, no face culling, no depth testing, scissor enabled, vertex/texcoord/color pointers. + GLint last_texture; glGetIntegerv(GL_TEXTURE_BINDING_2D, &last_texture); + GLint last_viewport[4]; glGetIntegerv(GL_VIEWPORT, last_viewport); + glPushAttrib(GL_ENABLE_BIT | GL_COLOR_BUFFER_BIT | GL_TRANSFORM_BIT); + glEnable(GL_BLEND); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + glDisable(GL_CULL_FACE); + glDisable(GL_DEPTH_TEST); + glEnable(GL_SCISSOR_TEST); + glEnableClientState(GL_VERTEX_ARRAY); + glEnableClientState(GL_TEXTURE_COORD_ARRAY); + glEnableClientState(GL_COLOR_ARRAY); + glEnable(GL_TEXTURE_2D); + //glUseProgram(0); // You may want this if using this code in an OpenGL 3+ context + + // Setup viewport, orthographic projection matrix + glViewport(0, 0, (GLsizei)fb_width, (GLsizei)fb_height); + glMatrixMode(GL_PROJECTION); + glPushMatrix(); + glLoadIdentity(); + glOrtho(0.0f, io.DisplaySize.x, io.DisplaySize.y, 0.0f, -1.0f, +1.0f); + glMatrixMode(GL_MODELVIEW); + glPushMatrix(); + glLoadIdentity(); + + // Render command lists + #define OFFSETOF(TYPE, ELEMENT) ((size_t)&(((TYPE *)0)->ELEMENT)) + for (int n = 0; n < draw_data->CmdListsCount; n++) + { + const ImDrawList* cmd_list = draw_data->CmdLists[n]; + const unsigned char* vtx_buffer = (const unsigned char*)&cmd_list->VtxBuffer.front(); + const ImDrawIdx* idx_buffer = &cmd_list->IdxBuffer.front(); + glVertexPointer(2, GL_FLOAT, sizeof(ImDrawVert), (void*)(vtx_buffer + OFFSETOF(ImDrawVert, pos))); + glTexCoordPointer(2, GL_FLOAT, sizeof(ImDrawVert), (void*)(vtx_buffer + OFFSETOF(ImDrawVert, uv))); + glColorPointer(4, GL_UNSIGNED_BYTE, sizeof(ImDrawVert), (void*)(vtx_buffer + OFFSETOF(ImDrawVert, col))); + + for (int cmd_i = 0; cmd_i < cmd_list->CmdBuffer.size(); cmd_i++) + { + const ImDrawCmd* pcmd = &cmd_list->CmdBuffer[cmd_i]; + if (pcmd->UserCallback) + { + pcmd->UserCallback(cmd_list, pcmd); + } + else + { + glBindTexture(GL_TEXTURE_2D, (GLuint)(intptr_t)pcmd->TextureId); + glScissor((int)pcmd->ClipRect.x, (int)(fb_height - pcmd->ClipRect.w), (int)(pcmd->ClipRect.z - pcmd->ClipRect.x), (int)(pcmd->ClipRect.w - pcmd->ClipRect.y)); + glDrawElements(GL_TRIANGLES, (GLsizei)pcmd->ElemCount, sizeof(ImDrawIdx) == 2 ? GL_UNSIGNED_SHORT : GL_UNSIGNED_INT, idx_buffer); + } + idx_buffer += pcmd->ElemCount; + } + } + #undef OFFSETOF + + // Restore modified state + glDisableClientState(GL_COLOR_ARRAY); + glDisableClientState(GL_TEXTURE_COORD_ARRAY); + glDisableClientState(GL_VERTEX_ARRAY); + glBindTexture(GL_TEXTURE_2D, (GLuint)last_texture); + glMatrixMode(GL_MODELVIEW); + glPopMatrix(); + glMatrixMode(GL_PROJECTION); + glPopMatrix(); + glPopAttrib(); + glViewport(last_viewport[0], last_viewport[1], (GLsizei)last_viewport[2], (GLsizei)last_viewport[3]); +} + +static const char* ImGui_ImplGlfw_GetClipboardText() +{ + return glfwGetClipboardString(g_Window); +} + +static void ImGui_ImplGlfw_SetClipboardText(const char* text) +{ + glfwSetClipboardString(g_Window, text); +} + +void ImGui_ImplGlfw_MouseButtonCallback(GLFWwindow*, int button, int action, int /*mods*/) +{ + if (action == GLFW_PRESS && button >= 0 && button < 3) + g_MousePressed[button] = true; +} + +void ImGui_ImplGlfw_ScrollCallback(GLFWwindow*, double /*xoffset*/, double yoffset) +{ + g_MouseWheel += (float)yoffset; // Use fractional mouse wheel, 1.0 unit 5 lines. +} + +void ImGui_ImplGlFw_KeyCallback(GLFWwindow*, int key, int, int action, int mods) +{ + ImGuiIO& io = ImGui::GetIO(); + if (action == GLFW_PRESS) + io.KeysDown[key] = true; + if (action == GLFW_RELEASE) + io.KeysDown[key] = false; + + (void)mods; // Modifiers are not reliable across systems + io.KeyCtrl = io.KeysDown[GLFW_KEY_LEFT_CONTROL] || io.KeysDown[GLFW_KEY_RIGHT_CONTROL]; + io.KeyShift = io.KeysDown[GLFW_KEY_LEFT_SHIFT] || io.KeysDown[GLFW_KEY_RIGHT_SHIFT]; + io.KeyAlt = io.KeysDown[GLFW_KEY_LEFT_ALT] || io.KeysDown[GLFW_KEY_RIGHT_ALT]; + io.KeySuper = io.KeysDown[GLFW_KEY_LEFT_SUPER] || io.KeysDown[GLFW_KEY_RIGHT_SUPER]; +} + +void ImGui_ImplGlfw_CharCallback(GLFWwindow*, unsigned int c) +{ + ImGuiIO& io = ImGui::GetIO(); + if (c > 0 && c < 0x10000) + io.AddInputCharacter((unsigned short)c); +} + +bool ImGui_ImplGlfw_CreateDeviceObjects() +{ + // Build texture atlas + ImGuiIO& io = ImGui::GetIO(); + unsigned char* pixels; + int width, height; + io.Fonts->GetTexDataAsAlpha8(&pixels, &width, &height); + + // Upload texture to graphics system + GLint last_texture; + glGetIntegerv(GL_TEXTURE_BINDING_2D, &last_texture); + glGenTextures(1, &g_FontTexture); + glBindTexture(GL_TEXTURE_2D, g_FontTexture); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, width, height, 0, GL_ALPHA, GL_UNSIGNED_BYTE, pixels); + + // Store our identifier + io.Fonts->TexID = (void *)(intptr_t)g_FontTexture; + + // Restore state + glBindTexture(GL_TEXTURE_2D, last_texture); + + return true; +} + +void ImGui_ImplGlfw_InvalidateDeviceObjects() +{ + if (g_FontTexture) + { + glDeleteTextures(1, &g_FontTexture); + ImGui::GetIO().Fonts->TexID = 0; + g_FontTexture = 0; + } +} + +bool ImGui_ImplGlfw_Init(GLFWwindow* window, bool install_callbacks) +{ + g_Window = window; + + ImGuiIO& io = ImGui::GetIO(); + 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; + io.KeyMap[ImGuiKey_DownArrow] = GLFW_KEY_DOWN; + io.KeyMap[ImGuiKey_PageUp] = GLFW_KEY_PAGE_UP; + io.KeyMap[ImGuiKey_PageDown] = GLFW_KEY_PAGE_DOWN; + io.KeyMap[ImGuiKey_Home] = GLFW_KEY_HOME; + io.KeyMap[ImGuiKey_End] = GLFW_KEY_END; + io.KeyMap[ImGuiKey_Delete] = GLFW_KEY_DELETE; + io.KeyMap[ImGuiKey_Backspace] = GLFW_KEY_BACKSPACE; + io.KeyMap[ImGuiKey_Enter] = GLFW_KEY_ENTER; + io.KeyMap[ImGuiKey_Escape] = GLFW_KEY_ESCAPE; + io.KeyMap[ImGuiKey_A] = GLFW_KEY_A; + io.KeyMap[ImGuiKey_C] = GLFW_KEY_C; + io.KeyMap[ImGuiKey_V] = GLFW_KEY_V; + io.KeyMap[ImGuiKey_X] = GLFW_KEY_X; + io.KeyMap[ImGuiKey_Y] = GLFW_KEY_Y; + io.KeyMap[ImGuiKey_Z] = GLFW_KEY_Z; + + io.RenderDrawListsFn = ImGui_ImplGlfw_RenderDrawLists; // Alternatively you can set this to NULL and call ImGui::GetDrawData() after ImGui::Render() to get the same ImDrawData pointer. + io.SetClipboardTextFn = ImGui_ImplGlfw_SetClipboardText; + io.GetClipboardTextFn = ImGui_ImplGlfw_GetClipboardText; +#ifdef _WIN32 + io.ImeWindowHandle = glfwGetWin32Window(g_Window); +#endif + + if (install_callbacks) + { + glfwSetMouseButtonCallback(window, ImGui_ImplGlfw_MouseButtonCallback); + glfwSetScrollCallback(window, ImGui_ImplGlfw_ScrollCallback); + glfwSetKeyCallback(window, ImGui_ImplGlFw_KeyCallback); + glfwSetCharCallback(window, ImGui_ImplGlfw_CharCallback); + } + + return true; +} + +void ImGui_ImplGlfw_Shutdown() +{ + ImGui_ImplGlfw_InvalidateDeviceObjects(); + ImGui::Shutdown(); +} + +void ImGui_ImplGlfw_NewFrame() +{ + if (!g_FontTexture) + ImGui_ImplGlfw_CreateDeviceObjects(); + + ImGuiIO& io = ImGui::GetIO(); + + // Setup display size (every frame to accommodate for window resizing) + int w, h; + int display_w, display_h; + glfwGetWindowSize(g_Window, &w, &h); + glfwGetFramebufferSize(g_Window, &display_w, &display_h); + io.DisplaySize = ImVec2((float)w, (float)h); + io.DisplayFramebufferScale = ImVec2(w > 0 ? ((float)display_w / w) : 0, h > 0 ? ((float)display_h / h) : 0); + + // Setup time step + double current_time = glfwGetTime(); + io.DeltaTime = g_Time > 0.0 ? (float)(current_time - g_Time) : (float)(1.0f/60.0f); + g_Time = current_time; + + // Setup inputs + // (we already got mouse wheel, keyboard keys & characters from glfw callbacks polled in glfwPollEvents()) + if (glfwGetWindowAttrib(g_Window, GLFW_FOCUSED)) + { + double mouse_x, mouse_y; + glfwGetCursorPos(g_Window, &mouse_x, &mouse_y); + io.MousePos = ImVec2((float)mouse_x, (float)mouse_y); // Mouse position in screen coordinates (set to -1,-1 if no mouse / on another screen, etc.) + } + else + { + io.MousePos = ImVec2(-1,-1); + } + + for (int i = 0; i < 3; i++) + { + io.MouseDown[i] = g_MousePressed[i] || glfwGetMouseButton(g_Window, i) != 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. + g_MousePressed[i] = false; + } + + io.MouseWheel = g_MouseWheel; + g_MouseWheel = 0.0f; + + // Hide OS mouse cursor if ImGui is drawing it + glfwSetInputMode(g_Window, GLFW_CURSOR, io.MouseDrawCursor ? GLFW_CURSOR_HIDDEN : GLFW_CURSOR_NORMAL); + + // Start the frame + ImGui::NewFrame(); +} diff --git a/examples/opengl2_example/imgui_impl_glfw.h b/examples/opengl2_example/imgui_impl_glfw.h new file mode 100644 index 0000000..07dd96f --- /dev/null +++ b/examples/opengl2_example/imgui_impl_glfw.h @@ -0,0 +1,29 @@ +// ImGui GLFW binding with OpenGL +// In this binding, ImTextureID is used to store an OpenGL 'GLuint' texture identifier. Read the FAQ about ImTextureID in imgui.cpp. + +// If your context is GL3/GL3 then prefer using the code in opengl3_example. +// You *might* use this code with a GL3/GL4 context but make sure you disable the programmable pipeline by calling "glUseProgram(0)" before ImGui::Render(). +// We cannot do that from GL2 code because the function doesn't exist. + +// You can copy and use unmodified imgui_impl_* files in your project. See main.cpp for an example of using this. +// If you use this binding you'll need to call 4 functions: ImGui_ImplXXXX_Init(), ImGui_ImplXXXX_NewFrame(), ImGui::Render() and ImGui_ImplXXXX_Shutdown(). +// If you are new to ImGui, see examples/README.txt and documentation at the top of imgui.cpp. +// https://github.com/ocornut/imgui + +struct GLFWwindow; + +IMGUI_API bool ImGui_ImplGlfw_Init(GLFWwindow* window, bool install_callbacks); +IMGUI_API void ImGui_ImplGlfw_Shutdown(); +IMGUI_API void ImGui_ImplGlfw_NewFrame(); + +// Use if you want to reset your rendering device without losing ImGui state. +IMGUI_API void ImGui_ImplGlfw_InvalidateDeviceObjects(); +IMGUI_API bool ImGui_ImplGlfw_CreateDeviceObjects(); + +// GLFW callbacks (installed by default if you enable 'install_callbacks' during initialization) +// Provided here if you want to chain callbacks. +// You can also handle inputs yourself and use those as a reference. +IMGUI_API void ImGui_ImplGlfw_MouseButtonCallback(GLFWwindow* window, int button, int action, int mods); +IMGUI_API void ImGui_ImplGlfw_ScrollCallback(GLFWwindow* window, double xoffset, double yoffset); +IMGUI_API void ImGui_ImplGlFw_KeyCallback(GLFWwindow* window, int key, int scancode, int action, int mods); +IMGUI_API void ImGui_ImplGlfw_CharCallback(GLFWwindow* window, unsigned int c); diff --git a/examples/opengl2_example/main.cpp b/examples/opengl2_example/main.cpp new file mode 100644 index 0000000..a844db5 --- /dev/null +++ b/examples/opengl2_example/main.cpp @@ -0,0 +1,89 @@ +// ImGui - standalone example application for Glfw + OpenGL 2, using fixed pipeline +// If you are new to ImGui, see examples/README.txt and documentation at the top of imgui.cpp. + +#include +#include "imgui_impl_glfw.h" +#include +#include + +static void error_callback(int error, const char* description) +{ + fprintf(stderr, "Error %d: %s\n", error, description); +} + +int main(int, char**) +{ + // Setup window + glfwSetErrorCallback(error_callback); + if (!glfwInit()) + return 1; + GLFWwindow* window = glfwCreateWindow(1280, 720, "ImGui OpenGL2 example", NULL, NULL); + glfwMakeContextCurrent(window); + + // Setup ImGui binding + ImGui_ImplGlfw_Init(window, true); + + // Load Fonts + // (there is a default font, this is only if you want to change it. see extra_fonts/README.txt for more details) + //ImGuiIO& io = ImGui::GetIO(); + //io.Fonts->AddFontDefault(); + //io.Fonts->AddFontFromFileTTF("../../extra_fonts/Cousine-Regular.ttf", 15.0f); + //io.Fonts->AddFontFromFileTTF("../../extra_fonts/DroidSans.ttf", 16.0f); + //io.Fonts->AddFontFromFileTTF("../../extra_fonts/ProggyClean.ttf", 13.0f); + //io.Fonts->AddFontFromFileTTF("../../extra_fonts/ProggyTiny.ttf", 10.0f); + //io.Fonts->AddFontFromFileTTF("c:\\Windows\\Fonts\\ArialUni.ttf", 18.0f, NULL, io.Fonts->GetGlyphRangesJapanese()); + + bool show_test_window = true; + bool show_another_window = false; + ImVec4 clear_color = ImColor(114, 144, 154); + + // Main loop + while (!glfwWindowShouldClose(window)) + { + glfwPollEvents(); + ImGui_ImplGlfw_NewFrame(); + + // 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 = 0.0f; + ImGui::Text("Hello, world!"); + ImGui::SliderFloat("float", &f, 0.0f, 1.0f); + ImGui::ColorEdit3("clear color", (float*)&clear_color); + if (ImGui::Button("Test Window")) show_test_window ^= 1; + if (ImGui::Button("Another Window")) show_another_window ^= 1; + ImGui::Text("Application average %.3f ms/frame (%.1f FPS)", 1000.0f / ImGui::GetIO().Framerate, ImGui::GetIO().Framerate); + } + + // 2. Show another simple window, this time using an explicit Begin/End pair + if (show_another_window) + { + ImGui::SetNextWindowSize(ImVec2(200,100), ImGuiSetCond_FirstUseEver); + ImGui::Begin("Another Window", &show_another_window); + 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::SetNextWindowPos(ImVec2(650, 20), ImGuiSetCond_FirstUseEver); + ImGui::ShowTestWindow(&show_test_window); + } + + // Rendering + int display_w, display_h; + glfwGetFramebufferSize(window, &display_w, &display_h); + glViewport(0, 0, display_w, display_h); + glClearColor(clear_color.x, clear_color.y, clear_color.z, clear_color.w); + glClear(GL_COLOR_BUFFER_BIT); + ImGui::Render(); + glfwSwapBuffers(window); + } + + // Cleanup + ImGui_ImplGlfw_Shutdown(); + glfwTerminate(); + + return 0; +} diff --git a/examples/README.txt b/examples/README.txt index df2e86d..5a1c8df 100644 --- a/examples/README.txt +++ b/examples/README.txt @@ -8,11 +8,13 @@ TL;DR; - Newcomers, read 'PROGRAMMER GUIDE' in imgui.cpp for notes on how to setup ImGui in your codebase. - - Refer to 'opengl_example' to understand how the library is setup, it is the simplest one. + - Refer to 'opengl2_example' to LEARN how the library is setup, it is the simplest one. The other examples requires more boilerplate and are harder to read. + - If you are using OpenGL in your application, probably use an opengl3_xxx backend. + Mixing old fixed pipeline OpenGL2 and programmable pipeline OpenGL3+ isn't well supported by drivers. - If you are using of the backend provided here, so you can copy the imgui_impl_xxx.cpp/h files to your project and use them unmodified. - - If you have your own engine, you probably want to start from 'opengl_example' and adapt it to + - If you have your own engine, you probably want to start from one of the OpenGL example and adapt it to your engine, but you can read the other examples as well. ImGui is highly portable and only requires a few things to run: @@ -41,15 +43,14 @@ Also note that some setup or GPU drivers may be causing extra lag (possibly by enforcing triple buffering), leaving you with no option but sadness/anger (Intel GPU drivers were reported as such). -opengl_example/ - OpenGL example, using GLFW + fixed pipeline. - This is simple and should work for all OpenGL enabled applications. - Prefer following this example to learn how ImGui works! - (You can use this code in a GL3/GL4 context but make sure you disable the programmable pipeline - by calling "glUseProgram(0)" before ImGui::Render.) +opengl2_example/ + GLFW + OpenGL example (old fixed pipeline). + This is simple to read. Prefer following this example to learn how ImGui works! + (You might be able to use this code in a GL3/GL4 context but make sure you disable the programmable + pipeline by calling "glUseProgram(0)" before ImGui::Render.) opengl3_example/ - OpenGL example, using GLFW/GL3W + programmable pipeline. + GLFW + OpenGL example (programmable pipeline, binding modern functions with GL3W). This uses more modern OpenGL calls and custom shaders. It's more messy. directx9_example/ @@ -68,8 +69,8 @@ On iOS, Using Synergy to access keyboard/mouse data from server computer. Synergy keyboard integration is rather hacky. -sdl_opengl_example/ - SDL2 + OpenGL example. +sdl_opengl2_example/ + SDL2 + OpenGL example (old fixed pipeline). sdl_opengl3_example/ SDL2 + OpenGL3 example. diff --git a/examples/imgui_examples_msvc2010.sln b/examples/imgui_examples_msvc2010.sln index b7e6a25..16f0d60 100644 --- a/examples/imgui_examples_msvc2010.sln +++ b/examples/imgui_examples_msvc2010.sln @@ -1,7 +1,7 @@  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}" +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "opengl2_example", "opengl_example\opengl2_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 diff --git a/examples/opengl2_example/Makefile b/examples/opengl2_example/Makefile new file mode 100644 index 0000000..bd79d1b --- /dev/null +++ b/examples/opengl2_example/Makefile @@ -0,0 +1,60 @@ +# +# Cross Platform Makefile +# Compatible with Ubuntu 14.04.1 and Mac OS X +# +# +# if you using Mac OS X: +# You'll need glfw +# http://www.glfw.org +# + +#CXX = g++ + +EXE = opengl2_example +OBJS = main.o imgui_impl_glfw.o +OBJS += ../../imgui.o ../../imgui_demo.o ../../imgui_draw.o + +UNAME_S := $(shell uname -s) + + +ifeq ($(UNAME_S), Linux) #LINUX + ECHO_MESSAGE = "Linux" + LIBS = -lGL `pkg-config --static --libs glfw3` + + CXXFLAGS = -I../../ `pkg-config --cflags glfw3` + CXXFLAGS += -Wall -Wformat + CFLAGS = $(CXXFLAGS) +endif + +ifeq ($(UNAME_S), Darwin) #APPLE + ECHO_MESSAGE = "Mac OS X" + LIBS = -framework OpenGL -framework Cocoa -framework IOKit -framework CoreVideo + LIBS += -L/usr/local/lib -lglfw3 + + CXXFLAGS = -I../../ -I/usr/local/include + CXXFLAGS += -Wall -Wformat +# CXXFLAGS += -D__APPLE__ + CFLAGS = $(CXXFLAGS) +endif + +ifeq ($(UNAME_S), MINGW64_NT-6.3) + ECHO_MESSAGE = "Windows" + LIBS = -lglfw3 -lgdi32 -lopengl32 -limm32 + + CXXFLAGS = -I../../ -I../libs/gl3w `pkg-config --cflags glfw3` + CXXFLAGS += -Wall -Wformat + CFLAGS = $(CXXFLAGS) +endif + +.cpp.o: + $(CXX) $(CXXFLAGS) -c -o $@ $< + +all: $(EXE) + @echo Build complete for $(ECHO_MESSAGE) + +$(EXE): $(OBJS) + $(CXX) -o $(EXE) $(OBJS) $(CXXFLAGS) $(LIBS) + +clean: + rm $(EXE) $(OBJS) + diff --git a/examples/opengl2_example/build_win32.bat b/examples/opengl2_example/build_win32.bat new file mode 100644 index 0000000..278381c --- /dev/null +++ b/examples/opengl2_example/build_win32.bat @@ -0,0 +1,3 @@ +@REM Build for Visual Studio compiler. Run your copy of vcvars32.bat or vcvarsall.bat to setup command-line compiler. +mkdir Debug +cl /nologo /Zi /MD /I ..\.. /I ..\libs\glfw\include *.cpp ..\..\*.cpp /FeDebug/opengl_example.exe /FoDebug/ /link /LIBPATH:..\libs\glfw\lib-vc2010-32 glfw3.lib opengl32.lib gdi32.lib shell32.lib diff --git a/examples/opengl2_example/imgui_impl_glfw.cpp b/examples/opengl2_example/imgui_impl_glfw.cpp new file mode 100644 index 0000000..2d1f5c1 --- /dev/null +++ b/examples/opengl2_example/imgui_impl_glfw.cpp @@ -0,0 +1,288 @@ +// ImGui GLFW binding with OpenGL +// In this binding, ImTextureID is used to store an OpenGL 'GLuint' texture identifier. Read the FAQ about ImTextureID in imgui.cpp. + +// If your context is GL3/GL3 then prefer using the code in opengl3_example. +// You *might* use this code with a GL3/GL4 context but make sure you disable the programmable pipeline by calling "glUseProgram(0)" before ImGui::Render(). +// We cannot do that from GL2 code because the function doesn't exist. + +// You can copy and use unmodified imgui_impl_* files in your project. See main.cpp for an example of using this. +// If you use this binding you'll need to call 4 functions: ImGui_ImplXXXX_Init(), ImGui_ImplXXXX_NewFrame(), ImGui::Render() and ImGui_ImplXXXX_Shutdown(). +// If you are new to ImGui, see examples/README.txt and documentation at the top of imgui.cpp. +// https://github.com/ocornut/imgui + +#include +#include "imgui_impl_glfw.h" + +// GLFW +#include +#ifdef _WIN32 +#undef APIENTRY +#define GLFW_EXPOSE_NATIVE_WIN32 +#define GLFW_EXPOSE_NATIVE_WGL +#include +#endif + +// Data +static GLFWwindow* g_Window = NULL; +static double g_Time = 0.0f; +static bool g_MousePressed[3] = { false, false, false }; +static float g_MouseWheel = 0.0f; +static GLuint g_FontTexture = 0; + +// 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) +void ImGui_ImplGlfw_RenderDrawLists(ImDrawData* draw_data) +{ + // Avoid rendering when minimized, scale coordinates for retina displays (screen coordinates != framebuffer coordinates) + ImGuiIO& io = ImGui::GetIO(); + int fb_width = (int)(io.DisplaySize.x * io.DisplayFramebufferScale.x); + int fb_height = (int)(io.DisplaySize.y * io.DisplayFramebufferScale.y); + if (fb_width == 0 || fb_height == 0) + return; + draw_data->ScaleClipRects(io.DisplayFramebufferScale); + + // We are using the OpenGL fixed pipeline to make the example code simpler to read! + // Setup render state: alpha-blending enabled, no face culling, no depth testing, scissor enabled, vertex/texcoord/color pointers. + GLint last_texture; glGetIntegerv(GL_TEXTURE_BINDING_2D, &last_texture); + GLint last_viewport[4]; glGetIntegerv(GL_VIEWPORT, last_viewport); + glPushAttrib(GL_ENABLE_BIT | GL_COLOR_BUFFER_BIT | GL_TRANSFORM_BIT); + glEnable(GL_BLEND); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + glDisable(GL_CULL_FACE); + glDisable(GL_DEPTH_TEST); + glEnable(GL_SCISSOR_TEST); + glEnableClientState(GL_VERTEX_ARRAY); + glEnableClientState(GL_TEXTURE_COORD_ARRAY); + glEnableClientState(GL_COLOR_ARRAY); + glEnable(GL_TEXTURE_2D); + //glUseProgram(0); // You may want this if using this code in an OpenGL 3+ context + + // Setup viewport, orthographic projection matrix + glViewport(0, 0, (GLsizei)fb_width, (GLsizei)fb_height); + glMatrixMode(GL_PROJECTION); + glPushMatrix(); + glLoadIdentity(); + glOrtho(0.0f, io.DisplaySize.x, io.DisplaySize.y, 0.0f, -1.0f, +1.0f); + glMatrixMode(GL_MODELVIEW); + glPushMatrix(); + glLoadIdentity(); + + // Render command lists + #define OFFSETOF(TYPE, ELEMENT) ((size_t)&(((TYPE *)0)->ELEMENT)) + for (int n = 0; n < draw_data->CmdListsCount; n++) + { + const ImDrawList* cmd_list = draw_data->CmdLists[n]; + const unsigned char* vtx_buffer = (const unsigned char*)&cmd_list->VtxBuffer.front(); + const ImDrawIdx* idx_buffer = &cmd_list->IdxBuffer.front(); + glVertexPointer(2, GL_FLOAT, sizeof(ImDrawVert), (void*)(vtx_buffer + OFFSETOF(ImDrawVert, pos))); + glTexCoordPointer(2, GL_FLOAT, sizeof(ImDrawVert), (void*)(vtx_buffer + OFFSETOF(ImDrawVert, uv))); + glColorPointer(4, GL_UNSIGNED_BYTE, sizeof(ImDrawVert), (void*)(vtx_buffer + OFFSETOF(ImDrawVert, col))); + + for (int cmd_i = 0; cmd_i < cmd_list->CmdBuffer.size(); cmd_i++) + { + const ImDrawCmd* pcmd = &cmd_list->CmdBuffer[cmd_i]; + if (pcmd->UserCallback) + { + pcmd->UserCallback(cmd_list, pcmd); + } + else + { + glBindTexture(GL_TEXTURE_2D, (GLuint)(intptr_t)pcmd->TextureId); + glScissor((int)pcmd->ClipRect.x, (int)(fb_height - pcmd->ClipRect.w), (int)(pcmd->ClipRect.z - pcmd->ClipRect.x), (int)(pcmd->ClipRect.w - pcmd->ClipRect.y)); + glDrawElements(GL_TRIANGLES, (GLsizei)pcmd->ElemCount, sizeof(ImDrawIdx) == 2 ? GL_UNSIGNED_SHORT : GL_UNSIGNED_INT, idx_buffer); + } + idx_buffer += pcmd->ElemCount; + } + } + #undef OFFSETOF + + // Restore modified state + glDisableClientState(GL_COLOR_ARRAY); + glDisableClientState(GL_TEXTURE_COORD_ARRAY); + glDisableClientState(GL_VERTEX_ARRAY); + glBindTexture(GL_TEXTURE_2D, (GLuint)last_texture); + glMatrixMode(GL_MODELVIEW); + glPopMatrix(); + glMatrixMode(GL_PROJECTION); + glPopMatrix(); + glPopAttrib(); + glViewport(last_viewport[0], last_viewport[1], (GLsizei)last_viewport[2], (GLsizei)last_viewport[3]); +} + +static const char* ImGui_ImplGlfw_GetClipboardText() +{ + return glfwGetClipboardString(g_Window); +} + +static void ImGui_ImplGlfw_SetClipboardText(const char* text) +{ + glfwSetClipboardString(g_Window, text); +} + +void ImGui_ImplGlfw_MouseButtonCallback(GLFWwindow*, int button, int action, int /*mods*/) +{ + if (action == GLFW_PRESS && button >= 0 && button < 3) + g_MousePressed[button] = true; +} + +void ImGui_ImplGlfw_ScrollCallback(GLFWwindow*, double /*xoffset*/, double yoffset) +{ + g_MouseWheel += (float)yoffset; // Use fractional mouse wheel, 1.0 unit 5 lines. +} + +void ImGui_ImplGlFw_KeyCallback(GLFWwindow*, int key, int, int action, int mods) +{ + ImGuiIO& io = ImGui::GetIO(); + if (action == GLFW_PRESS) + io.KeysDown[key] = true; + if (action == GLFW_RELEASE) + io.KeysDown[key] = false; + + (void)mods; // Modifiers are not reliable across systems + io.KeyCtrl = io.KeysDown[GLFW_KEY_LEFT_CONTROL] || io.KeysDown[GLFW_KEY_RIGHT_CONTROL]; + io.KeyShift = io.KeysDown[GLFW_KEY_LEFT_SHIFT] || io.KeysDown[GLFW_KEY_RIGHT_SHIFT]; + io.KeyAlt = io.KeysDown[GLFW_KEY_LEFT_ALT] || io.KeysDown[GLFW_KEY_RIGHT_ALT]; + io.KeySuper = io.KeysDown[GLFW_KEY_LEFT_SUPER] || io.KeysDown[GLFW_KEY_RIGHT_SUPER]; +} + +void ImGui_ImplGlfw_CharCallback(GLFWwindow*, unsigned int c) +{ + ImGuiIO& io = ImGui::GetIO(); + if (c > 0 && c < 0x10000) + io.AddInputCharacter((unsigned short)c); +} + +bool ImGui_ImplGlfw_CreateDeviceObjects() +{ + // Build texture atlas + ImGuiIO& io = ImGui::GetIO(); + unsigned char* pixels; + int width, height; + io.Fonts->GetTexDataAsAlpha8(&pixels, &width, &height); + + // Upload texture to graphics system + GLint last_texture; + glGetIntegerv(GL_TEXTURE_BINDING_2D, &last_texture); + glGenTextures(1, &g_FontTexture); + glBindTexture(GL_TEXTURE_2D, g_FontTexture); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, width, height, 0, GL_ALPHA, GL_UNSIGNED_BYTE, pixels); + + // Store our identifier + io.Fonts->TexID = (void *)(intptr_t)g_FontTexture; + + // Restore state + glBindTexture(GL_TEXTURE_2D, last_texture); + + return true; +} + +void ImGui_ImplGlfw_InvalidateDeviceObjects() +{ + if (g_FontTexture) + { + glDeleteTextures(1, &g_FontTexture); + ImGui::GetIO().Fonts->TexID = 0; + g_FontTexture = 0; + } +} + +bool ImGui_ImplGlfw_Init(GLFWwindow* window, bool install_callbacks) +{ + g_Window = window; + + ImGuiIO& io = ImGui::GetIO(); + 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; + io.KeyMap[ImGuiKey_DownArrow] = GLFW_KEY_DOWN; + io.KeyMap[ImGuiKey_PageUp] = GLFW_KEY_PAGE_UP; + io.KeyMap[ImGuiKey_PageDown] = GLFW_KEY_PAGE_DOWN; + io.KeyMap[ImGuiKey_Home] = GLFW_KEY_HOME; + io.KeyMap[ImGuiKey_End] = GLFW_KEY_END; + io.KeyMap[ImGuiKey_Delete] = GLFW_KEY_DELETE; + io.KeyMap[ImGuiKey_Backspace] = GLFW_KEY_BACKSPACE; + io.KeyMap[ImGuiKey_Enter] = GLFW_KEY_ENTER; + io.KeyMap[ImGuiKey_Escape] = GLFW_KEY_ESCAPE; + io.KeyMap[ImGuiKey_A] = GLFW_KEY_A; + io.KeyMap[ImGuiKey_C] = GLFW_KEY_C; + io.KeyMap[ImGuiKey_V] = GLFW_KEY_V; + io.KeyMap[ImGuiKey_X] = GLFW_KEY_X; + io.KeyMap[ImGuiKey_Y] = GLFW_KEY_Y; + io.KeyMap[ImGuiKey_Z] = GLFW_KEY_Z; + + io.RenderDrawListsFn = ImGui_ImplGlfw_RenderDrawLists; // Alternatively you can set this to NULL and call ImGui::GetDrawData() after ImGui::Render() to get the same ImDrawData pointer. + io.SetClipboardTextFn = ImGui_ImplGlfw_SetClipboardText; + io.GetClipboardTextFn = ImGui_ImplGlfw_GetClipboardText; +#ifdef _WIN32 + io.ImeWindowHandle = glfwGetWin32Window(g_Window); +#endif + + if (install_callbacks) + { + glfwSetMouseButtonCallback(window, ImGui_ImplGlfw_MouseButtonCallback); + glfwSetScrollCallback(window, ImGui_ImplGlfw_ScrollCallback); + glfwSetKeyCallback(window, ImGui_ImplGlFw_KeyCallback); + glfwSetCharCallback(window, ImGui_ImplGlfw_CharCallback); + } + + return true; +} + +void ImGui_ImplGlfw_Shutdown() +{ + ImGui_ImplGlfw_InvalidateDeviceObjects(); + ImGui::Shutdown(); +} + +void ImGui_ImplGlfw_NewFrame() +{ + if (!g_FontTexture) + ImGui_ImplGlfw_CreateDeviceObjects(); + + ImGuiIO& io = ImGui::GetIO(); + + // Setup display size (every frame to accommodate for window resizing) + int w, h; + int display_w, display_h; + glfwGetWindowSize(g_Window, &w, &h); + glfwGetFramebufferSize(g_Window, &display_w, &display_h); + io.DisplaySize = ImVec2((float)w, (float)h); + io.DisplayFramebufferScale = ImVec2(w > 0 ? ((float)display_w / w) : 0, h > 0 ? ((float)display_h / h) : 0); + + // Setup time step + double current_time = glfwGetTime(); + io.DeltaTime = g_Time > 0.0 ? (float)(current_time - g_Time) : (float)(1.0f/60.0f); + g_Time = current_time; + + // Setup inputs + // (we already got mouse wheel, keyboard keys & characters from glfw callbacks polled in glfwPollEvents()) + if (glfwGetWindowAttrib(g_Window, GLFW_FOCUSED)) + { + double mouse_x, mouse_y; + glfwGetCursorPos(g_Window, &mouse_x, &mouse_y); + io.MousePos = ImVec2((float)mouse_x, (float)mouse_y); // Mouse position in screen coordinates (set to -1,-1 if no mouse / on another screen, etc.) + } + else + { + io.MousePos = ImVec2(-1,-1); + } + + for (int i = 0; i < 3; i++) + { + io.MouseDown[i] = g_MousePressed[i] || glfwGetMouseButton(g_Window, i) != 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. + g_MousePressed[i] = false; + } + + io.MouseWheel = g_MouseWheel; + g_MouseWheel = 0.0f; + + // Hide OS mouse cursor if ImGui is drawing it + glfwSetInputMode(g_Window, GLFW_CURSOR, io.MouseDrawCursor ? GLFW_CURSOR_HIDDEN : GLFW_CURSOR_NORMAL); + + // Start the frame + ImGui::NewFrame(); +} diff --git a/examples/opengl2_example/imgui_impl_glfw.h b/examples/opengl2_example/imgui_impl_glfw.h new file mode 100644 index 0000000..07dd96f --- /dev/null +++ b/examples/opengl2_example/imgui_impl_glfw.h @@ -0,0 +1,29 @@ +// ImGui GLFW binding with OpenGL +// In this binding, ImTextureID is used to store an OpenGL 'GLuint' texture identifier. Read the FAQ about ImTextureID in imgui.cpp. + +// If your context is GL3/GL3 then prefer using the code in opengl3_example. +// You *might* use this code with a GL3/GL4 context but make sure you disable the programmable pipeline by calling "glUseProgram(0)" before ImGui::Render(). +// We cannot do that from GL2 code because the function doesn't exist. + +// You can copy and use unmodified imgui_impl_* files in your project. See main.cpp for an example of using this. +// If you use this binding you'll need to call 4 functions: ImGui_ImplXXXX_Init(), ImGui_ImplXXXX_NewFrame(), ImGui::Render() and ImGui_ImplXXXX_Shutdown(). +// If you are new to ImGui, see examples/README.txt and documentation at the top of imgui.cpp. +// https://github.com/ocornut/imgui + +struct GLFWwindow; + +IMGUI_API bool ImGui_ImplGlfw_Init(GLFWwindow* window, bool install_callbacks); +IMGUI_API void ImGui_ImplGlfw_Shutdown(); +IMGUI_API void ImGui_ImplGlfw_NewFrame(); + +// Use if you want to reset your rendering device without losing ImGui state. +IMGUI_API void ImGui_ImplGlfw_InvalidateDeviceObjects(); +IMGUI_API bool ImGui_ImplGlfw_CreateDeviceObjects(); + +// GLFW callbacks (installed by default if you enable 'install_callbacks' during initialization) +// Provided here if you want to chain callbacks. +// You can also handle inputs yourself and use those as a reference. +IMGUI_API void ImGui_ImplGlfw_MouseButtonCallback(GLFWwindow* window, int button, int action, int mods); +IMGUI_API void ImGui_ImplGlfw_ScrollCallback(GLFWwindow* window, double xoffset, double yoffset); +IMGUI_API void ImGui_ImplGlFw_KeyCallback(GLFWwindow* window, int key, int scancode, int action, int mods); +IMGUI_API void ImGui_ImplGlfw_CharCallback(GLFWwindow* window, unsigned int c); diff --git a/examples/opengl2_example/main.cpp b/examples/opengl2_example/main.cpp new file mode 100644 index 0000000..a844db5 --- /dev/null +++ b/examples/opengl2_example/main.cpp @@ -0,0 +1,89 @@ +// ImGui - standalone example application for Glfw + OpenGL 2, using fixed pipeline +// If you are new to ImGui, see examples/README.txt and documentation at the top of imgui.cpp. + +#include +#include "imgui_impl_glfw.h" +#include +#include + +static void error_callback(int error, const char* description) +{ + fprintf(stderr, "Error %d: %s\n", error, description); +} + +int main(int, char**) +{ + // Setup window + glfwSetErrorCallback(error_callback); + if (!glfwInit()) + return 1; + GLFWwindow* window = glfwCreateWindow(1280, 720, "ImGui OpenGL2 example", NULL, NULL); + glfwMakeContextCurrent(window); + + // Setup ImGui binding + ImGui_ImplGlfw_Init(window, true); + + // Load Fonts + // (there is a default font, this is only if you want to change it. see extra_fonts/README.txt for more details) + //ImGuiIO& io = ImGui::GetIO(); + //io.Fonts->AddFontDefault(); + //io.Fonts->AddFontFromFileTTF("../../extra_fonts/Cousine-Regular.ttf", 15.0f); + //io.Fonts->AddFontFromFileTTF("../../extra_fonts/DroidSans.ttf", 16.0f); + //io.Fonts->AddFontFromFileTTF("../../extra_fonts/ProggyClean.ttf", 13.0f); + //io.Fonts->AddFontFromFileTTF("../../extra_fonts/ProggyTiny.ttf", 10.0f); + //io.Fonts->AddFontFromFileTTF("c:\\Windows\\Fonts\\ArialUni.ttf", 18.0f, NULL, io.Fonts->GetGlyphRangesJapanese()); + + bool show_test_window = true; + bool show_another_window = false; + ImVec4 clear_color = ImColor(114, 144, 154); + + // Main loop + while (!glfwWindowShouldClose(window)) + { + glfwPollEvents(); + ImGui_ImplGlfw_NewFrame(); + + // 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 = 0.0f; + ImGui::Text("Hello, world!"); + ImGui::SliderFloat("float", &f, 0.0f, 1.0f); + ImGui::ColorEdit3("clear color", (float*)&clear_color); + if (ImGui::Button("Test Window")) show_test_window ^= 1; + if (ImGui::Button("Another Window")) show_another_window ^= 1; + ImGui::Text("Application average %.3f ms/frame (%.1f FPS)", 1000.0f / ImGui::GetIO().Framerate, ImGui::GetIO().Framerate); + } + + // 2. Show another simple window, this time using an explicit Begin/End pair + if (show_another_window) + { + ImGui::SetNextWindowSize(ImVec2(200,100), ImGuiSetCond_FirstUseEver); + ImGui::Begin("Another Window", &show_another_window); + 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::SetNextWindowPos(ImVec2(650, 20), ImGuiSetCond_FirstUseEver); + ImGui::ShowTestWindow(&show_test_window); + } + + // Rendering + int display_w, display_h; + glfwGetFramebufferSize(window, &display_w, &display_h); + glViewport(0, 0, display_w, display_h); + glClearColor(clear_color.x, clear_color.y, clear_color.z, clear_color.w); + glClear(GL_COLOR_BUFFER_BIT); + ImGui::Render(); + glfwSwapBuffers(window); + } + + // Cleanup + ImGui_ImplGlfw_Shutdown(); + glfwTerminate(); + + return 0; +} diff --git a/examples/opengl2_example/opengl_example.vcxproj b/examples/opengl2_example/opengl_example.vcxproj new file mode 100644 index 0000000..4b354b6 --- /dev/null +++ b/examples/opengl2_example/opengl_example.vcxproj @@ -0,0 +1,169 @@ + + + + + Debug + Win32 + + + Debug + x64 + + + Release + Win32 + + + Release + x64 + + + + {9CDA7840-B7A5-496D-A527-E95571496D18} + opengl_example + + + + Application + true + MultiByte + + + Application + true + MultiByte + + + Application + false + true + MultiByte + + + Application + false + true + MultiByte + + + + + + + + + + + + + + + + + + + $(ProjectDir)$(Configuration)\ + $(ProjectDir)$(Configuration)\ + $(IncludePath) + + + $(ProjectDir)$(Configuration)\ + $(ProjectDir)$(Configuration)\ + $(IncludePath) + + + $(ProjectDir)$(Configuration)\ + $(ProjectDir)$(Configuration)\ + $(IncludePath) + + + $(ProjectDir)$(Configuration)\ + $(ProjectDir)$(Configuration)\ + $(IncludePath) + + + + Level4 + Disabled + $(SolutionDir)\libs\glfw\include;..\..;%(AdditionalIncludeDirectories) + + + true + $(SolutionDir)\libs\glfw\lib-vc2010-32;%(AdditionalLibraryDirectories) + opengl32.lib;glfw3.lib;%(AdditionalDependencies) + Console + msvcrt.lib + + + + + Level4 + Disabled + $(SolutionDir)\libs\glfw\include;..\..;%(AdditionalIncludeDirectories) + + + true + $(SolutionDir)\libs\glfw\lib-vc2010-64;%(AdditionalLibraryDirectories) + opengl32.lib;glfw3.lib;%(AdditionalDependencies) + Console + msvcrt.lib + + + + + Level4 + MaxSpeed + true + true + $(SolutionDir)\libs\glfw\include;..\..;%(AdditionalIncludeDirectories) + + + true + true + true + $(SolutionDir)\libs\glfw\lib-vc2010-32;%(AdditionalLibraryDirectories) + opengl32.lib;glfw3.lib;%(AdditionalDependencies) + Console + + + + + + + Level4 + MaxSpeed + true + true + $(SolutionDir)\libs\glfw\include;..\..;%(AdditionalIncludeDirectories) + + + true + true + true + $(SolutionDir)\libs\glfw\lib-vc2010-64;%(AdditionalLibraryDirectories) + opengl32.lib;glfw3.lib;%(AdditionalDependencies) + Console + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/examples/README.txt b/examples/README.txt index df2e86d..5a1c8df 100644 --- a/examples/README.txt +++ b/examples/README.txt @@ -8,11 +8,13 @@ TL;DR; - Newcomers, read 'PROGRAMMER GUIDE' in imgui.cpp for notes on how to setup ImGui in your codebase. - - Refer to 'opengl_example' to understand how the library is setup, it is the simplest one. + - Refer to 'opengl2_example' to LEARN how the library is setup, it is the simplest one. The other examples requires more boilerplate and are harder to read. + - If you are using OpenGL in your application, probably use an opengl3_xxx backend. + Mixing old fixed pipeline OpenGL2 and programmable pipeline OpenGL3+ isn't well supported by drivers. - If you are using of the backend provided here, so you can copy the imgui_impl_xxx.cpp/h files to your project and use them unmodified. - - If you have your own engine, you probably want to start from 'opengl_example' and adapt it to + - If you have your own engine, you probably want to start from one of the OpenGL example and adapt it to your engine, but you can read the other examples as well. ImGui is highly portable and only requires a few things to run: @@ -41,15 +43,14 @@ Also note that some setup or GPU drivers may be causing extra lag (possibly by enforcing triple buffering), leaving you with no option but sadness/anger (Intel GPU drivers were reported as such). -opengl_example/ - OpenGL example, using GLFW + fixed pipeline. - This is simple and should work for all OpenGL enabled applications. - Prefer following this example to learn how ImGui works! - (You can use this code in a GL3/GL4 context but make sure you disable the programmable pipeline - by calling "glUseProgram(0)" before ImGui::Render.) +opengl2_example/ + GLFW + OpenGL example (old fixed pipeline). + This is simple to read. Prefer following this example to learn how ImGui works! + (You might be able to use this code in a GL3/GL4 context but make sure you disable the programmable + pipeline by calling "glUseProgram(0)" before ImGui::Render.) opengl3_example/ - OpenGL example, using GLFW/GL3W + programmable pipeline. + GLFW + OpenGL example (programmable pipeline, binding modern functions with GL3W). This uses more modern OpenGL calls and custom shaders. It's more messy. directx9_example/ @@ -68,8 +69,8 @@ On iOS, Using Synergy to access keyboard/mouse data from server computer. Synergy keyboard integration is rather hacky. -sdl_opengl_example/ - SDL2 + OpenGL example. +sdl_opengl2_example/ + SDL2 + OpenGL example (old fixed pipeline). sdl_opengl3_example/ SDL2 + OpenGL3 example. diff --git a/examples/imgui_examples_msvc2010.sln b/examples/imgui_examples_msvc2010.sln index b7e6a25..16f0d60 100644 --- a/examples/imgui_examples_msvc2010.sln +++ b/examples/imgui_examples_msvc2010.sln @@ -1,7 +1,7 @@  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}" +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "opengl2_example", "opengl_example\opengl2_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 diff --git a/examples/opengl2_example/Makefile b/examples/opengl2_example/Makefile new file mode 100644 index 0000000..bd79d1b --- /dev/null +++ b/examples/opengl2_example/Makefile @@ -0,0 +1,60 @@ +# +# Cross Platform Makefile +# Compatible with Ubuntu 14.04.1 and Mac OS X +# +# +# if you using Mac OS X: +# You'll need glfw +# http://www.glfw.org +# + +#CXX = g++ + +EXE = opengl2_example +OBJS = main.o imgui_impl_glfw.o +OBJS += ../../imgui.o ../../imgui_demo.o ../../imgui_draw.o + +UNAME_S := $(shell uname -s) + + +ifeq ($(UNAME_S), Linux) #LINUX + ECHO_MESSAGE = "Linux" + LIBS = -lGL `pkg-config --static --libs glfw3` + + CXXFLAGS = -I../../ `pkg-config --cflags glfw3` + CXXFLAGS += -Wall -Wformat + CFLAGS = $(CXXFLAGS) +endif + +ifeq ($(UNAME_S), Darwin) #APPLE + ECHO_MESSAGE = "Mac OS X" + LIBS = -framework OpenGL -framework Cocoa -framework IOKit -framework CoreVideo + LIBS += -L/usr/local/lib -lglfw3 + + CXXFLAGS = -I../../ -I/usr/local/include + CXXFLAGS += -Wall -Wformat +# CXXFLAGS += -D__APPLE__ + CFLAGS = $(CXXFLAGS) +endif + +ifeq ($(UNAME_S), MINGW64_NT-6.3) + ECHO_MESSAGE = "Windows" + LIBS = -lglfw3 -lgdi32 -lopengl32 -limm32 + + CXXFLAGS = -I../../ -I../libs/gl3w `pkg-config --cflags glfw3` + CXXFLAGS += -Wall -Wformat + CFLAGS = $(CXXFLAGS) +endif + +.cpp.o: + $(CXX) $(CXXFLAGS) -c -o $@ $< + +all: $(EXE) + @echo Build complete for $(ECHO_MESSAGE) + +$(EXE): $(OBJS) + $(CXX) -o $(EXE) $(OBJS) $(CXXFLAGS) $(LIBS) + +clean: + rm $(EXE) $(OBJS) + diff --git a/examples/opengl2_example/build_win32.bat b/examples/opengl2_example/build_win32.bat new file mode 100644 index 0000000..278381c --- /dev/null +++ b/examples/opengl2_example/build_win32.bat @@ -0,0 +1,3 @@ +@REM Build for Visual Studio compiler. Run your copy of vcvars32.bat or vcvarsall.bat to setup command-line compiler. +mkdir Debug +cl /nologo /Zi /MD /I ..\.. /I ..\libs\glfw\include *.cpp ..\..\*.cpp /FeDebug/opengl_example.exe /FoDebug/ /link /LIBPATH:..\libs\glfw\lib-vc2010-32 glfw3.lib opengl32.lib gdi32.lib shell32.lib diff --git a/examples/opengl2_example/imgui_impl_glfw.cpp b/examples/opengl2_example/imgui_impl_glfw.cpp new file mode 100644 index 0000000..2d1f5c1 --- /dev/null +++ b/examples/opengl2_example/imgui_impl_glfw.cpp @@ -0,0 +1,288 @@ +// ImGui GLFW binding with OpenGL +// In this binding, ImTextureID is used to store an OpenGL 'GLuint' texture identifier. Read the FAQ about ImTextureID in imgui.cpp. + +// If your context is GL3/GL3 then prefer using the code in opengl3_example. +// You *might* use this code with a GL3/GL4 context but make sure you disable the programmable pipeline by calling "glUseProgram(0)" before ImGui::Render(). +// We cannot do that from GL2 code because the function doesn't exist. + +// You can copy and use unmodified imgui_impl_* files in your project. See main.cpp for an example of using this. +// If you use this binding you'll need to call 4 functions: ImGui_ImplXXXX_Init(), ImGui_ImplXXXX_NewFrame(), ImGui::Render() and ImGui_ImplXXXX_Shutdown(). +// If you are new to ImGui, see examples/README.txt and documentation at the top of imgui.cpp. +// https://github.com/ocornut/imgui + +#include +#include "imgui_impl_glfw.h" + +// GLFW +#include +#ifdef _WIN32 +#undef APIENTRY +#define GLFW_EXPOSE_NATIVE_WIN32 +#define GLFW_EXPOSE_NATIVE_WGL +#include +#endif + +// Data +static GLFWwindow* g_Window = NULL; +static double g_Time = 0.0f; +static bool g_MousePressed[3] = { false, false, false }; +static float g_MouseWheel = 0.0f; +static GLuint g_FontTexture = 0; + +// 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) +void ImGui_ImplGlfw_RenderDrawLists(ImDrawData* draw_data) +{ + // Avoid rendering when minimized, scale coordinates for retina displays (screen coordinates != framebuffer coordinates) + ImGuiIO& io = ImGui::GetIO(); + int fb_width = (int)(io.DisplaySize.x * io.DisplayFramebufferScale.x); + int fb_height = (int)(io.DisplaySize.y * io.DisplayFramebufferScale.y); + if (fb_width == 0 || fb_height == 0) + return; + draw_data->ScaleClipRects(io.DisplayFramebufferScale); + + // We are using the OpenGL fixed pipeline to make the example code simpler to read! + // Setup render state: alpha-blending enabled, no face culling, no depth testing, scissor enabled, vertex/texcoord/color pointers. + GLint last_texture; glGetIntegerv(GL_TEXTURE_BINDING_2D, &last_texture); + GLint last_viewport[4]; glGetIntegerv(GL_VIEWPORT, last_viewport); + glPushAttrib(GL_ENABLE_BIT | GL_COLOR_BUFFER_BIT | GL_TRANSFORM_BIT); + glEnable(GL_BLEND); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + glDisable(GL_CULL_FACE); + glDisable(GL_DEPTH_TEST); + glEnable(GL_SCISSOR_TEST); + glEnableClientState(GL_VERTEX_ARRAY); + glEnableClientState(GL_TEXTURE_COORD_ARRAY); + glEnableClientState(GL_COLOR_ARRAY); + glEnable(GL_TEXTURE_2D); + //glUseProgram(0); // You may want this if using this code in an OpenGL 3+ context + + // Setup viewport, orthographic projection matrix + glViewport(0, 0, (GLsizei)fb_width, (GLsizei)fb_height); + glMatrixMode(GL_PROJECTION); + glPushMatrix(); + glLoadIdentity(); + glOrtho(0.0f, io.DisplaySize.x, io.DisplaySize.y, 0.0f, -1.0f, +1.0f); + glMatrixMode(GL_MODELVIEW); + glPushMatrix(); + glLoadIdentity(); + + // Render command lists + #define OFFSETOF(TYPE, ELEMENT) ((size_t)&(((TYPE *)0)->ELEMENT)) + for (int n = 0; n < draw_data->CmdListsCount; n++) + { + const ImDrawList* cmd_list = draw_data->CmdLists[n]; + const unsigned char* vtx_buffer = (const unsigned char*)&cmd_list->VtxBuffer.front(); + const ImDrawIdx* idx_buffer = &cmd_list->IdxBuffer.front(); + glVertexPointer(2, GL_FLOAT, sizeof(ImDrawVert), (void*)(vtx_buffer + OFFSETOF(ImDrawVert, pos))); + glTexCoordPointer(2, GL_FLOAT, sizeof(ImDrawVert), (void*)(vtx_buffer + OFFSETOF(ImDrawVert, uv))); + glColorPointer(4, GL_UNSIGNED_BYTE, sizeof(ImDrawVert), (void*)(vtx_buffer + OFFSETOF(ImDrawVert, col))); + + for (int cmd_i = 0; cmd_i < cmd_list->CmdBuffer.size(); cmd_i++) + { + const ImDrawCmd* pcmd = &cmd_list->CmdBuffer[cmd_i]; + if (pcmd->UserCallback) + { + pcmd->UserCallback(cmd_list, pcmd); + } + else + { + glBindTexture(GL_TEXTURE_2D, (GLuint)(intptr_t)pcmd->TextureId); + glScissor((int)pcmd->ClipRect.x, (int)(fb_height - pcmd->ClipRect.w), (int)(pcmd->ClipRect.z - pcmd->ClipRect.x), (int)(pcmd->ClipRect.w - pcmd->ClipRect.y)); + glDrawElements(GL_TRIANGLES, (GLsizei)pcmd->ElemCount, sizeof(ImDrawIdx) == 2 ? GL_UNSIGNED_SHORT : GL_UNSIGNED_INT, idx_buffer); + } + idx_buffer += pcmd->ElemCount; + } + } + #undef OFFSETOF + + // Restore modified state + glDisableClientState(GL_COLOR_ARRAY); + glDisableClientState(GL_TEXTURE_COORD_ARRAY); + glDisableClientState(GL_VERTEX_ARRAY); + glBindTexture(GL_TEXTURE_2D, (GLuint)last_texture); + glMatrixMode(GL_MODELVIEW); + glPopMatrix(); + glMatrixMode(GL_PROJECTION); + glPopMatrix(); + glPopAttrib(); + glViewport(last_viewport[0], last_viewport[1], (GLsizei)last_viewport[2], (GLsizei)last_viewport[3]); +} + +static const char* ImGui_ImplGlfw_GetClipboardText() +{ + return glfwGetClipboardString(g_Window); +} + +static void ImGui_ImplGlfw_SetClipboardText(const char* text) +{ + glfwSetClipboardString(g_Window, text); +} + +void ImGui_ImplGlfw_MouseButtonCallback(GLFWwindow*, int button, int action, int /*mods*/) +{ + if (action == GLFW_PRESS && button >= 0 && button < 3) + g_MousePressed[button] = true; +} + +void ImGui_ImplGlfw_ScrollCallback(GLFWwindow*, double /*xoffset*/, double yoffset) +{ + g_MouseWheel += (float)yoffset; // Use fractional mouse wheel, 1.0 unit 5 lines. +} + +void ImGui_ImplGlFw_KeyCallback(GLFWwindow*, int key, int, int action, int mods) +{ + ImGuiIO& io = ImGui::GetIO(); + if (action == GLFW_PRESS) + io.KeysDown[key] = true; + if (action == GLFW_RELEASE) + io.KeysDown[key] = false; + + (void)mods; // Modifiers are not reliable across systems + io.KeyCtrl = io.KeysDown[GLFW_KEY_LEFT_CONTROL] || io.KeysDown[GLFW_KEY_RIGHT_CONTROL]; + io.KeyShift = io.KeysDown[GLFW_KEY_LEFT_SHIFT] || io.KeysDown[GLFW_KEY_RIGHT_SHIFT]; + io.KeyAlt = io.KeysDown[GLFW_KEY_LEFT_ALT] || io.KeysDown[GLFW_KEY_RIGHT_ALT]; + io.KeySuper = io.KeysDown[GLFW_KEY_LEFT_SUPER] || io.KeysDown[GLFW_KEY_RIGHT_SUPER]; +} + +void ImGui_ImplGlfw_CharCallback(GLFWwindow*, unsigned int c) +{ + ImGuiIO& io = ImGui::GetIO(); + if (c > 0 && c < 0x10000) + io.AddInputCharacter((unsigned short)c); +} + +bool ImGui_ImplGlfw_CreateDeviceObjects() +{ + // Build texture atlas + ImGuiIO& io = ImGui::GetIO(); + unsigned char* pixels; + int width, height; + io.Fonts->GetTexDataAsAlpha8(&pixels, &width, &height); + + // Upload texture to graphics system + GLint last_texture; + glGetIntegerv(GL_TEXTURE_BINDING_2D, &last_texture); + glGenTextures(1, &g_FontTexture); + glBindTexture(GL_TEXTURE_2D, g_FontTexture); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, width, height, 0, GL_ALPHA, GL_UNSIGNED_BYTE, pixels); + + // Store our identifier + io.Fonts->TexID = (void *)(intptr_t)g_FontTexture; + + // Restore state + glBindTexture(GL_TEXTURE_2D, last_texture); + + return true; +} + +void ImGui_ImplGlfw_InvalidateDeviceObjects() +{ + if (g_FontTexture) + { + glDeleteTextures(1, &g_FontTexture); + ImGui::GetIO().Fonts->TexID = 0; + g_FontTexture = 0; + } +} + +bool ImGui_ImplGlfw_Init(GLFWwindow* window, bool install_callbacks) +{ + g_Window = window; + + ImGuiIO& io = ImGui::GetIO(); + 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; + io.KeyMap[ImGuiKey_DownArrow] = GLFW_KEY_DOWN; + io.KeyMap[ImGuiKey_PageUp] = GLFW_KEY_PAGE_UP; + io.KeyMap[ImGuiKey_PageDown] = GLFW_KEY_PAGE_DOWN; + io.KeyMap[ImGuiKey_Home] = GLFW_KEY_HOME; + io.KeyMap[ImGuiKey_End] = GLFW_KEY_END; + io.KeyMap[ImGuiKey_Delete] = GLFW_KEY_DELETE; + io.KeyMap[ImGuiKey_Backspace] = GLFW_KEY_BACKSPACE; + io.KeyMap[ImGuiKey_Enter] = GLFW_KEY_ENTER; + io.KeyMap[ImGuiKey_Escape] = GLFW_KEY_ESCAPE; + io.KeyMap[ImGuiKey_A] = GLFW_KEY_A; + io.KeyMap[ImGuiKey_C] = GLFW_KEY_C; + io.KeyMap[ImGuiKey_V] = GLFW_KEY_V; + io.KeyMap[ImGuiKey_X] = GLFW_KEY_X; + io.KeyMap[ImGuiKey_Y] = GLFW_KEY_Y; + io.KeyMap[ImGuiKey_Z] = GLFW_KEY_Z; + + io.RenderDrawListsFn = ImGui_ImplGlfw_RenderDrawLists; // Alternatively you can set this to NULL and call ImGui::GetDrawData() after ImGui::Render() to get the same ImDrawData pointer. + io.SetClipboardTextFn = ImGui_ImplGlfw_SetClipboardText; + io.GetClipboardTextFn = ImGui_ImplGlfw_GetClipboardText; +#ifdef _WIN32 + io.ImeWindowHandle = glfwGetWin32Window(g_Window); +#endif + + if (install_callbacks) + { + glfwSetMouseButtonCallback(window, ImGui_ImplGlfw_MouseButtonCallback); + glfwSetScrollCallback(window, ImGui_ImplGlfw_ScrollCallback); + glfwSetKeyCallback(window, ImGui_ImplGlFw_KeyCallback); + glfwSetCharCallback(window, ImGui_ImplGlfw_CharCallback); + } + + return true; +} + +void ImGui_ImplGlfw_Shutdown() +{ + ImGui_ImplGlfw_InvalidateDeviceObjects(); + ImGui::Shutdown(); +} + +void ImGui_ImplGlfw_NewFrame() +{ + if (!g_FontTexture) + ImGui_ImplGlfw_CreateDeviceObjects(); + + ImGuiIO& io = ImGui::GetIO(); + + // Setup display size (every frame to accommodate for window resizing) + int w, h; + int display_w, display_h; + glfwGetWindowSize(g_Window, &w, &h); + glfwGetFramebufferSize(g_Window, &display_w, &display_h); + io.DisplaySize = ImVec2((float)w, (float)h); + io.DisplayFramebufferScale = ImVec2(w > 0 ? ((float)display_w / w) : 0, h > 0 ? ((float)display_h / h) : 0); + + // Setup time step + double current_time = glfwGetTime(); + io.DeltaTime = g_Time > 0.0 ? (float)(current_time - g_Time) : (float)(1.0f/60.0f); + g_Time = current_time; + + // Setup inputs + // (we already got mouse wheel, keyboard keys & characters from glfw callbacks polled in glfwPollEvents()) + if (glfwGetWindowAttrib(g_Window, GLFW_FOCUSED)) + { + double mouse_x, mouse_y; + glfwGetCursorPos(g_Window, &mouse_x, &mouse_y); + io.MousePos = ImVec2((float)mouse_x, (float)mouse_y); // Mouse position in screen coordinates (set to -1,-1 if no mouse / on another screen, etc.) + } + else + { + io.MousePos = ImVec2(-1,-1); + } + + for (int i = 0; i < 3; i++) + { + io.MouseDown[i] = g_MousePressed[i] || glfwGetMouseButton(g_Window, i) != 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. + g_MousePressed[i] = false; + } + + io.MouseWheel = g_MouseWheel; + g_MouseWheel = 0.0f; + + // Hide OS mouse cursor if ImGui is drawing it + glfwSetInputMode(g_Window, GLFW_CURSOR, io.MouseDrawCursor ? GLFW_CURSOR_HIDDEN : GLFW_CURSOR_NORMAL); + + // Start the frame + ImGui::NewFrame(); +} diff --git a/examples/opengl2_example/imgui_impl_glfw.h b/examples/opengl2_example/imgui_impl_glfw.h new file mode 100644 index 0000000..07dd96f --- /dev/null +++ b/examples/opengl2_example/imgui_impl_glfw.h @@ -0,0 +1,29 @@ +// ImGui GLFW binding with OpenGL +// In this binding, ImTextureID is used to store an OpenGL 'GLuint' texture identifier. Read the FAQ about ImTextureID in imgui.cpp. + +// If your context is GL3/GL3 then prefer using the code in opengl3_example. +// You *might* use this code with a GL3/GL4 context but make sure you disable the programmable pipeline by calling "glUseProgram(0)" before ImGui::Render(). +// We cannot do that from GL2 code because the function doesn't exist. + +// You can copy and use unmodified imgui_impl_* files in your project. See main.cpp for an example of using this. +// If you use this binding you'll need to call 4 functions: ImGui_ImplXXXX_Init(), ImGui_ImplXXXX_NewFrame(), ImGui::Render() and ImGui_ImplXXXX_Shutdown(). +// If you are new to ImGui, see examples/README.txt and documentation at the top of imgui.cpp. +// https://github.com/ocornut/imgui + +struct GLFWwindow; + +IMGUI_API bool ImGui_ImplGlfw_Init(GLFWwindow* window, bool install_callbacks); +IMGUI_API void ImGui_ImplGlfw_Shutdown(); +IMGUI_API void ImGui_ImplGlfw_NewFrame(); + +// Use if you want to reset your rendering device without losing ImGui state. +IMGUI_API void ImGui_ImplGlfw_InvalidateDeviceObjects(); +IMGUI_API bool ImGui_ImplGlfw_CreateDeviceObjects(); + +// GLFW callbacks (installed by default if you enable 'install_callbacks' during initialization) +// Provided here if you want to chain callbacks. +// You can also handle inputs yourself and use those as a reference. +IMGUI_API void ImGui_ImplGlfw_MouseButtonCallback(GLFWwindow* window, int button, int action, int mods); +IMGUI_API void ImGui_ImplGlfw_ScrollCallback(GLFWwindow* window, double xoffset, double yoffset); +IMGUI_API void ImGui_ImplGlFw_KeyCallback(GLFWwindow* window, int key, int scancode, int action, int mods); +IMGUI_API void ImGui_ImplGlfw_CharCallback(GLFWwindow* window, unsigned int c); diff --git a/examples/opengl2_example/main.cpp b/examples/opengl2_example/main.cpp new file mode 100644 index 0000000..a844db5 --- /dev/null +++ b/examples/opengl2_example/main.cpp @@ -0,0 +1,89 @@ +// ImGui - standalone example application for Glfw + OpenGL 2, using fixed pipeline +// If you are new to ImGui, see examples/README.txt and documentation at the top of imgui.cpp. + +#include +#include "imgui_impl_glfw.h" +#include +#include + +static void error_callback(int error, const char* description) +{ + fprintf(stderr, "Error %d: %s\n", error, description); +} + +int main(int, char**) +{ + // Setup window + glfwSetErrorCallback(error_callback); + if (!glfwInit()) + return 1; + GLFWwindow* window = glfwCreateWindow(1280, 720, "ImGui OpenGL2 example", NULL, NULL); + glfwMakeContextCurrent(window); + + // Setup ImGui binding + ImGui_ImplGlfw_Init(window, true); + + // Load Fonts + // (there is a default font, this is only if you want to change it. see extra_fonts/README.txt for more details) + //ImGuiIO& io = ImGui::GetIO(); + //io.Fonts->AddFontDefault(); + //io.Fonts->AddFontFromFileTTF("../../extra_fonts/Cousine-Regular.ttf", 15.0f); + //io.Fonts->AddFontFromFileTTF("../../extra_fonts/DroidSans.ttf", 16.0f); + //io.Fonts->AddFontFromFileTTF("../../extra_fonts/ProggyClean.ttf", 13.0f); + //io.Fonts->AddFontFromFileTTF("../../extra_fonts/ProggyTiny.ttf", 10.0f); + //io.Fonts->AddFontFromFileTTF("c:\\Windows\\Fonts\\ArialUni.ttf", 18.0f, NULL, io.Fonts->GetGlyphRangesJapanese()); + + bool show_test_window = true; + bool show_another_window = false; + ImVec4 clear_color = ImColor(114, 144, 154); + + // Main loop + while (!glfwWindowShouldClose(window)) + { + glfwPollEvents(); + ImGui_ImplGlfw_NewFrame(); + + // 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 = 0.0f; + ImGui::Text("Hello, world!"); + ImGui::SliderFloat("float", &f, 0.0f, 1.0f); + ImGui::ColorEdit3("clear color", (float*)&clear_color); + if (ImGui::Button("Test Window")) show_test_window ^= 1; + if (ImGui::Button("Another Window")) show_another_window ^= 1; + ImGui::Text("Application average %.3f ms/frame (%.1f FPS)", 1000.0f / ImGui::GetIO().Framerate, ImGui::GetIO().Framerate); + } + + // 2. Show another simple window, this time using an explicit Begin/End pair + if (show_another_window) + { + ImGui::SetNextWindowSize(ImVec2(200,100), ImGuiSetCond_FirstUseEver); + ImGui::Begin("Another Window", &show_another_window); + 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::SetNextWindowPos(ImVec2(650, 20), ImGuiSetCond_FirstUseEver); + ImGui::ShowTestWindow(&show_test_window); + } + + // Rendering + int display_w, display_h; + glfwGetFramebufferSize(window, &display_w, &display_h); + glViewport(0, 0, display_w, display_h); + glClearColor(clear_color.x, clear_color.y, clear_color.z, clear_color.w); + glClear(GL_COLOR_BUFFER_BIT); + ImGui::Render(); + glfwSwapBuffers(window); + } + + // Cleanup + ImGui_ImplGlfw_Shutdown(); + glfwTerminate(); + + return 0; +} diff --git a/examples/opengl2_example/opengl_example.vcxproj b/examples/opengl2_example/opengl_example.vcxproj new file mode 100644 index 0000000..4b354b6 --- /dev/null +++ b/examples/opengl2_example/opengl_example.vcxproj @@ -0,0 +1,169 @@ + + + + + Debug + Win32 + + + Debug + x64 + + + Release + Win32 + + + Release + x64 + + + + {9CDA7840-B7A5-496D-A527-E95571496D18} + opengl_example + + + + Application + true + MultiByte + + + Application + true + MultiByte + + + Application + false + true + MultiByte + + + Application + false + true + MultiByte + + + + + + + + + + + + + + + + + + + $(ProjectDir)$(Configuration)\ + $(ProjectDir)$(Configuration)\ + $(IncludePath) + + + $(ProjectDir)$(Configuration)\ + $(ProjectDir)$(Configuration)\ + $(IncludePath) + + + $(ProjectDir)$(Configuration)\ + $(ProjectDir)$(Configuration)\ + $(IncludePath) + + + $(ProjectDir)$(Configuration)\ + $(ProjectDir)$(Configuration)\ + $(IncludePath) + + + + Level4 + Disabled + $(SolutionDir)\libs\glfw\include;..\..;%(AdditionalIncludeDirectories) + + + true + $(SolutionDir)\libs\glfw\lib-vc2010-32;%(AdditionalLibraryDirectories) + opengl32.lib;glfw3.lib;%(AdditionalDependencies) + Console + msvcrt.lib + + + + + Level4 + Disabled + $(SolutionDir)\libs\glfw\include;..\..;%(AdditionalIncludeDirectories) + + + true + $(SolutionDir)\libs\glfw\lib-vc2010-64;%(AdditionalLibraryDirectories) + opengl32.lib;glfw3.lib;%(AdditionalDependencies) + Console + msvcrt.lib + + + + + Level4 + MaxSpeed + true + true + $(SolutionDir)\libs\glfw\include;..\..;%(AdditionalIncludeDirectories) + + + true + true + true + $(SolutionDir)\libs\glfw\lib-vc2010-32;%(AdditionalLibraryDirectories) + opengl32.lib;glfw3.lib;%(AdditionalDependencies) + Console + + + + + + + Level4 + MaxSpeed + true + true + $(SolutionDir)\libs\glfw\include;..\..;%(AdditionalIncludeDirectories) + + + true + true + true + $(SolutionDir)\libs\glfw\lib-vc2010-64;%(AdditionalLibraryDirectories) + opengl32.lib;glfw3.lib;%(AdditionalDependencies) + Console + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/examples/opengl2_example/opengl_example.vcxproj.filters b/examples/opengl2_example/opengl_example.vcxproj.filters new file mode 100644 index 0000000..f2282bf --- /dev/null +++ b/examples/opengl2_example/opengl_example.vcxproj.filters @@ -0,0 +1,46 @@ + + + + + {c336cfe3-f0c4-464c-9ef0-a9e17a7ff222} + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx + + + + + sources + + + imgui + + + sources + + + imgui + + + imgui + + + + + imgui + + + imgui + + + sources + + + imgui + + + + + + \ No newline at end of file diff --git a/examples/README.txt b/examples/README.txt index df2e86d..5a1c8df 100644 --- a/examples/README.txt +++ b/examples/README.txt @@ -8,11 +8,13 @@ TL;DR; - Newcomers, read 'PROGRAMMER GUIDE' in imgui.cpp for notes on how to setup ImGui in your codebase. - - Refer to 'opengl_example' to understand how the library is setup, it is the simplest one. + - Refer to 'opengl2_example' to LEARN how the library is setup, it is the simplest one. The other examples requires more boilerplate and are harder to read. + - If you are using OpenGL in your application, probably use an opengl3_xxx backend. + Mixing old fixed pipeline OpenGL2 and programmable pipeline OpenGL3+ isn't well supported by drivers. - If you are using of the backend provided here, so you can copy the imgui_impl_xxx.cpp/h files to your project and use them unmodified. - - If you have your own engine, you probably want to start from 'opengl_example' and adapt it to + - If you have your own engine, you probably want to start from one of the OpenGL example and adapt it to your engine, but you can read the other examples as well. ImGui is highly portable and only requires a few things to run: @@ -41,15 +43,14 @@ Also note that some setup or GPU drivers may be causing extra lag (possibly by enforcing triple buffering), leaving you with no option but sadness/anger (Intel GPU drivers were reported as such). -opengl_example/ - OpenGL example, using GLFW + fixed pipeline. - This is simple and should work for all OpenGL enabled applications. - Prefer following this example to learn how ImGui works! - (You can use this code in a GL3/GL4 context but make sure you disable the programmable pipeline - by calling "glUseProgram(0)" before ImGui::Render.) +opengl2_example/ + GLFW + OpenGL example (old fixed pipeline). + This is simple to read. Prefer following this example to learn how ImGui works! + (You might be able to use this code in a GL3/GL4 context but make sure you disable the programmable + pipeline by calling "glUseProgram(0)" before ImGui::Render.) opengl3_example/ - OpenGL example, using GLFW/GL3W + programmable pipeline. + GLFW + OpenGL example (programmable pipeline, binding modern functions with GL3W). This uses more modern OpenGL calls and custom shaders. It's more messy. directx9_example/ @@ -68,8 +69,8 @@ On iOS, Using Synergy to access keyboard/mouse data from server computer. Synergy keyboard integration is rather hacky. -sdl_opengl_example/ - SDL2 + OpenGL example. +sdl_opengl2_example/ + SDL2 + OpenGL example (old fixed pipeline). sdl_opengl3_example/ SDL2 + OpenGL3 example. diff --git a/examples/imgui_examples_msvc2010.sln b/examples/imgui_examples_msvc2010.sln index b7e6a25..16f0d60 100644 --- a/examples/imgui_examples_msvc2010.sln +++ b/examples/imgui_examples_msvc2010.sln @@ -1,7 +1,7 @@  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}" +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "opengl2_example", "opengl_example\opengl2_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 diff --git a/examples/opengl2_example/Makefile b/examples/opengl2_example/Makefile new file mode 100644 index 0000000..bd79d1b --- /dev/null +++ b/examples/opengl2_example/Makefile @@ -0,0 +1,60 @@ +# +# Cross Platform Makefile +# Compatible with Ubuntu 14.04.1 and Mac OS X +# +# +# if you using Mac OS X: +# You'll need glfw +# http://www.glfw.org +# + +#CXX = g++ + +EXE = opengl2_example +OBJS = main.o imgui_impl_glfw.o +OBJS += ../../imgui.o ../../imgui_demo.o ../../imgui_draw.o + +UNAME_S := $(shell uname -s) + + +ifeq ($(UNAME_S), Linux) #LINUX + ECHO_MESSAGE = "Linux" + LIBS = -lGL `pkg-config --static --libs glfw3` + + CXXFLAGS = -I../../ `pkg-config --cflags glfw3` + CXXFLAGS += -Wall -Wformat + CFLAGS = $(CXXFLAGS) +endif + +ifeq ($(UNAME_S), Darwin) #APPLE + ECHO_MESSAGE = "Mac OS X" + LIBS = -framework OpenGL -framework Cocoa -framework IOKit -framework CoreVideo + LIBS += -L/usr/local/lib -lglfw3 + + CXXFLAGS = -I../../ -I/usr/local/include + CXXFLAGS += -Wall -Wformat +# CXXFLAGS += -D__APPLE__ + CFLAGS = $(CXXFLAGS) +endif + +ifeq ($(UNAME_S), MINGW64_NT-6.3) + ECHO_MESSAGE = "Windows" + LIBS = -lglfw3 -lgdi32 -lopengl32 -limm32 + + CXXFLAGS = -I../../ -I../libs/gl3w `pkg-config --cflags glfw3` + CXXFLAGS += -Wall -Wformat + CFLAGS = $(CXXFLAGS) +endif + +.cpp.o: + $(CXX) $(CXXFLAGS) -c -o $@ $< + +all: $(EXE) + @echo Build complete for $(ECHO_MESSAGE) + +$(EXE): $(OBJS) + $(CXX) -o $(EXE) $(OBJS) $(CXXFLAGS) $(LIBS) + +clean: + rm $(EXE) $(OBJS) + diff --git a/examples/opengl2_example/build_win32.bat b/examples/opengl2_example/build_win32.bat new file mode 100644 index 0000000..278381c --- /dev/null +++ b/examples/opengl2_example/build_win32.bat @@ -0,0 +1,3 @@ +@REM Build for Visual Studio compiler. Run your copy of vcvars32.bat or vcvarsall.bat to setup command-line compiler. +mkdir Debug +cl /nologo /Zi /MD /I ..\.. /I ..\libs\glfw\include *.cpp ..\..\*.cpp /FeDebug/opengl_example.exe /FoDebug/ /link /LIBPATH:..\libs\glfw\lib-vc2010-32 glfw3.lib opengl32.lib gdi32.lib shell32.lib diff --git a/examples/opengl2_example/imgui_impl_glfw.cpp b/examples/opengl2_example/imgui_impl_glfw.cpp new file mode 100644 index 0000000..2d1f5c1 --- /dev/null +++ b/examples/opengl2_example/imgui_impl_glfw.cpp @@ -0,0 +1,288 @@ +// ImGui GLFW binding with OpenGL +// In this binding, ImTextureID is used to store an OpenGL 'GLuint' texture identifier. Read the FAQ about ImTextureID in imgui.cpp. + +// If your context is GL3/GL3 then prefer using the code in opengl3_example. +// You *might* use this code with a GL3/GL4 context but make sure you disable the programmable pipeline by calling "glUseProgram(0)" before ImGui::Render(). +// We cannot do that from GL2 code because the function doesn't exist. + +// You can copy and use unmodified imgui_impl_* files in your project. See main.cpp for an example of using this. +// If you use this binding you'll need to call 4 functions: ImGui_ImplXXXX_Init(), ImGui_ImplXXXX_NewFrame(), ImGui::Render() and ImGui_ImplXXXX_Shutdown(). +// If you are new to ImGui, see examples/README.txt and documentation at the top of imgui.cpp. +// https://github.com/ocornut/imgui + +#include +#include "imgui_impl_glfw.h" + +// GLFW +#include +#ifdef _WIN32 +#undef APIENTRY +#define GLFW_EXPOSE_NATIVE_WIN32 +#define GLFW_EXPOSE_NATIVE_WGL +#include +#endif + +// Data +static GLFWwindow* g_Window = NULL; +static double g_Time = 0.0f; +static bool g_MousePressed[3] = { false, false, false }; +static float g_MouseWheel = 0.0f; +static GLuint g_FontTexture = 0; + +// 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) +void ImGui_ImplGlfw_RenderDrawLists(ImDrawData* draw_data) +{ + // Avoid rendering when minimized, scale coordinates for retina displays (screen coordinates != framebuffer coordinates) + ImGuiIO& io = ImGui::GetIO(); + int fb_width = (int)(io.DisplaySize.x * io.DisplayFramebufferScale.x); + int fb_height = (int)(io.DisplaySize.y * io.DisplayFramebufferScale.y); + if (fb_width == 0 || fb_height == 0) + return; + draw_data->ScaleClipRects(io.DisplayFramebufferScale); + + // We are using the OpenGL fixed pipeline to make the example code simpler to read! + // Setup render state: alpha-blending enabled, no face culling, no depth testing, scissor enabled, vertex/texcoord/color pointers. + GLint last_texture; glGetIntegerv(GL_TEXTURE_BINDING_2D, &last_texture); + GLint last_viewport[4]; glGetIntegerv(GL_VIEWPORT, last_viewport); + glPushAttrib(GL_ENABLE_BIT | GL_COLOR_BUFFER_BIT | GL_TRANSFORM_BIT); + glEnable(GL_BLEND); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + glDisable(GL_CULL_FACE); + glDisable(GL_DEPTH_TEST); + glEnable(GL_SCISSOR_TEST); + glEnableClientState(GL_VERTEX_ARRAY); + glEnableClientState(GL_TEXTURE_COORD_ARRAY); + glEnableClientState(GL_COLOR_ARRAY); + glEnable(GL_TEXTURE_2D); + //glUseProgram(0); // You may want this if using this code in an OpenGL 3+ context + + // Setup viewport, orthographic projection matrix + glViewport(0, 0, (GLsizei)fb_width, (GLsizei)fb_height); + glMatrixMode(GL_PROJECTION); + glPushMatrix(); + glLoadIdentity(); + glOrtho(0.0f, io.DisplaySize.x, io.DisplaySize.y, 0.0f, -1.0f, +1.0f); + glMatrixMode(GL_MODELVIEW); + glPushMatrix(); + glLoadIdentity(); + + // Render command lists + #define OFFSETOF(TYPE, ELEMENT) ((size_t)&(((TYPE *)0)->ELEMENT)) + for (int n = 0; n < draw_data->CmdListsCount; n++) + { + const ImDrawList* cmd_list = draw_data->CmdLists[n]; + const unsigned char* vtx_buffer = (const unsigned char*)&cmd_list->VtxBuffer.front(); + const ImDrawIdx* idx_buffer = &cmd_list->IdxBuffer.front(); + glVertexPointer(2, GL_FLOAT, sizeof(ImDrawVert), (void*)(vtx_buffer + OFFSETOF(ImDrawVert, pos))); + glTexCoordPointer(2, GL_FLOAT, sizeof(ImDrawVert), (void*)(vtx_buffer + OFFSETOF(ImDrawVert, uv))); + glColorPointer(4, GL_UNSIGNED_BYTE, sizeof(ImDrawVert), (void*)(vtx_buffer + OFFSETOF(ImDrawVert, col))); + + for (int cmd_i = 0; cmd_i < cmd_list->CmdBuffer.size(); cmd_i++) + { + const ImDrawCmd* pcmd = &cmd_list->CmdBuffer[cmd_i]; + if (pcmd->UserCallback) + { + pcmd->UserCallback(cmd_list, pcmd); + } + else + { + glBindTexture(GL_TEXTURE_2D, (GLuint)(intptr_t)pcmd->TextureId); + glScissor((int)pcmd->ClipRect.x, (int)(fb_height - pcmd->ClipRect.w), (int)(pcmd->ClipRect.z - pcmd->ClipRect.x), (int)(pcmd->ClipRect.w - pcmd->ClipRect.y)); + glDrawElements(GL_TRIANGLES, (GLsizei)pcmd->ElemCount, sizeof(ImDrawIdx) == 2 ? GL_UNSIGNED_SHORT : GL_UNSIGNED_INT, idx_buffer); + } + idx_buffer += pcmd->ElemCount; + } + } + #undef OFFSETOF + + // Restore modified state + glDisableClientState(GL_COLOR_ARRAY); + glDisableClientState(GL_TEXTURE_COORD_ARRAY); + glDisableClientState(GL_VERTEX_ARRAY); + glBindTexture(GL_TEXTURE_2D, (GLuint)last_texture); + glMatrixMode(GL_MODELVIEW); + glPopMatrix(); + glMatrixMode(GL_PROJECTION); + glPopMatrix(); + glPopAttrib(); + glViewport(last_viewport[0], last_viewport[1], (GLsizei)last_viewport[2], (GLsizei)last_viewport[3]); +} + +static const char* ImGui_ImplGlfw_GetClipboardText() +{ + return glfwGetClipboardString(g_Window); +} + +static void ImGui_ImplGlfw_SetClipboardText(const char* text) +{ + glfwSetClipboardString(g_Window, text); +} + +void ImGui_ImplGlfw_MouseButtonCallback(GLFWwindow*, int button, int action, int /*mods*/) +{ + if (action == GLFW_PRESS && button >= 0 && button < 3) + g_MousePressed[button] = true; +} + +void ImGui_ImplGlfw_ScrollCallback(GLFWwindow*, double /*xoffset*/, double yoffset) +{ + g_MouseWheel += (float)yoffset; // Use fractional mouse wheel, 1.0 unit 5 lines. +} + +void ImGui_ImplGlFw_KeyCallback(GLFWwindow*, int key, int, int action, int mods) +{ + ImGuiIO& io = ImGui::GetIO(); + if (action == GLFW_PRESS) + io.KeysDown[key] = true; + if (action == GLFW_RELEASE) + io.KeysDown[key] = false; + + (void)mods; // Modifiers are not reliable across systems + io.KeyCtrl = io.KeysDown[GLFW_KEY_LEFT_CONTROL] || io.KeysDown[GLFW_KEY_RIGHT_CONTROL]; + io.KeyShift = io.KeysDown[GLFW_KEY_LEFT_SHIFT] || io.KeysDown[GLFW_KEY_RIGHT_SHIFT]; + io.KeyAlt = io.KeysDown[GLFW_KEY_LEFT_ALT] || io.KeysDown[GLFW_KEY_RIGHT_ALT]; + io.KeySuper = io.KeysDown[GLFW_KEY_LEFT_SUPER] || io.KeysDown[GLFW_KEY_RIGHT_SUPER]; +} + +void ImGui_ImplGlfw_CharCallback(GLFWwindow*, unsigned int c) +{ + ImGuiIO& io = ImGui::GetIO(); + if (c > 0 && c < 0x10000) + io.AddInputCharacter((unsigned short)c); +} + +bool ImGui_ImplGlfw_CreateDeviceObjects() +{ + // Build texture atlas + ImGuiIO& io = ImGui::GetIO(); + unsigned char* pixels; + int width, height; + io.Fonts->GetTexDataAsAlpha8(&pixels, &width, &height); + + // Upload texture to graphics system + GLint last_texture; + glGetIntegerv(GL_TEXTURE_BINDING_2D, &last_texture); + glGenTextures(1, &g_FontTexture); + glBindTexture(GL_TEXTURE_2D, g_FontTexture); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, width, height, 0, GL_ALPHA, GL_UNSIGNED_BYTE, pixels); + + // Store our identifier + io.Fonts->TexID = (void *)(intptr_t)g_FontTexture; + + // Restore state + glBindTexture(GL_TEXTURE_2D, last_texture); + + return true; +} + +void ImGui_ImplGlfw_InvalidateDeviceObjects() +{ + if (g_FontTexture) + { + glDeleteTextures(1, &g_FontTexture); + ImGui::GetIO().Fonts->TexID = 0; + g_FontTexture = 0; + } +} + +bool ImGui_ImplGlfw_Init(GLFWwindow* window, bool install_callbacks) +{ + g_Window = window; + + ImGuiIO& io = ImGui::GetIO(); + 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; + io.KeyMap[ImGuiKey_DownArrow] = GLFW_KEY_DOWN; + io.KeyMap[ImGuiKey_PageUp] = GLFW_KEY_PAGE_UP; + io.KeyMap[ImGuiKey_PageDown] = GLFW_KEY_PAGE_DOWN; + io.KeyMap[ImGuiKey_Home] = GLFW_KEY_HOME; + io.KeyMap[ImGuiKey_End] = GLFW_KEY_END; + io.KeyMap[ImGuiKey_Delete] = GLFW_KEY_DELETE; + io.KeyMap[ImGuiKey_Backspace] = GLFW_KEY_BACKSPACE; + io.KeyMap[ImGuiKey_Enter] = GLFW_KEY_ENTER; + io.KeyMap[ImGuiKey_Escape] = GLFW_KEY_ESCAPE; + io.KeyMap[ImGuiKey_A] = GLFW_KEY_A; + io.KeyMap[ImGuiKey_C] = GLFW_KEY_C; + io.KeyMap[ImGuiKey_V] = GLFW_KEY_V; + io.KeyMap[ImGuiKey_X] = GLFW_KEY_X; + io.KeyMap[ImGuiKey_Y] = GLFW_KEY_Y; + io.KeyMap[ImGuiKey_Z] = GLFW_KEY_Z; + + io.RenderDrawListsFn = ImGui_ImplGlfw_RenderDrawLists; // Alternatively you can set this to NULL and call ImGui::GetDrawData() after ImGui::Render() to get the same ImDrawData pointer. + io.SetClipboardTextFn = ImGui_ImplGlfw_SetClipboardText; + io.GetClipboardTextFn = ImGui_ImplGlfw_GetClipboardText; +#ifdef _WIN32 + io.ImeWindowHandle = glfwGetWin32Window(g_Window); +#endif + + if (install_callbacks) + { + glfwSetMouseButtonCallback(window, ImGui_ImplGlfw_MouseButtonCallback); + glfwSetScrollCallback(window, ImGui_ImplGlfw_ScrollCallback); + glfwSetKeyCallback(window, ImGui_ImplGlFw_KeyCallback); + glfwSetCharCallback(window, ImGui_ImplGlfw_CharCallback); + } + + return true; +} + +void ImGui_ImplGlfw_Shutdown() +{ + ImGui_ImplGlfw_InvalidateDeviceObjects(); + ImGui::Shutdown(); +} + +void ImGui_ImplGlfw_NewFrame() +{ + if (!g_FontTexture) + ImGui_ImplGlfw_CreateDeviceObjects(); + + ImGuiIO& io = ImGui::GetIO(); + + // Setup display size (every frame to accommodate for window resizing) + int w, h; + int display_w, display_h; + glfwGetWindowSize(g_Window, &w, &h); + glfwGetFramebufferSize(g_Window, &display_w, &display_h); + io.DisplaySize = ImVec2((float)w, (float)h); + io.DisplayFramebufferScale = ImVec2(w > 0 ? ((float)display_w / w) : 0, h > 0 ? ((float)display_h / h) : 0); + + // Setup time step + double current_time = glfwGetTime(); + io.DeltaTime = g_Time > 0.0 ? (float)(current_time - g_Time) : (float)(1.0f/60.0f); + g_Time = current_time; + + // Setup inputs + // (we already got mouse wheel, keyboard keys & characters from glfw callbacks polled in glfwPollEvents()) + if (glfwGetWindowAttrib(g_Window, GLFW_FOCUSED)) + { + double mouse_x, mouse_y; + glfwGetCursorPos(g_Window, &mouse_x, &mouse_y); + io.MousePos = ImVec2((float)mouse_x, (float)mouse_y); // Mouse position in screen coordinates (set to -1,-1 if no mouse / on another screen, etc.) + } + else + { + io.MousePos = ImVec2(-1,-1); + } + + for (int i = 0; i < 3; i++) + { + io.MouseDown[i] = g_MousePressed[i] || glfwGetMouseButton(g_Window, i) != 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. + g_MousePressed[i] = false; + } + + io.MouseWheel = g_MouseWheel; + g_MouseWheel = 0.0f; + + // Hide OS mouse cursor if ImGui is drawing it + glfwSetInputMode(g_Window, GLFW_CURSOR, io.MouseDrawCursor ? GLFW_CURSOR_HIDDEN : GLFW_CURSOR_NORMAL); + + // Start the frame + ImGui::NewFrame(); +} diff --git a/examples/opengl2_example/imgui_impl_glfw.h b/examples/opengl2_example/imgui_impl_glfw.h new file mode 100644 index 0000000..07dd96f --- /dev/null +++ b/examples/opengl2_example/imgui_impl_glfw.h @@ -0,0 +1,29 @@ +// ImGui GLFW binding with OpenGL +// In this binding, ImTextureID is used to store an OpenGL 'GLuint' texture identifier. Read the FAQ about ImTextureID in imgui.cpp. + +// If your context is GL3/GL3 then prefer using the code in opengl3_example. +// You *might* use this code with a GL3/GL4 context but make sure you disable the programmable pipeline by calling "glUseProgram(0)" before ImGui::Render(). +// We cannot do that from GL2 code because the function doesn't exist. + +// You can copy and use unmodified imgui_impl_* files in your project. See main.cpp for an example of using this. +// If you use this binding you'll need to call 4 functions: ImGui_ImplXXXX_Init(), ImGui_ImplXXXX_NewFrame(), ImGui::Render() and ImGui_ImplXXXX_Shutdown(). +// If you are new to ImGui, see examples/README.txt and documentation at the top of imgui.cpp. +// https://github.com/ocornut/imgui + +struct GLFWwindow; + +IMGUI_API bool ImGui_ImplGlfw_Init(GLFWwindow* window, bool install_callbacks); +IMGUI_API void ImGui_ImplGlfw_Shutdown(); +IMGUI_API void ImGui_ImplGlfw_NewFrame(); + +// Use if you want to reset your rendering device without losing ImGui state. +IMGUI_API void ImGui_ImplGlfw_InvalidateDeviceObjects(); +IMGUI_API bool ImGui_ImplGlfw_CreateDeviceObjects(); + +// GLFW callbacks (installed by default if you enable 'install_callbacks' during initialization) +// Provided here if you want to chain callbacks. +// You can also handle inputs yourself and use those as a reference. +IMGUI_API void ImGui_ImplGlfw_MouseButtonCallback(GLFWwindow* window, int button, int action, int mods); +IMGUI_API void ImGui_ImplGlfw_ScrollCallback(GLFWwindow* window, double xoffset, double yoffset); +IMGUI_API void ImGui_ImplGlFw_KeyCallback(GLFWwindow* window, int key, int scancode, int action, int mods); +IMGUI_API void ImGui_ImplGlfw_CharCallback(GLFWwindow* window, unsigned int c); diff --git a/examples/opengl2_example/main.cpp b/examples/opengl2_example/main.cpp new file mode 100644 index 0000000..a844db5 --- /dev/null +++ b/examples/opengl2_example/main.cpp @@ -0,0 +1,89 @@ +// ImGui - standalone example application for Glfw + OpenGL 2, using fixed pipeline +// If you are new to ImGui, see examples/README.txt and documentation at the top of imgui.cpp. + +#include +#include "imgui_impl_glfw.h" +#include +#include + +static void error_callback(int error, const char* description) +{ + fprintf(stderr, "Error %d: %s\n", error, description); +} + +int main(int, char**) +{ + // Setup window + glfwSetErrorCallback(error_callback); + if (!glfwInit()) + return 1; + GLFWwindow* window = glfwCreateWindow(1280, 720, "ImGui OpenGL2 example", NULL, NULL); + glfwMakeContextCurrent(window); + + // Setup ImGui binding + ImGui_ImplGlfw_Init(window, true); + + // Load Fonts + // (there is a default font, this is only if you want to change it. see extra_fonts/README.txt for more details) + //ImGuiIO& io = ImGui::GetIO(); + //io.Fonts->AddFontDefault(); + //io.Fonts->AddFontFromFileTTF("../../extra_fonts/Cousine-Regular.ttf", 15.0f); + //io.Fonts->AddFontFromFileTTF("../../extra_fonts/DroidSans.ttf", 16.0f); + //io.Fonts->AddFontFromFileTTF("../../extra_fonts/ProggyClean.ttf", 13.0f); + //io.Fonts->AddFontFromFileTTF("../../extra_fonts/ProggyTiny.ttf", 10.0f); + //io.Fonts->AddFontFromFileTTF("c:\\Windows\\Fonts\\ArialUni.ttf", 18.0f, NULL, io.Fonts->GetGlyphRangesJapanese()); + + bool show_test_window = true; + bool show_another_window = false; + ImVec4 clear_color = ImColor(114, 144, 154); + + // Main loop + while (!glfwWindowShouldClose(window)) + { + glfwPollEvents(); + ImGui_ImplGlfw_NewFrame(); + + // 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 = 0.0f; + ImGui::Text("Hello, world!"); + ImGui::SliderFloat("float", &f, 0.0f, 1.0f); + ImGui::ColorEdit3("clear color", (float*)&clear_color); + if (ImGui::Button("Test Window")) show_test_window ^= 1; + if (ImGui::Button("Another Window")) show_another_window ^= 1; + ImGui::Text("Application average %.3f ms/frame (%.1f FPS)", 1000.0f / ImGui::GetIO().Framerate, ImGui::GetIO().Framerate); + } + + // 2. Show another simple window, this time using an explicit Begin/End pair + if (show_another_window) + { + ImGui::SetNextWindowSize(ImVec2(200,100), ImGuiSetCond_FirstUseEver); + ImGui::Begin("Another Window", &show_another_window); + 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::SetNextWindowPos(ImVec2(650, 20), ImGuiSetCond_FirstUseEver); + ImGui::ShowTestWindow(&show_test_window); + } + + // Rendering + int display_w, display_h; + glfwGetFramebufferSize(window, &display_w, &display_h); + glViewport(0, 0, display_w, display_h); + glClearColor(clear_color.x, clear_color.y, clear_color.z, clear_color.w); + glClear(GL_COLOR_BUFFER_BIT); + ImGui::Render(); + glfwSwapBuffers(window); + } + + // Cleanup + ImGui_ImplGlfw_Shutdown(); + glfwTerminate(); + + return 0; +} diff --git a/examples/opengl2_example/opengl_example.vcxproj b/examples/opengl2_example/opengl_example.vcxproj new file mode 100644 index 0000000..4b354b6 --- /dev/null +++ b/examples/opengl2_example/opengl_example.vcxproj @@ -0,0 +1,169 @@ + + + + + Debug + Win32 + + + Debug + x64 + + + Release + Win32 + + + Release + x64 + + + + {9CDA7840-B7A5-496D-A527-E95571496D18} + opengl_example + + + + Application + true + MultiByte + + + Application + true + MultiByte + + + Application + false + true + MultiByte + + + Application + false + true + MultiByte + + + + + + + + + + + + + + + + + + + $(ProjectDir)$(Configuration)\ + $(ProjectDir)$(Configuration)\ + $(IncludePath) + + + $(ProjectDir)$(Configuration)\ + $(ProjectDir)$(Configuration)\ + $(IncludePath) + + + $(ProjectDir)$(Configuration)\ + $(ProjectDir)$(Configuration)\ + $(IncludePath) + + + $(ProjectDir)$(Configuration)\ + $(ProjectDir)$(Configuration)\ + $(IncludePath) + + + + Level4 + Disabled + $(SolutionDir)\libs\glfw\include;..\..;%(AdditionalIncludeDirectories) + + + true + $(SolutionDir)\libs\glfw\lib-vc2010-32;%(AdditionalLibraryDirectories) + opengl32.lib;glfw3.lib;%(AdditionalDependencies) + Console + msvcrt.lib + + + + + Level4 + Disabled + $(SolutionDir)\libs\glfw\include;..\..;%(AdditionalIncludeDirectories) + + + true + $(SolutionDir)\libs\glfw\lib-vc2010-64;%(AdditionalLibraryDirectories) + opengl32.lib;glfw3.lib;%(AdditionalDependencies) + Console + msvcrt.lib + + + + + Level4 + MaxSpeed + true + true + $(SolutionDir)\libs\glfw\include;..\..;%(AdditionalIncludeDirectories) + + + true + true + true + $(SolutionDir)\libs\glfw\lib-vc2010-32;%(AdditionalLibraryDirectories) + opengl32.lib;glfw3.lib;%(AdditionalDependencies) + Console + + + + + + + Level4 + MaxSpeed + true + true + $(SolutionDir)\libs\glfw\include;..\..;%(AdditionalIncludeDirectories) + + + true + true + true + $(SolutionDir)\libs\glfw\lib-vc2010-64;%(AdditionalLibraryDirectories) + opengl32.lib;glfw3.lib;%(AdditionalDependencies) + Console + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/examples/opengl2_example/opengl_example.vcxproj.filters b/examples/opengl2_example/opengl_example.vcxproj.filters new file mode 100644 index 0000000..f2282bf --- /dev/null +++ b/examples/opengl2_example/opengl_example.vcxproj.filters @@ -0,0 +1,46 @@ + + + + + {c336cfe3-f0c4-464c-9ef0-a9e17a7ff222} + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx + + + + + sources + + + imgui + + + sources + + + imgui + + + imgui + + + + + imgui + + + imgui + + + sources + + + imgui + + + + + + \ No newline at end of file diff --git a/examples/opengl_example/Makefile b/examples/opengl_example/Makefile deleted file mode 100644 index 91d1b14..0000000 --- a/examples/opengl_example/Makefile +++ /dev/null @@ -1,60 +0,0 @@ -# -# Cross Platform Makefile -# Compatible with Ubuntu 14.04.1 and Mac OS X -# -# -# if you using Mac OS X: -# You'll need glfw -# http://www.glfw.org -# - -#CXX = g++ - -EXE = opengl_example -OBJS = main.o imgui_impl_glfw.o -OBJS += ../../imgui.o ../../imgui_demo.o ../../imgui_draw.o - -UNAME_S := $(shell uname -s) - - -ifeq ($(UNAME_S), Linux) #LINUX - ECHO_MESSAGE = "Linux" - LIBS = -lGL `pkg-config --static --libs glfw3` - - CXXFLAGS = -I../../ `pkg-config --cflags glfw3` - CXXFLAGS += -Wall -Wformat - CFLAGS = $(CXXFLAGS) -endif - -ifeq ($(UNAME_S), Darwin) #APPLE - ECHO_MESSAGE = "Mac OS X" - LIBS = -framework OpenGL -framework Cocoa -framework IOKit -framework CoreVideo - LIBS += -L/usr/local/lib -lglfw3 - - CXXFLAGS = -I../../ -I/usr/local/include - CXXFLAGS += -Wall -Wformat -# CXXFLAGS += -D__APPLE__ - CFLAGS = $(CXXFLAGS) -endif - -ifeq ($(UNAME_S), MINGW64_NT-6.3) - ECHO_MESSAGE = "Windows" - LIBS = -lglfw3 -lgdi32 -lopengl32 -limm32 - - CXXFLAGS = -I../../ -I../libs/gl3w `pkg-config --cflags glfw3` - CXXFLAGS += -Wall -Wformat - CFLAGS = $(CXXFLAGS) -endif - -.cpp.o: - $(CXX) $(CXXFLAGS) -c -o $@ $< - -all: $(EXE) - @echo Build complete for $(ECHO_MESSAGE) - -$(EXE): $(OBJS) - $(CXX) -o $(EXE) $(OBJS) $(CXXFLAGS) $(LIBS) - -clean: - rm $(EXE) $(OBJS) - diff --git a/examples/README.txt b/examples/README.txt index df2e86d..5a1c8df 100644 --- a/examples/README.txt +++ b/examples/README.txt @@ -8,11 +8,13 @@ TL;DR; - Newcomers, read 'PROGRAMMER GUIDE' in imgui.cpp for notes on how to setup ImGui in your codebase. - - Refer to 'opengl_example' to understand how the library is setup, it is the simplest one. + - Refer to 'opengl2_example' to LEARN how the library is setup, it is the simplest one. The other examples requires more boilerplate and are harder to read. + - If you are using OpenGL in your application, probably use an opengl3_xxx backend. + Mixing old fixed pipeline OpenGL2 and programmable pipeline OpenGL3+ isn't well supported by drivers. - If you are using of the backend provided here, so you can copy the imgui_impl_xxx.cpp/h files to your project and use them unmodified. - - If you have your own engine, you probably want to start from 'opengl_example' and adapt it to + - If you have your own engine, you probably want to start from one of the OpenGL example and adapt it to your engine, but you can read the other examples as well. ImGui is highly portable and only requires a few things to run: @@ -41,15 +43,14 @@ Also note that some setup or GPU drivers may be causing extra lag (possibly by enforcing triple buffering), leaving you with no option but sadness/anger (Intel GPU drivers were reported as such). -opengl_example/ - OpenGL example, using GLFW + fixed pipeline. - This is simple and should work for all OpenGL enabled applications. - Prefer following this example to learn how ImGui works! - (You can use this code in a GL3/GL4 context but make sure you disable the programmable pipeline - by calling "glUseProgram(0)" before ImGui::Render.) +opengl2_example/ + GLFW + OpenGL example (old fixed pipeline). + This is simple to read. Prefer following this example to learn how ImGui works! + (You might be able to use this code in a GL3/GL4 context but make sure you disable the programmable + pipeline by calling "glUseProgram(0)" before ImGui::Render.) opengl3_example/ - OpenGL example, using GLFW/GL3W + programmable pipeline. + GLFW + OpenGL example (programmable pipeline, binding modern functions with GL3W). This uses more modern OpenGL calls and custom shaders. It's more messy. directx9_example/ @@ -68,8 +69,8 @@ On iOS, Using Synergy to access keyboard/mouse data from server computer. Synergy keyboard integration is rather hacky. -sdl_opengl_example/ - SDL2 + OpenGL example. +sdl_opengl2_example/ + SDL2 + OpenGL example (old fixed pipeline). sdl_opengl3_example/ SDL2 + OpenGL3 example. diff --git a/examples/imgui_examples_msvc2010.sln b/examples/imgui_examples_msvc2010.sln index b7e6a25..16f0d60 100644 --- a/examples/imgui_examples_msvc2010.sln +++ b/examples/imgui_examples_msvc2010.sln @@ -1,7 +1,7 @@  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}" +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "opengl2_example", "opengl_example\opengl2_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 diff --git a/examples/opengl2_example/Makefile b/examples/opengl2_example/Makefile new file mode 100644 index 0000000..bd79d1b --- /dev/null +++ b/examples/opengl2_example/Makefile @@ -0,0 +1,60 @@ +# +# Cross Platform Makefile +# Compatible with Ubuntu 14.04.1 and Mac OS X +# +# +# if you using Mac OS X: +# You'll need glfw +# http://www.glfw.org +# + +#CXX = g++ + +EXE = opengl2_example +OBJS = main.o imgui_impl_glfw.o +OBJS += ../../imgui.o ../../imgui_demo.o ../../imgui_draw.o + +UNAME_S := $(shell uname -s) + + +ifeq ($(UNAME_S), Linux) #LINUX + ECHO_MESSAGE = "Linux" + LIBS = -lGL `pkg-config --static --libs glfw3` + + CXXFLAGS = -I../../ `pkg-config --cflags glfw3` + CXXFLAGS += -Wall -Wformat + CFLAGS = $(CXXFLAGS) +endif + +ifeq ($(UNAME_S), Darwin) #APPLE + ECHO_MESSAGE = "Mac OS X" + LIBS = -framework OpenGL -framework Cocoa -framework IOKit -framework CoreVideo + LIBS += -L/usr/local/lib -lglfw3 + + CXXFLAGS = -I../../ -I/usr/local/include + CXXFLAGS += -Wall -Wformat +# CXXFLAGS += -D__APPLE__ + CFLAGS = $(CXXFLAGS) +endif + +ifeq ($(UNAME_S), MINGW64_NT-6.3) + ECHO_MESSAGE = "Windows" + LIBS = -lglfw3 -lgdi32 -lopengl32 -limm32 + + CXXFLAGS = -I../../ -I../libs/gl3w `pkg-config --cflags glfw3` + CXXFLAGS += -Wall -Wformat + CFLAGS = $(CXXFLAGS) +endif + +.cpp.o: + $(CXX) $(CXXFLAGS) -c -o $@ $< + +all: $(EXE) + @echo Build complete for $(ECHO_MESSAGE) + +$(EXE): $(OBJS) + $(CXX) -o $(EXE) $(OBJS) $(CXXFLAGS) $(LIBS) + +clean: + rm $(EXE) $(OBJS) + diff --git a/examples/opengl2_example/build_win32.bat b/examples/opengl2_example/build_win32.bat new file mode 100644 index 0000000..278381c --- /dev/null +++ b/examples/opengl2_example/build_win32.bat @@ -0,0 +1,3 @@ +@REM Build for Visual Studio compiler. Run your copy of vcvars32.bat or vcvarsall.bat to setup command-line compiler. +mkdir Debug +cl /nologo /Zi /MD /I ..\.. /I ..\libs\glfw\include *.cpp ..\..\*.cpp /FeDebug/opengl_example.exe /FoDebug/ /link /LIBPATH:..\libs\glfw\lib-vc2010-32 glfw3.lib opengl32.lib gdi32.lib shell32.lib diff --git a/examples/opengl2_example/imgui_impl_glfw.cpp b/examples/opengl2_example/imgui_impl_glfw.cpp new file mode 100644 index 0000000..2d1f5c1 --- /dev/null +++ b/examples/opengl2_example/imgui_impl_glfw.cpp @@ -0,0 +1,288 @@ +// ImGui GLFW binding with OpenGL +// In this binding, ImTextureID is used to store an OpenGL 'GLuint' texture identifier. Read the FAQ about ImTextureID in imgui.cpp. + +// If your context is GL3/GL3 then prefer using the code in opengl3_example. +// You *might* use this code with a GL3/GL4 context but make sure you disable the programmable pipeline by calling "glUseProgram(0)" before ImGui::Render(). +// We cannot do that from GL2 code because the function doesn't exist. + +// You can copy and use unmodified imgui_impl_* files in your project. See main.cpp for an example of using this. +// If you use this binding you'll need to call 4 functions: ImGui_ImplXXXX_Init(), ImGui_ImplXXXX_NewFrame(), ImGui::Render() and ImGui_ImplXXXX_Shutdown(). +// If you are new to ImGui, see examples/README.txt and documentation at the top of imgui.cpp. +// https://github.com/ocornut/imgui + +#include +#include "imgui_impl_glfw.h" + +// GLFW +#include +#ifdef _WIN32 +#undef APIENTRY +#define GLFW_EXPOSE_NATIVE_WIN32 +#define GLFW_EXPOSE_NATIVE_WGL +#include +#endif + +// Data +static GLFWwindow* g_Window = NULL; +static double g_Time = 0.0f; +static bool g_MousePressed[3] = { false, false, false }; +static float g_MouseWheel = 0.0f; +static GLuint g_FontTexture = 0; + +// 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) +void ImGui_ImplGlfw_RenderDrawLists(ImDrawData* draw_data) +{ + // Avoid rendering when minimized, scale coordinates for retina displays (screen coordinates != framebuffer coordinates) + ImGuiIO& io = ImGui::GetIO(); + int fb_width = (int)(io.DisplaySize.x * io.DisplayFramebufferScale.x); + int fb_height = (int)(io.DisplaySize.y * io.DisplayFramebufferScale.y); + if (fb_width == 0 || fb_height == 0) + return; + draw_data->ScaleClipRects(io.DisplayFramebufferScale); + + // We are using the OpenGL fixed pipeline to make the example code simpler to read! + // Setup render state: alpha-blending enabled, no face culling, no depth testing, scissor enabled, vertex/texcoord/color pointers. + GLint last_texture; glGetIntegerv(GL_TEXTURE_BINDING_2D, &last_texture); + GLint last_viewport[4]; glGetIntegerv(GL_VIEWPORT, last_viewport); + glPushAttrib(GL_ENABLE_BIT | GL_COLOR_BUFFER_BIT | GL_TRANSFORM_BIT); + glEnable(GL_BLEND); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + glDisable(GL_CULL_FACE); + glDisable(GL_DEPTH_TEST); + glEnable(GL_SCISSOR_TEST); + glEnableClientState(GL_VERTEX_ARRAY); + glEnableClientState(GL_TEXTURE_COORD_ARRAY); + glEnableClientState(GL_COLOR_ARRAY); + glEnable(GL_TEXTURE_2D); + //glUseProgram(0); // You may want this if using this code in an OpenGL 3+ context + + // Setup viewport, orthographic projection matrix + glViewport(0, 0, (GLsizei)fb_width, (GLsizei)fb_height); + glMatrixMode(GL_PROJECTION); + glPushMatrix(); + glLoadIdentity(); + glOrtho(0.0f, io.DisplaySize.x, io.DisplaySize.y, 0.0f, -1.0f, +1.0f); + glMatrixMode(GL_MODELVIEW); + glPushMatrix(); + glLoadIdentity(); + + // Render command lists + #define OFFSETOF(TYPE, ELEMENT) ((size_t)&(((TYPE *)0)->ELEMENT)) + for (int n = 0; n < draw_data->CmdListsCount; n++) + { + const ImDrawList* cmd_list = draw_data->CmdLists[n]; + const unsigned char* vtx_buffer = (const unsigned char*)&cmd_list->VtxBuffer.front(); + const ImDrawIdx* idx_buffer = &cmd_list->IdxBuffer.front(); + glVertexPointer(2, GL_FLOAT, sizeof(ImDrawVert), (void*)(vtx_buffer + OFFSETOF(ImDrawVert, pos))); + glTexCoordPointer(2, GL_FLOAT, sizeof(ImDrawVert), (void*)(vtx_buffer + OFFSETOF(ImDrawVert, uv))); + glColorPointer(4, GL_UNSIGNED_BYTE, sizeof(ImDrawVert), (void*)(vtx_buffer + OFFSETOF(ImDrawVert, col))); + + for (int cmd_i = 0; cmd_i < cmd_list->CmdBuffer.size(); cmd_i++) + { + const ImDrawCmd* pcmd = &cmd_list->CmdBuffer[cmd_i]; + if (pcmd->UserCallback) + { + pcmd->UserCallback(cmd_list, pcmd); + } + else + { + glBindTexture(GL_TEXTURE_2D, (GLuint)(intptr_t)pcmd->TextureId); + glScissor((int)pcmd->ClipRect.x, (int)(fb_height - pcmd->ClipRect.w), (int)(pcmd->ClipRect.z - pcmd->ClipRect.x), (int)(pcmd->ClipRect.w - pcmd->ClipRect.y)); + glDrawElements(GL_TRIANGLES, (GLsizei)pcmd->ElemCount, sizeof(ImDrawIdx) == 2 ? GL_UNSIGNED_SHORT : GL_UNSIGNED_INT, idx_buffer); + } + idx_buffer += pcmd->ElemCount; + } + } + #undef OFFSETOF + + // Restore modified state + glDisableClientState(GL_COLOR_ARRAY); + glDisableClientState(GL_TEXTURE_COORD_ARRAY); + glDisableClientState(GL_VERTEX_ARRAY); + glBindTexture(GL_TEXTURE_2D, (GLuint)last_texture); + glMatrixMode(GL_MODELVIEW); + glPopMatrix(); + glMatrixMode(GL_PROJECTION); + glPopMatrix(); + glPopAttrib(); + glViewport(last_viewport[0], last_viewport[1], (GLsizei)last_viewport[2], (GLsizei)last_viewport[3]); +} + +static const char* ImGui_ImplGlfw_GetClipboardText() +{ + return glfwGetClipboardString(g_Window); +} + +static void ImGui_ImplGlfw_SetClipboardText(const char* text) +{ + glfwSetClipboardString(g_Window, text); +} + +void ImGui_ImplGlfw_MouseButtonCallback(GLFWwindow*, int button, int action, int /*mods*/) +{ + if (action == GLFW_PRESS && button >= 0 && button < 3) + g_MousePressed[button] = true; +} + +void ImGui_ImplGlfw_ScrollCallback(GLFWwindow*, double /*xoffset*/, double yoffset) +{ + g_MouseWheel += (float)yoffset; // Use fractional mouse wheel, 1.0 unit 5 lines. +} + +void ImGui_ImplGlFw_KeyCallback(GLFWwindow*, int key, int, int action, int mods) +{ + ImGuiIO& io = ImGui::GetIO(); + if (action == GLFW_PRESS) + io.KeysDown[key] = true; + if (action == GLFW_RELEASE) + io.KeysDown[key] = false; + + (void)mods; // Modifiers are not reliable across systems + io.KeyCtrl = io.KeysDown[GLFW_KEY_LEFT_CONTROL] || io.KeysDown[GLFW_KEY_RIGHT_CONTROL]; + io.KeyShift = io.KeysDown[GLFW_KEY_LEFT_SHIFT] || io.KeysDown[GLFW_KEY_RIGHT_SHIFT]; + io.KeyAlt = io.KeysDown[GLFW_KEY_LEFT_ALT] || io.KeysDown[GLFW_KEY_RIGHT_ALT]; + io.KeySuper = io.KeysDown[GLFW_KEY_LEFT_SUPER] || io.KeysDown[GLFW_KEY_RIGHT_SUPER]; +} + +void ImGui_ImplGlfw_CharCallback(GLFWwindow*, unsigned int c) +{ + ImGuiIO& io = ImGui::GetIO(); + if (c > 0 && c < 0x10000) + io.AddInputCharacter((unsigned short)c); +} + +bool ImGui_ImplGlfw_CreateDeviceObjects() +{ + // Build texture atlas + ImGuiIO& io = ImGui::GetIO(); + unsigned char* pixels; + int width, height; + io.Fonts->GetTexDataAsAlpha8(&pixels, &width, &height); + + // Upload texture to graphics system + GLint last_texture; + glGetIntegerv(GL_TEXTURE_BINDING_2D, &last_texture); + glGenTextures(1, &g_FontTexture); + glBindTexture(GL_TEXTURE_2D, g_FontTexture); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, width, height, 0, GL_ALPHA, GL_UNSIGNED_BYTE, pixels); + + // Store our identifier + io.Fonts->TexID = (void *)(intptr_t)g_FontTexture; + + // Restore state + glBindTexture(GL_TEXTURE_2D, last_texture); + + return true; +} + +void ImGui_ImplGlfw_InvalidateDeviceObjects() +{ + if (g_FontTexture) + { + glDeleteTextures(1, &g_FontTexture); + ImGui::GetIO().Fonts->TexID = 0; + g_FontTexture = 0; + } +} + +bool ImGui_ImplGlfw_Init(GLFWwindow* window, bool install_callbacks) +{ + g_Window = window; + + ImGuiIO& io = ImGui::GetIO(); + 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; + io.KeyMap[ImGuiKey_DownArrow] = GLFW_KEY_DOWN; + io.KeyMap[ImGuiKey_PageUp] = GLFW_KEY_PAGE_UP; + io.KeyMap[ImGuiKey_PageDown] = GLFW_KEY_PAGE_DOWN; + io.KeyMap[ImGuiKey_Home] = GLFW_KEY_HOME; + io.KeyMap[ImGuiKey_End] = GLFW_KEY_END; + io.KeyMap[ImGuiKey_Delete] = GLFW_KEY_DELETE; + io.KeyMap[ImGuiKey_Backspace] = GLFW_KEY_BACKSPACE; + io.KeyMap[ImGuiKey_Enter] = GLFW_KEY_ENTER; + io.KeyMap[ImGuiKey_Escape] = GLFW_KEY_ESCAPE; + io.KeyMap[ImGuiKey_A] = GLFW_KEY_A; + io.KeyMap[ImGuiKey_C] = GLFW_KEY_C; + io.KeyMap[ImGuiKey_V] = GLFW_KEY_V; + io.KeyMap[ImGuiKey_X] = GLFW_KEY_X; + io.KeyMap[ImGuiKey_Y] = GLFW_KEY_Y; + io.KeyMap[ImGuiKey_Z] = GLFW_KEY_Z; + + io.RenderDrawListsFn = ImGui_ImplGlfw_RenderDrawLists; // Alternatively you can set this to NULL and call ImGui::GetDrawData() after ImGui::Render() to get the same ImDrawData pointer. + io.SetClipboardTextFn = ImGui_ImplGlfw_SetClipboardText; + io.GetClipboardTextFn = ImGui_ImplGlfw_GetClipboardText; +#ifdef _WIN32 + io.ImeWindowHandle = glfwGetWin32Window(g_Window); +#endif + + if (install_callbacks) + { + glfwSetMouseButtonCallback(window, ImGui_ImplGlfw_MouseButtonCallback); + glfwSetScrollCallback(window, ImGui_ImplGlfw_ScrollCallback); + glfwSetKeyCallback(window, ImGui_ImplGlFw_KeyCallback); + glfwSetCharCallback(window, ImGui_ImplGlfw_CharCallback); + } + + return true; +} + +void ImGui_ImplGlfw_Shutdown() +{ + ImGui_ImplGlfw_InvalidateDeviceObjects(); + ImGui::Shutdown(); +} + +void ImGui_ImplGlfw_NewFrame() +{ + if (!g_FontTexture) + ImGui_ImplGlfw_CreateDeviceObjects(); + + ImGuiIO& io = ImGui::GetIO(); + + // Setup display size (every frame to accommodate for window resizing) + int w, h; + int display_w, display_h; + glfwGetWindowSize(g_Window, &w, &h); + glfwGetFramebufferSize(g_Window, &display_w, &display_h); + io.DisplaySize = ImVec2((float)w, (float)h); + io.DisplayFramebufferScale = ImVec2(w > 0 ? ((float)display_w / w) : 0, h > 0 ? ((float)display_h / h) : 0); + + // Setup time step + double current_time = glfwGetTime(); + io.DeltaTime = g_Time > 0.0 ? (float)(current_time - g_Time) : (float)(1.0f/60.0f); + g_Time = current_time; + + // Setup inputs + // (we already got mouse wheel, keyboard keys & characters from glfw callbacks polled in glfwPollEvents()) + if (glfwGetWindowAttrib(g_Window, GLFW_FOCUSED)) + { + double mouse_x, mouse_y; + glfwGetCursorPos(g_Window, &mouse_x, &mouse_y); + io.MousePos = ImVec2((float)mouse_x, (float)mouse_y); // Mouse position in screen coordinates (set to -1,-1 if no mouse / on another screen, etc.) + } + else + { + io.MousePos = ImVec2(-1,-1); + } + + for (int i = 0; i < 3; i++) + { + io.MouseDown[i] = g_MousePressed[i] || glfwGetMouseButton(g_Window, i) != 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. + g_MousePressed[i] = false; + } + + io.MouseWheel = g_MouseWheel; + g_MouseWheel = 0.0f; + + // Hide OS mouse cursor if ImGui is drawing it + glfwSetInputMode(g_Window, GLFW_CURSOR, io.MouseDrawCursor ? GLFW_CURSOR_HIDDEN : GLFW_CURSOR_NORMAL); + + // Start the frame + ImGui::NewFrame(); +} diff --git a/examples/opengl2_example/imgui_impl_glfw.h b/examples/opengl2_example/imgui_impl_glfw.h new file mode 100644 index 0000000..07dd96f --- /dev/null +++ b/examples/opengl2_example/imgui_impl_glfw.h @@ -0,0 +1,29 @@ +// ImGui GLFW binding with OpenGL +// In this binding, ImTextureID is used to store an OpenGL 'GLuint' texture identifier. Read the FAQ about ImTextureID in imgui.cpp. + +// If your context is GL3/GL3 then prefer using the code in opengl3_example. +// You *might* use this code with a GL3/GL4 context but make sure you disable the programmable pipeline by calling "glUseProgram(0)" before ImGui::Render(). +// We cannot do that from GL2 code because the function doesn't exist. + +// You can copy and use unmodified imgui_impl_* files in your project. See main.cpp for an example of using this. +// If you use this binding you'll need to call 4 functions: ImGui_ImplXXXX_Init(), ImGui_ImplXXXX_NewFrame(), ImGui::Render() and ImGui_ImplXXXX_Shutdown(). +// If you are new to ImGui, see examples/README.txt and documentation at the top of imgui.cpp. +// https://github.com/ocornut/imgui + +struct GLFWwindow; + +IMGUI_API bool ImGui_ImplGlfw_Init(GLFWwindow* window, bool install_callbacks); +IMGUI_API void ImGui_ImplGlfw_Shutdown(); +IMGUI_API void ImGui_ImplGlfw_NewFrame(); + +// Use if you want to reset your rendering device without losing ImGui state. +IMGUI_API void ImGui_ImplGlfw_InvalidateDeviceObjects(); +IMGUI_API bool ImGui_ImplGlfw_CreateDeviceObjects(); + +// GLFW callbacks (installed by default if you enable 'install_callbacks' during initialization) +// Provided here if you want to chain callbacks. +// You can also handle inputs yourself and use those as a reference. +IMGUI_API void ImGui_ImplGlfw_MouseButtonCallback(GLFWwindow* window, int button, int action, int mods); +IMGUI_API void ImGui_ImplGlfw_ScrollCallback(GLFWwindow* window, double xoffset, double yoffset); +IMGUI_API void ImGui_ImplGlFw_KeyCallback(GLFWwindow* window, int key, int scancode, int action, int mods); +IMGUI_API void ImGui_ImplGlfw_CharCallback(GLFWwindow* window, unsigned int c); diff --git a/examples/opengl2_example/main.cpp b/examples/opengl2_example/main.cpp new file mode 100644 index 0000000..a844db5 --- /dev/null +++ b/examples/opengl2_example/main.cpp @@ -0,0 +1,89 @@ +// ImGui - standalone example application for Glfw + OpenGL 2, using fixed pipeline +// If you are new to ImGui, see examples/README.txt and documentation at the top of imgui.cpp. + +#include +#include "imgui_impl_glfw.h" +#include +#include + +static void error_callback(int error, const char* description) +{ + fprintf(stderr, "Error %d: %s\n", error, description); +} + +int main(int, char**) +{ + // Setup window + glfwSetErrorCallback(error_callback); + if (!glfwInit()) + return 1; + GLFWwindow* window = glfwCreateWindow(1280, 720, "ImGui OpenGL2 example", NULL, NULL); + glfwMakeContextCurrent(window); + + // Setup ImGui binding + ImGui_ImplGlfw_Init(window, true); + + // Load Fonts + // (there is a default font, this is only if you want to change it. see extra_fonts/README.txt for more details) + //ImGuiIO& io = ImGui::GetIO(); + //io.Fonts->AddFontDefault(); + //io.Fonts->AddFontFromFileTTF("../../extra_fonts/Cousine-Regular.ttf", 15.0f); + //io.Fonts->AddFontFromFileTTF("../../extra_fonts/DroidSans.ttf", 16.0f); + //io.Fonts->AddFontFromFileTTF("../../extra_fonts/ProggyClean.ttf", 13.0f); + //io.Fonts->AddFontFromFileTTF("../../extra_fonts/ProggyTiny.ttf", 10.0f); + //io.Fonts->AddFontFromFileTTF("c:\\Windows\\Fonts\\ArialUni.ttf", 18.0f, NULL, io.Fonts->GetGlyphRangesJapanese()); + + bool show_test_window = true; + bool show_another_window = false; + ImVec4 clear_color = ImColor(114, 144, 154); + + // Main loop + while (!glfwWindowShouldClose(window)) + { + glfwPollEvents(); + ImGui_ImplGlfw_NewFrame(); + + // 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 = 0.0f; + ImGui::Text("Hello, world!"); + ImGui::SliderFloat("float", &f, 0.0f, 1.0f); + ImGui::ColorEdit3("clear color", (float*)&clear_color); + if (ImGui::Button("Test Window")) show_test_window ^= 1; + if (ImGui::Button("Another Window")) show_another_window ^= 1; + ImGui::Text("Application average %.3f ms/frame (%.1f FPS)", 1000.0f / ImGui::GetIO().Framerate, ImGui::GetIO().Framerate); + } + + // 2. Show another simple window, this time using an explicit Begin/End pair + if (show_another_window) + { + ImGui::SetNextWindowSize(ImVec2(200,100), ImGuiSetCond_FirstUseEver); + ImGui::Begin("Another Window", &show_another_window); + 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::SetNextWindowPos(ImVec2(650, 20), ImGuiSetCond_FirstUseEver); + ImGui::ShowTestWindow(&show_test_window); + } + + // Rendering + int display_w, display_h; + glfwGetFramebufferSize(window, &display_w, &display_h); + glViewport(0, 0, display_w, display_h); + glClearColor(clear_color.x, clear_color.y, clear_color.z, clear_color.w); + glClear(GL_COLOR_BUFFER_BIT); + ImGui::Render(); + glfwSwapBuffers(window); + } + + // Cleanup + ImGui_ImplGlfw_Shutdown(); + glfwTerminate(); + + return 0; +} diff --git a/examples/opengl2_example/opengl_example.vcxproj b/examples/opengl2_example/opengl_example.vcxproj new file mode 100644 index 0000000..4b354b6 --- /dev/null +++ b/examples/opengl2_example/opengl_example.vcxproj @@ -0,0 +1,169 @@ + + + + + Debug + Win32 + + + Debug + x64 + + + Release + Win32 + + + Release + x64 + + + + {9CDA7840-B7A5-496D-A527-E95571496D18} + opengl_example + + + + Application + true + MultiByte + + + Application + true + MultiByte + + + Application + false + true + MultiByte + + + Application + false + true + MultiByte + + + + + + + + + + + + + + + + + + + $(ProjectDir)$(Configuration)\ + $(ProjectDir)$(Configuration)\ + $(IncludePath) + + + $(ProjectDir)$(Configuration)\ + $(ProjectDir)$(Configuration)\ + $(IncludePath) + + + $(ProjectDir)$(Configuration)\ + $(ProjectDir)$(Configuration)\ + $(IncludePath) + + + $(ProjectDir)$(Configuration)\ + $(ProjectDir)$(Configuration)\ + $(IncludePath) + + + + Level4 + Disabled + $(SolutionDir)\libs\glfw\include;..\..;%(AdditionalIncludeDirectories) + + + true + $(SolutionDir)\libs\glfw\lib-vc2010-32;%(AdditionalLibraryDirectories) + opengl32.lib;glfw3.lib;%(AdditionalDependencies) + Console + msvcrt.lib + + + + + Level4 + Disabled + $(SolutionDir)\libs\glfw\include;..\..;%(AdditionalIncludeDirectories) + + + true + $(SolutionDir)\libs\glfw\lib-vc2010-64;%(AdditionalLibraryDirectories) + opengl32.lib;glfw3.lib;%(AdditionalDependencies) + Console + msvcrt.lib + + + + + Level4 + MaxSpeed + true + true + $(SolutionDir)\libs\glfw\include;..\..;%(AdditionalIncludeDirectories) + + + true + true + true + $(SolutionDir)\libs\glfw\lib-vc2010-32;%(AdditionalLibraryDirectories) + opengl32.lib;glfw3.lib;%(AdditionalDependencies) + Console + + + + + + + Level4 + MaxSpeed + true + true + $(SolutionDir)\libs\glfw\include;..\..;%(AdditionalIncludeDirectories) + + + true + true + true + $(SolutionDir)\libs\glfw\lib-vc2010-64;%(AdditionalLibraryDirectories) + opengl32.lib;glfw3.lib;%(AdditionalDependencies) + Console + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/examples/opengl2_example/opengl_example.vcxproj.filters b/examples/opengl2_example/opengl_example.vcxproj.filters new file mode 100644 index 0000000..f2282bf --- /dev/null +++ b/examples/opengl2_example/opengl_example.vcxproj.filters @@ -0,0 +1,46 @@ + + + + + {c336cfe3-f0c4-464c-9ef0-a9e17a7ff222} + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx + + + + + sources + + + imgui + + + sources + + + imgui + + + imgui + + + + + imgui + + + imgui + + + sources + + + imgui + + + + + + \ No newline at end of file diff --git a/examples/opengl_example/Makefile b/examples/opengl_example/Makefile deleted file mode 100644 index 91d1b14..0000000 --- a/examples/opengl_example/Makefile +++ /dev/null @@ -1,60 +0,0 @@ -# -# Cross Platform Makefile -# Compatible with Ubuntu 14.04.1 and Mac OS X -# -# -# if you using Mac OS X: -# You'll need glfw -# http://www.glfw.org -# - -#CXX = g++ - -EXE = opengl_example -OBJS = main.o imgui_impl_glfw.o -OBJS += ../../imgui.o ../../imgui_demo.o ../../imgui_draw.o - -UNAME_S := $(shell uname -s) - - -ifeq ($(UNAME_S), Linux) #LINUX - ECHO_MESSAGE = "Linux" - LIBS = -lGL `pkg-config --static --libs glfw3` - - CXXFLAGS = -I../../ `pkg-config --cflags glfw3` - CXXFLAGS += -Wall -Wformat - CFLAGS = $(CXXFLAGS) -endif - -ifeq ($(UNAME_S), Darwin) #APPLE - ECHO_MESSAGE = "Mac OS X" - LIBS = -framework OpenGL -framework Cocoa -framework IOKit -framework CoreVideo - LIBS += -L/usr/local/lib -lglfw3 - - CXXFLAGS = -I../../ -I/usr/local/include - CXXFLAGS += -Wall -Wformat -# CXXFLAGS += -D__APPLE__ - CFLAGS = $(CXXFLAGS) -endif - -ifeq ($(UNAME_S), MINGW64_NT-6.3) - ECHO_MESSAGE = "Windows" - LIBS = -lglfw3 -lgdi32 -lopengl32 -limm32 - - CXXFLAGS = -I../../ -I../libs/gl3w `pkg-config --cflags glfw3` - CXXFLAGS += -Wall -Wformat - CFLAGS = $(CXXFLAGS) -endif - -.cpp.o: - $(CXX) $(CXXFLAGS) -c -o $@ $< - -all: $(EXE) - @echo Build complete for $(ECHO_MESSAGE) - -$(EXE): $(OBJS) - $(CXX) -o $(EXE) $(OBJS) $(CXXFLAGS) $(LIBS) - -clean: - rm $(EXE) $(OBJS) - diff --git a/examples/opengl_example/build_win32.bat b/examples/opengl_example/build_win32.bat deleted file mode 100644 index 278381c..0000000 --- a/examples/opengl_example/build_win32.bat +++ /dev/null @@ -1,3 +0,0 @@ -@REM Build for Visual Studio compiler. Run your copy of vcvars32.bat or vcvarsall.bat to setup command-line compiler. -mkdir Debug -cl /nologo /Zi /MD /I ..\.. /I ..\libs\glfw\include *.cpp ..\..\*.cpp /FeDebug/opengl_example.exe /FoDebug/ /link /LIBPATH:..\libs\glfw\lib-vc2010-32 glfw3.lib opengl32.lib gdi32.lib shell32.lib diff --git a/examples/README.txt b/examples/README.txt index df2e86d..5a1c8df 100644 --- a/examples/README.txt +++ b/examples/README.txt @@ -8,11 +8,13 @@ TL;DR; - Newcomers, read 'PROGRAMMER GUIDE' in imgui.cpp for notes on how to setup ImGui in your codebase. - - Refer to 'opengl_example' to understand how the library is setup, it is the simplest one. + - Refer to 'opengl2_example' to LEARN how the library is setup, it is the simplest one. The other examples requires more boilerplate and are harder to read. + - If you are using OpenGL in your application, probably use an opengl3_xxx backend. + Mixing old fixed pipeline OpenGL2 and programmable pipeline OpenGL3+ isn't well supported by drivers. - If you are using of the backend provided here, so you can copy the imgui_impl_xxx.cpp/h files to your project and use them unmodified. - - If you have your own engine, you probably want to start from 'opengl_example' and adapt it to + - If you have your own engine, you probably want to start from one of the OpenGL example and adapt it to your engine, but you can read the other examples as well. ImGui is highly portable and only requires a few things to run: @@ -41,15 +43,14 @@ Also note that some setup or GPU drivers may be causing extra lag (possibly by enforcing triple buffering), leaving you with no option but sadness/anger (Intel GPU drivers were reported as such). -opengl_example/ - OpenGL example, using GLFW + fixed pipeline. - This is simple and should work for all OpenGL enabled applications. - Prefer following this example to learn how ImGui works! - (You can use this code in a GL3/GL4 context but make sure you disable the programmable pipeline - by calling "glUseProgram(0)" before ImGui::Render.) +opengl2_example/ + GLFW + OpenGL example (old fixed pipeline). + This is simple to read. Prefer following this example to learn how ImGui works! + (You might be able to use this code in a GL3/GL4 context but make sure you disable the programmable + pipeline by calling "glUseProgram(0)" before ImGui::Render.) opengl3_example/ - OpenGL example, using GLFW/GL3W + programmable pipeline. + GLFW + OpenGL example (programmable pipeline, binding modern functions with GL3W). This uses more modern OpenGL calls and custom shaders. It's more messy. directx9_example/ @@ -68,8 +69,8 @@ On iOS, Using Synergy to access keyboard/mouse data from server computer. Synergy keyboard integration is rather hacky. -sdl_opengl_example/ - SDL2 + OpenGL example. +sdl_opengl2_example/ + SDL2 + OpenGL example (old fixed pipeline). sdl_opengl3_example/ SDL2 + OpenGL3 example. diff --git a/examples/imgui_examples_msvc2010.sln b/examples/imgui_examples_msvc2010.sln index b7e6a25..16f0d60 100644 --- a/examples/imgui_examples_msvc2010.sln +++ b/examples/imgui_examples_msvc2010.sln @@ -1,7 +1,7 @@  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}" +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "opengl2_example", "opengl_example\opengl2_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 diff --git a/examples/opengl2_example/Makefile b/examples/opengl2_example/Makefile new file mode 100644 index 0000000..bd79d1b --- /dev/null +++ b/examples/opengl2_example/Makefile @@ -0,0 +1,60 @@ +# +# Cross Platform Makefile +# Compatible with Ubuntu 14.04.1 and Mac OS X +# +# +# if you using Mac OS X: +# You'll need glfw +# http://www.glfw.org +# + +#CXX = g++ + +EXE = opengl2_example +OBJS = main.o imgui_impl_glfw.o +OBJS += ../../imgui.o ../../imgui_demo.o ../../imgui_draw.o + +UNAME_S := $(shell uname -s) + + +ifeq ($(UNAME_S), Linux) #LINUX + ECHO_MESSAGE = "Linux" + LIBS = -lGL `pkg-config --static --libs glfw3` + + CXXFLAGS = -I../../ `pkg-config --cflags glfw3` + CXXFLAGS += -Wall -Wformat + CFLAGS = $(CXXFLAGS) +endif + +ifeq ($(UNAME_S), Darwin) #APPLE + ECHO_MESSAGE = "Mac OS X" + LIBS = -framework OpenGL -framework Cocoa -framework IOKit -framework CoreVideo + LIBS += -L/usr/local/lib -lglfw3 + + CXXFLAGS = -I../../ -I/usr/local/include + CXXFLAGS += -Wall -Wformat +# CXXFLAGS += -D__APPLE__ + CFLAGS = $(CXXFLAGS) +endif + +ifeq ($(UNAME_S), MINGW64_NT-6.3) + ECHO_MESSAGE = "Windows" + LIBS = -lglfw3 -lgdi32 -lopengl32 -limm32 + + CXXFLAGS = -I../../ -I../libs/gl3w `pkg-config --cflags glfw3` + CXXFLAGS += -Wall -Wformat + CFLAGS = $(CXXFLAGS) +endif + +.cpp.o: + $(CXX) $(CXXFLAGS) -c -o $@ $< + +all: $(EXE) + @echo Build complete for $(ECHO_MESSAGE) + +$(EXE): $(OBJS) + $(CXX) -o $(EXE) $(OBJS) $(CXXFLAGS) $(LIBS) + +clean: + rm $(EXE) $(OBJS) + diff --git a/examples/opengl2_example/build_win32.bat b/examples/opengl2_example/build_win32.bat new file mode 100644 index 0000000..278381c --- /dev/null +++ b/examples/opengl2_example/build_win32.bat @@ -0,0 +1,3 @@ +@REM Build for Visual Studio compiler. Run your copy of vcvars32.bat or vcvarsall.bat to setup command-line compiler. +mkdir Debug +cl /nologo /Zi /MD /I ..\.. /I ..\libs\glfw\include *.cpp ..\..\*.cpp /FeDebug/opengl_example.exe /FoDebug/ /link /LIBPATH:..\libs\glfw\lib-vc2010-32 glfw3.lib opengl32.lib gdi32.lib shell32.lib diff --git a/examples/opengl2_example/imgui_impl_glfw.cpp b/examples/opengl2_example/imgui_impl_glfw.cpp new file mode 100644 index 0000000..2d1f5c1 --- /dev/null +++ b/examples/opengl2_example/imgui_impl_glfw.cpp @@ -0,0 +1,288 @@ +// ImGui GLFW binding with OpenGL +// In this binding, ImTextureID is used to store an OpenGL 'GLuint' texture identifier. Read the FAQ about ImTextureID in imgui.cpp. + +// If your context is GL3/GL3 then prefer using the code in opengl3_example. +// You *might* use this code with a GL3/GL4 context but make sure you disable the programmable pipeline by calling "glUseProgram(0)" before ImGui::Render(). +// We cannot do that from GL2 code because the function doesn't exist. + +// You can copy and use unmodified imgui_impl_* files in your project. See main.cpp for an example of using this. +// If you use this binding you'll need to call 4 functions: ImGui_ImplXXXX_Init(), ImGui_ImplXXXX_NewFrame(), ImGui::Render() and ImGui_ImplXXXX_Shutdown(). +// If you are new to ImGui, see examples/README.txt and documentation at the top of imgui.cpp. +// https://github.com/ocornut/imgui + +#include +#include "imgui_impl_glfw.h" + +// GLFW +#include +#ifdef _WIN32 +#undef APIENTRY +#define GLFW_EXPOSE_NATIVE_WIN32 +#define GLFW_EXPOSE_NATIVE_WGL +#include +#endif + +// Data +static GLFWwindow* g_Window = NULL; +static double g_Time = 0.0f; +static bool g_MousePressed[3] = { false, false, false }; +static float g_MouseWheel = 0.0f; +static GLuint g_FontTexture = 0; + +// 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) +void ImGui_ImplGlfw_RenderDrawLists(ImDrawData* draw_data) +{ + // Avoid rendering when minimized, scale coordinates for retina displays (screen coordinates != framebuffer coordinates) + ImGuiIO& io = ImGui::GetIO(); + int fb_width = (int)(io.DisplaySize.x * io.DisplayFramebufferScale.x); + int fb_height = (int)(io.DisplaySize.y * io.DisplayFramebufferScale.y); + if (fb_width == 0 || fb_height == 0) + return; + draw_data->ScaleClipRects(io.DisplayFramebufferScale); + + // We are using the OpenGL fixed pipeline to make the example code simpler to read! + // Setup render state: alpha-blending enabled, no face culling, no depth testing, scissor enabled, vertex/texcoord/color pointers. + GLint last_texture; glGetIntegerv(GL_TEXTURE_BINDING_2D, &last_texture); + GLint last_viewport[4]; glGetIntegerv(GL_VIEWPORT, last_viewport); + glPushAttrib(GL_ENABLE_BIT | GL_COLOR_BUFFER_BIT | GL_TRANSFORM_BIT); + glEnable(GL_BLEND); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + glDisable(GL_CULL_FACE); + glDisable(GL_DEPTH_TEST); + glEnable(GL_SCISSOR_TEST); + glEnableClientState(GL_VERTEX_ARRAY); + glEnableClientState(GL_TEXTURE_COORD_ARRAY); + glEnableClientState(GL_COLOR_ARRAY); + glEnable(GL_TEXTURE_2D); + //glUseProgram(0); // You may want this if using this code in an OpenGL 3+ context + + // Setup viewport, orthographic projection matrix + glViewport(0, 0, (GLsizei)fb_width, (GLsizei)fb_height); + glMatrixMode(GL_PROJECTION); + glPushMatrix(); + glLoadIdentity(); + glOrtho(0.0f, io.DisplaySize.x, io.DisplaySize.y, 0.0f, -1.0f, +1.0f); + glMatrixMode(GL_MODELVIEW); + glPushMatrix(); + glLoadIdentity(); + + // Render command lists + #define OFFSETOF(TYPE, ELEMENT) ((size_t)&(((TYPE *)0)->ELEMENT)) + for (int n = 0; n < draw_data->CmdListsCount; n++) + { + const ImDrawList* cmd_list = draw_data->CmdLists[n]; + const unsigned char* vtx_buffer = (const unsigned char*)&cmd_list->VtxBuffer.front(); + const ImDrawIdx* idx_buffer = &cmd_list->IdxBuffer.front(); + glVertexPointer(2, GL_FLOAT, sizeof(ImDrawVert), (void*)(vtx_buffer + OFFSETOF(ImDrawVert, pos))); + glTexCoordPointer(2, GL_FLOAT, sizeof(ImDrawVert), (void*)(vtx_buffer + OFFSETOF(ImDrawVert, uv))); + glColorPointer(4, GL_UNSIGNED_BYTE, sizeof(ImDrawVert), (void*)(vtx_buffer + OFFSETOF(ImDrawVert, col))); + + for (int cmd_i = 0; cmd_i < cmd_list->CmdBuffer.size(); cmd_i++) + { + const ImDrawCmd* pcmd = &cmd_list->CmdBuffer[cmd_i]; + if (pcmd->UserCallback) + { + pcmd->UserCallback(cmd_list, pcmd); + } + else + { + glBindTexture(GL_TEXTURE_2D, (GLuint)(intptr_t)pcmd->TextureId); + glScissor((int)pcmd->ClipRect.x, (int)(fb_height - pcmd->ClipRect.w), (int)(pcmd->ClipRect.z - pcmd->ClipRect.x), (int)(pcmd->ClipRect.w - pcmd->ClipRect.y)); + glDrawElements(GL_TRIANGLES, (GLsizei)pcmd->ElemCount, sizeof(ImDrawIdx) == 2 ? GL_UNSIGNED_SHORT : GL_UNSIGNED_INT, idx_buffer); + } + idx_buffer += pcmd->ElemCount; + } + } + #undef OFFSETOF + + // Restore modified state + glDisableClientState(GL_COLOR_ARRAY); + glDisableClientState(GL_TEXTURE_COORD_ARRAY); + glDisableClientState(GL_VERTEX_ARRAY); + glBindTexture(GL_TEXTURE_2D, (GLuint)last_texture); + glMatrixMode(GL_MODELVIEW); + glPopMatrix(); + glMatrixMode(GL_PROJECTION); + glPopMatrix(); + glPopAttrib(); + glViewport(last_viewport[0], last_viewport[1], (GLsizei)last_viewport[2], (GLsizei)last_viewport[3]); +} + +static const char* ImGui_ImplGlfw_GetClipboardText() +{ + return glfwGetClipboardString(g_Window); +} + +static void ImGui_ImplGlfw_SetClipboardText(const char* text) +{ + glfwSetClipboardString(g_Window, text); +} + +void ImGui_ImplGlfw_MouseButtonCallback(GLFWwindow*, int button, int action, int /*mods*/) +{ + if (action == GLFW_PRESS && button >= 0 && button < 3) + g_MousePressed[button] = true; +} + +void ImGui_ImplGlfw_ScrollCallback(GLFWwindow*, double /*xoffset*/, double yoffset) +{ + g_MouseWheel += (float)yoffset; // Use fractional mouse wheel, 1.0 unit 5 lines. +} + +void ImGui_ImplGlFw_KeyCallback(GLFWwindow*, int key, int, int action, int mods) +{ + ImGuiIO& io = ImGui::GetIO(); + if (action == GLFW_PRESS) + io.KeysDown[key] = true; + if (action == GLFW_RELEASE) + io.KeysDown[key] = false; + + (void)mods; // Modifiers are not reliable across systems + io.KeyCtrl = io.KeysDown[GLFW_KEY_LEFT_CONTROL] || io.KeysDown[GLFW_KEY_RIGHT_CONTROL]; + io.KeyShift = io.KeysDown[GLFW_KEY_LEFT_SHIFT] || io.KeysDown[GLFW_KEY_RIGHT_SHIFT]; + io.KeyAlt = io.KeysDown[GLFW_KEY_LEFT_ALT] || io.KeysDown[GLFW_KEY_RIGHT_ALT]; + io.KeySuper = io.KeysDown[GLFW_KEY_LEFT_SUPER] || io.KeysDown[GLFW_KEY_RIGHT_SUPER]; +} + +void ImGui_ImplGlfw_CharCallback(GLFWwindow*, unsigned int c) +{ + ImGuiIO& io = ImGui::GetIO(); + if (c > 0 && c < 0x10000) + io.AddInputCharacter((unsigned short)c); +} + +bool ImGui_ImplGlfw_CreateDeviceObjects() +{ + // Build texture atlas + ImGuiIO& io = ImGui::GetIO(); + unsigned char* pixels; + int width, height; + io.Fonts->GetTexDataAsAlpha8(&pixels, &width, &height); + + // Upload texture to graphics system + GLint last_texture; + glGetIntegerv(GL_TEXTURE_BINDING_2D, &last_texture); + glGenTextures(1, &g_FontTexture); + glBindTexture(GL_TEXTURE_2D, g_FontTexture); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, width, height, 0, GL_ALPHA, GL_UNSIGNED_BYTE, pixels); + + // Store our identifier + io.Fonts->TexID = (void *)(intptr_t)g_FontTexture; + + // Restore state + glBindTexture(GL_TEXTURE_2D, last_texture); + + return true; +} + +void ImGui_ImplGlfw_InvalidateDeviceObjects() +{ + if (g_FontTexture) + { + glDeleteTextures(1, &g_FontTexture); + ImGui::GetIO().Fonts->TexID = 0; + g_FontTexture = 0; + } +} + +bool ImGui_ImplGlfw_Init(GLFWwindow* window, bool install_callbacks) +{ + g_Window = window; + + ImGuiIO& io = ImGui::GetIO(); + 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; + io.KeyMap[ImGuiKey_DownArrow] = GLFW_KEY_DOWN; + io.KeyMap[ImGuiKey_PageUp] = GLFW_KEY_PAGE_UP; + io.KeyMap[ImGuiKey_PageDown] = GLFW_KEY_PAGE_DOWN; + io.KeyMap[ImGuiKey_Home] = GLFW_KEY_HOME; + io.KeyMap[ImGuiKey_End] = GLFW_KEY_END; + io.KeyMap[ImGuiKey_Delete] = GLFW_KEY_DELETE; + io.KeyMap[ImGuiKey_Backspace] = GLFW_KEY_BACKSPACE; + io.KeyMap[ImGuiKey_Enter] = GLFW_KEY_ENTER; + io.KeyMap[ImGuiKey_Escape] = GLFW_KEY_ESCAPE; + io.KeyMap[ImGuiKey_A] = GLFW_KEY_A; + io.KeyMap[ImGuiKey_C] = GLFW_KEY_C; + io.KeyMap[ImGuiKey_V] = GLFW_KEY_V; + io.KeyMap[ImGuiKey_X] = GLFW_KEY_X; + io.KeyMap[ImGuiKey_Y] = GLFW_KEY_Y; + io.KeyMap[ImGuiKey_Z] = GLFW_KEY_Z; + + io.RenderDrawListsFn = ImGui_ImplGlfw_RenderDrawLists; // Alternatively you can set this to NULL and call ImGui::GetDrawData() after ImGui::Render() to get the same ImDrawData pointer. + io.SetClipboardTextFn = ImGui_ImplGlfw_SetClipboardText; + io.GetClipboardTextFn = ImGui_ImplGlfw_GetClipboardText; +#ifdef _WIN32 + io.ImeWindowHandle = glfwGetWin32Window(g_Window); +#endif + + if (install_callbacks) + { + glfwSetMouseButtonCallback(window, ImGui_ImplGlfw_MouseButtonCallback); + glfwSetScrollCallback(window, ImGui_ImplGlfw_ScrollCallback); + glfwSetKeyCallback(window, ImGui_ImplGlFw_KeyCallback); + glfwSetCharCallback(window, ImGui_ImplGlfw_CharCallback); + } + + return true; +} + +void ImGui_ImplGlfw_Shutdown() +{ + ImGui_ImplGlfw_InvalidateDeviceObjects(); + ImGui::Shutdown(); +} + +void ImGui_ImplGlfw_NewFrame() +{ + if (!g_FontTexture) + ImGui_ImplGlfw_CreateDeviceObjects(); + + ImGuiIO& io = ImGui::GetIO(); + + // Setup display size (every frame to accommodate for window resizing) + int w, h; + int display_w, display_h; + glfwGetWindowSize(g_Window, &w, &h); + glfwGetFramebufferSize(g_Window, &display_w, &display_h); + io.DisplaySize = ImVec2((float)w, (float)h); + io.DisplayFramebufferScale = ImVec2(w > 0 ? ((float)display_w / w) : 0, h > 0 ? ((float)display_h / h) : 0); + + // Setup time step + double current_time = glfwGetTime(); + io.DeltaTime = g_Time > 0.0 ? (float)(current_time - g_Time) : (float)(1.0f/60.0f); + g_Time = current_time; + + // Setup inputs + // (we already got mouse wheel, keyboard keys & characters from glfw callbacks polled in glfwPollEvents()) + if (glfwGetWindowAttrib(g_Window, GLFW_FOCUSED)) + { + double mouse_x, mouse_y; + glfwGetCursorPos(g_Window, &mouse_x, &mouse_y); + io.MousePos = ImVec2((float)mouse_x, (float)mouse_y); // Mouse position in screen coordinates (set to -1,-1 if no mouse / on another screen, etc.) + } + else + { + io.MousePos = ImVec2(-1,-1); + } + + for (int i = 0; i < 3; i++) + { + io.MouseDown[i] = g_MousePressed[i] || glfwGetMouseButton(g_Window, i) != 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. + g_MousePressed[i] = false; + } + + io.MouseWheel = g_MouseWheel; + g_MouseWheel = 0.0f; + + // Hide OS mouse cursor if ImGui is drawing it + glfwSetInputMode(g_Window, GLFW_CURSOR, io.MouseDrawCursor ? GLFW_CURSOR_HIDDEN : GLFW_CURSOR_NORMAL); + + // Start the frame + ImGui::NewFrame(); +} diff --git a/examples/opengl2_example/imgui_impl_glfw.h b/examples/opengl2_example/imgui_impl_glfw.h new file mode 100644 index 0000000..07dd96f --- /dev/null +++ b/examples/opengl2_example/imgui_impl_glfw.h @@ -0,0 +1,29 @@ +// ImGui GLFW binding with OpenGL +// In this binding, ImTextureID is used to store an OpenGL 'GLuint' texture identifier. Read the FAQ about ImTextureID in imgui.cpp. + +// If your context is GL3/GL3 then prefer using the code in opengl3_example. +// You *might* use this code with a GL3/GL4 context but make sure you disable the programmable pipeline by calling "glUseProgram(0)" before ImGui::Render(). +// We cannot do that from GL2 code because the function doesn't exist. + +// You can copy and use unmodified imgui_impl_* files in your project. See main.cpp for an example of using this. +// If you use this binding you'll need to call 4 functions: ImGui_ImplXXXX_Init(), ImGui_ImplXXXX_NewFrame(), ImGui::Render() and ImGui_ImplXXXX_Shutdown(). +// If you are new to ImGui, see examples/README.txt and documentation at the top of imgui.cpp. +// https://github.com/ocornut/imgui + +struct GLFWwindow; + +IMGUI_API bool ImGui_ImplGlfw_Init(GLFWwindow* window, bool install_callbacks); +IMGUI_API void ImGui_ImplGlfw_Shutdown(); +IMGUI_API void ImGui_ImplGlfw_NewFrame(); + +// Use if you want to reset your rendering device without losing ImGui state. +IMGUI_API void ImGui_ImplGlfw_InvalidateDeviceObjects(); +IMGUI_API bool ImGui_ImplGlfw_CreateDeviceObjects(); + +// GLFW callbacks (installed by default if you enable 'install_callbacks' during initialization) +// Provided here if you want to chain callbacks. +// You can also handle inputs yourself and use those as a reference. +IMGUI_API void ImGui_ImplGlfw_MouseButtonCallback(GLFWwindow* window, int button, int action, int mods); +IMGUI_API void ImGui_ImplGlfw_ScrollCallback(GLFWwindow* window, double xoffset, double yoffset); +IMGUI_API void ImGui_ImplGlFw_KeyCallback(GLFWwindow* window, int key, int scancode, int action, int mods); +IMGUI_API void ImGui_ImplGlfw_CharCallback(GLFWwindow* window, unsigned int c); diff --git a/examples/opengl2_example/main.cpp b/examples/opengl2_example/main.cpp new file mode 100644 index 0000000..a844db5 --- /dev/null +++ b/examples/opengl2_example/main.cpp @@ -0,0 +1,89 @@ +// ImGui - standalone example application for Glfw + OpenGL 2, using fixed pipeline +// If you are new to ImGui, see examples/README.txt and documentation at the top of imgui.cpp. + +#include +#include "imgui_impl_glfw.h" +#include +#include + +static void error_callback(int error, const char* description) +{ + fprintf(stderr, "Error %d: %s\n", error, description); +} + +int main(int, char**) +{ + // Setup window + glfwSetErrorCallback(error_callback); + if (!glfwInit()) + return 1; + GLFWwindow* window = glfwCreateWindow(1280, 720, "ImGui OpenGL2 example", NULL, NULL); + glfwMakeContextCurrent(window); + + // Setup ImGui binding + ImGui_ImplGlfw_Init(window, true); + + // Load Fonts + // (there is a default font, this is only if you want to change it. see extra_fonts/README.txt for more details) + //ImGuiIO& io = ImGui::GetIO(); + //io.Fonts->AddFontDefault(); + //io.Fonts->AddFontFromFileTTF("../../extra_fonts/Cousine-Regular.ttf", 15.0f); + //io.Fonts->AddFontFromFileTTF("../../extra_fonts/DroidSans.ttf", 16.0f); + //io.Fonts->AddFontFromFileTTF("../../extra_fonts/ProggyClean.ttf", 13.0f); + //io.Fonts->AddFontFromFileTTF("../../extra_fonts/ProggyTiny.ttf", 10.0f); + //io.Fonts->AddFontFromFileTTF("c:\\Windows\\Fonts\\ArialUni.ttf", 18.0f, NULL, io.Fonts->GetGlyphRangesJapanese()); + + bool show_test_window = true; + bool show_another_window = false; + ImVec4 clear_color = ImColor(114, 144, 154); + + // Main loop + while (!glfwWindowShouldClose(window)) + { + glfwPollEvents(); + ImGui_ImplGlfw_NewFrame(); + + // 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 = 0.0f; + ImGui::Text("Hello, world!"); + ImGui::SliderFloat("float", &f, 0.0f, 1.0f); + ImGui::ColorEdit3("clear color", (float*)&clear_color); + if (ImGui::Button("Test Window")) show_test_window ^= 1; + if (ImGui::Button("Another Window")) show_another_window ^= 1; + ImGui::Text("Application average %.3f ms/frame (%.1f FPS)", 1000.0f / ImGui::GetIO().Framerate, ImGui::GetIO().Framerate); + } + + // 2. Show another simple window, this time using an explicit Begin/End pair + if (show_another_window) + { + ImGui::SetNextWindowSize(ImVec2(200,100), ImGuiSetCond_FirstUseEver); + ImGui::Begin("Another Window", &show_another_window); + 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::SetNextWindowPos(ImVec2(650, 20), ImGuiSetCond_FirstUseEver); + ImGui::ShowTestWindow(&show_test_window); + } + + // Rendering + int display_w, display_h; + glfwGetFramebufferSize(window, &display_w, &display_h); + glViewport(0, 0, display_w, display_h); + glClearColor(clear_color.x, clear_color.y, clear_color.z, clear_color.w); + glClear(GL_COLOR_BUFFER_BIT); + ImGui::Render(); + glfwSwapBuffers(window); + } + + // Cleanup + ImGui_ImplGlfw_Shutdown(); + glfwTerminate(); + + return 0; +} diff --git a/examples/opengl2_example/opengl_example.vcxproj b/examples/opengl2_example/opengl_example.vcxproj new file mode 100644 index 0000000..4b354b6 --- /dev/null +++ b/examples/opengl2_example/opengl_example.vcxproj @@ -0,0 +1,169 @@ + + + + + Debug + Win32 + + + Debug + x64 + + + Release + Win32 + + + Release + x64 + + + + {9CDA7840-B7A5-496D-A527-E95571496D18} + opengl_example + + + + Application + true + MultiByte + + + Application + true + MultiByte + + + Application + false + true + MultiByte + + + Application + false + true + MultiByte + + + + + + + + + + + + + + + + + + + $(ProjectDir)$(Configuration)\ + $(ProjectDir)$(Configuration)\ + $(IncludePath) + + + $(ProjectDir)$(Configuration)\ + $(ProjectDir)$(Configuration)\ + $(IncludePath) + + + $(ProjectDir)$(Configuration)\ + $(ProjectDir)$(Configuration)\ + $(IncludePath) + + + $(ProjectDir)$(Configuration)\ + $(ProjectDir)$(Configuration)\ + $(IncludePath) + + + + Level4 + Disabled + $(SolutionDir)\libs\glfw\include;..\..;%(AdditionalIncludeDirectories) + + + true + $(SolutionDir)\libs\glfw\lib-vc2010-32;%(AdditionalLibraryDirectories) + opengl32.lib;glfw3.lib;%(AdditionalDependencies) + Console + msvcrt.lib + + + + + Level4 + Disabled + $(SolutionDir)\libs\glfw\include;..\..;%(AdditionalIncludeDirectories) + + + true + $(SolutionDir)\libs\glfw\lib-vc2010-64;%(AdditionalLibraryDirectories) + opengl32.lib;glfw3.lib;%(AdditionalDependencies) + Console + msvcrt.lib + + + + + Level4 + MaxSpeed + true + true + $(SolutionDir)\libs\glfw\include;..\..;%(AdditionalIncludeDirectories) + + + true + true + true + $(SolutionDir)\libs\glfw\lib-vc2010-32;%(AdditionalLibraryDirectories) + opengl32.lib;glfw3.lib;%(AdditionalDependencies) + Console + + + + + + + Level4 + MaxSpeed + true + true + $(SolutionDir)\libs\glfw\include;..\..;%(AdditionalIncludeDirectories) + + + true + true + true + $(SolutionDir)\libs\glfw\lib-vc2010-64;%(AdditionalLibraryDirectories) + opengl32.lib;glfw3.lib;%(AdditionalDependencies) + Console + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/examples/opengl2_example/opengl_example.vcxproj.filters b/examples/opengl2_example/opengl_example.vcxproj.filters new file mode 100644 index 0000000..f2282bf --- /dev/null +++ b/examples/opengl2_example/opengl_example.vcxproj.filters @@ -0,0 +1,46 @@ + + + + + {c336cfe3-f0c4-464c-9ef0-a9e17a7ff222} + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx + + + + + sources + + + imgui + + + sources + + + imgui + + + imgui + + + + + imgui + + + imgui + + + sources + + + imgui + + + + + + \ No newline at end of file diff --git a/examples/opengl_example/Makefile b/examples/opengl_example/Makefile deleted file mode 100644 index 91d1b14..0000000 --- a/examples/opengl_example/Makefile +++ /dev/null @@ -1,60 +0,0 @@ -# -# Cross Platform Makefile -# Compatible with Ubuntu 14.04.1 and Mac OS X -# -# -# if you using Mac OS X: -# You'll need glfw -# http://www.glfw.org -# - -#CXX = g++ - -EXE = opengl_example -OBJS = main.o imgui_impl_glfw.o -OBJS += ../../imgui.o ../../imgui_demo.o ../../imgui_draw.o - -UNAME_S := $(shell uname -s) - - -ifeq ($(UNAME_S), Linux) #LINUX - ECHO_MESSAGE = "Linux" - LIBS = -lGL `pkg-config --static --libs glfw3` - - CXXFLAGS = -I../../ `pkg-config --cflags glfw3` - CXXFLAGS += -Wall -Wformat - CFLAGS = $(CXXFLAGS) -endif - -ifeq ($(UNAME_S), Darwin) #APPLE - ECHO_MESSAGE = "Mac OS X" - LIBS = -framework OpenGL -framework Cocoa -framework IOKit -framework CoreVideo - LIBS += -L/usr/local/lib -lglfw3 - - CXXFLAGS = -I../../ -I/usr/local/include - CXXFLAGS += -Wall -Wformat -# CXXFLAGS += -D__APPLE__ - CFLAGS = $(CXXFLAGS) -endif - -ifeq ($(UNAME_S), MINGW64_NT-6.3) - ECHO_MESSAGE = "Windows" - LIBS = -lglfw3 -lgdi32 -lopengl32 -limm32 - - CXXFLAGS = -I../../ -I../libs/gl3w `pkg-config --cflags glfw3` - CXXFLAGS += -Wall -Wformat - CFLAGS = $(CXXFLAGS) -endif - -.cpp.o: - $(CXX) $(CXXFLAGS) -c -o $@ $< - -all: $(EXE) - @echo Build complete for $(ECHO_MESSAGE) - -$(EXE): $(OBJS) - $(CXX) -o $(EXE) $(OBJS) $(CXXFLAGS) $(LIBS) - -clean: - rm $(EXE) $(OBJS) - diff --git a/examples/opengl_example/build_win32.bat b/examples/opengl_example/build_win32.bat deleted file mode 100644 index 278381c..0000000 --- a/examples/opengl_example/build_win32.bat +++ /dev/null @@ -1,3 +0,0 @@ -@REM Build for Visual Studio compiler. Run your copy of vcvars32.bat or vcvarsall.bat to setup command-line compiler. -mkdir Debug -cl /nologo /Zi /MD /I ..\.. /I ..\libs\glfw\include *.cpp ..\..\*.cpp /FeDebug/opengl_example.exe /FoDebug/ /link /LIBPATH:..\libs\glfw\lib-vc2010-32 glfw3.lib opengl32.lib gdi32.lib shell32.lib diff --git a/examples/opengl_example/imgui_impl_glfw.cpp b/examples/opengl_example/imgui_impl_glfw.cpp deleted file mode 100644 index 2d1f5c1..0000000 --- a/examples/opengl_example/imgui_impl_glfw.cpp +++ /dev/null @@ -1,288 +0,0 @@ -// ImGui GLFW binding with OpenGL -// In this binding, ImTextureID is used to store an OpenGL 'GLuint' texture identifier. Read the FAQ about ImTextureID in imgui.cpp. - -// If your context is GL3/GL3 then prefer using the code in opengl3_example. -// You *might* use this code with a GL3/GL4 context but make sure you disable the programmable pipeline by calling "glUseProgram(0)" before ImGui::Render(). -// We cannot do that from GL2 code because the function doesn't exist. - -// You can copy and use unmodified imgui_impl_* files in your project. See main.cpp for an example of using this. -// If you use this binding you'll need to call 4 functions: ImGui_ImplXXXX_Init(), ImGui_ImplXXXX_NewFrame(), ImGui::Render() and ImGui_ImplXXXX_Shutdown(). -// If you are new to ImGui, see examples/README.txt and documentation at the top of imgui.cpp. -// https://github.com/ocornut/imgui - -#include -#include "imgui_impl_glfw.h" - -// GLFW -#include -#ifdef _WIN32 -#undef APIENTRY -#define GLFW_EXPOSE_NATIVE_WIN32 -#define GLFW_EXPOSE_NATIVE_WGL -#include -#endif - -// Data -static GLFWwindow* g_Window = NULL; -static double g_Time = 0.0f; -static bool g_MousePressed[3] = { false, false, false }; -static float g_MouseWheel = 0.0f; -static GLuint g_FontTexture = 0; - -// 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) -void ImGui_ImplGlfw_RenderDrawLists(ImDrawData* draw_data) -{ - // Avoid rendering when minimized, scale coordinates for retina displays (screen coordinates != framebuffer coordinates) - ImGuiIO& io = ImGui::GetIO(); - int fb_width = (int)(io.DisplaySize.x * io.DisplayFramebufferScale.x); - int fb_height = (int)(io.DisplaySize.y * io.DisplayFramebufferScale.y); - if (fb_width == 0 || fb_height == 0) - return; - draw_data->ScaleClipRects(io.DisplayFramebufferScale); - - // We are using the OpenGL fixed pipeline to make the example code simpler to read! - // Setup render state: alpha-blending enabled, no face culling, no depth testing, scissor enabled, vertex/texcoord/color pointers. - GLint last_texture; glGetIntegerv(GL_TEXTURE_BINDING_2D, &last_texture); - GLint last_viewport[4]; glGetIntegerv(GL_VIEWPORT, last_viewport); - glPushAttrib(GL_ENABLE_BIT | GL_COLOR_BUFFER_BIT | GL_TRANSFORM_BIT); - glEnable(GL_BLEND); - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - glDisable(GL_CULL_FACE); - glDisable(GL_DEPTH_TEST); - glEnable(GL_SCISSOR_TEST); - glEnableClientState(GL_VERTEX_ARRAY); - glEnableClientState(GL_TEXTURE_COORD_ARRAY); - glEnableClientState(GL_COLOR_ARRAY); - glEnable(GL_TEXTURE_2D); - //glUseProgram(0); // You may want this if using this code in an OpenGL 3+ context - - // Setup viewport, orthographic projection matrix - glViewport(0, 0, (GLsizei)fb_width, (GLsizei)fb_height); - glMatrixMode(GL_PROJECTION); - glPushMatrix(); - glLoadIdentity(); - glOrtho(0.0f, io.DisplaySize.x, io.DisplaySize.y, 0.0f, -1.0f, +1.0f); - glMatrixMode(GL_MODELVIEW); - glPushMatrix(); - glLoadIdentity(); - - // Render command lists - #define OFFSETOF(TYPE, ELEMENT) ((size_t)&(((TYPE *)0)->ELEMENT)) - for (int n = 0; n < draw_data->CmdListsCount; n++) - { - const ImDrawList* cmd_list = draw_data->CmdLists[n]; - const unsigned char* vtx_buffer = (const unsigned char*)&cmd_list->VtxBuffer.front(); - const ImDrawIdx* idx_buffer = &cmd_list->IdxBuffer.front(); - glVertexPointer(2, GL_FLOAT, sizeof(ImDrawVert), (void*)(vtx_buffer + OFFSETOF(ImDrawVert, pos))); - glTexCoordPointer(2, GL_FLOAT, sizeof(ImDrawVert), (void*)(vtx_buffer + OFFSETOF(ImDrawVert, uv))); - glColorPointer(4, GL_UNSIGNED_BYTE, sizeof(ImDrawVert), (void*)(vtx_buffer + OFFSETOF(ImDrawVert, col))); - - for (int cmd_i = 0; cmd_i < cmd_list->CmdBuffer.size(); cmd_i++) - { - const ImDrawCmd* pcmd = &cmd_list->CmdBuffer[cmd_i]; - if (pcmd->UserCallback) - { - pcmd->UserCallback(cmd_list, pcmd); - } - else - { - glBindTexture(GL_TEXTURE_2D, (GLuint)(intptr_t)pcmd->TextureId); - glScissor((int)pcmd->ClipRect.x, (int)(fb_height - pcmd->ClipRect.w), (int)(pcmd->ClipRect.z - pcmd->ClipRect.x), (int)(pcmd->ClipRect.w - pcmd->ClipRect.y)); - glDrawElements(GL_TRIANGLES, (GLsizei)pcmd->ElemCount, sizeof(ImDrawIdx) == 2 ? GL_UNSIGNED_SHORT : GL_UNSIGNED_INT, idx_buffer); - } - idx_buffer += pcmd->ElemCount; - } - } - #undef OFFSETOF - - // Restore modified state - glDisableClientState(GL_COLOR_ARRAY); - glDisableClientState(GL_TEXTURE_COORD_ARRAY); - glDisableClientState(GL_VERTEX_ARRAY); - glBindTexture(GL_TEXTURE_2D, (GLuint)last_texture); - glMatrixMode(GL_MODELVIEW); - glPopMatrix(); - glMatrixMode(GL_PROJECTION); - glPopMatrix(); - glPopAttrib(); - glViewport(last_viewport[0], last_viewport[1], (GLsizei)last_viewport[2], (GLsizei)last_viewport[3]); -} - -static const char* ImGui_ImplGlfw_GetClipboardText() -{ - return glfwGetClipboardString(g_Window); -} - -static void ImGui_ImplGlfw_SetClipboardText(const char* text) -{ - glfwSetClipboardString(g_Window, text); -} - -void ImGui_ImplGlfw_MouseButtonCallback(GLFWwindow*, int button, int action, int /*mods*/) -{ - if (action == GLFW_PRESS && button >= 0 && button < 3) - g_MousePressed[button] = true; -} - -void ImGui_ImplGlfw_ScrollCallback(GLFWwindow*, double /*xoffset*/, double yoffset) -{ - g_MouseWheel += (float)yoffset; // Use fractional mouse wheel, 1.0 unit 5 lines. -} - -void ImGui_ImplGlFw_KeyCallback(GLFWwindow*, int key, int, int action, int mods) -{ - ImGuiIO& io = ImGui::GetIO(); - if (action == GLFW_PRESS) - io.KeysDown[key] = true; - if (action == GLFW_RELEASE) - io.KeysDown[key] = false; - - (void)mods; // Modifiers are not reliable across systems - io.KeyCtrl = io.KeysDown[GLFW_KEY_LEFT_CONTROL] || io.KeysDown[GLFW_KEY_RIGHT_CONTROL]; - io.KeyShift = io.KeysDown[GLFW_KEY_LEFT_SHIFT] || io.KeysDown[GLFW_KEY_RIGHT_SHIFT]; - io.KeyAlt = io.KeysDown[GLFW_KEY_LEFT_ALT] || io.KeysDown[GLFW_KEY_RIGHT_ALT]; - io.KeySuper = io.KeysDown[GLFW_KEY_LEFT_SUPER] || io.KeysDown[GLFW_KEY_RIGHT_SUPER]; -} - -void ImGui_ImplGlfw_CharCallback(GLFWwindow*, unsigned int c) -{ - ImGuiIO& io = ImGui::GetIO(); - if (c > 0 && c < 0x10000) - io.AddInputCharacter((unsigned short)c); -} - -bool ImGui_ImplGlfw_CreateDeviceObjects() -{ - // Build texture atlas - ImGuiIO& io = ImGui::GetIO(); - unsigned char* pixels; - int width, height; - io.Fonts->GetTexDataAsAlpha8(&pixels, &width, &height); - - // Upload texture to graphics system - GLint last_texture; - glGetIntegerv(GL_TEXTURE_BINDING_2D, &last_texture); - glGenTextures(1, &g_FontTexture); - glBindTexture(GL_TEXTURE_2D, g_FontTexture); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, width, height, 0, GL_ALPHA, GL_UNSIGNED_BYTE, pixels); - - // Store our identifier - io.Fonts->TexID = (void *)(intptr_t)g_FontTexture; - - // Restore state - glBindTexture(GL_TEXTURE_2D, last_texture); - - return true; -} - -void ImGui_ImplGlfw_InvalidateDeviceObjects() -{ - if (g_FontTexture) - { - glDeleteTextures(1, &g_FontTexture); - ImGui::GetIO().Fonts->TexID = 0; - g_FontTexture = 0; - } -} - -bool ImGui_ImplGlfw_Init(GLFWwindow* window, bool install_callbacks) -{ - g_Window = window; - - ImGuiIO& io = ImGui::GetIO(); - 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; - io.KeyMap[ImGuiKey_DownArrow] = GLFW_KEY_DOWN; - io.KeyMap[ImGuiKey_PageUp] = GLFW_KEY_PAGE_UP; - io.KeyMap[ImGuiKey_PageDown] = GLFW_KEY_PAGE_DOWN; - io.KeyMap[ImGuiKey_Home] = GLFW_KEY_HOME; - io.KeyMap[ImGuiKey_End] = GLFW_KEY_END; - io.KeyMap[ImGuiKey_Delete] = GLFW_KEY_DELETE; - io.KeyMap[ImGuiKey_Backspace] = GLFW_KEY_BACKSPACE; - io.KeyMap[ImGuiKey_Enter] = GLFW_KEY_ENTER; - io.KeyMap[ImGuiKey_Escape] = GLFW_KEY_ESCAPE; - io.KeyMap[ImGuiKey_A] = GLFW_KEY_A; - io.KeyMap[ImGuiKey_C] = GLFW_KEY_C; - io.KeyMap[ImGuiKey_V] = GLFW_KEY_V; - io.KeyMap[ImGuiKey_X] = GLFW_KEY_X; - io.KeyMap[ImGuiKey_Y] = GLFW_KEY_Y; - io.KeyMap[ImGuiKey_Z] = GLFW_KEY_Z; - - io.RenderDrawListsFn = ImGui_ImplGlfw_RenderDrawLists; // Alternatively you can set this to NULL and call ImGui::GetDrawData() after ImGui::Render() to get the same ImDrawData pointer. - io.SetClipboardTextFn = ImGui_ImplGlfw_SetClipboardText; - io.GetClipboardTextFn = ImGui_ImplGlfw_GetClipboardText; -#ifdef _WIN32 - io.ImeWindowHandle = glfwGetWin32Window(g_Window); -#endif - - if (install_callbacks) - { - glfwSetMouseButtonCallback(window, ImGui_ImplGlfw_MouseButtonCallback); - glfwSetScrollCallback(window, ImGui_ImplGlfw_ScrollCallback); - glfwSetKeyCallback(window, ImGui_ImplGlFw_KeyCallback); - glfwSetCharCallback(window, ImGui_ImplGlfw_CharCallback); - } - - return true; -} - -void ImGui_ImplGlfw_Shutdown() -{ - ImGui_ImplGlfw_InvalidateDeviceObjects(); - ImGui::Shutdown(); -} - -void ImGui_ImplGlfw_NewFrame() -{ - if (!g_FontTexture) - ImGui_ImplGlfw_CreateDeviceObjects(); - - ImGuiIO& io = ImGui::GetIO(); - - // Setup display size (every frame to accommodate for window resizing) - int w, h; - int display_w, display_h; - glfwGetWindowSize(g_Window, &w, &h); - glfwGetFramebufferSize(g_Window, &display_w, &display_h); - io.DisplaySize = ImVec2((float)w, (float)h); - io.DisplayFramebufferScale = ImVec2(w > 0 ? ((float)display_w / w) : 0, h > 0 ? ((float)display_h / h) : 0); - - // Setup time step - double current_time = glfwGetTime(); - io.DeltaTime = g_Time > 0.0 ? (float)(current_time - g_Time) : (float)(1.0f/60.0f); - g_Time = current_time; - - // Setup inputs - // (we already got mouse wheel, keyboard keys & characters from glfw callbacks polled in glfwPollEvents()) - if (glfwGetWindowAttrib(g_Window, GLFW_FOCUSED)) - { - double mouse_x, mouse_y; - glfwGetCursorPos(g_Window, &mouse_x, &mouse_y); - io.MousePos = ImVec2((float)mouse_x, (float)mouse_y); // Mouse position in screen coordinates (set to -1,-1 if no mouse / on another screen, etc.) - } - else - { - io.MousePos = ImVec2(-1,-1); - } - - for (int i = 0; i < 3; i++) - { - io.MouseDown[i] = g_MousePressed[i] || glfwGetMouseButton(g_Window, i) != 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. - g_MousePressed[i] = false; - } - - io.MouseWheel = g_MouseWheel; - g_MouseWheel = 0.0f; - - // Hide OS mouse cursor if ImGui is drawing it - glfwSetInputMode(g_Window, GLFW_CURSOR, io.MouseDrawCursor ? GLFW_CURSOR_HIDDEN : GLFW_CURSOR_NORMAL); - - // Start the frame - ImGui::NewFrame(); -} diff --git a/examples/README.txt b/examples/README.txt index df2e86d..5a1c8df 100644 --- a/examples/README.txt +++ b/examples/README.txt @@ -8,11 +8,13 @@ TL;DR; - Newcomers, read 'PROGRAMMER GUIDE' in imgui.cpp for notes on how to setup ImGui in your codebase. - - Refer to 'opengl_example' to understand how the library is setup, it is the simplest one. + - Refer to 'opengl2_example' to LEARN how the library is setup, it is the simplest one. The other examples requires more boilerplate and are harder to read. + - If you are using OpenGL in your application, probably use an opengl3_xxx backend. + Mixing old fixed pipeline OpenGL2 and programmable pipeline OpenGL3+ isn't well supported by drivers. - If you are using of the backend provided here, so you can copy the imgui_impl_xxx.cpp/h files to your project and use them unmodified. - - If you have your own engine, you probably want to start from 'opengl_example' and adapt it to + - If you have your own engine, you probably want to start from one of the OpenGL example and adapt it to your engine, but you can read the other examples as well. ImGui is highly portable and only requires a few things to run: @@ -41,15 +43,14 @@ Also note that some setup or GPU drivers may be causing extra lag (possibly by enforcing triple buffering), leaving you with no option but sadness/anger (Intel GPU drivers were reported as such). -opengl_example/ - OpenGL example, using GLFW + fixed pipeline. - This is simple and should work for all OpenGL enabled applications. - Prefer following this example to learn how ImGui works! - (You can use this code in a GL3/GL4 context but make sure you disable the programmable pipeline - by calling "glUseProgram(0)" before ImGui::Render.) +opengl2_example/ + GLFW + OpenGL example (old fixed pipeline). + This is simple to read. Prefer following this example to learn how ImGui works! + (You might be able to use this code in a GL3/GL4 context but make sure you disable the programmable + pipeline by calling "glUseProgram(0)" before ImGui::Render.) opengl3_example/ - OpenGL example, using GLFW/GL3W + programmable pipeline. + GLFW + OpenGL example (programmable pipeline, binding modern functions with GL3W). This uses more modern OpenGL calls and custom shaders. It's more messy. directx9_example/ @@ -68,8 +69,8 @@ On iOS, Using Synergy to access keyboard/mouse data from server computer. Synergy keyboard integration is rather hacky. -sdl_opengl_example/ - SDL2 + OpenGL example. +sdl_opengl2_example/ + SDL2 + OpenGL example (old fixed pipeline). sdl_opengl3_example/ SDL2 + OpenGL3 example. diff --git a/examples/imgui_examples_msvc2010.sln b/examples/imgui_examples_msvc2010.sln index b7e6a25..16f0d60 100644 --- a/examples/imgui_examples_msvc2010.sln +++ b/examples/imgui_examples_msvc2010.sln @@ -1,7 +1,7 @@  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}" +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "opengl2_example", "opengl_example\opengl2_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 diff --git a/examples/opengl2_example/Makefile b/examples/opengl2_example/Makefile new file mode 100644 index 0000000..bd79d1b --- /dev/null +++ b/examples/opengl2_example/Makefile @@ -0,0 +1,60 @@ +# +# Cross Platform Makefile +# Compatible with Ubuntu 14.04.1 and Mac OS X +# +# +# if you using Mac OS X: +# You'll need glfw +# http://www.glfw.org +# + +#CXX = g++ + +EXE = opengl2_example +OBJS = main.o imgui_impl_glfw.o +OBJS += ../../imgui.o ../../imgui_demo.o ../../imgui_draw.o + +UNAME_S := $(shell uname -s) + + +ifeq ($(UNAME_S), Linux) #LINUX + ECHO_MESSAGE = "Linux" + LIBS = -lGL `pkg-config --static --libs glfw3` + + CXXFLAGS = -I../../ `pkg-config --cflags glfw3` + CXXFLAGS += -Wall -Wformat + CFLAGS = $(CXXFLAGS) +endif + +ifeq ($(UNAME_S), Darwin) #APPLE + ECHO_MESSAGE = "Mac OS X" + LIBS = -framework OpenGL -framework Cocoa -framework IOKit -framework CoreVideo + LIBS += -L/usr/local/lib -lglfw3 + + CXXFLAGS = -I../../ -I/usr/local/include + CXXFLAGS += -Wall -Wformat +# CXXFLAGS += -D__APPLE__ + CFLAGS = $(CXXFLAGS) +endif + +ifeq ($(UNAME_S), MINGW64_NT-6.3) + ECHO_MESSAGE = "Windows" + LIBS = -lglfw3 -lgdi32 -lopengl32 -limm32 + + CXXFLAGS = -I../../ -I../libs/gl3w `pkg-config --cflags glfw3` + CXXFLAGS += -Wall -Wformat + CFLAGS = $(CXXFLAGS) +endif + +.cpp.o: + $(CXX) $(CXXFLAGS) -c -o $@ $< + +all: $(EXE) + @echo Build complete for $(ECHO_MESSAGE) + +$(EXE): $(OBJS) + $(CXX) -o $(EXE) $(OBJS) $(CXXFLAGS) $(LIBS) + +clean: + rm $(EXE) $(OBJS) + diff --git a/examples/opengl2_example/build_win32.bat b/examples/opengl2_example/build_win32.bat new file mode 100644 index 0000000..278381c --- /dev/null +++ b/examples/opengl2_example/build_win32.bat @@ -0,0 +1,3 @@ +@REM Build for Visual Studio compiler. Run your copy of vcvars32.bat or vcvarsall.bat to setup command-line compiler. +mkdir Debug +cl /nologo /Zi /MD /I ..\.. /I ..\libs\glfw\include *.cpp ..\..\*.cpp /FeDebug/opengl_example.exe /FoDebug/ /link /LIBPATH:..\libs\glfw\lib-vc2010-32 glfw3.lib opengl32.lib gdi32.lib shell32.lib diff --git a/examples/opengl2_example/imgui_impl_glfw.cpp b/examples/opengl2_example/imgui_impl_glfw.cpp new file mode 100644 index 0000000..2d1f5c1 --- /dev/null +++ b/examples/opengl2_example/imgui_impl_glfw.cpp @@ -0,0 +1,288 @@ +// ImGui GLFW binding with OpenGL +// In this binding, ImTextureID is used to store an OpenGL 'GLuint' texture identifier. Read the FAQ about ImTextureID in imgui.cpp. + +// If your context is GL3/GL3 then prefer using the code in opengl3_example. +// You *might* use this code with a GL3/GL4 context but make sure you disable the programmable pipeline by calling "glUseProgram(0)" before ImGui::Render(). +// We cannot do that from GL2 code because the function doesn't exist. + +// You can copy and use unmodified imgui_impl_* files in your project. See main.cpp for an example of using this. +// If you use this binding you'll need to call 4 functions: ImGui_ImplXXXX_Init(), ImGui_ImplXXXX_NewFrame(), ImGui::Render() and ImGui_ImplXXXX_Shutdown(). +// If you are new to ImGui, see examples/README.txt and documentation at the top of imgui.cpp. +// https://github.com/ocornut/imgui + +#include +#include "imgui_impl_glfw.h" + +// GLFW +#include +#ifdef _WIN32 +#undef APIENTRY +#define GLFW_EXPOSE_NATIVE_WIN32 +#define GLFW_EXPOSE_NATIVE_WGL +#include +#endif + +// Data +static GLFWwindow* g_Window = NULL; +static double g_Time = 0.0f; +static bool g_MousePressed[3] = { false, false, false }; +static float g_MouseWheel = 0.0f; +static GLuint g_FontTexture = 0; + +// 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) +void ImGui_ImplGlfw_RenderDrawLists(ImDrawData* draw_data) +{ + // Avoid rendering when minimized, scale coordinates for retina displays (screen coordinates != framebuffer coordinates) + ImGuiIO& io = ImGui::GetIO(); + int fb_width = (int)(io.DisplaySize.x * io.DisplayFramebufferScale.x); + int fb_height = (int)(io.DisplaySize.y * io.DisplayFramebufferScale.y); + if (fb_width == 0 || fb_height == 0) + return; + draw_data->ScaleClipRects(io.DisplayFramebufferScale); + + // We are using the OpenGL fixed pipeline to make the example code simpler to read! + // Setup render state: alpha-blending enabled, no face culling, no depth testing, scissor enabled, vertex/texcoord/color pointers. + GLint last_texture; glGetIntegerv(GL_TEXTURE_BINDING_2D, &last_texture); + GLint last_viewport[4]; glGetIntegerv(GL_VIEWPORT, last_viewport); + glPushAttrib(GL_ENABLE_BIT | GL_COLOR_BUFFER_BIT | GL_TRANSFORM_BIT); + glEnable(GL_BLEND); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + glDisable(GL_CULL_FACE); + glDisable(GL_DEPTH_TEST); + glEnable(GL_SCISSOR_TEST); + glEnableClientState(GL_VERTEX_ARRAY); + glEnableClientState(GL_TEXTURE_COORD_ARRAY); + glEnableClientState(GL_COLOR_ARRAY); + glEnable(GL_TEXTURE_2D); + //glUseProgram(0); // You may want this if using this code in an OpenGL 3+ context + + // Setup viewport, orthographic projection matrix + glViewport(0, 0, (GLsizei)fb_width, (GLsizei)fb_height); + glMatrixMode(GL_PROJECTION); + glPushMatrix(); + glLoadIdentity(); + glOrtho(0.0f, io.DisplaySize.x, io.DisplaySize.y, 0.0f, -1.0f, +1.0f); + glMatrixMode(GL_MODELVIEW); + glPushMatrix(); + glLoadIdentity(); + + // Render command lists + #define OFFSETOF(TYPE, ELEMENT) ((size_t)&(((TYPE *)0)->ELEMENT)) + for (int n = 0; n < draw_data->CmdListsCount; n++) + { + const ImDrawList* cmd_list = draw_data->CmdLists[n]; + const unsigned char* vtx_buffer = (const unsigned char*)&cmd_list->VtxBuffer.front(); + const ImDrawIdx* idx_buffer = &cmd_list->IdxBuffer.front(); + glVertexPointer(2, GL_FLOAT, sizeof(ImDrawVert), (void*)(vtx_buffer + OFFSETOF(ImDrawVert, pos))); + glTexCoordPointer(2, GL_FLOAT, sizeof(ImDrawVert), (void*)(vtx_buffer + OFFSETOF(ImDrawVert, uv))); + glColorPointer(4, GL_UNSIGNED_BYTE, sizeof(ImDrawVert), (void*)(vtx_buffer + OFFSETOF(ImDrawVert, col))); + + for (int cmd_i = 0; cmd_i < cmd_list->CmdBuffer.size(); cmd_i++) + { + const ImDrawCmd* pcmd = &cmd_list->CmdBuffer[cmd_i]; + if (pcmd->UserCallback) + { + pcmd->UserCallback(cmd_list, pcmd); + } + else + { + glBindTexture(GL_TEXTURE_2D, (GLuint)(intptr_t)pcmd->TextureId); + glScissor((int)pcmd->ClipRect.x, (int)(fb_height - pcmd->ClipRect.w), (int)(pcmd->ClipRect.z - pcmd->ClipRect.x), (int)(pcmd->ClipRect.w - pcmd->ClipRect.y)); + glDrawElements(GL_TRIANGLES, (GLsizei)pcmd->ElemCount, sizeof(ImDrawIdx) == 2 ? GL_UNSIGNED_SHORT : GL_UNSIGNED_INT, idx_buffer); + } + idx_buffer += pcmd->ElemCount; + } + } + #undef OFFSETOF + + // Restore modified state + glDisableClientState(GL_COLOR_ARRAY); + glDisableClientState(GL_TEXTURE_COORD_ARRAY); + glDisableClientState(GL_VERTEX_ARRAY); + glBindTexture(GL_TEXTURE_2D, (GLuint)last_texture); + glMatrixMode(GL_MODELVIEW); + glPopMatrix(); + glMatrixMode(GL_PROJECTION); + glPopMatrix(); + glPopAttrib(); + glViewport(last_viewport[0], last_viewport[1], (GLsizei)last_viewport[2], (GLsizei)last_viewport[3]); +} + +static const char* ImGui_ImplGlfw_GetClipboardText() +{ + return glfwGetClipboardString(g_Window); +} + +static void ImGui_ImplGlfw_SetClipboardText(const char* text) +{ + glfwSetClipboardString(g_Window, text); +} + +void ImGui_ImplGlfw_MouseButtonCallback(GLFWwindow*, int button, int action, int /*mods*/) +{ + if (action == GLFW_PRESS && button >= 0 && button < 3) + g_MousePressed[button] = true; +} + +void ImGui_ImplGlfw_ScrollCallback(GLFWwindow*, double /*xoffset*/, double yoffset) +{ + g_MouseWheel += (float)yoffset; // Use fractional mouse wheel, 1.0 unit 5 lines. +} + +void ImGui_ImplGlFw_KeyCallback(GLFWwindow*, int key, int, int action, int mods) +{ + ImGuiIO& io = ImGui::GetIO(); + if (action == GLFW_PRESS) + io.KeysDown[key] = true; + if (action == GLFW_RELEASE) + io.KeysDown[key] = false; + + (void)mods; // Modifiers are not reliable across systems + io.KeyCtrl = io.KeysDown[GLFW_KEY_LEFT_CONTROL] || io.KeysDown[GLFW_KEY_RIGHT_CONTROL]; + io.KeyShift = io.KeysDown[GLFW_KEY_LEFT_SHIFT] || io.KeysDown[GLFW_KEY_RIGHT_SHIFT]; + io.KeyAlt = io.KeysDown[GLFW_KEY_LEFT_ALT] || io.KeysDown[GLFW_KEY_RIGHT_ALT]; + io.KeySuper = io.KeysDown[GLFW_KEY_LEFT_SUPER] || io.KeysDown[GLFW_KEY_RIGHT_SUPER]; +} + +void ImGui_ImplGlfw_CharCallback(GLFWwindow*, unsigned int c) +{ + ImGuiIO& io = ImGui::GetIO(); + if (c > 0 && c < 0x10000) + io.AddInputCharacter((unsigned short)c); +} + +bool ImGui_ImplGlfw_CreateDeviceObjects() +{ + // Build texture atlas + ImGuiIO& io = ImGui::GetIO(); + unsigned char* pixels; + int width, height; + io.Fonts->GetTexDataAsAlpha8(&pixels, &width, &height); + + // Upload texture to graphics system + GLint last_texture; + glGetIntegerv(GL_TEXTURE_BINDING_2D, &last_texture); + glGenTextures(1, &g_FontTexture); + glBindTexture(GL_TEXTURE_2D, g_FontTexture); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, width, height, 0, GL_ALPHA, GL_UNSIGNED_BYTE, pixels); + + // Store our identifier + io.Fonts->TexID = (void *)(intptr_t)g_FontTexture; + + // Restore state + glBindTexture(GL_TEXTURE_2D, last_texture); + + return true; +} + +void ImGui_ImplGlfw_InvalidateDeviceObjects() +{ + if (g_FontTexture) + { + glDeleteTextures(1, &g_FontTexture); + ImGui::GetIO().Fonts->TexID = 0; + g_FontTexture = 0; + } +} + +bool ImGui_ImplGlfw_Init(GLFWwindow* window, bool install_callbacks) +{ + g_Window = window; + + ImGuiIO& io = ImGui::GetIO(); + 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; + io.KeyMap[ImGuiKey_DownArrow] = GLFW_KEY_DOWN; + io.KeyMap[ImGuiKey_PageUp] = GLFW_KEY_PAGE_UP; + io.KeyMap[ImGuiKey_PageDown] = GLFW_KEY_PAGE_DOWN; + io.KeyMap[ImGuiKey_Home] = GLFW_KEY_HOME; + io.KeyMap[ImGuiKey_End] = GLFW_KEY_END; + io.KeyMap[ImGuiKey_Delete] = GLFW_KEY_DELETE; + io.KeyMap[ImGuiKey_Backspace] = GLFW_KEY_BACKSPACE; + io.KeyMap[ImGuiKey_Enter] = GLFW_KEY_ENTER; + io.KeyMap[ImGuiKey_Escape] = GLFW_KEY_ESCAPE; + io.KeyMap[ImGuiKey_A] = GLFW_KEY_A; + io.KeyMap[ImGuiKey_C] = GLFW_KEY_C; + io.KeyMap[ImGuiKey_V] = GLFW_KEY_V; + io.KeyMap[ImGuiKey_X] = GLFW_KEY_X; + io.KeyMap[ImGuiKey_Y] = GLFW_KEY_Y; + io.KeyMap[ImGuiKey_Z] = GLFW_KEY_Z; + + io.RenderDrawListsFn = ImGui_ImplGlfw_RenderDrawLists; // Alternatively you can set this to NULL and call ImGui::GetDrawData() after ImGui::Render() to get the same ImDrawData pointer. + io.SetClipboardTextFn = ImGui_ImplGlfw_SetClipboardText; + io.GetClipboardTextFn = ImGui_ImplGlfw_GetClipboardText; +#ifdef _WIN32 + io.ImeWindowHandle = glfwGetWin32Window(g_Window); +#endif + + if (install_callbacks) + { + glfwSetMouseButtonCallback(window, ImGui_ImplGlfw_MouseButtonCallback); + glfwSetScrollCallback(window, ImGui_ImplGlfw_ScrollCallback); + glfwSetKeyCallback(window, ImGui_ImplGlFw_KeyCallback); + glfwSetCharCallback(window, ImGui_ImplGlfw_CharCallback); + } + + return true; +} + +void ImGui_ImplGlfw_Shutdown() +{ + ImGui_ImplGlfw_InvalidateDeviceObjects(); + ImGui::Shutdown(); +} + +void ImGui_ImplGlfw_NewFrame() +{ + if (!g_FontTexture) + ImGui_ImplGlfw_CreateDeviceObjects(); + + ImGuiIO& io = ImGui::GetIO(); + + // Setup display size (every frame to accommodate for window resizing) + int w, h; + int display_w, display_h; + glfwGetWindowSize(g_Window, &w, &h); + glfwGetFramebufferSize(g_Window, &display_w, &display_h); + io.DisplaySize = ImVec2((float)w, (float)h); + io.DisplayFramebufferScale = ImVec2(w > 0 ? ((float)display_w / w) : 0, h > 0 ? ((float)display_h / h) : 0); + + // Setup time step + double current_time = glfwGetTime(); + io.DeltaTime = g_Time > 0.0 ? (float)(current_time - g_Time) : (float)(1.0f/60.0f); + g_Time = current_time; + + // Setup inputs + // (we already got mouse wheel, keyboard keys & characters from glfw callbacks polled in glfwPollEvents()) + if (glfwGetWindowAttrib(g_Window, GLFW_FOCUSED)) + { + double mouse_x, mouse_y; + glfwGetCursorPos(g_Window, &mouse_x, &mouse_y); + io.MousePos = ImVec2((float)mouse_x, (float)mouse_y); // Mouse position in screen coordinates (set to -1,-1 if no mouse / on another screen, etc.) + } + else + { + io.MousePos = ImVec2(-1,-1); + } + + for (int i = 0; i < 3; i++) + { + io.MouseDown[i] = g_MousePressed[i] || glfwGetMouseButton(g_Window, i) != 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. + g_MousePressed[i] = false; + } + + io.MouseWheel = g_MouseWheel; + g_MouseWheel = 0.0f; + + // Hide OS mouse cursor if ImGui is drawing it + glfwSetInputMode(g_Window, GLFW_CURSOR, io.MouseDrawCursor ? GLFW_CURSOR_HIDDEN : GLFW_CURSOR_NORMAL); + + // Start the frame + ImGui::NewFrame(); +} diff --git a/examples/opengl2_example/imgui_impl_glfw.h b/examples/opengl2_example/imgui_impl_glfw.h new file mode 100644 index 0000000..07dd96f --- /dev/null +++ b/examples/opengl2_example/imgui_impl_glfw.h @@ -0,0 +1,29 @@ +// ImGui GLFW binding with OpenGL +// In this binding, ImTextureID is used to store an OpenGL 'GLuint' texture identifier. Read the FAQ about ImTextureID in imgui.cpp. + +// If your context is GL3/GL3 then prefer using the code in opengl3_example. +// You *might* use this code with a GL3/GL4 context but make sure you disable the programmable pipeline by calling "glUseProgram(0)" before ImGui::Render(). +// We cannot do that from GL2 code because the function doesn't exist. + +// You can copy and use unmodified imgui_impl_* files in your project. See main.cpp for an example of using this. +// If you use this binding you'll need to call 4 functions: ImGui_ImplXXXX_Init(), ImGui_ImplXXXX_NewFrame(), ImGui::Render() and ImGui_ImplXXXX_Shutdown(). +// If you are new to ImGui, see examples/README.txt and documentation at the top of imgui.cpp. +// https://github.com/ocornut/imgui + +struct GLFWwindow; + +IMGUI_API bool ImGui_ImplGlfw_Init(GLFWwindow* window, bool install_callbacks); +IMGUI_API void ImGui_ImplGlfw_Shutdown(); +IMGUI_API void ImGui_ImplGlfw_NewFrame(); + +// Use if you want to reset your rendering device without losing ImGui state. +IMGUI_API void ImGui_ImplGlfw_InvalidateDeviceObjects(); +IMGUI_API bool ImGui_ImplGlfw_CreateDeviceObjects(); + +// GLFW callbacks (installed by default if you enable 'install_callbacks' during initialization) +// Provided here if you want to chain callbacks. +// You can also handle inputs yourself and use those as a reference. +IMGUI_API void ImGui_ImplGlfw_MouseButtonCallback(GLFWwindow* window, int button, int action, int mods); +IMGUI_API void ImGui_ImplGlfw_ScrollCallback(GLFWwindow* window, double xoffset, double yoffset); +IMGUI_API void ImGui_ImplGlFw_KeyCallback(GLFWwindow* window, int key, int scancode, int action, int mods); +IMGUI_API void ImGui_ImplGlfw_CharCallback(GLFWwindow* window, unsigned int c); diff --git a/examples/opengl2_example/main.cpp b/examples/opengl2_example/main.cpp new file mode 100644 index 0000000..a844db5 --- /dev/null +++ b/examples/opengl2_example/main.cpp @@ -0,0 +1,89 @@ +// ImGui - standalone example application for Glfw + OpenGL 2, using fixed pipeline +// If you are new to ImGui, see examples/README.txt and documentation at the top of imgui.cpp. + +#include +#include "imgui_impl_glfw.h" +#include +#include + +static void error_callback(int error, const char* description) +{ + fprintf(stderr, "Error %d: %s\n", error, description); +} + +int main(int, char**) +{ + // Setup window + glfwSetErrorCallback(error_callback); + if (!glfwInit()) + return 1; + GLFWwindow* window = glfwCreateWindow(1280, 720, "ImGui OpenGL2 example", NULL, NULL); + glfwMakeContextCurrent(window); + + // Setup ImGui binding + ImGui_ImplGlfw_Init(window, true); + + // Load Fonts + // (there is a default font, this is only if you want to change it. see extra_fonts/README.txt for more details) + //ImGuiIO& io = ImGui::GetIO(); + //io.Fonts->AddFontDefault(); + //io.Fonts->AddFontFromFileTTF("../../extra_fonts/Cousine-Regular.ttf", 15.0f); + //io.Fonts->AddFontFromFileTTF("../../extra_fonts/DroidSans.ttf", 16.0f); + //io.Fonts->AddFontFromFileTTF("../../extra_fonts/ProggyClean.ttf", 13.0f); + //io.Fonts->AddFontFromFileTTF("../../extra_fonts/ProggyTiny.ttf", 10.0f); + //io.Fonts->AddFontFromFileTTF("c:\\Windows\\Fonts\\ArialUni.ttf", 18.0f, NULL, io.Fonts->GetGlyphRangesJapanese()); + + bool show_test_window = true; + bool show_another_window = false; + ImVec4 clear_color = ImColor(114, 144, 154); + + // Main loop + while (!glfwWindowShouldClose(window)) + { + glfwPollEvents(); + ImGui_ImplGlfw_NewFrame(); + + // 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 = 0.0f; + ImGui::Text("Hello, world!"); + ImGui::SliderFloat("float", &f, 0.0f, 1.0f); + ImGui::ColorEdit3("clear color", (float*)&clear_color); + if (ImGui::Button("Test Window")) show_test_window ^= 1; + if (ImGui::Button("Another Window")) show_another_window ^= 1; + ImGui::Text("Application average %.3f ms/frame (%.1f FPS)", 1000.0f / ImGui::GetIO().Framerate, ImGui::GetIO().Framerate); + } + + // 2. Show another simple window, this time using an explicit Begin/End pair + if (show_another_window) + { + ImGui::SetNextWindowSize(ImVec2(200,100), ImGuiSetCond_FirstUseEver); + ImGui::Begin("Another Window", &show_another_window); + 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::SetNextWindowPos(ImVec2(650, 20), ImGuiSetCond_FirstUseEver); + ImGui::ShowTestWindow(&show_test_window); + } + + // Rendering + int display_w, display_h; + glfwGetFramebufferSize(window, &display_w, &display_h); + glViewport(0, 0, display_w, display_h); + glClearColor(clear_color.x, clear_color.y, clear_color.z, clear_color.w); + glClear(GL_COLOR_BUFFER_BIT); + ImGui::Render(); + glfwSwapBuffers(window); + } + + // Cleanup + ImGui_ImplGlfw_Shutdown(); + glfwTerminate(); + + return 0; +} diff --git a/examples/opengl2_example/opengl_example.vcxproj b/examples/opengl2_example/opengl_example.vcxproj new file mode 100644 index 0000000..4b354b6 --- /dev/null +++ b/examples/opengl2_example/opengl_example.vcxproj @@ -0,0 +1,169 @@ + + + + + Debug + Win32 + + + Debug + x64 + + + Release + Win32 + + + Release + x64 + + + + {9CDA7840-B7A5-496D-A527-E95571496D18} + opengl_example + + + + Application + true + MultiByte + + + Application + true + MultiByte + + + Application + false + true + MultiByte + + + Application + false + true + MultiByte + + + + + + + + + + + + + + + + + + + $(ProjectDir)$(Configuration)\ + $(ProjectDir)$(Configuration)\ + $(IncludePath) + + + $(ProjectDir)$(Configuration)\ + $(ProjectDir)$(Configuration)\ + $(IncludePath) + + + $(ProjectDir)$(Configuration)\ + $(ProjectDir)$(Configuration)\ + $(IncludePath) + + + $(ProjectDir)$(Configuration)\ + $(ProjectDir)$(Configuration)\ + $(IncludePath) + + + + Level4 + Disabled + $(SolutionDir)\libs\glfw\include;..\..;%(AdditionalIncludeDirectories) + + + true + $(SolutionDir)\libs\glfw\lib-vc2010-32;%(AdditionalLibraryDirectories) + opengl32.lib;glfw3.lib;%(AdditionalDependencies) + Console + msvcrt.lib + + + + + Level4 + Disabled + $(SolutionDir)\libs\glfw\include;..\..;%(AdditionalIncludeDirectories) + + + true + $(SolutionDir)\libs\glfw\lib-vc2010-64;%(AdditionalLibraryDirectories) + opengl32.lib;glfw3.lib;%(AdditionalDependencies) + Console + msvcrt.lib + + + + + Level4 + MaxSpeed + true + true + $(SolutionDir)\libs\glfw\include;..\..;%(AdditionalIncludeDirectories) + + + true + true + true + $(SolutionDir)\libs\glfw\lib-vc2010-32;%(AdditionalLibraryDirectories) + opengl32.lib;glfw3.lib;%(AdditionalDependencies) + Console + + + + + + + Level4 + MaxSpeed + true + true + $(SolutionDir)\libs\glfw\include;..\..;%(AdditionalIncludeDirectories) + + + true + true + true + $(SolutionDir)\libs\glfw\lib-vc2010-64;%(AdditionalLibraryDirectories) + opengl32.lib;glfw3.lib;%(AdditionalDependencies) + Console + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/examples/opengl2_example/opengl_example.vcxproj.filters b/examples/opengl2_example/opengl_example.vcxproj.filters new file mode 100644 index 0000000..f2282bf --- /dev/null +++ b/examples/opengl2_example/opengl_example.vcxproj.filters @@ -0,0 +1,46 @@ + + + + + {c336cfe3-f0c4-464c-9ef0-a9e17a7ff222} + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx + + + + + sources + + + imgui + + + sources + + + imgui + + + imgui + + + + + imgui + + + imgui + + + sources + + + imgui + + + + + + \ No newline at end of file diff --git a/examples/opengl_example/Makefile b/examples/opengl_example/Makefile deleted file mode 100644 index 91d1b14..0000000 --- a/examples/opengl_example/Makefile +++ /dev/null @@ -1,60 +0,0 @@ -# -# Cross Platform Makefile -# Compatible with Ubuntu 14.04.1 and Mac OS X -# -# -# if you using Mac OS X: -# You'll need glfw -# http://www.glfw.org -# - -#CXX = g++ - -EXE = opengl_example -OBJS = main.o imgui_impl_glfw.o -OBJS += ../../imgui.o ../../imgui_demo.o ../../imgui_draw.o - -UNAME_S := $(shell uname -s) - - -ifeq ($(UNAME_S), Linux) #LINUX - ECHO_MESSAGE = "Linux" - LIBS = -lGL `pkg-config --static --libs glfw3` - - CXXFLAGS = -I../../ `pkg-config --cflags glfw3` - CXXFLAGS += -Wall -Wformat - CFLAGS = $(CXXFLAGS) -endif - -ifeq ($(UNAME_S), Darwin) #APPLE - ECHO_MESSAGE = "Mac OS X" - LIBS = -framework OpenGL -framework Cocoa -framework IOKit -framework CoreVideo - LIBS += -L/usr/local/lib -lglfw3 - - CXXFLAGS = -I../../ -I/usr/local/include - CXXFLAGS += -Wall -Wformat -# CXXFLAGS += -D__APPLE__ - CFLAGS = $(CXXFLAGS) -endif - -ifeq ($(UNAME_S), MINGW64_NT-6.3) - ECHO_MESSAGE = "Windows" - LIBS = -lglfw3 -lgdi32 -lopengl32 -limm32 - - CXXFLAGS = -I../../ -I../libs/gl3w `pkg-config --cflags glfw3` - CXXFLAGS += -Wall -Wformat - CFLAGS = $(CXXFLAGS) -endif - -.cpp.o: - $(CXX) $(CXXFLAGS) -c -o $@ $< - -all: $(EXE) - @echo Build complete for $(ECHO_MESSAGE) - -$(EXE): $(OBJS) - $(CXX) -o $(EXE) $(OBJS) $(CXXFLAGS) $(LIBS) - -clean: - rm $(EXE) $(OBJS) - diff --git a/examples/opengl_example/build_win32.bat b/examples/opengl_example/build_win32.bat deleted file mode 100644 index 278381c..0000000 --- a/examples/opengl_example/build_win32.bat +++ /dev/null @@ -1,3 +0,0 @@ -@REM Build for Visual Studio compiler. Run your copy of vcvars32.bat or vcvarsall.bat to setup command-line compiler. -mkdir Debug -cl /nologo /Zi /MD /I ..\.. /I ..\libs\glfw\include *.cpp ..\..\*.cpp /FeDebug/opengl_example.exe /FoDebug/ /link /LIBPATH:..\libs\glfw\lib-vc2010-32 glfw3.lib opengl32.lib gdi32.lib shell32.lib diff --git a/examples/opengl_example/imgui_impl_glfw.cpp b/examples/opengl_example/imgui_impl_glfw.cpp deleted file mode 100644 index 2d1f5c1..0000000 --- a/examples/opengl_example/imgui_impl_glfw.cpp +++ /dev/null @@ -1,288 +0,0 @@ -// ImGui GLFW binding with OpenGL -// In this binding, ImTextureID is used to store an OpenGL 'GLuint' texture identifier. Read the FAQ about ImTextureID in imgui.cpp. - -// If your context is GL3/GL3 then prefer using the code in opengl3_example. -// You *might* use this code with a GL3/GL4 context but make sure you disable the programmable pipeline by calling "glUseProgram(0)" before ImGui::Render(). -// We cannot do that from GL2 code because the function doesn't exist. - -// You can copy and use unmodified imgui_impl_* files in your project. See main.cpp for an example of using this. -// If you use this binding you'll need to call 4 functions: ImGui_ImplXXXX_Init(), ImGui_ImplXXXX_NewFrame(), ImGui::Render() and ImGui_ImplXXXX_Shutdown(). -// If you are new to ImGui, see examples/README.txt and documentation at the top of imgui.cpp. -// https://github.com/ocornut/imgui - -#include -#include "imgui_impl_glfw.h" - -// GLFW -#include -#ifdef _WIN32 -#undef APIENTRY -#define GLFW_EXPOSE_NATIVE_WIN32 -#define GLFW_EXPOSE_NATIVE_WGL -#include -#endif - -// Data -static GLFWwindow* g_Window = NULL; -static double g_Time = 0.0f; -static bool g_MousePressed[3] = { false, false, false }; -static float g_MouseWheel = 0.0f; -static GLuint g_FontTexture = 0; - -// 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) -void ImGui_ImplGlfw_RenderDrawLists(ImDrawData* draw_data) -{ - // Avoid rendering when minimized, scale coordinates for retina displays (screen coordinates != framebuffer coordinates) - ImGuiIO& io = ImGui::GetIO(); - int fb_width = (int)(io.DisplaySize.x * io.DisplayFramebufferScale.x); - int fb_height = (int)(io.DisplaySize.y * io.DisplayFramebufferScale.y); - if (fb_width == 0 || fb_height == 0) - return; - draw_data->ScaleClipRects(io.DisplayFramebufferScale); - - // We are using the OpenGL fixed pipeline to make the example code simpler to read! - // Setup render state: alpha-blending enabled, no face culling, no depth testing, scissor enabled, vertex/texcoord/color pointers. - GLint last_texture; glGetIntegerv(GL_TEXTURE_BINDING_2D, &last_texture); - GLint last_viewport[4]; glGetIntegerv(GL_VIEWPORT, last_viewport); - glPushAttrib(GL_ENABLE_BIT | GL_COLOR_BUFFER_BIT | GL_TRANSFORM_BIT); - glEnable(GL_BLEND); - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - glDisable(GL_CULL_FACE); - glDisable(GL_DEPTH_TEST); - glEnable(GL_SCISSOR_TEST); - glEnableClientState(GL_VERTEX_ARRAY); - glEnableClientState(GL_TEXTURE_COORD_ARRAY); - glEnableClientState(GL_COLOR_ARRAY); - glEnable(GL_TEXTURE_2D); - //glUseProgram(0); // You may want this if using this code in an OpenGL 3+ context - - // Setup viewport, orthographic projection matrix - glViewport(0, 0, (GLsizei)fb_width, (GLsizei)fb_height); - glMatrixMode(GL_PROJECTION); - glPushMatrix(); - glLoadIdentity(); - glOrtho(0.0f, io.DisplaySize.x, io.DisplaySize.y, 0.0f, -1.0f, +1.0f); - glMatrixMode(GL_MODELVIEW); - glPushMatrix(); - glLoadIdentity(); - - // Render command lists - #define OFFSETOF(TYPE, ELEMENT) ((size_t)&(((TYPE *)0)->ELEMENT)) - for (int n = 0; n < draw_data->CmdListsCount; n++) - { - const ImDrawList* cmd_list = draw_data->CmdLists[n]; - const unsigned char* vtx_buffer = (const unsigned char*)&cmd_list->VtxBuffer.front(); - const ImDrawIdx* idx_buffer = &cmd_list->IdxBuffer.front(); - glVertexPointer(2, GL_FLOAT, sizeof(ImDrawVert), (void*)(vtx_buffer + OFFSETOF(ImDrawVert, pos))); - glTexCoordPointer(2, GL_FLOAT, sizeof(ImDrawVert), (void*)(vtx_buffer + OFFSETOF(ImDrawVert, uv))); - glColorPointer(4, GL_UNSIGNED_BYTE, sizeof(ImDrawVert), (void*)(vtx_buffer + OFFSETOF(ImDrawVert, col))); - - for (int cmd_i = 0; cmd_i < cmd_list->CmdBuffer.size(); cmd_i++) - { - const ImDrawCmd* pcmd = &cmd_list->CmdBuffer[cmd_i]; - if (pcmd->UserCallback) - { - pcmd->UserCallback(cmd_list, pcmd); - } - else - { - glBindTexture(GL_TEXTURE_2D, (GLuint)(intptr_t)pcmd->TextureId); - glScissor((int)pcmd->ClipRect.x, (int)(fb_height - pcmd->ClipRect.w), (int)(pcmd->ClipRect.z - pcmd->ClipRect.x), (int)(pcmd->ClipRect.w - pcmd->ClipRect.y)); - glDrawElements(GL_TRIANGLES, (GLsizei)pcmd->ElemCount, sizeof(ImDrawIdx) == 2 ? GL_UNSIGNED_SHORT : GL_UNSIGNED_INT, idx_buffer); - } - idx_buffer += pcmd->ElemCount; - } - } - #undef OFFSETOF - - // Restore modified state - glDisableClientState(GL_COLOR_ARRAY); - glDisableClientState(GL_TEXTURE_COORD_ARRAY); - glDisableClientState(GL_VERTEX_ARRAY); - glBindTexture(GL_TEXTURE_2D, (GLuint)last_texture); - glMatrixMode(GL_MODELVIEW); - glPopMatrix(); - glMatrixMode(GL_PROJECTION); - glPopMatrix(); - glPopAttrib(); - glViewport(last_viewport[0], last_viewport[1], (GLsizei)last_viewport[2], (GLsizei)last_viewport[3]); -} - -static const char* ImGui_ImplGlfw_GetClipboardText() -{ - return glfwGetClipboardString(g_Window); -} - -static void ImGui_ImplGlfw_SetClipboardText(const char* text) -{ - glfwSetClipboardString(g_Window, text); -} - -void ImGui_ImplGlfw_MouseButtonCallback(GLFWwindow*, int button, int action, int /*mods*/) -{ - if (action == GLFW_PRESS && button >= 0 && button < 3) - g_MousePressed[button] = true; -} - -void ImGui_ImplGlfw_ScrollCallback(GLFWwindow*, double /*xoffset*/, double yoffset) -{ - g_MouseWheel += (float)yoffset; // Use fractional mouse wheel, 1.0 unit 5 lines. -} - -void ImGui_ImplGlFw_KeyCallback(GLFWwindow*, int key, int, int action, int mods) -{ - ImGuiIO& io = ImGui::GetIO(); - if (action == GLFW_PRESS) - io.KeysDown[key] = true; - if (action == GLFW_RELEASE) - io.KeysDown[key] = false; - - (void)mods; // Modifiers are not reliable across systems - io.KeyCtrl = io.KeysDown[GLFW_KEY_LEFT_CONTROL] || io.KeysDown[GLFW_KEY_RIGHT_CONTROL]; - io.KeyShift = io.KeysDown[GLFW_KEY_LEFT_SHIFT] || io.KeysDown[GLFW_KEY_RIGHT_SHIFT]; - io.KeyAlt = io.KeysDown[GLFW_KEY_LEFT_ALT] || io.KeysDown[GLFW_KEY_RIGHT_ALT]; - io.KeySuper = io.KeysDown[GLFW_KEY_LEFT_SUPER] || io.KeysDown[GLFW_KEY_RIGHT_SUPER]; -} - -void ImGui_ImplGlfw_CharCallback(GLFWwindow*, unsigned int c) -{ - ImGuiIO& io = ImGui::GetIO(); - if (c > 0 && c < 0x10000) - io.AddInputCharacter((unsigned short)c); -} - -bool ImGui_ImplGlfw_CreateDeviceObjects() -{ - // Build texture atlas - ImGuiIO& io = ImGui::GetIO(); - unsigned char* pixels; - int width, height; - io.Fonts->GetTexDataAsAlpha8(&pixels, &width, &height); - - // Upload texture to graphics system - GLint last_texture; - glGetIntegerv(GL_TEXTURE_BINDING_2D, &last_texture); - glGenTextures(1, &g_FontTexture); - glBindTexture(GL_TEXTURE_2D, g_FontTexture); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, width, height, 0, GL_ALPHA, GL_UNSIGNED_BYTE, pixels); - - // Store our identifier - io.Fonts->TexID = (void *)(intptr_t)g_FontTexture; - - // Restore state - glBindTexture(GL_TEXTURE_2D, last_texture); - - return true; -} - -void ImGui_ImplGlfw_InvalidateDeviceObjects() -{ - if (g_FontTexture) - { - glDeleteTextures(1, &g_FontTexture); - ImGui::GetIO().Fonts->TexID = 0; - g_FontTexture = 0; - } -} - -bool ImGui_ImplGlfw_Init(GLFWwindow* window, bool install_callbacks) -{ - g_Window = window; - - ImGuiIO& io = ImGui::GetIO(); - 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; - io.KeyMap[ImGuiKey_DownArrow] = GLFW_KEY_DOWN; - io.KeyMap[ImGuiKey_PageUp] = GLFW_KEY_PAGE_UP; - io.KeyMap[ImGuiKey_PageDown] = GLFW_KEY_PAGE_DOWN; - io.KeyMap[ImGuiKey_Home] = GLFW_KEY_HOME; - io.KeyMap[ImGuiKey_End] = GLFW_KEY_END; - io.KeyMap[ImGuiKey_Delete] = GLFW_KEY_DELETE; - io.KeyMap[ImGuiKey_Backspace] = GLFW_KEY_BACKSPACE; - io.KeyMap[ImGuiKey_Enter] = GLFW_KEY_ENTER; - io.KeyMap[ImGuiKey_Escape] = GLFW_KEY_ESCAPE; - io.KeyMap[ImGuiKey_A] = GLFW_KEY_A; - io.KeyMap[ImGuiKey_C] = GLFW_KEY_C; - io.KeyMap[ImGuiKey_V] = GLFW_KEY_V; - io.KeyMap[ImGuiKey_X] = GLFW_KEY_X; - io.KeyMap[ImGuiKey_Y] = GLFW_KEY_Y; - io.KeyMap[ImGuiKey_Z] = GLFW_KEY_Z; - - io.RenderDrawListsFn = ImGui_ImplGlfw_RenderDrawLists; // Alternatively you can set this to NULL and call ImGui::GetDrawData() after ImGui::Render() to get the same ImDrawData pointer. - io.SetClipboardTextFn = ImGui_ImplGlfw_SetClipboardText; - io.GetClipboardTextFn = ImGui_ImplGlfw_GetClipboardText; -#ifdef _WIN32 - io.ImeWindowHandle = glfwGetWin32Window(g_Window); -#endif - - if (install_callbacks) - { - glfwSetMouseButtonCallback(window, ImGui_ImplGlfw_MouseButtonCallback); - glfwSetScrollCallback(window, ImGui_ImplGlfw_ScrollCallback); - glfwSetKeyCallback(window, ImGui_ImplGlFw_KeyCallback); - glfwSetCharCallback(window, ImGui_ImplGlfw_CharCallback); - } - - return true; -} - -void ImGui_ImplGlfw_Shutdown() -{ - ImGui_ImplGlfw_InvalidateDeviceObjects(); - ImGui::Shutdown(); -} - -void ImGui_ImplGlfw_NewFrame() -{ - if (!g_FontTexture) - ImGui_ImplGlfw_CreateDeviceObjects(); - - ImGuiIO& io = ImGui::GetIO(); - - // Setup display size (every frame to accommodate for window resizing) - int w, h; - int display_w, display_h; - glfwGetWindowSize(g_Window, &w, &h); - glfwGetFramebufferSize(g_Window, &display_w, &display_h); - io.DisplaySize = ImVec2((float)w, (float)h); - io.DisplayFramebufferScale = ImVec2(w > 0 ? ((float)display_w / w) : 0, h > 0 ? ((float)display_h / h) : 0); - - // Setup time step - double current_time = glfwGetTime(); - io.DeltaTime = g_Time > 0.0 ? (float)(current_time - g_Time) : (float)(1.0f/60.0f); - g_Time = current_time; - - // Setup inputs - // (we already got mouse wheel, keyboard keys & characters from glfw callbacks polled in glfwPollEvents()) - if (glfwGetWindowAttrib(g_Window, GLFW_FOCUSED)) - { - double mouse_x, mouse_y; - glfwGetCursorPos(g_Window, &mouse_x, &mouse_y); - io.MousePos = ImVec2((float)mouse_x, (float)mouse_y); // Mouse position in screen coordinates (set to -1,-1 if no mouse / on another screen, etc.) - } - else - { - io.MousePos = ImVec2(-1,-1); - } - - for (int i = 0; i < 3; i++) - { - io.MouseDown[i] = g_MousePressed[i] || glfwGetMouseButton(g_Window, i) != 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. - g_MousePressed[i] = false; - } - - io.MouseWheel = g_MouseWheel; - g_MouseWheel = 0.0f; - - // Hide OS mouse cursor if ImGui is drawing it - glfwSetInputMode(g_Window, GLFW_CURSOR, io.MouseDrawCursor ? GLFW_CURSOR_HIDDEN : GLFW_CURSOR_NORMAL); - - // Start the frame - ImGui::NewFrame(); -} diff --git a/examples/opengl_example/imgui_impl_glfw.h b/examples/opengl_example/imgui_impl_glfw.h deleted file mode 100644 index 07dd96f..0000000 --- a/examples/opengl_example/imgui_impl_glfw.h +++ /dev/null @@ -1,29 +0,0 @@ -// ImGui GLFW binding with OpenGL -// In this binding, ImTextureID is used to store an OpenGL 'GLuint' texture identifier. Read the FAQ about ImTextureID in imgui.cpp. - -// If your context is GL3/GL3 then prefer using the code in opengl3_example. -// You *might* use this code with a GL3/GL4 context but make sure you disable the programmable pipeline by calling "glUseProgram(0)" before ImGui::Render(). -// We cannot do that from GL2 code because the function doesn't exist. - -// You can copy and use unmodified imgui_impl_* files in your project. See main.cpp for an example of using this. -// If you use this binding you'll need to call 4 functions: ImGui_ImplXXXX_Init(), ImGui_ImplXXXX_NewFrame(), ImGui::Render() and ImGui_ImplXXXX_Shutdown(). -// If you are new to ImGui, see examples/README.txt and documentation at the top of imgui.cpp. -// https://github.com/ocornut/imgui - -struct GLFWwindow; - -IMGUI_API bool ImGui_ImplGlfw_Init(GLFWwindow* window, bool install_callbacks); -IMGUI_API void ImGui_ImplGlfw_Shutdown(); -IMGUI_API void ImGui_ImplGlfw_NewFrame(); - -// Use if you want to reset your rendering device without losing ImGui state. -IMGUI_API void ImGui_ImplGlfw_InvalidateDeviceObjects(); -IMGUI_API bool ImGui_ImplGlfw_CreateDeviceObjects(); - -// GLFW callbacks (installed by default if you enable 'install_callbacks' during initialization) -// Provided here if you want to chain callbacks. -// You can also handle inputs yourself and use those as a reference. -IMGUI_API void ImGui_ImplGlfw_MouseButtonCallback(GLFWwindow* window, int button, int action, int mods); -IMGUI_API void ImGui_ImplGlfw_ScrollCallback(GLFWwindow* window, double xoffset, double yoffset); -IMGUI_API void ImGui_ImplGlFw_KeyCallback(GLFWwindow* window, int key, int scancode, int action, int mods); -IMGUI_API void ImGui_ImplGlfw_CharCallback(GLFWwindow* window, unsigned int c); diff --git a/examples/README.txt b/examples/README.txt index df2e86d..5a1c8df 100644 --- a/examples/README.txt +++ b/examples/README.txt @@ -8,11 +8,13 @@ TL;DR; - Newcomers, read 'PROGRAMMER GUIDE' in imgui.cpp for notes on how to setup ImGui in your codebase. - - Refer to 'opengl_example' to understand how the library is setup, it is the simplest one. + - Refer to 'opengl2_example' to LEARN how the library is setup, it is the simplest one. The other examples requires more boilerplate and are harder to read. + - If you are using OpenGL in your application, probably use an opengl3_xxx backend. + Mixing old fixed pipeline OpenGL2 and programmable pipeline OpenGL3+ isn't well supported by drivers. - If you are using of the backend provided here, so you can copy the imgui_impl_xxx.cpp/h files to your project and use them unmodified. - - If you have your own engine, you probably want to start from 'opengl_example' and adapt it to + - If you have your own engine, you probably want to start from one of the OpenGL example and adapt it to your engine, but you can read the other examples as well. ImGui is highly portable and only requires a few things to run: @@ -41,15 +43,14 @@ Also note that some setup or GPU drivers may be causing extra lag (possibly by enforcing triple buffering), leaving you with no option but sadness/anger (Intel GPU drivers were reported as such). -opengl_example/ - OpenGL example, using GLFW + fixed pipeline. - This is simple and should work for all OpenGL enabled applications. - Prefer following this example to learn how ImGui works! - (You can use this code in a GL3/GL4 context but make sure you disable the programmable pipeline - by calling "glUseProgram(0)" before ImGui::Render.) +opengl2_example/ + GLFW + OpenGL example (old fixed pipeline). + This is simple to read. Prefer following this example to learn how ImGui works! + (You might be able to use this code in a GL3/GL4 context but make sure you disable the programmable + pipeline by calling "glUseProgram(0)" before ImGui::Render.) opengl3_example/ - OpenGL example, using GLFW/GL3W + programmable pipeline. + GLFW + OpenGL example (programmable pipeline, binding modern functions with GL3W). This uses more modern OpenGL calls and custom shaders. It's more messy. directx9_example/ @@ -68,8 +69,8 @@ On iOS, Using Synergy to access keyboard/mouse data from server computer. Synergy keyboard integration is rather hacky. -sdl_opengl_example/ - SDL2 + OpenGL example. +sdl_opengl2_example/ + SDL2 + OpenGL example (old fixed pipeline). sdl_opengl3_example/ SDL2 + OpenGL3 example. diff --git a/examples/imgui_examples_msvc2010.sln b/examples/imgui_examples_msvc2010.sln index b7e6a25..16f0d60 100644 --- a/examples/imgui_examples_msvc2010.sln +++ b/examples/imgui_examples_msvc2010.sln @@ -1,7 +1,7 @@  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}" +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "opengl2_example", "opengl_example\opengl2_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 diff --git a/examples/opengl2_example/Makefile b/examples/opengl2_example/Makefile new file mode 100644 index 0000000..bd79d1b --- /dev/null +++ b/examples/opengl2_example/Makefile @@ -0,0 +1,60 @@ +# +# Cross Platform Makefile +# Compatible with Ubuntu 14.04.1 and Mac OS X +# +# +# if you using Mac OS X: +# You'll need glfw +# http://www.glfw.org +# + +#CXX = g++ + +EXE = opengl2_example +OBJS = main.o imgui_impl_glfw.o +OBJS += ../../imgui.o ../../imgui_demo.o ../../imgui_draw.o + +UNAME_S := $(shell uname -s) + + +ifeq ($(UNAME_S), Linux) #LINUX + ECHO_MESSAGE = "Linux" + LIBS = -lGL `pkg-config --static --libs glfw3` + + CXXFLAGS = -I../../ `pkg-config --cflags glfw3` + CXXFLAGS += -Wall -Wformat + CFLAGS = $(CXXFLAGS) +endif + +ifeq ($(UNAME_S), Darwin) #APPLE + ECHO_MESSAGE = "Mac OS X" + LIBS = -framework OpenGL -framework Cocoa -framework IOKit -framework CoreVideo + LIBS += -L/usr/local/lib -lglfw3 + + CXXFLAGS = -I../../ -I/usr/local/include + CXXFLAGS += -Wall -Wformat +# CXXFLAGS += -D__APPLE__ + CFLAGS = $(CXXFLAGS) +endif + +ifeq ($(UNAME_S), MINGW64_NT-6.3) + ECHO_MESSAGE = "Windows" + LIBS = -lglfw3 -lgdi32 -lopengl32 -limm32 + + CXXFLAGS = -I../../ -I../libs/gl3w `pkg-config --cflags glfw3` + CXXFLAGS += -Wall -Wformat + CFLAGS = $(CXXFLAGS) +endif + +.cpp.o: + $(CXX) $(CXXFLAGS) -c -o $@ $< + +all: $(EXE) + @echo Build complete for $(ECHO_MESSAGE) + +$(EXE): $(OBJS) + $(CXX) -o $(EXE) $(OBJS) $(CXXFLAGS) $(LIBS) + +clean: + rm $(EXE) $(OBJS) + diff --git a/examples/opengl2_example/build_win32.bat b/examples/opengl2_example/build_win32.bat new file mode 100644 index 0000000..278381c --- /dev/null +++ b/examples/opengl2_example/build_win32.bat @@ -0,0 +1,3 @@ +@REM Build for Visual Studio compiler. Run your copy of vcvars32.bat or vcvarsall.bat to setup command-line compiler. +mkdir Debug +cl /nologo /Zi /MD /I ..\.. /I ..\libs\glfw\include *.cpp ..\..\*.cpp /FeDebug/opengl_example.exe /FoDebug/ /link /LIBPATH:..\libs\glfw\lib-vc2010-32 glfw3.lib opengl32.lib gdi32.lib shell32.lib diff --git a/examples/opengl2_example/imgui_impl_glfw.cpp b/examples/opengl2_example/imgui_impl_glfw.cpp new file mode 100644 index 0000000..2d1f5c1 --- /dev/null +++ b/examples/opengl2_example/imgui_impl_glfw.cpp @@ -0,0 +1,288 @@ +// ImGui GLFW binding with OpenGL +// In this binding, ImTextureID is used to store an OpenGL 'GLuint' texture identifier. Read the FAQ about ImTextureID in imgui.cpp. + +// If your context is GL3/GL3 then prefer using the code in opengl3_example. +// You *might* use this code with a GL3/GL4 context but make sure you disable the programmable pipeline by calling "glUseProgram(0)" before ImGui::Render(). +// We cannot do that from GL2 code because the function doesn't exist. + +// You can copy and use unmodified imgui_impl_* files in your project. See main.cpp for an example of using this. +// If you use this binding you'll need to call 4 functions: ImGui_ImplXXXX_Init(), ImGui_ImplXXXX_NewFrame(), ImGui::Render() and ImGui_ImplXXXX_Shutdown(). +// If you are new to ImGui, see examples/README.txt and documentation at the top of imgui.cpp. +// https://github.com/ocornut/imgui + +#include +#include "imgui_impl_glfw.h" + +// GLFW +#include +#ifdef _WIN32 +#undef APIENTRY +#define GLFW_EXPOSE_NATIVE_WIN32 +#define GLFW_EXPOSE_NATIVE_WGL +#include +#endif + +// Data +static GLFWwindow* g_Window = NULL; +static double g_Time = 0.0f; +static bool g_MousePressed[3] = { false, false, false }; +static float g_MouseWheel = 0.0f; +static GLuint g_FontTexture = 0; + +// 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) +void ImGui_ImplGlfw_RenderDrawLists(ImDrawData* draw_data) +{ + // Avoid rendering when minimized, scale coordinates for retina displays (screen coordinates != framebuffer coordinates) + ImGuiIO& io = ImGui::GetIO(); + int fb_width = (int)(io.DisplaySize.x * io.DisplayFramebufferScale.x); + int fb_height = (int)(io.DisplaySize.y * io.DisplayFramebufferScale.y); + if (fb_width == 0 || fb_height == 0) + return; + draw_data->ScaleClipRects(io.DisplayFramebufferScale); + + // We are using the OpenGL fixed pipeline to make the example code simpler to read! + // Setup render state: alpha-blending enabled, no face culling, no depth testing, scissor enabled, vertex/texcoord/color pointers. + GLint last_texture; glGetIntegerv(GL_TEXTURE_BINDING_2D, &last_texture); + GLint last_viewport[4]; glGetIntegerv(GL_VIEWPORT, last_viewport); + glPushAttrib(GL_ENABLE_BIT | GL_COLOR_BUFFER_BIT | GL_TRANSFORM_BIT); + glEnable(GL_BLEND); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + glDisable(GL_CULL_FACE); + glDisable(GL_DEPTH_TEST); + glEnable(GL_SCISSOR_TEST); + glEnableClientState(GL_VERTEX_ARRAY); + glEnableClientState(GL_TEXTURE_COORD_ARRAY); + glEnableClientState(GL_COLOR_ARRAY); + glEnable(GL_TEXTURE_2D); + //glUseProgram(0); // You may want this if using this code in an OpenGL 3+ context + + // Setup viewport, orthographic projection matrix + glViewport(0, 0, (GLsizei)fb_width, (GLsizei)fb_height); + glMatrixMode(GL_PROJECTION); + glPushMatrix(); + glLoadIdentity(); + glOrtho(0.0f, io.DisplaySize.x, io.DisplaySize.y, 0.0f, -1.0f, +1.0f); + glMatrixMode(GL_MODELVIEW); + glPushMatrix(); + glLoadIdentity(); + + // Render command lists + #define OFFSETOF(TYPE, ELEMENT) ((size_t)&(((TYPE *)0)->ELEMENT)) + for (int n = 0; n < draw_data->CmdListsCount; n++) + { + const ImDrawList* cmd_list = draw_data->CmdLists[n]; + const unsigned char* vtx_buffer = (const unsigned char*)&cmd_list->VtxBuffer.front(); + const ImDrawIdx* idx_buffer = &cmd_list->IdxBuffer.front(); + glVertexPointer(2, GL_FLOAT, sizeof(ImDrawVert), (void*)(vtx_buffer + OFFSETOF(ImDrawVert, pos))); + glTexCoordPointer(2, GL_FLOAT, sizeof(ImDrawVert), (void*)(vtx_buffer + OFFSETOF(ImDrawVert, uv))); + glColorPointer(4, GL_UNSIGNED_BYTE, sizeof(ImDrawVert), (void*)(vtx_buffer + OFFSETOF(ImDrawVert, col))); + + for (int cmd_i = 0; cmd_i < cmd_list->CmdBuffer.size(); cmd_i++) + { + const ImDrawCmd* pcmd = &cmd_list->CmdBuffer[cmd_i]; + if (pcmd->UserCallback) + { + pcmd->UserCallback(cmd_list, pcmd); + } + else + { + glBindTexture(GL_TEXTURE_2D, (GLuint)(intptr_t)pcmd->TextureId); + glScissor((int)pcmd->ClipRect.x, (int)(fb_height - pcmd->ClipRect.w), (int)(pcmd->ClipRect.z - pcmd->ClipRect.x), (int)(pcmd->ClipRect.w - pcmd->ClipRect.y)); + glDrawElements(GL_TRIANGLES, (GLsizei)pcmd->ElemCount, sizeof(ImDrawIdx) == 2 ? GL_UNSIGNED_SHORT : GL_UNSIGNED_INT, idx_buffer); + } + idx_buffer += pcmd->ElemCount; + } + } + #undef OFFSETOF + + // Restore modified state + glDisableClientState(GL_COLOR_ARRAY); + glDisableClientState(GL_TEXTURE_COORD_ARRAY); + glDisableClientState(GL_VERTEX_ARRAY); + glBindTexture(GL_TEXTURE_2D, (GLuint)last_texture); + glMatrixMode(GL_MODELVIEW); + glPopMatrix(); + glMatrixMode(GL_PROJECTION); + glPopMatrix(); + glPopAttrib(); + glViewport(last_viewport[0], last_viewport[1], (GLsizei)last_viewport[2], (GLsizei)last_viewport[3]); +} + +static const char* ImGui_ImplGlfw_GetClipboardText() +{ + return glfwGetClipboardString(g_Window); +} + +static void ImGui_ImplGlfw_SetClipboardText(const char* text) +{ + glfwSetClipboardString(g_Window, text); +} + +void ImGui_ImplGlfw_MouseButtonCallback(GLFWwindow*, int button, int action, int /*mods*/) +{ + if (action == GLFW_PRESS && button >= 0 && button < 3) + g_MousePressed[button] = true; +} + +void ImGui_ImplGlfw_ScrollCallback(GLFWwindow*, double /*xoffset*/, double yoffset) +{ + g_MouseWheel += (float)yoffset; // Use fractional mouse wheel, 1.0 unit 5 lines. +} + +void ImGui_ImplGlFw_KeyCallback(GLFWwindow*, int key, int, int action, int mods) +{ + ImGuiIO& io = ImGui::GetIO(); + if (action == GLFW_PRESS) + io.KeysDown[key] = true; + if (action == GLFW_RELEASE) + io.KeysDown[key] = false; + + (void)mods; // Modifiers are not reliable across systems + io.KeyCtrl = io.KeysDown[GLFW_KEY_LEFT_CONTROL] || io.KeysDown[GLFW_KEY_RIGHT_CONTROL]; + io.KeyShift = io.KeysDown[GLFW_KEY_LEFT_SHIFT] || io.KeysDown[GLFW_KEY_RIGHT_SHIFT]; + io.KeyAlt = io.KeysDown[GLFW_KEY_LEFT_ALT] || io.KeysDown[GLFW_KEY_RIGHT_ALT]; + io.KeySuper = io.KeysDown[GLFW_KEY_LEFT_SUPER] || io.KeysDown[GLFW_KEY_RIGHT_SUPER]; +} + +void ImGui_ImplGlfw_CharCallback(GLFWwindow*, unsigned int c) +{ + ImGuiIO& io = ImGui::GetIO(); + if (c > 0 && c < 0x10000) + io.AddInputCharacter((unsigned short)c); +} + +bool ImGui_ImplGlfw_CreateDeviceObjects() +{ + // Build texture atlas + ImGuiIO& io = ImGui::GetIO(); + unsigned char* pixels; + int width, height; + io.Fonts->GetTexDataAsAlpha8(&pixels, &width, &height); + + // Upload texture to graphics system + GLint last_texture; + glGetIntegerv(GL_TEXTURE_BINDING_2D, &last_texture); + glGenTextures(1, &g_FontTexture); + glBindTexture(GL_TEXTURE_2D, g_FontTexture); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, width, height, 0, GL_ALPHA, GL_UNSIGNED_BYTE, pixels); + + // Store our identifier + io.Fonts->TexID = (void *)(intptr_t)g_FontTexture; + + // Restore state + glBindTexture(GL_TEXTURE_2D, last_texture); + + return true; +} + +void ImGui_ImplGlfw_InvalidateDeviceObjects() +{ + if (g_FontTexture) + { + glDeleteTextures(1, &g_FontTexture); + ImGui::GetIO().Fonts->TexID = 0; + g_FontTexture = 0; + } +} + +bool ImGui_ImplGlfw_Init(GLFWwindow* window, bool install_callbacks) +{ + g_Window = window; + + ImGuiIO& io = ImGui::GetIO(); + 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; + io.KeyMap[ImGuiKey_DownArrow] = GLFW_KEY_DOWN; + io.KeyMap[ImGuiKey_PageUp] = GLFW_KEY_PAGE_UP; + io.KeyMap[ImGuiKey_PageDown] = GLFW_KEY_PAGE_DOWN; + io.KeyMap[ImGuiKey_Home] = GLFW_KEY_HOME; + io.KeyMap[ImGuiKey_End] = GLFW_KEY_END; + io.KeyMap[ImGuiKey_Delete] = GLFW_KEY_DELETE; + io.KeyMap[ImGuiKey_Backspace] = GLFW_KEY_BACKSPACE; + io.KeyMap[ImGuiKey_Enter] = GLFW_KEY_ENTER; + io.KeyMap[ImGuiKey_Escape] = GLFW_KEY_ESCAPE; + io.KeyMap[ImGuiKey_A] = GLFW_KEY_A; + io.KeyMap[ImGuiKey_C] = GLFW_KEY_C; + io.KeyMap[ImGuiKey_V] = GLFW_KEY_V; + io.KeyMap[ImGuiKey_X] = GLFW_KEY_X; + io.KeyMap[ImGuiKey_Y] = GLFW_KEY_Y; + io.KeyMap[ImGuiKey_Z] = GLFW_KEY_Z; + + io.RenderDrawListsFn = ImGui_ImplGlfw_RenderDrawLists; // Alternatively you can set this to NULL and call ImGui::GetDrawData() after ImGui::Render() to get the same ImDrawData pointer. + io.SetClipboardTextFn = ImGui_ImplGlfw_SetClipboardText; + io.GetClipboardTextFn = ImGui_ImplGlfw_GetClipboardText; +#ifdef _WIN32 + io.ImeWindowHandle = glfwGetWin32Window(g_Window); +#endif + + if (install_callbacks) + { + glfwSetMouseButtonCallback(window, ImGui_ImplGlfw_MouseButtonCallback); + glfwSetScrollCallback(window, ImGui_ImplGlfw_ScrollCallback); + glfwSetKeyCallback(window, ImGui_ImplGlFw_KeyCallback); + glfwSetCharCallback(window, ImGui_ImplGlfw_CharCallback); + } + + return true; +} + +void ImGui_ImplGlfw_Shutdown() +{ + ImGui_ImplGlfw_InvalidateDeviceObjects(); + ImGui::Shutdown(); +} + +void ImGui_ImplGlfw_NewFrame() +{ + if (!g_FontTexture) + ImGui_ImplGlfw_CreateDeviceObjects(); + + ImGuiIO& io = ImGui::GetIO(); + + // Setup display size (every frame to accommodate for window resizing) + int w, h; + int display_w, display_h; + glfwGetWindowSize(g_Window, &w, &h); + glfwGetFramebufferSize(g_Window, &display_w, &display_h); + io.DisplaySize = ImVec2((float)w, (float)h); + io.DisplayFramebufferScale = ImVec2(w > 0 ? ((float)display_w / w) : 0, h > 0 ? ((float)display_h / h) : 0); + + // Setup time step + double current_time = glfwGetTime(); + io.DeltaTime = g_Time > 0.0 ? (float)(current_time - g_Time) : (float)(1.0f/60.0f); + g_Time = current_time; + + // Setup inputs + // (we already got mouse wheel, keyboard keys & characters from glfw callbacks polled in glfwPollEvents()) + if (glfwGetWindowAttrib(g_Window, GLFW_FOCUSED)) + { + double mouse_x, mouse_y; + glfwGetCursorPos(g_Window, &mouse_x, &mouse_y); + io.MousePos = ImVec2((float)mouse_x, (float)mouse_y); // Mouse position in screen coordinates (set to -1,-1 if no mouse / on another screen, etc.) + } + else + { + io.MousePos = ImVec2(-1,-1); + } + + for (int i = 0; i < 3; i++) + { + io.MouseDown[i] = g_MousePressed[i] || glfwGetMouseButton(g_Window, i) != 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. + g_MousePressed[i] = false; + } + + io.MouseWheel = g_MouseWheel; + g_MouseWheel = 0.0f; + + // Hide OS mouse cursor if ImGui is drawing it + glfwSetInputMode(g_Window, GLFW_CURSOR, io.MouseDrawCursor ? GLFW_CURSOR_HIDDEN : GLFW_CURSOR_NORMAL); + + // Start the frame + ImGui::NewFrame(); +} diff --git a/examples/opengl2_example/imgui_impl_glfw.h b/examples/opengl2_example/imgui_impl_glfw.h new file mode 100644 index 0000000..07dd96f --- /dev/null +++ b/examples/opengl2_example/imgui_impl_glfw.h @@ -0,0 +1,29 @@ +// ImGui GLFW binding with OpenGL +// In this binding, ImTextureID is used to store an OpenGL 'GLuint' texture identifier. Read the FAQ about ImTextureID in imgui.cpp. + +// If your context is GL3/GL3 then prefer using the code in opengl3_example. +// You *might* use this code with a GL3/GL4 context but make sure you disable the programmable pipeline by calling "glUseProgram(0)" before ImGui::Render(). +// We cannot do that from GL2 code because the function doesn't exist. + +// You can copy and use unmodified imgui_impl_* files in your project. See main.cpp for an example of using this. +// If you use this binding you'll need to call 4 functions: ImGui_ImplXXXX_Init(), ImGui_ImplXXXX_NewFrame(), ImGui::Render() and ImGui_ImplXXXX_Shutdown(). +// If you are new to ImGui, see examples/README.txt and documentation at the top of imgui.cpp. +// https://github.com/ocornut/imgui + +struct GLFWwindow; + +IMGUI_API bool ImGui_ImplGlfw_Init(GLFWwindow* window, bool install_callbacks); +IMGUI_API void ImGui_ImplGlfw_Shutdown(); +IMGUI_API void ImGui_ImplGlfw_NewFrame(); + +// Use if you want to reset your rendering device without losing ImGui state. +IMGUI_API void ImGui_ImplGlfw_InvalidateDeviceObjects(); +IMGUI_API bool ImGui_ImplGlfw_CreateDeviceObjects(); + +// GLFW callbacks (installed by default if you enable 'install_callbacks' during initialization) +// Provided here if you want to chain callbacks. +// You can also handle inputs yourself and use those as a reference. +IMGUI_API void ImGui_ImplGlfw_MouseButtonCallback(GLFWwindow* window, int button, int action, int mods); +IMGUI_API void ImGui_ImplGlfw_ScrollCallback(GLFWwindow* window, double xoffset, double yoffset); +IMGUI_API void ImGui_ImplGlFw_KeyCallback(GLFWwindow* window, int key, int scancode, int action, int mods); +IMGUI_API void ImGui_ImplGlfw_CharCallback(GLFWwindow* window, unsigned int c); diff --git a/examples/opengl2_example/main.cpp b/examples/opengl2_example/main.cpp new file mode 100644 index 0000000..a844db5 --- /dev/null +++ b/examples/opengl2_example/main.cpp @@ -0,0 +1,89 @@ +// ImGui - standalone example application for Glfw + OpenGL 2, using fixed pipeline +// If you are new to ImGui, see examples/README.txt and documentation at the top of imgui.cpp. + +#include +#include "imgui_impl_glfw.h" +#include +#include + +static void error_callback(int error, const char* description) +{ + fprintf(stderr, "Error %d: %s\n", error, description); +} + +int main(int, char**) +{ + // Setup window + glfwSetErrorCallback(error_callback); + if (!glfwInit()) + return 1; + GLFWwindow* window = glfwCreateWindow(1280, 720, "ImGui OpenGL2 example", NULL, NULL); + glfwMakeContextCurrent(window); + + // Setup ImGui binding + ImGui_ImplGlfw_Init(window, true); + + // Load Fonts + // (there is a default font, this is only if you want to change it. see extra_fonts/README.txt for more details) + //ImGuiIO& io = ImGui::GetIO(); + //io.Fonts->AddFontDefault(); + //io.Fonts->AddFontFromFileTTF("../../extra_fonts/Cousine-Regular.ttf", 15.0f); + //io.Fonts->AddFontFromFileTTF("../../extra_fonts/DroidSans.ttf", 16.0f); + //io.Fonts->AddFontFromFileTTF("../../extra_fonts/ProggyClean.ttf", 13.0f); + //io.Fonts->AddFontFromFileTTF("../../extra_fonts/ProggyTiny.ttf", 10.0f); + //io.Fonts->AddFontFromFileTTF("c:\\Windows\\Fonts\\ArialUni.ttf", 18.0f, NULL, io.Fonts->GetGlyphRangesJapanese()); + + bool show_test_window = true; + bool show_another_window = false; + ImVec4 clear_color = ImColor(114, 144, 154); + + // Main loop + while (!glfwWindowShouldClose(window)) + { + glfwPollEvents(); + ImGui_ImplGlfw_NewFrame(); + + // 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 = 0.0f; + ImGui::Text("Hello, world!"); + ImGui::SliderFloat("float", &f, 0.0f, 1.0f); + ImGui::ColorEdit3("clear color", (float*)&clear_color); + if (ImGui::Button("Test Window")) show_test_window ^= 1; + if (ImGui::Button("Another Window")) show_another_window ^= 1; + ImGui::Text("Application average %.3f ms/frame (%.1f FPS)", 1000.0f / ImGui::GetIO().Framerate, ImGui::GetIO().Framerate); + } + + // 2. Show another simple window, this time using an explicit Begin/End pair + if (show_another_window) + { + ImGui::SetNextWindowSize(ImVec2(200,100), ImGuiSetCond_FirstUseEver); + ImGui::Begin("Another Window", &show_another_window); + 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::SetNextWindowPos(ImVec2(650, 20), ImGuiSetCond_FirstUseEver); + ImGui::ShowTestWindow(&show_test_window); + } + + // Rendering + int display_w, display_h; + glfwGetFramebufferSize(window, &display_w, &display_h); + glViewport(0, 0, display_w, display_h); + glClearColor(clear_color.x, clear_color.y, clear_color.z, clear_color.w); + glClear(GL_COLOR_BUFFER_BIT); + ImGui::Render(); + glfwSwapBuffers(window); + } + + // Cleanup + ImGui_ImplGlfw_Shutdown(); + glfwTerminate(); + + return 0; +} diff --git a/examples/opengl2_example/opengl_example.vcxproj b/examples/opengl2_example/opengl_example.vcxproj new file mode 100644 index 0000000..4b354b6 --- /dev/null +++ b/examples/opengl2_example/opengl_example.vcxproj @@ -0,0 +1,169 @@ + + + + + Debug + Win32 + + + Debug + x64 + + + Release + Win32 + + + Release + x64 + + + + {9CDA7840-B7A5-496D-A527-E95571496D18} + opengl_example + + + + Application + true + MultiByte + + + Application + true + MultiByte + + + Application + false + true + MultiByte + + + Application + false + true + MultiByte + + + + + + + + + + + + + + + + + + + $(ProjectDir)$(Configuration)\ + $(ProjectDir)$(Configuration)\ + $(IncludePath) + + + $(ProjectDir)$(Configuration)\ + $(ProjectDir)$(Configuration)\ + $(IncludePath) + + + $(ProjectDir)$(Configuration)\ + $(ProjectDir)$(Configuration)\ + $(IncludePath) + + + $(ProjectDir)$(Configuration)\ + $(ProjectDir)$(Configuration)\ + $(IncludePath) + + + + Level4 + Disabled + $(SolutionDir)\libs\glfw\include;..\..;%(AdditionalIncludeDirectories) + + + true + $(SolutionDir)\libs\glfw\lib-vc2010-32;%(AdditionalLibraryDirectories) + opengl32.lib;glfw3.lib;%(AdditionalDependencies) + Console + msvcrt.lib + + + + + Level4 + Disabled + $(SolutionDir)\libs\glfw\include;..\..;%(AdditionalIncludeDirectories) + + + true + $(SolutionDir)\libs\glfw\lib-vc2010-64;%(AdditionalLibraryDirectories) + opengl32.lib;glfw3.lib;%(AdditionalDependencies) + Console + msvcrt.lib + + + + + Level4 + MaxSpeed + true + true + $(SolutionDir)\libs\glfw\include;..\..;%(AdditionalIncludeDirectories) + + + true + true + true + $(SolutionDir)\libs\glfw\lib-vc2010-32;%(AdditionalLibraryDirectories) + opengl32.lib;glfw3.lib;%(AdditionalDependencies) + Console + + + + + + + Level4 + MaxSpeed + true + true + $(SolutionDir)\libs\glfw\include;..\..;%(AdditionalIncludeDirectories) + + + true + true + true + $(SolutionDir)\libs\glfw\lib-vc2010-64;%(AdditionalLibraryDirectories) + opengl32.lib;glfw3.lib;%(AdditionalDependencies) + Console + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/examples/opengl2_example/opengl_example.vcxproj.filters b/examples/opengl2_example/opengl_example.vcxproj.filters new file mode 100644 index 0000000..f2282bf --- /dev/null +++ b/examples/opengl2_example/opengl_example.vcxproj.filters @@ -0,0 +1,46 @@ + + + + + {c336cfe3-f0c4-464c-9ef0-a9e17a7ff222} + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx + + + + + sources + + + imgui + + + sources + + + imgui + + + imgui + + + + + imgui + + + imgui + + + sources + + + imgui + + + + + + \ No newline at end of file diff --git a/examples/opengl_example/Makefile b/examples/opengl_example/Makefile deleted file mode 100644 index 91d1b14..0000000 --- a/examples/opengl_example/Makefile +++ /dev/null @@ -1,60 +0,0 @@ -# -# Cross Platform Makefile -# Compatible with Ubuntu 14.04.1 and Mac OS X -# -# -# if you using Mac OS X: -# You'll need glfw -# http://www.glfw.org -# - -#CXX = g++ - -EXE = opengl_example -OBJS = main.o imgui_impl_glfw.o -OBJS += ../../imgui.o ../../imgui_demo.o ../../imgui_draw.o - -UNAME_S := $(shell uname -s) - - -ifeq ($(UNAME_S), Linux) #LINUX - ECHO_MESSAGE = "Linux" - LIBS = -lGL `pkg-config --static --libs glfw3` - - CXXFLAGS = -I../../ `pkg-config --cflags glfw3` - CXXFLAGS += -Wall -Wformat - CFLAGS = $(CXXFLAGS) -endif - -ifeq ($(UNAME_S), Darwin) #APPLE - ECHO_MESSAGE = "Mac OS X" - LIBS = -framework OpenGL -framework Cocoa -framework IOKit -framework CoreVideo - LIBS += -L/usr/local/lib -lglfw3 - - CXXFLAGS = -I../../ -I/usr/local/include - CXXFLAGS += -Wall -Wformat -# CXXFLAGS += -D__APPLE__ - CFLAGS = $(CXXFLAGS) -endif - -ifeq ($(UNAME_S), MINGW64_NT-6.3) - ECHO_MESSAGE = "Windows" - LIBS = -lglfw3 -lgdi32 -lopengl32 -limm32 - - CXXFLAGS = -I../../ -I../libs/gl3w `pkg-config --cflags glfw3` - CXXFLAGS += -Wall -Wformat - CFLAGS = $(CXXFLAGS) -endif - -.cpp.o: - $(CXX) $(CXXFLAGS) -c -o $@ $< - -all: $(EXE) - @echo Build complete for $(ECHO_MESSAGE) - -$(EXE): $(OBJS) - $(CXX) -o $(EXE) $(OBJS) $(CXXFLAGS) $(LIBS) - -clean: - rm $(EXE) $(OBJS) - diff --git a/examples/opengl_example/build_win32.bat b/examples/opengl_example/build_win32.bat deleted file mode 100644 index 278381c..0000000 --- a/examples/opengl_example/build_win32.bat +++ /dev/null @@ -1,3 +0,0 @@ -@REM Build for Visual Studio compiler. Run your copy of vcvars32.bat or vcvarsall.bat to setup command-line compiler. -mkdir Debug -cl /nologo /Zi /MD /I ..\.. /I ..\libs\glfw\include *.cpp ..\..\*.cpp /FeDebug/opengl_example.exe /FoDebug/ /link /LIBPATH:..\libs\glfw\lib-vc2010-32 glfw3.lib opengl32.lib gdi32.lib shell32.lib diff --git a/examples/opengl_example/imgui_impl_glfw.cpp b/examples/opengl_example/imgui_impl_glfw.cpp deleted file mode 100644 index 2d1f5c1..0000000 --- a/examples/opengl_example/imgui_impl_glfw.cpp +++ /dev/null @@ -1,288 +0,0 @@ -// ImGui GLFW binding with OpenGL -// In this binding, ImTextureID is used to store an OpenGL 'GLuint' texture identifier. Read the FAQ about ImTextureID in imgui.cpp. - -// If your context is GL3/GL3 then prefer using the code in opengl3_example. -// You *might* use this code with a GL3/GL4 context but make sure you disable the programmable pipeline by calling "glUseProgram(0)" before ImGui::Render(). -// We cannot do that from GL2 code because the function doesn't exist. - -// You can copy and use unmodified imgui_impl_* files in your project. See main.cpp for an example of using this. -// If you use this binding you'll need to call 4 functions: ImGui_ImplXXXX_Init(), ImGui_ImplXXXX_NewFrame(), ImGui::Render() and ImGui_ImplXXXX_Shutdown(). -// If you are new to ImGui, see examples/README.txt and documentation at the top of imgui.cpp. -// https://github.com/ocornut/imgui - -#include -#include "imgui_impl_glfw.h" - -// GLFW -#include -#ifdef _WIN32 -#undef APIENTRY -#define GLFW_EXPOSE_NATIVE_WIN32 -#define GLFW_EXPOSE_NATIVE_WGL -#include -#endif - -// Data -static GLFWwindow* g_Window = NULL; -static double g_Time = 0.0f; -static bool g_MousePressed[3] = { false, false, false }; -static float g_MouseWheel = 0.0f; -static GLuint g_FontTexture = 0; - -// 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) -void ImGui_ImplGlfw_RenderDrawLists(ImDrawData* draw_data) -{ - // Avoid rendering when minimized, scale coordinates for retina displays (screen coordinates != framebuffer coordinates) - ImGuiIO& io = ImGui::GetIO(); - int fb_width = (int)(io.DisplaySize.x * io.DisplayFramebufferScale.x); - int fb_height = (int)(io.DisplaySize.y * io.DisplayFramebufferScale.y); - if (fb_width == 0 || fb_height == 0) - return; - draw_data->ScaleClipRects(io.DisplayFramebufferScale); - - // We are using the OpenGL fixed pipeline to make the example code simpler to read! - // Setup render state: alpha-blending enabled, no face culling, no depth testing, scissor enabled, vertex/texcoord/color pointers. - GLint last_texture; glGetIntegerv(GL_TEXTURE_BINDING_2D, &last_texture); - GLint last_viewport[4]; glGetIntegerv(GL_VIEWPORT, last_viewport); - glPushAttrib(GL_ENABLE_BIT | GL_COLOR_BUFFER_BIT | GL_TRANSFORM_BIT); - glEnable(GL_BLEND); - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - glDisable(GL_CULL_FACE); - glDisable(GL_DEPTH_TEST); - glEnable(GL_SCISSOR_TEST); - glEnableClientState(GL_VERTEX_ARRAY); - glEnableClientState(GL_TEXTURE_COORD_ARRAY); - glEnableClientState(GL_COLOR_ARRAY); - glEnable(GL_TEXTURE_2D); - //glUseProgram(0); // You may want this if using this code in an OpenGL 3+ context - - // Setup viewport, orthographic projection matrix - glViewport(0, 0, (GLsizei)fb_width, (GLsizei)fb_height); - glMatrixMode(GL_PROJECTION); - glPushMatrix(); - glLoadIdentity(); - glOrtho(0.0f, io.DisplaySize.x, io.DisplaySize.y, 0.0f, -1.0f, +1.0f); - glMatrixMode(GL_MODELVIEW); - glPushMatrix(); - glLoadIdentity(); - - // Render command lists - #define OFFSETOF(TYPE, ELEMENT) ((size_t)&(((TYPE *)0)->ELEMENT)) - for (int n = 0; n < draw_data->CmdListsCount; n++) - { - const ImDrawList* cmd_list = draw_data->CmdLists[n]; - const unsigned char* vtx_buffer = (const unsigned char*)&cmd_list->VtxBuffer.front(); - const ImDrawIdx* idx_buffer = &cmd_list->IdxBuffer.front(); - glVertexPointer(2, GL_FLOAT, sizeof(ImDrawVert), (void*)(vtx_buffer + OFFSETOF(ImDrawVert, pos))); - glTexCoordPointer(2, GL_FLOAT, sizeof(ImDrawVert), (void*)(vtx_buffer + OFFSETOF(ImDrawVert, uv))); - glColorPointer(4, GL_UNSIGNED_BYTE, sizeof(ImDrawVert), (void*)(vtx_buffer + OFFSETOF(ImDrawVert, col))); - - for (int cmd_i = 0; cmd_i < cmd_list->CmdBuffer.size(); cmd_i++) - { - const ImDrawCmd* pcmd = &cmd_list->CmdBuffer[cmd_i]; - if (pcmd->UserCallback) - { - pcmd->UserCallback(cmd_list, pcmd); - } - else - { - glBindTexture(GL_TEXTURE_2D, (GLuint)(intptr_t)pcmd->TextureId); - glScissor((int)pcmd->ClipRect.x, (int)(fb_height - pcmd->ClipRect.w), (int)(pcmd->ClipRect.z - pcmd->ClipRect.x), (int)(pcmd->ClipRect.w - pcmd->ClipRect.y)); - glDrawElements(GL_TRIANGLES, (GLsizei)pcmd->ElemCount, sizeof(ImDrawIdx) == 2 ? GL_UNSIGNED_SHORT : GL_UNSIGNED_INT, idx_buffer); - } - idx_buffer += pcmd->ElemCount; - } - } - #undef OFFSETOF - - // Restore modified state - glDisableClientState(GL_COLOR_ARRAY); - glDisableClientState(GL_TEXTURE_COORD_ARRAY); - glDisableClientState(GL_VERTEX_ARRAY); - glBindTexture(GL_TEXTURE_2D, (GLuint)last_texture); - glMatrixMode(GL_MODELVIEW); - glPopMatrix(); - glMatrixMode(GL_PROJECTION); - glPopMatrix(); - glPopAttrib(); - glViewport(last_viewport[0], last_viewport[1], (GLsizei)last_viewport[2], (GLsizei)last_viewport[3]); -} - -static const char* ImGui_ImplGlfw_GetClipboardText() -{ - return glfwGetClipboardString(g_Window); -} - -static void ImGui_ImplGlfw_SetClipboardText(const char* text) -{ - glfwSetClipboardString(g_Window, text); -} - -void ImGui_ImplGlfw_MouseButtonCallback(GLFWwindow*, int button, int action, int /*mods*/) -{ - if (action == GLFW_PRESS && button >= 0 && button < 3) - g_MousePressed[button] = true; -} - -void ImGui_ImplGlfw_ScrollCallback(GLFWwindow*, double /*xoffset*/, double yoffset) -{ - g_MouseWheel += (float)yoffset; // Use fractional mouse wheel, 1.0 unit 5 lines. -} - -void ImGui_ImplGlFw_KeyCallback(GLFWwindow*, int key, int, int action, int mods) -{ - ImGuiIO& io = ImGui::GetIO(); - if (action == GLFW_PRESS) - io.KeysDown[key] = true; - if (action == GLFW_RELEASE) - io.KeysDown[key] = false; - - (void)mods; // Modifiers are not reliable across systems - io.KeyCtrl = io.KeysDown[GLFW_KEY_LEFT_CONTROL] || io.KeysDown[GLFW_KEY_RIGHT_CONTROL]; - io.KeyShift = io.KeysDown[GLFW_KEY_LEFT_SHIFT] || io.KeysDown[GLFW_KEY_RIGHT_SHIFT]; - io.KeyAlt = io.KeysDown[GLFW_KEY_LEFT_ALT] || io.KeysDown[GLFW_KEY_RIGHT_ALT]; - io.KeySuper = io.KeysDown[GLFW_KEY_LEFT_SUPER] || io.KeysDown[GLFW_KEY_RIGHT_SUPER]; -} - -void ImGui_ImplGlfw_CharCallback(GLFWwindow*, unsigned int c) -{ - ImGuiIO& io = ImGui::GetIO(); - if (c > 0 && c < 0x10000) - io.AddInputCharacter((unsigned short)c); -} - -bool ImGui_ImplGlfw_CreateDeviceObjects() -{ - // Build texture atlas - ImGuiIO& io = ImGui::GetIO(); - unsigned char* pixels; - int width, height; - io.Fonts->GetTexDataAsAlpha8(&pixels, &width, &height); - - // Upload texture to graphics system - GLint last_texture; - glGetIntegerv(GL_TEXTURE_BINDING_2D, &last_texture); - glGenTextures(1, &g_FontTexture); - glBindTexture(GL_TEXTURE_2D, g_FontTexture); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, width, height, 0, GL_ALPHA, GL_UNSIGNED_BYTE, pixels); - - // Store our identifier - io.Fonts->TexID = (void *)(intptr_t)g_FontTexture; - - // Restore state - glBindTexture(GL_TEXTURE_2D, last_texture); - - return true; -} - -void ImGui_ImplGlfw_InvalidateDeviceObjects() -{ - if (g_FontTexture) - { - glDeleteTextures(1, &g_FontTexture); - ImGui::GetIO().Fonts->TexID = 0; - g_FontTexture = 0; - } -} - -bool ImGui_ImplGlfw_Init(GLFWwindow* window, bool install_callbacks) -{ - g_Window = window; - - ImGuiIO& io = ImGui::GetIO(); - 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; - io.KeyMap[ImGuiKey_DownArrow] = GLFW_KEY_DOWN; - io.KeyMap[ImGuiKey_PageUp] = GLFW_KEY_PAGE_UP; - io.KeyMap[ImGuiKey_PageDown] = GLFW_KEY_PAGE_DOWN; - io.KeyMap[ImGuiKey_Home] = GLFW_KEY_HOME; - io.KeyMap[ImGuiKey_End] = GLFW_KEY_END; - io.KeyMap[ImGuiKey_Delete] = GLFW_KEY_DELETE; - io.KeyMap[ImGuiKey_Backspace] = GLFW_KEY_BACKSPACE; - io.KeyMap[ImGuiKey_Enter] = GLFW_KEY_ENTER; - io.KeyMap[ImGuiKey_Escape] = GLFW_KEY_ESCAPE; - io.KeyMap[ImGuiKey_A] = GLFW_KEY_A; - io.KeyMap[ImGuiKey_C] = GLFW_KEY_C; - io.KeyMap[ImGuiKey_V] = GLFW_KEY_V; - io.KeyMap[ImGuiKey_X] = GLFW_KEY_X; - io.KeyMap[ImGuiKey_Y] = GLFW_KEY_Y; - io.KeyMap[ImGuiKey_Z] = GLFW_KEY_Z; - - io.RenderDrawListsFn = ImGui_ImplGlfw_RenderDrawLists; // Alternatively you can set this to NULL and call ImGui::GetDrawData() after ImGui::Render() to get the same ImDrawData pointer. - io.SetClipboardTextFn = ImGui_ImplGlfw_SetClipboardText; - io.GetClipboardTextFn = ImGui_ImplGlfw_GetClipboardText; -#ifdef _WIN32 - io.ImeWindowHandle = glfwGetWin32Window(g_Window); -#endif - - if (install_callbacks) - { - glfwSetMouseButtonCallback(window, ImGui_ImplGlfw_MouseButtonCallback); - glfwSetScrollCallback(window, ImGui_ImplGlfw_ScrollCallback); - glfwSetKeyCallback(window, ImGui_ImplGlFw_KeyCallback); - glfwSetCharCallback(window, ImGui_ImplGlfw_CharCallback); - } - - return true; -} - -void ImGui_ImplGlfw_Shutdown() -{ - ImGui_ImplGlfw_InvalidateDeviceObjects(); - ImGui::Shutdown(); -} - -void ImGui_ImplGlfw_NewFrame() -{ - if (!g_FontTexture) - ImGui_ImplGlfw_CreateDeviceObjects(); - - ImGuiIO& io = ImGui::GetIO(); - - // Setup display size (every frame to accommodate for window resizing) - int w, h; - int display_w, display_h; - glfwGetWindowSize(g_Window, &w, &h); - glfwGetFramebufferSize(g_Window, &display_w, &display_h); - io.DisplaySize = ImVec2((float)w, (float)h); - io.DisplayFramebufferScale = ImVec2(w > 0 ? ((float)display_w / w) : 0, h > 0 ? ((float)display_h / h) : 0); - - // Setup time step - double current_time = glfwGetTime(); - io.DeltaTime = g_Time > 0.0 ? (float)(current_time - g_Time) : (float)(1.0f/60.0f); - g_Time = current_time; - - // Setup inputs - // (we already got mouse wheel, keyboard keys & characters from glfw callbacks polled in glfwPollEvents()) - if (glfwGetWindowAttrib(g_Window, GLFW_FOCUSED)) - { - double mouse_x, mouse_y; - glfwGetCursorPos(g_Window, &mouse_x, &mouse_y); - io.MousePos = ImVec2((float)mouse_x, (float)mouse_y); // Mouse position in screen coordinates (set to -1,-1 if no mouse / on another screen, etc.) - } - else - { - io.MousePos = ImVec2(-1,-1); - } - - for (int i = 0; i < 3; i++) - { - io.MouseDown[i] = g_MousePressed[i] || glfwGetMouseButton(g_Window, i) != 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. - g_MousePressed[i] = false; - } - - io.MouseWheel = g_MouseWheel; - g_MouseWheel = 0.0f; - - // Hide OS mouse cursor if ImGui is drawing it - glfwSetInputMode(g_Window, GLFW_CURSOR, io.MouseDrawCursor ? GLFW_CURSOR_HIDDEN : GLFW_CURSOR_NORMAL); - - // Start the frame - ImGui::NewFrame(); -} diff --git a/examples/opengl_example/imgui_impl_glfw.h b/examples/opengl_example/imgui_impl_glfw.h deleted file mode 100644 index 07dd96f..0000000 --- a/examples/opengl_example/imgui_impl_glfw.h +++ /dev/null @@ -1,29 +0,0 @@ -// ImGui GLFW binding with OpenGL -// In this binding, ImTextureID is used to store an OpenGL 'GLuint' texture identifier. Read the FAQ about ImTextureID in imgui.cpp. - -// If your context is GL3/GL3 then prefer using the code in opengl3_example. -// You *might* use this code with a GL3/GL4 context but make sure you disable the programmable pipeline by calling "glUseProgram(0)" before ImGui::Render(). -// We cannot do that from GL2 code because the function doesn't exist. - -// You can copy and use unmodified imgui_impl_* files in your project. See main.cpp for an example of using this. -// If you use this binding you'll need to call 4 functions: ImGui_ImplXXXX_Init(), ImGui_ImplXXXX_NewFrame(), ImGui::Render() and ImGui_ImplXXXX_Shutdown(). -// If you are new to ImGui, see examples/README.txt and documentation at the top of imgui.cpp. -// https://github.com/ocornut/imgui - -struct GLFWwindow; - -IMGUI_API bool ImGui_ImplGlfw_Init(GLFWwindow* window, bool install_callbacks); -IMGUI_API void ImGui_ImplGlfw_Shutdown(); -IMGUI_API void ImGui_ImplGlfw_NewFrame(); - -// Use if you want to reset your rendering device without losing ImGui state. -IMGUI_API void ImGui_ImplGlfw_InvalidateDeviceObjects(); -IMGUI_API bool ImGui_ImplGlfw_CreateDeviceObjects(); - -// GLFW callbacks (installed by default if you enable 'install_callbacks' during initialization) -// Provided here if you want to chain callbacks. -// You can also handle inputs yourself and use those as a reference. -IMGUI_API void ImGui_ImplGlfw_MouseButtonCallback(GLFWwindow* window, int button, int action, int mods); -IMGUI_API void ImGui_ImplGlfw_ScrollCallback(GLFWwindow* window, double xoffset, double yoffset); -IMGUI_API void ImGui_ImplGlFw_KeyCallback(GLFWwindow* window, int key, int scancode, int action, int mods); -IMGUI_API void ImGui_ImplGlfw_CharCallback(GLFWwindow* window, unsigned int c); diff --git a/examples/opengl_example/main.cpp b/examples/opengl_example/main.cpp deleted file mode 100644 index a844db5..0000000 --- a/examples/opengl_example/main.cpp +++ /dev/null @@ -1,89 +0,0 @@ -// ImGui - standalone example application for Glfw + OpenGL 2, using fixed pipeline -// If you are new to ImGui, see examples/README.txt and documentation at the top of imgui.cpp. - -#include -#include "imgui_impl_glfw.h" -#include -#include - -static void error_callback(int error, const char* description) -{ - fprintf(stderr, "Error %d: %s\n", error, description); -} - -int main(int, char**) -{ - // Setup window - glfwSetErrorCallback(error_callback); - if (!glfwInit()) - return 1; - GLFWwindow* window = glfwCreateWindow(1280, 720, "ImGui OpenGL2 example", NULL, NULL); - glfwMakeContextCurrent(window); - - // Setup ImGui binding - ImGui_ImplGlfw_Init(window, true); - - // Load Fonts - // (there is a default font, this is only if you want to change it. see extra_fonts/README.txt for more details) - //ImGuiIO& io = ImGui::GetIO(); - //io.Fonts->AddFontDefault(); - //io.Fonts->AddFontFromFileTTF("../../extra_fonts/Cousine-Regular.ttf", 15.0f); - //io.Fonts->AddFontFromFileTTF("../../extra_fonts/DroidSans.ttf", 16.0f); - //io.Fonts->AddFontFromFileTTF("../../extra_fonts/ProggyClean.ttf", 13.0f); - //io.Fonts->AddFontFromFileTTF("../../extra_fonts/ProggyTiny.ttf", 10.0f); - //io.Fonts->AddFontFromFileTTF("c:\\Windows\\Fonts\\ArialUni.ttf", 18.0f, NULL, io.Fonts->GetGlyphRangesJapanese()); - - bool show_test_window = true; - bool show_another_window = false; - ImVec4 clear_color = ImColor(114, 144, 154); - - // Main loop - while (!glfwWindowShouldClose(window)) - { - glfwPollEvents(); - ImGui_ImplGlfw_NewFrame(); - - // 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 = 0.0f; - ImGui::Text("Hello, world!"); - ImGui::SliderFloat("float", &f, 0.0f, 1.0f); - ImGui::ColorEdit3("clear color", (float*)&clear_color); - if (ImGui::Button("Test Window")) show_test_window ^= 1; - if (ImGui::Button("Another Window")) show_another_window ^= 1; - ImGui::Text("Application average %.3f ms/frame (%.1f FPS)", 1000.0f / ImGui::GetIO().Framerate, ImGui::GetIO().Framerate); - } - - // 2. Show another simple window, this time using an explicit Begin/End pair - if (show_another_window) - { - ImGui::SetNextWindowSize(ImVec2(200,100), ImGuiSetCond_FirstUseEver); - ImGui::Begin("Another Window", &show_another_window); - 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::SetNextWindowPos(ImVec2(650, 20), ImGuiSetCond_FirstUseEver); - ImGui::ShowTestWindow(&show_test_window); - } - - // Rendering - int display_w, display_h; - glfwGetFramebufferSize(window, &display_w, &display_h); - glViewport(0, 0, display_w, display_h); - glClearColor(clear_color.x, clear_color.y, clear_color.z, clear_color.w); - glClear(GL_COLOR_BUFFER_BIT); - ImGui::Render(); - glfwSwapBuffers(window); - } - - // Cleanup - ImGui_ImplGlfw_Shutdown(); - glfwTerminate(); - - return 0; -} diff --git a/examples/README.txt b/examples/README.txt index df2e86d..5a1c8df 100644 --- a/examples/README.txt +++ b/examples/README.txt @@ -8,11 +8,13 @@ TL;DR; - Newcomers, read 'PROGRAMMER GUIDE' in imgui.cpp for notes on how to setup ImGui in your codebase. - - Refer to 'opengl_example' to understand how the library is setup, it is the simplest one. + - Refer to 'opengl2_example' to LEARN how the library is setup, it is the simplest one. The other examples requires more boilerplate and are harder to read. + - If you are using OpenGL in your application, probably use an opengl3_xxx backend. + Mixing old fixed pipeline OpenGL2 and programmable pipeline OpenGL3+ isn't well supported by drivers. - If you are using of the backend provided here, so you can copy the imgui_impl_xxx.cpp/h files to your project and use them unmodified. - - If you have your own engine, you probably want to start from 'opengl_example' and adapt it to + - If you have your own engine, you probably want to start from one of the OpenGL example and adapt it to your engine, but you can read the other examples as well. ImGui is highly portable and only requires a few things to run: @@ -41,15 +43,14 @@ Also note that some setup or GPU drivers may be causing extra lag (possibly by enforcing triple buffering), leaving you with no option but sadness/anger (Intel GPU drivers were reported as such). -opengl_example/ - OpenGL example, using GLFW + fixed pipeline. - This is simple and should work for all OpenGL enabled applications. - Prefer following this example to learn how ImGui works! - (You can use this code in a GL3/GL4 context but make sure you disable the programmable pipeline - by calling "glUseProgram(0)" before ImGui::Render.) +opengl2_example/ + GLFW + OpenGL example (old fixed pipeline). + This is simple to read. Prefer following this example to learn how ImGui works! + (You might be able to use this code in a GL3/GL4 context but make sure you disable the programmable + pipeline by calling "glUseProgram(0)" before ImGui::Render.) opengl3_example/ - OpenGL example, using GLFW/GL3W + programmable pipeline. + GLFW + OpenGL example (programmable pipeline, binding modern functions with GL3W). This uses more modern OpenGL calls and custom shaders. It's more messy. directx9_example/ @@ -68,8 +69,8 @@ On iOS, Using Synergy to access keyboard/mouse data from server computer. Synergy keyboard integration is rather hacky. -sdl_opengl_example/ - SDL2 + OpenGL example. +sdl_opengl2_example/ + SDL2 + OpenGL example (old fixed pipeline). sdl_opengl3_example/ SDL2 + OpenGL3 example. diff --git a/examples/imgui_examples_msvc2010.sln b/examples/imgui_examples_msvc2010.sln index b7e6a25..16f0d60 100644 --- a/examples/imgui_examples_msvc2010.sln +++ b/examples/imgui_examples_msvc2010.sln @@ -1,7 +1,7 @@  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}" +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "opengl2_example", "opengl_example\opengl2_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 diff --git a/examples/opengl2_example/Makefile b/examples/opengl2_example/Makefile new file mode 100644 index 0000000..bd79d1b --- /dev/null +++ b/examples/opengl2_example/Makefile @@ -0,0 +1,60 @@ +# +# Cross Platform Makefile +# Compatible with Ubuntu 14.04.1 and Mac OS X +# +# +# if you using Mac OS X: +# You'll need glfw +# http://www.glfw.org +# + +#CXX = g++ + +EXE = opengl2_example +OBJS = main.o imgui_impl_glfw.o +OBJS += ../../imgui.o ../../imgui_demo.o ../../imgui_draw.o + +UNAME_S := $(shell uname -s) + + +ifeq ($(UNAME_S), Linux) #LINUX + ECHO_MESSAGE = "Linux" + LIBS = -lGL `pkg-config --static --libs glfw3` + + CXXFLAGS = -I../../ `pkg-config --cflags glfw3` + CXXFLAGS += -Wall -Wformat + CFLAGS = $(CXXFLAGS) +endif + +ifeq ($(UNAME_S), Darwin) #APPLE + ECHO_MESSAGE = "Mac OS X" + LIBS = -framework OpenGL -framework Cocoa -framework IOKit -framework CoreVideo + LIBS += -L/usr/local/lib -lglfw3 + + CXXFLAGS = -I../../ -I/usr/local/include + CXXFLAGS += -Wall -Wformat +# CXXFLAGS += -D__APPLE__ + CFLAGS = $(CXXFLAGS) +endif + +ifeq ($(UNAME_S), MINGW64_NT-6.3) + ECHO_MESSAGE = "Windows" + LIBS = -lglfw3 -lgdi32 -lopengl32 -limm32 + + CXXFLAGS = -I../../ -I../libs/gl3w `pkg-config --cflags glfw3` + CXXFLAGS += -Wall -Wformat + CFLAGS = $(CXXFLAGS) +endif + +.cpp.o: + $(CXX) $(CXXFLAGS) -c -o $@ $< + +all: $(EXE) + @echo Build complete for $(ECHO_MESSAGE) + +$(EXE): $(OBJS) + $(CXX) -o $(EXE) $(OBJS) $(CXXFLAGS) $(LIBS) + +clean: + rm $(EXE) $(OBJS) + diff --git a/examples/opengl2_example/build_win32.bat b/examples/opengl2_example/build_win32.bat new file mode 100644 index 0000000..278381c --- /dev/null +++ b/examples/opengl2_example/build_win32.bat @@ -0,0 +1,3 @@ +@REM Build for Visual Studio compiler. Run your copy of vcvars32.bat or vcvarsall.bat to setup command-line compiler. +mkdir Debug +cl /nologo /Zi /MD /I ..\.. /I ..\libs\glfw\include *.cpp ..\..\*.cpp /FeDebug/opengl_example.exe /FoDebug/ /link /LIBPATH:..\libs\glfw\lib-vc2010-32 glfw3.lib opengl32.lib gdi32.lib shell32.lib diff --git a/examples/opengl2_example/imgui_impl_glfw.cpp b/examples/opengl2_example/imgui_impl_glfw.cpp new file mode 100644 index 0000000..2d1f5c1 --- /dev/null +++ b/examples/opengl2_example/imgui_impl_glfw.cpp @@ -0,0 +1,288 @@ +// ImGui GLFW binding with OpenGL +// In this binding, ImTextureID is used to store an OpenGL 'GLuint' texture identifier. Read the FAQ about ImTextureID in imgui.cpp. + +// If your context is GL3/GL3 then prefer using the code in opengl3_example. +// You *might* use this code with a GL3/GL4 context but make sure you disable the programmable pipeline by calling "glUseProgram(0)" before ImGui::Render(). +// We cannot do that from GL2 code because the function doesn't exist. + +// You can copy and use unmodified imgui_impl_* files in your project. See main.cpp for an example of using this. +// If you use this binding you'll need to call 4 functions: ImGui_ImplXXXX_Init(), ImGui_ImplXXXX_NewFrame(), ImGui::Render() and ImGui_ImplXXXX_Shutdown(). +// If you are new to ImGui, see examples/README.txt and documentation at the top of imgui.cpp. +// https://github.com/ocornut/imgui + +#include +#include "imgui_impl_glfw.h" + +// GLFW +#include +#ifdef _WIN32 +#undef APIENTRY +#define GLFW_EXPOSE_NATIVE_WIN32 +#define GLFW_EXPOSE_NATIVE_WGL +#include +#endif + +// Data +static GLFWwindow* g_Window = NULL; +static double g_Time = 0.0f; +static bool g_MousePressed[3] = { false, false, false }; +static float g_MouseWheel = 0.0f; +static GLuint g_FontTexture = 0; + +// 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) +void ImGui_ImplGlfw_RenderDrawLists(ImDrawData* draw_data) +{ + // Avoid rendering when minimized, scale coordinates for retina displays (screen coordinates != framebuffer coordinates) + ImGuiIO& io = ImGui::GetIO(); + int fb_width = (int)(io.DisplaySize.x * io.DisplayFramebufferScale.x); + int fb_height = (int)(io.DisplaySize.y * io.DisplayFramebufferScale.y); + if (fb_width == 0 || fb_height == 0) + return; + draw_data->ScaleClipRects(io.DisplayFramebufferScale); + + // We are using the OpenGL fixed pipeline to make the example code simpler to read! + // Setup render state: alpha-blending enabled, no face culling, no depth testing, scissor enabled, vertex/texcoord/color pointers. + GLint last_texture; glGetIntegerv(GL_TEXTURE_BINDING_2D, &last_texture); + GLint last_viewport[4]; glGetIntegerv(GL_VIEWPORT, last_viewport); + glPushAttrib(GL_ENABLE_BIT | GL_COLOR_BUFFER_BIT | GL_TRANSFORM_BIT); + glEnable(GL_BLEND); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + glDisable(GL_CULL_FACE); + glDisable(GL_DEPTH_TEST); + glEnable(GL_SCISSOR_TEST); + glEnableClientState(GL_VERTEX_ARRAY); + glEnableClientState(GL_TEXTURE_COORD_ARRAY); + glEnableClientState(GL_COLOR_ARRAY); + glEnable(GL_TEXTURE_2D); + //glUseProgram(0); // You may want this if using this code in an OpenGL 3+ context + + // Setup viewport, orthographic projection matrix + glViewport(0, 0, (GLsizei)fb_width, (GLsizei)fb_height); + glMatrixMode(GL_PROJECTION); + glPushMatrix(); + glLoadIdentity(); + glOrtho(0.0f, io.DisplaySize.x, io.DisplaySize.y, 0.0f, -1.0f, +1.0f); + glMatrixMode(GL_MODELVIEW); + glPushMatrix(); + glLoadIdentity(); + + // Render command lists + #define OFFSETOF(TYPE, ELEMENT) ((size_t)&(((TYPE *)0)->ELEMENT)) + for (int n = 0; n < draw_data->CmdListsCount; n++) + { + const ImDrawList* cmd_list = draw_data->CmdLists[n]; + const unsigned char* vtx_buffer = (const unsigned char*)&cmd_list->VtxBuffer.front(); + const ImDrawIdx* idx_buffer = &cmd_list->IdxBuffer.front(); + glVertexPointer(2, GL_FLOAT, sizeof(ImDrawVert), (void*)(vtx_buffer + OFFSETOF(ImDrawVert, pos))); + glTexCoordPointer(2, GL_FLOAT, sizeof(ImDrawVert), (void*)(vtx_buffer + OFFSETOF(ImDrawVert, uv))); + glColorPointer(4, GL_UNSIGNED_BYTE, sizeof(ImDrawVert), (void*)(vtx_buffer + OFFSETOF(ImDrawVert, col))); + + for (int cmd_i = 0; cmd_i < cmd_list->CmdBuffer.size(); cmd_i++) + { + const ImDrawCmd* pcmd = &cmd_list->CmdBuffer[cmd_i]; + if (pcmd->UserCallback) + { + pcmd->UserCallback(cmd_list, pcmd); + } + else + { + glBindTexture(GL_TEXTURE_2D, (GLuint)(intptr_t)pcmd->TextureId); + glScissor((int)pcmd->ClipRect.x, (int)(fb_height - pcmd->ClipRect.w), (int)(pcmd->ClipRect.z - pcmd->ClipRect.x), (int)(pcmd->ClipRect.w - pcmd->ClipRect.y)); + glDrawElements(GL_TRIANGLES, (GLsizei)pcmd->ElemCount, sizeof(ImDrawIdx) == 2 ? GL_UNSIGNED_SHORT : GL_UNSIGNED_INT, idx_buffer); + } + idx_buffer += pcmd->ElemCount; + } + } + #undef OFFSETOF + + // Restore modified state + glDisableClientState(GL_COLOR_ARRAY); + glDisableClientState(GL_TEXTURE_COORD_ARRAY); + glDisableClientState(GL_VERTEX_ARRAY); + glBindTexture(GL_TEXTURE_2D, (GLuint)last_texture); + glMatrixMode(GL_MODELVIEW); + glPopMatrix(); + glMatrixMode(GL_PROJECTION); + glPopMatrix(); + glPopAttrib(); + glViewport(last_viewport[0], last_viewport[1], (GLsizei)last_viewport[2], (GLsizei)last_viewport[3]); +} + +static const char* ImGui_ImplGlfw_GetClipboardText() +{ + return glfwGetClipboardString(g_Window); +} + +static void ImGui_ImplGlfw_SetClipboardText(const char* text) +{ + glfwSetClipboardString(g_Window, text); +} + +void ImGui_ImplGlfw_MouseButtonCallback(GLFWwindow*, int button, int action, int /*mods*/) +{ + if (action == GLFW_PRESS && button >= 0 && button < 3) + g_MousePressed[button] = true; +} + +void ImGui_ImplGlfw_ScrollCallback(GLFWwindow*, double /*xoffset*/, double yoffset) +{ + g_MouseWheel += (float)yoffset; // Use fractional mouse wheel, 1.0 unit 5 lines. +} + +void ImGui_ImplGlFw_KeyCallback(GLFWwindow*, int key, int, int action, int mods) +{ + ImGuiIO& io = ImGui::GetIO(); + if (action == GLFW_PRESS) + io.KeysDown[key] = true; + if (action == GLFW_RELEASE) + io.KeysDown[key] = false; + + (void)mods; // Modifiers are not reliable across systems + io.KeyCtrl = io.KeysDown[GLFW_KEY_LEFT_CONTROL] || io.KeysDown[GLFW_KEY_RIGHT_CONTROL]; + io.KeyShift = io.KeysDown[GLFW_KEY_LEFT_SHIFT] || io.KeysDown[GLFW_KEY_RIGHT_SHIFT]; + io.KeyAlt = io.KeysDown[GLFW_KEY_LEFT_ALT] || io.KeysDown[GLFW_KEY_RIGHT_ALT]; + io.KeySuper = io.KeysDown[GLFW_KEY_LEFT_SUPER] || io.KeysDown[GLFW_KEY_RIGHT_SUPER]; +} + +void ImGui_ImplGlfw_CharCallback(GLFWwindow*, unsigned int c) +{ + ImGuiIO& io = ImGui::GetIO(); + if (c > 0 && c < 0x10000) + io.AddInputCharacter((unsigned short)c); +} + +bool ImGui_ImplGlfw_CreateDeviceObjects() +{ + // Build texture atlas + ImGuiIO& io = ImGui::GetIO(); + unsigned char* pixels; + int width, height; + io.Fonts->GetTexDataAsAlpha8(&pixels, &width, &height); + + // Upload texture to graphics system + GLint last_texture; + glGetIntegerv(GL_TEXTURE_BINDING_2D, &last_texture); + glGenTextures(1, &g_FontTexture); + glBindTexture(GL_TEXTURE_2D, g_FontTexture); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, width, height, 0, GL_ALPHA, GL_UNSIGNED_BYTE, pixels); + + // Store our identifier + io.Fonts->TexID = (void *)(intptr_t)g_FontTexture; + + // Restore state + glBindTexture(GL_TEXTURE_2D, last_texture); + + return true; +} + +void ImGui_ImplGlfw_InvalidateDeviceObjects() +{ + if (g_FontTexture) + { + glDeleteTextures(1, &g_FontTexture); + ImGui::GetIO().Fonts->TexID = 0; + g_FontTexture = 0; + } +} + +bool ImGui_ImplGlfw_Init(GLFWwindow* window, bool install_callbacks) +{ + g_Window = window; + + ImGuiIO& io = ImGui::GetIO(); + 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; + io.KeyMap[ImGuiKey_DownArrow] = GLFW_KEY_DOWN; + io.KeyMap[ImGuiKey_PageUp] = GLFW_KEY_PAGE_UP; + io.KeyMap[ImGuiKey_PageDown] = GLFW_KEY_PAGE_DOWN; + io.KeyMap[ImGuiKey_Home] = GLFW_KEY_HOME; + io.KeyMap[ImGuiKey_End] = GLFW_KEY_END; + io.KeyMap[ImGuiKey_Delete] = GLFW_KEY_DELETE; + io.KeyMap[ImGuiKey_Backspace] = GLFW_KEY_BACKSPACE; + io.KeyMap[ImGuiKey_Enter] = GLFW_KEY_ENTER; + io.KeyMap[ImGuiKey_Escape] = GLFW_KEY_ESCAPE; + io.KeyMap[ImGuiKey_A] = GLFW_KEY_A; + io.KeyMap[ImGuiKey_C] = GLFW_KEY_C; + io.KeyMap[ImGuiKey_V] = GLFW_KEY_V; + io.KeyMap[ImGuiKey_X] = GLFW_KEY_X; + io.KeyMap[ImGuiKey_Y] = GLFW_KEY_Y; + io.KeyMap[ImGuiKey_Z] = GLFW_KEY_Z; + + io.RenderDrawListsFn = ImGui_ImplGlfw_RenderDrawLists; // Alternatively you can set this to NULL and call ImGui::GetDrawData() after ImGui::Render() to get the same ImDrawData pointer. + io.SetClipboardTextFn = ImGui_ImplGlfw_SetClipboardText; + io.GetClipboardTextFn = ImGui_ImplGlfw_GetClipboardText; +#ifdef _WIN32 + io.ImeWindowHandle = glfwGetWin32Window(g_Window); +#endif + + if (install_callbacks) + { + glfwSetMouseButtonCallback(window, ImGui_ImplGlfw_MouseButtonCallback); + glfwSetScrollCallback(window, ImGui_ImplGlfw_ScrollCallback); + glfwSetKeyCallback(window, ImGui_ImplGlFw_KeyCallback); + glfwSetCharCallback(window, ImGui_ImplGlfw_CharCallback); + } + + return true; +} + +void ImGui_ImplGlfw_Shutdown() +{ + ImGui_ImplGlfw_InvalidateDeviceObjects(); + ImGui::Shutdown(); +} + +void ImGui_ImplGlfw_NewFrame() +{ + if (!g_FontTexture) + ImGui_ImplGlfw_CreateDeviceObjects(); + + ImGuiIO& io = ImGui::GetIO(); + + // Setup display size (every frame to accommodate for window resizing) + int w, h; + int display_w, display_h; + glfwGetWindowSize(g_Window, &w, &h); + glfwGetFramebufferSize(g_Window, &display_w, &display_h); + io.DisplaySize = ImVec2((float)w, (float)h); + io.DisplayFramebufferScale = ImVec2(w > 0 ? ((float)display_w / w) : 0, h > 0 ? ((float)display_h / h) : 0); + + // Setup time step + double current_time = glfwGetTime(); + io.DeltaTime = g_Time > 0.0 ? (float)(current_time - g_Time) : (float)(1.0f/60.0f); + g_Time = current_time; + + // Setup inputs + // (we already got mouse wheel, keyboard keys & characters from glfw callbacks polled in glfwPollEvents()) + if (glfwGetWindowAttrib(g_Window, GLFW_FOCUSED)) + { + double mouse_x, mouse_y; + glfwGetCursorPos(g_Window, &mouse_x, &mouse_y); + io.MousePos = ImVec2((float)mouse_x, (float)mouse_y); // Mouse position in screen coordinates (set to -1,-1 if no mouse / on another screen, etc.) + } + else + { + io.MousePos = ImVec2(-1,-1); + } + + for (int i = 0; i < 3; i++) + { + io.MouseDown[i] = g_MousePressed[i] || glfwGetMouseButton(g_Window, i) != 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. + g_MousePressed[i] = false; + } + + io.MouseWheel = g_MouseWheel; + g_MouseWheel = 0.0f; + + // Hide OS mouse cursor if ImGui is drawing it + glfwSetInputMode(g_Window, GLFW_CURSOR, io.MouseDrawCursor ? GLFW_CURSOR_HIDDEN : GLFW_CURSOR_NORMAL); + + // Start the frame + ImGui::NewFrame(); +} diff --git a/examples/opengl2_example/imgui_impl_glfw.h b/examples/opengl2_example/imgui_impl_glfw.h new file mode 100644 index 0000000..07dd96f --- /dev/null +++ b/examples/opengl2_example/imgui_impl_glfw.h @@ -0,0 +1,29 @@ +// ImGui GLFW binding with OpenGL +// In this binding, ImTextureID is used to store an OpenGL 'GLuint' texture identifier. Read the FAQ about ImTextureID in imgui.cpp. + +// If your context is GL3/GL3 then prefer using the code in opengl3_example. +// You *might* use this code with a GL3/GL4 context but make sure you disable the programmable pipeline by calling "glUseProgram(0)" before ImGui::Render(). +// We cannot do that from GL2 code because the function doesn't exist. + +// You can copy and use unmodified imgui_impl_* files in your project. See main.cpp for an example of using this. +// If you use this binding you'll need to call 4 functions: ImGui_ImplXXXX_Init(), ImGui_ImplXXXX_NewFrame(), ImGui::Render() and ImGui_ImplXXXX_Shutdown(). +// If you are new to ImGui, see examples/README.txt and documentation at the top of imgui.cpp. +// https://github.com/ocornut/imgui + +struct GLFWwindow; + +IMGUI_API bool ImGui_ImplGlfw_Init(GLFWwindow* window, bool install_callbacks); +IMGUI_API void ImGui_ImplGlfw_Shutdown(); +IMGUI_API void ImGui_ImplGlfw_NewFrame(); + +// Use if you want to reset your rendering device without losing ImGui state. +IMGUI_API void ImGui_ImplGlfw_InvalidateDeviceObjects(); +IMGUI_API bool ImGui_ImplGlfw_CreateDeviceObjects(); + +// GLFW callbacks (installed by default if you enable 'install_callbacks' during initialization) +// Provided here if you want to chain callbacks. +// You can also handle inputs yourself and use those as a reference. +IMGUI_API void ImGui_ImplGlfw_MouseButtonCallback(GLFWwindow* window, int button, int action, int mods); +IMGUI_API void ImGui_ImplGlfw_ScrollCallback(GLFWwindow* window, double xoffset, double yoffset); +IMGUI_API void ImGui_ImplGlFw_KeyCallback(GLFWwindow* window, int key, int scancode, int action, int mods); +IMGUI_API void ImGui_ImplGlfw_CharCallback(GLFWwindow* window, unsigned int c); diff --git a/examples/opengl2_example/main.cpp b/examples/opengl2_example/main.cpp new file mode 100644 index 0000000..a844db5 --- /dev/null +++ b/examples/opengl2_example/main.cpp @@ -0,0 +1,89 @@ +// ImGui - standalone example application for Glfw + OpenGL 2, using fixed pipeline +// If you are new to ImGui, see examples/README.txt and documentation at the top of imgui.cpp. + +#include +#include "imgui_impl_glfw.h" +#include +#include + +static void error_callback(int error, const char* description) +{ + fprintf(stderr, "Error %d: %s\n", error, description); +} + +int main(int, char**) +{ + // Setup window + glfwSetErrorCallback(error_callback); + if (!glfwInit()) + return 1; + GLFWwindow* window = glfwCreateWindow(1280, 720, "ImGui OpenGL2 example", NULL, NULL); + glfwMakeContextCurrent(window); + + // Setup ImGui binding + ImGui_ImplGlfw_Init(window, true); + + // Load Fonts + // (there is a default font, this is only if you want to change it. see extra_fonts/README.txt for more details) + //ImGuiIO& io = ImGui::GetIO(); + //io.Fonts->AddFontDefault(); + //io.Fonts->AddFontFromFileTTF("../../extra_fonts/Cousine-Regular.ttf", 15.0f); + //io.Fonts->AddFontFromFileTTF("../../extra_fonts/DroidSans.ttf", 16.0f); + //io.Fonts->AddFontFromFileTTF("../../extra_fonts/ProggyClean.ttf", 13.0f); + //io.Fonts->AddFontFromFileTTF("../../extra_fonts/ProggyTiny.ttf", 10.0f); + //io.Fonts->AddFontFromFileTTF("c:\\Windows\\Fonts\\ArialUni.ttf", 18.0f, NULL, io.Fonts->GetGlyphRangesJapanese()); + + bool show_test_window = true; + bool show_another_window = false; + ImVec4 clear_color = ImColor(114, 144, 154); + + // Main loop + while (!glfwWindowShouldClose(window)) + { + glfwPollEvents(); + ImGui_ImplGlfw_NewFrame(); + + // 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 = 0.0f; + ImGui::Text("Hello, world!"); + ImGui::SliderFloat("float", &f, 0.0f, 1.0f); + ImGui::ColorEdit3("clear color", (float*)&clear_color); + if (ImGui::Button("Test Window")) show_test_window ^= 1; + if (ImGui::Button("Another Window")) show_another_window ^= 1; + ImGui::Text("Application average %.3f ms/frame (%.1f FPS)", 1000.0f / ImGui::GetIO().Framerate, ImGui::GetIO().Framerate); + } + + // 2. Show another simple window, this time using an explicit Begin/End pair + if (show_another_window) + { + ImGui::SetNextWindowSize(ImVec2(200,100), ImGuiSetCond_FirstUseEver); + ImGui::Begin("Another Window", &show_another_window); + 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::SetNextWindowPos(ImVec2(650, 20), ImGuiSetCond_FirstUseEver); + ImGui::ShowTestWindow(&show_test_window); + } + + // Rendering + int display_w, display_h; + glfwGetFramebufferSize(window, &display_w, &display_h); + glViewport(0, 0, display_w, display_h); + glClearColor(clear_color.x, clear_color.y, clear_color.z, clear_color.w); + glClear(GL_COLOR_BUFFER_BIT); + ImGui::Render(); + glfwSwapBuffers(window); + } + + // Cleanup + ImGui_ImplGlfw_Shutdown(); + glfwTerminate(); + + return 0; +} diff --git a/examples/opengl2_example/opengl_example.vcxproj b/examples/opengl2_example/opengl_example.vcxproj new file mode 100644 index 0000000..4b354b6 --- /dev/null +++ b/examples/opengl2_example/opengl_example.vcxproj @@ -0,0 +1,169 @@ + + + + + Debug + Win32 + + + Debug + x64 + + + Release + Win32 + + + Release + x64 + + + + {9CDA7840-B7A5-496D-A527-E95571496D18} + opengl_example + + + + Application + true + MultiByte + + + Application + true + MultiByte + + + Application + false + true + MultiByte + + + Application + false + true + MultiByte + + + + + + + + + + + + + + + + + + + $(ProjectDir)$(Configuration)\ + $(ProjectDir)$(Configuration)\ + $(IncludePath) + + + $(ProjectDir)$(Configuration)\ + $(ProjectDir)$(Configuration)\ + $(IncludePath) + + + $(ProjectDir)$(Configuration)\ + $(ProjectDir)$(Configuration)\ + $(IncludePath) + + + $(ProjectDir)$(Configuration)\ + $(ProjectDir)$(Configuration)\ + $(IncludePath) + + + + Level4 + Disabled + $(SolutionDir)\libs\glfw\include;..\..;%(AdditionalIncludeDirectories) + + + true + $(SolutionDir)\libs\glfw\lib-vc2010-32;%(AdditionalLibraryDirectories) + opengl32.lib;glfw3.lib;%(AdditionalDependencies) + Console + msvcrt.lib + + + + + Level4 + Disabled + $(SolutionDir)\libs\glfw\include;..\..;%(AdditionalIncludeDirectories) + + + true + $(SolutionDir)\libs\glfw\lib-vc2010-64;%(AdditionalLibraryDirectories) + opengl32.lib;glfw3.lib;%(AdditionalDependencies) + Console + msvcrt.lib + + + + + Level4 + MaxSpeed + true + true + $(SolutionDir)\libs\glfw\include;..\..;%(AdditionalIncludeDirectories) + + + true + true + true + $(SolutionDir)\libs\glfw\lib-vc2010-32;%(AdditionalLibraryDirectories) + opengl32.lib;glfw3.lib;%(AdditionalDependencies) + Console + + + + + + + Level4 + MaxSpeed + true + true + $(SolutionDir)\libs\glfw\include;..\..;%(AdditionalIncludeDirectories) + + + true + true + true + $(SolutionDir)\libs\glfw\lib-vc2010-64;%(AdditionalLibraryDirectories) + opengl32.lib;glfw3.lib;%(AdditionalDependencies) + Console + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/examples/opengl2_example/opengl_example.vcxproj.filters b/examples/opengl2_example/opengl_example.vcxproj.filters new file mode 100644 index 0000000..f2282bf --- /dev/null +++ b/examples/opengl2_example/opengl_example.vcxproj.filters @@ -0,0 +1,46 @@ + + + + + {c336cfe3-f0c4-464c-9ef0-a9e17a7ff222} + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx + + + + + sources + + + imgui + + + sources + + + imgui + + + imgui + + + + + imgui + + + imgui + + + sources + + + imgui + + + + + + \ No newline at end of file diff --git a/examples/opengl_example/Makefile b/examples/opengl_example/Makefile deleted file mode 100644 index 91d1b14..0000000 --- a/examples/opengl_example/Makefile +++ /dev/null @@ -1,60 +0,0 @@ -# -# Cross Platform Makefile -# Compatible with Ubuntu 14.04.1 and Mac OS X -# -# -# if you using Mac OS X: -# You'll need glfw -# http://www.glfw.org -# - -#CXX = g++ - -EXE = opengl_example -OBJS = main.o imgui_impl_glfw.o -OBJS += ../../imgui.o ../../imgui_demo.o ../../imgui_draw.o - -UNAME_S := $(shell uname -s) - - -ifeq ($(UNAME_S), Linux) #LINUX - ECHO_MESSAGE = "Linux" - LIBS = -lGL `pkg-config --static --libs glfw3` - - CXXFLAGS = -I../../ `pkg-config --cflags glfw3` - CXXFLAGS += -Wall -Wformat - CFLAGS = $(CXXFLAGS) -endif - -ifeq ($(UNAME_S), Darwin) #APPLE - ECHO_MESSAGE = "Mac OS X" - LIBS = -framework OpenGL -framework Cocoa -framework IOKit -framework CoreVideo - LIBS += -L/usr/local/lib -lglfw3 - - CXXFLAGS = -I../../ -I/usr/local/include - CXXFLAGS += -Wall -Wformat -# CXXFLAGS += -D__APPLE__ - CFLAGS = $(CXXFLAGS) -endif - -ifeq ($(UNAME_S), MINGW64_NT-6.3) - ECHO_MESSAGE = "Windows" - LIBS = -lglfw3 -lgdi32 -lopengl32 -limm32 - - CXXFLAGS = -I../../ -I../libs/gl3w `pkg-config --cflags glfw3` - CXXFLAGS += -Wall -Wformat - CFLAGS = $(CXXFLAGS) -endif - -.cpp.o: - $(CXX) $(CXXFLAGS) -c -o $@ $< - -all: $(EXE) - @echo Build complete for $(ECHO_MESSAGE) - -$(EXE): $(OBJS) - $(CXX) -o $(EXE) $(OBJS) $(CXXFLAGS) $(LIBS) - -clean: - rm $(EXE) $(OBJS) - diff --git a/examples/opengl_example/build_win32.bat b/examples/opengl_example/build_win32.bat deleted file mode 100644 index 278381c..0000000 --- a/examples/opengl_example/build_win32.bat +++ /dev/null @@ -1,3 +0,0 @@ -@REM Build for Visual Studio compiler. Run your copy of vcvars32.bat or vcvarsall.bat to setup command-line compiler. -mkdir Debug -cl /nologo /Zi /MD /I ..\.. /I ..\libs\glfw\include *.cpp ..\..\*.cpp /FeDebug/opengl_example.exe /FoDebug/ /link /LIBPATH:..\libs\glfw\lib-vc2010-32 glfw3.lib opengl32.lib gdi32.lib shell32.lib diff --git a/examples/opengl_example/imgui_impl_glfw.cpp b/examples/opengl_example/imgui_impl_glfw.cpp deleted file mode 100644 index 2d1f5c1..0000000 --- a/examples/opengl_example/imgui_impl_glfw.cpp +++ /dev/null @@ -1,288 +0,0 @@ -// ImGui GLFW binding with OpenGL -// In this binding, ImTextureID is used to store an OpenGL 'GLuint' texture identifier. Read the FAQ about ImTextureID in imgui.cpp. - -// If your context is GL3/GL3 then prefer using the code in opengl3_example. -// You *might* use this code with a GL3/GL4 context but make sure you disable the programmable pipeline by calling "glUseProgram(0)" before ImGui::Render(). -// We cannot do that from GL2 code because the function doesn't exist. - -// You can copy and use unmodified imgui_impl_* files in your project. See main.cpp for an example of using this. -// If you use this binding you'll need to call 4 functions: ImGui_ImplXXXX_Init(), ImGui_ImplXXXX_NewFrame(), ImGui::Render() and ImGui_ImplXXXX_Shutdown(). -// If you are new to ImGui, see examples/README.txt and documentation at the top of imgui.cpp. -// https://github.com/ocornut/imgui - -#include -#include "imgui_impl_glfw.h" - -// GLFW -#include -#ifdef _WIN32 -#undef APIENTRY -#define GLFW_EXPOSE_NATIVE_WIN32 -#define GLFW_EXPOSE_NATIVE_WGL -#include -#endif - -// Data -static GLFWwindow* g_Window = NULL; -static double g_Time = 0.0f; -static bool g_MousePressed[3] = { false, false, false }; -static float g_MouseWheel = 0.0f; -static GLuint g_FontTexture = 0; - -// 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) -void ImGui_ImplGlfw_RenderDrawLists(ImDrawData* draw_data) -{ - // Avoid rendering when minimized, scale coordinates for retina displays (screen coordinates != framebuffer coordinates) - ImGuiIO& io = ImGui::GetIO(); - int fb_width = (int)(io.DisplaySize.x * io.DisplayFramebufferScale.x); - int fb_height = (int)(io.DisplaySize.y * io.DisplayFramebufferScale.y); - if (fb_width == 0 || fb_height == 0) - return; - draw_data->ScaleClipRects(io.DisplayFramebufferScale); - - // We are using the OpenGL fixed pipeline to make the example code simpler to read! - // Setup render state: alpha-blending enabled, no face culling, no depth testing, scissor enabled, vertex/texcoord/color pointers. - GLint last_texture; glGetIntegerv(GL_TEXTURE_BINDING_2D, &last_texture); - GLint last_viewport[4]; glGetIntegerv(GL_VIEWPORT, last_viewport); - glPushAttrib(GL_ENABLE_BIT | GL_COLOR_BUFFER_BIT | GL_TRANSFORM_BIT); - glEnable(GL_BLEND); - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - glDisable(GL_CULL_FACE); - glDisable(GL_DEPTH_TEST); - glEnable(GL_SCISSOR_TEST); - glEnableClientState(GL_VERTEX_ARRAY); - glEnableClientState(GL_TEXTURE_COORD_ARRAY); - glEnableClientState(GL_COLOR_ARRAY); - glEnable(GL_TEXTURE_2D); - //glUseProgram(0); // You may want this if using this code in an OpenGL 3+ context - - // Setup viewport, orthographic projection matrix - glViewport(0, 0, (GLsizei)fb_width, (GLsizei)fb_height); - glMatrixMode(GL_PROJECTION); - glPushMatrix(); - glLoadIdentity(); - glOrtho(0.0f, io.DisplaySize.x, io.DisplaySize.y, 0.0f, -1.0f, +1.0f); - glMatrixMode(GL_MODELVIEW); - glPushMatrix(); - glLoadIdentity(); - - // Render command lists - #define OFFSETOF(TYPE, ELEMENT) ((size_t)&(((TYPE *)0)->ELEMENT)) - for (int n = 0; n < draw_data->CmdListsCount; n++) - { - const ImDrawList* cmd_list = draw_data->CmdLists[n]; - const unsigned char* vtx_buffer = (const unsigned char*)&cmd_list->VtxBuffer.front(); - const ImDrawIdx* idx_buffer = &cmd_list->IdxBuffer.front(); - glVertexPointer(2, GL_FLOAT, sizeof(ImDrawVert), (void*)(vtx_buffer + OFFSETOF(ImDrawVert, pos))); - glTexCoordPointer(2, GL_FLOAT, sizeof(ImDrawVert), (void*)(vtx_buffer + OFFSETOF(ImDrawVert, uv))); - glColorPointer(4, GL_UNSIGNED_BYTE, sizeof(ImDrawVert), (void*)(vtx_buffer + OFFSETOF(ImDrawVert, col))); - - for (int cmd_i = 0; cmd_i < cmd_list->CmdBuffer.size(); cmd_i++) - { - const ImDrawCmd* pcmd = &cmd_list->CmdBuffer[cmd_i]; - if (pcmd->UserCallback) - { - pcmd->UserCallback(cmd_list, pcmd); - } - else - { - glBindTexture(GL_TEXTURE_2D, (GLuint)(intptr_t)pcmd->TextureId); - glScissor((int)pcmd->ClipRect.x, (int)(fb_height - pcmd->ClipRect.w), (int)(pcmd->ClipRect.z - pcmd->ClipRect.x), (int)(pcmd->ClipRect.w - pcmd->ClipRect.y)); - glDrawElements(GL_TRIANGLES, (GLsizei)pcmd->ElemCount, sizeof(ImDrawIdx) == 2 ? GL_UNSIGNED_SHORT : GL_UNSIGNED_INT, idx_buffer); - } - idx_buffer += pcmd->ElemCount; - } - } - #undef OFFSETOF - - // Restore modified state - glDisableClientState(GL_COLOR_ARRAY); - glDisableClientState(GL_TEXTURE_COORD_ARRAY); - glDisableClientState(GL_VERTEX_ARRAY); - glBindTexture(GL_TEXTURE_2D, (GLuint)last_texture); - glMatrixMode(GL_MODELVIEW); - glPopMatrix(); - glMatrixMode(GL_PROJECTION); - glPopMatrix(); - glPopAttrib(); - glViewport(last_viewport[0], last_viewport[1], (GLsizei)last_viewport[2], (GLsizei)last_viewport[3]); -} - -static const char* ImGui_ImplGlfw_GetClipboardText() -{ - return glfwGetClipboardString(g_Window); -} - -static void ImGui_ImplGlfw_SetClipboardText(const char* text) -{ - glfwSetClipboardString(g_Window, text); -} - -void ImGui_ImplGlfw_MouseButtonCallback(GLFWwindow*, int button, int action, int /*mods*/) -{ - if (action == GLFW_PRESS && button >= 0 && button < 3) - g_MousePressed[button] = true; -} - -void ImGui_ImplGlfw_ScrollCallback(GLFWwindow*, double /*xoffset*/, double yoffset) -{ - g_MouseWheel += (float)yoffset; // Use fractional mouse wheel, 1.0 unit 5 lines. -} - -void ImGui_ImplGlFw_KeyCallback(GLFWwindow*, int key, int, int action, int mods) -{ - ImGuiIO& io = ImGui::GetIO(); - if (action == GLFW_PRESS) - io.KeysDown[key] = true; - if (action == GLFW_RELEASE) - io.KeysDown[key] = false; - - (void)mods; // Modifiers are not reliable across systems - io.KeyCtrl = io.KeysDown[GLFW_KEY_LEFT_CONTROL] || io.KeysDown[GLFW_KEY_RIGHT_CONTROL]; - io.KeyShift = io.KeysDown[GLFW_KEY_LEFT_SHIFT] || io.KeysDown[GLFW_KEY_RIGHT_SHIFT]; - io.KeyAlt = io.KeysDown[GLFW_KEY_LEFT_ALT] || io.KeysDown[GLFW_KEY_RIGHT_ALT]; - io.KeySuper = io.KeysDown[GLFW_KEY_LEFT_SUPER] || io.KeysDown[GLFW_KEY_RIGHT_SUPER]; -} - -void ImGui_ImplGlfw_CharCallback(GLFWwindow*, unsigned int c) -{ - ImGuiIO& io = ImGui::GetIO(); - if (c > 0 && c < 0x10000) - io.AddInputCharacter((unsigned short)c); -} - -bool ImGui_ImplGlfw_CreateDeviceObjects() -{ - // Build texture atlas - ImGuiIO& io = ImGui::GetIO(); - unsigned char* pixels; - int width, height; - io.Fonts->GetTexDataAsAlpha8(&pixels, &width, &height); - - // Upload texture to graphics system - GLint last_texture; - glGetIntegerv(GL_TEXTURE_BINDING_2D, &last_texture); - glGenTextures(1, &g_FontTexture); - glBindTexture(GL_TEXTURE_2D, g_FontTexture); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, width, height, 0, GL_ALPHA, GL_UNSIGNED_BYTE, pixels); - - // Store our identifier - io.Fonts->TexID = (void *)(intptr_t)g_FontTexture; - - // Restore state - glBindTexture(GL_TEXTURE_2D, last_texture); - - return true; -} - -void ImGui_ImplGlfw_InvalidateDeviceObjects() -{ - if (g_FontTexture) - { - glDeleteTextures(1, &g_FontTexture); - ImGui::GetIO().Fonts->TexID = 0; - g_FontTexture = 0; - } -} - -bool ImGui_ImplGlfw_Init(GLFWwindow* window, bool install_callbacks) -{ - g_Window = window; - - ImGuiIO& io = ImGui::GetIO(); - 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; - io.KeyMap[ImGuiKey_DownArrow] = GLFW_KEY_DOWN; - io.KeyMap[ImGuiKey_PageUp] = GLFW_KEY_PAGE_UP; - io.KeyMap[ImGuiKey_PageDown] = GLFW_KEY_PAGE_DOWN; - io.KeyMap[ImGuiKey_Home] = GLFW_KEY_HOME; - io.KeyMap[ImGuiKey_End] = GLFW_KEY_END; - io.KeyMap[ImGuiKey_Delete] = GLFW_KEY_DELETE; - io.KeyMap[ImGuiKey_Backspace] = GLFW_KEY_BACKSPACE; - io.KeyMap[ImGuiKey_Enter] = GLFW_KEY_ENTER; - io.KeyMap[ImGuiKey_Escape] = GLFW_KEY_ESCAPE; - io.KeyMap[ImGuiKey_A] = GLFW_KEY_A; - io.KeyMap[ImGuiKey_C] = GLFW_KEY_C; - io.KeyMap[ImGuiKey_V] = GLFW_KEY_V; - io.KeyMap[ImGuiKey_X] = GLFW_KEY_X; - io.KeyMap[ImGuiKey_Y] = GLFW_KEY_Y; - io.KeyMap[ImGuiKey_Z] = GLFW_KEY_Z; - - io.RenderDrawListsFn = ImGui_ImplGlfw_RenderDrawLists; // Alternatively you can set this to NULL and call ImGui::GetDrawData() after ImGui::Render() to get the same ImDrawData pointer. - io.SetClipboardTextFn = ImGui_ImplGlfw_SetClipboardText; - io.GetClipboardTextFn = ImGui_ImplGlfw_GetClipboardText; -#ifdef _WIN32 - io.ImeWindowHandle = glfwGetWin32Window(g_Window); -#endif - - if (install_callbacks) - { - glfwSetMouseButtonCallback(window, ImGui_ImplGlfw_MouseButtonCallback); - glfwSetScrollCallback(window, ImGui_ImplGlfw_ScrollCallback); - glfwSetKeyCallback(window, ImGui_ImplGlFw_KeyCallback); - glfwSetCharCallback(window, ImGui_ImplGlfw_CharCallback); - } - - return true; -} - -void ImGui_ImplGlfw_Shutdown() -{ - ImGui_ImplGlfw_InvalidateDeviceObjects(); - ImGui::Shutdown(); -} - -void ImGui_ImplGlfw_NewFrame() -{ - if (!g_FontTexture) - ImGui_ImplGlfw_CreateDeviceObjects(); - - ImGuiIO& io = ImGui::GetIO(); - - // Setup display size (every frame to accommodate for window resizing) - int w, h; - int display_w, display_h; - glfwGetWindowSize(g_Window, &w, &h); - glfwGetFramebufferSize(g_Window, &display_w, &display_h); - io.DisplaySize = ImVec2((float)w, (float)h); - io.DisplayFramebufferScale = ImVec2(w > 0 ? ((float)display_w / w) : 0, h > 0 ? ((float)display_h / h) : 0); - - // Setup time step - double current_time = glfwGetTime(); - io.DeltaTime = g_Time > 0.0 ? (float)(current_time - g_Time) : (float)(1.0f/60.0f); - g_Time = current_time; - - // Setup inputs - // (we already got mouse wheel, keyboard keys & characters from glfw callbacks polled in glfwPollEvents()) - if (glfwGetWindowAttrib(g_Window, GLFW_FOCUSED)) - { - double mouse_x, mouse_y; - glfwGetCursorPos(g_Window, &mouse_x, &mouse_y); - io.MousePos = ImVec2((float)mouse_x, (float)mouse_y); // Mouse position in screen coordinates (set to -1,-1 if no mouse / on another screen, etc.) - } - else - { - io.MousePos = ImVec2(-1,-1); - } - - for (int i = 0; i < 3; i++) - { - io.MouseDown[i] = g_MousePressed[i] || glfwGetMouseButton(g_Window, i) != 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. - g_MousePressed[i] = false; - } - - io.MouseWheel = g_MouseWheel; - g_MouseWheel = 0.0f; - - // Hide OS mouse cursor if ImGui is drawing it - glfwSetInputMode(g_Window, GLFW_CURSOR, io.MouseDrawCursor ? GLFW_CURSOR_HIDDEN : GLFW_CURSOR_NORMAL); - - // Start the frame - ImGui::NewFrame(); -} diff --git a/examples/opengl_example/imgui_impl_glfw.h b/examples/opengl_example/imgui_impl_glfw.h deleted file mode 100644 index 07dd96f..0000000 --- a/examples/opengl_example/imgui_impl_glfw.h +++ /dev/null @@ -1,29 +0,0 @@ -// ImGui GLFW binding with OpenGL -// In this binding, ImTextureID is used to store an OpenGL 'GLuint' texture identifier. Read the FAQ about ImTextureID in imgui.cpp. - -// If your context is GL3/GL3 then prefer using the code in opengl3_example. -// You *might* use this code with a GL3/GL4 context but make sure you disable the programmable pipeline by calling "glUseProgram(0)" before ImGui::Render(). -// We cannot do that from GL2 code because the function doesn't exist. - -// You can copy and use unmodified imgui_impl_* files in your project. See main.cpp for an example of using this. -// If you use this binding you'll need to call 4 functions: ImGui_ImplXXXX_Init(), ImGui_ImplXXXX_NewFrame(), ImGui::Render() and ImGui_ImplXXXX_Shutdown(). -// If you are new to ImGui, see examples/README.txt and documentation at the top of imgui.cpp. -// https://github.com/ocornut/imgui - -struct GLFWwindow; - -IMGUI_API bool ImGui_ImplGlfw_Init(GLFWwindow* window, bool install_callbacks); -IMGUI_API void ImGui_ImplGlfw_Shutdown(); -IMGUI_API void ImGui_ImplGlfw_NewFrame(); - -// Use if you want to reset your rendering device without losing ImGui state. -IMGUI_API void ImGui_ImplGlfw_InvalidateDeviceObjects(); -IMGUI_API bool ImGui_ImplGlfw_CreateDeviceObjects(); - -// GLFW callbacks (installed by default if you enable 'install_callbacks' during initialization) -// Provided here if you want to chain callbacks. -// You can also handle inputs yourself and use those as a reference. -IMGUI_API void ImGui_ImplGlfw_MouseButtonCallback(GLFWwindow* window, int button, int action, int mods); -IMGUI_API void ImGui_ImplGlfw_ScrollCallback(GLFWwindow* window, double xoffset, double yoffset); -IMGUI_API void ImGui_ImplGlFw_KeyCallback(GLFWwindow* window, int key, int scancode, int action, int mods); -IMGUI_API void ImGui_ImplGlfw_CharCallback(GLFWwindow* window, unsigned int c); diff --git a/examples/opengl_example/main.cpp b/examples/opengl_example/main.cpp deleted file mode 100644 index a844db5..0000000 --- a/examples/opengl_example/main.cpp +++ /dev/null @@ -1,89 +0,0 @@ -// ImGui - standalone example application for Glfw + OpenGL 2, using fixed pipeline -// If you are new to ImGui, see examples/README.txt and documentation at the top of imgui.cpp. - -#include -#include "imgui_impl_glfw.h" -#include -#include - -static void error_callback(int error, const char* description) -{ - fprintf(stderr, "Error %d: %s\n", error, description); -} - -int main(int, char**) -{ - // Setup window - glfwSetErrorCallback(error_callback); - if (!glfwInit()) - return 1; - GLFWwindow* window = glfwCreateWindow(1280, 720, "ImGui OpenGL2 example", NULL, NULL); - glfwMakeContextCurrent(window); - - // Setup ImGui binding - ImGui_ImplGlfw_Init(window, true); - - // Load Fonts - // (there is a default font, this is only if you want to change it. see extra_fonts/README.txt for more details) - //ImGuiIO& io = ImGui::GetIO(); - //io.Fonts->AddFontDefault(); - //io.Fonts->AddFontFromFileTTF("../../extra_fonts/Cousine-Regular.ttf", 15.0f); - //io.Fonts->AddFontFromFileTTF("../../extra_fonts/DroidSans.ttf", 16.0f); - //io.Fonts->AddFontFromFileTTF("../../extra_fonts/ProggyClean.ttf", 13.0f); - //io.Fonts->AddFontFromFileTTF("../../extra_fonts/ProggyTiny.ttf", 10.0f); - //io.Fonts->AddFontFromFileTTF("c:\\Windows\\Fonts\\ArialUni.ttf", 18.0f, NULL, io.Fonts->GetGlyphRangesJapanese()); - - bool show_test_window = true; - bool show_another_window = false; - ImVec4 clear_color = ImColor(114, 144, 154); - - // Main loop - while (!glfwWindowShouldClose(window)) - { - glfwPollEvents(); - ImGui_ImplGlfw_NewFrame(); - - // 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 = 0.0f; - ImGui::Text("Hello, world!"); - ImGui::SliderFloat("float", &f, 0.0f, 1.0f); - ImGui::ColorEdit3("clear color", (float*)&clear_color); - if (ImGui::Button("Test Window")) show_test_window ^= 1; - if (ImGui::Button("Another Window")) show_another_window ^= 1; - ImGui::Text("Application average %.3f ms/frame (%.1f FPS)", 1000.0f / ImGui::GetIO().Framerate, ImGui::GetIO().Framerate); - } - - // 2. Show another simple window, this time using an explicit Begin/End pair - if (show_another_window) - { - ImGui::SetNextWindowSize(ImVec2(200,100), ImGuiSetCond_FirstUseEver); - ImGui::Begin("Another Window", &show_another_window); - 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::SetNextWindowPos(ImVec2(650, 20), ImGuiSetCond_FirstUseEver); - ImGui::ShowTestWindow(&show_test_window); - } - - // Rendering - int display_w, display_h; - glfwGetFramebufferSize(window, &display_w, &display_h); - glViewport(0, 0, display_w, display_h); - glClearColor(clear_color.x, clear_color.y, clear_color.z, clear_color.w); - glClear(GL_COLOR_BUFFER_BIT); - ImGui::Render(); - glfwSwapBuffers(window); - } - - // Cleanup - ImGui_ImplGlfw_Shutdown(); - glfwTerminate(); - - return 0; -} diff --git a/examples/opengl_example/opengl_example.vcxproj b/examples/opengl_example/opengl_example.vcxproj deleted file mode 100644 index 4b354b6..0000000 --- a/examples/opengl_example/opengl_example.vcxproj +++ /dev/null @@ -1,169 +0,0 @@ - - - - - Debug - Win32 - - - Debug - x64 - - - Release - Win32 - - - Release - x64 - - - - {9CDA7840-B7A5-496D-A527-E95571496D18} - opengl_example - - - - Application - true - MultiByte - - - Application - true - MultiByte - - - Application - false - true - MultiByte - - - Application - false - true - MultiByte - - - - - - - - - - - - - - - - - - - $(ProjectDir)$(Configuration)\ - $(ProjectDir)$(Configuration)\ - $(IncludePath) - - - $(ProjectDir)$(Configuration)\ - $(ProjectDir)$(Configuration)\ - $(IncludePath) - - - $(ProjectDir)$(Configuration)\ - $(ProjectDir)$(Configuration)\ - $(IncludePath) - - - $(ProjectDir)$(Configuration)\ - $(ProjectDir)$(Configuration)\ - $(IncludePath) - - - - Level4 - Disabled - $(SolutionDir)\libs\glfw\include;..\..;%(AdditionalIncludeDirectories) - - - true - $(SolutionDir)\libs\glfw\lib-vc2010-32;%(AdditionalLibraryDirectories) - opengl32.lib;glfw3.lib;%(AdditionalDependencies) - Console - msvcrt.lib - - - - - Level4 - Disabled - $(SolutionDir)\libs\glfw\include;..\..;%(AdditionalIncludeDirectories) - - - true - $(SolutionDir)\libs\glfw\lib-vc2010-64;%(AdditionalLibraryDirectories) - opengl32.lib;glfw3.lib;%(AdditionalDependencies) - Console - msvcrt.lib - - - - - Level4 - MaxSpeed - true - true - $(SolutionDir)\libs\glfw\include;..\..;%(AdditionalIncludeDirectories) - - - true - true - true - $(SolutionDir)\libs\glfw\lib-vc2010-32;%(AdditionalLibraryDirectories) - opengl32.lib;glfw3.lib;%(AdditionalDependencies) - Console - - - - - - - Level4 - MaxSpeed - true - true - $(SolutionDir)\libs\glfw\include;..\..;%(AdditionalIncludeDirectories) - - - true - true - true - $(SolutionDir)\libs\glfw\lib-vc2010-64;%(AdditionalLibraryDirectories) - opengl32.lib;glfw3.lib;%(AdditionalDependencies) - Console - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/examples/README.txt b/examples/README.txt index df2e86d..5a1c8df 100644 --- a/examples/README.txt +++ b/examples/README.txt @@ -8,11 +8,13 @@ TL;DR; - Newcomers, read 'PROGRAMMER GUIDE' in imgui.cpp for notes on how to setup ImGui in your codebase. - - Refer to 'opengl_example' to understand how the library is setup, it is the simplest one. + - Refer to 'opengl2_example' to LEARN how the library is setup, it is the simplest one. The other examples requires more boilerplate and are harder to read. + - If you are using OpenGL in your application, probably use an opengl3_xxx backend. + Mixing old fixed pipeline OpenGL2 and programmable pipeline OpenGL3+ isn't well supported by drivers. - If you are using of the backend provided here, so you can copy the imgui_impl_xxx.cpp/h files to your project and use them unmodified. - - If you have your own engine, you probably want to start from 'opengl_example' and adapt it to + - If you have your own engine, you probably want to start from one of the OpenGL example and adapt it to your engine, but you can read the other examples as well. ImGui is highly portable and only requires a few things to run: @@ -41,15 +43,14 @@ Also note that some setup or GPU drivers may be causing extra lag (possibly by enforcing triple buffering), leaving you with no option but sadness/anger (Intel GPU drivers were reported as such). -opengl_example/ - OpenGL example, using GLFW + fixed pipeline. - This is simple and should work for all OpenGL enabled applications. - Prefer following this example to learn how ImGui works! - (You can use this code in a GL3/GL4 context but make sure you disable the programmable pipeline - by calling "glUseProgram(0)" before ImGui::Render.) +opengl2_example/ + GLFW + OpenGL example (old fixed pipeline). + This is simple to read. Prefer following this example to learn how ImGui works! + (You might be able to use this code in a GL3/GL4 context but make sure you disable the programmable + pipeline by calling "glUseProgram(0)" before ImGui::Render.) opengl3_example/ - OpenGL example, using GLFW/GL3W + programmable pipeline. + GLFW + OpenGL example (programmable pipeline, binding modern functions with GL3W). This uses more modern OpenGL calls and custom shaders. It's more messy. directx9_example/ @@ -68,8 +69,8 @@ On iOS, Using Synergy to access keyboard/mouse data from server computer. Synergy keyboard integration is rather hacky. -sdl_opengl_example/ - SDL2 + OpenGL example. +sdl_opengl2_example/ + SDL2 + OpenGL example (old fixed pipeline). sdl_opengl3_example/ SDL2 + OpenGL3 example. diff --git a/examples/imgui_examples_msvc2010.sln b/examples/imgui_examples_msvc2010.sln index b7e6a25..16f0d60 100644 --- a/examples/imgui_examples_msvc2010.sln +++ b/examples/imgui_examples_msvc2010.sln @@ -1,7 +1,7 @@  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}" +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "opengl2_example", "opengl_example\opengl2_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 diff --git a/examples/opengl2_example/Makefile b/examples/opengl2_example/Makefile new file mode 100644 index 0000000..bd79d1b --- /dev/null +++ b/examples/opengl2_example/Makefile @@ -0,0 +1,60 @@ +# +# Cross Platform Makefile +# Compatible with Ubuntu 14.04.1 and Mac OS X +# +# +# if you using Mac OS X: +# You'll need glfw +# http://www.glfw.org +# + +#CXX = g++ + +EXE = opengl2_example +OBJS = main.o imgui_impl_glfw.o +OBJS += ../../imgui.o ../../imgui_demo.o ../../imgui_draw.o + +UNAME_S := $(shell uname -s) + + +ifeq ($(UNAME_S), Linux) #LINUX + ECHO_MESSAGE = "Linux" + LIBS = -lGL `pkg-config --static --libs glfw3` + + CXXFLAGS = -I../../ `pkg-config --cflags glfw3` + CXXFLAGS += -Wall -Wformat + CFLAGS = $(CXXFLAGS) +endif + +ifeq ($(UNAME_S), Darwin) #APPLE + ECHO_MESSAGE = "Mac OS X" + LIBS = -framework OpenGL -framework Cocoa -framework IOKit -framework CoreVideo + LIBS += -L/usr/local/lib -lglfw3 + + CXXFLAGS = -I../../ -I/usr/local/include + CXXFLAGS += -Wall -Wformat +# CXXFLAGS += -D__APPLE__ + CFLAGS = $(CXXFLAGS) +endif + +ifeq ($(UNAME_S), MINGW64_NT-6.3) + ECHO_MESSAGE = "Windows" + LIBS = -lglfw3 -lgdi32 -lopengl32 -limm32 + + CXXFLAGS = -I../../ -I../libs/gl3w `pkg-config --cflags glfw3` + CXXFLAGS += -Wall -Wformat + CFLAGS = $(CXXFLAGS) +endif + +.cpp.o: + $(CXX) $(CXXFLAGS) -c -o $@ $< + +all: $(EXE) + @echo Build complete for $(ECHO_MESSAGE) + +$(EXE): $(OBJS) + $(CXX) -o $(EXE) $(OBJS) $(CXXFLAGS) $(LIBS) + +clean: + rm $(EXE) $(OBJS) + diff --git a/examples/opengl2_example/build_win32.bat b/examples/opengl2_example/build_win32.bat new file mode 100644 index 0000000..278381c --- /dev/null +++ b/examples/opengl2_example/build_win32.bat @@ -0,0 +1,3 @@ +@REM Build for Visual Studio compiler. Run your copy of vcvars32.bat or vcvarsall.bat to setup command-line compiler. +mkdir Debug +cl /nologo /Zi /MD /I ..\.. /I ..\libs\glfw\include *.cpp ..\..\*.cpp /FeDebug/opengl_example.exe /FoDebug/ /link /LIBPATH:..\libs\glfw\lib-vc2010-32 glfw3.lib opengl32.lib gdi32.lib shell32.lib diff --git a/examples/opengl2_example/imgui_impl_glfw.cpp b/examples/opengl2_example/imgui_impl_glfw.cpp new file mode 100644 index 0000000..2d1f5c1 --- /dev/null +++ b/examples/opengl2_example/imgui_impl_glfw.cpp @@ -0,0 +1,288 @@ +// ImGui GLFW binding with OpenGL +// In this binding, ImTextureID is used to store an OpenGL 'GLuint' texture identifier. Read the FAQ about ImTextureID in imgui.cpp. + +// If your context is GL3/GL3 then prefer using the code in opengl3_example. +// You *might* use this code with a GL3/GL4 context but make sure you disable the programmable pipeline by calling "glUseProgram(0)" before ImGui::Render(). +// We cannot do that from GL2 code because the function doesn't exist. + +// You can copy and use unmodified imgui_impl_* files in your project. See main.cpp for an example of using this. +// If you use this binding you'll need to call 4 functions: ImGui_ImplXXXX_Init(), ImGui_ImplXXXX_NewFrame(), ImGui::Render() and ImGui_ImplXXXX_Shutdown(). +// If you are new to ImGui, see examples/README.txt and documentation at the top of imgui.cpp. +// https://github.com/ocornut/imgui + +#include +#include "imgui_impl_glfw.h" + +// GLFW +#include +#ifdef _WIN32 +#undef APIENTRY +#define GLFW_EXPOSE_NATIVE_WIN32 +#define GLFW_EXPOSE_NATIVE_WGL +#include +#endif + +// Data +static GLFWwindow* g_Window = NULL; +static double g_Time = 0.0f; +static bool g_MousePressed[3] = { false, false, false }; +static float g_MouseWheel = 0.0f; +static GLuint g_FontTexture = 0; + +// 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) +void ImGui_ImplGlfw_RenderDrawLists(ImDrawData* draw_data) +{ + // Avoid rendering when minimized, scale coordinates for retina displays (screen coordinates != framebuffer coordinates) + ImGuiIO& io = ImGui::GetIO(); + int fb_width = (int)(io.DisplaySize.x * io.DisplayFramebufferScale.x); + int fb_height = (int)(io.DisplaySize.y * io.DisplayFramebufferScale.y); + if (fb_width == 0 || fb_height == 0) + return; + draw_data->ScaleClipRects(io.DisplayFramebufferScale); + + // We are using the OpenGL fixed pipeline to make the example code simpler to read! + // Setup render state: alpha-blending enabled, no face culling, no depth testing, scissor enabled, vertex/texcoord/color pointers. + GLint last_texture; glGetIntegerv(GL_TEXTURE_BINDING_2D, &last_texture); + GLint last_viewport[4]; glGetIntegerv(GL_VIEWPORT, last_viewport); + glPushAttrib(GL_ENABLE_BIT | GL_COLOR_BUFFER_BIT | GL_TRANSFORM_BIT); + glEnable(GL_BLEND); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + glDisable(GL_CULL_FACE); + glDisable(GL_DEPTH_TEST); + glEnable(GL_SCISSOR_TEST); + glEnableClientState(GL_VERTEX_ARRAY); + glEnableClientState(GL_TEXTURE_COORD_ARRAY); + glEnableClientState(GL_COLOR_ARRAY); + glEnable(GL_TEXTURE_2D); + //glUseProgram(0); // You may want this if using this code in an OpenGL 3+ context + + // Setup viewport, orthographic projection matrix + glViewport(0, 0, (GLsizei)fb_width, (GLsizei)fb_height); + glMatrixMode(GL_PROJECTION); + glPushMatrix(); + glLoadIdentity(); + glOrtho(0.0f, io.DisplaySize.x, io.DisplaySize.y, 0.0f, -1.0f, +1.0f); + glMatrixMode(GL_MODELVIEW); + glPushMatrix(); + glLoadIdentity(); + + // Render command lists + #define OFFSETOF(TYPE, ELEMENT) ((size_t)&(((TYPE *)0)->ELEMENT)) + for (int n = 0; n < draw_data->CmdListsCount; n++) + { + const ImDrawList* cmd_list = draw_data->CmdLists[n]; + const unsigned char* vtx_buffer = (const unsigned char*)&cmd_list->VtxBuffer.front(); + const ImDrawIdx* idx_buffer = &cmd_list->IdxBuffer.front(); + glVertexPointer(2, GL_FLOAT, sizeof(ImDrawVert), (void*)(vtx_buffer + OFFSETOF(ImDrawVert, pos))); + glTexCoordPointer(2, GL_FLOAT, sizeof(ImDrawVert), (void*)(vtx_buffer + OFFSETOF(ImDrawVert, uv))); + glColorPointer(4, GL_UNSIGNED_BYTE, sizeof(ImDrawVert), (void*)(vtx_buffer + OFFSETOF(ImDrawVert, col))); + + for (int cmd_i = 0; cmd_i < cmd_list->CmdBuffer.size(); cmd_i++) + { + const ImDrawCmd* pcmd = &cmd_list->CmdBuffer[cmd_i]; + if (pcmd->UserCallback) + { + pcmd->UserCallback(cmd_list, pcmd); + } + else + { + glBindTexture(GL_TEXTURE_2D, (GLuint)(intptr_t)pcmd->TextureId); + glScissor((int)pcmd->ClipRect.x, (int)(fb_height - pcmd->ClipRect.w), (int)(pcmd->ClipRect.z - pcmd->ClipRect.x), (int)(pcmd->ClipRect.w - pcmd->ClipRect.y)); + glDrawElements(GL_TRIANGLES, (GLsizei)pcmd->ElemCount, sizeof(ImDrawIdx) == 2 ? GL_UNSIGNED_SHORT : GL_UNSIGNED_INT, idx_buffer); + } + idx_buffer += pcmd->ElemCount; + } + } + #undef OFFSETOF + + // Restore modified state + glDisableClientState(GL_COLOR_ARRAY); + glDisableClientState(GL_TEXTURE_COORD_ARRAY); + glDisableClientState(GL_VERTEX_ARRAY); + glBindTexture(GL_TEXTURE_2D, (GLuint)last_texture); + glMatrixMode(GL_MODELVIEW); + glPopMatrix(); + glMatrixMode(GL_PROJECTION); + glPopMatrix(); + glPopAttrib(); + glViewport(last_viewport[0], last_viewport[1], (GLsizei)last_viewport[2], (GLsizei)last_viewport[3]); +} + +static const char* ImGui_ImplGlfw_GetClipboardText() +{ + return glfwGetClipboardString(g_Window); +} + +static void ImGui_ImplGlfw_SetClipboardText(const char* text) +{ + glfwSetClipboardString(g_Window, text); +} + +void ImGui_ImplGlfw_MouseButtonCallback(GLFWwindow*, int button, int action, int /*mods*/) +{ + if (action == GLFW_PRESS && button >= 0 && button < 3) + g_MousePressed[button] = true; +} + +void ImGui_ImplGlfw_ScrollCallback(GLFWwindow*, double /*xoffset*/, double yoffset) +{ + g_MouseWheel += (float)yoffset; // Use fractional mouse wheel, 1.0 unit 5 lines. +} + +void ImGui_ImplGlFw_KeyCallback(GLFWwindow*, int key, int, int action, int mods) +{ + ImGuiIO& io = ImGui::GetIO(); + if (action == GLFW_PRESS) + io.KeysDown[key] = true; + if (action == GLFW_RELEASE) + io.KeysDown[key] = false; + + (void)mods; // Modifiers are not reliable across systems + io.KeyCtrl = io.KeysDown[GLFW_KEY_LEFT_CONTROL] || io.KeysDown[GLFW_KEY_RIGHT_CONTROL]; + io.KeyShift = io.KeysDown[GLFW_KEY_LEFT_SHIFT] || io.KeysDown[GLFW_KEY_RIGHT_SHIFT]; + io.KeyAlt = io.KeysDown[GLFW_KEY_LEFT_ALT] || io.KeysDown[GLFW_KEY_RIGHT_ALT]; + io.KeySuper = io.KeysDown[GLFW_KEY_LEFT_SUPER] || io.KeysDown[GLFW_KEY_RIGHT_SUPER]; +} + +void ImGui_ImplGlfw_CharCallback(GLFWwindow*, unsigned int c) +{ + ImGuiIO& io = ImGui::GetIO(); + if (c > 0 && c < 0x10000) + io.AddInputCharacter((unsigned short)c); +} + +bool ImGui_ImplGlfw_CreateDeviceObjects() +{ + // Build texture atlas + ImGuiIO& io = ImGui::GetIO(); + unsigned char* pixels; + int width, height; + io.Fonts->GetTexDataAsAlpha8(&pixels, &width, &height); + + // Upload texture to graphics system + GLint last_texture; + glGetIntegerv(GL_TEXTURE_BINDING_2D, &last_texture); + glGenTextures(1, &g_FontTexture); + glBindTexture(GL_TEXTURE_2D, g_FontTexture); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, width, height, 0, GL_ALPHA, GL_UNSIGNED_BYTE, pixels); + + // Store our identifier + io.Fonts->TexID = (void *)(intptr_t)g_FontTexture; + + // Restore state + glBindTexture(GL_TEXTURE_2D, last_texture); + + return true; +} + +void ImGui_ImplGlfw_InvalidateDeviceObjects() +{ + if (g_FontTexture) + { + glDeleteTextures(1, &g_FontTexture); + ImGui::GetIO().Fonts->TexID = 0; + g_FontTexture = 0; + } +} + +bool ImGui_ImplGlfw_Init(GLFWwindow* window, bool install_callbacks) +{ + g_Window = window; + + ImGuiIO& io = ImGui::GetIO(); + 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; + io.KeyMap[ImGuiKey_DownArrow] = GLFW_KEY_DOWN; + io.KeyMap[ImGuiKey_PageUp] = GLFW_KEY_PAGE_UP; + io.KeyMap[ImGuiKey_PageDown] = GLFW_KEY_PAGE_DOWN; + io.KeyMap[ImGuiKey_Home] = GLFW_KEY_HOME; + io.KeyMap[ImGuiKey_End] = GLFW_KEY_END; + io.KeyMap[ImGuiKey_Delete] = GLFW_KEY_DELETE; + io.KeyMap[ImGuiKey_Backspace] = GLFW_KEY_BACKSPACE; + io.KeyMap[ImGuiKey_Enter] = GLFW_KEY_ENTER; + io.KeyMap[ImGuiKey_Escape] = GLFW_KEY_ESCAPE; + io.KeyMap[ImGuiKey_A] = GLFW_KEY_A; + io.KeyMap[ImGuiKey_C] = GLFW_KEY_C; + io.KeyMap[ImGuiKey_V] = GLFW_KEY_V; + io.KeyMap[ImGuiKey_X] = GLFW_KEY_X; + io.KeyMap[ImGuiKey_Y] = GLFW_KEY_Y; + io.KeyMap[ImGuiKey_Z] = GLFW_KEY_Z; + + io.RenderDrawListsFn = ImGui_ImplGlfw_RenderDrawLists; // Alternatively you can set this to NULL and call ImGui::GetDrawData() after ImGui::Render() to get the same ImDrawData pointer. + io.SetClipboardTextFn = ImGui_ImplGlfw_SetClipboardText; + io.GetClipboardTextFn = ImGui_ImplGlfw_GetClipboardText; +#ifdef _WIN32 + io.ImeWindowHandle = glfwGetWin32Window(g_Window); +#endif + + if (install_callbacks) + { + glfwSetMouseButtonCallback(window, ImGui_ImplGlfw_MouseButtonCallback); + glfwSetScrollCallback(window, ImGui_ImplGlfw_ScrollCallback); + glfwSetKeyCallback(window, ImGui_ImplGlFw_KeyCallback); + glfwSetCharCallback(window, ImGui_ImplGlfw_CharCallback); + } + + return true; +} + +void ImGui_ImplGlfw_Shutdown() +{ + ImGui_ImplGlfw_InvalidateDeviceObjects(); + ImGui::Shutdown(); +} + +void ImGui_ImplGlfw_NewFrame() +{ + if (!g_FontTexture) + ImGui_ImplGlfw_CreateDeviceObjects(); + + ImGuiIO& io = ImGui::GetIO(); + + // Setup display size (every frame to accommodate for window resizing) + int w, h; + int display_w, display_h; + glfwGetWindowSize(g_Window, &w, &h); + glfwGetFramebufferSize(g_Window, &display_w, &display_h); + io.DisplaySize = ImVec2((float)w, (float)h); + io.DisplayFramebufferScale = ImVec2(w > 0 ? ((float)display_w / w) : 0, h > 0 ? ((float)display_h / h) : 0); + + // Setup time step + double current_time = glfwGetTime(); + io.DeltaTime = g_Time > 0.0 ? (float)(current_time - g_Time) : (float)(1.0f/60.0f); + g_Time = current_time; + + // Setup inputs + // (we already got mouse wheel, keyboard keys & characters from glfw callbacks polled in glfwPollEvents()) + if (glfwGetWindowAttrib(g_Window, GLFW_FOCUSED)) + { + double mouse_x, mouse_y; + glfwGetCursorPos(g_Window, &mouse_x, &mouse_y); + io.MousePos = ImVec2((float)mouse_x, (float)mouse_y); // Mouse position in screen coordinates (set to -1,-1 if no mouse / on another screen, etc.) + } + else + { + io.MousePos = ImVec2(-1,-1); + } + + for (int i = 0; i < 3; i++) + { + io.MouseDown[i] = g_MousePressed[i] || glfwGetMouseButton(g_Window, i) != 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. + g_MousePressed[i] = false; + } + + io.MouseWheel = g_MouseWheel; + g_MouseWheel = 0.0f; + + // Hide OS mouse cursor if ImGui is drawing it + glfwSetInputMode(g_Window, GLFW_CURSOR, io.MouseDrawCursor ? GLFW_CURSOR_HIDDEN : GLFW_CURSOR_NORMAL); + + // Start the frame + ImGui::NewFrame(); +} diff --git a/examples/opengl2_example/imgui_impl_glfw.h b/examples/opengl2_example/imgui_impl_glfw.h new file mode 100644 index 0000000..07dd96f --- /dev/null +++ b/examples/opengl2_example/imgui_impl_glfw.h @@ -0,0 +1,29 @@ +// ImGui GLFW binding with OpenGL +// In this binding, ImTextureID is used to store an OpenGL 'GLuint' texture identifier. Read the FAQ about ImTextureID in imgui.cpp. + +// If your context is GL3/GL3 then prefer using the code in opengl3_example. +// You *might* use this code with a GL3/GL4 context but make sure you disable the programmable pipeline by calling "glUseProgram(0)" before ImGui::Render(). +// We cannot do that from GL2 code because the function doesn't exist. + +// You can copy and use unmodified imgui_impl_* files in your project. See main.cpp for an example of using this. +// If you use this binding you'll need to call 4 functions: ImGui_ImplXXXX_Init(), ImGui_ImplXXXX_NewFrame(), ImGui::Render() and ImGui_ImplXXXX_Shutdown(). +// If you are new to ImGui, see examples/README.txt and documentation at the top of imgui.cpp. +// https://github.com/ocornut/imgui + +struct GLFWwindow; + +IMGUI_API bool ImGui_ImplGlfw_Init(GLFWwindow* window, bool install_callbacks); +IMGUI_API void ImGui_ImplGlfw_Shutdown(); +IMGUI_API void ImGui_ImplGlfw_NewFrame(); + +// Use if you want to reset your rendering device without losing ImGui state. +IMGUI_API void ImGui_ImplGlfw_InvalidateDeviceObjects(); +IMGUI_API bool ImGui_ImplGlfw_CreateDeviceObjects(); + +// GLFW callbacks (installed by default if you enable 'install_callbacks' during initialization) +// Provided here if you want to chain callbacks. +// You can also handle inputs yourself and use those as a reference. +IMGUI_API void ImGui_ImplGlfw_MouseButtonCallback(GLFWwindow* window, int button, int action, int mods); +IMGUI_API void ImGui_ImplGlfw_ScrollCallback(GLFWwindow* window, double xoffset, double yoffset); +IMGUI_API void ImGui_ImplGlFw_KeyCallback(GLFWwindow* window, int key, int scancode, int action, int mods); +IMGUI_API void ImGui_ImplGlfw_CharCallback(GLFWwindow* window, unsigned int c); diff --git a/examples/opengl2_example/main.cpp b/examples/opengl2_example/main.cpp new file mode 100644 index 0000000..a844db5 --- /dev/null +++ b/examples/opengl2_example/main.cpp @@ -0,0 +1,89 @@ +// ImGui - standalone example application for Glfw + OpenGL 2, using fixed pipeline +// If you are new to ImGui, see examples/README.txt and documentation at the top of imgui.cpp. + +#include +#include "imgui_impl_glfw.h" +#include +#include + +static void error_callback(int error, const char* description) +{ + fprintf(stderr, "Error %d: %s\n", error, description); +} + +int main(int, char**) +{ + // Setup window + glfwSetErrorCallback(error_callback); + if (!glfwInit()) + return 1; + GLFWwindow* window = glfwCreateWindow(1280, 720, "ImGui OpenGL2 example", NULL, NULL); + glfwMakeContextCurrent(window); + + // Setup ImGui binding + ImGui_ImplGlfw_Init(window, true); + + // Load Fonts + // (there is a default font, this is only if you want to change it. see extra_fonts/README.txt for more details) + //ImGuiIO& io = ImGui::GetIO(); + //io.Fonts->AddFontDefault(); + //io.Fonts->AddFontFromFileTTF("../../extra_fonts/Cousine-Regular.ttf", 15.0f); + //io.Fonts->AddFontFromFileTTF("../../extra_fonts/DroidSans.ttf", 16.0f); + //io.Fonts->AddFontFromFileTTF("../../extra_fonts/ProggyClean.ttf", 13.0f); + //io.Fonts->AddFontFromFileTTF("../../extra_fonts/ProggyTiny.ttf", 10.0f); + //io.Fonts->AddFontFromFileTTF("c:\\Windows\\Fonts\\ArialUni.ttf", 18.0f, NULL, io.Fonts->GetGlyphRangesJapanese()); + + bool show_test_window = true; + bool show_another_window = false; + ImVec4 clear_color = ImColor(114, 144, 154); + + // Main loop + while (!glfwWindowShouldClose(window)) + { + glfwPollEvents(); + ImGui_ImplGlfw_NewFrame(); + + // 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 = 0.0f; + ImGui::Text("Hello, world!"); + ImGui::SliderFloat("float", &f, 0.0f, 1.0f); + ImGui::ColorEdit3("clear color", (float*)&clear_color); + if (ImGui::Button("Test Window")) show_test_window ^= 1; + if (ImGui::Button("Another Window")) show_another_window ^= 1; + ImGui::Text("Application average %.3f ms/frame (%.1f FPS)", 1000.0f / ImGui::GetIO().Framerate, ImGui::GetIO().Framerate); + } + + // 2. Show another simple window, this time using an explicit Begin/End pair + if (show_another_window) + { + ImGui::SetNextWindowSize(ImVec2(200,100), ImGuiSetCond_FirstUseEver); + ImGui::Begin("Another Window", &show_another_window); + 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::SetNextWindowPos(ImVec2(650, 20), ImGuiSetCond_FirstUseEver); + ImGui::ShowTestWindow(&show_test_window); + } + + // Rendering + int display_w, display_h; + glfwGetFramebufferSize(window, &display_w, &display_h); + glViewport(0, 0, display_w, display_h); + glClearColor(clear_color.x, clear_color.y, clear_color.z, clear_color.w); + glClear(GL_COLOR_BUFFER_BIT); + ImGui::Render(); + glfwSwapBuffers(window); + } + + // Cleanup + ImGui_ImplGlfw_Shutdown(); + glfwTerminate(); + + return 0; +} diff --git a/examples/opengl2_example/opengl_example.vcxproj b/examples/opengl2_example/opengl_example.vcxproj new file mode 100644 index 0000000..4b354b6 --- /dev/null +++ b/examples/opengl2_example/opengl_example.vcxproj @@ -0,0 +1,169 @@ + + + + + Debug + Win32 + + + Debug + x64 + + + Release + Win32 + + + Release + x64 + + + + {9CDA7840-B7A5-496D-A527-E95571496D18} + opengl_example + + + + Application + true + MultiByte + + + Application + true + MultiByte + + + Application + false + true + MultiByte + + + Application + false + true + MultiByte + + + + + + + + + + + + + + + + + + + $(ProjectDir)$(Configuration)\ + $(ProjectDir)$(Configuration)\ + $(IncludePath) + + + $(ProjectDir)$(Configuration)\ + $(ProjectDir)$(Configuration)\ + $(IncludePath) + + + $(ProjectDir)$(Configuration)\ + $(ProjectDir)$(Configuration)\ + $(IncludePath) + + + $(ProjectDir)$(Configuration)\ + $(ProjectDir)$(Configuration)\ + $(IncludePath) + + + + Level4 + Disabled + $(SolutionDir)\libs\glfw\include;..\..;%(AdditionalIncludeDirectories) + + + true + $(SolutionDir)\libs\glfw\lib-vc2010-32;%(AdditionalLibraryDirectories) + opengl32.lib;glfw3.lib;%(AdditionalDependencies) + Console + msvcrt.lib + + + + + Level4 + Disabled + $(SolutionDir)\libs\glfw\include;..\..;%(AdditionalIncludeDirectories) + + + true + $(SolutionDir)\libs\glfw\lib-vc2010-64;%(AdditionalLibraryDirectories) + opengl32.lib;glfw3.lib;%(AdditionalDependencies) + Console + msvcrt.lib + + + + + Level4 + MaxSpeed + true + true + $(SolutionDir)\libs\glfw\include;..\..;%(AdditionalIncludeDirectories) + + + true + true + true + $(SolutionDir)\libs\glfw\lib-vc2010-32;%(AdditionalLibraryDirectories) + opengl32.lib;glfw3.lib;%(AdditionalDependencies) + Console + + + + + + + Level4 + MaxSpeed + true + true + $(SolutionDir)\libs\glfw\include;..\..;%(AdditionalIncludeDirectories) + + + true + true + true + $(SolutionDir)\libs\glfw\lib-vc2010-64;%(AdditionalLibraryDirectories) + opengl32.lib;glfw3.lib;%(AdditionalDependencies) + Console + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/examples/opengl2_example/opengl_example.vcxproj.filters b/examples/opengl2_example/opengl_example.vcxproj.filters new file mode 100644 index 0000000..f2282bf --- /dev/null +++ b/examples/opengl2_example/opengl_example.vcxproj.filters @@ -0,0 +1,46 @@ + + + + + {c336cfe3-f0c4-464c-9ef0-a9e17a7ff222} + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx + + + + + sources + + + imgui + + + sources + + + imgui + + + imgui + + + + + imgui + + + imgui + + + sources + + + imgui + + + + + + \ No newline at end of file diff --git a/examples/opengl_example/Makefile b/examples/opengl_example/Makefile deleted file mode 100644 index 91d1b14..0000000 --- a/examples/opengl_example/Makefile +++ /dev/null @@ -1,60 +0,0 @@ -# -# Cross Platform Makefile -# Compatible with Ubuntu 14.04.1 and Mac OS X -# -# -# if you using Mac OS X: -# You'll need glfw -# http://www.glfw.org -# - -#CXX = g++ - -EXE = opengl_example -OBJS = main.o imgui_impl_glfw.o -OBJS += ../../imgui.o ../../imgui_demo.o ../../imgui_draw.o - -UNAME_S := $(shell uname -s) - - -ifeq ($(UNAME_S), Linux) #LINUX - ECHO_MESSAGE = "Linux" - LIBS = -lGL `pkg-config --static --libs glfw3` - - CXXFLAGS = -I../../ `pkg-config --cflags glfw3` - CXXFLAGS += -Wall -Wformat - CFLAGS = $(CXXFLAGS) -endif - -ifeq ($(UNAME_S), Darwin) #APPLE - ECHO_MESSAGE = "Mac OS X" - LIBS = -framework OpenGL -framework Cocoa -framework IOKit -framework CoreVideo - LIBS += -L/usr/local/lib -lglfw3 - - CXXFLAGS = -I../../ -I/usr/local/include - CXXFLAGS += -Wall -Wformat -# CXXFLAGS += -D__APPLE__ - CFLAGS = $(CXXFLAGS) -endif - -ifeq ($(UNAME_S), MINGW64_NT-6.3) - ECHO_MESSAGE = "Windows" - LIBS = -lglfw3 -lgdi32 -lopengl32 -limm32 - - CXXFLAGS = -I../../ -I../libs/gl3w `pkg-config --cflags glfw3` - CXXFLAGS += -Wall -Wformat - CFLAGS = $(CXXFLAGS) -endif - -.cpp.o: - $(CXX) $(CXXFLAGS) -c -o $@ $< - -all: $(EXE) - @echo Build complete for $(ECHO_MESSAGE) - -$(EXE): $(OBJS) - $(CXX) -o $(EXE) $(OBJS) $(CXXFLAGS) $(LIBS) - -clean: - rm $(EXE) $(OBJS) - diff --git a/examples/opengl_example/build_win32.bat b/examples/opengl_example/build_win32.bat deleted file mode 100644 index 278381c..0000000 --- a/examples/opengl_example/build_win32.bat +++ /dev/null @@ -1,3 +0,0 @@ -@REM Build for Visual Studio compiler. Run your copy of vcvars32.bat or vcvarsall.bat to setup command-line compiler. -mkdir Debug -cl /nologo /Zi /MD /I ..\.. /I ..\libs\glfw\include *.cpp ..\..\*.cpp /FeDebug/opengl_example.exe /FoDebug/ /link /LIBPATH:..\libs\glfw\lib-vc2010-32 glfw3.lib opengl32.lib gdi32.lib shell32.lib diff --git a/examples/opengl_example/imgui_impl_glfw.cpp b/examples/opengl_example/imgui_impl_glfw.cpp deleted file mode 100644 index 2d1f5c1..0000000 --- a/examples/opengl_example/imgui_impl_glfw.cpp +++ /dev/null @@ -1,288 +0,0 @@ -// ImGui GLFW binding with OpenGL -// In this binding, ImTextureID is used to store an OpenGL 'GLuint' texture identifier. Read the FAQ about ImTextureID in imgui.cpp. - -// If your context is GL3/GL3 then prefer using the code in opengl3_example. -// You *might* use this code with a GL3/GL4 context but make sure you disable the programmable pipeline by calling "glUseProgram(0)" before ImGui::Render(). -// We cannot do that from GL2 code because the function doesn't exist. - -// You can copy and use unmodified imgui_impl_* files in your project. See main.cpp for an example of using this. -// If you use this binding you'll need to call 4 functions: ImGui_ImplXXXX_Init(), ImGui_ImplXXXX_NewFrame(), ImGui::Render() and ImGui_ImplXXXX_Shutdown(). -// If you are new to ImGui, see examples/README.txt and documentation at the top of imgui.cpp. -// https://github.com/ocornut/imgui - -#include -#include "imgui_impl_glfw.h" - -// GLFW -#include -#ifdef _WIN32 -#undef APIENTRY -#define GLFW_EXPOSE_NATIVE_WIN32 -#define GLFW_EXPOSE_NATIVE_WGL -#include -#endif - -// Data -static GLFWwindow* g_Window = NULL; -static double g_Time = 0.0f; -static bool g_MousePressed[3] = { false, false, false }; -static float g_MouseWheel = 0.0f; -static GLuint g_FontTexture = 0; - -// 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) -void ImGui_ImplGlfw_RenderDrawLists(ImDrawData* draw_data) -{ - // Avoid rendering when minimized, scale coordinates for retina displays (screen coordinates != framebuffer coordinates) - ImGuiIO& io = ImGui::GetIO(); - int fb_width = (int)(io.DisplaySize.x * io.DisplayFramebufferScale.x); - int fb_height = (int)(io.DisplaySize.y * io.DisplayFramebufferScale.y); - if (fb_width == 0 || fb_height == 0) - return; - draw_data->ScaleClipRects(io.DisplayFramebufferScale); - - // We are using the OpenGL fixed pipeline to make the example code simpler to read! - // Setup render state: alpha-blending enabled, no face culling, no depth testing, scissor enabled, vertex/texcoord/color pointers. - GLint last_texture; glGetIntegerv(GL_TEXTURE_BINDING_2D, &last_texture); - GLint last_viewport[4]; glGetIntegerv(GL_VIEWPORT, last_viewport); - glPushAttrib(GL_ENABLE_BIT | GL_COLOR_BUFFER_BIT | GL_TRANSFORM_BIT); - glEnable(GL_BLEND); - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - glDisable(GL_CULL_FACE); - glDisable(GL_DEPTH_TEST); - glEnable(GL_SCISSOR_TEST); - glEnableClientState(GL_VERTEX_ARRAY); - glEnableClientState(GL_TEXTURE_COORD_ARRAY); - glEnableClientState(GL_COLOR_ARRAY); - glEnable(GL_TEXTURE_2D); - //glUseProgram(0); // You may want this if using this code in an OpenGL 3+ context - - // Setup viewport, orthographic projection matrix - glViewport(0, 0, (GLsizei)fb_width, (GLsizei)fb_height); - glMatrixMode(GL_PROJECTION); - glPushMatrix(); - glLoadIdentity(); - glOrtho(0.0f, io.DisplaySize.x, io.DisplaySize.y, 0.0f, -1.0f, +1.0f); - glMatrixMode(GL_MODELVIEW); - glPushMatrix(); - glLoadIdentity(); - - // Render command lists - #define OFFSETOF(TYPE, ELEMENT) ((size_t)&(((TYPE *)0)->ELEMENT)) - for (int n = 0; n < draw_data->CmdListsCount; n++) - { - const ImDrawList* cmd_list = draw_data->CmdLists[n]; - const unsigned char* vtx_buffer = (const unsigned char*)&cmd_list->VtxBuffer.front(); - const ImDrawIdx* idx_buffer = &cmd_list->IdxBuffer.front(); - glVertexPointer(2, GL_FLOAT, sizeof(ImDrawVert), (void*)(vtx_buffer + OFFSETOF(ImDrawVert, pos))); - glTexCoordPointer(2, GL_FLOAT, sizeof(ImDrawVert), (void*)(vtx_buffer + OFFSETOF(ImDrawVert, uv))); - glColorPointer(4, GL_UNSIGNED_BYTE, sizeof(ImDrawVert), (void*)(vtx_buffer + OFFSETOF(ImDrawVert, col))); - - for (int cmd_i = 0; cmd_i < cmd_list->CmdBuffer.size(); cmd_i++) - { - const ImDrawCmd* pcmd = &cmd_list->CmdBuffer[cmd_i]; - if (pcmd->UserCallback) - { - pcmd->UserCallback(cmd_list, pcmd); - } - else - { - glBindTexture(GL_TEXTURE_2D, (GLuint)(intptr_t)pcmd->TextureId); - glScissor((int)pcmd->ClipRect.x, (int)(fb_height - pcmd->ClipRect.w), (int)(pcmd->ClipRect.z - pcmd->ClipRect.x), (int)(pcmd->ClipRect.w - pcmd->ClipRect.y)); - glDrawElements(GL_TRIANGLES, (GLsizei)pcmd->ElemCount, sizeof(ImDrawIdx) == 2 ? GL_UNSIGNED_SHORT : GL_UNSIGNED_INT, idx_buffer); - } - idx_buffer += pcmd->ElemCount; - } - } - #undef OFFSETOF - - // Restore modified state - glDisableClientState(GL_COLOR_ARRAY); - glDisableClientState(GL_TEXTURE_COORD_ARRAY); - glDisableClientState(GL_VERTEX_ARRAY); - glBindTexture(GL_TEXTURE_2D, (GLuint)last_texture); - glMatrixMode(GL_MODELVIEW); - glPopMatrix(); - glMatrixMode(GL_PROJECTION); - glPopMatrix(); - glPopAttrib(); - glViewport(last_viewport[0], last_viewport[1], (GLsizei)last_viewport[2], (GLsizei)last_viewport[3]); -} - -static const char* ImGui_ImplGlfw_GetClipboardText() -{ - return glfwGetClipboardString(g_Window); -} - -static void ImGui_ImplGlfw_SetClipboardText(const char* text) -{ - glfwSetClipboardString(g_Window, text); -} - -void ImGui_ImplGlfw_MouseButtonCallback(GLFWwindow*, int button, int action, int /*mods*/) -{ - if (action == GLFW_PRESS && button >= 0 && button < 3) - g_MousePressed[button] = true; -} - -void ImGui_ImplGlfw_ScrollCallback(GLFWwindow*, double /*xoffset*/, double yoffset) -{ - g_MouseWheel += (float)yoffset; // Use fractional mouse wheel, 1.0 unit 5 lines. -} - -void ImGui_ImplGlFw_KeyCallback(GLFWwindow*, int key, int, int action, int mods) -{ - ImGuiIO& io = ImGui::GetIO(); - if (action == GLFW_PRESS) - io.KeysDown[key] = true; - if (action == GLFW_RELEASE) - io.KeysDown[key] = false; - - (void)mods; // Modifiers are not reliable across systems - io.KeyCtrl = io.KeysDown[GLFW_KEY_LEFT_CONTROL] || io.KeysDown[GLFW_KEY_RIGHT_CONTROL]; - io.KeyShift = io.KeysDown[GLFW_KEY_LEFT_SHIFT] || io.KeysDown[GLFW_KEY_RIGHT_SHIFT]; - io.KeyAlt = io.KeysDown[GLFW_KEY_LEFT_ALT] || io.KeysDown[GLFW_KEY_RIGHT_ALT]; - io.KeySuper = io.KeysDown[GLFW_KEY_LEFT_SUPER] || io.KeysDown[GLFW_KEY_RIGHT_SUPER]; -} - -void ImGui_ImplGlfw_CharCallback(GLFWwindow*, unsigned int c) -{ - ImGuiIO& io = ImGui::GetIO(); - if (c > 0 && c < 0x10000) - io.AddInputCharacter((unsigned short)c); -} - -bool ImGui_ImplGlfw_CreateDeviceObjects() -{ - // Build texture atlas - ImGuiIO& io = ImGui::GetIO(); - unsigned char* pixels; - int width, height; - io.Fonts->GetTexDataAsAlpha8(&pixels, &width, &height); - - // Upload texture to graphics system - GLint last_texture; - glGetIntegerv(GL_TEXTURE_BINDING_2D, &last_texture); - glGenTextures(1, &g_FontTexture); - glBindTexture(GL_TEXTURE_2D, g_FontTexture); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, width, height, 0, GL_ALPHA, GL_UNSIGNED_BYTE, pixels); - - // Store our identifier - io.Fonts->TexID = (void *)(intptr_t)g_FontTexture; - - // Restore state - glBindTexture(GL_TEXTURE_2D, last_texture); - - return true; -} - -void ImGui_ImplGlfw_InvalidateDeviceObjects() -{ - if (g_FontTexture) - { - glDeleteTextures(1, &g_FontTexture); - ImGui::GetIO().Fonts->TexID = 0; - g_FontTexture = 0; - } -} - -bool ImGui_ImplGlfw_Init(GLFWwindow* window, bool install_callbacks) -{ - g_Window = window; - - ImGuiIO& io = ImGui::GetIO(); - 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; - io.KeyMap[ImGuiKey_DownArrow] = GLFW_KEY_DOWN; - io.KeyMap[ImGuiKey_PageUp] = GLFW_KEY_PAGE_UP; - io.KeyMap[ImGuiKey_PageDown] = GLFW_KEY_PAGE_DOWN; - io.KeyMap[ImGuiKey_Home] = GLFW_KEY_HOME; - io.KeyMap[ImGuiKey_End] = GLFW_KEY_END; - io.KeyMap[ImGuiKey_Delete] = GLFW_KEY_DELETE; - io.KeyMap[ImGuiKey_Backspace] = GLFW_KEY_BACKSPACE; - io.KeyMap[ImGuiKey_Enter] = GLFW_KEY_ENTER; - io.KeyMap[ImGuiKey_Escape] = GLFW_KEY_ESCAPE; - io.KeyMap[ImGuiKey_A] = GLFW_KEY_A; - io.KeyMap[ImGuiKey_C] = GLFW_KEY_C; - io.KeyMap[ImGuiKey_V] = GLFW_KEY_V; - io.KeyMap[ImGuiKey_X] = GLFW_KEY_X; - io.KeyMap[ImGuiKey_Y] = GLFW_KEY_Y; - io.KeyMap[ImGuiKey_Z] = GLFW_KEY_Z; - - io.RenderDrawListsFn = ImGui_ImplGlfw_RenderDrawLists; // Alternatively you can set this to NULL and call ImGui::GetDrawData() after ImGui::Render() to get the same ImDrawData pointer. - io.SetClipboardTextFn = ImGui_ImplGlfw_SetClipboardText; - io.GetClipboardTextFn = ImGui_ImplGlfw_GetClipboardText; -#ifdef _WIN32 - io.ImeWindowHandle = glfwGetWin32Window(g_Window); -#endif - - if (install_callbacks) - { - glfwSetMouseButtonCallback(window, ImGui_ImplGlfw_MouseButtonCallback); - glfwSetScrollCallback(window, ImGui_ImplGlfw_ScrollCallback); - glfwSetKeyCallback(window, ImGui_ImplGlFw_KeyCallback); - glfwSetCharCallback(window, ImGui_ImplGlfw_CharCallback); - } - - return true; -} - -void ImGui_ImplGlfw_Shutdown() -{ - ImGui_ImplGlfw_InvalidateDeviceObjects(); - ImGui::Shutdown(); -} - -void ImGui_ImplGlfw_NewFrame() -{ - if (!g_FontTexture) - ImGui_ImplGlfw_CreateDeviceObjects(); - - ImGuiIO& io = ImGui::GetIO(); - - // Setup display size (every frame to accommodate for window resizing) - int w, h; - int display_w, display_h; - glfwGetWindowSize(g_Window, &w, &h); - glfwGetFramebufferSize(g_Window, &display_w, &display_h); - io.DisplaySize = ImVec2((float)w, (float)h); - io.DisplayFramebufferScale = ImVec2(w > 0 ? ((float)display_w / w) : 0, h > 0 ? ((float)display_h / h) : 0); - - // Setup time step - double current_time = glfwGetTime(); - io.DeltaTime = g_Time > 0.0 ? (float)(current_time - g_Time) : (float)(1.0f/60.0f); - g_Time = current_time; - - // Setup inputs - // (we already got mouse wheel, keyboard keys & characters from glfw callbacks polled in glfwPollEvents()) - if (glfwGetWindowAttrib(g_Window, GLFW_FOCUSED)) - { - double mouse_x, mouse_y; - glfwGetCursorPos(g_Window, &mouse_x, &mouse_y); - io.MousePos = ImVec2((float)mouse_x, (float)mouse_y); // Mouse position in screen coordinates (set to -1,-1 if no mouse / on another screen, etc.) - } - else - { - io.MousePos = ImVec2(-1,-1); - } - - for (int i = 0; i < 3; i++) - { - io.MouseDown[i] = g_MousePressed[i] || glfwGetMouseButton(g_Window, i) != 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. - g_MousePressed[i] = false; - } - - io.MouseWheel = g_MouseWheel; - g_MouseWheel = 0.0f; - - // Hide OS mouse cursor if ImGui is drawing it - glfwSetInputMode(g_Window, GLFW_CURSOR, io.MouseDrawCursor ? GLFW_CURSOR_HIDDEN : GLFW_CURSOR_NORMAL); - - // Start the frame - ImGui::NewFrame(); -} diff --git a/examples/opengl_example/imgui_impl_glfw.h b/examples/opengl_example/imgui_impl_glfw.h deleted file mode 100644 index 07dd96f..0000000 --- a/examples/opengl_example/imgui_impl_glfw.h +++ /dev/null @@ -1,29 +0,0 @@ -// ImGui GLFW binding with OpenGL -// In this binding, ImTextureID is used to store an OpenGL 'GLuint' texture identifier. Read the FAQ about ImTextureID in imgui.cpp. - -// If your context is GL3/GL3 then prefer using the code in opengl3_example. -// You *might* use this code with a GL3/GL4 context but make sure you disable the programmable pipeline by calling "glUseProgram(0)" before ImGui::Render(). -// We cannot do that from GL2 code because the function doesn't exist. - -// You can copy and use unmodified imgui_impl_* files in your project. See main.cpp for an example of using this. -// If you use this binding you'll need to call 4 functions: ImGui_ImplXXXX_Init(), ImGui_ImplXXXX_NewFrame(), ImGui::Render() and ImGui_ImplXXXX_Shutdown(). -// If you are new to ImGui, see examples/README.txt and documentation at the top of imgui.cpp. -// https://github.com/ocornut/imgui - -struct GLFWwindow; - -IMGUI_API bool ImGui_ImplGlfw_Init(GLFWwindow* window, bool install_callbacks); -IMGUI_API void ImGui_ImplGlfw_Shutdown(); -IMGUI_API void ImGui_ImplGlfw_NewFrame(); - -// Use if you want to reset your rendering device without losing ImGui state. -IMGUI_API void ImGui_ImplGlfw_InvalidateDeviceObjects(); -IMGUI_API bool ImGui_ImplGlfw_CreateDeviceObjects(); - -// GLFW callbacks (installed by default if you enable 'install_callbacks' during initialization) -// Provided here if you want to chain callbacks. -// You can also handle inputs yourself and use those as a reference. -IMGUI_API void ImGui_ImplGlfw_MouseButtonCallback(GLFWwindow* window, int button, int action, int mods); -IMGUI_API void ImGui_ImplGlfw_ScrollCallback(GLFWwindow* window, double xoffset, double yoffset); -IMGUI_API void ImGui_ImplGlFw_KeyCallback(GLFWwindow* window, int key, int scancode, int action, int mods); -IMGUI_API void ImGui_ImplGlfw_CharCallback(GLFWwindow* window, unsigned int c); diff --git a/examples/opengl_example/main.cpp b/examples/opengl_example/main.cpp deleted file mode 100644 index a844db5..0000000 --- a/examples/opengl_example/main.cpp +++ /dev/null @@ -1,89 +0,0 @@ -// ImGui - standalone example application for Glfw + OpenGL 2, using fixed pipeline -// If you are new to ImGui, see examples/README.txt and documentation at the top of imgui.cpp. - -#include -#include "imgui_impl_glfw.h" -#include -#include - -static void error_callback(int error, const char* description) -{ - fprintf(stderr, "Error %d: %s\n", error, description); -} - -int main(int, char**) -{ - // Setup window - glfwSetErrorCallback(error_callback); - if (!glfwInit()) - return 1; - GLFWwindow* window = glfwCreateWindow(1280, 720, "ImGui OpenGL2 example", NULL, NULL); - glfwMakeContextCurrent(window); - - // Setup ImGui binding - ImGui_ImplGlfw_Init(window, true); - - // Load Fonts - // (there is a default font, this is only if you want to change it. see extra_fonts/README.txt for more details) - //ImGuiIO& io = ImGui::GetIO(); - //io.Fonts->AddFontDefault(); - //io.Fonts->AddFontFromFileTTF("../../extra_fonts/Cousine-Regular.ttf", 15.0f); - //io.Fonts->AddFontFromFileTTF("../../extra_fonts/DroidSans.ttf", 16.0f); - //io.Fonts->AddFontFromFileTTF("../../extra_fonts/ProggyClean.ttf", 13.0f); - //io.Fonts->AddFontFromFileTTF("../../extra_fonts/ProggyTiny.ttf", 10.0f); - //io.Fonts->AddFontFromFileTTF("c:\\Windows\\Fonts\\ArialUni.ttf", 18.0f, NULL, io.Fonts->GetGlyphRangesJapanese()); - - bool show_test_window = true; - bool show_another_window = false; - ImVec4 clear_color = ImColor(114, 144, 154); - - // Main loop - while (!glfwWindowShouldClose(window)) - { - glfwPollEvents(); - ImGui_ImplGlfw_NewFrame(); - - // 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 = 0.0f; - ImGui::Text("Hello, world!"); - ImGui::SliderFloat("float", &f, 0.0f, 1.0f); - ImGui::ColorEdit3("clear color", (float*)&clear_color); - if (ImGui::Button("Test Window")) show_test_window ^= 1; - if (ImGui::Button("Another Window")) show_another_window ^= 1; - ImGui::Text("Application average %.3f ms/frame (%.1f FPS)", 1000.0f / ImGui::GetIO().Framerate, ImGui::GetIO().Framerate); - } - - // 2. Show another simple window, this time using an explicit Begin/End pair - if (show_another_window) - { - ImGui::SetNextWindowSize(ImVec2(200,100), ImGuiSetCond_FirstUseEver); - ImGui::Begin("Another Window", &show_another_window); - 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::SetNextWindowPos(ImVec2(650, 20), ImGuiSetCond_FirstUseEver); - ImGui::ShowTestWindow(&show_test_window); - } - - // Rendering - int display_w, display_h; - glfwGetFramebufferSize(window, &display_w, &display_h); - glViewport(0, 0, display_w, display_h); - glClearColor(clear_color.x, clear_color.y, clear_color.z, clear_color.w); - glClear(GL_COLOR_BUFFER_BIT); - ImGui::Render(); - glfwSwapBuffers(window); - } - - // Cleanup - ImGui_ImplGlfw_Shutdown(); - glfwTerminate(); - - return 0; -} diff --git a/examples/opengl_example/opengl_example.vcxproj b/examples/opengl_example/opengl_example.vcxproj deleted file mode 100644 index 4b354b6..0000000 --- a/examples/opengl_example/opengl_example.vcxproj +++ /dev/null @@ -1,169 +0,0 @@ - - - - - Debug - Win32 - - - Debug - x64 - - - Release - Win32 - - - Release - x64 - - - - {9CDA7840-B7A5-496D-A527-E95571496D18} - opengl_example - - - - Application - true - MultiByte - - - Application - true - MultiByte - - - Application - false - true - MultiByte - - - Application - false - true - MultiByte - - - - - - - - - - - - - - - - - - - $(ProjectDir)$(Configuration)\ - $(ProjectDir)$(Configuration)\ - $(IncludePath) - - - $(ProjectDir)$(Configuration)\ - $(ProjectDir)$(Configuration)\ - $(IncludePath) - - - $(ProjectDir)$(Configuration)\ - $(ProjectDir)$(Configuration)\ - $(IncludePath) - - - $(ProjectDir)$(Configuration)\ - $(ProjectDir)$(Configuration)\ - $(IncludePath) - - - - Level4 - Disabled - $(SolutionDir)\libs\glfw\include;..\..;%(AdditionalIncludeDirectories) - - - true - $(SolutionDir)\libs\glfw\lib-vc2010-32;%(AdditionalLibraryDirectories) - opengl32.lib;glfw3.lib;%(AdditionalDependencies) - Console - msvcrt.lib - - - - - Level4 - Disabled - $(SolutionDir)\libs\glfw\include;..\..;%(AdditionalIncludeDirectories) - - - true - $(SolutionDir)\libs\glfw\lib-vc2010-64;%(AdditionalLibraryDirectories) - opengl32.lib;glfw3.lib;%(AdditionalDependencies) - Console - msvcrt.lib - - - - - Level4 - MaxSpeed - true - true - $(SolutionDir)\libs\glfw\include;..\..;%(AdditionalIncludeDirectories) - - - true - true - true - $(SolutionDir)\libs\glfw\lib-vc2010-32;%(AdditionalLibraryDirectories) - opengl32.lib;glfw3.lib;%(AdditionalDependencies) - Console - - - - - - - Level4 - MaxSpeed - true - true - $(SolutionDir)\libs\glfw\include;..\..;%(AdditionalIncludeDirectories) - - - true - true - true - $(SolutionDir)\libs\glfw\lib-vc2010-64;%(AdditionalLibraryDirectories) - opengl32.lib;glfw3.lib;%(AdditionalDependencies) - Console - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/examples/opengl_example/opengl_example.vcxproj.filters b/examples/opengl_example/opengl_example.vcxproj.filters deleted file mode 100644 index f2282bf..0000000 --- a/examples/opengl_example/opengl_example.vcxproj.filters +++ /dev/null @@ -1,46 +0,0 @@ - - - - - {c336cfe3-f0c4-464c-9ef0-a9e17a7ff222} - - - {4FC737F1-C7A5-4376-A066-2A32D752A2FF} - cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx - - - - - sources - - - imgui - - - sources - - - imgui - - - imgui - - - - - imgui - - - imgui - - - sources - - - imgui - - - - - - \ No newline at end of file diff --git a/examples/README.txt b/examples/README.txt index df2e86d..5a1c8df 100644 --- a/examples/README.txt +++ b/examples/README.txt @@ -8,11 +8,13 @@ TL;DR; - Newcomers, read 'PROGRAMMER GUIDE' in imgui.cpp for notes on how to setup ImGui in your codebase. - - Refer to 'opengl_example' to understand how the library is setup, it is the simplest one. + - Refer to 'opengl2_example' to LEARN how the library is setup, it is the simplest one. The other examples requires more boilerplate and are harder to read. + - If you are using OpenGL in your application, probably use an opengl3_xxx backend. + Mixing old fixed pipeline OpenGL2 and programmable pipeline OpenGL3+ isn't well supported by drivers. - If you are using of the backend provided here, so you can copy the imgui_impl_xxx.cpp/h files to your project and use them unmodified. - - If you have your own engine, you probably want to start from 'opengl_example' and adapt it to + - If you have your own engine, you probably want to start from one of the OpenGL example and adapt it to your engine, but you can read the other examples as well. ImGui is highly portable and only requires a few things to run: @@ -41,15 +43,14 @@ Also note that some setup or GPU drivers may be causing extra lag (possibly by enforcing triple buffering), leaving you with no option but sadness/anger (Intel GPU drivers were reported as such). -opengl_example/ - OpenGL example, using GLFW + fixed pipeline. - This is simple and should work for all OpenGL enabled applications. - Prefer following this example to learn how ImGui works! - (You can use this code in a GL3/GL4 context but make sure you disable the programmable pipeline - by calling "glUseProgram(0)" before ImGui::Render.) +opengl2_example/ + GLFW + OpenGL example (old fixed pipeline). + This is simple to read. Prefer following this example to learn how ImGui works! + (You might be able to use this code in a GL3/GL4 context but make sure you disable the programmable + pipeline by calling "glUseProgram(0)" before ImGui::Render.) opengl3_example/ - OpenGL example, using GLFW/GL3W + programmable pipeline. + GLFW + OpenGL example (programmable pipeline, binding modern functions with GL3W). This uses more modern OpenGL calls and custom shaders. It's more messy. directx9_example/ @@ -68,8 +69,8 @@ On iOS, Using Synergy to access keyboard/mouse data from server computer. Synergy keyboard integration is rather hacky. -sdl_opengl_example/ - SDL2 + OpenGL example. +sdl_opengl2_example/ + SDL2 + OpenGL example (old fixed pipeline). sdl_opengl3_example/ SDL2 + OpenGL3 example. diff --git a/examples/imgui_examples_msvc2010.sln b/examples/imgui_examples_msvc2010.sln index b7e6a25..16f0d60 100644 --- a/examples/imgui_examples_msvc2010.sln +++ b/examples/imgui_examples_msvc2010.sln @@ -1,7 +1,7 @@  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}" +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "opengl2_example", "opengl_example\opengl2_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 diff --git a/examples/opengl2_example/Makefile b/examples/opengl2_example/Makefile new file mode 100644 index 0000000..bd79d1b --- /dev/null +++ b/examples/opengl2_example/Makefile @@ -0,0 +1,60 @@ +# +# Cross Platform Makefile +# Compatible with Ubuntu 14.04.1 and Mac OS X +# +# +# if you using Mac OS X: +# You'll need glfw +# http://www.glfw.org +# + +#CXX = g++ + +EXE = opengl2_example +OBJS = main.o imgui_impl_glfw.o +OBJS += ../../imgui.o ../../imgui_demo.o ../../imgui_draw.o + +UNAME_S := $(shell uname -s) + + +ifeq ($(UNAME_S), Linux) #LINUX + ECHO_MESSAGE = "Linux" + LIBS = -lGL `pkg-config --static --libs glfw3` + + CXXFLAGS = -I../../ `pkg-config --cflags glfw3` + CXXFLAGS += -Wall -Wformat + CFLAGS = $(CXXFLAGS) +endif + +ifeq ($(UNAME_S), Darwin) #APPLE + ECHO_MESSAGE = "Mac OS X" + LIBS = -framework OpenGL -framework Cocoa -framework IOKit -framework CoreVideo + LIBS += -L/usr/local/lib -lglfw3 + + CXXFLAGS = -I../../ -I/usr/local/include + CXXFLAGS += -Wall -Wformat +# CXXFLAGS += -D__APPLE__ + CFLAGS = $(CXXFLAGS) +endif + +ifeq ($(UNAME_S), MINGW64_NT-6.3) + ECHO_MESSAGE = "Windows" + LIBS = -lglfw3 -lgdi32 -lopengl32 -limm32 + + CXXFLAGS = -I../../ -I../libs/gl3w `pkg-config --cflags glfw3` + CXXFLAGS += -Wall -Wformat + CFLAGS = $(CXXFLAGS) +endif + +.cpp.o: + $(CXX) $(CXXFLAGS) -c -o $@ $< + +all: $(EXE) + @echo Build complete for $(ECHO_MESSAGE) + +$(EXE): $(OBJS) + $(CXX) -o $(EXE) $(OBJS) $(CXXFLAGS) $(LIBS) + +clean: + rm $(EXE) $(OBJS) + diff --git a/examples/opengl2_example/build_win32.bat b/examples/opengl2_example/build_win32.bat new file mode 100644 index 0000000..278381c --- /dev/null +++ b/examples/opengl2_example/build_win32.bat @@ -0,0 +1,3 @@ +@REM Build for Visual Studio compiler. Run your copy of vcvars32.bat or vcvarsall.bat to setup command-line compiler. +mkdir Debug +cl /nologo /Zi /MD /I ..\.. /I ..\libs\glfw\include *.cpp ..\..\*.cpp /FeDebug/opengl_example.exe /FoDebug/ /link /LIBPATH:..\libs\glfw\lib-vc2010-32 glfw3.lib opengl32.lib gdi32.lib shell32.lib diff --git a/examples/opengl2_example/imgui_impl_glfw.cpp b/examples/opengl2_example/imgui_impl_glfw.cpp new file mode 100644 index 0000000..2d1f5c1 --- /dev/null +++ b/examples/opengl2_example/imgui_impl_glfw.cpp @@ -0,0 +1,288 @@ +// ImGui GLFW binding with OpenGL +// In this binding, ImTextureID is used to store an OpenGL 'GLuint' texture identifier. Read the FAQ about ImTextureID in imgui.cpp. + +// If your context is GL3/GL3 then prefer using the code in opengl3_example. +// You *might* use this code with a GL3/GL4 context but make sure you disable the programmable pipeline by calling "glUseProgram(0)" before ImGui::Render(). +// We cannot do that from GL2 code because the function doesn't exist. + +// You can copy and use unmodified imgui_impl_* files in your project. See main.cpp for an example of using this. +// If you use this binding you'll need to call 4 functions: ImGui_ImplXXXX_Init(), ImGui_ImplXXXX_NewFrame(), ImGui::Render() and ImGui_ImplXXXX_Shutdown(). +// If you are new to ImGui, see examples/README.txt and documentation at the top of imgui.cpp. +// https://github.com/ocornut/imgui + +#include +#include "imgui_impl_glfw.h" + +// GLFW +#include +#ifdef _WIN32 +#undef APIENTRY +#define GLFW_EXPOSE_NATIVE_WIN32 +#define GLFW_EXPOSE_NATIVE_WGL +#include +#endif + +// Data +static GLFWwindow* g_Window = NULL; +static double g_Time = 0.0f; +static bool g_MousePressed[3] = { false, false, false }; +static float g_MouseWheel = 0.0f; +static GLuint g_FontTexture = 0; + +// 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) +void ImGui_ImplGlfw_RenderDrawLists(ImDrawData* draw_data) +{ + // Avoid rendering when minimized, scale coordinates for retina displays (screen coordinates != framebuffer coordinates) + ImGuiIO& io = ImGui::GetIO(); + int fb_width = (int)(io.DisplaySize.x * io.DisplayFramebufferScale.x); + int fb_height = (int)(io.DisplaySize.y * io.DisplayFramebufferScale.y); + if (fb_width == 0 || fb_height == 0) + return; + draw_data->ScaleClipRects(io.DisplayFramebufferScale); + + // We are using the OpenGL fixed pipeline to make the example code simpler to read! + // Setup render state: alpha-blending enabled, no face culling, no depth testing, scissor enabled, vertex/texcoord/color pointers. + GLint last_texture; glGetIntegerv(GL_TEXTURE_BINDING_2D, &last_texture); + GLint last_viewport[4]; glGetIntegerv(GL_VIEWPORT, last_viewport); + glPushAttrib(GL_ENABLE_BIT | GL_COLOR_BUFFER_BIT | GL_TRANSFORM_BIT); + glEnable(GL_BLEND); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + glDisable(GL_CULL_FACE); + glDisable(GL_DEPTH_TEST); + glEnable(GL_SCISSOR_TEST); + glEnableClientState(GL_VERTEX_ARRAY); + glEnableClientState(GL_TEXTURE_COORD_ARRAY); + glEnableClientState(GL_COLOR_ARRAY); + glEnable(GL_TEXTURE_2D); + //glUseProgram(0); // You may want this if using this code in an OpenGL 3+ context + + // Setup viewport, orthographic projection matrix + glViewport(0, 0, (GLsizei)fb_width, (GLsizei)fb_height); + glMatrixMode(GL_PROJECTION); + glPushMatrix(); + glLoadIdentity(); + glOrtho(0.0f, io.DisplaySize.x, io.DisplaySize.y, 0.0f, -1.0f, +1.0f); + glMatrixMode(GL_MODELVIEW); + glPushMatrix(); + glLoadIdentity(); + + // Render command lists + #define OFFSETOF(TYPE, ELEMENT) ((size_t)&(((TYPE *)0)->ELEMENT)) + for (int n = 0; n < draw_data->CmdListsCount; n++) + { + const ImDrawList* cmd_list = draw_data->CmdLists[n]; + const unsigned char* vtx_buffer = (const unsigned char*)&cmd_list->VtxBuffer.front(); + const ImDrawIdx* idx_buffer = &cmd_list->IdxBuffer.front(); + glVertexPointer(2, GL_FLOAT, sizeof(ImDrawVert), (void*)(vtx_buffer + OFFSETOF(ImDrawVert, pos))); + glTexCoordPointer(2, GL_FLOAT, sizeof(ImDrawVert), (void*)(vtx_buffer + OFFSETOF(ImDrawVert, uv))); + glColorPointer(4, GL_UNSIGNED_BYTE, sizeof(ImDrawVert), (void*)(vtx_buffer + OFFSETOF(ImDrawVert, col))); + + for (int cmd_i = 0; cmd_i < cmd_list->CmdBuffer.size(); cmd_i++) + { + const ImDrawCmd* pcmd = &cmd_list->CmdBuffer[cmd_i]; + if (pcmd->UserCallback) + { + pcmd->UserCallback(cmd_list, pcmd); + } + else + { + glBindTexture(GL_TEXTURE_2D, (GLuint)(intptr_t)pcmd->TextureId); + glScissor((int)pcmd->ClipRect.x, (int)(fb_height - pcmd->ClipRect.w), (int)(pcmd->ClipRect.z - pcmd->ClipRect.x), (int)(pcmd->ClipRect.w - pcmd->ClipRect.y)); + glDrawElements(GL_TRIANGLES, (GLsizei)pcmd->ElemCount, sizeof(ImDrawIdx) == 2 ? GL_UNSIGNED_SHORT : GL_UNSIGNED_INT, idx_buffer); + } + idx_buffer += pcmd->ElemCount; + } + } + #undef OFFSETOF + + // Restore modified state + glDisableClientState(GL_COLOR_ARRAY); + glDisableClientState(GL_TEXTURE_COORD_ARRAY); + glDisableClientState(GL_VERTEX_ARRAY); + glBindTexture(GL_TEXTURE_2D, (GLuint)last_texture); + glMatrixMode(GL_MODELVIEW); + glPopMatrix(); + glMatrixMode(GL_PROJECTION); + glPopMatrix(); + glPopAttrib(); + glViewport(last_viewport[0], last_viewport[1], (GLsizei)last_viewport[2], (GLsizei)last_viewport[3]); +} + +static const char* ImGui_ImplGlfw_GetClipboardText() +{ + return glfwGetClipboardString(g_Window); +} + +static void ImGui_ImplGlfw_SetClipboardText(const char* text) +{ + glfwSetClipboardString(g_Window, text); +} + +void ImGui_ImplGlfw_MouseButtonCallback(GLFWwindow*, int button, int action, int /*mods*/) +{ + if (action == GLFW_PRESS && button >= 0 && button < 3) + g_MousePressed[button] = true; +} + +void ImGui_ImplGlfw_ScrollCallback(GLFWwindow*, double /*xoffset*/, double yoffset) +{ + g_MouseWheel += (float)yoffset; // Use fractional mouse wheel, 1.0 unit 5 lines. +} + +void ImGui_ImplGlFw_KeyCallback(GLFWwindow*, int key, int, int action, int mods) +{ + ImGuiIO& io = ImGui::GetIO(); + if (action == GLFW_PRESS) + io.KeysDown[key] = true; + if (action == GLFW_RELEASE) + io.KeysDown[key] = false; + + (void)mods; // Modifiers are not reliable across systems + io.KeyCtrl = io.KeysDown[GLFW_KEY_LEFT_CONTROL] || io.KeysDown[GLFW_KEY_RIGHT_CONTROL]; + io.KeyShift = io.KeysDown[GLFW_KEY_LEFT_SHIFT] || io.KeysDown[GLFW_KEY_RIGHT_SHIFT]; + io.KeyAlt = io.KeysDown[GLFW_KEY_LEFT_ALT] || io.KeysDown[GLFW_KEY_RIGHT_ALT]; + io.KeySuper = io.KeysDown[GLFW_KEY_LEFT_SUPER] || io.KeysDown[GLFW_KEY_RIGHT_SUPER]; +} + +void ImGui_ImplGlfw_CharCallback(GLFWwindow*, unsigned int c) +{ + ImGuiIO& io = ImGui::GetIO(); + if (c > 0 && c < 0x10000) + io.AddInputCharacter((unsigned short)c); +} + +bool ImGui_ImplGlfw_CreateDeviceObjects() +{ + // Build texture atlas + ImGuiIO& io = ImGui::GetIO(); + unsigned char* pixels; + int width, height; + io.Fonts->GetTexDataAsAlpha8(&pixels, &width, &height); + + // Upload texture to graphics system + GLint last_texture; + glGetIntegerv(GL_TEXTURE_BINDING_2D, &last_texture); + glGenTextures(1, &g_FontTexture); + glBindTexture(GL_TEXTURE_2D, g_FontTexture); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, width, height, 0, GL_ALPHA, GL_UNSIGNED_BYTE, pixels); + + // Store our identifier + io.Fonts->TexID = (void *)(intptr_t)g_FontTexture; + + // Restore state + glBindTexture(GL_TEXTURE_2D, last_texture); + + return true; +} + +void ImGui_ImplGlfw_InvalidateDeviceObjects() +{ + if (g_FontTexture) + { + glDeleteTextures(1, &g_FontTexture); + ImGui::GetIO().Fonts->TexID = 0; + g_FontTexture = 0; + } +} + +bool ImGui_ImplGlfw_Init(GLFWwindow* window, bool install_callbacks) +{ + g_Window = window; + + ImGuiIO& io = ImGui::GetIO(); + 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; + io.KeyMap[ImGuiKey_DownArrow] = GLFW_KEY_DOWN; + io.KeyMap[ImGuiKey_PageUp] = GLFW_KEY_PAGE_UP; + io.KeyMap[ImGuiKey_PageDown] = GLFW_KEY_PAGE_DOWN; + io.KeyMap[ImGuiKey_Home] = GLFW_KEY_HOME; + io.KeyMap[ImGuiKey_End] = GLFW_KEY_END; + io.KeyMap[ImGuiKey_Delete] = GLFW_KEY_DELETE; + io.KeyMap[ImGuiKey_Backspace] = GLFW_KEY_BACKSPACE; + io.KeyMap[ImGuiKey_Enter] = GLFW_KEY_ENTER; + io.KeyMap[ImGuiKey_Escape] = GLFW_KEY_ESCAPE; + io.KeyMap[ImGuiKey_A] = GLFW_KEY_A; + io.KeyMap[ImGuiKey_C] = GLFW_KEY_C; + io.KeyMap[ImGuiKey_V] = GLFW_KEY_V; + io.KeyMap[ImGuiKey_X] = GLFW_KEY_X; + io.KeyMap[ImGuiKey_Y] = GLFW_KEY_Y; + io.KeyMap[ImGuiKey_Z] = GLFW_KEY_Z; + + io.RenderDrawListsFn = ImGui_ImplGlfw_RenderDrawLists; // Alternatively you can set this to NULL and call ImGui::GetDrawData() after ImGui::Render() to get the same ImDrawData pointer. + io.SetClipboardTextFn = ImGui_ImplGlfw_SetClipboardText; + io.GetClipboardTextFn = ImGui_ImplGlfw_GetClipboardText; +#ifdef _WIN32 + io.ImeWindowHandle = glfwGetWin32Window(g_Window); +#endif + + if (install_callbacks) + { + glfwSetMouseButtonCallback(window, ImGui_ImplGlfw_MouseButtonCallback); + glfwSetScrollCallback(window, ImGui_ImplGlfw_ScrollCallback); + glfwSetKeyCallback(window, ImGui_ImplGlFw_KeyCallback); + glfwSetCharCallback(window, ImGui_ImplGlfw_CharCallback); + } + + return true; +} + +void ImGui_ImplGlfw_Shutdown() +{ + ImGui_ImplGlfw_InvalidateDeviceObjects(); + ImGui::Shutdown(); +} + +void ImGui_ImplGlfw_NewFrame() +{ + if (!g_FontTexture) + ImGui_ImplGlfw_CreateDeviceObjects(); + + ImGuiIO& io = ImGui::GetIO(); + + // Setup display size (every frame to accommodate for window resizing) + int w, h; + int display_w, display_h; + glfwGetWindowSize(g_Window, &w, &h); + glfwGetFramebufferSize(g_Window, &display_w, &display_h); + io.DisplaySize = ImVec2((float)w, (float)h); + io.DisplayFramebufferScale = ImVec2(w > 0 ? ((float)display_w / w) : 0, h > 0 ? ((float)display_h / h) : 0); + + // Setup time step + double current_time = glfwGetTime(); + io.DeltaTime = g_Time > 0.0 ? (float)(current_time - g_Time) : (float)(1.0f/60.0f); + g_Time = current_time; + + // Setup inputs + // (we already got mouse wheel, keyboard keys & characters from glfw callbacks polled in glfwPollEvents()) + if (glfwGetWindowAttrib(g_Window, GLFW_FOCUSED)) + { + double mouse_x, mouse_y; + glfwGetCursorPos(g_Window, &mouse_x, &mouse_y); + io.MousePos = ImVec2((float)mouse_x, (float)mouse_y); // Mouse position in screen coordinates (set to -1,-1 if no mouse / on another screen, etc.) + } + else + { + io.MousePos = ImVec2(-1,-1); + } + + for (int i = 0; i < 3; i++) + { + io.MouseDown[i] = g_MousePressed[i] || glfwGetMouseButton(g_Window, i) != 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. + g_MousePressed[i] = false; + } + + io.MouseWheel = g_MouseWheel; + g_MouseWheel = 0.0f; + + // Hide OS mouse cursor if ImGui is drawing it + glfwSetInputMode(g_Window, GLFW_CURSOR, io.MouseDrawCursor ? GLFW_CURSOR_HIDDEN : GLFW_CURSOR_NORMAL); + + // Start the frame + ImGui::NewFrame(); +} diff --git a/examples/opengl2_example/imgui_impl_glfw.h b/examples/opengl2_example/imgui_impl_glfw.h new file mode 100644 index 0000000..07dd96f --- /dev/null +++ b/examples/opengl2_example/imgui_impl_glfw.h @@ -0,0 +1,29 @@ +// ImGui GLFW binding with OpenGL +// In this binding, ImTextureID is used to store an OpenGL 'GLuint' texture identifier. Read the FAQ about ImTextureID in imgui.cpp. + +// If your context is GL3/GL3 then prefer using the code in opengl3_example. +// You *might* use this code with a GL3/GL4 context but make sure you disable the programmable pipeline by calling "glUseProgram(0)" before ImGui::Render(). +// We cannot do that from GL2 code because the function doesn't exist. + +// You can copy and use unmodified imgui_impl_* files in your project. See main.cpp for an example of using this. +// If you use this binding you'll need to call 4 functions: ImGui_ImplXXXX_Init(), ImGui_ImplXXXX_NewFrame(), ImGui::Render() and ImGui_ImplXXXX_Shutdown(). +// If you are new to ImGui, see examples/README.txt and documentation at the top of imgui.cpp. +// https://github.com/ocornut/imgui + +struct GLFWwindow; + +IMGUI_API bool ImGui_ImplGlfw_Init(GLFWwindow* window, bool install_callbacks); +IMGUI_API void ImGui_ImplGlfw_Shutdown(); +IMGUI_API void ImGui_ImplGlfw_NewFrame(); + +// Use if you want to reset your rendering device without losing ImGui state. +IMGUI_API void ImGui_ImplGlfw_InvalidateDeviceObjects(); +IMGUI_API bool ImGui_ImplGlfw_CreateDeviceObjects(); + +// GLFW callbacks (installed by default if you enable 'install_callbacks' during initialization) +// Provided here if you want to chain callbacks. +// You can also handle inputs yourself and use those as a reference. +IMGUI_API void ImGui_ImplGlfw_MouseButtonCallback(GLFWwindow* window, int button, int action, int mods); +IMGUI_API void ImGui_ImplGlfw_ScrollCallback(GLFWwindow* window, double xoffset, double yoffset); +IMGUI_API void ImGui_ImplGlFw_KeyCallback(GLFWwindow* window, int key, int scancode, int action, int mods); +IMGUI_API void ImGui_ImplGlfw_CharCallback(GLFWwindow* window, unsigned int c); diff --git a/examples/opengl2_example/main.cpp b/examples/opengl2_example/main.cpp new file mode 100644 index 0000000..a844db5 --- /dev/null +++ b/examples/opengl2_example/main.cpp @@ -0,0 +1,89 @@ +// ImGui - standalone example application for Glfw + OpenGL 2, using fixed pipeline +// If you are new to ImGui, see examples/README.txt and documentation at the top of imgui.cpp. + +#include +#include "imgui_impl_glfw.h" +#include +#include + +static void error_callback(int error, const char* description) +{ + fprintf(stderr, "Error %d: %s\n", error, description); +} + +int main(int, char**) +{ + // Setup window + glfwSetErrorCallback(error_callback); + if (!glfwInit()) + return 1; + GLFWwindow* window = glfwCreateWindow(1280, 720, "ImGui OpenGL2 example", NULL, NULL); + glfwMakeContextCurrent(window); + + // Setup ImGui binding + ImGui_ImplGlfw_Init(window, true); + + // Load Fonts + // (there is a default font, this is only if you want to change it. see extra_fonts/README.txt for more details) + //ImGuiIO& io = ImGui::GetIO(); + //io.Fonts->AddFontDefault(); + //io.Fonts->AddFontFromFileTTF("../../extra_fonts/Cousine-Regular.ttf", 15.0f); + //io.Fonts->AddFontFromFileTTF("../../extra_fonts/DroidSans.ttf", 16.0f); + //io.Fonts->AddFontFromFileTTF("../../extra_fonts/ProggyClean.ttf", 13.0f); + //io.Fonts->AddFontFromFileTTF("../../extra_fonts/ProggyTiny.ttf", 10.0f); + //io.Fonts->AddFontFromFileTTF("c:\\Windows\\Fonts\\ArialUni.ttf", 18.0f, NULL, io.Fonts->GetGlyphRangesJapanese()); + + bool show_test_window = true; + bool show_another_window = false; + ImVec4 clear_color = ImColor(114, 144, 154); + + // Main loop + while (!glfwWindowShouldClose(window)) + { + glfwPollEvents(); + ImGui_ImplGlfw_NewFrame(); + + // 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 = 0.0f; + ImGui::Text("Hello, world!"); + ImGui::SliderFloat("float", &f, 0.0f, 1.0f); + ImGui::ColorEdit3("clear color", (float*)&clear_color); + if (ImGui::Button("Test Window")) show_test_window ^= 1; + if (ImGui::Button("Another Window")) show_another_window ^= 1; + ImGui::Text("Application average %.3f ms/frame (%.1f FPS)", 1000.0f / ImGui::GetIO().Framerate, ImGui::GetIO().Framerate); + } + + // 2. Show another simple window, this time using an explicit Begin/End pair + if (show_another_window) + { + ImGui::SetNextWindowSize(ImVec2(200,100), ImGuiSetCond_FirstUseEver); + ImGui::Begin("Another Window", &show_another_window); + 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::SetNextWindowPos(ImVec2(650, 20), ImGuiSetCond_FirstUseEver); + ImGui::ShowTestWindow(&show_test_window); + } + + // Rendering + int display_w, display_h; + glfwGetFramebufferSize(window, &display_w, &display_h); + glViewport(0, 0, display_w, display_h); + glClearColor(clear_color.x, clear_color.y, clear_color.z, clear_color.w); + glClear(GL_COLOR_BUFFER_BIT); + ImGui::Render(); + glfwSwapBuffers(window); + } + + // Cleanup + ImGui_ImplGlfw_Shutdown(); + glfwTerminate(); + + return 0; +} diff --git a/examples/opengl2_example/opengl_example.vcxproj b/examples/opengl2_example/opengl_example.vcxproj new file mode 100644 index 0000000..4b354b6 --- /dev/null +++ b/examples/opengl2_example/opengl_example.vcxproj @@ -0,0 +1,169 @@ + + + + + Debug + Win32 + + + Debug + x64 + + + Release + Win32 + + + Release + x64 + + + + {9CDA7840-B7A5-496D-A527-E95571496D18} + opengl_example + + + + Application + true + MultiByte + + + Application + true + MultiByte + + + Application + false + true + MultiByte + + + Application + false + true + MultiByte + + + + + + + + + + + + + + + + + + + $(ProjectDir)$(Configuration)\ + $(ProjectDir)$(Configuration)\ + $(IncludePath) + + + $(ProjectDir)$(Configuration)\ + $(ProjectDir)$(Configuration)\ + $(IncludePath) + + + $(ProjectDir)$(Configuration)\ + $(ProjectDir)$(Configuration)\ + $(IncludePath) + + + $(ProjectDir)$(Configuration)\ + $(ProjectDir)$(Configuration)\ + $(IncludePath) + + + + Level4 + Disabled + $(SolutionDir)\libs\glfw\include;..\..;%(AdditionalIncludeDirectories) + + + true + $(SolutionDir)\libs\glfw\lib-vc2010-32;%(AdditionalLibraryDirectories) + opengl32.lib;glfw3.lib;%(AdditionalDependencies) + Console + msvcrt.lib + + + + + Level4 + Disabled + $(SolutionDir)\libs\glfw\include;..\..;%(AdditionalIncludeDirectories) + + + true + $(SolutionDir)\libs\glfw\lib-vc2010-64;%(AdditionalLibraryDirectories) + opengl32.lib;glfw3.lib;%(AdditionalDependencies) + Console + msvcrt.lib + + + + + Level4 + MaxSpeed + true + true + $(SolutionDir)\libs\glfw\include;..\..;%(AdditionalIncludeDirectories) + + + true + true + true + $(SolutionDir)\libs\glfw\lib-vc2010-32;%(AdditionalLibraryDirectories) + opengl32.lib;glfw3.lib;%(AdditionalDependencies) + Console + + + + + + + Level4 + MaxSpeed + true + true + $(SolutionDir)\libs\glfw\include;..\..;%(AdditionalIncludeDirectories) + + + true + true + true + $(SolutionDir)\libs\glfw\lib-vc2010-64;%(AdditionalLibraryDirectories) + opengl32.lib;glfw3.lib;%(AdditionalDependencies) + Console + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/examples/opengl2_example/opengl_example.vcxproj.filters b/examples/opengl2_example/opengl_example.vcxproj.filters new file mode 100644 index 0000000..f2282bf --- /dev/null +++ b/examples/opengl2_example/opengl_example.vcxproj.filters @@ -0,0 +1,46 @@ + + + + + {c336cfe3-f0c4-464c-9ef0-a9e17a7ff222} + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx + + + + + sources + + + imgui + + + sources + + + imgui + + + imgui + + + + + imgui + + + imgui + + + sources + + + imgui + + + + + + \ No newline at end of file diff --git a/examples/opengl_example/Makefile b/examples/opengl_example/Makefile deleted file mode 100644 index 91d1b14..0000000 --- a/examples/opengl_example/Makefile +++ /dev/null @@ -1,60 +0,0 @@ -# -# Cross Platform Makefile -# Compatible with Ubuntu 14.04.1 and Mac OS X -# -# -# if you using Mac OS X: -# You'll need glfw -# http://www.glfw.org -# - -#CXX = g++ - -EXE = opengl_example -OBJS = main.o imgui_impl_glfw.o -OBJS += ../../imgui.o ../../imgui_demo.o ../../imgui_draw.o - -UNAME_S := $(shell uname -s) - - -ifeq ($(UNAME_S), Linux) #LINUX - ECHO_MESSAGE = "Linux" - LIBS = -lGL `pkg-config --static --libs glfw3` - - CXXFLAGS = -I../../ `pkg-config --cflags glfw3` - CXXFLAGS += -Wall -Wformat - CFLAGS = $(CXXFLAGS) -endif - -ifeq ($(UNAME_S), Darwin) #APPLE - ECHO_MESSAGE = "Mac OS X" - LIBS = -framework OpenGL -framework Cocoa -framework IOKit -framework CoreVideo - LIBS += -L/usr/local/lib -lglfw3 - - CXXFLAGS = -I../../ -I/usr/local/include - CXXFLAGS += -Wall -Wformat -# CXXFLAGS += -D__APPLE__ - CFLAGS = $(CXXFLAGS) -endif - -ifeq ($(UNAME_S), MINGW64_NT-6.3) - ECHO_MESSAGE = "Windows" - LIBS = -lglfw3 -lgdi32 -lopengl32 -limm32 - - CXXFLAGS = -I../../ -I../libs/gl3w `pkg-config --cflags glfw3` - CXXFLAGS += -Wall -Wformat - CFLAGS = $(CXXFLAGS) -endif - -.cpp.o: - $(CXX) $(CXXFLAGS) -c -o $@ $< - -all: $(EXE) - @echo Build complete for $(ECHO_MESSAGE) - -$(EXE): $(OBJS) - $(CXX) -o $(EXE) $(OBJS) $(CXXFLAGS) $(LIBS) - -clean: - rm $(EXE) $(OBJS) - diff --git a/examples/opengl_example/build_win32.bat b/examples/opengl_example/build_win32.bat deleted file mode 100644 index 278381c..0000000 --- a/examples/opengl_example/build_win32.bat +++ /dev/null @@ -1,3 +0,0 @@ -@REM Build for Visual Studio compiler. Run your copy of vcvars32.bat or vcvarsall.bat to setup command-line compiler. -mkdir Debug -cl /nologo /Zi /MD /I ..\.. /I ..\libs\glfw\include *.cpp ..\..\*.cpp /FeDebug/opengl_example.exe /FoDebug/ /link /LIBPATH:..\libs\glfw\lib-vc2010-32 glfw3.lib opengl32.lib gdi32.lib shell32.lib diff --git a/examples/opengl_example/imgui_impl_glfw.cpp b/examples/opengl_example/imgui_impl_glfw.cpp deleted file mode 100644 index 2d1f5c1..0000000 --- a/examples/opengl_example/imgui_impl_glfw.cpp +++ /dev/null @@ -1,288 +0,0 @@ -// ImGui GLFW binding with OpenGL -// In this binding, ImTextureID is used to store an OpenGL 'GLuint' texture identifier. Read the FAQ about ImTextureID in imgui.cpp. - -// If your context is GL3/GL3 then prefer using the code in opengl3_example. -// You *might* use this code with a GL3/GL4 context but make sure you disable the programmable pipeline by calling "glUseProgram(0)" before ImGui::Render(). -// We cannot do that from GL2 code because the function doesn't exist. - -// You can copy and use unmodified imgui_impl_* files in your project. See main.cpp for an example of using this. -// If you use this binding you'll need to call 4 functions: ImGui_ImplXXXX_Init(), ImGui_ImplXXXX_NewFrame(), ImGui::Render() and ImGui_ImplXXXX_Shutdown(). -// If you are new to ImGui, see examples/README.txt and documentation at the top of imgui.cpp. -// https://github.com/ocornut/imgui - -#include -#include "imgui_impl_glfw.h" - -// GLFW -#include -#ifdef _WIN32 -#undef APIENTRY -#define GLFW_EXPOSE_NATIVE_WIN32 -#define GLFW_EXPOSE_NATIVE_WGL -#include -#endif - -// Data -static GLFWwindow* g_Window = NULL; -static double g_Time = 0.0f; -static bool g_MousePressed[3] = { false, false, false }; -static float g_MouseWheel = 0.0f; -static GLuint g_FontTexture = 0; - -// 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) -void ImGui_ImplGlfw_RenderDrawLists(ImDrawData* draw_data) -{ - // Avoid rendering when minimized, scale coordinates for retina displays (screen coordinates != framebuffer coordinates) - ImGuiIO& io = ImGui::GetIO(); - int fb_width = (int)(io.DisplaySize.x * io.DisplayFramebufferScale.x); - int fb_height = (int)(io.DisplaySize.y * io.DisplayFramebufferScale.y); - if (fb_width == 0 || fb_height == 0) - return; - draw_data->ScaleClipRects(io.DisplayFramebufferScale); - - // We are using the OpenGL fixed pipeline to make the example code simpler to read! - // Setup render state: alpha-blending enabled, no face culling, no depth testing, scissor enabled, vertex/texcoord/color pointers. - GLint last_texture; glGetIntegerv(GL_TEXTURE_BINDING_2D, &last_texture); - GLint last_viewport[4]; glGetIntegerv(GL_VIEWPORT, last_viewport); - glPushAttrib(GL_ENABLE_BIT | GL_COLOR_BUFFER_BIT | GL_TRANSFORM_BIT); - glEnable(GL_BLEND); - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - glDisable(GL_CULL_FACE); - glDisable(GL_DEPTH_TEST); - glEnable(GL_SCISSOR_TEST); - glEnableClientState(GL_VERTEX_ARRAY); - glEnableClientState(GL_TEXTURE_COORD_ARRAY); - glEnableClientState(GL_COLOR_ARRAY); - glEnable(GL_TEXTURE_2D); - //glUseProgram(0); // You may want this if using this code in an OpenGL 3+ context - - // Setup viewport, orthographic projection matrix - glViewport(0, 0, (GLsizei)fb_width, (GLsizei)fb_height); - glMatrixMode(GL_PROJECTION); - glPushMatrix(); - glLoadIdentity(); - glOrtho(0.0f, io.DisplaySize.x, io.DisplaySize.y, 0.0f, -1.0f, +1.0f); - glMatrixMode(GL_MODELVIEW); - glPushMatrix(); - glLoadIdentity(); - - // Render command lists - #define OFFSETOF(TYPE, ELEMENT) ((size_t)&(((TYPE *)0)->ELEMENT)) - for (int n = 0; n < draw_data->CmdListsCount; n++) - { - const ImDrawList* cmd_list = draw_data->CmdLists[n]; - const unsigned char* vtx_buffer = (const unsigned char*)&cmd_list->VtxBuffer.front(); - const ImDrawIdx* idx_buffer = &cmd_list->IdxBuffer.front(); - glVertexPointer(2, GL_FLOAT, sizeof(ImDrawVert), (void*)(vtx_buffer + OFFSETOF(ImDrawVert, pos))); - glTexCoordPointer(2, GL_FLOAT, sizeof(ImDrawVert), (void*)(vtx_buffer + OFFSETOF(ImDrawVert, uv))); - glColorPointer(4, GL_UNSIGNED_BYTE, sizeof(ImDrawVert), (void*)(vtx_buffer + OFFSETOF(ImDrawVert, col))); - - for (int cmd_i = 0; cmd_i < cmd_list->CmdBuffer.size(); cmd_i++) - { - const ImDrawCmd* pcmd = &cmd_list->CmdBuffer[cmd_i]; - if (pcmd->UserCallback) - { - pcmd->UserCallback(cmd_list, pcmd); - } - else - { - glBindTexture(GL_TEXTURE_2D, (GLuint)(intptr_t)pcmd->TextureId); - glScissor((int)pcmd->ClipRect.x, (int)(fb_height - pcmd->ClipRect.w), (int)(pcmd->ClipRect.z - pcmd->ClipRect.x), (int)(pcmd->ClipRect.w - pcmd->ClipRect.y)); - glDrawElements(GL_TRIANGLES, (GLsizei)pcmd->ElemCount, sizeof(ImDrawIdx) == 2 ? GL_UNSIGNED_SHORT : GL_UNSIGNED_INT, idx_buffer); - } - idx_buffer += pcmd->ElemCount; - } - } - #undef OFFSETOF - - // Restore modified state - glDisableClientState(GL_COLOR_ARRAY); - glDisableClientState(GL_TEXTURE_COORD_ARRAY); - glDisableClientState(GL_VERTEX_ARRAY); - glBindTexture(GL_TEXTURE_2D, (GLuint)last_texture); - glMatrixMode(GL_MODELVIEW); - glPopMatrix(); - glMatrixMode(GL_PROJECTION); - glPopMatrix(); - glPopAttrib(); - glViewport(last_viewport[0], last_viewport[1], (GLsizei)last_viewport[2], (GLsizei)last_viewport[3]); -} - -static const char* ImGui_ImplGlfw_GetClipboardText() -{ - return glfwGetClipboardString(g_Window); -} - -static void ImGui_ImplGlfw_SetClipboardText(const char* text) -{ - glfwSetClipboardString(g_Window, text); -} - -void ImGui_ImplGlfw_MouseButtonCallback(GLFWwindow*, int button, int action, int /*mods*/) -{ - if (action == GLFW_PRESS && button >= 0 && button < 3) - g_MousePressed[button] = true; -} - -void ImGui_ImplGlfw_ScrollCallback(GLFWwindow*, double /*xoffset*/, double yoffset) -{ - g_MouseWheel += (float)yoffset; // Use fractional mouse wheel, 1.0 unit 5 lines. -} - -void ImGui_ImplGlFw_KeyCallback(GLFWwindow*, int key, int, int action, int mods) -{ - ImGuiIO& io = ImGui::GetIO(); - if (action == GLFW_PRESS) - io.KeysDown[key] = true; - if (action == GLFW_RELEASE) - io.KeysDown[key] = false; - - (void)mods; // Modifiers are not reliable across systems - io.KeyCtrl = io.KeysDown[GLFW_KEY_LEFT_CONTROL] || io.KeysDown[GLFW_KEY_RIGHT_CONTROL]; - io.KeyShift = io.KeysDown[GLFW_KEY_LEFT_SHIFT] || io.KeysDown[GLFW_KEY_RIGHT_SHIFT]; - io.KeyAlt = io.KeysDown[GLFW_KEY_LEFT_ALT] || io.KeysDown[GLFW_KEY_RIGHT_ALT]; - io.KeySuper = io.KeysDown[GLFW_KEY_LEFT_SUPER] || io.KeysDown[GLFW_KEY_RIGHT_SUPER]; -} - -void ImGui_ImplGlfw_CharCallback(GLFWwindow*, unsigned int c) -{ - ImGuiIO& io = ImGui::GetIO(); - if (c > 0 && c < 0x10000) - io.AddInputCharacter((unsigned short)c); -} - -bool ImGui_ImplGlfw_CreateDeviceObjects() -{ - // Build texture atlas - ImGuiIO& io = ImGui::GetIO(); - unsigned char* pixels; - int width, height; - io.Fonts->GetTexDataAsAlpha8(&pixels, &width, &height); - - // Upload texture to graphics system - GLint last_texture; - glGetIntegerv(GL_TEXTURE_BINDING_2D, &last_texture); - glGenTextures(1, &g_FontTexture); - glBindTexture(GL_TEXTURE_2D, g_FontTexture); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, width, height, 0, GL_ALPHA, GL_UNSIGNED_BYTE, pixels); - - // Store our identifier - io.Fonts->TexID = (void *)(intptr_t)g_FontTexture; - - // Restore state - glBindTexture(GL_TEXTURE_2D, last_texture); - - return true; -} - -void ImGui_ImplGlfw_InvalidateDeviceObjects() -{ - if (g_FontTexture) - { - glDeleteTextures(1, &g_FontTexture); - ImGui::GetIO().Fonts->TexID = 0; - g_FontTexture = 0; - } -} - -bool ImGui_ImplGlfw_Init(GLFWwindow* window, bool install_callbacks) -{ - g_Window = window; - - ImGuiIO& io = ImGui::GetIO(); - 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; - io.KeyMap[ImGuiKey_DownArrow] = GLFW_KEY_DOWN; - io.KeyMap[ImGuiKey_PageUp] = GLFW_KEY_PAGE_UP; - io.KeyMap[ImGuiKey_PageDown] = GLFW_KEY_PAGE_DOWN; - io.KeyMap[ImGuiKey_Home] = GLFW_KEY_HOME; - io.KeyMap[ImGuiKey_End] = GLFW_KEY_END; - io.KeyMap[ImGuiKey_Delete] = GLFW_KEY_DELETE; - io.KeyMap[ImGuiKey_Backspace] = GLFW_KEY_BACKSPACE; - io.KeyMap[ImGuiKey_Enter] = GLFW_KEY_ENTER; - io.KeyMap[ImGuiKey_Escape] = GLFW_KEY_ESCAPE; - io.KeyMap[ImGuiKey_A] = GLFW_KEY_A; - io.KeyMap[ImGuiKey_C] = GLFW_KEY_C; - io.KeyMap[ImGuiKey_V] = GLFW_KEY_V; - io.KeyMap[ImGuiKey_X] = GLFW_KEY_X; - io.KeyMap[ImGuiKey_Y] = GLFW_KEY_Y; - io.KeyMap[ImGuiKey_Z] = GLFW_KEY_Z; - - io.RenderDrawListsFn = ImGui_ImplGlfw_RenderDrawLists; // Alternatively you can set this to NULL and call ImGui::GetDrawData() after ImGui::Render() to get the same ImDrawData pointer. - io.SetClipboardTextFn = ImGui_ImplGlfw_SetClipboardText; - io.GetClipboardTextFn = ImGui_ImplGlfw_GetClipboardText; -#ifdef _WIN32 - io.ImeWindowHandle = glfwGetWin32Window(g_Window); -#endif - - if (install_callbacks) - { - glfwSetMouseButtonCallback(window, ImGui_ImplGlfw_MouseButtonCallback); - glfwSetScrollCallback(window, ImGui_ImplGlfw_ScrollCallback); - glfwSetKeyCallback(window, ImGui_ImplGlFw_KeyCallback); - glfwSetCharCallback(window, ImGui_ImplGlfw_CharCallback); - } - - return true; -} - -void ImGui_ImplGlfw_Shutdown() -{ - ImGui_ImplGlfw_InvalidateDeviceObjects(); - ImGui::Shutdown(); -} - -void ImGui_ImplGlfw_NewFrame() -{ - if (!g_FontTexture) - ImGui_ImplGlfw_CreateDeviceObjects(); - - ImGuiIO& io = ImGui::GetIO(); - - // Setup display size (every frame to accommodate for window resizing) - int w, h; - int display_w, display_h; - glfwGetWindowSize(g_Window, &w, &h); - glfwGetFramebufferSize(g_Window, &display_w, &display_h); - io.DisplaySize = ImVec2((float)w, (float)h); - io.DisplayFramebufferScale = ImVec2(w > 0 ? ((float)display_w / w) : 0, h > 0 ? ((float)display_h / h) : 0); - - // Setup time step - double current_time = glfwGetTime(); - io.DeltaTime = g_Time > 0.0 ? (float)(current_time - g_Time) : (float)(1.0f/60.0f); - g_Time = current_time; - - // Setup inputs - // (we already got mouse wheel, keyboard keys & characters from glfw callbacks polled in glfwPollEvents()) - if (glfwGetWindowAttrib(g_Window, GLFW_FOCUSED)) - { - double mouse_x, mouse_y; - glfwGetCursorPos(g_Window, &mouse_x, &mouse_y); - io.MousePos = ImVec2((float)mouse_x, (float)mouse_y); // Mouse position in screen coordinates (set to -1,-1 if no mouse / on another screen, etc.) - } - else - { - io.MousePos = ImVec2(-1,-1); - } - - for (int i = 0; i < 3; i++) - { - io.MouseDown[i] = g_MousePressed[i] || glfwGetMouseButton(g_Window, i) != 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. - g_MousePressed[i] = false; - } - - io.MouseWheel = g_MouseWheel; - g_MouseWheel = 0.0f; - - // Hide OS mouse cursor if ImGui is drawing it - glfwSetInputMode(g_Window, GLFW_CURSOR, io.MouseDrawCursor ? GLFW_CURSOR_HIDDEN : GLFW_CURSOR_NORMAL); - - // Start the frame - ImGui::NewFrame(); -} diff --git a/examples/opengl_example/imgui_impl_glfw.h b/examples/opengl_example/imgui_impl_glfw.h deleted file mode 100644 index 07dd96f..0000000 --- a/examples/opengl_example/imgui_impl_glfw.h +++ /dev/null @@ -1,29 +0,0 @@ -// ImGui GLFW binding with OpenGL -// In this binding, ImTextureID is used to store an OpenGL 'GLuint' texture identifier. Read the FAQ about ImTextureID in imgui.cpp. - -// If your context is GL3/GL3 then prefer using the code in opengl3_example. -// You *might* use this code with a GL3/GL4 context but make sure you disable the programmable pipeline by calling "glUseProgram(0)" before ImGui::Render(). -// We cannot do that from GL2 code because the function doesn't exist. - -// You can copy and use unmodified imgui_impl_* files in your project. See main.cpp for an example of using this. -// If you use this binding you'll need to call 4 functions: ImGui_ImplXXXX_Init(), ImGui_ImplXXXX_NewFrame(), ImGui::Render() and ImGui_ImplXXXX_Shutdown(). -// If you are new to ImGui, see examples/README.txt and documentation at the top of imgui.cpp. -// https://github.com/ocornut/imgui - -struct GLFWwindow; - -IMGUI_API bool ImGui_ImplGlfw_Init(GLFWwindow* window, bool install_callbacks); -IMGUI_API void ImGui_ImplGlfw_Shutdown(); -IMGUI_API void ImGui_ImplGlfw_NewFrame(); - -// Use if you want to reset your rendering device without losing ImGui state. -IMGUI_API void ImGui_ImplGlfw_InvalidateDeviceObjects(); -IMGUI_API bool ImGui_ImplGlfw_CreateDeviceObjects(); - -// GLFW callbacks (installed by default if you enable 'install_callbacks' during initialization) -// Provided here if you want to chain callbacks. -// You can also handle inputs yourself and use those as a reference. -IMGUI_API void ImGui_ImplGlfw_MouseButtonCallback(GLFWwindow* window, int button, int action, int mods); -IMGUI_API void ImGui_ImplGlfw_ScrollCallback(GLFWwindow* window, double xoffset, double yoffset); -IMGUI_API void ImGui_ImplGlFw_KeyCallback(GLFWwindow* window, int key, int scancode, int action, int mods); -IMGUI_API void ImGui_ImplGlfw_CharCallback(GLFWwindow* window, unsigned int c); diff --git a/examples/opengl_example/main.cpp b/examples/opengl_example/main.cpp deleted file mode 100644 index a844db5..0000000 --- a/examples/opengl_example/main.cpp +++ /dev/null @@ -1,89 +0,0 @@ -// ImGui - standalone example application for Glfw + OpenGL 2, using fixed pipeline -// If you are new to ImGui, see examples/README.txt and documentation at the top of imgui.cpp. - -#include -#include "imgui_impl_glfw.h" -#include -#include - -static void error_callback(int error, const char* description) -{ - fprintf(stderr, "Error %d: %s\n", error, description); -} - -int main(int, char**) -{ - // Setup window - glfwSetErrorCallback(error_callback); - if (!glfwInit()) - return 1; - GLFWwindow* window = glfwCreateWindow(1280, 720, "ImGui OpenGL2 example", NULL, NULL); - glfwMakeContextCurrent(window); - - // Setup ImGui binding - ImGui_ImplGlfw_Init(window, true); - - // Load Fonts - // (there is a default font, this is only if you want to change it. see extra_fonts/README.txt for more details) - //ImGuiIO& io = ImGui::GetIO(); - //io.Fonts->AddFontDefault(); - //io.Fonts->AddFontFromFileTTF("../../extra_fonts/Cousine-Regular.ttf", 15.0f); - //io.Fonts->AddFontFromFileTTF("../../extra_fonts/DroidSans.ttf", 16.0f); - //io.Fonts->AddFontFromFileTTF("../../extra_fonts/ProggyClean.ttf", 13.0f); - //io.Fonts->AddFontFromFileTTF("../../extra_fonts/ProggyTiny.ttf", 10.0f); - //io.Fonts->AddFontFromFileTTF("c:\\Windows\\Fonts\\ArialUni.ttf", 18.0f, NULL, io.Fonts->GetGlyphRangesJapanese()); - - bool show_test_window = true; - bool show_another_window = false; - ImVec4 clear_color = ImColor(114, 144, 154); - - // Main loop - while (!glfwWindowShouldClose(window)) - { - glfwPollEvents(); - ImGui_ImplGlfw_NewFrame(); - - // 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 = 0.0f; - ImGui::Text("Hello, world!"); - ImGui::SliderFloat("float", &f, 0.0f, 1.0f); - ImGui::ColorEdit3("clear color", (float*)&clear_color); - if (ImGui::Button("Test Window")) show_test_window ^= 1; - if (ImGui::Button("Another Window")) show_another_window ^= 1; - ImGui::Text("Application average %.3f ms/frame (%.1f FPS)", 1000.0f / ImGui::GetIO().Framerate, ImGui::GetIO().Framerate); - } - - // 2. Show another simple window, this time using an explicit Begin/End pair - if (show_another_window) - { - ImGui::SetNextWindowSize(ImVec2(200,100), ImGuiSetCond_FirstUseEver); - ImGui::Begin("Another Window", &show_another_window); - 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::SetNextWindowPos(ImVec2(650, 20), ImGuiSetCond_FirstUseEver); - ImGui::ShowTestWindow(&show_test_window); - } - - // Rendering - int display_w, display_h; - glfwGetFramebufferSize(window, &display_w, &display_h); - glViewport(0, 0, display_w, display_h); - glClearColor(clear_color.x, clear_color.y, clear_color.z, clear_color.w); - glClear(GL_COLOR_BUFFER_BIT); - ImGui::Render(); - glfwSwapBuffers(window); - } - - // Cleanup - ImGui_ImplGlfw_Shutdown(); - glfwTerminate(); - - return 0; -} diff --git a/examples/opengl_example/opengl_example.vcxproj b/examples/opengl_example/opengl_example.vcxproj deleted file mode 100644 index 4b354b6..0000000 --- a/examples/opengl_example/opengl_example.vcxproj +++ /dev/null @@ -1,169 +0,0 @@ - - - - - Debug - Win32 - - - Debug - x64 - - - Release - Win32 - - - Release - x64 - - - - {9CDA7840-B7A5-496D-A527-E95571496D18} - opengl_example - - - - Application - true - MultiByte - - - Application - true - MultiByte - - - Application - false - true - MultiByte - - - Application - false - true - MultiByte - - - - - - - - - - - - - - - - - - - $(ProjectDir)$(Configuration)\ - $(ProjectDir)$(Configuration)\ - $(IncludePath) - - - $(ProjectDir)$(Configuration)\ - $(ProjectDir)$(Configuration)\ - $(IncludePath) - - - $(ProjectDir)$(Configuration)\ - $(ProjectDir)$(Configuration)\ - $(IncludePath) - - - $(ProjectDir)$(Configuration)\ - $(ProjectDir)$(Configuration)\ - $(IncludePath) - - - - Level4 - Disabled - $(SolutionDir)\libs\glfw\include;..\..;%(AdditionalIncludeDirectories) - - - true - $(SolutionDir)\libs\glfw\lib-vc2010-32;%(AdditionalLibraryDirectories) - opengl32.lib;glfw3.lib;%(AdditionalDependencies) - Console - msvcrt.lib - - - - - Level4 - Disabled - $(SolutionDir)\libs\glfw\include;..\..;%(AdditionalIncludeDirectories) - - - true - $(SolutionDir)\libs\glfw\lib-vc2010-64;%(AdditionalLibraryDirectories) - opengl32.lib;glfw3.lib;%(AdditionalDependencies) - Console - msvcrt.lib - - - - - Level4 - MaxSpeed - true - true - $(SolutionDir)\libs\glfw\include;..\..;%(AdditionalIncludeDirectories) - - - true - true - true - $(SolutionDir)\libs\glfw\lib-vc2010-32;%(AdditionalLibraryDirectories) - opengl32.lib;glfw3.lib;%(AdditionalDependencies) - Console - - - - - - - Level4 - MaxSpeed - true - true - $(SolutionDir)\libs\glfw\include;..\..;%(AdditionalIncludeDirectories) - - - true - true - true - $(SolutionDir)\libs\glfw\lib-vc2010-64;%(AdditionalLibraryDirectories) - opengl32.lib;glfw3.lib;%(AdditionalDependencies) - Console - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/examples/opengl_example/opengl_example.vcxproj.filters b/examples/opengl_example/opengl_example.vcxproj.filters deleted file mode 100644 index f2282bf..0000000 --- a/examples/opengl_example/opengl_example.vcxproj.filters +++ /dev/null @@ -1,46 +0,0 @@ - - - - - {c336cfe3-f0c4-464c-9ef0-a9e17a7ff222} - - - {4FC737F1-C7A5-4376-A066-2A32D752A2FF} - cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx - - - - - sources - - - imgui - - - sources - - - imgui - - - imgui - - - - - imgui - - - imgui - - - sources - - - imgui - - - - - - \ No newline at end of file diff --git a/examples/sdl_opengl2_example/README.md b/examples/sdl_opengl2_example/README.md new file mode 100644 index 0000000..aada45d --- /dev/null +++ b/examples/sdl_opengl2_example/README.md @@ -0,0 +1,22 @@ + +# How to Build + +- On Windows with Visual Studio's CLI + +``` +set SDL2DIR=path_to_your_sdl2_folder +cl /Zi /MD /I %SDL2DIR%\include> /I ..\.. main.cpp imgui_impl_sdl.cpp ..\..\imgui*.cpp /link /LIBPATH:%SDL2DIR%\lib SDL2.lib SDL2main.lib +``` + +- On Linux and similar Unixes + +``` +c++ `sdl2-config --cflags` -I ../.. main.cpp imgui_impl_sdl.cpp ../../imgui*.cpp `sdl2-config --libs` -lGL -o sdl2example +``` + +- On Mac OS X + +``` +brew install sdl2 +c++ `sdl2-config --cflags` -I ../.. main.cpp imgui_impl_sdl.cpp ../../imgui*.cpp `sdl2-config --libs` -framework OpenGl -o sdl2example +``` diff --git a/examples/README.txt b/examples/README.txt index df2e86d..5a1c8df 100644 --- a/examples/README.txt +++ b/examples/README.txt @@ -8,11 +8,13 @@ TL;DR; - Newcomers, read 'PROGRAMMER GUIDE' in imgui.cpp for notes on how to setup ImGui in your codebase. - - Refer to 'opengl_example' to understand how the library is setup, it is the simplest one. + - Refer to 'opengl2_example' to LEARN how the library is setup, it is the simplest one. The other examples requires more boilerplate and are harder to read. + - If you are using OpenGL in your application, probably use an opengl3_xxx backend. + Mixing old fixed pipeline OpenGL2 and programmable pipeline OpenGL3+ isn't well supported by drivers. - If you are using of the backend provided here, so you can copy the imgui_impl_xxx.cpp/h files to your project and use them unmodified. - - If you have your own engine, you probably want to start from 'opengl_example' and adapt it to + - If you have your own engine, you probably want to start from one of the OpenGL example and adapt it to your engine, but you can read the other examples as well. ImGui is highly portable and only requires a few things to run: @@ -41,15 +43,14 @@ Also note that some setup or GPU drivers may be causing extra lag (possibly by enforcing triple buffering), leaving you with no option but sadness/anger (Intel GPU drivers were reported as such). -opengl_example/ - OpenGL example, using GLFW + fixed pipeline. - This is simple and should work for all OpenGL enabled applications. - Prefer following this example to learn how ImGui works! - (You can use this code in a GL3/GL4 context but make sure you disable the programmable pipeline - by calling "glUseProgram(0)" before ImGui::Render.) +opengl2_example/ + GLFW + OpenGL example (old fixed pipeline). + This is simple to read. Prefer following this example to learn how ImGui works! + (You might be able to use this code in a GL3/GL4 context but make sure you disable the programmable + pipeline by calling "glUseProgram(0)" before ImGui::Render.) opengl3_example/ - OpenGL example, using GLFW/GL3W + programmable pipeline. + GLFW + OpenGL example (programmable pipeline, binding modern functions with GL3W). This uses more modern OpenGL calls and custom shaders. It's more messy. directx9_example/ @@ -68,8 +69,8 @@ On iOS, Using Synergy to access keyboard/mouse data from server computer. Synergy keyboard integration is rather hacky. -sdl_opengl_example/ - SDL2 + OpenGL example. +sdl_opengl2_example/ + SDL2 + OpenGL example (old fixed pipeline). sdl_opengl3_example/ SDL2 + OpenGL3 example. diff --git a/examples/imgui_examples_msvc2010.sln b/examples/imgui_examples_msvc2010.sln index b7e6a25..16f0d60 100644 --- a/examples/imgui_examples_msvc2010.sln +++ b/examples/imgui_examples_msvc2010.sln @@ -1,7 +1,7 @@  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}" +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "opengl2_example", "opengl_example\opengl2_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 diff --git a/examples/opengl2_example/Makefile b/examples/opengl2_example/Makefile new file mode 100644 index 0000000..bd79d1b --- /dev/null +++ b/examples/opengl2_example/Makefile @@ -0,0 +1,60 @@ +# +# Cross Platform Makefile +# Compatible with Ubuntu 14.04.1 and Mac OS X +# +# +# if you using Mac OS X: +# You'll need glfw +# http://www.glfw.org +# + +#CXX = g++ + +EXE = opengl2_example +OBJS = main.o imgui_impl_glfw.o +OBJS += ../../imgui.o ../../imgui_demo.o ../../imgui_draw.o + +UNAME_S := $(shell uname -s) + + +ifeq ($(UNAME_S), Linux) #LINUX + ECHO_MESSAGE = "Linux" + LIBS = -lGL `pkg-config --static --libs glfw3` + + CXXFLAGS = -I../../ `pkg-config --cflags glfw3` + CXXFLAGS += -Wall -Wformat + CFLAGS = $(CXXFLAGS) +endif + +ifeq ($(UNAME_S), Darwin) #APPLE + ECHO_MESSAGE = "Mac OS X" + LIBS = -framework OpenGL -framework Cocoa -framework IOKit -framework CoreVideo + LIBS += -L/usr/local/lib -lglfw3 + + CXXFLAGS = -I../../ -I/usr/local/include + CXXFLAGS += -Wall -Wformat +# CXXFLAGS += -D__APPLE__ + CFLAGS = $(CXXFLAGS) +endif + +ifeq ($(UNAME_S), MINGW64_NT-6.3) + ECHO_MESSAGE = "Windows" + LIBS = -lglfw3 -lgdi32 -lopengl32 -limm32 + + CXXFLAGS = -I../../ -I../libs/gl3w `pkg-config --cflags glfw3` + CXXFLAGS += -Wall -Wformat + CFLAGS = $(CXXFLAGS) +endif + +.cpp.o: + $(CXX) $(CXXFLAGS) -c -o $@ $< + +all: $(EXE) + @echo Build complete for $(ECHO_MESSAGE) + +$(EXE): $(OBJS) + $(CXX) -o $(EXE) $(OBJS) $(CXXFLAGS) $(LIBS) + +clean: + rm $(EXE) $(OBJS) + diff --git a/examples/opengl2_example/build_win32.bat b/examples/opengl2_example/build_win32.bat new file mode 100644 index 0000000..278381c --- /dev/null +++ b/examples/opengl2_example/build_win32.bat @@ -0,0 +1,3 @@ +@REM Build for Visual Studio compiler. Run your copy of vcvars32.bat or vcvarsall.bat to setup command-line compiler. +mkdir Debug +cl /nologo /Zi /MD /I ..\.. /I ..\libs\glfw\include *.cpp ..\..\*.cpp /FeDebug/opengl_example.exe /FoDebug/ /link /LIBPATH:..\libs\glfw\lib-vc2010-32 glfw3.lib opengl32.lib gdi32.lib shell32.lib diff --git a/examples/opengl2_example/imgui_impl_glfw.cpp b/examples/opengl2_example/imgui_impl_glfw.cpp new file mode 100644 index 0000000..2d1f5c1 --- /dev/null +++ b/examples/opengl2_example/imgui_impl_glfw.cpp @@ -0,0 +1,288 @@ +// ImGui GLFW binding with OpenGL +// In this binding, ImTextureID is used to store an OpenGL 'GLuint' texture identifier. Read the FAQ about ImTextureID in imgui.cpp. + +// If your context is GL3/GL3 then prefer using the code in opengl3_example. +// You *might* use this code with a GL3/GL4 context but make sure you disable the programmable pipeline by calling "glUseProgram(0)" before ImGui::Render(). +// We cannot do that from GL2 code because the function doesn't exist. + +// You can copy and use unmodified imgui_impl_* files in your project. See main.cpp for an example of using this. +// If you use this binding you'll need to call 4 functions: ImGui_ImplXXXX_Init(), ImGui_ImplXXXX_NewFrame(), ImGui::Render() and ImGui_ImplXXXX_Shutdown(). +// If you are new to ImGui, see examples/README.txt and documentation at the top of imgui.cpp. +// https://github.com/ocornut/imgui + +#include +#include "imgui_impl_glfw.h" + +// GLFW +#include +#ifdef _WIN32 +#undef APIENTRY +#define GLFW_EXPOSE_NATIVE_WIN32 +#define GLFW_EXPOSE_NATIVE_WGL +#include +#endif + +// Data +static GLFWwindow* g_Window = NULL; +static double g_Time = 0.0f; +static bool g_MousePressed[3] = { false, false, false }; +static float g_MouseWheel = 0.0f; +static GLuint g_FontTexture = 0; + +// 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) +void ImGui_ImplGlfw_RenderDrawLists(ImDrawData* draw_data) +{ + // Avoid rendering when minimized, scale coordinates for retina displays (screen coordinates != framebuffer coordinates) + ImGuiIO& io = ImGui::GetIO(); + int fb_width = (int)(io.DisplaySize.x * io.DisplayFramebufferScale.x); + int fb_height = (int)(io.DisplaySize.y * io.DisplayFramebufferScale.y); + if (fb_width == 0 || fb_height == 0) + return; + draw_data->ScaleClipRects(io.DisplayFramebufferScale); + + // We are using the OpenGL fixed pipeline to make the example code simpler to read! + // Setup render state: alpha-blending enabled, no face culling, no depth testing, scissor enabled, vertex/texcoord/color pointers. + GLint last_texture; glGetIntegerv(GL_TEXTURE_BINDING_2D, &last_texture); + GLint last_viewport[4]; glGetIntegerv(GL_VIEWPORT, last_viewport); + glPushAttrib(GL_ENABLE_BIT | GL_COLOR_BUFFER_BIT | GL_TRANSFORM_BIT); + glEnable(GL_BLEND); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + glDisable(GL_CULL_FACE); + glDisable(GL_DEPTH_TEST); + glEnable(GL_SCISSOR_TEST); + glEnableClientState(GL_VERTEX_ARRAY); + glEnableClientState(GL_TEXTURE_COORD_ARRAY); + glEnableClientState(GL_COLOR_ARRAY); + glEnable(GL_TEXTURE_2D); + //glUseProgram(0); // You may want this if using this code in an OpenGL 3+ context + + // Setup viewport, orthographic projection matrix + glViewport(0, 0, (GLsizei)fb_width, (GLsizei)fb_height); + glMatrixMode(GL_PROJECTION); + glPushMatrix(); + glLoadIdentity(); + glOrtho(0.0f, io.DisplaySize.x, io.DisplaySize.y, 0.0f, -1.0f, +1.0f); + glMatrixMode(GL_MODELVIEW); + glPushMatrix(); + glLoadIdentity(); + + // Render command lists + #define OFFSETOF(TYPE, ELEMENT) ((size_t)&(((TYPE *)0)->ELEMENT)) + for (int n = 0; n < draw_data->CmdListsCount; n++) + { + const ImDrawList* cmd_list = draw_data->CmdLists[n]; + const unsigned char* vtx_buffer = (const unsigned char*)&cmd_list->VtxBuffer.front(); + const ImDrawIdx* idx_buffer = &cmd_list->IdxBuffer.front(); + glVertexPointer(2, GL_FLOAT, sizeof(ImDrawVert), (void*)(vtx_buffer + OFFSETOF(ImDrawVert, pos))); + glTexCoordPointer(2, GL_FLOAT, sizeof(ImDrawVert), (void*)(vtx_buffer + OFFSETOF(ImDrawVert, uv))); + glColorPointer(4, GL_UNSIGNED_BYTE, sizeof(ImDrawVert), (void*)(vtx_buffer + OFFSETOF(ImDrawVert, col))); + + for (int cmd_i = 0; cmd_i < cmd_list->CmdBuffer.size(); cmd_i++) + { + const ImDrawCmd* pcmd = &cmd_list->CmdBuffer[cmd_i]; + if (pcmd->UserCallback) + { + pcmd->UserCallback(cmd_list, pcmd); + } + else + { + glBindTexture(GL_TEXTURE_2D, (GLuint)(intptr_t)pcmd->TextureId); + glScissor((int)pcmd->ClipRect.x, (int)(fb_height - pcmd->ClipRect.w), (int)(pcmd->ClipRect.z - pcmd->ClipRect.x), (int)(pcmd->ClipRect.w - pcmd->ClipRect.y)); + glDrawElements(GL_TRIANGLES, (GLsizei)pcmd->ElemCount, sizeof(ImDrawIdx) == 2 ? GL_UNSIGNED_SHORT : GL_UNSIGNED_INT, idx_buffer); + } + idx_buffer += pcmd->ElemCount; + } + } + #undef OFFSETOF + + // Restore modified state + glDisableClientState(GL_COLOR_ARRAY); + glDisableClientState(GL_TEXTURE_COORD_ARRAY); + glDisableClientState(GL_VERTEX_ARRAY); + glBindTexture(GL_TEXTURE_2D, (GLuint)last_texture); + glMatrixMode(GL_MODELVIEW); + glPopMatrix(); + glMatrixMode(GL_PROJECTION); + glPopMatrix(); + glPopAttrib(); + glViewport(last_viewport[0], last_viewport[1], (GLsizei)last_viewport[2], (GLsizei)last_viewport[3]); +} + +static const char* ImGui_ImplGlfw_GetClipboardText() +{ + return glfwGetClipboardString(g_Window); +} + +static void ImGui_ImplGlfw_SetClipboardText(const char* text) +{ + glfwSetClipboardString(g_Window, text); +} + +void ImGui_ImplGlfw_MouseButtonCallback(GLFWwindow*, int button, int action, int /*mods*/) +{ + if (action == GLFW_PRESS && button >= 0 && button < 3) + g_MousePressed[button] = true; +} + +void ImGui_ImplGlfw_ScrollCallback(GLFWwindow*, double /*xoffset*/, double yoffset) +{ + g_MouseWheel += (float)yoffset; // Use fractional mouse wheel, 1.0 unit 5 lines. +} + +void ImGui_ImplGlFw_KeyCallback(GLFWwindow*, int key, int, int action, int mods) +{ + ImGuiIO& io = ImGui::GetIO(); + if (action == GLFW_PRESS) + io.KeysDown[key] = true; + if (action == GLFW_RELEASE) + io.KeysDown[key] = false; + + (void)mods; // Modifiers are not reliable across systems + io.KeyCtrl = io.KeysDown[GLFW_KEY_LEFT_CONTROL] || io.KeysDown[GLFW_KEY_RIGHT_CONTROL]; + io.KeyShift = io.KeysDown[GLFW_KEY_LEFT_SHIFT] || io.KeysDown[GLFW_KEY_RIGHT_SHIFT]; + io.KeyAlt = io.KeysDown[GLFW_KEY_LEFT_ALT] || io.KeysDown[GLFW_KEY_RIGHT_ALT]; + io.KeySuper = io.KeysDown[GLFW_KEY_LEFT_SUPER] || io.KeysDown[GLFW_KEY_RIGHT_SUPER]; +} + +void ImGui_ImplGlfw_CharCallback(GLFWwindow*, unsigned int c) +{ + ImGuiIO& io = ImGui::GetIO(); + if (c > 0 && c < 0x10000) + io.AddInputCharacter((unsigned short)c); +} + +bool ImGui_ImplGlfw_CreateDeviceObjects() +{ + // Build texture atlas + ImGuiIO& io = ImGui::GetIO(); + unsigned char* pixels; + int width, height; + io.Fonts->GetTexDataAsAlpha8(&pixels, &width, &height); + + // Upload texture to graphics system + GLint last_texture; + glGetIntegerv(GL_TEXTURE_BINDING_2D, &last_texture); + glGenTextures(1, &g_FontTexture); + glBindTexture(GL_TEXTURE_2D, g_FontTexture); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, width, height, 0, GL_ALPHA, GL_UNSIGNED_BYTE, pixels); + + // Store our identifier + io.Fonts->TexID = (void *)(intptr_t)g_FontTexture; + + // Restore state + glBindTexture(GL_TEXTURE_2D, last_texture); + + return true; +} + +void ImGui_ImplGlfw_InvalidateDeviceObjects() +{ + if (g_FontTexture) + { + glDeleteTextures(1, &g_FontTexture); + ImGui::GetIO().Fonts->TexID = 0; + g_FontTexture = 0; + } +} + +bool ImGui_ImplGlfw_Init(GLFWwindow* window, bool install_callbacks) +{ + g_Window = window; + + ImGuiIO& io = ImGui::GetIO(); + 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; + io.KeyMap[ImGuiKey_DownArrow] = GLFW_KEY_DOWN; + io.KeyMap[ImGuiKey_PageUp] = GLFW_KEY_PAGE_UP; + io.KeyMap[ImGuiKey_PageDown] = GLFW_KEY_PAGE_DOWN; + io.KeyMap[ImGuiKey_Home] = GLFW_KEY_HOME; + io.KeyMap[ImGuiKey_End] = GLFW_KEY_END; + io.KeyMap[ImGuiKey_Delete] = GLFW_KEY_DELETE; + io.KeyMap[ImGuiKey_Backspace] = GLFW_KEY_BACKSPACE; + io.KeyMap[ImGuiKey_Enter] = GLFW_KEY_ENTER; + io.KeyMap[ImGuiKey_Escape] = GLFW_KEY_ESCAPE; + io.KeyMap[ImGuiKey_A] = GLFW_KEY_A; + io.KeyMap[ImGuiKey_C] = GLFW_KEY_C; + io.KeyMap[ImGuiKey_V] = GLFW_KEY_V; + io.KeyMap[ImGuiKey_X] = GLFW_KEY_X; + io.KeyMap[ImGuiKey_Y] = GLFW_KEY_Y; + io.KeyMap[ImGuiKey_Z] = GLFW_KEY_Z; + + io.RenderDrawListsFn = ImGui_ImplGlfw_RenderDrawLists; // Alternatively you can set this to NULL and call ImGui::GetDrawData() after ImGui::Render() to get the same ImDrawData pointer. + io.SetClipboardTextFn = ImGui_ImplGlfw_SetClipboardText; + io.GetClipboardTextFn = ImGui_ImplGlfw_GetClipboardText; +#ifdef _WIN32 + io.ImeWindowHandle = glfwGetWin32Window(g_Window); +#endif + + if (install_callbacks) + { + glfwSetMouseButtonCallback(window, ImGui_ImplGlfw_MouseButtonCallback); + glfwSetScrollCallback(window, ImGui_ImplGlfw_ScrollCallback); + glfwSetKeyCallback(window, ImGui_ImplGlFw_KeyCallback); + glfwSetCharCallback(window, ImGui_ImplGlfw_CharCallback); + } + + return true; +} + +void ImGui_ImplGlfw_Shutdown() +{ + ImGui_ImplGlfw_InvalidateDeviceObjects(); + ImGui::Shutdown(); +} + +void ImGui_ImplGlfw_NewFrame() +{ + if (!g_FontTexture) + ImGui_ImplGlfw_CreateDeviceObjects(); + + ImGuiIO& io = ImGui::GetIO(); + + // Setup display size (every frame to accommodate for window resizing) + int w, h; + int display_w, display_h; + glfwGetWindowSize(g_Window, &w, &h); + glfwGetFramebufferSize(g_Window, &display_w, &display_h); + io.DisplaySize = ImVec2((float)w, (float)h); + io.DisplayFramebufferScale = ImVec2(w > 0 ? ((float)display_w / w) : 0, h > 0 ? ((float)display_h / h) : 0); + + // Setup time step + double current_time = glfwGetTime(); + io.DeltaTime = g_Time > 0.0 ? (float)(current_time - g_Time) : (float)(1.0f/60.0f); + g_Time = current_time; + + // Setup inputs + // (we already got mouse wheel, keyboard keys & characters from glfw callbacks polled in glfwPollEvents()) + if (glfwGetWindowAttrib(g_Window, GLFW_FOCUSED)) + { + double mouse_x, mouse_y; + glfwGetCursorPos(g_Window, &mouse_x, &mouse_y); + io.MousePos = ImVec2((float)mouse_x, (float)mouse_y); // Mouse position in screen coordinates (set to -1,-1 if no mouse / on another screen, etc.) + } + else + { + io.MousePos = ImVec2(-1,-1); + } + + for (int i = 0; i < 3; i++) + { + io.MouseDown[i] = g_MousePressed[i] || glfwGetMouseButton(g_Window, i) != 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. + g_MousePressed[i] = false; + } + + io.MouseWheel = g_MouseWheel; + g_MouseWheel = 0.0f; + + // Hide OS mouse cursor if ImGui is drawing it + glfwSetInputMode(g_Window, GLFW_CURSOR, io.MouseDrawCursor ? GLFW_CURSOR_HIDDEN : GLFW_CURSOR_NORMAL); + + // Start the frame + ImGui::NewFrame(); +} diff --git a/examples/opengl2_example/imgui_impl_glfw.h b/examples/opengl2_example/imgui_impl_glfw.h new file mode 100644 index 0000000..07dd96f --- /dev/null +++ b/examples/opengl2_example/imgui_impl_glfw.h @@ -0,0 +1,29 @@ +// ImGui GLFW binding with OpenGL +// In this binding, ImTextureID is used to store an OpenGL 'GLuint' texture identifier. Read the FAQ about ImTextureID in imgui.cpp. + +// If your context is GL3/GL3 then prefer using the code in opengl3_example. +// You *might* use this code with a GL3/GL4 context but make sure you disable the programmable pipeline by calling "glUseProgram(0)" before ImGui::Render(). +// We cannot do that from GL2 code because the function doesn't exist. + +// You can copy and use unmodified imgui_impl_* files in your project. See main.cpp for an example of using this. +// If you use this binding you'll need to call 4 functions: ImGui_ImplXXXX_Init(), ImGui_ImplXXXX_NewFrame(), ImGui::Render() and ImGui_ImplXXXX_Shutdown(). +// If you are new to ImGui, see examples/README.txt and documentation at the top of imgui.cpp. +// https://github.com/ocornut/imgui + +struct GLFWwindow; + +IMGUI_API bool ImGui_ImplGlfw_Init(GLFWwindow* window, bool install_callbacks); +IMGUI_API void ImGui_ImplGlfw_Shutdown(); +IMGUI_API void ImGui_ImplGlfw_NewFrame(); + +// Use if you want to reset your rendering device without losing ImGui state. +IMGUI_API void ImGui_ImplGlfw_InvalidateDeviceObjects(); +IMGUI_API bool ImGui_ImplGlfw_CreateDeviceObjects(); + +// GLFW callbacks (installed by default if you enable 'install_callbacks' during initialization) +// Provided here if you want to chain callbacks. +// You can also handle inputs yourself and use those as a reference. +IMGUI_API void ImGui_ImplGlfw_MouseButtonCallback(GLFWwindow* window, int button, int action, int mods); +IMGUI_API void ImGui_ImplGlfw_ScrollCallback(GLFWwindow* window, double xoffset, double yoffset); +IMGUI_API void ImGui_ImplGlFw_KeyCallback(GLFWwindow* window, int key, int scancode, int action, int mods); +IMGUI_API void ImGui_ImplGlfw_CharCallback(GLFWwindow* window, unsigned int c); diff --git a/examples/opengl2_example/main.cpp b/examples/opengl2_example/main.cpp new file mode 100644 index 0000000..a844db5 --- /dev/null +++ b/examples/opengl2_example/main.cpp @@ -0,0 +1,89 @@ +// ImGui - standalone example application for Glfw + OpenGL 2, using fixed pipeline +// If you are new to ImGui, see examples/README.txt and documentation at the top of imgui.cpp. + +#include +#include "imgui_impl_glfw.h" +#include +#include + +static void error_callback(int error, const char* description) +{ + fprintf(stderr, "Error %d: %s\n", error, description); +} + +int main(int, char**) +{ + // Setup window + glfwSetErrorCallback(error_callback); + if (!glfwInit()) + return 1; + GLFWwindow* window = glfwCreateWindow(1280, 720, "ImGui OpenGL2 example", NULL, NULL); + glfwMakeContextCurrent(window); + + // Setup ImGui binding + ImGui_ImplGlfw_Init(window, true); + + // Load Fonts + // (there is a default font, this is only if you want to change it. see extra_fonts/README.txt for more details) + //ImGuiIO& io = ImGui::GetIO(); + //io.Fonts->AddFontDefault(); + //io.Fonts->AddFontFromFileTTF("../../extra_fonts/Cousine-Regular.ttf", 15.0f); + //io.Fonts->AddFontFromFileTTF("../../extra_fonts/DroidSans.ttf", 16.0f); + //io.Fonts->AddFontFromFileTTF("../../extra_fonts/ProggyClean.ttf", 13.0f); + //io.Fonts->AddFontFromFileTTF("../../extra_fonts/ProggyTiny.ttf", 10.0f); + //io.Fonts->AddFontFromFileTTF("c:\\Windows\\Fonts\\ArialUni.ttf", 18.0f, NULL, io.Fonts->GetGlyphRangesJapanese()); + + bool show_test_window = true; + bool show_another_window = false; + ImVec4 clear_color = ImColor(114, 144, 154); + + // Main loop + while (!glfwWindowShouldClose(window)) + { + glfwPollEvents(); + ImGui_ImplGlfw_NewFrame(); + + // 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 = 0.0f; + ImGui::Text("Hello, world!"); + ImGui::SliderFloat("float", &f, 0.0f, 1.0f); + ImGui::ColorEdit3("clear color", (float*)&clear_color); + if (ImGui::Button("Test Window")) show_test_window ^= 1; + if (ImGui::Button("Another Window")) show_another_window ^= 1; + ImGui::Text("Application average %.3f ms/frame (%.1f FPS)", 1000.0f / ImGui::GetIO().Framerate, ImGui::GetIO().Framerate); + } + + // 2. Show another simple window, this time using an explicit Begin/End pair + if (show_another_window) + { + ImGui::SetNextWindowSize(ImVec2(200,100), ImGuiSetCond_FirstUseEver); + ImGui::Begin("Another Window", &show_another_window); + 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::SetNextWindowPos(ImVec2(650, 20), ImGuiSetCond_FirstUseEver); + ImGui::ShowTestWindow(&show_test_window); + } + + // Rendering + int display_w, display_h; + glfwGetFramebufferSize(window, &display_w, &display_h); + glViewport(0, 0, display_w, display_h); + glClearColor(clear_color.x, clear_color.y, clear_color.z, clear_color.w); + glClear(GL_COLOR_BUFFER_BIT); + ImGui::Render(); + glfwSwapBuffers(window); + } + + // Cleanup + ImGui_ImplGlfw_Shutdown(); + glfwTerminate(); + + return 0; +} diff --git a/examples/opengl2_example/opengl_example.vcxproj b/examples/opengl2_example/opengl_example.vcxproj new file mode 100644 index 0000000..4b354b6 --- /dev/null +++ b/examples/opengl2_example/opengl_example.vcxproj @@ -0,0 +1,169 @@ + + + + + Debug + Win32 + + + Debug + x64 + + + Release + Win32 + + + Release + x64 + + + + {9CDA7840-B7A5-496D-A527-E95571496D18} + opengl_example + + + + Application + true + MultiByte + + + Application + true + MultiByte + + + Application + false + true + MultiByte + + + Application + false + true + MultiByte + + + + + + + + + + + + + + + + + + + $(ProjectDir)$(Configuration)\ + $(ProjectDir)$(Configuration)\ + $(IncludePath) + + + $(ProjectDir)$(Configuration)\ + $(ProjectDir)$(Configuration)\ + $(IncludePath) + + + $(ProjectDir)$(Configuration)\ + $(ProjectDir)$(Configuration)\ + $(IncludePath) + + + $(ProjectDir)$(Configuration)\ + $(ProjectDir)$(Configuration)\ + $(IncludePath) + + + + Level4 + Disabled + $(SolutionDir)\libs\glfw\include;..\..;%(AdditionalIncludeDirectories) + + + true + $(SolutionDir)\libs\glfw\lib-vc2010-32;%(AdditionalLibraryDirectories) + opengl32.lib;glfw3.lib;%(AdditionalDependencies) + Console + msvcrt.lib + + + + + Level4 + Disabled + $(SolutionDir)\libs\glfw\include;..\..;%(AdditionalIncludeDirectories) + + + true + $(SolutionDir)\libs\glfw\lib-vc2010-64;%(AdditionalLibraryDirectories) + opengl32.lib;glfw3.lib;%(AdditionalDependencies) + Console + msvcrt.lib + + + + + Level4 + MaxSpeed + true + true + $(SolutionDir)\libs\glfw\include;..\..;%(AdditionalIncludeDirectories) + + + true + true + true + $(SolutionDir)\libs\glfw\lib-vc2010-32;%(AdditionalLibraryDirectories) + opengl32.lib;glfw3.lib;%(AdditionalDependencies) + Console + + + + + + + Level4 + MaxSpeed + true + true + $(SolutionDir)\libs\glfw\include;..\..;%(AdditionalIncludeDirectories) + + + true + true + true + $(SolutionDir)\libs\glfw\lib-vc2010-64;%(AdditionalLibraryDirectories) + opengl32.lib;glfw3.lib;%(AdditionalDependencies) + Console + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/examples/opengl2_example/opengl_example.vcxproj.filters b/examples/opengl2_example/opengl_example.vcxproj.filters new file mode 100644 index 0000000..f2282bf --- /dev/null +++ b/examples/opengl2_example/opengl_example.vcxproj.filters @@ -0,0 +1,46 @@ + + + + + {c336cfe3-f0c4-464c-9ef0-a9e17a7ff222} + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx + + + + + sources + + + imgui + + + sources + + + imgui + + + imgui + + + + + imgui + + + imgui + + + sources + + + imgui + + + + + + \ No newline at end of file diff --git a/examples/opengl_example/Makefile b/examples/opengl_example/Makefile deleted file mode 100644 index 91d1b14..0000000 --- a/examples/opengl_example/Makefile +++ /dev/null @@ -1,60 +0,0 @@ -# -# Cross Platform Makefile -# Compatible with Ubuntu 14.04.1 and Mac OS X -# -# -# if you using Mac OS X: -# You'll need glfw -# http://www.glfw.org -# - -#CXX = g++ - -EXE = opengl_example -OBJS = main.o imgui_impl_glfw.o -OBJS += ../../imgui.o ../../imgui_demo.o ../../imgui_draw.o - -UNAME_S := $(shell uname -s) - - -ifeq ($(UNAME_S), Linux) #LINUX - ECHO_MESSAGE = "Linux" - LIBS = -lGL `pkg-config --static --libs glfw3` - - CXXFLAGS = -I../../ `pkg-config --cflags glfw3` - CXXFLAGS += -Wall -Wformat - CFLAGS = $(CXXFLAGS) -endif - -ifeq ($(UNAME_S), Darwin) #APPLE - ECHO_MESSAGE = "Mac OS X" - LIBS = -framework OpenGL -framework Cocoa -framework IOKit -framework CoreVideo - LIBS += -L/usr/local/lib -lglfw3 - - CXXFLAGS = -I../../ -I/usr/local/include - CXXFLAGS += -Wall -Wformat -# CXXFLAGS += -D__APPLE__ - CFLAGS = $(CXXFLAGS) -endif - -ifeq ($(UNAME_S), MINGW64_NT-6.3) - ECHO_MESSAGE = "Windows" - LIBS = -lglfw3 -lgdi32 -lopengl32 -limm32 - - CXXFLAGS = -I../../ -I../libs/gl3w `pkg-config --cflags glfw3` - CXXFLAGS += -Wall -Wformat - CFLAGS = $(CXXFLAGS) -endif - -.cpp.o: - $(CXX) $(CXXFLAGS) -c -o $@ $< - -all: $(EXE) - @echo Build complete for $(ECHO_MESSAGE) - -$(EXE): $(OBJS) - $(CXX) -o $(EXE) $(OBJS) $(CXXFLAGS) $(LIBS) - -clean: - rm $(EXE) $(OBJS) - diff --git a/examples/opengl_example/build_win32.bat b/examples/opengl_example/build_win32.bat deleted file mode 100644 index 278381c..0000000 --- a/examples/opengl_example/build_win32.bat +++ /dev/null @@ -1,3 +0,0 @@ -@REM Build for Visual Studio compiler. Run your copy of vcvars32.bat or vcvarsall.bat to setup command-line compiler. -mkdir Debug -cl /nologo /Zi /MD /I ..\.. /I ..\libs\glfw\include *.cpp ..\..\*.cpp /FeDebug/opengl_example.exe /FoDebug/ /link /LIBPATH:..\libs\glfw\lib-vc2010-32 glfw3.lib opengl32.lib gdi32.lib shell32.lib diff --git a/examples/opengl_example/imgui_impl_glfw.cpp b/examples/opengl_example/imgui_impl_glfw.cpp deleted file mode 100644 index 2d1f5c1..0000000 --- a/examples/opengl_example/imgui_impl_glfw.cpp +++ /dev/null @@ -1,288 +0,0 @@ -// ImGui GLFW binding with OpenGL -// In this binding, ImTextureID is used to store an OpenGL 'GLuint' texture identifier. Read the FAQ about ImTextureID in imgui.cpp. - -// If your context is GL3/GL3 then prefer using the code in opengl3_example. -// You *might* use this code with a GL3/GL4 context but make sure you disable the programmable pipeline by calling "glUseProgram(0)" before ImGui::Render(). -// We cannot do that from GL2 code because the function doesn't exist. - -// You can copy and use unmodified imgui_impl_* files in your project. See main.cpp for an example of using this. -// If you use this binding you'll need to call 4 functions: ImGui_ImplXXXX_Init(), ImGui_ImplXXXX_NewFrame(), ImGui::Render() and ImGui_ImplXXXX_Shutdown(). -// If you are new to ImGui, see examples/README.txt and documentation at the top of imgui.cpp. -// https://github.com/ocornut/imgui - -#include -#include "imgui_impl_glfw.h" - -// GLFW -#include -#ifdef _WIN32 -#undef APIENTRY -#define GLFW_EXPOSE_NATIVE_WIN32 -#define GLFW_EXPOSE_NATIVE_WGL -#include -#endif - -// Data -static GLFWwindow* g_Window = NULL; -static double g_Time = 0.0f; -static bool g_MousePressed[3] = { false, false, false }; -static float g_MouseWheel = 0.0f; -static GLuint g_FontTexture = 0; - -// 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) -void ImGui_ImplGlfw_RenderDrawLists(ImDrawData* draw_data) -{ - // Avoid rendering when minimized, scale coordinates for retina displays (screen coordinates != framebuffer coordinates) - ImGuiIO& io = ImGui::GetIO(); - int fb_width = (int)(io.DisplaySize.x * io.DisplayFramebufferScale.x); - int fb_height = (int)(io.DisplaySize.y * io.DisplayFramebufferScale.y); - if (fb_width == 0 || fb_height == 0) - return; - draw_data->ScaleClipRects(io.DisplayFramebufferScale); - - // We are using the OpenGL fixed pipeline to make the example code simpler to read! - // Setup render state: alpha-blending enabled, no face culling, no depth testing, scissor enabled, vertex/texcoord/color pointers. - GLint last_texture; glGetIntegerv(GL_TEXTURE_BINDING_2D, &last_texture); - GLint last_viewport[4]; glGetIntegerv(GL_VIEWPORT, last_viewport); - glPushAttrib(GL_ENABLE_BIT | GL_COLOR_BUFFER_BIT | GL_TRANSFORM_BIT); - glEnable(GL_BLEND); - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - glDisable(GL_CULL_FACE); - glDisable(GL_DEPTH_TEST); - glEnable(GL_SCISSOR_TEST); - glEnableClientState(GL_VERTEX_ARRAY); - glEnableClientState(GL_TEXTURE_COORD_ARRAY); - glEnableClientState(GL_COLOR_ARRAY); - glEnable(GL_TEXTURE_2D); - //glUseProgram(0); // You may want this if using this code in an OpenGL 3+ context - - // Setup viewport, orthographic projection matrix - glViewport(0, 0, (GLsizei)fb_width, (GLsizei)fb_height); - glMatrixMode(GL_PROJECTION); - glPushMatrix(); - glLoadIdentity(); - glOrtho(0.0f, io.DisplaySize.x, io.DisplaySize.y, 0.0f, -1.0f, +1.0f); - glMatrixMode(GL_MODELVIEW); - glPushMatrix(); - glLoadIdentity(); - - // Render command lists - #define OFFSETOF(TYPE, ELEMENT) ((size_t)&(((TYPE *)0)->ELEMENT)) - for (int n = 0; n < draw_data->CmdListsCount; n++) - { - const ImDrawList* cmd_list = draw_data->CmdLists[n]; - const unsigned char* vtx_buffer = (const unsigned char*)&cmd_list->VtxBuffer.front(); - const ImDrawIdx* idx_buffer = &cmd_list->IdxBuffer.front(); - glVertexPointer(2, GL_FLOAT, sizeof(ImDrawVert), (void*)(vtx_buffer + OFFSETOF(ImDrawVert, pos))); - glTexCoordPointer(2, GL_FLOAT, sizeof(ImDrawVert), (void*)(vtx_buffer + OFFSETOF(ImDrawVert, uv))); - glColorPointer(4, GL_UNSIGNED_BYTE, sizeof(ImDrawVert), (void*)(vtx_buffer + OFFSETOF(ImDrawVert, col))); - - for (int cmd_i = 0; cmd_i < cmd_list->CmdBuffer.size(); cmd_i++) - { - const ImDrawCmd* pcmd = &cmd_list->CmdBuffer[cmd_i]; - if (pcmd->UserCallback) - { - pcmd->UserCallback(cmd_list, pcmd); - } - else - { - glBindTexture(GL_TEXTURE_2D, (GLuint)(intptr_t)pcmd->TextureId); - glScissor((int)pcmd->ClipRect.x, (int)(fb_height - pcmd->ClipRect.w), (int)(pcmd->ClipRect.z - pcmd->ClipRect.x), (int)(pcmd->ClipRect.w - pcmd->ClipRect.y)); - glDrawElements(GL_TRIANGLES, (GLsizei)pcmd->ElemCount, sizeof(ImDrawIdx) == 2 ? GL_UNSIGNED_SHORT : GL_UNSIGNED_INT, idx_buffer); - } - idx_buffer += pcmd->ElemCount; - } - } - #undef OFFSETOF - - // Restore modified state - glDisableClientState(GL_COLOR_ARRAY); - glDisableClientState(GL_TEXTURE_COORD_ARRAY); - glDisableClientState(GL_VERTEX_ARRAY); - glBindTexture(GL_TEXTURE_2D, (GLuint)last_texture); - glMatrixMode(GL_MODELVIEW); - glPopMatrix(); - glMatrixMode(GL_PROJECTION); - glPopMatrix(); - glPopAttrib(); - glViewport(last_viewport[0], last_viewport[1], (GLsizei)last_viewport[2], (GLsizei)last_viewport[3]); -} - -static const char* ImGui_ImplGlfw_GetClipboardText() -{ - return glfwGetClipboardString(g_Window); -} - -static void ImGui_ImplGlfw_SetClipboardText(const char* text) -{ - glfwSetClipboardString(g_Window, text); -} - -void ImGui_ImplGlfw_MouseButtonCallback(GLFWwindow*, int button, int action, int /*mods*/) -{ - if (action == GLFW_PRESS && button >= 0 && button < 3) - g_MousePressed[button] = true; -} - -void ImGui_ImplGlfw_ScrollCallback(GLFWwindow*, double /*xoffset*/, double yoffset) -{ - g_MouseWheel += (float)yoffset; // Use fractional mouse wheel, 1.0 unit 5 lines. -} - -void ImGui_ImplGlFw_KeyCallback(GLFWwindow*, int key, int, int action, int mods) -{ - ImGuiIO& io = ImGui::GetIO(); - if (action == GLFW_PRESS) - io.KeysDown[key] = true; - if (action == GLFW_RELEASE) - io.KeysDown[key] = false; - - (void)mods; // Modifiers are not reliable across systems - io.KeyCtrl = io.KeysDown[GLFW_KEY_LEFT_CONTROL] || io.KeysDown[GLFW_KEY_RIGHT_CONTROL]; - io.KeyShift = io.KeysDown[GLFW_KEY_LEFT_SHIFT] || io.KeysDown[GLFW_KEY_RIGHT_SHIFT]; - io.KeyAlt = io.KeysDown[GLFW_KEY_LEFT_ALT] || io.KeysDown[GLFW_KEY_RIGHT_ALT]; - io.KeySuper = io.KeysDown[GLFW_KEY_LEFT_SUPER] || io.KeysDown[GLFW_KEY_RIGHT_SUPER]; -} - -void ImGui_ImplGlfw_CharCallback(GLFWwindow*, unsigned int c) -{ - ImGuiIO& io = ImGui::GetIO(); - if (c > 0 && c < 0x10000) - io.AddInputCharacter((unsigned short)c); -} - -bool ImGui_ImplGlfw_CreateDeviceObjects() -{ - // Build texture atlas - ImGuiIO& io = ImGui::GetIO(); - unsigned char* pixels; - int width, height; - io.Fonts->GetTexDataAsAlpha8(&pixels, &width, &height); - - // Upload texture to graphics system - GLint last_texture; - glGetIntegerv(GL_TEXTURE_BINDING_2D, &last_texture); - glGenTextures(1, &g_FontTexture); - glBindTexture(GL_TEXTURE_2D, g_FontTexture); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, width, height, 0, GL_ALPHA, GL_UNSIGNED_BYTE, pixels); - - // Store our identifier - io.Fonts->TexID = (void *)(intptr_t)g_FontTexture; - - // Restore state - glBindTexture(GL_TEXTURE_2D, last_texture); - - return true; -} - -void ImGui_ImplGlfw_InvalidateDeviceObjects() -{ - if (g_FontTexture) - { - glDeleteTextures(1, &g_FontTexture); - ImGui::GetIO().Fonts->TexID = 0; - g_FontTexture = 0; - } -} - -bool ImGui_ImplGlfw_Init(GLFWwindow* window, bool install_callbacks) -{ - g_Window = window; - - ImGuiIO& io = ImGui::GetIO(); - 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; - io.KeyMap[ImGuiKey_DownArrow] = GLFW_KEY_DOWN; - io.KeyMap[ImGuiKey_PageUp] = GLFW_KEY_PAGE_UP; - io.KeyMap[ImGuiKey_PageDown] = GLFW_KEY_PAGE_DOWN; - io.KeyMap[ImGuiKey_Home] = GLFW_KEY_HOME; - io.KeyMap[ImGuiKey_End] = GLFW_KEY_END; - io.KeyMap[ImGuiKey_Delete] = GLFW_KEY_DELETE; - io.KeyMap[ImGuiKey_Backspace] = GLFW_KEY_BACKSPACE; - io.KeyMap[ImGuiKey_Enter] = GLFW_KEY_ENTER; - io.KeyMap[ImGuiKey_Escape] = GLFW_KEY_ESCAPE; - io.KeyMap[ImGuiKey_A] = GLFW_KEY_A; - io.KeyMap[ImGuiKey_C] = GLFW_KEY_C; - io.KeyMap[ImGuiKey_V] = GLFW_KEY_V; - io.KeyMap[ImGuiKey_X] = GLFW_KEY_X; - io.KeyMap[ImGuiKey_Y] = GLFW_KEY_Y; - io.KeyMap[ImGuiKey_Z] = GLFW_KEY_Z; - - io.RenderDrawListsFn = ImGui_ImplGlfw_RenderDrawLists; // Alternatively you can set this to NULL and call ImGui::GetDrawData() after ImGui::Render() to get the same ImDrawData pointer. - io.SetClipboardTextFn = ImGui_ImplGlfw_SetClipboardText; - io.GetClipboardTextFn = ImGui_ImplGlfw_GetClipboardText; -#ifdef _WIN32 - io.ImeWindowHandle = glfwGetWin32Window(g_Window); -#endif - - if (install_callbacks) - { - glfwSetMouseButtonCallback(window, ImGui_ImplGlfw_MouseButtonCallback); - glfwSetScrollCallback(window, ImGui_ImplGlfw_ScrollCallback); - glfwSetKeyCallback(window, ImGui_ImplGlFw_KeyCallback); - glfwSetCharCallback(window, ImGui_ImplGlfw_CharCallback); - } - - return true; -} - -void ImGui_ImplGlfw_Shutdown() -{ - ImGui_ImplGlfw_InvalidateDeviceObjects(); - ImGui::Shutdown(); -} - -void ImGui_ImplGlfw_NewFrame() -{ - if (!g_FontTexture) - ImGui_ImplGlfw_CreateDeviceObjects(); - - ImGuiIO& io = ImGui::GetIO(); - - // Setup display size (every frame to accommodate for window resizing) - int w, h; - int display_w, display_h; - glfwGetWindowSize(g_Window, &w, &h); - glfwGetFramebufferSize(g_Window, &display_w, &display_h); - io.DisplaySize = ImVec2((float)w, (float)h); - io.DisplayFramebufferScale = ImVec2(w > 0 ? ((float)display_w / w) : 0, h > 0 ? ((float)display_h / h) : 0); - - // Setup time step - double current_time = glfwGetTime(); - io.DeltaTime = g_Time > 0.0 ? (float)(current_time - g_Time) : (float)(1.0f/60.0f); - g_Time = current_time; - - // Setup inputs - // (we already got mouse wheel, keyboard keys & characters from glfw callbacks polled in glfwPollEvents()) - if (glfwGetWindowAttrib(g_Window, GLFW_FOCUSED)) - { - double mouse_x, mouse_y; - glfwGetCursorPos(g_Window, &mouse_x, &mouse_y); - io.MousePos = ImVec2((float)mouse_x, (float)mouse_y); // Mouse position in screen coordinates (set to -1,-1 if no mouse / on another screen, etc.) - } - else - { - io.MousePos = ImVec2(-1,-1); - } - - for (int i = 0; i < 3; i++) - { - io.MouseDown[i] = g_MousePressed[i] || glfwGetMouseButton(g_Window, i) != 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. - g_MousePressed[i] = false; - } - - io.MouseWheel = g_MouseWheel; - g_MouseWheel = 0.0f; - - // Hide OS mouse cursor if ImGui is drawing it - glfwSetInputMode(g_Window, GLFW_CURSOR, io.MouseDrawCursor ? GLFW_CURSOR_HIDDEN : GLFW_CURSOR_NORMAL); - - // Start the frame - ImGui::NewFrame(); -} diff --git a/examples/opengl_example/imgui_impl_glfw.h b/examples/opengl_example/imgui_impl_glfw.h deleted file mode 100644 index 07dd96f..0000000 --- a/examples/opengl_example/imgui_impl_glfw.h +++ /dev/null @@ -1,29 +0,0 @@ -// ImGui GLFW binding with OpenGL -// In this binding, ImTextureID is used to store an OpenGL 'GLuint' texture identifier. Read the FAQ about ImTextureID in imgui.cpp. - -// If your context is GL3/GL3 then prefer using the code in opengl3_example. -// You *might* use this code with a GL3/GL4 context but make sure you disable the programmable pipeline by calling "glUseProgram(0)" before ImGui::Render(). -// We cannot do that from GL2 code because the function doesn't exist. - -// You can copy and use unmodified imgui_impl_* files in your project. See main.cpp for an example of using this. -// If you use this binding you'll need to call 4 functions: ImGui_ImplXXXX_Init(), ImGui_ImplXXXX_NewFrame(), ImGui::Render() and ImGui_ImplXXXX_Shutdown(). -// If you are new to ImGui, see examples/README.txt and documentation at the top of imgui.cpp. -// https://github.com/ocornut/imgui - -struct GLFWwindow; - -IMGUI_API bool ImGui_ImplGlfw_Init(GLFWwindow* window, bool install_callbacks); -IMGUI_API void ImGui_ImplGlfw_Shutdown(); -IMGUI_API void ImGui_ImplGlfw_NewFrame(); - -// Use if you want to reset your rendering device without losing ImGui state. -IMGUI_API void ImGui_ImplGlfw_InvalidateDeviceObjects(); -IMGUI_API bool ImGui_ImplGlfw_CreateDeviceObjects(); - -// GLFW callbacks (installed by default if you enable 'install_callbacks' during initialization) -// Provided here if you want to chain callbacks. -// You can also handle inputs yourself and use those as a reference. -IMGUI_API void ImGui_ImplGlfw_MouseButtonCallback(GLFWwindow* window, int button, int action, int mods); -IMGUI_API void ImGui_ImplGlfw_ScrollCallback(GLFWwindow* window, double xoffset, double yoffset); -IMGUI_API void ImGui_ImplGlFw_KeyCallback(GLFWwindow* window, int key, int scancode, int action, int mods); -IMGUI_API void ImGui_ImplGlfw_CharCallback(GLFWwindow* window, unsigned int c); diff --git a/examples/opengl_example/main.cpp b/examples/opengl_example/main.cpp deleted file mode 100644 index a844db5..0000000 --- a/examples/opengl_example/main.cpp +++ /dev/null @@ -1,89 +0,0 @@ -// ImGui - standalone example application for Glfw + OpenGL 2, using fixed pipeline -// If you are new to ImGui, see examples/README.txt and documentation at the top of imgui.cpp. - -#include -#include "imgui_impl_glfw.h" -#include -#include - -static void error_callback(int error, const char* description) -{ - fprintf(stderr, "Error %d: %s\n", error, description); -} - -int main(int, char**) -{ - // Setup window - glfwSetErrorCallback(error_callback); - if (!glfwInit()) - return 1; - GLFWwindow* window = glfwCreateWindow(1280, 720, "ImGui OpenGL2 example", NULL, NULL); - glfwMakeContextCurrent(window); - - // Setup ImGui binding - ImGui_ImplGlfw_Init(window, true); - - // Load Fonts - // (there is a default font, this is only if you want to change it. see extra_fonts/README.txt for more details) - //ImGuiIO& io = ImGui::GetIO(); - //io.Fonts->AddFontDefault(); - //io.Fonts->AddFontFromFileTTF("../../extra_fonts/Cousine-Regular.ttf", 15.0f); - //io.Fonts->AddFontFromFileTTF("../../extra_fonts/DroidSans.ttf", 16.0f); - //io.Fonts->AddFontFromFileTTF("../../extra_fonts/ProggyClean.ttf", 13.0f); - //io.Fonts->AddFontFromFileTTF("../../extra_fonts/ProggyTiny.ttf", 10.0f); - //io.Fonts->AddFontFromFileTTF("c:\\Windows\\Fonts\\ArialUni.ttf", 18.0f, NULL, io.Fonts->GetGlyphRangesJapanese()); - - bool show_test_window = true; - bool show_another_window = false; - ImVec4 clear_color = ImColor(114, 144, 154); - - // Main loop - while (!glfwWindowShouldClose(window)) - { - glfwPollEvents(); - ImGui_ImplGlfw_NewFrame(); - - // 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 = 0.0f; - ImGui::Text("Hello, world!"); - ImGui::SliderFloat("float", &f, 0.0f, 1.0f); - ImGui::ColorEdit3("clear color", (float*)&clear_color); - if (ImGui::Button("Test Window")) show_test_window ^= 1; - if (ImGui::Button("Another Window")) show_another_window ^= 1; - ImGui::Text("Application average %.3f ms/frame (%.1f FPS)", 1000.0f / ImGui::GetIO().Framerate, ImGui::GetIO().Framerate); - } - - // 2. Show another simple window, this time using an explicit Begin/End pair - if (show_another_window) - { - ImGui::SetNextWindowSize(ImVec2(200,100), ImGuiSetCond_FirstUseEver); - ImGui::Begin("Another Window", &show_another_window); - 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::SetNextWindowPos(ImVec2(650, 20), ImGuiSetCond_FirstUseEver); - ImGui::ShowTestWindow(&show_test_window); - } - - // Rendering - int display_w, display_h; - glfwGetFramebufferSize(window, &display_w, &display_h); - glViewport(0, 0, display_w, display_h); - glClearColor(clear_color.x, clear_color.y, clear_color.z, clear_color.w); - glClear(GL_COLOR_BUFFER_BIT); - ImGui::Render(); - glfwSwapBuffers(window); - } - - // Cleanup - ImGui_ImplGlfw_Shutdown(); - glfwTerminate(); - - return 0; -} diff --git a/examples/opengl_example/opengl_example.vcxproj b/examples/opengl_example/opengl_example.vcxproj deleted file mode 100644 index 4b354b6..0000000 --- a/examples/opengl_example/opengl_example.vcxproj +++ /dev/null @@ -1,169 +0,0 @@ - - - - - Debug - Win32 - - - Debug - x64 - - - Release - Win32 - - - Release - x64 - - - - {9CDA7840-B7A5-496D-A527-E95571496D18} - opengl_example - - - - Application - true - MultiByte - - - Application - true - MultiByte - - - Application - false - true - MultiByte - - - Application - false - true - MultiByte - - - - - - - - - - - - - - - - - - - $(ProjectDir)$(Configuration)\ - $(ProjectDir)$(Configuration)\ - $(IncludePath) - - - $(ProjectDir)$(Configuration)\ - $(ProjectDir)$(Configuration)\ - $(IncludePath) - - - $(ProjectDir)$(Configuration)\ - $(ProjectDir)$(Configuration)\ - $(IncludePath) - - - $(ProjectDir)$(Configuration)\ - $(ProjectDir)$(Configuration)\ - $(IncludePath) - - - - Level4 - Disabled - $(SolutionDir)\libs\glfw\include;..\..;%(AdditionalIncludeDirectories) - - - true - $(SolutionDir)\libs\glfw\lib-vc2010-32;%(AdditionalLibraryDirectories) - opengl32.lib;glfw3.lib;%(AdditionalDependencies) - Console - msvcrt.lib - - - - - Level4 - Disabled - $(SolutionDir)\libs\glfw\include;..\..;%(AdditionalIncludeDirectories) - - - true - $(SolutionDir)\libs\glfw\lib-vc2010-64;%(AdditionalLibraryDirectories) - opengl32.lib;glfw3.lib;%(AdditionalDependencies) - Console - msvcrt.lib - - - - - Level4 - MaxSpeed - true - true - $(SolutionDir)\libs\glfw\include;..\..;%(AdditionalIncludeDirectories) - - - true - true - true - $(SolutionDir)\libs\glfw\lib-vc2010-32;%(AdditionalLibraryDirectories) - opengl32.lib;glfw3.lib;%(AdditionalDependencies) - Console - - - - - - - Level4 - MaxSpeed - true - true - $(SolutionDir)\libs\glfw\include;..\..;%(AdditionalIncludeDirectories) - - - true - true - true - $(SolutionDir)\libs\glfw\lib-vc2010-64;%(AdditionalLibraryDirectories) - opengl32.lib;glfw3.lib;%(AdditionalDependencies) - Console - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/examples/opengl_example/opengl_example.vcxproj.filters b/examples/opengl_example/opengl_example.vcxproj.filters deleted file mode 100644 index f2282bf..0000000 --- a/examples/opengl_example/opengl_example.vcxproj.filters +++ /dev/null @@ -1,46 +0,0 @@ - - - - - {c336cfe3-f0c4-464c-9ef0-a9e17a7ff222} - - - {4FC737F1-C7A5-4376-A066-2A32D752A2FF} - cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx - - - - - sources - - - imgui - - - sources - - - imgui - - - imgui - - - - - imgui - - - imgui - - - sources - - - imgui - - - - - - \ No newline at end of file diff --git a/examples/sdl_opengl2_example/README.md b/examples/sdl_opengl2_example/README.md new file mode 100644 index 0000000..aada45d --- /dev/null +++ b/examples/sdl_opengl2_example/README.md @@ -0,0 +1,22 @@ + +# How to Build + +- On Windows with Visual Studio's CLI + +``` +set SDL2DIR=path_to_your_sdl2_folder +cl /Zi /MD /I %SDL2DIR%\include> /I ..\.. main.cpp imgui_impl_sdl.cpp ..\..\imgui*.cpp /link /LIBPATH:%SDL2DIR%\lib SDL2.lib SDL2main.lib +``` + +- On Linux and similar Unixes + +``` +c++ `sdl2-config --cflags` -I ../.. main.cpp imgui_impl_sdl.cpp ../../imgui*.cpp `sdl2-config --libs` -lGL -o sdl2example +``` + +- On Mac OS X + +``` +brew install sdl2 +c++ `sdl2-config --cflags` -I ../.. main.cpp imgui_impl_sdl.cpp ../../imgui*.cpp `sdl2-config --libs` -framework OpenGl -o sdl2example +``` diff --git a/examples/sdl_opengl2_example/imgui_impl_sdl.cpp b/examples/sdl_opengl2_example/imgui_impl_sdl.cpp new file mode 100644 index 0000000..63ed9f4 --- /dev/null +++ b/examples/sdl_opengl2_example/imgui_impl_sdl.cpp @@ -0,0 +1,277 @@ +// ImGui SDL2 binding with OpenGL +// In this binding, ImTextureID is used to store an OpenGL 'GLuint' texture identifier. Read the FAQ about ImTextureID in imgui.cpp. + +// You can copy and use unmodified imgui_impl_* files in your project. See main.cpp for an example of using this. +// If you use this binding you'll need to call 4 functions: ImGui_ImplXXXX_Init(), ImGui_ImplXXXX_NewFrame(), ImGui::Render() and ImGui_ImplXXXX_Shutdown(). +// If you are new to ImGui, see examples/README.txt and documentation at the top of imgui.cpp. +// https://github.com/ocornut/imgui + +#include +#include +#include +#include +#include "imgui_impl_sdl.h" + +// Data +static double g_Time = 0.0f; +static bool g_MousePressed[3] = { false, false, false }; +static float g_MouseWheel = 0.0f; +static GLuint g_FontTexture = 0; + +// 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) +void ImGui_ImplSdl_RenderDrawLists(ImDrawData* draw_data) +{ + // Avoid rendering when minimized, scale coordinates for retina displays (screen coordinates != framebuffer coordinates) + ImGuiIO& io = ImGui::GetIO(); + int fb_width = (int)(io.DisplaySize.x * io.DisplayFramebufferScale.x); + int fb_height = (int)(io.DisplaySize.y * io.DisplayFramebufferScale.y); + if (fb_width == 0 || fb_height == 0) + return; + draw_data->ScaleClipRects(io.DisplayFramebufferScale); + + // We are using the OpenGL fixed pipeline to make the example code simpler to read! + // Setup render state: alpha-blending enabled, no face culling, no depth testing, scissor enabled, vertex/texcoord/color pointers. + GLint last_texture; glGetIntegerv(GL_TEXTURE_BINDING_2D, &last_texture); + GLint last_viewport[4]; glGetIntegerv(GL_VIEWPORT, last_viewport); + glPushAttrib(GL_ENABLE_BIT | GL_COLOR_BUFFER_BIT | GL_TRANSFORM_BIT); + glEnable(GL_BLEND); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + glDisable(GL_CULL_FACE); + glDisable(GL_DEPTH_TEST); + glEnable(GL_SCISSOR_TEST); + glEnableClientState(GL_VERTEX_ARRAY); + glEnableClientState(GL_TEXTURE_COORD_ARRAY); + glEnableClientState(GL_COLOR_ARRAY); + glEnable(GL_TEXTURE_2D); + //glUseProgram(0); // You may want this if using this code in an OpenGL 3+ context + + // Setup viewport, orthographic projection matrix + glViewport(0, 0, (GLsizei)fb_width, (GLsizei)fb_height); + glMatrixMode(GL_PROJECTION); + glPushMatrix(); + glLoadIdentity(); + glOrtho(0.0f, io.DisplaySize.x, io.DisplaySize.y, 0.0f, -1.0f, +1.0f); + glMatrixMode(GL_MODELVIEW); + glPushMatrix(); + glLoadIdentity(); + + // Render command lists + #define OFFSETOF(TYPE, ELEMENT) ((size_t)&(((TYPE *)0)->ELEMENT)) + for (int n = 0; n < draw_data->CmdListsCount; n++) + { + const ImDrawList* cmd_list = draw_data->CmdLists[n]; + const unsigned char* vtx_buffer = (const unsigned char*)&cmd_list->VtxBuffer.front(); + const ImDrawIdx* idx_buffer = &cmd_list->IdxBuffer.front(); + glVertexPointer(2, GL_FLOAT, sizeof(ImDrawVert), (void*)(vtx_buffer + OFFSETOF(ImDrawVert, pos))); + glTexCoordPointer(2, GL_FLOAT, sizeof(ImDrawVert), (void*)(vtx_buffer + OFFSETOF(ImDrawVert, uv))); + glColorPointer(4, GL_UNSIGNED_BYTE, sizeof(ImDrawVert), (void*)(vtx_buffer + OFFSETOF(ImDrawVert, col))); + + for (int cmd_i = 0; cmd_i < cmd_list->CmdBuffer.size(); cmd_i++) + { + const ImDrawCmd* pcmd = &cmd_list->CmdBuffer[cmd_i]; + if (pcmd->UserCallback) + { + pcmd->UserCallback(cmd_list, pcmd); + } + else + { + glBindTexture(GL_TEXTURE_2D, (GLuint)(intptr_t)pcmd->TextureId); + glScissor((int)pcmd->ClipRect.x, (int)(fb_height - pcmd->ClipRect.w), (int)(pcmd->ClipRect.z - pcmd->ClipRect.x), (int)(pcmd->ClipRect.w - pcmd->ClipRect.y)); + glDrawElements(GL_TRIANGLES, (GLsizei)pcmd->ElemCount, sizeof(ImDrawIdx) == 2 ? GL_UNSIGNED_SHORT : GL_UNSIGNED_INT, idx_buffer); + } + idx_buffer += pcmd->ElemCount; + } + } + #undef OFFSETOF + + // Restore modified state + glDisableClientState(GL_COLOR_ARRAY); + glDisableClientState(GL_TEXTURE_COORD_ARRAY); + glDisableClientState(GL_VERTEX_ARRAY); + glBindTexture(GL_TEXTURE_2D, (GLuint)last_texture); + glMatrixMode(GL_MODELVIEW); + glPopMatrix(); + glMatrixMode(GL_PROJECTION); + glPopMatrix(); + glPopAttrib(); + glViewport(last_viewport[0], last_viewport[1], (GLsizei)last_viewport[2], (GLsizei)last_viewport[3]); +} + +static const char* ImGui_ImplSdl_GetClipboardText() +{ + return SDL_GetClipboardText(); +} + +static void ImGui_ImplSdl_SetClipboardText(const char* text) +{ + SDL_SetClipboardText(text); +} + +bool ImGui_ImplSdl_ProcessEvent(SDL_Event* event) +{ + ImGuiIO& io = ImGui::GetIO(); + switch (event->type) + { + case SDL_MOUSEWHEEL: + { + if (event->wheel.y > 0) + g_MouseWheel = 1; + if (event->wheel.y < 0) + g_MouseWheel = -1; + return true; + } + case SDL_MOUSEBUTTONDOWN: + { + if (event->button.button == SDL_BUTTON_LEFT) g_MousePressed[0] = true; + if (event->button.button == SDL_BUTTON_RIGHT) g_MousePressed[1] = true; + if (event->button.button == SDL_BUTTON_MIDDLE) g_MousePressed[2] = true; + return true; + } + case SDL_TEXTINPUT: + { + io.AddInputCharactersUTF8(event->text.text); + return true; + } + case SDL_KEYDOWN: + case SDL_KEYUP: + { + int key = event->key.keysym.sym & ~SDLK_SCANCODE_MASK; + io.KeysDown[key] = (event->type == SDL_KEYDOWN); + io.KeyShift = ((SDL_GetModState() & KMOD_SHIFT) != 0); + io.KeyCtrl = ((SDL_GetModState() & KMOD_CTRL) != 0); + io.KeyAlt = ((SDL_GetModState() & KMOD_ALT) != 0); + io.KeySuper = ((SDL_GetModState() & KMOD_GUI) != 0); + return true; + } + } + return false; +} + +bool ImGui_ImplSdl_CreateDeviceObjects() +{ + // Build texture atlas + ImGuiIO& io = ImGui::GetIO(); + unsigned char* pixels; + int width, height; + io.Fonts->GetTexDataAsAlpha8(&pixels, &width, &height); + + // Upload texture to graphics system + GLint last_texture; + glGetIntegerv(GL_TEXTURE_BINDING_2D, &last_texture); + glGenTextures(1, &g_FontTexture); + glBindTexture(GL_TEXTURE_2D, g_FontTexture); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glPixelStorei(GL_UNPACK_ROW_LENGTH, 0); + glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, width, height, 0, GL_ALPHA, GL_UNSIGNED_BYTE, pixels); + + // Store our identifier + io.Fonts->TexID = (void *)(intptr_t)g_FontTexture; + + // Restore state + glBindTexture(GL_TEXTURE_2D, last_texture); + + return true; +} + +void ImGui_ImplSdl_InvalidateDeviceObjects() +{ + if (g_FontTexture) + { + glDeleteTextures(1, &g_FontTexture); + ImGui::GetIO().Fonts->TexID = 0; + g_FontTexture = 0; + } +} + +bool ImGui_ImplSdl_Init(SDL_Window* window) +{ + ImGuiIO& io = ImGui::GetIO(); + io.KeyMap[ImGuiKey_Tab] = SDLK_TAB; // Keyboard mapping. ImGui will use those indices to peek into the io.KeyDown[] array. + io.KeyMap[ImGuiKey_LeftArrow] = SDL_SCANCODE_LEFT; + io.KeyMap[ImGuiKey_RightArrow] = SDL_SCANCODE_RIGHT; + io.KeyMap[ImGuiKey_UpArrow] = SDL_SCANCODE_UP; + io.KeyMap[ImGuiKey_DownArrow] = SDL_SCANCODE_DOWN; + io.KeyMap[ImGuiKey_PageUp] = SDL_SCANCODE_PAGEUP; + io.KeyMap[ImGuiKey_PageDown] = SDL_SCANCODE_PAGEDOWN; + io.KeyMap[ImGuiKey_Home] = SDL_SCANCODE_HOME; + io.KeyMap[ImGuiKey_End] = SDL_SCANCODE_END; + io.KeyMap[ImGuiKey_Delete] = SDLK_DELETE; + io.KeyMap[ImGuiKey_Backspace] = SDLK_BACKSPACE; + io.KeyMap[ImGuiKey_Enter] = SDLK_RETURN; + io.KeyMap[ImGuiKey_Escape] = SDLK_ESCAPE; + io.KeyMap[ImGuiKey_A] = SDLK_a; + io.KeyMap[ImGuiKey_C] = SDLK_c; + io.KeyMap[ImGuiKey_V] = SDLK_v; + io.KeyMap[ImGuiKey_X] = SDLK_x; + io.KeyMap[ImGuiKey_Y] = SDLK_y; + io.KeyMap[ImGuiKey_Z] = SDLK_z; + + io.RenderDrawListsFn = ImGui_ImplSdl_RenderDrawLists; // Alternatively you can set this to NULL and call ImGui::GetDrawData() after ImGui::Render() to get the same ImDrawData pointer. + io.SetClipboardTextFn = ImGui_ImplSdl_SetClipboardText; + io.GetClipboardTextFn = ImGui_ImplSdl_GetClipboardText; + +#ifdef _WIN32 + SDL_SysWMinfo wmInfo; + SDL_VERSION(&wmInfo.version); + SDL_GetWindowWMInfo(window, &wmInfo); + io.ImeWindowHandle = wmInfo.info.win.window; +#else + (void)window; +#endif + + return true; +} + +void ImGui_ImplSdl_Shutdown() +{ + ImGui_ImplSdl_InvalidateDeviceObjects(); + ImGui::Shutdown(); +} + +void ImGui_ImplSdl_NewFrame(SDL_Window *window) +{ + if (!g_FontTexture) + ImGui_ImplSdl_CreateDeviceObjects(); + + ImGuiIO& io = ImGui::GetIO(); + + // Setup display size (every frame to accommodate for window resizing) + int w, h; + int display_w, display_h; + SDL_GetWindowSize(window, &w, &h); + SDL_GL_GetDrawableSize(window, &display_w, &display_h); + io.DisplaySize = ImVec2((float)w, (float)h); + io.DisplayFramebufferScale = ImVec2(w > 0 ? ((float)display_w / w) : 0, h > 0 ? ((float)display_h / h) : 0); + + // Setup time step + Uint32 time = SDL_GetTicks(); + double current_time = time / 1000.0; + io.DeltaTime = g_Time > 0.0 ? (float)(current_time - g_Time) : (float)(1.0f/60.0f); + g_Time = current_time; + + // Setup inputs + // (we already got mouse wheel, keyboard keys & characters from SDL_PollEvent()) + int mx, my; + Uint32 mouseMask = SDL_GetMouseState(&mx, &my); + if (SDL_GetWindowFlags(window) & SDL_WINDOW_MOUSE_FOCUS) + io.MousePos = ImVec2((float)mx, (float)my); // Mouse position, in pixels (set to -1,-1 if no mouse / on another screen, etc.) + else + io.MousePos = ImVec2(-1,-1); + + io.MouseDown[0] = g_MousePressed[0] || (mouseMask & SDL_BUTTON(SDL_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] = g_MousePressed[1] || (mouseMask & SDL_BUTTON(SDL_BUTTON_RIGHT)) != 0; + io.MouseDown[2] = g_MousePressed[2] || (mouseMask & SDL_BUTTON(SDL_BUTTON_MIDDLE)) != 0; + g_MousePressed[0] = g_MousePressed[1] = g_MousePressed[2] = false; + + io.MouseWheel = g_MouseWheel; + g_MouseWheel = 0.0f; + + // Hide OS mouse cursor if ImGui is drawing it + SDL_ShowCursor(io.MouseDrawCursor ? 0 : 1); + + // Start the frame + ImGui::NewFrame(); +} diff --git a/examples/README.txt b/examples/README.txt index df2e86d..5a1c8df 100644 --- a/examples/README.txt +++ b/examples/README.txt @@ -8,11 +8,13 @@ TL;DR; - Newcomers, read 'PROGRAMMER GUIDE' in imgui.cpp for notes on how to setup ImGui in your codebase. - - Refer to 'opengl_example' to understand how the library is setup, it is the simplest one. + - Refer to 'opengl2_example' to LEARN how the library is setup, it is the simplest one. The other examples requires more boilerplate and are harder to read. + - If you are using OpenGL in your application, probably use an opengl3_xxx backend. + Mixing old fixed pipeline OpenGL2 and programmable pipeline OpenGL3+ isn't well supported by drivers. - If you are using of the backend provided here, so you can copy the imgui_impl_xxx.cpp/h files to your project and use them unmodified. - - If you have your own engine, you probably want to start from 'opengl_example' and adapt it to + - If you have your own engine, you probably want to start from one of the OpenGL example and adapt it to your engine, but you can read the other examples as well. ImGui is highly portable and only requires a few things to run: @@ -41,15 +43,14 @@ Also note that some setup or GPU drivers may be causing extra lag (possibly by enforcing triple buffering), leaving you with no option but sadness/anger (Intel GPU drivers were reported as such). -opengl_example/ - OpenGL example, using GLFW + fixed pipeline. - This is simple and should work for all OpenGL enabled applications. - Prefer following this example to learn how ImGui works! - (You can use this code in a GL3/GL4 context but make sure you disable the programmable pipeline - by calling "glUseProgram(0)" before ImGui::Render.) +opengl2_example/ + GLFW + OpenGL example (old fixed pipeline). + This is simple to read. Prefer following this example to learn how ImGui works! + (You might be able to use this code in a GL3/GL4 context but make sure you disable the programmable + pipeline by calling "glUseProgram(0)" before ImGui::Render.) opengl3_example/ - OpenGL example, using GLFW/GL3W + programmable pipeline. + GLFW + OpenGL example (programmable pipeline, binding modern functions with GL3W). This uses more modern OpenGL calls and custom shaders. It's more messy. directx9_example/ @@ -68,8 +69,8 @@ On iOS, Using Synergy to access keyboard/mouse data from server computer. Synergy keyboard integration is rather hacky. -sdl_opengl_example/ - SDL2 + OpenGL example. +sdl_opengl2_example/ + SDL2 + OpenGL example (old fixed pipeline). sdl_opengl3_example/ SDL2 + OpenGL3 example. diff --git a/examples/imgui_examples_msvc2010.sln b/examples/imgui_examples_msvc2010.sln index b7e6a25..16f0d60 100644 --- a/examples/imgui_examples_msvc2010.sln +++ b/examples/imgui_examples_msvc2010.sln @@ -1,7 +1,7 @@  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}" +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "opengl2_example", "opengl_example\opengl2_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 diff --git a/examples/opengl2_example/Makefile b/examples/opengl2_example/Makefile new file mode 100644 index 0000000..bd79d1b --- /dev/null +++ b/examples/opengl2_example/Makefile @@ -0,0 +1,60 @@ +# +# Cross Platform Makefile +# Compatible with Ubuntu 14.04.1 and Mac OS X +# +# +# if you using Mac OS X: +# You'll need glfw +# http://www.glfw.org +# + +#CXX = g++ + +EXE = opengl2_example +OBJS = main.o imgui_impl_glfw.o +OBJS += ../../imgui.o ../../imgui_demo.o ../../imgui_draw.o + +UNAME_S := $(shell uname -s) + + +ifeq ($(UNAME_S), Linux) #LINUX + ECHO_MESSAGE = "Linux" + LIBS = -lGL `pkg-config --static --libs glfw3` + + CXXFLAGS = -I../../ `pkg-config --cflags glfw3` + CXXFLAGS += -Wall -Wformat + CFLAGS = $(CXXFLAGS) +endif + +ifeq ($(UNAME_S), Darwin) #APPLE + ECHO_MESSAGE = "Mac OS X" + LIBS = -framework OpenGL -framework Cocoa -framework IOKit -framework CoreVideo + LIBS += -L/usr/local/lib -lglfw3 + + CXXFLAGS = -I../../ -I/usr/local/include + CXXFLAGS += -Wall -Wformat +# CXXFLAGS += -D__APPLE__ + CFLAGS = $(CXXFLAGS) +endif + +ifeq ($(UNAME_S), MINGW64_NT-6.3) + ECHO_MESSAGE = "Windows" + LIBS = -lglfw3 -lgdi32 -lopengl32 -limm32 + + CXXFLAGS = -I../../ -I../libs/gl3w `pkg-config --cflags glfw3` + CXXFLAGS += -Wall -Wformat + CFLAGS = $(CXXFLAGS) +endif + +.cpp.o: + $(CXX) $(CXXFLAGS) -c -o $@ $< + +all: $(EXE) + @echo Build complete for $(ECHO_MESSAGE) + +$(EXE): $(OBJS) + $(CXX) -o $(EXE) $(OBJS) $(CXXFLAGS) $(LIBS) + +clean: + rm $(EXE) $(OBJS) + diff --git a/examples/opengl2_example/build_win32.bat b/examples/opengl2_example/build_win32.bat new file mode 100644 index 0000000..278381c --- /dev/null +++ b/examples/opengl2_example/build_win32.bat @@ -0,0 +1,3 @@ +@REM Build for Visual Studio compiler. Run your copy of vcvars32.bat or vcvarsall.bat to setup command-line compiler. +mkdir Debug +cl /nologo /Zi /MD /I ..\.. /I ..\libs\glfw\include *.cpp ..\..\*.cpp /FeDebug/opengl_example.exe /FoDebug/ /link /LIBPATH:..\libs\glfw\lib-vc2010-32 glfw3.lib opengl32.lib gdi32.lib shell32.lib diff --git a/examples/opengl2_example/imgui_impl_glfw.cpp b/examples/opengl2_example/imgui_impl_glfw.cpp new file mode 100644 index 0000000..2d1f5c1 --- /dev/null +++ b/examples/opengl2_example/imgui_impl_glfw.cpp @@ -0,0 +1,288 @@ +// ImGui GLFW binding with OpenGL +// In this binding, ImTextureID is used to store an OpenGL 'GLuint' texture identifier. Read the FAQ about ImTextureID in imgui.cpp. + +// If your context is GL3/GL3 then prefer using the code in opengl3_example. +// You *might* use this code with a GL3/GL4 context but make sure you disable the programmable pipeline by calling "glUseProgram(0)" before ImGui::Render(). +// We cannot do that from GL2 code because the function doesn't exist. + +// You can copy and use unmodified imgui_impl_* files in your project. See main.cpp for an example of using this. +// If you use this binding you'll need to call 4 functions: ImGui_ImplXXXX_Init(), ImGui_ImplXXXX_NewFrame(), ImGui::Render() and ImGui_ImplXXXX_Shutdown(). +// If you are new to ImGui, see examples/README.txt and documentation at the top of imgui.cpp. +// https://github.com/ocornut/imgui + +#include +#include "imgui_impl_glfw.h" + +// GLFW +#include +#ifdef _WIN32 +#undef APIENTRY +#define GLFW_EXPOSE_NATIVE_WIN32 +#define GLFW_EXPOSE_NATIVE_WGL +#include +#endif + +// Data +static GLFWwindow* g_Window = NULL; +static double g_Time = 0.0f; +static bool g_MousePressed[3] = { false, false, false }; +static float g_MouseWheel = 0.0f; +static GLuint g_FontTexture = 0; + +// 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) +void ImGui_ImplGlfw_RenderDrawLists(ImDrawData* draw_data) +{ + // Avoid rendering when minimized, scale coordinates for retina displays (screen coordinates != framebuffer coordinates) + ImGuiIO& io = ImGui::GetIO(); + int fb_width = (int)(io.DisplaySize.x * io.DisplayFramebufferScale.x); + int fb_height = (int)(io.DisplaySize.y * io.DisplayFramebufferScale.y); + if (fb_width == 0 || fb_height == 0) + return; + draw_data->ScaleClipRects(io.DisplayFramebufferScale); + + // We are using the OpenGL fixed pipeline to make the example code simpler to read! + // Setup render state: alpha-blending enabled, no face culling, no depth testing, scissor enabled, vertex/texcoord/color pointers. + GLint last_texture; glGetIntegerv(GL_TEXTURE_BINDING_2D, &last_texture); + GLint last_viewport[4]; glGetIntegerv(GL_VIEWPORT, last_viewport); + glPushAttrib(GL_ENABLE_BIT | GL_COLOR_BUFFER_BIT | GL_TRANSFORM_BIT); + glEnable(GL_BLEND); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + glDisable(GL_CULL_FACE); + glDisable(GL_DEPTH_TEST); + glEnable(GL_SCISSOR_TEST); + glEnableClientState(GL_VERTEX_ARRAY); + glEnableClientState(GL_TEXTURE_COORD_ARRAY); + glEnableClientState(GL_COLOR_ARRAY); + glEnable(GL_TEXTURE_2D); + //glUseProgram(0); // You may want this if using this code in an OpenGL 3+ context + + // Setup viewport, orthographic projection matrix + glViewport(0, 0, (GLsizei)fb_width, (GLsizei)fb_height); + glMatrixMode(GL_PROJECTION); + glPushMatrix(); + glLoadIdentity(); + glOrtho(0.0f, io.DisplaySize.x, io.DisplaySize.y, 0.0f, -1.0f, +1.0f); + glMatrixMode(GL_MODELVIEW); + glPushMatrix(); + glLoadIdentity(); + + // Render command lists + #define OFFSETOF(TYPE, ELEMENT) ((size_t)&(((TYPE *)0)->ELEMENT)) + for (int n = 0; n < draw_data->CmdListsCount; n++) + { + const ImDrawList* cmd_list = draw_data->CmdLists[n]; + const unsigned char* vtx_buffer = (const unsigned char*)&cmd_list->VtxBuffer.front(); + const ImDrawIdx* idx_buffer = &cmd_list->IdxBuffer.front(); + glVertexPointer(2, GL_FLOAT, sizeof(ImDrawVert), (void*)(vtx_buffer + OFFSETOF(ImDrawVert, pos))); + glTexCoordPointer(2, GL_FLOAT, sizeof(ImDrawVert), (void*)(vtx_buffer + OFFSETOF(ImDrawVert, uv))); + glColorPointer(4, GL_UNSIGNED_BYTE, sizeof(ImDrawVert), (void*)(vtx_buffer + OFFSETOF(ImDrawVert, col))); + + for (int cmd_i = 0; cmd_i < cmd_list->CmdBuffer.size(); cmd_i++) + { + const ImDrawCmd* pcmd = &cmd_list->CmdBuffer[cmd_i]; + if (pcmd->UserCallback) + { + pcmd->UserCallback(cmd_list, pcmd); + } + else + { + glBindTexture(GL_TEXTURE_2D, (GLuint)(intptr_t)pcmd->TextureId); + glScissor((int)pcmd->ClipRect.x, (int)(fb_height - pcmd->ClipRect.w), (int)(pcmd->ClipRect.z - pcmd->ClipRect.x), (int)(pcmd->ClipRect.w - pcmd->ClipRect.y)); + glDrawElements(GL_TRIANGLES, (GLsizei)pcmd->ElemCount, sizeof(ImDrawIdx) == 2 ? GL_UNSIGNED_SHORT : GL_UNSIGNED_INT, idx_buffer); + } + idx_buffer += pcmd->ElemCount; + } + } + #undef OFFSETOF + + // Restore modified state + glDisableClientState(GL_COLOR_ARRAY); + glDisableClientState(GL_TEXTURE_COORD_ARRAY); + glDisableClientState(GL_VERTEX_ARRAY); + glBindTexture(GL_TEXTURE_2D, (GLuint)last_texture); + glMatrixMode(GL_MODELVIEW); + glPopMatrix(); + glMatrixMode(GL_PROJECTION); + glPopMatrix(); + glPopAttrib(); + glViewport(last_viewport[0], last_viewport[1], (GLsizei)last_viewport[2], (GLsizei)last_viewport[3]); +} + +static const char* ImGui_ImplGlfw_GetClipboardText() +{ + return glfwGetClipboardString(g_Window); +} + +static void ImGui_ImplGlfw_SetClipboardText(const char* text) +{ + glfwSetClipboardString(g_Window, text); +} + +void ImGui_ImplGlfw_MouseButtonCallback(GLFWwindow*, int button, int action, int /*mods*/) +{ + if (action == GLFW_PRESS && button >= 0 && button < 3) + g_MousePressed[button] = true; +} + +void ImGui_ImplGlfw_ScrollCallback(GLFWwindow*, double /*xoffset*/, double yoffset) +{ + g_MouseWheel += (float)yoffset; // Use fractional mouse wheel, 1.0 unit 5 lines. +} + +void ImGui_ImplGlFw_KeyCallback(GLFWwindow*, int key, int, int action, int mods) +{ + ImGuiIO& io = ImGui::GetIO(); + if (action == GLFW_PRESS) + io.KeysDown[key] = true; + if (action == GLFW_RELEASE) + io.KeysDown[key] = false; + + (void)mods; // Modifiers are not reliable across systems + io.KeyCtrl = io.KeysDown[GLFW_KEY_LEFT_CONTROL] || io.KeysDown[GLFW_KEY_RIGHT_CONTROL]; + io.KeyShift = io.KeysDown[GLFW_KEY_LEFT_SHIFT] || io.KeysDown[GLFW_KEY_RIGHT_SHIFT]; + io.KeyAlt = io.KeysDown[GLFW_KEY_LEFT_ALT] || io.KeysDown[GLFW_KEY_RIGHT_ALT]; + io.KeySuper = io.KeysDown[GLFW_KEY_LEFT_SUPER] || io.KeysDown[GLFW_KEY_RIGHT_SUPER]; +} + +void ImGui_ImplGlfw_CharCallback(GLFWwindow*, unsigned int c) +{ + ImGuiIO& io = ImGui::GetIO(); + if (c > 0 && c < 0x10000) + io.AddInputCharacter((unsigned short)c); +} + +bool ImGui_ImplGlfw_CreateDeviceObjects() +{ + // Build texture atlas + ImGuiIO& io = ImGui::GetIO(); + unsigned char* pixels; + int width, height; + io.Fonts->GetTexDataAsAlpha8(&pixels, &width, &height); + + // Upload texture to graphics system + GLint last_texture; + glGetIntegerv(GL_TEXTURE_BINDING_2D, &last_texture); + glGenTextures(1, &g_FontTexture); + glBindTexture(GL_TEXTURE_2D, g_FontTexture); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, width, height, 0, GL_ALPHA, GL_UNSIGNED_BYTE, pixels); + + // Store our identifier + io.Fonts->TexID = (void *)(intptr_t)g_FontTexture; + + // Restore state + glBindTexture(GL_TEXTURE_2D, last_texture); + + return true; +} + +void ImGui_ImplGlfw_InvalidateDeviceObjects() +{ + if (g_FontTexture) + { + glDeleteTextures(1, &g_FontTexture); + ImGui::GetIO().Fonts->TexID = 0; + g_FontTexture = 0; + } +} + +bool ImGui_ImplGlfw_Init(GLFWwindow* window, bool install_callbacks) +{ + g_Window = window; + + ImGuiIO& io = ImGui::GetIO(); + 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; + io.KeyMap[ImGuiKey_DownArrow] = GLFW_KEY_DOWN; + io.KeyMap[ImGuiKey_PageUp] = GLFW_KEY_PAGE_UP; + io.KeyMap[ImGuiKey_PageDown] = GLFW_KEY_PAGE_DOWN; + io.KeyMap[ImGuiKey_Home] = GLFW_KEY_HOME; + io.KeyMap[ImGuiKey_End] = GLFW_KEY_END; + io.KeyMap[ImGuiKey_Delete] = GLFW_KEY_DELETE; + io.KeyMap[ImGuiKey_Backspace] = GLFW_KEY_BACKSPACE; + io.KeyMap[ImGuiKey_Enter] = GLFW_KEY_ENTER; + io.KeyMap[ImGuiKey_Escape] = GLFW_KEY_ESCAPE; + io.KeyMap[ImGuiKey_A] = GLFW_KEY_A; + io.KeyMap[ImGuiKey_C] = GLFW_KEY_C; + io.KeyMap[ImGuiKey_V] = GLFW_KEY_V; + io.KeyMap[ImGuiKey_X] = GLFW_KEY_X; + io.KeyMap[ImGuiKey_Y] = GLFW_KEY_Y; + io.KeyMap[ImGuiKey_Z] = GLFW_KEY_Z; + + io.RenderDrawListsFn = ImGui_ImplGlfw_RenderDrawLists; // Alternatively you can set this to NULL and call ImGui::GetDrawData() after ImGui::Render() to get the same ImDrawData pointer. + io.SetClipboardTextFn = ImGui_ImplGlfw_SetClipboardText; + io.GetClipboardTextFn = ImGui_ImplGlfw_GetClipboardText; +#ifdef _WIN32 + io.ImeWindowHandle = glfwGetWin32Window(g_Window); +#endif + + if (install_callbacks) + { + glfwSetMouseButtonCallback(window, ImGui_ImplGlfw_MouseButtonCallback); + glfwSetScrollCallback(window, ImGui_ImplGlfw_ScrollCallback); + glfwSetKeyCallback(window, ImGui_ImplGlFw_KeyCallback); + glfwSetCharCallback(window, ImGui_ImplGlfw_CharCallback); + } + + return true; +} + +void ImGui_ImplGlfw_Shutdown() +{ + ImGui_ImplGlfw_InvalidateDeviceObjects(); + ImGui::Shutdown(); +} + +void ImGui_ImplGlfw_NewFrame() +{ + if (!g_FontTexture) + ImGui_ImplGlfw_CreateDeviceObjects(); + + ImGuiIO& io = ImGui::GetIO(); + + // Setup display size (every frame to accommodate for window resizing) + int w, h; + int display_w, display_h; + glfwGetWindowSize(g_Window, &w, &h); + glfwGetFramebufferSize(g_Window, &display_w, &display_h); + io.DisplaySize = ImVec2((float)w, (float)h); + io.DisplayFramebufferScale = ImVec2(w > 0 ? ((float)display_w / w) : 0, h > 0 ? ((float)display_h / h) : 0); + + // Setup time step + double current_time = glfwGetTime(); + io.DeltaTime = g_Time > 0.0 ? (float)(current_time - g_Time) : (float)(1.0f/60.0f); + g_Time = current_time; + + // Setup inputs + // (we already got mouse wheel, keyboard keys & characters from glfw callbacks polled in glfwPollEvents()) + if (glfwGetWindowAttrib(g_Window, GLFW_FOCUSED)) + { + double mouse_x, mouse_y; + glfwGetCursorPos(g_Window, &mouse_x, &mouse_y); + io.MousePos = ImVec2((float)mouse_x, (float)mouse_y); // Mouse position in screen coordinates (set to -1,-1 if no mouse / on another screen, etc.) + } + else + { + io.MousePos = ImVec2(-1,-1); + } + + for (int i = 0; i < 3; i++) + { + io.MouseDown[i] = g_MousePressed[i] || glfwGetMouseButton(g_Window, i) != 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. + g_MousePressed[i] = false; + } + + io.MouseWheel = g_MouseWheel; + g_MouseWheel = 0.0f; + + // Hide OS mouse cursor if ImGui is drawing it + glfwSetInputMode(g_Window, GLFW_CURSOR, io.MouseDrawCursor ? GLFW_CURSOR_HIDDEN : GLFW_CURSOR_NORMAL); + + // Start the frame + ImGui::NewFrame(); +} diff --git a/examples/opengl2_example/imgui_impl_glfw.h b/examples/opengl2_example/imgui_impl_glfw.h new file mode 100644 index 0000000..07dd96f --- /dev/null +++ b/examples/opengl2_example/imgui_impl_glfw.h @@ -0,0 +1,29 @@ +// ImGui GLFW binding with OpenGL +// In this binding, ImTextureID is used to store an OpenGL 'GLuint' texture identifier. Read the FAQ about ImTextureID in imgui.cpp. + +// If your context is GL3/GL3 then prefer using the code in opengl3_example. +// You *might* use this code with a GL3/GL4 context but make sure you disable the programmable pipeline by calling "glUseProgram(0)" before ImGui::Render(). +// We cannot do that from GL2 code because the function doesn't exist. + +// You can copy and use unmodified imgui_impl_* files in your project. See main.cpp for an example of using this. +// If you use this binding you'll need to call 4 functions: ImGui_ImplXXXX_Init(), ImGui_ImplXXXX_NewFrame(), ImGui::Render() and ImGui_ImplXXXX_Shutdown(). +// If you are new to ImGui, see examples/README.txt and documentation at the top of imgui.cpp. +// https://github.com/ocornut/imgui + +struct GLFWwindow; + +IMGUI_API bool ImGui_ImplGlfw_Init(GLFWwindow* window, bool install_callbacks); +IMGUI_API void ImGui_ImplGlfw_Shutdown(); +IMGUI_API void ImGui_ImplGlfw_NewFrame(); + +// Use if you want to reset your rendering device without losing ImGui state. +IMGUI_API void ImGui_ImplGlfw_InvalidateDeviceObjects(); +IMGUI_API bool ImGui_ImplGlfw_CreateDeviceObjects(); + +// GLFW callbacks (installed by default if you enable 'install_callbacks' during initialization) +// Provided here if you want to chain callbacks. +// You can also handle inputs yourself and use those as a reference. +IMGUI_API void ImGui_ImplGlfw_MouseButtonCallback(GLFWwindow* window, int button, int action, int mods); +IMGUI_API void ImGui_ImplGlfw_ScrollCallback(GLFWwindow* window, double xoffset, double yoffset); +IMGUI_API void ImGui_ImplGlFw_KeyCallback(GLFWwindow* window, int key, int scancode, int action, int mods); +IMGUI_API void ImGui_ImplGlfw_CharCallback(GLFWwindow* window, unsigned int c); diff --git a/examples/opengl2_example/main.cpp b/examples/opengl2_example/main.cpp new file mode 100644 index 0000000..a844db5 --- /dev/null +++ b/examples/opengl2_example/main.cpp @@ -0,0 +1,89 @@ +// ImGui - standalone example application for Glfw + OpenGL 2, using fixed pipeline +// If you are new to ImGui, see examples/README.txt and documentation at the top of imgui.cpp. + +#include +#include "imgui_impl_glfw.h" +#include +#include + +static void error_callback(int error, const char* description) +{ + fprintf(stderr, "Error %d: %s\n", error, description); +} + +int main(int, char**) +{ + // Setup window + glfwSetErrorCallback(error_callback); + if (!glfwInit()) + return 1; + GLFWwindow* window = glfwCreateWindow(1280, 720, "ImGui OpenGL2 example", NULL, NULL); + glfwMakeContextCurrent(window); + + // Setup ImGui binding + ImGui_ImplGlfw_Init(window, true); + + // Load Fonts + // (there is a default font, this is only if you want to change it. see extra_fonts/README.txt for more details) + //ImGuiIO& io = ImGui::GetIO(); + //io.Fonts->AddFontDefault(); + //io.Fonts->AddFontFromFileTTF("../../extra_fonts/Cousine-Regular.ttf", 15.0f); + //io.Fonts->AddFontFromFileTTF("../../extra_fonts/DroidSans.ttf", 16.0f); + //io.Fonts->AddFontFromFileTTF("../../extra_fonts/ProggyClean.ttf", 13.0f); + //io.Fonts->AddFontFromFileTTF("../../extra_fonts/ProggyTiny.ttf", 10.0f); + //io.Fonts->AddFontFromFileTTF("c:\\Windows\\Fonts\\ArialUni.ttf", 18.0f, NULL, io.Fonts->GetGlyphRangesJapanese()); + + bool show_test_window = true; + bool show_another_window = false; + ImVec4 clear_color = ImColor(114, 144, 154); + + // Main loop + while (!glfwWindowShouldClose(window)) + { + glfwPollEvents(); + ImGui_ImplGlfw_NewFrame(); + + // 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 = 0.0f; + ImGui::Text("Hello, world!"); + ImGui::SliderFloat("float", &f, 0.0f, 1.0f); + ImGui::ColorEdit3("clear color", (float*)&clear_color); + if (ImGui::Button("Test Window")) show_test_window ^= 1; + if (ImGui::Button("Another Window")) show_another_window ^= 1; + ImGui::Text("Application average %.3f ms/frame (%.1f FPS)", 1000.0f / ImGui::GetIO().Framerate, ImGui::GetIO().Framerate); + } + + // 2. Show another simple window, this time using an explicit Begin/End pair + if (show_another_window) + { + ImGui::SetNextWindowSize(ImVec2(200,100), ImGuiSetCond_FirstUseEver); + ImGui::Begin("Another Window", &show_another_window); + 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::SetNextWindowPos(ImVec2(650, 20), ImGuiSetCond_FirstUseEver); + ImGui::ShowTestWindow(&show_test_window); + } + + // Rendering + int display_w, display_h; + glfwGetFramebufferSize(window, &display_w, &display_h); + glViewport(0, 0, display_w, display_h); + glClearColor(clear_color.x, clear_color.y, clear_color.z, clear_color.w); + glClear(GL_COLOR_BUFFER_BIT); + ImGui::Render(); + glfwSwapBuffers(window); + } + + // Cleanup + ImGui_ImplGlfw_Shutdown(); + glfwTerminate(); + + return 0; +} diff --git a/examples/opengl2_example/opengl_example.vcxproj b/examples/opengl2_example/opengl_example.vcxproj new file mode 100644 index 0000000..4b354b6 --- /dev/null +++ b/examples/opengl2_example/opengl_example.vcxproj @@ -0,0 +1,169 @@ + + + + + Debug + Win32 + + + Debug + x64 + + + Release + Win32 + + + Release + x64 + + + + {9CDA7840-B7A5-496D-A527-E95571496D18} + opengl_example + + + + Application + true + MultiByte + + + Application + true + MultiByte + + + Application + false + true + MultiByte + + + Application + false + true + MultiByte + + + + + + + + + + + + + + + + + + + $(ProjectDir)$(Configuration)\ + $(ProjectDir)$(Configuration)\ + $(IncludePath) + + + $(ProjectDir)$(Configuration)\ + $(ProjectDir)$(Configuration)\ + $(IncludePath) + + + $(ProjectDir)$(Configuration)\ + $(ProjectDir)$(Configuration)\ + $(IncludePath) + + + $(ProjectDir)$(Configuration)\ + $(ProjectDir)$(Configuration)\ + $(IncludePath) + + + + Level4 + Disabled + $(SolutionDir)\libs\glfw\include;..\..;%(AdditionalIncludeDirectories) + + + true + $(SolutionDir)\libs\glfw\lib-vc2010-32;%(AdditionalLibraryDirectories) + opengl32.lib;glfw3.lib;%(AdditionalDependencies) + Console + msvcrt.lib + + + + + Level4 + Disabled + $(SolutionDir)\libs\glfw\include;..\..;%(AdditionalIncludeDirectories) + + + true + $(SolutionDir)\libs\glfw\lib-vc2010-64;%(AdditionalLibraryDirectories) + opengl32.lib;glfw3.lib;%(AdditionalDependencies) + Console + msvcrt.lib + + + + + Level4 + MaxSpeed + true + true + $(SolutionDir)\libs\glfw\include;..\..;%(AdditionalIncludeDirectories) + + + true + true + true + $(SolutionDir)\libs\glfw\lib-vc2010-32;%(AdditionalLibraryDirectories) + opengl32.lib;glfw3.lib;%(AdditionalDependencies) + Console + + + + + + + Level4 + MaxSpeed + true + true + $(SolutionDir)\libs\glfw\include;..\..;%(AdditionalIncludeDirectories) + + + true + true + true + $(SolutionDir)\libs\glfw\lib-vc2010-64;%(AdditionalLibraryDirectories) + opengl32.lib;glfw3.lib;%(AdditionalDependencies) + Console + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/examples/opengl2_example/opengl_example.vcxproj.filters b/examples/opengl2_example/opengl_example.vcxproj.filters new file mode 100644 index 0000000..f2282bf --- /dev/null +++ b/examples/opengl2_example/opengl_example.vcxproj.filters @@ -0,0 +1,46 @@ + + + + + {c336cfe3-f0c4-464c-9ef0-a9e17a7ff222} + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx + + + + + sources + + + imgui + + + sources + + + imgui + + + imgui + + + + + imgui + + + imgui + + + sources + + + imgui + + + + + + \ No newline at end of file diff --git a/examples/opengl_example/Makefile b/examples/opengl_example/Makefile deleted file mode 100644 index 91d1b14..0000000 --- a/examples/opengl_example/Makefile +++ /dev/null @@ -1,60 +0,0 @@ -# -# Cross Platform Makefile -# Compatible with Ubuntu 14.04.1 and Mac OS X -# -# -# if you using Mac OS X: -# You'll need glfw -# http://www.glfw.org -# - -#CXX = g++ - -EXE = opengl_example -OBJS = main.o imgui_impl_glfw.o -OBJS += ../../imgui.o ../../imgui_demo.o ../../imgui_draw.o - -UNAME_S := $(shell uname -s) - - -ifeq ($(UNAME_S), Linux) #LINUX - ECHO_MESSAGE = "Linux" - LIBS = -lGL `pkg-config --static --libs glfw3` - - CXXFLAGS = -I../../ `pkg-config --cflags glfw3` - CXXFLAGS += -Wall -Wformat - CFLAGS = $(CXXFLAGS) -endif - -ifeq ($(UNAME_S), Darwin) #APPLE - ECHO_MESSAGE = "Mac OS X" - LIBS = -framework OpenGL -framework Cocoa -framework IOKit -framework CoreVideo - LIBS += -L/usr/local/lib -lglfw3 - - CXXFLAGS = -I../../ -I/usr/local/include - CXXFLAGS += -Wall -Wformat -# CXXFLAGS += -D__APPLE__ - CFLAGS = $(CXXFLAGS) -endif - -ifeq ($(UNAME_S), MINGW64_NT-6.3) - ECHO_MESSAGE = "Windows" - LIBS = -lglfw3 -lgdi32 -lopengl32 -limm32 - - CXXFLAGS = -I../../ -I../libs/gl3w `pkg-config --cflags glfw3` - CXXFLAGS += -Wall -Wformat - CFLAGS = $(CXXFLAGS) -endif - -.cpp.o: - $(CXX) $(CXXFLAGS) -c -o $@ $< - -all: $(EXE) - @echo Build complete for $(ECHO_MESSAGE) - -$(EXE): $(OBJS) - $(CXX) -o $(EXE) $(OBJS) $(CXXFLAGS) $(LIBS) - -clean: - rm $(EXE) $(OBJS) - diff --git a/examples/opengl_example/build_win32.bat b/examples/opengl_example/build_win32.bat deleted file mode 100644 index 278381c..0000000 --- a/examples/opengl_example/build_win32.bat +++ /dev/null @@ -1,3 +0,0 @@ -@REM Build for Visual Studio compiler. Run your copy of vcvars32.bat or vcvarsall.bat to setup command-line compiler. -mkdir Debug -cl /nologo /Zi /MD /I ..\.. /I ..\libs\glfw\include *.cpp ..\..\*.cpp /FeDebug/opengl_example.exe /FoDebug/ /link /LIBPATH:..\libs\glfw\lib-vc2010-32 glfw3.lib opengl32.lib gdi32.lib shell32.lib diff --git a/examples/opengl_example/imgui_impl_glfw.cpp b/examples/opengl_example/imgui_impl_glfw.cpp deleted file mode 100644 index 2d1f5c1..0000000 --- a/examples/opengl_example/imgui_impl_glfw.cpp +++ /dev/null @@ -1,288 +0,0 @@ -// ImGui GLFW binding with OpenGL -// In this binding, ImTextureID is used to store an OpenGL 'GLuint' texture identifier. Read the FAQ about ImTextureID in imgui.cpp. - -// If your context is GL3/GL3 then prefer using the code in opengl3_example. -// You *might* use this code with a GL3/GL4 context but make sure you disable the programmable pipeline by calling "glUseProgram(0)" before ImGui::Render(). -// We cannot do that from GL2 code because the function doesn't exist. - -// You can copy and use unmodified imgui_impl_* files in your project. See main.cpp for an example of using this. -// If you use this binding you'll need to call 4 functions: ImGui_ImplXXXX_Init(), ImGui_ImplXXXX_NewFrame(), ImGui::Render() and ImGui_ImplXXXX_Shutdown(). -// If you are new to ImGui, see examples/README.txt and documentation at the top of imgui.cpp. -// https://github.com/ocornut/imgui - -#include -#include "imgui_impl_glfw.h" - -// GLFW -#include -#ifdef _WIN32 -#undef APIENTRY -#define GLFW_EXPOSE_NATIVE_WIN32 -#define GLFW_EXPOSE_NATIVE_WGL -#include -#endif - -// Data -static GLFWwindow* g_Window = NULL; -static double g_Time = 0.0f; -static bool g_MousePressed[3] = { false, false, false }; -static float g_MouseWheel = 0.0f; -static GLuint g_FontTexture = 0; - -// 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) -void ImGui_ImplGlfw_RenderDrawLists(ImDrawData* draw_data) -{ - // Avoid rendering when minimized, scale coordinates for retina displays (screen coordinates != framebuffer coordinates) - ImGuiIO& io = ImGui::GetIO(); - int fb_width = (int)(io.DisplaySize.x * io.DisplayFramebufferScale.x); - int fb_height = (int)(io.DisplaySize.y * io.DisplayFramebufferScale.y); - if (fb_width == 0 || fb_height == 0) - return; - draw_data->ScaleClipRects(io.DisplayFramebufferScale); - - // We are using the OpenGL fixed pipeline to make the example code simpler to read! - // Setup render state: alpha-blending enabled, no face culling, no depth testing, scissor enabled, vertex/texcoord/color pointers. - GLint last_texture; glGetIntegerv(GL_TEXTURE_BINDING_2D, &last_texture); - GLint last_viewport[4]; glGetIntegerv(GL_VIEWPORT, last_viewport); - glPushAttrib(GL_ENABLE_BIT | GL_COLOR_BUFFER_BIT | GL_TRANSFORM_BIT); - glEnable(GL_BLEND); - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - glDisable(GL_CULL_FACE); - glDisable(GL_DEPTH_TEST); - glEnable(GL_SCISSOR_TEST); - glEnableClientState(GL_VERTEX_ARRAY); - glEnableClientState(GL_TEXTURE_COORD_ARRAY); - glEnableClientState(GL_COLOR_ARRAY); - glEnable(GL_TEXTURE_2D); - //glUseProgram(0); // You may want this if using this code in an OpenGL 3+ context - - // Setup viewport, orthographic projection matrix - glViewport(0, 0, (GLsizei)fb_width, (GLsizei)fb_height); - glMatrixMode(GL_PROJECTION); - glPushMatrix(); - glLoadIdentity(); - glOrtho(0.0f, io.DisplaySize.x, io.DisplaySize.y, 0.0f, -1.0f, +1.0f); - glMatrixMode(GL_MODELVIEW); - glPushMatrix(); - glLoadIdentity(); - - // Render command lists - #define OFFSETOF(TYPE, ELEMENT) ((size_t)&(((TYPE *)0)->ELEMENT)) - for (int n = 0; n < draw_data->CmdListsCount; n++) - { - const ImDrawList* cmd_list = draw_data->CmdLists[n]; - const unsigned char* vtx_buffer = (const unsigned char*)&cmd_list->VtxBuffer.front(); - const ImDrawIdx* idx_buffer = &cmd_list->IdxBuffer.front(); - glVertexPointer(2, GL_FLOAT, sizeof(ImDrawVert), (void*)(vtx_buffer + OFFSETOF(ImDrawVert, pos))); - glTexCoordPointer(2, GL_FLOAT, sizeof(ImDrawVert), (void*)(vtx_buffer + OFFSETOF(ImDrawVert, uv))); - glColorPointer(4, GL_UNSIGNED_BYTE, sizeof(ImDrawVert), (void*)(vtx_buffer + OFFSETOF(ImDrawVert, col))); - - for (int cmd_i = 0; cmd_i < cmd_list->CmdBuffer.size(); cmd_i++) - { - const ImDrawCmd* pcmd = &cmd_list->CmdBuffer[cmd_i]; - if (pcmd->UserCallback) - { - pcmd->UserCallback(cmd_list, pcmd); - } - else - { - glBindTexture(GL_TEXTURE_2D, (GLuint)(intptr_t)pcmd->TextureId); - glScissor((int)pcmd->ClipRect.x, (int)(fb_height - pcmd->ClipRect.w), (int)(pcmd->ClipRect.z - pcmd->ClipRect.x), (int)(pcmd->ClipRect.w - pcmd->ClipRect.y)); - glDrawElements(GL_TRIANGLES, (GLsizei)pcmd->ElemCount, sizeof(ImDrawIdx) == 2 ? GL_UNSIGNED_SHORT : GL_UNSIGNED_INT, idx_buffer); - } - idx_buffer += pcmd->ElemCount; - } - } - #undef OFFSETOF - - // Restore modified state - glDisableClientState(GL_COLOR_ARRAY); - glDisableClientState(GL_TEXTURE_COORD_ARRAY); - glDisableClientState(GL_VERTEX_ARRAY); - glBindTexture(GL_TEXTURE_2D, (GLuint)last_texture); - glMatrixMode(GL_MODELVIEW); - glPopMatrix(); - glMatrixMode(GL_PROJECTION); - glPopMatrix(); - glPopAttrib(); - glViewport(last_viewport[0], last_viewport[1], (GLsizei)last_viewport[2], (GLsizei)last_viewport[3]); -} - -static const char* ImGui_ImplGlfw_GetClipboardText() -{ - return glfwGetClipboardString(g_Window); -} - -static void ImGui_ImplGlfw_SetClipboardText(const char* text) -{ - glfwSetClipboardString(g_Window, text); -} - -void ImGui_ImplGlfw_MouseButtonCallback(GLFWwindow*, int button, int action, int /*mods*/) -{ - if (action == GLFW_PRESS && button >= 0 && button < 3) - g_MousePressed[button] = true; -} - -void ImGui_ImplGlfw_ScrollCallback(GLFWwindow*, double /*xoffset*/, double yoffset) -{ - g_MouseWheel += (float)yoffset; // Use fractional mouse wheel, 1.0 unit 5 lines. -} - -void ImGui_ImplGlFw_KeyCallback(GLFWwindow*, int key, int, int action, int mods) -{ - ImGuiIO& io = ImGui::GetIO(); - if (action == GLFW_PRESS) - io.KeysDown[key] = true; - if (action == GLFW_RELEASE) - io.KeysDown[key] = false; - - (void)mods; // Modifiers are not reliable across systems - io.KeyCtrl = io.KeysDown[GLFW_KEY_LEFT_CONTROL] || io.KeysDown[GLFW_KEY_RIGHT_CONTROL]; - io.KeyShift = io.KeysDown[GLFW_KEY_LEFT_SHIFT] || io.KeysDown[GLFW_KEY_RIGHT_SHIFT]; - io.KeyAlt = io.KeysDown[GLFW_KEY_LEFT_ALT] || io.KeysDown[GLFW_KEY_RIGHT_ALT]; - io.KeySuper = io.KeysDown[GLFW_KEY_LEFT_SUPER] || io.KeysDown[GLFW_KEY_RIGHT_SUPER]; -} - -void ImGui_ImplGlfw_CharCallback(GLFWwindow*, unsigned int c) -{ - ImGuiIO& io = ImGui::GetIO(); - if (c > 0 && c < 0x10000) - io.AddInputCharacter((unsigned short)c); -} - -bool ImGui_ImplGlfw_CreateDeviceObjects() -{ - // Build texture atlas - ImGuiIO& io = ImGui::GetIO(); - unsigned char* pixels; - int width, height; - io.Fonts->GetTexDataAsAlpha8(&pixels, &width, &height); - - // Upload texture to graphics system - GLint last_texture; - glGetIntegerv(GL_TEXTURE_BINDING_2D, &last_texture); - glGenTextures(1, &g_FontTexture); - glBindTexture(GL_TEXTURE_2D, g_FontTexture); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, width, height, 0, GL_ALPHA, GL_UNSIGNED_BYTE, pixels); - - // Store our identifier - io.Fonts->TexID = (void *)(intptr_t)g_FontTexture; - - // Restore state - glBindTexture(GL_TEXTURE_2D, last_texture); - - return true; -} - -void ImGui_ImplGlfw_InvalidateDeviceObjects() -{ - if (g_FontTexture) - { - glDeleteTextures(1, &g_FontTexture); - ImGui::GetIO().Fonts->TexID = 0; - g_FontTexture = 0; - } -} - -bool ImGui_ImplGlfw_Init(GLFWwindow* window, bool install_callbacks) -{ - g_Window = window; - - ImGuiIO& io = ImGui::GetIO(); - 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; - io.KeyMap[ImGuiKey_DownArrow] = GLFW_KEY_DOWN; - io.KeyMap[ImGuiKey_PageUp] = GLFW_KEY_PAGE_UP; - io.KeyMap[ImGuiKey_PageDown] = GLFW_KEY_PAGE_DOWN; - io.KeyMap[ImGuiKey_Home] = GLFW_KEY_HOME; - io.KeyMap[ImGuiKey_End] = GLFW_KEY_END; - io.KeyMap[ImGuiKey_Delete] = GLFW_KEY_DELETE; - io.KeyMap[ImGuiKey_Backspace] = GLFW_KEY_BACKSPACE; - io.KeyMap[ImGuiKey_Enter] = GLFW_KEY_ENTER; - io.KeyMap[ImGuiKey_Escape] = GLFW_KEY_ESCAPE; - io.KeyMap[ImGuiKey_A] = GLFW_KEY_A; - io.KeyMap[ImGuiKey_C] = GLFW_KEY_C; - io.KeyMap[ImGuiKey_V] = GLFW_KEY_V; - io.KeyMap[ImGuiKey_X] = GLFW_KEY_X; - io.KeyMap[ImGuiKey_Y] = GLFW_KEY_Y; - io.KeyMap[ImGuiKey_Z] = GLFW_KEY_Z; - - io.RenderDrawListsFn = ImGui_ImplGlfw_RenderDrawLists; // Alternatively you can set this to NULL and call ImGui::GetDrawData() after ImGui::Render() to get the same ImDrawData pointer. - io.SetClipboardTextFn = ImGui_ImplGlfw_SetClipboardText; - io.GetClipboardTextFn = ImGui_ImplGlfw_GetClipboardText; -#ifdef _WIN32 - io.ImeWindowHandle = glfwGetWin32Window(g_Window); -#endif - - if (install_callbacks) - { - glfwSetMouseButtonCallback(window, ImGui_ImplGlfw_MouseButtonCallback); - glfwSetScrollCallback(window, ImGui_ImplGlfw_ScrollCallback); - glfwSetKeyCallback(window, ImGui_ImplGlFw_KeyCallback); - glfwSetCharCallback(window, ImGui_ImplGlfw_CharCallback); - } - - return true; -} - -void ImGui_ImplGlfw_Shutdown() -{ - ImGui_ImplGlfw_InvalidateDeviceObjects(); - ImGui::Shutdown(); -} - -void ImGui_ImplGlfw_NewFrame() -{ - if (!g_FontTexture) - ImGui_ImplGlfw_CreateDeviceObjects(); - - ImGuiIO& io = ImGui::GetIO(); - - // Setup display size (every frame to accommodate for window resizing) - int w, h; - int display_w, display_h; - glfwGetWindowSize(g_Window, &w, &h); - glfwGetFramebufferSize(g_Window, &display_w, &display_h); - io.DisplaySize = ImVec2((float)w, (float)h); - io.DisplayFramebufferScale = ImVec2(w > 0 ? ((float)display_w / w) : 0, h > 0 ? ((float)display_h / h) : 0); - - // Setup time step - double current_time = glfwGetTime(); - io.DeltaTime = g_Time > 0.0 ? (float)(current_time - g_Time) : (float)(1.0f/60.0f); - g_Time = current_time; - - // Setup inputs - // (we already got mouse wheel, keyboard keys & characters from glfw callbacks polled in glfwPollEvents()) - if (glfwGetWindowAttrib(g_Window, GLFW_FOCUSED)) - { - double mouse_x, mouse_y; - glfwGetCursorPos(g_Window, &mouse_x, &mouse_y); - io.MousePos = ImVec2((float)mouse_x, (float)mouse_y); // Mouse position in screen coordinates (set to -1,-1 if no mouse / on another screen, etc.) - } - else - { - io.MousePos = ImVec2(-1,-1); - } - - for (int i = 0; i < 3; i++) - { - io.MouseDown[i] = g_MousePressed[i] || glfwGetMouseButton(g_Window, i) != 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. - g_MousePressed[i] = false; - } - - io.MouseWheel = g_MouseWheel; - g_MouseWheel = 0.0f; - - // Hide OS mouse cursor if ImGui is drawing it - glfwSetInputMode(g_Window, GLFW_CURSOR, io.MouseDrawCursor ? GLFW_CURSOR_HIDDEN : GLFW_CURSOR_NORMAL); - - // Start the frame - ImGui::NewFrame(); -} diff --git a/examples/opengl_example/imgui_impl_glfw.h b/examples/opengl_example/imgui_impl_glfw.h deleted file mode 100644 index 07dd96f..0000000 --- a/examples/opengl_example/imgui_impl_glfw.h +++ /dev/null @@ -1,29 +0,0 @@ -// ImGui GLFW binding with OpenGL -// In this binding, ImTextureID is used to store an OpenGL 'GLuint' texture identifier. Read the FAQ about ImTextureID in imgui.cpp. - -// If your context is GL3/GL3 then prefer using the code in opengl3_example. -// You *might* use this code with a GL3/GL4 context but make sure you disable the programmable pipeline by calling "glUseProgram(0)" before ImGui::Render(). -// We cannot do that from GL2 code because the function doesn't exist. - -// You can copy and use unmodified imgui_impl_* files in your project. See main.cpp for an example of using this. -// If you use this binding you'll need to call 4 functions: ImGui_ImplXXXX_Init(), ImGui_ImplXXXX_NewFrame(), ImGui::Render() and ImGui_ImplXXXX_Shutdown(). -// If you are new to ImGui, see examples/README.txt and documentation at the top of imgui.cpp. -// https://github.com/ocornut/imgui - -struct GLFWwindow; - -IMGUI_API bool ImGui_ImplGlfw_Init(GLFWwindow* window, bool install_callbacks); -IMGUI_API void ImGui_ImplGlfw_Shutdown(); -IMGUI_API void ImGui_ImplGlfw_NewFrame(); - -// Use if you want to reset your rendering device without losing ImGui state. -IMGUI_API void ImGui_ImplGlfw_InvalidateDeviceObjects(); -IMGUI_API bool ImGui_ImplGlfw_CreateDeviceObjects(); - -// GLFW callbacks (installed by default if you enable 'install_callbacks' during initialization) -// Provided here if you want to chain callbacks. -// You can also handle inputs yourself and use those as a reference. -IMGUI_API void ImGui_ImplGlfw_MouseButtonCallback(GLFWwindow* window, int button, int action, int mods); -IMGUI_API void ImGui_ImplGlfw_ScrollCallback(GLFWwindow* window, double xoffset, double yoffset); -IMGUI_API void ImGui_ImplGlFw_KeyCallback(GLFWwindow* window, int key, int scancode, int action, int mods); -IMGUI_API void ImGui_ImplGlfw_CharCallback(GLFWwindow* window, unsigned int c); diff --git a/examples/opengl_example/main.cpp b/examples/opengl_example/main.cpp deleted file mode 100644 index a844db5..0000000 --- a/examples/opengl_example/main.cpp +++ /dev/null @@ -1,89 +0,0 @@ -// ImGui - standalone example application for Glfw + OpenGL 2, using fixed pipeline -// If you are new to ImGui, see examples/README.txt and documentation at the top of imgui.cpp. - -#include -#include "imgui_impl_glfw.h" -#include -#include - -static void error_callback(int error, const char* description) -{ - fprintf(stderr, "Error %d: %s\n", error, description); -} - -int main(int, char**) -{ - // Setup window - glfwSetErrorCallback(error_callback); - if (!glfwInit()) - return 1; - GLFWwindow* window = glfwCreateWindow(1280, 720, "ImGui OpenGL2 example", NULL, NULL); - glfwMakeContextCurrent(window); - - // Setup ImGui binding - ImGui_ImplGlfw_Init(window, true); - - // Load Fonts - // (there is a default font, this is only if you want to change it. see extra_fonts/README.txt for more details) - //ImGuiIO& io = ImGui::GetIO(); - //io.Fonts->AddFontDefault(); - //io.Fonts->AddFontFromFileTTF("../../extra_fonts/Cousine-Regular.ttf", 15.0f); - //io.Fonts->AddFontFromFileTTF("../../extra_fonts/DroidSans.ttf", 16.0f); - //io.Fonts->AddFontFromFileTTF("../../extra_fonts/ProggyClean.ttf", 13.0f); - //io.Fonts->AddFontFromFileTTF("../../extra_fonts/ProggyTiny.ttf", 10.0f); - //io.Fonts->AddFontFromFileTTF("c:\\Windows\\Fonts\\ArialUni.ttf", 18.0f, NULL, io.Fonts->GetGlyphRangesJapanese()); - - bool show_test_window = true; - bool show_another_window = false; - ImVec4 clear_color = ImColor(114, 144, 154); - - // Main loop - while (!glfwWindowShouldClose(window)) - { - glfwPollEvents(); - ImGui_ImplGlfw_NewFrame(); - - // 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 = 0.0f; - ImGui::Text("Hello, world!"); - ImGui::SliderFloat("float", &f, 0.0f, 1.0f); - ImGui::ColorEdit3("clear color", (float*)&clear_color); - if (ImGui::Button("Test Window")) show_test_window ^= 1; - if (ImGui::Button("Another Window")) show_another_window ^= 1; - ImGui::Text("Application average %.3f ms/frame (%.1f FPS)", 1000.0f / ImGui::GetIO().Framerate, ImGui::GetIO().Framerate); - } - - // 2. Show another simple window, this time using an explicit Begin/End pair - if (show_another_window) - { - ImGui::SetNextWindowSize(ImVec2(200,100), ImGuiSetCond_FirstUseEver); - ImGui::Begin("Another Window", &show_another_window); - 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::SetNextWindowPos(ImVec2(650, 20), ImGuiSetCond_FirstUseEver); - ImGui::ShowTestWindow(&show_test_window); - } - - // Rendering - int display_w, display_h; - glfwGetFramebufferSize(window, &display_w, &display_h); - glViewport(0, 0, display_w, display_h); - glClearColor(clear_color.x, clear_color.y, clear_color.z, clear_color.w); - glClear(GL_COLOR_BUFFER_BIT); - ImGui::Render(); - glfwSwapBuffers(window); - } - - // Cleanup - ImGui_ImplGlfw_Shutdown(); - glfwTerminate(); - - return 0; -} diff --git a/examples/opengl_example/opengl_example.vcxproj b/examples/opengl_example/opengl_example.vcxproj deleted file mode 100644 index 4b354b6..0000000 --- a/examples/opengl_example/opengl_example.vcxproj +++ /dev/null @@ -1,169 +0,0 @@ - - - - - Debug - Win32 - - - Debug - x64 - - - Release - Win32 - - - Release - x64 - - - - {9CDA7840-B7A5-496D-A527-E95571496D18} - opengl_example - - - - Application - true - MultiByte - - - Application - true - MultiByte - - - Application - false - true - MultiByte - - - Application - false - true - MultiByte - - - - - - - - - - - - - - - - - - - $(ProjectDir)$(Configuration)\ - $(ProjectDir)$(Configuration)\ - $(IncludePath) - - - $(ProjectDir)$(Configuration)\ - $(ProjectDir)$(Configuration)\ - $(IncludePath) - - - $(ProjectDir)$(Configuration)\ - $(ProjectDir)$(Configuration)\ - $(IncludePath) - - - $(ProjectDir)$(Configuration)\ - $(ProjectDir)$(Configuration)\ - $(IncludePath) - - - - Level4 - Disabled - $(SolutionDir)\libs\glfw\include;..\..;%(AdditionalIncludeDirectories) - - - true - $(SolutionDir)\libs\glfw\lib-vc2010-32;%(AdditionalLibraryDirectories) - opengl32.lib;glfw3.lib;%(AdditionalDependencies) - Console - msvcrt.lib - - - - - Level4 - Disabled - $(SolutionDir)\libs\glfw\include;..\..;%(AdditionalIncludeDirectories) - - - true - $(SolutionDir)\libs\glfw\lib-vc2010-64;%(AdditionalLibraryDirectories) - opengl32.lib;glfw3.lib;%(AdditionalDependencies) - Console - msvcrt.lib - - - - - Level4 - MaxSpeed - true - true - $(SolutionDir)\libs\glfw\include;..\..;%(AdditionalIncludeDirectories) - - - true - true - true - $(SolutionDir)\libs\glfw\lib-vc2010-32;%(AdditionalLibraryDirectories) - opengl32.lib;glfw3.lib;%(AdditionalDependencies) - Console - - - - - - - Level4 - MaxSpeed - true - true - $(SolutionDir)\libs\glfw\include;..\..;%(AdditionalIncludeDirectories) - - - true - true - true - $(SolutionDir)\libs\glfw\lib-vc2010-64;%(AdditionalLibraryDirectories) - opengl32.lib;glfw3.lib;%(AdditionalDependencies) - Console - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/examples/opengl_example/opengl_example.vcxproj.filters b/examples/opengl_example/opengl_example.vcxproj.filters deleted file mode 100644 index f2282bf..0000000 --- a/examples/opengl_example/opengl_example.vcxproj.filters +++ /dev/null @@ -1,46 +0,0 @@ - - - - - {c336cfe3-f0c4-464c-9ef0-a9e17a7ff222} - - - {4FC737F1-C7A5-4376-A066-2A32D752A2FF} - cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx - - - - - sources - - - imgui - - - sources - - - imgui - - - imgui - - - - - imgui - - - imgui - - - sources - - - imgui - - - - - - \ No newline at end of file diff --git a/examples/sdl_opengl2_example/README.md b/examples/sdl_opengl2_example/README.md new file mode 100644 index 0000000..aada45d --- /dev/null +++ b/examples/sdl_opengl2_example/README.md @@ -0,0 +1,22 @@ + +# How to Build + +- On Windows with Visual Studio's CLI + +``` +set SDL2DIR=path_to_your_sdl2_folder +cl /Zi /MD /I %SDL2DIR%\include> /I ..\.. main.cpp imgui_impl_sdl.cpp ..\..\imgui*.cpp /link /LIBPATH:%SDL2DIR%\lib SDL2.lib SDL2main.lib +``` + +- On Linux and similar Unixes + +``` +c++ `sdl2-config --cflags` -I ../.. main.cpp imgui_impl_sdl.cpp ../../imgui*.cpp `sdl2-config --libs` -lGL -o sdl2example +``` + +- On Mac OS X + +``` +brew install sdl2 +c++ `sdl2-config --cflags` -I ../.. main.cpp imgui_impl_sdl.cpp ../../imgui*.cpp `sdl2-config --libs` -framework OpenGl -o sdl2example +``` diff --git a/examples/sdl_opengl2_example/imgui_impl_sdl.cpp b/examples/sdl_opengl2_example/imgui_impl_sdl.cpp new file mode 100644 index 0000000..63ed9f4 --- /dev/null +++ b/examples/sdl_opengl2_example/imgui_impl_sdl.cpp @@ -0,0 +1,277 @@ +// ImGui SDL2 binding with OpenGL +// In this binding, ImTextureID is used to store an OpenGL 'GLuint' texture identifier. Read the FAQ about ImTextureID in imgui.cpp. + +// You can copy and use unmodified imgui_impl_* files in your project. See main.cpp for an example of using this. +// If you use this binding you'll need to call 4 functions: ImGui_ImplXXXX_Init(), ImGui_ImplXXXX_NewFrame(), ImGui::Render() and ImGui_ImplXXXX_Shutdown(). +// If you are new to ImGui, see examples/README.txt and documentation at the top of imgui.cpp. +// https://github.com/ocornut/imgui + +#include +#include +#include +#include +#include "imgui_impl_sdl.h" + +// Data +static double g_Time = 0.0f; +static bool g_MousePressed[3] = { false, false, false }; +static float g_MouseWheel = 0.0f; +static GLuint g_FontTexture = 0; + +// 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) +void ImGui_ImplSdl_RenderDrawLists(ImDrawData* draw_data) +{ + // Avoid rendering when minimized, scale coordinates for retina displays (screen coordinates != framebuffer coordinates) + ImGuiIO& io = ImGui::GetIO(); + int fb_width = (int)(io.DisplaySize.x * io.DisplayFramebufferScale.x); + int fb_height = (int)(io.DisplaySize.y * io.DisplayFramebufferScale.y); + if (fb_width == 0 || fb_height == 0) + return; + draw_data->ScaleClipRects(io.DisplayFramebufferScale); + + // We are using the OpenGL fixed pipeline to make the example code simpler to read! + // Setup render state: alpha-blending enabled, no face culling, no depth testing, scissor enabled, vertex/texcoord/color pointers. + GLint last_texture; glGetIntegerv(GL_TEXTURE_BINDING_2D, &last_texture); + GLint last_viewport[4]; glGetIntegerv(GL_VIEWPORT, last_viewport); + glPushAttrib(GL_ENABLE_BIT | GL_COLOR_BUFFER_BIT | GL_TRANSFORM_BIT); + glEnable(GL_BLEND); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + glDisable(GL_CULL_FACE); + glDisable(GL_DEPTH_TEST); + glEnable(GL_SCISSOR_TEST); + glEnableClientState(GL_VERTEX_ARRAY); + glEnableClientState(GL_TEXTURE_COORD_ARRAY); + glEnableClientState(GL_COLOR_ARRAY); + glEnable(GL_TEXTURE_2D); + //glUseProgram(0); // You may want this if using this code in an OpenGL 3+ context + + // Setup viewport, orthographic projection matrix + glViewport(0, 0, (GLsizei)fb_width, (GLsizei)fb_height); + glMatrixMode(GL_PROJECTION); + glPushMatrix(); + glLoadIdentity(); + glOrtho(0.0f, io.DisplaySize.x, io.DisplaySize.y, 0.0f, -1.0f, +1.0f); + glMatrixMode(GL_MODELVIEW); + glPushMatrix(); + glLoadIdentity(); + + // Render command lists + #define OFFSETOF(TYPE, ELEMENT) ((size_t)&(((TYPE *)0)->ELEMENT)) + for (int n = 0; n < draw_data->CmdListsCount; n++) + { + const ImDrawList* cmd_list = draw_data->CmdLists[n]; + const unsigned char* vtx_buffer = (const unsigned char*)&cmd_list->VtxBuffer.front(); + const ImDrawIdx* idx_buffer = &cmd_list->IdxBuffer.front(); + glVertexPointer(2, GL_FLOAT, sizeof(ImDrawVert), (void*)(vtx_buffer + OFFSETOF(ImDrawVert, pos))); + glTexCoordPointer(2, GL_FLOAT, sizeof(ImDrawVert), (void*)(vtx_buffer + OFFSETOF(ImDrawVert, uv))); + glColorPointer(4, GL_UNSIGNED_BYTE, sizeof(ImDrawVert), (void*)(vtx_buffer + OFFSETOF(ImDrawVert, col))); + + for (int cmd_i = 0; cmd_i < cmd_list->CmdBuffer.size(); cmd_i++) + { + const ImDrawCmd* pcmd = &cmd_list->CmdBuffer[cmd_i]; + if (pcmd->UserCallback) + { + pcmd->UserCallback(cmd_list, pcmd); + } + else + { + glBindTexture(GL_TEXTURE_2D, (GLuint)(intptr_t)pcmd->TextureId); + glScissor((int)pcmd->ClipRect.x, (int)(fb_height - pcmd->ClipRect.w), (int)(pcmd->ClipRect.z - pcmd->ClipRect.x), (int)(pcmd->ClipRect.w - pcmd->ClipRect.y)); + glDrawElements(GL_TRIANGLES, (GLsizei)pcmd->ElemCount, sizeof(ImDrawIdx) == 2 ? GL_UNSIGNED_SHORT : GL_UNSIGNED_INT, idx_buffer); + } + idx_buffer += pcmd->ElemCount; + } + } + #undef OFFSETOF + + // Restore modified state + glDisableClientState(GL_COLOR_ARRAY); + glDisableClientState(GL_TEXTURE_COORD_ARRAY); + glDisableClientState(GL_VERTEX_ARRAY); + glBindTexture(GL_TEXTURE_2D, (GLuint)last_texture); + glMatrixMode(GL_MODELVIEW); + glPopMatrix(); + glMatrixMode(GL_PROJECTION); + glPopMatrix(); + glPopAttrib(); + glViewport(last_viewport[0], last_viewport[1], (GLsizei)last_viewport[2], (GLsizei)last_viewport[3]); +} + +static const char* ImGui_ImplSdl_GetClipboardText() +{ + return SDL_GetClipboardText(); +} + +static void ImGui_ImplSdl_SetClipboardText(const char* text) +{ + SDL_SetClipboardText(text); +} + +bool ImGui_ImplSdl_ProcessEvent(SDL_Event* event) +{ + ImGuiIO& io = ImGui::GetIO(); + switch (event->type) + { + case SDL_MOUSEWHEEL: + { + if (event->wheel.y > 0) + g_MouseWheel = 1; + if (event->wheel.y < 0) + g_MouseWheel = -1; + return true; + } + case SDL_MOUSEBUTTONDOWN: + { + if (event->button.button == SDL_BUTTON_LEFT) g_MousePressed[0] = true; + if (event->button.button == SDL_BUTTON_RIGHT) g_MousePressed[1] = true; + if (event->button.button == SDL_BUTTON_MIDDLE) g_MousePressed[2] = true; + return true; + } + case SDL_TEXTINPUT: + { + io.AddInputCharactersUTF8(event->text.text); + return true; + } + case SDL_KEYDOWN: + case SDL_KEYUP: + { + int key = event->key.keysym.sym & ~SDLK_SCANCODE_MASK; + io.KeysDown[key] = (event->type == SDL_KEYDOWN); + io.KeyShift = ((SDL_GetModState() & KMOD_SHIFT) != 0); + io.KeyCtrl = ((SDL_GetModState() & KMOD_CTRL) != 0); + io.KeyAlt = ((SDL_GetModState() & KMOD_ALT) != 0); + io.KeySuper = ((SDL_GetModState() & KMOD_GUI) != 0); + return true; + } + } + return false; +} + +bool ImGui_ImplSdl_CreateDeviceObjects() +{ + // Build texture atlas + ImGuiIO& io = ImGui::GetIO(); + unsigned char* pixels; + int width, height; + io.Fonts->GetTexDataAsAlpha8(&pixels, &width, &height); + + // Upload texture to graphics system + GLint last_texture; + glGetIntegerv(GL_TEXTURE_BINDING_2D, &last_texture); + glGenTextures(1, &g_FontTexture); + glBindTexture(GL_TEXTURE_2D, g_FontTexture); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glPixelStorei(GL_UNPACK_ROW_LENGTH, 0); + glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, width, height, 0, GL_ALPHA, GL_UNSIGNED_BYTE, pixels); + + // Store our identifier + io.Fonts->TexID = (void *)(intptr_t)g_FontTexture; + + // Restore state + glBindTexture(GL_TEXTURE_2D, last_texture); + + return true; +} + +void ImGui_ImplSdl_InvalidateDeviceObjects() +{ + if (g_FontTexture) + { + glDeleteTextures(1, &g_FontTexture); + ImGui::GetIO().Fonts->TexID = 0; + g_FontTexture = 0; + } +} + +bool ImGui_ImplSdl_Init(SDL_Window* window) +{ + ImGuiIO& io = ImGui::GetIO(); + io.KeyMap[ImGuiKey_Tab] = SDLK_TAB; // Keyboard mapping. ImGui will use those indices to peek into the io.KeyDown[] array. + io.KeyMap[ImGuiKey_LeftArrow] = SDL_SCANCODE_LEFT; + io.KeyMap[ImGuiKey_RightArrow] = SDL_SCANCODE_RIGHT; + io.KeyMap[ImGuiKey_UpArrow] = SDL_SCANCODE_UP; + io.KeyMap[ImGuiKey_DownArrow] = SDL_SCANCODE_DOWN; + io.KeyMap[ImGuiKey_PageUp] = SDL_SCANCODE_PAGEUP; + io.KeyMap[ImGuiKey_PageDown] = SDL_SCANCODE_PAGEDOWN; + io.KeyMap[ImGuiKey_Home] = SDL_SCANCODE_HOME; + io.KeyMap[ImGuiKey_End] = SDL_SCANCODE_END; + io.KeyMap[ImGuiKey_Delete] = SDLK_DELETE; + io.KeyMap[ImGuiKey_Backspace] = SDLK_BACKSPACE; + io.KeyMap[ImGuiKey_Enter] = SDLK_RETURN; + io.KeyMap[ImGuiKey_Escape] = SDLK_ESCAPE; + io.KeyMap[ImGuiKey_A] = SDLK_a; + io.KeyMap[ImGuiKey_C] = SDLK_c; + io.KeyMap[ImGuiKey_V] = SDLK_v; + io.KeyMap[ImGuiKey_X] = SDLK_x; + io.KeyMap[ImGuiKey_Y] = SDLK_y; + io.KeyMap[ImGuiKey_Z] = SDLK_z; + + io.RenderDrawListsFn = ImGui_ImplSdl_RenderDrawLists; // Alternatively you can set this to NULL and call ImGui::GetDrawData() after ImGui::Render() to get the same ImDrawData pointer. + io.SetClipboardTextFn = ImGui_ImplSdl_SetClipboardText; + io.GetClipboardTextFn = ImGui_ImplSdl_GetClipboardText; + +#ifdef _WIN32 + SDL_SysWMinfo wmInfo; + SDL_VERSION(&wmInfo.version); + SDL_GetWindowWMInfo(window, &wmInfo); + io.ImeWindowHandle = wmInfo.info.win.window; +#else + (void)window; +#endif + + return true; +} + +void ImGui_ImplSdl_Shutdown() +{ + ImGui_ImplSdl_InvalidateDeviceObjects(); + ImGui::Shutdown(); +} + +void ImGui_ImplSdl_NewFrame(SDL_Window *window) +{ + if (!g_FontTexture) + ImGui_ImplSdl_CreateDeviceObjects(); + + ImGuiIO& io = ImGui::GetIO(); + + // Setup display size (every frame to accommodate for window resizing) + int w, h; + int display_w, display_h; + SDL_GetWindowSize(window, &w, &h); + SDL_GL_GetDrawableSize(window, &display_w, &display_h); + io.DisplaySize = ImVec2((float)w, (float)h); + io.DisplayFramebufferScale = ImVec2(w > 0 ? ((float)display_w / w) : 0, h > 0 ? ((float)display_h / h) : 0); + + // Setup time step + Uint32 time = SDL_GetTicks(); + double current_time = time / 1000.0; + io.DeltaTime = g_Time > 0.0 ? (float)(current_time - g_Time) : (float)(1.0f/60.0f); + g_Time = current_time; + + // Setup inputs + // (we already got mouse wheel, keyboard keys & characters from SDL_PollEvent()) + int mx, my; + Uint32 mouseMask = SDL_GetMouseState(&mx, &my); + if (SDL_GetWindowFlags(window) & SDL_WINDOW_MOUSE_FOCUS) + io.MousePos = ImVec2((float)mx, (float)my); // Mouse position, in pixels (set to -1,-1 if no mouse / on another screen, etc.) + else + io.MousePos = ImVec2(-1,-1); + + io.MouseDown[0] = g_MousePressed[0] || (mouseMask & SDL_BUTTON(SDL_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] = g_MousePressed[1] || (mouseMask & SDL_BUTTON(SDL_BUTTON_RIGHT)) != 0; + io.MouseDown[2] = g_MousePressed[2] || (mouseMask & SDL_BUTTON(SDL_BUTTON_MIDDLE)) != 0; + g_MousePressed[0] = g_MousePressed[1] = g_MousePressed[2] = false; + + io.MouseWheel = g_MouseWheel; + g_MouseWheel = 0.0f; + + // Hide OS mouse cursor if ImGui is drawing it + SDL_ShowCursor(io.MouseDrawCursor ? 0 : 1); + + // Start the frame + ImGui::NewFrame(); +} diff --git a/examples/sdl_opengl2_example/imgui_impl_sdl.h b/examples/sdl_opengl2_example/imgui_impl_sdl.h new file mode 100644 index 0000000..a322bf2 --- /dev/null +++ b/examples/sdl_opengl2_example/imgui_impl_sdl.h @@ -0,0 +1,19 @@ +// ImGui SDL2 binding with OpenGL +// In this binding, ImTextureID is used to store an OpenGL 'GLuint' texture identifier. Read the FAQ about ImTextureID in imgui.cpp. + +// You can copy and use unmodified imgui_impl_* files in your project. See main.cpp for an example of using this. +// If you use this binding you'll need to call 4 functions: ImGui_ImplXXXX_Init(), ImGui_ImplXXXX_NewFrame(), ImGui::Render() and ImGui_ImplXXXX_Shutdown(). +// If you are new to ImGui, see examples/README.txt and documentation at the top of imgui.cpp. +// https://github.com/ocornut/imgui + +struct SDL_Window; +typedef union SDL_Event SDL_Event; + +IMGUI_API bool ImGui_ImplSdl_Init(SDL_Window* window); +IMGUI_API void ImGui_ImplSdl_Shutdown(); +IMGUI_API void ImGui_ImplSdl_NewFrame(SDL_Window* window); +IMGUI_API bool ImGui_ImplSdl_ProcessEvent(SDL_Event* event); + +// Use if you want to reset your rendering device without losing ImGui state. +IMGUI_API void ImGui_ImplSdl_InvalidateDeviceObjects(); +IMGUI_API bool ImGui_ImplSdl_CreateDeviceObjects(); diff --git a/examples/README.txt b/examples/README.txt index df2e86d..5a1c8df 100644 --- a/examples/README.txt +++ b/examples/README.txt @@ -8,11 +8,13 @@ TL;DR; - Newcomers, read 'PROGRAMMER GUIDE' in imgui.cpp for notes on how to setup ImGui in your codebase. - - Refer to 'opengl_example' to understand how the library is setup, it is the simplest one. + - Refer to 'opengl2_example' to LEARN how the library is setup, it is the simplest one. The other examples requires more boilerplate and are harder to read. + - If you are using OpenGL in your application, probably use an opengl3_xxx backend. + Mixing old fixed pipeline OpenGL2 and programmable pipeline OpenGL3+ isn't well supported by drivers. - If you are using of the backend provided here, so you can copy the imgui_impl_xxx.cpp/h files to your project and use them unmodified. - - If you have your own engine, you probably want to start from 'opengl_example' and adapt it to + - If you have your own engine, you probably want to start from one of the OpenGL example and adapt it to your engine, but you can read the other examples as well. ImGui is highly portable and only requires a few things to run: @@ -41,15 +43,14 @@ Also note that some setup or GPU drivers may be causing extra lag (possibly by enforcing triple buffering), leaving you with no option but sadness/anger (Intel GPU drivers were reported as such). -opengl_example/ - OpenGL example, using GLFW + fixed pipeline. - This is simple and should work for all OpenGL enabled applications. - Prefer following this example to learn how ImGui works! - (You can use this code in a GL3/GL4 context but make sure you disable the programmable pipeline - by calling "glUseProgram(0)" before ImGui::Render.) +opengl2_example/ + GLFW + OpenGL example (old fixed pipeline). + This is simple to read. Prefer following this example to learn how ImGui works! + (You might be able to use this code in a GL3/GL4 context but make sure you disable the programmable + pipeline by calling "glUseProgram(0)" before ImGui::Render.) opengl3_example/ - OpenGL example, using GLFW/GL3W + programmable pipeline. + GLFW + OpenGL example (programmable pipeline, binding modern functions with GL3W). This uses more modern OpenGL calls and custom shaders. It's more messy. directx9_example/ @@ -68,8 +69,8 @@ On iOS, Using Synergy to access keyboard/mouse data from server computer. Synergy keyboard integration is rather hacky. -sdl_opengl_example/ - SDL2 + OpenGL example. +sdl_opengl2_example/ + SDL2 + OpenGL example (old fixed pipeline). sdl_opengl3_example/ SDL2 + OpenGL3 example. diff --git a/examples/imgui_examples_msvc2010.sln b/examples/imgui_examples_msvc2010.sln index b7e6a25..16f0d60 100644 --- a/examples/imgui_examples_msvc2010.sln +++ b/examples/imgui_examples_msvc2010.sln @@ -1,7 +1,7 @@  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}" +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "opengl2_example", "opengl_example\opengl2_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 diff --git a/examples/opengl2_example/Makefile b/examples/opengl2_example/Makefile new file mode 100644 index 0000000..bd79d1b --- /dev/null +++ b/examples/opengl2_example/Makefile @@ -0,0 +1,60 @@ +# +# Cross Platform Makefile +# Compatible with Ubuntu 14.04.1 and Mac OS X +# +# +# if you using Mac OS X: +# You'll need glfw +# http://www.glfw.org +# + +#CXX = g++ + +EXE = opengl2_example +OBJS = main.o imgui_impl_glfw.o +OBJS += ../../imgui.o ../../imgui_demo.o ../../imgui_draw.o + +UNAME_S := $(shell uname -s) + + +ifeq ($(UNAME_S), Linux) #LINUX + ECHO_MESSAGE = "Linux" + LIBS = -lGL `pkg-config --static --libs glfw3` + + CXXFLAGS = -I../../ `pkg-config --cflags glfw3` + CXXFLAGS += -Wall -Wformat + CFLAGS = $(CXXFLAGS) +endif + +ifeq ($(UNAME_S), Darwin) #APPLE + ECHO_MESSAGE = "Mac OS X" + LIBS = -framework OpenGL -framework Cocoa -framework IOKit -framework CoreVideo + LIBS += -L/usr/local/lib -lglfw3 + + CXXFLAGS = -I../../ -I/usr/local/include + CXXFLAGS += -Wall -Wformat +# CXXFLAGS += -D__APPLE__ + CFLAGS = $(CXXFLAGS) +endif + +ifeq ($(UNAME_S), MINGW64_NT-6.3) + ECHO_MESSAGE = "Windows" + LIBS = -lglfw3 -lgdi32 -lopengl32 -limm32 + + CXXFLAGS = -I../../ -I../libs/gl3w `pkg-config --cflags glfw3` + CXXFLAGS += -Wall -Wformat + CFLAGS = $(CXXFLAGS) +endif + +.cpp.o: + $(CXX) $(CXXFLAGS) -c -o $@ $< + +all: $(EXE) + @echo Build complete for $(ECHO_MESSAGE) + +$(EXE): $(OBJS) + $(CXX) -o $(EXE) $(OBJS) $(CXXFLAGS) $(LIBS) + +clean: + rm $(EXE) $(OBJS) + diff --git a/examples/opengl2_example/build_win32.bat b/examples/opengl2_example/build_win32.bat new file mode 100644 index 0000000..278381c --- /dev/null +++ b/examples/opengl2_example/build_win32.bat @@ -0,0 +1,3 @@ +@REM Build for Visual Studio compiler. Run your copy of vcvars32.bat or vcvarsall.bat to setup command-line compiler. +mkdir Debug +cl /nologo /Zi /MD /I ..\.. /I ..\libs\glfw\include *.cpp ..\..\*.cpp /FeDebug/opengl_example.exe /FoDebug/ /link /LIBPATH:..\libs\glfw\lib-vc2010-32 glfw3.lib opengl32.lib gdi32.lib shell32.lib diff --git a/examples/opengl2_example/imgui_impl_glfw.cpp b/examples/opengl2_example/imgui_impl_glfw.cpp new file mode 100644 index 0000000..2d1f5c1 --- /dev/null +++ b/examples/opengl2_example/imgui_impl_glfw.cpp @@ -0,0 +1,288 @@ +// ImGui GLFW binding with OpenGL +// In this binding, ImTextureID is used to store an OpenGL 'GLuint' texture identifier. Read the FAQ about ImTextureID in imgui.cpp. + +// If your context is GL3/GL3 then prefer using the code in opengl3_example. +// You *might* use this code with a GL3/GL4 context but make sure you disable the programmable pipeline by calling "glUseProgram(0)" before ImGui::Render(). +// We cannot do that from GL2 code because the function doesn't exist. + +// You can copy and use unmodified imgui_impl_* files in your project. See main.cpp for an example of using this. +// If you use this binding you'll need to call 4 functions: ImGui_ImplXXXX_Init(), ImGui_ImplXXXX_NewFrame(), ImGui::Render() and ImGui_ImplXXXX_Shutdown(). +// If you are new to ImGui, see examples/README.txt and documentation at the top of imgui.cpp. +// https://github.com/ocornut/imgui + +#include +#include "imgui_impl_glfw.h" + +// GLFW +#include +#ifdef _WIN32 +#undef APIENTRY +#define GLFW_EXPOSE_NATIVE_WIN32 +#define GLFW_EXPOSE_NATIVE_WGL +#include +#endif + +// Data +static GLFWwindow* g_Window = NULL; +static double g_Time = 0.0f; +static bool g_MousePressed[3] = { false, false, false }; +static float g_MouseWheel = 0.0f; +static GLuint g_FontTexture = 0; + +// 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) +void ImGui_ImplGlfw_RenderDrawLists(ImDrawData* draw_data) +{ + // Avoid rendering when minimized, scale coordinates for retina displays (screen coordinates != framebuffer coordinates) + ImGuiIO& io = ImGui::GetIO(); + int fb_width = (int)(io.DisplaySize.x * io.DisplayFramebufferScale.x); + int fb_height = (int)(io.DisplaySize.y * io.DisplayFramebufferScale.y); + if (fb_width == 0 || fb_height == 0) + return; + draw_data->ScaleClipRects(io.DisplayFramebufferScale); + + // We are using the OpenGL fixed pipeline to make the example code simpler to read! + // Setup render state: alpha-blending enabled, no face culling, no depth testing, scissor enabled, vertex/texcoord/color pointers. + GLint last_texture; glGetIntegerv(GL_TEXTURE_BINDING_2D, &last_texture); + GLint last_viewport[4]; glGetIntegerv(GL_VIEWPORT, last_viewport); + glPushAttrib(GL_ENABLE_BIT | GL_COLOR_BUFFER_BIT | GL_TRANSFORM_BIT); + glEnable(GL_BLEND); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + glDisable(GL_CULL_FACE); + glDisable(GL_DEPTH_TEST); + glEnable(GL_SCISSOR_TEST); + glEnableClientState(GL_VERTEX_ARRAY); + glEnableClientState(GL_TEXTURE_COORD_ARRAY); + glEnableClientState(GL_COLOR_ARRAY); + glEnable(GL_TEXTURE_2D); + //glUseProgram(0); // You may want this if using this code in an OpenGL 3+ context + + // Setup viewport, orthographic projection matrix + glViewport(0, 0, (GLsizei)fb_width, (GLsizei)fb_height); + glMatrixMode(GL_PROJECTION); + glPushMatrix(); + glLoadIdentity(); + glOrtho(0.0f, io.DisplaySize.x, io.DisplaySize.y, 0.0f, -1.0f, +1.0f); + glMatrixMode(GL_MODELVIEW); + glPushMatrix(); + glLoadIdentity(); + + // Render command lists + #define OFFSETOF(TYPE, ELEMENT) ((size_t)&(((TYPE *)0)->ELEMENT)) + for (int n = 0; n < draw_data->CmdListsCount; n++) + { + const ImDrawList* cmd_list = draw_data->CmdLists[n]; + const unsigned char* vtx_buffer = (const unsigned char*)&cmd_list->VtxBuffer.front(); + const ImDrawIdx* idx_buffer = &cmd_list->IdxBuffer.front(); + glVertexPointer(2, GL_FLOAT, sizeof(ImDrawVert), (void*)(vtx_buffer + OFFSETOF(ImDrawVert, pos))); + glTexCoordPointer(2, GL_FLOAT, sizeof(ImDrawVert), (void*)(vtx_buffer + OFFSETOF(ImDrawVert, uv))); + glColorPointer(4, GL_UNSIGNED_BYTE, sizeof(ImDrawVert), (void*)(vtx_buffer + OFFSETOF(ImDrawVert, col))); + + for (int cmd_i = 0; cmd_i < cmd_list->CmdBuffer.size(); cmd_i++) + { + const ImDrawCmd* pcmd = &cmd_list->CmdBuffer[cmd_i]; + if (pcmd->UserCallback) + { + pcmd->UserCallback(cmd_list, pcmd); + } + else + { + glBindTexture(GL_TEXTURE_2D, (GLuint)(intptr_t)pcmd->TextureId); + glScissor((int)pcmd->ClipRect.x, (int)(fb_height - pcmd->ClipRect.w), (int)(pcmd->ClipRect.z - pcmd->ClipRect.x), (int)(pcmd->ClipRect.w - pcmd->ClipRect.y)); + glDrawElements(GL_TRIANGLES, (GLsizei)pcmd->ElemCount, sizeof(ImDrawIdx) == 2 ? GL_UNSIGNED_SHORT : GL_UNSIGNED_INT, idx_buffer); + } + idx_buffer += pcmd->ElemCount; + } + } + #undef OFFSETOF + + // Restore modified state + glDisableClientState(GL_COLOR_ARRAY); + glDisableClientState(GL_TEXTURE_COORD_ARRAY); + glDisableClientState(GL_VERTEX_ARRAY); + glBindTexture(GL_TEXTURE_2D, (GLuint)last_texture); + glMatrixMode(GL_MODELVIEW); + glPopMatrix(); + glMatrixMode(GL_PROJECTION); + glPopMatrix(); + glPopAttrib(); + glViewport(last_viewport[0], last_viewport[1], (GLsizei)last_viewport[2], (GLsizei)last_viewport[3]); +} + +static const char* ImGui_ImplGlfw_GetClipboardText() +{ + return glfwGetClipboardString(g_Window); +} + +static void ImGui_ImplGlfw_SetClipboardText(const char* text) +{ + glfwSetClipboardString(g_Window, text); +} + +void ImGui_ImplGlfw_MouseButtonCallback(GLFWwindow*, int button, int action, int /*mods*/) +{ + if (action == GLFW_PRESS && button >= 0 && button < 3) + g_MousePressed[button] = true; +} + +void ImGui_ImplGlfw_ScrollCallback(GLFWwindow*, double /*xoffset*/, double yoffset) +{ + g_MouseWheel += (float)yoffset; // Use fractional mouse wheel, 1.0 unit 5 lines. +} + +void ImGui_ImplGlFw_KeyCallback(GLFWwindow*, int key, int, int action, int mods) +{ + ImGuiIO& io = ImGui::GetIO(); + if (action == GLFW_PRESS) + io.KeysDown[key] = true; + if (action == GLFW_RELEASE) + io.KeysDown[key] = false; + + (void)mods; // Modifiers are not reliable across systems + io.KeyCtrl = io.KeysDown[GLFW_KEY_LEFT_CONTROL] || io.KeysDown[GLFW_KEY_RIGHT_CONTROL]; + io.KeyShift = io.KeysDown[GLFW_KEY_LEFT_SHIFT] || io.KeysDown[GLFW_KEY_RIGHT_SHIFT]; + io.KeyAlt = io.KeysDown[GLFW_KEY_LEFT_ALT] || io.KeysDown[GLFW_KEY_RIGHT_ALT]; + io.KeySuper = io.KeysDown[GLFW_KEY_LEFT_SUPER] || io.KeysDown[GLFW_KEY_RIGHT_SUPER]; +} + +void ImGui_ImplGlfw_CharCallback(GLFWwindow*, unsigned int c) +{ + ImGuiIO& io = ImGui::GetIO(); + if (c > 0 && c < 0x10000) + io.AddInputCharacter((unsigned short)c); +} + +bool ImGui_ImplGlfw_CreateDeviceObjects() +{ + // Build texture atlas + ImGuiIO& io = ImGui::GetIO(); + unsigned char* pixels; + int width, height; + io.Fonts->GetTexDataAsAlpha8(&pixels, &width, &height); + + // Upload texture to graphics system + GLint last_texture; + glGetIntegerv(GL_TEXTURE_BINDING_2D, &last_texture); + glGenTextures(1, &g_FontTexture); + glBindTexture(GL_TEXTURE_2D, g_FontTexture); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, width, height, 0, GL_ALPHA, GL_UNSIGNED_BYTE, pixels); + + // Store our identifier + io.Fonts->TexID = (void *)(intptr_t)g_FontTexture; + + // Restore state + glBindTexture(GL_TEXTURE_2D, last_texture); + + return true; +} + +void ImGui_ImplGlfw_InvalidateDeviceObjects() +{ + if (g_FontTexture) + { + glDeleteTextures(1, &g_FontTexture); + ImGui::GetIO().Fonts->TexID = 0; + g_FontTexture = 0; + } +} + +bool ImGui_ImplGlfw_Init(GLFWwindow* window, bool install_callbacks) +{ + g_Window = window; + + ImGuiIO& io = ImGui::GetIO(); + 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; + io.KeyMap[ImGuiKey_DownArrow] = GLFW_KEY_DOWN; + io.KeyMap[ImGuiKey_PageUp] = GLFW_KEY_PAGE_UP; + io.KeyMap[ImGuiKey_PageDown] = GLFW_KEY_PAGE_DOWN; + io.KeyMap[ImGuiKey_Home] = GLFW_KEY_HOME; + io.KeyMap[ImGuiKey_End] = GLFW_KEY_END; + io.KeyMap[ImGuiKey_Delete] = GLFW_KEY_DELETE; + io.KeyMap[ImGuiKey_Backspace] = GLFW_KEY_BACKSPACE; + io.KeyMap[ImGuiKey_Enter] = GLFW_KEY_ENTER; + io.KeyMap[ImGuiKey_Escape] = GLFW_KEY_ESCAPE; + io.KeyMap[ImGuiKey_A] = GLFW_KEY_A; + io.KeyMap[ImGuiKey_C] = GLFW_KEY_C; + io.KeyMap[ImGuiKey_V] = GLFW_KEY_V; + io.KeyMap[ImGuiKey_X] = GLFW_KEY_X; + io.KeyMap[ImGuiKey_Y] = GLFW_KEY_Y; + io.KeyMap[ImGuiKey_Z] = GLFW_KEY_Z; + + io.RenderDrawListsFn = ImGui_ImplGlfw_RenderDrawLists; // Alternatively you can set this to NULL and call ImGui::GetDrawData() after ImGui::Render() to get the same ImDrawData pointer. + io.SetClipboardTextFn = ImGui_ImplGlfw_SetClipboardText; + io.GetClipboardTextFn = ImGui_ImplGlfw_GetClipboardText; +#ifdef _WIN32 + io.ImeWindowHandle = glfwGetWin32Window(g_Window); +#endif + + if (install_callbacks) + { + glfwSetMouseButtonCallback(window, ImGui_ImplGlfw_MouseButtonCallback); + glfwSetScrollCallback(window, ImGui_ImplGlfw_ScrollCallback); + glfwSetKeyCallback(window, ImGui_ImplGlFw_KeyCallback); + glfwSetCharCallback(window, ImGui_ImplGlfw_CharCallback); + } + + return true; +} + +void ImGui_ImplGlfw_Shutdown() +{ + ImGui_ImplGlfw_InvalidateDeviceObjects(); + ImGui::Shutdown(); +} + +void ImGui_ImplGlfw_NewFrame() +{ + if (!g_FontTexture) + ImGui_ImplGlfw_CreateDeviceObjects(); + + ImGuiIO& io = ImGui::GetIO(); + + // Setup display size (every frame to accommodate for window resizing) + int w, h; + int display_w, display_h; + glfwGetWindowSize(g_Window, &w, &h); + glfwGetFramebufferSize(g_Window, &display_w, &display_h); + io.DisplaySize = ImVec2((float)w, (float)h); + io.DisplayFramebufferScale = ImVec2(w > 0 ? ((float)display_w / w) : 0, h > 0 ? ((float)display_h / h) : 0); + + // Setup time step + double current_time = glfwGetTime(); + io.DeltaTime = g_Time > 0.0 ? (float)(current_time - g_Time) : (float)(1.0f/60.0f); + g_Time = current_time; + + // Setup inputs + // (we already got mouse wheel, keyboard keys & characters from glfw callbacks polled in glfwPollEvents()) + if (glfwGetWindowAttrib(g_Window, GLFW_FOCUSED)) + { + double mouse_x, mouse_y; + glfwGetCursorPos(g_Window, &mouse_x, &mouse_y); + io.MousePos = ImVec2((float)mouse_x, (float)mouse_y); // Mouse position in screen coordinates (set to -1,-1 if no mouse / on another screen, etc.) + } + else + { + io.MousePos = ImVec2(-1,-1); + } + + for (int i = 0; i < 3; i++) + { + io.MouseDown[i] = g_MousePressed[i] || glfwGetMouseButton(g_Window, i) != 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. + g_MousePressed[i] = false; + } + + io.MouseWheel = g_MouseWheel; + g_MouseWheel = 0.0f; + + // Hide OS mouse cursor if ImGui is drawing it + glfwSetInputMode(g_Window, GLFW_CURSOR, io.MouseDrawCursor ? GLFW_CURSOR_HIDDEN : GLFW_CURSOR_NORMAL); + + // Start the frame + ImGui::NewFrame(); +} diff --git a/examples/opengl2_example/imgui_impl_glfw.h b/examples/opengl2_example/imgui_impl_glfw.h new file mode 100644 index 0000000..07dd96f --- /dev/null +++ b/examples/opengl2_example/imgui_impl_glfw.h @@ -0,0 +1,29 @@ +// ImGui GLFW binding with OpenGL +// In this binding, ImTextureID is used to store an OpenGL 'GLuint' texture identifier. Read the FAQ about ImTextureID in imgui.cpp. + +// If your context is GL3/GL3 then prefer using the code in opengl3_example. +// You *might* use this code with a GL3/GL4 context but make sure you disable the programmable pipeline by calling "glUseProgram(0)" before ImGui::Render(). +// We cannot do that from GL2 code because the function doesn't exist. + +// You can copy and use unmodified imgui_impl_* files in your project. See main.cpp for an example of using this. +// If you use this binding you'll need to call 4 functions: ImGui_ImplXXXX_Init(), ImGui_ImplXXXX_NewFrame(), ImGui::Render() and ImGui_ImplXXXX_Shutdown(). +// If you are new to ImGui, see examples/README.txt and documentation at the top of imgui.cpp. +// https://github.com/ocornut/imgui + +struct GLFWwindow; + +IMGUI_API bool ImGui_ImplGlfw_Init(GLFWwindow* window, bool install_callbacks); +IMGUI_API void ImGui_ImplGlfw_Shutdown(); +IMGUI_API void ImGui_ImplGlfw_NewFrame(); + +// Use if you want to reset your rendering device without losing ImGui state. +IMGUI_API void ImGui_ImplGlfw_InvalidateDeviceObjects(); +IMGUI_API bool ImGui_ImplGlfw_CreateDeviceObjects(); + +// GLFW callbacks (installed by default if you enable 'install_callbacks' during initialization) +// Provided here if you want to chain callbacks. +// You can also handle inputs yourself and use those as a reference. +IMGUI_API void ImGui_ImplGlfw_MouseButtonCallback(GLFWwindow* window, int button, int action, int mods); +IMGUI_API void ImGui_ImplGlfw_ScrollCallback(GLFWwindow* window, double xoffset, double yoffset); +IMGUI_API void ImGui_ImplGlFw_KeyCallback(GLFWwindow* window, int key, int scancode, int action, int mods); +IMGUI_API void ImGui_ImplGlfw_CharCallback(GLFWwindow* window, unsigned int c); diff --git a/examples/opengl2_example/main.cpp b/examples/opengl2_example/main.cpp new file mode 100644 index 0000000..a844db5 --- /dev/null +++ b/examples/opengl2_example/main.cpp @@ -0,0 +1,89 @@ +// ImGui - standalone example application for Glfw + OpenGL 2, using fixed pipeline +// If you are new to ImGui, see examples/README.txt and documentation at the top of imgui.cpp. + +#include +#include "imgui_impl_glfw.h" +#include +#include + +static void error_callback(int error, const char* description) +{ + fprintf(stderr, "Error %d: %s\n", error, description); +} + +int main(int, char**) +{ + // Setup window + glfwSetErrorCallback(error_callback); + if (!glfwInit()) + return 1; + GLFWwindow* window = glfwCreateWindow(1280, 720, "ImGui OpenGL2 example", NULL, NULL); + glfwMakeContextCurrent(window); + + // Setup ImGui binding + ImGui_ImplGlfw_Init(window, true); + + // Load Fonts + // (there is a default font, this is only if you want to change it. see extra_fonts/README.txt for more details) + //ImGuiIO& io = ImGui::GetIO(); + //io.Fonts->AddFontDefault(); + //io.Fonts->AddFontFromFileTTF("../../extra_fonts/Cousine-Regular.ttf", 15.0f); + //io.Fonts->AddFontFromFileTTF("../../extra_fonts/DroidSans.ttf", 16.0f); + //io.Fonts->AddFontFromFileTTF("../../extra_fonts/ProggyClean.ttf", 13.0f); + //io.Fonts->AddFontFromFileTTF("../../extra_fonts/ProggyTiny.ttf", 10.0f); + //io.Fonts->AddFontFromFileTTF("c:\\Windows\\Fonts\\ArialUni.ttf", 18.0f, NULL, io.Fonts->GetGlyphRangesJapanese()); + + bool show_test_window = true; + bool show_another_window = false; + ImVec4 clear_color = ImColor(114, 144, 154); + + // Main loop + while (!glfwWindowShouldClose(window)) + { + glfwPollEvents(); + ImGui_ImplGlfw_NewFrame(); + + // 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 = 0.0f; + ImGui::Text("Hello, world!"); + ImGui::SliderFloat("float", &f, 0.0f, 1.0f); + ImGui::ColorEdit3("clear color", (float*)&clear_color); + if (ImGui::Button("Test Window")) show_test_window ^= 1; + if (ImGui::Button("Another Window")) show_another_window ^= 1; + ImGui::Text("Application average %.3f ms/frame (%.1f FPS)", 1000.0f / ImGui::GetIO().Framerate, ImGui::GetIO().Framerate); + } + + // 2. Show another simple window, this time using an explicit Begin/End pair + if (show_another_window) + { + ImGui::SetNextWindowSize(ImVec2(200,100), ImGuiSetCond_FirstUseEver); + ImGui::Begin("Another Window", &show_another_window); + 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::SetNextWindowPos(ImVec2(650, 20), ImGuiSetCond_FirstUseEver); + ImGui::ShowTestWindow(&show_test_window); + } + + // Rendering + int display_w, display_h; + glfwGetFramebufferSize(window, &display_w, &display_h); + glViewport(0, 0, display_w, display_h); + glClearColor(clear_color.x, clear_color.y, clear_color.z, clear_color.w); + glClear(GL_COLOR_BUFFER_BIT); + ImGui::Render(); + glfwSwapBuffers(window); + } + + // Cleanup + ImGui_ImplGlfw_Shutdown(); + glfwTerminate(); + + return 0; +} diff --git a/examples/opengl2_example/opengl_example.vcxproj b/examples/opengl2_example/opengl_example.vcxproj new file mode 100644 index 0000000..4b354b6 --- /dev/null +++ b/examples/opengl2_example/opengl_example.vcxproj @@ -0,0 +1,169 @@ + + + + + Debug + Win32 + + + Debug + x64 + + + Release + Win32 + + + Release + x64 + + + + {9CDA7840-B7A5-496D-A527-E95571496D18} + opengl_example + + + + Application + true + MultiByte + + + Application + true + MultiByte + + + Application + false + true + MultiByte + + + Application + false + true + MultiByte + + + + + + + + + + + + + + + + + + + $(ProjectDir)$(Configuration)\ + $(ProjectDir)$(Configuration)\ + $(IncludePath) + + + $(ProjectDir)$(Configuration)\ + $(ProjectDir)$(Configuration)\ + $(IncludePath) + + + $(ProjectDir)$(Configuration)\ + $(ProjectDir)$(Configuration)\ + $(IncludePath) + + + $(ProjectDir)$(Configuration)\ + $(ProjectDir)$(Configuration)\ + $(IncludePath) + + + + Level4 + Disabled + $(SolutionDir)\libs\glfw\include;..\..;%(AdditionalIncludeDirectories) + + + true + $(SolutionDir)\libs\glfw\lib-vc2010-32;%(AdditionalLibraryDirectories) + opengl32.lib;glfw3.lib;%(AdditionalDependencies) + Console + msvcrt.lib + + + + + Level4 + Disabled + $(SolutionDir)\libs\glfw\include;..\..;%(AdditionalIncludeDirectories) + + + true + $(SolutionDir)\libs\glfw\lib-vc2010-64;%(AdditionalLibraryDirectories) + opengl32.lib;glfw3.lib;%(AdditionalDependencies) + Console + msvcrt.lib + + + + + Level4 + MaxSpeed + true + true + $(SolutionDir)\libs\glfw\include;..\..;%(AdditionalIncludeDirectories) + + + true + true + true + $(SolutionDir)\libs\glfw\lib-vc2010-32;%(AdditionalLibraryDirectories) + opengl32.lib;glfw3.lib;%(AdditionalDependencies) + Console + + + + + + + Level4 + MaxSpeed + true + true + $(SolutionDir)\libs\glfw\include;..\..;%(AdditionalIncludeDirectories) + + + true + true + true + $(SolutionDir)\libs\glfw\lib-vc2010-64;%(AdditionalLibraryDirectories) + opengl32.lib;glfw3.lib;%(AdditionalDependencies) + Console + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/examples/opengl2_example/opengl_example.vcxproj.filters b/examples/opengl2_example/opengl_example.vcxproj.filters new file mode 100644 index 0000000..f2282bf --- /dev/null +++ b/examples/opengl2_example/opengl_example.vcxproj.filters @@ -0,0 +1,46 @@ + + + + + {c336cfe3-f0c4-464c-9ef0-a9e17a7ff222} + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx + + + + + sources + + + imgui + + + sources + + + imgui + + + imgui + + + + + imgui + + + imgui + + + sources + + + imgui + + + + + + \ No newline at end of file diff --git a/examples/opengl_example/Makefile b/examples/opengl_example/Makefile deleted file mode 100644 index 91d1b14..0000000 --- a/examples/opengl_example/Makefile +++ /dev/null @@ -1,60 +0,0 @@ -# -# Cross Platform Makefile -# Compatible with Ubuntu 14.04.1 and Mac OS X -# -# -# if you using Mac OS X: -# You'll need glfw -# http://www.glfw.org -# - -#CXX = g++ - -EXE = opengl_example -OBJS = main.o imgui_impl_glfw.o -OBJS += ../../imgui.o ../../imgui_demo.o ../../imgui_draw.o - -UNAME_S := $(shell uname -s) - - -ifeq ($(UNAME_S), Linux) #LINUX - ECHO_MESSAGE = "Linux" - LIBS = -lGL `pkg-config --static --libs glfw3` - - CXXFLAGS = -I../../ `pkg-config --cflags glfw3` - CXXFLAGS += -Wall -Wformat - CFLAGS = $(CXXFLAGS) -endif - -ifeq ($(UNAME_S), Darwin) #APPLE - ECHO_MESSAGE = "Mac OS X" - LIBS = -framework OpenGL -framework Cocoa -framework IOKit -framework CoreVideo - LIBS += -L/usr/local/lib -lglfw3 - - CXXFLAGS = -I../../ -I/usr/local/include - CXXFLAGS += -Wall -Wformat -# CXXFLAGS += -D__APPLE__ - CFLAGS = $(CXXFLAGS) -endif - -ifeq ($(UNAME_S), MINGW64_NT-6.3) - ECHO_MESSAGE = "Windows" - LIBS = -lglfw3 -lgdi32 -lopengl32 -limm32 - - CXXFLAGS = -I../../ -I../libs/gl3w `pkg-config --cflags glfw3` - CXXFLAGS += -Wall -Wformat - CFLAGS = $(CXXFLAGS) -endif - -.cpp.o: - $(CXX) $(CXXFLAGS) -c -o $@ $< - -all: $(EXE) - @echo Build complete for $(ECHO_MESSAGE) - -$(EXE): $(OBJS) - $(CXX) -o $(EXE) $(OBJS) $(CXXFLAGS) $(LIBS) - -clean: - rm $(EXE) $(OBJS) - diff --git a/examples/opengl_example/build_win32.bat b/examples/opengl_example/build_win32.bat deleted file mode 100644 index 278381c..0000000 --- a/examples/opengl_example/build_win32.bat +++ /dev/null @@ -1,3 +0,0 @@ -@REM Build for Visual Studio compiler. Run your copy of vcvars32.bat or vcvarsall.bat to setup command-line compiler. -mkdir Debug -cl /nologo /Zi /MD /I ..\.. /I ..\libs\glfw\include *.cpp ..\..\*.cpp /FeDebug/opengl_example.exe /FoDebug/ /link /LIBPATH:..\libs\glfw\lib-vc2010-32 glfw3.lib opengl32.lib gdi32.lib shell32.lib diff --git a/examples/opengl_example/imgui_impl_glfw.cpp b/examples/opengl_example/imgui_impl_glfw.cpp deleted file mode 100644 index 2d1f5c1..0000000 --- a/examples/opengl_example/imgui_impl_glfw.cpp +++ /dev/null @@ -1,288 +0,0 @@ -// ImGui GLFW binding with OpenGL -// In this binding, ImTextureID is used to store an OpenGL 'GLuint' texture identifier. Read the FAQ about ImTextureID in imgui.cpp. - -// If your context is GL3/GL3 then prefer using the code in opengl3_example. -// You *might* use this code with a GL3/GL4 context but make sure you disable the programmable pipeline by calling "glUseProgram(0)" before ImGui::Render(). -// We cannot do that from GL2 code because the function doesn't exist. - -// You can copy and use unmodified imgui_impl_* files in your project. See main.cpp for an example of using this. -// If you use this binding you'll need to call 4 functions: ImGui_ImplXXXX_Init(), ImGui_ImplXXXX_NewFrame(), ImGui::Render() and ImGui_ImplXXXX_Shutdown(). -// If you are new to ImGui, see examples/README.txt and documentation at the top of imgui.cpp. -// https://github.com/ocornut/imgui - -#include -#include "imgui_impl_glfw.h" - -// GLFW -#include -#ifdef _WIN32 -#undef APIENTRY -#define GLFW_EXPOSE_NATIVE_WIN32 -#define GLFW_EXPOSE_NATIVE_WGL -#include -#endif - -// Data -static GLFWwindow* g_Window = NULL; -static double g_Time = 0.0f; -static bool g_MousePressed[3] = { false, false, false }; -static float g_MouseWheel = 0.0f; -static GLuint g_FontTexture = 0; - -// 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) -void ImGui_ImplGlfw_RenderDrawLists(ImDrawData* draw_data) -{ - // Avoid rendering when minimized, scale coordinates for retina displays (screen coordinates != framebuffer coordinates) - ImGuiIO& io = ImGui::GetIO(); - int fb_width = (int)(io.DisplaySize.x * io.DisplayFramebufferScale.x); - int fb_height = (int)(io.DisplaySize.y * io.DisplayFramebufferScale.y); - if (fb_width == 0 || fb_height == 0) - return; - draw_data->ScaleClipRects(io.DisplayFramebufferScale); - - // We are using the OpenGL fixed pipeline to make the example code simpler to read! - // Setup render state: alpha-blending enabled, no face culling, no depth testing, scissor enabled, vertex/texcoord/color pointers. - GLint last_texture; glGetIntegerv(GL_TEXTURE_BINDING_2D, &last_texture); - GLint last_viewport[4]; glGetIntegerv(GL_VIEWPORT, last_viewport); - glPushAttrib(GL_ENABLE_BIT | GL_COLOR_BUFFER_BIT | GL_TRANSFORM_BIT); - glEnable(GL_BLEND); - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - glDisable(GL_CULL_FACE); - glDisable(GL_DEPTH_TEST); - glEnable(GL_SCISSOR_TEST); - glEnableClientState(GL_VERTEX_ARRAY); - glEnableClientState(GL_TEXTURE_COORD_ARRAY); - glEnableClientState(GL_COLOR_ARRAY); - glEnable(GL_TEXTURE_2D); - //glUseProgram(0); // You may want this if using this code in an OpenGL 3+ context - - // Setup viewport, orthographic projection matrix - glViewport(0, 0, (GLsizei)fb_width, (GLsizei)fb_height); - glMatrixMode(GL_PROJECTION); - glPushMatrix(); - glLoadIdentity(); - glOrtho(0.0f, io.DisplaySize.x, io.DisplaySize.y, 0.0f, -1.0f, +1.0f); - glMatrixMode(GL_MODELVIEW); - glPushMatrix(); - glLoadIdentity(); - - // Render command lists - #define OFFSETOF(TYPE, ELEMENT) ((size_t)&(((TYPE *)0)->ELEMENT)) - for (int n = 0; n < draw_data->CmdListsCount; n++) - { - const ImDrawList* cmd_list = draw_data->CmdLists[n]; - const unsigned char* vtx_buffer = (const unsigned char*)&cmd_list->VtxBuffer.front(); - const ImDrawIdx* idx_buffer = &cmd_list->IdxBuffer.front(); - glVertexPointer(2, GL_FLOAT, sizeof(ImDrawVert), (void*)(vtx_buffer + OFFSETOF(ImDrawVert, pos))); - glTexCoordPointer(2, GL_FLOAT, sizeof(ImDrawVert), (void*)(vtx_buffer + OFFSETOF(ImDrawVert, uv))); - glColorPointer(4, GL_UNSIGNED_BYTE, sizeof(ImDrawVert), (void*)(vtx_buffer + OFFSETOF(ImDrawVert, col))); - - for (int cmd_i = 0; cmd_i < cmd_list->CmdBuffer.size(); cmd_i++) - { - const ImDrawCmd* pcmd = &cmd_list->CmdBuffer[cmd_i]; - if (pcmd->UserCallback) - { - pcmd->UserCallback(cmd_list, pcmd); - } - else - { - glBindTexture(GL_TEXTURE_2D, (GLuint)(intptr_t)pcmd->TextureId); - glScissor((int)pcmd->ClipRect.x, (int)(fb_height - pcmd->ClipRect.w), (int)(pcmd->ClipRect.z - pcmd->ClipRect.x), (int)(pcmd->ClipRect.w - pcmd->ClipRect.y)); - glDrawElements(GL_TRIANGLES, (GLsizei)pcmd->ElemCount, sizeof(ImDrawIdx) == 2 ? GL_UNSIGNED_SHORT : GL_UNSIGNED_INT, idx_buffer); - } - idx_buffer += pcmd->ElemCount; - } - } - #undef OFFSETOF - - // Restore modified state - glDisableClientState(GL_COLOR_ARRAY); - glDisableClientState(GL_TEXTURE_COORD_ARRAY); - glDisableClientState(GL_VERTEX_ARRAY); - glBindTexture(GL_TEXTURE_2D, (GLuint)last_texture); - glMatrixMode(GL_MODELVIEW); - glPopMatrix(); - glMatrixMode(GL_PROJECTION); - glPopMatrix(); - glPopAttrib(); - glViewport(last_viewport[0], last_viewport[1], (GLsizei)last_viewport[2], (GLsizei)last_viewport[3]); -} - -static const char* ImGui_ImplGlfw_GetClipboardText() -{ - return glfwGetClipboardString(g_Window); -} - -static void ImGui_ImplGlfw_SetClipboardText(const char* text) -{ - glfwSetClipboardString(g_Window, text); -} - -void ImGui_ImplGlfw_MouseButtonCallback(GLFWwindow*, int button, int action, int /*mods*/) -{ - if (action == GLFW_PRESS && button >= 0 && button < 3) - g_MousePressed[button] = true; -} - -void ImGui_ImplGlfw_ScrollCallback(GLFWwindow*, double /*xoffset*/, double yoffset) -{ - g_MouseWheel += (float)yoffset; // Use fractional mouse wheel, 1.0 unit 5 lines. -} - -void ImGui_ImplGlFw_KeyCallback(GLFWwindow*, int key, int, int action, int mods) -{ - ImGuiIO& io = ImGui::GetIO(); - if (action == GLFW_PRESS) - io.KeysDown[key] = true; - if (action == GLFW_RELEASE) - io.KeysDown[key] = false; - - (void)mods; // Modifiers are not reliable across systems - io.KeyCtrl = io.KeysDown[GLFW_KEY_LEFT_CONTROL] || io.KeysDown[GLFW_KEY_RIGHT_CONTROL]; - io.KeyShift = io.KeysDown[GLFW_KEY_LEFT_SHIFT] || io.KeysDown[GLFW_KEY_RIGHT_SHIFT]; - io.KeyAlt = io.KeysDown[GLFW_KEY_LEFT_ALT] || io.KeysDown[GLFW_KEY_RIGHT_ALT]; - io.KeySuper = io.KeysDown[GLFW_KEY_LEFT_SUPER] || io.KeysDown[GLFW_KEY_RIGHT_SUPER]; -} - -void ImGui_ImplGlfw_CharCallback(GLFWwindow*, unsigned int c) -{ - ImGuiIO& io = ImGui::GetIO(); - if (c > 0 && c < 0x10000) - io.AddInputCharacter((unsigned short)c); -} - -bool ImGui_ImplGlfw_CreateDeviceObjects() -{ - // Build texture atlas - ImGuiIO& io = ImGui::GetIO(); - unsigned char* pixels; - int width, height; - io.Fonts->GetTexDataAsAlpha8(&pixels, &width, &height); - - // Upload texture to graphics system - GLint last_texture; - glGetIntegerv(GL_TEXTURE_BINDING_2D, &last_texture); - glGenTextures(1, &g_FontTexture); - glBindTexture(GL_TEXTURE_2D, g_FontTexture); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, width, height, 0, GL_ALPHA, GL_UNSIGNED_BYTE, pixels); - - // Store our identifier - io.Fonts->TexID = (void *)(intptr_t)g_FontTexture; - - // Restore state - glBindTexture(GL_TEXTURE_2D, last_texture); - - return true; -} - -void ImGui_ImplGlfw_InvalidateDeviceObjects() -{ - if (g_FontTexture) - { - glDeleteTextures(1, &g_FontTexture); - ImGui::GetIO().Fonts->TexID = 0; - g_FontTexture = 0; - } -} - -bool ImGui_ImplGlfw_Init(GLFWwindow* window, bool install_callbacks) -{ - g_Window = window; - - ImGuiIO& io = ImGui::GetIO(); - 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; - io.KeyMap[ImGuiKey_DownArrow] = GLFW_KEY_DOWN; - io.KeyMap[ImGuiKey_PageUp] = GLFW_KEY_PAGE_UP; - io.KeyMap[ImGuiKey_PageDown] = GLFW_KEY_PAGE_DOWN; - io.KeyMap[ImGuiKey_Home] = GLFW_KEY_HOME; - io.KeyMap[ImGuiKey_End] = GLFW_KEY_END; - io.KeyMap[ImGuiKey_Delete] = GLFW_KEY_DELETE; - io.KeyMap[ImGuiKey_Backspace] = GLFW_KEY_BACKSPACE; - io.KeyMap[ImGuiKey_Enter] = GLFW_KEY_ENTER; - io.KeyMap[ImGuiKey_Escape] = GLFW_KEY_ESCAPE; - io.KeyMap[ImGuiKey_A] = GLFW_KEY_A; - io.KeyMap[ImGuiKey_C] = GLFW_KEY_C; - io.KeyMap[ImGuiKey_V] = GLFW_KEY_V; - io.KeyMap[ImGuiKey_X] = GLFW_KEY_X; - io.KeyMap[ImGuiKey_Y] = GLFW_KEY_Y; - io.KeyMap[ImGuiKey_Z] = GLFW_KEY_Z; - - io.RenderDrawListsFn = ImGui_ImplGlfw_RenderDrawLists; // Alternatively you can set this to NULL and call ImGui::GetDrawData() after ImGui::Render() to get the same ImDrawData pointer. - io.SetClipboardTextFn = ImGui_ImplGlfw_SetClipboardText; - io.GetClipboardTextFn = ImGui_ImplGlfw_GetClipboardText; -#ifdef _WIN32 - io.ImeWindowHandle = glfwGetWin32Window(g_Window); -#endif - - if (install_callbacks) - { - glfwSetMouseButtonCallback(window, ImGui_ImplGlfw_MouseButtonCallback); - glfwSetScrollCallback(window, ImGui_ImplGlfw_ScrollCallback); - glfwSetKeyCallback(window, ImGui_ImplGlFw_KeyCallback); - glfwSetCharCallback(window, ImGui_ImplGlfw_CharCallback); - } - - return true; -} - -void ImGui_ImplGlfw_Shutdown() -{ - ImGui_ImplGlfw_InvalidateDeviceObjects(); - ImGui::Shutdown(); -} - -void ImGui_ImplGlfw_NewFrame() -{ - if (!g_FontTexture) - ImGui_ImplGlfw_CreateDeviceObjects(); - - ImGuiIO& io = ImGui::GetIO(); - - // Setup display size (every frame to accommodate for window resizing) - int w, h; - int display_w, display_h; - glfwGetWindowSize(g_Window, &w, &h); - glfwGetFramebufferSize(g_Window, &display_w, &display_h); - io.DisplaySize = ImVec2((float)w, (float)h); - io.DisplayFramebufferScale = ImVec2(w > 0 ? ((float)display_w / w) : 0, h > 0 ? ((float)display_h / h) : 0); - - // Setup time step - double current_time = glfwGetTime(); - io.DeltaTime = g_Time > 0.0 ? (float)(current_time - g_Time) : (float)(1.0f/60.0f); - g_Time = current_time; - - // Setup inputs - // (we already got mouse wheel, keyboard keys & characters from glfw callbacks polled in glfwPollEvents()) - if (glfwGetWindowAttrib(g_Window, GLFW_FOCUSED)) - { - double mouse_x, mouse_y; - glfwGetCursorPos(g_Window, &mouse_x, &mouse_y); - io.MousePos = ImVec2((float)mouse_x, (float)mouse_y); // Mouse position in screen coordinates (set to -1,-1 if no mouse / on another screen, etc.) - } - else - { - io.MousePos = ImVec2(-1,-1); - } - - for (int i = 0; i < 3; i++) - { - io.MouseDown[i] = g_MousePressed[i] || glfwGetMouseButton(g_Window, i) != 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. - g_MousePressed[i] = false; - } - - io.MouseWheel = g_MouseWheel; - g_MouseWheel = 0.0f; - - // Hide OS mouse cursor if ImGui is drawing it - glfwSetInputMode(g_Window, GLFW_CURSOR, io.MouseDrawCursor ? GLFW_CURSOR_HIDDEN : GLFW_CURSOR_NORMAL); - - // Start the frame - ImGui::NewFrame(); -} diff --git a/examples/opengl_example/imgui_impl_glfw.h b/examples/opengl_example/imgui_impl_glfw.h deleted file mode 100644 index 07dd96f..0000000 --- a/examples/opengl_example/imgui_impl_glfw.h +++ /dev/null @@ -1,29 +0,0 @@ -// ImGui GLFW binding with OpenGL -// In this binding, ImTextureID is used to store an OpenGL 'GLuint' texture identifier. Read the FAQ about ImTextureID in imgui.cpp. - -// If your context is GL3/GL3 then prefer using the code in opengl3_example. -// You *might* use this code with a GL3/GL4 context but make sure you disable the programmable pipeline by calling "glUseProgram(0)" before ImGui::Render(). -// We cannot do that from GL2 code because the function doesn't exist. - -// You can copy and use unmodified imgui_impl_* files in your project. See main.cpp for an example of using this. -// If you use this binding you'll need to call 4 functions: ImGui_ImplXXXX_Init(), ImGui_ImplXXXX_NewFrame(), ImGui::Render() and ImGui_ImplXXXX_Shutdown(). -// If you are new to ImGui, see examples/README.txt and documentation at the top of imgui.cpp. -// https://github.com/ocornut/imgui - -struct GLFWwindow; - -IMGUI_API bool ImGui_ImplGlfw_Init(GLFWwindow* window, bool install_callbacks); -IMGUI_API void ImGui_ImplGlfw_Shutdown(); -IMGUI_API void ImGui_ImplGlfw_NewFrame(); - -// Use if you want to reset your rendering device without losing ImGui state. -IMGUI_API void ImGui_ImplGlfw_InvalidateDeviceObjects(); -IMGUI_API bool ImGui_ImplGlfw_CreateDeviceObjects(); - -// GLFW callbacks (installed by default if you enable 'install_callbacks' during initialization) -// Provided here if you want to chain callbacks. -// You can also handle inputs yourself and use those as a reference. -IMGUI_API void ImGui_ImplGlfw_MouseButtonCallback(GLFWwindow* window, int button, int action, int mods); -IMGUI_API void ImGui_ImplGlfw_ScrollCallback(GLFWwindow* window, double xoffset, double yoffset); -IMGUI_API void ImGui_ImplGlFw_KeyCallback(GLFWwindow* window, int key, int scancode, int action, int mods); -IMGUI_API void ImGui_ImplGlfw_CharCallback(GLFWwindow* window, unsigned int c); diff --git a/examples/opengl_example/main.cpp b/examples/opengl_example/main.cpp deleted file mode 100644 index a844db5..0000000 --- a/examples/opengl_example/main.cpp +++ /dev/null @@ -1,89 +0,0 @@ -// ImGui - standalone example application for Glfw + OpenGL 2, using fixed pipeline -// If you are new to ImGui, see examples/README.txt and documentation at the top of imgui.cpp. - -#include -#include "imgui_impl_glfw.h" -#include -#include - -static void error_callback(int error, const char* description) -{ - fprintf(stderr, "Error %d: %s\n", error, description); -} - -int main(int, char**) -{ - // Setup window - glfwSetErrorCallback(error_callback); - if (!glfwInit()) - return 1; - GLFWwindow* window = glfwCreateWindow(1280, 720, "ImGui OpenGL2 example", NULL, NULL); - glfwMakeContextCurrent(window); - - // Setup ImGui binding - ImGui_ImplGlfw_Init(window, true); - - // Load Fonts - // (there is a default font, this is only if you want to change it. see extra_fonts/README.txt for more details) - //ImGuiIO& io = ImGui::GetIO(); - //io.Fonts->AddFontDefault(); - //io.Fonts->AddFontFromFileTTF("../../extra_fonts/Cousine-Regular.ttf", 15.0f); - //io.Fonts->AddFontFromFileTTF("../../extra_fonts/DroidSans.ttf", 16.0f); - //io.Fonts->AddFontFromFileTTF("../../extra_fonts/ProggyClean.ttf", 13.0f); - //io.Fonts->AddFontFromFileTTF("../../extra_fonts/ProggyTiny.ttf", 10.0f); - //io.Fonts->AddFontFromFileTTF("c:\\Windows\\Fonts\\ArialUni.ttf", 18.0f, NULL, io.Fonts->GetGlyphRangesJapanese()); - - bool show_test_window = true; - bool show_another_window = false; - ImVec4 clear_color = ImColor(114, 144, 154); - - // Main loop - while (!glfwWindowShouldClose(window)) - { - glfwPollEvents(); - ImGui_ImplGlfw_NewFrame(); - - // 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 = 0.0f; - ImGui::Text("Hello, world!"); - ImGui::SliderFloat("float", &f, 0.0f, 1.0f); - ImGui::ColorEdit3("clear color", (float*)&clear_color); - if (ImGui::Button("Test Window")) show_test_window ^= 1; - if (ImGui::Button("Another Window")) show_another_window ^= 1; - ImGui::Text("Application average %.3f ms/frame (%.1f FPS)", 1000.0f / ImGui::GetIO().Framerate, ImGui::GetIO().Framerate); - } - - // 2. Show another simple window, this time using an explicit Begin/End pair - if (show_another_window) - { - ImGui::SetNextWindowSize(ImVec2(200,100), ImGuiSetCond_FirstUseEver); - ImGui::Begin("Another Window", &show_another_window); - 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::SetNextWindowPos(ImVec2(650, 20), ImGuiSetCond_FirstUseEver); - ImGui::ShowTestWindow(&show_test_window); - } - - // Rendering - int display_w, display_h; - glfwGetFramebufferSize(window, &display_w, &display_h); - glViewport(0, 0, display_w, display_h); - glClearColor(clear_color.x, clear_color.y, clear_color.z, clear_color.w); - glClear(GL_COLOR_BUFFER_BIT); - ImGui::Render(); - glfwSwapBuffers(window); - } - - // Cleanup - ImGui_ImplGlfw_Shutdown(); - glfwTerminate(); - - return 0; -} diff --git a/examples/opengl_example/opengl_example.vcxproj b/examples/opengl_example/opengl_example.vcxproj deleted file mode 100644 index 4b354b6..0000000 --- a/examples/opengl_example/opengl_example.vcxproj +++ /dev/null @@ -1,169 +0,0 @@ - - - - - Debug - Win32 - - - Debug - x64 - - - Release - Win32 - - - Release - x64 - - - - {9CDA7840-B7A5-496D-A527-E95571496D18} - opengl_example - - - - Application - true - MultiByte - - - Application - true - MultiByte - - - Application - false - true - MultiByte - - - Application - false - true - MultiByte - - - - - - - - - - - - - - - - - - - $(ProjectDir)$(Configuration)\ - $(ProjectDir)$(Configuration)\ - $(IncludePath) - - - $(ProjectDir)$(Configuration)\ - $(ProjectDir)$(Configuration)\ - $(IncludePath) - - - $(ProjectDir)$(Configuration)\ - $(ProjectDir)$(Configuration)\ - $(IncludePath) - - - $(ProjectDir)$(Configuration)\ - $(ProjectDir)$(Configuration)\ - $(IncludePath) - - - - Level4 - Disabled - $(SolutionDir)\libs\glfw\include;..\..;%(AdditionalIncludeDirectories) - - - true - $(SolutionDir)\libs\glfw\lib-vc2010-32;%(AdditionalLibraryDirectories) - opengl32.lib;glfw3.lib;%(AdditionalDependencies) - Console - msvcrt.lib - - - - - Level4 - Disabled - $(SolutionDir)\libs\glfw\include;..\..;%(AdditionalIncludeDirectories) - - - true - $(SolutionDir)\libs\glfw\lib-vc2010-64;%(AdditionalLibraryDirectories) - opengl32.lib;glfw3.lib;%(AdditionalDependencies) - Console - msvcrt.lib - - - - - Level4 - MaxSpeed - true - true - $(SolutionDir)\libs\glfw\include;..\..;%(AdditionalIncludeDirectories) - - - true - true - true - $(SolutionDir)\libs\glfw\lib-vc2010-32;%(AdditionalLibraryDirectories) - opengl32.lib;glfw3.lib;%(AdditionalDependencies) - Console - - - - - - - Level4 - MaxSpeed - true - true - $(SolutionDir)\libs\glfw\include;..\..;%(AdditionalIncludeDirectories) - - - true - true - true - $(SolutionDir)\libs\glfw\lib-vc2010-64;%(AdditionalLibraryDirectories) - opengl32.lib;glfw3.lib;%(AdditionalDependencies) - Console - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/examples/opengl_example/opengl_example.vcxproj.filters b/examples/opengl_example/opengl_example.vcxproj.filters deleted file mode 100644 index f2282bf..0000000 --- a/examples/opengl_example/opengl_example.vcxproj.filters +++ /dev/null @@ -1,46 +0,0 @@ - - - - - {c336cfe3-f0c4-464c-9ef0-a9e17a7ff222} - - - {4FC737F1-C7A5-4376-A066-2A32D752A2FF} - cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx - - - - - sources - - - imgui - - - sources - - - imgui - - - imgui - - - - - imgui - - - imgui - - - sources - - - imgui - - - - - - \ No newline at end of file diff --git a/examples/sdl_opengl2_example/README.md b/examples/sdl_opengl2_example/README.md new file mode 100644 index 0000000..aada45d --- /dev/null +++ b/examples/sdl_opengl2_example/README.md @@ -0,0 +1,22 @@ + +# How to Build + +- On Windows with Visual Studio's CLI + +``` +set SDL2DIR=path_to_your_sdl2_folder +cl /Zi /MD /I %SDL2DIR%\include> /I ..\.. main.cpp imgui_impl_sdl.cpp ..\..\imgui*.cpp /link /LIBPATH:%SDL2DIR%\lib SDL2.lib SDL2main.lib +``` + +- On Linux and similar Unixes + +``` +c++ `sdl2-config --cflags` -I ../.. main.cpp imgui_impl_sdl.cpp ../../imgui*.cpp `sdl2-config --libs` -lGL -o sdl2example +``` + +- On Mac OS X + +``` +brew install sdl2 +c++ `sdl2-config --cflags` -I ../.. main.cpp imgui_impl_sdl.cpp ../../imgui*.cpp `sdl2-config --libs` -framework OpenGl -o sdl2example +``` diff --git a/examples/sdl_opengl2_example/imgui_impl_sdl.cpp b/examples/sdl_opengl2_example/imgui_impl_sdl.cpp new file mode 100644 index 0000000..63ed9f4 --- /dev/null +++ b/examples/sdl_opengl2_example/imgui_impl_sdl.cpp @@ -0,0 +1,277 @@ +// ImGui SDL2 binding with OpenGL +// In this binding, ImTextureID is used to store an OpenGL 'GLuint' texture identifier. Read the FAQ about ImTextureID in imgui.cpp. + +// You can copy and use unmodified imgui_impl_* files in your project. See main.cpp for an example of using this. +// If you use this binding you'll need to call 4 functions: ImGui_ImplXXXX_Init(), ImGui_ImplXXXX_NewFrame(), ImGui::Render() and ImGui_ImplXXXX_Shutdown(). +// If you are new to ImGui, see examples/README.txt and documentation at the top of imgui.cpp. +// https://github.com/ocornut/imgui + +#include +#include +#include +#include +#include "imgui_impl_sdl.h" + +// Data +static double g_Time = 0.0f; +static bool g_MousePressed[3] = { false, false, false }; +static float g_MouseWheel = 0.0f; +static GLuint g_FontTexture = 0; + +// 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) +void ImGui_ImplSdl_RenderDrawLists(ImDrawData* draw_data) +{ + // Avoid rendering when minimized, scale coordinates for retina displays (screen coordinates != framebuffer coordinates) + ImGuiIO& io = ImGui::GetIO(); + int fb_width = (int)(io.DisplaySize.x * io.DisplayFramebufferScale.x); + int fb_height = (int)(io.DisplaySize.y * io.DisplayFramebufferScale.y); + if (fb_width == 0 || fb_height == 0) + return; + draw_data->ScaleClipRects(io.DisplayFramebufferScale); + + // We are using the OpenGL fixed pipeline to make the example code simpler to read! + // Setup render state: alpha-blending enabled, no face culling, no depth testing, scissor enabled, vertex/texcoord/color pointers. + GLint last_texture; glGetIntegerv(GL_TEXTURE_BINDING_2D, &last_texture); + GLint last_viewport[4]; glGetIntegerv(GL_VIEWPORT, last_viewport); + glPushAttrib(GL_ENABLE_BIT | GL_COLOR_BUFFER_BIT | GL_TRANSFORM_BIT); + glEnable(GL_BLEND); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + glDisable(GL_CULL_FACE); + glDisable(GL_DEPTH_TEST); + glEnable(GL_SCISSOR_TEST); + glEnableClientState(GL_VERTEX_ARRAY); + glEnableClientState(GL_TEXTURE_COORD_ARRAY); + glEnableClientState(GL_COLOR_ARRAY); + glEnable(GL_TEXTURE_2D); + //glUseProgram(0); // You may want this if using this code in an OpenGL 3+ context + + // Setup viewport, orthographic projection matrix + glViewport(0, 0, (GLsizei)fb_width, (GLsizei)fb_height); + glMatrixMode(GL_PROJECTION); + glPushMatrix(); + glLoadIdentity(); + glOrtho(0.0f, io.DisplaySize.x, io.DisplaySize.y, 0.0f, -1.0f, +1.0f); + glMatrixMode(GL_MODELVIEW); + glPushMatrix(); + glLoadIdentity(); + + // Render command lists + #define OFFSETOF(TYPE, ELEMENT) ((size_t)&(((TYPE *)0)->ELEMENT)) + for (int n = 0; n < draw_data->CmdListsCount; n++) + { + const ImDrawList* cmd_list = draw_data->CmdLists[n]; + const unsigned char* vtx_buffer = (const unsigned char*)&cmd_list->VtxBuffer.front(); + const ImDrawIdx* idx_buffer = &cmd_list->IdxBuffer.front(); + glVertexPointer(2, GL_FLOAT, sizeof(ImDrawVert), (void*)(vtx_buffer + OFFSETOF(ImDrawVert, pos))); + glTexCoordPointer(2, GL_FLOAT, sizeof(ImDrawVert), (void*)(vtx_buffer + OFFSETOF(ImDrawVert, uv))); + glColorPointer(4, GL_UNSIGNED_BYTE, sizeof(ImDrawVert), (void*)(vtx_buffer + OFFSETOF(ImDrawVert, col))); + + for (int cmd_i = 0; cmd_i < cmd_list->CmdBuffer.size(); cmd_i++) + { + const ImDrawCmd* pcmd = &cmd_list->CmdBuffer[cmd_i]; + if (pcmd->UserCallback) + { + pcmd->UserCallback(cmd_list, pcmd); + } + else + { + glBindTexture(GL_TEXTURE_2D, (GLuint)(intptr_t)pcmd->TextureId); + glScissor((int)pcmd->ClipRect.x, (int)(fb_height - pcmd->ClipRect.w), (int)(pcmd->ClipRect.z - pcmd->ClipRect.x), (int)(pcmd->ClipRect.w - pcmd->ClipRect.y)); + glDrawElements(GL_TRIANGLES, (GLsizei)pcmd->ElemCount, sizeof(ImDrawIdx) == 2 ? GL_UNSIGNED_SHORT : GL_UNSIGNED_INT, idx_buffer); + } + idx_buffer += pcmd->ElemCount; + } + } + #undef OFFSETOF + + // Restore modified state + glDisableClientState(GL_COLOR_ARRAY); + glDisableClientState(GL_TEXTURE_COORD_ARRAY); + glDisableClientState(GL_VERTEX_ARRAY); + glBindTexture(GL_TEXTURE_2D, (GLuint)last_texture); + glMatrixMode(GL_MODELVIEW); + glPopMatrix(); + glMatrixMode(GL_PROJECTION); + glPopMatrix(); + glPopAttrib(); + glViewport(last_viewport[0], last_viewport[1], (GLsizei)last_viewport[2], (GLsizei)last_viewport[3]); +} + +static const char* ImGui_ImplSdl_GetClipboardText() +{ + return SDL_GetClipboardText(); +} + +static void ImGui_ImplSdl_SetClipboardText(const char* text) +{ + SDL_SetClipboardText(text); +} + +bool ImGui_ImplSdl_ProcessEvent(SDL_Event* event) +{ + ImGuiIO& io = ImGui::GetIO(); + switch (event->type) + { + case SDL_MOUSEWHEEL: + { + if (event->wheel.y > 0) + g_MouseWheel = 1; + if (event->wheel.y < 0) + g_MouseWheel = -1; + return true; + } + case SDL_MOUSEBUTTONDOWN: + { + if (event->button.button == SDL_BUTTON_LEFT) g_MousePressed[0] = true; + if (event->button.button == SDL_BUTTON_RIGHT) g_MousePressed[1] = true; + if (event->button.button == SDL_BUTTON_MIDDLE) g_MousePressed[2] = true; + return true; + } + case SDL_TEXTINPUT: + { + io.AddInputCharactersUTF8(event->text.text); + return true; + } + case SDL_KEYDOWN: + case SDL_KEYUP: + { + int key = event->key.keysym.sym & ~SDLK_SCANCODE_MASK; + io.KeysDown[key] = (event->type == SDL_KEYDOWN); + io.KeyShift = ((SDL_GetModState() & KMOD_SHIFT) != 0); + io.KeyCtrl = ((SDL_GetModState() & KMOD_CTRL) != 0); + io.KeyAlt = ((SDL_GetModState() & KMOD_ALT) != 0); + io.KeySuper = ((SDL_GetModState() & KMOD_GUI) != 0); + return true; + } + } + return false; +} + +bool ImGui_ImplSdl_CreateDeviceObjects() +{ + // Build texture atlas + ImGuiIO& io = ImGui::GetIO(); + unsigned char* pixels; + int width, height; + io.Fonts->GetTexDataAsAlpha8(&pixels, &width, &height); + + // Upload texture to graphics system + GLint last_texture; + glGetIntegerv(GL_TEXTURE_BINDING_2D, &last_texture); + glGenTextures(1, &g_FontTexture); + glBindTexture(GL_TEXTURE_2D, g_FontTexture); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glPixelStorei(GL_UNPACK_ROW_LENGTH, 0); + glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, width, height, 0, GL_ALPHA, GL_UNSIGNED_BYTE, pixels); + + // Store our identifier + io.Fonts->TexID = (void *)(intptr_t)g_FontTexture; + + // Restore state + glBindTexture(GL_TEXTURE_2D, last_texture); + + return true; +} + +void ImGui_ImplSdl_InvalidateDeviceObjects() +{ + if (g_FontTexture) + { + glDeleteTextures(1, &g_FontTexture); + ImGui::GetIO().Fonts->TexID = 0; + g_FontTexture = 0; + } +} + +bool ImGui_ImplSdl_Init(SDL_Window* window) +{ + ImGuiIO& io = ImGui::GetIO(); + io.KeyMap[ImGuiKey_Tab] = SDLK_TAB; // Keyboard mapping. ImGui will use those indices to peek into the io.KeyDown[] array. + io.KeyMap[ImGuiKey_LeftArrow] = SDL_SCANCODE_LEFT; + io.KeyMap[ImGuiKey_RightArrow] = SDL_SCANCODE_RIGHT; + io.KeyMap[ImGuiKey_UpArrow] = SDL_SCANCODE_UP; + io.KeyMap[ImGuiKey_DownArrow] = SDL_SCANCODE_DOWN; + io.KeyMap[ImGuiKey_PageUp] = SDL_SCANCODE_PAGEUP; + io.KeyMap[ImGuiKey_PageDown] = SDL_SCANCODE_PAGEDOWN; + io.KeyMap[ImGuiKey_Home] = SDL_SCANCODE_HOME; + io.KeyMap[ImGuiKey_End] = SDL_SCANCODE_END; + io.KeyMap[ImGuiKey_Delete] = SDLK_DELETE; + io.KeyMap[ImGuiKey_Backspace] = SDLK_BACKSPACE; + io.KeyMap[ImGuiKey_Enter] = SDLK_RETURN; + io.KeyMap[ImGuiKey_Escape] = SDLK_ESCAPE; + io.KeyMap[ImGuiKey_A] = SDLK_a; + io.KeyMap[ImGuiKey_C] = SDLK_c; + io.KeyMap[ImGuiKey_V] = SDLK_v; + io.KeyMap[ImGuiKey_X] = SDLK_x; + io.KeyMap[ImGuiKey_Y] = SDLK_y; + io.KeyMap[ImGuiKey_Z] = SDLK_z; + + io.RenderDrawListsFn = ImGui_ImplSdl_RenderDrawLists; // Alternatively you can set this to NULL and call ImGui::GetDrawData() after ImGui::Render() to get the same ImDrawData pointer. + io.SetClipboardTextFn = ImGui_ImplSdl_SetClipboardText; + io.GetClipboardTextFn = ImGui_ImplSdl_GetClipboardText; + +#ifdef _WIN32 + SDL_SysWMinfo wmInfo; + SDL_VERSION(&wmInfo.version); + SDL_GetWindowWMInfo(window, &wmInfo); + io.ImeWindowHandle = wmInfo.info.win.window; +#else + (void)window; +#endif + + return true; +} + +void ImGui_ImplSdl_Shutdown() +{ + ImGui_ImplSdl_InvalidateDeviceObjects(); + ImGui::Shutdown(); +} + +void ImGui_ImplSdl_NewFrame(SDL_Window *window) +{ + if (!g_FontTexture) + ImGui_ImplSdl_CreateDeviceObjects(); + + ImGuiIO& io = ImGui::GetIO(); + + // Setup display size (every frame to accommodate for window resizing) + int w, h; + int display_w, display_h; + SDL_GetWindowSize(window, &w, &h); + SDL_GL_GetDrawableSize(window, &display_w, &display_h); + io.DisplaySize = ImVec2((float)w, (float)h); + io.DisplayFramebufferScale = ImVec2(w > 0 ? ((float)display_w / w) : 0, h > 0 ? ((float)display_h / h) : 0); + + // Setup time step + Uint32 time = SDL_GetTicks(); + double current_time = time / 1000.0; + io.DeltaTime = g_Time > 0.0 ? (float)(current_time - g_Time) : (float)(1.0f/60.0f); + g_Time = current_time; + + // Setup inputs + // (we already got mouse wheel, keyboard keys & characters from SDL_PollEvent()) + int mx, my; + Uint32 mouseMask = SDL_GetMouseState(&mx, &my); + if (SDL_GetWindowFlags(window) & SDL_WINDOW_MOUSE_FOCUS) + io.MousePos = ImVec2((float)mx, (float)my); // Mouse position, in pixels (set to -1,-1 if no mouse / on another screen, etc.) + else + io.MousePos = ImVec2(-1,-1); + + io.MouseDown[0] = g_MousePressed[0] || (mouseMask & SDL_BUTTON(SDL_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] = g_MousePressed[1] || (mouseMask & SDL_BUTTON(SDL_BUTTON_RIGHT)) != 0; + io.MouseDown[2] = g_MousePressed[2] || (mouseMask & SDL_BUTTON(SDL_BUTTON_MIDDLE)) != 0; + g_MousePressed[0] = g_MousePressed[1] = g_MousePressed[2] = false; + + io.MouseWheel = g_MouseWheel; + g_MouseWheel = 0.0f; + + // Hide OS mouse cursor if ImGui is drawing it + SDL_ShowCursor(io.MouseDrawCursor ? 0 : 1); + + // Start the frame + ImGui::NewFrame(); +} diff --git a/examples/sdl_opengl2_example/imgui_impl_sdl.h b/examples/sdl_opengl2_example/imgui_impl_sdl.h new file mode 100644 index 0000000..a322bf2 --- /dev/null +++ b/examples/sdl_opengl2_example/imgui_impl_sdl.h @@ -0,0 +1,19 @@ +// ImGui SDL2 binding with OpenGL +// In this binding, ImTextureID is used to store an OpenGL 'GLuint' texture identifier. Read the FAQ about ImTextureID in imgui.cpp. + +// You can copy and use unmodified imgui_impl_* files in your project. See main.cpp for an example of using this. +// If you use this binding you'll need to call 4 functions: ImGui_ImplXXXX_Init(), ImGui_ImplXXXX_NewFrame(), ImGui::Render() and ImGui_ImplXXXX_Shutdown(). +// If you are new to ImGui, see examples/README.txt and documentation at the top of imgui.cpp. +// https://github.com/ocornut/imgui + +struct SDL_Window; +typedef union SDL_Event SDL_Event; + +IMGUI_API bool ImGui_ImplSdl_Init(SDL_Window* window); +IMGUI_API void ImGui_ImplSdl_Shutdown(); +IMGUI_API void ImGui_ImplSdl_NewFrame(SDL_Window* window); +IMGUI_API bool ImGui_ImplSdl_ProcessEvent(SDL_Event* event); + +// Use if you want to reset your rendering device without losing ImGui state. +IMGUI_API void ImGui_ImplSdl_InvalidateDeviceObjects(); +IMGUI_API bool ImGui_ImplSdl_CreateDeviceObjects(); diff --git a/examples/sdl_opengl2_example/main.cpp b/examples/sdl_opengl2_example/main.cpp new file mode 100644 index 0000000..f42e7fa --- /dev/null +++ b/examples/sdl_opengl2_example/main.cpp @@ -0,0 +1,103 @@ +// ImGui - standalone example application for SDL2 + OpenGL +// If you are new to ImGui, see examples/README.txt and documentation at the top of imgui.cpp. + +#include +#include "imgui_impl_sdl.h" +#include +#include +#include + +int main(int, char**) +{ + // Setup SDL + if (SDL_Init(SDL_INIT_VIDEO|SDL_INIT_TIMER) != 0) + { + printf("Error: %s\n", SDL_GetError()); + return -1; + } + + // Setup window + SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1); + SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 24); + SDL_GL_SetAttribute(SDL_GL_STENCIL_SIZE, 8); + SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 2); + SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 2); + SDL_DisplayMode current; + SDL_GetCurrentDisplayMode(0, ¤t); + SDL_Window *window = SDL_CreateWindow("ImGui SDL2+OpenGL example", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, 1280, 720, SDL_WINDOW_OPENGL|SDL_WINDOW_RESIZABLE); + SDL_GLContext glcontext = SDL_GL_CreateContext(window); + + // Setup ImGui binding + ImGui_ImplSdl_Init(window); + + // Load Fonts + // (there is a default font, this is only if you want to change it. see extra_fonts/README.txt for more details) + //ImGuiIO& io = ImGui::GetIO(); + //io.Fonts->AddFontDefault(); + //io.Fonts->AddFontFromFileTTF("../../extra_fonts/Cousine-Regular.ttf", 15.0f); + //io.Fonts->AddFontFromFileTTF("../../extra_fonts/DroidSans.ttf", 16.0f); + //io.Fonts->AddFontFromFileTTF("../../extra_fonts/ProggyClean.ttf", 13.0f); + //io.Fonts->AddFontFromFileTTF("../../extra_fonts/ProggyTiny.ttf", 10.0f); + //io.Fonts->AddFontFromFileTTF("c:\\Windows\\Fonts\\ArialUni.ttf", 18.0f, NULL, io.Fonts->GetGlyphRangesJapanese()); + + bool show_test_window = true; + bool show_another_window = false; + ImVec4 clear_color = ImColor(114, 144, 154); + + // Main loop + bool done = false; + while (!done) + { + SDL_Event event; + while (SDL_PollEvent(&event)) + { + ImGui_ImplSdl_ProcessEvent(&event); + if (event.type == SDL_QUIT) + done = true; + } + ImGui_ImplSdl_NewFrame(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" + { + static float f = 0.0f; + ImGui::Text("Hello, world!"); + ImGui::SliderFloat("float", &f, 0.0f, 1.0f); + ImGui::ColorEdit3("clear color", (float*)&clear_color); + if (ImGui::Button("Test Window")) show_test_window ^= 1; + if (ImGui::Button("Another Window")) show_another_window ^= 1; + ImGui::Text("Application average %.3f ms/frame (%.1f FPS)", 1000.0f / ImGui::GetIO().Framerate, ImGui::GetIO().Framerate); + } + + // 2. Show another simple window, this time using an explicit Begin/End pair + if (show_another_window) + { + ImGui::SetNextWindowSize(ImVec2(200,100), ImGuiSetCond_FirstUseEver); + ImGui::Begin("Another Window", &show_another_window); + 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::SetNextWindowPos(ImVec2(650, 20), ImGuiSetCond_FirstUseEver); + ImGui::ShowTestWindow(&show_test_window); + } + + // Rendering + glViewport(0, 0, (int)ImGui::GetIO().DisplaySize.x, (int)ImGui::GetIO().DisplaySize.y); + glClearColor(clear_color.x, clear_color.y, clear_color.z, clear_color.w); + glClear(GL_COLOR_BUFFER_BIT); + ImGui::Render(); + SDL_GL_SwapWindow(window); + } + + // Cleanup + ImGui_ImplSdl_Shutdown(); + SDL_GL_DeleteContext(glcontext); + SDL_DestroyWindow(window); + SDL_Quit(); + + return 0; +} diff --git a/examples/README.txt b/examples/README.txt index df2e86d..5a1c8df 100644 --- a/examples/README.txt +++ b/examples/README.txt @@ -8,11 +8,13 @@ TL;DR; - Newcomers, read 'PROGRAMMER GUIDE' in imgui.cpp for notes on how to setup ImGui in your codebase. - - Refer to 'opengl_example' to understand how the library is setup, it is the simplest one. + - Refer to 'opengl2_example' to LEARN how the library is setup, it is the simplest one. The other examples requires more boilerplate and are harder to read. + - If you are using OpenGL in your application, probably use an opengl3_xxx backend. + Mixing old fixed pipeline OpenGL2 and programmable pipeline OpenGL3+ isn't well supported by drivers. - If you are using of the backend provided here, so you can copy the imgui_impl_xxx.cpp/h files to your project and use them unmodified. - - If you have your own engine, you probably want to start from 'opengl_example' and adapt it to + - If you have your own engine, you probably want to start from one of the OpenGL example and adapt it to your engine, but you can read the other examples as well. ImGui is highly portable and only requires a few things to run: @@ -41,15 +43,14 @@ Also note that some setup or GPU drivers may be causing extra lag (possibly by enforcing triple buffering), leaving you with no option but sadness/anger (Intel GPU drivers were reported as such). -opengl_example/ - OpenGL example, using GLFW + fixed pipeline. - This is simple and should work for all OpenGL enabled applications. - Prefer following this example to learn how ImGui works! - (You can use this code in a GL3/GL4 context but make sure you disable the programmable pipeline - by calling "glUseProgram(0)" before ImGui::Render.) +opengl2_example/ + GLFW + OpenGL example (old fixed pipeline). + This is simple to read. Prefer following this example to learn how ImGui works! + (You might be able to use this code in a GL3/GL4 context but make sure you disable the programmable + pipeline by calling "glUseProgram(0)" before ImGui::Render.) opengl3_example/ - OpenGL example, using GLFW/GL3W + programmable pipeline. + GLFW + OpenGL example (programmable pipeline, binding modern functions with GL3W). This uses more modern OpenGL calls and custom shaders. It's more messy. directx9_example/ @@ -68,8 +69,8 @@ On iOS, Using Synergy to access keyboard/mouse data from server computer. Synergy keyboard integration is rather hacky. -sdl_opengl_example/ - SDL2 + OpenGL example. +sdl_opengl2_example/ + SDL2 + OpenGL example (old fixed pipeline). sdl_opengl3_example/ SDL2 + OpenGL3 example. diff --git a/examples/imgui_examples_msvc2010.sln b/examples/imgui_examples_msvc2010.sln index b7e6a25..16f0d60 100644 --- a/examples/imgui_examples_msvc2010.sln +++ b/examples/imgui_examples_msvc2010.sln @@ -1,7 +1,7 @@  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}" +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "opengl2_example", "opengl_example\opengl2_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 diff --git a/examples/opengl2_example/Makefile b/examples/opengl2_example/Makefile new file mode 100644 index 0000000..bd79d1b --- /dev/null +++ b/examples/opengl2_example/Makefile @@ -0,0 +1,60 @@ +# +# Cross Platform Makefile +# Compatible with Ubuntu 14.04.1 and Mac OS X +# +# +# if you using Mac OS X: +# You'll need glfw +# http://www.glfw.org +# + +#CXX = g++ + +EXE = opengl2_example +OBJS = main.o imgui_impl_glfw.o +OBJS += ../../imgui.o ../../imgui_demo.o ../../imgui_draw.o + +UNAME_S := $(shell uname -s) + + +ifeq ($(UNAME_S), Linux) #LINUX + ECHO_MESSAGE = "Linux" + LIBS = -lGL `pkg-config --static --libs glfw3` + + CXXFLAGS = -I../../ `pkg-config --cflags glfw3` + CXXFLAGS += -Wall -Wformat + CFLAGS = $(CXXFLAGS) +endif + +ifeq ($(UNAME_S), Darwin) #APPLE + ECHO_MESSAGE = "Mac OS X" + LIBS = -framework OpenGL -framework Cocoa -framework IOKit -framework CoreVideo + LIBS += -L/usr/local/lib -lglfw3 + + CXXFLAGS = -I../../ -I/usr/local/include + CXXFLAGS += -Wall -Wformat +# CXXFLAGS += -D__APPLE__ + CFLAGS = $(CXXFLAGS) +endif + +ifeq ($(UNAME_S), MINGW64_NT-6.3) + ECHO_MESSAGE = "Windows" + LIBS = -lglfw3 -lgdi32 -lopengl32 -limm32 + + CXXFLAGS = -I../../ -I../libs/gl3w `pkg-config --cflags glfw3` + CXXFLAGS += -Wall -Wformat + CFLAGS = $(CXXFLAGS) +endif + +.cpp.o: + $(CXX) $(CXXFLAGS) -c -o $@ $< + +all: $(EXE) + @echo Build complete for $(ECHO_MESSAGE) + +$(EXE): $(OBJS) + $(CXX) -o $(EXE) $(OBJS) $(CXXFLAGS) $(LIBS) + +clean: + rm $(EXE) $(OBJS) + diff --git a/examples/opengl2_example/build_win32.bat b/examples/opengl2_example/build_win32.bat new file mode 100644 index 0000000..278381c --- /dev/null +++ b/examples/opengl2_example/build_win32.bat @@ -0,0 +1,3 @@ +@REM Build for Visual Studio compiler. Run your copy of vcvars32.bat or vcvarsall.bat to setup command-line compiler. +mkdir Debug +cl /nologo /Zi /MD /I ..\.. /I ..\libs\glfw\include *.cpp ..\..\*.cpp /FeDebug/opengl_example.exe /FoDebug/ /link /LIBPATH:..\libs\glfw\lib-vc2010-32 glfw3.lib opengl32.lib gdi32.lib shell32.lib diff --git a/examples/opengl2_example/imgui_impl_glfw.cpp b/examples/opengl2_example/imgui_impl_glfw.cpp new file mode 100644 index 0000000..2d1f5c1 --- /dev/null +++ b/examples/opengl2_example/imgui_impl_glfw.cpp @@ -0,0 +1,288 @@ +// ImGui GLFW binding with OpenGL +// In this binding, ImTextureID is used to store an OpenGL 'GLuint' texture identifier. Read the FAQ about ImTextureID in imgui.cpp. + +// If your context is GL3/GL3 then prefer using the code in opengl3_example. +// You *might* use this code with a GL3/GL4 context but make sure you disable the programmable pipeline by calling "glUseProgram(0)" before ImGui::Render(). +// We cannot do that from GL2 code because the function doesn't exist. + +// You can copy and use unmodified imgui_impl_* files in your project. See main.cpp for an example of using this. +// If you use this binding you'll need to call 4 functions: ImGui_ImplXXXX_Init(), ImGui_ImplXXXX_NewFrame(), ImGui::Render() and ImGui_ImplXXXX_Shutdown(). +// If you are new to ImGui, see examples/README.txt and documentation at the top of imgui.cpp. +// https://github.com/ocornut/imgui + +#include +#include "imgui_impl_glfw.h" + +// GLFW +#include +#ifdef _WIN32 +#undef APIENTRY +#define GLFW_EXPOSE_NATIVE_WIN32 +#define GLFW_EXPOSE_NATIVE_WGL +#include +#endif + +// Data +static GLFWwindow* g_Window = NULL; +static double g_Time = 0.0f; +static bool g_MousePressed[3] = { false, false, false }; +static float g_MouseWheel = 0.0f; +static GLuint g_FontTexture = 0; + +// 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) +void ImGui_ImplGlfw_RenderDrawLists(ImDrawData* draw_data) +{ + // Avoid rendering when minimized, scale coordinates for retina displays (screen coordinates != framebuffer coordinates) + ImGuiIO& io = ImGui::GetIO(); + int fb_width = (int)(io.DisplaySize.x * io.DisplayFramebufferScale.x); + int fb_height = (int)(io.DisplaySize.y * io.DisplayFramebufferScale.y); + if (fb_width == 0 || fb_height == 0) + return; + draw_data->ScaleClipRects(io.DisplayFramebufferScale); + + // We are using the OpenGL fixed pipeline to make the example code simpler to read! + // Setup render state: alpha-blending enabled, no face culling, no depth testing, scissor enabled, vertex/texcoord/color pointers. + GLint last_texture; glGetIntegerv(GL_TEXTURE_BINDING_2D, &last_texture); + GLint last_viewport[4]; glGetIntegerv(GL_VIEWPORT, last_viewport); + glPushAttrib(GL_ENABLE_BIT | GL_COLOR_BUFFER_BIT | GL_TRANSFORM_BIT); + glEnable(GL_BLEND); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + glDisable(GL_CULL_FACE); + glDisable(GL_DEPTH_TEST); + glEnable(GL_SCISSOR_TEST); + glEnableClientState(GL_VERTEX_ARRAY); + glEnableClientState(GL_TEXTURE_COORD_ARRAY); + glEnableClientState(GL_COLOR_ARRAY); + glEnable(GL_TEXTURE_2D); + //glUseProgram(0); // You may want this if using this code in an OpenGL 3+ context + + // Setup viewport, orthographic projection matrix + glViewport(0, 0, (GLsizei)fb_width, (GLsizei)fb_height); + glMatrixMode(GL_PROJECTION); + glPushMatrix(); + glLoadIdentity(); + glOrtho(0.0f, io.DisplaySize.x, io.DisplaySize.y, 0.0f, -1.0f, +1.0f); + glMatrixMode(GL_MODELVIEW); + glPushMatrix(); + glLoadIdentity(); + + // Render command lists + #define OFFSETOF(TYPE, ELEMENT) ((size_t)&(((TYPE *)0)->ELEMENT)) + for (int n = 0; n < draw_data->CmdListsCount; n++) + { + const ImDrawList* cmd_list = draw_data->CmdLists[n]; + const unsigned char* vtx_buffer = (const unsigned char*)&cmd_list->VtxBuffer.front(); + const ImDrawIdx* idx_buffer = &cmd_list->IdxBuffer.front(); + glVertexPointer(2, GL_FLOAT, sizeof(ImDrawVert), (void*)(vtx_buffer + OFFSETOF(ImDrawVert, pos))); + glTexCoordPointer(2, GL_FLOAT, sizeof(ImDrawVert), (void*)(vtx_buffer + OFFSETOF(ImDrawVert, uv))); + glColorPointer(4, GL_UNSIGNED_BYTE, sizeof(ImDrawVert), (void*)(vtx_buffer + OFFSETOF(ImDrawVert, col))); + + for (int cmd_i = 0; cmd_i < cmd_list->CmdBuffer.size(); cmd_i++) + { + const ImDrawCmd* pcmd = &cmd_list->CmdBuffer[cmd_i]; + if (pcmd->UserCallback) + { + pcmd->UserCallback(cmd_list, pcmd); + } + else + { + glBindTexture(GL_TEXTURE_2D, (GLuint)(intptr_t)pcmd->TextureId); + glScissor((int)pcmd->ClipRect.x, (int)(fb_height - pcmd->ClipRect.w), (int)(pcmd->ClipRect.z - pcmd->ClipRect.x), (int)(pcmd->ClipRect.w - pcmd->ClipRect.y)); + glDrawElements(GL_TRIANGLES, (GLsizei)pcmd->ElemCount, sizeof(ImDrawIdx) == 2 ? GL_UNSIGNED_SHORT : GL_UNSIGNED_INT, idx_buffer); + } + idx_buffer += pcmd->ElemCount; + } + } + #undef OFFSETOF + + // Restore modified state + glDisableClientState(GL_COLOR_ARRAY); + glDisableClientState(GL_TEXTURE_COORD_ARRAY); + glDisableClientState(GL_VERTEX_ARRAY); + glBindTexture(GL_TEXTURE_2D, (GLuint)last_texture); + glMatrixMode(GL_MODELVIEW); + glPopMatrix(); + glMatrixMode(GL_PROJECTION); + glPopMatrix(); + glPopAttrib(); + glViewport(last_viewport[0], last_viewport[1], (GLsizei)last_viewport[2], (GLsizei)last_viewport[3]); +} + +static const char* ImGui_ImplGlfw_GetClipboardText() +{ + return glfwGetClipboardString(g_Window); +} + +static void ImGui_ImplGlfw_SetClipboardText(const char* text) +{ + glfwSetClipboardString(g_Window, text); +} + +void ImGui_ImplGlfw_MouseButtonCallback(GLFWwindow*, int button, int action, int /*mods*/) +{ + if (action == GLFW_PRESS && button >= 0 && button < 3) + g_MousePressed[button] = true; +} + +void ImGui_ImplGlfw_ScrollCallback(GLFWwindow*, double /*xoffset*/, double yoffset) +{ + g_MouseWheel += (float)yoffset; // Use fractional mouse wheel, 1.0 unit 5 lines. +} + +void ImGui_ImplGlFw_KeyCallback(GLFWwindow*, int key, int, int action, int mods) +{ + ImGuiIO& io = ImGui::GetIO(); + if (action == GLFW_PRESS) + io.KeysDown[key] = true; + if (action == GLFW_RELEASE) + io.KeysDown[key] = false; + + (void)mods; // Modifiers are not reliable across systems + io.KeyCtrl = io.KeysDown[GLFW_KEY_LEFT_CONTROL] || io.KeysDown[GLFW_KEY_RIGHT_CONTROL]; + io.KeyShift = io.KeysDown[GLFW_KEY_LEFT_SHIFT] || io.KeysDown[GLFW_KEY_RIGHT_SHIFT]; + io.KeyAlt = io.KeysDown[GLFW_KEY_LEFT_ALT] || io.KeysDown[GLFW_KEY_RIGHT_ALT]; + io.KeySuper = io.KeysDown[GLFW_KEY_LEFT_SUPER] || io.KeysDown[GLFW_KEY_RIGHT_SUPER]; +} + +void ImGui_ImplGlfw_CharCallback(GLFWwindow*, unsigned int c) +{ + ImGuiIO& io = ImGui::GetIO(); + if (c > 0 && c < 0x10000) + io.AddInputCharacter((unsigned short)c); +} + +bool ImGui_ImplGlfw_CreateDeviceObjects() +{ + // Build texture atlas + ImGuiIO& io = ImGui::GetIO(); + unsigned char* pixels; + int width, height; + io.Fonts->GetTexDataAsAlpha8(&pixels, &width, &height); + + // Upload texture to graphics system + GLint last_texture; + glGetIntegerv(GL_TEXTURE_BINDING_2D, &last_texture); + glGenTextures(1, &g_FontTexture); + glBindTexture(GL_TEXTURE_2D, g_FontTexture); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, width, height, 0, GL_ALPHA, GL_UNSIGNED_BYTE, pixels); + + // Store our identifier + io.Fonts->TexID = (void *)(intptr_t)g_FontTexture; + + // Restore state + glBindTexture(GL_TEXTURE_2D, last_texture); + + return true; +} + +void ImGui_ImplGlfw_InvalidateDeviceObjects() +{ + if (g_FontTexture) + { + glDeleteTextures(1, &g_FontTexture); + ImGui::GetIO().Fonts->TexID = 0; + g_FontTexture = 0; + } +} + +bool ImGui_ImplGlfw_Init(GLFWwindow* window, bool install_callbacks) +{ + g_Window = window; + + ImGuiIO& io = ImGui::GetIO(); + 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; + io.KeyMap[ImGuiKey_DownArrow] = GLFW_KEY_DOWN; + io.KeyMap[ImGuiKey_PageUp] = GLFW_KEY_PAGE_UP; + io.KeyMap[ImGuiKey_PageDown] = GLFW_KEY_PAGE_DOWN; + io.KeyMap[ImGuiKey_Home] = GLFW_KEY_HOME; + io.KeyMap[ImGuiKey_End] = GLFW_KEY_END; + io.KeyMap[ImGuiKey_Delete] = GLFW_KEY_DELETE; + io.KeyMap[ImGuiKey_Backspace] = GLFW_KEY_BACKSPACE; + io.KeyMap[ImGuiKey_Enter] = GLFW_KEY_ENTER; + io.KeyMap[ImGuiKey_Escape] = GLFW_KEY_ESCAPE; + io.KeyMap[ImGuiKey_A] = GLFW_KEY_A; + io.KeyMap[ImGuiKey_C] = GLFW_KEY_C; + io.KeyMap[ImGuiKey_V] = GLFW_KEY_V; + io.KeyMap[ImGuiKey_X] = GLFW_KEY_X; + io.KeyMap[ImGuiKey_Y] = GLFW_KEY_Y; + io.KeyMap[ImGuiKey_Z] = GLFW_KEY_Z; + + io.RenderDrawListsFn = ImGui_ImplGlfw_RenderDrawLists; // Alternatively you can set this to NULL and call ImGui::GetDrawData() after ImGui::Render() to get the same ImDrawData pointer. + io.SetClipboardTextFn = ImGui_ImplGlfw_SetClipboardText; + io.GetClipboardTextFn = ImGui_ImplGlfw_GetClipboardText; +#ifdef _WIN32 + io.ImeWindowHandle = glfwGetWin32Window(g_Window); +#endif + + if (install_callbacks) + { + glfwSetMouseButtonCallback(window, ImGui_ImplGlfw_MouseButtonCallback); + glfwSetScrollCallback(window, ImGui_ImplGlfw_ScrollCallback); + glfwSetKeyCallback(window, ImGui_ImplGlFw_KeyCallback); + glfwSetCharCallback(window, ImGui_ImplGlfw_CharCallback); + } + + return true; +} + +void ImGui_ImplGlfw_Shutdown() +{ + ImGui_ImplGlfw_InvalidateDeviceObjects(); + ImGui::Shutdown(); +} + +void ImGui_ImplGlfw_NewFrame() +{ + if (!g_FontTexture) + ImGui_ImplGlfw_CreateDeviceObjects(); + + ImGuiIO& io = ImGui::GetIO(); + + // Setup display size (every frame to accommodate for window resizing) + int w, h; + int display_w, display_h; + glfwGetWindowSize(g_Window, &w, &h); + glfwGetFramebufferSize(g_Window, &display_w, &display_h); + io.DisplaySize = ImVec2((float)w, (float)h); + io.DisplayFramebufferScale = ImVec2(w > 0 ? ((float)display_w / w) : 0, h > 0 ? ((float)display_h / h) : 0); + + // Setup time step + double current_time = glfwGetTime(); + io.DeltaTime = g_Time > 0.0 ? (float)(current_time - g_Time) : (float)(1.0f/60.0f); + g_Time = current_time; + + // Setup inputs + // (we already got mouse wheel, keyboard keys & characters from glfw callbacks polled in glfwPollEvents()) + if (glfwGetWindowAttrib(g_Window, GLFW_FOCUSED)) + { + double mouse_x, mouse_y; + glfwGetCursorPos(g_Window, &mouse_x, &mouse_y); + io.MousePos = ImVec2((float)mouse_x, (float)mouse_y); // Mouse position in screen coordinates (set to -1,-1 if no mouse / on another screen, etc.) + } + else + { + io.MousePos = ImVec2(-1,-1); + } + + for (int i = 0; i < 3; i++) + { + io.MouseDown[i] = g_MousePressed[i] || glfwGetMouseButton(g_Window, i) != 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. + g_MousePressed[i] = false; + } + + io.MouseWheel = g_MouseWheel; + g_MouseWheel = 0.0f; + + // Hide OS mouse cursor if ImGui is drawing it + glfwSetInputMode(g_Window, GLFW_CURSOR, io.MouseDrawCursor ? GLFW_CURSOR_HIDDEN : GLFW_CURSOR_NORMAL); + + // Start the frame + ImGui::NewFrame(); +} diff --git a/examples/opengl2_example/imgui_impl_glfw.h b/examples/opengl2_example/imgui_impl_glfw.h new file mode 100644 index 0000000..07dd96f --- /dev/null +++ b/examples/opengl2_example/imgui_impl_glfw.h @@ -0,0 +1,29 @@ +// ImGui GLFW binding with OpenGL +// In this binding, ImTextureID is used to store an OpenGL 'GLuint' texture identifier. Read the FAQ about ImTextureID in imgui.cpp. + +// If your context is GL3/GL3 then prefer using the code in opengl3_example. +// You *might* use this code with a GL3/GL4 context but make sure you disable the programmable pipeline by calling "glUseProgram(0)" before ImGui::Render(). +// We cannot do that from GL2 code because the function doesn't exist. + +// You can copy and use unmodified imgui_impl_* files in your project. See main.cpp for an example of using this. +// If you use this binding you'll need to call 4 functions: ImGui_ImplXXXX_Init(), ImGui_ImplXXXX_NewFrame(), ImGui::Render() and ImGui_ImplXXXX_Shutdown(). +// If you are new to ImGui, see examples/README.txt and documentation at the top of imgui.cpp. +// https://github.com/ocornut/imgui + +struct GLFWwindow; + +IMGUI_API bool ImGui_ImplGlfw_Init(GLFWwindow* window, bool install_callbacks); +IMGUI_API void ImGui_ImplGlfw_Shutdown(); +IMGUI_API void ImGui_ImplGlfw_NewFrame(); + +// Use if you want to reset your rendering device without losing ImGui state. +IMGUI_API void ImGui_ImplGlfw_InvalidateDeviceObjects(); +IMGUI_API bool ImGui_ImplGlfw_CreateDeviceObjects(); + +// GLFW callbacks (installed by default if you enable 'install_callbacks' during initialization) +// Provided here if you want to chain callbacks. +// You can also handle inputs yourself and use those as a reference. +IMGUI_API void ImGui_ImplGlfw_MouseButtonCallback(GLFWwindow* window, int button, int action, int mods); +IMGUI_API void ImGui_ImplGlfw_ScrollCallback(GLFWwindow* window, double xoffset, double yoffset); +IMGUI_API void ImGui_ImplGlFw_KeyCallback(GLFWwindow* window, int key, int scancode, int action, int mods); +IMGUI_API void ImGui_ImplGlfw_CharCallback(GLFWwindow* window, unsigned int c); diff --git a/examples/opengl2_example/main.cpp b/examples/opengl2_example/main.cpp new file mode 100644 index 0000000..a844db5 --- /dev/null +++ b/examples/opengl2_example/main.cpp @@ -0,0 +1,89 @@ +// ImGui - standalone example application for Glfw + OpenGL 2, using fixed pipeline +// If you are new to ImGui, see examples/README.txt and documentation at the top of imgui.cpp. + +#include +#include "imgui_impl_glfw.h" +#include +#include + +static void error_callback(int error, const char* description) +{ + fprintf(stderr, "Error %d: %s\n", error, description); +} + +int main(int, char**) +{ + // Setup window + glfwSetErrorCallback(error_callback); + if (!glfwInit()) + return 1; + GLFWwindow* window = glfwCreateWindow(1280, 720, "ImGui OpenGL2 example", NULL, NULL); + glfwMakeContextCurrent(window); + + // Setup ImGui binding + ImGui_ImplGlfw_Init(window, true); + + // Load Fonts + // (there is a default font, this is only if you want to change it. see extra_fonts/README.txt for more details) + //ImGuiIO& io = ImGui::GetIO(); + //io.Fonts->AddFontDefault(); + //io.Fonts->AddFontFromFileTTF("../../extra_fonts/Cousine-Regular.ttf", 15.0f); + //io.Fonts->AddFontFromFileTTF("../../extra_fonts/DroidSans.ttf", 16.0f); + //io.Fonts->AddFontFromFileTTF("../../extra_fonts/ProggyClean.ttf", 13.0f); + //io.Fonts->AddFontFromFileTTF("../../extra_fonts/ProggyTiny.ttf", 10.0f); + //io.Fonts->AddFontFromFileTTF("c:\\Windows\\Fonts\\ArialUni.ttf", 18.0f, NULL, io.Fonts->GetGlyphRangesJapanese()); + + bool show_test_window = true; + bool show_another_window = false; + ImVec4 clear_color = ImColor(114, 144, 154); + + // Main loop + while (!glfwWindowShouldClose(window)) + { + glfwPollEvents(); + ImGui_ImplGlfw_NewFrame(); + + // 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 = 0.0f; + ImGui::Text("Hello, world!"); + ImGui::SliderFloat("float", &f, 0.0f, 1.0f); + ImGui::ColorEdit3("clear color", (float*)&clear_color); + if (ImGui::Button("Test Window")) show_test_window ^= 1; + if (ImGui::Button("Another Window")) show_another_window ^= 1; + ImGui::Text("Application average %.3f ms/frame (%.1f FPS)", 1000.0f / ImGui::GetIO().Framerate, ImGui::GetIO().Framerate); + } + + // 2. Show another simple window, this time using an explicit Begin/End pair + if (show_another_window) + { + ImGui::SetNextWindowSize(ImVec2(200,100), ImGuiSetCond_FirstUseEver); + ImGui::Begin("Another Window", &show_another_window); + 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::SetNextWindowPos(ImVec2(650, 20), ImGuiSetCond_FirstUseEver); + ImGui::ShowTestWindow(&show_test_window); + } + + // Rendering + int display_w, display_h; + glfwGetFramebufferSize(window, &display_w, &display_h); + glViewport(0, 0, display_w, display_h); + glClearColor(clear_color.x, clear_color.y, clear_color.z, clear_color.w); + glClear(GL_COLOR_BUFFER_BIT); + ImGui::Render(); + glfwSwapBuffers(window); + } + + // Cleanup + ImGui_ImplGlfw_Shutdown(); + glfwTerminate(); + + return 0; +} diff --git a/examples/opengl2_example/opengl_example.vcxproj b/examples/opengl2_example/opengl_example.vcxproj new file mode 100644 index 0000000..4b354b6 --- /dev/null +++ b/examples/opengl2_example/opengl_example.vcxproj @@ -0,0 +1,169 @@ + + + + + Debug + Win32 + + + Debug + x64 + + + Release + Win32 + + + Release + x64 + + + + {9CDA7840-B7A5-496D-A527-E95571496D18} + opengl_example + + + + Application + true + MultiByte + + + Application + true + MultiByte + + + Application + false + true + MultiByte + + + Application + false + true + MultiByte + + + + + + + + + + + + + + + + + + + $(ProjectDir)$(Configuration)\ + $(ProjectDir)$(Configuration)\ + $(IncludePath) + + + $(ProjectDir)$(Configuration)\ + $(ProjectDir)$(Configuration)\ + $(IncludePath) + + + $(ProjectDir)$(Configuration)\ + $(ProjectDir)$(Configuration)\ + $(IncludePath) + + + $(ProjectDir)$(Configuration)\ + $(ProjectDir)$(Configuration)\ + $(IncludePath) + + + + Level4 + Disabled + $(SolutionDir)\libs\glfw\include;..\..;%(AdditionalIncludeDirectories) + + + true + $(SolutionDir)\libs\glfw\lib-vc2010-32;%(AdditionalLibraryDirectories) + opengl32.lib;glfw3.lib;%(AdditionalDependencies) + Console + msvcrt.lib + + + + + Level4 + Disabled + $(SolutionDir)\libs\glfw\include;..\..;%(AdditionalIncludeDirectories) + + + true + $(SolutionDir)\libs\glfw\lib-vc2010-64;%(AdditionalLibraryDirectories) + opengl32.lib;glfw3.lib;%(AdditionalDependencies) + Console + msvcrt.lib + + + + + Level4 + MaxSpeed + true + true + $(SolutionDir)\libs\glfw\include;..\..;%(AdditionalIncludeDirectories) + + + true + true + true + $(SolutionDir)\libs\glfw\lib-vc2010-32;%(AdditionalLibraryDirectories) + opengl32.lib;glfw3.lib;%(AdditionalDependencies) + Console + + + + + + + Level4 + MaxSpeed + true + true + $(SolutionDir)\libs\glfw\include;..\..;%(AdditionalIncludeDirectories) + + + true + true + true + $(SolutionDir)\libs\glfw\lib-vc2010-64;%(AdditionalLibraryDirectories) + opengl32.lib;glfw3.lib;%(AdditionalDependencies) + Console + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/examples/opengl2_example/opengl_example.vcxproj.filters b/examples/opengl2_example/opengl_example.vcxproj.filters new file mode 100644 index 0000000..f2282bf --- /dev/null +++ b/examples/opengl2_example/opengl_example.vcxproj.filters @@ -0,0 +1,46 @@ + + + + + {c336cfe3-f0c4-464c-9ef0-a9e17a7ff222} + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx + + + + + sources + + + imgui + + + sources + + + imgui + + + imgui + + + + + imgui + + + imgui + + + sources + + + imgui + + + + + + \ No newline at end of file diff --git a/examples/opengl_example/Makefile b/examples/opengl_example/Makefile deleted file mode 100644 index 91d1b14..0000000 --- a/examples/opengl_example/Makefile +++ /dev/null @@ -1,60 +0,0 @@ -# -# Cross Platform Makefile -# Compatible with Ubuntu 14.04.1 and Mac OS X -# -# -# if you using Mac OS X: -# You'll need glfw -# http://www.glfw.org -# - -#CXX = g++ - -EXE = opengl_example -OBJS = main.o imgui_impl_glfw.o -OBJS += ../../imgui.o ../../imgui_demo.o ../../imgui_draw.o - -UNAME_S := $(shell uname -s) - - -ifeq ($(UNAME_S), Linux) #LINUX - ECHO_MESSAGE = "Linux" - LIBS = -lGL `pkg-config --static --libs glfw3` - - CXXFLAGS = -I../../ `pkg-config --cflags glfw3` - CXXFLAGS += -Wall -Wformat - CFLAGS = $(CXXFLAGS) -endif - -ifeq ($(UNAME_S), Darwin) #APPLE - ECHO_MESSAGE = "Mac OS X" - LIBS = -framework OpenGL -framework Cocoa -framework IOKit -framework CoreVideo - LIBS += -L/usr/local/lib -lglfw3 - - CXXFLAGS = -I../../ -I/usr/local/include - CXXFLAGS += -Wall -Wformat -# CXXFLAGS += -D__APPLE__ - CFLAGS = $(CXXFLAGS) -endif - -ifeq ($(UNAME_S), MINGW64_NT-6.3) - ECHO_MESSAGE = "Windows" - LIBS = -lglfw3 -lgdi32 -lopengl32 -limm32 - - CXXFLAGS = -I../../ -I../libs/gl3w `pkg-config --cflags glfw3` - CXXFLAGS += -Wall -Wformat - CFLAGS = $(CXXFLAGS) -endif - -.cpp.o: - $(CXX) $(CXXFLAGS) -c -o $@ $< - -all: $(EXE) - @echo Build complete for $(ECHO_MESSAGE) - -$(EXE): $(OBJS) - $(CXX) -o $(EXE) $(OBJS) $(CXXFLAGS) $(LIBS) - -clean: - rm $(EXE) $(OBJS) - diff --git a/examples/opengl_example/build_win32.bat b/examples/opengl_example/build_win32.bat deleted file mode 100644 index 278381c..0000000 --- a/examples/opengl_example/build_win32.bat +++ /dev/null @@ -1,3 +0,0 @@ -@REM Build for Visual Studio compiler. Run your copy of vcvars32.bat or vcvarsall.bat to setup command-line compiler. -mkdir Debug -cl /nologo /Zi /MD /I ..\.. /I ..\libs\glfw\include *.cpp ..\..\*.cpp /FeDebug/opengl_example.exe /FoDebug/ /link /LIBPATH:..\libs\glfw\lib-vc2010-32 glfw3.lib opengl32.lib gdi32.lib shell32.lib diff --git a/examples/opengl_example/imgui_impl_glfw.cpp b/examples/opengl_example/imgui_impl_glfw.cpp deleted file mode 100644 index 2d1f5c1..0000000 --- a/examples/opengl_example/imgui_impl_glfw.cpp +++ /dev/null @@ -1,288 +0,0 @@ -// ImGui GLFW binding with OpenGL -// In this binding, ImTextureID is used to store an OpenGL 'GLuint' texture identifier. Read the FAQ about ImTextureID in imgui.cpp. - -// If your context is GL3/GL3 then prefer using the code in opengl3_example. -// You *might* use this code with a GL3/GL4 context but make sure you disable the programmable pipeline by calling "glUseProgram(0)" before ImGui::Render(). -// We cannot do that from GL2 code because the function doesn't exist. - -// You can copy and use unmodified imgui_impl_* files in your project. See main.cpp for an example of using this. -// If you use this binding you'll need to call 4 functions: ImGui_ImplXXXX_Init(), ImGui_ImplXXXX_NewFrame(), ImGui::Render() and ImGui_ImplXXXX_Shutdown(). -// If you are new to ImGui, see examples/README.txt and documentation at the top of imgui.cpp. -// https://github.com/ocornut/imgui - -#include -#include "imgui_impl_glfw.h" - -// GLFW -#include -#ifdef _WIN32 -#undef APIENTRY -#define GLFW_EXPOSE_NATIVE_WIN32 -#define GLFW_EXPOSE_NATIVE_WGL -#include -#endif - -// Data -static GLFWwindow* g_Window = NULL; -static double g_Time = 0.0f; -static bool g_MousePressed[3] = { false, false, false }; -static float g_MouseWheel = 0.0f; -static GLuint g_FontTexture = 0; - -// 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) -void ImGui_ImplGlfw_RenderDrawLists(ImDrawData* draw_data) -{ - // Avoid rendering when minimized, scale coordinates for retina displays (screen coordinates != framebuffer coordinates) - ImGuiIO& io = ImGui::GetIO(); - int fb_width = (int)(io.DisplaySize.x * io.DisplayFramebufferScale.x); - int fb_height = (int)(io.DisplaySize.y * io.DisplayFramebufferScale.y); - if (fb_width == 0 || fb_height == 0) - return; - draw_data->ScaleClipRects(io.DisplayFramebufferScale); - - // We are using the OpenGL fixed pipeline to make the example code simpler to read! - // Setup render state: alpha-blending enabled, no face culling, no depth testing, scissor enabled, vertex/texcoord/color pointers. - GLint last_texture; glGetIntegerv(GL_TEXTURE_BINDING_2D, &last_texture); - GLint last_viewport[4]; glGetIntegerv(GL_VIEWPORT, last_viewport); - glPushAttrib(GL_ENABLE_BIT | GL_COLOR_BUFFER_BIT | GL_TRANSFORM_BIT); - glEnable(GL_BLEND); - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - glDisable(GL_CULL_FACE); - glDisable(GL_DEPTH_TEST); - glEnable(GL_SCISSOR_TEST); - glEnableClientState(GL_VERTEX_ARRAY); - glEnableClientState(GL_TEXTURE_COORD_ARRAY); - glEnableClientState(GL_COLOR_ARRAY); - glEnable(GL_TEXTURE_2D); - //glUseProgram(0); // You may want this if using this code in an OpenGL 3+ context - - // Setup viewport, orthographic projection matrix - glViewport(0, 0, (GLsizei)fb_width, (GLsizei)fb_height); - glMatrixMode(GL_PROJECTION); - glPushMatrix(); - glLoadIdentity(); - glOrtho(0.0f, io.DisplaySize.x, io.DisplaySize.y, 0.0f, -1.0f, +1.0f); - glMatrixMode(GL_MODELVIEW); - glPushMatrix(); - glLoadIdentity(); - - // Render command lists - #define OFFSETOF(TYPE, ELEMENT) ((size_t)&(((TYPE *)0)->ELEMENT)) - for (int n = 0; n < draw_data->CmdListsCount; n++) - { - const ImDrawList* cmd_list = draw_data->CmdLists[n]; - const unsigned char* vtx_buffer = (const unsigned char*)&cmd_list->VtxBuffer.front(); - const ImDrawIdx* idx_buffer = &cmd_list->IdxBuffer.front(); - glVertexPointer(2, GL_FLOAT, sizeof(ImDrawVert), (void*)(vtx_buffer + OFFSETOF(ImDrawVert, pos))); - glTexCoordPointer(2, GL_FLOAT, sizeof(ImDrawVert), (void*)(vtx_buffer + OFFSETOF(ImDrawVert, uv))); - glColorPointer(4, GL_UNSIGNED_BYTE, sizeof(ImDrawVert), (void*)(vtx_buffer + OFFSETOF(ImDrawVert, col))); - - for (int cmd_i = 0; cmd_i < cmd_list->CmdBuffer.size(); cmd_i++) - { - const ImDrawCmd* pcmd = &cmd_list->CmdBuffer[cmd_i]; - if (pcmd->UserCallback) - { - pcmd->UserCallback(cmd_list, pcmd); - } - else - { - glBindTexture(GL_TEXTURE_2D, (GLuint)(intptr_t)pcmd->TextureId); - glScissor((int)pcmd->ClipRect.x, (int)(fb_height - pcmd->ClipRect.w), (int)(pcmd->ClipRect.z - pcmd->ClipRect.x), (int)(pcmd->ClipRect.w - pcmd->ClipRect.y)); - glDrawElements(GL_TRIANGLES, (GLsizei)pcmd->ElemCount, sizeof(ImDrawIdx) == 2 ? GL_UNSIGNED_SHORT : GL_UNSIGNED_INT, idx_buffer); - } - idx_buffer += pcmd->ElemCount; - } - } - #undef OFFSETOF - - // Restore modified state - glDisableClientState(GL_COLOR_ARRAY); - glDisableClientState(GL_TEXTURE_COORD_ARRAY); - glDisableClientState(GL_VERTEX_ARRAY); - glBindTexture(GL_TEXTURE_2D, (GLuint)last_texture); - glMatrixMode(GL_MODELVIEW); - glPopMatrix(); - glMatrixMode(GL_PROJECTION); - glPopMatrix(); - glPopAttrib(); - glViewport(last_viewport[0], last_viewport[1], (GLsizei)last_viewport[2], (GLsizei)last_viewport[3]); -} - -static const char* ImGui_ImplGlfw_GetClipboardText() -{ - return glfwGetClipboardString(g_Window); -} - -static void ImGui_ImplGlfw_SetClipboardText(const char* text) -{ - glfwSetClipboardString(g_Window, text); -} - -void ImGui_ImplGlfw_MouseButtonCallback(GLFWwindow*, int button, int action, int /*mods*/) -{ - if (action == GLFW_PRESS && button >= 0 && button < 3) - g_MousePressed[button] = true; -} - -void ImGui_ImplGlfw_ScrollCallback(GLFWwindow*, double /*xoffset*/, double yoffset) -{ - g_MouseWheel += (float)yoffset; // Use fractional mouse wheel, 1.0 unit 5 lines. -} - -void ImGui_ImplGlFw_KeyCallback(GLFWwindow*, int key, int, int action, int mods) -{ - ImGuiIO& io = ImGui::GetIO(); - if (action == GLFW_PRESS) - io.KeysDown[key] = true; - if (action == GLFW_RELEASE) - io.KeysDown[key] = false; - - (void)mods; // Modifiers are not reliable across systems - io.KeyCtrl = io.KeysDown[GLFW_KEY_LEFT_CONTROL] || io.KeysDown[GLFW_KEY_RIGHT_CONTROL]; - io.KeyShift = io.KeysDown[GLFW_KEY_LEFT_SHIFT] || io.KeysDown[GLFW_KEY_RIGHT_SHIFT]; - io.KeyAlt = io.KeysDown[GLFW_KEY_LEFT_ALT] || io.KeysDown[GLFW_KEY_RIGHT_ALT]; - io.KeySuper = io.KeysDown[GLFW_KEY_LEFT_SUPER] || io.KeysDown[GLFW_KEY_RIGHT_SUPER]; -} - -void ImGui_ImplGlfw_CharCallback(GLFWwindow*, unsigned int c) -{ - ImGuiIO& io = ImGui::GetIO(); - if (c > 0 && c < 0x10000) - io.AddInputCharacter((unsigned short)c); -} - -bool ImGui_ImplGlfw_CreateDeviceObjects() -{ - // Build texture atlas - ImGuiIO& io = ImGui::GetIO(); - unsigned char* pixels; - int width, height; - io.Fonts->GetTexDataAsAlpha8(&pixels, &width, &height); - - // Upload texture to graphics system - GLint last_texture; - glGetIntegerv(GL_TEXTURE_BINDING_2D, &last_texture); - glGenTextures(1, &g_FontTexture); - glBindTexture(GL_TEXTURE_2D, g_FontTexture); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, width, height, 0, GL_ALPHA, GL_UNSIGNED_BYTE, pixels); - - // Store our identifier - io.Fonts->TexID = (void *)(intptr_t)g_FontTexture; - - // Restore state - glBindTexture(GL_TEXTURE_2D, last_texture); - - return true; -} - -void ImGui_ImplGlfw_InvalidateDeviceObjects() -{ - if (g_FontTexture) - { - glDeleteTextures(1, &g_FontTexture); - ImGui::GetIO().Fonts->TexID = 0; - g_FontTexture = 0; - } -} - -bool ImGui_ImplGlfw_Init(GLFWwindow* window, bool install_callbacks) -{ - g_Window = window; - - ImGuiIO& io = ImGui::GetIO(); - 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; - io.KeyMap[ImGuiKey_DownArrow] = GLFW_KEY_DOWN; - io.KeyMap[ImGuiKey_PageUp] = GLFW_KEY_PAGE_UP; - io.KeyMap[ImGuiKey_PageDown] = GLFW_KEY_PAGE_DOWN; - io.KeyMap[ImGuiKey_Home] = GLFW_KEY_HOME; - io.KeyMap[ImGuiKey_End] = GLFW_KEY_END; - io.KeyMap[ImGuiKey_Delete] = GLFW_KEY_DELETE; - io.KeyMap[ImGuiKey_Backspace] = GLFW_KEY_BACKSPACE; - io.KeyMap[ImGuiKey_Enter] = GLFW_KEY_ENTER; - io.KeyMap[ImGuiKey_Escape] = GLFW_KEY_ESCAPE; - io.KeyMap[ImGuiKey_A] = GLFW_KEY_A; - io.KeyMap[ImGuiKey_C] = GLFW_KEY_C; - io.KeyMap[ImGuiKey_V] = GLFW_KEY_V; - io.KeyMap[ImGuiKey_X] = GLFW_KEY_X; - io.KeyMap[ImGuiKey_Y] = GLFW_KEY_Y; - io.KeyMap[ImGuiKey_Z] = GLFW_KEY_Z; - - io.RenderDrawListsFn = ImGui_ImplGlfw_RenderDrawLists; // Alternatively you can set this to NULL and call ImGui::GetDrawData() after ImGui::Render() to get the same ImDrawData pointer. - io.SetClipboardTextFn = ImGui_ImplGlfw_SetClipboardText; - io.GetClipboardTextFn = ImGui_ImplGlfw_GetClipboardText; -#ifdef _WIN32 - io.ImeWindowHandle = glfwGetWin32Window(g_Window); -#endif - - if (install_callbacks) - { - glfwSetMouseButtonCallback(window, ImGui_ImplGlfw_MouseButtonCallback); - glfwSetScrollCallback(window, ImGui_ImplGlfw_ScrollCallback); - glfwSetKeyCallback(window, ImGui_ImplGlFw_KeyCallback); - glfwSetCharCallback(window, ImGui_ImplGlfw_CharCallback); - } - - return true; -} - -void ImGui_ImplGlfw_Shutdown() -{ - ImGui_ImplGlfw_InvalidateDeviceObjects(); - ImGui::Shutdown(); -} - -void ImGui_ImplGlfw_NewFrame() -{ - if (!g_FontTexture) - ImGui_ImplGlfw_CreateDeviceObjects(); - - ImGuiIO& io = ImGui::GetIO(); - - // Setup display size (every frame to accommodate for window resizing) - int w, h; - int display_w, display_h; - glfwGetWindowSize(g_Window, &w, &h); - glfwGetFramebufferSize(g_Window, &display_w, &display_h); - io.DisplaySize = ImVec2((float)w, (float)h); - io.DisplayFramebufferScale = ImVec2(w > 0 ? ((float)display_w / w) : 0, h > 0 ? ((float)display_h / h) : 0); - - // Setup time step - double current_time = glfwGetTime(); - io.DeltaTime = g_Time > 0.0 ? (float)(current_time - g_Time) : (float)(1.0f/60.0f); - g_Time = current_time; - - // Setup inputs - // (we already got mouse wheel, keyboard keys & characters from glfw callbacks polled in glfwPollEvents()) - if (glfwGetWindowAttrib(g_Window, GLFW_FOCUSED)) - { - double mouse_x, mouse_y; - glfwGetCursorPos(g_Window, &mouse_x, &mouse_y); - io.MousePos = ImVec2((float)mouse_x, (float)mouse_y); // Mouse position in screen coordinates (set to -1,-1 if no mouse / on another screen, etc.) - } - else - { - io.MousePos = ImVec2(-1,-1); - } - - for (int i = 0; i < 3; i++) - { - io.MouseDown[i] = g_MousePressed[i] || glfwGetMouseButton(g_Window, i) != 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. - g_MousePressed[i] = false; - } - - io.MouseWheel = g_MouseWheel; - g_MouseWheel = 0.0f; - - // Hide OS mouse cursor if ImGui is drawing it - glfwSetInputMode(g_Window, GLFW_CURSOR, io.MouseDrawCursor ? GLFW_CURSOR_HIDDEN : GLFW_CURSOR_NORMAL); - - // Start the frame - ImGui::NewFrame(); -} diff --git a/examples/opengl_example/imgui_impl_glfw.h b/examples/opengl_example/imgui_impl_glfw.h deleted file mode 100644 index 07dd96f..0000000 --- a/examples/opengl_example/imgui_impl_glfw.h +++ /dev/null @@ -1,29 +0,0 @@ -// ImGui GLFW binding with OpenGL -// In this binding, ImTextureID is used to store an OpenGL 'GLuint' texture identifier. Read the FAQ about ImTextureID in imgui.cpp. - -// If your context is GL3/GL3 then prefer using the code in opengl3_example. -// You *might* use this code with a GL3/GL4 context but make sure you disable the programmable pipeline by calling "glUseProgram(0)" before ImGui::Render(). -// We cannot do that from GL2 code because the function doesn't exist. - -// You can copy and use unmodified imgui_impl_* files in your project. See main.cpp for an example of using this. -// If you use this binding you'll need to call 4 functions: ImGui_ImplXXXX_Init(), ImGui_ImplXXXX_NewFrame(), ImGui::Render() and ImGui_ImplXXXX_Shutdown(). -// If you are new to ImGui, see examples/README.txt and documentation at the top of imgui.cpp. -// https://github.com/ocornut/imgui - -struct GLFWwindow; - -IMGUI_API bool ImGui_ImplGlfw_Init(GLFWwindow* window, bool install_callbacks); -IMGUI_API void ImGui_ImplGlfw_Shutdown(); -IMGUI_API void ImGui_ImplGlfw_NewFrame(); - -// Use if you want to reset your rendering device without losing ImGui state. -IMGUI_API void ImGui_ImplGlfw_InvalidateDeviceObjects(); -IMGUI_API bool ImGui_ImplGlfw_CreateDeviceObjects(); - -// GLFW callbacks (installed by default if you enable 'install_callbacks' during initialization) -// Provided here if you want to chain callbacks. -// You can also handle inputs yourself and use those as a reference. -IMGUI_API void ImGui_ImplGlfw_MouseButtonCallback(GLFWwindow* window, int button, int action, int mods); -IMGUI_API void ImGui_ImplGlfw_ScrollCallback(GLFWwindow* window, double xoffset, double yoffset); -IMGUI_API void ImGui_ImplGlFw_KeyCallback(GLFWwindow* window, int key, int scancode, int action, int mods); -IMGUI_API void ImGui_ImplGlfw_CharCallback(GLFWwindow* window, unsigned int c); diff --git a/examples/opengl_example/main.cpp b/examples/opengl_example/main.cpp deleted file mode 100644 index a844db5..0000000 --- a/examples/opengl_example/main.cpp +++ /dev/null @@ -1,89 +0,0 @@ -// ImGui - standalone example application for Glfw + OpenGL 2, using fixed pipeline -// If you are new to ImGui, see examples/README.txt and documentation at the top of imgui.cpp. - -#include -#include "imgui_impl_glfw.h" -#include -#include - -static void error_callback(int error, const char* description) -{ - fprintf(stderr, "Error %d: %s\n", error, description); -} - -int main(int, char**) -{ - // Setup window - glfwSetErrorCallback(error_callback); - if (!glfwInit()) - return 1; - GLFWwindow* window = glfwCreateWindow(1280, 720, "ImGui OpenGL2 example", NULL, NULL); - glfwMakeContextCurrent(window); - - // Setup ImGui binding - ImGui_ImplGlfw_Init(window, true); - - // Load Fonts - // (there is a default font, this is only if you want to change it. see extra_fonts/README.txt for more details) - //ImGuiIO& io = ImGui::GetIO(); - //io.Fonts->AddFontDefault(); - //io.Fonts->AddFontFromFileTTF("../../extra_fonts/Cousine-Regular.ttf", 15.0f); - //io.Fonts->AddFontFromFileTTF("../../extra_fonts/DroidSans.ttf", 16.0f); - //io.Fonts->AddFontFromFileTTF("../../extra_fonts/ProggyClean.ttf", 13.0f); - //io.Fonts->AddFontFromFileTTF("../../extra_fonts/ProggyTiny.ttf", 10.0f); - //io.Fonts->AddFontFromFileTTF("c:\\Windows\\Fonts\\ArialUni.ttf", 18.0f, NULL, io.Fonts->GetGlyphRangesJapanese()); - - bool show_test_window = true; - bool show_another_window = false; - ImVec4 clear_color = ImColor(114, 144, 154); - - // Main loop - while (!glfwWindowShouldClose(window)) - { - glfwPollEvents(); - ImGui_ImplGlfw_NewFrame(); - - // 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 = 0.0f; - ImGui::Text("Hello, world!"); - ImGui::SliderFloat("float", &f, 0.0f, 1.0f); - ImGui::ColorEdit3("clear color", (float*)&clear_color); - if (ImGui::Button("Test Window")) show_test_window ^= 1; - if (ImGui::Button("Another Window")) show_another_window ^= 1; - ImGui::Text("Application average %.3f ms/frame (%.1f FPS)", 1000.0f / ImGui::GetIO().Framerate, ImGui::GetIO().Framerate); - } - - // 2. Show another simple window, this time using an explicit Begin/End pair - if (show_another_window) - { - ImGui::SetNextWindowSize(ImVec2(200,100), ImGuiSetCond_FirstUseEver); - ImGui::Begin("Another Window", &show_another_window); - 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::SetNextWindowPos(ImVec2(650, 20), ImGuiSetCond_FirstUseEver); - ImGui::ShowTestWindow(&show_test_window); - } - - // Rendering - int display_w, display_h; - glfwGetFramebufferSize(window, &display_w, &display_h); - glViewport(0, 0, display_w, display_h); - glClearColor(clear_color.x, clear_color.y, clear_color.z, clear_color.w); - glClear(GL_COLOR_BUFFER_BIT); - ImGui::Render(); - glfwSwapBuffers(window); - } - - // Cleanup - ImGui_ImplGlfw_Shutdown(); - glfwTerminate(); - - return 0; -} diff --git a/examples/opengl_example/opengl_example.vcxproj b/examples/opengl_example/opengl_example.vcxproj deleted file mode 100644 index 4b354b6..0000000 --- a/examples/opengl_example/opengl_example.vcxproj +++ /dev/null @@ -1,169 +0,0 @@ - - - - - Debug - Win32 - - - Debug - x64 - - - Release - Win32 - - - Release - x64 - - - - {9CDA7840-B7A5-496D-A527-E95571496D18} - opengl_example - - - - Application - true - MultiByte - - - Application - true - MultiByte - - - Application - false - true - MultiByte - - - Application - false - true - MultiByte - - - - - - - - - - - - - - - - - - - $(ProjectDir)$(Configuration)\ - $(ProjectDir)$(Configuration)\ - $(IncludePath) - - - $(ProjectDir)$(Configuration)\ - $(ProjectDir)$(Configuration)\ - $(IncludePath) - - - $(ProjectDir)$(Configuration)\ - $(ProjectDir)$(Configuration)\ - $(IncludePath) - - - $(ProjectDir)$(Configuration)\ - $(ProjectDir)$(Configuration)\ - $(IncludePath) - - - - Level4 - Disabled - $(SolutionDir)\libs\glfw\include;..\..;%(AdditionalIncludeDirectories) - - - true - $(SolutionDir)\libs\glfw\lib-vc2010-32;%(AdditionalLibraryDirectories) - opengl32.lib;glfw3.lib;%(AdditionalDependencies) - Console - msvcrt.lib - - - - - Level4 - Disabled - $(SolutionDir)\libs\glfw\include;..\..;%(AdditionalIncludeDirectories) - - - true - $(SolutionDir)\libs\glfw\lib-vc2010-64;%(AdditionalLibraryDirectories) - opengl32.lib;glfw3.lib;%(AdditionalDependencies) - Console - msvcrt.lib - - - - - Level4 - MaxSpeed - true - true - $(SolutionDir)\libs\glfw\include;..\..;%(AdditionalIncludeDirectories) - - - true - true - true - $(SolutionDir)\libs\glfw\lib-vc2010-32;%(AdditionalLibraryDirectories) - opengl32.lib;glfw3.lib;%(AdditionalDependencies) - Console - - - - - - - Level4 - MaxSpeed - true - true - $(SolutionDir)\libs\glfw\include;..\..;%(AdditionalIncludeDirectories) - - - true - true - true - $(SolutionDir)\libs\glfw\lib-vc2010-64;%(AdditionalLibraryDirectories) - opengl32.lib;glfw3.lib;%(AdditionalDependencies) - Console - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/examples/opengl_example/opengl_example.vcxproj.filters b/examples/opengl_example/opengl_example.vcxproj.filters deleted file mode 100644 index f2282bf..0000000 --- a/examples/opengl_example/opengl_example.vcxproj.filters +++ /dev/null @@ -1,46 +0,0 @@ - - - - - {c336cfe3-f0c4-464c-9ef0-a9e17a7ff222} - - - {4FC737F1-C7A5-4376-A066-2A32D752A2FF} - cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx - - - - - sources - - - imgui - - - sources - - - imgui - - - imgui - - - - - imgui - - - imgui - - - sources - - - imgui - - - - - - \ No newline at end of file diff --git a/examples/sdl_opengl2_example/README.md b/examples/sdl_opengl2_example/README.md new file mode 100644 index 0000000..aada45d --- /dev/null +++ b/examples/sdl_opengl2_example/README.md @@ -0,0 +1,22 @@ + +# How to Build + +- On Windows with Visual Studio's CLI + +``` +set SDL2DIR=path_to_your_sdl2_folder +cl /Zi /MD /I %SDL2DIR%\include> /I ..\.. main.cpp imgui_impl_sdl.cpp ..\..\imgui*.cpp /link /LIBPATH:%SDL2DIR%\lib SDL2.lib SDL2main.lib +``` + +- On Linux and similar Unixes + +``` +c++ `sdl2-config --cflags` -I ../.. main.cpp imgui_impl_sdl.cpp ../../imgui*.cpp `sdl2-config --libs` -lGL -o sdl2example +``` + +- On Mac OS X + +``` +brew install sdl2 +c++ `sdl2-config --cflags` -I ../.. main.cpp imgui_impl_sdl.cpp ../../imgui*.cpp `sdl2-config --libs` -framework OpenGl -o sdl2example +``` diff --git a/examples/sdl_opengl2_example/imgui_impl_sdl.cpp b/examples/sdl_opengl2_example/imgui_impl_sdl.cpp new file mode 100644 index 0000000..63ed9f4 --- /dev/null +++ b/examples/sdl_opengl2_example/imgui_impl_sdl.cpp @@ -0,0 +1,277 @@ +// ImGui SDL2 binding with OpenGL +// In this binding, ImTextureID is used to store an OpenGL 'GLuint' texture identifier. Read the FAQ about ImTextureID in imgui.cpp. + +// You can copy and use unmodified imgui_impl_* files in your project. See main.cpp for an example of using this. +// If you use this binding you'll need to call 4 functions: ImGui_ImplXXXX_Init(), ImGui_ImplXXXX_NewFrame(), ImGui::Render() and ImGui_ImplXXXX_Shutdown(). +// If you are new to ImGui, see examples/README.txt and documentation at the top of imgui.cpp. +// https://github.com/ocornut/imgui + +#include +#include +#include +#include +#include "imgui_impl_sdl.h" + +// Data +static double g_Time = 0.0f; +static bool g_MousePressed[3] = { false, false, false }; +static float g_MouseWheel = 0.0f; +static GLuint g_FontTexture = 0; + +// 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) +void ImGui_ImplSdl_RenderDrawLists(ImDrawData* draw_data) +{ + // Avoid rendering when minimized, scale coordinates for retina displays (screen coordinates != framebuffer coordinates) + ImGuiIO& io = ImGui::GetIO(); + int fb_width = (int)(io.DisplaySize.x * io.DisplayFramebufferScale.x); + int fb_height = (int)(io.DisplaySize.y * io.DisplayFramebufferScale.y); + if (fb_width == 0 || fb_height == 0) + return; + draw_data->ScaleClipRects(io.DisplayFramebufferScale); + + // We are using the OpenGL fixed pipeline to make the example code simpler to read! + // Setup render state: alpha-blending enabled, no face culling, no depth testing, scissor enabled, vertex/texcoord/color pointers. + GLint last_texture; glGetIntegerv(GL_TEXTURE_BINDING_2D, &last_texture); + GLint last_viewport[4]; glGetIntegerv(GL_VIEWPORT, last_viewport); + glPushAttrib(GL_ENABLE_BIT | GL_COLOR_BUFFER_BIT | GL_TRANSFORM_BIT); + glEnable(GL_BLEND); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + glDisable(GL_CULL_FACE); + glDisable(GL_DEPTH_TEST); + glEnable(GL_SCISSOR_TEST); + glEnableClientState(GL_VERTEX_ARRAY); + glEnableClientState(GL_TEXTURE_COORD_ARRAY); + glEnableClientState(GL_COLOR_ARRAY); + glEnable(GL_TEXTURE_2D); + //glUseProgram(0); // You may want this if using this code in an OpenGL 3+ context + + // Setup viewport, orthographic projection matrix + glViewport(0, 0, (GLsizei)fb_width, (GLsizei)fb_height); + glMatrixMode(GL_PROJECTION); + glPushMatrix(); + glLoadIdentity(); + glOrtho(0.0f, io.DisplaySize.x, io.DisplaySize.y, 0.0f, -1.0f, +1.0f); + glMatrixMode(GL_MODELVIEW); + glPushMatrix(); + glLoadIdentity(); + + // Render command lists + #define OFFSETOF(TYPE, ELEMENT) ((size_t)&(((TYPE *)0)->ELEMENT)) + for (int n = 0; n < draw_data->CmdListsCount; n++) + { + const ImDrawList* cmd_list = draw_data->CmdLists[n]; + const unsigned char* vtx_buffer = (const unsigned char*)&cmd_list->VtxBuffer.front(); + const ImDrawIdx* idx_buffer = &cmd_list->IdxBuffer.front(); + glVertexPointer(2, GL_FLOAT, sizeof(ImDrawVert), (void*)(vtx_buffer + OFFSETOF(ImDrawVert, pos))); + glTexCoordPointer(2, GL_FLOAT, sizeof(ImDrawVert), (void*)(vtx_buffer + OFFSETOF(ImDrawVert, uv))); + glColorPointer(4, GL_UNSIGNED_BYTE, sizeof(ImDrawVert), (void*)(vtx_buffer + OFFSETOF(ImDrawVert, col))); + + for (int cmd_i = 0; cmd_i < cmd_list->CmdBuffer.size(); cmd_i++) + { + const ImDrawCmd* pcmd = &cmd_list->CmdBuffer[cmd_i]; + if (pcmd->UserCallback) + { + pcmd->UserCallback(cmd_list, pcmd); + } + else + { + glBindTexture(GL_TEXTURE_2D, (GLuint)(intptr_t)pcmd->TextureId); + glScissor((int)pcmd->ClipRect.x, (int)(fb_height - pcmd->ClipRect.w), (int)(pcmd->ClipRect.z - pcmd->ClipRect.x), (int)(pcmd->ClipRect.w - pcmd->ClipRect.y)); + glDrawElements(GL_TRIANGLES, (GLsizei)pcmd->ElemCount, sizeof(ImDrawIdx) == 2 ? GL_UNSIGNED_SHORT : GL_UNSIGNED_INT, idx_buffer); + } + idx_buffer += pcmd->ElemCount; + } + } + #undef OFFSETOF + + // Restore modified state + glDisableClientState(GL_COLOR_ARRAY); + glDisableClientState(GL_TEXTURE_COORD_ARRAY); + glDisableClientState(GL_VERTEX_ARRAY); + glBindTexture(GL_TEXTURE_2D, (GLuint)last_texture); + glMatrixMode(GL_MODELVIEW); + glPopMatrix(); + glMatrixMode(GL_PROJECTION); + glPopMatrix(); + glPopAttrib(); + glViewport(last_viewport[0], last_viewport[1], (GLsizei)last_viewport[2], (GLsizei)last_viewport[3]); +} + +static const char* ImGui_ImplSdl_GetClipboardText() +{ + return SDL_GetClipboardText(); +} + +static void ImGui_ImplSdl_SetClipboardText(const char* text) +{ + SDL_SetClipboardText(text); +} + +bool ImGui_ImplSdl_ProcessEvent(SDL_Event* event) +{ + ImGuiIO& io = ImGui::GetIO(); + switch (event->type) + { + case SDL_MOUSEWHEEL: + { + if (event->wheel.y > 0) + g_MouseWheel = 1; + if (event->wheel.y < 0) + g_MouseWheel = -1; + return true; + } + case SDL_MOUSEBUTTONDOWN: + { + if (event->button.button == SDL_BUTTON_LEFT) g_MousePressed[0] = true; + if (event->button.button == SDL_BUTTON_RIGHT) g_MousePressed[1] = true; + if (event->button.button == SDL_BUTTON_MIDDLE) g_MousePressed[2] = true; + return true; + } + case SDL_TEXTINPUT: + { + io.AddInputCharactersUTF8(event->text.text); + return true; + } + case SDL_KEYDOWN: + case SDL_KEYUP: + { + int key = event->key.keysym.sym & ~SDLK_SCANCODE_MASK; + io.KeysDown[key] = (event->type == SDL_KEYDOWN); + io.KeyShift = ((SDL_GetModState() & KMOD_SHIFT) != 0); + io.KeyCtrl = ((SDL_GetModState() & KMOD_CTRL) != 0); + io.KeyAlt = ((SDL_GetModState() & KMOD_ALT) != 0); + io.KeySuper = ((SDL_GetModState() & KMOD_GUI) != 0); + return true; + } + } + return false; +} + +bool ImGui_ImplSdl_CreateDeviceObjects() +{ + // Build texture atlas + ImGuiIO& io = ImGui::GetIO(); + unsigned char* pixels; + int width, height; + io.Fonts->GetTexDataAsAlpha8(&pixels, &width, &height); + + // Upload texture to graphics system + GLint last_texture; + glGetIntegerv(GL_TEXTURE_BINDING_2D, &last_texture); + glGenTextures(1, &g_FontTexture); + glBindTexture(GL_TEXTURE_2D, g_FontTexture); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glPixelStorei(GL_UNPACK_ROW_LENGTH, 0); + glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, width, height, 0, GL_ALPHA, GL_UNSIGNED_BYTE, pixels); + + // Store our identifier + io.Fonts->TexID = (void *)(intptr_t)g_FontTexture; + + // Restore state + glBindTexture(GL_TEXTURE_2D, last_texture); + + return true; +} + +void ImGui_ImplSdl_InvalidateDeviceObjects() +{ + if (g_FontTexture) + { + glDeleteTextures(1, &g_FontTexture); + ImGui::GetIO().Fonts->TexID = 0; + g_FontTexture = 0; + } +} + +bool ImGui_ImplSdl_Init(SDL_Window* window) +{ + ImGuiIO& io = ImGui::GetIO(); + io.KeyMap[ImGuiKey_Tab] = SDLK_TAB; // Keyboard mapping. ImGui will use those indices to peek into the io.KeyDown[] array. + io.KeyMap[ImGuiKey_LeftArrow] = SDL_SCANCODE_LEFT; + io.KeyMap[ImGuiKey_RightArrow] = SDL_SCANCODE_RIGHT; + io.KeyMap[ImGuiKey_UpArrow] = SDL_SCANCODE_UP; + io.KeyMap[ImGuiKey_DownArrow] = SDL_SCANCODE_DOWN; + io.KeyMap[ImGuiKey_PageUp] = SDL_SCANCODE_PAGEUP; + io.KeyMap[ImGuiKey_PageDown] = SDL_SCANCODE_PAGEDOWN; + io.KeyMap[ImGuiKey_Home] = SDL_SCANCODE_HOME; + io.KeyMap[ImGuiKey_End] = SDL_SCANCODE_END; + io.KeyMap[ImGuiKey_Delete] = SDLK_DELETE; + io.KeyMap[ImGuiKey_Backspace] = SDLK_BACKSPACE; + io.KeyMap[ImGuiKey_Enter] = SDLK_RETURN; + io.KeyMap[ImGuiKey_Escape] = SDLK_ESCAPE; + io.KeyMap[ImGuiKey_A] = SDLK_a; + io.KeyMap[ImGuiKey_C] = SDLK_c; + io.KeyMap[ImGuiKey_V] = SDLK_v; + io.KeyMap[ImGuiKey_X] = SDLK_x; + io.KeyMap[ImGuiKey_Y] = SDLK_y; + io.KeyMap[ImGuiKey_Z] = SDLK_z; + + io.RenderDrawListsFn = ImGui_ImplSdl_RenderDrawLists; // Alternatively you can set this to NULL and call ImGui::GetDrawData() after ImGui::Render() to get the same ImDrawData pointer. + io.SetClipboardTextFn = ImGui_ImplSdl_SetClipboardText; + io.GetClipboardTextFn = ImGui_ImplSdl_GetClipboardText; + +#ifdef _WIN32 + SDL_SysWMinfo wmInfo; + SDL_VERSION(&wmInfo.version); + SDL_GetWindowWMInfo(window, &wmInfo); + io.ImeWindowHandle = wmInfo.info.win.window; +#else + (void)window; +#endif + + return true; +} + +void ImGui_ImplSdl_Shutdown() +{ + ImGui_ImplSdl_InvalidateDeviceObjects(); + ImGui::Shutdown(); +} + +void ImGui_ImplSdl_NewFrame(SDL_Window *window) +{ + if (!g_FontTexture) + ImGui_ImplSdl_CreateDeviceObjects(); + + ImGuiIO& io = ImGui::GetIO(); + + // Setup display size (every frame to accommodate for window resizing) + int w, h; + int display_w, display_h; + SDL_GetWindowSize(window, &w, &h); + SDL_GL_GetDrawableSize(window, &display_w, &display_h); + io.DisplaySize = ImVec2((float)w, (float)h); + io.DisplayFramebufferScale = ImVec2(w > 0 ? ((float)display_w / w) : 0, h > 0 ? ((float)display_h / h) : 0); + + // Setup time step + Uint32 time = SDL_GetTicks(); + double current_time = time / 1000.0; + io.DeltaTime = g_Time > 0.0 ? (float)(current_time - g_Time) : (float)(1.0f/60.0f); + g_Time = current_time; + + // Setup inputs + // (we already got mouse wheel, keyboard keys & characters from SDL_PollEvent()) + int mx, my; + Uint32 mouseMask = SDL_GetMouseState(&mx, &my); + if (SDL_GetWindowFlags(window) & SDL_WINDOW_MOUSE_FOCUS) + io.MousePos = ImVec2((float)mx, (float)my); // Mouse position, in pixels (set to -1,-1 if no mouse / on another screen, etc.) + else + io.MousePos = ImVec2(-1,-1); + + io.MouseDown[0] = g_MousePressed[0] || (mouseMask & SDL_BUTTON(SDL_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] = g_MousePressed[1] || (mouseMask & SDL_BUTTON(SDL_BUTTON_RIGHT)) != 0; + io.MouseDown[2] = g_MousePressed[2] || (mouseMask & SDL_BUTTON(SDL_BUTTON_MIDDLE)) != 0; + g_MousePressed[0] = g_MousePressed[1] = g_MousePressed[2] = false; + + io.MouseWheel = g_MouseWheel; + g_MouseWheel = 0.0f; + + // Hide OS mouse cursor if ImGui is drawing it + SDL_ShowCursor(io.MouseDrawCursor ? 0 : 1); + + // Start the frame + ImGui::NewFrame(); +} diff --git a/examples/sdl_opengl2_example/imgui_impl_sdl.h b/examples/sdl_opengl2_example/imgui_impl_sdl.h new file mode 100644 index 0000000..a322bf2 --- /dev/null +++ b/examples/sdl_opengl2_example/imgui_impl_sdl.h @@ -0,0 +1,19 @@ +// ImGui SDL2 binding with OpenGL +// In this binding, ImTextureID is used to store an OpenGL 'GLuint' texture identifier. Read the FAQ about ImTextureID in imgui.cpp. + +// You can copy and use unmodified imgui_impl_* files in your project. See main.cpp for an example of using this. +// If you use this binding you'll need to call 4 functions: ImGui_ImplXXXX_Init(), ImGui_ImplXXXX_NewFrame(), ImGui::Render() and ImGui_ImplXXXX_Shutdown(). +// If you are new to ImGui, see examples/README.txt and documentation at the top of imgui.cpp. +// https://github.com/ocornut/imgui + +struct SDL_Window; +typedef union SDL_Event SDL_Event; + +IMGUI_API bool ImGui_ImplSdl_Init(SDL_Window* window); +IMGUI_API void ImGui_ImplSdl_Shutdown(); +IMGUI_API void ImGui_ImplSdl_NewFrame(SDL_Window* window); +IMGUI_API bool ImGui_ImplSdl_ProcessEvent(SDL_Event* event); + +// Use if you want to reset your rendering device without losing ImGui state. +IMGUI_API void ImGui_ImplSdl_InvalidateDeviceObjects(); +IMGUI_API bool ImGui_ImplSdl_CreateDeviceObjects(); diff --git a/examples/sdl_opengl2_example/main.cpp b/examples/sdl_opengl2_example/main.cpp new file mode 100644 index 0000000..f42e7fa --- /dev/null +++ b/examples/sdl_opengl2_example/main.cpp @@ -0,0 +1,103 @@ +// ImGui - standalone example application for SDL2 + OpenGL +// If you are new to ImGui, see examples/README.txt and documentation at the top of imgui.cpp. + +#include +#include "imgui_impl_sdl.h" +#include +#include +#include + +int main(int, char**) +{ + // Setup SDL + if (SDL_Init(SDL_INIT_VIDEO|SDL_INIT_TIMER) != 0) + { + printf("Error: %s\n", SDL_GetError()); + return -1; + } + + // Setup window + SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1); + SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 24); + SDL_GL_SetAttribute(SDL_GL_STENCIL_SIZE, 8); + SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 2); + SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 2); + SDL_DisplayMode current; + SDL_GetCurrentDisplayMode(0, ¤t); + SDL_Window *window = SDL_CreateWindow("ImGui SDL2+OpenGL example", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, 1280, 720, SDL_WINDOW_OPENGL|SDL_WINDOW_RESIZABLE); + SDL_GLContext glcontext = SDL_GL_CreateContext(window); + + // Setup ImGui binding + ImGui_ImplSdl_Init(window); + + // Load Fonts + // (there is a default font, this is only if you want to change it. see extra_fonts/README.txt for more details) + //ImGuiIO& io = ImGui::GetIO(); + //io.Fonts->AddFontDefault(); + //io.Fonts->AddFontFromFileTTF("../../extra_fonts/Cousine-Regular.ttf", 15.0f); + //io.Fonts->AddFontFromFileTTF("../../extra_fonts/DroidSans.ttf", 16.0f); + //io.Fonts->AddFontFromFileTTF("../../extra_fonts/ProggyClean.ttf", 13.0f); + //io.Fonts->AddFontFromFileTTF("../../extra_fonts/ProggyTiny.ttf", 10.0f); + //io.Fonts->AddFontFromFileTTF("c:\\Windows\\Fonts\\ArialUni.ttf", 18.0f, NULL, io.Fonts->GetGlyphRangesJapanese()); + + bool show_test_window = true; + bool show_another_window = false; + ImVec4 clear_color = ImColor(114, 144, 154); + + // Main loop + bool done = false; + while (!done) + { + SDL_Event event; + while (SDL_PollEvent(&event)) + { + ImGui_ImplSdl_ProcessEvent(&event); + if (event.type == SDL_QUIT) + done = true; + } + ImGui_ImplSdl_NewFrame(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" + { + static float f = 0.0f; + ImGui::Text("Hello, world!"); + ImGui::SliderFloat("float", &f, 0.0f, 1.0f); + ImGui::ColorEdit3("clear color", (float*)&clear_color); + if (ImGui::Button("Test Window")) show_test_window ^= 1; + if (ImGui::Button("Another Window")) show_another_window ^= 1; + ImGui::Text("Application average %.3f ms/frame (%.1f FPS)", 1000.0f / ImGui::GetIO().Framerate, ImGui::GetIO().Framerate); + } + + // 2. Show another simple window, this time using an explicit Begin/End pair + if (show_another_window) + { + ImGui::SetNextWindowSize(ImVec2(200,100), ImGuiSetCond_FirstUseEver); + ImGui::Begin("Another Window", &show_another_window); + 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::SetNextWindowPos(ImVec2(650, 20), ImGuiSetCond_FirstUseEver); + ImGui::ShowTestWindow(&show_test_window); + } + + // Rendering + glViewport(0, 0, (int)ImGui::GetIO().DisplaySize.x, (int)ImGui::GetIO().DisplaySize.y); + glClearColor(clear_color.x, clear_color.y, clear_color.z, clear_color.w); + glClear(GL_COLOR_BUFFER_BIT); + ImGui::Render(); + SDL_GL_SwapWindow(window); + } + + // Cleanup + ImGui_ImplSdl_Shutdown(); + SDL_GL_DeleteContext(glcontext); + SDL_DestroyWindow(window); + SDL_Quit(); + + return 0; +} diff --git a/examples/sdl_opengl_example/README.md b/examples/sdl_opengl_example/README.md deleted file mode 100644 index aada45d..0000000 --- a/examples/sdl_opengl_example/README.md +++ /dev/null @@ -1,22 +0,0 @@ - -# How to Build - -- On Windows with Visual Studio's CLI - -``` -set SDL2DIR=path_to_your_sdl2_folder -cl /Zi /MD /I %SDL2DIR%\include> /I ..\.. main.cpp imgui_impl_sdl.cpp ..\..\imgui*.cpp /link /LIBPATH:%SDL2DIR%\lib SDL2.lib SDL2main.lib -``` - -- On Linux and similar Unixes - -``` -c++ `sdl2-config --cflags` -I ../.. main.cpp imgui_impl_sdl.cpp ../../imgui*.cpp `sdl2-config --libs` -lGL -o sdl2example -``` - -- On Mac OS X - -``` -brew install sdl2 -c++ `sdl2-config --cflags` -I ../.. main.cpp imgui_impl_sdl.cpp ../../imgui*.cpp `sdl2-config --libs` -framework OpenGl -o sdl2example -``` diff --git a/examples/README.txt b/examples/README.txt index df2e86d..5a1c8df 100644 --- a/examples/README.txt +++ b/examples/README.txt @@ -8,11 +8,13 @@ TL;DR; - Newcomers, read 'PROGRAMMER GUIDE' in imgui.cpp for notes on how to setup ImGui in your codebase. - - Refer to 'opengl_example' to understand how the library is setup, it is the simplest one. + - Refer to 'opengl2_example' to LEARN how the library is setup, it is the simplest one. The other examples requires more boilerplate and are harder to read. + - If you are using OpenGL in your application, probably use an opengl3_xxx backend. + Mixing old fixed pipeline OpenGL2 and programmable pipeline OpenGL3+ isn't well supported by drivers. - If you are using of the backend provided here, so you can copy the imgui_impl_xxx.cpp/h files to your project and use them unmodified. - - If you have your own engine, you probably want to start from 'opengl_example' and adapt it to + - If you have your own engine, you probably want to start from one of the OpenGL example and adapt it to your engine, but you can read the other examples as well. ImGui is highly portable and only requires a few things to run: @@ -41,15 +43,14 @@ Also note that some setup or GPU drivers may be causing extra lag (possibly by enforcing triple buffering), leaving you with no option but sadness/anger (Intel GPU drivers were reported as such). -opengl_example/ - OpenGL example, using GLFW + fixed pipeline. - This is simple and should work for all OpenGL enabled applications. - Prefer following this example to learn how ImGui works! - (You can use this code in a GL3/GL4 context but make sure you disable the programmable pipeline - by calling "glUseProgram(0)" before ImGui::Render.) +opengl2_example/ + GLFW + OpenGL example (old fixed pipeline). + This is simple to read. Prefer following this example to learn how ImGui works! + (You might be able to use this code in a GL3/GL4 context but make sure you disable the programmable + pipeline by calling "glUseProgram(0)" before ImGui::Render.) opengl3_example/ - OpenGL example, using GLFW/GL3W + programmable pipeline. + GLFW + OpenGL example (programmable pipeline, binding modern functions with GL3W). This uses more modern OpenGL calls and custom shaders. It's more messy. directx9_example/ @@ -68,8 +69,8 @@ On iOS, Using Synergy to access keyboard/mouse data from server computer. Synergy keyboard integration is rather hacky. -sdl_opengl_example/ - SDL2 + OpenGL example. +sdl_opengl2_example/ + SDL2 + OpenGL example (old fixed pipeline). sdl_opengl3_example/ SDL2 + OpenGL3 example. diff --git a/examples/imgui_examples_msvc2010.sln b/examples/imgui_examples_msvc2010.sln index b7e6a25..16f0d60 100644 --- a/examples/imgui_examples_msvc2010.sln +++ b/examples/imgui_examples_msvc2010.sln @@ -1,7 +1,7 @@  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}" +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "opengl2_example", "opengl_example\opengl2_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 diff --git a/examples/opengl2_example/Makefile b/examples/opengl2_example/Makefile new file mode 100644 index 0000000..bd79d1b --- /dev/null +++ b/examples/opengl2_example/Makefile @@ -0,0 +1,60 @@ +# +# Cross Platform Makefile +# Compatible with Ubuntu 14.04.1 and Mac OS X +# +# +# if you using Mac OS X: +# You'll need glfw +# http://www.glfw.org +# + +#CXX = g++ + +EXE = opengl2_example +OBJS = main.o imgui_impl_glfw.o +OBJS += ../../imgui.o ../../imgui_demo.o ../../imgui_draw.o + +UNAME_S := $(shell uname -s) + + +ifeq ($(UNAME_S), Linux) #LINUX + ECHO_MESSAGE = "Linux" + LIBS = -lGL `pkg-config --static --libs glfw3` + + CXXFLAGS = -I../../ `pkg-config --cflags glfw3` + CXXFLAGS += -Wall -Wformat + CFLAGS = $(CXXFLAGS) +endif + +ifeq ($(UNAME_S), Darwin) #APPLE + ECHO_MESSAGE = "Mac OS X" + LIBS = -framework OpenGL -framework Cocoa -framework IOKit -framework CoreVideo + LIBS += -L/usr/local/lib -lglfw3 + + CXXFLAGS = -I../../ -I/usr/local/include + CXXFLAGS += -Wall -Wformat +# CXXFLAGS += -D__APPLE__ + CFLAGS = $(CXXFLAGS) +endif + +ifeq ($(UNAME_S), MINGW64_NT-6.3) + ECHO_MESSAGE = "Windows" + LIBS = -lglfw3 -lgdi32 -lopengl32 -limm32 + + CXXFLAGS = -I../../ -I../libs/gl3w `pkg-config --cflags glfw3` + CXXFLAGS += -Wall -Wformat + CFLAGS = $(CXXFLAGS) +endif + +.cpp.o: + $(CXX) $(CXXFLAGS) -c -o $@ $< + +all: $(EXE) + @echo Build complete for $(ECHO_MESSAGE) + +$(EXE): $(OBJS) + $(CXX) -o $(EXE) $(OBJS) $(CXXFLAGS) $(LIBS) + +clean: + rm $(EXE) $(OBJS) + diff --git a/examples/opengl2_example/build_win32.bat b/examples/opengl2_example/build_win32.bat new file mode 100644 index 0000000..278381c --- /dev/null +++ b/examples/opengl2_example/build_win32.bat @@ -0,0 +1,3 @@ +@REM Build for Visual Studio compiler. Run your copy of vcvars32.bat or vcvarsall.bat to setup command-line compiler. +mkdir Debug +cl /nologo /Zi /MD /I ..\.. /I ..\libs\glfw\include *.cpp ..\..\*.cpp /FeDebug/opengl_example.exe /FoDebug/ /link /LIBPATH:..\libs\glfw\lib-vc2010-32 glfw3.lib opengl32.lib gdi32.lib shell32.lib diff --git a/examples/opengl2_example/imgui_impl_glfw.cpp b/examples/opengl2_example/imgui_impl_glfw.cpp new file mode 100644 index 0000000..2d1f5c1 --- /dev/null +++ b/examples/opengl2_example/imgui_impl_glfw.cpp @@ -0,0 +1,288 @@ +// ImGui GLFW binding with OpenGL +// In this binding, ImTextureID is used to store an OpenGL 'GLuint' texture identifier. Read the FAQ about ImTextureID in imgui.cpp. + +// If your context is GL3/GL3 then prefer using the code in opengl3_example. +// You *might* use this code with a GL3/GL4 context but make sure you disable the programmable pipeline by calling "glUseProgram(0)" before ImGui::Render(). +// We cannot do that from GL2 code because the function doesn't exist. + +// You can copy and use unmodified imgui_impl_* files in your project. See main.cpp for an example of using this. +// If you use this binding you'll need to call 4 functions: ImGui_ImplXXXX_Init(), ImGui_ImplXXXX_NewFrame(), ImGui::Render() and ImGui_ImplXXXX_Shutdown(). +// If you are new to ImGui, see examples/README.txt and documentation at the top of imgui.cpp. +// https://github.com/ocornut/imgui + +#include +#include "imgui_impl_glfw.h" + +// GLFW +#include +#ifdef _WIN32 +#undef APIENTRY +#define GLFW_EXPOSE_NATIVE_WIN32 +#define GLFW_EXPOSE_NATIVE_WGL +#include +#endif + +// Data +static GLFWwindow* g_Window = NULL; +static double g_Time = 0.0f; +static bool g_MousePressed[3] = { false, false, false }; +static float g_MouseWheel = 0.0f; +static GLuint g_FontTexture = 0; + +// 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) +void ImGui_ImplGlfw_RenderDrawLists(ImDrawData* draw_data) +{ + // Avoid rendering when minimized, scale coordinates for retina displays (screen coordinates != framebuffer coordinates) + ImGuiIO& io = ImGui::GetIO(); + int fb_width = (int)(io.DisplaySize.x * io.DisplayFramebufferScale.x); + int fb_height = (int)(io.DisplaySize.y * io.DisplayFramebufferScale.y); + if (fb_width == 0 || fb_height == 0) + return; + draw_data->ScaleClipRects(io.DisplayFramebufferScale); + + // We are using the OpenGL fixed pipeline to make the example code simpler to read! + // Setup render state: alpha-blending enabled, no face culling, no depth testing, scissor enabled, vertex/texcoord/color pointers. + GLint last_texture; glGetIntegerv(GL_TEXTURE_BINDING_2D, &last_texture); + GLint last_viewport[4]; glGetIntegerv(GL_VIEWPORT, last_viewport); + glPushAttrib(GL_ENABLE_BIT | GL_COLOR_BUFFER_BIT | GL_TRANSFORM_BIT); + glEnable(GL_BLEND); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + glDisable(GL_CULL_FACE); + glDisable(GL_DEPTH_TEST); + glEnable(GL_SCISSOR_TEST); + glEnableClientState(GL_VERTEX_ARRAY); + glEnableClientState(GL_TEXTURE_COORD_ARRAY); + glEnableClientState(GL_COLOR_ARRAY); + glEnable(GL_TEXTURE_2D); + //glUseProgram(0); // You may want this if using this code in an OpenGL 3+ context + + // Setup viewport, orthographic projection matrix + glViewport(0, 0, (GLsizei)fb_width, (GLsizei)fb_height); + glMatrixMode(GL_PROJECTION); + glPushMatrix(); + glLoadIdentity(); + glOrtho(0.0f, io.DisplaySize.x, io.DisplaySize.y, 0.0f, -1.0f, +1.0f); + glMatrixMode(GL_MODELVIEW); + glPushMatrix(); + glLoadIdentity(); + + // Render command lists + #define OFFSETOF(TYPE, ELEMENT) ((size_t)&(((TYPE *)0)->ELEMENT)) + for (int n = 0; n < draw_data->CmdListsCount; n++) + { + const ImDrawList* cmd_list = draw_data->CmdLists[n]; + const unsigned char* vtx_buffer = (const unsigned char*)&cmd_list->VtxBuffer.front(); + const ImDrawIdx* idx_buffer = &cmd_list->IdxBuffer.front(); + glVertexPointer(2, GL_FLOAT, sizeof(ImDrawVert), (void*)(vtx_buffer + OFFSETOF(ImDrawVert, pos))); + glTexCoordPointer(2, GL_FLOAT, sizeof(ImDrawVert), (void*)(vtx_buffer + OFFSETOF(ImDrawVert, uv))); + glColorPointer(4, GL_UNSIGNED_BYTE, sizeof(ImDrawVert), (void*)(vtx_buffer + OFFSETOF(ImDrawVert, col))); + + for (int cmd_i = 0; cmd_i < cmd_list->CmdBuffer.size(); cmd_i++) + { + const ImDrawCmd* pcmd = &cmd_list->CmdBuffer[cmd_i]; + if (pcmd->UserCallback) + { + pcmd->UserCallback(cmd_list, pcmd); + } + else + { + glBindTexture(GL_TEXTURE_2D, (GLuint)(intptr_t)pcmd->TextureId); + glScissor((int)pcmd->ClipRect.x, (int)(fb_height - pcmd->ClipRect.w), (int)(pcmd->ClipRect.z - pcmd->ClipRect.x), (int)(pcmd->ClipRect.w - pcmd->ClipRect.y)); + glDrawElements(GL_TRIANGLES, (GLsizei)pcmd->ElemCount, sizeof(ImDrawIdx) == 2 ? GL_UNSIGNED_SHORT : GL_UNSIGNED_INT, idx_buffer); + } + idx_buffer += pcmd->ElemCount; + } + } + #undef OFFSETOF + + // Restore modified state + glDisableClientState(GL_COLOR_ARRAY); + glDisableClientState(GL_TEXTURE_COORD_ARRAY); + glDisableClientState(GL_VERTEX_ARRAY); + glBindTexture(GL_TEXTURE_2D, (GLuint)last_texture); + glMatrixMode(GL_MODELVIEW); + glPopMatrix(); + glMatrixMode(GL_PROJECTION); + glPopMatrix(); + glPopAttrib(); + glViewport(last_viewport[0], last_viewport[1], (GLsizei)last_viewport[2], (GLsizei)last_viewport[3]); +} + +static const char* ImGui_ImplGlfw_GetClipboardText() +{ + return glfwGetClipboardString(g_Window); +} + +static void ImGui_ImplGlfw_SetClipboardText(const char* text) +{ + glfwSetClipboardString(g_Window, text); +} + +void ImGui_ImplGlfw_MouseButtonCallback(GLFWwindow*, int button, int action, int /*mods*/) +{ + if (action == GLFW_PRESS && button >= 0 && button < 3) + g_MousePressed[button] = true; +} + +void ImGui_ImplGlfw_ScrollCallback(GLFWwindow*, double /*xoffset*/, double yoffset) +{ + g_MouseWheel += (float)yoffset; // Use fractional mouse wheel, 1.0 unit 5 lines. +} + +void ImGui_ImplGlFw_KeyCallback(GLFWwindow*, int key, int, int action, int mods) +{ + ImGuiIO& io = ImGui::GetIO(); + if (action == GLFW_PRESS) + io.KeysDown[key] = true; + if (action == GLFW_RELEASE) + io.KeysDown[key] = false; + + (void)mods; // Modifiers are not reliable across systems + io.KeyCtrl = io.KeysDown[GLFW_KEY_LEFT_CONTROL] || io.KeysDown[GLFW_KEY_RIGHT_CONTROL]; + io.KeyShift = io.KeysDown[GLFW_KEY_LEFT_SHIFT] || io.KeysDown[GLFW_KEY_RIGHT_SHIFT]; + io.KeyAlt = io.KeysDown[GLFW_KEY_LEFT_ALT] || io.KeysDown[GLFW_KEY_RIGHT_ALT]; + io.KeySuper = io.KeysDown[GLFW_KEY_LEFT_SUPER] || io.KeysDown[GLFW_KEY_RIGHT_SUPER]; +} + +void ImGui_ImplGlfw_CharCallback(GLFWwindow*, unsigned int c) +{ + ImGuiIO& io = ImGui::GetIO(); + if (c > 0 && c < 0x10000) + io.AddInputCharacter((unsigned short)c); +} + +bool ImGui_ImplGlfw_CreateDeviceObjects() +{ + // Build texture atlas + ImGuiIO& io = ImGui::GetIO(); + unsigned char* pixels; + int width, height; + io.Fonts->GetTexDataAsAlpha8(&pixels, &width, &height); + + // Upload texture to graphics system + GLint last_texture; + glGetIntegerv(GL_TEXTURE_BINDING_2D, &last_texture); + glGenTextures(1, &g_FontTexture); + glBindTexture(GL_TEXTURE_2D, g_FontTexture); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, width, height, 0, GL_ALPHA, GL_UNSIGNED_BYTE, pixels); + + // Store our identifier + io.Fonts->TexID = (void *)(intptr_t)g_FontTexture; + + // Restore state + glBindTexture(GL_TEXTURE_2D, last_texture); + + return true; +} + +void ImGui_ImplGlfw_InvalidateDeviceObjects() +{ + if (g_FontTexture) + { + glDeleteTextures(1, &g_FontTexture); + ImGui::GetIO().Fonts->TexID = 0; + g_FontTexture = 0; + } +} + +bool ImGui_ImplGlfw_Init(GLFWwindow* window, bool install_callbacks) +{ + g_Window = window; + + ImGuiIO& io = ImGui::GetIO(); + 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; + io.KeyMap[ImGuiKey_DownArrow] = GLFW_KEY_DOWN; + io.KeyMap[ImGuiKey_PageUp] = GLFW_KEY_PAGE_UP; + io.KeyMap[ImGuiKey_PageDown] = GLFW_KEY_PAGE_DOWN; + io.KeyMap[ImGuiKey_Home] = GLFW_KEY_HOME; + io.KeyMap[ImGuiKey_End] = GLFW_KEY_END; + io.KeyMap[ImGuiKey_Delete] = GLFW_KEY_DELETE; + io.KeyMap[ImGuiKey_Backspace] = GLFW_KEY_BACKSPACE; + io.KeyMap[ImGuiKey_Enter] = GLFW_KEY_ENTER; + io.KeyMap[ImGuiKey_Escape] = GLFW_KEY_ESCAPE; + io.KeyMap[ImGuiKey_A] = GLFW_KEY_A; + io.KeyMap[ImGuiKey_C] = GLFW_KEY_C; + io.KeyMap[ImGuiKey_V] = GLFW_KEY_V; + io.KeyMap[ImGuiKey_X] = GLFW_KEY_X; + io.KeyMap[ImGuiKey_Y] = GLFW_KEY_Y; + io.KeyMap[ImGuiKey_Z] = GLFW_KEY_Z; + + io.RenderDrawListsFn = ImGui_ImplGlfw_RenderDrawLists; // Alternatively you can set this to NULL and call ImGui::GetDrawData() after ImGui::Render() to get the same ImDrawData pointer. + io.SetClipboardTextFn = ImGui_ImplGlfw_SetClipboardText; + io.GetClipboardTextFn = ImGui_ImplGlfw_GetClipboardText; +#ifdef _WIN32 + io.ImeWindowHandle = glfwGetWin32Window(g_Window); +#endif + + if (install_callbacks) + { + glfwSetMouseButtonCallback(window, ImGui_ImplGlfw_MouseButtonCallback); + glfwSetScrollCallback(window, ImGui_ImplGlfw_ScrollCallback); + glfwSetKeyCallback(window, ImGui_ImplGlFw_KeyCallback); + glfwSetCharCallback(window, ImGui_ImplGlfw_CharCallback); + } + + return true; +} + +void ImGui_ImplGlfw_Shutdown() +{ + ImGui_ImplGlfw_InvalidateDeviceObjects(); + ImGui::Shutdown(); +} + +void ImGui_ImplGlfw_NewFrame() +{ + if (!g_FontTexture) + ImGui_ImplGlfw_CreateDeviceObjects(); + + ImGuiIO& io = ImGui::GetIO(); + + // Setup display size (every frame to accommodate for window resizing) + int w, h; + int display_w, display_h; + glfwGetWindowSize(g_Window, &w, &h); + glfwGetFramebufferSize(g_Window, &display_w, &display_h); + io.DisplaySize = ImVec2((float)w, (float)h); + io.DisplayFramebufferScale = ImVec2(w > 0 ? ((float)display_w / w) : 0, h > 0 ? ((float)display_h / h) : 0); + + // Setup time step + double current_time = glfwGetTime(); + io.DeltaTime = g_Time > 0.0 ? (float)(current_time - g_Time) : (float)(1.0f/60.0f); + g_Time = current_time; + + // Setup inputs + // (we already got mouse wheel, keyboard keys & characters from glfw callbacks polled in glfwPollEvents()) + if (glfwGetWindowAttrib(g_Window, GLFW_FOCUSED)) + { + double mouse_x, mouse_y; + glfwGetCursorPos(g_Window, &mouse_x, &mouse_y); + io.MousePos = ImVec2((float)mouse_x, (float)mouse_y); // Mouse position in screen coordinates (set to -1,-1 if no mouse / on another screen, etc.) + } + else + { + io.MousePos = ImVec2(-1,-1); + } + + for (int i = 0; i < 3; i++) + { + io.MouseDown[i] = g_MousePressed[i] || glfwGetMouseButton(g_Window, i) != 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. + g_MousePressed[i] = false; + } + + io.MouseWheel = g_MouseWheel; + g_MouseWheel = 0.0f; + + // Hide OS mouse cursor if ImGui is drawing it + glfwSetInputMode(g_Window, GLFW_CURSOR, io.MouseDrawCursor ? GLFW_CURSOR_HIDDEN : GLFW_CURSOR_NORMAL); + + // Start the frame + ImGui::NewFrame(); +} diff --git a/examples/opengl2_example/imgui_impl_glfw.h b/examples/opengl2_example/imgui_impl_glfw.h new file mode 100644 index 0000000..07dd96f --- /dev/null +++ b/examples/opengl2_example/imgui_impl_glfw.h @@ -0,0 +1,29 @@ +// ImGui GLFW binding with OpenGL +// In this binding, ImTextureID is used to store an OpenGL 'GLuint' texture identifier. Read the FAQ about ImTextureID in imgui.cpp. + +// If your context is GL3/GL3 then prefer using the code in opengl3_example. +// You *might* use this code with a GL3/GL4 context but make sure you disable the programmable pipeline by calling "glUseProgram(0)" before ImGui::Render(). +// We cannot do that from GL2 code because the function doesn't exist. + +// You can copy and use unmodified imgui_impl_* files in your project. See main.cpp for an example of using this. +// If you use this binding you'll need to call 4 functions: ImGui_ImplXXXX_Init(), ImGui_ImplXXXX_NewFrame(), ImGui::Render() and ImGui_ImplXXXX_Shutdown(). +// If you are new to ImGui, see examples/README.txt and documentation at the top of imgui.cpp. +// https://github.com/ocornut/imgui + +struct GLFWwindow; + +IMGUI_API bool ImGui_ImplGlfw_Init(GLFWwindow* window, bool install_callbacks); +IMGUI_API void ImGui_ImplGlfw_Shutdown(); +IMGUI_API void ImGui_ImplGlfw_NewFrame(); + +// Use if you want to reset your rendering device without losing ImGui state. +IMGUI_API void ImGui_ImplGlfw_InvalidateDeviceObjects(); +IMGUI_API bool ImGui_ImplGlfw_CreateDeviceObjects(); + +// GLFW callbacks (installed by default if you enable 'install_callbacks' during initialization) +// Provided here if you want to chain callbacks. +// You can also handle inputs yourself and use those as a reference. +IMGUI_API void ImGui_ImplGlfw_MouseButtonCallback(GLFWwindow* window, int button, int action, int mods); +IMGUI_API void ImGui_ImplGlfw_ScrollCallback(GLFWwindow* window, double xoffset, double yoffset); +IMGUI_API void ImGui_ImplGlFw_KeyCallback(GLFWwindow* window, int key, int scancode, int action, int mods); +IMGUI_API void ImGui_ImplGlfw_CharCallback(GLFWwindow* window, unsigned int c); diff --git a/examples/opengl2_example/main.cpp b/examples/opengl2_example/main.cpp new file mode 100644 index 0000000..a844db5 --- /dev/null +++ b/examples/opengl2_example/main.cpp @@ -0,0 +1,89 @@ +// ImGui - standalone example application for Glfw + OpenGL 2, using fixed pipeline +// If you are new to ImGui, see examples/README.txt and documentation at the top of imgui.cpp. + +#include +#include "imgui_impl_glfw.h" +#include +#include + +static void error_callback(int error, const char* description) +{ + fprintf(stderr, "Error %d: %s\n", error, description); +} + +int main(int, char**) +{ + // Setup window + glfwSetErrorCallback(error_callback); + if (!glfwInit()) + return 1; + GLFWwindow* window = glfwCreateWindow(1280, 720, "ImGui OpenGL2 example", NULL, NULL); + glfwMakeContextCurrent(window); + + // Setup ImGui binding + ImGui_ImplGlfw_Init(window, true); + + // Load Fonts + // (there is a default font, this is only if you want to change it. see extra_fonts/README.txt for more details) + //ImGuiIO& io = ImGui::GetIO(); + //io.Fonts->AddFontDefault(); + //io.Fonts->AddFontFromFileTTF("../../extra_fonts/Cousine-Regular.ttf", 15.0f); + //io.Fonts->AddFontFromFileTTF("../../extra_fonts/DroidSans.ttf", 16.0f); + //io.Fonts->AddFontFromFileTTF("../../extra_fonts/ProggyClean.ttf", 13.0f); + //io.Fonts->AddFontFromFileTTF("../../extra_fonts/ProggyTiny.ttf", 10.0f); + //io.Fonts->AddFontFromFileTTF("c:\\Windows\\Fonts\\ArialUni.ttf", 18.0f, NULL, io.Fonts->GetGlyphRangesJapanese()); + + bool show_test_window = true; + bool show_another_window = false; + ImVec4 clear_color = ImColor(114, 144, 154); + + // Main loop + while (!glfwWindowShouldClose(window)) + { + glfwPollEvents(); + ImGui_ImplGlfw_NewFrame(); + + // 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 = 0.0f; + ImGui::Text("Hello, world!"); + ImGui::SliderFloat("float", &f, 0.0f, 1.0f); + ImGui::ColorEdit3("clear color", (float*)&clear_color); + if (ImGui::Button("Test Window")) show_test_window ^= 1; + if (ImGui::Button("Another Window")) show_another_window ^= 1; + ImGui::Text("Application average %.3f ms/frame (%.1f FPS)", 1000.0f / ImGui::GetIO().Framerate, ImGui::GetIO().Framerate); + } + + // 2. Show another simple window, this time using an explicit Begin/End pair + if (show_another_window) + { + ImGui::SetNextWindowSize(ImVec2(200,100), ImGuiSetCond_FirstUseEver); + ImGui::Begin("Another Window", &show_another_window); + 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::SetNextWindowPos(ImVec2(650, 20), ImGuiSetCond_FirstUseEver); + ImGui::ShowTestWindow(&show_test_window); + } + + // Rendering + int display_w, display_h; + glfwGetFramebufferSize(window, &display_w, &display_h); + glViewport(0, 0, display_w, display_h); + glClearColor(clear_color.x, clear_color.y, clear_color.z, clear_color.w); + glClear(GL_COLOR_BUFFER_BIT); + ImGui::Render(); + glfwSwapBuffers(window); + } + + // Cleanup + ImGui_ImplGlfw_Shutdown(); + glfwTerminate(); + + return 0; +} diff --git a/examples/opengl2_example/opengl_example.vcxproj b/examples/opengl2_example/opengl_example.vcxproj new file mode 100644 index 0000000..4b354b6 --- /dev/null +++ b/examples/opengl2_example/opengl_example.vcxproj @@ -0,0 +1,169 @@ + + + + + Debug + Win32 + + + Debug + x64 + + + Release + Win32 + + + Release + x64 + + + + {9CDA7840-B7A5-496D-A527-E95571496D18} + opengl_example + + + + Application + true + MultiByte + + + Application + true + MultiByte + + + Application + false + true + MultiByte + + + Application + false + true + MultiByte + + + + + + + + + + + + + + + + + + + $(ProjectDir)$(Configuration)\ + $(ProjectDir)$(Configuration)\ + $(IncludePath) + + + $(ProjectDir)$(Configuration)\ + $(ProjectDir)$(Configuration)\ + $(IncludePath) + + + $(ProjectDir)$(Configuration)\ + $(ProjectDir)$(Configuration)\ + $(IncludePath) + + + $(ProjectDir)$(Configuration)\ + $(ProjectDir)$(Configuration)\ + $(IncludePath) + + + + Level4 + Disabled + $(SolutionDir)\libs\glfw\include;..\..;%(AdditionalIncludeDirectories) + + + true + $(SolutionDir)\libs\glfw\lib-vc2010-32;%(AdditionalLibraryDirectories) + opengl32.lib;glfw3.lib;%(AdditionalDependencies) + Console + msvcrt.lib + + + + + Level4 + Disabled + $(SolutionDir)\libs\glfw\include;..\..;%(AdditionalIncludeDirectories) + + + true + $(SolutionDir)\libs\glfw\lib-vc2010-64;%(AdditionalLibraryDirectories) + opengl32.lib;glfw3.lib;%(AdditionalDependencies) + Console + msvcrt.lib + + + + + Level4 + MaxSpeed + true + true + $(SolutionDir)\libs\glfw\include;..\..;%(AdditionalIncludeDirectories) + + + true + true + true + $(SolutionDir)\libs\glfw\lib-vc2010-32;%(AdditionalLibraryDirectories) + opengl32.lib;glfw3.lib;%(AdditionalDependencies) + Console + + + + + + + Level4 + MaxSpeed + true + true + $(SolutionDir)\libs\glfw\include;..\..;%(AdditionalIncludeDirectories) + + + true + true + true + $(SolutionDir)\libs\glfw\lib-vc2010-64;%(AdditionalLibraryDirectories) + opengl32.lib;glfw3.lib;%(AdditionalDependencies) + Console + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/examples/opengl2_example/opengl_example.vcxproj.filters b/examples/opengl2_example/opengl_example.vcxproj.filters new file mode 100644 index 0000000..f2282bf --- /dev/null +++ b/examples/opengl2_example/opengl_example.vcxproj.filters @@ -0,0 +1,46 @@ + + + + + {c336cfe3-f0c4-464c-9ef0-a9e17a7ff222} + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx + + + + + sources + + + imgui + + + sources + + + imgui + + + imgui + + + + + imgui + + + imgui + + + sources + + + imgui + + + + + + \ No newline at end of file diff --git a/examples/opengl_example/Makefile b/examples/opengl_example/Makefile deleted file mode 100644 index 91d1b14..0000000 --- a/examples/opengl_example/Makefile +++ /dev/null @@ -1,60 +0,0 @@ -# -# Cross Platform Makefile -# Compatible with Ubuntu 14.04.1 and Mac OS X -# -# -# if you using Mac OS X: -# You'll need glfw -# http://www.glfw.org -# - -#CXX = g++ - -EXE = opengl_example -OBJS = main.o imgui_impl_glfw.o -OBJS += ../../imgui.o ../../imgui_demo.o ../../imgui_draw.o - -UNAME_S := $(shell uname -s) - - -ifeq ($(UNAME_S), Linux) #LINUX - ECHO_MESSAGE = "Linux" - LIBS = -lGL `pkg-config --static --libs glfw3` - - CXXFLAGS = -I../../ `pkg-config --cflags glfw3` - CXXFLAGS += -Wall -Wformat - CFLAGS = $(CXXFLAGS) -endif - -ifeq ($(UNAME_S), Darwin) #APPLE - ECHO_MESSAGE = "Mac OS X" - LIBS = -framework OpenGL -framework Cocoa -framework IOKit -framework CoreVideo - LIBS += -L/usr/local/lib -lglfw3 - - CXXFLAGS = -I../../ -I/usr/local/include - CXXFLAGS += -Wall -Wformat -# CXXFLAGS += -D__APPLE__ - CFLAGS = $(CXXFLAGS) -endif - -ifeq ($(UNAME_S), MINGW64_NT-6.3) - ECHO_MESSAGE = "Windows" - LIBS = -lglfw3 -lgdi32 -lopengl32 -limm32 - - CXXFLAGS = -I../../ -I../libs/gl3w `pkg-config --cflags glfw3` - CXXFLAGS += -Wall -Wformat - CFLAGS = $(CXXFLAGS) -endif - -.cpp.o: - $(CXX) $(CXXFLAGS) -c -o $@ $< - -all: $(EXE) - @echo Build complete for $(ECHO_MESSAGE) - -$(EXE): $(OBJS) - $(CXX) -o $(EXE) $(OBJS) $(CXXFLAGS) $(LIBS) - -clean: - rm $(EXE) $(OBJS) - diff --git a/examples/opengl_example/build_win32.bat b/examples/opengl_example/build_win32.bat deleted file mode 100644 index 278381c..0000000 --- a/examples/opengl_example/build_win32.bat +++ /dev/null @@ -1,3 +0,0 @@ -@REM Build for Visual Studio compiler. Run your copy of vcvars32.bat or vcvarsall.bat to setup command-line compiler. -mkdir Debug -cl /nologo /Zi /MD /I ..\.. /I ..\libs\glfw\include *.cpp ..\..\*.cpp /FeDebug/opengl_example.exe /FoDebug/ /link /LIBPATH:..\libs\glfw\lib-vc2010-32 glfw3.lib opengl32.lib gdi32.lib shell32.lib diff --git a/examples/opengl_example/imgui_impl_glfw.cpp b/examples/opengl_example/imgui_impl_glfw.cpp deleted file mode 100644 index 2d1f5c1..0000000 --- a/examples/opengl_example/imgui_impl_glfw.cpp +++ /dev/null @@ -1,288 +0,0 @@ -// ImGui GLFW binding with OpenGL -// In this binding, ImTextureID is used to store an OpenGL 'GLuint' texture identifier. Read the FAQ about ImTextureID in imgui.cpp. - -// If your context is GL3/GL3 then prefer using the code in opengl3_example. -// You *might* use this code with a GL3/GL4 context but make sure you disable the programmable pipeline by calling "glUseProgram(0)" before ImGui::Render(). -// We cannot do that from GL2 code because the function doesn't exist. - -// You can copy and use unmodified imgui_impl_* files in your project. See main.cpp for an example of using this. -// If you use this binding you'll need to call 4 functions: ImGui_ImplXXXX_Init(), ImGui_ImplXXXX_NewFrame(), ImGui::Render() and ImGui_ImplXXXX_Shutdown(). -// If you are new to ImGui, see examples/README.txt and documentation at the top of imgui.cpp. -// https://github.com/ocornut/imgui - -#include -#include "imgui_impl_glfw.h" - -// GLFW -#include -#ifdef _WIN32 -#undef APIENTRY -#define GLFW_EXPOSE_NATIVE_WIN32 -#define GLFW_EXPOSE_NATIVE_WGL -#include -#endif - -// Data -static GLFWwindow* g_Window = NULL; -static double g_Time = 0.0f; -static bool g_MousePressed[3] = { false, false, false }; -static float g_MouseWheel = 0.0f; -static GLuint g_FontTexture = 0; - -// 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) -void ImGui_ImplGlfw_RenderDrawLists(ImDrawData* draw_data) -{ - // Avoid rendering when minimized, scale coordinates for retina displays (screen coordinates != framebuffer coordinates) - ImGuiIO& io = ImGui::GetIO(); - int fb_width = (int)(io.DisplaySize.x * io.DisplayFramebufferScale.x); - int fb_height = (int)(io.DisplaySize.y * io.DisplayFramebufferScale.y); - if (fb_width == 0 || fb_height == 0) - return; - draw_data->ScaleClipRects(io.DisplayFramebufferScale); - - // We are using the OpenGL fixed pipeline to make the example code simpler to read! - // Setup render state: alpha-blending enabled, no face culling, no depth testing, scissor enabled, vertex/texcoord/color pointers. - GLint last_texture; glGetIntegerv(GL_TEXTURE_BINDING_2D, &last_texture); - GLint last_viewport[4]; glGetIntegerv(GL_VIEWPORT, last_viewport); - glPushAttrib(GL_ENABLE_BIT | GL_COLOR_BUFFER_BIT | GL_TRANSFORM_BIT); - glEnable(GL_BLEND); - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - glDisable(GL_CULL_FACE); - glDisable(GL_DEPTH_TEST); - glEnable(GL_SCISSOR_TEST); - glEnableClientState(GL_VERTEX_ARRAY); - glEnableClientState(GL_TEXTURE_COORD_ARRAY); - glEnableClientState(GL_COLOR_ARRAY); - glEnable(GL_TEXTURE_2D); - //glUseProgram(0); // You may want this if using this code in an OpenGL 3+ context - - // Setup viewport, orthographic projection matrix - glViewport(0, 0, (GLsizei)fb_width, (GLsizei)fb_height); - glMatrixMode(GL_PROJECTION); - glPushMatrix(); - glLoadIdentity(); - glOrtho(0.0f, io.DisplaySize.x, io.DisplaySize.y, 0.0f, -1.0f, +1.0f); - glMatrixMode(GL_MODELVIEW); - glPushMatrix(); - glLoadIdentity(); - - // Render command lists - #define OFFSETOF(TYPE, ELEMENT) ((size_t)&(((TYPE *)0)->ELEMENT)) - for (int n = 0; n < draw_data->CmdListsCount; n++) - { - const ImDrawList* cmd_list = draw_data->CmdLists[n]; - const unsigned char* vtx_buffer = (const unsigned char*)&cmd_list->VtxBuffer.front(); - const ImDrawIdx* idx_buffer = &cmd_list->IdxBuffer.front(); - glVertexPointer(2, GL_FLOAT, sizeof(ImDrawVert), (void*)(vtx_buffer + OFFSETOF(ImDrawVert, pos))); - glTexCoordPointer(2, GL_FLOAT, sizeof(ImDrawVert), (void*)(vtx_buffer + OFFSETOF(ImDrawVert, uv))); - glColorPointer(4, GL_UNSIGNED_BYTE, sizeof(ImDrawVert), (void*)(vtx_buffer + OFFSETOF(ImDrawVert, col))); - - for (int cmd_i = 0; cmd_i < cmd_list->CmdBuffer.size(); cmd_i++) - { - const ImDrawCmd* pcmd = &cmd_list->CmdBuffer[cmd_i]; - if (pcmd->UserCallback) - { - pcmd->UserCallback(cmd_list, pcmd); - } - else - { - glBindTexture(GL_TEXTURE_2D, (GLuint)(intptr_t)pcmd->TextureId); - glScissor((int)pcmd->ClipRect.x, (int)(fb_height - pcmd->ClipRect.w), (int)(pcmd->ClipRect.z - pcmd->ClipRect.x), (int)(pcmd->ClipRect.w - pcmd->ClipRect.y)); - glDrawElements(GL_TRIANGLES, (GLsizei)pcmd->ElemCount, sizeof(ImDrawIdx) == 2 ? GL_UNSIGNED_SHORT : GL_UNSIGNED_INT, idx_buffer); - } - idx_buffer += pcmd->ElemCount; - } - } - #undef OFFSETOF - - // Restore modified state - glDisableClientState(GL_COLOR_ARRAY); - glDisableClientState(GL_TEXTURE_COORD_ARRAY); - glDisableClientState(GL_VERTEX_ARRAY); - glBindTexture(GL_TEXTURE_2D, (GLuint)last_texture); - glMatrixMode(GL_MODELVIEW); - glPopMatrix(); - glMatrixMode(GL_PROJECTION); - glPopMatrix(); - glPopAttrib(); - glViewport(last_viewport[0], last_viewport[1], (GLsizei)last_viewport[2], (GLsizei)last_viewport[3]); -} - -static const char* ImGui_ImplGlfw_GetClipboardText() -{ - return glfwGetClipboardString(g_Window); -} - -static void ImGui_ImplGlfw_SetClipboardText(const char* text) -{ - glfwSetClipboardString(g_Window, text); -} - -void ImGui_ImplGlfw_MouseButtonCallback(GLFWwindow*, int button, int action, int /*mods*/) -{ - if (action == GLFW_PRESS && button >= 0 && button < 3) - g_MousePressed[button] = true; -} - -void ImGui_ImplGlfw_ScrollCallback(GLFWwindow*, double /*xoffset*/, double yoffset) -{ - g_MouseWheel += (float)yoffset; // Use fractional mouse wheel, 1.0 unit 5 lines. -} - -void ImGui_ImplGlFw_KeyCallback(GLFWwindow*, int key, int, int action, int mods) -{ - ImGuiIO& io = ImGui::GetIO(); - if (action == GLFW_PRESS) - io.KeysDown[key] = true; - if (action == GLFW_RELEASE) - io.KeysDown[key] = false; - - (void)mods; // Modifiers are not reliable across systems - io.KeyCtrl = io.KeysDown[GLFW_KEY_LEFT_CONTROL] || io.KeysDown[GLFW_KEY_RIGHT_CONTROL]; - io.KeyShift = io.KeysDown[GLFW_KEY_LEFT_SHIFT] || io.KeysDown[GLFW_KEY_RIGHT_SHIFT]; - io.KeyAlt = io.KeysDown[GLFW_KEY_LEFT_ALT] || io.KeysDown[GLFW_KEY_RIGHT_ALT]; - io.KeySuper = io.KeysDown[GLFW_KEY_LEFT_SUPER] || io.KeysDown[GLFW_KEY_RIGHT_SUPER]; -} - -void ImGui_ImplGlfw_CharCallback(GLFWwindow*, unsigned int c) -{ - ImGuiIO& io = ImGui::GetIO(); - if (c > 0 && c < 0x10000) - io.AddInputCharacter((unsigned short)c); -} - -bool ImGui_ImplGlfw_CreateDeviceObjects() -{ - // Build texture atlas - ImGuiIO& io = ImGui::GetIO(); - unsigned char* pixels; - int width, height; - io.Fonts->GetTexDataAsAlpha8(&pixels, &width, &height); - - // Upload texture to graphics system - GLint last_texture; - glGetIntegerv(GL_TEXTURE_BINDING_2D, &last_texture); - glGenTextures(1, &g_FontTexture); - glBindTexture(GL_TEXTURE_2D, g_FontTexture); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, width, height, 0, GL_ALPHA, GL_UNSIGNED_BYTE, pixels); - - // Store our identifier - io.Fonts->TexID = (void *)(intptr_t)g_FontTexture; - - // Restore state - glBindTexture(GL_TEXTURE_2D, last_texture); - - return true; -} - -void ImGui_ImplGlfw_InvalidateDeviceObjects() -{ - if (g_FontTexture) - { - glDeleteTextures(1, &g_FontTexture); - ImGui::GetIO().Fonts->TexID = 0; - g_FontTexture = 0; - } -} - -bool ImGui_ImplGlfw_Init(GLFWwindow* window, bool install_callbacks) -{ - g_Window = window; - - ImGuiIO& io = ImGui::GetIO(); - 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; - io.KeyMap[ImGuiKey_DownArrow] = GLFW_KEY_DOWN; - io.KeyMap[ImGuiKey_PageUp] = GLFW_KEY_PAGE_UP; - io.KeyMap[ImGuiKey_PageDown] = GLFW_KEY_PAGE_DOWN; - io.KeyMap[ImGuiKey_Home] = GLFW_KEY_HOME; - io.KeyMap[ImGuiKey_End] = GLFW_KEY_END; - io.KeyMap[ImGuiKey_Delete] = GLFW_KEY_DELETE; - io.KeyMap[ImGuiKey_Backspace] = GLFW_KEY_BACKSPACE; - io.KeyMap[ImGuiKey_Enter] = GLFW_KEY_ENTER; - io.KeyMap[ImGuiKey_Escape] = GLFW_KEY_ESCAPE; - io.KeyMap[ImGuiKey_A] = GLFW_KEY_A; - io.KeyMap[ImGuiKey_C] = GLFW_KEY_C; - io.KeyMap[ImGuiKey_V] = GLFW_KEY_V; - io.KeyMap[ImGuiKey_X] = GLFW_KEY_X; - io.KeyMap[ImGuiKey_Y] = GLFW_KEY_Y; - io.KeyMap[ImGuiKey_Z] = GLFW_KEY_Z; - - io.RenderDrawListsFn = ImGui_ImplGlfw_RenderDrawLists; // Alternatively you can set this to NULL and call ImGui::GetDrawData() after ImGui::Render() to get the same ImDrawData pointer. - io.SetClipboardTextFn = ImGui_ImplGlfw_SetClipboardText; - io.GetClipboardTextFn = ImGui_ImplGlfw_GetClipboardText; -#ifdef _WIN32 - io.ImeWindowHandle = glfwGetWin32Window(g_Window); -#endif - - if (install_callbacks) - { - glfwSetMouseButtonCallback(window, ImGui_ImplGlfw_MouseButtonCallback); - glfwSetScrollCallback(window, ImGui_ImplGlfw_ScrollCallback); - glfwSetKeyCallback(window, ImGui_ImplGlFw_KeyCallback); - glfwSetCharCallback(window, ImGui_ImplGlfw_CharCallback); - } - - return true; -} - -void ImGui_ImplGlfw_Shutdown() -{ - ImGui_ImplGlfw_InvalidateDeviceObjects(); - ImGui::Shutdown(); -} - -void ImGui_ImplGlfw_NewFrame() -{ - if (!g_FontTexture) - ImGui_ImplGlfw_CreateDeviceObjects(); - - ImGuiIO& io = ImGui::GetIO(); - - // Setup display size (every frame to accommodate for window resizing) - int w, h; - int display_w, display_h; - glfwGetWindowSize(g_Window, &w, &h); - glfwGetFramebufferSize(g_Window, &display_w, &display_h); - io.DisplaySize = ImVec2((float)w, (float)h); - io.DisplayFramebufferScale = ImVec2(w > 0 ? ((float)display_w / w) : 0, h > 0 ? ((float)display_h / h) : 0); - - // Setup time step - double current_time = glfwGetTime(); - io.DeltaTime = g_Time > 0.0 ? (float)(current_time - g_Time) : (float)(1.0f/60.0f); - g_Time = current_time; - - // Setup inputs - // (we already got mouse wheel, keyboard keys & characters from glfw callbacks polled in glfwPollEvents()) - if (glfwGetWindowAttrib(g_Window, GLFW_FOCUSED)) - { - double mouse_x, mouse_y; - glfwGetCursorPos(g_Window, &mouse_x, &mouse_y); - io.MousePos = ImVec2((float)mouse_x, (float)mouse_y); // Mouse position in screen coordinates (set to -1,-1 if no mouse / on another screen, etc.) - } - else - { - io.MousePos = ImVec2(-1,-1); - } - - for (int i = 0; i < 3; i++) - { - io.MouseDown[i] = g_MousePressed[i] || glfwGetMouseButton(g_Window, i) != 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. - g_MousePressed[i] = false; - } - - io.MouseWheel = g_MouseWheel; - g_MouseWheel = 0.0f; - - // Hide OS mouse cursor if ImGui is drawing it - glfwSetInputMode(g_Window, GLFW_CURSOR, io.MouseDrawCursor ? GLFW_CURSOR_HIDDEN : GLFW_CURSOR_NORMAL); - - // Start the frame - ImGui::NewFrame(); -} diff --git a/examples/opengl_example/imgui_impl_glfw.h b/examples/opengl_example/imgui_impl_glfw.h deleted file mode 100644 index 07dd96f..0000000 --- a/examples/opengl_example/imgui_impl_glfw.h +++ /dev/null @@ -1,29 +0,0 @@ -// ImGui GLFW binding with OpenGL -// In this binding, ImTextureID is used to store an OpenGL 'GLuint' texture identifier. Read the FAQ about ImTextureID in imgui.cpp. - -// If your context is GL3/GL3 then prefer using the code in opengl3_example. -// You *might* use this code with a GL3/GL4 context but make sure you disable the programmable pipeline by calling "glUseProgram(0)" before ImGui::Render(). -// We cannot do that from GL2 code because the function doesn't exist. - -// You can copy and use unmodified imgui_impl_* files in your project. See main.cpp for an example of using this. -// If you use this binding you'll need to call 4 functions: ImGui_ImplXXXX_Init(), ImGui_ImplXXXX_NewFrame(), ImGui::Render() and ImGui_ImplXXXX_Shutdown(). -// If you are new to ImGui, see examples/README.txt and documentation at the top of imgui.cpp. -// https://github.com/ocornut/imgui - -struct GLFWwindow; - -IMGUI_API bool ImGui_ImplGlfw_Init(GLFWwindow* window, bool install_callbacks); -IMGUI_API void ImGui_ImplGlfw_Shutdown(); -IMGUI_API void ImGui_ImplGlfw_NewFrame(); - -// Use if you want to reset your rendering device without losing ImGui state. -IMGUI_API void ImGui_ImplGlfw_InvalidateDeviceObjects(); -IMGUI_API bool ImGui_ImplGlfw_CreateDeviceObjects(); - -// GLFW callbacks (installed by default if you enable 'install_callbacks' during initialization) -// Provided here if you want to chain callbacks. -// You can also handle inputs yourself and use those as a reference. -IMGUI_API void ImGui_ImplGlfw_MouseButtonCallback(GLFWwindow* window, int button, int action, int mods); -IMGUI_API void ImGui_ImplGlfw_ScrollCallback(GLFWwindow* window, double xoffset, double yoffset); -IMGUI_API void ImGui_ImplGlFw_KeyCallback(GLFWwindow* window, int key, int scancode, int action, int mods); -IMGUI_API void ImGui_ImplGlfw_CharCallback(GLFWwindow* window, unsigned int c); diff --git a/examples/opengl_example/main.cpp b/examples/opengl_example/main.cpp deleted file mode 100644 index a844db5..0000000 --- a/examples/opengl_example/main.cpp +++ /dev/null @@ -1,89 +0,0 @@ -// ImGui - standalone example application for Glfw + OpenGL 2, using fixed pipeline -// If you are new to ImGui, see examples/README.txt and documentation at the top of imgui.cpp. - -#include -#include "imgui_impl_glfw.h" -#include -#include - -static void error_callback(int error, const char* description) -{ - fprintf(stderr, "Error %d: %s\n", error, description); -} - -int main(int, char**) -{ - // Setup window - glfwSetErrorCallback(error_callback); - if (!glfwInit()) - return 1; - GLFWwindow* window = glfwCreateWindow(1280, 720, "ImGui OpenGL2 example", NULL, NULL); - glfwMakeContextCurrent(window); - - // Setup ImGui binding - ImGui_ImplGlfw_Init(window, true); - - // Load Fonts - // (there is a default font, this is only if you want to change it. see extra_fonts/README.txt for more details) - //ImGuiIO& io = ImGui::GetIO(); - //io.Fonts->AddFontDefault(); - //io.Fonts->AddFontFromFileTTF("../../extra_fonts/Cousine-Regular.ttf", 15.0f); - //io.Fonts->AddFontFromFileTTF("../../extra_fonts/DroidSans.ttf", 16.0f); - //io.Fonts->AddFontFromFileTTF("../../extra_fonts/ProggyClean.ttf", 13.0f); - //io.Fonts->AddFontFromFileTTF("../../extra_fonts/ProggyTiny.ttf", 10.0f); - //io.Fonts->AddFontFromFileTTF("c:\\Windows\\Fonts\\ArialUni.ttf", 18.0f, NULL, io.Fonts->GetGlyphRangesJapanese()); - - bool show_test_window = true; - bool show_another_window = false; - ImVec4 clear_color = ImColor(114, 144, 154); - - // Main loop - while (!glfwWindowShouldClose(window)) - { - glfwPollEvents(); - ImGui_ImplGlfw_NewFrame(); - - // 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 = 0.0f; - ImGui::Text("Hello, world!"); - ImGui::SliderFloat("float", &f, 0.0f, 1.0f); - ImGui::ColorEdit3("clear color", (float*)&clear_color); - if (ImGui::Button("Test Window")) show_test_window ^= 1; - if (ImGui::Button("Another Window")) show_another_window ^= 1; - ImGui::Text("Application average %.3f ms/frame (%.1f FPS)", 1000.0f / ImGui::GetIO().Framerate, ImGui::GetIO().Framerate); - } - - // 2. Show another simple window, this time using an explicit Begin/End pair - if (show_another_window) - { - ImGui::SetNextWindowSize(ImVec2(200,100), ImGuiSetCond_FirstUseEver); - ImGui::Begin("Another Window", &show_another_window); - 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::SetNextWindowPos(ImVec2(650, 20), ImGuiSetCond_FirstUseEver); - ImGui::ShowTestWindow(&show_test_window); - } - - // Rendering - int display_w, display_h; - glfwGetFramebufferSize(window, &display_w, &display_h); - glViewport(0, 0, display_w, display_h); - glClearColor(clear_color.x, clear_color.y, clear_color.z, clear_color.w); - glClear(GL_COLOR_BUFFER_BIT); - ImGui::Render(); - glfwSwapBuffers(window); - } - - // Cleanup - ImGui_ImplGlfw_Shutdown(); - glfwTerminate(); - - return 0; -} diff --git a/examples/opengl_example/opengl_example.vcxproj b/examples/opengl_example/opengl_example.vcxproj deleted file mode 100644 index 4b354b6..0000000 --- a/examples/opengl_example/opengl_example.vcxproj +++ /dev/null @@ -1,169 +0,0 @@ - - - - - Debug - Win32 - - - Debug - x64 - - - Release - Win32 - - - Release - x64 - - - - {9CDA7840-B7A5-496D-A527-E95571496D18} - opengl_example - - - - Application - true - MultiByte - - - Application - true - MultiByte - - - Application - false - true - MultiByte - - - Application - false - true - MultiByte - - - - - - - - - - - - - - - - - - - $(ProjectDir)$(Configuration)\ - $(ProjectDir)$(Configuration)\ - $(IncludePath) - - - $(ProjectDir)$(Configuration)\ - $(ProjectDir)$(Configuration)\ - $(IncludePath) - - - $(ProjectDir)$(Configuration)\ - $(ProjectDir)$(Configuration)\ - $(IncludePath) - - - $(ProjectDir)$(Configuration)\ - $(ProjectDir)$(Configuration)\ - $(IncludePath) - - - - Level4 - Disabled - $(SolutionDir)\libs\glfw\include;..\..;%(AdditionalIncludeDirectories) - - - true - $(SolutionDir)\libs\glfw\lib-vc2010-32;%(AdditionalLibraryDirectories) - opengl32.lib;glfw3.lib;%(AdditionalDependencies) - Console - msvcrt.lib - - - - - Level4 - Disabled - $(SolutionDir)\libs\glfw\include;..\..;%(AdditionalIncludeDirectories) - - - true - $(SolutionDir)\libs\glfw\lib-vc2010-64;%(AdditionalLibraryDirectories) - opengl32.lib;glfw3.lib;%(AdditionalDependencies) - Console - msvcrt.lib - - - - - Level4 - MaxSpeed - true - true - $(SolutionDir)\libs\glfw\include;..\..;%(AdditionalIncludeDirectories) - - - true - true - true - $(SolutionDir)\libs\glfw\lib-vc2010-32;%(AdditionalLibraryDirectories) - opengl32.lib;glfw3.lib;%(AdditionalDependencies) - Console - - - - - - - Level4 - MaxSpeed - true - true - $(SolutionDir)\libs\glfw\include;..\..;%(AdditionalIncludeDirectories) - - - true - true - true - $(SolutionDir)\libs\glfw\lib-vc2010-64;%(AdditionalLibraryDirectories) - opengl32.lib;glfw3.lib;%(AdditionalDependencies) - Console - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/examples/opengl_example/opengl_example.vcxproj.filters b/examples/opengl_example/opengl_example.vcxproj.filters deleted file mode 100644 index f2282bf..0000000 --- a/examples/opengl_example/opengl_example.vcxproj.filters +++ /dev/null @@ -1,46 +0,0 @@ - - - - - {c336cfe3-f0c4-464c-9ef0-a9e17a7ff222} - - - {4FC737F1-C7A5-4376-A066-2A32D752A2FF} - cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx - - - - - sources - - - imgui - - - sources - - - imgui - - - imgui - - - - - imgui - - - imgui - - - sources - - - imgui - - - - - - \ No newline at end of file diff --git a/examples/sdl_opengl2_example/README.md b/examples/sdl_opengl2_example/README.md new file mode 100644 index 0000000..aada45d --- /dev/null +++ b/examples/sdl_opengl2_example/README.md @@ -0,0 +1,22 @@ + +# How to Build + +- On Windows with Visual Studio's CLI + +``` +set SDL2DIR=path_to_your_sdl2_folder +cl /Zi /MD /I %SDL2DIR%\include> /I ..\.. main.cpp imgui_impl_sdl.cpp ..\..\imgui*.cpp /link /LIBPATH:%SDL2DIR%\lib SDL2.lib SDL2main.lib +``` + +- On Linux and similar Unixes + +``` +c++ `sdl2-config --cflags` -I ../.. main.cpp imgui_impl_sdl.cpp ../../imgui*.cpp `sdl2-config --libs` -lGL -o sdl2example +``` + +- On Mac OS X + +``` +brew install sdl2 +c++ `sdl2-config --cflags` -I ../.. main.cpp imgui_impl_sdl.cpp ../../imgui*.cpp `sdl2-config --libs` -framework OpenGl -o sdl2example +``` diff --git a/examples/sdl_opengl2_example/imgui_impl_sdl.cpp b/examples/sdl_opengl2_example/imgui_impl_sdl.cpp new file mode 100644 index 0000000..63ed9f4 --- /dev/null +++ b/examples/sdl_opengl2_example/imgui_impl_sdl.cpp @@ -0,0 +1,277 @@ +// ImGui SDL2 binding with OpenGL +// In this binding, ImTextureID is used to store an OpenGL 'GLuint' texture identifier. Read the FAQ about ImTextureID in imgui.cpp. + +// You can copy and use unmodified imgui_impl_* files in your project. See main.cpp for an example of using this. +// If you use this binding you'll need to call 4 functions: ImGui_ImplXXXX_Init(), ImGui_ImplXXXX_NewFrame(), ImGui::Render() and ImGui_ImplXXXX_Shutdown(). +// If you are new to ImGui, see examples/README.txt and documentation at the top of imgui.cpp. +// https://github.com/ocornut/imgui + +#include +#include +#include +#include +#include "imgui_impl_sdl.h" + +// Data +static double g_Time = 0.0f; +static bool g_MousePressed[3] = { false, false, false }; +static float g_MouseWheel = 0.0f; +static GLuint g_FontTexture = 0; + +// 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) +void ImGui_ImplSdl_RenderDrawLists(ImDrawData* draw_data) +{ + // Avoid rendering when minimized, scale coordinates for retina displays (screen coordinates != framebuffer coordinates) + ImGuiIO& io = ImGui::GetIO(); + int fb_width = (int)(io.DisplaySize.x * io.DisplayFramebufferScale.x); + int fb_height = (int)(io.DisplaySize.y * io.DisplayFramebufferScale.y); + if (fb_width == 0 || fb_height == 0) + return; + draw_data->ScaleClipRects(io.DisplayFramebufferScale); + + // We are using the OpenGL fixed pipeline to make the example code simpler to read! + // Setup render state: alpha-blending enabled, no face culling, no depth testing, scissor enabled, vertex/texcoord/color pointers. + GLint last_texture; glGetIntegerv(GL_TEXTURE_BINDING_2D, &last_texture); + GLint last_viewport[4]; glGetIntegerv(GL_VIEWPORT, last_viewport); + glPushAttrib(GL_ENABLE_BIT | GL_COLOR_BUFFER_BIT | GL_TRANSFORM_BIT); + glEnable(GL_BLEND); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + glDisable(GL_CULL_FACE); + glDisable(GL_DEPTH_TEST); + glEnable(GL_SCISSOR_TEST); + glEnableClientState(GL_VERTEX_ARRAY); + glEnableClientState(GL_TEXTURE_COORD_ARRAY); + glEnableClientState(GL_COLOR_ARRAY); + glEnable(GL_TEXTURE_2D); + //glUseProgram(0); // You may want this if using this code in an OpenGL 3+ context + + // Setup viewport, orthographic projection matrix + glViewport(0, 0, (GLsizei)fb_width, (GLsizei)fb_height); + glMatrixMode(GL_PROJECTION); + glPushMatrix(); + glLoadIdentity(); + glOrtho(0.0f, io.DisplaySize.x, io.DisplaySize.y, 0.0f, -1.0f, +1.0f); + glMatrixMode(GL_MODELVIEW); + glPushMatrix(); + glLoadIdentity(); + + // Render command lists + #define OFFSETOF(TYPE, ELEMENT) ((size_t)&(((TYPE *)0)->ELEMENT)) + for (int n = 0; n < draw_data->CmdListsCount; n++) + { + const ImDrawList* cmd_list = draw_data->CmdLists[n]; + const unsigned char* vtx_buffer = (const unsigned char*)&cmd_list->VtxBuffer.front(); + const ImDrawIdx* idx_buffer = &cmd_list->IdxBuffer.front(); + glVertexPointer(2, GL_FLOAT, sizeof(ImDrawVert), (void*)(vtx_buffer + OFFSETOF(ImDrawVert, pos))); + glTexCoordPointer(2, GL_FLOAT, sizeof(ImDrawVert), (void*)(vtx_buffer + OFFSETOF(ImDrawVert, uv))); + glColorPointer(4, GL_UNSIGNED_BYTE, sizeof(ImDrawVert), (void*)(vtx_buffer + OFFSETOF(ImDrawVert, col))); + + for (int cmd_i = 0; cmd_i < cmd_list->CmdBuffer.size(); cmd_i++) + { + const ImDrawCmd* pcmd = &cmd_list->CmdBuffer[cmd_i]; + if (pcmd->UserCallback) + { + pcmd->UserCallback(cmd_list, pcmd); + } + else + { + glBindTexture(GL_TEXTURE_2D, (GLuint)(intptr_t)pcmd->TextureId); + glScissor((int)pcmd->ClipRect.x, (int)(fb_height - pcmd->ClipRect.w), (int)(pcmd->ClipRect.z - pcmd->ClipRect.x), (int)(pcmd->ClipRect.w - pcmd->ClipRect.y)); + glDrawElements(GL_TRIANGLES, (GLsizei)pcmd->ElemCount, sizeof(ImDrawIdx) == 2 ? GL_UNSIGNED_SHORT : GL_UNSIGNED_INT, idx_buffer); + } + idx_buffer += pcmd->ElemCount; + } + } + #undef OFFSETOF + + // Restore modified state + glDisableClientState(GL_COLOR_ARRAY); + glDisableClientState(GL_TEXTURE_COORD_ARRAY); + glDisableClientState(GL_VERTEX_ARRAY); + glBindTexture(GL_TEXTURE_2D, (GLuint)last_texture); + glMatrixMode(GL_MODELVIEW); + glPopMatrix(); + glMatrixMode(GL_PROJECTION); + glPopMatrix(); + glPopAttrib(); + glViewport(last_viewport[0], last_viewport[1], (GLsizei)last_viewport[2], (GLsizei)last_viewport[3]); +} + +static const char* ImGui_ImplSdl_GetClipboardText() +{ + return SDL_GetClipboardText(); +} + +static void ImGui_ImplSdl_SetClipboardText(const char* text) +{ + SDL_SetClipboardText(text); +} + +bool ImGui_ImplSdl_ProcessEvent(SDL_Event* event) +{ + ImGuiIO& io = ImGui::GetIO(); + switch (event->type) + { + case SDL_MOUSEWHEEL: + { + if (event->wheel.y > 0) + g_MouseWheel = 1; + if (event->wheel.y < 0) + g_MouseWheel = -1; + return true; + } + case SDL_MOUSEBUTTONDOWN: + { + if (event->button.button == SDL_BUTTON_LEFT) g_MousePressed[0] = true; + if (event->button.button == SDL_BUTTON_RIGHT) g_MousePressed[1] = true; + if (event->button.button == SDL_BUTTON_MIDDLE) g_MousePressed[2] = true; + return true; + } + case SDL_TEXTINPUT: + { + io.AddInputCharactersUTF8(event->text.text); + return true; + } + case SDL_KEYDOWN: + case SDL_KEYUP: + { + int key = event->key.keysym.sym & ~SDLK_SCANCODE_MASK; + io.KeysDown[key] = (event->type == SDL_KEYDOWN); + io.KeyShift = ((SDL_GetModState() & KMOD_SHIFT) != 0); + io.KeyCtrl = ((SDL_GetModState() & KMOD_CTRL) != 0); + io.KeyAlt = ((SDL_GetModState() & KMOD_ALT) != 0); + io.KeySuper = ((SDL_GetModState() & KMOD_GUI) != 0); + return true; + } + } + return false; +} + +bool ImGui_ImplSdl_CreateDeviceObjects() +{ + // Build texture atlas + ImGuiIO& io = ImGui::GetIO(); + unsigned char* pixels; + int width, height; + io.Fonts->GetTexDataAsAlpha8(&pixels, &width, &height); + + // Upload texture to graphics system + GLint last_texture; + glGetIntegerv(GL_TEXTURE_BINDING_2D, &last_texture); + glGenTextures(1, &g_FontTexture); + glBindTexture(GL_TEXTURE_2D, g_FontTexture); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glPixelStorei(GL_UNPACK_ROW_LENGTH, 0); + glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, width, height, 0, GL_ALPHA, GL_UNSIGNED_BYTE, pixels); + + // Store our identifier + io.Fonts->TexID = (void *)(intptr_t)g_FontTexture; + + // Restore state + glBindTexture(GL_TEXTURE_2D, last_texture); + + return true; +} + +void ImGui_ImplSdl_InvalidateDeviceObjects() +{ + if (g_FontTexture) + { + glDeleteTextures(1, &g_FontTexture); + ImGui::GetIO().Fonts->TexID = 0; + g_FontTexture = 0; + } +} + +bool ImGui_ImplSdl_Init(SDL_Window* window) +{ + ImGuiIO& io = ImGui::GetIO(); + io.KeyMap[ImGuiKey_Tab] = SDLK_TAB; // Keyboard mapping. ImGui will use those indices to peek into the io.KeyDown[] array. + io.KeyMap[ImGuiKey_LeftArrow] = SDL_SCANCODE_LEFT; + io.KeyMap[ImGuiKey_RightArrow] = SDL_SCANCODE_RIGHT; + io.KeyMap[ImGuiKey_UpArrow] = SDL_SCANCODE_UP; + io.KeyMap[ImGuiKey_DownArrow] = SDL_SCANCODE_DOWN; + io.KeyMap[ImGuiKey_PageUp] = SDL_SCANCODE_PAGEUP; + io.KeyMap[ImGuiKey_PageDown] = SDL_SCANCODE_PAGEDOWN; + io.KeyMap[ImGuiKey_Home] = SDL_SCANCODE_HOME; + io.KeyMap[ImGuiKey_End] = SDL_SCANCODE_END; + io.KeyMap[ImGuiKey_Delete] = SDLK_DELETE; + io.KeyMap[ImGuiKey_Backspace] = SDLK_BACKSPACE; + io.KeyMap[ImGuiKey_Enter] = SDLK_RETURN; + io.KeyMap[ImGuiKey_Escape] = SDLK_ESCAPE; + io.KeyMap[ImGuiKey_A] = SDLK_a; + io.KeyMap[ImGuiKey_C] = SDLK_c; + io.KeyMap[ImGuiKey_V] = SDLK_v; + io.KeyMap[ImGuiKey_X] = SDLK_x; + io.KeyMap[ImGuiKey_Y] = SDLK_y; + io.KeyMap[ImGuiKey_Z] = SDLK_z; + + io.RenderDrawListsFn = ImGui_ImplSdl_RenderDrawLists; // Alternatively you can set this to NULL and call ImGui::GetDrawData() after ImGui::Render() to get the same ImDrawData pointer. + io.SetClipboardTextFn = ImGui_ImplSdl_SetClipboardText; + io.GetClipboardTextFn = ImGui_ImplSdl_GetClipboardText; + +#ifdef _WIN32 + SDL_SysWMinfo wmInfo; + SDL_VERSION(&wmInfo.version); + SDL_GetWindowWMInfo(window, &wmInfo); + io.ImeWindowHandle = wmInfo.info.win.window; +#else + (void)window; +#endif + + return true; +} + +void ImGui_ImplSdl_Shutdown() +{ + ImGui_ImplSdl_InvalidateDeviceObjects(); + ImGui::Shutdown(); +} + +void ImGui_ImplSdl_NewFrame(SDL_Window *window) +{ + if (!g_FontTexture) + ImGui_ImplSdl_CreateDeviceObjects(); + + ImGuiIO& io = ImGui::GetIO(); + + // Setup display size (every frame to accommodate for window resizing) + int w, h; + int display_w, display_h; + SDL_GetWindowSize(window, &w, &h); + SDL_GL_GetDrawableSize(window, &display_w, &display_h); + io.DisplaySize = ImVec2((float)w, (float)h); + io.DisplayFramebufferScale = ImVec2(w > 0 ? ((float)display_w / w) : 0, h > 0 ? ((float)display_h / h) : 0); + + // Setup time step + Uint32 time = SDL_GetTicks(); + double current_time = time / 1000.0; + io.DeltaTime = g_Time > 0.0 ? (float)(current_time - g_Time) : (float)(1.0f/60.0f); + g_Time = current_time; + + // Setup inputs + // (we already got mouse wheel, keyboard keys & characters from SDL_PollEvent()) + int mx, my; + Uint32 mouseMask = SDL_GetMouseState(&mx, &my); + if (SDL_GetWindowFlags(window) & SDL_WINDOW_MOUSE_FOCUS) + io.MousePos = ImVec2((float)mx, (float)my); // Mouse position, in pixels (set to -1,-1 if no mouse / on another screen, etc.) + else + io.MousePos = ImVec2(-1,-1); + + io.MouseDown[0] = g_MousePressed[0] || (mouseMask & SDL_BUTTON(SDL_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] = g_MousePressed[1] || (mouseMask & SDL_BUTTON(SDL_BUTTON_RIGHT)) != 0; + io.MouseDown[2] = g_MousePressed[2] || (mouseMask & SDL_BUTTON(SDL_BUTTON_MIDDLE)) != 0; + g_MousePressed[0] = g_MousePressed[1] = g_MousePressed[2] = false; + + io.MouseWheel = g_MouseWheel; + g_MouseWheel = 0.0f; + + // Hide OS mouse cursor if ImGui is drawing it + SDL_ShowCursor(io.MouseDrawCursor ? 0 : 1); + + // Start the frame + ImGui::NewFrame(); +} diff --git a/examples/sdl_opengl2_example/imgui_impl_sdl.h b/examples/sdl_opengl2_example/imgui_impl_sdl.h new file mode 100644 index 0000000..a322bf2 --- /dev/null +++ b/examples/sdl_opengl2_example/imgui_impl_sdl.h @@ -0,0 +1,19 @@ +// ImGui SDL2 binding with OpenGL +// In this binding, ImTextureID is used to store an OpenGL 'GLuint' texture identifier. Read the FAQ about ImTextureID in imgui.cpp. + +// You can copy and use unmodified imgui_impl_* files in your project. See main.cpp for an example of using this. +// If you use this binding you'll need to call 4 functions: ImGui_ImplXXXX_Init(), ImGui_ImplXXXX_NewFrame(), ImGui::Render() and ImGui_ImplXXXX_Shutdown(). +// If you are new to ImGui, see examples/README.txt and documentation at the top of imgui.cpp. +// https://github.com/ocornut/imgui + +struct SDL_Window; +typedef union SDL_Event SDL_Event; + +IMGUI_API bool ImGui_ImplSdl_Init(SDL_Window* window); +IMGUI_API void ImGui_ImplSdl_Shutdown(); +IMGUI_API void ImGui_ImplSdl_NewFrame(SDL_Window* window); +IMGUI_API bool ImGui_ImplSdl_ProcessEvent(SDL_Event* event); + +// Use if you want to reset your rendering device without losing ImGui state. +IMGUI_API void ImGui_ImplSdl_InvalidateDeviceObjects(); +IMGUI_API bool ImGui_ImplSdl_CreateDeviceObjects(); diff --git a/examples/sdl_opengl2_example/main.cpp b/examples/sdl_opengl2_example/main.cpp new file mode 100644 index 0000000..f42e7fa --- /dev/null +++ b/examples/sdl_opengl2_example/main.cpp @@ -0,0 +1,103 @@ +// ImGui - standalone example application for SDL2 + OpenGL +// If you are new to ImGui, see examples/README.txt and documentation at the top of imgui.cpp. + +#include +#include "imgui_impl_sdl.h" +#include +#include +#include + +int main(int, char**) +{ + // Setup SDL + if (SDL_Init(SDL_INIT_VIDEO|SDL_INIT_TIMER) != 0) + { + printf("Error: %s\n", SDL_GetError()); + return -1; + } + + // Setup window + SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1); + SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 24); + SDL_GL_SetAttribute(SDL_GL_STENCIL_SIZE, 8); + SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 2); + SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 2); + SDL_DisplayMode current; + SDL_GetCurrentDisplayMode(0, ¤t); + SDL_Window *window = SDL_CreateWindow("ImGui SDL2+OpenGL example", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, 1280, 720, SDL_WINDOW_OPENGL|SDL_WINDOW_RESIZABLE); + SDL_GLContext glcontext = SDL_GL_CreateContext(window); + + // Setup ImGui binding + ImGui_ImplSdl_Init(window); + + // Load Fonts + // (there is a default font, this is only if you want to change it. see extra_fonts/README.txt for more details) + //ImGuiIO& io = ImGui::GetIO(); + //io.Fonts->AddFontDefault(); + //io.Fonts->AddFontFromFileTTF("../../extra_fonts/Cousine-Regular.ttf", 15.0f); + //io.Fonts->AddFontFromFileTTF("../../extra_fonts/DroidSans.ttf", 16.0f); + //io.Fonts->AddFontFromFileTTF("../../extra_fonts/ProggyClean.ttf", 13.0f); + //io.Fonts->AddFontFromFileTTF("../../extra_fonts/ProggyTiny.ttf", 10.0f); + //io.Fonts->AddFontFromFileTTF("c:\\Windows\\Fonts\\ArialUni.ttf", 18.0f, NULL, io.Fonts->GetGlyphRangesJapanese()); + + bool show_test_window = true; + bool show_another_window = false; + ImVec4 clear_color = ImColor(114, 144, 154); + + // Main loop + bool done = false; + while (!done) + { + SDL_Event event; + while (SDL_PollEvent(&event)) + { + ImGui_ImplSdl_ProcessEvent(&event); + if (event.type == SDL_QUIT) + done = true; + } + ImGui_ImplSdl_NewFrame(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" + { + static float f = 0.0f; + ImGui::Text("Hello, world!"); + ImGui::SliderFloat("float", &f, 0.0f, 1.0f); + ImGui::ColorEdit3("clear color", (float*)&clear_color); + if (ImGui::Button("Test Window")) show_test_window ^= 1; + if (ImGui::Button("Another Window")) show_another_window ^= 1; + ImGui::Text("Application average %.3f ms/frame (%.1f FPS)", 1000.0f / ImGui::GetIO().Framerate, ImGui::GetIO().Framerate); + } + + // 2. Show another simple window, this time using an explicit Begin/End pair + if (show_another_window) + { + ImGui::SetNextWindowSize(ImVec2(200,100), ImGuiSetCond_FirstUseEver); + ImGui::Begin("Another Window", &show_another_window); + 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::SetNextWindowPos(ImVec2(650, 20), ImGuiSetCond_FirstUseEver); + ImGui::ShowTestWindow(&show_test_window); + } + + // Rendering + glViewport(0, 0, (int)ImGui::GetIO().DisplaySize.x, (int)ImGui::GetIO().DisplaySize.y); + glClearColor(clear_color.x, clear_color.y, clear_color.z, clear_color.w); + glClear(GL_COLOR_BUFFER_BIT); + ImGui::Render(); + SDL_GL_SwapWindow(window); + } + + // Cleanup + ImGui_ImplSdl_Shutdown(); + SDL_GL_DeleteContext(glcontext); + SDL_DestroyWindow(window); + SDL_Quit(); + + return 0; +} diff --git a/examples/sdl_opengl_example/README.md b/examples/sdl_opengl_example/README.md deleted file mode 100644 index aada45d..0000000 --- a/examples/sdl_opengl_example/README.md +++ /dev/null @@ -1,22 +0,0 @@ - -# How to Build - -- On Windows with Visual Studio's CLI - -``` -set SDL2DIR=path_to_your_sdl2_folder -cl /Zi /MD /I %SDL2DIR%\include> /I ..\.. main.cpp imgui_impl_sdl.cpp ..\..\imgui*.cpp /link /LIBPATH:%SDL2DIR%\lib SDL2.lib SDL2main.lib -``` - -- On Linux and similar Unixes - -``` -c++ `sdl2-config --cflags` -I ../.. main.cpp imgui_impl_sdl.cpp ../../imgui*.cpp `sdl2-config --libs` -lGL -o sdl2example -``` - -- On Mac OS X - -``` -brew install sdl2 -c++ `sdl2-config --cflags` -I ../.. main.cpp imgui_impl_sdl.cpp ../../imgui*.cpp `sdl2-config --libs` -framework OpenGl -o sdl2example -``` diff --git a/examples/sdl_opengl_example/imgui_impl_sdl.cpp b/examples/sdl_opengl_example/imgui_impl_sdl.cpp deleted file mode 100644 index 63ed9f4..0000000 --- a/examples/sdl_opengl_example/imgui_impl_sdl.cpp +++ /dev/null @@ -1,277 +0,0 @@ -// ImGui SDL2 binding with OpenGL -// In this binding, ImTextureID is used to store an OpenGL 'GLuint' texture identifier. Read the FAQ about ImTextureID in imgui.cpp. - -// You can copy and use unmodified imgui_impl_* files in your project. See main.cpp for an example of using this. -// If you use this binding you'll need to call 4 functions: ImGui_ImplXXXX_Init(), ImGui_ImplXXXX_NewFrame(), ImGui::Render() and ImGui_ImplXXXX_Shutdown(). -// If you are new to ImGui, see examples/README.txt and documentation at the top of imgui.cpp. -// https://github.com/ocornut/imgui - -#include -#include -#include -#include -#include "imgui_impl_sdl.h" - -// Data -static double g_Time = 0.0f; -static bool g_MousePressed[3] = { false, false, false }; -static float g_MouseWheel = 0.0f; -static GLuint g_FontTexture = 0; - -// 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) -void ImGui_ImplSdl_RenderDrawLists(ImDrawData* draw_data) -{ - // Avoid rendering when minimized, scale coordinates for retina displays (screen coordinates != framebuffer coordinates) - ImGuiIO& io = ImGui::GetIO(); - int fb_width = (int)(io.DisplaySize.x * io.DisplayFramebufferScale.x); - int fb_height = (int)(io.DisplaySize.y * io.DisplayFramebufferScale.y); - if (fb_width == 0 || fb_height == 0) - return; - draw_data->ScaleClipRects(io.DisplayFramebufferScale); - - // We are using the OpenGL fixed pipeline to make the example code simpler to read! - // Setup render state: alpha-blending enabled, no face culling, no depth testing, scissor enabled, vertex/texcoord/color pointers. - GLint last_texture; glGetIntegerv(GL_TEXTURE_BINDING_2D, &last_texture); - GLint last_viewport[4]; glGetIntegerv(GL_VIEWPORT, last_viewport); - glPushAttrib(GL_ENABLE_BIT | GL_COLOR_BUFFER_BIT | GL_TRANSFORM_BIT); - glEnable(GL_BLEND); - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - glDisable(GL_CULL_FACE); - glDisable(GL_DEPTH_TEST); - glEnable(GL_SCISSOR_TEST); - glEnableClientState(GL_VERTEX_ARRAY); - glEnableClientState(GL_TEXTURE_COORD_ARRAY); - glEnableClientState(GL_COLOR_ARRAY); - glEnable(GL_TEXTURE_2D); - //glUseProgram(0); // You may want this if using this code in an OpenGL 3+ context - - // Setup viewport, orthographic projection matrix - glViewport(0, 0, (GLsizei)fb_width, (GLsizei)fb_height); - glMatrixMode(GL_PROJECTION); - glPushMatrix(); - glLoadIdentity(); - glOrtho(0.0f, io.DisplaySize.x, io.DisplaySize.y, 0.0f, -1.0f, +1.0f); - glMatrixMode(GL_MODELVIEW); - glPushMatrix(); - glLoadIdentity(); - - // Render command lists - #define OFFSETOF(TYPE, ELEMENT) ((size_t)&(((TYPE *)0)->ELEMENT)) - for (int n = 0; n < draw_data->CmdListsCount; n++) - { - const ImDrawList* cmd_list = draw_data->CmdLists[n]; - const unsigned char* vtx_buffer = (const unsigned char*)&cmd_list->VtxBuffer.front(); - const ImDrawIdx* idx_buffer = &cmd_list->IdxBuffer.front(); - glVertexPointer(2, GL_FLOAT, sizeof(ImDrawVert), (void*)(vtx_buffer + OFFSETOF(ImDrawVert, pos))); - glTexCoordPointer(2, GL_FLOAT, sizeof(ImDrawVert), (void*)(vtx_buffer + OFFSETOF(ImDrawVert, uv))); - glColorPointer(4, GL_UNSIGNED_BYTE, sizeof(ImDrawVert), (void*)(vtx_buffer + OFFSETOF(ImDrawVert, col))); - - for (int cmd_i = 0; cmd_i < cmd_list->CmdBuffer.size(); cmd_i++) - { - const ImDrawCmd* pcmd = &cmd_list->CmdBuffer[cmd_i]; - if (pcmd->UserCallback) - { - pcmd->UserCallback(cmd_list, pcmd); - } - else - { - glBindTexture(GL_TEXTURE_2D, (GLuint)(intptr_t)pcmd->TextureId); - glScissor((int)pcmd->ClipRect.x, (int)(fb_height - pcmd->ClipRect.w), (int)(pcmd->ClipRect.z - pcmd->ClipRect.x), (int)(pcmd->ClipRect.w - pcmd->ClipRect.y)); - glDrawElements(GL_TRIANGLES, (GLsizei)pcmd->ElemCount, sizeof(ImDrawIdx) == 2 ? GL_UNSIGNED_SHORT : GL_UNSIGNED_INT, idx_buffer); - } - idx_buffer += pcmd->ElemCount; - } - } - #undef OFFSETOF - - // Restore modified state - glDisableClientState(GL_COLOR_ARRAY); - glDisableClientState(GL_TEXTURE_COORD_ARRAY); - glDisableClientState(GL_VERTEX_ARRAY); - glBindTexture(GL_TEXTURE_2D, (GLuint)last_texture); - glMatrixMode(GL_MODELVIEW); - glPopMatrix(); - glMatrixMode(GL_PROJECTION); - glPopMatrix(); - glPopAttrib(); - glViewport(last_viewport[0], last_viewport[1], (GLsizei)last_viewport[2], (GLsizei)last_viewport[3]); -} - -static const char* ImGui_ImplSdl_GetClipboardText() -{ - return SDL_GetClipboardText(); -} - -static void ImGui_ImplSdl_SetClipboardText(const char* text) -{ - SDL_SetClipboardText(text); -} - -bool ImGui_ImplSdl_ProcessEvent(SDL_Event* event) -{ - ImGuiIO& io = ImGui::GetIO(); - switch (event->type) - { - case SDL_MOUSEWHEEL: - { - if (event->wheel.y > 0) - g_MouseWheel = 1; - if (event->wheel.y < 0) - g_MouseWheel = -1; - return true; - } - case SDL_MOUSEBUTTONDOWN: - { - if (event->button.button == SDL_BUTTON_LEFT) g_MousePressed[0] = true; - if (event->button.button == SDL_BUTTON_RIGHT) g_MousePressed[1] = true; - if (event->button.button == SDL_BUTTON_MIDDLE) g_MousePressed[2] = true; - return true; - } - case SDL_TEXTINPUT: - { - io.AddInputCharactersUTF8(event->text.text); - return true; - } - case SDL_KEYDOWN: - case SDL_KEYUP: - { - int key = event->key.keysym.sym & ~SDLK_SCANCODE_MASK; - io.KeysDown[key] = (event->type == SDL_KEYDOWN); - io.KeyShift = ((SDL_GetModState() & KMOD_SHIFT) != 0); - io.KeyCtrl = ((SDL_GetModState() & KMOD_CTRL) != 0); - io.KeyAlt = ((SDL_GetModState() & KMOD_ALT) != 0); - io.KeySuper = ((SDL_GetModState() & KMOD_GUI) != 0); - return true; - } - } - return false; -} - -bool ImGui_ImplSdl_CreateDeviceObjects() -{ - // Build texture atlas - ImGuiIO& io = ImGui::GetIO(); - unsigned char* pixels; - int width, height; - io.Fonts->GetTexDataAsAlpha8(&pixels, &width, &height); - - // Upload texture to graphics system - GLint last_texture; - glGetIntegerv(GL_TEXTURE_BINDING_2D, &last_texture); - glGenTextures(1, &g_FontTexture); - glBindTexture(GL_TEXTURE_2D, g_FontTexture); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - glPixelStorei(GL_UNPACK_ROW_LENGTH, 0); - glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, width, height, 0, GL_ALPHA, GL_UNSIGNED_BYTE, pixels); - - // Store our identifier - io.Fonts->TexID = (void *)(intptr_t)g_FontTexture; - - // Restore state - glBindTexture(GL_TEXTURE_2D, last_texture); - - return true; -} - -void ImGui_ImplSdl_InvalidateDeviceObjects() -{ - if (g_FontTexture) - { - glDeleteTextures(1, &g_FontTexture); - ImGui::GetIO().Fonts->TexID = 0; - g_FontTexture = 0; - } -} - -bool ImGui_ImplSdl_Init(SDL_Window* window) -{ - ImGuiIO& io = ImGui::GetIO(); - io.KeyMap[ImGuiKey_Tab] = SDLK_TAB; // Keyboard mapping. ImGui will use those indices to peek into the io.KeyDown[] array. - io.KeyMap[ImGuiKey_LeftArrow] = SDL_SCANCODE_LEFT; - io.KeyMap[ImGuiKey_RightArrow] = SDL_SCANCODE_RIGHT; - io.KeyMap[ImGuiKey_UpArrow] = SDL_SCANCODE_UP; - io.KeyMap[ImGuiKey_DownArrow] = SDL_SCANCODE_DOWN; - io.KeyMap[ImGuiKey_PageUp] = SDL_SCANCODE_PAGEUP; - io.KeyMap[ImGuiKey_PageDown] = SDL_SCANCODE_PAGEDOWN; - io.KeyMap[ImGuiKey_Home] = SDL_SCANCODE_HOME; - io.KeyMap[ImGuiKey_End] = SDL_SCANCODE_END; - io.KeyMap[ImGuiKey_Delete] = SDLK_DELETE; - io.KeyMap[ImGuiKey_Backspace] = SDLK_BACKSPACE; - io.KeyMap[ImGuiKey_Enter] = SDLK_RETURN; - io.KeyMap[ImGuiKey_Escape] = SDLK_ESCAPE; - io.KeyMap[ImGuiKey_A] = SDLK_a; - io.KeyMap[ImGuiKey_C] = SDLK_c; - io.KeyMap[ImGuiKey_V] = SDLK_v; - io.KeyMap[ImGuiKey_X] = SDLK_x; - io.KeyMap[ImGuiKey_Y] = SDLK_y; - io.KeyMap[ImGuiKey_Z] = SDLK_z; - - io.RenderDrawListsFn = ImGui_ImplSdl_RenderDrawLists; // Alternatively you can set this to NULL and call ImGui::GetDrawData() after ImGui::Render() to get the same ImDrawData pointer. - io.SetClipboardTextFn = ImGui_ImplSdl_SetClipboardText; - io.GetClipboardTextFn = ImGui_ImplSdl_GetClipboardText; - -#ifdef _WIN32 - SDL_SysWMinfo wmInfo; - SDL_VERSION(&wmInfo.version); - SDL_GetWindowWMInfo(window, &wmInfo); - io.ImeWindowHandle = wmInfo.info.win.window; -#else - (void)window; -#endif - - return true; -} - -void ImGui_ImplSdl_Shutdown() -{ - ImGui_ImplSdl_InvalidateDeviceObjects(); - ImGui::Shutdown(); -} - -void ImGui_ImplSdl_NewFrame(SDL_Window *window) -{ - if (!g_FontTexture) - ImGui_ImplSdl_CreateDeviceObjects(); - - ImGuiIO& io = ImGui::GetIO(); - - // Setup display size (every frame to accommodate for window resizing) - int w, h; - int display_w, display_h; - SDL_GetWindowSize(window, &w, &h); - SDL_GL_GetDrawableSize(window, &display_w, &display_h); - io.DisplaySize = ImVec2((float)w, (float)h); - io.DisplayFramebufferScale = ImVec2(w > 0 ? ((float)display_w / w) : 0, h > 0 ? ((float)display_h / h) : 0); - - // Setup time step - Uint32 time = SDL_GetTicks(); - double current_time = time / 1000.0; - io.DeltaTime = g_Time > 0.0 ? (float)(current_time - g_Time) : (float)(1.0f/60.0f); - g_Time = current_time; - - // Setup inputs - // (we already got mouse wheel, keyboard keys & characters from SDL_PollEvent()) - int mx, my; - Uint32 mouseMask = SDL_GetMouseState(&mx, &my); - if (SDL_GetWindowFlags(window) & SDL_WINDOW_MOUSE_FOCUS) - io.MousePos = ImVec2((float)mx, (float)my); // Mouse position, in pixels (set to -1,-1 if no mouse / on another screen, etc.) - else - io.MousePos = ImVec2(-1,-1); - - io.MouseDown[0] = g_MousePressed[0] || (mouseMask & SDL_BUTTON(SDL_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] = g_MousePressed[1] || (mouseMask & SDL_BUTTON(SDL_BUTTON_RIGHT)) != 0; - io.MouseDown[2] = g_MousePressed[2] || (mouseMask & SDL_BUTTON(SDL_BUTTON_MIDDLE)) != 0; - g_MousePressed[0] = g_MousePressed[1] = g_MousePressed[2] = false; - - io.MouseWheel = g_MouseWheel; - g_MouseWheel = 0.0f; - - // Hide OS mouse cursor if ImGui is drawing it - SDL_ShowCursor(io.MouseDrawCursor ? 0 : 1); - - // Start the frame - ImGui::NewFrame(); -} diff --git a/examples/README.txt b/examples/README.txt index df2e86d..5a1c8df 100644 --- a/examples/README.txt +++ b/examples/README.txt @@ -8,11 +8,13 @@ TL;DR; - Newcomers, read 'PROGRAMMER GUIDE' in imgui.cpp for notes on how to setup ImGui in your codebase. - - Refer to 'opengl_example' to understand how the library is setup, it is the simplest one. + - Refer to 'opengl2_example' to LEARN how the library is setup, it is the simplest one. The other examples requires more boilerplate and are harder to read. + - If you are using OpenGL in your application, probably use an opengl3_xxx backend. + Mixing old fixed pipeline OpenGL2 and programmable pipeline OpenGL3+ isn't well supported by drivers. - If you are using of the backend provided here, so you can copy the imgui_impl_xxx.cpp/h files to your project and use them unmodified. - - If you have your own engine, you probably want to start from 'opengl_example' and adapt it to + - If you have your own engine, you probably want to start from one of the OpenGL example and adapt it to your engine, but you can read the other examples as well. ImGui is highly portable and only requires a few things to run: @@ -41,15 +43,14 @@ Also note that some setup or GPU drivers may be causing extra lag (possibly by enforcing triple buffering), leaving you with no option but sadness/anger (Intel GPU drivers were reported as such). -opengl_example/ - OpenGL example, using GLFW + fixed pipeline. - This is simple and should work for all OpenGL enabled applications. - Prefer following this example to learn how ImGui works! - (You can use this code in a GL3/GL4 context but make sure you disable the programmable pipeline - by calling "glUseProgram(0)" before ImGui::Render.) +opengl2_example/ + GLFW + OpenGL example (old fixed pipeline). + This is simple to read. Prefer following this example to learn how ImGui works! + (You might be able to use this code in a GL3/GL4 context but make sure you disable the programmable + pipeline by calling "glUseProgram(0)" before ImGui::Render.) opengl3_example/ - OpenGL example, using GLFW/GL3W + programmable pipeline. + GLFW + OpenGL example (programmable pipeline, binding modern functions with GL3W). This uses more modern OpenGL calls and custom shaders. It's more messy. directx9_example/ @@ -68,8 +69,8 @@ On iOS, Using Synergy to access keyboard/mouse data from server computer. Synergy keyboard integration is rather hacky. -sdl_opengl_example/ - SDL2 + OpenGL example. +sdl_opengl2_example/ + SDL2 + OpenGL example (old fixed pipeline). sdl_opengl3_example/ SDL2 + OpenGL3 example. diff --git a/examples/imgui_examples_msvc2010.sln b/examples/imgui_examples_msvc2010.sln index b7e6a25..16f0d60 100644 --- a/examples/imgui_examples_msvc2010.sln +++ b/examples/imgui_examples_msvc2010.sln @@ -1,7 +1,7 @@  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}" +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "opengl2_example", "opengl_example\opengl2_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 diff --git a/examples/opengl2_example/Makefile b/examples/opengl2_example/Makefile new file mode 100644 index 0000000..bd79d1b --- /dev/null +++ b/examples/opengl2_example/Makefile @@ -0,0 +1,60 @@ +# +# Cross Platform Makefile +# Compatible with Ubuntu 14.04.1 and Mac OS X +# +# +# if you using Mac OS X: +# You'll need glfw +# http://www.glfw.org +# + +#CXX = g++ + +EXE = opengl2_example +OBJS = main.o imgui_impl_glfw.o +OBJS += ../../imgui.o ../../imgui_demo.o ../../imgui_draw.o + +UNAME_S := $(shell uname -s) + + +ifeq ($(UNAME_S), Linux) #LINUX + ECHO_MESSAGE = "Linux" + LIBS = -lGL `pkg-config --static --libs glfw3` + + CXXFLAGS = -I../../ `pkg-config --cflags glfw3` + CXXFLAGS += -Wall -Wformat + CFLAGS = $(CXXFLAGS) +endif + +ifeq ($(UNAME_S), Darwin) #APPLE + ECHO_MESSAGE = "Mac OS X" + LIBS = -framework OpenGL -framework Cocoa -framework IOKit -framework CoreVideo + LIBS += -L/usr/local/lib -lglfw3 + + CXXFLAGS = -I../../ -I/usr/local/include + CXXFLAGS += -Wall -Wformat +# CXXFLAGS += -D__APPLE__ + CFLAGS = $(CXXFLAGS) +endif + +ifeq ($(UNAME_S), MINGW64_NT-6.3) + ECHO_MESSAGE = "Windows" + LIBS = -lglfw3 -lgdi32 -lopengl32 -limm32 + + CXXFLAGS = -I../../ -I../libs/gl3w `pkg-config --cflags glfw3` + CXXFLAGS += -Wall -Wformat + CFLAGS = $(CXXFLAGS) +endif + +.cpp.o: + $(CXX) $(CXXFLAGS) -c -o $@ $< + +all: $(EXE) + @echo Build complete for $(ECHO_MESSAGE) + +$(EXE): $(OBJS) + $(CXX) -o $(EXE) $(OBJS) $(CXXFLAGS) $(LIBS) + +clean: + rm $(EXE) $(OBJS) + diff --git a/examples/opengl2_example/build_win32.bat b/examples/opengl2_example/build_win32.bat new file mode 100644 index 0000000..278381c --- /dev/null +++ b/examples/opengl2_example/build_win32.bat @@ -0,0 +1,3 @@ +@REM Build for Visual Studio compiler. Run your copy of vcvars32.bat or vcvarsall.bat to setup command-line compiler. +mkdir Debug +cl /nologo /Zi /MD /I ..\.. /I ..\libs\glfw\include *.cpp ..\..\*.cpp /FeDebug/opengl_example.exe /FoDebug/ /link /LIBPATH:..\libs\glfw\lib-vc2010-32 glfw3.lib opengl32.lib gdi32.lib shell32.lib diff --git a/examples/opengl2_example/imgui_impl_glfw.cpp b/examples/opengl2_example/imgui_impl_glfw.cpp new file mode 100644 index 0000000..2d1f5c1 --- /dev/null +++ b/examples/opengl2_example/imgui_impl_glfw.cpp @@ -0,0 +1,288 @@ +// ImGui GLFW binding with OpenGL +// In this binding, ImTextureID is used to store an OpenGL 'GLuint' texture identifier. Read the FAQ about ImTextureID in imgui.cpp. + +// If your context is GL3/GL3 then prefer using the code in opengl3_example. +// You *might* use this code with a GL3/GL4 context but make sure you disable the programmable pipeline by calling "glUseProgram(0)" before ImGui::Render(). +// We cannot do that from GL2 code because the function doesn't exist. + +// You can copy and use unmodified imgui_impl_* files in your project. See main.cpp for an example of using this. +// If you use this binding you'll need to call 4 functions: ImGui_ImplXXXX_Init(), ImGui_ImplXXXX_NewFrame(), ImGui::Render() and ImGui_ImplXXXX_Shutdown(). +// If you are new to ImGui, see examples/README.txt and documentation at the top of imgui.cpp. +// https://github.com/ocornut/imgui + +#include +#include "imgui_impl_glfw.h" + +// GLFW +#include +#ifdef _WIN32 +#undef APIENTRY +#define GLFW_EXPOSE_NATIVE_WIN32 +#define GLFW_EXPOSE_NATIVE_WGL +#include +#endif + +// Data +static GLFWwindow* g_Window = NULL; +static double g_Time = 0.0f; +static bool g_MousePressed[3] = { false, false, false }; +static float g_MouseWheel = 0.0f; +static GLuint g_FontTexture = 0; + +// 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) +void ImGui_ImplGlfw_RenderDrawLists(ImDrawData* draw_data) +{ + // Avoid rendering when minimized, scale coordinates for retina displays (screen coordinates != framebuffer coordinates) + ImGuiIO& io = ImGui::GetIO(); + int fb_width = (int)(io.DisplaySize.x * io.DisplayFramebufferScale.x); + int fb_height = (int)(io.DisplaySize.y * io.DisplayFramebufferScale.y); + if (fb_width == 0 || fb_height == 0) + return; + draw_data->ScaleClipRects(io.DisplayFramebufferScale); + + // We are using the OpenGL fixed pipeline to make the example code simpler to read! + // Setup render state: alpha-blending enabled, no face culling, no depth testing, scissor enabled, vertex/texcoord/color pointers. + GLint last_texture; glGetIntegerv(GL_TEXTURE_BINDING_2D, &last_texture); + GLint last_viewport[4]; glGetIntegerv(GL_VIEWPORT, last_viewport); + glPushAttrib(GL_ENABLE_BIT | GL_COLOR_BUFFER_BIT | GL_TRANSFORM_BIT); + glEnable(GL_BLEND); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + glDisable(GL_CULL_FACE); + glDisable(GL_DEPTH_TEST); + glEnable(GL_SCISSOR_TEST); + glEnableClientState(GL_VERTEX_ARRAY); + glEnableClientState(GL_TEXTURE_COORD_ARRAY); + glEnableClientState(GL_COLOR_ARRAY); + glEnable(GL_TEXTURE_2D); + //glUseProgram(0); // You may want this if using this code in an OpenGL 3+ context + + // Setup viewport, orthographic projection matrix + glViewport(0, 0, (GLsizei)fb_width, (GLsizei)fb_height); + glMatrixMode(GL_PROJECTION); + glPushMatrix(); + glLoadIdentity(); + glOrtho(0.0f, io.DisplaySize.x, io.DisplaySize.y, 0.0f, -1.0f, +1.0f); + glMatrixMode(GL_MODELVIEW); + glPushMatrix(); + glLoadIdentity(); + + // Render command lists + #define OFFSETOF(TYPE, ELEMENT) ((size_t)&(((TYPE *)0)->ELEMENT)) + for (int n = 0; n < draw_data->CmdListsCount; n++) + { + const ImDrawList* cmd_list = draw_data->CmdLists[n]; + const unsigned char* vtx_buffer = (const unsigned char*)&cmd_list->VtxBuffer.front(); + const ImDrawIdx* idx_buffer = &cmd_list->IdxBuffer.front(); + glVertexPointer(2, GL_FLOAT, sizeof(ImDrawVert), (void*)(vtx_buffer + OFFSETOF(ImDrawVert, pos))); + glTexCoordPointer(2, GL_FLOAT, sizeof(ImDrawVert), (void*)(vtx_buffer + OFFSETOF(ImDrawVert, uv))); + glColorPointer(4, GL_UNSIGNED_BYTE, sizeof(ImDrawVert), (void*)(vtx_buffer + OFFSETOF(ImDrawVert, col))); + + for (int cmd_i = 0; cmd_i < cmd_list->CmdBuffer.size(); cmd_i++) + { + const ImDrawCmd* pcmd = &cmd_list->CmdBuffer[cmd_i]; + if (pcmd->UserCallback) + { + pcmd->UserCallback(cmd_list, pcmd); + } + else + { + glBindTexture(GL_TEXTURE_2D, (GLuint)(intptr_t)pcmd->TextureId); + glScissor((int)pcmd->ClipRect.x, (int)(fb_height - pcmd->ClipRect.w), (int)(pcmd->ClipRect.z - pcmd->ClipRect.x), (int)(pcmd->ClipRect.w - pcmd->ClipRect.y)); + glDrawElements(GL_TRIANGLES, (GLsizei)pcmd->ElemCount, sizeof(ImDrawIdx) == 2 ? GL_UNSIGNED_SHORT : GL_UNSIGNED_INT, idx_buffer); + } + idx_buffer += pcmd->ElemCount; + } + } + #undef OFFSETOF + + // Restore modified state + glDisableClientState(GL_COLOR_ARRAY); + glDisableClientState(GL_TEXTURE_COORD_ARRAY); + glDisableClientState(GL_VERTEX_ARRAY); + glBindTexture(GL_TEXTURE_2D, (GLuint)last_texture); + glMatrixMode(GL_MODELVIEW); + glPopMatrix(); + glMatrixMode(GL_PROJECTION); + glPopMatrix(); + glPopAttrib(); + glViewport(last_viewport[0], last_viewport[1], (GLsizei)last_viewport[2], (GLsizei)last_viewport[3]); +} + +static const char* ImGui_ImplGlfw_GetClipboardText() +{ + return glfwGetClipboardString(g_Window); +} + +static void ImGui_ImplGlfw_SetClipboardText(const char* text) +{ + glfwSetClipboardString(g_Window, text); +} + +void ImGui_ImplGlfw_MouseButtonCallback(GLFWwindow*, int button, int action, int /*mods*/) +{ + if (action == GLFW_PRESS && button >= 0 && button < 3) + g_MousePressed[button] = true; +} + +void ImGui_ImplGlfw_ScrollCallback(GLFWwindow*, double /*xoffset*/, double yoffset) +{ + g_MouseWheel += (float)yoffset; // Use fractional mouse wheel, 1.0 unit 5 lines. +} + +void ImGui_ImplGlFw_KeyCallback(GLFWwindow*, int key, int, int action, int mods) +{ + ImGuiIO& io = ImGui::GetIO(); + if (action == GLFW_PRESS) + io.KeysDown[key] = true; + if (action == GLFW_RELEASE) + io.KeysDown[key] = false; + + (void)mods; // Modifiers are not reliable across systems + io.KeyCtrl = io.KeysDown[GLFW_KEY_LEFT_CONTROL] || io.KeysDown[GLFW_KEY_RIGHT_CONTROL]; + io.KeyShift = io.KeysDown[GLFW_KEY_LEFT_SHIFT] || io.KeysDown[GLFW_KEY_RIGHT_SHIFT]; + io.KeyAlt = io.KeysDown[GLFW_KEY_LEFT_ALT] || io.KeysDown[GLFW_KEY_RIGHT_ALT]; + io.KeySuper = io.KeysDown[GLFW_KEY_LEFT_SUPER] || io.KeysDown[GLFW_KEY_RIGHT_SUPER]; +} + +void ImGui_ImplGlfw_CharCallback(GLFWwindow*, unsigned int c) +{ + ImGuiIO& io = ImGui::GetIO(); + if (c > 0 && c < 0x10000) + io.AddInputCharacter((unsigned short)c); +} + +bool ImGui_ImplGlfw_CreateDeviceObjects() +{ + // Build texture atlas + ImGuiIO& io = ImGui::GetIO(); + unsigned char* pixels; + int width, height; + io.Fonts->GetTexDataAsAlpha8(&pixels, &width, &height); + + // Upload texture to graphics system + GLint last_texture; + glGetIntegerv(GL_TEXTURE_BINDING_2D, &last_texture); + glGenTextures(1, &g_FontTexture); + glBindTexture(GL_TEXTURE_2D, g_FontTexture); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, width, height, 0, GL_ALPHA, GL_UNSIGNED_BYTE, pixels); + + // Store our identifier + io.Fonts->TexID = (void *)(intptr_t)g_FontTexture; + + // Restore state + glBindTexture(GL_TEXTURE_2D, last_texture); + + return true; +} + +void ImGui_ImplGlfw_InvalidateDeviceObjects() +{ + if (g_FontTexture) + { + glDeleteTextures(1, &g_FontTexture); + ImGui::GetIO().Fonts->TexID = 0; + g_FontTexture = 0; + } +} + +bool ImGui_ImplGlfw_Init(GLFWwindow* window, bool install_callbacks) +{ + g_Window = window; + + ImGuiIO& io = ImGui::GetIO(); + 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; + io.KeyMap[ImGuiKey_DownArrow] = GLFW_KEY_DOWN; + io.KeyMap[ImGuiKey_PageUp] = GLFW_KEY_PAGE_UP; + io.KeyMap[ImGuiKey_PageDown] = GLFW_KEY_PAGE_DOWN; + io.KeyMap[ImGuiKey_Home] = GLFW_KEY_HOME; + io.KeyMap[ImGuiKey_End] = GLFW_KEY_END; + io.KeyMap[ImGuiKey_Delete] = GLFW_KEY_DELETE; + io.KeyMap[ImGuiKey_Backspace] = GLFW_KEY_BACKSPACE; + io.KeyMap[ImGuiKey_Enter] = GLFW_KEY_ENTER; + io.KeyMap[ImGuiKey_Escape] = GLFW_KEY_ESCAPE; + io.KeyMap[ImGuiKey_A] = GLFW_KEY_A; + io.KeyMap[ImGuiKey_C] = GLFW_KEY_C; + io.KeyMap[ImGuiKey_V] = GLFW_KEY_V; + io.KeyMap[ImGuiKey_X] = GLFW_KEY_X; + io.KeyMap[ImGuiKey_Y] = GLFW_KEY_Y; + io.KeyMap[ImGuiKey_Z] = GLFW_KEY_Z; + + io.RenderDrawListsFn = ImGui_ImplGlfw_RenderDrawLists; // Alternatively you can set this to NULL and call ImGui::GetDrawData() after ImGui::Render() to get the same ImDrawData pointer. + io.SetClipboardTextFn = ImGui_ImplGlfw_SetClipboardText; + io.GetClipboardTextFn = ImGui_ImplGlfw_GetClipboardText; +#ifdef _WIN32 + io.ImeWindowHandle = glfwGetWin32Window(g_Window); +#endif + + if (install_callbacks) + { + glfwSetMouseButtonCallback(window, ImGui_ImplGlfw_MouseButtonCallback); + glfwSetScrollCallback(window, ImGui_ImplGlfw_ScrollCallback); + glfwSetKeyCallback(window, ImGui_ImplGlFw_KeyCallback); + glfwSetCharCallback(window, ImGui_ImplGlfw_CharCallback); + } + + return true; +} + +void ImGui_ImplGlfw_Shutdown() +{ + ImGui_ImplGlfw_InvalidateDeviceObjects(); + ImGui::Shutdown(); +} + +void ImGui_ImplGlfw_NewFrame() +{ + if (!g_FontTexture) + ImGui_ImplGlfw_CreateDeviceObjects(); + + ImGuiIO& io = ImGui::GetIO(); + + // Setup display size (every frame to accommodate for window resizing) + int w, h; + int display_w, display_h; + glfwGetWindowSize(g_Window, &w, &h); + glfwGetFramebufferSize(g_Window, &display_w, &display_h); + io.DisplaySize = ImVec2((float)w, (float)h); + io.DisplayFramebufferScale = ImVec2(w > 0 ? ((float)display_w / w) : 0, h > 0 ? ((float)display_h / h) : 0); + + // Setup time step + double current_time = glfwGetTime(); + io.DeltaTime = g_Time > 0.0 ? (float)(current_time - g_Time) : (float)(1.0f/60.0f); + g_Time = current_time; + + // Setup inputs + // (we already got mouse wheel, keyboard keys & characters from glfw callbacks polled in glfwPollEvents()) + if (glfwGetWindowAttrib(g_Window, GLFW_FOCUSED)) + { + double mouse_x, mouse_y; + glfwGetCursorPos(g_Window, &mouse_x, &mouse_y); + io.MousePos = ImVec2((float)mouse_x, (float)mouse_y); // Mouse position in screen coordinates (set to -1,-1 if no mouse / on another screen, etc.) + } + else + { + io.MousePos = ImVec2(-1,-1); + } + + for (int i = 0; i < 3; i++) + { + io.MouseDown[i] = g_MousePressed[i] || glfwGetMouseButton(g_Window, i) != 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. + g_MousePressed[i] = false; + } + + io.MouseWheel = g_MouseWheel; + g_MouseWheel = 0.0f; + + // Hide OS mouse cursor if ImGui is drawing it + glfwSetInputMode(g_Window, GLFW_CURSOR, io.MouseDrawCursor ? GLFW_CURSOR_HIDDEN : GLFW_CURSOR_NORMAL); + + // Start the frame + ImGui::NewFrame(); +} diff --git a/examples/opengl2_example/imgui_impl_glfw.h b/examples/opengl2_example/imgui_impl_glfw.h new file mode 100644 index 0000000..07dd96f --- /dev/null +++ b/examples/opengl2_example/imgui_impl_glfw.h @@ -0,0 +1,29 @@ +// ImGui GLFW binding with OpenGL +// In this binding, ImTextureID is used to store an OpenGL 'GLuint' texture identifier. Read the FAQ about ImTextureID in imgui.cpp. + +// If your context is GL3/GL3 then prefer using the code in opengl3_example. +// You *might* use this code with a GL3/GL4 context but make sure you disable the programmable pipeline by calling "glUseProgram(0)" before ImGui::Render(). +// We cannot do that from GL2 code because the function doesn't exist. + +// You can copy and use unmodified imgui_impl_* files in your project. See main.cpp for an example of using this. +// If you use this binding you'll need to call 4 functions: ImGui_ImplXXXX_Init(), ImGui_ImplXXXX_NewFrame(), ImGui::Render() and ImGui_ImplXXXX_Shutdown(). +// If you are new to ImGui, see examples/README.txt and documentation at the top of imgui.cpp. +// https://github.com/ocornut/imgui + +struct GLFWwindow; + +IMGUI_API bool ImGui_ImplGlfw_Init(GLFWwindow* window, bool install_callbacks); +IMGUI_API void ImGui_ImplGlfw_Shutdown(); +IMGUI_API void ImGui_ImplGlfw_NewFrame(); + +// Use if you want to reset your rendering device without losing ImGui state. +IMGUI_API void ImGui_ImplGlfw_InvalidateDeviceObjects(); +IMGUI_API bool ImGui_ImplGlfw_CreateDeviceObjects(); + +// GLFW callbacks (installed by default if you enable 'install_callbacks' during initialization) +// Provided here if you want to chain callbacks. +// You can also handle inputs yourself and use those as a reference. +IMGUI_API void ImGui_ImplGlfw_MouseButtonCallback(GLFWwindow* window, int button, int action, int mods); +IMGUI_API void ImGui_ImplGlfw_ScrollCallback(GLFWwindow* window, double xoffset, double yoffset); +IMGUI_API void ImGui_ImplGlFw_KeyCallback(GLFWwindow* window, int key, int scancode, int action, int mods); +IMGUI_API void ImGui_ImplGlfw_CharCallback(GLFWwindow* window, unsigned int c); diff --git a/examples/opengl2_example/main.cpp b/examples/opengl2_example/main.cpp new file mode 100644 index 0000000..a844db5 --- /dev/null +++ b/examples/opengl2_example/main.cpp @@ -0,0 +1,89 @@ +// ImGui - standalone example application for Glfw + OpenGL 2, using fixed pipeline +// If you are new to ImGui, see examples/README.txt and documentation at the top of imgui.cpp. + +#include +#include "imgui_impl_glfw.h" +#include +#include + +static void error_callback(int error, const char* description) +{ + fprintf(stderr, "Error %d: %s\n", error, description); +} + +int main(int, char**) +{ + // Setup window + glfwSetErrorCallback(error_callback); + if (!glfwInit()) + return 1; + GLFWwindow* window = glfwCreateWindow(1280, 720, "ImGui OpenGL2 example", NULL, NULL); + glfwMakeContextCurrent(window); + + // Setup ImGui binding + ImGui_ImplGlfw_Init(window, true); + + // Load Fonts + // (there is a default font, this is only if you want to change it. see extra_fonts/README.txt for more details) + //ImGuiIO& io = ImGui::GetIO(); + //io.Fonts->AddFontDefault(); + //io.Fonts->AddFontFromFileTTF("../../extra_fonts/Cousine-Regular.ttf", 15.0f); + //io.Fonts->AddFontFromFileTTF("../../extra_fonts/DroidSans.ttf", 16.0f); + //io.Fonts->AddFontFromFileTTF("../../extra_fonts/ProggyClean.ttf", 13.0f); + //io.Fonts->AddFontFromFileTTF("../../extra_fonts/ProggyTiny.ttf", 10.0f); + //io.Fonts->AddFontFromFileTTF("c:\\Windows\\Fonts\\ArialUni.ttf", 18.0f, NULL, io.Fonts->GetGlyphRangesJapanese()); + + bool show_test_window = true; + bool show_another_window = false; + ImVec4 clear_color = ImColor(114, 144, 154); + + // Main loop + while (!glfwWindowShouldClose(window)) + { + glfwPollEvents(); + ImGui_ImplGlfw_NewFrame(); + + // 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 = 0.0f; + ImGui::Text("Hello, world!"); + ImGui::SliderFloat("float", &f, 0.0f, 1.0f); + ImGui::ColorEdit3("clear color", (float*)&clear_color); + if (ImGui::Button("Test Window")) show_test_window ^= 1; + if (ImGui::Button("Another Window")) show_another_window ^= 1; + ImGui::Text("Application average %.3f ms/frame (%.1f FPS)", 1000.0f / ImGui::GetIO().Framerate, ImGui::GetIO().Framerate); + } + + // 2. Show another simple window, this time using an explicit Begin/End pair + if (show_another_window) + { + ImGui::SetNextWindowSize(ImVec2(200,100), ImGuiSetCond_FirstUseEver); + ImGui::Begin("Another Window", &show_another_window); + 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::SetNextWindowPos(ImVec2(650, 20), ImGuiSetCond_FirstUseEver); + ImGui::ShowTestWindow(&show_test_window); + } + + // Rendering + int display_w, display_h; + glfwGetFramebufferSize(window, &display_w, &display_h); + glViewport(0, 0, display_w, display_h); + glClearColor(clear_color.x, clear_color.y, clear_color.z, clear_color.w); + glClear(GL_COLOR_BUFFER_BIT); + ImGui::Render(); + glfwSwapBuffers(window); + } + + // Cleanup + ImGui_ImplGlfw_Shutdown(); + glfwTerminate(); + + return 0; +} diff --git a/examples/opengl2_example/opengl_example.vcxproj b/examples/opengl2_example/opengl_example.vcxproj new file mode 100644 index 0000000..4b354b6 --- /dev/null +++ b/examples/opengl2_example/opengl_example.vcxproj @@ -0,0 +1,169 @@ + + + + + Debug + Win32 + + + Debug + x64 + + + Release + Win32 + + + Release + x64 + + + + {9CDA7840-B7A5-496D-A527-E95571496D18} + opengl_example + + + + Application + true + MultiByte + + + Application + true + MultiByte + + + Application + false + true + MultiByte + + + Application + false + true + MultiByte + + + + + + + + + + + + + + + + + + + $(ProjectDir)$(Configuration)\ + $(ProjectDir)$(Configuration)\ + $(IncludePath) + + + $(ProjectDir)$(Configuration)\ + $(ProjectDir)$(Configuration)\ + $(IncludePath) + + + $(ProjectDir)$(Configuration)\ + $(ProjectDir)$(Configuration)\ + $(IncludePath) + + + $(ProjectDir)$(Configuration)\ + $(ProjectDir)$(Configuration)\ + $(IncludePath) + + + + Level4 + Disabled + $(SolutionDir)\libs\glfw\include;..\..;%(AdditionalIncludeDirectories) + + + true + $(SolutionDir)\libs\glfw\lib-vc2010-32;%(AdditionalLibraryDirectories) + opengl32.lib;glfw3.lib;%(AdditionalDependencies) + Console + msvcrt.lib + + + + + Level4 + Disabled + $(SolutionDir)\libs\glfw\include;..\..;%(AdditionalIncludeDirectories) + + + true + $(SolutionDir)\libs\glfw\lib-vc2010-64;%(AdditionalLibraryDirectories) + opengl32.lib;glfw3.lib;%(AdditionalDependencies) + Console + msvcrt.lib + + + + + Level4 + MaxSpeed + true + true + $(SolutionDir)\libs\glfw\include;..\..;%(AdditionalIncludeDirectories) + + + true + true + true + $(SolutionDir)\libs\glfw\lib-vc2010-32;%(AdditionalLibraryDirectories) + opengl32.lib;glfw3.lib;%(AdditionalDependencies) + Console + + + + + + + Level4 + MaxSpeed + true + true + $(SolutionDir)\libs\glfw\include;..\..;%(AdditionalIncludeDirectories) + + + true + true + true + $(SolutionDir)\libs\glfw\lib-vc2010-64;%(AdditionalLibraryDirectories) + opengl32.lib;glfw3.lib;%(AdditionalDependencies) + Console + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/examples/opengl2_example/opengl_example.vcxproj.filters b/examples/opengl2_example/opengl_example.vcxproj.filters new file mode 100644 index 0000000..f2282bf --- /dev/null +++ b/examples/opengl2_example/opengl_example.vcxproj.filters @@ -0,0 +1,46 @@ + + + + + {c336cfe3-f0c4-464c-9ef0-a9e17a7ff222} + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx + + + + + sources + + + imgui + + + sources + + + imgui + + + imgui + + + + + imgui + + + imgui + + + sources + + + imgui + + + + + + \ No newline at end of file diff --git a/examples/opengl_example/Makefile b/examples/opengl_example/Makefile deleted file mode 100644 index 91d1b14..0000000 --- a/examples/opengl_example/Makefile +++ /dev/null @@ -1,60 +0,0 @@ -# -# Cross Platform Makefile -# Compatible with Ubuntu 14.04.1 and Mac OS X -# -# -# if you using Mac OS X: -# You'll need glfw -# http://www.glfw.org -# - -#CXX = g++ - -EXE = opengl_example -OBJS = main.o imgui_impl_glfw.o -OBJS += ../../imgui.o ../../imgui_demo.o ../../imgui_draw.o - -UNAME_S := $(shell uname -s) - - -ifeq ($(UNAME_S), Linux) #LINUX - ECHO_MESSAGE = "Linux" - LIBS = -lGL `pkg-config --static --libs glfw3` - - CXXFLAGS = -I../../ `pkg-config --cflags glfw3` - CXXFLAGS += -Wall -Wformat - CFLAGS = $(CXXFLAGS) -endif - -ifeq ($(UNAME_S), Darwin) #APPLE - ECHO_MESSAGE = "Mac OS X" - LIBS = -framework OpenGL -framework Cocoa -framework IOKit -framework CoreVideo - LIBS += -L/usr/local/lib -lglfw3 - - CXXFLAGS = -I../../ -I/usr/local/include - CXXFLAGS += -Wall -Wformat -# CXXFLAGS += -D__APPLE__ - CFLAGS = $(CXXFLAGS) -endif - -ifeq ($(UNAME_S), MINGW64_NT-6.3) - ECHO_MESSAGE = "Windows" - LIBS = -lglfw3 -lgdi32 -lopengl32 -limm32 - - CXXFLAGS = -I../../ -I../libs/gl3w `pkg-config --cflags glfw3` - CXXFLAGS += -Wall -Wformat - CFLAGS = $(CXXFLAGS) -endif - -.cpp.o: - $(CXX) $(CXXFLAGS) -c -o $@ $< - -all: $(EXE) - @echo Build complete for $(ECHO_MESSAGE) - -$(EXE): $(OBJS) - $(CXX) -o $(EXE) $(OBJS) $(CXXFLAGS) $(LIBS) - -clean: - rm $(EXE) $(OBJS) - diff --git a/examples/opengl_example/build_win32.bat b/examples/opengl_example/build_win32.bat deleted file mode 100644 index 278381c..0000000 --- a/examples/opengl_example/build_win32.bat +++ /dev/null @@ -1,3 +0,0 @@ -@REM Build for Visual Studio compiler. Run your copy of vcvars32.bat or vcvarsall.bat to setup command-line compiler. -mkdir Debug -cl /nologo /Zi /MD /I ..\.. /I ..\libs\glfw\include *.cpp ..\..\*.cpp /FeDebug/opengl_example.exe /FoDebug/ /link /LIBPATH:..\libs\glfw\lib-vc2010-32 glfw3.lib opengl32.lib gdi32.lib shell32.lib diff --git a/examples/opengl_example/imgui_impl_glfw.cpp b/examples/opengl_example/imgui_impl_glfw.cpp deleted file mode 100644 index 2d1f5c1..0000000 --- a/examples/opengl_example/imgui_impl_glfw.cpp +++ /dev/null @@ -1,288 +0,0 @@ -// ImGui GLFW binding with OpenGL -// In this binding, ImTextureID is used to store an OpenGL 'GLuint' texture identifier. Read the FAQ about ImTextureID in imgui.cpp. - -// If your context is GL3/GL3 then prefer using the code in opengl3_example. -// You *might* use this code with a GL3/GL4 context but make sure you disable the programmable pipeline by calling "glUseProgram(0)" before ImGui::Render(). -// We cannot do that from GL2 code because the function doesn't exist. - -// You can copy and use unmodified imgui_impl_* files in your project. See main.cpp for an example of using this. -// If you use this binding you'll need to call 4 functions: ImGui_ImplXXXX_Init(), ImGui_ImplXXXX_NewFrame(), ImGui::Render() and ImGui_ImplXXXX_Shutdown(). -// If you are new to ImGui, see examples/README.txt and documentation at the top of imgui.cpp. -// https://github.com/ocornut/imgui - -#include -#include "imgui_impl_glfw.h" - -// GLFW -#include -#ifdef _WIN32 -#undef APIENTRY -#define GLFW_EXPOSE_NATIVE_WIN32 -#define GLFW_EXPOSE_NATIVE_WGL -#include -#endif - -// Data -static GLFWwindow* g_Window = NULL; -static double g_Time = 0.0f; -static bool g_MousePressed[3] = { false, false, false }; -static float g_MouseWheel = 0.0f; -static GLuint g_FontTexture = 0; - -// 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) -void ImGui_ImplGlfw_RenderDrawLists(ImDrawData* draw_data) -{ - // Avoid rendering when minimized, scale coordinates for retina displays (screen coordinates != framebuffer coordinates) - ImGuiIO& io = ImGui::GetIO(); - int fb_width = (int)(io.DisplaySize.x * io.DisplayFramebufferScale.x); - int fb_height = (int)(io.DisplaySize.y * io.DisplayFramebufferScale.y); - if (fb_width == 0 || fb_height == 0) - return; - draw_data->ScaleClipRects(io.DisplayFramebufferScale); - - // We are using the OpenGL fixed pipeline to make the example code simpler to read! - // Setup render state: alpha-blending enabled, no face culling, no depth testing, scissor enabled, vertex/texcoord/color pointers. - GLint last_texture; glGetIntegerv(GL_TEXTURE_BINDING_2D, &last_texture); - GLint last_viewport[4]; glGetIntegerv(GL_VIEWPORT, last_viewport); - glPushAttrib(GL_ENABLE_BIT | GL_COLOR_BUFFER_BIT | GL_TRANSFORM_BIT); - glEnable(GL_BLEND); - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - glDisable(GL_CULL_FACE); - glDisable(GL_DEPTH_TEST); - glEnable(GL_SCISSOR_TEST); - glEnableClientState(GL_VERTEX_ARRAY); - glEnableClientState(GL_TEXTURE_COORD_ARRAY); - glEnableClientState(GL_COLOR_ARRAY); - glEnable(GL_TEXTURE_2D); - //glUseProgram(0); // You may want this if using this code in an OpenGL 3+ context - - // Setup viewport, orthographic projection matrix - glViewport(0, 0, (GLsizei)fb_width, (GLsizei)fb_height); - glMatrixMode(GL_PROJECTION); - glPushMatrix(); - glLoadIdentity(); - glOrtho(0.0f, io.DisplaySize.x, io.DisplaySize.y, 0.0f, -1.0f, +1.0f); - glMatrixMode(GL_MODELVIEW); - glPushMatrix(); - glLoadIdentity(); - - // Render command lists - #define OFFSETOF(TYPE, ELEMENT) ((size_t)&(((TYPE *)0)->ELEMENT)) - for (int n = 0; n < draw_data->CmdListsCount; n++) - { - const ImDrawList* cmd_list = draw_data->CmdLists[n]; - const unsigned char* vtx_buffer = (const unsigned char*)&cmd_list->VtxBuffer.front(); - const ImDrawIdx* idx_buffer = &cmd_list->IdxBuffer.front(); - glVertexPointer(2, GL_FLOAT, sizeof(ImDrawVert), (void*)(vtx_buffer + OFFSETOF(ImDrawVert, pos))); - glTexCoordPointer(2, GL_FLOAT, sizeof(ImDrawVert), (void*)(vtx_buffer + OFFSETOF(ImDrawVert, uv))); - glColorPointer(4, GL_UNSIGNED_BYTE, sizeof(ImDrawVert), (void*)(vtx_buffer + OFFSETOF(ImDrawVert, col))); - - for (int cmd_i = 0; cmd_i < cmd_list->CmdBuffer.size(); cmd_i++) - { - const ImDrawCmd* pcmd = &cmd_list->CmdBuffer[cmd_i]; - if (pcmd->UserCallback) - { - pcmd->UserCallback(cmd_list, pcmd); - } - else - { - glBindTexture(GL_TEXTURE_2D, (GLuint)(intptr_t)pcmd->TextureId); - glScissor((int)pcmd->ClipRect.x, (int)(fb_height - pcmd->ClipRect.w), (int)(pcmd->ClipRect.z - pcmd->ClipRect.x), (int)(pcmd->ClipRect.w - pcmd->ClipRect.y)); - glDrawElements(GL_TRIANGLES, (GLsizei)pcmd->ElemCount, sizeof(ImDrawIdx) == 2 ? GL_UNSIGNED_SHORT : GL_UNSIGNED_INT, idx_buffer); - } - idx_buffer += pcmd->ElemCount; - } - } - #undef OFFSETOF - - // Restore modified state - glDisableClientState(GL_COLOR_ARRAY); - glDisableClientState(GL_TEXTURE_COORD_ARRAY); - glDisableClientState(GL_VERTEX_ARRAY); - glBindTexture(GL_TEXTURE_2D, (GLuint)last_texture); - glMatrixMode(GL_MODELVIEW); - glPopMatrix(); - glMatrixMode(GL_PROJECTION); - glPopMatrix(); - glPopAttrib(); - glViewport(last_viewport[0], last_viewport[1], (GLsizei)last_viewport[2], (GLsizei)last_viewport[3]); -} - -static const char* ImGui_ImplGlfw_GetClipboardText() -{ - return glfwGetClipboardString(g_Window); -} - -static void ImGui_ImplGlfw_SetClipboardText(const char* text) -{ - glfwSetClipboardString(g_Window, text); -} - -void ImGui_ImplGlfw_MouseButtonCallback(GLFWwindow*, int button, int action, int /*mods*/) -{ - if (action == GLFW_PRESS && button >= 0 && button < 3) - g_MousePressed[button] = true; -} - -void ImGui_ImplGlfw_ScrollCallback(GLFWwindow*, double /*xoffset*/, double yoffset) -{ - g_MouseWheel += (float)yoffset; // Use fractional mouse wheel, 1.0 unit 5 lines. -} - -void ImGui_ImplGlFw_KeyCallback(GLFWwindow*, int key, int, int action, int mods) -{ - ImGuiIO& io = ImGui::GetIO(); - if (action == GLFW_PRESS) - io.KeysDown[key] = true; - if (action == GLFW_RELEASE) - io.KeysDown[key] = false; - - (void)mods; // Modifiers are not reliable across systems - io.KeyCtrl = io.KeysDown[GLFW_KEY_LEFT_CONTROL] || io.KeysDown[GLFW_KEY_RIGHT_CONTROL]; - io.KeyShift = io.KeysDown[GLFW_KEY_LEFT_SHIFT] || io.KeysDown[GLFW_KEY_RIGHT_SHIFT]; - io.KeyAlt = io.KeysDown[GLFW_KEY_LEFT_ALT] || io.KeysDown[GLFW_KEY_RIGHT_ALT]; - io.KeySuper = io.KeysDown[GLFW_KEY_LEFT_SUPER] || io.KeysDown[GLFW_KEY_RIGHT_SUPER]; -} - -void ImGui_ImplGlfw_CharCallback(GLFWwindow*, unsigned int c) -{ - ImGuiIO& io = ImGui::GetIO(); - if (c > 0 && c < 0x10000) - io.AddInputCharacter((unsigned short)c); -} - -bool ImGui_ImplGlfw_CreateDeviceObjects() -{ - // Build texture atlas - ImGuiIO& io = ImGui::GetIO(); - unsigned char* pixels; - int width, height; - io.Fonts->GetTexDataAsAlpha8(&pixels, &width, &height); - - // Upload texture to graphics system - GLint last_texture; - glGetIntegerv(GL_TEXTURE_BINDING_2D, &last_texture); - glGenTextures(1, &g_FontTexture); - glBindTexture(GL_TEXTURE_2D, g_FontTexture); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, width, height, 0, GL_ALPHA, GL_UNSIGNED_BYTE, pixels); - - // Store our identifier - io.Fonts->TexID = (void *)(intptr_t)g_FontTexture; - - // Restore state - glBindTexture(GL_TEXTURE_2D, last_texture); - - return true; -} - -void ImGui_ImplGlfw_InvalidateDeviceObjects() -{ - if (g_FontTexture) - { - glDeleteTextures(1, &g_FontTexture); - ImGui::GetIO().Fonts->TexID = 0; - g_FontTexture = 0; - } -} - -bool ImGui_ImplGlfw_Init(GLFWwindow* window, bool install_callbacks) -{ - g_Window = window; - - ImGuiIO& io = ImGui::GetIO(); - 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; - io.KeyMap[ImGuiKey_DownArrow] = GLFW_KEY_DOWN; - io.KeyMap[ImGuiKey_PageUp] = GLFW_KEY_PAGE_UP; - io.KeyMap[ImGuiKey_PageDown] = GLFW_KEY_PAGE_DOWN; - io.KeyMap[ImGuiKey_Home] = GLFW_KEY_HOME; - io.KeyMap[ImGuiKey_End] = GLFW_KEY_END; - io.KeyMap[ImGuiKey_Delete] = GLFW_KEY_DELETE; - io.KeyMap[ImGuiKey_Backspace] = GLFW_KEY_BACKSPACE; - io.KeyMap[ImGuiKey_Enter] = GLFW_KEY_ENTER; - io.KeyMap[ImGuiKey_Escape] = GLFW_KEY_ESCAPE; - io.KeyMap[ImGuiKey_A] = GLFW_KEY_A; - io.KeyMap[ImGuiKey_C] = GLFW_KEY_C; - io.KeyMap[ImGuiKey_V] = GLFW_KEY_V; - io.KeyMap[ImGuiKey_X] = GLFW_KEY_X; - io.KeyMap[ImGuiKey_Y] = GLFW_KEY_Y; - io.KeyMap[ImGuiKey_Z] = GLFW_KEY_Z; - - io.RenderDrawListsFn = ImGui_ImplGlfw_RenderDrawLists; // Alternatively you can set this to NULL and call ImGui::GetDrawData() after ImGui::Render() to get the same ImDrawData pointer. - io.SetClipboardTextFn = ImGui_ImplGlfw_SetClipboardText; - io.GetClipboardTextFn = ImGui_ImplGlfw_GetClipboardText; -#ifdef _WIN32 - io.ImeWindowHandle = glfwGetWin32Window(g_Window); -#endif - - if (install_callbacks) - { - glfwSetMouseButtonCallback(window, ImGui_ImplGlfw_MouseButtonCallback); - glfwSetScrollCallback(window, ImGui_ImplGlfw_ScrollCallback); - glfwSetKeyCallback(window, ImGui_ImplGlFw_KeyCallback); - glfwSetCharCallback(window, ImGui_ImplGlfw_CharCallback); - } - - return true; -} - -void ImGui_ImplGlfw_Shutdown() -{ - ImGui_ImplGlfw_InvalidateDeviceObjects(); - ImGui::Shutdown(); -} - -void ImGui_ImplGlfw_NewFrame() -{ - if (!g_FontTexture) - ImGui_ImplGlfw_CreateDeviceObjects(); - - ImGuiIO& io = ImGui::GetIO(); - - // Setup display size (every frame to accommodate for window resizing) - int w, h; - int display_w, display_h; - glfwGetWindowSize(g_Window, &w, &h); - glfwGetFramebufferSize(g_Window, &display_w, &display_h); - io.DisplaySize = ImVec2((float)w, (float)h); - io.DisplayFramebufferScale = ImVec2(w > 0 ? ((float)display_w / w) : 0, h > 0 ? ((float)display_h / h) : 0); - - // Setup time step - double current_time = glfwGetTime(); - io.DeltaTime = g_Time > 0.0 ? (float)(current_time - g_Time) : (float)(1.0f/60.0f); - g_Time = current_time; - - // Setup inputs - // (we already got mouse wheel, keyboard keys & characters from glfw callbacks polled in glfwPollEvents()) - if (glfwGetWindowAttrib(g_Window, GLFW_FOCUSED)) - { - double mouse_x, mouse_y; - glfwGetCursorPos(g_Window, &mouse_x, &mouse_y); - io.MousePos = ImVec2((float)mouse_x, (float)mouse_y); // Mouse position in screen coordinates (set to -1,-1 if no mouse / on another screen, etc.) - } - else - { - io.MousePos = ImVec2(-1,-1); - } - - for (int i = 0; i < 3; i++) - { - io.MouseDown[i] = g_MousePressed[i] || glfwGetMouseButton(g_Window, i) != 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. - g_MousePressed[i] = false; - } - - io.MouseWheel = g_MouseWheel; - g_MouseWheel = 0.0f; - - // Hide OS mouse cursor if ImGui is drawing it - glfwSetInputMode(g_Window, GLFW_CURSOR, io.MouseDrawCursor ? GLFW_CURSOR_HIDDEN : GLFW_CURSOR_NORMAL); - - // Start the frame - ImGui::NewFrame(); -} diff --git a/examples/opengl_example/imgui_impl_glfw.h b/examples/opengl_example/imgui_impl_glfw.h deleted file mode 100644 index 07dd96f..0000000 --- a/examples/opengl_example/imgui_impl_glfw.h +++ /dev/null @@ -1,29 +0,0 @@ -// ImGui GLFW binding with OpenGL -// In this binding, ImTextureID is used to store an OpenGL 'GLuint' texture identifier. Read the FAQ about ImTextureID in imgui.cpp. - -// If your context is GL3/GL3 then prefer using the code in opengl3_example. -// You *might* use this code with a GL3/GL4 context but make sure you disable the programmable pipeline by calling "glUseProgram(0)" before ImGui::Render(). -// We cannot do that from GL2 code because the function doesn't exist. - -// You can copy and use unmodified imgui_impl_* files in your project. See main.cpp for an example of using this. -// If you use this binding you'll need to call 4 functions: ImGui_ImplXXXX_Init(), ImGui_ImplXXXX_NewFrame(), ImGui::Render() and ImGui_ImplXXXX_Shutdown(). -// If you are new to ImGui, see examples/README.txt and documentation at the top of imgui.cpp. -// https://github.com/ocornut/imgui - -struct GLFWwindow; - -IMGUI_API bool ImGui_ImplGlfw_Init(GLFWwindow* window, bool install_callbacks); -IMGUI_API void ImGui_ImplGlfw_Shutdown(); -IMGUI_API void ImGui_ImplGlfw_NewFrame(); - -// Use if you want to reset your rendering device without losing ImGui state. -IMGUI_API void ImGui_ImplGlfw_InvalidateDeviceObjects(); -IMGUI_API bool ImGui_ImplGlfw_CreateDeviceObjects(); - -// GLFW callbacks (installed by default if you enable 'install_callbacks' during initialization) -// Provided here if you want to chain callbacks. -// You can also handle inputs yourself and use those as a reference. -IMGUI_API void ImGui_ImplGlfw_MouseButtonCallback(GLFWwindow* window, int button, int action, int mods); -IMGUI_API void ImGui_ImplGlfw_ScrollCallback(GLFWwindow* window, double xoffset, double yoffset); -IMGUI_API void ImGui_ImplGlFw_KeyCallback(GLFWwindow* window, int key, int scancode, int action, int mods); -IMGUI_API void ImGui_ImplGlfw_CharCallback(GLFWwindow* window, unsigned int c); diff --git a/examples/opengl_example/main.cpp b/examples/opengl_example/main.cpp deleted file mode 100644 index a844db5..0000000 --- a/examples/opengl_example/main.cpp +++ /dev/null @@ -1,89 +0,0 @@ -// ImGui - standalone example application for Glfw + OpenGL 2, using fixed pipeline -// If you are new to ImGui, see examples/README.txt and documentation at the top of imgui.cpp. - -#include -#include "imgui_impl_glfw.h" -#include -#include - -static void error_callback(int error, const char* description) -{ - fprintf(stderr, "Error %d: %s\n", error, description); -} - -int main(int, char**) -{ - // Setup window - glfwSetErrorCallback(error_callback); - if (!glfwInit()) - return 1; - GLFWwindow* window = glfwCreateWindow(1280, 720, "ImGui OpenGL2 example", NULL, NULL); - glfwMakeContextCurrent(window); - - // Setup ImGui binding - ImGui_ImplGlfw_Init(window, true); - - // Load Fonts - // (there is a default font, this is only if you want to change it. see extra_fonts/README.txt for more details) - //ImGuiIO& io = ImGui::GetIO(); - //io.Fonts->AddFontDefault(); - //io.Fonts->AddFontFromFileTTF("../../extra_fonts/Cousine-Regular.ttf", 15.0f); - //io.Fonts->AddFontFromFileTTF("../../extra_fonts/DroidSans.ttf", 16.0f); - //io.Fonts->AddFontFromFileTTF("../../extra_fonts/ProggyClean.ttf", 13.0f); - //io.Fonts->AddFontFromFileTTF("../../extra_fonts/ProggyTiny.ttf", 10.0f); - //io.Fonts->AddFontFromFileTTF("c:\\Windows\\Fonts\\ArialUni.ttf", 18.0f, NULL, io.Fonts->GetGlyphRangesJapanese()); - - bool show_test_window = true; - bool show_another_window = false; - ImVec4 clear_color = ImColor(114, 144, 154); - - // Main loop - while (!glfwWindowShouldClose(window)) - { - glfwPollEvents(); - ImGui_ImplGlfw_NewFrame(); - - // 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 = 0.0f; - ImGui::Text("Hello, world!"); - ImGui::SliderFloat("float", &f, 0.0f, 1.0f); - ImGui::ColorEdit3("clear color", (float*)&clear_color); - if (ImGui::Button("Test Window")) show_test_window ^= 1; - if (ImGui::Button("Another Window")) show_another_window ^= 1; - ImGui::Text("Application average %.3f ms/frame (%.1f FPS)", 1000.0f / ImGui::GetIO().Framerate, ImGui::GetIO().Framerate); - } - - // 2. Show another simple window, this time using an explicit Begin/End pair - if (show_another_window) - { - ImGui::SetNextWindowSize(ImVec2(200,100), ImGuiSetCond_FirstUseEver); - ImGui::Begin("Another Window", &show_another_window); - 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::SetNextWindowPos(ImVec2(650, 20), ImGuiSetCond_FirstUseEver); - ImGui::ShowTestWindow(&show_test_window); - } - - // Rendering - int display_w, display_h; - glfwGetFramebufferSize(window, &display_w, &display_h); - glViewport(0, 0, display_w, display_h); - glClearColor(clear_color.x, clear_color.y, clear_color.z, clear_color.w); - glClear(GL_COLOR_BUFFER_BIT); - ImGui::Render(); - glfwSwapBuffers(window); - } - - // Cleanup - ImGui_ImplGlfw_Shutdown(); - glfwTerminate(); - - return 0; -} diff --git a/examples/opengl_example/opengl_example.vcxproj b/examples/opengl_example/opengl_example.vcxproj deleted file mode 100644 index 4b354b6..0000000 --- a/examples/opengl_example/opengl_example.vcxproj +++ /dev/null @@ -1,169 +0,0 @@ - - - - - Debug - Win32 - - - Debug - x64 - - - Release - Win32 - - - Release - x64 - - - - {9CDA7840-B7A5-496D-A527-E95571496D18} - opengl_example - - - - Application - true - MultiByte - - - Application - true - MultiByte - - - Application - false - true - MultiByte - - - Application - false - true - MultiByte - - - - - - - - - - - - - - - - - - - $(ProjectDir)$(Configuration)\ - $(ProjectDir)$(Configuration)\ - $(IncludePath) - - - $(ProjectDir)$(Configuration)\ - $(ProjectDir)$(Configuration)\ - $(IncludePath) - - - $(ProjectDir)$(Configuration)\ - $(ProjectDir)$(Configuration)\ - $(IncludePath) - - - $(ProjectDir)$(Configuration)\ - $(ProjectDir)$(Configuration)\ - $(IncludePath) - - - - Level4 - Disabled - $(SolutionDir)\libs\glfw\include;..\..;%(AdditionalIncludeDirectories) - - - true - $(SolutionDir)\libs\glfw\lib-vc2010-32;%(AdditionalLibraryDirectories) - opengl32.lib;glfw3.lib;%(AdditionalDependencies) - Console - msvcrt.lib - - - - - Level4 - Disabled - $(SolutionDir)\libs\glfw\include;..\..;%(AdditionalIncludeDirectories) - - - true - $(SolutionDir)\libs\glfw\lib-vc2010-64;%(AdditionalLibraryDirectories) - opengl32.lib;glfw3.lib;%(AdditionalDependencies) - Console - msvcrt.lib - - - - - Level4 - MaxSpeed - true - true - $(SolutionDir)\libs\glfw\include;..\..;%(AdditionalIncludeDirectories) - - - true - true - true - $(SolutionDir)\libs\glfw\lib-vc2010-32;%(AdditionalLibraryDirectories) - opengl32.lib;glfw3.lib;%(AdditionalDependencies) - Console - - - - - - - Level4 - MaxSpeed - true - true - $(SolutionDir)\libs\glfw\include;..\..;%(AdditionalIncludeDirectories) - - - true - true - true - $(SolutionDir)\libs\glfw\lib-vc2010-64;%(AdditionalLibraryDirectories) - opengl32.lib;glfw3.lib;%(AdditionalDependencies) - Console - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/examples/opengl_example/opengl_example.vcxproj.filters b/examples/opengl_example/opengl_example.vcxproj.filters deleted file mode 100644 index f2282bf..0000000 --- a/examples/opengl_example/opengl_example.vcxproj.filters +++ /dev/null @@ -1,46 +0,0 @@ - - - - - {c336cfe3-f0c4-464c-9ef0-a9e17a7ff222} - - - {4FC737F1-C7A5-4376-A066-2A32D752A2FF} - cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx - - - - - sources - - - imgui - - - sources - - - imgui - - - imgui - - - - - imgui - - - imgui - - - sources - - - imgui - - - - - - \ No newline at end of file diff --git a/examples/sdl_opengl2_example/README.md b/examples/sdl_opengl2_example/README.md new file mode 100644 index 0000000..aada45d --- /dev/null +++ b/examples/sdl_opengl2_example/README.md @@ -0,0 +1,22 @@ + +# How to Build + +- On Windows with Visual Studio's CLI + +``` +set SDL2DIR=path_to_your_sdl2_folder +cl /Zi /MD /I %SDL2DIR%\include> /I ..\.. main.cpp imgui_impl_sdl.cpp ..\..\imgui*.cpp /link /LIBPATH:%SDL2DIR%\lib SDL2.lib SDL2main.lib +``` + +- On Linux and similar Unixes + +``` +c++ `sdl2-config --cflags` -I ../.. main.cpp imgui_impl_sdl.cpp ../../imgui*.cpp `sdl2-config --libs` -lGL -o sdl2example +``` + +- On Mac OS X + +``` +brew install sdl2 +c++ `sdl2-config --cflags` -I ../.. main.cpp imgui_impl_sdl.cpp ../../imgui*.cpp `sdl2-config --libs` -framework OpenGl -o sdl2example +``` diff --git a/examples/sdl_opengl2_example/imgui_impl_sdl.cpp b/examples/sdl_opengl2_example/imgui_impl_sdl.cpp new file mode 100644 index 0000000..63ed9f4 --- /dev/null +++ b/examples/sdl_opengl2_example/imgui_impl_sdl.cpp @@ -0,0 +1,277 @@ +// ImGui SDL2 binding with OpenGL +// In this binding, ImTextureID is used to store an OpenGL 'GLuint' texture identifier. Read the FAQ about ImTextureID in imgui.cpp. + +// You can copy and use unmodified imgui_impl_* files in your project. See main.cpp for an example of using this. +// If you use this binding you'll need to call 4 functions: ImGui_ImplXXXX_Init(), ImGui_ImplXXXX_NewFrame(), ImGui::Render() and ImGui_ImplXXXX_Shutdown(). +// If you are new to ImGui, see examples/README.txt and documentation at the top of imgui.cpp. +// https://github.com/ocornut/imgui + +#include +#include +#include +#include +#include "imgui_impl_sdl.h" + +// Data +static double g_Time = 0.0f; +static bool g_MousePressed[3] = { false, false, false }; +static float g_MouseWheel = 0.0f; +static GLuint g_FontTexture = 0; + +// 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) +void ImGui_ImplSdl_RenderDrawLists(ImDrawData* draw_data) +{ + // Avoid rendering when minimized, scale coordinates for retina displays (screen coordinates != framebuffer coordinates) + ImGuiIO& io = ImGui::GetIO(); + int fb_width = (int)(io.DisplaySize.x * io.DisplayFramebufferScale.x); + int fb_height = (int)(io.DisplaySize.y * io.DisplayFramebufferScale.y); + if (fb_width == 0 || fb_height == 0) + return; + draw_data->ScaleClipRects(io.DisplayFramebufferScale); + + // We are using the OpenGL fixed pipeline to make the example code simpler to read! + // Setup render state: alpha-blending enabled, no face culling, no depth testing, scissor enabled, vertex/texcoord/color pointers. + GLint last_texture; glGetIntegerv(GL_TEXTURE_BINDING_2D, &last_texture); + GLint last_viewport[4]; glGetIntegerv(GL_VIEWPORT, last_viewport); + glPushAttrib(GL_ENABLE_BIT | GL_COLOR_BUFFER_BIT | GL_TRANSFORM_BIT); + glEnable(GL_BLEND); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + glDisable(GL_CULL_FACE); + glDisable(GL_DEPTH_TEST); + glEnable(GL_SCISSOR_TEST); + glEnableClientState(GL_VERTEX_ARRAY); + glEnableClientState(GL_TEXTURE_COORD_ARRAY); + glEnableClientState(GL_COLOR_ARRAY); + glEnable(GL_TEXTURE_2D); + //glUseProgram(0); // You may want this if using this code in an OpenGL 3+ context + + // Setup viewport, orthographic projection matrix + glViewport(0, 0, (GLsizei)fb_width, (GLsizei)fb_height); + glMatrixMode(GL_PROJECTION); + glPushMatrix(); + glLoadIdentity(); + glOrtho(0.0f, io.DisplaySize.x, io.DisplaySize.y, 0.0f, -1.0f, +1.0f); + glMatrixMode(GL_MODELVIEW); + glPushMatrix(); + glLoadIdentity(); + + // Render command lists + #define OFFSETOF(TYPE, ELEMENT) ((size_t)&(((TYPE *)0)->ELEMENT)) + for (int n = 0; n < draw_data->CmdListsCount; n++) + { + const ImDrawList* cmd_list = draw_data->CmdLists[n]; + const unsigned char* vtx_buffer = (const unsigned char*)&cmd_list->VtxBuffer.front(); + const ImDrawIdx* idx_buffer = &cmd_list->IdxBuffer.front(); + glVertexPointer(2, GL_FLOAT, sizeof(ImDrawVert), (void*)(vtx_buffer + OFFSETOF(ImDrawVert, pos))); + glTexCoordPointer(2, GL_FLOAT, sizeof(ImDrawVert), (void*)(vtx_buffer + OFFSETOF(ImDrawVert, uv))); + glColorPointer(4, GL_UNSIGNED_BYTE, sizeof(ImDrawVert), (void*)(vtx_buffer + OFFSETOF(ImDrawVert, col))); + + for (int cmd_i = 0; cmd_i < cmd_list->CmdBuffer.size(); cmd_i++) + { + const ImDrawCmd* pcmd = &cmd_list->CmdBuffer[cmd_i]; + if (pcmd->UserCallback) + { + pcmd->UserCallback(cmd_list, pcmd); + } + else + { + glBindTexture(GL_TEXTURE_2D, (GLuint)(intptr_t)pcmd->TextureId); + glScissor((int)pcmd->ClipRect.x, (int)(fb_height - pcmd->ClipRect.w), (int)(pcmd->ClipRect.z - pcmd->ClipRect.x), (int)(pcmd->ClipRect.w - pcmd->ClipRect.y)); + glDrawElements(GL_TRIANGLES, (GLsizei)pcmd->ElemCount, sizeof(ImDrawIdx) == 2 ? GL_UNSIGNED_SHORT : GL_UNSIGNED_INT, idx_buffer); + } + idx_buffer += pcmd->ElemCount; + } + } + #undef OFFSETOF + + // Restore modified state + glDisableClientState(GL_COLOR_ARRAY); + glDisableClientState(GL_TEXTURE_COORD_ARRAY); + glDisableClientState(GL_VERTEX_ARRAY); + glBindTexture(GL_TEXTURE_2D, (GLuint)last_texture); + glMatrixMode(GL_MODELVIEW); + glPopMatrix(); + glMatrixMode(GL_PROJECTION); + glPopMatrix(); + glPopAttrib(); + glViewport(last_viewport[0], last_viewport[1], (GLsizei)last_viewport[2], (GLsizei)last_viewport[3]); +} + +static const char* ImGui_ImplSdl_GetClipboardText() +{ + return SDL_GetClipboardText(); +} + +static void ImGui_ImplSdl_SetClipboardText(const char* text) +{ + SDL_SetClipboardText(text); +} + +bool ImGui_ImplSdl_ProcessEvent(SDL_Event* event) +{ + ImGuiIO& io = ImGui::GetIO(); + switch (event->type) + { + case SDL_MOUSEWHEEL: + { + if (event->wheel.y > 0) + g_MouseWheel = 1; + if (event->wheel.y < 0) + g_MouseWheel = -1; + return true; + } + case SDL_MOUSEBUTTONDOWN: + { + if (event->button.button == SDL_BUTTON_LEFT) g_MousePressed[0] = true; + if (event->button.button == SDL_BUTTON_RIGHT) g_MousePressed[1] = true; + if (event->button.button == SDL_BUTTON_MIDDLE) g_MousePressed[2] = true; + return true; + } + case SDL_TEXTINPUT: + { + io.AddInputCharactersUTF8(event->text.text); + return true; + } + case SDL_KEYDOWN: + case SDL_KEYUP: + { + int key = event->key.keysym.sym & ~SDLK_SCANCODE_MASK; + io.KeysDown[key] = (event->type == SDL_KEYDOWN); + io.KeyShift = ((SDL_GetModState() & KMOD_SHIFT) != 0); + io.KeyCtrl = ((SDL_GetModState() & KMOD_CTRL) != 0); + io.KeyAlt = ((SDL_GetModState() & KMOD_ALT) != 0); + io.KeySuper = ((SDL_GetModState() & KMOD_GUI) != 0); + return true; + } + } + return false; +} + +bool ImGui_ImplSdl_CreateDeviceObjects() +{ + // Build texture atlas + ImGuiIO& io = ImGui::GetIO(); + unsigned char* pixels; + int width, height; + io.Fonts->GetTexDataAsAlpha8(&pixels, &width, &height); + + // Upload texture to graphics system + GLint last_texture; + glGetIntegerv(GL_TEXTURE_BINDING_2D, &last_texture); + glGenTextures(1, &g_FontTexture); + glBindTexture(GL_TEXTURE_2D, g_FontTexture); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glPixelStorei(GL_UNPACK_ROW_LENGTH, 0); + glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, width, height, 0, GL_ALPHA, GL_UNSIGNED_BYTE, pixels); + + // Store our identifier + io.Fonts->TexID = (void *)(intptr_t)g_FontTexture; + + // Restore state + glBindTexture(GL_TEXTURE_2D, last_texture); + + return true; +} + +void ImGui_ImplSdl_InvalidateDeviceObjects() +{ + if (g_FontTexture) + { + glDeleteTextures(1, &g_FontTexture); + ImGui::GetIO().Fonts->TexID = 0; + g_FontTexture = 0; + } +} + +bool ImGui_ImplSdl_Init(SDL_Window* window) +{ + ImGuiIO& io = ImGui::GetIO(); + io.KeyMap[ImGuiKey_Tab] = SDLK_TAB; // Keyboard mapping. ImGui will use those indices to peek into the io.KeyDown[] array. + io.KeyMap[ImGuiKey_LeftArrow] = SDL_SCANCODE_LEFT; + io.KeyMap[ImGuiKey_RightArrow] = SDL_SCANCODE_RIGHT; + io.KeyMap[ImGuiKey_UpArrow] = SDL_SCANCODE_UP; + io.KeyMap[ImGuiKey_DownArrow] = SDL_SCANCODE_DOWN; + io.KeyMap[ImGuiKey_PageUp] = SDL_SCANCODE_PAGEUP; + io.KeyMap[ImGuiKey_PageDown] = SDL_SCANCODE_PAGEDOWN; + io.KeyMap[ImGuiKey_Home] = SDL_SCANCODE_HOME; + io.KeyMap[ImGuiKey_End] = SDL_SCANCODE_END; + io.KeyMap[ImGuiKey_Delete] = SDLK_DELETE; + io.KeyMap[ImGuiKey_Backspace] = SDLK_BACKSPACE; + io.KeyMap[ImGuiKey_Enter] = SDLK_RETURN; + io.KeyMap[ImGuiKey_Escape] = SDLK_ESCAPE; + io.KeyMap[ImGuiKey_A] = SDLK_a; + io.KeyMap[ImGuiKey_C] = SDLK_c; + io.KeyMap[ImGuiKey_V] = SDLK_v; + io.KeyMap[ImGuiKey_X] = SDLK_x; + io.KeyMap[ImGuiKey_Y] = SDLK_y; + io.KeyMap[ImGuiKey_Z] = SDLK_z; + + io.RenderDrawListsFn = ImGui_ImplSdl_RenderDrawLists; // Alternatively you can set this to NULL and call ImGui::GetDrawData() after ImGui::Render() to get the same ImDrawData pointer. + io.SetClipboardTextFn = ImGui_ImplSdl_SetClipboardText; + io.GetClipboardTextFn = ImGui_ImplSdl_GetClipboardText; + +#ifdef _WIN32 + SDL_SysWMinfo wmInfo; + SDL_VERSION(&wmInfo.version); + SDL_GetWindowWMInfo(window, &wmInfo); + io.ImeWindowHandle = wmInfo.info.win.window; +#else + (void)window; +#endif + + return true; +} + +void ImGui_ImplSdl_Shutdown() +{ + ImGui_ImplSdl_InvalidateDeviceObjects(); + ImGui::Shutdown(); +} + +void ImGui_ImplSdl_NewFrame(SDL_Window *window) +{ + if (!g_FontTexture) + ImGui_ImplSdl_CreateDeviceObjects(); + + ImGuiIO& io = ImGui::GetIO(); + + // Setup display size (every frame to accommodate for window resizing) + int w, h; + int display_w, display_h; + SDL_GetWindowSize(window, &w, &h); + SDL_GL_GetDrawableSize(window, &display_w, &display_h); + io.DisplaySize = ImVec2((float)w, (float)h); + io.DisplayFramebufferScale = ImVec2(w > 0 ? ((float)display_w / w) : 0, h > 0 ? ((float)display_h / h) : 0); + + // Setup time step + Uint32 time = SDL_GetTicks(); + double current_time = time / 1000.0; + io.DeltaTime = g_Time > 0.0 ? (float)(current_time - g_Time) : (float)(1.0f/60.0f); + g_Time = current_time; + + // Setup inputs + // (we already got mouse wheel, keyboard keys & characters from SDL_PollEvent()) + int mx, my; + Uint32 mouseMask = SDL_GetMouseState(&mx, &my); + if (SDL_GetWindowFlags(window) & SDL_WINDOW_MOUSE_FOCUS) + io.MousePos = ImVec2((float)mx, (float)my); // Mouse position, in pixels (set to -1,-1 if no mouse / on another screen, etc.) + else + io.MousePos = ImVec2(-1,-1); + + io.MouseDown[0] = g_MousePressed[0] || (mouseMask & SDL_BUTTON(SDL_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] = g_MousePressed[1] || (mouseMask & SDL_BUTTON(SDL_BUTTON_RIGHT)) != 0; + io.MouseDown[2] = g_MousePressed[2] || (mouseMask & SDL_BUTTON(SDL_BUTTON_MIDDLE)) != 0; + g_MousePressed[0] = g_MousePressed[1] = g_MousePressed[2] = false; + + io.MouseWheel = g_MouseWheel; + g_MouseWheel = 0.0f; + + // Hide OS mouse cursor if ImGui is drawing it + SDL_ShowCursor(io.MouseDrawCursor ? 0 : 1); + + // Start the frame + ImGui::NewFrame(); +} diff --git a/examples/sdl_opengl2_example/imgui_impl_sdl.h b/examples/sdl_opengl2_example/imgui_impl_sdl.h new file mode 100644 index 0000000..a322bf2 --- /dev/null +++ b/examples/sdl_opengl2_example/imgui_impl_sdl.h @@ -0,0 +1,19 @@ +// ImGui SDL2 binding with OpenGL +// In this binding, ImTextureID is used to store an OpenGL 'GLuint' texture identifier. Read the FAQ about ImTextureID in imgui.cpp. + +// You can copy and use unmodified imgui_impl_* files in your project. See main.cpp for an example of using this. +// If you use this binding you'll need to call 4 functions: ImGui_ImplXXXX_Init(), ImGui_ImplXXXX_NewFrame(), ImGui::Render() and ImGui_ImplXXXX_Shutdown(). +// If you are new to ImGui, see examples/README.txt and documentation at the top of imgui.cpp. +// https://github.com/ocornut/imgui + +struct SDL_Window; +typedef union SDL_Event SDL_Event; + +IMGUI_API bool ImGui_ImplSdl_Init(SDL_Window* window); +IMGUI_API void ImGui_ImplSdl_Shutdown(); +IMGUI_API void ImGui_ImplSdl_NewFrame(SDL_Window* window); +IMGUI_API bool ImGui_ImplSdl_ProcessEvent(SDL_Event* event); + +// Use if you want to reset your rendering device without losing ImGui state. +IMGUI_API void ImGui_ImplSdl_InvalidateDeviceObjects(); +IMGUI_API bool ImGui_ImplSdl_CreateDeviceObjects(); diff --git a/examples/sdl_opengl2_example/main.cpp b/examples/sdl_opengl2_example/main.cpp new file mode 100644 index 0000000..f42e7fa --- /dev/null +++ b/examples/sdl_opengl2_example/main.cpp @@ -0,0 +1,103 @@ +// ImGui - standalone example application for SDL2 + OpenGL +// If you are new to ImGui, see examples/README.txt and documentation at the top of imgui.cpp. + +#include +#include "imgui_impl_sdl.h" +#include +#include +#include + +int main(int, char**) +{ + // Setup SDL + if (SDL_Init(SDL_INIT_VIDEO|SDL_INIT_TIMER) != 0) + { + printf("Error: %s\n", SDL_GetError()); + return -1; + } + + // Setup window + SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1); + SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 24); + SDL_GL_SetAttribute(SDL_GL_STENCIL_SIZE, 8); + SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 2); + SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 2); + SDL_DisplayMode current; + SDL_GetCurrentDisplayMode(0, ¤t); + SDL_Window *window = SDL_CreateWindow("ImGui SDL2+OpenGL example", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, 1280, 720, SDL_WINDOW_OPENGL|SDL_WINDOW_RESIZABLE); + SDL_GLContext glcontext = SDL_GL_CreateContext(window); + + // Setup ImGui binding + ImGui_ImplSdl_Init(window); + + // Load Fonts + // (there is a default font, this is only if you want to change it. see extra_fonts/README.txt for more details) + //ImGuiIO& io = ImGui::GetIO(); + //io.Fonts->AddFontDefault(); + //io.Fonts->AddFontFromFileTTF("../../extra_fonts/Cousine-Regular.ttf", 15.0f); + //io.Fonts->AddFontFromFileTTF("../../extra_fonts/DroidSans.ttf", 16.0f); + //io.Fonts->AddFontFromFileTTF("../../extra_fonts/ProggyClean.ttf", 13.0f); + //io.Fonts->AddFontFromFileTTF("../../extra_fonts/ProggyTiny.ttf", 10.0f); + //io.Fonts->AddFontFromFileTTF("c:\\Windows\\Fonts\\ArialUni.ttf", 18.0f, NULL, io.Fonts->GetGlyphRangesJapanese()); + + bool show_test_window = true; + bool show_another_window = false; + ImVec4 clear_color = ImColor(114, 144, 154); + + // Main loop + bool done = false; + while (!done) + { + SDL_Event event; + while (SDL_PollEvent(&event)) + { + ImGui_ImplSdl_ProcessEvent(&event); + if (event.type == SDL_QUIT) + done = true; + } + ImGui_ImplSdl_NewFrame(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" + { + static float f = 0.0f; + ImGui::Text("Hello, world!"); + ImGui::SliderFloat("float", &f, 0.0f, 1.0f); + ImGui::ColorEdit3("clear color", (float*)&clear_color); + if (ImGui::Button("Test Window")) show_test_window ^= 1; + if (ImGui::Button("Another Window")) show_another_window ^= 1; + ImGui::Text("Application average %.3f ms/frame (%.1f FPS)", 1000.0f / ImGui::GetIO().Framerate, ImGui::GetIO().Framerate); + } + + // 2. Show another simple window, this time using an explicit Begin/End pair + if (show_another_window) + { + ImGui::SetNextWindowSize(ImVec2(200,100), ImGuiSetCond_FirstUseEver); + ImGui::Begin("Another Window", &show_another_window); + 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::SetNextWindowPos(ImVec2(650, 20), ImGuiSetCond_FirstUseEver); + ImGui::ShowTestWindow(&show_test_window); + } + + // Rendering + glViewport(0, 0, (int)ImGui::GetIO().DisplaySize.x, (int)ImGui::GetIO().DisplaySize.y); + glClearColor(clear_color.x, clear_color.y, clear_color.z, clear_color.w); + glClear(GL_COLOR_BUFFER_BIT); + ImGui::Render(); + SDL_GL_SwapWindow(window); + } + + // Cleanup + ImGui_ImplSdl_Shutdown(); + SDL_GL_DeleteContext(glcontext); + SDL_DestroyWindow(window); + SDL_Quit(); + + return 0; +} diff --git a/examples/sdl_opengl_example/README.md b/examples/sdl_opengl_example/README.md deleted file mode 100644 index aada45d..0000000 --- a/examples/sdl_opengl_example/README.md +++ /dev/null @@ -1,22 +0,0 @@ - -# How to Build - -- On Windows with Visual Studio's CLI - -``` -set SDL2DIR=path_to_your_sdl2_folder -cl /Zi /MD /I %SDL2DIR%\include> /I ..\.. main.cpp imgui_impl_sdl.cpp ..\..\imgui*.cpp /link /LIBPATH:%SDL2DIR%\lib SDL2.lib SDL2main.lib -``` - -- On Linux and similar Unixes - -``` -c++ `sdl2-config --cflags` -I ../.. main.cpp imgui_impl_sdl.cpp ../../imgui*.cpp `sdl2-config --libs` -lGL -o sdl2example -``` - -- On Mac OS X - -``` -brew install sdl2 -c++ `sdl2-config --cflags` -I ../.. main.cpp imgui_impl_sdl.cpp ../../imgui*.cpp `sdl2-config --libs` -framework OpenGl -o sdl2example -``` diff --git a/examples/sdl_opengl_example/imgui_impl_sdl.cpp b/examples/sdl_opengl_example/imgui_impl_sdl.cpp deleted file mode 100644 index 63ed9f4..0000000 --- a/examples/sdl_opengl_example/imgui_impl_sdl.cpp +++ /dev/null @@ -1,277 +0,0 @@ -// ImGui SDL2 binding with OpenGL -// In this binding, ImTextureID is used to store an OpenGL 'GLuint' texture identifier. Read the FAQ about ImTextureID in imgui.cpp. - -// You can copy and use unmodified imgui_impl_* files in your project. See main.cpp for an example of using this. -// If you use this binding you'll need to call 4 functions: ImGui_ImplXXXX_Init(), ImGui_ImplXXXX_NewFrame(), ImGui::Render() and ImGui_ImplXXXX_Shutdown(). -// If you are new to ImGui, see examples/README.txt and documentation at the top of imgui.cpp. -// https://github.com/ocornut/imgui - -#include -#include -#include -#include -#include "imgui_impl_sdl.h" - -// Data -static double g_Time = 0.0f; -static bool g_MousePressed[3] = { false, false, false }; -static float g_MouseWheel = 0.0f; -static GLuint g_FontTexture = 0; - -// 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) -void ImGui_ImplSdl_RenderDrawLists(ImDrawData* draw_data) -{ - // Avoid rendering when minimized, scale coordinates for retina displays (screen coordinates != framebuffer coordinates) - ImGuiIO& io = ImGui::GetIO(); - int fb_width = (int)(io.DisplaySize.x * io.DisplayFramebufferScale.x); - int fb_height = (int)(io.DisplaySize.y * io.DisplayFramebufferScale.y); - if (fb_width == 0 || fb_height == 0) - return; - draw_data->ScaleClipRects(io.DisplayFramebufferScale); - - // We are using the OpenGL fixed pipeline to make the example code simpler to read! - // Setup render state: alpha-blending enabled, no face culling, no depth testing, scissor enabled, vertex/texcoord/color pointers. - GLint last_texture; glGetIntegerv(GL_TEXTURE_BINDING_2D, &last_texture); - GLint last_viewport[4]; glGetIntegerv(GL_VIEWPORT, last_viewport); - glPushAttrib(GL_ENABLE_BIT | GL_COLOR_BUFFER_BIT | GL_TRANSFORM_BIT); - glEnable(GL_BLEND); - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - glDisable(GL_CULL_FACE); - glDisable(GL_DEPTH_TEST); - glEnable(GL_SCISSOR_TEST); - glEnableClientState(GL_VERTEX_ARRAY); - glEnableClientState(GL_TEXTURE_COORD_ARRAY); - glEnableClientState(GL_COLOR_ARRAY); - glEnable(GL_TEXTURE_2D); - //glUseProgram(0); // You may want this if using this code in an OpenGL 3+ context - - // Setup viewport, orthographic projection matrix - glViewport(0, 0, (GLsizei)fb_width, (GLsizei)fb_height); - glMatrixMode(GL_PROJECTION); - glPushMatrix(); - glLoadIdentity(); - glOrtho(0.0f, io.DisplaySize.x, io.DisplaySize.y, 0.0f, -1.0f, +1.0f); - glMatrixMode(GL_MODELVIEW); - glPushMatrix(); - glLoadIdentity(); - - // Render command lists - #define OFFSETOF(TYPE, ELEMENT) ((size_t)&(((TYPE *)0)->ELEMENT)) - for (int n = 0; n < draw_data->CmdListsCount; n++) - { - const ImDrawList* cmd_list = draw_data->CmdLists[n]; - const unsigned char* vtx_buffer = (const unsigned char*)&cmd_list->VtxBuffer.front(); - const ImDrawIdx* idx_buffer = &cmd_list->IdxBuffer.front(); - glVertexPointer(2, GL_FLOAT, sizeof(ImDrawVert), (void*)(vtx_buffer + OFFSETOF(ImDrawVert, pos))); - glTexCoordPointer(2, GL_FLOAT, sizeof(ImDrawVert), (void*)(vtx_buffer + OFFSETOF(ImDrawVert, uv))); - glColorPointer(4, GL_UNSIGNED_BYTE, sizeof(ImDrawVert), (void*)(vtx_buffer + OFFSETOF(ImDrawVert, col))); - - for (int cmd_i = 0; cmd_i < cmd_list->CmdBuffer.size(); cmd_i++) - { - const ImDrawCmd* pcmd = &cmd_list->CmdBuffer[cmd_i]; - if (pcmd->UserCallback) - { - pcmd->UserCallback(cmd_list, pcmd); - } - else - { - glBindTexture(GL_TEXTURE_2D, (GLuint)(intptr_t)pcmd->TextureId); - glScissor((int)pcmd->ClipRect.x, (int)(fb_height - pcmd->ClipRect.w), (int)(pcmd->ClipRect.z - pcmd->ClipRect.x), (int)(pcmd->ClipRect.w - pcmd->ClipRect.y)); - glDrawElements(GL_TRIANGLES, (GLsizei)pcmd->ElemCount, sizeof(ImDrawIdx) == 2 ? GL_UNSIGNED_SHORT : GL_UNSIGNED_INT, idx_buffer); - } - idx_buffer += pcmd->ElemCount; - } - } - #undef OFFSETOF - - // Restore modified state - glDisableClientState(GL_COLOR_ARRAY); - glDisableClientState(GL_TEXTURE_COORD_ARRAY); - glDisableClientState(GL_VERTEX_ARRAY); - glBindTexture(GL_TEXTURE_2D, (GLuint)last_texture); - glMatrixMode(GL_MODELVIEW); - glPopMatrix(); - glMatrixMode(GL_PROJECTION); - glPopMatrix(); - glPopAttrib(); - glViewport(last_viewport[0], last_viewport[1], (GLsizei)last_viewport[2], (GLsizei)last_viewport[3]); -} - -static const char* ImGui_ImplSdl_GetClipboardText() -{ - return SDL_GetClipboardText(); -} - -static void ImGui_ImplSdl_SetClipboardText(const char* text) -{ - SDL_SetClipboardText(text); -} - -bool ImGui_ImplSdl_ProcessEvent(SDL_Event* event) -{ - ImGuiIO& io = ImGui::GetIO(); - switch (event->type) - { - case SDL_MOUSEWHEEL: - { - if (event->wheel.y > 0) - g_MouseWheel = 1; - if (event->wheel.y < 0) - g_MouseWheel = -1; - return true; - } - case SDL_MOUSEBUTTONDOWN: - { - if (event->button.button == SDL_BUTTON_LEFT) g_MousePressed[0] = true; - if (event->button.button == SDL_BUTTON_RIGHT) g_MousePressed[1] = true; - if (event->button.button == SDL_BUTTON_MIDDLE) g_MousePressed[2] = true; - return true; - } - case SDL_TEXTINPUT: - { - io.AddInputCharactersUTF8(event->text.text); - return true; - } - case SDL_KEYDOWN: - case SDL_KEYUP: - { - int key = event->key.keysym.sym & ~SDLK_SCANCODE_MASK; - io.KeysDown[key] = (event->type == SDL_KEYDOWN); - io.KeyShift = ((SDL_GetModState() & KMOD_SHIFT) != 0); - io.KeyCtrl = ((SDL_GetModState() & KMOD_CTRL) != 0); - io.KeyAlt = ((SDL_GetModState() & KMOD_ALT) != 0); - io.KeySuper = ((SDL_GetModState() & KMOD_GUI) != 0); - return true; - } - } - return false; -} - -bool ImGui_ImplSdl_CreateDeviceObjects() -{ - // Build texture atlas - ImGuiIO& io = ImGui::GetIO(); - unsigned char* pixels; - int width, height; - io.Fonts->GetTexDataAsAlpha8(&pixels, &width, &height); - - // Upload texture to graphics system - GLint last_texture; - glGetIntegerv(GL_TEXTURE_BINDING_2D, &last_texture); - glGenTextures(1, &g_FontTexture); - glBindTexture(GL_TEXTURE_2D, g_FontTexture); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - glPixelStorei(GL_UNPACK_ROW_LENGTH, 0); - glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, width, height, 0, GL_ALPHA, GL_UNSIGNED_BYTE, pixels); - - // Store our identifier - io.Fonts->TexID = (void *)(intptr_t)g_FontTexture; - - // Restore state - glBindTexture(GL_TEXTURE_2D, last_texture); - - return true; -} - -void ImGui_ImplSdl_InvalidateDeviceObjects() -{ - if (g_FontTexture) - { - glDeleteTextures(1, &g_FontTexture); - ImGui::GetIO().Fonts->TexID = 0; - g_FontTexture = 0; - } -} - -bool ImGui_ImplSdl_Init(SDL_Window* window) -{ - ImGuiIO& io = ImGui::GetIO(); - io.KeyMap[ImGuiKey_Tab] = SDLK_TAB; // Keyboard mapping. ImGui will use those indices to peek into the io.KeyDown[] array. - io.KeyMap[ImGuiKey_LeftArrow] = SDL_SCANCODE_LEFT; - io.KeyMap[ImGuiKey_RightArrow] = SDL_SCANCODE_RIGHT; - io.KeyMap[ImGuiKey_UpArrow] = SDL_SCANCODE_UP; - io.KeyMap[ImGuiKey_DownArrow] = SDL_SCANCODE_DOWN; - io.KeyMap[ImGuiKey_PageUp] = SDL_SCANCODE_PAGEUP; - io.KeyMap[ImGuiKey_PageDown] = SDL_SCANCODE_PAGEDOWN; - io.KeyMap[ImGuiKey_Home] = SDL_SCANCODE_HOME; - io.KeyMap[ImGuiKey_End] = SDL_SCANCODE_END; - io.KeyMap[ImGuiKey_Delete] = SDLK_DELETE; - io.KeyMap[ImGuiKey_Backspace] = SDLK_BACKSPACE; - io.KeyMap[ImGuiKey_Enter] = SDLK_RETURN; - io.KeyMap[ImGuiKey_Escape] = SDLK_ESCAPE; - io.KeyMap[ImGuiKey_A] = SDLK_a; - io.KeyMap[ImGuiKey_C] = SDLK_c; - io.KeyMap[ImGuiKey_V] = SDLK_v; - io.KeyMap[ImGuiKey_X] = SDLK_x; - io.KeyMap[ImGuiKey_Y] = SDLK_y; - io.KeyMap[ImGuiKey_Z] = SDLK_z; - - io.RenderDrawListsFn = ImGui_ImplSdl_RenderDrawLists; // Alternatively you can set this to NULL and call ImGui::GetDrawData() after ImGui::Render() to get the same ImDrawData pointer. - io.SetClipboardTextFn = ImGui_ImplSdl_SetClipboardText; - io.GetClipboardTextFn = ImGui_ImplSdl_GetClipboardText; - -#ifdef _WIN32 - SDL_SysWMinfo wmInfo; - SDL_VERSION(&wmInfo.version); - SDL_GetWindowWMInfo(window, &wmInfo); - io.ImeWindowHandle = wmInfo.info.win.window; -#else - (void)window; -#endif - - return true; -} - -void ImGui_ImplSdl_Shutdown() -{ - ImGui_ImplSdl_InvalidateDeviceObjects(); - ImGui::Shutdown(); -} - -void ImGui_ImplSdl_NewFrame(SDL_Window *window) -{ - if (!g_FontTexture) - ImGui_ImplSdl_CreateDeviceObjects(); - - ImGuiIO& io = ImGui::GetIO(); - - // Setup display size (every frame to accommodate for window resizing) - int w, h; - int display_w, display_h; - SDL_GetWindowSize(window, &w, &h); - SDL_GL_GetDrawableSize(window, &display_w, &display_h); - io.DisplaySize = ImVec2((float)w, (float)h); - io.DisplayFramebufferScale = ImVec2(w > 0 ? ((float)display_w / w) : 0, h > 0 ? ((float)display_h / h) : 0); - - // Setup time step - Uint32 time = SDL_GetTicks(); - double current_time = time / 1000.0; - io.DeltaTime = g_Time > 0.0 ? (float)(current_time - g_Time) : (float)(1.0f/60.0f); - g_Time = current_time; - - // Setup inputs - // (we already got mouse wheel, keyboard keys & characters from SDL_PollEvent()) - int mx, my; - Uint32 mouseMask = SDL_GetMouseState(&mx, &my); - if (SDL_GetWindowFlags(window) & SDL_WINDOW_MOUSE_FOCUS) - io.MousePos = ImVec2((float)mx, (float)my); // Mouse position, in pixels (set to -1,-1 if no mouse / on another screen, etc.) - else - io.MousePos = ImVec2(-1,-1); - - io.MouseDown[0] = g_MousePressed[0] || (mouseMask & SDL_BUTTON(SDL_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] = g_MousePressed[1] || (mouseMask & SDL_BUTTON(SDL_BUTTON_RIGHT)) != 0; - io.MouseDown[2] = g_MousePressed[2] || (mouseMask & SDL_BUTTON(SDL_BUTTON_MIDDLE)) != 0; - g_MousePressed[0] = g_MousePressed[1] = g_MousePressed[2] = false; - - io.MouseWheel = g_MouseWheel; - g_MouseWheel = 0.0f; - - // Hide OS mouse cursor if ImGui is drawing it - SDL_ShowCursor(io.MouseDrawCursor ? 0 : 1); - - // Start the frame - ImGui::NewFrame(); -} diff --git a/examples/sdl_opengl_example/imgui_impl_sdl.h b/examples/sdl_opengl_example/imgui_impl_sdl.h deleted file mode 100644 index a322bf2..0000000 --- a/examples/sdl_opengl_example/imgui_impl_sdl.h +++ /dev/null @@ -1,19 +0,0 @@ -// ImGui SDL2 binding with OpenGL -// In this binding, ImTextureID is used to store an OpenGL 'GLuint' texture identifier. Read the FAQ about ImTextureID in imgui.cpp. - -// You can copy and use unmodified imgui_impl_* files in your project. See main.cpp for an example of using this. -// If you use this binding you'll need to call 4 functions: ImGui_ImplXXXX_Init(), ImGui_ImplXXXX_NewFrame(), ImGui::Render() and ImGui_ImplXXXX_Shutdown(). -// If you are new to ImGui, see examples/README.txt and documentation at the top of imgui.cpp. -// https://github.com/ocornut/imgui - -struct SDL_Window; -typedef union SDL_Event SDL_Event; - -IMGUI_API bool ImGui_ImplSdl_Init(SDL_Window* window); -IMGUI_API void ImGui_ImplSdl_Shutdown(); -IMGUI_API void ImGui_ImplSdl_NewFrame(SDL_Window* window); -IMGUI_API bool ImGui_ImplSdl_ProcessEvent(SDL_Event* event); - -// Use if you want to reset your rendering device without losing ImGui state. -IMGUI_API void ImGui_ImplSdl_InvalidateDeviceObjects(); -IMGUI_API bool ImGui_ImplSdl_CreateDeviceObjects(); diff --git a/examples/README.txt b/examples/README.txt index df2e86d..5a1c8df 100644 --- a/examples/README.txt +++ b/examples/README.txt @@ -8,11 +8,13 @@ TL;DR; - Newcomers, read 'PROGRAMMER GUIDE' in imgui.cpp for notes on how to setup ImGui in your codebase. - - Refer to 'opengl_example' to understand how the library is setup, it is the simplest one. + - Refer to 'opengl2_example' to LEARN how the library is setup, it is the simplest one. The other examples requires more boilerplate and are harder to read. + - If you are using OpenGL in your application, probably use an opengl3_xxx backend. + Mixing old fixed pipeline OpenGL2 and programmable pipeline OpenGL3+ isn't well supported by drivers. - If you are using of the backend provided here, so you can copy the imgui_impl_xxx.cpp/h files to your project and use them unmodified. - - If you have your own engine, you probably want to start from 'opengl_example' and adapt it to + - If you have your own engine, you probably want to start from one of the OpenGL example and adapt it to your engine, but you can read the other examples as well. ImGui is highly portable and only requires a few things to run: @@ -41,15 +43,14 @@ Also note that some setup or GPU drivers may be causing extra lag (possibly by enforcing triple buffering), leaving you with no option but sadness/anger (Intel GPU drivers were reported as such). -opengl_example/ - OpenGL example, using GLFW + fixed pipeline. - This is simple and should work for all OpenGL enabled applications. - Prefer following this example to learn how ImGui works! - (You can use this code in a GL3/GL4 context but make sure you disable the programmable pipeline - by calling "glUseProgram(0)" before ImGui::Render.) +opengl2_example/ + GLFW + OpenGL example (old fixed pipeline). + This is simple to read. Prefer following this example to learn how ImGui works! + (You might be able to use this code in a GL3/GL4 context but make sure you disable the programmable + pipeline by calling "glUseProgram(0)" before ImGui::Render.) opengl3_example/ - OpenGL example, using GLFW/GL3W + programmable pipeline. + GLFW + OpenGL example (programmable pipeline, binding modern functions with GL3W). This uses more modern OpenGL calls and custom shaders. It's more messy. directx9_example/ @@ -68,8 +69,8 @@ On iOS, Using Synergy to access keyboard/mouse data from server computer. Synergy keyboard integration is rather hacky. -sdl_opengl_example/ - SDL2 + OpenGL example. +sdl_opengl2_example/ + SDL2 + OpenGL example (old fixed pipeline). sdl_opengl3_example/ SDL2 + OpenGL3 example. diff --git a/examples/imgui_examples_msvc2010.sln b/examples/imgui_examples_msvc2010.sln index b7e6a25..16f0d60 100644 --- a/examples/imgui_examples_msvc2010.sln +++ b/examples/imgui_examples_msvc2010.sln @@ -1,7 +1,7 @@  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}" +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "opengl2_example", "opengl_example\opengl2_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 diff --git a/examples/opengl2_example/Makefile b/examples/opengl2_example/Makefile new file mode 100644 index 0000000..bd79d1b --- /dev/null +++ b/examples/opengl2_example/Makefile @@ -0,0 +1,60 @@ +# +# Cross Platform Makefile +# Compatible with Ubuntu 14.04.1 and Mac OS X +# +# +# if you using Mac OS X: +# You'll need glfw +# http://www.glfw.org +# + +#CXX = g++ + +EXE = opengl2_example +OBJS = main.o imgui_impl_glfw.o +OBJS += ../../imgui.o ../../imgui_demo.o ../../imgui_draw.o + +UNAME_S := $(shell uname -s) + + +ifeq ($(UNAME_S), Linux) #LINUX + ECHO_MESSAGE = "Linux" + LIBS = -lGL `pkg-config --static --libs glfw3` + + CXXFLAGS = -I../../ `pkg-config --cflags glfw3` + CXXFLAGS += -Wall -Wformat + CFLAGS = $(CXXFLAGS) +endif + +ifeq ($(UNAME_S), Darwin) #APPLE + ECHO_MESSAGE = "Mac OS X" + LIBS = -framework OpenGL -framework Cocoa -framework IOKit -framework CoreVideo + LIBS += -L/usr/local/lib -lglfw3 + + CXXFLAGS = -I../../ -I/usr/local/include + CXXFLAGS += -Wall -Wformat +# CXXFLAGS += -D__APPLE__ + CFLAGS = $(CXXFLAGS) +endif + +ifeq ($(UNAME_S), MINGW64_NT-6.3) + ECHO_MESSAGE = "Windows" + LIBS = -lglfw3 -lgdi32 -lopengl32 -limm32 + + CXXFLAGS = -I../../ -I../libs/gl3w `pkg-config --cflags glfw3` + CXXFLAGS += -Wall -Wformat + CFLAGS = $(CXXFLAGS) +endif + +.cpp.o: + $(CXX) $(CXXFLAGS) -c -o $@ $< + +all: $(EXE) + @echo Build complete for $(ECHO_MESSAGE) + +$(EXE): $(OBJS) + $(CXX) -o $(EXE) $(OBJS) $(CXXFLAGS) $(LIBS) + +clean: + rm $(EXE) $(OBJS) + diff --git a/examples/opengl2_example/build_win32.bat b/examples/opengl2_example/build_win32.bat new file mode 100644 index 0000000..278381c --- /dev/null +++ b/examples/opengl2_example/build_win32.bat @@ -0,0 +1,3 @@ +@REM Build for Visual Studio compiler. Run your copy of vcvars32.bat or vcvarsall.bat to setup command-line compiler. +mkdir Debug +cl /nologo /Zi /MD /I ..\.. /I ..\libs\glfw\include *.cpp ..\..\*.cpp /FeDebug/opengl_example.exe /FoDebug/ /link /LIBPATH:..\libs\glfw\lib-vc2010-32 glfw3.lib opengl32.lib gdi32.lib shell32.lib diff --git a/examples/opengl2_example/imgui_impl_glfw.cpp b/examples/opengl2_example/imgui_impl_glfw.cpp new file mode 100644 index 0000000..2d1f5c1 --- /dev/null +++ b/examples/opengl2_example/imgui_impl_glfw.cpp @@ -0,0 +1,288 @@ +// ImGui GLFW binding with OpenGL +// In this binding, ImTextureID is used to store an OpenGL 'GLuint' texture identifier. Read the FAQ about ImTextureID in imgui.cpp. + +// If your context is GL3/GL3 then prefer using the code in opengl3_example. +// You *might* use this code with a GL3/GL4 context but make sure you disable the programmable pipeline by calling "glUseProgram(0)" before ImGui::Render(). +// We cannot do that from GL2 code because the function doesn't exist. + +// You can copy and use unmodified imgui_impl_* files in your project. See main.cpp for an example of using this. +// If you use this binding you'll need to call 4 functions: ImGui_ImplXXXX_Init(), ImGui_ImplXXXX_NewFrame(), ImGui::Render() and ImGui_ImplXXXX_Shutdown(). +// If you are new to ImGui, see examples/README.txt and documentation at the top of imgui.cpp. +// https://github.com/ocornut/imgui + +#include +#include "imgui_impl_glfw.h" + +// GLFW +#include +#ifdef _WIN32 +#undef APIENTRY +#define GLFW_EXPOSE_NATIVE_WIN32 +#define GLFW_EXPOSE_NATIVE_WGL +#include +#endif + +// Data +static GLFWwindow* g_Window = NULL; +static double g_Time = 0.0f; +static bool g_MousePressed[3] = { false, false, false }; +static float g_MouseWheel = 0.0f; +static GLuint g_FontTexture = 0; + +// 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) +void ImGui_ImplGlfw_RenderDrawLists(ImDrawData* draw_data) +{ + // Avoid rendering when minimized, scale coordinates for retina displays (screen coordinates != framebuffer coordinates) + ImGuiIO& io = ImGui::GetIO(); + int fb_width = (int)(io.DisplaySize.x * io.DisplayFramebufferScale.x); + int fb_height = (int)(io.DisplaySize.y * io.DisplayFramebufferScale.y); + if (fb_width == 0 || fb_height == 0) + return; + draw_data->ScaleClipRects(io.DisplayFramebufferScale); + + // We are using the OpenGL fixed pipeline to make the example code simpler to read! + // Setup render state: alpha-blending enabled, no face culling, no depth testing, scissor enabled, vertex/texcoord/color pointers. + GLint last_texture; glGetIntegerv(GL_TEXTURE_BINDING_2D, &last_texture); + GLint last_viewport[4]; glGetIntegerv(GL_VIEWPORT, last_viewport); + glPushAttrib(GL_ENABLE_BIT | GL_COLOR_BUFFER_BIT | GL_TRANSFORM_BIT); + glEnable(GL_BLEND); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + glDisable(GL_CULL_FACE); + glDisable(GL_DEPTH_TEST); + glEnable(GL_SCISSOR_TEST); + glEnableClientState(GL_VERTEX_ARRAY); + glEnableClientState(GL_TEXTURE_COORD_ARRAY); + glEnableClientState(GL_COLOR_ARRAY); + glEnable(GL_TEXTURE_2D); + //glUseProgram(0); // You may want this if using this code in an OpenGL 3+ context + + // Setup viewport, orthographic projection matrix + glViewport(0, 0, (GLsizei)fb_width, (GLsizei)fb_height); + glMatrixMode(GL_PROJECTION); + glPushMatrix(); + glLoadIdentity(); + glOrtho(0.0f, io.DisplaySize.x, io.DisplaySize.y, 0.0f, -1.0f, +1.0f); + glMatrixMode(GL_MODELVIEW); + glPushMatrix(); + glLoadIdentity(); + + // Render command lists + #define OFFSETOF(TYPE, ELEMENT) ((size_t)&(((TYPE *)0)->ELEMENT)) + for (int n = 0; n < draw_data->CmdListsCount; n++) + { + const ImDrawList* cmd_list = draw_data->CmdLists[n]; + const unsigned char* vtx_buffer = (const unsigned char*)&cmd_list->VtxBuffer.front(); + const ImDrawIdx* idx_buffer = &cmd_list->IdxBuffer.front(); + glVertexPointer(2, GL_FLOAT, sizeof(ImDrawVert), (void*)(vtx_buffer + OFFSETOF(ImDrawVert, pos))); + glTexCoordPointer(2, GL_FLOAT, sizeof(ImDrawVert), (void*)(vtx_buffer + OFFSETOF(ImDrawVert, uv))); + glColorPointer(4, GL_UNSIGNED_BYTE, sizeof(ImDrawVert), (void*)(vtx_buffer + OFFSETOF(ImDrawVert, col))); + + for (int cmd_i = 0; cmd_i < cmd_list->CmdBuffer.size(); cmd_i++) + { + const ImDrawCmd* pcmd = &cmd_list->CmdBuffer[cmd_i]; + if (pcmd->UserCallback) + { + pcmd->UserCallback(cmd_list, pcmd); + } + else + { + glBindTexture(GL_TEXTURE_2D, (GLuint)(intptr_t)pcmd->TextureId); + glScissor((int)pcmd->ClipRect.x, (int)(fb_height - pcmd->ClipRect.w), (int)(pcmd->ClipRect.z - pcmd->ClipRect.x), (int)(pcmd->ClipRect.w - pcmd->ClipRect.y)); + glDrawElements(GL_TRIANGLES, (GLsizei)pcmd->ElemCount, sizeof(ImDrawIdx) == 2 ? GL_UNSIGNED_SHORT : GL_UNSIGNED_INT, idx_buffer); + } + idx_buffer += pcmd->ElemCount; + } + } + #undef OFFSETOF + + // Restore modified state + glDisableClientState(GL_COLOR_ARRAY); + glDisableClientState(GL_TEXTURE_COORD_ARRAY); + glDisableClientState(GL_VERTEX_ARRAY); + glBindTexture(GL_TEXTURE_2D, (GLuint)last_texture); + glMatrixMode(GL_MODELVIEW); + glPopMatrix(); + glMatrixMode(GL_PROJECTION); + glPopMatrix(); + glPopAttrib(); + glViewport(last_viewport[0], last_viewport[1], (GLsizei)last_viewport[2], (GLsizei)last_viewport[3]); +} + +static const char* ImGui_ImplGlfw_GetClipboardText() +{ + return glfwGetClipboardString(g_Window); +} + +static void ImGui_ImplGlfw_SetClipboardText(const char* text) +{ + glfwSetClipboardString(g_Window, text); +} + +void ImGui_ImplGlfw_MouseButtonCallback(GLFWwindow*, int button, int action, int /*mods*/) +{ + if (action == GLFW_PRESS && button >= 0 && button < 3) + g_MousePressed[button] = true; +} + +void ImGui_ImplGlfw_ScrollCallback(GLFWwindow*, double /*xoffset*/, double yoffset) +{ + g_MouseWheel += (float)yoffset; // Use fractional mouse wheel, 1.0 unit 5 lines. +} + +void ImGui_ImplGlFw_KeyCallback(GLFWwindow*, int key, int, int action, int mods) +{ + ImGuiIO& io = ImGui::GetIO(); + if (action == GLFW_PRESS) + io.KeysDown[key] = true; + if (action == GLFW_RELEASE) + io.KeysDown[key] = false; + + (void)mods; // Modifiers are not reliable across systems + io.KeyCtrl = io.KeysDown[GLFW_KEY_LEFT_CONTROL] || io.KeysDown[GLFW_KEY_RIGHT_CONTROL]; + io.KeyShift = io.KeysDown[GLFW_KEY_LEFT_SHIFT] || io.KeysDown[GLFW_KEY_RIGHT_SHIFT]; + io.KeyAlt = io.KeysDown[GLFW_KEY_LEFT_ALT] || io.KeysDown[GLFW_KEY_RIGHT_ALT]; + io.KeySuper = io.KeysDown[GLFW_KEY_LEFT_SUPER] || io.KeysDown[GLFW_KEY_RIGHT_SUPER]; +} + +void ImGui_ImplGlfw_CharCallback(GLFWwindow*, unsigned int c) +{ + ImGuiIO& io = ImGui::GetIO(); + if (c > 0 && c < 0x10000) + io.AddInputCharacter((unsigned short)c); +} + +bool ImGui_ImplGlfw_CreateDeviceObjects() +{ + // Build texture atlas + ImGuiIO& io = ImGui::GetIO(); + unsigned char* pixels; + int width, height; + io.Fonts->GetTexDataAsAlpha8(&pixels, &width, &height); + + // Upload texture to graphics system + GLint last_texture; + glGetIntegerv(GL_TEXTURE_BINDING_2D, &last_texture); + glGenTextures(1, &g_FontTexture); + glBindTexture(GL_TEXTURE_2D, g_FontTexture); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, width, height, 0, GL_ALPHA, GL_UNSIGNED_BYTE, pixels); + + // Store our identifier + io.Fonts->TexID = (void *)(intptr_t)g_FontTexture; + + // Restore state + glBindTexture(GL_TEXTURE_2D, last_texture); + + return true; +} + +void ImGui_ImplGlfw_InvalidateDeviceObjects() +{ + if (g_FontTexture) + { + glDeleteTextures(1, &g_FontTexture); + ImGui::GetIO().Fonts->TexID = 0; + g_FontTexture = 0; + } +} + +bool ImGui_ImplGlfw_Init(GLFWwindow* window, bool install_callbacks) +{ + g_Window = window; + + ImGuiIO& io = ImGui::GetIO(); + 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; + io.KeyMap[ImGuiKey_DownArrow] = GLFW_KEY_DOWN; + io.KeyMap[ImGuiKey_PageUp] = GLFW_KEY_PAGE_UP; + io.KeyMap[ImGuiKey_PageDown] = GLFW_KEY_PAGE_DOWN; + io.KeyMap[ImGuiKey_Home] = GLFW_KEY_HOME; + io.KeyMap[ImGuiKey_End] = GLFW_KEY_END; + io.KeyMap[ImGuiKey_Delete] = GLFW_KEY_DELETE; + io.KeyMap[ImGuiKey_Backspace] = GLFW_KEY_BACKSPACE; + io.KeyMap[ImGuiKey_Enter] = GLFW_KEY_ENTER; + io.KeyMap[ImGuiKey_Escape] = GLFW_KEY_ESCAPE; + io.KeyMap[ImGuiKey_A] = GLFW_KEY_A; + io.KeyMap[ImGuiKey_C] = GLFW_KEY_C; + io.KeyMap[ImGuiKey_V] = GLFW_KEY_V; + io.KeyMap[ImGuiKey_X] = GLFW_KEY_X; + io.KeyMap[ImGuiKey_Y] = GLFW_KEY_Y; + io.KeyMap[ImGuiKey_Z] = GLFW_KEY_Z; + + io.RenderDrawListsFn = ImGui_ImplGlfw_RenderDrawLists; // Alternatively you can set this to NULL and call ImGui::GetDrawData() after ImGui::Render() to get the same ImDrawData pointer. + io.SetClipboardTextFn = ImGui_ImplGlfw_SetClipboardText; + io.GetClipboardTextFn = ImGui_ImplGlfw_GetClipboardText; +#ifdef _WIN32 + io.ImeWindowHandle = glfwGetWin32Window(g_Window); +#endif + + if (install_callbacks) + { + glfwSetMouseButtonCallback(window, ImGui_ImplGlfw_MouseButtonCallback); + glfwSetScrollCallback(window, ImGui_ImplGlfw_ScrollCallback); + glfwSetKeyCallback(window, ImGui_ImplGlFw_KeyCallback); + glfwSetCharCallback(window, ImGui_ImplGlfw_CharCallback); + } + + return true; +} + +void ImGui_ImplGlfw_Shutdown() +{ + ImGui_ImplGlfw_InvalidateDeviceObjects(); + ImGui::Shutdown(); +} + +void ImGui_ImplGlfw_NewFrame() +{ + if (!g_FontTexture) + ImGui_ImplGlfw_CreateDeviceObjects(); + + ImGuiIO& io = ImGui::GetIO(); + + // Setup display size (every frame to accommodate for window resizing) + int w, h; + int display_w, display_h; + glfwGetWindowSize(g_Window, &w, &h); + glfwGetFramebufferSize(g_Window, &display_w, &display_h); + io.DisplaySize = ImVec2((float)w, (float)h); + io.DisplayFramebufferScale = ImVec2(w > 0 ? ((float)display_w / w) : 0, h > 0 ? ((float)display_h / h) : 0); + + // Setup time step + double current_time = glfwGetTime(); + io.DeltaTime = g_Time > 0.0 ? (float)(current_time - g_Time) : (float)(1.0f/60.0f); + g_Time = current_time; + + // Setup inputs + // (we already got mouse wheel, keyboard keys & characters from glfw callbacks polled in glfwPollEvents()) + if (glfwGetWindowAttrib(g_Window, GLFW_FOCUSED)) + { + double mouse_x, mouse_y; + glfwGetCursorPos(g_Window, &mouse_x, &mouse_y); + io.MousePos = ImVec2((float)mouse_x, (float)mouse_y); // Mouse position in screen coordinates (set to -1,-1 if no mouse / on another screen, etc.) + } + else + { + io.MousePos = ImVec2(-1,-1); + } + + for (int i = 0; i < 3; i++) + { + io.MouseDown[i] = g_MousePressed[i] || glfwGetMouseButton(g_Window, i) != 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. + g_MousePressed[i] = false; + } + + io.MouseWheel = g_MouseWheel; + g_MouseWheel = 0.0f; + + // Hide OS mouse cursor if ImGui is drawing it + glfwSetInputMode(g_Window, GLFW_CURSOR, io.MouseDrawCursor ? GLFW_CURSOR_HIDDEN : GLFW_CURSOR_NORMAL); + + // Start the frame + ImGui::NewFrame(); +} diff --git a/examples/opengl2_example/imgui_impl_glfw.h b/examples/opengl2_example/imgui_impl_glfw.h new file mode 100644 index 0000000..07dd96f --- /dev/null +++ b/examples/opengl2_example/imgui_impl_glfw.h @@ -0,0 +1,29 @@ +// ImGui GLFW binding with OpenGL +// In this binding, ImTextureID is used to store an OpenGL 'GLuint' texture identifier. Read the FAQ about ImTextureID in imgui.cpp. + +// If your context is GL3/GL3 then prefer using the code in opengl3_example. +// You *might* use this code with a GL3/GL4 context but make sure you disable the programmable pipeline by calling "glUseProgram(0)" before ImGui::Render(). +// We cannot do that from GL2 code because the function doesn't exist. + +// You can copy and use unmodified imgui_impl_* files in your project. See main.cpp for an example of using this. +// If you use this binding you'll need to call 4 functions: ImGui_ImplXXXX_Init(), ImGui_ImplXXXX_NewFrame(), ImGui::Render() and ImGui_ImplXXXX_Shutdown(). +// If you are new to ImGui, see examples/README.txt and documentation at the top of imgui.cpp. +// https://github.com/ocornut/imgui + +struct GLFWwindow; + +IMGUI_API bool ImGui_ImplGlfw_Init(GLFWwindow* window, bool install_callbacks); +IMGUI_API void ImGui_ImplGlfw_Shutdown(); +IMGUI_API void ImGui_ImplGlfw_NewFrame(); + +// Use if you want to reset your rendering device without losing ImGui state. +IMGUI_API void ImGui_ImplGlfw_InvalidateDeviceObjects(); +IMGUI_API bool ImGui_ImplGlfw_CreateDeviceObjects(); + +// GLFW callbacks (installed by default if you enable 'install_callbacks' during initialization) +// Provided here if you want to chain callbacks. +// You can also handle inputs yourself and use those as a reference. +IMGUI_API void ImGui_ImplGlfw_MouseButtonCallback(GLFWwindow* window, int button, int action, int mods); +IMGUI_API void ImGui_ImplGlfw_ScrollCallback(GLFWwindow* window, double xoffset, double yoffset); +IMGUI_API void ImGui_ImplGlFw_KeyCallback(GLFWwindow* window, int key, int scancode, int action, int mods); +IMGUI_API void ImGui_ImplGlfw_CharCallback(GLFWwindow* window, unsigned int c); diff --git a/examples/opengl2_example/main.cpp b/examples/opengl2_example/main.cpp new file mode 100644 index 0000000..a844db5 --- /dev/null +++ b/examples/opengl2_example/main.cpp @@ -0,0 +1,89 @@ +// ImGui - standalone example application for Glfw + OpenGL 2, using fixed pipeline +// If you are new to ImGui, see examples/README.txt and documentation at the top of imgui.cpp. + +#include +#include "imgui_impl_glfw.h" +#include +#include + +static void error_callback(int error, const char* description) +{ + fprintf(stderr, "Error %d: %s\n", error, description); +} + +int main(int, char**) +{ + // Setup window + glfwSetErrorCallback(error_callback); + if (!glfwInit()) + return 1; + GLFWwindow* window = glfwCreateWindow(1280, 720, "ImGui OpenGL2 example", NULL, NULL); + glfwMakeContextCurrent(window); + + // Setup ImGui binding + ImGui_ImplGlfw_Init(window, true); + + // Load Fonts + // (there is a default font, this is only if you want to change it. see extra_fonts/README.txt for more details) + //ImGuiIO& io = ImGui::GetIO(); + //io.Fonts->AddFontDefault(); + //io.Fonts->AddFontFromFileTTF("../../extra_fonts/Cousine-Regular.ttf", 15.0f); + //io.Fonts->AddFontFromFileTTF("../../extra_fonts/DroidSans.ttf", 16.0f); + //io.Fonts->AddFontFromFileTTF("../../extra_fonts/ProggyClean.ttf", 13.0f); + //io.Fonts->AddFontFromFileTTF("../../extra_fonts/ProggyTiny.ttf", 10.0f); + //io.Fonts->AddFontFromFileTTF("c:\\Windows\\Fonts\\ArialUni.ttf", 18.0f, NULL, io.Fonts->GetGlyphRangesJapanese()); + + bool show_test_window = true; + bool show_another_window = false; + ImVec4 clear_color = ImColor(114, 144, 154); + + // Main loop + while (!glfwWindowShouldClose(window)) + { + glfwPollEvents(); + ImGui_ImplGlfw_NewFrame(); + + // 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 = 0.0f; + ImGui::Text("Hello, world!"); + ImGui::SliderFloat("float", &f, 0.0f, 1.0f); + ImGui::ColorEdit3("clear color", (float*)&clear_color); + if (ImGui::Button("Test Window")) show_test_window ^= 1; + if (ImGui::Button("Another Window")) show_another_window ^= 1; + ImGui::Text("Application average %.3f ms/frame (%.1f FPS)", 1000.0f / ImGui::GetIO().Framerate, ImGui::GetIO().Framerate); + } + + // 2. Show another simple window, this time using an explicit Begin/End pair + if (show_another_window) + { + ImGui::SetNextWindowSize(ImVec2(200,100), ImGuiSetCond_FirstUseEver); + ImGui::Begin("Another Window", &show_another_window); + 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::SetNextWindowPos(ImVec2(650, 20), ImGuiSetCond_FirstUseEver); + ImGui::ShowTestWindow(&show_test_window); + } + + // Rendering + int display_w, display_h; + glfwGetFramebufferSize(window, &display_w, &display_h); + glViewport(0, 0, display_w, display_h); + glClearColor(clear_color.x, clear_color.y, clear_color.z, clear_color.w); + glClear(GL_COLOR_BUFFER_BIT); + ImGui::Render(); + glfwSwapBuffers(window); + } + + // Cleanup + ImGui_ImplGlfw_Shutdown(); + glfwTerminate(); + + return 0; +} diff --git a/examples/opengl2_example/opengl_example.vcxproj b/examples/opengl2_example/opengl_example.vcxproj new file mode 100644 index 0000000..4b354b6 --- /dev/null +++ b/examples/opengl2_example/opengl_example.vcxproj @@ -0,0 +1,169 @@ + + + + + Debug + Win32 + + + Debug + x64 + + + Release + Win32 + + + Release + x64 + + + + {9CDA7840-B7A5-496D-A527-E95571496D18} + opengl_example + + + + Application + true + MultiByte + + + Application + true + MultiByte + + + Application + false + true + MultiByte + + + Application + false + true + MultiByte + + + + + + + + + + + + + + + + + + + $(ProjectDir)$(Configuration)\ + $(ProjectDir)$(Configuration)\ + $(IncludePath) + + + $(ProjectDir)$(Configuration)\ + $(ProjectDir)$(Configuration)\ + $(IncludePath) + + + $(ProjectDir)$(Configuration)\ + $(ProjectDir)$(Configuration)\ + $(IncludePath) + + + $(ProjectDir)$(Configuration)\ + $(ProjectDir)$(Configuration)\ + $(IncludePath) + + + + Level4 + Disabled + $(SolutionDir)\libs\glfw\include;..\..;%(AdditionalIncludeDirectories) + + + true + $(SolutionDir)\libs\glfw\lib-vc2010-32;%(AdditionalLibraryDirectories) + opengl32.lib;glfw3.lib;%(AdditionalDependencies) + Console + msvcrt.lib + + + + + Level4 + Disabled + $(SolutionDir)\libs\glfw\include;..\..;%(AdditionalIncludeDirectories) + + + true + $(SolutionDir)\libs\glfw\lib-vc2010-64;%(AdditionalLibraryDirectories) + opengl32.lib;glfw3.lib;%(AdditionalDependencies) + Console + msvcrt.lib + + + + + Level4 + MaxSpeed + true + true + $(SolutionDir)\libs\glfw\include;..\..;%(AdditionalIncludeDirectories) + + + true + true + true + $(SolutionDir)\libs\glfw\lib-vc2010-32;%(AdditionalLibraryDirectories) + opengl32.lib;glfw3.lib;%(AdditionalDependencies) + Console + + + + + + + Level4 + MaxSpeed + true + true + $(SolutionDir)\libs\glfw\include;..\..;%(AdditionalIncludeDirectories) + + + true + true + true + $(SolutionDir)\libs\glfw\lib-vc2010-64;%(AdditionalLibraryDirectories) + opengl32.lib;glfw3.lib;%(AdditionalDependencies) + Console + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/examples/opengl2_example/opengl_example.vcxproj.filters b/examples/opengl2_example/opengl_example.vcxproj.filters new file mode 100644 index 0000000..f2282bf --- /dev/null +++ b/examples/opengl2_example/opengl_example.vcxproj.filters @@ -0,0 +1,46 @@ + + + + + {c336cfe3-f0c4-464c-9ef0-a9e17a7ff222} + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx + + + + + sources + + + imgui + + + sources + + + imgui + + + imgui + + + + + imgui + + + imgui + + + sources + + + imgui + + + + + + \ No newline at end of file diff --git a/examples/opengl_example/Makefile b/examples/opengl_example/Makefile deleted file mode 100644 index 91d1b14..0000000 --- a/examples/opengl_example/Makefile +++ /dev/null @@ -1,60 +0,0 @@ -# -# Cross Platform Makefile -# Compatible with Ubuntu 14.04.1 and Mac OS X -# -# -# if you using Mac OS X: -# You'll need glfw -# http://www.glfw.org -# - -#CXX = g++ - -EXE = opengl_example -OBJS = main.o imgui_impl_glfw.o -OBJS += ../../imgui.o ../../imgui_demo.o ../../imgui_draw.o - -UNAME_S := $(shell uname -s) - - -ifeq ($(UNAME_S), Linux) #LINUX - ECHO_MESSAGE = "Linux" - LIBS = -lGL `pkg-config --static --libs glfw3` - - CXXFLAGS = -I../../ `pkg-config --cflags glfw3` - CXXFLAGS += -Wall -Wformat - CFLAGS = $(CXXFLAGS) -endif - -ifeq ($(UNAME_S), Darwin) #APPLE - ECHO_MESSAGE = "Mac OS X" - LIBS = -framework OpenGL -framework Cocoa -framework IOKit -framework CoreVideo - LIBS += -L/usr/local/lib -lglfw3 - - CXXFLAGS = -I../../ -I/usr/local/include - CXXFLAGS += -Wall -Wformat -# CXXFLAGS += -D__APPLE__ - CFLAGS = $(CXXFLAGS) -endif - -ifeq ($(UNAME_S), MINGW64_NT-6.3) - ECHO_MESSAGE = "Windows" - LIBS = -lglfw3 -lgdi32 -lopengl32 -limm32 - - CXXFLAGS = -I../../ -I../libs/gl3w `pkg-config --cflags glfw3` - CXXFLAGS += -Wall -Wformat - CFLAGS = $(CXXFLAGS) -endif - -.cpp.o: - $(CXX) $(CXXFLAGS) -c -o $@ $< - -all: $(EXE) - @echo Build complete for $(ECHO_MESSAGE) - -$(EXE): $(OBJS) - $(CXX) -o $(EXE) $(OBJS) $(CXXFLAGS) $(LIBS) - -clean: - rm $(EXE) $(OBJS) - diff --git a/examples/opengl_example/build_win32.bat b/examples/opengl_example/build_win32.bat deleted file mode 100644 index 278381c..0000000 --- a/examples/opengl_example/build_win32.bat +++ /dev/null @@ -1,3 +0,0 @@ -@REM Build for Visual Studio compiler. Run your copy of vcvars32.bat or vcvarsall.bat to setup command-line compiler. -mkdir Debug -cl /nologo /Zi /MD /I ..\.. /I ..\libs\glfw\include *.cpp ..\..\*.cpp /FeDebug/opengl_example.exe /FoDebug/ /link /LIBPATH:..\libs\glfw\lib-vc2010-32 glfw3.lib opengl32.lib gdi32.lib shell32.lib diff --git a/examples/opengl_example/imgui_impl_glfw.cpp b/examples/opengl_example/imgui_impl_glfw.cpp deleted file mode 100644 index 2d1f5c1..0000000 --- a/examples/opengl_example/imgui_impl_glfw.cpp +++ /dev/null @@ -1,288 +0,0 @@ -// ImGui GLFW binding with OpenGL -// In this binding, ImTextureID is used to store an OpenGL 'GLuint' texture identifier. Read the FAQ about ImTextureID in imgui.cpp. - -// If your context is GL3/GL3 then prefer using the code in opengl3_example. -// You *might* use this code with a GL3/GL4 context but make sure you disable the programmable pipeline by calling "glUseProgram(0)" before ImGui::Render(). -// We cannot do that from GL2 code because the function doesn't exist. - -// You can copy and use unmodified imgui_impl_* files in your project. See main.cpp for an example of using this. -// If you use this binding you'll need to call 4 functions: ImGui_ImplXXXX_Init(), ImGui_ImplXXXX_NewFrame(), ImGui::Render() and ImGui_ImplXXXX_Shutdown(). -// If you are new to ImGui, see examples/README.txt and documentation at the top of imgui.cpp. -// https://github.com/ocornut/imgui - -#include -#include "imgui_impl_glfw.h" - -// GLFW -#include -#ifdef _WIN32 -#undef APIENTRY -#define GLFW_EXPOSE_NATIVE_WIN32 -#define GLFW_EXPOSE_NATIVE_WGL -#include -#endif - -// Data -static GLFWwindow* g_Window = NULL; -static double g_Time = 0.0f; -static bool g_MousePressed[3] = { false, false, false }; -static float g_MouseWheel = 0.0f; -static GLuint g_FontTexture = 0; - -// 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) -void ImGui_ImplGlfw_RenderDrawLists(ImDrawData* draw_data) -{ - // Avoid rendering when minimized, scale coordinates for retina displays (screen coordinates != framebuffer coordinates) - ImGuiIO& io = ImGui::GetIO(); - int fb_width = (int)(io.DisplaySize.x * io.DisplayFramebufferScale.x); - int fb_height = (int)(io.DisplaySize.y * io.DisplayFramebufferScale.y); - if (fb_width == 0 || fb_height == 0) - return; - draw_data->ScaleClipRects(io.DisplayFramebufferScale); - - // We are using the OpenGL fixed pipeline to make the example code simpler to read! - // Setup render state: alpha-blending enabled, no face culling, no depth testing, scissor enabled, vertex/texcoord/color pointers. - GLint last_texture; glGetIntegerv(GL_TEXTURE_BINDING_2D, &last_texture); - GLint last_viewport[4]; glGetIntegerv(GL_VIEWPORT, last_viewport); - glPushAttrib(GL_ENABLE_BIT | GL_COLOR_BUFFER_BIT | GL_TRANSFORM_BIT); - glEnable(GL_BLEND); - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - glDisable(GL_CULL_FACE); - glDisable(GL_DEPTH_TEST); - glEnable(GL_SCISSOR_TEST); - glEnableClientState(GL_VERTEX_ARRAY); - glEnableClientState(GL_TEXTURE_COORD_ARRAY); - glEnableClientState(GL_COLOR_ARRAY); - glEnable(GL_TEXTURE_2D); - //glUseProgram(0); // You may want this if using this code in an OpenGL 3+ context - - // Setup viewport, orthographic projection matrix - glViewport(0, 0, (GLsizei)fb_width, (GLsizei)fb_height); - glMatrixMode(GL_PROJECTION); - glPushMatrix(); - glLoadIdentity(); - glOrtho(0.0f, io.DisplaySize.x, io.DisplaySize.y, 0.0f, -1.0f, +1.0f); - glMatrixMode(GL_MODELVIEW); - glPushMatrix(); - glLoadIdentity(); - - // Render command lists - #define OFFSETOF(TYPE, ELEMENT) ((size_t)&(((TYPE *)0)->ELEMENT)) - for (int n = 0; n < draw_data->CmdListsCount; n++) - { - const ImDrawList* cmd_list = draw_data->CmdLists[n]; - const unsigned char* vtx_buffer = (const unsigned char*)&cmd_list->VtxBuffer.front(); - const ImDrawIdx* idx_buffer = &cmd_list->IdxBuffer.front(); - glVertexPointer(2, GL_FLOAT, sizeof(ImDrawVert), (void*)(vtx_buffer + OFFSETOF(ImDrawVert, pos))); - glTexCoordPointer(2, GL_FLOAT, sizeof(ImDrawVert), (void*)(vtx_buffer + OFFSETOF(ImDrawVert, uv))); - glColorPointer(4, GL_UNSIGNED_BYTE, sizeof(ImDrawVert), (void*)(vtx_buffer + OFFSETOF(ImDrawVert, col))); - - for (int cmd_i = 0; cmd_i < cmd_list->CmdBuffer.size(); cmd_i++) - { - const ImDrawCmd* pcmd = &cmd_list->CmdBuffer[cmd_i]; - if (pcmd->UserCallback) - { - pcmd->UserCallback(cmd_list, pcmd); - } - else - { - glBindTexture(GL_TEXTURE_2D, (GLuint)(intptr_t)pcmd->TextureId); - glScissor((int)pcmd->ClipRect.x, (int)(fb_height - pcmd->ClipRect.w), (int)(pcmd->ClipRect.z - pcmd->ClipRect.x), (int)(pcmd->ClipRect.w - pcmd->ClipRect.y)); - glDrawElements(GL_TRIANGLES, (GLsizei)pcmd->ElemCount, sizeof(ImDrawIdx) == 2 ? GL_UNSIGNED_SHORT : GL_UNSIGNED_INT, idx_buffer); - } - idx_buffer += pcmd->ElemCount; - } - } - #undef OFFSETOF - - // Restore modified state - glDisableClientState(GL_COLOR_ARRAY); - glDisableClientState(GL_TEXTURE_COORD_ARRAY); - glDisableClientState(GL_VERTEX_ARRAY); - glBindTexture(GL_TEXTURE_2D, (GLuint)last_texture); - glMatrixMode(GL_MODELVIEW); - glPopMatrix(); - glMatrixMode(GL_PROJECTION); - glPopMatrix(); - glPopAttrib(); - glViewport(last_viewport[0], last_viewport[1], (GLsizei)last_viewport[2], (GLsizei)last_viewport[3]); -} - -static const char* ImGui_ImplGlfw_GetClipboardText() -{ - return glfwGetClipboardString(g_Window); -} - -static void ImGui_ImplGlfw_SetClipboardText(const char* text) -{ - glfwSetClipboardString(g_Window, text); -} - -void ImGui_ImplGlfw_MouseButtonCallback(GLFWwindow*, int button, int action, int /*mods*/) -{ - if (action == GLFW_PRESS && button >= 0 && button < 3) - g_MousePressed[button] = true; -} - -void ImGui_ImplGlfw_ScrollCallback(GLFWwindow*, double /*xoffset*/, double yoffset) -{ - g_MouseWheel += (float)yoffset; // Use fractional mouse wheel, 1.0 unit 5 lines. -} - -void ImGui_ImplGlFw_KeyCallback(GLFWwindow*, int key, int, int action, int mods) -{ - ImGuiIO& io = ImGui::GetIO(); - if (action == GLFW_PRESS) - io.KeysDown[key] = true; - if (action == GLFW_RELEASE) - io.KeysDown[key] = false; - - (void)mods; // Modifiers are not reliable across systems - io.KeyCtrl = io.KeysDown[GLFW_KEY_LEFT_CONTROL] || io.KeysDown[GLFW_KEY_RIGHT_CONTROL]; - io.KeyShift = io.KeysDown[GLFW_KEY_LEFT_SHIFT] || io.KeysDown[GLFW_KEY_RIGHT_SHIFT]; - io.KeyAlt = io.KeysDown[GLFW_KEY_LEFT_ALT] || io.KeysDown[GLFW_KEY_RIGHT_ALT]; - io.KeySuper = io.KeysDown[GLFW_KEY_LEFT_SUPER] || io.KeysDown[GLFW_KEY_RIGHT_SUPER]; -} - -void ImGui_ImplGlfw_CharCallback(GLFWwindow*, unsigned int c) -{ - ImGuiIO& io = ImGui::GetIO(); - if (c > 0 && c < 0x10000) - io.AddInputCharacter((unsigned short)c); -} - -bool ImGui_ImplGlfw_CreateDeviceObjects() -{ - // Build texture atlas - ImGuiIO& io = ImGui::GetIO(); - unsigned char* pixels; - int width, height; - io.Fonts->GetTexDataAsAlpha8(&pixels, &width, &height); - - // Upload texture to graphics system - GLint last_texture; - glGetIntegerv(GL_TEXTURE_BINDING_2D, &last_texture); - glGenTextures(1, &g_FontTexture); - glBindTexture(GL_TEXTURE_2D, g_FontTexture); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, width, height, 0, GL_ALPHA, GL_UNSIGNED_BYTE, pixels); - - // Store our identifier - io.Fonts->TexID = (void *)(intptr_t)g_FontTexture; - - // Restore state - glBindTexture(GL_TEXTURE_2D, last_texture); - - return true; -} - -void ImGui_ImplGlfw_InvalidateDeviceObjects() -{ - if (g_FontTexture) - { - glDeleteTextures(1, &g_FontTexture); - ImGui::GetIO().Fonts->TexID = 0; - g_FontTexture = 0; - } -} - -bool ImGui_ImplGlfw_Init(GLFWwindow* window, bool install_callbacks) -{ - g_Window = window; - - ImGuiIO& io = ImGui::GetIO(); - 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; - io.KeyMap[ImGuiKey_DownArrow] = GLFW_KEY_DOWN; - io.KeyMap[ImGuiKey_PageUp] = GLFW_KEY_PAGE_UP; - io.KeyMap[ImGuiKey_PageDown] = GLFW_KEY_PAGE_DOWN; - io.KeyMap[ImGuiKey_Home] = GLFW_KEY_HOME; - io.KeyMap[ImGuiKey_End] = GLFW_KEY_END; - io.KeyMap[ImGuiKey_Delete] = GLFW_KEY_DELETE; - io.KeyMap[ImGuiKey_Backspace] = GLFW_KEY_BACKSPACE; - io.KeyMap[ImGuiKey_Enter] = GLFW_KEY_ENTER; - io.KeyMap[ImGuiKey_Escape] = GLFW_KEY_ESCAPE; - io.KeyMap[ImGuiKey_A] = GLFW_KEY_A; - io.KeyMap[ImGuiKey_C] = GLFW_KEY_C; - io.KeyMap[ImGuiKey_V] = GLFW_KEY_V; - io.KeyMap[ImGuiKey_X] = GLFW_KEY_X; - io.KeyMap[ImGuiKey_Y] = GLFW_KEY_Y; - io.KeyMap[ImGuiKey_Z] = GLFW_KEY_Z; - - io.RenderDrawListsFn = ImGui_ImplGlfw_RenderDrawLists; // Alternatively you can set this to NULL and call ImGui::GetDrawData() after ImGui::Render() to get the same ImDrawData pointer. - io.SetClipboardTextFn = ImGui_ImplGlfw_SetClipboardText; - io.GetClipboardTextFn = ImGui_ImplGlfw_GetClipboardText; -#ifdef _WIN32 - io.ImeWindowHandle = glfwGetWin32Window(g_Window); -#endif - - if (install_callbacks) - { - glfwSetMouseButtonCallback(window, ImGui_ImplGlfw_MouseButtonCallback); - glfwSetScrollCallback(window, ImGui_ImplGlfw_ScrollCallback); - glfwSetKeyCallback(window, ImGui_ImplGlFw_KeyCallback); - glfwSetCharCallback(window, ImGui_ImplGlfw_CharCallback); - } - - return true; -} - -void ImGui_ImplGlfw_Shutdown() -{ - ImGui_ImplGlfw_InvalidateDeviceObjects(); - ImGui::Shutdown(); -} - -void ImGui_ImplGlfw_NewFrame() -{ - if (!g_FontTexture) - ImGui_ImplGlfw_CreateDeviceObjects(); - - ImGuiIO& io = ImGui::GetIO(); - - // Setup display size (every frame to accommodate for window resizing) - int w, h; - int display_w, display_h; - glfwGetWindowSize(g_Window, &w, &h); - glfwGetFramebufferSize(g_Window, &display_w, &display_h); - io.DisplaySize = ImVec2((float)w, (float)h); - io.DisplayFramebufferScale = ImVec2(w > 0 ? ((float)display_w / w) : 0, h > 0 ? ((float)display_h / h) : 0); - - // Setup time step - double current_time = glfwGetTime(); - io.DeltaTime = g_Time > 0.0 ? (float)(current_time - g_Time) : (float)(1.0f/60.0f); - g_Time = current_time; - - // Setup inputs - // (we already got mouse wheel, keyboard keys & characters from glfw callbacks polled in glfwPollEvents()) - if (glfwGetWindowAttrib(g_Window, GLFW_FOCUSED)) - { - double mouse_x, mouse_y; - glfwGetCursorPos(g_Window, &mouse_x, &mouse_y); - io.MousePos = ImVec2((float)mouse_x, (float)mouse_y); // Mouse position in screen coordinates (set to -1,-1 if no mouse / on another screen, etc.) - } - else - { - io.MousePos = ImVec2(-1,-1); - } - - for (int i = 0; i < 3; i++) - { - io.MouseDown[i] = g_MousePressed[i] || glfwGetMouseButton(g_Window, i) != 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. - g_MousePressed[i] = false; - } - - io.MouseWheel = g_MouseWheel; - g_MouseWheel = 0.0f; - - // Hide OS mouse cursor if ImGui is drawing it - glfwSetInputMode(g_Window, GLFW_CURSOR, io.MouseDrawCursor ? GLFW_CURSOR_HIDDEN : GLFW_CURSOR_NORMAL); - - // Start the frame - ImGui::NewFrame(); -} diff --git a/examples/opengl_example/imgui_impl_glfw.h b/examples/opengl_example/imgui_impl_glfw.h deleted file mode 100644 index 07dd96f..0000000 --- a/examples/opengl_example/imgui_impl_glfw.h +++ /dev/null @@ -1,29 +0,0 @@ -// ImGui GLFW binding with OpenGL -// In this binding, ImTextureID is used to store an OpenGL 'GLuint' texture identifier. Read the FAQ about ImTextureID in imgui.cpp. - -// If your context is GL3/GL3 then prefer using the code in opengl3_example. -// You *might* use this code with a GL3/GL4 context but make sure you disable the programmable pipeline by calling "glUseProgram(0)" before ImGui::Render(). -// We cannot do that from GL2 code because the function doesn't exist. - -// You can copy and use unmodified imgui_impl_* files in your project. See main.cpp for an example of using this. -// If you use this binding you'll need to call 4 functions: ImGui_ImplXXXX_Init(), ImGui_ImplXXXX_NewFrame(), ImGui::Render() and ImGui_ImplXXXX_Shutdown(). -// If you are new to ImGui, see examples/README.txt and documentation at the top of imgui.cpp. -// https://github.com/ocornut/imgui - -struct GLFWwindow; - -IMGUI_API bool ImGui_ImplGlfw_Init(GLFWwindow* window, bool install_callbacks); -IMGUI_API void ImGui_ImplGlfw_Shutdown(); -IMGUI_API void ImGui_ImplGlfw_NewFrame(); - -// Use if you want to reset your rendering device without losing ImGui state. -IMGUI_API void ImGui_ImplGlfw_InvalidateDeviceObjects(); -IMGUI_API bool ImGui_ImplGlfw_CreateDeviceObjects(); - -// GLFW callbacks (installed by default if you enable 'install_callbacks' during initialization) -// Provided here if you want to chain callbacks. -// You can also handle inputs yourself and use those as a reference. -IMGUI_API void ImGui_ImplGlfw_MouseButtonCallback(GLFWwindow* window, int button, int action, int mods); -IMGUI_API void ImGui_ImplGlfw_ScrollCallback(GLFWwindow* window, double xoffset, double yoffset); -IMGUI_API void ImGui_ImplGlFw_KeyCallback(GLFWwindow* window, int key, int scancode, int action, int mods); -IMGUI_API void ImGui_ImplGlfw_CharCallback(GLFWwindow* window, unsigned int c); diff --git a/examples/opengl_example/main.cpp b/examples/opengl_example/main.cpp deleted file mode 100644 index a844db5..0000000 --- a/examples/opengl_example/main.cpp +++ /dev/null @@ -1,89 +0,0 @@ -// ImGui - standalone example application for Glfw + OpenGL 2, using fixed pipeline -// If you are new to ImGui, see examples/README.txt and documentation at the top of imgui.cpp. - -#include -#include "imgui_impl_glfw.h" -#include -#include - -static void error_callback(int error, const char* description) -{ - fprintf(stderr, "Error %d: %s\n", error, description); -} - -int main(int, char**) -{ - // Setup window - glfwSetErrorCallback(error_callback); - if (!glfwInit()) - return 1; - GLFWwindow* window = glfwCreateWindow(1280, 720, "ImGui OpenGL2 example", NULL, NULL); - glfwMakeContextCurrent(window); - - // Setup ImGui binding - ImGui_ImplGlfw_Init(window, true); - - // Load Fonts - // (there is a default font, this is only if you want to change it. see extra_fonts/README.txt for more details) - //ImGuiIO& io = ImGui::GetIO(); - //io.Fonts->AddFontDefault(); - //io.Fonts->AddFontFromFileTTF("../../extra_fonts/Cousine-Regular.ttf", 15.0f); - //io.Fonts->AddFontFromFileTTF("../../extra_fonts/DroidSans.ttf", 16.0f); - //io.Fonts->AddFontFromFileTTF("../../extra_fonts/ProggyClean.ttf", 13.0f); - //io.Fonts->AddFontFromFileTTF("../../extra_fonts/ProggyTiny.ttf", 10.0f); - //io.Fonts->AddFontFromFileTTF("c:\\Windows\\Fonts\\ArialUni.ttf", 18.0f, NULL, io.Fonts->GetGlyphRangesJapanese()); - - bool show_test_window = true; - bool show_another_window = false; - ImVec4 clear_color = ImColor(114, 144, 154); - - // Main loop - while (!glfwWindowShouldClose(window)) - { - glfwPollEvents(); - ImGui_ImplGlfw_NewFrame(); - - // 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 = 0.0f; - ImGui::Text("Hello, world!"); - ImGui::SliderFloat("float", &f, 0.0f, 1.0f); - ImGui::ColorEdit3("clear color", (float*)&clear_color); - if (ImGui::Button("Test Window")) show_test_window ^= 1; - if (ImGui::Button("Another Window")) show_another_window ^= 1; - ImGui::Text("Application average %.3f ms/frame (%.1f FPS)", 1000.0f / ImGui::GetIO().Framerate, ImGui::GetIO().Framerate); - } - - // 2. Show another simple window, this time using an explicit Begin/End pair - if (show_another_window) - { - ImGui::SetNextWindowSize(ImVec2(200,100), ImGuiSetCond_FirstUseEver); - ImGui::Begin("Another Window", &show_another_window); - 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::SetNextWindowPos(ImVec2(650, 20), ImGuiSetCond_FirstUseEver); - ImGui::ShowTestWindow(&show_test_window); - } - - // Rendering - int display_w, display_h; - glfwGetFramebufferSize(window, &display_w, &display_h); - glViewport(0, 0, display_w, display_h); - glClearColor(clear_color.x, clear_color.y, clear_color.z, clear_color.w); - glClear(GL_COLOR_BUFFER_BIT); - ImGui::Render(); - glfwSwapBuffers(window); - } - - // Cleanup - ImGui_ImplGlfw_Shutdown(); - glfwTerminate(); - - return 0; -} diff --git a/examples/opengl_example/opengl_example.vcxproj b/examples/opengl_example/opengl_example.vcxproj deleted file mode 100644 index 4b354b6..0000000 --- a/examples/opengl_example/opengl_example.vcxproj +++ /dev/null @@ -1,169 +0,0 @@ - - - - - Debug - Win32 - - - Debug - x64 - - - Release - Win32 - - - Release - x64 - - - - {9CDA7840-B7A5-496D-A527-E95571496D18} - opengl_example - - - - Application - true - MultiByte - - - Application - true - MultiByte - - - Application - false - true - MultiByte - - - Application - false - true - MultiByte - - - - - - - - - - - - - - - - - - - $(ProjectDir)$(Configuration)\ - $(ProjectDir)$(Configuration)\ - $(IncludePath) - - - $(ProjectDir)$(Configuration)\ - $(ProjectDir)$(Configuration)\ - $(IncludePath) - - - $(ProjectDir)$(Configuration)\ - $(ProjectDir)$(Configuration)\ - $(IncludePath) - - - $(ProjectDir)$(Configuration)\ - $(ProjectDir)$(Configuration)\ - $(IncludePath) - - - - Level4 - Disabled - $(SolutionDir)\libs\glfw\include;..\..;%(AdditionalIncludeDirectories) - - - true - $(SolutionDir)\libs\glfw\lib-vc2010-32;%(AdditionalLibraryDirectories) - opengl32.lib;glfw3.lib;%(AdditionalDependencies) - Console - msvcrt.lib - - - - - Level4 - Disabled - $(SolutionDir)\libs\glfw\include;..\..;%(AdditionalIncludeDirectories) - - - true - $(SolutionDir)\libs\glfw\lib-vc2010-64;%(AdditionalLibraryDirectories) - opengl32.lib;glfw3.lib;%(AdditionalDependencies) - Console - msvcrt.lib - - - - - Level4 - MaxSpeed - true - true - $(SolutionDir)\libs\glfw\include;..\..;%(AdditionalIncludeDirectories) - - - true - true - true - $(SolutionDir)\libs\glfw\lib-vc2010-32;%(AdditionalLibraryDirectories) - opengl32.lib;glfw3.lib;%(AdditionalDependencies) - Console - - - - - - - Level4 - MaxSpeed - true - true - $(SolutionDir)\libs\glfw\include;..\..;%(AdditionalIncludeDirectories) - - - true - true - true - $(SolutionDir)\libs\glfw\lib-vc2010-64;%(AdditionalLibraryDirectories) - opengl32.lib;glfw3.lib;%(AdditionalDependencies) - Console - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/examples/opengl_example/opengl_example.vcxproj.filters b/examples/opengl_example/opengl_example.vcxproj.filters deleted file mode 100644 index f2282bf..0000000 --- a/examples/opengl_example/opengl_example.vcxproj.filters +++ /dev/null @@ -1,46 +0,0 @@ - - - - - {c336cfe3-f0c4-464c-9ef0-a9e17a7ff222} - - - {4FC737F1-C7A5-4376-A066-2A32D752A2FF} - cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx - - - - - sources - - - imgui - - - sources - - - imgui - - - imgui - - - - - imgui - - - imgui - - - sources - - - imgui - - - - - - \ No newline at end of file diff --git a/examples/sdl_opengl2_example/README.md b/examples/sdl_opengl2_example/README.md new file mode 100644 index 0000000..aada45d --- /dev/null +++ b/examples/sdl_opengl2_example/README.md @@ -0,0 +1,22 @@ + +# How to Build + +- On Windows with Visual Studio's CLI + +``` +set SDL2DIR=path_to_your_sdl2_folder +cl /Zi /MD /I %SDL2DIR%\include> /I ..\.. main.cpp imgui_impl_sdl.cpp ..\..\imgui*.cpp /link /LIBPATH:%SDL2DIR%\lib SDL2.lib SDL2main.lib +``` + +- On Linux and similar Unixes + +``` +c++ `sdl2-config --cflags` -I ../.. main.cpp imgui_impl_sdl.cpp ../../imgui*.cpp `sdl2-config --libs` -lGL -o sdl2example +``` + +- On Mac OS X + +``` +brew install sdl2 +c++ `sdl2-config --cflags` -I ../.. main.cpp imgui_impl_sdl.cpp ../../imgui*.cpp `sdl2-config --libs` -framework OpenGl -o sdl2example +``` diff --git a/examples/sdl_opengl2_example/imgui_impl_sdl.cpp b/examples/sdl_opengl2_example/imgui_impl_sdl.cpp new file mode 100644 index 0000000..63ed9f4 --- /dev/null +++ b/examples/sdl_opengl2_example/imgui_impl_sdl.cpp @@ -0,0 +1,277 @@ +// ImGui SDL2 binding with OpenGL +// In this binding, ImTextureID is used to store an OpenGL 'GLuint' texture identifier. Read the FAQ about ImTextureID in imgui.cpp. + +// You can copy and use unmodified imgui_impl_* files in your project. See main.cpp for an example of using this. +// If you use this binding you'll need to call 4 functions: ImGui_ImplXXXX_Init(), ImGui_ImplXXXX_NewFrame(), ImGui::Render() and ImGui_ImplXXXX_Shutdown(). +// If you are new to ImGui, see examples/README.txt and documentation at the top of imgui.cpp. +// https://github.com/ocornut/imgui + +#include +#include +#include +#include +#include "imgui_impl_sdl.h" + +// Data +static double g_Time = 0.0f; +static bool g_MousePressed[3] = { false, false, false }; +static float g_MouseWheel = 0.0f; +static GLuint g_FontTexture = 0; + +// 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) +void ImGui_ImplSdl_RenderDrawLists(ImDrawData* draw_data) +{ + // Avoid rendering when minimized, scale coordinates for retina displays (screen coordinates != framebuffer coordinates) + ImGuiIO& io = ImGui::GetIO(); + int fb_width = (int)(io.DisplaySize.x * io.DisplayFramebufferScale.x); + int fb_height = (int)(io.DisplaySize.y * io.DisplayFramebufferScale.y); + if (fb_width == 0 || fb_height == 0) + return; + draw_data->ScaleClipRects(io.DisplayFramebufferScale); + + // We are using the OpenGL fixed pipeline to make the example code simpler to read! + // Setup render state: alpha-blending enabled, no face culling, no depth testing, scissor enabled, vertex/texcoord/color pointers. + GLint last_texture; glGetIntegerv(GL_TEXTURE_BINDING_2D, &last_texture); + GLint last_viewport[4]; glGetIntegerv(GL_VIEWPORT, last_viewport); + glPushAttrib(GL_ENABLE_BIT | GL_COLOR_BUFFER_BIT | GL_TRANSFORM_BIT); + glEnable(GL_BLEND); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + glDisable(GL_CULL_FACE); + glDisable(GL_DEPTH_TEST); + glEnable(GL_SCISSOR_TEST); + glEnableClientState(GL_VERTEX_ARRAY); + glEnableClientState(GL_TEXTURE_COORD_ARRAY); + glEnableClientState(GL_COLOR_ARRAY); + glEnable(GL_TEXTURE_2D); + //glUseProgram(0); // You may want this if using this code in an OpenGL 3+ context + + // Setup viewport, orthographic projection matrix + glViewport(0, 0, (GLsizei)fb_width, (GLsizei)fb_height); + glMatrixMode(GL_PROJECTION); + glPushMatrix(); + glLoadIdentity(); + glOrtho(0.0f, io.DisplaySize.x, io.DisplaySize.y, 0.0f, -1.0f, +1.0f); + glMatrixMode(GL_MODELVIEW); + glPushMatrix(); + glLoadIdentity(); + + // Render command lists + #define OFFSETOF(TYPE, ELEMENT) ((size_t)&(((TYPE *)0)->ELEMENT)) + for (int n = 0; n < draw_data->CmdListsCount; n++) + { + const ImDrawList* cmd_list = draw_data->CmdLists[n]; + const unsigned char* vtx_buffer = (const unsigned char*)&cmd_list->VtxBuffer.front(); + const ImDrawIdx* idx_buffer = &cmd_list->IdxBuffer.front(); + glVertexPointer(2, GL_FLOAT, sizeof(ImDrawVert), (void*)(vtx_buffer + OFFSETOF(ImDrawVert, pos))); + glTexCoordPointer(2, GL_FLOAT, sizeof(ImDrawVert), (void*)(vtx_buffer + OFFSETOF(ImDrawVert, uv))); + glColorPointer(4, GL_UNSIGNED_BYTE, sizeof(ImDrawVert), (void*)(vtx_buffer + OFFSETOF(ImDrawVert, col))); + + for (int cmd_i = 0; cmd_i < cmd_list->CmdBuffer.size(); cmd_i++) + { + const ImDrawCmd* pcmd = &cmd_list->CmdBuffer[cmd_i]; + if (pcmd->UserCallback) + { + pcmd->UserCallback(cmd_list, pcmd); + } + else + { + glBindTexture(GL_TEXTURE_2D, (GLuint)(intptr_t)pcmd->TextureId); + glScissor((int)pcmd->ClipRect.x, (int)(fb_height - pcmd->ClipRect.w), (int)(pcmd->ClipRect.z - pcmd->ClipRect.x), (int)(pcmd->ClipRect.w - pcmd->ClipRect.y)); + glDrawElements(GL_TRIANGLES, (GLsizei)pcmd->ElemCount, sizeof(ImDrawIdx) == 2 ? GL_UNSIGNED_SHORT : GL_UNSIGNED_INT, idx_buffer); + } + idx_buffer += pcmd->ElemCount; + } + } + #undef OFFSETOF + + // Restore modified state + glDisableClientState(GL_COLOR_ARRAY); + glDisableClientState(GL_TEXTURE_COORD_ARRAY); + glDisableClientState(GL_VERTEX_ARRAY); + glBindTexture(GL_TEXTURE_2D, (GLuint)last_texture); + glMatrixMode(GL_MODELVIEW); + glPopMatrix(); + glMatrixMode(GL_PROJECTION); + glPopMatrix(); + glPopAttrib(); + glViewport(last_viewport[0], last_viewport[1], (GLsizei)last_viewport[2], (GLsizei)last_viewport[3]); +} + +static const char* ImGui_ImplSdl_GetClipboardText() +{ + return SDL_GetClipboardText(); +} + +static void ImGui_ImplSdl_SetClipboardText(const char* text) +{ + SDL_SetClipboardText(text); +} + +bool ImGui_ImplSdl_ProcessEvent(SDL_Event* event) +{ + ImGuiIO& io = ImGui::GetIO(); + switch (event->type) + { + case SDL_MOUSEWHEEL: + { + if (event->wheel.y > 0) + g_MouseWheel = 1; + if (event->wheel.y < 0) + g_MouseWheel = -1; + return true; + } + case SDL_MOUSEBUTTONDOWN: + { + if (event->button.button == SDL_BUTTON_LEFT) g_MousePressed[0] = true; + if (event->button.button == SDL_BUTTON_RIGHT) g_MousePressed[1] = true; + if (event->button.button == SDL_BUTTON_MIDDLE) g_MousePressed[2] = true; + return true; + } + case SDL_TEXTINPUT: + { + io.AddInputCharactersUTF8(event->text.text); + return true; + } + case SDL_KEYDOWN: + case SDL_KEYUP: + { + int key = event->key.keysym.sym & ~SDLK_SCANCODE_MASK; + io.KeysDown[key] = (event->type == SDL_KEYDOWN); + io.KeyShift = ((SDL_GetModState() & KMOD_SHIFT) != 0); + io.KeyCtrl = ((SDL_GetModState() & KMOD_CTRL) != 0); + io.KeyAlt = ((SDL_GetModState() & KMOD_ALT) != 0); + io.KeySuper = ((SDL_GetModState() & KMOD_GUI) != 0); + return true; + } + } + return false; +} + +bool ImGui_ImplSdl_CreateDeviceObjects() +{ + // Build texture atlas + ImGuiIO& io = ImGui::GetIO(); + unsigned char* pixels; + int width, height; + io.Fonts->GetTexDataAsAlpha8(&pixels, &width, &height); + + // Upload texture to graphics system + GLint last_texture; + glGetIntegerv(GL_TEXTURE_BINDING_2D, &last_texture); + glGenTextures(1, &g_FontTexture); + glBindTexture(GL_TEXTURE_2D, g_FontTexture); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glPixelStorei(GL_UNPACK_ROW_LENGTH, 0); + glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, width, height, 0, GL_ALPHA, GL_UNSIGNED_BYTE, pixels); + + // Store our identifier + io.Fonts->TexID = (void *)(intptr_t)g_FontTexture; + + // Restore state + glBindTexture(GL_TEXTURE_2D, last_texture); + + return true; +} + +void ImGui_ImplSdl_InvalidateDeviceObjects() +{ + if (g_FontTexture) + { + glDeleteTextures(1, &g_FontTexture); + ImGui::GetIO().Fonts->TexID = 0; + g_FontTexture = 0; + } +} + +bool ImGui_ImplSdl_Init(SDL_Window* window) +{ + ImGuiIO& io = ImGui::GetIO(); + io.KeyMap[ImGuiKey_Tab] = SDLK_TAB; // Keyboard mapping. ImGui will use those indices to peek into the io.KeyDown[] array. + io.KeyMap[ImGuiKey_LeftArrow] = SDL_SCANCODE_LEFT; + io.KeyMap[ImGuiKey_RightArrow] = SDL_SCANCODE_RIGHT; + io.KeyMap[ImGuiKey_UpArrow] = SDL_SCANCODE_UP; + io.KeyMap[ImGuiKey_DownArrow] = SDL_SCANCODE_DOWN; + io.KeyMap[ImGuiKey_PageUp] = SDL_SCANCODE_PAGEUP; + io.KeyMap[ImGuiKey_PageDown] = SDL_SCANCODE_PAGEDOWN; + io.KeyMap[ImGuiKey_Home] = SDL_SCANCODE_HOME; + io.KeyMap[ImGuiKey_End] = SDL_SCANCODE_END; + io.KeyMap[ImGuiKey_Delete] = SDLK_DELETE; + io.KeyMap[ImGuiKey_Backspace] = SDLK_BACKSPACE; + io.KeyMap[ImGuiKey_Enter] = SDLK_RETURN; + io.KeyMap[ImGuiKey_Escape] = SDLK_ESCAPE; + io.KeyMap[ImGuiKey_A] = SDLK_a; + io.KeyMap[ImGuiKey_C] = SDLK_c; + io.KeyMap[ImGuiKey_V] = SDLK_v; + io.KeyMap[ImGuiKey_X] = SDLK_x; + io.KeyMap[ImGuiKey_Y] = SDLK_y; + io.KeyMap[ImGuiKey_Z] = SDLK_z; + + io.RenderDrawListsFn = ImGui_ImplSdl_RenderDrawLists; // Alternatively you can set this to NULL and call ImGui::GetDrawData() after ImGui::Render() to get the same ImDrawData pointer. + io.SetClipboardTextFn = ImGui_ImplSdl_SetClipboardText; + io.GetClipboardTextFn = ImGui_ImplSdl_GetClipboardText; + +#ifdef _WIN32 + SDL_SysWMinfo wmInfo; + SDL_VERSION(&wmInfo.version); + SDL_GetWindowWMInfo(window, &wmInfo); + io.ImeWindowHandle = wmInfo.info.win.window; +#else + (void)window; +#endif + + return true; +} + +void ImGui_ImplSdl_Shutdown() +{ + ImGui_ImplSdl_InvalidateDeviceObjects(); + ImGui::Shutdown(); +} + +void ImGui_ImplSdl_NewFrame(SDL_Window *window) +{ + if (!g_FontTexture) + ImGui_ImplSdl_CreateDeviceObjects(); + + ImGuiIO& io = ImGui::GetIO(); + + // Setup display size (every frame to accommodate for window resizing) + int w, h; + int display_w, display_h; + SDL_GetWindowSize(window, &w, &h); + SDL_GL_GetDrawableSize(window, &display_w, &display_h); + io.DisplaySize = ImVec2((float)w, (float)h); + io.DisplayFramebufferScale = ImVec2(w > 0 ? ((float)display_w / w) : 0, h > 0 ? ((float)display_h / h) : 0); + + // Setup time step + Uint32 time = SDL_GetTicks(); + double current_time = time / 1000.0; + io.DeltaTime = g_Time > 0.0 ? (float)(current_time - g_Time) : (float)(1.0f/60.0f); + g_Time = current_time; + + // Setup inputs + // (we already got mouse wheel, keyboard keys & characters from SDL_PollEvent()) + int mx, my; + Uint32 mouseMask = SDL_GetMouseState(&mx, &my); + if (SDL_GetWindowFlags(window) & SDL_WINDOW_MOUSE_FOCUS) + io.MousePos = ImVec2((float)mx, (float)my); // Mouse position, in pixels (set to -1,-1 if no mouse / on another screen, etc.) + else + io.MousePos = ImVec2(-1,-1); + + io.MouseDown[0] = g_MousePressed[0] || (mouseMask & SDL_BUTTON(SDL_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] = g_MousePressed[1] || (mouseMask & SDL_BUTTON(SDL_BUTTON_RIGHT)) != 0; + io.MouseDown[2] = g_MousePressed[2] || (mouseMask & SDL_BUTTON(SDL_BUTTON_MIDDLE)) != 0; + g_MousePressed[0] = g_MousePressed[1] = g_MousePressed[2] = false; + + io.MouseWheel = g_MouseWheel; + g_MouseWheel = 0.0f; + + // Hide OS mouse cursor if ImGui is drawing it + SDL_ShowCursor(io.MouseDrawCursor ? 0 : 1); + + // Start the frame + ImGui::NewFrame(); +} diff --git a/examples/sdl_opengl2_example/imgui_impl_sdl.h b/examples/sdl_opengl2_example/imgui_impl_sdl.h new file mode 100644 index 0000000..a322bf2 --- /dev/null +++ b/examples/sdl_opengl2_example/imgui_impl_sdl.h @@ -0,0 +1,19 @@ +// ImGui SDL2 binding with OpenGL +// In this binding, ImTextureID is used to store an OpenGL 'GLuint' texture identifier. Read the FAQ about ImTextureID in imgui.cpp. + +// You can copy and use unmodified imgui_impl_* files in your project. See main.cpp for an example of using this. +// If you use this binding you'll need to call 4 functions: ImGui_ImplXXXX_Init(), ImGui_ImplXXXX_NewFrame(), ImGui::Render() and ImGui_ImplXXXX_Shutdown(). +// If you are new to ImGui, see examples/README.txt and documentation at the top of imgui.cpp. +// https://github.com/ocornut/imgui + +struct SDL_Window; +typedef union SDL_Event SDL_Event; + +IMGUI_API bool ImGui_ImplSdl_Init(SDL_Window* window); +IMGUI_API void ImGui_ImplSdl_Shutdown(); +IMGUI_API void ImGui_ImplSdl_NewFrame(SDL_Window* window); +IMGUI_API bool ImGui_ImplSdl_ProcessEvent(SDL_Event* event); + +// Use if you want to reset your rendering device without losing ImGui state. +IMGUI_API void ImGui_ImplSdl_InvalidateDeviceObjects(); +IMGUI_API bool ImGui_ImplSdl_CreateDeviceObjects(); diff --git a/examples/sdl_opengl2_example/main.cpp b/examples/sdl_opengl2_example/main.cpp new file mode 100644 index 0000000..f42e7fa --- /dev/null +++ b/examples/sdl_opengl2_example/main.cpp @@ -0,0 +1,103 @@ +// ImGui - standalone example application for SDL2 + OpenGL +// If you are new to ImGui, see examples/README.txt and documentation at the top of imgui.cpp. + +#include +#include "imgui_impl_sdl.h" +#include +#include +#include + +int main(int, char**) +{ + // Setup SDL + if (SDL_Init(SDL_INIT_VIDEO|SDL_INIT_TIMER) != 0) + { + printf("Error: %s\n", SDL_GetError()); + return -1; + } + + // Setup window + SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1); + SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 24); + SDL_GL_SetAttribute(SDL_GL_STENCIL_SIZE, 8); + SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 2); + SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 2); + SDL_DisplayMode current; + SDL_GetCurrentDisplayMode(0, ¤t); + SDL_Window *window = SDL_CreateWindow("ImGui SDL2+OpenGL example", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, 1280, 720, SDL_WINDOW_OPENGL|SDL_WINDOW_RESIZABLE); + SDL_GLContext glcontext = SDL_GL_CreateContext(window); + + // Setup ImGui binding + ImGui_ImplSdl_Init(window); + + // Load Fonts + // (there is a default font, this is only if you want to change it. see extra_fonts/README.txt for more details) + //ImGuiIO& io = ImGui::GetIO(); + //io.Fonts->AddFontDefault(); + //io.Fonts->AddFontFromFileTTF("../../extra_fonts/Cousine-Regular.ttf", 15.0f); + //io.Fonts->AddFontFromFileTTF("../../extra_fonts/DroidSans.ttf", 16.0f); + //io.Fonts->AddFontFromFileTTF("../../extra_fonts/ProggyClean.ttf", 13.0f); + //io.Fonts->AddFontFromFileTTF("../../extra_fonts/ProggyTiny.ttf", 10.0f); + //io.Fonts->AddFontFromFileTTF("c:\\Windows\\Fonts\\ArialUni.ttf", 18.0f, NULL, io.Fonts->GetGlyphRangesJapanese()); + + bool show_test_window = true; + bool show_another_window = false; + ImVec4 clear_color = ImColor(114, 144, 154); + + // Main loop + bool done = false; + while (!done) + { + SDL_Event event; + while (SDL_PollEvent(&event)) + { + ImGui_ImplSdl_ProcessEvent(&event); + if (event.type == SDL_QUIT) + done = true; + } + ImGui_ImplSdl_NewFrame(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" + { + static float f = 0.0f; + ImGui::Text("Hello, world!"); + ImGui::SliderFloat("float", &f, 0.0f, 1.0f); + ImGui::ColorEdit3("clear color", (float*)&clear_color); + if (ImGui::Button("Test Window")) show_test_window ^= 1; + if (ImGui::Button("Another Window")) show_another_window ^= 1; + ImGui::Text("Application average %.3f ms/frame (%.1f FPS)", 1000.0f / ImGui::GetIO().Framerate, ImGui::GetIO().Framerate); + } + + // 2. Show another simple window, this time using an explicit Begin/End pair + if (show_another_window) + { + ImGui::SetNextWindowSize(ImVec2(200,100), ImGuiSetCond_FirstUseEver); + ImGui::Begin("Another Window", &show_another_window); + 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::SetNextWindowPos(ImVec2(650, 20), ImGuiSetCond_FirstUseEver); + ImGui::ShowTestWindow(&show_test_window); + } + + // Rendering + glViewport(0, 0, (int)ImGui::GetIO().DisplaySize.x, (int)ImGui::GetIO().DisplaySize.y); + glClearColor(clear_color.x, clear_color.y, clear_color.z, clear_color.w); + glClear(GL_COLOR_BUFFER_BIT); + ImGui::Render(); + SDL_GL_SwapWindow(window); + } + + // Cleanup + ImGui_ImplSdl_Shutdown(); + SDL_GL_DeleteContext(glcontext); + SDL_DestroyWindow(window); + SDL_Quit(); + + return 0; +} diff --git a/examples/sdl_opengl_example/README.md b/examples/sdl_opengl_example/README.md deleted file mode 100644 index aada45d..0000000 --- a/examples/sdl_opengl_example/README.md +++ /dev/null @@ -1,22 +0,0 @@ - -# How to Build - -- On Windows with Visual Studio's CLI - -``` -set SDL2DIR=path_to_your_sdl2_folder -cl /Zi /MD /I %SDL2DIR%\include> /I ..\.. main.cpp imgui_impl_sdl.cpp ..\..\imgui*.cpp /link /LIBPATH:%SDL2DIR%\lib SDL2.lib SDL2main.lib -``` - -- On Linux and similar Unixes - -``` -c++ `sdl2-config --cflags` -I ../.. main.cpp imgui_impl_sdl.cpp ../../imgui*.cpp `sdl2-config --libs` -lGL -o sdl2example -``` - -- On Mac OS X - -``` -brew install sdl2 -c++ `sdl2-config --cflags` -I ../.. main.cpp imgui_impl_sdl.cpp ../../imgui*.cpp `sdl2-config --libs` -framework OpenGl -o sdl2example -``` diff --git a/examples/sdl_opengl_example/imgui_impl_sdl.cpp b/examples/sdl_opengl_example/imgui_impl_sdl.cpp deleted file mode 100644 index 63ed9f4..0000000 --- a/examples/sdl_opengl_example/imgui_impl_sdl.cpp +++ /dev/null @@ -1,277 +0,0 @@ -// ImGui SDL2 binding with OpenGL -// In this binding, ImTextureID is used to store an OpenGL 'GLuint' texture identifier. Read the FAQ about ImTextureID in imgui.cpp. - -// You can copy and use unmodified imgui_impl_* files in your project. See main.cpp for an example of using this. -// If you use this binding you'll need to call 4 functions: ImGui_ImplXXXX_Init(), ImGui_ImplXXXX_NewFrame(), ImGui::Render() and ImGui_ImplXXXX_Shutdown(). -// If you are new to ImGui, see examples/README.txt and documentation at the top of imgui.cpp. -// https://github.com/ocornut/imgui - -#include -#include -#include -#include -#include "imgui_impl_sdl.h" - -// Data -static double g_Time = 0.0f; -static bool g_MousePressed[3] = { false, false, false }; -static float g_MouseWheel = 0.0f; -static GLuint g_FontTexture = 0; - -// 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) -void ImGui_ImplSdl_RenderDrawLists(ImDrawData* draw_data) -{ - // Avoid rendering when minimized, scale coordinates for retina displays (screen coordinates != framebuffer coordinates) - ImGuiIO& io = ImGui::GetIO(); - int fb_width = (int)(io.DisplaySize.x * io.DisplayFramebufferScale.x); - int fb_height = (int)(io.DisplaySize.y * io.DisplayFramebufferScale.y); - if (fb_width == 0 || fb_height == 0) - return; - draw_data->ScaleClipRects(io.DisplayFramebufferScale); - - // We are using the OpenGL fixed pipeline to make the example code simpler to read! - // Setup render state: alpha-blending enabled, no face culling, no depth testing, scissor enabled, vertex/texcoord/color pointers. - GLint last_texture; glGetIntegerv(GL_TEXTURE_BINDING_2D, &last_texture); - GLint last_viewport[4]; glGetIntegerv(GL_VIEWPORT, last_viewport); - glPushAttrib(GL_ENABLE_BIT | GL_COLOR_BUFFER_BIT | GL_TRANSFORM_BIT); - glEnable(GL_BLEND); - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - glDisable(GL_CULL_FACE); - glDisable(GL_DEPTH_TEST); - glEnable(GL_SCISSOR_TEST); - glEnableClientState(GL_VERTEX_ARRAY); - glEnableClientState(GL_TEXTURE_COORD_ARRAY); - glEnableClientState(GL_COLOR_ARRAY); - glEnable(GL_TEXTURE_2D); - //glUseProgram(0); // You may want this if using this code in an OpenGL 3+ context - - // Setup viewport, orthographic projection matrix - glViewport(0, 0, (GLsizei)fb_width, (GLsizei)fb_height); - glMatrixMode(GL_PROJECTION); - glPushMatrix(); - glLoadIdentity(); - glOrtho(0.0f, io.DisplaySize.x, io.DisplaySize.y, 0.0f, -1.0f, +1.0f); - glMatrixMode(GL_MODELVIEW); - glPushMatrix(); - glLoadIdentity(); - - // Render command lists - #define OFFSETOF(TYPE, ELEMENT) ((size_t)&(((TYPE *)0)->ELEMENT)) - for (int n = 0; n < draw_data->CmdListsCount; n++) - { - const ImDrawList* cmd_list = draw_data->CmdLists[n]; - const unsigned char* vtx_buffer = (const unsigned char*)&cmd_list->VtxBuffer.front(); - const ImDrawIdx* idx_buffer = &cmd_list->IdxBuffer.front(); - glVertexPointer(2, GL_FLOAT, sizeof(ImDrawVert), (void*)(vtx_buffer + OFFSETOF(ImDrawVert, pos))); - glTexCoordPointer(2, GL_FLOAT, sizeof(ImDrawVert), (void*)(vtx_buffer + OFFSETOF(ImDrawVert, uv))); - glColorPointer(4, GL_UNSIGNED_BYTE, sizeof(ImDrawVert), (void*)(vtx_buffer + OFFSETOF(ImDrawVert, col))); - - for (int cmd_i = 0; cmd_i < cmd_list->CmdBuffer.size(); cmd_i++) - { - const ImDrawCmd* pcmd = &cmd_list->CmdBuffer[cmd_i]; - if (pcmd->UserCallback) - { - pcmd->UserCallback(cmd_list, pcmd); - } - else - { - glBindTexture(GL_TEXTURE_2D, (GLuint)(intptr_t)pcmd->TextureId); - glScissor((int)pcmd->ClipRect.x, (int)(fb_height - pcmd->ClipRect.w), (int)(pcmd->ClipRect.z - pcmd->ClipRect.x), (int)(pcmd->ClipRect.w - pcmd->ClipRect.y)); - glDrawElements(GL_TRIANGLES, (GLsizei)pcmd->ElemCount, sizeof(ImDrawIdx) == 2 ? GL_UNSIGNED_SHORT : GL_UNSIGNED_INT, idx_buffer); - } - idx_buffer += pcmd->ElemCount; - } - } - #undef OFFSETOF - - // Restore modified state - glDisableClientState(GL_COLOR_ARRAY); - glDisableClientState(GL_TEXTURE_COORD_ARRAY); - glDisableClientState(GL_VERTEX_ARRAY); - glBindTexture(GL_TEXTURE_2D, (GLuint)last_texture); - glMatrixMode(GL_MODELVIEW); - glPopMatrix(); - glMatrixMode(GL_PROJECTION); - glPopMatrix(); - glPopAttrib(); - glViewport(last_viewport[0], last_viewport[1], (GLsizei)last_viewport[2], (GLsizei)last_viewport[3]); -} - -static const char* ImGui_ImplSdl_GetClipboardText() -{ - return SDL_GetClipboardText(); -} - -static void ImGui_ImplSdl_SetClipboardText(const char* text) -{ - SDL_SetClipboardText(text); -} - -bool ImGui_ImplSdl_ProcessEvent(SDL_Event* event) -{ - ImGuiIO& io = ImGui::GetIO(); - switch (event->type) - { - case SDL_MOUSEWHEEL: - { - if (event->wheel.y > 0) - g_MouseWheel = 1; - if (event->wheel.y < 0) - g_MouseWheel = -1; - return true; - } - case SDL_MOUSEBUTTONDOWN: - { - if (event->button.button == SDL_BUTTON_LEFT) g_MousePressed[0] = true; - if (event->button.button == SDL_BUTTON_RIGHT) g_MousePressed[1] = true; - if (event->button.button == SDL_BUTTON_MIDDLE) g_MousePressed[2] = true; - return true; - } - case SDL_TEXTINPUT: - { - io.AddInputCharactersUTF8(event->text.text); - return true; - } - case SDL_KEYDOWN: - case SDL_KEYUP: - { - int key = event->key.keysym.sym & ~SDLK_SCANCODE_MASK; - io.KeysDown[key] = (event->type == SDL_KEYDOWN); - io.KeyShift = ((SDL_GetModState() & KMOD_SHIFT) != 0); - io.KeyCtrl = ((SDL_GetModState() & KMOD_CTRL) != 0); - io.KeyAlt = ((SDL_GetModState() & KMOD_ALT) != 0); - io.KeySuper = ((SDL_GetModState() & KMOD_GUI) != 0); - return true; - } - } - return false; -} - -bool ImGui_ImplSdl_CreateDeviceObjects() -{ - // Build texture atlas - ImGuiIO& io = ImGui::GetIO(); - unsigned char* pixels; - int width, height; - io.Fonts->GetTexDataAsAlpha8(&pixels, &width, &height); - - // Upload texture to graphics system - GLint last_texture; - glGetIntegerv(GL_TEXTURE_BINDING_2D, &last_texture); - glGenTextures(1, &g_FontTexture); - glBindTexture(GL_TEXTURE_2D, g_FontTexture); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - glPixelStorei(GL_UNPACK_ROW_LENGTH, 0); - glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, width, height, 0, GL_ALPHA, GL_UNSIGNED_BYTE, pixels); - - // Store our identifier - io.Fonts->TexID = (void *)(intptr_t)g_FontTexture; - - // Restore state - glBindTexture(GL_TEXTURE_2D, last_texture); - - return true; -} - -void ImGui_ImplSdl_InvalidateDeviceObjects() -{ - if (g_FontTexture) - { - glDeleteTextures(1, &g_FontTexture); - ImGui::GetIO().Fonts->TexID = 0; - g_FontTexture = 0; - } -} - -bool ImGui_ImplSdl_Init(SDL_Window* window) -{ - ImGuiIO& io = ImGui::GetIO(); - io.KeyMap[ImGuiKey_Tab] = SDLK_TAB; // Keyboard mapping. ImGui will use those indices to peek into the io.KeyDown[] array. - io.KeyMap[ImGuiKey_LeftArrow] = SDL_SCANCODE_LEFT; - io.KeyMap[ImGuiKey_RightArrow] = SDL_SCANCODE_RIGHT; - io.KeyMap[ImGuiKey_UpArrow] = SDL_SCANCODE_UP; - io.KeyMap[ImGuiKey_DownArrow] = SDL_SCANCODE_DOWN; - io.KeyMap[ImGuiKey_PageUp] = SDL_SCANCODE_PAGEUP; - io.KeyMap[ImGuiKey_PageDown] = SDL_SCANCODE_PAGEDOWN; - io.KeyMap[ImGuiKey_Home] = SDL_SCANCODE_HOME; - io.KeyMap[ImGuiKey_End] = SDL_SCANCODE_END; - io.KeyMap[ImGuiKey_Delete] = SDLK_DELETE; - io.KeyMap[ImGuiKey_Backspace] = SDLK_BACKSPACE; - io.KeyMap[ImGuiKey_Enter] = SDLK_RETURN; - io.KeyMap[ImGuiKey_Escape] = SDLK_ESCAPE; - io.KeyMap[ImGuiKey_A] = SDLK_a; - io.KeyMap[ImGuiKey_C] = SDLK_c; - io.KeyMap[ImGuiKey_V] = SDLK_v; - io.KeyMap[ImGuiKey_X] = SDLK_x; - io.KeyMap[ImGuiKey_Y] = SDLK_y; - io.KeyMap[ImGuiKey_Z] = SDLK_z; - - io.RenderDrawListsFn = ImGui_ImplSdl_RenderDrawLists; // Alternatively you can set this to NULL and call ImGui::GetDrawData() after ImGui::Render() to get the same ImDrawData pointer. - io.SetClipboardTextFn = ImGui_ImplSdl_SetClipboardText; - io.GetClipboardTextFn = ImGui_ImplSdl_GetClipboardText; - -#ifdef _WIN32 - SDL_SysWMinfo wmInfo; - SDL_VERSION(&wmInfo.version); - SDL_GetWindowWMInfo(window, &wmInfo); - io.ImeWindowHandle = wmInfo.info.win.window; -#else - (void)window; -#endif - - return true; -} - -void ImGui_ImplSdl_Shutdown() -{ - ImGui_ImplSdl_InvalidateDeviceObjects(); - ImGui::Shutdown(); -} - -void ImGui_ImplSdl_NewFrame(SDL_Window *window) -{ - if (!g_FontTexture) - ImGui_ImplSdl_CreateDeviceObjects(); - - ImGuiIO& io = ImGui::GetIO(); - - // Setup display size (every frame to accommodate for window resizing) - int w, h; - int display_w, display_h; - SDL_GetWindowSize(window, &w, &h); - SDL_GL_GetDrawableSize(window, &display_w, &display_h); - io.DisplaySize = ImVec2((float)w, (float)h); - io.DisplayFramebufferScale = ImVec2(w > 0 ? ((float)display_w / w) : 0, h > 0 ? ((float)display_h / h) : 0); - - // Setup time step - Uint32 time = SDL_GetTicks(); - double current_time = time / 1000.0; - io.DeltaTime = g_Time > 0.0 ? (float)(current_time - g_Time) : (float)(1.0f/60.0f); - g_Time = current_time; - - // Setup inputs - // (we already got mouse wheel, keyboard keys & characters from SDL_PollEvent()) - int mx, my; - Uint32 mouseMask = SDL_GetMouseState(&mx, &my); - if (SDL_GetWindowFlags(window) & SDL_WINDOW_MOUSE_FOCUS) - io.MousePos = ImVec2((float)mx, (float)my); // Mouse position, in pixels (set to -1,-1 if no mouse / on another screen, etc.) - else - io.MousePos = ImVec2(-1,-1); - - io.MouseDown[0] = g_MousePressed[0] || (mouseMask & SDL_BUTTON(SDL_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] = g_MousePressed[1] || (mouseMask & SDL_BUTTON(SDL_BUTTON_RIGHT)) != 0; - io.MouseDown[2] = g_MousePressed[2] || (mouseMask & SDL_BUTTON(SDL_BUTTON_MIDDLE)) != 0; - g_MousePressed[0] = g_MousePressed[1] = g_MousePressed[2] = false; - - io.MouseWheel = g_MouseWheel; - g_MouseWheel = 0.0f; - - // Hide OS mouse cursor if ImGui is drawing it - SDL_ShowCursor(io.MouseDrawCursor ? 0 : 1); - - // Start the frame - ImGui::NewFrame(); -} diff --git a/examples/sdl_opengl_example/imgui_impl_sdl.h b/examples/sdl_opengl_example/imgui_impl_sdl.h deleted file mode 100644 index a322bf2..0000000 --- a/examples/sdl_opengl_example/imgui_impl_sdl.h +++ /dev/null @@ -1,19 +0,0 @@ -// ImGui SDL2 binding with OpenGL -// In this binding, ImTextureID is used to store an OpenGL 'GLuint' texture identifier. Read the FAQ about ImTextureID in imgui.cpp. - -// You can copy and use unmodified imgui_impl_* files in your project. See main.cpp for an example of using this. -// If you use this binding you'll need to call 4 functions: ImGui_ImplXXXX_Init(), ImGui_ImplXXXX_NewFrame(), ImGui::Render() and ImGui_ImplXXXX_Shutdown(). -// If you are new to ImGui, see examples/README.txt and documentation at the top of imgui.cpp. -// https://github.com/ocornut/imgui - -struct SDL_Window; -typedef union SDL_Event SDL_Event; - -IMGUI_API bool ImGui_ImplSdl_Init(SDL_Window* window); -IMGUI_API void ImGui_ImplSdl_Shutdown(); -IMGUI_API void ImGui_ImplSdl_NewFrame(SDL_Window* window); -IMGUI_API bool ImGui_ImplSdl_ProcessEvent(SDL_Event* event); - -// Use if you want to reset your rendering device without losing ImGui state. -IMGUI_API void ImGui_ImplSdl_InvalidateDeviceObjects(); -IMGUI_API bool ImGui_ImplSdl_CreateDeviceObjects(); diff --git a/examples/sdl_opengl_example/main.cpp b/examples/sdl_opengl_example/main.cpp deleted file mode 100644 index f42e7fa..0000000 --- a/examples/sdl_opengl_example/main.cpp +++ /dev/null @@ -1,103 +0,0 @@ -// ImGui - standalone example application for SDL2 + OpenGL -// If you are new to ImGui, see examples/README.txt and documentation at the top of imgui.cpp. - -#include -#include "imgui_impl_sdl.h" -#include -#include -#include - -int main(int, char**) -{ - // Setup SDL - if (SDL_Init(SDL_INIT_VIDEO|SDL_INIT_TIMER) != 0) - { - printf("Error: %s\n", SDL_GetError()); - return -1; - } - - // Setup window - SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1); - SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 24); - SDL_GL_SetAttribute(SDL_GL_STENCIL_SIZE, 8); - SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 2); - SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 2); - SDL_DisplayMode current; - SDL_GetCurrentDisplayMode(0, ¤t); - SDL_Window *window = SDL_CreateWindow("ImGui SDL2+OpenGL example", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, 1280, 720, SDL_WINDOW_OPENGL|SDL_WINDOW_RESIZABLE); - SDL_GLContext glcontext = SDL_GL_CreateContext(window); - - // Setup ImGui binding - ImGui_ImplSdl_Init(window); - - // Load Fonts - // (there is a default font, this is only if you want to change it. see extra_fonts/README.txt for more details) - //ImGuiIO& io = ImGui::GetIO(); - //io.Fonts->AddFontDefault(); - //io.Fonts->AddFontFromFileTTF("../../extra_fonts/Cousine-Regular.ttf", 15.0f); - //io.Fonts->AddFontFromFileTTF("../../extra_fonts/DroidSans.ttf", 16.0f); - //io.Fonts->AddFontFromFileTTF("../../extra_fonts/ProggyClean.ttf", 13.0f); - //io.Fonts->AddFontFromFileTTF("../../extra_fonts/ProggyTiny.ttf", 10.0f); - //io.Fonts->AddFontFromFileTTF("c:\\Windows\\Fonts\\ArialUni.ttf", 18.0f, NULL, io.Fonts->GetGlyphRangesJapanese()); - - bool show_test_window = true; - bool show_another_window = false; - ImVec4 clear_color = ImColor(114, 144, 154); - - // Main loop - bool done = false; - while (!done) - { - SDL_Event event; - while (SDL_PollEvent(&event)) - { - ImGui_ImplSdl_ProcessEvent(&event); - if (event.type == SDL_QUIT) - done = true; - } - ImGui_ImplSdl_NewFrame(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" - { - static float f = 0.0f; - ImGui::Text("Hello, world!"); - ImGui::SliderFloat("float", &f, 0.0f, 1.0f); - ImGui::ColorEdit3("clear color", (float*)&clear_color); - if (ImGui::Button("Test Window")) show_test_window ^= 1; - if (ImGui::Button("Another Window")) show_another_window ^= 1; - ImGui::Text("Application average %.3f ms/frame (%.1f FPS)", 1000.0f / ImGui::GetIO().Framerate, ImGui::GetIO().Framerate); - } - - // 2. Show another simple window, this time using an explicit Begin/End pair - if (show_another_window) - { - ImGui::SetNextWindowSize(ImVec2(200,100), ImGuiSetCond_FirstUseEver); - ImGui::Begin("Another Window", &show_another_window); - 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::SetNextWindowPos(ImVec2(650, 20), ImGuiSetCond_FirstUseEver); - ImGui::ShowTestWindow(&show_test_window); - } - - // Rendering - glViewport(0, 0, (int)ImGui::GetIO().DisplaySize.x, (int)ImGui::GetIO().DisplaySize.y); - glClearColor(clear_color.x, clear_color.y, clear_color.z, clear_color.w); - glClear(GL_COLOR_BUFFER_BIT); - ImGui::Render(); - SDL_GL_SwapWindow(window); - } - - // Cleanup - ImGui_ImplSdl_Shutdown(); - SDL_GL_DeleteContext(glcontext); - SDL_DestroyWindow(window); - SDL_Quit(); - - return 0; -} diff --git a/examples/README.txt b/examples/README.txt index df2e86d..5a1c8df 100644 --- a/examples/README.txt +++ b/examples/README.txt @@ -8,11 +8,13 @@ TL;DR; - Newcomers, read 'PROGRAMMER GUIDE' in imgui.cpp for notes on how to setup ImGui in your codebase. - - Refer to 'opengl_example' to understand how the library is setup, it is the simplest one. + - Refer to 'opengl2_example' to LEARN how the library is setup, it is the simplest one. The other examples requires more boilerplate and are harder to read. + - If you are using OpenGL in your application, probably use an opengl3_xxx backend. + Mixing old fixed pipeline OpenGL2 and programmable pipeline OpenGL3+ isn't well supported by drivers. - If you are using of the backend provided here, so you can copy the imgui_impl_xxx.cpp/h files to your project and use them unmodified. - - If you have your own engine, you probably want to start from 'opengl_example' and adapt it to + - If you have your own engine, you probably want to start from one of the OpenGL example and adapt it to your engine, but you can read the other examples as well. ImGui is highly portable and only requires a few things to run: @@ -41,15 +43,14 @@ Also note that some setup or GPU drivers may be causing extra lag (possibly by enforcing triple buffering), leaving you with no option but sadness/anger (Intel GPU drivers were reported as such). -opengl_example/ - OpenGL example, using GLFW + fixed pipeline. - This is simple and should work for all OpenGL enabled applications. - Prefer following this example to learn how ImGui works! - (You can use this code in a GL3/GL4 context but make sure you disable the programmable pipeline - by calling "glUseProgram(0)" before ImGui::Render.) +opengl2_example/ + GLFW + OpenGL example (old fixed pipeline). + This is simple to read. Prefer following this example to learn how ImGui works! + (You might be able to use this code in a GL3/GL4 context but make sure you disable the programmable + pipeline by calling "glUseProgram(0)" before ImGui::Render.) opengl3_example/ - OpenGL example, using GLFW/GL3W + programmable pipeline. + GLFW + OpenGL example (programmable pipeline, binding modern functions with GL3W). This uses more modern OpenGL calls and custom shaders. It's more messy. directx9_example/ @@ -68,8 +69,8 @@ On iOS, Using Synergy to access keyboard/mouse data from server computer. Synergy keyboard integration is rather hacky. -sdl_opengl_example/ - SDL2 + OpenGL example. +sdl_opengl2_example/ + SDL2 + OpenGL example (old fixed pipeline). sdl_opengl3_example/ SDL2 + OpenGL3 example. diff --git a/examples/imgui_examples_msvc2010.sln b/examples/imgui_examples_msvc2010.sln index b7e6a25..16f0d60 100644 --- a/examples/imgui_examples_msvc2010.sln +++ b/examples/imgui_examples_msvc2010.sln @@ -1,7 +1,7 @@  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}" +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "opengl2_example", "opengl_example\opengl2_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 diff --git a/examples/opengl2_example/Makefile b/examples/opengl2_example/Makefile new file mode 100644 index 0000000..bd79d1b --- /dev/null +++ b/examples/opengl2_example/Makefile @@ -0,0 +1,60 @@ +# +# Cross Platform Makefile +# Compatible with Ubuntu 14.04.1 and Mac OS X +# +# +# if you using Mac OS X: +# You'll need glfw +# http://www.glfw.org +# + +#CXX = g++ + +EXE = opengl2_example +OBJS = main.o imgui_impl_glfw.o +OBJS += ../../imgui.o ../../imgui_demo.o ../../imgui_draw.o + +UNAME_S := $(shell uname -s) + + +ifeq ($(UNAME_S), Linux) #LINUX + ECHO_MESSAGE = "Linux" + LIBS = -lGL `pkg-config --static --libs glfw3` + + CXXFLAGS = -I../../ `pkg-config --cflags glfw3` + CXXFLAGS += -Wall -Wformat + CFLAGS = $(CXXFLAGS) +endif + +ifeq ($(UNAME_S), Darwin) #APPLE + ECHO_MESSAGE = "Mac OS X" + LIBS = -framework OpenGL -framework Cocoa -framework IOKit -framework CoreVideo + LIBS += -L/usr/local/lib -lglfw3 + + CXXFLAGS = -I../../ -I/usr/local/include + CXXFLAGS += -Wall -Wformat +# CXXFLAGS += -D__APPLE__ + CFLAGS = $(CXXFLAGS) +endif + +ifeq ($(UNAME_S), MINGW64_NT-6.3) + ECHO_MESSAGE = "Windows" + LIBS = -lglfw3 -lgdi32 -lopengl32 -limm32 + + CXXFLAGS = -I../../ -I../libs/gl3w `pkg-config --cflags glfw3` + CXXFLAGS += -Wall -Wformat + CFLAGS = $(CXXFLAGS) +endif + +.cpp.o: + $(CXX) $(CXXFLAGS) -c -o $@ $< + +all: $(EXE) + @echo Build complete for $(ECHO_MESSAGE) + +$(EXE): $(OBJS) + $(CXX) -o $(EXE) $(OBJS) $(CXXFLAGS) $(LIBS) + +clean: + rm $(EXE) $(OBJS) + diff --git a/examples/opengl2_example/build_win32.bat b/examples/opengl2_example/build_win32.bat new file mode 100644 index 0000000..278381c --- /dev/null +++ b/examples/opengl2_example/build_win32.bat @@ -0,0 +1,3 @@ +@REM Build for Visual Studio compiler. Run your copy of vcvars32.bat or vcvarsall.bat to setup command-line compiler. +mkdir Debug +cl /nologo /Zi /MD /I ..\.. /I ..\libs\glfw\include *.cpp ..\..\*.cpp /FeDebug/opengl_example.exe /FoDebug/ /link /LIBPATH:..\libs\glfw\lib-vc2010-32 glfw3.lib opengl32.lib gdi32.lib shell32.lib diff --git a/examples/opengl2_example/imgui_impl_glfw.cpp b/examples/opengl2_example/imgui_impl_glfw.cpp new file mode 100644 index 0000000..2d1f5c1 --- /dev/null +++ b/examples/opengl2_example/imgui_impl_glfw.cpp @@ -0,0 +1,288 @@ +// ImGui GLFW binding with OpenGL +// In this binding, ImTextureID is used to store an OpenGL 'GLuint' texture identifier. Read the FAQ about ImTextureID in imgui.cpp. + +// If your context is GL3/GL3 then prefer using the code in opengl3_example. +// You *might* use this code with a GL3/GL4 context but make sure you disable the programmable pipeline by calling "glUseProgram(0)" before ImGui::Render(). +// We cannot do that from GL2 code because the function doesn't exist. + +// You can copy and use unmodified imgui_impl_* files in your project. See main.cpp for an example of using this. +// If you use this binding you'll need to call 4 functions: ImGui_ImplXXXX_Init(), ImGui_ImplXXXX_NewFrame(), ImGui::Render() and ImGui_ImplXXXX_Shutdown(). +// If you are new to ImGui, see examples/README.txt and documentation at the top of imgui.cpp. +// https://github.com/ocornut/imgui + +#include +#include "imgui_impl_glfw.h" + +// GLFW +#include +#ifdef _WIN32 +#undef APIENTRY +#define GLFW_EXPOSE_NATIVE_WIN32 +#define GLFW_EXPOSE_NATIVE_WGL +#include +#endif + +// Data +static GLFWwindow* g_Window = NULL; +static double g_Time = 0.0f; +static bool g_MousePressed[3] = { false, false, false }; +static float g_MouseWheel = 0.0f; +static GLuint g_FontTexture = 0; + +// 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) +void ImGui_ImplGlfw_RenderDrawLists(ImDrawData* draw_data) +{ + // Avoid rendering when minimized, scale coordinates for retina displays (screen coordinates != framebuffer coordinates) + ImGuiIO& io = ImGui::GetIO(); + int fb_width = (int)(io.DisplaySize.x * io.DisplayFramebufferScale.x); + int fb_height = (int)(io.DisplaySize.y * io.DisplayFramebufferScale.y); + if (fb_width == 0 || fb_height == 0) + return; + draw_data->ScaleClipRects(io.DisplayFramebufferScale); + + // We are using the OpenGL fixed pipeline to make the example code simpler to read! + // Setup render state: alpha-blending enabled, no face culling, no depth testing, scissor enabled, vertex/texcoord/color pointers. + GLint last_texture; glGetIntegerv(GL_TEXTURE_BINDING_2D, &last_texture); + GLint last_viewport[4]; glGetIntegerv(GL_VIEWPORT, last_viewport); + glPushAttrib(GL_ENABLE_BIT | GL_COLOR_BUFFER_BIT | GL_TRANSFORM_BIT); + glEnable(GL_BLEND); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + glDisable(GL_CULL_FACE); + glDisable(GL_DEPTH_TEST); + glEnable(GL_SCISSOR_TEST); + glEnableClientState(GL_VERTEX_ARRAY); + glEnableClientState(GL_TEXTURE_COORD_ARRAY); + glEnableClientState(GL_COLOR_ARRAY); + glEnable(GL_TEXTURE_2D); + //glUseProgram(0); // You may want this if using this code in an OpenGL 3+ context + + // Setup viewport, orthographic projection matrix + glViewport(0, 0, (GLsizei)fb_width, (GLsizei)fb_height); + glMatrixMode(GL_PROJECTION); + glPushMatrix(); + glLoadIdentity(); + glOrtho(0.0f, io.DisplaySize.x, io.DisplaySize.y, 0.0f, -1.0f, +1.0f); + glMatrixMode(GL_MODELVIEW); + glPushMatrix(); + glLoadIdentity(); + + // Render command lists + #define OFFSETOF(TYPE, ELEMENT) ((size_t)&(((TYPE *)0)->ELEMENT)) + for (int n = 0; n < draw_data->CmdListsCount; n++) + { + const ImDrawList* cmd_list = draw_data->CmdLists[n]; + const unsigned char* vtx_buffer = (const unsigned char*)&cmd_list->VtxBuffer.front(); + const ImDrawIdx* idx_buffer = &cmd_list->IdxBuffer.front(); + glVertexPointer(2, GL_FLOAT, sizeof(ImDrawVert), (void*)(vtx_buffer + OFFSETOF(ImDrawVert, pos))); + glTexCoordPointer(2, GL_FLOAT, sizeof(ImDrawVert), (void*)(vtx_buffer + OFFSETOF(ImDrawVert, uv))); + glColorPointer(4, GL_UNSIGNED_BYTE, sizeof(ImDrawVert), (void*)(vtx_buffer + OFFSETOF(ImDrawVert, col))); + + for (int cmd_i = 0; cmd_i < cmd_list->CmdBuffer.size(); cmd_i++) + { + const ImDrawCmd* pcmd = &cmd_list->CmdBuffer[cmd_i]; + if (pcmd->UserCallback) + { + pcmd->UserCallback(cmd_list, pcmd); + } + else + { + glBindTexture(GL_TEXTURE_2D, (GLuint)(intptr_t)pcmd->TextureId); + glScissor((int)pcmd->ClipRect.x, (int)(fb_height - pcmd->ClipRect.w), (int)(pcmd->ClipRect.z - pcmd->ClipRect.x), (int)(pcmd->ClipRect.w - pcmd->ClipRect.y)); + glDrawElements(GL_TRIANGLES, (GLsizei)pcmd->ElemCount, sizeof(ImDrawIdx) == 2 ? GL_UNSIGNED_SHORT : GL_UNSIGNED_INT, idx_buffer); + } + idx_buffer += pcmd->ElemCount; + } + } + #undef OFFSETOF + + // Restore modified state + glDisableClientState(GL_COLOR_ARRAY); + glDisableClientState(GL_TEXTURE_COORD_ARRAY); + glDisableClientState(GL_VERTEX_ARRAY); + glBindTexture(GL_TEXTURE_2D, (GLuint)last_texture); + glMatrixMode(GL_MODELVIEW); + glPopMatrix(); + glMatrixMode(GL_PROJECTION); + glPopMatrix(); + glPopAttrib(); + glViewport(last_viewport[0], last_viewport[1], (GLsizei)last_viewport[2], (GLsizei)last_viewport[3]); +} + +static const char* ImGui_ImplGlfw_GetClipboardText() +{ + return glfwGetClipboardString(g_Window); +} + +static void ImGui_ImplGlfw_SetClipboardText(const char* text) +{ + glfwSetClipboardString(g_Window, text); +} + +void ImGui_ImplGlfw_MouseButtonCallback(GLFWwindow*, int button, int action, int /*mods*/) +{ + if (action == GLFW_PRESS && button >= 0 && button < 3) + g_MousePressed[button] = true; +} + +void ImGui_ImplGlfw_ScrollCallback(GLFWwindow*, double /*xoffset*/, double yoffset) +{ + g_MouseWheel += (float)yoffset; // Use fractional mouse wheel, 1.0 unit 5 lines. +} + +void ImGui_ImplGlFw_KeyCallback(GLFWwindow*, int key, int, int action, int mods) +{ + ImGuiIO& io = ImGui::GetIO(); + if (action == GLFW_PRESS) + io.KeysDown[key] = true; + if (action == GLFW_RELEASE) + io.KeysDown[key] = false; + + (void)mods; // Modifiers are not reliable across systems + io.KeyCtrl = io.KeysDown[GLFW_KEY_LEFT_CONTROL] || io.KeysDown[GLFW_KEY_RIGHT_CONTROL]; + io.KeyShift = io.KeysDown[GLFW_KEY_LEFT_SHIFT] || io.KeysDown[GLFW_KEY_RIGHT_SHIFT]; + io.KeyAlt = io.KeysDown[GLFW_KEY_LEFT_ALT] || io.KeysDown[GLFW_KEY_RIGHT_ALT]; + io.KeySuper = io.KeysDown[GLFW_KEY_LEFT_SUPER] || io.KeysDown[GLFW_KEY_RIGHT_SUPER]; +} + +void ImGui_ImplGlfw_CharCallback(GLFWwindow*, unsigned int c) +{ + ImGuiIO& io = ImGui::GetIO(); + if (c > 0 && c < 0x10000) + io.AddInputCharacter((unsigned short)c); +} + +bool ImGui_ImplGlfw_CreateDeviceObjects() +{ + // Build texture atlas + ImGuiIO& io = ImGui::GetIO(); + unsigned char* pixels; + int width, height; + io.Fonts->GetTexDataAsAlpha8(&pixels, &width, &height); + + // Upload texture to graphics system + GLint last_texture; + glGetIntegerv(GL_TEXTURE_BINDING_2D, &last_texture); + glGenTextures(1, &g_FontTexture); + glBindTexture(GL_TEXTURE_2D, g_FontTexture); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, width, height, 0, GL_ALPHA, GL_UNSIGNED_BYTE, pixels); + + // Store our identifier + io.Fonts->TexID = (void *)(intptr_t)g_FontTexture; + + // Restore state + glBindTexture(GL_TEXTURE_2D, last_texture); + + return true; +} + +void ImGui_ImplGlfw_InvalidateDeviceObjects() +{ + if (g_FontTexture) + { + glDeleteTextures(1, &g_FontTexture); + ImGui::GetIO().Fonts->TexID = 0; + g_FontTexture = 0; + } +} + +bool ImGui_ImplGlfw_Init(GLFWwindow* window, bool install_callbacks) +{ + g_Window = window; + + ImGuiIO& io = ImGui::GetIO(); + 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; + io.KeyMap[ImGuiKey_DownArrow] = GLFW_KEY_DOWN; + io.KeyMap[ImGuiKey_PageUp] = GLFW_KEY_PAGE_UP; + io.KeyMap[ImGuiKey_PageDown] = GLFW_KEY_PAGE_DOWN; + io.KeyMap[ImGuiKey_Home] = GLFW_KEY_HOME; + io.KeyMap[ImGuiKey_End] = GLFW_KEY_END; + io.KeyMap[ImGuiKey_Delete] = GLFW_KEY_DELETE; + io.KeyMap[ImGuiKey_Backspace] = GLFW_KEY_BACKSPACE; + io.KeyMap[ImGuiKey_Enter] = GLFW_KEY_ENTER; + io.KeyMap[ImGuiKey_Escape] = GLFW_KEY_ESCAPE; + io.KeyMap[ImGuiKey_A] = GLFW_KEY_A; + io.KeyMap[ImGuiKey_C] = GLFW_KEY_C; + io.KeyMap[ImGuiKey_V] = GLFW_KEY_V; + io.KeyMap[ImGuiKey_X] = GLFW_KEY_X; + io.KeyMap[ImGuiKey_Y] = GLFW_KEY_Y; + io.KeyMap[ImGuiKey_Z] = GLFW_KEY_Z; + + io.RenderDrawListsFn = ImGui_ImplGlfw_RenderDrawLists; // Alternatively you can set this to NULL and call ImGui::GetDrawData() after ImGui::Render() to get the same ImDrawData pointer. + io.SetClipboardTextFn = ImGui_ImplGlfw_SetClipboardText; + io.GetClipboardTextFn = ImGui_ImplGlfw_GetClipboardText; +#ifdef _WIN32 + io.ImeWindowHandle = glfwGetWin32Window(g_Window); +#endif + + if (install_callbacks) + { + glfwSetMouseButtonCallback(window, ImGui_ImplGlfw_MouseButtonCallback); + glfwSetScrollCallback(window, ImGui_ImplGlfw_ScrollCallback); + glfwSetKeyCallback(window, ImGui_ImplGlFw_KeyCallback); + glfwSetCharCallback(window, ImGui_ImplGlfw_CharCallback); + } + + return true; +} + +void ImGui_ImplGlfw_Shutdown() +{ + ImGui_ImplGlfw_InvalidateDeviceObjects(); + ImGui::Shutdown(); +} + +void ImGui_ImplGlfw_NewFrame() +{ + if (!g_FontTexture) + ImGui_ImplGlfw_CreateDeviceObjects(); + + ImGuiIO& io = ImGui::GetIO(); + + // Setup display size (every frame to accommodate for window resizing) + int w, h; + int display_w, display_h; + glfwGetWindowSize(g_Window, &w, &h); + glfwGetFramebufferSize(g_Window, &display_w, &display_h); + io.DisplaySize = ImVec2((float)w, (float)h); + io.DisplayFramebufferScale = ImVec2(w > 0 ? ((float)display_w / w) : 0, h > 0 ? ((float)display_h / h) : 0); + + // Setup time step + double current_time = glfwGetTime(); + io.DeltaTime = g_Time > 0.0 ? (float)(current_time - g_Time) : (float)(1.0f/60.0f); + g_Time = current_time; + + // Setup inputs + // (we already got mouse wheel, keyboard keys & characters from glfw callbacks polled in glfwPollEvents()) + if (glfwGetWindowAttrib(g_Window, GLFW_FOCUSED)) + { + double mouse_x, mouse_y; + glfwGetCursorPos(g_Window, &mouse_x, &mouse_y); + io.MousePos = ImVec2((float)mouse_x, (float)mouse_y); // Mouse position in screen coordinates (set to -1,-1 if no mouse / on another screen, etc.) + } + else + { + io.MousePos = ImVec2(-1,-1); + } + + for (int i = 0; i < 3; i++) + { + io.MouseDown[i] = g_MousePressed[i] || glfwGetMouseButton(g_Window, i) != 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. + g_MousePressed[i] = false; + } + + io.MouseWheel = g_MouseWheel; + g_MouseWheel = 0.0f; + + // Hide OS mouse cursor if ImGui is drawing it + glfwSetInputMode(g_Window, GLFW_CURSOR, io.MouseDrawCursor ? GLFW_CURSOR_HIDDEN : GLFW_CURSOR_NORMAL); + + // Start the frame + ImGui::NewFrame(); +} diff --git a/examples/opengl2_example/imgui_impl_glfw.h b/examples/opengl2_example/imgui_impl_glfw.h new file mode 100644 index 0000000..07dd96f --- /dev/null +++ b/examples/opengl2_example/imgui_impl_glfw.h @@ -0,0 +1,29 @@ +// ImGui GLFW binding with OpenGL +// In this binding, ImTextureID is used to store an OpenGL 'GLuint' texture identifier. Read the FAQ about ImTextureID in imgui.cpp. + +// If your context is GL3/GL3 then prefer using the code in opengl3_example. +// You *might* use this code with a GL3/GL4 context but make sure you disable the programmable pipeline by calling "glUseProgram(0)" before ImGui::Render(). +// We cannot do that from GL2 code because the function doesn't exist. + +// You can copy and use unmodified imgui_impl_* files in your project. See main.cpp for an example of using this. +// If you use this binding you'll need to call 4 functions: ImGui_ImplXXXX_Init(), ImGui_ImplXXXX_NewFrame(), ImGui::Render() and ImGui_ImplXXXX_Shutdown(). +// If you are new to ImGui, see examples/README.txt and documentation at the top of imgui.cpp. +// https://github.com/ocornut/imgui + +struct GLFWwindow; + +IMGUI_API bool ImGui_ImplGlfw_Init(GLFWwindow* window, bool install_callbacks); +IMGUI_API void ImGui_ImplGlfw_Shutdown(); +IMGUI_API void ImGui_ImplGlfw_NewFrame(); + +// Use if you want to reset your rendering device without losing ImGui state. +IMGUI_API void ImGui_ImplGlfw_InvalidateDeviceObjects(); +IMGUI_API bool ImGui_ImplGlfw_CreateDeviceObjects(); + +// GLFW callbacks (installed by default if you enable 'install_callbacks' during initialization) +// Provided here if you want to chain callbacks. +// You can also handle inputs yourself and use those as a reference. +IMGUI_API void ImGui_ImplGlfw_MouseButtonCallback(GLFWwindow* window, int button, int action, int mods); +IMGUI_API void ImGui_ImplGlfw_ScrollCallback(GLFWwindow* window, double xoffset, double yoffset); +IMGUI_API void ImGui_ImplGlFw_KeyCallback(GLFWwindow* window, int key, int scancode, int action, int mods); +IMGUI_API void ImGui_ImplGlfw_CharCallback(GLFWwindow* window, unsigned int c); diff --git a/examples/opengl2_example/main.cpp b/examples/opengl2_example/main.cpp new file mode 100644 index 0000000..a844db5 --- /dev/null +++ b/examples/opengl2_example/main.cpp @@ -0,0 +1,89 @@ +// ImGui - standalone example application for Glfw + OpenGL 2, using fixed pipeline +// If you are new to ImGui, see examples/README.txt and documentation at the top of imgui.cpp. + +#include +#include "imgui_impl_glfw.h" +#include +#include + +static void error_callback(int error, const char* description) +{ + fprintf(stderr, "Error %d: %s\n", error, description); +} + +int main(int, char**) +{ + // Setup window + glfwSetErrorCallback(error_callback); + if (!glfwInit()) + return 1; + GLFWwindow* window = glfwCreateWindow(1280, 720, "ImGui OpenGL2 example", NULL, NULL); + glfwMakeContextCurrent(window); + + // Setup ImGui binding + ImGui_ImplGlfw_Init(window, true); + + // Load Fonts + // (there is a default font, this is only if you want to change it. see extra_fonts/README.txt for more details) + //ImGuiIO& io = ImGui::GetIO(); + //io.Fonts->AddFontDefault(); + //io.Fonts->AddFontFromFileTTF("../../extra_fonts/Cousine-Regular.ttf", 15.0f); + //io.Fonts->AddFontFromFileTTF("../../extra_fonts/DroidSans.ttf", 16.0f); + //io.Fonts->AddFontFromFileTTF("../../extra_fonts/ProggyClean.ttf", 13.0f); + //io.Fonts->AddFontFromFileTTF("../../extra_fonts/ProggyTiny.ttf", 10.0f); + //io.Fonts->AddFontFromFileTTF("c:\\Windows\\Fonts\\ArialUni.ttf", 18.0f, NULL, io.Fonts->GetGlyphRangesJapanese()); + + bool show_test_window = true; + bool show_another_window = false; + ImVec4 clear_color = ImColor(114, 144, 154); + + // Main loop + while (!glfwWindowShouldClose(window)) + { + glfwPollEvents(); + ImGui_ImplGlfw_NewFrame(); + + // 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 = 0.0f; + ImGui::Text("Hello, world!"); + ImGui::SliderFloat("float", &f, 0.0f, 1.0f); + ImGui::ColorEdit3("clear color", (float*)&clear_color); + if (ImGui::Button("Test Window")) show_test_window ^= 1; + if (ImGui::Button("Another Window")) show_another_window ^= 1; + ImGui::Text("Application average %.3f ms/frame (%.1f FPS)", 1000.0f / ImGui::GetIO().Framerate, ImGui::GetIO().Framerate); + } + + // 2. Show another simple window, this time using an explicit Begin/End pair + if (show_another_window) + { + ImGui::SetNextWindowSize(ImVec2(200,100), ImGuiSetCond_FirstUseEver); + ImGui::Begin("Another Window", &show_another_window); + 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::SetNextWindowPos(ImVec2(650, 20), ImGuiSetCond_FirstUseEver); + ImGui::ShowTestWindow(&show_test_window); + } + + // Rendering + int display_w, display_h; + glfwGetFramebufferSize(window, &display_w, &display_h); + glViewport(0, 0, display_w, display_h); + glClearColor(clear_color.x, clear_color.y, clear_color.z, clear_color.w); + glClear(GL_COLOR_BUFFER_BIT); + ImGui::Render(); + glfwSwapBuffers(window); + } + + // Cleanup + ImGui_ImplGlfw_Shutdown(); + glfwTerminate(); + + return 0; +} diff --git a/examples/opengl2_example/opengl_example.vcxproj b/examples/opengl2_example/opengl_example.vcxproj new file mode 100644 index 0000000..4b354b6 --- /dev/null +++ b/examples/opengl2_example/opengl_example.vcxproj @@ -0,0 +1,169 @@ + + + + + Debug + Win32 + + + Debug + x64 + + + Release + Win32 + + + Release + x64 + + + + {9CDA7840-B7A5-496D-A527-E95571496D18} + opengl_example + + + + Application + true + MultiByte + + + Application + true + MultiByte + + + Application + false + true + MultiByte + + + Application + false + true + MultiByte + + + + + + + + + + + + + + + + + + + $(ProjectDir)$(Configuration)\ + $(ProjectDir)$(Configuration)\ + $(IncludePath) + + + $(ProjectDir)$(Configuration)\ + $(ProjectDir)$(Configuration)\ + $(IncludePath) + + + $(ProjectDir)$(Configuration)\ + $(ProjectDir)$(Configuration)\ + $(IncludePath) + + + $(ProjectDir)$(Configuration)\ + $(ProjectDir)$(Configuration)\ + $(IncludePath) + + + + Level4 + Disabled + $(SolutionDir)\libs\glfw\include;..\..;%(AdditionalIncludeDirectories) + + + true + $(SolutionDir)\libs\glfw\lib-vc2010-32;%(AdditionalLibraryDirectories) + opengl32.lib;glfw3.lib;%(AdditionalDependencies) + Console + msvcrt.lib + + + + + Level4 + Disabled + $(SolutionDir)\libs\glfw\include;..\..;%(AdditionalIncludeDirectories) + + + true + $(SolutionDir)\libs\glfw\lib-vc2010-64;%(AdditionalLibraryDirectories) + opengl32.lib;glfw3.lib;%(AdditionalDependencies) + Console + msvcrt.lib + + + + + Level4 + MaxSpeed + true + true + $(SolutionDir)\libs\glfw\include;..\..;%(AdditionalIncludeDirectories) + + + true + true + true + $(SolutionDir)\libs\glfw\lib-vc2010-32;%(AdditionalLibraryDirectories) + opengl32.lib;glfw3.lib;%(AdditionalDependencies) + Console + + + + + + + Level4 + MaxSpeed + true + true + $(SolutionDir)\libs\glfw\include;..\..;%(AdditionalIncludeDirectories) + + + true + true + true + $(SolutionDir)\libs\glfw\lib-vc2010-64;%(AdditionalLibraryDirectories) + opengl32.lib;glfw3.lib;%(AdditionalDependencies) + Console + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/examples/opengl2_example/opengl_example.vcxproj.filters b/examples/opengl2_example/opengl_example.vcxproj.filters new file mode 100644 index 0000000..f2282bf --- /dev/null +++ b/examples/opengl2_example/opengl_example.vcxproj.filters @@ -0,0 +1,46 @@ + + + + + {c336cfe3-f0c4-464c-9ef0-a9e17a7ff222} + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx + + + + + sources + + + imgui + + + sources + + + imgui + + + imgui + + + + + imgui + + + imgui + + + sources + + + imgui + + + + + + \ No newline at end of file diff --git a/examples/opengl_example/Makefile b/examples/opengl_example/Makefile deleted file mode 100644 index 91d1b14..0000000 --- a/examples/opengl_example/Makefile +++ /dev/null @@ -1,60 +0,0 @@ -# -# Cross Platform Makefile -# Compatible with Ubuntu 14.04.1 and Mac OS X -# -# -# if you using Mac OS X: -# You'll need glfw -# http://www.glfw.org -# - -#CXX = g++ - -EXE = opengl_example -OBJS = main.o imgui_impl_glfw.o -OBJS += ../../imgui.o ../../imgui_demo.o ../../imgui_draw.o - -UNAME_S := $(shell uname -s) - - -ifeq ($(UNAME_S), Linux) #LINUX - ECHO_MESSAGE = "Linux" - LIBS = -lGL `pkg-config --static --libs glfw3` - - CXXFLAGS = -I../../ `pkg-config --cflags glfw3` - CXXFLAGS += -Wall -Wformat - CFLAGS = $(CXXFLAGS) -endif - -ifeq ($(UNAME_S), Darwin) #APPLE - ECHO_MESSAGE = "Mac OS X" - LIBS = -framework OpenGL -framework Cocoa -framework IOKit -framework CoreVideo - LIBS += -L/usr/local/lib -lglfw3 - - CXXFLAGS = -I../../ -I/usr/local/include - CXXFLAGS += -Wall -Wformat -# CXXFLAGS += -D__APPLE__ - CFLAGS = $(CXXFLAGS) -endif - -ifeq ($(UNAME_S), MINGW64_NT-6.3) - ECHO_MESSAGE = "Windows" - LIBS = -lglfw3 -lgdi32 -lopengl32 -limm32 - - CXXFLAGS = -I../../ -I../libs/gl3w `pkg-config --cflags glfw3` - CXXFLAGS += -Wall -Wformat - CFLAGS = $(CXXFLAGS) -endif - -.cpp.o: - $(CXX) $(CXXFLAGS) -c -o $@ $< - -all: $(EXE) - @echo Build complete for $(ECHO_MESSAGE) - -$(EXE): $(OBJS) - $(CXX) -o $(EXE) $(OBJS) $(CXXFLAGS) $(LIBS) - -clean: - rm $(EXE) $(OBJS) - diff --git a/examples/opengl_example/build_win32.bat b/examples/opengl_example/build_win32.bat deleted file mode 100644 index 278381c..0000000 --- a/examples/opengl_example/build_win32.bat +++ /dev/null @@ -1,3 +0,0 @@ -@REM Build for Visual Studio compiler. Run your copy of vcvars32.bat or vcvarsall.bat to setup command-line compiler. -mkdir Debug -cl /nologo /Zi /MD /I ..\.. /I ..\libs\glfw\include *.cpp ..\..\*.cpp /FeDebug/opengl_example.exe /FoDebug/ /link /LIBPATH:..\libs\glfw\lib-vc2010-32 glfw3.lib opengl32.lib gdi32.lib shell32.lib diff --git a/examples/opengl_example/imgui_impl_glfw.cpp b/examples/opengl_example/imgui_impl_glfw.cpp deleted file mode 100644 index 2d1f5c1..0000000 --- a/examples/opengl_example/imgui_impl_glfw.cpp +++ /dev/null @@ -1,288 +0,0 @@ -// ImGui GLFW binding with OpenGL -// In this binding, ImTextureID is used to store an OpenGL 'GLuint' texture identifier. Read the FAQ about ImTextureID in imgui.cpp. - -// If your context is GL3/GL3 then prefer using the code in opengl3_example. -// You *might* use this code with a GL3/GL4 context but make sure you disable the programmable pipeline by calling "glUseProgram(0)" before ImGui::Render(). -// We cannot do that from GL2 code because the function doesn't exist. - -// You can copy and use unmodified imgui_impl_* files in your project. See main.cpp for an example of using this. -// If you use this binding you'll need to call 4 functions: ImGui_ImplXXXX_Init(), ImGui_ImplXXXX_NewFrame(), ImGui::Render() and ImGui_ImplXXXX_Shutdown(). -// If you are new to ImGui, see examples/README.txt and documentation at the top of imgui.cpp. -// https://github.com/ocornut/imgui - -#include -#include "imgui_impl_glfw.h" - -// GLFW -#include -#ifdef _WIN32 -#undef APIENTRY -#define GLFW_EXPOSE_NATIVE_WIN32 -#define GLFW_EXPOSE_NATIVE_WGL -#include -#endif - -// Data -static GLFWwindow* g_Window = NULL; -static double g_Time = 0.0f; -static bool g_MousePressed[3] = { false, false, false }; -static float g_MouseWheel = 0.0f; -static GLuint g_FontTexture = 0; - -// 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) -void ImGui_ImplGlfw_RenderDrawLists(ImDrawData* draw_data) -{ - // Avoid rendering when minimized, scale coordinates for retina displays (screen coordinates != framebuffer coordinates) - ImGuiIO& io = ImGui::GetIO(); - int fb_width = (int)(io.DisplaySize.x * io.DisplayFramebufferScale.x); - int fb_height = (int)(io.DisplaySize.y * io.DisplayFramebufferScale.y); - if (fb_width == 0 || fb_height == 0) - return; - draw_data->ScaleClipRects(io.DisplayFramebufferScale); - - // We are using the OpenGL fixed pipeline to make the example code simpler to read! - // Setup render state: alpha-blending enabled, no face culling, no depth testing, scissor enabled, vertex/texcoord/color pointers. - GLint last_texture; glGetIntegerv(GL_TEXTURE_BINDING_2D, &last_texture); - GLint last_viewport[4]; glGetIntegerv(GL_VIEWPORT, last_viewport); - glPushAttrib(GL_ENABLE_BIT | GL_COLOR_BUFFER_BIT | GL_TRANSFORM_BIT); - glEnable(GL_BLEND); - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - glDisable(GL_CULL_FACE); - glDisable(GL_DEPTH_TEST); - glEnable(GL_SCISSOR_TEST); - glEnableClientState(GL_VERTEX_ARRAY); - glEnableClientState(GL_TEXTURE_COORD_ARRAY); - glEnableClientState(GL_COLOR_ARRAY); - glEnable(GL_TEXTURE_2D); - //glUseProgram(0); // You may want this if using this code in an OpenGL 3+ context - - // Setup viewport, orthographic projection matrix - glViewport(0, 0, (GLsizei)fb_width, (GLsizei)fb_height); - glMatrixMode(GL_PROJECTION); - glPushMatrix(); - glLoadIdentity(); - glOrtho(0.0f, io.DisplaySize.x, io.DisplaySize.y, 0.0f, -1.0f, +1.0f); - glMatrixMode(GL_MODELVIEW); - glPushMatrix(); - glLoadIdentity(); - - // Render command lists - #define OFFSETOF(TYPE, ELEMENT) ((size_t)&(((TYPE *)0)->ELEMENT)) - for (int n = 0; n < draw_data->CmdListsCount; n++) - { - const ImDrawList* cmd_list = draw_data->CmdLists[n]; - const unsigned char* vtx_buffer = (const unsigned char*)&cmd_list->VtxBuffer.front(); - const ImDrawIdx* idx_buffer = &cmd_list->IdxBuffer.front(); - glVertexPointer(2, GL_FLOAT, sizeof(ImDrawVert), (void*)(vtx_buffer + OFFSETOF(ImDrawVert, pos))); - glTexCoordPointer(2, GL_FLOAT, sizeof(ImDrawVert), (void*)(vtx_buffer + OFFSETOF(ImDrawVert, uv))); - glColorPointer(4, GL_UNSIGNED_BYTE, sizeof(ImDrawVert), (void*)(vtx_buffer + OFFSETOF(ImDrawVert, col))); - - for (int cmd_i = 0; cmd_i < cmd_list->CmdBuffer.size(); cmd_i++) - { - const ImDrawCmd* pcmd = &cmd_list->CmdBuffer[cmd_i]; - if (pcmd->UserCallback) - { - pcmd->UserCallback(cmd_list, pcmd); - } - else - { - glBindTexture(GL_TEXTURE_2D, (GLuint)(intptr_t)pcmd->TextureId); - glScissor((int)pcmd->ClipRect.x, (int)(fb_height - pcmd->ClipRect.w), (int)(pcmd->ClipRect.z - pcmd->ClipRect.x), (int)(pcmd->ClipRect.w - pcmd->ClipRect.y)); - glDrawElements(GL_TRIANGLES, (GLsizei)pcmd->ElemCount, sizeof(ImDrawIdx) == 2 ? GL_UNSIGNED_SHORT : GL_UNSIGNED_INT, idx_buffer); - } - idx_buffer += pcmd->ElemCount; - } - } - #undef OFFSETOF - - // Restore modified state - glDisableClientState(GL_COLOR_ARRAY); - glDisableClientState(GL_TEXTURE_COORD_ARRAY); - glDisableClientState(GL_VERTEX_ARRAY); - glBindTexture(GL_TEXTURE_2D, (GLuint)last_texture); - glMatrixMode(GL_MODELVIEW); - glPopMatrix(); - glMatrixMode(GL_PROJECTION); - glPopMatrix(); - glPopAttrib(); - glViewport(last_viewport[0], last_viewport[1], (GLsizei)last_viewport[2], (GLsizei)last_viewport[3]); -} - -static const char* ImGui_ImplGlfw_GetClipboardText() -{ - return glfwGetClipboardString(g_Window); -} - -static void ImGui_ImplGlfw_SetClipboardText(const char* text) -{ - glfwSetClipboardString(g_Window, text); -} - -void ImGui_ImplGlfw_MouseButtonCallback(GLFWwindow*, int button, int action, int /*mods*/) -{ - if (action == GLFW_PRESS && button >= 0 && button < 3) - g_MousePressed[button] = true; -} - -void ImGui_ImplGlfw_ScrollCallback(GLFWwindow*, double /*xoffset*/, double yoffset) -{ - g_MouseWheel += (float)yoffset; // Use fractional mouse wheel, 1.0 unit 5 lines. -} - -void ImGui_ImplGlFw_KeyCallback(GLFWwindow*, int key, int, int action, int mods) -{ - ImGuiIO& io = ImGui::GetIO(); - if (action == GLFW_PRESS) - io.KeysDown[key] = true; - if (action == GLFW_RELEASE) - io.KeysDown[key] = false; - - (void)mods; // Modifiers are not reliable across systems - io.KeyCtrl = io.KeysDown[GLFW_KEY_LEFT_CONTROL] || io.KeysDown[GLFW_KEY_RIGHT_CONTROL]; - io.KeyShift = io.KeysDown[GLFW_KEY_LEFT_SHIFT] || io.KeysDown[GLFW_KEY_RIGHT_SHIFT]; - io.KeyAlt = io.KeysDown[GLFW_KEY_LEFT_ALT] || io.KeysDown[GLFW_KEY_RIGHT_ALT]; - io.KeySuper = io.KeysDown[GLFW_KEY_LEFT_SUPER] || io.KeysDown[GLFW_KEY_RIGHT_SUPER]; -} - -void ImGui_ImplGlfw_CharCallback(GLFWwindow*, unsigned int c) -{ - ImGuiIO& io = ImGui::GetIO(); - if (c > 0 && c < 0x10000) - io.AddInputCharacter((unsigned short)c); -} - -bool ImGui_ImplGlfw_CreateDeviceObjects() -{ - // Build texture atlas - ImGuiIO& io = ImGui::GetIO(); - unsigned char* pixels; - int width, height; - io.Fonts->GetTexDataAsAlpha8(&pixels, &width, &height); - - // Upload texture to graphics system - GLint last_texture; - glGetIntegerv(GL_TEXTURE_BINDING_2D, &last_texture); - glGenTextures(1, &g_FontTexture); - glBindTexture(GL_TEXTURE_2D, g_FontTexture); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, width, height, 0, GL_ALPHA, GL_UNSIGNED_BYTE, pixels); - - // Store our identifier - io.Fonts->TexID = (void *)(intptr_t)g_FontTexture; - - // Restore state - glBindTexture(GL_TEXTURE_2D, last_texture); - - return true; -} - -void ImGui_ImplGlfw_InvalidateDeviceObjects() -{ - if (g_FontTexture) - { - glDeleteTextures(1, &g_FontTexture); - ImGui::GetIO().Fonts->TexID = 0; - g_FontTexture = 0; - } -} - -bool ImGui_ImplGlfw_Init(GLFWwindow* window, bool install_callbacks) -{ - g_Window = window; - - ImGuiIO& io = ImGui::GetIO(); - 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; - io.KeyMap[ImGuiKey_DownArrow] = GLFW_KEY_DOWN; - io.KeyMap[ImGuiKey_PageUp] = GLFW_KEY_PAGE_UP; - io.KeyMap[ImGuiKey_PageDown] = GLFW_KEY_PAGE_DOWN; - io.KeyMap[ImGuiKey_Home] = GLFW_KEY_HOME; - io.KeyMap[ImGuiKey_End] = GLFW_KEY_END; - io.KeyMap[ImGuiKey_Delete] = GLFW_KEY_DELETE; - io.KeyMap[ImGuiKey_Backspace] = GLFW_KEY_BACKSPACE; - io.KeyMap[ImGuiKey_Enter] = GLFW_KEY_ENTER; - io.KeyMap[ImGuiKey_Escape] = GLFW_KEY_ESCAPE; - io.KeyMap[ImGuiKey_A] = GLFW_KEY_A; - io.KeyMap[ImGuiKey_C] = GLFW_KEY_C; - io.KeyMap[ImGuiKey_V] = GLFW_KEY_V; - io.KeyMap[ImGuiKey_X] = GLFW_KEY_X; - io.KeyMap[ImGuiKey_Y] = GLFW_KEY_Y; - io.KeyMap[ImGuiKey_Z] = GLFW_KEY_Z; - - io.RenderDrawListsFn = ImGui_ImplGlfw_RenderDrawLists; // Alternatively you can set this to NULL and call ImGui::GetDrawData() after ImGui::Render() to get the same ImDrawData pointer. - io.SetClipboardTextFn = ImGui_ImplGlfw_SetClipboardText; - io.GetClipboardTextFn = ImGui_ImplGlfw_GetClipboardText; -#ifdef _WIN32 - io.ImeWindowHandle = glfwGetWin32Window(g_Window); -#endif - - if (install_callbacks) - { - glfwSetMouseButtonCallback(window, ImGui_ImplGlfw_MouseButtonCallback); - glfwSetScrollCallback(window, ImGui_ImplGlfw_ScrollCallback); - glfwSetKeyCallback(window, ImGui_ImplGlFw_KeyCallback); - glfwSetCharCallback(window, ImGui_ImplGlfw_CharCallback); - } - - return true; -} - -void ImGui_ImplGlfw_Shutdown() -{ - ImGui_ImplGlfw_InvalidateDeviceObjects(); - ImGui::Shutdown(); -} - -void ImGui_ImplGlfw_NewFrame() -{ - if (!g_FontTexture) - ImGui_ImplGlfw_CreateDeviceObjects(); - - ImGuiIO& io = ImGui::GetIO(); - - // Setup display size (every frame to accommodate for window resizing) - int w, h; - int display_w, display_h; - glfwGetWindowSize(g_Window, &w, &h); - glfwGetFramebufferSize(g_Window, &display_w, &display_h); - io.DisplaySize = ImVec2((float)w, (float)h); - io.DisplayFramebufferScale = ImVec2(w > 0 ? ((float)display_w / w) : 0, h > 0 ? ((float)display_h / h) : 0); - - // Setup time step - double current_time = glfwGetTime(); - io.DeltaTime = g_Time > 0.0 ? (float)(current_time - g_Time) : (float)(1.0f/60.0f); - g_Time = current_time; - - // Setup inputs - // (we already got mouse wheel, keyboard keys & characters from glfw callbacks polled in glfwPollEvents()) - if (glfwGetWindowAttrib(g_Window, GLFW_FOCUSED)) - { - double mouse_x, mouse_y; - glfwGetCursorPos(g_Window, &mouse_x, &mouse_y); - io.MousePos = ImVec2((float)mouse_x, (float)mouse_y); // Mouse position in screen coordinates (set to -1,-1 if no mouse / on another screen, etc.) - } - else - { - io.MousePos = ImVec2(-1,-1); - } - - for (int i = 0; i < 3; i++) - { - io.MouseDown[i] = g_MousePressed[i] || glfwGetMouseButton(g_Window, i) != 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. - g_MousePressed[i] = false; - } - - io.MouseWheel = g_MouseWheel; - g_MouseWheel = 0.0f; - - // Hide OS mouse cursor if ImGui is drawing it - glfwSetInputMode(g_Window, GLFW_CURSOR, io.MouseDrawCursor ? GLFW_CURSOR_HIDDEN : GLFW_CURSOR_NORMAL); - - // Start the frame - ImGui::NewFrame(); -} diff --git a/examples/opengl_example/imgui_impl_glfw.h b/examples/opengl_example/imgui_impl_glfw.h deleted file mode 100644 index 07dd96f..0000000 --- a/examples/opengl_example/imgui_impl_glfw.h +++ /dev/null @@ -1,29 +0,0 @@ -// ImGui GLFW binding with OpenGL -// In this binding, ImTextureID is used to store an OpenGL 'GLuint' texture identifier. Read the FAQ about ImTextureID in imgui.cpp. - -// If your context is GL3/GL3 then prefer using the code in opengl3_example. -// You *might* use this code with a GL3/GL4 context but make sure you disable the programmable pipeline by calling "glUseProgram(0)" before ImGui::Render(). -// We cannot do that from GL2 code because the function doesn't exist. - -// You can copy and use unmodified imgui_impl_* files in your project. See main.cpp for an example of using this. -// If you use this binding you'll need to call 4 functions: ImGui_ImplXXXX_Init(), ImGui_ImplXXXX_NewFrame(), ImGui::Render() and ImGui_ImplXXXX_Shutdown(). -// If you are new to ImGui, see examples/README.txt and documentation at the top of imgui.cpp. -// https://github.com/ocornut/imgui - -struct GLFWwindow; - -IMGUI_API bool ImGui_ImplGlfw_Init(GLFWwindow* window, bool install_callbacks); -IMGUI_API void ImGui_ImplGlfw_Shutdown(); -IMGUI_API void ImGui_ImplGlfw_NewFrame(); - -// Use if you want to reset your rendering device without losing ImGui state. -IMGUI_API void ImGui_ImplGlfw_InvalidateDeviceObjects(); -IMGUI_API bool ImGui_ImplGlfw_CreateDeviceObjects(); - -// GLFW callbacks (installed by default if you enable 'install_callbacks' during initialization) -// Provided here if you want to chain callbacks. -// You can also handle inputs yourself and use those as a reference. -IMGUI_API void ImGui_ImplGlfw_MouseButtonCallback(GLFWwindow* window, int button, int action, int mods); -IMGUI_API void ImGui_ImplGlfw_ScrollCallback(GLFWwindow* window, double xoffset, double yoffset); -IMGUI_API void ImGui_ImplGlFw_KeyCallback(GLFWwindow* window, int key, int scancode, int action, int mods); -IMGUI_API void ImGui_ImplGlfw_CharCallback(GLFWwindow* window, unsigned int c); diff --git a/examples/opengl_example/main.cpp b/examples/opengl_example/main.cpp deleted file mode 100644 index a844db5..0000000 --- a/examples/opengl_example/main.cpp +++ /dev/null @@ -1,89 +0,0 @@ -// ImGui - standalone example application for Glfw + OpenGL 2, using fixed pipeline -// If you are new to ImGui, see examples/README.txt and documentation at the top of imgui.cpp. - -#include -#include "imgui_impl_glfw.h" -#include -#include - -static void error_callback(int error, const char* description) -{ - fprintf(stderr, "Error %d: %s\n", error, description); -} - -int main(int, char**) -{ - // Setup window - glfwSetErrorCallback(error_callback); - if (!glfwInit()) - return 1; - GLFWwindow* window = glfwCreateWindow(1280, 720, "ImGui OpenGL2 example", NULL, NULL); - glfwMakeContextCurrent(window); - - // Setup ImGui binding - ImGui_ImplGlfw_Init(window, true); - - // Load Fonts - // (there is a default font, this is only if you want to change it. see extra_fonts/README.txt for more details) - //ImGuiIO& io = ImGui::GetIO(); - //io.Fonts->AddFontDefault(); - //io.Fonts->AddFontFromFileTTF("../../extra_fonts/Cousine-Regular.ttf", 15.0f); - //io.Fonts->AddFontFromFileTTF("../../extra_fonts/DroidSans.ttf", 16.0f); - //io.Fonts->AddFontFromFileTTF("../../extra_fonts/ProggyClean.ttf", 13.0f); - //io.Fonts->AddFontFromFileTTF("../../extra_fonts/ProggyTiny.ttf", 10.0f); - //io.Fonts->AddFontFromFileTTF("c:\\Windows\\Fonts\\ArialUni.ttf", 18.0f, NULL, io.Fonts->GetGlyphRangesJapanese()); - - bool show_test_window = true; - bool show_another_window = false; - ImVec4 clear_color = ImColor(114, 144, 154); - - // Main loop - while (!glfwWindowShouldClose(window)) - { - glfwPollEvents(); - ImGui_ImplGlfw_NewFrame(); - - // 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 = 0.0f; - ImGui::Text("Hello, world!"); - ImGui::SliderFloat("float", &f, 0.0f, 1.0f); - ImGui::ColorEdit3("clear color", (float*)&clear_color); - if (ImGui::Button("Test Window")) show_test_window ^= 1; - if (ImGui::Button("Another Window")) show_another_window ^= 1; - ImGui::Text("Application average %.3f ms/frame (%.1f FPS)", 1000.0f / ImGui::GetIO().Framerate, ImGui::GetIO().Framerate); - } - - // 2. Show another simple window, this time using an explicit Begin/End pair - if (show_another_window) - { - ImGui::SetNextWindowSize(ImVec2(200,100), ImGuiSetCond_FirstUseEver); - ImGui::Begin("Another Window", &show_another_window); - 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::SetNextWindowPos(ImVec2(650, 20), ImGuiSetCond_FirstUseEver); - ImGui::ShowTestWindow(&show_test_window); - } - - // Rendering - int display_w, display_h; - glfwGetFramebufferSize(window, &display_w, &display_h); - glViewport(0, 0, display_w, display_h); - glClearColor(clear_color.x, clear_color.y, clear_color.z, clear_color.w); - glClear(GL_COLOR_BUFFER_BIT); - ImGui::Render(); - glfwSwapBuffers(window); - } - - // Cleanup - ImGui_ImplGlfw_Shutdown(); - glfwTerminate(); - - return 0; -} diff --git a/examples/opengl_example/opengl_example.vcxproj b/examples/opengl_example/opengl_example.vcxproj deleted file mode 100644 index 4b354b6..0000000 --- a/examples/opengl_example/opengl_example.vcxproj +++ /dev/null @@ -1,169 +0,0 @@ - - - - - Debug - Win32 - - - Debug - x64 - - - Release - Win32 - - - Release - x64 - - - - {9CDA7840-B7A5-496D-A527-E95571496D18} - opengl_example - - - - Application - true - MultiByte - - - Application - true - MultiByte - - - Application - false - true - MultiByte - - - Application - false - true - MultiByte - - - - - - - - - - - - - - - - - - - $(ProjectDir)$(Configuration)\ - $(ProjectDir)$(Configuration)\ - $(IncludePath) - - - $(ProjectDir)$(Configuration)\ - $(ProjectDir)$(Configuration)\ - $(IncludePath) - - - $(ProjectDir)$(Configuration)\ - $(ProjectDir)$(Configuration)\ - $(IncludePath) - - - $(ProjectDir)$(Configuration)\ - $(ProjectDir)$(Configuration)\ - $(IncludePath) - - - - Level4 - Disabled - $(SolutionDir)\libs\glfw\include;..\..;%(AdditionalIncludeDirectories) - - - true - $(SolutionDir)\libs\glfw\lib-vc2010-32;%(AdditionalLibraryDirectories) - opengl32.lib;glfw3.lib;%(AdditionalDependencies) - Console - msvcrt.lib - - - - - Level4 - Disabled - $(SolutionDir)\libs\glfw\include;..\..;%(AdditionalIncludeDirectories) - - - true - $(SolutionDir)\libs\glfw\lib-vc2010-64;%(AdditionalLibraryDirectories) - opengl32.lib;glfw3.lib;%(AdditionalDependencies) - Console - msvcrt.lib - - - - - Level4 - MaxSpeed - true - true - $(SolutionDir)\libs\glfw\include;..\..;%(AdditionalIncludeDirectories) - - - true - true - true - $(SolutionDir)\libs\glfw\lib-vc2010-32;%(AdditionalLibraryDirectories) - opengl32.lib;glfw3.lib;%(AdditionalDependencies) - Console - - - - - - - Level4 - MaxSpeed - true - true - $(SolutionDir)\libs\glfw\include;..\..;%(AdditionalIncludeDirectories) - - - true - true - true - $(SolutionDir)\libs\glfw\lib-vc2010-64;%(AdditionalLibraryDirectories) - opengl32.lib;glfw3.lib;%(AdditionalDependencies) - Console - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/examples/opengl_example/opengl_example.vcxproj.filters b/examples/opengl_example/opengl_example.vcxproj.filters deleted file mode 100644 index f2282bf..0000000 --- a/examples/opengl_example/opengl_example.vcxproj.filters +++ /dev/null @@ -1,46 +0,0 @@ - - - - - {c336cfe3-f0c4-464c-9ef0-a9e17a7ff222} - - - {4FC737F1-C7A5-4376-A066-2A32D752A2FF} - cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx - - - - - sources - - - imgui - - - sources - - - imgui - - - imgui - - - - - imgui - - - imgui - - - sources - - - imgui - - - - - - \ No newline at end of file diff --git a/examples/sdl_opengl2_example/README.md b/examples/sdl_opengl2_example/README.md new file mode 100644 index 0000000..aada45d --- /dev/null +++ b/examples/sdl_opengl2_example/README.md @@ -0,0 +1,22 @@ + +# How to Build + +- On Windows with Visual Studio's CLI + +``` +set SDL2DIR=path_to_your_sdl2_folder +cl /Zi /MD /I %SDL2DIR%\include> /I ..\.. main.cpp imgui_impl_sdl.cpp ..\..\imgui*.cpp /link /LIBPATH:%SDL2DIR%\lib SDL2.lib SDL2main.lib +``` + +- On Linux and similar Unixes + +``` +c++ `sdl2-config --cflags` -I ../.. main.cpp imgui_impl_sdl.cpp ../../imgui*.cpp `sdl2-config --libs` -lGL -o sdl2example +``` + +- On Mac OS X + +``` +brew install sdl2 +c++ `sdl2-config --cflags` -I ../.. main.cpp imgui_impl_sdl.cpp ../../imgui*.cpp `sdl2-config --libs` -framework OpenGl -o sdl2example +``` diff --git a/examples/sdl_opengl2_example/imgui_impl_sdl.cpp b/examples/sdl_opengl2_example/imgui_impl_sdl.cpp new file mode 100644 index 0000000..63ed9f4 --- /dev/null +++ b/examples/sdl_opengl2_example/imgui_impl_sdl.cpp @@ -0,0 +1,277 @@ +// ImGui SDL2 binding with OpenGL +// In this binding, ImTextureID is used to store an OpenGL 'GLuint' texture identifier. Read the FAQ about ImTextureID in imgui.cpp. + +// You can copy and use unmodified imgui_impl_* files in your project. See main.cpp for an example of using this. +// If you use this binding you'll need to call 4 functions: ImGui_ImplXXXX_Init(), ImGui_ImplXXXX_NewFrame(), ImGui::Render() and ImGui_ImplXXXX_Shutdown(). +// If you are new to ImGui, see examples/README.txt and documentation at the top of imgui.cpp. +// https://github.com/ocornut/imgui + +#include +#include +#include +#include +#include "imgui_impl_sdl.h" + +// Data +static double g_Time = 0.0f; +static bool g_MousePressed[3] = { false, false, false }; +static float g_MouseWheel = 0.0f; +static GLuint g_FontTexture = 0; + +// 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) +void ImGui_ImplSdl_RenderDrawLists(ImDrawData* draw_data) +{ + // Avoid rendering when minimized, scale coordinates for retina displays (screen coordinates != framebuffer coordinates) + ImGuiIO& io = ImGui::GetIO(); + int fb_width = (int)(io.DisplaySize.x * io.DisplayFramebufferScale.x); + int fb_height = (int)(io.DisplaySize.y * io.DisplayFramebufferScale.y); + if (fb_width == 0 || fb_height == 0) + return; + draw_data->ScaleClipRects(io.DisplayFramebufferScale); + + // We are using the OpenGL fixed pipeline to make the example code simpler to read! + // Setup render state: alpha-blending enabled, no face culling, no depth testing, scissor enabled, vertex/texcoord/color pointers. + GLint last_texture; glGetIntegerv(GL_TEXTURE_BINDING_2D, &last_texture); + GLint last_viewport[4]; glGetIntegerv(GL_VIEWPORT, last_viewport); + glPushAttrib(GL_ENABLE_BIT | GL_COLOR_BUFFER_BIT | GL_TRANSFORM_BIT); + glEnable(GL_BLEND); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + glDisable(GL_CULL_FACE); + glDisable(GL_DEPTH_TEST); + glEnable(GL_SCISSOR_TEST); + glEnableClientState(GL_VERTEX_ARRAY); + glEnableClientState(GL_TEXTURE_COORD_ARRAY); + glEnableClientState(GL_COLOR_ARRAY); + glEnable(GL_TEXTURE_2D); + //glUseProgram(0); // You may want this if using this code in an OpenGL 3+ context + + // Setup viewport, orthographic projection matrix + glViewport(0, 0, (GLsizei)fb_width, (GLsizei)fb_height); + glMatrixMode(GL_PROJECTION); + glPushMatrix(); + glLoadIdentity(); + glOrtho(0.0f, io.DisplaySize.x, io.DisplaySize.y, 0.0f, -1.0f, +1.0f); + glMatrixMode(GL_MODELVIEW); + glPushMatrix(); + glLoadIdentity(); + + // Render command lists + #define OFFSETOF(TYPE, ELEMENT) ((size_t)&(((TYPE *)0)->ELEMENT)) + for (int n = 0; n < draw_data->CmdListsCount; n++) + { + const ImDrawList* cmd_list = draw_data->CmdLists[n]; + const unsigned char* vtx_buffer = (const unsigned char*)&cmd_list->VtxBuffer.front(); + const ImDrawIdx* idx_buffer = &cmd_list->IdxBuffer.front(); + glVertexPointer(2, GL_FLOAT, sizeof(ImDrawVert), (void*)(vtx_buffer + OFFSETOF(ImDrawVert, pos))); + glTexCoordPointer(2, GL_FLOAT, sizeof(ImDrawVert), (void*)(vtx_buffer + OFFSETOF(ImDrawVert, uv))); + glColorPointer(4, GL_UNSIGNED_BYTE, sizeof(ImDrawVert), (void*)(vtx_buffer + OFFSETOF(ImDrawVert, col))); + + for (int cmd_i = 0; cmd_i < cmd_list->CmdBuffer.size(); cmd_i++) + { + const ImDrawCmd* pcmd = &cmd_list->CmdBuffer[cmd_i]; + if (pcmd->UserCallback) + { + pcmd->UserCallback(cmd_list, pcmd); + } + else + { + glBindTexture(GL_TEXTURE_2D, (GLuint)(intptr_t)pcmd->TextureId); + glScissor((int)pcmd->ClipRect.x, (int)(fb_height - pcmd->ClipRect.w), (int)(pcmd->ClipRect.z - pcmd->ClipRect.x), (int)(pcmd->ClipRect.w - pcmd->ClipRect.y)); + glDrawElements(GL_TRIANGLES, (GLsizei)pcmd->ElemCount, sizeof(ImDrawIdx) == 2 ? GL_UNSIGNED_SHORT : GL_UNSIGNED_INT, idx_buffer); + } + idx_buffer += pcmd->ElemCount; + } + } + #undef OFFSETOF + + // Restore modified state + glDisableClientState(GL_COLOR_ARRAY); + glDisableClientState(GL_TEXTURE_COORD_ARRAY); + glDisableClientState(GL_VERTEX_ARRAY); + glBindTexture(GL_TEXTURE_2D, (GLuint)last_texture); + glMatrixMode(GL_MODELVIEW); + glPopMatrix(); + glMatrixMode(GL_PROJECTION); + glPopMatrix(); + glPopAttrib(); + glViewport(last_viewport[0], last_viewport[1], (GLsizei)last_viewport[2], (GLsizei)last_viewport[3]); +} + +static const char* ImGui_ImplSdl_GetClipboardText() +{ + return SDL_GetClipboardText(); +} + +static void ImGui_ImplSdl_SetClipboardText(const char* text) +{ + SDL_SetClipboardText(text); +} + +bool ImGui_ImplSdl_ProcessEvent(SDL_Event* event) +{ + ImGuiIO& io = ImGui::GetIO(); + switch (event->type) + { + case SDL_MOUSEWHEEL: + { + if (event->wheel.y > 0) + g_MouseWheel = 1; + if (event->wheel.y < 0) + g_MouseWheel = -1; + return true; + } + case SDL_MOUSEBUTTONDOWN: + { + if (event->button.button == SDL_BUTTON_LEFT) g_MousePressed[0] = true; + if (event->button.button == SDL_BUTTON_RIGHT) g_MousePressed[1] = true; + if (event->button.button == SDL_BUTTON_MIDDLE) g_MousePressed[2] = true; + return true; + } + case SDL_TEXTINPUT: + { + io.AddInputCharactersUTF8(event->text.text); + return true; + } + case SDL_KEYDOWN: + case SDL_KEYUP: + { + int key = event->key.keysym.sym & ~SDLK_SCANCODE_MASK; + io.KeysDown[key] = (event->type == SDL_KEYDOWN); + io.KeyShift = ((SDL_GetModState() & KMOD_SHIFT) != 0); + io.KeyCtrl = ((SDL_GetModState() & KMOD_CTRL) != 0); + io.KeyAlt = ((SDL_GetModState() & KMOD_ALT) != 0); + io.KeySuper = ((SDL_GetModState() & KMOD_GUI) != 0); + return true; + } + } + return false; +} + +bool ImGui_ImplSdl_CreateDeviceObjects() +{ + // Build texture atlas + ImGuiIO& io = ImGui::GetIO(); + unsigned char* pixels; + int width, height; + io.Fonts->GetTexDataAsAlpha8(&pixels, &width, &height); + + // Upload texture to graphics system + GLint last_texture; + glGetIntegerv(GL_TEXTURE_BINDING_2D, &last_texture); + glGenTextures(1, &g_FontTexture); + glBindTexture(GL_TEXTURE_2D, g_FontTexture); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glPixelStorei(GL_UNPACK_ROW_LENGTH, 0); + glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, width, height, 0, GL_ALPHA, GL_UNSIGNED_BYTE, pixels); + + // Store our identifier + io.Fonts->TexID = (void *)(intptr_t)g_FontTexture; + + // Restore state + glBindTexture(GL_TEXTURE_2D, last_texture); + + return true; +} + +void ImGui_ImplSdl_InvalidateDeviceObjects() +{ + if (g_FontTexture) + { + glDeleteTextures(1, &g_FontTexture); + ImGui::GetIO().Fonts->TexID = 0; + g_FontTexture = 0; + } +} + +bool ImGui_ImplSdl_Init(SDL_Window* window) +{ + ImGuiIO& io = ImGui::GetIO(); + io.KeyMap[ImGuiKey_Tab] = SDLK_TAB; // Keyboard mapping. ImGui will use those indices to peek into the io.KeyDown[] array. + io.KeyMap[ImGuiKey_LeftArrow] = SDL_SCANCODE_LEFT; + io.KeyMap[ImGuiKey_RightArrow] = SDL_SCANCODE_RIGHT; + io.KeyMap[ImGuiKey_UpArrow] = SDL_SCANCODE_UP; + io.KeyMap[ImGuiKey_DownArrow] = SDL_SCANCODE_DOWN; + io.KeyMap[ImGuiKey_PageUp] = SDL_SCANCODE_PAGEUP; + io.KeyMap[ImGuiKey_PageDown] = SDL_SCANCODE_PAGEDOWN; + io.KeyMap[ImGuiKey_Home] = SDL_SCANCODE_HOME; + io.KeyMap[ImGuiKey_End] = SDL_SCANCODE_END; + io.KeyMap[ImGuiKey_Delete] = SDLK_DELETE; + io.KeyMap[ImGuiKey_Backspace] = SDLK_BACKSPACE; + io.KeyMap[ImGuiKey_Enter] = SDLK_RETURN; + io.KeyMap[ImGuiKey_Escape] = SDLK_ESCAPE; + io.KeyMap[ImGuiKey_A] = SDLK_a; + io.KeyMap[ImGuiKey_C] = SDLK_c; + io.KeyMap[ImGuiKey_V] = SDLK_v; + io.KeyMap[ImGuiKey_X] = SDLK_x; + io.KeyMap[ImGuiKey_Y] = SDLK_y; + io.KeyMap[ImGuiKey_Z] = SDLK_z; + + io.RenderDrawListsFn = ImGui_ImplSdl_RenderDrawLists; // Alternatively you can set this to NULL and call ImGui::GetDrawData() after ImGui::Render() to get the same ImDrawData pointer. + io.SetClipboardTextFn = ImGui_ImplSdl_SetClipboardText; + io.GetClipboardTextFn = ImGui_ImplSdl_GetClipboardText; + +#ifdef _WIN32 + SDL_SysWMinfo wmInfo; + SDL_VERSION(&wmInfo.version); + SDL_GetWindowWMInfo(window, &wmInfo); + io.ImeWindowHandle = wmInfo.info.win.window; +#else + (void)window; +#endif + + return true; +} + +void ImGui_ImplSdl_Shutdown() +{ + ImGui_ImplSdl_InvalidateDeviceObjects(); + ImGui::Shutdown(); +} + +void ImGui_ImplSdl_NewFrame(SDL_Window *window) +{ + if (!g_FontTexture) + ImGui_ImplSdl_CreateDeviceObjects(); + + ImGuiIO& io = ImGui::GetIO(); + + // Setup display size (every frame to accommodate for window resizing) + int w, h; + int display_w, display_h; + SDL_GetWindowSize(window, &w, &h); + SDL_GL_GetDrawableSize(window, &display_w, &display_h); + io.DisplaySize = ImVec2((float)w, (float)h); + io.DisplayFramebufferScale = ImVec2(w > 0 ? ((float)display_w / w) : 0, h > 0 ? ((float)display_h / h) : 0); + + // Setup time step + Uint32 time = SDL_GetTicks(); + double current_time = time / 1000.0; + io.DeltaTime = g_Time > 0.0 ? (float)(current_time - g_Time) : (float)(1.0f/60.0f); + g_Time = current_time; + + // Setup inputs + // (we already got mouse wheel, keyboard keys & characters from SDL_PollEvent()) + int mx, my; + Uint32 mouseMask = SDL_GetMouseState(&mx, &my); + if (SDL_GetWindowFlags(window) & SDL_WINDOW_MOUSE_FOCUS) + io.MousePos = ImVec2((float)mx, (float)my); // Mouse position, in pixels (set to -1,-1 if no mouse / on another screen, etc.) + else + io.MousePos = ImVec2(-1,-1); + + io.MouseDown[0] = g_MousePressed[0] || (mouseMask & SDL_BUTTON(SDL_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] = g_MousePressed[1] || (mouseMask & SDL_BUTTON(SDL_BUTTON_RIGHT)) != 0; + io.MouseDown[2] = g_MousePressed[2] || (mouseMask & SDL_BUTTON(SDL_BUTTON_MIDDLE)) != 0; + g_MousePressed[0] = g_MousePressed[1] = g_MousePressed[2] = false; + + io.MouseWheel = g_MouseWheel; + g_MouseWheel = 0.0f; + + // Hide OS mouse cursor if ImGui is drawing it + SDL_ShowCursor(io.MouseDrawCursor ? 0 : 1); + + // Start the frame + ImGui::NewFrame(); +} diff --git a/examples/sdl_opengl2_example/imgui_impl_sdl.h b/examples/sdl_opengl2_example/imgui_impl_sdl.h new file mode 100644 index 0000000..a322bf2 --- /dev/null +++ b/examples/sdl_opengl2_example/imgui_impl_sdl.h @@ -0,0 +1,19 @@ +// ImGui SDL2 binding with OpenGL +// In this binding, ImTextureID is used to store an OpenGL 'GLuint' texture identifier. Read the FAQ about ImTextureID in imgui.cpp. + +// You can copy and use unmodified imgui_impl_* files in your project. See main.cpp for an example of using this. +// If you use this binding you'll need to call 4 functions: ImGui_ImplXXXX_Init(), ImGui_ImplXXXX_NewFrame(), ImGui::Render() and ImGui_ImplXXXX_Shutdown(). +// If you are new to ImGui, see examples/README.txt and documentation at the top of imgui.cpp. +// https://github.com/ocornut/imgui + +struct SDL_Window; +typedef union SDL_Event SDL_Event; + +IMGUI_API bool ImGui_ImplSdl_Init(SDL_Window* window); +IMGUI_API void ImGui_ImplSdl_Shutdown(); +IMGUI_API void ImGui_ImplSdl_NewFrame(SDL_Window* window); +IMGUI_API bool ImGui_ImplSdl_ProcessEvent(SDL_Event* event); + +// Use if you want to reset your rendering device without losing ImGui state. +IMGUI_API void ImGui_ImplSdl_InvalidateDeviceObjects(); +IMGUI_API bool ImGui_ImplSdl_CreateDeviceObjects(); diff --git a/examples/sdl_opengl2_example/main.cpp b/examples/sdl_opengl2_example/main.cpp new file mode 100644 index 0000000..f42e7fa --- /dev/null +++ b/examples/sdl_opengl2_example/main.cpp @@ -0,0 +1,103 @@ +// ImGui - standalone example application for SDL2 + OpenGL +// If you are new to ImGui, see examples/README.txt and documentation at the top of imgui.cpp. + +#include +#include "imgui_impl_sdl.h" +#include +#include +#include + +int main(int, char**) +{ + // Setup SDL + if (SDL_Init(SDL_INIT_VIDEO|SDL_INIT_TIMER) != 0) + { + printf("Error: %s\n", SDL_GetError()); + return -1; + } + + // Setup window + SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1); + SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 24); + SDL_GL_SetAttribute(SDL_GL_STENCIL_SIZE, 8); + SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 2); + SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 2); + SDL_DisplayMode current; + SDL_GetCurrentDisplayMode(0, ¤t); + SDL_Window *window = SDL_CreateWindow("ImGui SDL2+OpenGL example", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, 1280, 720, SDL_WINDOW_OPENGL|SDL_WINDOW_RESIZABLE); + SDL_GLContext glcontext = SDL_GL_CreateContext(window); + + // Setup ImGui binding + ImGui_ImplSdl_Init(window); + + // Load Fonts + // (there is a default font, this is only if you want to change it. see extra_fonts/README.txt for more details) + //ImGuiIO& io = ImGui::GetIO(); + //io.Fonts->AddFontDefault(); + //io.Fonts->AddFontFromFileTTF("../../extra_fonts/Cousine-Regular.ttf", 15.0f); + //io.Fonts->AddFontFromFileTTF("../../extra_fonts/DroidSans.ttf", 16.0f); + //io.Fonts->AddFontFromFileTTF("../../extra_fonts/ProggyClean.ttf", 13.0f); + //io.Fonts->AddFontFromFileTTF("../../extra_fonts/ProggyTiny.ttf", 10.0f); + //io.Fonts->AddFontFromFileTTF("c:\\Windows\\Fonts\\ArialUni.ttf", 18.0f, NULL, io.Fonts->GetGlyphRangesJapanese()); + + bool show_test_window = true; + bool show_another_window = false; + ImVec4 clear_color = ImColor(114, 144, 154); + + // Main loop + bool done = false; + while (!done) + { + SDL_Event event; + while (SDL_PollEvent(&event)) + { + ImGui_ImplSdl_ProcessEvent(&event); + if (event.type == SDL_QUIT) + done = true; + } + ImGui_ImplSdl_NewFrame(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" + { + static float f = 0.0f; + ImGui::Text("Hello, world!"); + ImGui::SliderFloat("float", &f, 0.0f, 1.0f); + ImGui::ColorEdit3("clear color", (float*)&clear_color); + if (ImGui::Button("Test Window")) show_test_window ^= 1; + if (ImGui::Button("Another Window")) show_another_window ^= 1; + ImGui::Text("Application average %.3f ms/frame (%.1f FPS)", 1000.0f / ImGui::GetIO().Framerate, ImGui::GetIO().Framerate); + } + + // 2. Show another simple window, this time using an explicit Begin/End pair + if (show_another_window) + { + ImGui::SetNextWindowSize(ImVec2(200,100), ImGuiSetCond_FirstUseEver); + ImGui::Begin("Another Window", &show_another_window); + 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::SetNextWindowPos(ImVec2(650, 20), ImGuiSetCond_FirstUseEver); + ImGui::ShowTestWindow(&show_test_window); + } + + // Rendering + glViewport(0, 0, (int)ImGui::GetIO().DisplaySize.x, (int)ImGui::GetIO().DisplaySize.y); + glClearColor(clear_color.x, clear_color.y, clear_color.z, clear_color.w); + glClear(GL_COLOR_BUFFER_BIT); + ImGui::Render(); + SDL_GL_SwapWindow(window); + } + + // Cleanup + ImGui_ImplSdl_Shutdown(); + SDL_GL_DeleteContext(glcontext); + SDL_DestroyWindow(window); + SDL_Quit(); + + return 0; +} diff --git a/examples/sdl_opengl_example/README.md b/examples/sdl_opengl_example/README.md deleted file mode 100644 index aada45d..0000000 --- a/examples/sdl_opengl_example/README.md +++ /dev/null @@ -1,22 +0,0 @@ - -# How to Build - -- On Windows with Visual Studio's CLI - -``` -set SDL2DIR=path_to_your_sdl2_folder -cl /Zi /MD /I %SDL2DIR%\include> /I ..\.. main.cpp imgui_impl_sdl.cpp ..\..\imgui*.cpp /link /LIBPATH:%SDL2DIR%\lib SDL2.lib SDL2main.lib -``` - -- On Linux and similar Unixes - -``` -c++ `sdl2-config --cflags` -I ../.. main.cpp imgui_impl_sdl.cpp ../../imgui*.cpp `sdl2-config --libs` -lGL -o sdl2example -``` - -- On Mac OS X - -``` -brew install sdl2 -c++ `sdl2-config --cflags` -I ../.. main.cpp imgui_impl_sdl.cpp ../../imgui*.cpp `sdl2-config --libs` -framework OpenGl -o sdl2example -``` diff --git a/examples/sdl_opengl_example/imgui_impl_sdl.cpp b/examples/sdl_opengl_example/imgui_impl_sdl.cpp deleted file mode 100644 index 63ed9f4..0000000 --- a/examples/sdl_opengl_example/imgui_impl_sdl.cpp +++ /dev/null @@ -1,277 +0,0 @@ -// ImGui SDL2 binding with OpenGL -// In this binding, ImTextureID is used to store an OpenGL 'GLuint' texture identifier. Read the FAQ about ImTextureID in imgui.cpp. - -// You can copy and use unmodified imgui_impl_* files in your project. See main.cpp for an example of using this. -// If you use this binding you'll need to call 4 functions: ImGui_ImplXXXX_Init(), ImGui_ImplXXXX_NewFrame(), ImGui::Render() and ImGui_ImplXXXX_Shutdown(). -// If you are new to ImGui, see examples/README.txt and documentation at the top of imgui.cpp. -// https://github.com/ocornut/imgui - -#include -#include -#include -#include -#include "imgui_impl_sdl.h" - -// Data -static double g_Time = 0.0f; -static bool g_MousePressed[3] = { false, false, false }; -static float g_MouseWheel = 0.0f; -static GLuint g_FontTexture = 0; - -// 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) -void ImGui_ImplSdl_RenderDrawLists(ImDrawData* draw_data) -{ - // Avoid rendering when minimized, scale coordinates for retina displays (screen coordinates != framebuffer coordinates) - ImGuiIO& io = ImGui::GetIO(); - int fb_width = (int)(io.DisplaySize.x * io.DisplayFramebufferScale.x); - int fb_height = (int)(io.DisplaySize.y * io.DisplayFramebufferScale.y); - if (fb_width == 0 || fb_height == 0) - return; - draw_data->ScaleClipRects(io.DisplayFramebufferScale); - - // We are using the OpenGL fixed pipeline to make the example code simpler to read! - // Setup render state: alpha-blending enabled, no face culling, no depth testing, scissor enabled, vertex/texcoord/color pointers. - GLint last_texture; glGetIntegerv(GL_TEXTURE_BINDING_2D, &last_texture); - GLint last_viewport[4]; glGetIntegerv(GL_VIEWPORT, last_viewport); - glPushAttrib(GL_ENABLE_BIT | GL_COLOR_BUFFER_BIT | GL_TRANSFORM_BIT); - glEnable(GL_BLEND); - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - glDisable(GL_CULL_FACE); - glDisable(GL_DEPTH_TEST); - glEnable(GL_SCISSOR_TEST); - glEnableClientState(GL_VERTEX_ARRAY); - glEnableClientState(GL_TEXTURE_COORD_ARRAY); - glEnableClientState(GL_COLOR_ARRAY); - glEnable(GL_TEXTURE_2D); - //glUseProgram(0); // You may want this if using this code in an OpenGL 3+ context - - // Setup viewport, orthographic projection matrix - glViewport(0, 0, (GLsizei)fb_width, (GLsizei)fb_height); - glMatrixMode(GL_PROJECTION); - glPushMatrix(); - glLoadIdentity(); - glOrtho(0.0f, io.DisplaySize.x, io.DisplaySize.y, 0.0f, -1.0f, +1.0f); - glMatrixMode(GL_MODELVIEW); - glPushMatrix(); - glLoadIdentity(); - - // Render command lists - #define OFFSETOF(TYPE, ELEMENT) ((size_t)&(((TYPE *)0)->ELEMENT)) - for (int n = 0; n < draw_data->CmdListsCount; n++) - { - const ImDrawList* cmd_list = draw_data->CmdLists[n]; - const unsigned char* vtx_buffer = (const unsigned char*)&cmd_list->VtxBuffer.front(); - const ImDrawIdx* idx_buffer = &cmd_list->IdxBuffer.front(); - glVertexPointer(2, GL_FLOAT, sizeof(ImDrawVert), (void*)(vtx_buffer + OFFSETOF(ImDrawVert, pos))); - glTexCoordPointer(2, GL_FLOAT, sizeof(ImDrawVert), (void*)(vtx_buffer + OFFSETOF(ImDrawVert, uv))); - glColorPointer(4, GL_UNSIGNED_BYTE, sizeof(ImDrawVert), (void*)(vtx_buffer + OFFSETOF(ImDrawVert, col))); - - for (int cmd_i = 0; cmd_i < cmd_list->CmdBuffer.size(); cmd_i++) - { - const ImDrawCmd* pcmd = &cmd_list->CmdBuffer[cmd_i]; - if (pcmd->UserCallback) - { - pcmd->UserCallback(cmd_list, pcmd); - } - else - { - glBindTexture(GL_TEXTURE_2D, (GLuint)(intptr_t)pcmd->TextureId); - glScissor((int)pcmd->ClipRect.x, (int)(fb_height - pcmd->ClipRect.w), (int)(pcmd->ClipRect.z - pcmd->ClipRect.x), (int)(pcmd->ClipRect.w - pcmd->ClipRect.y)); - glDrawElements(GL_TRIANGLES, (GLsizei)pcmd->ElemCount, sizeof(ImDrawIdx) == 2 ? GL_UNSIGNED_SHORT : GL_UNSIGNED_INT, idx_buffer); - } - idx_buffer += pcmd->ElemCount; - } - } - #undef OFFSETOF - - // Restore modified state - glDisableClientState(GL_COLOR_ARRAY); - glDisableClientState(GL_TEXTURE_COORD_ARRAY); - glDisableClientState(GL_VERTEX_ARRAY); - glBindTexture(GL_TEXTURE_2D, (GLuint)last_texture); - glMatrixMode(GL_MODELVIEW); - glPopMatrix(); - glMatrixMode(GL_PROJECTION); - glPopMatrix(); - glPopAttrib(); - glViewport(last_viewport[0], last_viewport[1], (GLsizei)last_viewport[2], (GLsizei)last_viewport[3]); -} - -static const char* ImGui_ImplSdl_GetClipboardText() -{ - return SDL_GetClipboardText(); -} - -static void ImGui_ImplSdl_SetClipboardText(const char* text) -{ - SDL_SetClipboardText(text); -} - -bool ImGui_ImplSdl_ProcessEvent(SDL_Event* event) -{ - ImGuiIO& io = ImGui::GetIO(); - switch (event->type) - { - case SDL_MOUSEWHEEL: - { - if (event->wheel.y > 0) - g_MouseWheel = 1; - if (event->wheel.y < 0) - g_MouseWheel = -1; - return true; - } - case SDL_MOUSEBUTTONDOWN: - { - if (event->button.button == SDL_BUTTON_LEFT) g_MousePressed[0] = true; - if (event->button.button == SDL_BUTTON_RIGHT) g_MousePressed[1] = true; - if (event->button.button == SDL_BUTTON_MIDDLE) g_MousePressed[2] = true; - return true; - } - case SDL_TEXTINPUT: - { - io.AddInputCharactersUTF8(event->text.text); - return true; - } - case SDL_KEYDOWN: - case SDL_KEYUP: - { - int key = event->key.keysym.sym & ~SDLK_SCANCODE_MASK; - io.KeysDown[key] = (event->type == SDL_KEYDOWN); - io.KeyShift = ((SDL_GetModState() & KMOD_SHIFT) != 0); - io.KeyCtrl = ((SDL_GetModState() & KMOD_CTRL) != 0); - io.KeyAlt = ((SDL_GetModState() & KMOD_ALT) != 0); - io.KeySuper = ((SDL_GetModState() & KMOD_GUI) != 0); - return true; - } - } - return false; -} - -bool ImGui_ImplSdl_CreateDeviceObjects() -{ - // Build texture atlas - ImGuiIO& io = ImGui::GetIO(); - unsigned char* pixels; - int width, height; - io.Fonts->GetTexDataAsAlpha8(&pixels, &width, &height); - - // Upload texture to graphics system - GLint last_texture; - glGetIntegerv(GL_TEXTURE_BINDING_2D, &last_texture); - glGenTextures(1, &g_FontTexture); - glBindTexture(GL_TEXTURE_2D, g_FontTexture); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - glPixelStorei(GL_UNPACK_ROW_LENGTH, 0); - glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, width, height, 0, GL_ALPHA, GL_UNSIGNED_BYTE, pixels); - - // Store our identifier - io.Fonts->TexID = (void *)(intptr_t)g_FontTexture; - - // Restore state - glBindTexture(GL_TEXTURE_2D, last_texture); - - return true; -} - -void ImGui_ImplSdl_InvalidateDeviceObjects() -{ - if (g_FontTexture) - { - glDeleteTextures(1, &g_FontTexture); - ImGui::GetIO().Fonts->TexID = 0; - g_FontTexture = 0; - } -} - -bool ImGui_ImplSdl_Init(SDL_Window* window) -{ - ImGuiIO& io = ImGui::GetIO(); - io.KeyMap[ImGuiKey_Tab] = SDLK_TAB; // Keyboard mapping. ImGui will use those indices to peek into the io.KeyDown[] array. - io.KeyMap[ImGuiKey_LeftArrow] = SDL_SCANCODE_LEFT; - io.KeyMap[ImGuiKey_RightArrow] = SDL_SCANCODE_RIGHT; - io.KeyMap[ImGuiKey_UpArrow] = SDL_SCANCODE_UP; - io.KeyMap[ImGuiKey_DownArrow] = SDL_SCANCODE_DOWN; - io.KeyMap[ImGuiKey_PageUp] = SDL_SCANCODE_PAGEUP; - io.KeyMap[ImGuiKey_PageDown] = SDL_SCANCODE_PAGEDOWN; - io.KeyMap[ImGuiKey_Home] = SDL_SCANCODE_HOME; - io.KeyMap[ImGuiKey_End] = SDL_SCANCODE_END; - io.KeyMap[ImGuiKey_Delete] = SDLK_DELETE; - io.KeyMap[ImGuiKey_Backspace] = SDLK_BACKSPACE; - io.KeyMap[ImGuiKey_Enter] = SDLK_RETURN; - io.KeyMap[ImGuiKey_Escape] = SDLK_ESCAPE; - io.KeyMap[ImGuiKey_A] = SDLK_a; - io.KeyMap[ImGuiKey_C] = SDLK_c; - io.KeyMap[ImGuiKey_V] = SDLK_v; - io.KeyMap[ImGuiKey_X] = SDLK_x; - io.KeyMap[ImGuiKey_Y] = SDLK_y; - io.KeyMap[ImGuiKey_Z] = SDLK_z; - - io.RenderDrawListsFn = ImGui_ImplSdl_RenderDrawLists; // Alternatively you can set this to NULL and call ImGui::GetDrawData() after ImGui::Render() to get the same ImDrawData pointer. - io.SetClipboardTextFn = ImGui_ImplSdl_SetClipboardText; - io.GetClipboardTextFn = ImGui_ImplSdl_GetClipboardText; - -#ifdef _WIN32 - SDL_SysWMinfo wmInfo; - SDL_VERSION(&wmInfo.version); - SDL_GetWindowWMInfo(window, &wmInfo); - io.ImeWindowHandle = wmInfo.info.win.window; -#else - (void)window; -#endif - - return true; -} - -void ImGui_ImplSdl_Shutdown() -{ - ImGui_ImplSdl_InvalidateDeviceObjects(); - ImGui::Shutdown(); -} - -void ImGui_ImplSdl_NewFrame(SDL_Window *window) -{ - if (!g_FontTexture) - ImGui_ImplSdl_CreateDeviceObjects(); - - ImGuiIO& io = ImGui::GetIO(); - - // Setup display size (every frame to accommodate for window resizing) - int w, h; - int display_w, display_h; - SDL_GetWindowSize(window, &w, &h); - SDL_GL_GetDrawableSize(window, &display_w, &display_h); - io.DisplaySize = ImVec2((float)w, (float)h); - io.DisplayFramebufferScale = ImVec2(w > 0 ? ((float)display_w / w) : 0, h > 0 ? ((float)display_h / h) : 0); - - // Setup time step - Uint32 time = SDL_GetTicks(); - double current_time = time / 1000.0; - io.DeltaTime = g_Time > 0.0 ? (float)(current_time - g_Time) : (float)(1.0f/60.0f); - g_Time = current_time; - - // Setup inputs - // (we already got mouse wheel, keyboard keys & characters from SDL_PollEvent()) - int mx, my; - Uint32 mouseMask = SDL_GetMouseState(&mx, &my); - if (SDL_GetWindowFlags(window) & SDL_WINDOW_MOUSE_FOCUS) - io.MousePos = ImVec2((float)mx, (float)my); // Mouse position, in pixels (set to -1,-1 if no mouse / on another screen, etc.) - else - io.MousePos = ImVec2(-1,-1); - - io.MouseDown[0] = g_MousePressed[0] || (mouseMask & SDL_BUTTON(SDL_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] = g_MousePressed[1] || (mouseMask & SDL_BUTTON(SDL_BUTTON_RIGHT)) != 0; - io.MouseDown[2] = g_MousePressed[2] || (mouseMask & SDL_BUTTON(SDL_BUTTON_MIDDLE)) != 0; - g_MousePressed[0] = g_MousePressed[1] = g_MousePressed[2] = false; - - io.MouseWheel = g_MouseWheel; - g_MouseWheel = 0.0f; - - // Hide OS mouse cursor if ImGui is drawing it - SDL_ShowCursor(io.MouseDrawCursor ? 0 : 1); - - // Start the frame - ImGui::NewFrame(); -} diff --git a/examples/sdl_opengl_example/imgui_impl_sdl.h b/examples/sdl_opengl_example/imgui_impl_sdl.h deleted file mode 100644 index a322bf2..0000000 --- a/examples/sdl_opengl_example/imgui_impl_sdl.h +++ /dev/null @@ -1,19 +0,0 @@ -// ImGui SDL2 binding with OpenGL -// In this binding, ImTextureID is used to store an OpenGL 'GLuint' texture identifier. Read the FAQ about ImTextureID in imgui.cpp. - -// You can copy and use unmodified imgui_impl_* files in your project. See main.cpp for an example of using this. -// If you use this binding you'll need to call 4 functions: ImGui_ImplXXXX_Init(), ImGui_ImplXXXX_NewFrame(), ImGui::Render() and ImGui_ImplXXXX_Shutdown(). -// If you are new to ImGui, see examples/README.txt and documentation at the top of imgui.cpp. -// https://github.com/ocornut/imgui - -struct SDL_Window; -typedef union SDL_Event SDL_Event; - -IMGUI_API bool ImGui_ImplSdl_Init(SDL_Window* window); -IMGUI_API void ImGui_ImplSdl_Shutdown(); -IMGUI_API void ImGui_ImplSdl_NewFrame(SDL_Window* window); -IMGUI_API bool ImGui_ImplSdl_ProcessEvent(SDL_Event* event); - -// Use if you want to reset your rendering device without losing ImGui state. -IMGUI_API void ImGui_ImplSdl_InvalidateDeviceObjects(); -IMGUI_API bool ImGui_ImplSdl_CreateDeviceObjects(); diff --git a/examples/sdl_opengl_example/main.cpp b/examples/sdl_opengl_example/main.cpp deleted file mode 100644 index f42e7fa..0000000 --- a/examples/sdl_opengl_example/main.cpp +++ /dev/null @@ -1,103 +0,0 @@ -// ImGui - standalone example application for SDL2 + OpenGL -// If you are new to ImGui, see examples/README.txt and documentation at the top of imgui.cpp. - -#include -#include "imgui_impl_sdl.h" -#include -#include -#include - -int main(int, char**) -{ - // Setup SDL - if (SDL_Init(SDL_INIT_VIDEO|SDL_INIT_TIMER) != 0) - { - printf("Error: %s\n", SDL_GetError()); - return -1; - } - - // Setup window - SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1); - SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 24); - SDL_GL_SetAttribute(SDL_GL_STENCIL_SIZE, 8); - SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 2); - SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 2); - SDL_DisplayMode current; - SDL_GetCurrentDisplayMode(0, ¤t); - SDL_Window *window = SDL_CreateWindow("ImGui SDL2+OpenGL example", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, 1280, 720, SDL_WINDOW_OPENGL|SDL_WINDOW_RESIZABLE); - SDL_GLContext glcontext = SDL_GL_CreateContext(window); - - // Setup ImGui binding - ImGui_ImplSdl_Init(window); - - // Load Fonts - // (there is a default font, this is only if you want to change it. see extra_fonts/README.txt for more details) - //ImGuiIO& io = ImGui::GetIO(); - //io.Fonts->AddFontDefault(); - //io.Fonts->AddFontFromFileTTF("../../extra_fonts/Cousine-Regular.ttf", 15.0f); - //io.Fonts->AddFontFromFileTTF("../../extra_fonts/DroidSans.ttf", 16.0f); - //io.Fonts->AddFontFromFileTTF("../../extra_fonts/ProggyClean.ttf", 13.0f); - //io.Fonts->AddFontFromFileTTF("../../extra_fonts/ProggyTiny.ttf", 10.0f); - //io.Fonts->AddFontFromFileTTF("c:\\Windows\\Fonts\\ArialUni.ttf", 18.0f, NULL, io.Fonts->GetGlyphRangesJapanese()); - - bool show_test_window = true; - bool show_another_window = false; - ImVec4 clear_color = ImColor(114, 144, 154); - - // Main loop - bool done = false; - while (!done) - { - SDL_Event event; - while (SDL_PollEvent(&event)) - { - ImGui_ImplSdl_ProcessEvent(&event); - if (event.type == SDL_QUIT) - done = true; - } - ImGui_ImplSdl_NewFrame(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" - { - static float f = 0.0f; - ImGui::Text("Hello, world!"); - ImGui::SliderFloat("float", &f, 0.0f, 1.0f); - ImGui::ColorEdit3("clear color", (float*)&clear_color); - if (ImGui::Button("Test Window")) show_test_window ^= 1; - if (ImGui::Button("Another Window")) show_another_window ^= 1; - ImGui::Text("Application average %.3f ms/frame (%.1f FPS)", 1000.0f / ImGui::GetIO().Framerate, ImGui::GetIO().Framerate); - } - - // 2. Show another simple window, this time using an explicit Begin/End pair - if (show_another_window) - { - ImGui::SetNextWindowSize(ImVec2(200,100), ImGuiSetCond_FirstUseEver); - ImGui::Begin("Another Window", &show_another_window); - 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::SetNextWindowPos(ImVec2(650, 20), ImGuiSetCond_FirstUseEver); - ImGui::ShowTestWindow(&show_test_window); - } - - // Rendering - glViewport(0, 0, (int)ImGui::GetIO().DisplaySize.x, (int)ImGui::GetIO().DisplaySize.y); - glClearColor(clear_color.x, clear_color.y, clear_color.z, clear_color.w); - glClear(GL_COLOR_BUFFER_BIT); - ImGui::Render(); - SDL_GL_SwapWindow(window); - } - - // Cleanup - ImGui_ImplSdl_Shutdown(); - SDL_GL_DeleteContext(glcontext); - SDL_DestroyWindow(window); - SDL_Quit(); - - return 0; -} diff --git a/imgui.cpp b/imgui.cpp index a8cddc6..a52903e 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -80,7 +80,7 @@ - read the FAQ below this section! - your code creates the UI, if your code doesn't run the UI is gone! == very dynamic UI, no construction/destructions steps, less data retention on your side, no state duplication, less sync, less bugs. - call and read ImGui::ShowTestWindow() for demo code demonstrating most features. - - see examples/ folder for standalone sample applications. Prefer reading examples/opengl_example/ first as it is the simplest. + - see examples/ folder for standalone sample applications. Prefer reading examples/opengl2_example/ first as it is the simplest. you may be able to grab and copy a ready made imgui_impl_*** file from the examples/. - customization: PushStyleColor()/PushStyleVar() or the style editor to tweak the look of the interface (e.g. if you want a more compact UI or a different color scheme).