22#include < algorithm>
33#include < random>
44
5- #include < glm/glm.hpp>
5+ #include < glm/vec2.hpp>
6+ #include < glm/vec3.hpp>
67
78#include < glbinding/gl/gl.h>
89#include < glbinding/gl/extension.h>
1920
2021#include " ScreenAlignedQuad.h"
2122
23+ // example commons
24+ #include " contextinfo.inl"
25+ #include " datapath.inl"
2226
23- using namespace gl ;
24- using namespace glm ;
25- using namespace globjects ;
26-
27-
28- namespace {
29- bool g_toggleFS = false ;
30- bool g_isFS = false ;
31-
32- Texture * g_texture = nullptr ;
33- ScreenAlignedQuad * g_quad = nullptr ;
34- ivec2 g_pageSize;
35- ivec2 g_numPages;
36- int g_totalPages;
37-
38- const ivec2 g_textureSize (4096 );
39- const int g_maxResidentPages (512 );
40- }
41-
42-
43- void key_callback (GLFWwindow * window, int key, int /* scancode*/ , int action, int /* modes*/ )
44- {
45- if (key == GLFW_KEY_ESCAPE && action == GLFW_RELEASE)
46- glfwSetWindowShouldClose (window, true );
4727
48- if (key == GLFW_KEY_F5 && action == GLFW_RELEASE)
49- File::reloadAll ();
28+ using namespace gl ;
5029
51- if (key == GLFW_KEY_F11 && action == GLFW_RELEASE)
52- g_toggleFS = true ;
53- }
5430
55- GLFWwindow * createWindow ( bool fs = false )
31+ namespace
5632{
57- // Set GLFW window hints
58- glfwSetErrorCallback ( [] (int /* error*/ , const char * description) { puts (description); } );
59- glfwWindowHint (GLFW_CONTEXT_VERSION_MAJOR, 3 );
60- glfwWindowHint (GLFW_CONTEXT_VERSION_MINOR, 1 );
61- glfwWindowHint (GLFW_OPENGL_FORWARD_COMPAT, true );
62-
63- // Create a context and, if valid, make it current
64- GLFWwindow * window = glfwCreateWindow (1024 , 768 , " " , fs ? glfwGetPrimaryMonitor () : NULL , NULL );
65- if (window == nullptr )
66- {
67- critical () << " Context creation failed. Terminate execution." ;
68-
69- glfwTerminate ();
70- exit (1 );
71- }
72- glfwMakeContextCurrent (window);
73-
74- // Create callback that when user presses ESC, the context should be destroyed and window closed
75- glfwSetKeyCallback (window, key_callback);
76-
77- // Initialize globjects (internally initializes glbinding, and registers the current context)
78- globjects::init ();
79-
80- // Do only on startup
81- if (!g_toggleFS)
82- {
83- // Dump information about context and graphics card
84- info () << std::endl
85- << " OpenGL Version: " << glbinding::ContextInfo::version () << std::endl
86- << " OpenGL Vendor: " << glbinding::ContextInfo::vendor () << std::endl
87- << " OpenGL Renderer: " << glbinding::ContextInfo::renderer () << std::endl;
88- }
89-
90- if (!hasExtension (GLextension::GL_ARB_sparse_texture))
91- {
92- critical () << " Sparse textues not supported." ;
33+ globjects::Texture * g_texture = nullptr ;
34+ ScreenAlignedQuad * g_quad = nullptr ;
9335
94- glfwTerminate () ;
95- exit ( 1 ) ;
96- }
36+ auto g_pageSize = glm::ivec2{ } ;
37+ auto g_numPages = glm::ivec2{ } ;
38+ auto g_totalPages = 0u ;
9739
98- glClearColor (0 .2f , 0 .3f , 0 .4f , 1 .f );
40+ const auto g_textureSize = glm::ivec2{4096 };
41+ const auto g_maxResidentPages = 512 ;
9942
100- g_isFS = fs;
101- return window;
43+ auto g_size = glm::ivec2{};
10244}
10345
104- void destroyWindow (GLFWwindow * window)
105- {
106- globjects::detachAllObjects ();
107- glfwDestroyWindow (window);
108- }
10946
11047void initialize ()
11148{
11249 // Initialize OpenGL objects
11350 int numPageSizes;
11451 glGetInternalformativ (GL_TEXTURE_2D, GL_RGBA8, GL_NUM_VIRTUAL_PAGE_SIZES_ARB, sizeof (int ), &numPageSizes);
115- info (" GL_NUM_VIRTUAL_PAGE_SIZES_ARB = %d;" , numPageSizes);
52+ globjects:: info (" GL_NUM_VIRTUAL_PAGE_SIZES_ARB = %d;" , numPageSizes);
11653
11754 if (numPageSizes == 0 )
11855 {
119- fatal (" Sparse Texture not supported for GL_RGBA8" );
56+ globjects:: fatal (" Sparse Texture not supported for GL_RGBA8" );
12057 exit (1 );
12158 }
12259
12360 std::vector<int > pageSizesX (numPageSizes);
12461 glGetInternalformativ (GL_TEXTURE_2D, GL_RGBA8, GL_VIRTUAL_PAGE_SIZE_X_ARB
12562 , static_cast <GLsizei>(numPageSizes * sizeof (int )), pageSizesX.data ());
12663 for (int i = 0 ; i < numPageSizes; ++i)
127- info (" GL_VIRTUAL_PAGE_SIZE_X_ARB[%;] = %;" , i, pageSizesX[i]);
64+ globjects:: info (" GL_VIRTUAL_PAGE_SIZE_X_ARB[%;] = %;" , i, pageSizesX[i]);
12865
12966 std::vector<int > pageSizesY (numPageSizes);
13067 glGetInternalformativ (GL_TEXTURE_2D, GL_RGBA8, GL_VIRTUAL_PAGE_SIZE_Y_ARB
13168 , static_cast <GLsizei>(numPageSizes * sizeof (int )), pageSizesY.data ());
13269 for (int i = 0 ; i < numPageSizes; ++i)
133- info (" GL_VIRTUAL_PAGE_SIZE_Y_ARB[%;] = %;" , i, pageSizesY[i]);
70+ globjects:: info (" GL_VIRTUAL_PAGE_SIZE_Y_ARB[%;] = %;" , i, pageSizesY[i]);
13471
13572 std::vector<int > pageSizesZ (numPageSizes);
13673 glGetInternalformativ (GL_TEXTURE_2D, GL_RGBA8, GL_VIRTUAL_PAGE_SIZE_Z_ARB
13774 , static_cast <GLsizei>(numPageSizes * sizeof (int )), pageSizesZ.data ());
13875 for (int i = 0 ; i < numPageSizes; ++i)
139- info (" GL_VIRTUAL_PAGE_SIZE_Z_ARB[%;] = %;" , i, pageSizesZ[i]);
76+ globjects:: info (" GL_VIRTUAL_PAGE_SIZE_Z_ARB[%;] = %;" , i, pageSizesZ[i]);
14077
141- g_pageSize = ivec2 (pageSizesX[0 ], pageSizesY[0 ]);
78+ g_pageSize = glm:: ivec2 (pageSizesX[0 ], pageSizesY[0 ]);
14279 g_numPages = g_textureSize / g_pageSize;
14380 g_totalPages = g_numPages.x * g_numPages.y ;
14481
14582 // Get maximum sparse texture size
14683
14784 int maxSparseTextureSize;
14885 glGetIntegerv (GL_MAX_SPARSE_TEXTURE_SIZE_ARB, &maxSparseTextureSize);
149- info (" GL_MAX_SPARSE_TEXTURE_SIZE_ARB = %d;" , maxSparseTextureSize);
86+ globjects:: info (" GL_MAX_SPARSE_TEXTURE_SIZE_ARB = %d;" , maxSparseTextureSize);
15087
151- g_texture = new Texture (GL_TEXTURE_2D);
88+ g_texture = new globjects:: Texture (GL_TEXTURE_2D);
15289 g_texture->ref ();
15390
15491 // make texture sparse
@@ -195,14 +132,14 @@ void mapNextPage()
195132 data[i] = static_cast <unsigned char >(255 - static_cast <unsigned char >(r (generator) * 255 ));
196133
197134 // unmap oldest page
198- int oldestPage = (currentPage + g_totalPages - g_maxResidentPages) % g_totalPages;
199- ivec2 oldOffset = ivec2 (oldestPage % g_numPages.x , oldestPage / g_numPages.x ) * g_pageSize;
200- g_texture->pageCommitment (0 , ivec3 (oldOffset, 0 ), ivec3 (g_pageSize, 1 ), GL_FALSE);
135+ const auto oldestPage = (currentPage + g_totalPages - g_maxResidentPages) % g_totalPages;
136+ const auto oldOffset = glm:: ivec2 (oldestPage % g_numPages.x , oldestPage / g_numPages.x ) * g_pageSize;
137+ g_texture->pageCommitment (0 , glm:: ivec3 (oldOffset, 0 ), glm:: ivec3 (g_pageSize, 1 ), GL_FALSE);
201138
202139 // map next page
203- ivec2 newOffset = ivec2 (currentPage % g_numPages.x , currentPage / g_numPages.x ) * g_pageSize;
140+ glm:: ivec2 newOffset = glm:: ivec2 (currentPage % g_numPages.x , currentPage / g_numPages.x ) * g_pageSize;
204141
205- g_texture->pageCommitment (0 , ivec3 (newOffset, 0 ), ivec3 (g_pageSize, 1 ), GL_TRUE);
142+ g_texture->pageCommitment (0 , glm:: ivec3 (newOffset, 0 ), glm:: ivec3 (g_pageSize, 1 ), GL_TRUE);
206143 g_texture->subImage2D (0 , newOffset, g_pageSize, GL_RGBA, GL_UNSIGNED_BYTE, data.data ());
207144
208145 currentPage = (currentPage + 1 ) % g_totalPages;
@@ -214,42 +151,73 @@ void draw()
214151
215152 mapNextPage ();
216153
154+ glViewport (0 , 0 , g_size.x , g_size.y );
217155 g_quad->draw ();
218156}
219157
220158
221- /* *
222- * @brief This example shows how to set up a sparse texture and then map/unmap pages using the ARB_sparse_texture extension.
223- *
224- * See http://www.opengl.org/registry/specs/ARB/sparse_texture.txt
225- */
159+ void error (int errnum, const char * errmsg)
160+ {
161+ globjects::critical () << errnum << " : " << errmsg << std::endl;
162+ }
163+
164+ void framebuffer_size_callback (GLFWwindow * /* window*/ , int width, int height)
165+ {
166+ g_size = glm::ivec2{ width, height };
167+ }
168+
169+ void key_callback (GLFWwindow * window, int key, int /* scancode*/ , int action, int /* modes*/ )
170+ {
171+ if (key == GLFW_KEY_ESCAPE && action == GLFW_RELEASE)
172+ glfwSetWindowShouldClose (window, true );
173+ }
174+
175+
226176int main (int /* argc*/ , char * /* argv*/ [])
227177{
228178 // Initialize GLFW
229- glfwInit ();
179+ if (!glfwInit ())
180+ return 1 ;
181+
182+ glfwSetErrorCallback (error);
183+ glfwDefaultWindowHints ();
184+
185+ glfwSetErrorCallback ([](int /* error*/ , const char * description) { puts (description); });
186+ glfwWindowHint (GLFW_CONTEXT_VERSION_MAJOR, 3 );
187+ glfwWindowHint (GLFW_CONTEXT_VERSION_MINOR, 1 );
188+ glfwWindowHint (GLFW_OPENGL_FORWARD_COMPAT, true );
189+
190+ // Create a context and, if valid, make it current
191+ GLFWwindow * window = glfwCreateWindow (320 , 240 , " globjects Sparse Textures" , NULL , NULL );
192+ if (window == nullptr )
193+ {
194+ globjects::critical () << " Context creation failed. Terminate execution." ;
195+
196+ glfwTerminate ();
197+ return -1 ;
198+ }
199+ glfwSetKeyCallback (window, key_callback);
200+ glfwSetFramebufferSizeCallback (window, framebuffer_size_callback);
201+
202+ glfwMakeContextCurrent (window);
203+
204+ // Initialize globjects (internally initializes glbinding, and registers the current context)
205+ globjects::init ();
206+ common::printContextInfo ();
207+
208+ globjects::info () << " Press F5 to reload shaders." << std::endl;
209+
230210
231- GLFWwindow * window = createWindow ();
232211 initialize ();
212+ glfwGetFramebufferSize (window, &g_size[0 ], &g_size[1 ]);
233213
234214 // Main loop
235215 while (!glfwWindowShouldClose (window))
236216 {
237217 glfwPollEvents ();
238-
239- if (g_toggleFS)
240- {
241- deinitialize ();
242- destroyWindow (window);
243- window = createWindow (!g_isFS);
244- initialize ();
245-
246- g_toggleFS = false ;
247- }
248-
249218 draw ();
250219 glfwSwapBuffers (window);
251220 }
252-
253221 deinitialize ();
254222
255223 // Properly shutdown GLFW
0 commit comments