diff options
Diffstat (limited to 'graphics/asymptote/glrender.cc')
-rw-r--r-- | graphics/asymptote/glrender.cc | 324 |
1 files changed, 200 insertions, 124 deletions
diff --git a/graphics/asymptote/glrender.cc b/graphics/asymptote/glrender.cc index 68f298d10a..9b60846784 100644 --- a/graphics/asymptote/glrender.cc +++ b/graphics/asymptote/glrender.cc @@ -29,6 +29,7 @@ extern uint32_t CLZ(uint32_t a); bool GPUindexing; +bool GPUcompress; namespace gl { #ifdef HAVE_PTHREAD @@ -84,13 +85,15 @@ GLint countShader; GLint transparentShader; GLint blendShader; GLint zeroShader; +GLint compressShader; GLint sum1Shader; GLint sum2Shader; GLint sum3Shader; GLuint offsetBuffer; +GLuint indexBuffer; +GLuint elementsBuffer; GLuint countBuffer; -GLuint maxBuffer; GLuint localSumBuffer; GLuint globalSumBuffer; GLuint fragmentBuffer; @@ -165,8 +168,10 @@ GLint gs; GLint g; GLuint processors; GLuint localsize; +GLuint lastlocalsize; GLint maxgroups; GLuint maxSize; +GLuint lastSize; bool outlinemode=false; bool ibl=false; @@ -208,6 +213,7 @@ string Format; int fullWidth,fullHeight; int Width,Height; GLuint pixels; +GLuint elements; GLuint lastpixels; double oWidth,oHeight; int screenWidth,screenHeight; @@ -533,12 +539,6 @@ void noShaders() exit(-1); } -// Return ceil(log2(n)) where n is a 32 bit unsigned integer. -uint32_t ceillog2(uint32_t n) -{ - return 32-CLZ(n-1); -} - void initComputeShaders() { string sum1=locateFile("shaders/sum1.glsl"); @@ -585,31 +585,44 @@ void initBlendShader() std::vector<ShaderfileModePair> shaders(2); std::vector<std::string> shaderParams; - ostringstream s,m2; + ostringstream s; s << "ARRAYSIZE " << maxSize << "u" << endl; shaderParams.push_back(s.str().c_str()); - m2 << "m2 " << localsize; - shaderParams.push_back(m2.str().c_str()); if(GPUindexing) shaderParams.push_back("GPUINDEXING"); + if(GPUcompress) + shaderParams.push_back("GPUCOMPRESS"); shaders[0]=ShaderfileModePair(screen.c_str(),GL_VERTEX_SHADER); shaders[1]=ShaderfileModePair(blend.c_str(),GL_FRAGMENT_SHADER); camp::blendShader=compileAndLinkShader(shaders,shaderParams,ssbo); } +// Return the smallest power of 2 greater than or equal to n. +inline GLuint ceilpow2(GLuint n) +{ + --n; + n |= n >> 1; + n |= n >> 2; + n |= n >> 4; + n |= n >> 8; + n |= n >> 16; + return ++n; +} + void initShaders() { Nlights=nlights == 0 ? 0 : max(Nlights,nlights); Nmaterials=max(Nmaterials,nmaterials); string zero=locateFile("shaders/zero.glsl"); + string compress=locateFile("shaders/compress.glsl"); string vertex=locateFile("shaders/vertex.glsl"); string count=locateFile("shaders/count.glsl"); string fragment=locateFile("shaders/fragment.glsl"); string screen=locateFile("shaders/screen.glsl"); - if(zero.empty() || vertex.empty() || fragment.empty() || screen.empty() || - count.empty()) + if(zero.empty() || compress.empty() || vertex.empty() || fragment.empty() || + screen.empty() || count.empty()) noShaders(); if(GPUindexing) @@ -628,6 +641,8 @@ void initShaders() #ifdef HAVE_SSBO if(GPUindexing) shaderParams.push_back("GPUINDEXING"); + if(GPUcompress) + shaderParams.push_back("GPUCOMPRESS"); shaders[1]=ShaderfileModePair(count.c_str(),GL_FRAGMENT_SHADER); camp::countShader=compileAndLinkShader(shaders,shaderParams,true); if(camp::countShader) @@ -647,10 +662,6 @@ void initShaders() cout << "No SSBO support; order-independent transparency unavailable" << endl; - ostringstream m2; - m2 << "m2 " << localsize; - shaderParams.push_back(m2.str().c_str()); - shaders[1]=ShaderfileModePair(fragment.c_str(),GL_FRAGMENT_SHADER); shaderParams.push_back("MATERIAL"); if(orthographic) @@ -670,7 +681,7 @@ void initShaders() if(interlock) shaderParams.push_back("HAVE_INTERLOCK"); camp::materialShader[0]=compileAndLinkShader(shaders,shaderParams,ssbo, interlock); - if(!camp::materialShader[0]) { + if(interlock && !camp::materialShader[0]) { shaderParams.pop_back(); interlock=false; camp::materialShader[0]=compileAndLinkShader(shaders,shaderParams,ssbo); @@ -704,8 +715,14 @@ void initShaders() shaderParams.clear(); if(ssbo) { - if(!GPUindexing) { - shaders[0]=ShaderfileModePair(screen.c_str(),GL_VERTEX_SHADER); + if(GPUindexing) + shaderParams.push_back("GPUINDEXING"); + shaders[0]=ShaderfileModePair(screen.c_str(),GL_VERTEX_SHADER); + shaders[1]=ShaderfileModePair(compress.c_str(),GL_FRAGMENT_SHADER); + camp::compressShader=compileAndLinkShader(shaders,shaderParams,ssbo); + if(GPUindexing) + shaderParams.pop_back(); + else { shaders[1]=ShaderfileModePair(zero.c_str(),GL_FRAGMENT_SHADER); camp::zeroShader=compileAndLinkShader(shaders,shaderParams,ssbo); } @@ -736,6 +753,7 @@ void deleteShaders() else glDeleteProgram(camp::zeroShader); glDeleteProgram(camp::countShader); + glDeleteProgram(camp::compressShader); } glDeleteProgram(camp::transparentShader); @@ -747,6 +765,14 @@ void deleteShaders() glDeleteProgram(camp::pixelShader); } +void resizeBlendShader() +{ + gl::maxSize=ceilpow2(gl::maxSize); + gl::deleteBlendShader(); + gl::initBlendShader(); + gl::lastSize=gl::maxSize; +} + void setBuffers() { GLuint vao; @@ -761,12 +787,15 @@ void setBuffers() #ifdef HAVE_SSBO glGenBuffers(1, &camp::offsetBuffer); - glGenBuffers(1, &camp::maxBuffer); if(GPUindexing) { glGenBuffers(1, &camp::localSumBuffer); glGenBuffers(1, &camp::globalSumBuffer); } else glGenBuffers(1, &camp::countBuffer); + if(GPUcompress) { + glGenBuffers(1, &camp::indexBuffer); + glGenBuffers(1, &camp::elementsBuffer); + } glGenBuffers(1, &camp::fragmentBuffer); glGenBuffers(1, &camp::depthBuffer); glGenBuffers(1, &camp::opaqueBuffer); @@ -1862,6 +1891,12 @@ void init_osmesa() #endif /* HAVE_GL */ +bool NVIDIA() +{ + char *GLSL_VERSION=(char *) glGetString(GL_SHADING_LANGUAGE_VERSION); + return string(GLSL_VERSION).find("NVIDIA") != string::npos; +} + // angle=0 means orthographic. void glrender(const string& prefix, const picture *pic, const string& format, double width, double height, double angle, double zoom, @@ -1872,12 +1907,6 @@ void glrender(const string& prefix, const picture *pic, const string& format, { Iconify=getSetting<bool>("iconify"); -#if defined(HAVE_COMPUTE_SHADER) && !defined(HAVE_LIBOSMESA) - GPUindexing=getSetting<bool>("GPUindexing"); -#else - GPUindexing=false; -#endif - if(zoom == 0.0) zoom=1.0; Prefix=prefix; @@ -2124,11 +2153,19 @@ void glrender(const string& prefix, const picture *pic, const string& format, initialized=true; +#if defined(HAVE_COMPUTE_SHADER) && !defined(HAVE_LIBOSMESA) + GPUindexing=getSetting<bool>("GPUindexing"); + GPUcompress=NVIDIA() || getSetting<bool>("GPUcompress"); +#else + GPUindexing=false; + GPUcompress=false; +#endif + GLint val; glGetIntegerv(GL_MAX_UNIFORM_BLOCK_SIZE,&val); if(GPUindexing) - localsize=getSetting<Int>("GPUlocalSize"); + lastlocalsize=localsize=getSetting<Int>("GPUlocalSize"); Maxmaterials=val/sizeof(Material); if(nmaterials > Maxmaterials) nmaterials=Maxmaterials; @@ -2279,6 +2316,18 @@ void clearCount() glMemoryBarrier(GL_SHADER_STORAGE_BARRIER_BIT); } +void compressCount() +{ + glMemoryBarrier(GL_BUFFER_UPDATE_BARRIER_BIT); + glUseProgram(compressShader); + gl::lastshader=compressShader; + glUniform1ui(glGetUniformLocation(compressShader,"width"),gl::Width); + fpu_trap(false); // Work around FE_INVALID + glDrawArrays(GL_TRIANGLES, 0, 3); + fpu_trap(settings::trap()); + glMemoryBarrier(GL_SHADER_STORAGE_BARRIER_BIT); +} + void initPartialSums() { gl::gs=gl::localsize*gl::g; @@ -2286,26 +2335,28 @@ void initPartialSums() gl::processors=gl::localsize*gl::gs2; GLuint zero=0; glBindBuffer(GL_SHADER_STORAGE_BUFFER,camp::localSumBuffer); - glBufferData(GL_SHADER_STORAGE_BUFFER,(gl::processors+gl::gs2+2)*sizeof(GLuint),NULL, + glBufferData(GL_SHADER_STORAGE_BUFFER, + (gl::processors+gl::gs2+2)*sizeof(GLuint),NULL, GL_DYNAMIC_DRAW); - glClearBufferData(GL_SHADER_STORAGE_BUFFER,GL_R8UI,GL_RED_INTEGER, - GL_UNSIGNED_BYTE,&zero); + glClearBufferData(GL_SHADER_STORAGE_BUFFER,GL_R32UI,GL_RED_INTEGER, + GL_UNSIGNED_INT,&zero); glBindBufferBase(GL_SHADER_STORAGE_BUFFER,2,camp::localSumBuffer); glBindBuffer(GL_SHADER_STORAGE_BUFFER,camp::globalSumBuffer); - glBufferData(GL_SHADER_STORAGE_BUFFER,(1+gl::gs)*sizeof(GLuint),NULL, + glBufferData(GL_SHADER_STORAGE_BUFFER,(gl::gs+1)*sizeof(GLuint),NULL, GL_DYNAMIC_DRAW); - glClearBufferData(GL_SHADER_STORAGE_BUFFER,GL_R8UI,GL_RED_INTEGER, - GL_UNSIGNED_BYTE,&zero); + glClearBufferData(GL_SHADER_STORAGE_BUFFER,GL_R32UI,GL_RED_INTEGER, + GL_UNSIGNED_INT,&zero); glBindBufferBase(GL_SHADER_STORAGE_BUFFER,3,camp::globalSumBuffer); } -GLuint partialSums() +GLuint partialSums(bool readSize=false) { GLuint fragments; // Compute local partial sums on the GPU glUseProgram(sum1Shader); - glUniform1ui(glGetUniformLocation(sum1Shader,"elements"),gl::pixels); + glUniform1ui(glGetUniformLocation(sum1Shader,"elements"),gl::elements); + glDispatchCompute(gl::gs2,1,1); glMemoryBarrier(GL_BUFFER_UPDATE_BARRIER_BIT); @@ -2319,18 +2370,27 @@ GLuint partialSums() glUseProgram(sum3Shader); glUniform1ui(glGetUniformLocation(sum3Shader,"offset2"),offset2); + glUniform1ui(glGetUniformLocation(sum3Shader,"final"),offset2+gl::gs2); glDispatchCompute(gl::g,1,1); glMemoryBarrier(GL_BUFFER_UPDATE_BARRIER_BIT); // Compute global partial sums, including number of fragments, on the CPU - GLuint *sum=(GLuint *) (glMapBuffer(GL_SHADER_STORAGE_BUFFER, - GL_READ_WRITE)); - fragments=0; - for(GLint i=1; i <= gl::gs; ++i) { - fragments += sum[i]; - sum[i]=fragments; + GLuint *sum=(GLuint *) glMapBuffer(GL_SHADER_STORAGE_BUFFER,GL_READ_WRITE); + + if(readSize) { + gl::maxSize=sum[0]; + sum[0]=0; + if(gl::maxSize > gl::lastSize) + gl::resizeBlendShader(); } + + fragments=sum[1]; + for(GLint i=2; i < gl::gs; ++i) + sum[i]=fragments += sum[i]; + fragments += sum[gl::gs]; + glUnmapBuffer(GL_SHADER_STORAGE_BUFFER); + return fragments; } @@ -2341,20 +2401,35 @@ void refreshBuffers() gl::pixels=gl::Width*gl::Height; if(initSSBO) { + gl::processors=1; + glBindBuffer(GL_SHADER_STORAGE_BUFFER,camp::offsetBuffer); glBufferData(GL_SHADER_STORAGE_BUFFER, - (GPUindexing ? 2:1)*gl::pixels*sizeof(GLuint), + (GPUindexing ? 2 : 1)*(gl::pixels+1)*sizeof(GLuint), NULL,GL_DYNAMIC_DRAW); glBindBufferBase(GL_SHADER_STORAGE_BUFFER,0,camp::offsetBuffer); - glClearBufferData(GL_SHADER_STORAGE_BUFFER,GL_R8UI,GL_RED_INTEGER, - GL_UNSIGNED_BYTE,&zero); - glBindBuffer(GL_SHADER_STORAGE_BUFFER,camp::maxBuffer); - glBufferData(GL_SHADER_STORAGE_BUFFER,sizeof(GLuint), - NULL,GL_DYNAMIC_DRAW); - glBindBufferBase(GL_SHADER_STORAGE_BUFFER,1,camp::maxBuffer); - glClearBufferData(GL_SHADER_STORAGE_BUFFER,GL_R8UI,GL_RED_INTEGER, - GL_UNSIGNED_BYTE,&zero); + if(GPUcompress) { + glBindBuffer(GL_SHADER_STORAGE_BUFFER,camp::indexBuffer); + glBufferData(GL_SHADER_STORAGE_BUFFER,gl::pixels*sizeof(GLuint), + NULL,GL_DYNAMIC_DRAW); + glBindBufferBase(GL_SHADER_STORAGE_BUFFER,1,camp::indexBuffer); + glClearBufferData(GL_SHADER_STORAGE_BUFFER,GL_R32UI,GL_RED_INTEGER, + GL_UNSIGNED_INT,&zero); + + GLuint one=1; + glBindBuffer(GL_ATOMIC_COUNTER_BUFFER,camp::elementsBuffer); + glBufferData(GL_ATOMIC_COUNTER_BUFFER,sizeof(GLuint),&one, + GL_DYNAMIC_DRAW); + glBindBufferBase(GL_ATOMIC_COUNTER_BUFFER,0,camp::elementsBuffer); + } + + if(!GPUindexing) { + glBindBuffer(GL_SHADER_STORAGE_BUFFER,camp::countBuffer); + glBufferData(GL_SHADER_STORAGE_BUFFER,(gl::pixels+1)*sizeof(GLuint), + NULL,GL_DYNAMIC_DRAW); + glBindBufferBase(GL_SHADER_STORAGE_BUFFER,2,camp::countBuffer); + } glBindBuffer(GL_SHADER_STORAGE_BUFFER,camp::opaqueBuffer); glBufferData(GL_SHADER_STORAGE_BUFFER,gl::pixels*sizeof(glm::vec4),NULL, @@ -2362,17 +2437,59 @@ void refreshBuffers() glBindBufferBase(GL_SHADER_STORAGE_BUFFER,6,camp::opaqueBuffer); glBindBuffer(GL_SHADER_STORAGE_BUFFER,camp::opaqueDepthBuffer); - glBufferData(GL_SHADER_STORAGE_BUFFER,gl::pixels*sizeof(GLfloat),NULL, + glBufferData(GL_SHADER_STORAGE_BUFFER, + sizeof(GLuint)+gl::pixels*sizeof(GLfloat),NULL, GL_DYNAMIC_DRAW); glBindBufferBase(GL_SHADER_STORAGE_BUFFER,7,camp::opaqueDepthBuffer); const GLfloat zerof=0.0; glClearBufferData(GL_SHADER_STORAGE_BUFFER,GL_R32F,GL_RED,GL_FLOAT,&zerof); + } + + // Determine the fragment offsets + + if(!interlock) { + drawBuffer(material1Data,countShader); + drawBuffer(materialData,countShader); + drawBuffer(colorData,countShader,true); + drawBuffer(triangleData,countShader,true); + } + glDepthMask(GL_FALSE); // Don't write to depth buffer + glDisable(GL_MULTISAMPLE); + drawBuffer(transparentData,countShader,true); + glEnable(GL_MULTISAMPLE); + glDepthMask(GL_TRUE); // Write to depth buffer + + if(GPUcompress) { + compressCount(); + + GLuint *p=(GLuint *) glMapBuffer(GL_ATOMIC_COUNTER_BUFFER,GL_READ_WRITE); + gl::elements=GPUindexing ? p[0] : p[0]-1; + p[0]=1; + glUnmapBuffer(GL_ATOMIC_COUNTER_BUFFER); + if(gl::elements == 0) return; + } else + gl::elements=gl::pixels; + + if(initSSBO) { if(GPUindexing) { double Tmin=HUGE_VAL; GLuint G=1; - for(gl::g=2; gl::g <= gl::maxgroups; - gl::g *= 2) { + GLuint twos3=2*gl::localsize*gl::localsize*gl::localsize; + + if(twos3 > gl::elements) { + gl::localsize=1; + twos3=2; + } else gl::localsize=settings::getSetting<Int>("GPUlocalSize"); + + if(gl::localsize != gl::lastlocalsize) { + gl::deleteComputeShaders(); + gl::initComputeShaders(); + gl::lastlocalsize=gl::localsize; + } + + GLint stop=min(gl::maxgroups,(GLint) (gl::elements/twos3)); + for(gl::g=2; gl::g <= stop; gl::g *= 2) { initPartialSums(); partialSums(); seconds(); @@ -2385,54 +2502,30 @@ void refreshBuffers() } gl::g=G; initPartialSums(); - } else { - glBindBuffer(GL_SHADER_STORAGE_BUFFER,camp::countBuffer); - glBufferData(GL_SHADER_STORAGE_BUFFER,gl::pixels*sizeof(GLuint), - NULL,GL_DYNAMIC_DRAW); - glBindBufferBase(GL_SHADER_STORAGE_BUFFER,2,camp::countBuffer); - glClearBufferData(GL_SHADER_STORAGE_BUFFER,GL_R8UI,GL_RED_INTEGER, - GL_UNSIGNED_BYTE,&zero); } initSSBO=false; } - if(GPUindexing && gl::exporting) { - glBindBuffer(GL_SHADER_STORAGE_BUFFER,camp::offsetBuffer); - glClearBufferData(GL_SHADER_STORAGE_BUFFER,GL_R8UI,GL_RED_INTEGER, - GL_UNSIGNED_BYTE,&zero); - - glBindBuffer(GL_SHADER_STORAGE_BUFFER,camp::globalSumBuffer); - } - - // Determine the fragment offsets - - if(!interlock) { - drawBuffer(material1Data,countShader); - drawBuffer(materialData,countShader); - drawBuffer(colorData,countShader,true); - drawBuffer(triangleData,countShader,true); - } - - glDepthMask(GL_FALSE); // Don't write to depth buffer - glDisable(GL_MULTISAMPLE); - drawBuffer(transparentData,countShader,true); - glEnable(GL_MULTISAMPLE); - glDepthMask(GL_TRUE); // Write to depth buffer - if(GPUindexing) - fragments=partialSums(); + fragments=partialSums(true); else { + size_t size=gl::elements*sizeof(GLuint); + // Compute partial sums on the CPU glBindBuffer(GL_SHADER_STORAGE_BUFFER,camp::countBuffer); - GLuint *count=((GLuint *) glMapBuffer(GL_SHADER_STORAGE_BUFFER, - GL_READ_ONLY)); + GLuint *p=(GLuint *) glMapBufferRange(GL_SHADER_STORAGE_BUFFER, + 0,size+sizeof(GLuint), + GL_MAP_READ_BIT); + gl::maxSize=p[0]; + GLuint *count=p+1; glBindBuffer(GL_SHADER_STORAGE_BUFFER,camp::offsetBuffer); - GLuint *offset=(GLuint *) glMapBuffer(GL_SHADER_STORAGE_BUFFER, - GL_WRITE_ONLY); + GLuint *offset=(GLuint *) glMapBufferRange(GL_SHADER_STORAGE_BUFFER, + sizeof(GLuint),size, + GL_MAP_WRITE_BIT); size_t Offset=offset[0]=count[0]; - for(size_t i=1; i < gl::pixels; ++i) + for(size_t i=1; i < gl::elements; ++i) offset[i]=Offset += count[i]; fragments=Offset; @@ -2442,7 +2535,16 @@ void refreshBuffers() glBindBuffer(GL_SHADER_STORAGE_BUFFER,camp::countBuffer); glUnmapBuffer(GL_SHADER_STORAGE_BUFFER); - clearCount(); + if(gl::exporting && !GPUindexing) { + GLuint zero=0; + glBindBuffer(GL_SHADER_STORAGE_BUFFER,camp::countBuffer); + glClearBufferData(GL_SHADER_STORAGE_BUFFER,GL_R32UI,GL_RED_INTEGER, + GL_UNSIGNED_INT,&zero); + } else + clearCount(); + + if(gl::maxSize > gl::lastSize) + gl::resizeBlendShader(); } if(fragments > maxFragments) { @@ -2478,12 +2580,13 @@ void setUniforms(vertexBuffer& data, GLint shader) if(camp::ssbo && GPUindexing && (shader == transparentShader || !interlock)) { - glUniform1ui(glGetUniformLocation(shader,"pixels"),gl::pixels); GLuint offset2=1+gl::processors; + glUniform1ui(glGetUniformLocation(shader,"elements"),gl::elements); glUniform1ui(glGetUniformLocation(shader,"offset2"),offset2); - GLuint m=GPUindexing ? gl::pixels/gl::processors : 0; - GLuint r=gl::pixels-m*gl::processors; + GLuint m=gl::elements/gl::processors; + GLuint r=gl::elements-m*gl::processors; glUniform1ui(glGetUniformLocation(shader,"m1"),m); + glUniform1ui(glGetUniformLocation(shader,"m2"),gl::localsize); glUniform1ui(glGetUniformLocation(shader,"r"),r); } } @@ -2632,18 +2735,6 @@ void drawTriangle() triangleData.clear(); } -// Return the smallest power of 2 greater than or equal to n. -inline GLuint ceilpow2(GLuint n) -{ - --n; - n |= n >> 1; - n |= n >> 2; - n |= n >> 4; - n |= n >> 8; - n |= n >> 16; - return ++n; -} - void aBufferTransparency() { // Collect transparent fragments @@ -2657,12 +2748,13 @@ void aBufferTransparency() gl::lastshader=blendShader; glUniform1ui(glGetUniformLocation(blendShader,"width"),gl::Width); if(GPUindexing) { - glUniform1ui(glGetUniformLocation(blendShader,"pixels"),gl::pixels); GLuint offset2=gl::processors+1; + glUniform1ui(glGetUniformLocation(blendShader,"elements"),gl::elements); glUniform1ui(glGetUniformLocation(blendShader,"offset2"),offset2); - GLuint m=GPUindexing ? gl::pixels/gl::processors : 0; - GLuint r=gl::pixels-m*gl::processors; + GLuint m=gl::elements/gl::processors; + GLuint r=gl::elements-m*gl::processors; glUniform1ui(glGetUniformLocation(blendShader,"m1"),m); + glUniform1ui(glGetUniformLocation(blendShader,"m2"),gl::localsize); glUniform1ui(glGetUniformLocation(blendShader,"r"),r); } glUniform4f(glGetUniformLocation(blendShader,"background"), @@ -2673,22 +2765,6 @@ void aBufferTransparency() glDrawArrays(GL_TRIANGLES,0,3); fpu_trap(settings::trap()); transparentData.clear(); - - if(gl::maxSize > 0) { - glBindBuffer(GL_SHADER_STORAGE_BUFFER,camp::maxBuffer); - GLuint *p=(GLuint *) glMapBuffer(GL_SHADER_STORAGE_BUFFER,GL_READ_WRITE); - gl::maxSize=p[0]; - p[0]=0; - glUnmapBuffer(GL_SHADER_STORAGE_BUFFER); - if(gl::maxSize > 0) { - gl::maxSize=ceilpow2(gl::maxSize); - gl::deleteBlendShader(); - gl::initBlendShader(); - } - if(GPUindexing) - glBindBuffer(GL_SHADER_STORAGE_BUFFER,camp::globalSumBuffer); - } - glEnable(GL_DEPTH_TEST); } |