Thanks all of you for your replies! :]
better not to mix LWJGL and Slick2D code unless you really know what's going on under the hood of Slick2D. If you are using Slick2D, better to drop all the LWJGL code and use just the Slick2D API's.
I was thinking along the same lines, only because I didn't realize just how many tools Slick has that I was programming myself before and which are done more efficiently since it interfaces with OpenGL rather than Java's graphics libraries.
While it's true Slick was never designed to be used alongside low-level GL calls, it's entirely possible to do so granted you take care of a few things.
If you're comfortable with OpenGL, I'd personally suggest rolling your own sprite renderer, as it may lead to better performance (i.e. using VBOs instead of immediate mode) and more reliability.
Show us your rendering code -- there's not much we can do without it.
To be honest, I'm not terribly comfortable with OpenGL just yet (been doing some reading and tutorials and such, which has been helping but only scratching the surface). I will post my rendering code below. :]
could be an issue we encounter and fixed by using our own image class instead Slicks (just copied the Slick one and changes it a bit)
How does look/behave exactly ?
As theagentd described, it looks exactly as if every other frame is black, so there is a constant flicker on the screen.
I believe you're manually calling Display.update(), right? Slick2D also calls that, most likely resulting in every other screen being black = flickering. Let Slick2D handle the buffer swapping or drop Slick2D altogether.
You're right, I am, and so I got rid of the Display.update() call in my game loop and it ended up crashing the game and giving me only a black screen, unfortunately. I was probably supposed to do something else as well, wasn't I? :p
Here's the relevant rendering code:
This is the core game loop.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40
| public void gameLoop() { long startTime = System.currentTimeMillis(); long currTime = startTime; glMatrixMode(GL_PROJECTION); glLoadIdentity(); glOrtho(0, Display.getWidth(), Display.getHeight(), 0, 1, -1); glMatrixMode(GL_MODELVIEW); glEnable(GL_TEXTURE_2D);
while (isRunning) { long elapsedTime = System.currentTimeMillis() - currTime; currTime += elapsedTime; glClear(GL_COLOR_BUFFER_BIT);
update(elapsedTime);
draw(); while (!Display.isCloseRequested()) { Display.update(); Display.sync(60); } isRunning = false; } Display.destroy(); System.exit(0); } |
This method is the core draw method.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| public void draw() { player = (Player)map.getPlayer(); renderer.draw(map, Display.getWidth(), Display.getHeight()); guiManager.draw(); if (inventoryOpen) { guiManager.renderInventory(); } if (chestOpen) { guiManager.renderChest(currentChest); } } |
This is the renderer's draw method, which is called from the core draw method, just as an example.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78
| public void draw(TileMap map, int screenWidth, int screenHeight) { Sprite player = map.getPlayer(); int mapWidth = tilesToPixels(map.getWidth()); int mapHeight = tilesToPixels(map.getHeight());
int offsetX = screenWidth / 2 - Math.round(player.getX()) - TILE_SIZE; offsetX = Math.min(offsetX, 0); offsetX = Math.max(offsetX, screenWidth - mapWidth);
int offsetY = screenHeight / 2 - Math.round(player.getY()) - TILE_SIZE; offsetY = Math.min(offsetY, 0); offsetY = Math.max(offsetY, screenHeight - mapHeight); int bx = offsetX * (screenWidth - background.getWidth()) / (screenWidth - mapWidth); int by = screenHeight - background.getHeight();
background.draw(bx, by);
int firstTileX = pixelsToTiles(-offsetX); int lastTileX = firstTileX + pixelsToTiles(screenWidth) + 1; int firstTileY = pixelsToTiles(-offsetY); int lastTileY = firstTileY + pixelsToTiles(screenHeight) + 1; for (int y = firstTileY; y < lastTileY; y++) { for (int x = firstTileX; x <= lastTileX; x++) { Image imageF = map.getTileF(x, y); Image imageB = map.getTileB(x, y); if (imageB != null) { imageB.draw(tilesToPixels(x) + offsetX, tilesToPixels(y) + offsetY); } if (imageF != null) { imageF.draw(tilesToPixels(x) + offsetX, tilesToPixels(y) + offsetY); } } }
player.draw(Math.round(player.getX() + offsetX), Math.round(player.getY()) + offsetY);
Iterator i = map.getSprites(); while (i.hasNext()) { Sprite sprite = (Sprite)i.next(); int x = Math.round(sprite.getX()) + offsetX; int y = Math.round(sprite.getY()) + offsetY; sprite.draw(x, y);
if (sprite instanceof Creature && x >= 0 && x < screenWidth) { ((Creature)sprite).wakeUp(); } } } |
Thanks for all the help, everyone! I'm really liking Slick and LWJGL at this point and I don't mind dropping LWJGL if I have to, considering Slick is basically an extended version of it; the features the library offers is a breath of fresh air after studying how engines work and how to program all my own stuff for 2 years. lol
Colton