Files
grafikaKBT/Gl_template.c.DONTCOMPILE
2024-11-26 15:46:22 +01:00

1514 lines
39 KiB
Plaintext

// 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 <windows.h> // Window defines
#include <gl\gl.h> // OpenGL
#include <gl\glu.h> // GLU library
#include <math.h> // Define for sqrt
#include <stdio.h>
#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("<spacja> - 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;
}