EDIT: DirectX 9 buffer access in plug-ins + AGSCharacter->view

Started by lemmy101, Sun 17/02/2008 21:49:02

Previous topic - Next topic

lemmy101

Hey CJ! First thanks for the super fast fix on the PREGUI stuff! didn't want to clutter the thread with this followup thing:

EDIT: Actually sorry to be a pain but the new version it looks like it is drawing that layer behind the background :-S... well it's calling the event and drawing to the buffer but nothing drawn there seems to be visible onscreen at all.

"though bear in mind if you use the Direct3D driver this event will never occur."

I was wondering if there was any documentation on how all this works? or if you could give me any quick pointers on how to access DX9 stuff from plugins, if indeed it is possible at all yet. As if possible we would like to use the DX9 driver as we're doing lots of alpha blendy stuff and at the moment are doing it in software, and as such the game crashes in DX9 rendering and I assume this is because the buffer stuff in the Allegro stuff is not compatible as you say.

Thanks again! :)

lemmy

Pumaman

Quote from: lemmy101 on Sun 17/02/2008 21:49:02
EDIT: Actually sorry to be a pain but the new version it looks like it is drawing that layer behind the background :-S... well it's calling the event and drawing to the buffer but nothing drawn there seems to be visible onscreen at all.

Hmm I'll spend some time later this week to look into this properly. I didn't have any plugin code to hand to test it with today so I made a fix but didn't have an opportunity to make sure it was working.

Quote
"though bear in mind if you use the Direct3D driver this event will never occur."

I was wondering if there was any documentation on how all this works? or if you could give me any quick pointers on how to access DX9 stuff from plugins, if indeed it is possible at all yet. As if possible we would like to use the DX9 driver as we're doing lots of alpha blendy stuff and at the moment are doing it in software, and as such the game crashes in DX9 rendering and I assume this is because the buffer stuff in the Allegro stuff is not compatible as you say.

Well, when in DirectDraw mode, AGS uses a virtual screen that it draws everything to, and then copies this to the real screen at the end of every game loop. That's the behaviour you're used to when using the plugin API.

With Direct3D, there is no virtual screen and the screen has to be redrawn from scratch on every game loop, by blitting all the sprites all over again. At the moment the plugin API doesn't provide a method to interact with this because I wasn't sure what people wanted it to do, but basically the only option I think would be a hook that allowed you to blit extra sprites as part of the rendering loop.

What sort of thing are you wanting to accomplish?

lemmy101

#2
Hi CJ, thanks for the response! :)

Basically at the moment we have TGAs loaded dynamically by the script that can be drawn and animated on the screen with various blend modes... e.g. an additive animated light beam coming in a window with smoke swirls in it, or a subtractive shadow crawling across the room, or for e.g. the logo on the opening sequence which has one normal alpha transparency layer for the text, and a blue additive transparent glow around the letters. These can be set up in the xml script to appear before or after the objects are drawn allowing for layered lighting effects that the characters can walk in front of or behind.

At the moment all the blend modes (transparency, additive, subtractive and overlay) are calculated in software for each pixel based on the alpha value of the overlay that frame and the TGA alpha channel. While this works great, it can take its toll if too much is drawn, or the res gets higher... we did experiment with having a D3D proxy between the player and AGS but it proved to be too flaky.

So if the plugin interface had access to all the D3D interfaces, and with callbacks from different points in the AGS drawing methods... if it would be possible to draw these in hardware and set up renderstates for the blend modes, i.e. be able to pass our own vertex buffers in between the D3D Begin and End calls, and more specifically be able to slot them in between background, objects and gui draws, possibly even be able to set your own pixel shaders and such, then that would be awesome and would provide the plugin interface with a lot of power to do visual effect plug-ins.

Obviously that's no small task and probably not useful for the majority of developers (at least until particle engines and visual effect plugins started to appear), and to be honest we can get away without it so it's hardly a priority feature... but would basically mean unlimited hardware accelerated graphical extensibility within AGS, so if you're open to suggestions for cool plugin interface features then I think this would be one of them now you're all D3D :).

Thanks again!

lemmy

Pumaman

A plugin hook like that shouldn't be hard to do, I'll look into it.

Pumaman

Could you try out this new version of the engine:
http://www.adventuregamestudio.co.uk/acwin.zip
(overwrite the ACWIN.EXE in your AGS Editor folder with it, then re-build your game)

This should fix the screen drawing events with the DX5 driver, and also enable them with the D3D9 driver. When using D3D, the data parameter to the four drawing events is a pointer to the IDirect3DDevice9 that will be in a state between BeginScene and EndScene, and you can call any methods you like on it.

lemmy101


lemmy101

That works a charm! (draw order) Thanks CJ! :)

re: Direct3D It'll take a while to have any feedback, but will let you know!

Thanks muchly! :)

lemmy

Pumaman

Glad it's fixed and working now, I'll put that fix into the next beta.

lemmy101

#8
Hi CJ, I've just noticed something strange that only occurs with the version posted in this thread, not the last beta.

Basically in the plug-in PRESCREENDRAW event, we are overriding the views and frames of all characters on screen using the AGSCharacter* to allow the plugin gesture / pose system to work. For some reason in this build the player character's view variable is having no effect on her current view and she animates with the overridden frame numbers of the walking view instead of her current pose's defined view, where on all other characters setting the view variable works perfectly.

Thanks,

lemmy

Pumaman

If you're modifying the character state inside PRESCREENDRAW, then you might notice a change in behaviour from AGS 2.x. This is because AGS 3 now uses a rendering mechanism whereby it prepares all the images to draw, and then blits them all in one go. In other words, in 2.x it did this:

Draw current background scene
Call AGSE_PRESCREENDRAW
Construct & draw objects and characters
Call AGSE_PREGUIDRAW
Construct & draw screen overlays
Construct & draw GUIs
Call AGSE_POSTSCREENDRAW
Draw mouse cursor and finalize.
Call AGSE_FINALSCREENDRAW
Paste the virtual screen to the real screen. 

Whereas in AGS 3 it does this:

Construct background scene
Construct objects and characters
Construct screen overlays
Construct GUIs
Draw current background scene
Call AGSE_PRESCREENDRAW
Draw objects and characters
Call AGSE_PREGUIDRAW
Draw screen overlays
Draw GUIs
Call AGSE_POSTSCREENDRAW
Draw mouse cursor and finalize.
Call AGSE_FINALSCREENDRAW

This means that it was possible to affect the output of characters & objects by changing their properties in AGSE_PRESCREENDRAW in 2.x, but this will not now work.

Could you use AGSE_FINALSCREENDRAW to prepare them for the next loop, or would you need a new event that happened before AGS constructs the graphics?

lemmy101

Hi CJ, it's doing the same in AGSE_FINALSCREENDRAW unfortunately. :(

Also the thing is that is it works perfectly in 3.0.1 beta 2, and it's only in this acwin.exe that it's started going weird. Also, it only happens to Mia, the player character and all the other characters (like the Doctor in the opening scene) views are being set correctly no matter whether I set them in AGSE_PRESCREENDRAW or AGSE_FINALSCREENDRAW.

Strangely enough, when I reverted back to beta 2 it was still behaving incorrectly. After a bit of panicing I realised I still had the view / frame rewrites on AGSE_FINALSCREENDRAW... So I switched em back to AGSE_PRESCREENDRAW and it worked.

Do you think a new event would work even if AGSE_FINALSCREENDRAW doesn't make a difference? It definitely the reordering of the events seems to have brought this problem to the surface. :(

Thanks for your time :)

lemmy


Pumaman

QuoteAlso the thing is that is it works perfectly in 3.0.1 beta 2, and it's only in this acwin.exe that it's started going weird.

Well, that would be expected, because in beta 2 and previous versions, the events were being fired at the wrong times for the new graphics rendering system, but the times at which they were being fired were consistent with 2.72.

What exactly are you doing? Are you changing the AGSCharacter.view property? If so, are you changing it back again afterwards? Without knowing more about what you're trying to do it's hard to comment on why it might not be working.

lemmy101

For every character in the room we are overriding AGSCharacter->view and AGSCharacter->frame each time the plugin update runs. This is because our gesture system is handling all animation outside walking itself, where basically we have characters set up in an XML file as such:


   <character name="Sam" id="6">

      <pose name="ArmsCrossed">
         <in view="130" start="2" end="5" delay="5" />
         <during  view="130" start="0" end="0" delay="5">
         </during>
         <talking  view="130" start="0" end="1" delay="5" />
         <out view="130" start="5" end="2" delay="2" />
      </pose>
  </character>

In this example Sam, who is character ID 6, has one pose defined, "ArmsCrossed", which uses view 130 frame 2 - 5 to trasition in, then plays frame 0 during the pose, 0 - 1 when talking, and 5 - 2 played backwards to transition out to the next pose.

So therefore every character in the game will be in one of these poses at any specific time, and will have all the views / frames overridden until they start walking, when their animation is unlocked for AGS to take over walking with the walking view. As soon as they stop, the system relocks them and they start feeding off the pose system again.

So we're setting every character's variables in AGSCharacter only once, but whoever is selected at as the player character only the ->frame value is taking root (causing them to do the anims defined in the XML using the correct frame numbers, but remaining on the walking view so facing forward dancing weirdly on the spot) the view is being set, but has no effect on the view used by the player character... where all the other NPC characters view parameter in AGSCharacter is being set with the exact same code, and it works fine. This happens at any stage of the draw events.

If it would help I could try and prepare a demo of the problem?

Thanks again! Sorry I know this is probably a very specific problem to us. :(

lemmy

PS: Thanks for the noexceptionhandling in latest beta! :D that totally rules! :)

PPS: The Direct3D stuff works a charm, thanks! We've got a simple D3D particle system working in an AGS default game. Huzzah! :)

Pumaman

On every game loop, if the character is not locked, AGS resets the player character's view to their default walking view.

With 2.72, in the PRESCREENDRAW event you were able to intercept it after the view had been reset, but before it was used to actually draw the character to the screen.

With the fixed 3.0.1 build, the PRESCREENDRAW event is now occurring after the view has been reset and the character has been drawn -- thus no matter what you change it to, it will get reset again before the character is next drawn.

One thing you could do is change the "defview" of the character, which is the default view that AGS will reset the "view" property to (and is what the ChangeCharacterView command changes).
Another possibility is to set the CHF_FIXVIEW bit on the character flags, which will prevent AGS from resetting the view. However, this could then mess up if the script code runs a LockView/ReleaseView.

So it sounds like what you really need is a new event that allows you to hook into the engine in the same place that AGSE_PRESCREENDRAW used to do, in order for you to update the character properties.

lemmy101

"Another possibility is to set the CHF_FIXVIEW bit on the character flags, which will prevent AGS from resetting the view. However, this could then mess up if the script code runs a LockView/ReleaseView."

Hi CJ! I tried this approach earlier, however it causes problems when I try and move the characters.

"So it sounds like what you really need is a new event that allows you to hook into the engine in the same place that AGSE_PRESCREENDRAW used to do, in order for you to update the character properties."

That sounds great, thanks again for all your help, CJ! :)


SMF spam blocked by CleanTalk