Need help "Thinking 3D"

Hi.

I need some help learning to think 3D. I’ve coded 2D games for a while, but finally took the step to try to learn this third dimension. I am used to thinking in definite widths, heights, x’s and y’s. I’ve started tampering with JOGL, and although I usually manage to try/fail until I get somewhat of the look I want, I feel I do not really understand why some things work, why some do not, and why things look like they do.

There seems to be so many things that affect what actually pops up on my screen, and where it pops up. I’ll give an example.


 gl.glVertex3f( 1.0f, 1.0f,-1,0f);

From what I gather, 1.0f here is somewhat of a size ratio. 0.0f is the center. (relative to translation). Lets say I have a texture that is 64*64 pixels. When is (-1.0 …1.0f) in the previous line 64 pixels?
I use negative z translation (otherwise naturally, part of what I draw is drawn outside of my scope). I also use gluPerspective in my resize event. I read that you can interpret gluPerspective’s first parameter as a camera lense, (…180mm so to speak). However, I dont know when it is “flat”, in lack of a better word…

Now I dont understand how gluPerspective works in detail on a whole, either.

I guess I would just like to be able to foresee how big, and where, my sprites would be positioned on the screen before I run the program. (This comes so naturally in 2D that I have a difficult time adjusting my line of thinking).

Any advice is appreciated. If you link to articles, that is fine, - but if you try to explain it with your own words, it would be much appreciated.

Thanks.

Hi,
from the text you put after your example it seems to me that your are far from understanding the way glVertex works (no harm meant here)…
Try to read chapter 3 of the red book, it will give you a good start.
http://www.glprogramming.com/red/

Also, try to get away from using pixel’s as a measurement since they only happen at the very end of the GL pipeline. You could use whatever scale you want, like meters or whatever to say what the values passed into glVertex calls mean. Since then you’re dealing with real world dimensions, just think about how things would line up in the real world with the given sizes and you should be fine.

Also, you use texture coordinates to specify how a texture image spreads across the polygon and these, in the end, determine how many pixels on screen the actual texture takes up. I would highly recommend looking at the redbook (it’s online http://www.opengl.org/documentation/red_book/)

No offense taken turquiouse :wink: It is no big secret I am new to this.

I looked at this red book. Gosh, this is one jewel of a book so far. Its chapter on Drawing Geometric Objects, and Viewing was absolutely fabolous. I got quite a few “aha…” experiences, to say the least.
I’m going to try using Orthographic projection for now. It seems to be the easiast thing to adapt to for me, and I think it will work well for a pretty static game, where 3D objects live on a more or less flat space. (Correct me if I am wrong!).

I am sure I will have many questions even after reading this book, but so far it seems like an excellent read. Thank you both for pointing me to it.

PS! I notice 5th edition is out on amazon, which covers up to OpenGL 2.0(?)… Is the html red book for earliar versions still valid in most areas?

Well you can assume that new version of opengl added stuff to the red book
You can safely assume that basic stuff remains valid… At least until they decide to release v3 and stop the immediate mode.

Onto the next problem…

I have a huge image, (20482048) which I want to render as a background image. I remember from years ago that to be compatible with some older cards, it might be wise to split the image up.
I created 256 tiles (128
128) which I now want to render.

My first approach was to simply iterate over my texture array, translate, draw the given texture at its location on a quad. This worked. However, then I read about display lists. I wondered if it was a good idea to use these on my textures. So I tried. It compiles and runs fine, but it does not work. Black screen :slight_smile:

What I am trying is this: (This is what ends up with black screen)


private void createStarField()
	{
		final GL gl = window.getGL();
		gl.glNewList(STARFIELD_LIST_ID, GL.GL_COMPILE);
		
		   gl.glPushMatrix();
		   gl.glTranslatef((starFieldIndex/16)*128, (starFieldIndex%16)*128, -10.0f);
		   starField[starFieldIndex].bind();
		   gl.glBegin(GL.GL_QUADS);
		   {
				TextureCoords tx = starField[starFieldIndex].getImageTexCoords();
				gl.glColor3f(1.0f,1.0f,0.0f);
				gl.glTexCoord2f(tx.left(), tx.top());
				gl.glVertex3f(0, 0, 0);
				gl.glTexCoord2f(tx.left(), 1);
				gl.glVertex3f(0,128, 0);
				gl.glTexCoord2f(1, 1);
				gl.glVertex3f(128,128, 0);
				gl.glTexCoord2f(1, tx.top());
				gl.glVertex3f(128,0, 0);
				
			}
			gl.glEnd();
		
	                     gl.glPopMatrix();
		gl.glEndList();
		fieldCreated=true;

	}

my draw method would then simply increment the starFieldIndex (which is a global variable) and call glCallList.

Now this code, which was my first try, works perfectly.


final GL gl = window.getGL();
	
    		 gl.glPushMatrix();
			gl.glLoadIdentity();
	        
			//System.out.println("Translating to: "+(i%16)*128+" , "+(i/16)*128);
			gl.glTranslatef((i/16)*128, (i%16)*128, -10.0f);
			starField[i].bind();
			
			 
		       
		    		
			gl.glBegin(GL.GL_QUADS);
			{
				
				TextureCoords tx = starField[i].getImageTexCoords();
				gl.glColor3f(1.0f,1.0f,0.0f);
				gl.glTexCoord2f(tx.left(), tx.top());
				gl.glVertex3f(0, 0, 0);
				gl.glTexCoord2f(tx.left(), 1);
				gl.glVertex3f(0,128, 0);
				gl.glTexCoord2f(1, 1);
				gl.glVertex3f(128,128, 0);
				gl.glTexCoord2f(1, tx.top());
				gl.glVertex3f(128,0, 0);
				
			}
			gl.glEnd();
			gl.glPopMatrix();
    	}
		
		
		
	}

(Dont shoot me down please, still all new to this… First attempt at ever doing anything similar).

Can anyone tell me what the magic (or anti-magic in this case) with the display list is?

Edit: I also tried doing the iteration over the textures inside the list creation. (Dont know which is the right way…?)

I read your code quite “diagonally” but aren’t you expect variable to be changed in your display list…
If so you you’re wrong. Once a display list is compiled everything in it is fixed… (redbook chapter 7 for more information)
I think you can try to put the bind outside the display list.

Hope it helps

turquoise is right, but if you want to keep using display lists, why not have one large display lists that iterates through the entire set of things. It seems to me that this would be faster and you want to visit all of the star field textures anyway. Now it would just be one display list call in your rendering program.

I might add that the days of such small textures is long gone, I believe even the Intel integrated stuff supports 2048x2048. Both ATI and Nvidia have long since supported such large textures, with the newest cards supporting 4096x4096.

I figured as much :wink: But I figured better safe than sorry. I’ll do some tests when I have most things up an running, to see if there are some performance differences, and whether older cards can handle it properly. Thanks for all the feedback.

Oh and in the event you don’t know how to programatically check the hardware…

gl.glGetIntegerv(GL.GL_MAX_TEXTURE_SIZE, max_dim);

And I would be interested in some performance tests on the matter, I wonder how much the additional draw calls and pipeline stalls (when switching textures) will affect performance with the tiled approach.