Jump to content
  • Advertisement
Sign in to follow this  
EnochDagor

Sprite Render Problem

This topic is 4815 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

I'm becoming a regular on this forum... Not sure if that's a good thing. The last two times were stupid things. This time, I'm not quite sure. I'm using a Sprite object to do Draw2D calls for rendering interface objects onto the screen. .Begin(SpriteFlags.None) .Draw2D(ControlImage, System.Drawing.Point.Empty, 0, oLoc, System.Drawing.Color.FromArgb(&HFFFFFFFF)) .End() Here's the problem... ControlImage is a Texture that is 24x24 pixels. Am I running into the Power of 2 Problem where my texture will be loaded and saved as a 32x32 pixel texture? Because that seems to be happening... the control renders 32x32 pixels. Is there a way to resize the image so it will be 24x24 or any other value I deem necessary? For example, my ControlImage texture is 32x32 pixels and my control is actually 128x32 pixels, how would I stretch or scale the image? So, to summarize, I am asking two questions: 1) Why is my ControlImage Texture that is 24x24 pixels on disk always being rendered as 32x32 pixels? Is this problem related to the Power of 2 for textures? 2) How can I scale/resize my textures as necessary for rendering purposes? Thanks, Matt Edit - Oh, and I am using VB.NET and DirectX9. Sorry for not stating that earlier.

Share this post


Link to post
Share on other sites
Advertisement
There are several versions of the Draw2D function. You need to use one with a rectangle parameter, that let's you select which area of the texture you want to draw.

Check the documentation and pick the version you need. I see 4 out of 6 which let you select the texture area to render.

Good luck :).

Share this post


Link to post
Share on other sites
Well, since the problem is with the texture loading, we should probably look there. Sorry, I don't use ManagedDX, so I don't know the exact function names.

If you use D3DXCreateTextureFromFileEx(), you can specify D3DX_DEFAULT_NONPOW2 for the texture width and height. This will produce a texture that is the exact size of the loaded image, not the closest power of two.

If your graphics card doesn't support non-pow2 textures (all newer cards do, check your CAPS), then you are stuck.

Share this post


Link to post
Share on other sites
One way to get around your limitation of power of 2 textures is just to render a portion of the texture. So create a power of 2 texture and put your non power of 2 texture into it (you could even put a few in) then when rendering with the sprite use the rect parameter to specify the 24 by 24 image.

Share this post


Link to post
Share on other sites
Thanks for the replies. Here's what I have done...

I created a 256x256 bmp and put all of my images for controls in there.

I then defined rectangles (which I'll likely load from an XML file later, but hardcoded for now) for each control and each state of the control (Button_Normal, Button_Pressed, Button_Disabled, etc...) and defined the points in the 256x256 texture that I am loading.

I then changed my code to read:

.Draw2D(moUILib.oInterfaceTexture, ControlImageRect, System.Drawing.Rectangle.FromLTRB(oLoc.X, oLoc.Y, oLoc.X + Width, oLoc.Y + Height), oLoc, System.Drawing.Color.FromArgb(&HFFFFFFFF))

However, it does not render now. I don't understand why not. I checked the variables and the values are correct and valid. But I am unsure of the oLoc parameter which is the "position" parameter. If I have a Source Rectangle and a Dest Rectangle, what purpose does "position" as a point serve? Furthermore, what should that be equal to?

Also to note, I'm not getting an error, the control is simply not visible on the screen.

Share this post


Link to post
Share on other sites
Ok, getting closer to fixing the issue, sad thing is I don't understand it.

Found on the internet someone doing something similar to what I am doing. Their code read:

fMultX = ControlImageRect.Width / Width
fMultY = ControlImageRect.Height / Height

.Draw2D(moUILib.oInterfaceTexture, ControlImageRect, New Rectangle(oLoc.X, oLoc.Y, Width, Height), New Point(0, 0), 0, New Point(oLoc.X * fMultX, oLoc.Y * fMultY), System.Drawing.Color.FromArgb(&HFFFFFFFF))

I tried different calls based on this using only the parameters I needed and if I change it just a little bit (such as removing the RotationCenter) the image doesn't render.

I'm going a bit cross-eyed.

Share this post


Link to post
Share on other sites
The second and third parameters are the source rectangle and destination rectangle. The fourth is a centre and the fifth a float. These two are not needed if you are not doing any rotation. The 6th is the position and the 7th the colour.

Share this post


Link to post
Share on other sites
Right, but what's odd is that if I use the Overloaded version that does not have the rotationCenter and rotationAngle, then the graphic does not render. Oddest thing I've seen. I'll use the prototype that has the rotationCenter and Angle and just pass Empty and 0. It doesnt seem to have any performance impact. Just thought it was odd.

-Matt

Share this post


Link to post
Share on other sites
Regarding the power of 2 problem... sometimes I solve these problems using mostly an image editor because it allows you to keep things general (ie, you don't have bizarre custom rectangles inside all your textures to keep track of, and in some cases wasted video memory.)

Say you have an image that's 800x18 pixels. When I encounter something like this, I do one of several things depending on the quality needed and whether I have access to larger resolution artwork:

1, start with a massive source image (1600x36 pixels or something like that, but this is not always an option) and resize it down to 1024x32 (which is the nearest LARGER power of two texture in both dimensions). Then when you render the image, draw your quads respecting the original aspect ratio (x/y = 800/18).

2, take your source image and resize it DOWN to the nearest power of two (say 512x16) and then render the image again keeping in mind your original dimensions. Obviously your image will be slightly lower quality than the above method but your texture is smaller and the difference might not be noticeable depending on the application.

3, take your source image and resize it UP to 1024x32 pixels and then render again keeping in mind your original image dimensions. If you don't have access to higher quality originals then this might be a feasible option that at least preserves the quality of your original.

If you do everything right, your image will look good as long as you have bilinear filtering on. You may want to apply a sharpen filter in an image editor whenever you resize artwork. Of course, any time you resize or otherwise filter artwork you do lose detail, but these are general guidelines to retain image quality in a power-of-2 restricted situation, and your art is going to be stretched/squashed one final time as it is rasterized anyways unless you are working on a 100% fixed-resolution project, which doesn't cut it anymore for PC apps at least.

I've seen people coming from DirectDraw sometimes not realize that the pixel dimensions of your source image are totally irrelevant in terms of the proportion of what is rendered, which is beautiful in many ways. You can take an image that's 1024x1024 and resize it down to 256x64 and it will still look roughly the same on the screen, minus quality of course. When you're building a project for distribution, you can keep huge textures in your directories during development and resize them to production sizes at the last minute and they will still look good. You really have to start thinking less about "pixels" and more about "screen proportion" and texels and such. The other obvious (massive) benefit to all this work is a resolution-independent app.

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!