你好,歡迎來到IOS教程網

 Ios教程網 >> IOS編程開發 >> IOS開發基礎 >> OpenGL雜談之復用GLSL代碼

OpenGL雜談之復用GLSL代碼

編輯:IOS開發基礎

原文

歡迎訪問我的個人主頁了解更多關於OpenGL的知識

前言

GLSL是OpenGL的著色語言,在編寫GLSL的過程中,復用代碼是一件比較麻煩的事情,GLSL基本是不支持#include預編譯指令的。

目前我已知的OpenGL對於GLSL include的支持僅限於擴展ARB_shading_language_include,如果你的系統支持該OpenGL擴展,那麼你就可以在GLSL中使用include。不過似乎只有nvidia的OpenGL驅動對它有支持。

復用GLSL代碼的級別

既然官方的include使用如此艱難,我們就來自己造輪子吧。首先我們要確定在什麼級別復用代碼。有兩種選擇:

  • 程序代碼運行時將可復用的GLSL代碼塊合並成可運行的GLSL代碼。

  • 程序編譯時跑一個腳本,將可復用的GLSL代碼合並成可運行的GLSL文件,然後在運行時使用生成好的GLSL文件。

我之前嘗試過第一種方法,運行時合並GLSL代碼,不過調試不是很方便,報錯時不好定位到哪行,而且運行時生成終究會消耗一些性能。所以這一次我打算探索第二條路。

預編譯工具m4

在研究第二種方式時,碰巧找到了一個非常符合解決本次問題的工具m4。m4說白的就是一個預編譯工具,將寫有宏的文本進行預編譯展開。如果你使用Mac。在終端輸入

m4 --version

如果得到如下,恭喜你,你已經擁有了此工具。

GNU M4 1.4.6
Copyright (C) 2006 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

Written by Rene' Seindal.

當然你也可能是其他版本。如果沒有出現,你可以使用homebrew安裝。

brew install m4

如果你喜歡使用源碼安裝,可以訪問m4的官網。

m4的使用示例

我們先來寫一個例子來感受一下m4的功能。在同一個目錄下創建2個文件,Test.m4和inc.m4。

在inc.m4中輸入下面內容。

這裡是被包含的內容

在Test.m4中我們做兩件事情,包含inc.m4,定義一個變量。

include(`inc.m4')
define(`content', `例子')

這是一個content

注意,inc.m4左邊不是單引號,是`,右邊是單引號。content和 例子也是一樣。include(`inc.m4')將inc.m4包含到Test.m4中,define(`content', `例子')將例子這個值賦給content。我們使用m4預處理一下看看結果。在終端運行。

m4 Test.m4

結果如下。

這裡是被包含的內容


這是一個例子

將m4運用於GLSL

下面是我的一個GLSL程序結構目錄,我使用m4將這些復用代碼合並到一起。

這裡我寫了兩個光照模型,lambert_phong和lambert_blinn,它們大部分代碼都是一樣的,只有高光部分代碼不一樣。targets文件夾下是最終被m4處理的文件。處理完後直接被OpenGL使用。我們看一下其中的一個文件frag_lambert_phong.glsl。

// defines
include(`fragment shader components/frag_base_header.glsl')
include(`fragment shader components/frag_structs.glsl')
include(`fragment shader components/frag_in_vars.glsl')
include(`fragment shader components/frag_uniform_vars.glsl')

// functions
include(`fragment shader components/frag_normal.glsl')
include(`fragment shader components/frag_light_base.glsl')
include(`fragment shader components/frag_light_lambert.glsl')
include(`fragment shader components/frag_light_phong.glsl')

// light model
include(`fragment shader light model/frag_light_model_lambert_phong.glsl')

其實我只用到了m4的include功能,我們將這個文件和frag_lambert_blinn對比一下。

// defines
include(`fragment shader components/frag_base_header.glsl')
include(`fragment shader components/frag_structs.glsl')
include(`fragment shader components/frag_in_vars.glsl')
include(`fragment shader components/frag_uniform_vars.glsl')

// functions
include(`fragment shader components/frag_normal.glsl')
include(`fragment shader components/frag_light_base.glsl')
include(`fragment shader components/frag_light_lambert.glsl')
include(`fragment shader components/frag_light_blinn.glsl')

// light model
include(`fragment shader light model/frag_light_model_lambert_blinn.glsl')

只有最後兩個include不一樣,很好的滿足了我復用GLSL的需求。最後我寫了一個簡單的腳本批量處理targets下的文件。

#!env python

import os
import subprocess

target_files = os.listdir("./targets")

for file in target_files:
    print("building " + file + "...")
    command = str.format("m4 ./targets/{0} > ../{0}", file)
    subprocess.call(command, shell=True)
    print(file + " build finish.")

將這個腳本集成到你的編譯系統中,就可以做到完全自動化復用和預處理GLSL了。

作者:handyTOOL

鏈接:http://www.jianshu.com/p/960337be3547

來源:簡書

著作權歸作者所有。商業轉載請聯系作者獲得授權,非商業轉載請注明出處。

  1. 上一頁:
  2. 下一頁:
蘋果刷機越獄教程| IOS教程問題解答| IOS技巧綜合| IOS7技巧| IOS8教程
Copyright © Ios教程網 All Rights Reserved