Canvas or Image Shift

BlitzMax Forums/BlitzMax Programming/Canvas or Image Shift

Tyler(Posted 2006) [#1]
Hello everyone,
I'm working on a tile-map creation program and I'm wondering what the best way to setup the canvas would be. I read that the image buffer isn't in BMax, so what's the point of creating a new image if you can't write to it? The method I was using before was to create an image, write all my info to it, then display that image on the canvas, then shift the image with DrawImageRect using the slider bars for input. Is there any similar process I can follow for what I'll need?

Thanks in advance,
-Tyler

Edit: Tile-map creation program isn't a good description. I'm trying to make a DnD map program that uses tiles for some parts, photoshop-like painting ability for others, and free-range tokens, all on different layers.


FlameDuck(Posted 2006) [#2]
Use the same method you use in your game. Infact you can use the exact same code if you go about it a bit cleverly.


Tyler(Posted 2006) [#3]
Hmm, if I could use the exact same code, I wouldn't have to go about it cleverly, lol. I could go about it literally. Could you explain what you meant by that? Thanks.

Edit: Also, I have to note, that when I create my image, it's all virtual until the users hits the save button. There is no file on the harddrive to load until then.

Edit(x2): I need this to run in real-time. From what I'm reading the only methods to do this are slow and unconventional. Shame on you BRL! Is this something they're going to change ever?


Tyler(Posted 2006) [#4]
Gee crimminy crap, I've read through what has to be fifteen million posts on people having problems with the change to the way the buffers are setup (now non-existant) Nearly every one of which trails off and doesn't get answered completely, and most assume you know exactly how the Pixmaps work and how to achieve what you want by playing hop-scotch with the TImage and TPixmap. Can't BRL ease our pain and suffering and just add a blasted imagebuffer imitation?

Anyone want to help a brother out and aim me towards a good Pixmap tutorial? I'm not even sure if it's what I need to achieve my goal, but the other posts I've found so far have been little to no help.

Edit: Breakthrough?! I think I need to load all my images up as Pixmaps, draw them to one large pixmap (depending on the users size input it could be from 1 x 1 inch [72 x 72 pixels] to 40+ inches on either side) then convert that to an image ... and then display that on a canvas. I've got no clue how, but dern it, I'll find out. Any help would be great, thanks!

Edit(x2): Still no good :( Pixmap loading of my PNG file produces a horrendous blocky / psychadelic image for images with Alpha channels. BMax doesn't want me to succeed.


tonyg(Posted 2006) [#5]
Mi might have missed something but...
If it's a tilemap editor why not display your map in tiles rather than copy to a single image?


Tyler(Posted 2006) [#6]
Well, Tilemap editing is one capability, but it's a composite of many efforts. For instance, The base texture is a single image that the user can edit with different terrain styles and brushes (painting on grass, dirt, river, etc), so it's not tile-based in that respects, and there are tokens that are free-moving too (not restrained by the 72 x 72 pixel snapping)

Then, when they're down, they can export the entire thing as a jpg, png, tga, whatever.


tonyg(Posted 2006) [#7]
It still sounds like you talking about a 'normal' Tilemap Editor with, possibly, different layers and image blending/fringing.
The ability to save the map as a single png/jpg is not unusual.


Tyler(Posted 2006) [#8]
Right, I guess. I still don't know what BMax functionality is required to achieve it, though. Tiles are involved, but that's certainly not the bulk of it, and I need the ability to shift the potentially large image around on a canvas with sliders (which I can figure out quickly, if I knew how to get my elements composited properly) Forgive me if I'm misunderstanding a particular direction, but the end concept may be so completely different that the original concept I've pulled from BlitzPlus.

I took a look at the Render 2 Texture module by Indiepath, my questions are, could it handle a 2880 x 2880 image or higher (if my users make a 40 x 40+ inch map), and is it good enough for real-time? I'm looking up how to get it to read as a module now, but I'm sure that's around here somewhere :D

Thanks!


tonyg(Posted 2006) [#9]
Don't shift the large image around. Don't even have a large image. Have an arrray of tiles and only draw those which would be displayed in the canvas. When you move the slider simply take the input to adjust a 'start from' value and draw the tiles from there.
I really must be missing something though.
Why, exactly, do you need a large image?


Tyler(Posted 2006) [#10]
Because I'll have what amounts to a (very much not tiled) watered down version of Photoshop. User pics a brush, and a tile, then paints freehand all over the map. So I need the ability to write to a larger-than-tile image file, or try to scrounge together some kind of tile-by-tile editing that is transparent to the user, but seems to have the same effect as a larger image, since that seems to be the only way to do it.

Although, I don't see that working at all, because the brush size can change to be quite large, then it would effect a larger area than one tile.


Tyler(Posted 2006) [#11]
τΏτ I think I understand now. I could make detail layers that are full of the tiled image (overlayed on top of the others), and perhaps edit the alpha pixels of each tile as the user paints to produce the same results? Although, I'm still not sure how to output all those pieces as one large saved image.


Dreamora(Posted 2006) [#12]
Output: That will be the real fun although extremely easy:

Create pixmap with the needed size.
for all image do
lockimage
read all pixel data and copy to above created pixmap
unlock image

savepixmap

easy ... but will take its time to perform the operations.

If you are willing to use an even slower solution, you could even use this pixmap directly and always draw that one to the screen. Then no 3D texture restriction etc applies but you have to manually write the color data (not as worse as it sounds, just a little "offset" math excercise)


tonyg(Posted 2006) [#13]
... or use pixmap.paste?


Tyler(Posted 2006) [#14]
:) Thank you Dreamora! When you say "for all image do", do you mean i have to cycle through all the images that are placed (level by level), read pixel data for it, copy the pixel data to the segment of pixmap that corresponds to the tile, then go to the next segment, do the same until finished?

How is this process complicated by PNG files that use alpha? Whenever I tried to load a PNG file as a pixmap and display it, the displayed image went AWOL if it had an alpha channel.

Edit: Also, I think I hit another snag. What am I to do with the free-placed tokens that aren't restricted by the tiling snap? These can be selected by clicking on them, dragged anywhere the user wants, and they have to be drawn correctly as the scroll-trackbar moves.


Tyler(Posted 2006) [#15]
Also, thank you Tonyg. The support has got be fiddling around in the right direction.


Tyler(Posted 2006) [#16]
I'm starting to wonder whether I should just can this BMax project. It seems next to impossible to do without making the users wait forever for results, having complicated work-arounds, and sacrificing too much in the way of functionality. Overall I'm impressed with BMax, but the lack of functionality in this particular area is discouraging since it more or less makes my purchase useless.


Dreamora(Posted 2006) [#17]
BM is 2D in 3D, it does not have normal 2D.

For that reason it is just hard to use for pure 2D and not that recommended as the most "usefull" way to do so is pixmaps, which are several times slower than images.

For doing something like a drawing app, there are ways to do as well. (as mentioned, using 1 pixmap of the desired size is one possibility and then simply copy the image to the backbuffer)


Tyler(Posted 2006) [#18]
Thanks for the reply, Dreamora. When you say copy the image to the backbuffer, something like that wouldn't work in a windowed environment (on a canvas), would it?

I apologize for being at my wits end :) It's a frustrating ordeal.


Dreamora(Posted 2006) [#19]
Pixmap to Backbuffer, not image (image are not usefull for that operation)

By copy I mean a simple draw of the pixmap. As pixmap draw actually does nothing else then copy the pixeldata to the backbuffer this works on canvas as on fullscreen.


Tyler(Posted 2006) [#20]
Any tips on loading an alpha PNG as pixmap? This is the only thing standing between me and victory, lol.

I'll try this out now and report back. Thank you!


Tyler(Posted 2006) [#21]
I can't figure out why the TPixmap "paste" method isn't working, because the documentation for it resembles clothing's equivalent to a thong. I tried looking up TPixmap on the BMax wiki, and the most pertanent information of all time came to light. I can buy aciphex, check out it's side effects, get a discount, even find some adderall. Just peachy.

My current usage is mapImg.paste (gridImg, 0, 0) where mapImg is a pixmap that I've created to proper size, and gridImg is the masked grid loaded as a pixmap.


Yan(Posted 2006) [#22]
Do you mean drawing them with alpha (as the alpha channel *is* loaded)?

Load the pixmap into an image and draw the image...
Strict

Graphics 640, 480, 32

Local pmap:TPixmap = LoadPixmap(getenv_("BMXPATH") + "\samples\digesteroids\graphics\digestive.png") 
Local img:TImage = LoadImage(pmap)

SetBlend ALPHABLEND

DrawPixmap pmap, 100, 100
DrawImage img, 100, 300
Flip

WaitKey()

End



Tyler(Posted 2006) [#23]
For instance, this is what a pixmap produces when the PNG has alpha. As opposed to the regular image, which is displayed below it (using your same code, but my images)

Is it going to look like that when I paste the pixmap over to another pixmap? Or will all that ugly go away when I convert it to an image to be drawn to the screen?




Yan(Posted 2006) [#24]
Does this help with the pasting ('not working', is a bit vague)...
Strict

Graphics 640, 480, 32

Local pmap1:TPixmap = LoadPixmap(getenv_("BMXPATH") + "\samples\digesteroids\graphics\digestive.png") 
Local pmap2:TPixmap = LoadPixmap(getenv_("BMXPATH") + "\samples\digesteroids\graphics\sparkle.png")

pmap1.paste(pmap2, (pmap1.width - pmap2.width) / 2, (pmap1.height - pmap2.height) / 2)

DrawPixmap pmap1, 100, 100
Flip

WaitKey()

End


??

[edit]
LOL...We posted at the same time...again! :o)
[/edit]


Tyler(Posted 2006) [#25]
Thank you for an example! That's what I needed, since my results weren't showing properly, "not working" is the best I could describe it as, lol. And without an example to test my code again, I had no clue why or how to tell anyone. Again, thank you!


Yan(Posted 2006) [#26]
No problem, I wasn't sure if you were just referring to the lack of alpha or not.

Which brings me to...

Is it going to look like that when I paste the pixmap over to another pixmap?
I'm afraid so. Pixmap operations do not respect the alpha channel (although they preserve it). If you want to blit pixmaps with alpha, you'll have to create your own routines (or use a render to texture routine).


Tyler(Posted 2006) [#27]
And that routine (if I were to make it) would end up being entirely too slow for real-time use, right?


Yan(Posted 2006) [#28]
I'm by no means an expert on this stuff, but I'd have to say, not necessarily. All pixmap operations are carried out in system memory, and so, should be pretty fast. The relatively slow part of the process is when the pixmap is transferred to the video card as a texture. So, as long as you can keep the transfers down to a minimum, you may be alright. It really depends on just how *much* data you're gonna be shifting around each frame.

All I can suggest is, suck it and see. :o)


Dreamora(Posted 2006) [#29]
I think you should try to implement a hybrid system.

One that does such "image application" stuff on pixmap, but the actual tile map editor part (which is the reason you started this thread) with images.

Because for maps in realtime, images and thus full tile map is needed anyway, you won't be able to use pixmap for realtime if you only use pixmaps.
You might use it for some minor parts but the large part that is drawn must be images.


impixi(Posted 2006) [#30]
I'm encountering similiar issues with pixmaps vs images vs alpha vs scrolling.

My attempts to implement an 'area map' that utilises an alpha-based, pixel-based 'fog of war' effect have ended poorly, mainly because TImage pixels cannot be manipulated directly. I have to use a TPixmap, alter every pixel, and then 'load' it into a TImage for every render pass. For the scrolling effect I modify the viewport based on the player's position, because using TPixmaps for scrolling proved far too slow. Here's some rough sample code:



The visual results are what I wanted to achieve, but the performance is poor (though less so when not compiled in 'debug' mode).

In light of this, I have to use a less pleasing visual workaround, but the performance is far better because the code only renders TImages and rectangles. Example:



Hopefully my post has not been too off-topic...

I suppose the lesson here is you will need to re-think/compromise your designs to workaround BlitzMax's limitations and exploit its strenths. However, this is true for all computer languages.


Tyler(Posted 2006) [#31]
I appreciate the help, I'll fiddle around with it a little and see what I can figure out. The real moral of the story is don't build a 2D system with 3D and leave out the 2D, but I couldn't do it in the first place, so I guess I can't gripe too much.


Tyler(Posted 2006) [#32]
I think I found a better solution. I'll hold tight and wait for the feature of simulated ImageBuffer to be added, however long that might take, but it's a fairly commonly asked / griped about requirement, so I have confidence it'll be dealt with accordingly. Thanks for all the help guys (or gals ... but since I don't know any female programmers, I'll assume guys)