void VisibilityExtractionDemo::init() { window = generateWindow(); // load a file std::vector<std::string> paths; //paths.push_back("/home/nlichtenberg/1crn.pdb"); paths.push_back("/home/nlichtenberg/1vis.pdb"); //paths.push_back("/home/nlichtenberg/Develop/Mol_Sandbox/resources/TrajectoryFiles/1aon.pdb"); MdTrajWrapper mdwrap; std::auto_ptr<Protein> prot = mdwrap.load(paths); impSph = new ImpostorSpheres(!useAtomicCounters, false); impSph->setProteinData(prot.get()); impSph->init(); num_balls = impSph->num_balls; if(perspectiveProj) projection = perspective(45.0f, getRatio(window), 0.1f, 100.0f); else projection = ortho(-30.0f, 30.0f, -30.0f, 30.0f, 0.0f, 100.0f); if (useAtomicCounters) { spRenderImpostor = ShaderProgram("/VisibleAtomsDetection/Impostor/impostorSpheres_InstancedUA.vert", "/VisibleAtomsDetection/Detection/solidColorInstanceCount.frag"); spRenderDiscs = ShaderProgram("/VisibleAtomsDetection//Impostor/impostorSpheres_InstancedUA.vert", "/VisibleAtomsDetection//Impostor/impostorSpheres_discardFragments_Instanced.frag"); if(perspectiveProj) spRenderBalls = ShaderProgram("/VisibleAtomsDetection/Base/modelViewProjectionInstancedUA.vert", "/VisibleAtomsDetection/Impostor/Impostor3DSphere.frag"); else spRenderBalls = ShaderProgram("/VisibleAtomsDetection/Base/modelViewProjectionInstancedUA.vert", "/VisibleAtomsDetection/Impostor/Impostor3DSphere_Ortho.frag"); } else { spRenderImpostor = ShaderProgram("/VisibleAtomsDetection/Impostor/impostorSpheres_Instanced.vert", "/VisibleAtomsDetection/Detection/solidColorInstanceCount.frag"); spRenderDiscs = ShaderProgram("/VisibleAtomsDetection/Impostor/impostorSpheres_Instanced.vert", "/VisibleAtomsDetection/Impostor/impostorSpheres_discardFragments_Instanced.frag"); spRenderBalls = ShaderProgram("/VisibleAtomsDetection/Impostor/impostorSpheres_Instanced.vert", "/VisibleAtomsDetection/Impostor/Impostor3DSphere.frag"); } /// Renderpass to render impostors/fake geometry renderBalls = new RenderPass( impSph, &spRenderBalls, getWidth(window), getHeight(window)); renderBalls->update("projection", projection); // define projection matrix for other shader programs renderBalls->setShaderProgram(&spRenderDiscs); renderBalls->update("projection", projection); renderBalls->setShaderProgram(&spRenderImpostor); renderBalls->update("projection", projection); /// Renderpass to detect the visible instances collectSurfaceIDs = new RenderPass( new Quad(), new ShaderProgram("/VisibleAtomsDetection/Base/fullscreen.vert", "/VisibleAtomsDetection/Detection/DetectVisibleInstanceIDs.frag"), getWidth(window), getHeight(window)); // prepare 1D buffer for entries tex_collectedIDsBuffer = new Texture(GL_R8UI, GL_RED_INTEGER, GL_UNSIGNED_INT); tex_collectedIDsBuffer->genUimageBuffer(num_balls); collectSurfaceIDs->texture("collectedIDsBuffer", tex_collectedIDsBuffer); collectSurfaceIDs->texture("tex", renderBalls->get("InstanceID")); /// renderpass to display result frame result = new RenderPass( new Quad(), new ShaderProgram("/VisibleAtomsDetection/Base/fullscreen.vert", "/VisibleAtomsDetection/Detection/toneMapperLinearInstanceCount.frag")); result->texture("tex", renderBalls->get("fragColor")); /// compute shader to process a list of visible IDs (with the actual instanceID of the first general draw) computeSortedIDs = new ComputeProgram(new ShaderProgram("/VisibleAtomsDetection/Detection/CreateVisibleIDList.comp")); // 1D buffer for visible IDs tex_sortedVisibleIDsBuffer = new Texture(GL_R32UI, GL_RED_INTEGER, GL_UNSIGNED_INT); tex_sortedVisibleIDsBuffer->genUimageBuffer(num_balls); computeSortedIDs->texture("collectedIDsBuffer", tex_collectedIDsBuffer); computeSortedIDs->texture("sortedVisibleIDsBuffer", tex_sortedVisibleIDsBuffer); // atomic counter buffer for consecutive index access in compute shader glGenBuffers(1, &atomBuff); glBindBuffer(GL_ATOMIC_COUNTER_BUFFER, atomBuff); glBindBufferBase(GL_ATOMIC_COUNTER_BUFFER, 3, atomBuff); glBufferData(GL_ATOMIC_COUNTER_BUFFER, sizeof(GLuint), NULL, GL_DYNAMIC_DRAW); glBindBuffer(GL_ATOMIC_COUNTER_BUFFER, 0); positions_size = sizeof(glm::vec4) * impSph->instance_positions_s.instance_positions.size(); colors_size = sizeof(glm::vec4) * impSph->instance_colors_s.instance_colors.size(); // SSBO setup glGenBuffers(2, SSBO); glBindBuffer(GL_SHADER_STORAGE_BUFFER, SSBO[0]); glBufferData(GL_SHADER_STORAGE_BUFFER, positions_size, &impSph->instance_positions_s.instance_positions[0], GL_DYNAMIC_COPY); glBindBufferRange(GL_SHADER_STORAGE_BUFFER, 0, SSBO[0], 0, positions_size); glBindBuffer(GL_SHADER_STORAGE_BUFFER, SSBO[1]); glBufferData(GL_SHADER_STORAGE_BUFFER, colors_size, &impSph->instance_colors_s.instance_colors[0], GL_DYNAMIC_COPY); glBindBufferRange(GL_SHADER_STORAGE_BUFFER, 1, SSBO[1], 0, colors_size); glBindBuffer(GL_SHADER_STORAGE_BUFFER, 0); // SSBO copy data glBindBuffer(GL_SHADER_STORAGE_BUFFER, SSBO[0]); GLvoid* p_ = glMapBuffer(GL_SHADER_STORAGE_BUFFER, GL_WRITE_ONLY); memcpy(p_, &impSph->instance_positions_s.instance_positions[0], positions_size); glUnmapBuffer(GL_SHADER_STORAGE_BUFFER); glBindBuffer(GL_SHADER_STORAGE_BUFFER, SSBO[1]); p_ = glMapBuffer(GL_SHADER_STORAGE_BUFFER, GL_WRITE_ONLY); memcpy(p_, &impSph->instance_colors_s.instance_colors[0], colors_size); glUnmapBuffer(GL_SHADER_STORAGE_BUFFER); // SSBO bind to shaders glBindBuffer(GL_SHADER_STORAGE_BUFFER, SSBO[0]); GLuint block_index = 0; block_index = glGetProgramResourceIndex(spRenderBalls.getProgramHandle(), GL_SHADER_STORAGE_BLOCK, "instance_positions_t"); glShaderStorageBlockBinding(spRenderBalls.getProgramHandle(), block_index, 0); glBindBuffer(GL_SHADER_STORAGE_BUFFER, SSBO[1]); block_index = glGetProgramResourceIndex(spRenderBalls.getProgramHandle(), GL_SHADER_STORAGE_BLOCK, "instance_colors_t"); glShaderStorageBlockBinding(spRenderBalls.getProgramHandle(), block_index, 1); glBindBuffer(GL_SHADER_STORAGE_BUFFER, SSBO[0]); block_index = glGetProgramResourceIndex(spRenderDiscs.getProgramHandle(), GL_SHADER_STORAGE_BLOCK, "instance_positions_t"); glShaderStorageBlockBinding(spRenderBalls.getProgramHandle(), block_index, 0); glBindBuffer(GL_SHADER_STORAGE_BUFFER, SSBO[1]); block_index = glGetProgramResourceIndex(spRenderDiscs.getProgramHandle(), GL_SHADER_STORAGE_BLOCK, "instance_colors_t"); glShaderStorageBlockBinding(spRenderBalls.getProgramHandle(), block_index, 1); glBindBuffer(GL_SHADER_STORAGE_BUFFER, SSBO[0]); block_index = glGetProgramResourceIndex(spRenderImpostor.getProgramHandle(), GL_SHADER_STORAGE_BLOCK, "instance_positions_t"); glShaderStorageBlockBinding(spRenderBalls.getProgramHandle(), block_index, 0); glBindBuffer(GL_SHADER_STORAGE_BUFFER, SSBO[1]); block_index = glGetProgramResourceIndex(spRenderImpostor.getProgramHandle(), GL_SHADER_STORAGE_BLOCK, "instance_colors_t"); glShaderStorageBlockBinding(spRenderBalls.getProgramHandle(), block_index, 1); // prepare data to reset the buffer that holds the visible instance IDs int byteCount = sizeof(unsigned int)* num_balls; zeros = new unsigned char[byteCount]; unsigned int f = 0; unsigned char const * p = reinterpret_cast<unsigned char const *>(&f); for (int i = 0; i < byteCount; i+=4) { zeros[i] = p[0]; zeros[i+1] = p[1]; zeros[i+2] = p[2]; zeros[i+3] = p[3]; } // prepare buffer with index = value // used to draw all istances identityInstancesMap.clear(); for (GLuint i = 0; i < num_balls; i++) identityInstancesMap.push_back(i); glBindTexture(GL_TEXTURE_1D, tex_sortedVisibleIDsBuffer->getHandle()); glTexImage1D(GL_TEXTURE_1D, 0, GL_R32UI, num_balls, 0, GL_RED_INTEGER, GL_UNSIGNED_INT, &identityInstancesMap[0]); // map to set all instances visible mapAllVisible.resize(num_balls); std::fill(mapAllVisible.begin(), mapAllVisible.end(), 1); // time query GLuint timeQuery; glGenQueries(1, &timeQuery); glEnable(GL_DEPTH_TEST); }
void Application::update(float time, float timeSinceLastFrame) { if (m_w_pressed) m_camera.Move(CameraDirection::FORWARD); if (m_s_pressed) m_camera.Move(CameraDirection::BACK); if (m_a_pressed) m_camera.Move(CameraDirection::LEFT); if (m_d_pressed) m_camera.Move(CameraDirection::RIGHT); if (m_q_pressed) m_camera.Move(CameraDirection::UP); if (m_e_pressed) m_camera.Move(CameraDirection::DOWN); // Updating the camera matrices m_camera.Update(); m_camera.GetMatricies(m_projmat, m_viewmat, m_worldmat); m_inv_viewmat = glm::inverse(m_viewmat); glBindBufferBase(GL_UNIFORM_BUFFER, 0, m_transformation_buffer); glm::mat4* transform_matrices = (glm::mat4*)glMapBufferRange(GL_UNIFORM_BUFFER, 0, 4 * sizeof(glm::mat4), GL_MAP_WRITE_BIT); transform_matrices[0] = m_projmat; transform_matrices[1] = m_viewmat; transform_matrices[2] = m_worldmat; transform_matrices[3] = m_projmat * m_viewmat * m_worldmat; glUnmapBuffer(GL_UNIFORM_BUFFER); glMatrixMode(GL_MODELVIEW); glLoadMatrixf((float*)&(m_viewmat)); //glLoadMatrixf((float*)&m_viewmat); glMatrixMode(GL_PROJECTION); glLoadMatrixf((float*)&(m_projmat)); //glLoadMatrixf((float*)&m_projmat); // updating the lighting info glBindBufferBase(GL_UNIFORM_BUFFER, 1, m_lighting_buffer); glm::vec4* light_info = (glm::vec4*)glMapBufferRange(GL_UNIFORM_BUFFER, 0, 2 * sizeof(glm::vec4), GL_MAP_WRITE_BIT); light_info[0] = glm::vec4(-1, -1, -1, 0); light_info[1] = glm::vec4(m_camera.getPosition(), 1.0f); glUnmapBuffer(GL_UNIFORM_BUFFER); // Buffer 2 is reserved for the sample points of the Ambient Occlusion Rendering // updating the general information for every object glBindBufferBase(GL_UNIFORM_BUFFER, 3, m_general_buffer); glm::vec4* general_info = (glm::vec4*)glMapBufferRange(GL_UNIFORM_BUFFER, 0, 2 * sizeof(glm::vec4), GL_MAP_WRITE_BIT); glUnmapBuffer(GL_UNIFORM_BUFFER); #ifdef UPDATE_PARTICLES for (size_t i = 0; i < points.size(); i++) { points[i].x += 0.5f * ((rand() % 1000) / 1000.0f - 0.5f); points[i].y += 0.5f * ((rand() % 1000) / 1000.0f - 0.5f); points[i].z += 0.5f * ((rand() % 1000) / 1000.0f - 0.5f); } // glPointSize(10); glBindBuffer(GL_ARRAY_BUFFER, point_buffer); glBufferSubData(GL_ARRAY_BUFFER, 0, points.size() * sizeof(glm::vec4), points.data()); #endif }
void Font_Print(float x, float y, char *string, ...) { // float pointer for VBO mappings (both vertex and instance data) float *verts=NULL; // pointer and buffer for formatted text char *ptr, text[4096]; // variable arguments list va_list ap; // some misc variables int sx=(int)x, numchar, i; // current text color float r=1.0f, g=1.0f, b=1.0f; // Check if the string is even valid first if(string==NULL) return; // Format string, including variable arguments va_start(ap, string); vsprintf(text, string, ap); va_end(ap); // Find how many characters were need to deal with numchar=strlen(text); // Generate texture, shaders, etc once if(Font_Init) { GLuint Vertex, Fragment; GLint Status; // Upload font texture data, single 8bit red, no longer have alpha texture support :( glGenTextures(1, &Font_Texture); glBindTexture(GL_TEXTURE_2D, Font_Texture); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexImage2D(GL_TEXTURE_2D, 0, GL_R8, 256, 256, 0, GL_RED, GL_UNSIGNED_BYTE, _FontData); // Load and compile GLSL shaders, get uniform locations Font_Shader=glCreateProgram(); Vertex=glCreateShader(GL_VERTEX_SHADER); glShaderSource(Vertex, 1, (const char **)&VertexSrc, NULL); glCompileShader(Vertex); glGetShaderiv(Vertex, GL_COMPILE_STATUS, &Status); if(Status) glAttachShader(Font_Shader, Vertex); glDeleteShader(Vertex); Fragment=glCreateShader(GL_FRAGMENT_SHADER); glShaderSource(Fragment, 1, (const char **)&FragmentSrc, NULL); glCompileShader(Fragment); glGetShaderiv(Fragment, GL_COMPILE_STATUS, &Status); if(Status) glAttachShader(Font_Shader, Fragment); glDeleteShader(Fragment); glLinkProgram(Font_Shader); glGetProgramiv(Font_Shader, GL_LINK_STATUS, &Status); if(!Status) return; glUseProgram(Font_Shader); Font_Shader_Texture=glGetUniformLocation(Font_Shader, "Texture"); Font_Shader_Viewport=glGetUniformLocation(Font_Shader, "Viewport"); // Build triangle strip for the font quad // 4 floats per vertex, 4 vertices glGenBuffers(1, &Font_VBO); glBindBuffer(GL_ARRAY_BUFFER, Font_VBO); glBufferData(GL_ARRAY_BUFFER, sizeof(float)*4*4, NULL, GL_STATIC_DRAW); // Map the buffer to avoid system memory transfers verts=(float *)glMapBuffer(GL_ARRAY_BUFFER, GL_WRITE_ONLY); if(verts==NULL) return; // Since this is only 2D data, just using a single attrib with 4 floats is enough *verts++=4.0f; // X *verts++=16.0f; // Y *verts++=0.0125f; // U *verts++=0.0f; // V *verts++=4.0f; *verts++=0.0f; *verts++=0.0125f; *verts++=-0.0625f; *verts++=12.0f; *verts++=16.0f; *verts++=0.05f; *verts++=0.0f; *verts++=12.0f; *verts++=0.0f; *verts++=0.05f; *verts++=-0.0625f; // Unmap buffer glUnmapBuffer(GL_ARRAY_BUFFER); // Allocate buffer for instance data glGenBuffers(1, &Font_Instanced); glBindBuffer(GL_ARRAY_BUFFER, Font_Instanced); glBufferData(GL_ARRAY_BUFFER, sizeof(float)*7*numchar, NULL, GL_DYNAMIC_DRAW); // Done with init Font_Init=0; } // Update instance data glBindBuffer(GL_ARRAY_BUFFER, Font_Instanced); glBufferData(GL_ARRAY_BUFFER, sizeof(float)*7*numchar, NULL, GL_DYNAMIC_DRAW); verts=(float *)glMapBuffer(GL_ARRAY_BUFFER, GL_WRITE_ONLY); if(verts==NULL) return; // Loop through the text string until EOL for(ptr=text, i=0;*ptr!='\0';ptr++) { // Decrement 'y' for any CR's if(*ptr=='\n') { x=(float)sx; y-=12; continue; } // Just advance spaces instead of rendering empty quads if(*ptr==' ') { x+=8; numchar--; continue; } // ANSI color escape codes // I'm sure there's a better way to do this! // But it works, so whatever. if(*ptr=='\x1B') { ptr++; if(*(ptr+0)=='['&&*(ptr+1)=='3'&&*(ptr+2)=='0'&&*(ptr+3)=='m') { r=0.0f; g=0.0f; b=0.0f; } // BLACK else if(*(ptr+0)=='['&&*(ptr+1)=='3'&&*(ptr+2)=='1'&&*(ptr+3)=='m') { r=0.5f; g=0.0f; b=0.0f; } // DARK RED else if(*(ptr+0)=='['&&*(ptr+1)=='3'&&*(ptr+2)=='2'&&*(ptr+3)=='m') { r=0.0f; g=0.5f; b=0.0f; } // DARK GREEN else if(*(ptr+0)=='['&&*(ptr+1)=='3'&&*(ptr+2)=='3'&&*(ptr+3)=='m') { r=0.5f; g=0.5f; b=0.0f; } // DARK YELLOW else if(*(ptr+0)=='['&&*(ptr+1)=='3'&&*(ptr+2)=='4'&&*(ptr+3)=='m') { r=0.0f; g=0.0f; b=0.5f; } // DARK BLUE else if(*(ptr+0)=='['&&*(ptr+1)=='3'&&*(ptr+2)=='5'&&*(ptr+3)=='m') { r=0.5f; g=0.0f; b=0.5f; } // DARK MAGENTA else if(*(ptr+0)=='['&&*(ptr+1)=='3'&&*(ptr+2)=='6'&&*(ptr+3)=='m') { r=0.0f; g=0.5f; b=0.5f; } // DARK CYAN else if(*(ptr+0)=='['&&*(ptr+1)=='3'&&*(ptr+2)=='7'&&*(ptr+3)=='m') { r=0.5f; g=0.5f; b=0.5f; } // GREY else if(*(ptr+0)=='['&&*(ptr+1)=='9'&&*(ptr+2)=='0'&&*(ptr+3)=='m') { r=0.5f; g=0.5f; b=0.5f; } // GREY else if(*(ptr+0)=='['&&*(ptr+1)=='9'&&*(ptr+2)=='1'&&*(ptr+3)=='m') { r=1.0f; g=0.0f; b=0.0f; } // RED else if(*(ptr+0)=='['&&*(ptr+1)=='9'&&*(ptr+2)=='2'&&*(ptr+3)=='m') { r=0.0f; g=1.0f; b=0.0f; } // GREEN else if(*(ptr+0)=='['&&*(ptr+1)=='9'&&*(ptr+2)=='3'&&*(ptr+3)=='m') { r=1.0f; g=1.0f; b=0.0f; } // YELLOW else if(*(ptr+0)=='['&&*(ptr+1)=='9'&&*(ptr+2)=='4'&&*(ptr+3)=='m') { r=0.0f; g=0.0f; b=1.0f; } // BLUE else if(*(ptr+0)=='['&&*(ptr+1)=='9'&&*(ptr+2)=='5'&&*(ptr+3)=='m') { r=1.0f; g=0.0f; b=1.0f; } // MAGENTA else if(*(ptr+0)=='['&&*(ptr+1)=='9'&&*(ptr+2)=='6'&&*(ptr+3)=='m') { r=0.0f; g=1.0f; b=1.0f; } // CYAN else if(*(ptr+0)=='['&&*(ptr+1)=='9'&&*(ptr+2)=='7'&&*(ptr+3)=='m') { r=1.0f; g=1.0f; b=1.0f; } // WHITE ptr+=4; } // Emit position, atlas offset, and color for this character *verts++=x; *verts++=y; *verts++= (float)(*ptr%16)*0.0625f; *verts++=1.0f-(float)(*ptr/16)*0.0625f; *verts++=r; *verts++=g; *verts++=b; // Advance one character x+=8; } // Unmap instance data buffer glUnmapBuffer(GL_ARRAY_BUFFER); // Set program and uniforms glUseProgram(Font_Shader); glUniform1i(Font_Shader_Texture, 0); glUniform2i(Font_Shader_Viewport, Width, Height); // Bind texture glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D, Font_Texture); // Bind quad VBO glBindBuffer(GL_ARRAY_BUFFER, Font_VBO); glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, 0, (void *)0); glEnableVertexAttribArray(0); // Bind/set instance data glBindBuffer(GL_ARRAY_BUFFER, Font_Instanced); glVertexAttribPointer(1, 4, GL_FLOAT, GL_FALSE, sizeof(float)*7, (char *)0); glVertexAttribDivisor(1, 1); glEnableVertexAttribArray(1); glVertexAttribPointer(2, 3, GL_FLOAT, GL_FALSE, sizeof(float)*7, (char *)(0+sizeof(float)*4)); glVertexAttribDivisor(2, 1); glEnableVertexAttribArray(2); // Draw characters! glDrawArraysInstanced(GL_TRIANGLE_STRIP, 0, 4, numchar); // Unset glDisableVertexAttribArray(0); glDisableVertexAttribArray(1); glVertexAttribDivisor(1, 0); glVertexAttribDivisor(2, 0); }
bool OpenGLSWFrameBuffer::Wiper_Burn::Run(int ticks, OpenGLSWFrameBuffer *fb) { bool done; BurnTime += ticks; ticks *= 2; // Make the fire burn done = false; while (!done && ticks--) { Density = wipe_CalcBurn(BurnArray, WIDTH, HEIGHT, Density); done = (Density < 0); } // Update the burn texture with the new burn data if (BurnTexture->Buffers[0] == 0) { glGenBuffers(2, (GLuint*)BurnTexture->Buffers); glBindBuffer(GL_PIXEL_UNPACK_BUFFER, BurnTexture->Buffers[0]); glBufferData(GL_PIXEL_UNPACK_BUFFER, WIDTH * HEIGHT, nullptr, GL_STREAM_DRAW); glBindBuffer(GL_PIXEL_UNPACK_BUFFER, BurnTexture->Buffers[1]); glBufferData(GL_PIXEL_UNPACK_BUFFER, WIDTH * HEIGHT, nullptr, GL_STREAM_DRAW); } else { glBindBuffer(GL_PIXEL_UNPACK_BUFFER, BurnTexture->Buffers[BurnTexture->CurrentBuffer]); BurnTexture->CurrentBuffer = (BurnTexture->CurrentBuffer + 1) & 1; } uint8_t *dest = (uint8_t*)glMapBufferRange(GL_PIXEL_UNPACK_BUFFER, 0, WIDTH * HEIGHT, GL_MAP_WRITE_BIT | GL_MAP_INVALIDATE_RANGE_BIT | GL_MAP_INVALIDATE_BUFFER_BIT); if (dest) { memcpy(dest, BurnArray, WIDTH * HEIGHT); glUnmapBuffer(GL_PIXEL_UNPACK_BUFFER); GLint oldBinding = 0; glGetIntegerv(GL_TEXTURE_BINDING_2D, &oldBinding); glBindTexture(GL_TEXTURE_2D, BurnTexture->Texture); glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, WIDTH, HEIGHT, GL_RED, GL_UNSIGNED_BYTE, 0); glBindTexture(GL_TEXTURE_2D, oldBinding); glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0); } // Put the initial screen back to the buffer. DrawScreen(fb, fb->InitialWipeScreen); // Burn the new screen on top of it. float right = float(fb->Width); float bot = float(fb->Height); BURNVERTEX verts[4] = { { 0.f, 0.f, 0.f, 1.f, 0.f, 0.f, 0, 0 }, { right, 0.f, 0.f, 1.f, 1.f, 0.f, 1, 0 }, { right, bot, 0.f, 1.f, 1.f, 1.f, 1, 1 }, { 0.f, bot, 0.f, 1.f, 0.f, 1.f, 0, 1 } }; fb->SetTexture(0, fb->FinalWipeScreen); fb->SetTexture(1, BurnTexture); fb->SetAlphaBlend(GL_FUNC_ADD, GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); fb->SetPixelShader(fb->Shaders[SHADER_BurnWipe]); glActiveTexture(GL_TEXTURE1); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); fb->DrawTriangleFans(2, verts); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glActiveTexture(GL_TEXTURE0); // The fire may not always stabilize, so the wipe is forced to end // after an arbitrary maximum time. return done || (BurnTime > 40); }
static void EncodeToRamUsingShader(GLuint srcTexture, u8* destAddr, int dstWidth, int dstHeight, int readStride, bool linearFilter) { // switch to texture converter frame buffer // attach render buffer as color destination FramebufferManager::SetFramebuffer(s_texConvFrameBuffer[0]); OpenGL_BindAttributelessVAO(); // set source texture glActiveTexture(GL_TEXTURE0+9); glBindTexture(GL_TEXTURE_2D_ARRAY, srcTexture); if (linearFilter) { glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MIN_FILTER, GL_LINEAR); } else { glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MIN_FILTER, GL_NEAREST); } glViewport(0, 0, (GLsizei)dstWidth, (GLsizei)dstHeight); glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); // .. and then read back the results. // TODO: make this less slow. int writeStride = bpmem.copyMipMapStrideChannels * 32; int dstSize = dstWidth*dstHeight*4; int readHeight = readStride / dstWidth / 4; // 4 bytes per pixel int readLoops = dstHeight / readHeight; if (writeStride != readStride && readLoops > 1) { // writing to a texture of a different size // also copy more then one block line, so the different strides matters // copy into one pbo first, map this buffer, and then memcpy into GC memory // in this way, we only have one vram->ram transfer, but maybe a bigger // CPU overhead because of the pbo glBindBuffer(GL_PIXEL_PACK_BUFFER, s_PBO); glBufferData(GL_PIXEL_PACK_BUFFER, dstSize, nullptr, GL_STREAM_READ); glReadPixels(0, 0, (GLsizei)dstWidth, (GLsizei)dstHeight, GL_BGRA, GL_UNSIGNED_BYTE, nullptr); u8* pbo = (u8*)glMapBufferRange(GL_PIXEL_PACK_BUFFER, 0, dstSize, GL_MAP_READ_BIT); for (int i = 0; i < readLoops; i++) { memcpy(destAddr, pbo, readStride); pbo += readStride; destAddr += writeStride; } glUnmapBuffer(GL_PIXEL_PACK_BUFFER); glBindBuffer(GL_PIXEL_PACK_BUFFER, 0); } else { glReadPixels(0, 0, (GLsizei)dstWidth, (GLsizei)dstHeight, GL_BGRA, GL_UNSIGNED_BYTE, destAddr); } }
void startup(void) { int i, j; load_shaders(); vmath::vec4 * initial_positions = new vmath::vec4 [POINTS_TOTAL]; vmath::vec3 * initial_velocities = new vmath::vec3 [POINTS_TOTAL]; vmath::ivec4 * connection_vectors = new vmath::ivec4 [POINTS_TOTAL]; int n = 0; for (j = 0; j < POINTS_Y; j++) { float fj = (float)j / (float)POINTS_Y; for (i = 0; i < POINTS_X; i++) { float fi = (float)i / (float)POINTS_X; initial_positions[n] = vmath::vec4((fi - 0.5f) * (float)POINTS_X, (fj - 0.5f) * (float)POINTS_Y, 0.6f * sinf(fi) * cosf(fj), 1.0f); initial_velocities[n] = vmath::vec3(0.0f); connection_vectors[n] = vmath::ivec4(-1); if (j != (POINTS_Y - 1)) { if (i != 0) connection_vectors[n][0] = n - 1; if (j != 0) connection_vectors[n][1] = n - POINTS_X; if (i != (POINTS_X - 1)) connection_vectors[n][2] = n + 1; if (j != (POINTS_Y - 1)) connection_vectors[n][3] = n + POINTS_X; } n++; } } glGenVertexArrays(2, m_vao); glGenBuffers(5, m_vbo); for (i = 0; i < 2; i++) { glBindVertexArray(m_vao[i]); glBindBuffer(GL_ARRAY_BUFFER, m_vbo[POSITION_A + i]); glBufferData(GL_ARRAY_BUFFER, POINTS_TOTAL * sizeof(vmath::vec4), initial_positions, GL_DYNAMIC_COPY); glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, 0, NULL); glEnableVertexAttribArray(0); glBindBuffer(GL_ARRAY_BUFFER, m_vbo[VELOCITY_A + i]); glBufferData(GL_ARRAY_BUFFER, POINTS_TOTAL * sizeof(vmath::vec3), initial_velocities, GL_DYNAMIC_COPY); glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 0, NULL); glEnableVertexAttribArray(1); glBindBuffer(GL_ARRAY_BUFFER, m_vbo[CONNECTION]); glBufferData(GL_ARRAY_BUFFER, POINTS_TOTAL * sizeof(vmath::ivec4), connection_vectors, GL_STATIC_DRAW); glVertexAttribIPointer(2, 4, GL_INT, 0, NULL); glEnableVertexAttribArray(2); } delete [] connection_vectors; delete [] initial_velocities; delete [] initial_positions; glGenTextures(2, m_pos_tbo); glBindTexture(GL_TEXTURE_BUFFER, m_pos_tbo[0]); glTexBuffer(GL_TEXTURE_BUFFER, GL_RGBA32F, m_vbo[POSITION_A]); glBindTexture(GL_TEXTURE_BUFFER, m_pos_tbo[1]); glTexBuffer(GL_TEXTURE_BUFFER, GL_RGBA32F, m_vbo[POSITION_B]); int lines = (POINTS_X - 1) * POINTS_Y + (POINTS_Y - 1) * POINTS_X; glGenBuffers(1, &m_index_buffer); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_index_buffer); glBufferData(GL_ELEMENT_ARRAY_BUFFER, lines * 2 * sizeof(int), NULL, GL_STATIC_DRAW); int * e = (int *)glMapBufferRange(GL_ELEMENT_ARRAY_BUFFER, 0, lines * 2 * sizeof(int), GL_MAP_WRITE_BIT | GL_MAP_INVALIDATE_BUFFER_BIT); for (j = 0; j < POINTS_Y; j++) { for (i = 0; i < POINTS_X - 1; i++) { *e++ = i + j * POINTS_X; *e++ = 1 + i + j * POINTS_X; } } for (i = 0; i < POINTS_X; i++) { for (j = 0; j < POINTS_Y - 1; j++) { *e++ = i + j * POINTS_X; *e++ = POINTS_X + i + j * POINTS_X; } } glUnmapBuffer(GL_ELEMENT_ARRAY_BUFFER); }
void OGLTexture1D::Unmap1D(uint32_t array_index, uint32_t level) { OGLRenderEngine& re = *checked_cast<OGLRenderEngine*>(&Context::Instance().RenderFactoryInstance().RenderEngineInstance()); switch (last_tma_) { case TMA_Read_Only: re.BindBuffer(GL_PIXEL_UNPACK_BUFFER, 0); re.BindBuffer(GL_PIXEL_PACK_BUFFER, pbos_[array_index * num_mip_maps_ + level]); glUnmapBuffer(GL_PIXEL_PACK_BUFFER); break; case TMA_Write_Only: case TMA_Read_Write: { GLint gl_internalFormat; GLenum gl_format; GLenum gl_type; OGLMapping::MappingFormat(gl_internalFormat, gl_format, gl_type, format_); uint32_t const w = this->Width(level); re.BindTexture(0, target_type_, texture_); re.BindBuffer(GL_PIXEL_PACK_BUFFER, 0); re.BindBuffer(GL_PIXEL_UNPACK_BUFFER, pbos_[array_index * num_mip_maps_ + level]); glUnmapBuffer(GL_PIXEL_UNPACK_BUFFER); if (IsCompressedFormat(format_)) { uint32_t const block_size = NumFormatBytes(format_) * 4; GLsizei const image_size = ((w + 3) / 4) * block_size; if (array_size_ > 1) { glCompressedTexSubImage2D(target_type_, level, 0, array_index, w, 1, gl_format, image_size, nullptr); } else { glCompressedTexSubImage1D(target_type_, level, 0, w, gl_format, image_size, nullptr); } } else { if (array_size_ > 1) { glTexSubImage2D(target_type_, level, 0, array_index, w, 1, gl_format, gl_type, nullptr); } else { glTexSubImage1D(target_type_, level, 0, w, gl_format, gl_type, nullptr); } } } break; default: BOOST_ASSERT(false); break; } }
enum piglit_result test_bitmap(void *null) { GLuint pb_unpack[1]; GLuint pb_pack[1]; int use_unpack = 1; int use_pack = 0; GLubyte bitmap[TEXSIZE * TEXSIZE / 8]; GLfloat buf[WINSIZE * WINSIZE * 3]; GLfloat white[3] = { 1.0, 1.0, 1.0 }; GLfloat black[3] = { 0.0, 0.0, 0.0 }; int i, j; GLubyte *pbo_unpack_mem = NULL; GLfloat *pbo_pack_mem = NULL; GLfloat expected[WINSIZE * WINSIZE * 3]; float tolerance[4]; bool pass = true; glBindBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB, 0); glBindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, 0); for (use_pack = 0; use_pack < 2; use_pack++) { for (use_unpack = 0; use_unpack < 2; use_unpack++) { glClearColor(0.0, 0.0, 0.0, 1.0); glClear(GL_COLOR_BUFFER_BIT); if (use_unpack) { glGenBuffersARB(1, pb_unpack); glBindBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB, pb_unpack[0]); glBufferDataARB(GL_PIXEL_UNPACK_BUFFER_ARB, TEXSIZE * TEXSIZE, NULL, GL_STREAM_DRAW); pbo_unpack_mem = (GLubyte *) glMapBufferARB( GL_PIXEL_UNPACK_BUFFER_ARB, GL_WRITE_ONLY); } else { pbo_unpack_mem = bitmap; } for (i = 0; i < TEXSIZE * TEXSIZE / 8; i++) { pbo_unpack_mem[i] = 0xAA; /* Binary 10101010 */ } glColor4f(1.0, 1.0, 1.0, 0.0); glRasterPos2f(0.0, 0.0); if (use_unpack) { glUnmapBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB); /* Draw white into every other pixel, * for a white/black checkerboard. */ glBitmap(TEXSIZE, TEXSIZE, 0, 0, 0, 0, NULL); glBindBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB, 0); } else { glBitmap(TEXSIZE, TEXSIZE, 0, 0, 0, 0, pbo_unpack_mem); } if (!piglit_automatic) piglit_present_results(); /* Check the result */ if (use_pack) { glGenBuffersARB(1, pb_pack); glBindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, pb_pack[0]); glBufferDataARB(GL_PIXEL_PACK_BUFFER_ARB, WINSIZE * WINSIZE * 4 * sizeof(GLfloat), NULL, GL_STREAM_DRAW); glReadPixels(0, 0, WINSIZE, WINSIZE, GL_RGB, GL_FLOAT, NULL); pbo_pack_mem = (GLfloat *) glMapBufferARB( GL_PIXEL_PACK_BUFFER_ARB, GL_READ_ONLY); } else { pbo_pack_mem = buf; glReadPixels(0, 0, WINSIZE, WINSIZE, GL_RGB, GL_FLOAT, pbo_pack_mem); } /* Compute expected and compare it to the result. */ for (j = 0; j < WINSIZE; j++) { for (i = 0; i < WINSIZE; i++) { int idx = (j * WINSIZE + i) * 3; if ((i & 1) || (i >= TEXSIZE) || (j >= TEXSIZE)) { expected[idx + 0] = black[0]; expected[idx + 1] = black[1]; expected[idx + 2] = black[2]; } else { expected[idx + 0] = white[0]; expected[idx + 1] = white[1]; expected[idx + 2] = white[2]; } } } piglit_compute_probe_tolerance(GL_RGB, &tolerance[0]); pass &= piglit_compare_images_color(0, 0, WINSIZE, WINSIZE, 3, tolerance, expected, pbo_pack_mem); if (use_pack) { glUnmapBuffer(GL_PIXEL_PACK_BUFFER_ARB); glBindBuffer(GL_PIXEL_PACK_BUFFER_ARB, 0); glDeleteBuffersARB(1, pb_pack); } if (use_unpack) { glBindBuffer(GL_PIXEL_UNPACK_BUFFER_ARB, 0); glDeleteBuffersARB(1, pb_unpack); } } } return pass ? PIGLIT_PASS : PIGLIT_FAIL; }
~BufferStorage() { DeleteFences(); glUnmapBuffer(m_buffertype); glBindBuffer(m_buffertype, 0); }
static void testBufferStorage(void) { if (!GLAD_GL_VERSION_4_4 && !glfwExtensionSupported("GL_ARB_buffer_storage")) { fprintf(stderr, "error: GL_ARB_buffer_storage not supported\n"); glfwTerminate(); exit(EXIT_SKIP); } GLbitfield map_trace_explicit_bit = 0; if (glfwExtensionSupported("GL_VMWX_map_buffer_debug")) { glNotifyMappedBufferRangeVMWX = (PFNGLNOTIFYMAPPEDBUFFERRANGEVMWXPROC)glfwGetProcAddress("glNotifyMappedBufferRangeVMWX"); assert(glNotifyMappedBufferRangeVMWX); map_trace_explicit_bit = GL_MAP_NOTIFY_EXPLICIT_BIT_VMWX; } GLuint buffer = 0; glGenBuffers(1, &buffer); glBindBuffer(target, buffer); GLsizeiptr size = 1000; void *data = malloc(size); memset(data, 0, size); while ((glGetError() != GL_NO_ERROR)) ; glBufferStorage(target, size, data, GL_MAP_WRITE_BIT | GL_MAP_PERSISTENT_BIT | GL_MAP_COHERENT_BIT | map_trace_explicit_bit); free(data); GLenum error = glGetError(); switch (error) { case GL_NO_ERROR: break; case GL_OUT_OF_MEMORY: exit(EXIT_SKIP); default: exit(EXIT_FAILURE); } GLubyte *map; // straightforward mapping map = (GLubyte *)glMapBufferRange(target, 100, 100, GL_MAP_WRITE_BIT); memset(map, 1, 100); glUnmapBuffer(target); // persistent mapping w/ explicit flush map = (GLubyte *)glMapBufferRange(target, 200, 300, GL_MAP_WRITE_BIT | GL_MAP_PERSISTENT_BIT | GL_MAP_FLUSH_EXPLICIT_BIT); memset(map + 20, 2, 30); glFlushMappedBufferRange(target, 20, 30); memset(map + 50, 3, 50); glFlushMappedBufferRange(target, 50, 50); glUnmapBuffer(target); // persistent & coherent mapping map = (GLubyte *)glMapBufferRange(target, 500, 100, GL_MAP_WRITE_BIT | GL_MAP_PERSISTENT_BIT | GL_MAP_COHERENT_BIT | map_trace_explicit_bit); memset(map + 20, 4, 30); glNotifyMappedBufferRangeVMWX(map + 20, 30); memset(map + 50, 5, 50); glNotifyMappedBufferRangeVMWX(map + 50, 50); glUnmapBuffer(target); glBindBuffer(target, 0); glDeleteBuffers(1, &buffer); }
void unmap() const { assert( id > 0 ); $glUnmapBuffer( GL_ARRAY_BUFFER ); }
bool CGutModel_OpenGL::ConvertToOpenGLModel(CGutModel *pModel) { if ( pModel->m_iNumMeshes==0 ) return false; int i,j,k; m_iNumMaterials = pModel->m_iNumMaterials; char szTextureName[256]; if ( m_iNumMaterials ) { m_pMaterialArray = new sModelMaterial_OpenGL[m_iNumMaterials]; sModelMaterial_OpenGL *target = m_pMaterialArray; sModelMaterial *source = pModel->m_pMaterialArray; for ( i=0; i<m_iNumMaterials; i++, target++, source++ ) { target->m_bCullFace = source->m_bCullFace; target->m_Emissive = source->m_Emissive; target->m_Ambient = source->m_Ambient; target->m_Diffuse = source->m_Diffuse; target->m_Specular = source->m_Specular; target->m_fShininess = source->m_fShininess; if ( !strcmp(source->m_szBlendMode, "replace") ) { target->m_bBlend = false; } else { target->m_bBlend = true; if ( !strcmp(source->m_szBlendMode, "blend") ) { target->m_SrcBlend = GL_SRC_ALPHA; target->m_DestBlend = GL_ONE_MINUS_SRC_ALPHA; } else if ( !strcmp(source->m_szBlendMode, "subtrace") ) { target->m_SrcBlend = GL_ONE; target->m_DestBlend = GL_ONE; } else if ( !strcmp(source->m_szBlendMode, "add") ) { target->m_SrcBlend = GL_ONE; target->m_DestBlend = GL_ONE; } else { target->m_SrcBlend = GL_ONE; target->m_DestBlend = GL_ZERO; target->m_bBlend = false; } } for ( j=0; j<MAX_NUM_TEXTURES; j++ ) { if ( source->m_szTexture[j][0] ) { sprintf(szTextureName, "%s%s", CGutModel::GetTexturePath(), source->m_szTexture[j]); target->m_Textures[j] = GutLoadTexture_OpenGL(szTextureName); } else { target->m_Textures[j] = 0; } target->m_MapChannel[j] = source->m_MapChannel[j]; } } } m_iNumMeshes = pModel->m_iNumMeshes; m_pMeshArray = new sModelMesh_OpenGL[m_iNumMeshes]; void *vbuffer_pointer, *ibuffer_pointer; for ( i=0; i<m_iNumMeshes; i++ ) { sModelMesh *pMeshSource = pModel->m_pMeshArray + i; sModelMesh_OpenGL *pMesh = m_pMeshArray + i; pMesh->m_iNumVertexChunks = pMeshSource->m_iNumVertexChunks; pMesh->m_pVertexChunk = new sModelVertexChunk_OpenGL[pMesh->m_iNumVertexChunks]; for ( j=0; j<pMesh->m_iNumVertexChunks; j++ ) { sModelVertexChunk *pVertexChunkTarget = &pMeshSource->m_pVertexChunks[j]; sModelVertexChunk_OpenGL *pVertexChunk = pMesh->m_pVertexChunk + j; pVertexChunk->m_VertexDecl = pVertexChunkTarget->m_VertexDecl; pVertexChunk->m_iNumVertices = pVertexChunkTarget->m_iNumVertices; int vbuffer_size = pVertexChunk->m_iNumVertices * pVertexChunk->m_VertexDecl.m_iVertexSize; // allocate opengl vertex buffer object glGenBuffers(1, &pVertexChunk->m_VertexBufferID); glBindBuffer(GL_ARRAY_BUFFER, pVertexChunk->m_VertexBufferID); glBufferData(GL_ARRAY_BUFFER, vbuffer_size, NULL, GL_STATIC_COPY); vbuffer_pointer = glMapBuffer(GL_ARRAY_BUFFER, GL_WRITE_ONLY); pVertexChunkTarget->OutputVertexBuffer(vbuffer_pointer); glUnmapBuffer(GL_ARRAY_BUFFER); pVertexChunk->m_iNumIndices = pVertexChunkTarget->m_iNumIndices; int ibuffer_size = pVertexChunk->m_iNumIndices * 2; // allocate opengl index buffer object glGenBuffers(1, &pVertexChunk->m_IndexBufferID); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, pVertexChunk->m_IndexBufferID); glBufferData(GL_ELEMENT_ARRAY_BUFFER, ibuffer_size, NULL, GL_STATIC_COPY); ibuffer_pointer = glMapBuffer(GL_ELEMENT_ARRAY_BUFFER, GL_WRITE_ONLY); memcpy(ibuffer_pointer, pVertexChunkTarget->m_pIndexArray, ibuffer_size); glUnmapBuffer(GL_ELEMENT_ARRAY_BUFFER); pVertexChunk->m_iNumBatches = pVertexChunkTarget->m_iNumBatches; if ( pVertexChunk->m_iNumBatches ) { pVertexChunk->m_pBatchArray = new sModelBatch[pVertexChunk->m_iNumBatches]; memcpy(pVertexChunk->m_pBatchArray, pVertexChunkTarget->m_pBatchArray, sizeof(sModelBatch) * pVertexChunk->m_iNumBatches); } } } glBindBuffer(GL_ARRAY_BUFFER, 0); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); }
void AtlasManager::updateAtlas(BUFFER_INDEX bufferIndex, std::vector<int>& brickIndices) { int nBrickIndices = brickIndices.size(); _requiredBricks.clear(); for (int i = 0; i < nBrickIndices; i++) { _requiredBricks.insert(brickIndices[i]); } for (unsigned int it : _prevRequiredBricks) { if (!_requiredBricks.count(it)) { removeFromAtlas(it); } } // Stats _nUsedBricks = _requiredBricks.size(); _nStreamedBricks = 0; _nDiskReads = 0; glBindBuffer(GL_PIXEL_UNPACK_BUFFER, _pboHandle[bufferIndex]); glBufferData(GL_PIXEL_UNPACK_BUFFER, _volumeSize, 0, GL_STREAM_DRAW); float* mappedBuffer = reinterpret_cast<float*>(glMapBuffer(GL_PIXEL_UNPACK_BUFFER, GL_WRITE_ONLY)); if (!mappedBuffer) { LERROR("Failed to map PBO"); std::cout << glGetError() << std::endl; return; } for (auto itStart = _requiredBricks.begin(); itStart != _requiredBricks.end();) { int firstBrick = *itStart; int lastBrick = firstBrick; auto itEnd = itStart; for (itEnd++; itEnd != _requiredBricks.end() && *itEnd == lastBrick + 1; itEnd++) { lastBrick = *itEnd; } addToAtlas(firstBrick, lastBrick, mappedBuffer); itStart = itEnd; } glUnmapBuffer(GL_PIXEL_UNPACK_BUFFER); glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0); for (int i = 0; i < nBrickIndices; i++) { _atlasMap[i] = _brickMap[brickIndices[i]]; } std::swap(_prevRequiredBricks, _requiredBricks); pboToAtlas(bufferIndex); glBindBuffer(GL_SHADER_STORAGE_BUFFER, _atlasMapBuffer); GLint *to = (GLint*)glMapBuffer(GL_SHADER_STORAGE_BUFFER, GL_WRITE_ONLY); memcpy(to, _atlasMap.data(), sizeof(GLint)*_atlasMap.size()); glUnmapBuffer(GL_SHADER_STORAGE_BUFFER); glBindBuffer(GL_SHADER_STORAGE_BUFFER, 0); }
void ImGuiImpl::State::RenderDrawLists(ImDrawList** const cmdLists, int cmdListsCount) { // GL states needed to render ImGui. glEnable(GL_BLEND); glBlendEquation(GL_FUNC_ADD); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glDisable(GL_CULL_FACE); glDisable(GL_DEPTH_TEST); glEnable(GL_SCISSOR_TEST); // Setup texture glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D, fontTextureHandle); // Setup orthographic projection matrix float const width = ImGui::GetIO().DisplaySize.x; float const height = ImGui::GetIO().DisplaySize.y; float const orthoProjection[4][4] = { { 2.0f / width, 0.0f, 0.0f, 0.0f }, { 0.0f, 2.0f / -height, 0.0f, 0.0f }, { 0.0f, 0.0f, -1.0f, 0.0f }, { -1.0f, 1.0f, 0.0f, 1.0f }, }; glUseProgram(shaderHandle); glUniform1i(textureLocation, 0); glUniformMatrix4fv(orthoLocation, 1, GL_FALSE, &orthoProjection[0][0]); // Grow our buffer according to what we need size_t total_vtx_count = 0; for (int n = 0; n < cmdListsCount; n++) total_vtx_count += cmdLists[n]->vtx_buffer.size(); glBindBuffer(GL_ARRAY_BUFFER, vboHandle); size_t neededBufferSize = total_vtx_count * sizeof(ImDrawVert); if (neededBufferSize > vboMaxSize) { vboMaxSize = neededBufferSize + 5000; // Grow buffer glBufferData(GL_ARRAY_BUFFER, vboMaxSize, NULL, GL_STREAM_DRAW); } // Copy and convert all vertices into a single contiguous buffer unsigned char *bufferData = static_cast<unsigned char*>(glMapBuffer( GL_ARRAY_BUFFER, GL_WRITE_ONLY)); if (!bufferData) return; for (int n = 0; n < cmdListsCount; n++) { ImDrawList const *cmd_list = cmdLists[n]; std::memcpy(bufferData, &cmd_list->vtx_buffer[0], cmd_list->vtx_buffer.size() * sizeof(ImDrawVert)); bufferData += cmd_list->vtx_buffer.size() * sizeof(ImDrawVert); } glUnmapBuffer(GL_ARRAY_BUFFER); glBindBuffer(GL_ARRAY_BUFFER, 0); glBindVertexArray(vaoHandle); int cmdOffset = 0; for (int n = 0; n < cmdListsCount; n++) { ImDrawList *cmdList = cmdLists[n]; int vtxOffset = cmdOffset; auto &commands = cmdList->commands; ImDrawCmd *pcmd_end = commands.end(); for (ImDrawCmd const *pcmd = commands.begin(); pcmd != pcmd_end; pcmd++) { glScissor(static_cast<GLint>(pcmd->clip_rect.x), static_cast<GLint>(height - pcmd->clip_rect.w), static_cast<GLint>(pcmd->clip_rect.z - pcmd->clip_rect.x), static_cast<GLint>(pcmd->clip_rect.w - pcmd->clip_rect.y)); glDrawArrays(GL_TRIANGLES, vtxOffset, pcmd->vtx_count); vtxOffset += pcmd->vtx_count; } cmdOffset = vtxOffset; } // Restore modified state glBindVertexArray(0); glUseProgram(0); glDisable(GL_SCISSOR_TEST); glDisable(GL_BLEND); glEnable(GL_DEPTH_TEST); glBindTexture(GL_TEXTURE_2D, 0); }
int main(int argc, char** argv) { GLFWwindow* glfwwindow; {//OpenGL/GLFW Init if (!glfwInit()) { std::cerr << "Error: GLFW init failed" << std::endl; exit(EXIT_FAILURE); } glfwwindow = glfwCreateWindow(200, 200, "Nvidia interop bug demo", nullptr, nullptr); glfwMakeContextCurrent(glfwwindow); glewInit(); std::cout << "OpenGL Info: " << (char*)glGetString(GL_VENDOR) << " " << (char*)glGetString(GL_RENDERER) << std::endl; } cl_context clcontext; cl_command_queue clqueue; {//OpenCL init cl_platform_id platform = nullptr; {//Platform init cl_uint numPlatforms; clGetPlatformIDs(0, nullptr, &numPlatforms); if (numPlatforms == 0) { std::cerr << "Error: No OpenCL platforms available" << std::endl; return EXIT_FAILURE; } cl_platform_id* all_platforms = new cl_platform_id[numPlatforms]; clGetPlatformIDs(numPlatforms, all_platforms, nullptr); for (size_t i = 0; i < numPlatforms; i++) //Select Nvidia out of the platforms { char name[300]; clGetPlatformInfo(all_platforms[i], CL_PLATFORM_NAME, sizeof(name), &name, nullptr); std::string namestring(name); if (namestring.find("NVIDIA") != std::string::npos || namestring.find("Nvidia") != std::string::npos) platform = all_platforms[i]; } if (platform == nullptr) { std::cerr << "No Nvidia OpenCL platform found, will default to platform 0 "; } delete[] all_platforms; } { //Create shared context cl_context_properties properties[7]; properties[0] = CL_CONTEXT_PLATFORM; //This is different for other operating systems than Windows properties[1] = (cl_context_properties)platform; properties[2] = CL_GL_CONTEXT_KHR; properties[3] = (cl_context_properties)wglGetCurrentContext(); properties[4] = CL_WGL_HDC_KHR; properties[5] = (cl_context_properties)wglGetCurrentDC(); properties[6] = 0; clcontext = clCreateContextFromType(properties, CL_DEVICE_TYPE_GPU, nullptr, nullptr, nullptr); } cl_device_id cldevice; { //Create cldevice cl_device_id* devices; cl_command_queue commandQueue = nullptr; size_t numDevices = 0; // First get the size of the devices buffer clGetContextInfo(clcontext, CL_CONTEXT_DEVICES, 0, nullptr, &numDevices); if (numDevices == 0) { std::cerr << "Error: No OpenCL devices available" << std::endl; return EXIT_FAILURE; } devices = new cl_device_id[numDevices]; clGetContextInfo(clcontext, CL_CONTEXT_DEVICES, numDevices, devices, nullptr); cldevice = devices[0]; delete[] devices; } { //Create CL command queue clqueue = clCreateCommandQueue(clcontext, cldevice, 0, nullptr); } char platformname[300]; char devicename[300]; clGetPlatformInfo(platform, CL_PLATFORM_NAME, sizeof(platformname), &platformname, nullptr); clGetDeviceInfo(cldevice, CL_DEVICE_NAME, sizeof(devicename), &devicename, nullptr); std::cout << "OpenCL platform " << platformname << " device " << devicename << std::endl; } size_t size = 200 * 200 * 4; //w=200, h=200, 4 bytes per channel char* databuffer = new char[size]; GLuint glbuffer, gltexture; cl_mem unsharedbuffer, sharedbuffer, unsharedtexture, sharedtexture; { //Init test data glGenBuffers(1, &glbuffer); glBindBuffer(GL_ARRAY_BUFFER, glbuffer); glBufferData(GL_ARRAY_BUFFER, size, databuffer, GL_STREAM_DRAW); glBindBuffer(GL_ARRAY_BUFFER, GL_NONE); glGenTextures(1, &gltexture); glBindTexture(GL_TEXTURE_2D, gltexture); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 200, 200, 0, GL_RGBA, GL_UNSIGNED_BYTE, databuffer); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); //Intel needs this for shared textures glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); //Intel needs this for shared textures glBindTexture(GL_TEXTURE_2D, GL_NONE); sharedtexture = clCreateFromGLTexture(clcontext, CL_MEM_READ_WRITE, GL_TEXTURE_2D, 0, gltexture, nullptr); sharedbuffer = clCreateFromGLBuffer(clcontext, CL_MEM_READ_WRITE, glbuffer, nullptr); unsharedbuffer = clCreateBuffer(clcontext, CL_MEM_READ_WRITE | CL_MEM_COPY_HOST_PTR, size, databuffer, nullptr); cl_image_format imgformat; cl_image_desc desc; imgformat.image_channel_data_type = CL_UNSIGNED_INT8; imgformat.image_channel_order = CL_RGBA; desc.image_type = CL_MEM_OBJECT_IMAGE2D; desc.image_width = 200; desc.image_height = 200; desc.image_depth = 1; desc.image_array_size = 1; desc.image_row_pitch = 0; desc.image_slice_pitch = 0; desc.num_mip_levels = 0; desc.num_samples = 0; desc.buffer = nullptr; unsharedtexture = clCreateImage(clcontext, CL_MEM_READ_WRITE | CL_MEM_COPY_HOST_PTR, &imgformat, &desc, databuffer, nullptr); } { const size_t origin[3] = { 0, 0, 0 }; const size_t region[3] = { 200, 200, 1 }; size_t pitch; // //MAIN PART BEGINS HERE // { //OpenGL buffer std::cout << "Mapping buffer with OpenGL: "; glBindBuffer(GL_ARRAY_BUFFER, glbuffer); void* glmapptr = glMapBuffer(GL_ARRAY_BUFFER, GL_MAP_READ_BIT | GL_MAP_WRITE_BIT); glUnmapBuffer(GL_ARRAY_BUFFER); glBindBuffer(GL_ARRAY_BUFFER, GL_NONE); std::cout << "OK" << std::endl; glFinish(); } { //OpenCL unshared texture std::cout << "Mapping unshared texture with OpenCL: "; void* unsimgptr = clEnqueueMapImage(clqueue, unsharedtexture, CL_TRUE, CL_MAP_READ | CL_MAP_WRITE, origin, region, &pitch, nullptr, 0, nullptr, nullptr, nullptr); //This API call works fine for unshared objects clEnqueueUnmapMemObject(clqueue, unsharedtexture, unsimgptr, 0, nullptr, nullptr); std::cout << "OK" << std::endl; } { //OpenCL shared texture std::cout << "Mapping shared texture with OpenCL: "; clEnqueueAcquireGLObjects(clqueue, 1, &sharedtexture, 0, nullptr, nullptr); void* shdimgptr = clEnqueueMapImage(clqueue, unsharedtexture, CL_TRUE, CL_MAP_READ | CL_MAP_WRITE, origin, region, &pitch, nullptr, 0, nullptr, nullptr, nullptr); //This API call works fine shared objects clEnqueueUnmapMemObject(clqueue, unsharedtexture, shdimgptr, 0, nullptr, nullptr); clEnqueueReleaseGLObjects(clqueue, 1, &sharedtexture, 0, nullptr, nullptr); std::cout << "OK" << std::endl; } { //OpenCL unshared buffer std::cout << "Mapping unshared buffer with OpenCL: "; void* unsbufptr = clEnqueueMapBuffer(clqueue, unsharedbuffer, CL_TRUE, CL_MAP_READ | CL_MAP_WRITE, 0, size, 0, nullptr, nullptr, nullptr); //This API call works fine for unshared buffers clEnqueueUnmapMemObject(clqueue, unsharedbuffer, unsbufptr, 0, nullptr, nullptr); std::cout << "OK" << std::endl; } { //OpenCL shared buffer std::cout << "Mapping shared buffer with OpenCL (EXPECTING CRASH ON NVIDIA SYSTEMS): " << std::endl; clEnqueueAcquireGLObjects(clqueue, 1, &sharedbuffer, 0, nullptr, nullptr); // //CRITICAL PART BEGINS HERE // void* shdbufptr = clEnqueueMapBuffer(clqueue, sharedbuffer, CL_TRUE, CL_MAP_READ | CL_MAP_WRITE, 0, size, 0, nullptr, nullptr, nullptr); //On Nvidia systems when using shared objects, error 0xC0000005 occurs in ntdll.dll: write access violation at position 0xSOMETHING //This leaves my application in an unusable state //But it works fine everywhere else (tested on ARM, AMD, Intel systems) // //CRITICAL PART ENDS HERE // std::cout << "did not fail" << std::endl; clEnqueueUnmapMemObject(clqueue, sharedbuffer, shdbufptr, 0, nullptr, nullptr); clEnqueueReleaseGLObjects(clqueue, 1, &sharedbuffer, 0, nullptr, nullptr); std::cout << "OK" << std::endl; } // //MAIN PART ENDS HERE // } clFinish(clqueue); delete[] databuffer; clReleaseMemObject(sharedbuffer); clReleaseMemObject(unsharedbuffer); clReleaseMemObject(sharedtexture); clReleaseMemObject(unsharedtexture); clReleaseCommandQueue(clqueue); clReleaseContext(clcontext); glDeleteTextures(1, &gltexture); glDeleteBuffers(1, &glbuffer); glfwDestroyWindow(glfwwindow); glfwTerminate(); return EXIT_SUCCESS; }
void VBO::releasePtr() const { glBindBuffer(GL_ARRAY_BUFFER, *m_id); glUnmapBuffer(GL_ARRAY_BUFFER); m_lock = false; }
void Mesh::link() { if (isLinked) return; // Build the data buffer size_t numSubmeshes = submeshes.size(); glBindBuffer(GL_ARRAY_BUFFER, dataBuffer); char* bufData = (char*) glMapBuffer(GL_ARRAY_BUFFER, GL_READ_ONLY); char* newData = new char[dataBufferSingleSize * numSubmeshes]; for (uint8_t i = 0 ; i < numSubmeshes ; i++) { memcpy(newData + i*dataBufferSingleSize, bufData, dataBufferSingleSize); if (submeshIDOffs != -1) { for (size_t j = 0 ; j < vertexCount ; j++) { newData[i*dataBufferSingleSize + submeshIDOffs + j*submeshIDStride] = i; } } } glUnmapBuffer(GL_ARRAY_BUFFER); glBufferData(GL_ARRAY_BUFFER, dataBufferSingleSize * numSubmeshes, newData, GL_STATIC_DRAW); delete[] newData; // Build the index buffer if (indexBuffer == 0) glGenBuffers(1, &indexBuffer); bool hasCompiledSubmeshes = false; //GLuint bufSize = 0; size_t numIndices = 0; for (SubmeshIterator it = submeshes.begin() ; it != submeshes.end() ; it++) { Submesh* submesh = *it; if (submesh->isLinked()) hasCompiledSubmeshes = true; numIndices += submesh->getIndexCount(); } uint32_t* newIndices = new uint32_t[numIndices]; glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indexBuffer); uint32_t* oldIndices; if (hasCompiledSubmeshes) oldIndices = (uint32_t*) glMapBuffer(GL_ELEMENT_ARRAY_BUFFER, GL_READ_ONLY); size_t offset = 0; for (SubmeshIterator it = submeshes.begin() ; it != submeshes.end() ; it++) { Submesh* submesh = *it; int ic = submesh->getIndexCount(); if (submesh->isLinked()) { memcpy(newIndices + offset, oldIndices + submesh->getIndexOffset(), ic*4); } else { memcpy(newIndices + offset, submesh->indices, ic*4); } submesh->setLinked(offset); offset += ic; } if (hasCompiledSubmeshes) glUnmapBuffer(GL_ELEMENT_ARRAY_BUFFER); glBufferData(GL_ELEMENT_ARRAY_BUFFER, numIndices*4, newIndices, GL_STATIC_DRAW); delete[] newIndices; isLinked = true; }
void display() { glm::vec3 MinScissor( 10000.f); glm::vec3 MaxScissor(-10000.f); // Update of the uniform buffer { glBindBuffer(GL_UNIFORM_BUFFER, BufferName[buffer::TRANSFORM]); glm::mat4* Pointer = (glm::mat4*)glMapBufferRange( GL_UNIFORM_BUFFER, 0, sizeof(glm::mat4), GL_MAP_WRITE_BIT | GL_MAP_INVALIDATE_BUFFER_BIT); glm::mat4 Projection = glm::perspective(45.0f, 4.0f / 3.0f, 0.1f, 100.0f); glm::mat4 ViewTranslate = glm::translate(glm::mat4(1.0f), glm::vec3(0.0f, 0.0f, -Window.TranlationCurrent.y)); glm::mat4 ViewRotateX = glm::rotate(ViewTranslate, Window.RotationCurrent.y, glm::vec3(1.f, 0.f, 0.f)); glm::mat4 View = glm::rotate(ViewRotateX, Window.RotationCurrent.x, glm::vec3(0.f, 1.f, 0.f)); glm::mat4 Model = glm::mat4(1.0f); *Pointer = Projection * View * Model; // Make sure the uniform buffer is uploaded glUnmapBuffer(GL_UNIFORM_BUFFER); glm::mat4 Ortho = glm::ortho(0.0f, 0.0f, float(Window.Size.x), float(Window.Size.y)); for(GLsizei i = 0; i < VertexCount; ++i) { glm::vec3 Projected = glm::project( glm::vec3(VertexData[i].Position, 0.0f), View * Model, Projection, glm::ivec4(0, 0, Window.Size.x, Window.Size.y)); MinScissor = glm::min(MinScissor, glm::vec3(Projected)); MaxScissor = glm::max(MaxScissor, glm::vec3(Projected)); } } glViewport(0, 0, Window.Size.x, Window.Size.y); glClearBufferfv(GL_COLOR, 0, &glm::vec4(1.0f, 0.5f, 0.0f, 1.0f)[0]); glScissor(GLint(MinScissor.x), GLint(MinScissor.y), GLsizei(MaxScissor.x - MinScissor.x), GLsizei(MaxScissor.y - MinScissor.y)); glEnable(GL_SCISSOR_TEST); glClearBufferfv(GL_COLOR, 0, &glm::vec4(0.0f, 0.0f, 0.0f, 1.0f)[0]); // Bind the program for use glUseProgram(ProgramName); glUniform1i(UniformDiffuse, 0); glUniformBlockBinding(ProgramName, UniformTransform, glf::semantic::uniform::TRANSFORM0); glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D, TextureName); glBindBufferBase(GL_UNIFORM_BUFFER, glf::semantic::uniform::TRANSFORM0, BufferName[buffer::TRANSFORM]); glBindVertexArray(VertexArrayName); glDrawArraysInstanced(GL_TRIANGLES, 0, VertexCount, 1); glDisable(GL_SCISSOR_TEST); glf::checkError("display"); glf::swapBuffers(); }
KDvoid CCTextureAtlas::drawNumberOfQuads ( KDuint uNumber, KDuint uStart ) { if ( 0 == uNumber ) { return; } ccGLBindTexture2D ( m_pTexture->getName ( ) ); #if CC_TEXTURE_ATLAS_USE_VAO // // Using VBO and VAO // // XXX: update is done in draw... perhaps it should be done in a timer if ( m_bDirty ) { glBindBuffer ( GL_ARRAY_BUFFER, m_pBuffersVBO[0] ); // option 1: subdata // glBufferSubData ( GL_ARRAY_BUFFER, sizeof ( m_pQuads[0] ) * uStart, sizeof ( m_pQuads[0] ) * uNumber , &m_pQuads [ uStart ] ); // option 2: data // glBufferData ( GL_ARRAY_BUFFER, sizeof ( m_pQuads[0] ) * ( n - uStart ), &m_pQuads [ uStart ], GL_DYNAMIC_DRAW ); // option 3: orphaning + glMapBuffer glBufferData ( GL_ARRAY_BUFFER, sizeof ( m_pQuads[0] ) * ( n - uStart ), KD_NULL, GL_DYNAMIC_DRAW ); KDvoid* pBuff = glMapBuffer ( GL_ARRAY_BUFFER, GL_WRITE_ONLY ); kdMemcpy ( pBuff, m_pQuads, sizeof ( m_pQuads [ 0 ] ) * ( n - uStart ) ); glUnmapBuffer ( GL_ARRAY_BUFFER ); glBindBuffer ( GL_ARRAY_BUFFER, 0 ); m_bDirty = KD_FALSE; } ccGLBindVAO ( m_uVAOname ); #if CC_REBIND_INDICES_BUFFER glBindBuffer ( GL_ELEMENT_ARRAY_BUFFER, m_pBuffersVBO[1] ); #endif glDrawElements ( GL_TRIANGLES, (GLsizei) uNumber * 6, GL_UNSIGNED_SHORT, (GLvoid*) ( uStart * 6 * sizeof ( m_pIndices[0] ) ) ); #if CC_REBIND_INDICES_BUFFER glBindBuffer ( GL_ELEMENT_ARRAY_BUFFER, 0 ); #endif // glBindVertexArray ( 0 ); #else // CC_TEXTURE_ATLAS_USE_VAO // // Using VBO without VAO // #define kQuadSize sizeof(m_pQuads[0].bl) glBindBuffer ( GL_ARRAY_BUFFER, m_pBuffersVBO[0] ); // XXX: update is done in draw... perhaps it should be done in a timer if ( m_bDirty ) { glBufferSubData ( GL_ARRAY_BUFFER, sizeof ( m_pQuads[0] ) * uStart, sizeof ( m_pQuads[0] ) * uNumber , &m_pQuads[ uStart ] ); m_bDirty = KD_FALSE; } ccGLEnableVertexAttribs ( kCCVertexAttribFlag_PosColorTex ); ccGLVertexAttribPointer ( kCCVertexAttrib_Position , 3, GL_FLOAT , GL_FALSE, kQuadSize, (GLvoid*) offsetof ( ccV3F_C4B_T2F, vertices ) ); ccGLVertexAttribPointer ( kCCVertexAttrib_Color , 4, GL_UNSIGNED_BYTE, GL_TRUE , kQuadSize, (GLvoid*) offsetof ( ccV3F_C4B_T2F, colors ) ); ccGLVertexAttribPointer ( kCCVertexAttrib_TexCoords, 2, GL_FLOAT , GL_FALSE, kQuadSize, (GLvoid*) offsetof ( ccV3F_C4B_T2F, texCoords ) ); glBindBuffer ( GL_ELEMENT_ARRAY_BUFFER, m_pBuffersVBO[1] ); glDrawElements ( GL_TRIANGLES, (GLsizei) uNumber * 6, GL_UNSIGNED_SHORT, (GLvoid*) ( uStart * 6 * sizeof ( m_pIndices[0] ) ) ); glBindBuffer ( GL_ARRAY_BUFFER, 0 ); glBindBuffer ( GL_ELEMENT_ARRAY_BUFFER, 0 ); #endif // CC_TEXTURE_ATLAS_USE_VAO CC_INCREMENT_GL_DRAWS ( 1 ); CHECK_GL_ERROR_DEBUG ( ); }
bool render() { glm::ivec2 WindowSize(this->getWindowSize()); glm::ivec2 FramebufferSize = WindowSize / FRAMEBUFFER_SIZE; // Update of the uniform buffer { glBindBuffer(GL_UNIFORM_BUFFER, BufferName[buffer::TRANSFORM]); glm::mat4* Pointer = (glm::mat4*)glMapBufferRange( GL_UNIFORM_BUFFER, 0, sizeof(glm::mat4), GL_MAP_WRITE_BIT | GL_MAP_INVALIDATE_BUFFER_BIT); glm::mat4 Projection = glm::perspective(glm::pi<float>() * 0.25f, 4.0f / 3.0f, 0.1f, 100.0f); glm::mat4 Model = glm::mat4(1.0f); *Pointer = Projection * this->view() * Model; // Make sure the uniform buffer is uploaded glUnmapBuffer(GL_UNIFORM_BUFFER); } glEnable(GL_DEPTH_TEST); glDepthFunc(GL_LESS); glViewport(0, 0, FramebufferSize.x, FramebufferSize.y); glBindFramebuffer(GL_FRAMEBUFFER, FramebufferName); float Depth(1.0f); glClearBufferfv(GL_DEPTH , 0, &Depth); glClearBufferfv(GL_COLOR, 0, &glm::vec4(0.0f, 0.0f, 0.0f, 1.0f)[0]); glUseProgram(ProgramName[program::TEXTURE]); glUniform1i(UniformDiffuse[program::TEXTURE], 0); glUniformBlockBinding(ProgramName[program::TEXTURE], UniformTransform, semantic::uniform::TRANSFORM0); glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D, TextureName[texture::DIFFUSE]); glBindVertexArray(VertexArrayName[program::TEXTURE]); glBindBufferBase(GL_UNIFORM_BUFFER, semantic::uniform::TRANSFORM0, BufferName[buffer::TRANSFORM]); glEnable(GL_SCISSOR_TEST); glScissor(0, 0, FramebufferSize.x / 2, FramebufferSize.y); glUniform1i(UniformUseGrad, 1); glDrawElementsInstancedBaseVertex(GL_TRIANGLES, ElementCount, GL_UNSIGNED_SHORT, 0, 2, 0); glScissor(FramebufferSize.x / 2, 0, FramebufferSize.x / 2, FramebufferSize.y); glUniform1i(UniformUseGrad, 0); glDrawElementsInstancedBaseVertex(GL_TRIANGLES, ElementCount, GL_UNSIGNED_SHORT, 0, 2, 0); glDisable(GL_SCISSOR_TEST); glDisable(GL_DEPTH_TEST); glViewport(0, 0, static_cast<GLsizei>(WindowSize.x), static_cast<GLsizei>(WindowSize.y)); glBindFramebuffer(GL_FRAMEBUFFER, 0); glUseProgram(ProgramName[program::SPLASH]); glUniform1i(UniformDiffuse[program::SPLASH], 0); glUniform1f(UniformFramebufferSize, static_cast<float>(FRAMEBUFFER_SIZE)); glActiveTexture(GL_TEXTURE0); glBindVertexArray(VertexArrayName[program::SPLASH]); glBindTexture(GL_TEXTURE_2D, TextureName[texture::COLORBUFFER]); glDrawArraysInstanced(GL_TRIANGLES, 0, 3, 1); return true; }
void CLPhysicsDemo::stepSimulation() { BT_PROFILE("simulationLoop"); { BT_PROFILE("glFinish"); glFinish(); } cl_int ciErrNum = CL_SUCCESS; if(m_data->m_useInterop) { clBuffer = g_interopBuffer->getCLBUffer(); BT_PROFILE("clEnqueueAcquireGLObjects"); ciErrNum = clEnqueueAcquireGLObjects(g_cqCommandQue, 1, &clBuffer, 0, 0, NULL); adl::DeviceUtils::waitForCompletion( g_deviceCL ); } else { glBindBuffer(GL_ARRAY_BUFFER, cube_vbo); glFlush(); BT_PROFILE("glMapBuffer and clEnqueueWriteBuffer"); blocking= CL_TRUE; hostPtr= (char*)glMapBuffer( GL_ARRAY_BUFFER,GL_READ_WRITE);//GL_WRITE_ONLY if (!clBuffer) { clBuffer = clCreateBuffer(g_cxMainContext, CL_MEM_READ_WRITE, VBOsize, 0, &ciErrNum); } adl::DeviceUtils::waitForCompletion( g_deviceCL ); oclCHECKERROR(ciErrNum, CL_SUCCESS); ciErrNum = clEnqueueWriteBuffer ( g_cqCommandQue, clBuffer, blocking, 0, VBOsize, hostPtr,0,0,0 ); adl::DeviceUtils::waitForCompletion( g_deviceCL ); } oclCHECKERROR(ciErrNum, CL_SUCCESS); if (runOpenCLKernels && m_numPhysicsInstances) { gFpIO.m_numObjects = m_numPhysicsInstances; gFpIO.m_positionOffset = SHAPE_VERTEX_BUFFER_SIZE/4; gFpIO.m_clObjectsBuffer = clBuffer; gFpIO.m_dAABB = m_data->m_Broadphase->m_dAABB; gFpIO.m_dlocalShapeAABB = (cl_mem)m_data->m_localShapeAABB->m_ptr; gFpIO.m_numOverlap = 0; { BT_PROFILE("setupGpuAabbs"); setupGpuAabbsFull(gFpIO,narrowphaseAndSolver->getBodiesGpu() ); } if (1) { BT_PROFILE("calculateOverlappingPairs"); m_data->m_Broadphase->calculateOverlappingPairs(0, m_numPhysicsInstances); gFpIO.m_dAllOverlappingPairs = m_data->m_Broadphase->m_dAllOverlappingPairs; gFpIO.m_numOverlap = m_data->m_Broadphase->m_numPrefixSum; } //printf("gFpIO.m_numOverlap = %d\n",gFpIO.m_numOverlap ); if (gFpIO.m_numOverlap>=0 && gFpIO.m_numOverlap<MAX_BROADPHASE_COLLISION_CL) { colorPairsOpenCL(gFpIO); if (1) { { //BT_PROFILE("setupBodies"); if (narrowphaseAndSolver) setupBodies(gFpIO, gLinVelMem, gAngVelMem, narrowphaseAndSolver->getBodiesGpu(), narrowphaseAndSolver->getBodyInertiasGpu()); } if (gFpIO.m_numOverlap) { BT_PROFILE("computeContactsAndSolver"); if (narrowphaseAndSolver) narrowphaseAndSolver->computeContactsAndSolver(gFpIO.m_dAllOverlappingPairs,gFpIO.m_numOverlap); } { BT_PROFILE("copyBodyVelocities"); if (narrowphaseAndSolver) copyBodyVelocities(gFpIO, gLinVelMem, gAngVelMem, narrowphaseAndSolver->getBodiesGpu(), narrowphaseAndSolver->getBodyInertiasGpu()); } } } else { printf("error, gFpIO.m_numOverlap = %d\n",gFpIO.m_numOverlap); btAssert(0); } { BT_PROFILE("integrateTransforms"); if (runOpenCLKernels) { int numObjects = m_numPhysicsInstances; int offset = SHAPE_VERTEX_BUFFER_SIZE/4; ciErrNum = clSetKernelArg(g_integrateTransformsKernel, 0, sizeof(int), &offset); ciErrNum = clSetKernelArg(g_integrateTransformsKernel, 1, sizeof(int), &numObjects); ciErrNum = clSetKernelArg(g_integrateTransformsKernel, 2, sizeof(cl_mem), (void*)&clBuffer ); ciErrNum = clSetKernelArg(g_integrateTransformsKernel, 3, sizeof(cl_mem), (void*)&gLinVelMem); ciErrNum = clSetKernelArg(g_integrateTransformsKernel, 4, sizeof(cl_mem), (void*)&gAngVelMem); ciErrNum = clSetKernelArg(g_integrateTransformsKernel, 5, sizeof(cl_mem), (void*)&gBodyTimes); size_t workGroupSize = 64; size_t numWorkItems = workGroupSize*((m_numPhysicsInstances + (workGroupSize)) / workGroupSize); if (workGroupSize>numWorkItems) workGroupSize=numWorkItems; ciErrNum = clEnqueueNDRangeKernel(g_cqCommandQue, g_integrateTransformsKernel, 1, NULL, &numWorkItems, &workGroupSize,0 ,0 ,0); oclCHECKERROR(ciErrNum, CL_SUCCESS); } } } if(m_data->m_useInterop) { BT_PROFILE("clEnqueueReleaseGLObjects"); ciErrNum = clEnqueueReleaseGLObjects(g_cqCommandQue, 1, &clBuffer, 0, 0, 0); adl::DeviceUtils::waitForCompletion( g_deviceCL ); } else { BT_PROFILE("clEnqueueReadBuffer clReleaseMemObject and glUnmapBuffer"); ciErrNum = clEnqueueReadBuffer ( g_cqCommandQue, clBuffer, blocking, 0, VBOsize, hostPtr,0,0,0); //clReleaseMemObject(clBuffer); adl::DeviceUtils::waitForCompletion( g_deviceCL ); glUnmapBuffer( GL_ARRAY_BUFFER); glFlush(); } oclCHECKERROR(ciErrNum, CL_SUCCESS); if (runOpenCLKernels) { BT_PROFILE("clFinish"); clFinish(g_cqCommandQue); } }
void GLVertexBuffer::ReleasePointer() { GLCall(glUnmapBuffer(GL_ARRAY_BUFFER)); }
void Topo3PrimalRender<PFP>::updateData(MAP& mapx, const VertexAttribute<VEC3, MAP>& positions, float ke, float kf) { if (m_attIndex.map() != &mapx) m_attIndex = mapx.template getAttribute<unsigned int, DART, MAP>("dart_index"); if (!m_attIndex.isValid()) m_attIndex = mapx.template addAttribute<unsigned int, DART, MAP>("dart_index"); // m_nbDarts = 0; // for (Dart d = mapx.begin(); d != mapx.end(); mapx.next(d)) // { // m_nbDarts++; // } m_nbDarts = mapx.getNbDarts(); // beta2/3 DartAutoAttribute<VEC3, MAP> fv2(mapx); m_vbo2->bind(); glBufferData(GL_ARRAY_BUFFER, 2*m_nbDarts*sizeof(Geom::Vec3f), 0, GL_STREAM_DRAW); GLvoid* ColorDartsBuffer = glMapBuffer(GL_ARRAY_BUFFER, GL_READ_WRITE); Geom::Vec3f* colorDartBuf = reinterpret_cast<Geom::Vec3f*>(ColorDartsBuffer); if (m_bufferDartPosition!=NULL) delete m_bufferDartPosition; m_bufferDartPosition = new Geom::Vec3f[2*m_nbDarts]; Geom::Vec3f* positionDartBuf = reinterpret_cast<Geom::Vec3f*>(m_bufferDartPosition); unsigned int posDBI = 0; int nbf = 0; //traverse each face of each volume TraversorF<MAP> traFace(mapx); for (Dart d = traFace.begin(); d != traFace.end(); d = traFace.next()) { std::vector<VEC3> vecPos; vecPos.reserve(16); VEC3 centerFace = Algo::Surface::Geometry::faceCentroidELW<PFP>(mapx, d, positions); //shrink the face float okf = 1.0f - kf; Dart dd = d; do { VEC3 P = centerFace*okf + positions[dd]*kf; vecPos.push_back(P); dd = mapx.phi1(dd); } while (dd != d); unsigned int nb = vecPos.size(); vecPos.push_back(vecPos.front()); // copy the first for easy computation on next loop // compute position of points to use for drawing topo float oke = 1.0f - ke; for (unsigned int i = 0; i < nb; ++i) { VEC3 P = vecPos[i]*ke + vecPos[i+1]*oke; VEC3 Q = vecPos[i+1]*ke + vecPos[i]*oke; // VEC3 PP = 0.52f*P + 0.48f*Q; // VEC3 QQ = 0.52f*Q + 0.48f*P; VEC3 PP = 0.56f*P + 0.44f*Q; VEC3 QQ = 0.56f*Q + 0.44f*P; *positionDartBuf++ = PFP::toVec3f(P); *positionDartBuf++ = PFP::toVec3f(PP); if (mapx.template isBoundaryMarked<3>(d)) { *colorDartBuf++ = m_boundaryDartsColor; *colorDartBuf++ = m_boundaryDartsColor; } else { *colorDartBuf++ = m_dartsColor; *colorDartBuf++ = m_dartsColor; } m_attIndex[d] = posDBI; posDBI+=2; fv2[d] = (P+PP)*0.5f; *positionDartBuf++ = PFP::toVec3f(Q); *positionDartBuf++ = PFP::toVec3f(QQ); Dart dx = mapx.phi3(d); if (mapx.template isBoundaryMarked<3>(dx)) { *colorDartBuf++ = m_boundaryDartsColor; *colorDartBuf++ = m_boundaryDartsColor; } else { *colorDartBuf++ = m_dartsColor; *colorDartBuf++ = m_dartsColor; } m_attIndex[dx] = posDBI; posDBI+=2; fv2[dx] = (Q+QQ)*0.5f; d = mapx.phi1(d); } nbf++; } m_vbo2->bind(); glUnmapBuffer(GL_ARRAY_BUFFER); m_vbo0->bind(); glBufferData(GL_ARRAY_BUFFER, 2*m_nbDarts*sizeof(Geom::Vec3f), m_bufferDartPosition, GL_STREAM_DRAW); // alpha2 m_vbo1->bind(); glBufferData(GL_ARRAY_BUFFER, 2*m_nbDarts*sizeof(Geom::Vec3f), 0, GL_STREAM_DRAW); GLvoid* PositionBuffer2 = glMapBufferARB(GL_ARRAY_BUFFER, GL_READ_WRITE); Geom::Vec3f* positionF2 = reinterpret_cast<Geom::Vec3f*>(PositionBuffer2); m_nbRel2 = 0; for (Dart d = mapx.begin(); d != mapx.end(); mapx.next(d)) { Dart e = mapx.phi2(mapx.phi3(d)); //if (d < e) { *positionF2++ = PFP::toVec3f(fv2[d]); *positionF2++ = PFP::toVec3f(fv2[e]); m_nbRel2++; } } m_vbo1->bind(); glUnmapBuffer(GL_ARRAY_BUFFER); glBindBuffer(GL_ARRAY_BUFFER, 0); }
void VertexArrayObject::freeDataPointer() { glUnmapBuffer(GL_ARRAY_BUFFER); // unmap it after use }
void KT_API OGL3HardwareBuffer::Unmap( OGL3ImmediateContext* ctx ) { ktOGL3Check( glBindBuffer(myTarget, myBufferID) ); ktOGL3Check( glUnmapBuffer(myTarget) ); ktOGL3Check( glBindBuffer(myTarget, 0) ); }
void raytracer_app::render(double currentTime) { static const GLfloat zeros[] = { 0.0f, 0.0f, 0.0f, 0.0f }; static const GLfloat gray[] = { 0.1f, 0.1f, 0.1f, 0.0f }; static const GLfloat ones[] = { 1.0f }; static double last_time = 0.0; static double total_time = 0.0; if (!paused) total_time += (currentTime - last_time); last_time = currentTime; float f = (float)total_time; vmath::vec3 view_position = vmath::vec3(sinf(f * 0.3234f) * 28.0f, cosf(f * 0.4234f) * 28.0f, cosf(f * 0.1234f) * 28.0f); // sinf(f * 0.2341f) * 20.0f - 8.0f); vmath::vec3 lookat_point = vmath::vec3(sinf(f * 0.214f) * 8.0f, cosf(f * 0.153f) * 8.0f, sinf(f * 0.734f) * 8.0f); vmath::mat4 view_matrix = vmath::lookat(view_position, lookat_point, vmath::vec3(0.0f, 1.0f, 0.0f)); glBindBufferBase(GL_UNIFORM_BUFFER, 0, uniforms_buffer); uniforms_block * block = (uniforms_block *)glMapBufferRange(GL_UNIFORM_BUFFER, 0, sizeof(uniforms_block), GL_MAP_WRITE_BIT | GL_MAP_INVALIDATE_BUFFER_BIT); vmath::mat4 model_matrix = vmath::scale(7.0f); // f = 0.0f; block->mv_matrix = view_matrix * model_matrix; block->view_matrix = view_matrix; block->proj_matrix = vmath::perspective(50.0f, (float)info.windowWidth / (float)info.windowHeight, 0.1f, 1000.0f); glUnmapBuffer(GL_UNIFORM_BUFFER); glBindBufferBase(GL_UNIFORM_BUFFER, 1, sphere_buffer); sphere * s = (sphere *)glMapBufferRange(GL_UNIFORM_BUFFER, 0, 128 * sizeof(sphere), GL_MAP_WRITE_BIT | GL_MAP_INVALIDATE_BUFFER_BIT); int i; for (i = 0; i < 128; i++) { // float f = 0.0f; float fi = (float)i / 128.0f; s[i].center = vmath::vec3(sinf(fi * 123.0f + f) * 15.75f, cosf(fi * 456.0f + f) * 15.75f, (sinf(fi * 300.0f + f) * cosf(fi * 200.0f + f)) * 20.0f); s[i].radius = fi * 2.3f + 3.5f; float r = fi * 61.0f; float g = r + 0.25f; float b = g + 0.25f; r = (r - floorf(r)) * 0.8f + 0.2f; g = (g - floorf(g)) * 0.8f + 0.2f; b = (b - floorf(b)) * 0.8f + 0.2f; s[i].color = vmath::vec4(r, g, b, 1.0f); } glUnmapBuffer(GL_UNIFORM_BUFFER); glBindBufferBase(GL_UNIFORM_BUFFER, 2, plane_buffer); plane * p = (plane *)glMapBufferRange(GL_UNIFORM_BUFFER, 0, 128 * sizeof(plane), GL_MAP_WRITE_BIT | GL_MAP_INVALIDATE_BUFFER_BIT); //for (i = 0; i < 1; i++) { p[0].normal = vmath::vec3(0.0f, 0.0f, -1.0f); p[0].d = 30.0f; p[1].normal = vmath::vec3(0.0f, 0.0f, 1.0f); p[1].d = 30.0f; p[2].normal = vmath::vec3(-1.0f, 0.0f, 0.0f); p[2].d = 30.0f; p[3].normal = vmath::vec3(1.0f, 0.0f, 0.0f); p[3].d = 30.0f; p[4].normal = vmath::vec3(0.0f, -1.0f, 0.0f); p[4].d = 30.0f; p[5].normal = vmath::vec3(0.0f, 1.0f, 0.0f); p[5].d = 30.0f; } glUnmapBuffer(GL_UNIFORM_BUFFER); glBindBufferBase(GL_UNIFORM_BUFFER, 3, light_buffer); light * l = (light *)glMapBufferRange(GL_UNIFORM_BUFFER, 0, 128 * sizeof(light), GL_MAP_WRITE_BIT | GL_MAP_INVALIDATE_BUFFER_BIT); f *= 1.0f; for (i = 0; i < 128; i++) { float fi = 3.33f - (float)i; // / 35.0f; l[i].position = vmath::vec3(sinf(fi * 2.0f - f) * 15.75f, cosf(fi * 5.0f - f) * 5.75f, (sinf(fi * 3.0f - f) * cosf(fi * 2.5f - f)) * 19.4f); } glUnmapBuffer(GL_UNIFORM_BUFFER); glBindVertexArray(vao); glViewport(0, 0, info.windowWidth, info.windowHeight); glUseProgram(prepare_program); glUniformMatrix4fv(uniforms.ray_lookat, 1, GL_FALSE, view_matrix); glUniform3fv(uniforms.ray_origin, 1, view_position); glUniform1f(uniforms.aspect, (float)info.windowHeight / (float)info.windowWidth); glBindFramebuffer(GL_FRAMEBUFFER, ray_fbo[0]); static const GLenum draw_buffers[] = { GL_COLOR_ATTACHMENT0, GL_COLOR_ATTACHMENT1, GL_COLOR_ATTACHMENT2, GL_COLOR_ATTACHMENT3, GL_COLOR_ATTACHMENT4, GL_COLOR_ATTACHMENT5 }; glDrawBuffers(6, draw_buffers); glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); glUseProgram(trace_program); recurse(0); glUseProgram(blit_program); glBindFramebuffer(GL_FRAMEBUFFER, 0); glDrawBuffer(GL_BACK); glActiveTexture(GL_TEXTURE0); switch (debug_mode) { case DEBUG_NONE: glBindTexture(GL_TEXTURE_2D, tex_composite); break; case DEBUG_REFLECTED: glBindTexture(GL_TEXTURE_2D, tex_reflected[debug_depth]); break; case DEBUG_REFRACTED: glBindTexture(GL_TEXTURE_2D, tex_refracted[debug_depth]); break; case DEBUG_REFLECTED_COLOR: glBindTexture(GL_TEXTURE_2D, tex_reflection_intensity[debug_depth]); break; case DEBUG_REFRACTED_COLOR: glBindTexture(GL_TEXTURE_2D, tex_refraction_intensity[debug_depth]); break; } glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); /* glClearBufferfv(GL_COLOR, 0, gray); glClearBufferfv(GL_DEPTH, 0, ones); glBindVertexArray(vao); glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); */ }
void Renderer::drawBatchedQuads() { //TODO: we can improve the draw performance by insert material switching command before hand. int indexToDraw = 0; int startIndex = 0; //Upload buffer to VBO if(_numberQuads <= 0 || _batchQuadCommands.empty()) { return; } if (Configuration::getInstance()->supportsShareableVAO()) { //Bind VAO GL::bindVAO(_quadVAO); //Set VBO data glBindBuffer(GL_ARRAY_BUFFER, _quadbuffersVBO[0]); // option 1: subdata // glBufferSubData(GL_ARRAY_BUFFER, sizeof(_quads[0])*start, sizeof(_quads[0]) * n , &_quads[start] ); // option 2: data // glBufferData(GL_ARRAY_BUFFER, sizeof(quads_[0]) * (n-start), &quads_[start], GL_DYNAMIC_DRAW); // option 3: orphaning + glMapBuffer glBufferData(GL_ARRAY_BUFFER, sizeof(_quadVerts[0]) * _numberQuads * 4, nullptr, GL_DYNAMIC_DRAW); void *buf = glMapBuffer(GL_ARRAY_BUFFER, GL_WRITE_ONLY); memcpy(buf, _quadVerts, sizeof(_quadVerts[0])* _numberQuads * 4); glUnmapBuffer(GL_ARRAY_BUFFER); glBindBuffer(GL_ARRAY_BUFFER, 0); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, _quadbuffersVBO[1]); } else { #define kQuadSize sizeof(_verts[0]) glBindBuffer(GL_ARRAY_BUFFER, _quadbuffersVBO[0]); glBufferData(GL_ARRAY_BUFFER, sizeof(_quadVerts[0]) * _numberQuads * 4 , _quadVerts, GL_DYNAMIC_DRAW); GL::enableVertexAttribs(GL::VERTEX_ATTRIB_FLAG_POS_COLOR_TEX); // vertices glVertexAttribPointer(GLProgram::VERTEX_ATTRIB_POSITION, 3, GL_FLOAT, GL_FALSE, kQuadSize, (GLvoid*) offsetof(V3F_C4B_T2F, vertices)); // colors glVertexAttribPointer(GLProgram::VERTEX_ATTRIB_COLOR, 4, GL_UNSIGNED_BYTE, GL_TRUE, kQuadSize, (GLvoid*) offsetof(V3F_C4B_T2F, colors)); // tex coords glVertexAttribPointer(GLProgram::VERTEX_ATTRIB_TEX_COORD, 2, GL_FLOAT, GL_FALSE, kQuadSize, (GLvoid*) offsetof(V3F_C4B_T2F, texCoords)); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, _quadbuffersVBO[1]); } //Start drawing verties in batch for(const auto& cmd : _batchQuadCommands) { auto newMaterialID = cmd->getMaterialID(); if(_lastMaterialID != newMaterialID || newMaterialID == MATERIAL_ID_DO_NOT_BATCH) { //Draw quads if(indexToDraw > 0) { glDrawElements(GL_TRIANGLES, (GLsizei) indexToDraw, GL_UNSIGNED_SHORT, (GLvoid*) (startIndex*sizeof(_indices[0])) ); _drawnBatches++; _drawnVertices += indexToDraw; startIndex += indexToDraw; indexToDraw = 0; } //Use new material cmd->useMaterial(); _lastMaterialID = newMaterialID; } indexToDraw += cmd->getQuadCount() * 6; } //Draw any remaining quad if(indexToDraw > 0) { glDrawElements(GL_TRIANGLES, (GLsizei) indexToDraw, GL_UNSIGNED_SHORT, (GLvoid*) (startIndex*sizeof(_indices[0])) ); _drawnBatches++; _drawnVertices += indexToDraw; } if (Configuration::getInstance()->supportsShareableVAO()) { //Unbind VAO GL::bindVAO(0); } else { glBindBuffer(GL_ARRAY_BUFFER, 0); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); } _batchQuadCommands.clear(); _numberQuads = 0; }
void ParticleBatchRenderer::end() { glUnmapBuffer(GL_ARRAY_BUFFER); glBindBuffer(GL_ARRAY_BUFFER, 0); }
void Unmap(u32 used_size) override { glFlushMappedBufferRange(m_buffertype, 0, used_size); glUnmapBuffer(m_buffertype); m_iterator += used_size; }
void VisibilityExtractionDemo::run() { const GLuint zero = 0; render(window, [&] (float deltaTime) { numberOfFrames++; frameInterval += deltaTime; if (frameInterval > 1.0f) { fps = numberOfFrames / frameInterval; std::cout << "FPS: " << fps << std::endl; numberOfFrames = 0; frameInterval = 0.0f; } if (glfwGetKey(window, GLFW_KEY_LEFT) == GLFW_PRESS) (rotY - deltaTime < 0)? rotY -= deltaTime + 6.283 : rotY -= deltaTime; if (glfwGetKey(window, GLFW_KEY_RIGHT) == GLFW_PRESS) (rotY + deltaTime > 6.283)? rotY += deltaTime - 6.283 : rotY += deltaTime; if (glfwGetKey(window, GLFW_KEY_UP) == GLFW_PRESS) (rotX - deltaTime < 0)? rotX -= deltaTime + 6.283 : rotX -= deltaTime; if (glfwGetKey(window, GLFW_KEY_DOWN) == GLFW_PRESS) (rotX + deltaTime > 6.283)? rotX += deltaTime - 6.283 : rotX += deltaTime; if (glfwGetKey(window, GLFW_KEY_PAGE_DOWN) == GLFW_PRESS) distance += deltaTime * 50; if (glfwGetKey(window, GLFW_KEY_PAGE_UP) == GLFW_PRESS) distance = max(distance - deltaTime * 50, 0.0f); if (glfwGetKey(window, GLFW_KEY_PERIOD) == GLFW_PRESS) scale += deltaTime*4; if (glfwGetKey(window, GLFW_KEY_COMMA) == GLFW_PRESS) scale = glm::max(scale - deltaTime*4, 0.01f); if (glfwGetKey(window, GLFW_KEY_L) == GLFW_PRESS) {updateVisibilityMapLock = true; updateVisibilityMap = true;} if (glfwGetKey(window, GLFW_KEY_U) == GLFW_PRESS) updateVisibilityMapLock = false; if (glfwGetKey(window, GLFW_KEY_P) == GLFW_PRESS) pingPongOff = false; if (glfwGetKey(window, GLFW_KEY_O) == GLFW_PRESS) pingPongOff = true; if (glfwGetKey(window, GLFW_KEY_F11) == GLFW_PRESS) { vsync = !vsync; vsync ? glfwSwapInterval(1) : glfwSwapInterval(0); vsync ? std::cout << "VSync enabled\n" : std::cout << "VSync disabled\n"; } // Render impostor geometry if (glfwGetKey(window, GLFW_KEY_1) == GLFW_PRESS) { renderBalls->setShaderProgram(&spRenderImpostor); renderBalls->texture("sortedVisibleIDsBuffer", tex_sortedVisibleIDsBuffer); result->update("maxRange", 1.0f); result->texture("tex", renderBalls->get("fragColor")); } // Render impostor geometry as disc if (glfwGetKey(window, GLFW_KEY_2) == GLFW_PRESS) { renderBalls->setShaderProgram(&spRenderDiscs); renderBalls->texture("sortedVisibleIDsBuffer", tex_sortedVisibleIDsBuffer); result->update("maxRange", 1.0f); result->texture("tex", renderBalls->get("fragColor")); } // Render faked geometry if (glfwGetKey(window, GLFW_KEY_3) == GLFW_PRESS) { renderBalls->setShaderProgram(&spRenderBalls); renderBalls->texture("sortedVisibleIDsBuffer", tex_sortedVisibleIDsBuffer); result->update("maxRange", 1.0f); result->texture("tex", renderBalls->get("fragColor")); } // Render instance IDs geometry if (glfwGetKey(window, GLFW_KEY_4) == GLFW_PRESS) { renderBalls->setShaderProgram(&spRenderBalls); renderBalls->texture("sortedVisibleIDsBuffer", tex_sortedVisibleIDsBuffer); result->update("maxRange", float(impSph->num_balls)); result->texture("tex", renderBalls->get("InstanceID")); } if (glfwGetKey(window, GLFW_KEY_A) == GLFW_PRESS) { if(animate) { animate = false; lastTime = glfwGetTime(); } else { animate = true; glfwSetTime(lastTime); } } if (animate) { elapsedTime = glfwGetTime(); if (elapsedTime > 628) { elapsedTime = 0; glfwSetTime(0); } } mat4 view = translate(mat4(1), vec3(0,0,-distance)) * eulerAngleXY(-rotX, -rotY); // reset the detected instance IDs glBindTexture(GL_TEXTURE_1D, tex_collectedIDsBuffer->getHandle()); glTexImage1D(GL_TEXTURE_1D, 0, GL_R8UI, num_balls, 0, GL_RED_INTEGER, GL_UNSIGNED_INT, zeros); //glBindTexture(GL_TEXTURE_1D, visibleIDsBuff->getHandle()); //glTexImage1D(GL_TEXTURE_1D, 0, GL_R32UI, num_balls, 0, GL_RED_INTEGER, GL_UNSIGNED_INT, &identityInstancesMap[0]); glBindBuffer(GL_ATOMIC_COUNTER_BUFFER, atomBuff); glClearBufferSubData(GL_ATOMIC_COUNTER_BUFFER, GL_R32UI, 0, sizeof(GLuint), GL_RED_INTEGER, GL_UNSIGNED_INT, zero); renderBalls->clear(-1,-1,-1,-1); // the clear color may not interfere with the detected instance IDs renderBalls->clearDepth(); renderBalls->update("scale", vec2(scale)); renderBalls->update("view", view); renderBalls->update("probeRadius", probeRadius); renderBalls->run(); // Depending on user input: sort out instances for the next frame or not, // or lock the current set of visible instances if(useAtomicCounters) if (updateVisibilityMap && !pingPongOff) { // the following shaders in detectVisible look at what has been written to the screen (framebuffer0) // better render the instance stuff to a texture and read from there collectSurfaceIDs->run(); glMemoryBarrier(GL_SHADER_IMAGE_ACCESS_BARRIER_BIT|GL_BUFFER_UPDATE_BARRIER_BIT); glBeginQuery(GL_TIME_ELAPSED, timeQuery); computeSortedIDs->run(16,1,1); // 16 work groups * 1024 work items = 16384 atoms and IDs glMemoryBarrier(GL_ATOMIC_COUNTER_BARRIER_BIT|GL_SHADER_IMAGE_ACCESS_BARRIER_BIT|GL_BUFFER_UPDATE_BARRIER_BIT); glEndQuery(GL_TIME_ELAPSED); glGetQueryObjectuiv(timeQuery, GL_QUERY_RESULT, &queryTime); std::cout << "compute shader time: " << queryTime << std::endl; // Check buffer data // GLuint visibilityMapFromBuff[ImpostorSpheres::num_balls]; // GLuint visibleIDsFromBuff[ImpostorSpheres::num_balls]; // glBindTexture(GL_TEXTURE_1D, bufferTex->getHandle()); // glGetTexImage(GL_TEXTURE_1D, 0, GL_RED_INTEGER, GL_UNSIGNED_INT, visibilityMapFromBuff); // glBindTexture(GL_TEXTURE_1D, visibleIDsBuff->getHandle()); // glGetTexImage(GL_TEXTURE_1D, 0, GL_RED_INTEGER, GL_UNSIGNED_INT, visibleIDsFromBuff); //get the value of the atomic counter glBindBuffer(GL_ATOMIC_COUNTER_BUFFER, atomBuff); GLuint* counterVal = (GLuint*) glMapBufferRange(GL_ATOMIC_COUNTER_BUFFER, 0, sizeof(GLuint), GL_MAP_READ_BIT ); glUnmapBuffer(GL_ATOMIC_COUNTER_BUFFER); impSph->instancesToRender = *counterVal; std::cout << "Number of visible instances by atomic Counter: " << *counterVal << std::endl; updateVisibilityMap = false; }else { if(!updateVisibilityMapLock) { // ToDo // instead of uploading the data, swap the buffer glBindTexture(GL_TEXTURE_1D, tex_sortedVisibleIDsBuffer->getHandle()); glTexImage1D(GL_TEXTURE_1D, 0, GL_R32UI, num_balls, 0, GL_RED_INTEGER, GL_UNSIGNED_INT, &identityInstancesMap[0]); impSph->instancesToRender = impSph->num_balls; updateVisibilityMap = true; // sort out every other frame } } else if (updateVisibilityMap && !pingPongOff) { collectSurfaceIDs->run(); // detect visible instances glBeginQuery(GL_TIME_ELAPSED, timeQuery); GLuint visibilityMapFromBuff[impSph->num_balls]; glBindTexture(GL_TEXTURE_1D, tex_collectedIDsBuffer->getHandle()); glGetTexImage(GL_TEXTURE_1D, 0, GL_RED_INTEGER, GL_UNSIGNED_INT, visibilityMapFromBuff); // copy visible instance information to a vector with size = num_balls int num_vis = 0; std::vector<GLint> newMap; newMap.resize(num_balls); for (int i = 0; i < num_balls; i++) { newMap[i] = (int)visibilityMapFromBuff[i]; if(visibilityMapFromBuff[i] != 0) num_vis++; } glEndQuery(GL_TIME_ELAPSED); glGetQueryObjectuiv(timeQuery, GL_QUERY_RESULT, &queryTime); std::cout << "cpu time: " << queryTime << std::endl; // print number of visible instances std::cout << "Number of visible instances: " << num_vis << std::endl; impSph->updateVisibilityMap(newMap); updateVisibilityMap = false; }else { if(!updateVisibilityMapLock) { impSph->updateVisibilityMap(mapAllVisible); updateVisibilityMap = true; // sort out every other frame } } result->clear(num_balls,num_balls,num_balls,num_balls); result->run(); }); }