2010-05-25 84 views
2

我一直負責解決我的知識領域之外的問題,並且我希望能夠從更熟練的openGL人員那裏獲得一些故障排除建議(我非常喜歡對OpenGL有一點經驗)。我們正在研究一個跨平臺的應用程序,這個程序是在一個叫做ccl的通用lisp實現中實現的。在這個應用程序中,我們需要顯示一些顯示文本的3D對象。在Mac上,所有的文本都可以很好地顯示,但是在PC上而不是顯示文本時會顯示其他紋理。起初,我認爲可能是錯誤的紋理被引用,所以我嘗試更改紋理編號,但是列表中的紋理都不是文本(或者紋理被扭曲,看起來不像文本)。我知道這個問題非常模糊,我不是在尋找某人發佈解決方案,但我想知道是否人們可以建議我可能會試着去嘗試解決這個問題的地方。問題解決openGL文本紋理不能正確顯示跨平臺

當我添加打印語句來打印寬像素和像素高的文件時,最終從文件創建紋理的方法(對不起,代碼使用cocoa/cocotron在lisp中編寫) 2的冪(512):

(defun CREATE-IMAGE-FROM-FILE (Filename &key Verbose Forced-Depth (Flip-Vertical t)) " 
in: Filename string-or-pathname, &key Verbose boolean, Forced-Depth int, 
out: Pixels byte-vector, 
    Width Height Forced-Depth int; Has-Alpha boolean. 
    Create an image buffer from <Filename> 
    - File must be 32 bit ARGB compatible, e.g., .png with mask or 24 bit RGB." 
(print "CREATE IMAGE FROM FILE") 
(print Filename) 
(when Verbose (format t "CREATE-IMAGE-FROM-FILE: ~A~%" Filename)) 
(let* ((Image-Representation (#/retain (ns-image-rep-from-file (native-string  (namestring (translate-logical-pathname Filename))))))) 
;; should massage data: GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV for best performance 
;; http://developer.apple.com/documentation/graphicsimaging/Conceptual/OpenGL-MacProgGuide/opengl_texturedata/opengl_texturedata.html 
(when (%null-ptr-p Image-Representation) 
    (format t "~%missing texture ~S" Filename) 
    (return-from create-image-from-file)) 
;; do the OpenGL vertical image flip 
(when Flip-Vertical 
    (flip-vertical-buffer 
    (#/bitmapData Image-Representation) 
    (* (#/bytesPerRow Image-Representation) (#/pixelsHigh Image-Representation)) 
    (#/bytesPerRow Image-Representation))) 
(print (#/pixelsWide Image-Representation)) 
(print (#/pixelsHigh Image-Representation)) 
(values 
(#/bitmapData Image-Representation) 
(#/pixelsWide Image-Representation) 
(#/pixelsHigh Image-Representation) 
(#/bitsPerPixel Image-Representation) 
(#/hasAlpha Image-Representation) 
(#/bitmapFormat Image-Representation)))) 


(defmethod DISPLAY-VERTEX-ARRAYS ((Self string-shape)) 
    (glEnable gl_texture_2d) 
    (cond 
    ;; Color! 
    ((color-vector Self) 
    (glcolor3ubv (color-vector Self)) 
    (gltexenvi gl_texture_env gl_texture_env_mode gl_blend)) 
    ;; Black 
    (t 
    (gltexenvi gl_texture_env gl_texture_env_mode gl_modulate))) 
    (glbindtexture gl_texture_2d (texture (font Self))) 
    (glInterleavedArrays GL_T2F_V3F (va-stride Self) (vertex-arrays Self)) 
    (glDrawArrays gl_quads 0 (va-elements-count Self)) 
    (gltexenvi gl_texture_env gl_texture_env_mode gl_modulate) 
    (glDisable gl_texture_2d) 
    ;; if color was use better reset to white? 
    (when (color-vector Self) (glColor3f 1.0 1.0 1.0))) 

alt text http://www.freeimagehosting.net/uploads/e2eaeeca57.png

alt text http://www.freeimagehosting.net/uploads/0a84c32403.png

+0

聽起來像你沒有妥善管理你的記憶。你能提供至少代碼片段或截圖嗎? – 2010-05-26 03:40:26

+0

我添加了一些截圖,第一個截圖是我們在OSX上運行的示例之一(文本顯示正常),第二個示例在Windows 7上運行(看起來,而不是使用正確的紋理文本對象正在使用紋理的盒子)。我會在發佈代碼片段時遇到麻煩,因爲我仍然不確定代碼中發生問題的位置。 – Mike2012 2010-05-26 17:36:24

回答

2

這是在黑暗中拍攝的照片,但是字體往往會很早就建立起來,因爲沒有文字就沒有樂趣。因此,請檢查wglMakeCurrent的第一個電話先於glGenTextures用於創建字體紋理的名稱。更一般地說,儘管我只用過C++的OpenGL,但我還是遇到了一些奇怪的行爲,我不得不追蹤到這些行爲。所以我建議兩件事,我發現直接使用OpenGL時有幫助:

首先,在儘可能多的地方插入對glGetError的調用。在每次OpenGL調用之後加入 - 除了調用wglMakeCurrent來取消激活當前上下文外,因爲glGetError總是返回一個沒有上下文的錯誤 - 總是很好。

一些簡單的像assert(glGetError()==GL_NO_ERROR)是一個合理的開始(或挑闖入,讓你堅持下去呢,看看接下來會發生什麼調試器的任何行吟詩人方法),如果你檢查文檔爲glGetError你也許可以想出一些更全面。其次,至少在Windows上,確保您始終使用有效的當前上下文進行操作。這對於生成紋理名稱的glGenTextures的調用尤其重要。

assert(wglGetCurrentContext())會在這裏執行這個技巧,理想情況是在OpenGL調用的每個塊之前,當然除了調用wglMakeCurrent來調用當前上下文之外。

0

這裏是我的2美分。

我遇到了紋理奇怪大小的問題。當支持ARB_texture_non_power_of_two擴展時,理論上圖形系統可以用不具有兩個範圍的非功率的尺寸管理紋理,但實際上它不具有任何組合。

我發現,在NVIDIA®(英偉達™)卡上,在Windows操作系統上,不具有倍數2的2D紋理無法正確顯示(例如,231x73),並且與某些其他NVIDIA卡無法管理紋理,是4的倍數(可能是驅動程序,也許是圖形卡,還是未知的問題)。

所以,我的建議是調查紋理大小。

+0

非常感謝您的建議,但不幸的是,這似乎不成問題。我添加了實際創建紋理的代碼,並且當您查看像素寬度和高度時,它們都是512. – Mike2012 2010-05-26 22:52:29

0

繪製框後繪製的文本是?

對於我來說,打開文本紋理時看起來不像打開文本紋理時的問題。

0

Kim Reece在正確的軌道上。人們可以說,這些盒子的紋理狀態正在泄漏到單詞的渲染中。您發佈的代碼不是問題的根源。您需要找到實際渲染框和單詞的代碼,並確保在繪製單詞poly之前使用glBindTexture綁定字體紋理。現在,其中一些取決於您的應用程序是使用「原始」OpenGL還是使用頂級庫來構建「場景圖」,並將這些低級細節抽象出來。你能發佈更多關於你正在使用的信息嗎?

CCL很棒!我曾經幾乎完全使用它。

+0

非常感謝您的建議Tim和Kim Reece。我發佈了上面實際繪製文本對象的代碼。它是一種叫做display-vertex-arrays的方法,它可以從draw方法中調用(draw方法基本上是推動,做一些縮放,調用display-vertex-arrays然後彈出)。看起來這個方法實際上在繪製頂點數組之前調用glbindtexture。 我同意CCL很漂亮! – Mike2012 2010-06-03 17:53:00

+0

您可能會檢查(紋理(字體字符串形狀))的值看起來合理,並且與框的紋理不同。另外,您可能想要跟蹤create-image-from-file返回值的情況;確保圖像製作成沒有錯誤的紋理等。 – Tim 2010-06-03 20:54:47