example_gl3.c 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230
  1. //
  2. // Copyright (c) 2013 Mikko Mononen memon@inside.org
  3. //
  4. // This software is provided 'as-is', without any express or implied
  5. // warranty. In no event will the authors be held liable for any damages
  6. // arising from the use of this software.
  7. // Permission is granted to anyone to use this software for any purpose,
  8. // including commercial applications, and to alter it and redistribute it
  9. // freely, subject to the following restrictions:
  10. // 1. The origin of this software must not be misrepresented; you must not
  11. // claim that you wrote the original software. If you use this software
  12. // in a product, an acknowledgment in the product documentation would be
  13. // appreciated but is not required.
  14. // 2. Altered source versions must be plainly marked as such, and must not be
  15. // misrepresented as being the original software.
  16. // 3. This notice may not be removed or altered from any source distribution.
  17. //
  18. #include <stdio.h>
  19. #ifdef NANOVG_GLEW
  20. # include <GL/glew.h>
  21. #endif
  22. #ifdef __APPLE__
  23. # define GLFW_INCLUDE_GLCOREARB
  24. #endif
  25. #ifdef NANOVG_GLAD
  26. # include <glad/glad.h>
  27. #else
  28. # define GLFW_INCLUDE_GLEXT
  29. #endif
  30. #include <GLFW/glfw3.h>
  31. #ifndef DEMO_ANTIALIAS
  32. # define DEMO_ANTIALIAS 1
  33. #endif
  34. #ifndef DEMO_STENCIL_STROKES
  35. # define DEMO_STENCIL_STROKES 1
  36. #endif
  37. #ifndef DEMO_MSAA
  38. # define DEMO_MSAA 0
  39. #endif
  40. #include "nanovg.h"
  41. #define NANOVG_GL3_IMPLEMENTATION
  42. #include "nanovg_gl.h"
  43. #include "demo.h"
  44. #include "perf.h"
  45. void errorcb(int error, const char* desc)
  46. {
  47. printf("GLFW error %d: %s\n", error, desc);
  48. }
  49. int blowup = 0;
  50. int screenshot = 0;
  51. int premult = 0;
  52. static void key(GLFWwindow* window, int key, int scancode, int action, int mods)
  53. {
  54. NVG_NOTUSED(scancode);
  55. NVG_NOTUSED(mods);
  56. if (key == GLFW_KEY_ESCAPE && action == GLFW_PRESS)
  57. glfwSetWindowShouldClose(window, GL_TRUE);
  58. if (key == GLFW_KEY_SPACE && action == GLFW_PRESS)
  59. blowup = !blowup;
  60. if (key == GLFW_KEY_S && action == GLFW_PRESS)
  61. screenshot = 1;
  62. if (key == GLFW_KEY_P && action == GLFW_PRESS)
  63. premult = !premult;
  64. }
  65. int main()
  66. {
  67. GLFWwindow* window;
  68. DemoData data;
  69. NVGcontext* vg = NULL;
  70. GPUtimer gpuTimer;
  71. PerfGraph fps, cpuGraph, gpuGraph;
  72. double prevt = 0, cpuTime = 0;
  73. if (!glfwInit()) {
  74. printf("Failed to init GLFW.");
  75. return -1;
  76. }
  77. initGraph(&fps, GRAPH_RENDER_FPS, "Frame Time");
  78. initGraph(&cpuGraph, GRAPH_RENDER_MS, "CPU Time");
  79. initGraph(&gpuGraph, GRAPH_RENDER_MS, "GPU Time");
  80. glfwSetErrorCallback(errorcb);
  81. #ifndef _WIN32 // don't require this on win32, and works with more cards
  82. glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
  83. glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 2);
  84. glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE);
  85. glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
  86. #endif
  87. glfwWindowHint(GLFW_OPENGL_DEBUG_CONTEXT, 1);
  88. #if DEMO_MSAA
  89. glfwWindowHint(GLFW_SAMPLES, 4);
  90. #endif
  91. window = glfwCreateWindow(1000, 600, "NanoVG Example OpenGL 3.2", NULL, NULL);
  92. // window = glfwCreateWindow(1000, 600, "NanoVG Example OpenGL 3.2", glfwGetPrimaryMonitor(), NULL);
  93. if (!window) {
  94. glfwTerminate();
  95. return -1;
  96. }
  97. glfwSetKeyCallback(window, key);
  98. glfwMakeContextCurrent(window);
  99. #ifdef NANOVG_GLEW
  100. glewExperimental = GL_TRUE;
  101. if(glewInit() != GLEW_OK) {
  102. printf("Could not init glew.\n");
  103. return -1;
  104. }
  105. // GLEW generates GL error because it calls glGetString(GL_EXTENSIONS), we'll consumeP it here.
  106. glGetError();
  107. #endif
  108. #ifdef NANOVG_GLAD
  109. if (!gladLoadGLLoader((GLADloadproc)glfwGetProcAddress)) {
  110. printf("Could not init glad.\n");
  111. return -1;
  112. }
  113. #endif
  114. int flags = 0;
  115. #ifndef NDEBUG
  116. flags |= NVG_DEBUG;
  117. #endif
  118. #if !DEMO_MSAA && DEMO_ANTIALIAS
  119. flags |= NVG_ANTIALIAS;
  120. #endif
  121. #if DEMO_STENCIL_STROKES
  122. flags |= NVG_STENCIL_STROKES;
  123. #endif
  124. vg = nvgCreateGL3(flags);
  125. if (vg == NULL) {
  126. printf("Could not init nanovg.\n");
  127. return -1;
  128. }
  129. if (loadDemoData(vg, &data) == -1)
  130. return -1;
  131. glfwSwapInterval(0);
  132. initGPUTimer(&gpuTimer);
  133. glfwSetTime(0);
  134. prevt = glfwGetTime();
  135. while (!glfwWindowShouldClose(window))
  136. {
  137. double mx, my, t, dt;
  138. int winWidth, winHeight;
  139. int fbWidth, fbHeight;
  140. float pxRatio;
  141. float gpuTimes[3];
  142. int i, n;
  143. t = glfwGetTime();
  144. dt = t - prevt;
  145. prevt = t;
  146. startGPUTimer(&gpuTimer);
  147. glfwGetCursorPos(window, &mx, &my);
  148. glfwGetWindowSize(window, &winWidth, &winHeight);
  149. glfwGetFramebufferSize(window, &fbWidth, &fbHeight);
  150. // Calculate pixel ration for hi-dpi devices.
  151. pxRatio = (float)fbWidth / (float)winWidth;
  152. // Update and render
  153. glViewport(0, 0, fbWidth, fbHeight);
  154. if (premult)
  155. glClearColor(0,0,0,0);
  156. else
  157. glClearColor(0.3f, 0.3f, 0.32f, 1.0f);
  158. glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT|GL_STENCIL_BUFFER_BIT);
  159. nvgBeginFrame(vg, winWidth, winHeight, pxRatio);
  160. renderDemo(vg, mx,my, winWidth,winHeight, t, blowup, &data);
  161. renderGraph(vg, 5,5, &fps);
  162. renderGraph(vg, 5+200+5,5, &cpuGraph);
  163. if (gpuTimer.supported)
  164. renderGraph(vg, 5+200+5+200+5,5, &gpuGraph);
  165. nvgEndFrame(vg);
  166. // Measure the CPU time taken excluding swap buffers (as the swap may wait for GPU)
  167. cpuTime = glfwGetTime() - t;
  168. updateGraph(&fps, dt);
  169. updateGraph(&cpuGraph, cpuTime);
  170. // We may get multiple results.
  171. n = stopGPUTimer(&gpuTimer, gpuTimes, 3);
  172. for (i = 0; i < n; i++)
  173. updateGraph(&gpuGraph, gpuTimes[i]);
  174. if (screenshot) {
  175. screenshot = 0;
  176. saveScreenShot(fbWidth, fbHeight, premult, "dump.png");
  177. }
  178. glfwSwapBuffers(window);
  179. glfwPollEvents();
  180. }
  181. freeDemoData(vg, &data);
  182. nvgDeleteGL3(vg);
  183. printf("Average Frame Time: %.2f ms\n", getGraphAverage(&fps) * 1000.0f);
  184. printf(" CPU Time: %.2f ms\n", getGraphAverage(&cpuGraph) * 1000.0f);
  185. printf(" GPU Time: %.2f ms\n", getGraphAverage(&gpuGraph) * 1000.0f);
  186. glfwTerminate();
  187. return 0;
  188. }