OpenGL Grafiken flimmern (Vorsicht Noob)



  • hmm... ok
    Da muss wohl tiefgreifenderes Wissen her.
    Ich hab gedacht, dass ich erstmal das Grundgerüst mehr oder weniger zusammenkopiere und erstmal nach dem Motto "rumprobieren und dies und das nachschauen" rumbastle. So sollte es zumindest laut tutorial laufen. Klappte bis auf das Flimmern soweit ganz gut.
    Dann muss ich wohl "wieder" mit der trockenen Theorie anfangen und etwas über Back- und Frontbuffer nachlesen.

    Danke dir für den Hinweis. So weiß ich wenigstens genau wo es an Wissen mangelt.



  • Wenn du GLUT benutzt:
    einfach bei glutInitDisplayMode den Eintrag GLUT_DOUBLE "mitodern"



  • Ich versteh das mit dem Front- und Backbuffer nicht ganz. Dafür scheint die Funktion glDrawBuffer verantwortich zu sein und ich soll anscheinend bei jedem Zeichenvorgang erst in den Front- und beim nächsten in den Backbuffer zeichnen und immer hin und her schalten, aber ich kriegs nicht gebacken.

    Kannst du das kurz erläutern oder mir einen brauchbaren Link schicken. Aus der OpenGL Doku werde ich auch nicht schlau. Und ich verstehe auch nicht warum die Beispielprogramme, als Konsolenanwendung (main anstatt WinMain) programmiert werden. Für mich ergibt das keinen Sinn und verwirrt mich noch mehr.


  • Mod

    doublebuffer heisst nur dass man zwei buffer benutzt, dein einen bearbeitet man, und der andere dient als quelle fuer etwas anders. In deinem Speziellen fall ist es der Front und Backbuffer, der Frontbuffer ist der, der gerade angezeigt wird auf dem bildschirm, der backbuffer ist der, in den du reinzeichnest damit er, wenn du fertig bist, zum frontbuffer wird, der momentane frontbuffer wird dann zum backbuffer, den du erstmal loescht und dann etwas reinzeichnest.

    bei opengl macht man das mit glSwapBuffers.



  • glSwapBuffers kennt er nicht...
    Hat das nicht was mit GLUT zu tun?

    Wie gesagt: Neuland für mich.
    Könnte mir jemand das einfach einbauen, damit ich eine Grundlage zum rumprobieren und lernen hab?
    Ich denke mir, dass ihr da größeren Durchblick habt als ich^^
    Wäre echt nett, wenn sich jemand kurz die Zeit nimmt...

    Dnek mal, dass das mit diesen Funktionen zusammenhängt:

    int InitGL(GLvoid)
    {
        glShadeModel(GL_SMOOTH);
        glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
        glClearDepth(1.0f);
        glEnable(GL_DEPTH_TEST);
        glDepthFunc(GL_LEQUAL);
        glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
    
        return TRUE;
    }
    
    int DrawGLScene(GLvoid)
    {
        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
        glLoadIdentity();
        glTranslatef(-1.5f,0.0f,-6.0f);
    
        glBegin(GL_TRIANGLES);
        glColor3f(0.0f,0.0f,1.0f);
        glVertex3f( 0.0f, 1.0f, 0.0f);
        glVertex3f(-1.0f,-1.0f, 0.0f);
        glVertex3f( 1.0f,-1.0f, 0.0f);
        glEnd();
    
        return TRUE;
    }
    

    Falls benötigt, hier der ganze Code:

    #include <windows.h>
    #include <gl\glu.h>
    #include <gl\gl.h>
    #include <gl\glaux.h> 
    
    HGLRC     hRC =NULL;
    HDC       hDC =NULL;
    HWND      hWnd=NULL;
    HINSTANCE hInstance;
    
    bool keys[256];
    bool active=TRUE;
    bool fullscreen=TRUE;
    
    LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
    
    GLvoid ReSizeGLScene(GLsizei width, GLsizei height) 
    {
    	if (height==0)   
    		height=1;    
    
    	glViewport(0, 0, width, height);
    	glMatrixMode(GL_PROJECTION); 
    	glLoadIdentity(); 
    	gluPerspective(45.0f,(GLfloat)width/(GLfloat)height,0.1f,100.0f); 
    	glMatrixMode(GL_MODELVIEW); 
    	glLoadIdentity();
    }
    
    int InitGL(GLvoid)
    {
    	glShadeModel(GL_SMOOTH); 
    	glClearColor(0.0f, 0.0f, 0.0f, 0.0f); 
    	glClearDepth(1.0f);
    	glEnable(GL_DEPTH_TEST);
    	glDepthFunc(GL_LEQUAL);
    	glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
    
    	return TRUE;
    }
    
    int DrawGLScene(GLvoid) 
    {
    	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); 
    	glLoadIdentity(); 
    	glTranslatef(-1.5f,0.0f,-6.0f);
    
    	glBegin(GL_TRIANGLES);
        glColor3f(0.0f,0.0f,1.0f);
        glVertex3f( 0.0f, 1.0f, 0.0f);
        glVertex3f(-1.0f,-1.0f, 0.0f);
        glVertex3f( 1.0f,-1.0f, 0.0f);
    	glEnd();
    
    	return TRUE;
    }
    
    GLvoid KillGLWindow(GLvoid)
    {
    	if (fullscreen)
    	{
    		ChangeDisplaySettings(NULL,0);
    		ShowCursor(TRUE);
    	}
    
    	if (hRC)
    	{
    		if (!wglMakeCurrent(NULL,NULL))
    			MessageBox(NULL,"Entfernen des DC und RC fehlgeschlagen.","Fehler",MB_OK | MB_ICONINFORMATION);
    
    		if (!wglDeleteContext(hRC))
    			MessageBox(NULL,"Entfernen des RC fehlgeschlagen.","Fehler...",MB_OK | MB_ICONINFORMATION);
    
    		hRC=NULL;
        }
    
    	if (hDC && !ReleaseDC(hWnd,hDC)) 
    	{
    		MessageBox(NULL,"Freigabe des Device Context fehlgeschlagen.","Fehler",MB_OK | MB_ICONINFORMATION);
    		hDC=NULL;
    	}
    
    	if (hWnd && !DestroyWindow(hWnd)) 
    	{
    		MessageBox(NULL,"Konnte hWnd nicht löschen.","SHUTDOWN ERROR",MB_OK | MB_ICONINFORMATION);
    		hWnd=NULL;
    	}
    
    	if (!UnregisterClass("OpenGL",hInstance)) 
    	{
    		MessageBox(NULL,"Konnte Klasse nicht entfernen.","SHUTDOWN ERROR",MB_OK | MB_ICONINFORMATION);
    		hInstance=NULL;
    	}
    }
    
    BOOL CreateGLWindow(char* title, int width, int height, 
                        int bits, bool fullscreenflag)
    {
    	GLuint PixelFormat;
    	WNDCLASS wc;
    	DWORD dwExStyle;
    	DWORD dwStyle;
    	RECT WindowRect;
    	WindowRect.left=(long)0;
    	WindowRect.right=(long)width;
    	WindowRect.top=(long)0;
    	WindowRect.bottom=(long)height;
    	fullscreen=fullscreenflag;
    	hInstance = GetModuleHandle(NULL);
    	wc.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC;
    	wc.lpfnWndProc = (WNDPROC) WndProc; 
    	wc.cbClsExtra = 0;
    	wc.cbWndExtra = 0;
    	wc.hInstance = hInstance;
    	wc.hIcon = LoadIcon(NULL, IDI_WINLOGO);
    	wc.hCursor = LoadCursor(NULL, IDC_ARROW);
    	wc.hbrBackground = NULL;
    	wc.lpszMenuName = NULL;
    	wc.lpszClassName = "OpenGL";
    
    	if (!RegisterClass(&wc))
    	{
    		MessageBox(NULL,"Konnte die Fensterklasse nicht registrieren.","ERROR",MB_OK|MB_ICONEXCLAMATION);
    
    		return FALSE;
    	}
    
    	if (fullscreen)
    	{
    		DEVMODE dmScreenSettings;
    		memset(&dmScreenSettings,0,sizeof(dmScreenSettings));
    		dmScreenSettings.dmSize=sizeof(dmScreenSettings);
    		dmScreenSettings.dmPelsWidth = width;
    		dmScreenSettings.dmPelsHeight = height;
    		dmScreenSettings.dmBitsPerPel = bits; 
    		dmScreenSettings.dmFields=DM_BITSPERPEL|DM_PELSWIDTH|DM_PELSHEIGHT; 
    
    		if (ChangeDisplaySettings(&dmScreenSettings,CDS_FULLSCREEN)!=DISP_CHANGE_SUCCESSFUL)    
    		{
    			if (MessageBox(NULL,"Der gewünschte Vollbildmodus wird nicht unterstützt, soll stattdessen im Fenstermodus ausgegeben werden?",
    			    "OpenGL",MB_YESNO|MB_ICONEXCLAMATION)==IDYES)
    				fullscreen=FALSE; 
    
    			else
    				return FALSE;
    		}
    	}
    
    	if (fullscreen) 
    	{
    		dwExStyle=WS_EX_APPWINDOW;
    		dwStyle=WS_POPUP;
    		ShowCursor(FALSE);
    	}
    	else
    	{
    		dwExStyle=WS_EX_APPWINDOW | WS_EX_WINDOWEDGE;
    		dwStyle=WS_OVERLAPPEDWINDOW; 		
    	}
    
    	AdjustWindowRectEx(&WindowRect, dwStyle, FALSE, dwExStyle); 
    
    	if (!(hWnd=CreateWindowEx(	dwExStyle,
    								"OpenGL",
    								title,
    								WS_CLIPSIBLINGS | WS_CLIPCHILDREN | dwStyle,
    								0, 0,
    								WindowRect.right-WindowRect.left, 
    								WindowRect.bottom-WindowRect.top,
    								NULL,NULL,hInstance,NULL )) )
    
    	{
    		KillGLWindow();
    		MessageBox(NULL,"Fenster konnte nicht erstellt werden.","ERROR",MB_OK|MB_ICONEXCLAMATION);
    
    		return FALSE; 
    	}
    
    	static PIXELFORMATDESCRIPTOR pfd= 
    	{
    		sizeof(PIXELFORMATDESCRIPTOR), 
    		PFD_DRAW_TO_WINDOW | 
    		PFD_SUPPORT_OPENGL | 
    		PFD_DOUBLEBUFFER, 
    		PFD_TYPE_RGBA, 
    		bits,
    		0, 0, 0, 0, 0, 0,
    		0,
    		0,
    		0,
    		0, 0, 0, 0,
    		16,
    		0,
    		0,
    		PFD_MAIN_PLANE,
    		0,
    		0, 0, 0
    	};
    
    	if (!(hDC=GetDC(hWnd)))
    	{
    		KillGLWindow(); 
    		MessageBox(NULL,"Konnte keinen DC erstellen.","ERROR",MB_OK|MB_ICONEXCLAMATION);
    		return FALSE;
    	}
    
    	if (!(PixelFormat=ChoosePixelFormat(hDC,&pfd))) 
    	{ 
    		KillGLWindow();
    		MessageBox(NULL,"Konnte kein passendes Pixelformat finden.","ERROR",MB_OK|MB_ICONEXCLAMATION);
    		return FALSE; 
    	}
    
    	if(!SetPixelFormat(hDC,PixelFormat,&pfd))
        {
    		KillGLWindow();
    		MessageBox(NULL,"Konnte Pixelformat nicht setzen.","ERROR",MB_OK|MB_ICONEXCLAMATION);
    		return FALSE;
    	}
    
    	if (!(hRC=wglCreateContext(hDC)))
        {
          KillGLWindow();
          MessageBox(NULL,"Konnte keinen Rendering Context bekommen.","Fehler",MB_OK|MB_ICONEXCLAMATION);
    	  return FALSE;
        }
    
    	if(!wglMakeCurrent(hDC,hRC))
    	{
    		KillGLWindow();
    		MessageBox(NULL,"Konnte den Rendering Context nmicht aktivieren.","Fehler",MB_OK|MB_ICONEXCLAMATION);
    		return FALSE;
    	}
    
    	ShowWindow(hWnd,SW_SHOW);
    	SetForegroundWindow(hWnd);
    	SetFocus(hWnd);
    
    	ReSizeGLScene(width, height);
    
    	if (!InitGL())
    	{
    		KillGLWindow();
    		MessageBox(NULL,"Initialisierung fehlgeschlagen.","Fehler",MB_OK|MB_ICONEXCLAMATION);
    		return FALSE;
    	}
    
    	return TRUE; 
    }
    
    LRESULT CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
    {
    
    	switch (uMsg)
    	{
        case WM_ACTIVATE:
    		{
    			if (!HIWORD(wParam))
    				active=TRUE;
    
    			else
    				active=FALSE;   
    
    			return 0;
    		}
    	case WM_SYSCOMMAND:
    		{
    			switch (wParam)
    			{
    			case SC_SCREENSAVE: 
    			case SC_MONITORPOWER: 
    				return 0; 
    			}
    			break;
    		}
        case WM_CLOSE:
    		{
    			PostQuitMessage(0); 
    			return 0;
    		}
        case WM_KEYDOWN:
    		{
    			keys[wParam] = TRUE; 
    			return 0;
    		}
        case WM_KEYUP:
    		{
    			keys[wParam] = FALSE; 
    			return 0;
    		}
        case WM_SIZE:
    		{
    			ReSizeGLScene(LOWORD(lParam),HIWORD(lParam)); 
    			return 0;
    		}
    	}
    
    	return DefWindowProc(hWnd,uMsg,wParam,lParam);
    }
    
    int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, 
                       LPSTR lpCmdLine, int nCmdShow)
    {
    	MSG msg;
    	BOOL done=FALSE;
    
    	if (MessageBox(NULL,"Soll im Vollbildmodus gestartet werden?","Vollbilmodus gewünscht?",MB_YESNO|MB_ICONQUESTION)==IDNO)
    		fullscreen=FALSE;
    
    	if (!CreateGLWindow("Opengl Tutorial 2 - Farben und Formen - www.codeworx.org",640,480,16,fullscreen))
    		return 0;
    
    	while(!done)
    	{
    		if (PeekMessage(&msg,NULL,0,0,PM_REMOVE)) 
    		{
    			if (msg.message==WM_QUIT) 
    				done=TRUE;
    
    			else 
    			{
    				TranslateMessage(&msg);
    				DispatchMessage(&msg); 
    			}
    		}
    
    		else
    		{
    			if (active)
    			{
    				if (keys[VK_ESCAPE])
    					done=TRUE;
    
    				else
    				{
    					DrawGLScene();
    					SwapBuffers(hDC);
    				}
    			}
    
    			if (keys[VK_F1])
    			{
    				keys[VK_F1]=FALSE;
    				KillGLWindow();
    				fullscreen=!fullscreen; 
    
    				if (!CreateGLWindow("Lektion 1",640,480,16,fullscreen))    
    					return 0;
    			}
    		}
    	}
    
    	KillGLWindow();
    	return (msg.wParam);
    }
    


  • Soweit ich weiss, gibts auch kein glSwaBuffers(),
    versuch mal SwapBuffers()



  • Der Befehl heisst glutSwapBuffers und gehört zum GLUT package!



  • Ich hab jetzt die Fuktion SwapBuffers( hDC ); ans Ende der DrawGLScene(GLvoid) Fuktion gepackt, aber es ändert nichts.

    Habe jetzt einfach mal gesucht und bin darauf gestoßen:
    http://www.nullterminator.net/opengl32.html
    Unten ist ein Screenshot von dem, was man sehen sollte und wenn ich in den Code schaue, sollte sich dieses Dreieck nicht drehen, aber bei mir dreht es sich schnell und ist verzerrt. Wenn ich die Maus nicht bewege, ist das drehende Dreieck bei mir weiß und hat bunte Ränder und wenn ich sie bewege, dann drehen sich ein blaues, rotes und ein grünes Dreick versetzt und in der Mitte, wo sie sich überschneiden, ist es weiß. Ist das ein Treiberproblem?! Ich spiele auch OpenGL-Spiele und da klappt das ja wunderbar...



  • du hast einen parameter vergessen - dementsprechend sind alle flags falsch:

    static PIXELFORMATDESCRIPTOR pfd=
        {
            sizeof(PIXELFORMATDESCRIPTOR),
    // ** hier fehlt "WORD nVersion"
            PFD_DRAW_TO_WINDOW |
            PFD_SUPPORT_OPENGL |
            PFD_DOUBLEBUFFER,
            PFD_TYPE_RGBA,
            bits,
            0, 0, 0, 0, 0, 0,
            0,
            0,
            0,
            0, 0, 0, 0,
            16,
            0,
            0,
            PFD_MAIN_PLANE,
            0,
            0, 0, 0
        };
    


  • Oh mein Gott, ich danke dir.
    Ich weiß zwar nicht, warum das Andere (drehendes Dreieck) nicht geht, aber jetzt habe ich endlich ein funktionierendes Grundgerüst dessen Einzelne Befehle und Funktionen ich nach und nach kennenlernen kann.

    Vielen, vielen Dank!


Anmelden zum Antworten