我在github上关注apitest,并且在我的渲染器中看到了一些非常奇怪的行为。
虚拟页面似乎没有收到正确的图像数据。
原始图片为500x311:
当我使用稀疏纹理渲染此图像时,我必须将后备存储大小调整为512x384(为页面大小的多个),结果是:
如您所见,它看起来像是子图像的一部分(子子图像)被加载到每个单独的虚拟页面。
为了测试这一点,我将图像裁剪为仅1个虚拟页面(256x128)的大小:结果如下:
正如预期的那样,单个虚拟页面中填充了精确,正确的裁剪图像。
最后,我将裁剪尺寸增加到2个虚拟页面,256x256,一个在另一个之上。结果如下:
这证明使用大于Virtual_Page_Size的texelData数量调用texSubimage会导致错误。
将数据传递给大于虚拟页面大小的glsubimage时是否需要小心?我认为没有任何逻辑,所以认为这可能是一个驱动问题。或者我错过了一些重要的东西。
以下是一些代码:
我将纹理存储在纹理数组中,并简化了将数组转换为纹理2d。两者都产生相同的确切结果。这是纹理内存分配:
_check_gl_error();
glGenTextures(1, &mTexId);
glBindTexture(GL_TEXTURE_2D, mTexId);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SPARSE_ARB, GL_TRUE);
// TODO: This could be done once per internal format. For now, just do it every time.
GLint indexCount = 0,
xSize = 0,
ySize = 0,
zSize = 0;
GLint bestIndex = -1,
bestXSize = 0,
bestYSize = 0;
glGetInternalformativ(GL_TEXTURE_2D, internalformat, GL_NUM_VIRTUAL_PAGE_SIZES_ARB, 1, &indexCount);
if(indexCount == 0) {
fprintf(stdout, "No Virtual Page Sizes for given format");
fflush(stdout);
}
_check_gl_error();
for (GLint i = 0; i < indexCount; ++i) {
glTexParameteri(GL_TEXTURE_2D, GL_VIRTUAL_PAGE_SIZE_INDEX_ARB, i);
glGetInternalformativ(GL_TEXTURE_2D, internalformat, GL_VIRTUAL_PAGE_SIZE_X_ARB, 1, &xSize);
glGetInternalformativ(GL_TEXTURE_2D, internalformat, GL_VIRTUAL_PAGE_SIZE_Y_ARB, 1, &ySize);
glGetInternalformativ(GL_TEXTURE_2D, internalformat, GL_VIRTUAL_PAGE_SIZE_Z_ARB, 1, &zSize);
// For our purposes, the "best" format is the one that winds up with Z=1 and the largest x and y sizes.
if (zSize == 1) {
if (xSize >= bestXSize && ySize >= bestYSize) {
bestIndex = i;
bestXSize = xSize;
bestYSize = ySize;
}
}
}
_check_gl_error();
mXTileSize = bestXSize;
glTexParameteri(GL_TEXTURE_2D, GL_VIRTUAL_PAGE_SIZE_INDEX_ARB, bestIndex);
_check_gl_error();
//Need to ensure that the texture is a multiple of the tile size.
physicalWidth = roundUpToMultiple(width, bestXSize);
physicalHeight = roundUpToMultiple(height, bestYSize);
// We've set all the necessary parameters, now it's time to create the sparse texture.
glTexStorage2D(GL_TEXTURE_2D, levels, GL_RGBA8, physicalWidth, physicalHeight);
_check_gl_error();
for (GLsizei i = 0; i < slices; ++i) {
mFreeList.push(i);
}
_check_gl_error();
mHandle = glGetTextureHandleARB(mTexId);
_check_gl_error();
glMakeTextureHandleResidentARB(mHandle);
_check_gl_error();
mWidth = physicalWidth;
mHeight = physicalHeight;
mLevels = levels;
以下是分配后发生的事情:
glTextureSubImage2DEXT(mTexId, GL_TEXTURE_2D, level, 0, 0, width, height, GL_RGB, GL_UNSIGNED_BYTE, data);
我尝试将宽度和高度设置为后备存储的物理宽度和传入图像内容的宽度/高度。都没有产生预期的结果。我现在排除了mip级别。当我使用Mip级别和纹理数组时,我得到了不同的结果,但行为相似。
此外,图像是从SOIL加载的,在我实现稀疏纹理之前,效果非常好(在稀疏之前我实现了无绑定)。