Qt OpenGL Font 的使用限制

這篇是之前《使用 QGraphicsScene 繪製 widget、產生 OpenGL Texture》和《使用 QGraphicsScene 繪製 widget、產生 OpenGL Texture:續》這兩篇的延伸,主要是針對 Qt OpenGL 裡面,字型的問題做一些研究紀錄。

老實說,最初一直以為 Qt 應該都處理掉了,應該可以一下就弄完,結果沒想到牽扯的問題很多,一堆問題還是無解…

首先,這邊最基本的需求,就是使用 QOpenGLPaintDevice,透過 QGraphicsScene 把 Qt 的圖形介面(QWidget)以 offscreen 的形式、畫成一個 OpenGL Texture。

而現在碰到的主要問題,則是兩個部分:

  • 文字大小超過一定程度,會變成黑框
  • 部分地方的繪製效果不一致
  • High DPI 設定造成顯示結果與預期不同

閱讀更多»

廣告

OpenVR 控制器的進階顯示方法

從買了 HTC Vive 後,Heresy 這邊一直有在研究怎麼用 OpenVR 這個 SDK 來開發 C++ 搭配 OpenGL 的虛擬實境程式,而實際上,到現在也算有些可以用的成品了。

而由於 Windows Mixed Reality 系統的頭戴顯示器(例如 Acer AH101)也可以透過「Windows Mixed Reality for SteamVR」來執行 OpenVR 的程式,所以當然也會想讓自己的程式可以支援 Windows MR 的硬體了~

基本上,在顯示的部分,只要透過 OpenVR 來開發,理論上就可以直接用(還是有些狀況就是了);但是在控制器的顯示部分,卻碰到了比較直接的問題…

那就是雖然在使用 HTC Vive 的時候是可以正確顯示的,但是在換成 Acer AH101,卻沒有辦法畫出控制器來。

閱讀更多»

使用 QGraphicsScene 繪製 widget、產生 OpenGL Texture:續

這篇基本上是之前《使用 QGraphicsScene 繪製 widget、產生 OpenGL Texture》一文的後續。

在當時,Heresy 有提過,如果真的用 QOpenGLPaintDevice 來給 QGraphicsScene 繪製到 Frame Buffer Object 上的話,會造成文字的破碎、無法識別的狀況;而 Heresy 當時的解法,是暫時放棄 OpenGL 繪圖,而讓 QGraphicsScene 先畫到 QImage 上(raster)、然後再把它傳到顯示當作為 OpenGL 的 texture。

理論上,這個方法的確是可行的,但是實際上,在後來使用的時候,卻發現:

當介面稍微多一些東西的時候,用 QGraphicsScene 把圖形介面畫在 QImage 上要花超過 150ms… orz

如果是一般視窗環境,或許還算勉強可以接受,但是在 VR 環境下,這樣連 10FPS 都到不了的速度,是完全無法被當作「堪用」的…

閱讀更多»

Qt OpenGL 的一些使用問題

這一篇,算是自己點單紀錄一下,目前使用 Qt 5 來開發 OpenGL 程式時,碰到的一些問題吧…

基本上,Heresy 對於整個 Qt OpenGL 的使用架構不算非常熟,也是邊寫邊摸,所以本文也不盡然正確,很大的機會應該有不少地方是使用錯誤…不過,基本上就算記錄下來,給自己以後參考用了。

首先,Qt 5 基本上應該算是已經深度整合 OpenGL/OpenGL ES 了~預設下載預先編譯好的版本,都有支援 OpenGL、而不用另外自行編譯了。

而他的主要文件,應該可以從《OpenGL and OpenGL ES Integration》這邊開始看。

閱讀更多»

使用 QGraphicsScene 繪製 widget、產生 OpenGL Texture

從去年開始,Heresy 就有在試著用 Qt 搭配 OpenVR,開發支援 SteamVR 的虛擬實境的程式。當時在寫的時候,一部分是參考 GitHub 上的「QVRViewer」這個專案(連結),也算是成功地把 Qt OpenGL(官網)的框架,成功地和 OpenVR 整合到一定程度了。

而接下來,則是希望可以在虛擬實境的環境裡面,顯示圖形介面的部分。這部分,則是參考了 OpenVR 的「helloworldoverlay」這個範例(連結);在它裡面的「openvroverlaycontroller.cpp」這個檔案(連結)就有把 Qt 的 Widget 繪製成 OpenGL Texture、並手動傳送滑鼠事件進去的操作方法。

首先,他這邊的概念,就是透過 Qt Graphics View Framework 的框架,來繪製 QWidget;而和一般使用 QGraphicsScene 時不同的地方,是這邊不會去使用 QGraphicsView 來做呈現,而是特別去設定要使用的 QPainter,來決定要畫到哪裡。

閱讀更多»

Boost 的另一個型別轉換函式庫:Convert

在幾年前,Heresy 曾經寫了一篇《在文字和數字間轉換:boost::lexical_cast》,來介紹 Boost C++ Libraries 裡的 lexical_cast 這個函式庫;他的基本功能,就是來將文字、和其他的資料型別做轉換。

在 Heresy 當時看來,這個函式庫算是相當方便的~就算是自定義的型別,也可以透過實作 operator << 和 >> 來支援 lexical_cast。整體來說,他應該是可以簡化一些型別轉換時的程式寫法的。

不過,他還是有一些限制與問題在。除了效能不算很好外,他的錯誤處理方法也只有 exception 一種,此外更不支援格式化的設定,這讓他在某些情況下,不是很好用。

所以,在 Boost 1.59.0 的時候,Boost 又加入了另一個名為「Convert」的函式庫(官網),希望可以解決 lexical_cast 的這些問題。

閱讀更多»

C++17 更通用的 union:variant

std::variantC++17 中,一個新加入標準函式庫的 template 容器;他的概念基本上是和 union參考)一樣,是一個可以用來儲存多種型別資料的容器。

比如說:

std::variant<int, double> v;

就代表 v 這個變數,可以用來儲存 intdouble 的資料,variant 內部自己會去記錄相關的資訊。

而和 union 不同的地方,variant 也是 type-safe 的,再加上有許多函式可以搭配使用,所以在使用上應該算是相對安全;另外也由於他是標準函式庫的 template class,在使用時不需要另外去宣告一個新的型別。

閱讀更多»

使用 gcc 建置 Boost 時開啟 c++11 的功能

Heresy 在 2010 年開始使用 Boost C++ Libraries(官網)的時候,已經有寫過一篇《Boost C++ Libraries 簡介》,大致介紹過這套半 C++ 官方的函式庫集合,以及他的建置方法了。

而之後,其實也有寫了不少文章,來介紹裡面的一些函式庫(參考)。

至於這一篇呢,則是簡單紀錄一下,在 Linux 環境下如果想要自行建置 Boost 的話,要怎麼開啟 c++11 的支援。

閱讀更多»

一些比較少人知道的 VisualStudio 偵錯功能

這篇主要是針對微軟 VisualStudio Team 部落格的《7 lesser known hacks for debugging in Visual Studio》和《7 More Lesser-known Debugging Tactics for Visual Studio》這兩篇文章,做簡單的整理。

在 Heresy 來看,微軟的 Visual Studio 算是目前數一數二的程式開發環境。不過另一方面,它的功能也相當地多,多到一般人應該有超過七成的功能都沒有用過。而在這些從來沒用過、甚至從來不知道的功能裡面,其實有些是相當實用、相當方便的!

微軟在這邊就是列出了 7 + 7 個罕為人知的 debug 技巧,來分享給開發者;不過裡面有的內容是針對 C# 這類 managed code 的,有的則是針對原生 C++ 的,並非全部都可以使用。

而這邊 Heresy 則是稍微再重新整理一些 C++ 可以用、個人也覺得比較有用的出來了~

另外,這邊所列的功能,大多是在 Visual Studio 2015 就已經有的,不過還是有部分功能是 Visual Studio 2017 才有的;如果是 2017 才有的,這邊也會特別強調。

閱讀更多»

Ubuntu 16 遇到的 g++ 5.x ABI 不相容問題

Heresy 目前開發跨平台的 C++ 程式的時候,主要是透過 Windows 10 的「Bash on Ubuntu on Windows」這個 Windows Subsystem for Linux(WSL)來進行操作的。

在微軟剛貼出的時候,他的 Ubunutu 版本還是 14,而後來在微軟推出 Creators Update (1703) 的時候,也把 Ubuntu 的版本升級到 16.04 了~而在 Ubuntu 系統版本升級的同時,系統預設使用的編譯器也由 g++ 4.x 更新到 g++ 5.x 了。

而也因為這樣,當 Heresy 要做 Linux 環境的建置測試的時候,也碰到了一些問題,這邊就稍微紀錄一下了。

首先,會有問題的主要原因,是 GCC5.1 在發布的同時,也推出了新的 libstdc++;而這個 C++ 的標準函式庫為了符合 C++11 的標準,重新實作了 std::stringstd::list;而這兩個類別由於遵循了新的規範(禁止 Copy-On-Write),所以變得和舊版的函式庫不相容。

為了避免混亂,gcc 5.1 修改了對應的 ABI(Application binary interface),像是 std::list<int> 實際上會是定義成 std::__cxx11::list<int> 的形式;基本上,就是有部分標準函式庫的東西的 namespace 會從 std 變成 std::__cxx11 了。

閱讀更多»