void ShaderInterface::preparePostProduction(GLuint& width, GLuint& height, GLdouble& fov, const int fbo_reg) { // save original render settings (needed for oversized fbos) original_width = width; original_height = height; original_fov = fov; // global shader init glUseProgram(runningProgram->second->getId()); // check if a post program has been selected: if so, prepare the frame buffer objects if(postProgram == programs.end()) return; // check fbo if(fbos.find(fbo_reg) == fbos.end()) { if(!initFramebufferObject(fbo_reg)) { // if we tried creation longer than a minute: abort if(fboInit - clock() > 1000) { GLHelper::getGLH()->glPrintText(TextObject::WARNING_HINTS, TextObject::WARNING, 5000, "WARNING: preparing post production failed: fbo initialization went wrong"); postProgram = programs.end(); } return; } } // choose render destination currentFBO = fbo_reg; FramebufferObject* fbo = fbos[currentFBO]; if(!fbo->update(width, height)) { GLHelper::getGLH()->glPrintText(TextObject::WARNING_HINTS, TextObject::WARNING, 500, "WARNING: preparing post production failed: fbo not initialized"); destroyFramebufferObjects(); postProgram = programs.end(); return; } // set the new render resolution (if oversized fbos are used) if(fbo_oversized) { width = (GLuint)((float)(width)*1.4f); height = (GLuint)((float)(height)*1.4f); fov *= 1.6; } // choose render target glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fbo->getID()); postProgram->second->optionalClearDrawBuffers(fbo->getColorBuffersExt()); fbo->handleTextures(postProgram->second->getMRTclearindex()); runningProgram->second->activateDrawBuffers(fbo->getColorBuffersExt()); runningProgram->second->bindTextures(fbo); }
Splatterer::Splatterer( const Logger* logger, const Context* context, GLfloat viewportSize, QString textureFilename, BufferTexture* baseDiscomfort) : pointBuffer(0), screenSizedQuadBuffer(0), framebufferObject(0), densityDiscomfortVelocity(NULL), splatAreas(NULL), agent(NULL), splatAttribVertex(-1), splatProgram(NULL), splatVertexShader(NULL), splatGeometryShader(NULL), splatFragmentShader(NULL), camera(NULL), bufferSideLength(viewportSize), totalBufferSize(0), densityDiscomfortVelocityTripple(NULL), logger(logger), context(context), prepareFramebufferRenderer(NULL), discomfortProgram(NULL), discomfortVertexShader(NULL), discomfortGeometryShader(NULL), discomfortFragmentShader(NULL), discomfortFactor(NULL), discomfortRadius(NULL), discomfortPosition(NULL) { attachments[0] = GL_COLOR_ATTACHMENT0; attachments[1] = GL_COLOR_ATTACHMENT1; initCamera(); initSplatShaderProgram(); initAttribs(); initVBO(); initUniforms(); initFramebufferObject(); try { // // Create splatted texture // QImage image = Texture::loadTexture(textureFilename, false, true); uint pixelCount = image.width() * image.height(); std::vector<float> data(pixelCount * 4); Texture::convertToFloats(image, data, pixelCount); glActiveTexture(GL_TEXTURE0); agent = new Texture2D(image.width(), image.height(), GL_CLAMP_TO_EDGE, GL_LINEAR, GL_LINEAR, GL_RGBA32F, GL_RGBA, GL_FLOAT, &data[0]); totalBufferSize += image.width() * image.height() * 4 * 4; } catch (Exception& e) { throw Exception("Could not load splatting texture: " + e.message); } // // Create buffer object for density, discomfort and velocity // size_t bufferByteSize = bufferSideLength * bufferSideLength * sizeof(GLfloat) * 4; densityDiscomfortVelocityTripple = new TextureBufferTripple(bufferByteSize, NULL, GL_DYNAMIC_COPY, GL_RGBA32F, CL_MEM_READ_WRITE, context); totalBufferSize += bufferByteSize; // // Create renderer to render base discomfort map to framebuffer // std::vector<QString> filenamesVert; std::vector<QString> filenamesFrag; filenamesVert.push_back("src/shaders/shared.vert"); filenamesFrag.push_back("src/shaders/shared.frag"); filenamesFrag.push_back("src/shaders/prepareFramebuffer.frag"); prepareFramebufferRenderer = new TextureRenderer(bufferSideLength, baseDiscomfort, filenamesVert, filenamesFrag, "Framebuffer Preparation Shader", false); // // Create shader to render discomfort at pointer to framebuffer // initDiscomfortShaderProgram(); }