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 Professional Discussion / [Advanced Tutorial] Memblocks, Images, and Objects (Illustrated!)

Author
Message
BMacZero
20
Years of Service
User Offline
Joined: 30th Dec 2005
Location: E:/ NA / USA
Posted: 19th Jul 2010 19:55 Edited at: 20th Jul 2010 22:33
Hi, I had some time to kill and realized there are very few tutorials that cover stuff like real-time object manipulation. I hope this helps you understand it .

Memblocks, Images, and Objects
by BMacZero

To those not in the know, memblocks can be downright scary. However, they are invaluable tools for creating and manipulating media in-game, a must-have for many projects.

As their full name, memory blocks, might indicate, memblocks are really just a long line of bytes (a byte being a little block holding a number between 0 and 255 in the computer's memory). Once you learn the significance behind the order of the bytes, manipulating a memblock is no harder than manipulating an array.

Naturally, you can create your own memblocks for storage purposes with the MAKE MEMBLOCK command, but for this tutorial I'll focus on making and manipulating objects and images. You should be able to figure out how to do that on your own with this information, should you need to.

Images

So let's say you've got an image, and you need to modify it in some way during the running of your program. For example, in a Space Invaders game, one would have to dynamically blast a hole in the bunkers whenever they got shot:



You might first try to paste the image into a bitmap, draw on it with the DOT or LINE commands, and then use GET IMAGE to store it as an image again. The problem with this is that GET IMAGE is slow. We can do this much more quickly by making the image into a memblock and manipulating it directly in the memory.

First, you use the MAKE MEMBLOCK FROM IMAGE command to make a memblock with all of the image data in it.

This data is formatted simply. The first four bytes, or one dword, tell the image width. The next dword tells the image height, and the third one gives its color depth. Width and height should be self-explanatory. The Color Depth describes the number of bits of information there are about each pixel in the image. This will generally be a power of two. There are 8 bits in a byte, and four bytes in a dword.

Almost every image you deal with will be a standard RGB image with color depth 32 - one byte each for the Red, Green, Blue, and Alpha components of the pixel (Alpha is the amount of transparency). The following illustration of a color depth 32 image as a memblock may help:



Yes, that's right, the bytes are in reverse order from the RGB configuration you're used to - BGR. Don't get tripped up! The color information is stored pixel-by-pixel, working from the top-left pixel across the first row, then the second row, then the third...all the way to the end. Just like reading this tutorial. It's easy, honest!

As an example of how you would use and manipulate this info, here is a cleaned-up snippet from my Space Invaders code. This is what the code does after it has determined that a bullet has entered the area occupied by one of the bunker sprites.



You might have got from the code above that one of the most annoying parts of working with images in memblocks is figuring out the position of a pixel within the memblock. In my opinion, you'd be right. We're storing 2 dimensions of data in 1 dimension of storage - it's gonna get ugly. Just work carefully and make sure you do it right the first time - it's a pain to debug. Remember that the memblock bytes start at number 0 and end at one less than the memblock's size, because the zero term counts, unlike in arrays.

Get it, got it, good? See if you can make a program that loads an image and allows the user to scribble lines on it with the mouse, using memblocks of course .

Objects

Tired yet? Reading this isn't as much work as writing it, I guess. Well, on to object manipulation! Memblocks for objects are much more complicated in many ways (they're 3-dimensional, so that's to be expected), but also less complicated in some. One of the reasons they are less complicated is that instead of storing data on each and every pixel by location like we have to do with images, we just store the coordinates of each vertex in the object and how they connect. One of the reasons they are more complicated is that there are a lot of different ways this information can be stored. With images, the color depth tells you how many bits deal with each pixel, and that's that. But with objects, each vertex can have coordinates, normals, diffuse colors, and even more. An FVF (flexible vertex format) number tells you how all this is stored (you can read this for more information on different FVF formats, but you won't need to for this tutorial).

Before I proceed, I will point out that while memblock can be used to manipulate objects, they aren't always the best way. Often, you'll want to use the vertexdata commands if you are manipulating an object during the execution of your program. They are faster when simply manipulating, but if you needed to add or remove vertices from a mesh, you would have to create a suitable mesh and add it with ADD MESH TO VERTEXDATA, then manipulate the added vertices so they go where you want - a memblock, however, can easily be copied to one of a different size, and more vertices added.

So, you have an object. You make it into a mesh with MAKE MESH FROM OBJECT, and then make your memblock with MAKE MEMBLOCK FROM MESH (you can't go straight from object to memblock). Most objects you load into DarkBASIC should be FVF 274 (not 338 like the help files say). The memblock data for a mesh with this format looks like this:



Explain, you say. Okay - the first dword in the memblock is the object's FVF. The second dword is the number of bytes of information that belong to each vertex. For example, if each vertex had only its location, each vertex would take up three dwords, or 12 bytes, and this number would be 12. The third dword is the total number of vertices in the mesh.

Let's look at the second dword. For FVF 274, this number should be 32. So, 8 floats or dwords per vertex (a float is 4 bytes, same as a dword, but the object data uses floats instead of dwords for some data because they can store decimals). These happen to be (in order): the float x, y, and z positions of the vertex relative to the object's center, the float x, y, and z components of the normal vector for that vertex, and the float u and v coordinates of the vertex on the object's texture. The normal of the vertex should be thought of as the direction it points - usually away from the object. This is used in calculating lighting. Notes that the u and v coordinates are actually proportions between 0.0 and 1.0, not pixel coordinates. For example, if a vertex had u 0.5 v 0.5, and the object was textured with a 512 by 512 texture, that vertex would lie on the 256,256 pixel on the texture.

How does DBP know which vertices connect to form faces? Every consecutive set of three vertices in the data form a triangle. This means that one vertex may appear many times in the data if it serves as a corner to a number of polygons.

So, another example (this one is from one of my DBP Coding Challenge entries). In this code, I'm using a combination of sine and cosine waves to simulate an ocean on a flat, gridlike mesh (in an ocean wave, each particle actually moves in a circle, not just up and down in a sine pattern).



I didn't follow my own advice in this one, and used memblocks to just manipulate the mesh. I tested it against a similar entry by Kira Vakaan using the vertexdata commands and found them to be far faster. But this is good for teaching purposes.

Questions or comments?

Green Gandalf
VIP Member
21
Years of Service
User Offline
Joined: 3rd Jan 2005
Playing: Malevolence:Sword of Ahkranox, Skyrim, Civ6.
Posted: 19th Jul 2010 20:25
Nice explanation.

Spotted a couple of technical typos:

Quote: "There are four bits in a byte"


Eight?

Quote: "Let's look at the second dword. For FVF 274, this number should be 34."


32 (as in your code snippet)?
BMacZero
20
Years of Service
User Offline
Joined: 30th Dec 2005
Location: E:/ NA / USA
Posted: 20th Jul 2010 01:28
Both fixed

Diggsey
20
Years of Service
User Offline
Joined: 24th Apr 2006
Location: On this web page.
Posted: 20th Jul 2010 03:06
Nice tutorial
One thing:
Quote: "However, the vertexdata commands do not allow you to add or remove vertices from the model - to do this, you will have to use memblocks."


Actually, you can add and remove vertices using the vertexdata commands. You would use 'make object triangle' at the start of your program, and then make a mesh from it. You can delete the object.

Then use 'add mesh to vertexdata' to add data to the vertexdata. To delete data you can use 'delete mesh from vertexdata'.

Even better, if you have IanM's plugins you can call 'make object new' and specify exactly how many indices and how many vertices you want, and then add that to the vertexdata.

[b]
BMacZero
20
Years of Service
User Offline
Joined: 30th Dec 2005
Location: E:/ NA / USA
Posted: 20th Jul 2010 22:27
Heh, I learn more from writing tutorials than anything else . I'll note that, Diggsey.

Adrian
22
Years of Service
User Offline
Joined: 11th Nov 2003
Location: My Living Room
Posted: 22nd Jul 2010 23:54
Interesting. Thanks for posting
Dark Dragon
19
Years of Service
User Offline
Joined: 22nd Jun 2007
Location: In the ring, Kickin\' *donkeybutt*.
Posted: 23rd Jul 2010 19:39
Explained Very well. I like how you broke it down.


Here, have a

Madscientist
16
Years of Service
User Offline
Joined: 23rd Aug 2009
Location: Between a rock and a hard place
Posted: 16th Aug 2010 05:02
Before reading this:
Memblock=Pit of fire

After reading this:
Memblock=Enlightening coding pathway

My computer can render anything no matter the complexity of it in real time.
The memory is enormous. My computer is unique to everyone else’s. What computer do I have?

Fatal Berserker
16
Years of Service
User Offline
Joined: 2nd Jul 2010
Location:
Posted: 22nd Aug 2010 16:26
would memblocks work on 3d objects aswell?

Smoke me a kipper, ill be back for breakfast.
BMacZero
20
Years of Service
User Offline
Joined: 30th Dec 2005
Location: E:/ NA / USA
Posted: 22nd Aug 2010 16:45
Yes, that is what the second half is about.

Fatal Berserker
16
Years of Service
User Offline
Joined: 2nd Jul 2010
Location:
Posted: 22nd Aug 2010 16:46
Quote: "Yes, that is what the second half is about."

Sorry, i should of read before i commented ^^

Smoke me a kipper, ill be back for breakfast.

Login to post a reply

Server time is: 2026-07-23 12:10:42
Your offset time is: 2026-07-23 12:10:42