I have this code:
public class Main {
private BoardHandler boardHandler;
Main() {
Display.setTitle(Cons.WINDOW_TITLE);
try {
Display.setDisplayMode(new DisplayMode(Cons.SCREEN_WIDTH, Cons.SCREEN_HEIGHT));
Display.create();
}
catch (LWJGLException e) {
e.printStackTrace();
}
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(0, Cons.SCREEN_WIDTH, Cons.SCREEN_HEIGHT, 0, 1, -1);
glMatrixMode(GL_MODELVIEW);
glEnable(GL_TEXTURE_2D);
glClearColor(0, 0, 0, 0);
glEnable(GL_BLEND);
glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
boardHandler = new BoardHandler();
while (!Display.isCloseRequested()) {
glClear(GL_COLOR_BUFFER_BIT);
Clock.update();
// game:
boardHandler.update();
Display.update();
Display.sync(60);
}
Display.destroy();
}
public static void main(String[] args) {
new Main();
}
}
I load textures using this function:
public static Texture loadTexture(String path, String fileType) {
Texture tex = null;
InputStream in = ResourceLoader.getResourceAsStream(path);
try {
tex = TextureLoader.getTexture(fileType, in);
}
catch (IOException e) {
e.printStackTrace();
}
return tex;
}
I draw stuff with this function:
public static void drawTile(Texture tex, float x, float y, float radius) {
tex.bind();
glTranslated(x - radius / 2, y - radius / 2, 0);
glBegin(GL_QUADS);
glTexCoord2d(0, 0);
glVertex2d(0, 0);
glTexCoord2d(1, 0);
glVertex2d(radius, 0);
glTexCoord2d(1, 1);
glVertex2d(radius, radius);
glTexCoord2d(0, 1);
glVertex2d(0, radius);
glEnd();
glLoadIdentity();
}
I draw these images:
http://imgur.com/4IZO9CC,gmpPfMM,gF1EeBs,nrv6NRR,OwLgHoM,wfGvAvr,CVEagHD,6ij24M4,pheIjuI#0
And get this as a result:
http://imgur.com/pgExbTE,liEJ01d#0
The X'es are drawn the exact same way as all the other tiles, yet the X'es has these ugly white borders around them. Do note that these white borders are "inside" of the image I'm trying to draw. The blackness inside the white borders is the background showing through like how it's supposed to look.
What is the problem? Why are the white borders present when those parts are transparent in the image? Is there a solution to this?
This is my first attempt at using any 2D/3D engine to draw stuff, I'm just searching for a quick fix if possible.
I fixed it! It seems like openGL (or at least the way I set it up) does not like semi-transparent images for some reason. All I had to do in order for the white borders to disappear was to make every pixel in the image either fully transparent or fully opaque.
Related
Ive tried a lot but dont find my error. Heres my Code:
public class Renderer {
public static final int WIDTH = 1080, HEIGHT = 720, FPS = 60;
public static void createDisplay()
{
try {
Display.setDisplayMode(new DisplayMode(WIDTH,HEIGHT));
Display.create();
Display.setVSyncEnabled(true);
} catch (LWJGLException e) {
e.printStackTrace();
System.exit(0);
}
GL11.glEnable(GL11.GL_TEXTURE_2D);
GL11.glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
// enable alpha blending
GL11.glEnable(GL11.GL_BLEND);
GL11.glBlendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA);
GL11.glViewport(0,0,WIDTH,HEIGHT);
GL11.glMatrixMode(GL11.GL_MODELVIEW);
GL11.glMatrixMode(GL11.GL_PROJECTION);
GL11.glLoadIdentity();
GL11.glOrtho(0, WIDTH, HEIGHT, 0, 1, -1);
GL11.glMatrixMode(GL11.GL_MODELVIEW);
}
public static void updateDisplay(){
Display.update();
Display.sync(FPS);
glClear(GL_COLOR_BUFFER_BIT);
glClearColor(0.2f,0.2f,0.2f,1.0f);
}
public static void destroyDisplay()
{
Display.destroy();
}
public static void renderDisplay(ArrayList<GameObject> render, Camera cam)
{
Color.white.bind();
for(GameObject obj: render)
{
obj.getTex().bind();
if(obj instanceof Player)
{
glBegin(GL_QUADS);
glTexCoord2f(0,0);
glVertex2f(obj.getX()+WIDTH/2-cam.getX(), obj.getY()+HEIGHT/2-cam.getY());
glTexCoord2f(obj.getTex().getWidth(),0);
glVertex2f(obj.getX()+WIDTH/2+obj.getSizeX()-cam.getX(), obj.getY()+HEIGHT/2-cam.getY());
glTexCoord2f(obj.getTex().getWidth(),obj.getTex().getHeight());
glVertex2f(obj.getX()+WIDTH/2+obj.getSizeX()-cam.getX(), obj.getY()+HEIGHT/2+obj.getSizeY()-cam.getY());
glTexCoord2f(0,obj.getTex().getHeight());
glVertex2f(obj.getX()+WIDTH/2-cam.getX(), obj.getY()+HEIGHT/2+obj.getSizeY()-cam.getY());
glEnd();
}else{
glBegin(GL_QUADS);
glTexCoord2f(0,0);
glVertex2f((obj.getX()-cam.getX()), (obj.getY()-cam.getY()));
glTexCoord2f(1,0);
glVertex2f((obj.getX()-cam.getX())+obj.getSizeX(), (obj.getY()-cam.getY()));
glTexCoord2f(1,1);
glVertex2f((obj.getX()-cam.getX())+obj.getSizeX(), (obj.getY()-cam.getY())+obj.getSizeY());
glTexCoord2f(0,1);
glVertex2f((obj.getX()-cam.getX()), (obj.getY()-cam.getY())+obj.getSizeY());
glEnd();
}
obj.getTex().release();
}
}
There is no error the Texture is just not displayed. I use this method to load the images:
public static Texture getTex(String path)
{
Texture texture = null;
try {
texture = TextureLoader.getTexture("PNG", ResourceLoader.getResourceAsStream(path));
} catch (FileNotFoundException e) {
e.printStackTrace();
Display.destroy();
System.exit(1);
} catch (IOException e) {
e.printStackTrace();
Display.destroy();
System.exit(1);
}
return texture;
}
This is my main game loop:
public static Player player = new Player(0, 0, 0, 0, 20, 20, 2, null);
public static Camera cam = new Camera(0, 0);
static ArrayList<GameObject> toRender = new ArrayList<GameObject>();
public static void main(String[] args) {
Renderer.createDisplay();
toRender.add(new Wall(300, 300, 200, 100, IO.getTex("res/Terrain/Grass.png")));
toRender.add(player);
player.setTex(IO.getTex("res/Entities/Player/Player.png"));
while(!Display.isCloseRequested())
{
Renderer.updateDisplay();
Input.updateInput();
player.update();
Renderer.renderDisplay(toRender, cam);
}
Renderer.destroyDisplay();
System.exit(0);
}
Its just displayed a white quad instead of a textured one.
To render Texture load with slick on LWJGL quads you need to bind the texture before draw the quads
just try
texture.bind(); //texture = your Texture name
before
glBegin(GL_QUADS);
I'm currently developing a game where you have to avoid Asteroids. To make the Game look same on every device I use the FitViewport. Unfortunately I somehow get White Bars on the top and on the Bottom instead of Black ones. My Game Background is also white, so it looks a bit weird.
GameScreen:
#Override
public void create()
{
float aspectRatio = (float)Gdx.graphics.getWidth() / (float)Gdx.graphics.getHeight();
cam = new OrthographicCamera();
viewport = new FitViewport(MyGdxGame.WIDTH * aspectRatio, MyGdxGame.HEIGHT, cam);
[...]
}
#Override
public void render(SpriteBatch batch)
{
cam.update();
batch.setProjectionMatrix(cam.combined);
batch.begin();
em.render(batch); //render Ship and Asteroids
[...]
}
#Override
public void resize(int width, int height)
{
viewport.update(width, height);
cam.position.set(MyGdxGame.WIDTH / 2, MyGdxGame.HEIGHT /2, 0);
}
I dragged the Ship into the white Bar.
LibGDX provides viewports as a more convenient way of dealing with different aspect ratios. You don't have to multiply MyGdxGame.WIDTH with aspectRatio. Just initialize it with MyGdxGame.WIDTH and MyGdxGame.HEIGHT.
Also, in resize function, you can change the cam position using viewport values (instead of using constants):
cam.position.set(cam.viewportWidth / 2, cam.viewportHeight / 2, 0);
I found some issues in your code. for best practice while handling with the different screen ratio just try with the fill viewPort. Here is simply editing your code with the fill viewport . Just try it once.
#Override
public void create()
{
float aspectRatio = (float)Gdx.graphics.getWidth() / (float)Gdx.graphics.getHeight();
camera = new OrthographicCamera();
camera.position.set(0, 0, 0);
camera.update();
//1280 is the screen width and 800 is screen height
camera.setToOrtho(false, 1280, 800);
viewPort = new FillViewport(1280, 800, camera);
}
#Override
public void render(SpriteBatch batch)
{
batch.setProjectionMatrix(camera.combined);
batch.begin();
em.render(batch); //render Ship and Asteroids
[...]
}
#Override
public void resize(int width, int height)
{
viewPort.update(width, height);
}
just try with the above code . it will definitely work
I have a simple application that displays a 3D cube that rotates on all axes, and a camera controlled via mouse that allows you to adjust the angle you're looking at the cube.
The entire application works exactly as I want when I use glOrtho, but once I change it to gluPerspective I only get a black screen.
Here is my method to initialize openGL:
public void initializeOpenGL()
{
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(45.0f, ((float)WIDTH) / ((float)HEIGHT), 0.01f, 500f);
//glOrtho(0, 640, 480, 0, 600, -1); //displays everything correctly
glMatrixMode(GL_MODELVIEW);
glEnable(GL_DEPTH_TEST);
}
And then here is my loop method:
public void begin()
{
float degrees = 0;
Mouse.setGrabbed(false);
while(!Display.isCloseRequested())
{
moveCamera(); //calculates the changes in mouse position
GL11.glLoadIdentity();
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
camera.lookThrough(); //applies the changes
glTranslatef((float)WIDTH/2,(float)HEIGHT/2,10f);
glRotatef(degrees++,1f,1f,1f);
glScalef(100,100,100);
drawQuad();
Display.update();
Display.sync(60);
}
Display.destroy();
System.exit(0);
}
I created an image displaying where the camera looks: http://i.imgur.com/9NVSyqj.png
As you can see the camera looks along the -z axis
-> you should try translating the quad to something like:
glTranslatef(0,0, -10f );
Instead of moving the quad to the middle of the Display you move it half the size of the Display in the nowhere of your Landscape
SHORT VERSION: Gist: https://gist.github.com/Chronove/11da12b2635bfc040981
package me.tutorial;
import static org.lwjgl.opengl.GL11.*;
import static org.lwjgl.util.glu.GLU.gluPerspective;
import org.lwjgl.opengl.Display;
import org.lwjgl.opengl.DisplayMode;
/**
* #author Chronove
*/
public class Example {
public static void main(String[] args) throws Exception {
int WIDTH = 600;
int HEIGHT = 400;
// INIT
Display.setDisplayMode(new DisplayMode(WIDTH,HEIGHT));
Display.create();
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(45.0f,(float)(WIDTH / HEIGHT),0.1f,500f);
glMatrixMode(GL_MODELVIEW);
glEnable(GL_DEPTH_TEST);
float degrees = 0;
while(!(Display.isCloseRequested())){
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glLoadIdentity();
glTranslatef(0,0,-10f);
glRotatef(degrees++,0f,0f,1f);
// drawQuad();
{
glBegin(GL_QUADS);
glVertex3f(-1f,-1f,0f);
glVertex3f( 1f,-1f,0f);
glVertex3f( 1f, 1f,0f);
glVertex3f(-1f, 1f,0f);
glEnd();
}
Display.update();
Display.sync(60);
}
Display.destroy();
System.exit(0);
}
}
Alright, so I started learning LWJGL through a few tutorials of TheCodingUniverse, but I've hit a wall at drawing lines and quads.
The code
package LWJGL_Learn;
import static org.lwjgl.opengl.GL11.*;
import org.lwjgl.opengl.*;
import org.lwjgl.*;
public class SimpleOGLRenderer {
public SimpleOGLRenderer() {
try {
Display.setDisplayMode(new DisplayMode(640, 480));
Display.setTitle("SimpleOGLRenderer");
//Display.setInitialBackground(256, 256, 256);
Display.create();
} catch (LWJGLException e) {
e.printStackTrace();
}
//OpenGL Initialization
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(0, 640, 480, 0, 1, -1);
glMatrixMode(GL_MODELVIEW);
while (!Display.isCloseRequested()) {
//Render Code'
glBegin(GL_QUADS);
glVertex2i(50, 50);
glVertex2i(80, 70);
glVertex2i(80, 130);
glVertex2i(50, 300);
glEnd();
glBegin(GL_LINES);
glVertex2i(100, 100);
glVertex2i(200, 200);
glEnd();
GL11.glClear(GL11.GL_COLOR_BUFFER_BIT);
Display.update();
Display.sync(60);
}
Display.destroy();
System.exit(0);
}
public static void main(String[] args) {
new SimpleOGLRenderer();
}
}
Refer to around 6:50 minutes in this video to see what the code is supposed to be, and what its supposed to do.
Anyway, the problem is that no lines or quads show up. The screen stays black. Now, I thought maybe it was because black lines were being drawn on a black display so I modified the background color (the commented out line which went like .setInitialDisplay...), but with no result. The color changed, but the screen stayed white and no lines appeared. Do any of you guys know what I'm doing wrong?
1) The default color is white, but you are clearing the color buffer right before doing the Display.update()
remove:
GL11.glClear(GL11.GL_COLOR_BUFFER_BIT);
2) You're not using the coordinates from the video, right before 6:50.
The problem i am encountering is that i cannot get my texture to render in the correct proportions and for some reason the texture is also repeating itself with a space inbetween.
this is the texture im using(i am trzing to fill the screen with this texture):
When rendered it looks like this(red outline is the entire screen and texture is rendered with a 1 px border):
and here is the code:
package game;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import org.lwjgl.input.Keyboard;
import org.lwjgl.opengl.Display;
import org.lwjgl.opengl.DisplayMode;
import org.lwjgl.opengl.GL11;
import org.lwjgl.util.Timer;
import org.lwjgl.util.glu.GLU;
import org.newdawn.slick.opengl.TextureLoader;
public class WarZone {
private boolean done = false;
private String windowTitle = "War Zone";
private DisplayMode displayMode;
private Timer timer;
private float dt;
public static void main(String[] args) {
new WarZone().run(false);
}
public void run(boolean fullscreen) {
try {
init();
switchToOrtho();
while (!done) {
timer.tick();
update();
render();
Display.update();
}
cleanup();
} catch (Exception e) {
e.printStackTrace();
System.exit(0);
}
}
private void update() {
// Exit if Escape is pressed or window is closed
if (Keyboard.isKeyDown(Keyboard.KEY_ESCAPE) || Display.isCloseRequested()) {
done = true;
return;
}
}
private boolean render() {
GL11.glClear(GL11.GL_COLOR_BUFFER_BIT | GL11.GL_DEPTH_BUFFER_BIT); // Clear the screen and the depth buffer
GL11.glLoadIdentity(); // Reset the current modelview matrix
int w = displayMode.getWidth();
int h = displayMode.getHeight();
GL11.glColor3f(1, 0, 0);
GL11.glBindTexture(GL11.GL_TEXTURE_2D, 0);
GL11.glBegin(GL11.GL_QUADS);
GL11.glVertex2i(0, 0);
GL11.glVertex2i(w, 0);
GL11.glVertex2i(w, h);
GL11.glVertex2i(0, h);
GL11.glEnd();
//if(true)return false;
GL11.glColor3f(0, 1, 1);
GL11.glBindTexture(GL11.GL_TEXTURE_2D, 1);
GL11.glBegin(GL11.GL_QUADS);
GL11.glTexCoord2f(0, 0);
GL11.glVertex2i(1, 1);
GL11.glTexCoord2f(1, 0);
GL11.glVertex2i(w - 1, 1);
GL11.glTexCoord2f(1, 1);
GL11.glVertex2i(w - 1, h - 1);
GL11.glTexCoord2f(0, 1);
GL11.glVertex2i(1, h - 1);
GL11.glEnd();
return true; // Rendered correctly
}
public static void switchToOrtho() {
GL11.glDisable(GL11.GL_DEPTH_TEST);
GL11.glDisable(GL11.GL_LIGHTING);
GL11.glMatrixMode(GL11.GL_PROJECTION);
GL11.glPushMatrix();
GL11.glLoadIdentity();
GL11.glOrtho(0, Display.getDisplayMode().getWidth(), 0, Display.getDisplayMode().getHeight(), -1, 1);
GL11.glMatrixMode(GL11.GL_MODELVIEW);
GL11.glLoadIdentity();
}
public static void switchToFrustum() {
GL11.glEnable(GL11.GL_DEPTH_TEST);
GL11.glEnable(GL11.GL_LIGHTING);
GL11.glMatrixMode(GL11.GL_PROJECTION);
GL11.glPopMatrix();
GL11.glMatrixMode(GL11.GL_MODELVIEW);
}
private void init() throws Exception {
createWindow();
initGL();
load();
}
private void load() throws FileNotFoundException, IOException {
TextureLoader.getTexture("BMP", new FileInputStream("res/temp/Main_Menu_Play_Button.bmp"), true).getTextureID();
}
private void createWindow() throws Exception {
DisplayMode availibleDisplayModes[] = Display.getAvailableDisplayModes();
for (DisplayMode d:availibleDisplayModes) {
if (d.getWidth() == 640 && d.getHeight() == 480 && d.getBitsPerPixel() == 32) {
displayMode = d;
break;
}
}
Display.setDisplayMode(displayMode);
Display.setTitle(windowTitle);
Display.create();
}
private void initGL() {
GL11.glEnable(GL11.GL_TEXTURE_2D); // Enable texture mapping
GL11.glShadeModel(GL11.GL_SMOOTH); // Enable smooth shading
GL11.glClearColor(0.0f, 0.0f, 0.0f, 0.0f); // Black background
GL11.glClearDepth(1.0f); // Depth buffer setup
GL11.glEnable(GL11.GL_DEPTH_TEST); // Enables depth testing
GL11.glDepthFunc(GL11.GL_LEQUAL); // Type of depth testing
GL11.glMatrixMode(GL11.GL_PROJECTION); // Select projection matrix
GL11.glLoadIdentity(); // Reset the projection matrix
// Calculate the aspect ratio of the window
GLU.gluPerspective(45.0f, (float)displayMode.getWidth() / (float)displayMode.getHeight(), 0.1f, 100.0f);
GL11.glMatrixMode(GL11.GL_MODELVIEW);// Select the modelview matrix
GL11.glHint(GL11.GL_PERSPECTIVE_CORRECTION_HINT, GL11.GL_NICEST);// Most precise perspective calculations
}
public void requestFinish() {
done = true;
}
private void cleanup() {
Display.destroy();
}
}
I would reallz appreciate it if someone could tell me what i had done wrong.
First, I don't know what TextureLoader or newdawn.slick.opengl are, so there is only limited information I can give about this.
However, it is very possible that your texture loading code does not know how to handle non-power-of-two textures. Which means it is likely padding the texture's size out to the nearest power of two.
More importantly is this:
GL11.glColor3f(0, 1, 1);
GL11.glBindTexture(GL11.GL_TEXTURE_2D, 1);
GL11.glBegin(GL11.GL_QUADS);
GL11.glTexCoord2f(0, 0);
GL11.glVertex2i(1, 1);
GL11.glTexCoord2f(1, 0);
GL11.glVertex2i(w - 1, 1);
GL11.glTexCoord2f(1, 1);
GL11.glVertex2i(w - 1, h - 1);
GL11.glTexCoord2f(0, 1);
GL11.glVertex2i(1, h - 1);
GL11.glEnd();
This will draw a screen-sized quad (assuming that w and h are screen sizes). This quad maps the entire area of the texture to this quad. OpenGL is only doing what you told it to do: take the texture and map it to the quad.
If you want to draw a texture with pixel accuracy (1:1 texel to pixel), then you need to provide a width and height to the vertex positions that is equal to the texture's size, not the screen size.
Also, you set the color to (0, 1, 1). The default texture environment will multiply the per-vertex color by the texel values fetched from the texture. So you should either set the color to white, or change the texture environment.
OpenGL Doesn't like textures that are not powers of two if I recall. Is your texture a power of 2 for both height and width?
http://www.gamedev.net/topic/466904-opengl-textures-only-power-of-two/