如果想要特別讀取 BMP、JPEG 或 PNG 檔案,通常都會需要撰寫 Reder,但除了 BMP 之外其他的格式讀取或寫入都較為複雜,所以說一般建議使用已經開發好的函式庫即可。
stb_image.h
到專案根目錄,Github 載點。.cpp
檔案,名稱隨意,裡面內容如下:main.cpp
)引入標頭檔,即可開始使用 stb 圖片函式庫了!stb
函式庫。CMakeLists.txt
加上相關設定.cpp
檔案,名稱隨意,裡面內容如下:main.cpp
)引入標頭檔,即可開始使用 stb 圖片函式庫了!讀取圖片的方式,就是這麼如此簡單:
由於 OpenGL 的 Texture Coordinate 中,原點 (0, 0)
是在左下角,而一般來說圖片索引的 (0, 0)
會是左上角(想想陣列的概念),所以讀取出來的圖片會是上下顛倒的,這個時候可以透過下列函式來矯正它:
記得要在呼叫
stbi_load()
之前。
除了使用 stb_image.h
之外,還可以使用 SDL2 自己的衍生函式庫 SDL2-Image
來實現讀取圖片的功能。
sdl2-image
函式庫。CMakeLists.txt
做相關設定:SDL2-Image
了。讀取圖片的方式,就是這麼如此簡單:
很可惜的是,SDL2-Image
沒有提供垂直翻轉的函式可以呼叫,所以這邊只能自己寫函式去翻轉圖片,或者是另一個方法..,把 Texture Coordinate 的 Y 顛倒過來(雖然是最簡單但是不建議)。
當你有開始有讀取外部圖片的需求時,就會發現圖片路徑是一個很大的問題,比如說你在主程式寫說要讀取 assets\textures\doge.png
(相對路徑寫法),但編譯後執行程式卻說一直找不到該檔案,除非你改成絕對路徑寫法,比如 C:\uers\user\Desktop\CGHomework05\assets\textures\doge.png
才可以讀取,但問題是這樣的寫法很不明智,因為代表就已經寫死你的專案必須要放在桌面,一旦改變了路徑或是換了地方又整個要重改。
之所以會有這樣的原因,就是因為你認為的【相對】路徑中的相對是基於 main.cpp
,而事實上不是,是【相對於你最終編譯出來的執行檔】,舉例來說使用 Visual Studio 編譯的話,最終的程式(.exe
)會產生在路徑 CGHomework05\out\build\x64-Debug
當中,所以說在 main.cpp
所寫的圖片路徑(假設是 assets\textures\doge.png
),程式的路徑反而是會抓取 CGHomework05\out\build\x64-Debug\assets\textures\doge.png
,而非我們預期的 CGHomework05\assets\textures\doge.png
。
或許會有人就乾脆把在專案根目錄(CGHomework05
)下的外部資源檔案全部手動複製到建置目錄下(CGHomework05\out\build\x64-Debug\
),雖然可以解決方法但一樣換湯不換藥,畢竟建置目錄內的東西可是會隨著不同電腦、不同環境、不同 IDE、不同建置器和不同編譯器就會有所不一樣,所以說強烈不建議這樣做。
最好的解法就是透過 CMake 來自動幫我們處理,只要輸入以下語法即可:
add_custom_command()
代表是我們可以透過該函式來執行一些自定義的指令,來達成一些我們可能會需要的事情,大概就式輸入指令到終端機的概念。POST_BUILD
意思是【建置後事件】,也就說當程式建置好後才會觸發指令,除此之外還有 PRE_BUILD
和 PRE_LINK
。COMMAND
就是用來執行命令的意思。DEPENDS
就是依賴條件,當某檔案不存在時將會出錯。VERBATIM
大概就是命令的所有參數都將為構建工具正確轉義,總之 CMake 官方文件建議使用。而上述指令大致上的意思就是說,在程式建置好後會輸入以下指令:
而這個指令的意思就是建立符號連結(Symbolic Link),如果是熟悉類 Unix 系統的使用者想必很熟悉,但 Windows 使用者可能就未必了,基本上這個東西跟 Windows 上的捷徑(.lnk
)是截然不同的東西,功能雖然很像但基本上是完全不一樣,根據微軟官方的解釋,【符號連結是指向另一個檔案系統物件的檔案系統物件】,符號連結在檔案總管中會顯示為一般檔案或者是目錄,使用者或應用程式可以用完全相同的方式處理或是存取它們。
現在知道這個指令是在創建符號連結,但是路徑到底是哪裡呢?我們可以看出這邊有 CMake 的變數:${CMAKE_CURRENT_SOURCE_DIR}
和 $<TARGET_FILE_DIR:目標名稱>
,前者為你當前 CMakeLists.txt
的所在根目錄,後者則是 CMake 生產器表達式,它的語法其實是 $<TARGET_FILE_DIR:tgt>
,這其中的 tgt
就是你專案的目標名稱,比如說 add_executable(my-target)
,那 my-target
就是你的目標名稱,但如果你是有設定變數的話,例如 set(MY_EXECUTABLE "my-target")
,那你的目標名稱反而要變成 ${MY_EXECUTABLE}
。
回到主題,$<TARGET_FILE_DIR:目標名稱>
回傳的就是你程式建置好的所在目錄(可以說是建置根目錄),所以我們只要把符號連結建立在該目錄下,你的外部檔案就可以被程式讀取到了。
CMake 可以透過參數 -E
來實現例如建立符號連結 create_symlink
、複製資料夾 copy_directory
、刪除檔案 remove
、cat
和 touch
等行為。
如果你會發生以下錯誤的話:
其解決方案很簡單,就是到【設定】->【更新與安全性】->【開發人員專用】,然後將【開發人員模式】給它開啟起來就解決了:
如果你會發生以下錯誤的話:
其解決方案很簡單,把整個建置資料夾刪除,並且也清除掉 CMake 快取,重新建立就可以解決了。
OpenGL