diff --git a/docs/CHANGELOG.txt b/docs/CHANGELOG.txt index 53f1b2ae..ad43c685 100644 --- a/docs/CHANGELOG.txt +++ b/docs/CHANGELOG.txt @@ -112,8 +112,11 @@ Other Changes: GL function loaders early, and help users understand what they are missing. (#2421) - Examples: OpenGL3: Minor tweaks + not calling glBindBuffer more than necessary in the render loop. - Examples: Vulkan: Added missing support for 32-bit indices (#define ImDrawIdx unsigned int). +- Examples: Vulkan: Avoid passing negative coordinates to vkCmdSetScissor, which debug validation layers do not like. - Examples: DirectX9: Fixed erroneous assert in ImGui_ImplDX9_InvalidateDeviceObjects(). (#2454) -- Examples: FreeGLUT: Made io.DeltaTime always > 0. (#2430) +- Examples: GLUT: Fixed existing FreeGLUT example to work with regular GLUT. (#2465) [@andrewwillmott] +- Examples: GLUT: Renamed imgui_impl_freeglut.cpp/.h to imgui_impl_glut.cpp/.h. (#2465) [@andrewwillmott] +- Examples: GLUT: Made io.DeltaTime always > 0. (#2430) ----------------------------------------------------------------------- diff --git a/docs/README.md b/docs/README.md index 1a70ebf3..febacf05 100644 --- a/docs/README.md +++ b/docs/README.md @@ -134,7 +134,7 @@ Languages: (third-party bindings) Frameworks: - Renderers: DirectX 9/10/11/12, Metal, OpenGL2, OpenGL3+/ES2/ES3, Vulkan: [examples/](https://github.com/ocornut/imgui/tree/master/examples) -- Platform: GLFW, SDL, Win32, OSX, Freeglut: [examples/](https://github.com/ocornut/imgui/tree/master/examples) +- Platform: GLFW, SDL, Win32, OSX, GLUT: [examples/](https://github.com/ocornut/imgui/tree/master/examples) - Framework: Allegro 5, Marmalade: [examples/](https://github.com/ocornut/imgui/tree/master/examples) - Unmerged PR: SDL2 + OpenGLES + Emscripten: [#336](https://github.com/ocornut/imgui/pull/336) - Unmerged PR: Android: [#421](https://github.com/ocornut/imgui/pull/421) diff --git a/examples/.gitignore b/examples/.gitignore index b9e1bb62..428ea446 100644 --- a/examples/.gitignore +++ b/examples/.gitignore @@ -33,6 +33,7 @@ example_glfw_opengl2/example_glfw_opengl2 example_glfw_opengl3/example_glfw_opengl3 example_sdl_opengl2/example_sdl_opengl2 example_sdl_opengl3/example_sdl_opengl3 +example_glut_opengl2/example_glut_opengl2 ## Dear ImGui Ini files imgui.ini diff --git a/examples/README.txt b/examples/README.txt index 1712e283..0a870750 100644 --- a/examples/README.txt +++ b/examples/README.txt @@ -111,7 +111,7 @@ List of Platforms Bindings in this repository: imgui_impl_osx.mm ; macOS native API imgui_impl_sdl.cpp ; SDL2 (Windows, macOS, Linux, iOS, Android) https://www.libsdl.org imgui_impl_win32.cpp ; Win32 native API (Windows) - imgui_impl_freeglut.cpp ; FreeGLUT (if you really miss the 90's) + imgui_impl_glut.cpp ; GLUT/FreeGLUT (not recommended unless really miss the 90's) List of Renderer Bindings in this repository: @@ -230,9 +230,9 @@ example_allegro5/ Allegro 5 example. = main.cpp + imgui_impl_allegro5.cpp -example_freeglut_opengl2/ - FreeGLUT + OpenGL2. - = main.cpp + imgui_impl_freeglut.cpp + imgui_impl_opengl2.cpp +example_glut_opengl2/ + GLUT (e.g., FreeGLUT on Linux/Windows, GLUT framework on OSX) + OpenGL2. + = main.cpp + imgui_impl_glut.cpp + imgui_impl_opengl2.cpp example_marmalade/ Marmalade example using IwGx. diff --git a/examples/example_glfw_vulkan/glsl_shader.frag b/examples/example_glfw_vulkan/glsl_shader.frag index 313a8880..ce7e6f72 100644 --- a/examples/example_glfw_vulkan/glsl_shader.frag +++ b/examples/example_glfw_vulkan/glsl_shader.frag @@ -3,7 +3,7 @@ layout(location = 0) out vec4 fColor; layout(set=0, binding=0) uniform sampler2D sTexture; -layout(location = 0) in struct{ +layout(location = 0) in struct { vec4 Color; vec2 UV; } In; diff --git a/examples/example_glfw_vulkan/glsl_shader.vert b/examples/example_glfw_vulkan/glsl_shader.vert index 20b29082..9425365a 100644 --- a/examples/example_glfw_vulkan/glsl_shader.vert +++ b/examples/example_glfw_vulkan/glsl_shader.vert @@ -3,16 +3,16 @@ layout(location = 0) in vec2 aPos; layout(location = 1) in vec2 aUV; layout(location = 2) in vec4 aColor; -layout(push_constant) uniform uPushConstant{ +layout(push_constant) uniform uPushConstant { vec2 uScale; vec2 uTranslate; } pc; -out gl_PerVertex{ +out gl_PerVertex { vec4 gl_Position; }; -layout(location = 0) out struct{ +layout(location = 0) out struct { vec4 Color; vec2 UV; } Out; @@ -21,5 +21,5 @@ void main() { Out.Color = aColor; Out.UV = aUV; - gl_Position = vec4(aPos*pc.uScale+pc.uTranslate, 0, 1); + gl_Position = vec4(aPos * pc.uScale + pc.uTranslate, 0, 1); } diff --git a/examples/example_glfw_vulkan/main.cpp b/examples/example_glfw_vulkan/main.cpp index 74edf5d9..6f2c4cd6 100644 --- a/examples/example_glfw_vulkan/main.cpp +++ b/examples/example_glfw_vulkan/main.cpp @@ -233,77 +233,77 @@ static void CleanupVulkan() static void FrameRender(ImGui_ImplVulkanH_WindowData* wd) { - VkResult err; + VkResult err; - VkSemaphore& image_acquired_semaphore = wd->Frames[wd->FrameIndex].ImageAcquiredSemaphore; - err = vkAcquireNextImageKHR(g_Device, wd->Swapchain, UINT64_MAX, image_acquired_semaphore, VK_NULL_HANDLE, &wd->FrameIndex); - check_vk_result(err); + VkSemaphore& image_acquired_semaphore = wd->Frames[wd->FrameIndex].ImageAcquiredSemaphore; + err = vkAcquireNextImageKHR(g_Device, wd->Swapchain, UINT64_MAX, image_acquired_semaphore, VK_NULL_HANDLE, &wd->FrameIndex); + check_vk_result(err); ImGui_ImplVulkanH_FrameData* fd = &wd->Frames[wd->FrameIndex]; { - err = vkWaitForFences(g_Device, 1, &fd->Fence, VK_TRUE, UINT64_MAX); // wait indefinitely instead of periodically checking - check_vk_result(err); + err = vkWaitForFences(g_Device, 1, &fd->Fence, VK_TRUE, UINT64_MAX); // wait indefinitely instead of periodically checking + check_vk_result(err); - err = vkResetFences(g_Device, 1, &fd->Fence); - check_vk_result(err); - } - { - err = vkResetCommandPool(g_Device, fd->CommandPool, 0); - check_vk_result(err); - VkCommandBufferBeginInfo info = {}; - info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO; - info.flags |= VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT; - err = vkBeginCommandBuffer(fd->CommandBuffer, &info); - check_vk_result(err); - } - { - VkRenderPassBeginInfo info = {}; - info.sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO; - info.renderPass = wd->RenderPass; - info.framebuffer = wd->Framebuffer[wd->FrameIndex]; - info.renderArea.extent.width = wd->Width; - info.renderArea.extent.height = wd->Height; - info.clearValueCount = 1; - info.pClearValues = &wd->ClearValue; - vkCmdBeginRenderPass(fd->CommandBuffer, &info, VK_SUBPASS_CONTENTS_INLINE); - } + err = vkResetFences(g_Device, 1, &fd->Fence); + check_vk_result(err); + } + { + err = vkResetCommandPool(g_Device, fd->CommandPool, 0); + check_vk_result(err); + VkCommandBufferBeginInfo info = {}; + info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO; + info.flags |= VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT; + err = vkBeginCommandBuffer(fd->CommandBuffer, &info); + check_vk_result(err); + } + { + VkRenderPassBeginInfo info = {}; + info.sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO; + info.renderPass = wd->RenderPass; + info.framebuffer = wd->Framebuffer[wd->FrameIndex]; + info.renderArea.extent.width = wd->Width; + info.renderArea.extent.height = wd->Height; + info.clearValueCount = 1; + info.pClearValues = &wd->ClearValue; + vkCmdBeginRenderPass(fd->CommandBuffer, &info, VK_SUBPASS_CONTENTS_INLINE); + } - // Record Imgui Draw Data and draw funcs into command buffer - ImGui_ImplVulkan_RenderDrawData(ImGui::GetDrawData(), fd->CommandBuffer); + // Record Imgui Draw Data and draw funcs into command buffer + ImGui_ImplVulkan_RenderDrawData(ImGui::GetDrawData(), fd->CommandBuffer); - // Submit command buffer - vkCmdEndRenderPass(fd->CommandBuffer); - { - VkPipelineStageFlags wait_stage = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT; - VkSubmitInfo info = {}; - info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO; - info.waitSemaphoreCount = 1; - info.pWaitSemaphores = &image_acquired_semaphore; - info.pWaitDstStageMask = &wait_stage; - info.commandBufferCount = 1; - info.pCommandBuffers = &fd->CommandBuffer; - info.signalSemaphoreCount = 1; - info.pSignalSemaphores = &fd->RenderCompleteSemaphore; + // Submit command buffer + vkCmdEndRenderPass(fd->CommandBuffer); + { + VkPipelineStageFlags wait_stage = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT; + VkSubmitInfo info = {}; + info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO; + info.waitSemaphoreCount = 1; + info.pWaitSemaphores = &image_acquired_semaphore; + info.pWaitDstStageMask = &wait_stage; + info.commandBufferCount = 1; + info.pCommandBuffers = &fd->CommandBuffer; + info.signalSemaphoreCount = 1; + info.pSignalSemaphores = &fd->RenderCompleteSemaphore; - err = vkEndCommandBuffer(fd->CommandBuffer); - check_vk_result(err); - err = vkQueueSubmit(g_Queue, 1, &info, fd->Fence); - check_vk_result(err); - } + err = vkEndCommandBuffer(fd->CommandBuffer); + check_vk_result(err); + err = vkQueueSubmit(g_Queue, 1, &info, fd->Fence); + check_vk_result(err); + } } static void FramePresent(ImGui_ImplVulkanH_WindowData* wd) { ImGui_ImplVulkanH_FrameData* fd = &wd->Frames[wd->FrameIndex]; - VkPresentInfoKHR info = {}; - info.sType = VK_STRUCTURE_TYPE_PRESENT_INFO_KHR; - info.waitSemaphoreCount = 1; - info.pWaitSemaphores = &fd->RenderCompleteSemaphore; - info.swapchainCount = 1; - info.pSwapchains = &wd->Swapchain; - info.pImageIndices = &wd->FrameIndex; - VkResult err = vkQueuePresentKHR(g_Queue, &info); - check_vk_result(err); + VkPresentInfoKHR info = {}; + info.sType = VK_STRUCTURE_TYPE_PRESENT_INFO_KHR; + info.waitSemaphoreCount = 1; + info.pWaitSemaphores = &fd->RenderCompleteSemaphore; + info.swapchainCount = 1; + info.pSwapchains = &wd->Swapchain; + info.pImageIndices = &wd->FrameIndex; + VkResult err = vkQueuePresentKHR(g_Queue, &info); + check_vk_result(err); } static void glfw_error_callback(int error, const char* description) @@ -315,12 +315,12 @@ static void glfw_resize_callback(GLFWwindow*, int w, int h) { g_ResizeWanted = true; g_ResizeWidth = w; - g_ResizeHeight = h; + g_ResizeHeight = h; } int main(int, char**) { - // Setup window + // Setup window glfwSetErrorCallback(glfw_error_callback); if (!glfwInit()) return 1; @@ -445,11 +445,11 @@ int main(int, char**) // - When io.WantCaptureKeyboard is true, do not dispatch keyboard input data to your main application. // Generally you may always pass all inputs to dear imgui, and hide them from your application based on those two flags. glfwPollEvents(); - if (g_ResizeWanted) - { - ImGui_ImplVulkanH_CreateWindowDataSwapChainAndFramebuffer(g_PhysicalDevice, g_Device, &g_WindowData, g_Allocator, g_ResizeWidth, g_ResizeHeight); - g_ResizeWanted = false; - } + if (g_ResizeWanted) + { + ImGui_ImplVulkanH_CreateWindowDataSwapChainAndFramebuffer(g_PhysicalDevice, g_Device, &g_WindowData, g_Allocator, g_ResizeWidth, g_ResizeHeight); + g_ResizeWanted = false; + } // Start the Dear ImGui frame ImGui_ImplVulkan_NewFrame(); @@ -496,7 +496,7 @@ int main(int, char**) // Rendering ImGui::Render(); memcpy(&wd->ClearValue.color.float32[0], &clear_color, 4 * sizeof(float)); - FrameRender(wd); + FrameRender(wd); // Update and Render additional Platform Windows if (io.ConfigFlags & ImGuiConfigFlags_ViewportsEnable) diff --git a/examples/example_glut_opengl2/Makefile b/examples/example_glut_opengl2/Makefile new file mode 100644 index 00000000..25ddc43a --- /dev/null +++ b/examples/example_glut_opengl2/Makefile @@ -0,0 +1,65 @@ +# +# Cross Platform Makefile +# Compatible with Ubuntu 14.04.1 and Mac OS X +# +# Linux: +# apt-get install freeglut3-dev +# + +#CXX = g++ +#CXX = clang++ + +EXE = example_glut_opengl2 +SOURCES = main.cpp +SOURCES += ../imgui_impl_glut.cpp ../imgui_impl_opengl2.cpp +SOURCES += ../../imgui.cpp ../../imgui_demo.cpp ../../imgui_draw.cpp ../../imgui_widgets.cpp +OBJS = $(addsuffix .o, $(basename $(notdir $(SOURCES)))) + +UNAME_S := $(shell uname -s) + + +ifeq ($(UNAME_S), Linux) #LINUX + ECHO_MESSAGE = "Linux" + LIBS = -lGL -lglut + + CXXFLAGS = -I ../ -I../.. + CXXFLAGS += -Wall -Wformat + CFLAGS = $(CXXFLAGS) +endif + +ifeq ($(UNAME_S), Darwin) #APPLE + ECHO_MESSAGE = "Mac OS X" + LIBS = -framework OpenGL -framework GLUT + + CXXFLAGS = -I .. -I../.. + CXXFLAGS += -Wall -Wformat + CFLAGS = $(CXXFLAGS) +endif + +ifeq ($(findstring MINGW,$(UNAME_S)),MINGW) + ECHO_MESSAGE = "Windows" + LIBS = -lgdi32 -lopengl32 -limm32 -lglut + + CXXFLAGS = -I ../ -I../../ + CXXFLAGS += -Wall -Wformat + CFLAGS = $(CXXFLAGS) +endif + + +%.o:%.cpp + $(CXX) $(CXXFLAGS) -c -o $@ $< + +%.o:../%.cpp + $(CXX) $(CXXFLAGS) -c -o $@ $< + +%.o:../../%.cpp + $(CXX) $(CXXFLAGS) -c -o $@ $< + +all: $(EXE) + @echo Build complete for $(ECHO_MESSAGE) + +$(EXE): $(OBJS) + $(CXX) -o $@ $^ $(CXXFLAGS) $(LIBS) + +clean: + rm -f $(EXE) $(OBJS) diff --git a/examples/example_freeglut_opengl2/example_freeglut_opengl2.vcxproj b/examples/example_glut_opengl2/example_glut_opengl2.vcxproj similarity index 98% rename from examples/example_freeglut_opengl2/example_freeglut_opengl2.vcxproj rename to examples/example_glut_opengl2/example_glut_opengl2.vcxproj index e3bd4176..58599e6d 100644 --- a/examples/example_freeglut_opengl2/example_freeglut_opengl2.vcxproj +++ b/examples/example_glut_opengl2/example_glut_opengl2.vcxproj @@ -20,7 +20,7 @@ {F90D0333-5FB1-440D-918D-DD39A1B5187E} - example_freeglut_opengl2 + example_glut_opengl2 @@ -154,7 +154,7 @@ - + @@ -162,7 +162,7 @@ - + @@ -172,4 +172,4 @@ - \ No newline at end of file + diff --git a/examples/example_freeglut_opengl2/example_freeglut_opengl2.vcxproj.filters b/examples/example_glut_opengl2/example_glut_opengl2.vcxproj.filters similarity index 93% rename from examples/example_freeglut_opengl2/example_freeglut_opengl2.vcxproj.filters rename to examples/example_glut_opengl2/example_glut_opengl2.vcxproj.filters index eb6d8526..290d43d7 100644 --- a/examples/example_freeglut_opengl2/example_freeglut_opengl2.vcxproj.filters +++ b/examples/example_glut_opengl2/example_glut_opengl2.vcxproj.filters @@ -22,7 +22,7 @@ imgui - + sources @@ -42,7 +42,7 @@ imgui - + sources @@ -55,4 +55,4 @@ sources - \ No newline at end of file + diff --git a/examples/example_freeglut_opengl2/main.cpp b/examples/example_glut_opengl2/main.cpp similarity index 89% rename from examples/example_freeglut_opengl2/main.cpp rename to examples/example_glut_opengl2/main.cpp index 41d9bff6..52b10a94 100644 --- a/examples/example_freeglut_opengl2/main.cpp +++ b/examples/example_glut_opengl2/main.cpp @@ -1,13 +1,17 @@ -// dear imgui: standalone example application for FreeGLUT + OpenGL2, using legacy fixed pipeline +// dear imgui: standalone example application for GLUT/FreeGLUT + OpenGL2, using legacy fixed pipeline // If you are new to dear imgui, see examples/README.txt and documentation at the top of imgui.cpp. -// !!! GLUT IS OBSOLETE SOFTWARE. Using GLUT is not recommended unless you really miss the 90's. !!! +// !!! GLUT/FreeGLUT IS OBSOLETE SOFTWARE. Using GLUT is not recommended unless you really miss the 90's. !!! // !!! If someone or something is teaching you GLUT in 2019, you are being abused. Please show some resistance. !!! #include "imgui.h" -#include "../imgui_impl_freeglut.h" +#include "../imgui_impl_glut.h" #include "../imgui_impl_opengl2.h" -#include +#ifdef __APPLE__ + #include +#else + #include +#endif #ifdef _MSC_VER #pragma warning (disable: 4505) // unreferenced local function has been removed @@ -61,7 +65,7 @@ void glut_display_func() { // Start the Dear ImGui frame ImGui_ImplOpenGL2_NewFrame(); - ImGui_ImplFreeGLUT_NewFrame(); + ImGui_ImplGLUT_NewFrame(); my_display_code(); @@ -87,14 +91,16 @@ int main(int argc, char** argv) { // Create GLUT window glutInit(&argc, argv); +#ifdef __FREEGLUT_EXT_H__ glutSetOption(GLUT_ACTION_ON_WINDOW_CLOSE, GLUT_ACTION_GLUTMAINLOOP_RETURNS); +#endif glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE | GLUT_MULTISAMPLE); glutInitWindowSize(1280, 720); - glutCreateWindow("Dear ImGui FreeGLUT+OpenGL2 Example"); + glutCreateWindow("Dear ImGui GLUT+OpenGL2 Example"); // Setup GLUT display function - // We will also call ImGui_ImplFreeGLUT_InstallFuncs() to get all the other functions installed for us, - // otherwise it is possible to install our own functions and call the imgui_impl_freeglut.h functions ourselves. + // We will also call ImGui_ImplGLUT_InstallFuncs() to get all the other functions installed for us, + // otherwise it is possible to install our own functions and call the imgui_impl_glut.h functions ourselves. glutDisplayFunc(glut_display_func); // Setup Dear ImGui context @@ -108,8 +114,8 @@ int main(int argc, char** argv) //ImGui::StyleColorsClassic(); // Setup Platform/Renderer bindings - ImGui_ImplFreeGLUT_Init(); - ImGui_ImplFreeGLUT_InstallFuncs(); + ImGui_ImplGLUT_Init(); + ImGui_ImplGLUT_InstallFuncs(); ImGui_ImplOpenGL2_Init(); // Load Fonts @@ -131,7 +137,7 @@ int main(int argc, char** argv) // Cleanup ImGui_ImplOpenGL2_Shutdown(); - ImGui_ImplFreeGLUT_Shutdown(); + ImGui_ImplGLUT_Shutdown(); ImGui::DestroyContext(); return 0; diff --git a/examples/example_sdl_vulkan/main.cpp b/examples/example_sdl_vulkan/main.cpp index b5d32bb9..42ab4a6b 100644 --- a/examples/example_sdl_vulkan/main.cpp +++ b/examples/example_sdl_vulkan/main.cpp @@ -223,18 +223,18 @@ static void CleanupVulkan() static void FrameRender(ImGui_ImplVulkanH_WindowData* wd) { - VkResult err; + VkResult err; - VkSemaphore& image_acquired_semaphore = wd->Frames[wd->FrameIndex].ImageAcquiredSemaphore; - err = vkAcquireNextImageKHR(g_Device, wd->Swapchain, UINT64_MAX, image_acquired_semaphore, VK_NULL_HANDLE, &wd->FrameIndex); - check_vk_result(err); + VkSemaphore& image_acquired_semaphore = wd->Frames[wd->FrameIndex].ImageAcquiredSemaphore; + err = vkAcquireNextImageKHR(g_Device, wd->Swapchain, UINT64_MAX, image_acquired_semaphore, VK_NULL_HANDLE, &wd->FrameIndex); + check_vk_result(err); ImGui_ImplVulkanH_FrameData* fd = &wd->Frames[wd->FrameIndex]; { - err = vkWaitForFences(g_Device, 1, &fd->Fence, VK_TRUE, UINT64_MAX); // wait indefinitely instead of periodically checking + err = vkWaitForFences(g_Device, 1, &fd->Fence, VK_TRUE, UINT64_MAX); // wait indefinitely instead of periodically checking check_vk_result(err); - err = vkResetFences(g_Device, 1, &fd->Fence); + err = vkResetFences(g_Device, 1, &fd->Fence); check_vk_result(err); } { @@ -250,7 +250,7 @@ static void FrameRender(ImGui_ImplVulkanH_WindowData* wd) VkRenderPassBeginInfo info = {}; info.sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO; info.renderPass = wd->RenderPass; - info.framebuffer = wd->Framebuffer[wd->FrameIndex]; + info.framebuffer = wd->Framebuffer[wd->FrameIndex]; info.renderArea.extent.width = wd->Width; info.renderArea.extent.height = wd->Height; info.clearValueCount = 1; @@ -258,17 +258,17 @@ static void FrameRender(ImGui_ImplVulkanH_WindowData* wd) vkCmdBeginRenderPass(fd->CommandBuffer, &info, VK_SUBPASS_CONTENTS_INLINE); } - // Record Imgui Draw Data and draw funcs into command buffer - ImGui_ImplVulkan_RenderDrawData(ImGui::GetDrawData(), fd->CommandBuffer); + // Record Imgui Draw Data and draw funcs into command buffer + ImGui_ImplVulkan_RenderDrawData(ImGui::GetDrawData(), fd->CommandBuffer); - // Submit command buffer + // Submit command buffer vkCmdEndRenderPass(fd->CommandBuffer); { VkPipelineStageFlags wait_stage = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT; VkSubmitInfo info = {}; info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO; info.waitSemaphoreCount = 1; - info.pWaitSemaphores = &image_acquired_semaphore; + info.pWaitSemaphores = &image_acquired_semaphore; info.pWaitDstStageMask = &wait_stage; info.commandBufferCount = 1; info.pCommandBuffers = &fd->CommandBuffer; @@ -291,8 +291,8 @@ static void FramePresent(ImGui_ImplVulkanH_WindowData* wd) info.pWaitSemaphores = &fd->RenderCompleteSemaphore; info.swapchainCount = 1; info.pSwapchains = &wd->Swapchain; - info.pImageIndices = &wd->FrameIndex; - VkResult err = vkQueuePresentKHR(g_Queue, &info); + info.pImageIndices = &wd->FrameIndex; + VkResult err = vkQueuePresentKHR(g_Queue, &info); check_vk_result(err); } @@ -482,7 +482,7 @@ int main(int, char**) // Rendering ImGui::Render(); memcpy(&wd->ClearValue.color.float32[0], &clear_color, 4 * sizeof(float)); - FrameRender(wd); + FrameRender(wd); // Update and Render additional Platform Windows if (io.ConfigFlags & ImGuiConfigFlags_ViewportsEnable) diff --git a/examples/imgui_impl_freeglut.h b/examples/imgui_impl_freeglut.h deleted file mode 100644 index 6d565ec6..00000000 --- a/examples/imgui_impl_freeglut.h +++ /dev/null @@ -1,33 +0,0 @@ -// dear imgui: Platform Binding for FreeGLUT -// This needs to be used along with a Renderer (e.g. OpenGL2) - -// !!! GLUT IS OBSOLETE SOFTWARE. Using GLUT is not recommended unless you really miss the 90's. !!! -// !!! If someone or something is teaching you GLUT in 2019, you are being abused. Please show some resistance. !!! - -// Issues: -// [ ] Platform: GLUT is unable to distinguish e.g. Backspace from CTRL+H or TAB from CTRL+I -// [ ] Platform: Missing clipboard support (not supported by Glut). -// [ ] Platform: Missing gamepad support. - -// You can copy and use unmodified imgui_impl_* files in your project. See main.cpp for an example of using this. -// If you are new to dear imgui, read examples/README.txt and read the documentation at the top of imgui.cpp. -// https://github.com/ocornut/imgui - -#pragma once - -IMGUI_IMPL_API bool ImGui_ImplFreeGLUT_Init(); -IMGUI_IMPL_API void ImGui_ImplFreeGLUT_InstallFuncs(); -IMGUI_IMPL_API void ImGui_ImplFreeGLUT_Shutdown(); -IMGUI_IMPL_API void ImGui_ImplFreeGLUT_NewFrame(); - -// You can call ImGui_ImplFreeGLUT_InstallFuncs() to get all those functions installed automatically, -// or call them yourself from your own GLUT handlers. We are using the same weird names as GLUT for consistency.. -//---------------------------------------- GLUT name --------------------------------------------- Decent Name --------- -IMGUI_IMPL_API void ImGui_ImplFreeGLUT_ReshapeFunc(int w, int h); // ~ ResizeFunc -IMGUI_IMPL_API void ImGui_ImplFreeGLUT_MotionFunc(int x, int y); // ~ MouseMoveFunc -IMGUI_IMPL_API void ImGui_ImplFreeGLUT_MouseFunc(int button, int state, int x, int y); // ~ MouseButtonFunc -IMGUI_IMPL_API void ImGui_ImplFreeGLUT_MouseWheelFunc(int button, int dir, int x, int y); // ~ MouseWheelFunc -IMGUI_IMPL_API void ImGui_ImplFreeGLUT_KeyboardFunc(unsigned char c, int x, int y); // ~ CharPressedFunc -IMGUI_IMPL_API void ImGui_ImplFreeGLUT_KeyboardUpFunc(unsigned char c, int x, int y); // ~ CharReleasedFunc -IMGUI_IMPL_API void ImGui_ImplFreeGLUT_SpecialFunc(int key, int x, int y); // ~ KeyPressedFunc -IMGUI_IMPL_API void ImGui_ImplFreeGLUT_SpecialUpFunc(int key, int x, int y); // ~ KeyReleasedFunc diff --git a/examples/imgui_impl_freeglut.cpp b/examples/imgui_impl_glut.cpp similarity index 75% rename from examples/imgui_impl_freeglut.cpp rename to examples/imgui_impl_glut.cpp index 32671a6d..d8bd7498 100644 --- a/examples/imgui_impl_freeglut.cpp +++ b/examples/imgui_impl_glut.cpp @@ -1,7 +1,7 @@ -// dear imgui: Platform Binding for FreeGLUT +// dear imgui: Platform Binding for GLUT/FreeGLUT // This needs to be used along with a Renderer (e.g. OpenGL2) -// !!! GLUT IS OBSOLETE SOFTWARE. Using GLUT is not recommended unless you really miss the 90's. !!! +// !!! GLUT/FreeGLUT IS OBSOLETE SOFTWARE. Using GLUT is not recommended unless you really miss the 90's. !!! // !!! If someone or something is teaching you GLUT in 2019, you are being abused. Please show some resistance. !!! // Issues: @@ -15,13 +15,18 @@ // CHANGELOG // (minor and older changes stripped away, please see git history for details) +// 2019-04-03: Misc: Renamed imgui_impl_freeglut.cpp/.h to imgui_impl_glut.cpp/.h. // 2019-03-25: Misc: Made io.DeltaTime always above zero. // 2018-11-30: Misc: Setting up io.BackendPlatformName so it can be displayed in the About Window. -// 2018-03-22: Added FreeGLUT Platform binding. +// 2018-03-22: Added GLUT Platform binding. #include "imgui.h" -#include "imgui_impl_freeglut.h" -#include +#include "imgui_impl_glut.h" +#ifdef __APPLE__ + #include +#else + #include +#endif #ifdef _MSC_VER #pragma warning (disable: 4505) // unreferenced local function has been removed (stb stuff) @@ -29,10 +34,10 @@ static int g_Time = 0; // Current time, in milliseconds -bool ImGui_ImplFreeGLUT_Init() +bool ImGui_ImplGLUT_Init() { ImGuiIO& io = ImGui::GetIO(); - io.BackendPlatformName ="imgui_impl_freeglut"; + io.BackendPlatformName ="imgui_impl_glut"; g_Time = 0; @@ -62,24 +67,26 @@ bool ImGui_ImplFreeGLUT_Init() return true; } -void ImGui_ImplFreeGLUT_InstallFuncs() +void ImGui_ImplGLUT_InstallFuncs() { - glutReshapeFunc(ImGui_ImplFreeGLUT_ReshapeFunc); - glutMotionFunc(ImGui_ImplFreeGLUT_MotionFunc); - glutPassiveMotionFunc(ImGui_ImplFreeGLUT_MotionFunc); - glutMouseFunc(ImGui_ImplFreeGLUT_MouseFunc); - glutMouseWheelFunc(ImGui_ImplFreeGLUT_MouseWheelFunc); - glutKeyboardFunc(ImGui_ImplFreeGLUT_KeyboardFunc); - glutKeyboardUpFunc(ImGui_ImplFreeGLUT_KeyboardUpFunc); - glutSpecialFunc(ImGui_ImplFreeGLUT_SpecialFunc); - glutSpecialUpFunc(ImGui_ImplFreeGLUT_SpecialUpFunc); + glutReshapeFunc(ImGui_ImplGLUT_ReshapeFunc); + glutMotionFunc(ImGui_ImplGLUT_MotionFunc); + glutPassiveMotionFunc(ImGui_ImplGLUT_MotionFunc); + glutMouseFunc(ImGui_ImplGLUT_MouseFunc); +#ifdef __FREEGLUT_EXT_H__ + glutMouseWheelFunc(ImGui_ImplGLUT_MouseWheelFunc); +#endif + glutKeyboardFunc(ImGui_ImplGLUT_KeyboardFunc); + glutKeyboardUpFunc(ImGui_ImplGLUT_KeyboardUpFunc); + glutSpecialFunc(ImGui_ImplGLUT_SpecialFunc); + glutSpecialUpFunc(ImGui_ImplGLUT_SpecialUpFunc); } -void ImGui_ImplFreeGLUT_Shutdown() +void ImGui_ImplGLUT_Shutdown() { } -void ImGui_ImplFreeGLUT_NewFrame() +void ImGui_ImplGLUT_NewFrame() { // Setup time step ImGuiIO& io = ImGui::GetIO(); @@ -94,7 +101,7 @@ void ImGui_ImplFreeGLUT_NewFrame() ImGui::NewFrame(); } -static void ImGui_ImplFreeGLUT_UpdateKeyboardMods() +static void ImGui_ImplGLUT_UpdateKeyboardMods() { ImGuiIO& io = ImGui::GetIO(); int mods = glutGetModifiers(); @@ -103,7 +110,7 @@ static void ImGui_ImplFreeGLUT_UpdateKeyboardMods() io.KeyAlt = (mods & GLUT_ACTIVE_ALT) != 0; } -void ImGui_ImplFreeGLUT_KeyboardFunc(unsigned char c, int x, int y) +void ImGui_ImplGLUT_KeyboardFunc(unsigned char c, int x, int y) { // Send character to imgui //printf("char_down_func %d '%c'\n", c, c); @@ -121,11 +128,11 @@ void ImGui_ImplFreeGLUT_KeyboardFunc(unsigned char c, int x, int y) io.KeysDown[c] = io.KeysDown[c - 'A' + 'a'] = true; else io.KeysDown[c] = true; - ImGui_ImplFreeGLUT_UpdateKeyboardMods(); + ImGui_ImplGLUT_UpdateKeyboardMods(); (void)x; (void)y; // Unused } -void ImGui_ImplFreeGLUT_KeyboardUpFunc(unsigned char c, int x, int y) +void ImGui_ImplGLUT_KeyboardUpFunc(unsigned char c, int x, int y) { //printf("char_up_func %d '%c'\n", c, c); ImGuiIO& io = ImGui::GetIO(); @@ -137,31 +144,31 @@ void ImGui_ImplFreeGLUT_KeyboardUpFunc(unsigned char c, int x, int y) io.KeysDown[c] = io.KeysDown[c - 'A' + 'a'] = false; else io.KeysDown[c] = false; - ImGui_ImplFreeGLUT_UpdateKeyboardMods(); + ImGui_ImplGLUT_UpdateKeyboardMods(); (void)x; (void)y; // Unused } -void ImGui_ImplFreeGLUT_SpecialFunc(int key, int x, int y) +void ImGui_ImplGLUT_SpecialFunc(int key, int x, int y) { //printf("key_down_func %d\n", key); ImGuiIO& io = ImGui::GetIO(); if (key + 256 < IM_ARRAYSIZE(io.KeysDown)) io.KeysDown[key + 256] = true; - ImGui_ImplFreeGLUT_UpdateKeyboardMods(); + ImGui_ImplGLUT_UpdateKeyboardMods(); (void)x; (void)y; // Unused } -void ImGui_ImplFreeGLUT_SpecialUpFunc(int key, int x, int y) +void ImGui_ImplGLUT_SpecialUpFunc(int key, int x, int y) { //printf("key_up_func %d\n", key); ImGuiIO& io = ImGui::GetIO(); if (key + 256 < IM_ARRAYSIZE(io.KeysDown)) io.KeysDown[key + 256] = false; - ImGui_ImplFreeGLUT_UpdateKeyboardMods(); + ImGui_ImplGLUT_UpdateKeyboardMods(); (void)x; (void)y; // Unused } -void ImGui_ImplFreeGLUT_MouseFunc(int glut_button, int state, int x, int y) +void ImGui_ImplGLUT_MouseFunc(int glut_button, int state, int x, int y) { ImGuiIO& io = ImGui::GetIO(); io.MousePos = ImVec2((float)x, (float)y); @@ -175,7 +182,8 @@ void ImGui_ImplFreeGLUT_MouseFunc(int glut_button, int state, int x, int y) io.MouseDown[button] = false; } -void ImGui_ImplFreeGLUT_MouseWheelFunc(int button, int dir, int x, int y) +#ifdef __FREEGLUT_EXT_H__ +void ImGui_ImplGLUT_MouseWheelFunc(int button, int dir, int x, int y) { ImGuiIO& io = ImGui::GetIO(); io.MousePos = ImVec2((float)x, (float)y); @@ -185,14 +193,15 @@ void ImGui_ImplFreeGLUT_MouseWheelFunc(int button, int dir, int x, int y) io.MouseWheel -= 1.0; (void)button; // Unused } +#endif -void ImGui_ImplFreeGLUT_ReshapeFunc(int w, int h) +void ImGui_ImplGLUT_ReshapeFunc(int w, int h) { ImGuiIO& io = ImGui::GetIO(); io.DisplaySize = ImVec2((float)w, (float)h); } -void ImGui_ImplFreeGLUT_MotionFunc(int x, int y) +void ImGui_ImplGLUT_MotionFunc(int x, int y) { ImGuiIO& io = ImGui::GetIO(); io.MousePos = ImVec2((float)x, (float)y); diff --git a/examples/imgui_impl_glut.h b/examples/imgui_impl_glut.h new file mode 100644 index 00000000..8fde9bab --- /dev/null +++ b/examples/imgui_impl_glut.h @@ -0,0 +1,33 @@ +// dear imgui: Platform Binding for GLUT/FreeGLUT +// This needs to be used along with a Renderer (e.g. OpenGL2) + +// !!! GLUT/FreeGLUT IS OBSOLETE SOFTWARE. Using GLUT is not recommended unless you really miss the 90's. !!! +// !!! If someone or something is teaching you GLUT in 2019, you are being abused. Please show some resistance. !!! + +// Issues: +// [ ] Platform: GLUT is unable to distinguish e.g. Backspace from CTRL+H or TAB from CTRL+I +// [ ] Platform: Missing clipboard support (not supported by Glut). +// [ ] Platform: Missing gamepad support. + +// You can copy and use unmodified imgui_impl_* files in your project. See main.cpp for an example of using this. +// If you are new to dear imgui, read examples/README.txt and read the documentation at the top of imgui.cpp. +// https://github.com/ocornut/imgui + +#pragma once + +IMGUI_IMPL_API bool ImGui_ImplGLUT_Init(); +IMGUI_IMPL_API void ImGui_ImplGLUT_InstallFuncs(); +IMGUI_IMPL_API void ImGui_ImplGLUT_Shutdown(); +IMGUI_IMPL_API void ImGui_ImplGLUT_NewFrame(); + +// You can call ImGui_ImplGLUT_InstallFuncs() to get all those functions installed automatically, +// or call them yourself from your own GLUT handlers. We are using the same weird names as GLUT for consistency.. +//---------------------------------------- GLUT name --------------------------------------------- Decent Name --------- +IMGUI_IMPL_API void ImGui_ImplGLUT_ReshapeFunc(int w, int h); // ~ ResizeFunc +IMGUI_IMPL_API void ImGui_ImplGLUT_MotionFunc(int x, int y); // ~ MouseMoveFunc +IMGUI_IMPL_API void ImGui_ImplGLUT_MouseFunc(int button, int state, int x, int y); // ~ MouseButtonFunc +IMGUI_IMPL_API void ImGui_ImplGLUT_MouseWheelFunc(int button, int dir, int x, int y); // ~ MouseWheelFunc +IMGUI_IMPL_API void ImGui_ImplGLUT_KeyboardFunc(unsigned char c, int x, int y); // ~ CharPressedFunc +IMGUI_IMPL_API void ImGui_ImplGLUT_KeyboardUpFunc(unsigned char c, int x, int y); // ~ CharReleasedFunc +IMGUI_IMPL_API void ImGui_ImplGLUT_SpecialFunc(int key, int x, int y); // ~ KeyPressedFunc +IMGUI_IMPL_API void ImGui_ImplGLUT_SpecialUpFunc(int key, int x, int y); // ~ KeyReleasedFunc diff --git a/examples/imgui_impl_metal.mm b/examples/imgui_impl_metal.mm index 401e0722..f6689450 100644 --- a/examples/imgui_impl_metal.mm +++ b/examples/imgui_impl_metal.mm @@ -20,7 +20,7 @@ #include "imgui_impl_metal.h" #import -// #import // Not suported in XCode 9.2. Maybe a macro to detect the SDK version can be used (something like #if MACOS_SDK >= 10.13 ...) +// #import // Not supported in XCode 9.2. Maybe a macro to detect the SDK version can be used (something like #if MACOS_SDK >= 10.13 ...) #import #pragma mark - Support classes diff --git a/examples/imgui_impl_opengl2.cpp b/examples/imgui_impl_opengl2.cpp index 6b2d3137..d5abcc69 100644 --- a/examples/imgui_impl_opengl2.cpp +++ b/examples/imgui_impl_opengl2.cpp @@ -114,9 +114,9 @@ void ImGui_ImplOpenGL2_RenderDrawData(ImDrawData* draw_data) glEnable(GL_TEXTURE_2D); glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); - // If you are using this code with non-legacy OpenGL header/contexts (which you should not, prefer using imgui_impl_opengl3.cpp!!), + // If you are using this code with non-legacy OpenGL header/contexts (which you should not, prefer using imgui_impl_opengl3.cpp!!), // you may need to backup/reset/restore current shader using the lines below. DO NOT MODIFY THIS FILE! Add the code in your calling function: - // GLint last_program; + // GLint last_program; // glGetIntegerv(GL_CURRENT_PROGRAM, &last_program); // glUseProgram(0); // ImGui_ImplOpenGL2_RenderDrawData(...); diff --git a/examples/imgui_impl_vulkan.cpp b/examples/imgui_impl_vulkan.cpp index 179a63a0..5911878f 100644 --- a/examples/imgui_impl_vulkan.cpp +++ b/examples/imgui_impl_vulkan.cpp @@ -14,6 +14,7 @@ // CHANGELOG // (minor and older changes stripped away, please see git history for details) +// 2019-04-04: Vulkan: Avoid passing negative coordinates to vkCmdSetScissor, which debug validation layers do not like. // 2019-04-01: Vulkan: Support for 32-bit index buffer (#define ImDrawIdx unsigned int). // 2019-02-16: Vulkan: Viewport and clipping rectangles correctly using draw_data->FramebufferScale to allow retina display. // 2018-11-30: Misc: Setting up io.BackendRendererName so it can be displayed in the About Window. @@ -81,6 +82,23 @@ static void ImGui_ImplVulkan_ShutdownPlatformInterface(); // glsl_shader.vert, compiled with: // # glslangValidator -V -x -o glsl_shader.vert.u32 glsl_shader.vert +/* +#version 450 core +layout(location = 0) in vec2 aPos; +layout(location = 1) in vec2 aUV; +layout(location = 2) in vec4 aColor; +layout(push_constant) uniform uPushConstant { vec2 uScale; vec2 uTranslate; } pc; + +out gl_PerVertex { vec4 gl_Position; }; +layout(location = 0) out struct { vec4 Color; vec2 UV; } Out; + +void main() +{ + Out.Color = aColor; + Out.UV = aUV; + gl_Position = vec4(aPos * pc.uScale + pc.uTranslate, 0, 1); +} +*/ static uint32_t __glsl_shader_vert_spv[] = { 0x07230203,0x00010000,0x00080001,0x0000002e,0x00000000,0x00020011,0x00000001,0x0006000b, @@ -128,6 +146,16 @@ static uint32_t __glsl_shader_vert_spv[] = // glsl_shader.frag, compiled with: // # glslangValidator -V -x -o glsl_shader.frag.u32 glsl_shader.frag +/* +#version 450 core +layout(location = 0) out vec4 fColor; +layout(set=0, binding=0) uniform sampler2D sTexture; +layout(location = 0) in struct { vec4 Color; vec2 UV; } In; +void main() +{ + fColor = In.Color * texture(sTexture, In.UV.st); +} +*/ static uint32_t __glsl_shader_frag_spv[] = { 0x07230203,0x00010000,0x00080001,0x0000001e,0x00000000,0x00020011,0x00000001,0x0006000b, @@ -325,6 +353,12 @@ void ImGui_ImplVulkan_RenderDrawData(ImDrawData* draw_data, VkCommandBuffer comm if (clip_rect.x < fb_width && clip_rect.y < fb_height && clip_rect.z >= 0.0f && clip_rect.w >= 0.0f) { + // Negative offsets are illegal for vkCmdSetScissor + if (clip_rect.x < 0.0f) + clip_rect.x = 0.0f; + if (clip_rect.y < 0.0f) + clip_rect.y = 0.0f; + // Apply scissor/clipping rectangle VkRect2D scissor; scissor.offset.x = (int32_t)(clip_rect.x); @@ -930,7 +964,7 @@ int ImGui_ImplVulkanH_GetMinImageCountFromPresentMode(VkPresentModeKHR present_m void ImGui_ImplVulkanH_CreateWindowDataSwapChainAndFramebuffer(VkPhysicalDevice physical_device, VkDevice device, ImGui_ImplVulkanH_WindowData* wd, const VkAllocationCallbacks* allocator, int w, int h) { - uint32_t min_image_count = 2; // FIXME: this should become a function parameter + uint32_t min_image_count = 2; // FIXME: this should become a function parameter VkResult err; VkSwapchainKHR old_swapchain = wd->Swapchain; @@ -958,7 +992,7 @@ void ImGui_ImplVulkanH_CreateWindowDataSwapChainAndFramebuffer(VkPhysicalDevice VkSwapchainCreateInfoKHR info = {}; info.sType = VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR; info.surface = wd->Surface; - info.minImageCount = min_image_count; + info.minImageCount = min_image_count; info.imageFormat = wd->SurfaceFormat.format; info.imageColorSpace = wd->SurfaceFormat.colorSpace; info.imageArrayLayers = 1; @@ -973,9 +1007,9 @@ void ImGui_ImplVulkanH_CreateWindowDataSwapChainAndFramebuffer(VkPhysicalDevice err = vkGetPhysicalDeviceSurfaceCapabilitiesKHR(physical_device, wd->Surface, &cap); check_vk_result(err); if (info.minImageCount < cap.minImageCount) - info.minImageCount = cap.minImageCount; - else if (cap.maxImageCount != 0 && info.minImageCount > cap.maxImageCount) - info.minImageCount = cap.maxImageCount; + info.minImageCount = cap.minImageCount; + else if (cap.maxImageCount != 0 && info.minImageCount > cap.maxImageCount) + info.minImageCount = cap.maxImageCount; if (cap.currentExtent.width == 0xffffffff) { diff --git a/examples/imgui_impl_vulkan.h b/examples/imgui_impl_vulkan.h index ec9eb54b..ec45dbec 100644 --- a/examples/imgui_impl_vulkan.h +++ b/examples/imgui_impl_vulkan.h @@ -47,6 +47,7 @@ IMGUI_IMPL_API void ImGui_ImplVulkan_InvalidateDeviceObjects(); //------------------------------------------------------------------------- // Internal / Miscellaneous Vulkan Helpers +// (Used by example's main.cpp. Used by multi-viewport features. Probably NOT used by your own app.) //------------------------------------------------------------------------- // You probably do NOT need to use or care about those functions. // Those functions only exist because: @@ -70,6 +71,7 @@ IMGUI_IMPL_API VkPresentModeKHR ImGui_ImplVulkanH_SelectPresentMode(VkPhysic IMGUI_IMPL_API int ImGui_ImplVulkanH_GetMinImageCountFromPresentMode(VkPresentModeKHR present_mode); // Helper structure to hold the data needed by one rendering frame +// (Used by example's main.cpp. Used by multi-viewport features. Probably NOT used by your own app.) struct ImGui_ImplVulkanH_FrameData { uint32_t BackbufferIndex; // Keep track of recently rendered swapchain frame indices @@ -83,6 +85,7 @@ struct ImGui_ImplVulkanH_FrameData }; // Helper structure to hold the data needed by one rendering context into one OS window +// (Used by example's main.cpp. Used by multi-viewport features. Probably NOT used by your own app.) struct ImGui_ImplVulkanH_WindowData { int Width; diff --git a/imgui.cpp b/imgui.cpp index 5db1d8a9..c96b2d8a 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -1370,7 +1370,7 @@ const char* ImStrchrRange(const char* str, const char* str_end, char c) int ImStrlenW(const ImWchar* str) { - //return (int)wcslen((const wchar_t*)str); // FIXME-OPT: Could use this when wchar_t are 16-bits + //return (int)wcslen((const wchar_t*)str); // FIXME-OPT: Could use this when wchar_t are 16-bits int n = 0; while (*str++) n++; return n;