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.
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());
I have been using LWJGL 3 and a tutorial at LearnOpenGL.com in order to create a game engine. However, after following the tutorial, I have discovered that the use of glVertexAttribPointer is not working. It works when uploading vertex positions and indices, but when I try to upload color and texture coordinates, nothing's happening, and I'm just getting a white box. I have attached the source code of the render engine, main class, and shaders:
public class Mesh {
public float[] vertices;
public float[] colors;
public float[] textureCoords;
public int[] indices;
public Mesh(float[] vertices, float[] colors, float[] textureCoords, int[] indices) {
this.vertices = vertices;
this.colors = colors;
this.textureCoords = textureCoords;
this.indices = indices;
}
}
public class MasterRenderer {
private int vbo;
private int vao;
private int ebo;
private Mesh mesh;
private ShaderProgram program;
public void Init(Mesh mesh) {
this.mesh = mesh;
program = new ShaderProgram();
vao = GL30.glGenVertexArrays();
vbo = GL20.glGenBuffers();
ebo = GL20.glGenBuffers();
}
public void Render(Color clearColor) {
// Clear Screen
GL11.glClearColor(clearColor.getRed(), clearColor.getGreen(), clearColor.getBlue(), clearColor.getAlpha());
GL11.glClear(GL11.GL_COLOR_BUFFER_BIT | GL11.GL_DEPTH_BUFFER_BIT);
// Bind vao
GL30.glBindVertexArray(vao);
// Bind Buffers
GL20.glBindBuffer(GL20.GL_ARRAY_BUFFER, vbo);
GL20.glBufferData(GL20.GL_ARRAY_BUFFER, mesh.vertices, GL20.GL_STATIC_DRAW);
GL20.glBindBuffer(GL20.GL_ELEMENT_ARRAY_BUFFER, ebo);
GL20.glBufferData(GL20.GL_ELEMENT_ARRAY_BUFFER, mesh.indices, GL20.GL_STATIC_DRAW);
// Enable vertex attribPointers
GL20.glVertexAttribPointer(0, 3, GL11.GL_FLOAT, false, 0, 0);
GL20.glEnableVertexAttribArray(0);
// Handle Textures
Texture texture = Utils.LoadTexture("resources//textures//test.png");
// Uniforms
// Use Program
program.UseProgram();
// Draw the shape
GL20.glActiveTexture(GL20.GL_TEXTURE0);
GL20.glBindTexture(GL20.GL_TEXTURE_2D, texture.getId());
GL30.glBindVertexArray(vao);
GL20.glDrawElements(GL20.GL_TRIANGLES, 6, GL20.GL_UNSIGNED_INT, 0);
}
}
public class ShaderProgram {
public int programID;
public int vertexShaderID;
public int fragmentShaderID;
public ShaderProgram() {
programID = GL20.glCreateProgram();
try {
CompileVertexShader(Utils.LoadResource("resources/shaders/default/defaultShader.vs"));
CompileFragmentShader(Utils.LoadResource("resources/shaders/default/defaultShader.fs"));
GL20.glAttachShader(programID, vertexShaderID);
GL20.glAttachShader(programID, fragmentShaderID);
if(GL20.glGetShaderi(vertexShaderID, GL20.GL_COMPILE_STATUS) == 0) {
Logger.LogErrorClose("Error compiling vertex shader code: " + GL20.glGetShaderInfoLog(vertexShaderID, 1024));
}
if(GL20.glGetShaderi(fragmentShaderID, GL20.GL_COMPILE_STATUS) == 0) {
Logger.LogErrorClose("Error compiling fragment shader code: " + GL20.glGetShaderInfoLog(fragmentShaderID, 1024));
}
GL20.glLinkProgram(programID);
} catch (Exception e) {
e.printStackTrace();
}
}
public void UseProgram() {
GL20.glUseProgram(programID);
GL20.glDeleteShader(vertexShaderID);
GL20.glDeleteShader(fragmentShaderID);
}
public void CompileVertexShader(String shaderCode) {
vertexShaderID = GL20.glCreateShader(GL20.GL_VERTEX_SHADER);
GL20.glShaderSource(vertexShaderID, shaderCode);
GL20.glCompileShader(vertexShaderID);
}
public void CompileFragmentShader(String shaderCode) {
fragmentShaderID = GL20.glCreateShader(GL20.GL_FRAGMENT_SHADER);
GL20.glShaderSource(fragmentShaderID, shaderCode);
GL20.glCompileShader(fragmentShaderID);
}
}
public class Texture {
private int id;
public Texture(int id){
this.id = id;
}
public int getId(){
return id;
}
}
public class FoodFight {
public static void main(String[] args) {
Logger.LogMessage("Running on LWJGL Version: " + Version.getVersion());
Window w = new Window();
long window = w.CreateWindow(640, 360, "Food Fight");
MasterRenderer renderer = new MasterRenderer();
float[] vertices = {
0.5f, 0.5f, 0f,
0.5f, -0.5f, 0f,
-0.5f, -0.5f, 0f,
-0.5f, 0.5f, 0f
};
float[] colors = {
1f, 0f, 0f,
0f, 1f, 0f,
0f, 0f, 1f,
1f, 1f, 0f
};
float[] textureCoords = {
1f, 1f,
1f, 0f,
0f, 0f,
0f, 1f
};
int[] indices = {
0, 1, 3,
1, 2, 3
};
Mesh m = new Mesh(vertices, colors, textureCoords, indices);
renderer.Init(m);
while(!w.ShouldClose(window)) {
Input.ProcessInput(window);
renderer.Render(Color.black);
w.HandleWindow(window);
}
w.DestroyWindow(window);
}
}
Fragment:
#version 330 core
in vec3 color;
in vec2 texCoords;
out vec4 fragColor;
uniform sampler2D inputTexture;
void main() {
fragColor = texture(inputTexture, texCoords) * vec4(color, 1.0);
}
Vertex:
#version 330 core
in vec3 aPos;
in vec3 aColor;
in vec2 aTexCoord;
out vec3 color;
out vec2 texCoord;
void main() {
gl_Position = vec4(aPos, 1.0);
color = aColor;
texCoord = aTexCoord;
}
Since you have separate arrays for the vertex coordinates, colors and texture coordinates, you have specify separat buffers for the attributes:
vbo_ver = GL20.glGenBuffers();
vbo_col = GL20.glGenBuffers();
vbo_tex = GL20.glGenBuffers();
Creates and initializes the buffer object's data store
GL20.glBindBuffer(GL20.GL_ARRAY_BUFFER, vbo_ver);
GL20.glBufferData(GL20.GL_ARRAY_BUFFER, mesh.vertices, GL20.GL_STATIC_DRAW);
GL20.glBindBuffer(GL20.GL_ARRAY_BUFFER, vbo_col);
GL20.glBufferData(GL20.GL_ARRAY_BUFFER, mesh.colors, GL20.GL_STATIC_DRAW);
GL20.glBindBuffer(GL20.GL_ARRAY_BUFFER, vbo_tex);
GL20.glBufferData(GL20.GL_ARRAY_BUFFER, mesh.textureCoords, GL20.GL_STATIC_DRAW);
Specify the attribute indices, in the vertex shader by layout qualifiers:
#version 330 core
layout(location = 0) in vec3 aPos;
layout(location = 1) in vec3 aColor;
layout(location = 2) in vec2 aTexCoord;
glVertexAttribPointer associates the buffer which is currently bound to the ARRAY_BUFFER target, to the specified attribute (index), in the state vector of the currently bound Vertex Array Object. (See Vertex Specification).
Hence, the proper buffer and the VAO has to be bound before glVertexAttribPointer.
(The ELEMENT_ARRAY_BUFFER) is stated in the VAO, thus the VAO has to be bound before specifying the index buffer):
GL30.glBindVertexArray(vao);
GL20.glBindBuffer(GL20.GL_ELEMENT_ARRAY_BUFFER, ebo);
GL20.glBufferData(GL20.GL_ELEMENT_ARRAY_BUFFER, mesh.indices, GL20.GL_STATIC_DRAW);
GL20.glEnableVertexAttribArray(0);
GL20.glEnableVertexAttribArray(1);
GL20.glEnableVertexAttribArray(2);
GL20.glBindBuffer(GL20.GL_ARRAY_BUFFER, vbo_ver);
GL20.glVertexAttribPointer(0, 3, GL11.GL_FLOAT, false, 0, 0);
GL20.glBindBuffer(GL20.GL_ARRAY_BUFFER, vbo_col);
GL20.glVertexAttribPointer(1, 3, GL11.GL_FLOAT, false, 0, 0);
GL20.glBindBuffer(GL20.GL_ARRAY_BUFFER, vbo_tex);
GL20.glVertexAttribPointer(2, 2, GL11.GL_FLOAT, false, 0, 0);
Alternatively you can put the vertices and attributes to 1 array:
float[] attributes = {
// x y z r g b u v
0.5f, 0.5f, 0f, 1f, 0f, 0f, 1f, 1f,
0.5f, -0.5f, 0f, 0f, 1f, 0f, 1f, 0f,
-0.5f, -0.5f, 0f, 0f, 0f, 1f, 0f, 0f,
-0.5f, 0.5f, 0f, 1f, 1f, 0f 0f, 1f
};
vbo = GL20.glGenBuffers();
GL20.glBindBuffer(GL20.GL_ARRAY_BUFFER, vbo);
GL20.glBufferData(GL20.GL_ARRAY_BUFFER, mesh.attributes, GL20.GL_STATIC_DRAW);
The stride and the offset have to be specified in bates:
GL20.glBindBuffer(GL20.GL_ARRAY_BUFFER, vbo);
int stride = 8 * 4; // the tuple size is 8 (x y z r g b u v), sizeof float is 4
GL20.glVertexAttribPointer(0, 3, GL11.GL_FLOAT, false, stride, 0);
GL20.glVertexAttribPointer(1, 3, GL11.GL_FLOAT, false, stride, 3*4);
GL20.glVertexAttribPointer(2, 2, GL11.GL_FLOAT, false, stride, 6*4);
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 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 have adapted the code from Draw Text in OpenGL ES Android into my app, but the text isn't really showing up.
Here's what it currently looks like:
The green rectangle box is actually a Drawable bitmap.
I am expecting some sort of text, either white or black on top of the background, but nothing is ever showing up.
Here's the code for the Text class.
package gl.es;
import java.nio.*;
import android.content.Context;
import android.graphics.*;
import android.graphics.drawable.Drawable;
import android.opengl.*;
import android.opengl.Matrix;
public class Text {
public int textTexture;
public FloatBuffer textFloatBuffer;
public FloatBuffer textureFloatBuffer;
public int bufferSize;
public int program;
private final int textWidth = 112;
private final int textHeight = 16;
//private float posX;
private int aTextPositionLocation;
private int aTexturePositionLocation;
private int uMatrixLocation;
private int uTextureUnitLocation;
public Text(Context context) {
program = Shader.buildProgram(context, R.raw.text_vert, R.raw.text_frag);
aTextPositionLocation = GLES20.glGetAttribLocation(program, "a_textPosition");
aTexturePositionLocation = GLES20.glGetAttribLocation(program, "a_texturePosition");
uMatrixLocation = GLES20.glGetUniformLocation(program, "u_matrix");
uTextureUnitLocation = GLES20.glGetUniformLocation(program, "u_textureUnit");
textTexture = createTexture(context);
setBuffer();
//posX = 0f;
}
public int createTexture(Context context) {
//Create empty mutable bitmap.
Bitmap bitmap = Bitmap.createBitmap(textWidth, textHeight, Bitmap.Config.ARGB_8888);
//Use Canvas to paint over it.
Canvas canvas = new Canvas(bitmap);
bitmap.eraseColor(0);
//Draw background
Drawable background = context.getResources().getDrawable(R.drawable.text_bg);
background.setBounds(0, 0, 112, 16);
background.draw(canvas);
//Draw text
Paint textPaint = new Paint();
textPaint.setTextSize(6f);
textPaint.setAntiAlias(false);
textPaint.setARGB(0xff, 0, 0, 0);
//Draw text centered.
canvas.drawText("Text.", 0, 0, textPaint);
int[] texture = new int[1];
GLES20.glGenTextures(1, texture, 0);
GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, texture[0]);
GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MAG_FILTER, GLES20.GL_LINEAR);
GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MIN_FILTER, GLES20.GL_LINEAR);
GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_WRAP_S, GLES20.GL_REPEAT);
GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_WRAP_T, GLES20.GL_REPEAT);
GLUtils.texImage2D(GLES20.GL_TEXTURE_2D, 0, bitmap, 0);
//Recycle.
bitmap.recycle();
return texture[0];
}
public void setBuffer() {
final float[] vertexData = {
0f, 0f,
textWidth, 0f,
0f, textHeight,
0f, textHeight,
textWidth, 0f,
textWidth, textHeight
};
final float[] texData = {
0f, 1f,
1f, 1f,
0f, 0f,
0f, 0f,
1f, 1f,
1f, 0f
};
textFloatBuffer = ByteBuffer.allocateDirect(vertexData.length * 4).order(ByteOrder.nativeOrder()).asFloatBuffer();
textFloatBuffer.put(vertexData);
textureFloatBuffer = ByteBuffer.allocateDirect(texData.length * 4).order(ByteOrder.nativeOrder()).asFloatBuffer();
textureFloatBuffer.put(texData);
bufferSize = vertexData.length / 2;
}
public void transform(float[] model, float[] projection, float[] mvp) {
Matrix.setIdentityM(model, 0);
Matrix.translateM(model, 0, 0f, 0f, -60f);
Matrix.translateM(model, 0, -60f, 0f, 0f);
Matrix.multiplyMM(mvp, 0, projection, 0, model, 0);
//posX = (posX - 0.3f) % 112f;
}
public void setVertexPointers() {
textFloatBuffer.position(0);
GLES20.glVertexAttribPointer(aTextPositionLocation, 2, GLES20.GL_FLOAT, false, 2 * 4, textFloatBuffer);
GLES20.glEnableVertexAttribArray(aTextPositionLocation);
textFloatBuffer.position(0);
textureFloatBuffer.position(0);
GLES20.glVertexAttribPointer(aTexturePositionLocation, 2, GLES20.GL_FLOAT, false, 2 * 4, textureFloatBuffer);
GLES20.glEnableVertexAttribArray(aTexturePositionLocation);
textureFloatBuffer.position(0);
}
public void draw() {
GLES20.glDrawArrays(GLES20.GL_TRIANGLES, 0, bufferSize);
}
public void useProgram() {
GLES20.glUseProgram(program);
}
public void setUniforms(float[] matrix) {
GLES20.glUniformMatrix4fv(uMatrixLocation, 1, false, matrix, 0);
GLES20.glActiveTexture(GLES20.GL_TEXTURE1);
GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, textTexture);
GLES20.glUniform1i(uTextureUnitLocation, 1);
}
}
Could someone tell me where I'm doing wrong? What should I do in order to fix this? Thanks in advance.
UPDATE 1:
To answer deathember:
This is what happens when I changed the Matrix.transformM() to what you have suggested:
And here's the code that shows where I put my view matrix at:
package gl.es;
import javax.microedition.khronos.egl.EGLConfig;
import javax.microedition.khronos.opengles.GL10;
import android.content.Context;
import android.opengl.*;
public class MyRenderer implements GLSurfaceView.Renderer
{
Context context;
Text text;
float eyeX;
float eyeY;
float eyeZ;
private float[] modelMatrix;
private float[] viewMatrix;
private float[] projectionMatrix;
private float[] modelViewProjectionMatrix;
public MyRenderer(Context context) {
this.context = context;
modelMatrix = new float[16];
projectionMatrix = new float[16];
viewMatrix = new float[16];
modelViewProjectionMatrix = new float[16];
}
#Override
public void onSurfaceCreated(GL10 p1, EGLConfig config)
{
// TODO: Implement this method
GLES20.glClearColor(0.4f, 0.8f, 1.0f, 1.0f);
this.text = new Text(this.context);
}
#Override
public void onSurfaceChanged(GL10 p1, int width, int height)
{
// TODO: Implement this method
GLES20.glViewport(0, 0, width, height);
this.setPerspectiveM(45f, (float) (width) / (float) (height), 1f, 200f);
// Did not use view matrix at all for transformations of Text textures.
Matrix.setLookAtM(viewMatrix, 0, 0, 0, 0, 0, 0, 0, 0, 1f, 0); //Unused.
Matrix.setIdentityM(modelMatrix, 0);
projectionMatrix, 0, modelMatrix, 0);
}
#Override
public void onDrawFrame(GL10 p1)
{
// TODO: Implement this method
GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT);
text.transform(modelMatrix, projectionMatrix, modelViewProjectionMatrix);
text.useProgram();
text.setUniforms(modelViewProjectionMatrix);
text.setVertexPointers();
text.draw();
}
private void setPerspectiveM(float fov, float aspectRatio, float near, float far) {
final float anglesInRadians = (float) (fov * Math.PI / 180f);
final float angle = (float) (1f / Math.atan(anglesInRadians) / 2f);
projectionMatrix[0] = angle / aspectRatio;
projectionMatrix[1] = 0f;
projectionMatrix[2] = 0f;
projectionMatrix[3] = 0f;
projectionMatrix[4] = 0f;
projectionMatrix[5] = angle;
projectionMatrix[6] = 0f;
projectionMatrix[7] = 0f;
projectionMatrix[8] = 0f;
projectionMatrix[9] = 0f;
projectionMatrix[10] = -((far + near) / (far - near));
projectionMatrix[11] = -1f;
projectionMatrix[12] = 0f;
projectionMatrix[13] = 0f;
projectionMatrix[14] = -((2f * far * near) / (far - near));
projectionMatrix[15] = 0f;
}
}
Hope that helps.
Try to change
public void transform(float[] model, float[] projection, float[] mvp) {
Matrix.setIdentityM(model, 0);
Matrix.translateM(model, 0, 0f, 0f, -60f);
Matrix.translateM(model, 0, -60f, 0f, 0f);
Matrix.multiplyMM(mvp, 0, projection, 0, model, 0);
//posX = (posX - 0.3f) % 112f;
}
into
public void transform(float[] model, float[] projection, float[] mvp) {
Matrix.setIdentityM(model, 0);
Matrix.translateM(model, 0, 0f, 0f, 0f);
Matrix.multiplyMM(mvp, 0, projection, 0, model, 0);
//posX = (posX - 0.3f) % 112f;
}
And also set your view matrix look at center. May be you draw your text, but you can't see him. And where you set view matrix?
Add true inside view.getDrawingCache() as a parameter.
Note that on some devices and hardwares, this will never work. I found this out the hard way.