对 VBO 中的特定三角形使用不同的纹理

Posted

技术标签:

【中文标题】对 VBO 中的特定三角形使用不同的纹理【英文标题】:Use different texture for specific triangles in VBO 【发布时间】:2013-03-02 11:13:34 【问题描述】:

我有 9 个由三角形组成的四边形,如下所示:

我正在使用VBO 来存储关于它们的数据——它们的位置和纹理坐标。

我的问题是 - 是否可以通过仅使用一个 VBOshader 使四边形 5 具有与其他四边形不同的纹理? :

绿色代表纹理1,黄色代表纹理2。

到目前为止,我得到了:

GLfloat vertices[] =  
    // Positions
    0.0f, 0.0f,
    ...

    // Texture coordinates
    0.0f, 0.0f, 
    ...
;

我正在使用 vertices[] 数组创建 VBO,然后绑定我的第一个纹理 m_texture1(我还可以访问第二个纹理 - m_texture2)并调用着色器:

glBindTexture(GL_TEXTURE_2D, m_texture1);

glUseProgram(program);

glBindBufferARB(GL_ARRAY_BUFFER_ARB, m_vboId);          // for vertex coordinates
glEnableVertexAttribArray(0);
glEnableVertexAttribArray(1);
glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 0, 0);                                      // Vertices
glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 0, (void*)(sizeof(GLfloat)*108));           // Texture
glDrawArrays(GL_TRIANGLES, 0, 108);
glDisableVertexAttribArray(0);
glDisableVertexAttribArray(1);

glUseProgram(0);

我的顶点着色器:

#version 330

layout (location = 0) in vec4 position;
layout (location = 1) in vec2 texcoord;

out vec2 Texcoord;

void main()

    gl_Position = position;
    Texcoord = texcoord;

和片段着色器:

#version 330

in vec2 Texcoord;

out vec4 outputColor;

uniform sampler2D tex;

void main()

    outputColor = texture(tex, Texcoord) * vec4(1.0,1.0,1.0,1.0);

所以基本上我在这里只使用一种纹理,因为我不知道如何使用第二种纹理。

【问题讨论】:

【参考方案1】:

您可以使用不同的texture image units 并将它们的值设置为uniform sampler2D tex 来执行此操作。

您必须调用glActiveTexture 并设置纹理图像单元 (GL_TEXTURE0),绑定绿色纹理,然后将活动纹理设置为 GL_TEXTURE1 并绑定黄色纹理。这样,您的绿色纹理将具有纹理图像单元 id 0 和黄色 1。

您必须将绘图调用分成两个:一个用于绿色四边形,另一个用于黄色。 您必须通过在每次调用中使用glUniform1i 设置uniform sampler2D tex 来设置要使用的纹理。 最后调用 glDrawArrays 获取 VBO 中的三角形子集,指示您在当前调用中绘制的绿色或黄色三角形。

如果您只需要在示例中绘​​制一张图片,您也可以考虑使用texture atlas。在这种情况下,您将在一次调用中映射一个纹理。

【讨论】:

感谢您的回答。老实说,我把它放在一个纹理中,但是因为我需要不同的外部和内部纹理样式(GL_REPEAT 和 GL_CLAMP)我把它分成了两个,但也许有可能只为内部四边形改变这些参数?跨度> @Mosquito,在这种情况下不使用两个纹理。 当使用多个绘制调用时,显而易见的事情就是切换纹理绑定。但是对于多纹理(所有纹理绑定在多个单元中),您还可以引入一个额外的整数顶点属性,标识要使用的纹理,这允许使用单个绘图调用来完成此操作。 @datenwolf 你知道网上有什么文章可以帮助我理解你刚刚写的吗?我知道如何使用多个纹理(glActiveTexture),例如将它们混合在一起,但我不知道如何使用单个绘制调用“定位”特定区域(我的四边形在中心)中的第二个纹理。 @Mosquito,您只需添加一个额外的顶点属性(除了位置和纹理坐标之外)并使用它来代替 uniform tex。

以上是关于对 VBO 中的特定三角形使用不同的纹理的主要内容,如果未能解决你的问题,请参考以下文章

LWJGL VBO 三角形纹理坐标不起作用

VBO中的自定义三角形,如何渲染

为啥绘制我的 OpenGL-ES VBO 网格会阻止其他三角形显示?

VAO/VBO 管理 - 更改所有 VBO 数据

OpenGL VBO 不显示

每个 VBO 都需要一个 VAO 吗?