A few noob questions

Started by Darrin, January 25, 2011, 02:49:51

Previous topic - Next topic

Darrin

Hi,

I'm trying to set up a game with a 2d plane which has a zoom with middle mouse and left/right & up down scrolling while maintaining the same downward view.  Something along the line of Supreme Commander but in space.

I've started using the demo code.  Hopefully I can write up somethings that I've been playing with (setting up as window, drawing various shapes, zoom, colorizing, background color etc) but I've gotten a little confused by a few things.

1) Why is the original code set up with with Y = 0 in the lower left rather than upper left?

glOrtho(0.0, Display.getDisplayMode().getWidth(), Display.getDisplayMode().getHeight(), 0.0, 0.0, 1.0);


2) I started to implement left and right scrolling which works fine for all the objects I've drawn.  Just hold your mouse on the left or right edge.  But when I rotate one of the GL_QUADS it's position or rotation point gets larger and larger.  While it is a cool effect, I want it to continue to spin in place.  What am I'm not understanding? Conceptually I think I'm missing something.


import org.lwjgl.Sys;
import org.lwjgl.input.Keyboard;
import org.lwjgl.input.Mouse;
import org.lwjgl.openal.AL;
import org.lwjgl.opengl.Display;
import org.lwjgl.opengl.DisplayMode;

import static org.lwjgl.opengl.GL11.*;

/**
 *
 * This is a <em>very basic</em> skeleton to init a game and run it.
 *
 * @author $Author: spasi $
 * @version $Revision: 3418 $
 * $Id: Game.java 3418 2010-09-28 21:11:35Z spasi $
 */
public class game {

	/** Game title */
	public static final String GAME_TITLE = "My Game";

	/** Desired frame time */
	private static final int FRAMERATE = 60;

	/** Exit the game */
	private static boolean finished;

  /** A rotating square! */
  private static float  angle;
  private static float zoom = 1.0f;
  private static float w = 800;
  private static float h = 600;
  private static int dx = 0;
  private static int dy = 0;
  

	/**
	 * No constructor needed - this class is static
	 */
	private game() {}

	/**
	 * Application init
	 * @param args Commandline args
	 */
	public static void main(String[] args) {
		try {
			init();
			run();
		} catch (Exception e) {
			e.printStackTrace(System.err);
			Sys.alert(GAME_TITLE, "An error occured and the game will exit.");
		} finally {
			cleanup();
		}

		System.exit(0);
	}

	/**
	 * Initialise the game
	 * @throws Exception if init fails
	 */
	private static void init() throws Exception {
		// Create a fullscreen window with 1:1 orthographic 2D projection, and with
		// mouse, keyboard, and gamepad inputs.
    Display.setTitle(GAME_TITLE);
    Display.setFullscreen(false);
    
    // ** Darrin
    Display.setDisplayMode(new DisplayMode(800,600));  // controls screen size otherwise takes default windows resolution

    // Enable vsync if we can
    Display.setVSyncEnabled(true);

    Display.create();

		// Start up the sound system
		AL.create();

		// TODO: Load in your textures etc here

		// Put the window into orthographic projection mode with 1:1 pixel ratio.
		// We haven't used GLU here to do this to avoid an unnecessary dependency.
		
		// this is setting up a 2d view, not a 3d view. 
		// see http://basic4gl.wikispaces.com/2D+Drawing+in+OpenGL
		
		glMatrixMode(GL_PROJECTION);
		glLoadIdentity();
		glOrtho(0.0, Display.getDisplayMode().getWidth(), Display.getDisplayMode().getHeight(), 0.0, 0.0, 1.0);
		glMatrixMode(GL_MODELVIEW);
		glLoadIdentity();
		
		// specifies how much of the opengl panel gets painted.
		glViewport(0, 0, Display.getDisplayMode().getWidth(), Display.getDisplayMode().getHeight());	
		
		// enables color calls
		glEnable(GL_COLOR_MATERIAL);   
		
		// sets background color
		glClearColor(0.2f, 0.0f, 0.0f, 1.0f);  
	}

	/**
	 * Runs the game (the "main loop")
	 */
	private static void run() {
		while (!finished) {
			// Always call Window.update(), all the time
			
			
			Display.update();

			if (Display.isCloseRequested()) {
				// Check for O/S close requests
				finished = true;
			} else if (Display.isActive()) {
				// The window is in the foreground, so we should play the game
				userInput();
				logic();
				render();
				Display.sync(FRAMERATE);
			} else {
				// The window is not in the foreground, so we can allow other stuff to run and
				// infrequently update
				try {
					Thread.sleep(100);
				} catch (InterruptedException e) {
				}
				logic();
				if (Display.isVisible() || Display.isDirty()) {
					// Only bother rendering if the window is visible or dirty
					render();
				}
			}
		}
	}

	/**
	 * Do any game-specific cleanup
	 */
	private static void cleanup() {
		// TODO: save anything you want to disk here

		// Stop the sound
		AL.destroy();

		// Close the window
		Display.destroy();
	}

	private static void userInput(){
	
		// Mouse x/y scroll
	    int x = Mouse.getX();
	    int y = Mouse.getY();
	   
	    
	    if ((x > 750) && (Mouse.isInsideWindow())){
	    	dx += 1;
	    }
	    
	    if (x < 50 && (Mouse.isInsideWindow())){
	    	dx -= 1;
	    }
		
        if (Mouse.isButtonDown(0)) {    	
    	    System.out.println("MOUSE DOWN @ X: " + x + " Y: " + y);
    	}
        
  
        // Mouse Zoom
        int z = Mouse.getDWheel();  	
    	
        if (z != 0){
        	System.out.println("Wheel is " + z);
        	if (z > 0) {
        		zoom += -0.5;
        		if (zoom < 0.5)
        			zoom = 0.5f;
        	}
        	
        	if (z < 0){
        		zoom += 0.5;
        		if (zoom > 6)
        			zoom = 6.0f;
        	}

        }
     
    	if (Keyboard.isKeyDown(Keyboard.KEY_SPACE)) {
    	    System.out.println("SPACE KEY IS DOWN");
    	}

	}
	
	/**
	 * Do all calculations, handle input, etc.
	 */	
	
	private static void logic() {
		// Example input handler: we'll check for the ESC key and finish the game instantly when it's pressed
		if (Keyboard.isKeyDown(Keyboard.KEY_ESCAPE)) {
			finished = true;
		}

    // TODO: all your game logic goes here.
		angle += 1.0f % 360;
	}

	/**
	 * Render the current frame
	 */
	private static void render() {
		

	    	
	glClear(GL_COLOR_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);

    // TODO: all your rendering goes here



	// Zoom
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    glOrtho((w-w*zoom)/2,
    		zoom*w + (w-w*zoom)/2,
    		zoom*h + (h-h*zoom)/2,
    		(h-h*zoom)/2, 
    		-1.0, 
    		1) ;    
    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();
    
    
    // Colorized Square
    glPushMatrix();
    glBegin(GL_QUADS);
	  glColor3f(0.5f, 0.0f, 0.8f);
	  glVertex2i(-50+dx, -50);
	  glColor3f(0.0f, 0.0f, 0.8f);
	  glVertex2i(50+dx, -50);
	  glColor3f(1.0f, 0.0f, 0.2f);
	  glVertex2i(50+dx, 50);
	  glColor3f(0.2f, 0.5f, 0.5f);
	  glVertex2i(-50+dx, 50);
	glEnd();
    glPopMatrix();
    

    glPushMatrix();  // Translation state
    
    //glTranslatef((Display.getDisplayMode().getWidth() / 2)+dx, Display.getDisplayMode().getHeight() / 2, 0.0f);
    
    //glScalef(2,2,2); // 1 = normal size 2 equals double
    // glRotatef(a, 0, 1, 0); // rotation about the y-axis
    // glRotatef(a, 0, 0, 1); // rotation about the z-axis
    
    glRotatef(-angle, 0, 0, 1.0f);    
    glBegin(GL_QUADS);
	    glColor3f(0.5f, 0.0f, 0.8f);
	    glVertex2i(-50+dx, -50);
	    glColor3f(0.0f, 0.0f, 0.8f);
	    glVertex2i(50+dx, -50);
	    glColor3f(1.0f, 0.0f, 0.2f);
	    glVertex2i(50+dx, 50);
	    glColor3f(0.2f, 0.5f, 0.5f);
	    glVertex2i(-50+dx, 50);
    glEnd();
    glPopMatrix();  // Ends translation state
    
    
    // why doesn't the point scale with ortho?
    glPushMatrix();    
    //glPointSize(40);  // sets point size diaeter
    glEnable(GL_POINT_SMOOTH);   // Makes it into a circle rather than square
    glBegin(GL_POINTS);
    	glVertex2f(69.0f,49.0f);
    	glVertex2i(100,50);
    glEnd();
    glPopMatrix();

    
    
    glColor3f(0.0f, 1.0f, 0.0f);   
    glBegin (GL_LINES);
    glVertex2i (39, 200);
    glVertex2i (75, 250);
    glVertex2i (60, 200);
    glVertex2i (85, 250);
    glEnd();
    glColor3f(0.0f, 0.0f, 1.0f);
    glBegin (GL_LINES);
    glVertex3f (45, 200, 0);
    glVertex3f (75, 250, 0);
    glVertex3f (44, 200, 0);
    glVertex3f (85, 250, 0);
    glEnd();
}
}


3) With my zoom code all objects shrink and increase in size except the GL_POINTS.  Even if I set them to a larger size, like 40 pixels, they move but they don't actually shrink / scale when zooming out.

4) Almost all Opengl tutorials, NEHE, etc, include GLUT.   Is it basically a competitor or sorts with LWJGL?  They seem to have a few overlaps with mouse but they have several other features as well.   Just curious why it isn't implemented with LWJGL or perhaps it is.  Not quite seeing it?

5) I've been looking over http://potatoland.org/code/gl/    and it is a really cool tutorial but there is quite a bit of code in his glApp....  have the developers thought about including some of those features?   I mean the really seem important building blocks to game writing... models, fonts, camera, etc.   

I appreciate any insights you may have. 

avm1979

1) Coordinates in OpenGL are with the y-axis going down to up, like on a math graph.  You *could* switch it, but it's more trouble than it's worth and I would recommend just getting used to it this way.

2) A rotation is around the origin.  So to make the quad rotate in place, you want to translate to the location of the quad, rotate about the (new) origin, and then translate back, something like this:
glPushMatrix(); // store matrix
glTranslate2f(quadCoordinateX, quadCoordinateY);
glRotatef(angle, 0, 0, 1);
glPopMatrix(); // restore previous matrix - undoes the translation/rotation


3) The size of GL_POINTs, GL_LINEs (and maybe some other stuff? not sure) is not affected by the modelview matrix, though their position is.  So you're not doing anything wrong - it just doesn't work that way.

4) GLUT is a set of utilities built on top of GL.  All of it could be replicated with normal GL calls.  I'm not sure if it's done in LWJGL, actually - it might be.

5) As I understand, LWJGL is supposed to be a low-level API that actually *lets* you use OpenGL from Java to begin with.  If you want higher-level features, take a look at something like this.