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