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.

Dark GDK / custom image clipping

Author
Message
Sephnroth
21
Years of Service
User Offline
Joined: 10th Oct 2002
Location: United Kingdom
Posted: 23rd Feb 2005 14:18
lol - I dont seem to get much luck getting any replies to my questions But I will be strong! Heres another odd one for you.

I wish to be able to perform custom clipping on images. Just like when an image goes part off screen the bit that is off screen gets clipped off and not drawn (I hope!). But I wish to be able to setup drawing regions on the screen, maybe several.

Setting up regions, defining the rectangles for them, keeping track of which image belongs to which region - thats easy enough for me to do myself. But how to actually clip the image.. i dunno >>;

I know I can get a pointer to the dx image surface (or texture surface, whatever the correct terminology is I dunno) for the image so if doing it with directX commands myself is what is required, i'm willing if someone will guide me through it ^^

Note, I tend to paste my images to my own bitmap buffer for several reasons and when im done with all my shinanigans I paste bitmap 2 onto 1 (well, copy, you know what i mean) - so yeah, I dunno if that effects anything.
Some guy I was talking to all of five seconds said something about using directX clipping rectangles. No idea if he knows what hes talking about, but sounds good - anyone know?

Help appreichated ^^ Please? ^^

[07:16:59-pm] « Sephnroth » you were dreaming about lee...
[07:17:13-pm] « Mouse » stfu
[07:17:22-pm] « Mouse » he was hanging himself lol
billy the kid
19
Years of Service
User Offline
Joined: 7th Dec 2004
Location:
Posted: 23rd Feb 2005 18:13 Edited at: 23rd Feb 2005 18:16
Since you say (I think) you can get the actual image data, why not do a crop operation on the image? And I mean do this from scratch. So basically you have your large array in RGBA, BGRA, RGB, or one of the other possible formats. And you just copy the stuff you want to keep into a new image buffer. So then lets say your image is 200x100 and you want to make the image 100x100. Well you just wouldnt copy the last 100 pixel columns in the image. Does that make any sense?

If you want more information on cropping, you should be able to find something on google. I would search for something like "image crop filter" or "image crop operation", otherwise youll either get a lot of results about corn or about how to crop a photo in photoshop. There are also free C++ image APIs you could use too. Also I think Microsoft's GDI+ might be good for this too.

But personally I would just do it from scratch. Because its actually easier in this case, and youll learn something. And Im usually not one to reinvent the wheel. I would much rather rape and pillage others code than to write it myself. But in this case, it might be better.
IanM
Retired Moderator
21
Years of Service
User Offline
Joined: 11th Sep 2002
Location: In my moon base
Posted: 24th Feb 2005 19:59
Clipping rectangles are a part of the obsolete DX7 DirectDraw interface, so I don't believe that they will help you here.

There is a DX9 3D equivalent that may work for you. I have never used it myself, but it doesn't seem complex:
http://msdn.microsoft.com/archive/default.asp?url=/archive/en-us/directx9_c/directx/graphics/programmingguide/fixedfunction/viewportsclipping/viewportsclipping.asp

An alternative method that you are already using (sort of) is to continue pasting your images to a secondary bitmap, then to copy only the rectangles required to your display bitmap.

*** Coming soon - Network Plug-in - Check my site for info ***
For free Plug-ins and source code http://www.matrix1.demon.co.uk
Sephnroth
21
Years of Service
User Offline
Joined: 10th Oct 2002
Location: United Kingdom
Posted: 26th Feb 2005 08:20 Edited at: 26th Feb 2005 08:25
Well I implemented the second method you suggested Ian. It actually worked fine for my initial requirements, but I have since stumbled across some problems with it :/

The first and most immediate problem was that my regions could not overlap. Whenever I make a call to setup a region I create a new bitmap the width and height passed to it and then my own function to handle rendering of sprites checks which region the sprite belongs to and pastes it to the correct bitmap. At the end of everything, i dbCopyBitmap() my regions to my screen buffer and then the normal buffer to screen copy takes place. So of course, whichever region is copied last is the one whos data is shown at a region overlap (even if I didnt dbPasteSprite() to that part, it just copies a black rectangle)

Secondly, any previous region-free operations that have taken place (a normal sprite paste, drawing a line, plotting a pixel etc) obviously went direct to my screen buffer and the copying of regions overwrites those too.

I need to be able to allow sprites to be region free, I REALLY just need to clip them. I foresee the same problem using the viewport directx functions as I imagine that supposing i actually SOMEHOW manage to a) hijack dx and setup my own viewport and b) manage to tell each sprite what viewport it belongs to then simulary the view ports will probably overwrite each other at an overlap.

Is there REALLY no way to clip a sprite? The only alternitive I can come up with is when I render a sprite to make a new bitmap the same size of the sprite (allowing for rotation..), dbPasteSprite into that and then write a function to software blit it to the screen with checks that each pixel is in a region before drawing and which are transparent etc. Much like the first suggestion.
That would mean I wouldnt get any of the speed bonus from hardware blitting and well its going to be disgustingly slow, especially with large sprites. There must be -some- way to do this? Just clip a db sprite T_T

Someone please help me! ;;;;;

[07:16:59-pm] « Sephnroth » you were dreaming about lee...
[07:17:13-pm] « Mouse » stfu
[07:17:22-pm] « Mouse » he was hanging himself lol
Sephnroth
21
Years of Service
User Offline
Joined: 10th Oct 2002
Location: United Kingdom
Posted: 26th Feb 2005 09:36
well, i've been browsing directx help file and I really am grasping at straws. I'm just guessing at all the code im writing and dunno if i make it work wether it will actually do what I want

I've taken a blind guess and got IDirect3DDevice9::UpdateSurface() as the most likely function of use. Its description is:
Copies rectangular subsets of pixels from one surface to another.

It takes two RECT objects to say which pixels to copy to where.

So what i'm intending is if a sprite is set to a region, then to grab its surface pointer, basically make a new image using directx commands and then fill my new image with the old ones pixels but calculate the rect to copy by taking into account the region boundaries, thus clipping it. At least thats the idea >>;

I've been guessing my way through ALL the code I have written so im obviously making a stupid mistake (years of programming experiance and alot of that is c/c++, but i have NEVER used directX before) and im getting a nice crash atm trying to get a pointer to the surface of a darkbasic sprite. Im using alot of internal darksdk commands that arnt documented, so bare with me if im fouling it up stupidly.

The line my program hangs on (some sort of memory leak i think) is: darksprite->GetSurfaceLevel(0, darksurface);
which i was hoping would copy the surface of the db Sprite to my own little surface pointer so i can use updatesurface to read from it.

All my code is attached, its obvious incomplete without any code to do the clipping yet, but you should see where I was trying to take it.

Can anyone explain to me how I can use these commands properly to do what I want? Or is my whole idea of using UpdateSurface() to copy calculated rectangles not going to work because i either miss understood the command completly or im just plain stupid?

Please help me out here, I feel all cold and alone with directX...


Thanks in advance.

[07:16:59-pm] « Sephnroth » you were dreaming about lee...
[07:17:13-pm] « Mouse » stfu
[07:17:22-pm] « Mouse » he was hanging himself lol
Sephnroth
21
Years of Service
User Offline
Joined: 10th Oct 2002
Location: United Kingdom
Posted: 26th Feb 2005 10:03
ok, I fixed that hang thanks to APEX in the irc channel, im sure I will be back with more problems in the future though XD

[07:16:59-pm] « Sephnroth » you were dreaming about lee...
[07:17:13-pm] « Mouse » stfu
[07:17:22-pm] « Mouse » he was hanging himself lol
Sephnroth
21
Years of Service
User Offline
Joined: 10th Oct 2002
Location: United Kingdom
Posted: 26th Feb 2005 13:06 Edited at: 26th Feb 2005 13:12
Ok, me again XD

I think i've made some serious progress. I've tried a million things and learned about all sorts of different parts of directx XD
I have now refined my code and removed all my old experiments to make it easier to read.

Its not working. That is, it compiles fine and when I run it there is no crash, but my sprite isnt displaying. Can anyone tell me why? You can see what i've done with it, I feel like im so close. If I can make the full sprite display like im trying to now then all I have to do is alter the co-ordinates of that rectangle and it will draw a different part of the sprite and walla! custom clipping! Then I will just have to worry about rotating it etc >> lol

Can anyone tell me WHY this isnt displaying? Please help, I feel like im so close and its frustrating to get stuck again XD

See attached source

I suspect that maybe I need to setup some sort of view matrix or something?


EDIT:

Also, I realise this will only draw directly to the screen atm. If someone could explain how I can get this to draw to the current bitmap just like PasteSprite does (i am, after all, basically writing PasteSprite with clipping parameters) then I would be most greatful. I suspect it will involve these found amongst the db global vars:

LPDIRECT3DTEXTURE9 pCurrentBitmapTexture;
LPDIRECT3DSURFACE9 pCurrentBitmapSurface;

[07:16:59-pm] « Sephnroth » you were dreaming about lee...
[07:17:13-pm] « Mouse » stfu
[07:17:22-pm] « Mouse » he was hanging himself lol
billy the kid
19
Years of Service
User Offline
Joined: 7th Dec 2004
Location:
Posted: 27th Feb 2005 03:44
I think you are making this way too complicated if all you want to do is clip (or crop) the images. Im not familiar with all the DG functions for images, sprites, bitmaps, etc but I am familiar with writing my own image operations from scratch. And you say you have several years of experience with C++. So seriously all you need to do is this:

- fopen(image)
- fopen(new image)
- copy pixels you want to keep into new image file buffer
- fclose(image)
- fclose(new image)
- load new image into DG
- use new image for the sprite

Its really not as complicated as you think. The hardest part is parsing the file correctly since the format depends on the type of file. Now an alternative to this using DG functions is using the memblock functions. And for efficiency you could preload all the images you want to use into a buffer. And then you crop that buffer and save to a new image. This will reduce the number of file operations you have to do while in the game loop.

Does that make sense? Do I understand your problem correctly that all you really want to do is crop the images in an easy and efficient way?
Sephnroth
21
Years of Service
User Offline
Joined: 10th Oct 2002
Location: United Kingdom
Posted: 27th Feb 2005 04:33
I do wish to just crop images in an easy and effcient way yes basically.

I understand what your saying but it sounds far too slow to me. There could be hundreads, nay, thousands of sprites on screen at one time in any particular region. Loading the file that many times sounds disgustingly slow just to clip it, it would have to be done to hundreads of sprites every Sync!

the memblock idea sounds more acceptable, but even those usually end up too slow for me when im doing any significant amount of operations per frame :/ The reason for using direct directly is the api is FAST. I'm quite upset that dbp doesnt support this kind of feature from the start tbh :/ All the data is already loaded by dbp, directx has functions for controling the data - having to copy data into a memblock or even load it again from a file is just, ungh, disgusting :/ Its not effcient use of data, duplication should always be avoided whenever possiable --;

[07:16:59-pm] « Sephnroth » you were dreaming about lee...
[07:17:13-pm] « Mouse » stfu
[07:17:22-pm] « Mouse » he was hanging himself lol
billy the kid
19
Years of Service
User Offline
Joined: 7th Dec 2004
Location:
Posted: 27th Feb 2005 05:55 Edited at: 27th Feb 2005 06:01
Oh I see, its super efficiency you are looking for with 100s of sprites. Was thinking just needed it for a few images. Alright how about this instead:

An image is a texture correct? So why not manipulate the texture coordinates of the sprite? By doing that you can specifically say how much of the texture is shown. I will attempt to explain how it works, but I may make a mistake as I have not done this in a long time. Just a warning, nevertheless the basic idea is correct.

Your sprite has 4 vertex coordinates, call them P0, P1, P2, P3. And the texture coordinates U,V range from 0 to 1. And then you map the texture coordinates onto the vertex coordinates.

So lets say you want the full texture to be shown, but no repeating. The mapping would be:

P0 - U = 0, V = 0
P1 - U = 0, V = 1
P2 - U = 1, V = 1
P3 - U = 1, V = 0

Do you see what this does? So the bottom-left corner of the texture is mapped to P0, the top-left is mapped to P1, top-right to P2, and bottom-right mapped to P3. And this will stretch the image over the sprite without any visible stretching or repeating. This is probably the default setting in DG.

Now lets say you only want the bottom-left quarter of the texture displayed, the mapping would be:

P0 - U = 0, V = 0
P1 - U = 0, V = 0.5
P2 - U = 0.5, V = 0.5
P3 - U = 0.5, V = 0

And lets say I wanted to have the texture repeat or stretch depending on setting, this would be a possible mapping:

P0 - U = 0, V = 0
P1 - U = 0, V = 10
P2 - U = 10, V = 10
P3 - U = 10, V = 0

Do you understand? This is the fastest way I can think of and DG has a function to modify the U,V coordinates of the sprite. You will probably have to play with the mapping as I dont know which corner DG specifies as 0,0. You will also have to scale the sprite too in such a way that it isnt noticeable you are changing the texture mapping.

The correct function is (wrong in docs):
void dbSetSpriteTextureCoordinates(int iSprite, int iVertex, float fU, float fV)

Also you could look into dbOffsetSprite() which seems to do a similar thing except it actually changes where the image is drawn in relation to the position of the sprite. And this might be better for you because there is no scaling of the image like there is when messing with the U,V values.
Sephnroth
21
Years of Service
User Offline
Joined: 10th Oct 2002
Location: United Kingdom
Posted: 27th Feb 2005 06:01
this idea looks interesting. But I would have to figure out how to convert x/y ints into u/v co-ordinates. Any pointers on this?

Example, I know the x/y of the sprite and its width/height. I know the region data and i could say clipx = x - region.x; if it was out the region (or simular, im writing whilst standing atm im tidying my room so this is hurried XD but yeah you get the idea) and i could then say ok, the sprite has gone ClipX pixels too far so i need to clip off the number of pixels from the left side of the sprite that are in ClipX - how would i use the pixel value in ClipX to know how to edit the u/v?

[07:16:59-pm] « Sephnroth » you were dreaming about lee...
[07:17:13-pm] « Mouse » stfu
[07:17:22-pm] « Mouse » he was hanging himself lol
billy the kid
19
Years of Service
User Offline
Joined: 7th Dec 2004
Location:
Posted: 27th Feb 2005 06:19
Well the default mapping is:
P0 - U = 0, V = 0
P1 - U = 0, V = 1
P2 - U = 1, V = 1
P3 - U = 1, V = 0

And like I said I dont know which point is mapped to which texture coordinate in DG, youll have to play with that. But no matter what the x,y coordinate of the point is, it is always mapped to the same texture coordinate. So the simpliest way I can think of to doing the mapping based on how much of the sprite should be visible is this:

You calculate the percentage of what is visible in the X direction and in the Y direction. So then lets say for example the first 20% of the sprite is not visible in the x direction, next 60% is visible in the x direction, and last 20% is not visible in the x direction. And 100% in the y direction is visible. So your mapping for the texture coordinates would be:

P0 - U = 0.2, V = 0
P1 - U = 0.2, V = 1
P2 - U = 0.8, V = 1
P3 - U = 0.8, V = 0

Does that make sense? And again it doesnt really matter the x,y coordinates. All that matters is the percentage that should be visible. Though you need the x,y coordinates to calculate the percentage. And again like I said you might need to scale the sprite itself too. Just so it isnt obvious you are changing the resolution of the texture, which is what you are doing by messing with the U,V values.

For now just get the U,V stuff working and I can help you with the sprite scale mapping when you are done with that, if you want. And thats if you go down this path. But I really think its probably the fastest and one of the easier ways to do it.
Sephnroth
21
Years of Service
User Offline
Joined: 10th Oct 2002
Location: United Kingdom
Posted: 27th Feb 2005 06:59
well 0 appears to be top left, 1 top right, 2 bottom right, etc.

But i cant tell how you are supposed to do this.. it doesnt matter what i pass to the command the sprite is distorted if i call it at all. i tried passing 1.0 to vertex 2 and a quater of it appears to disapear, i pass 0.0 and it ends up streched.. *confused* XD

but the command appears to work. Unless its bugged.

[07:16:59-pm] « Sephnroth » you were dreaming about lee...
[07:17:13-pm] « Mouse » stfu
[07:17:22-pm] « Mouse » he was hanging himself lol
billy the kid
19
Years of Service
User Offline
Joined: 7th Dec 2004
Location:
Posted: 27th Feb 2005 07:11 Edited at: 27th Feb 2005 07:15
Alright I messed with it and the mapping is:

0 - top-left
1 - top-right
2 - bottom-left
3 - bottom-right

It has to be one of the goofier mappings Ive seen but anyway. Try this code, uncomment the code to see only the top-left quarter of the texture appear.



That image is in the example media that comes with DGSDK. I use it cause you can easily tell that you have changed the UVs.
Sephnroth
21
Years of Service
User Offline
Joined: 10th Oct 2002
Location: United Kingdom
Posted: 27th Feb 2005 07:45
oh I see now, then you half the size so it looks like its just been quatered.. cunning! Its so dirty and cheap, but I love it XD

ok. If I write code to calculate how much % has gone over the boundary for the left, top, right and bottom, can you show me what code I would use to use those values to clip? I expect the size will need to be calculated off them too.

btw - I really appreichate this input, im not used to ppl replying to my posts, thanks tons

[07:16:59-pm] « Sephnroth » you were dreaming about lee...
[07:17:13-pm] « Mouse » stfu
[07:17:22-pm] « Mouse » he was hanging himself lol
billy the kid
19
Years of Service
User Offline
Joined: 7th Dec 2004
Location:
Posted: 27th Feb 2005 07:49
Yeah I can help you with the code, but write the code you know how to do first. And glad to help.
Sephnroth
21
Years of Service
User Offline
Joined: 10th Oct 2002
Location: United Kingdom
Posted: 27th Feb 2005 08:50
ok thanks ^^ im off out now (yes.. at 1am.. my friends are odd) I will write the code either when i get in (im a night owl coder) or tomorrow. check the forums tomorrow for it Again, thankyou ^^

[07:16:59-pm] « Sephnroth » you were dreaming about lee...
[07:17:13-pm] « Mouse » stfu
[07:17:22-pm] « Mouse » he was hanging himself lol
Sephnroth
21
Years of Service
User Offline
Joined: 10th Oct 2002
Location: United Kingdom
Posted: 8th Mar 2005 18:21
hi
sorry for the long time since my last reply - i became ill :/ Sucks to be me oh well XD

Anyway, i was about to finally sit down and write the relitivly simple code to detect how much % in what direction needed clipping and i suddenly realised that things could possiably get trick when the sprite is rotated. Now it will make my life harder calculating the percentage when rotated (rather than just x - w/2 etc) but i think i CAN because i've done simular point calculations before for a tile based game (where i calculated each corner point of a sprite taking into account rotations to check for tile collision XD) but what i want to know is do you know how to adjust the UV's even taking into account rotation? Because i sure as hell dont If you dont then I may be wasting my time :/

[07:16:59-pm] « Sephnroth » you were dreaming about lee...
[07:17:13-pm] « Mouse » stfu
[07:17:22-pm] « Mouse » he was hanging himself lol
billy the kid
19
Years of Service
User Offline
Joined: 7th Dec 2004
Location:
Posted: 9th Mar 2005 00:24
I think you are missing the main point about UV coordinates. That is no matter the position, rotation, scale of an object, the UV coordinates are always the same. So that means if P0 is mapped to UV(0,0), P0 is ALWAYS mapped to UV(0,0) no matter the position, rotation, scale of the object. Unless of course you change the mapping for P0. So essentially all the math is the same for UV coordinates whether you are changing position, rotation, or scale. Now yes there are differences when you take into account rotation, but they are minor. And although I would have to sit down and figure it out, it shouldnt be too big a pain.

My suggestion is to get the whole system working without rotation and then we will go from there.
Sephnroth
21
Years of Service
User Offline
Joined: 10th Oct 2002
Location: United Kingdom
Posted: 9th Mar 2005 01:50
Righto, we'll do that. I'll have some code for you tomorrow, I wont attempt to write any right now as i've been awake 23 hours already ><; I hate missing nights of sleep lol

But tomorrow, I promise

[07:16:59-pm] « Sephnroth » you were dreaming about lee...
[07:17:13-pm] « Mouse » stfu
[07:17:22-pm] « Mouse » he was hanging himself lol
Sephnroth
21
Years of Service
User Offline
Joined: 10th Oct 2002
Location: United Kingdom
Posted: 18th Mar 2005 23:57
SORRY!

So sorry it took so long man!
I have been all over the place lately x.x So many things going on over here, people giving birth left right and center - jobs to do and blah blah, you know how it is

Anyway I finally got around to writing the code. Theres a problem with it though.. the percentages it calculates are always 0 X_X I think its going something to do with float/int conversion, either that or im doing something supremly stupid and wrong (likely)

Apart from that it works perfect, tells you how many pixels over the region the sprite is etc. Everything you want is in the render_sprite function, but i've included the whole thing for easy testing. just replace tank0r.bmp with whatever (for me is ths 32x64 bitmap of a cartoon tank) to run it.

Any ideas on how to fix the percentage calculation? and if you do then its over to you for the UV magic ^^ I commented the point where the uv clipping would happen ^^

Thanks much bro, looking forward to your response - see attached source.

[07:16:59-pm] « Sephnroth » you were dreaming about lee...
[07:17:13-pm] « Mouse » stfu
[07:17:22-pm] « Mouse » he was hanging himself lol
Sephnroth
21
Years of Service
User Offline
Joined: 10th Oct 2002
Location: United Kingdom
Posted: 18th Mar 2005 23:59
incidently, lc = left clip, rc = right clip, tc = top clip, bc = bottom clip.

lcp = left clip percentage, and so on.

[07:16:59-pm] « Sephnroth » you were dreaming about lee...
[07:17:13-pm] « Mouse » stfu
[07:17:22-pm] « Mouse » he was hanging himself lol
billy the kid
19
Years of Service
User Offline
Joined: 7th Dec 2004
Location:
Posted: 19th Mar 2005 00:35
Cool. This post is just to say I have seen it and will take a look at it. But like you I am very busy also. So dont expect an immediate response. I should be able to give you some feedback next week some time and possibly this weekend.
Sephnroth
21
Years of Service
User Offline
Joined: 10th Oct 2002
Location: United Kingdom
Posted: 25th Mar 2005 02:46
just to say I did read this when you replied and am eagerly looking forward to your response when you have the time to write it ^^

[07:16:59-pm] « Sephnroth » you were dreaming about lee...
[07:17:13-pm] « Mouse » stfu
[07:17:22-pm] « Mouse » he was hanging himself lol
Sephnroth
21
Years of Service
User Offline
Joined: 10th Oct 2002
Location: United Kingdom
Posted: 7th Apr 2005 10:41
bump.

Dont rush yourself if you are really busy billy, but I am getting a bit desperate for this now

[07:16:59-pm] « Sephnroth » you were dreaming about lee...
[07:17:13-pm] « Mouse » stfu
[07:17:22-pm] « Mouse » he was hanging himself lol
billy the kid
19
Years of Service
User Offline
Joined: 7th Dec 2004
Location:
Posted: 7th Apr 2005 10:52
Oops! I completely forgot, sorry. I cant look at it till this weekend however I will get to it then. Ill even put it on my calendar. Sorry man.
billy the kid
19
Years of Service
User Offline
Joined: 7th Dec 2004
Location:
Posted: 11th Apr 2005 04:41
1) Can you send me the tank image?

2) I think before I go to the trouble of doing the U,V stuff you need to make sure everything else is working properly. And the reason all your calculations are zero is because width and height are always zero. So I have no idea what you are doing with the memblock stuff but it isnt working. At least not with wall.jpg that comes with DGSDK.

3) Maybe we should keep this up through email so I dont forget again.

Login to post a reply

Server time is: 2024-03-29 12:47:07
Your offset time is: 2024-03-29 12:47:07