I need to make 3D objects to face up same way no matter their position to the camera. As if camera was very very far away and zoomed in. Here is what I mean (take a look at the pillar and walls): http://youtu.be/Pn9fh93oV-c
Here is what I have so far:
package pack;
import org.lwjgl.LWJGLException;
import org.lwjgl.input.Keyboard;
import org.lwjgl.opengl.Display;
import org.lwjgl.opengl.DisplayMode;
import org.lwjgl.opengl.GL11;
import java.util.Random;
import static org.lwjgl.opengl.GL11.*;
import static org.lwjgl.util.glu.GLU.gluPerspective;
public class Main {
float viewx, viewy;
float angle;
public static void main(String[] args) {
Main main = new Main();
main.start();
}
private void start() {
try {
Display.setDisplayMode(new DisplayMode(640, 480));
Display.setTitle("Three Dee Demo");
Display.create();
} catch (LWJGLException e) {
e.printStackTrace();
Display.destroy();
System.exit(1);
}
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective((float) 30, 640f / 480f, 0.001f, 100);
glMatrixMode(GL_MODELVIEW);
glEnable(GL_DEPTH_TEST);
glTranslatef(0, 0, -20);
while (!Display.isCloseRequested()) {
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
update();
render();
Display.update();
Display.sync(60);
}
Display.destroy();
System.exit(0);
}
private void render() {
GL11.glBegin(GL11.GL_QUADS);
GL11.glColor3f(1.0f,1.0f,0.0f);
GL11.glVertex3f( 1.0f, 1.0f,-1.0f);
GL11.glVertex3f(-1.0f, 1.0f,-1.0f);
GL11.glVertex3f(-1.0f, 1.0f, 1.0f);
GL11.glVertex3f( 1.0f, 1.0f, 1.0f);
GL11.glColor3f(1.0f,0.5f,0.0f);
GL11.glVertex3f( 1.0f,-1.0f, 1.0f);
GL11.glVertex3f(-1.0f,-1.0f, 1.0f);
GL11.glVertex3f(-1.0f,-1.0f,-1.0f);
GL11.glVertex3f( 1.0f,-1.0f,-1.0f);
GL11.glColor3f(1.0f,0.0f,0.0f);
GL11.glVertex3f( 1.0f, 1.0f, 1.0f);
GL11.glVertex3f(-1.0f, 1.0f, 1.0f);
GL11.glVertex3f(-1.0f,-1.0f, 1.0f);
GL11.glVertex3f( 1.0f,-1.0f, 1.0f);
GL11.glColor3f(1.0f,1.0f,0.0f);
GL11.glVertex3f( 1.0f,-1.0f,-1.0f);
GL11.glVertex3f(-1.0f,-1.0f,-1.0f);
GL11.glVertex3f(-1.0f, 1.0f,-1.0f);
GL11.glVertex3f( 1.0f, 1.0f,-1.0f);
GL11.glColor3f(0.0f,0.0f,1.0f);
GL11.glVertex3f(-1.0f, 1.0f, 1.0f);
GL11.glVertex3f(-1.0f, 1.0f,-1.0f);
GL11.glVertex3f(-1.0f,-1.0f,-1.0f);
GL11.glVertex3f(-1.0f,-1.0f, 1.0f);
GL11.glColor3f(1.0f,0.0f,1.0f);
GL11.glVertex3f( 1.0f, 1.0f,-1.0f);
GL11.glVertex3f( 1.0f, 1.0f, 1.0f);
GL11.glVertex3f( 1.0f,-1.0f, 1.0f);
GL11.glVertex3f( 1.0f,-1.0f,-1.0f);
GL11.glEnd();
}
private void update() {
if (Keyboard.isKeyDown(Keyboard.KEY_UP)) {
viewx -= 0.1f*(float)Math.sin(Math.toRadians(angle));
viewy -= 0.1f*(float)Math.cos(Math.toRadians(angle));
}
if (Keyboard.isKeyDown(Keyboard.KEY_DOWN)) {
viewx += 0.1f*(float)Math.sin(Math.toRadians(angle));
viewy += 0.1f*(float)Math.cos(Math.toRadians(angle));
}
if (Keyboard.isKeyDown(Keyboard.KEY_RIGHT)) {
viewx+= 0.1f*(float)Math.sin(Math.toRadians(angle-90));
viewy+=0.1f*(float)Math.cos(Math.toRadians(angle-90));
}
if (Keyboard.isKeyDown(Keyboard.KEY_LEFT)) {
viewx+= 0.1f*(float)Math.sin(Math.toRadians(angle+90));
viewy+=0.1f*(float)Math.cos(Math.toRadians(angle+90));
}
if (Keyboard.isKeyDown(Keyboard.KEY_Q)) {
angle += 1;
}
if (Keyboard.isKeyDown(Keyboard.KEY_E)) {
angle -= 1;
}
glLoadIdentity();
glRotatef (angle, 0, 0, 1);
glTranslated(viewx, viewy, -20);
GL11.glBegin(GL11.GL_QUADS);
GL11.glColor3f(1.0f,1.0f,0.0f);
GL11.glVertex3f( -viewx-0.2f, -viewy-0.2f,0);
GL11.glVertex3f(-viewx+0.2f, -viewy-0.2f, 0);
GL11.glVertex3f(-viewx+0.2f, -viewy+0.2f, 0);
GL11.glVertex3f( -viewx-0.2f, -viewy+0.2f, 0);
glEnd();
}
}
That game appeaers to be using an orthographic projection - notice how the thing farther away from the camera are not smaller. That is why the direction of lines doesn't depend on the camera position.
The left half of this picture shows a grid of crates rendered with a perspective projection. The right half shows the same grid rendered with an orthographic projection.
Notice how, with the orthographic projection, all of the crates look identical regardless of their position, and regardless of their distance from the camera - only their orientation matters.
In the OpenGL fixed-function pipeline, you can set up an orthographic projection using glOrtho. If you are using the programmable pipeline, then it depends on your specific program; in general, you'll want to use a projection matrix in the fo
Related
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();
}
}
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.
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.
I'm trying to get a simple triangle drawn in Java using LWJGL.
I'm trying to get a simple triangle up, each with a corner of one specific color. Right now it is just giving me a blank screen.
Here is my code:
package com.ex;
import org.lwjgl.LWJGLException;
import org.lwjgl.opengl.Display;
import org.lwjgl.opengl.DisplayMode;
import org.lwjgl.opengl.GL11;
import org.lwjgl.input.Keyboard;
public class ColoredTriangle {
public void start() {
try {
Display.setDisplayMode(new DisplayMode(640, 480));
Display.create();
} catch (LWJGLException e) {
e.printStackTrace();
System.exit(0);
}
// Init OpenGL
GL11.glMatrixMode(GL11.GL_PROJECTION);
GL11.glLoadIdentity();
GL11.glOrtho(0, 640, 480, 0, 1, -1);
GL11.glMatrixMode(GL11.GL_MODELVIEW);
boolean quit = false;
while (!quit) {
// Clear the screen.
GL11.glClear(GL11.GL_COLOR_BUFFER_BIT | GL11.GL_DEPTH_BUFFER_BIT);
// Begin drawing
GL11.glBegin(GL11.GL_TRIANGLES);
// Top & Red
GL11.glColor3f(1.0f, 0.0f, 0.0f);
GL11.glVertex2f(0.0f, 1.0f);
// Right & Green
GL11.glColor3f(0.0f, 1.0f, 0.0f);
GL11.glVertex2f(1.0f, 1.0f);
// Left & Blue
GL11.glColor3f(0.0f, 0.0f, 1.0f);
GL11.glVertex2f(1.0f, -1.0f);
GL11.glEnd();
Display.update();
if (Display.isCloseRequested() || Keyboard.isKeyDown(Keyboard.KEY_ESCAPE))
quit = true;
}
Display.destroy();
}
public static void main(String args[]) {
ColoredTriangle ct = new ColoredTriangle();
ct.start();
}
}
It is working perfectly fine, it's just that your triangle is 1 unit high and your window is 480 units high, so it only shows up as one pixel in the corner.
If you replace GL11.glOrtho(0, 640, 480, 0, 1, -1); with GL11.glOrtho(-3.2, 3.2, -2.4, 2.4, -1, 1); then you'll see everything just fine.
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