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());
Related
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 new to OpenGL and I just begin to try LWJGL, everything worked fine until I added the PVM matrices, I don't know why nothing shows up when I added them.
The matrices related code is commented.
Here is the code :
public class Window {
private int vaoid;
private int vbover;
private int vboind;
private int vid;
private int fid;
private int pid;
//private int pml;projection matrix location
//private int vml;view matrix location
//private int mml;model matrix location
//private Matrix4f projectionMatrix;
//private Matrix4f viewMatrix;
//private Matrix4f modelMatrix;
//private FloatBuffer projbuffer = BufferUtils.createFloatBuffer(16);
public void start() {
try {
Display.setDisplayMode(new DisplayMode(800,600));
Display.setTitle("OpenGL Try");
Display.create();
} catch (LWJGLException e) {
e.printStackTrace();
System.exit(0);
}
init();
while (!Display.isCloseRequested()) {
update();
Display.sync(60);
Display.update();
}
cleanUp();
Display.destroy();
}
public static void main(String[] argv) {
Window displayExample = new Window();
displayExample.start();
}
public void init() {
//projectionMatrix = createProjectionMatrix();
float[] vertices = {
-0.5f, 0.5f, 0f, // Left top ID: 0
-0.5f, -0.5f, 0f, // Left bottom ID: 1
0.5f, -0.5f, 0f, // Right bottom ID: 2
0.5f, 0.5f, 0f // Right left ID: 3
};
FloatBuffer verticesbuffer = BufferUtils.createFloatBuffer(vertices.length);
verticesbuffer.put(vertices);
verticesbuffer.flip();
byte[] indices = {
// Left bottom triangle
0, 1, 2,
// Right top triangle
2, 3, 0
};
ByteBuffer indicesbuffer = BufferUtils.createByteBuffer(indices.length);
indicesbuffer.put(indices);
indicesbuffer.flip();
vaoid = GL30.glGenVertexArrays();
GL30.glBindVertexArray(vaoid);
vbover = GL15.glGenBuffers();
GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, vbover);
GL15.glBufferData(GL15.GL_ARRAY_BUFFER,verticesbuffer, GL15.GL_STATIC_DRAW);
GL20.glVertexAttribPointer(0,3,GL11.GL_FLOAT,false,0,0);
GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER,0);
GL30.glBindVertexArray(0);
vboind = GL15.glGenBuffers();
GL15.glBindBuffer(GL15.GL_ELEMENT_ARRAY_BUFFER,vboind);
GL15.glBufferData(GL15.GL_ELEMENT_ARRAY_BUFFER,indicesbuffer,GL15.GL_STATIC_DRAW);
GL15.glBindBuffer(GL15.GL_ELEMENT_ARRAY_BUFFER,0);
vid = loadShader("./res/shader.ver",GL20.GL_VERTEX_SHADER);
fid = loadShader("./res/shader.frag",GL20.GL_FRAGMENT_SHADER);
pid = GL20.glCreateProgram();
GL20.glAttachShader(pid,vid);
GL20.glAttachShader(pid, fid);
GL20.glBindAttribLocation(pid, 0, "in_position");
GL20.glLinkProgram(pid);
GL20.glValidateProgram(pid);
//pml = GL20.glGetUniformLocation(pid, "projMatrix");
//vml = GL20.glGetUniformLocation(pid, "viewMatrix");
//mml = GL20.glGetUniformLocation(pid, "modelMatrix");
GL20.glUseProgram(pid);
//projectionMatrix.store(projbuffer);
//projbuffer.flip();
//GL20.glUniformMatrix4(pml, false, projbuffer);
GL20.glUseProgram(0);
}
public void update() {
GL11.glClear(GL11.GL_COLOR_BUFFER_BIT|GL11.GL_DEPTH_BUFFER_BIT);
GL20.glUseProgram(pid);
//viewMatrix = createTransformationMatrix(new Vector3f(0,0,0),new Vector3f(0,0,0),1f);
//viewMatrix.store(projbuffer);projbuffer.flip();
//GL20.glUniformMatrix4(vml, false, projbuffer);
//modelMatrix = createTransformationMatrix(new Vector3f(0,0,0),new Vector3f(0,0,0),1f);
//modelMatrix.store(projbuffer);projbuffer.flip();
//GL20.glUniformMatrix4(mml, false, projbuffer);
GL30.glBindVertexArray(vaoid);
GL20.glEnableVertexAttribArray(0);
GL15.glBindBuffer(GL15.GL_ELEMENT_ARRAY_BUFFER,vboind);
GL11.glDrawElements(GL11.GL_TRIANGLES,6,GL11.GL_UNSIGNED_BYTE,0);
GL15.glBindBuffer(GL15.GL_ELEMENT_ARRAY_BUFFER,0);
GL20.glDisableVertexAttribArray(0);
GL30.glBindVertexArray(0);
GL20.glUseProgram(0);
}
public void cleanUp() {
GL20.glUseProgram(0);
GL20.glDetachShader(pid, vid);
GL20.glDetachShader(pid, fid);
GL20.glDeleteShader(vid);
GL20.glDeleteShader(fid);
GL20.glDeleteProgram(pid);
GL20.glDisableVertexAttribArray(0);
GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, 0);
GL15.glDeleteBuffers(vbover);
GL15.glBindBuffer(GL15.GL_ELEMENT_ARRAY_BUFFER, 0);
GL15.glDeleteBuffers(vboind);
GL30.glBindVertexArray(0);
GL30.glDeleteVertexArrays(vaoid);
}
public int loadShader(String filePath,int type) {
StringBuilder sb = new StringBuilder();
int shaderId = 0;
try {
BufferedReader br = new BufferedReader(new FileReader(filePath));
String line="";
while((line = br.readLine())!=null) {
sb.append(line).append("\n");
}
} catch (IOException e) {
e.printStackTrace();
System.exit(-1);
}
shaderId = GL20.glCreateShader(type);
GL20.glShaderSource(shaderId, sb);
GL20.glCompileShader(shaderId);
return shaderId;
}
/* public Matrix4f createTransformationMatrix(Vector3f pos,Vector3f
rot,float scale) {
Matrix4f mat = new Matrix4f();
Matrix4f.scale(new Vector3f(scale,scale,scale),mat,mat);
Matrix4f.translate(pos,mat,mat);
Matrix4f.rotate((float) Math.toRadians(rot.x),new
Vector3f(1,0,0),mat,mat);
Matrix4f.rotate((float) Math.toRadians(rot.y),new
Vector3f(0,1,0),mat,mat);
Matrix4f.rotate((float) Math.toRadians(rot.z),new
Vector3f(0,0,1),mat,mat);
return mat;
}*/
/*public Matrix4f createProjectionMatrix() {
Matrix4f pm = new Matrix4f();
float fieldOfView = 60f;
float aspectRatio = (float)Display.getWidth()/(float)Display.getHeight();
float znear = 0.1f;
float zfar = 100f;
float frustumLength = zfar-znear;
float ysize = (float) (1/Math.tan(Math.toRadians(fieldOfView/2f)));
float xsize = ysize/aspectRatio;
pm.m00 = xsize;
pm.m11 = ysize;
pm.m22 = -((znear+zfar)/frustumLength);
pm.m23 = -1;
pm.m32 = -((2*znear*zfar)/frustumLength);
pm.m33 = 0;
return pm;
} */
}
And the vertex shader :
#version 150 core
in vec3 in_position;
uniform mat4 projMatrix;
uniform mat4 viewMatrix;
uniform mat4 modelMatrix;
out vec4 pass_color;
void main(void){
gl_Position = projMatrix * viewMarix * modelMatrix *
vec4(in_position,1.0);
pass_color = vec4(1,0,1,1);
}
And the fragment shader :
#version 150 core
in vec4 pass_color;
out vec4 out_color;
void main(void){
out_color = pass_color;
}
Any help is appreciated ,that block me to continue learning the new opengl stuff, thank you.
I've noticed 3 problems.
You should use an IntBuffer instead of a ByteBuffer for the indices, because you store integers in this buffer. If you change the buffer type you need to also change GL_UNSIGNED_BYTE in glDrawElements to GL_UNSIGNED_INT.
Don't bind GL_ELEMENT_ARRAY_BUFFER to 0 after binding the indices buffer.
You don't need to bind and unbind GL_ELEMENT_ARRAY_BUFFER when calling glDarwElements
I hope this helps.
I'm doing some beginning work with shaders in LibGDX. I'm trying to set the color manually but all I get is white.
vertex shader:
attribute vec4 a_position;
uniform mat4 u_projTrans;
void main() {
gl_Position = u_projTrans * a_position;
gl_PointSize = 10.0;
}
fragment shader:
void main()
{
gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);
}
Extremely simple as you can see. With this setup I am able to draw shapes, but they always come out white. With my fragment shader I would expect everything to be red.
Am I missing something in the libgdx stack? Is something getting overridden further up the chain by some libgdx shader defaults or something?
Screen output:
Somehow you need to pass vertex to OpenGL so LibGDX having Mesh class for this requirement. I am using SpriteBatch that having own mesh that use to draw.
Vertex Shader :
attribute vec4 a_position;
uniform mat4 u_projTrans;
void main()
{
gl_Position = u_projTrans * a_position;
}
Fragment Shader :
#ifdef GL_ES
#define LOWP lowp
precision mediump float;
#else
#define LOWP
#endif
void main()
{
gl_FragColor = vec4(1,0,0,1);
}
ShaderTest
public class ShaderTest extends ApplicationAdapter {
SpriteBatch spriteBatch;
Texture texture;
ShaderProgram shaderProgram;
#Override
public void create() {
spriteBatch=new SpriteBatch();
shaderProgram=new ShaderProgram(Gdx.files.internal("default.vertex.glsl"),Gdx.files.internal("default.fragment.glsl"));
shaderProgram.pedantic = false;
if(shaderProgram.isCompiled()) {
System.out.println("Compiled Successfully");
spriteBatch.setShader(shaderProgram);
}else {
System.out.println("Some Problem in Shader");
}
texture=new Texture("badlogic.jpg");
}
#Override
public void render() {
Gdx.gl.glClearColor(1,1,0,1);
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
spriteBatch.begin();
spriteBatch.draw(texture,100,100);
spriteBatch.end();
}
#Override
public void dispose() {
shaderProgram.dispose();
texture.dispose();
spriteBatch.dispose();
}
}
And the output is :
EDIT
Mesh is nothing, It is just a big array of vertices, contains value that required by OpenGL and a single vertex can hold information about Position, Color, Texture Coordinates, or whatever else we would like to pass to the shaders.
According to question you fixed colour in fragment shader that is RED so you only need to pass position of quard to OpenGL.
public class QuardTest extends ApplicationAdapter {
Mesh quard;
OrthographicCamera cam;
ShaderProgram shaderProgram;
private int Idx = 0;
private float[] verts= new float[4 * 2];
#Override
public void create() {
cam=new OrthographicCamera();
shaderProgram=new ShaderProgram(Gdx.files.internal("default.vertex.glsl"),Gdx.files.internal("default.fragment.glsl"));
if(shaderProgram.isCompiled()) {
System.out.println("Compiled Successfully");
}else {
System.out.println("Some Problem in Shader");
}
quard =new Mesh(true,4,0,new VertexAttribute(VertexAttributes.Usage.Position, 2, "a_position"));
}
#Override
public void render() {
Gdx.gl.glClearColor(1,1,0,1);
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
drawRect(100,100,100,100);
drawRect(250,250,50,50);
}
public void drawRect(float x, float y, float width, float height){
if (Idx ==verts.length) {
flush();
}
verts[Idx++] = x;
verts[Idx++] = y;
verts[Idx++] = x + width;
verts[Idx++] = y;
verts[Idx++] = x + width;
verts[Idx++] = y + height;
verts[Idx++] = x;
verts[Idx++] = y + height;
}
public void flush(){
if (Idx ==0)
return;
quard.setVertices(verts);
Gdx.gl.glDepthMask(false);
int vertexCount = (Idx /2);
cam.setToOrtho(false, Gdx.graphics.getWidth(), Gdx.graphics.getHeight());
shaderProgram.begin();
shaderProgram.setUniformMatrix("u_projTrans", cam.combined);
quard.render(shaderProgram, GL20.GL_TRIANGLE_FAN, 0, vertexCount);
shaderProgram.end();
Gdx.gl.glDepthMask(true);
Idx =0;
}
}
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";
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