我有一個非常艱難的時間在我的應用程序中整理出這個奇怪的剪切錯誤。基本上,出於某種原因,OpenGL正在剪裁(使用剪刀測試)我的glClear()調用,但不是之後做的渲染。Windows OpenGL實現錯誤?
然而,真正的問題是,當我調整窗口大小時,問題消失。我可以保證調整窗口大小不會改變我的應用程序中的任何內容或運行任何代碼。這非常棒。更糟糕的是,乾脆把
glDisable(GL_SCISSOR_TEST);
glDisable(GL_SCISSOR_TEST);
,我需要禁用剪刀測試,而不是僅具有一個調用glDisable()函數解決了這個問題。所以一起刪除代碼(在這個測試用例中,剪刀測試已經被禁用了,但是代碼在這個代碼中沒有在之前的代碼中被禁用)。它甚至解決了這個問題:
glEnable(GL_SCISSOR_TEST);
glDisable(GL_SCISSOR_TEST);
只有兩個解釋我能想到。要麼我以某種方式調用UB(我懷疑,因爲opengl沒有UB AFAIK),或者存在實現錯誤,因爲連續調用兩次具有相同參數的glDisable()應該與調用一次相同。如果我沒錯的話。
只是櫃面很感興趣,這裏是該問題發生的功能:
void gle::Renderer::setup3DCamera(gle::CameraNode& cam, gle::Colour bkcol,
int clrmask, int skymode, gle::Texture* skytex, bool uselight) {
// Viewport
Rectangle wr(cam.getViewport()?*cam.getViewport():Rectangle(0,0,1,1));
if (cam.isRatioViewport()||(!cam.getViewport())) {
if (i_frameBind==NULL)
wr.scale(selectedWindow->getWidth(),selectedWindow->getHeight());
else wr.scale(i_frameBind->getWidth(),i_frameBind->getHeight());
}
gle::Rectangle_t<int> iport; iport.set(wr);
int winHei;
if (i_frameBind==NULL)
winHei = selectedWindow->getHeight();
else
winHei = i_frameBind->getHeight();
glViewport(iport.x1(),winHei-iport.y2(),iport.wid(),iport.hei());
// Viewport Clipping
if (cam.isClipping()) {
/* This is never executed in the test case */
glEnable(GL_SCISSOR_TEST);
glScissor(iport.x1(),winHei-iport.y2(),iport.wid(),iport.hei());
} else {
/* This is where I disable the scissor test */
glDisable(GL_SCISSOR_TEST);
glDisable(GL_SCISSOR_TEST);
}
float w=wr.wid()/2, h=wr.hei()/2;
// Projection
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
Projection proj = cam.getProjection();
gluPerspective(proj.fov,proj.aspect*(w/h),proj.cnear,proj.cfar);
// Camera
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
float m[] = { 1,0,0,0, 0,0,-1,0, 0,1,0,0, 0,0,0,1 };
glMultMatrixf(m);
static gle::Mesh *skyBox = NULL;
// Screen Clearing
switch (clrmask&GLE_CLR_COLOUR&0x00F?skymode:GLE_SKYNONE) {
case GLE_SKYNONE:
clear(clrmask&(~GLE_CLR_COLOUR)); break;
case GLE_SKYCOLOUR:
clearColour(clrmask,bkcol); break;
case GLE_SKYBOX:
glDisable(GL_DEPTH_TEST);
if (!(clrmask&GLE_CLR_DEPTH&0x00F)) glDepthMask(0);
float m = (cam.getProjection().cnear+cam.getProjection().cfar)/2.0f;
if (skyBox==NULL) skyBox = gle::createStockMesh(GLE_MESHSKYBOX,GLE_WHITE,0,m);
glEnable(GL_TEXTURE_2D);
glDisable(GL_CULL_FACE);
skytex->flush();
glBindTexture(GL_TEXTURE_2D,skytex->getID());
glDisable(GL_LIGHTING);
glPushMatrix();
float m3[16];
Orientation::matrixSet(m3,cam.pos().getMatrix(GLE_ROTMATRIX));
Orientation::matrixTranspose(m3);
glMultMatrixf(m3);
if (i_reflectionOn) glMultMatrixf(Orientation::matrixGet3x3(i_reflectionTransform));
renderMesh(*skyBox,NULL,1);
glPopMatrix();
glDisable(GL_TEXTURE_2D);
if (clrmask&GLE_CLR_DEPTH) glClear(GL_DEPTH_BUFFER_BIT);
else glDepthMask(1);
glAble(GL_DEPTH_TEST,depthmode!=GLE_ALWAYS);
break;
}
// Camera
glMultMatrixf(cam.getAbsInverseMatrix());
if (i_reflectionOn) glMultMatrixf(i_reflectionTransform);
// Lighting
i_lightOn = uselight;
glAble(GL_LIGHTING,i_lightOn);
}
您可以使用[Mesa](http://www.mesa3d.org/)軟件光柵器進行重現嗎? – genpfault
什麼顯卡?除NVidia之外的任何人的windows openGL驅動程序都非常糟糕 - 英特爾驅動程序是最糟糕的。 –
看起來像一個bug給我。將您的GL驅動程序更新到硬件的最新版本,如果它仍然重現,請提交錯誤... – Bahbar