glClear(GL_COLOR_BUFFER_BIT) setzt den Hintergrund nicht!?



  • Hallo

    Irgendwie ist mir das recht peinlich hier so eine grundlegende Frage zu stellen, aber ich bin mir wirklich nicht mehr sicher, ob das Problem bei mir liegt, oder bei der Vorlage die ich übernommen habe (und nicht so ganz verstehe, aber dass kann ja noch werden).

    Eigentlich wollte ich nur mit

    glClearColor(1.0, 1.0, 1.0, 0.0);		// weisser Hintergrund
    	glClear(GL_COLOR_BUFFER_BIT);			// Hintergrund zeichnen
    
    	glBegin(GL_QUADS);  //wir wollen ein Viereck zeichnen
    		glColor3f(1,0,0); //rote Farbe
    		glVertex3f( 1 , 1, -6);
    		glColor3f(0,1,0); //grüne Farbe
    		glVertex3f( -1 , 1, -6);
    		glColor3f(1,1,0); //gelbe Farbe
    		glVertex3f( -1 , -1, -6);
    		glColor3f(0,0,1); //blaue Farbe
    		glVertex3f( 1 , -1, -6);
    	glEnd();
    

    den Hintergrund auf weis setzen und danach ein Quadrat zeichnen (ja, Anfänger!), aber es erscheint nach wie vor alles in schwarz. Wenn ich das Quadrat nicht dargestellt bekomme wäre das ja noch verständlich, und ich müsste an der viewing transformation herumbasteln, aber wenn's schon am Hintergrund scheitert...

    Zu meiner Verteidigung, ich habe mal mit Delphi und OpenGL was gemacht (simpel) was funktioniert hat, also so richtig dumm™ kann ich nun doch nicht sein (oder doch?)

    Könnte ev. in der Initialisierung was falsch laufen?

    #include <windows.h>
    #include <gl/gl.h>
    
    // Function Declarations
    LRESULT CALLBACK 	WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam);
    VOID 				EnableOpenGL(HWND hWnd, HDC * hDC, HGLRC * hRC);
    VOID 				DisableOpenGL(HWND hWnd, HDC hDC, HGLRC hRC);
    
    /* ------ Main Function ------ */
    int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
                       LPSTR lpCmdLine, int iCmdShow) 
    {
      WNDCLASS wc;
      HWND hWnd;
      HDC hDC;
      HGLRC hRC;    
      MSG msg;
      BOOL bQuit = FALSE;
      float theta = 0.0f;
    
      // register window class
      wc.style = CS_OWNDC;
      wc.lpfnWndProc = WndProc;
      wc.cbClsExtra = 0;
      wc.cbWndExtra = 0;
      wc.hInstance = hInstance;
      wc.hIcon = LoadIcon( NULL, IDI_APPLICATION );
      wc.hCursor = LoadCursor( NULL, IDC_ARROW );
      wc.hbrBackground = (HBRUSH)GetStockObject( BLACK_BRUSH );
      wc.lpszMenuName = NULL;
      wc.lpszClassName = "GLSample";
      RegisterClass( &wc );
    
      // create main window
      hWnd = CreateWindow( 
      		"GLSample", "OpenGL Sample", 
      		WS_CAPTION | WS_POPUPWINDOW | WS_VISIBLE,
      		0, 0, 256, 256,
      		NULL, NULL, hInstance, NULL);
    
      // enable OpenGL for the window
      EnableOpenGL( hWnd, &hDC, &hRC );
    
    	/* ----- Mein "Code" ----- */
    	glClearColor(1.0, 1.0, 1.0, 0.0);		// weisser Hintergrund
    	glClear(GL_COLOR_BUFFER_BIT);			// Hintergrund zeichnen
    
    	glBegin(GL_QUADS);  //wir wollen ein Viereck zeichnen
    		glColor3f(1,0,0); //rote Farbe
    		glVertex3f( 1 , 1, -6);
    		glColor3f(0,1,0); //grüne Farbe
    		glVertex3f( -1 , 1, -6);
    		glColor3f(1,1,0); //gelbe Farbe
    		glVertex3f( -1 , -1, -6);
    		glColor3f(0,0,1); //blaue Farbe
    		glVertex3f( 1 , -1, -6);
    	glEnd();
    
      // program main loop
      while (!bQuit) 
        {
          // check for messages
          if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) 
            {
              // handle or dispatch messages
              if (msg.message == WM_QUIT) 
                {
                  bQuit = TRUE;
                } 
              else 
                {
                  TranslateMessage(&msg);
                  DispatchMessage(&msg);
                }
    
             } 
          else 
            {
    			/* OpenGL Code */
    
            }
      }
      // shutdown OpenGL
      DisableOpenGL( hWnd, hDC, hRC );
      // destroy the window explicitly
      DestroyWindow( hWnd );
      return msg.wParam;
    }
    
    // Window Procedure
    
    LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
    {
      switch (message) 
        {
          case WM_CREATE:
            return 0;
    
          case WM_CLOSE:
            PostQuitMessage( 0 );
            return 0;
    
          case WM_DESTROY:
            return 0;
    
          case WM_KEYDOWN:
            switch (wParam) 
            {
              case VK_ESCAPE:
                PostQuitMessage( 0 );
                return 0;
            }
            return 0;
    
            default:
              return DefWindowProc(hWnd, message, wParam, lParam);
      }
    }
    
    // Enable OpenGL
    
    VOID EnableOpenGL( HWND hWnd, HDC * hDC, HGLRC * hRC )
    {
      PIXELFORMATDESCRIPTOR pfd;
      int iFormat;
    
      // get the device context (DC)
      *hDC = GetDC( hWnd );
    
      // set the pixel format for the DC
      ZeroMemory( &pfd, sizeof( pfd ) );
      pfd.nSize = sizeof( pfd );
      pfd.nVersion = 1;
      pfd.dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER;
      pfd.iPixelType = PFD_TYPE_RGBA;
      pfd.cColorBits = 24;
      pfd.cDepthBits = 16;
      pfd.iLayerType = PFD_MAIN_PLANE;
      iFormat = ChoosePixelFormat( *hDC, &pfd );
      SetPixelFormat( *hDC, iFormat, &pfd );
    
      // create and enable the render context (RC)
      *hRC = wglCreateContext( *hDC );
      wglMakeCurrent( *hDC, *hRC );
    }
    
    // Disable OpenGL
    
    VOID DisableOpenGL( HWND hWnd, HDC hDC, HGLRC hRC )
    {
      wglMakeCurrent( NULL, NULL );
      wglDeleteContext( hRC );
      ReleaseDC( hWnd, hDC );
    }
    

    In der Hoffnung, dass mir jemand den Fehler sagt, bevor ich auseinander genommen werde...

    Grüsse von einem deprimierten gierigen Affe

    ps. Falls sich jemand fragt, was der Depp denn mit OpenGL anstellen will, ich muss später mal in der Lage sein, einen seltsamen Attraktor darzustellen.



  • Jo, da wäre jetzt eine Löschfunktion hilfreich...

    Wie auch immer, vieleicht hat mal eine andere Pfeiffe das selbe Problem:

    pfd.dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER;
    

    Da der Device Context doppelt gepuffert ist wird alles, was gezeichnet wird erst mal in einen nicht sichtbaren Speicherbereich geschrieben:

    Double Buffer

    Since we're using a double buffered DC, anything we draw to the DC actually goes to a non-visible space in memory. This happens when you specify the PFD_DOUBLEBUFFER flag in the pixel format above. It isn't displayed in the window until we tell it to. This is very useful for rendering the scene off-screen and displaying the final image in one shot. This can be done in one simple function call to SwapBuffers, simply supply the DC in question.

    SwapBuffers( hDC );

    And viola! We have our final image displayed.

    Somit bringt

    glClearColor(1.0, 0.0, 0.0, 0.0);		// weisser Hintergrund
    	glClear(GL_COLOR_BUFFER_BIT);			// Hintergrund zeichnen
    
    	glBegin(GL_QUADS);  //wir wollen ein Viereck zeichnen
    		glColor3f(1,0,0); //rote Farbe
    		glVertex3f( 1 , 1, -6);
    		glColor3f(0,1,0); //grüne Farbe
    		glVertex3f( -1 , 1, -6);
    		glColor3f(1,1,0); //gelbe Farbe
    		glVertex3f( -1 , -1, -6);
    		glColor3f(0,0,1); //blaue Farbe
    		glVertex3f( 1 , -1, -6);
    	glEnd();
    
    	SwapBuffers( hDC );
    

    die gewünschte Ausgabe.

    Manchmal sollte man mehr als nur ein Tutorial zu hilfe nehmen 😉

    ps. Das hat sich jetzt überschnitten, nicht dass ich dich beleidigen wollte 🤡



  • Wenn Du schon was funktionierendes in Delphi hast, versuch' doch Deinen Code da mal!

    Hier prüfst Du ja überhaupt nicht auf Fehler, d.h. Du weißt gar nicht, ob der OpenGL RenderContext wirklich gesetzt wurde etc. pp. Also mal mit dem Debugger checken bzw. loggen.


  • Mod

    ja, manchmal ist es nur ne zeile... 😉



  • Zum einen fehlt wie schon erwaehnt die sawpbuffer funktion, wenn man doublebuffert. Zum zweiten ist der draw code dort wo er ist etwas unangebracht.
    wenn mans eilig hat schraubt man eine paint/swap funtion in der endless loop.
    Ist man gemuetlich drauf kann mans auch mit WM_PAINT machen.


Anmelden zum Antworten