You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

JOGL中向片段着色器传递整数值异常问题

OpenGL整数顶点属性传递始终为0的问题排查与解决

问题描述

在OpenGL应用中,尝试通过VBO将整数传递至顶点着色器,再转发给片段着色器用作纹理数组的zIndex,但该整数值始终为0。顶点、法线、纹理坐标通过VBO传递均正常,改用浮点数传递也出现相同问题。

相关代码

顶点着色器

#version 410

layout (location = 0) in vec3 aPos;
layout (location = 1) in vec3 aNorm;
layout (location = 2) in vec2 aTexCoords;
layout (location = 3) in uint aDepth;

out vec2 TexCoords;
out vec3 Normal;
out vec3 FragPos;
out uint vDepth;

uniform mat4 model;
uniform mat4 view;
uniform mat4 projection;

void main()
{
     vDepth = aDepth;
     TexCoords = aTexCoords;
     gl_Position = projection * view * model * vec4(aPos, 1.0);
}

片段着色器

#version 410

in vec2 TexCoords;
flat in uint vDepth;

uniform sampler2DArray textureArray;

out vec4 FragColor;


void main()
{
    if(vDepth == 0) {
        FragColor = vec4(1.0, 0.0, 0.0, 1.0);
    } else {
        FragColor = vec4(0.0, 1.0, 0.0, 1.0);
    }

//    FragColor = texture(textureArray, vec3(TexCoords, vDepth));
}

VAO/VBO创建代码

public Block(GL4 gl, int shaderProgram, float[] vertices, float[] normals, float[] textureCoordinates, int blockType) {

        gl.glUseProgram(shaderProgram);

        // setup object
        gl.glGenVertexArrays(1, vao, 0);
        gl.glGenBuffers(vbo.length, vbo, 0);

        // bind to vao
        gl.glBindVertexArray(vao[0]);

        gl.glBindBuffer(GL_ARRAY_BUFFER, vbo[0]);
        gl.glBufferData(GL_ARRAY_BUFFER, (long) vertices.length * Float.BYTES, Buffers.newDirectFloatBuffer(vertices), GL_STATIC_DRAW);

        gl.glBindBuffer(GL_ARRAY_BUFFER, vbo[1]);
        gl.glBufferData(GL_ARRAY_BUFFER, (long) normals.length * Float.BYTES, Buffers.newDirectFloatBuffer(normals), GL_STATIC_DRAW);

        gl.glBindBuffer(GL_ARRAY_BUFFER, vbo[2]);
        gl.glBufferData(GL_ARRAY_BUFFER, (long) textureCoordinates.length * Float.BYTES, Buffers.newDirectFloatBuffer(textureCoordinates), GL_STATIC_DRAW);

        // ISSUE IS HERE //
        gl.glBindBuffer(GL_ARRAY_BUFFER, vbo[3]);
        IntBuffer blockBuffer = Buffers.newDirectIntBuffer(blockType);
        gl.glBufferData(GL_ARRAY_BUFFER, Integer.BYTES, blockBuffer, GL_STATIC_DRAW);

        // bind to indices
        gl.glBindBuffer(GL_ARRAY_BUFFER, vbo[0]);
        gl.glVertexAttribPointer(0, 3, GL_FLOAT, false, 3 * Float.BYTES, 0);
        gl.glEnableVertexAttribArray(0);

        gl.glBindBuffer(GL_ARRAY_BUFFER, vbo[1]);
        gl.glVertexAttribPointer(1, 3, GL_FLOAT, false, 3 * Float.BYTES, 0);
        gl.glEnableVertexAttribArray(1);

        gl.glBindBuffer(GL_ARRAY_BUFFER, vbo[2]);
        gl.glVertexAttribPointer(2, 2, GL_FLOAT, false, 2 * Float.BYTES, 0);
        gl.glEnableVertexAttribArray(2);


        // ISSUE IS HERE //
        gl.glBindBuffer(GL_ARRAY_BUFFER, vbo[3]);
        gl.glVertexAttribIPointer(3, 1, GL_UNSIGNED_INT, Integer.BYTES, 0);
        gl.glEnableVertexAttribArray(3);

        gl.glBindBuffer(GL_ARRAY_BUFFER, 0);
    }

问题根源

核心问题在于深度属性的VBO数据长度与顶点数量不匹配:

  • 位置、法线等属性的VBO存储了与顶点数量对应的多组数据,但深度属性仅传入了单个整数。当OpenGL绘制多个顶点时,只有第一个顶点能读取到传入的blockType值,后续顶点会读取VBO中超出初始化范围的内存(通常为0或未定义值)。
  • 改用浮点数传递时问题依旧,也验证了这一点——浮点数VBO同样只传入了单个值,无法覆盖所有顶点。

解决步骤

  1. 生成与顶点数量匹配的深度数据
    计算顶点总数,创建对应长度的整数数组,每个元素填充blockType值,再传入VBO:

    // 计算顶点数量:每个顶点占3个float分量
    int vertexCount = vertices.length / 3;
    int[] depthData = new int[vertexCount];
    // 所有顶点复用同一个blockType值
    Arrays.fill(depthData, blockType);
    
    gl.glBindBuffer(GL_ARRAY_BUFFER, vbo[3]);
    IntBuffer blockBuffer = Buffers.newDirectIntBuffer(depthData);
    // 传入完整的深度数据数组
    gl.glBufferData(GL_ARRAY_BUFFER, (long) depthData.length * Integer.BYTES, blockBuffer, GL_STATIC_DRAW);
    
  2. 验证顶点属性指针参数
    当前glVertexAttribIPointer的参数是正确的:

    • 第三个参数GL_UNSIGNED_INT与顶点着色器的uint类型匹配;
    • 第四个参数Integer.BYTES是单个深度属性的字节步长(无间隔,步长等于单个元素大小);
    • 偏移量为0,符合单独VBO的布局。
  3. 保持类型一致性(可选)
    如果blockType是有符号整数,可将顶点着色器的aDepth改为int,同时将glVertexAttribIPointer的第三个参数改为GL_INT,避免无符号/有符号转换的潜在问题。

  4. 确认绘制调用的顶点数量
    确保绘制时使用的顶点数量与depthData的长度一致,例如:

    gl.glBindVertexArray(vao[0]);
    gl.glDrawArrays(GL_TRIANGLES, 0, vertexCount);
    

内容的提问来源于stack exchange,提问作者user10039647

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.05 10:25:00