Created
May 3, 2024 22:57
-
-
Save habibg1232191/80ee600e812a0ed75fd8e28cafa87df2 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include "Render.h" | |
#include <sstream> | |
#include <iostream> | |
#include <windows.h> | |
#include <GL\GL.h> | |
#include <GL\GLU.h> | |
#include "MyOGL.h" | |
#include "Camera.h" | |
#include "Light.h" | |
#include "Primitives.h" | |
#include "GUItextRectangle.h" | |
#define PI 3.14 | |
bool textureMode = true; | |
bool lightMode = true; | |
bool textureReplace = true; // (Н) Эта переменная отвечает за смену текстур | |
//класс для настройки камеры | |
class CustomCamera : public Camera | |
{ | |
public: | |
//дистанция камеры | |
double camDist; | |
//углы поворота камеры | |
double fi1, fi2; | |
//значния масеры по умолчанию | |
CustomCamera() | |
{ | |
camDist = 15; | |
fi1 = 1; | |
fi2 = 1; | |
} | |
//считает позицию камеры, исходя из углов поворота, вызывается движком | |
void SetUpCamera() | |
{ | |
//отвечает за поворот камеры мышкой | |
lookPoint.setCoords(0, 0, 0); | |
pos.setCoords(camDist*cos(fi2)*cos(fi1), | |
camDist*cos(fi2)*sin(fi1), | |
camDist*sin(fi2)); | |
if (cos(fi2) <= 0) | |
normal.setCoords(0, 0, -1); | |
else | |
normal.setCoords(0, 0, 1); | |
LookAt(); | |
} | |
void CustomCamera::LookAt() | |
{ | |
//функция настройки камеры | |
gluLookAt(pos.X(), pos.Y(), pos.Z(), lookPoint.X(), lookPoint.Y(), lookPoint.Z(), normal.X(), normal.Y(), normal.Z()); | |
} | |
} camera; //создаем объект камеры | |
//Класс для настройки света | |
class CustomLight : public Light | |
{ | |
public: | |
CustomLight() | |
{ | |
//начальная позиция света | |
pos = Vector3(1, 1, 3); | |
} | |
//рисует сферу и линии под источником света, вызывается движком | |
void DrawLightGhismo() | |
{ | |
glDisable(GL_LIGHTING); | |
glColor3d(0.9, 0.8, 0); | |
Sphere s; | |
s.pos = pos; | |
s.scale = s.scale*0.08; | |
s.Show(); | |
if (OpenGL::isKeyPressed('G')) | |
{ | |
glColor3d(0, 0, 0); | |
//линия от источника света до окружности | |
glBegin(GL_LINES); | |
glVertex3d(pos.X(), pos.Y(), pos.Z()); | |
glVertex3d(pos.X(), pos.Y(), 0); | |
glEnd(); | |
//рисуем окруность | |
Circle c; | |
c.pos.setCoords(pos.X(), pos.Y(), 0); | |
c.scale = c.scale*1.5; | |
c.Show(); | |
} | |
} | |
void SetUpLight() | |
{ | |
GLfloat amb[] = { 0.2, 0.2, 0.2, 0 }; | |
GLfloat dif[] = { 1.0, 1.0, 1.0, 0 }; | |
GLfloat spec[] = { .7, .7, .7, 0 }; | |
GLfloat position[] = { pos.X(), pos.Y(), pos.Z(), 1. }; | |
// параметры источника света | |
glLightfv(GL_LIGHT0, GL_POSITION, position); | |
// характеристики излучаемого света | |
// фоновое освещение (рассеянный свет) | |
glLightfv(GL_LIGHT0, GL_AMBIENT, amb); | |
// диффузная составляющая света | |
glLightfv(GL_LIGHT0, GL_DIFFUSE, dif); | |
// зеркально отражаемая составляющая света | |
glLightfv(GL_LIGHT0, GL_SPECULAR, spec); | |
glEnable(GL_LIGHT0); | |
} | |
} light; //создаем источник света | |
//старые координаты мыши | |
int mouseX = 0, mouseY = 0; | |
void mouseEvent(OpenGL *ogl, int mX, int mY) | |
{ | |
int dx = mouseX - mX; | |
int dy = mouseY - mY; | |
mouseX = mX; | |
mouseY = mY; | |
//меняем углы камеры при нажатой левой кнопке мыши | |
if (OpenGL::isKeyPressed(VK_RBUTTON)) | |
{ | |
camera.fi1 += 0.01*dx; | |
camera.fi2 += -0.01*dy; | |
} | |
//двигаем свет по плоскости, в точку где мышь | |
if (OpenGL::isKeyPressed('G') && !OpenGL::isKeyPressed(VK_LBUTTON)) | |
{ | |
LPPOINT POINT = new tagPOINT(); | |
GetCursorPos(POINT); | |
ScreenToClient(ogl->getHwnd(), POINT); | |
POINT->y = ogl->getHeight() - POINT->y; | |
Ray r = camera.getLookRay(POINT->x, POINT->y); | |
double z = light.pos.Z(); | |
double k = 0, x = 0, y = 0; | |
if (r.direction.Z() == 0) | |
k = 0; | |
else | |
k = (z - r.origin.Z()) / r.direction.Z(); | |
x = k*r.direction.X() + r.origin.X(); | |
y = k*r.direction.Y() + r.origin.Y(); | |
light.pos = Vector3(x, y, z); | |
} | |
if (OpenGL::isKeyPressed('G') && OpenGL::isKeyPressed(VK_LBUTTON)) | |
{ | |
light.pos = light.pos + Vector3(0, 0, 0.02*dy); | |
} | |
} | |
void mouseWheelEvent(OpenGL *ogl, int delta) | |
{ | |
if (delta < 0 && camera.camDist <= 1) | |
return; | |
if (delta > 0 && camera.camDist >= 100) | |
return; | |
camera.camDist += 0.01*delta; | |
} | |
void keyDownEvent(OpenGL *ogl, int key) | |
{ | |
if (key == 'L') | |
{ | |
lightMode = !lightMode; | |
} | |
if (key == 'T') | |
{ | |
textureMode = !textureMode; | |
} | |
if (key == 'R') | |
{ | |
camera.fi1 = 1; | |
camera.fi2 = 1; | |
camera.camDist = 15; | |
light.pos = Vector3(1, 1, 3); | |
} | |
if (key == 'F') | |
{ | |
light.pos = camera.pos; | |
} | |
if (key == 'E') // (Н) Смена текстуры происходит по этой кнопке | |
{ | |
textureReplace = !textureReplace; | |
} | |
} | |
void keyUpEvent(OpenGL *ogl, int key) | |
{ | |
} | |
GLuint texId; | |
GLuint texId2; // (Н) Я хз как по другому делать, поэтому я просто скопировал часть кода, ко всем переменным в конце добавил "2", и всё работает | |
//выполняется перед первым рендером | |
void initRender(OpenGL *ogl) | |
{ | |
//настройка текстур | |
//4 байта на хранение пикселя | |
glPixelStorei(GL_UNPACK_ALIGNMENT, 4); | |
//настройка режима наложения текстур | |
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); | |
//включаем текстуры | |
glEnable(GL_TEXTURE_2D); | |
//массив трехбайтных элементов (R G B) (Н) Код брался и копировался отсюда | |
RGBTRIPLE *texarray; | |
//массив символов, (высота*ширина*4 4, потомучто выше, мы указали использовать по 4 байта на пиксель текстуры - R G B A) | |
char *texCharArray; | |
int texW, texH; | |
OpenGL::LoadBMP("texture.bmp", &texW, &texH, &texarray); // (Н) Чтоб не мучаться с картинками, я коприовал старую и рисовал на ней | |
OpenGL::RGBtoChar(texarray, texW, texH, &texCharArray); | |
//генерируем ИД для текстуры | |
glGenTextures(1, &texId); | |
//биндим айдишник, все что будет происходить с текстурой, будте происходить по этому ИД | |
glBindTexture(GL_TEXTURE_2D, texId); | |
//загружаем текстуру в видеопямять, в оперативке нам больше она не нужна | |
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, texW, texH, 0, GL_RGBA, GL_UNSIGNED_BYTE, texCharArray); | |
//отчистка памяти | |
free(texCharArray); | |
free(texarray); | |
//наводим шмон | |
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); | |
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); | |
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); | |
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); // (Н) И досюда | |
//массив трехбайтных элементов (R G B) | |
RGBTRIPLE* texarray2; | |
//массив символов, (высота*ширина*4 4, потомучто выше, мы указали использовать по 4 байта на пиксель текстуры - R G B A) | |
char* texCharArray2; | |
int texW2, texH2; | |
OpenGL::LoadBMP("texture1.bmp", &texW2, &texH2, &texarray2); | |
OpenGL::RGBtoChar(texarray2, texW2, texH2, &texCharArray2); | |
//генерируем ИД для текстуры | |
glGenTextures(1, &texId2); | |
//биндим айдишник, все что будет происходить с текстурой, будте происходить по этому ИД | |
glBindTexture(GL_TEXTURE_2D, texId2); | |
//загружаем текстуру в видеопямять, в оперативке нам больше она не нужна | |
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, texW2, texH2, 0, GL_RGBA, GL_UNSIGNED_BYTE, texCharArray2); | |
//отчистка памяти | |
free(texCharArray2); | |
free(texarray2); | |
//наводим шмон | |
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); | |
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); | |
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); | |
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); | |
//камеру и свет привязываем к "движку" | |
ogl->mainCamera = &camera; | |
ogl->mainLight = &light; | |
// нормализация нормалей : их длины будет равна 1 | |
glEnable(GL_NORMALIZE); | |
// устранение ступенчатости для линий | |
glEnable(GL_LINE_SMOOTH); | |
// задать параметры освещения | |
// параметр GL_LIGHT_MODEL_TWO_SIDE - | |
// 0 - лицевые и изнаночные рисуются одинаково(по умолчанию), | |
// 1 - лицевые и изнаночные обрабатываются разными режимами | |
// соответственно лицевым и изнаночным свойствам материалов. | |
// параметр GL_LIGHT_MODEL_AMBIENT - задать фоновое освещение, | |
// не зависящее от сточников | |
// по умолчанию (0.2, 0.2, 0.2, 1.0) | |
glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, 0); | |
camera.fi1 = -1.3; | |
camera.fi2 = 0.8; | |
} | |
void crossProduct( double vec1[3], double vec2[3], double result[3]) { | |
result[0] = vec1[1] * vec2[2] - vec1[2] * vec2[1]; | |
result[1] = vec1[2] * vec2[0] - vec1[0] * vec2[2]; | |
result[2] = vec1[0] * vec2[1] - vec1[1] * vec2[0]; | |
} | |
// Функция для нормализации вектора | |
void normalize(double vec[3]) { | |
double length = std::sqrt(vec[0] * vec[0] + vec[1] * vec[1] + vec[2] * vec[2]); | |
if (length != 0.0f) { | |
vec[0] /= length; | |
vec[1] /= length; | |
vec[2] /= length; | |
} | |
} | |
// Функция для вычисления нормали по трем векторам | |
void computeNormal(double vec1[3], double vec2[3], double vec3[3], double normal[3]) { | |
double vecA[3] = { vec2[0] - vec1[0], vec2[1] - vec1[1], vec2[2] - vec1[2] }; | |
double vecB[3] = { vec3[0] - vec1[0], vec3[1] - vec1[1], vec3[2] - vec1[2] }; | |
crossProduct(vecA, vecB, normal); | |
normalize(normal); | |
} | |
// Функция для вычисления нормали по четырем векторам | |
void computeQuadNormal( double A[3], const double B[3], double C[3], double D[3], double normal[3]) { | |
double vec1[3] = { B[0] - A[0], B[1] - A[1], B[2] - A[2] }; | |
double vec2[3] = { D[0] - A[0], D[1] - A[1], D[2] - A[2] }; | |
crossProduct(vec1, vec2, normal); | |
normalize(normal); | |
} | |
//Начало рисования квадратика станкина | |
double A[] = { 0.0, 0.0, 0.0 }; | |
double B[] = { 7, -3, 0 }; | |
double C[] = { 5, -7, 0 }; | |
double D[] = { 8, -11, 0 }; | |
double E[] = { 2, -13, 0 }; //polukrug dlya 40 | |
double F[] = { 2, -8, 0 }; //polukrug dlya 40 | |
double G[] = { -6, -7, 0 }; | |
double H[] = { 0, -6, 0 }; | |
double A1[] = { 0.0, 0.0, 5 }; | |
double B1[] = { 7, -3, 5 }; | |
double C1[] = { 5, -7, 5 }; | |
double D1[] = { 8, -11, 5 }; | |
double E1[] = { 2, -13, 5 }; //polukrug dlya 40 | |
double F1[] = { 2, -8, 5 }; //polukrug dlya 40 | |
double G1[] = { -6, -7, 5 }; | |
double H1[] = { 0, -6, 5 }; | |
double ED[] = { 4.95, -11.9, 0 }; //polukrug dlya 40 | |
double AB[] = { 4.145, 0, 0 }; //polukrug dlya 40 | |
void drawGreenCylinder() | |
{ | |
glColor3d(0, 1, 0); | |
double step = 0.1; | |
double height = 5; | |
double radius = PI * 2.0 / 2; | |
glPushMatrix(); | |
glTranslatef(ED[0], ED[1], ED[2]); | |
glRotatef(18, 0, 0, 1); | |
glBegin(GL_TRIANGLE_FAN); | |
glVertex3f(0, 0, 0); | |
glNormal3d(0, 0, -1); | |
for (double a = -PI; a <= 0; a += step) | |
{ | |
glVertex3f(radius * cos(a), radius * sin(a), 0); | |
} | |
glVertex3f(radius * cos(0), radius * sin(0), 0); | |
glEnd(); | |
/*glBegin(GL_TRIANGLE_FAN); | |
glVertex3f(0, 0, height); | |
glNormal3d(0, 0, 1); | |
for (double a = -PI; a <= 0; a += step) | |
{ | |
glVertex3f(radius * cos(a), radius * sin(a), height); | |
} | |
glVertex3f(radius * cos(0), radius * sin(0), height); | |
glEnd();*/ | |
double normal[3]; | |
double Det[] = { 0,0,0 }; | |
double Det1[] = { 0,0,5 }; | |
double N[] = { 0,0,0 }; | |
double Nl; | |
double x0 = radius * cos(PI); | |
double y0 = radius * sin(PI); | |
double tx0 = 0; | |
double ty0 = 0; | |
step = 0.0001; | |
for (double a = -PI; a <= 0; a += step) | |
{ | |
double x = radius * cos(a); | |
double y = radius * sin(a); | |
double tx = tx0 + 1.0 / 8440.0; | |
double ty = tx0 + 1.0 / 8440.0; | |
glBegin(GL_QUADS); | |
Det[0] = { x - (16 + PI * cos((a - 0.0001) * 3.141593)) }; // (Н) Это нахождение нормалей | |
Det[1] = { y - (2 + PI * 2 * sin((a - 0.0001) * 3.141593)) }; | |
N[0] = { Det[1] * Det1[2] - Det1[1] * Det[2] }; | |
N[1] = { -Det[0] * Det1[2] + Det1[0] * Det[2] }; | |
N[2] = { Det[0] * Det1[1] - Det1[0] * Det[1] }; | |
Nl = sqrt(N[0] * N[0] + N[1] * N[1] + N[2] * N[2]); | |
N[0] = { N[0] / Nl }; | |
N[1] = { N[1] / Nl }; | |
N[2] = { N[2] / Nl }; | |
glNormal3d(N[0], -N[1], N[2]); | |
glTexCoord2d(tx0, 0); // (Н) Это пиздец, нигде нет нормального гайда наложения текстуры на выпулкую плоскость | |
glVertex3d(x0, y0, 0); // (Н) Для работы с текстурами существуют текстурные координаты от 0 до 1. Если мы хотим впихнуть в условный квадрат половину текстуры мы просто вводим дробь | |
glTexCoord2d(tx, 0); // (Н) Вот здесь это и используется, я, по сути, делю текстуру на 7000 частей, и на каждый квадрат(их 7000 штук) накладываю определённую часть текстуры | |
glVertex3d(x, y, 0); // (Н) Если что не понятно спрашивайте лично, правда объяснять я не умею :p | |
glTexCoord2d(ty, 1); // (Н) Если у вас будет текстура с зарисованным правым углом(у меня такая была, лучше края не закрашывать) будут артефакты!!!!! | |
glVertex3d(x, y, 5); | |
glTexCoord2d(ty0, 1); | |
glVertex3d(x0, y0, 5); | |
glEnd(); | |
x0 = x; | |
y0 = y; | |
tx0 = tx; | |
ty0 = ty; | |
} | |
glPopMatrix(); | |
} | |
void drawPurpleCylinder() | |
{ | |
glColor3d(0.54, 0, 1); | |
double step = 0.1; | |
double height = 5; | |
double radius = PI * 2.64 / 2; | |
glPushMatrix(); | |
glTranslatef(AB[0], AB[1], AB[2]); | |
// glRotatef(-23.19, 0, 0, 1); // x = 7, y = -3 | |
double cut_angle = 2 * PI - 0.8; | |
const double finalAngle = 3 * PI / 2 + 0.05; | |
glColor3f(1, 0, 0); | |
glBegin(GL_TRIANGLE_FAN); | |
glVertex3f(-AB[0], H[1], 0); | |
glNormal3d(0, 0, -1); | |
for (double a = PI; a <= PI * 2; a += step) | |
{ | |
double px = radius * cos(a); | |
double py = radius * sin(a); | |
if (a >= PI && a <= finalAngle) | |
{ | |
glVertex3f(px, py, 0); | |
} | |
} | |
glVertex3f(radius * cos(finalAngle), radius * sin(finalAngle), 0); | |
glEnd(); | |
double normal[3]; | |
double Det[] = { 0,0,0 }; | |
double Det1[] = { 0,0,5 }; | |
double N[] = { 0,0,0 }; | |
double Nl; | |
double x0 = radius * cos(PI); | |
double y0 = radius * sin(PI); | |
double tx0 = 0; | |
double ty0 = 0; | |
step = 0.0001; | |
for (double a = PI; a <= cut_angle; a += step) { | |
double x = radius * cos(a); | |
double y = radius * sin(a); | |
double tx = tx0 + 1.0 / 7000.0; | |
double ty = tx0 + 1.0 / 7000.0; | |
glBegin(GL_QUADS); | |
Det[0] = { x - (18 + PI * cos((a - 0.0001) * 3.141593)) }; // (Н) Это нахождение нормалей | |
Det[1] = { y - (2 + PI * sin((a - 0.0001) * 3.141593)) }; | |
N[0] = { Det[1] * Det1[2] - Det1[1] * Det[2] }; | |
N[1] = { -Det[0] * Det1[2] + Det1[0] * Det[2] }; | |
N[2] = { Det[0] * Det1[1] - Det1[0] * Det[1] }; | |
Nl = sqrt(N[0] * N[0] + N[1] * N[1] + N[2] * N[2]); | |
N[0] = { N[0] / Nl }; | |
N[1] = { N[1] / Nl }; | |
N[2] = { N[2] / Nl }; | |
glNormal3d(N[0], N[1], N[2]); | |
glTexCoord2d(tx0, 0); // (Н) Это пиздец, нигде нет нормального гайда наложения текстуры на выпулкую плоскость | |
glVertex3d(x0, y0, 0); // (Н) Для работы с текстурами существуют текстурные координаты от 0 до 1. Если мы хотим впихнуть в условный квадрат половину текстуры мы просто вводим дробь | |
glTexCoord2d(tx, 0); // (Н) Вот здесь это и используется, я, по сути, делю текстуру на 7000 частей, и на каждый квадрат(их 7000 штук) накладываю определённую часть текстуры | |
glVertex3d(x, y, 0); // (Н) Если что не понятно спрашивайте лично, правда объяснять я не умею :p | |
glTexCoord2d(ty, 1); // (Н) Если у вас будет текстура с зарисованным правым углом(у меня такая была, лучше края не закрашывать) будут артефакты!!!!! | |
glVertex3d(x, y, 5); | |
glTexCoord2d(ty0, 1); | |
glVertex3d(x0, y0, 5); | |
glEnd(); | |
x0 = x; | |
y0 = y; | |
tx0 = tx; | |
ty0 = ty; | |
} | |
//glColor3d(0.54, 0, 1); // цвет стенки | |
//glBegin(GL_QUADS); | |
//glVertex3f(-AB[0], 0, 0); | |
//glVertex3f(-AB[0], 0, height); | |
//glVertex3f(radius * cos(cut_angle), radius * sin(cut_angle), height); | |
//glVertex3f(radius * cos(cut_angle), radius * sin(cut_angle), 0); | |
//glEnd(); | |
glPopMatrix(); | |
} | |
void Render(OpenGL *ogl) | |
{ | |
glDisable(GL_TEXTURE_2D); | |
glDisable(GL_LIGHTING); | |
glEnable(GL_DEPTH_TEST); | |
if (textureMode) | |
glEnable(GL_TEXTURE_2D); | |
if (lightMode) | |
glEnable(GL_LIGHTING); | |
if (textureReplace) // (Н) Здесь переключаются текстуры: textureReplace - создаётся на 20 строчке | |
glBindTexture(GL_TEXTURE_2D, texId); // (Н) Назначение кнопки на 225 | |
else | |
glBindTexture(GL_TEXTURE_2D, texId2); | |
//альфаналожение | |
glEnable(GL_BLEND); | |
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_DST_ALPHA); | |
glDisable(GL_BLEND); | |
//настройка материала | |
GLfloat amb[] = { 0.2, 0.2, 0.1, 1. }; | |
GLfloat dif[] = { 0.4, 0.65, 0.5, 1. }; | |
GLfloat spec[] = { 0.9, 0.8, 0.3, 1. }; | |
GLfloat sh = 0.1f * 256; | |
//фоновая | |
glMaterialfv(GL_FRONT, GL_AMBIENT, amb); | |
//дифузная | |
glMaterialfv(GL_FRONT, GL_DIFFUSE, dif); | |
//зеркальная | |
glMaterialfv(GL_FRONT, GL_SPECULAR, spec); | |
//размер блика | |
glMaterialf(GL_FRONT, GL_SHININESS, sh); | |
//чтоб было красиво, без квадратиков (сглаживание освещения) | |
glShadeModel(GL_SMOOTH); | |
//=================================== | |
//Прогать тут (Н) это обман, пришлось прогать не только тут | |
glColor3d(0.7, 0.7, 0.7); | |
double normal[3]; | |
//glBegin(GL_TRIANGLES); | |
//computeNormal(A, B, H, normal); | |
//glNormal3d(normal[0], normal[1], -0.01); // (Н) Это нормаль | |
//glColor3f(0.5f, 0.5f, 0.5f); | |
//glVertex3dv(A); | |
//glVertex3dv(B); | |
//glVertex3dv(H); | |
//glEnd(); | |
glBegin(GL_TRIANGLES); | |
computeNormal(B, H, C, normal); | |
glNormal3d(normal[0], normal[1], -0.01); | |
glColor3f(0.5f, 0.5f, 0.5f); | |
glVertex3dv(B); | |
glVertex3dv(H); | |
glVertex3dv(C); | |
glEnd(); | |
glBegin(GL_TRIANGLES); | |
computeNormal(D, E, C, normal); | |
glNormal3d(normal[0], normal[1], -0.01); | |
glColor3f(0.5f, 0.5f, 0.5f); | |
glVertex3dv(D); | |
glVertex3dv(E); | |
glVertex3dv(C); | |
glEnd(); | |
glBegin(GL_TRIANGLES); | |
computeNormal(C, F, E, normal); | |
glNormal3d(normal[0], normal[1], -0.01); | |
glColor3f(0.5f, 0.5f, 0.5f); | |
glVertex3dv(C); | |
glVertex3dv(F); | |
glVertex3dv(E); | |
glEnd(); | |
glBegin(GL_TRIANGLES); | |
computeNormal(G, H, C, normal); | |
glNormal3d(normal[0], normal[1], -0.01); | |
glColor3f(0.5f, 0.5f, 0.5f); | |
glVertex3dv(G); | |
glVertex3dv(H); | |
glVertex3dv(C); | |
glEnd(); | |
glBegin(GL_TRIANGLES); | |
computeNormal(C, F, G, normal); | |
glNormal3d(normal[0], normal[1], -0.01); | |
glColor3f(0.5f, 0.5f, 0.5f); | |
glVertex3dv(C); | |
glVertex3dv(F); | |
glVertex3dv(G); | |
glEnd(); | |
/*glBegin(GL_QUADS); | |
glColor3f(0.3f, 0.3f, 0.3f); | |
computeQuadNormal(A, A1, B1, B, normal); | |
glNormal3dv(normal); | |
glTexCoord2d(0, 0); | |
glVertex3dv(A); | |
glTexCoord2d(0, 1); | |
glVertex3dv(A1); | |
glTexCoord2d(1, 1); | |
glVertex3dv(B1); | |
glTexCoord2d(1, 0); | |
glVertex3dv(B); | |
glEnd();*/ | |
glBegin(GL_QUADS); | |
glColor3f(0.3f, 0.3f, 0.3f); | |
computeQuadNormal(B, B1, C1, C, normal); | |
glNormal3dv(normal); | |
glTexCoord2d(0, 0); // (Н) Это накладывается текстура (x, y) это углы текстуры, пишутся поверх углов квадратов | |
glVertex3dv(B); | |
glTexCoord2d(0, 1); | |
glVertex3dv(B1); | |
glTexCoord2d(1, 1); | |
glVertex3dv(C1); | |
glTexCoord2d(1, 0); | |
glVertex3dv(C); | |
glEnd(); | |
glBegin(GL_QUADS); | |
glColor3f(0.3f, 0.3f, 0.3f); | |
computeQuadNormal(C1, C, D, D1, normal); | |
glNormal3d(-normal[0], -normal[1], normal[2]); // 2 | |
glTexCoord2d(0, 0); | |
glVertex3dv(C1); | |
glTexCoord2d(1, 0); | |
glVertex3dv(C); | |
glTexCoord2d(1, 1); | |
glVertex3dv(D); | |
glTexCoord2d(0, 1); | |
glVertex3dv(D1); | |
glEnd(); | |
//glBegin(GL_QUADS); | |
//glColor3f(0.3f, 0.3f, 0.3f); | |
//computeQuadNormal(D1, D, E, E1, normal); | |
//glNormal3d(-normal[0], -normal[1], normal[2]); // 1 | |
//glTexCoord2d(0, 0); | |
//glVertex3dv(D1); | |
//glTexCoord2d(1, 0); | |
//glVertex3dv(D); | |
//glTexCoord2d(1, 1); | |
//glVertex3dv(E); | |
//glTexCoord2d(0, 1); | |
//glVertex3dv(E1); | |
//glEnd(); | |
glBegin(GL_QUADS); | |
glColor3f(0.3f, 0.3f, 0.3f); | |
computeQuadNormal(E, E1, F1, F, normal); | |
glNormal3dv(normal); | |
glTexCoord2d(0, 0); | |
glVertex3dv(E); | |
glTexCoord2d(1, 0); | |
glVertex3dv(E1); | |
glTexCoord2d(1, 1); | |
glVertex3dv(F1); | |
glTexCoord2d(0, 1); | |
glVertex3dv(F); | |
glEnd(); | |
glBegin(GL_QUADS); | |
glColor3f(0.3f, 0.3f, 0.3f); | |
computeQuadNormal(F, F1, G1, G, normal); | |
glNormal3dv(normal); | |
glTexCoord2d(0, 0); | |
glVertex3dv(F); | |
glTexCoord2d(0, 1); | |
glVertex3dv(F1); | |
glTexCoord2d(1, 1); | |
glVertex3dv(G1); | |
glTexCoord2d(1, 0); | |
glVertex3dv(G); | |
glEnd(); | |
glBegin(GL_QUADS); | |
glColor3f(0.3f, 0.3f, 0.3f); | |
computeQuadNormal(G, G1, H1, H, normal); | |
glNormal3dv(normal); | |
glTexCoord2d(0, 0); | |
glVertex3dv(G); | |
glTexCoord2d(0, 1); | |
glVertex3dv(G1); | |
glTexCoord2d(1, 1); | |
glVertex3dv(H1); | |
glTexCoord2d(1, 0); | |
glVertex3dv(H); | |
glEnd(); | |
glBegin(GL_QUADS); | |
glColor3f(0.3f, 0.3f, 0.3f); | |
computeQuadNormal(H, H1, A1, A, normal); | |
glNormal3dv(normal); | |
glTexCoord2d(0, 0); | |
glVertex3dv(H); | |
glTexCoord2d(0, 1); | |
glVertex3dv(H1); | |
glTexCoord2d(1, 1); | |
glVertex3dv(A1); | |
glTexCoord2d(1, 0); | |
glVertex3dv(A); | |
glEnd(); | |
drawPurpleCylinder(); | |
drawGreenCylinder(); | |
glEnable(GL_BLEND); // (Н) Здесь строится крышка. Чтоб Альфа наложение хорошо работало, то объект, который должен быть прозрачным(для этого альфа и существует) | |
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); //Должен строится в последнию очередь, иначе он будет просвечиваться "насквозь", если захотите сами поэксперементируйте | |
// (Н) Аргументы объяснять не буду, сами найдёте инфу | |
glBegin(GL_TRIANGLES); | |
computeNormal(B1, H1, C1, normal); | |
glNormal3d(normal[0], normal[1], 5); // (Н) Это нормаль | |
glColor3f(0.5f, 0.5f, 0.5f); | |
glVertex3dv(B1); | |
glVertex3dv(H1); | |
glVertex3dv(C1); | |
glEnd(); | |
glPushMatrix(); | |
glTranslatef(ED[0], ED[1], ED[2]); | |
glRotatef(18, 0, 0, 1); | |
double step = 0.1; | |
double height = 5; | |
double radius = PI * 2.0 / 2; | |
glBegin(GL_TRIANGLE_FAN); | |
glVertex3f(0, 0, height); | |
glNormal3d(0, 0, height); | |
for (double a = -PI; a <= 0; a += step) | |
{ | |
glVertex3f(radius * cos(a), radius * sin(a), height); | |
} | |
glVertex3f(radius * cos(0), radius * sin(0), height); | |
glEnd(); | |
glBegin(GL_TRIANGLES); | |
computeNormal(D1, E1, C1, normal); | |
glNormal3d(normal[0], normal[1], 5); | |
glColor3f(0.5f, 0.5f, 0.5f); | |
glVertex3dv(D1); | |
glVertex3dv(E1); | |
glVertex3dv(C1); | |
glEnd(); | |
glBegin(GL_TRIANGLES); | |
computeNormal(C1, F1, E1, normal); | |
glNormal3d(normal[0], normal[1], 5); | |
glColor3f(0.5f, 0.5f, 0.5f); | |
glVertex3dv(C1); | |
glVertex3dv(F1); | |
glVertex3dv(E1); | |
glEnd(); | |
glBegin(GL_TRIANGLES); | |
computeNormal(G1, H1, C1, normal); | |
glNormal3d(normal[0], normal[1], 5); | |
glColor3f(0.5f, 0.5f, 0.5f); | |
glVertex3dv(G1); | |
glVertex3dv(H1); | |
glVertex3dv(C1); | |
glEnd(); | |
glBegin(GL_TRIANGLES); | |
computeNormal(C1, F1, G1, normal); | |
glNormal3d(normal[0], normal[1], 5); | |
glColor3f(0.5f, 0.5f, 0.5f); | |
glVertex3dv(C1); | |
glVertex3dv(F1); | |
glVertex3dv(G1); | |
glEnd(); | |
glBegin(GL_TRIANGLES); | |
computeNormal(A1, B1, H1, normal); | |
glNormal3d(normal[0], normal[1], 5); | |
glColor3f(0.5f, 0.5f, 0.5f); | |
glVertex3dv(A1); | |
glVertex3dv(B1); | |
glVertex3dv(H1); | |
glEnd(); | |
glDisable(GL_BLEND); | |
//Круг с текстурой внизу! | |
/*glBegin(GL_POLYGON); // (Н) Круг с норм текстурой, хз как работает код взял с Overflow | |
for (double i = 0; i <= 2; i += 0.01) | |
{ | |
double x = 9 * cos(i * 3.141593); | |
double y = 9 * sin(i * 3.141593); | |
double tx = cos(i * 3.141593) * 0.5 + 0.5; // (Н) Для корректного отображения текстуры нужны эти переменные | |
double ty = sin(i * 3.141593) * 0.5 + 0.5; | |
glColor3d(0.5f, 0.5f, 0.5f); | |
glNormal3d(0, 0, 1); | |
glTexCoord2d(tx, ty); // (Н) Суюда их засовываем и всё норм | |
glVertex3d(x, y, 0); | |
} | |
glEnd(); | |
*/ | |
/*double A2[] = {4,4,4}; | |
double B2[] = { 4,-4,4 }; | |
double C2[] = { -4,-4,4 }; | |
double D2[] = { -4,4,4 }; | |
double A3[] = { 4,4,0.1 }; | |
double B3[] = { 4,-4,0.1 }; | |
double C3[] = { -4,-4,0.1 }; | |
double D3[] = { -4,4,0.1 }; | |
glEnable(GL_BLEND); | |
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); | |
glBegin(GL_QUADS); | |
glColor4f(0, 1, 0, 0.5); | |
glTexCoord2d(0, 0); | |
glVertex3dv(A2); | |
glTexCoord2d(0, 1); | |
glVertex3dv(B2); | |
glTexCoord2d(1, 1); | |
glVertex3dv(C2); | |
glTexCoord2d(1, 0); | |
glVertex3dv(D2); | |
glEnd(); | |
glDisable(GL_BLEND); | |
glBegin(GL_QUADS); | |
glColor3f(1, 0, 0); | |
glVertex3dv(A3); | |
glVertex3dv(B3); | |
glVertex3dv(C3); | |
glVertex3dv(D3); | |
glEnd();*/ | |
//Сообщение вверху экрана | |
glMatrixMode(GL_PROJECTION); //Делаем активной матрицу проекций. | |
//(всек матричные операции, будут ее видоизменять.) | |
glPushMatrix(); //сохраняем текущую матрицу проецирования (которая описывает перспективную проекцию) в стек | |
glLoadIdentity(); //Загружаем единичную матрицу | |
glOrtho(0, ogl->getWidth(), 0, ogl->getHeight(), 0, 1); //врубаем режим ортогональной проекции | |
glMatrixMode(GL_MODELVIEW); //переключаемся на модел-вью матрицу | |
glPushMatrix(); //сохраняем текущую матрицу в стек (положение камеры, фактически) | |
glLoadIdentity(); //сбрасываем ее в дефолт | |
glDisable(GL_LIGHTING); | |
GuiTextRectangle rec; //классик моего авторства для удобной работы с рендером текста. | |
rec.setSize(300, 200); | |
rec.setPosition(10, ogl->getHeight() - 200 - 10); | |
std::stringstream ss; | |
ss << "T - вкл/выкл текстур" << std::endl; | |
ss << "E - Переключение текстур" << std::endl; | |
ss << "L - вкл/выкл освещение" << std::endl; | |
ss << "F - Свет из камеры" << std::endl; | |
ss << "G - двигать свет по горизонтали" << std::endl; | |
ss << "G+ЛКМ двигать свет по вертекали" << std::endl; | |
ss << "Коорд. света: (" << light.pos.X() << ", " << light.pos.Y() << ", " << light.pos.Z() << ")" << std::endl; | |
ss << "Коорд. камеры: (" << camera.pos.X() << ", " << camera.pos.Y() << ", " << camera.pos.Z() << ")" << std::endl; | |
ss << "Параметры камеры: R=" << camera.camDist << ", fi1=" << camera.fi1 << ", fi2=" << camera.fi2 << std::endl; | |
ss << "UV-развёртка" << std::endl; | |
rec.setText(ss.str().c_str()); | |
rec.Draw(); | |
glMatrixMode(GL_PROJECTION); //восстанавливаем матрицы проекции и модел-вью обратьно из стека. | |
glPopMatrix(); | |
glMatrixMode(GL_MODELVIEW); | |
glPopMatrix(); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment