1274ca49c63557a8c3ee12c8da5f75e28b4875a5dWei-Ta Chen/* 2274ca49c63557a8c3ee12c8da5f75e28b4875a5dWei-Ta Chen * Copyright (C) 2011 The Android Open Source Project 3274ca49c63557a8c3ee12c8da5f75e28b4875a5dWei-Ta Chen * 4274ca49c63557a8c3ee12c8da5f75e28b4875a5dWei-Ta Chen * Licensed under the Apache License, Version 2.0 (the "License"); 5274ca49c63557a8c3ee12c8da5f75e28b4875a5dWei-Ta Chen * you may not use this file except in compliance with the License. 6274ca49c63557a8c3ee12c8da5f75e28b4875a5dWei-Ta Chen * You may obtain a copy of the License at 7274ca49c63557a8c3ee12c8da5f75e28b4875a5dWei-Ta Chen * 8274ca49c63557a8c3ee12c8da5f75e28b4875a5dWei-Ta Chen * http://www.apache.org/licenses/LICENSE-2.0 9274ca49c63557a8c3ee12c8da5f75e28b4875a5dWei-Ta Chen * 10274ca49c63557a8c3ee12c8da5f75e28b4875a5dWei-Ta Chen * Unless required by applicable law or agreed to in writing, software 11274ca49c63557a8c3ee12c8da5f75e28b4875a5dWei-Ta Chen * distributed under the License is distributed on an "AS IS" BASIS, 12274ca49c63557a8c3ee12c8da5f75e28b4875a5dWei-Ta Chen * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13274ca49c63557a8c3ee12c8da5f75e28b4875a5dWei-Ta Chen * See the License for the specific language governing permissions and 14274ca49c63557a8c3ee12c8da5f75e28b4875a5dWei-Ta Chen * limitations under the License. 15274ca49c63557a8c3ee12c8da5f75e28b4875a5dWei-Ta Chen */ 16274ca49c63557a8c3ee12c8da5f75e28b4875a5dWei-Ta Chen 17eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal#include "WarpRenderer.h" 18eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal 19eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal#include <GLES2/gl2ext.h> 20eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal 21eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansalconst GLfloat g_vVertices[] = { 221e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal -1.f, 1.f, 0.0f, 1.0f, // Position 0 23eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal 0.0f, 1.0f, // TexCoord 0 241e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal 1.f, 1.f, 0.0f, 1.0f, // Position 1 25eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal 1.0f, 1.0f, // TexCoord 1 261e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal -1.f, -1.f, 0.0f, 1.0f, // Position 2 27eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal 0.0f, 0.0f, // TexCoord 2 281e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal 1.f, -1.f, 0.0f, 1.0f, // Position 3 29eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal 1.0f, 0.0f // TexCoord 3 30eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal}; 31eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal 32eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansalconst int VERTEX_STRIDE = 6 * sizeof(GLfloat); 33eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal 34eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansalGLushort g_iIndices[] = { 0, 1, 2, 3 }; 35eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal 361e762b1f935c9d4a06af6dd56121590ca81d48b1mbansalWarpRenderer::WarpRenderer() : Renderer() 37a6f0b9e759fa2d19d493bde7ffa8105ec2978b94mbansal{ 38eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal} 39eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal 40eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansalWarpRenderer::~WarpRenderer() { 41eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal} 42eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal 431e762b1f935c9d4a06af6dd56121590ca81d48b1mbansalvoid WarpRenderer::SetViewportMatrix(int w, int h, int W, int H) 44eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal{ 451e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal for(int i=0; i<16; i++) 46eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal { 471e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal mViewportMatrix[i] = 0.0f; 48eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal } 49eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal 501e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal mViewportMatrix[0] = float(w)/float(W); 511e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal mViewportMatrix[5] = float(h)/float(H); 521e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal mViewportMatrix[10] = 1.0f; 531e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal mViewportMatrix[12] = -1.0f + float(w)/float(W); 541e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal mViewportMatrix[13] = -1.0f + float(h)/float(H); 551e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal mViewportMatrix[15] = 1.0f; 561e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal} 57eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal 581e762b1f935c9d4a06af6dd56121590ca81d48b1mbansalvoid WarpRenderer::SetScalingMatrix(float xscale, float yscale) 591e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal{ 601e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal for(int i=0; i<16; i++) 61eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal { 621e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal mScalingMatrix[i] = 0.0f; 63eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal } 641e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal 651e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal mScalingMatrix[0] = xscale; 661e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal mScalingMatrix[5] = yscale; 671e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal mScalingMatrix[10] = 1.0f; 681e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal mScalingMatrix[15] = 1.0f; 69eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal} 70eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal 71eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansalbool WarpRenderer::InitializeGLProgram() 72eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal{ 73eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal bool succeeded = false; 74eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal do { 75eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal GLuint glProgram; 76eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal glProgram = createProgram(VertexShaderSource(), 77eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal FragmentShaderSource()); 78eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal if (!glProgram) { 79eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal break; 80eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal } 81eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal 82eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal glUseProgram(glProgram); 83eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal if (!checkGlError("glUseProgram")) break; 84eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal 85eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal // Get attribute locations 86eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal mPositionLoc = glGetAttribLocation(glProgram, "a_position"); 87eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal mAffinetransLoc = glGetUniformLocation(glProgram, "u_affinetrans"); 88eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal mViewporttransLoc = glGetUniformLocation(glProgram, "u_viewporttrans"); 89eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal mScalingtransLoc = glGetUniformLocation(glProgram, "u_scalingtrans"); 90eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal mTexCoordLoc = glGetAttribLocation(glProgram, "a_texCoord"); 91eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal 92eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal // Get sampler location 93eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal mSamplerLoc = glGetUniformLocation(glProgram, "s_texture"); 94eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal 95eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal mGlProgram = glProgram; 96eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal succeeded = true; 97eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal } while (false); 98eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal 99eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal if (!succeeded && (mGlProgram != 0)) 100eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal { 101eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal glDeleteProgram(mGlProgram); 102eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal checkGlError("glDeleteProgram"); 103eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal mGlProgram = 0; 104eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal } 105eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal return succeeded; 106eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal} 107eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal 108eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansalbool WarpRenderer::DrawTexture(GLfloat *affine) 109eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal{ 110eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal bool succeeded = false; 111eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal do { 112eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal bool rt = (mFrameBuffer == NULL)? 113eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal SetupGraphics(mSurfaceWidth, mSurfaceHeight) : 114eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal SetupGraphics(mFrameBuffer); 115eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal 116eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal if(!rt) 117eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal break; 118eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal 119eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal glDisable(GL_BLEND); 120eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal 121eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal glActiveTexture(GL_TEXTURE0); 122eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal if (!checkGlError("glActiveTexture")) break; 123eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal 124eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal const GLenum texture_type = InputTextureType(); 125eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal glBindTexture(texture_type, mInputTextureName); 126eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal if (!checkGlError("glBindTexture")) break; 127eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal 128eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal // Set the sampler texture unit to 0 129eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal glUniform1i(mSamplerLoc, 0); 130eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal 131eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal // Load the vertex position 132eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal glVertexAttribPointer(mPositionLoc, 4, GL_FLOAT, 133eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal GL_FALSE, VERTEX_STRIDE, g_vVertices); 134eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal 135eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal // Load the texture coordinate 136eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal glVertexAttribPointer(mTexCoordLoc, 2, GL_FLOAT, 137eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal GL_FALSE, VERTEX_STRIDE, &g_vVertices[4]); 138eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal 139eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal glEnableVertexAttribArray(mPositionLoc); 140eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal glEnableVertexAttribArray(mTexCoordLoc); 141eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal 142eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal // pass matrix information to the vertex shader 143eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal glUniformMatrix4fv(mAffinetransLoc, 1, GL_FALSE, affine); 144eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal glUniformMatrix4fv(mViewporttransLoc, 1, GL_FALSE, mViewportMatrix); 145eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal glUniformMatrix4fv(mScalingtransLoc, 1, GL_FALSE, mScalingMatrix); 146eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal 147eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal // And, finally, execute the GL draw command. 148eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal glDrawElements(GL_TRIANGLE_STRIP, 4, GL_UNSIGNED_SHORT, g_iIndices); 149eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal 150eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal checkGlError("glDrawElements"); 151eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal 152eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal glBindFramebuffer(GL_FRAMEBUFFER, 0); 153eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal succeeded = true; 154eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal } while (false); 155eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal return succeeded; 156eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal} 157eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal 158eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansalconst char* WarpRenderer::VertexShaderSource() const 159eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal{ 1601e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal static const char gVertexShader[] = 1611e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal "uniform mat4 u_affinetrans; \n" 1621e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal "uniform mat4 u_viewporttrans; \n" 1631e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal "uniform mat4 u_scalingtrans; \n" 1641e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal "attribute vec4 a_position; \n" 1651e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal "attribute vec2 a_texCoord; \n" 1661e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal "varying vec2 v_texCoord; \n" 1671e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal "void main() \n" 1681e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal "{ \n" 1691e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal " gl_Position = u_scalingtrans * u_viewporttrans * u_affinetrans * a_position; \n" 1701e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal " v_texCoord = a_texCoord; \n" 1711e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal "} \n"; 1721e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal 173eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal return gVertexShader; 174eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal} 175eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal 176eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansalconst char* WarpRenderer::FragmentShaderSource() const 177eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal{ 1781e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal static const char gFragmentShader[] = 1791e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal "precision mediump float; \n" 1801e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal "varying vec2 v_texCoord; \n" 1811e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal "uniform sampler2D s_texture; \n" 1821e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal "void main() \n" 1831e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal "{ \n" 1841e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal " vec4 color; \n" 1851e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal " color = texture2D(s_texture, v_texCoord); \n" 1861e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal " gl_FragColor = color; \n" 1871e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal "} \n"; 1881e762b1f935c9d4a06af6dd56121590ca81d48b1mbansal 189eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal return gFragmentShader; 190eeb94d4de94bfd4e01f3a716803f77a530f5b92cmbansal} 191