//! Initialize the frame buffer objects. void initFBOs() { invariant(); Q_ASSERT_X(useFBO(), Q_FUNC_INFO, "We're not using FBO"); if (NULL == backBuffer) { Q_ASSERT_X(NULL == frontBuffer, Q_FUNC_INFO, "frontBuffer is not null even though backBuffer is"); // If non-power-of-two textures are supported, // FBOs must have power of two size large enough to fit the viewport. const QSize bufferSize = nonPowerOfTwoTexturesSupported ? StelUtils::smallestPowerOfTwoSizeGreaterOrEqualTo(viewportSize) : viewportSize; // We want a depth and stencil buffer attached to our FBO if possible. const QGLFramebufferObject::Attachment attachment = QGLFramebufferObject::CombinedDepthStencil; backBuffer = new QGLFramebufferObject(bufferSize, attachment); frontBuffer = new QGLFramebufferObject(bufferSize, attachment); Q_ASSERT_X(backBuffer->isValid() && frontBuffer->isValid(), Q_FUNC_INFO, "Framebuffer objects failed to initialize"); } invariant(); }
//! Swap front and back buffers, when using FBO. void swapFBOs() { invariant(); Q_ASSERT_X(useFBO(), Q_FUNC_INFO, "We're not using FBO"); QGLFramebufferObject* tmp = backBuffer; backBuffer = frontBuffer; frontBuffer = tmp; invariant(); }
void calculateNextPos2(vector<glm::vec3> &particle, FBOstruct *fboPos, FBOstruct *fboOldPos, FBOstruct *fboVel, FBOstruct *fboOldVel, Model* squareModel, GLuint velocityEulerShader, GLuint pass, GLuint PositionEulerShader) { ReloadModelData(squareModel); //update old velosity glUseProgram(pass); useFBO(fboOldVel, fboVel, 0L); glClearColor(0.0, 0.0, 0.0, 0); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); DrawModel(squareModel, pass, "in_Position", NULL, "in_TexCoord"); //old position is updated to current position glUseProgram(pass); useFBO(fboOldPos, fboPos, 0L); glClearColor(0.0, 0.0, 0.0, 0); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); DrawModel(squareModel, pass, "in_Position", NULL, "in_TexCoord"); //update velosity glUseProgram(velocityEulerShader); use2FBO(fboVel, fboOldVel, fboOldPos, velocityEulerShader); glClearColor(0.0, 0.0, 0.0, 0); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); DrawModel(squareModel, velocityEulerShader, "in_Position", NULL, "in_TexCoord"); //current position is updated to new position, need currnt position therfor updated old position first glUseProgram(PositionEulerShader); use2FBO(fboPos, fboVel, fboOldPos, PositionEulerShader); glClearColor(0.0, 0.0, 0.0, 0); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); DrawModel(squareModel, PositionEulerShader, "in_Position", NULL, "in_TexCoord"); // position vector is updated const size_t SIZE = nrOfParticlesVertically*nrOfParticlesHorizontally * 4; float particlePixels[SIZE]; glReadPixels(0, 0, nrOfParticlesVertically*nrOfParticlesHorizontally, 1, GL_RGBA, GL_FLOAT, particlePixels); for (int i = 0, j = 0; i < particle.size(); i++, j += 4) { //cout << "Position vector: " << particlePixels[j] << " " << particlePixels[j + 1] << " " << particlePixels[j + 2] << endl; particle.at(i).x = particlePixels[j]; particle.at(i).y = particlePixels[j + 1]; particle.at(i).z = particlePixels[j + 2]; }; }
//! Code that must run before drawing the final result of the rendering to the viewport. void prepareToDrawViewport() { invariant(); //Put the result of drawing to the FBO on the screen, applying an effect. if (useFBO()) { Q_ASSERT_X(!backBuffer->isBound() && !frontBuffer->isBound(), Q_FUNC_INFO, "Framebuffer objects weren't released before drawing the result"); } }
//! Start using drawing calls. void startFrame() { invariant(); if (useFBO()) { //Draw to backBuffer. initFBOs(); backBuffer->bind(); backBufferPainter = new QPainter(backBuffer); enablePainting(backBufferPainter); } else { enablePainting(); } drawing = true; invariant(); }
FBO *createFBO(s32 width, s32 height, bool hd) { // save current FBO FBO *oldFBO = getFBOUsed(); GLuint framebuffer; GLuint depthRenderbuffer; width = width; height = height; s32 texturePtrId = createTexture(0, 0); setTexture(texturePtrId, width, height, 3, NULL); Texture *tex = getTexture(texturePtrId); // create depth renderbuffer glGenRenderbuffersOES(1, &depthRenderbuffer); glBindRenderbufferOES(GL_RENDERBUFFER_OES, depthRenderbuffer); glRenderbufferStorageOES(GL_RENDERBUFFER_OES, GL_DEPTH_COMPONENT16_OES, width, height); // bind framebuffer & attach texture glGenFramebuffersOES(1, &framebuffer); glBindFramebufferOES(GL_FRAMEBUFFER_OES, framebuffer); glFramebufferTexture2DOES(GL_FRAMEBUFFER_OES, GL_COLOR_ATTACHMENT0_OES, GL_TEXTURE_2D, tex->mTextureId, 0); glFramebufferRenderbufferOES(GL_FRAMEBUFFER_OES, GL_DEPTH_ATTACHMENT_OES, GL_RENDERBUFFER_OES, depthRenderbuffer); // check binding if (glCheckFramebufferStatusOES(GL_FRAMEBUFFER_OES) != GL_FRAMEBUFFER_COMPLETE_OES) { logError(TAG, "CRITICAL ERROR: FBO no complete"); return 0; } // save info into structure FBO *fbo = (FBO *)malloc(sizeof(FBO)); fbo->mFBO = framebuffer; fbo->mWidth = width; fbo->mHeight = height; fbo->mTexturePtrId = texturePtrId; fbo->mDepthRenderBuffer = depthRenderbuffer; // restore FBO useFBO(oldFBO); return fbo; }
//! Finish using draw calls. void finishFrame(const bool swapBuffers = true) { invariant(); drawing = false; disablePainting(); if (useFBO()) { //Release the backbuffer. delete backBufferPainter; backBufferPainter = NULL; backBuffer->release(); //Swap buffers if finishing, don't swap yet if suspending. if(swapBuffers){swapFBOs();} } invariant(); }
//! Asserts that we're in a valid state. void invariant() const { #ifndef NDEBUG Q_ASSERT_X(NULL != glWidget, Q_FUNC_INFO, "Destroyed StelQGLViewport"); Q_ASSERT_X(glWidget->isValid(), Q_FUNC_INFO, "Invalid glWidget (maybe there is no OpenGL support?)"); const bool fbo = useFBO(); Q_ASSERT_X(NULL == backBufferPainter || fbo, Q_FUNC_INFO, "We have a backbuffer painter even though we're not using FBO"); Q_ASSERT_X(drawing && fbo ? backBufferPainter != NULL : true, Q_FUNC_INFO, "We're drawing and using FBOs, but the backBufferPainter is NULL"); Q_ASSERT_X(NULL == backBuffer || fbo, Q_FUNC_INFO, "We have a backbuffer even though we're not using FBO"); Q_ASSERT_X(NULL == frontBuffer || fbo, Q_FUNC_INFO, "We have a frontbuffer even though we're not using FBO"); Q_ASSERT_X(drawing && fbo ? backBuffer != NULL : true, Q_FUNC_INFO, "We're drawing and using FBOs, but the backBuffer is NULL"); Q_ASSERT_X(drawing && fbo ? frontBuffer != NULL : true, Q_FUNC_INFO, "We're drawing and using FBOs, but the frontBuffer is NULL"); #endif }
//! Suspend drawing, not showing the result on the screen. //! //! Finishes using draw calls for this frame. //! Drawing can continue later. Only usable with FBOs. void suspendFrame() { Q_ASSERT_X(useFBO(), Q_FUNC_INFO, "Partial rendering only works with FBOs"); finishFrame(false); }
void display(void) { //Update matrices and light to scene transformation int backup = 1; updateScene(); lightPosition = SetVector(sphereModelMatrix.m[3],sphereModelMatrix.m[7],sphereModelMatrix.m[11]); //Create DepthMaps if(backup == 1){ //DRAW __ALL__ PHONG OBJECTS TO THE SAME FBO (+ Depth test! ) useFBO(fbo_phong,0L,0L); glUseProgram(phongshader); glClearColor(0.2, 0.0, 0.0, 1.0); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); //Send info that is the same for all objects (projection, view matrix, light etc) glUniformMatrix4fv(glGetUniformLocation(phongshader, "projMatrix"), 1, GL_TRUE, projectionMatrix.m); glUniformMatrix4fv(glGetUniformLocation(phongshader, "viewMatrix"), 1, GL_TRUE, viewMatrix.m); glUniform3f(glGetUniformLocation(phongshader, "camPosition"),cam.x,cam.y,cam.z); glUniform1i(glGetUniformLocation(phongshader, "texUnit"), 0); glUniform3f(glGetUniformLocation(phongshader,"lightPosition"), lightPosition.x, lightPosition.y, lightPosition.z); glUniform3f(glGetUniformLocation(phongshader,"lightColor"), lightColor.x, lightColor.y, lightColor.z); //Enable depth tests and all that // Enable Z-buffering glEnable(GL_DEPTH_TEST); // Enable backface culling glEnable(GL_CULL_FACE); glCullFace(GL_BACK); drawSinglePhongObject(bunny, modelMatrix, bunnyColor.x,bunnyColor.y, bunnyColor.z); drawSinglePhongObject(statue, statueMatrix, 0.3,0.7,0.4); drawSinglePhongObject(box, boxMatrix, 1.0,0.2,0.5); drawSinglePhongObject(bottom, bottomModelMatrix, sceneColor.x, sceneColor.y, sceneColor.z); drawSinglePhongObject(side1, side1ModelMatrix, sceneColor.x, sceneColor.y, sceneColor.z); drawSinglePhongObject(side2, side2ModelMatrix, sceneColor.x, sceneColor.y, sceneColor.z); //ALL LIGHTSURFACES (SAME FBO as PHONG) glUseProgram(lightShader); glUniformMatrix4fv(glGetUniformLocation(lightShader, "projMatrix"), 1, GL_TRUE, projectionMatrix.m); glUniformMatrix4fv(glGetUniformLocation(lightShader, "viewMatrix"), 1, GL_TRUE, viewMatrix.m); //sphere glUniformMatrix4fv(glGetUniformLocation(lightShader, "modelMatrix"), 1, GL_TRUE, sphereModelMatrix.m); DrawModel(sphere, lightShader, "in_Position", NULL, NULL); //DRAW ALL TRANSLUCENT OBJECTS TO ANOTHER FBO useFBO(fbo_sub, 0L, 0L); glClearColor(0.0, 0.0, 0.0, 1.0); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glUseProgram(shader); glUniformMatrix4fv(glGetUniformLocation(shader, "projMatrix"), 1, GL_TRUE, projectionMatrix.m); glUniformMatrix4fv(glGetUniformLocation(shader, "viewMatrix"), 1, GL_TRUE, viewMatrix.m); glUniform3f(glGetUniformLocation(shader, "camPosition"),cam.x,cam.y,cam.z); glUniform3f(glGetUniformLocation(shader,"lightPosition"), lightPosition.x, lightPosition.y, lightPosition.z); glUniform1i(glGetUniformLocation(shader, "texUnit"), 0); // Enable Z-buffering glDisable(GL_CULL_FACE); //bunny drawSingleTranslucentObject(thicknessBunny , bunny, modelMatrix, bunnyColor.x,bunnyColor.y, bunnyColor.z); drawSingleTranslucentObject(thicknessStatue, statue, statueMatrix, 0.3,0.7,0.4); drawSingleTranslucentObject(thicknessBox, box, boxMatrix, 1.0,0.2,0.5); //JOIN SHADER useFBO(fbo3, fbo_phong, fbo_sub); //write to fbo3, read from fbo2 and from fbo1 glUseProgram(joinshader); glUniform1i(glGetUniformLocation(joinshader, "texUnit"), 0); glUniform1i(glGetUniformLocation(joinshader, "texUnit2"), 1); glDisable(GL_CULL_FACE); glDisable(GL_DEPTH_TEST); DrawModel(squareModel, joinshader, "in_Position", NULL, "in_TexCoord"); //Pass on Shader useFBO(0L, fbo3, 0L); glClearColor(0.0, 0.0, 0.0, 0); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glUseProgram(passShader); glUniform1i(glGetUniformLocation(passShader, "texUnit"), 0); glDisable(GL_CULL_FACE); glDisable(GL_DEPTH_TEST); DrawModel(squareModel, passShader, "in_Position", NULL, "in_TexCoord"); } else{ vec3 cameraPosition = cam; lightViewMatrix = lookAt(lightPosition.x, lightPosition.y, lightPosition.z, point.x, point.y, point.z, 0,1,0); // Setup the view from the light source viewMatrix = lightViewMatrix; //Setup projection matrix // 1. render scene to FBO 1 with Back culling useFBO(fbo_depth, NULL, NULL); glViewport(0,0,W,H); glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_TRUE); // Depth only glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); //Using the simple shader glUseProgram(plainShaderId); glUniform1i(plainShaderId,TEX_UNIT); glActiveTexture(GL_TEXTURE0 + TEX_UNIT); glBindTexture(GL_TEXTURE_2D,0); glCullFace(GL_BACK); printf("%s\n", "mohahahaha"); drawObjectsFirstPass(plainShaderId); // 1. render scene to FBO 2 useFBO(fbo_depth2, NULL, NULL); glViewport(0,0,W,H); glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_TRUE); // Depth only glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); //Using the simple shader with front culling glUseProgram(plainShaderId); glUniform1i(plainShaderId,TEX_UNIT); glActiveTexture(GL_TEXTURE1 + TEX_UNIT); glBindTexture(GL_TEXTURE_2D,1); glCullFace(GL_FRONT); printf("%s\n", "mohahahaha"); drawObjectsFirstPass(plainShaderId); // Render from Camera //Move camera back to original camera position //zprInit(&viewMatrix, camtemp,point); useFBO(NULL, fbo_depth, fbo_depth2); glViewport(0,0,W,H); //Enabling color write (previously disabled for light POV z-buffer rendering) glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); // Clear previous frame values glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); //Using the projTex shader glUseProgram(projTexShaderId2); glUniform1i(glGetUniformLocation(projTexShaderId2, "texxxUnit"), 0); glUniform1i(glGetUniformLocation(projTexShaderId2, "texxxUnit2"), 1); glUniform1i(projTexMapUniform,TEX_UNIT); glActiveTexture(GL_TEXTURE0 + TEX_UNIT); glBindTexture(GL_TEXTURE_2D,fbo_depth->depth); glUniform1i(projTexMapUniform,TEX_UNIT); glActiveTexture(GL_TEXTURE1 + TEX_UNIT); glBindTexture(GL_TEXTURE_2D,fbo_depth2->depth); // Setup the modelview from the camera // modelViewMatrix = lookAt(p_camera.x, p_camera.y, p_camera.z, // l_camera.x, l_camera.y, l_camera.z, 0,1,0); // Setup the view from the light source // viewMatrix = lookAt(cameraPosition.x, cameraPosition.y, cameraPosition.z, // point.x, point.y, point.z, 0,1,0); printf("%s\n", "yakiyakiyaki"); glCullFace(GL_BACK); drawObjects(projTexShaderId2); } //Reset scene transformation sceneModelMatrix = IdentityMatrix(); }
/************************* * Use the GPGPU Shader * *************************/ void calculateNextPos(vector<glm::vec3> &particle, FBOstruct *fboPos, FBOstruct *fboOldPos, FBOstruct *fboVel, FBOstruct *fboOldVel, GLuint velocityEulerShader, GLuint pass, GLuint PositionEulerShader) { // en enkel fyrkant att rita på GLfloat square[] = { -1, -1, 0, -1, 1, 0, 1, 1, 0, 1, -1, 0 }; GLfloat squareTexCoord[] = { 0, 0, 0, 1, 1, 1, 1, 0 }; GLuint squareIndices[] = { 0, 1, 2, 0, 2, 3 }; Model* squareModel = LoadDataToModel( square, NULL, squareTexCoord, NULL, squareIndices, 4, 6); glUseProgram(velocityEulerShader); use2FBO(fboVel, fboOldVel, fboOldPos, velocityEulerShader); glClearColor(0.0, 0.0, 0.0, 0); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); //send shared varible to shader, only need to be done the first time glUniform1f(glGetUniformLocation(velocityEulerShader, "nrOfParticlesVertically"), nrOfParticlesVertically); glUniform1f(glGetUniformLocation(velocityEulerShader, "nrOfParticlesHorizontally"), nrOfParticlesHorizontally); glUniform1f(glGetUniformLocation(velocityEulerShader, "timestep"), timestep); glUniform1f(glGetUniformLocation(velocityEulerShader, "particleMass"), particleMass); glUniform3f(glGetUniformLocation(velocityEulerShader, "g"), g.x, g.y, g.z); glUniform1f(glGetUniformLocation(velocityEulerShader, "kSt"), kSt); glUniform1f(glGetUniformLocation(velocityEulerShader, "kSh"), kSh); glUniform1f(glGetUniformLocation(velocityEulerShader, "kB"), kB); glUniform1f(glGetUniformLocation(velocityEulerShader, "oaSt"), oaSt); glUniform1f(glGetUniformLocation(velocityEulerShader, "oaSh"), oaSh); glUniform1f(glGetUniformLocation(velocityEulerShader, "oaB"), oaB); glUniform1f(glGetUniformLocation(velocityEulerShader, "cSt"), cSt); glUniform1f(glGetUniformLocation(velocityEulerShader, "cSh"), cSh); glUniform1f(glGetUniformLocation(velocityEulerShader, "cB"), cB); DrawModel(squareModel, velocityEulerShader, "in_Position", NULL, "in_TexCoord"); glUseProgram(pass); useFBO(fboOldVel, fboVel, 0L); //MÅSTE VARA PÅ VÄNSTER SIDA!!!!! glClearColor(0.0, 0.0, 0.0, 0); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); DrawModel(squareModel, pass, "in_Position", NULL, "in_TexCoord"); //old position is updated to current position useFBO(fboOldPos, fboPos, 0L); glClearColor(0.0, 0.0, 0.0, 0); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); DrawModel(squareModel, pass, "in_Position", NULL, "in_TexCoord"); //current position is updated to new position, need currnt position therfor updated ond position first glUseProgram(PositionEulerShader); use2FBO(fboPos, fboVel, fboOldPos, PositionEulerShader); glClearColor(0.0, 0.0, 0.0, 0); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glUniform1f(glGetUniformLocation(PositionEulerShader, "timestep"), timestep); DrawModel(squareModel, PositionEulerShader, "in_Position", NULL, "in_TexCoord"); const size_t SIZE = nrOfParticlesVertically*nrOfParticlesHorizontally * 4; float particlePixels[SIZE]; glReadPixels(0, 0, nrOfParticlesVertically*nrOfParticlesHorizontally, 1, GL_RGBA, GL_FLOAT, particlePixels); for (int i = 0, j = 0; i < particle.size(); i++, j += 4) { //cout << "Position vector: " << particlePixels[j] << " " << particlePixels[j + 1] << " " << particlePixels[j + 2] << endl; particle.at(i).x = particlePixels[j]; particle.at(i).y = particlePixels[j + 1]; particle.at(i).z = particlePixels[j + 2]; }; }
/************************************** * Create initial textures on the FBOs* **************************************/ void initGPGPU(FBOstruct *fboPos, FBOstruct *fboOldPos, FBOstruct *fboVel, FBOstruct *fboOldVel) { // en enkel fyrkant att rita på GLfloat square[] = {-1, -1, 0, -1, 1, 0, 1, 1, 0, 1, -1, 0 }; GLfloat squareTexCoord[] = {0, 0, 0, 1, 1, 1, 1, 0 }; GLuint squareIndices[] = { 0, 1, 2, 0, 2, 3 }; Model* squareModel = LoadDataToModel(square, NULL, squareTexCoord, NULL,squareIndices, 4, 6); GLuint initVelosity = loadShaders("Shaders/initVelocityVertexShader.glsl", "Shaders/initVelocityFragmentShader.glsl"); GLuint passOverValues = loadShaders("Shaders/passVertexShader.glsl", "Shaders/passFragmentShader.glsl"); GLuint initPosition = loadShaders("Shaders/initPositionVertexShader.glsl", "Shaders/initPositionFragmentShader.glsl"); /**************** * Velosity FBO * ****************/ useFBO(fboVel, 0L, 0L); glClearColor(0.0, 0.0, 0.0, 0); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glUseProgram(initVelosity); GLint locHeight = glGetUniformLocation(initVelosity, "height"); GLint locWidth = glGetUniformLocation(initVelosity, "width"); if (locHeight != -1 && locWidth != -1) { glUniform1f(locWidth, nrOfParticlesHorizontally); glUniform1f(locHeight, nrOfParticlesVertically); } DrawModel(squareModel, initVelosity, "in_Position", NULL, "in_TexCoord"); /****************************************************** * Old velosity * * The same sa velosity, so just pass over the values * ******************************************************/ useFBO(fboOldVel, fboVel, 0L); glClearColor(0.0, 0.0, 0.0, 0); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glUseProgram(passOverValues); DrawModel(squareModel, passOverValues, "in_Position", NULL, "in_TexCoord"); //test so everything whent fine //const size_t SIZE = nrOfParticlesVertically*nrOfParticlesHorizontally * 4; //float particlePixels[SIZE]; /*glReadPixels(0, 0, nrOfParticlesVertically*nrOfParticlesHorizontally, 1, GL_RGBA, GL_FLOAT, particlePixels); for (int j = 0; j < SIZE; j += 4) { cout << " Init velosity: " << particlePixels[j] << " " << particlePixels[j + 1] << " " << particlePixels[j + 2] << " " << particlePixels[j + 3] << endl; }*/ /*************** * Position FBO * ****************/ useFBO(fboPos, 0L, 0L); glClearColor(0.0, 0.0, 0.0, 0); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glUseProgram(initPosition); locHeight = glGetUniformLocation(initPosition, "height"); locWidth = glGetUniformLocation(initPosition, "width"); GLint locSpringLenght = glGetUniformLocation(initPosition, "springRestLenght"); if (locHeight != -1 && locWidth != -1 && locSpringLenght != -1) { glUniform1f(locWidth, nrOfParticlesHorizontally); glUniform1f(locHeight, nrOfParticlesVertically); glUniform1f(locSpringLenght, springRestLenght); } DrawModel(squareModel, initPosition, "in_Position", NULL, "in_TexCoord"); /****************************************************** * Old Position * * The same sa position, so just pass over the values * ******************************************************/ useFBO(fboOldPos, fboPos, 0L); glClearColor(0.0, 0.0, 0.0, 0); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glUseProgram(passOverValues); DrawModel(squareModel, passOverValues, "in_Position", NULL, "in_TexCoord"); }