Odd graphic shifting

Started by Noxyro, March 15, 2014, 13:52:57

Previous topic - Next topic

Noxyro

Hello,

I've started programming with LWJGL a few days ago.
Yesterday i noticed that my images i use in my programm (for buttons) are slightly shifted from their intended place.

Here a picture of what im talking about:



The image is 256 x 64 and is placed at X: 32 and Y: 32.
As you can see my mouse-cursor is at X: 288 and Y: 504 wich SHOULD BE the exact bottom right pixel of the image (Y: 600-504 = 96).
But it isn't... Then i noticed these tiny black borders at the bottom and the right of the program, matching exactly the shifting of the image.

I just can't figure out where my problem is?

Here's my code:

(Main) Game.java
package com.gmail.noxyro;

import com.gmail.noxyro.util.Button;
import com.gmail.noxyro.util.Entity;
import com.gmail.noxyro.util.Sprite;

import org.lwjgl.LWJGLException;
import org.lwjgl.Sys;
import org.lwjgl.opengl.Display;
import org.lwjgl.opengl.DisplayMode;
import org.lwjgl.opengl.GL11;

public class Game {
	private static Game instance;
  
	public void run() {
		initGraphics();
		init();
    
		gameLoop();
	}
  
	public static void main(String[] args) {
		Game instance = new Game();
		instance.run();
	}
  
	public void initGraphics() {
		try {
			Display.setDisplayMode(new DisplayMode(800, 600));
			Display.create();
			Display.setResizable(true);
		} catch (LWJGLException ex) {
			ex.printStackTrace();
			System.exit(-1);
		}
    
		GL11.glEnable(GL11.GL_TEXTURE_2D);
		GL11.glClearColor(1.0F, 1.0F, 1.0F, 0.0F);
    
		GL11.glEnable(GL11.GL_BLEND);
		GL11.glBlendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA);
    
		GL11.glViewport(0, 0, Display.getWidth(), Display.getHeight());
		GL11.glMatrixMode(GL11.GL_MODELVIEW);
    
		GL11.glMatrixMode(GL11.GL_PROJECTION);
		GL11.glLoadIdentity();
		GL11.glOrtho(0, Display.getWidth(), Display.getHeight(), 0, -1, 1);
		GL11.glMatrixMode(GL11.GL_MODELVIEW);
	}
  
	public void init() {
		Display.setTitle("Hashtag Attack");
    
		Sprite button = Sprite.loadAnimImage("button", "res/images/buttons", "button_simple1.png", "button_simple1_hover.png", "button_simple1_click.png");
		new Button(button, 256.0F, 64.0F, 0.0F, 32.0F, 32.0F, 0.0F).register();
		new Button(button, 256.0F, 64.0F, 0.0F, 320.0F, 320.0F, 0.0F).register();
	}
  
	public void update(long elapsedTime) {
		for (Entity e : Entity.getEntities()) {
			e.update(elapsedTime);
		}
	}
  
	public void render(long elapsedTime) {
		for (Entity e : Entity.getEntities()) {
			e.draw(elapsedTime);
		}
	}
  
	public void resized() {}
  
	public void dispose() {}
  
	public static long getCurrentTime() {
		return Sys.getTime() * 1000L / Sys.getTimerResolution();
	}
  
	private void gameLoop() {
		long lastFrame = getCurrentTime();
		long thisFrame = getCurrentTime();
    
		while (!Display.isCloseRequested()) {      
			GL11.glClear(16384);
      
			thisFrame = getCurrentTime();      
			update(thisFrame - lastFrame);
			render(thisFrame - lastFrame);
			lastFrame = thisFrame;
      
			Display.update();
			Display.sync(100);
		}
		
		Display.destroy();
		System.exit(0);
	}
  
	public static void end() {
		instance.dispose();
		Display.destroy();
		System.exit(0);
 	}
}


Entity.java
package com.gmail.noxyro.util;

import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
import org.lwjgl.opengl.GL11;

public abstract class Entity {
	protected int ID;
	protected Sprite sprite;
	protected float sizeX;
	protected float sizeY;
	protected float sizeZ;
	protected float x;
	protected float y;
	protected float z;
	protected float speedX;
	protected float speedY;
	protected float speedZ;
	protected float accX;
	protected float accY;
	protected float accZ;
	
	protected long frameSpeed = 1000;
	protected long frameTime;
  
	public Entity() {
		this.setID(genID());
	}
	  
	public Entity(Sprite sprite) {
		this.setID(genID());
		this.setSprite(sprite);
	}
	  
	public Entity(Sprite sprite, float sizeX, float sizeY, float sizeZ) {
		this.setID(genID());
		setSprite(sprite);
		setSizeX(sizeX);
		setSizeY(sizeY);
		setSizeZ(sizeZ);
	}
	  
	public Entity(Sprite sprite, float sizeX, float sizeY, float sizeZ, float x, float y, float z) {
		this.setID(genID());
		setSprite(sprite);
		setSizeX(sizeX);
		setSizeY(sizeY);
		setSizeZ(sizeZ);
		setX(x);
		setY(y);
		setZ(z);
	}
	  
	public Entity(Sprite sprite, float sizeX, float sizeY, float sizeZ, float x, float y, float z, float speedX, float speedY, float speedZ) {
		this.setID(genID());
		this.setSprite(sprite);
		this.setSizeX(sizeX);
		this.setSizeY(sizeY);
		this.setSizeZ(sizeZ);
		this.setX(x);
		this.setY(y);
		this.setZ(z);
		this.setSpeedX(speedX);
		this.setSpeedY(speedY);
		this.setSpeedZ(speedZ);
	}
	  
	public Entity(Sprite sprite, float sizeX, float sizeY, float sizeZ, float x, float y, float z, float speedX, float speedY, float speedZ, float accX, float accY, float accZ) {
		this.setID(genID());
		this.setSprite(sprite);
		this.setSizeX(sizeX);
		this.setSizeY(sizeY);
		this.setSizeZ(sizeZ);
		this.setX(x);
		this.setY(y);
		this.setZ(z);
		this.setSpeedX(speedX);
		this.setSpeedY(speedY);
		this.setSpeedZ(speedZ);
		this.setAccX(accX);
		this.setAccY(accY);
		this.setAccZ(accZ);
	}
	
	public int getID() {
		return ID;
	}

	public void setID(int iD) {
		ID = iD;
	}

	public Sprite getSprite() {
		return sprite;
	}

	public void setSprite(Sprite sprite) {
		this.sprite = sprite;
	}

	public float getSizeX() {
		return sizeX;
	}

	public void setSizeX(float sizeX) {
		this.sizeX = sizeX;
	}

	public float getSizeY() {
		return sizeY;
	}

	public void setSizeY(float sizeY) {
		this.sizeY = sizeY;
	}

	public float getSizeZ() {
		return sizeZ;
	}

	public void setSizeZ(float sizeZ) {
		this.sizeZ = sizeZ;
	}

	public float getX() {
		return x;
	}

	public void setX(float x) {
		this.x = x;
	}

	public float getY() {
		return y;
	}

	public void setY(float y) {
		this.y = y;
	}

	public float getZ() {
		return z;
	}

	public void setZ(float z) {
		this.z = z;
	}

	public float getSpeedX() {
		return speedX;
	}

	public void setSpeedX(float speedX) {
		this.speedX = speedX;
	}

	public float getSpeedY() {
		return speedY;
	}

	public void setSpeedY(float speedY) {
		this.speedY = speedY;
	}

	public float getSpeedZ() {
		return speedZ;
	}

	public void setSpeedZ(float speedZ) {
		this.speedZ = speedZ;
	}

	public float getAccX() {
		return accX;
	}

	public void setAccX(float accX) {
		this.accX = accX;
	}

	public float getAccY() {
		return accY;
	}

	public void setAccY(float accY) {
		this.accY = accY;
	}

	public float getAccZ() {
		return accZ;
	}

	public void setAccZ(float accZ) {
		this.accZ = accZ;
	}
  
	public Entity register() {
		registerEntity(this);
		return this;
	}
  
	public void unregister() {
		unregisterEntity(this);
	}
  
	public void update(long elapsedTime) {
		this.setX(this.getX() + this.getSpeedX());
		this.setY(this.getY() + this.getSpeedY());
		this.setZ(this.getZ() + this.getSpeedZ());
		this.setSpeedX(this.getSpeedX() + this.getAccX());
		this.setSpeedY(this.getSpeedY() + this.getAccY());
		this.setSpeedZ(this.getSpeedZ() + this.getAccZ());
	}
  
  	public void draw(long elapsedTime) {
  		this.frameTime = this.frameTime + elapsedTime;
		  
		if (this.frameTime >= this.frameSpeed) {
			int frameSkip = (int) Math.floor(this.frameTime / (this.frameSpeed > 0 ? this.frameSpeed : 1));
			this.frameTime = this.frameTime % (this.frameSpeed > 0 ? this.frameSpeed : 1);
			this.getSprite().setFrame(this.getSprite().getFrame()+frameSkip);
			this.getSprite().nextFrame();
		}
	  
		this.getSprite().use();
		    
		GL11.glBegin(GL11.GL_QUADS);
			GL11.glTexCoord2f(0, 0);
			GL11.glVertex2f(this.getX(), this.getY());
			    
			GL11.glTexCoord2f(getSizeX()/this.getSprite().getFrameTexture().getTextureWidth(), 0);
			GL11.glVertex2f(this.getX() + this.getSizeX(), this.getY());
			    
			GL11.glTexCoord2f(getSizeX()/this.getSprite().getFrameTexture().getTextureWidth(), getSizeY()/this.getSprite().getFrameTexture().getTextureHeight());
			GL11.glVertex2f(this.getX() + this.getSizeX(), this.getY() + this.getSizeY());
			    
			GL11.glTexCoord2f(0, getSizeY()/this.getSprite().getFrameTexture().getTextureHeight());
			GL11.glVertex2f(this.getX(), this.getY() + this.getSizeY());
		GL11.glEnd();
	}
  
  	// ######################
  	// ### STATIC SECTION ###
  	// ######################
  	
  	public static Map<Integer, Entity> entityMap = new HashMap<Integer, Entity>();
  	public static int entityID = 0;
  
  	public static Collection<Entity> getEntities() {
  		return entityMap.values();
  	}
  
  	public static void registerEntity(Entity entity) {
  		entityMap.put(Integer.valueOf(entity.getID()), entity);
  	}
  
  	public static void unregisterEntity(Entity entity) {
  		entityMap.remove(entity);
  	}
  
  	public static int genID() {
  		entityID += 1;
  		return entityID;
  	}
}


Button.java
package com.gmail.noxyro.util;

import org.lwjgl.input.Mouse;
import org.lwjgl.opengl.Display;
import org.lwjgl.opengl.GL11;

public class Button extends Entity {
	private boolean hovered;
	private boolean down;
	private boolean clicked;
	
	private int mx, my;
	
	public Button(Sprite sprite, float sizeX, float sizeY, float sizeZ) {
		super(sprite, sizeX, sizeY, sizeZ);
	}
	  
	public Button(Sprite sprite, float sizeX, float sizeY, float sizeZ, float x, float y, float z) {
		super(sprite, sizeX, sizeY, sizeZ, x, y, z);
	}
	
	@Override
	public void update(long elapsedTime) {
		this.setX(this.getX() + this.getSpeedX());
	    this.setY(this.getY() + this.getSpeedY());
	    this.setZ(this.getZ() + this.getSpeedZ());
	    this.setSpeedX(this.getSpeedX() + this.getAccX());
	    this.setSpeedY(this.getSpeedY() + this.getAccY());
	    this.setSpeedZ(this.getSpeedZ() + this.getAccZ());
	    
		 // Debugging
		    
		    if (mx != Mouse.getX() || my != Mouse.getY()) {
		    	System.out.println("X: " + Mouse.getX() + " | Y: " + Mouse.getY());
		    }
		    
		    mx = Mouse.getX();
		    my = Mouse.getY();
	    
	    // Debugging end
	    
	    if (isClicked()) {
	    	setClicked(false);
	    }
	    
	    if (Mouse.getX() >= this.getX() && Mouse.getX() <= this.getX() + this.getSizeX()) {
	    	if (Mouse.getY() <= (Display.getHeight()-this.getY()) && Mouse.getY() >= (Display.getHeight()-this.getY()) - this.getSizeY()) {
	    		setHovered(true);
	    	} else {
	    		setHovered(false);
	    	}
	    } else {
	    	setHovered(false);
	    }
	    
	    if (isHovered()) {
	    	if (Mouse.isButtonDown(0)) {
	    		setDown(true);
	    	}
	    } else {
	    	setDown(false);
	    }
	    
    	if (isDown()) {
	    	if (!Mouse.isButtonDown(0)) {
	    		setClicked(true);
	    		setDown(false);
	    	}
    	}
	}
	
	@Override
	public void draw(long elapsedTime) {
		if (this.getSprite().isAnimated()) {
			if (isDown()) {
				this.getSprite().setFrame(2);
			} else if (isHovered()) {
				this.getSprite().setFrame(1);
			} else {
				this.getSprite().setFrame(0);
			}
		}
		
		this.getSprite().use();
	    
	    GL11.glBegin(GL11.GL_QUADS);
		    GL11.glTexCoord2f(0, 0);
		    GL11.glVertex2f(this.getX(), this.getY());
		    
		    GL11.glTexCoord2f(getSizeX()/this.getSprite().getFrameTexture().getTextureWidth(), 0);
		    GL11.glVertex2f(this.getX() + this.getSizeX(), this.getY());
		    
		    GL11.glTexCoord2f(getSizeX()/this.getSprite().getFrameTexture().getTextureWidth(), getSizeY()/this.getSprite().getFrameTexture().getTextureHeight());
		    GL11.glVertex2f(this.getX() + this.getSizeX(), this.getY() + this.getSizeY());
		    
		    GL11.glTexCoord2f(0, getSizeY()/this.getSprite().getFrameTexture().getTextureHeight());
		    GL11.glVertex2f(this.getX(), this.getY() + this.getSizeY());
	    GL11.glEnd();
	}

	public boolean isHovered() {
		return hovered;
	}

	public void setHovered(boolean hovered) {
		this.hovered = hovered;
	}
	
	public boolean isDown() {
		return down;
	}

	public void setDown(boolean down) {
		this.down = down;
	}

	public boolean isClicked() {
		return clicked;
	}

	public void setClicked(boolean clicked) {
		this.clicked = clicked;
	}
}


Grettings - Noxyro

Daslee

Quote from: Noxyro on March 15, 2014, 13:52:57
The image is 256 x 64 and is placed at X: 32 and Y: 32.
As you can see my mouse-cursor is at X: 288 and Y: 504 wich SHOULD BE the exact bottom right pixel of the image (Y: 600-504 = 96).
But it isn't...

As I understood you, your mouse Y value is incorrect? Try doing this:
mx = Display.getHeight() - Mouse.getY();

Noxyro

Quote from: Daslee on March 16, 2014, 09:28:24
As I understood you, your mouse Y value is incorrect? Try doing this:
mx = Display.getHeight() - Mouse.getY();


If you read my code (Button.java), you can see that i use the real mouse position only in debug output and for the "Collision" check i  already use Display.getHeight() - Mouse.getY(). That's what i meant with (Y: 600-504 = 96).

My Mouse is at X: 288 and Y: 96, the upper left pixel of the image is placed at X: 32 and Y: 32. The image has a size of 256 x 64.
So, the bottom right pixel of the image is at X: 288 (32 + 256) and Y: 96 (32 + 64) - my mouse SHOULD BE in the bottom right pixel of the image - but as you can see on the screenshot, the image of the button is shifted a few pixels to the top left corner ... but it's still recognizing the "Collision" check and changes its image to "hover".

This distance the image is shifted can also be found as a black border at the bottom and right of the window.

The problem is NOT my Mouse position and NOT the position of the image - the values BEHIND it are all correct.
The problem is the SHIFTING of the complete graphic output.

Greetings - Noxyro


Noxyro

Solved it by myself now.

The problem was Display.setResizable().

I have no idea why, but when the window is created the black border appears and as soon as you resize the window it disappears.
So, I just removed Display.setResizable() and now it's all working fine.

Still can't figure out why this happened, but my problem is solved - closed.

Greetings - Noxyro