Hi folks.
I'm new to lwjgl as well as to opengl. Currently I'm trying to create cube with quads but it seems like the different side of the cube don't really know weather they are before or behind another. Here is the code:
import org.lwjgl.opengl.DisplayMode;
import org.lwjgl.opengl.GL11;
import org.lwjgl.opengl.PixelFormat;
import org.lwjgl.opengl.Display;
import org.lwjgl.opengl.glu.*;
public class MyTest implements Runnable {
private boolean exitApplication = false;
public static void main(String[] args) {
MyTest game = new MyTest();
try {
game.init(800, 600);
game.run();
new Thread(game).start();
} catch(Exception ex) {
ex.printStackTrace();
}
}
private void init(int width, int height) throws Exception {
DisplayMode[] modes = Display.getAvailableDisplayModes();
if (modes.length == 0) {
throw new Exception("Can't find any display modes.");
}
DisplayMode chosenDisplay = modes[0];
for (int i=0; i<modes.length; i++) {
if ((modes[i].getWidth() == width) && (modes[i].getHeight() == height) && (modes[i].getBitsPerPixel() == 16)) {
chosenDisplay = modes[i];
break;
}
}
Display.setDisplayMode(chosenDisplay);
Display.setTitle("My OpenGL Test");
Display.create(new PixelFormat(0, 8, 0));
GL11.glMatrixMode(GL11.GL_PROJECTION);
}
public void run() {
try {
while (!exitApplication) {
if (!Display.isVisible()) {
Thread.sleep(200);
} else if (Display.isCloseRequested()) {
exitApplication = true;
} else {
render();
}
Display.update();
}
} catch (Throwable t) {
t.printStackTrace();
} finally {
Display.destroy();
}
}
private void render() {
GL11.glLoadIdentity();
GL11.glClearColor(0f, 0f, 0f, 0f);
GL11.glClear(GL11.GL_COLOR_BUFFER_BIT);
GLU.gluLookAt(0.5f, 0.5f, 0.5f, 0, 0, 0, 0, 1, 0);
cube();
GL11.glFlush();
}
private void cube() {
GL11.glBegin(GL11.GL_QUADS);
//1
GL11.glColor3f(1f, 0f, 0f);
GL11.glVertex3f(0, 0, 0);
GL11.glVertex3f(0.5f, 0, 0);
GL11.glVertex3f(0.5f, 0.5f, 0);
GL11.glVertex3f(0, 0.5f, 0);
//2
GL11.glColor3f(0f, 0f, 1);
GL11.glVertex3f(0, 0, 0.5f);
GL11.glVertex3f(0, 0.5f, 0.5f);
GL11.glVertex3f(0.5f, 0.5f, 0.5f);
GL11.glVertex3f(0.5f, 0, 0.5f);
//3
GL11.glColor3f(0, 1, 0);
GL11.glVertex3f(0.5f, 0.5f, 0);
GL11.glVertex3f(0.5f, 0f, 0f);
GL11.glVertex3f(0.5f, 0, 0.5f);
GL11.glVertex3f(0.5f, 0.5f, 0.5f);
//4
GL11.glColor3f(1, 0, 1);
GL11.glVertex3f(0, 0.5f, 0.5f);
GL11.glVertex3f(0, 0f, 0.5f);
GL11.glVertex3f(0, 0, 0);
GL11.glVertex3f(0, 0.5f, 0);
GL11.glEnd();
}
}
Can somebody help me?
you need to enable depth testing to set a sort method
doing something like this at initiation might help
GL11.glClearDepth(1.0f); // Depth Buffer Setup
GL11.glEnable(GL11.GL_DEPTH_TEST); // Enables Depth Testing
GL11.glDepthFunc(GL11.GL_LEQUAL); // The Type Of Depth Testing To Do
if you're new to opengl, this site might help you alot: http://nehe.gamedev.net/ (http://nehe.gamedev.net/). Enjoy!
Hi, thx for your answers.
The NeHe Tutorials seem not to cover this. I'd suggest this to appear in chapter 5 "3D Shapes" but it doesnt. After chapter 5 they continue with texture mapping.
Your 3 commmands dont really help javalwjgl, I added them after "GL11.glMatrixMode(GL11.GL_PROJECTION);" in #init(). My shapes first appeared in hundreds of dots because I forgot to clear GL_DEPTH_BUFFER_BIT. Now that I clear it, there seems to be no difference.
Hi, yes i searched NeHe but they indeed don't tell you anything about it.. To help you out, i compiled your code, i changed it a bit: adding the code suggested by javalwjgl and putting some things at different places. It's the best place for those commands (I think ::) ). It shows up nicely now.
import org.lwjgl.opengl.DisplayMode;
import org.lwjgl.opengl.GL11;
import org.lwjgl.opengl.PixelFormat;
import org.lwjgl.opengl.Display;
import org.lwjgl.opengl.glu.*;
public class MyTest implements Runnable {
private boolean exitApplication = false;
public static void main(String[] args) {
MyTest game = new MyTest();
try {
game.init(800, 600);
game.run();
new Thread(game).start();
} catch(Exception ex) {
ex.printStackTrace();
}
}
private void init(int width, int height) throws Exception {
DisplayMode[] modes = Display.getAvailableDisplayModes();
if (modes.length == 0) {
throw new Exception("Can't find any display modes.");
}
DisplayMode chosenDisplay = modes[0];
for (int i=0; i<modes.length; i++) {
if ((modes[i].getWidth() == width) && (modes[i].getHeight() == height) && (modes[i].getBitsPerPixel() == 16)) {
chosenDisplay = modes[i];
break;
}
}
Display.setDisplayMode(chosenDisplay);
Display.setTitle("My OpenGL Test");
Display.create(new PixelFormat(0, 8, 0));
GL11.glClearDepth(1.0f); // Depth Buffer Setup
GL11.glClearColor(0f, 0f, 0f, 0f); // <-- moved this over here to set the clear color only once
GL11.glEnable(GL11.GL_DEPTH_TEST); // Enables Depth Testing
GL11.glDepthFunc(GL11.GL_LEQUAL); // The Type Of Depth Testing To Do
}
public void run() {
try {
while (!exitApplication) {
if (!Display.isVisible()) {
Thread.sleep(200);
} else if (Display.isCloseRequested()) {
exitApplication = true;
} else {
render();
}
Display.update();
}
} catch (Throwable t) {
t.printStackTrace();
} finally {
Display.destroy();
}
}
private void render() {
GL11.glClear(GL11.GL_COLOR_BUFFER_BIT|GL11.GL_DEPTH_BUFFER_BIT);
GL11.glMatrixMode(GL11.GL_PROJECTION);
GL11.glLoadIdentity();
GLU.gluLookAt(0.5f, 0.5f, 0.5f, 0, 0, 0, 0, 1, 0);
GL11.glMatrixMode(GL11.GL_MODELVIEW);// not really useful in this example, but it's best to switch to modelview before rendering
GL11.glLoadIdentity();
cube();
GL11.glFlush();
}
private void cube() {
GL11.glBegin(GL11.GL_QUADS);
//1
GL11.glColor3f(1f, 0f, 0f);
GL11.glVertex3f(0, 0, 0);
GL11.glVertex3f(0.5f, 0, 0);
GL11.glVertex3f(0.5f, 0.5f, 0);
GL11.glVertex3f(0, 0.5f, 0);
//2
GL11.glColor3f(0f, 0f, 1);
GL11.glVertex3f(0, 0, 0.5f);
GL11.glVertex3f(0, 0.5f, 0.5f);
GL11.glVertex3f(0.5f, 0.5f, 0.5f);
GL11.glVertex3f(0.5f, 0, 0.5f);
//3
GL11.glColor3f(0, 1, 0);
GL11.glVertex3f(0.5f, 0.5f, 0);
GL11.glVertex3f(0.5f, 0f, 0f);
GL11.glVertex3f(0.5f, 0, 0.5f);
GL11.glVertex3f(0.5f, 0.5f, 0.5f);
//4
GL11.glColor3f(1, 0, 1);
GL11.glVertex3f(0, 0.5f, 0.5f);
GL11.glVertex3f(0, 0f, 0.5f);
GL11.glVertex3f(0, 0, 0);
GL11.glVertex3f(0, 0.5f, 0);
GL11.glEnd();
}
}
Does it? But not over here. The quads are ok (no dots) but still there are quads in front of some they shouldn't be in front of. Try rotating the cube around the y-Axis.
(http://img80.imageshack.us/img80/2695/screenshotmyopengltestrf8.th.png) (http://img80.imageshack.us/my.php?image=screenshotmyopengltestrf8.png)
the blue and the green quad should actually be opposite to the magenta and red one, so in front of them.
Hi, I found a piece of code that does pretty much the same thing except it works. But I don't really know what the difference to my code is.
import org.lwjgl.*;
import org.lwjgl.opengl.*;
import org.lwjgl.opengl.glu.*;
public class GLApp {
public static boolean finished; // App will exit when finished is true (when finishedKey is hit: see mainloop())
public static String windowTitle = "My Test";
public static DisplayMode DM, origDM; // hold display mode we set, and the display mode when app first executes
public static int displayWidth = 800;
public static int displayHeight = 600;
public static int displayColorBits = 24;
public static int displayFrequency = 60;
public static int depthBufferBits = 24; // bits per pixel in the depth buffer
public static boolean fullScreen = false; // full screen or floating window
public static float aspectRatio = 0; // aspect ratio of Display (will default to displayWidth/displayHeight)
public static int viewportX, viewportY; // viewport position (will default to 0,0)
public static int viewportW, viewportH; // viewport size (will default to screen width, height)
static float rotation = 0f; // to rotate cubes (just to put something on screen)
public static void main(String args[]) {
GLApp demo = new GLApp();
demo.run();
}
public void run() {
init();
while (!finished) {
if (!Display.isVisible()) {
try {
Thread.sleep(200L);
} catch(Exception ex) {}
} else if (Display.isCloseRequested()) {
finished = true;
}
mainLoop();
Display.update();
}
cleanup();
System.exit(0);
}
public void mainLoop() {
render();
}
public void render() {
// select model view for subsequent transforms
GL11.glMatrixMode(GL11.GL_MODELVIEW);
GL11.glLoadIdentity();
// clear depth buffer and color
GL11.glClear(GL11.GL_COLOR_BUFFER_BIT | GL11.GL_DEPTH_BUFFER_BIT);
// rotate, scale and draw cube
rotation += .3;
GL11.glPushMatrix();
GL11.glLoadIdentity();
GL11.glRotatef(rotation, (float)1, (float)1, (float)1);
GL11.glColor4f(0f, .5f, 1f, 1f);
renderCube();
GL11.glPopMatrix();
}
public void cleanup() {
Display.destroy();
}
public void init() {
initDisplay();
initOpenGL();
}
public void initOpenGL() {
GL11.glClearDepth(1.0f); // Depth Buffer Setup
GL11.glEnable(GL11.GL_DEPTH_TEST); // Enables Depth Testing // Need this ON if using textures
GL11.glDepthFunc(GL11.GL_LEQUAL); // The Type Of Depth Testing To Do
GL11.glClearColor(0f, 0f, 0f, 0f); // Black Background
GL11.glViewport(viewportX, viewportY, viewportW, viewportH);
setPerspective();
GL11.glMatrixMode(GL11.GL_MODELVIEW);
}
public boolean initDisplay () {
origDM = Display.getDisplayMode();
System.out.println("GLApp.initDisplay(): Current display mode is " + origDM);
if ( (DM = getDisplayMode(displayWidth, displayHeight, displayColorBits, displayFrequency)) == null) {
if ( (DM = getDisplayMode(800, 600, 32, 60)) == null) {
if( (DM = getDisplayMode(800, 600, 24, 60)) == null) {
if ( (DM = getDisplayMode(800, 600, 16, 60)) == null) {
if ( (DM = getDisplayMode(origDM.getWidth(), origDM.getHeight(), origDM.getBitsPerPixel(), origDM.getFrequency())) == null) {
System.out.println("GLApp.initDisplay(): Can't find a compatible Display Mode!!!");
}
}
}
}
}
try {
System.out.println("GLApp.initDisplay(): Setting display mode to " + DM + " with pixel depth = " + depthBufferBits);
Display.setDisplayMode(DM);
} catch (Exception exception) {
System.err.println("GLApp.initDisplay(): Failed to create display: " + exception);
System.exit(1);
}
// Initialize the Window
try {
Display.create(new PixelFormat(0, depthBufferBits, 0)); // set bits per buffer: alpha, depth, stencil
Display.setTitle(windowTitle);
Display.setFullscreen(fullScreen);
Display.setVSyncEnabled(true);
System.out.println("GLApp.initDisplay(): Created OpenGL window.");
} catch (Exception exception1) {
System.err.println("GLApp.initDisplay(): Failed to create OpenGL window: " + exception1);
System.exit(1);
}
// Set viewport width/height and Aspect ratio.
if (aspectRatio == 0f) {
aspectRatio = (float)DM.getWidth() / (float)DM.getHeight();
}
// viewport may not match shape of screen. Adjust to fit.
viewportH = DM.getHeight(); // viewport Height
viewportW = (int) (DM.getHeight() * aspectRatio); // Width
if (viewportW > DM.getWidth()) {
viewportW = DM.getWidth();
viewportH = (int) (DM.getWidth() * (1 / aspectRatio));
}
// center viewport in screen
viewportX = (int) ((DM.getWidth()-viewportW) / 2);
viewportY = (int) ((DM.getHeight()-viewportH) / 2);
return true;
}
public static DisplayMode getDisplayMode(int w, int h, int colorBits, int freq) {
try {
DisplayMode adisplaymode[] = Display.getAvailableDisplayModes();
DisplayMode dm = null;
for (int j = 0; j < adisplaymode.length; j++) {
dm = adisplaymode[j];
if (dm.getWidth() == w && dm.getHeight() == h && dm.getBitsPerPixel() == colorBits &&
dm.getFrequency() == freq) {
return dm;
}
}
}
catch (LWJGLException e) {
System.out.println("GLApp.getDisplayMode(): Exception " + e);
}
return null;
}
public static void setPerspective() {
GL11.glMatrixMode(GL11.GL_PROJECTION);
GL11.glLoadIdentity();
GLU.gluPerspective(30f, aspectRatio, 1f, 30f);
GLU.gluLookAt(0f, 0f, 15f, 0f, 0f, 0f, 0f, 1f, 0f);
}
public static void renderCube() {
GL11.glBegin(GL11.GL_QUADS);
// Front Face
GL11.glColor3f(1f, 0f, 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);
// Back Face
GL11.glColor3f(0f, 1f, 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);
// Top Face
GL11.glColor3f(0f, 0f, 1f);
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);
// Bottom Face
GL11.glColor3f(1f, 1f, 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);
// Right face
GL11.glColor3f(1f, 0f, 1f);
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);
// Left Face
GL11.glColor3f(0f, 1f, 1f);
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();
}
}
Why does this code switch between GL_PROJECTION and GL_MODEL_VIEW all the time???
QuoteBut I don't really know what the difference to my code is.
Did you try the code that Ramon pasted? It's exactly the same (at least in the parts that matter) as the code you say works (as near as I can tell :D). The only things that I can see is what Ramon changed (added the glClear() and the setup for the depth testing).
QuoteWhy does this code switch between GL_PROJECTION and GL_MODEL_VIEW all the time???
The Projection matrix is what determines the projection or the translation to the screen from world space (i.e. where the camera is usually looking). GLU.gluPerspective() creates a view where closer things are bigger than far away things (more like real-life 3D space), GLU.gluLookAt() determines where the camera is looking (in this case by specifying a location to look at).
The model view matrix translates objects from the origin in world space. GL11.glRotatef() rotates the cube without changing the camera (set in the projection matrix) because it is working in the world coordinates.
There are probably much better explanations somewhere ;D, but I hope that helps. (This is why I didn't become a teacher ;) )
The code cannot be the same because the screenshot I took was made with this code. The screenshot I appended here is made the the GLApp code.
(http://img167.imageshack.us/img167/8814/screenshotmytestkr4.th.png) (http://img167.imageshack.us/my.php?image=screenshotmytestkr4.png)
Ok, but nevertheless it works now, thx. I will probably understand why in a few days ;)
QuoteOk, but nevertheless it works now, thx. I will probably understand why in a few days
I would be interested in knowing what the difference is if you find out. :D I'm gonna do some testing at home to see if I can spot it... They seem the same though ???
The only difference I can see is glClearDepth(1.0f) which isn't executed in the first example.