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.