平民程序 - linghuye's blog

天下风云出我辈,一入江湖岁月催。皇图霸业谈笑中,不胜人生一场醉。提剑跨骑挥鬼雨,白骨如山鸟惊飞。尘事如潮人如水,只笑江湖几人回。

随笔 - 221, 文章 - 0, 评论 - 680, 引用 - 0
数据加载中……

模板编译期计算

     摘要: Code highlighting produced by Actipro CodeHighlighter (freeware)http://www.CodeHighlighter.com/-->  1#ifndef _COMPILER_CALCULATION_H  2#define _COMPILER_CALCULATION_H&nbs...  阅读全文

posted @ 2005-09-25 23:33 linghuye 阅读(462) | 评论 (0)编辑 收藏

glDrawBuffers和GL_TEXTURE_RECTANGLE_NV对渲染概念的扩展

1.建立并进入一个PBuffer Context,依次使用glDrawBuffer切换到其中的各辅助Draw Buffer(GL_AUXn),清除其颜色和深度缓冲区.
2.使用glDrawBuffersATI设置目标为一个Draw Buffer数组,作图,则数组中所有Draw Buffer都将反映作图指令.
3.切回主窗口Context,使用wglBindTexImageARB将PBuffer中的某个Draw Buffer绑定到当前纹理,作图.

Note:
1. NV_texture_rectangle extension adds a new texture target that supports 2D textures without requiring power-of-two dimensions.
   glEnable(GL_TEXTURE_RECTANGLE_NV);
   glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
2.使用glWindowPos2dARB直接设置当前窗口象素坐标系下的位置,避过当前变换矩阵的影响.
3.使用ARB_transpose_matrix,使得程序能传递/接收常规的C/C++下的行主存储矩阵数组,
   glLoadTransposeMatrixARB,glMultTransposeMatrixARB,
   TRANSPOSE_MODELVIEW_MATRIX_ARB 
   TRANSPOSE_PROJECTION_MATRIX_ARB 
   TRANSPOSE_TEXTURE_MATRIX_ARB 
   TRANSPOSE_COLOR_MATRIX_ARB, 隶属1.3标准
4.使用glBlendColorEXT定义一个常量颜色值,然后在glBlendFunc中使用如下factor,使得所定义的颜色作为factor参与Blend运算公式. 
   CONSTANT_COLOR_EXT
   ONE_MINUS_CONSTANT_COLOR_EXT
   CONSTANT_ALPHA_EXT     
   ONE_MINUS_CONSTANT_ALPHA_EXT
5.GL_MIRRORED_REPEAT_ARB 镜像反复的纹理wrap模式
6.glMultiDrawArraysEXT:
   These functions behave identically to the standard OpenGL 1.1 functions glDrawArrays() and glDrawElements() except they handle multiple lists of vertices in one call. Their main purpose is to allow one function call to render more than one primitive such as triangle strip, triangle fan,etc.
7.使用 glBlendFuncSeparateEXT(enum sfactorRGB, enum dfactorRGB,  enum sfactorAlpha, enum dfactorAlpha);
   依然根据Blend方程但分开计算颜色中的RGB部分和Alpha部分.
8.ARB_texture_non_power_of_two是个很有意思很强很好用的扩展,它既没添加新函数,也没添加新模式,如果从驱动程序中能得到该扩展,则表明所有纹理操作支持非2次方大小模式.
9.SGIS_generate_mipmap,  glTexParameteri(GL_TEXTURE_2D, GENERATE_MIPMAP_SGIS, GL_TRUE)
   This extension defines a mechanism by which OpenGL can derive the entire set of mipmap arrays when provided with only the base level array.  Automatic mipmap generation is particularly useful when texture images are being provided as a video stream.
10.ARB_multisample,使用wglChoosePixelFormatARB建立支持WGL_SAMPLE_BUFFERS_ARB的Context,在需要进行多重采样抗锯齿的地方使用glEnable(GL_MULTISAMPLE_ARB).
int iAttributes[] =
{
     WGL_DRAW_TO_WINDOW_ARB,GL_TRUE,
     WGL_SUPPORT_OPENGL_ARB,GL_TRUE,
     WGL_ACCELERATION_ARB,WGL_FULL_ACCELERATION_ARB,
     WGL_COLOR_BITS_ARB,24,
     WGL_ALPHA_BITS_ARB,8,
     WGL_DEPTH_BITS_ARB,16,
     WGL_STENCIL_BITS_ARB,0,
     WGL_DOUBLE_BUFFER_ARB,GL_TRUE,
     WGL_SAMPLE_BUFFERS_ARB,GL_TRUE,
     WGL_SAMPLES_ARB,4,
     0,0
 };

11. The buffer region extension is a mechanism that allows an area of
    an OpenGL window to be saved in off-screen memory for quick
    restores.  The off-screen memory can either be frame buffer memory
    or system memory.
   HANDLE wglCreateBufferRegionARB(HDC hDC, int iLayerPlane, UINT uType)
   VOID wglDeleteBufferRegionARB(HANDLE hRegion)
    BOOL wglSaveBufferRegionARB(HANDLE hRegion, int x, int y, int width, int height)
    BOOL wglRestoreBufferRegionARB(HANDLE hRegion, int x, int y, int width, int height, int xSrc, int ySrc)

12.使用纹理传送浮点数组缓冲给Shader
      float *data1 = new float[kImageWidth * kImageHeight * 3];
      glEnable(GL_TEXTURE_RECTANGLE_ARB);
      glBindTexture(GL_TEXTURE_RECTANGLE_ARB, textures[0]);
 glTexImage2D(GL_TEXTURE_RECTANGLE_ARB, 0, GL_RGBA32F_ARB, kImageWidth, kImageHeight, 0, GL_RGB, GL_FLOAT, data1);
 glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
 glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MAG_FILTER, GL_NEAREST);

13.使用glVertexBlendARB指定顶点受到几个变换矩阵的影响.使用glEnable(GL_WEIGHT_SUM_UNITY_ARB);指定权重之和为1.使用glEnable(GL_VERTEX_BLEND_ARB);激活顶点混合模式.使用glWeightPointerARB(3, GL_FLOAT, 0, Weights);glEnableClientState(GL_WEIGHT_ARRAY_ARB);绑定每个顶点的权重值(以vector形式表达,未知),使用型如:glMatrixMode(GL_MODELVIEW0_ARB);进入每个矩阵模式,并设置变换矩阵.

意随心走,无拘无束,自由的Opengl.

Reference:
http://oss.sgi.com/projects/ogl-sample/registry/index.html

posted @ 2005-09-25 21:34 linghuye 阅读(2954) | 评论 (2)编辑 收藏

显卡对Opengl标准的支持

显卡对Opengl标准的支持,在逻辑是通过驱动程序完成的.理论上通过软件实现,驱动程序可以实现所有的最新的Opengl标准(只要驱动程序暴露扩展函数接口即可),但受限于原先固有硬件的设计,有些扩展无法或实现非常困难,如Shader标准,FrameBuffer等与硬件紧密相关的技术. 但很多扩展只需要升级驱动程序即可.尽管Opengl 2.0是刚通过ARB的,但在此前出产的有相关硬件能力的显卡只需升级驱动程序即可.

OpenGL Extensions Viewer这个工具能检查当前显卡驱动程序对Opengl的实现程度.

// 取显卡内存量
bool getVideoMemUsage(DWORD &vidMemTotal, DWORD &vidMemFree)
{
// Uses directdraw to get total and free video memory
LPDIRECTDRAW lpDD = NULL;
HWND hWnd = NULL;
DDCAPS ddcaps;
ddcaps.dwSize=sizeof(DDCAPS);

if(DirectDrawCreate(NULL, &lpDD, NULL)!=DD_OK)
{
return false;
}
if(lpDD->SetCooperativeLevel(hWnd, DDSCL_NORMAL)!=DD_OK)
{
lpDD->Release();
return false;
}
if(lpDD->GetCaps(&ddcaps, NULL)!=DD_OK)
{
lpDD->Release();
return false;
}
vidMemTotal = ddcaps.dwVidMemTotal;
vidMemFree = ddcaps.dwVidMemFree;
lpDD->Release();
return true;
}

posted @ 2005-09-24 23:48 linghuye 阅读(634) | 评论 (0)编辑 收藏

Opengl点精灵扩展理解与使用

1.以点描述一个正方形Billboard概念,节省了顶点数据传输带宽.
2.激活glEnable(GL_POINT_SPRITE_ARB);之后画点即可使用.
3.使用glPointSize控制Billboard大小,依公式控制透视效果  
  // clamp(size * sqrt(1 / (a + b * d + c * d ^ 2)))
  float quadratic[] =  { a, b, c };
  glPointParameterfvARB(GL_POINT_DISTANCE_ATTENUATION_ARB, quadratic);
  glPointParameterfARB( GL_POINT_SIZE_MIN_ARB, minsize );
  glPointParameterfARB( GL_POINT_SIZE_MAX_ARB, maxSize );
  使用 glPointParameterfARB(GL_POINT_FADE_THRESHOLD_SIZE_ARB, 60.0f);控制消隐效果.
  使用 glTexEnvf(GL_POINT_SPRITE_ARB, GL_COORD_REPLACE_ARB, GL_TRUE);为Billboard上纹理.
4.名义上隶属Opengl2.0标准,实际实现上由于硬件限制不大,更新最新的驱动程序都能实现该扩展,ARB的官僚可见一斑.

Reference:
http://www.khronos.org/opengles/documentation/opengles1_1/gl_egl_ref_1_1_20041110/glPointParameter.html
http://www.codesampler.com/oglsrc/oglsrc_6.htm#ogl_point_sprites

posted @ 2005-09-24 16:19 linghuye 阅读(1166) | 评论 (0)编辑 收藏

又一个图像包格式

今天研究了Magic Online的pig图像包格式,数组接着数组,易用好理解,图片挺好看的,竟然还有刘关张桃园结义的图,万智牌还真有意思,嘿嘿,有意思.



破解cards.dat,strconst.dat,遇到加密数据,经数日,而失败告终.

posted @ 2005-09-23 20:45 linghuye 阅读(517) | 评论 (0)编辑 收藏

MyWarCraftStudio's DBCViewer

DBCTool的数据打开速度太慢,排序也很慢,受不了,于是改良了一下我原有的DBCReader.dll,打开和排序速度都很快,当然跟DBCTool的功能不能比.

MyWarCraftStudio's DBCCraft, support:

1.DBC data browse
2.Data field sort by clicking column title.
3.Data search by text
4.Data export to csv
5.Data field define by change the Cnfg\DBCRecordDef.xml

http://www.linghuye.nease.net/Tools/MyWarCraftStudio_DBCViewer.rar

linghuye software

posted @ 2005-09-23 16:01 linghuye 阅读(3536) | 评论 (6)编辑 收藏

2005.09.20

有的时候,你作不出决定,那你就把自己慢慢地逼到那一条路上去.

2005.09.21
我作出了决定,决不翻悔. I make my decision, I decide my destiny!

借口理由
给自己放假,学习时间,编写引擎,创造突破机会.

2005.10.08
Quit my job,as four years ago.又结束了人生的一个时期,谁又知道明天会怎样,不去管他.

posted @ 2005-09-20 11:16 linghuye 阅读(318) | 评论 (0)编辑 收藏

阴影技术的理解和使用

当基础知识都已完备,所谓的高级技术不过是巧妙的应用而已.犹如高中的物理题,无论多么复杂都逃不脱几个基本的物理定理.

一.平面投影
    Planar shadows are created by building a special matrix transform which flattens an object's geometry into a plane when rendered and is definitely one of the simplest ways of creating real-time shadows. Unfortunately, planar shadows are only useful when projected onto planar surface like a wall or floor so their use in modern applications or games is quickly falling out of favor.

二.Shadow map

基本实现原理: Two pass algorithm
1.首先,以光源为视点,按正常镜头参数(Project Matrix和Frustum),渲染整个场景,以得到场景相对于光源的深度图,又称Shadow map.
2.然后,以正常镜头视点,渲染整个场景.对每个Fragment计算其相对于光源的XYZ位置,并与深度图中XY位置处的Z值比较,若小等于深度图的Z,表明照射该处的光线不受其他物体遮挡,反之,则收到其他物体遮挡,呈现阴影.

OpenGL实现原理:
We render the scene from the light's view and store the depth values in a texture.  We then render the world normally from the camera's view.  Texture generation is used to calculate and project our texture coordinates for the shadow mapping.  We test the depth values of the light's view and the camera's view in the light's clip space to see if there is a shadow.  Basically, if the camera can see something that the light can't, that means that that part should be shadowed.

1.使用PixelBuffer或FrameBuffer作为渲染环境,进行1的渲染,得到Depth Buffer,并将其绑定到某纹理,称该纹理为Shadow map texture.

2.建立纹理投影矩阵为光源视点下的模型矩阵,并设定纹理坐标生成方式为镜头空间的平面自动生成.
  // 设置纹理矩阵
    glMatrixMode(GL_TEXTURE);
    glLoadIdentity();
    gluPerspective(...); // light frustum
    glMultMatrixf(...);  // Light matrix
    glMatrixMode(GL_MODELVIEW);
   
    // 激活4元纹理坐标的生成
    glEnable(GL_TEXTURE_GEN_S);
    glEnable(GL_TEXTURE_GEN_T);
    glEnable(GL_TEXTURE_GEN_R);
    glEnable(GL_TEXTURE_GEN_Q);

  // 设置纹理坐标生成方式为平面公式线性插值的镜头空间坐标   
    glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR);
    glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR);
    glTexGeni(GL_R, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR);
    glTexGeni(GL_Q, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR);
  
    // 设置GL_EYE_LINEAR下纹理坐标生成的平面公式的系数
    float x[] = { 1.0f, 0.0f, 0.0f, 0.0f };
    float y[] = { 0.0f, 1.0f, 0.0f, 0.0f };
    float z[] = { 0.0f, 0.0f, 1.0f, 0.0f };
    float w[] = { 0.0f, 0.0f, 0.0f, 1.0f };
    glTexGenfv(GL_S, GL_EYE_PLANE, x);
    glTexGenfv(GL_T, GL_EYE_PLANE, y);
    glTexGenfv(GL_R, GL_EYE_PLANE, z);
    glTexGenfv(GL_Q, GL_EYE_PLANE, w);

该步骤的目的是为了使用纹理坐标生成这一图形硬件技巧计算得到每个Fragment处相对于光源的XYZ位置.
按纹理投影和变换矩阵将当前的镜头空间下的XYZ,转换为纹理空间/光源视点空间下的XYZ,
按GL_EYE_LINEAR纹理坐标生成公式Ax + By + Cz + D,且依如上参数设置的纹理坐标生成方式,计算纹理投影矩阵(即光源视点矩阵)下的(x,y,z,w),得到的纹理坐标(s,t,r,q)即:
s = 1.0f * x + 0.0f * y + 0.0f * z + 0.0f = x;
t = 0.0f * x + 1.0f * y + 0.0f * z + 0.0f = y;
r = 0.0f * x + 0.0f * y + 1.0f * z + 0.0f = z;
q = 0.0f * x + 0.0f * y + 0.0f * z + 1.0f = 1.0;
=> 顶点坐标和纹理坐标在数值上相等对应 => 生成的纹理坐标的r即为z => 即在纹理投影矩阵/光源视点矩阵下的深度值.
   
3.设置阴影纹理(GL_ARB_shadow)比较模式为:
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE_ARB, GL_COMPARE_R_TO_TEXTURE_ARB);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_FUNC_ARB, GL_LEQUAL);
该步骤的目的是进行Z值比较,并将得到的结果送入Fragment处理.
取2中计算得到的当前纹理坐标的r值(即当前Fragment的深度值)与当前深度纹理图寻址(s,t)处的值Dt进行对比,若r <= Dt,返回值1.0,反之,返回值0.0.
将返回的1.0或0.0作为Texel的LUMINANCE对当前Fragment混合,这样1.0的不变,0.0的成阴影.
  
4.最终渲染,Shadow map在管线作为纹理中发挥作用,影响最终的输出画面,产生阴影效果.

三.Shadow volume
 Refer to http://blog.donews.com/yyh/archive/2005/05/19/387143.aspx  文章写的很好
ZFail表达了: 有阴影体face在显示的物点之后.
ZPass和ZFail的逻辑区别在于,ZPass考察显示的物点之前的阴影体face,ZFail考察显示的物点之后的阴影体face,镜头是在显示的物点之前的(所谓之前之后就是以离镜头的远近为准的),所以镜头的位置会影响ZPass的逻辑,但不会影响ZFail的逻辑. 两者的基本判断逻辑是多边形穿越算法.

无论是ZPass还是ZFail都有与镜头剪裁面发生剪切的情况,这个剪切是指某个阴影体face被镜头裁剪掉了,即在几何处理阶段就被抛弃了,从而被裁剪的部分阴影体face根本没有进入设计的ZPass/ZFail stencil阶段,考察的阴影体face不完整,算法基础崩溃了.

所以产生需要Capping的问题, ZPass需要考察物点前的阴影体face,所以会被Near Plane裁剪,而ZFail则需要Capping Far Plane.


References:
http://www.pcgames.com.cn/netgames/zhuanti/wow/pince/0503/574679.html
http://www.codesampler.com/oglsrc/oglsrc_7.htm#ogl_planar_shadow
http://www.gametutorials.com/gtstore/c-1-test-cat.aspx
游戏编程精粹1
http://developer.nvidia.com/object/ogl_rtt_shadow.html
http://resumbrae.com/ub/dms424_s04/15/03.html
http://oss.sgi.com/projects/ogl-sample/registry/ARB/shadow.txt
http://oss.sgi.com/projects/ogl-sample/registry/ARB/depth_texture.txt
http://www.paulsprojects.net/opengl/shadvol/shadvol.html

posted @ 2005-09-20 10:12 linghuye 阅读(2228) | 评论 (0)编辑 收藏

Bump Map理解和使用

Bump Map的基本原理很简单,就是使用纹理图像中的数据修改光照方程中的法线.
造成Bump Map变得复杂的原因,是实际应用中的纹理的具体数据表达以及它们如何修改法线值的方式.

1.3字节RGB法线图,以我的观点,法线图就是一个Bump Map(这里的法线它就不垂直于表面),用它们直接替换光照方程中的法线值.当然大多数人不这么想,起了个深奥的名词:dot3_bump_map,丫得不就一法线图吗.在Shader语言中用的通常是这种直接可寻纹理的数据,因为它最快.但在固定流水线中也可以实现这些,结果差不多等于实现了一遍光照方程,相当麻烦.根据法线图内法线的定义空间,可分模型空间和正切空间,这个概念也相当复杂,游戏编程精粹1里有专门论述,总之,很麻烦,最好写 Shader

2.Offset vector bump map,似乎是Blinn提出这种奇怪的修改方式,因为他老人家是泰斗,所以大部分文章讲述凹凸贴图时引用的都是这个标准方法,但实际应用中却有很多的变种,有时甚至面目全非.此中纹理图的每Texel存储的是2个带符号单字节数值(A8L8),经过/127,得到浮点数bu,bv.
  设原某法线为N,先求N的2个分别延u,v方向的垂直标准向量Nu,Nv,分别乘以bu,bv,累加到N上,得到:
  N' = N + Nu * bu + Nv * bv;
  为了节省空间,在Shader中也使用这种方法,计算上比1慢.

3.使用高度图修改法线值,根据相邻行列间的高度差计算出2中偏移值.这种方法最节省空间,但最慢,通常用于在Shader中通过3次纹理查找完成.
  从魔兽世界的流体数据上分析,它应该采用的是这种方式,节省数据量为主,即通过Shader实现(在BLS文件内),所以在不支持Pixel Shader的显卡机器上是没有水面凹凸,地面闪光效果的.

三种方法使用的Texel分别是3,2,1字节,但实际使用中会有其他附加的字节集成到Texel,如Specular color map,Specular exponent (shininess),Parallax bump mapping.
Bump Map是一个最能体现理论与实际之间差距的技术,它的概念建立在Phong逐象素光照模型基础之上.


Reference:
http://freespace.virgin.net/hugo.elias/graphics/x_polybm.htm
http://download.nvidia.com/developer/Papers/2004/Bump_Map_Compression/Bump_Map_Compression.pdf
http://www.codesampler.com/oglsrc/oglsrc_4.htm#ogl_dot3_bump_mapping
http://www.r3.nu/~cass/thesis/thesis/

posted @ 2005-09-19 00:27 linghuye 阅读(3432) | 评论 (2)编辑 收藏

中秋

为了学习,没办法,死活从电脑城以被宰的价格拿回华硕的N6600,AGP 8X.
拆机,上显卡,槽口怎么对不上,难道4X和8X连接口规格都变了?再仔细看看,faint,插到PCI了,插AGP,嘿嘿,4X和8X的规格没有变.
硬件规格对上就好办了,开机测试,100分贝的警笛长鸣,这下完了,不兼容.
换回显卡,上网查资料30分钟,有说可以有说不可以的,死菜.突然看到显卡警告上有写着如遇显卡报警,可直接连主机电源到显卡上的电源接口.
于是拔下CD Rom的电源到显卡,开机,果然不报警了,但主板自检还是过不去,en,再拔掉CD Rom的数据线,开机通过了,god bless asus.
Windows启动正常,进入桌面正常,重新安装显卡驱动重启正常,修改显示参数正常,看着N6600和AGP 4X的标识,cool bi le.
装机,封盖,重启,完了,刚进入Windows用户登陆的界面,显示器显示信号没了,重启依旧,shit.
进安全模式,正常,卸掉驱动,重启进入正常,驱动有问题,显卡工作不稳定都有可能,将分辨率调低,运行正常.
启动Wow测试,又完了,nnd,死机,重启,删除原有wow的运行配置,重运行正常,播放影碟正常.
结论 1.N6600插AGP 4X运行是可以了,估计此后极不稳定,麻烦不断. 2.世事无常,随机应变而已.

这N6600最后还是去了,换回的N6200问题依旧,所以我猜想似乎是电压问题,于是撤了一个CDRom,使用单独的电源线给显卡供电,现在似乎是正常了,who knows,who cares.

说起世事无常,却是我对人生一贯的主张,所以人要有长远的目标和计划,而短期的得失确实不可计较,如上学时的分数,一时的人际,暂时的财富.总是有那么几个关键的决定影响你一生的发展,其余时间象牛一样默默耕田,象西西弗一样推石上山,如我在中学时不知大学在哪,大学时不知自己会成为程序员,现在不知明天怎样,但却有几个明确的目标点一个一个实现.所以管他那些学校的约束制度,公司的狗屁规矩,一切事物只是矛盾激化的必然结果,矛盾犹如你的程序,如果一开始设计不好,最后只能推翻重来,我要感受的是自己的进步,看到的是我的目标.

中秋,除了大学4年,我都是和家人一起过的,这也是我看到的目标,我的快乐是很贵地.

posted @ 2005-09-18 19:14 linghuye 阅读(306) | 评论 (0)编辑 收藏

仅列出标题
共23页: First 12 13 14 15 16 17 18 19 20 Last