当前位置: 首页 > 知识库问答 >
问题:

C OpenGL 中的第二个窗口在第一个窗口中停用土壤纹理

丁灿
2023-03-14

所以我一直在为openGL课程玩土壤,我的项目遇到了一个奇怪的问题。我将显示两个窗口,每个窗口包含三个视口,在其中绘制一个带纹理的立方体或椭圆体,以展示我对深度和面剔除的理解。现在,所有形状都正确绘制,并且当单独测试时,它看起来完全符合预期,但是一旦我同时启用两个窗口,纹理就会在第一个窗口中禁用。我之前已经发布了类似的问题,所以只是为了澄清,如果我禁用窗口二,或者如果我在窗口二中使用窗口一绘制功能,纹理工作有效。只有当两个窗口同时显示时,问题才会出现。我还能够更改渲染形状的颜色,因此我最好的想法是,当我移动到窗口二时,我以某种方式禁用了第一个窗口中的矩阵或缓冲区。

这是我的主代码,带有初始化void main(int argc,char**argv){glutInit(

    glutInitWindowSize(750, 250);

    #pragma region WINDOW ONE INITIALISATION
    glutInitWindowPosition(0, 50);

    windowID[1] = glutCreateWindow("cubes");

    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    glOrtho(-400, 400, -400, 400, -500, 500);

    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();

    glutDisplayFunc(DrawWindowOne);
    #pragma endregion 

    #pragma region WINDOW TWO INITIALISATION
    glutInitWindowPosition(0, 450);
    windowID[1] = glutCreateWindow("ellipsoids");

    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    glFrustum(-60, 60, -60, 60, 60, 200);
    gluLookAt(0, 0, 120, 0, 0, 0, 0, 1, 0);

    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();

    glutDisplayFunc(DrawWindowTwo);
    #pragma endregion

    LoadTextures(); // Handles the SOIL_load_OGL_Texture() lines. Works 100%

    gluQuadricTexture(quad, GL_TRUE);
}

这是两个窗口绘制函数

void DrawWindowOne()
{
    glClearColor(0.0, 0.0, 0.0, 0.0);    
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); 

#pragma region Viewport One 

    glViewport(0, 0, 250, 250);                     

    glMatrixMode(GL_MODELVIEW);         

    DrawCubes();

#pragma endregion
#pragma region Viewport Two 

    glViewport(250, 0, 250, 250);   

    glMatrixMode(GL_MODELVIEW);     

    glEnable(GL_CULL_FACE);
    DrawCubes();
    glDisable(GL_CULL_FACE);

#pragma endregion
#pragma region Viewport Three   

    glViewport(500, 0, 250, 250);

    glMatrixMode(GL_MODELVIEW);

    glEnable(GL_DEPTH_TEST);
    DrawCubes();
    glDisable(GL_DEPTH_TEST);

#pragma endregion

    glFlush();
    glutSwapBuffers();
}

void DrawWindowTwo()
{
    glClearColor(1.0, 1.0, 1.0, 0.0);
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);     

    #pragma region Viewport One 

    glViewport(0, 0, 250, 250); 

    glMatrixMode(GL_MODELVIEW); 
    DrawEllipsoids();

    #pragma endregion
    #pragma region Viewport Two 

    glViewport(250, 0, 250, 250);   

    glMatrixMode(GL_MODELVIEW); 

    glEnable(GL_CULL_FACE);
    DrawEllipsoids();
    glDisable(GL_CULL_FACE);

    #pragma endregion
    #pragma region Viewport Three   

    glViewport(500, 0, 250, 250);   

    glMatrixMode(GL_MODELVIEW);     

    glEnable(GL_DEPTH_TEST);
    DrawEllipsoids();
    glDisable(GL_DEPTH_TEST);

    #pragma endregion

    glFlush();
    glutSwapBuffers();
}

这是我的一点点对象绘制代码。我已经把它剥离了一点;它只为立方体绘制一个面(我已经确认,如果所有视口都绘制一个面,也会出现同样的问题)。

void DrawCubes()
{
    glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); 
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);   
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);   
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);

    glEnable(GL_TEXTURE_2D);
    glBindTexture(GL_TEXTURE_2D, textureID[0]);

    glBegin(GL_QUADS);
    glNormal3f(0.0, 0.0, -1.0); // front face
    glTexCoord2f(0.0, 0.0); glVertex3f(-a,-a,-a);
    glTexCoord2f(0.0, 1.0); glVertex3f(-a, a,-a);
    glTexCoord2f(1.0, 1.0); glVertex3f( a, a,-a);
    glTexCoord2f(1.0, 0.0); glVertex3f( a,-a,-a);
    glEnd()
    glDisable(GL_TEXTURE_2D);
}

共有1个答案

高承望
2023-03-14

GLUT为每个窗口创建OpenGL上下文。这些上下文不共享。在GL中,最多有一个GL上下文可以“设置为当前”线程,因此您调用的任何GL函数都将使用当前活动的GL上下文。

如果窗口二初始化中的代码处于活动状态,GLUT 将创建一个新窗口并使其上下文成为当前上下文。因此,您的 LoadTextures() 调用将仅影响第二个上下文,并且您的第一个上下文将不会加载任何纹理。

一种解决方案是调用加载纹理()两次。但是,该函数可能使用一些变量来存储纹理名称 - 并且这些变量在两个相同的上下文之间可能不相同,因此从概念上讲,您必须扩展代码。

另一种解决方案是使用共享上下文。它们共享任何对象,如纹理、缓冲区等。但是,GLUT不支持这一点。

另一个解决方案是依赖freeglut的扩展,而不是“官方”的glut规范(这在任何情况下都是完全过时的):

glutSetOption(GLUT_RENDERING_CONTEXT, GLUT_USE_CURRENT_CONTEXT);

将告诉 freeglut 不要为它创建的下一个窗口创建新上下文,而是重用现有的上下文。然后,您的代码基本上可以按照您的预期工作。

 类似资料:
  • 问题内容: 我正在尝试从第二个窗口切换到第三个窗口。但是无法处理第三个窗口。有人可以帮助我解决此问题。我已经使用比较窗口标题的逻辑,但是它不起作用。代码======================= 错误堆栈跟踪: 问题答案: 这是切换到 并单击 按钮的完整代码块: 我的IDE控制台上的输出是:

  • 问题内容: 我正在有限的时间里进行学校项目,导致代码混乱和混乱。我正在尝试打开两个jFrame,一个显示聊天界面,另一个显示图像。从第一个窗口调用时,我想调用一个方法,该方法多次更改第二个窗口上的图像,并且之间有一些延迟。但是,图像不会改变。 我认为我的问题是由于在文本窗口中使用了一些示例代码,并试图合并我自己的修改而没有完全理解前者。在尝试查找此问题时,我仅发现人们根据计时器和in来更新其jFr

  • 第一课: 新建一个窗口 简介 欢迎来到第一课! 在学习OpenGL之前,我们将先学习如何生成,运行,和玩转(最重要的一点)课程中的代码。 预备知识 不需要特别的预备知识。如果你有C、Java、Lisp、Javascript等编程语言的经验,那么理解课程代码会更快;但这不是必需的;如果没有,那么也仅仅是同时学两样东西(编程语言+OpenGL)会稍微复杂点而已。 课程全部用“傻瓜式C++”编写:我费了

  • 我的应用程序在单击按钮时打开一个新窗口,我需要在该窗口中执行一些操作。但是SeleniumWebDriver的响应getWindowHandles()方法中只有一个窗口id。如果在打开新窗口后调用getWindowHandles()时出现延迟,则会发生这种情况。硒有一个已知的问题。https://github.com/SeleniumHQ/selenium/wiki/InternetExplore

  • 我正在使用JavaFx对GUI进行编程,我真的不知道如何连接所有内容。我有一个主窗口,在主窗口中我有一个按钮可以打开另一个窗口,允许我选择客户。现在我已经在努力将选定客户的信息返回给主窗口,因为我没有打开它的返回方法。 我是这样打开的:public void openSecondWindow(ActionEvent事件){ 我自己没有初始化第二个窗口,也没有像第二个窗口sc=new第二个窗口()这

  • 现在我们开始编写全书的第一个程序。跟我们以前学习程序设计的方法不同(以前我们是输入完整程序,然后运行),我们首先利用Visual Studio的可视化编程工具AppWizard生成框架程序,再往里边填写代码。这是一种“填空式”的编程方法:首先生成框架,然后根据目标程序的要求,看哪些地方需要修改,再往里填写代码。类似其他语言,我们把第一个程序命名为Hello。 首先启动AppWizard:在File