当前位置: 首页 > 知识库问答 >
问题:

绑定到单个VBO并使用着色器(LWJGL)渲染的多个纹理

呼延鹏云
2023-03-14

目前,我有一个OBJ加载程序,可以加载必要的OBJ,解析材质,并在必要时绑定纹理。

但是,我需要澄清,当顶点指针在刚刚绑定的VBO中移动时,是否可以绑定多个纹理。我的意思是:我想在一个VBO中跨不同网格放置多个材质。研究告诉我需要使用着色器,但没有指定如何在VBO中间加载它们。

我试图尽量减少绘制调用和VBOs的数量,同时(希望)尽可能远离多纹理。任何帮助都非常感谢!

当前绘图代码

private void Run() {
    GetInput inputController = new GetInput();
    while (!Display.isCloseRequested() && !Keyboard.isKeyDown(Keyboard.KEY_ESCAPE)) {
        CalculateFPS();
        GL11.glClear(GL11.GL_COLOR_BUFFER_BIT | GL11.GL_DEPTH_BUFFER_BIT);
        //Get Input
        GL11.glLoadIdentity();
        inputController.GetMouse();
        inputController.GetKeyboard();
        //Rotate
        GL11.glRotated(inputController.mousey, 1, 0, 0);
        GL11.glRotated(inputController.mousex, 0, 1, 0);
        //Move
        GL11.glTranslated(inputController.position.x, inputController.position.y, inputController.position.z);
        //Draw
        GL11.glEnableClientState(GL11.GL_VERTEX_ARRAY); //Allow vertex arrays
        GL11.glEnableClientState(GL11.GL_NORMAL_ARRAY); //Allow normal arrays
        GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, VBO_OBJ.vertexVBO); //Bind vertexVBO for drawing
        GL11.glVertexPointer(3, GL11.GL_FLOAT, 0, 0L);  //Setup vertexPointer for drawing
        GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, VBO_OBJ.normalVBO); //Bind normalVBO for drawing
        GL11.glNormalPointer(GL11.GL_FLOAT, 0, 0L); //Setup normalPointer for drawing
        GL11.glDrawArrays(GL11.GL_TRIANGLES, 0, VBO_OBJ.totalVertices); //Draw!
        GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, 0); //Unbind
        GL11.glDisableClientState(GL11.GL_VERTEX_ARRAY);
        GL11.glDisableClientState(GL11.GL_NORMAL_ARRAY);
        //Update Display
        Display.update();
        Display.sync(1000);
    }
    System.exit(0);
}

共有1个答案

马飞
2023-03-14

您需要绘制顶点缓冲区的部分(请参见glDrawArrays的第二个和第三个参数),在每个部分之后,您可以执行状态切换(例如调整绑定纹理、调整着色器),或者您必须对着色器进行编程,以便它可以在不使用“状态切换”的情况下进行渲染。这种可能性的范围完全取决于状态开关的类型和“可编程管道”的当前可能性。

例如,如果您当前拥有的唯一状态开关是纹理。您可以将纹理放在纹理数组(或采样器数组)中;在对象几何中,您需要添加一个属性来确定用于采样的纹理层。因为属性必须存储在顶点缓冲区中,所以它也成为一个复杂的问题,即它消耗了多少空间来使它与净性能增益相匹配。

Original:
sampler2d texture;
varying vec2 uv;
void main()
{
    vec4 color = texture2D(texture, uv);
}

Array of samplers:
sampler2d texture[32];
varying vec2 uv;
varying float layer;

void main()
{
    vec4 color = texture2D(texture[layer], uv);
}

Texture Array version:
sampler2dArray texture;
varying vec2 uv;
varying float layer;

void main()
{
    vec4 color = texture3D(texture, vec3(uv, layer));
}

请注意,上面的代码只是粗略的伪代码。

 类似资料:
  • 在过去的一个小时左右,我一直在尝试修复一个错误,使我尝试渲染的纹理只是单一颜色。奇怪的是,这种加载纹理的方法以前对我来说非常有效,没有这样的问题。这是我如何加载纹理(来自BufferedImage): 这就是纹理如何绘制到屏幕上: 上面的代码在显示列表中。任何想法可能导致四边形呈现为单一颜色?

  • 我想在FBO中加载两个纹理,其中一个纹理包含HDR图像,我的第一个目标是将图像从第一个纹理“复制”到第二个纹理(该纹理为空),并称为“下采样纹理”。 所以我创建FBO,加载我想用颜色_附件_0书写的纹理,并绑定它;然后初始化我的着色器程序并渲染一个四边形,其中包含我要在GL\u texture\u 0中读取的纹理。 然后我解开FBO并绑定“DownSamplingTex”,然后画一个四元组。 我不

  • 我有一个非常简单的OpenGL应用程序,只渲染一个带纹理的四边形。这是我的代码,效果很好(带纹理的四边形看起来很好): 然后我想介绍一个简单的着色器。所以我稍微修改了我的代码: 顶点着色器: 片段着色器: 现在我得到的只是一个黑色的四边形:-( 我已经尝试并测试了很多东西: 着色器编译良好(无错误) 有人知道为什么我在使用着色器时看不到我的纹理吗?

  • 我是OpenGL的新手,在整理如何将纹理和着色器绑定到VBOs时遇到了困难。 我正在使用Cinder的纹理和着色器类。以下是我绘制方法的一部分: 在上面的代码中,如果我注释掉对mShader的调用。bind(),我的球体VBO将显示纹理(myImage)。我的着色器适用于普通(无纹理)形状,但当我在绘制任何带有包裹纹理的形状之前绑定着色器时,它会阻止纹理显示。 这是我使用的着色器的问题,还是我不理

  • 我试图弄清楚为什么我不能用LWJGL 3渲染任何纹理。我尝试了多种加载(PNGDecoder、STB、BufferedImage)和渲染纹理的方法。但结果总是一个白色的四边形。 主要类: 加载方法: 渲染方法: ModelTexture类只是存储一些现在不使用的信息,blue.png是16x16的png文件。 这是我在启动程序时得到的输出:

  • 他们没有提到的是如何首先将两个纹理传递给着色器。 以前我 所以现在我 如何将大小不同的纹理数组传递给GLSL? 将多个纹理从OpenGL传递到GLSL着色器 GLSL中的多个纹理-只有一个有效 (这是家庭作业,所以请用最少的代码片段回答(如果有的话)。谢谢!) 如果做不到这一点,有人有茶具吗?