Home | History | Annotate | Download | only in mosaic_renderer
      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 
     24 Renderer::Renderer()
     25       : mGlProgram(0),
     26         mInputTextureName(-1),
     27         mInputTextureWidth(0),
     28         mInputTextureHeight(0),
     29         mSurfaceWidth(0),
     30         mSurfaceHeight(0)
     31 {
     32     InitializeGLContext();
     33 }
     34 
     35 Renderer::~Renderer() {
     36 }
     37 
     38 GLuint 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 
     64 GLuint 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).
    115 bool 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.
    146 bool 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 
    174 bool 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 
    194 void 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 
    207 int Renderer::GetTextureName()
    208 {
    209     return mInputTextureName;
    210 }
    211 
    212 void Renderer::SetInputTextureName(GLuint textureName)
    213 {
    214     mInputTextureName = textureName;
    215 }
    216 
    217 void Renderer::SetInputTextureType(GLenum textureType)
    218 {
    219     mInputTextureType = textureType;
    220 }
    221 
    222 void Renderer::SetInputTextureDimensions(int width, int height)
    223 {
    224     mInputTextureWidth = width;
    225     mInputTextureHeight = height;
    226 }
    227