Allegro.cc - Online Community

Allegro.cc Forums » Game Design & Concepts » 3D game design + my skybox works!

This thread is locked; no one can reply to it. rss feed Print
 1   2   3   4 
3D game design + my skybox works!
Edgar Reynaldo
Member #8,592
May 2007
avatar

Well, I finally got my skybox to work correctly. I gave up on using two triangle fans to render half the cube each, and just used a triangle fan for each side.

I've learned quite a bit from dabbling in OpenGL with Allegro. First, allegro text won't render if GL_CULL_FACE is enabled. Two, you must set the color and texture position of a vertex before specifying the vertex with glVertex. I was specifying the texture coordinate after the vertex, which caused it to apply to the next vertex and made everything off by one.

{"name":"611354","src":"\/\/djungxnpq2nug.cloudfront.net\/image\/cache\/0\/f\/0fb79bd2fd10457512d788ae7d5e7631.png","w":802,"h":633,"tn":"\/\/djungxnpq2nug.cloudfront.net\/image\/cache\/0\/f\/0fb79bd2fd10457512d788ae7d5e7631"}611354

Skybox.zip (win32 binary + src + data)

Neil, I guess you were right after all. :-X

So my questions are, what should I do with my 3D environment? Should I make some terrain now? Or should I make a 3D Maze? I can use Kruskal's algorithm to remove faces from rooms, creating exits. I've always wanted to make a dungeon crawler of some sort.

Mark Oates
Member #1,146
March 2001
avatar

I think the easiest thing to do is use a gameplay mechanic you're familiar with from 2D, but with 3D components. So like, a top-down "2d" tank game or dungeon or something.

My only true 3D games (3D with OpenGL/DirectX) are The Path, Alex Park, and A Slug's Life. The Path is point-and-click with a 3D engine, Alex Park is sim-city 2D gameplay but with 3D, while A Slug's Life is true 3D gameplay.

The architecture quality of all three of those are far below what I would prescribe in terms of a "proper" 3D game engine. My progress has advanced substantially since then, and I'm super eager to finally get all my new thoughts into a proper engine.

Edgar Reynaldo
Member #8,592
May 2007
avatar

I have a basic terrain height map complete now. Wasn't too hard. Everything looked pretty crazy until I realized I swapped my y and z values.

{"name":"611356","src":"\/\/djungxnpq2nug.cloudfront.net\/image\/cache\/c\/4\/c455640bcde5b52dde191d3dc9e2f00d.png","w":802,"h":633,"tn":"\/\/djungxnpq2nug.cloudfront.net\/image\/cache\/c\/4\/c455640bcde5b52dde191d3dc9e2f00d"}611356

Eric Johnson
Member #14,841
January 2013
avatar

Nicely done. Your terrain makes me think of those jagged memory foam topper things. :P

{"name":"13287355_Alt01","src":"\/\/djungxnpq2nug.cloudfront.net\/image\/cache\/c\/7\/c7675cc1d631a195933bfc13a417da6c.jpg","w":520,"h":520,"tn":"\/\/djungxnpq2nug.cloudfront.net\/image\/cache\/c\/7\/c7675cc1d631a195933bfc13a417da6c"}13287355_Alt01

Edgar Reynaldo
Member #8,592
May 2007
avatar

Neil Roy
Member #2,229
April 2002
avatar

Neil, I guess you were right after all. :-X

(Marks calender and takes a screencap of that). ;) Glad you got it working. If text isn't appearing with cull face enabled, that tells me it's facing the wrong direction. Facing away from the camera and so being culled and not drawn.

I started out doing 3D terrain. Later on I decided to go more simpler, similar to Mark's suggestions, and I went with a more "2D" 3D environment, and that is my City3D. It is basically just a cube world (like Minecraft, only I created it LONG before Minecraft ever existed) laid out in a simple 2D style grid. Then some sections of the grid are marked to have one of two different height buildings (cubes), and I apply building textures to the sides of it and a roof to the top. For collission I also used 2D colission detection, just based on that grid again. You can't travel over a grid location that has a building, which is pretty simple. Later on I added in code to check your height (though flying was never planned) so you could fly over the buildings if your Y axis was higher than the current building height (I have two heights at this time). Pretty simple, some tiles are marked as different road sections and just have different textures applied... or grass.

For a dungeon you could do something similar, have a grid where the dungeon is marked like a 2D game, only you could have different styled cubes for the various walls and ceiling. You wouldn't really need a skybox in a dungeon unless you want an outside area with a town, like in roguelikes/Diablo 1 style.

I have yet to create a complete game in 3D, I mostly just mess around with it. :)

I want to enable the ability for my own City3D "game" to import simple models for the buildings, replace the cubes and add in traffic etc. Been messing with 3D models as well. I have a simple model format loaded, but it doesn't support textures well. I looked into wavefront OBJ format... oh man... maybe I'll stick to 2D! ;D

Edgar Reynaldo
Member #8,592
May 2007
avatar

Mark Oates
Member #1,146
March 2001
avatar

Quote:

obj

You might be interested in my Model3D class and Model3DObjLoader. The latter loads .obj files and imports them to the more allegro-usable Model3D format. These classes come with my standard "I would write it differently if I wrote it today" disclaimer, but if I recall correctly, it's feature complete - it loads all features of the .obj format, and, all of which are supported on Model3D.

- model3d.h
- model3d.cpp
- model3d_obj_loader.h
- model3d_obj_loader.cpp

(Actually looking over it now, it's not too far off from how I might approach writing these classes today. I'd throw some more exceptions, have it test thoroughly, privatize the member variables, add a few getters/setters, etc, mostly cosmetic stuff though :)).

Note that this does not include the correlated .mtl or "material" file that may accompany the .obj file. To have control over the texture, color, and shading, you would use whatever shader you have currently running, and some combination of the functions:

- Model3D::set_texture(ALLEGRO_BITMAP *tx)
- Model3D::set_named_object_texture(...) (2 overloads)
- Model3D::set_named_object_color(...) (2 overloads)

Aaron Bolyard
Member #7,537
July 2006
avatar

3D is great!

I've been adding 3D support to Love2D:

{"name":"611357","src":"\/\/djungxnpq2nug.cloudfront.net\/image\/cache\/8\/1\/81356a56a6191214a8d5447c6e32e797.png","w":802,"h":632,"tn":"\/\/djungxnpq2nug.cloudfront.net\/image\/cache\/8\/1\/81356a56a6191214a8d5447c6e32e797"}611357

Neil Roy
Member #2,229
April 2002
avatar

You might be interested in my Model3D class and Model3DObjLoader.

Nice, thanks, I'll check it out. It's the materials that got me. Avoiding them would simplify things.

There is a library out there for loading models called ASSIMP... it seems to load it all, materials etc... but... I dunno. I read a tutorial on it and my head about exploded! ;)

This is what I managed in my own little program... I basically loaded in a 3DStudio ASC file, which was simple enough. I could probably expand on that more with textures as well.

{"name":"611358","src":"\/\/djungxnpq2nug.cloudfront.net\/image\/cache\/6\/b\/6bfbf9dbaac5870adb205ea613c5b227.png","w":765,"h":809,"tn":"\/\/djungxnpq2nug.cloudfront.net\/image\/cache\/6\/b\/6bfbf9dbaac5870adb205ea613c5b227"}611358

Edit: I was looking at your code and I noticed you had...

struct named_object {
      public:
   // ...
}

structs in C++ are public by default (they have to be in order to be compatible with C actually), there's no need for a specifier like that. Structs are public by default, classes as private by default.

Eric Johnson
Member #14,841
January 2013
avatar

So I began learning WebGL recently (basically doing OpenGL on the Web). Things like GLSL and matrices are foreign to me, so it's all quite confusing so far (but it's getting easier). Anyway, newbie question: why does OpenGL draw textures upside-down? Am I doing something wrong, or is that just or how it is? And yeah, I know I can fix it with transformations. Just curious though.

Edgar Reynaldo
Member #8,592
May 2007
avatar

Neil Roy
Member #2,229
April 2002
avatar

why does OpenGL draw textures upside-down?

The reason has to do with the co-ordinate system used in 3D. The starting point for textures is the bottom left corner and then positive goes to the right and up which is in line with how 3D co-ordinates work. This is easily compensated for in your GLSL shader code. When you load in the texture co-ordinates you can flip the vertical co-ordinate to match the textures orientation.

OpenGL isn't upside down

They are when compared to texture co-ordinates. Texture co-ordinates start in the upper left corner. In OpenGL texture co-ordinates start in the bottom left corner.

Eric Johnson
Member #14,841
January 2013
avatar

Neil Roy said:

The reason has to do with the co-ordinate system used in 3D. The starting point for textures is the bottom left corner and then positive goes to the right and up which is in line with how 3D co-ordinates work. This is easily compensated for in your GLSL shader code. When you load in the texture co-ordinates you can flip the vertical co-ordinate to match the textures orientation.

Interesting. Thanks for the explanation.

I'm only interested in doing 2D stuff with OpenGL right now. My math skills aren't good enough for 3D just yet. So far I've managed to display an image on the screen by creating two triangles (is that what they call a "quad"?) to form a rectangle and then putting the texture on that. I still need to work out how to render it to pixel space and do transformations. I'm reading up on matrices right now.

Chris Katko
Member #1,881
January 2002
avatar

Well, I finally got my skybox to work correctly.

Told you it'd work. ;)

-----sig:
“Programs should be written for people to read, and only incidentally for machines to execute.” - Structure and Interpretation of Computer Programs

Edgar Reynaldo
Member #8,592
May 2007
avatar

LennyLen
Member #5,313
December 2004
avatar

According to who?

Pretty much every computer graphics system since the 1970s, possibly earlier.

Edgar Reynaldo
Member #8,592
May 2007
avatar

Chris Katko
Member #1,881
January 2002
avatar

Real men only use polar coordinates for screen coordinates. 8-)

-----sig:
“Programs should be written for people to read, and only incidentally for machines to execute.” - Structure and Interpretation of Computer Programs

Edgar Reynaldo
Member #8,592
May 2007
avatar

Neil Roy
Member #2,229
April 2002
avatar

I should reword that... IMAGE co-ordinates start in the upper left corner. Texture co-ordinates in OpenGL start in the bottom left (I just noticed my wording, but LennyLen understood what I meant).

When you load an image into OpenGL and assign it to vertices, in GLSL you can REALLY easily flip it so the two match. Either that, or you can flip the image itself vertically after being loaded (which is more work than needed) or flip it before it is loaded, when you create it.

Personally, the GLSL shader solution is the simplest.

According to who? Besides, D3D sucks. OpenGL is the only hardware accelerated graphics library I care to care about.

I meant image co-ordinates, LennyLen understood, and I think you did too, you just like to argue I think. Anyhow, where in the hell did you see me even mention D3D?! I am talking about OpenGL. The images you load... have their co-ordinates in the upper left, OpenGL is in the bottom left, which is why the images can come up flipped upside down (which was the original comment I was responding to). There are simple solutions that I already mentioned. But your original response that opengl does not flip them was wrong, it most certainly does when they are in the bottom left corner instead of the upper left which is what all images use.

Edgar Reynaldo
Member #8,592
May 2007
avatar

No, not meaning to be argumentative (maybe) but images and textures are not the same thing. And when I referred to D3D, their texture coordinates do indeed start at 0.0,0.0 being the top left and 1.0,1.0 being bottom right. Which is nonsense, because world space goes up right. But OpenGL likes to make Z point towards you, which is BS if you ask me. But all it takes to fix it is a simple glScale3d(1.0,1.0,-1.0); call, so what is there to complain about.

   back_on_topic = this->thread->avoid(THREAD_DERAIL);

What I really want to talk about is what to do with my maze. I'm in the middle of generating the edge removal code. I've got it to O(N), which is awesome, because the big O of my old 2D maze code was terrible. I think it was O(N^2) but I'm not sure. I had terrible performance keeping the edges in a linked list until I changed it to use a vector.

So, any ideas what to do with the maze? I've thought of a few things, like after generating the maze to make some larger rooms by removing a few more edges and creating some cycles and open space. I've thought of deforming the vertices of the maze, so it makes more natural inclines. My maze is based on unit cubes, and if I move a single vertice by 0.5 then I can create widths of between 0.0 and 2.0 or more.

I've also thought of adding in 3D objects (likely creatures, but maybe inanimate objects like furniture as well).

Anyone feel like creating a team to work on this and write some code?

It would be pretty dang cool to make something like Eye of the Beholder, or Doom, or Quake or whatever.

Up to you guys. You can monitor my progress on GitHub here :

https://github.com/EdgarReynaldo/Maze3D

Anyway, back to work on my kruskalification (trust me, that's a real word) process. ;)

Chris Katko
Member #1,881
January 2002
avatar

But OpenGL likes to make Z point towards you,

It's just left vs right-handed coordinate systems. They're as old as math.

https://www.evl.uic.edu/ralph/508S98/coordinates.html

https://msdn.microsoft.com/en-us/library/windows/desktop/bb204853(v=vs.85).aspx

https://softwareengineering.stackexchange.com/questions/17519/why-does-directx-use-a-left-handed-coordinate-system?utm_medium=organic&utm_source=google_rich_qa&utm_campaign=google_rich_qa

A standard is just arbitrary convention. Flipping 0 to 1, and vice-versa really isn't that big a deal.

I mean, if I were to pick, I'd probably scold Direct3D for not following OpenGL "just to be different" when it had been around for years as a industry standard. In fact, in school I was taught right-hand rule as "better", and even a poster from SO in the link, mentions he was taught "right-hand rule" back in the 70's as the preferred convention. So AFAICT, Direct3D decided to be !@$!holes just for the sake of being !@$!holes.

But again, it's just numbers. It reminds me of circuit theory. There's two competing conventions to draw the direction of electron flow. "Conventional" vs "Electron Flow." The original one shows electrons moving from positive to negative which is what Newton/whoever "thought" they traveled. But electrons travel from negative to positive (*except they don't always, it depends on the carrier medium). So do we use the convention "as designed by Newton/whoever", or do we use the INTENT of the convention as designed by whoever? An interesting question with no right answer that of course fuels blood wars for centuries after the death of the author.

OH, but the key is, "as long as they're used consistently, it doesn't matter which is used."

[edit] Oh, the SO post brings up another point. I haven't touched shaders in forever so I forgot:

- In OpenGL "Shaders use left-hand rule when working with default depth range." Even if the Window coordinates are right-hand rule!

So again, as long as you remember the coordinate transforms, it doesn't really matter. You're going to have to convert coordinates no matter what you do!

OpenGL transformation overview:

- http://www.songho.ca/opengl/gl_transform.html

Quote:

9.011 How are coordinates transformed? What are the different coordinate spaces?

Object Coordinates are transformed by the ModelView matrix to produce Eye Coordinates.

Eye Coordinates are transformed by the Projection matrix to produce Clip Coordinates.

Clip Coordinate X, Y, and Z are divided by Clip Coordinate W to produce Normalized Device Coordinates.

Normalized Device Coordinates are scaled and translated by the viewport parameters to produce Window Coordinates.

Object coordinates are the raw coordinates you submit to OpenGL with a call to glVertex*() or glVertexPointer(). They represent the coordinates of your object or other geometry you want to render.

Many programmers use a World Coordinate system. Objects are often modeled in one coordinate system, then scaled, translated, and rotated into the world you're constructing. World Coordinates result from transforming Object Coordinates by the modelling transforms stored in the ModelView matrix. However, OpenGL has no concept of World Coordinates. World Coordinates are purely an application construct.

Eye Coordinates result from transforming Object Coordinates by the ModelView matrix. The ModelView matrix contains both modelling and viewing transformations that place the viewer at the origin with the view direction aligned with the negative Z axis.

Clip Coordinates result from transforming Eye Coordinates by the Projection matrix. Clip Coordinate space ranges from -Wc to Wc in all three axes, where Wc is the Clip Coordinate W value. OpenGL clips all coordinates outside this range.

Perspective division performed on the Clip Coordinates produces Normalized Device Coordinates, ranging from -1 to 1 in all three axes.

Window Coordinates result from scaling and translating Normalized Device Coordinates by the viewport. The parameters to glViewport() and glDepthRange() control this transformation. With the viewport, you can map the Normalized Device Coordinate cube to any location in your window and depth buffer.

For more information, see the OpenGL Specification, Figure 2.6.

[...]

9.150 Can I make OpenGL use a left-handed coordinate space?

OpenGL doesn't have a mode switch to change from right- to left-handed coordinates. However, you can easily obtain a left-handed coordinate system by multiplying a negative Z scale onto the ModelView matrix. For example:

glMatrixMode (GL_MODELVIEW); glLoadIdentity (); glScalef (1., 1., -1.); /* multiply view transforms as usual... */ /* multiply model transforms as usual... */

https://www.opengl.org/archives/resources/faq/technical/transformations.htm

[edit] Also, likewise, using DirectX with right-handed:

Quote:

Microsoft Direct3D uses a left-handed coordinate system. If you are porting an application that is based on a right-handed coordinate system, you must make two changes to the data passed to Direct3D.

Flip the order of triangle vertices so that the system traverses them clockwise from the front. In other words, if the vertices are v0, v1, v2, pass them to Direct3D as v0, v2, v1.
Use the view matrix to scale world space by -1 in the z direction. To do this, flip the sign of the M31, M32, M33, and M34 fields of the Matrix structure that you use for your view matrix.
To obtain what amounts to a right-handed world, use the PerspectiveRH and PerspectiveLH methods to define the projection transform. However, be careful to use the corresponding LookAtRH function, reverse the backface-culling order, and lay out the cube maps accordingly.

https://msdn.microsoft.com/en-us/library/windows/desktop/bb324490(v=vs.85).aspx

Also, here's an article on using same data for both DirectX and OpenGL:

https://anteru.net/blog/2011/12/27/1830/index.html

-----sig:
“Programs should be written for people to read, and only incidentally for machines to execute.” - Structure and Interpretation of Computer Programs

Edgar Reynaldo
Member #8,592
May 2007
avatar

Chris Katko said:

OpenGL doesn't have a mode switch to change from right- to left-handed coordinates. However, you can easily obtain a left-handed coordinate system by multiplying a negative Z scale onto the ModelView matrix. For example:

glMatrixMode (GL_MODELVIEW); glLoadIdentity (); glScalef (1., 1., -1.); /* multiply view transforms as usual... */ /* multiply model transforms as usual... */

But OpenGL likes to make Z point towards you, which is BS if you ask me. But all it takes to fix it is a simple glScale3d(1.0,1.0,-1.0); call, so what is there to complain about.

Thanks. ;D

What do you mean shaders use ... what did you say? Are there any decent shader tutorials out there? That tell you the exact semantics of the language without taking 1000 pages?

EDIT

{"name":"righthandrule.png","src":"\/\/djungxnpq2nug.cloudfront.net\/image\/cache\/a\/7\/a77ec8f14e73d88aa51de254265656f4.png","w":875,"h":832,"tn":"\/\/djungxnpq2nug.cloudfront.net\/image\/cache\/a\/7\/a77ec8f14e73d88aa51de254265656f4"}righthandrule.png

Hang loose, man ;)

Neil Roy
Member #2,229
April 2002
avatar

I have thought about a rogue-like dungeon myself and generating random levels for it. Whether it is 2D or 3D wouldn't matter to me as in 3D I would use a grid system like in 2D anyhow.

For generation I thought about randomly placing several large rooms of varying sizes on a map, doing a bounding box collision test to make sure none overlap (I suppose you could allow that though).

Then picking random sides and joining them up to other room's random side and then creating hallways between these points. You could find a point between the two rooms in open space and then create straight walls which meet at that point, creating a hall with a 90 degree turn in it perhaps which links the two.

Keep doing that for so many iterations, perhaps even joining up new halls with old ones etc... could even to a maze creation algorithm which I have played with a lot, treat each large room as a node in that and work from there.

I have generated 3D mazes using depth first and prim's algorithm (and my own C code for stacks I can push and pop from).

You could then have a set of random 3D objects would could be randomly placed in different rooms. You could even create room types which would only allow certain object types which fit the motif.

I haven't actually coded anything for a large roomed maze yet though. It's one of those things I wanted to do. I was actually working on a "3D Text" maze which uses only text character and I came up with a system to make it display larger rooms with just text characters.

I created a video showing part of the work a while back...

video

...I thought about making a full OpenGL 3D version of it. Shouldn't be too difficult it is uses textured cubes (like Wolfenstien 3D did).

 1   2   3   4 


Go to: