From 52b3e807a5394cbf5dd1402c4556015025fba2e0 Mon Sep 17 00:00:00 2001 From: Matthias Hochsteger Date: Fri, 6 Dec 2019 13:48:00 +0100 Subject: [PATCH 1/7] New Snapshot function (custom resolution) --- libsrc/include/incopengl.hpp | 17 +++++++++ libsrc/visualization/mvdraw.cpp | 58 +++++++++++++++++++++++++++++ libsrc/visualization/mvdraw.hpp | 1 + libsrc/visualization/vssolution.cpp | 25 +++++++++++++ ng/netgenpy.cpp | 5 +++ python/gui.py | 13 +++++++ 6 files changed, 119 insertions(+) diff --git a/libsrc/include/incopengl.hpp b/libsrc/include/incopengl.hpp index dc4c469f..d8c3bcea 100644 --- a/libsrc/include/incopengl.hpp +++ b/libsrc/include/incopengl.hpp @@ -28,6 +28,11 @@ #define GL_ARRAY_BUFFER 0x8892 #define GL_ELEMENT_ARRAY_BUFFER 0x8893 #define GL_STATIC_DRAW 0x88E4 +#define GL_FRAMEBUFFER_COMPLETE 0x8CD5 +#define GL_FRAMEBUFFER 0x8D40 +#define GL_RENDERBUFFER 0x8D41 +#define GL_DEPTH_ATTACHMENT 0x8D00 +#define GL_COLOR_ATTACHMENT0 0x8CE0 typedef ptrdiff_t GLintptr; typedef ptrdiff_t GLsizeiptr; extern void (*glBindBuffer) (GLenum a, GLuint b); @@ -35,6 +40,18 @@ extern void (*glDeleteBuffers) (GLsizei a, const GLuint *b); extern void (*glGenBuffers) (GLsizei a, GLuint *b); extern void (*glBufferData) (GLenum a, GLsizeiptr b, const GLvoid *c, GLenum d); extern void (*glBufferSubData) (GLenum a, GLintptr b, GLsizeiptr c, const GLvoid *d); + +extern GLenum (*glCheckFramebufferStatus) (GLenum target); +extern void (*glBindFramebuffer) (GLenum target, GLuint framebuffer); +extern void (*glBindRenderbuffer) (GLenum target, GLuint renderbuffer); +extern void (*glDeleteFramebuffers) (GLsizei n, const GLuint *framebuffers); +extern void (*glDeleteRenderbuffers) (GLsizei n, const GLuint *renderbuffers); +extern void (*glFramebufferTexture) (GLenum target, GLenum attachment, GLuint texture, GLint level); +extern void (*glGenFramebuffers) (GLsizei n, GLuint *framebuffers); +extern void (*glGenRenderbuffers) (GLsizei n, GLuint *renderbuffers); +extern void (*glRenderbufferStorage) (GLenum target, GLenum internalformat, GLsizei width, GLsizei height); +extern void (*glFramebufferRenderbuffer) (GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer); +extern void (*glNamedFramebufferReadBuffer) ( GLuint framebuffer, GLenum mode); #endif DLL_HEADER void LoadOpenGLFunctionPointers(); #endif // INCOPENGL_HPP___ diff --git a/libsrc/visualization/mvdraw.cpp b/libsrc/visualization/mvdraw.cpp index 07d9aec4..b9c5f4dc 100644 --- a/libsrc/visualization/mvdraw.cpp +++ b/libsrc/visualization/mvdraw.cpp @@ -779,6 +779,64 @@ namespace netgen VisualScene::MouseMove(oldx, oldy, newx, newy, mode); } + std::vector Snapshot( int w, int h ) + { + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + + double pnear = 0.1; + double pfar = 10; + + gluPerspective(20.0f, double(w) / h, pnear, pfar); + + glMatrixMode(GL_MODELVIEW); + + GLuint fb = 0; + glGenFramebuffers(1, &fb); + glBindFramebuffer(GL_FRAMEBUFFER, fb); + + GLuint tex; + glGenTextures(1, &tex); + + glBindTexture(GL_TEXTURE_2D, tex); + + glTexImage2D(GL_TEXTURE_2D, 0,GL_RGBA, w, h, 0,GL_RGBA, GL_UNSIGNED_BYTE, 0); + + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + + GLuint depthrenderbuffer; + glGenRenderbuffers(1, &depthrenderbuffer); + glBindRenderbuffer(GL_RENDERBUFFER, depthrenderbuffer); + glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT, w, h); + glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, depthrenderbuffer); + + glFramebufferTexture(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, tex, 0); + + if(int fbstatus; (fbstatus = glCheckFramebufferStatus(GL_FRAMEBUFFER)) != GL_FRAMEBUFFER_COMPLETE) + cerr << "no frame buffer " << fbstatus << endl; + + glBindFramebuffer(GL_FRAMEBUFFER, fb); + glViewport(0,0,w,h); + + glPushMatrix(); + GetVSSolution().DrawScene(); + glFinish(); + glPopMatrix(); + + std::vector buffer(w*h*3); + glPixelStorei(GL_UNPACK_ALIGNMENT,1); + glPixelStorei(GL_PACK_ALIGNMENT,1); + glNamedFramebufferReadBuffer( fb, GL_COLOR_ATTACHMENT0 ); + glReadPixels (0, 0, w, h, GL_RGB, GL_UNSIGNED_BYTE, &buffer[0]); + + glDeleteRenderbuffers(1, &depthrenderbuffer); + glDeleteTextures(1, &tex); + glDeleteFramebuffers(1, &fb); + + return buffer; + } + #ifdef PARALLELGL void VisualScene :: InitParallelGL () diff --git a/libsrc/visualization/mvdraw.hpp b/libsrc/visualization/mvdraw.hpp index 264dd6a4..7a0045a5 100644 --- a/libsrc/visualization/mvdraw.hpp +++ b/libsrc/visualization/mvdraw.hpp @@ -247,6 +247,7 @@ namespace netgen PointIndex & selpoint2, int & locpi); + DLL_HEADER std::vector Snapshot( int w, int h ); } diff --git a/libsrc/visualization/vssolution.cpp b/libsrc/visualization/vssolution.cpp index 2a61662b..624e95f7 100644 --- a/libsrc/visualization/vssolution.cpp +++ b/libsrc/visualization/vssolution.cpp @@ -4890,6 +4890,19 @@ void (*glDeleteBuffers) (GLsizei a, const GLuint *b); void (*glGenBuffers) (GLsizei a, GLuint *b); void (*glBufferData) (GLenum a, GLsizeiptr b, const GLvoid *c, GLenum d); void (*glBufferSubData) (GLenum a, GLintptr b, GLsizeiptr c, const GLvoid *d); + +GLenum (*glCheckFramebufferStatus) (GLenum target); +void (*glBindFramebuffer) (GLenum target, GLuint framebuffer); +void (*glBindRenderbuffer) (GLenum target, GLuint renderbuffer); +void (*glDeleteFramebuffers) (GLsizei n, const GLuint *framebuffers); +void (*glDeleteRenderbuffers) (GLsizei n, const GLuint *renderbuffers); +void (*glFramebufferTexture) (GLenum target, GLenum attachment, GLuint texture, GLint level); +void (*glGenFramebuffers) (GLsizei n, GLuint *framebuffers); +void (*glGenRenderbuffers) (GLsizei n, GLuint *renderbuffers); +void (*glRenderbufferStorage) (GLenum target, GLenum internalformat, GLsizei width, GLsizei height); +void (*glFramebufferRenderbuffer) (GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer); +void (*glNamedFramebufferReadBuffer) ( GLuint framebuffer, GLenum mode); + DLL_HEADER void LoadOpenGLFunctionPointers() { #ifdef USE_BUFFERS glBindBuffer = (decltype(glBindBuffer)) wglGetProcAddress("glBindBuffer"); @@ -4899,6 +4912,18 @@ DLL_HEADER void LoadOpenGLFunctionPointers() { glGenBuffers = (decltype(glGenBuffers)) wglGetProcAddress("glGenBuffers"); if(!glBindBuffer) throw std::runtime_error("Could not load OpenGL functions!"); #endif + + glCheckFramebufferStatus = (decltype(glCheckFramebufferStatus )) wglGetProcAddress("glCheckFramebufferStatus"); + glBindFramebuffer = (decltype(glBindFramebuffer )) wglGetProcAddress("glBindFramebuffer"); + glBindRenderbuffer = (decltype(glBindRenderbuffer )) wglGetProcAddress("glBindRenderbuffer"); + glDeleteFramebuffers = (decltype(glDeleteFramebuffers )) wglGetProcAddress("glDeleteFramebuffers"); + glDeleteRenderbuffers = (decltype(glDeleteRenderbuffers )) wglGetProcAddress("glDeleteRenderbuffers"); + glFramebufferTexture = (decltype(glFramebufferTexture )) wglGetProcAddress("glFramebufferTexture"); + glGenFramebuffers = (decltype(glGenFramebuffers )) wglGetProcAddress("glGenFramebuffers"); + glGenRenderbuffers = (decltype(glGenRenderbuffers )) wglGetProcAddress("glGenRenderbuffers"); + glRenderbufferStorage = (decltype(glRenderbufferStorage )) wglGetProcAddress("glRenderbufferStorage"); + glFramebufferRenderbuffer = (decltype(glFramebufferRenderbuffer )) wglGetProcAddress("glFramebufferRenderbuffer"); + glNamedFramebufferReadBuffer = (decltype(glNamedFramebufferReadBuffer )) wglGetProcAddress("glNamedFramebufferReadBuffer"); } #else // WIN32 DLL_HEADER void LoadOpenGLFunctionPointers() { } diff --git a/ng/netgenpy.cpp b/ng/netgenpy.cpp index d9d8a5c2..2b68e408 100644 --- a/ng/netgenpy.cpp +++ b/ng/netgenpy.cpp @@ -20,6 +20,10 @@ void DLL_HEADER ExportSTLVis(py::module &m); #ifdef OCCGEOMETRY void DLL_HEADER ExportNgOCC(py::module &m); #endif // OCCGEOMETRY +namespace netgen +{ + std::vector DLL_HEADER Snapshot( int w, int h ); +} PYBIND11_MODULE(libngpy, ngpy) { @@ -43,6 +47,7 @@ PYBIND11_MODULE(libngpy, ngpy) ExportCSGVis(csgvis); py::module stlvis = ngpy.def_submodule("stlvis", "pybind stlvis module"); ExportSTLVis(stlvis); + ngpy.def("Snapshot", netgen::Snapshot); #endif // OPENGL } diff --git a/python/gui.py b/python/gui.py index 959b2fd3..d43c9473 100644 --- a/python/gui.py +++ b/python/gui.py @@ -24,3 +24,16 @@ if not netgen.libngpy._meshing._netgen_executable_started: StartGUI() except: pass + +def Snapshot(w,h, filename=None): + import ngsolve + ngsolve.Redraw(blocking=True) + import numpy + image = netgen.libngpy.Snapshot(w, h) + image = numpy.array(image, dtype=numpy.uint8).reshape(h, w, 3) + image = image[::-1,:,:] + if filename: + import PIL.Image + im = PIL.Image.fromarray(image) + im.save(filename) + return image From 64b1331c23375e85f522b42cbd54314297a87824 Mon Sep 17 00:00:00 2001 From: Matthias Hochsteger Date: Tue, 10 Dec 2019 11:57:11 +0100 Subject: [PATCH 2/7] Fix build errors on Macos - Include opengl3 headers - Remove unneeded Opengl4.5 function call --- libsrc/include/incopengl.hpp | 3 ++- libsrc/visualization/mvdraw.cpp | 1 - 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/libsrc/include/incopengl.hpp b/libsrc/include/incopengl.hpp index d8c3bcea..c4630a09 100644 --- a/libsrc/include/incopengl.hpp +++ b/libsrc/include/incopengl.hpp @@ -6,7 +6,8 @@ # if defined(TOGL_AGL) || defined(TOGL_AGL_CLASSIC) || defined(TOGL_NSOPENGL) #define GL_SILENCE_DEPRECATION -# include +#define GL_DO_NOT_WARN_IF_MULTI_GL_VERSION_HEADERS_INCLUDED +# include # include # else # include diff --git a/libsrc/visualization/mvdraw.cpp b/libsrc/visualization/mvdraw.cpp index b9c5f4dc..6754b7de 100644 --- a/libsrc/visualization/mvdraw.cpp +++ b/libsrc/visualization/mvdraw.cpp @@ -827,7 +827,6 @@ namespace netgen std::vector buffer(w*h*3); glPixelStorei(GL_UNPACK_ALIGNMENT,1); glPixelStorei(GL_PACK_ALIGNMENT,1); - glNamedFramebufferReadBuffer( fb, GL_COLOR_ATTACHMENT0 ); glReadPixels (0, 0, w, h, GL_RGB, GL_UNSIGNED_BYTE, &buffer[0]); glDeleteRenderbuffers(1, &depthrenderbuffer); From 245da0ee87223858b9cdd22e96597767e4d228df Mon Sep 17 00:00:00 2001 From: Matthias Hochsteger Date: Tue, 10 Dec 2019 11:59:16 +0100 Subject: [PATCH 3/7] Move Redraw() function from NGSolve to Netgen - used in Snapshot --- libsrc/visualization/vsmesh.cpp | 27 +++++++++++++++++++++++++++ python/__init__.py | 11 +++++++++++ python/gui.py | 3 +-- 3 files changed, 39 insertions(+), 2 deletions(-) diff --git a/libsrc/visualization/vsmesh.cpp b/libsrc/visualization/vsmesh.cpp index ed04a128..21a2f43e 100644 --- a/libsrc/visualization/vsmesh.cpp +++ b/libsrc/visualization/vsmesh.cpp @@ -3536,6 +3536,7 @@ namespace netgen #ifdef NG_PYTHON #include <../general/ngpython.hpp> +#include "../include/nginterface.h" DLL_HEADER void ExportMeshVis(py::module &m) { @@ -3577,6 +3578,32 @@ DLL_HEADER void ExportMeshVis(py::module &m) ([] () { return vsmesh.GetMesh(); })); + m.def ("_Redraw", + ([](bool blocking, double fr) + { + static auto last_time = std::chrono::system_clock::now()-std::chrono::seconds(10); + auto now = std::chrono::system_clock::now(); + double elapsed = std::chrono::duration(now-last_time).count(); + if (elapsed * fr > 1) + { + Ng_Redraw(blocking); + last_time = std::chrono::system_clock::now(); + return true; + } + return false; + }), + py::arg("blocking")=false, py::arg("fr") = 25, R"raw_string( +Redraw all + +Parameters: + +blocking : bool + input blocking + +fr : double + input framerate + +)raw_string"); } // BOOST_PYTHON_MODULE(libvisual) // { diff --git a/python/__init__.py b/python/__init__.py index e74d1a49..0981769c 100644 --- a/python/__init__.py +++ b/python/__init__.py @@ -11,3 +11,14 @@ del sys del os from . import libngpy + +def Redraw(*args, **kwargs): + if libngpy.meshvis._Redraw(*args, **kwargs): + try: + import netgen + import tkinter + cnt = 0 + while(netgen.gui.win.tk.dooneevent(tkinter._tkinter.DONT_WAIT) and cnt < 100): + cnt += 1 + except: + pass diff --git a/python/gui.py b/python/gui.py index d43c9473..7f317144 100644 --- a/python/gui.py +++ b/python/gui.py @@ -26,8 +26,7 @@ if not netgen.libngpy._meshing._netgen_executable_started: pass def Snapshot(w,h, filename=None): - import ngsolve - ngsolve.Redraw(blocking=True) + netgen.Redraw(blocking=True) import numpy image = netgen.libngpy.Snapshot(w, h) image = numpy.array(image, dtype=numpy.uint8).reshape(h, w, 3) From d6095e9364d00d549e32c78398f2972d7e538772 Mon Sep 17 00:00:00 2001 From: Matthias Hochsteger Date: Tue, 10 Dec 2019 12:18:53 +0100 Subject: [PATCH 4/7] Move global visual scene from ngpkg.cpp to mvdraw.cpp ... so it is available in Snapshot() also rename the global variables: vs -> visual_scene vscross -> visual_scene_cross --- libsrc/visualization/mvdraw.cpp | 4 +++- libsrc/visualization/mvdraw.hpp | 2 ++ ng/demoview.cpp | 4 ++-- ng/ngpkg.cpp | 23 ++++++++++++----------- 4 files changed, 19 insertions(+), 14 deletions(-) diff --git a/libsrc/visualization/mvdraw.cpp b/libsrc/visualization/mvdraw.cpp index 6754b7de..1142755a 100644 --- a/libsrc/visualization/mvdraw.cpp +++ b/libsrc/visualization/mvdraw.cpp @@ -25,6 +25,8 @@ namespace netgen DLL_HEADER Point3d VisualScene :: center; DLL_HEADER double VisualScene :: rad; DLL_HEADER GLdouble VisualScene :: backcolor; + DLL_HEADER VisualScene visual_scene_cross; + DLL_HEADER VisualScene *visual_scene = &visual_scene_cross; /* #if TOGL_MAJOR_VERSION!=2 @@ -820,7 +822,7 @@ namespace netgen glViewport(0,0,w,h); glPushMatrix(); - GetVSSolution().DrawScene(); + visual_scene->DrawScene(); glFinish(); glPopMatrix(); diff --git a/libsrc/visualization/mvdraw.hpp b/libsrc/visualization/mvdraw.hpp index 7a0045a5..cae7c792 100644 --- a/libsrc/visualization/mvdraw.hpp +++ b/libsrc/visualization/mvdraw.hpp @@ -83,6 +83,8 @@ namespace netgen DLL_HEADER extern void MyOpenGLText (const char * text); DLL_HEADER extern void Set_OpenGLText_Callback ( void (*fun) (const char * text) ); + DLL_HEADER extern VisualScene visual_scene_cross; + DLL_HEADER extern VisualScene *visual_scene; diff --git a/ng/demoview.cpp b/ng/demoview.cpp index 81fb329f..9b9ce7b9 100644 --- a/ng/demoview.cpp +++ b/ng/demoview.cpp @@ -20,7 +20,7 @@ #include namespace netgen { - extern VisualScene *vs; + extern VisualScene *visual_scene; #include "demoview.hpp" @@ -422,7 +422,7 @@ namespace netgen { */ - vs -> LookAt ( Point<3>( campos.Evaluate (time)), + visual_scene -> LookAt ( Point<3>( campos.Evaluate (time)), Point<3>(campoint.Evaluate (time)), Point<3>( camup.Evaluate (time)) ); diff --git a/ng/ngpkg.cpp b/ng/ngpkg.cpp index aed8161d..afd4d0e1 100644 --- a/ng/ngpkg.cpp +++ b/ng/ngpkg.cpp @@ -103,7 +103,6 @@ namespace netgen // visualization scenes, pointer vs selects which one is drawn: - static VisualScene vscross; DLL_HEADER extern VisualSceneSurfaceMeshing vssurfacemeshing; DLL_HEADER extern VisualSceneMeshDoctor vsmeshdoc; @@ -111,7 +110,8 @@ namespace netgen - VisualScene *vs = &vscross; + DLL_HEADER extern VisualScene *visual_scene; + DLL_HEADER extern VisualScene visual_scene_cross; @@ -1973,7 +1973,8 @@ namespace netgen { const char * vismode = vispar.selectvisual; // Tcl_GetVar (interp, "selectvisual", 0); - vs = &vscross; + VisualScene *& vs = visual_scene; + vs = &visual_scene_cross; if (GetVisualizationScenes().Used(vismode)) { vs = GetVisualizationScenes()[vismode]; @@ -2049,7 +2050,7 @@ namespace netgen glMatrixMode(GL_MODELVIEW); SetVisualScene (Togl_Interp(togl)); - vs->DrawScene(); + visual_scene->DrawScene(); Set_OpenGLText_Callback (&MyOpenGLText_GUI); return TCL_OK; } @@ -2069,7 +2070,7 @@ namespace netgen glPushMatrix(); glLoadIdentity(); - vs->DrawScene(); + visual_scene->DrawScene(); Togl_SwapBuffers(togl); glPopMatrix(); @@ -2290,7 +2291,7 @@ namespace netgen newy = atoi (argv[4]); SetVisualScene(interp); - vs->MouseMove (oldx, oldy, newx, newy, argv[5][0]); + visual_scene->MouseMove (oldx, oldy, newx, newy, argv[5][0]); return TCL_OK; } @@ -2304,7 +2305,7 @@ namespace netgen int py = Togl_PixelScale(togl)*atoi (argv[2]); SetVisualScene(interp); - vs->MouseDblClick (px, py); + visual_scene->MouseDblClick (px, py); return TCL_OK; } @@ -2315,7 +2316,7 @@ namespace netgen int argc, tcl_const char *argv[]) { SetVisualScene(interp); - vs->BuildScene (1); + visual_scene->BuildScene (1); return TCL_OK; } @@ -2326,7 +2327,7 @@ namespace netgen int argc, tcl_const char *argv[]) { SetVisualScene(interp); - vs->BuildScene (2); + visual_scene->BuildScene (2); return TCL_OK; } @@ -2337,7 +2338,7 @@ namespace netgen int argc, tcl_const char *argv[]) { SetVisualScene(interp); - vs->StandardRotation (argv[1]); + visual_scene->StandardRotation (argv[1]); return TCL_OK; } @@ -2356,7 +2357,7 @@ namespace netgen vec.Append(Vec3d(atof(argv[i+1]),atof(argv[i+2]),atof(argv[i+3]))); } - vs->ArbitraryRotation (alpha,vec); + visual_scene->ArbitraryRotation (alpha,vec); return TCL_OK; } From 4a6b6e8ab8d8e4ab564df0c74045e68cc7d0da73 Mon Sep 17 00:00:00 2001 From: Matthias Hochsteger Date: Tue, 10 Dec 2019 14:10:14 +0100 Subject: [PATCH 5/7] Remove redundant declaration fixes build error on Windows --- ng/demoview.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/ng/demoview.cpp b/ng/demoview.cpp index 9b9ce7b9..996082ce 100644 --- a/ng/demoview.cpp +++ b/ng/demoview.cpp @@ -20,7 +20,6 @@ #include namespace netgen { - extern VisualScene *visual_scene; #include "demoview.hpp" From a06189ac4e171b2807efbeeb40df34483193ab58 Mon Sep 17 00:00:00 2001 From: Matthias Hochsteger Date: Tue, 10 Dec 2019 17:57:20 +0100 Subject: [PATCH 6/7] Redraw after geom2d::Draw() --- libsrc/geom2d/python_geom2d.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/libsrc/geom2d/python_geom2d.cpp b/libsrc/geom2d/python_geom2d.cpp index e8bff0b7..a890579b 100644 --- a/libsrc/geom2d/python_geom2d.cpp +++ b/libsrc/geom2d/python_geom2d.cpp @@ -367,6 +367,7 @@ DLL_HEADER void ExportGeom2d(py::module &m) ([] (shared_ptr self) { ng_geometry = self; + py::module::import("netgen").attr("Redraw")(); }) ) From c8901ba46b04e90c6ada66c21395c0f666cbac79 Mon Sep 17 00:00:00 2001 From: Matthias Hochsteger Date: Fri, 13 Dec 2019 10:20:19 +0100 Subject: [PATCH 7/7] cleanup in Snapshot() --- libsrc/include/incopengl.hpp | 2 -- libsrc/visualization/mvdraw.cpp | 51 +++++++++++++++-------------- libsrc/visualization/vssolution.cpp | 4 --- 3 files changed, 27 insertions(+), 30 deletions(-) diff --git a/libsrc/include/incopengl.hpp b/libsrc/include/incopengl.hpp index c4630a09..8cff36af 100644 --- a/libsrc/include/incopengl.hpp +++ b/libsrc/include/incopengl.hpp @@ -47,12 +47,10 @@ extern void (*glBindFramebuffer) (GLenum target, GLuint framebuffer); extern void (*glBindRenderbuffer) (GLenum target, GLuint renderbuffer); extern void (*glDeleteFramebuffers) (GLsizei n, const GLuint *framebuffers); extern void (*glDeleteRenderbuffers) (GLsizei n, const GLuint *renderbuffers); -extern void (*glFramebufferTexture) (GLenum target, GLenum attachment, GLuint texture, GLint level); extern void (*glGenFramebuffers) (GLsizei n, GLuint *framebuffers); extern void (*glGenRenderbuffers) (GLsizei n, GLuint *renderbuffers); extern void (*glRenderbufferStorage) (GLenum target, GLenum internalformat, GLsizei width, GLsizei height); extern void (*glFramebufferRenderbuffer) (GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer); -extern void (*glNamedFramebufferReadBuffer) ( GLuint framebuffer, GLenum mode); #endif DLL_HEADER void LoadOpenGLFunctionPointers(); #endif // INCOPENGL_HPP___ diff --git a/libsrc/visualization/mvdraw.cpp b/libsrc/visualization/mvdraw.cpp index 1142755a..65b89b05 100644 --- a/libsrc/visualization/mvdraw.cpp +++ b/libsrc/visualization/mvdraw.cpp @@ -783,7 +783,12 @@ namespace netgen std::vector Snapshot( int w, int h ) { - glMatrixMode(GL_PROJECTION); + // save current settings + GLint viewport[4]; + glGetIntegerv (GL_VIEWPORT, viewport); + + glMatrixMode (GL_PROJECTION); + glPushMatrix(); glLoadIdentity(); double pnear = 0.1; @@ -791,50 +796,48 @@ namespace netgen gluPerspective(20.0f, double(w) / h, pnear, pfar); - glMatrixMode(GL_MODELVIEW); + glMatrixMode (GL_MODELVIEW); + glPushMatrix(); + glLoadIdentity(); + glViewport(0,0,w,h); GLuint fb = 0; glGenFramebuffers(1, &fb); glBindFramebuffer(GL_FRAMEBUFFER, fb); - GLuint tex; - glGenTextures(1, &tex); + // create, reserve and attach color and depth renderbuffer + GLuint rbs[2]; + glGenRenderbuffers(2, rbs); + glBindRenderbuffer(GL_RENDERBUFFER, rbs[0]); + glRenderbufferStorage(GL_RENDERBUFFER, GL_RGBA8, w, h); + glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, rbs[0]); - glBindTexture(GL_TEXTURE_2D, tex); - - glTexImage2D(GL_TEXTURE_2D, 0,GL_RGBA, w, h, 0,GL_RGBA, GL_UNSIGNED_BYTE, 0); - - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); - - GLuint depthrenderbuffer; - glGenRenderbuffers(1, &depthrenderbuffer); - glBindRenderbuffer(GL_RENDERBUFFER, depthrenderbuffer); + glBindRenderbuffer(GL_RENDERBUFFER, rbs[1]); glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT, w, h); - glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, depthrenderbuffer); - - glFramebufferTexture(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, tex, 0); + glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, rbs[1]); + // check if framebuffer status is complete if(int fbstatus; (fbstatus = glCheckFramebufferStatus(GL_FRAMEBUFFER)) != GL_FRAMEBUFFER_COMPLETE) cerr << "no frame buffer " << fbstatus << endl; - glBindFramebuffer(GL_FRAMEBUFFER, fb); - glViewport(0,0,w,h); - - glPushMatrix(); visual_scene->DrawScene(); glFinish(); - glPopMatrix(); std::vector buffer(w*h*3); glPixelStorei(GL_UNPACK_ALIGNMENT,1); glPixelStorei(GL_PACK_ALIGNMENT,1); glReadPixels (0, 0, w, h, GL_RGB, GL_UNSIGNED_BYTE, &buffer[0]); - glDeleteRenderbuffers(1, &depthrenderbuffer); - glDeleteTextures(1, &tex); + glDeleteRenderbuffers(2, rbs); glDeleteFramebuffers(1, &fb); + glBindFramebuffer(GL_FRAMEBUFFER, 0); + // restore previous settings + glViewport(viewport[0], viewport[1], viewport[2], viewport[3]); + glMatrixMode (GL_PROJECTION); + glPopMatrix(); + glMatrixMode (GL_MODELVIEW); + glPopMatrix(); return buffer; } diff --git a/libsrc/visualization/vssolution.cpp b/libsrc/visualization/vssolution.cpp index 624e95f7..d0aa8468 100644 --- a/libsrc/visualization/vssolution.cpp +++ b/libsrc/visualization/vssolution.cpp @@ -4896,12 +4896,10 @@ void (*glBindFramebuffer) (GLenum target, GLuint framebuffer); void (*glBindRenderbuffer) (GLenum target, GLuint renderbuffer); void (*glDeleteFramebuffers) (GLsizei n, const GLuint *framebuffers); void (*glDeleteRenderbuffers) (GLsizei n, const GLuint *renderbuffers); -void (*glFramebufferTexture) (GLenum target, GLenum attachment, GLuint texture, GLint level); void (*glGenFramebuffers) (GLsizei n, GLuint *framebuffers); void (*glGenRenderbuffers) (GLsizei n, GLuint *renderbuffers); void (*glRenderbufferStorage) (GLenum target, GLenum internalformat, GLsizei width, GLsizei height); void (*glFramebufferRenderbuffer) (GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer); -void (*glNamedFramebufferReadBuffer) ( GLuint framebuffer, GLenum mode); DLL_HEADER void LoadOpenGLFunctionPointers() { #ifdef USE_BUFFERS @@ -4918,12 +4916,10 @@ DLL_HEADER void LoadOpenGLFunctionPointers() { glBindRenderbuffer = (decltype(glBindRenderbuffer )) wglGetProcAddress("glBindRenderbuffer"); glDeleteFramebuffers = (decltype(glDeleteFramebuffers )) wglGetProcAddress("glDeleteFramebuffers"); glDeleteRenderbuffers = (decltype(glDeleteRenderbuffers )) wglGetProcAddress("glDeleteRenderbuffers"); - glFramebufferTexture = (decltype(glFramebufferTexture )) wglGetProcAddress("glFramebufferTexture"); glGenFramebuffers = (decltype(glGenFramebuffers )) wglGetProcAddress("glGenFramebuffers"); glGenRenderbuffers = (decltype(glGenRenderbuffers )) wglGetProcAddress("glGenRenderbuffers"); glRenderbufferStorage = (decltype(glRenderbufferStorage )) wglGetProcAddress("glRenderbufferStorage"); glFramebufferRenderbuffer = (decltype(glFramebufferRenderbuffer )) wglGetProcAddress("glFramebufferRenderbuffer"); - glNamedFramebufferReadBuffer = (decltype(glNamedFramebufferReadBuffer )) wglGetProcAddress("glNamedFramebufferReadBuffer"); } #else // WIN32 DLL_HEADER void LoadOpenGLFunctionPointers() { }