*/}}
Browse Source

Gradient in materials

YimingWu 1 year ago
parent
commit
a18a42ea1e
5 changed files with 67 additions and 10 deletions
  1. 12 5
      la_tns.h
  2. 2 2
      la_tns_kernel.c
  3. 5 1
      la_tns_shape.c
  4. 32 2
      resources/la_properties.c
  5. 16 0
      resources/la_templates.c

+ 12 - 5
la_tns.h

@@ -19,6 +19,7 @@
 #pragma once
 
 #include "la_5.h"
+#include <nanovg.h>
 //#include "tinycthread.h"
 #include <float.h>
 
@@ -574,20 +575,25 @@ STRUCTURE(tnsMakeTransformNode){
 #define TNS_ID_TO_COLOR(color, i) \
     {color[0]=(real)((i & 0x000000FF)>>0)/255.0; color[1]=(real)((i & 0x0000FF00)>>8)/255.0; color[2]=(real)((i & 0x00FF0000)>>16)/255.0;}
 
+#define TNS_GRADIENT_MODE_LINEAR 1
+#define TNS_GRADIENT_MODE_BOX    2
+#define TNS_GRADIENT_MODE_RADIAL 3
+
 STRUCTURE(tnsMaterial){
     laListItem Item;
     laSafeString *Name;
-    real Color[4];
+    real Color[4], Color2[4];
     int Colorful;
     int AsLibrary;
     laRackPage* Page;
     tnsShader* Shader;
+    int GradientMode;
+    tnsVector2d GradientCenter;
+    tnsVector2d GradientSize;
+    real GradientBoxR,GradientBoxF;
+    NVGpaint Paint;
 };
 
-#define TNS_CAMERA_PERSPECTIVE 0
-#define TNS_CAMERA_ORTHO 1
-#define TNS_CAMERA_FISHEYE 2
-
 STRUCTURE(tnsRootObject){
     tnsObject Base;
 
@@ -1282,6 +1288,7 @@ tnsMaterialSlot* tnsNewMaterialSlot(tnsObject* o);
 void tnsRemoveMaterialSlot(tnsObject* o, tnsMaterialSlot* ms);
 void tnsAssignMaterialSlot(tnsObject* o, tnsMaterialSlot* ms);
 
+void tns_RefreshMaterial2D(tnsMaterial* m);
 void tnsRefreshMaterialLibraries();
 void tnsEnsureMaterialShader(tnsMaterial* mat, int Refresh);
 

+ 2 - 2
la_tns_kernel.c

@@ -4183,9 +4183,9 @@ void tnsDrawCursor(tnsObject* root){
 tnsMaterial *tnsCreateMaterial(char *Name){
     tnsMaterial *m; if(!Name || !Name[0]) return 0;
     m = memAcquireHyper(sizeof(tnsMaterial));
-    strSafeSet(&m->Name, Name); tnsVectorSet4(m->Color,0.8,0.8,0.8,1);
+    strSafeSet(&m->Name, Name); tnsVectorSet4(m->Color,0.8,0.8,0.8,1); tnsVectorSet4(m->Color2,0.8,0.8,0.8,1);
     m->Page=memAcquire(sizeof(laRackPage));
-    lstAppendItem(&T->World->Materials, m);
+    lstAppendItem(&T->World->Materials, m); tns_RefreshMaterial2D(m);
     return m;
 }
 tnsMaterial *tnsFindMaterial(char *name){

+ 5 - 1
la_tns_shape.c

@@ -277,7 +277,11 @@ void tns_DrawShape(tnsShape* s, tnsMaterial* mat, real* override_color, int Draw
         nvgClosePath(vg);
         nvgPathWinding(vg,(s->flags&TNS_SHAPE_HOLE)?NVG_HOLE:NVG_SOLID);
         if(!(s->flags&TNS_SHAPE_HOLE)){
-            nvgFillColor(vg, override_color?nvgRGBAf(LA_COLOR4(override_color)):(mat?nvgRGBAf(LA_COLOR4(mat->Color)):nvgRGBAf(0.8,0.8,0.8,1)));
+            if((!override_color) && mat && mat->GradientMode){
+                nvgFillPaint(vg,mat->Paint);
+            }else{
+                nvgFillColor(vg, override_color?nvgRGBAf(LA_COLOR4(override_color)):(mat?nvgRGBAf(LA_COLOR4(mat->Color)):nvgRGBAf(0.8,0.8,0.8,1)));
+            }
         }
     }
     if(DrawEdit || (!closed)){

+ 32 - 2
resources/la_properties.c

@@ -811,6 +811,7 @@ void tnspost_World(tnsWorld *w){
     tnsRefreshMaterialLibraries();
 }
 void tnspost_Material(tnsMaterial *m){
+    tns_RefreshMaterial2D(m);
     //if(m->AsLibrary){ tnsRefreshMaterialLibraries(); return; }
     //tnsEnsureMaterialShader(m,1);
 }
@@ -896,8 +897,27 @@ void tns_InvalidateMeshWithMaterial(tnsMaterial* m){
     }
 }
 void tnsset_MaterialColor(tnsMaterial* m, real* c){
-    tnsVectorCopy4d(c,m->Color); tns_InvalidateMeshWithMaterial(m); laNotifyUsers("tns.world");
+    tnsVectorCopy4d(c,m->Color); tns_InvalidateMeshWithMaterial(m); tns_RefreshMaterial2D(m); laNotifyUsers("tns.world");
+}
+void tns_RefreshMaterial2D(tnsMaterial* m){
+    NVGcontext* vg=MAIN.CurrentWindow->nvg;
+    if(m->GradientMode==TNS_GRADIENT_MODE_LINEAR){
+        m->Paint=nvgLinearGradient(vg,m->GradientCenter[0],m->GradientCenter[1],m->GradientSize[0],m->GradientSize[1],
+            nvgRGBAf(LA_COLOR4(m->Color)),nvgRGBAf(LA_COLOR4(m->Color2)));
+    }elif(m->GradientMode==TNS_GRADIENT_MODE_BOX){
+        m->Paint=nvgBoxGradient(vg,m->GradientCenter[0],m->GradientCenter[1],m->GradientSize[0],m->GradientSize[1],
+            m->GradientBoxR,m->GradientBoxF,nvgRGBAf(LA_COLOR4(m->Color)),nvgRGBAf(LA_COLOR4(m->Color2)));
+    }elif(m->GradientMode==TNS_GRADIENT_MODE_RADIAL){
+        m->Paint=nvgRadialGradient(vg,m->GradientCenter[0],m->GradientCenter[1],m->GradientSize[0],m->GradientSize[1],
+            nvgRGBAf(LA_COLOR4(m->Color)),nvgRGBAf(LA_COLOR4(m->Color2)));
+    }
 }
+void tnsset_MaterialColor2(tnsMaterial* m, real* c){ tnsVectorCopy4d(c,m->Color2); tns_RefreshMaterial2D(m); laNotifyUsers("tns.world"); }
+void tnsset_MaterialGradientMode(tnsMaterial* m, int Mode){ m->GradientMode=Mode; tns_RefreshMaterial2D(m); laNotifyUsers("tns.world"); }
+void tnsset_MaterialGradientCenter(tnsMaterial* m, real* c){ tnsVectorCopy2d(c,m->GradientCenter); tns_RefreshMaterial2D(m); laNotifyUsers("tns.world"); }
+void tnsset_MaterialGradientSize(tnsMaterial* m, real* c){ tnsVectorCopy2d(c,m->GradientSize); tns_RefreshMaterial2D(m); laNotifyUsers("tns.world"); }
+void tnsset_MaterialGradientF(tnsMaterial* m, real c){ m->GradientBoxF=c; tns_RefreshMaterial2D(m); laNotifyUsers("tns.world"); }
+void tnsset_MaterialGradientR(tnsMaterial* m, real c){ m->GradientBoxR=c; tns_RefreshMaterial2D(m); laNotifyUsers("tns.world"); }
 void tnsget_MaterialSlotname(tnsMaterialSlot* ms, char *result, char** here){
     if(!ms){ strcpy(result,"?"); return; }
     if(ms->Material&&ms->Material->Name&&ms->Material->Name->Ptr){
@@ -1131,7 +1151,8 @@ void la_RegisterTNSProps(){
     p = laAddPropertyContainer("tns_material", "Material" "Object material", 0,0,0,sizeof(tnsMaterial),tnspost_Material,0,2);{
         TNS_PC_MATERIAL=p;
         laAddStringProperty(p, "name", "Material Name", "The name ff the material", 0,0,0,0,1, offsetof(tnsMaterial, Name), 0,0,0,0,LA_AS_IDENTIFIER);
-        laAddFloatProperty(p, "color", "Color", "Base color of the material", LA_WIDGET_FLOAT_COLOR, "R,G,B,A", 0,1,0,0.025, 1, 0,offsetof(tnsMaterial, Color), 0,0,4, 0,0,0,0,tnsset_MaterialColor, 0,0,0);
+        laAddFloatProperty(p, "color", "Color", "Base color of the material", LA_WIDGET_FLOAT_COLOR, "R,G,B,A", 0,1,0,0.025, 1, 0,offsetof(tnsMaterial, Color), 0,0,4, 0,0,0,0,tnsset_MaterialColor,0,0,0);
+        laAddFloatProperty(p, "color2", "Color 2", "Gradient end color of the material", LA_WIDGET_FLOAT_COLOR, "R,G,B,A", 0,1,0,0.025, 1, 0,offsetof(tnsMaterial, Color2), 0,0,4, 0,0,0,0,tnsset_MaterialColor2,0,0,0);
         ep = laAddEnumProperty(p, "colorful", "Colorful", "Use colorful display", 0,0,0,0,0,offsetof(tnsMaterial, Colorful), 0,0,0,0,0,0,0,0,0,0);{
             laAddEnumItemAs(ep, "NONE", "None", "Display materials normally",0,0);
             laAddEnumItemAs(ep, "COLORFUL", "Colorful", "Display material with colorful halftone",1,0);
@@ -1140,6 +1161,15 @@ void la_RegisterTNSProps(){
             laAddEnumItemAs(ep, "NONE", "None", "Use as normal material",0,0);
             laAddEnumItemAs(ep, "LIBRARY", "LIBRARY", "As commom library",1,0);
         }
+        ep=laAddEnumProperty(p,"gradient_mode","Gradient Mode","2D Gradient mode of shapes",0,0,0,0,0,offsetof(tnsMaterial,GradientMode),0,tnsset_MaterialGradientMode,0,0,0,0,0,0,0,0);
+        laAddEnumItemAs(ep,"NONE","None","Don't do any gradient",0,0);
+        laAddEnumItemAs(ep,"LINEAR","Linear","Do linear gradient",TNS_GRADIENT_MODE_LINEAR,0);
+        laAddEnumItemAs(ep,"BOX","Box","Do box gradient",TNS_GRADIENT_MODE_BOX,0);
+        laAddEnumItemAs(ep,"RADIAL","Radial","Do radial gradient",TNS_GRADIENT_MODE_RADIAL,0);
+        laAddFloatProperty(p,"gradient_center","Gradient Center","Starting point of the gradient",0,0,0,0,0,0,0,0,offsetof(tnsMaterial,GradientCenter),0,0,2,0,0,0,0,tnsset_MaterialGradientCenter,0,0,0);
+        laAddFloatProperty(p,"gradient_size","Gradient Size","Size of the gradient",0,0,0,0,0,0,0,0,offsetof(tnsMaterial,GradientSize),0,0,2,0,0,0,0,tnsset_MaterialGradientSize,0,0,0);
+        laAddFloatProperty(p,"gradient_box_r","Corner","Corner radius of the box gradient",0,0,0,0,0,0,0,0,offsetof(tnsMaterial,GradientBoxR),0,tnsset_MaterialGradientR,0,0,0,0,0,0,0,0,0);
+        laAddFloatProperty(p,"gradient_box_f","Feather","Feather distance of the box gradient",0,0,0,0,0,0,0,0,offsetof(tnsMaterial,GradientBoxF),0,tnsset_MaterialGradientF,0,0,0,0,0,0,0,0,0);
         laAddSubGroup(p, "shader_page", "Shader Page", "Shader page of this material","la_rack_page",0,0,0,offsetof(tnsMaterial,Page),0,0,0,0,0,0,0,LA_UDF_SINGLE|LA_HIDE_IN_SAVE);
         laAddOperatorProperty(p,"refresh","Refresh","Refresh material shader","M_refresh_material_shader",L'🗘',0);
         laAddOperatorProperty(p,"remove","Remove","Remove this material","M_remove_material",L'🗴',0);

+ 16 - 0
resources/la_templates.c

@@ -1823,6 +1823,22 @@ void tnsui_Material(laUiList *uil, laPropPack *This, laPropPack *UNUSED_Extra, l
         laShowItemFull(uil,cr,This,"color",LA_WIDGET_FLOAT_COLOR,0,0,0)->Flags|=LA_UI_FLAGS_COLORFUL;
         laShowItemFull(uil,cr,This,"colorful",LA_WIDGET_ENUM_HIGHLIGHT,0,0,0);
     }laEndCondition(uil,b2);
+
+    laShowSeparator(uil,c);
+    laShowItemFull(uil,c,This,"gradient_mode",0,0,0,0)->Flags|=LA_UI_FLAGS_EXPAND;
+    b1=laOnConditionThat(uil,c,laPropExpression(This,"gradient_mode"));{
+        laShowLabel(uil,cl,"End Color",0,0);
+        laShowItemFull(uil,cr,This,"color2",LA_WIDGET_FLOAT_COLOR,0,0,0)->Flags|=LA_UI_FLAGS_COLORFUL;
+        laShowLabel(uil,cl,"Center",0,0);
+        laShowItemFull(uil,cr,This,"gradient_center",0,0,0,0);
+        laShowLabel(uil,cl,"Size",0,0);
+        laShowItemFull(uil,cr,This,"gradient_size",0,0,0,0);
+        b2=laOnConditionThat(uil,c,laEqual(laPropExpression(This,"gradient_mode"),laIntExpression(TNS_GRADIENT_MODE_BOX)));{
+        laShowItemFull(uil,cr,This,"gradient_box_r",0,0,0,0);
+        laShowItemFull(uil,cr,This,"gradient_box_f",0,0,0,0);
+        }laEndCondition(uil,b2);
+    }laEndCondition(uil,b1);
+    
 }
 void tnsui_MaterialListItem(laUiList *uil, laPropPack *This, laPropPack *UNUSED_Extra, laColumn *UNUSED_Colums, int context){
     laColumn* c=laFirstColumn(uil); laUiItem* b,*b1;