SDL2.0的几何图形绘画
通过SDL_Window、SDL_Renderer、SDL_Texture三者实现了简单的几何图形绘画。
包括了SDL_RenderDrawPoint、SDL_RenderFillRect、SDL_RenderDrawLine、SDL_SetRenderDrawColor等。
具体看代码吧(VS2012运行):
#include <stdio.h>
#include <string.h>
#include <time.h>
#include <SDL2\SDL.h>
#include <SDL2\SDL_image.h>
#include <SDL2\ex\SDLex.h>
SDL_Window *sdlWindow = NULL;
SDL_Renderer *sdlRender = NULL;
SDL_Texture *sdlTexture = NULL;
SDL srcRect;
int w = 500;
int h = 500;
void DrawCircle(SDL_Renderer *ren,int radius){
int st=clock(),tx=0,ty=radius,d=3-(radius<<1),x=radius,y=radius;
while(tx<ty){
for (int i=x-ty;i<=x+ty;++i){
SDL_RenderDrawPoint(ren,i,y-tx);
if (tx)
SDL_RenderDrawPoint(ren,i,y+tx);
}
if (d<0)
d+=(tx<<2)+6;
else{
for (int i=x-tx;i<=x+tx;++i){
SDL_RenderDrawPoint(ren,i,y-ty);
SDL_RenderDrawPoint(ren,i,y+ty);
}
d+=((tx - ty)<<2)+10,ty--;
}
tx++;
}
if (tx==ty)
for (int i=x-ty;i<=x+ty;++i){
SDL_RenderDrawPoint(ren,i,y-tx);
SDL_RenderDrawPoint(ren,i,y+tx);
}
int en=clock();
}
bool InitView(int width, int height, const char *iconName)
{
//初始化窗体
SDL_Init(SDL_INIT_VIDEO);
sdlWindow = SDL_CreateWindow(
"The First SDL Program",
SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, width, height,
SDL_WINDOW_RESIZABLE);
if (sdlWindow == NULL) return false;
//加载窗体图标
SDL_Surface *iconSurface = IMG_Load(iconName);
if (iconSurface == NULL) return false;
SDL_SetWindowIcon(sdlWindow, iconSurface);
return true;
}
bool InitDraw()
{
//加载渲染器
sdlRender = SDL_CreateRenderer(sdlWindow, -1, 0);
if (sdlRender == NULL) return false;
sdlTexture = SDL_CreateTexture(sdlRender, SDL_PIXELFORMAT_RGBA8888, SDL_TEXTUREACCESS_TARGET, w, h);
if (sdlTexture == NULL) return false;
//SDL_SetTextureBlendMode(sdlTexture, SDL_BLENDMODE_BLEND);
//SDL_SetRenderTarget(sdlRender, sdlTexture);
return true;
}
void UpdateDraw()
{
//设置背景颜色
SDL_SetRenderDrawColor(sdlRender, 255, 153, 153, 0xFF);
SDL_RenderClear(sdlRender);
//左眼
SDL_SetRenderDrawColor(sdlRender, 0x00, 0xFF, 0xFF, 0xFF);
srcRect = SDLMake(w/7*2, h/7, w/8, h/8);
SDL_RenderFillRect(sdlRender, &srcRect);
//左眉毛
SDL_SetRenderDrawColor(sdlRender, 0x00, 0x00, 0x00, 0xFF);
SDL_RenderDrawLine(sdlRender, srcRect.x, srcRect.y - 10, SDLMaxX(srcRect), srcRect.y - 10);
//右眼
SDL_SetRenderDrawColor(sdlRender, 0xFF, 0x00, 0xFF, 0xFF);
srcRect = SDLMake(w/7*4, srcRect.y, srcRect.w, srcRect.h);
SDL_RenderDrawRect(sdlRender, &srcRect);
//右眉毛
SDL_SetRenderDrawColor(sdlRender, 0x00, 0x00, 0x00, 0xFF);
SDL_RenderDrawLine(sdlRender, srcRect.x, srcRect.y - 10, SDLMaxX(srcRect), srcRect.y - 10);
//嘴巴
SDL_SetRenderDrawColor(sdlRender, 0xFF, 0xFF, 0x00, 0xFF);
srcRect = SDLMake(w/8*3, h/7*3, w/8*2, h/8);
SDL_RenderFillRect(sdlRender, &srcRect);
SDL_SetRenderDrawColor(sdlRender, 0xFF, 0x00, 0x00, 0xFF);
DrawCircle(sdlRender, 10);
SDL_RenderPresent(sdlRender);
}
void Quit(int code)
{
const char *errMsg = SDL_GetError();
if (errMsg && strlen(errMsg)) {
SDL_Log("Error : %s\n", errMsg);
}
//销毁窗口、渲染器、纹理
if (sdlWindow) SDL_DestroyWindow(sdlWindow);
if (sdlRender) SDL_DestroyRenderer(sdlRender);
if (sdlTexture) SDL_DestroyTexture(sdlTexture);
SDL_Quit();
exit(code);
}
void HandleKeyEvent(const SDL_Keysym* keysym)
{
int key = keysym->sym;
switch(key)
{
case SDLK_ESCAPE:
Quit(0);
break;
case SDLK_SPACE:
break;
case SDLK_UP:
case SDLK_DOWN:
case SDLK_LEFT:
case SDLK_RIGHT:
int x, y;
SDL_GetWindowPosition(sdlWindow, &x, &y);
x = (key == SDLK_LEFT ? x-2 : (key == SDLK_RIGHT ? x+2 : x));
y = (key == SDLK_UP ? y-2 : (key == SDLK_DOWN ? y+2 : y));
SDL_SetWindowPosition(sdlWindow, x, y);
SDL_Log("x=%d, y=%d\n", x, y);
break;
case SDLK_KP_PLUS:
case SDLK_KP_MINUS:
w = (key == SDLK_KP_PLUS ? w+2 : w-2);
h = (key == SDLK_KP_PLUS ? h+2 : h-2);
SDL_SetWindowSize(sdlWindow, w, h);
SDL_Log("w=%d, h=%d\n", w, h);
break;
default:
break;
}
}
void HandleEvents()
{
//Our SDL event placeholder.
SDL_Event event;
//Grab all the events off the queue.
while(SDL_PollEvent(&event)) {
switch(event.type) {
case SDL_KEYDOWN:
//Handle key Event
HandleKeyEvent(&event.key.keysym);
break;
case SDL_QUIT:
//Handle quit requests (like Ctrl-c).
Quit(0);
break;
}
}
}
int main(int argc, char* argv[])
{
printf("可以通过↑↓←→+ -按键控制移动和大小\n");
if (InitView(w, h, "yp.ico") == false) {
SDL_Log("sdlWindow is null @_@\n");
Quit(0);
return -1;
}
if (InitDraw() == false) {
SDL_Log("Init Fail @_@\n");
Quit(0);
return -1;
}
//配置客户区大小
SDL_QueryTexture(sdlTexture,NULL, NULL, &w, &h);
SDL_SetWindowSize(sdlWindow, w + 2, h);
SDL_Log("w=%d, h=%d\n", w, h);
while (1) {
HandleEvents();
UpdateDraw();
}
SDL_DestroyWindow(sdlWindow);
SDL_Quit();
return 0;
}