OpenGL / Glut:如何创建一个checkboard纹理

时间:2015-10-12 15:32:25

标签: opengl textures glut

我想创建一个适用于Torus的纹理,如下所示:

enter image description here

这是我刚刚开始编写的代码:

void initMyProceduralTexture() {
  GLubyte image[64][64][3];
  int i,  j, c, r, g, b;

  glGenTextures( 1, &textureName[NUM_TEXTURES - 1] );
  glBindTexture(GL_TEXTURE_2D, textureName[NUM_TEXTURES - 1]);

  for(i=0;i<64;i++) {
    for(j=0;j<64;j++) {
        float a = floor(i * 8.0);
        float b = floor(j * 8.0);
        if (fmod(a,b) > 0.5 ) {
            image[i][j][0]= (GLubyte) 255.0;
            image[i][j][1]= (GLubyte) 127.5;
            image[i][j][2]= (GLubyte) 127.5;
        }
        else {
            image[i][j][0]= (GLubyte) 153.0;
            image[i][j][1]= (GLubyte) 153.0;
            image[i][j][2]= (GLubyte) 255.0;
        }
    }

  }

glTexImage2D(GL_TEXTURE_2D,0,3,64,64,0,GL_RGB,GL_UNSIGNED_BYTE, image);
...

但我不知道如何区分蓝色部分和红色部分以及如何设置图像矩阵。我查看了this网站,这就是为什么我将该比例设置为8.0 ... 你能帮帮忙吗? 这是我得到的代码: enter image description here

1 个答案:

答案 0 :(得分:2)

由于纹理通常是2的2次幂的正方形大小,你可以将它们分成两端的n个子方块,其中n也是2的幂。这样可以保证纹理的平滑包裹。

任何其他数字都可能导致问题,因为数字不能被它整除(2 n 的因子分解只有2s),并且它将以一部分结束一个正方形,或者你在纹理中放置的正方形不会有完全相同的尺寸。

1D示例

让我们首先采用一维纹理。循环中的索引将从1变化到例如64.我们只需要将该数字除以所需的段数,以获得我们想要的一个段中的像素数:

int texSize = 64;
const int desiredSegmentCount = 8;
int segmentSize = texSize / desiredSegmentCount; // 8

现在,在迭代时,我们可以通过将索引除以段大小来获取段数:

for (int i = 0; i < texSize; ++i) {
    const int segmentNum = i / segmentSize;
}

一旦我们有了段号,就可以轻松评估它是否奇怪,甚至可以通过segmentNum % 2进行评估(为了清晰起见,可选择添加== 0)。

因此,完整循环看起来像:

for (int i = 0; i < texSize; ++i) {
    const int segmentNum = i / segmentSize;
    const bool isEven = (segmentNum % 2) == 0;

    if (isEven) {
        // output red pixel
    } else {
       // output blue pixel
    }
}

扩展到2D

当我们添加另一个维度时,它只会稍微复杂一些。我们仍然可以假设大小将是数字,因为我们只处理方形。循环需要在另一个维度上循环:

for (int i = 0; i < texSize; ++i) {
    for (int j = 0; j < texSize; ++j) {
        const int segmentNum = i / segmentSize;
        const bool isEven = (segmentNum % 2) == 0;

        if (isEven) {
            // output red pixel
        } else {
           // output blue pixel
        }
    }
}

这应该会产生条纹纹理。现在我们需要在行和列上添加实际的依赖项。

&#34;条件&#34;如果&#34;成为真相表:

     | odd  | even        j
-----|------------------
odd  | blue | red
even | red  | blue

i

你应该立即认识到这是一个XOR操作,对于布尔实际上它与(!=)运算符相同。现在,下面的代码应该非常清楚:

for (int i = 0; i < texSize; ++i) {
    for (int j = 0; j < texSize; ++j) {
        const int segmentNumI = i / segmentSize;
        const int segmentNumJ = j / segmentSize;

        const bool isEvenI = (segmentNumI % 2) == 0;
        const bool isEvenJ = (segmentNumJ % 2) == 0;

        const bool redPixel = isEvenI != isEvenJ;

        if (redPixel) {
            // output red pixel
        } else {
           // output blue pixel
        }
    }
}