Opengl macos失败

Posted

技术标签:

【中文标题】Opengl macos失败【英文标题】:Opengl macos fail 【发布时间】:2015-02-07 19:25:25 【问题描述】:

我有问题。我在没有任何库(glut,glew ...)的情况下在clear opengl和c ++上编写了代码,但它不起作用。 函数displayCB用

显示多边形
glColor3f(1.0f, 0.0f, 0.0f);
   glBegin(GL_POLYGON);
     glVertex2f(-0.5f, -0.5f);
     glVertex2f( 0.5f, -0.5f);
     glVertex2f( 0.5f,  0.5f);
     glVertex2f(-0.5f,  0.5f);
   glEnd();

并且不要用

显示两个多边形
glColor3f(1.0f, 0.0f, 0.0f);
     glLoadIdentity();                                  // Reset The Current Modelview Matrix
        glTranslatef(-1.5f,0.0f,-6.0f);                     // Move Left 1.5 Units And Into The Screen 6.0
        glBegin(GL_TRIANGLES);                              // Drawing Using Triangles
            glVertex3f( 0.0f, 1.0f, 0.0f);                  // Top
            glVertex3f(-1.0f,-1.0f, 0.0f);                  // Bottom Left
            glVertex3f( 1.0f,-1.0f, 0.0f);                  // Bottom Right
        glEnd();                                            // Finished Drawing The Triangle
        glTranslatef(3.0f,0.0f,0.0f);                       // Move Right 3 Units
        glBegin(GL_QUADS);                                  // Draw A Quad
            glVertex3f(-1.0f, 1.0f, 0.0f);                  // Top Left
            glVertex3f( 1.0f, 1.0f, 0.0f);                  // Top Right
            glVertex3f( 1.0f,-1.0f, 0.0f);                  // Bottom Right
            glVertex3f(-1.0f,-1.0f, 0.0f);                  // Bottom Left
        glEnd();

你能帮帮我吗?

编译:g++ -g -o opengl1 opengl1.cxx -lGLU -lGL -lX11

    #include <stdio.h>
    #include <stdlib.h>
    #include <ctype.h>
    #include <sys/time.h>
    #define GL_GLEXT_PROTOTYPES
    #define GLX_GLXEXT_PROTOTYPES
    #include <GL/gl.h>
    #include <GL/glu.h>
    #include <GL/glx.h>

    struct MyWin
    
      Display  *display;
      Window    win;
      bool      displayed;
      int       width;
      int       height;
    ;


    const int   WIN_XPOS    = 256;
    const int   WIN_YPOS    = 64;
    const int   WIN_XRES    = 600;
    const int   WIN_YRES    = 600;
    const int   NUM_SAMPLES = 4;


    MyWin        Win;


    double elapsedMsec( const struct timeval &start, const struct timeval &stop )
    
      return ( ( stop.tv_sec  - start.tv_sec  ) * 1000.0 +
               ( stop.tv_usec - start.tv_usec ) / 1000.0 );
    


    double elapsedUsec( const struct timeval &start, const struct timeval &stop )
    
      return ( ( stop.tv_sec  - start.tv_sec  ) * 1000000.0 +
           ( stop.tv_usec - start.tv_usec ) );
    


    /// check() - Check for GL errors, and report any queued

    void check( const char hdr[] = "" )

  int err;

  while ( ( err = glGetError() ) != GL_NO_ERROR )
    fprintf( stderr, "OpenGL Error at %s: %s\n", hdr, gluErrorString(err) );




void displayCB()

  glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );

  //---------------------------------------------------
  // FIXME: Insert GL draw code here
  //---------------------------------------------------
  glColor3f(1.0f, 0.0f, 0.0f);
  glLoadIdentity();                                 // Reset The Current Modelview Matrix
    glTranslatef(-1.5f,0.0f,-6.0f);                     // Move Left 1.5 Units And Into The Screen 6.0
    glBegin(GL_TRIANGLES);                              // Drawing Using Triangles
        glVertex3f( 0.0f, 1.0f, 0.0f);                  // Top
        glVertex3f(-1.0f,-1.0f, 0.0f);                  // Bottom Left
        glVertex3f( 1.0f,-1.0f, 0.0f);                  // Bottom Right
    glEnd();                                            // Finished Drawing The Triangle
    glTranslatef(3.0f,0.0f,0.0f);                       // Move Right 3 Units
    glBegin(GL_QUADS);                                  // Draw A Quad
        glVertex3f(-1.0f, 1.0f, 0.0f);                  // Top Left
        glVertex3f( 1.0f, 1.0f, 0.0f);                  // Top Right
        glVertex3f( 1.0f,-1.0f, 0.0f);                  // Bottom Right
        glVertex3f(-1.0f,-1.0f, 0.0f);                  // Bottom Left
    glEnd();            
  // glBegin(GL_POLYGON);
  //   glVertex2f(-0.5f, -0.5f);
  //   glVertex2f( 0.5f, -0.5f);
  //   glVertex2f( 0.5f,  0.5f);
  //   glVertex2f(-0.5f,  0.5f);
  // glEnd();
  // Display it
  glXSwapBuffers( Win.display, Win.win );

  check( "displayCB()" );


//----------------------------------------------------------------------------

void keyboardCB( KeySym sym, unsigned char key, int x, int y,
                 bool &setting_change )

  switch ( tolower( key ) )
  
    case 27:
      // ESCape - We're done!
      exit (0);
      break;

    case 'k':
      printf( "You hit the 'k' key\n" );
      break;

    case 0:
      switch ( sym )
      
        case XK_Left  : 
          printf( "You hit the Left Arrow key\n" );
          break;

        case XK_Right :
          printf( "You hit the Right Arrow key\n" );
          break;
      
      break;
  


//----------------------------------------------------------------------------

void reshapeCB( int width, int height )

  Win.width = width;
  Win.height = height;


//----------------------------------------------------------------------------

XVisualInfo *chooseVisual( Display *display )

  int attribs [ 100 ] ;
  int n = 0 ;

  // Request 24-bit color with alpha
  attribs [n++] = GLX_RGBA ;
  attribs [n++] = GLX_RED_SIZE   ; attribs [n++] = 8 ;
  attribs [n++] = GLX_GREEN_SIZE ; attribs [n++] = 8 ;
  attribs [n++] = GLX_BLUE_SIZE  ; attribs [n++] = 8 ;

  // Request 24-bit depth buffer
  attribs [n++] = GLX_DEPTH_SIZE ; attribs [n++] = 24 ;

  // Request 4 multisamples per pixel
  attribs [n++] = GLX_SAMPLE_BUFFERS ; attribs [n++] = 1 ;
  attribs [n++] = GLX_SAMPLES        ; attribs [n++] = NUM_SAMPLES ;

  // Request double-buffering
  attribs [n++] = GLX_DOUBLEBUFFER ;
  attribs [n++] = None ;

  return glXChooseVisual( display, DefaultScreen( display ), attribs );


//----------------------------------------------------------------------------

void createWindow()

  // Init X and GLX
  Win.displayed = false;
  Display *display = Win.display = XOpenDisplay( ":0.0" );
  if ( !display )
    printf( "Cannot open X display\n" );

  int    screen   = DefaultScreen( display );
  Window root_win = RootWindow( display, screen );

  if ( !glXQueryExtension( display, 0, 0 ) )
    printf( "X Server doesn't support GLX extension\n" );

  // Pick a visual
  XVisualInfo *visinfo = chooseVisual( display );
  if ( visinfo == 0 )
    printf( "glXChooseVisual failed\n" );

  // Describe the visual
  printf( "Window Visual 0x%.2x\n", unsigned( visinfo->visualid ) );

  // Create the X window
  XSetWindowAttributes winAttr ;

  winAttr.event_mask = StructureNotifyMask | KeyPressMask ;
  winAttr.background_pixmap = None ;
  winAttr.background_pixel  = 0    ;
  winAttr.border_pixel      = 0    ;

  winAttr.colormap = XCreateColormap( display, root_win,
                                      visinfo->visual, AllocNone );

  unsigned int mask = CWBackPixmap | CWBorderPixel | CWColormap | CWEventMask;

  Window win = Win.win = XCreateWindow ( display, root_win, 
                                         WIN_XPOS, WIN_YPOS, 
                                         WIN_XRES, WIN_YRES, 0, 
                                         visinfo->depth, InputOutput, 
                                         visinfo->visual, mask, &winAttr ) ;

  XStoreName( Win.display, win, "My GLX Window");

  // Create an OpenGL context and attach it to our X window
  GLXContext context = glXCreateContext( display, visinfo, NULL, 1 ) ;

  if ( ! glXMakeCurrent( display, win, context ) )
    printf( "glXMakeCurrent failed.\n" );

  if ( ! glXIsDirect ( display, glXGetCurrentContext() ) )
    printf( "Indirect GLX rendering context obtained\n" );

  // Display the window
  XMapWindow( display, win );

  if ( ! glXMakeCurrent( display, win, context ) )
    printf( "glXMakeCurrent failed.\n" );

  check( "createWindow()" );

  printf( "Window Size    = %d x %d\n", WIN_XRES, WIN_YRES );
  printf( "Window Samples = %d\n", NUM_SAMPLES );


//----------------------------------------------------------------------------

void processXEvents( Atom wm_protocols, Atom wm_delete_window )

  bool setting_change = false;

  while ( XEventsQueued( Win.display, QueuedAfterFlush ) )
  
    XEvent    event;

    XNextEvent( Win.display, &event );

    if( event.xany.window != Win.win )
      continue;

    switch ( event.type )
    
      case MapNotify:
        
          Win.displayed = true;
          break;
        
      case ConfigureNotify:
        
          XConfigureEvent &cevent = event.xconfigure;
          reshapeCB( cevent.width, cevent.height );
          break;
        
      case KeyPress:
        
          char      chr;
          KeySym    symbol;
          XComposeStatus status;

          XLookupString( &event.xkey, &chr, 1, &symbol, &status );

          keyboardCB( symbol, chr, event.xkey.x, event.xkey.y,
                      setting_change );
          break;
        
      case ClientMessage:
        
          if ( event.xclient.message_type      == wm_protocols &&
               Atom( event.xclient.data.l[0] ) == wm_delete_window )
          
            //printf( "Received WM_DELETE_WINDOW\n" );
            exit(0);
          
          break;
        
    
  


//----------------------------------------------------------------------------

void mainLoop()

  // Register to receive window close events (the "X" window manager button)
  Atom wm_protocols     = XInternAtom( Win.display, "WM_PROTOCOLS"    , False);
  Atom wm_delete_window = XInternAtom( Win.display, "WM_DELETE_WINDOW", False);
  XSetWMProtocols( Win.display, Win.win, &wm_delete_window, True );

  while (1) 
  
    // Redraw window (after it's mapped)
    if ( Win.displayed )
      displayCB();

    // Update frame rate
    static timeval last_xcheck   = 0,0;
    struct timeval now;
    gettimeofday( &now, 0 );

    // Check X events every 1/10 second
    if ( elapsedMsec( last_xcheck, now ) > 100 )
    
      processXEvents( wm_protocols, wm_delete_window );
      last_xcheck = now;
    
  


//----------------------------------------------------------------------------

int main( int argc, char *argv[] )

  // Init globals
  Win.width = WIN_XRES, Win.height = WIN_YRES;

  // Create context and window
  createWindow();

  // Init OpenGL
  glViewport  ( 0, 0, Win.width, Win.height ); 
  glColorMask ( 1,1,1,1 );
  glClearColor( 0,0,1,1 );
  glClear     ( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );

  // Go
  printf( "Valid keys: Left, Right, k, ESC\n" );
  printf( "Press ESC to quit\n" );

  mainLoop();

  return 0;

【问题讨论】:

【参考方案1】:

这里有三个问题。

首先:您尚未设置 GL 视口(例如,使用 glFrustum()gluPerspective()),因此未正确设置透视矩阵以执行 3D 图形。因此,尝试在 3D 中绘制模型将无法正常工作。

第二:您在此处获得的代码是针对 X11 窗口系统而不是 Mac OS X 编写的。虽然它可以在 Mac OS 上编译和运行,但它会不能原生运行,也不会表现得特别好。你真的很想使用一些接口来与本机 Mac OS X GL 实现交互,例如 SDL、GLUT/GLEW 或 AGL。

(请记住,没有“没有库”就可以使用 GL。OpenGL 本身就是一个库,libX11 也是如此;使用额外的实用程序库来删除一些特定于操作系统的库并没有任何问题设置并使您的应用程序更易于移植。)

第三:您目前正在学习如何使用在 OpenGL 3.0 之前使用的 OpenGL 即时模式。现代 OpenGL(即 OpenGL 3.0 或更高版本以及 OpenGL ES)使用显着不同的 API,与立即模式几乎没有共同之处。我强烈建议您完全跳过立即模式;在这一点上,这是一项死技术。有很多关于 OpenGL 3+ 的优秀教程,包括:

http://www.opengl-tutorial.org/ http://www.arcsynthesis.org/gltut/ https://open.gl/

【讨论】:

如果您使用剪辑空间坐标,则不必使用glFrustum()gluPerspective() @duskwuff 谢谢。我可以像nehe.gamedev.net/tutorial/creating_an_opengl_window_(win32)/… 那样在mac os 系统中制作应用程序吗?没有任何库。 nehe.gamedev.net 已经过时了? 来自您链接的页面:“本教程于 2000 年 1 月完全重写。”所以是的,它难以置信地已经过时了。就库而言,请参阅我回答的第三段 - OpenGL 没有“没有任何库”这样的东西。 @duskwuff 谢谢。我在公司有测试任务,他们被要求只在 ios 平台上的 opengl 和 c++ 上做游戏小行星:) 谢谢你的链接,我会读这个

以上是关于Opengl macos失败的主要内容,如果未能解决你的问题,请参考以下文章

为啥禁用顶点属性数组零时OpenGL绘图失败?

Flutter - http.get 在 macos 构建目标上失败:连接失败

pyqtgraph 的 OpenGL 导入失败

macOS 10.13 安装Virtualbox失败

尝试运行 web 后颤振 macos 桌面构建失败

macOS 项目在运行时失败