void update(float dt) { PROFILER_CPU_TIMESLICE("ui->update"); memcpy(keyStatePrev, keyStateCurr, SDL_NUM_SCANCODES); memcpy(keyStateCurr, SDL_GetKeyboardState(NULL), SDL_NUM_SCANCODES); mouseStatePrev = mouseStateCurr; mouseStateCurr = SDL_GetMouseState(&mouseX, &mouseY); SDL_GetRelativeMouseState(&deltaX, &deltaY); mouseWheelUp = mouseWheelDown = false; processInputEvents(); if (profilerState == PROF_STATE_DATA_RETRIEVAL) { profilerState = PROF_STATE_NO_CAPTURE; overlayProfiler->loadProfilerData(); } else if ( profilerState==PROF_STATE_TIMESLICE_CAPTURE && ui::keyIsPressed(SDL_SCANCODE_GRAVE) && ui::keyWasReleased(SDL_SCANCODE_T) ) { profilerState = PROF_STATE_DATA_RETRIEVAL; profilerStopCapture(); } else if (profilerState == PROF_STATE_FRAME_CAPTURE) { profilerState = PROF_STATE_DATA_RETRIEVAL; profilerStopCapture(); } else if ( profilerState==PROF_STATE_NO_CAPTURE && ui::keyIsPressed(SDL_SCANCODE_GRAVE) && ui::keyWasReleased(SDL_SCANCODE_T) ) { profilerState = PROF_STATE_TIMESLICE_CAPTURE; profilerStartCapture(); } else if ( profilerState==PROF_STATE_NO_CAPTURE && ui::keyIsPressed(SDL_SCANCODE_GRAVE) && ui::keyWasReleased(SDL_SCANCODE_F) ) { profilerState = PROF_STATE_FRAME_CAPTURE; profilerStartCapture(); } else if ( profilerState!=PROF_STATE_NO_CAPTURE && profilerState!=PROF_STATE_TIMESLICE_CAPTURE ) { assert(!"Invalid state"); } if (uiState==STATE_PROFILER) { PROFILER_CPU_TIMESLICE("mProfilerOverlay->updateUI"); overlayProfiler->updateUI(dt); } else if (uiState==STATE_DEFAULT) { PROFILER_CPU_TIMESLICE("onUpdate"); } if (overlayShaderEdit->requireReset()) { PROFILER_CPU_TIMESLICE("onShaderRecompile"); fwk::recompilePrograms(); } checkBoxUpdateAll(); }
static void glnvg__renderFill(void* uptr, NVGpaint* paint, NVGscissor* scissor, float fringe, const float* bounds, const NVGpath* paths, int npaths) { PROFILER_CPU_TIMESLICE("NVG backend renderFill"); GLNVGcontext* gl = (GLNVGcontext*)uptr; GLNVGcall* call = glnvg__allocCall(gl); GLNVGfragUniforms* frag; GLuint maxverts, offset; if (call == NULL) return; call->type = GLNVG_FILL; call->pathOffset = glnvg__allocPaths(gl, npaths); if (call->pathOffset == -1) goto error; call->pathCount = npaths; call->image = paint->image; if (npaths == 1 && paths[0].convex) call->type = GLNVG_CONVEXFILL; // Allocate vertices for all the paths. maxverts = glnvg__maxVertCount(paths, npaths) + 6; NVGvertex* vtx = gfx::frameAllocVertices<NVGvertex>(maxverts, &offset); if (!vtx) goto error; for (int i = 0; i < npaths; i++) { GLNVGpath* copy = &gl->paths[call->pathOffset + i]; const NVGpath* path = &paths[i]; mem_zero(copy); if (path->nfill > 0) { copy->fillOffset = offset; copy->fillCount = path->nfill; mem_copy(vtx, path->fill, sizeof(NVGvertex) * path->nfill); offset += path->nfill; vtx += path->nfill; } if (path->nstroke > 0) { copy->strokeOffset = offset; copy->strokeCount = path->nstroke; mem_copy(vtx, path->stroke, sizeof(NVGvertex) * path->nstroke); offset += path->nstroke; vtx += path->nstroke; } } // Quad call->triangleOffset = offset; call->triangleCount = 6; *vtx++ = {bounds[0], bounds[3], 0.5f, 1.0f}; *vtx++ = {bounds[2], bounds[3], 0.5f, 1.0f}; *vtx++ = {bounds[2], bounds[1], 0.5f, 1.0f}; *vtx++ = {bounds[0], bounds[3], 0.5f, 1.0f}; *vtx++ = {bounds[2], bounds[1], 0.5f, 1.0f}; *vtx++ = {bounds[0], bounds[1], 0.5f, 1.0f}; gfx::dynbufAlignMem(gfx::caps.uboAlignment, &call->uniformOffset); // Setup uniforms for draw calls if (call->type == GLNVG_FILL) { // Simple shader for stencil frag = (GLNVGfragUniforms*)gfx::dynbufAlloc(gl->fragSize); if (!frag) goto error; mem_zero(frag); frag->strokeThr = -1.0f; frag->type = NSVG_SHADER_SIMPLE; // Fill shader frag = (GLNVGfragUniforms*)gfx::dynbufAlloc(gl->fragSize); if (!frag) goto error; glnvg__convertPaint(gl, frag, paint, scissor, fringe, fringe, -1.0f); } else { // Fill shader frag = (GLNVGfragUniforms*)gfx::dynbufAlloc(gl->fragSize); if (!frag) goto error; glnvg__convertPaint(gl, frag, paint, scissor, fringe, fringe, -1.0f); } return; error: // We get here if call alloc was ok, but something else is not. // Roll back the last call to prevent drawing it. if (gl->ncalls > 0) gl->ncalls--; }
static void glnvg__renderStroke(void* uptr, NVGpaint* paint, NVGscissor* scissor, float fringe, float strokeWidth, const NVGpath* paths, int npaths) { PROFILER_CPU_TIMESLICE("NVG backend renderStroke"); GLNVGcontext* gl = (GLNVGcontext*)uptr; GLNVGcall* call = glnvg__allocCall(gl); GLuint maxverts, offset; if (call == NULL) return; call->type = GLNVG_STROKE; call->pathOffset = glnvg__allocPaths(gl, npaths); if (call->pathOffset == -1) goto error; call->pathCount = npaths; call->image = paint->image; // Allocate vertices for all the paths. maxverts = glnvg__maxVertCount(paths, npaths); NVGvertex* vtx = gfx::frameAllocVertices<NVGvertex>(maxverts, &offset); if (!vtx) goto error; for (int i = 0; i < npaths; i++) { GLNVGpath* copy = &gl->paths[call->pathOffset + i]; const NVGpath* path = &paths[i]; mem_zero(copy); if (path->nstroke) { copy->strokeOffset = offset; copy->strokeCount = path->nstroke; mem_copy(vtx, path->stroke, sizeof(NVGvertex) * path->nstroke); offset += path->nstroke; vtx += path->nstroke; } } GLNVGfragUniforms* frag; gfx::dynbufAlignMem(gfx::caps.uboAlignment, &call->uniformOffset); if (gl->flags & NVG_STENCIL_STROKES) { // Fill shader frag = (GLNVGfragUniforms*)gfx::dynbufAlloc(gl->fragSize); if (!frag) goto error; glnvg__convertPaint(gl, frag, paint, scissor, strokeWidth, fringe, -1.0f); frag = (GLNVGfragUniforms*)gfx::dynbufAlloc(gl->fragSize); if (!frag) goto error; glnvg__convertPaint(gl, frag, paint, scissor, strokeWidth, fringe, 1.0f - 0.5f / 255.0f); } else { // Fill shader frag = (GLNVGfragUniforms*)gfx::dynbufAlloc(gl->fragSize); if (!frag) goto error; glnvg__convertPaint(gl, frag, paint, scissor, strokeWidth, fringe, -1.0f); } return; error: // We get here if call alloc was ok, but something else is not. // Roll back the last call to prevent drawing it. if (gl->ncalls > 0) gl->ncalls--; }
static int glnvg__convertPaint(GLNVGcontext* gl, GLNVGfragUniforms* frag, NVGpaint* paint, NVGscissor* scissor, float width, float fringe, float strokeThr) { PROFILER_CPU_TIMESLICE("NVG backend convertPaint"); GLNVGtexture* tex = NULL; float invxform[6]; mem_zero(frag); frag->innerCol = glnvg__premulColor(paint->innerColor); frag->outerCol = glnvg__premulColor(paint->outerColor); if (scissor->extent[0] < -0.5f || scissor->extent[1] < -0.5f) { mem_zero(frag->scissorMat); frag->scissorExt[0] = 1.0f; frag->scissorExt[1] = 1.0f; frag->scissorScale[0] = 1.0f; frag->scissorScale[1] = 1.0f; } else { nvgTransformInverse(invxform, scissor->xform); glnvg__xformToMat3x4(frag->scissorMat, invxform); frag->scissorExt[0] = scissor->extent[0]; frag->scissorExt[1] = scissor->extent[1]; frag->scissorScale[0] = ml::sqrt(scissor->xform[0] * scissor->xform[0] + scissor->xform[2] * scissor->xform[2]) / fringe; frag->scissorScale[1] = ml::sqrt(scissor->xform[1] * scissor->xform[1] + scissor->xform[3] * scissor->xform[3]) / fringe; } mem_copy(frag->extent, paint->extent, sizeof(frag->extent)); frag->strokeMult = (width*0.5f + fringe*0.5f) / fringe; frag->strokeThr = strokeThr; if (paint->image != 0) { tex = glnvg__findTexture(gl, paint->image); if (tex == NULL) return 0; if ((tex->flags & NVGL_TEXTURE_FLIP_Y) != 0) { float flipped[6]; nvgTransformScale(flipped, 1.0f, -1.0f); nvgTransformMultiply(flipped, paint->xform); nvgTransformInverse(invxform, flipped); } else { nvgTransformInverse(invxform, paint->xform); } frag->type = NSVG_SHADER_FILLIMG; if (tex->type == NVG_TEXTURE_RGBA) frag->texType = (tex->flags & NVGL_TEXTURE_PREMULTIPLIED) ? 0 : 1; else frag->texType = 2; // printf("frag->texType = %d\n", frag->texType); } else { frag->type = NSVG_SHADER_FILLGRAD; frag->radius = paint->radius; frag->feather = paint->feather; nvgTransformInverse(invxform, paint->xform); } glnvg__xformToMat3x4(frag->paintMat, invxform); return 1; }