Android OpenGL ES Polygon Tutorial Assistance - java
I have followed some Android tutorials and have this Triangle program that works and runs and creates a filled Triangle successfully.
I am now trying to follow several different Polygon tutorials but none seem to help translating my code to a polygon. I have scoured stack and everywhere else, so I know this may seem repetitive.
I want to be able to enter the number of sides and have the program generate the polygon with that many sides. I can sort of hard code in vertices in order to generate a polygon but cannot make this a polygon of n sides.
Would anyone be able to guide me in the right direction or provide some examples? I am lost.
Triangle.java
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.FloatBuffer;
import javax.microedition.khronos.opengles.GL10;
public class Triangle{
private FloatBuffer vertexBuffer;
private int vSize = 7;
public Triangle(){
float vertices[] = {
-.5f, -.433f, 0, 1, 0, 0, 1,
.5f, -.433f, 0, 0, 1, 0, 1,
0, .433f, 0, 0, 0, 1, 1
};
ByteBuffer byteBuffer = ByteBuffer.allocateDirect(vertices.length*4);
byteBuffer.order(ByteOrder.nativeOrder());
vertexBuffer = byteBuffer.asFloatBuffer();
vertexBuffer.put(vertices);
}
public void onDrawFrame(GL10 gl) {
vertexBuffer.position(0);
gl.glVertexPointer(3, GL10.GL_FLOAT, vSize*4, vertexBuffer);
vertexBuffer.position(3);
gl.glColorPointer(4, GL10.GL_FLOAT, vSize*4, vertexBuffer);
gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
gl.glEnableClientState(GL10.GL_COLOR_ARRAY);
gl.glDrawArrays(GL10.GL_TRIANGLES, 0, 3); // GL_TRAINGLEFAN for polygon?
gl.glDisableClientState(GL10.GL_VERTEX_ARRAY);
gl.glDisableClientState(GL10.GL_COLOR_ARRAY);
}
}
MyRenderer.java
import javax.microedition.khronos.egl.EGLConfig;
import javax.microedition.khronos.opengles.GL10;
import android.opengl.GLSurfaceView.Renderer;
public class MyRenderer implements Renderer {
private Triangle triangle;
#Override
public void onDrawFrame(GL10 gl) {
gl.glClear(GL10.GL_COLOR_BUFFER_BIT|GL10.GL_DEPTH_BUFFER_BIT);
triangle.onDrawFrame(gl);
}
#Override
public void onSurfaceChanged(GL10 gl, int width, int height) {
if(width<height){
gl.glViewport(0, 0, width, width);
}else{
gl.glViewport(0, 0, height, height);
}
gl.glMatrixMode(GL10.GL_PROJECTION); //to work with the projection matrix
//to do: set up ortho projection
gl.glLoadIdentity();
gl.glOrthof(-1.0f, 1.0f, -1.0f, 1.0f, -0.1f, 0.1f);
gl.glMatrixMode(GL10.GL_MODELVIEW);//methods should restore model view matrix mode
}
#Override
public void onSurfaceCreated(GL10 gl, EGLConfig arg1) {
gl.glClearColor(0.8f, 0.8f, 0.8f, 1);
triangle = new Triangle();
}
}
MainActivity.java
import android.opengl.GLSurfaceView;
import android.os.Bundle;
import android.app.Activity;
import android.view.Menu;
public class MainActivity extends Activity {
private GLSurfaceView view;
private MyRenderer renderer;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//setContentView(R.layout.activity_main);
view = new GLSurfaceView(this);
renderer = new MyRenderer();
view.setRenderer(renderer);
setContentView(view);
}
#Override
protected void onPause() {
view.onPause();
super.onPause();
}
#Override
protected void onResume() {
view.onResume();
super.onResume();
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
}
Sample a circle every (2 * pi) / n radians:
void glPolygon( unsigned int sides )
{
glBegin( GL_TRIANGLE_FAN );
glVertex2f( 0, 0 );
for( unsigned int i = 0; i <= sides; i++ )
{
const float u = ( i / (float)sides );
const float a = ( 2 * 3.14159 ) * u;
glVertex2f( cos( a ), sin( a ) );
}
glEnd();
}
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 ;)
Why glTranslatef?
I just don't understand why in this case if I get rid of this stroke gl.glTranslatef(0.0f,(float)Math.sin(mTransY), -3.0f); square just not drawing? Full code here (and ignore those cyrillic comments - i just wrote for myself what each func does ) MainActivity class package opengl.tutorial.one; import android.app.Activity; import android.opengl.GLSurfaceView; import android.os.Bundle; import android.view.WindowManager; public class MainActivity extends Activity { /** Called when the activity is first created. */ #Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN); GLSurfaceView view = new GLSurfaceView(this); view.setRenderer(new SquareRenderer(true)); setContentView(view); } } Square class package opengl.tutorial.one; import java.nio.ByteBuffer; import java.nio.ByteOrder; import java.nio.FloatBuffer; import java.nio.IntBuffer; import javax.microedition.khronos.opengles.GL10; //1 import javax.microedition.khronos.opengles.GL11; public class Square { private FloatBuffer mFVertexBuffer; private ByteBuffer mColorBuffer; private ByteBuffer mIndexBuffer; public Square(){ float vertices[] = { -1.0f, -1.0f,//0 1.0f, -1.0f, //1 -1.0f, 1.0f, //2 1.0f, 1.0f //3 };//задали положение веришн квадрата по координатам byte maxColor=(byte)255; byte colors[] = //задали цвет веришнам { maxColor,maxColor, 0,maxColor, maxColor,maxColor, 0,maxColor, maxColor,maxColor, 0,maxColor, maxColor,maxColor, 0,maxColor, }; byte indices[] = //порядок построения треугольников вершинами { 0, 3, 1, //первый 0, 2, 3 //второй }; ByteBuffer vbb = ByteBuffer.allocateDirect(vertices.length * 4); //5 vbb.order(ByteOrder.nativeOrder()); mFVertexBuffer = vbb.asFloatBuffer(); mFVertexBuffer.put(vertices); mFVertexBuffer.position(0); mColorBuffer = ByteBuffer.allocateDirect(colors.length); mColorBuffer.put(colors); mColorBuffer.position(0); mIndexBuffer = ByteBuffer.allocateDirect(indices.length); mIndexBuffer.put(indices); mIndexBuffer.position(0); } public void draw(GL10 gl) //6 { gl.glFrontFace(GL11.GL_CW); //выводит полигон по заданной ориентации к экрану. CW - по часовой gl.glVertexPointer(2, GL11.GL_FLOAT, 0, mFVertexBuffer); //Установка массива для вершинных координат gl.glColorPointer(4, GL11.GL_UNSIGNED_BYTE, 0, mColorBuffer); //9 gl.glDrawElements(GL11.GL_TRIANGLES, 6,GL11.GL_UNSIGNED_BYTE, mIndexBuffer); gl.glFrontFace(GL11.GL_CCW); //выводит полигон по заданной ориентации к экрану. СCW - против часовой } } class SquareRenderer package opengl.tutorial.one; import javax.microedition.khronos.egl.EGL10; //1 import javax.microedition.khronos.egl.EGLConfig; import javax.microedition.khronos.opengles.GL10; import android.opengl.GLSurfaceView.Renderer; import java.lang.Math; public class SquareRenderer implements Renderer { private boolean mTranslucentBackground; private Square mSquare; private float mTransY; private float mAngle; public SquareRenderer(boolean useTranslucentBackground) { mTranslucentBackground = useTranslucentBackground;//прозрачный фон mSquare = new Square(); //новый объект типа квадрат } public void onDrawFrame(GL10 gl) //4 { gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT); //5 gl.glMatrixMode(GL10.GL_MODELVIEW); //6 gl.glLoadIdentity(); //7 gl.glTranslatef(0.0f,(float)Math.sin(mTransY), -3.0f); //8 gl.glEnableClientState(GL10.GL_VERTEX_ARRAY); //9 gl.glEnableClientState(GL10.GL_COLOR_ARRAY); mSquare.draw(gl); //10 mTransY += 0f; } public void onSurfaceChanged(GL10 gl, int width, int height) //11 { gl.glViewport(0, 0, width, height); //12 float ratio = (float) width / height; gl.glMatrixMode(GL10.GL_PROJECTION); //13 gl.glLoadIdentity(); gl.glFrustumf(-ratio, ratio, -1, 1, 1, 10); //14 } public void onSurfaceCreated(GL10 gl, EGLConfig config) //15 { gl.glDisable(GL10.GL_DITHER); //16 gl.glHint(GL10.GL_PERSPECTIVE_CORRECTION_HINT, GL10.GL_FASTEST); if (mTranslucentBackground) //18 { } else { gl.glClearColor(1,1,1,1); } gl.glEnable(GL10.GL_CULL_FACE); //19 gl.glShadeModel(GL10.GL_SMOOTH); //20 gl.glEnable(GL10.GL_DEPTH_TEST); //21 } }
The whole square is at z=0 plane. glTranslatef defines point of view 3.0 by z axis. Without this call, the point of view has z=0 coordinate, so you are looking at the square inside of the square itself. Play with glTranslatef coordinates to see what happens. The best way to understand the meaning of every OpenGL function is to exclude/include it (well, you have already done this...) and to set different parameter values. y parameter of glTranslatef gives rotation effect around y-axis.
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.
OpenGL ES : Using Texture: Blank White instead of Texture Image
I'm coding on Android Platform. I'm trying to use texture (load image from Assets folder) for triangle. When my app run, it just blank white in triangle (not texture what I want). I have read some other source that say image must be a power of two. And I have checked, my image is a power of two. (128 x 128). That a reason why make me headache. Here is my code: (the main code that you should see in onDrawFrame method, It contains code that I use for Render) package com.test; import java.io.IOException; import java.nio.ByteBuffer; import java.nio.ByteOrder; import java.nio.FloatBuffer; import javax.microedition.khronos.egl.EGLConfig; import javax.microedition.khronos.opengles.GL10; import android.app.Activity; import android.content.res.AssetManager; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.opengl.GLSurfaceView; import android.opengl.GLSurfaceView.Renderer; import android.opengl.GLUtils; import android.os.Bundle; import android.util.Log; public class TextureTriangleTest extends Activity{ GLSurfaceView glView; ByteBuffer byteBuffer; FloatBuffer vertices; AssetManager assets; #Override public void onCreate(Bundle savedInstanceState){ super.onCreate(savedInstanceState); assets = getAssets(); int VERTEX_SIZE = (2+2)*4; byteBuffer = ByteBuffer.allocateDirect(3*VERTEX_SIZE); byteBuffer.order(ByteOrder.nativeOrder()); vertices = byteBuffer.asFloatBuffer(); vertices.put(new float[] { 0.0f, 0.0f, 0.0f, 1.0f, 319.0f, 0.0f, 1.0f, 1.0f, 160.0f, 479.0f, 0.5f, 0.0f } ); vertices.flip(); glView = new GLSurfaceView(this); glView.setRenderer(new Render()); setContentView(glView); } class Render implements Renderer{ #Override public void onDrawFrame(GL10 gl) { try { Bitmap bitmap = BitmapFactory.decodeStream(assets.open("bobrgb888.png")); int textureIds[] = new int[1]; gl.glGenTextures(1, textureIds, 0); int textureId = textureIds[0]; gl.glBindTexture(GL10.GL_TEXTURE_2D, textureId); GLUtils.texImage2D(GL10.GL_TEXTURE_2D, 0, bitmap, 0); gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MIN_FILTER, GL10.GL_NEAREST); gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MAG_FILTER, GL10.GL_NEAREST); gl.glBindTexture(GL10.GL_TEXTURE_2D, 0); bitmap.recycle(); } catch (IOException e) { Log.d("", "FAILED LOAD FILE"); throw new RuntimeException("Couldn't load asset!"); } gl.glViewport(0, 0, glView.getWidth(), glView.getHeight()); gl.glClear(GL10.GL_COLOR_BUFFER_BIT); gl.glMatrixMode(GL10.GL_PROJECTION); gl.glLoadIdentity(); gl.glOrthof(0, 320, 0, 480, 1, -1); gl.glEnableClientState(GL10.GL_VERTEX_ARRAY); gl.glEnableClientState(GL10.GL_TEXTURE_COORD_ARRAY); int VERTEX_SIZE = (2+2)*4; vertices.position(0); gl.glVertexPointer(2, GL10.GL_FLOAT, VERTEX_SIZE, vertices); vertices.position(2); gl.glTexCoordPointer(2, GL10.GL_FLOAT, VERTEX_SIZE, vertices); gl.glDrawArrays(GL10.GL_TRIANGLES, 0, 3); } #Override public void onSurfaceChanged(GL10 gl, int width, int height) { // TODO Auto-generated method stub } #Override public void onSurfaceCreated(GL10 gl, EGLConfig config) { // TODO Auto-generated method stub } } } My code just a simple example. I have debug and all thing is true. (such as: successfully load image). But, I don't know how to debug OpenGL app. (It means : when debug, I can view parameter of variable, but I don't know how it be, because OpenGL is too complicated than Canvas- that you just use one line of code and has result :) ) thanks for help :)
Oh. I have fixed whole my solutions, and below is my full code. I posted here for whom try to read my long post (^^) and need a real solution :) Thanks to SteveL has suggested me :) In my solution, I have some change: first. Performance: I put code read texture in onSurfaceCreate. second. As SteveL say. I'm missing gl.glEnable and I have reseted again gl.glBindTexture. Thinks again, I see that those error really silly. Just because I'm a newbie of OpenGL :( package com.test; import java.nio.ByteBuffer; import java.nio.ByteOrder; import java.nio.FloatBuffer; import javax.microedition.khronos.egl.EGLConfig; import javax.microedition.khronos.opengles.GL10; import android.app.Activity; import android.opengl.GLSurfaceView; import android.opengl.GLSurfaceView.Renderer; import android.os.Bundle; public class ColorTriangleTest extends Activity{ GLSurfaceView glView; ByteBuffer byteBuffer; FloatBuffer vertices; public void onCreate(Bundle savedInstanceState){ super.onCreate(savedInstanceState); int VERTEX_SIZE = (2+4)*4; byteBuffer = ByteBuffer.allocateDirect(3*VERTEX_SIZE); byteBuffer.order(ByteOrder.nativeOrder()); vertices = byteBuffer.asFloatBuffer(); vertices.put(new float[] { 0.0f, 0.0f, 1, 0, 0, 1, 319.0f, 0.0f, 1, 1, 0, 1, 160.0f, 479.0f, 1, 0, 1, 1 }); vertices.flip(); glView = new GLSurfaceView(this); glView.setRenderer(new Render()); setContentView(glView); } class Render implements Renderer { #Override public void onDrawFrame(GL10 gl) { int VERTEX_SIZE = (2+4)*4; gl.glViewport(0, 0, glView.getWidth(), glView.getHeight()); gl.glClear(GL10.GL_COLOR_BUFFER_BIT); gl.glMatrixMode(GL10.GL_PROJECTION); gl.glLoadIdentity(); gl.glOrthof(0, 320, 0, 480, 10, -10); gl.glEnableClientState(GL10.GL_VERTEX_ARRAY); gl.glEnableClientState(GL10.GL_COLOR_ARRAY); vertices.position(0); gl.glVertexPointer(2, GL10.GL_FLOAT, VERTEX_SIZE, vertices); vertices.position(2); gl.glColorPointer(4, GL10.GL_FLOAT, VERTEX_SIZE, vertices); gl.glDrawArrays(GL10.GL_TRIANGLES, 0, 3); } #Override public void onSurfaceChanged(GL10 gl, int width, int height) { // TODO Auto-generated method stub } #Override public void onSurfaceCreated(GL10 gl, EGLConfig config) { // TODO Auto-generated method stub } } }
Oh. I have fixed my problem. But I cannot explain why. (I can fixed because I do like some tutorial on the internet). Here is my code. I have pointed some lines that I have changed. Please tell me why it works, please: package com.test; import java.io.IOException; import java.nio.ByteBuffer; import java.nio.ByteOrder; import java.nio.FloatBuffer; import javax.microedition.khronos.egl.EGLConfig; import javax.microedition.khronos.opengles.GL10; import android.app.Activity; import android.content.res.AssetManager; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.opengl.GLSurfaceView; import android.opengl.GLSurfaceView.Renderer; import android.opengl.GLUtils; import android.os.Bundle; import android.util.Log; public class TextureTriangleTest extends Activity{ GLSurfaceView glView; ByteBuffer byteBuffer; FloatBuffer vertices; AssetManager assets; #Override public void onCreate(Bundle savedInstanceState){ super.onCreate(savedInstanceState); assets = getAssets(); int VERTEX_SIZE = (2+2)*4; byteBuffer = ByteBuffer.allocateDirect(3*VERTEX_SIZE); byteBuffer.order(ByteOrder.nativeOrder()); vertices = byteBuffer.asFloatBuffer(); vertices.put(new float[] { 0.0f, 0.0f, 0.0f, 1.0f, 319.0f, 0.0f, 1.0f, 1.0f, 160.0f, 479.0f, 0.5f, 0.0f } ); vertices.flip(); glView = new GLSurfaceView(this); glView.setRenderer(new Render()); setContentView(glView); } class Render implements Renderer{ #Override public void onDrawFrame(GL10 gl) { int a = 0; try { Bitmap bitmap = BitmapFactory.decodeStream(assets.open("bobrgb888.png")); int textureIds[] = new int[1]; gl.glGenTextures(1, textureIds, 0); int textureId = textureIds[0]; a= textureId; gl.glBindTexture(GL10.GL_TEXTURE_2D, textureId); //this line GLUtils.texImage2D(GL10.GL_TEXTURE_2D, 0, bitmap, 0); gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MIN_FILTER, GL10.GL_NEAREST); gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MAG_FILTER, GL10.GL_NEAREST); gl.glBindTexture(GL10.GL_TEXTURE_2D, 0); //and this line bitmap.recycle(); } catch (IOException e) { Log.d("", "FAILED LOAD FILE"); throw new RuntimeException("Couldn't load asset!"); } gl.glViewport(0, 0, glView.getWidth(), glView.getHeight()); gl.glClear(GL10.GL_COLOR_BUFFER_BIT); gl.glMatrixMode(GL10.GL_PROJECTION); gl.glLoadIdentity(); gl.glOrthof(0, 320, 0, 480, 1, -1); //Here two lines that I added. Two lines I have declared above in try_catch //So, WHY I NEED TO DECLARE AGAIN ??!!! gl.glEnable(GL10.GL_TEXTURE_2D); gl.glBindTexture(GL10.GL_TEXTURE_2D, a); gl.glEnableClientState(GL10.GL_VERTEX_ARRAY); gl.glEnableClientState(GL10.GL_TEXTURE_COORD_ARRAY); int VERTEX_SIZE = (2+2)*4; vertices.position(0); gl.glVertexPointer(2, GL10.GL_FLOAT, VERTEX_SIZE, vertices); vertices.position(2); gl.glTexCoordPointer(2, GL10.GL_FLOAT, VERTEX_SIZE, vertices); gl.glDrawArrays(GL10.GL_TRIANGLES, 0, 3); } #Override public void onSurfaceChanged(GL10 gl, int width, int height) { // TODO Auto-generated method stub } #Override public void onSurfaceCreated(GL10 gl, EGLConfig config) { // TODO Auto-generated method stub } } } That works for me now :) Who can explain why ??!!
OpenGL ES texture won't draw
I have followed a tutorial on how to display an image in OpenGL, and I first had to make a square and then texture it. I have tried gl.glColor4f(0f,0f,0f,1f); and that works, I can see the square. But then when I try to texture it, the screen just stays white. What did I do wrong? Here is the screen with the gl.glColor4f(0f,0f,0f,1f); : If I apply the texture (using the custom Texture class that the tutorial suggested), the screen is completely white. Here is my code: Square.java: package com.chrypthic.android.reference; import java.nio.ByteBuffer; import java.nio.ByteOrder; import java.nio.FloatBuffer; import java.nio.ShortBuffer; import javax.microedition.khronos.opengles.GL10; import android.content.Context; public class Square { final int VERTEX_SIZE = (2+2) *4; FloatBuffer vertices; ShortBuffer indices; Texture texture; GL10 gl; Context c; public Square(GL10 gl, Context context) { this.gl = gl; this.c = context; ByteBuffer byteBuffer = ByteBuffer.allocateDirect(VERTEX_SIZE * 4); byteBuffer.order(ByteOrder.nativeOrder()); vertices = byteBuffer.asFloatBuffer(); vertices.put(new float[]{ 10.0f, 10.0f, 0.0f, 0.0f, //bl 160.0f, 10.0f, 1.0f, 0.0f, //br 160.0f, 160.0f, 1.0f, 1.0f, //tr 10.0f, 160.0f, 1.0f, 0.0f, //tl }); vertices.flip(); byteBuffer = ByteBuffer.allocateDirect(VERTEX_SIZE * 4); byteBuffer.order(ByteOrder.nativeOrder()); indices = byteBuffer.asShortBuffer(); indices.put(new short[]{ 0, 1, 2, 2, 3, 0 }); indices.flip(); texture = new Texture("image/picture.png", c, gl); } public void draw() { gl.glEnable(GL10.GL_TEXTURE_2D); texture.bind(); //gl.glColor4f(0f, 0f, 0f, 1f); gl.glEnableClientState(GL10.GL_TEXTURE_COORD_ARRAY); gl.glEnableClientState(GL10.GL_VERTEX_ARRAY); vertices.position(0); gl.glVertexPointer(2, GL10.GL_FLOAT, VERTEX_SIZE, vertices); vertices.position(2); gl.glTexCoordPointer(2, GL10.GL_FLOAT, VERTEX_SIZE, vertices); gl.glDrawElements(GL10.GL_TRIANGLES, 6, GL10.GL_UNSIGNED_SHORT, indices); } } Texture.java package com.chrypthic.android.reference; import java.io.InputStream; import javax.microedition.khronos.opengles.GL10; import android.content.Context; import android.content.res.AssetManager; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.opengl.GLUtils; public class Texture { String texturePath; Context context; GL10 gl; int textureId; int minFilter; int magFilter; Bitmap texture; public Texture(String texturePath, Context context, GL10 gl) { this.gl = gl; this.texturePath = texturePath; this.context = context; } public void load() { try{ AssetManager assetManager = context.getAssets(); InputStream is = assetManager.open(texturePath); texture = BitmapFactory.decodeStream(is); gl.glBindTexture(GL10.GL_TEXTURE_2D, textureId); GLUtils.texImage2D(GL10.GL_TEXTURE_2D, 0, texture, 0); setFilters(GL10.GL_NEAREST, GL10.GL_NEAREST); gl.glBindTexture(GL10.GL_TEXTURE_2D, 0); }catch(Exception e) { e.printStackTrace(); } } public void reload() { load(); bind(); setFilters(minFilter, magFilter); gl.glBindTexture(GL10.GL_TEXTURE_2D, 0); } public void setFilters(int minFilter, int magFilter) { this.minFilter = minFilter; this.magFilter = magFilter; gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MIN_FILTER, minFilter); gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MAG_FILTER, magFilter); } public void bind() { gl.glBindTexture(GL10.GL_TEXTURE_2D, textureId); } public void dispose() { gl.glBindTexture(GL10.GL_TEXTURE_2D, textureId); int[] textureIds = {textureId}; gl.glDeleteTextures(1, textureIds, 0); } } OpenGLRenderer.java package com.chrypthic.android.reference; 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; public class OpenGLRenderer implements Renderer { Random rand = new Random(); int mWidth = 0; int mHeight = 0; Context c; Square square; public OpenGLRenderer(Context c) { this.c = c; } #Override public void onDrawFrame(GL10 gl) { gl.glClearColor(1, 1, 1, 1); gl.glClear(GL10.GL_COLOR_BUFFER_BIT); gl.glViewport(0, 0, mWidth, mHeight); gl.glMatrixMode(GL10.GL_PROJECTION); gl.glLoadIdentity(); gl.glOrthof(0, mWidth, 0, mHeight, -1, 1); if(square != null)square.draw(); } #Override public void onSurfaceChanged(GL10 gl, int width, int height) { mWidth = width; mHeight = height; } #Override public void onSurfaceCreated(GL10 gl, EGLConfig config) { square = new Square(gl, c); } } I hope you can help me, if you need even more information just tell me. Thanks in advance. I did't post the white screen as a screenshot, because it seems kind of pointless with the white background that stackoverflow have.
You never create the texture! public void load() { try{ int []texture = new int[1]; gl.glGenTextures(1, texture,0);//the missing method textureId = texture[0]; //now you can call AssetManager assetManager = context.getAssets(); InputStream is = assetManager.open(texturePath); texture = BitmapFactory.decodeStream(is); gl.glBindTexture(GL10.GL_TEXTURE_2D, textureId);/*this fails if textureId is a 'random' number. You must/should generate a valid id. */ GLUtils.texImage2D(GL10.GL_TEXTURE_2D, 0, texture, 0); setFilters(GL10.GL_NEAREST, GL10.GL_NEAREST); gl.glBindTexture(GL10.GL_TEXTURE_2D, 0); It is exactly the opposite of your dispose() method.
Going from a comment to an answer. (Comment): Why are you using glVertexPointer twice rather that glVertexPointer and then glTexCoordPointer? Also there seems to be a typo in that line that says GL_FLAT instead of GL_FLOAT. Are you sure you're giving us your actual code? -Answer starts here- It looks like you aren't using texture coordinates at all. You have to specify which corner of the texture you'd like to assign to which corner of the triangle/quad. For example, I see that you've got a "tl" comment next to the top left vertex. You similarly need to supply a texture coordinate that says "use the top left corner of the image with this vertex" and then OpenGL figures out the rest. Then when you go to pass the vertex pointer, you also have to pass a texture coordinate pointer that contains those texture coordinates I were just talking about in the previous paragraph. You do this with glTexCoordPointer in the exact same fashion as glVertexPointer. You can also load texture coordinates into a VBO (in fact, into the same VBO as the vertices, then you can call glTexCoordPointer with the offset into the VBO to where the tex coords start). Let me know (via comment) if you need more elaboration/code examples or more explanation anywhere. Edit 1: See these links for information about texture mapping: gamedev, nehe Edit 2: Okay, stupid me. I didn't notice that you've actually got the texture coordinate data in with the vertex data. Try changing your second call to glVertexPointer to glTexCoordPointer. This might fix your problem entirely.