我想创建一个适用于Torus的纹理,如下所示:
这是我刚刚开始编写的代码:
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 ... 你能帮帮忙吗? 这是我得到的代码:
答案 0 :(得分:2)
由于纹理通常是2的2次幂的正方形大小,你可以将它们分成两端的n个子方块,其中n也是2的幂。这样可以保证纹理的平滑包裹。
任何其他数字都可能导致问题,因为数字不能被它整除(2 n 的因子分解只有2s),并且它将以一部分结束一个正方形,或者你在纹理中放置的正方形不会有完全相同的尺寸。
让我们首先采用一维纹理。循环中的索引将从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
}
}
当我们添加另一个维度时,它只会稍微复杂一些。我们仍然可以假设大小将是数字,因为我们只处理方形。循环需要在另一个维度上循环:
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
}
}
}