JNIEXPORT void JNICALL Java_org_lwjgl_nanovg_NanoVG_nnvgHSLA(JNIEnv *__env, jclass clazz, jfloat h, jfloat s, jfloat l, jbyte a, jlong __result) { UNUSED_PARAMS(__env, clazz) *((NVGcolor*)(intptr_t)__result) = nvgHSLA(h, s, l, a); }
void ColorWheel::draw(NVGcontext *ctx) { Widget::draw(ctx); if (!mVisible) return; float x = mPos.x(), y = mPos.y(), w = mSize.x(), h = mSize.y(); NVGcontext* vg = ctx; int i; float r0, r1, ax,ay, bx,by, cx,cy, aeps, r; float hue = mHue; NVGpaint paint; nvgSave(vg); cx = x + w*0.5f; cy = y + h*0.5f; r1 = (w < h ? w : h) * 0.5f - 5.0f; r0 = r1 * .75f; aeps = 0.5f / r1; // half a pixel arc length in radians (2pi cancels out). for (i = 0; i < 6; i++) { float a0 = (float)i / 6.0f * NVG_PI * 2.0f - aeps; float a1 = (float)(i+1.0f) / 6.0f * NVG_PI * 2.0f + aeps; nvgBeginPath(vg); nvgArc(vg, cx,cy, r0, a0, a1, NVG_CW); nvgArc(vg, cx,cy, r1, a1, a0, NVG_CCW); nvgClosePath(vg); ax = cx + cosf(a0) * (r0+r1)*0.5f; ay = cy + sinf(a0) * (r0+r1)*0.5f; bx = cx + cosf(a1) * (r0+r1)*0.5f; by = cy + sinf(a1) * (r0+r1)*0.5f; paint = nvgLinearGradient(vg, ax, ay, bx, by, nvgHSLA(a0 / (NVG_PI * 2), 1.0f, 0.55f, 255), nvgHSLA(a1 / (NVG_PI * 2), 1.0f, 0.55f, 255)); nvgFillPaint(vg, paint); nvgFill(vg); } nvgBeginPath(vg); nvgCircle(vg, cx,cy, r0-0.5f); nvgCircle(vg, cx,cy, r1+0.5f); nvgStrokeColor(vg, nvgRGBA(0,0,0,64)); nvgStrokeWidth(vg, 1.0f); nvgStroke(vg); // Selector nvgSave(vg); nvgTranslate(vg, cx,cy); nvgRotate(vg, hue*NVG_PI*2); // Marker on float u = std::max(r1/50, 1.5f); u = std::min(u, 4.f); nvgStrokeWidth(vg, u); nvgBeginPath(vg); nvgRect(vg, r0-1,-2*u,r1-r0+2,4*u); nvgStrokeColor(vg, nvgRGBA(255,255,255,192)); nvgStroke(vg); paint = nvgBoxGradient(vg, r0-3,-5,r1-r0+6,10, 2,4, nvgRGBA(0,0,0,128), nvgRGBA(0,0,0,0)); nvgBeginPath(vg); nvgRect(vg, r0-2-10,-4-10,r1-r0+4+20,8+20); nvgRect(vg, r0-2,-4,r1-r0+4,8); nvgPathWinding(vg, NVG_HOLE); nvgFillPaint(vg, paint); nvgFill(vg); // Center triangle r = r0 - 6; ax = cosf(120.0f/180.0f*NVG_PI) * r; ay = sinf(120.0f/180.0f*NVG_PI) * r; bx = cosf(-120.0f/180.0f*NVG_PI) * r; by = sinf(-120.0f/180.0f*NVG_PI) * r; nvgBeginPath(vg); nvgMoveTo(vg, r,0); nvgLineTo(vg, ax, ay); nvgLineTo(vg, bx, by); nvgClosePath(vg); paint = nvgLinearGradient(vg, r, 0, ax, ay, nvgHSLA(hue, 1.0f, 0.5f, 255), nvgRGBA(255, 255, 255, 255)); nvgFillPaint(vg, paint); nvgFill(vg); paint = nvgLinearGradient(vg, (r + ax) * 0.5f, (0 + ay) * 0.5f, bx, by, nvgRGBA(0, 0, 0, 0), nvgRGBA(0, 0, 0, 255)); nvgFillPaint(vg, paint); nvgFill(vg); nvgStrokeColor(vg, nvgRGBA(0, 0, 0, 64)); nvgStroke(vg); // Select circle on triangle float sx = r*(1 - mWhite - mBlack) + ax*mWhite + bx*mBlack; float sy = ay*mWhite + by*mBlack; nvgStrokeWidth(vg, u); nvgBeginPath(vg); nvgCircle(vg, sx,sy,2*u); nvgStrokeColor(vg, nvgRGBA(255,255,255,192)); nvgStroke(vg); nvgRestore(vg); nvgRestore(vg); }
int main() { GLFWwindow* window; NVGcontext* vg = NULL; GPUtimer gpuTimer; PerfGraph fps, cpuGraph, gpuGraph; double prevt = 0, cpuTime = 0; NVGLUframebuffer* fb = NULL; int winWidth, winHeight; int fbWidth, fbHeight; float pxRatio; if (!glfwInit()) { printf("Failed to init GLFW."); return -1; } initGraph(&fps, GRAPH_RENDER_FPS, "Frame Time"); initGraph(&cpuGraph, GRAPH_RENDER_MS, "CPU Time"); initGraph(&gpuGraph, GRAPH_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); #endif glfwWindowHint(GLFW_OPENGL_DEBUG_CONTEXT, 1); #ifdef DEMO_MSAA glfwWindowHint(GLFW_SAMPLES, 4); #endif window = glfwCreateWindow(1000, 600, "NanoVG", NULL, NULL); // window = glfwCreateWindow(1000, 600, "NanoVG", glfwGetPrimaryMonitor(), NULL); if (!window) { glfwTerminate(); return -1; } glfwSetKeyCallback(window, key); glfwMakeContextCurrent(window); #ifdef NANOVG_GLEW glewExperimental = GL_TRUE; if(glewInit() != GLEW_OK) { printf("Could not init glew.\n"); return -1; } // GLEW generates GL error because it calls glGetString(GL_EXTENSIONS), we'll consume it here. glGetError(); #endif #ifdef DEMO_MSAA vg = nvgCreateGL3(NVG_STENCIL_STROKES | NVG_DEBUG); #else vg = nvgCreateGL3(NVG_ANTIALIAS | NVG_STENCIL_STROKES | NVG_DEBUG); #endif if (vg == NULL) { printf("Could not init nanovg.\n"); return -1; } // Create hi-dpi FBO for hi-dpi screens. glfwGetWindowSize(window, &winWidth, &winHeight); glfwGetFramebufferSize(window, &fbWidth, &fbHeight); // Calculate pixel ration for hi-dpi devices. pxRatio = (float)fbWidth / (float)winWidth; // The image pattern is tiled, set repeat on x and y. fb = nvgluCreateFramebuffer(vg, (int)(100*pxRatio), (int)(100*pxRatio), NVG_IMAGE_REPEATX | NVG_IMAGE_REPEATY); if (fb == NULL) { printf("Could not create FBO.\n"); return -1; } if (loadFonts(vg) == -1) { printf("Could not load fonts\n"); return -1; } glfwSwapInterval(0); initGPUTimer(&gpuTimer); glfwSetTime(0); prevt = glfwGetTime(); while (!glfwWindowShouldClose(window)) { double mx, my, t, dt; float gpuTimes[3]; int i, n; t = glfwGetTime(); dt = t - prevt; prevt = t; startGPUTimer(&gpuTimer); glfwGetCursorPos(window, &mx, &my); glfwGetWindowSize(window, &winWidth, &winHeight); glfwGetFramebufferSize(window, &fbWidth, &fbHeight); // Calculate pixel ration for hi-dpi devices. pxRatio = (float)fbWidth / (float)winWidth; renderPattern(vg, fb, t, pxRatio); // Update and render glViewport(0, 0, fbWidth, fbHeight); glClearColor(0.3f, 0.3f, 0.32f, 1.0f); glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT|GL_STENCIL_BUFFER_BIT); nvgBeginFrame(vg, winWidth, winHeight, pxRatio); // Use the FBO as image pattern. if (fb != NULL) { NVGpaint img = nvgImagePattern(vg, 0, 0, 100, 100, 0, fb->image, 1.0f); nvgSave(vg); for (i = 0; i < 20; i++) { nvgBeginPath(vg); nvgRect(vg, 10 + i*30,10, 10, winHeight-20); nvgFillColor(vg, nvgHSLA(i/19.0f, 0.5f, 0.5f, 255)); nvgFill(vg); } nvgBeginPath(vg); nvgRoundedRect(vg, 140 + sinf(t*1.3f)*100, 140 + cosf(t*1.71244f)*100, 250, 250, 20); nvgFillPaint(vg, img); nvgFill(vg); nvgStrokeColor(vg, nvgRGBA(220,160,0,255)); nvgStrokeWidth(vg, 3.0f); nvgStroke(vg); nvgRestore(vg); } renderGraph(vg, 5,5, &fps); renderGraph(vg, 5+200+5,5, &cpuGraph); if (gpuTimer.supported) renderGraph(vg, 5+200+5+200+5,5, &gpuGraph); nvgEndFrame(vg); // Measure the CPU time taken excluding swap buffers (as the swap may wait for GPU) cpuTime = glfwGetTime() - t; updateGraph(&fps, dt); updateGraph(&cpuGraph, cpuTime); // We may get multiple results. n = stopGPUTimer(&gpuTimer, gpuTimes, 3); for (i = 0; i < n; i++) updateGraph(&gpuGraph, gpuTimes[i]); glfwSwapBuffers(window); glfwPollEvents(); } nvgluDeleteFramebuffer(fb); nvgDeleteGL3(vg); printf("Average Frame Time: %.2f ms\n", getGraphAverage(&fps) * 1000.0f); printf(" CPU Time: %.2f ms\n", getGraphAverage(&cpuGraph) * 1000.0f); printf(" GPU Time: %.2f ms\n", getGraphAverage(&gpuGraph) * 1000.0f); glfwTerminate(); return 0; }
void drawColorwheel(struct NVGcontext* vg, float x, float y, float w, float h, float t) { int i; float r0, r1, ax,ay, bx,by, cx,cy, aeps, r; float hue = sinf(t * 0.12f); struct NVGpaint paint; nvgSave(vg); /* nvgBeginPath(vg); nvgRect(vg, x,y,w,h); nvgFillColor(vg, nvgRGBA(255,0,0,128) ); nvgFill(vg);*/ cx = x + w*0.5f; cy = y + h*0.5f; r1 = (w < h ? w : h) * 0.5f - 5.0f; r0 = r1 - 20.0f; aeps = 0.5f / r1; // half a pixel arc length in radians (2pi cancels out). for (i = 0; i < 6; i++) { float a0 = (float)i / 6.0f * NVG_PI * 2.0f - aeps; float a1 = (float)(i+1.0f) / 6.0f * NVG_PI * 2.0f + aeps; nvgBeginPath(vg); nvgArc(vg, cx,cy, r0, a0, a1, NVG_CW); nvgArc(vg, cx,cy, r1, a1, a0, NVG_CCW); nvgClosePath(vg); ax = cx + cosf(a0) * (r0+r1)*0.5f; ay = cy + sinf(a0) * (r0+r1)*0.5f; bx = cx + cosf(a1) * (r0+r1)*0.5f; by = cy + sinf(a1) * (r0+r1)*0.5f; paint = nvgLinearGradient(vg, ax,ay, bx,by, nvgHSLA(a0/(NVG_PI*2),1.0f,0.55f,255), nvgHSLA(a1/(NVG_PI*2),1.0f,0.55f,255) ); nvgFillPaint(vg, paint); nvgFill(vg); } nvgBeginPath(vg); nvgCircle(vg, cx,cy, r0-0.5f); nvgCircle(vg, cx,cy, r1+0.5f); nvgStrokeColor(vg, nvgRGBA(0,0,0,64) ); nvgStrokeWidth(vg, 1.0f); nvgStroke(vg); // Selector nvgSave(vg); nvgTranslate(vg, cx,cy); nvgRotate(vg, hue*NVG_PI*2); // Marker on nvgStrokeWidth(vg, 2.0f); nvgBeginPath(vg); nvgRect(vg, r0-1,-3,r1-r0+2,6); nvgStrokeColor(vg, nvgRGBA(255,255,255,192) ); nvgStroke(vg); paint = nvgBoxGradient(vg, r0-3,-5,r1-r0+6,10, 2,4, nvgRGBA(0,0,0,128), nvgRGBA(0,0,0,0) ); nvgBeginPath(vg); nvgRect(vg, r0-2-10,-4-10,r1-r0+4+20,8+20); nvgRect(vg, r0-2,-4,r1-r0+4,8); nvgPathWinding(vg, NVG_HOLE); nvgFillPaint(vg, paint); nvgFill(vg); // Center triangle r = r0 - 6; ax = cosf(120.0f/180.0f*NVG_PI) * r; ay = sinf(120.0f/180.0f*NVG_PI) * r; bx = cosf(-120.0f/180.0f*NVG_PI) * r; by = sinf(-120.0f/180.0f*NVG_PI) * r; nvgBeginPath(vg); nvgMoveTo(vg, r,0); nvgLineTo(vg, ax,ay); nvgLineTo(vg, bx,by); nvgClosePath(vg); paint = nvgLinearGradient(vg, r,0, ax,ay, nvgHSLA(hue,1.0f,0.5f,255), nvgRGBA(255,255,255,255) ); nvgFillPaint(vg, paint); nvgFill(vg); paint = nvgLinearGradient(vg, (r+ax)*0.5f,(0+ay)*0.5f, bx,by, nvgRGBA(0,0,0,0), nvgRGBA(0,0,0,255) ); nvgFillPaint(vg, paint); nvgFill(vg); nvgStrokeColor(vg, nvgRGBA(0,0,0,64) ); nvgStroke(vg); // Select circle on triangle ax = cosf(120.0f/180.0f*NVG_PI) * r*0.3f; ay = sinf(120.0f/180.0f*NVG_PI) * r*0.4f; nvgStrokeWidth(vg, 2.0f); nvgBeginPath(vg); nvgCircle(vg, ax,ay,5); nvgStrokeColor(vg, nvgRGBA(255,255,255,192) ); nvgStroke(vg); paint = nvgRadialGradient(vg, ax,ay, 7,9, nvgRGBA(0,0,0,64), nvgRGBA(0,0,0,0) ); nvgBeginPath(vg); nvgRect(vg, ax-20,ay-20,40,40); nvgCircle(vg, ax,ay,7); nvgPathWinding(vg, NVG_HOLE); nvgFillPaint(vg, paint); nvgFill(vg); nvgRestore(vg); nvgRestore(vg); }
Color Color::fromHSL(float hue, float saturation, float lightness, float alpha) { return nvgHSLA(hue, saturation, lightness, static_cast<uchar>(getFixedRange(alpha)*255.0f)); }
JNIEXPORT void Java_firststep_internal_NVG_00024Color_putHSLA(JNIEnv *e, jobject o, jfloat h, jfloat s, jfloat l, jfloat a) { NVGcolor c = nvgHSLA(h, s, l, (char)(a * 255)); void *ptr = getBuffPtr(e, o); memcpy(ptr, &c, sizeof(NVGcolor)); }