LWJGL / OpenGL Rendering Questions (Center Render/Bending Polygons) - java

So I am creating a simple 3d render engine in the LWJGL, and I am having issues with the fact that when I back up from an object, it travels to the left and upwards (towards 0,0) when I really need it to travel to screenResX/2,screenResY/2 (maybe 0 I dont know). Is there a way that I can set some kind of variable that will let it fade towards the center?
Additionally, In this engine, I need to bend the polygons to render as if the player was looking at them. At the moment, I only have polygons rendering if you are looking straight at them, and I know that that's not what is needed, can anyone help me?
Thanks in advance for your help, this is my first 3d engine and I'm pretty clueless.

So for the first question: Scaling always takes place around the origin. Meaning that you have to translate your object to the origin, scale it and then translate it to its destination. This is better explained here: OpenGL: scale then translate? and how?
But the basics are something like this (from the linked question):
//this moves the scaled
glTranslatef(destCenter.x, destCenter.y, 0.0);
//scale to the desired factor
glScalef(scaleX, scaleY, 0.0);
//move the center of the scaling operation into the origin
glTranslatef(sourceCenter.x * -1.0, sourceCenter.y * -1.0, 0.0);
I still don't quite understand your second question, but I am guessing that you mean that you want something to be drawn in perspective rather than in an orthogonal fashion. Have a look at gluPerspective(...) or glFrustum(...) instead of glOrtho(...).

Related

Trying to achieve dynamic lighting in a tiled 2D isometric environment using Java2D

I am trying write some lighting code for a Java2D isometric game I am writing - I have found a few algorithms I want to try implementing - one of which I found here:
here
The problem is that this sort of algorithm would require some optimal pixel-shading effect that I haven't found a way of achieving via Java2D. Preferably some method via the graphics hardware but if that isn't possible - at least a method of achieving the same effect quickly in software.
If that isn't possible, could someone direct me to a more optimal algorithm with Java2D in mind? I have considered per-tile lighting - however I find the drawPolygon method isn't hardware accelerated and thus performs very slowly.
I want to try and avoid native dependencies or the requirement for elevated permissions in an applet.
Thanks
I did a lot of research since I posted this question - there are tons of alternatives and JavaFX does intend (on a later release) to include its own shader language for those interested. There is also a ofcourse LWJGL that will allow you to load your own shaders onto the GPU.
However, if you're stuck in Java2D (as I am) it is still possible to implement lighting in an isometric game it is just 'awkward' because you cannot perform the light shading on a per-pixel level.
How it Looks:
I have achieved a (highly unpolished - after some polishing I can assure you it will look great) effect for casting shadows, depth sorting the light map, and applying the lighting without experiencing a drop in frame-rate. Here is how it looks:
You'll see in this screen-shot a diffuse light (not shaded in but that step I'd say is relatively easy in contrast to the steps to get there) casting shadows - the areas behind the entities that obstructs the light's passage BUT also in the bounds of the light's maximum fall-out is shaded in as the ambient lighting but in reality this area is passed to the lights rendering routine to factor in the amount of obstruction that has occurred so that the light can apply a prettier gradient (or fading effect of some sort.)
The current implementation of the diffuse lighting is to just simply render obstructed regions the ambient colour and render non-obstructed regions the light's colour - obviously though you'd apply a fading effect as you got further from the light (that part of the implementation I haven't done yet - but as I said it is relatively easy.)
How I did it:
I don't guarantee this is the most optimal method, but for those interested:
Essentially, this effect is achieved by using a lot of Java shape operations - the rendering of the light map is accelerated by using a VolatileImage.
When the light map is being generated, the render routine does the following:
Creates an Area object that contains a Rectangle that covers the
entirety of the screen. This area will contain your ambient
lighting.
It then iterates through the lights asking them what their
light-casting Area would be if there were no obstructions in the way.
It takes this area object and searches the world for Actors\Tiles
that are contained within that area that the light would be cast in.
For every tile that it finds that obstructs view in the light's casting area, it will calculate the difference in the light source's position and the obstruction's
position (essentially creating a vector that points AT the
obstruction from the light source - this is the direction you want to cast your shadow) This pointing vector (in world
space) needs to be translated to screen space.
Once that has been done, a perpendicular to that vector is taken and
normalized. This essentially gives you a line you can travel up or
down on by multiplying it by any given length to travel the given direction in. This vector is
perpendicular to the direction you want to cast your shadow over.
Almost done, you consturct a polygon that consists of four points.
The first two points are at the the base of the screen coordinate of
your obstruction's center point. To get the first point, you want to
travel up your perpendicular vector (calculated in 5) a quantity of
half your tile's height [ this is a relatively accurate
approximation though I think this part of the algorithm is slightly
incorrect - but it has no noticable decay on the visual effect] -
then ofcourse add to that the obstructions origin. To get the
second, you do the same but instead travel down.
The remainder of the two points are calculated exactly the same way -
only these points need to be projected outward in the direction of
your shadow's projection vector calculated in 4. - You can choose any large amount to project it outwards by - just as long as it reaches at least outside of you light's casting area (so if you just want to do it stupidly multiply your shadow projection vector by a factor of 10 and you should be safe)
From this polygon you just constructed, construct an area, and then
invoke the "intersect" method with your light's area as the first
argument - this will assure that your shadows area doesn't reach
outside of the bounds of the area that your light casts over.
Subtract from your light's casting the shadow area you constructed
above. At this point you now have two areas - the area where the
light casts unobstructed, and the area the light casts over
obstructed - if your Actors have a visibility obstruction factor
that you used to determine that a particular actor was obstructing
view - you also have the grade at which it obstructs the view that
you can apply later when you are drawing in the light effect (this will allow you to chose between a darker\brighter shade depending on how much light is being obstructed
Subtract from your ambient light area you constructed in (1) both
the light area, and the obstructed light area so you don't apply
the ambient light to areas where the lighting effect will take over
and render into
Now you need to merge your light map with your depth-buffered world's render routine
Now that you've rendered you're light map and it is contained inside of a volatile image, you need to throw it into your world's render routine and depth-sorting algorithm. Since the back-buffer and the light map are both volatileimages, rendering the light map over the world is relatively optimal.
You need to construct a polygon that is essentially a strip that contains what a vertical strip of your world tiles would be rendered into (look at my screen shot, you'll see an array of thin diagonal lines seperating these strips. These strips are what I am referring). You can than render parts of this light map strip by strip (render it over the strip after you've rendered the last tile in that strip since - obviously - the light map has to be applied over the map). You can use the same image-map just use that strip as a clip for Graphics - you will need to translate that strip polygon down per render of a strip.
Anyway, like I said I don't guarantee this is the most optimal way - but so far it is working fine for me.
The light map is applied p

Getting nearest focused object in opengl

I'm making a minecraft-inspired game through Java LWJGL, which is heavy into development already. However, I am not quite sure what method I would use to pick/highlight the nearest block in the exact center of the player's view frustum.
I am already storing frustum and positional data, which I could use.
I had a vague idea about using raycasting, but this seems to be unrelated based on what people have done with raycasting.
So which function or test would I use to determine this?
Raycasting will definitively work. You need to create a ray from the orientation of your camera and its position.
If your camera rotation matrix has no scale, the axis is the third column ( the z-axis ). Now depending on your convention, z axis may point to screen or to the world

OpenGL: Create a sky box?

I'm new to OpenGL. I'm using JOGL.
I would like to create a sky for my world that I can texture with clouds or stars. I'm not sure what the best way to do this is. My first instinct is to make a really big sphere with quadric orientation GLU_INSIDE, and texture that. Is there a better way?
A skybox is a pretty good way to go. You'll want to use a cube map for this. Basically, you render a cube around the camera and map a texture onto the inside of each face of the cube. I believe OpenGL may include this in its fixed function pipeline, but in case you're taking the shader approach (fixed function is deprecated anyway), you'll want to use cube map samplers (samplerCUBE in Cg, not sure about GLSL). When drawing the cube map, you also want to remove translation from the modelview matrix but keep the rotation (this causes the skybox to "follow" the camera but allows you to look around at different parts of the sky).
The best thing to do is actually draw the cube map after drawing all opaque objects. This may seem strange because by default the sky will block other objects, but you use the following trick (if using shaders) to avoid this: when writing the final output position in the vertex shader, instead of writing out .xyzw, write .xyww. This will force the sky to the far plane which causes it to be behind everything. The advantage to this is that there is absolutely 0 overdraw!
Yes.
Making a really big sphere has two major problems. First, you may encounter problems with clipping. The sky may disappear if it is outside of your far clipping distance. Additionally, objects that enter your sky box from a distance will visually pass through a very solid wall. Second, you are wasting a lot of polygons(and a lot of pain) for a very simple effect.
Most people actually use a small cube(Hence the name "Sky box"). You need to render the cube in the pre-pass with depth testing turned off. Thus, all objects will render on top of the cube regardless of their actual distance to you. Just make sure that the length of a side is greater than twice your near clipping distance, and you should be fine.
Spheres are nice to handle as they easily avoid distortions, corners etc. , which may be visible in some situations. Another possibility is a cylinder.
For a really high quality sky you can make a sky lighting simulation, setting the sphere colors depending on the time (=> sun position!) and direction, and add some clouds as 3D objects between the sky sphere and the view position.

How would one implement an FPS camera?

So I'm currently working on some FPS game programming in OpenGL (JOGL, more specifically) just for fun and I wanted to know what would be the recommended way to create an FPS-like camera?
At the moment I basically have a vector for the direction the player is facing, which will be added to the current player position upon pressing the "w" or forward key. The negative of that vector is of course used for the "s" or backward key. For "a", left, and "d", right I use the normal of the direction vector. (I am aware that this would let the player fly, but that is not a problem at the moment)
Upon moving the mouse, the direction vector will be rotated using trigonometry and matrices. All vectors are, of course, normalized for easy speed control.
Is this the common and/or good way or is there an easier/better way?
The way I have always seen it done is using two angles, yaw and pitch. The two axes of mouse movement correspond to changes in these angles.
You can calculate the forward vector easily with a spherical-to-rectangular coordinate transformation. (pitch=latitude=φ, yaw=longitude=θ)
You can use a fixed up vector (say (0,0,1)) but this means you can't look directly upwards or downwards. (Most games solve this by allowing you to look no steeper than 89.999 degrees.)
The right vector is then the cross product of the forward and up vectors. It will always be parallel to the ground plane since the up vector is always perpendicular to the ground plane.
Left/right strafe keys then use the +/-right vector. For a forward vector parallel to the ground plane, you can take the cross product of the right and the up vectors.
As for the GL part, you can simply use gluLookAt() using the player's origin, the origin plus the forward vector and the up vector.
Oh and please, please add an "invert mouse" option.
Edit: Here's an alternative solution which gets rid of the 89.9 problem, asked in another question, which involves building the right vector first (with no pitch information) and then forward and up.
Yes, thats essentially the way I have always seen it done.
Yeah, but in the end you will want to add various other attributes to the camera. To spell it n00b: keep it tidy if you want to mimic Quake or CS. In the end might have bobing, FoV, motion filtering, network lag suspension and more.
Cameras are actually one of the more difficult parts to make in a good game. That's why developers usually are content with a seriously dull, fixed 1st/3rd person ditto.
You could use Quaternions for your camera rotation. Although I have not tried it myself, they are useful for avoiding gimbal lock.

Determining visible area from globe frustum

I'm working with a mapping application (worldwind) and trying to determine the minimum and maximum latitudes and longitudes that are currently displayed. I have access to the frustum, but I'm not sure how to account for the fact that the globe can have its heading and/or pitch changed. Any help on this problem would be appreciated.
thanks,
Jeff
Actually the Frustum isn't the most useful thing in this context. What you need to do is reverse the ModelView-Project transform.
If you can retrieve your projection (frustum) and model-view matrices, then you can invert them. If you project a ray from your camera position along projection space, then you can use those inversions to find that ray in world space. From there, you can intersect that ray with your world to find the exact point where that ray hits the globe.
Do this for the four corners of the screen and then calculate your 2D bounding box based upon those intersection coordinates.
What exactly are you trying to calculate ? Corner points of your window or that of your globe. Remember a circle does not have corners (nor does a sphere). Have you seen the minimap tool in worldwind (WorldMapLayer) . It shows the currently visible extent as an overlay in the minimap, this can give you an idea to work out what exactly is being displayed.
Good to see worldwind questions flowing everywhere. We mustn't be doing a good enough job at the forums.
The corner cases (1) of my previous proposal are making the algorithm difficult for you (I've never had to zoom out from the globe and still don't understand why you still don't just use the hemisphere in that case), so here is another method that can work.
Take your projection frustum as a 3D object and intersect it with the globe (as a 3D object). There are a variety CSG algorithms that can give you union, intersection, and difference. Use intersection. This will result in a 3D mesh of the pieces of the globe that intersect with the frustum. The extents of that mesh are the extents of the bounding box. (Project along the major axis of the frustum.)
This is horribly less efficient than my previous proposal. :-)
(1) Pun completely intended.

Categories

Resources