You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
198 lines
6.4 KiB
198 lines
6.4 KiB
/*
|
|
* Copyright (C) 2013 The Android Open Source Project
|
|
*
|
|
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
|
|
* in compliance with the License. You may obtain a copy of the License at
|
|
*
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
*
|
|
* Unless required by applicable law or agreed to in writing, software distributed under the License
|
|
* is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
|
|
* or implied. See the License for the specific language governing permissions and limitations under
|
|
* the License.
|
|
*/
|
|
#include "GlowingScene.h"
|
|
#include "BlurMeshNode.h"
|
|
|
|
#include <Trace.h>
|
|
|
|
#include <graphics/PerspectiveMeshNode.h>
|
|
#include <graphics/PerspectiveProgram.h>
|
|
#include <graphics/Program.h>
|
|
#include <graphics/GLUtils.h>
|
|
#include <graphics/Mesh.h>
|
|
#include <graphics/ProgramNode.h>
|
|
#include <graphics/TransformationNode.h>
|
|
|
|
GlowingScene::GlowingScene(int width, int height) :
|
|
Scene(width, height), mFboId(0), mMainProgram(NULL), mBlurProgram(NULL) {
|
|
mFboWidth = GLUtils::roundUpToSmallestPowerOf2(width);
|
|
mFboHeight = GLUtils::roundUpToSmallestPowerOf2(height);
|
|
mFboRatio = mFboWidth / mFboHeight;
|
|
mFboModelMatrix = setUpModelMatrix();
|
|
mFboViewMatrix = setUpViewMatrix();
|
|
mFboProjectionMatrix = setUpProjectionMatrix(mFboWidth, mFboHeight);
|
|
}
|
|
|
|
bool GlowingScene::setUpContext() {
|
|
if (!Scene::setUpContext()) {
|
|
return false;
|
|
}
|
|
// Create a fbo
|
|
glGenFramebuffers(1, &mFboId);
|
|
return true;
|
|
}
|
|
|
|
bool GlowingScene::setUpPrograms() {
|
|
// Main Program
|
|
const char* vertex = GLUtils::openTextFile("vertex/perspective");
|
|
const char* fragment = GLUtils::openTextFile("fragment/perspective");
|
|
if (vertex == NULL || fragment == NULL) {
|
|
return false;
|
|
}
|
|
GLuint programId = GLUtils::createProgram(&vertex, &fragment);
|
|
delete[] vertex;
|
|
delete[] fragment;
|
|
if (programId == 0) {
|
|
return false;
|
|
}
|
|
mMainProgram = new PerspectiveProgram(programId);
|
|
// Blur Program
|
|
vertex = GLUtils::openTextFile("vertex/blur");
|
|
fragment = GLUtils::openTextFile("fragment/blur");
|
|
if (vertex == NULL || fragment == NULL) {
|
|
return false;
|
|
}
|
|
programId = GLUtils::createProgram(&vertex, &fragment);
|
|
delete[] vertex;
|
|
delete[] fragment;
|
|
if (programId == 0) {
|
|
return false;
|
|
}
|
|
mBlurProgram = new Program(programId);
|
|
return true;
|
|
}
|
|
|
|
Matrix* GlowingScene::setUpModelMatrix() {
|
|
return new Matrix();
|
|
}
|
|
|
|
Matrix* GlowingScene::setUpViewMatrix() {
|
|
// Position the eye in front of the origin.
|
|
float eyeX = 0.0f;
|
|
float eyeY = 0.0f;
|
|
float eyeZ = 10.0f;
|
|
|
|
// Look at the origin
|
|
float centerX = 0.0f;
|
|
float centerY = 0.0f;
|
|
float centerZ = 0.0f;
|
|
|
|
// Set up vector.
|
|
float upX = 0.0f;
|
|
float upY = 1.0f;
|
|
float upZ = 0.0f;
|
|
|
|
// Set the view matrix.
|
|
return Matrix::newLookAt(eyeX, eyeY, eyeZ, centerX, centerY, centerZ, upX, upY, upZ);
|
|
}
|
|
|
|
Matrix* GlowingScene::setUpProjectionMatrix(float width, float height) {
|
|
// Create a new perspective projection matrix. The height will stay the same
|
|
// while the width will vary as per aspect ratio.
|
|
float ratio = width / height;
|
|
float left = -ratio;
|
|
float right = ratio;
|
|
float bottom = -1.0f;
|
|
float top = 1.0f;
|
|
float near = 8.0f;
|
|
float far = 12.0f;
|
|
|
|
return Matrix::newFrustum(left, right, bottom, top, near, far);
|
|
}
|
|
|
|
bool GlowingScene::setUpTextures() {
|
|
SCOPED_TRACE();
|
|
mTextureIds.push_back(GLUtils::genTexture(mWidth, mHeight, 0)); // fbo
|
|
mTextureIds.push_back(GLUtils::genTexture(mWidth, mHeight, 0)); // tmp1
|
|
mTextureIds.push_back(GLUtils::genTexture(mWidth, mHeight, 0)); // tmp2
|
|
mTextureIds.push_back(GLUtils::loadTexture("texture/arc.png"));
|
|
return true;
|
|
}
|
|
|
|
bool GlowingScene::setUpMeshes() {
|
|
SCOPED_TRACE();
|
|
mMeshes.push_back(GLUtils::loadMesh("mesh/plane.cob"));
|
|
mMeshes.push_back(GLUtils::loadMesh("mesh/arc.cob"));
|
|
return true;
|
|
}
|
|
|
|
bool GlowingScene::tearDown() {
|
|
SCOPED_TRACE();
|
|
if (mMainProgram != NULL) {
|
|
delete mMainProgram;
|
|
mMainProgram = NULL;
|
|
}
|
|
if (mBlurProgram != NULL) {
|
|
delete mBlurProgram;
|
|
mBlurProgram = NULL;
|
|
}
|
|
if (mFboId != 0) {
|
|
glDeleteFramebuffers(1, &mFboId);
|
|
mFboId = 0;
|
|
}
|
|
delete mFboModelMatrix;
|
|
mFboModelMatrix = NULL;
|
|
delete mFboViewMatrix;
|
|
mFboViewMatrix = NULL;
|
|
delete mFboProjectionMatrix;
|
|
mFboProjectionMatrix = NULL;
|
|
return Scene::tearDown();
|
|
}
|
|
|
|
bool GlowingScene::updateSceneGraphs(int frame) {
|
|
// To render the mesh to the FBO
|
|
ProgramNode* lightSceneGraph = new ProgramNode(*mMainProgram);
|
|
mSceneGraphs.push_back(lightSceneGraph);
|
|
MeshNode* meshNode = new PerspectiveMeshNode(mMeshes[1], mTextureIds[3]);
|
|
lightSceneGraph->addChild(meshNode);
|
|
|
|
// To blur the image
|
|
ProgramNode* blurSceneGraph = new ProgramNode(*mBlurProgram);
|
|
mSceneGraphs.push_back(blurSceneGraph);
|
|
meshNode = new BlurMeshNode(mMeshes[0], mTextureIds[0], mTextureIds[1], mTextureIds[2],
|
|
mFboWidth, mFboHeight);
|
|
blurSceneGraph->addChild(meshNode);
|
|
|
|
// Blur To screen
|
|
ProgramNode* glowSceneGraph = new ProgramNode(*mMainProgram);
|
|
mSceneGraphs.push_back(glowSceneGraph);
|
|
Matrix* transformMatrix = Matrix::newScale(mFboRatio, 1.0f, 1.0f);
|
|
TransformationNode* transformNode = new TransformationNode(transformMatrix);
|
|
glowSceneGraph->addChild(transformNode);
|
|
meshNode = new PerspectiveMeshNode(mMeshes[0], mTextureIds[2]);
|
|
transformNode->addChild(meshNode);
|
|
return true;
|
|
}
|
|
|
|
bool GlowingScene::draw() {
|
|
SCOPED_TRACE();
|
|
glBindFramebuffer(GL_FRAMEBUFFER, mFboId); // Use FBO
|
|
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, mTextureIds[0], 0);
|
|
if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) {
|
|
return false;
|
|
}
|
|
glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
|
|
glClear (GL_COLOR_BUFFER_BIT);
|
|
glViewport(0, 0, mFboWidth, mFboHeight);
|
|
mFboModelMatrix->identity();
|
|
mSceneGraphs[0]->drawProgram(*mFboModelMatrix, *mFboViewMatrix, *mFboProjectionMatrix); // Mesh
|
|
mFboModelMatrix->identity();
|
|
mSceneGraphs[1]->drawProgram(*mFboModelMatrix, *mFboViewMatrix, *mFboProjectionMatrix); // Blur
|
|
|
|
glBindFramebuffer(GL_FRAMEBUFFER, 0); // Use Screen
|
|
glViewport(0, 0, mWidth, mHeight);
|
|
Scene::drawSceneGraph(2); // Blur to Screen
|
|
return true;
|
|
}
|