【问题标题】:OpenGL 2DTexture from c++ unsigned byte array来自 C++ 无符号字节数组的 OpenGL 2DTexture
【发布时间】:2021-03-19 18:40:47
【问题描述】:

我正在尝试在片段着色器中处理二维数组 - 为了了解这一点,我开始构建我的数组:

int const _s = 512;
std::array<GLubyte,_s*_s*4> hitmap;
for(unsigned j = 0; j < _s; j++) {
  for(unsigned i = 0; i < _s; i+=4) {
   hitmap[i+j*_s] = j%256;                  //R     
   if(j>33 && j < 45) hitmap[i+j*_s] = 0;   //R
   hitmap[i+j*_s+1] = i%256;                //G
   if(i>33 && i < 45) hitmap[i+j*_s+1] = 0; //G
   hitmap[i+j*_s+2] = 0;                    //B
   hitmap[i+j*_s+3] = 255;                  //A
  }
}

作为第一步,只需将其作为纹理推送并显示在表面上。

glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_MIRRORED_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_MIRRORED_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, _s, _s, 0, GL_RGBA, GL_UNSIGNED_BYTE, hitmap.data());

我正在用以下坐标绘制两个三角形来得到一个正方形:

    // positions           // texture coords
     1.f,  1.f, 0.0f,      1.0f, 1.0f, // top right
     1.f, -1.f, 0.0f,      1.0f, 0.0f, // bottom right
    -1.f, -1.f, 0.0f,      0.0f, 0.0f, // bottom left
    -1.f,  1.f, 0.0f,      0.0f, 1.0f  // top left 

而且我的片段着色器非常愚蠢:

#version 150 core
uniform sampler2D ourTexture;
out vec4 FragColor;
in vec2 TexCoord;
void main()
{
FragColor = texture(ourTexture, TexCoord);
};

(是的,我在这里使用的是相当旧的版本:/)

我得到的结果如下:

顶部有一些奇怪的东西,纹理似乎重复(尽管不是镜像)。我真的无法弄清楚我做错了什么 - 看起来我没有提供足够的数据。 我希望得到一个 2x2 的正方形图案,因为我通过 mod 分割将 512 px 映射到 256 的范围内。

编辑:像这样:

【问题讨论】:

    标签: c++ opengl glsl shader textures


    【解决方案1】:

    您误解了GL_MIRRORED_REPEAT 的概念。请参阅 OpenGL 维基 glTexParameter

    GL_MIRRORED_REPEAT 如果 s 的整数部分是偶数,则将 s 坐标设置为纹理坐标的小数部分;如果s的整数部分是奇数,则s纹理坐标设置为1−frac(s),其中frac (s) 表示s的小数部分。

    这意味着如果纹理坐标在 [1.0, 2.0], [3.0, 4.0], ... 范围内,则纹理被镜像;如果纹理坐标在 [0.0, 1.0], [2.0, 3.0], ... 范围内,则不会被镜像。
    由于所有纹理坐标都在 [0.0, 1.0] 范围内,因此根本没有镜像。

    在片段着色器中缩放纹理坐标看看GL_MIRRORED_REPEAT的概念:

    void main()
    {
        FragColor = texture(ourTexture, TexCoord * 2.0);
    };
    

    内部for-loop的条件语句也有错误。内部循环必须从0 运行到_s*4,而不是从0_s

    for(unsigned i = 0; i &lt; _s; i+=4) {

    for(unsigned i = 0; i < _s*4; i+=4) {
    

    以字节为单位的行大小是_s*4 而不是_s

    int const _s = 512;
    std::array<GLubyte,_s*_s*4> hitmap;
    for(unsigned j = 0; j < _s; j++) {
        for(unsigned i = 0; i < _s*4; i+=4) {
            hitmap[i + j*_s*4] = j%256;                    //R     
            if(j>33 && j < 45) hitmap[i + j*_s*4] = 0;     //R
            hitmap[i + j*_s*4 + 1] = i%256;                //G
            if(i>33 && i < 45) hitmap[i + j*_s*4 + 1] = 0; //G
            hitmap[i + j*_s*4 + 2] = 0;                    //B
            hitmap[i + j*_s*4 + 3] = 255;                  //A
        }
    }
    

    【讨论】:

    • 感谢您的澄清 - 但我仍然对我得到的结果感到困惑。我希望得到一个 2x2 的“方形”图案,完全延伸到表面上——根本没有任何重复。但我确实得到了一个重复的模式。
    • 如果我将 TexCoord*2.0 相乘,我会在两个方向上镜像纹理——这正是我所期望的。我不希望在我的初始示例中出现任何镜像 - 我不明白的一点是为什么我的纹理看起来像它看起来的样子。我正在构建一个 512x512 纹理 - 将其缩放为一个字节只是 %256 (+一条特征线)。我将它准确地投射到整个表面上。那么为什么我会有这么大的黑色区域呢? (将我期望的图片作为编辑放入帖子中)
    • @user3895986 以字节为单位的行大小是_s*4 而不是_s。查看答案。
    • 谢谢,是的,就是那个索引……我现在觉得很傻:)
    • @user3895986 我认为你不是第一个犯这种错误的人(我也是,肯定不止一次)。谢谢你。不客气。
    猜你喜欢
    • 1970-01-01
    • 2019-01-17
    • 2017-12-03
    • 2014-07-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-04-15
    相关资源
    最近更新 更多