render(1)

  内容太多了,我只能分上好几个文件来存放这个的(原来绿色文字,我自己感觉看的时候不是特好,所以改了,由于文章很多格式和图片严重影响书写改进速度,所以我删除了..)

渲染器

由三维数据生成二维图像的过程就叫做渲染(rending)

基本上

2根据bsp文件中存储的玩家的位置,

来决定玩家的照相机的位置,根据配置文件的存储的这个view视口的

长,宽,远,近平面来生成这个平截头体,来判断这个与

bsp树中的这个

视锥体的六个平面与这个照相机的处理了这个,然后这个六个平面和这个pvs的处理者也

照相机的,这个六个视锥平面,来判断这个与bsp文件的相交处理,

然后相交来进行判断,

来裁剪了这个叶子节点,看不见的model了者也

对于照相机与平面的判定,如果在平面之前,那么渲染前面平面,

在渲染当前的平面

在渲染后面的平面

如果照相机在平面的后面,那么闲渲染这个后面的节点,在渲染中间的节点了,

再渲染前面的节点了,
 

比如 什么投影变换,视口裁剪等等 之类

5、 按从后到前的顺序渲染透明的面列表

点于这个六个平面的相交来进行判断

渲染器主要流程如下(我感觉 错也错不到哪里去了,改动也改不了太多了,很多再添加其实也...有的可以说比如阴影其他就算代码 改进,但是意义真的大吗?)

(“
 

渲染器前端

R_LoadEntities

加载了这个entity物体的函数
 

quake3的bsp这个文件里面里面的这个解析出来了这个灯光的处理,灯光的类型,是不是进行这个

然后对于这个灯在渲染时,来进行这个光照
 

其他的静态的模型乃是使用这个bsp文件里面存储的这个model

对于更新的这个entity,游戏逻辑部分发过来的这个粒子系统这个的更新的处理等等

然后bsp file->winding
model->mesh
flare->addflare者也
然后历经这个view的各项裁剪,例如box裁剪,sphere裁剪,等等各项裁剪者也
 

 render->根据配置文件的来配置opengl->设置视口大小->加载bsp文件

->根据 玩家位置,计算pvs潜在可视集->来找到这个brush的处理等等

+md3 model所有的这个多边形者也!


 

这里还可以加上了这个玩家武器发出的这个粒子系统者也!

找到玩家所在的房间及邻居房间+敌人模型或表示物体的模型->

  (1)表示房间多边形 数目(2)表示物体的多  边 形,(3)光源数目等等->

(1)将表示房间的多边形与表示物体或人物模型的多边形组合到一起

(2)在确定完玩家潜在能看到的多边形后->

 对于玩家生成平截头体,根据平截头体,再进一步裁剪pvs中看不见的多边形,

也有填充,比如多边形小于 配置所能渲染的多边形,就要进行细分 ->

  剩下的多边形其实就是一幁所要处理的东西了
->当对于多边形阶段完了后,对多边形进行细分

->     将要渲染的多边形进行排序,

对不透明的多边形从前往后渲染,

从后往前对透明的多边形先渲染->

  
winding细分,mesh细分,网格的细分函数
 

后端阶段

这个裁剪的处理了,对于在平面的处理

裁剪的curve的处理,对于brush的处理了
 

R_AddMarkFragments

把这些子弹的痕迹做成了这个段的处理

 R_BoxSurfaces_r

R_ColorShiftLightingBytes

这个颜色挪移的位 函数
 

渲染器后端

// all of the information needed by the back end must be

// contained in a backEndData_t. This entire structure is

// duplicated so the front and back end can run in parallel

// on an SMP machine

(翻译为“

后端所需的所有信息必须是

//包含在backEndData_t中。整个结构是

//复制,以便前后端可以并行运行

//在SMP机器上”

typedef struct {

drawSurf_t drawSurfs[MAX_DRAWSURFS];

dlight_t dlights[MAX_DLIGHTS];

trRefEntity_t entities[MAX_ENTITIES];

srfPoly_t *polys;//[MAX_POLYS];

polyVert_t *polyVerts;//[MAX_POLYVERTS];

renderCommandList_t commands;

} backEndData_t;

后置处理的这个多边形数量,

还有这个动态灯的数量

还有这个实体的数量等等

渲染命令列表


 

RE_AddDynamicLightToScene

增加动态灯光给场景中

RE_AddLightToScene

RE_AddAdditiveLightToScene

渲染场景的处理了


 

RE_RenderScene

然后渲染了场景


 

主要是更新的这个brush model

还有这个md3 model模型

还有光源部分的更新处理等等


 

我明白了这个后置阶段以后,把模型还有场景的信息全部加载进来之后

然后再进行这个细分的处理,细分到了一定的程度


 

最后到达这个后端阶段者也
多边形数目
光源数目
实体数目、多边形顶点数目
这就是每一幁所能看见的数目者也

每一次都要更新这个三者,最后消除时,直接把构成这个三个数量清0即可者也

在更新的过程中,

对于动态的灯光的更新和对于运动物体的更新等等的处理

                       ”)

初始化阶段

主要配置opengl驱动等等者也

渲染文件夹需要渲染的数据,

主要有比如roq格式的视频播放,还有字体部分,还有这个ui菜单部分等等

hud,粒子系统,3d模型,地图可见部分等等方面的东西来进行这个渲染处理了

初始化阶段

主要配置opengl驱动等等者也

主要调用的函数有

typedef struct {

// called before the library is unloaded

// if the system is just reconfiguring, pass destroyWindow = qfalse,

// which will keep the screen from flashing to the desktop.

void (*Shutdown)( qboolean destroyWindow );

// All data that will be used in a level should be

// registered before rendering any frames to prevent disk hits,

(“ ”在渲染任何帧之前注册以防止磁盘撞击???,”)

// but they can still be registered at a later time

(但他们仍然可以在以后的时间登记 )

// if necessary.

//  BeginRegistration makes any existing media pointers invalid

 ( BeginRegistration使任何现有的媒体指针无效)

//  and returns the current gl configuration, including screen width

 (并返回当前的gl配置,包括屏幕宽度)

//   and height, which can be used by the client to intelligently

 (高度,可被客户智能利用 )

//   size display elements

(显示 元素 大小  )

void (*BeginRegistration)( glconfig_t *config );

qhandle_t (*RegisterModel)( const char *name );

qhandle_t (*RegisterSkin)( const char *name );

qhandle_t (*RegisterShader)( const char *name );

qhandle_t (*RegisterShaderNoMip)( const char *name );

void (*LoadWorld)( const char *name ) ;

开始初始化时要干的,

// the vis data is a large enough block of data that we go to the trouble

( vis数据是一个足够大的数据块,我们遇到了麻烦 )

// of sharing it with the clipmodel subsystem

( 与clipmodel子系统共享它)

void (*SetWorldVisData)( const byte *vis );

然后进行pvs可见部分的处理者也

// EndRegistration will draw a tiny polygon with each texture, forcing

(EndRegistration 将为 每个 纹理 绘制 一个 小多边形,强制 )

// them to be loaded into card memory

 (它们被加载到卡片存储器中)

void (*EndRegistration)( void );

// a scene is built up by calls to R_ClearScene and the various R_Add functions.

// Nothing is drawn until R_RenderScene is called.

void (*ClearScene)( void );

void (*AddRefEntityToScene)( const refEntity_t *re );

void (*AddPolyToScene)( qhandle_t hShader , int numVerts, const polyVert_t *verts, int num );

int (*LightForPoint)( vec3_t point, vec3_t ambientLight, vec3_t directedLight, vec3_t lightDir );

void (*AddLightToScene)( const vec3_t org, float intensity, float r, float g, float b );

void (*AddAdditiveLightToScene)( const vec3_t org, float intensity, float r, float g, float b );

void (*RenderScene)( const refdef_t *fd );

void (*SetColor)( const float *rgba ); // NULL = 1,1,1,1

void (*DrawStretchPic) ( float x, float y, float w, float h,

float s1, float t1, float s2, float t2, qhandle_t hShader ); // 0 = white

// Draw images for cinematic rendering, pass as 32 bit rgba

void (*DrawStretchRaw) (int x, int y, int w, int h, int cols, int rows, const byte *data, int client, qboolean dirty);

void (*UploadCinematic) (int w, int h, int cols, int rows, const byte *data, int client, qboolean dirty);

void (*BeginFrame)( stereoFrame_t stereoFrame );

// if the pointers are not NULL, timing info will be returned

(如果指针不为NULL,则返回计时信息 )

void (*EndFrame)( int *frontEndMsec, int *backEndMsec );

这个主要是cgame部分来进行调用的

int (*MarkFragments)( int numPoints, const vec3_t *points, const vec3_t projection,

int maxPoints, vec3_t pointBuffer, int maxFragments, markFragment_t *fragmentBuffer );

int (*LerpTag) ( orientation_t *tag, qhandle_t model, int startFrame, int endFrame,

float frac, const char *tagName );

void (*ModelBounds)( qhandle_t model, vec3_t mins, vec3_t maxs );

#ifdef __USEA3D

void   (*A3D_RenderGeometry) (void *pVoidA3D, void *pVoidGeom, void *pVoidMat, void *pVoidGeomStatus);

#endif

void (*RegisterFont)(const char *fontName, int pointSize, fontInfo_t *font);

void (*RemapShader)(const char *oldShader, const char *newShader, const char *offsetTime);

qboolean (*GetEntityToken)( char *buffer, int size );

qboolean (*inPVS)( const vec3_t p1, const vec3_t p2 );

} refexport_t;

这个quake3的这个渲染这一条,居然使用的把所有的函数写成了

这个指向函数的指针的几个结构体

这样子一下子调用整个结构体里面的函数,

(2)检查opengl可能出现的错误,设置opengl的状态,

诸如缓存溢出未能初始值等等

堆栈 等等

得到显示的模式,例如320*240, 1024*768,800*600等等分辨率等等的问题

windows要初始化midi音频,使用 glide 初始化opengl

模式列表等等截屏的处理,把屏幕上的图像保存为一个jpeg图像

(3)有 显示 quake3中鼠标的箭头变成一个 枪口的样子的函数

得到了默认的状态,例如  初始化 cullface 为  裁剪 前面

开启多重纹理,清除深度缓存,

开启纹理模式

,设置opengl画图为平滑模式

开启顶点数组,

禁用混合,

开启多边形模式为

开启视口裁剪

禁用gl_face_cull

(4)输出机器上的opengl类型,例如opengl版本为多少,opengl支持的扩展等等

如果驱动支持gamma,则输出这个硬件,

否则软件支持这个位数的处理

输出纹理模式,

开启纹理字符串模式

如果硬件类型为rival显卡,

如果 smp    active这个活跃的话,那么显示出来........

如果完成了,输出完成了 gl 的检查

记录,得到了这个机器上的配置,cvar变量,从保存的机器配置上

检查opengl是不是支持多重纹理等等api函数

颜色位数等等

模版位数等等

深度位数

模式、

是否全屏,自定义的宽高等等

宽度,高度等等

明亮度,

动态光,纹理模式,动态太阳

初始化时候要加载整个关卡里面所有的图像文件,

加载一个关卡里面的模型文件,

比如 md3和这个md4文件模型的处理者也

这个md4文件的这个lod处理者也,

还有对于这个多少个骨骼的处理者也,对于这个增加了这个surface面的数量

md3和md4文件相乘了以后,然后这个来进行这个来处理者也

来表示这个模型的运动等等者也

shader文件

加载所有的这个属性文件shader.......

加载这个freetype库文件等等

用来渲染这个字体的函数

Registerskins 函数

其实就是加载这个纹理文件,

jpg,bmp,tga文件调用了这个bmp文件,jpg,tga等等文件的图像者也

加载地图文件bsp文件

1加载bsp文件

对于bsp文件的这个加载以及处理方案,

对于bsp文件中得到了这个光源,entity来抽取出来进行显示了者也


 

R_ColorShiftLightingBytes( &buf_p[j*3], &image[j*4] );

这个说什么都想象不到的者也


 

// we are about to upload textures

R_SyncRenderThread();


 

R_LoadShaders( &header->lumps[LUMP_SHADERS] );


 

R_LoadLightmaps( &header->lumps[LUMP_LIGHTMAPS] );、

加载光照贴图的处理了者也!


 

R_LoadShaders( &header->lumps[LUMP_SHADERS] );


 

R_LoadLightmaps( &header->lumps[LUMP_LIGHTMAPS] );


 

R_LoadPlanes (&header->lumps[LUMP_PLANES]);


 

R_LoadFogs( &header->lumps[LUMP_FOGS], &header->lumps[LUMP_BRUSHES], &header->lumps[LUMP_BRUSHSIDES] );


 

R_LoadSurfaces( &header->lumps[LUMP_SURFACES], &header->lumps[LUMP_DRAWVERTS], &header-

>lumps[LUMP_DRAWINDEXES] );


 

R_LoadMarksurfaces (&header->lumps[LUMP_LEAFSURFACES]);


R_LoadNodesAndLeafs (&header->lumps[LUMP_NODES], &header->lumps[LUMP_LEAFS]);


 

R_LoadSubmodels (&header->lumps[LUMP_MODELS]);


 

R_LoadVisibility( &header->lumps[LUMP_VISIBILITY] );


 

R_LoadEntities( &header->lumps[LUMP_ENTITIES] );


 

R_LoadLightGrid( &header->lumps[LUMP_LIGHTGRID] );


 

加载整个quake3整个的这个流程的处理等等了者也

对于这个分析face,分析光照贴图的分析等等


 

case MST_PATCH:

ParseMesh ( in, dv, out );

numMeshes++;

break;

case MST_TRIANGLE_SOUP:

ParseTriSurf( in, dv, out, indexes );

numTriSurfs++;

break;

case MST_PLANAR:

ParseFace( in, dv, out, indexes );

numFaces++;

break;

case MST_FLARE:

ParseFlare( in, dv, out, indexes );

numFlares++;

break;


 

out->colorInt = ColorBytes4 ( shader->fogParms.color[0] * tr.identityLight,

                         shader->fogParms.color[1] * tr.identityLight,

                         shader->fogParms.color[2] * tr.identityLight, 1.0 );

R_ColorShiftLightingBytes( &w->lightGridData[i*8], &w->lightGridData[i*8] );

R_ColorShiftLightingBytes( &w->lightGridData[i*8+3], &w->lightGridData[i*8+3] );

对于光照这个偏移了

根据视口的高度,宽度等等来生成


 

2根据bsp文件中存储的玩家的位置,

来决定玩家的照相机的位置,根据配置文件的存储的这个view视口的

长,宽,远,近平面来生成这个平截头体,来判断这个与

bsp树中的这个视锥体的六个平面与这个照相机的处理了这个

然后这个六个平面和这个pvs的处理者也

照相机的,这个六个视锥平面,来判断这个与bsp文件的相交处理,

然后相交来进行判断,

来裁剪了这个叶子节点,看不见的model了者也

对于照相机与平面的判定,如果在平面之前,那么渲染前面平面,

在渲染当前的平面

在渲染后面的平面

如果照相机在平面的后面,那么闲渲染这个后面的节点,在渲染中间的节点了,

再渲染前面的节点了,


 

5、 按从后到前的顺序渲染透明的面列表

点于这个六个平面的相交来进行判断


 

Render

 初始化这个渲染列表的命令 函数

停止渲染列表  函数

对于渲染器方面,使用控制命令来控制这个渲染状态者也,

 (

  渲染2d,

  设置颜色

  渲染3d

这几个状态,分别在ui界面时,渲染器切换到2D渲染,

进入游戏后,切换到3D渲染,

 前端,

初始化命令行者也记录总数者也

如渲染线程的状态分为场景电影,2D,3D,Buffer,画surface,画缓冲区等等

在播放游戏开始的画面视频时,在切换到视频的状态,每个状态对应的执行过程不同,例如3D的渲染3D空间的物体,2D渲染的平面的物体,场景的电影,我们把它剪成一幁一幁地画上去, 

  

交换缓存,来进行渲染者也

画缓存,

画多边形等等的处理者也

后置阶段的所有的多边形者也

线程的处理等等

线程的状态 比如

{

渲染场景,

设置颜色

DrawBuffer

Draw2D

Draw3d

}


 

线程的状态等等,例如交换缓存,提交数据,一个线程把数据准备好了,另一个进行渲染者也

不断的运行线程者也,切换线程的状态者也

渲染



 

渲染buffer

对于子弹的痕迹,还有粒子系统的处理等等


 

对于 光照贴图 的匹配,渲染的时候,比如 Patch , Triangle_soup, Planer,

case MST_PATCH:

       ParseMesh ( in, dv, out );

       numMeshes++;

        break;

case    MST_TRIANGLE_SOUP:

             ParseTriSurf( in, dv, out, indexes );

             numTriSurfs++;

              break;

case    MST_PLANAR:

               ParseFace( in, dv, out, indexes );

              numFaces++;

               break;

case MST_FLARE:

         ParseFlare( in, dv, out, indexes );

         numFlares++;

         break;

out->colorInt = ColorBytes4 (

                        shader->fogParms.color[0] * tr.identityLight,

                         shader->fogParms.color[1] * tr.identityLight,

                         shader->fogParms.color[2] * tr.identityLight, 1.0

                          );

R_ColorShiftLightingBytes(

                                          &w->lightGridData[i*8],

                                           &w->lightGridData[i*8]

                                             );

R_ColorShiftLightingBytes( &w->lightGridData[i*8+3],

                                            &w->lightGridData[i*8+3]

                                                     );

("对于 光照 这个偏移 的函数")


 

渲染3d

noise噪声的处理


 

初始化这个命令列表,

各种命令的处理,遍历

在这个最后,消除了命令列表了者也

backEndData[tr.smpFrame]->commands.used = 0;

r_firstSceneDrawSurf = 0;

r_numdlights = 0;

r_firstSceneDlight = 0;


 

r_numentities = 0;

r_firstSceneEntity = 0;


 

r_numpolys = 0;

r_firstScenePoly = 0;


 

r_numpolyverts = 0;

}


 

每一帧,清除了这个一幁之内的多边形数目

和所有的entity的数据了

渲染队列

Brush model和这个md3模型

quake3这个还有一个关于运行期间的这个glstate设置的结构......

这个乃是设置这个运行时刻的这个状态的东西

data = GLimp_RendererSleep();

if ( !data ) {

return; // all done, renderer is shutting down

}


 

renderThreadActive = qtrue;

渲染线程是否激活 的状态 可以设置的

在渲染时,来交换这个线程的数据 ,循环

交换这个线程的数据

不断的更换这个线程里面的这个数据者也

渲染视图内的多边形等等了。


 

(1)渲染器

(其实这一部分乃是在这个cgame里面定义的者也)

初始化渲染状态,渲染2d,渲染3d,渲染缓存,


 

关卡截屏的函数比如F12我记得....,对于每一关 可以 生成了截屏的图片了


 

渲染过程中

渲染命令列表


 

不断的切换渲染线程者也,

例如设置颜色,


 


 

2d部分的显示者也

渲染2d


 

字体

渲染2d的处理,,

要渲染了字体和图像了者也

freetype这个opengl的显示纹理乃是使用的这个纹理的2次方了者也,

这个乃是调用的这个把字体保存为了纹理图片,然后来显示纹理的

拉伸纹理,拉伸这个字体的处理等等

载入了这个字体的轮廓,把轮廓保存为了位图,然后来进行处理了者也!

调用显示列表来处理

保存位图,把这个转化为了这个opengl能够使用的这个纹理东西了者也

8位的亮度表示这个alpha?

绑定了字体的纹理

 计算位图中字符图像的宽度

绘制一个正方形,显示字符

然后绑定了这个纹理的宽度和这个长度,来显示的这个字体的处理了者也


 

//创建FreeType库

创建一个freetype这个字体的库?

在FreeType库中保存字体信息的类叫做face

在FreeType中使用1/64作为一个像素的高度所以我们需要缩放h来满足这个要求

设置这个face这个的尺寸了者也

然后再来创建了这个显示列表,

释放了这个freetype类,

释放了这个face


 

最后释放显示列表

最后显示这个字体的处理

字体的使用者也,使用的freetype来绘制


 

图像

StretchPic();//拉宽页面

显示一幅图像者也

设置颜色

设置2d式的状态等等


 

在显示这个文字时候,拉宽图像,文字在制定的地方渲染

对于2d的东西,例如生命值,中心的交叉点,还有弹药值等等2d的东西要不断的切换线程的状态,

从而来进行渲染者也
 

渲染器前端


 

R_LoadEntities

加载了这个entity物体了者也


 


 

quake3的bsp这个文件里面里面的这个解析出来了这个灯光的处理,灯光的类型,是不是进行这个

然后对于这个灯在渲染时,来进行这个光照


 


 

其他的静态的模型乃是使用这个bsp文件里面存储的这个model者也!

对于静态模型的这个处理怎么回事者也!

对于这个模型等等的这个处理怎么来处理的呢?


 


 


 

对于更新的这个entity,游戏逻辑部分发过来的这个粒子系统这个的更新的处理等等

然后bsp file->winding
model->mesh
flare->addflare者也
然后历经这个view的各项裁剪,例如box裁剪,sphere裁剪,等等各项裁剪者也
 

 render->根据配置文件的来配置opengl->设置视口大小->加载bsp文件

->根据玩家位置,计算pvs潜在可视集->来找到这个brush的处理等等

+md3 model所有的这个多边形者也!


 

这里还可以加上了这个玩家武器发出的这个粒子系统者也!

找到玩家所在的房间及邻居房间+敌人模型或表示物体的模型->

 (1)表示房间多边形数目(2)表示物体的多 边形,(3)光源数目等等->

(1)将表示房间的多边形与表示物体或人物模型的多边形组合到一起

(2)在确定完玩家潜在能看到的多边形后->

对于玩家生成平截头体,根据平截头体,再进一步裁剪pvs中看不见的多边形,

 剩下的多边形其实就是一幁所要处理的东西了->

    将多边形进行排序,对不透明的多边形从前往后渲染,从后往前对透明的多边形先渲染->

  当对于多边形阶段完了后,对多边形进行细分->

然后对于这一部分的顶点,进行细分者也
winding细分,mesh细分,网格的细分者也
 


 


 


 

后端阶段

这个裁剪的处理了,对于在平面的处理


 

裁剪的curve的处理,对于brush的处理了


 


 

R_AddMarkFragments


 

把这些子弹的痕迹做成了这个段的处理了

 R_BoxSurfaces_r


 


 

R_ColorShiftLightingBytes

这个颜色挪移的位了者也

渲染器后端

// all of the information needed by the back end must be

// contained in a backEndData_t. This entire structure is

// duplicated so the front and back end can run in parallel

// on an SMP machine

typedef struct {

drawSurf_t drawSurfs[MAX_DRAWSURFS];

dlight_t dlights[MAX_DLIGHTS];

trRefEntity_t entities[MAX_ENTITIES];

srfPoly_t *polys;//[MAX_POLYS];

polyVert_t *polyVerts;//[MAX_POLYVERTS];

renderCommandList_t commands;

} backEndData_t;

后置处理的这个多边形数量,

还有这个动态灯的数量

还有这个实体的数量等等

这个渲染命令列表者也


 

RE_AddDynamicLightToScene

增加动态灯光给场景中

RE_AddLightToScene

RE_AddAdditiveLightToScene

渲染场景的处理了


 

RE_RenderScene

然后渲染了场景


 

主要是更新的这个brush model

还有这个md3 model模型

还有光源部分的更新处理等等


 

我明白了这个后置阶段以后,把模型还有场景的信息全部加载进来之后

然后再进行这个细分的处理,细分到了一定的程度


 

最后到达这个后端阶段者也
多边形数目
光源数目
实体数目、多边形顶点数目
这就是每一幁所能看见的数目者也

每一次都要更新这个三者,最后消除时,直接把构成这个三个数量清0即可者也

在更新的过程中,

对于动态的灯光的更新和对于运动物体的更新等等的处理


 

model模型的处理

从bsp文件中的静态的md3 mesh模型,和这个游戏过程中加载的这个敌人的md3模型的处理等等


 

lod = (md4LOD_t *)( (byte *)header + header->ofsLODs );

这个家伙这个lod的这个处理,原来这个md4文件这个东西乃是骨骼的处理了

还有这个md3文件乃是这个网格的处理了


 

增加了这个动画的曲面surface

/ lerp all the needed bones


 

插值这个

header = (md4Header_t *)((byte *)surface + surface->ofsHeader);


 

frameSize = (int)( &((md4Frame_t *)0)->bones[ header->numBones ] );


 

frame = (md4Frame_t *)((byte *)header + header->ofsFrames +

backEnd.currentEntity->e.frame * frameSize );

oldFrame = (md4Frame_t *)((byte *)header + header->ofsFrames +

backEnd.currentEntity->e.oldframe * frameSize );


 

RB_CheckOverflow( surface->numVerts, surface->numTriangles * 3 );


 

triangles = (int *) ((byte *)surface + surface->ofsTriangles);

indexes = surface->numTriangles * 3;

baseIndex = tess.numIndexes;

baseVertex = tess.numVertexes;

for (j = 0 ; j < indexes ; j++) {

tess.indexes[baseIndex + j] = baseIndex + triangles[j];

}

tess.numIndexes += indexes;


 

//

// lerp all the needed bones

//

if ( !backlerp ) {

// no lerping needed

bonePtr = frame->bones;

} else {

bonePtr = bones;

for ( i = 0 ; i < header->numBones*12 ; i++ ) {

((float *)bonePtr)[i] = frontlerp * ((float *)frame->bones)[i]

+ backlerp * ((float *)oldFrame->bones)[i];

}

}


 


 

模型如果是水的波浪的话

对于水波浪的移动,根据法线来计算水波的颜色,从而来显示这个水面的颜色者也

波浪阶段wave的形式有几种

sin,三角形,四边形,还有其他的形,来处理者也,

根据shader文件中记录的这个wave的类型,来进行这个相应的水波的选择,来绘制

水波的移动,根据这个法线来计算水面的颜色

这个乃是使用的这个shader文件里面的东西者也


 

渲染器后端的处理

决定下了这个视口内部要渲染的多边形数目以后


 

光照的处理

从bsp这个地图的文件中找到了这个light,提取了出来了者也,

然后对于这个light的处理了这样

灯的闪烁,

在quake3游戏中可以看到了这个灯的闪烁,其实就是frare来表示的,

其实就是闪烁的一副图像而已

使用这个flare来表现这个光照的这个闪烁,

如场景中需要这个flare的话

增加这个flare,来显示者也

渲染这个flare


 


 


 


 


 

entity的光照

entity增加这个动态的光照的处理者也!

对于quake3来说,你可以观察到了这个游戏中的武器,弹药箱的下面都有点光源的

照射,这使得你在游戏中可以看的见这个的。

检查一个entity是不是收到了光?美工可以指定这个物体收不收到光照的影响,

前向光照来计算entity收到的光照的

者也!


 


 

环境光照

quake3居然还有渲染网格,来存储的环境光的值者也,

drawvertex来表示网格的一个点者也

还有一个栅格系统呢!我们要给与栅格环境光照者也,使用栅格来存储这个环境光的值啊

栅格也有lod

渲染时,预先处理栅格方面,


 

=================

R_SetupEntityLightingGrid


 

游戏中的光照

基本几何体的光照,

更新动态的光源,静态的光源不必要进行更新的处理了者也

主要是brush上面的光照


 

分为两种情况,

光照贴图和顶点光照

当然现在普遍是逐像素光照了,doom3中已经变成了这个逐像素的光照了


 

如果是这个光照贴图的光照的话


 

在这个bsp文件中

已经存储了这个光照贴图的值了


 

R_LoadLightmaps

加载了这个光照贴图的处理了者也

// create all the lightmaps

创建所有的这个光照贴图了者也


 

// if we are in r_vertexLight mode, we don't need the lightmaps at all

如果位于这个顶点光模式的话,那么不启用了这个光照贴图了


 

  
 

#define DLIGHT_AT_RADIUS 16

// at the edge of a dlight's influence, this amount of light will be added

这个动态灯光的这个弧度为16

#define DLIGHT_MINIMUM_RADIUS 16

// never calculate a range less than this to prevent huge light numbersR_DlightBmodel

Determine which dynamic lights may effect this bmodel


 

对于所有的灯的处理,检查这个灯是不是一个动态的灯,灯光如何影响了这个物体了者也

// we need to check this light

mask |= 1 << i;


 

if ( *surf->data == SF_FACE ) {

((srfSurfaceFace_t *)surf->data)->dlightBits[ tr.smpFrame ] = mask;

} else if ( *surf->data == SF_GRID ) {

((srfGridMesh_t *)surf->data)->dlightBits[ tr.smpFrame ] = mask;

} else if ( *surf->data == SF_TRIANGLES ) {

((srfTriangles_t *)surf->data)->dlightBits[ tr.smpFrame ] = mask;

}

}

  计算brush收到的光照,如果brush表面上是face,,triangle,grid网格,等等几种的处理方案者也


 

裁剪方式

typedef enum {

CT_FRONT_SIDED,

CT_BACK_SIDED,

CT_TWO_SIDED

} cullType_t;

裁剪类型,一共包括了三类,前面的裁剪,后面的裁剪

两面裁剪

裁剪面方式(裁剪前面,裁剪后面,)


 

开启视口的裁剪

开启多边形后向面的裁剪者也

多边形偏移等等

雾的处理

typedef enum {

FP_NONE, // surface is translucent and will just be adjusted properly

FP_EQUAL, // surface is opaque but possibly alpha tested

FP_LE // surface is trnaslucent, but still needs a fog pass (fog surface)

} fogPass_t;


 

雾的通过状态

没有雾

等于

小于雾

typedef struct {

vec3_t color;

float depthForOpaque;

} fogParms_t;

雾的颜色,雾的深度和透明的处理了

这个没有使用opengl的雾阶段的函数,主要是在q3map阶段来进行的处理


 

纹理图片


 

quake3主要是32位的tga图像居多,有少部分使用的8位的pcx图像,

再加上纹理的颜色,


 

使用多重纹理来保证贴图的质量等等

纹理阶段


 

例如这个

根据entity(物体)表面的shader文件里面的属性

例如图像是什么类型,(jpg bmp,tga)来,调用不同的bmp,tga,jpg等等文件

加载到内存中,这个转换纹理坐标系,quake3中的纹理坐标系和opengl不同。

需要进行转换

,根据1d,2d,3d,cube等等纹理状态,分别绑定了,生成对应的纹理

texture纹理部分的处理等等的处理

加载256色图像,16位的图像

加载bmp图像,tga图像、jpg图像文件


typedef struct {

image_t *image[MAX_IMAGE_ANIMATIONS];

int numImageAnimations;

float imageAnimationSpeed;


 

texCoordGen_t tcGen;

vec3_t tcGenVectors[2];


 

int numTexMods;

texModInfo_t *texMods;


 

int videoMapHandle;

qboolean isLightmap;

qboolean vertexLightmap;

qboolean isVideoMap;

} textureBundle_t;

根据shader文件中存储的纹理的结构,来进行对于纹理的过滤等等的处理者也

根据这个纹理的滤波状态,如点采样,双线性过滤等等给纹理进行过滤者也

对于纹理的组合

纹理的这个混合

纹理的滤波了者也


 

根据这个shader文件中的这个来计算这个水波等等其他的一些东西了者也

对于多重纹理的处理者也

We must set some things up before beginning any tesselation,


 

output = t0 * t1 or t0 + t1

t0 = most upstream according to spec

t1 = most downstream according to spec

第一趟,进行这个基本纹理的加载

第二趟,进行这个光照贴图的处理,组合或者是这个纹理的替换了

qglEnable( GL_TEXTURE_2D );

qglEnableClientState( GL_TEXTURE_COORD_ARRAY );

qglTexCoordPointer( 2, GL_FLOAT, 0, input->svars.texcoords[1] );


 

R_BindAnimatedImage( &pStage->bundle[1] );


 

R_DrawElements( input->numIndexes, input->indexes );

ProjectDlightTexture

动态光灯的投影到了纹理之中了者也

纹理的参数等等,

例如:对于shader脚本的加载,以及计算这个shader里面的东西者也

textures/liquids/lava    //表示的纹理是液体里面的岩浆

{deformVertexes wave sin 0 3 0 0.1//表示这个岩浆的属性者也

tessSize 64

{

 map textures/common/lava.tga    //岩浆图像的路径者也

}

}

等等处理,最后呈现的问题的颜色者也!
经过了纹理绑定阶段以后,光栅化以后,形成了幁缓存区,

 然后,进行对于幁缓存的处理,例如深度测试,模板等等测试
 

画surface时的情况者也

entity类型;构成的最小元素

surface一共分为种类型,这个主要是quake3渲染的部分者也

brush          ->winding->顶点缓存->画点

model             ->mesh->triangle队列-.>画三角形

flare            ->图片->使用矩形加载图片,显示

patch         ->mesh->triangle队列-.>画三角形


 

显示图像,drawworld等等

面的裁剪

环境光缩放的值


 


 

shader_cac

quake3使用shader脚本来表示物体的属性,等等,

shader脚本可以控制水波是由三角形,四边形,等等其他的属性,把他们保存下来,

水波在渲染时使用什么图元来进行显示呢?


 

天空盒

天空盒的参数等等

天空使用一个天空盒,来进行渲染者也,增加天空盒的边等等的处理者也

对于天空盒的绘制,增加了边等等的处理,纹理的映射者也

生成所有的这个云,居然还有这个云的生成啊,

生成了云的顶点了啊

初始化这个天空盒的纹理坐标了者也

天空盒这个也是在这个后置阶段细分之后的处理了者也

// go through all the polygons and project them onto

// the sky box to see which blocks on each side need

// to be drawn

RB_ClipSkyPolygons( &tess );


 

渲染器

noise这个噪声的值,计算这个噪声的值,我怀疑这个用于纹理时这个有用者也

fft,这个乃是用的这个傅里叶计算这个水面?
 

后置阶段的这个视口的参数的处理了者也


 

R_InitSkyTexCoords

** Called when a sky shader is parsed

调集这个当天空的这个shader 被建立的时候,或者分析的时候的处理等等

typedef struct {

float cloudHeight;

image_t *outerbox[6], *innerbox[6];

} skyParms_t;

天空盒的参数,

云的高度

// init zfar so MakeSkyVec works even though

// a world hasn't been bounded

// compute vector from view origin to sky side integral point

//  翻译为  初始化 zfa r使 MakeSkyVec 工作,即使

// 一个世界没有被限定

//  计算从视图原点到 天空 边积分点 的 矢量 )

input->shader->sky.cloudHeight

对于这个云的这个盒子了......

天空盒子的处理,最小值和最大值的处理

shader->sky.fullClouds )


 

增加这个天空盒的面

根据这个shader这个脚本制定的很多方面来执行命令者也

计算噪声函数,水波的函数

雾的颜色,(rgb等等),deform这个的属性,表示brush这个的形式


 

glState这个状态的绑定者

//我想这个在这个渲染器的处理之后,就能够对于阴影的处理者也!

我想阴影在这个后置渲染的后面了

阴影

阴影的处理

/*

 for a projection shadow:做一个投影的矩阵


 

 point[x] += light vector * ( z - shadow plane )

 point[y] +=

 point[z] = shadow plane


 

 1 0 light[x] / light[z]

这个阴影边的处理了,这个东西乃是使用的这个

edge这个边的处理,对于细分的处理


 

平面投影贴图  (planar projection mapping)、


 

阴影体阴影,

增加这个阴影边的数量等等


 

shadow,这个乃是使用的细分后的这个阴影啊,阴影边的总数,来渲染这个阴影边啊

细分后的阴影啊,阴影体的处理

阴影的颜色者也,动态阴影处理 

对于阴影边的设置,这个边与光源的位数

对于阴影边的增加,


 

在渲染的时候,来进行lod的处理了,细分

对于阴影体渲染来说,乃是禁用深度缓存,启用模板缓存,绘制阴影体

再启用了深度缓存,在启动模板缓存,颜色缓存,再绘制场景,绘制阴影体

最后gamma修正

gamma这个东西,我自己在gpu精粹3中见到过,这个乃是对于线性过滤,

如果不启用这个,平面光颜色就会有问题的

gpu精粹3中的这个gammma的处理

对于 crt 转化为了线性的过程中,这个显示器的结果近似为了一个指数的曲线,

这个指数被称为了gamma,常用的指数为这个2.2,表示50%,的光强像素的数据,要小于100%

光强像素放射出的光,要小于100%,光强放射强度的四分之一,gamma对于每个单独的显示设备,都是不同的

,但是2.0-2.4之间,对于这种非线性特征效果的调整,被称为gamma修正

可以调用这个window的这个gamma修正,也可以软件的gammma修正处理了者也

  这个patch乃是使用的这个曲面慢慢的填充了多边形,来达到了曲面的目的了


 


 


 

shader文件

加载所有的这个属性文件shader者也!


 

加载这个freetype库文件等等

用来渲染这个字体的处理者也!


 


 

Registerskins

其实就是加载这个纹理文件,

jpg,bmp,tga文件调用了这个bmp文件,jpg,tga等等文件的图像者也


 

加载地图文件bsp文件者也


 

InitRenderCommand


 

初始化这个渲染列表的命令者也!

typedef enum {

RC_END_OF_LIST,

RC_SET_COLOR,

RC_STRETCH_PIC,

RC_DRAW_SURFS,

RC_DRAW_BUFFER,

RC_SWAP_BUFFERS,

RC_SCREENSHOT

} renderCommand_t;

停止渲染列表


 

线程的状态

{

渲染场景,

设置颜色

DrawBuffer

Draw2D

Draw3d

}


 

对于线程的互斥锁,mutex,线程的切换,同步的处理了


 


 

线程的状态等等,例如交换缓存,提交数据,一个线程把数据准备好了,另一个进行渲染者也

不断的运行线程者也,切换线程的状态者也

渲染


 


 

渲染buffer

对于子弹的痕迹,还有粒子系统的处理等等


 

对于beginFrame之前,进行前端的处理

在一幁处理完了后,

每次不断的交换缓存,来进行渲染


 

RenderFrame,来渲染后置数据了

renderView,视口从配置文件里面得到的这个的

对于配置文件中找到了这个各种功能了


 

md3模型的顶点数目,这个纹理坐标的处理了


 


 


 


 


 

渲染3d

noise噪声的处理


 

初始化这个命令列表,

各种命令的处理

在这个最后,消除了命令列表了者也


 


 

backEndData[tr.smpFrame]->commands.used = 0;


 

r_firstSceneDrawSurf = 0;


 

r_numdlights = 0;

r_firstSceneDlight = 0;


 

r_numentities = 0;

r_firstSceneEntity = 0;


 

r_numpolys = 0;

r_firstScenePoly = 0;


 

r_numpolyverts = 0;

}


 

每一帧,清除了这个一幁之内的多边形数目

和所有的entity的数据了

渲染队列

Brush model和这个md3模型了者也

原来这个quake3这个还有一个关于运行期间的这个glstate设置的结构者也

这个乃是设置这个运行时刻的这个状态的东西者也

data = GLimp_RendererSleep();


 

if ( !data ) {

return; // all done, renderer is shutting down

}


 

renderThreadActive = qtrue;

画这个多边形者也!

在渲染时,来交换这个线程的数据者也!

交换这个线程的数据者也

不断的更换这个线程里面的这个数据者也

渲染视图内的多边形

渲染这个


 

(1)渲染器

(其实这一部分乃是在这个cgame里面定义的者也)

初始化渲染状态,渲染2d,渲染3d,渲染缓存,


 


 

关卡截屏,对于每一关生成了截屏的图片了者也

渲染过程中

渲染命令列表


 

不断的切换渲染线程者也,

例如设置颜色,


 

对于渲染器方面,使用控制命令来控制这个渲染状态者也,渲染2d,设置颜色者也

   渲染3d

这几个状态,分别在ui界面时,渲染器切换到2D渲染,

进入游戏后,切换到3D渲染,

 前端,

初始化命令行者也 记录总数者也

如渲染线程的状态分为场景电影,2D,3D,Buffer,画surface,画缓冲区等等

在播放游戏开始的画面视频时,在切换到视频的状态,每个状态对应的执行过程不同,例如3D的渲染3D空间的物体,2D渲染的平面的物体,场景的电影,我们把它剪成一幁一幁地画上去, 

  

交换缓存,来进行渲染者也

画缓存,

画多边形等等的处理者也

后置阶段的所有的多边形者也

线程的处理等等

2d部分的显示者也

渲染2d


 

字体

渲染2d的处理,,

要渲染了字体和图像了者也

freetype这个opengl的显示纹理乃是使用的这个纹理的2次方了者也,

这个乃是调用的这个把字体保存为了纹理图片,然后来显示纹理的

拉伸纹理,拉伸这个字体的处理等等

载入了这个字体的轮廓,把轮廓保存为了位图,然后来进行处理了者也!

调用显示列表来处理

保存位图,把这个转化为了这个opengl能够使用的这个纹理东西了者也

8位的亮度表示这个alpha?

绑定了字体的纹理

 计算位图中字符图像的宽度

绘制一个正方形,显示字符

然后绑定了这个纹理的宽度和这个长度,来显示的这个字体的处理了者也


 

// 创建FreeType库

创建一个freetype这个字体的库?

在FreeType库中保存字体信息的类叫做face

在FreeType中使用1/64作为一个像素的高度所以我们需要缩放h来满足这个要求

设置这个face这个的尺寸了者也

然后再来创建了这个显示列表,

释放了这个freetype类,

释放了这个face


 

最后释放显示列表

最后显示这个字体的处理

字体的使用者也,使用的freetype来绘制


 

图像

StretchPic();//拉宽页面

显示一幅图像者也

设置颜色

设置2d式的状态等等


 

在显示这个文字时候,拉宽图像,文字在制定的地方渲染

对于2d的东西,例如生命值,中心的交叉点,还有弹药值等等2d的东西要不断的切换线程的状态,

从而来进行渲染者也


 




 

对于bsp文件的这个加载以及处理方案,

对于bsp文件中得到了这个光源,entity来抽取出来进行显示了者也


 

R_ColorShiftLightingBytes( &buf_p[j*3], &image[j*4] );

这个说什么都想象不到的者也


 

// we are about to upload textures

// (""我们讨论 关于 上传 纹理“”)

R_SyncRenderThread();

(“ 同步渲染线程 ”)
 

R_LoadShaders (

                       &header->lumps[LUMP_SHADERS]

                              );

R_LoadLightmaps ( 

                             &header->lumps[LUMP_LIGHTMAPS]

                             );、

(“加载 光照贴图 的 函数”)

R_LoadShaders( &header->lumps[LUMP_SHADERS] );

R_LoadLightmaps(  &header->lumps[LUMP_LIGHTMAPS] );

R_LoadPlanes (    &header->lumps[LUMP_PLANES]      );

R_LoadFogs  (

                       &header->lumps[LUMP_FOGS],

                       &header->lumps[LUMP_BRUSHES],

                       &header->lumps[LUMP_BRUSHSIDES]

                        );

R_LoadSurfaces  (

                     &header->lumps[LUMP_SURFACES],

                     &header->lumps[LUMP_DRAWVERTS],

                     &header->lumps[LUMP_DRAWINDEXES]

                              );


 

R_LoadMarksurfaces     (     &header->lumps[LUMP_LEAFSURFACES] );


R_LoadNodesAndLeafs (      &header->lumps[LUMP_NODES],

                                           &header->lumps[LUMP_LEAFS]

                                          );


 

R_LoadSubmodels (

                                      &header->lumps[LUMP_MODELS]

                                  );


 

R_LoadVisibility  (

                            &header->lumps[LUMP_VISIBILITY]

                              );


 

R_LoadEntities  (      &header->lumps [LUMP_ENTITIES]      );


 

R_LoadLightGrid ( 

                                    &header->lumps[LUMP_LIGHTGRID]

                                   );

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值