2017-04-19 56 views
2

背景

我正在python/pyglet中創建一個程序生成的地形。 我用pyglet通過爲屏幕上的每個x和y座標運行一個lambda函數,然後以我想要的顏色繪製該像素來對其進行可視化。程序GL紋理

這不是非常優化的。

我有一個偷偷摸摸的懷疑,有一種方法來創建一個矩形對象,並告訴GL引擎渲染一個紋理,給GL引擎一個lambda函數,將返回顏色換取x和y座標。

僞pyglet例如

def get_color(pos): 
    x, y = pos 
    color = x * y % 255 
    return [color, color, color] 


width = 1680 
height = 1024 

win = window.Window(fullscreen=False, vsync=True, width=width, height=height) 

glMatrixMode(GL_PROJECTION) 
glLoadIdentity() 
gluOrtho2D(0, win.width, 0, win.height) 
glTextureMapper(get_color) 
win.clear() 

points = [0, 0, width, 0, width, height, 0, height] 
pyglet.graphics.draw(int(len(points)/2), GL_QUADS, ('v2f', points)) 

TLDR問題

如何使用lambda函數顏色的多邊形?這是着色器嗎?

Pyglet例子是首選,但在任何語言例子,歡迎

+0

OpenGL不使用多邊形,只使用三角形(以及直線和點)。像素的顏色在定義圖元(三角形,直線或點)的頂點之間進行插值。如果你想爲每個像素使用一個函數,那麼最好使用着色器。如果您已經爲每個像素計算了顏色,則紋理可能很有用。我最好的建議是遵循一些教程或一本關於現代OpenGL(ver> = 3.x)的書 – Ripi2

回答

1

這可能不是一個完整的答案,但可能會進一步給你一點。
另外請記住,我從來沒有用足夠奇怪的方式處理過很多紋理。

您可以做的是爲任何一組四邊形創建一個貼圖組,並將它們添加到批處理中。因爲我不完全確定你爲什麼需要lambda函數?

class TextureGroup(pyglet.graphics.Group): 
    def set_state(self): 
     glEnable(texture.target) 
     glBindTexture(texture.target, texture.id) 

    def unset_state(self): 
     glDisable(texture.target) 

vertice_mem = {} 

batch = pyglet.graphics.Batch() 
texture_group = TextureGroup() 
vertice_list = batch.add(2, pyglet.gl.GL_QUADS, None, ('v2f', points)) 
vertice_mem[(x,y)] = vertex_list 

這是優化紋理如何添加到特定的面孔,並添加這些面成批處理渲染他們快了很多,更有活力的一種方式。

如果您需要更新頂點,可以隨時訪問vertice_list.vertices並更改x,y對該特定面。

您可以使用自定義組在「實時」創建某些紋理,或者在此案例中預先渲染某些紋理,您可以將它們縫合在一起以創建「程序性」紋理。

What @ Ripi2說的也是一個很好的提示,請閱讀程序內存映射的工作原理和實際內容。您在沙盒遊戲中看到的大多數圖形都是巧妙地重複使用紋理來創建按需圖形的幻覺。

最後一個也是最後一個提示是,您很可能需要查看着色器,它們是迄今爲止通過操縱和創建紋理動盪來自動生成「紋理」的最快方法,否則將嚴重影響您的系統,因爲您需要以某種方式遍歷像素區域。

但是,這不是我的經驗領域 - 只有同行者多年來收集的信息。

+0

感謝您的回答,即使它沒有太多回答我的問題,它在這個主題上有一些優點。 – firelynx

1

正如嚴格指出的那樣,OpenGL無法繪製矩形(四邊形),但您始終可以使用兩個角之間的對角線來製作兩個三角形。 (角落之間的插值可能會有一些差異,但它們可能不會影響到你。)

雖然我很迂腐,你不着色像素,你在你的三維地形對象表面着色點。 (我假設你希望地形從任何角度或距離觀看時保持相同的顏色。)

好的,我希望將是真正的答案。你的程序性地形生成着色是否一次完成,還是動態改變?

如果您只創建並着色一次地形,請使用紋理貼圖。您需要了解如何在地形的角落分配紋理座標(TL; DR:它們將是(0.0,0.0),(1.0,0.0),(1.0,1.0),(0.0,1.0))以及如何使用glTexImage2D將圖像傳輸到GPU。

紋理貼圖只是2D柵格圖像。 Pyglet應該能夠爲您處理這個問題,如果不是Pillow或Python Imaging Library軟件包。

如果您希望地形隨時更改顏色,則需要使用片段着色器,這是一種用OpenGL着色語言編寫的小函數,每次繪製地形時都會執行。由於OpenGL的工作方式,您還必須編寫一個處理3D座標轉換的頂點着色器。

這意味着更多的思考和編碼,即紋理貼圖方法。但是現在OpenGL(或DirectX或RenderMan,...)中的所有內容都是用着色器完成的,所以你不妨開始學習。着色器可讓您執行任何類型的程序建模和動畫,而不僅僅是顏色。例如,您可以動態生成地形高度以及顏色。

希望這會有所幫助。