Edward Angel 示例 OpenGL 代码:在 Lenovo X60 上运行良好,但不能在我的桌面上呈现窗口(英特尔高清显卡)

Posted

技术标签:

【中文标题】Edward Angel 示例 OpenGL 代码:在 Lenovo X60 上运行良好,但不能在我的桌面上呈现窗口(英特尔高清显卡)【英文标题】:Edward Angel example OpenGL code: runs fine on Lenovo X60, but does not render windows on my desktop (Intel HD Graphics) 【发布时间】:2013-08-20 08:45:03 【问题描述】:

我是 OpenGL 的新手,正在尝试运行 Edward Angel 的著名书籍 Interactive Computer Graphics 中的一些经典示例代码。但是,我遇到了一个让我很困惑但对其他人来说可能非常明显的问题。示例代码为“Gasket.c”,可从http://www.cs.unm.edu/~angel/BOOK/INTERACTIVE_COMPUTER_GRAPHICS/FIFTH_EDITION/PROGRAMS/CHAPTER02/下载

我已经在我的 Lenovo X60(Windows 7)上使用 VS2010 Express 运行了这段代码,它成功绘制了 Sierspinski 垫片。但是,当我尝试在具有相同软件系统的桌面(英特尔高清显卡)上运行相同代码时,它没有绘制任何内容,仅显示一个空白(白色)窗口。该文件已编译/构建,没有任何问题,也没有错误/警告。

Gasket.c如下

/* Two-Dimensional Sierpinski Gasket          */
/* Generated Using Randomly Selected Vertices */
/* And Bisection                              */

#ifdef __APPLE__
#include <GLUT/glut.h>
#else
#include <GL/glut.h>
#endif

void myinit()


/* attributes */

     glClearColor(1.0, 1.0, 1.0, 1.0); /* white background */
     glColor3f(1.0, 0.0, 0.0); /* draw in red */

/* set up viewing */
/* 500 x 500 window with origin lower left */

     glMatrixMode(GL_PROJECTION);
     glLoadIdentity();
     gluOrtho2D(0.0, 50.0, 0.0, 50.0);
     glMatrixMode(GL_MODELVIEW);


void display( void )

    GLfloat vertices[3][2]=0.0,0.0,25.0,50.0,50.0,0.0; /* A triangle */

    int j, k;
    int rand();       /* standard random number generator */
    GLfloat p[2] =7.5,5.0;  /* An arbitrary initial point inside traingle */

    glClear(GL_COLOR_BUFFER_BIT);  /*clear the window */


/* compute and plots 5000 new points */

        glBegin(GL_POINTS);

    for( k=0; k<5000; k++)
    
         j=rand()%3; /* pick a vertex at random */


     /* Compute point halfway between selected vertex and old point */

         p[0] = (p[0]+vertices[j][0])/2.0; 
         p[1] = (p[1]+vertices[j][1])/2.0;

     /* plot new point */

        glVertex2fv(p); 

     
     glEnd();
     glFlush(); /* clear buffers */
   

void main(int argc, char** argv)


/* Standard GLUT initialization */

    glutInit(&argc,argv);
    glutInitDisplayMode (GLUT_SINGLE | GLUT_RGB); /* default, not needed */
    glutInitWindowSize(500,500); /* 500 x 500 pixel window */
    glutInitWindowPosition(0,0); /* place window top left on display */
    glutCreateWindow("Sierpinski Gasket"); /* window title */
    glutDisplayFunc(display); /* display callback invoked when window opened */

    myinit(); /* set attributes */

    glutMainLoop(); /* enter event loop */

【问题讨论】:

这不是一个答案,而是一个有用的提示 - 您正在学习高度过时的 OpenGL。如果您打算真正学习现代图形,请立即停止并学习可编程管道。它更快、更灵活,虽然它的初始学习曲线更陡峭——但是,嘿,谁开自动兰博基尼,对吧?与问题相关的提示:尝试画一个点或一个三角形,然后画几个,然后改变周围的颜色。这应该有助于隔离问题。 是的,你是对的。我还是想学可编程流水线。我实际上是从 OpenGL 教程 3.2+ 开始的,但它不能在我的笔记本电脑(联想 X60)上运行,也不能在我的带有英特尔高清显卡的台式机上运行。然后我为我的桌面切换到 OpenGL 教程 2.1,它运行良好。但我被我的笔记本电脑困住了:(我想我最终还是得更新我的笔记本电脑,尽管我仍然很喜欢它...... 【参考方案1】:

尝试从单缓冲 (GLUT_SINGLE) 切换到双缓冲 (GLUT_DOUBLE):

#include <GL/glut.h>

void display( void )

    GLfloat vertices[3][2]=0.0,0.0,25.0,50.0,50.0,0.0; /* A triangle */

    int j, k;
    int rand();       /* standard random number generator */
    GLfloat p[2] =7.5,5.0;  /* An arbitrary initial point inside traingle */

    glClearColor(1.0, 1.0, 1.0, 1.0); /* white background */
    glClear(GL_COLOR_BUFFER_BIT);  /*clear the window */

    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();

    gluOrtho2D(0.0, 50.0, 0.0, 50.0);
    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();

    /* compute and plots 5000 new points */
    glColor3f(1.0, 0.0, 0.0); /* draw in red */
    glBegin(GL_POINTS);
    for( k=0; k<5000; k++)
    
        j=rand()%3; /* pick a vertex at random */

        /* Compute point halfway between selected vertex and old point */
        p[0] = (p[0]+vertices[j][0])/2.0; 
        p[1] = (p[1]+vertices[j][1])/2.0;

        /* plot new point */
        glVertex2fv(p); 

    
    glEnd();

    glutSwapBuffers();


void main(int argc, char** argv)

    glutInit(&argc,argv);
    glutInitDisplayMode (GLUT_DOUBLE | GLUT_RGB); /* default, not needed */
    glutInitWindowSize(500,500); /* 500 x 500 pixel window */
    glutInitWindowPosition(0,0); /* place window top left on display */
    glutCreateWindow("Sierpinski Gasket"); /* window title */
    glutDisplayFunc(display); /* display callback invoked when window opened */
    glutMainLoop(); /* enter event loop */

【讨论】:

是的,它有效!你能解释一下为什么我的旧联想 X60 不需要双缓冲,而我需要使用英特尔高清显卡吗?有什么条件我们应该使用单缓冲或双缓冲? @iyl:我怀疑在您的较新系统上您正在运行一个执行窗口合成的操作系统。合成器需要双缓冲交换作为将图片从应用程序绘制到屏幕的提示。在单个缓冲窗口上,合成器要么必须不断地拉动,要么挂钩一些基本的图形上下文功能(在 Windows 上通常是 BeginPaint / EndPaint 和 WM_PAINT 消息)。这完全错过了通常的 OpenGL 操作。 @iyl:你也可以试试glFinish() instead of glFlush() 我试过了,没用。我认为使用双缓冲和 glutSwapBuffers 是 OpenGL 代码在我的桌面上正常运行的唯一方法。 @datenwolf:感谢您的解释——这似乎很有说服力。我如何知道操作系统是否在进行窗口合成? OpenGL 中是否有任何方法可以自动检测并设置正确的设置? @iyl:OpenGL 与操作系统无关,窗口绘制到屏幕上的方式可能会有很大差异,这取决于操作系统、图形系统运行甚至设置。但是有一些强烈的暗示。 Microsoft Windows 从 Windows Vista 开始支持合成,使用 Aero;存在称为dwm.exe 的进程表明合成可能处于活动状态。 MacOS X 总是像 Tiger 一样复合,并引入了 Quartz Extreme。

以上是关于Edward Angel 示例 OpenGL 代码:在 Lenovo X60 上运行良好,但不能在我的桌面上呈现窗口(英特尔高清显卡)的主要内容,如果未能解决你的问题,请参考以下文章

NDK-第一个OpenGL示例

“openSuse 和 openGL”环境的示例程序

纹理小部件渲染 OpenGL 示例

Angel - MemoryDataBlock - angel.task.estimize.sample.number

无法在 SDL2 中运行 OpenGL 示例

颜色在开始示例opengl中不起作用