GL_POINTS draws a circle - java
I am encountering a problem whenever I draw a GL_POINT, it draws a circle while all the examples I am using show a square appear I have done some research and it appears it might be anti aliasing but nothing I try fixes it.
package main.ui;
import static com.jogamp.opengl.GL4.*;
import java.nio.FloatBuffer;
import com.jogamp.common.nio.Buffers;
import com.jogamp.opengl.GL2;
import com.jogamp.opengl.GL4;
import com.jogamp.opengl.GLAutoDrawable;
import com.jogamp.opengl.GLContext;
import com.jogamp.opengl.GLEventListener;
import com.jogamp.opengl.awt.GLCanvas;
public class CanvasHandler extends GLCanvas implements GLEventListener {
private static final long serialVersionUID = 1L;
private int rendering_program;
private int[] vao = new int[1];
public CanvasHandler(int x, int y, int width, int height) {
setBounds(x, y, width, height);
setVisible(true);
addGLEventListener(this);
}
#Override
public void display(GLAutoDrawable arg0) {
GL4 gl = (GL4) GLContext.getCurrentGL();
float colors[] = {1.0f, 0.0f, 0.0f, 1.0f};
FloatBuffer color = Buffers.newDirectFloatBuffer(colors);
gl.glClearBufferfv(GL_COLOR, 0 , color);
//Drawing handler
gl.glUseProgram(rendering_program);
gl.glPointSize(400f);
gl.glDrawArrays(GL_POINTS, 0, 1);
//System.out.println(GL_POINT);
}
#Override
public void init(GLAutoDrawable arg0) {
GL4 gl = (GL4) GLContext.getCurrentGL();
rendering_program = createShaderProgram();
gl.glGenVertexArrays(vao.length, vao, 0);
gl.glBindVertexArray(vao[0]);
}
private int createShaderProgram() {
GL4 gl = (GL4) GLContext.getCurrentGL();
String[] rawVertexShader = {
"#version 430 \n",
"void main(void) \n",
"{ gl_Position = vec4(0.0, 0.0, 0.0, 1.0); } \n"
};
String[] rawFragmentShader = {
"#version 430 \n",
"out vec4 color; \n",
"void main(void) \n",
"{ \n",
//"if(gl_FragCoord.x < 200) color = vec4(0.0, 1.0f, 0.0, 1.0f); else color = vec4(0.0f,0.0f,1.0f,1.0f);",
"color = vec4(0.0f, 0.0f, 1.0f, 1.0f);",
"} \n"
};
int vertexShader = gl.glCreateShader(GL_VERTEX_SHADER);
int fragmentShader = gl.glCreateShader(GL_FRAGMENT_SHADER);
gl.glShaderSource(vertexShader, rawVertexShader.length, rawVertexShader, null, 0);
gl.glShaderSource(fragmentShader, rawFragmentShader.length, rawFragmentShader, null, 0);
gl.glCompileShader(vertexShader);
gl.glCompileShader(fragmentShader);
int programid = gl.glCreateProgram();
gl.glAttachShader(programid, vertexShader);
gl.glAttachShader(programid, fragmentShader);
gl.glLinkProgram(programid);
gl.glDeleteShader(vertexShader);
gl.glDeleteShader(fragmentShader);
return programid;
}
#Override
public void dispose(GLAutoDrawable arg0) {
}
#Override
public void reshape(GLAutoDrawable arg0, int arg1, int arg2, int arg3, int arg4) {
}
}
The way it starts is in another class.
Try disabling point smoothing by calling the following before you render the points:
glDisable(GL_POINT_SMOOTH);
That being said, note that point drawing is quite driver-dependent, especially for large sizes (I have seen drivers that won't even go above a point size of 16ish). In general, GL_POINTS should only be used as a quick debug facility, and typically for much smaller sizes. When you need a rectangle, use GL_QUADS (with four vertices, one for each corner).
Related
GP/GPU : ping pong technique with JOGL
I've tried to implement an reaction-diffusion model on GPU with JOGL and GLSL. I use a ping pong technique with 2 FramebufferObject ( I've tried too with one FBO and 2 Colors attachements without success). Shader seems correct since I've tried it in unity (with some adaptations) and it works. After one week of trying many things, i'm completely out of idea to make this code works. I'm really not specialist of JOGL, so maybe i miss something evident. The result is an image which becomes white with time : no reaction-diffusion behaviors and I don't understand why ! Thanks in advance for helps. Here is my code : package gpu2; import java.awt.*; import java.awt.event.*; import javax.swing.*; import java.nio.IntBuffer; import java.nio.FloatBuffer; import java.io.File; import com.jogamp.opengl.GL2; import com.jogamp.opengl.GLAutoDrawable; import com.jogamp.opengl.GLEventListener; import com.jogamp.opengl.awt.GLCanvas; import com.jogamp.opengl.glu.GLU; import com.jogamp.opengl.util.FPSAnimator; import com.jogamp.opengl.GLFBODrawable; import com.jogamp.opengl.FBObject; import com.jogamp.opengl.FBObject.Colorbuffer; import com.jogamp.opengl.FBObject.ColorAttachment; import com.jogamp.opengl.FBObject.TextureAttachment; import com.jogamp.opengl.util.glsl.ShaderCode; import com.jogamp.opengl.util.glsl.ShaderProgram; import com.jogamp.opengl.util.glsl.ShaderUtil; import com.jogamp.opengl.util.GLBuffers; import com.jogamp.opengl.util.texture.Texture; import com.jogamp.opengl.util.texture.TextureIO; import com.jogamp.opengl.GLCapabilities; import com.jogamp.opengl.GLOffscreenAutoDrawable; import com.jogamp.opengl.GLProfile; import com.jogamp.opengl.util.awt.AWTGLReadBufferUtil; import com.jogamp.opengl.GLDrawableFactory; import static com.jogamp.opengl.GL.*; // GL constants import static com.jogamp.opengl.GL2.*; // GL2 constants import gpu2.ModelParam; /** * JOGL 2.0 Program Template (GLCanvas) * This is a "Component" which can be added into a top-level "Container". * It also handles the OpenGL events to render graphics. */ #SuppressWarnings("serial") public class JOGL2Setup_GLCanvas extends GLCanvas implements GLEventListener { // Define constants for the top-level container private static String TITLE = "JOGL 2.0 Setup (GLCanvas)"; // window's title private static final int CANVAS_WIDTH = 512; // width of the drawable private static final int CANVAS_HEIGHT = 512; // height of the drawable private static final int FPS = 30; // animator's target frames per second private final float[] canvasVertices = { -1f, -1f, 0.0f, -1f, 1f, 0.0f, 1f, -1f, 0.0f, 1f, 1f, 0.0f, }; private final float[] canvasTexCoords = { 0.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.0f, 1.0f, 1.0f, }; /** The entry main() method to setup the top-level container and animator */ public static void main(String[] args) { // Run the GUI codes in the event-dispatching thread for thread safety SwingUtilities.invokeLater(new Runnable() { #Override public void run() { // Create the OpenGL rendering canvas GLCanvas canvas = new JOGL2Setup_GLCanvas(); canvas.setPreferredSize(new Dimension(CANVAS_WIDTH, CANVAS_HEIGHT)); // Create a animator that drives canvas' display() at the specified FPS. final FPSAnimator animator = new FPSAnimator(canvas, FPS, true); // Create the top-level container final JFrame frame = new JFrame(); // Swing's JFrame or AWT's Frame frame.getContentPane().add(canvas); frame.addWindowListener(new WindowAdapter() { #Override public void windowClosing(WindowEvent e) { // Use a dedicate thread to run the stop() to ensure that the // animator stops before program exits. new Thread() { #Override public void run() { if (animator.isStarted()) animator.stop(); System.exit(0); } }.start(); } }); frame.setTitle(TITLE); frame.pack(); frame.setVisible(true); animator.start(); // start the animation loop } }); } // Setup OpenGL Graphics Renderer private GLU glu; // for the GL Utility private GL2 gl; //OpenGl data private int vboVertices; private int vboTextCoord; private Texture textureFile; private FBObject fbo[]; private ShaderProgram shaderCompute; private ShaderProgram shaderVisu; private ShaderProgram shaderComputeInit; private int currentSourceBuffer = 0; private int currentDestBuffer = 1; private int currentFrame = 0; private int maxFrameCount = 5000000; private float clearUniform = 0; ModelParam params = new ModelParam(); public JOGL2Setup_GLCanvas() { this.addGLEventListener(this); } #Override public void init(GLAutoDrawable drawable) { gl = drawable.getGL().getGL2(); // get the OpenGL graphics context glu = new GLU(); // get GL Utilities gl.glClearColor(0.0f, 0.0f, 0.0f, 0.0f); // set background (clear) color gl.glEnable(GL_TEXTURE_2D); gl.glEnable( GL_COLOR_MATERIAL ); gl.glEnable( GL_FRAMEBUFFER ); gl.glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NEAREST); // best perspective correction viewOrtho(gl); gl.glViewport(0,0,CANVAS_WIDTH,CANVAS_HEIGHT); int[] buffers = new int[2]; gl.glGenBuffers(2, buffers, 0); vboVertices = buffers[0]; vboTextCoord = buffers[1]; gl.glBindBuffer(GL_ARRAY_BUFFER, vboVertices); gl.glBufferData(GL_ARRAY_BUFFER, canvasVertices.length*(Float.SIZE/Byte.SIZE)*3, FloatBuffer.wrap(canvasVertices), GL_STATIC_DRAW); gl.glBindBuffer(GL_ARRAY_BUFFER, vboTextCoord); gl.glBufferData(GL_ARRAY_BUFFER, canvasTexCoords.length*(Float.SIZE/Byte.SIZE)*2, FloatBuffer.wrap(canvasTexCoords), GL_STATIC_DRAW); gl.glBindBuffer( GL_ARRAY_BUFFER, 0 ); // ------------ create Texture Source------------------------ textureFile = initializeTexture(); if (textureFile==null) { System.out.println("cannot load texture from disk"); } // ------------ load shaders ------------------------ shaderCompute = loadShader(gl, "compute.vsh", "compute.fsh"); shaderComputeInit = loadShader(gl, "compute.vsh", "computeInit.fsh"); shaderVisu = loadShader(gl, "visu.vsh", "visu.fsh"); // ------------ create FBO ------------------------ initFBO(); } /** * Called back by the animator to perform rendering. */ #Override public void display(GLAutoDrawable drawable) { if (currentFrame < maxFrameCount) { prepareNextStep(); renderToFBO(); currentFrame++; } renderFBOToScreen(); } private void prepareNextStep() { currentSourceBuffer = 1 - currentSourceBuffer; currentDestBuffer = 1 - currentDestBuffer; } private void renderToFBO() { fbo[currentDestBuffer].bind(gl); //gl.glClear(GL_COLOR_BUFFER_BIT); viewOrtho(gl); shaderCompute.useProgram(gl, true); setShaderUniformFloat(gl, shaderCompute.program(), "diffuseU", 0.211f); setShaderUniformFloat(gl, shaderCompute.program(), "diffuseV", 0.088f); setShaderUniformFloat(gl, shaderCompute.program(), "feed", 0.007f); setShaderUniformFloat(gl, shaderCompute.program(), "kill", 0.08f); setShaderUniformFloat(gl, shaderCompute.program(), "Tech", 1f); setShaderUniformFloat(gl, shaderCompute.program(), "currentFrame", currentFrame); setShaderUniformFloat2(gl, shaderCompute.program(), "resolution", CANVAS_WIDTH, CANVAS_HEIGHT); drawDataBuffer(shaderCompute, true); shaderCompute.useProgram(gl, false); fbo[currentDestBuffer].unbind(gl); } void drawDataBuffer(ShaderProgram currentShader, boolean sencondImage) { // --- draw vbo gl.glEnableClientState(GL_VERTEX_ARRAY); gl.glEnableClientState(GL_TEXTURE_COORD_ARRAY); //textcoords gl.glBindBuffer(GL_ARRAY_BUFFER,vboTextCoord); gl.glTexCoordPointer(2, GL_FLOAT, 0, 0); //vertices gl.glBindBuffer( GL_ARRAY_BUFFER, vboVertices ); gl.glVertexPointer(3, GL_FLOAT, 0, 0); //activate texture data from last fbo final FBObject.Colorbuffer texSource = (FBObject.Colorbuffer) fbo[currentSourceBuffer].getColorbuffer(0); gl.glActiveTexture(GL_TEXTURE0); gl.glBindTexture(GL_TEXTURE_2D, texSource.getName()); setShaderUniform1i(gl, currentShader.program(), "textureData", 0); if (sencondImage) { //activate texture with image from file gl.glActiveTexture(GL_TEXTURE1); gl.glBindTexture(GL_TEXTURE_2D, textureFile.getTextureObject()); textureFile.bind(gl); setShaderUniform1i(gl, currentShader.program(), "textureImage", 1); } //draw buffer on screens gl.glDrawArrays(GL_TRIANGLE_STRIP, 0, canvasVertices.length / 3); //disable texture image if (sencondImage) { gl.glActiveTexture(GL_TEXTURE1); textureFile.disable(gl); } //disable texture data gl.glActiveTexture(GL_TEXTURE0); gl.glDisable(texSource.getName()); gl.glDisableClientState(GL_TEXTURE_COORD_ARRAY); gl.glDisableClientState(GL_VERTEX_ARRAY); } public void renderFBOToScreen() { gl.glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // clear color and depth buffers gl.glLoadIdentity(); // reset the model-view matrix viewOrtho(gl); gl.glEnable(GL_TEXTURE_2D); final FBObject.Colorbuffer tex0 = (FBObject.Colorbuffer) fbo[currentDestBuffer].getColorbuffer(0); gl.glActiveTexture(GL_TEXTURE0); gl.glBindTexture(GL_TEXTURE_2D, tex0.getName()); //activate shader shaderVisu.useProgram(gl, true); // --- draw vbo gl.glEnableClientState(GL_VERTEX_ARRAY); gl.glEnableClientState(GL_TEXTURE_COORD_ARRAY); //textcoords gl.glBindBuffer(GL_ARRAY_BUFFER, vboTextCoord); gl.glTexCoordPointer(2, GL_FLOAT, 0, 0); //vertices gl.glBindBuffer( GL_ARRAY_BUFFER, vboVertices ); gl.glVertexPointer(3, GL_FLOAT, 0, 0); //draw buffer on screens gl.glDrawArrays(GL_TRIANGLE_STRIP, 0, canvasVertices.length / 3); gl.glDisableClientState(GL_TEXTURE_COORD_ARRAY); gl.glDisableClientState(GL_VERTEX_ARRAY); gl.glBindBuffer( GL_ARRAY_BUFFER, 0 ); //desactivate shader shaderVisu.useProgram(gl, false); } private void initFBO() { try { gl.glEnable(GL_TEXTURE_2D); fbo = new FBObject[2]; //first fbo fbo[currentSourceBuffer] = new FBObject(); // Create FrameBuffer fbo[currentSourceBuffer].init(gl, CANVAS_WIDTH, CANVAS_HEIGHT, 0); fbo[currentSourceBuffer].reset(gl, CANVAS_WIDTH, CANVAS_HEIGHT, 0); // int width, height - size of FBO, can be resized with the same call fbo[currentSourceBuffer].bind(gl); int tex = genTexture(gl); gl.glBindTexture(GL_TEXTURE_2D, tex); gl.glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA32F, CANVAS_WIDTH, CANVAS_HEIGHT, 0, GL_RGBA, GL_FLOAT, null); fbo[currentSourceBuffer].attachTexture2D(gl, 0, GL_RGBA32F, GL_RGBA, GL_FLOAT, GL_NEAREST, GL_NEAREST, GL_CLAMP_TO_EDGE, GL_CLAMP_TO_EDGE); //gl.glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, tex, 0); int DrawBuffers[] = {GL_COLOR_ATTACHMENT0}; gl.glDrawBuffers(1, DrawBuffers, 0); // "1" is the size of DrawBuffers fbo[currentSourceBuffer].unbind(gl); //second fbo fbo[currentDestBuffer] = new FBObject(); // Create FrameBuffer fbo[currentDestBuffer].init(gl, CANVAS_WIDTH, CANVAS_HEIGHT, 0); fbo[currentDestBuffer].reset(gl, CANVAS_WIDTH, CANVAS_HEIGHT, 0); // int width, height - size of FBO, can be resized with the same call fbo[currentDestBuffer].bind(gl); tex = genTexture(gl); gl.glBindTexture(GL_TEXTURE_2D, tex); gl.glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA32F, CANVAS_WIDTH, CANVAS_HEIGHT, 0, GL_RGBA, GL_FLOAT, null); fbo[currentDestBuffer].attachTexture2D(gl, 0, GL_RGBA32F, GL_RGBA, GL_FLOAT, GL_NEAREST, GL_NEAREST, GL_CLAMP_TO_EDGE, GL_CLAMP_TO_EDGE); //ogl.glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, tex, 0); gl.glDrawBuffers(1, DrawBuffers, 1); // "1" is the size of DrawBuffers fbo[currentDestBuffer].unbind(gl); } catch (Exception e) { System.out.println("Problem with fbo init " + e); e.printStackTrace(); } } private Texture initializeTexture() { Texture t = null; try { t = TextureIO.newTexture(new File("e:/shaders/wiki.jpg"), false); t.setTexParameteri(gl, GL_TEXTURE_MIN_FILTER, GL_LINEAR); t.setTexParameteri(gl, GL_TEXTURE_MAG_FILTER, GL_LINEAR); t.setTexParameteri(gl, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); t.setTexParameteri(gl, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); } catch (Exception e) { System.out.println("Unable to read texture file: " + e); e.printStackTrace(); } return t; } private ShaderProgram loadShader(GL2 gl, String vertexShader, String fragmentShader) { ShaderCode vertShader = ShaderCode.create(gl, GL2.GL_VERTEX_SHADER, 1, getClass(), new String[]{"e:/shaders/"+vertexShader},false); vertShader.compile(gl); ShaderCode fragShader = ShaderCode.create(gl, GL2.GL_FRAGMENT_SHADER, 1, getClass(), new String[]{"e:/shaders/"+fragmentShader},false); fragShader.compile(gl); ShaderProgram newShader = new ShaderProgram(); newShader.init(gl); newShader.add(vertShader); newShader.add(fragShader); newShader.link(gl, System.out); vertShader.destroy(gl); fragShader.destroy(gl); return newShader; } public static void setShaderUniform1i(GL2 inGL,int inProgramID,String inName,int inValue) { int tUniformLocation = inGL.glGetUniformLocation(inProgramID,inName); if (tUniformLocation != -1) { inGL.glUniform1i(tUniformLocation, inValue); } else { System.out.println("UNIFORM COULD NOT BE FOUND! NAME="+inName); } } public static void setShaderUniformFloat(GL2 inGL,int inProgramID,String inName,float inValue) { int tUniformLocation = inGL.glGetUniformLocation(inProgramID,inName); if (tUniformLocation != -1) { inGL.glUniform1f(tUniformLocation, inValue); } else { System.out.println("UNIFORM COULD NOT BE FOUND! NAME="+inName); } } public static void setShaderUniformFloat2(GL2 inGL,int inProgramID,String inName,float inValue1 ,float inValue2) { int tUniformLocation = inGL.glGetUniformLocation(inProgramID,inName); if (tUniformLocation != -1) { inGL.glUniform2f(tUniformLocation, inValue1, inValue2); } else { System.out.println("UNIFORM COULD NOT BE FOUND! NAME="+inName); } } private void viewOrtho(GL2 gl) // Set Up An Ortho View { gl.glMatrixMode(GL_PROJECTION); // Select Projection gl.glPushMatrix(); // Push The Matrix gl.glLoadIdentity(); // Reset The Matrix gl.glOrtho(-1.0, 1.0, -1.0, 1.0, -1.0, 1.0); gl.glMatrixMode(GL_MODELVIEW); // Select Modelview Matrix gl.glPushMatrix(); // Push The Matrix gl.glLoadIdentity(); // Reset The Matrix } private int genTexture(GL2 gl) { final int[] tmp = new int[1]; gl.glGenTextures(1, tmp, 0); return tmp[0]; } /** * Called back before the OpenGL context is destroyed. Release resource such as buffers. */ #Override public void dispose(GLAutoDrawable drawable) { } } And the corresponding GLSL Shader : #version 120 uniform sampler2D textureData; uniform sampler2D textureImage; uniform vec2 resolution; uniform float diffuseU; uniform float diffuseV; uniform float feed; uniform float kill; uniform float Tech = 1.0; uniform float currentFrame = 0.0; void main() { //coords vec2 position = ( gl_FragCoord.xy / resolution.xy ); vec2 pixel = 1./resolution; //get data from texture vec4 imgSource = texture2D(textureImage, gl_TexCoord[0].st); vec2 oldUV = texture2D(textureData, gl_TexCoord[0].st).rg; if(currentFrame<10){ if (distance(position,vec2(0.5,0.5 - currentFrame * 0.01f)) < 0.2f) oldUV = vec2(0.0,0.2); else if (distance(position,vec2(0.5,0.5 - currentFrame * 0.01f)) < 0.3f) oldUV = vec2(0.5,0.1); else oldUV = vec2(0.1,0.0); gl_FragColor = vec4(oldUV.rg, 0.0, 1.0); return; } //get neightboors vec2 dataUp = texture2D(textureData, position + pixel * vec2(0., 1.)).rg; vec2 dataDown = texture2D(textureData, position + pixel * vec2(0., -1.)).rg; vec2 dataLeft = texture2D(textureData, position + pixel * vec2(-1., 0.)).rg; vec2 dataRight = texture2D(textureData, position + pixel * vec2(1., 0.)).rg; //adapt parameters vec2 imgParam = imgSource.rg; float dU = diffuseU ;//+ 0.01 * (imgParam - 0.5); float dV = diffuseV ;//+ 0.01 * (imgParam - 0.5); float F = feed ;//+ 0.01 * (imgParam - 0.5); float K = kill ;//+ 0.01 * (imgParam - 0.5); //compute new values vec2 laplace = (dataUp+dataDown+dataLeft+dataRight) - 4.0 * oldUV; float uvv = oldUV.r * oldUV.g * oldUV.g; // calculate delta quantities float du = dU * laplace.r - uvv + F*(1.0 - oldUV.r); float dv = dV * laplace.g + uvv - (F+K)*oldUV.g; vec2 newUV = oldUV + vec2(du, dv)* Tech; gl_FragColor = vec4(newUV.rg, 0.0, 1.0); }
Few considerations: avoid deprecated OpenGL (and GLU), use GL4 (or GL3) unless you need awt/swt/swing, prefer newt, more here prefer Animator instead of FPSAnimator, more here prefer direct buffers instead of arrays, since otherwise jogl has to create them underneath and you can't keep trace (= deallocate when done) of those native allocations GL4 will allow you also to avoid all those uniform overhead (and also potential bugs) you have to deal with (especially during runtime), thanks to explicit locations prefer direct buffer management instead of FBObject for the moment unless you really know what FBObject is doing. Once you get it working, you can move on using that class. This may be (one of the) cause your code is not working, because something is not getting setup up as you need. Moreover, the lines of codes needed to replace FBObject are essentially the same (if you can't use explicit location for any reason) prefer some literal way to define the texture uniform location, it is usually another tricky part causing bugs, something like this prefer also a sampler for the textures, gives you more flexibility don't wait one week next time, let us know earlier! :) Frustation can be a nasty thing that put you down easily. Together we can help you getting it working ;)
Is it possible to draw more than one object using OpenGL ES 2.0
This is an update to a question I recently asked, but with new problems after I tried some stuff. What I want is to draw multiple circles on the screen. I created a class for the circle object. In my renderer class, I created an array list of these circles each with a different position. When called to draw, it only draws one of them. I logged what was going on and each object is being called to get drawn, but it seems only one appears on the screen. It's not just my circles. It appears throughout personal testing OpenGL ES 2.0 will only draw one object on the screen. I have no idea how to fix this. Is there something special I have to do in OpenGL ES 2.0? Here is my code. Ignore the incredibly sloppy and inefficient code right now. I am aware of it and will fix it later. Here is my circle object class: GLCircle: package com.background.gl.objects; import static android.opengl.GLES20.GL_TRIANGLE_FAN; import static android.opengl.GLES20.glDrawArrays; import static android.opengl.Matrix.multiplyMM; import static android.opengl.Matrix.setIdentityM; import static android.opengl.Matrix.translateM; import static com.background.gl.glcirclebackgroundanimation.Constants.BYTES_PER_FLOAT; import java.util.Random; import android.opengl.Matrix; import android.util.Log; import com.background.gl.data.VertexArray; import com.background.gl.helper.TextureShaderProgram; public class GLCircle { private static final int POSITION_COMPONENT_COUNT = 2; private static final int TEXTURE_COORDINATES_COMPONENT_COUNT = 2; private static final int STRIDE = (POSITION_COMPONENT_COUNT + TEXTURE_COORDINATES_COMPONENT_COUNT) * BYTES_PER_FLOAT; public float x; public float y; protected float[] wallBounds; protected boolean positiveX, positiveY; public boolean nullify; protected float xCounter = 0f; protected float yCounter = 0f; public float[] bounds; protected Random ran; private float[] VERTEX_DATA = { // Order of coordinates: X, Y, S, T // Triangle Fan 0f, 0f, 0.5f, 0.5f, -0.25f, -0.25f, 0f, 0.9f, 0.25f, -0.25f, 1f, 0.9f, 0.25f, 0.25f, 1f, 0.1f, -0.25f, 0.25f, 0f, 0.1f, -0.25f, -0.25f, 0f, 0.9f }; private final VertexArray vertexArray; public GLCircle(float x, float y) { vertexArray = new VertexArray(VERTEX_DATA); ran = new Random(); wallBounds = new float[4]; nullify = false; this.x = x; this.y = y; } public void bindData(TextureShaderProgram textureProgram) { //Bind the position data to the shader attribute vertexArray.setVertexAttribPointer( 0, textureProgram.getPositionAttributeLocation(), POSITION_COMPONENT_COUNT, STRIDE); //Bind the texture coordinate data to the shader attribute vertexArray.setVertexAttribPointer( POSITION_COMPONENT_COUNT, textureProgram.getTextureCoordinatesAttributeLocation(), TEXTURE_COORDINATES_COMPONENT_COUNT, STRIDE); } public void drawCircle() { glDrawArrays(GL_TRIANGLE_FAN, 0, 6); } public float getX() { return this.x; } public float getY() { return this.y; } public boolean isPositiveX() { return positiveX; } public boolean isPositiveY() { return positiveY; } public float[] getBounds(float ranX, float ranY) { if(!positiveX) { /*if(ranX >= 0f) { wallBounds[0] = 1.05f + ranX; } else {*/ this.wallBounds[0] = 1.05f + ranX; //} } else { /* if(ranX >= 0f) { wallBounds[0] = 1.05f - ranX; } else {*/ this.wallBounds[1] = 1.05f - ranX; //} } if(!positiveY) { this.wallBounds[2] = 1.75f + ranY; } else { this.wallBounds[3] = 1.75f - ranY; } return this.wallBounds; } public void setPos(float[] modelMatrix, float[] projectionMatrix, TextureShaderProgram textureProgram, int texture, float x, float y, String log) { setIdentityM(modelMatrix, 0); translateM(modelMatrix, 0, 0f, 0.01f, 0f); final float[] temp = new float[16]; multiplyMM(temp, 0, projectionMatrix, 0, modelMatrix, 0); System.arraycopy(temp, 0, projectionMatrix, 0, temp.length); textureProgram.useProgram(); textureProgram.setUniforms(projectionMatrix, texture); bindData(textureProgram); drawCircle(); Log.d("Drawing", "Drawing " + log); } public void scaleCircle(float[] modelMatrix, float x, float y, float z) { Matrix.scaleM(modelMatrix, 0, x, y, z); } public void storeResults(float[] results) { this.x = results[0]; this.y = results[1]; } public void translateCircle(float x, float[] modelMatrix, float[] projectionMatrix) { setIdentityM(modelMatrix, 0); translateM(modelMatrix, 0, /*-0.001f*/ x, -3f, -2f); final float[] temp = new float[16]; multiplyMM(temp, 0, projectionMatrix, 0, modelMatrix, 0); System.arraycopy(temp, 0, projectionMatrix, 0, temp.length); } } Again, I'm aware of most things I'm doing incorrectly, but currently I just need to figure out why I can't draw multiple objects on the screen. Here is my renderer code: package com.background.gl.glcirclebackgroundanimation; import static android.opengl.GLES20.GL_COLOR_BUFFER_BIT; import static android.opengl.GLES20.glClear; import static android.opengl.GLES20.glClearColor; import static android.opengl.GLES20.glViewport; import static android.opengl.Matrix.multiplyMM; import static android.opengl.Matrix.setIdentityM; import static android.opengl.Matrix.translateM; import java.util.ArrayList; import java.util.List; import java.util.Random; import javax.microedition.khronos.egl.EGLConfig; import javax.microedition.khronos.opengles.GL10; import android.content.Context; import android.opengl.GLSurfaceView.Renderer; import android.util.Log; import com.background.gl.helper.TextureShaderProgram; import com.background.gl.objects.GLCircle; import com.background.gl.objects.Mallet; import com.background.gl.objects.Table; import com.background.gl.util.MatrixHelper; import com.background.gl.util.TextureHelper; public class CircleDynamicBackgroundRenderer implements Renderer { private final Context context; private final float[] projectionMatrix = new float[16]; private final float[] modelMatrix = new float[16]; protected static float ranX, ranY, ranSignX, ranSignY, ranSignVeloX, ranSignVeloY; public boolean logNums; private Table table; private Mallet mallet; private List<GLCircle> circles; private GLCircle circle2; float xPos, yPos; int x = 1; float[] bounds; Random ran; private TextureShaderProgram textureProgram; private int texture; public CircleDynamicBackgroundRenderer(Context context) { this.context = context; circles = new ArrayList<GLCircle>(); xPos = 0.1f; ran = new Random(); logNums = true; } #Override public void onSurfaceChanged(GL10 glUnused, int width, int height) { glViewport(0, 0, width, height); Log.w("Width and height", Integer.toString(width) + ", " + Integer.toString(height)); MatrixHelper.perspectiveM(projectionMatrix, 90, (float) width / (float) height, 1f, 10f); for(int i = 0; i < circles.size(); i++) { circles.get(i).translateCircle(circles.get(i).x, modelMatrix, projectionMatrix); } // /circle2.translateCircle(circle2.x, modelMatrix); /*final float[] temp = new float[16]; multiplyMM(temp, 0, projectionMatrix, 0, modelMatrix, 0); System.arraycopy(temp, 0, projectionMatrix, 0, temp.length);*/ } #Override public void onSurfaceCreated(GL10 glUnused, EGLConfig config) { glClearColor(0.0f, 0.0f, 1.0f, 0.0f); table = new Table(); mallet = new Mallet(); textureProgram = new TextureShaderProgram(context); texture = TextureHelper.loadTexture(context, R.drawable.air_hockey_surface); //texture2 = TextureHelper.loadTexture(context, R.drawable.air_hockey_surface_2); for(int i = 0; i < 3; i++) { GLCircle circle = new GLCircle(generateRanFloats()[0], generateRanFloats()[1]); circles.add(circle); /*circle[i].x = circle[i].getX(); circle[i].y = circle[i].getY(); circle[i].bounds = circle[i].getBounds();*/ } //circle2 = new GLCircle(generateRanFloats()[0], generateRanFloats()[1]); Log.d("Circles size", Integer.toString(circles.size())); Log.d("circles", Float.toString(circles.get(1).getX()) + " " + Float.toString(circles.get(2).getX())); } #Override public void onDrawFrame(GL10 glUnused) { //Clear the rendering surface glClear(GL_COLOR_BUFFER_BIT); for(int i = 0; i < circles.size(); i++) { circles.get(i).setPos(modelMatrix, projectionMatrix, textureProgram, texture, circles.get(i).x, circles.get(i).y, "1"); if(logNums) { Log.d("Circle1, c2", Float.toString(circles.get(i).x) + ", " + Float.toString(circles.get(i).x)); logNums = false; } //Log.d("Circles", Float.toString(circles.get(i).x)); } } public float[] generateRanFloats() { ranSignX = ran.nextFloat(); ranSignY = ran.nextFloat(); ranSignX = ranSignX > 0.5f? -1:1; ranSignY = ranSignY > 0.5f? -1:1; ranSignVeloX = ran.nextFloat(); ranSignVeloY = ran.nextFloat(); ranX = ran.nextFloat() * 1.05f; ranY = ran.nextFloat() * 1.75f; ranX = ranSignX > 0.5? -ranX:ranX; ranY = ranSignY > 0.5? -ranY:ranY; Log.d("Generated", Float.toString(ranX)); return new float[] {ranX, ranY}; } } It's been two days now and I cannot for the live of me figure out what is wrong and how to fix this. I really need to figure out a way to fix this. Any assistance will be greatly appreciated. If you need to see more code, let me know.
Per the last discussion - did you work on the perspective matrix ? I would recommend first starting with the ortho projection, get your code working, then move to working with perspective projection. You can use the below as a starting point for ortho projection. mat4.ortho(-1.0, 1.0, -1, 1.0, -10.0, 100.0, projectionMatrix); Also remove all the z translations in your code, make your code work on xy, then add z translations. PS: Isnt it better to continue in the same thread as (OpenGL ES 2.0 only draws the object once) ?
Android Open GL not drawing square
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
Basic GLSL shaders not working
So I've tried to follow some tutorials on OpenGL and GLSL. I'm writing them in Java, using JOGL2, Original is in C++ though. All code compiles without any problems, shader preview in Shader designer even shows right effect, but when I run my app, it only draws blank white triangle. I can't find where am I making a mistake at all-.- btw my graphics card is Geforce GT330M, supports OpenGL 3.3, GLSL 3.30. newest drivers installed, so that shouldnt be a problem I guess. My code for loading and creating a shader: package OpenGL33.Utils; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.util.ArrayList; import javax.media.opengl.GL3; public class ShaderUtils { public int createProgram(GL3 gl, String vertexSource, String fragmentSource) throws IOException{ int v = gl.glCreateShader(GL3.GL_VERTEX_SHADER); int f = gl.glCreateShader(GL3.GL_FRAGMENT_SHADER); String[] strings; /* * vertex shader */ strings = loadResource(vertexSource); gl.glShaderSource(v, strings.length, strings, (int[]) null, 0); gl.glCompileShader(v); /* * fragment shader */ strings = loadResource(fragmentSource); gl.glShaderSource(f, strings.length, strings, (int[]) null, 0); gl.glCompileShader(f); /* * Create shader program and attach shaders */ int program = gl.glCreateProgram(); gl.glAttachShader(program, v); gl.glAttachShader(program, f); gl.glLinkProgram(program); gl.glValidateProgram(program); return program; } private String[] loadResource(String resource) throws IOException{ BufferedReader reader; ArrayList<String> input = new ArrayList<String>(); String line; reader = new BufferedReader(new InputStreamReader(getClass().getResource(resource).openStream())); while ((line = reader.readLine()) != null) { input.add(line); } String[] strings = new String[input.size()]; input.toArray(strings); return strings; } } Vertex shader: #version 330 layout(location = 0) in vec4 position; void main() { gl_Position = position; } Fragment shader: #version 330 out vec4 outputColor; void main() { float lerpValue = gl_FragCoord.y / 500.0f; outputColor = mix(vec4(1.0f, 1.0f, 1.0f, 1.0f), vec4(0.0f, 0.0f, 0.0f, 1.0f), lerpValue); } and OpenGlListener class: package OpenGL33; import OpenGL33.Utils.ShaderUtils; import com.jogamp.common.nio.Buffers; import com.jogamp.opengl.util.gl2.GLUT; import java.io.IOException; import java.nio.FloatBuffer; import java.util.logging.Level; import java.util.logging.Logger; import javax.media.opengl.GL3; import javax.media.opengl.GLAutoDrawable; import javax.media.opengl.GLEventListener; import javax.media.opengl.glu.GLU; class OpenGlListener implements GLEventListener{ private GLU glu = new GLU(); private GLUT glut = new GLUT(); // vertex buffer private FloatBuffer vertices; private int[] verticesBuffer = new int[1]; private int shaderProgram; private ShaderUtils sUtils; // triangle coords public static final float[] vertexPositions = { 0.0f, 0.5f, 0.0f, 1.0f, 0.5f, -0.366f, 0.0f, 1.0f, -0.5f, -0.366f, 0.0f, 1.0f}; public OpenGlListener(){ sUtils = new ShaderUtils(); } public void initializeVertexBuffer(GLAutoDrawable drawable){ GL3 gl = drawable.getGL().getGL3bc(); vertices = Buffers.newDirectFloatBuffer(vertexPositions.length); vertices.put(vertexPositions); vertices.position(0); gl.glGenBuffers(1, verticesBuffer, 0); gl.glBindBuffer(GL3.GL_ARRAY_BUFFER, verticesBuffer[0]); gl.glBufferData(GL3.GL_ARRAY_BUFFER, vertexPositions.length * 4 * Buffers.SIZEOF_FLOAT, vertices, GL3.GL_STATIC_DRAW); gl.glBindBuffer(GL3.GL_ARRAY_BUFFER, 0); } #Override public void init(GLAutoDrawable drawable) { GL3 gl = drawable.getGL().getGL3(); // check VBO support if(!gl.isExtensionAvailable("GL_ARB_vertex_buffer_object")){ System.err.println("Error - missing VBO support"); } // load shaders try{ //tutorial 1 shaderProgram = sUtils.createProgram(gl, "/resources/shaders/FragPosition.vert", "/resources/shaders/FragPosition.frag"); //tutorial 2 //shaderProgram = sUtils.createProgram(gl, "/resources/shaders/MultiInput.vert", "/resources/shaders/MultiInput.frag"); } catch (IOException ex) { Logger.getLogger(OpenGlListener.class.getName()).log(Level.SEVERE, null, ex); } initializeVertexBuffer(drawable); } #Override public void dispose(GLAutoDrawable drawable) { //To change body of generated methods, choose Tools | Templates. } #Override public void display(GLAutoDrawable drawable) { GL3 gl = drawable.getGL().getGL3(); gl.glClear(GL3.GL_COLOR_BUFFER_BIT); gl.glUseProgram(shaderProgram); gl.glBindBuffer(GL3.GL_ARRAY_BUFFER, verticesBuffer[0]); gl.glEnableVertexAttribArray(0); gl.glVertexAttribPointer(0, 4, GL3.GL_FLOAT, false, 0, 0); gl.glDrawArrays(GL3.GL_TRIANGLES, 0, 3); gl.glDisableVertexAttribArray(0); gl.glUseProgram(0); drawable.swapBuffers(); } #Override public void reshape(GLAutoDrawable drawable, int x, int y, int width, int height) { GL3 gl = drawable.getGL().getGL3bc(); gl.glViewport(0, 0, width, height); } } App runs in swing window, drawing in GLJPanel.
OpenGL ES Object is Displaying Strangely / Distorted - Android
EDIT OK - I grabbed a device and..guess what...it displays correctly ? Does anyone know why this would be happening on the simulator only ? Thank you. I am trying to draw an object using glDrawElements on Android. I am using the code below to read in my vertice and indice data and then draw the object in my render method. I am testing this on the simulator rather than a real device. This is my scene object code : import java.nio.ByteBuffer; import java.nio.ByteOrder; import java.nio.FloatBuffer; import java.nio.IntBuffer; import java.nio.ShortBuffer; import javax.microedition.khronos.opengles.GL10; public class SceneObject { public FloatBuffer mVertexBuffer; public FloatBuffer mTextureBuffer; public ShortBuffer indexBuffer; public FloatBuffer mMatriceBuffer; public FloatBuffer mPivotBuffer; public short[] indicesTest = {0,1,2,3,4,5,3,5,6,7,5,8,7,8,9,10,7,9,11,10,9,12,1,0,13,12,14,15,13,14,14,10,11,15,14,11,0,14,12,16,17,18,19,16,18,18,20,19,21,16,19,22,21,19,22,19,23,4,24,25,25,26,27,25,27,28,4,25,28,5,4,28,5,28,8,29,30,31,29,31,19,29,19,20,32,33,31,32,31,30,32,34,33,35,22,23,36,35,23,37,36,23,37,23,38,39,37,38,40,39,38,41,40,38,41,38,1,42,41,1,12,43,1,42,1,43,17,27,26,26,18,17,44,45,46,46,47,44,48,49,50,51,52,53,53,54,51,55,51,54,54,56,55,57,48,50,50,58,57,52,59,60,60,53,52,59,44,47,47,60,59,61,62,63,63,64,61,65,66,67,67,68,65,69,70,71,71,72,69,66,69,72,72,67,66,73,65,68,68,74,73,70,75,76,76,71,70,75,61,64,64,76,75,77,78,79,79,80,77,81,82,62,62,61,81,83,81,61,61,75,83,84,63,62,62,82,84,63,84,85,86,87,88,89,90,91,92,93,87,87,86,92,94,95,96,96,97,94,98,99,100,100,101,98,102,103,104,104,105,102,106,107,108,108,109,106,110,111,112,78,77,113,114,115,78,112,111,116,117,118,115,119,116,120,121,122,123,123,124,121,125,126,127,127,128,125,129,130,131,132,133,5,5,133,6,5,134,135,135,134,136,134,137,136,137,138,136,129,139,130,139,140,141,140,142,141,137,141,138,141,142,138,141,130,139,143,144,145,144,146,145,147,145,146,144,148,146,148,149,146,146,149,150,151,132,152,153,152,154,154,152,155,152,132,155,132,5,155,155,5,135,156,157,158,158,157,146,146,157,147,159,160,158,158,160,156,34,160,159,149,161,150,161,162,150,162,163,150,150,163,164,163,165,164,165,166,164,166,167,164,164,167,129,167,168,129,169,139,129,129,168,169,154,143,153,145,153,143,170,171,172,173,172,171,174,175,176,177,178,179,180,179,178,178,181,180,182,180,181,175,183,176,184,176,183,185,177,186,179,186,177,171,185,173,186,173,185,187,188,189,190,189,188,191,192,193,194,193,192,195,196,197,198,197,196,196,191,198,193,198,191,192,199,194,200,194,199,201,195,202,197,202,195,188,201,190,202,190,201,203,204,205,206,205,204,207,208,187,188,187,208,208,209,188,201,188,209,189,210,187,207,187,210,210,189,211,212,213,214,215,216,217,218,219,220,221,220,219,222,223,224,225,226,227,228,229,230,231,230,229,232,233,234,235,236,237,238,239,240,241,242,243,123,244,124,245,246,203,204,203,246,247,248,203,249,250,251,252,253,247,248,247,253,159,33,34,254,255,256,256,257,254,255,244,123,123,256,255,244,258,121,121,124,244,259,260,125,125,128,259}; public float[] verticeTest = {20360.8f,20679.5f,611.547f,24248.7f,13527f,1074.93f,24207.4f,23005.5f,1503.19f,9819.59f,14845.7f,8.81875f,11126.3f,13982.2f,32.0718f,8379.01f,17678.5f,0.00115749f,8379.01f,15141.6f,0.00111471f,12137.8f,17973.8f,60.0461f,14591.9f,14509.2f,164.113f,15621.5f,15846.6f,223.075f,15136.7f,18549.5f,194.186f,16918.2f,16705.3f,310.215f,21081.8f,15846.6f,687.576f,19789f,16705.3f,554.435f,18467.9f,19868.7f,433.258f,18354.3f,17001.2f,423.539f,14591.9f,7402.34f,164.113f,13930.5f,9087.62f,131.015f,13039.7f,9096.18f,92.3283f,19110.4f,-8011.43f,490.311f,12811.7f,7228.03f,83.5128f,15621.5f,6064.9f,223.074f,16918.2f,5206.21f,310.215f,21807.5f,-426.492f,768.658f,11221.5f,13854f,34.3347f,12150f,12649.6f,60.4329f,12811.7f,10964.3f,83.513f,13702.6f,10955.8f,120.472f,13930.5f,12823.9f,131.015f,12150f,5542.76f,60.4327f,11119f,4205.31f,31.902f,15341.7f,-15792.9f,206.155f,9819.59f,3346.62f,8.81857f,10735.6f,-21752.5f,23.5976f,8379.01f,3050.73f,0.000981022f,18354.3f,4910.32f,423.538f,19789f,5206.21f,554.434f,21081.8f,6064.9f,687.576f,23336.1f,6399.27f,954.364f,22106.6f,7402.34f,803.393f,22764f,9087.62f,882.485f,22990.5f,10955.8f,910.595f,22764f,12823.9f,882.485f,22106.6f,14509.2f,803.393f,24248.7f,8492.36f,-3249.03f,24207.4f,17415.3f,-3297.97f,24207.4f,23005.5f,1503.19f,24248.7f,13527f,1074.93f,12728.3f,-24463.4f,-4243.56f,15341.7f,-20827.5f,-4117.81f,15341.7f,-15792.9f,206.155f,19110.4f,-13046f,-3833.65f,21807.5f,-5461.09f,-3555.3f,21807.5f,-426.492f,768.658f,19110.4f,-8011.43f,490.311f,15341.7f,-20827.5f,-4117.81f,15341.7f,-15792.9f,206.155f,10735.6f,-26787.1f,-4300.36f,10735.6f,-21752.5f,23.5976f,23336.1f,1364.68f,-3369.59f,23336.1f,6399.27f,954.364f,24883.8f,8123.11f,-2819.08f,24859.5f,16025.8f,-2803.12f,24207.4f,17415.3f,-3297.97f,24248.7f,8492.36f,-3249.03f,13363.4f,-24832.7f,-3813.62f,15976.8f,-21196.8f,-3687.86f,15341.7f,-20827.5f,-4117.81f,12728.3f,-24463.4f,-4243.56f,19745.5f,-13415.3f,-3403.7f,22442.7f,-5830.35f,-3125.36f,21807.5f,-5461.09f,-3555.3f,19110.4f,-13046f,-3833.65f,10915.8f,-27847.5f,-3863.23f,10735.6f,-26787.1f,-4300.36f,23222.6f,-2518.03f,-3057.67f,23336.1f,1364.68f,-3369.59f,10301.8f,-40240.8f,-15469.8f,10482f,-40907.1f,-14694f,10915.8f,-27847.5f,-3863.23f,10735.6f,-26787.1f,-4300.36f,25648.8f,8121.58f,-2817.31f,25624.5f,16024.2f,-2801.34f,24056.1f,-2550.94f,-3019.36f,25678.7f,16560.2f,-2907.29f,25594.2f,17951.2f,-3237.71f,25624.5f,-88046.9f,-92182.7f,25678.7f,-87767f,-92508.6f,25678.7f,16560.2f,-2907.29f,25678.7f,16560.2f,-2907.29f,25624.5f,16024.2f,-2801.34f,25624.5f,-88046.9f,-92182.7f,25624.5f,-88413.1f,-92497.2f,25678.7f,-88133.2f,-92823.1f,24765.7f,-88413.1f,-92497.2f,24820f,-88133.2f,-92823.1f,25678.7f,-88133.2f,-92823.1f,25624.5f,-88413.1f,-92497.2f,24765.7f,-89895.8f,-93770.7f,24820f,-89615.9f,-94096.6f,24820f,-88133.2f,-92823.1f,24765.7f,-88413.1f,-92497.2f,25678.7f,-89596.5f,-94079.9f,25678.7f,-88133.2f,-92823.1f,24820f,-88133.2f,-92823.1f,24820f,-89615.9f,-94096.6f,23222.6f,-93458.9f,-81162.2f,24056.1f,-93491.8f,-81123.9f,24056.1f,-2550.94f,-3019.36f,23222.6f,-2518.03f,-3057.67f,10579.6f,-102089f,-68973.2f,10579f,-102925f,-68042.7f,10482f,-40907.1f,-14694f,10579.6f,-102089f,-68973.2f,10579f,-102925f,-68042.7f,10482f,-41291.8f,-14246f,10579f,-102925f,-68042.7f,10489f,-103571f,-67018.6f,10482f,-41713.9f,-13886.7f,10482f,-41291.8f,-14246f,10489f,-103571f,-67018.6f,8379.01f,-102145f,-69021.7f,10579.6f,-102089f,-68973.2f,10301.8f,-40240.8f,-15469.8f,8379.01f,-68082.6f,-39554.7f,8379.01f,-101057f,-70411.1f,10735.6f,-101057f,-70411.1f,10579.6f,-102089f,-68973.2f,8379.01f,-102145f,-69021.7f,-7490.7f,13527f,1074.93f,-3602.79f,20679.5f,611.547f,-7449.35f,23005.5f,1503.19f,5631.77f,13982.2f,32.0718f,6938.43f,14845.7f,8.81875f,4620.19f,17973.8f,60.0461f,2166.16f,14509.2f,164.113f,1136.48f,15846.6f,223.075f,1621.29f,18549.5f,194.186f,-160.178f,16705.3f,310.215f,-4323.73f,15846.6f,687.576f,-3030.97f,16705.3f,554.435f,-1709.92f,19868.7f,433.258f,-1596.32f,17001.2f,423.539f,2827.51f,9087.62f,131.015f,2166.16f,7402.34f,164.113f,3718.3f,9096.18f,92.3283f,-2352.36f,-8011.43f,490.311f,3946.3f,7228.03f,83.5128f,1136.48f,6064.9f,223.074f,-160.182f,5206.21f,310.215f,-5049.53f,-426.492f,768.658f,5536.51f,13854f,34.3347f,4608.07f,12649.6f,60.4329f,3946.3f,10964.3f,83.513f,3055.44f,10955.8f,120.472f,2827.51f,12823.9f,131.015f,5639.04f,4205.31f,31.902f,4608.07f,5542.76f,60.4327f,1416.3f,-15792.9f,206.155f,6022.45f,-21752.5f,23.5976f,6938.43f,3346.62f,8.81857f,-1596.32f,4910.32f,423.538f,-3030.97f,5206.21f,554.434f,-4323.73f,6064.9f,687.576f,-6578.08f,6399.27f,954.364f,-5348.56f,7402.34f,803.393f,-6006f,9087.62f,882.485f,-6232.44f,10955.8f,910.595f,-6006f,12823.9f,882.485f,-5348.57f,14509.2f,803.393f,-7449.35f,17415.3f,-3297.97f,-7490.7f,8492.36f,-3249.03f,-7449.35f,23005.5f,1503.19f,-7490.7f,13527f,1074.93f,1416.3f,-20827.5f,-4117.81f,4029.77f,-24463.4f,-4243.56f,1416.3f,-15792.9f,206.155f,-5049.53f,-5461.09f,-3555.3f,-2352.36f,-13046f,-3833.65f,-5049.53f,-426.492f,768.658f,-2352.36f,-8011.43f,490.311f,1416.3f,-20827.5f,-4117.81f,1416.3f,-15792.9f,206.155f,6022.45f,-26787.1f,-4300.36f,6022.45f,-21752.5f,23.5976f,-6578.08f,1364.68f,-3369.59f,-6578.08f,6399.27f,954.364f,-8101.47f,16025.8f,-2803.12f,-8125.81f,8123.11f,-2819.08f,-7449.35f,17415.3f,-3297.97f,-7490.7f,8492.36f,-3249.03f,781.19f,-21196.8f,-3687.86f,3394.66f,-24832.7f,-3813.62f,1416.3f,-20827.5f,-4117.81f,4029.77f,-24463.4f,-4243.56f,-5684.64f,-5830.35f,-3125.36f,-2987.47f,-13415.3f,-3403.7f,-5049.53f,-5461.09f,-3555.3f,-2352.36f,-13046f,-3833.65f,5842.26f,-27847.5f,-3863.23f,6022.45f,-26787.1f,-4300.36f,-6464.54f,-2518.03f,-3057.67f,-6578.08f,1364.68f,-3369.59f,6276.06f,-40907.1f,-14694f,6456.25f,-40240.8f,-15469.8f,5842.26f,-27847.5f,-3863.23f,6022.45f,-26787.1f,-4300.36f,-8866.45f,16024.2f,-2801.34f,-8890.79f,8121.58f,-2817.31f,-7298.12f,-2550.94f,-3019.36f,-8920.72f,16560.2f,-2907.29f,-8836.13f,17951.2f,-3237.71f,-8920.72f,-87767f,-92508.6f,-8866.45f,-88046.9f,-92182.7f,-8920.72f,16560.2f,-2907.29f,-8866.45f,16024.2f,-2801.34f,-8920.72f,16560.2f,-2907.29f,-8866.45f,-88046.9f,-92182.7f,-8920.72f,-88133.2f,-92823.1f,-8866.45f,-88413.1f,-92497.2f,-8920.72f,-87767f,-92508.6f,-8866.45f,-88046.9f,-92182.7f,-8061.98f,-88133.2f,-92823.1f,-8007.72f,-88413.1f,-92497.2f,-8920.72f,-88133.2f,-92823.1f,-8866.45f,-88413.1f,-92497.2f,-8920.72f,-88133.2f,-92823.1f,-8007.72f,-88413.1f,-92497.2f,-8061.98f,-89615.9f,-94096.6f,-8007.72f,-89895.8f,-93770.7f,-8061.98f,-88133.2f,-92823.1f,-8007.72f,-88413.1f,-92497.2f,-8920.72f,-88133.2f,-92823.1f,-8920.72f,-89596.5f,-94079.9f,-8061.98f,-88133.2f,-92823.1f,-8061.98f,-89615.9f,-94096.6f,-8061.98f,-88133.2f,-92823.1f,-8920.72f,-89596.5f,-94079.9f,-7298.12f,-93491.8f,-81123.9f,-6464.54f,-93458.9f,-81162.2f,-7298.12f,-2550.94f,-3019.36f,-6464.54f,-2518.03f,-3057.67f,-7298.12f,-2550.94f,-3019.36f,-6464.54f,-93458.9f,-81162.2f,6456.25f,-40240.8f,-15469.8f,6179.01f,-102925f,-68042.7f,6178.41f,-102089f,-68973.2f,6276.06f,-41291.8f,-14246f,6179.01f,-102925f,-68042.7f,6179.01f,-102925f,-68042.7f,6276.06f,-40907.1f,-14694f,6179.01f,-102925f,-68042.7f,6276.06f,-41713.9f,-13886.7f,6269.01f,-103571f,-67018.6f,6022.45f,-21752.5f,23.5976f,6022.45f,-26787.1f,-4300.36f,10735.6f,-26787.1f,-4300.36f,10735.6f,-21752.5f,23.5976f,6178.41f,-102089f,-68973.2f,6178.41f,-102089f,-68973.2f,6022.45f,-101057f,-70411.1f }; public String objectName; public int triangleCount; public int verticeCount; public float[] vertices; public float[] normals; public float[] textures; public short[] indices; public float[] matrices; public float[] pivots; public float[] animations; public void awake() { ByteBuffer vbb = ByteBuffer.allocateDirect(verticeTest.length * 4); vbb.order(ByteOrder.nativeOrder()); mVertexBuffer = vbb.asFloatBuffer(); mVertexBuffer.put(verticeTest); mVertexBuffer.position(0); ByteBuffer tbb = ByteBuffer.allocateDirect(textures.length * 4); tbb.order(ByteOrder.nativeOrder()); mTextureBuffer = tbb.asFloatBuffer(); mTextureBuffer.put(textures); mTextureBuffer.position(0); //short has 2 bytes ByteBuffer ibb = ByteBuffer.allocateDirect(indicesTest.length*2); ibb.order(ByteOrder.nativeOrder()); indexBuffer = ibb.asShortBuffer(); indexBuffer.put(indicesTest); indexBuffer.position(0); verticeCount = (triangleCount*3); } public void draw(GL10 gl) { System.out.println("Draw Method Called in Object"); gl.glEnable(GL10.GL_TEXTURE_2D); //workaround bug 3623 gl.glVertexPointer(3, GL10.GL_FLOAT, 0, mVertexBuffer); System.out.println("Triangle Vertice Count is "+verticeCount); int x = vertices.length; System.out.println("Rendering following number of vertices "+x); int y = indices.length; System.out.println("Rendering following number of indices "+y); gl.glDrawElements(GL10.GL_TRIANGLES, indices.length, GL10.GL_UNSIGNED_SHORT, indexBuffer); } } And here is the code where I call the draw method : import java.nio.FloatBuffer; import java.util.ArrayList; import java.util.Iterator; import javax.microedition.khronos.egl.EGLConfig; import javax.microedition.khronos.opengles.GL10; import android.content.Context; import android.opengl.GLSurfaceView; import android.opengl.GLU; class GLRenderer implements GLSurfaceView.Renderer { private static final String TAG = "GLRenderer"; private final Context context; private final GLCube cube = new GLCube(); private long startTime; private long fpsStartTime; private long numFrames; SceneObject drawObject; SceneObject object; //Used for object position and rotation. float zRotation; float xRotation; float yRotation; float kxRotation = 0.0f; float kyRotation = 0.0f; ArrayList<SceneObject> sceneObjects = new ArrayList<SceneObject>(); boolean SEE_THRU = false; GLRenderer(Context context) { this.context = context; } public void onSurfaceCreated(GL10 gl, EGLConfig config) { // Setup any OpenGL Options that are required. gl.glEnable(GL10.GL_DEPTH_TEST); gl.glDepthFunc(GL10.GL_LEQUAL); gl.glEnableClientState(GL10.GL_VERTEX_ARRAY); gl.glEnableClientState(GL10.GL_TEXTURE_COORD_ARRAY); gl.glEnable(GL10.GL_TEXTURE_2D); if (SEE_THRU) { gl.glDisable(GL10.GL_DEPTH_TEST); gl.glEnable(GL10.GL_BLEND); gl.glBlendFunc(GL10.GL_SRC_ALPHA, GL10.GL_ONE); } //Optional - disable dither to boost peformance. //gl.glDisable(GL10.GL_DITHER); //Dithering enabled by default. //Turn on the lights. float lightAmbient[] = new float[] { 0.2f, 0.2f, 0.2f, 1}; float lightDiffuse[] = new float[] {1, 1, 1, 1}; float[] lightPos = new float[] {1 ,1 ,1 , 1}; gl.glEnable(GL10.GL_LIGHTING); gl.glEnable(GL10.GL_LIGHT0); gl.glLightfv(GL10.GL_LIGHT0, GL10.GL_AMBIENT, lightAmbient, 0); gl.glLightfv(GL10.GL_LIGHT0, GL10.GL_DIFFUSE, lightDiffuse, 0); gl.glLightfv(GL10.GL_LIGHT0, GL10.GL_POSITION, lightPos, 0); //Specify which materials we should use. float matAmbient[] = new float[] {1, 1, 1, 1}; float matDiffuse[] = new float[] {1, 1, 1, 1}; gl.glMaterialfv(GL10.GL_FRONT_AND_BACK, GL10.GL_AMBIENT, matAmbient, 0); gl.glMaterialfv(GL10.GL_FRONT_AND_BACK, GL10.GL_DIFFUSE, matDiffuse, 0); } public void onSurfaceChanged(GL10 gl, int width, int height) { //Define the view frustrum gl.glViewport(0, 0, width, height); gl.glMatrixMode(GL10.GL_PROJECTION); float ratio = (float)width/height; gl.glLoadIdentity(); //gl.glOrthof(0, 480f, 800f, 0, 0, 1); GLU.gluPerspective(gl, 45.0f, ratio, 1.0f, 100f); } public void onDrawFrame (GL10 gl) { //Defs for rotation of object. float kzRotation = 0.0f; kyRotation +=1.0f; kxRotation =280.0f; gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT); SceneObject object = sceneObjects.get(13); //Get the object //Position the model. gl.glMatrixMode(GL10.GL_MODELVIEW); gl.glLoadIdentity(); gl.glTranslatef(0.0f, 0.0f, -30.0f); gl.glScalef(0.0001f, 0.0001f, 0.0001f); zRotation = kzRotation; xRotation = kxRotation; yRotation = kyRotation; gl.glRotatef(yRotation, 0.0f, 1.0f, 0.0f); gl.glRotatef(xRotation, 1.0f, 0.0f, 0.0f); gl.glRotatef(zRotation, 0.0f, 0.0f, 1.0f); object.draw(gl); } } } The problem is that the object is not displaying as it should, but instead looks warped and squashed. Can anyone spot what might be wrong ? EDIT - Changed the onSufaceChanged method as per Tim's answer below, however no improvement. I've added an image of how the object is rendering on Android and the same object rendering correct on the iPhone. The most noticeable problem is that the "legs" should be straight and not bend and overall the object should be much longer. I'm sure the vertices and indices in the code above are correct (they are exactly the same as the iPhone ones). In case it is relevant here is how I am setting up the surfaceview / view: public class SaxParserActivity extends Activity { /** Called when the activity is first created. */ ArrayList<SceneObject> sceneObjects = new ArrayList<SceneObject>(); #Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); //setContentView(R.layout.main); GLView view; view = new GLView(this, sceneObjects); //Pass down our sceneObjects into the view class. //view.sceneObjects = sceneObjects; setContentView(view); } } class GLView extends GLSurfaceView { private final GLRenderer renderer; ArrayList<SceneObject> sceneObjects = new ArrayList<SceneObject>(); GLView(Context context, ArrayList<SceneObject> sceneObjects) { super (context); //Uncomment this to turn on error-checking and logging. //setDebugFlags(DEBUG_CHECK_GL_ERROR | DEBUG_LOG_GL_CALLS); renderer = new GLRenderer(context); //Pass down our sceneObjects. renderer.sceneObjects = sceneObjects; setRenderer(renderer); } }
I'm a bit confused by what you're doing. Why do you wipe on the projection matrix in onDrawFrame, after setting it in onSurfaceChanged? You should set projection in onSurfaceChanged like so: public void onSurfaceChanged(GL10 gl, int width, int height) { gl.glViewport(0, 0, width, height); gl.glMatrixMode(GL10.GL_PROJECTION); gl.glLoadIdentity(); //make sure to reset before glOrthof gl.glOrthof(0, 320f, 480f, 0, 0, 1); } And then change back to modelview and don't disturb the projection matrix during onDrawFrame. You'll probably need to recalibrate your scale and translate in onDrawFrame as well after doing this.