topameng's profileQuake3 启示录PhotosBlogListsMore ![]() | Help |
|
August 22 tga图像文件格式读取
quake3 中读取 tga 图像代码:
name 要加载的图片名称. 指向pic 返回的 tga 图片像素数据.width 返回图片宽度.height 返回图片高度
ri.FS_ReadFile 读取文件,并返回文件内容指针 ri.FS_FreeFile 释放文件内容缓存
ri.Malloc 分配内存
typedef struct _TargaHeader
{ unsigned char id_length, colormap_type, image_type; unsigned short colormap_index, colormap_length; unsigned char colormap_size; unsigned short x_origin, y_origin, width, height; unsigned char pixel_size, attributes; } TargaHeader; static void LoadTGA ( const char *name, byte **pic, int *width, int *height) { int columns, rows, numPixels; byte *pixbuf; int row, column; byte *buf_p; byte *buffer; TargaHeader targa_header; byte *targa_rgba; *pic = NULL;
// load the file
ri.FS_ReadFile ( ( char * ) name, (void **)&buffer); if (!buffer) { return; } buf_p = buffer;
targa_header.id_length = *buf_p++;
targa_header.colormap_type = *buf_p++; //如果colormap_type为0从18位开始为图像数据 targa_header.image_type = *buf_p++; // 第三个字节为文件类型 targa_header.colormap_index = LittleShort ( *(short *)buf_p ); //对于 win32 LittleShort 是空的宏
buf_p += 2; targa_header.colormap_length = LittleShort ( *(short *)buf_p ); buf_p += 2; targa_header.colormap_size = *buf_p++; targa_header.x_origin = LittleShort ( *(short *)buf_p ); //8 图像 x 坐标起始位置 buf_p += 2; targa_header.y_origin = LittleShort ( *(short *)buf_p ); //10 图像 y 坐标起始位置 buf_p += 2; targa_header.width = LittleShort ( *(short *)buf_p ); //12 图像宽度 buf_p += 2; targa_header.height = LittleShort ( *(short *)buf_p ); //14 图像高度 buf_p += 2; targa_header.pixel_size = *buf_p++; //16 图像每像素存储占用位(bit)数 targa_header.attributes = *buf_p++; //17 //2 - 未压缩的,rgb 图像 //3 - 未压缩的,黑白图像 //10 - runlength 编码的 rgb 图像 if (targa_header.image_type!=2&& targa_header.image_type!=10&& targa_header.image_type != 3 ) { ri.Error (ERR_DROP, "LoadTGA: Only type 2 (RGB), 3 (gray), and 10 (RGB) TGA images supported\n"); } //该字段的内容或者为 0 或者为 1,0 表示没有颜色表,1 表示颜色表存在.格式 2,3,10 是无颜色表的
if ( targa_header.colormap_type != 0 ) { ri.Error( ERR_DROP, "LoadTGA: colormaps not supported\n" ); } //图像每像素存储占用位(bit)数
if ( ( targa_header.pixel_size != 32 && targa_header.pixel_size != 24 ) && targa_header.image_type != 3 ) { ri.Error (ERR_DROP, "LoadTGA: Only 32 or 24 bit images supported (no colormaps)\n"); } columns = targa_header.width;
rows = targa_header.height; numPixels = columns * rows; //像素个数 if (width)
*width = columns; if (height) *height = rows; targa_rgba = (byte *)ri.Malloc (numPixels*4); //分配内存保存图像像素数据
*pic = targa_rgba; if (targa_header.id_length != 0)
buf_p += targa_header.id_length; // skip TARGA image comment if ( targa_header.image_type==2 || targa_header.image_type == 3 )
{ // Uncompressed RGB or gray scale image for(row=rows-1; row>=0; row--) { pixbuf = targa_rgba + row*columns*4; for(column=0; column<columns; column++) { unsigned char red,green,blue,alphabyte; switch (targa_header.pixel_size) { case 8:
blue = *buf_p++; green = blue; red = blue; *pixbuf++ = red; *pixbuf++ = green; *pixbuf++ = blue; *pixbuf++ = 255; break; case 24:
blue = *buf_p++; green = *buf_p++; red = *buf_p++; *pixbuf++ = red; *pixbuf++ = green; *pixbuf++ = blue; *pixbuf++ = 255; break; case 32: blue = *buf_p++; //tga 存放像素以BGRA 顺序。我们需要转换为 RGBA 顺序 green = *buf_p++; red = *buf_p++; alphabyte = *buf_p++; *pixbuf++ = red; *pixbuf++ = green; *pixbuf++ = blue; *pixbuf++ = alphabyte; break; default: ri.Error( ERR_DROP, "LoadTGA: illegal pixel_size '%d' in file '%s'\n", targa_header.pixel_size, name ); break; } } } } else if (targa_header.image_type==10) { // Runlength encoded RGB images unsigned char red,green,blue,alphabyte,packetHeader,packetSize,j; red = 0;
green = 0; blue = 0; alphabyte = 0xff; for(row=rows-1; row>=0; row--)
{ pixbuf = targa_rgba + row*columns*4; for(column=0; column<columns; ) { packetHeader= *buf_p++; packetSize = 1 + (packetHeader & 0x7f); if (packetHeader & 0x80) { // run-length packet switch (targa_header.pixel_size) { case 24: blue = *buf_p++; green = *buf_p++; red = *buf_p++; alphabyte = 255; break; case 32: blue = *buf_p++; green = *buf_p++; red = *buf_p++; alphabyte = *buf_p++; break; default: ri.Error( ERR_DROP, "LoadTGA: illegal pixel_size '%d' in file '%s'\n", targa_header.pixel_size, name ); break; } for(j=0;j<packetSize;j++)
{ *pixbuf++=red; *pixbuf++=green; *pixbuf++=blue; *pixbuf++=alphabyte; column++; if (column==columns) { // run spans across rows column=0; if (row>0) row--; else goto breakOut; pixbuf = targa_rgba + row*columns*4; } } } else { // non run-length packet for(j=0;j<packetSize;j++) { switch (targa_header.pixel_size) { case 24: blue = *buf_p++; green = *buf_p++; red = *buf_p++; *pixbuf++ = red; *pixbuf++ = green; *pixbuf++ = blue; *pixbuf++ = 255; break; case 32: blue = *buf_p++; green = *buf_p++; red = *buf_p++; alphabyte = *buf_p++; *pixbuf++ = red; *pixbuf++ = green; *pixbuf++ = blue; *pixbuf++ = alphabyte; break; default: ri.Error( ERR_DROP, "LoadTGA: illegal pixel_size '%d' in file '%s'\n", targa_header.pixel_size, name ); break; } column++; if (column==columns) { // pixel packet run spans across rows column=0; if (row>0) row--; else goto breakOut; pixbuf = targa_rgba + row*columns*4; } } } } breakOut:; } } // instead we just print a warning if (targa_header.attributes & 0x20) { ri.Printf( PRINT_WARNING, "WARNING: '%s' TGA file header declares top-down image, ignoring\n", name); } ri.FS_FreeFile (buffer); } August 06 quake3 使用到的 opengl 函数说明对于opengl 扩展函数必须在初始化窗口结束后才能使用 wglGetProcAddress 获得 如果, 2.void ( APIENTRY * glClientActiveTextureARB )( GLenum texture ); 关闭多重纹理:禁用所有非GL_TEXTURE0_ARB层纹理,最后激活GL_TEXTURE0_ARB纹理 对应的头文件 qgl.h : quake 中采用 q+opengl函数名 替代被使用的opengl函数 extern void ( APIENTRY * qglMultiTexCoord2fARB )( GLenum texture, GLfloat s, GLfloat t ); /*opgl1.0版本扩展函数 为了方便指定包含多组纹理坐标的顶点数组,opengl提供了命令glClientActiveTexture。应用程序使用glTexCoordPointer()指定纹理坐标数组时,Opengl将这组纹理坐标分配给glClientActiveTexture指定的纹理单元 /* extern void ( APIENTRY * qglActiveTextureARB )( GLenum texture ); extern void ( APIENTRY * qglClientActiveTextureARB )( GLenum texture ); /* */ extern void ( APIENTRY * qglLockArraysEXT) (GLint, GLint); extern void ( APIENTRY * qglUnlockArraysEXT) (void); extern void ( APIENTRY * qglAccum )(GLenum op, GLfloat value); extern void ( APIENTRY * qglAlphaFunc )(GLenum func, GLclampf ref); extern GLboolean ( APIENTRY * qglAreTexturesResident )(GLsizei n, const GLuint *textures, GLboolean *residences); extern void ( APIENTRY * qglArrayElement )(GLint i); extern void ( APIENTRY * qglBegin )(GLenum mode); /* tells OpenGL to bind the named texture texture to a texture target 将纹理名字texture代表的纹理绑定到纹理目标上。 target: GL_TEXTURE_1D 或者 GL_TEXTURE_2D,代表纹理的维数 texture: 一个数字用来绑定并代表一个纹理目标。 使用它来切换纹理 */ extern void ( APIENTRY * qglBindTexture )(GLenum target, GLuint texture); extern void ( APIENTRY * qglBitmap )(GLsizei width, GLsizei height, GLfloat xorig, GLfloat yorig, GLfloat xmove, GLfloat ymove, const GLubyte *bitmap); /* 混合方程: c = (src * sfactor) + (dst * dfactor)
例如:半透明效果 glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA); 设: dst = (1.0f,0.0f,0.0f,0.0f) red src = (0.0f,0.0f,1.0f,0.3f) blue sfactor = 源Alpha值 = 0.3f dfactor = 1 - 源Alpha值 = 1 - 0.3f 则最终混合后颜色: c = (blue * 0.3f) + (red * 0.7f) sfactor 是输入的片元颜色值混合参数。dfactor 是目前帧缓存中的像素颜色值混合参数 */ extern void ( APIENTRY * qglBlendFunc )(GLenum sfactor, GLenum dfactor); extern void ( APIENTRY * qglCallList )(GLuint list); extern void ( APIENTRY * qglCallLists )(GLsizei n, GLenum type, const GLvoid *lists); /* 清空帧缓存。mask 可以设置为GL_COLOR_BUFFER_BIT 清空颜色缓存 GL_DEPTH_BUFFER_BIT 清空深度缓存 GL_STENCIL_BUFFER_BIT 清空模板缓存 例如: glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT ) */ extern void ( APIENTRY * qglClear )(GLbitfield mask); extern void ( APIENTRY * qglClearAccum )(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha); /* 指定glClear 清空颜色缓存时使用的颜色,取值范围 0.0-1.0 例如: qglClearColor( 1, 0, 0.5, 1 ) */ extern void ( APIENTRY * qglClearColor )(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha); /*glClearDepth 指定 glClear 函数清除深度缓存使用的深度值 当调用glClear(GL_DEPTH_BUFFER_BIT)时清空深度缓存写入深度值depth,如果不通过glClearDepth设置,默认写入最大的深度值 例如: glClearDepth( 1.0f ) */ extern void ( APIENTRY * qglClearDepth )(GLclampd depth); extern void ( APIENTRY * qglClearIndex )(GLfloat c); extern void ( APIENTRY * qglClearStencil )(GLint s); extern void ( APIENTRY * qglClipPlane )(GLenum plane, const GLdouble *equation); extern void ( APIENTRY * qglColor3b )(GLbyte red, GLbyte green, GLbyte blue); extern void ( APIENTRY * qglColor3bv )(const GLbyte *v); extern void ( APIENTRY * qglColor3d )(GLdouble red, GLdouble green, GLdouble blue); extern void ( APIENTRY * qglColor3dv )(const GLdouble *v); extern void ( APIENTRY * qglColor3f )(GLfloat red, GLfloat green, GLfloat blue); extern void ( APIENTRY * qglColor3fv )(const GLfloat *v); extern void ( APIENTRY * qglColor3i )(GLint red, GLint green, GLint blue); extern void ( APIENTRY * qglColor3iv )(const GLint *v); extern void ( APIENTRY * qglColor3s )(GLshort red, GLshort green, GLshort blue); extern void ( APIENTRY * qglColor3sv )(const GLshort *v); extern void ( APIENTRY * qglColor3ub )(GLubyte red, GLubyte green, GLubyte blue); extern void ( APIENTRY * qglColor3ubv )(const GLubyte *v); extern void ( APIENTRY * qglColor3ui )(GLuint red, GLuint green, GLuint blue); extern void ( APIENTRY * qglColor3uiv )(const GLuint *v); extern void ( APIENTRY * qglColor3us )(GLushort red, GLushort green, GLushort blue); extern void ( APIENTRY * qglColor3usv )(const GLushort *v); extern void ( APIENTRY * qglColor4b )(GLbyte red, GLbyte green, GLbyte blue, GLbyte alpha); extern void ( APIENTRY * qglColor4bv )(const GLbyte *v); extern void ( APIENTRY * qglColor4d )(GLdouble red, GLdouble green, GLdouble blue, GLdouble alpha); extern void ( APIENTRY * qglColor4dv )(const GLdouble *v); extern void ( APIENTRY * qglColor4f )(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha); extern void ( APIENTRY * qglColor4fv )(const GLfloat *v); extern void ( APIENTRY * qglColor4i )(GLint red, GLint green, GLint blue, GLint alpha); extern void ( APIENTRY * qglColor4iv )(const GLint *v); extern void ( APIENTRY * qglColor4s )(GLshort red, GLshort green, GLshort blue, GLshort alpha); extern void ( APIENTRY * qglColor4sv )(const GLshort *v); extern void ( APIENTRY * qglColor4ub )(GLubyte red, GLubyte green, GLubyte blue, GLubyte alpha); extern void ( APIENTRY * qglColor4ubv )(const GLubyte *v); extern void ( APIENTRY * qglColor4ui )(GLuint red, GLuint green, GLuint blue, GLuint alpha); extern void ( APIENTRY * qglColor4uiv )(const GLuint *v); extern void ( APIENTRY * qglColor4us )(GLushort red, GLushort green, GLushort blue, GLushort alpha); extern void ( APIENTRY * qglColor4usv )(const GLushort *v); extern void ( APIENTRY * qglColorMask )(GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha); extern void ( APIENTRY * qglColorMaterial )(GLenum face, GLenum mode); /*提交颜色数组供OpenGL使用 size: 数据大小 . 如:4 type: 数据类型. 如:GL_UNSIGNED_BYTE ,颜色数据针对 GL_UNSIGNED_BYTE 做了优化。 stride: 如果数据是紧密连接指定其为0,否则为颜色数据之间的跨距 pointer: 数组的位置 例如: qglColorPointer( 4,GL_UNSIGNED_BYTE,0,colors); */ extern void ( APIENTRY * qglColorPointer )(GLint size, GLenum type, GLsizei stride, const GLvoid *pointer); extern void ( APIENTRY * qglCopyPixels )(GLint x, GLint y, GLsizei width, GLsizei height, GLenum type); extern void ( APIENTRY * qglCopyTexImage1D )(GLenum target, GLint level, GLenum internalFormat, GLint x, GLint y, GLsizei width, GLint border); extern void ( APIENTRY * qglCopyTexImage2D )(GLenum target, GLint level, GLenum internalFormat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border); extern void ( APIENTRY * qglCopyTexSubImage1D )(GLenum target, GLint level, GLint xoffset, GLint x, GLint y, GLsizei width); extern void ( APIENTRY * qglCopyTexSubImage2D )(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height); /* OpenGl 面剔除特性根据填充图元面对的方向决定是否将其丢弃,使用前需要掉用 glEnable(GL_CULL_FACE) mode 参数: GL_FRONT 剔除正面 GL_BACK 剔除背面 */ extern void ( APIENTRY * qglCullFace )(GLenum mode); extern void ( APIENTRY * qglDeleteLists )(GLuint list, GLsizei range); extern void ( APIENTRY * qglDeleteTextures )(GLsizei n, const GLuint *textures); /* 深度值比较,默认为 GL_LESS 如果片元窗口空间z值小于存储的在深度缓存中的值,片元将通过深度测试。 如果参数为GL_LEQUAL, 片元窗口空间z值小于或等于存储的在深度缓存中的值,片元将通过深度测试。 这在multipass中很有用。 例如: glDepthFunc( GL_LEQUAL ) */ extern void ( APIENTRY * qglDepthFunc )(GLenum func); /* 调用glDepthMask(GL_FALSE);可将深度缓冲区设置为只读形式。 调用glDepthMask(GL_TRUE);可将深度缓冲区设置为可读可写形式 画透明物体时必须将深度缓冲区设置为只读形式.防止深度缓冲起作用,不画透明物体后面的物体 */ extern void ( APIENTRY * qglDepthMask )(GLboolean flag); /* 深度缓冲区所存储的值范围在-1.0-1.0之间。这个函数允许把一个特定的线性深度值映射到一个标准范围的窗口z坐标。窗口z值的缺省范围是0到1,分别对应近和远裁剪平面 */ extern void ( APIENTRY * qglDepthRange )(GLclampd zNear, GLclampd zFar); extern void ( APIENTRY * qglDisable )(GLenum cap); extern void ( APIENTRY * qglDisableClientState )(GLenum array); /* 只用1个函数的调用就可以替代几个函数调用:glNormal glColor glVertex 等等 mode: 指定要被渲染的图元 first: 指定从已启用数组什么位置开始 count: 表示有多少个数组元素被提取 */ extern void ( APIENTRY * qglDrawArrays )(GLenum mode, GLint first, GLsizei count); /* 指定要写入的缓存,使用双缓存时,通常只绘制后缓存,并在绘制完成后交换缓存。 还可以指定要将立体图像(电子眼镜)渲染到那个缓存(GL*LEFT 和 GL*RIGHT),以及将图像渲染到辅助缓存(GL_AUXi)中 使用单缓存时,mode默认为 GL_FRONT, 使用双缓存时,mode 默认为GL_BACK */ extern void ( APIENTRY * qglDrawBuffer )(GLenum mode); /* 绘制单个Opengl图元,mode可以是任何合法的OpenGL图元类型:GL_POINTS GL_LINES GL_TRIANGLES count: 要渲染的索引个数 type: 是数组indeces的数据类型 indices 是一个索引数组 例如: qglDrawElements( GL_TRIANGLES,numIndexes,GL_UNSIGNED_INT,indexes ); */ extern void ( APIENTRY * qglDrawElements )(GLenum mode, GLsizei count, GLenum type, const GLvoid *indices); extern void ( APIENTRY * qglDrawPixels )(GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *pixels); extern void ( APIENTRY * qglEdgeFlag )(GLboolean flag); extern void ( APIENTRY * qglEdgeFlagPointer )(GLsizei stride, const GLvoid *pointer); extern void ( APIENTRY * qglEdgeFlagv )(const GLboolean *flag); /* 设置Opengl特性的启用状态。 默认情况大多数OpenGL特性都被禁用,事实上只有两项特性默认被起用,抖动(GL_DITHER) 和多重采样(GL_MULTISMAPLE) 实际上游戏很多时候不需要抖动 GL_BLEND 混合 GL_DEPTH_TEST 深度测试 GL_LIGHTING 光照 GL_ALPHA_TEST 启用alpha测试 GL_CULL_FACE 启用面剔除 GL_TEXTURE_2D 启用2维纹理映射模式 例如: glEnable(GL_DEPTH_TEST) 启动深度测试 */ extern void ( APIENTRY * qglEnable )(GLenum cap); /* 启用Opengl客户端状态: array: GL_VERTEX_ARRAY 启用顶点数组 GL_NORMAL_ARRAY 启用法线数组 GL_TEXTURE_COORD_ARRAY 启用纹理坐标数组 GL_COLOR_ARRAY 启用颜色数组 */ extern void ( APIENTRY * qglEnableClientState )(GLenum array); extern void ( APIENTRY * qglEnd )(void); extern void ( APIENTRY * qglEndList )(void); extern void ( APIENTRY * qglEvalCoord1d )(GLdouble u); extern void ( APIENTRY * qglEvalCoord1dv )(const GLdouble *u); extern void ( APIENTRY * qglEvalCoord1f )(GLfloat u); extern void ( APIENTRY * qglEvalCoord1fv )(const GLfloat *u); extern void ( APIENTRY * qglEvalCoord2d )(GLdouble u, GLdouble v); extern void ( APIENTRY * qglEvalCoord2dv )(const GLdouble *u); extern void ( APIENTRY * qglEvalCoord2f )(GLfloat u, GLfloat v); extern void ( APIENTRY * qglEvalCoord2fv )(const GLfloat *u); extern void ( APIENTRY * qglEvalMesh1 )(GLenum mode, GLint i1, GLint i2); extern void ( APIENTRY * qglEvalMesh2 )(GLenum mode, GLint i1, GLint i2, GLint j1, GLint j2); extern void ( APIENTRY * qglEvalPoint1 )(GLint i); extern void ( APIENTRY * qglEvalPoint2 )(GLint i, GLint j); extern void ( APIENTRY * qglFeedbackBuffer )(GLsizei size, GLenum type, GLfloat *buffer); /* The glFinish function does not return until the effects of all previously called OpenGL functions are complete. Such effects include all changes to the OpenGL state, all changes to the connection state, and all changes to the framebuffer contents. 阻塞直到Opengl 执行命令结束 */ extern void ( APIENTRY * qglFinish )(void); /* */ extern void ( APIENTRY * qglFlush )(void); extern void ( APIENTRY * qglFogf )(GLenum pname, GLfloat param); extern void ( APIENTRY * qglFogfv )(GLenum pname, const GLfloat *params); extern void ( APIENTRY * qglFogi )(GLenum pname, GLint param); extern void ( APIENTRY * qglFogiv )(GLenum pname, const GLint *params); extern void ( APIENTRY * qglFrontFace )(GLenum mode); extern void ( APIENTRY * qglFrustum )(GLdouble left, GLdouble right, GLdouble bottom, GLdouble top, GLdouble zNear, GLdouble zFar); extern GLuint ( APIENTRY * qglGenLists )(GLsizei range); extern void ( APIENTRY * qglGenTextures )(GLsizei n, GLuint *textures); extern void ( APIENTRY * qglGetBooleanv )(GLenum pname, GLboolean *params); extern void ( APIENTRY * qglGetClipPlane )(GLenum plane, GLdouble *equation); extern void ( APIENTRY * qglGetDoublev )(GLenum pname, GLdouble *params); /* 返回 Opengl 错误信息 GL_NO_ERROR 没有错误. 这个常量值为0 GL_INVALID_ENUM 向 Opengl 命令传递了无效的枚举值 GL_INVALID_VALUE 向 Opengl 传递的值不再允许的范围内 GL_INVALID_OPERATION 发出的Opengl 命令非法(就当前状态而言,此函数命令不合适) GL_STACK_OVERFLOW 命令导致Opengl堆栈溢出 GL_STACK_UNDERFLOW 命令导致Opengl堆栈下溢 GL_OUT_OF_MEMORY Opengl 无法分配足够的内存来处理命令 Opengl 错误是应用程序的bug,需要修改代码。在应用程序中,通常在初始化后面以及渲染动画中的每帧后调用glGetError().为了避免影响性能通常在非生产代码中调用它 如: assert(glGetError() == GL_NO_ERROR); */ extern GLenum ( APIENTRY * qglGetError )(void); extern void ( APIENTRY * qglGetFloatv )(GLenum pname, GLfloat *params); /* 查询特定的阀值 GL_MAX_TEXTURE_SIZE 查询支持的最大纹理大小 GL_MAX_TEXTURE_UNITS 查询支持的纹理单元个数 quake3 中重定义为 GL_MAX_ACTIVE_TEXTURES_ARB GL_MAX_ELEMENTS_VRTICES 最大支持的顶点数 GL_MAX_ELEMENTS_INDICES 最大支持的索引数 GL_MAX_LIGHTS 查询支持的最大灯光数量 */ extern void ( APIENTRY * qglGetIntegerv )(GLenum pname, GLint *params); extern void ( APIENTRY * qglGetLightfv )(GLenum light, GLenum pname, GLfloat *params); extern void ( APIENTRY * qglGetLightiv )(GLenum light, GLenum pname, GLint *params); extern void ( APIENTRY * qglGetMapdv )(GLenum target, GLenum query, GLdouble *v); extern void ( APIENTRY * qglGetMapfv )(GLenum target, GLenum query, GLfloat *v); extern void ( APIENTRY * qglGetMapiv )(GLenum target, GLenum query, GLint *v); extern void ( APIENTRY * qglGetMaterialfv )(GLenum face, GLenum pname, GLfloat *params); extern void ( APIENTRY * qglGetMaterialiv )(GLenum face, GLenum pname, GLint *params); extern void ( APIENTRY * qglGetPixelMapfv )(GLenum map, GLfloat *values); extern void ( APIENTRY * qglGetPixelMapuiv )(GLenum map, GLuint *values); extern void ( APIENTRY * qglGetPixelMapusv )(GLenum map, GLushort *values); extern void ( APIENTRY * qglGetPointerv )(GLenum pname, GLvoid* *params); extern void ( APIENTRY * qglGetPolygonStipple )(GLubyte *mask); /* 查询信息 根据name的值返回不同的字符串值 GL_VENDOR: 返回OpenGL 实现的厂商 GL_VERSION:返回OpenGL 版本 GL_EXTENSISONS:返回OpenGL实现中可用的扩展 GL_RENDERER: 返回厂商特定的渲染器信息 必须具备渲染上下文时才能调用这个函数 */ extern const GLubyte * ( APIENTRY * qglGetString )(GLenum name); extern void ( APIENTRY * qglGetTexEnvfv )(GLenum target, GLenum pname, GLfloat *params); extern void ( APIENTRY * qglGetTexEnviv )(GLenum target, GLenum pname, GLint *params); extern void ( APIENTRY * qglGetTexGendv )(GLenum coord, GLenum pname, GLdouble *params); extern void ( APIENTRY * qglGetTexGenfv )(GLenum coord, GLenum pname, GLfloat *params); extern void ( APIENTRY * qglGetTexGeniv )(GLenum coord, GLenum pname, GLint *params); extern void ( APIENTRY * qglGetTexImage )(GLenum target, GLint level, GLenum format, GLenum type, GLvoid *pixels); extern void ( APIENTRY * qglGetTexLevelParameterfv )(GLenum target, GLint level, GLenum pname, GLfloat *params); extern void ( APIENTRY * qglGetTexLevelParameteriv )(GLenum target, GLint level, GLenum pname, GLint *params); extern void ( APIENTRY * qglGetTexParameterfv )(GLenum target, GLenum pname, GLfloat *params); extern void ( APIENTRY * qglGetTexParameteriv )(GLenum target, GLenum pname, GLint *params); extern void ( APIENTRY * qglHint )(GLenum target, GLenum mode); extern void ( APIENTRY * qglIndexMask )(GLuint mask); extern void ( APIENTRY * qglIndexPointer )(GLenum type, GLsizei stride, const GLvoid *pointer); extern void ( APIENTRY * qglIndexd )(GLdouble c); extern void ( APIENTRY * qglIndexdv )(const GLdouble *c); extern void ( APIENTRY * qglIndexf )(GLfloat c); extern void ( APIENTRY * qglIndexfv )(const GLfloat *c); extern void ( APIENTRY * qglIndexi )(GLint c); extern void ( APIENTRY * qglIndexiv )(const GLint *c); extern void ( APIENTRY * qglIndexs )(GLshort c); extern void ( APIENTRY * qglIndexsv )(const GLshort *c); extern void ( APIENTRY * qglIndexub )(GLubyte c); extern void ( APIENTRY * qglIndexubv )(const GLubyte *c); extern void ( APIENTRY * qglInitNames )(void); extern void ( APIENTRY * qglInterleavedArrays )(GLenum format, GLsizei stride, const GLvoid *pointer); extern GLboolean ( APIENTRY * qglIsEnabled )(GLenum cap); extern GLboolean ( APIENTRY * qglIsList )(GLuint list); extern GLboolean ( APIENTRY * qglIsTexture )(GLuint texture); extern void ( APIENTRY * qglLightModelf )(GLenum pname, GLfloat param); extern void ( APIENTRY * qglLightModelfv )(GLenum pname, const GLfloat *params); extern void ( APIENTRY * qglLightModeli )(GLenum pname, GLint param); extern void ( APIENTRY * qglLightModeliv )(GLenum pname, const GLint *params); extern void ( APIENTRY * qglLightf )(GLenum light, GLenum pname, GLfloat param); extern void ( APIENTRY * qglLightfv )(GLenum light, GLenum pname, const GLfloat *params); extern void ( APIENTRY * qglLighti )(GLenum light, GLenum pname, GLint param); extern void ( APIENTRY * qglLightiv )(GLenum light, GLenum pname, const GLint *params); extern void ( APIENTRY * qglLineStipple )(GLint factor, GLushort pattern); extern void ( APIENTRY * qglLineWidth )(GLfloat width); extern void ( APIENTRY * qglListBase )(GLuint base); /* 修改当前活动矩阵堆栈的栈顶,将栈顶矩阵替换为单位矩阵 */ extern void ( APIENTRY * qglLoadIdentity )(void); /* 修改当前活动矩阵堆栈的栈顶,将栈顶矩阵替换为矩阵m */ extern void ( APIENTRY * qglLoadMatrixd )(const GLdouble *m); //同上 extern void ( APIENTRY * qglLoadMatrixf )(const GLfloat *m); extern void ( APIENTRY * qglLoadName )(GLuint name); extern void ( APIENTRY * qglLogicOp )(GLenum opcode); extern void ( APIENTRY * qglMap1d )(GLenum target, GLdouble u1, GLdouble u2, GLint stride, GLint order, const GLdouble *points); extern void ( APIENTRY * qglMap1f )(GLenum target, GLfloat u1, GLfloat u2, GLint stride, GLint order, const GLfloat *points); extern void ( APIENTRY * qglMap2d )(GLenum target, GLdouble u1, GLdouble u2, GLint ustride, GLint uorder, GLdouble v1, GLdouble v2, GLint vstride, GLint vorder, const GLdouble *points); extern void ( APIENTRY * qglMap2f )(GLenum target, GLfloat u1, GLfloat u2, GLint ustride, GLint uorder, GLfloat v1, GLfloat v2, GLint vstride, GLint vorder, const GLfloat *points); extern void ( APIENTRY * qglMapGrid1d )(GLint un, GLdouble u1, GLdouble u2); extern void ( APIENTRY * qglMapGrid1f )(GLint un, GLfloat u1, GLfloat u2); extern void ( APIENTRY * qglMapGrid2d )(GLint un, GLdouble u1, GLdouble u2, GLint vn, GLdouble v1, GLdouble v2); extern void ( APIENTRY * qglMapGrid2f )(GLint un, GLfloat u1, GLfloat u2, GLint vn, GLfloat v1, GLfloat v2); extern void ( APIENTRY * qglMaterialf )(GLenum face, GLenum pname, GLfloat param); extern void ( APIENTRY * qglMaterialfv )(GLenum face, GLenum pname, const GLfloat *params); extern void ( APIENTRY * qglMateriali )(GLenum face, GLenum pname, GLint param); extern void ( APIENTRY * qglMaterialiv )(GLenum face, GLenum pname, const GLint *params); /* mode 可以为 GL_PROJECTION GL_MODELVIEW 或 GL_TEXTURE 选择活动矩阵堆栈: GL_PROJECTION 选择投影矩阵堆栈 GL_MODELVIEW 选择模型视点矩阵堆栈 */ extern void ( APIENTRY * qglMatrixMode )(GLenum mode); extern void ( APIENTRY * qglMultMatrixd )(const GLdouble *m); extern void ( APIENTRY * qglMultMatrixf )(const GLfloat *m); extern void ( APIENTRY * qglNewList )(GLuint list, GLenum mode); extern void ( APIENTRY * qglNormal3b )(GLbyte nx, GLbyte ny, GLbyte nz); extern void ( APIENTRY * qglNormal3bv )(const GLbyte *v); extern void ( APIENTRY * qglNormal3d )(GLdouble nx, GLdouble ny, GLdouble nz); extern void ( APIENTRY * qglNormal3dv )(const GLdouble *v); extern void ( APIENTRY * qglNormal3f )(GLfloat nx, GLfloat ny, GLfloat nz); extern void ( APIENTRY * qglNormal3fv )(const GLfloat *v); extern void ( APIENTRY * qglNormal3i )(GLint nx, GLint ny, GLint nz); extern void ( APIENTRY * qglNormal3iv )(const GLint *v); extern void ( APIENTRY * qglNormal3s )(GLshort nx, GLshort ny, GLshort nz); extern void ( APIENTRY * qglNormal3sv )(const GLshort *v); extern void ( APIENTRY * qglNormalPointer )(GLenum type, GLsizei stride, const GLvoid *pointer); extern void ( APIENTRY * qglOrtho )(GLdouble left, GLdouble right, GLdouble bottom, GLdouble top, GLdouble zNear, GLdouble zFar); extern void ( APIENTRY * qglPassThrough )(GLfloat token); extern void ( APIENTRY * qglPixelMapfv )(GLenum map, GLsizei mapsize, const GLfloat *values); extern void ( APIENTRY * qglPixelMapuiv )(GLenum map, GLsizei mapsize, const GLuint *values); extern void ( APIENTRY * qglPixelMapusv )(GLenum map, GLsizei mapsize, const GLushort *values); extern void ( APIENTRY * qglPixelStoref )(GLenum pname, GLfloat param); extern void ( APIENTRY * qglPixelStorei )(GLenum pname, GLint param); extern void ( APIENTRY * qglPixelTransferf )(GLenum pname, GLfloat param); extern void ( APIENTRY * qglPixelTransferi )(GLenum pname, GLint param); extern void ( APIENTRY * qglPixelZoom )(GLfloat xfactor, GLfloat yfactor); extern void ( APIENTRY * qglPointSize )(GLfloat size); /* Opengl可以将填充图元渲染为线段或点。 mode 可以为 GL_POINT 绘制点 GL_LINE 绘制多边形线框 GL_FILL填充多边形 face 可以为 GL_FONT GL_BACK GL_FONT_AND_BACK 它指定用于正面图元,背面图元还是两者 glPloygonMode(GL_FONT_AND_BACK,GL_FILL) */ extern void ( APIENTRY * qglPolygonMode )(GLenum face, GLenum mode); extern void ( APIENTRY * qglPolygonOffset )(GLfloat factor, GLfloat units); extern void ( APIENTRY * qglPolygonStipple )(const GLubyte *mask); //glPopAttrib此函数未使用 extern void ( APIENTRY * qglPopAttrib )(void); //glPopClientAttrib 此函数未使用 extern void ( APIENTRY * qglPopClientAttrib )(void); extern void ( APIENTRY * qglPopMatrix )(void); extern void ( APIENTRY * qglPopName )(void); extern void ( APIENTRY * qglPrioritizeTextures )(GLsizei n, const GLuint *textures, const GLclampf *priorities); //此函数未使用 extern void ( APIENTRY * qglPushAttrib )(GLbitfield mask); //此函数未使用 extern void ( APIENTRY * qglPushClientAttrib )(GLbitfield mask); extern void ( APIENTRY * qglPushMatrix )(void); extern void ( APIENTRY * qglPushName )(GLuint name); extern void ( APIENTRY * qglRasterPos2d )(GLdouble x, GLdouble y); extern void ( APIENTRY * qglRasterPos2dv )(const GLdouble *v); extern void ( APIENTRY * qglRasterPos2f )(GLfloat x, GLfloat y); extern void ( APIENTRY * qglRasterPos2fv )(const GLfloat *v); extern void ( APIENTRY * qglRasterPos2i )(GLint x, GLint y); extern void ( APIENTRY * qglRasterPos2iv )(const GLint *v); extern void ( APIENTRY * qglRasterPos2s )(GLshort x, GLshort y); extern void ( APIENTRY * qglRasterPos2sv )(const GLshort *v); extern void ( APIENTRY * qglRasterPos3d )(GLdouble x, GLdouble y, GLdouble z); extern void ( APIENTRY * qglRasterPos3dv )(const GLdouble *v); extern void ( APIENTRY * qglRasterPos3f )(GLfloat x, GLfloat y, GLfloat z); extern void ( APIENTRY * qglRasterPos3fv )(const GLfloat *v); extern void ( APIENTRY * qglRasterPos3i )(GLint x, GLint y, GLint z); extern void ( APIENTRY * qglRasterPos3iv )(const GLint *v); extern void ( APIENTRY * qglRasterPos3s )(GLshort x, GLshort y, GLshort z); extern void ( APIENTRY * qglRasterPos3sv )(const GLshort *v); extern void ( APIENTRY * qglRasterPos4d )(GLdouble x, GLdouble y, GLdouble z, GLdouble w); extern void ( APIENTRY * qglRasterPos4dv )(const GLdouble *v); extern void ( APIENTRY * qglRasterPos4f )(GLfloat x, GLfloat y, GLfloat z, GLfloat w); extern void ( APIENTRY * qglRasterPos4fv )(const GLfloat *v); extern void ( APIENTRY * qglRasterPos4i )(GLint x, GLint y, GLint z, GLint w); extern void ( APIENTRY * qglRasterPos4iv )(const GLint *v); extern void ( APIENTRY * qglRasterPos4s )(GLshort x, GLshort y, GLshort z, GLshort w); extern void ( APIENTRY * qglRasterPos4sv )(const GLshort *v); extern void ( APIENTRY * qglReadBuffer )(GLenum mode); extern void ( APIENTRY * qglReadPixels )(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLvoid *pixels); extern void ( APIENTRY * qglRectd )(GLdouble x1, GLdouble y1, GLdouble x2, GLdouble y2); extern void ( APIENTRY * qglRectdv )(const GLdouble *v1, const GLdouble *v2); extern void ( APIENTRY * qglRectf )(GLfloat x1, GLfloat y1, GLfloat x2, GLfloat y2); extern void ( APIENTRY * qglRectfv )(const GLfloat *v1, const GLfloat *v2); extern void ( APIENTRY * qglRecti )(GLint x1, GLint y1, GLint x2, GLint y2); extern void ( APIENTRY * qglRectiv )(const GLint *v1, const GLint *v2); extern void ( APIENTRY * qglRects )(GLshort x1, GLshort y1, GLshort x2, GLshort y2); extern void ( APIENTRY * qglRectsv )(const GLshort *v1, const GLshort *v2); extern GLint ( APIENTRY * qglRenderMode )(GLenum mode); extern void ( APIENTRY * qglRotated )(GLdouble angle, GLdouble x, GLdouble y, GLdouble z); extern void ( APIENTRY * qglRotatef )(GLfloat angle, GLfloat x, GLfloat y, GLfloat z); extern void ( APIENTRY * qglScaled )(GLdouble x, GLdouble y, GLdouble z); extern void ( APIENTRY * qglScalef )(GLfloat x, GLfloat y, GLfloat z); /* 裁剪测试,可以定义窗口中的一个矩形区域,并将作图限制在其中。若片元部分落在该矩形区,则剪取测试通过,否则片元被删除。超出的部分不会画出 启用裁剪测试 qglEnable(GL_SCISSOR_TEST) qglScissor( 0, 0, glConfig.vidWidth, glConfig.vidHeight ); */ extern void ( APIENTRY * qglScissor )(GLint x, GLint y, GLsizei width, GLsizei height); extern void ( APIENTRY * qglSelectBuffer )(GLsizei size, GLuint *buffer); /* 指定使用平滑着色还是恒定着色。mode 可以是 GL_SMOOTH 或 GL_FLAT。 默认为平滑着色,Opengl 在渲染时对顶点颜色执行插值计算 如果用GL_FLAT,一般使用最后一个顶点做为图元的颜色 qglShadeModel( GL_SMOOTH ); */ extern void ( APIENTRY * qglShadeModel )(GLenum mode); extern void ( APIENTRY * qglStencilFunc )(GLenum func, GLint ref, GLuint mask); extern void ( APIENTRY * qglStencilMask )(GLuint mask); extern void ( APIENTRY * qglStencilOp )(GLenum fail, GLenum zfail, GLenum zpass); extern void ( APIENTRY * qglTexCoord1d )(GLdouble s); extern void ( APIENTRY * qglTexCoord1dv )(const GLdouble *v); extern void ( APIENTRY * qglTexCoord1f )(GLfloat s); extern void ( APIENTRY * qglTexCoord1fv )(const GLfloat *v); extern void ( APIENTRY * qglTexCoord1i )(GLint s); extern void ( APIENTRY * qglTexCoord1iv )(const GLint *v); extern void ( APIENTRY * qglTexCoord1s )(GLshort s); extern void ( APIENTRY * qglTexCoord1sv )(const GLshort *v); extern void ( APIENTRY * qglTexCoord2d )(GLdouble s, GLdouble t); extern void ( APIENTRY * qglTexCoord2dv )(const GLdouble *v); extern void ( APIENTRY * qglTexCoord2f )(GLfloat s, GLfloat t); extern void ( APIENTRY * qglTexCoord2fv )(const GLfloat *v); extern void ( APIENTRY * qglTexCoord2i )(GLint s, GLint t); extern void ( APIENTRY * qglTexCoord2iv )(const GLint *v); extern void ( APIENTRY * qglTexCoord2s )(GLshort s, GLshort t); extern void ( APIENTRY * qglTexCoord2sv )(const GLshort *v); extern void ( APIENTRY * qglTexCoord3d )(GLdouble s, GLdouble t, GLdouble r); extern void ( APIENTRY * qglTexCoord3dv )(const GLdouble *v); extern void ( APIENTRY * qglTexCoord3f )(GLfloat s, GLfloat t, GLfloat r); extern void ( APIENTRY * qglTexCoord3fv )(const GLfloat *v); extern void ( APIENTRY * qglTexCoord3i )(GLint s, GLint t, GLint r); extern void ( APIENTRY * qglTexCoord3iv )(const GLint *v); extern void ( APIENTRY * qglTexCoord3s )(GLshort s, GLshort t, GLshort r); extern void ( APIENTRY * qglTexCoord3sv )(const GLshort *v); extern void ( APIENTRY * qglTexCoord4d )(GLdouble s, GLdouble t, GLdouble r, GLdouble q); extern void ( APIENTRY * qglTexCoord4dv )(const GLdouble *v); extern void ( APIENTRY * qglTexCoord4f )(GLfloat s, GLfloat t, GLfloat r, GLfloat q); extern void ( APIENTRY * qglTexCoord4fv )(const GLfloat *v); extern void ( APIENTRY * qglTexCoord4i )(GLint s, GLint t, GLint r, GLint q); extern void ( APIENTRY * qglTexCoord4iv )(const GLint *v); extern void ( APIENTRY * qglTexCoord4s )(GLshort s, GLshort t, GLshort r, GLshort q); extern void ( APIENTRY * qglTexCoord4sv )(const GLshort *v); /* 应用程序使用glTexCoorPointer()指定纹理坐标数组时,Opengl将这组纹理坐标分配给glClientActiveTexture指定的纹理单元. 定义一组纹理坐标数组,用于OpenGL的顶点数组功能 size 每个数组元素坐标数量。有效值 1-4 type 数组的数据类型.GL_FLOAT GL_INT GL_SHORT GL_DOUBLE stride 数组坐标之间的字节偏移。0 表示数据是紧密相邻的 pointer 一个指定顶点数组的数据开始位置的指针 例如: qglTexCoordPointer( 2, GL_FLOAT, 0, texcoords[0] ); */ extern void ( APIENTRY * qglTexCoordPointer )(GLint size, GLenum type, GLsizei stride, const GLvoid *pointer); /* 在进行纹理贴图时,纹理贴图可以直接贴到物体上从而覆盖物体已有的颜色,也可以和物体原有的颜色进行融合。融合是一种重要的图像处理技术,主要用于透明,发光等等效果的处理。 void glTexEnvf(GLenum target,GLenum pname,GLfloat param); target 的参数必须是GL_TEXTURE_ENV; pname的参数可以为GL_TEXTURE_ENV_MODE或GL_TEXTURE_ENV_COLOR; param可以为GL_MODULATE、GL_DECAL、GL_BLEND 、GL_ADD、GL_REPLACE 等等 */ extern void ( APIENTRY * qglTexEnvf )(GLenum target, GLenum pname, GLfloat param); extern void ( APIENTRY * qglTexEnvfv )(GLenum target, GLenum pname, const GLfloat *params); extern void ( APIENTRY * qglTexEnvi )(GLenum target, GLenum pname, GLint param); extern void ( APIENTRY * qglTexEnviv )(GLenum target, GLenum pname, const GLint *params); extern void ( APIENTRY * qglTexGend )(GLenum coord, GLenum pname, GLdouble param); extern void ( APIENTRY * qglTexGendv )(GLenum coord, GLenum pname, const GLdouble *params); extern void ( APIENTRY * qglTexGenf )(GLenum coord, GLenum pname, GLfloat param); extern void ( APIENTRY * qglTexGenfv )(GLenum coord, GLenum pname, const GLfloat *params); extern void ( APIENTRY * qglTexGeni )(GLenum coord, GLenum pname, GLint param); extern void ( APIENTRY * qglTexGeniv )(GLenum coord, GLenum pname, const GLint *params); extern void ( APIENTRY * qglTexImage1D )(GLenum target, GLint level, GLint internalformat, GLsizei width, GLint border, GLenum format, GLenum type, const GLvoid *pixels); /*qglTexImage2D 定义一个二维纹理映射。
*/ /* 提交顶点数组供opengl使用 */ /* extern int ( WINAPI * qwglChoosePixelFormat )(HDC, CONST PIXELFORMATDESCRIPTOR *); extern BOOL ( WINAPI * qwglGetDeviceGammaRamp3DFX)( HDC, LPVOID ); extern BOOL ( WINAPI * qwglCopyContext)(HGLRC, HGLRC, UINT);
没有使用 gluLookAt 函数。相机使用默认位置的方向。默认情况下,相机位于原点,镜头指向z轴负方向,向上向量为(0,1,0) August 02 去掉webbrowse控件的滚动条 // TODO: 在此处添加消息处理程序代码 对于delphi vb 类很简单: IHTMLBodyElementDisp(IHTMLDocument2(WebBrowser1.document).body).scroll:= 'no'; vc 要查询接口才能使用,相应代码如下: HRESULT hr = S_OK; IDispatch* pDocDisp = m_wndWeb.get_Document(); //m_wndWeb 为 webbrowse控件类对象 if (pDocDisp) { IHTMLDocument2* pDoc = NULL; IHTMLElement* pElement = NULL; IHTMLBodyElement* pBodyElement = NULL; hr = pDocDisp->QueryInterface(IID_IHTMLDocument2, reinterpret_cast<void **>(&pDoc)); hr = pDoc->get_body(&pElement); hr = pElement->QueryInterface(IID_IHTMLBodyElement, (void**)&pBodyElement); pBodyElement->put_scroll(::SysAllocString(L"no")); pBodyElement->Release(); pElement->Release(); pDoc->Release(); pDocDisp->Release(); } 网页中也必须有去掉滚动条的格式说明,可以参考baidu,google等网站 August 01 二叉空间分割(BSP)二叉空间分割(BSP) 1.什么是BSP树 BSP树就是用来对N维空间中的元素进行排序和查找的二叉树。BSP树表示整个空间,BSP树中的任意一个接点表示一个凸的子空间。每个接点包含一个“超平面”,将这个接点表示的空间分割成两个子空间。每个接点除了保存其两个子接点的引用以外,还可以保存一个或多个元素。
对于N维空间,超平面为N-1维的对象。通常,用BSP树来表示二维或者三维空间,这时,空间中的元素分别指的是线段和多边型。 因其强大的排序和分类功能,BSP树有着非常广泛的应用。从隐藏面剔除、光线追踪到实体建模和机器人动作规划,都能看到BSP树的身影。 2.举例
如何建立BSP树 介绍 给定三维空间中的一组多边形,我们要建立的BSP树应该包含它们当中的每一个。建立BSP树的算法是非常简单的: 1.选择分割平面 如何建立BSP树 介绍 给定三维空间中的一组多边形,我们要建立的BSP树应该包含它们当中的每一个。建立BSP树的算法是非常简单的: 1. 选择分割平面 分割平面的选择依赖于BSP树将如何被使用,以及空间中多边形的排序条件。某些情况下,使用空间中某个多边形所在的平面进行分割(叫做自动分割)。在另外一些情况下,与坐标轴垂直的平面常被用做分割平面。 在任何一种情况下,对选择分割平面的策略进行评估都是很重要的。一个很普遍的想法是让BSP树的结构尽量趋近于平衡二叉树,但是这样做是有代价的。要实现一个完全平衡的BSP树,当一个多边形与分割平面相交时,它必须被分割成两部分。一个糟糕的分割平面选择策略会产生很多这样的分割。 2. 分割多边形集合 需要根据步骤1中选择的分割平面将多边形集合分解成两个子集。如果一个多边形完全处于分割平面的一侧,只需要把它添加对应的子集中。如果与分割平面相交,先将其分成两部分,再分别添加到两个子集中。 3. 何时停止分割 判断建立BSP树的递归过程在什么条件下停止,也是与具体的应用有关的。可以在接点包含的多边形数目小于某个界限时停止,也可以当BSP树的深度超过某个界限时停止。
伪代码 这个结构体定义在下面的讨论中将被一直使用。它表示BSP树的一个接点,包含有一个分割平面,处于分割平面的多边形列表,以及指向子接点的指针。 void Buld_BSP_Tree( BSP_tree *tree, list polygons ) while( ( poly = polygons.Get_From_List() ) != 0 ) switch( result ) if( !front_list.Is->Empty_List() ) Buld_BSP_Tree函数根据以上说明的步骤递归地建立BSP树。它使用输入的多边形列表中的第一个多边形所在的平面作为分割平面,假定此列表中的每一个多边形都为凸多边形。
用平面对多边形分类也就是判断平面位于多边形的哪一边。这通常被称为前/后测试,是通过测试多边形的每一个顶点与平面的位置关系来完成的。基本的算法就是遍利多边形的每一条边,找出那些两个顶点分别位于多边形两侧的边,交点将成为分割出的两个多边形的新曾顶点。 关于实现: 下面是分割一个凸多边形的C++伪代码。 void SplitPolygon(polygon *poly, plane *part, polygon **front, polygon **back) point ptA, ptB; ptA = poly->Vertex[verNum-1]; for( size_t i = EPSILON; ++i < verNum; ) if( distB > EPSILON && distA < -EPSILON ) ptA = ptB; if( !verFront.empty() )
|
|
|