2015年1月13日星期二(11-1深度缓存和可见性简介)

2023-11-10


新的一年,开始新的篇章,终于进入第11章了。必须首要搞这个。争取今年搞完,我也相信,会对3D学习不是浪费时间。而是内力提升。

在以前,用画家算法进行多边形排序,即根据渲染列表中的每个多边形的平均、最小或最大值进行排序,然后,再从后到前的顺序绘制多边形。

大多数情况下,是正确的。但是,在多边形相互贯通、包含大小各异的几何体时,画家算法可能失效,

引入Z缓存(即像素级画家算法):将对像素进行排序,

算法如下:

For(渲染列表中的每个多边形) begin

 1,对其进行光栅化,生成xi,yi,zi,

For(每组xi,yi,zi)

2,if( zi < zbuffer[xi,yi], then

 Zbuffer[xi,yi]= zi,然后将像素显示到屏幕上,Plot(xi,yi).

End for

 

获取多边形的Z值方法:

根据多边形所在的平面;ax+by+cz+d=0.求得z值。

然后可以进行插值运算。

 

Z缓存的问题:

上述三角形的(x,y,z)是3D空间推导进行,即世界做表空间或相机坐标空间,而Z缓冲是在屏幕空间的投影坐标(x_screen,y_screen),而x_screen = d * x/z; y_screen= d * y /z,可知,Z值不是线性的,而1/z是线性的。

首先定义z缓存的变量和数据结构

//为z缓存数据结构定义的常量

#define  ZBUFFER_ATTR_16BIT                     16

#define  ZBUFFER_ATTR_32BIT                     32

 

//Z缓存数据结构

typedef struct ZBUFFERV1_TYP

{

    int               attr;             //z缓存的属性,位或位

    UCHAR    *        zbuffer;     //指向Z缓存的指针

    int               width;            //z缓存的宽度,单位为像素

    int               height;           //z缓存的高度,单位为像素

    int               sizeq;            //实际的四元组大小(每个四元组为个字节)

} ZBUFFERV1, *ZBUFFERV1_PTR;

 

 

创建z缓存

 

 

int DDRAW_LIUSHUIXIAN_TEXTURE::Create_Zbuffer(ZBUFFERV1_PTRzb, int width, int height, int attr)

{

    //指针zb是否有效

    if(!zb )

         return0;

 

    //是否已经给zb指向的ZBUFFERV1分配了内存

    if(zb->zbuffer)

         free(zb->zbuffer);

 

    //设置字段

    zb->width                              =width;

    zb->height                             =height;

    zb->attr                           =attr;

 

    //z缓存是位的还是位的

    if(attr & ZBUFFER_ATTR_16BIT)

    {

         //计算四元组数

         zb->sizeq                          =width * height/ 2;

 

         //分配内存

         if(( zb->zbuffer= ( UCHAR * ) malloc(width * height* sizeof( SHORT) ) ) )

             return1;

         else

             return0;

    }

    else

    if(attr & ZBUFFER_ATTR_32BIT)

    {

         //计算四元组数

         zb->sizeq                          =width * height;

 

         //分配内存

         if(( zb->zbuffer= ( UCHAR * ) malloc(width * height* sizeof( INT) ) ) )

             return1;

         else

             return0;

    }

    else

         return0;

}

 

每次写入一个32位UINT值的方式填充/设置内存

void ddraw_math::Mem_Set_QUAD( void* dest, USHORTdata, int count )

{

    _asm

    {

         movedi, dest     ;

         movecx, count    ;

         moveaxdata    ;

         repstosd         ;

    }

}

清空/填充z缓存

 

 

void DDRAW_LIUSHUIXIAN_TEXTURE::Clear_Zbufffer(ZBUFFERV1_PTRzb, UINT data)

{

    ddraw_mathmath;

    math.Mem_Set_QUAD( ( void* ) zb->zbuffer,data, zb->sizeq );

}

 

删除z缓存,

 

int DDRAW_LIUSHUIXIAN_TEXTURE::Delete_Zbuffer(ZBUFFERV1_PTRzb)

{

    if(zb )

    {

         //释放内存

         if(zb->zbuffer)

             free(zb->zbuffer);

 

         //清除内存中的数据

         memset(( void * ) zb,0, sizeof( ZBUFFERV1) );

         return1;

    }

    else

         return0;

}

 

首先,更新恒定Shader处理函数

以GouraudShader处理函数,不进行RGB颜色插值,每个像素都使用相同的颜色,并将对某个颜色分量进行插值的代码改为对Z值进行插值的代码。

 

 

void ddraw_math::Draw_Triangle_2DZB_16(                  POLYF4DV2_PTR                  face,         //指向多边形面的指针

                                                             UCHAR                     *    _dest_buffer,//指向视频缓存的指针

                                                             int                           mem_pitch,   //每行占用多少字节(,640

                                                             UCHAR                     *    _zbuffer,    //指向z缓存的指针

                                                             int                           zpitch )

中,把U,I坐标改为Z坐标,其余没变。

 

对于Gouraud shader,只需加入z值的代码即可。

 

 

void ddraw_math::Draw_Gouraud_TriangleZB16( POLYF4DV2_PTR    face,        //指向多边形的指针

                                                                  UCHAR    *       _dest_buffer,//指向视频缓存的指针

                                                                  int               mem_pitch, //每行占据的字节数

                                                                  UCHAR                     *    _zbuffer,    //指向z缓存的指针

                                                                                                                                        int                            zpitch ) //z缓存每行占用的字节数

 

 

对于支持固定着色的纹理映射函数。,也是插入Z代码,并Z缓存比较。

 

void ddraw_math::Draw_Textured_TriangleZB16(    POLYF4DV2_PTR     face,        //指向多边形的指针

                                                                  UCHAR    *       _dest_buffer,//指向视频缓存的指针

                                                                  int               mem_pitch, //每行占据的字节数

                                                                  UCHAR        *   _zbuffer,    //指向z缓存的指针

                                                                                                                                        int               zpitch ) //z缓存每行占用的字节数

 

对于支持恒定着色的纹理映射函数,更新Z缓冲将通过Z缓冲的绘制

 

void ddraw_math::Draw_Textured_TriangleFSZB16POLYF4DV2_PTR     face,        //指向多边形的指针

                                                                  UCHAR    *       _dest_buffer,//指向视频缓存的指针

                                                                  int               mem_pitch, //每行占据的字节数

                                                                  UCHAR        *   _zbuffer,    //指向z缓存的指针

                                                                                                                                        int               zpitch) //z缓存每行占用的字节数

对于接下来进行更新渲染列表函数,进行绘制的各个路径。

 

void DDRAW_LIUSHUIXIAN_TEXTURE::   Draw_RENDERLIST4DV2_SolidZB16(ddraw_math math2,RENDERLIST4DV2_PTR rend_list,UCHAR * video_buffer,int lpitch,

                                                                          UCHAR    *                 zbuffer,

                                                                          int                        zpitch)

{

    POLYF4DV2                 face;

 

    for(int poly =0; poly < rend_list->num_polys; poly++)

    {

         //获得当前多边形

         POLYF4DV2_PTR         curr_poly                 = rend_list->poly_ptrs[poly];

 

 

         //当且仅当多边形没有被剔除或者裁剪掉,同时处于活动状态且可见时,才对其进行变换)

         if(!( curr_poly->state& POLY4DV2_STATE_ACTIVE ) ||

             ( curr_poly->state& POLY4DV2_STATE_CLIPPED ) ||

             ( curr_poly->state& POLY4DV2_STATE_BACKFACE ) )

             continue;    //进入下一个多边形

 

         //先测试纹理,

         if(rend_list->poly_ptrs[poly]->attr& POLY4DV2_ATTR_SHADE_MODE_TEXTURE )

         {

             face.tvlist[0].x                    =( int ) rend_list->poly_ptrs[poly]->tvlist[0].x;

             face.tvlist[0].y                   = ( int) rend_list->poly_ptrs[poly]->tvlist[0].y;

             face.tvlist[0].z                   = ( int) rend_list->poly_ptrs[poly]->tvlist[0].z;

             face.tvlist[0].u0                  = ( int) rend_list->poly_ptrs[poly]->tvlist[0].u0;

             face.tvlist[0].v0                  = ( int) rend_list->poly_ptrs[poly]->tvlist[0].v0;

 

             face.tvlist[1].x                   = ( int) rend_list->poly_ptrs[poly]->tvlist[1].x;

             face.tvlist[1].y                   = ( int) rend_list->poly_ptrs[poly]->tvlist[1].y;

             face.tvlist[1].z                   =( int ) rend_list->poly_ptrs[poly]->tvlist[1].z;

             face.tvlist[1].u0                  = ( int) rend_list->poly_ptrs[poly]->tvlist[1].u0;

             face.tvlist[1].v0                  = ( int) rend_list->poly_ptrs[poly]->tvlist[1].v0;

 

             face.tvlist[2].x                   = ( int) rend_list->poly_ptrs[poly]->tvlist[2].x;

             face.tvlist[2].y                   = ( int) rend_list->poly_ptrs[poly]->tvlist[2].y;

             face.tvlist[2].z                   = ( int) rend_list->poly_ptrs[poly]->tvlist[2].z;

             face.tvlist[2].u0                  = ( int) rend_list->poly_ptrs[poly]->tvlist[2].u0;

             face.tvlist[2].v0                  = ( int) rend_list->poly_ptrs[poly]->tvlist[2].v0;

 

             face.texture                       =rend_list->poly_ptrs[poly]->texture;

 

             if(rend_list->poly_ptrs[poly]->attr& POLY4DV2_ATTR_SHADE_MODE_CONSTANT )

             {

                  math2.Draw_Textured_TriangleZB16(& face, video_buffer,lpitch, zbuffer,zpitch );

             }

             else

             {

                  face.lit_color[0]              = rend_list->poly_ptrs[poly]->lit_color[0];

 

                  math2.Draw_Textured_TriangleFSZB16(& face, video_buffer,lpitch, zbuffer,zpitch );

             }

 

         }

         else

             if(( rend_list->poly_ptrs[poly]->attr& POLY4DV2_ATTR_SHADE_MODE_FLAT )

                  || ( rend_list->poly_ptrs[poly]->attr& POLY4DV2_ATTR_SHADE_MODE_CONSTANT ) )

             {

                  //使用固定着色

                  face.lit_color[0]              = rend_list->poly_ptrs[poly]->lit_color[0];

 

                  //设置顶点坐标

                  face.tvlist[0].x               =( float ) rend_list->poly_ptrs[poly]->tvlist[0].x;

                  face.tvlist[0].y               =( float ) rend_list->poly_ptrs[poly]->tvlist[0].y;

                  face.tvlist[0].z               =( float ) rend_list->poly_ptrs[poly]->tvlist[0].z;

 

                  face.tvlist[1].x               =( float ) rend_list->poly_ptrs[poly]->tvlist[1].x;

                  face.tvlist[1].y               =( float ) rend_list->poly_ptrs[poly]->tvlist[1].y;

                  face.tvlist[1].z               =( float ) rend_list->poly_ptrs[poly]->tvlist[1].z;

 

                  face.tvlist[2].x               =( float ) rend_list->poly_ptrs[poly]->tvlist[2].x;

                  face.tvlist[2].y               =( float ) rend_list->poly_ptrs[poly]->tvlist[2].y;

                  face.tvlist[2].z               =( float ) rend_list->poly_ptrs[poly]->tvlist[2].z;

 

                  math2.Draw_Triangle_2DZB_16(& face, video_buffer,lpitch, zbuffer,zpitch );

 

 

                 

             }

             else

                  if( rend_list->poly_ptrs[poly]->attr & POLY4DV2_ATTR_SHADE_MODE_GOURAUD)

                  {

                      face.tvlist[0].x                   =( float ) rend_list->poly_ptrs[poly]->tvlist[0].x;

                      face.tvlist[0].y                   =( float ) rend_list->poly_ptrs[poly]->tvlist[0].y;

                      face.tvlist[0].z                   =( float ) rend_list->poly_ptrs[poly]->tvlist[0].z;

                      face.lit_color[0]                  =  rend_list->poly_ptrs[poly]->lit_color[0];

 

                      face.tvlist[1].x                   =( float ) rend_list->poly_ptrs[poly]->tvlist[1].x;

                      face.tvlist[1].y                   =( float ) rend_list->poly_ptrs[poly]->tvlist[1].y;

                      face.tvlist[1].z                   =( float ) rend_list->poly_ptrs[poly]->tvlist[1].z;

                      face.lit_color[1]                  =  rend_list->poly_ptrs[poly]->lit_color[1];

 

                      face.tvlist[2].x                   =( float ) rend_list->poly_ptrs[poly]->tvlist[2].x;

                      face.tvlist[2].y                   =( float ) rend_list->poly_ptrs[poly]->tvlist[2].y;

                      face.tvlist[2].z                   =( float ) rend_list->poly_ptrs[poly]->tvlist[2].z;

                      face.lit_color[2]                  =  rend_list->poly_ptrs[poly]->lit_color[2];

 

                      math2.Draw_Gouraud_TriangleZB16(& face, video_buffer,lpitch, zbuffer,zpitch );

                  }

 

 

 

 

    }

 

 

}

 

优化部分基本过时,主要看算法,看看例子如何运行。

 

首先定义了个庞大的物体,(因为要Z缓冲排序,所以物体较多。)

#define  CAM_DECEL                 0.25

#define  MAX_SPEED                 20

#define  NUM_OBJECTS               5

#define  NUM_SCENE_OBJECTS     500

#define  UNIVERSE_RADIUS           2000

 

摄像机改变位置

POINT4D  cam_pos    ={0,0,0,1};

物体名和当前物体序号

char *        object_filenames[NUM_OBJECTS]      ={ "cube_flat_01.cob", "cube_gouraud_01.cob",

"cube_flat_textured_01.cob","sphere02.cob","sphere03.cob",};

 

int                                                  curr_object  =2;

每个物体的位置

POINT4D           scene_objects[NUM_SCENE_OBJECTS];

摄像机速度和Z缓冲设置。

 

float             cam_speed         =0;

ZBUFFERV1                                   zbuffer;

 

在Game_Init()中,

设置摄像机参数

 

    liushuixian.Init_CAM4DV1( * math,&cam,      // the camera object

         CAM_MODEL_EULER,// the euler model

         &cam_pos // initial camera position

         &cam_dir // initial camera angles

         &cam_target,      // no target

         15.0,      // near and farclipping planes

         12000.0,

         120.0,      // field ofview in degrees

         SCREEN_WIDTH,   // size of finalscreen viewport

                                            SCREEN_HEIGHT);

加载物体

    for(int index_obj= 0; index_obj < NUM_OBJECTS;index_obj++ )

    {

 

         liushuixian_texture.Load_OBJECT4DV2_COB( * math,matiGroup, &obj_array[index_obj], object_filenames[index_obj], 

         &vscale, &vpos, &vrot, VERTEX_FLAGS_SWAP_YZ|

         VERTEX_FLAGS_TRANSFORM_LOCAL); 

                                           }

 

设置当前物体

 

 

    curr_object  = 2;

    obj_work = & obj_array[curr_object];

 

加载场景

 

    liushuixian_texture.Load_OBJECT4DV2_COB( * math,matiGroup, &obj_scene,"cube_gouraud_01.cob"

         &vscale, &vpos, &vrot, VERTEX_FLAGS_SWAP_YZ|

         VERTEX_FLAGS_TRANSFORM_LOCAL); 

 

看了一下DEMO的例子效果,感觉不错,所以把4个灯光全加上

white.rgba = _RGBA32BIT(255,255,255,0);

    gray.rgba  = _RGBA32BIT(100,100,100,0);

    black.rgba = _RGBA32BIT(0,0,0,0);

    red.rgba   = _RGBA32BIT(255,0,0,0);

    green.rgba = _RGBA32BIT(0,255,0,0);

    blue.rgba  = _RGBA32BIT(0,0,255,0) ;

 

    light.Init_Light_LIGHTV2( * math,lightGroup,AMBIENT_LIGHT_INDEX,LIGHTV2_STATE_ON, LIGHTV2_ATTR_AMBIENT,gray, black,black, NULL,NULL, 0, 0, 0, 0, 0, 0 );

   

    VECTOR4D dlight_dir        = { -1, 0, -1, 1 };

    light.Init_Light_LIGHTV2( * math,lightGroup,INFINITE_LIGHT_INDEX,LIGHTV2_STATE_ON, LIGHTV2_ATTR_INFINITE,black, gray,black, NULL,& dlight_dir, 0, 0, 0, 0, 0, 0 );

 

    VECTOR4D plight_pos        = { 0, 200, 0, 1 };

    light.Init_Light_LIGHTV2( * math,lightGroup,POINT_LIGHT_INDEX,LIGHTV2_STATE_ON, LIGHTV2_ATTR_POINT,black, green,black, & plight_pos,NULL, 0, 0.002, 0, 0, 0, 1 );

 

    VECTOR4D slight2_dir       = { -1, 0, -1, 1 };

    VECTOR4D slight2_pos       = { 0, 1000, 0, 1 };

    light.Init_Light_LIGHTV2( * math,lightGroup,SPOT_LIGHT2_INDEX,LIGHTV2_STATE_ON, LIGHTV2_ATTR_SPOTLIGHT2,black, red,black, & slight2_pos,& slight2_dir, 0, 0.001, 0, 0, 0, 1 );

 

 

设置Z缓冲

 

      liushuixian_texture.Create_Zbuffer(& zbuffer, SCREEN_WIDTH,SCREEN_HEIGHT, ZBUFFER_ATTR_32BIT);

 

在每帧中,设定灯光旋转

    staticfloat plight_ang= 0, slight_ang = 0;

物体旋转

    staticfloat x_ang= 0, y_ang = 0, z_ang= 0;

Z缓冲模式

static int z_buffer_mode                 =1;

忘了背面消除,这里补上。

 

int DDRAW_LIUSHUIXIAN_TEXTURE::Cull_OBJECT4DV2( OBJECT4DV2_PTRobj, CAM4DV1_PTRcam, int cull_flags,ddraw_mathmath )

{

    //将物体包围球球心变换为相机坐标

    POINT4D                                sphere_pos;           //用于存储包围球球心变换后的坐标

    //对点进行变换

    math.Mat_Mul_VECTOR4D_4X4( & obj->world_pos,& cam->mcam,& sphere_pos );

    //根据剔除标记对物体执行剔除操作

    if(cull_flags & CULL_OBJECT_Z_PLANE)

    {

         //cull only based on z clipping planes

 

         //test far plane

         if( ((sphere_pos.z- obj->max_radius[obj->curr_frame]) > cam->far_clip_z)||

             ((sphere_pos.z + obj->max_radius[obj->curr_frame])< cam->near_clip_z))

         {

             SET_BIT(obj->state, OBJECT4DV2_STATE_CULLED);

             return(1);

         } //end if

 

    } //end if

 

    if(cull_flags & CULL_OBJECT_X_PLANE)

    {

         //cull only based on x clipping planes

         //we could use plane equations, but simple similar triangles

         //is easier since this is really a 2D problem

         //if the view volume is 90 degrees the the problem is trivial

         //buts lets assume its not

 

         //test the the right and left clipping planes against the leftmost and rightmost

         //points of the bounding sphere

         floatz_test = (0.5)*cam->viewplane_width*sphere_pos.z/cam->view_dist;

 

         if( ((sphere_pos.x-obj->max_radius[obj->curr_frame])> z_test) || // right side

             ((sphere_pos.x+obj->max_radius[obj->curr_frame])< -z_test) )  // left side, notesign change

         {

             SET_BIT(obj->state, OBJECT4DV2_STATE_CULLED);

             return(1);

         } //end if

    } //end if

 

 

    if(cull_flags & CULL_OBJECT_Y_PLANE)

    {

 

         //test the the right and left clipping planes against the leftmost and rightmost

         //points of the bounding sphere

         floatz_test = (0.5)*cam->viewplane_height*sphere_pos.z/cam->view_dist;

 

         if( ((sphere_pos.y-obj->max_radius[obj->curr_frame])> z_test) || // right side

             ((sphere_pos.y+obj->max_radius[obj->curr_frame])< -z_test) )  // left side, notesign change

         {

             SET_BIT(obj->state, OBJECT4DV2_STATE_CULLED);

             return(1);

         } //end if

    } //end if

 

    return( 0 );

}

 

根据Z缓冲,按照Z的大小不同图示如下:



本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

2015年1月13日星期二(11-1深度缓存和可见性简介) 的相关文章

  • SVN服务器搭建和使用(一)

    Subversion是优秀的版本控制工具 其具体的的优点和详细介绍 这里就不再多说 首先来下载和搭建SVN服务器 现在Subversion已经迁移到apache网站上了 下载地址 http subversion apache org pac
  • C#复制构造函数学习

    通过从另一个对象复制变量或将一个对象的数据复制到另一个对象来创建对象的构造函数称为复制构造函数 复制构造函数是一个参数化构造函数 包含相同类类型的参数 它的主要用途是将新实例初始化为现有实例的值 using System namespace
  • 电脑提示MSVCP140.dll文件丢失的解决方法

    打开软件或者游戏出现运行出现报错 提示 由于找不到 MSVCP140 dll 无法继续执行代码 重新安装程序可能会解决此问题 这一般是什么原因导致了这个问题 我们要如何解决 下面小编分享一下由于找不到MSVCP140 dll无法继续执行代码
  • linux卸载zookeeper_Zookeeper学习

    zookeeper 是一个分布式协调服务的开源框架 主要用来解决分布式集群中应用系统的一致性问题 本质上是一个分布式的小文件存储系统 提供基于类似文件系统的目录树方式的数据存储 并且可以对树中的节点进行有效管理 从而用来维护和监控你存储的数

随机推荐

  • nosql 之认识篇

    使用sql server n年后 发现mysql这个开源数据库也很好用 于是投身到这个行列中 最近开发个sns类型的网站 随着用户的增多 感觉数据库所承受的压力成为了整个网站继续发展的瓶颈 为了更好的解决此问题 发现twitter face
  • CRNN+CTC实现不定长验证码识别(keras模型-训练篇)

    目录 前言 运行环境 生成数据集 构建网络模型 初步训练模型 测试模型 进一步训练模型 结语 前言 本文为CRNN CTC实现不定长验证码识别 keras模型 示例篇 的续篇 示例篇中使用的字符仅为数字 本文将训练集拓展到包含数字字母在内的
  • SharedPreferences存储

    目录 1 获得SharedPreferences对象 1 1 使用getSharedPreferences 方法获取 1 2 使用getPreferences 方法获取 2 向SharedPreferences文件中存储数据 3 读取Sha
  • 封装一个底部导航

    html部分
  • GPT-3.5-turbo小白连接教程

    前言 最近在看Chat几批题的相关内容 尝试了在自己电脑上调用一下OpenAI的api 下面以调用几批题 3 5 turbo为例进行讲解 本次分享分为三大模块 第一个模块先对连接成功后的AI聊天机器人的功能进行简要了解 第二个模块讲一下国内
  • mysql workbench怎么设置为中文?(仅菜单项汉化)附带main_menu文件

    找到Mysql Workbench安装目录 若全部默认则地址如下 C Program Files MySQL MySQL Workbench 8 0 CE data 里面有main menu xml文件 用汉化后的文件替换软件重启即可 链接
  • 性能测试ftp服务器,测试ftp服务器的性能

    测试ftp服务器的性能 内容精选 换一换 云耀云服务器适用于对CPU 内存 硬盘空间和带宽无特殊要求 服务一般只需要部署在一台或少量的服务器上 一次投入成本少 后期维护成本低的场景 例如网站开发 Web应用 推荐使用云耀云服务器 主要提供均
  • 退出屏保前玩一把游戏吧!webBrowser中网页如何调用.NET方法

    本文主要以 HackerScreenSaver 新功能的开发经历介绍 webBrowser中网页如何调用 NET方法的过程 1 背景 之前开源了一款名为 HackerScreenSaver 的 Windows 屏保程序 该程序具有模拟黑客炫
  • 大专应届生内心独白:室友都有依靠,孤单的只有我自己

    前言 室友都有大腿抱 孤单的只有自己 作为大专生 我们大三下学期没有课程 主要是写论文 找工作 可我一点也不着急 因为我还没做好毕业的准备 也很迷茫 室友A准备回老家考公务员 室友B的父母已经给他找好了工作 室友C去亲戚公司了 而我 却只能
  • 一个关于POP3协议超时的问题

    前段时间在做一个email项目时 一个测试人员报了一个BUG 就是当email客户端在连接hotmail 的POP3服务器之后大概4 5分钟就会自动把客户端断掉 为这个问题我查了一下POP协议规范 协议中有这么一段话 POP3服务器可以拥有
  • 老司机才懂的测试问题定位方法!

    在软件开发过程中 项目测试是至关重要的一环 然而 测试过程中常常会遇到各种问题 本文将介绍一些常见的项目测试问题 并探讨如何有效地定位这些问题 1 问题一 功能不符合预期 定位方式 检查需求文档和设计文档 确保理解功能的正确性和预期行为 仔
  • MSF使用教程

    MSF使用教程 1 简介 Metasploit是一款开源安全漏洞检测工具 附带数百个已知的软件漏洞 并保持频繁更新 被安全社区冠以 可以黑掉整个宇宙 之名的强大渗透测试框架 2 MSF模块介绍 1 辅助模块 auxiliary 负责执行信息
  • 字符集编码(GBK,BIG5,UNICODE)与C++的string/wstring

    GBK BIG5等字符集编码范围的具体说明 一 预备知识 1 字符 字符是抽象的最小文本单位 它没有固定的形状 可能是一个字形 而且没有值 A 是一个字符 德国 法国和许多其他欧洲国家通用货币的标志 也是一个字符 中 国 这是两个汉字字符
  • 以太坊2.0主网即将上线 一轮前所未有的超级牛市来了

    8月4日 以太坊2 0第0阶段信标链的最终版测试网Medalla上线 多个客户端同时运行测试 至少有16384个验证者参与了本次测试 在测试过程中 虽然出现了Nimbus 和 Lodestar 节点因无法处理测试网的负载量而卡住 导致Med
  • logback配置两套日志路径

    日志推送工作根据公司日志管理规范及国家攻防演练需要 请协助对所有应用重要场景的日志进行收集 需求如下 1 涉及场景 用户登录场景 密码修改场景 密码找回场景 注册场景 2 日志字段需求及格式 filebeat对接日志格式 登录 修改 注册
  • 消息队列MQ-面试题

    一个用消息队列 的人 不知道为啥用 MQ 这就有点尴尬 1 什么是消息队列 可以看作是一个存放消息的容器 当我们需要使用消息的时候可以取出消息供自己使用 消息队列是分布式系统中重要的组件 使用消息队列主要是为了通过异步处理提高系统性能和削峰
  • vue3 中应用 element plus,pinia 实现简易购物车

    使用pinia 进行全局的状态管理 降低组件之间的耦合性 一 项目需要的资源 1 element plus官方地址 https element plus gitee io zh CN guide quickstart html 2 pini
  • matlab卡农,又用Mathematica写了一段卡农

    你能在这里听到它 用数学软件演奏音乐早已不是什么新鲜事 很早就有人用Matlab弹奏卡农或是最炫民族风 最近我知道还有人用无理数生成一段音乐 很有趣 而我选择用Mathematica弹奏卡农是因为卡农这种谱曲方式很奇妙 体现在程序上也会是简
  • 内网如何下载docker镜像

    内网无法联网 因此不能直接运行docker pull命令下载docker镜像 可按下述方法获取docker镜像 步骤 1 在可以联网的机子上执行docker pull命令下载镜像 如 sudo docker pull freewil bit
  • 2015年1月13日星期二(11-1深度缓存和可见性简介)

    新的一年 开始新的篇章 终于进入第11章了 必须首要搞这个 争取今年搞完 我也相信 会对3D学习不是浪费时间 而是内力提升 在以前 用画家算法进行多边形排序 即根据渲染列表中的每个多边形的平均 最小或最大值进行排序 然后 再从后到前的顺序绘