Sorry your browser is not supported!

You are using an outdated browser that does not support modern web technologies, in order to use this site please update to a new browser.

Browsers supported include Chrome, FireFox, Safari, Opera, Internet Explorer 10+ or Microsoft Edge.

AppGameKit Classic Chat / (Problem) BackBuffer Access...

Author
Message
Raven
14
Years of Service
User Offline
Joined: 23rd Mar 2005
Location: Hertfordshire, England
Posted: 12th Apr 2019 19:47 Edited at: 12th Apr 2019 19:48
Alright... so I'm not trying to do anything overtly complex




Now this is stripped down to basically a few elements I'm tinkering with and to remain runnable.
The key function in question is at the end of the code., you're bog standard "Get The Colour at the Indicated Pixel" ... except, it doesn't.

I mean it "Does" but because it seems to be ignoring the Draw Operations ... it means what it's Returning is., well... wrong; as the Final Composite Colour relies on the Alpha Blend between the Layers.
On top of this the Background itself is just coming up Milhouse (I mean NULL).
Now you'd think, "Oh hey... why not just shadow the ACTUAL Backbuffer" ... man, would I love to do that., except for reasons known only to the TGC Team... there is no way to access it (atleast not from within BASIC., via C++; sure I could just grab the OpenGL Context Pointer, blah blah blah)

I'm sure given some time, I'd eventually figure out a workaround on my own., but this is like the 3rd damn thing today that doesn't "Just Work" as outlined within the Help and I'm about ready to throw my PC through a Window., because of how absolutely Basic this is in terms of 2D Workflow.
I mean FFS... you want the Alpha of a Pixel? Yeah, the Normal Colour Function doesn't do that... you have to manually take it from the Signed Integer., oh and you want to use Standard Hex Colour Values? Yeah, no... we don't order the Pixel Colours like that., so you have to manually convert between how everyone else constructs a pixel and how AppGameKit has decided to do it.
fubarpk
Moderator
14
Years of Service
Recently Online
Joined: 11th Jan 2005
Location: Adelaide
Posted: 12th Apr 2019 20:09 Edited at: 12th Apr 2019 20:28
if you want to get the backscreen colours what I believe you need to do is make use of memblocks
you have two ways you could do this one is by grabbing the pixel colour at that location
Method1 you may find this one a little less source hungry as it doesn't grab the full background image each time


Method 2
is similar and also uses the memblock but if the background dont change there isnt a need to
grab the image again and again you just need to do similar to the above snippet but just calculate
and return the color from that location

with the returned values from the function you could use
r=GetColorRed ( color )
g=GetColorGreen ( color )
b=GetColorBlue ( color )

EDITED nomatter which way you chose the background image needs to exist and any additions
to it should be rendered to it. So you may need to make use of the rendering commands
fubarpk
fubarpk on Itch...………...https://fubarpk.itch.io/
fubarpk on googleplay..https://play.google.com/store/apps/developer?id=fubarpk
Golelorn
2
Years of Service
User Offline
Joined: 20th Nov 2016
Location:
Posted: 12th Apr 2019 20:16
You are clearing your backbuffer, after you draw your sprites. You are then rendering your entire scene to the "backbuffer" image which no longer include your draw commands.

Here is how I usually call to the back buffer:
SetRenderToImage()
ClearScreen() // Clears everything out
DrawSprites // Objects or render or whatever
SetRenderToScreen()
Bengismo
1
Years of Service
User Offline
Joined: 20th Nov 2017
Location: Yorkshire, England
Posted: 12th Apr 2019 21:41 Edited at: 12th Apr 2019 21:44
Quote: "for reasons known only to the TGC Team... there is no way to access it (THE BACKBUFFER) (atleast not from within BASIC., via C++; sure I could just grab the OpenGL Context Pointer, blah blah blah)"


Yes there is a way to get the backbuffer..... Its the GetImage() command
Fubarpk and golorn are correct above and have pretty much covered it.

You can just grab one pixel if you want then convert that one pixel to a memblock and sample RGBA values.

So:
GetImage()
Convert to single pixel memblock
Read 4 values RGBA
delete image
delete memblock


Draw Commands
If you use any of the commands starting with "Draw":
Draw3DParticles ( ID )
DrawParticles ( ID )
DrawObject ( objID )
DrawSprite ( iSpriteIndex )
DrawBox ( x, y, x2, y2, color1, color2, color3, color4, filled )
DrawEllipse ( x, y, radiusx, radiusy, color1, color2, filled )
DrawLine ( x, y, x2, y2, red, green, blue )

These render just that particular item to the backbuffer immediately. These calls are not stored and rendered on any subsequent frames. They are not managed by AppGameKit - meaning they are not persistent. They are drawn just once in that frame and depth sorting can be dependent on the order in which they are called.

Render() or Sync()
This draws all managed Items (visible sprites,particles and textboxes and edit boxes) to the backbuffer. Every time its called, all the previously created items are drawn. Non of the previous "draw" based commands are repeated though.
Raven
14
Years of Service
User Offline
Joined: 23rd Mar 2005
Location: Hertfordshire, England
Posted: 13th Apr 2019 00:50


Bengismo wrote: "Yes there is a way to get the backbuffer..... Its the GetImage() command"


And how do you push it back to the Backbuffer without putting it on a Quad or making it into a Sprite?
Yet, beyond that... that one command is actually what was causing the issues with the Rendering Pipeline I was having.

I'd strongly suggest trying (without looking at what I did to resolve it) the solutions proposed with my original code... it will drive you crazy trying to figure out why it isn't behaving as the Help is saying it should.
Because that order of stuff you posted., yeah that's not how that works... if it was, I wouldn't even need to call Render( ) but even doing so should work but doesn't.
Now I think I've got a "Good" Grasp on what it's doing., and I need to remember to frankly ignore the help as it's wrong.

< • >

As for the current make-shift solution., it's expensive; and honestly I'm rethinking the entire approach.
What I have could potentially be used for (near) costless manual calls, but they still always have to be in the same position; so I might create a Push-Pop Queue for a Per Render Execution; might reduce the cost., but I don't know if the performance is due to call count or size of the memory being moved.
Still something of this nature requiring quite this much effort., well it somewhat defeats the purpose of AGK.
Bengismo
1
Years of Service
User Offline
Joined: 20th Nov 2017
Location: Yorkshire, England
Posted: 13th Apr 2019 09:53
Which bit of the help is wrong exactly??
Raven
14
Years of Service
User Offline
Joined: 23rd Mar 2005
Location: Hertfordshire, England
Posted: 14th Apr 2019 17:46
Render Ordering … and frankly what the Render() Commands are even doing.
Like you want a good example, simple play with the ordering of the Sprite Draw and / Point Grab from my "Fixed" approach.

Drawing the Sprites before calling Render( ) while using GetImage( ) after., simply refuses to Render the Sprites.
Remove the GetImage( ) and they Render again.

On top of this the Swap( ) clearly states you must Clear it., something to do with "Performance on certain GPUs" … alright but that should mean that Swapping (Buffer Flipping) is just that., you're essentially doing:
BackBuffer = RenderColor[0] ? RenderColor[1]
(And man what I wouldn't give for THAT Operator to be available in the BASIC Language., essentially it swaps the contents of the 2 Elements; some BASICs do have Swap(A, B) … not DB/DBP/AGK though, because "Reasons")
Alright, but that would also mean that doing this would result in the Previous Frame being accessible via the GetImage( ) (as the Active BackBuffer has changed, but the actual Data hasn't gone anywhere) until you call the ClearScreen( )

Except that's not the case, as it seems AppGameKit either Automatically Clears the Screen at some point during the Swap( ) to the Clear Colour.
Although why this isn't forced as a Manual thing is weird.

I'm not sure why we can't manually set the Front, Back and Depth Buffer... like I mean, we technically can., but well when I have time I'll showcase what I mean; but still essentially this is getting to the point where I might as well be using Native OpenGL instead.
All of this could easily be solved if when the Swap() / Present() occurs; the entire Back Buffer is Shadowed in an Accessible Image / MemBlock.
It would also be great if there was a GetImageUpdate( ) or GetMemblockUpdate( ) Function., as it's the Allocation aspect that's quite performance intensive... if I already have an Image / Memblock that is the correct size., then I should be able to just do a basic MemCpy operation; which is relatively performance neutral.
I'll throw together an example of that as well in a bit., because seriously you'd be surprised at just how much of a difference it makes; but simply isn't something we have access to.
Bengismo
1
Years of Service
User Offline
Joined: 20th Nov 2017
Location: Yorkshire, England
Posted: 14th Apr 2019 20:45 Edited at: 14th Apr 2019 22:24
To be honest ive not had a problem drawing sprites and then using get image to get the backbuffer. Its always seemed to work ok so I cant really comment on the issues your having.


Quote: "Except that's not the case, as it seems AppGameKit either Automatically Clears the Screen at some point during the Swap( ) to the Clear Colour.
Although why this isn't forced as a Manual thing is weird. "


It is documented though....
https://www.appgamekit.com/documentation/Reference/Core/EnableClearColor.htm

AGK does clear the backbuffer automatically as standard in the swap() and sync() but you can disable it if you want to manually do it so you can keep the previous contents. There's an example that comes with agk that uses the technique of continually modifying the previous back buffer. Its the same with the depth buffer too as most people just want it to be cleared but you can disable it if wanted.

The command describes using a renderimage to continually control your own backbuffer or buffer chain that you can use. A render image might really be exactly what your after.

If you could provide code and an explanation of what your trying to acheive but that isnt working as expected then im sure people could actually help.



EDIT:
Im not sure what you were trying to achieve with your code above but ive edited it to make it work and at least display the correct pixel color. You were doing a number of things that were preventing you from getting correct values. Rather then actually list them all....I will just list the code.




Lastly, just for reference...for some reason you have listed in you code that AppGameKit stores RGBA in an integer in some weird colour order
// AppGameKit Colour Format, I know "CreateColor" exists but it doesn't support Alpha Channel :\
// Remember Standard is ( Red, Green, Blue, Alpha ) ., AppGameKit is ( Blue, Green, Red, Alpha )

Thats not correct, AppGameKit stores as Red,Green,Blue,Alpha .. same as standard

bits 0-7 Red
bits 8-15 Green
bits 16-23 Blue
bits 24-31 Alpha

I havent bothered correcting that section of your code
Ortu
DBPro Master
11
Years of Service
User Offline
Joined: 21st Nov 2007
Location: Austin, TX
Posted: 15th Apr 2019 00:16
There is some little endian/big endian oddness going on with agk, I've run in to this also
http://games.joshkirklin.com/sulium

A single player RPG featuring a branching, player driven storyline of meaningful choices and multiple endings alongside challenging active combat and intelligent AI.
Raven
14
Years of Service
User Offline
Joined: 23rd Mar 2005
Location: Hertfordshire, England
Posted: 18th Apr 2019 19:18
Quote: "Im not sure what you were trying to achieve with your code above but ive edited it to make it work and at least display the correct pixel color. You were doing a number of things that were preventing you from getting correct values. Rather then actually list them all....I will just list the code."


o_O … the Code worked fine to return the Colour on Windows / x86-64.
It was one of the elements that was frustrating me in regards to the help... as the help clearly stated that the Memory Blocks [I]should[/I] work identically to Dark BASIC v1 "Classic" and Dark BASIC v3 "Professional"., except... they don't.
At least that is to say they don't for me on Windows 10 (64bit) with AMD Processors.

So take the Image Memory Block for example., my code above with the Alpha / Blue Swapped; Returns / Sets the CORRECT Colour.
The same is true when using Hexidecimal Colours; where-in the Standard: 0xFF0000 / 0x00FF00 / 0x0000FF … should be Red, Green, Blue (in that order) except they aren't in AGK; as they produce Blue, Green, Red.
Which as Ortu suggest; could easily be caused by Reversed Endian Behaviour when it comes to the RGB (24bit) Component of the ARGB Value (and remember that has been the Universal Ordering for Colours independent of Platform since 1991 and the W3C / VESA Standard)
I've seen similar issues in regards to the XYZ(W) … which become XZYW., and I know this has nothing to do with the Endian; but instead is a switch between Common Axis Ordering and OpenGL Axis Ordering which today, MOST Engines will Silently Fix this "Odd" Behaviour that was never corrected.

And AppGameKit does in some cases., and doesn't in other cases. (Again, at least as far as Windows 10 / x86 is concerned)

Quote: "It is documented though....
https://www.appgamekit.com/documentation/Reference/Core/EnableClearColor.htm

AGK does clear the backbuffer automatically as standard in the swap() and sync() but you can disable it if you want to manually do it so you can keep the previous contents. There's an example that comes with agk that uses the technique of continually modifying the previous back buffer. Its the same with the depth buffer too as most people just want it to be cleared but you can disable it if wanted."


Except., disabling that doesn't just Disable Automatic Back Buffer Clearing; but instead Disables the Clear Commands Entirely.
Meaning when you want to Clear the Buffer / Screen., you HAVE to use for any Alpha / Direct Surface Draws; you're essentially forced to use the Slower Commands (such-as DrawBox) to handle this or have a Custom Back Buffer Pipeline; which STILL need to be used along side the AppGameKit Pipeline.
While... it isn't strictly a "Doubled Frame Render", in a best case scenario you're still looking ~28% Performance.

All because the BackBuffer doesn't wait for the "ClearScreen()" call for Manual Clearing... NOR can you Create your own Back/Front Buffer and them simply assign them to be used as the Actual (Virtual) Screen Buffers; instead as noted you essentially have to create your OWN.
Now (a) Solution to this was to create a Screen Size Sprite; with the Clear Colour and setting it to the Bottom Z-Depth (10,000) Layer, ensuring it's always Rendered first; and this does improve performance slightly; but still this means replacing all of the "Clear" Functions with your own; and this if further compounded by the fact that this won't even work on Mobile because; they Render in Tiles (as opposed to the whole Screen)., so when you Sync( ) / Swap( ) they'll perform this Clear anyway regardless if it's Enabled / Disabled.

This could all be avoided IF the Back/Front Buffer was something you could either (a) manually override with AppGameKit Resources (Render Images) or (b) were provided as say ImageID 0 (Back), 1 (Front) and 2 (Depth) by Default.
In any case., as I stated from the very beginning... ALL of this is A LOT of faffing about just to have a Working "Point(X, Y)" Function to Grab the Final Result (i.e. Rendered) Pixel Colour at Screen Coordinate; you know the Feature EVERY BASIC since 1972 has had, which is just simply not present in AGK.
While many of the solutions above work "In Theory"., in-practise however they run into various issues due to Draw Ordering that simply make them unusable in regards to the Final Composite.
And why? Well, because AGK's Drawing Routines are using a variety of different methodologies when it comes to how / when they are Drawn and Presented to the Screen Buffer.

Some are Immediate., Some are Queued., Some are Immediate ONCE other Raster Operations are Complete., and there is no blasted Rhyme or Reason as to why which uses which.
If TGC want AppGameKit Sprites to be part of the 3D Pipeline (as is the case in DirectX) … fine., I have no issues with that; but don't do this retarded half-way house about it; they're either Queued for the Render( ) Call; or they're Immediate; but this situation where depending on the Scenario they can be either / or like Schrodinger' Sprites is stupid and confusing.

AGK as a whole feels like it's two different Engines that were simply duct tapped together... so when you try to do certain things., the Engine has it's own ideas about what it's going to do and needs to be handled.

Login to post a reply

Server time is: 2019-05-22 18:03:10
Your offset time is: 2019-05-22 18:03:10