Updated translate? (Extended Convo)

After drawing the world and moving the camera back to 0, 0, you draw your HUD with normal, pixel coordinates. You don’t need to account for the world or camera or anything.

Translating negatively means you’re subtracting the camera position from all the future render calls. I explained in an earlier post why subtracting is used and not adding. When you’re done rendering the world (blocks, sprites, what have you) you add the camera’s position to the graphics context (translate). This resets it back to 0 because -500 + 500 = 0, for example.

I swear I saw this question before regarding levels but it might’ve been a different person. I would keep all your levels to one state. Instead of hard-coding a level class instance for each level, you can merely load it from a file. About your question with the player dying, you can just either a) reload from the file if it’s quick enough or b) store a copy of the level before anything has happened and load it in to reset the world without reading from a file.

Your game loop looks fine. I do the exact same thing (although I do logic right before rendering in the render loop).

I hope that answers your questions.

[quote]After drawing the world and moving the camera back to 0, 0, you draw your HUD with normal, pixel coordinates. You don’t need to account for the world or camera or anything.
[/quote]
So I have the camera normally stay at the players location… which is this:

GL11.glLoadIdentity();
GL11.glTranslatef(-x + startOffset, 0.0f, 0.0f);

so… wouldn’t running GL11.glLoadIdentity(); reset it back to 0,0?

I haven’t made a HUD yet, but it’s something I was thinking about. Are you saying the HUD (which would be pretty much a bunch of pictures/text drawn last) are all drawn as if the camera is always at 0,0 (default view). Cause if that’s the case, why would that work? This sounds a lot like what Jesse was trying to tell me in an earlier post regarding updating the location of objects/VBOs.

[quote]I swear I saw this question before regarding levels but it might’ve been a different person. I would keep all your levels to one state. Instead of hard-coding a level class instance for each level, you can merely load it from a file. About your question with the player dying, you can just either a) reload from the file if it’s quick enough or b) store a copy of the level before anything has happened and load it in to reset the world without reading from a file.
[/quote]
That indeed was me xD. I really just didn’t feel like doing that, as I struggled to really see why it would make things easier. I actually thought it was more difficult, so for the time being I just want to stick with seperate class files. As for my main game loop, I got it working like I said I could easily (just added a needsReset boolean in each level), but I just didn’t know if each level should have a gameloop, instead of just one. Like I said before, it crashed when I tried it, so unless someone understands what I’m asking and thinks it’s a way better idea to do that, it all works.

[quote]I hope that answers your questions.
[/quote]
So ya, I just don’t get the reasoning for the HUD being put back at 0,0. I can try it I guess, but that involves some time setting up a HUD. If you could try explaining it in a little more detail or in another way, that would be great.

I don’t know much about core GL to know what glLoadIdentity does, but it sounds like a much more expensive method to just reverse translate (ie does other things not just reset to 0, 0).

The HUD is on-screen, it’s not physically in the world. Therefore you always want it to be in the same place each time. When you reset the graphics context offset to 0, 0 rendering a texture at 0, 0 actually appears at 0, 0 on screen, it won’t appear 0, 0 in the world.

You could render the hud at the camera coordinates but why do all that extra work?

My world objects always have a tickUpdate method for updating logic. Heck the chunk objects INSIDE the world object have them too. It really makes everything neater because all the logic for different things is in its own classes.

I should elaborate on the HUD part.

Say you have a health bar that appears in the bottom left corner of the screen. 0, 0 is at the bottom left corner of the screen (assuming Y-up) so you draw everything at 0, 0. Perfect!

But… if you translated the camera AWAY from 0, 0, it would appear like the health bar was stuck at the bottom left corner of the world, which would be bad as the player could no longer see it.

Translating the camera merely means you’re converting from screen coordinates to world coordinates. I can understand it’s difficult to grasp the concept of this so I’ll try to make it as detailed and understandable as possible. Tell me if I make some parts vague.

[quote]The HUD is on-screen, it’s not physically in the world. Therefore you always want it to be in the same place each time. When you reset the graphics context offset to 0, 0 rendering a texture at 0, 0 actually appears at 0, 0 on screen, it won’t appear 0, 0 in the world.
[/quote]
Ya, but how do i do dat. I have my level which renders a bunch of objects based on an x and y, and a I use glTranslate that moves the camera. I don’t get how I make something on screen, but not in the world. Does this have to do with Graphics and stuff from slick?

This doesn’t have to do anything with Slick. If you can render something in the world, surely you can render something on screen. Whatever’s on the world is on screen anyway.

You’re already rendering stuff on screen. It’s just that you changed the rendering positions so it appears that it’s scrolling by. A HUD is merely a collection of items on screen that don’t scroll by. You should not link the HUD to the world (unless you’re going for some cool effect that involves it).

I don’t understand how you know how to render something in the world but not on screen. It seems a bit backwards to me but I’ll try to explain it as best as I can.

Say your screen is 1280x720. You have a red dot (1x1 pixel) that you want to render in the very middle of the screen. Therefore you should put it at half the screen width/height which is at 640, 360.

Whatever you choose to render at those coordinates will appear at those coordinates. There’s no change in rendering position, if you want a square at 100, 100, it WILL render at 100, 100.

Ok, maybe I’m just doing things differently than you would, but from my understand of how this all works, I have a Level that simply draws things. The objects that draw are drawn based on their x and y. These are drawn On Screen and only move if their x and y move. Then I also have a player object within that, and it does the exact same thing. However, it moves based on user input (left and right arrow and up arrow), but still moves by the x and y changing. The only way the screen moves is by glTranslate, which is what I refer to as the camera. I don’t render any other way, so if there’s something I’m doing wrong/backwards, feel free to explain. I thought this was the correct way to do things, so I guess I don’t get how you would make something On Screen, and the “camera” doesn’t move it. That almost seems like you have 2 screens on top of each other from what I know.

If you want to see how I create my OpenGL Window, my init() for OpenGL, or anything like that feel free to ask. I do start from the bottom left with Y up fyi.

UI/HUD elements exist as if there were in the very bottom left corner of the world. When you move your camera away from that area to focus on the player, you won’t be able to see the elements, therefore you have to move the camera back to the bottom left (0, 0) so you can see them again. I’m not saying to physically render the HUD in the world, but you have to pretend it is like that. You’ll obviously render the world first and then the HUD right on top.

If you had a HUD element at 0, 0, but the camera was 2000 pixels to the right, that HUD element would be rendered at -2000, 0. It would be very much off-screen. That’s why you have to move the camera back to 0, 0 to see it again.

I understand that you could potentially just render the HUD elements relative to the camera, but why do all that work.


glTranslatef(-player.x, -player.y);
// render your world
glTranslatef(player.x, player.y) // this moves it right back to 0, 0
// render your HUD

My question is wouldn’t that put the camera back at 0,0?

Exactly, which is what I’ve been trying to tell you this entire time.

I get you keep saying that, but doesn’t that completely take away the point of the camera following the player? The camera can only show 1 view at a time I would assume lol.

… I totally understand why you’re having difficulty grasping this!

When you translate the matrix, all render calls after that will be translated.

When you translate the matrix again, all the previous render calls won’t be modified.

It’s like that GL push/pop whatever thing (in libgdx it’s begin and end). There’s like a queue of things to render at X and Y values, and when you pass the thing to be rendered into the queue, the thing’s position gets modified by the matrix position ahead of time. Therefore changing the matrix’s position after putting some things in the queue won’t affect things in the queue.

I swear I’ve hit the jackpot of explaining things to you right now and if I’m wrong I’m going to be very upset :persecutioncomplex:

Ok I think I get it now. That makes sense lol xD.

One last question.

So, this is the code I’m using currently for the camera:

		//Camera Stuff
		startOffset = ((level.getScreenWidth() / 2) - (this.getWidth() / 2));
		endOffset = (level.getEndX() - ((level.getScreenWidth() / 2) + (this.getWidth() / 2)));
		if(x <= startOffset)
		{
			GL11.glLoadIdentity();
			GL11.glTranslatef(-level.getStartX(), 0.0f, 0.0f);
		}
		else if(x >= endOffset && x <= (level.getEndX() - this.getWidth()))
		{
			GL11.glLoadIdentity();
			GL11.glTranslatef(-endOffset + startOffset, 0.0f, 0.0f);
		}
		else
		{
			System.out.println(this.x);
			GL11.glLoadIdentity();
			GL11.glTranslatef(-x + startOffset, 0.0f, 0.0f);
		}

I have this before the player is rendered. Would this create an issue? Or should I have it before anything on the screen renders? I was told to do it before anything renders, but it worked the same within the player, so I just did that. Cause then I could make a HUD object, and just have it run after I render the player. Or do I need to render the hud after every object? I guess I’m just wondering if the camera really affects anything, cause what you’re making it seem like is the way I have the camrea set it, it shows what’s at the area I have it set to, then if I set it to the HUD’s location, it goes back to there and overlays it on the screen. I’m setting a HUD up right now, and will try it out when I get it set up, but I guesss I’m just wondering if it really matters when I change the camrea view to the hud, as long as it’s after i do it with the Player.

In the end, I think I get what you’re saying, and if I’m correct in my mind it makes sense.

The HUD is rendered after all the world rendering is done. If you feel uncertain you could always flush the batch (pop and then push again). This ensures whatever you’ve rendered goes to the screen, and then you can render the HUD right on top of it and you’ll be good to go.

hmm, do you have an example of a simple way to show how to do this? (Like a working HUD)

I googled this and a guy gave an example with the following code:

void OGLRender::ready2D()
{
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();

    gluOrtho2D(0.0f, m_Setup.width, m_Setup.height, 0.0f);

    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();
    glTranslatef(0.375, 0.375, 0.0);

    glDisable(GL_DEPTH_TEST);
}
void OGLRender::render2D()
{
    this->ready2D();

    // ... draw GUI here ...
}
while(m_drawFrame)
{
    gm_Render->render2D(); // draw GUI

    SDL_GL_SwapBuffers(); // make drawn frame visible
}

I don’t know really how this helps, but I tried what you said to do in my game (At least I believe I did), and it doesn’t work.

I really think I understand what you’re saying , but it’s not working.

Could we see the implementation attempt in your game code? I’ll see what you did and try to correct anything that stands out.

Ok, so I tried a couple of things, but I’ll try and set this up a little better for you.

Main Level Render Code

	public void loadScreen()
	{
		if(isAdded == false)
		{
			addObjects();
			timeStarted = getTime();
			isAdded = true;
			hud = new HUD(this);
		}
		
		GL11.glClear(GL11.GL_COLOR_BUFFER_BIT | GL11.GL_DEPTH_BUFFER_BIT);
		renderBackground();
		renderBackscene();
		renderBlocks();
		renderItems();
		renderCreatures();
		renderFrontscene();
		hud.draw();
	}

Player Render Code + Camera Code (renders in renderCreatures())


public void drawTile()
	{
		
		if (hasinit == false)
		{
			setTexture("PNG", "Player.png");
			initVBO();
			hasinit = true;
		}
		getInput();
		
		
		//Camera Stuff
			GL11.glLoadIdentity();
			GL11.glTranslatef(-x + startOffset, 0.0f, 0.0f);
		
		//Other updates/Rendering
		updateEffects();
		currentWeapon.draw();
		updateVBO();
		bar.draw();
	}

Hud Code

public class HUD
{
	protected Level level;
	Picture pic = new Picture(50, 300, 175, 175);
	
	public HUD(Level level)
	{
		this.level = level;
	}
	public void draw()
	{
		
		GL11.glTranslatef(level.player.x - 350, 0.0f, 0.0f);
		pic.draw();
	}
	public void update()
	{
		//something
	}
}

I just made player public to test this out, the correct way I would do this is to go through the creatures, and if it’s a player, then get the coords. But that shouldn’t affect this. Weird things happen when I try this. Like just straight up it doesn’t do what it should do. When I don’t draw the hud it works just fine.

Question:

Why are you resetting the camera for every object? Shouldn’t it just be translated to the player’s position at the start, then rendering everything and resetting the camera?

I think you should avoid reloading the GL identity each time. Other than that it actually looks okay (try to implement not translating everything each time first and see if you can get that working).

I thought I was just resetting it when the player renders, that’s all. I could literally copy the camera code in the player’s render code and put it before i render anything in the level render code. It does the exact same thing from what I saw when I tested it.

So from what I know I thought I was only resetting the camera when the player renders (before). You also said I should avoid reloading the GL identity… but literally thats how i got this to work (that was the main topic of this thread).

Also to be clear, I tried what I showed, and it doesn’t work. The HUD renders, but it doesn’t move with the player. The box i made just stays there like any other object/picture/block.

So… I don’t know if you can give a clear example on what I need to change, but I don’t really know what I need to do now for the HUD :/.

If trying to figure out how to move the graphics context back to 0, 0 was the main topic of this thread, you did a very poor job of trying to make that clear.

If you want to reset the graphics instance, simply re-translate it by how much you translated it by. Sum to zero.

I’ll try to answer your future questions in the morning.

Ok, but lol the point of this thread was to understand correctly how the “camera” worked. The solution that I found that worked was using the glLoadIdentity(). I think that was all made very ver yclear, it just took you a little to understand my issue.

My problem is still as stated. The code I gave you, you said seemed ok, but it doesn’t work. I don’t know if glLoadIdentity() messes it up, but if so then I guess that’s what I need to know how to fix. Using that is what got me to understand this whole camera better, but if you’ve got a better idea (or you said it before in this thread), I’ll try it once again. I’m still saying though, I can change up my code to do exactly as you say, and I’ll see if it works.

Anyway I’ll look at it again in the morning.