1/* 2 * Copyright (C) 2011 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17#include "Renderer.h" 18 19#include "mosaic/Log.h" 20#define LOG_TAG "Renderer" 21 22#include <GLES2/gl2ext.h> 23 24Renderer::Renderer() 25 : mGlProgram(0), 26 mInputTextureName(-1), 27 mInputTextureWidth(0), 28 mInputTextureHeight(0), 29 mSurfaceWidth(0), 30 mSurfaceHeight(0) 31{ 32 InitializeGLContext(); 33} 34 35Renderer::~Renderer() { 36} 37 38GLuint Renderer::loadShader(GLenum shaderType, const char* pSource) { 39 GLuint shader = glCreateShader(shaderType); 40 if (shader) { 41 glShaderSource(shader, 1, &pSource, NULL); 42 glCompileShader(shader); 43 GLint compiled = 0; 44 glGetShaderiv(shader, GL_COMPILE_STATUS, &compiled); 45 if (!compiled) { 46 GLint infoLen = 0; 47 glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &infoLen); 48 if (infoLen) { 49 char* buf = (char*) malloc(infoLen); 50 if (buf) { 51 glGetShaderInfoLog(shader, infoLen, NULL, buf); 52 LOGE("Could not compile shader %d:\n%s\n", 53 shaderType, buf); 54 free(buf); 55 } 56 glDeleteShader(shader); 57 shader = 0; 58 } 59 } 60 } 61 return shader; 62} 63 64GLuint Renderer::createProgram(const char* pVertexSource, const char* pFragmentSource) 65{ 66 GLuint vertexShader = loadShader(GL_VERTEX_SHADER, pVertexSource); 67 if (!vertexShader) 68 { 69 return 0; 70 } 71 72 GLuint pixelShader = loadShader(GL_FRAGMENT_SHADER, pFragmentSource); 73 if (!pixelShader) 74 { 75 return 0; 76 } 77 78 GLuint program = glCreateProgram(); 79 if (program) 80 { 81 glAttachShader(program, vertexShader); 82 checkGlError("glAttachShader"); 83 glAttachShader(program, pixelShader); 84 checkGlError("glAttachShader"); 85 86 glLinkProgram(program); 87 GLint linkStatus = GL_FALSE; 88 glGetProgramiv(program, GL_LINK_STATUS, &linkStatus); 89 90 LOGI("Program Linked!"); 91 92 if (linkStatus != GL_TRUE) 93 { 94 GLint bufLength = 0; 95 glGetProgramiv(program, GL_INFO_LOG_LENGTH, &bufLength); 96 if (bufLength) 97 { 98 char* buf = (char*) malloc(bufLength); 99 if (buf) 100 { 101 glGetProgramInfoLog(program, bufLength, NULL, buf); 102 LOGE("Could not link program:\n%s\n", buf); 103 free(buf); 104 } 105 } 106 glDeleteProgram(program); 107 program = 0; 108 } 109 } 110 return program; 111} 112 113// Set this renderer to use the default frame-buffer (screen) and 114// set the viewport size to be the given width and height (pixels). 115bool Renderer::SetupGraphics(int width, int height) 116{ 117 bool succeeded = false; 118 do { 119 if (mGlProgram == 0) 120 { 121 if (!InitializeGLProgram()) 122 { 123 break; 124 } 125 } 126 glUseProgram(mGlProgram); 127 if (!checkGlError("glUseProgram")) break; 128 129 glBindFramebuffer(GL_FRAMEBUFFER, 0); 130 131 mFrameBuffer = NULL; 132 mSurfaceWidth = width; 133 mSurfaceHeight = height; 134 135 glViewport(0, 0, mSurfaceWidth, mSurfaceHeight); 136 if (!checkGlError("glViewport")) break; 137 succeeded = true; 138 } while (false); 139 140 return succeeded; 141} 142 143 144// Set this renderer to use the specified FBO and 145// set the viewport size to be the width and height of this FBO. 146bool Renderer::SetupGraphics(FrameBuffer* buffer) 147{ 148 bool succeeded = false; 149 do { 150 if (mGlProgram == 0) 151 { 152 if (!InitializeGLProgram()) 153 { 154 break; 155 } 156 } 157 glUseProgram(mGlProgram); 158 if (!checkGlError("glUseProgram")) break; 159 160 glBindFramebuffer(GL_FRAMEBUFFER, buffer->GetFrameBufferName()); 161 162 mFrameBuffer = buffer; 163 mSurfaceWidth = mFrameBuffer->GetWidth(); 164 mSurfaceHeight = mFrameBuffer->GetHeight(); 165 166 glViewport(0, 0, mSurfaceWidth, mSurfaceHeight); 167 if (!checkGlError("glViewport")) break; 168 succeeded = true; 169 } while (false); 170 171 return succeeded; 172} 173 174bool Renderer::Clear(float r, float g, float b, float a) 175{ 176 bool succeeded = false; 177 do { 178 bool rt = (mFrameBuffer == NULL)? 179 SetupGraphics(mSurfaceWidth, mSurfaceHeight) : 180 SetupGraphics(mFrameBuffer); 181 182 if(!rt) 183 break; 184 185 glClearColor(r, g, b, a); 186 glClear(GL_COLOR_BUFFER_BIT); 187 188 succeeded = true; 189 } while (false); 190 return succeeded; 191 192} 193 194void Renderer::InitializeGLContext() 195{ 196 if(mFrameBuffer != NULL) 197 { 198 delete mFrameBuffer; 199 mFrameBuffer = NULL; 200 } 201 202 mInputTextureName = -1; 203 mInputTextureType = GL_TEXTURE_2D; 204 mGlProgram = 0; 205} 206 207int Renderer::GetTextureName() 208{ 209 return mInputTextureName; 210} 211 212void Renderer::SetInputTextureName(GLuint textureName) 213{ 214 mInputTextureName = textureName; 215} 216 217void Renderer::SetInputTextureType(GLenum textureType) 218{ 219 mInputTextureType = textureType; 220} 221 222void Renderer::SetInputTextureDimensions(int width, int height) 223{ 224 mInputTextureWidth = width; 225 mInputTextureHeight = height; 226} 227