*/}}
Browse Source

NanoVG demo program.

YimingWu 1 năm trước cách đây
mục cha
commit
4158713d5e
3 tập tin đã thay đổi với 230 bổ sung1 xóa
  1. 5 0
      CMakeLists.txt
  2. 15 1
      example_viewer.c
  3. 210 0
      nvgtest.c

+ 5 - 0
CMakeLists.txt

@@ -17,6 +17,7 @@ set(WidgetFlagsFiles ${CMAKE_SOURCE_DIR}/widget_flags.c)
 set(FruitsFiles ${CMAKE_SOURCE_DIR}/fruits.c)
 set(ModellingFiles ${CMAKE_SOURCE_DIR}/modelling_main.c)
 set(CalculatorFiles ${CMAKE_SOURCE_DIR}/calculator.c)
+set(NVGTestFiles ${CMAKE_SOURCE_DIR}/nvgtest.c)
 
 set(ExampleViewerFiles ${CMAKE_SOURCE_DIR}/example_viewer.c)
 
@@ -28,6 +29,8 @@ add_executable(widget_flags ${WidgetFlagsFiles})
 add_executable(fruits ${FruitsFiles})
 add_executable(modelling_main ${ModellingFiles})
 add_executable(calculator ${CalculatorFiles})
+add_executable(nvgtest ${NVGTestFiles})
+
 add_executable(example_viewer ${ExampleViewerFiles})
 
 target_link_libraries(simplest ${LAGUI_SHARED_LIBS} )
@@ -38,12 +41,14 @@ target_link_libraries(widget_flags ${LAGUI_SHARED_LIBS} )
 target_link_libraries(fruits ${LAGUI_SHARED_LIBS} )
 target_link_libraries(modelling_main ${LAGUI_SHARED_LIBS} )
 target_link_libraries(calculator ${LAGUI_SHARED_LIBS} )
+target_link_libraries(nvgtest ${LAGUI_SHARED_LIBS} )
 
 target_link_libraries(example_viewer ${LAGUI_SHARED_LIBS} )
 
 add_custom_command(
     TARGET example_viewer POST_BUILD
     COMMAND mkdir -p ${CMAKE_CURRENT_BINARY_DIR}/example_source_files
+    COMMAND cp ${CMAKE_SOURCE_DIR}/nvgtest.c        ${CMAKE_CURRENT_BINARY_DIR}/example_source_files/nvgtest.c
     COMMAND cp ${CMAKE_SOURCE_DIR}/calculator.c     ${CMAKE_CURRENT_BINARY_DIR}/example_source_files/calculator.c
     COMMAND cp ${CMAKE_SOURCE_DIR}/widgets.c        ${CMAKE_CURRENT_BINARY_DIR}/example_source_files/widgets.c
     COMMAND cp ${CMAKE_SOURCE_DIR}/widget_flags.c   ${CMAKE_CURRENT_BINARY_DIR}/example_source_files/widget_flags.c

+ 15 - 1
example_viewer.c

@@ -252,6 +252,17 @@ Modelling functionality demo\n\
 
     EXAMPLE_COMMON_END
 }
+void ui_NVGTest(laUiList *uil, laPropPack *This, laPropPack *DetachedProps, laColumn *UNUSED, int context){
+    EXAMPLE_COMMON_BEGIN
+
+    laShowLabel(uil,c,"\
+This demo shows how to use NanoVG inside LaGUI\n\
+\n\
+NanoVG is a light weight vector graph drawing library. This demo shows how to use NanoVG inside LaGUI 2D canvas.\n",
+    0,0)->Flags|=LA_TEXT_LINE_WRAP|LA_TEXT_MONO;
+    
+    EXAMPLE_COMMON_END
+}
 
 int inv_LaunchDemo(laOperator* a, laEvent* e){
     char* program=strGetArgumentString(a->ExtraInstructionsP,"program"); if(!program) return LA_FINISHED;
@@ -267,7 +278,7 @@ int inv_OpenDemoSource(laOperator* a, laEvent* e){
 }
 
 
-laPropContainer *pcGeneric,*pcFruits,*pcSimplest,*pcOperator,*pcSimpleProperties,*pcModelling,*pcCalculator,*pcWidgets,*pcWidgetFlags;
+laPropContainer *pcGeneric,*pcFruits,*pcSimplest,*pcOperator,*pcSimpleProperties,*pcModelling,*pcCalculator,*pcWidgets,*pcWidgetFlags,*pcNVGTest;
 
 void* get_ExampleViewer(void* unused){
     return EV;
@@ -281,6 +292,7 @@ laPropContainer* get_ExamplesGetType(ExampleItem* ei){
     if(ei->Define==ui_Calculator) return pcCalculator;
     if(ei->Define==ui_Widgets) return pcWidgets;
     if(ei->Define==ui_WidgetFlags) return pcWidgetFlags;
+    if(ei->Define==ui_NVGTest) return pcNVGTest;
     return pcGeneric;
 }
 void set_CurrentExample(ExampleViewer* v, ExampleItem* ei){
@@ -316,6 +328,7 @@ static void InitExamples(){
     EXAMPLE_ADD_PC("fruits",pcFruits,ui_Fruits);
     EXAMPLE_ADD_PC("widgets",pcWidgets,ui_Widgets);
     EXAMPLE_ADD_PC("widget_flags",pcWidgetFlags,ui_WidgetFlags);
+    EXAMPLE_ADD_PC("nvgtest",pcNVGTest,ui_NVGTest);
     EXAMPLE_ADD_PC("calculator",pcCalculator,ui_Calculator);
     EXAMPLE_ADD_PC("modelling_main",pcModelling,ui_Modelling);
 
@@ -325,6 +338,7 @@ static void InitExamples(){
     AddExample("Simple Properties","simple_properties",ui_SimpleProperties);
     AddExample("Widgets","widgets",ui_Widgets);
     AddExample("Widget Flags","widget_flags",ui_WidgetFlags);
+    AddExample("NanoVG Test","nvgtest",ui_NVGTest);
     AddExample("Fruits","fruits",ui_Fruits);
     AddExample("Calculator","calculator",ui_Calculator);
     AddExample("Modelling","modelling_main",ui_Modelling);

+ 210 - 0
nvgtest.c

@@ -0,0 +1,210 @@
+/*
+* Part of LaGUI demonstration programs
+* Copyright (C) 2022-2023 Wu Yiming
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 3 of the License, or
+* (at your option) any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program.  If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#define NANOVG_GL3_IMPLEMENTATION
+
+#include "la_5.h"
+extern LA MAIN;
+extern tnsMain* T;
+
+void MyPanel(laUiList *uil, laPropPack *This, laPropPack *DetachedProps, laColumn *UNUSED, int context){
+    laColumn* c=laFirstColumn(uil);
+    laShowCanvas(uil,c,0,"tns","my_nanovg_canvas",-1);
+}
+
+typedef struct MyCanvas{
+    laCanvasExtra e;
+    NVGcontext* c;
+}MyCanvas;
+
+/* From NanoVG */
+void drawColorwheel(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);
+	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);
+}
+
+
+void my_CanvasInit(laUiItem *ui){
+    MyCanvas* mye=memAcquire(sizeof(MyCanvas)); ui->Extra=mye;
+    la_CanvasInit(ui);
+    mye->c=nvgCreateGL3(NVG_STENCIL_STROKES|NVG_DEBUG|NVG_ANTIALIAS);
+}
+void my_CanvasDestroy(laUiItem *ui){
+    MyCanvas* mye=ui->Extra;
+    nvgDeleteGL3(mye->c);
+    la_CanvasDestroy(ui);
+}
+
+void my_CanvasDrawCanvas(laBoxedTheme *bt, void *unused_c, laUiItem* ui){
+    laCanvasExtra* e=ui->Extra; MyCanvas* mye=e;
+    int W, H; W = ui->R - ui->L; H = ui->B - ui->U;
+    tnsFlush();
+
+    if (!e->OffScr || e->OffScr->pColor[0]->Height != ui->B - ui->U || e->OffScr->pColor[0]->Width != ui->R - ui->L){
+        if (e->OffScr) tnsDelete2DOffscreen(e->OffScr);
+        e->OffScr = tnsCreate2DOffscreen(GL_RGBA8, W, H, 0, 0, 1);
+    }
+
+    tnsDrawToOffscreen(e->OffScr,1,0);
+    tnsViewportWithScissor(0, 0, W, H);
+    tnsResetViewMatrix();tnsResetModelMatrix();tnsResetProjectionMatrix();
+    tnsOrtho(e->PanX - W * e->ZoomX / 2, e->PanX + W * e->ZoomX / 2, e->PanY - e->ZoomY * H / 2, e->PanY + e->ZoomY * H / 2, 100, -100);
+    tnsClearColor(0,0,0,1); tnsClearAll();
+
+    NVGcontext* vg=mye->c;
+
+    nvgBeginFrame(vg,W,H,1);
+    
+    drawColorwheel(vg,0,0,W,H,1);
+
+    nvgEndFrame(vg);
+    tnsRestoreFromNanoVG();
+}
+void my_CanvasDrawOverlay(laUiItem* ui,int h){
+    laCanvasExtra *e = ui->Extra;
+    laBoxedTheme *bt = (*ui->Type->Theme);
+
+    tnsUseImmShader(); tnsEnableShaderv(T->immShader);
+    tnsUniformColorMode(T->immShader,0); tnsUniformOutputColorSpace(T->immShader, 0);
+
+    tnsDraw2DTextureDirectly(e->OffScr->pColor[0], ui->L, ui->U, ui->R - ui->L, ui->B - ui->U);
+    tnsFlush();
+
+    la_CanvasDefaultOverlay(ui, h);
+}
+
+
+int main(int argc, char *argv[]){
+    laGetReady();
+
+    transSetLanguage("zh-CN");
+
+    laCanvasTemplate* ct=laRegisterCanvasTemplate("my_nanovg_canvas", 0, 0, my_CanvasDrawCanvas, my_CanvasDrawOverlay, my_CanvasInit, my_CanvasDestroy);
+ 
+    laRegisterUiTemplate("nanovg_panel","NanoVG Panel", MyPanel,0,0,"NanoVG Demonstration", 0,0,0);
+
+    laWindow* w = laDesignWindow(-1,-1,600,600);
+    laLayout* l = laDesignLayout(w,"My Layout");
+    laCreatePanel(l->FirstBlock,"nanovg_panel");
+
+    laStartWindow(w);
+    laMainLoop();
+
+    return 0;
+}
+