这个问题是我所描述的here问题的延续。这是我见过的最奇怪的错误之一。我的引擎在两种模式下运行:显示模式和屏幕外。操作系统是Linux。我为纹理生成mipmap,在显示模式下它一切正常。在那种模式下,我使用GLFW3进行上下文创建。现在,有趣的部分:在屏幕外模式下,我用下面的代码手动创建的上下文,mipmap生成偶然失败!在某些运行中,结果输出看起来没问题,而在其他情况下,缺少的级别可以清楚地看到帧充满纹理垃圾数据或完全为空。 起初我虽然我的mipmap gen例程错了,但是这样:
glGenTextures(1, &textureName);
glBindTexture(GL_TEXTURE_2D, textureName);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, imageInfo.Width, imageInfo.Height, 0, imageInfo.Format, imageInfo.Type, imageInfo.Data);
glTexParameteri ( GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 0 );
glGenerateMipmap(GL_TEXTURE_2D);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
我也试过玩这个参数:
glTexParameteri ( GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, XXX);
包括最高水平检测公式:
int numMipmaps = 1 + floor(log2(glm::max(imageInfoOut.width, imageInfoOut.height)));
但所有这些东西并没有一致地工作。在10-15次运行中3-4出现了破碎的Mipmaps。然后我发现切换到GL_LINEAR解决了它。在mipmap模式下,只设置1最后我开始认为在上下文层面可能有问题,因为在屏幕模式下它可以工作!我将上下文创建切换到GLFW3并且它有效。所以我想知道这里发生了什么?我想念一些东西吗?在打破mipmaps生成的Pbuffer设置中?我怀疑它是因为AFAIK是由驱动程序完成的。
这是我自定义的离屏上下文创建设置:
int visual_attribs[] = {
GLX_RENDER_TYPE,
GLX_RGBA_BIT,
GLX_RED_SIZE, 8,
GLX_GREEN_SIZE, 8,
GLX_BLUE_SIZE, 8,
GLX_ALPHA_SIZE, 8,
GLX_DEPTH_SIZE, 24,
GLX_STENCIL_SIZE, 8,
None
};
int context_attribs[] = {
GLX_CONTEXT_MAJOR_VERSION_ARB, vmaj,
GLX_CONTEXT_MINOR_VERSION_ARB, vmin,
GLX_CONTEXT_FLAGS_ARB,
GLX_CONTEXT_ROBUST_ACCESS_BIT_ARB
#ifdef DEBUG
| GLX_CONTEXT_DEBUG_BIT_ARB
#endif
,
GLX_CONTEXT_PROFILE_MASK_ARB, GLX_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB,
None
};
_xdisplay = XOpenDisplay(NULL);
int fbcount = 0;
_fbconfig = NULL;
// _render_context
if (!_xdisplay) {
throw();
}
/* get framebuffer configs, any is usable (might want to add proper attribs) */
if (!(_fbconfig = glXChooseFBConfig(_xdisplay, DefaultScreen(_xdisplay), visual_attribs, &fbcount))) {
throw();
}
/* get the required extensions */
glXCreateContextAttribsARB = (glXCreateContextAttribsARBProc) glXGetProcAddressARB((const GLubyte *) "glXCreateContextAttribsARB");
glXMakeContextCurrentARB = (glXMakeContextCurrentARBProc) glXGetProcAddressARB((const GLubyte *) "glXMakeContextCurrent");
if (!(glXCreateContextAttribsARB && glXMakeContextCurrentARB)) {
XFree(_fbconfig);
throw();
}
/* create a context using glXCreateContextAttribsARB */
if (!(_render_context = glXCreateContextAttribsARB(_xdisplay, _fbconfig[0], 0, True, context_attribs))) {
XFree(_fbconfig);
throw();
}
// GLX_MIPMAP_TEXTURE_EXT
/* create temporary pbuffer */
int pbuffer_attribs[] = {
GLX_PBUFFER_WIDTH, 128,
GLX_PBUFFER_HEIGHT, 128,
None
};
_pbuff = glXCreatePbuffer(_xdisplay, _fbconfig[0], pbuffer_attribs);
XFree(_fbconfig);
XSync(_xdisplay, False);
/* try to make it the current context */
if (!glXMakeContextCurrent(_xdisplay, _pbuff, _pbuff, _render_context)) {
/* some drivers does not support context without default framebuffer, so fallback on
* using the default window.
*/
if (!glXMakeContextCurrent(_xdisplay, DefaultRootWindow(_xdisplay),
DefaultRootWindow(_xdisplay), _render_context)) {
throw();
}
}
几乎忘了:我的系统和硬件:
Kubuntu 13.04 64bit。 GPU:NVidia Geforce GTX 680。该引擎使用OpenGL 4.2 API
完整的OpenGL信息:
** OpenGL供应商字符串:NVIDIA Corporation
OpenGL渲染器字符串:GeForce GTX 680 / PCIe / SSE2
OpenGL版本字符串:4.4.0 NVIDIA 331.49
OpenGL着色语言版本字符串:4.40 NVIDIA通过Cg编译器**
不过,我还使用了较老的司机,但这并不重要。更新
似乎我对GLFW的假设是错误的。当我编译引擎并从终端运行它时也会发生同样的情况。但是 - 如果我从IDE运行引擎(调试或发布),则mipmap没有问题。独立应用程序是否可以针对不同的SO工作?
为了说清楚,我没有使用Pbuffers渲染到。我渲染到自定义帧缓冲区。
UPDATE1:
我已经读过2个纹理的非强大功能可能很难自动生成mipmap。并且在OpenGL无法生成所有级别的情况下,它会转换纹理使用情况。这可能是我遇到的问题这里?因为一旦mipmapped纹理出错,剩下的纹理(非mipmap)也会消失。但是如果是这种情况那么为什么这种行为是不一致的呢?
答案 0 :(得分:0)
你想要屏幕外渲染吗?然后使用帧缓冲对象(FBO)。
你需要纯粹的屏幕外环境吗?然后创建一个普通窗口,您只是不显示它并在其上创建一个FBO。