I'm trying to use the code for decode mp4 video add a bitmap (at x, y position) and encode.
I'm trying to use the Android OpenGL code (ExtractDecodeEditEncodeMuxTest.java) for decode of a mp4 video and add a image every frame (at a specific x,y position) and at end re-encode the video to mp4.
I load a bitmap when the surface is created and in drawFrame function I try to draw the bitmap, but only the video frames (without the bitmap) are encoded, why?
I try to edit the TextureRender in this way
package com.test.decodeeditencode;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.FloatBuffer;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.SurfaceTexture;
import android.opengl.GLES11Ext;
import android.opengl.GLES20;
import android.opengl.GLUtils;
import android.opengl.Matrix;
import android.util.Log;
/**
* Code for rendering a texture onto a surface using OpenGL ES 2.0.
*/
class TextureRender {
private static final String TAG = "TextureRender";
private static final int FLOAT_SIZE_BYTES = 4;
private static final int TRIANGLE_VERTICES_DATA_STRIDE_BYTES = 5 * FLOAT_SIZE_BYTES;
private static final int TRIANGLE_VERTICES_DATA_POS_OFFSET = 0;
private static final int TRIANGLE_VERTICES_DATA_UV_OFFSET = 3;
private final float[] mTriangleVerticesData = {
// X, Y, Z, U, V
-1.0f, -1.0f, 0, 0.f, 0.f,
1.0f, -1.0f, 0, 1.f, 0.f,
-1.0f, 1.0f, 0, 0.f, 1.f,
1.0f, 1.0f, 0, 1.f, 1.f,
};
private final FloatBuffer mTexVertices;
private final FloatBuffer mPosVertices;
private final FloatBuffer mTriangleVertices;
private static final String VERTEX_SHADER =
"uniform mat4 uMVPMatrix;\n" +
"uniform mat4 uSTMatrix;\n" +
"attribute vec4 aPosition;\n" +
"attribute vec4 aTextureCoord;\n" +
"varying vec2 vTextureCoord;\n" +
"void main() {\n" +
" gl_Position = uMVPMatrix * aPosition;\n" +
" vTextureCoord = (uSTMatrix * aTextureCoord).xy;\n" +
"}\n";
private static final String FRAGMENT_SHADER =
"#extension GL_OES_EGL_image_external : require\n" +
"precision mediump float;\n" + // highp here doesn't seem to matter
"varying vec2 vTextureCoord;\n" +
"uniform samplerExternalOES sTexture;\n" +
"void main() {\n" +
" gl_FragColor = texture2D(sTexture, vTextureCoord);\n" +
"}\n";
private float[] mMVPMatrix = new float[16];
private float[] mSTMatrix = new float[16];
private int mProgram;
private int mTextureID = -12345;
private int mLogoTextureID;
private int muMVPMatrixHandle;
private int muSTMatrixHandle;
private int maPositionHandle;
private int maTextureHandle;
private final Context mContext;
public TextureRender(Context context) {
mContext = context;
mTriangleVertices = ByteBuffer.allocateDirect(mTriangleVerticesData.length * FLOAT_SIZE_BYTES).order(ByteOrder.nativeOrder()).asFloatBuffer();
mTriangleVertices.put(mTriangleVerticesData).position(0);
Matrix.setIdentityM(mSTMatrix, 0);
}
public int getTextureId() {
return mTextureID;
}
public void drawFrame(SurfaceTexture st) {
checkGlError("onDrawFrame start");
st.getTransformMatrix(mSTMatrix);
GLES20.glClearColor(0.0f, 1.0f, 0.0f, 1.0f);
GLES20.glClear(GLES20.GL_DEPTH_BUFFER_BIT | GLES20.GL_COLOR_BUFFER_BIT);
GLES20.glUseProgram(mProgram);
checkGlError("glUseProgram");
GLES20.glActiveTexture(GLES20.GL_TEXTURE0);
GLES20.glBindTexture(GLES11Ext.GL_TEXTURE_EXTERNAL_OES, mTextureID);
//***********DRAW BITMAP************
GLES20.glActiveTexture(GLES20.GL_TEXTURE1);
checkGlError("glActiveTexture");
GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, mLogoTextureID);
checkGlError("glBindTexture");
GLES20.glUniform1i(maTextureHandle, 0);
mTriangleVertices.position(TRIANGLE_VERTICES_DATA_POS_OFFSET);
GLES20.glVertexAttribPointer(maPositionHandle, 3, GLES20.GL_FLOAT, false, TRIANGLE_VERTICES_DATA_STRIDE_BYTES, mTriangleVertices);
checkGlError("glVertexAttribPointer maPosition");
GLES20.glEnableVertexAttribArray(maPositionHandle);
checkGlError("glEnableVertexAttribArray maPositionHandle");
mTriangleVertices.position(TRIANGLE_VERTICES_DATA_UV_OFFSET);
GLES20.glVertexAttribPointer(maTextureHandle, 2, GLES20.GL_FLOAT, false, TRIANGLE_VERTICES_DATA_STRIDE_BYTES, mTriangleVertices);
checkGlError("glVertexAttribPointer maTextureHandle");
GLES20.glEnableVertexAttribArray(maTextureHandle);
checkGlError("glEnableVertexAttribArray maTextureHandle");
Matrix.setIdentityM(mMVPMatrix, 0);
GLES20.glUniformMatrix4fv(muMVPMatrixHandle, 1, false, mMVPMatrix, 0);
GLES20.glUniformMatrix4fv(muSTMatrixHandle, 1, false, mSTMatrix, 0);
GLES20.glDrawArrays(GLES20.GL_TRIANGLE_STRIP, 0, 4);
checkGlError("glDrawArrays");
GLES20.glFinish();
}
/**
* Initializes GL state. Call this after the EGL surface has been created and made current.
*/
public void surfaceCreated() {
mProgram = createProgram(VERTEX_SHADER, FRAGMENT_SHADER);
if (mProgram == 0) {
throw new RuntimeException("failed creating program");
}
maPositionHandle = GLES20.glGetAttribLocation(mProgram, "aPosition");
checkGlError("glGetAttribLocation aPosition");
if (maPositionHandle == -1) {
throw new RuntimeException("Could not get attrib location for aPosition");
}
maTextureHandle = GLES20.glGetAttribLocation(mProgram, "aTextureCoord");
checkGlError("glGetAttribLocation aTextureCoord");
if (maTextureHandle == -1) {
throw new RuntimeException("Could not get attrib location for aTextureCoord");
}
muMVPMatrixHandle = GLES20.glGetUniformLocation(mProgram, "uMVPMatrix");
checkGlError("glGetUniformLocation uMVPMatrix");
if (muMVPMatrixHandle == -1) {
throw new RuntimeException("Could not get attrib location for uMVPMatrix");
}
muSTMatrixHandle = GLES20.glGetUniformLocation(mProgram, "uSTMatrix");
checkGlError("glGetUniformLocation uSTMatrix");
if (muSTMatrixHandle == -1) {
throw new RuntimeException("Could not get attrib location for uSTMatrix");
}
int[] textures = new int[2];
GLES20.glGenTextures(2, textures, 0);
mTextureID = textures[0];
GLES20.glBindTexture(GLES11Ext.GL_TEXTURE_EXTERNAL_OES, mTextureID);
checkGlError("glBindTexture mTextureID");
GLES20.glTexParameterf(GLES11Ext.GL_TEXTURE_EXTERNAL_OES, GLES20.GL_TEXTURE_MIN_FILTER, GLES20.GL_NEAREST);
GLES20.glTexParameterf(GLES11Ext.GL_TEXTURE_EXTERNAL_OES, GLES20.GL_TEXTURE_MAG_FILTER, GLES20.GL_LINEAR);
GLES20.glTexParameteri(GLES11Ext.GL_TEXTURE_EXTERNAL_OES, GLES20.GL_TEXTURE_WRAP_S, GLES20.GL_CLAMP_TO_EDGE);
GLES20.glTexParameteri(GLES11Ext.GL_TEXTURE_EXTERNAL_OES, GLES20.GL_TEXTURE_WRAP_T, GLES20.GL_CLAMP_TO_EDGE);
checkGlError("glTexParameter");
mLogoTextureID = textures[1];
//*******************Load input bitmap*************
Bitmap bitmap = BitmapFactory.decodeResource(mContext.getResources(), R.drawable.google);
// Upload to texture
GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, mLogoTextureID);
GLUtils.texImage2D(GLES20.GL_TEXTURE_2D, 0, bitmap, 0);
bitmap.recycle();
}
/**
* Replaces the fragment shader.
*/
public void changeFragmentShader(String fragmentShader) {
GLES20.glDeleteProgram(mProgram);
mProgram = createProgram(VERTEX_SHADER, fragmentShader);
if (mProgram == 0) {
throw new RuntimeException("failed creating program");
}
}
private int loadShader(int shaderType, String source) {
int shader = GLES20.glCreateShader(shaderType);
checkGlError("glCreateShader type=" + shaderType);
GLES20.glShaderSource(shader, source);
GLES20.glCompileShader(shader);
int[] compiled = new int[1];
GLES20.glGetShaderiv(shader, GLES20.GL_COMPILE_STATUS, compiled, 0);
if (compiled[0] == 0) {
Log.e(TAG, "Could not compile shader " + shaderType + ":");
Log.e(TAG, " " + GLES20.glGetShaderInfoLog(shader));
GLES20.glDeleteShader(shader);
shader = 0;
}
return shader;
}
private int createProgram(String vertexSource, String fragmentSource) {
int vertexShader = loadShader(GLES20.GL_VERTEX_SHADER, vertexSource);
if (vertexShader == 0) {
return 0;
}
int pixelShader = loadShader(GLES20.GL_FRAGMENT_SHADER, fragmentSource);
if (pixelShader == 0) {
return 0;
}
int program = GLES20.glCreateProgram();
checkGlError("glCreateProgram");
if (program == 0) {
Log.e(TAG, "Could not create program");
}
GLES20.glAttachShader(program, vertexShader);
checkGlError("glAttachShader");
GLES20.glAttachShader(program, pixelShader);
checkGlError("glAttachShader");
GLES20.glLinkProgram(program);
int[] linkStatus = new int[1];
GLES20.glGetProgramiv(program, GLES20.GL_LINK_STATUS, linkStatus, 0);
if (linkStatus[0] != GLES20.GL_TRUE) {
Log.e(TAG, "Could not link program: ");
Log.e(TAG, GLES20.glGetProgramInfoLog(program));
GLES20.glDeleteProgram(program);
program = 0;
}
return program;
}
public void checkGlError(String op) {
int error;
while ((error = GLES20.glGetError()) != GLES20.GL_NO_ERROR) {
Log.e(TAG, op + ": glError " + error);
throw new RuntimeException(op + ": glError " + error);
}
}
}
But the bitmap not showing,
Vertex attributes aPosition and aTexture are declared as vec4 but you supply only vec3 and vec2:
GLES20.glVertexAttribPointer(maPositionHandle, 3, GLES20.GL_FLOAT, false, TRIANGLE_VERTICES_DATA_STRIDE_BYTES, mTriangleVertices);
GLES20.glVertexAttribPointer(maTextureHandle, 2, GLES20.GL_FLOAT, false, TRIANGLE_VERTICES_DATA_STRIDE_BYTES, mTriangleVertices);
You should change your VS code to:
private static final String VERTEX_SHADER =
"uniform mat4 uMVPMatrix;\n" +
"uniform mat4 uSTMatrix;\n" +
"attribute vec3 aPosition;\n" +
"attribute vec2 aTextureCoord;\n" +
"varying vec2 vTextureCoord;\n" +
"void main() {\n" +
" gl_Position = uMVPMatrix * vec4(aPosition, 1.0);\n" +
" vTextureCoord = (uSTMatrix * vec4(aTextureCoord, 0.0, 1.0)).xy;\n" +
"}\n";
Related
I've basically followed the guide on the android docs religiously, other than a couple variable names, and that I'm rendering in a fragment. I've been spending a bit off time commenting out lines and I managed to figure out that
public static int loadShader(int type, String shaderCode) {
int shader = GLES20.glCreateShader(type);
//System.out.println(shader + " ass");
//GLES20.glShaderSource(shader, shaderCode);
//GLES20.glCompileShader(shader);
//return shader;
return 0;
}
the glCreateShader method crashes the app. It doesn't return anything, it just crashes. The type inputs are always either GLES20.GL_VERTEX_SHADER or GLES20.GL_FRAGMENT_SHADER it crashes with both.
The rest of my renderer class looks like this
public class OpenGLRenderer implements GLSurfaceView.Renderer {
private Triangle trangle;
#Override
public void onSurfaceCreated(GL10 gl10, EGLConfig eglConfig) {
GLES20.glClearColor(0.0f, 1.0f, 0.0f, 1.0f);
trangle = new Triangle();
}
#Override
public void onSurfaceChanged(GL10 gl10, int i, int i1) {
}
#Override
public void onDrawFrame(GL10 gl10) {
GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT);
//trangle.draw();
}
public static int loadShader(int type, String shaderCode) {
int shader = GLES20.glCreateShader(type);
//System.out.println(shader + " ass");
//GLES20.glShaderSource(shader, shaderCode);
//GLES20.glCompileShader(shader);
//return shader;
return 0;
}
And here's my triangle class:
public class Triangle {
private FloatBuffer vertexBuffer;
private final int shaderProgram;
private final String vertexShaderCode =
"attribute vec4 vPosition;" +
"void main() {" +
" gl_Position = vPosition;" +
"}";
private final String fragmentShaderCode =
"precision mediump float;" +
"uniform vec4 vColor;" +
"void main() {" +
" gl_FragColor = vColor;" +
"}";
static float[] triangleCoords = {
0.0f, 0.5f, 0.0f,
-0.5f,-0.3f, 0.0f,
0.5f, -0.3f, 0.0f
};
static final int coordsInVertex = 3, vertexCount = triangleCoords.length / coordsInVertex, vertexStride = coordsInVertex * 4;
private int positionHandle, colorHandle;
float color[] = {1f, 0f, 0f, 1f};
public Triangle () {
ByteBuffer byteBuffer = ByteBuffer.allocateDirect(triangleCoords.length*4);
byteBuffer.order(ByteOrder.nativeOrder());
vertexBuffer = byteBuffer.asFloatBuffer();
vertexBuffer.put (triangleCoords);
vertexBuffer.position(0);
int vertexShader = OpenGLRenderer.loadShader(GLES20.GL_VERTEX_SHADER, vertexShaderCode);
int fragmentShader = OpenGLRenderer.loadShader(GLES20.GL_FRAGMENT_SHADER, fragmentShaderCode);
shaderProgram = GLES20.glCreateProgram();
GLES20.glAttachShader(shaderProgram, vertexShader);
GLES20.glAttachShader(shaderProgram, fragmentShader);
GLES20.glLinkProgram(shaderProgram);
}
public void draw () {
GLES20.glUseProgram(shaderProgram);
positionHandle = GLES20.glGetAttribLocation(shaderProgram, "vPosition");
GLES20.glEnableVertexAttribArray(positionHandle);
GLES20.glVertexAttribPointer(positionHandle, coordsInVertex, GLES20.GL_FLOAT, false, vertexStride, vertexBuffer);
colorHandle = GLES20.glGetUniformLocation(shaderProgram, "vColor");
GLES20.glUniform4fv(colorHandle, 1, color, 0);
GLES20.glDrawArrays(GLES20.GL_TRIANGLES, 0, vertexCount);
GLES20.glDisableVertexAttribArray(positionHandle);
}
}
Could someone shed some light?
Not found any issue or error in the aforementioned sources that you provided, and it is completely workable when connects with a GLSurfaceView.
I think the issue is on configuring GLSurfaceView where you must explicitly set the EGLContextClientVersion of OpenGL-ES context before setRenderer;
without eglContext program will not be performed any GL operations.
GLSurfaceView view = findViewById(R.id.glview);
view.setEGLContextClientVersion(2);
view.setRenderer(new OpenGLRenderer());
Sorry for my English. I'm beginner in OpenglES. I wrote this code to draw simple table for airhockey. The code was taken from book OpenglES2 for Android and i'm a bit to modified it. When i launched my app, it's crashed. Wherein do not appear an errors.
The code from ShaderHandler.java
public class ShaderHandler {
private static int program;
private static final String TAG = "TAG";
public static int loadShader(int type, String shaderCode){
final int shader = GLES20.glCreateShader(type);
if(shader == 0){
if(LoggerConfig.ON) {
Log.w(TAG, "Could not create new shader");
}
}
GLES20.glShaderSource(shader, shaderCode);
GLES20.glCompileShader(shader);
//----------------------------------------------------------------------------------------
//check compile status. This is pattern
final int[] compileStatus = new int[1];
GLES20.glGetShaderiv(shader, GLES20.GL_COMPILE_STATUS, compileStatus, 0);
if (LoggerConfig.ON) {
Log.v(TAG, "Results of compiling source: " + "\n" + shaderCode + "\n:"
+ GLES20.glGetShaderInfoLog(shader));
}
if (compileStatus[0] == 0){
//if it failed, delete the shader object
GLES20.glDeleteShader(shader);
if (LoggerConfig.ON) Log.w(TAG, "Compilation of shader failed");
}
//----------------------------------------------------------------------------------------
return shader;
}
public static int makeProgram(int vertexShader, int fragmentShader) {
program = GLES20.glCreateProgram();
if (program == 0){
if (LoggerConfig.ON){
Log.w(TAG, "Could not create a program");
}
}
GLES20.glAttachShader(program, vertexShader);
GLES20.glAttachShader(program, fragmentShader);
GLES20.glLinkProgram(program);
if(LoggerConfig.ON) validateProgram(program);
GLES20.glUseProgram(program);
return program;
}
}
And the code from myRenderer.java
public class MyRenderer implements GLSurfaceView.Renderer {
private static final int POSITION_COMPONENT_COUNT = 2;
private static final int BYTES_PER_FLOAT = 4;
private FloatBuffer vertexData;
private Context context;
private ShaderHandler shaderHandler;
private static final String A_POSITION = "a_Position";
private int aPositionLocation;
private static final String U_COLOR = "u_Color";
private int uColorLocation;
private final String vertexShaderCode =
"attribute vec4 a_Position;" +
"void main() {" +
" gl_Position = a_Position;" +
"}";
private final String fragmentShaderCode =
"precision mediump float;" +
"uniform vec4 u_Color;" +
"void main() {" +
" gl_FragColor = u_Color;" +
"}";
float[] tableVertices = {
0f, 0f,
0f, 14f,
9f, 14f,
9f, 0f
};
float[] tableVerticesTriangles = {
//Triangle1
0f, 0f,
9f, 14f,
0f, 14f,
//Triangle2
0f, 0f,
9f, 0f,
9f, 14f,
//Line1
0f, 7f,
9f, 7f,
//Mallets
4.5f, 2f,
4.5f, 12f
};
#Override
public void onSurfaceCreated(GL10 gl, EGLConfig config) {
GLES20.glClearColor(1.0f, 0.0f, 0.0f, 0.0f);
vertexData = ByteBuffer
.allocateDirect(tableVerticesTriangles.length * BYTES_PER_FLOAT)
.order(ByteOrder.nativeOrder())
.asFloatBuffer();
vertexData.put(tableVertices);
int compiledVertShader = shaderHandler.loadShader(GLES20.GL_VERTEX_SHADER, vertexShaderCode);
int compiledFragShader = shaderHandler.loadShader(GLES20.GL_FRAGMENT_SHADER, fragmentShaderCode);
int program = shaderHandler.makeProgram(compiledVertShader, compiledFragShader);
aPositionLocation = GLES20.glGetAttribLocation(program, "a_Position");
uColorLocation = GLES20.glGetUniformLocation(program, "u_Color");
vertexData.position(0);
GLES20.glVertexAttribPointer(aPositionLocation, POSITION_COMPONENT_COUNT, GLES20.GL_FLOAT,
false, 0, vertexData);
GLES20.glEnableVertexAttribArray(aPositionLocation);
}
#Override
public void onSurfaceChanged(GL10 gl, int width, int height) {
GLES20.glViewport(0, 0, width, height);
}
#Override
public void onDrawFrame(GL10 gl) {
GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT);
GLES20.glUniform4f(uColorLocation, 1.0f, 1.0f, 1.0f, 1.0f);
GLES20.glDrawArrays(GLES20.GL_TRIANGLES, 0, 6);
GLES20.glUniform4f(uColorLocation, 1.0f, 0.0f, 0.0f, 1.0f);
GLES20.glDrawArrays(GLES20.GL_LINES, 6, 2);
GLES20.glUniform4f(uColorLocation, 0.0f, 0.0f, 1.0f, 1.0f);
GLES20.glDrawArrays(GLES20.GL_POINTS, 8, 1);
GLES20.glUniform4f(uColorLocation, 1.0f, 0.0f, 0.0f, 1.0f);
GLES20.glDrawArrays(GLES20.GL_POINTS, 9, 1);
}
}
After that as app crashes, i see this message in logcat
A/libc: Fatal signal 11 (SIGSEGV), code 1 (SEGV_MAPERR), fault addr 0x0 in tid 17311 (GLThread 891), pid 17264 (ockey.airhockey)
Please help. I've been trying to overcome this problem all day, but I just can’t figure out what to do.
I am working on video editing android application and want to apply filters and watermark together on video.
I have been using GPUVideo-android lib for this
https://github.com/MasayukiSuda/GPUVideo-android
The problem is in this library I am not able to get both watermark and fliter together.
below is my FRAGMENT_SHADER for one of my filters
private static final String FRAGMENT_SHADER =
"precision mediump float;" +
"varying vec2 vTextureCoord;" +
"uniform lowp sampler2D sTexture;" +
"const highp vec3 weight = vec3(0.2125, 0.7154, 0.0721);" +
"void main() {" +
" vec4 FragColor = texture2D(sTexture, vTextureCoord);\n" +
" gl_FragColor.r = dot(FragColor.rgb, vec3(.393, .769, .189));\n" +
" gl_FragColor.g = dot(FragColor.rgb, vec3(.349, .686, .168));\n" +
" gl_FragColor.b = dot(FragColor.rgb, vec3(.272, .534, .131));\n" +
"}";
and below is for watermark
protected static final String DEFAULT_FRAGMENT_SHADER =
"precision mediump float;\n" +
"varying vec2 vTextureCoord;\n" +
"uniform lowp sampler2D sTexture;\n" +
"uniform lowp sampler2D oTexture;\n" +
"void main() {\n" +
" lowp vec4 textureColor = texture2D(sTexture, vTextureCoord);\n" +
" lowp vec4 textureColor2 = texture2D(oTexture, vTextureCoord);\n" +
" \n" +
" gl_FragColor = mix(textureColor, textureColor2, textureColor2.a);\n" +
"}\n";
I want to have both effects together in one:
https://github.com/MasayukiSuda/GPUVideo-android/blob/master/gpuv/src/main/java/com/daasuu/gpuv/egl/filter/GlWatermarkFilter.java
https://github.com/MasayukiSuda/GPUVideo-android/blob/master/gpuv/src/main/java/com/daasuu/gpuv/egl/filter/GlMonochromeFilter.java
Please help me with this
I tried to make a custom class for a filter that extends GLFilter class
below is code for my SepiaFilter and OverlayFilter.
public class SepiaFilter extends OverlayFilter {
private Bitmap bitmap;
private Position position = Position.LEFT_TOP;
private static final String FRAGMENT_SHADER =
"precision mediump float;" +
"varying vec2 vTextureCoord;" +
"uniform lowp sampler2D sTexture;" +
"const highp vec3 weight = vec3(0.2125, 0.7154, 0.0721);" +
"void main() {" +
" vec4 FragColor = texture2D(sTexture, vTextureCoord);\n" +
" gl_FragColor.r = dot(FragColor.rgb, vec3(.393, .769, .189));\n" +
" gl_FragColor.g = dot(FragColor.rgb, vec3(.349, .686, .168));\n" +
" gl_FragColor.b = dot(FragColor.rgb, vec3(.272, .534, .131));\n" +
"}";
public SepiaFilter(Bitmap bitmap)
{
super(FRAGMENT_SHADER);
this.bitmap = bitmap;
}
public SepiaFilter(Bitmap bitmap, Position position)
{
super(FRAGMENT_SHADER);
this.bitmap = bitmap;
this.position = position;
}
#Override
protected void drawCanvas(Canvas canvas) {
if (bitmap != null && !bitmap.isRecycled()) {
switch (position) {
case LEFT_TOP:
canvas.drawBitmap(bitmap, 0, 0, null);
break;
case LEFT_BOTTOM:
canvas.drawBitmap(bitmap, 0, canvas.getHeight() - bitmap.getHeight(), null);
break;
case RIGHT_TOP:
canvas.drawBitmap(bitmap, canvas.getWidth() - bitmap.getWidth(), 0, null);
break;
case RIGHT_BOTTOM:
canvas.drawBitmap(bitmap, canvas.getWidth() - bitmap.getWidth(), canvas.getHeight() - bitmap.getHeight(), null);
break;
}
}
}
public enum Position {
LEFT_TOP,
LEFT_BOTTOM,
RIGHT_TOP,
RIGHT_BOTTOM
}
}
public abstract class OverlayFilter extends GlFilter {
private int[] textures = new int[1];
private Bitmap bitmap = null;
protected Size inputResolution = new Size(1280, 720);
public OverlayFilter(String FRAGMENT_SHADER)
{
super(DEFAULT_VERTEX_SHADER, FRAGMENT_SHADER);
}
public void setResolution(Size resolution) {
this.inputResolution = resolution;
}
#Override
public void setFrameSize(int width, int height) {
super.setFrameSize(width, height);
setResolution(new Size(width, height));
}
private void createBitmap() {
releaseBitmap(bitmap);
bitmap = Bitmap.createBitmap(inputResolution.getWidth(), inputResolution.getHeight(), Bitmap.Config.ARGB_8888);
}
#Override
public void setup() {
super.setup();// 1
GLES20.glGenTextures(1, textures, 0);
GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, textures[0]);
GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MIN_FILTER, GLES20.GL_LINEAR);
GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MAG_FILTER, GLES20.GL_LINEAR);
GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_WRAP_S, GLES20.GL_CLAMP_TO_EDGE);
GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_WRAP_T, GLES20.GL_CLAMP_TO_EDGE);
createBitmap();
}
#Override
public void onDraw() {
if (bitmap == null) {
createBitmap();
}
if (bitmap.getWidth() != inputResolution.getWidth() || bitmap.getHeight() != inputResolution.getHeight()) {
createBitmap();
}
bitmap.eraseColor(Color.argb(0, 0, 0, 0));
Canvas bitmapCanvas = new Canvas(bitmap);
bitmapCanvas.scale(1, -1, bitmapCanvas.getWidth() / 2, bitmapCanvas.getHeight() / 2);
drawCanvas(bitmapCanvas);
int offsetDepthMapTextureUniform = getHandle("oTexture");// 3
GLES20.glActiveTexture(GLES20.GL_TEXTURE3);
GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, textures[0]);
if (bitmap != null && !bitmap.isRecycled()) {
GLUtils.texImage2D(GLES20.GL_TEXTURE_2D, 0, GLES20.GL_RGBA, bitmap, 0);
}
GLES20.glUniform1i(offsetDepthMapTextureUniform, 3);
}
protected abstract void drawCanvas(Canvas canvas);
public static void releaseBitmap(Bitmap bitmap) {
if (bitmap != null && !bitmap.isRecycled()) {
bitmap.recycle();
bitmap = null;
}
}
}
// code to apply filter
Bitmap watermark = BitmapFactory.decodeResource(getResources(), R.drawable.shashankimg);
GPUPlayerView gpuPlayerView.setGlFilter( new SepiaFilter(watermark));
Use GlFilterGroup class.
Usage is written read me.
Shouldn’t edit shader.
https://github.com/MasayukiSuda/GPUVideo-android/blob/master/gpuv/src/main/java/com/daasuu/gpuv/egl/filter/GlFilterGroup.java
I have been following the Android Developer Open GL tutorial and iv just trying to draw a square in my own program as am starting to rewrite my android game in Open GL as opposed to using the Canvas class. I have encountered a problem where it wont draw the square that i am trying to draw but it will color the background.
I am trying to draw the GLSquareEntity class which is extended from the GLEntity class, below is the code
GLSquareEntity Class:
public class GLSquareEntity extends GLEntity
{
public GLSquareEntity()
{
super();
cords = new float[] {
-0.5f, 0.5f, 0.0f, // top left
-0.5f, -0.5f, 0.0f, // bottom left
0.5f, -0.5f, 0.0f, // bottom right
0.5f, 0.5f, 0.0f }; // top right
CORDS_PER_VERTEX = 3;
drawOrder = new short[] { 0, 1, 2, 0 , 2, 3 };
// Initlise the class
setup();
}
}
GLEntity Class:
public class GLEntity
{
protected final String TAG = "GLENTITY";
// Shaders
private final String vertexShaderCode =
"uniform mat4 uMVPMatrix;" +
"attribute vec4 vPosition;" +
"void main() {" +
" gl_Position = uMVPMatrix * vPosition;" +
"}";
private final String fragmentShaderCode =
"precision mediump float;" +
"uniform vec4 vColor;" +
"void main() {" +
" gl_FragColor = vColor;" +
"}";
// Open GL Variables
protected FloatBuffer vertexBuffer;
protected ShortBuffer drawListBuffer;
protected short[] drawOrder;
protected int CORDS_PER_VERTEX;
protected int vertexStride;
protected int vertexCount;
protected float[] cords;
// Just unill i can get an image to display
protected float[] color = {0.0f, 0.0f, 1.0f, 1.0f};
protected int program;
protected int positionHandle;
protected int colorHandle;
public GLEntity()
{
}
protected void setup()
{
Log.d(TAG, "GLEntity Setup");
vertexStride = CORDS_PER_VERTEX * 4;
vertexCount = cords.length / CORDS_PER_VERTEX;
// Initilise buffer for vertex cordernats
ByteBuffer vbuffer = ByteBuffer.allocateDirect(cords.length * 4);
vbuffer.order(ByteOrder.nativeOrder());
vertexBuffer = vbuffer.asFloatBuffer();
vertexBuffer.put(cords);
vertexBuffer.position(0);
// Initilise buffer for the draw list
ByteBuffer dlbuffer = ByteBuffer.allocateDirect(drawOrder.length * 2);
dlbuffer.order(ByteOrder.nativeOrder());
drawListBuffer = dlbuffer.asShortBuffer();
drawListBuffer.put(drawOrder);
drawListBuffer.position(0);
// Set up the shaders
int vertexShader = OpenGLRenderer.loadShader(GLES20.GL_VERTEX_SHADER, vertexShaderCode);
int fragmentShader = OpenGLRenderer.loadShader(GLES20.GL_FRAGMENT_SHADER, fragmentShaderCode);
program = GLES20.glCreateProgram();
GLES20.glAttachShader(program, vertexShader);
GLES20.glAttachShader(program, fragmentShader);
GLES20.glLinkProgram(program);
}
public void draw()
{
//Log.d(TAG, "Drawing GL Entity");
// Select shader program to use
GLES20.glUseProgram(program);
positionHandle = GLES20.glGetAttribLocation(program, "vPosition");
GLES20.glEnableVertexAttribArray(positionHandle);
// Prepar the data
GLES20.glVertexAttribPointer(positionHandle, CORDS_PER_VERTEX, GLES20.GL_FLOAT, false, vertexStride, vertexBuffer);
// Prepare and set the color
colorHandle = GLES20.glGetUniformLocation(program, "vColor");
GLES20.glUniform4fv(colorHandle, 1, color, 0);
//GLES20.glDrawArrays(GLES20.GL_TRIANGLE_FAN, 0, vertexCount);
GLES20.glDrawElements(GLES20.GL_TRIANGLES, drawOrder.length, GLES20.GL_UNSIGNED_SHORT, drawListBuffer);
GLES20.glDisableVertexAttribArray(positionHandle);
}
}
The next classes are the GLSurfaceView class and the GLRenderer class
GLSurfaceView Class:
public class OpenGLSurfaceView extends GLSurfaceView
{
public OpenGLSurfaceView(Context context)
{
super(context);
// Set to OpenGL ES 2
setEGLContextClientVersion(2);
// Set the renderer for drawing
//OpenGLRenderer glRenderer = ;
setRenderer( new OpenGLRenderer() );
// Set to only rerender when function called
setRenderMode(GLSurfaceView.RENDERMODE_CONTINUOUSLY);
}
}
OpenGLRenderer Class:
public class OpenGLRenderer implements GLSurfaceView.Renderer
{
GLPlayer player;
#Override
public void onDrawFrame(GL10 gl)
{
GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT);
player.draw();
}
#Override
public void onSurfaceChanged(GL10 gl, int width, int height)
{
GLES20.glViewport(0, 0, width, height);
}
#Override
public void onSurfaceCreated(GL10 gl, EGLConfig config)
{
GLES20.glClearColor(0.0f, 1.0f, 0.0f, 1.0f);
player = new GLPlayer();
}
public static int loadShader(int type, String shaderCode)
{
int shader = GLES20.glCreateShader(type);
GLES20.glShaderSource(shader, shaderCode);
GLES20.glCompileShader(shader);
return shader;
}
}
Any help figuring out what the problem is would be much appreciated :)
Thanks
I've been trying to figure out how to port chapter 2 of these tutorials.
The code is only producing a black screen, and I can't figure out why. There are no errors produced.
package modern.opengl;
import java.awt.image.BufferedImage;
import java.awt.image.DataBufferByte;
import java.io.File;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.FloatBuffer;
import java.nio.ShortBuffer;
import java.util.logging.FileHandler;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.imageio.ImageIO;
import org.lwjgl.LWJGLException;
import org.lwjgl.input.Keyboard;
import org.lwjgl.input.Mouse;
import org.lwjgl.opengl.Display;
import org.lwjgl.opengl.DisplayMode;
import static org.lwjgl.opengl.GL11.*;
import static org.lwjgl.opengl.GL12.GL_BGR;
import static org.lwjgl.opengl.GL12.GL_CLAMP_TO_EDGE;
import static org.lwjgl.opengl.GL13.*;
import static org.lwjgl.opengl.GL15.*;
import static org.lwjgl.opengl.GL20.*;
import org.lwjgl.util.Timer;
public class Lesson01 {
public static final Logger logger = Logger.getLogger(Lesson01.class.getName());
static {
try {
logger.addHandler(new FileHandler("errors.log", true));
} catch (IOException ex) {
logger.log(Level.WARNING, ex.toString(), ex);
}
}
private int displayWidth;
private int displayHeight;
private String displayTitle;
private int vertexBuffer;
private int elementBuffer;
private int texture0;
private int texture1;
private int program;
private int uniformFadeFactor;
private int uniformTexture0;
private int uniformTexture1;
private int attributePosition;
private float fadeFactor;
private Timer timer;
public static void main(String[] args) {
Lesson01 lesson01 = null;
try {
lesson01 = new Lesson01();
lesson01.setup();
lesson01.run();
} catch (Exception ex) {
logger.log(Level.SEVERE, ex.toString(), ex);
} finally {
if (lesson01 != null) {
lesson01.teardown();
}
}
}
public Lesson01() {
timer = new Timer();
timer.resume();
displayWidth = 400;
displayHeight = 300;
displayTitle = "Lesson 01";
}
public void makeResources() throws Exception {
float[] vertexBufferDataArray = {-1.0f, -1.0f, 1.0f, -1.0f, -1.0f, 1.0f, 1.0f, 1.0f};
FloatBuffer vertexBufferData = ByteBuffer.allocateDirect(vertexBufferDataArray.length * 4).asFloatBuffer();
vertexBufferData.put(vertexBufferDataArray);
vertexBufferData.rewind();
vertexBuffer = glGenBuffers();
glBindBuffer(GL_ARRAY_BUFFER, vertexBuffer);
glBufferData(GL_ARRAY_BUFFER, vertexBufferData, GL_STATIC_DRAW);
short[] elementBufferDataArray = {0, 1, 2, 3};
ShortBuffer elementBufferData = ByteBuffer.allocateDirect(elementBufferDataArray.length * 2).asShortBuffer();
elementBufferData.put(elementBufferDataArray);
elementBufferData.rewind();
elementBuffer = glGenBuffers();
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, elementBuffer);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, elementBufferData, GL_STATIC_DRAW);
texture0 = makeTexture("hello1.png");
texture1 = makeTexture("hello2.png");
if (texture0 == 0 || texture1 == 0) {
throw new Exception("Failed to allocate textures!");
}
String vertexShaderSource =
"#version 110 \n"
+ "attribute vec2 position; \n"
+ "varying vec2 texcoord; \n"
+ "void main() \n"
+ "{ \n"
+ "gl_Position = vec4(position, 0.0, 1.0); \n"
+ "texcoord = position * vec2(0.5) + vec2(0.5); \n"
+ "} \n";
int vertexShader = glCreateShader(GL_VERTEX_SHADER);
glShaderSource(vertexShader, vertexShaderSource);
glCompileShader(vertexShader);
if (glGetShader(vertexShader, GL_COMPILE_STATUS) == 0) {
logger.log(Level.SEVERE, glGetShaderInfoLog(vertexShader, 10240));
throw new Exception("Failed to compile vertex shader!");
}
String fragmentShaderSource =
"#version 110 \n"
+ "uniform float fade_factor; \n"
+ "uniform sampler2D textures[2]; \n"
+ "varying vec2 texcoord; \n"
+ "void main() \n"
+ "{ \n"
+ " gl_FragColor = mix( \n"
+ " texture2D(textures[0], texcoord), \n"
+ " texture2D(textures[1], texcoord), \n"
+ " fade_factor \n"
+ " ); \n"
+ "} \n";
int fragmentShader = glCreateShader(GL_FRAGMENT_SHADER);
glShaderSource(fragmentShader, fragmentShaderSource);
glCompileShader(fragmentShader);
if (glGetShader(fragmentShader, GL_COMPILE_STATUS) == 0) {
logger.log(Level.SEVERE, glGetShaderInfoLog(fragmentShader, 10240));
throw new Exception("Failed to compule vertex shader!");
}
program = glCreateProgram();
glAttachShader(program, vertexShader);
glAttachShader(program, fragmentShader);
glLinkProgram(program);
if (glGetProgram(program, GL_LINK_STATUS) == 0) {
logger.log(Level.SEVERE, glGetProgramInfoLog(program, 10240));
throw new Exception("Failed to link shader program.");
}
uniformFadeFactor = glGetUniformLocation(program, "fade_factor");
uniformTexture0 = glGetUniformLocation(program, "textures[0]");
uniformTexture1 = glGetUniformLocation(program, "textures[1]");
attributePosition = glGetAttribLocation(program, "position");
}
public void setup() throws LWJGLException, Exception {
Display.setDisplayMode(new DisplayMode(displayWidth, displayHeight));
Display.setFullscreen(false);
Display.setTitle(displayTitle);
Display.create();
Keyboard.create();
Mouse.create();
makeResources();
}
public void teardown() {
Mouse.destroy();
Keyboard.destroy();
Display.destroy();
}
public void run() {
while (!Display.isCloseRequested()) {
Timer.tick();
if (Display.isVisible()) {
fadeFactor = (float) (Math.sin(timer.getTime()) * 0.5 + 0.5);
render();
} else {
if (Display.isDirty()) {
render();
}
try {
Thread.sleep(100);
} catch (InterruptedException ex) {
// Pass
}
}
Display.update();
Display.sync(60);
}
}
public void render() {
glUseProgram(program);
glUniform1f(uniformFadeFactor, fadeFactor);
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, texture0);
glUniform1i(uniformTexture0, 0);
glActiveTexture(GL_TEXTURE1);
glBindTexture(GL_TEXTURE_2D, texture1);
glUniform1i(uniformTexture1, 1);
glBindBuffer(GL_ARRAY_BUFFER, vertexBuffer);
glVertexAttribPointer(attributePosition, 2, GL_FLOAT, false, 8, 0);
glEnableVertexAttribArray(attributePosition);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, elementBuffer);
glDrawElements(GL_TRIANGLE_STRIP, 4, GL_SHORT, 0);
glDisableVertexAttribArray(attributePosition);
}
public static int makeTexture(String filename) throws IOException {
BufferedImage bufferedImage = ImageIO.read(new File(filename));
byte[] textureBufferArray = ((DataBufferByte) (bufferedImage.getRaster().getDataBuffer())).getData();
ByteBuffer textureBuffer = ByteBuffer.allocateDirect(textureBufferArray.length);
textureBuffer.put(textureBufferArray);
textureBuffer.rewind();
int textureId = glGenTextures();
glBindTexture(GL_TEXTURE_2D, textureId);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexImage2D(
GL_TEXTURE_2D,
0,
GL_RGB8,
bufferedImage.getWidth(),
bufferedImage.getHeight(),
0,
GL_BGR,
GL_UNSIGNED_BYTE,
textureBuffer
);
return textureId;
}
}
I guess you already found.
add the option -Dorg.lwjgl.util.Debug=true
I tried the same thing, and I think the error is at the line
glDrawElements(GL_TRIANGLE_STRIP, 4, GL_SHORT, 0);
from the specs http://www.opengl.org/sdk/docs/man/xhtml/glDrawElements.xml, the type can't be GL_SHORT.