私は、この奇妙なクリッピングのバグをアプリで並べ替えるのに非常に苦労しています。Windows OpenGL実装のバグ?
基本的に、何らかの理由で、OpenGLがglClear()呼び出しをクリッピング(シザーテストを使用)していますが、後で行うレンダリングではありません。
しかし、本当の問題は、ウィンドウのサイズを変更すると問題が消えてしまうことです。ウィンドウのサイズを変更してもアプリで何も変わったり、コードを実行したりすることはありません。それは非常に奇妙です。さらに悪いことに、単に私が代わりにまたはglDisable(ちょうど1つのコールを持つのシザーテストを、無効にする必要があり
glDisable(GL_SCISSOR_TEST);
glDisable(GL_SCISSOR_TEST);
)を置くこと問題を解決します。コードを一括して削除します(シーザーテストはすでにこのテストケースでは無効になっていますが、コードは前のコードで無効にしていないときに使用されています)。これは、問題を解決するためにも役立ちます。
glEnable(GL_SCISSOR_TEST);
glDisable(GL_SCISSOR_TEST);
私は考えることができるのは2つだけです。私は何とかUBを呼び出しています(OpenGLにはUB AFAIKがないので疑います)、またはglDisable()を同じパラメータで2回呼び出すと、一度呼び出すと同じでなければならないので、実装上のバグがあります。もし私が間違っていなければ。
ことが重要であるJUST包み、ここで問題が起こっされた機能は次のとおりです。
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ドライバはかなり吸う - インテルのドライバが最悪です。 –
私にバグのように見えます。あなたのハードウェアの最新版にあなたのGLドライバを更新します。 – Bahbar