164 lines
5.4 KiB
Java
164 lines
5.4 KiB
Java
/*
|
|
* Copyright (C) 2012 The Android Open Source Project
|
|
*
|
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
* you may not use this file except in compliance with the License.
|
|
* You may obtain a copy of the License at
|
|
*
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
*
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
* See the License for the specific language governing permissions and
|
|
* limitations under the License.
|
|
*/
|
|
|
|
package com.example.android.mediafx;
|
|
|
|
import android.opengl.GLES20;
|
|
|
|
import java.nio.ByteBuffer;
|
|
import java.nio.ByteOrder;
|
|
import java.nio.FloatBuffer;
|
|
|
|
public class TextureRenderer {
|
|
|
|
private int mProgram;
|
|
private int mTexSamplerHandle;
|
|
private int mTexCoordHandle;
|
|
private int mPosCoordHandle;
|
|
|
|
private FloatBuffer mTexVertices;
|
|
private FloatBuffer mPosVertices;
|
|
|
|
private int mViewWidth;
|
|
private int mViewHeight;
|
|
|
|
private int mTexWidth;
|
|
private int mTexHeight;
|
|
|
|
private static final String VERTEX_SHADER =
|
|
"attribute vec4 a_position;\n" +
|
|
"attribute vec2 a_texcoord;\n" +
|
|
"varying vec2 v_texcoord;\n" +
|
|
"void main() {\n" +
|
|
" gl_Position = a_position;\n" +
|
|
" v_texcoord = a_texcoord;\n" +
|
|
"}\n";
|
|
|
|
private static final String FRAGMENT_SHADER =
|
|
"precision mediump float;\n" +
|
|
"uniform sampler2D tex_sampler;\n" +
|
|
"varying vec2 v_texcoord;\n" +
|
|
"void main() {\n" +
|
|
" gl_FragColor = texture2D(tex_sampler, v_texcoord);\n" +
|
|
"}\n";
|
|
|
|
private static final float[] TEX_VERTICES = {
|
|
0.0f, 1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f
|
|
};
|
|
|
|
private static final float[] POS_VERTICES = {
|
|
-1.0f, -1.0f, 1.0f, -1.0f, -1.0f, 1.0f, 1.0f, 1.0f
|
|
};
|
|
|
|
private static final int FLOAT_SIZE_BYTES = 4;
|
|
|
|
public void init() {
|
|
// Create program
|
|
mProgram = GLToolbox.createProgram(VERTEX_SHADER, FRAGMENT_SHADER);
|
|
|
|
// Bind attributes and uniforms
|
|
mTexSamplerHandle = GLES20.glGetUniformLocation(mProgram,
|
|
"tex_sampler");
|
|
mTexCoordHandle = GLES20.glGetAttribLocation(mProgram, "a_texcoord");
|
|
mPosCoordHandle = GLES20.glGetAttribLocation(mProgram, "a_position");
|
|
|
|
// Setup coordinate buffers
|
|
mTexVertices = ByteBuffer.allocateDirect(
|
|
TEX_VERTICES.length * FLOAT_SIZE_BYTES)
|
|
.order(ByteOrder.nativeOrder()).asFloatBuffer();
|
|
mTexVertices.put(TEX_VERTICES).position(0);
|
|
mPosVertices = ByteBuffer.allocateDirect(
|
|
POS_VERTICES.length * FLOAT_SIZE_BYTES)
|
|
.order(ByteOrder.nativeOrder()).asFloatBuffer();
|
|
mPosVertices.put(POS_VERTICES).position(0);
|
|
}
|
|
|
|
public void tearDown() {
|
|
GLES20.glDeleteProgram(mProgram);
|
|
}
|
|
|
|
public void updateTextureSize(int texWidth, int texHeight) {
|
|
mTexWidth = texWidth;
|
|
mTexHeight = texHeight;
|
|
computeOutputVertices();
|
|
}
|
|
|
|
public void updateViewSize(int viewWidth, int viewHeight) {
|
|
mViewWidth = viewWidth;
|
|
mViewHeight = viewHeight;
|
|
computeOutputVertices();
|
|
}
|
|
|
|
public void renderTexture(int texId) {
|
|
// Bind default FBO
|
|
GLES20.glBindFramebuffer(GLES20.GL_FRAMEBUFFER, 0);
|
|
|
|
// Use our shader program
|
|
GLES20.glUseProgram(mProgram);
|
|
GLToolbox.checkGlError("glUseProgram");
|
|
|
|
// Set viewport
|
|
GLES20.glViewport(0, 0, mViewWidth, mViewHeight);
|
|
GLToolbox.checkGlError("glViewport");
|
|
|
|
// Disable blending
|
|
GLES20.glDisable(GLES20.GL_BLEND);
|
|
|
|
// Set the vertex attributes
|
|
GLES20.glVertexAttribPointer(mTexCoordHandle, 2, GLES20.GL_FLOAT, false,
|
|
0, mTexVertices);
|
|
GLES20.glEnableVertexAttribArray(mTexCoordHandle);
|
|
GLES20.glVertexAttribPointer(mPosCoordHandle, 2, GLES20.GL_FLOAT, false,
|
|
0, mPosVertices);
|
|
GLES20.glEnableVertexAttribArray(mPosCoordHandle);
|
|
GLToolbox.checkGlError("vertex attribute setup");
|
|
|
|
// Set the input texture
|
|
GLES20.glActiveTexture(GLES20.GL_TEXTURE0);
|
|
GLToolbox.checkGlError("glActiveTexture");
|
|
GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, texId);
|
|
GLToolbox.checkGlError("glBindTexture");
|
|
GLES20.glUniform1i(mTexSamplerHandle, 0);
|
|
|
|
// Draw
|
|
GLES20.glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
|
|
GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT);
|
|
GLES20.glDrawArrays(GLES20.GL_TRIANGLE_STRIP, 0, 4);
|
|
}
|
|
|
|
private void computeOutputVertices() {
|
|
if (mPosVertices != null) {
|
|
float imgAspectRatio = mTexWidth / (float)mTexHeight;
|
|
float viewAspectRatio = mViewWidth / (float)mViewHeight;
|
|
float relativeAspectRatio = viewAspectRatio / imgAspectRatio;
|
|
float x0, y0, x1, y1;
|
|
if (relativeAspectRatio > 1.0f) {
|
|
x0 = -1.0f / relativeAspectRatio;
|
|
y0 = -1.0f;
|
|
x1 = 1.0f / relativeAspectRatio;
|
|
y1 = 1.0f;
|
|
} else {
|
|
x0 = -1.0f;
|
|
y0 = -relativeAspectRatio;
|
|
x1 = 1.0f;
|
|
y1 = relativeAspectRatio;
|
|
}
|
|
float[] coords = new float[] { x0, y0, x1, y0, x0, y1, x1, y1 };
|
|
mPosVertices.put(coords).position(0);
|
|
}
|
|
}
|
|
}
|