glread像素模板缓冲区总是抛出GL_INVALID_OPERATION

glreadpixels stencil buffer always throws GL_INVALID_OPERATION

本文关键字:GL INVALID OPERATION 像素 缓冲区 glread      更新时间:2023-10-16

我正在尝试找出模板。现在我只是画一些带有模板值的框,然后读取值。每次我用GL_STENCIL_INDEX调用glReadPixel时,我都会得到GL_INVALID_OPERATION。这是有问题的代码:

glPixelStorei(GL_PACK_ALIGNMENT, 1);
GLfloat tempStencilVal = 3;
glGetError();
glReadPixels(10, g_window1Height-10, 1, 1, GL_STENCIL_INDEX, GL_FLOAT, &tempStencilVal);
if (glGetError() == GL_INVALID_OPERATION) {std::cout << "GL Invalid Operationn";}
else {std::cout << "X: " << 10 << " Y: " << 10 << " S: " << tempStencilVal << "n";}

我尝试了 5 种不同的数据格式、3 种不同的 glPixelStore 模式,并查看了 glReadPixel 错误列表 7 次。(是的,OGL 2.1)如果我将STENCIL_INDEX更改为DEPTH_COMPONENT它工作正常。我唯一无法确认的是我是否有模板缓冲区。我是否缺少一些初始化或一些 glGet 来检查?

潜在相关信息:Win7 x64 SP1 |华硕 GTX650Ti |VS2012 终极版

以下是用于绘制框的函数的代码,以防导致它:

glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(0, g_window1Width, -g_window1Height, 0, 0.0, 50.0);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glScaled(1.0, -1.0, -1.0);
glTranslated(0.0, 0.0, 0.5);
glClearColor(0.0, 0.0, 0.0, 0.0);
glClearStencil(0);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
glDisable(GL_DEPTH_TEST);
glEnable(GL_STENCIL_TEST);
glStencilOp( GL_REPLACE, GL_REPLACE, GL_REPLACE );
glColor3ub(0, 100, 250);
glStencilFunc(GL_ALWAYS, 1, 1);
glBegin(GL_QUADS);
glVertex3d(0, 0, 0);
glVertex3d(0, 50, 0);
glVertex3d(50, 50, 0);
glVertex3d(50, 0, 0);
glEnd();
glStencilFunc(GL_ALWAYS, 1, 1);
glBegin(GL_QUADS);
glVertex3d(g_window1Width-50, 0, 0);
glVertex3d(g_window1Width, 0, 0);
glVertex3d(g_window1Width, 50, 0);
glVertex3d(g_window1Width-50, 50, 0);
glEnd();

这不是OGL第一次无缘无故地做错事,但这打破了我对界面编码的计划。

要检查您是否确实有模板缓冲区,您可以尝试使用这些值执行一些操作,例如在启用和未启用模板测试的情况下绘制另一个带有glStencilFunc(GL_NOTEQUAL, 1, 1);的四边形。

要找到使用的实际格式,正如您所说的那样 glGet... ,看起来glGetFramebufferAttachmentParameter会给你答案(绑定默认帧缓冲)。

模板缓冲区是 8 位(我认为它不能是其他任何东西),所以也许将格式更改为 GL_UNSIGNED_BYTE .

也可以将深度和模板缓冲区与GL_DEPTH_STENCIL混合,您可以使用GL_UNSIGNED_INT_24_8 。我不知道默认帧缓冲的格式是什么,或者这是否适用于您的情况。如果您使用的是 glut、SDL 或 glfw 等库,则负责设置它以及您应该在其中查找配置默认帧缓冲区的位置。