博文

目前显示的是标签为“程序”的博文

卡通阴影的构造原理--OpenGL笔记

图片
看了两篇关于卡通阴影构造的教程, 觉得有必要写下自己的理解 原理教程: http://www.gamedev.net/reference/programming/features/celshading/ 实例教程: http://nehe.gamedev.net/data/lessons/lesson.asp?lesson=37 其实实例教程是作者写的第二个版本, 以解他人求代码之苦, 呵呵 本文并非翻译, 如有谬误之处, 请指出 卡通阴影主要是指那些漫画手绘绘出的阴影效果, 不用光照实现的虚拟效果. 首先构造一个一维纹理, 其像素值只有白色, 不同程度的灰色, 黑色. 如下图所示 上图为16个像素的一维纹理数据. 然后根据顶点的法线与光线方向的角度设置纹理坐标.其中顶点法线与光线成0度角, 则取纹理坐标1(cos0).如果顶点法线与光线方向垂直,则取纹理坐标0(cos(∏/2)). 本实例的一维纹理有32个像素,如下图所示 用三角形来实现效果, 假设顶点1和顶点3的法线平行于光线方向. 而顶点2的法线则垂直于光线方向. 则效果如下: 代码为: glBegin(GL_TRIANGLES); glTexCoord1f(0.0); glVertex3f(-0.5, -0.5, 0.0); glTexCoord1f(1.0); glVertex3f(0.5, -0.5, 0.0); glTexCoord1f(1.0); glVertex3f(0, 0.5, 0.0); glEnd(); 结论: 如果绘制一个模型, 已知顶点法线向量N, 光线向量L, 顶点坐标V. 则 V*N = |V|*|N|cos(V和N的夹角) (其中*为点积) 所以 V*N / (|V|*|N|) 就等于其纹理坐标向量, 标记为T. 然后 绘制的时候,设置顶点和设置纹理坐标的语句如下: glTexCoord1f(T); glVertex3fv(V); 在使用纹理过程中注意要禁止光照,禁止混合, 允许一维纹理. 在实例教程中, 还涉及了法线向量旋转的问题. 假设原法线向量在单元矩阵中为N, 旋转后的矩阵为 M = {x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x...

OpenGL 红宝书 帧缓冲区

图片
第10章 帧缓存 在OpenGL窗口中, 左下角的像素为(0, 0). 一般而言, 像素(x, y)占据的矩形区域左下角为(x, y), 右上角为(x+1, y+1). 10.1 缓存及其用途 1) 颜色缓存, 左前,右前,左后,右后和任意数量的辅助颜色缓存; 2) 深度缓存 3) 模板缓存 4) 累积缓存 注意:X窗口系统,RGBA模式至少保证1个颜色缓冲区,模板缓冲区,深度缓冲区,累计缓冲区 颜色索引模式至少保证1个眼色缓冲区,深度缓冲区,模板缓冲区. 可以使用glXGetConfig{}函数查询. 用glGetIntegerv()查询每个像素占据的缓存空间的参数 GL_RED_BITS, GL_GREEN_BITS, GL_BLUE_BITS, GL_ALPHA_BITS --- 颜色缓存中R, G, B, A分量的位数 GL_INDEX_BITS --- 颜色缓存中每个颜色索引的位数 GL_DEPTH_BITS --- 深度缓存中每个像素的位数 GL_STENCIL_BITS --- 模板缓存中每个像素的位数 GL_ACCUM_RED_BITS, GL_ACCUM_GREEN_BITS, GL_ACCUM_BLUE_BITS, GL_ACCUM_ALPHA_BITS --- 累积缓存中R, G, B, A分量的位数. 10.1.1 颜色缓存 1) 颜色缓存存储了颜色索引或RGB颜色数据, 还可能存储了alpha值. 2) 支持立体观察(stereoscopic viewing)的OpenGL实现有左颜色缓存和右颜色缓存. 它们分别用于左立体图像和右立体图像. 3) 如不支持立体观察, 则只使用左颜色缓存. 4) 双颜色缓存有前缓存和后缓存, 单缓存系统只有前缓存. 5) 支持不可显示的辅助颜色缓存 6) 函数glGetBooleanv()查询是否支持立体观察和双缓存: GL_STEREO和GL_DOUBLE_BUFFER. 函数glGetIntegerv()查询多少个辅助缓存可用: GL_AUX_BUFFERES. 10.1.2 深度缓存 深度缓存 --- 存储了每个像素的深度值. 通常是离视点的距离, 因此深度值大的像素会被深度值小的像素覆盖. 10.1.3 模板缓存 用...

OpenGL 红宝书 纹理映射

图片
9.1 概述和范例 9.1.1 纹理映射的步骤 1) 创建纹理对象并为其指定纹理. 2) 指出如何将纹理应用于每个像素 3) 启用纹理映射 4) 使用纹理坐标和几何坐标来绘制场景. 只能RGBA模式下使用纹理映射 步骤: 1, 创建纹理对象并为其指定纹理 纹理不但是二维的,也可以是一维或三维的. 2. 指定如何将纹理应用于每个像素 根据片元的颜色和纹理图像数据计算最终的RGBA值的方法: 1) 将纹理颜色作为最终的颜色, 就像贴花(替换模式), 将纹理绘制到片元 2) 使用纹理来调整(缩放)片元的颜色 3) 根据纹理数据, 将一种常量颜色和片元混合起来. 3. 启用纹理映射 使用符号常量 GL_TEXTURE_1D, GL_TEXTURE_2D, GL_TEXTURE_3D, GL_TEXTURE_CUBE_MAP作为参数调用函数glEnable()或glDisable(); 分别对应于一维, 二维, 三维和立方图纹理映射模式 4. 使用纹理坐标和几何坐标绘制场景 9.2 指定纹理 void glTexImage2D(GLenum target,GLint level,GLint internalformat,GLsizei width,GLsizei height,         GLint border,GLenum format,GLenum type,const GLvoid *pixels); target: GL_TEXTURE_2D, GL_PROXY_TEXTURE_2D, GL_TEXTURE_CUBE_MAP_POSITIVE_X, GL_TEXTURE_CUBE_MAP_NEGATIVE_X, GL_TEXTURE_CUBE_MAP_POSITIVE_Y, GL_TEXTURE_CUBE_MAP_NEGATIVE_Y, GL_TEXTURE_CUBE_MAP_POSITIVE_Z, GL_TEXTURE_CUBE_MAP_NEGATIVE_Z,GL_PROXY_TEXTURE_CUBE_MAP level: 如果提供的纹理映射图有多种分辨率, 应相应地设置参数level, 如只有一种分辨率, level为0. internalformat...

OpenGL 红宝书 反走样 雾 点参数 多边形偏移

6.1 混合 6.1.1 源因子和目标因子 假定源和目标混合因子分别为(Sr, Sg, Sb, Sa)和(Dr,Dg,Db,Da), 混合后的RGB值如下: (RsSr + RdDr, GsSg + GdDg, BsSb + BdDb, AsSa + AdDa) 最后,将该四元组的各个分量截取到[0,1]. 将源片元和目标象素合并起来的默认方式是,将它们的值相加. 选择源混合因子和目标混合因子的方式: 第一种方式是调用函数glBlendFunc(),并指定两个混合因子, 其中第一个参数为源RGBA的混合因子, 第二个参数为目标RGBA的混合因子. 第二种方法是调用glBlendFuncSeparate()并指定4个混合因子, 这样可以用不同的方式来混合RGB和alpha值. void glBlendFunc(GLenum srcfactor, GLenum destfactor); srcfactor指出如何计算源混合因子; destfactor指出如何计算目标混合因子. void glBlendFuncSeparate(GLenum srcRGB, GLenum destRGB, GLenum srcalpha, GLenum destalpha); 源混合因子和目标混合因子 常量: RGB混合因子 alpha混合因子 GL_ZERO: (0, 0, 0) 0 GL_ONE: (1, 1, 1) 1 GL_DST_COLOR: (Rd, Gd, Bd) GL_SRC_COLOR: (Rs, Gs, Bs) A GL_ONE_MINUS_DST_COLOR: (1, 1, 1) - (Rd, Gd, Bd) GL_ONE_MINUS_SRC_COLOR: (1, 1, 1) - (Rs, Gs, Bs) 1 - A GL_SRC_ALPHA: (As,As,As,As) GL_ONE_MINUS_SRC_ALPHA: (1, 1, 1, 1) - (As,As,As,As) GL_DST_ALPHA: (Ad, Ad, Ad, Ad) GL_ONE_MINUS_DST_ALPHA: (1, 1, 1, 1) - (Ad, Ad, Ad, Ad) GL_SRC_ALPHA_STATURATE: (f, f, f,...

OpenGL 红宝书 混合

图片
6.1 混合 6.1.1 源因子和目标因子 假定源和目标混合因子分别为 (Sr, Sg, Sb, Sa) 和 (Dr,Dg,Db,Da), 混合后的 RGB 值如下 : (RsSr + RdDr, GsSg + GdDg, BsSb + BdDb, AsSa + AdDa) 最后 , 将该四元组的各个分量截取到 [0,1]. 将源片元和目标象素合并起来的默认方式是 , 将它们的值相加 . 选择源混合因子和目标混合因子的方式 : 第一种方式是调用函数 glBlendFunc(), 并指定两个混合因子 , 其中第一个参数为源 RGBA 的混合因子 , 第二个参数为目标 RGBA 的混合因子 . 第二种方法是调用 glBlendFuncSeparate() 并指定 4 个混合因子 , 这样可以用不同的方式来混合 RGB 和 alpha 值 . void glBlendFunc(GLenum srcfactor, GLenum destfactor); srcfactor 指出如何计算源混合因子 ; destfactor 指出如何计算目标混合因子 . void glBlendFuncSeparate(GLenum srcRGB, GLenum destRGB, GLenum srcalpha, GLenum destalpha); 源混合因子和目标混合因子 常量 : RGB 混合因子 alpha 混合因子 GL_ZERO: (0, 0, 0) 0 GL_ONE: (1, 1, 1) 1 GL_DST_COLOR: (Rd, Gd, Bd) GL_SRC_COLOR: (Rs, Gs, Bs) A GL_ONE_MINUS_DST_COLOR: (1, 1, 1) - (Rd, Gd, Bd) GL_ONE_MINUS_SRC_COLOR: (1, 1, 1) - (Rs, Gs, Bs) 1 - A GL_SRC_ALPHA: (As,As,As,As) GL_ONE_MINUS_SRC_ALPHA: (1, 1, 1, 1) - (As,As,As,As) GL_DST_ALPHA: (Ad, Ad, Ad, Ad) GL_ONE_MINUS_DST_ALPH...

深入理解计算机系统 第五章(一)

图片

c++语法大全记点(C语言部分)

C 语言五种基本数据类型 char int float double void C++ 程序中 , 局部变量的定义可以在程序的任何位置 C 标准库中的许多函数在它们的参数说明中 例 int strlen(const char *str); volatile 语句 . C 语言四个存储分类值 extern static register auto extern var_list 在别处说明过的变量表 static 用于隐藏 register 仅仅适用于局部变量和函数的形式参数 , 不允许全局 , 不能用 & 对寄存器变量进行地址操作 使用标准库函数 exit() 退出程序 函数若要接收一维数组 , 可用指针 , 有界数组 , 无界数组 形参 字符串操作函数   strcpy(s1,s2) 将 s2 拷贝到 s1  strcat(s1,s2) 将 s2 连接到 s1 的末尾   strlen(s1) s1 的长度 strcmp(s1,s2) 若 s1 与 s2 相等 —0, 若 s1<s2 小于 0, 若 s1>s2 大于 0,strchr(s1,ch) 返回一个指针指向 s1 中第一次出现字符 ch 的位置 strstr(s1,s2) 返回一个指针指向 s1 中第一次出现字符串 s2 的位置 P120 游戏程序 函数的指针问题 ? 149 第六章 函数 传给 main() 的变元 argc 和 argv argc 最少为 1 程序名为第一个变元 位域 struct tag {type name1:length; type name2:length; type name3:length;...} 181 第七章 结构联合枚举 205 第八章 I/O 231 第九章 fopen()    打开一个文件 fclose() 关闭一个文件 putc()     把一个字符输出到文件中 fputc() 同 putc() getc() 从某一文件读一字符 fgetc() 同 getc() fseek() 在文件中查一特定类型字符 fprintf() 输出到磁盘文件中 fscanf() 从磁盘文件中读数据 feof() 若到...