目前,我可以加载我创建的静态大小的纹理。在这种情况下,它是512 x 512。
此代码来自标题:
#define TEXTURE_WIDTH 512
#define TEXTURE_HEIGHT 512
GLubyte textureArray[TEXTURE_HEIGHT][TEXTURE_WIDTH][4];
这是glTexImage2D的用法:
glTexImage2D(
GL_TEXTURE_2D, 0, GL_RGBA,
TEXTURE_WIDTH, TEXTURE_HEIGHT,
0, GL_RGBA, GL_UNSIGNED_BYTE, textureArray);
这就是我填充数组的方法(粗略的例子,不是我代码中的精确副本):
for (int i = 0; i < getTexturePixelCount(); i++)
{
textureArray[column][row][0] = (GLubyte)pixelValue1;
textureArray[column][row][1] = (GLubyte)pixelValue2;
textureArray[column][row][2] = (GLubyte)pixelValue3;
textureArray[column][row][3] = (GLubyte)pixelValue4;
}
如何更改它以便不需要TEXTURE_WIDTH和TEXTURE_HEIGHT?也许我可以使用指针样式数组并动态分配内存......
我想我看到了问题,在C ++中它无法真正完成。 Budric指出的工作是使用单维数组,但使用所有3个维度乘以表示索引:
GLbyte *array = new GLbyte[xMax * yMax * zMax];
要访问,例如1/2 / 3的x / y / z,您需要执行以下操作:
GLbyte byte = array[1 * 2 * 3];
然而,问题是,我不认为glTexImage2D
函数支持这一点。任何人都可以想到一个适用于这个OpenGL函数的解决方法吗?
注意OpenGL开发人员,这可以通过使用单维像素数组来克服......
[0]:第0列&gt; [1]:第0行&gt; [2]:通道0 ... n&gt; [n]:第1行...... n&gt; [n]:第1栏...... n
...不需要使用3维数组。在这种情况下,我不得不使用这个工作,因为在C ++中显然不能严格地使用三维数组。
答案 0 :(得分:5)
好的,因为我花了很多时间来弄清楚这一点,这里是:
我的任务是使用动态纹理数组实现OpenGL Red Book(9-1,p373,5th Ed。)中的示例。
该示例使用:
static GLubyte checkImage[checkImageHeight][checkImageWidth][4];
正如您所猜测的那样,尝试分配三维数组将无法完成任务。 Someth。像这样 NOT 工作:
GLubyte***checkImage;
checkImage = new GLubyte**[HEIGHT];
for (int i = 0; i < HEIGHT; ++i)
{
checkImage[i] = new GLubyte*[WIDTH];
for (int j = 0; j < WIDTH; ++j)
checkImage[i][j] = new GLubyte[DEPTH];
}
您必须使用 一维数组 :
unsigned int depth = 4;
GLubyte *checkImage = new GLubyte[height * width * depth];
您可以使用此循环访问元素:
for(unsigned int ix = 0; ix < height; ++ix)
{
for(unsigned int iy = 0; iy < width; ++iy)
{
int c = (((ix&0x8) == 0) ^ ((iy&0x8)) == 0) * 255;
checkImage[ix * width * depth + iy * depth + 0] = c; //red
checkImage[ix * width * depth + iy * depth + 1] = c; //green
checkImage[ix * width * depth + iy * depth + 2] = c; //blue
checkImage[ix * width * depth + iy * depth + 3] = 255; //alpha
}
}
不要忘记正确删除它:
delete [] checkImage;
希望这会有所帮助......
答案 1 :(得分:4)
您可以使用
int width = 1024;
int height = 1024;
GLubyte * texture = new GLubyte[4*width*height];
...
glTexImage2D(
GL_TEXTURE_2D, 0, GL_RGBA,
width, height,
0, GL_RGBA, GL_UNSIGNED_BYTE, textureArray);
delete [] texture; //remove the un-needed local copy of the texture;
但是你仍然需要在glTexImage2D调用中指定OpenGL的宽度和高度。此调用复制纹理数据,该数据由OpenGL管理。您可以删除,调整大小,更改原始纹理数组,并且它与您为OpenGL指定的纹理不同。
修改强> C / C ++只处理1维数组。您可以执行纹理[a] [b]的事实在编译时由编译器隐藏和转换。编译器必须知道列数,并且将执行纹理[a * cols + b]。
使用类来隐藏分配,访问纹理。
出于学术目的,如果您真的想要动态多维数组,则以下内容应该有效:
int rows = 16, cols = 16;
char * storage = new char[rows * cols];
char ** accessor2D = new char *[rows];
for (int i = 0; i < rows; i++)
{
accessor2D[i] = storage + i*cols;
}
accessor2D[5][5] = 2;
assert(storage[5*cols + 5] == accessor2D[5][5]);
delete [] accessor2D;
delete [] storage;
请注意,在所有情况下我都在使用一维数组。它们只是指针数组和指针指针数组。这有内存开销。这也适用于没有颜色分量的2D阵列。对于3D解除引用,这非常麻烦。不要在代码中使用它。
答案 2 :(得分:1)
你总是可以在课堂上把它包起来。如果要从文件加载图像,则使用其余数据获得高度和宽度(如何使用该文件?),您可以将它们存储在包装文件加载的类中,而不是使用预处理器定义。类似的东西:
class ImageLoader
{
...
ImageLoader(const char* filename, ...);
...
int GetHeight();
int GetWidth();
void* GetDataPointer();
...
};
更好的是你可以用它隐藏对glTexImage2d的函数调用。
class GLImageLoader
{
...
ImageLoader(const char* filename, ...);
...
GLuint LoadToTexture2D(); // returns texture id
...
};