How do i convert the DevIL in NEHE Lesson07 to Slick libraries? - java

I'm trying to learn how to use LWJGL libraries. Took me forever to find lessons. I eventually stumbled upon the NEHE lessons that teach OpenGL across many programming languages. I downloaded the LWJGL version of Lesson07 and noticed it was using DevIL for the images.
I asked a question on here earlier on what i should use instead of DevIL, and an informative user suggested that i go with Slick instead. I got past Lesson06 after tweaking it for a while, but now i am seriously stuck on Lesson07.
Specifically HERE:
private int[] loadTexture(String path) {
IntBuffer image = ByteBuffer.allocateDirect(4).order(ByteOrder.nativeOrder()).asIntBuffer();
IL.ilGenImages(1, image);
IL.ilBindImage(image.get(0));
IL.ilLoadImage(path);
IL.ilConvertImage(IL.IL_RGB, IL.IL_BYTE);
ByteBuffer scratch = ByteBuffer.allocateDirect(IL.ilGetInteger(IL.IL_IMAGE_WIDTH) * IL.ilGetInteger(IL.IL_IMAGE_HEIGHT) * 3);
IL.ilCopyPixels(0, 0, 0, IL.ilGetInteger(IL.IL_IMAGE_WIDTH), IL.ilGetInteger(IL.IL_IMAGE_HEIGHT), 1, IL.IL_RGB, IL.IL_BYTE, scratch);
// Create A IntBuffer For Image Address In Memory
IntBuffer buf = ByteBuffer.allocateDirect(12).order(ByteOrder.nativeOrder()).asIntBuffer();
GL11.glGenTextures(buf); // Create Texture In OpenGL
GL11.glBindTexture(GL11.GL_TEXTURE_2D, buf.get(0));
// Typical Texture Generation Using Data From The Image
// Create Nearest Filtered Texture
GL11.glBindTexture(GL11.GL_TEXTURE_2D, buf.get(0));
GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_MAG_FILTER, GL11.GL_NEAREST);
GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_MIN_FILTER, GL11.GL_NEAREST);
GL11.glTexImage2D(GL11.GL_TEXTURE_2D, 0, GL11.GL_RGB, IL.ilGetInteger(IL.IL_IMAGE_WIDTH),
IL.ilGetInteger(IL.IL_IMAGE_HEIGHT), 0, GL11.GL_RGB, GL11.GL_UNSIGNED_BYTE, scratch);
// Create Linear Filtered Texture
GL11.glBindTexture(GL11.GL_TEXTURE_2D, buf.get(1));
GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_MAG_FILTER, GL11.GL_LINEAR);
GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_MIN_FILTER, GL11.GL_LINEAR);
GL11.glTexImage2D(GL11.GL_TEXTURE_2D, 0, GL11.GL_RGB, IL.ilGetInteger(IL.IL_IMAGE_WIDTH),
IL.ilGetInteger(IL.IL_IMAGE_HEIGHT), 0, GL11.GL_RGB, GL11.GL_UNSIGNED_BYTE, scratch);
// Create MipMapped Texture
GL11.glBindTexture(GL11.GL_TEXTURE_2D, buf.get(2));
GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_MAG_FILTER, GL11.GL_LINEAR);
GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_MIN_FILTER, GL11.GL_LINEAR_MIPMAP_NEAREST);
GLU.gluBuild2DMipmaps(GL11.GL_TEXTURE_2D, 3, IL.ilGetInteger(IL.IL_IMAGE_WIDTH),
IL.ilGetInteger(IL.IL_IMAGE_HEIGHT), GL11.GL_RGB, GL11.GL_UNSIGNED_BYTE, scratch);
return new int[]{ buf.get(0), buf.get(1), buf.get(2) }; // Return Image Addresses In Memory
}
I've tried to get it working, tried substituting Slick stuff in, yet all i have tried has either crashed or led to a black screen.
What is the best way to do this with Slick?

This one was rather annoying. I think it was easier to convert than Lesson 06, but that could be because I was at least a little more used to it than I was in 06. It still took me all night to get this to work and I didn't figure it out until morning, though.
Here's my entire code. Lines are commented on the most annoying parts, along with some CODE commented to show what DIDN'T work. Any such code that was put in a comment is probably very fragmented so I'm not sure if you'll understand what I was trying to do, but I left it in anyway. The two places that I got stuck at are the two places with helpful comments and links.
package LWJGLTest2;
import java.awt.Image;
import java.awt.image.BufferedImage;
import java.awt.image.DataBufferByte;
import java.awt.image.DataBufferInt;
import static org.lwjgl.opengl.GL11.*;
import static org.lwjgl.util.glu.GLU.*;
import java.io.IOException;
import java.net.URL;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.FloatBuffer;
import java.nio.IntBuffer;
import java.util.logging.FileHandler;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.imageio.ImageIO;
import javax.swing.ImageIcon;
import org.lwjgl.BufferUtils;
import org.lwjgl.LWJGLException;
import org.lwjgl.input.Keyboard;
import org.lwjgl.input.Mouse;
import org.lwjgl.opengl.Display;
import org.lwjgl.opengl.DisplayMode;
import org.lwjgl.util.glu.GLU;
import org.newdawn.slick.opengl.Texture;
import org.newdawn.slick.opengl.TextureLoader;
import org.newdawn.slick.util.ResourceLoader;
/**
*
* #author Jay
*/
public class LWJGLTest2 {
public static final int WIDTH = 640;
public static final int HEIGHT = 480;
public static final Logger LOGGER = Logger.getLogger(LWJGLTest2.class.getName());
float xrot;
float yrot;
float xspeed;
float yspeed;
float zpos = -5f;
boolean lp;
boolean fp;
boolean light;
final float[] AMBIENT = {.5f, .5f, .5f, 1f};
final float[] DIFFUSE = {1f, 1f, 1f, 1f};
final float[] LPOSITION = {0f, 0f, 2f, 1f};
int filter;
BufferedImage textureImage;
Texture texture[] = new Texture[3];
static {
try {
LOGGER.addHandler(new FileHandler("errors.log",true));
}
catch(IOException ex) {
LOGGER.log(Level.WARNING,ex.toString(),ex);
}
}
public static void main(String[] args) {
LWJGLTest2 main = null;
try {
main = new LWJGLTest2();
main.create();
main.run();
} catch (Exception ex) {
LOGGER.log(Level.SEVERE, ex.toString(), ex);
} finally {
if (main != null) {
main.destroy();
}
}
}
public void create() throws LWJGLException {
// Display
Display.setDisplayMode(new DisplayMode(WIDTH, HEIGHT));
Display.setFullscreen(false);
Display.setTitle("LWJGL Test");
Display.create();
// Keyboard
Keyboard.create();
// Mouse
Mouse.setGrabbed(false);
Mouse.create();
// OpenGL
initGL();
resizeGL();
}
public void destroy() {
Mouse.destroy();
Keyboard.destroy();
Display.destroy();
}
public void initGL() {
try {
loadTextures();
} catch (IOException ex) {
System.err.println(ex); System.exit(0);
}
glEnable(GL_TEXTURE_2D);
glShadeModel(GL_SMOOTH);
glClearColor(0f, 0f, 0f, 0.5f);
glClearDepth(1f);
glEnable(GL_DEPTH_TEST);
glDepthFunc(GL_LEQUAL);
glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
//FloatBuffer scratch = BufferUtils.createFloatBuffer(8); // 4 for the values and 4 for the extra buffer
//scratch.put(AMBIENT);
ByteBuffer scratch = ByteBuffer.allocateDirect(16);
scratch.order(ByteOrder.nativeOrder());
//scratch.put(AMBIENT);
glLight(GL_LIGHT1, GL_AMBIENT, (FloatBuffer)scratch.asFloatBuffer().put(AMBIENT).flip()); // 3rd argument used to be only scratch
//scratch = ByteBuffer.allocateDirect(32).asFloatBuffer(); // reset the buffer to prevent an overflow
//scratch.put(DIFFUSE);
glLight(GL_LIGHT1, GL_DIFFUSE, (FloatBuffer)scratch.asFloatBuffer().put(AMBIENT).flip());
//scratch = ByteBuffer.allocateDirect(32).asFloatBuffer();
//scratch.put(LPOSITION);
glLight(GL_LIGHT1, GL_POSITION, (FloatBuffer)scratch.asFloatBuffer().put(AMBIENT).flip());
glEnable(GL_LIGHT1);
}
public void resizeGL() {
glViewport(0, 0, WIDTH, HEIGHT);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(45f, (float)WIDTH/(float)HEIGHT, 0.1f, 100f);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
}
public void run() {
while (!Display.isCloseRequested() && !Keyboard.isKeyDown(Keyboard.KEY_ESCAPE)) {
if (Display.isVisible()) {
checkInput();
render();
Display.update();
}
}
}
public void checkInput() {
if (Keyboard.isKeyDown(Keyboard.KEY_L) && !lp) {
lp = true;
light = !light;
if (light)
glEnable(GL_LIGHTING);
else
glDisable(GL_LIGHTING);
}
if (!Keyboard.isKeyDown(Keyboard.KEY_L))
lp = false;
if (Keyboard.isKeyDown(Keyboard.KEY_F) && !fp) {
fp = true;
filter = (filter + 1) % 3;
}
if (!Keyboard.isKeyDown(Keyboard.KEY_F))
fp = false;
if (Keyboard.isKeyDown(Keyboard.KEY_PRIOR))
zpos -= 0.02f;
if (Keyboard.isKeyDown(Keyboard.KEY_NEXT))
zpos += 0.02f;
if (Keyboard.isKeyDown(Keyboard.KEY_UP))
xspeed -= 0.001f;
if (Keyboard.isKeyDown(Keyboard.KEY_DOWN))
xspeed += 0.001f;
if (Keyboard.isKeyDown(Keyboard.KEY_RIGHT))
yspeed -= 0.001f;
if (Keyboard.isKeyDown(Keyboard.KEY_LEFT))
yspeed += 0.001f;
}
public void render() {
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glLoadIdentity();
glTranslatef(0f, 0f, zpos);
glRotatef(xrot, 1f, 0f, 0f);
glRotatef(yrot, 0f, 1f, 0f);
texture[filter].bind();
glBegin(GL_QUADS);
// Front Face
glNormal3f(0f, 0f, 1f);
glTexCoord2f(0.0f, 0.0f); glVertex3f(-1.0f, -1.0f, 1.0f); // Bottom Left Of The Texture and Quad
glTexCoord2f(1.0f, 0.0f); glVertex3f( 1.0f, -1.0f, 1.0f); // Bottom Right Of The Texture and Quad
glTexCoord2f(1.0f, 1.0f); glVertex3f( 1.0f, 1.0f, 1.0f); // Top Right Of The Texture and Quad
glTexCoord2f(0.0f, 1.0f); glVertex3f(-1.0f, 1.0f, 1.0f); // Top Left Of The Texture and Quad
// Back Face
glNormal3f(0f, 0f, -1f);
glTexCoord2f(1.0f, 0.0f); glVertex3f(-1.0f, -1.0f, -1.0f); // Bottom Right Of The Texture and Quad
glTexCoord2f(1.0f, 1.0f); glVertex3f(-1.0f, 1.0f, -1.0f); // Top Right Of The Texture and Quad
glTexCoord2f(0.0f, 1.0f); glVertex3f( 1.0f, 1.0f, -1.0f); // Top Left Of The Texture and Quad
glTexCoord2f(0.0f, 0.0f); glVertex3f( 1.0f, -1.0f, -1.0f); // Bottom Left Of The Texture and Quad
// Top Face
glNormal3f(0f, 1f, 0f);
glTexCoord2f(0.0f, 1.0f); glVertex3f(-1.0f, 1.0f, -1.0f); // Top Left Of The Texture and Quad
glTexCoord2f(0.0f, 0.0f); glVertex3f(-1.0f, 1.0f, 1.0f); // Bottom Left Of The Texture and Quad
glTexCoord2f(1.0f, 0.0f); glVertex3f( 1.0f, 1.0f, 1.0f); // Bottom Right Of The Texture and Quad
glTexCoord2f(1.0f, 1.0f); glVertex3f( 1.0f, 1.0f, -1.0f); // Top Right Of The Texture and Quad
// Bottom Face
glNormal3f(0f, -1f, 0f);
glTexCoord2f(1.0f, 1.0f); glVertex3f(-1.0f, -1.0f, -1.0f); // Top Right Of The Texture and Quad
glTexCoord2f(0.0f, 1.0f); glVertex3f( 1.0f, -1.0f, -1.0f); // Top Left Of The Texture and Quad
glTexCoord2f(0.0f, 0.0f); glVertex3f( 1.0f, -1.0f, 1.0f); // Bottom Left Of The Texture and Quad
glTexCoord2f(1.0f, 0.0f); glVertex3f(-1.0f, -1.0f, 1.0f); // Bottom Right Of The Texture and Quad
// Right face
glNormal3f(1f, 0f, 0f);
glTexCoord2f(1.0f, 0.0f); glVertex3f( 1.0f, -1.0f, -1.0f); // Bottom Right Of The Texture and Quad
glTexCoord2f(1.0f, 1.0f); glVertex3f( 1.0f, 1.0f, -1.0f); // Top Right Of The Texture and Quad
glTexCoord2f(0.0f, 1.0f); glVertex3f( 1.0f, 1.0f, 1.0f); // Top Left Of The Texture and Quad
glTexCoord2f(0.0f, 0.0f); glVertex3f( 1.0f, -1.0f, 1.0f); // Bottom Left Of The Texture and Quad
// Left Face
glNormal3f(-1f, 0f, 0f);
glTexCoord2f(0.0f, 0.0f); glVertex3f(-1.0f, -1.0f, -1.0f); // Bottom Left Of The Texture and Quad
glTexCoord2f(1.0f, 0.0f); glVertex3f(-1.0f, -1.0f, 1.0f); // Bottom Right Of The Texture and Quad
glTexCoord2f(1.0f, 1.0f); glVertex3f(-1.0f, 1.0f, 1.0f); // Top Right Of The Texture and Quad
glTexCoord2f(0.0f, 1.0f); glVertex3f(-1.0f, 1.0f, -1.0f); // Top Left Of The Texture and Quad
glEnd();
xrot += xspeed;
yrot += yspeed;
}
public void loadTextures() throws IOException {
//textureImage = ImageIO.read(this.getClass().getResourceAsStream("Crate.png"));
texture[0] = TextureLoader.getTexture("BMP", this.getClass().getResourceAsStream("Crate.bmp"), true, GL_NEAREST);
texture[1] = TextureLoader.getTexture("BMP", this.getClass().getResourceAsStream("Crate.bmp"), true, GL_LINEAR);
texture[2] = TextureLoader.getTexture("BMP", this.getClass().getResourceAsStream("Crate.bmp"), true);
//ByteBuffer scratch = ByteBuffer.wrap(((DataBufferByte)textureImage.getRaster().getDataBuffer()).getData());
//ByteBuffer scratch = ByteBuffer.allocateDirect(((DataBufferByte)textureImage.getRaster().getDataBuffer()).getData().length + 3);
/*
* The +3 in the last statement is important! Without it, you get this:
* SEVERE: java.lang.IllegalArgumentException: Number of remaining buffer
* elements is 0, must be at least 3. Because at most 3 elements can be
* returned, a buffer with at least 3 elements is required, regardless of
* actual returned element count
*/
//scratch.put(((DataBufferByte)textureImage.getRaster().getDataBuffer()).getData()); // RED
//scratch.rewind(); // NOW IT'S RED.
//for (int i = 0; i < scratch.limit(); ++i)
// System.out.println(scratch);
texture[2].bind();
//ByteBuffer scratch = ByteBuffer.allocateDirect(texture[2].getTextureData().length);
//scratch.order(ByteOrder.nativeOrder());
//glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
//glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST);
//GLU.gluBuild2DMipmaps(GL_TEXTURE_2D, 3, (int)texture[2].getWidth(), (int)texture[2].getHeight(), GL_RGB, GL_UNSIGNED_BYTE, (ByteBuffer)scratch.put(texture[2].getTextureData()).flip());
org.lwjgl.opengl.GL30.glGenerateMipmap(GL_TEXTURE_2D); /* http://slick.javaunlimited.net/viewtopic.php?t=2755
* Not sure if this worked properly, but I rather enjoy
* not crying so I'll just smile and nod.
* I went through a LOT of other options before I got this.
* I also tried using the trick I found at
* http://lwjgl.org/forum/index.php?action=printpage;topic=2233.0
* (used above, in initGL) but that didn't work either.
*/
}
}
This code has been run and FINALLY works. Using Slick-Util compresses it a LOT. You'll also notice that I changed the rate of change for the speeds; 0.01f was way too fast, so I put it to 0.001f instead. Hope this helps!
Links from my source code:
"Mipmapping"
"Why is adding of the light in lwjgl so difficult?"

You'll probably need to adapt the code to use the standard LWJGL image / texture loading features, at least up to the point of the glBindTexture() call. After that point I think you should be OK, it's all pretty standard OpenGL from that point.
There is some pretty decent example code here that demonstrates what you need to do:
http://lwjgl.org/wiki/index.php?title=Slick-Util_Library_-_Part_1_-_Loading_Images_for_LWJGL
I think the key lines of code you need are:
import org.newdawn.slick.opengl.Texture;
import org.newdawn.slick.opengl.TextureLoader;
...
Texture texture = TextureLoader.getTexture("PNG", ResourceLoader.getResourceAsStream("res/image.png"));
...
GL11.glBind(texture.getTextureID());
In other words, I think it's actually a bit simpler than using DevIL.

Related

OpenGL ES - Too much work on main thread

I'm trying to render a 3D cube with different textures on each face (a dice), it works flawlessly when I only render the cube with one of the same image, but the cube doesn't even display and the following is thrown in the android monitor when I try to do the former:
Skipped 36 frames! The application may be doing too much work on its main thread.
After some research I'm aware that I could run this "heavy processing" in its own thread but I'm lost as to how to go about it. I'm relatively new to OpenGL rendering so I don't know whether my code is super optimal either.
I'm thinking I should run the Dice3D.java in another thread? This is the only class that doesn't extend or implement anything and through a little research I have found the class needs to implement runnable?
Any help in making this work would be great, thanks in advance!
Here are my classes:
OpenGLRenderer.java
public class OpenGLRenderer implements GLSurfaceView.Renderer {
private Context context;
private Dice3D dice3D;
public OpenGLRenderer(Context context, FrameLayout openGLLayout) {
this.context = context;
dice3D = new Dice3D(context);
GLSurfaceView glView = new GLSurfaceView(context);
glView.setRenderer(this);
//put to welcome layout
openGLLayout.addView(glView, new FrameLayout.LayoutParams(FrameLayout.LayoutParams.MATCH_PARENT, FrameLayout.LayoutParams.MATCH_PARENT));
}
private float mCubeRotation;
#Override
public void onSurfaceCreated(GL10 gl, EGLConfig config) {
gl.glClearColor(1.0f, 1.0f, 1.0f, 1.0f); // Set color's clear-value to black
gl.glClearDepthf(1.0f); // Set depth's clear-value to farthest
gl.glEnable(GL10.GL_DEPTH_TEST); // Enables depth-buffer for hidden surface removal
gl.glDepthFunc(GL10.GL_LEQUAL); // The type of depth testing to do
gl.glHint(GL10.GL_PERSPECTIVE_CORRECTION_HINT, GL10.GL_NICEST); // nice perspective view
gl.glShadeModel(GL10.GL_SMOOTH); // Enable smooth shading of color
gl.glDisable(GL10.GL_DITHER); // Disable dithering for better performance
// Setup Texture, each time the surface is created (NEW)
dice3D.loadTexture(gl); // Load images into textures (NEW)
gl.glEnable(GL10.GL_TEXTURE_2D); // Enable texture (NEW)
}
#Override
public void onDrawFrame(GL10 gl) {
gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT);
gl.glLoadIdentity();
gl.glTranslatef(0.0f, 0.0f, -6.0f);
gl.glRotatef(mCubeRotation, 1.0f, 1.0f, 1.0f);
dice3D.draw(gl);
mCubeRotation -= 0.15f;
}
#Override
public void onSurfaceChanged(GL10 gl, int width, int height) {
gl.glViewport(0, 0, width, height);
gl.glMatrixMode(GL10.GL_PROJECTION);
gl.glLoadIdentity();
GLU.gluPerspective(gl, 45.0f, (float)width / (float)height, 0.1f, 100.0f);
gl.glViewport(0, 0, width, height);
gl.glMatrixMode(GL10.GL_MODELVIEW);
gl.glLoadIdentity();
}
}
Dice3D.java
public class Dice3D {
private FloatBuffer vertexBuffer; // Buffer for vertex-array
private FloatBuffer texBuffer; // Buffer for texture-coords-array (NEW)
private int numFaces = 6;
private int[] imageFileIDs = { // Image file IDs
R.drawable.one,
R.drawable.two,
R.drawable.three,
R.drawable.four,
R.drawable.five,
R.drawable.six
};
private int[] textureIDs = new int[numFaces];
private Bitmap[] bitmap = new Bitmap[numFaces];
// Constructor - Set up the buffers
public Dice3D(Context context) {
// Setup vertex-array buffer. Vertices in float. An float has 4 bytes
ByteBuffer vbb = ByteBuffer.allocateDirect(12 * 4 * numFaces);
vbb.order(ByteOrder.nativeOrder()); // Use native byte order
vertexBuffer = vbb.asFloatBuffer(); // Convert from byte to float
for (int face = 0; face < numFaces; face++) {
bitmap[face] = BitmapFactory.decodeStream(context.getResources().openRawResource(imageFileIDs[face]));
float[] vertices = { // Vertices for a face
-1.0f, -1.0f, 0.0f, // 0. left-bottom-front
1.0f, -1.0f, 0.0f, // 1. right-bottom-front
-1.0f, 1.0f, 0.0f, // 2. left-top-front
1.0f, 1.0f, 0.0f // 3. right-top-front
};
vertexBuffer.put(vertices); // Populate
}
vertexBuffer.position(0); // Rewind
float[] texCoords = { // Texture coords for the above face (NEW)
0.0f, 1.0f, // A. left-bottom (NEW)
1.0f, 1.0f, // B. right-bottom (NEW)
0.0f, 0.0f, // C. left-top (NEW)
1.0f, 0.0f // D. right-top (NEW)
};
// Setup texture-coords-array buffer, in float. An float has 4 bytes (NEW)
ByteBuffer tbb = ByteBuffer.allocateDirect(texCoords.length * 4 * numFaces);
tbb.order(ByteOrder.nativeOrder());
texBuffer = tbb.asFloatBuffer();
for (int face = 0; face < numFaces; face++) {
texBuffer.put(texCoords);
}
texBuffer.position(0);
}
// Draw the shape
public void draw(GL10 gl) {
gl.glFrontFace(GL10.GL_CCW); // Front face in counter-clockwise orientation
gl.glEnable(GL10.GL_CULL_FACE); // Enable cull face
gl.glCullFace(GL10.GL_BACK); // Cull the back face (don't display)
gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
gl.glVertexPointer(3, GL10.GL_FLOAT, 0, vertexBuffer);
gl.glEnableClientState(GL10.GL_TEXTURE_COORD_ARRAY); // Enable texture-coords-array (NEW)
gl.glTexCoordPointer(2, GL10.GL_FLOAT, 0, texBuffer); // Define texture-coords buffer (NEW)
// front
gl.glPushMatrix();
gl.glTranslatef(0.0f, 0.0f, 1.0f);
gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP, 0, 4);
gl.glPopMatrix();
// left
gl.glPushMatrix();
gl.glRotatef(270.0f, 0.0f, 1.0f, 0.0f);
gl.glTranslatef(0.0f, 0.0f, 1.0f);
gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP, 0, 4);
gl.glPopMatrix();
// back
gl.glPushMatrix();
gl.glRotatef(180.0f, 0.0f, 1.0f, 0.0f);
gl.glTranslatef(0.0f, 0.0f, 1.0f);
gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP, 0, 4);
gl.glPopMatrix();
// right
gl.glPushMatrix();
gl.glRotatef(90.0f, 0.0f, 1.0f, 0.0f);
gl.glTranslatef(0.0f, 0.0f, 1.0f);
gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP, 0, 4);
gl.glPopMatrix();
// top
gl.glPushMatrix();
gl.glRotatef(270.0f, 1.0f, 0.0f, 0.0f);
gl.glTranslatef(0.0f, 0.0f, 1.0f);
gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP, 0, 4);
gl.glPopMatrix();
// bottom
gl.glPushMatrix();
gl.glRotatef(90.0f, 1.0f, 0.0f, 0.0f);
gl.glTranslatef(0.0f, 0.0f, 1.0f);
gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP, 0, 4);
gl.glPopMatrix();
gl.glDisableClientState(GL10.GL_TEXTURE_COORD_ARRAY); // Disable texture-coords-array
gl.glDisableClientState(GL10.GL_VERTEX_ARRAY);
gl.glDisable(GL10.GL_CULL_FACE);
}
// Load an image into GL texture
public void loadTexture(GL10 gl) {
gl.glGenTextures(6, textureIDs, 0); // Generate texture-ID array for 6 IDs
// Generate OpenGL texture images
for (int face = 0; face < numFaces; face++) {
gl.glBindTexture(GL10.GL_TEXTURE_2D, textureIDs[face]);
// Build Texture from loaded bitmap for the currently-bind texture ID
GLUtils.texImage2D(GL10.GL_TEXTURE_2D, 0, bitmap[face], 0);
bitmap[face].recycle();
}
}
}
and finally my activity Welcome.java
public class Welcome extends AppCompatActivity {
LinearLayout l1,l2;
public Button btnsub;
Animation uptodown,downtoup;
#Override
protected void onCreate(Bundle savedInstanceState) {
requestWindowFeature(Window.FEATURE_NO_TITLE);
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_welcome);
FrameLayout openGLLayout = (FrameLayout) findViewById(R.id.frameLayout1);
//creates an openGL surface and renders it to the framelayout in the activity layout
OpenGLRenderer gl3DView = new OpenGLRenderer(this, openGLLayout);
btnsub = (Button)findViewById(R.id.buttonsub);
btnsub.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent test = new Intent(Welcome.this,DiceGame.class);
startActivity(test);
}
});
l1 = (LinearLayout) findViewById(R.id.l1);
l2 = (LinearLayout) findViewById(R.id.l2);
uptodown = AnimationUtils.loadAnimation(this,R.anim.uptodown);
downtoup = AnimationUtils.loadAnimation(this,R.anim.downtoup);
l1.setAnimation(uptodown);
l2.setAnimation(downtoup);
}
}
In terms of performance:
1) Learn OpenGL ES 2.0 and use shaders; it's a much cleaner API with a lot less messing about needed in the application and/or in the driver stack. All of the new APIs are shader-based, so this is a good thing to learn. I wouldn't consider using OpenGL ES 1.x for any new projects as it's a dead-end from a technology point of view.
(2) Once using OpenGL ES 2.0 or newer the use buffer objects for storing vertex data, and upload the data at the start of the application, nor per frame. It shouldn't really matter in this case (cube is very simple), but it's a good habit to get in to.

OpenGL lwjgl won't draw polygon

I was doing and creating a triangle in the lwjgl openGL but it doesnt display the square and the triangle that I specify. I am stuck and I cant seemingly make it work, I am new to openGL lwjgl. why is it not drawing on the screen?
public Cube3D() {
try {
Display.setDisplayMode(new DisplayMode(640,480));
Display.setTitle("Gaming");
Display.create();
} catch (LWJGLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
//initiallized code OPENGL
glShadeModel(GL_SMOOTH);
glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
glClearDepth(1.0);
glEnable(GL_DEPTH_TEST);
glDepthFunc(GL_LEQUAL);
glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
glViewport(0, 0, 640, 480);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
while(!Display.isCloseRequested()) { //Reset The View
glTranslatef(-1.5f,0.0f,-8.0f); // Move Left 1.5 Units And Into
// The Screen 8 (not 6.0 like
// VC../ not sure why)
glBegin(GL_TRIANGLES); // Drawing Using Triangles
glVertex3f( 0.0f, 1.0f, 0.0f); // Top
glVertex3f(-1.0f,-1.0f, 0.0f); // Bottom Left
glVertex3f( 1.0f,-1.0f, 0.0f); // Bottom Right
glEnd(); // Finished Drawing The Triangle
glTranslatef(3.0f,0.0f,0.0f); // Move Right 3 Units
glBegin(GL_QUADS); // Draw A Quad
glVertex3f(-1.0f, 1.0f, 0.0f); // Top Left
glVertex3f( 1.0f, 1.0f, 0.0f); // Top Right
glVertex3f( 1.0f,-1.0f, 0.0f); // Bottom Right
glVertex3f(-1.0f,-1.0f, 0.0f); // Bottom Left
glEnd();
Display.update();
Display.sync(60);
}
Display.destroy();
}
}
It took a little bit of time but I manage to find the problem. The first is how you initialize the opengl.
Replace:
glShadeModel(GL_SMOOTH);
glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
glClearDepth(1.0);
glEnable(GL_DEPTH_TEST);
glDepthFunc(GL_LEQUAL);
glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
glViewport(0, 0, 640, 480);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
with:
glMatrixMode(GL11.GL_PROJECTION);
glLoadIdentity();
GLU.gluPerspective(45.0f, ((float) 800) / ((float) 600), 0.1f, 100.0f);
glMatrixMode(GL11.GL_MODELVIEW);
glLoadIdentity();
glEnable(GL11.GL_DEPTH_TEST);
replacing 800 with the width of the window and 600 with the height should you change the resolution.
and in your while loop put these two lines at the beginning:
GL11.glClear(GL11.GL_COLOR_BUFFER_BIT | GL11.GL_DEPTH_BUFFER_BIT);
glLoadIdentity();

LWJGL Texture blending not working

I'm trying to draw a gradient and then draw a transparent texture ontop of it.
This is the code I'm using right now:
GL11.glClearColor(0.0F, 0.0F, 0.0F, 0.0F);
// Draw the gradient
GL11.glBegin(GL11.GL_QUADS);
GL11.glTexCoord2f(0.0f, 0.0f);
GL11.glColor4f(1F, 1F, 1F, 0F);
GL11.glVertex3f(0, 0, 0.0f);
GL11.glTexCoord2f(1.0f, 0.0f);
GL11.glColor4f(0F, 1F, 1F, 0F);
GL11.glVertex3f(0 + gameWidth, 0, 0.0f);
GL11.glTexCoord2f(1.0f, 1.0f);
GL11.glColor4f(0F, 0F, 1F, 0F);
GL11.glVertex3f(0 + gameWidth, 0 + gameHeight, 0.0f);
GL11.glTexCoord2f(0.0f, 1.0f);
GL11.glColor4f(1F, 0F, 1F, 0F);
GL11.glVertex3f(0, 0 + gameHeight, 0.0f);
GL11.glEnd();
GL11.glColor4f(1F, 1F, 1F, 0F);
GL11.glEnable(GL11.GL_BLEND);
GL11.glBlendFunc(GL11.GL_ONE, GL11.GL_ONE_MINUS_SRC_ALPHA);
TexLoader.loadTex("/example.png"); // Loads and binds the texture, also enables GL_TEXTURE_2D
GL11.glBegin(GL11.GL_QUADS);
GL11.glTexCoord2f(0.0f, 0.0f);
GL11.glVertex3f(parX, parY, 0.0f);
GL11.glTexCoord2f(1.0f, 0.0f);
GL11.glVertex3f(parX + parWidth, parY, 0.0f);
GL11.glTexCoord2f(1.0f, 1.0f);
GL11.glVertex3f(parX + parWidth, parY + parHeight, 0.0f);
GL11.glTexCoord2f(0.0f, 1.0f);
GL11.glVertex3f(parX, parY + parHeight, 0.0f);
GL11.glEnd();
GL11.glDisable(GL11.GL_TEXTURE_2D);
GL11.glDisable(GL11.GL_BLEND);
However, instead of drawing the texture and hiding the transparent pixels it just draws a white quad.
What am I doing wrong?

Why is my cube failing to draw properly in LWJGL/OpenGL?

I believe it has something to do with draw order, but I've just given up at this point.
Basically, the Quads are drawing, but they're not in the right order, and backface culling is enabled but doesn't help.
import java.awt.Color;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.nio.DoubleBuffer;
import javax.imageio.ImageIO;
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 org.lwjgl.util.glu.GLU;
public class Main {
public Main() {
this.start();
}
private void start() {
try {
Display.setDisplayMode(new DisplayMode(640,640));
Display.setTitle("FPSTest");
Display.create();
} catch (LWJGLException e) {
e.printStackTrace();
}
GL11.glMatrixMode(GL11.GL_PROJECTION);
GL11.glLoadIdentity();
GL11.glOrtho(-5, 5, -5, 5, -1, 5);
GL11.glMatrixMode(GL11.GL_MODELVIEW);
int x=0;
while (!Display.isCloseRequested()) {
Display.sync(60);
//poll for keypresses first, default key is 'forward'
//if(Keyboard.isKeyDown(Keyboard.KEY_NUMPAD8));
GL11.glClear(GL11.GL_DEPTH_BUFFER_BIT|GL11.GL_COLOR_BUFFER_BIT);
GL11.glEnable(GL11.GL_CULL_FACE|GL11.GL_DEPTH_TEST);
GL11.glColor3f(1, 0, 0);
GL11.glRotatef(x++, 1, 1, 1);
GL11.glBegin(GL11.GL_QUADS);
GL11.glColor3f(0.0f,1.0f,0.0f); // Set The Color To Green
GL11.glVertex3f( 1.0f, 1.0f,-1.0f); // Top Right Of The Quad (Top)
GL11.glVertex3f(-1.0f, 1.0f,-1.0f); // Top Left Of The Quad (Top)
GL11.glVertex3f(-1.0f, 1.0f, 1.0f); // Bottom Left Of The Quad (Top)
GL11.glVertex3f( 1.0f, 1.0f, 1.0f); // Bottom Right Of The Quad (Top)
GL11.glColor3f(1.0f,0.5f,0.0f); // Set The Color To Orange
GL11.glVertex3f( 1.0f,-1.0f, 1.0f); // Top Right Of The Quad (Bottom)
GL11.glVertex3f(-1.0f,-1.0f, 1.0f); // Top Left Of The Quad (Bottom)
GL11.glVertex3f(-1.0f,-1.0f,-1.0f); // Bottom Left Of The Quad (Bottom)
GL11.glVertex3f( 1.0f,-1.0f,-1.0f); // Bottom Right Of The Quad (Bottom)
GL11.glColor3f(1.0f,0.0f,0.0f); // Set The Color To Red
GL11.glVertex3f( 1.0f, 1.0f, 1.0f); // Top Right Of The Quad (Front)
GL11.glVertex3f(-1.0f, 1.0f, 1.0f); // Top Left Of The Quad (Front)
GL11.glVertex3f(-1.0f,-1.0f, 1.0f); // Bottom Left Of The Quad (Front)
GL11.glVertex3f( 1.0f,-1.0f, 1.0f); // Bottom Right Of The Quad (Front)
GL11.glColor3f(1.0f,1.0f,0.0f); // Set The Color To Yellow
GL11.glVertex3f( 1.0f,-1.0f,-1.0f); // Bottom Left Of The Quad (Back)
GL11.glVertex3f(-1.0f,-1.0f,-1.0f); // Bottom Right Of The Quad (Back)
GL11.glVertex3f(-1.0f, 1.0f,-1.0f); // Top Right Of The Quad (Back)
GL11.glVertex3f( 1.0f, 1.0f,-1.0f); // Top Left Of The Quad (Back)
GL11.glColor3f(0.0f,0.0f,1.0f); // Set The Color To Blue
GL11.glVertex3f(-1.0f, 1.0f, 1.0f); // Top Right Of The Quad (Left)
GL11.glVertex3f(-1.0f, 1.0f,-1.0f); // Top Left Of The Quad (Left)
GL11.glVertex3f(-1.0f,-1.0f,-1.0f); // Bottom Left Of The Quad (Left)
GL11.glVertex3f(-1.0f,-1.0f, 1.0f); // Bottom Right Of The Quad (Left)
GL11.glColor3f(1.0f,0.0f,1.0f); // Set The Color To Violet
GL11.glVertex3f( 1.0f, 1.0f,-1.0f); // Top Right Of The Quad (Right)
GL11.glVertex3f( 1.0f, 1.0f, 1.0f); // Top Left Of The Quad (Right)
GL11.glVertex3f( 1.0f,-1.0f, 1.0f); // Bottom Left Of The Quad (Right)
GL11.glVertex3f( 1.0f,-1.0f,-1.0f); // Bottom Right Of The Quad (Right)
GL11.glEnd();
GL11.glLoadIdentity();
Display.update();
}
Display.destroy();
}
public static void main(String[] argv) {
new Main();
}
}
GL11.glEnable(GL11.GL_CULL_FACE|GL11.GL_DEPTH_TEST);
You can't do this. You have to give each glEnable as a separate command. Try this instead and see if it helps you.
GL11.glEnable(GL11.GL_CULL_FACE);
GL11.glEnable(GL11.GL_DEPTH_TEST);
Also use glGetError!

What am I doing wrong in my drawing of a Quad in LWJGL?

If I switch GL_QUADS to GL_TRIANGLES and remove the last point, the triangle renders fine.
However, changing it back to GL_QUADS and adding another point just leaves me with a black screen. So what do I do?
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;
public class Main {
public Main() {
this.start();
}
private void start() {
try {
Display.setDisplayMode(new DisplayMode(640,640));
Display.setTitle("FPSTest");
Display.create();
} catch (LWJGLException e) {
e.printStackTrace();
}
GL11.glMatrixMode(GL11.GL_PROJECTION);
GL11.glLoadIdentity();
GL11.glOrtho(-10, 10, -10, 10, -1000, 1000);
GL11.glMatrixMode(GL11.GL_MODELVIEW);
while (!Display.isCloseRequested()) {
GL11.glClear(GL11.GL_DEPTH_BUFFER_BIT|GL11.GL_COLOR_BUFFER_BIT);
GL11.glRotatef(0, 1, 1, 1);
GL11.glBegin(GL11.GL_QUADS);
// GL11.glBegin(GL11.GL_TRIANGLES);
{
GL11.glColor3f(1.0f, 0.0f, 0.0f);
GL11.glVertex3f(0.0f, 3.0f, 0.0f);
GL11.glColor3f(0.0f, 1.0f, 0.0f);
GL11.glVertex3f(0.0f, 0.0f, -3.0f);
GL11.glColor3f(0.0f, 0.0f, 1.0f);
GL11.glVertex3f(3.0f, 0.0f, 0.0f);
GL11.glColor3f(0.0f, 1.0f, 0.0f);
GL11.glVertex3f(0.0f, 0.0f, 3.0f);
}
GL11.glEnd();
GL11.glLoadIdentity();
Display.update();
}
Display.destroy();
}
public static void main(String[] argv) {
new Main();
}
}
As mgibsonbr mentioned, the vertices are non-coplanar. He posted a nice tool to help you as well.
This may also help you.
If four vertices, with components; 1 <= n <= 4 are coplanar then the determinant of the matrix:
|x1 y1 z1 1|
|x2 y2 z2 1|
|x3 y3 z3 1|
|x4 y4 z4 1|
will be 0.
The vertices of a quad must be coplanar. The four vertices you specified are not, and according to this, the results are undefined in this case (which is probably the reason for the blank screen).
Here's a tool to help you find the plane equation, so you can choose a coplanar 4th point. Your first 3 points form the equation -9x -9y +9z + 27 = 0, so one example of a suitable point is:
GL11.glVertex3f(2.0f, 2.0f, 1.0f);
You can also use glBegin(GL_TRIANGLE_STRIP), all triangles are coplanar ;)

Categories

Resources