Sign in to follow this  
nlraley

Trying to Create a Background where the user can click and drag and change the view

Recommended Posts

Okay, I've been going through the tutorials and have finally been able to:
Create and Initialize Direct3D
Create and Initialize a Direct3D Device
Create a Sprite
Load Multiple Textures from Files
Load Textures into Sprite
Load Sprites onto the Map

Now, I have a background full of 256x256 tiles( 1024x512 in 2D). My question is this. Is it possible to create a background beyond my 1024x512 window so that when the user drags, it changes the position to the new viewable area? If so how would I go about creating and displaying this background that would be different from what I have done thus far.

I set the position of the Sprite when I call the draw, can I pass negative positions to this and have the view port, the viewable area to the user, change the perspective as they drag? I only need to work in 2D.

I want something like this:

**************************************************************
* *
* *
* *
* *************************** *
* * * *
* * Viewable Area * *
* * * *
* * * *
* * * *
* *************************** *
* *
* Loaded but Not Viewable Area *
* *
* *
**************************************************************


And when they drag to show:

**************************************************************
* *
* *************************** *
* * * *
* * Viewable Area * *
* * * *
* * * *
* * * *
* *************************** *
* *
* Loaded but Not Viewable Area *
* *
* *
* *
* *
**************************************************************


Does that make sense? What would I have to set up to do this?

Share this post


Link to post
Share on other sites
You should be able to pass in position coordinates that are outside the viewable area; I believe they will just be clipped away. So you would create a coordinate that represents the viewer's position, and just subtract that from each sprite coordinate.

So instead of
sprite.Draw(spritePosition);
You would do
sprite.Draw(spritePosition - viewerPosition);
Hope that helps.

Share this post


Link to post
Share on other sites
Plan A. Draw the items directly using a culling that will scan a 2D rectangle in your grid. Triangles can be outside of the screen area but you should avoid drawing things that aren't visible and too large triangles causes rounding errors.

Plan B. If you have many alpha filtered decals on top of each other and don't need much area for the level, render the background to a texture and draw the texture on a quad with the texture coordinates generated by input from the global constant buffer.

I have rendered deep bump mapping with specular dynamic light in over 33 megapixels downsampled to the low resolution "Full HD" with about 50 frames per second. There is a limit at 8192x8192 in DirectX 11 as I discovered when trying to get a high resolution.

Share this post


Link to post
Share on other sites
assuming that four tiles covers the viewable area, just draw the appropriate four tiles as quads/triangles with textures together with an offset that makes

Four quads with "viewport" in top left corner (offset=0,0)
*******************
* 1* | 2*
* * | *
* * | *
*******************
* 3* | 4*
*--------*----+ *
* * *
*******************

Same four quads but viewable area move over a notch (offset: 2,3):
*******************
* 1* 2*
* +-----*------+ *
* | * | *
*******************
* | 3* |4*
* | * | *
* +-----*------+ *
*******************

Draw different quads if you scroll too far away:
XXXXXXXXX*******************
X 1* 2* 5*
X * +-----*------+ *
X * | * | *
XXXXXXXXX*******************
X 3* | 4* |6*
X * | * | *
X * +-----*------+ *
XXXXXXXXX*******************


This technique works for any tiles size actually. You just have to draw all the tiles that actually touch the screen and don't attempt to draw the others.

Share this post


Link to post
Share on other sites
First of all, how do you provide the capability for them to scroll within the window? Right now its drawing the tiles in a window, but I have no scrolling capabilities to move to the other view points, I can increase the size which stretches the tiles or decrease it which cuts out the tiles not in view, but I can't "drag and move" my point of view.

Secondly, even though I was able to draw a triangle, and a quad, I was never able to get the quad to load a texture for some reason. It would draw the quad but never place the texture in it. I had other posts on here where I kept trying and was asking for advice, but was never pointed to what I was doing wrong with it and in the end the only way I was able to get a tile in there was by using the sprite and setting the coordinates for the sprite.

Finally, I know I can set a center and position of the sprite. So say I only need the right 200 pixels of my tile.

I could set the center to the top left (0,0), and the position to (-56, 0)? Or would the correct way to do this be set the center to (56, 0) and the position to (0,0), assuming the tile belonged in the top left corner?

To go with that, I guess if I used managed mode I can "pre-load" all the tiles, using system memory and page file, thus reducing fetch time, and it just automatically copies the tile to video memory only when I display it?

* If you need to see how I am drawing them further I can provide code samples here or source if someone would even like to look at it that way.

Share this post


Link to post
Share on other sites
So what, use my sprites to create a viewable area 2x the size of what's viewable and "set the camera position" by setting the tile positions to adjust for the camera adjustment?

Thing is I don't have 1 image I am working with, I have however many tiles it takes to fill up my view, which is at the minimum 6 but can be quite a bit more than that. How would I do this? Do the adjustment for each tile? Or should I load the sprites into a single texture, 2x the size of the viewable area, and adjust the position of the single texture?

Am I making sense?

Share this post


Link to post
Share on other sites
So is there any way to implement a drag and shift? Or do I just need to capture the mouse down event, check if its in map range, and then start adjusting the tile positions accordingly?

Share this post


Link to post
Share on other sites
Quote:
Original post by nlraley
So is there any way to implement a drag and shift? Or do I just need to capture the mouse down event, check if its in map range, and then start adjusting the tile positions accordingly?


Pseudo code:

Mouse down:
Drag = true
LastX = MouseX
LastY = MouseY

Mouse up:
Drag = false

Mouse move:
if (Drag) {
CameraX = CameraX + (LastX - MouseX)
CameraY = CameraY + (LastY - MouseY)
LastX = MouseX
LastY = MouseY
}




You can fill the outside of the level with a default tile so that you can move the camera outside of the active area.

Share this post


Link to post
Share on other sites
That could be done simpler...


RECT r;
r = ScreenSize; //RECT structure filled with the screensize

//Render the background
DrawBackground();

//Set to the region we want to render
r.left=20;
r.top=20;
r.right=180;
r.bottom=180;
//Pass to D3D
D3DDevice->SetScissorRect(&r);

//Just draw the whole visible area, our
//ScissorRect will cull everything outside away
DrawViewableArea();



You have to make sure to set D3DRS_SCISSORTESTENABLE into your rasterizer state then, though. (Think it was like this, haven't done much with D3D9 for a while)

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this