天天看點

NeHe OpenGL教程 第四十六課:全屏反走樣

前言

NeHe OpenGL第四十六課:全屏反走樣

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);

// 如果都不支援,則傳回失敗

return false;

// 查找是否包含需要的擴充名

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

{

p = strstr(p, extension);

if (p == NULL)

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;

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;

// 傳回支援多重采樣

下面到了我們的主程式部分了,和前面一樣還是按照正常包含一些頭檔案  

#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);

原文及其個版本源代碼下載下傳:

<a href="http://nehe.gamedev.net/data/lessons/lesson.asp?lesson=46">http://nehe.gamedev.net/data/lessons/lesson.asp?lesson=46</a>

沒有整理與歸納的知識,一文不值!高度概括與梳理的知識,才是自己真正的知識與技能。 永遠不要讓自己的自由、好奇、充滿創造力的想法被現實的架構所束縛,讓創造力自由成長吧! 多花時間,關心他(她)人,正如别人所關心你的。理想的騰飛與實作,沒有别人的支援與幫助,是萬萬不能的。

    本文轉自wenglabs部落格園部落格,原文連結:http://www.cnblogs.com/arxive/p/6239553.html,如需轉載請自行聯系原作者

繼續閱讀