# Image scaling with scanlines effect

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

## Recommended Posts

Hi - I'm looking for some fast scaling algotythm. I'm writing a game, that normally runs in 320x240 (arcade style), but I want it to resize into 640x480 with scanlines effect (just like in the most of the emulators). The algorythm I wrote works perfectly fine, the thing is it runs 8fps (while when non-scaled it runs about 130fps) on Athlon 1.7Ghz.

##### Share on other sites
Your going to have to explain your method in better detail, some code/pseudo code would help.

##### Share on other sites
if you are interested look at the graphics programming forum into my thread about image enlargement with bicubic interpolation

as for your problem which algorithem to you use?
if you have scanlines how many pixel do you put between scanlines?

did you use the nearest neightbour scaling algorithm? you only scale up by a factor of2 sp nearest neighbour should do the job here is a piece of code from my library i am currently working on

//sample image up( powers of 2)	template<class U, class W> void sample_up_nearest(const U& x, W& y)	{		uint32	i;		uint32	j;		uint32	xcoord;		float	flFactor = 1/static_cast<float>(W::MAP_SIZE / U::MAP_SIZE);		for(i=0;i<W::MAP_SIZE;i++)		{			xcoord = static_cast<uint32>(i*flFactor)			for(j=0;j<W::MAP_SIZE;j++)			{				y.m_Map[j]=x.m_Map[xcoord][static_cast<uint32>(j*flFactor)];			}		}	}

##### Share on other sites
How do you render the screen? SDL? GDI?
I haven't got my compiler here, but I have some pretty good resizing code at home. You can use a rewritten bresenham line algorithm to prevent all the casting from float to int.

##### Share on other sites
You could use stencil testing to block out every other line after scaling as been done. Just pre-load the stencil buffer with alternating white & black horizontal lines. And set up the stencil test to fail on black and pass on white

##### Share on other sites
This is my graphics class, the scaling loop is in graphics::blitMap function.

#include "headers.h"graphics::graphics(void) { //funkcja inicjuj&#261;ca grafik&#281; (konstruktor)    SDL_Init(SDL_INIT_VIDEO);    Uint32 SDL_FLAGS;    const SDL_VideoInfo *video_Probe; // pobieram informacje na temat dostepnego trybu video    video_Probe = SDL_GetVideoInfo();         cout << "sprawdzenie czy jest accel:..." << endl;    if (video_Probe->hw_available) { // czy dostepna jest akceleracja sprzetowa ekranu       SDL_FLAGS = SDL_HWSURFACE;              cout << "HWACCEL AVAILABLE" << endl;    } else {       SDL_FLAGS = SDL_SWSURFACE;       printf("Software mode only...\n");    }    if (video_Probe->blit_hw) {  // sprawdzenie czy zadziala sprzetowy blitter       SDL_FLAGS |= SDL_HWACCEL;       SDL_FLAGS |= SDL_DOUBLEBUF;    }    window = SDL_SetVideoMode(WINDOW_WIDTH, WINDOW_HEIGHT, WINDOW_BPP, SDL_FLAGS);    screen = SDL_CreateRGBSurface(SDL_SWSURFACE, SCREEN_WIDTH, SCREEN_HEIGHT, SCREEN_BPP, window->format->Rmask,                                                                                      window->format->Gmask,                                                                                      window->format->Bmask,                                                                                      window->format->Amask);    //screen = SDL_DisplayFormat(window);    scalemask = (Uint32 *) malloc ((640 * 480) * sizeof(Uint32));;                                              //ta tablica posluzyc ma do szybkiego przeskalowania                                              //obrazu z 320x240 do 640x480    for(iy=0; iy < window->h; iy++){              for(ix=0; ix < window->w; ix++){                        scalemask[ix + (iy * window->w)] = (ix/2 + ((iy/2)* (window->w/2)));              }    }                  SDL_WM_SetCaption(CAPTION, CAPTION);    next_time = SDL_GetTicks(); //inicjalizacja tajmera :)    frame =0;}void graphics::blitMap( void ){     //SDL_BlitSurface(screen, NULL, window, NULL);     if (SDL_MUSTLOCK(window) != 0) SDL_LockSurface(window);  //Ten kod skaluje obraz do 640x480     if (SDL_MUSTLOCK(screen) != 0) SDL_LockSurface(screen);     for (iy=0; iy < ((window->w*window->h)) ; iy++){                   ((Uint16*)window->pixels)[iy]=((Uint16*)screen->pixels)[scalemask[iy]];                        }     //SDL_UpdateRect(window, 0,0,0,0);     if (SDL_MUSTLOCK(screen) != 0) SDL_UnlockSurface(screen);     if (SDL_MUSTLOCK(window) != 0) SDL_UnlockSurface(window);};

##### Share on other sites
Well.. the code shouldn't give such an inpact. What kind of computer do you run it on? When you run the unscaled version, do you still lock the buffers? When using hardware rendering, locking a buffer is extremely slow. Another thing is that using a lookup table usually is slower than simple calculations. I've just installed SDL to test out some code..

##### Share on other sites
ok... here's a modified version that compiles to about 2-4 times faster then the other version (in msvs 2005). I've just changed some names when coding my test

pWindow = pointer to screen/window surface
PSurface = the image to scale

uint16* pDest = reinterpret_cast<uint16*>(pWindow->pixels);uint16* pSrc = reinterpret_cast<uint16*>(pSurface->pixels);for (int y = 0; y < WINDOW_HEIGHT; y += 2){	for (int x = 0; x < WINDOW_WIDTH; ++x)	{		int color = *pSrc;		*pDest = color;		pDest[WINDOW_WIDTH] = color;		pSrc += (x & 1);		++pDest;	}	pDest += WINDOW_WIDTH;}

By commenting out the line:

pDest[WINDOW_WIDTH] = color;

You'll get a simple scanline effect. This is the simplest scanline effect you can get. A method that might be visually more pleasing is to darken the color (though this didn't seem necessary in my test), but this requires some bit fiddling. This isn't difficult, but you'll end up with some different versions if you want different screen formats.

1. 1
Rutin
32
2. 2
3. 3
4. 4
5. 5

• 13
• 9
• 9
• 9
• 14
• ### Forum Statistics

• Total Topics
633323
• Total Posts
3011361
• ### Who's Online (See full list)

There are no registered users currently online

×