gl_frame.cpp revision 15ebdcc40023b94f8f7184b8c4ea47acc8d207c6
130ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni/* 230ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni * Copyright (C) 2011 The Android Open Source Project 330ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni * 430ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni * Licensed under the Apache License, Version 2.0 (the "License"); 530ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni * you may not use this file except in compliance with the License. 630ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni * You may obtain a copy of the License at 730ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni * 830ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni * http://www.apache.org/licenses/LICENSE-2.0 930ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni * 1030ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni * Unless required by applicable law or agreed to in writing, software 1130ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni * distributed under the License is distributed on an "AS IS" BASIS, 1230ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1330ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni * See the License for the specific language governing permissions and 1430ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni * limitations under the License. 1530ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni */ 1630ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni 1730ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni#include "base/logging.h" 1830ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni 1930ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni#include "core/gl_env.h" 2030ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni#include "core/gl_frame.h" 2130ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni#include "core/shader_program.h" 2230ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni 23e9912de34684f1b8deaf36bcf77686152d33765dEino-Ville Talvala#include <vector> 24e9912de34684f1b8deaf36bcf77686152d33765dEino-Ville Talvala 2530ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroninamespace android { 2630ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroninamespace filterfw { 2730ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni 28511360e61650864ea22a171159efe073c80d0cdbMarius Rennstatic const int kIdentityShaderKey = 1; 29511360e61650864ea22a171159efe073c80d0cdbMarius Renn 3030ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni// 3130ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni// A GLFrame stores pixel data on the GPU. It uses two kinds of GL data 3230ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni// containers for this: Textures and Frame Buffer Objects (FBOs). Textures are 3330ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni// used whenever pixel data needs to be read into a shader or the host program, 3430ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni// and when pixel data is uploaded to a GLFrame. The FBO is used as a rendering 3530ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni// target for shaders. 3630ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni// 3730ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni 38511360e61650864ea22a171159efe073c80d0cdbMarius RennGLFrame::GLFrame(GLEnv* gl_env) 39511360e61650864ea22a171159efe073c80d0cdbMarius Renn : gl_env_(gl_env), 40511360e61650864ea22a171159efe073c80d0cdbMarius Renn width_(0), 4130ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni height_(0), 4230ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni vp_x_(0), 4330ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni vp_y_(0), 4430ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni vp_width_(0), 4530ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni vp_height_(0), 4630ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni texture_id_(0), 4730ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni fbo_id_(0), 4830ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni texture_target_(GL_TEXTURE_2D), 4930ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni texture_state_(kStateUninitialized), 5030ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni fbo_state_(kStateUninitialized), 51776102d45a18a5df53d2ec76c5d93f20b3e99da1Marius Renn owns_texture_(false), 52776102d45a18a5df53d2ec76c5d93f20b3e99da1Marius Renn owns_fbo_(false) { 53f5ae8eafa7605c6593f62f873b62cb64a3254db3Marius Renn SetDefaultTexParameters(); 5430ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni} 5530ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni 5630ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceronibool GLFrame::Init(int width, int height) { 5730ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni // Make sure we haven't been initialized already 5830ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni if (width_ == 0 && height_ == 0) { 5930ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni InitDimensions(width, height); 6030ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni return true; 6130ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni } 6230ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni return false; 6330ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni} 6430ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni 65776102d45a18a5df53d2ec76c5d93f20b3e99da1Marius Rennbool GLFrame::InitWithTexture(GLint texture_id, int width, int height) { 6630ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni texture_id_ = texture_id; 67776102d45a18a5df53d2ec76c5d93f20b3e99da1Marius Renn texture_state_ = glIsTexture(texture_id) ? kStateComplete : kStateGenerated; 6830ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni InitDimensions(width, height); 6930ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni return true; 7030ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni} 7130ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni 72776102d45a18a5df53d2ec76c5d93f20b3e99da1Marius Rennbool GLFrame::InitWithFbo(GLint fbo_id, int width, int height) { 7330ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni fbo_id_ = fbo_id; 74776102d45a18a5df53d2ec76c5d93f20b3e99da1Marius Renn fbo_state_ = glIsFramebuffer(fbo_id) ? kStateComplete : kStateGenerated; 7530ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni InitDimensions(width, height); 7630ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni return true; 7730ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni} 7830ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni 7930ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceronibool GLFrame::InitWithExternalTexture() { 8030ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni texture_target_ = GL_TEXTURE_EXTERNAL_OES; 8130ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni width_ = 0; 8230ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni height_ = 0; 8330ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni return CreateTexture(); 8430ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni} 8530ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni 8630ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceronivoid GLFrame::InitDimensions(int width, int height) { 8730ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni width_ = width; 8830ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni height_ = height; 8930ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni vp_width_ = width; 9030ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni vp_height_ = height; 9130ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni} 9230ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni 9330ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo CarceroniGLFrame::~GLFrame() { 94776102d45a18a5df53d2ec76c5d93f20b3e99da1Marius Renn // Delete texture 95776102d45a18a5df53d2ec76c5d93f20b3e99da1Marius Renn if (owns_texture_) { 96776102d45a18a5df53d2ec76c5d93f20b3e99da1Marius Renn // Bind FBO so that texture is unbound from it during deletion 97776102d45a18a5df53d2ec76c5d93f20b3e99da1Marius Renn if (fbo_state_ == kStateComplete) { 98776102d45a18a5df53d2ec76c5d93f20b3e99da1Marius Renn glBindFramebuffer(GL_FRAMEBUFFER, fbo_id_); 99776102d45a18a5df53d2ec76c5d93f20b3e99da1Marius Renn } 100776102d45a18a5df53d2ec76c5d93f20b3e99da1Marius Renn glDeleteTextures(1, &texture_id_); 101776102d45a18a5df53d2ec76c5d93f20b3e99da1Marius Renn } 102776102d45a18a5df53d2ec76c5d93f20b3e99da1Marius Renn 103776102d45a18a5df53d2ec76c5d93f20b3e99da1Marius Renn // Delete FBO 104776102d45a18a5df53d2ec76c5d93f20b3e99da1Marius Renn if (owns_fbo_) { 105776102d45a18a5df53d2ec76c5d93f20b3e99da1Marius Renn glDeleteFramebuffers(1, &fbo_id_); 10630ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni } 10730ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni} 10830ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni 10930ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceronibool GLFrame::GenerateMipMap() { 110fb7c020acdd0fb38c9d2b6750d904b64cc78458dWei Hua if (FocusTexture()) { 11130ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni glGenerateMipmap(GL_TEXTURE_2D); 11230ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni return !GLEnv::CheckGLError("Generating MipMap!"); 11330ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni } 11430ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni return false; 11530ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni} 11630ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni 11730ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceronibool GLFrame::SetTextureParameter(GLenum pname, GLint value) { 118f5ae8eafa7605c6593f62f873b62cb64a3254db3Marius Renn if (value != tex_params_[pname]) { 119f5ae8eafa7605c6593f62f873b62cb64a3254db3Marius Renn if (FocusTexture()) { 120f5ae8eafa7605c6593f62f873b62cb64a3254db3Marius Renn glTexParameteri(GL_TEXTURE_2D, pname, value); 121f5ae8eafa7605c6593f62f873b62cb64a3254db3Marius Renn if (!GLEnv::CheckGLError("Setting texture parameter!")) { 122f5ae8eafa7605c6593f62f873b62cb64a3254db3Marius Renn tex_params_[pname] = value; 123f5ae8eafa7605c6593f62f873b62cb64a3254db3Marius Renn return true; 124f5ae8eafa7605c6593f62f873b62cb64a3254db3Marius Renn } 125f5ae8eafa7605c6593f62f873b62cb64a3254db3Marius Renn } 126f5ae8eafa7605c6593f62f873b62cb64a3254db3Marius Renn } else { 127f5ae8eafa7605c6593f62f873b62cb64a3254db3Marius Renn return true; 12830ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni } 12930ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni return false; 13030ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni} 13130ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni 132f5ae8eafa7605c6593f62f873b62cb64a3254db3Marius Rennbool GLFrame::UpdateTexParameters() { 133f5ae8eafa7605c6593f62f873b62cb64a3254db3Marius Renn glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, tex_params_[GL_TEXTURE_MAG_FILTER]); 134f5ae8eafa7605c6593f62f873b62cb64a3254db3Marius Renn glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, tex_params_[GL_TEXTURE_MIN_FILTER]); 135f5ae8eafa7605c6593f62f873b62cb64a3254db3Marius Renn glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, tex_params_[GL_TEXTURE_WRAP_S]); 136f5ae8eafa7605c6593f62f873b62cb64a3254db3Marius Renn glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, tex_params_[GL_TEXTURE_WRAP_T]); 137f5ae8eafa7605c6593f62f873b62cb64a3254db3Marius Renn return !GLEnv::CheckGLError("Resetting texture parameters!"); 138f5ae8eafa7605c6593f62f873b62cb64a3254db3Marius Renn} 139f5ae8eafa7605c6593f62f873b62cb64a3254db3Marius Renn 140f5ae8eafa7605c6593f62f873b62cb64a3254db3Marius Rennbool GLFrame::TexParametersModifed() { 141f5ae8eafa7605c6593f62f873b62cb64a3254db3Marius Renn return tex_params_[GL_TEXTURE_MAG_FILTER] != GL_LINEAR 142f5ae8eafa7605c6593f62f873b62cb64a3254db3Marius Renn || tex_params_[GL_TEXTURE_MIN_FILTER] != GL_LINEAR 143f5ae8eafa7605c6593f62f873b62cb64a3254db3Marius Renn || tex_params_[GL_TEXTURE_WRAP_S] != GL_CLAMP_TO_EDGE 144f5ae8eafa7605c6593f62f873b62cb64a3254db3Marius Renn || tex_params_[GL_TEXTURE_WRAP_T] != GL_CLAMP_TO_EDGE; 145f5ae8eafa7605c6593f62f873b62cb64a3254db3Marius Renn} 146f5ae8eafa7605c6593f62f873b62cb64a3254db3Marius Renn 147f5ae8eafa7605c6593f62f873b62cb64a3254db3Marius Rennvoid GLFrame::SetDefaultTexParameters() { 148f5ae8eafa7605c6593f62f873b62cb64a3254db3Marius Renn tex_params_[GL_TEXTURE_MAG_FILTER] = GL_LINEAR; 149f5ae8eafa7605c6593f62f873b62cb64a3254db3Marius Renn tex_params_[GL_TEXTURE_MIN_FILTER] = GL_LINEAR; 150f5ae8eafa7605c6593f62f873b62cb64a3254db3Marius Renn tex_params_[GL_TEXTURE_WRAP_S] = GL_CLAMP_TO_EDGE; 151f5ae8eafa7605c6593f62f873b62cb64a3254db3Marius Renn tex_params_[GL_TEXTURE_WRAP_T] = GL_CLAMP_TO_EDGE; 152f5ae8eafa7605c6593f62f873b62cb64a3254db3Marius Renn} 153f5ae8eafa7605c6593f62f873b62cb64a3254db3Marius Renn 154f5ae8eafa7605c6593f62f873b62cb64a3254db3Marius Rennbool GLFrame::ResetTexParameters() { 155f5ae8eafa7605c6593f62f873b62cb64a3254db3Marius Renn if (TexParametersModifed()) { 15633164fee278e106cc5d0493a1c184f208e9d273fMarius Renn if (BindTexture()) { 157f5ae8eafa7605c6593f62f873b62cb64a3254db3Marius Renn SetDefaultTexParameters(); 158f5ae8eafa7605c6593f62f873b62cb64a3254db3Marius Renn return UpdateTexParameters(); 15933164fee278e106cc5d0493a1c184f208e9d273fMarius Renn } 160f5ae8eafa7605c6593f62f873b62cb64a3254db3Marius Renn return false; 16133164fee278e106cc5d0493a1c184f208e9d273fMarius Renn } 162f5ae8eafa7605c6593f62f873b62cb64a3254db3Marius Renn return true; 16333164fee278e106cc5d0493a1c184f208e9d273fMarius Renn} 16433164fee278e106cc5d0493a1c184f208e9d273fMarius Renn 165e9912de34684f1b8deaf36bcf77686152d33765dEino-Ville Talvalabool GLFrame::CopyDataTo(uint8_t* buffer, int size) { 16630ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni return (size >= Size()) 16730ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni ? CopyPixelsTo(buffer) 16830ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni : false; 16930ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni} 17030ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni 171e9912de34684f1b8deaf36bcf77686152d33765dEino-Ville Talvalabool GLFrame::CopyPixelsTo(uint8_t* buffer) { 17215ebdcc40023b94f8f7184b8c4ea47acc8d207c6Marius Renn // Use one of the pixel reading methods below, ordered from most 17315ebdcc40023b94f8f7184b8c4ea47acc8d207c6Marius Renn // efficient to least efficient. 17415ebdcc40023b94f8f7184b8c4ea47acc8d207c6Marius Renn if (fbo_state_ == kStateComplete) 17530ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni return ReadFboPixels(buffer); 17615ebdcc40023b94f8f7184b8c4ea47acc8d207c6Marius Renn else if (texture_state_ == kStateComplete) 17715ebdcc40023b94f8f7184b8c4ea47acc8d207c6Marius Renn return ReadTexturePixels(buffer); 17830ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni else 17930ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni return false; 18030ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni} 18130ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni 182e9912de34684f1b8deaf36bcf77686152d33765dEino-Ville Talvalabool GLFrame::WriteData(const uint8_t* data, int data_size) { 18330ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni return (data_size == Size()) ? UploadTexturePixels(data) : false; 18430ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni} 18530ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni 18630ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceronibool GLFrame::SetViewport(int x, int y, int width, int height) { 18730ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni vp_x_ = x; 18830ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni vp_y_ = y; 18930ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni vp_width_ = width; 19030ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni vp_height_ = height; 19130ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni return true; 19230ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni} 19330ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni 19430ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo CarceroniGLFrame* GLFrame::Clone() const { 195511360e61650864ea22a171159efe073c80d0cdbMarius Renn GLFrame* target = new GLFrame(gl_env_); 19630ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni target->Init(width_, height_); 19730ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni target->CopyPixelsFrom(this); 19830ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni return target; 19930ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni} 20030ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni 20130ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceronibool GLFrame::CopyPixelsFrom(const GLFrame* frame) { 20230ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni if (frame == this) { 20330ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni return true; 20430ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni } else if (frame && frame->width_ == width_ && frame->height_ == height_) { 205e9912de34684f1b8deaf36bcf77686152d33765dEino-Ville Talvala std::vector<const GLFrame*> sources; 20630ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni sources.push_back(frame); 20730ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni GetIdentity()->Process(sources, this); 20830ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni return true; 20930ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni } 21030ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni return false; 21130ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni} 21230ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni 21330ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroniint GLFrame::Size() const { 21430ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni return width_ * height_ * 4; 21530ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni} 21630ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni 21730ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo CarceroniShaderProgram* GLFrame::GetIdentity() const { 218511360e61650864ea22a171159efe073c80d0cdbMarius Renn ShaderProgram* stored_shader = gl_env_->ShaderWithKey(kIdentityShaderKey); 219511360e61650864ea22a171159efe073c80d0cdbMarius Renn if (!stored_shader) { 220511360e61650864ea22a171159efe073c80d0cdbMarius Renn stored_shader = ShaderProgram::CreateIdentity(gl_env_); 221511360e61650864ea22a171159efe073c80d0cdbMarius Renn gl_env_->AttachShader(kIdentityShaderKey, stored_shader); 222511360e61650864ea22a171159efe073c80d0cdbMarius Renn } 223511360e61650864ea22a171159efe073c80d0cdbMarius Renn return stored_shader; 22430ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni} 22530ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni 22630ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceronibool GLFrame::BindFrameBuffer() const { 22730ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni // Bind the FBO 22830ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni glBindFramebuffer(GL_FRAMEBUFFER, fbo_id_); 22930ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni if (GLEnv::CheckGLError("FBO Binding")) return false; 23030ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni 23130ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni // Set viewport 23230ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni glViewport(vp_x_, vp_y_, vp_width_, vp_height_); 23330ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni if (GLEnv::CheckGLError("ViewPort Setup")) return false; 23430ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni 23530ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni return true; 23630ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni} 23730ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni 23830ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceronibool GLFrame::FocusFrameBuffer() { 23930ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni // Create texture backing if necessary 24030ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni if (texture_state_ == kStateUninitialized) { 24130ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni if (!CreateTexture()) 24230ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni return false; 24330ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni } 24430ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni 24530ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni // Create and bind FBO to texture if necessary 246776102d45a18a5df53d2ec76c5d93f20b3e99da1Marius Renn if (fbo_state_ != kStateComplete) { 247776102d45a18a5df53d2ec76c5d93f20b3e99da1Marius Renn if (!CreateFBO() || !AttachTextureToFBO()) 24830ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni return false; 24930ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni } 25030ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni 25130ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni // And bind it. 25230ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni return BindFrameBuffer(); 25330ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni} 25430ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni 25530ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceronibool GLFrame::BindTexture() const { 25630ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni glBindTexture(GL_TEXTURE_2D, texture_id_); 25730ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni return !GLEnv::CheckGLError("Texture Binding"); 25830ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni} 25930ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni 26030ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo CarceroniGLuint GLFrame::GetTextureId() const { 26130ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni return texture_id_; 26230ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni} 26330ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni 26430ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni// Returns the held FBO id. Only call this if the GLFrame holds an FBO. You 26530ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni// can check this by calling HoldsFbo(). 26630ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo CarceroniGLuint GLFrame::GetFboId() const { 26730ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni return fbo_id_; 26830ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni} 26930ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni 27030ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceronibool GLFrame::FocusTexture() { 27130ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni // Make sure we have a texture 27230ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni if (!CreateTexture()) 27330ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni return false; 27430ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni 27530ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni // Bind the texture 27630ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni if (!BindTexture()) 27730ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni return false; 27830ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni 27930ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni return !GLEnv::CheckGLError("Texture Binding"); 28030ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni} 28130ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni 28230ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceronibool GLFrame::CreateTexture() { 28330ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni if (texture_state_ == kStateUninitialized) { 28430ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni // Make sure texture not in use already 28530ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni if (glIsTexture(texture_id_)) { 28630ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni LOGE("GLFrame: Cannot generate texture id %d, as it is in use already!", texture_id_); 28730ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni return false; 28830ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni } 28930ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni 29030ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni // Generate the texture 29130ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni glGenTextures (1, &texture_id_); 29230ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni if (GLEnv::CheckGLError("Texture Generation")) 29330ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni return false; 29430ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni texture_state_ = kStateGenerated; 295776102d45a18a5df53d2ec76c5d93f20b3e99da1Marius Renn owns_texture_ = true; 29630ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni } 29730ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni 29830ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni return true; 29930ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni} 30030ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni 30130ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceronibool GLFrame::CreateFBO() { 30230ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni if (fbo_state_ == kStateUninitialized) { 30330ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni // Make sure FBO not in use already 30430ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni if (glIsFramebuffer(fbo_id_)) { 30530ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni LOGE("GLFrame: Cannot generate FBO id %d, as it is in use already!", fbo_id_); 30630ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni return false; 30730ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni } 30830ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni 30930ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni // Create FBO 31030ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni glGenFramebuffers(1, &fbo_id_); 31130ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni if (GLEnv::CheckGLError("FBO Generation")) 31230ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni return false; 31330ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni fbo_state_ = kStateGenerated; 314776102d45a18a5df53d2ec76c5d93f20b3e99da1Marius Renn owns_fbo_ = true; 31530ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni } 31630ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni 31730ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni return true; 31830ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni} 31930ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni 320e9912de34684f1b8deaf36bcf77686152d33765dEino-Ville Talvalabool GLFrame::ReadFboPixels(uint8_t* pixels) const { 321776102d45a18a5df53d2ec76c5d93f20b3e99da1Marius Renn if (fbo_state_ == kStateComplete) { 32230ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni BindFrameBuffer(); 32330ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni glReadPixels(0, 32430ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni 0, 32530ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni width_, 32630ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni height_, 32730ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni GL_RGBA, 32830ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni GL_UNSIGNED_BYTE, 32930ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni pixels); 33030ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni return !GLEnv::CheckGLError("FBO Pixel Readout"); 33130ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni } 33230ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni return false; 33330ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni} 33430ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni 335e9912de34684f1b8deaf36bcf77686152d33765dEino-Ville Talvalabool GLFrame::ReadTexturePixels(uint8_t* pixels) const { 33630ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni // Read pixels from texture if we do not have an FBO 33730ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni // NOTE: OpenGL ES does NOT support glGetTexImage() for reading out texture 33830ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni // data. The only way for us to get texture data is to create a new FBO and 33930ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni // render the current texture frame into it. As this is quite inefficient, 34030ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni // and unnecessary (this can only happen if the user is reading out data 34130ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni // that was just set, and not run through a filter), we warn the user about 34230ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni // this here. 34330ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni LOGW("Warning: Reading pixel data from unfiltered GL frame. This is highly " 34430ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni "inefficient. Please consider using your original pixel buffer " 34530ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni "instead!"); 34630ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni 34730ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni // Create source frame set (unfortunately this requires an ugly const-cast, 34830ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni // as we need to wrap ourselves in a frame-set. Still, as this set is used 34930ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni // as input only, we are certain we will not be modified). 350e9912de34684f1b8deaf36bcf77686152d33765dEino-Ville Talvala std::vector<const GLFrame*> sources; 35130ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni sources.push_back(this); 35230ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni 35330ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni // Create target frame 354511360e61650864ea22a171159efe073c80d0cdbMarius Renn GLFrame target(gl_env_); 35530ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni target.Init(width_, height_); 35630ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni 35730ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni // Render the texture to the target 35830ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni GetIdentity()->Process(sources, &target); 35930ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni 36030ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni // Get the pixel data 36130ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni return target.ReadFboPixels(pixels); 36230ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni} 36330ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni 364776102d45a18a5df53d2ec76c5d93f20b3e99da1Marius Rennbool GLFrame::AttachTextureToFBO() { 36530ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni // Check if we are already bound 366776102d45a18a5df53d2ec76c5d93f20b3e99da1Marius Renn if (fbo_state_ == kStateComplete) 36730ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni return true; 36830ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni 36930ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni // Otherwise check if the texture and fbo states are acceptable 370776102d45a18a5df53d2ec76c5d93f20b3e99da1Marius Renn if ((texture_state_ != kStateGenerated && texture_state_ != kStateComplete) 371776102d45a18a5df53d2ec76c5d93f20b3e99da1Marius Renn || (fbo_state_ != kStateGenerated)) 37230ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni return false; 37330ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni 37430ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni // Bind the frame buffer, and check if we it is already bound 37530ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni glBindFramebuffer(GL_FRAMEBUFFER, fbo_id_); 37630ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) { 37730ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni // Bind texture 37830ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni glBindTexture(GL_TEXTURE_2D, texture_id_); 37930ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni 38030ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni // Set the texture format 38130ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni glTexImage2D(GL_TEXTURE_2D, 38230ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni 0, 38330ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni GL_RGBA, 38430ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni width_, 38530ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni height_, 38630ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni 0, 38730ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni GL_RGBA, 38830ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni GL_UNSIGNED_BYTE, 38930ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni NULL); 390f5ae8eafa7605c6593f62f873b62cb64a3254db3Marius Renn 391f5ae8eafa7605c6593f62f873b62cb64a3254db3Marius Renn // Set the user specified texture parameters 392f5ae8eafa7605c6593f62f873b62cb64a3254db3Marius Renn UpdateTexParameters(); 39330ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni 39430ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni // Bind the texture to the frame buffer 39530ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni LOG_FRAME("Binding tex %d w %d h %d to fbo %d", texture_id_, width_, height_, fbo_id_); 39630ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni glFramebufferTexture2D(GL_FRAMEBUFFER, 39730ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni GL_COLOR_ATTACHMENT0, 39830ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni GL_TEXTURE_2D, 39930ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni texture_id_, 40030ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni 0); 40130ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni } 40230ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni 40330ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni // Cleanup 40430ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni glBindTexture(GL_TEXTURE_2D, 0); 40530ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni glBindFramebuffer(GL_FRAMEBUFFER, 0); 40630ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni 40730ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni if (GLEnv::CheckGLError("Texture Binding to FBO")) 40830ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni return false; 40930ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni 410776102d45a18a5df53d2ec76c5d93f20b3e99da1Marius Renn // FBO is now complete 411776102d45a18a5df53d2ec76c5d93f20b3e99da1Marius Renn fbo_state_ = kStateComplete; 41230ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni return true; 41330ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni} 41430ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni 415e9912de34684f1b8deaf36bcf77686152d33765dEino-Ville Talvalabool GLFrame::UploadTexturePixels(const uint8_t* pixels) { 41630ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni // Bind the texture object 41730ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni FocusTexture(); 41830ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni 41930ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni // Load mipmap level 0 42030ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width_, height_, 42130ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni 0, GL_RGBA, GL_UNSIGNED_BYTE, pixels); 42230ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni 423f5ae8eafa7605c6593f62f873b62cb64a3254db3Marius Renn // Set the user specified texture parameters 424f5ae8eafa7605c6593f62f873b62cb64a3254db3Marius Renn UpdateTexParameters(); 42530ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni 42630ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni if (GLEnv::CheckGLError("Texture Pixel Upload")) 42730ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni return false; 42830ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni 429776102d45a18a5df53d2ec76c5d93f20b3e99da1Marius Renn texture_state_ = kStateComplete; 43030ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni return true; 43130ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni} 43230ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni 43330ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni} // namespace filterfw 43430ab3fc173709a491c9e2e103f53fb7c0d1b96b7Rodrigo Carceroni} // namespace android 435