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.

DarkBASIC Discussion / Caleb1994 and Backbuffer drawing

Author
Message
Latch
17
Years of Service
User Offline
Joined: 23rd Jul 2006
Location:
Posted: 13th Feb 2010 20:18
Hi Caleb,

Previously, you were asking about creating a drawing dll and what methods might be faster than others. At the time, one of my responses indicated that using the backbuffer could be slower than one would expect. I based this on things I had read on the forum, some of my own implementation attempts, and on the examples that came packaged with DBC.

I was poking around a little with accessing and writing directly to the backbuffer lately and it's much faster than I had originally thought. My original tests involved using memblocks, and images and writing back and forth from the backbuffer to the memblocks and to the images etc. This was SLOOOOWWWWW. I think mainly because of the conversion between memblocks, bitmaps, and images. But when writing directly to the backbuffer, it seems very fast. I've just tested creating a dot command and a point() command in a dll. Both are fast. My custom dot command passes color information directly to the dll so there is no INK command being used which also adds to the speed if changing the color of pixels on the fly.

At 800,600,32 resolution, with a rotating cube on the screen, code such as:



which puts 100000 random colored dots all over the screen takes about 1100 ms to run using the built in color and dot commands. Using my custom dll in place of ink and dot, it takes about 168 ms . That's about 7 times as fast.

I have yet to run more tests. I want to recreate the example from DBC where there is a cube warbling on the screen. That runs extremely slow with emulation on and off. I think the slowness that I've read about quoted on the forums and in that example itself is more due to code that may need optimization. I know on my part, I was using memblocks and images along with the backbuffer and managing the graphics with the bb pretty poorly when I look at it now - and I never really did proper testing and took what I have read at face value without really challenging it.

So with all that being said, If I had discouraged you from trying out stuff on the backbuffer, I encourage you now. I'm gonna try and recreate a few of the other drawing commands like box, and line, and see how they match up to the internal ones.

Enjoy your day.
Libervurto
17
Years of Service
User Offline
Joined: 30th Jun 2006
Location: On Toast
Posted: 14th Feb 2010 10:24
Sounds good,
I've been working on a paint program using memblocks and I've found it is a lot faster than the built in commands.
What I do is create a memblock in bitmap format which I only update when necessary, the more drawing I do to the memblock before conversion, the greater the increase in speed compared to the built-in commands. So drawing my own custom lines and boxes and circles are all much faster than the built-in commands. That seems odd to me because the built-in commands can't be doing any more maths, and I don't see why the screen would need updating more than I do with the memblocks.
The memblock conversion is evidently the slowest part of this process.

I'll have to learn how to use DLL's, this one interests me.

"With games, we create these elaborate worlds in our minds, and the computer is there to do the bookkeeping." - Will Wright
TDK
Retired Moderator
21
Years of Service
User Offline
Joined: 19th Nov 2002
Location: UK
Posted: 14th Feb 2010 19:48 Edited at: 14th Feb 2010 19:49
I too am doing the same thing - but in DBPro for Dark Sprites. And, when it comes to speed, there's very little difference in the speed of 2D drawing commands in DBC and Pro.

I also got around this by using memblocks - but didn't go as far as bypassing DB's built-in drawing commands (apart from a couple I needed that didn't exist).

But at least I know I have another level of optimization available to me if I need it.

TDK

Libervurto
17
Years of Service
User Offline
Joined: 30th Jun 2006
Location: On Toast
Posted: 15th Feb 2010 04:06
@TDK
It's surprising how much faster it is. Even a single dot is far quicker if you write the pixel to a memblock. I can't remember how my test came out but I think it was about seven times faster than the DOT command.

"With games, we create these elaborate worlds in our minds, and the computer is there to do the bookkeeping." - Will Wright
TDK
Retired Moderator
21
Years of Service
User Offline
Joined: 19th Nov 2002
Location: UK
Posted: 15th Feb 2010 04:41
Quote: "It's surprising how much faster it is"


I think you misunderstood me.

I'm agreeing that using memblocks is a lot faster. What I was saying was that there wasn't a lot of difference in speed between DBPro's 2D drawing commands and DBC's - in other words, DBP wasn't significantly faster drawing in 2D like I expected it to be.

TDK

Latch
17
Years of Service
User Offline
Joined: 23rd Jul 2006
Location:
Posted: 15th Feb 2010 11:03
Ok. I ran a few more tests. I'm starting to understand what the slowness with the backbuffer is about. It's about reading information from the backbuffer. Writing to it is lightning fast, but reading from it is very slow - which puts a bit of a monkey wrench in a few plans I had. At any rate, I'm going to still try and see how similar drawing commands to the built in DBC 2d commands function in terms of speed when writing to the backbuffer directly.

Quote: "What I do is create a memblock in bitmap format which I only update when necessary, the more drawing I do to the memblock before conversion, the greater the increase in speed compared to the built-in commands. So drawing my own custom lines and boxes and circles are all much faster than the built-in commands."


Quote: "I also got around this by using memblocks "


Did you guys get this to work with 3d and 2d at the same time? If so, how? The only way I can think of is changing the memblock to an image and pasting that with transparency or using draw to back.

Quote: "I've been working on a paint program using memblocks and I've found it is a lot faster than the built in commands."

I'm just curious, instead of a memblock did you try just drawing everything on an off-screen bitmap and just copy that bitmap to 0? That tends to be faster than drawing directly on 0 even with the built in commands.



no offscreen bitmap is slower:



Enjoy your day.
TDK
Retired Moderator
21
Years of Service
User Offline
Joined: 19th Nov 2002
Location: UK
Posted: 15th Feb 2010 13:55 Edited at: 15th Feb 2010 13:55
Quote: "Did you guys get this to work with 3d and 2d at the same time?"


I am mixing 2D and 3D at the same time in my application, but I think you mean writing 2D on top of 3D, so the answer is no.

I needed normal 2D paint program functions for my sprite designer (http://forum.thegamecreators.com/?m=forum_view&t=164981&b=4) and as you say, it's the reading side of things that are really slow, so you can imagine writing a magnify routine was just not possible using Point().

TDK

Libervurto
17
Years of Service
User Offline
Joined: 30th Jun 2006
Location: On Toast
Posted: 15th Feb 2010 17:59 Edited at: 15th Feb 2010 18:00
Quote: "I also got around this by using memblocks - but didn't go as far as bypassing DB's built-in drawing commands"

That's what I was referring to when I said even making your own dot function is faster. I know you were agreeing, I was agreeing with your agreement

Quote: "Did you guys get this to work with 3d and 2d at the same time?"

No, mine is totally 2D.

"With games, we create these elaborate worlds in our minds, and the computer is there to do the bookkeeping." - Will Wright
TDK
Retired Moderator
21
Years of Service
User Offline
Joined: 19th Nov 2002
Location: UK
Posted: 15th Feb 2010 19:15
Quote: "I was agreeing with your agreement"


Ah, that's OK then!

TDK

Caleb1994
15
Years of Service
User Offline
Joined: 10th Oct 2008
Location: The Internet you idiot!
Posted: 18th Feb 2010 05:57 Edited at: 18th Feb 2010 06:03
Interesting, How are you do the drawing operations? On the fly or batched? When i did it i believe mine were batch so that i didn't have to keep locking and unlocking the backbuffer.

Quote: "I'll have to learn how to use DLL's, this one interests me."


pretty simple really.

Think of it like this, You have a source file that has functions that are used by many projects. You then compile that into a dll. Those functions that were exported are all available to any program that loads the dll. In DBC you load a dll into memory with the command load dll. To call a function from the dll you use call dll and specify the name of the function (using a string).

Unless the functions were defined with C Linkage( using extern "C") the function names look a little garbled. like this:



So if you want to call a function from a dll open the dll with notepad and search for the name of the function. You will find it. if it's C Linkage then it will just be the name of the function, otherwise you will need to find it in the dll and copy it.

There that simple. lol

Edit:

Oh for creating them, if you know c++ then it's easy. you have to define the calling convention as dllexport like this



New Site! Check it out \/
Latch
17
Years of Service
User Offline
Joined: 23rd Jul 2006
Location:
Posted: 18th Feb 2010 22:20
Quote: "When i did it i believe mine were batch so that i didn't have to keep locking and unlocking the backbuffer."

I guess the backbuffer pointer has the potential to be different every time so I thought it was necessary to lock and unlock it every time you want to write. And if using 3d, the screen is redrawn every iteration so to hold any 2d drawn on it, you have to draw on it every loop.

What's batched?

Enjoy your day.
Caleb1994
15
Years of Service
User Offline
Joined: 10th Oct 2008
Location: The Internet you idiot!
Posted: 19th Feb 2010 01:42 Edited at: 19th Feb 2010 01:46
Quote: "What's batched?"


It means i queued all the drawing operations and upon a call to a 'flush' or a 'draw' function it would draw all of them and clear the queue at the same time. that way you only needed to lock/unlock once (or more if you wanted to) although i'm not sure how it would work with 3D.

The pointer to the backbuffer never changes. How i did it was something like this:




Btw I was doing some testing. It's not the reading from the pointer that is slow. It's the returning a value from a function.

I made a little testing dll and i had a dot function called DBD_Dot (DarkBasic Drawing dot lol) and another called DBD_Dot_return. Of course the second returns a value. Drawing 10000 dots the one with a return value took about 98 ms and the one without took about 10. Btw no i was not assigning the value to a variable.


I have a question. For a line equation. Should this work?

y = mx + b

first find m using the 2 points that were given (y2-y1) / (x2-x1) then find b like this:

b = mx-y

now you have b and m. then go through every y position from the starting y and the ending y, find the x position for that y position and drawing a simple horizontal line from the old x to the new at the current y. like this (if y2 > y1)



but it doesn't work. Any ideas?

My code probly made more sense then when i explained it. hey i didn't say i wanted to teach coding

New Site! Check it out \/
Latch
17
Years of Service
User Offline
Joined: 23rd Jul 2006
Location:
Posted: 19th Feb 2010 03:06 Edited at: 21st Feb 2010 12:05
Quote: "It means i queued all the drawing operations and upon a call to a 'flush' or a 'draw' function it would draw all of them and clear the queue at the same time."

Oh, I see. You can use point, and line, and circle (for example) all together and then have them do their thing on screen at once instead of individual calls between back buffer locks.

Quote: "The pointer to the backbuffer never changes"

If that is the case, then there shouldn't be a need to lock and unlock the backbuffer if synchronization is on except once upon initialization to get it's stats because I think calling a sync reinitializes the drawing. I could have sworn I read somewhere that the pointer could change - maybe I'm thinking of the screen information if the backbuffer isn't locked - tearing and such... Running it in DBC though, it doesn't seem to change - then again, I haven't done any memory intensive stuff while using the backbuffer commands. I guess this is something to test until it gets broke!

Quote: "Btw I was doing some testing. It's not the reading from the pointer that is slow. It's the returning a value from a function."

I would disagree in the sense that reading means using the color information from the back buffer to do something with. Like make an image, or alpha blend, or copy a portion of the screen. In any of these cases, the back buffer color has to be read into something. You don't need to return a value from the dll function for this slowness to be noticed. As an example of the speed difference between assigning a value and reading a value, take a look at this function:



If you compile this as a dll and run it from DBC at 800,600,32 resolution, when value isn't a remark (we're reading from the backbuffer) the time it takes to assign a byte value from the backbuffer (it's the same screen position but the loop runs for the entire size of the screen) for the length of the loop is around 1200 ms on my machine.

If I comment that line and uncomment
*(ptrBackBuffer+pos)=255;
(now we are writing to the backbuffer) compile it and run it in DBC, it takes about 13 ms to get through the loop on my machine. About 100 times faster in this case. So, I would argue that it is the reading from the back buffer (video memory) that is slow - returning the value from the function makes very little difference.

Quote: "I have a question. For a line equation. Should this work?

y = mx + b

"

Why is b even necessary? Don't you just need the slope and your xs and ys? The slope describes the ratio of ys to xs. Which ever absoulte value is greater, x2-x1 or y2-y1, is the number of iterations for the loop. As you move through the loop, the other value only increase by the amount of the slope. So if the length was longer in the y direction, you would loop through y1 to y2. The x values would be y*slope for each position of y. The slope would flip also for which ever axis value is greater. If y > x then m=1/m for example .

And when you finish reading this and say to yourself, "that nutcase latch makes no sense", make it easier on yourself and look up Bressenhams algorithm.

Enjoy your day.
Caleb1994
15
Years of Service
User Offline
Joined: 10th Oct 2008
Location: The Internet you idiot!
Posted: 19th Feb 2010 16:54 Edited at: 19th Feb 2010 16:57
Quote: "Oh, I see. You can use point, and line, and circle (for example) all together and then have them do their thing on screen at once instead of individual calls between back buffer locks."

Exactly.

Quote: "If that is the case, then there shouldn't be a need to lock and unlock the backbuffer if synchronization is on "


No not really. DB isn't drawing the bitmap at that point, but it does weird things. I think the lock backbuffer command is the same as the D3D Surface equivalent(Direct3DSurface9::Lock()/Unlock()) Which according to directx, you are supposed to call before altering the surface.

Quote: "I would disagree in the sense that reading means using the color information from the back buffer to do something with"


Ok well i see your point, but at the same time returning a value does effect the time also. try these two functions(of course repeatedly) and see the difference.



Quote: "And when you finish reading this and say to yourself, "that nutcase latch makes no sense", make it easier on yourself and look up Bressenhams algorithm.
"


Will do!

Edit:

btw the START_EXTERNC and END_EXTERNC are just defines i always use.



New Site! Check it out \/
Latch
17
Years of Service
User Offline
Joined: 23rd Jul 2006
Location:
Posted: 19th Feb 2010 19:45
Quote: "No not really. DB isn't drawing the bitmap at that point, but it does weird things. I think the lock backbuffer command is the same as the D3D Surface equivalent(Direct3DSurface9::Lock()/Unlock()) Which according to directx, you are supposed to call before altering the surface."

Yeah, but DB is going to alter the surface itself based on the commands that are in the loop - 3d,2d etc after the next sync - locking the back buffer so it can draw there without interruption. So sneaking in some direct pokes to the back buffer pointer should just add to the pot. Since we aren't managing the directx portion ourselves, the only reason I can see locking the backbuffer initially is to get the pointer and the pitch. DBC should be managing the locking and the page flipping every sync because it has to draw to the back buffer based on the commands from the interpreter that the user typed in.

It's something I'm gonna try out until it blows up!

Quote: "btw the START_EXTERNC and END_EXTERNC are just defines i always use"

Ok. I'll test that out the return code when I'm back on windows.

Enjoy your day.
Caleb1994
15
Years of Service
User Offline
Joined: 10th Oct 2008
Location: The Internet you idiot!
Posted: 19th Feb 2010 21:39
Quote: "It's something I'm gonna try out until it blows up!
"


I think i did that before... lol I can't remember what i was working on, but i was using either DirectX or SDL and had some pointer mix-ups. Let's just say i ended up drawing red dots all over the screen(not just in the window but overtop of the WHOLE screen. lol. Just another 'be careful with pointers' lesson

Quote: "Ok. I'll test that out the return code when I'm back on windows.
"


Ok Cool.

New Site! Check it out \/
Latch
17
Years of Service
User Offline
Joined: 23rd Jul 2006
Location:
Posted: 20th Feb 2010 05:05 Edited at: 20th Feb 2010 08:22
@Caleb
I tried them out: after 1,000,000 DBC iterations for each, (i.e. returning a value and not returning a value) there was no difference between the two if I didn't assign the returned value to a DBC variable. There was a 50 ms difference when I did. That means there's a loss of about .00005 ms per iteration. That's negligible. For this test, the return value seems to have no significant effect on performance.

So I'll sustain that the slowdown when accessing the backbuffer is from reading video memory, and that writing to it is very fast.

Enjoy your day.
Caleb1994
15
Years of Service
User Offline
Joined: 10th Oct 2008
Location: The Internet you idiot!
Posted: 20th Feb 2010 16:23
Oh ok. That's odd. Idk what my computer was doing when i tested it

New Site! Check it out \/
Kevin Picone
21
Years of Service
User Offline
Joined: 27th Aug 2002
Location: Australia
Posted: 20th Feb 2010 17:23 Edited at: 11th Aug 2010 22:54
The bottle neck is the reading from the video memory. In order to get data the from the backbuffer, the data has be fetched across video memory and returned across the video bus.. Which is SLOW...

Caleb1994
15
Years of Service
User Offline
Joined: 10th Oct 2008
Location: The Internet you idiot!
Posted: 20th Feb 2010 17:45
What about creating a internal surface? as in just allocating enough memory to hold the backbuffer and copy that backbuffer to it (only at certain times when needed). That way for things like alpha blending and stuff you wouldn't be reading from the backbuffer at all, but actually a copy of it.

New Site! Check it out \/
Latch
17
Years of Service
User Offline
Joined: 23rd Jul 2006
Location:
Posted: 21st Feb 2010 12:23
Quote: "What about creating a internal surface? as in just allocating enough memory to hold the backbuffer and copy that backbuffer to it (only at certain times when needed). That way for things like alpha blending and stuff you wouldn't be reading from the backbuffer at all, but actually a copy of it."

It sounds interesting, but wouldn't it be the same situations? Wouldn't you still have to read from a surface that is in video memory that you would want to change? Can you pull off an example?

Along those same lines, could a basic directx app be written in a dll where you can load objects and such and then draw them to the backbuffer that DBC is giving you a pointer to? Since DBC is using direct x 7 perhaps all the tools available in directdraw are available. We just have to write them to the backbuffer. Don't know if it's possible or not but DBC already has a directx surface created ready to be manipulated if we can actually get it's id.

Enjoy your day.
Caleb1994
15
Years of Service
User Offline
Joined: 10th Oct 2008
Location: The Internet you idiot!
Posted: 22nd Feb 2010 01:39
Quote: "It sounds interesting, but wouldn't it be the same situations? Wouldn't you still have to read from a surface that is in video memory that you would want to change? Can you pull off an example?"


It wouldn't be in video memory. i am talking about something like this:


it would then be just like any other memory, exept the same size as the surface. and you could kindof 'flip' the memory or just copy it and clear it.

As far as the DirectX stuff it could work if you could get the D3D Device pointer. Although just letting you know There's no way to alter the pointer to find the pointer to the D3D Surface because to get the pointer to the pixels with d3d you have to call IDirect3DSurface9::GetPrivateData() function and it's not explicitly defined in the class.

New Site! Check it out \/
Latch
17
Years of Service
User Offline
Joined: 23rd Jul 2006
Location:
Posted: 23rd Feb 2010 02:55 Edited at: 23rd Feb 2010 02:57
@Caleb
Alright. Based on your 3d in 2d DBC example, I put together a line function in a dll to draw directly to the backbuffer. It's about 10 times as fast as using the built in DBC line command directly on bitmap 0. I did no optimization to your code. I just ran your code straight but set it up to use the DLL.

So, first try your original code:



Now try the code below with the DLL call. The DLL is attached to the post.



Enjoy your day.

Attachments

Login to view attachments
Caleb1994
15
Years of Service
User Offline
Joined: 10th Oct 2008
Location: The Internet you idiot!
Posted: 23rd Feb 2010 04:44 Edited at: 23rd Feb 2010 05:13
I am putting together a dll as well. I have a backbuffer copy working. it takes around 0.2 seconds to draw 100,000 dots straight to the backbuffer and 0.1 to draw 100,000 to the copy and flip them. So around half the time (although thats only 0.1 second difference lol)

I am working on a alpha blending example to see the speed difference. Thats where the copy will really come in handy.

For the modified 3D in 2D looks great! i get about 20 fps with my original (haha. wasn't going for speed, but for learning ) and hit my cap at 99 ( i didn't uncap it ) with the dll!

Btw it looks like your going in a different root for your dll.

For mine i am doing something like this:



I store it like this:



It looks like your just passing the pointer to it for every call. Just wondering if you had a specific reason? I like to see why someone structures there code in a certain way. I'm not criticizing


________________________________________
I HAVE FOUND A SNAG IN OUR PLAN!!!!!!!!!

The dbc integer cannot hold a fully opaque, fully white color. (argb(255,255,255,255) or 0xFFFFFFFF) because as i stated it's a integer. It ends up as negative 1 because 0xFFFFFFFF is too large.

New Site! Check it out \/
Latch
17
Years of Service
User Offline
Joined: 23rd Jul 2006
Location:
Posted: 23rd Feb 2010 10:01 Edited at: 24th Feb 2010 00:52
Quote: "It looks like your just passing the pointer to it for every call. Just wondering if you had a specific reason? I like to see why someone structures there code in a certain way. I'm not criticizing"

The only thing the DLL in the above example contains is the line function. It's a test DLL put together just to test the communication and also the changeability of the parameters passed. Also when locking the backbuffer, it's not the pointer to the backbuffer that can be volatile (my memory was telling me something was), it's the pitch that can change depending on how d3d is handling the cache and the bit depth of the surface. So, to make sure everything works, for testing, I pass everything all the time. Making a structure and holding the values indefinitely makes a lot of sense, but DBC tends to be just quirky enough that any values it generates itself may not always be the same. DBPro was written as an upgrade for more than 1 reason.

Basically, for the example DLL, I read the pointers in as BYTE pointers and access the memory with pointer arithmetic. I type cast and dereference the values I need. The passing of the pointer to the DLL doesn't take any more time than calling the DLL from DBC. The only slowdown might be from locking the backbuffer and calling the backbuffer functions from DBC.

Quote: "I HAVE FOUND A SNAG IN OUR PLAN!!!!!!!!!

The dbc integer cannot hold a fully opaque, fully white color."

Not exactly. The max screen bytes that hold color in DBC is 3 or 24 bit (I'm pretty sure). Even though the surface may be aligned to 32 bit, the 4th byte will cause a read as a float value/and or negative values. Only write colors up to 255,255,255,0 . And if you are in 16 bit, you'll have to account for pitch and most likely RGB565 color format. For alpha blending, you'd most likely have to write your own routine. That's part of the reason I also pass the pointer to the backbuffer as a BYTE pointer so I can access the individual bytes of r,g and b .

Quote: "it takes around 0.2 seconds to draw 100,000 dots straight to the backbuffer and 0.1 to draw 100,000 to the copy and flip them"

Hmmmmm so that matches what my dots tests yielded. Are you actually flipping the memory by swapping pointers or are you using memcpy?

Enjoy your day.
Kevin Picone
21
Years of Service
User Offline
Joined: 27th Aug 2002
Location: Australia
Posted: 23rd Feb 2010 14:44 Edited at: 11th Aug 2010 22:56
Quote: "The dbc integer cannot hold a fully opaque, fully white color. (argb(255,255,255,255) or 0xFFFFFFFF) because as i stated it's a integer. It ends up as negative 1 because 0xFFFFFFFF is too large."



DarkBasic treats integers as signed! So it'll print -1 for the value $ffffffff.

Caleb1994
15
Years of Service
User Offline
Joined: 10th Oct 2008
Location: The Internet you idiot!
Posted: 23rd Feb 2010 16:08
Quote: "Basically, for the example DLL, I read the pointers in as BYTE pointers and access the memory with pointer arithmetic. I type cast and dereference the values I need. The passing of the pointer to the DLL doesn't take any more time than calling the DLL from DBC. The only slowdown might be from locking the backbuffer and calling the backbuffer functions from DBC."


I didn't mean it was a slowdown lol i just wanted to know.

Quote: "Not exactly. The max screen bytes that hold color in DBC is 3 or 24 bit (I'm pretty sure). Even though the surface may be aligned to 32 bit, the 4th byte will cause a read as a float value/and or negative values. Only write colors up to 255,255,255,0"


Oh i see. Grrrr lol

Quote: "That's part of the reason I also pass the pointer to the backbuffer as a BYTE pointer so I can access the individual bytes of r,g and b ."


I pass it in as void pointer and then cast to was i need. Really any pointer can be cast to anything so it doesn't matter what it comes in as, as long as there is enough space for that data type at that position in memory

Quote: "Hmmmmm so that jives with what my dots tests yielded. Are you actually flipping the memory by swapping pointers or are you using memcpy?"


Sorry. Used the wrong word. I am using memcpy to copy the data from my internal 'surface' to the backbuffer.

New Site! Check it out \/
Latch
17
Years of Service
User Offline
Joined: 23rd Jul 2006
Location:
Posted: 24th Feb 2010 00:37 Edited at: 24th Feb 2010 00:56
Quote: "I didn't mean it was a slowdown lol i just wanted to know.
"

I didn't take it like that, I just thought you'd want to know what I was doing and if I had any reasoning behind it besides hearing myself talk!

Quote: "I pass it in as void pointer and then cast to was i need. Really any pointer can be cast to anything so it doesn't matter what it comes in as, as long as there is enough space for that data type at that position in memory"

Sounds like you have a lot of good ideas with the surfaces, structures and pointer use! But I'm too scared to give up control of my pointer types - and I thought you couldn't dereference a void pointer...

In regards to whatever final dll someone comes up with, if a series of drawing commands in a the dll could be made to replace the DBC native ones, that would speed up any 2d operations in DBC quite a bit. I could even see creating some sprite like controls with priorities and such. Store them in a chunk of memory and blit them to the backbuffer as needed. I've tested lines and dots so far and the drawing of those average 7 to 10 times faster than native DBC - and that's with calling LOCK BACKBUFFER and querying it's stats every iteration. I wonder if creating a sprite like thing would be similarly faster than DBC.

So what started this thread was your question from back in the past, (paraphrasing) "what's the best method to create a drawing dll for DBC".

It may be drawing directly to the back buffer.

Enjoy your day.
Caleb1994
15
Years of Service
User Offline
Joined: 10th Oct 2008
Location: The Internet you idiot!
Posted: 24th Feb 2010 01:09
Quote: "I thought you couldn't dereference a void pointer..."


Nope. You can do it like this:

LPVOID ptr = old_ptr;
DWORD*dwptr = ((DWORD*)(ptr));
ptr[x+y*(pitch/4)] = color;

or

LPVOID ptr = old_ptr;
((DWORD*)(ptr))[x+y*(pitch/4)] = color;

Quote: "It may be drawing directly to the back buffer."


From my testing i would have to disagree. The only problem is after doing the DLL's sync command any text drawn doesn't show up. although your sprite idea would work a lot like what i am doing now.

For the sprite idea, would you want to handle it like dbc does where you have multiple images and you can link it to a sprite number or do you want a sprite to have it's own image?

New Site! Check it out \/
Latch
17
Years of Service
User Offline
Joined: 23rd Jul 2006
Location:
Posted: 24th Feb 2010 02:27
Quote: "From my testing i would have to disagree. The only problem is after doing the DLL's sync command any text drawn doesn't show up. although your sprite idea would work a lot like what i am doing now."

What do you mean? What's a dll's sync command? Everything that is on the screen remains the same. The only thing on the screen that changes is what one adds to it or draws on it. Or are you rewriting the entire backbuffer with your memory swap?

Quote: "For the sprite idea, would you want to handle it like dbc does where you have multiple images and you can link it to a sprite number or do you want a sprite to have it's own image?"

Well, I was thinking that the picture data for the sprite would be stored in an index or array of memory in the dll. The actual image data could be ported over through memblock pointers to images or bitmap screens. Once the sprite is created in memory, it's basically just a block of colored pixels, that block can be blitted onto the backbuffer. It wouldn't be an actual movable object block that is it's own surface, it would basically be a painting onto the backbuffer. Much like the paste image command. So for multiple sprites with the same image, it would just be a pasting of that image block onto the back buffer at multiple locations.

Enjoy your day.
Caleb1994
15
Years of Service
User Offline
Joined: 10th Oct 2008
Location: The Internet you idiot!
Posted: 24th Feb 2010 07:11
Quote: "What's a dll's sync command?"


I mean MY dll's sync function. Where it blits the surface to the backbuffer. After i said that i looked at it some more. The more i look at it i think that it's not very useful to do it like this right now. I think drawing straight to the backbuffer is going to be better. If we get to something where we need to read from the backbuffer then we can think of something like this(or even better maybe ). I think i was complicating things when i didn't need to, which is something i seem to do sometimes. I just get carried away with things that could be done

Quote: "So for multiple sprites with the same image, it would just be a pasting of that image block onto the back buffer at multiple locations."


Sounds good. Just trying to get a feel for what your thinking. Just thinking out loud here, but i am imagining a class.



Just popped into my head. Thought i'd throw it out there

New Site! Check it out \/
Latch
17
Years of Service
User Offline
Joined: 23rd Jul 2006
Location:
Posted: 26th Feb 2010 23:31
I don't use C++ so I don't know what your code above is doing. I hadn't thought of the details of how to do the sprite stuff. I was thinking of using directdraw and using fastblt() or something after loading in the image data from either a memblock or directly from a file. I even wonder if the GDI BitBlt would work. I've used that for screen shots in DBC.

Enjoy your day.
Caleb1994
15
Years of Service
User Offline
Joined: 10th Oct 2008
Location: The Internet you idiot!
Posted: 28th Feb 2010 23:21
I apologize. What do you use to code dlls? jw.

The code above creates a 'structure'. Kind of like types in dbpro. exept with a class you can have private,public, and protected variables and you can have functions. Public will be available to anyone anywhere in the program. Protected. Well i can't remember now. I never use protected, but private is where no one can access it exept the functions in the class.

You can also define 'friend' functions of classes. They can also access private members although they can't just reference them by a name they need a actual variable of that class. unlike member functions for instance the width() function from above which is accessing the w variable.

Don't you need a D3D Device to use DirectDraw? or anything directx? as for BlitBlt. You would need to create a windows bitmap and create a DC for each and then you can select them using there dc's and use BlitBlt, but you do need a DC

New Site! Check it out \/
Latch
17
Years of Service
User Offline
Joined: 23rd Jul 2006
Location:
Posted: 1st Mar 2010 01:40 Edited at: 1st Mar 2010 01:50
Quote: "I apologize. What do you use to code dlls? jw."

C . There aren't classes.

Quote: "Don't you need a D3D Device to use DirectDraw? or anything directx?"

Since DBC is using Directx 7 I believe one would need a pointer to the DirectDraw7 interface. Since the backbuffer is a pointer most likely to a directdraw surface, the interface can probably be derived from there. Or perhaps, a new interface can be created and the old interface queried.

Quote: "as for BlitBlt. You would need to create a windows bitmap and create a DC for each and then you can select them using there dc's and use BlitBlt, but you do need a DC"

Yeah. I've gotten the DC to the actual DBC window and can write directly to it, however, it is replaced almost instantly by direct x swapping the buffers - all kinds of flashing going on (though the text or image are there). If one could obtain the DC to the surface, then there may be stability. Right now it works, but it looks terrible because the screen seems to be overwritten by the back buffer.

Perhaps this is where a private DC would come into play. Is it possible to just blit to the backbuffer, I wonder, from another memory location that's set up the same way without having to use directx to create the surface? It would seem that the backbuffer is just a pixel layout of the screen whose scanlines may differ because of pitch related to bit depth. If the pointer to the backbuffer is actually a directdraw surface, then to create another surface would just mean creating an identical chunk of memory that is the same size as the back buffer. If a DC in this context is the same thing, then blitting from one surface to the other should be straight forward.

Enjoy your day.

Login to post a reply

Server time is: 2024-04-19 10:12:50
Your offset time is: 2024-04-19 10:12:50