Replicate texture effect from 2d to 3d OpenGL - java

I have a 2D OpenGL project for android of a .png as a texture on a Square. I would like to replicate the effect on all 6 sides of a 3D cube. I tried matching the format as closely as possible, but ran into a unexpected stopping issue.
My first code block:
package book.BouncySquare;
import android.content.Context;
import android.graphics.*;
import android.opengl.*;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.FloatBuffer;
import java.nio.IntBuffer;
import javax.microedition.khronos.opengles.GL10;
import javax.microedition.khronos.opengles.GL11;
/**
* A vertex shaded square.
*/
class Square
{
public Square()
{
float vertices[] =
{
-1.0f, -1.0f,
1.0f, -1.0f,
-1.0f, 1.0f,
1.0f, 1.0f
};
byte maxColor=(byte)255;
byte colors[] =
{
maxColor,maxColor, 0,maxColor,
0, maxColor,maxColor,maxColor,
0, 0, 0,maxColor,
maxColor, 0,maxColor,maxColor
};
byte indices[] =
{
0, 3, 1,
0, 2, 3
};
float[] textureCoords =
{
0.0f, 0.0f,
1.0f, 0.0f,
0.0f, 1.0f,
1.0f, 1.0f
};
ByteBuffer vbb = ByteBuffer.allocateDirect(vertices.length * 4);
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);
ByteBuffer tbb = ByteBuffer.allocateDirect(textureCoords.length * 4);
tbb.order(ByteOrder.nativeOrder());
mTextureBuffer = tbb.asFloatBuffer();
mTextureBuffer.put(textureCoords);
mTextureBuffer.position(0);
}
public void draw(GL10 gl)
{
gl.glVertexPointer(2, GL10.GL_FLOAT, 0, mFVertexBuffer);
gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
gl.glColorPointer(4, GL10.GL_UNSIGNED_BYTE, 0, mColorBuffer);
gl.glEnableClientState(GL10.GL_COLOR_ARRAY);
gl.glEnable(GL10.GL_TEXTURE_2D); //1
gl.glEnable(GL10.GL_BLEND); //2
gl.glBlendFunc(GL10.GL_ONE, GL10.GL_SRC_COLOR); //3
gl.glBindTexture(GL10.GL_TEXTURE_2D, textures[0]); //4
gl.glTexCoordPointer(2, GL10.GL_FLOAT,0, mTextureBuffer); //5
gl.glEnableClientState(GL10.GL_TEXTURE_COORD_ARRAY); //6
gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP, 0, 4); //7
gl.glDisableClientState(GL10.GL_COLOR_ARRAY);
gl.glDisableClientState(GL10.GL_VERTEX_ARRAY);
gl.glDisableClientState(GL10.GL_TEXTURE_COORD_ARRAY); //8
}
private int[] textures = new int[1];
public int createTexture(GL10 gl, Context contextRegf, int resource)
{
Bitmap tempImage = BitmapFactory.decodeResource(contextRegf.getResources(), resource); // 1
gl.glGenTextures(1, textures, 0); // 2
gl.glBindTexture(GL10.GL_TEXTURE_2D, textures[0]); // 3
GLUtils.texImage2D(GL10.GL_TEXTURE_2D, 0, tempImage, 0); // 4
gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MIN_FILTER, GL10.GL_LINEAR); // 5a
gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MAG_FILTER, GL10.GL_LINEAR); // 5b
tempImage.recycle();//6
return resource;
}
private Float mTransY;
public FloatBuffer mTextureBuffer;
private FloatBuffer mFVertexBuffer;
private ByteBuffer mColorBuffer;
private ByteBuffer mIndexBuffer;
}
My second code block:
package book.BouncyCube1;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.FloatBuffer;
import java.nio.IntBuffer;
import javax.microedition.khronos.opengles.GL10;
import javax.microedition.khronos.opengles.GL11;
import android.view.MotionEvent;
/**
* A vertex shaded cube.
*/
class Cube
{
float[] mVertices =
{
-1.0f, 1.0f, 1.0f,
1.0f, 1.0f, 1.0f,
1.0f, -1.0f, 1.0f,
-1.0f, -1.0f, 1.0f,
-1.0f, 1.0f,-1.0f,
1.0f, 1.0f,-1.0f,
1.0f, -1.0f,-1.0f,
-1.0f, -1.0f,-1.0f
};
float maxColor=1.0f;
float[] mColors =
{
maxColor, maxColor, 0.0f,maxColor,
0.0f, maxColor, maxColor,maxColor,
0.0f, 0.0f, 0.0f,maxColor,
maxColor, 0.0f, maxColor,maxColor,
maxColor, 0.0f, 0.0f,maxColor,
0.0f, maxColor, 0.0f,maxColor,
0.0f, 0.0f, maxColor,maxColor,
0.0f, 0.0f, 0.0f,maxColor
};
float[] mNormals =
{
0.0f, 0.0f, 1.0f,
0.0f, 0.0f, 1.0f,
1.0f, 0.0f, 0.0f,
1.0f, 0.0f, 0.0f,
0.0f, 1.0f, 0.0f,
0.0f, 1.0f, 0.0f,
0.0f, 0.0f, -1.0f,
0.0f, 0.0f, -1.0f,
0.0f, -1.0f, 0.0f,
0.0f, -1.0f, 0.0f,
-1.0f, 0.0f, 0.0f,
-1.0f, 0.0f, 0.0f,
};
byte[] tfan1 =
{
1,0,3,
1,3,2,
1,2,6,
1,6,5,
1,5,4,
1,4,0
};
byte[] tfan2 =
{
7,4,5,
7,5,6,
7,6,2,
7,2,3,
7,3,0,
7,0,4
};
public Cube()
{
mTfan1 = ByteBuffer.allocateDirect(tfan1.length);
mTfan1.put(tfan1);
mTfan1.position(0);
mTfan2 = ByteBuffer.allocateDirect(tfan2.length);
mTfan2.put(tfan2);
mTfan2.position(0);
}
public void draw(GL10 gl)
{
gl.glVertexPointer(3, GL11.GL_FLOAT, 0,makeFloatBuffer(mVertices));
gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
gl.glColorPointer(4, GL11.GL_FLOAT, 0,makeFloatBuffer(mColors));
gl.glEnableClientState(GL10.GL_COLOR_ARRAY);
gl.glNormalPointer(GL11.GL_FLOAT, 0,makeFloatBuffer(mNormals));
gl.glEnableClientState(GL10.GL_NORMAL_ARRAY);
gl.glDrawElements( gl.GL_TRIANGLE_FAN, 6 * 3, gl.GL_UNSIGNED_BYTE, mTfan1);
gl.glDrawElements( gl.GL_TRIANGLE_FAN, 6 * 3, gl.GL_UNSIGNED_BYTE, mTfan2);
}
protected static FloatBuffer makeFloatBuffer(float[] arr)
{
ByteBuffer bb = ByteBuffer.allocateDirect(arr.length*4);
bb.order(ByteOrder.nativeOrder());
FloatBuffer fb = bb.asFloatBuffer();
fb.put(arr);
fb.position(0);
return fb;
}
private FloatBuffer mFVertexBuffer;
private FloatBuffer mNormalBuffer;
private ByteBuffer mColorBuffer;
private ByteBuffer mIndexBuffer;
private ByteBuffer mTfan1;
private ByteBuffer mTfan2;
}

OpenGL only supports one set of indices for a draw call, and these indices are used to address all vertex attributes (positions, colors, normals). Looking at your second version, you have 8 positions, 8 colors, and 12 normals. One way to notice that this can't work is that the range of your indices is 0..7, so not all of your 12 normals are used.
What you need to do is create a OpenGL vertex for every unique combination of position, color and normal. For a cube, you will end up with 24 vertices. While the cube has only 8 corners, there are 3 different normals at each corner, and 8 * 3 = 24. While the cube has only 6 different normals, each normal is used for 4 corners, and 6 * 4 = 24.
So define an array with 24 positions, an array with 24 colors, and an array with 24 normals, matched up to define all 24 vertices. Or one array with all of these 3 attributes interleaved. Then define your index array to connect the 24 vertices with the correct triangles, and draw.

Related

Texturing a cube in jogl results in black screen

I am trying to texture a cube in jogl with an image of calvin and hobbes. Every source I look at online says to have the line
gl.glEnable(GL2.GL_TEXTURE_2D); in there. However, when I add it in, I get a black screen. When I comment it out, I get a cube on the screen. Any help is welcomed as I have googled this problem to death and have tried countless solutions. My Source code is below.
package project1;
import java.awt.Dimension;
import java.io.File;
import java.io.IOException;
import javax.swing.JFrame;
import com.jogamp.opengl.GL2;
import com.jogamp.opengl.GL3;
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.Animator;
import com.jogamp.opengl.util.texture.Texture;
import com.jogamp.opengl.util.texture.TextureIO;
/**
* Simple Implements GLEventListener so that I can modify
* what happens when application runs
*
* #author Alex Thoennes
*
*/
public class Simple extends GLCanvas implements GLEventListener
{
private static final long serialVersionUID = 1L;
private double eyeX = 5;
private double eyeY = 5;
private double eyeZ = 5;
private float o = 0.0001f;
// this is the title of the frame
static final String TITLE = "Simple";
// these are the dimensions of the frame
static final int CANVAS_WIDTH = 500;
static final int CANVAS_HEIGHT = 500;
int texture;
Texture t;
public static void main (String [] args)
{
// this class extends the GLCanvas class
// so that I have something to reference
// when I want to draw
GLCanvas canvas = new Simple();
canvas.setPreferredSize(new Dimension(CANVAS_WIDTH, CANVAS_HEIGHT));
// create a new frame to hold the canvas
JFrame frame = new JFrame();
// add the canvas to the frame
frame.getContentPane().add(canvas);
// set the title of the frame
frame.setTitle(TITLE);
// this is not required but is convenient. When you
// click the 'x' in the top left of the screen, the
// application will close
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
// pack the frame
frame.pack();
// then make it displayable to the user
frame.setVisible(true);
// Create an animator object and then add it to
// the canvas and start the animation
Animator animator = new Animator(canvas);
animator.start();
}
// constructor for the class
// you need to add a GLEventListener
// to it so that you can draw with the gl methods
public Simple ()
{
this.addGLEventListener(this);
}
#Override
public void init(GLAutoDrawable drawable)
{
final GL2 gl = drawable.getGL().getGL2();
gl.glEnable(GL2.GL_DEPTH_TEST);
//gl.glEnable(GL2.GL_TEXTURE_2D);
try
{
File im = new File("calvin-and-hobbes.png");
t = TextureIO.newTexture(im, true);
texture = t.getTextureObject(gl);
gl.glBindTexture(GL2.GL_TEXTURE_2D, texture);
gl.glTexParameteri(GL2.GL_TEXTURE_2D, GL2.GL_TEXTURE_MAG_FILTER, GL2.GL_LINEAR);
gl.glTexParameteri(GL2.GL_TEXTURE_2D, GL2.GL_TEXTURE_MIN_FILTER, GL2.GL_LINEAR);
}
catch(IOException e)
{
e.printStackTrace();
}
}
#Override
public void dispose(GLAutoDrawable drawable) {}
#Override
public void display(GLAutoDrawable drawable)
{
// create objects used for drawing
final GL2 gl = drawable.getGL().getGL2();
GLU glu = new GLU();
transformEye();
gl.glMatrixMode(GL2.GL_PROJECTION);
gl.glLoadIdentity();
glu.gluPerspective(40.0, 1.0, 1.0, 10000.0);
gl.glMatrixMode(GL2.GL_TEXTURE);
gl.glLoadIdentity();
gl.glMatrixMode(GL2.GL_MODELVIEW);
gl.glLoadIdentity();
glu.gluLookAt(eyeX, eyeY, eyeZ, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0);
gl.glClear(GL2.GL_COLOR_BUFFER_BIT | GL2.GL_DEPTH_BUFFER_BIT);
//gl.glEnable(GL2.GL_TEXTURE_2D);
//t.bind(gl);
//t.enable(gl);
gl.glBindTexture(GL2.GL_TEXTURE_2D, texture);
//gl.glEnable(GL2.GL_TEXTURE_2D);
drawTriangles(gl);
//gl.glFlush();
// increment the angle so that the viewer rotates
//o += 0.0001f;
}
#Override
public void reshape(GLAutoDrawable drawable, int x, int y, int width, int height) {}
/**
* This method rotates the viewer
*/
private void transformEye()
{
// use o for theta which is the amount of degrees
eyeX = (5 * Math.cos(o)) + (5 * Math.sin(o));
eyeZ = (-5 * Math.sin(o)) + (5 * Math.cos(o));
}
/**
* This method draws all the triangles as the viewer rotates
*
* #param gl
*/
private void drawTriangles(GL2 gl)
{
// gl.glColor3f(1.0f, 1.0f, 1.0f);
// gl.glColor3f(1.0f, 0.0f, 0.0f);
// Triangle 0
gl.glBegin(GL3.GL_TRIANGLES);
gl.glTexCoord2f(0f, 0f);
gl.glVertex3f(0.5f, 0.5f, 0.5f);
gl.glTexCoord2f(0f, 1f);
gl.glVertex3f(0.5f, -0.5f, 0.5f);
gl.glTexCoord2f(1f, 0f);
gl.glVertex3f(-0.5f, 0.5f, 0.5f);
gl.glEnd();
// Triangle 1
gl.glBegin(GL3.GL_TRIANGLES);
// gl.glTexCoord3f(-0.5f, -0.5f, 0.5f);
gl.glVertex3f(-0.5f, -0.5f, 0.5f);
// gl.glTexCoord3f(0.5f, -0.5f, 0.5f);
gl.glVertex3f(0.5f, -0.5f, 0.5f);
// gl.glTexCoord3f(-0.5f, 0.5f, 0.5f);
gl.glVertex3f(-0.5f, 0.5f, 0.5f);
gl.glEnd();
// gl.glColor3f(0.0f, 0.5f, 0.0f);
// Triangle 2
gl.glBegin(GL3.GL_TRIANGLES);
gl.glVertex3f(0.5f, 0.5f, 0.5f);
gl.glVertex3f(0.5f, 0.5f, -0.5f);
gl.glVertex3f(-0.5f, 0.5f, 0.5f);
gl.glEnd();
// Triangle 3
gl.glBegin(GL3.GL_TRIANGLES);
gl.glVertex3f(-0.5f, 0.5f, -0.5f);
gl.glVertex3f(0.5f, 0.5f, -0.5f);
gl.glVertex3f(-0.5f, 0.5f, 0.5f);
gl.glEnd();
// gl.glColor3f(0.0f, 0.0f, 0.5f);
// Triangle 4
gl.glBegin(GL3.GL_TRIANGLES);
gl.glVertex3f(0.5f, -0.5f, 0.5f);
gl.glVertex3f(0.5f, 0.5f, 0.5f);
gl.glVertex3f(0.5f, 0.5f, -0.5f);
gl.glEnd();
// Triangle 5
gl.glBegin(GL3.GL_TRIANGLES);
gl.glVertex3f(0.5f, -0.5f, 0.5f);
gl.glVertex3f(0.5f, -0.5f, -0.5f);
gl.glVertex3f(0.5f, 0.5f, -0.5f);
gl.glEnd();
// gl.glColor3f(0.5f, 0.0f, 0.5f);
// Triangle 6
gl.glBegin(GL3.GL_TRIANGLES);
gl.glVertex3f(-0.5f, -0.5f, 0.5f);
gl.glVertex3f(-0.5f, -0.5f, -0.5f);
gl.glVertex3f(0.5f, -0.5f, -0.5f);
gl.glEnd();
// Triangle 7
gl.glBegin(GL3.GL_TRIANGLES);
gl.glVertex3f(-0.5f, -0.5f, 0.5f);
gl.glVertex3f(0.5f, -0.5f, 0.5f);
gl.glVertex3f(0.5f, -0.5f, -0.5f);
gl.glEnd();
// gl.glColor3f(0.0f, 0.2f, 0.613f);
// Triangle 8
gl.glBegin(GL3.GL_TRIANGLES);
gl.glVertex3f(-0.5f, -0.5f, 0.5f);
gl.glVertex3f(-0.5f, -0.5f, -0.5f);
gl.glVertex3f(-0.5f, 0.5f, -0.5f);
gl.glEnd();
// Triangle 9
gl.glBegin(GL3.GL_TRIANGLES);
gl.glVertex3f(-0.5f, 0.5f, 0.5f);
gl.glVertex3f(-0.5f, -0.5f, 0.5f);
gl.glVertex3f(-0.5f, 0.5f, -0.5f);
gl.glEnd();
// gl.glColor3f(0.6134f, 0.4513f, 0.1423f);
// Triangle 10
gl.glBegin(GL3.GL_TRIANGLES);
gl.glVertex3f(-0.5f, -0.5f, -0.5f);
gl.glVertex3f(0.5f, -0.5f, -0.5f);
gl.glVertex3f(0.5f, 0.5f, -0.5f);
gl.glEnd();
// Triangle 11
gl.glBegin(GL3.GL_TRIANGLES);
gl.glVertex3f(-0.5f, -0.5f, -0.5f);
gl.glVertex3f(-0.5f, 0.5f, -0.5f);
gl.glVertex3f(0.5f, 0.5f, -0.5f);
gl.glEnd();
}
}

Why is the cube rendered without colors?

Please advise why is the cube rendered without colors although my VBO contains colors? What am I doing wrong? Many thanks in advance!
Voxel.java
package cz.rv.cubeworld.mesh;
import org.lwjgl.BufferUtils;
import org.lwjgl.opengl.GL11;
import org.lwjgl.opengl.GL15;
import java.nio.FloatBuffer;
public class Voxel {
/**
H_______________G
/. /|
/ . / |
D/_____________C/ |
| . | |
| . | |
| ...........|...|
| . E | /F
|______________|/
A B
*/
private static final float[] vertexData = {
// Position // Normal // Color
// Back side - E H G F
-1.0f, -1.0f, -1.0f, 0.0f, 0.0f, -1.0f, 1.0f, 1.0f, 1.0f, 1.0f, // E
1.0f, -1.0f, -1.0f, 0.0f, 0.0f, -1.0f, 1.0f, 1.0f, 1.0f, 1.0f, // F
1.0f, 1.0f, -1.0f, 0.0f, 0.0f, -1.0f, 1.0f, 1.0f, 1.0f, 1.0f, // G
-1.0f, 1.0f, -1.0f, 0.0f, 0.0f, -1.0f, 1.0f, 1.0f, 1.0f, 1.0f, // H
// Bottom side - F B A E
1.0f, -1.0f, -1.0f, 0.0f, -1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 1.0f, // F
1.0f, -1.0f, 1.0f, 0.0f, -1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 1.0f, // B
-1.0f, -1.0f, 1.0f, 0.0f, -1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 1.0f, // A
-1.0f, -1.0f, -1.0f, 0.0f, -1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 1.0f, // E
// Right side - F G C B
1.0f, -1.0f, -1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, 1.0f, // F
1.0f, 1.0f, -1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, 1.0f, // G
1.0f, 1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, 1.0f, // C
1.0f, -1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, 1.0f, // B
// Top side - C G H D
1.0f, 1.0f, -1.0f, 0.0f, 1.0f, 0.0f, 1.0f, 1.0f, 0.0f, 1.0f, // C
1.0f, 1.0f, 1.0f, 0.0f, 1.0f, 0.0f, 1.0f, 1.0f, 0.0f, 1.0f, // G
-1.0f, 1.0f, 1.0f, 0.0f, 1.0f, 0.0f, 1.0f, 1.0f, 0.0f, 1.0f, // H
-1.0f, 1.0f, -1.0f, 0.0f, 1.0f, 0.0f, 1.0f, 1.0f, 0.0f, 1.0f, // D
// Left side - A D H E
-1.0f, -1.0f, -1.0f, -1.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, // A
-1.0f, 1.0f, -1.0f, -1.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, // D
-1.0f, 1.0f, 1.0f, -1.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, // H
-1.0f, -1.0f, 1.0f, -1.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, // E
// Front side - A D C B
-1.0f, -1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.0f, 1.0f, 1.0f, // A
-1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.0f, 1.0f, 1.0f, // D
1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.0f, 1.0f, 1.0f, // C
1.0f, -1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.0f, 1.0f, 1.0f, // B
};
private static final int TOTAL_NUMBER_OF_VERTICES = 24;
private static final int VERTEX_ATTRIBUTE_SIZE = 10 * Float.BYTES; // In bytes
private static final int VERTEX_POSITION_SIZE = 3; // In floats
private static final int VERTEX_COLOR_SIZE = 4; // In floats
private static final int FIRST_VERTEX_POSITION_POINTER = 0; // In bytes
private static final int FIRST_VERTEX_NORMAL_POINTER = 3 * Float.BYTES; // In bytes
private static final int FIRST_VERTEX_COLOR_POINTER = 6 * Float.BYTES; // In bytes
private final int vertexBufferObjectHandle;
private final FloatBuffer vertexBufferObject;
public Voxel() {
vertexBufferObject = BufferUtils.createFloatBuffer(vertexData.length); // Allocate direct float buffer
vertexBufferObject.put(vertexData).flip(); // Write data to the buffer and reset the position to zero
vertexBufferObjectHandle = GL15.glGenBuffers(); // Create named buffer object
GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, vertexBufferObjectHandle); // Hey, GL, we will be using named buffer object we just generated
GL15.glBufferData(GL15.GL_ARRAY_BUFFER, vertexBufferObject, GL15.GL_STATIC_DRAW); // Write vertexBufferObject data to our named buffer object
GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, 0); // Tell GL we aren't using any named buffer since now
}
public void render(float x, float y, float z, float xrot, float yrot, float zrot) {
GL11.glLoadIdentity();
GL11.glTranslatef(x, y, z);
GL11.glRotatef(xrot, 1.0f, 0.0f, 0.0f);
GL11.glRotatef(yrot, 0.0f, 1.0f, 0.0f);
GL11.glRotatef(zrot, 0.0f, 0.0f, 1.0f);
GL11.glEnableClientState(GL11.GL_VERTEX_ARRAY);
GL11.glEnableClientState(GL11.GL_NORMAL_ARRAY);
GL11.glEnableClientState(GL11.GL_COLOR_ARRAY);
GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, vertexBufferObjectHandle);
GL11.glVertexPointer(VERTEX_POSITION_SIZE, GL11.GL_FLOAT, VERTEX_ATTRIBUTE_SIZE, FIRST_VERTEX_POSITION_POINTER);
GL11.glColorPointer(VERTEX_COLOR_SIZE, GL11.GL_FLOAT, VERTEX_ATTRIBUTE_SIZE, FIRST_VERTEX_COLOR_POINTER);
GL11.glNormalPointer(GL11.GL_FLOAT, VERTEX_ATTRIBUTE_SIZE, FIRST_VERTEX_NORMAL_POINTER);
GL11.glDrawArrays(GL11.GL_QUADS, 0, TOTAL_NUMBER_OF_VERTICES);
GL11.glDisableClientState(GL11.GL_VERTEX_ARRAY);
GL11.glDisableClientState(GL11.GL_NORMAL_ARRAY);
GL11.glDisableClientState(GL11.GL_COLOR_ARRAY);
}
}
DisplayExample.java
package cz.rv.cubeworld;
import cz.rv.cubeworld.mesh.Voxel;
import org.lwjgl.LWJGLException;
import org.lwjgl.opengl.Display;
import org.lwjgl.opengl.DisplayMode;
import org.lwjgl.opengl.GL11;
import org.lwjgl.util.glu.GLU;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.FloatBuffer;
public class DisplayExample {
private float xrot;
private float yrot;
private float zrot;
private float lightAmbient[] = { 1.0f, 1.0f, 1.0f, 1.0f };
private float lightDiffuse[] = { 1.0f, 1.0f, 1.0f, 1.0f };
private float lightPosition[] = { 0.0f, 0.0f, 0.1f, 1.0f };
private Voxel voxel;
public static void main(String[] args) {
DisplayExample displayExample = new DisplayExample();
displayExample.start();
}
public void start() {
try {
init();
voxel = new Voxel();
while (!Display.isCloseRequested()) {
render();
Display.update();
Display.sync(60);
xrot += 0.2f;
yrot += 0.3f;
zrot += 0.1f;
}
cleanup();
} catch (LWJGLException | IOException e) {
e.printStackTrace();
System.exit(0);
}
}
private void init() throws LWJGLException, IOException {
createWindow();
initGL();
}
private void createWindow() throws LWJGLException {
DisplayMode displayMode = null;
for (DisplayMode mode : Display.getAvailableDisplayModes()) {
if (mode.getWidth() == 640 && mode.getHeight() == 480 && mode.getBitsPerPixel() == 24) {
displayMode = mode;
break;
}
}
Display.setDisplayMode(displayMode);
Display.setTitle("CubeWorld");
Display.create();
}
private void initGL() {
//GL11.glEnable(GL11.GL_TEXTURE_2D); // Enable Texture Mapping
GL11.glShadeModel(GL11.GL_SMOOTH); // Enable Smooth Shading
GL11.glClearColor(0.0f, 0.0f, 0.0f, 0.0f); // Black Background
GL11.glClearDepth(1.0); // Depth Buffer Setup
GL11.glEnable(GL11.GL_DEPTH_TEST); // Enables Depth Testing
GL11.glDepthFunc(GL11.GL_LEQUAL); // The Type Of Depth Testing To Do
GL11.glMatrixMode(GL11.GL_PROJECTION); // Select The Projection Matrix
GL11.glLoadIdentity(); // Reset The Projection Matrix
GLU.gluPerspective(45.0f, (float) Display.getWidth() / (float) Display.getHeight(), 0.1f, 100.0f); // Calculate The Aspect Ratio Of The Window
GL11.glMatrixMode(GL11.GL_MODELVIEW); // Select The Modelview Matrix
GL11.glHint(GL11.GL_PERSPECTIVE_CORRECTION_HINT, GL11.GL_NICEST); // Really Nice Perspective Calculations
GL11.glEnable(GL11.GL_LIGHTING);
ByteBuffer lightBuffer = ByteBuffer.allocateDirect(16);
lightBuffer.order(ByteOrder.nativeOrder());
GL11.glLight(GL11.GL_LIGHT1, GL11.GL_AMBIENT, (FloatBuffer) lightBuffer.asFloatBuffer().put(lightAmbient).flip()); // Setup The Ambient Light
GL11.glLight(GL11.GL_LIGHT1, GL11.GL_DIFFUSE, (FloatBuffer) lightBuffer.asFloatBuffer().put(lightDiffuse).flip()); // Setup The Diffuse Light
GL11.glLight(GL11.GL_LIGHT1, GL11.GL_POSITION, (FloatBuffer) lightBuffer.asFloatBuffer().put(lightPosition).flip()); // Position The Light
GL11.glEnable(GL11.GL_LIGHT1); // Enable Light One
}
private void cleanup() {
Display.destroy();
}
private void render() {
GL11.glClear(GL11.GL_COLOR_BUFFER_BIT | GL11.GL_DEPTH_BUFFER_BIT);
voxel.render(0, 0, -5, xrot, yrot ,zrot);
}
}
It looks like you're missing:
GL11.glEnable(GL11.GL_COLOR_MATERIAL);

GSON unable to invoke no-constructor for class FloatBuffer

So im trying to load an object, but for some reason its throwing gson unable to invoke no-args constructor for class java.nio.FloatBuffer:
Saving works
The main class(where the load function is:
public void saveNode(RenderNode node, String key) {
SharedPreferences.Editor ed = prefs.edit();
Gson gson = new Gson();
String json = gson.toJson(node);
ed.putString(key, json);
ed.commit();
}
public RenderNode loadNode(String key) throws IOException,
ClassNotFoundException {
Gson gson = new Gson();
String json = prefs.getString(key, "");
RenderNode obj = gson.fromJson(json, RenderNode.class);
return obj;
}
The object:
package com.uraniumdevelopers.etchcubes;
public class RenderNode {
int nodeSize = 10;
Cube[][] cubes = new Cube[nodeSize][nodeSize];
public RenderNode() {
float i1 = -5f, j1 = -5f;
for (int i = 0; i < nodeSize; i++) {
j1 = -5f;
for (int j = nodeSize - 1; j >= 0; j--) {
cubes[i][j] = new Cube(i1, j1, -5f);
j1 += 1f;
}
i1 += 1f;
}
}
public void renderNode() {
for (int i = 0; i < nodeSize; i++) {
for (int j = 0; j < nodeSize; j++) {
if (cubes[i][j] != null)
cubes[i][j].drawCube(shouldRender(i, j));
}
}
}
private int[] shouldRender(int i, int j) {
int[] sR = new int[4];
for (int k = 0; k < sR.length; k++) {
sR[k] = 37;
}
if ((i - 1) > 0)
if (cubes[i - 1][j] == null)
sR[0] = 3 * 6;
if ((i + 1) < (nodeSize - 1))
if (cubes[i + 1][j] == null)
sR[1] = 1 * 6;
if ((j + 1) < (nodeSize - 1))
if (cubes[i][j + 1] == null)
sR[2] = 5 * 6;
if ((j - 1) > 0)
if (cubes[i][j - 1] == null)
sR[3] = 4 * 6;
return sR;
}
public void deleteCube(int i, int j) {
if (!(i < 0 || i > nodeSize - 1 || j < 0 || j > nodeSize - 1))
cubes[i][j] = null;
}
}
And the Cube object:
package com.uraniumdevelopers.etchcubes;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.FloatBuffer;
import android.opengl.GLES20;
import android.opengl.Matrix;
public class Cube {
private final FloatBuffer mCubePositions;
private final FloatBuffer mCubeColors;
private final FloatBuffer mCubeNormals;
float x, y, z;
public Cube(float x, float y, float z) {
this.x = x;
this.y = y;
this.z = z;
final float[] cubePositionData = {
// Front face
-1.0f, 1.0f, 1.0f, -1.0f, -1.0f, 1.0f, 1.0f, 1.0f, 1.0f, -1.0f,
-1.0f, 1.0f, 1.0f, -1.0f,
1.0f,
1.0f,
1.0f,
1.0f,
// Right face
1.0f, 1.0f, 1.0f, 1.0f, -1.0f, 1.0f, 1.0f, 1.0f, -1.0f, 1.0f,
-1.0f, 1.0f, 1.0f, -1.0f, -1.0f,
1.0f,
1.0f,
-1.0f,
// Back face
1.0f, 1.0f, -1.0f, 1.0f, -1.0f, -1.0f, -1.0f, 1.0f, -1.0f,
1.0f, -1.0f, -1.0f, -1.0f, -1.0f, -1.0f, -1.0f,
1.0f,
-1.0f,
// Left face
-1.0f, 1.0f, -1.0f, -1.0f, -1.0f, -1.0f, -1.0f, 1.0f, 1.0f,
-1.0f, -1.0f, -1.0f, -1.0f, -1.0f, 1.0f, -1.0f, 1.0f,
1.0f,
// Top face
-1.0f, 1.0f, -1.0f, -1.0f, 1.0f, 1.0f, 1.0f, 1.0f, -1.0f,
-1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, -1.0f,
// Bottom face
1.0f, -1.0f, -1.0f, 1.0f, -1.0f, 1.0f, -1.0f, -1.0f, -1.0f,
1.0f, -1.0f, 1.0f, -1.0f, -1.0f, 1.0f, -1.0f, -1.0f, -1.0f, };
final float[] cubeColorData = {
// Front face (red)
1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.0f,
0.0f, 1.0f, 1.0f, 0.0f,
0.0f,
1.0f,
1.0f,
0.0f,
0.0f,
1.0f,
1.0f,
0.0f,
0.0f,
1.0f,
// Right face (green)
0.0f, 1.0f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f, 1.0f,
0.0f, 1.0f, 0.0f, 1.0f, 0.0f, 1.0f,
0.0f,
1.0f,
0.0f,
1.0f,
0.0f,
1.0f,
0.0f,
1.0f,
// Back face (blue)
0.0f, 0.0f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.0f, 0.0f,
1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.0f, 0.0f,
1.0f,
1.0f,
0.0f,
0.0f,
1.0f,
1.0f,
// Left face (yellow)
1.0f, 1.0f, 0.0f, 1.0f, 1.0f, 1.0f, 0.0f, 1.0f, 1.0f, 1.0f,
0.0f, 1.0f, 1.0f, 1.0f, 0.0f, 1.0f, 1.0f, 1.0f, 0.0f, 1.0f,
1.0f,
1.0f,
0.0f,
1.0f,
// Top face (cyan)
0.0f, 1.0f, 1.0f, 1.0f, 0.0f, 1.0f, 1.0f, 1.0f, 0.0f, 1.0f,
1.0f, 1.0f, 0.0f, 1.0f, 1.0f, 1.0f, 0.0f, 1.0f, 1.0f, 1.0f,
0.0f, 1.0f, 1.0f,
1.0f,
// Bottom face (magenta)
1.0f, 0.0f, 1.0f, 1.0f, 1.0f, 0.0f, 1.0f, 1.0f, 1.0f, 0.0f,
1.0f, 1.0f, 1.0f, 0.0f, 1.0f, 1.0f, 1.0f, 0.0f, 1.0f, 1.0f,
1.0f, 0.0f, 1.0f, 1.0f };
final float[] cubeNormalData = {
// Front face
0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f,
0.0f, 1.0f, 0.0f, 0.0f,
1.0f,
0.0f,
0.0f,
1.0f,
// Right face
1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f,
0.0f, 0.0f, 1.0f, 0.0f, 0.0f,
1.0f,
0.0f,
0.0f,
// Back face
0.0f, 0.0f, -1.0f, 0.0f, 0.0f, -1.0f, 0.0f, 0.0f, -1.0f, 0.0f,
0.0f, -1.0f, 0.0f, 0.0f, -1.0f, 0.0f,
0.0f,
-1.0f,
// Left face
-1.0f, 0.0f, 0.0f, -1.0f, 0.0f, 0.0f, -1.0f, 0.0f, 0.0f, -1.0f,
0.0f, 0.0f, -1.0f, 0.0f, 0.0f, -1.0f, 0.0f,
0.0f,
// Top face
0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f,
1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f,
// Bottom face
0.0f, -1.0f, 0.0f, 0.0f, -1.0f, 0.0f, 0.0f, -1.0f, 0.0f, 0.0f,
-1.0f, 0.0f, 0.0f, -1.0f, 0.0f, 0.0f, -1.0f, 0.0f };
mCubePositions = ByteBuffer
.allocateDirect(
cubePositionData.length * Renderer.mBytesPerFloat)
.order(ByteOrder.nativeOrder()).asFloatBuffer();
mCubePositions.put(cubePositionData).position(0);
mCubeColors = ByteBuffer
.allocateDirect(cubeColorData.length * Renderer.mBytesPerFloat)
.order(ByteOrder.nativeOrder()).asFloatBuffer();
mCubeColors.put(cubeColorData).position(0);
mCubeNormals = ByteBuffer
.allocateDirect(cubeNormalData.length * Renderer.mBytesPerFloat)
.order(ByteOrder.nativeOrder()).asFloatBuffer();
mCubeNormals.put(cubeNormalData).position(0);
}
public void drawCube(int[] draw) {
Matrix.setIdentityM(Renderer.mModelMatrix, 0);
Matrix.translateM(Renderer.mModelMatrix, 0, x + 0.5f, y, z);
Matrix.scaleM(Renderer.mModelMatrix, 0, 0.5f, 0.5f, 0.5f);
mCubePositions.position(0);
GLES20.glVertexAttribPointer(Renderer.mPositionHandle,
Renderer.mPositionDataSize, GLES20.GL_FLOAT, false, 0,
mCubePositions);
GLES20.glEnableVertexAttribArray(Renderer.mPositionHandle);
mCubeColors.position(0);
GLES20.glVertexAttribPointer(Renderer.mColorHandle,
Renderer.mColorDataSize, GLES20.GL_FLOAT, false, 0, mCubeColors);
GLES20.glEnableVertexAttribArray(Renderer.mColorHandle);
mCubeNormals.position(0);
GLES20.glVertexAttribPointer(Renderer.mNormalHandle,
Renderer.mNormalDataSize, GLES20.GL_FLOAT, false, 0,
mCubeNormals);
GLES20.glEnableVertexAttribArray(Renderer.mNormalHandle);
Matrix.multiplyMM(Renderer.mMVPMatrix, 0, Renderer.mViewMatrix, 0,
Renderer.mModelMatrix, 0);
GLES20.glUniformMatrix4fv(Renderer.mMVMatrixHandle, 1, false,
Renderer.mMVPMatrix, 0);
Matrix.multiplyMM(Renderer.mMVPMatrix, 0, Renderer.mProjectionMatrix,
0, Renderer.mMVPMatrix, 0);
GLES20.glUniformMatrix4fv(Renderer.mMVPMatrixHandle, 1, false,
Renderer.mMVPMatrix, 0);
GLES20.glUniform3f(Renderer.mLightPosHandle,
Renderer.mLightPosInEyeSpace[0],
Renderer.mLightPosInEyeSpace[1],
Renderer.mLightPosInEyeSpace[2]);
for (int i = 0; i < draw.length; i++) {
if (draw[i] != 37)
GLES20.glDrawArrays(GLES20.GL_TRIANGLES, draw[i], 6);
}
GLES20.glDrawArrays(GLES20.GL_TRIANGLES, 0, 6);
}
public float getX() {
return x;
}
public float getY() {
return y;
}
public float getZ() {
return z;
}
}
STACKTRACE:
03-23 20:32:09.257: E/AndroidRuntime(14477): FATAL EXCEPTION: main
03-23 20:32:09.257: E/AndroidRuntime(14477): java.lang.RuntimeException: Unable to invoke no-args constructor for class java.nio.FloatBuffer. Register an InstanceCreator with Gson for this type may fix this problem.
03-23 20:32:09.257: E/AndroidRuntime(14477): at com.google.gson.internal.ConstructorConstructor$8.construct(ConstructorConstructor.java:167)
03-23 20:32:09.257: E/AndroidRuntime(14477): at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$Adapter.read(ReflectiveTypeAdapterFactory.java:162)
03-23 20:32:09.257: E/AndroidRuntime(14477): at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$1.read(ReflectiveTypeAdapterFactory.java:93)
03-23 20:32:09.257: E/AndroidRuntime(14477): at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$Adapter.read(ReflectiveTypeAdapterFactory.java:172)
03-23 20:32:09.257: E/AndroidRuntime(14477): at com.google.gson.internal.bind.TypeAdapterRuntimeTypeWrapper.read(TypeAdapterRuntimeTypeWrapper.java:40)
03-23 20:32:09.257: E/AndroidRuntime(14477): at com.google.gson.internal.bind.ArrayTypeAdapter.read(ArrayTypeAdapter.java:72)
03-23 20:32:09.257: E/AndroidRuntime(14477): at com.google.gson.internal.bind.TypeAdapterRuntimeTypeWrapper.read(TypeAdapterRuntimeTypeWrapper.java:40)
03-23 20:32:09.257: E/AndroidRuntime(14477): at com.google.gson.internal.bind.ArrayTypeAdapter.read(ArrayTypeAdapter.java:72)
03-23 20:32:09.257: E/AndroidRuntime(14477): at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$1.read(ReflectiveTypeAdapterFactory.java:93)
03-23 20:32:09.257: E/AndroidRuntime(14477): at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$Adapter.read(ReflectiveTypeAdapterFactory.java:172)
03-23 20:32:09.257: E/AndroidRuntime(14477): at com.google.gson.Gson.fromJson(Gson.java:795)
03-23 20:32:09.257: E/AndroidRuntime(14477): at com.google.gson.Gson.fromJson(Gson.java:761)
03-23 20:32:09.257: E/AndroidRuntime(14477): at com.google.gson.Gson.fromJson(Gson.java:710)
03-23 20:32:09.257: E/AndroidRuntime(14477): at com.google.gson.Gson.fromJson(Gson.java:682)
03-23 20:32:09.257: E/AndroidRuntime(14477): at com.uraniumdevelopers.etchcubes.MainActivity.loadNode(MainActivity.java:184)
03-23 20:32:09.257: E/AndroidRuntime(14477): at com.uraniumdevelopers.etchcubes.MainActivity$1.onClick(MainActivity.java:89)
03-23 20:32:09.257: E/AndroidRuntime(14477): at com.android.internal.app.AlertController$AlertParams$3.onItemClick(AlertController.java:934)
03-23 20:32:09.257: E/AndroidRuntime(14477): at android.widget.AdapterView.performItemClick(AdapterView.java:301)
03-23 20:32:09.257: E/AndroidRuntime(14477): at android.widget.AbsListView.performItemClick(AbsListView.java:1280)
03-23 20:32:09.257: E/AndroidRuntime(14477): at android.widget.AbsListView$PerformClick.run(AbsListView.java:3071)
03-23 20:32:09.257: E/AndroidRuntime(14477): at android.widget.AbsListView$1.run(AbsListView.java:3973)
03-23 20:32:09.257: E/AndroidRuntime(14477): at android.os.Handler.handleCallback(Handler.java:615)
03-23 20:32:09.257: E/AndroidRuntime(14477): at android.os.Handler.dispatchMessage(Handler.java:92)
03-23 20:32:09.257: E/AndroidRuntime(14477): at android.os.Looper.loop(Looper.java:137)
03-23 20:32:09.257: E/AndroidRuntime(14477): at android.app.ActivityThread.main(ActivityThread.java:4960)
03-23 20:32:09.257: E/AndroidRuntime(14477): at java.lang.reflect.Method.invokeNative(Native Method)
03-23 20:32:09.257: E/AndroidRuntime(14477): at java.lang.reflect.Method.invoke(Method.java:511)
03-23 20:32:09.257: E/AndroidRuntime(14477): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1038)
03-23 20:32:09.257: E/AndroidRuntime(14477): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:805)
03-23 20:32:09.257: E/AndroidRuntime(14477): at dalvik.system.NativeStart.main(Native Method)
03-23 20:32:09.257: E/AndroidRuntime(14477): Caused by: java.lang.reflect.InvocationTargetException
03-23 20:32:09.257: E/AndroidRuntime(14477): at java.lang.reflect.Method.invokeNative(Native Method)
03-23 20:32:09.257: E/AndroidRuntime(14477): at java.lang.reflect.Method.invoke(Method.java:511)
03-23 20:32:09.257: E/AndroidRuntime(14477): at com.google.gson.internal.UnsafeAllocator$3.newInstance(UnsafeAllocator.java:90)
03-23 20:32:09.257: E/AndroidRuntime(14477): at com.google.gson.internal.ConstructorConstructor$8.construct(ConstructorConstructor.java:164)
03-23 20:32:09.257: E/AndroidRuntime(14477): ... 29 more
03-23 20:32:09.257: E/AndroidRuntime(14477): Caused by: java.lang.InstantiationException: can't instantiate class java.nio.FloatBuffer; abstract class or interface
03-23 20:32:09.257: E/AndroidRuntime(14477): at java.io.ObjectStreamClass.newInstance(Native Method)
03-23 20:32:09.257: E/AndroidRuntime(14477): ... 33 more
You should never actually save it, it should be a static field!

Android - 3D Cube with OPENGL + Textures

I've done a 3d cube with OPENGL library on Android, the cube works pretty but the image on to print on the cube is not displaying...
Here's the code of my Render (java class):
public class GLRenderEx implements Renderer {
private GLCube cube;
Context c;
public GLRenderEx(Context c) {
cube = new GLCube();
this.c = c;
}
#Override
public void onDrawFrame(GL10 gl) {
gl.glDisable(GL10.GL_DITHER);
gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT);
gl.glMatrixMode(GL10.GL_MODELVIEW);
gl.glLoadIdentity();
GLU.gluLookAt(gl, 0, 0, -3, 0, 0, 0, 0, 2, 0);
long time = SystemClock.uptimeMillis() % 4000L;
float angle = .090f * ((int) time);
gl.glRotatef(angle, 2, 4, 3);
cube.draw(gl);
}
#Override
public void onSurfaceChanged(GL10 gl, int width, int height) {
// TODO Auto-generated method stub
gl.glViewport(0, 0, width, height);
float ratio = (float) width / height;
gl.glMatrixMode(GL10.GL_PROJECTION);
gl.glLoadIdentity();
gl.glFrustumf(-ratio, ratio, -1, 1, 1, 25);
}
#Override
public void onSurfaceCreated(GL10 gl, EGLConfig egl) {
gl.glDisable(GL10.GL_DITHER);
gl.glHint(GL10.GL_PERSPECTIVE_CORRECTION_HINT, GL10.GL_FASTEST);
gl.glClearColor(0f, 0f, 0f, 1);
gl.glClearDepthf(1f);
}
}
Here's the code of my cube:
public class GLCube {
/** The buffer holding the vertices */
private FloatBuffer vertexBuffer;
/** The buffer holding the texture coordinates */
private FloatBuffer textureBuffer;
/** The buffer holding the indices */
private ByteBuffer indexBuffer;
/** Our texture pointer */
private int[] textures = new int[1];
/**
* The initial vertex definition
*
* Note that each face is defined, even if indices are available, because of
* the texturing we want to achieve
*/
private float vertices[] = {
// Vertices according to faces
-1.0f,
-1.0f,
1.0f, // Vertex 0
1.0f,
-1.0f,
1.0f, // v1
-1.0f,
1.0f,
1.0f, // v2
1.0f,
1.0f,
1.0f, // v3
1.0f,
-1.0f,
1.0f, // ...
1.0f, -1.0f, -1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, -1.0f,
1.0f, -1.0f, -1.0f, -1.0f, -1.0f, -1.0f, 1.0f, 1.0f, -1.0f, -1.0f,
1.0f, -1.0f,
-1.0f, -1.0f, -1.0f, -1.0f, -1.0f, 1.0f, -1.0f, 1.0f, -1.0f, -1.0f,
1.0f, 1.0f,
-1.0f, -1.0f, -1.0f, 1.0f, -1.0f, -1.0f, -1.0f, -1.0f, 1.0f, 1.0f,
-1.0f, 1.0f,
-1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, -1.0f, 1.0f, -1.0f, 1.0f,
1.0f, -1.0f, };
/** The initial texture coordinates (u, v) */
private float texture[] = {
// Mapping coordinates for the vertices
0.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.0f, 1.0f, 1.0f,
0.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.0f, 1.0f, 1.0f,
0.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.0f, 1.0f, 1.0f,
0.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.0f, 1.0f, 1.0f,
0.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.0f, 1.0f, 1.0f,
0.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.0f, 1.0f, 1.0f,
};
/** The initial indices definition */
private byte indices[] = {
// Faces definition
0, 1, 3, 0, 3,
2, // Face front
4, 5, 7, 4, 7,
6, // Face right
8, 9, 11, 8, 11,
10, // ...
12, 13, 15, 12, 15, 14, 16, 17, 19, 16, 19, 18, 20, 21, 23, 20, 23,
22, };
/**
* The Cube constructor.
*
* Initiate the buffers.
*/
public GLCube() {
//
ByteBuffer byteBuf = ByteBuffer.allocateDirect(vertices.length * 4);
byteBuf.order(ByteOrder.nativeOrder());
vertexBuffer = byteBuf.asFloatBuffer();
vertexBuffer.put(vertices);
vertexBuffer.position(0);
//
byteBuf = ByteBuffer.allocateDirect(texture.length * 4);
byteBuf.order(ByteOrder.nativeOrder());
textureBuffer = byteBuf.asFloatBuffer();
textureBuffer.put(texture);
textureBuffer.position(0);
//
indexBuffer = ByteBuffer.allocateDirect(indices.length);
indexBuffer.put(indices);
indexBuffer.position(0);
}
/**
* The object own drawing function. Called from the renderer to redraw this
* instance with possible changes in values.
*
* #param gl
* - The GL Context
*/
public void draw(GL10 gl) {
// Bind our only previously generated texture in this case
gl.glBindTexture(GL10.GL_TEXTURE_2D, textures[0]);
gl.glEnable(GL10.GL_TEXTURE_2D);
// Point to our buffers
gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
gl.glEnableClientState(GL10.GL_TEXTURE_COORD_ARRAY);
// Set the face rotation
gl.glFrontFace(GL10.GL_CCW);
// Enable the vertex and texture state
gl.glVertexPointer(3, GL10.GL_FLOAT, 0, vertexBuffer);
gl.glTexCoordPointer(2, GL10.GL_FLOAT, 0, textureBuffer);
// Draw the vertices as triangles, based on the Index Buffer information
gl.glDrawElements(GL10.GL_TRIANGLES, indices.length,
GL10.GL_UNSIGNED_BYTE, indexBuffer);
// Disable the client state before leaving
gl.glDisableClientState(GL10.GL_VERTEX_ARRAY);
gl.glDisableClientState(GL10.GL_TEXTURE_COORD_ARRAY);
}
/**
* Load the textures
*
* #param gl
* - The GL Context
* #param context
* - The Activity context
*/
public void loadGLTexture(GL10 gl, Context context) {
// Get the texture from the Android resource directory
InputStream is = context.getResources().openRawResource(
R.drawable.ic_launcher);
Bitmap bitmap = null;
try {
// BitmapFactory is an Android graphics utility for images
bitmap = BitmapFactory.decodeStream(is);
} finally {
// Always clear and close
try {
is.close();
is = null;
} catch (IOException e) {
}
}
// Generate one texture pointer...
gl.glGenTextures(1, textures, 0);
// ...and bind it to our array
gl.glBindTexture(GL10.GL_TEXTURE_2D, textures[0]);
// Create Nearest Filtered Texture
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_LINEAR);
// Different possible texture parameters, e.g. GL10.GL_CLAMP_TO_EDGE
gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_WRAP_S,
GL10.GL_CLAMP_TO_EDGE);
gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_WRAP_T,
GL10.GL_CLAMP_TO_EDGE);
// Use the Android GLUtils to specify a two-dimensional texture image
// from our bitmap
GLUtils.texImage2D(GL10.GL_TEXTURE_2D, 0, bitmap, 0);
// Clean up
bitmap.recycle();
}
}
Why is the bitmap on my code not displaying in the cube??!!
Thanks.
I have looked through your code and haven't found a place, where you call loadGLTexture(). When I implemented your code to make textures, I just added cube.loadGLTexture(gl, c); above cube.draw(gl); in onDrawFrame() method. Hope that helps.
If you want to texture your objects, you must enable texturing with glEnable(GL_TEXTURE_2D);
I don't see this anywhere in your code.
I've had the some problem as you.
What caused my problem was the texture not matching exactly with the cube.
Check your code carefully, you might notice some mismatching.

How do I move a shape with a texture in OpenGL ES?

How can I move the shape? I have tried changing the float that holds all the vertices but it didnt work... Then I have tried glTranslateF, but it didnt work either. What am I doing wrong?
Here is my code:
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;
import android.util.Log;
public class Square
{
final int VERTEX_SIZE = (2+2) *4;
FloatBuffer vertices;
ShortBuffer indices;
Texture texture;
GL10 gl;
Context c;
int x;
int y;
int w;
int h;
public Square(GL10 gl, Context context, int x, int y, int w, int h, String imageTexture)
{
this.gl = gl;
this.c = context;
this.x = x;
this.y = y;
this.w = w;
this.h = h;
ByteBuffer byteBuffer = ByteBuffer.allocateDirect(4 * VERTEX_SIZE);
byteBuffer.order(ByteOrder.nativeOrder());
vertices = byteBuffer.asFloatBuffer();
/*vertices.put(new float[]{
10.0f, 10.0f, 0.0f, 1.0f, //bl
160.0f, 10.0f, 1.0f, 1.0f, //br
160.0f, 160.0f, 1.0f, 0.0f, //tr
10.0f, 160.0f, 0.0f, 0.0f, //tl
});*/
vertices.put(new float[]{
(float)x, ((float)y+(float)h), 0.0f, 1.0f, //bl
((float)x+(float)w), ((float)y+(float)h), 1.0f, 1.0f, //br
((float)x+(float)w), (float)y, 1.0f, 0.0f, //tr
(float)x, (float)y, 0.0f, 0.0f, //tl
});
vertices.flip();
byteBuffer = ByteBuffer.allocateDirect(6 * 2);
byteBuffer.order(ByteOrder.nativeOrder());
indices = byteBuffer.asShortBuffer();
indices.put(new short[]{
0, 1, 2, 2, 3, 0
});
indices.flip();
texture = new Texture(imageTexture, c, gl);
texture.load();
}
public void draw()
{
gl.glMatrixMode(GL10.GL_PROJECTION);
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);
}
public void update()
{
//this doesnt work. I call the method every 10 milliseconds from a thread in another class.
gl.glEnable(GL10.GL_TEXTURE_2D);
gl.glTranslatef(10, y, 0);
}
}
The problem in the source you provided was the fact that glTranslatef needs to be called before performing the draw operation. Set the matrix mode to modelview set the translation and all the drawing will be drawn at the new position.
You mention you call update from another thread, but OpenGL calls are only valid on the same thread that created the context.
Also you should read about OpenGL transformations. It takes some effort to understand so have patience.
http://glprogramming.com/red/chapter03.html

Categories