beginner needs help: problems creating a cube

Started by jagdfalke, December 06, 2006, 09:10:41

Previous topic - Next topic

jagdfalke

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?

kappa

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

Ramon

if you're new to opengl, this site might help you alot: http://nehe.gamedev.net/. Enjoy!

jagdfalke

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.

Ramon

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();
  }
}

jagdfalke

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.




the blue and the green quad should actually be opposite to the magenta and red one, so in front of them.

jagdfalke

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???

Fool Running

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 ;) )
Programmers will, one day, rule the world... and the world won't notice until its too late.Just testing the marquee option ;D

jagdfalke

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.


Ok, but nevertheless it works now, thx. I will probably understand why in a few days ;)

Fool Running

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 ???
Programmers will, one day, rule the world... and the world won't notice until its too late.Just testing the marquee option ;D

jagdfalke

The only difference I can see is glClearDepth(1.0f) which isn't executed in the first example.