Jump to content

  • Log In with Google      Sign In   
  • Create Account


Scaling game to different resolutions (LWJGL)


Old topic!
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.

  • You cannot reply to this topic
3 replies to this topic

#1 Lane Spangler   Members   -  Reputation: 114

Like
0Likes
Like

Posted 15 May 2012 - 03:34 PM

I have made a pong clone in java using the LWJGL game library. I am not sure how to make it so the game plays the same way in different resolutions. It is kind of hard to explain. I made the game based on a 1920x1080 resolution. When I change the resolution the paddle and ball and everything remains the same size in pixels. So in a lower resolution you are playing in an extremely small space and the paddles and the ball are huge. This is the code that I use to set up the display and stuff:

From main class:
package com.gmail.l5p4ngl312.pong;
import java.awt.Dimension;
import java.awt.Toolkit;
import org.lwjgl.LWJGLException;
import org.lwjgl.Sys;
import org.lwjgl.opengl.Display;
import org.lwjgl.opengl.DisplayMode;
public class main {
   static boolean running = true;
   int fps;
   long lastFPS;
   int currentDelta;
   static long lastFrame;
   public void start()
   {
	 game game = new game();
	
   Toolkit toolkit = Toolkit.getDefaultToolkit();
   Dimension screensize = toolkit.getScreenSize();
  
   System.out.println(screensize);
   game.xRes = (int) screensize.getWidth();
   game.yRes = (int) screensize.getHeight();
  
	 try {
	   setDisplayMode(game.xRes, game.yRes, false);
	   Display.create();
	   Display.setVSyncEnabled(true);
	 } catch (LWJGLException e) {
	   e.printStackTrace();
	   System.exit(0);
	 }
	 game.OnInit();
	 this.lastFPS = getTime();
	 while ((!Display.isCloseRequested()) && (running))
	 {
	  currentDelta = getDelta();
	   game.OnEvent(currentDelta);
	   game.OnUpdate(currentDelta);
	   updateFPS();
	   game.OnRender();
	   Display.update();
	   Display.sync(120);
	 }
	 Display.destroy();
   }
   public void setDisplayMode(int width, int height, boolean fullscreen)
   {
	 if ((Display.getDisplayMode().getWidth() == width) &&
	   (Display.getDisplayMode().getHeight() == height) &&
	   (Display.isFullscreen() == fullscreen)) {
	   return;
	 }
	 try
	 {
	   DisplayMode targetDisplayMode = null;
	   if (fullscreen) {
		 DisplayMode[] modes = Display.getAvailableDisplayModes();
		 int freq = 0;
		 for (int i = 0; i < modes.length; i++) {
		   DisplayMode current = modes[i];
		   if ((current.getWidth() == width) && (current.getHeight() == height)) {
			 if (((targetDisplayMode == null) || (current.getFrequency() >= freq)) && (
			   (targetDisplayMode == null) || (current.getBitsPerPixel() > targetDisplayMode.getBitsPerPixel()))) {
			   targetDisplayMode = current;
			   freq = targetDisplayMode.getFrequency();
			 }
			 if ((current.getBitsPerPixel() != Display.getDesktopDisplayMode().getBitsPerPixel()) ||
			   (current.getFrequency() != Display.getDesktopDisplayMode().getFrequency())) continue;
			 targetDisplayMode = current;
			 break;
		   }
		 }
	   }
	   else {
		 targetDisplayMode = new DisplayMode(width, height);
	   }
	   if (targetDisplayMode == null) {
		 System.out.println("Failed to find value mode: " + width + "x" + height + " fs=" + fullscreen);
		 return;
	   }
	   Display.setDisplayMode(targetDisplayMode);
	   Display.setFullscreen(fullscreen);
	 }
	 catch (LWJGLException e) {
	   System.out.println("Unable to setup mode " + width + "x" + height + " fullscreen=" + fullscreen + e);
	 }
   }
   public static long getTime()
   {
	 return Sys.getTime() * 1000L / Sys.getTimerResolution();
   }
   public void updateFPS()
   {
	 if (getTime() - this.lastFPS > 1000L) {
	   this.fps = 0;
	   this.lastFPS += 1000L;
	 }
	 this.fps += 1;
   }
  
   public static int getDelta()
   {
	long time = getTime();
	int delta = (int)(time - lastFrame);
	lastFrame = time;
	return delta;
   }
   public static void main(String[] argv)
   {
	 main display = new main();
	 display.start();
   }

}


From game class:
package com.gmail.l5p4ngl312.pong;
import java.awt.Dimension;
import java.awt.Toolkit;
import java.util.Stack;
import org.lwjgl.input.Mouse;
import org.lwjgl.opengl.Display;
import org.lwjgl.opengl.GL11;
public class game
{
  static Stack<stateManager> stateStack = new Stack();
  String TITLE = "Pong";
  static int xRes = 0;
  static int yRes = 0;
  public static boolean lmbPressed;
  public static boolean rmbPressed;
  public void OnInit()
  {

	Display.setTitle(this.TITLE);
	GL11.glEnable(GL11.GL_TEXTURE_2D);
	GL11.glClearColor(0.0F, 0.0F, 0.0F, 0.0F);
	GL11.glEnable(GL11.GL_BLEND);
	GL11.glBlendFunc(GL11.GL_SRC_ALPHA , GL11.GL_ONE_MINUS_SRC_ALPHA);
	GL11.glLoadIdentity();
	GL11.glViewport(0, 0, xRes, yRes);
	GL11.glMatrixMode(GL11.GL_PROJECTION);
	GL11.glOrtho(0.0D, xRes, 0.0D, yRes, 1.0D, -1.0D);
	GL11.glMatrixMode(GL11.GL_MODELVIEW);
	textures.LoadTextures();
	ChangeState(stateMenu.Instance());
  }
  public void OnEvent(int delta)
  {
	if (Mouse.isButtonDown(0))
	{
	  lmbPressed = true;
	}
	else lmbPressed = false;
	if (Mouse.isButtonDown(1))
	{
	  rmbPressed = true;
	}
	else rmbPressed = false;
	if (!stateStack.empty())
	{
	  ((stateManager)stateStack.peek()).OnEvent(delta);
	}
  }
  public void OnUpdate(int delta)
  {
	if ((!stateStack.empty()) && (!((stateManager)stateStack.peek()).Paused))
	{
	  ((stateManager)stateStack.peek()).OnUpdate(delta);
	}
  }
  public static void OnRender()
  {
	GL11.glClear(GL11.GL_COLOR_BUFFER_BIT | GL11.GL_STENCIL_BUFFER_BIT);
	if (!stateStack.empty())
	{
	  ((stateManager)stateStack.peek()).OnRender();
	}
  }
  public static void OnCleanup()
  {
	while (!stateStack.empty())
	{
	  ((stateManager)stateStack.peek()).OnCleanup();
	  stateStack.pop();
	}
	main.running = false;
  }
  public static void ChangeState(stateManager state) {
	if (!stateStack.empty())
	{
	  ((stateManager)stateStack.peek()).OnCleanup();
	  stateStack.pop();
	}
	stateStack.push(state);
	((stateManager)stateStack.peek()).OnInit();
  }
  public static void PopState()
  {
	if (!stateStack.empty())
	{
	  ((stateManager)stateStack.peek()).OnCleanup();
	  stateStack.pop();
	}
	if (!stateStack.empty())
	{
	  ((stateManager)stateStack.peek()).Resume();
	}
  }
  public static void PushState(stateManager state)
  {
	if (!stateStack.empty())
	{
	  ((stateManager)stateStack.peek()).Pause();
	}
	stateStack.push(state);
	((stateManager)stateStack.peek()).OnInit();
  }
}

Edited by Lane Spangler, 15 May 2012 - 03:36 PM.


Sponsor:

#2 Neophyte   Members   -  Reputation: 542

Like
0Likes
Like

Posted 16 May 2012 - 07:20 AM

It's been a while since I played with OpenGL, so take this with a grain of salt, but glOrtho doesn't require you to use the actual resolution of the screen.

That is, your call
GL11.glOrtho(0.0D, xRes, 0.0D, yRes, 1.0D, -1.0D);
could be replaced with, for instance
GL11.glOrtho(0.0D, 1920.0D, 0.0D, 1080.0D, 1.0D, -1.0D);

which ought to solve your problem.

#3 Lane Spangler   Members   -  Reputation: 114

Like
1Likes
Like

Posted 16 May 2012 - 02:44 PM

I thought this as well. When I do that it does achieve the desired effect except the game no longer fits the game window. For example, in a 1024x576 window using

GL11.glOrtho(0.0D, 1920.0D, 0.0D, 1080.0D, 1.0D, -1.0D);
The game is fit to roughly the bottom left corner of the window. It seems to have scaled correctly at least.

#4 Lane Spangler   Members   -  Reputation: 114

Like
1Likes
Like

Posted 20 May 2012 - 09:36 AM

Ok, I fixed it. The issue was that I was using the current resolution to position game objects instead of the 1920x1080 resolution. So for example I would do
Paddle P1 = new Paddle(0, Display.getDisplayMode().getHeight()/2);
\
When I should be doing
Paddle P1 = new Paddle(0, 540);





Old topic!
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.



PARTNERS