ENIGMA Development Environment
Website is in read-only mode due to a recent attack.

Show Posts

This section allows you to view all posts made by this member. Note that you can only see posts made in areas you currently have access to.

Messages - Josh @ Dreamland

Proposals / Re: GL3 changes from immediate to retained mode
« on: July 31, 2013, 06:15:19 PM »
Well your example ordered 7 batches and if they are rendered in that order, then the output will differ. And if you draw a hud then that can be a difference between having text on the background or the background on the text (or even a player on the text).
The output will only differ if individual objects overlap. The correct draw order for everything drawn inside each object's draw event is preserved. So if you draw a square sprite, then a circle sprite over it, the corner of the square sprite for one object will not be able to overlap the circle sprite of another object, because all square sprites are drawn at the same time, and all circle sprites are drawn after.

This problem in fact manifests anywhere multiple sprite draws are used to create one sprite, such as for attaching a hat, or armor, or other equipables to a character sprite. In this case, other objects on that depth which are drawn in the same way would not overlap correctly. Consider two characters with these equipables standing such that they overlap each other. This would cause one character to appear to have all equipables drawn on him, while the body of the other character remains behind him. This is an unfortunate,  but rare, side effect of the conversion. Proper texture atlasing would fix that.

In your example above, Harri, the bombs would all be drawn under the nuclear signs. Assuming spr_0 is the bomb. The disaster case for my algorithm is doing all that drawing in a single loop instead of at one depth.

I don't see how that would change much. The slowdown now happens only when switching textures.
This is exactly what my method avoids, Harri. It does this by batching sprites of the same texture together under strict conditions. How are you not noticing a difference between those two codes? I think you missed the point of what I was saying. The bottom code demonstrates the original, un-batched behavior, when ENIGMA asks each object to perform its draw event. It requires 3n texture binds, where n is the number of instances. The top code shows how the batching algorithm refactors the code to look; it requires only three texture binds, regardless of how many instances there are. All sprites with spr_1's texture are drawn in batch. Then all sprites for spr_2, then all sprites for spr_3. The order is determined from the order they are drawn in the code, so it will look identical to the original except in cases of one-sprite overlap (described above).

As for texture aliasing, I cannot think of an efficient way to do this at run time. I think our best option is to allow the user to specify groups of sprites for texture atlases, then atlas those atlases together according to profiler data from a special compilation mode.

Again in your example, method (3) from my post would return the tuples (spr_0, spr_1) with 25,000 hits, and (spr_1, spr_0) with 24,999 hits. The result would be that the profiler would strongly recommend (to the IDE/Compiler) placing spr_0 and spr_1 on the same atlas. The user could also manually fix the glitch in appearance from my method (2) by atlasing them together manually in the interface.

That's a legitimate concern. Unfortunately, the option is to either stash matrix data in the bash operation, or treat transform calls as another barrier, which can be devastating for the performance of that batch algorithm.

One extra consideration:
Perhaps it would be a good idea to allow placing sprites in multiple texture atlases, and making it simple to check if the current atlas contains a sprite. This would further improve batching.

General ENIGMA / Re: Scalar Types
« on: July 31, 2013, 06:06:07 PM »
I'm not sure what to do with alpha, Harri. It's not a typical metric... Angles are also a special exception, as they're passed to trigonometry. Alpha only exists as a float long enough to cast to a byte for glColor4c. However, it might be wise to do the casting the other way, depending on where the float conversion is done. I'm not familiar with that part of the pipeline. The question is whether it's better on overall performance to do three float divs on the CPU, or one float mul on the CPU and four float divs on the GPU. Assuming that's what's happening.

Proposals / Re: GL3 changes from immediate to retained mode
« on: July 31, 2013, 12:39:54 PM »
I don't think taking away drawing order management other than depth is such a good thing.
The proposal I gave above in (2) doesn't do that. It emulates it perfectly, with speedup in your "worst case" comparable to speedup in the best case. The only thing it takes away is instance ID behaving as a secondary depth. The order of those drawings is deterministic, but different, and should not differ in any meaningful way.

In my method, an object that draws spr1, then spr2, then spr3 will behave like this:

Code: (EDL) [Select]
with (obj_0)
with (obj_0)
with (obj_0)

Instead of like this:
Code: (EDL) [Select]
with (obj_0)
And dynamically changing to that behavior is basically trivial.

That said, go ahead and commit what you have for now, as improvement is improvement, and your solution is much less involved than mine.

Proposals / Re: GL3 changes from immediate to retained mode
« on: July 31, 2013, 10:08:22 AM »
That's why I added that "if possible" clause to batching. It's hard to do batching when people layer sprites at the current depth, and intermix texture calls with untextured calls.

Fortunately, we can do some hackery in the compiler to help with that. We have a few options, which I propose we support as options in full:
  • Undefine the behavior of intermixed calls. We can add an option to treat depths as the only logical barrier for batching. This means that if you draw, as I mentioned in Robert's announcement earlier, an arm, a torso, then another arm, you might end up with both arms being in front of or behind the torso instead of sandwiched. For some games, this behavior is unacceptable—for others, this isn't an issue at all. Giving the option of drawing sprites immediately or batching them is a relatively simple operation which will have little impact on code size.
  • Place batching barriers in parallel. The compiler can register with the built-in sprite batching class that a draw event has started, and that a draw event has completed. This information can be used by the batch as a heuristic for what order to bind textures in. Barriers will be created not for each object, but instead for each time the user implicitly switches modes or textures. Examples below.
  • Do code profiling in a special mode. If ENIGMA has a Profile mode down the road, the sprite batch unit can denote, as a map of pairs, the texture IDs most commonly switched between. These pair counts can be used in generating texture atlases to avoid rebinding altogether, even when drawing sprites intermittently.

None of these options, alone, will solve the problem, but you can imagine that together these are extremely powerful options. Let me elaborate on points (2) and (3).

2. Parallel batch barriers
Say we have three events which are run during the game.
Code: (EDL) [Select]
draw_sprite(spr_wing_bottom, 0, x, y);
draw_sprite(spr_bird, 0, x, y);
draw_sprite(spr_wing_top, 0, x, y);
Code: (EDL) [Select]
draw_sprite(spr_fire, -1, x, y);
draw_sprite(spr_wing_bottom, 0, x, y);
draw_sprite(spr_firebird, 0, x, y);
draw_sprite(spr_wing_top, 0, x, y);
Code: (EDL) [Select]
draw_circle_color(x, y, 64, c_white, c_red, false);
draw_sprite(spr_wing_bottom, 0, x, y);
draw_rectangle_color(x-16, y-16, x+16, y+16, c1, c2, c3, c4);
draw_sprite(spr_wing_top, 0, x, y);

Our batch mechanism would work by keeping a list, in order, of each type of sprite, line, ...whatever needs drawn. At the beginning of each draw event would be batch_chunk_start(), at the end would be batch_chunk_end().

0. A list of batch jobs is created, and is initially empty.
1. The batch_chunk_start() method moves the head position to the beginning of the list.
2. Each time the user tries to draw something, the head advances until a batch job of that type is encountered.
3. If no batch job of that type is encountered, the head is moved back where it was, and a new batch job is inserted there.
4. The batch_chunk_end() method doesn't do anything except maybe a check in debug mode.

By the above process, the batch jobs generated for the above codes, in order, will be as follows (assuming the codes are first encountered in the order given above and then in any sequence for repetition):
  • Draw all circle_color.
  • Draw all spr_fire.
  • Draw all spr_wing_bottom.
  • Draw all rectangle_color.
  • Draw all spr_firebird.
  • Draw all spr_bird.
  • Draw all spr_wing_top

The worst case for this batch algorithm is when every object draws everything uniquely or in reverse order of another object which already drew it. The issue is that in this system, everything must be batchable, or have a batch node. Every. Single. Draw. Function.

3. Profiling
To improve further on the above, code profiling can be done by creating texture pairs as described. With our batch class in place, the pairs generated will be (spr_fire, spr_wing_bottom), (spr_wing_bottom, spr_firebird), (spr_firebird, spr_bird), (spr_bird, spr_wing_top). A very complicated (relatively speaking—I mean in terms of runtime complexity rather than in difficulty) algorithm would then decide the best arrangement for these sprites. An obvious answer (aside from put them all on the same sheet) is to arrange them so that spr_fire and spr_wing_bottom are on one atlas, and spr_firebird, spr_bird, and spr_wing_top are on another. The point is to minimize the number of texture switches in a batched or unbatched environment; for more complicated games, where these transitions will not be made 1:1 by the batch tool, the profiling will come in handy to a much higher degree.

Proposals / Re: GL3 changes from immediate to retained mode
« on: July 31, 2013, 07:25:33 AM »
The point of the GL3 graphics system is to assume that the hardware supports VBOs and shaders, as opposed to call lists and matrices.

This has been planned for a loooong time, but has only recently begun being implemented.

Purging immediate mode from GL3 is certainly a goal. Texture batching is also an interest, if possible.

If you're getting 50,000 sprite draws at 30 fps, my guess is that you have the batching on at full power. What I mean is, try drawing an arm sprite, then drawing a torso sprite over that, then drawing another arm sprite over that. You'll probably be disappointed.

Proposals / Re: Vertex color
« on: July 30, 2013, 02:50:28 PM »
Erm. I was speaking on the pretense that this was for the newer systems with shaders.

I was also working with the pretense that this was to emulate GM's exact behavior when intermixing calls with and without _color. Even with GL lists, if you draw one red vertex, one colorless vertex, one green vertex, and then another colorless vertex, the two colorless vertices will receive, respectively, red and green. Just how the pipeline works. GM's behavior could be simulated by pushing and popping the color in the list where needed. The boolean wouldn't really be required otherwise, as not specifying a color just means not changing the current color.

Now, with shaders, the boolean would need added to the vertex format to simulate GM's behavior. The boolean in RAM could be useful for determining the required vertex format and possibly shader—I actually really like that idea.

Proposals / Re: Vertex color
« on: July 30, 2013, 10:30:27 AM »
The space wasting is only done until d3d_model_primitive_end() as then all the vectors are destroyed. And I don't know how specifying vertex formats will help here.
"Destroyed" and "moved to the GPU" are two very different concepts. They exist *somewhere*.

I'm not sure what to make of that behavior. I guess your boolean idea is acceptable.

As an alternative, we could allow a secondary alpha parameter, which specifies the amount to use of the model color vs the draw color.

Indexed palettes are a third option, but an uglier one.

General ENIGMA / Re: DirectX Image formats and Fonts
« on: July 30, 2013, 07:20:08 AM »
I still am uncertain what to do with formats. I think the best course of action is to assume that there are differences in the formats that will be offered by each system's base installation, and that the user will only choose extensions for codecs/formats that are missing. So basically, the LoadPNG code would go in an extension, and would register an image format reader. Before loading any image, the loader function cycles through those loaders and asks each one, "can you load this?". If the extension returns true, it is asked for the data, and the search is over. Otherwise, the next extension is asked. When all extensions have been asked, the data is handed to the base system. In GL's case, that means it's a bitmap, or you're SOL. In DirectX's case, I guess that means it's .bmp, .dds, .dib, .hdr, .jpg, .pfm, .png, .ppm, or .tga, or you're SOL.

As for fonts, GL can do that, too; we don't want mesh fonts. We want nice, anti-aliased sprite fonts. When ENIGMA used meshes for its fonts, they were infinitely ugly. Moreover, you're also relying on an assumption you should certainly not be making: All computers have the font the user requested available. Turns out, not everyone has the super cool font the user picked out in the IDE that looks kind of alien-y. Guess Arial will work in its place, right? In embracing this, you also damn the font_add_sprite() function. The answer is no, no, no, no, and a thousand times, no.

I have no idea what you're asking with regard to sprites vs backgrounds. Maybe it'd help if you gave the correct link, instead of the first one twice. :P
In principle, the only difference between sprites and backgrounds is that backgrounds are not animated, are used as tilesets (meaning, are much more frequently drawn in pieces), and are more frequently tiled. If your sprite batching can accommodate that, I see no reason not to use it for both. Assuming that's what you're asking.

I promise DX can load from RGBA data.

Supposedly, thanks to the WINE team, it comes with DX10, too. There was just some difficulty using it, which isn't surprising.

Either way, if he's comfortable writing these functions for all of them, that's fine; the ones which are most used will naturally be the most maintained. I fear DX10 will basically never be used, but, que sera, sera.

Proposals / Re: Vertex color
« on: July 30, 2013, 07:02:40 AM »
How does GM allow specifying vertex formats manually?
Code: (GML) [Select]

Notice the UK spelling of color, inconsistent with the other spellings in GM. Can't tell if that's deliberate.

The problem is that it is not how GM does it.
Originally, it probably used the equivalent to GL lists in DX. Meaning it was purely an accident—the FFP expected everything to be in the format which was not disabled expressly. So it automatically assigned vertices the current color. This is likely not something Mark coded deliberately. You could use drawing color to work around GM6 Lite not having draw_vertex_color, but still having draw_vertex. Quite funny.

To emulate it outside the FFP, use draw_get_color().

EDIT: You seem to be under the impression that the currently bound color affects model vertices. That shouldn't be the case if they're in a VBO. In this case, all points will be blended by the current draw color, regardless of their own color or texture.

Off-Topic / Re: YoYoGames Compiler for 300$
« on: July 30, 2013, 06:07:30 AM »
Reading hard? Shaders are going to be given for free
Oh, my mistake. I've never been this wrong in my life. To make it up to you, I'll give you a few acres free beach-front property completely free, if you buy this island off of me.

it seems clear to me that YoYoGames' business model does not rely on building a good reputation amongst its customers. I don't know if that will work out for them in the long run.
Unfortunately, it will. The GMC has users who have been around for a long time and are on to Yoyo's tricks. Most of them are not overly interested in purchasing the newest Game Maker at present, but are waiting to see how the fight ends between them and Unity, as part of them buys into Duncan's promise that GM will be the best 2D game creation suite on the market.

The other 95% of the GMC comprises 14-year-olds who are just happy to try making games. These are in no short stock. They show up, sing Yoyo praises for a bit, maybe buy the cheapest GM, then realize Yoyo's a pit of retarded snakes and leave. This process takes a matter of months. But it's okay; customer loyalty is not required when the product rakes in $300 quarterly.

ENIGMA becomes easy, reliable and stable enough for most users
We've been fishtailing around this enormously. ENIGMA has been about that stable for a total of 20 minutes in its past. I don't see it as very likely for this to happen in the near future, but I suppose time will tell.

What's most amazing to me is how all the problems you named are massive, and concern strictly their business model, and are incompatible with ENIGMA's own. I wholly intend to capitalize on their "pirate sprite" faux pas in the future. If not the other two, as well. Granted, ENIGMA 3.5 Mac is not really supported, either; the key difference is that we refunded everyone who was disappointed in double.

Proposals / Re: Vertex color
« on: July 30, 2013, 05:55:20 AM »
We need to do something about that. The options are to waste space for each vertex format or to allow specifying vertex formats manually (as Yoyo has already done; didn't think they had it in them).

If the vertex format specifies draw color, and no draw color is supplied to create it, the current draw color should be used. It's that simple.

What we should do is just mimic their vertex format functions and then construct the d3d_model_ API around that. So d3d_model_vertex_color() would just be a wrapper to whatever new primitive function they use. That function would deal with passing the current draw color to the vertex format if not otherwise specified. The only issue with that is the default draw color of black; in general, the color will have to be white if they want their models to look right.

The intention is to keep the interfaces all but identical, forthevin. I believe it's in our best interest to encourage DirectX on Windows and OpenGL on Mac/Linux. The differences in behavior should be minimized, if not eliminated, to prevent any incidents with porting.

This will be necessary, anyway, for when we start "officially" supporting embedded systems.

Personally, though, I think DX9 Is a step in the wrong direction. Nothing written for it will be compatible with DX10 or 11.

DirectX11 would be my personal choice in target. It works on newer Windows service packs, and on the XBox One, which if anyone actually purchases, promises to support homebrew natively.
Moreover, DirectX11 has this. It's an XNA-like layer over DirectX11. As far as I know, it's .NET free. So you could use its SpriteBatch class for a quick, efficient solution.

Note: All ENIGMA games which use DirectXTK will have to be closed-source due to intentional licensing conflicts by Microsoft.

General ENIGMA / Re: Doxygen Commenting Removed
« on: July 27, 2013, 07:26:38 PM »
Agreed. This takes a lot of the stress off of JDI, so I don't need to focus on its ability to grab that information (though it will still be an objective later on).