Direct3d drawing 2d sprites. scaling issues - c++

I'm new to programming with c++ and direct3d. I try to draw textures(LPDIRECT3DTEXTURE9) on the screen with a sprite(LPD3DXSPRITE). But when I draw a texture it seems to enlarge it, a 100x100 px texture is not drawn from coordinates (100, 100) to (200, 200) but from (100, 100) to (227, 227), I tested that by drawing 1x1 px blocks at those coordinates. I can't figure out why this is the case... Is the creation of the LPDIRECT3DDEVICE9 of any influence on it or could it be something completely different?

This seems to be a scaling issue. When you first call CreateTextureFromFile(), the function causes the texture to be scaled to a power of 2 rule (512, 256 for example). To fix this, simply call the setScale function to 1,1 and this should fix your problem :)

Related

WinAPI create PatternBrush with offset

Sorry for the unclear title, but I'm having a problem with WinAPI.
I have created a window and added double buffering for graphics, and now I'm trying to draw a rectangle using FillRect(). The only problem is when I'm using CreatePatternBrush() to texture the rectangle, the texture then always starts at (0, 0) no matter where the rectangle starts.
I would like to, for example, be able to draw a rectangle between (10, 10) and (60, 60) and have the texture's corners match the rectangle's corners. Is that possible or do I have to use BitBlt() instead?

Direct2D Coordinate erro

I was doing a test program with direct2d to show lines, however I noticed a little detail and that is that when I tell direct2d to draw a dotted line (100,200) and (500,200), direct2d really isn't drawing the beginning of the line at the point (100,200), but it draws it one pixel less, that is, it coordinates at the coordinate (100,99). Does anyone know why this is? I checked this detail using direct2d without antialiasing mode and showing in the debug output the mouse coordinates.
This is caused by Direct2D's own design.
To be precise, the coordinates of the line are from (99.5, 199.5) - (500.5, 200.5).
And #Rick Brewster's answer has explained these.
When you give it a pixel coordinate such as (100, 120), that refers to
the top and left corner of the pixel element that spans from pixel
coordinates (100, 120) to (101, 121) (top/left are inclusive,
right/bottom are exclusive). Since it's a straight horizontal line you
are effectively getting a filled rectangle from (99.5, 119.5) -
(300.5, 120.5).
So if you want to draw a line from that covers the pixels (100, 200) to
(500, 200), you can use aliased rendering or use half-pixel offsets.

Draw only visible shapes

I'm developing a 2D graphics viewer by using Direct2D. I have a lot (up to 200,000) of shapes to draw. I would like to be able to draw only those shapes that are actually visible inside my canvas.
So, for example, if my window is 640x480 (starting from 0,0) I don't need to draw a rectangle which has its top-left corner in (1000, 1000).
How can I achieve this result?

OpenGL 2D doublebuffer scaling

I am using OpenGL for a 2D-based game which has been developed for a resolution of 640x480 pixels. Thus, I setup my OpenGL doublebuffer like this:
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(0, 640, 480, 0, 0, 1);
glDisable(GL_DEPTH_TEST);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
This works really well and I can draw all my sprites and background scrollers using hardware accelerated GL textures. Now I'd like to support other window sizes as well, i.e. the user should be able to run the game in 800x600, 1024x768, etc. So all graphics should be scaled to the new resolution. Of course I could do this by simply applying scaling factors to all my vertices when drawing the textures as quads. But I don't think that I'd be able to achieve pixel-perfect positioning that way.... but pixel-perfect positioning is of course very important for 2D games!
Thus, I'd like to ask if there's a possibility to work with a static 640x480 doublebuffer have it scaled only just before it is drawn to the screen, i.e. something like this:
1) My doublebuffer will always be 640x480 pixels, no matter what the real output window size is.
2) Once I call glfwSwapBuffers() the 640x480 doublebuffer should be scaled to the actual window size which can be smaller or larger than 640x480.
Is this possible somehow? I think this would be the easiest solution for my game because manually scaling all vertices is likely to give me some problems when it comes to pixel-perfect positioning, isn't it?
Thanks!
I setup my OpenGL doublebuffer like this:
I think you don't know what "doublebuffer" means. It means that you perform drawing on a invisible buffer which is then revealed to the user once the drawing is finished, so that the user doesn't see the drawing process.
The code snippet you have there is the projection setup. And hardcoding the dimensions in pixel units there is just wrong.
but pixel-perfect positioning is of course very important for 2D games!
No, not really. Instead of "pixel" units (which don't really exist in OpenGL except for texture image indexing and the viewport) you should use something like world unit. For example in a simple jump-and-run platformer like SMW
you could say, that each block is one unit high. The Yosi-sprite would be 2 units high, Mario 1.5 and so on.
The important thing is, that you can keep your sprite rendering dimensions independent of screen resolution. This is especially important with respect to all the varying screen resolutions and aspect ratios out there. Don't force the user on resolutions you think are appropriate. People have computers with big screens and they want to use them.
Also the appearance of your sprites depends largely on the texture images and filtering method you use. If you want to achieve a pixelated look, just make the texture images low resolution and use a GL_NEAREST magnification filter, OpenGL will do the rest (however you should provide minification mipmaps and use GL_LINEAR_MIPMAP_LINEAR for minification, so that things don't look awful on small resolutions).
Thus, I'd like to ask if there's a possibility to work with a static 640x480 doublebuffer have it scaled only just before it is drawn to the screen, i.e. something like this:
Yes, you can use a framebuffer object for this. Create a set of textures (color and depth-stencil) of the rendering dimensions (like 640×480) render to that, then when finished draw the color texture to a viewport filling quad on the main framebuffer.
Like before, render at 640x480 but to an offscreen texture. Then render a screen-sized (800x600, 1024x768,...) quad with this texture applied to it.

what is the actual difference between gluortho2d and glViewport

I made a window sized 800x600. I called
gluOrtho2D(-400,400,-300,300);
glViewport(400,300,400,300);
and I drew a line from (-100,-100) to (100,100). I think I should see a line from (0,0) to (100,100), but I am getting the whole line. Why is this?
In theory, glViewport doesn't cause any clipping (see section 10). Normally, all drawing is clipped to the window. Since you have asked OpenGL to draw into a region of your window, you will need to also tell OpenGL to clip coordinates outside this viewport. For that, you will need glScissor. However, some implementations do clip their drawing to the viewport (see my comment for details).
In addition, your math is wrong. Your projection matrix is 800 units wide by 600 units tall, centered at (0, 0). This is then mapped to a portion of the window that is 400 pixels wide by 300 pixels tall, in the upper-right corner of the window.
If you draw a line from (-100, -100) to (100, 100), it will extend across only a small part of your viewing frustrum. The frustrum is sized to fit in the viewport.
In the image, the blue box is the window, and the red box represents the viewport. The black line should be the line that you drew.
An image describing what the paragraph says. http://img696.imageshack.us/img696/6541/opengl.png
Hope that helps!
glViewport describes the area of your window which will be drawn by OpenGL.
glOrtho or gluOrtho2D define a unit system (OpenGL units) which fit into that (via glViewport defined) area.
So your line will be drawn within the Viewport from -100,-100 to 100,100