*/}}
ソースを参照

Our paint init

Yiming Wu 1 年間 前
コミット
6de9d87af4
3 ファイル変更271 行追加0 行削除
  1. 96 0
      source/OurPaint/ouroperations.c
  2. 124 0
      source/OurPaint/ourpaint.c
  3. 51 0
      source/OurPaint/ourpaint.h

+ 96 - 0
source/OurPaint/ouroperations.c

@@ -0,0 +1,96 @@
+#include "ourpaint.h"
+
+OurPaint *Our;
+
+const char OUR_CANVAS_SHADER[]="#version 430\n\
+layout(local_size_x = 32, local_size_y = 32, local_size_z = 1) in;\n\
+layout(rgba8, binding = 0) coherent uniform image2D img;\n\
+layout(std430, binding = 1) buffer CCOLOR { float ccolor[4]; };\n\
+uniform ivec2 Task;\n\
+\n\
+int dab(float d, vec4 color, float size, float hardness, float smudge, vec4 smudge_color, vec4 last_color, out vec4 final){\n\
+    color.rgb=mix(color,smudge_color,smudge).rgb;\n\
+    float a=clamp(color.a*1-pow(d/size,1+1/(1-hardness)),0,1);\n\
+    final=vec4(mix(last_color.rgb,color.rgb,a), 1-(1-last_color.a)*(1-a));\n\
+    return 1;\n\
+}\n\
+ivec2 DabPos(int i){\n\
+    return ivec2(mod(i,500)+250,i/500*50+100);\n\
+}\n\
+void main() {\n\
+    ivec2 px = ivec2(gl_GlobalInvocationID.xy);\n\
+    if(Task.x<1){\n\
+        vec4 pixel =px.x>500?vec4(0.2,0.2,0.9,1.0):(px.x>400?vec4(0.0,0.0,0.0,1.0):(px.x>300?vec4(1.0,0.2,0.2,1.0):vec4(1.0,1.0,0.2,1.0)));\n\
+        imageStore(img, px, pixel);\n\ return;}\n\
+    int ii=Task.x;\n\
+    float dd=distance(px,vec2(DabPos(ii*20))); if(dd>200) return;\n\
+    vec4 final;\n\
+    vec4 dabc=imageLoad(img, px);\n\
+    memoryBarrier();barrier(); \n\
+    vec4 smugec=imageLoad(img, DabPos(ii*20));\n\
+    int any=0;\n\
+    for(int t=0;t<20;t++){\n\
+        int i=t+ii*20;\n\
+        float size=15;\n\
+        float d=distance(px,vec2(DabPos(i))); if(d>size) continue;\n\
+        dab(d,vec4(1,1,1,0.1),size,0.95,0.95,smugec,dabc,final);\n\
+        dabc=final;\n\
+    }\n\
+    if(dd!=0) imageStore(img, px, dabc); //else ccolor=dabc;\n\
+}\n\
+";
+
+OurLayer* our_NewLayer(char* name){
+    OurLayer* l=memAcquire(sizeof(OurLayer)); strSafeSet(&l->Name,name); lstPushItem(&Our->Layers, l);
+    return l;
+}
+void our_RemoveLayer(OurLayer* l){
+    strSafeDestroy(&l->Name); lstRemoveItem(&Our->Layers, l);
+}
+
+void ourinv_NewLayer(laOperator* a, laEvent* e){
+    our_NewLayer("New Layer"); laNotifyUsers("our.canvas.layers");
+    return LA_FINISHED;
+}
+void ourinv_RemoveLayer(laOperator* a, laEvent* e){
+    OurLayer* l=a->This?a->This->EndInstance:0; if(!l) return LA_CANCELED;
+    our_RemoveLayer(l); laNotifyUsers("our.canvas.layers");
+    return LA_FINISHED;
+}
+
+
+void ourInit(){
+    Our=memAcquire(sizeof(OurPaint));
+
+    laCreateOperatorType("OUR_new_layer","New Layer","Create a new layer",0,0,0,ourinv_NewLayer,0,'+',0);
+    laCreateOperatorType("OUR_remove_layer","Remove Layer","Remove this layer",0,0,0,ourinv_RemoveLayer,0,L'🗴',0);
+
+    char error[1024]; int status;
+
+    Our->CanvasShader = glCreateShader(GL_COMPUTE_SHADER);
+    const GLchar* source = OUR_CANVAS_SHADER;
+    glShaderSource(Our->CanvasShader, 1, &source, NULL);
+    glCompileShader(Our->CanvasShader);
+    glGetShaderiv(Our->CanvasShader, GL_COMPILE_STATUS, &status);
+    if (status == GL_FALSE){
+        glGetShaderInfoLog(Our->CanvasShader, sizeof(error), 0, error);
+        printf("Compute shader error:\n%s", error);
+        glDeleteShader(Our->CanvasShader);
+        return -1;
+    }
+
+    Our->CanvasProgram = glCreateProgram();
+    glAttachShader(Our->CanvasProgram, Our->CanvasShader);
+    glLinkProgram(Our->CanvasProgram);
+    glGetProgramiv(Our->CanvasProgram, GL_LINK_STATUS, &status);
+    if (status == GL_FALSE){
+        glGetProgramInfoLog(Our->CanvasProgram, sizeof(error), 0, error);
+        printf("Shader Linking error:\n%s", error);
+        return 0;
+    }
+
+    Our->CanvasTaskUniform=glGetUniformLocation(Our->CanvasProgram,"Task");
+
+    tnsEnableShaderv(0);
+}
+

+ 124 - 0
source/OurPaint/ourpaint.c

@@ -0,0 +1,124 @@
+#include "ourpaint.h"
+
+extern LA MAIN;
+extern tnsMain* T;
+extern OurPaint *Our;
+
+void CanvasPanel(laUiList *uil, laPropPack *This, laPropPack *DetachedProps, laColumn *UNUSED, int context){
+    laColumn* c=laFirstColumn(uil);
+    
+    laUiItem* ui=laShowCanvas(uil,c,0,"our.canvas",0,-1);
+}
+
+void* ourget_our(void* unused, void* unused1){
+    return Our;
+}
+
+void our_CanvasDrawInit(laUiItem* ui){
+    la_CanvasInit(ui);
+
+    int work_grp_cnt[3];
+    glGetIntegeri_v(GL_MAX_COMPUTE_WORK_GROUP_COUNT, 0, &work_grp_cnt[0]);
+    glGetIntegeri_v(GL_MAX_COMPUTE_WORK_GROUP_COUNT, 1, &work_grp_cnt[1]);
+    glGetIntegeri_v(GL_MAX_COMPUTE_WORK_GROUP_COUNT, 2, &work_grp_cnt[2]);
+    printf("max global (total) work group counts x:%i y:%i z:%i\n", work_grp_cnt[0], work_grp_cnt[1], work_grp_cnt[2]);
+
+    int work_grp_size[3];
+    glGetIntegeri_v(GL_MAX_COMPUTE_WORK_GROUP_SIZE, 0, &work_grp_size[0]);
+    glGetIntegeri_v(GL_MAX_COMPUTE_WORK_GROUP_SIZE, 1, &work_grp_size[1]);
+    glGetIntegeri_v(GL_MAX_COMPUTE_WORK_GROUP_SIZE, 2, &work_grp_size[2]);
+    printf("max local (in one shader) work group sizes x:%i y:%i z:%i\n", work_grp_size[0], work_grp_size[1], work_grp_size[2]);
+
+    int work_grp_inv;
+    glGetIntegerv(GL_MAX_COMPUTE_WORK_GROUP_INVOCATIONS, &work_grp_inv);
+    printf("max local work group invocations %i\n", work_grp_inv);
+}
+void our_CanvasDrawCanvas(laBoxedTheme *bt, OurCanvas *unused_c, laUiItem* ui){
+    OurCanvasDraw* ocd=ui->Extra; OurCanvas* oc=ui->PP.EndInstance; laCanvasExtra*e=&ocd->Base;
+    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_RGBA, W, H, 0, 0);
+    }
+
+    if(!oc->Content){
+        oc->Content=tnsCreate2DTexture(GL_RGBA8,1024,1024,0);
+    }
+
+    tnsBindTexture(oc->Content);
+    glBindImageTexture(0, oc->Content->GLTexHandle, 0, GL_FALSE, 0, GL_READ_WRITE, GL_RGBA8);
+
+    glUseProgram(Our->CanvasProgram);
+    
+
+    for(int i=0;i<100;i++){
+        glUniform2i(Our->CanvasTaskUniform,i,0);
+        glDispatchCompute(32, 32, 1);
+        glMemoryBarrier(GL_SHADER_IMAGE_ACCESS_BARRIER_BIT);
+    }
+    //for(int i=0;i<32;i++){
+    //    for(int j=0;j<32;j++){
+    //        glUniform2i(Our->CanvasTaskUniform,i,j);
+    //        glDispatchCompute(1, 1, 1);
+    //        glMemoryBarrier(GL_SHADER_IMAGE_ACCESS_BARRIER_BIT);
+    //    }
+    //}
+
+    tnsEnableShaderv(T->immShader); tnsUseImmShader();
+    
+    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);
+
+    glClearColor(0,0,0,0); glClear(GL_COLOR_BUFFER_BIT);
+
+    real w2=oc->Content->Width/2, h2=oc->Content->Height/2;
+    tnsDraw2DTextureDirectly(oc->Content, -w2, h2, oc->Content->Width, -oc->Content->Height);
+    tnsFlush();
+}
+
+
+void ourRegisterEverything(){
+    laPropContainer* pc; laKeyMapper* km;
+
+    laRegisterUiTemplate("panel_canvas", "Canvas", CanvasPanel, 0, 0);
+    
+    pc=laDefineRoot();
+    laAddSubGroup(pc,"our","Our","OurPaint main","our_paint",0,0,0,-1,ourget_our,0,0,0,0,0,0,0);
+
+    pc=laAddPropertyContainer("our_paint","Our Paint","OurPaint main",0,0,sizeof(OurPaint),0,0,1);
+    laAddSubGroup(pc,"canvas","Canvas","OurPaint canvas","our_canvas",0,0,0,offsetof(OurPaint,Canvas),0,0,0,0,0,0,0,LA_UDF_SINGLE);
+
+    pc=laAddPropertyContainer("our_canvas","Our Canvas","OurPaint canvas",0,0,sizeof(OurCanvas),0,0,1);
+
+    laCanvasTemplate* ct=laRegisterCanvasTemplate("our_CanvasDraw", "our_canvas", 0, our_CanvasDrawCanvas, la_CanvasDrawOverlay, our_CanvasDrawInit, la_CanvasDestroy);
+    pc = laCanvasHasExtraProps(ct,sizeof(OurCanvasDraw),2);
+    km = &ct->KeyMapper;
+    laAssignNewKey(km, 0, "LA_2d_view_zoom", LA_KM_SEL_UI_EXTRA, 0, LA_MOUSE_WHEEL_DOWN, 0, "direction=out");
+    laAssignNewKey(km, 0, "LA_2d_view_zoom", LA_KM_SEL_UI_EXTRA, 0, LA_MOUSE_WHEEL_UP, 0, "direction=in");
+    laAssignNewKey(km, 0, "LA_2d_view_move", LA_KM_SEL_UI_EXTRA, LA_KEY_ALT, LA_L_MOUSE_DOWN, 0, 0);
+    laAssignNewKey(km, 0, "LA_2d_view_click", LA_KM_SEL_UI_EXTRA, 0, LA_L_MOUSE_DOWN, 0, 0);
+}
+
+int main(int argc, char *argv[]){
+    laGetReady();
+
+    ourInit();
+
+    ourRegisterEverything();
+
+    laRefreshUDFRegistries();
+    laEnsureUserPreferences();
+
+    laWindow* w = laDesignWindow(-1,-1,600,600);
+
+    laLayout* l = laDesignLayout(w, "Our Paint");
+    laBlock* b = l->FirstBlock;
+    laCreatePanel(b, "panel_canvas");
+
+    laStartWindow(w);
+    laMainLoop();
+}

+ 51 - 0
source/OurPaint/ourpaint.h

@@ -0,0 +1,51 @@
+#include "la_5.h"
+
+STRUCTURE(OurCanvasDraw){
+    laCanvasExtra Base;
+};
+
+
+STRUCTURE(OurRow){
+    laListItem Item;
+    laListHandle Tiles;
+    int Y;
+};
+STRUCTURE(OurTile){
+    laListItem Item;
+    OurRow Row;
+    void* Data;
+    int X; 
+};
+STRUCTURE(OurTexRow){
+    laListItem Item;
+    laListHandle Tiles;
+    int Y;
+};
+STRUCTURE(OurTexTile){
+    laListItem Item;
+    OurRow Row;
+    tnsTexture* Texture;
+    int X;
+};
+
+STRUCTURE(OurLayer){
+    laListItem Item;
+    laSafeString Name;
+    int OffsetX,OffsetY;
+    laListHandle Rows;
+    laListHandle TextureRows;
+};
+
+STRUCTURE(OurPaint){
+    real pad;
+
+    laListHandle Layers;
+
+    tnsTexture* Content;
+    GLuint CanvasShader;
+    GLuint CanvasProgram;
+    GLint CanvasTaskUniform;
+};
+
+void ourInit();
+