Animations and animation playback added. Posing is better, glitch with animation frame fixed, Objects retain independent armature state, small speedup.
Current Test:
Test it right now!
http://www.gocaco.com/webgl/test1/Test.zip
Current Exporter:
http://www.gocaco.com/webgl/igtl_export_ted.py
This pretty much has everything that's in a TED file, which, for your reference, contains:
Mesh data (coords, texcoords, normals, tangents, matrix palette weights, colors, params)
Textures (including texture data if you want)
Materials (some parameters, illy defined for now.)
Armatures (Includes bones, IK chains, armature splines, lots of data)
Animations (Includes channel blending animations, so channels are seperate and integrated. Includes scripts.)
Scenes (all objects and their properties)
Though there are still more things, this is the basics to get started cleaning this mess up and making it easier to work with. I don;t need the BGE if I can load this stuff into WebGL. That's what's really nice.
Although, it has some really painful disadvantages, mainly input problems, no joystick support, bad keyboard input events, no locking the mouse so no FPS possible... and so on.
Here's 9 marios independently running (bad running animation, I know. took me a minute ok??)
And 25 marios...
Most of the speed is CPU <-> GPU delays. Just remember that 1 gpu "talk" takes 6~100's of CPU cycles because of the bus communication. So, this is a "absolute worse case" naive way to do this, and I still get 15 FPS with 100k fully shaded armatured polygons. As a side note, an average frame of Oblivion as ~200k polygons, but most all of them were static (75% static to 25% dynamic).
-Z
Miscellaneous banter, Useful mathematics, game programming tools and the occasional kink or two.
Showing posts with label opengl. Show all posts
Showing posts with label opengl. Show all posts
2011-04-10
2011-03-29
WebGL - YES!
First, go here to update your Firefox (or use Chrome):
http://www.mozilla.com/en-US/firefox/all.html
In firefox 4.0, you have to enable this feature manually,
First type in "about:config" in the address bar,
Don't let it scare you,
Sort the items by name,
Find the "webgl.force_enabled" and double click that to make it true.
http://www.mozilla.com/en-US/firefox/all.html
In firefox 4.0, you have to enable this feature manually,
First type in "about:config" in the address bar,
Don't let it scare you,
Sort the items by name,
Find the "webgl.force_enabled" and double click that to make it true.
Now, go find some sweet OpenGL ES 2.0 type demos.
!!! ACHTUNG !!!
--> Make absolutely sure you have the NoScript AddOn (http://noscript.net/) for firefox first. This will allow you to STOP content from automatically loading, just in case you are like me and are trigger happy.
http://www.khronos.org/webgl/wiki/Demo_Repository
http://www.chromeexperiments.com/webgl
This is great because it eliminates the need for stupid plugins like Unity, Flash, Shockwave, Java, ect...
Now you can use the ECMA script (Javascript) built into the browser to make full powered 3D games, which now are compliant to any browsers that use them!
This is serious cool. I'm totally making something in this.
-Z
Labels:
opengl,
programming,
webgl
2010-06-11
GHOST, Mingl, XCore, Core, XGFX
Continually working on improving all the above components;
Here is a quick overview of what all this garbage is:
ghost - Lets you make programs for X11, Windows, Mac
mingl - Draws stuff in hardware lingo
core - Does everything you don't want to write yourself
xcore - Does things you should be doing anyways
xgfx - Makes everything look pretty + move around
In more details:
GHOST - Made primarily by the Blender.org guys; this is their generic host operating system toolkit; In other words, this is the code that allows you to receive low level input events and a OpenGL context; And the ability to create windows and draw to them/receive messages from them. I've heavily modified it to include some more game-friendly features, timing looks, multithreading and some specialized input event abstractions, joysticks support and other goodies. It's at least as good as SDL, and in many ways, far superior. Hard to find something better than code that has been attacked by many people.
Mingl - "Minimum Graphics Library"; essentially a wrapper around OpenGL; but, it's designed to specifically mimic OpenGL 3.0 specifications, and does an insanely good job of managing more annoying aspects of OpenGL programming; It makes writing graphical routines trivial, where you may spend hours trying to orient yourself in 3D space using any other toolkit (that includes you, blender. F*** your armature space conventions!). However, it's also interface abstracted just like GHOST, so it can use OpenGL, DirectX, software... it doesn't care. But it is primarily designed to expose low level hardware techniques to force you to write more efficient graphics code; and does a ton of things internally (like managing VBO/IBO/RC, states, transformations, ect...). It is still missing FBO operations, but those are trivial if you have a GL 2.0 + system (just need to sit down and do this)
XCore - Operating system and hacking level tools. A quite extensive library I made of tools I use frequently, such as texture conversions from DXT to / from anything, mathematical algorithms, VA/IA generation algorithms, numerical methods, statistics, even some unique IK algorithms and other tools. IT also contains agressive memory management and a slew of commonly used structures.
Core - The heart of everything; Based on the std C++ library; core contains separate components that should not rely on any one other component, like vec3 vec4, matrix3x3, matrix4x4, index_array, geo, and a lot of other commonly used, but often not needed tools. Chances are if you need any one of these tools, you need all of them.
XGFX - My rendering system built ontop of using mingl as the renderer interface. IS still under construction for the resource abstraction and management of massive resources.
No good screenshots; Just the city level again after implementing multithreaded loading + mingl improvements.
Here is a quick overview of what all this garbage is:
ghost - Lets you make programs for X11, Windows, Mac
mingl - Draws stuff in hardware lingo
core - Does everything you don't want to write yourself
xcore - Does things you should be doing anyways
xgfx - Makes everything look pretty + move around
In more details:
GHOST - Made primarily by the Blender.org guys; this is their generic host operating system toolkit; In other words, this is the code that allows you to receive low level input events and a OpenGL context; And the ability to create windows and draw to them/receive messages from them. I've heavily modified it to include some more game-friendly features, timing looks, multithreading and some specialized input event abstractions, joysticks support and other goodies. It's at least as good as SDL, and in many ways, far superior. Hard to find something better than code that has been attacked by many people.
Mingl - "Minimum Graphics Library"; essentially a wrapper around OpenGL; but, it's designed to specifically mimic OpenGL 3.0 specifications, and does an insanely good job of managing more annoying aspects of OpenGL programming; It makes writing graphical routines trivial, where you may spend hours trying to orient yourself in 3D space using any other toolkit (that includes you, blender. F*** your armature space conventions!). However, it's also interface abstracted just like GHOST, so it can use OpenGL, DirectX, software... it doesn't care. But it is primarily designed to expose low level hardware techniques to force you to write more efficient graphics code; and does a ton of things internally (like managing VBO/IBO/RC, states, transformations, ect...). It is still missing FBO operations, but those are trivial if you have a GL 2.0 + system (just need to sit down and do this)
XCore - Operating system and hacking level tools. A quite extensive library I made of tools I use frequently, such as texture conversions from DXT to / from anything, mathematical algorithms, VA/IA generation algorithms, numerical methods, statistics, even some unique IK algorithms and other tools. IT also contains agressive memory management and a slew of commonly used structures.
Core - The heart of everything; Based on the std C++ library; core contains separate components that should not rely on any one other component, like vec3 vec4, matrix3x3, matrix4x4, index_array, geo, and a lot of other commonly used, but often not needed tools. Chances are if you need any one of these tools, you need all of them.
XGFX - My rendering system built ontop of using mingl as the renderer interface. IS still under construction for the resource abstraction and management of massive resources.
No good screenshots; Just the city level again after implementing multithreaded loading + mingl improvements.
2010-06-04
TED Exporting + Mingl
"Walk the Walk"
I talk a lot of smack about things that I do. It's really nice when I visit artists that I can actually pop open their files and show them how to export them so I can load them in game.
It's much easier to convince people you aren't just blowing smoke when you can show them what you are doing in real time. Hard to dispute that kind of presentation.
So, more improvements on the TED file's; the exporter is more robust, and I'm in the process of verifying the data output is correct. So far this seems to be true, I've seen textures, models, scenes, and just about everything in the file working perfectly, especially animations. It's wonderful to just be able to load in a file directly exported from blender, and import it, then see your work immediately and accurately duplicated in a realtime game.
So here are some example shots; the next long haul is building the xgfx resource management system so I can maintain a logical coherence for all of these vastly different resources + files. Resources are essentially reference counted, but are not cleared until flagged to do so. Instance objects exist physically, so once they terminate they just dump all data. Plenty of re-use optimizations, tons of weird paradigms like "resource-source-instance" ideas with meshes; But this will be demonstrated eventually.
In order from top left clockwise;
Rayne from BloodRayne on PC with a static keyframe applied,
two of my custom levels,
Charizard from Super Smash Brothers Brawl on Wii with standard_wobble applied and hacked texture
another custom level,
The first boss from Dragon Blade on Wii, with wobble, note the material colors are showing now; easily removed.
Bowser Trophy from Super Smash Brothers Brawl on Wii
Rayquaza Boss from Super Smash Brothers Brawl on Wii with wobble.
Looks like I need a damn artist.
-Z
I talk a lot of smack about things that I do. It's really nice when I visit artists that I can actually pop open their files and show them how to export them so I can load them in game.
It's much easier to convince people you aren't just blowing smoke when you can show them what you are doing in real time. Hard to dispute that kind of presentation.
So, more improvements on the TED file's; the exporter is more robust, and I'm in the process of verifying the data output is correct. So far this seems to be true, I've seen textures, models, scenes, and just about everything in the file working perfectly, especially animations. It's wonderful to just be able to load in a file directly exported from blender, and import it, then see your work immediately and accurately duplicated in a realtime game.
So here are some example shots; the next long haul is building the xgfx resource management system so I can maintain a logical coherence for all of these vastly different resources + files. Resources are essentially reference counted, but are not cleared until flagged to do so. Instance objects exist physically, so once they terminate they just dump all data. Plenty of re-use optimizations, tons of weird paradigms like "resource-source-instance" ideas with meshes; But this will be demonstrated eventually.
In order from top left clockwise;
Rayne from BloodRayne on PC with a static keyframe applied,
two of my custom levels,
Charizard from Super Smash Brothers Brawl on Wii with standard_wobble applied and hacked texture
another custom level,
The first boss from Dragon Blade on Wii, with wobble, note the material colors are showing now; easily removed.
Bowser Trophy from Super Smash Brothers Brawl on Wii
Rayquaza Boss from Super Smash Brothers Brawl on Wii with wobble.
Looks like I need a damn artist.
-Z
2010-05-14
TED file format; Restricted XML
Ever notice how awful XML documents are?
Well, I upgraded my model exporter from blender to 2.49b; so now, instead of the annoying variety of formats I used to use (obm, arf, brf arf2.0, brf3.0, grf, iRF) I decided to spec out a more logical, easier to understand but far more byte/size inefficient DXML format.
I call it "TED" (Text Extracted Data).
The goal of TED files is to export the maximum usable, useful information out of Blender 2.49b+.
What TED files should NOT be used for:
I have not made the exporter for 2.5.2 yet because I have been burned many times by blender changing specifications mid-stream on me. Luckily, the ted exporter is written to avoid this as much as possible; but when more alpha versions come out I will snap one in easily. Until then, 2.49b it is.
If I could show you a .TED file I would; but HTML can't understand < > signs.
Have a dragon instead (All credit goes to DragonBlade from the Wii; Obviously I'll never use this model, it just happens to be the first example I picked)

Blender on the left, mingl without GLSL on the right (in-game)
-Z
Well, I upgraded my model exporter from blender to 2.49b; so now, instead of the annoying variety of formats I used to use (obm, arf, brf arf2.0, brf3.0, grf, iRF) I decided to spec out a more logical, easier to understand but far more byte/size inefficient DXML format.
I call it "TED" (Text Extracted Data).
The goal of TED files is to export the maximum usable, useful information out of Blender 2.49b+.
- This includes Meshes, Armatures, Animations, Objects, Materials, Textures, and some scripting and logic elements. Meshes should contain enough data to be GLSL renderable (IE normals, tangents, uv layers, parameters).
- TED files must also conform to a very strict file standard, so there will be NO allowed coordinate systems other than the default universal correct system (RHR, +X forward, +Y left, +Z up; This is universal for ALL transforms. Matrices also have a standard definition of Xx Xy Xz Yx Yy Yz Zx Zy Zz where X is the forward axis, Y is the left axis, Z is the up axis. Quaternions follow these definitions as well.)
- TED files must be easy to read in; Though they are not (byte) efficient, they should contain "hints" for a loader so it may allocate elements beforehand; for example declaring the number of elements in an array before reading it in. You might notice .TED files can be
- TED files must maintain a logical and render-system friendly data model; And must encapsulate all data elements; No element can have differing types of data; ergo a tag can store an array of strings, an array of ints, an array of floats, or other tags ONLY.
What TED files should NOT be used for:
- Final game data (you should convert to your own or local host format)
- Final Level descriptions (TED files do not provide hashing or optimizations or portals of scenes)
- Replacing something you already understand (unless it has something you need; just make a converter to convert TED to whatever)
I have not made the exporter for 2.5.2 yet because I have been burned many times by blender changing specifications mid-stream on me. Luckily, the ted exporter is written to avoid this as much as possible; but when more alpha versions come out I will snap one in easily. Until then, 2.49b it is.
If I could show you a .TED file I would; but HTML can't understand < > signs.
Have a dragon instead (All credit goes to DragonBlade from the Wii; Obviously I'll never use this model, it just happens to be the first example I picked)

Blender on the left, mingl without GLSL on the right (in-game)
-Z
Labels:
blender,
blender python,
data structures,
dragon,
mingl,
opengl
2010-01-29
Picking, Mouse Projections, Screen to Ray
The Problem:
When the user clicks on the 2D screen, how do we know in 3D coordinates where they actually clicked, so we can select the object they clicked on?
The Solution:
Obviously a simple geometric / linear algebra problem. It is commonly done by querying the graphics card for the projection, modelview, and viewport. I despise asking the card for anything, as it should be a one way pipe. (minus CUDA, which is still new).
Our special case is, if we know how we constructed the projection matrix, we can easily invert the process to convert a screen ray into world coordinates. Then we can make those world coordinates relative to our "camera" matrix, and you can then perform a ray to scene collision detection;
This is also called "picking", "selection", and has a variety of other names. I highly reccomend never using any method but your own geometric methods, since you can't rely on this type of functionality to be consistent, without ensuring your own code is.
In layman terms, "You can click things in 3D" / "What you see is what you get"
The orange dot is the actual 3D position of the Ray -> AABB intersection
(A Ray is defined by a point and a direction, a AABB is a axis aligned bounding box, so it has a minimum position and a maximum position, or a center and a half-size for each axis)
Here's some code snippet:
Works beautifully! Onward with my megaman project.
-Z
When the user clicks on the 2D screen, how do we know in 3D coordinates where they actually clicked, so we can select the object they clicked on?
The Solution:
Obviously a simple geometric / linear algebra problem. It is commonly done by querying the graphics card for the projection, modelview, and viewport. I despise asking the card for anything, as it should be a one way pipe. (minus CUDA, which is still new).
Our special case is, if we know how we constructed the projection matrix, we can easily invert the process to convert a screen ray into world coordinates. Then we can make those world coordinates relative to our "camera" matrix, and you can then perform a ray to scene collision detection;
This is also called "picking", "selection", and has a variety of other names. I highly reccomend never using any method but your own geometric methods, since you can't rely on this type of functionality to be consistent, without ensuring your own code is.
In layman terms, "You can click things in 3D" / "What you see is what you get"
The orange dot is the actual 3D position of the Ray -> AABB intersection
(A Ray is defined by a point and a direction, a AABB is a axis aligned bounding box, so it has a minimum position and a maximum position, or a center and a half-size for each axis)
Here's some code snippet:
From reading that code, you'll notice the projection matrix is defined by:class matrix
{
public:
//+X = left, +Y = up, +Z = forward
float Xx, Xy, Xz, Xw; //Order from spec; Colum major 0..16. Have to transpose all the mathematics (internally)
float Yx, Yy, Yz, Yw;
float Zx, Zy, Zz, Zw;
float x, y, z, w;
...
void mingl::matrix::frustum_get_ray( int umouse_x, int umouse_y, int window_w, int window_h, float distnear, float distfar, float fovangle, float & Rx, float & Ry, float & Rz, float & Rdx, float & Rdy, float & Rdz )
{
float scrn_x = (float)(2*umouse_x - window_w) / ((float)window_w);
float scrn_y = -(float)(2*umouse_y - window_h) / ((float)window_h);
float td_dx, td_dy;
float td_tan = tan( fovangle * (M_PI/360.0f) );
if( window_w > window_h ){
td_dx = td_tan * scrn_x * ((float)window_w/(float)window_h);
td_dy = td_tan * scrn_y;
}else{
td_dx = td_tan * scrn_x;
td_dy = td_tan * scrn_y * ((float)window_h/(float)window_w);
}
//Generate points on the projection viewport
float p1[3] = { td_dx*distnear, td_dy*distnear, distnear };
float p2[3] = { td_dx*distfar, td_dy*distfar, distfar };
float dv[3] = { (p2[0] - p1[0]), (p2[1] - p1[1]), (p2[2] - p1[2]) };
//Note this is a specialized "To Global" operation (because of the inversion on axes)
//Ray does not start from center of camera.
Rx = x - Zx * p1[2] + Xx * p1[0] + Yx * p1[1];
Ry = y - Zy * p1[2] + Xy * p1[0] + Yy * p1[1];
Rz = z - Zz * p1[2] + Xz * p1[0] + Yz * p1[1];
//note the conversion.
Rdx = -Zx * dv[2] + Xx * dv[0] + Yx * dv[1];
Rdy = -Zy * dv[2] + Xy * dv[0] + Yy * dv[1];
Rdz = -Zz * dv[2] + Xz * dv[0] + Yz * dv[1];
}
//3D projection matrix via symmetrical frustum; the most common projection.
float fov = 60.0;
float aspect = 1.0;
float unear = 0.125;
float ufar = 1024.0;
float top = tan(fov*0.00872664625997f) * unear; //0.00872665f = pi / 360 = (pi / 180) * 0.5
if( (window_h > 0) && (window_w > 0) ){
if( window_w > window_h ){
aspect = float(window_w)/float(window_h);
projection.frustum( aspect * -top, aspect * top, -top, top, unear, ufar );
}else{
aspect = float(window_h)/float(window_w);
projection.frustum( -top, top, aspect * -top,aspect * top, unear, ufar );
}
}
void mingl::matrix::frustum( float ul, float ur, float ub, float ut, float un, float uf )
{
float dx = (ur-ul);
float dy = (ut-ub);
float dz = (uf-un);
dx = (dx <= 0) ? 1.0 : dx;
dy = (dy <= 0) ? 1.0 : dy;
dz = (dz <= 0) ? 1.0 : dz;
identity();
Xx = (2.0*un)/dx;
Yy = (2.0*un)/dy;
Xz = (ur + ul)/dx;
Yz = (ut + ub)/dy;
Zz = -(uf + un)/dz;
Zw = -1.0;
z = -(2.0*uf*un)/dz;
w = 0;
Works beautifully! Onward with my megaman project.
-Z
2009-11-21
mingl - depth sorting order
Depth sorting is a traditional fix for a variety of problems;
However, it is a unsolvable problem. Consider that you have two long triangles, and you point the camera down the longest side of each. The triangles overlap; So if you draw one before the other, one triangle will depth clip the other, resulting in incorrect blending. The traditional fix is to draw with depth writing disabled, and then draw with color writing disabled. This can fix that special case, but causes other problems like highlights and odd depth clippings.
As a direct result, you generally need to draw all opaque objects first; Then perform the above method, which should correctly render the transparent polygons. however, as it may be obvious, you need a specialized structure to deal with being able to partition and sort your meshes by transparency.
This problem is not related to alpha clipping or depth fragment alpha, which is the problem of a semitransparent object occluding other geometry. In practice, it does well to solve this issue though.
Here is the difference between depth sorting and non depth sorting your objects; Notice there are still some errors, but the effect is minimal:
This effect is largely a matter of taste; And mingl is not responsible for how you draw, only for abstracting the graphics rendering hardware.
In a unrelated event; Any of you that know the Atari 2600 game "Adventure"? Well, you had better know about this hilarity: Adventure 2600 Reboot
Sound familiar?
Yeah. But it's not like my version; and after playing their version, I think I can one up this, so I'll try and make a "Adventure Remix" using my mingl / xcore system. The benefits, are it is something I like to make, as well as something people can probably enjoy messing with for a little bit. I'm just drawing and modeling, but I do not plan to clone or copy the game, instead I want to recreate the spirit of the game, and add my own little improvements. Plus, with my new toon hemi shader, it can look all sorts of shiny.
Til' later;
-Z
However, it is a unsolvable problem. Consider that you have two long triangles, and you point the camera down the longest side of each. The triangles overlap; So if you draw one before the other, one triangle will depth clip the other, resulting in incorrect blending. The traditional fix is to draw with depth writing disabled, and then draw with color writing disabled. This can fix that special case, but causes other problems like highlights and odd depth clippings.
As a direct result, you generally need to draw all opaque objects first; Then perform the above method, which should correctly render the transparent polygons. however, as it may be obvious, you need a specialized structure to deal with being able to partition and sort your meshes by transparency.
This problem is not related to alpha clipping or depth fragment alpha, which is the problem of a semitransparent object occluding other geometry. In practice, it does well to solve this issue though.
Here is the difference between depth sorting and non depth sorting your objects; Notice there are still some errors, but the effect is minimal:
In a unrelated event; Any of you that know the Atari 2600 game "Adventure"? Well, you had better know about this hilarity: Adventure 2600 Reboot
Sound familiar?
Yeah. But it's not like my version; and after playing their version, I think I can one up this, so I'll try and make a "Adventure Remix" using my mingl / xcore system. The benefits, are it is something I like to make, as well as something people can probably enjoy messing with for a little bit. I'm just drawing and modeling, but I do not plan to clone or copy the game, instead I want to recreate the spirit of the game, and add my own little improvements. Plus, with my new toon hemi shader, it can look all sorts of shiny.
Til' later;
-Z
2009-11-17
mingl - progress updates
xcore / mingl is moving along quite well.
Operating on a basic create / destroy paradigm, with bind/unbind as the activation mechanism and load as the data send mechanism, it works well for abstracting graphics hardware and allowing for faster creation of intense graphics applications.
Here's a nonsense screenshot:
This is a vector field represented as moving transparent spheres that are depth sorted. The vector field is generated by 3 functions modulated together.
The shading is generated via vertex and fragment program. The meshes are using a VBO/IBO abstraction paradigm.
All is well. More later.
Operating on a basic create / destroy paradigm, with bind/unbind as the activation mechanism and load as the data send mechanism, it works well for abstracting graphics hardware and allowing for faster creation of intense graphics applications.
Here's a nonsense screenshot:
This is a vector field represented as moving transparent spheres that are depth sorted. The vector field is generated by 3 functions modulated together.
The shading is generated via vertex and fragment program. The meshes are using a VBO/IBO abstraction paradigm.
All is well. More later.
Labels:
code,
fragment program,
opengl,
vbo,
vertex program
2009-11-06
DXT Texture compression
DXT image compression (also S3TC) allows you to save:
DXT1_RGB -> 1:8 RGB 565 4 level only
DXT1_RGBA -> 1:8 RGB 565 4 level and 1 bit alpha channel
DXT5_RGBA -> 1:4 RGB 565 4 level and 7 level alpha channel
As a result, for certain textures DXT can be used to compress images with reasonable loss of clarity.

Most importantly, within the DXT5 compression scheme, you still have 4x4 texel blocks interpolating between two color values. These color values are RGB565 (5 bits of red, 6 bits of gree, 5 bits of blue) and thus the green channel can be more precise. Also, the alpha channel has all 8 bits, but interpolates between 7 alpha values per texel. As a result, you can use DXT5 to store compressed normal maps by storing the x component in the green channel, and the y value in the alpha component. Then, in the shader, you can calculate the missing z value from assuming your normal map was actually normalized (x^2 + y^2 + z^2 = 1).
More updates later.
Z out.
DXT1_RGB -> 1:8 RGB 565 4 level only
DXT1_RGBA -> 1:8 RGB 565 4 level and 1 bit alpha channel
DXT5_RGBA -> 1:4 RGB 565 4 level and 7 level alpha channel
As a result, for certain textures DXT can be used to compress images with reasonable loss of clarity.

More updates later.
Z out.
Labels:
opengl
2009-10-31
Vertex Buffer Objects - speed testing
For drawing 32,768 meshes of 12*16*2 triangles each (1 triangle strip):
OpenGL 2.1 hardware:
VA/IA: ~230ms
VBO: ~30ms
OpenGL 1.4 hardware:
VA/IA: ~230ms
VBO: ~240ms
The note is, although your card may say it supports the VBO extension, or support VBO as per the OpenGL 1.5 specs, it doesn't.
VBO's only work in 1.5 GL's or later, due to hardware restrictions.
Remember; If you worry about optimization, you'd better have timing tests to verify that it even matters. Saving about 10% or more is useful.
Also, small frame optimizations are useless; Anyone can do those, and they generally introduce unmaintainable hacks. Worry about your high level optimizations, like using "most common failed test first" and algorithmic and design changes to maximize your logical speed.
Anyways. Here's a buncha UV spheres, as mentioned (generated using xcore + mingl):

Currently working on the texture functions in mingl. Having to write compressors/decompressors for all the DXT formats. It'll be quite useful though.
Z out. Happy Halloween.
OpenGL 2.1 hardware:
VA/IA: ~230ms
VBO: ~30ms
OpenGL 1.4 hardware:
VA/IA: ~230ms
VBO: ~240ms
The note is, although your card may say it supports the VBO extension, or support VBO as per the OpenGL 1.5 specs, it doesn't.
VBO's only work in 1.5 GL's or later, due to hardware restrictions.
Remember; If you worry about optimization, you'd better have timing tests to verify that it even matters. Saving about 10% or more is useful.
Also, small frame optimizations are useless; Anyone can do those, and they generally introduce unmaintainable hacks. Worry about your high level optimizations, like using "most common failed test first" and algorithmic and design changes to maximize your logical speed.
Anyways. Here's a buncha UV spheres, as mentioned (generated using xcore + mingl):

Currently working on the texture functions in mingl. Having to write compressors/decompressors for all the DXT formats. It'll be quite useful though.
Z out. Happy Halloween.
Labels:
code,
opengl,
programming,
vertex array
2009-10-29
xcode, mingl, xgfx
Continuing my great adventure to construct the engine I need;
Yes Unity is now free. Who cares; What we need is a blender Synthesis program so I can use all my high def animations and levels.
xcore is moving along nicely, most data structure and memory alignment things work perfectly. Still some issues with float hacks.
mingl is quickly being put together, the abstraction of all mesh data into the VBO/IBO/VAO paradigm makes using OpenGL very very nice. In fact, learning a mingl type system is far easier than learning OpenGL fixed pipeline crap.
Vertex Buffer Objects:
They don't help unless you have OpenGL 1.5 or higher. Go figure.
And instancing doesn't really help unless you have a very specialized, small geometry item.
Here's 32,768 cubes:

If you stare too long, you begin to see a n-dimensional triangulation or worse, a shadow of a n-dimensional object.
I'll press on until I can have dancing lizard demo # 4. Or in this case, it might be a higher res female model.
Peace out.
-Z
Yes Unity is now free. Who cares; What we need is a blender Synthesis program so I can use all my high def animations and levels.
xcore is moving along nicely, most data structure and memory alignment things work perfectly. Still some issues with float hacks.
mingl is quickly being put together, the abstraction of all mesh data into the VBO/IBO/VAO paradigm makes using OpenGL very very nice. In fact, learning a mingl type system is far easier than learning OpenGL fixed pipeline crap.
Vertex Buffer Objects:
They don't help unless you have OpenGL 1.5 or higher. Go figure.
And instancing doesn't really help unless you have a very specialized, small geometry item.
Here's 32,768 cubes:

If you stare too long, you begin to see a n-dimensional triangulation or worse, a shadow of a n-dimensional object.
I'll press on until I can have dancing lizard demo # 4. Or in this case, it might be a higher res female model.
Peace out.
-Z
Labels:
code,
opengl,
programming
2009-10-25
xcore, mingl, xgfx
Not much to update today; Started some new projects.
In the spirit of the IGTL::Sys classes I made (mostly copy paste from them since they're so dang useful), I am building xcore, which is responsible for:
1. OS level byte types
2. exceptions and error reporting
3. CPU identification, SSE intrinsic math and special instructions
4. Memory manager
5. Specialized templated common file structures, like index_array, carray, index_deque, string_table
6. Directory I/O and file I/O
XCore is the minimal utility toolkit that drives all of my programming. On top of XCore is an important layer called GHOST, which was coded by the blender foundation and furthur extended by me for my own projects. GHOST is a cross platform windowing toolkit that accomplishes some of these things, but not all of them. I'm using it religiously since it avoids stupid SDL licensing issues, and has support for context sharing, multiple windows, and a better event system. The nice thing is, since I use blender anyways to make all of my media, it'll be a cinch to always mention i am using code from blender, thus keeping in line with their license for distribution.
mingl is a minimum wrapper on top of OpenGL that completly abstracts it, preventing me from making any non-suppported OpenGL calls. For example, it wraps all geometry data as a vbo/ibo/vao class (read up on OpenGL 3.0 if you don't know what these are) and internally can down-support any openGL version using this system. It cannot abstract shades really well, so it looks like it will require GL 2.0+ for any shaders to even work. I'm also not sure yet if I need to write my own shader coders so that the engine can generate shaders for vertex/fragment program aas well as GLSL; This seems a little difficult at the moment so I'll defer it.
xgfx is the graphics engine that performs culling, scene management, mesh updating, keyframing, armature animations, lighting, shadowing, and all the regular crap you expect to have in a game engine.
So, with this toolchain of xcore/ mingl/ xgfx /xoal/ xnet, it should abstract all the things I need for any game, just like I did back in late 2005. Except this time, it'll be my engine with no rules and no hangups or lies to slow me down. Of other importance, it's all using C++ as much as possible, so each component should be independent as much as possible.
Z out.
In the spirit of the IGTL::Sys classes I made (mostly copy paste from them since they're so dang useful), I am building xcore, which is responsible for:
1. OS level byte types
2. exceptions and error reporting
3. CPU identification, SSE intrinsic math and special instructions
4. Memory manager
5. Specialized templated common file structures, like index_array, carray, index_deque, string_table
6. Directory I/O and file I/O
XCore is the minimal utility toolkit that drives all of my programming. On top of XCore is an important layer called GHOST, which was coded by the blender foundation and furthur extended by me for my own projects. GHOST is a cross platform windowing toolkit that accomplishes some of these things, but not all of them. I'm using it religiously since it avoids stupid SDL licensing issues, and has support for context sharing, multiple windows, and a better event system. The nice thing is, since I use blender anyways to make all of my media, it'll be a cinch to always mention i am using code from blender, thus keeping in line with their license for distribution.
mingl is a minimum wrapper on top of OpenGL that completly abstracts it, preventing me from making any non-suppported OpenGL calls. For example, it wraps all geometry data as a vbo/ibo/vao class (read up on OpenGL 3.0 if you don't know what these are) and internally can down-support any openGL version using this system. It cannot abstract shades really well, so it looks like it will require GL 2.0+ for any shaders to even work. I'm also not sure yet if I need to write my own shader coders so that the engine can generate shaders for vertex/fragment program aas well as GLSL; This seems a little difficult at the moment so I'll defer it.
xgfx is the graphics engine that performs culling, scene management, mesh updating, keyframing, armature animations, lighting, shadowing, and all the regular crap you expect to have in a game engine.
So, with this toolchain of xcore/ mingl/ xgfx /xoal/ xnet, it should abstract all the things I need for any game, just like I did back in late 2005. Except this time, it'll be my engine with no rules and no hangups or lies to slow me down. Of other importance, it's all using C++ as much as possible, so each component should be independent as much as possible.
Z out.
Labels:
code,
opengl,
programming
2009-10-10
KDTrees and blender gui synthetics
Remember kids, if you use a synthetic oil, it's not a good idea to switch back to regular.

As far as I understand it, "KDTrees" are simply a data structure that says:
def kdtree:
def node:
x,y,w,h
split
low_node *
high_node *
parent *
direction
And, each node occupies a region of space defined by a x,y,w,h box (or x,y,z) and "splits" that box into TWO boxes, along only one of the axes (either x or y). This way, you can more efficiently partition static objects into a scene; this is like all BSP / octree scene management techniques; However, updating a KD tree is rather expensive, it really is good for storing static scenes though as it requires a far lesser node density and can expand into any other volume as needed.
So, they're used in blender's GUI; I'm getting my mockup GUI system to work slowly, and here are many panels defined by glViewports with text in them. The text system is nothing more than a badass texture font I used some free program to generate with 2 px padding and as a alpha only texture, so the memory required for those letters is quite minimal; although fonts are not conducive to mipmapping, so you must manually provide other LOD fonts for your program. Don't forget that always mipmapping is better for your hardware.

I'm also perfecting my cMesh class, which will provide a full next generation mesh including armature animation and animux system, basically equaling and exceeding the capabilities of all existing high definition games; And doing so in a manner consistent with next gen technology (VBO/Shader) while still retaining the ability to be processed via older cards, at great CPU expense.
It looks something like this:

The concept is present in all games I have hacked, and works like this:
A mesh consists of "tiles", which are separate VA/IA's that contain some amount of triangle strips/triangles/quadstrips with a consistent vertex format and ideally contiguous data. This means each tile can store different vertex parameters, the usual culprits are:
current vertex position (3)
next vertex position + weight (4) //For mesh keyframes only
texcoord 0 (2) //1st texture coordinate
texcoord 1 (2) //2nd texture coordinate (if you have seperate UV mappings, not efficient)
normal (3) //Required for any lighting
binormal (3) //can be shader generated, but space may need to exist in VA array)
matrix indicies (4) //Required to skin a mesh that has more than 1 matrix deforming it
matrix weights (4) //Required to skin a mesh properly
So, each tile can behave as a independent mesh. Above a tile is a tile state, which contains the RC (RenderCommand) array for actually issuing the stripping indicies and material changes and matrix palette updates for this mesh.
Above that is the TileTree, so you can swap/zsort/prioritize and use lod tiles as needed.
the concept of a tile is to load all mesh data into your graphic card, and then merely tell the card what to use to render via a few array binding commands. This is extremely efficient, as it supports mesh instancing to a large degree, and prevents transferring data to the card. The only drawback is you still have to transmit matrix updates to the card, but even a 270 bone character (like Valgirt) this is still far less information that a small VA.
So, once you have tiles setup, we have a generic bone/matrix animation system, with a matrix class (yes, I like quat's too, but matrices require less conversions in a game setting; these matricies can be changed to be only state driven mind you.).
The heart of this system is the base animation classes, which consist of "Keys" which are blocks of static data to interpolate between, "Channels" which are a list of keys and times, and "Animations" which combine channels together to form complete animations.
The Animux is a animation multiplexer, which combines any number of animations together, so that you can use multiple types of animations together, for instance "Run_legs" and "Shoot_Torso" like Quake, or "Face_Phoneme_ma" and "Run". This allows you to make characters that can walk, talk, and run + shoot at the same time, and even use IK calculations as you want.
I've probably done this thrice before, but THIS time, I've got it nailed, and have massive amounts of evidence and experience with the new GLSL to support this type of design. Hopefully, I can get AniStar up and running so I can actually have a program that can make animations for given characters.
Z out.

As far as I understand it, "KDTrees" are simply a data structure that says:
def kdtree:
def node:
x,y,w,h
split
low_node *
high_node *
parent *
direction
And, each node occupies a region of space defined by a x,y,w,h box (or x,y,z) and "splits" that box into TWO boxes, along only one of the axes (either x or y). This way, you can more efficiently partition static objects into a scene; this is like all BSP / octree scene management techniques; However, updating a KD tree is rather expensive, it really is good for storing static scenes though as it requires a far lesser node density and can expand into any other volume as needed.
So, they're used in blender's GUI; I'm getting my mockup GUI system to work slowly, and here are many panels defined by glViewports with text in them. The text system is nothing more than a badass texture font I used some free program to generate with 2 px padding and as a alpha only texture, so the memory required for those letters is quite minimal; although fonts are not conducive to mipmapping, so you must manually provide other LOD fonts for your program. Don't forget that always mipmapping is better for your hardware.

I'm also perfecting my cMesh class, which will provide a full next generation mesh including armature animation and animux system, basically equaling and exceeding the capabilities of all existing high definition games; And doing so in a manner consistent with next gen technology (VBO/Shader) while still retaining the ability to be processed via older cards, at great CPU expense.
It looks something like this:

The concept is present in all games I have hacked, and works like this:
A mesh consists of "tiles", which are separate VA/IA's that contain some amount of triangle strips/triangles/quadstrips with a consistent vertex format and ideally contiguous data. This means each tile can store different vertex parameters, the usual culprits are:
current vertex position (3)
next vertex position + weight (4) //For mesh keyframes only
texcoord 0 (2) //1st texture coordinate
texcoord 1 (2) //2nd texture coordinate (if you have seperate UV mappings, not efficient)
normal (3) //Required for any lighting
binormal (3) //can be shader generated, but space may need to exist in VA array)
matrix indicies (4) //Required to skin a mesh that has more than 1 matrix deforming it
matrix weights (4) //Required to skin a mesh properly
So, each tile can behave as a independent mesh. Above a tile is a tile state, which contains the RC (RenderCommand) array for actually issuing the stripping indicies and material changes and matrix palette updates for this mesh.
Above that is the TileTree, so you can swap/zsort/prioritize and use lod tiles as needed.
the concept of a tile is to load all mesh data into your graphic card, and then merely tell the card what to use to render via a few array binding commands. This is extremely efficient, as it supports mesh instancing to a large degree, and prevents transferring data to the card. The only drawback is you still have to transmit matrix updates to the card, but even a 270 bone character (like Valgirt) this is still far less information that a small VA.
So, once you have tiles setup, we have a generic bone/matrix animation system, with a matrix class (yes, I like quat's too, but matrices require less conversions in a game setting; these matricies can be changed to be only state driven mind you.).
The heart of this system is the base animation classes, which consist of "Keys" which are blocks of static data to interpolate between, "Channels" which are a list of keys and times, and "Animations" which combine channels together to form complete animations.
The Animux is a animation multiplexer, which combines any number of animations together, so that you can use multiple types of animations together, for instance "Run_legs" and "Shoot_Torso" like Quake, or "Face_Phoneme_ma" and "Run". This allows you to make characters that can walk, talk, and run + shoot at the same time, and even use IK calculations as you want.
I've probably done this thrice before, but THIS time, I've got it nailed, and have massive amounts of evidence and experience with the new GLSL to support this type of design. Hopefully, I can get AniStar up and running so I can actually have a program that can make animations for given characters.
Z out.
Labels:
blender,
code,
GLSL,
graphics,
model,
opengl,
programming,
shaders,
vbo,
vertex array
2009-10-01
Graphical 'Lag' Problem resolved
Here's the problem:
You code up a nice 3D game, and find that every time you call 'swapBuffers' your program is blocked from execution. You've tried threads, weird API's, and even low level OS hacking tricks; And nothing fixes it! Your game will still be forced to run at 60 FPS, no matter what, and every buffer swap lags your code at least 15 ms! Which is total burned CPU! And tons of dropped packets! And messages!
If you happen to have a graphics card, and specifically a NVidia one, here is the problem:
Go to start->Control Panel-> NVidia Control Panel(Display; Move to the display tab, advanced... Open the Nvidia Control Panel)
Make sure this is off:

What is happening, is it is making a crit section/thread safe block for buffer swaps, which if you write high performance games, this kills your testing phase since your game is force-lagged out.
This easily pushed my FPS and IFPS from 60 to well in the hundreds. In fact, in my GHOST test, I went from 15 RFms with 1 dropped frame to 10 RFms with 0 dropped frames. This translates to 0 dropped frames per second from 60 dropped frames per second.
I have fought this problem for a while; glad it wasn't my problem. The moral of the story? Sometimes you just have to step back and learn something new.
- Imaginary Z
You code up a nice 3D game, and find that every time you call 'swapBuffers' your program is blocked from execution. You've tried threads, weird API's, and even low level OS hacking tricks; And nothing fixes it! Your game will still be forced to run at 60 FPS, no matter what, and every buffer swap lags your code at least 15 ms! Which is total burned CPU! And tons of dropped packets! And messages!
If you happen to have a graphics card, and specifically a NVidia one, here is the problem:
Go to start->Control Panel-> NVidia Control Panel(Display; Move to the display tab, advanced... Open the Nvidia Control Panel)
Make sure this is off:

What is happening, is it is making a crit section/thread safe block for buffer swaps, which if you write high performance games, this kills your testing phase since your game is force-lagged out.
This easily pushed my FPS and IFPS from 60 to well in the hundreds. In fact, in my GHOST test, I went from 15 RFms with 1 dropped frame to 10 RFms with 0 dropped frames. This translates to 0 dropped frames per second from 60 dropped frames per second.
I have fought this problem for a while; glad it wasn't my problem. The moral of the story? Sometimes you just have to step back and learn something new.
- Imaginary Z
2009-07-04
Technically Competent Flash Game Engine
After playing with flash enough (Flash Professional 8)
I've reached a conclusion about how to build powerful, dynamic flash games.
I've worked with flash off and on for years, C/C++ and OpenGL are much cooler, but it has become difficult to manage my pipeline without additional tools that do not exist; So I am taking a break from that for a bit.
In order to properly make a flash game, you must first understand what a 'video game' is and how it works internally; They are full of interesting technical challenges as well as evil hacks; Because a game tends to be a simulator or emulation of some system, that means we'll never be able to truly make exactly what we want, either due to time or power constraints.
With that in mind, let's build up a 'megaman' example game.
We know from playing the megaman series on the NES that megaman is a little robot dude that can shoot other robots, some of which can move around and shoot back! And, if he enters a boss room, he can shoot a special enemy that can give him additional weapons!
Not much else too the game, really! Let's generalize it.
What kinds of things are there in the game?
-Sprites (2D Pictures)
-Sounds (Sound effects)
-Music (Longer strings of sounds! .nsf or some other mod format)
Well, that's kind of an aesthetic look. The actual game however, isn't quite as simple, as there are a variety of object types, like each type of enemy, each type of bullet, and so on.
When we look at a game from the programmers perspective, we can group all the things that work that same, and build a hierarchy:
Object
-Sprite
-Moving Object
--Bullet
--Controlled Moving Object
---Enemies
---Megaman
So, for each level down we go, we have to add more special code; There still is no magical way to code each type, that will ultimately have to be done. However, we can reduce the amount of work signifigantly by providing generic utilities for moving and updating those objects;
For example, we can have "MoveAsPlatformingCharacter" "MoveAsFlyingThing" "MoveAsBullet".
And, the ironic thing, is the game is still just moving pictures that can add and remove pictures and sometimes play sounds. There isn't anything more to it than that.
So, stepping back a bit, let's look at what flash can do for us:
-Automatic Heirarchy
-Display sprites, images, movies...
-AND can move, rotate and scale them!
-AND can colorize, shade, ect...
-AND can dynamically draw shapes!
-Automatic Sound playing
-Streaming music palying
-Input handling
So flash can do everything we need! But, flash is not assembly code, it is a SCRIPT LANGUAGE. That means that you cannot apply the same logic you use in C to flash; Script languages are not C, and C is not a script language and vice versa.
So in flash terms, we will have 1 movie clip called 'game' that has everything we need in it, as well as having ALL the functions we will use in it, so that you can do this:
game.moveObject( obj, 4, 0 ); //Move object obj right by 4 units
Inside of the game movie clip, we must have all the clips we want to duplicate in real time. Usually this is accomplised by:
game.dup_character;
game.dup_bullet;
ect...
Where, inside each of those dup_character, you have a lot of named frames for that specific character type, like "Heatman", "Iceman", "Megaman", and in each of those frames, you put down the instance of the clip you want to animate; you do not do the animations in the duplicate clip, you make a seperate layer;
This way, you can name each clip inside of the duplicate clip the SAME THING, ergo: "mc", so that the game can reference the mc identically for each instance, AND separate scaling and other properties from it.
[MovieClip: dup_robot]
[FrameName : "Megaman"]
mc [Instance of "Megaman" movie clip, which has all his named animations, like "run", "jump", ect...]
[FrameName : "Heatman"]
mc [Instance of "Heatman" movie clip, which has all HIS animations ]
so your 'game' clip now has this:
[game : Game clip]
dup_robot [Instance of "dup_robot" movie clip, which has all the possible robot types each in a specially named frame]
dup_bullet [Instance of "dup_bullet" movie clip, which has all possible bullet types each in a named frame]
ect...
Using this method, you can simply duplicate a dup_clip, then set it's frame, then once you do that, you can set the mc inside of it's frame, thus instantly allowing your game to be very flexible to add extra things later!
So this is all fine and dandy' Now in flash you can duplicate any clip that graphically represents what your game is, but, what about the actual game?
Here's where it get's difficult; If you trust flash's 1 collision function (hitTest) then you might know that it DOES NOT WORK on and point test that is NOT on the stage (any non-rendered pixel CANNOT be hit-tested against. SO DONT USE IT!)
That means yes, you have to make up your own collision scheme, and make up your own collision math, and your own physics system for motion.
Basically, that means that every object should have a .x, .y, .vx, .vy in it, so you can perform basic rectilinear motion. As for updating your objects, so long as you make a working rectilinear motion function, you can add any complex types of motion you want later.
This will be covered later, but the easiest solution is to add another dup_clip that creates boxes and ramps, which are very basic and mathematically simple collision primitives that you CAN make a game out of quickly.
But all this high level talk isn't much use; Because when you get started, you'll find you need a couple of basic tools:
Something to store this data,
A Map (dict for those python kidz)
A SpaceHashing/Broadphase test
Map is actually simple in flash,
var mymap = new Object();
mymap[ "any key as a string" ] = data;
So you can abuse flash's quick Log2(n) internal string search for object properties as a map. It's as fast as it get's folks.
A Spacehash is up to you, I prefer using a single axis sort and doing a map/array of bins, which have maps of catergories, each which stores an object UID
Yes, every object you make should have a non-repeating Unique ID. Don;t rely on the movieclip as one, you never know when depth levels can change or clips for that matter. Use a Number and just increment it, or make a map and reuse unused keys.
Blargh; What a mess. Too much information to disgorge for ya'll.
I'll post the flash engine later. Then you can just %#@*(& use it!
Happy fourth!
-Z
I've reached a conclusion about how to build powerful, dynamic flash games.
I've worked with flash off and on for years, C/C++ and OpenGL are much cooler, but it has become difficult to manage my pipeline without additional tools that do not exist; So I am taking a break from that for a bit.
In order to properly make a flash game, you must first understand what a 'video game' is and how it works internally; They are full of interesting technical challenges as well as evil hacks; Because a game tends to be a simulator or emulation of some system, that means we'll never be able to truly make exactly what we want, either due to time or power constraints.
With that in mind, let's build up a 'megaman' example game.
We know from playing the megaman series on the NES that megaman is a little robot dude that can shoot other robots, some of which can move around and shoot back! And, if he enters a boss room, he can shoot a special enemy that can give him additional weapons!
Not much else too the game, really! Let's generalize it.
What kinds of things are there in the game?
-Sprites (2D Pictures)
-Sounds (Sound effects)
-Music (Longer strings of sounds! .nsf or some other mod format)
Well, that's kind of an aesthetic look. The actual game however, isn't quite as simple, as there are a variety of object types, like each type of enemy, each type of bullet, and so on.
When we look at a game from the programmers perspective, we can group all the things that work that same, and build a hierarchy:
Object
-Sprite
-Moving Object
--Bullet
--Controlled Moving Object
---Enemies
---Megaman
So, for each level down we go, we have to add more special code; There still is no magical way to code each type, that will ultimately have to be done. However, we can reduce the amount of work signifigantly by providing generic utilities for moving and updating those objects;
For example, we can have "MoveAsPlatformingCharacter" "MoveAsFlyingThing" "MoveAsBullet".
And, the ironic thing, is the game is still just moving pictures that can add and remove pictures and sometimes play sounds. There isn't anything more to it than that.
So, stepping back a bit, let's look at what flash can do for us:
-Automatic Heirarchy
-Display sprites, images, movies...
-AND can move, rotate and scale them!
-AND can colorize, shade, ect...
-AND can dynamically draw shapes!
-Automatic Sound playing
-Streaming music palying
-Input handling
So flash can do everything we need! But, flash is not assembly code, it is a SCRIPT LANGUAGE. That means that you cannot apply the same logic you use in C to flash; Script languages are not C, and C is not a script language and vice versa.
So in flash terms, we will have 1 movie clip called 'game' that has everything we need in it, as well as having ALL the functions we will use in it, so that you can do this:
game.moveObject( obj, 4, 0 ); //Move object obj right by 4 units
Inside of the game movie clip, we must have all the clips we want to duplicate in real time. Usually this is accomplised by:
game.dup_character;
game.dup_bullet;
ect...
Where, inside each of those dup_character, you have a lot of named frames for that specific character type, like "Heatman", "Iceman", "Megaman", and in each of those frames, you put down the instance of the clip you want to animate; you do not do the animations in the duplicate clip, you make a seperate layer;
This way, you can name each clip inside of the duplicate clip the SAME THING, ergo: "mc", so that the game can reference the mc identically for each instance, AND separate scaling and other properties from it.
[MovieClip: dup_robot]
[FrameName : "Megaman"]
mc [Instance of "Megaman" movie clip, which has all his named animations, like "run", "jump", ect...]
[FrameName : "Heatman"]
mc [Instance of "Heatman" movie clip, which has all HIS animations ]
so your 'game' clip now has this:
[game : Game clip]
dup_robot [Instance of "dup_robot" movie clip, which has all the possible robot types each in a specially named frame]
dup_bullet [Instance of "dup_bullet" movie clip, which has all possible bullet types each in a named frame]
ect...
Using this method, you can simply duplicate a dup_clip, then set it's frame, then once you do that, you can set the mc inside of it's frame, thus instantly allowing your game to be very flexible to add extra things later!
So this is all fine and dandy' Now in flash you can duplicate any clip that graphically represents what your game is, but, what about the actual game?
Here's where it get's difficult; If you trust flash's 1 collision function (hitTest) then you might know that it DOES NOT WORK on and point test that is NOT on the stage (any non-rendered pixel CANNOT be hit-tested against. SO DONT USE IT!)
That means yes, you have to make up your own collision scheme, and make up your own collision math, and your own physics system for motion.
Basically, that means that every object should have a .x, .y, .vx, .vy in it, so you can perform basic rectilinear motion. As for updating your objects, so long as you make a working rectilinear motion function, you can add any complex types of motion you want later.
This will be covered later, but the easiest solution is to add another dup_clip that creates boxes and ramps, which are very basic and mathematically simple collision primitives that you CAN make a game out of quickly.
But all this high level talk isn't much use; Because when you get started, you'll find you need a couple of basic tools:
Something to store this data,
A Map (dict for those python kidz)
A SpaceHashing/Broadphase test
Map is actually simple in flash,
var mymap = new Object();
mymap[ "any key as a string" ] = data;
So you can abuse flash's quick Log2(n) internal string search for object properties as a map. It's as fast as it get's folks.
A Spacehash is up to you, I prefer using a single axis sort and doing a map/array of bins, which have maps of catergories, each which stores an object UID
Yes, every object you make should have a non-repeating Unique ID. Don;t rely on the movieclip as one, you never know when depth levels can change or clips for that matter. Use a Number and just increment it, or make a map and reuse unused keys.
Blargh; What a mess. Too much information to disgorge for ya'll.
I'll post the flash engine later. Then you can just %#@*(& use it!
Happy fourth!
-Z
2009-04-22
Brawl models and dream
Man, I burned myself out yesterday trying to figure out textures.
As a result, I haven't slept well since I started this, I keep having crazy dreams, and I was able to remember most of this one:
Dream was odd.
I remember going through a 1st/3rd person shooter where there were unusual zombies, not like normal zombies but something more similar to crazy possessed demon people. I remember one room I got too where I kept getting killed, it was a large room, with a small cubby on one side of it and had a stairway at the back, but to the side of that stairway was a small windowed room with metal walls, and a sealed metal door where the special weapon I was supposed to get was. The entire look ot the scene was dark and grimy, like RE5, but better looking. The lighting was sometimes dynamic, but the walls dripped with rust and grime, as if there had been blood but it dried. The smell was bad too, though I think was was psychologically imposed via my imagination. So I ran pas this guy in a plaid shirt with a large broken pipe, who was some crazy lumberjack like dude, and past this other kid with the typical NY punk ass look who had a knife, got into the room, grabbed this special weapon, but when I did, those two turned into these much larger bug mutant monsters, walking with reversed legs from their back and having 4 spindly ones in front with gnashing teeth and large red eyes. Not particularly scary or anything, but they were really fast and had a sort of mantis mentality, if they got close to you, their legs snapped out and yanked you into their jaws for a kill bite. Not much you could do there, but this special weapon was a wired plasma arc discharger, think of it like a gun that can shoot chainsaws. It was very effective, but you had only milliseconds to get off two EXACT shots to kill these bugs before you had to exactly run upstairs and barricade the door, which saved, then you turned around and blasted more human zombies and some ceiling bugs.
Of course, sinec it took me enough tries to get past that room (There were lots more before it, somewhat like a Super Half-life or something) the dream took a different turn, and I noticed I was in a restaurant. I ran through hit the first time though, noticing that there were odd pictures on the walls, but after I had ran through it, I found a pool of survivors, who, weirdly enough, were all the buddies I knew from Eka's, even some of them I had never met in real life. That stuck me as odd, and apparently there was some sort of crazy furry convention or something going on and they just happened to congregate there. I talked to them for a moment or two, being slightly blood splattered and worn from intense combat. Two of the wanted to help, but they had no weapons, so I had them go get some while the safe room music queued. I went back to the restaurant and it clicked; Apparently, the wall pictures were of a toon-Kami, which immediately raised my mental threat level to max, at least until I saw Ted sitting at a table with two other people I knew. I went over and sat down, and we had some sort of funny conversation about the restaurant, it kinda looked like a Captain D's which was equally ironic. The information I gathered there wasn't too useful, but it was greatly entertaining.
After a few drinks, I went back to the convention, and it was, of course, empty, they didn't make it. There were much stronger bug monsters, some that could fly, and I said 'aw fuck it' and saved the game and went back to the restaurant to get some food. Needless to say, in that particular establishment that's not exactly how it works, but goddamnit I tried.
I can't seem to remember too much of it, I've had long strings of dreams lately that involve me missing my good friends a lot, mostly goathouse members and lots and lots of drinking involved. I conclude that I must be severely depressed, and I can't blame me for that.
I guess you can't really be friends until you've seen the fires of hell as a team, eh?
Update on the format converter; Still trying to sort out textures, but guess what? Blender doesn't like the 394 material MetalGearRex model because it can only handle 16! So f***.
Here's a stupid screenshot with MetaRidely, King K. Rool, Mario, Luigi, Peach, and Link.
Sortof.

For those of you that care, I'm still getting the hang of the transforms down; They don't seem as bad as figuring out how to find which textures and which blending modes to use. Obviously it's a snap to manually assign textures, but this should do most of the job for us, right? I do seem to have the polygon data down perfectly, I am not trying to get any particular model, just reverse engineering their format so I can improve my own. It's bizzare, there is no good reason I can think of why this file needs to be this complex. You can do the same thing or better with a GRF/BRF setup, or hell, any other normal linear file. Honestly the only complex thing WOULD be the materials, and that's what I'm having trouble with...
Also as a side note, blender's bone system is SHIT, because you cannot have zero length bones or infinite length bones. Come to think of it, hardware only uses matrices, so what the hell DOES a bone have length for?!?! This is very very stupid, as the convention makes no sense for any real application. Obviously you can display bones as octohedrons in reverse child->parent mode. This is trivial to do and would eliminate this horrid 'length' idea. Also, why the fuck is bone space so bizzare? What ever happened to consistent in +X forward, +Y left, +Z up? I really miss that idea, since it's correct for the hardware and avoids any confusion if it's all the same.
I don't think I'll ever stop being amazed that the more you know about something, the more flaws you can find.
! Oh shit, an icecream truck! GTG save it!
As a result, I haven't slept well since I started this, I keep having crazy dreams, and I was able to remember most of this one:
Dream was odd.
I remember going through a 1st/3rd person shooter where there were unusual zombies, not like normal zombies but something more similar to crazy possessed demon people. I remember one room I got too where I kept getting killed, it was a large room, with a small cubby on one side of it and had a stairway at the back, but to the side of that stairway was a small windowed room with metal walls, and a sealed metal door where the special weapon I was supposed to get was. The entire look ot the scene was dark and grimy, like RE5, but better looking. The lighting was sometimes dynamic, but the walls dripped with rust and grime, as if there had been blood but it dried. The smell was bad too, though I think was was psychologically imposed via my imagination. So I ran pas this guy in a plaid shirt with a large broken pipe, who was some crazy lumberjack like dude, and past this other kid with the typical NY punk ass look who had a knife, got into the room, grabbed this special weapon, but when I did, those two turned into these much larger bug mutant monsters, walking with reversed legs from their back and having 4 spindly ones in front with gnashing teeth and large red eyes. Not particularly scary or anything, but they were really fast and had a sort of mantis mentality, if they got close to you, their legs snapped out and yanked you into their jaws for a kill bite. Not much you could do there, but this special weapon was a wired plasma arc discharger, think of it like a gun that can shoot chainsaws. It was very effective, but you had only milliseconds to get off two EXACT shots to kill these bugs before you had to exactly run upstairs and barricade the door, which saved, then you turned around and blasted more human zombies and some ceiling bugs.
Of course, sinec it took me enough tries to get past that room (There were lots more before it, somewhat like a Super Half-life or something) the dream took a different turn, and I noticed I was in a restaurant. I ran through hit the first time though, noticing that there were odd pictures on the walls, but after I had ran through it, I found a pool of survivors, who, weirdly enough, were all the buddies I knew from Eka's, even some of them I had never met in real life. That stuck me as odd, and apparently there was some sort of crazy furry convention or something going on and they just happened to congregate there. I talked to them for a moment or two, being slightly blood splattered and worn from intense combat. Two of the wanted to help, but they had no weapons, so I had them go get some while the safe room music queued. I went back to the restaurant and it clicked; Apparently, the wall pictures were of a toon-Kami, which immediately raised my mental threat level to max, at least until I saw Ted sitting at a table with two other people I knew. I went over and sat down, and we had some sort of funny conversation about the restaurant, it kinda looked like a Captain D's which was equally ironic. The information I gathered there wasn't too useful, but it was greatly entertaining.
After a few drinks, I went back to the convention, and it was, of course, empty, they didn't make it. There were much stronger bug monsters, some that could fly, and I said 'aw fuck it' and saved the game and went back to the restaurant to get some food. Needless to say, in that particular establishment that's not exactly how it works, but goddamnit I tried.
I can't seem to remember too much of it, I've had long strings of dreams lately that involve me missing my good friends a lot, mostly goathouse members and lots and lots of drinking involved. I conclude that I must be severely depressed, and I can't blame me for that.
I guess you can't really be friends until you've seen the fires of hell as a team, eh?
Update on the format converter; Still trying to sort out textures, but guess what? Blender doesn't like the 394 material MetalGearRex model because it can only handle 16! So f***.
Here's a stupid screenshot with MetaRidely, King K. Rool, Mario, Luigi, Peach, and Link.
Sortof.

For those of you that care, I'm still getting the hang of the transforms down; They don't seem as bad as figuring out how to find which textures and which blending modes to use. Obviously it's a snap to manually assign textures, but this should do most of the job for us, right? I do seem to have the polygon data down perfectly, I am not trying to get any particular model, just reverse engineering their format so I can improve my own. It's bizzare, there is no good reason I can think of why this file needs to be this complex. You can do the same thing or better with a GRF/BRF setup, or hell, any other normal linear file. Honestly the only complex thing WOULD be the materials, and that's what I'm having trouble with...
Also as a side note, blender's bone system is SHIT, because you cannot have zero length bones or infinite length bones. Come to think of it, hardware only uses matrices, so what the hell DOES a bone have length for?!?! This is very very stupid, as the convention makes no sense for any real application. Obviously you can display bones as octohedrons in reverse child->parent mode. This is trivial to do and would eliminate this horrid 'length' idea. Also, why the fuck is bone space so bizzare? What ever happened to consistent in +X forward, +Y left, +Z up? I really miss that idea, since it's correct for the hardware and avoids any confusion if it's all the same.
I don't think I'll ever stop being amazed that the more you know about something, the more flaws you can find.
! Oh shit, an icecream truck! GTG save it!
2009-04-19
Super Smash Bros Brawl model format
So I have been exploring Brawl.
I've learned a little more about constructing armatured models, this is primarily useful for my art team in assisting their understanding of how professional projects handle their game media. Using references is extremely informative when you create your own models, as you get to learn from others mistakes more quickly, and see new ways to make special joints and features.
I'm doing this out of pure academic interest, as I found out there is not much difference between this and the melee formats. I hacked both, but brawl models in general look better.
So here's the Ridley Trophy in Blender, definitely not something desirable to wake up to:

And yeah, I still have that awesome little plastic Ridley figurine that Kelly let me have. He's quite happy guarding my desk!
Peace!
-Z
I've learned a little more about constructing armatured models, this is primarily useful for my art team in assisting their understanding of how professional projects handle their game media. Using references is extremely informative when you create your own models, as you get to learn from others mistakes more quickly, and see new ways to make special joints and features.
I'm doing this out of pure academic interest, as I found out there is not much difference between this and the melee formats. I hacked both, but brawl models in general look better.
So here's the Ridley Trophy in Blender, definitely not something desirable to wake up to:

And yeah, I still have that awesome little plastic Ridley figurine that Kelly let me have. He's quite happy guarding my desk!
Peace!
-Z
2009-03-24
More nonsense
So, working on more things, lots of things. 'Sys' is the new IGTL system namespace, which provides all the utilities that you could need for memory, data structures, file/directory IO, mathematics, 3D mathematics, algorithms, and all the basic stuf every system should have. Basically, it's a new version of cstdlib, that uses C++ stuff (like STL, but not junky) for some systems. Specially, it has a lot of very common math and algorithms in a very clean and not junky C-style system, so you don't have to freak out over overhead.
It's coming along awesome, and I love it. It makes so much more sense now, getting the base code out of the way. Although, it does prove that the C++ crap is near useless, which by extenstion makes most all languages that are not python a$$. And all other languages are useless for realtime stuff.
So, I also learned how to do 'Hemispherical Lighting', which is a simple little trick in your good ole shader math:
float dp = light_vector dot normal ;
float schemi = hemi_scale * pow( hemi_power, 0.5 * dp + 0.5 ); //Light factor to use
And, again in GL_fragment_shader_arb lingo,
DP3 temp2.x, nNorm, -mvp[2]; #Dot view normal (curr view) with vertex normal to get generic light intensity
#---Hemispherical lighting--- Req: K.y = 0.5, LK.z = light_pow, LK.w = light_scale
MAD temp2.y, temp2.x, LP.x, LP.y; #t = t*0.5 + 0.5 (hemispherical lighting = cool)
#---Scale the light to be the hemisphere
POW temp2.y, LP.z, temp2.y; #t = pow(t, hard), flip this to halo (A^B)
MUL temp2.y, temp2.y, LP.w; #t *= spec
#---Calculate final hemi diffuse color
MUL temp1, temp2.y, fragment.color; #Interpolate color to black (mult op)
And, some examples, but I don;t have comparison shots because Blender uses hemi lights, you can easily see the difference.
Hey, it's delgadosaur again, and it looks less plastic, more daylight plastic.
And a new member of the crew, this purple-dragon thing that's more friendly and low poly. But that's what textures and sub-surface models are for, right?
Anyways. Peace out.
-Z
It's coming along awesome, and I love it. It makes so much more sense now, getting the base code out of the way. Although, it does prove that the C++ crap is near useless, which by extenstion makes most all languages that are not python a$$. And all other languages are useless for realtime stuff.
So, I also learned how to do 'Hemispherical Lighting', which is a simple little trick in your good ole shader math:
float dp = light_vector dot normal ;
float schemi = hemi_scale * pow( hemi_power, 0.5 * dp + 0.5 ); //Light factor to use
And, again in GL_fragment_shader_arb lingo,
DP3 temp2.x, nNorm, -mvp[2]; #Dot view normal (curr view) with vertex normal to get generic light intensity
#---Hemispherical lighting--- Req: K.y = 0.5, LK.z = light_pow, LK.w = light_scale
MAD temp2.y, temp2.x, LP.x, LP.y; #t = t*0.5 + 0.5 (hemispherical lighting = cool)
#---Scale the light to be the hemisphere
POW temp2.y, LP.z, temp2.y; #t = pow(t, hard), flip this to halo (A^B)
MUL temp2.y, temp2.y, LP.w; #t *= spec
#---Calculate final hemi diffuse color
MUL temp1, temp2.y, fragment.color; #Interpolate color to black (mult op)
And, some examples, but I don;t have comparison shots because Blender uses hemi lights, you can easily see the difference.
Hey, it's delgadosaur again, and it looks less plastic, more daylight plastic.
And a new member of the crew, this purple-dragon thing that's more friendly and low poly. But that's what textures and sub-surface models are for, right?Anyways. Peace out.
-Z
Labels:
dragon,
fragment program,
GLSL,
lizard,
opengl,
SDL,
vertex program
2009-02-20
Hey look, a quadtree

So what's so special? This is a common data structure that everyone one of you should be able to do from memory. It's extremely simple, and uses recursion. Simply make a tree with each node linking to 4 child nodes that evenly divide space, and let each node store a list of pointers or the data itself.
The special part, is this is a generic quadtree, so, instead of 'storing' objects, it stores XData::Quadtree::Proxy object POINTERS to a XData::List, which means that Proxy lifecycle is left to the user (working on making it pointeriffic and more auto-delete) but that also means that every node stores a list of those proxy pointers, so that your game object:
class MyGameObject : public Game::BaseObject {
private:
XData::Quadtree::Proxy m_proxy;
}
Can simply access the quadtree as such:
qtree.insert( obj.m_proxy );
qtree.remove( obj.m_proxy );
m_proxy.IsValid();
qtree.get( XData::Array &, fptr_to_Collision_Function, collision_function_data );
So what this means, is in the above picture you can draw arbitrary edges for a odin-sphere style level, which get their proxies put into the quadtree. This is dangerous only if you forget to remove the proxy before deleting the object. But it means that you can query arbitrary shapes against the quadtree and get a quick enough broadphase test for intersection. Insertion is always better than O(log(n)), deletion/update is best case O(1), worst case O(log(n) + 1). Access is linked list, so fast iteration is possible.
Quadtree's are good for dynamic data, that is if everything is changing quickly. There are other methods for static data that are far superior, like KDTrees or Spaceblocks or even AxisSweeps, but quadtrees are a general good purpose solution that's still good in performance to be viable for many applications. In fact, you probably won't need much more than this, unless you have severe restrictions that force you to use sorted space blocks.
If you are making a 2D game, please do not use tiles. I will hate you, and you should be competent enough to make a quadtree (think Game Maker) that can handle arbitrary shapes and so forth.
Go look at this game to see one of these methods in action
-Z
Labels:
code,
collisions,
opengl,
screenshots,
SDL,
space
2009-02-10
Thumbs Up!
Okay, I got it. Matrix Palette exporter works fine now.

Next up is adding in textures in MIF/QIF format (already done, copy paste job), and then deciding the structure for spread-optimized armature/matrix palette, and then keyframes using vertex duplicate's.
Of course, now that THIS works, it'll be time to shove it onto the iPhone. Imagine that, "Monster Game" for the iPhone! Course it'll be stripped down, but hey, sounds fun.
Peace ya'll!
-Z
Next up is adding in textures in MIF/QIF format (already done, copy paste job), and then deciding the structure for spread-optimized armature/matrix palette, and then keyframes using vertex duplicate's.
Of course, now that THIS works, it'll be time to shove it onto the iPhone. Imagine that, "Monster Game" for the iPhone! Course it'll be stripped down, but hey, sounds fun.
Peace ya'll!
-Z
Labels:
ARF,
BRF,
fragment program,
lizard,
opengl,
SDL,
shaders,
vertex program
Subscribe to:
Posts (Atom)






