Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- //=============================================================================================
- // Szamitogepes grafika hazi feladat keret. Ervenyes 2018-tol.
- // A //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- // sorokon beluli reszben celszeru garazdalkodni, mert a tobbit ugyis toroljuk.
- // A beadott program csak ebben a fajlban lehet, a fajl 1 byte-os ASCII karaktereket tartalmazhat, BOM kihuzando.
- // Tilos:
- // - mast "beincludolni", illetve mas konyvtarat hasznalni
- // - faljmuveleteket vegezni a printf-et kiveve
- // - Mashonnan atvett programresszleteket forrasmegjeloles nelkul felhasznalni es
- // - felesleges programsorokat a beadott programban hagyni!!!!!!!
- // - felesleges kommenteket a beadott programba irni a forrasmegjelolest kommentjeit kiveve
- // ---------------------------------------------------------------------------------------------
- // A feladatot ANSI C++ nyelvu forditoprogrammal ellenorizzuk, a Visual Studio-hoz kepesti elteresekrol
- // es a leggyakoribb hibakrol (pl. ideiglenes objektumot nem lehet referencia tipusnak ertekul adni)
- // a hazibeado portal ad egy osszefoglalot.
- // ---------------------------------------------------------------------------------------------
- // A feladatmegoldasokban csak olyan OpenGL fuggvenyek hasznalhatok, amelyek az oran a feladatkiadasig elhangzottak
- // A keretben nem szereplo GLUT fuggvenyek tiltottak.
- //
- // NYILATKOZAT
- // ---------------------------------------------------------------------------------------------
- // Nev : Lakatos Dániel
- // Neptun : PRT14L
- // ---------------------------------------------------------------------------------------------
- // ezennel kijelentem, hogy a feladatot magam keszitettem, es ha barmilyen segitseget igenybe vettem vagy
- // mas szellemi termeket felhasznaltam, akkor a forrast es az atvett reszt kommentekben egyertelmuen jeloltem.
- // A forrasmegjeloles kotelme vonatkozik az eloadas foliakat es a targy oktatoi, illetve a
- // grafhazi doktor tanacsait kiveve barmilyen csatornan (szoban, irasban, Interneten, stb.) erkezo minden egyeb
- // informaciora (keplet, program, algoritmus, stb.). Kijelentem, hogy a forrasmegjelolessel atvett reszeket is ertem,
- // azok helyessegere matematikai bizonyitast tudok adni. Tisztaban vagyok azzal, hogy az atvett reszek nem szamitanak
- // a sajat kontribucioba, igy a feladat elfogadasarol a tobbi resz mennyisege es minosege alapjan szuletik dontes.
- // Tudomasul veszem, hogy a forrasmegjeloles kotelmenek megsertese eseten a hazifeladatra adhato pontokat
- // negativ elojellel szamoljak el es ezzel parhuzamosan eljaras is indul velem szemben.
- //=============================================================================================
- #define _USE_MATH_DEFINES // Van M_PI
- #include <stdio.h>
- #include <stdlib.h>
- #include <math.h>
- #include <vector>
- #if defined(__APPLE__)
- #include <GLUT/GLUT.h>
- #include <OpenGL/gl3.h>
- #include <OpenGL/glu.h>
- #else
- #if defined(WIN32) || defined(_WIN32) || defined(__WIN32__)
- #include <windows.h>
- #endif
- #include <GL/glew.h> // must be downloaded
- #include <GL/freeglut.h> // must be downloaded unless you have an Apple
- #endif
- const unsigned int windowWidth = 600, windowHeight = 600;
- // OpenGL major and minor versions
- int majorVersion = 3, minorVersion = 3;
- void getErrorInfo(unsigned int handle) {
- int logLen;
- glGetShaderiv(handle, GL_INFO_LOG_LENGTH, &logLen);
- if (logLen > 0) {
- char * log = new char[logLen];
- int written;
- glGetShaderInfoLog(handle, logLen, &written, log);
- printf("Shader log:\n%s", log);
- delete log;
- }
- }
- // check if shader could be compiled
- void checkShader(unsigned int shader, const char * message) {
- int OK;
- glGetShaderiv(shader, GL_COMPILE_STATUS, &OK);
- if (!OK) { printf("%s!\n", message); getErrorInfo(shader); }
- }
- // check if shader could be linked
- void checkLinking(unsigned int program) {
- int OK;
- glGetProgramiv(program, GL_LINK_STATUS, &OK);
- if (!OK) { printf("Failed to link shader program!\n"); getErrorInfo(program); }
- }
- // vertex shader in GLSL
- const char * vertexSource = R"(
- #version 330
- precision highp float;
- uniform mat4 MVP; // Model-View-Projection matrix in row-major format
- layout(location = 0) in vec2 vertexPosition; // Attrib Array 0
- layout(location = 1) in vec3 vertexColor; // Attrib Array 1
- out vec3 color; // output attribute
- void main() {
- color = vertexColor; // copy color from input to output
- gl_Position = vec4(vertexPosition.x, vertexPosition.y, 0, 1) * MVP; // transform to clipping space
- }
- )";
- // fragment shader in GLSL
- const char * fragmentSource = R"(
- #version 330
- precision highp float;
- in vec3 color; // variable input: interpolated color of vertex shader
- out vec4 fragmentColor; // output that goes to the raster memory as told by glBindFragDataLocation
- void main() {
- fragmentColor = vec4(color, 1);
- }
- )";
- // vertex shader in GLSL
- const char * vertexTSource = R"(
- #version 330
- precision highp float;
- uniform mat4 MVP; // Model-View-Projection matrix in row-major format
- layout(location = 0) in vec2 vertexPosition; // Attrib Array 0
- layout(location = 1) in vec2 vertexUV; // Attrib Array 1
- out vec2 texcoord; // output attribute
- void main() {
- texcoord = vertexUV; // copy color from input to output
- gl_Position = vec4(vertexPosition.x, vertexPosition.y, 0, 1) * MVP; // transform to clipping space
- }
- )";
- // fragment shader in GLSL
- const char * fragmentTSource = R"(
- #version 330
- uniform sampler2D samplerUnit;
- in vec2 texcoord; // variable input: interpolated color of vertex shader
- out vec4 fragmentColor; // output that goes to the raster memory as told by glBindFragDataLocation
- void main() {
- fragmentColor = texture(samplerUnit, vec2(texcoord.y, texcoord.x));
- }
- )";
- // row-major matrix 4x4
- struct mat4 {
- float m[4][4];
- public:
- mat4() {}
- mat4(float m00, float m01, float m02, float m03,
- float m10, float m11, float m12, float m13,
- float m20, float m21, float m22, float m23,
- float m30, float m31, float m32, float m33) {
- m[0][0] = m00; m[0][1] = m01; m[0][2] = m02; m[0][3] = m03;
- m[1][0] = m10; m[1][1] = m11; m[1][2] = m12; m[1][3] = m13;
- m[2][0] = m20; m[2][1] = m21; m[2][2] = m22; m[2][3] = m23;
- m[3][0] = m30; m[3][1] = m31; m[3][2] = m32; m[3][3] = m33;
- }
- mat4 operator*(const mat4& right) {
- mat4 result;
- for (int i = 0; i < 4; i++) {
- for (int j = 0; j < 4; j++) {
- result.m[i][j] = 0;
- for (int k = 0; k < 4; k++) result.m[i][j] += m[i][k] * right.m[k][j];
- }
- }
- return result;
- }
- mat4 operator*(float f) {
- mat4 result;
- for (int i = 0; i < 4; i++) {
- for (int j = 0; j < 4; j++) {
- result.m[i][j] = m[i][j] * f;
- }
- }
- return result;
- }
- operator float*() { return &m[0][0]; }
- };
- // 3D point in Cartesian coordinates or RGB color
- struct vec3 {
- float v[3];
- vec3(float x = 0, float y = 0, float z = 0) { v[0] = x; v[1] = y; v[2] = z; }
- float& operator[](int idx) {
- return v[idx];
- }
- const float& operator[](int idx) const {
- return v[idx];
- }
- void operator+=(const vec3& v) {
- this->v[0] += v[0];
- this->v[1] += v[1];
- this->v[2] += v[2];
- }
- vec3 operator*(const mat4& mat) {
- vec3 result;
- for (int j = 0; j < 3; j++) {
- result.v[j] = 0;
- for (int i = 0; i < 3; i++) result.v[j] += v[i] * mat.m[i][j];
- }
- return result;
- }
- vec3 operator+(const vec3& v) {
- return vec3(this->v[0] + v[0], this->v[1] + v[1], this->v[2] + v[2]);
- }
- vec3 operator-(const vec3& v) {
- return vec3(this->v[0] - v[0], this->v[1] - v[1], this->v[2] - v[2]);
- }
- vec3 operator*(const vec3& v) {
- return vec3(this->v[1] * v[2] - this->v[2] * v[1], this->v[2] * v[0] - this->v[0] * v[2], this->v[0] * v[1] - this->v[1] * v[0]);
- }
- vec3 operator*(float f) {
- return vec3(v[0] * f, v[1] * f, v[2] * f);
- }
- vec3 operator/(float f) {
- return vec3(v[0] / f, v[1] / f, v[2] / f);
- }
- };
- float dot(const vec3& left, const vec3& right) {
- return left[0] * right[0] + left[1] * right[1] + left[2] * right[2];
- }
- vec3 operator*(float f, const vec3& v) {
- return vec3(v[0] * f, v[1] * f, v[2] * f);
- }
- vec3 operator/(float f, const vec3& v) {
- return vec3(v[0] / f, v[1] / f, v[2] / f);
- }
- // 3D point in homogeneous coordinates
- struct vec4 {
- float v[4];
- vec4(float x = 0, float y = 0, float z = 0, float w = 1) {
- v[0] = x; v[1] = y; v[2] = z; v[3] = w;
- }
- vec4(vec3 const& v, float w) {
- this->v[0] = v[0]; this->v[1] = v[1]; this->v[2] = v[2]; this->v[3] = w;
- }
- vec4 operator*(const mat4& mat) {
- vec4 result;
- for (int j = 0; j < 4; j++) {
- result.v[j] = 0;
- for (int i = 0; i < 4; i++) result.v[j] += v[i] * mat.m[i][j];
- }
- return result;
- }
- };
- // 2D point in Cartesian coordinates
- struct vec2 {
- float v[2];
- vec2(float x = 0, float y = 0) { v[0] = x; v[1] = y; }
- float& operator[](int idx) {
- return v[idx];
- }
- const float& operator[](int idx) const {
- return v[idx];
- }
- float length() { return sqrtf(v[0] * v[0] + v[1] * v[1]); }
- void operator+=(const vec2& v) {
- this->v[0] += v[0];
- this->v[1] += v[1];
- }
- vec2 operator+(const vec2& v) {
- return vec2(this->v[0] + v[0], this->v[1] + v[1]);
- }
- vec2 operator-(const vec2& v) {
- return vec2(this->v[0] - v[0], this->v[1] - v[1]);
- }
- vec2 operator*(float f) {
- return vec2(v[0] * f, v[1] * f);
- }
- vec2 operator/(float f) {
- return vec2(v[0] / f, v[1] / f);
- }
- };
- vec2 operator*(float f, const vec2& v) {
- return vec2(v[0] * f, v[1] * f);
- }
- vec2 operator/(float f, const vec2& v) {
- return vec2(v[0] / f, v[1] / f);
- }
- struct Texture {
- unsigned int textureId;
- Texture(int height = 0, int width = 0, vec3* image = NULL) {
- glGenTextures(1, &textureId);
- glBindTexture(GL_TEXTURE_2D, textureId); // binding
- glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGB, GL_FLOAT, image); //Texture -> GPU
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
- }
- };
- // 2D camera
- struct Camera {
- float wCx, wCy; // center in world coordinates
- float wWx, wWy; // width and height in world coordinates
- float n = -100;
- float f = 100;
- public:
- Camera() {
- Animate(0);
- }
- mat4 V() { // view matrix: translates the center to the origin
- return mat4(1, 0, 0, 0,
- 0, 1, 0, 0,
- 0, 0, 1, 0,
- -wCx, -wCy, 0, 1);;
- }
- mat4 P() { // projection matrix: scales it to be a square of edge length 2
- return mat4(2 / wWx, 0, 0, 0,
- 0, 2 / wWy, 0, 0,
- 0, 0, 1 / (n-f), 0,
- 0, 0, (f + n) / (f - n), 1);
- }
- mat4 Vinv() { // inverse view matrix
- return mat4(1, 0, 0, 0,
- 0, 1, 0, 0,
- 0, 0, 1, 0,
- wCx, wCy, 0, 1);
- }
- mat4 Pinv() { // inverse projection matrix
- return mat4(wWx / 2, 0, 0, 0,
- 0, wWy / 2, 0, 0,
- 0, 0, 1 / (n - f), 0,
- 0, 0, (f + n) / (f - n), 1);
- }
- void Animate(float t) {
- wCx = 0; // 10 * cosf(t);
- wCy = 0;
- wWx = 20;
- wWy = 20;
- }
- };
- // 2D camera
- Camera camera;
- // handle of the shader program
- unsigned int shaderProgram;
- unsigned int shaderTProgram;
- //////////// Drawing functions :: BEGIN ////////////
- struct LagrangeCurve {
- std::vector<vec2> cps; // control pts
- std::vector<float> ts; // knots
- float L(int i, float t) {
- float Li = 1.0f;
- for (unsigned int j = 0; j < cps.size(); j++)
- if (j != i) Li *= (t - ts[j]) / (ts[i] - ts[j]);
- return Li;
- }
- public:
- void AddControlPoint(vec2 cp, float t) {
- cps.push_back(cp);
- ts.push_back(t);
- }
- vec2 r(float t) {
- vec2 rr(0, 0);
- for (unsigned int i = 0; i < cps.size(); i++) {
- rr += cps[i] * L(i, t);
- }
- return rr;
- }
- };
- void drawCircle(std::vector<vec2> &pts, std::vector<vec3> &clr, vec2 const& org = vec2(0, 0), vec3 const& color = vec3(0, 0, 0)) {
- vec2 prev;
- for (float i = 0.0f; i < M_PI * 2; i += 0.05f) {
- float x = cos(i) * 2;
- float y = sin(i) * 2;
- vec2 pos(x, y);
- if (i > 0) {
- pts.push_back(prev);
- pts.push_back(pos);
- pts.push_back(org);
- }
- prev = pos;
- }
- pts.push_back(prev);
- pts.push_back(pts[0]);
- pts.push_back(org);
- for (unsigned int i = 0; i < pts.size(); ++i) {
- clr.push_back(color);
- }
- }
- void drawLine(std::vector<vec2> &pts, std::vector<vec3> &clr, vec2 const& p1, vec2 const& p2, float str = 0.05f, vec3 const& color = vec3(0, 0, 0)) {
- float dst = sqrtf(powf((p2[0] - p1[0]), 2.0f) + powf((p2[1] - p1[1]), 2.0f));
- float sinA = (p1[1] - p2[1]) / dst;
- float cosA = (p1[0] - p2[0]) / dst;
- float x_ = str / 2 * sinA;
- float y_ = str / 2 * cosA;
- pts.push_back(vec2(p1[0] + x_, p1[1] - y_));
- pts.push_back(vec2(p1[0] - x_, p1[1] + y_));
- pts.push_back(vec2(p2[0] + x_, p2[1] - y_));
- pts.push_back(vec2(p1[0] - x_, p1[1] + y_));
- pts.push_back(vec2(p2[0] - x_, p2[1] + y_));
- pts.push_back(vec2(p2[0] + x_, p2[1] - y_));
- for (int i = 0; i < 6; ++i) {
- clr.push_back(color);
- }
- }
- //////////// Drawing functions :: END ////////////
- class Drawable {
- public:
- unsigned int vao, vbo[2];
- float sx, sy; // scaling
- float wTx, wTy; // translation
- float fiY; // rotationY
- float fiZ; // rotationZ
- mat4 Mscale;
- mat4 Mtranslate;
- mat4 MrotateY;
- mat4 MrotateZ;
- std::vector<vec2> pts;
- std::vector<vec3> clr;
- public:
- Drawable() { Animate(0); }
- void Create() {
- glGenVertexArrays(1, &vao);
- glBindVertexArray(vao);
- glGenBuffers(2, &vbo[0]);
- UpdateM();
- }
- void Draw() {
- mat4 MVPTransform = Mscale * Mtranslate * camera.V() * camera.P();
- int location = glGetUniformLocation(shaderProgram, "MVP");
- if (location >= 0) glUniformMatrix4fv(location, 1, GL_TRUE, MVPTransform);
- else printf("uniform MVP cannot be set\n");
- glBindVertexArray(vao);
- glDrawArrays(GL_TRIANGLES, 0, pts.size());
- }
- void Animate(float t) {
- sx = 0.2f;
- sy = 1;
- wTx = 0;
- wTy = 0;
- }
- void UpdateM() {
- Mscale = mat4(sx, 0, 0, 0,
- 0, sy, 0, 0,
- 0, 0, 1, 0,
- 0, 0, 0, 1);
- Mtranslate = mat4(1, 0, 0, 0,
- 0, 1, 0, 0,
- 0, 0, 1, 0,
- wTx, wTy, 0, 1);
- MrotateY = mat4(1, 0, 0, 0,
- 0, 1, 0, 0,
- 0, 0, 1, 0,
- 0, 0, 0, 1);
- MrotateZ = mat4(1, 0, 0, 0,
- 0, 1, 0, 0,
- 0, 0, 1, 0,
- 0, 0, 0, 1);
- }
- };
- bool mousePressed = false;
- vec3 cursor;
- const float D = 10.0f;
- const float DRAG = 10.0f;
- const float M = 1.0f;
- const vec3 G = vec3(0, 0, 10);
- vec3 F(vec3 pos, vec3 vcty) {
- if (mousePressed) {
- return D * (cursor - pos) - DRAG * vcty;
- }
- return vec3(0, 0, 0);
- }
- bool inSmallCircle(float x, float y) {
- float cx = 0.85f;
- float cy = 0.72f;
- float r = 0.07f;
- if (((x - cx)*(x - cx) + (y - cy)*(y - cy)) < ((r)*(r))) {
- return true;
- }
- return false;
- }
- bool inBigCircle(float x, float y) {
- float cx = 0.85f;
- float cy = 0.72f;
- float r1 = 0.1f;
- float r2 = 0.17f;
- if (((x - cx)*(x - cx) + (y - cy)*(y - cy)) < ((r2)*(r2)) && ((x - cx)*(x - cx) + (y - cy)*(y - cy)) > ((r1)*(r1))) {
- return true;
- }
- return false;
- }
- bool inParabole(float x, float y) {
- x -= 0.35f;
- if (y < (-6.7f*x*x + 0.8f*x + 0.5f)) {
- return true;
- }
- return false;
- }
- bool inEllipse(float x, float y) {
- float cx = 0.9f;
- float cy = 0.35f;
- if ((powf(((x - cx)*cosf(10.0f) + (y - cy)*sinf(10.0f)), 2) / (powf(0.17f, 2)) + powf(((y - cy)*cosf(10.0f) - (x - cx)*sinf(10.0f)), 2) / (powf(0.14f, 2))) < 1) {
- return true;
- }
- return false;
- }
- class Wing : public Drawable {
- public:
- vec3 pos;
- float fiYw;
- mat4 MrotateYw;
- std::vector<vec2> tex;
- Texture texture;
- public:
- Wing() { Animate(0); }
- void Create() {
- Drawable::Create();
- LagrangeCurve curve;
- vec2 v0(0.0f, -1.1f);
- vec2 v1(1.93f, -2.43f);
- vec2 v2(2.56f, -1.09f);
- vec2 v3(2.6f, 0.16f);
- vec2 v4(3.43f, 1.83f);
- vec2 v5(2.6f, 2.53f);
- vec2 v6(0.0f, 1.43f);
- curve.AddControlPoint(v0, 0.0f);
- curve.AddControlPoint(v1, 1 / 6.0f);
- curve.AddControlPoint(v2, 2 / 6.0f);
- curve.AddControlPoint(v3, 3 / 6.0f);
- curve.AddControlPoint(v4, 4 / 6.0f);
- curve.AddControlPoint(v5, 5 / 6.0f);
- curve.AddControlPoint(v6, 1.0f);
- float shift = 2.728842f;
- float norm = 0.160170f;
- vec2 prev;
- float step = 0.001f;
- for (float i = 0; i <= 1.0f; i += step) {
- vec2 pos = curve.r(i);
- if (i > 0) {
- pts.push_back(prev);
- pts.push_back(pos);
- pts.push_back(vec2(0.0f, 1.0f));
- tex.push_back(vec2((prev[0] + shift) * norm, (prev[1] + shift) * norm));
- tex.push_back(vec2((pos[0] + shift) * norm, (pos[1] + shift) * norm));
- tex.push_back(vec2((vec2(0.0f + shift, 1.0f + shift)[0]) * norm, (vec2(0.0f + shift, 1.0f + shift)[1]) * norm));
- }
- prev = pos;
- }
- pts.push_back(prev);
- pts.push_back(pts[0]);
- pts.push_back(vec2(0.0f, 1.0f));
- tex.push_back(vec2((prev[0] + shift) * norm, (prev[1] + shift) * norm));
- tex.push_back(vec2((pts[0][0] + shift) * norm, (pts[0][1] + shift) * norm));
- tex.push_back(vec2((vec2(0.0f + shift, 1.0f + shift)[0]) * norm, (vec2(0.0f + shift, 1.0f + shift)[1]) * norm));
- int w = 128;
- float s = 1.0f / w;
- vec3* image = new vec3[w * w];
- for (int y = 0; y < w; y++) {
- float yp = (float)y * s;
- for (int x = 0; x < w; x++) {
- float xp = (float)x * s;
- if (inSmallCircle(xp, yp)) {
- image[x * w + y] = vec3(0, 0, 0);
- }
- else if (inBigCircle(xp, yp)) {
- image[x * w + y] = vec3(183 / 255.0f, 219 / 255.0f, 1);
- }
- else if (inParabole(xp, yp)) {
- image[x * w + y] = vec3(240 / 255.0f, 78 / 255.0f, 0);
- }
- else if (inEllipse(xp, yp)) {
- image[x * w + y] = vec3(240 / 255.0f, 78 / 255.0f, 0);
- }
- else {
- image[x * w + y] = vec3(235 / 255.0f, 183 / 255.0f, 73 / 255.0f);
- }
- }
- }
- texture = Texture(w, w, image);
- delete[] image;
- glBindBuffer(GL_ARRAY_BUFFER, vbo[0]);
- glBufferData(GL_ARRAY_BUFFER, sizeof(vec2) * pts.size(), &pts[0], GL_STATIC_DRAW);
- glEnableVertexAttribArray(0);
- glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 0, NULL);
- glBindBuffer(GL_ARRAY_BUFFER, vbo[1]);
- glBufferData(GL_ARRAY_BUFFER, sizeof(vec2) * tex.size(), &tex[0], GL_STATIC_DRAW);
- glEnableVertexAttribArray(1);
- glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 0, NULL);
- }
- void Draw() {
- glBindVertexArray(vao);
- glUseProgram(shaderTProgram);
- mat4 MVPTransform = MrotateYw * Mscale * MrotateY * MrotateZ * Mtranslate * camera.V() * camera.P();
- int location = glGetUniformLocation(shaderTProgram, "MVP");
- if (location >= 0) glUniformMatrix4fv(location, 1, GL_TRUE, MVPTransform);
- else printf("uniform MVP cannot be set\n");
- int sampler = 0;
- location = glGetUniformLocation(shaderTProgram, "samplerUnit");
- glUniform1i(location, sampler);
- glActiveTexture(GL_TEXTURE0 + sampler);
- glBindTexture(GL_TEXTURE_2D, texture.textureId);
- glDrawArrays(GL_TRIANGLES, 0, pts.size());
- sx = -sx;
- UpdateM();
- MVPTransform = MrotateYw * Mscale * MrotateY * MrotateZ * Mtranslate * camera.V() * camera.P();
- location = glGetUniformLocation(shaderTProgram, "MVP");
- if (location >= 0) glUniformMatrix4fv(location, 1, GL_TRUE, MVPTransform);
- else printf("uniform MVP cannot be set\n");
- sampler = 0;
- location = glGetUniformLocation(shaderTProgram, "samplerUnit");
- glUniform1i(location, sampler);
- glActiveTexture(GL_TEXTURE0 + sampler);
- glBindTexture(GL_TEXTURE_2D, texture.textureId);
- glDrawArrays(GL_TRIANGLES, 0, pts.size());
- sx = -sx;
- UpdateM();
- glUseProgram(shaderProgram);
- }
- void Animate(float t) {
- sx = 0.8f;
- sy = 0.8f;
- wTx = pos[0];
- wTy = pos[1];
- fiYw = 0.8f * sin(4 * t);
- UpdateM();
- }
- void UpdateM() {
- Mscale = mat4(sx, 0, 0, 0,
- 0, sy, 0, 0,
- 0, 0, 1, 0,
- 0, 0, 0, 1);
- Mtranslate = mat4(1, 0, 0, 0,
- 0, 1, 0, 0,
- 0, 0, 1, 0,
- wTx, wTy, 0, 1);
- MrotateYw = mat4(cosf(fiYw), 0, -sinf(fiYw), 0,
- 0, 1, 0, 0,
- sinf(fiYw), 0, cosf(fiYw), 0,
- 0, 0, 0, 1);
- MrotateY = mat4(cosf(fiY), 0, -sinf(fiY), 0,
- 0, 1, 0, 0,
- sinf(fiY), 0, cosf(fiY), 0,
- 0, 0, 0, 1);
- MrotateZ = mat4(cosf(fiZ), sinf(fiZ), 0, 0,
- -sinf(fiZ), cosf(fiZ), 0, 0,
- 0, 0, 1, 0,
- 0, 0, 0, 1);
- }
- };
- class Butterfly : public Drawable {
- public:
- Wing wing;
- vec3 vcty;
- vec3 pos;
- public:
- Butterfly(float x = 0, float y = 0) {
- pos = vec3(x, y, 0);
- vcty = vec3(0, 0.001f, 0);
- wing.pos = pos;
- Animate(0);
- }
- void Create() {
- wing.Create();
- Drawable::Create();
- drawCircle(pts, clr, vec2(0, 0), vec3(85/255.0f, 43/255.0f, 0));
- glBindBuffer(GL_ARRAY_BUFFER, vbo[0]);
- glBufferData(GL_ARRAY_BUFFER, sizeof(vec2) * pts.size(), &pts[0], GL_STATIC_DRAW);
- glEnableVertexAttribArray(0);
- glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 0, NULL);
- glBindBuffer(GL_ARRAY_BUFFER, vbo[1]);
- glBufferData(GL_ARRAY_BUFFER, sizeof(vec3) * clr.size(), &clr[0], GL_STATIC_DRAW);
- glEnableVertexAttribArray(1);
- glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 0, NULL);
- }
- void Draw() {
- wing.Draw();
- mat4 MVPTransform = Mscale * MrotateY * MrotateZ * Mtranslate * camera.V() * camera.P();
- int location = glGetUniformLocation(shaderProgram, "MVP");
- if (location >= 0) glUniformMatrix4fv(location, 1, GL_TRUE, MVPTransform);
- else printf("uniform MVP cannot be set\n");
- glBindVertexArray(vao);
- glDrawArrays(GL_TRIANGLES, 0, pts.size());
- }
- void Animate(float t) {
- wing.Animate(t);
- sx = 0.2f;
- sy = 0.8f;
- wTx = pos[0];
- wTy = pos[1];
- float norm = sqrtf(powf(vcty[0], 2) + powf(vcty[1], 2) + powf(vcty[2], 2));
- vec3 Fbut;
- if (mousePressed) {
- Fbut = D * (cursor - pos) - M * G;
- }
- else {
- Fbut = - M * G;
- }
- vec3 j;
- float rotj;
- if (norm == 0) {
- j = vec3(0, 0, 0);
- rotj = atan2f(j[1], j[0]);
- }
- else {
- j = vcty / norm;
- rotj = atan2f(j[1], j[0]) - (float)M_PI_2;
- }
- vec3 tmp = j * Fbut;
- vec3 i = tmp / sqrtf(powf(tmp[0], 2) + powf(tmp[1], 2) + powf(tmp[2], 2));
- vec3 k = i * j;
- float rotk = atan2f(k[1], k[2]);
- fiZ = rotj;
- fiY = rotk;
- wing.fiZ = rotj;
- wing.fiY = rotk;
- UpdateM();
- }
- void UpdateM() {
- wing.UpdateM();
- Mscale = mat4(sx, 0, 0, 0,
- 0, sy, 0, 0,
- 0, 0, 1, 0,
- 0, 0, 0, 1);
- Mtranslate = mat4(1, 0, 0, 0,
- 0, 1, 0, 0,
- 0, 0, 1, 0,
- wTx, wTy, 0, 1);
- MrotateZ = mat4(cosf(fiZ), sinf(fiZ), 0, 0,
- -sinf(fiZ), cosf(fiZ), 0, 0,
- 0, 0, 1, 0,
- 0, 0, 0, 1);
- MrotateY = mat4(cosf(fiY), 0, -sinf(fiY), 0,
- 0, 1, 0, 0,
- sinf(fiY), 0, cosf(fiY), 0,
- 0, 0, 0, 1);
- }
- };
- class Leaf : public Drawable {
- public:
- Leaf() { Animate(0); }
- void Create(vec3 color) {
- Drawable::Create();
- LagrangeCurve curve;
- vec2 v0(-0.6f, 2.0f);
- vec2 v1(-1.0f, 4.0f);
- vec2 v2(-0.4f, 5.3f);
- vec2 v3(0.2f, 5.5f);
- vec2 v4(0.4f, 5.3f);
- vec2 v5(1.0f, 4.0f);
- vec2 v6(0.6f, 2.0f);
- curve.AddControlPoint(v0, 0.0f);
- curve.AddControlPoint(v1, 1 / 6.0f);
- curve.AddControlPoint(v2, 2 / 6.0f);
- curve.AddControlPoint(v3, 3 / 6.0f);
- curve.AddControlPoint(v4, 4 / 6.0f);
- curve.AddControlPoint(v5, 5 / 6.0f);
- curve.AddControlPoint(v6, 1.0f);
- vec2 prev;
- float step = 0.001f;
- for (float i = 0; i <= 1.0f; i += step) {
- vec2 pos = curve.r(i);
- if (i > 0) {
- pts.push_back(prev);
- pts.push_back(pos);
- pts.push_back(vec2(0, 0));
- }
- prev = pos;
- }
- pts.push_back(prev);
- pts.push_back(pts[0]);
- pts.push_back(vec2(0, 0));
- for (unsigned int i = 0; i < pts.size(); ++i) {
- clr.push_back(color);
- }
- glBindBuffer(GL_ARRAY_BUFFER, vbo[0]);
- glBufferData(GL_ARRAY_BUFFER, sizeof(vec2) * pts.size(), &pts[0], GL_STATIC_DRAW);
- glEnableVertexAttribArray(0);
- glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 0, NULL);
- glBindBuffer(GL_ARRAY_BUFFER, vbo[1]);
- glBufferData(GL_ARRAY_BUFFER, sizeof(vec3) * clr.size(), &clr[0], GL_STATIC_DRAW);
- glEnableVertexAttribArray(1);
- glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 0, NULL);
- }
- void Animate(float t) {
- sx = 0.5;
- sy = 0.5;
- UpdateM();
- }
- void UpdateM() {
- MrotateZ = mat4(cosf(fiZ), sinf(fiZ), 0, 0,
- -sinf(fiZ), cosf(fiZ), 0, 0,
- 0, 0, 1, 0,
- 0, 0, 0, 1);
- }
- void Draw(int leaves) {
- mat4 MVPTransform;
- float step = 2.0f * (float)M_PI / (float)leaves;
- fiZ = step;
- UpdateM();
- for (int i = 0; i < leaves; ++i) {
- MVPTransform = MrotateZ * Mscale * Mtranslate * camera.V() * camera.P();
- int location = glGetUniformLocation(shaderProgram, "MVP");
- if (location >= 0) glUniformMatrix4fv(location, 1, GL_TRUE, MVPTransform);
- else printf("uniform MVP cannot be set\n");
- glBindVertexArray(vao);
- glDrawArrays(GL_TRIANGLES, 0, pts.size());
- fiZ += step;
- UpdateM();
- }
- }
- };
- class Flower : public Drawable {
- Leaf leaf;
- int leaves;
- vec3 color;
- public:
- Flower(float x, float y, int leaves, vec3 color = vec3(1, 1, 1)) :leaves(leaves), color(color) {
- wTx = x;
- wTy = y;
- leaf.wTx = x;
- leaf.wTy = y;
- Animate(0);
- }
- void Create() {
- leaf.Create(color);
- Drawable::Create();
- drawCircle(pts, clr, vec2(0, 0), vec3(1, 1, 0));
- glBindBuffer(GL_ARRAY_BUFFER, vbo[0]);
- glBufferData(GL_ARRAY_BUFFER, sizeof(vec2) * pts.size(), &pts[0], GL_STATIC_DRAW);
- glEnableVertexAttribArray(0);
- glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 0, NULL);
- glBindBuffer(GL_ARRAY_BUFFER, vbo[1]);
- glBufferData(GL_ARRAY_BUFFER, sizeof(vec3) * clr.size(), &clr[0], GL_STATIC_DRAW);
- glEnableVertexAttribArray(1);
- glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 0, NULL);
- }
- void Animate(float t) {
- leaf.Animate(t);
- sx = 0.4f;
- sy = 0.4f;
- UpdateM();
- }
- void Draw() {
- leaf.Draw(leaves);
- mat4 MVPTransform = Mscale * Mtranslate * camera.V() * camera.P();
- int location = glGetUniformLocation(shaderProgram, "MVP");
- if (location >= 0) glUniformMatrix4fv(location, 1, GL_TRUE, MVPTransform);
- else printf("uniform MVP cannot be set\n");
- glBindVertexArray(vao);
- glDrawArrays(GL_TRIANGLES, 0, pts.size());
- }
- };
- // The virtual world
- Flower f1(-6, 6, 1, vec3(1, 128 / 255.0f, 128 / 255.0f));
- Flower f2(0, 6, 1, vec3(1, 1, 1));
- Flower f3(6, 6, 2, vec3(1, 0, 128 / 255.0f));
- Flower f4(-6, -6, 3, vec3(128 / 255.0f, 0, 0));
- Flower f5(0, -6, 5, vec3(1, 0, 0));
- Flower f6(6, -6, 8, vec3(0, 0, 1));
- Butterfly bfly;
- // Initialization, create an OpenGL context
- void onInitialization() {
- glViewport(0, 0, windowWidth, windowHeight);
- // Create objects by setting up their vertex data on the GPU
- f1.Create();
- f2.Create();
- f3.Create();
- f4.Create();
- f5.Create();
- f6.Create();
- bfly.Create();
- // Create vertex shader from string
- unsigned int vertexTShader = glCreateShader(GL_VERTEX_SHADER);
- if (!vertexTShader) {
- printf("Error in vertex shader creation\n");
- exit(1);
- }
- glShaderSource(vertexTShader, 1, &vertexTSource, NULL);
- glCompileShader(vertexTShader);
- checkShader(vertexTShader, "Vertex shader error");
- // Create fragment shader from string
- unsigned int fragmentTShader = glCreateShader(GL_FRAGMENT_SHADER);
- if (!fragmentTShader) {
- printf("Error in fragment shader creation\n");
- exit(1);
- }
- glShaderSource(fragmentTShader, 1, &fragmentTSource, NULL);
- glCompileShader(fragmentTShader);
- checkShader(fragmentTShader, "Fragment shader error");
- // Attach shaders to a single program
- shaderTProgram = glCreateProgram();
- if (!shaderTProgram) {
- printf("Error in shader program creation\n");
- exit(1);
- }
- glAttachShader(shaderTProgram, vertexTShader);
- glAttachShader(shaderTProgram, fragmentTShader);
- // Connect the fragmentColor to the frame buffer memory
- glBindFragDataLocation(shaderTProgram, 0, "fragmentColor"); // fragmentColor goes to the frame buffer memory
- // program packaging
- glLinkProgram(shaderTProgram);
- checkLinking(shaderTProgram);
- glUseProgram(shaderTProgram);
- // Create vertex shader from string
- unsigned int vertexShader = glCreateShader(GL_VERTEX_SHADER);
- if (!vertexShader) {
- printf("Error in vertex shader creation\n");
- exit(1);
- }
- glShaderSource(vertexShader, 1, &vertexSource, NULL);
- glCompileShader(vertexShader);
- checkShader(vertexShader, "Vertex shader error");
- // Create fragment shader from string
- unsigned int fragmentShader = glCreateShader(GL_FRAGMENT_SHADER);
- if (!fragmentShader) {
- printf("Error in fragment shader creation\n");
- exit(1);
- }
- glShaderSource(fragmentShader, 1, &fragmentSource, NULL);
- glCompileShader(fragmentShader);
- checkShader(fragmentShader, "Fragment shader error");
- // Attach shaders to a single program
- shaderProgram = glCreateProgram();
- if (!shaderProgram) {
- printf("Error in shader program creation\n");
- exit(1);
- }
- glAttachShader(shaderProgram, vertexShader);
- glAttachShader(shaderProgram, fragmentShader);
- // Connect the fragmentColor to the frame buffer memory
- glBindFragDataLocation(shaderProgram, 0, "fragmentColor"); // fragmentColor goes to the frame buffer memory
- // program packaging
- glLinkProgram(shaderProgram);
- checkLinking(shaderProgram);
- // make this program run
- glUseProgram(shaderProgram);
- }
- void onExit() {
- glDeleteProgram(shaderProgram);
- glDeleteProgram(shaderTProgram);
- printf("exit");
- }
- // Window has become invalid: Redraw
- void onDisplay() {
- glClearColor(0, 180/255.0f, 0, 1.0f); // background color
- glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // clear the screen
- f1.Draw();
- f2.Draw();
- f3.Draw();
- f4.Draw();
- f5.Draw();
- f6.Draw();
- bfly.Draw();
- glutSwapBuffers(); // exchange the two buffers
- }
- // Key of ASCII code pressed
- void onKeyboard(unsigned char key, int pX, int pY) {
- if (key == 'd') glutPostRedisplay(); // if d, invalidate display, i.e. redraw
- }
- // Key of ASCII code released
- void onKeyboardUp(unsigned char key, int pX, int pY) {
- }
- // Mouse click event
- void onMouse(int button, int state, int pX, int pY) {
- if (button == GLUT_LEFT_BUTTON && state == GLUT_DOWN) { // GLUT_LEFT_BUTTON / GLUT_RIGHT_BUTTON and GLUT_DOWN / GLUT_UP
- mousePressed = true;
- float cX = 2.0f * pX / windowWidth - 1; // flip y axis
- float cY = 1.0f - 2.0f * pY / windowHeight;
- vec3 wVertex = vec3(cX, cY) * camera.Pinv() * camera.Vinv();
- cursor = wVertex;
- glutPostRedisplay(); // redraw
- }
- if (button == GLUT_LEFT_BUTTON && state == GLUT_UP) { // GLUT_LEFT_BUTTON / GLUT_RIGHT_BUTTON and GLUT_DOWN / GLUT_UP
- mousePressed = false;
- glutPostRedisplay(); // redraw
- }
- }
- // Move mouse with key pressed
- void onMouseMotion(int pX, int pY) {
- float cX = 2.0f * pX / windowWidth - 1; // flip y axis
- float cY = 1.0f - 2.0f * pY / windowHeight;
- vec3 wVertex = vec3(cX, cY) * camera.Pinv() * camera.Vinv();
- cursor = wVertex;
- glutPostRedisplay(); // redraw
- }
- // Idle event indicating that some time elapsed: do animation here
- void onIdle() {
- static float tend = 0;
- const float dt = 0.01f; // dt is ”infinitesimal”
- float tstart = tend;
- tend = glutGet(GLUT_ELAPSED_TIME) / 1000.0f;
- bfly.Animate(tend);
- for (float t = tstart; t < tend; t += dt) {
- float Dt = fmin(dt, tend - t);
- vec3 butAccel = F(bfly.pos, bfly.vcty) / M;
- bfly.vcty += butAccel * Dt;
- bfly.pos += bfly.vcty * Dt;
- bfly.wing.pos += bfly.vcty * Dt;
- }
- glutPostRedisplay(); // redraw the scene
- }
- //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- // Do not touch the code below this line
- int main(int argc, char * argv[]) {
- glutInit(&argc, argv);
- #if !defined(__APPLE__)
- glutInitContextVersion(majorVersion, minorVersion);
- #endif
- glutInitWindowSize(windowWidth, windowHeight); // Application window is initially of resolution 600x600
- glutInitWindowPosition(100, 100); // Relative location of the application window
- #if defined(__APPLE__)
- glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE | GLUT_DEPTH | GLUT_3_3_CORE_PROFILE); // 8 bit R,G,B,A + double buffer + depth buffer
- #else
- glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE | GLUT_DEPTH);
- #endif
- glutCreateWindow(argv[0]);
- #if !defined(__APPLE__)
- glewExperimental = true; // magic
- glewInit();
- #endif
- printf("GL Vendor : %s\n", glGetString(GL_VENDOR));
- printf("GL Renderer : %s\n", glGetString(GL_RENDERER));
- printf("GL Version (string) : %s\n", glGetString(GL_VERSION));
- glGetIntegerv(GL_MAJOR_VERSION, &majorVersion);
- glGetIntegerv(GL_MINOR_VERSION, &minorVersion);
- printf("GL Version (integer) : %d.%d\n", majorVersion, minorVersion);
- printf("GLSL Version : %s\n", glGetString(GL_SHADING_LANGUAGE_VERSION));
- onInitialization();
- glutDisplayFunc(onDisplay); // Register event handlers
- glutMouseFunc(onMouse);
- glutIdleFunc(onIdle);
- glutKeyboardFunc(onKeyboard);
- glutKeyboardUpFunc(onKeyboardUp);
- glutMotionFunc(onMouseMotion);
- glutMainLoop();
- onExit();
- return 1;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement