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

OpenGL中如何通过glUniform向二维数组类型Uniform传值?

How to Set a 2D Sampler Array Uniform from C++ in OpenGL

Got it, let's work through this problem—since glUniform1iv doesn't handle 2D sampler arrays directly, we need to treat the GLSL 2D array as a collection of 1D sampler arrays and set each one individually. Here's a step-by-step breakdown:

1. Understand the Uniform Layout

In GLSL, a 2D array like uniform sampler2D depthMap[NUM_CASCADES][MAX_NUM_LIGHTS]; is treated by OpenGL as an array of 1D sampler arrays. Each depthMap[cascadeIndex] is its own independent 1D sampler array uniform, so we need to grab the location for each of these sub-arrays first.

2. Fetch Uniform Locations for Each Sub-Array

Loop through each cascade level and get the location of the corresponding 1D sampler array using glGetUniformLocation:

GLint depthMapSubArrayLocations[NUM_CASCADES];
for (int cascade = 0; cascade < NUM_CASCADES; ++cascade) {
    // Build the uniform name string (e.g., "depthMap[0]", "depthMap[1]")
    char uniformName[64];
    snprintf(uniformName, sizeof(uniformName), "depthMap[%d]", cascade);
    depthMapSubArrayLocations[cascade] = glGetUniformLocation(yourProgramID, uniformName);
}

3. Bind Textures and Set Each Sub-Array

This part is similar to setting a 1D sampler array, but we'll nest the loops to cover both cascades and lights. Make sure to assign unique texture units to avoid conflicts:

// Start texture units from a safe base (e.g., GL_TEXTURE2) to avoid overwriting existing bindings
const int baseTextureUnit = 2;

for (int cascade = 0; cascade < NUM_CASCADES; ++cascade) {
    GLint textureUnits[MAX_NUM_LIGHTS];
    
    for (int light = 0; light < MAX_NUM_LIGHTS; ++light) {
        // Calculate the unique texture unit for this (cascade, light) pair
        int currentTexUnit = baseTextureUnit + (cascade * MAX_NUM_LIGHTS) + light;
        textureUnits[light] = currentTexUnit;
        
        // Bind the corresponding texture to the calculated unit
        glActiveTexture(GL_TEXTURE0 + currentTexUnit);
        glBindTexture(GL_TEXTURE_2D, yourDepthMapIDs[cascade][light]);
    }
    
    // Set the texture units for the current cascade's 1D sampler array
    glUniform1iv(depthMapSubArrayLocations[cascade], MAX_NUM_LIGHTS, textureUnits);
}

Key Notes

  • Texture Unit Management: Always plan your texture unit assignments to avoid overlapping with other textures bound in your application. Using a base offset like GL_TEXTURE2 ensures you don't overwrite units used for other samplers.
  • Validation: If you run into issues, use glGetProgramiv with GL_ACTIVE_UNIFORMS and glGetActiveUniform to inspect the uniform layout of your shader program—this can confirm that each sub-array is being recognized correctly.
  • Shader Compatibility: Double-check that your GLSL version (450 in your case) supports nested sampler arrays—this should be fine, but it's good to confirm if you're working with older contexts.

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.27 09:36:32