- moved performance counter and drawing to separate file - tweaks to performance drawingshared-context
@@ -849,102 +849,3 @@ void renderDemo(struct NVGcontext* vg, float mx, float my, float width, float he | |||
nvgRestore(vg); | |||
} | |||
void initFPS(struct FPScounter* fps) | |||
{ | |||
memset(fps, 0, sizeof(struct FPScounter)); | |||
} | |||
void updateFPS(struct FPScounter* fps, float frameTime) | |||
{ | |||
fps->head = (fps->head+1) % FPS_HISTORY_COUNT; | |||
fps->values[fps->head] = frameTime; | |||
} | |||
#define AVG_SIZE 20 | |||
void renderFPS(struct NVGcontext* vg, float x, float y, struct FPScounter* fps) | |||
{ | |||
renderFPSEx(vg,x,y,fps,RENDER_FPS,NULL); | |||
} | |||
void renderFPSEx(struct NVGcontext* vg, float x, float y, struct FPScounter* fps, enum FPSRenderStyle style, const char* name) | |||
{ | |||
int i, head; | |||
float avg, w, h; | |||
char str[64]; | |||
avg = 0; | |||
head = fps->head; | |||
for (i = 0; i < AVG_SIZE; i++) { | |||
avg += fps->values[head]; | |||
head = (head+FPS_HISTORY_COUNT-1) % FPS_HISTORY_COUNT; | |||
} | |||
avg /= (float)AVG_SIZE; | |||
w = 200; | |||
h = 30; | |||
nvgBeginPath(vg); | |||
nvgRect(vg, x,y, w,h); | |||
nvgFillColor(vg, nvgRGBA(0,0,0,128)); | |||
nvgFill(vg); | |||
nvgBeginPath(vg); | |||
nvgMoveTo(vg, x, y+h); | |||
if( RENDER_FPS == style ) | |||
{ | |||
for (i = 0; i < FPS_HISTORY_COUNT; i++) { | |||
float v = 1.0f / (0.00001f + fps->values[(fps->head+i) % FPS_HISTORY_COUNT]); | |||
if (v > 80.0f) v = 80.0f; | |||
float vx = x + ((float)i/(FPS_HISTORY_COUNT-1)) * w; | |||
float vy = y + h - ((v / 80.0f) * h); | |||
nvgLineTo(vg, vx, vy); | |||
} | |||
} | |||
else | |||
{ | |||
for (i = 0; i < FPS_HISTORY_COUNT; i++) { | |||
float v = fps->values[(fps->head+i) % FPS_HISTORY_COUNT] * 1000.0f; | |||
if (v > 20.0f) v = 20.0f; | |||
float vx = x + ((float)i/(FPS_HISTORY_COUNT-1)) * w; | |||
float vy = y + h - ((v / 20.0f) * h); | |||
nvgLineTo(vg, vx, vy); | |||
} | |||
} | |||
nvgLineTo(vg, x+w, y+h); | |||
nvgFillColor(vg, nvgRGBA(255,192,0,128)); | |||
nvgFill(vg); | |||
nvgFontFace(vg, "sans"); | |||
if( RENDER_FPS == style ) { | |||
nvgFontSize(vg, 18.0f); | |||
nvgTextAlign(vg,NVG_ALIGN_RIGHT|NVG_ALIGN_MIDDLE); | |||
nvgFillColor(vg, nvgRGBA(240,240,240,255)); | |||
sprintf(str, "%.2f FPS", 1.0f / avg); | |||
nvgText(vg, x+w-5,y+h/2, str, NULL); | |||
nvgFontSize(vg, 15.0f); | |||
nvgTextAlign(vg,NVG_ALIGN_LEFT|NVG_ALIGN_MIDDLE); | |||
nvgFillColor(vg, nvgRGBA(240,240,240,160)); | |||
sprintf(str, "%.2f ms", avg * 1000.0f); | |||
nvgText(vg, x+5,y+h/2, str, NULL); | |||
} | |||
else { | |||
nvgFontSize(vg, 18.0f); | |||
nvgTextAlign(vg,NVG_ALIGN_RIGHT|NVG_ALIGN_MIDDLE); | |||
nvgFillColor(vg, nvgRGBA(240,240,240,255)); | |||
sprintf(str, "%.2f ms", avg * 1000.0f); | |||
nvgText(vg, x+w-5,y+h/2, str, NULL); | |||
if( name ) | |||
{ | |||
nvgFontSize(vg, 20.0f); | |||
nvgTextAlign(vg,NVG_ALIGN_LEFT|NVG_ALIGN_MIDDLE); | |||
nvgFillColor(vg, nvgRGBA(240,240,240,160)); | |||
nvgText(vg, x+5,y+h/2, name, NULL); | |||
} | |||
} | |||
} | |||
@@ -1,5 +1,5 @@ | |||
#ifndef WIDGETS_H | |||
#define WIDGETS_H | |||
#ifndef DEMO_H | |||
#define DEMO_H | |||
#include "nanovg.h" | |||
@@ -16,24 +16,8 @@ int loadDemoData(struct NVGcontext* vg, struct DemoData* data); | |||
void freeDemoData(struct NVGcontext* vg, struct DemoData* data); | |||
void renderDemo(struct NVGcontext* vg, float mx, float my, float width, float height, float t, int blowup, struct DemoData* data); | |||
#define FPS_HISTORY_COUNT 100 | |||
enum FPSRenderStyle { | |||
RENDER_FPS, | |||
RENDER_MS, | |||
}; | |||
struct FPScounter | |||
{ | |||
float values[FPS_HISTORY_COUNT]; | |||
int head; | |||
}; | |||
void initFPS(struct FPScounter* fps); | |||
void updateFPS(struct FPScounter* fps, float frameTime); | |||
void renderFPSEx(struct NVGcontext* vg, float x, float y, struct FPScounter* fps, enum FPSRenderStyle style, const char* name ); | |||
void renderFPS(struct NVGcontext* vg, float x, float y, struct FPScounter* fps); | |||
#ifdef __cplusplus | |||
} | |||
#endif | |||
#endif // WIDGETS_H | |||
#endif // DEMO_H |
@@ -25,6 +25,7 @@ | |||
#define NANOVG_GL2_IMPLEMENTATION | |||
#include "nanovg_gl2.h" | |||
#include "demo.h" | |||
#include "perf.h" | |||
void errorcb(int error, const char* desc) | |||
@@ -57,7 +58,7 @@ int main() | |||
return -1; | |||
} | |||
initFPS(&fps); | |||
initFPS(&fps, FPS_RENDER_FPS, "Frame Time"); | |||
glfwSetErrorCallback(errorcb); | |||
@@ -30,14 +30,7 @@ | |||
//#include "nanovg_gl3.h" | |||
#include "nanovg_gl3buf.h" | |||
#include "demo.h" | |||
// timer query support | |||
#ifndef GL_ARB_timer_query | |||
#define GL_TIME_ELAPSED 0x88BF | |||
typedef void (APIENTRY *pfnGLGETQUERYOBJECTUI64V)(GLuint id, GLenum pname, GLuint64* params); | |||
pfnGLGETQUERYOBJECTUI64V glGetQueryObjectui64v = 0; | |||
#endif | |||
#include "perf.h" | |||
void errorcb(int error, const char* desc) | |||
{ | |||
@@ -56,35 +49,30 @@ static void key(GLFWwindow* window, int key, int scancode, int action, int mods) | |||
blowup = !blowup; | |||
} | |||
enum numqueries { | |||
NUM_QUERIES = 5 | |||
}; | |||
int main() | |||
{ | |||
GLFWwindow* window; | |||
struct DemoData data; | |||
struct NVGcontext* vg = NULL; | |||
struct FPScounter fps, cpuTimes, gpuTimes; | |||
struct GPUtimer gpuTimer; | |||
struct FPScounter fps, cpuGraph, gpuGraph; | |||
double prevt = 0, cpuTime = 0; | |||
int timerquery = GL_FALSE, currquery = 0, retquery = 0; | |||
GLuint timerqueryid[NUM_QUERIES]; | |||
if (!glfwInit()) { | |||
printf("Failed to init GLFW."); | |||
return -1; | |||
} | |||
initFPS(&fps); | |||
initFPS(&cpuTimes); | |||
initFPS(&gpuTimes); | |||
initFPS(&fps, FPS_RENDER_FPS, "Frame Time"); | |||
initFPS(&cpuGraph, FPS_RENDER_MS, "CPU Time"); | |||
initFPS(&gpuGraph, FPS_RENDER_MS, "GPU Time"); | |||
glfwSetErrorCallback(errorcb); | |||
#ifndef _WIN32 // don't require this on win32, and works with more cards | |||
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3); | |||
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 2); | |||
glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE); | |||
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); | |||
glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE); | |||
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); | |||
#endif | |||
#ifdef DEMO_MSAA | |||
@@ -92,7 +80,7 @@ int main() | |||
#endif | |||
window = glfwCreateWindow(1000, 600, "NanoVG", NULL, NULL); | |||
// window = glfwCreateWindow(1000, 600, "NanoVG", glfwGetPrimaryMonitor(), NULL); | |||
if (!window) { | |||
if (!window) { | |||
glfwTerminate(); | |||
return -1; | |||
} | |||
@@ -102,7 +90,7 @@ int main() | |||
glfwMakeContextCurrent(window); | |||
#ifdef NANOVG_GLEW | |||
glewExperimental = GL_TRUE; | |||
if(glewInit() != GLEW_OK) { | |||
if(glewInit() != GLEW_OK) { | |||
printf("Could not init glew.\n"); | |||
return -1; | |||
} | |||
@@ -123,17 +111,7 @@ int main() | |||
glfwSwapInterval(0); | |||
timerquery = glfwExtensionSupported("GL_ARB_timer_query"); | |||
if( timerquery ) { | |||
#ifndef GL_ARB_timer_query | |||
glGetQueryObjectui64v = (pfnGLGETQUERYOBJECTUI64V)glfwGetProcAddress("glGetQueryObjectui64v"); | |||
if( !glGetQueryObjectui64v ) | |||
{ | |||
timerquery = GL_FALSE; | |||
} | |||
#endif | |||
glGenQueries(NUM_QUERIES, timerqueryid); | |||
} | |||
initGPUTimer(&gpuTimer); | |||
glfwSetTime(0); | |||
prevt = glfwGetTime(); | |||
@@ -144,16 +122,14 @@ int main() | |||
int winWidth, winHeight; | |||
int fbWidth, fbHeight; | |||
float pxRatio; | |||
float gpuTimes[3]; | |||
int i, n; | |||
t = glfwGetTime(); | |||
dt = t - prevt; | |||
prevt = t; | |||
updateFPS(&fps, dt); | |||
updateFPS(&cpuTimes, cpuTime); | |||
if( timerquery ) { | |||
glBeginQuery(GL_TIME_ELAPSED, timerqueryid[currquery % NUM_QUERIES] ); | |||
currquery = ++currquery; | |||
} | |||
startGPUTimer(&gpuTimer); | |||
glfwGetCursorPos(window, &mx, &my); | |||
glfwGetWindowSize(window, &winWidth, &winHeight); | |||
@@ -174,34 +150,27 @@ int main() | |||
nvgBeginFrame(vg, winWidth, winHeight, pxRatio); | |||
renderDemo(vg, mx,my, winWidth,winHeight, t, blowup, &data); | |||
renderFPS(vg, 5,5, &fps); | |||
renderFPSEx(vg, 310,5, &cpuTimes, RENDER_MS, "CPU Time"); | |||
renderFPSEx(vg, 615,5, &gpuTimes, RENDER_MS, "GPU Time"); | |||
renderFPS(vg, 5+200+5,5, &cpuGraph); | |||
if (gpuTimer.supported) | |||
renderFPS(vg, 5+200+5+200+5,5, &gpuGraph); | |||
nvgEndFrame(vg); | |||
glEnable(GL_DEPTH_TEST); | |||
// Measure the CPU time taken excluding swap buffers (as the swap may wait for GPU) | |||
cpuTime = glfwGetTime() - t; | |||
if( timerquery ) { | |||
GLint available = 1; | |||
glEndQuery(GL_TIME_ELAPSED); | |||
while( available && retquery <= currquery ) { | |||
// check for results if there are any | |||
glGetQueryObjectiv(timerqueryid[retquery % NUM_QUERIES], GL_QUERY_RESULT_AVAILABLE, &available); | |||
if( available ) { | |||
GLuint64 timeElapsed = 0; | |||
double gpuTime; | |||
glGetQueryObjectui64v(timerqueryid[retquery % NUM_QUERIES], GL_QUERY_RESULT, &timeElapsed); | |||
retquery = ++retquery ; | |||
gpuTime = (double)timeElapsed * 1e-9; | |||
updateFPS(&gpuTimes, (float)gpuTime); | |||
} | |||
} | |||
} | |||
// Measure the CPU time taken excluding swap buffers (as the swap may wait for GPU) | |||
cpuTime = glfwGetTime() - t; | |||
updateFPS(&fps, dt); | |||
updateFPS(&cpuGraph, cpuTime); | |||
// We may get multiple results. | |||
n = stopGPUTimer(&gpuTimer, gpuTimes, 3); | |||
for (i = 0; i < n; i++) | |||
updateFPS(&gpuGraph, gpuTimes[i]); | |||
glfwSwapBuffers(window); | |||
glfwPollEvents(); | |||
} | |||
@@ -23,6 +23,7 @@ | |||
#define NANOVG_GLES2_IMPLEMENTATION | |||
#include "nanovg_gl2.h" | |||
#include "demo.h" | |||
#include "perf.h" | |||
void errorcb(int error, const char* desc) | |||
@@ -55,7 +56,7 @@ int main() | |||
return -1; | |||
} | |||
initFPS(&fps); | |||
initFPS(&fps, FPS_RENDER_FPS, "Frame Time"); | |||
glfwSetErrorCallback(errorcb); | |||
@@ -23,6 +23,7 @@ | |||
#define NANOVG_GLES3_IMPLEMENTATION | |||
#include "nanovg_gl3.h" | |||
#include "demo.h" | |||
#include "perf.h" | |||
void errorcb(int error, const char* desc) | |||
@@ -55,7 +56,7 @@ int main() | |||
return -1; | |||
} | |||
initFPS(&fps); | |||
initFPS(&fps, FPS_RENDER_FPS, "Frame Time"); | |||
glfwSetErrorCallback(errorcb); | |||
@@ -0,0 +1,168 @@ | |||
#include "perf.h" | |||
#include <stdio.h> | |||
#include <string.h> | |||
#include <math.h> | |||
#ifdef NANOVG_GLEW | |||
# include <GL/glew.h> | |||
#endif | |||
#include <GLFW/glfw3.h> | |||
#include "nanovg.h" | |||
#ifdef _MSC_VER | |||
#define snprintf _snprintf | |||
#else | |||
#include <iconv.h> | |||
#endif | |||
// timer query support | |||
#ifndef GL_ARB_timer_query | |||
#define GL_TIME_ELAPSED 0x88BF | |||
typedef void (APIENTRY *pfnGLGETQUERYOBJECTUI64V)(GLuint id, GLenum pname, GLuint64* params); | |||
pfnGLGETQUERYOBJECTUI64V glGetQueryObjectui64v = 0; | |||
#endif | |||
void initGPUTimer(struct GPUtimer* timer) | |||
{ | |||
memset(timer, 0, sizeof(*timer)); | |||
timer->supported = glfwExtensionSupported("GL_ARB_timer_query"); | |||
if (timer->supported) { | |||
#ifndef GL_ARB_timer_query | |||
glGetQueryObjectui64v = (pfnGLGETQUERYOBJECTUI64V)glfwGetProcAddress("glGetQueryObjectui64v"); | |||
if (!glGetQueryObjectui64v) { | |||
timer->supported = GL_FALSE; | |||
return; | |||
} | |||
#endif | |||
glGenQueries(GPU_QUERY_COUNT, timer->queries); | |||
} | |||
} | |||
void startGPUTimer(struct GPUtimer* timer) | |||
{ | |||
if (!timer->supported) | |||
return; | |||
glBeginQuery(GL_TIME_ELAPSED, timer->queries[timer->cur % GPU_QUERY_COUNT] ); | |||
timer->cur++; | |||
} | |||
int stopGPUTimer(struct GPUtimer* timer, float* times, int maxTimes) | |||
{ | |||
GLint available = 1; | |||
int n = 0; | |||
if (!timer->supported) | |||
return 0; | |||
glEndQuery(GL_TIME_ELAPSED); | |||
while (available && timer->ret <= timer->cur) { | |||
// check for results if there are any | |||
glGetQueryObjectiv(timer->queries[timer->ret % GPU_QUERY_COUNT], GL_QUERY_RESULT_AVAILABLE, &available); | |||
if (available) { | |||
GLuint64 timeElapsed = 0; | |||
glGetQueryObjectui64v(timer->queries[timer->ret % GPU_QUERY_COUNT], GL_QUERY_RESULT, &timeElapsed); | |||
timer->ret++; | |||
if (n < maxTimes) { | |||
times[n] = (float)((double)timeElapsed * 1e-9); | |||
n++; | |||
} | |||
} | |||
} | |||
return n; | |||
} | |||
void initFPS(struct FPScounter* fps, int style, const char* name) | |||
{ | |||
memset(fps, 0, sizeof(struct FPScounter)); | |||
fps->style = style; | |||
strncpy(fps->name, name, sizeof(fps->name)); | |||
fps->name[sizeof(fps->name)-1] = '\0'; | |||
} | |||
void updateFPS(struct FPScounter* fps, float frameTime) | |||
{ | |||
fps->head = (fps->head+1) % FPS_HISTORY_COUNT; | |||
fps->values[fps->head] = frameTime; | |||
} | |||
#define AVG_SIZE 20 | |||
static float getAvg(struct FPScounter* fps) | |||
{ | |||
int i, head = fps->head; | |||
float avg = 0; | |||
for (i = 0; i < AVG_SIZE; i++) { | |||
avg += fps->values[head]; | |||
head = (head+FPS_HISTORY_COUNT-1) % FPS_HISTORY_COUNT; | |||
} | |||
return avg / (float)AVG_SIZE; | |||
} | |||
void renderFPS(struct NVGcontext* vg, float x, float y, struct FPScounter* fps) | |||
{ | |||
int i; | |||
float avg, w, h; | |||
char str[64]; | |||
avg = getAvg(fps); | |||
w = 200; | |||
h = 35; | |||
nvgBeginPath(vg); | |||
nvgRect(vg, x,y, w,h); | |||
nvgFillColor(vg, nvgRGBA(0,0,0,128)); | |||
nvgFill(vg); | |||
nvgBeginPath(vg); | |||
nvgMoveTo(vg, x, y+h); | |||
if (fps->style == FPS_RENDER_FPS) { | |||
for (i = 0; i < FPS_HISTORY_COUNT; i++) { | |||
float v = 1.0f / (0.00001f + fps->values[(fps->head+i) % FPS_HISTORY_COUNT]); | |||
if (v > 80.0f) v = 80.0f; | |||
float vx = x + ((float)i/(FPS_HISTORY_COUNT-1)) * w; | |||
float vy = y + h - ((v / 80.0f) * h); | |||
nvgLineTo(vg, vx, vy); | |||
} | |||
} else { | |||
for (i = 0; i < FPS_HISTORY_COUNT; i++) { | |||
float v = fps->values[(fps->head+i) % FPS_HISTORY_COUNT] * 1000.0f; | |||
if (v > 20.0f) v = 20.0f; | |||
float vx = x + ((float)i/(FPS_HISTORY_COUNT-1)) * w; | |||
float vy = y + h - ((v / 20.0f) * h); | |||
nvgLineTo(vg, vx, vy); | |||
} | |||
} | |||
nvgLineTo(vg, x+w, y+h); | |||
nvgFillColor(vg, nvgRGBA(255,192,0,128)); | |||
nvgFill(vg); | |||
nvgFontFace(vg, "sans"); | |||
if (fps->name[0] != '\0') { | |||
nvgFontSize(vg, 14.0f); | |||
nvgTextAlign(vg, NVG_ALIGN_LEFT|NVG_ALIGN_TOP); | |||
nvgFillColor(vg, nvgRGBA(240,240,240,192)); | |||
nvgText(vg, x+3,y+1, fps->name, NULL); | |||
} | |||
if (fps->style == FPS_RENDER_FPS) { | |||
nvgFontSize(vg, 18.0f); | |||
nvgTextAlign(vg,NVG_ALIGN_RIGHT|NVG_ALIGN_TOP); | |||
nvgFillColor(vg, nvgRGBA(240,240,240,255)); | |||
sprintf(str, "%.2f FPS", 1.0f / avg); | |||
nvgText(vg, x+w-3,y+1, str, NULL); | |||
nvgFontSize(vg, 15.0f); | |||
nvgTextAlign(vg,NVG_ALIGN_RIGHT|NVG_ALIGN_BOTTOM); | |||
nvgFillColor(vg, nvgRGBA(240,240,240,160)); | |||
sprintf(str, "%.2f ms", avg * 1000.0f); | |||
nvgText(vg, x+w-3,y+h-1, str, NULL); | |||
} else { | |||
nvgFontSize(vg, 18.0f); | |||
nvgTextAlign(vg,NVG_ALIGN_RIGHT|NVG_ALIGN_TOP); | |||
nvgFillColor(vg, nvgRGBA(240,240,240,255)); | |||
sprintf(str, "%.2f ms", avg * 1000.0f); | |||
nvgText(vg, x+w-3,y+1, str, NULL); | |||
} | |||
} |
@@ -0,0 +1,42 @@ | |||
#ifndef PERF_H | |||
#define PERF_H | |||
#include "nanovg.h" | |||
#ifdef __cplusplus | |||
extern "C" { | |||
#endif | |||
enum FPSrenderStyle { | |||
FPS_RENDER_FPS, | |||
FPS_RENDER_MS, | |||
}; | |||
#define FPS_HISTORY_COUNT 100 | |||
struct FPScounter { | |||
int style; | |||
char name[32]; | |||
float values[FPS_HISTORY_COUNT]; | |||
int head; | |||
}; | |||
void initFPS(struct FPScounter* fps, int style, const char* name); | |||
void updateFPS(struct FPScounter* fps, float frameTime); | |||
void renderFPS(struct NVGcontext* vg, float x, float y, struct FPScounter* fps); | |||
#define GPU_QUERY_COUNT 5 | |||
struct GPUtimer { | |||
int supported; | |||
int cur, ret; | |||
unsigned int queries[GPU_QUERY_COUNT]; | |||
}; | |||
void initGPUTimer(struct GPUtimer* timer); | |||
void startGPUTimer(struct GPUtimer* timer); | |||
int stopGPUTimer(struct GPUtimer* timer, float* times, int maxTimes); | |||
#ifdef __cplusplus | |||
} | |||
#endif | |||
#endif // PERF_H |
@@ -16,7 +16,7 @@ solution "nanovg" | |||
project "example_gl2" | |||
kind "ConsoleApp" | |||
language "C" | |||
files { "example/example_gl2.c", "example/demo.c" } | |||
files { "example/example_gl2.c", "example/demo.c", "example/perf.c" } | |||
includedirs { "src", "example" } | |||
targetdir("build") | |||
links { "nanovg" } | |||
@@ -43,7 +43,7 @@ solution "nanovg" | |||
project "example_gl3" | |||
kind "ConsoleApp" | |||
language "C" | |||
files { "example/example_gl3.c", "example/demo.c" } | |||
files { "example/example_gl3.c", "example/demo.c", "example/perf.c" } | |||
includedirs { "src", "example" } | |||
targetdir("build") | |||
links { "nanovg" } | |||
@@ -71,7 +71,7 @@ solution "nanovg" | |||
kind "ConsoleApp" | |||
language "C" | |||
defines { "DEMO_MSAA" } | |||
files { "example/example_gl2.c", "example/demo.c" } | |||
files { "example/example_gl2.c", "example/demo.c", "example/perf.c" } | |||
includedirs { "src", "example" } | |||
targetdir("build") | |||
links { "nanovg" } | |||
@@ -99,7 +99,7 @@ solution "nanovg" | |||
kind "ConsoleApp" | |||
language "C" | |||
defines { "DEMO_MSAA" } | |||
files { "example/example_gl3.c", "example/demo.c" } | |||
files { "example/example_gl3.c", "example/demo.c", "example/perf.c" } | |||
includedirs { "src", "example" } | |||
targetdir("build") | |||
links { "nanovg" } | |||
@@ -126,7 +126,7 @@ solution "nanovg" | |||
project "example_gles2" | |||
kind "ConsoleApp" | |||
language "C" | |||
files { "example/example_gles2.c", "example/demo.c" } | |||
files { "example/example_gles2.c", "example/demo.c", "example/perf.c" } | |||
includedirs { "src", "example" } | |||
targetdir("build") | |||
links { "nanovg" } | |||
@@ -152,7 +152,7 @@ solution "nanovg" | |||
project "example_gles3" | |||
kind "ConsoleApp" | |||
language "C" | |||
files { "example/example_gles3.c", "example/demo.c" } | |||
files { "example/example_gles3.c", "example/demo.c", "example/perf.c" } | |||
includedirs { "src", "example" } | |||
targetdir("build") | |||
links { "nanovg" } | |||