Renderer.cpp revision 1e762b1f935c9d4a06af6dd56121590ca81d48b1
11e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal#include "Renderer.h" 21e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal 31e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal#include <GLES2/gl2ext.h> 41e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal 51e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal#include <android/log.h> 61e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal#define LOG_TAG "Renderer" 71e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal#define LOGI(...) __android_log_print(ANDROID_LOG_INFO,LOG_TAG,__VA_ARGS__) 81e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal#define LOGE(...) __android_log_print(ANDROID_LOG_ERROR,LOG_TAG,__VA_ARGS__) 91e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal 101e762b1f935c9d4a06af6dd56121590ca81d48b1mbansalRenderer::Renderer() 111e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal : mGlProgram(0), 121e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal mInputTextureName(-1), 131e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal mInputTextureWidth(0), 141e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal mInputTextureHeight(0), 151e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal mSurfaceWidth(0), 161e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal mSurfaceHeight(0) 171e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal{ 181e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal InitializeGLContext(); 191e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal} 201e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal 211e762b1f935c9d4a06af6dd56121590ca81d48b1mbansalRenderer::~Renderer() { 221e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal} 231e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal 241e762b1f935c9d4a06af6dd56121590ca81d48b1mbansalGLuint Renderer::loadShader(GLenum shaderType, const char* pSource) { 251e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal GLuint shader = glCreateShader(shaderType); 261e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal if (shader) { 271e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal glShaderSource(shader, 1, &pSource, NULL); 281e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal glCompileShader(shader); 291e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal GLint compiled = 0; 301e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal glGetShaderiv(shader, GL_COMPILE_STATUS, &compiled); 311e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal if (!compiled) { 321e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal GLint infoLen = 0; 331e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &infoLen); 341e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal if (infoLen) { 351e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal char* buf = (char*) malloc(infoLen); 361e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal if (buf) { 371e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal glGetShaderInfoLog(shader, infoLen, NULL, buf); 381e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal LOGE("Could not compile shader %d:\n%s\n", 391e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal shaderType, buf); 401e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal free(buf); 411e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal } 421e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal glDeleteShader(shader); 431e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal shader = 0; 441e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal } 451e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal } 461e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal } 471e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal return shader; 481e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal} 491e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal 501e762b1f935c9d4a06af6dd56121590ca81d48b1mbansalGLuint Renderer::createProgram(const char* pVertexSource, const char* pFragmentSource) 511e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal{ 521e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal GLuint vertexShader = loadShader(GL_VERTEX_SHADER, pVertexSource); 531e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal if (!vertexShader) 541e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal { 551e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal return 0; 561e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal } 571e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal LOGI("VertexShader Loaded!"); 581e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal 591e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal GLuint pixelShader = loadShader(GL_FRAGMENT_SHADER, pFragmentSource); 601e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal if (!pixelShader) 611e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal { 621e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal return 0; 631e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal } 641e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal LOGI("FragmentShader Loaded!"); 651e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal 661e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal GLuint program = glCreateProgram(); 671e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal if (program) 681e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal { 691e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal glAttachShader(program, vertexShader); 701e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal checkGlError("glAttachShader"); 711e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal glAttachShader(program, pixelShader); 721e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal checkGlError("glAttachShader"); 731e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal 741e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal LOGI("Shaders Attached!"); 751e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal 761e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal glLinkProgram(program); 771e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal GLint linkStatus = GL_FALSE; 781e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal glGetProgramiv(program, GL_LINK_STATUS, &linkStatus); 791e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal 801e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal LOGI("Program Linked!"); 811e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal 821e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal if (linkStatus != GL_TRUE) 831e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal { 841e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal GLint bufLength = 0; 851e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal glGetProgramiv(program, GL_INFO_LOG_LENGTH, &bufLength); 861e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal if (bufLength) 871e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal { 881e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal char* buf = (char*) malloc(bufLength); 891e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal if (buf) 901e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal { 911e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal glGetProgramInfoLog(program, bufLength, NULL, buf); 921e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal LOGE("Could not link program:\n%s\n", buf); 931e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal free(buf); 941e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal } 951e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal } 961e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal glDeleteProgram(program); 971e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal program = 0; 981e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal } 991e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal } 1001e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal return program; 1011e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal} 1021e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal 1031e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal// Set this renderer to use the default frame-buffer (screen) and 1041e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal// set the viewport size to be the given width and height (pixels). 1051e762b1f935c9d4a06af6dd56121590ca81d48b1mbansalbool Renderer::SetupGraphics(int width, int height) 1061e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal{ 1071e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal bool succeeded = false; 1081e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal do { 1091e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal if (mGlProgram == 0) 1101e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal { 1111e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal if (!InitializeGLProgram()) 1121e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal { 1131e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal break; 1141e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal } 1151e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal } 1161e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal glUseProgram(mGlProgram); 1171e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal if (!checkGlError("glUseProgram")) break; 1181e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal 1191e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal glBindFramebuffer(GL_FRAMEBUFFER, 0); 1201e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal 1211e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal mFrameBuffer = NULL; 1221e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal mSurfaceWidth = width; 1231e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal mSurfaceHeight = height; 1241e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal 1251e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal glViewport(0, 0, mSurfaceWidth, mSurfaceHeight); 1261e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal if (!checkGlError("glViewport")) break; 1271e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal succeeded = true; 1281e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal } while (false); 1291e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal 1301e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal return succeeded; 1311e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal} 1321e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal 1331e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal 1341e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal// Set this renderer to use the specified FBO and 1351e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal// set the viewport size to be the width and height of this FBO. 1361e762b1f935c9d4a06af6dd56121590ca81d48b1mbansalbool Renderer::SetupGraphics(FrameBuffer* buffer) 1371e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal{ 1381e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal bool succeeded = false; 1391e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal do { 1401e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal if (mGlProgram == 0) 1411e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal { 1421e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal if (!InitializeGLProgram()) 1431e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal { 1441e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal break; 1451e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal } 1461e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal } 1471e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal glUseProgram(mGlProgram); 1481e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal if (!checkGlError("glUseProgram")) break; 1491e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal 1501e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal glBindFramebuffer(GL_FRAMEBUFFER, buffer->GetFrameBufferName()); 1511e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal 1521e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal mFrameBuffer = buffer; 1531e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal mSurfaceWidth = mFrameBuffer->GetWidth(); 1541e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal mSurfaceHeight = mFrameBuffer->GetHeight(); 1551e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal 1561e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal glViewport(0, 0, mSurfaceWidth, mSurfaceHeight); 1571e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal if (!checkGlError("glViewport")) break; 1581e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal succeeded = true; 1591e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal } while (false); 1601e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal 1611e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal return succeeded; 1621e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal} 1631e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal 1641e762b1f935c9d4a06af6dd56121590ca81d48b1mbansalbool Renderer::Clear(float r, float g, float b, float a) 1651e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal{ 1661e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal bool succeeded = false; 1671e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal do { 1681e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal bool rt = (mFrameBuffer == NULL)? 1691e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal SetupGraphics(mSurfaceWidth, mSurfaceHeight) : 1701e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal SetupGraphics(mFrameBuffer); 1711e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal 1721e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal if(!rt) 1731e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal break; 1741e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal 1751e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal glClearColor(r, g, b, a); 1761e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal glClear(GL_COLOR_BUFFER_BIT); 1771e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal 1781e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal succeeded = true; 1791e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal } while (false); 1801e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal return succeeded; 1811e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal 1821e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal} 1831e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal 1841e762b1f935c9d4a06af6dd56121590ca81d48b1mbansalvoid Renderer::InitializeGLContext() 1851e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal{ 1861e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal if(mFrameBuffer != NULL) 1871e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal { 1881e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal delete mFrameBuffer; 1891e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal mFrameBuffer = NULL; 1901e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal } 1911e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal 1921e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal mInputTextureName = -1; 1931e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal mInputTextureType = GL_TEXTURE_2D; 1941e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal mGlProgram = 0; 1951e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal} 1961e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal 1971e762b1f935c9d4a06af6dd56121590ca81d48b1mbansalint Renderer::GetTextureName() 1981e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal{ 1991e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal return mInputTextureName; 2001e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal} 2011e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal 2021e762b1f935c9d4a06af6dd56121590ca81d48b1mbansalvoid Renderer::SetInputTextureName(GLuint textureName) 2031e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal{ 2041e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal mInputTextureName = textureName; 2051e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal} 2061e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal 2071e762b1f935c9d4a06af6dd56121590ca81d48b1mbansalvoid Renderer::SetInputTextureType(GLenum textureType) 2081e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal{ 2091e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal mInputTextureType = textureType; 2101e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal} 2111e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal 2121e762b1f935c9d4a06af6dd56121590ca81d48b1mbansalvoid Renderer::SetInputTextureDimensions(int width, int height) 2131e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal{ 2141e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal mInputTextureWidth = width; 2151e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal mInputTextureHeight = height; 2161e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal} 217