免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 1097 | 回复: 0
打印 上一主题 下一主题

Pixel Manipulation and Surface Flipping [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2006-05-26 11:46 |只看该作者 |倒序浏览
Last Updated 2/26/06We've already done some work dealing with the pixels directly, but it was just reading pixels. In this tutorial we will read/write pixels to make our own surface flipping function.
bool load_files() { //Load the image topLeft = load_image( "corner.png" ); //If there was an problem loading the image if( topLeft == NULL ) { return false; } //If eveything loaded fine return true; }
In our loading function we only load one image:

In order to show all four corners we well have to create them ourselves by flipping the image we loaded.
Uint32 get_pixel32( SDL_Surface *surface, int x, int y ) { //Convert the pixels to 32 bit Uint32 *pixels = (Uint32 *)surface->pixels; //Get the requested pixel return pixels[ ( y * surface->w ) + x ]; } void put_pixel32( SDL_Surface *surface, int x, int y, Uint32 pixel ) { //Convert the pixels to 32 bit Uint32 *pixels = (Uint32 *)surface->pixels; //Set the pixel pixels[ ( y * surface->w ) + x ] = pixel; }
Here's our functions to get and put pixels. In case you missed the bitmap font tutorial, here's a quick review on how pixel access works:
First thing we do is convert the pixel pointer from type void to 32bit integer so we can properly access them. After all, a surface's pixels are nothing more than an array of 32bit integers. Then we get or set the requested pixel.
You maybe be wondering why I don't just go "return pixels[ x ][ y ]".
The thing is the pixels aren't stored like this:

They're stored like this:

in a single dimensional array. Its because different operating systems store 2D arrays differently (At least I think that's why).
So to retrieve the red pixel from the array we multiply the y offset by the width and add the x offset.
These functions only work for 32-bit surfaces. You'll have to make one of your own if you're using a different format.
SDL_Surface *flip_surface( SDL_Surface *surface, int flags ) { //Pointer to the soon to be flipped surface SDL_Surface *flipped = NULL; //Create a blank surface flipped = SDL_CreateRGBSurface( SDL_SWSURFACE, surface->w, surface->h, surface->format->BitsPerPixel, surface->format->Rmask, surface->format->Gmask, surface->format->Bmask, surface->format->Amask );
Now here's our surface flipping function.
At the top we create a blank surface using SDL_CreateRGBSurface(). It may look complicated, but ultimately we're just creating a surface of the same size and format as the surface we are given.
Take a look at the SDL Documentation to see how SDL_CreateRGBSurface() works.
//If the surface must be locked if( SDL_MUSTLOCK( surface ) ) { //Lock the surface SDL_LockSurface( screen ); }
Before we can start altering pixels we have to check if the surface has to be locked before accessing the pixels using SDL_MUSTLOCK(). If SDL_MUSTLOCK() says we have to lock the surface, we use SDL_LockSurface() to lock the surface.
Now that the surface is locked it's time to mess with the pixels.
//Go through columns for( int x = 0, rx = flipped->w - 1; x w; x++, rx-- ) { //Go through rows for( int y = 0, ry = flipped->h - 1; y h; y++, ry-- ) {
Here is our nested loops used for going through the pixels. You may be wondering why we declare 2 integers in our for loops. The reason is that when you flip pixels, you have to read them in one direction and write them in reverse.
In the x loop, we declare "x" and "rx". "x" is initialized to 0, and "rx" (which stands for reverse x) is initialized to the width minus 1 which is the end of the surface.
Then in the middle the condition is normal. At the end "x" is incremented and "rx" is decremented. "x" will start at the beginning and go forward, "rx" starts at the end and goes backward.
So if the surface's width was 10, the for loop will cycle like so:
"x"  : 0 1 2 3 4 5 6 7 8 9
"rx" : 9 8 7 6 5 4 3 2 1 0
I'm pretty sure you can now figure out what "y" and "ry" do.
//Get pixel Uint32 pixel = get_pixel32( surface, x, y ); //Copy pixel if( ( flags & FLIP_VERTICAL ) && ( flags & FLIP_HORIZONTAL ) ) { put_pixel32( flipped, rx, ry, pixel ); } else if( flags & FLIP_HORIZONTAL ) { put_pixel32( flipped, rx, y, pixel ); } else if( flags & FLIP_VERTICAL ) { put_pixel32( flipped, x, ry, pixel ); } } }
Here's the middle of the nested loops.
First we read in a pixel from the source surface. Then if the user passed in the FLIP_VERTICAL and the FLIP_HORIZONTAL flags, we write the pixels to the blank surface right to left, bottom to top.
If the user just passed the FLIP_VERTICAL flag, we write the pixels to the blank surface left to right, bottom to top.
If the user just passed the FLIP_HORIZONTAL flag, we write the pixels to the blank surface right to left, top to bottom.
If you're wondering what the flag values are, they're near the top of the source.
//Unlock surface if( SDL_MUSTLOCK( surface ) ) { SDL_UnlockSurface( surface ); } //Return flipped surface return flipped; }
At the end of our surface flipping function, we check if the surface had to be locked. If it did, we unlock it using SDL_UnlockSurface().
Lastly we return a pointer to our newly created flipped surface.
//Flip surfaces topRight = flip_surface( topLeft, FLIP_HORIZONTAL ); bottomLeft = flip_surface( topLeft, FLIP_VERTICAL ); bottomRight = flip_surface( topLeft, FLIP_HORIZONTAL | FLIP_VERTICAL ); //Apply the images to the screen apply_surface( 0, 0, topLeft, screen ); apply_surface( 320, 0, topRight, screen ); apply_surface( 0, 240, bottomLeft, screen ); apply_surface( 320, 240, bottomRight, screen ); //Update the screen if( SDL_Flip( screen ) == -1 ) { return 1; }
and here's the surface flipping function in action. Then the surfaces are applied and the screen is updated to show the daimond pattern.
Download the media and source code for this tutorial
here
.


本文来自ChinaUnix博客,如果查看原文请点:http://blog.chinaunix.net/u/19671/showart_118425.html
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP