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

OpenGL中keydown事件失效问题排查及代码修复求助

OpenGL片段着色器按键事件失效问题排查与修复

核心错误分析

你的代码无法触发CTRL键逻辑的主要问题是**texelFetch参数使用错误**:

  • texture2D是GLSL中用于纹理采样的函数,不是纹理对象(sampler2D),但texelFetch要求第一个参数是采样器类型(sampler2D),而非采样函数。你混淆了纹理采样器和采样函数的概念。

其他潜在问题

  1. mix函数无实际效果:你传入的cul和col是完全相同的纹理采样结果,即便触发按键逻辑,视觉上也不会有任何变化。
  2. blend值超出范围:mix函数的第三个参数要求在0.0~1.0之间,但你的计算可能得到超出这个范围的值,会导致不可预期的结果。
  3. 按键状态传递缺失:片段着色器本身无法直接读取键盘输入,需要CPU端将按键状态写入一个纹理,再传递给着色器的uniform采样器。

修复后的完整代码

// 必须定义CPU端传入的按键状态纹理采样器
uniform sampler2D keyboardTexture;
uniform sampler2D media;
uniform vec2 resolution;
uniform float time;

const int k = 17; // CTRL键对应的键码

// 检查按键是否按下的函数
bool keypress(int key) {
    // 使用正确的采样器,用>0.5判断避免浮点精度误差
    return texelFetch(keyboardTexture, ivec2(key, 2), 0).x > 0.5;
}

void main()
{ 
    vec2 p = gl_FragCoord.xy;
    vec2 uv = p / resolution.xy;
    
    // 限制blend值在0.0~1.0范围内
    float blend = clamp(1.9 - pow(1.5 * cos(time/8.0), 5.0), 0.0, 1.0);
    
    vec3 originalCol = texture2D(media, uv).rgb;
    // 定义一个不同的目标颜色,方便观察按键效果
    vec3 targetCol = vec3(0.0, 1.0, 0.0);
    vec3 col = originalCol;
     
    if (keypress(k)) {
        col = mix(originalCol, targetCol, blend); 
    }
    gl_FragColor = vec4(col, 1.0);
}

CPU端关键补充步骤

要让按键状态在着色器中生效,你需要在CPU端完成以下操作:

  • 创建一个256x3的纹理(覆盖常见键码范围,y轴可存储不同按键状态),初始化所有像素值为0.0。
  • 监听键盘事件:当CTRL键按下时,将纹理中坐标(17, 2)的像素值设为1.0;松开时设为0.0。
  • 将该纹理绑定到着色器的keyboardTexture uniform采样器上,每一帧更新纹理数据。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.16 12:45:47