(译)SDL编程入门(11)裁剪渲染和精灵表
裁剪渲染和精灵表
有时你只想渲染纹理的一部分。很多时候,游戏喜欢将多个图像保留在同一张精灵表上,而不是拥有一堆纹理。使用剪辑渲染,我们可以定义要渲染的纹理的一部分,而不是渲染整个对象。
//Texture wrapper class
class LTexture{
public:
//Initializes variables
LTexture();
//Deallocates memory
~LTexture();
//Loads image at specified path
bool loadFromFile( std::string path );
//Deallocates texture
void free();
//Renders texture at given point
void render( int x, int y, SDL_Rect* clip = NULL );
//Gets image dimensions
int getWidth();
int getHeight();
private:
//The actual hardware texture
SDL_Texture* mTexture;
//Image dimensions
int mWidth;
int mHeight;
};
在这里,我们对纹理类中的渲染函数做了一个小小的调整。渲染函数现在接受一个矩形,定义我们要渲染纹理的哪一部分。我们给它一个默认参数NULL,以防我们想渲染整个纹理。
//场景精灵
SDL_Rect gSpriteClips[ 4 ];
LTexture gSpriteSheetTexture;
在本教程中,我们将使用此精灵表:
并将每个精灵渲染在不同的角落:
所以我们需要一个纹理图像和4个矩形来定义精灵,这就是你看到的这里声明的变量。
void LTexture::render( int x, int y, SDL_Rect* clip ){
//设置渲染空间并渲染至屏幕
SDL_Rect renderQuad = { x, y, mWidth, mHeight };
//设置素材的渲染尺寸
if( clip != NULL )
{
renderQuad.w = clip->w;
renderQuad.h = clip->h;
}
//渲染到屏幕
SDL_RenderCopy( gRenderer, mTexture, clip, &renderQuad );
}
这是支持裁剪渲染的纹理类的新渲染函数。它和之前的纹理渲染函数大部分是一样的,但是有两个变化。
首先,当你在裁剪时,你使用的是裁剪矩形的尺寸而不是纹理,我们要将目标矩形(这里称为renderQuad)的宽度/高度设置为裁剪矩形的尺寸。
其次,我们要将裁剪矩形作为源矩形传递给SDL_RenderCopy。源矩形定义了你要渲染的纹理的哪一部分。当源矩形为NULL时,整个纹理将被渲染。
bool loadMedia(){
//Loading success flag
bool success = true;
//加载精灵表纹理
if( !gSpriteSheetTexture.loadFromFile( "11_clip_rendering_and_sprite_sheets/dots.png" ) )
{
printf( "Failed to load sprite sheet texture!n" );
success = false;
}
else
{
//设置左上角的精灵
gSpriteClips[ 0 ].x = 0;
gSpriteClips[ 0 ].y = 0;
gSpriteClips[ 0 ].w = 100;
gSpriteClips[ 0 ].h = 100;
//设置右上角的精灵
gSpriteClips[ 1 ].x = 100;
gSpriteClips[ 1 ].y = 0;
gSpriteClips[ 1 ].w = 100;
gSpriteClips[ 1 ].h = 100;
//设置左下角的精灵
gSpriteClips[ 2 ].x = 0;
gSpriteClips[ 2 ].y = 100;
gSpriteClips[ 2 ].w = 100;
gSpriteClips[ 2 ].h = 100;
//设置右下角的精灵
gSpriteClips[ 3 ].x = 100;
gSpriteClips[ 3 ].y = 100;
gSpriteClips[ 3 ].w = 100;
gSpriteClips[ 3 ].h = 100;
}
return success;
}
媒体加载函数加载纹理,然后如果成功加载纹理,则为圆形精灵定义裁剪矩形。
//While application is running
while( !quit )
{
//Handle events on queue
while( SDL_PollEvent( &e ) != 0 )
{
//User requests quit
if( e.type == SDL_QUIT )
{
quit = true;
}
}
//Clear screen
SDL_SetRenderDrawColor( gRenderer, 0xFF, 0xFF, 0xFF, 0xFF );
SDL_RenderClear( gRenderer );
//Render top left sprite
gSpriteSheetTexture.render( 0, 0, &gSpriteClips[ 0 ] );
//Render top right sprite
gSpriteSheetTexture.render( SCREEN_WIDTH - gSpriteClips[ 1 ].w, 0, &gSpriteClips[ 1 ] );
//Render bottom left sprite
gSpriteSheetTexture.render( 0, SCREEN_HEIGHT - gSpriteClips[ 2 ].h, &gSpriteClips[ 2 ] );
//Render bottom right sprite
gSpriteSheetTexture.render( SCREEN_WIDTH - gSpriteClips[ 3 ].w, SCREEN_HEIGHT - gSpriteClips[ 3 ].h, &gSpriteClips[ 3 ] );
//Update screen
SDL_RenderPresent( gRenderer );
}
最后在这里的主循环中,我们对同一个纹理渲染了4次,但是我们每次调用都会在不同的地方渲染精灵表的不同部分。
在 这里[1]下载本教程的媒体和源代码。
参考资料
[1]
这里: http://www.lazyfoo.net/tutorials/SDL/11_clip_rendering_and_sprite_sheets/11_clip_rendering_and_sprite_sheets.zip
[2]
原文链接: http://www.lazyfoo.net/tutorials/SDL/11_clip_rendering_and_sprite_sheets/index.php
- 基于 R 语言和 SPSS 的决策树算法介绍及应用
- Android 8.0 中的安全增强功能
- python2 群发 html 或文本邮件
- windows 安装 storm 及 eclipse 调试 TopN 实例
- shell 学习笔记(16)
- 根据ip查找ISP运营商和归属地的几种方法
- windows 安装 spark 及 pycharm 调试 TopN 实例
- storm kafka 编程指南
- 基于Session的身份窃取
- 使用 django-blog-zinnia 搭建个人博客
- 针对提权小神器Sherlock的分析与利用
- 关于 rsync 中: 和 :: 及 rysnc 和 ssh 认证协议的区别
- Java 反射机制详解
- shell 脚本多进程创建 mysql 测试数据
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- Tomcat NIO(6)-Acceptor
- 【C++】八皇后问题(竖列递进)
- Koom流程记录(一)
- FTP文件管理项目(本地云)项目日报(关于不定长包的测试)
- 指针传参解惑(3)
- 学以致用设计模式 之 “组合模式”
- 学以致用C++设计模式 之 “观察者模式”
- 学以致用C++设计模式 之 “门面模式“
- 学以致用C++设计模式 之 “状态模式”
- 学以致用设计模式 之 “享元模式”
- 程序员必备数据结构:堆
- 程序员必备数据结构:栈
- 【C++ STL】停下你到处找 hash_map 使用教程的手,看我的就好了
- 【C++】同样是讲解逆波兰式,为何这篇就图文并茂,通俗易懂呢?
- 学以致用C++设计模式 “建造者模式”