2017-04-19 59 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,...)中的所有内容都是用着色器完成的,所以你不妨开始学习。着色器可让您执行任何类型的程序建模和动画,而不仅仅是颜色。例如,您可以动态生成地形高度以及颜色。

希望这会有所帮助。