HGE 系列教材(5) --- 输入、声音和渲染

简介: 建议读者对应 HGE 的官方的例子:Tutorial 02 - Using input, sound and rendering 来阅读本文 渲染: 在 HGE 中,四边形是一种图元,对应了结构体 hgeQuad,另外还有三角形图元,对应 hgeTriple,为了渲染,我们现在需要使用 hgeQuad 结构体,这个结构体如下: struct hgeQuad{hgeVertex v[4

建议读者对应 HGE 的官方的例子:Tutorial 02 - Using input, sound and rendering 来阅读本文

渲染:

在 HGE 中,四边形是一种图元,对应了结构体 hgeQuad,另外还有三角形图元,对应 hgeTriple,为了渲染,我们现在需要使用 hgeQuad 结构体,这个结构体如下:

struct hgeQuad
{
hgeVertex v[4];   // 顶点描述了这个四边形
HTEXTURE   tex;   // 纹理的句柄或者为0
int        blend;   // 混合模式(blending mode)
};

HGE 中图元对应的结构体总含有这3个部分:顶点,纹理句柄,混合模式

struct hgeVertex

{

    float x, y;   // 屏幕的 x,y 坐标

    float z;   // Z-order,范围 [0, 1]

    DWORD col;   // 顶点的颜色

    float tx, ty;   // 纹理的 x,y 坐标(赋值前需要规格化坐标间隔,使得 tx,ty 取值范围在[0,1])

};

规格化坐标间隔在后面的例子中会谈到

 

1. 颜色的表示:

颜色使用32位表示,从左开始,8位为 Alpha 通道,8位红色,8位绿色,8位蓝色

对于后24位,如果全部为0,表示黑色,如果全部为1,表示白色

 

2. 定义颜色的运算:

我们把颜色看成一个四维向量,即 alpha 通道,红色,绿色,蓝色这四个分量

    <1> 颜色是可以相乘的

    颜色的相乘是对应的四个分量分别相乘的结果,即:alpha 通道的值与 alpha 通道的值相乘,红色的值与红色的值相乘,绿色的值与绿色的值相乘,蓝色的值与蓝色的值相乘。

    <2> 颜色是可以相加的

    同上,对应分量相加。

颜色的每个分量使用浮点数表示,范围是[0-1],相加操作可能导致溢出,一种处理的方式就是,如果溢出,则设定值为1。

 

3. 混合模式:

1)BLEND_COLORADD

表示顶点的颜色与纹理的纹元(texel)颜色相加,这使得纹理变亮,可见顶点颜色为 0x00000000 将不造成任何影响。

2)BLEND_COLORMUL

表示顶点的颜色与纹理的纹元颜色相乘,这使得纹理变暗,可见顶点颜色为 0xFFFFFFFF 将不造成任何影响。

注意:必须在1),2)中做一个选择,且只能选择1),2)中的一个。处理的对象是纹理颜色顶点颜色

这里有一个技巧:

如果我们需要在程序中显示一个气球,这个气球的颜色不断变化,这时候我们并不需要准备多张不同颜色的气球纹理,而只需要一张白色的气球纹理,设置 blend 为 BLEND_COLORMUL,白色的R,G,B值被表示成 1.0,也就是说,纹理颜色和顶点颜色相乘的结果是顶点的颜色,那么就可以通过修改顶点颜色,得到任意颜色的气球了。

3)BLEND_ALPHABLEND

渲染时,将对象的像素颜色(而非顶点的颜色)与当前屏幕的对应像素颜色进行 alpha 混合。alpha 混合使用到 alpha 通道,对于两个像素颜色进行如下操作,得到一个颜色:

R(C)=alpha*R(B)+(1-alpha)*R(A)
G(C)=alpha*G(B)+(1-alpha)*G(A)
B(C)=alpha*B(B)+(1-alpha)*B(A)

这里的BLEND_ALPHABLEND使用的是对象像素的颜色的 alpha 通道。可见如果对象像素颜色 alpha 通道为 0,那么结果就是只有当前屏幕的像素颜色,也就是常常说的 100% 透明,因此,我们可以理解 alpha 混合就是一个是图像透明的操作,0 表示完全透明,255 表示完全不透明。

4)BLEND_ALPHAADD

渲染时,将对象的像素颜色与当前屏幕的对应像素颜色相加,结果是有了变亮的效果。

注意:这里的3),4)必选其一,且只能选其一。处理的对象是对象像素颜色屏幕像素颜色

5)BLEND_ZWRITE

渲染时,写像素的 Z-order 到 Z-buffer

6)BLEND_NOZWRITE

渲染时,不写像素的 Z-order 到 Z-buffer

这里一样是二者选一

设置举例:

quad.blend=BLEND_ALPHAADD | BLEND_COLORMUL | BLEND_ZWRITE;   // quad 为 hgeQuad 变量

 

4. HGE 渲染

1)定义和初始化 hgeQuad 结构体:

hgeQuad quad;   // 定义四边形

2)初始化 hgeQuad 变量:

// 设置混合模式

quad.blend=BLEND_ALPHAADD | BLEND_COLORMUL | BLEND_ZWRITE;

// 加载纹理

quad.tex = pHGE->Texture_Load("particles.png");

注意,读取硬盘上资源的时候,可能会失败,因此通常都需要检查,例如:

if (!quad.tex)

{

    MessageBox(NULL, "Load particles.png", "Error", 0);

}

// 初始化顶点

for(int i=0;i<4;i++)
{
    // 设置顶点的 z 坐标
    quad.v[i].z=0.5f;
    // 设置顶点的颜色,颜色的格式为 0xAARRGGBB
    quad.v[i].col=0xFFFFA000;
}

// 这里假定载入的纹理大小为 128*128,现在截取由点(96,64),(128,64),(128,96),(96,96)这四个点围成的图形。

quad.v[0].tx=96.0/128.0; quad.v[0].ty=64.0/128.0;   // 规格化坐标间隔
quad.v[1].tx=128.0/128.0; quad.v[1].ty=64.0/128.0;
quad.v[2].tx=128.0/128.0; quad.v[2].ty=96.0/128.0;
quad.v[3].tx=96.0/128.0; quad.v[3].ty=96.0/128.0;

注意,对于 hgeQuad 结构体,顶点 quad.v[0] 表示左上那个点,quad.v[1] 表示右上的点,quad.v[2] 表示右下的点,quad.v[3] 表示左下的点。

// 设置 hgeQuad 在屏幕中的位置

float x=100.0f, y=100.0f;

quad.v[0].x=x-16; quad.v[0].y=y-16;
quad.v[1].x=x+16; quad.v[1].y=y-16;
quad.v[2].x=x+16; quad.v[2].y=y+16;

quad.v[3].x=x-16; quad.v[3].y=y+16;

 

3)设置渲染函数(render function):

System_SetState(HGE_RENDERFUNC,RenderFunc);

RenderFunc 原型和帧函数一样:

bool RenderFunc();

4)编写 RenderFunc 函数:

bool RenderFunc()
{
   pHGE->Gfx_BeginScene();   // 在如何渲染之前,必须调用这个函数
   pHGE->Gfx_Clear(0);   // 清屏,使用黑色,即颜色为 0
   pHGE->Gfx_RenderQuad(&quad);   // 渲染
   pHGE->Gfx_EndScene();   // 结束渲染,并且更新窗口
   return false;   // 必须返回 false
}

补充:Load 函数是和 Free 函数成对出现的,即在硬盘上加载了资源之后,需要 Free 它们,例如:

quad.tex = pHGE->Texture_Load("particles");

// ...

pHGE->Texture_Free(quad.tex);

 

音效:

使用音效是很简单的

1. 载入音效:

HEFFECT hEffect = pHGE->Effect_Load("sound.mp3");

2. 播放:

pHGE->Effect_PlayEx(hEffect);

或者 pHGE->Effect_Play(hEffect);

1)Effect_Play 函数只接受一个参数就是音效的句柄 HEFFECT xx;

2)Effect_PlayEx 函数较为强大,一共有四个参数:

HCHANNEL Effect_PlayEx(
                       HEFFECT effect,   // 音效的句柄
                       int volume = 100,   // 音量,100为最大,范围是[0, 100]
                       int pan = 0,   // 范围是[-100, 100],-100表示只使用左声道,100表示只使用右声道
                       float pitch = 1.0,   // 播放速度,1.0 表示正常速度,值越大播放速度越快,值越小播放越慢。这个值要大于0才有效(不可以等于0)
                       bool loop = false   // 是否循环播放,false表示不循环
                       );

 

输入:

仅仅需要调用函数 pHGE->Input_GetKeyState(HGEK_xxx); 来判断输入,应该在帧函数中调用它,例如:

bool FrameFunc()

{

    if (pHGE->Input_GetKeyState(HGEK_LBUTTOM))

       // ...

    if (pHGE->Input_GetKeyState(HGEK_UP))

       // ...

}

相关文章
|
5月前
|
vr&ar C# 图形学
从零开始的PICO开发教程(4)-- VR世界 射线传送、旋转和移动
这篇文章是PICO开发系列教程的第四部分,详细介绍了在VR世界中实现射线传送、视角旋转和人物移动的方法,包括使用Teleportation组件进行区域传送和锚点传送,通过Snap Turn Provider组件实现视角快速旋转,以及创建PlayControl脚本来控制人物移动,并通过手柄与脚本组件的交互来增强VR体验。
|
7月前
|
编解码 并行计算 算法
MPI分形图像高精度绘制程序和PC端Mandelbrot-Julia分形集预览程序
这篇文章描述了一个使用2010年技术的集群程序,该程序基于Linux + MPI + C++或Windows + .NET + C#,用于并行计算生成高分辨率BMP图像,特别是Mandelbrot和Julia集。在8台节点上,程序实现了7.31的稳定加速比,并在更大规模任务中有望提升。它支持MPI并行计算、任务日志、不同阶数的分形集生成、批处理、多线程以及优化的颜色处理等功能。创新点包括颜色表的正弦控制、动态调整运算精度、复杂颜色生成、优化的颜色更新和并发机制等。程序产生的图像样本显示了其多样性和质量。作者提供源代码,并提到设计思路可应用于类似图像生成任务。
|
7月前
|
定位技术 图形学 开发者
【用unity实现100个游戏之18】从零开始制作一个类CSGO/CS2、CF第一人称FPS射击游戏——基础篇1(附项目源码)
【用unity实现100个游戏之18】从零开始制作一个类CSGO/CS2、CF第一人称FPS射击游戏——基础篇1(附项目源码)
129 0
|
7月前
|
图形学
【用unity实现100个游戏之18】从零开始制作一个类CSGO/CS2、CF第一人称FPS射击游戏——基础篇3(附项目源码)
【用unity实现100个游戏之18】从零开始制作一个类CSGO/CS2、CF第一人称FPS射击游戏——基础篇3(附项目源码)
91 0
|
7月前
|
图形学
【用unity实现100个游戏之18】从零开始制作一个类CSGO/CS2、CF第一人称FPS射击游戏——基础篇2(附项目源码)
【用unity实现100个游戏之18】从零开始制作一个类CSGO/CS2、CF第一人称FPS射击游戏——基础篇2(附项目源码)
122 0
|
8月前
|
机器学习/深度学习 索引
Silverlight 2.5D RPG游戏技巧与特效处理:(五“.NET研究”)圣赞之HLSL渲染动画
  或许大家依旧对上一节中的“黑夜”及“梦回过去”记忆犹新,追问下去HLSL到底是何方神圣能实现如此炫酷之效果?HLSL(高级着色器语言)上海企业网站设计与制作an>作为微软的独门兵器,仅供Direct3D使用。
1394 0
一起谈.NET技术,Silverlight 2.5D RPG游戏技巧与特效处理:(五)圣赞之HLSL渲染动画
  或许大家依旧对上一节中的“黑夜”及“梦回过去”记忆犹新,追问下去HLSL到底是何方神圣能实现如此炫酷之效果?HLSL(高级着色器语言)作为微软的独门兵器,仅供Direct3D使用。Silverlight无比幸运,从第二个版本开始便已获得了这把旷世利器,虽然目前仅能发挥其不到3层之功力,不过前辈Moonlight近期已向世界宣布全面突破技术壁垒,HLSL的威力提升至7层左右。
1164 0
Silverlig“.NET研究”ht 2.5D RPG游戏技巧与特效处理:(三)动态光影
  通常来说,只要谈到影子及影子制作,首先想到的不外乎3D。游戏中的影子设计大致可分为硬实现和软实现两种,比如像“游戏影子制作技术”这篇文章所谈到3D游戏影子制作方案Projective Shadow、Shadow Map以及Shadow Volume均属于硬实现。
1040 0
|
算法 C# 计算机视觉
Win8Metro(C#)数字图像处理--2.7图像伪彩色
原文:Win8Metro(C#)数字图像处理--2.7图像伪彩色  2.7图像伪彩色函数 [函数名称] 图像伪彩色函数PseudoColorProcess(WriteableBitmap src) [算法说明]   伪彩色是为改善视觉效果,利用计算机图像增强技术对图像的灰度赋予的不同假色彩,即,将一张灰度图转化为彩色图。
1115 0