SDLで描画ライブラリの作成
プレゼンハムのアルゴリズムを使って、矩形を描画する関数を作ってみました。
main.c
#include <SDL/SDL.h> #include "drw_line.h" #pragma comment(lib,"SDL.lib") #pragma comment(lib,"SDLmain.lib") SDL_Surface *g_screen; int rcv_event(void); #define W 200 #define H 200 #define DRW_PARAM RECT_WINDOW int main(int argc,char *argv[]) { Uint8 flg = 1; Sint8 p_flg; Uint8 pxl = 1; SDL_Rect rects[9] = { { 0, 0, W, H}, { 200, 0, W, H}, { 400, 0, W, H}, { 0, 200,W, H}, { 200, 200,W, H}, { 400, 200,W, H}, { 0, 400,W, H}, { 200, 400,W, H}, { 400, 400,W, H}, }; Uint32 color[9] = { 0x90EE90, 0xffff00, 0x00ffff, 0xff00ff, 0x87CFFA, 0xFFD700, 0x008080, 0xFFA500, 0xD8BFD8, }; if( SDL_Init(SDL_INIT_VIDEO | SDL_INIT_TIMER) < 0) { printf("Initialize Error : %s",SDL_GetError()); return -1; } SDL_WM_SetCaption("SDL",NULL); if( (g_screen = SDL_SetVideoMode(600,600,32,SDL_SWSURFACE)) == NULL) { printf("SetVideoMode Error : %s",SDL_GetError()); return -1; } for(p_flg = 1; flg; ) { SDL_FillRect(g_screen, NULL, 0x00000000); switch( rcv_event() ) { case 1: flg = 0; break; case 2: break; default: { int idx = 0; int t = abs(pxl + p_flg); if((t >= W/2) || (t < 1)) { p_flg *= -1; pxl += p_flg; }else{ pxl += p_flg; } while(idx < 9) { drw_rect(&rects[idx],pxl,color[idx],DRW_PARAM,g_screen); idx++; } } SDL_Flip(g_screen); break; } SDL_Delay(60); } SDL_FreeSurface(g_screen); SDL_Quit(); return 0; } |
Graphics.c
/*--------------------------------------*/ /* 作成日時 2009/02/15 */ /* 概要 矩形を描画する */ /* Descripsion */ /* return value */ /* */ /*--------------------------------------*/ int drw_rect(SDL_Rect *r, Uint8 pxl, Uint32 color, Uint8 flg, SDL_Surface *screen) { Sint16 x1,y1,x2,y2; x1 = r->x; y1 = r->y; x2 = r->x+r->w-1; y2 = r->y+r->h-1; /********************************************/ /* 描画する線の幅はWIDTHの半分まで */ /********************************************/ if(pxl > r->w/2 || pxl < 1 ) { return -1; } switch( flg ) { case RECT_NORMAL: /* 通常の矩形を描画 */ { while(pxl-- > 0) { drw_line(x1, y1, x2, y1, color, screen); drw_line(x2, y1, x2, y2, color, screen); drw_line(x2, y2, x1, y2, color, screen); drw_line(x1, y2, x1, y1, color, screen); if(pxl > 0) { x1++; x2--; y1++; y2--; } } break; } case RECT_GRADATION: /* 矩形の色をグラデーションさせる */ { Sint16 R = color>>16&0xff; Sint16 G = color>>8 &0xff; Sint16 B = color &0xff; while(pxl-- > 0) { drw_line(x1, y1, x2, y1, color, screen); drw_line(x2, y1, x2, y2, color, screen); drw_line(x2, y2, x1, y2, color, screen); drw_line(x1, y2, x1, y1, color, screen); if(pxl > 0) { x1++; x2--; y1++; y2--; R = (R - 1 < 0) ? 0 : R - 1; G = (G - 1 < 0) ? 0 : G - 1; B = (B - 1 < 0) ? 0 : B - 1; color = (R<<16) + (G<<8) + (B); } } break; } case RECT_WINDOW: /* ウィンドウ風の図形を作成する */ if(r->w > DRW_MIN_W && r->h > DRW_MIN_W) { Uint8 inc_r,dec_r; Uint8 inc_g,dec_g; Uint8 inc_b,dec_b; Uint8 rl,rd; Uint8 gl,gd; Uint8 bl,bd; inc_r = (0xff - (color>>16 &0xff))/pxl; inc_g = (0xff - (color>>8 &0xff))/pxl; inc_b = (0xff - (color &0xff))/pxl; dec_r = (color>>16 &0xff)/pxl; dec_g = (color>>8 &0xff)/pxl; dec_b = (color &0xff)/pxl; rl = (color>>16 &0xff) + inc_r; gl = (color>>8 &0xff) + inc_g; bl = (color &0xff) + inc_b; rd = (color>>16 &0xff) - dec_r; gd = (color>>8 &0xff) - dec_g; bd = (color &0xff) - dec_b; x1 += pxl-1; x2 -= pxl-1; y1 += pxl-1; y2 -= pxl-1; /************************************/ /* 端以外の領域を塗りつぶす */ /************************************/ { SDL_Rect rect_t = {x1,y1,x2-x1,y2-y1}; SDL_FillRect(screen, &rect_t, color); } while(pxl-- > 0) { color = (rl<<16) + (gl<<8) + (bl); drw_line(x1, y1, x2, y1, color, screen); drw_line(x1, y2, x1, y1, color, screen); color = (rd<<16) + (gd<<8) + (bd); drw_line(x2, y1, x2, y2, color, screen); drw_line(x2, y2, x1, y2, color, screen); if(pxl > 0) { x1--; x2++; y1--; y2++; rl += inc_r; gl += inc_g; bl += inc_b; rd -= dec_r; gd -= dec_g; bd -= dec_b; } } } break; default: break; } return 0; } |