转自【翻译】NeHe OpenGL 教程

前言

声明,此 NeHe OpenGL教程系列文章由51博客yarin翻译(2010-08-19),本博客为转载并稍加整理与修改。对NeHe的OpenGL管线教程的编写,以及yarn的翻译整理表示感谢。

NeHe OpenGL第四十六课:全屏反走样

全屏反走样

当今显卡的强大功能,你几乎什么都不用做,只需要在创建窗口的时候该一个数据。看看吧,驱动程序为你做完了一切。

 

在图形的绘制中,直线的走样是非常影响美观的,我们可以使用反走样解决这个问题。在众多的解决方案里,多重采样是一种易于硬件实现的方法,也是一种快速的方法。

全凭多重采样可以使你的图形看起来更美观,我们可以使用ARB_MULTISAMPLE扩展完成这个功能,但它会降低你的程序的速度。

 

Vid_mem = sizeof(Front_buffer) + sizeof(Back_buffer) + num_samples  * (sizeof(Front_buffer) +sizeof(ZS_buffer))

  

如果你想知道更多的关于多重采样的信息,请访问下面的链接:

GDC2002 -- OpenGL Multisample

OpenGL Pixel Formats and Multisample Antialiasing

下面我们来介绍如何使用多重采样,不向其他的扩展,我们在使用多重采样时,必须在窗口创建时告诉它使用多重采样,典型的步骤如下:

1、创建一个窗口

2、查询是否支持多重采样

3、如果支持删除当前的窗口,使用支持多重采样的格式创建窗口

4、如果我们想使用多重采样,仅仅启用它既可。

了解了上面,我们从头说明如何使用多重采样,并介绍ARB_Multisample的实现方法:

 

#include <windows.h>#include <gl.h>#include <glu.h>#include "arb_multisample.h"

下面两行定义我需要使用的像素格式 

  

// 声明我们将要使用#define WGL_SAMPLE_BUFFERS_ARB 0x2041#define WGL_SAMPLES_ARB  0x2042

bool arbMultisampleSupported = false;

int arbMultisampleFormat = 0;

下面这个函数在扩展名的字符串中查找,如果包含则返回true

 

// 判断是否支持这个扩展bool WGLisExtensionSupported(const char *extension){ const
size_t extlen = strlen(extension); const char *supported = NULL;

// 返回在WGL的扩展中查找是否支持特定的扩展

PROC wglGetExtString = wglGetProcAddress("wglGetExtensionsStringARB");

if (wglGetExtString)

supported = ((char*(__stdcall*)(HDC))wglGetExtString)(wglGetCurrentDC());

//在OpenGL的扩展中查找是否支持特定的扩展

if (supported == NULL)

supported = (char*)glGetString(GL_EXTENSIONS);

// 如果都不支持,则返回失败

if (supported == NULL)

return false;

// 查找是否包含需要的扩展名

for (const char* p = supported; ; p++)

{

p = strstr(p, extension);

if (p == NULL)

return false;

if ((p==supported || p[-1]==' ') && (p[extlen]=='\0' || p[extlen]==' '))

return true;

}

}

下面这个函数在扩展名的字符串中查找,如果包含则返回true 

  

// 初始化多重渲染bool InitMultisample(HINSTANCE hInstance,HWND
hWnd,PIXELFORMATDESCRIPTOR pfd){    // 检测是否支持多重渲染 if
(!WGLisExtensionSupported

("WGL_ARB_multisample")) {  arbMultisampleSupported=false;  return false; }

// 返回wglChoosePixelFormatARB函数的入口

PFNWGLCHOOSEPIXELFORMATARBPROC wglChoosePixelFormatARB =
(PFNWGLCHOOSEPIXELFORMATARBPROC)wglGetProcAddress("wglChoosePixelFormatARB");


if (!wglChoosePixelFormatARB)

{

arbMultisampleSupported=false;

return false;

}

HDC hDC = GetDC(hWnd);

int pixelFormat;

int valid;

UINT numFormats;

float fAttributes[] = {0,0};

//下面的代码设置多重采样的像素格式

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

};

// 首先我们测试是否支持4个采样点的多重采样

valid = wglChoosePixelFormatARB(hDC,iAttributes,fAttributes,1,&pixelFormat,&numFormats);

// 如果返回true并且numformats大于1,则表示成功,那么起用多重采样

if (valid && numFormats >= 1)

{

arbMultisampleSupported = true;

arbMultisampleFormat = pixelFormat;

return arbMultisampleSupported;

}

// 接着我们测试是否支持2个采样点的多重采样

iAttributes[19] = 2;

// 如果返回true并且numformats大于1,则表示成功,那么起用多重采样

valid = wglChoosePixelFormatARB(hDC,iAttributes,fAttributes,1,&pixelFormat,&numFormats);

if (valid && numFormats >= 1)

{

arbMultisampleSupported = true;

arbMultisampleFormat = pixelFormat;

return arbMultisampleSupported;

}

// 返回支持多重采样

return arbMultisampleSupported;

}

下面到了我们的主程序部分了,和前面一样还是按照常规包含一些头文件 

  

#include <windows.h>        #include <gl/gl.h>

#include <gl/glu.h>       #include "NeHeGL.h" 

  #include "ARB_MULTISAMPLE.h"

BOOL DestroyWindowGL (GL_Window* window);

BOOL CreateWindowGL (GL_Window* window);

下面我们需要在CreateWindowGL函数中添加下面的代码,首先我们先创建一个不需要支持多重采样的窗口,它在不启用多重采样的情况下起作用。 

  

 //如果不启用多重采样 if(!arbMultisampleSupported) {  PixelFormat = ChoosePixelFormat (window->hDC, &pfd);

// 选择一种相容的像素格式  if (PixelFormat == 0)            // 是否获得相容

的像素格式  {

ReleaseDC (window->hWnd, window-

>hDC);       // 释放设备描述表   window->hDC = 0;

// 设置窗口设备描述表为0   DestroyWindow (window->hWnd);

// 删除窗口   window->hWnd = 0;

// 设置窗口句柄为0   return FALSE;             // 返回错误

}

}

//如果起用多重采样

else

{

PixelFormat = arbMultisampleFormat; //设置采样格式为多重采样格式

}

接着测试是否支持多重采样,如果支持,初始化多重采样,并重新创建窗口

//检测是否支持多重采样 if(!arbMultisampleSupported && CHECK_FOR_MULTISAMPLE) {  //如果是,初始化多重采样  if(InitMultisample

(window->init.application->hInstance,window->hWnd,pfd))  {   //消耗当前窗口   DestroyWindowGL (window);

//创建一个支持多重采样的窗口   return CreateWindowGL(window);  } }

好了创建好多重采样后,只需要起用它。其他的一切绘制都和平常一样。

glEnable(GL_MULTISAMPLE_ARB);

// 渲染场景

glDisable(GL_MULTISAMPLE_ARB);

原文及其个版本源代码下载:

http://nehe.gamedev.net/data/lessons/lesson.asp?lesson=46

 
 

NeHe OpenGL教程 第四十六课:全屏反走样的更多相关文章

  1. NeHe OpenGL教程 第三十六课:从渲染到纹理

    转自[翻译]NeHe OpenGL 教程 前言 声明,此 NeHe OpenGL教程系列文章由51博客yarin翻译(2010-08-19),本博客为转载并稍加整理与修改.对NeHe的OpenGL管线 ...

  2. NeHe OpenGL教程 第四十八课:轨迹球

    转自[翻译]NeHe OpenGL 教程 前言 声明,此 NeHe OpenGL教程系列文章由51博客yarin翻译(2010-08-19),本博客为转载并稍加整理与修改.对NeHe的OpenGL管线 ...

  3. NeHe OpenGL教程 第四十五课:顶点缓存

    转自[翻译]NeHe OpenGL 教程 前言 声明,此 NeHe OpenGL教程系列文章由51博客yarin翻译(2010-08-19),本博客为转载并稍加整理与修改.对NeHe的OpenGL管线 ...

  4. NeHe OpenGL教程 第四十二课:多重视口

    转自[翻译]NeHe OpenGL 教程 前言 声明,此 NeHe OpenGL教程系列文章由51博客yarin翻译(2010-08-19),本博客为转载并稍加整理与修改.对NeHe的OpenGL管线 ...

  5. NeHe OpenGL教程 第四十四课:3D光晕

    转自[翻译]NeHe OpenGL 教程 前言 声明,此 NeHe OpenGL教程系列文章由51博客yarin翻译(2010-08-19),本博客为转载并稍加整理与修改.对NeHe的OpenGL管线 ...

  6. NeHe OpenGL教程 第四十课:绳子的模拟

    转自[翻译]NeHe OpenGL 教程 前言 声明,此 NeHe OpenGL教程系列文章由51博客yarin翻译(2010-08-19),本博客为转载并稍加整理与修改.对NeHe的OpenGL管线 ...

  7. NeHe OpenGL教程 第三十八课:资源文件

    转自[翻译]NeHe OpenGL 教程 前言 声明,此 NeHe OpenGL教程系列文章由51博客yarin翻译(2010-08-19),本博客为转载并稍加整理与修改.对NeHe的OpenGL管线 ...

  8. NeHe OpenGL教程 第三十五课:播放AVI

    转自[翻译]NeHe OpenGL 教程 前言 声明,此 NeHe OpenGL教程系列文章由51博客yarin翻译(2010-08-19),本博客为转载并稍加整理与修改.对NeHe的OpenGL管线 ...

  9. NeHe OpenGL教程 第三十二课:拾取游戏

    转自[翻译]NeHe OpenGL 教程 前言 声明,此 NeHe OpenGL教程系列文章由51博客yarin翻译(2010-08-19),本博客为转载并稍加整理与修改.对NeHe的OpenGL管线 ...

随机推荐

  1. Android BaseAdapter 数据和显示之间的Adapter 接口

    http://www.cnblogs.com/mandroid/archive/2011/04/05/2005525.html

  2. row_number() OVER(PARTITION BY)函数介绍

      OVER(PARTITION BY)函数介绍 开窗函数               Oracle从8.1.6开始提供分析函数,分析函数用于计算基于组的某种聚合值,它和聚合函数的不同之处是:对于每个 ...

  3. 在Linux中使用vi打开文件时如何显示行号,及跳转到指定行

    vi 文件名,打开文件后 如果要显示所有行号,使用 :set nu 如果要显示当前行号,使用 :nu 如果要跳转到指定行,使用 :行号 例如,跳转到第10行,使用 :10

  4. 无任何网络提供程序接受指定的网络路径(系统服务里没有workstation服务)

    今天同事访问公司服务器时,提示“无任何网络提供程序接受指定的网络路径”,网络ping正常,把防火墙关掉,再次尝试问题如故. 于是上网搜索: 1.服务停止:一般有workstation,server,c ...

  5. CSS3制作漂亮的照片墙

    CSS3可以做动画大家肯定都是耳熟能详的了,但是大家有木有巧妙的利用这一个功能来制作一款漂亮的照片墙呢? 那么今天我们就利用CSS3动画这一特性来一起制作漂亮的照片墙吧! 第一部分:HTML 这里我们 ...

  6. Material Design之TextInputLayout使用示例

    Google在2015的IO大会上,给我们带来了更加详细的Material Design设计规范,同时,也给我们带来了全新的Android Design Support Library,在这个supp ...

  7. UIActionSheet的使用

    UIActionSheet是在iOS弹出的选择按钮项,可以添加多项,并为每项添加点击事件. 为了快速完成这例子,我们打开Xcode 4.3.2, 先建立一个single view applicatio ...

  8. enmo_day_08

    性能监视 管理内存组件 自动内存管理(AMM) : 指定分配给实例的总内存(SGA, PGA) 自动共享内存管理(ASMM) : 指定SGA, 管理分配给共享池, java池, 动态性能视图 :v$( ...

  9. jvm1

    字节码常量池: 01开头的说明是一个utf-8编码的常量,那么后面就一定要跟两个字节也就是四位16进制的数,来表示这个常量占几个字节,然后后面再跟与这个字节数对应长度的utf-8编码的字符串.之所以一 ...

  10. Hibernate原生SQL查询多表关联,SQL语句要注意的问题

    Hibernate原生SQL查询多表关联,SQL语句要注意的问题 @for&ever 2009-9-4 系统环境: MySQL5.1 Hibernate3.3 有如下的假定: 实体类 Ques ...