OpenGL: Torus



  • Hi,

    ich habe folgenden Code, der größtenteils aus einem Tutorial ist, nur die DrawTorus Funktion ist von mir (eigentlich auch nur von einer anderen Sprache übersetzt)

    // Includes
    #include <windows.h>
    #include <math.h>
    #include <gl\gl.h>
    #include <gl\glu.h>
    #include <gl\glaux.h>
    
    // Globale Variablen für das Windows Fenster
    HGLRC hRC = NULL;
    HDC hDC = NULL;
    HWND hWnd = NULL;
    HINSTANCE hInstance;
    
    // Sonstige Globale Variablen
    bool keys[256];
    bool active = true;
    bool fullscreen = true;
    
    GLfloat rtri = 0.0f;
    GLfloat rquad = 0.0f;
    
    // Prototypen
    int InitGL(GLvoid);
    GLvoid ReSizeGLScene(GLsizei width, GLsizei height);
    int DrawGLScene(GLvoid);
    bool CreateGLWindow(char* title, int width, int height, int bits, bool fullscreenflag);
    GLvoid KillGLWindow(GLvoid);
    LRESULT CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
    void DrawTorus(GLfloat x,GLfloat  y,GLfloat z, GLfloat rot, GLfloat yaw,GLfloat  pitch,GLfloat roll,GLfloat r,GLfloat  g,GLfloat  b, GLfloat Radius1=1.0f, GLfloat Radius2=0.5f, int Segments1=10, int Segments2=10);
    
    // WinMAIN Funktion
    int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
    {
    	// Lokale Variablen
    	MSG msg;
    	BOOL done = false;
    
    	// Fenster oder Vollbildmodus?
    	if(MessageBox(NULL, "Would You Like To Run In Windowed Mode?", "Start Windowed?", MB_YESNO | MB_ICONQUESTION) == IDYES)
    	{
    		fullscreen = false;
    	}
    
    	// OpenGL Initialisieren Fehlgeschlagen
    	if(!CreateGLWindow("OpenGL!", 800, 600, 16, fullscreen))
    	{
    		return 0;
    	}
    
    	// Solange nicht abgebrochen wird
    	while(!done)
    	{
    		if( PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
    		{
    			if(msg.message==WM_QUIT)
    			{
    				done=true;
    			}
    			else
    			{
    				// Messages übersetzen und weiterleiten
    				TranslateMessage(&msg);
    				DispatchMessage(&msg);
    			}
    		}
    		else
    		{
    			// Wenn unser Fenster den Fokus hat
    			if(active)
    			{
    				// Escape wurde gedrückt
    				if(keys[VK_ESCAPE])
    				{
    					done = true;
    				}
    				// 3D Szenerie zeichnen und Buffer tauschen
    				else
    				{
    					DrawGLScene();
    					SwapBuffers(hDC);
    				}
    			}
    			// bei Tastendruck auf F1 zwischen Vollbild und Fenstermodus wechseln
    			if(keys[VK_F1])
    			{
    				keys[VK_F1]=false;
    				KillGLWindow();
    				fullscreen=!fullscreen;
    				if(!CreateGLWindow("OpenGL!", 800, 600, 16, fullscreen))
    				{
    					return 0;
    				}
    			}
    		}
    	}
    
    	// Fenster freigeben
    	KillGLWindow();
    
    	return (msg.wParam);
    }
    
    // Fensterprozedur
    LRESULT CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
    {
    	// Messages verarbeiten
    	switch (uMsg)
    	{
    	// Aktivierung bzw. Deaktivierung unseres Fenster
    	case WM_ACTIVATE:
    		{
    			if(!HIWORD(wParam))
    			{
    				active = true;
    			}
    			else
    			{
    				active = false;
    			}
    			return 0;
    		}
    	// Wenn Windows Bildschirmschon oder Monitorstandby aktivieren will, das verhindern
    	case WM_SYSCOMMAND:
    		{
    			switch (wParam)
    			{
    			case SC_SCREENSAVE:
    			case SC_MONITORPOWER:
    				return 0;
    			}
    			break;
    		}
    	// Wenn Fenster geschlossen werden soll
    	case WM_CLOSE:
    		{
    			PostQuitMessage(0);
    			return(0);
    		}
    	// bei Tastendruck key Array anpassen
    	case WM_KEYDOWN:
    		{
    			keys[wParam] = true;
    			return 0;
    		}
    	case WM_KEYUP:
    		{
    			keys[wParam] = false;
    			return 0;
    		}
    	// bei verändern der Fenstergröße OpenGL größe anpassen
    	case WM_SIZE:
    		{
    			ReSizeGLScene(LOWORD(lParam), HIWORD(lParam));
    			return 0;
    		}
    	}
    
    	// Sonstige Messages weiterleiten
    	return DefWindowProc(hWnd, uMsg, wParam, lParam);
    }
    
    // OpenGL Fenster erstellen
    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, "Failed To Register The Window Class.", "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, "The Requested Fullscreen Mode Is Not Supportet By\nYour Cideo Card. Use Windowed Mode Instead?", "OpenGL", MB_YESNO | MB_ICONEXCLAMATION) == IDYES)
    			{
    				fullscreen = false;
    			}
    			else
    			{
    				MessageBox(NULL, "Program Will Now Close.", "ERROR", MB_OK | MB_ICONSTOP);
    				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, "Window Creation Error.", "ERROR", MB_OK | MB_ICONEXCLAMATION);
    		return false;
    	}
    
    	static PIXELFORMATDESCRIPTOR pfd =
    	{
    		sizeof(PIXELFORMATDESCRIPTOR),
    			1,
    			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, "Can't Create A GL Device Context.", "ERROR", MB_OK | MB_ICONEXCLAMATION);
    		return false;
    	}
    
    	if(!(PixelFormat = ChoosePixelFormat(hDC, &pfd)))
    	{
    		KillGLWindow();
    		MessageBox(NULL, "Can't Find A Suitable PixelFormat.", "ERROR", MB_OK | MB_ICONEXCLAMATION);
    		return false;
    	}
    
    	if(!SetPixelFormat(hDC, PixelFormat, &pfd))
    	{
    		KillGLWindow();
    		MessageBox(NULL, "Can't Set The PixelFormat.", "ERROR", MB_OK | MB_ICONEXCLAMATION);
    	}
    
    	if(!(hRC = wglCreateContext(hDC)))
    	{
    		KillGLWindow();
    		MessageBox(NULL, "Can't Create A GL Rendering Context.", "ERROR", MB_OK | MB_ICONEXCLAMATION);
    		return false;
    	}
    
    	if(!wglMakeCurrent(hDC, hRC))
    	{
    		KillGLWindow();
    		MessageBox(NULL, "Can't Activate The GL Rendering Context.", "ERROR", MB_OK | MB_ICONEXCLAMATION);
    		return false;
    	}
    
    	ShowWindow(hWnd, SW_SHOW);
    	SetForegroundWindow(hWnd);
    	SetFocus(hWnd);
    	ReSizeGLScene(width, height);
    
    	if(!InitGL())
    	{
    		KillGLWindow();
    		MessageBox(NULL, "Initialization Failed.", "ERROR", MB_OK | MB_ICONEXCLAMATION);
    		return false;
    	}
    
    	return true;
    }
    
    GLvoid KillGLWindow(GLvoid)
    {
    	if(fullscreen)
    	{
    		ChangeDisplaySettings(NULL, 0);
    		ShowCursor(true);
    	}
    
    	if(hRC)
    	{
    
    		if(!wglMakeCurrent(NULL, NULL))
    		{
    			MessageBox(NULL, "Release Of DC And RC Failed.", "ShutDown ERROR", MB_OK | MB_ICONINFORMATION);
    		}
    
    		if(!wglDeleteContext(hRC))
    		{
    			MessageBox(NULL, "Release Rendering Context Failed.", "ShutDown ERROR", MB_OK | MB_ICONINFORMATION);
    		}
    
    		hRC = NULL;
    	}
    
    	if(hDC && !ReleaseDC(hWnd, hDC))
    	{
    		MessageBox(NULL, "Release Device Context Failed.", "ShutDown ERROR", MB_OK | MB_ICONINFORMATION);
    		hDC = NULL;
    	}
    
    	if(hWnd && !DestroyWindow(hWnd))
    	{
    		MessageBox(NULL, "Could Not Release hWnd.", "ShutDown ERROR", MB_OK | MB_ICONINFORMATION);
    		hWnd = NULL;
    	}
    
    	if(!UnregisterClass("OpenGL", hInstance))
    	{
    		MessageBox(NULL, "Could Not Unregister Class.", "ShutDown ERROR", MB_OK | MB_ICONINFORMATION);
    		hInstance = NULL;
    	}
    }
    
    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)
    {
    	static DWORD lasttime;
    	static GLfloat rotation;
    
    	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    
    	DrawTorus(0.0f, 0.0f, -10.0f, rotation, 1.0f, 2.0f, 3.0f, 0.0f, 0.0f, 1.0f, 1.5f, 0.5f, 80, 12);
    
    	if(((GetTickCount()-lasttime) > 30) && (keys[VK_F2] == false))
    	{
    		rotation += 3.0f;
    
    		lasttime = GetTickCount();
    	}
    
    	return true;
    }
    
    void DrawTorus(GLfloat x,GLfloat  y,GLfloat z, GLfloat rot, GLfloat yaw,GLfloat  pitch,GLfloat roll,GLfloat r,GLfloat  g,GLfloat  b, GLfloat Radius1, GLfloat Radius2, int Segments1, int Segments2)
    {
    	// Lokale Variablen
    	GLfloat XPos1, YPos1, XPos2, YPos2, X1, Y1, Z1, X2, Y2, Z2, X3, Y3, Z3, X4, Y4, Z4;
    	GLfloat i, j;
    
    	glLoadIdentity();
    
    	glTranslatef(x, y, z);
    
    	glRotatef(rot, yaw, pitch, roll);
    
    	glBegin(GL_TRIANGLES);
    		glColor3f	(r, g, b);
    
    		i = 0;
    		do
    		{
    			i=i+(360.0f / Segments2);
    			XPos1 = (GLfloat)cos(((GLfloat)i)) * (GLfloat)Radius2 + (GLfloat)Radius1;
    			YPos1 = (GLfloat)sin(((GLfloat)i)) * (GLfloat)Radius2 + (GLfloat)Radius1;
    			XPos2 = (GLfloat)cos(((GLfloat)i) + (360.0f / Segments2)) * (GLfloat)Radius2 + (GLfloat)Radius1;
    			YPos2 = (GLfloat)sin(((GLfloat)i) + (360.0f / Segments2)) * (GLfloat)Radius2 + (GLfloat)Radius1;
    			j = 0;
    			do
    			{
    				j = j+(360.0f / Segments1);
    				X1 = (GLfloat)cos(j) * XPos1;
    				Y1 = YPos1;
    				Z1 = (GLfloat)sin(j) * XPos1;
    				X2 = (GLfloat)cos(j + (360.0f / Segments1)) * XPos1;
    				Y2 = YPos1;
    				Z2 = (GLfloat)sin(j + (360.0f / Segments1)) * XPos1;
    				X3 = (GLfloat)cos(j) * XPos2;
    				Y3 = YPos2;
    				Z3 = (GLfloat)sin(j) * XPos2;
    				X4 = (GLfloat)cos(j + (360.0f / Segments1)) * XPos2;
    				Y4 = YPos2;
    				Z4 = (GLfloat)sin(j + (360.0f / Segments1)) * XPos2;
    
    				glVertex3f	(X3,Y3,Z3);
    				glVertex3f	(X2,Y2,Z2);
    				glVertex3f	(X1,Y1,Z1);
    
    				glVertex3f	(X4,Y4,Z4);
    				glVertex3f	(X2,Y2,Z2);
    				glVertex3f	(X3,Y3,Z3);
    			} while(j <= (360.0f - (360.0f / Segments1)));
    		} while( i <= (360.0f - (360.0f / Segments2)));
    	glEnd();
    }
    

    Allerdings schaut der Torus hier in C++ OGL nicht so schön aus, wie der Donut in der anderen Sprache 😞

    Weis vielleicht wer warum?

    Achja und wegen Codestil beschwert euch bitte beim Tut herausgeber 😃

    Mfg Xenon



  • hmmm

    vieleicht könnte es ja an der Tatsache liegen das du keine Lichtquellen verwendest.

    gruß
    de_Bert



  • Boah ich dachte es antwortet keiner mehr 😃

    Auf jeden Fall: An der Lichtquelle liegts nicht, denn der Torus sieht einfach aus wie ein Zahnrad und nicht wie ein Donut.

    Mir geht es auch ehrlichgesagt nicht direkt um diesen Code hier. Von mir aus könnt ihr mir auch einen anderen geben, oder wenigstens die korrekten Formeln für das Ding.

    Mfg Xenon



  • hi

    ????????

    ich versuche mal den Code zu testen. Mal schauen was da raus kommt

    gruß
    de_Bert



  • hi

    musst bei dem Befehl

    DrawTorus(0.0f, 0.0f, -10.0f, rotation, 1.0f, 2.0f, 3.0f, 0.0f, 0.0f, 1.0f, 1.5f, 0.5f, 80, 12);
    

    die zwei letzten Parameter erhöhen. z.B. 100, 100. Dann wird die Sache ein bissel runder. Aber solche Berechnungen führt man vorher durch und nicht während dem Rendern.

    gruß
    de_Bert



  • Ich habs gemerkt das er da ein wenig runder wird, aber wie du gesagt hast das is zu langsam 😃

    Naja war nur ein Versuch.

    Will sowieso DX lernen, mein Buch is hoffentlich bald da.


Anmelden zum Antworten