Direct3D Accelerated AGS (beta 6) - Please Test

Started by Pumaman, Sun 02/09/2007 17:45:12

Previous topic - Next topic

TheMagician

I think that adding D3D opens up many new possibilities.
However, as other people already mentioned I think this won't work without changes and/or additions to our currently existing set of functions with regard to the very different nature of 3D and 2D rendering.

Quote from: PUMAMANThis sort of thing is where we need to discover what the optimal solution is. I'm not sure what you're using RawDraw for, but you might well find that just having an Object with the sprite in it is faster with D3D, whereas the RawDraw method is faster under DirectDraw.

I use RawDraw for 80 percent of the special effects in my game (i.e. transparent moving water surfaces, particle effects like rain and snow) simply because the limit of 20 objects per room doesn't allow for anything else. Am I right that this limit still exists in v2.8?
If I remember correctly objects were limited to 20 per room because they used to slow down the engine? If now D3D solves this issue then perhaps the limit should be increased? I could then rewrite the code of my rain particle engine to see if it runs faster with objects instead of RawDraw particles.

And one final question: Would this change to D3D allow for higher resolutions of games (up to 1280x1024)? Because again I think this mainly wasn't possible because the CPU had to render everything?

mätzyboy

Sorry if this is completely out of scope for this discussion, and for not adding any input to the testing of the D3D engine but... Would this increase the chance for 3D characters to be incorporated in the AGS engine in a future edition? I know it can be achieved with Besh's plug-in, but I'm still curious...

scotch

It would make it more easily possible on one level (especially if plugin authors or script can get some access to the 3D context) but AGS is a 2D engine. Trying to impose 3D characters on top of gameplay code written for 2D rooms, hotspots, and so on, is very awkward. Anyone serious about doing a 3D game shouldn't really be using AGS or any of the other primarily 2D game engines. They're just not suited to it.


Pumaman

QuoteAs mentioned above, the two top pics are both 640x480x32 with the new acwin and both fail to scale the original game up to the new resolution.  The sprite displacement and cursor ghosting only occurs with the dx5 mode, however.

Ok, looks like the DX5 driver has some problems with letterbox mode. I'll take a look.

QuoteI had two builds of my engine, one that was using dx 8.1's ddraw routines for blitting and the newer, less specialized d3d blitting routines that use flat polys and the older routines were a bit faster.

If you're talking about DirectDraw, then that's what AGS already uses (and what it continues to use if you select the DX5 driver). I'm not aware of the DirectDraw routines in DX8 being any faster than those in DX5. In fact, DirectDraw was last updated in DX7 and is discontinued from DX8 onwards, with MS telling developers to use D3D instead for 2D games.

QuoteOne simple way I can think of altering tint (without taking into account blending beneath a sprite) is to adjust the tintRed/G/B values and then do a TextureOperation.Add on the coloroperation variable of the sprite to multiply those values against the existing sprite's RGB vals, effectively tinting it.

I can tint the sprites no problem; the problem is replicating the same tint effect that AGS currently does in software mode. As scotch says, this converts the colours from RGB to HSV, combines the HS from the source with the V from the destination, and then converts back to RGB.
I don't believe this is possible in D3D.

This tint issue is the main thing holding it back from being a fully accelerated engine, so I'd like to resolve it somehow. I guess it depends if people would be prepared to put up with a less effective tint in 3D mode.

QuoteSomething else I noticed in dx5 mode is that when you start dialogs all the objects, sprites and guis in a room are shut off temporarily.  They come back on as soon as the dialog finishes.  This does not happen in D3D mode.

Interesting, I'll look into it.

QuoteThe sprites on Raven won't scale smoothly and some of the images alpha blending won't work.

As Gilbert says, please post a screenshot of a Before and After scenario. Your description is far too vague to investigate as it stands.

QuoteIf I remember correctly objects were limited to 20 per room because they used to slow down the engine? If now D3D solves this issue then perhaps the limit should be increased

That's a reasonable point, and something I'll certainly consider.

QuoteSorry if this is completely out of scope for this discussion, and for not adding any input to the testing of the D3D engine but... Would this increase the chance for 3D characters to be incorporated in the AGS engine in a future edition?

Potentially yes, however at the moment I have no plans to do so.

Pumaman

Ok, I've managed to get the HSV tinting working by using a custom pixel shader, however this would only work on graphics cards made for DX9.0a and later (which is basically cards made from about 2003/4 onwards).

I'm not sure if this is a reasonable minimum requirement to use the D3D driver, I guess I'll try and upload a version with this and see how many people it works for.

scotch

#25
It does seem unavoidable unless a very different tint effect was used. Most games don't use tinting though, so the pixel shader requirement would only be for games that do, right?

A lot of AGS game players will be on older hardware, perhaps the AGS effect can be cloned in PS1.1? Doing HSV conversion for each pixel seems to run out of temp registers (is that what's making it require PS2.0?) but since the tint is the same for the whole sprite you may as well precalculate that bit, set it as a vertex colour and scale it by the luminance of the sprite pixel, something like

Code: ags
sampler s0 : register(s0);

float4 main(float4 tint: COLOR0, float2 tex : TEXCOORD0) : COLOR {
	float amount = tint.a; // getting tint amount from the vertex colour alpha
	float4 pixel = tex2D(s0, tex); // supplied colour should be the RGB equiv of the HSL value, with 100% L
	float lum = dot(pixel, float4(0.299, 0.587, 0.114, 0)); // get lum from the image
	return tint * lum * amount + pixel*(1-amount); // scale the tint by the luma and blend it with the original sprite
}



the vertex colour supplied for object.Tint(are, g, b, sat, lum); would be HSLtoRGB(RGBtoHSL(are,g,b).h, 100%, lum) with the alpha set to sat. I might be way off the mark, but that looks similar to AGS's tint at a glance.

Edit: txt filter doesn't like "r"!

Shane 'ProgZmax' Stevens

That does look very similar, scotch.  You could do a quick internal check to see if a person's video card has the right hardware to support the new tinting method and switch between software/hardware rendering on the fly, that would eliminate the possibility of incompatibility issues altogether.

monkey0506

Quote from: ProgZmax on Tue 04/09/2007 06:10:56You could do a quick internal check to see if a person's video card has the right hardware to support the new tinting method and switch between software/hardware rendering on the fly, that would eliminate the possibility of incompatibility issues altogether.

I was going to mention something like that except 1) I have no experience in this field whatsoever and didn't really have a clue what I was saying and 2) I figured it was probably a pretty obvious solution to check "on-the-fly" if such a thing is even possible that I just felt dumb for considering suggesting it. :=

scotch

Yeah, that would be a better compromise.

GarageGothic

Is there any chance, that RawDraw could be implemented with a set of hybrid commands that allow the CPU to handle all RawDrawing in a screen buffer and only transferred to the GPU when actually displayed (at end of game cycle)?

I've spent 3 years coding different subsystems for my game (html module, dynamic shadows, lens refraction, even the custom dialog system), that all use RawDraw. Since they all operate by RawDrawing images or text onto the background, deforming and cropping the area and then grabbing it to a DynamicSprite, which may then be assigned to a character or an object, there is no easy workaround. It's really a shame if I can't take advantage of the hardware-accelerated engine, since my game is in hi-res using 32-bit, alpha channeled sprites which is exactly what it was made for.

Edit: Regarding the DirectDraw engine crashing on game-start, I'll see if I can isolate the problem and remove the game content that's not involved. Then I'll upload it.

Pumaman

QuoteA lot of AGS game players will be on older hardware, perhaps the AGS effect can be cloned in PS1.1? Doing HSV conversion for each pixel seems to run out of temp registers (is that what's making it require PS2.0?) but since the tint is the same for the whole sprite you may as well precalculate that bit, set it as a vertex colour and scale it by the luminance of the sprite pixel, something like

scotch, you're a genius, and I owe you a drink! :)
The problem was that I was calculating the HSV of the pixel colour in the shader, but since only the V is actually needed I've stripped out the H and S code, which now means it compiles with ps_1_4, which is DirectX 8.1. This means that it should run on graphics cards made from late 2002 onwards.

For the moment there's no software alternative, and I'm uploading beta 2 which will refuse to load with the D3D driver if your graphics card is too old, so that we can assess how many people it's likely to affect.

QuoteYou could do a quick internal check to see if a person's video card has the right hardware to support the new tinting method and switch between software/hardware rendering on the fly, that would eliminate the possibility of incompatibility issues altogether.

I'm not sure if there's any point. If the graphics card isn't made for at least DX 8.1, then its 3D capabilities are probably pretty shoddy, so the player would probably be better off just using the DX5 software driver.

QuoteIs there any chance, that RawDraw could be implemented with a set of hybrid commands that allow the CPU to handle all RawDrawing in a screen buffer and only transferred to the GPU when actually displayed (at end of game cycle)?

It does that already, but 3D cards *really* don't like you changing the data on their textures. If you're using anything like RawRestoreScreen, RawDrawFrame, etc then the whole background needs to be updated, which means updating a significant amount of texture data each frame, which is bound to cause it to run slowly.

QuoteI've spent 3 years coding different subsystems for my game (html module, dynamic shadows, lens refraction, even the custom dialog system), that all use RawDraw. Since they all operate by RawDrawing images or text onto the background, deforming and cropping the area and then grabbing it to a DynamicSprite, which may then be assigned to a character or an object, there is no easy workaround.

It's only if you RawDraw every frame that you'll notice the slowness. It's fine to construct some dynamic sprites by using raw draw, just as long as you don't do it on every game cycle.


Anyway, beta 2 is now up. This has the following changes:
* Implemented hardware accelerated tint
* Fixed walk-behinds not working in scrolling rooms
* Fixed letterbox mode with DX5 driver

I've also updated the Known Bugs section in the first post with the reported issues.

With this new engine's hardware tinting, the Mind's Eye intro goes from 10 fps to 50 fps on my machine.

Shane 'ProgZmax' Stevens

Nice work, CJ.  Shame I couldn't be of more help on this occasion.  At any rate, maybe a comparison of fps ratings using the AGS internal counter will be of some use.

First the original acwin @ 320x200:



and @ 640x400:




And now the new acwin using the dx5 setting @ 320x200:



and @ 640x400:




And finally d3d mode @ 320x200:



and 640x400:




First I'll say that these fps ratings were either taken as the average (in the case of the dx5 and original) or at a constant rate (the d3d values remained stuck at 40 regardless).

The main thing I noticed (aside from clearly not having as good a rig as you do) is that the original actually rendered the high res title screen faster than the newer acwin.  I thought perhaps the dx5 mode was just a carry-over from the old acwin but there seems to be some difference there. 

Both modes clearly outperform the old method in every case except 640x400 vs dx5, and after several retests it seems pretty clear that the old acwin has a 4-8 fps advantage in this mode over dx5, which is weird (but not large enough to worry about, I think).

Overall this new version yields considerable bonuses -- particularly at larger resolutions.  Excellent work!




SSH

I think this RawDraw issue highlights the need for being able to RawDraw onto sprites, or some kind of temp screen that isn't going to be displayed. Would rawdrawing onto a DIFFERENT background (i.e. switch BG number to one of the 2-5 other BGs) then switching back speed things up?
12

scotch

I can see a slight advantage to that, but like CJ said, this is only a real problem if you're doing a lot of big rawdraws every frame. In the kind of situation you might predraw some static things in another room it's going to be barely noticable.

Rawdrawing onto sprites sounds more useful, GarageGothic's hack of drawing to the screen then capturing that to a sprite sounds a little messy.

Pumaman

Quotethe d3d values remained stuck at 40 regardless

That's probably because your game speed is set at 40 fps. You can use the Ctrl+E key in the new engine to un-cap the game frame rate if you want to see how much your computer can manage.

Quotethe original actually rendered the high res title screen faster than the newer acwin.  I thought perhaps the dx5 mode was just a carry-over from the old acwin but there seems to be some difference there. 

Although the dx5 mode is just a carry-over from the old acwin in spirit, I've had to make a lot of changes to AGS in order to make the graphics rendering compatible with the way that 3D engines work. Therefore, I've had to re-jig a lot of the 2D code as well, which is why we're seeing bugs in the DX5 driver that weren't there in the old acwin.
Hopefully, by testing out this new engine as we are now, it'll allow us to find the problems early on.

QuoteI can see a slight advantage to that, but like CJ said, this is only a real problem if you're doing a lot of big rawdraws every frame. In the kind of situation you might predraw some static things in another room it's going to be barely noticable.

I'd be interested to see a few example cases of where people are RawDrawing on every game cycle. Perhaps there's a faster way?

QuoteRawdrawing onto sprites sounds more useful, GarageGothic's hack of drawing to the screen then capturing that to a sprite sounds a little messy.

I completely agree, it's something that I've been meaning to do for ages. Hopefully I'll get round to it soon ;)

GarageGothic

#35
QuoteI'd be interested to see a few example cases of where people are RawDrawing on every game cycle. Perhaps there's a faster way?

Here's a few examples of that from my game.

Dynamic Shadows (please disregard the pre-rendered shadow of the horse):


Arguably, this could be done without RawDrawing, but it would be a pain in the ass. The shadow module crops the floor,wall and ceiling shadows according to predefined wall lines by RawDrawing the geometry using RGB(255,0,255). The only workaround that I can think of would be to define detailed walkbehinds for every single room that uses shadows. This is not a satisfactory solution.

Edit: Oh, I just remember why it can't even be done with walkbehinds. You'd have to make sprites of every single floor surface, which is even worse

Optical effects:




These are examples of a couple of lens refraction effects. They use RawDrawing for 1) compositing many differently scaled pieces into one single sprite and 2) for cropping the DynamicSprite to a non-rectangular shape. I don't think there's a simpler (or even any other?) way to do this.

I think RawDrawing to sprites is a great idea, especially if it can help on the Direct3D situation since it would mean not having to use RawRestoreScreen every loop (which - to be - honest, even simple RawDraw effects like the dog leash in Blackwell Legacy needs). For my purposes the SpriteRawDraw would need to support all the same functions as the current RawDraw routines, and it would be nice with a few more (for instance copying the alpha channel of an existing sprite to a DynamicSprite of the same size).

Edit: Will the new DirectX 5 mode replace the current graphic rendering in future versions of AGS? I really hope I won't be stuck with 2.72 for my future games  :-\

Pumaman

QuoteThese are examples of a couple of lens refraction effects. They use RawDrawing for 1) compositing many differently scaled pieces into one single sprite and 2) for cropping the DynamicSprite to a non-rectangular shape. I don't think there's a simpler (or even any other?) way to do this.

Interesting, thanks for the examples. I guess the main problem is the fact that you're having to use RawRestoreScreen that's causing the slowness, if you were able to RawDraw directly to a sprite then this probably wouldn't be such an issue.

QuoteEdit: Will the new DirectX 5 mode replace the current graphic rendering in future versions of AGS? I really hope I won't be stuck with 2.72 for my future games

I don't really understand the question. The new DX5 mode *is* the same as the current 2.72 rendering.

GarageGothic

Oh, I see - then I REALLY must find out what makes the DirectX 5 engine crash my game when using the new .exe file.

And yes, RawRestoreScreen() does seem to be the main issue. On second thought - is there anything that keeps the RawSaveScreen() image from being stored in the graphics card memory rather than in the RAM?

Vince Twelve

Quote
QuoteWhen teleporting to a very big room (a 640x4000 pixel black background), the game crashed with the message: "Error: Bitmap too large for texture memory". My machine is a laptop with a 128MB Radeon Mobility 9700 and 1 GB RAM.

Interesting point. 3D cards have a maximum sprite size, and it looks like 4000 pixels is too high for your system. It's something I can code around by internally creating two D3D sprites and splitting the background across them, but I wonder how widespread this problem will be.

I was going to try this out on Linus which was also a system chugger, but I had this same problem.  For the intro and ending, I used a room that was 10 or 12 screen widths wide and moved the viewport down the room using each 640x480 block as a frame of animation.

Would weaker systems crash on even smaller screens than stronger systems?  This kind of uncertainty would make me nervous to use scrolling rooms.  I have a few larger rooms in my WiP.

Monsieur OUXX

#39
Quote from: Vince Twelve on Thu 06/09/2007 01:22:13
Quote
QuoteWhen teleporting to a very big room (a 640x4000 pixel black background), the game crashed with the message: "Error: Bitmap too large for texture memory". My machine is a laptop with a 128MB Radeon Mobility 9700 and 1 GB RAM.

Interesting point. 3D cards have a maximum sprite size, and it looks like 4000 pixels is too high for your system.

Would weaker systems crash on even smaller screens than stronger systems?  This kind of uncertainty would make me nervous to use scrolling rooms.  I have a few larger rooms in my WiP.

AFAIK, this problem doesn't come from the "strength" of the system (at least, not from the processor/ram combo); this would be exclusively a graphics card issue, since textures handling has been having very annoying restrictions for a long time (maximum size, dimensions must be a power of 2, etc.). I believe that texture size restriction has been removed only VERY recently, which could explain why this problem appears even on quite recent systems.

Nevertheless, i'm a bit surprised that this hasn't been "workarounded" by some kind of software - there ususually is a mad guy who codes the appropriate library to solve the harware limitations (i'm not talking about the AGS community, I'm talking about the OpenGL/DirectX communities). Maybe this kind of library didn't come in a consensual version, which would explain why it is not directly integrated in every rendering engines?
 

SMF spam blocked by CleanTalk