LWJGL Confusing Texture Mappings - java

I've been working on a very simple game, and I've decided to include some basic textures. I was experimenting with the code, and for some reason, I have no idea why, I cannot get the textures to map correctly. Right now, I am simply trying to map a green rectangle (512 x 64 .png file) to the bottom of a screen of size 640 x 480. This green rectangle is supposed to represent the ground. Here is an image of my failed attempt:
Here is the relevent code:
In the Boot class I have created I call this function:
public void initGL() {
GL11.glMatrixMode(GL11.GL_PROJECTION);
GL11.glLoadIdentity();
GL11.glOrtho(0, gameWidth, gameHeight, 0, 1, -1);
GL11.glMatrixMode(GL11.GL_MODELVIEW);
GL11.glEnable(GL11.GL_TEXTURE_2D);
}
In the ground class I have created, I call a draw function. The texture is loaded in the Boot class, and set as a protected variable which I bind and use in the ground.draw() function.
public void draw() {
this.texture.bind();
GL11.glLoadIdentity();
GL11.glTranslatef(0, 0, 0);
GL11.glBegin(GL11.GL_QUADS);
GL11.glTexCoord2f(0, 0);
GL11.glVertex2f(0, 480 - height);
GL11.glTexCoord2f(1, 0);
GL11.glVertex2f(640, 480 - height);
GL11.glTexCoord2f(1, 1);
GL11.glVertex2f(640, 480);
GL11.glTexCoord2f(0, 1);
GL11.glVertex2f(0, 480);
GL11.glEnd();
}
Also, if you'll note above I have a GL11.glTranslatef call. I can get my ground texture in the right position if I simply make the 2nd argument for this function large enough to displace it further in the y direction, however I don't wish to do it this way. I really don't know how the texture ended up in this location in the first place, and I would like to figure out why.

I think there is a problem with your matrices :
GL11.glMatrixMode(GL11.GL_PROJECTION);
GL11.glLoadIdentity();
GL11.glOrtho(0, gameWidth, gameHeight, 0, 1, -1);
I never really used OpenGL fixed pipeline but what I see or actually DON"T SEE is where you multiply your matrices. You must multiply the model matrix of your quad with projection matrix which is glOrtho(). ( glPushMatrix/glPopMatrix )
So in your scenario you should :
Push Ortho matrix.
Push camera(view) matrix (if exists).
Push Model Matrix.
Pop Model Matrix.
Pop camera (view) matrix (if exists).
Pop Ortho matrix.
If the Ortho never changes I think you need to push it only once.
Also make sure you take into account ortho coordinates changes because depending on glOrtho() setup the world center going to be different from the center of the screen.Usually top left or bottom left corner.
The bottom line is : while I don't recommend you using the old and deprecated OpenGL at all, you should take a look how the transformations are done the right way in the numerous online tutorials.Also here

Related

gltranslatef not quite working as expected

I was under the impression that gl.glTranslatef() effectively moved a sprite by the values passed in to the method (ie if I wanted a sprite to move by 2 pixels I would call gl.glTranslate(2.0f,0.0f,0.0f);
However If I do this then the sprite remains static. However If I pass in an absolute position (ie call gl.glTranslatef(52.0f,0.0f,0.0f)) my sprite moves as expected. However its starting position is out by the initial position coordinates (ie If I specify the sprite to start at 30,30 then the first draw loop draws the sprite at 62,30, once the first frame is done the sprite moves as I expect.
What is going on?
here is the draw code for my sprite.
//Reset the modelview matrix
gl.glLoadIdentity();
//drawing
//bind the previously generated texture
gl.glBindTexture(GL10.GL_TEXTURE_2D,this._texture);
//point to our buffers
gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
gl.glEnableClientState(GL10.GL_TEXTURE_COORD_ARRAY);
//set the face rotation
gl.glFrontFace(GL10.GL_CW);
gl.glPushMatrix();
gl.glTranslatef(_position.x,_position.y,0.0f);//need to work out fraction of 1 that the position of the sprite represents
//point to our vertex buffer
gl.glVertexPointer(3, GL10.GL_FLOAT, 0, _vertexBuffer);
gl.glTexCoordPointer(2, GL10.GL_FLOAT, 0, _textureBuffer);
//draw the vertices as a triangle strip
gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP, 0, _vertices.length / 3);
gl.glPopMatrix();
//disable the client state before leaving
gl.glDisableClientState(GL10.GL_VERTEX_ARRAY);
gl.glDisableClientState(GL10.GL_TEXTURE_COORD_ARRAY);
Note that this passes in the absolute position and not the small extra movement.
To simplify the above.
If I specify static inputs for gltranslatef
gl.glTranslatef(2.0f,2.0f,0.0f);
I would expect the matrix to move diagonally by 2 units each frame, however if I do this the matrix and hence my sprite stays at position 2,2
If I add 2 to the input parameters on each frame (ie 2, then 4 then 6 etc) my sprite moves diagonally but this is not how I thought translatef worked.
culprits for the given behaviour in your case are glPushMatrix() and glPopmatrix(). These two calls restore the original state(matrix stack) every frame. So every time your origin remain same and when you specify (2.0, 0.0,0.0) each fram with respect to world origin your sprite remains at world origin. Remove these two calls and see the magic !

LWJGL: Slick: Drawing fonts in 3D world

How to draw Slick's fonts (UnicodeFont), which can be drawn only via drawString(), which provides only x and y, in a 3D world?
I have tried this:
public void drawHudString(float _posX, float _posY, String _text, UnicodeFont _font, Color _color) {
glPushMatrix();
glRotatef(cam.rotX, -1.0f, 0.0f, 0.0f);
glRotatef(cam.rotY, 0.0f, -1.0f, 0.0f);
glRotatef(cam.rotZ, 0.0f, 0.0f, -1.0f);
glTranslatef(-cam.posX, -cam.posY, -cam.posZ + 20);
_font.drawString(_posX, _posY, _text, _color);
glPopMatrix();
}
but the text was not displayex. If used without glRotatefs and glTranslatef, then the text will be rendered by 3D-world coords
The rendering of fonts with Slick is based on OpenGL's immediate mode. This means that the behavior of drawString is determined by the current state, or in other words, the current GL_PROJECTION and GL_MODELVIEW matrices.
Your question does not really make it clear whether you want to draw text as a 2D overlay (probably in screen coordinates) or truly perspective embedded in 3d space. Nevertheless, you can achieve both with drawString. drawString renders the font texture at the specified x/y coordinates in the z=0 plane. Iirc the convention in drawString is to assume a left-handed coordinate system and the texture is visible from the negative z-side. The reason for this convention is probably that OpenGL uses a left-handed coordinate system for window space, while using a right-handed for world/object space (see this answer for a good explanation). As a result, rendering in 2D is straightforward with Slick: Set up a typical orthogonal projection matrix (as suggested by ryuyah2000) and you are good to go.
If you want to render in 3D space, you instead keep your regular perspective projection matrix (i.e., you are using the same projection you use for rendering your world). In order to control the position of the text in 3D space you have to set up the modelview matrix accordingly (i.e., aligning the z=0 plane in the plane where you want to render your text). Due to the left-hand and z-visibility conventions you may have to rotate your z-axis by 180° and have to invert the handedness (just scale your modelview by -1). In case you get one of these steps wrong, your text is either not visible (= looking to wrong z-side) or is written right-to-left (= wrong handedness). Slick's drawString method uses a scaling of 1 unit = 1 pixel of the font texture, so you have to apply an appropriate scaling to match that to your world units.
use this
glMatrixMode(GL_PROJECTION);
glPushMatrix();
glLoadIdentity();
glOrtho(0, 800, 600, 0, 1, -1);
glMatrixMode(GL_MODELVIEW);
glDisable(GL_CULL_FACE);
glDisable(GL_DEPTH_TEST);
glClear(GL_DEPTH_BUFFER_BIT);
glLoadIdentity();
// render font
glEnable(GL_DEPTH_TEST);
glEnable(GL_CULL_FACE);
glMatrixMode(GL_PROJECTION);
glPopMatrix();
glMatrixMode(GL_MODELVIEW);

LWJGL doesnt draw outside Display Mode

When I try to move an opengl quad outside the size of the main window, it doesn't render.
Say if I have a window 600x800. Then I resize it to be full screen. Once I move the quad(player) outside the defined window properties, it disappears.
I think this is essential because I'm working on a top down RPG and he will be moving around on the x and y plane. Also if that isn't enough, how would I make a camera that keeps the player in the center...
So far I have
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(0, 845, 0, 520, -1, 1);
glMatrixMode(GL_MODELVIEW);
I havent been able to test it due to the first problem
On the part to keep the camera in the center. Just translate everything -x, -y relative to the camera/player's position.
glTranslatef(-cameraX, -cameraY, 0);
So when you move the player change the players position and translate everything the opposite way.

can't render shape in openGL

I was trying to follow example codes to simply display a rectangle on a black background, but it didn't seem to be displaying. What I did was
private static void initGL(){
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(0,Display.getWidth(),0,Display.getHeight(),-1,1);
glMatrixMode(GL_MODELVIEW);
glDisable(GL_DEPTH_TEST); //2D mode
glColor3f(0.5f, 0.0f, 1.0f);
glBegin(GL_QUADS);
glVertex2f(-0.75, 0.75);
glVertex2f(-0.75, -0.75);
glVertex2f(0.75, -0.75);
glVertex2f(0.75, 0.75);
glEnd();
}
It doesn't display anything on the screen except for a black background. Does anyone know what I might have done wrong? I'm using lwjgl in eclipse.
First things first: You only have to run the whole
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(0,Display.getWidth(),0,Display.getHeight(),-1,1);
glMatrixMode(GL_MODELVIEW);
thing once during your program, probably shortly after you run Display.create().
Also, you're tessellating using the wrong vertices. You wrote
glVertex2f(-0.75, 0.75);
glVertex2f(-0.75, -0.75);
glVertex2f(0.75, -0.75);
glVertex2f(0.75, 0.75);
which means draw a rectangle from (-0.75, -0.75) pixels to (0.75, 0.75) pixels. This is too small to be noticed. My guess is you assumed glVertex2f deals with fractions of the display width. It does not. glVertex2f deals with actual coordinates, it just allows fractional pixels, unlike glVertex2i (this is useful believe it or not, it helps with smoother animations). Something like
glVertex2f(100F, 100F);
places a vertex at (100, 100), and is effectively equivalent to
glVertex2i(100, 100);
Also, remember that negative pixels will be rendered off the screen, because OpenGL's origin of the coordinate system, (0, 0), is in the lower left and behaves like the first quadrant from the coordinate system in math class, not like the traditional computer coordinate system with (0, 0) in the upper left.
As for the the black background, LWJGL's Display has a black background by default, so it's recommended to draw a quad with your background color that covers the entire display width and height. One quad won't really affect your performance.
glVertex2f uses same size units as your glOrtho so unless your display width and height are in units of ones, like 10 or less, you may not see anything!

Can't get to move libgdx OrthographicCamera

I'm having issues with the Camera class in libGDX, I just can't visually move it even though its position changes.
This is how I setup the camera:
camera = new OrthographicCamera(frustumWidth, frustumHeight);
This is how I change its position:
world.onUpdate(deltaTime, camera);
renderer.render(world);
camera.position.set(MathUtils.random(0, 800), MathUtils.random(0, 480), 0);
//camera.position.set(
// world.dynamicObjects.get(GameWorld.MainPgID).pos.x * GameWorld.frustumToWorldRatio,
//world.dynamicObjects.get(GameWorld.MainPgID).pos.y * GameWorld.frustumToWorldRatio, 0);
I submit the changes at the beginning of the .render function:
camera.update();
batcher.setProjectionMatrix(camera.combined);
batcher.begin();
polygonBatcher.begin();
As I've said the position does change, and yet of the many combinations I've tried none works.
Perhaps I misunderstood how the Camera works and I need to move the objects and not the camera? Seems to be stupid to me, after all it's called camera for a reason.
You have to apply the combined projection matrix on every batch/renderer you want it to affect.
But besides of that it seems to be fine. Try to debug it step by step.
Setup a simple project with only new OrthographicCamera(Gdx.graphics.getWidth(), Gdx.graphics.getHeight()); and some lines (ShapeRenderer) or sprites (SpriteBatch), set the projection matrix to camera.combined, change camera.position and update() the camera. That should do it.
Then when you change camera.position all the renderer with the camera's frustum should offset accordingly without changing the offsets of the sprites/geometry.
btw. the viewport is not 0 - 800, but rather -400 - 400 for x and respectively for y;

Categories

Resources