The following code shows a torus slowly revolving and coming into display:
package com.objloader.example;
import ...
public class ObjLoaderProg implements ApplicationListener{
String torus;
Mesh model;
private PerspectiveCamera camera;
#Override
public void create() {
InputStream stream=null;
try {
stream = new FileInputStream(Gdx.files.internal("data/torus.obj").path());
} catch (FileNotFoundException e) {
e.printStackTrace();
}
model = ObjLoader.loadObj(stream, true);
Gdx.gl.glEnable(GL10.GL_DEPTH_TEST);
Gdx.gl10.glTranslatef(0.0f,0.0f,-3.0f);
}
#Override
public void dispose() {
}
#Override
public void pause() {
}
protected int lastTouchX;
protected int lastTouchY;
protected float rotateZ=0.01f;
protected float increment=0.01f;
#Override
public void render() {
Gdx.gl.glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
Gdx.gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT);
camera.update();
camera.apply(Gdx.gl10);
Gdx.gl10.glTranslatef(0.0f,0.0f,-3.0f);
Gdx.gl10.glRotatef(rotateZ, rotateZ, 5.0f, rotateZ);
model.render(GL10.GL_TRIANGLES);
if (Gdx.input.justTouched()) {
lastTouchX = Gdx.input.getX();
lastTouchY = Gdx.input.getY();
} else if (Gdx.input.isTouched()) {
camera.rotate(0.2f * (lastTouchX - Gdx.input.getX()), 0, 1.0f, 0);
camera.rotate(0.2f * (lastTouchY - Gdx.input.getY()), 1.0f, 0, 0);
lastTouchX = Gdx.input.getX();
lastTouchY = Gdx.input.getY();
}
rotateZ+=increment;
System.out.println(""+rotateZ);
}
#Override
public void resize(int arg0, int arg1) {
float aspectRatio = (float) arg0 / (float) arg1;
camera = new PerspectiveCamera(67, 2f * aspectRatio, 2f);
camera.near=0.1f;
camera.translate(0, 0, 0);
}
#Override
public void resume() {
}
}
It renders a torus obj that's saved in the data folder, and by clicking and dragging on the screen the user can rotate the camera.
This works fine on the desktop, but when I try to run it on android, I get a NullPointerException at:
model.render(GL10.GL_TRIANGLES);
I've tried placing torus.obj just inside assets, and within assets/data. I'm using libgdx 0.9.2.
I assume you are referring to model.render(GL10.GL_TRIANGLES);. I believe you have two problems. First, model is null because you are catching a FileNotFoundException and ignoring it. I suggest you don't catch the FileNotFoundException right now, let it crash, and look at the stack trace. That will give you a better indication of why this failing. Note that e.printStackTrace() is not useful for debugging on android, try using the gdx log.
The second problem is that I suspect the path/stream is actually going to the wrong place. Instead of creating a FileInputStream, use the FileHandle.read() function. It returns a java.io.InputStream that you can pass to ObjLoader.loadObj().
in = Gdx.files.internal("data/torus.obj").read();
model ObjLoader.loadObj(in);
in.close();
The difference between this and your code is that FileHandle.read() in libgdx's android backend uses the android AssetManager to open files that are bundled with the program.
Finally, copy the torus.obj file to <YourAndroidProject>/assets/data/torus.obj.
An aside: if you specify the line number, please provide the full file otherwise the line will be off. Line 52 of the code you have provided is: lastTouchY = Gdx.input.getY();. Note the "import ..." at the beginning of your code. Those imports affect the line number.
Related
I am trying to render an OrthogonalTiledMap I created using the map editor Tiled however for some reason nothing is showing up in my game screen; all I get is a black image being shown. I am using the Libgdx framework which has features for exactly these kinds of maps already built in however they won't work for me.
Libdgx also provides an example of rendering OrthogonalTiledMaps however it is outdated but I adjusted it to current Libdgx version but as already stated it doesn't work.
There are no errors nor exceptions being thrown. The .tmx file does also not contain any errors. All the used tileset are present and do not cause any errors.
This is my code:
`
public class My_Game extends ApplicationAdapter {
private TiledMap map;
private TiledMapRenderer renderer;
private OrthographicCamera camera;
private CameraInputController cameraController;
#Override
public void create () {
float w = Gdx.graphics.getWidth();
float h = Gdx.graphics.getHeight();
camera = new OrthographicCamera();
camera.setToOrtho(true, w/8f, h/8f);
camera.update();
cameraController = new CameraInputController(camera);
Gdx.input.setInputProcessor(cameraController);
map = new TmxMapLoader().load("map.tmx");
renderer = new OrthogonalTiledMapRenderer(map, 1f / 8f);
}
#Override
public void render () {
camera.update();
renderer.setView(camera);
renderer.render();
}
#Override
public void dispose () {
map.dispose();
}
}`
Was a while since I did Libgdx so I might be thinking of something else, but don't you have to do some clearing in the render() function?
Try adding:
Gdx.gl.glClearColor(1, 0, 0, 1);
Gdx.gl.glBlendFunc(GL20.GL_SRC_ALPHA, GL20.GL_ONE_MINUS_SRC_ALPHA);
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
as the first three lines there and let me know if that helps.
On my 854 x 480 LG Leon it renders fine, but on a larger screen resolution (2560 x 1440) this happens: http://imgur.com/a/rcbJK.
The code for processing the text is: http://imgur.com/a/c316e.
I've tried expanding the bounds of the Label because I thought that it might be constricting the text, but it still won't display properly.
What could be causing this?
The different mobile phone has the different aspect ratio in their screen size . that is the reason it shows different different screen. to avoid this problem you must use the viewPort. So you will be able to handle the different screen size. for more details, you must read the libgdx documentation. here I'm posting a sample code which can help you to handle the different screen size. there are three kinds of viewports mainly using
1) fillviewport
2) fitviewPort
3)stretchviewport
here is the documentation in detail.
https://libgdx.badlogicgames.com/nightlies/docs/api/com/badlogic/gdx/utils/viewport/FillViewport.html
public class myGame extends ApplicationAdapter {
public OrthographicCamera camera;
public Viewport viewPort;
private SpriteBatch batch;
public myGame() {
}
#Override
public void create() {
float w = Gdx.graphics.getWidth();
float h = Gdx.graphics.getHeight();
camera = new OrthographicCamera();
camera.position.set(0, 0, 0);
camera.update();
camera.setToOrtho(false, 1280, 800);
viewPort = new FillViewport(1280, 800, camera);
}
#Override
public void dispose() {
batch.dispose();
}
#Override
public void render() {
Gdx.gl.glClearColor(1, 1, 1, 1);
Gdx.gl.glClear(GL30.GL_COLOR_BUFFER_BIT);
float deltaTime = Gdx.graphics.getDeltaTime();
batch.setProjectionMatrix(camera.combined);
batch.begin();
batch.draw(sprie,0,0)
batch.end();
}
#Override
public void resize(int width, int height) {
viewPort.update(width, height);
}
#Override
public void pause() {
}
#Override
public void resume() {
}
}
// don't copy paste it . just try to understand and implement it.
You should use Scene2D and ViewPort.
Also , be careful to use coordinates (i.e : x: 64 , y:32 changes in every different screen size)
This is the common issue when your running your game in multiple devices. Because your game is running in different aspect ratios in different screens . it's generally called the multi screen issue. To solve this problem the libgdx is providing it's on class called the viewPort. Mainly you can see three viewpors.
1)Fill viewPort.
2)Fit viewPort.
3)stretch viewport.
For more details you can go through the libgdx documentation. Here im posting some example code which can solve your multi screen issues.
public class myGame extends ApplicationAdapter {
public OrthographicCamera camera;
public Viewport viewPort;
private SpriteBatch batch;
private BitmapFont myScoreFont;
//General screen resolution
public int APP_WIDTH=1280;
public int APP_HEIGHT=800;
public int fontPositionIn_X=600;
public int fontPositionIn_Y=400;
public myGame() {
}
#Override
public void create() {
myScoreFont = new BitmapFont(Gdx.files.internal(Constants.PATH_TO_MY_SCORE_FONT), true);
batch = new SpriteBatch();
float w = Gdx.graphics.getWidth();
float h = Gdx.graphics.getHeight();
camera = new OrthographicCamera();
camera.position.set(0, 0, 0);
camera.update();
camera.setToOrtho(false, APP_WIDTH, APP_HEIGHT);
viewPort = new fillViewPort(1280, 800, camera);
}
#Override
public void dispose() {
batch.dispose();
}
#Override
public void render() {
Gdx.gl.glClearColor(1, 1, 1, 1);
Gdx.gl.glClear(GL30.GL_COLOR_BUFFER_BIT);
float deltaTime = Gdx.graphics.getDeltaTime();
batch.setProjectionMatrix(camera.combined);
batch.begin();
myScoreFont.draw(batch,"any texts", fontPositionIn_X, fontPositionIn_Y)
batch.end();
}
#Override
public void resize(int width, int height) {
viewPort.update(width, height);
}
#Override
public void pause() {
}
#Override
public void resume() {
}
}
so by using the viewPort you can be able to play your game in all the different screens.
I am using the following class to render an atlas on screen:
public class AnimationDemo implements ApplicationListener {
private SpriteBatch batch;
private TextureAtlas textureAtlas;
private Animation animation;
private float elapsedTime = 0;
#Override
public void create() {
batch = new SpriteBatch();
textureAtlas = new TextureAtlas(Gdx.files.internal("data/packOne.atlas"));
animation = new Animation(1 / 1f, textureAtlas.getRegions());
}
#Override
public void dispose() {
batch.dispose();
textureAtlas.dispose();
}
#Override
public void render() {
Gdx.gl.glClearColor(0, 0, 0, 1);
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
batch.begin();
//sprite.draw(batch);
elapsedTime += Gdx.graphics.getDeltaTime();
batch.draw(animation.getKeyFrame(elapsedTime, true), 0, 0);
batch.end();
}
#Override
public void resize(int width, int height) {
}
#Override
public void pause() {
}
#Override
public void resume() {
}
}
I am a beginner with libGDX, however with the above program my images are not rendered in order as random images appear. I was earlier using the following with the same . atlas file and it was working properly:
public class MyGdxGame implements ApplicationListener {
private SpriteBatch batch;
private TextureAtlas textureAtlas;
private Sprite sprite;
private int currentFrame = 1;
private String currentAtlasKey = new String("0001");
#Override
public void create() {
batch = new SpriteBatch();
textureAtlas = new TextureAtlas(Gdx.files.internal("data/packOne.atlas"));
TextureAtlas.AtlasRegion region = textureAtlas.findRegion("0001");
sprite = new Sprite(region);
sprite.setPosition(Gdx.graphics.getWidth() / 2 - sprite.getWidth() / 2, Gdx.graphics.getHeight() / 2 - sprite.getHeight() / 2);
sprite.scale(4.5f);
Timer.schedule(new Timer.Task() {
#Override
public void run() {
currentFrame++;
if (currentFrame > 393)
currentFrame = 1;
// ATTENTION! String.format() doesnt work under GWT for god knows why...
currentAtlasKey = String.format("%04d", currentFrame);
sprite.setRegion(textureAtlas.findRegion(currentAtlasKey));
}
}
, 0, 1 / 30.0f);
}
#Override
public void dispose() {
batch.dispose();
textureAtlas.dispose();
}
#Override
public void render() {
Gdx.gl.glClearColor(0, 0, 0, 1);
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
batch.begin();
sprite.draw(batch);
batch.end();
}
#Override
public void resize(int width, int height) {
}
#Override
public void pause() {
}
#Override
public void resume() {
}
}
Any hints about what might be wrong here?
I am also trying to adapt my program with Screen Viewport any headings as in how to implement this would also be welcome.
Edit: The .atlas file is located here
Your atlas file isn't ordered. If you call the code below, it will be ordered.
regions.sort(new Comparator<AtlasRegion>() {
#Override
public int compare(AtlasRegion o1, AtlasRegion o2) {
return Integer.parseInt(o1.name) > Integer.parseInt(o2.name) ? 1 : -1;
}
});
But I'm still checking why your atlas regions isn't ordered.
you should create array with frames ordered alphabetically instead of using textureAtlas.getRegions() which just gives you an array without caring of order.
The example for atlas with regions named like: region1, region2 and so on would be:
AtlasRegion[] frames = new AtlasRegion[framesCount];
for(int i = 0; i < framesCount; i++)
{
frames[i] = atlas.findRegion("region" + i);
}
so you can adjust it to your regions names.
If you want to get all frames from textureAtlas you can also do it like this:
Array<String> names = new Array<String>();
for(AtlasRegion region : textureAtlas.getRegions())
{
names.add( region.name );
}
names.sort();
Array<AtlasRegion> frames = new Array<AtlasRegion>();
for(String s : names)
{
frames.add( textureAtlas.findRegion(s) );
}
and then after get frames array just create animation object:
animation = new Animation(1/1f, frames.items); //or just frames depending on which type frames is
TexturePacker will index the images for you as long as you follow the naming scheme set forth here https://github.com/libgdx/libgdx/wiki/Texture-packer#image-indexes.
so your frames would be named something like
anim1_001.png
anim1_002.png
...
anim1_100.png
and a separate animation would simply be
anim2_001.png
....
anim2_100.png
EDIT:
additionally you can get the regions only related to certain animations. So instead of
animation = new Animation(1 / 1f, textureAtlas.getRegions());
you could use (yes it's findRegions() not findRegion()):
animation1 = new Animation(1 / 1f, textureAtlas.findRegions("anim1"));
animation2 = new Animation(1 / 1f, textureAtlas.findRegions("anim2"));
EDIT2:
If you're are using a stage it is quite easy to implement a screen viewport. I do it like this, (stage is a field and this step is in the show/create method):
stage = new Stage(new ScreenViewport());
Then in the resize method:
stage.getViewport().update(width, height, true);
Without a stage it's only slightly more complex
camera = new WhateverCamera();
viewport = new ScreenViewport(camera);
Then in the resize method:
viewport.update(width, height, true);
Use whatever camera you want, WhateverCamera is a placeholder and can be OrthographicCamera or PerspectiveCamera.
The last argument true centers the camera, if you don't want to do this set it to false or leave it out, it assumes false.
The problem
I cannot seem to be able to get Tiled maps to render properly. I am using LibGDX as a library for loading the map (Release 1.6.0).
Video demonstration
I have created a video to show you the actual problem and make things easier by skipping the whole process of explaining it. Here is a link to it.
The code I've used
protected Level level;
protected OrthogonalTiledMapRenderer mapRenderer;
protected OrthographicCamera camera;
protected TiledMap map;
protected MainGameLoop game;
protected SpriteBatch batch;
private BitmapFont font;
private int w, h;
public Level1(MainGameLoop game) {
this.game = game;
}
#Override
public void show() {
w = Gdx.graphics.getWidth();
h = Gdx.graphics.getHeight();
int CAMERA_WIDTH = 800;
int CAMERA_HEIGHT = 450 * (w / h);
camera = new OrthographicCamera(CAMERA_WIDTH, CAMERA_HEIGHT);
camera.setToOrtho(false);
camera.update();
map = new TmxMapLoader().load("maps/map1.tmx");
mapRenderer = new OrthogonalTiledMapRenderer(map);
Gdx.input.setInputProcessor(this);
font = new BitmapFont();
font.setColor(Color.BLUE);
batch = new SpriteBatch();
}
#Override
public void render(float delta) {
Gdx.gl.glClearColor(1, 1, 1, 1);
Gdx.gl.glBlendFunc(GL20.GL_SRC_ALPHA, GL20.GL_ONE_MINUS_SRC_ALPHA);
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
camera.update();
mapRenderer.setView(camera);
mapRenderer.render();
batch.begin();
font.draw(batch, "Camera zoom: " + camera.zoom, 40, 40);
batch.end();
}
#Override
public void resize(int width, int height) {
camera.viewportWidth = width;
camera.viewportHeight = height;
camera.update();
}
#Override
public void dispose() {
mapRenderer.dispose();
map.dispose();
background.dispose();
Gdx.input.setInputProcessor(null);
}
#Override
public boolean scrolled(int amount) {
camera.zoom += amount;
camera.update();
return true;
}
// Here go the rest of the methods, such as pause, resume, hide, keyDown, keyUp, keyTyped, touchDown, touchUp, touchDragged & mouseMoved.
Solutions I've tried
I have tried using different numbers for the camera's x and y with no luck. I have also tried tranlating the camera to the proper position (hardcoded it), as well as using another map (different tilemap and dimensions) but that did not work either.
Conclusion
I can't seem to find a way to fix this problem. Any help is much appreciated. Thank you very much.
Quick introduction
Ok after a good while, I managed to solve this matter by hardcoding some stuff. But it works properly, so I am happy with it.
What I did to solve the problem
First of all, I found out the exact number I had to use to scale up my Tiled map, which is this number: 3.125f .
Then, instead of using pixels for the camera, I used my own units (something I should have done from the the first moment).
After doing those two things, I noticed that the map was zoomed in a lot. So, by using the scrolled method from the InputProcessor, I managed to find the exact number the map had to be "unzoomed".
I also found out that if I call the setToOrtho(false) method from the OrthographicCamera object, it zooms the map in 19 times for some weird reason. If that method does not get called, the map is zoomed in only 1 time
The code I am currently using
TiledMap tiledMap;
OrthographicCamera camera;
TiledMapRenderer tiledMapRenderer;
final float WIDTH = 8000;
final float HEIGHT = 4500;
final float num = 3.125f;
#Override
public void show() {
tiledMap = MapLoader.realm1_level1;
tiledMapRenderer = new OrthogonalTiledMapRenderer(tiledMap, num);
camera = new OrthographicCamera(WIDTH, HEIGHT);
Gdx.input.setInputProcessor(this);
camera.zoom += 1f;
camera.update();
}
#Override
public void render(float delta) {
Gdx.gl.glClearColor(1, 1, 1, 1);
Gdx.gl.glBlendFunc(GL20.GL_SRC_ALPHA, GL20.GL_ONE_MINUS_SRC_ALPHA);
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
tiledMapRenderer.setView(camera);
tiledMapRenderer.render();
}
// This method was just used for testing to see where
// the map was or should have been placed.
#Override
public boolean keyDown(int keycode) {
if (keycode == Input.Keys.LEFT)
camera.translate(-32, 0);
if (keycode == Input.Keys.RIGHT)
camera.translate(32, 0);
if (keycode == Input.Keys.UP)
camera.translate(0, 32);
if (keycode == Input.Keys.DOWN)
camera.translate(0, -32);
if (keycode == Input.Keys.NUM_1)
tiledMap.getLayers().get(0).setVisible(!tiledMap.getLayers().get(0).isVisible());
return true;
}
#Override
public void resize(int width, int height) {
camera.position.set(WIDTH, HEIGHT, 0);
camera.update();
}
#Override
public boolean scrolled(int amount) {
camera.zoom += amount;
camera.update();
return true;
}
#Override
public void dispose() {
tiledMap.dispose();
}
// And here go the rest of the methods that come from the
//Screen and the InputProcessor interfaces.
Notes
The numbers I used for the WIDTH and the HEIGHT variables work properly, strictly with tiled maps that their width is 80 tiles, and their height is 45 tiles.
If you are facing the same problem, you'll have to find the appropriate number to scale your map up/down, depending on the unit numbers you're using. Trial and error is your only guide. If we ignore StackOverflow of course.
I've been programming for a few years now and wanted to try Java LWJGL, and people recommended using the Slick-Util library so I set all of it up, etc. and I've been working on several projects, never encountering this problem. However, I've encountered a problem where when binding a texture to openGL, the same incorrect texture is instead bound every time. I ran into this problem first with a project with a bunch of classes etc, and chose to try to condense the problem into one jar file.
So before I show the code, I wanna explain how the example file works. Basically, there are four PNG's within my project. They are contained in res/textures/character/texturesHere. The names of the PNG's consist as: char_d.png, char_u.png, char_l.png, char_r.png. I've checked all four and all four have different textures of the character's direction, as it should be. This is to prove that the resources of the project are NOT the problem. Here is the entire problem condensed into a "Main" class file.
package main_p;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import org.lwjgl.LWJGLException;
import org.lwjgl.opengl.*;
import org.newdawn.slick.opengl.Texture;
import org.newdawn.slick.opengl.TextureLoader;
import static org.lwjgl.opengl.GL11.*;
public class Main
{
public final int srcWidth = 1280;
public final int srcHeight = 720;
public float x = 150;
public float y = 150;
public float w = 40;
public float h = 40;
public Texture char_down;
public Texture char_right;
public Texture char_left;
public Texture char_up;
public Main()
{
try
{
Display.setTitle("Escape Alpha v0.0.1");
Display.setDisplayMode(new DisplayMode(srcWidth, srcHeight));
Display.create();
}
catch (LWJGLException e)
{
e.printStackTrace();
}
initGL();
initTextures();
loop();
}
public void loop()
{
glClear(GL_COLOR_BUFFER_BIT);
while (!Display.isCloseRequested())
{
glBegin(GL_QUADS);
char_left.bind();
glTexCoord2f(0, 0);
glVertex2f(x, y);
glTexCoord2f(1, 0);
glVertex2f(x + w, y);
glTexCoord2f(1, 1);
glVertex2f(x + w, y + h);
glTexCoord2f(0, 1);
glVertex2f(x, y + h);
glEnd();
Display.update();
Display.sync(60);
}
Display.destroy();
}
public void initGL()
{
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(0, srcWidth, srcHeight, 0, 1, -1);
glMatrixMode(GL_MODELVIEW);
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
}
public void initTextures()
{
char_down = loadTextureFrom("character/char_d.png");
char_up = loadTextureFrom("character/char_u.png");
char_left = loadTextureFrom("character/char_l.png");
char_right = loadTextureFrom("character/char_r.png");
}
public Texture loadTextureFrom(String path)
{
try
{
return TextureLoader.getTexture("PNG", new FileInputStream(new File("res/textures/" + path)));
}
catch (FileNotFoundException e)
{
e.printStackTrace();
}
catch (IOException e)
{
e.printStackTrace();
}
return null;
}
public static void write(Object ob)
{
System.out.println(ob);
}
public static void main(String[] args)
{
new Main();
}
}
One thing I've noticed is that within the initTextures() method, if I change the LAST loaded texture, ANY texture I bind will end up rendering the last texture loaded in initTextures()
In this example I bind Texture char_left, but instead it uses char_right, because it was the last one loaded in my initTextures() method. I can prove this because if I change whichever texture is LAST loaded in my initTextures() method, it ends up rendering that one instead, again disregarding the texture I tell it to bind. Like I said, I've checked all of my PNG's multiple times, and they all look good, and show the character facing the correct direction. My loadTextureFrom(String path) method is as any other texture loader. Nothing special about it really. I actually am using this exact method in 90% of my 2D projects for Java LWJGL / Slick-Util, and I've only recently started running into this problem. I'm at a loss for words, and have never ran into this problem before. Any help is greatly appreciated. :)
Edit 1:
I just did an important test. I checked the HashCode of all four textures, AFTER loading them within the initTextures() method.
public void initTextures()
{
char_left = loadTextureFrom("character/char_l.png");
char_right = loadTextureFrom("character/char_r.png");
char_down = loadTextureFrom("character/char_d.png");
char_up = loadTextureFrom("character/char_u.png");
write(System.identityHashCode(char_left));
write(System.identityHashCode(char_right));
write(System.identityHashCode(char_down));
write(System.identityHashCode(char_up));
}
It returned this:
1364345882
1878339755
1246651385
1619367563
I think this truly proves that the initTextures() method isn't the problem. Once again, any help is appreciated! This kind of 100% holds me back from doing any more work on any projects :/ Thanks! :)
I know this is an old post but I don't want anyone who sees this to go answerless. Basically, the texture bind call has to be outsde the "glBegin". That's all the problem is. You cannot bind textures inside of the glBegin call. If you don't do this, gl will just bind the last texture loaded.
I dont know if this will actually help but you have a problem in your loop method. Basically you are not clearing you screen. You do glClear(GL_COLOR_BUFFER_BIT); before your loop. Another thing that might cause this sort of problem is that you actually have to enable and disable GL_BLEND in a loop. Also almost forgot you didn't enable glEnable(GL_TEXTURE_2D); in your initGl() method.
public void loop()
{
while (!Display.isCloseRequested())
{
glClear(GL_COLOR_BUFFER_BIT);
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glBegin(GL_QUADS);
char_left.bind();
glTexCoord2f(0, 0);
glVertex2f(x, y);
glTexCoord2f(1, 0);
glVertex2f(x + w, y);
glTexCoord2f(1, 1);
glVertex2f(x + w, y + h);
glTexCoord2f(0, 1);
glVertex2f(x, y + h);
glEnd();
glDisable(GL_BLEND);
Display.update();
Display.sync(60);
}
Display.destroy();
}
Hmm try this and see if it works. I use it in my 2d game it works there.
package game.utils;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.net.URL;
import java.util.HashMap;
import java.util.Map;
import org.lwjgl.opengl.GL11;
import org.newdawn.slick.opengl.Texture;
import org.newdawn.slick.util.ResourceLoader;
public class TextureLoader {
private static Map<URL, Texture> texMap = new HashMap<>();
public static void bindTexture(URL tex) {
try {
Texture texture = texMap.get(tex);
if (texture == null) {
texture = loadTexture(tex);
}
texture.bind();
GL11.glTexParameterf(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_MIN_FILTER, GL11.GL_NEAREST);
GL11.glTexParameterf(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_MAG_FILTER, GL11.GL_NEAREST);
} catch (IOException e) {
// TODO Auto-generated catch block.
e.printStackTrace();
}
}
public static void bindTexture(String tex) {
try {
bindTexture(ResourceLoader.getResource(tex));
} catch (Exception e) {
bindTexture("res/other/white.png");
}
}
private static Texture loadTexture(URL tex) throws FileNotFoundException, IOException {
System.out.printf("Loading texture %s (%s)%n", texMap.size(), tex.getFile());
Texture texture = org.newdawn.slick.opengl.TextureLoader.getTexture("PNG", tex.openStream());
texMap.put(tex, texture);
return texture;
}
}
You can change the "res/other/white.png" to whatever your missing texture file is. Also the glTexParameterf lines are for disabling mipmap/filtering/whatever it's called.