*/}}
Bläddra i källkod

Managed context and container object.

YimingWu 1 år sedan
förälder
incheckning
9afe3d91e5
6 ändrade filer med 168 tillägg och 86 borttagningar
  1. 2 0
      la_interface.h
  2. 50 36
      la_kernel.c
  3. 28 4
      la_tns.h
  4. 83 39
      la_tns_kernel.c
  5. 1 1
      resources/la_properties.c
  6. 4 6
      resources/la_widgets_viewers.c

+ 2 - 0
la_interface.h

@@ -342,6 +342,7 @@ STRUCTURE(LA){
     laSafeString* CopyPending;
 
     int GLMajor,GLMinor,BufferSamples;
+    GLuint TempVAO;
     SYSTEMDISPLAY* dpy;
     SYSGLCONTEXT glc;
 #ifdef _WIN32
@@ -586,6 +587,7 @@ STRUCTURE(laWindow){
 
     SYSWINDOW* win;
     SYSGLCONTEXT glc;
+    GLuint vao;
 #ifdef _WIN32
     HDC hdc;
 #endif

+ 50 - 36
la_kernel.c

@@ -57,8 +57,7 @@ laColumn *DEBUG_C;
 #endif
 
 #ifdef __linux__
-typedef GLXContext (*glXCreateContextAttribsARBProc)(Display*, GLXFBConfig, GLXContext, Bool, const int*);
-typedef Bool (*glXMakeContextCurrentARBProc)(Display*, GLXDrawable, GLXDrawable, GLXContext);
+typedef GLXContext (*glXCreateContextAttribsARBProc)(Display*, GLXFBConfig, GLXContext, Bool, const int*);\
 typedef void (*glXSwapIntervalEXTProc)(Display *dpy, GLXDrawable drawable, int interval);
 glXCreateContextAttribsARBProc glXCreateContextAttribsF;
 glXSwapIntervalEXTProc glXSwapIntervalEXTF;
@@ -191,7 +190,7 @@ SYSWINDOW la_CreateWindowX11(int x, int y, int w, int h, char *title, int SyncTo
 
     XStoreName(MAIN.dpy, win, title);
     //XMapWindow(MAIN.dpy, win);
-    glXMakeCurrent(MAIN.dpy, win, MAIN.glc);
+    tnsContextMakeCurrent((*r_glc),win);
 
     int sync=SyncToVBlank?1:0; glXSwapIntervalEXTF(MAIN.dpy, win, sync);
 
@@ -222,8 +221,8 @@ SYSWINDOW la_CreateWindowX11(int x, int y, int w, int h, char *title, int SyncTo
     return win;
 };
 void la_DestroySystemWindowX11(laWindow* w) {
-    glXMakeCurrent(MAIN.dpy, None, NULL);
-    glXDestroyContext(MAIN.dpy, w->glc);
+    tnsContextMakeCurrent(0,0);
+    tnsDeleteContext(w->glc);
     XDestroyWindow(MAIN.dpy, w->win);
 };
 #endif //linux
@@ -350,13 +349,11 @@ void la_SetupGLEnviornment(laWindow* window, HWND hwnd, int Sync) {
     hdc = GetDC(hwnd);
     la_SetupPxlFormat(hdc, &a, &b);
 
-    wglMakeCurrent(0, 0);
     hglrc = wglCreateContextAttribsARB(hdc, MAIN.glc, Attrib);
 
     if (!hglrc) SEND_PANIC_ERROR("Can't Create Opengl Context!\n", );
 
-    //wglShareLists(hglrc, MAIN.glc);
-    wglMakeCurrent(hdc, hglrc);
+    tnsContextMakeCurrent(hglrc, hdc);
 
     //int sync = Sync ? 1 : 0; wglSwapIntervalEXT(sync);
     wglSwapIntervalEXT(-1);
@@ -373,7 +370,8 @@ SYSWINDOW la_CreateWindowWin32(int x, int y, int w, int h, char* title, int Sync
     return hwnd;
 };
 void la_DestroySystemWindowWin32(laWindow* w) {
-    wglDeleteContext(w->glc);
+    tnsContextMakeCurrent(0,0);
+    tnsDeleteContext(w->glc);
     ReleaseDC(w->win, w->hdc);
     DestroyWindow(w->win);
 };
@@ -421,6 +419,17 @@ void glDebugOutput(GLenum source, GLenum type, unsigned int id,
     }printf("%s\n\n", strsource);
 }
 
+void la_SetCurrentGLContextDebug(){
+    glEnable(GL_DEBUG_OUTPUT);
+    glEnable(GL_DEBUG_OUTPUT_SYNCHRONOUS);
+    glDebugMessageCallback(glDebugOutput, 0);
+    glDebugMessageControl(GL_DONT_CARE, GL_DONT_CARE, GL_DEBUG_SEVERITY_HIGH|GL_DEBUG_SEVERITY_MEDIUM, 0, 0, GL_TRUE);
+}
+
+void la_SetupWindowGLStates(laWindow* w){
+    tnsBindVertexArray(w->vao); tnsUnbindTexture(); tnsUseImmShader(); tnsEnableShaderv(T->immShader);
+}
+
 int la_CreateSystemWindow(laWindow *window, int SyncToVBlank){
     SYSGLCONTEXT glc;
 #ifdef __linux__
@@ -430,6 +439,7 @@ int la_CreateSystemWindow(laWindow *window, int SyncToVBlank){
     SYSWINDOW hwnd = la_CreateWindowWin32(window->X, window->Y, window->W, window->H, window->Title->Ptr, SyncToVBlank, &glc);
 #endif
     window->win = hwnd;
+    window->glc = glc;
 
 #ifdef _WIN32
     la_SetupGLEnviornment(window, hwnd, SyncToVBlank);
@@ -443,14 +453,10 @@ int la_CreateSystemWindow(laWindow *window, int SyncToVBlank){
     XGetWindowAttributes(MAIN.dpy, window->win, &attr);
     window->CW =attr.width;
     window->CH = attr.height;
-    window->glc = glc;
 #endif
-
-    glEnable(GL_DEBUG_OUTPUT);
-    glEnable(GL_DEBUG_OUTPUT_SYNCHRONOUS);
-    glDebugMessageCallback(glDebugOutput, 0);
-    glDebugMessageControl(GL_DONT_CARE, GL_DONT_CARE, GL_DONT_CARE, 0, 0, GL_TRUE);
-
+    la_SetCurrentGLContextDebug();
+    glGenVertexArrays(1,&window->vao); tnsBindVertexArray(window->vao);
+    la_SetupWindowGLStates(window);
     return 1;
 };
 
@@ -464,10 +470,12 @@ int la_DestroySystemWindow(laWindow* wnd){
 }
 
 void la_DestroyWindow(laWindow *wnd){
-    laLayout *l; laPanel *p;
-
-    if (!wnd) return;
+    laLayout *l; laPanel *p; if (!wnd) return;
     
+    tnsSwitchToCurrentWindowContext(wnd);
+
+    tnsBindVertexArray(0); glDeleteVertexArrays(1,&wnd->vao);
+
     la_StopAllOperators();
     strSafeDestroy(&wnd->Title);
 
@@ -733,6 +741,8 @@ int laGetReadyWith(laInitArguments* ia){
     if(MAIN.InitArgs.GLMinor<1){ MAIN.InitArgs.GLMinor=3; }
     if(MAIN.BufferSamples==1){ MAIN.BufferSamples=0; }
 
+    tnsInit();
+
 #ifdef __linux__
     SYSWINDOW root, win;
     GLint att[] = {GLX_RGBA, GLX_DEPTH_SIZE, 24, GLX_DOUBLEBUFFER, None};
@@ -809,7 +819,7 @@ int laGetReadyWith(laInitArguments* ia){
     }
     glXSwapIntervalEXTF = (glXSwapIntervalEXTProc) glXGetProcAddressARB( (const GLubyte *) "glXSwapIntervalEXT" );
 
-    glXMakeCurrent(MAIN.dpy, win, MAIN.glc);
+    tnsContextMakeCurrent(MAIN.glc,win);
 
     int major,minor; glGetIntegerv(GL_MAJOR_VERSION, &major); glGetIntegerv(GL_MINOR_VERSION, &minor);
     logPrint("    OpenGL Version: %d.%d\n",major,minor);
@@ -820,6 +830,10 @@ int laGetReadyWith(laInitArguments* ia){
         printf("%d\n",err); printf("%s\n",glewGetErrorString(err));
     };
 
+    glGenVertexArrays(1,&MAIN.TempVAO); tnsBindVertexArray(MAIN.TempVAO);
+
+    la_SetCurrentGLContextDebug();
+
     MAIN.MsgDelWindow = XInternAtom(MAIN.dpy, "WM_DELETE_WINDOW", 0);
     MAIN.bufid =  XInternAtom(MAIN.dpy, "CLIPBOARD", False),
     MAIN.fmtid =  XInternAtom(MAIN.dpy, "UTF8_STRING", False),
@@ -875,7 +889,7 @@ int laGetReadyWith(laInitArguments* ia){
 
     SetPixelFormat(hdc, 1, &cpfd);
     hglrc = wglCreateContext(hdc);
-    wglMakeCurrent(hdc, hglrc);
+    tnsContextMakeCurrent(hglrc, hdc);
 
     //MAIN.hdc = hdc;
    // MAIN.tWND = hwnd;
@@ -1044,6 +1058,18 @@ void laShutoff(int SavePrefereces){
 
     logClear();
 
+    tnsBindVertexArray(0); glDeleteVertexArrays(1,&MAIN.TempVAO);
+
+#ifdef __linux__
+    tnsContextMakeCurrent(0,0);
+    tnsDeleteContext(MAIN.glc);
+#endif
+#ifdef _WIN32
+    tnsContextMakeCurrent(0,0);
+    tnsDeleteContext(MAIN.glc);
+    UnloadWintab();
+#endif
+
     tnsQuit();
 
     laPropContainer* pc; while(pc=lstPopItem(&MAIN.PropContainers)){ la_FreePropertyContainer(pc); }
@@ -1053,14 +1079,6 @@ void laShutoff(int SavePrefereces){
 
     hshFree(&MAIN.DBInstMemLeft);
     memNoLonger();
-
-#ifdef __linux__
-    glXDestroyContext(MAIN.dpy,MAIN.glc);
-#endif
-#ifdef _WIN32
-    wglDeleteContext(MAIN.glc);
-    UnloadWintab();
-#endif
 }
 
 void laSaveUserPreferences(){
@@ -1703,11 +1721,7 @@ void laEnsurePanelInBound(laPanel *p, laUiList *uil){
     p->TX = p->X; p->TY = p->Y;
     p->TW = p->W; p->TH = p->H;
 
-    if (p->OffScr &&
-        (p->W != p->OffScr->pColor[0]->Width ||
-         p->H != p->OffScr->pColor[0]->Height)){
-        tnsConfigureOffscreen(p->OffScr, p->W,p->H);
-    }
+    if (p->OffScr){ tnsEnsureOffscreenStatus(p->OffScr, p->W,p->H); }
 }
 void la_SetPanelMatrix(laPanel *p, laBoxedTheme *bt){
     tnsDrawToOffscreen(p->OffScr, 1, 0);
@@ -2349,7 +2363,7 @@ void la_WindowDefDraw(laWindow *w, laBoxedTheme *bt){
 int laStartWindow(laWindow *w){
 #ifdef __linux__
     XMapWindow(MAIN.dpy,w->win);
-    glXMakeContextCurrent(MAIN.dpy, w->win,w->win, w->glc);
+    tnsContextMakeCurrent(w->glc,w->win);
 #endif
 #ifdef _WIN32
     ShowWindow(w->win, SW_SHOWNORMAL);
@@ -7283,7 +7297,7 @@ void laMainLoop(){
         if(MAIN.PreDraw){ MAIN.PreDraw(); }
 
         for(w=MAIN.Windows.pFirst;w;w=w->Item.pNext){
-            tnsSwitchToCurrentWindowContext(w);
+            tnsSwitchToCurrentWindowContext(w); la_SetupWindowGLStates(w);
             la_DrawWindow(w);
         }
         for(w=MAIN.Windows.pFirst;w;w=w->Item.pNext){

+ 28 - 4
la_tns.h

@@ -187,6 +187,15 @@ struct _tnsMain {
     tnsShader *CurrentShader;
     tnsShader *BindedShader;
 
+    GLuint CurrentVAO;
+    SYSGLCONTEXT CurrentContext;
+#ifdef _WIN32
+    SYSTEMDC CurrentDC;
+#endif
+#ifdef __linux__
+    SYSWINDOW CurrentWindow;
+#endif
+
     //int            MatrixMode;
     int IsOffscreen;
     laListHandle Offscreens;
@@ -203,8 +212,6 @@ struct _tnsMain {
     tnsShader* SelectionShader;
     tnsShader* FloorShader;
 
-    int GlobalVAO;
-
     tnsShader *uiShader;
     tnsShader *stringShader;
     tnsShader *TextureShader;
@@ -307,6 +314,13 @@ struct _tnsOffscreen
     tnsTexture *pDepth;
 
     GLuint FboHandle;
+    SYSGLCONTEXT FboContext;
+#ifdef _WIN32
+    SYSTEMDC FboDC;
+#endif
+#ifdef __linux__
+    SYSWINDOW FboWindow;
+#endif
 
     int UseSecondary;
 };
@@ -809,6 +823,7 @@ void tnsUseTransparentGridShader();
 
 void tnsUseImagePeelShader();
 
+void tnsInit();
 void tnsInitRenderKernel(int matrixStackLevel);
 void tnsInitBuiltinShaders();
 void tnsInitWindowDefaultRenderConfig();
@@ -1144,7 +1159,16 @@ tnsMaterial *tnsFindMaterial(char *name);
 void tnsClearAll();
 void tnsClearColorv(real *rgba);
 void tnsClearColor(real r, real g, real b, real a);
-void tnsSwitchToCurrentWindowContext(void *wnd);
+#ifdef __linux__
+void tnsContextMakeCurrent(SYSGLCONTEXT context, SYSWINDOW win);
+#endif
+#ifdef _WIN32
+void tnsContextMakeCurrent(SYSGLCONTEXT context, SYSTEMDC hdc);
+#endif
+NEED_STRUCTURE(laWindow)
+void tnsSwitchToCurrentWindowContext(laWindow* w);
+void tnsDeleteContext(SYSGLCONTEXT glc);
+void tnsBindVertexArray(GLuint vao);
 
 void tnsRecalculateVertNormal(tnsVert *v);
 void tnsRecalculateFaceAverageNormal(tnsFace *f);
@@ -1200,7 +1224,7 @@ int tnsTextureMemorySize(tnsTexture *t, int mem);
 
 void tnsDelete2DOffscreen(tnsOffscreen *o);
 tnsOffscreen *tnsCreateOffscreenHandle();
-void tnsConfigureOffscreen(tnsOffscreen *off, int w, int h);
+void tnsEnsureOffscreenStatus(tnsOffscreen *off, int w, int h);
 void tnsAttach2DOffscreenBuffer(tnsOffscreen *target, GLuint attatchment, tnsTexture *use);
 void tnsDetach2DOffscreenBuffer(tnsOffscreen *target, GLuint which_attach_point);
 

+ 83 - 39
la_tns_kernel.c

@@ -115,26 +115,42 @@ extern LA MAIN;
 void InitGLRenderEnviornment(){
     glEnable(GL_SCISSOR_TEST);
 };
-void tnsSwitchToCurrentWindowContext(void *wnd){
-    //HGLRC current = wglGetCurrentContext(), hglrc = wnd->SystemGLRC;
-    //HDC hdc = wnd->SystemDC;
-//
-    ////if (hglrc != current)
-    //int a = GetLastError();
-//
-    //int s = wglMakeCurrent(hdc, hglrc);
-    laWindow* win = wnd;
 #ifdef __linux__
-    glXMakeCurrent(MAIN.dpy,win->win, MAIN.glc);//on intel it should not be win->glc?
-    //glXMakeContextCurrent(MAIN.dpy, win->win, win->win, win->glc);
-    //tnsUnbindTexture(); tnsUseNoTexture(); // reset states needed for fonts to work correctly??
-    //tnsDrawToScreen();
+void tnsContextMakeCurrent(SYSGLCONTEXT context, SYSWINDOW win){
+    glXMakeContextCurrent(MAIN.dpy, win, win, context); T->CurrentContext=context; T->CurrentWindow=win;
+    tnsUnbindTexture(); tnsUseNoTexture();
+};
+#endif
+#ifdef _WIN32
+void tnsContextMakeCurrent(SYSGLCONTEXT context, SYSTEMDC hdc){
+    wglMakeCurrent(hdc, context); T->CurrentContext=context; T->CurrentDC=hdc;
+    tnsUnbindTexture(); tnsUseNoTexture();
+};
+#endif
+void tnsSwitchToCurrentWindowContext(laWindow* w){
+#ifdef __linux__
+    tnsContextMakeCurrent(w->glc,w->win);
 #endif
 #ifdef _WIN32
-    wglMakeCurrent(win->hdc, win->glc);
-    tnsUnbindTexture(); tnsUseNoTexture(); // reset states needed for fonts to work correctly??
+    tnsContextMakeCurrent(w->glc,w->hdc);
 #endif
 };
+
+void tnsDeleteContext(SYSGLCONTEXT glc){
+#ifdef __linux__
+    glXDestroyContext(MAIN.dpy,glc);
+#endif
+#ifdef _WIN32
+    wglDeleteContext(glc);
+#endif
+    for(tnsOffscreen* o=T->Offscreens.pFirst;o;o=o->Item.pNext){
+        if(o->FboContext==glc){ o->FboContext=0; }
+    }
+}
+void tnsBindVertexArray(GLuint vao){
+    T->CurrentVAO=vao; glBindVertexArray(vao);
+}
+
 void tnsViewportWithScissor(int x, int y, int w, int h){
     tnsShader *current_shader = 0;
     glEnable(GL_SCISSOR_TEST);
@@ -1247,10 +1263,12 @@ void tnsSetRayShaderUniformTextures(tnsOffscreen* doff){
     glUniform1i(T->RayShader->iTexColor, 0); glUniform1i(T->RayShader->iTexNormal, 1); glUniform1i(T->RayShader->iTexGPos, 2);
 }
 
+void tnsInit(){
+    T = memAcquire(sizeof(tnsMain));
+    T->World=memAcquire(sizeof(tnsWorld));
+}
 void tnsInitRenderKernel(int matrixStackLevel){
     tnsCommand *c;
-    T = memAcquireHyper(sizeof(tnsMain));
-    T->World=memAcquire(sizeof(tnsWorld));
     GLuint m_nQuadVAO;
 
     T->GLVersionStr = glGetString(GL_VERSION);
@@ -1266,10 +1284,6 @@ void tnsInitRenderKernel(int matrixStackLevel){
 
     T->StateLineWidth=T->SetLineWidth=1; T->StatePointSize=T->SetPointSize=1;
 
-    /* Needed for gl3.3+ */
-    glGenVertexArrays(1,&T->GlobalVAO);
-    glBindVertexArray(T->GlobalVAO);
-
     arrEnsureLength(&T->Vert, T->NextVert, &T->MaxVert, sizeof(GLfloat));
     glGenBuffers(1, &T->VertBufObject);
     glBindBuffer(GL_ARRAY_BUFFER, T->VertBufObject);
@@ -1372,16 +1386,13 @@ void tnsQuit(){
     glDeleteBuffers(1, &T->TexCoordBufObject);
     glDeleteBuffers(1, &T->IndexBufObject);
 
-    glBindVertexArray(0);
-    glDeleteVertexArrays(1,&T->GlobalVAO);
-
     FreeMem(T->stack.level);
     memFree(T->World);
     memFree(T);
 }
 
 void tnsRestoreFromNanoVG(){
-    glBindVertexArray(T->GlobalVAO);
+    glBindVertexArray(T->CurrentVAO);
     tnsUseImmShader(); tnsEnableShaderv(T->immShader);
 	glActiveTexture(GL_TEXTURE0);
     glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA,GL_ONE,GL_ONE_MINUS_SRC_ALPHA);
@@ -2331,7 +2342,14 @@ const GLuint TNS_ATTACHMENT_ARRAY_0_1_2[] = {GL_COLOR_ATTACHMENT0, GL_COLOR_ATTA
 const GLenum TNS_WINDOW_DRAWBUFFER_ARRAY[] = {GL_BACK};
 
 tnsOffscreen *tnsCreateOffscreenHandle(){
-    tnsOffscreen *toff = CreateNew(tnsOffscreen);
+    if(!T->CurrentContext){ printf("tnsCreateOffscreenHandle() called without GL Context. Exiting"); exit(0); }
+    tnsOffscreen *toff = CreateNew(tnsOffscreen); toff->FboContext=T->CurrentContext;
+#ifdef _WIN32
+    toff->FboDC=T->CurrentDC;
+#endif
+#ifdef __linux__
+    toff->FboWindow=T->CurrentWindow;
+#endif
     glGenFramebuffers(1, &toff->FboHandle);
     lstAppendItem(&T->Offscreens, toff);
     return toff;
@@ -2363,12 +2381,8 @@ void tnsAttach2DOffscreenBuffer(tnsOffscreen *target, GLuint attatchment, tnsTex
         //glBindFramebuffer(GL_FRAMEBUFFER, 0);
     }
     GLenum result = glCheckFramebufferStatus(GL_FRAMEBUFFER);
-    //if (result == GL_FRAMEBUFFER_COMPLETE) {
-    //	printf("Framebuffer complete!\n");
-    //}
-    //else {
-    //	printf("Framebuffer incomplete!\n");
-    //}
+    //if (result == GL_FRAMEBUFFER_COMPLETE) { printf("Framebuffer complete!\n"); }
+    //else { printf("Framebuffer incomplete!\n"); }
 }
 void tnsDetach2DOffscreenBuffer(tnsOffscreen *target, GLuint which_attach_point){
     if (which_attach_point >= GL_COLOR_ATTACHMENT0 && which_attach_point <= GL_COLOR_ATTACHMENT15){
@@ -2425,19 +2439,50 @@ tnsOffscreen *tnsCreateDeferredOffscreen(int w, int h, int Multisample){
     return toff;
 }
 
-void tnsConfigureOffscreen(tnsOffscreen *off, int w, int h){
+void tnsRecreateFBO(tnsOffscreen *off){
+    if(off->FboContext){
+#ifdef __linux__
+        SYSWINDOW sw=T->CurrentWindow; SYSGLCONTEXT sc=T->CurrentContext;
+        tnsContextMakeCurrent(off->FboContext,off->FboWindow);
+        glDeleteFramebuffers(1, &off->FboHandle);
+        tnsContextMakeCurrent(sc,sw);
+        off->FboContext=sc; off->FboWindow=sw;
+#endif
+#ifdef _WIN32
+        SYSTEMDC sd=T->CurrentDC; SYSGLCONTEXT sc=T->CurrentContext;
+        tnsContextMakeCurrent(off->FboContext,off->FboDC);
+        glDeleteFramebuffers(1, &off->FboHandle);
+        tnsContextMakeCurrent(sc,sd);
+        off->FboContext=sc; off->FboDC=sd;
+#endif
+    }
+    glGenFramebuffers(1, &off->FboHandle);
+    if(off->pColor[0]) tnsAttach2DOffscreenBuffer(off, GL_COLOR_ATTACHMENT0, off->pColor[0]);
+    if(off->pColor[1]) tnsAttach2DOffscreenBuffer(off, GL_COLOR_ATTACHMENT1, off->pColor[1]);
+    if(off->pColor[2]) tnsAttach2DOffscreenBuffer(off, GL_COLOR_ATTACHMENT2, off->pColor[2]);
+    if(off->pColor[3]) tnsAttach2DOffscreenBuffer(off, GL_COLOR_ATTACHMENT3, off->pColor[3]);
+    if(off->pDepth){ tnsAttach2DOffscreenBuffer(off, GL_DEPTH_ATTACHMENT, off->pDepth);
+        if(off->pDepth->GLTexBitsType==GL_DEPTH_STENCIL) tnsAttach2DOffscreenBuffer(off, GL_STENCIL_ATTACHMENT, off->pDepth);
+    }
+}
+void tnsEnsureOffscreenContext(tnsOffscreen *off){
+    if(off->FboContext!=T->CurrentContext){ tnsRecreateFBO(off); }
+}
+void tnsEnsureOffscreenStatus(tnsOffscreen *off, int w, int h){
     tnsTexture* t=off->pColor[0];
+    tnsEnsureOffscreenContext(off);
+    if(t->Width==w && t->Height==h) return;
     t->Width = w; t->Height = h; tnsConfigure2DTexture(t);
-    t=off->pDepth;
-    if(t){
-        t->Width = w; t->Height = h; tnsConfigure2DTexture(t);
-    }
+    if((t=off->pColor[1])){ t->Width = w; t->Height = h; tnsConfigure2DTexture(t); }
+    if((t=off->pColor[2])){ t->Width = w; t->Height = h; tnsConfigure2DTexture(t); }
+    if((t=off->pColor[3])){ t->Width = w; t->Height = h; tnsConfigure2DTexture(t); }
+    if((t=off->pDepth)){ t->Width = w; t->Height = h; tnsConfigure2DTexture(t); }
 }
 
 void tnsDelete2DOffscreen(tnsOffscreen *o){
     if (!o) return;
-
     glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
+    tnsEnsureOffscreenContext(o);
 
     for(int i=0;i<16;i++){
         if(o->pColor[i]){
@@ -2452,7 +2497,6 @@ void tnsDelete2DOffscreen(tnsOffscreen *o){
     }
 
     glDeleteFramebuffers(1, &o->FboHandle);
-    //tnsDeleteTexture(o->pStencil);
 
     lstRemoveItem(&T->Offscreens, o);
     FreeMem(o);

+ 1 - 1
resources/la_properties.c

@@ -942,7 +942,7 @@ void la_RegisterTNSProps(){
     laProp *ep; laPropPack pp; laSubProp *sp; laKeyMapper *km;
     laCanvasTemplate *v2dt;
     
-    p = laAddPropertyContainer("tns_main", "TNS Main", "Render Kernel Root Structure", 0,0,sizeof(tnsMain), 0,0,2);{
+    p = laAddPropertyContainer("tns_main", "TNS Main", "Render Kernel Root Structure", 0,0,sizeof(tnsMain), 0,0,1);{
         if(MAIN.InitArgs.HasWorldObjects){
             laAddSubGroup(p, "world", "World", "World Descriptor", "tns_world",0,0,0,offsetof(tnsMain, World), 0,0,0,0,0,0,0,LA_UDF_SINGLE);
         }

+ 4 - 6
resources/la_widgets_viewers.c

@@ -69,12 +69,10 @@ void la_RootObjectDraw(laBoxedTheme *bt, tnsObject *root, laUiItem* ui){
 
     if (!W || !H) return;
 
-    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);
-        //if (e->DeferredOffScr) tnsDelete2DOffscreen(e->DeferredOffScr);
-        e->OffScr = tnsCreateDeferredOffscreen(W,H,MAIN.PanelMultisample);//tnsCreate2DOffscreen(GL_RGBA, W, H, MAIN.PanelMultisample ,1, 0);
-        //e->DeferredOffScr = tnsCreateDeferredOffscreen(W,H,MAIN.PanelMultisample);
-    }
+    if (!e->OffScr){
+        e->OffScr = tnsCreateDeferredOffscreen(W,H,MAIN.PanelMultisample);
+        //e->OffScr = tnsCreate2DOffscreen(GL_RGBA, W, H, MAIN.PanelMultisample ,1, 0);
+    }else{ tnsEnsureOffscreenStatus(e->OffScr, ui->R - ui->L, ui->B - ui->U); }
 
     if (0){//(e->CurrentScene && e->CurrentScene->ActiveSun){
         //if(!e->OffScrShadow) e->OffScrShadow = tnsCreate2DOffscreen(0, LA_DEPTH_RESOLUTION, LA_DEPTH_RESOLUTION, MAIN.PanelMultisample, 1, 0);