// Gl_template.c //Wyłączanie błędów przed "fopen" #define _CRT_SECURE_NO_WARNINGS // Ładowanie bibliotek: #ifdef _MSC_VER // Check if MS Visual C compiler # pragma comment(lib, "opengl32.lib") // Compiler-specific directive to avoid manually configuration # pragma comment(lib, "glu32.lib") // Link libraries #endif // Ustalanie trybu tekstowego: #ifdef _MSC_VER // Check if MS Visual C compiler # ifndef _MBCS # define _MBCS // Uses Multi-byte character set # endif # ifdef _UNICODE // Not using Unicode character set # undef _UNICODE # endif # ifdef UNICODE # undef UNICODE # endif #endif #include // Window defines #include // OpenGL #include // GLU library #include // Define for sqrt #include #include "resource.h" // About box resource identifiers. #define glRGB(x, y, z) glColor3ub((GLubyte)x, (GLubyte)y, (GLubyte)z) #define BITMAP_ID 0x4D42 // identyfikator formatu BMP #define GL_PI 3.1415 // Color Palette handle HPALETTE hPalette = NULL; // Application name and instance storeage static LPCTSTR lpszAppName = "GL Template"; static HINSTANCE hInstance; // Rotation amounts static GLfloat xRot = 0.0f; static GLfloat yRot = 0.0f; static GLfloat zRot = 0.0f; static GLsizei lastHeight; static GLsizei lastWidth; // Opis tekstury BITMAPINFOHEADER bitmapInfoHeader; // nagłówek obrazu unsigned char* bitmapData; // dane tekstury unsigned int texture[2]; // obiekt tekstury // Declaration for Window procedure LRESULT CALLBACK WndProc( HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam); // Dialog procedure for about box BOOL APIENTRY AboutDlgProc (HWND hDlg, UINT message, UINT wParam, LONG lParam); // Set Pixel Format function - forward declaration void SetDCPixelFormat(HDC hDC); float KRAWEDZ = 20.0f; float PI = 3.1415f; // Reduces a normal vector specified as a set of three coordinates, // to a unit normal vector of length one. void ReduceToUnit(float vector[3]) { float length; // Calculate the length of the vector length = (float)sqrt((vector[0]*vector[0]) + (vector[1]*vector[1]) + (vector[2]*vector[2])); // Keep the program from blowing up by providing an exceptable // value for vectors that may calculated too close to zero. if(length == 0.0f) length = 1.0f; // Dividing each element by the length will result in a // unit normal vector. vector[0] /= length; vector[1] /= length; vector[2] /= length; } // Points p1, p2, & p3 specified in counter clock-wise order void calcNormal(float v[3][3], float out[3]) { float v1[3],v2[3]; static const int x = 0; static const int y = 1; static const int z = 2; // Calculate two vectors from the three points v1[x] = v[0][x] - v[1][x]; v1[y] = v[0][y] - v[1][y]; v1[z] = v[0][z] - v[1][z]; v2[x] = v[1][x] - v[2][x]; v2[y] = v[1][y] - v[2][y]; v2[z] = v[1][z] - v[2][z]; // Take the cross product of the two vectors to get // the normal vector which will be stored in out out[x] = v1[y]*v2[z] - v1[z]*v2[y]; out[y] = v1[z]*v2[x] - v1[x]*v2[z]; out[z] = v1[x]*v2[y] - v1[y]*v2[x]; // Normalize the vector (shorten length to one) ReduceToUnit(out); } // Change viewing volume and viewport. Called when window is resized void ChangeSize(GLsizei w, GLsizei h) { GLfloat nRange = 100.0f; GLfloat fAspect; // Prevent a divide by zero if(h == 0) h = 1; lastWidth = w; lastHeight = h; fAspect=(GLfloat)w/(GLfloat)h; // Set Viewport to window dimensions glViewport(0, 0, w, h); // Reset coordinate system glMatrixMode(GL_PROJECTION); glLoadIdentity(); // Establish clipping volume (left, right, bottom, top, near, far) if (w <= h) glOrtho (-nRange, nRange, -nRange*h/w, nRange*h/w, -nRange, nRange); else glOrtho (-nRange*w/h, nRange*w/h, -nRange, nRange, -nRange, nRange); // Establish perspective: /* gluPerspective(60.0f,fAspect,1.0,400); */ glMatrixMode(GL_MODELVIEW); glLoadIdentity(); } // This function does any needed initialization on the rendering // context. Here it sets up and initializes the lighting for // the scene. void SetupRC() { // Light values and coordinates //GLfloat ambientLight[] = { 0.3f, 0.3f, 0.3f, 1.0f }; //GLfloat diffuseLight[] = { 0.7f, 0.7f, 0.7f, 1.0f }; //GLfloat specular[] = { 1.0f, 1.0f, 1.0f, 1.0f}; //GLfloat lightPos[] = { 0.0f, 150.0f, 150.0f, 1.0f }; //GLfloat specref[] = { 1.0f, 1.0f, 1.0f, 1.0f }; glEnable(GL_DEPTH_TEST); // Hidden surface removal glFrontFace(GL_CCW); // Counter clock-wise polygons face out //glEnable(GL_CULL_FACE); // Do not calculate inside of jet // Enable lighting //glEnable(GL_LIGHTING); // Setup and enable light 0 //glLightfv(GL_LIGHT0,GL_AMBIENT,ambientLight); //glLightfv(GL_LIGHT0,GL_DIFFUSE,diffuseLight); //glLightfv(GL_LIGHT0,GL_SPECULAR,specular); //glLightfv(GL_LIGHT0,GL_POSITION,lightPos); //glEnable(GL_LIGHT0); // Enable color tracking //glEnable(GL_COLOR_MATERIAL); // Set Material properties to follow glColor values //glColorMaterial(GL_FRONT, GL_AMBIENT_AND_DIFFUSE); // All materials hereafter have full specular reflectivity // with a high shine //glMaterialfv(GL_FRONT, GL_SPECULAR,specref); //glMateriali(GL_FRONT,GL_SHININESS,128); // White background glClearColor(1.0f, 1.0f, 1.0f, 1.0f ); // Black brush glColor3f(0.0,0.0,0.0); } void skrzynka(void) { glColor3d(0.8,0.7,0.3); glEnable(GL_TEXTURE_2D); // Włącz teksturowanie glBindTexture(GL_TEXTURE_2D,texture[0]); glBegin(GL_QUADS); glNormal3d(0,0,1); glTexCoord2d(1.0,1.0); glVertex3d(25,25,25); glTexCoord2d(0.0,1.0); glVertex3d(-25,25,25); glTexCoord2d(0.0,0.0); glVertex3d(-25,-25,25); glTexCoord2d(1.0,0.0); glVertex3d(25,-25,25); glEnd(); glBindTexture(GL_TEXTURE_2D,texture[1]); glBegin(GL_QUADS); glNormal3d(1,0,0); glTexCoord2d(1.0,1.0); glVertex3d(25,25,25); glTexCoord2d(0.0,1.0); glVertex3d(25,-25,25); glTexCoord2d(0.0,0.0); glVertex3d(25,-25,-25); glTexCoord2d(1.0,0.0); glVertex3d(25,25,-25); glEnd(); glDisable(GL_TEXTURE_2D); // Wyłącz teksturowanie glBegin(GL_QUADS); glNormal3d(0,0,-1); glVertex3d(25,25,-25); glVertex3d(25,-25,-25); glVertex3d(-25,-25,-25); glVertex3d(-25,25,-25); glNormal3d(-1,0,0); glVertex3d(-25,25,-25); glVertex3d(-25,-25,-25); glVertex3d(-25,-25,25); glVertex3d(-25,25,25); glNormal3d(0,1,0); glVertex3d(25,25,25); glVertex3d(25,25,-25); glVertex3d(-25,25,-25); glVertex3d(-25,25,25); glNormal3d(0,-1,0); glVertex3d(25,-25,25); glVertex3d(-25,-25,25); glVertex3d(-25,-25,-25); glVertex3d(25,-25,-25); glEnd(); } void walec01(void) { GLUquadricObj*obj; obj=gluNewQuadric(); gluQuadricNormals(obj,GLU_SMOOTH); glColor3d(1,0,0); glPushMatrix(); gluCylinder(obj,20,20,30,15,7); gluCylinder(obj,0,20,0,15,7); glTranslated(0,0,60); glRotated(180.0,0,1,0); gluCylinder(obj,0,20,30,15,7); glPopMatrix(); } void kula(void) { GLUquadricObj*obj; obj=gluNewQuadric(); gluQuadricTexture(obj,GL_TRUE); glBindTexture(GL_TEXTURE_2D,texture[0]); glTexEnvi(GL_TEXTURE_ENV,GL_TEXTURE_ENV_MODE,GL_MODULATE); glColor3d(1.0,0.8,0.8); glEnable(GL_TEXTURE_2D); gluSphere(obj,40,15,7); glDisable(GL_TEXTURE_2D); } // LoadBitmapFile // opis: ładuje mapę bitową z pliku i zwraca jej adres. // Wypełnia strukturę nagłówka. // Nie obsługuje map 8-bitowych. unsigned char *LoadBitmapFile(char *filename, BITMAPINFOHEADER *bitmapInfoHeader) { FILE *filePtr; // wskaźnik pozycji pliku BITMAPFILEHEADER bitmapFileHeader; // nagłówek pliku unsigned char *bitmapImage; // dane obrazu int imageIdx = 0; // licznik pikseli unsigned char tempRGB; // zmienna zamiany składowych // otwiera plik w trybie "read binary" filePtr = fopen(filename, "rb"); if (filePtr == NULL) return NULL; // wczytuje nagłówek pliku fread(&bitmapFileHeader, sizeof(BITMAPFILEHEADER), 1, filePtr); // sprawdza, czy jest to plik formatu BMP if (bitmapFileHeader.bfType != BITMAP_ID) { fclose(filePtr); return NULL; } // wczytuje nagłówek obrazu fread(bitmapInfoHeader, sizeof(BITMAPINFOHEADER), 1, filePtr); // ustawia wskaźnik pozycji pliku na początku danych obrazu fseek(filePtr, bitmapFileHeader.bfOffBits, SEEK_SET); // przydziela pamięć buforowi obrazu bitmapImage = (unsigned char*)malloc(bitmapInfoHeader->biSizeImage); // sprawdza, czy udało się przydzielić pamięć if (!bitmapImage) { free(bitmapImage); fclose(filePtr); return NULL; } // wczytuje dane obrazu fread(bitmapImage, 1, bitmapInfoHeader->biSizeImage, filePtr); // sprawdza, czy dane zostały wczytane if (bitmapImage == NULL) { fclose(filePtr); return NULL; } // zamienia miejscami składowe R i B for (imageIdx = 0; imageIdx < bitmapInfoHeader->biSizeImage; imageIdx+=3) { tempRGB = bitmapImage[imageIdx]; bitmapImage[imageIdx] = bitmapImage[imageIdx + 2]; bitmapImage[imageIdx + 2] = tempRGB; } // zamyka plik i zwraca wskaźnik bufora zawierającego wczytany obraz fclose(filePtr); return bitmapImage; } float deg2rad(int degrees) { return degrees % 360 * PI / 180.0f; } int variable2 = 45; int variable3 = 0; int polygonmode = 0; int iloscwarstw = 5; int ilosccegiel = 3; int variableIndex = 0; float variableDegrees[] = {0, 30, 60, 90}; float D_x = 0.0f; float D_y = 10.0f; void szescian(void) { // glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); { // Parametry wierzcholkow GLfloat sa[3] = { 0.0f, 0.0f, 0.0f }; GLfloat sb[3] = { KRAWEDZ, 0.0f, 0.0f }; GLfloat sc[3] = { KRAWEDZ, KRAWEDZ, 0.0f }; GLfloat sd[3] = { 0.0f, KRAWEDZ, 0.0f }; GLfloat se[3] = { 0.0f, 0.0f, -KRAWEDZ }; GLfloat sf[3] = { KRAWEDZ, 0.0f, -KRAWEDZ }; GLfloat sg[3] = { KRAWEDZ, KRAWEDZ, -KRAWEDZ }; GLfloat sh[3] = { 0.0f, KRAWEDZ, -KRAWEDZ }; // Sciany skladowe switch (variable3){ case 0: // 0. ściana czerwona glColor3f(1.0f, 0.0f, 0.0f); glBegin(GL_POLYGON); glVertex3fv(sa); glVertex3fv(sb); glVertex3fv(sc); glVertex3fv(sd); glEnd(); break; case 1: // 1. (zakomentowana) ściana czerwona // glColor3f(1.0f, 0.0f, 0.0f); // glBegin(GL_POLYGON); // glVertex3fv(sa); // glVertex3fv(sb); // glVertex3fv(sc); // glVertex3fv(sd); // glEnd(); break; case 2: // 2. uniesiona ściana czerwona glColor3f(1.0f, 0.0f, 0.0f); glBegin(GL_POLYGON); glVertex3f(0.0f, 0.0f, KRAWEDZ); glVertex3f(KRAWEDZ, 0.0f, KRAWEDZ); glVertex3f(KRAWEDZ, KRAWEDZ, KRAWEDZ); glVertex3f(0.0f, KRAWEDZ, KRAWEDZ); glEnd(); break; case 3: // 3. ściana czerwona przesunięta bokiem równolegle do płaszczyzny XY glColor3f(1.0f, 0.0f, 0.0f); glBegin(GL_POLYGON); glVertex3f(0.0f + KRAWEDZ, 0.0f, 0.0f); glVertex3f(KRAWEDZ + KRAWEDZ, 0.0f, 0.0f); glVertex3f(KRAWEDZ + KRAWEDZ, KRAWEDZ, 0.0f); glVertex3f(0.0f + KRAWEDZ, KRAWEDZ, 0.0f); glEnd(); break; case 4: // 4. "otwarte pudełko" do góry pod kątem 45 stopni float pythagorean = KRAWEDZ * sin(deg2rad(45)); glColor3f(1.0f, 0.0f, 0.0f); glBegin(GL_POLYGON); glVertex3f(0.0f, 0.0f, 0.0f); glVertex3f(KRAWEDZ, 0.0f, 0.0f); glVertex3f(KRAWEDZ, KRAWEDZ * cos(deg2rad(45)), KRAWEDZ * sin(deg2rad(45))); // punkt C glVertex3f(0.0f, KRAWEDZ * cos(deg2rad(45)), KRAWEDZ * sin(deg2rad(45))); // punkt D glEnd(); break; case 5: // 5. "otwarte pudełko" bokiem pod kątem 45 stopni float diagonal = KRAWEDZ * sqrt(2); float katObrotu = deg2rad(variable2); // https://math.stackexchange.com/a/1385082 // D_x = KRAWEDZ + (D_x - KRAWEDZ)*cos(deg2rad(1)) - (D_y - 0)*sin(deg2rad(1)); // D_y = 0 + (D_x - KRAWEDZ)*sin(deg2rad(1)) + (D_y - 0)*cos(deg2rad(1)); D_x = KRAWEDZ + (0 - KRAWEDZ)*cos(deg2rad(variable2)) - (KRAWEDZ - 0)*sin(deg2rad(variable2)); D_y = 0 + (0 - KRAWEDZ)*sin(deg2rad(variable2)) + (KRAWEDZ - 0)*cos(deg2rad(variable2)); glColor3f(1.0f, 0.0f, 0.0f); glBegin(GL_POLYGON); glVertex3f(KRAWEDZ - KRAWEDZ * (float)cos(katObrotu), -(float)sin(katObrotu) * KRAWEDZ, 0.0f); // A glVertex3f(KRAWEDZ, 0.0f, 0.0f); // B glVertex3f(KRAWEDZ - KRAWEDZ * (float)sin(katObrotu), (float)cos(katObrotu) * KRAWEDZ, 0.0f); // C glVertex3f(D_x, D_y, 0.0f); // D glEnd(); break; case 6: // 6. "otwarte pudełko" do góry pod kątami 0-30-60-90 stopni float krawedz_sin = KRAWEDZ * sin(deg2rad(variableDegrees[variableIndex])); float krawedz_cos = KRAWEDZ * cos(deg2rad(variableDegrees[variableIndex])); glColor3f(1.0f, 0.0f, 0.0f); glBegin(GL_POLYGON); glVertex3f(0.0f, 0.0f, 0.0f); glVertex3f(KRAWEDZ, 0.0f, 0.0f); glVertex3f(KRAWEDZ, krawedz_cos, krawedz_sin); // punkt C glVertex3f(0.0f, krawedz_cos, krawedz_sin); // punkt D glEnd(); break; default: // 1. ściana czerwona glColor3f(1.0f, 0.0f, 0.0f); glBegin(GL_POLYGON); glVertex3fv(sa); glVertex3fv(sb); glVertex3fv(sc); glVertex3fv(sd); glEnd(); } glColor3f(0.0f, 1.0f, 0.0f); glBegin(GL_POLYGON); glVertex3fv(sb); glVertex3fv(sf); glVertex3fv(sg); glVertex3fv(sc); glEnd(); glColor3f(0.0f, 0.0f, 1.0f); glBegin(GL_POLYGON); glVertex3fv(sf); glVertex3fv(se); glVertex3fv(sh); glVertex3fv(sg); glEnd(); glColor3f(1.0f, 1.0f, 0.0f); glBegin(GL_POLYGON); glVertex3fv(se); glVertex3fv(sa); glVertex3fv(sd); glVertex3fv(sh); glEnd(); glColor3f(0.0f, 1.0f, 1.0f); glBegin(GL_POLYGON); glVertex3fv(sd); glVertex3fv(sc); glVertex3fv(sg); glVertex3fv(sh); glEnd(); glColor3f(1.0f, 0.0f, 1.0f); glBegin(GL_POLYGON); glVertex3fv(sa); glVertex3fv(sb); glVertex3fv(sf); glVertex3fv(se); glEnd(); } } void most(void) { // glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); { // Sciany skladowe // PRZÓD glColor3f(0.5f, 0.5f, 0.5f); glBegin(GL_TRIANGLES); glVertex3f( 0.0f, 0.0f, 0.0f); glVertex3f( 0.0f, 20.0f, 0.0f); glVertex3f(20.0f, 20.0f, 0.0f); glVertex3f( 0.0f, 0.0f, 0.0f); glVertex3f(20.0f, 0.0f, 0.0f); glVertex3f(20.0f, 20.0f, 0.0f); glEnd(); glColor3f(0.5f, 0.5f, 0.5f); glBegin(GL_TRIANGLES); glVertex3f(60.0f, 0.0f, 0.0f); glVertex3f(60.0f, 20.0f, 0.0f); glVertex3f(80.0f, 20.0f, 0.0f); glVertex3f(60.0f, 0.0f, 0.0f); glVertex3f(80.0f, 0.0f, 0.0f); glVertex3f(80.0f, 20.0f, 0.0f); glEnd(); glColor3f(0.5f, 0.5f, 0.5f); glBegin(GL_TRIANGLES); glVertex3f( 0.0f, 20.0f, 0.0f); glVertex3f( 0.0f, 40.0f, 0.0f); glVertex3f(80.0f, 40.0f, 0.0f); glVertex3f( 0.0f, 20.0f, 0.0f); glVertex3f(80.0f, 20.0f, 0.0f); glVertex3f(80.0f, 40.0f, 0.0f); glEnd(); glColor3f(0.5f, 0.5f, 0.5f); glBegin(GL_TRIANGLE_FAN); glVertex3f(20.0f, 20.0f, 0.0f); for (int i = -20; i < 0; i++){ float koord_y = sqrt((20 - i) * (20 + i)); glVertex3f(40.0f + i, koord_y, 0.0f); } glEnd(); glColor3f(0.5f, 0.5f, 0.5f); glBegin(GL_TRIANGLE_FAN); glVertex3f(60.0f, 20.0f, 0.0f); for (int i = 20; i > 0; i--){ float koord_y = sqrt((20 - i) * (20 + i)); glVertex3f(40.0f + i, koord_y, 0.0f); } glEnd(); // TYŁ glColor3f(0.5f, 0.5f, 0.5f); glBegin(GL_TRIANGLES); glVertex3f( 0.0f, 0.0f, 20.0f); glVertex3f( 0.0f, 20.0f, 20.0f); glVertex3f(20.0f, 20.0f, 20.0f); glVertex3f( 0.0f, 0.0f, 20.0f); glVertex3f(20.0f, 0.0f, 20.0f); glVertex3f(20.0f, 20.0f, 20.0f); glEnd(); glColor3f(0.5f, 0.5f, 0.5f); glBegin(GL_TRIANGLES); glVertex3f(60.0f, 0.0f, 20.0f); glVertex3f(60.0f, 20.0f, 20.0f); glVertex3f(80.0f, 20.0f, 20.0f); glVertex3f(60.0f, 0.0f, 20.0f); glVertex3f(80.0f, 0.0f, 20.0f); glVertex3f(80.0f, 20.0f, 20.0f); glEnd(); glColor3f(0.5f, 0.5f, 0.5f); glBegin(GL_TRIANGLES); glVertex3f( 0.0f, 20.0f, 20.0f); glVertex3f( 0.0f, 40.0f, 20.0f); glVertex3f(80.0f, 40.0f, 20.0f); glVertex3f( 0.0f, 20.0f, 20.0f); glVertex3f(80.0f, 20.0f, 20.0f); glVertex3f(80.0f, 40.0f, 20.0f); glEnd(); glColor3f(0.5f, 0.5f, 0.5f); glBegin(GL_TRIANGLE_FAN); glVertex3f(20.0f, 20.0f, 20.0f); for (int i = -20; i < 0; i++){ float koord_y = sqrt((20 - i) * (20 + i)); glVertex3f(40.0f + i, koord_y, 20.0f); } glEnd(); glColor3f(0.5f, 0.5f, 0.5f); glBegin(GL_TRIANGLE_FAN); glVertex3f(60.0f, 20.0f, 20.0f); for (int i = 20; i > 0; i--){ float koord_y = sqrt((20 - i) * (20 + i)); glVertex3f(40.0f + i, koord_y, 20.0f); } glEnd(); // GÓRA glColor3f(0.5f, 0.5f, 0.5f); glBegin(GL_TRIANGLES); glVertex3f( 0.0f, 40.0f, 0.0f); glVertex3f( 0.0f, 40.0f, 20.0f); glVertex3f(80.0f, 40.0f, 20.0f); glVertex3f(80.0f, 40.0f, 20.0f); glVertex3f(80.0f, 40.0f, 0.0f); glVertex3f( 0.0f, 40.0f, 0.0f); glEnd(); // BOKI glColor3f(0.5f, 0.5f, 0.5f); glBegin(GL_TRIANGLES); glVertex3f( 0.0f, 0.0f, 0.0f); glVertex3f( 0.0f, 40.0f, 0.0f); glVertex3f( 0.0f, 0.0f, 20.0f); glVertex3f( 0.0f, 0.0f, 20.0f); glVertex3f( 0.0f, 40.0f, 20.0f); glVertex3f( 0.0f, 40.0f, 0.0f); glVertex3f(80.0f, 0.0f, 0.0f); glVertex3f(80.0f, 40.0f, 0.0f); glVertex3f(80.0f, 0.0f, 20.0f); glVertex3f(80.0f, 0.0f, 20.0f); glVertex3f(80.0f, 40.0f, 20.0f); glVertex3f(80.0f, 40.0f, 0.0f); glEnd(); // DÓŁ glColor3f(0.5f, 0.5f, 0.5f); glBegin(GL_TRIANGLES); glVertex3f( 0.0f, 0.0f, 0.0f); glVertex3f( 0.0f, 0.0f, 20.0f); glVertex3f(20.0f, 0.0f, 20.0f); glVertex3f(20.0f, 0.0f, 20.0f); glVertex3f(20.0f, 0.0f, 0.0f); glVertex3f( 0.0f, 0.0f, 0.0f); glVertex3f(60.0f, 0.0f, 0.0f); glVertex3f(60.0f, 0.0f, 20.0f); glVertex3f(80.0f, 0.0f, 20.0f); glVertex3f(80.0f, 0.0f, 20.0f); glVertex3f(80.0f, 0.0f, 0.0f); glVertex3f(60.0f, 0.0f, 0.0f); glEnd(); glColor3f(0.48f, 0.48f, 0.48f); glBegin(GL_TRIANGLE_STRIP); glVertex3f(20.0f, 0.0f, 0.0f); for (int i = -20; i < 0; i++){ float koord_y = sqrt((20 - i) * (20 + i)); glVertex3f(40.0f + i, koord_y, 0.0f); glVertex3f(40.0f + i, koord_y, 20.0f); } // lekkie oszustwo, dla lepszego wyglądu glVertex3f(40.0f + 1.0f, 20.0f, 0.0f); glVertex3f(40.0f + 1.0f, 20.0f, 20.0f); glEnd(); glColor3f(0.48f, 0.48f, 0.48f); glBegin(GL_TRIANGLE_STRIP); glVertex3f(60.0f, 0.0f, 0.0f); for (int i = 20; i > 0; i--){ float koord_y = sqrt((20 - i) * (20 + i)); glVertex3f(40.0f + i, koord_y, 0.0f); glVertex3f(40.0f + i, koord_y, 20.0f); } glEnd(); } } void cegla(float x, float y, float z){ GLfloat sa[3] = { x - 12, y - 3, z - 12}; GLfloat sb[3] = { x + 12, y - 3, z - 12}; GLfloat sc[3] = { x + 12, y - 3, z + 12}; GLfloat sd[3] = { x - 12, y - 3, z + 12}; GLfloat se[3] = { x - 12, y + 3, z - 12}; GLfloat sf[3] = { x + 12, y + 3, z - 12}; GLfloat sg[3] = { x + 12, y + 3, z + 12}; GLfloat sh[3] = { x - 12, y + 3, z + 12}; glColor3f(0.5f, 0.05f, 0.05f); glBegin(GL_TRIANGLES); // SCIANY BOCZNE glVertex3fv(sa); glVertex3fv(se); glVertex3fv(sd); glVertex3fv(sd); glVertex3fv(sh); glVertex3fv(se); glVertex3fv(sb); glVertex3fv(sf); glVertex3fv(sc); glVertex3fv(sc); glVertex3fv(sg); glVertex3fv(sf); glEnd(); // PRZOD, TYL glColor3f(0.5f, 0.1f, 0.1f); glBegin(GL_TRIANGLES); glVertex3fv(sa); glVertex3fv(se); glVertex3fv(sb); glVertex3fv(sb); glVertex3fv(sf); glVertex3fv(se); glVertex3fv(sd); glVertex3fv(sh); glVertex3fv(sc); glVertex3fv(sc); glVertex3fv(sg); glVertex3fv(sh); glEnd(); // GORA, DOL glColor3f(0.5f, 0.2f, 0.2f); glBegin(GL_TRIANGLES); glVertex3fv(se); glVertex3fv(sh); glVertex3fv(sg); glVertex3fv(sg); glVertex3fv(sf); glVertex3fv(se); glEnd(); glColor3f(0.5f, 0.03f, 0.03f); glBegin(GL_TRIANGLES); glVertex3fv(sa); glVertex3fv(sd); glVertex3fv(sc); glVertex3fv(sc); glVertex3fv(sb); glVertex3fv(sa); glEnd(); } void mur(int mic, int iwm){ // mic - minimalna ilość cegieł // iwm - ilość warstw muru for (int i = 0; i <= iwm; i++){ int cegielWWarstwie = mic + (i + 1) % 2; float minValue = (cegielWWarstwie - 1) * (-12.5f); for (int j = 0; j < cegielWWarstwie; j++){ cegla(minValue + j * (24 + 3), (6 + 3) * i + 3, 0); } } } void walec(double r, double h) { double x, y, alpha, PI = 3.14; glBegin(GL_TRIANGLE_FAN); glColor3d(0.8, 0.0, 0); glVertex3d(0, 0, 0); for (alpha = 0; alpha <= 2 * PI; alpha += PI / 8.0) { x = r*sin(alpha); y = r*cos(alpha); glVertex3d(x, y, 0); } glEnd(); glBegin(GL_QUAD_STRIP); for (alpha = 0.0; alpha <= 2 * PI; alpha += PI / 8.0) { x = r*sin(alpha); y = r* cos(alpha); glVertex3d(x, y, 0); glVertex3d(x, y, h); } glEnd(); glBegin(GL_TRIANGLE_FAN); glVertex3d(0, 0, h); for (alpha = 0; alpha >= -2 * PI; alpha -= PI / 8.0) { x = r*sin(alpha); y = r*cos(alpha); glVertex3d(x, y, h); } glEnd(); } void ramie(double r1, double r2, double h, double d) { double PI = 3.14, alpha, x, y; glBegin(GL_TRIANGLE_FAN); glColor3d(0.8, 0.0, 0); glVertex3d(0, 0, 0); for (alpha = PI; alpha <= 2 * PI; alpha += PI / 8.0) { x = r1*sin(alpha); y = r1*cos(alpha); glVertex3d(x, y, 0); } glEnd(); glBegin(GL_QUAD_STRIP); for (alpha = 0; alpha >= -PI; alpha -= PI / 8.0) { x = r1*sin(alpha); y = r1* cos(alpha); glVertex3d(x, y, h); glVertex3d(x, y, 0); } glEnd(); glBegin(GL_TRIANGLE_FAN); glVertex3d(0, 0, h); for (alpha = 0; alpha >= -PI; alpha -= PI / 8.0) { x = r1*sin(alpha); y = r1*cos(alpha); glVertex3d(x, y, h); } glEnd(); glBegin(GL_TRIANGLE_FAN); glColor3d(0.8, 0.0, 0); //glVertex3d(d,r2,0); //glVertex3d(d, r2, h); for (alpha = 0; alpha <= PI; alpha += PI / 8.0) { x = d + r2 * sin(alpha); y = d + r2 * cos(alpha); glVertex3d(x, y, 0); } glEnd(); glBegin(GL_QUAD_STRIP); //glVertex3d(d, r2, 0); for (alpha = 0; alpha <= PI; alpha += PI / 8.0) { x = d+ r2*sin(alpha); y = d +r2* cos(alpha); glVertex3d(x, y, h); glVertex3d(x, y, 0); } glEnd(); glBegin(GL_TRIANGLE_FAN); //glVertex3d(d, r2, h); for (alpha = 0; alpha <= PI; alpha += PI / 8.0) { x = d +r2*sin(alpha); y = d +r2*cos(alpha); glVertex3d(x, y, h); } glEnd(); } char zadanie = 0; char pomoc = 0; // Called to draw scene void RenderScene(void) { //float normal[3]; // Storeage for calculated surface normal if (!pomoc) { printf("Grafika Komputerowa\n"); printf("L01 177188, 2 EF-DI\n\n"); printf("Nawigacja:\n"); printf(" q, e - obrot\n"); printf("<-, -> - obrot\n"); printf(" ^, v - obrot\n"); printf(" - zmiana trybu wyswietlania (wypelnienie, siatka)\n"); printf("r - reset widoku\n"); printf("1 - szescian\n"); printf("w - zmiana podpunktu zadania (szescian)\n"); printf("s - (1.5) zmiana katu obrotu wieczka szescianu\n"); printf("a - (1.6) zmiana katu otwarcia szescianu\n"); printf("2 - most\n"); printf("3 - cegielki\n"); printf(" z, x - zmiana ilosci cegielek\n"); printf(" c, v - zmiana ilosci warstw cegielek\n\n"); pomoc = 1; } // Clear the window with current clearing color glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // Save the matrix state and do the rotations glPushMatrix(); glRotatef(xRot, 1.0f, 0.0f, 0.0f); glRotatef(yRot, 0.0f, 1.0f, 0.0f); glRotatef(zRot, 0.0f, 0.0f, 1.0f); ///////////////////////////////////////////////////////////////// // MIEJSCE NA KOD OPENGL DO TWORZENIA WLASNYCH SCEN: // ///////////////////////////////////////////////////////////////// //szescian(); //Sposób na odróżnienie "przedniej" i "tylniej" ściany wielokąta: //glPolygonMode(GL_BACK,GL_LINE); //walec(40, 40); //szescian(); switch (polygonmode){ case 0: glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); break; case 1: glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); break; default: glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); } switch (zadanie){ case 1: szescian(); break; case 2: most(); break; case 3: mur(ilosccegiel, iloscwarstw); break; default: szescian(); } //Uzyskanie siatki: //glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); //Wyrysowanie prostokata: //glRectd(-10.0,-10.0,20.0,20.0); ///////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////// glPopMatrix(); glMatrixMode(GL_MODELVIEW); // Flush drawing commands glFlush(); } // Select the pixel format for a given device context void SetDCPixelFormat(HDC hDC) { int nPixelFormat; static PIXELFORMATDESCRIPTOR pfd = { sizeof(PIXELFORMATDESCRIPTOR), // Size of this structure 1, // Version of this structure PFD_DRAW_TO_WINDOW | // Draw to Window (not to bitmap) PFD_SUPPORT_OPENGL | // Support OpenGL calls in window PFD_DOUBLEBUFFER, // Double buffered PFD_TYPE_RGBA, // RGBA Color mode 24, // Want 24bit color 0,0,0,0,0,0, // Not used to select mode 0,0, // Not used to select mode 0,0,0,0,0, // Not used to select mode 32, // Size of depth buffer 0, // Not used to select mode 0, // Not used to select mode PFD_MAIN_PLANE, // Draw in main plane 0, // Not used to select mode 0,0,0 }; // Not used to select mode // Choose a pixel format that best matches that described in pfd nPixelFormat = ChoosePixelFormat(hDC, &pfd); // Set the pixel format for the device context SetPixelFormat(hDC, nPixelFormat, &pfd); } // If necessary, creates a 3-3-2 palette for the device context listed. HPALETTE GetOpenGLPalette(HDC hDC) { HPALETTE hRetPal = NULL; // Handle to palette to be created PIXELFORMATDESCRIPTOR pfd; // Pixel Format Descriptor LOGPALETTE *pPal; // Pointer to memory for logical palette int nPixelFormat; // Pixel format index int nColors; // Number of entries in palette int i; // Counting variable BYTE RedRange,GreenRange,BlueRange; // Range for each color entry (7,7,and 3) // Get the pixel format index and retrieve the pixel format description nPixelFormat = GetPixelFormat(hDC); DescribePixelFormat(hDC, nPixelFormat, sizeof(PIXELFORMATDESCRIPTOR), &pfd); // Does this pixel format require a palette? If not, do not create a // palette and just return NULL if(!(pfd.dwFlags & PFD_NEED_PALETTE)) return NULL; // Number of entries in palette. 8 bits yeilds 256 entries nColors = 1 << pfd.cColorBits; // Allocate space for a logical palette structure plus all the palette entries pPal = (LOGPALETTE*)malloc(sizeof(LOGPALETTE) +nColors*sizeof(PALETTEENTRY)); // Fill in palette header pPal->palVersion = 0x300; // Windows 3.0 pPal->palNumEntries = nColors; // table size // Build mask of all 1's. This creates a number represented by having // the low order x bits set, where x = pfd.cRedBits, pfd.cGreenBits, and // pfd.cBlueBits. RedRange = (1 << pfd.cRedBits) -1; GreenRange = (1 << pfd.cGreenBits) - 1; BlueRange = (1 << pfd.cBlueBits) -1; // Loop through all the palette entries for(i = 0; i < nColors; i++) { // Fill in the 8-bit equivalents for each component pPal->palPalEntry[i].peRed = (i >> pfd.cRedShift) & RedRange; pPal->palPalEntry[i].peRed = (unsigned char)( (double) pPal->palPalEntry[i].peRed * 255.0 / RedRange); pPal->palPalEntry[i].peGreen = (i >> pfd.cGreenShift) & GreenRange; pPal->palPalEntry[i].peGreen = (unsigned char)( (double)pPal->palPalEntry[i].peGreen * 255.0 / GreenRange); pPal->palPalEntry[i].peBlue = (i >> pfd.cBlueShift) & BlueRange; pPal->palPalEntry[i].peBlue = (unsigned char)( (double)pPal->palPalEntry[i].peBlue * 255.0 / BlueRange); // pPal->palPalEntry[i].peFlags = (unsigned char) NULL; pPal->palPalEntry[i].peFlags = 0; } // Create the palette hRetPal = CreatePalette(pPal); // Go ahead and select and realize the palette for this device context SelectPalette(hDC,hRetPal,FALSE); RealizePalette(hDC); // Free the memory used for the logical palette structure free(pPal); // Return the handle to the new palette return hRetPal; } // Entry point of all Windows programs int APIENTRY WinMain( HINSTANCE hInst, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) { MSG msg; // Windows message structure WNDCLASS wc; // Windows class structure HWND hWnd; // Storeage for window handle hInstance = hInst; // Register Window style wc.style = CS_HREDRAW | CS_VREDRAW; wc.lpfnWndProc = (WNDPROC) WndProc; wc.cbClsExtra = 0; wc.cbWndExtra = 0; wc.hInstance = hInstance; wc.hIcon = NULL; wc.hCursor = LoadCursor(NULL, IDC_ARROW); // No need for background brush for OpenGL window wc.hbrBackground = NULL; wc.lpszMenuName = MAKEINTRESOURCE(IDR_MENU); wc.lpszClassName = lpszAppName; // Register the window class if(RegisterClass(&wc) == 0) return FALSE; // Create the main application window hWnd = CreateWindow( lpszAppName, lpszAppName, // OpenGL requires WS_CLIPCHILDREN and WS_CLIPSIBLINGS WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN | WS_CLIPSIBLINGS, // Window position and size 50, 50, 400, 400, NULL, NULL, hInstance, NULL); // If window was not created, quit if(hWnd == NULL) return FALSE; // Display the window ShowWindow(hWnd,SW_SHOW); UpdateWindow(hWnd); // Process application messages until the application closes while( GetMessage(&msg, NULL, 0, 0)) { TranslateMessage(&msg); DispatchMessage(&msg); } return msg.wParam; } // Window procedure, handles all messages for this program LRESULT CALLBACK WndProc( HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) { static HGLRC hRC; // Permenant Rendering context static HDC hDC; // Private GDI Device context switch (message) { // Window creation, setup for OpenGL case WM_CREATE: // Store the device context hDC = GetDC(hWnd); // Select the pixel format SetDCPixelFormat(hDC); // Create palette if needed hPalette = GetOpenGLPalette(hDC); // Create the rendering context and make it current hRC = wglCreateContext(hDC); wglMakeCurrent(hDC, hRC); SetupRC(); glGenTextures(2, &texture[0]); // tworzy obiekt tekstury // ładuje pierwszy obraz tekstury: bitmapData = LoadBitmapFile("Bitmapy\\checker.bmp", &bitmapInfoHeader); glBindTexture(GL_TEXTURE_2D, texture[0]); // aktywuje obiekt tekstury glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP ); // tworzy obraz tekstury glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, bitmapInfoHeader.biWidth, bitmapInfoHeader.biHeight, 0, GL_RGB, GL_UNSIGNED_BYTE, bitmapData); if(bitmapData) free(bitmapData); // ładuje drugi obraz tekstury: bitmapData = LoadBitmapFile("Bitmapy\\crate.bmp", &bitmapInfoHeader); glBindTexture(GL_TEXTURE_2D, texture[1]); // aktywuje obiekt tekstury glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP ); // tworzy obraz tekstury glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, bitmapInfoHeader.biWidth, bitmapInfoHeader.biHeight, 0, GL_RGB, GL_UNSIGNED_BYTE, bitmapData); if(bitmapData) free(bitmapData); // ustalenie sposobu mieszania tekstury z tłem glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE,GL_MODULATE); break; // Window is being destroyed, cleanup case WM_DESTROY: // Deselect the current rendering context and delete it wglMakeCurrent(hDC,NULL); wglDeleteContext(hRC); // Delete the palette if it was created if(hPalette != NULL) DeleteObject(hPalette); // Tell the application to terminate after the window // is gone. PostQuitMessage(0); break; // Window is resized. case WM_SIZE: // Call our function which modifies the clipping // volume and viewport ChangeSize(LOWORD(lParam), HIWORD(lParam)); break; // The painting function. This message sent by Windows // whenever the screen needs updating. case WM_PAINT: { // Call OpenGL drawing code RenderScene(); SwapBuffers(hDC); // Validate the newly painted client area ValidateRect(hWnd,NULL); } break; // Windows is telling the application that it may modify // the system palette. This message in essance asks the // application for a new palette. case WM_QUERYNEWPALETTE: // If the palette was created. if(hPalette) { int nRet; // Selects the palette into the current device context SelectPalette(hDC, hPalette, FALSE); // Map entries from the currently selected palette to // the system palette. The return value is the number // of palette entries modified. nRet = RealizePalette(hDC); // Repaint, forces remap of palette in current window InvalidateRect(hWnd,NULL,FALSE); return nRet; } break; // This window may set the palette, even though it is not the // currently active window. case WM_PALETTECHANGED: // Don't do anything if the palette does not exist, or if // this is the window that changed the palette. if((hPalette != NULL) && ((HWND)wParam != hWnd)) { // Select the palette into the device context SelectPalette(hDC,hPalette,FALSE); // Map entries to system palette RealizePalette(hDC); // Remap the current colors to the newly realized palette UpdateColors(hDC); return 0; } break; // Key press, check for arrow keys to do cube rotation. case WM_KEYDOWN: { switch (wParam){ case VK_UP: xRot -= 5.0f; break; case VK_DOWN: xRot += 5.0f; break; case VK_LEFT: yRot -= 5.0f; break; case VK_RIGHT: yRot += 5.0f; break; case 'Q': zRot += 5.0f; break; case 'E': zRot -= 5.0f; break; case 'A': variableIndex++; variableIndex %= sizeof(variableDegrees) / sizeof(variableDegrees[0]); break; case 'S': variable2++; variable2 %= 360; break; case 'W': variable3++; variable3 %= 7; break; case 'Z': iloscwarstw--; break; case 'X': iloscwarstw++; break; case 'C': ilosccegiel--; break; case 'V': ilosccegiel++; break; case 'R': xRot = 0; yRot = 0; zRot = 0; variableIndex = 0; variable2 = 45; variable3 = 0; iloscwarstw = 5; ilosccegiel = 3; break; case 49: // 1 na klawiaturze zadanie = 1; break; case 50: // 2 na klawiaturze zadanie = 2; break; case 51: // 3 na klawiaturze zadanie = 3; break; case 32: polygonmode = !polygonmode; break; default: printf("debug: nacisnieto nierozpoznany klawisz: %d\n", wParam); } xRot = (const int)xRot % 360; yRot = (const int)yRot % 360; zRot = (const int)zRot % 360; InvalidateRect(hWnd,NULL,FALSE); } break; // A menu command case WM_COMMAND: { switch(LOWORD(wParam)) { // Exit the program case ID_FILE_EXIT: DestroyWindow(hWnd); break; // Display the about box case ID_HELP_ABOUT: DialogBox (hInstance, MAKEINTRESOURCE(IDD_DIALOG_ABOUT), hWnd, AboutDlgProc); break; } } break; default: // Passes it on if unproccessed return (DefWindowProc(hWnd, message, wParam, lParam)); } return (0L); } // Dialog procedure. BOOL APIENTRY AboutDlgProc (HWND hDlg, UINT message, UINT wParam, LONG lParam) { switch (message) { // Initialize the dialog box case WM_INITDIALOG: { int i; GLenum glError; // glGetString demo SetDlgItemText(hDlg,IDC_OPENGL_VENDOR,glGetString(GL_VENDOR)); SetDlgItemText(hDlg,IDC_OPENGL_RENDERER,glGetString(GL_RENDERER)); SetDlgItemText(hDlg,IDC_OPENGL_VERSION,glGetString(GL_VERSION)); SetDlgItemText(hDlg,IDC_OPENGL_EXTENSIONS,glGetString(GL_EXTENSIONS)); // gluGetString demo SetDlgItemText(hDlg,IDC_GLU_VERSION,gluGetString(GLU_VERSION)); SetDlgItemText(hDlg,IDC_GLU_EXTENSIONS,gluGetString(GLU_EXTENSIONS)); // Display any recent error messages i = 0; do { glError = glGetError(); SetDlgItemText(hDlg,IDC_ERROR1+i,gluErrorString(glError)); i++; } while(i < 6 && glError != GL_NO_ERROR); return (TRUE); } break; // Process command messages case WM_COMMAND: { // Validate and Make the changes if(LOWORD(wParam) == IDOK) EndDialog(hDlg,TRUE); } break; // Closed from sysbox case WM_CLOSE: EndDialog(hDlg,TRUE); break; } return FALSE; }