Program.cpp revision 6926c72e25b8dec3dd4b84af0819fa1937ae7296
1/* 2 * Copyright (C) 2010 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#define LOG_TAG "OpenGLRenderer" 18 19#include "Program.h" 20 21namespace android { 22namespace uirenderer { 23 24/////////////////////////////////////////////////////////////////////////////// 25// Shaders 26/////////////////////////////////////////////////////////////////////////////// 27 28#define SHADER_SOURCE(name, source) const char* name = #source 29 30#include "shaders/drawColor.vert" 31#include "shaders/drawColor.frag" 32 33#include "shaders/drawTexture.vert" 34#include "shaders/drawTexture.frag" 35 36/////////////////////////////////////////////////////////////////////////////// 37// Base program 38/////////////////////////////////////////////////////////////////////////////// 39 40Program::Program(const char* vertex, const char* fragment) { 41 vertexShader = buildShader(vertex, GL_VERTEX_SHADER); 42 fragmentShader = buildShader(fragment, GL_FRAGMENT_SHADER); 43 44 id = glCreateProgram(); 45 glAttachShader(id, vertexShader); 46 glAttachShader(id, fragmentShader); 47 glLinkProgram(id); 48 49 GLint status; 50 glGetProgramiv(id, GL_LINK_STATUS, &status); 51 if (status != GL_TRUE) { 52 GLint infoLen = 0; 53 glGetProgramiv(id, GL_INFO_LOG_LENGTH, &infoLen); 54 if (infoLen > 1) { 55 char* log = (char*) malloc(sizeof(char) * infoLen); 56 glGetProgramInfoLog(id, infoLen, 0, log); 57 LOGE("Error while linking shaders: %s", log); 58 delete log; 59 } 60 glDeleteProgram(id); 61 } 62 63 mUse = false; 64} 65 66Program::~Program() { 67 glDeleteShader(vertexShader); 68 glDeleteShader(fragmentShader); 69 glDeleteProgram(id); 70} 71 72void Program::use() { 73 glUseProgram(id); 74 mUse = true; 75} 76 77void Program::remove() { 78 mUse = false; 79} 80 81int Program::addAttrib(const char* name) { 82 int slot = glGetAttribLocation(id, name); 83 attributes.add(name, slot); 84 return slot; 85} 86 87int Program::getAttrib(const char* name) { 88 return attributes.valueFor(name); 89} 90 91int Program::addUniform(const char* name) { 92 int slot = glGetUniformLocation(id, name); 93 uniforms.add(name, slot); 94 return slot; 95} 96 97int Program::getUniform(const char* name) { 98 return uniforms.valueFor(name); 99} 100 101GLuint Program::buildShader(const char* source, GLenum type) { 102 GLuint shader = glCreateShader(type); 103 glShaderSource(shader, 1, &source, 0); 104 glCompileShader(shader); 105 106 GLint status; 107 glGetShaderiv(shader, GL_COMPILE_STATUS, &status); 108 if (status != GL_TRUE) { 109 // Some drivers return wrong values for GL_INFO_LOG_LENGTH 110 // use a fixed size instead 111 GLchar log[512]; 112 glGetShaderInfoLog(shader, sizeof(log), 0, &log[0]); 113 LOGE("Error while compiling shader: %s", log); 114 glDeleteShader(shader); 115 } 116 117 return shader; 118} 119 120/////////////////////////////////////////////////////////////////////////////// 121// Draw color 122/////////////////////////////////////////////////////////////////////////////// 123 124DrawColorProgram::DrawColorProgram(): 125 Program(gDrawColorVertexShader, gDrawColorFragmentShader) { 126 getAttribsAndUniforms(); 127} 128 129DrawColorProgram::DrawColorProgram(const char* vertex, const char* fragment): 130 Program(vertex, fragment) { 131 getAttribsAndUniforms(); 132} 133 134void DrawColorProgram::getAttribsAndUniforms() { 135 position = addAttrib("position"); 136 color = addUniform("color"); 137 transform = addUniform("transform"); 138} 139 140void DrawColorProgram::set(const mat4& projectionMatrix, const mat4& modelViewMatrix, 141 const mat4& transformMatrix) { 142 mat4 t(projectionMatrix); 143 t.multiply(transformMatrix); 144 t.multiply(modelViewMatrix); 145 146 glUniformMatrix4fv(transform, 1, GL_FALSE, &t.data[0]); 147} 148 149void DrawColorProgram::use() { 150 Program::use(); 151 glEnableVertexAttribArray(position); 152} 153 154void DrawColorProgram::remove() { 155 Program::remove(); 156 glDisableVertexAttribArray(position); 157} 158 159/////////////////////////////////////////////////////////////////////////////// 160// Draw texture 161/////////////////////////////////////////////////////////////////////////////// 162 163DrawTextureProgram::DrawTextureProgram(): 164 DrawColorProgram(gDrawTextureVertexShader, gDrawTextureFragmentShader) { 165 texCoords = addAttrib("texCoords"); 166 sampler = addUniform("sampler"); 167} 168 169void DrawTextureProgram::use() { 170 DrawColorProgram::use(); 171 glActiveTexture(GL_TEXTURE0); 172 glUniform1i(sampler, 0); 173 glEnableVertexAttribArray(texCoords); 174} 175 176void DrawTextureProgram::remove() { 177 DrawColorProgram::remove(); 178 glDisableVertexAttribArray(texCoords); 179} 180 181}; // namespace uirenderer 182}; // namespace android 183