// opengl_zbufor.cpp : Defines the entry point for the console application. // #include "stdafx.h" /* (c) Janusz Ganczarski http://www.januszg.hg.pl JanuszG@enter.net.pl */ #include <GL/glut.h> #include <stdlib.h> #include "colors.h" // rozmiary bryły obcinania const GLdouble left = -2.0; const GLdouble right = 2.0; const GLdouble bottom = -2.0; const GLdouble top = 2.0; const GLdouble near_ = 3.0; const GLdouble far_ = 7.0; // stałe do obsługi menu podręcznego enum { CUTTING_PLANE, // płaszczyzna przekroju POLYGON_OFFSET, // przesunięcie wartości głębi EXIT // wyjście }; // kąt obrotu kuli GLfloat angle = 0.0; // kąty obrotu sześcianu GLfloat rotatex = 0.0; GLfloat rotatey = 0.0; // wskaźnik rysowania płaszczyzna przekroju bool cutting_plane = true; // wskaźnik przesunięcia wartości głębi bool polygon_offset = true; // wskaźnik naciśnięcia lewego przycisku myszki int button_state = GLUT_UP; // położenie kursora myszki int button_x, button_y; // funkcja generująca scenę 3D void Display() { // kolor tła - zawartość bufora koloru glClearColor(1.0, 1.0, 1.0, 1.0); // czyszczenie bufora koloru i bufora głębokości glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // wybór macierzy modelowania glMatrixMode(GL_MODELVIEW); // macierz modelowania = macierz jednostkowa glLoadIdentity(); // przesunięcie układu współrzędnych sześcianu do środka bryły odcinania glTranslatef(0, 0, -(near_ + far_) / 2); // obroty sześcianu glRotatef(rotatex, 1.0, 0, 0); glRotatef(rotatey, 0, 1.0, 0); // niewielkie powiększenie sześcianu glScalef(1.15, 1.15, 1.15); // włączenie testu bufora głębokości glEnable(GL_DEPTH_TEST); // najpierw rysujemy kulę obracającą się wewnątrz sześcianu; // z uwagi na celowy brak efektów oświetlenia, obrót kuli // podkreśla druga kula w wersji "szkieletowej" glPushMatrix(); angle += 0.2; glRotatef(angle, 1.0, 1.0, 0.0); glColor3fv(Yellow); if (polygon_offset) glEnable(GL_POLYGON_OFFSET_FILL); glPolygonOffset(1.0, 1.0); glutSolidSphere(0.5, 10, 10); glColor3fv(Black); glutWireSphere(0.5, 10, 10); if (polygon_offset) glDisable(GL_POLYGON_OFFSET_FILL); glPopMatrix(); // w drugiej kolejności rysujemy wnętrze sześcianu; // rysowane są tylko przednie strony wewnętrznych ścian // no i nie jest rysowana ściana przednia, w której będzie otwór glEnable(GL_CULL_FACE); glBegin(GL_QUADS); glColor3fv(Blue); glVertex3f(-1.0, -1.0, -1.0); glVertex3f(1.0, -1.0, -1.0); glVertex3f(1.0, 1.0, -1.0); glVertex3f(-1.0, 1.0, -1.0); glColor3fv(Lime); glVertex3f(-1.0, 1.0, 1.0); glVertex3f(-1.0, -1.0, 1.0); glVertex3f(-1.0, -1.0, -1.0); glVertex3f(-1.0, 1.0, -1.0); glColor3fv(Cyan); glVertex3f(1.0, 1.0, 1.0); glVertex3f(-1.0, 1.0, 1.0); glVertex3f(-1.0, 1.0, -1.0); glVertex3f(1.0, 1.0, -1.0); glColor3fv(Green); glVertex3f(1.0, -1.0, 1.0); glVertex3f(1.0, 1.0, 1.0); glVertex3f(1.0, 1.0, -1.0); glVertex3f(1.0, -1.0, -1.0); glColor3fv(Cyan); glVertex3f(-1.0, -1.0, 1.0); glVertex3f(1.0, -1.0, 1.0); glVertex3f(1.0, -1.0, -1.0); glVertex3f(-1.0, -1.0, -1.0); glEnd(); glDisable(GL_CULL_FACE); // rysowanie płaszczyzny otworu w sześcianie if (cutting_plane) { // wyłączenie rysowania w buforze kolorów glDrawBuffer(GL_NONE); // rysowanie kwadratu częściowo odsłaniającego wnętrze sześcianu // (kwadrat jest położony o 0,001 jednostki nad bokiem sześcianu) glBegin(GL_QUADS); glVertex3f(-0.6, -0.6, 1.001); glVertex3f(0.6, -0.6, 1.001); glVertex3f(0.6, 0.6, 1.001); glVertex3f(-0.6, 0.6, 1.001); glEnd(); // włączenie rysowania w buforze kolorów glDrawBuffer(GL_BACK); } // właściwy sześcian z obramowaniem, którego rysowanie wymusza brak oświetlenia glColor3fv(Red); if (polygon_offset) glEnable(GL_POLYGON_OFFSET_FILL); glPolygonOffset(1.0, 1.0); glutSolidCube(2.0); glColor3fv(Black); glutWireCube(2.0); // skierowanie poleceń do wykonania glFlush(); // zamiana buforów koloru glutSwapBuffers(); } // zmiana wielkości okna void Reshape(int width, int height) { // obszar renderingu - całe okno glViewport(0, 0, width, height); // wybór macierzy rzutowania glMatrixMode(GL_PROJECTION); // macierz rzutowania = macierz jednostkowa glLoadIdentity(); // parametry bryły obcinania glFrustum(left, right, bottom, top, near_, far_); // generowanie sceny 3D Display(); } // obsługa klawiszy funkcyjnych i klawiszy kursora void SpecialKeys(int key, int x, int y) { switch (key) { // kursor w lewo case GLUT_KEY_LEFT: rotatey -= 1; break; // kursor w górę case GLUT_KEY_UP: rotatex -= 1; break; // kursor w prawo case GLUT_KEY_RIGHT: rotatey += 1; break; // kursor w dół case GLUT_KEY_DOWN: rotatex += 1; break; } // odrysowanie okna Reshape(glutGet(GLUT_WINDOW_WIDTH), glutGet(GLUT_WINDOW_HEIGHT)); } // obsługa przycisków myszki void MouseButton(int button, int state, int x, int y) { if (button == GLUT_LEFT_BUTTON) { // zapamiętanie stanu lewego przycisku myszki button_state = state; // zapamiętanie położenia kursora myszki if (state == GLUT_DOWN) { button_x = x; button_y = y; } } } // obsługa ruchu kursora myszki void MouseMotion(int x, int y) { if (button_state == GLUT_DOWN) { rotatey += 30 * (right - left) / glutGet(GLUT_WINDOW_WIDTH) *(x - button_x); button_x = x; rotatex -= 30 * (top - bottom) / glutGet(GLUT_WINDOW_HEIGHT) *(button_y - y); button_y = y; glutPostRedisplay(); } } // obsługa menu podręcznego void Menu(int value) { switch (value) { // płaszczyzna przekroju case CUTTING_PLANE: cutting_plane = !cutting_plane; Display(); break; // przesunięcie wartości głębi case POLYGON_OFFSET: polygon_offset = !polygon_offset; Display(); break; // wyjście case EXIT: exit(0); } } int main(int argc, char * argv[]) { // inicjalizacja biblioteki GLUT glutInit(&argc, argv); // inicjalizacja bufora ramki glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH); // rozmiary głównego okna programu glutInitWindowSize(500, 500); // utworzenie głównego okna programu glutCreateWindow("Z-bufor"); // dołączenie funkcji generującej scenę 3D glutDisplayFunc(Display); // dołączenie funkcji wywoływanej przy zmianie rozmiaru okna glutReshapeFunc(Reshape); // dołączenie funkcji obsługi klawiszy funkcyjnych i klawiszy kursora glutSpecialFunc(SpecialKeys); // obsługa przycisków myszki glutMouseFunc(MouseButton); // obsługa ruchu kursora myszki glutMotionFunc(MouseMotion); // utworzenie menu podręcznego glutCreateMenu(Menu); // menu główne glutCreateMenu(Menu); #ifdef WIN32 glutAddMenuEntry("Płaszczyzna przekroju: rysowana/nierysowana", CUTTING_PLANE); glutAddMenuEntry("Przesunięcie wartości głębi: włącz/wyłącz", POLYGON_OFFSET); glutAddMenuEntry("Wyjście", EXIT); #else glutAddMenuEntry("Plaszczyzna przekroju: rysowana/nierysowana", CUTTING_PLANE); glutAddMenuEntry("Przesuniecie wartosci glebi: wlacz/wylacz", POLYGON_OFFSET); glutAddMenuEntry("Wyjscie", EXIT); #endif // określenie przycisku myszki obsługującej menu podręczne glutAttachMenu(GLUT_RIGHT_BUTTON); // dołączenie funkcji wywoływanej podczas "bezczynności" systemu glutIdleFunc(Display); // wprowadzenie programu do obsługi pętli komunikatów glutMainLoop(); return 0; }
Nie wiem jak narysować ostrosłup prawidłowy podstawą figury jest okno tego kwadratu. Prosiłbym o pomoc.