blob: 7492cc034234c918af6d43cc924a02c4eb4ea2af [file] [log] [blame]
/*
* Copyright (C) 2019 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 android.gameperformance;
import java.util.List;
import javax.microedition.khronos.opengles.GL;
import android.annotation.NonNull;
import android.content.Context;
import android.opengl.GLES20;
import android.opengl.Matrix;
/**
* Base class for all OpenGL based tests that use RenderPatch as a base.
*/
public abstract class RenderPatchOpenGLTest extends OpenGLTest {
private final float[] COLOR = new float[] { 1.0f, 1.0f, 1.0f, 1.0f };
private final String VERTEX_SHADER =
"uniform mat4 uMVPMatrix;"
+ "attribute vec4 vPosition;"
+ "attribute vec2 vTexture;"
+ "varying vec2 vTex;"
+ "void main() {"
+ " vTex = vTexture;"
+ " gl_Position = uMVPMatrix * vPosition;"
+ "}";
private final String FRAGMENT_SHADER =
"precision mediump float;"
+ "uniform sampler2D uTexture;"
+ "uniform vec4 uColor;"
+ "varying vec2 vTex;"
+ "void main() {"
+ " vec4 color = texture2D(uTexture, vTex);"
+ " gl_FragColor = uColor * color;"
+ "}";
private List<RenderPatchAnimation> mRenderPatches;
private int mProgram = -1;
private int mMVPMatrixHandle;
private int mTextureHandle;
private int mPositionHandle;
private int mColorHandle;
private int mTextureCoordHandle;
private final float[] mVPMatrix = new float[16];
public RenderPatchOpenGLTest(@NonNull GamePerformanceActivity activity) {
super(activity);
}
protected void setRenderPatches(@NonNull List<RenderPatchAnimation> renderPatches) {
mRenderPatches = renderPatches;
}
private void ensureInited() {
if (mProgram >= 0) {
return;
}
mProgram = OpenGLUtils.createProgram(VERTEX_SHADER, FRAGMENT_SHADER);
// get handle to fragment shader's uColor member
GLES20.glUseProgram(mProgram);
OpenGLUtils.checkGlError("useProgram");
// get handle to shape's transformation matrix
mMVPMatrixHandle = GLES20.glGetUniformLocation(mProgram, "uMVPMatrix");
OpenGLUtils.checkGlError("get uMVPMatrix");
mTextureHandle = GLES20.glGetUniformLocation(mProgram, "uTexture");
OpenGLUtils.checkGlError("uTexture");
// get handle to vertex shader's vPosition member
mPositionHandle = GLES20.glGetAttribLocation(mProgram, "vPosition");
OpenGLUtils.checkGlError("vPosition");
mTextureCoordHandle = GLES20.glGetAttribLocation(mProgram, "vTexture");
OpenGLUtils.checkGlError("vTexture");
mColorHandle = GLES20.glGetUniformLocation(mProgram, "uColor");
OpenGLUtils.checkGlError("uColor");
mTextureHandle = OpenGLUtils.createTexture(getContext(), R.drawable.logo);
final float[] projectionMatrix = new float[16];
final float[] viewMatrix = new float[16];
final float ratio = getView().getRenderRatio();
Matrix.orthoM(projectionMatrix, 0, -ratio, ratio, -1, 1, -1, 1);
Matrix.setLookAtM(viewMatrix, 0, 0, 0, -0.5f, 0f, 0f, 0f, 0f, 1.0f, 0.0f);
Matrix.multiplyMM(mVPMatrix, 0, projectionMatrix, 0, viewMatrix, 0);
}
/**
* Returns global color for patch.
*/
public float[] getColor() {
return COLOR;
}
/**
* Extra setup for particular tests.
*/
public void onBeforeDraw(GL gl) {
}
@Override
public void draw(GL gl) {
ensureInited();
GLES20.glUseProgram(mProgram);
OpenGLUtils.checkGlError("useProgram");
GLES20.glDisable(GLES20.GL_BLEND);
OpenGLUtils.checkGlError("disableBlend");
GLES20.glEnableVertexAttribArray(mPositionHandle);
OpenGLUtils.checkGlError("enableVertexAttributes");
GLES20.glEnableVertexAttribArray(mTextureCoordHandle);
OpenGLUtils.checkGlError("enableTexturesAttributes");
GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, mTextureHandle);
OpenGLUtils.checkGlError("setTexture");
GLES20.glUniform4fv(mColorHandle, 1, getColor(), 0);
OpenGLUtils.checkGlError("setColor");
onBeforeDraw(gl);
for (final RenderPatchAnimation renderPatchAnimation : mRenderPatches) {
renderPatchAnimation.update(0.01f);
GLES20.glUniformMatrix4fv(mMVPMatrixHandle,
1,
false,
renderPatchAnimation.getTransform(mVPMatrix),
0);
OpenGLUtils.checkGlError("setTransform");
GLES20.glVertexAttribPointer(
mPositionHandle,
RenderPatch.VERTEX_COORD_COUNT,
GLES20.GL_FLOAT,
false /* normalized */,
RenderPatch.VERTEX_STRIDE,
renderPatchAnimation.getRenderPatch().getVertexBuffer());
OpenGLUtils.checkGlError("setVertexAttribute");
GLES20.glVertexAttribPointer(
mTextureCoordHandle,
RenderPatch.TEXTURE_COORD_COUNT,
GLES20.GL_FLOAT,
false /* normalized */,
RenderPatch.TEXTURE_STRIDE,
renderPatchAnimation.getRenderPatch().getTextureBuffer());
OpenGLUtils.checkGlError("setTextureAttribute");
// Draw the patch.
final int indicesCount =
renderPatchAnimation.getRenderPatch().getIndexBuffer().capacity() /
RenderPatch.SHORT_SIZE;
GLES20.glDrawElements(
GLES20.GL_TRIANGLES,
indicesCount,
GLES20.GL_UNSIGNED_SHORT,
renderPatchAnimation.getRenderPatch().getIndexBuffer());
OpenGLUtils.checkGlError("drawPatch");
}
GLES20.glDisableVertexAttribArray(mPositionHandle);
GLES20.glDisableVertexAttribArray(mTextureCoordHandle);
}
}