Jump to content
  • Advertisement


This topic is now archived and is closed to further replies.


Please tell me Direct3D has a function to do this

This topic is 5811 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 need a way to scale an image from let's say a 200x200 surface to a 256x256 texture. I know I can load an image (.bmp, .dds, .dib, .jpg, .png, and .tga) from a file of any dimension and Direct3D will automatically scale and convert the format with the D3DXCreateTextureFromFile method. But what I need is to do this on a pcx image file that I've loaded into memory and copied into a blank texture. Right now the texture is all messed up unless It's of a dimension of something like 256, 512, ect. Because this is a hardware issue, I need a way to scale my image in memory to these dimensions. I thought maybe the D3DXCreateTextureFromFileInMemory function could do it, but after looking at the docs, it to only supports the file formats I listed above. And I have to scale many pcx textures to those dimensions, which would take to long to convert them in a program like photoshop. After searching this forum, I found what appears to be an OpenGL function that can do it (gluScaleImage). So please tell me that there's an equivalent Direct3D function? [edited by - MagTDK on May 30, 2002 2:02:12 PM]

Share this post

Link to post
Share on other sites
why not just have your textures at 256x256? scaling at runtime is silly since you will introduce scaling artifacts into the texture. though since your already using improper images, that wont matter much.

psp support batch processing, and pretty sure it can allow you to scale all the images in a directory (though why your art was not created at the proper size in the first place seems odd). if all else fails, write your own app to scale all the images in a directory or using a text file listing all the files.

why are you using pcx? why not a more common format like bmp or png? pcx dies with dos i am afraid (though some ppl still use them, they are pretty useless for 3d apps when pngs are supported nativly by d3d8).

writing your own scaling funtion wont be too tough, do some research on software bilinear resampling. or you could just access the texture using a max uv of 200.0/256.0,200.0/256.0 and ignore resizing the image. though if your tiling the texture this wont be nice looking to do blending artifacts at the edges.

Share this post

Link to post
Share on other sites
You should be able to copy the 200x200 image into the 256x256 texture without a problem. If you do that, you can map the texture using 200/256 as your max u and v (assuming you aren''t tiling). (Oops - sorry, I guess a person just said that...)

If you are tiling, or if you need a "full" texture for some other reason, you might want to take a look at scripting photoshop. Unless you are talking about huge numbers of images, batch processing shouldn''t take too long. You get the advantage of using Photoshop''s filtering instead of writing your own.

Share this post

Link to post
Share on other sites

The problem is, as I''ve mentioned before, I''m loading textures from the quake 2 game. There using the pcx format for there models and what appears to be there own format (.wal) for the world textures. And both formats are of odd sizes.

I found this code at: http://polygone.flipcode.com/download.htm

It''s a QMDLViewer v1.0 that loads the pcx format. Because he''s using DirectX 7, it looks like he was using the DD interface to stretch the image. But because I''m not very fluent in DD, I''m not that sure. Perhaps someone with DD experience can tell. Here is the function I believe he is stretching the image to the power of 2:

void convert_pcx()
DDSURFACEDESC2 ddsd, ddsd2;
int i,j;
float xstep, ystep, xt, yt, x1,y1;
int x,y;
RECT rect;
FILE *klutt;

if(pcx_width > 256) //Always scale up

scale_width = 512;
else if(pcx_width > 128)
scale_width = 256;
else if(pcx_width > 64)
scale_width = 128;
else if(pcx_width > 32)
scale_width = 64;

if(pcx_height > 256)
scale_height = 512;
else if(pcx_height > 128)
scale_height = 256;
else if(pcx_height > 64)
scale_height = 128;
else if(pcx_height > 32)
scale_height = 64;

ZeroMemory(&ddsd, sizeof(ddsd) );
ddsd.dwSize = sizeof(ddsd);
ddsd.dwWidth = scale_width;
ddsd.dwHeight = scale_height;


SetRect(&rect, 0, 0, scale_width, scale_height);
memset(&ddsd,0, sizeof(ddsd));
ddsd.dwSize = sizeof(ddsd);
double_buf = (WORD *)ddsd.lpSurface;

(float)xstep = (float)pcx_width / (float)scale_width;
(float)ystep = (float)pcx_height / (float)scale_height;
xt = 0.0; yt = 0.0; x1 = 0.0f; y1 = 0.0f;
x = 0; y = 0;
for (j = 0; j < scale_height; j++) {
(float)y1 += (float)ystep;
(float)yt = (float)y1;
(int)y = yt; if(y > pcx_height) y = pcx_height;
for (i = 0; i < scale_width; i++) {
(float)x1 += (float)xstep;
(float)xt = (float)x1;
(int)x = (float)xt; if(x > pcx_width) x = pcx_width;

double_buf[(j * scale_width + i)] = RGB16(((long)pcx_pal_buffer[3 * pcx_buffer[ ( y * pcx_width ) + x ]+0 ] / 8),
((long)pcx_pal_buffer[3 * pcx_buffer[ ( y * pcx_width ) + x ]+1 ] / 8),
((long)pcx_pal_buffer[3 * pcx_buffer[ ( y * pcx_width ) + x ]+2 ] / 8));

x = 0; x1 = 0.0;

for(i = (scale_width * scale_height) - ((float)scale_width * 1 + 34); i < (scale_width * (scale_height - 1)); i++)
double_buf[i] = RGB16(0,0,0);



Now that I''ve found this source code, I think I''ll study it some more.

Share this post

Link to post
Share on other sites

By the way, does anyone know what DirectX uses for image scaling when loading a testure from file? Is it bilinear resampling, Bicubic interpolation, or some other algorithm.

Share this post

Link to post
Share on other sites
You could also use IDirectDrawSurface7::Blt(...)''s ability to stretch images to your advantage. This is especially useful if you are already loading your image onto a surface. Check out the SDK, it''s just a matter of having a source rect that is a different size than the dest rect, the stretching is automatic. In most cases, the stretching is done in hardware, making it pretty fast.


Share this post

Link to post
Share on other sites
It might be interesting/beneficial to look into packing several of the odd sized textures into one larger texture. For instance, packing 5 200x200 textures into 1 1024x256 texture would waste less resources than loading the 200x textures into 5 different 256x256 textures. That might be useful for the characters wher (AFAIK) there isn''t any tiling.

That way, you wouldn''t have to stretch at all. Stretching the original texture just introduces artifacts and wastes texture memory.

Share this post

Link to post
Share on other sites
do an AA scaler (ie weight each point against it neighbours when rescaling depending it strength) and get what size you shall resize to with:

for(int y = 0; y < 8; y++){
for(int x = 0; x < 8; x++){
int new_xres = pow(2,x);
int new_yres = pow(2,y);

and voila done

(lets see if i get that source shit work at last(editing)

uhm, ok fixing the < to <= .. sorry ;-) uhm iam bored and prety fucking fucked up.. this chemicales are cool

[edited by - stefandxm on June 9, 2002 2:45:40 PM]

Share this post

Link to post
Share on other sites
Eeeewwwww! Stay away from pow(), especially in tight loops.
use bit shifts instead:

int new_xres = 1 << x;


DirectX Programmer
Soon to be the new Bill Gates

Share this post

Link to post
Share on other sites

  • 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!