程序GL纹理

时间:2017-04-19 14:38:08

标签: python opengl textures shader pyglet

背景

我在python / pyglet中工作以创建程序生成的地形。 我通过对屏幕上的每个x和y坐标运行lambda函数,然后用我想要的颜色绘制该像素,用pyglet可视化它。

这不是最佳选择。

我有一种潜在的怀疑,即有一种方法可以创建一个矩形对象并告诉GL引擎在其上渲染纹理,为GL引擎提供一个lambda函数,该函数将返回颜色以换取x和y坐标

伪pyglet示例

<Window x:Class="WpfApplication1.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        mc:Ignorable="d"
        Title="MainWindow"
        SizeToContent="WidthAndHeight"
        ResizeMode="NoResize">
    <Grid>
        <ContentPresenter x:Name="cc" Focusable="true" Margin="0">
            <ContentPresenter.Content>
                <TextBlock>test</TextBlock>
            </ContentPresenter.Content>
        </ContentPresenter>
    </Grid>
</Window>

TLDR问题

如何使用lambda函数为多边形着色?这是一个着色器吗?

首选Pyglet示例,但欢迎使用任何语言的示例

2 个答案:

答案 0 :(得分: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对。

您可以使用自定义组“动态”创建某些纹理,或者在这种情况下预渲染某些纹理,您可以将它们拼接在一起以创建“程序”纹理。

@ Ripi2所说的内容也是一个很好的提示,请阅读程序性内存映射的工作原理及实际内容。您在沙盒游戏中看到的大多数图形都是实际巧妙地重复使用纹理来创建按需图形的幻觉。

最后和最后一个提示是你很可能需要查看着色器,它们是迄今为止通过在纹理中操纵和创建湍流来自动生成“纹理”的最快方法,否则将对您的系统造成沉重负担因为你需要以某种方式迭代像素区域。

但同样,这不是我的经验领域 - 多年来只收集了旅行者的一些信息。

答案 1 :(得分:1)

严格地说,OpenGL不能绘制矩形(四边形),但是你总是可以使用两个角之间的对角线来制作两个三角形。 (角落之间的插值可能会有一些差异,但它们可能不会对您产生影响。)

虽然我是迂腐的,但你并没有着色像素,你在3D地形物体表面上着色点。 (我假设您希望从任何角度或距离观看时地形都保持相同的颜色。)

好的,我希望这将是真正的答案。您的程序性地形生成着色是一次完成,还是动态变化?

如果您只创建一次地形并为地形着色,请使用纹理贴图。您需要学习如何在地形的角落分配纹理坐标(TL; DR:它们将是(0.0,0.0),(1.0,0.0),(1.0,1.0),(0.0) ,1.0))以及如何使用glTexImage2D将图像传输到GPU。

纹理贴图只是2D光栅图像。如果不是Pillow或Python Imaging Library软件包,Pyglet应该能够为你处理这个问题。

如果你想让地形动态改变颜色,你需要一个片段着色器,一个用OpenGL着色语言编写的小函数,每次绘制地形时都会执行。由于OpenGL的工作方式,您还必须编写一个处理3D坐标转换的顶点着色器。

这将意味着纹理贴图更多的思考和编码方法。但是现在OpenGL(或DirectX,或者RenderMan,......)中的所有东西都是用着色器完成的,所以你不妨开始学习。着色器允许您进行任何类型的程序建模和动画,而不仅仅是颜色。例如,您可以动态生成地形高度和颜色。

希望这有帮助。