OpenGL.Project2.Bezier Curve

来源:互联网 发布:淘宝评论不能上传图片 编辑:程序博客网 时间:2024/06/05 06:50

这次的OpenGL的project是完成了Bezeir曲线的生成,主要是两种方式。

第一种是不断地递归生成一些点,去逼近。

第二种是应用de casterjau算法生成Bezier曲线。

上代码了

// Include standard headers#include <stdio.h>#include <stdlib.h>#include <vector>#include <array>#include <sstream>#include <iostream>#include <math.h>// Include GLEW#include <GL/glew.h>// Include GLFW#include <glfw3.h>// Include GLM#include <glm/glm.hpp>#include <glm/gtc/matrix_transform.hpp>#include <glm/gtc/quaternion.hpp>#include <glm/gtx/quaternion.hpp>using namespace glm;// Include AntTweakBar#include <AntTweakBar.h>#include <common/shader.hpp>#include <common/controls.hpp>#include <common/objloader.hpp>#include <common/vboindexer.hpp>using namespace std;typedef struct Vertex {float XYZW[4];float RGBA[4];void SetCoords(float *coords) {XYZW[0] = coords[0];XYZW[1] = coords[1];XYZW[2] = coords[2];XYZW[3] = coords[3];}void SetColor(float *color) {RGBA[0] = color[0];RGBA[1] = color[1];RGBA[2] = color[2];RGBA[3] = color[3];}};// ATTN: USE POINT STRUCTS FOR EASIER COMPUTATIONStypedef struct point {float x, y, z;point(const float x = 0, const float y = 0, const float z = 0) : x(x), y(y), z(z){};point(float *coords) : x(coords[0]), y(coords[1]), z(coords[2]){};point operator -(const point& a)const {return point(x - a.x, y - a.y, z - a.z);}point operator +(const point& a)const {return point(x + a.x, y + a.y, z + a.z);}point operator *(const float& a)const {return point(x*a, y*a, z*a);}point operator /(const float& a)const {return point(x / a, y / a, z / a);}float* toArray() {float array[] = { x, y, z, 1.0f };return array;}};// function prototypesint initWindow(void);void initOpenGL(void);void createVAOs(Vertex[], unsigned short[], size_t, size_t, int);void createObjects(void);void pickVertex(void);void moveVertex(void);void drawScene(void);void cleanup(void);static void mouseCallback(GLFWwindow*, int, int, int);// GLOBAL VARIABLESGLFWwindow* window;const GLuint window_width = 1024, window_height = 768;glm::mat4 gProjectionMatrix;glm::mat4 gViewMatrix;GLuint gPickedIndex;std::string gMessage;GLuint programID;GLuint pickingProgramID;// ATTN: INCREASE THIS NUMBER AS YOU CREATE NEW OBJECTSconst GLuint NumObjects = 8;// number of different "objects" to be drawnGLuint VertexArrayId[NumObjects] = { 0,1,2,3,4,5,6,7 };GLuint VertexBufferId[NumObjects] = { 0,1,2,3,4,5,6,7 };GLuint IndexBufferId[NumObjects] = { 0,1,2,3,4,5,6,7 };size_t NumVert[NumObjects] = { 0,1,2,3,4,5,6,7 };GLuint MatrixID;GLuint ViewMatrixID;GLuint ModelMatrixID;GLuint PickingMatrixID;GLuint pickingColorArrayID;GLuint pickingColorID;GLuint LightID;// Define objectsVertex Vertices[] ={{ { 1.0f, 0.0f, 0.0f, 1.0f }, { 0.0f, 1.0f, 0.0f, 1.0f } },{ { 0.7f, 0.7f, 0.0f, 1.0f }, { 0.0f, 1.0f, 0.0f, 1.0f } },{ { 0.0f, 1.0f, 0.0f, 1.0f }, { 0.0f, 1.0f, 0.0f, 1.0f } },{ { -0.7f, 0.7f, 0.0f, 1.0f }, { 0.0f, 1.0f, 0.0f, 1.0f } },{ { -1.0f, 0.0f, 0.0f, 1.0f }, { 0.0f, 1.0f, 0.0f, 1.0f } },{ { -0.7f, -0.7f, 0.0f, 1.0f }, { 0.0f, 1.0f, 0.0f, 1.0f } },{ { 0.0f, -1.0f, 0.0f, 1.0f }, { 0.0f, 1.0f, 0.0f, 1.0f } },{ { 0.7f, -0.7f, 0.0f, 1.0f }, { 0.0f, 1.0f, 0.0f, 1.0f } },};Vertex Vertices2[] = {{ { 1.0f, 0.0f, 0.0f, 1.0f }, { 1.0f, 1.0f, 1.0f, 1.0f } },{ { 0.7f, 0.7f, 0.0f, 1.0f }, { 1.0f, 1.0f, 1.0f, 1.0f } },{ { 0.0f, 1.0f, 0.0f, 1.0f }, { 1.0f, 1.0f, 1.0f, 1.0f } },{ { -0.7f, 0.7f, 0.0f, 1.0f }, { 1.0f, 1.0f, 1.0f, 1.0f } },{ { -1.0f, 0.0f, 0.0f, 1.0f }, { 1.0f, 1.0f, 1.0f, 1.0f } },{ { -0.7f, -0.7f, 0.0f, 1.0f }, { 1.0f, 1.0f, 1.0f, 1.0f } },{ { 0.0f, -1.0f, 0.0f, 1.0f }, { 1.0f, 1.0f, 1.0f, 1.0f } },{ { 0.7f, -0.7f, 0.0f, 1.0f }, { 1.0f, 1.0f, 1.0f, 1.0f } },{ { 1.0f, 0.0f, 0.0f, 1.0f }, { 1.0f, 1.0f, 1.0f, 1.0f } },};unsigned short Indices[] = {0, 1, 2, 3, 4, 5, 6, 7};Vertex Vertices3[16];Vertex Vertices4[32];Vertex Vertices5[64];Vertex Vertices6[128];Vertex Vertices7[32];Vertex Vertices8[320];unsigned short Indices2[] = {0, 1, 2, 3, 4, 5, 6, 7,8,9,10,11,12,13,14,15};unsigned short Indices3[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31};unsigned short Indices4[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63};unsigned short Indices5[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63,64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120,121, 122, 123, 124, 125, 126, 127};unsigned short Indices6[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31};unsigned short Indices7[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65,66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123,124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174,175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225,226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, 275, 276,277, 278, 279, 280, 281, 282, 283, 284, 285, 286, 287, 288, 289, 290, 291, 292, 293, 294, 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, 305, 306, 307, 308, 309, 310, 311, 312, 313, 314, 315, 316, 317, 318, 319};Vertex sd[256];Vertex sd2[256];const size_t IndexCount = sizeof(Indices) / sizeof(unsigned short);// ATTN: DON'T FORGET TO INCREASE THE ARRAY SIZE IN THE PICKING VERTEX SHADER WHEN YOU ADD MORE PICKING COLORSfloat pickingColor[IndexCount] = { 0 / 255.0f, 1 / 255.0f, 2 / 255.0f, 3 / 255.0f, 4 / 255.0f, 5 / 255.0f, 6 / 255.0f, 7 / 255.0f };int cooot = 0; int cooot2 = 0;// ATTN: ADD YOU PER-OBJECT GLOBAL ARRAY DEFINITIONS HEREbool KeyLastFrame = GLFW_RELEASE;bool KeyLastFrame2 = GLFW_RELEASE;bool fm = true;bool fm2 = true;void createObjects(void){   //first level subdivisionfor (int i = 0; i < 8; i++){sd[i] = Vertices[i];}Vertex tmp = { { 1.0f, 0.0f, 0.0f, 1.0f }, { 0.0f, 1.0f, 0.0f, 1.0f } };Vertex tmp2 = { { 1.0f, 0.0f, 0.0f, 1.0f }, { 0.0f, 1.0f, 0.0f, 1.0f } };float cord1[4]; float cord2[4]; cord1[2] = 0.0f; cord1[3] = 1.0f; cord2[2] = 0.0f; cord2[3] = 1.0f;cord1[0] = (sd[7].XYZW[0] + 10 * sd[0].XYZW[0] + 5 * sd[1].XYZW[0]) / 16;cord1[1] = (sd[7].XYZW[1] + 10 * sd[0].XYZW[1] + 5 * sd[1].XYZW[1]) / 16;cord2[0] = (5 * sd[0].XYZW[0] + 10 * sd[1].XYZW[0] + sd[2].XYZW[0]) / 16;cord2[1] = (5 * sd[0].XYZW[1] + 10 * sd[1].XYZW[1] + sd[2].XYZW[1]) / 16;tmp.SetCoords(cord1); tmp2.SetCoords(cord2);Vertices3[2] = tmp;Vertices3[3] = tmp2;cord1[0] = (sd[6].XYZW[0] + 10 * sd[7].XYZW[0] + 5 * sd[0].XYZW[0]) / 16;cord1[1] = (sd[6].XYZW[1] + 10 * sd[7].XYZW[1] + 5 * sd[0].XYZW[1]) / 16;cord2[0] = (5 * sd[7].XYZW[0] + 10 * sd[0].XYZW[0] + sd[1].XYZW[0]) / 16;cord2[1] = (5 * sd[7].XYZW[1] + 10 * sd[0].XYZW[1] + sd[1].XYZW[1]) / 16;tmp.SetCoords(cord1); tmp2.SetCoords(cord2);Vertices3[0] = tmp;Vertices3[1] = tmp2;cord1[0] = (sd[5].XYZW[0] + 10 * sd[6].XYZW[0] + 5 * sd[7].XYZW[0]) / 16;cord1[1] = (sd[5].XYZW[1] + 10 * sd[6].XYZW[1] + 5 * sd[7].XYZW[1]) / 16;cord2[0] = (5 * sd[6].XYZW[0] + 10 * sd[7].XYZW[0] + sd[0].XYZW[0]) / 16;cord2[1] = (5 * sd[6].XYZW[1] + 10 * sd[7].XYZW[1] + sd[0].XYZW[1]) / 16;tmp.SetCoords(cord1); tmp2.SetCoords(cord2);Vertices3[14] = tmp;Vertices3[15] = tmp2;for (int i = 2; i < 7; i++){Vertex tmp = { { 1.0f, 0.0f, 0.0f, 1.0f }, { 0.0f, 1.0f, 0.0f, 1.0f } };Vertex tmp2 = { { 1.0f, 0.0f, 0.0f, 1.0f }, { 0.0f, 1.0f, 0.0f, 1.0f } };float cord1[4]; float cord2[4]; cord1[2] = 0.0f; cord1[3] = 1.0f; cord2[2] = 0.0f; cord2[3] = 1.0f;cord1[0] = (sd[i - 2].XYZW[0] + 10 * sd[i - 1].XYZW[0] + 5 * sd[i].XYZW[0])/16;cord1[1] = (sd[i - 2].XYZW[1] + 10 * sd[i - 1].XYZW[1] + 5 * sd[i].XYZW[1])/16;cord2[0] = (5*sd[i - 1].XYZW[0] + 10 * sd[i].XYZW[0] + sd[i+1].XYZW[0])/16;cord2[1] = (5*sd[i - 1].XYZW[1] + 10 * sd[i].XYZW[1] + sd[i+1].XYZW[1])/16;tmp.SetCoords(cord1); tmp2.SetCoords(cord2);Vertices3[2 * i] = tmp;Vertices3[2 * i + 1] = tmp2;}//Second level subdivisionfor (int i = 0; i < 16; i++){sd[i] = Vertices3[i];} tmp = { { 1.0f, 0.0f, 0.0f, 1.0f }, { 0.0f, 1.0f, 0.0f, 1.0f } }; tmp2 = { { 1.0f, 0.0f, 0.0f, 1.0f }, { 0.0f, 1.0f, 0.0f, 1.0f } };cord1[2] = 0.0f; cord1[3] = 1.0f; cord2[2] = 0.0f; cord2[3] = 1.0f;cord1[0] = (sd[15].XYZW[0] + 10 * sd[0].XYZW[0] + 5 * sd[1].XYZW[0]) / 16;cord1[1] = (sd[15].XYZW[1] + 10 * sd[0].XYZW[1] + 5 * sd[1].XYZW[1]) / 16;cord2[0] = (5 * sd[0].XYZW[0] + 10 * sd[1].XYZW[0] + sd[2].XYZW[0]) / 16;cord2[1] = (5 * sd[0].XYZW[1] + 10 * sd[1].XYZW[1] + sd[2].XYZW[1]) / 16;tmp.SetCoords(cord1); tmp2.SetCoords(cord2);Vertices4[2] = tmp;Vertices4[3] = tmp2;cord1[0] = (sd[14].XYZW[0] + 10 * sd[15].XYZW[0] + 5 * sd[0].XYZW[0]) / 16;cord1[1] = (sd[14].XYZW[1] + 10 * sd[15].XYZW[1] + 5 * sd[0].XYZW[1]) / 16;cord2[0] = (5 * sd[15].XYZW[0] + 10 * sd[0].XYZW[0] + sd[1].XYZW[0]) / 16;cord2[1] = (5 * sd[15].XYZW[1] + 10 * sd[0].XYZW[1] + sd[1].XYZW[1]) / 16;tmp.SetCoords(cord1); tmp2.SetCoords(cord2);Vertices4[0] = tmp;Vertices4[1] = tmp2;cord1[0] = (sd[13].XYZW[0] + 10 * sd[14].XYZW[0] + 5 * sd[15].XYZW[0]) / 16;cord1[1] = (sd[13].XYZW[1] + 10 * sd[14].XYZW[1] + 5 * sd[15].XYZW[1]) / 16;cord2[0] = (5 * sd[14].XYZW[0] + 10 * sd[15].XYZW[0] + sd[0].XYZW[0]) / 16;cord2[1] = (5 * sd[14].XYZW[1] + 10 * sd[15].XYZW[1] + sd[0].XYZW[1]) / 16;tmp.SetCoords(cord1); tmp2.SetCoords(cord2);Vertices4[30] = tmp;Vertices4[31] = tmp2;for (int i = 2; i < 15; i++){Vertex tmp = { { 1.0f, 0.0f, 0.0f, 1.0f }, { 0.0f, 1.0f, 0.0f, 1.0f } };Vertex tmp2 = { { 1.0f, 0.0f, 0.0f, 1.0f }, { 0.0f, 1.0f, 0.0f, 1.0f } };float cord1[4]; float cord2[4]; cord1[2] = 0.0f; cord1[3] = 1.0f; cord2[2] = 0.0f; cord2[3] = 1.0f;cord1[0] = (sd[i - 2].XYZW[0] + 10 * sd[i - 1].XYZW[0] + 5 * sd[i].XYZW[0]) / 16;cord1[1] = (sd[i - 2].XYZW[1] + 10 * sd[i - 1].XYZW[1] + 5 * sd[i].XYZW[1]) / 16;cord2[0] = (5 * sd[i - 1].XYZW[0] + 10 * sd[i].XYZW[0] + sd[i + 1].XYZW[0]) / 16;cord2[1] = (5 * sd[i - 1].XYZW[1] + 10 * sd[i].XYZW[1] + sd[i + 1].XYZW[1]) / 16;tmp.SetCoords(cord1); tmp2.SetCoords(cord2);Vertices4[2 * i] = tmp;Vertices4[2 * i + 1] = tmp2;}//Third level subdivisionfor (int i = 0; i < 32; i++){sd[i] = Vertices4[i];}tmp = { { 1.0f, 0.0f, 0.0f, 1.0f }, { 0.0f, 1.0f, 0.0f, 1.0f } };tmp2 = { { 1.0f, 0.0f, 0.0f, 1.0f }, { 0.0f, 1.0f, 0.0f, 1.0f } };cord1[2] = 0.0f; cord1[3] = 1.0f; cord2[2] = 0.0f; cord2[3] = 1.0f;cord1[0] = (sd[31].XYZW[0] + 10 * sd[0].XYZW[0] + 5 * sd[1].XYZW[0]) / 16;cord1[1] = (sd[31].XYZW[1] + 10 * sd[0].XYZW[1] + 5 * sd[1].XYZW[1]) / 16;cord2[0] = (5 * sd[0].XYZW[0] + 10 * sd[1].XYZW[0] + sd[2].XYZW[0]) / 16;cord2[1] = (5 * sd[0].XYZW[1] + 10 * sd[1].XYZW[1] + sd[2].XYZW[1]) / 16;tmp.SetCoords(cord1); tmp2.SetCoords(cord2);Vertices5[2] = tmp;Vertices5[3] = tmp2;cord1[0] = (sd[30].XYZW[0] + 10 * sd[31].XYZW[0] + 5 * sd[0].XYZW[0]) / 16;cord1[1] = (sd[30].XYZW[1] + 10 * sd[31].XYZW[1] + 5 * sd[0].XYZW[1]) / 16;cord2[0] = (5 * sd[31].XYZW[0] + 10 * sd[0].XYZW[0] + sd[1].XYZW[0]) / 16;cord2[1] = (5 * sd[31].XYZW[1] + 10 * sd[0].XYZW[1] + sd[1].XYZW[1]) / 16;tmp.SetCoords(cord1); tmp2.SetCoords(cord2);Vertices5[0] = tmp;Vertices5[1] = tmp2;cord1[0] = (sd[29].XYZW[0] + 10 * sd[30].XYZW[0] + 5 * sd[31].XYZW[0]) / 16;cord1[1] = (sd[29].XYZW[1] + 10 * sd[30].XYZW[1] + 5 * sd[31].XYZW[1]) / 16;cord2[0] = (5 * sd[30].XYZW[0] + 10 * sd[31].XYZW[0] + sd[0].XYZW[0]) / 16;cord2[1] = (5 * sd[30].XYZW[1] + 10 * sd[31].XYZW[1] + sd[0].XYZW[1]) / 16;tmp.SetCoords(cord1); tmp2.SetCoords(cord2);Vertices5[62] = tmp;Vertices5[63] = tmp2;for (int i = 2; i < 31; i++){Vertex tmp = { { 1.0f, 0.0f, 0.0f, 1.0f }, { 0.0f, 1.0f, 0.0f, 1.0f } };Vertex tmp2 = { { 1.0f, 0.0f, 0.0f, 1.0f }, { 0.0f, 1.0f, 0.0f, 1.0f } };float cord1[4]; float cord2[4]; cord1[2] = 0.0f; cord1[3] = 1.0f; cord2[2] = 0.0f; cord2[3] = 1.0f;cord1[0] = (sd[i - 2].XYZW[0] + 10 * sd[i - 1].XYZW[0] + 5 * sd[i].XYZW[0]) / 16;cord1[1] = (sd[i - 2].XYZW[1] + 10 * sd[i - 1].XYZW[1] + 5 * sd[i].XYZW[1]) / 16;cord2[0] = (5 * sd[i - 1].XYZW[0] + 10 * sd[i].XYZW[0] + sd[i + 1].XYZW[0]) / 16;cord2[1] = (5 * sd[i - 1].XYZW[1] + 10 * sd[i].XYZW[1] + sd[i + 1].XYZW[1]) / 16;tmp.SetCoords(cord1); tmp2.SetCoords(cord2);Vertices5[2 * i] = tmp;Vertices5[2 * i + 1] = tmp2;}//Fifth level subdivisionfor (int i = 0; i < 64; i++){sd[i] = Vertices5[i];}tmp = { { 1.0f, 0.0f, 0.0f, 1.0f }, { 0.0f, 1.0f, 0.0f, 1.0f } };tmp2 = { { 1.0f, 0.0f, 0.0f, 1.0f }, { 0.0f, 1.0f, 0.0f, 1.0f } };cord1[2] = 0.0f; cord1[3] = 1.0f; cord2[2] = 0.0f; cord2[3] = 1.0f;cord1[0] = (sd[63].XYZW[0] + 10 * sd[0].XYZW[0] + 5 * sd[1].XYZW[0]) / 16;cord1[1] = (sd[63].XYZW[1] + 10 * sd[0].XYZW[1] + 5 * sd[1].XYZW[1]) / 16;cord2[0] = (5 * sd[0].XYZW[0] + 10 * sd[1].XYZW[0] + sd[2].XYZW[0]) / 16;cord2[1] = (5 * sd[0].XYZW[1] + 10 * sd[1].XYZW[1] + sd[2].XYZW[1]) / 16;tmp.SetCoords(cord1); tmp2.SetCoords(cord2);Vertices6[2] = tmp;Vertices6[3] = tmp2;cord1[0] = (sd[62].XYZW[0] + 10 * sd[63].XYZW[0] + 5 * sd[0].XYZW[0]) / 16;cord1[1] = (sd[62].XYZW[1] + 10 * sd[63].XYZW[1] + 5 * sd[0].XYZW[1]) / 16;cord2[0] = (5 * sd[63].XYZW[0] + 10 * sd[0].XYZW[0] + sd[1].XYZW[0]) / 16;cord2[1] = (5 * sd[63].XYZW[1] + 10 * sd[0].XYZW[1] + sd[1].XYZW[1]) / 16;tmp.SetCoords(cord1); tmp2.SetCoords(cord2);Vertices6[0] = tmp;Vertices6[1] = tmp2;cord1[0] = (sd[61].XYZW[0] + 10 * sd[62].XYZW[0] + 5 * sd[63].XYZW[0]) / 16;cord1[1] = (sd[61].XYZW[1] + 10 * sd[62].XYZW[1] + 5 * sd[63].XYZW[1]) / 16;cord2[0] = (5 * sd[62].XYZW[0] + 10 * sd[63].XYZW[0] + sd[0].XYZW[0]) / 16;cord2[1] = (5 * sd[62].XYZW[1] + 10 * sd[63].XYZW[1] + sd[0].XYZW[1]) / 16;tmp.SetCoords(cord1); tmp2.SetCoords(cord2);Vertices6[126] = tmp;Vertices6[127] = tmp2;for (int i = 2; i < 63; i++){Vertex tmp = { { 1.0f, 0.0f, 0.0f, 1.0f }, { 0.0f, 1.0f, 0.0f, 1.0f } };Vertex tmp2 = { { 1.0f, 0.0f, 0.0f, 1.0f }, { 0.0f, 1.0f, 0.0f, 1.0f } };float cord1[4]; float cord2[4]; cord1[2] = 0.0f; cord1[3] = 1.0f; cord2[2] = 0.0f; cord2[3] = 1.0f;cord1[0] = (sd[i - 2].XYZW[0] + 10 * sd[i - 1].XYZW[0] + 5 * sd[i].XYZW[0]) / 16;cord1[1] = (sd[i - 2].XYZW[1] + 10 * sd[i - 1].XYZW[1] + 5 * sd[i].XYZW[1]) / 16;cord2[0] = (5 * sd[i - 1].XYZW[0] + 10 * sd[i].XYZW[0] + sd[i + 1].XYZW[0]) / 16;cord2[1] = (5 * sd[i - 1].XYZW[1] + 10 * sd[i].XYZW[1] + sd[i + 1].XYZW[1]) / 16;tmp.SetCoords(cord1); tmp2.SetCoords(cord2);Vertices6[2 * i] = tmp;Vertices6[2 * i + 1] = tmp2;}//Setting C3 Bezier control pointsfor (int i = 0; i < 8; i++){sd2[i] = Vertices[i];}tmp = { { 1.0f, 0.0f, 0.0f, 1.0f }, { 1.0f, 0.0f, 0.0f, 1.0f } };tmp2 = { { 1.0f, 0.0f, 0.0f, 1.0f }, { 1.0f, 0.0f, 0.0f, 1.0f } };Vertex tmp3 = { { 1.0f, 0.0f, 0.0f, 1.0f }, { 1.0f, 0.0f, 0.0f, 1.0f } };Vertex tmp4 = { { 1.0f, 0.0f, 0.0f, 1.0f }, { 1.0f, 0.0f, 0.0f, 1.0f } };    float cord3[4]; float cord4[4];cord1[2] = 0.0f; cord1[3] = 1.0f; cord2[2] = 0.0f; cord2[3] = 1.0f;cord3[2] = 0.0f; cord3[3] = 1.0f; cord4[2] = 0.0f; cord4[3] = 1.0f;cord1[0] = (sd2[6].XYZW[0] + 11 * sd2[7].XYZW[0] + 11 * sd2[0].XYZW[0] + sd2[1].XYZW[0]) / 24;cord1[1] = (sd2[6].XYZW[1] + 11 * sd2[7].XYZW[1] + 11 * sd2[0].XYZW[1] + sd2[1].XYZW[1]) / 24;cord2[0] = (8 * sd2[7].XYZW[0] + 14 * sd2[0].XYZW[0] + 2 * sd2[1].XYZW[0]) / 24;cord2[1] = (8 * sd2[7].XYZW[1] + 14 * sd2[0].XYZW[1] + 2 * sd2[1].XYZW[1]) / 24;cord3[0] = (4 * sd2[7].XYZW[0] + 16 * sd2[0].XYZW[0] + 4 * sd2[1].XYZW[0]) / 24;cord3[1] = (4 * sd2[7].XYZW[1] + 16 * sd2[0].XYZW[1] + 4 * sd2[1].XYZW[1]) / 24;cord4[0] = (2 * sd2[7].XYZW[0] + 14 * sd2[0].XYZW[0] + 8 * sd2[1].XYZW[0]) / 24;cord4[1] = (2 * sd2[7].XYZW[1] + 14 * sd2[0].XYZW[1] + 8 * sd2[1].XYZW[1]) / 24;tmp.SetCoords(cord1); tmp2.SetCoords(cord2); tmp3.SetCoords(cord3); tmp4.SetCoords(cord4);Vertices7[0] = tmp;Vertices7[1] = tmp2;Vertices7[2] = tmp3;Vertices7[3] = tmp4;tmp = { { 1.0f, 0.0f, 0.0f, 1.0f }, { 1.0f, 0.0f, 0.0f, 1.0f } };tmp2 = { { 1.0f, 0.0f, 0.0f, 1.0f }, { 1.0f, 0.0f, 0.0f, 1.0f } };    tmp3 = { { 1.0f, 0.0f, 0.0f, 1.0f }, { 1.0f, 0.0f, 0.0f, 1.0f } };tmp4 = { { 1.0f, 0.0f, 0.0f, 1.0f }, { 1.0f, 0.0f, 0.0f, 1.0f } };cord1[2] = 0.0f; cord1[3] = 1.0f; cord2[2] = 0.0f; cord2[3] = 1.0f;cord3[2] = 0.0f; cord3[3] = 1.0f; cord4[2] = 0.0f; cord4[3] = 1.0f;cord1[0] = (sd2[7].XYZW[0] + 11 * sd2[0].XYZW[0] + 11 * sd2[1].XYZW[0] + sd2[2].XYZW[0]) / 24;cord1[1] = (sd2[7].XYZW[1] + 11 * sd2[0].XYZW[1] + 11 * sd2[1].XYZW[1] + sd2[2].XYZW[1]) / 24;cord2[0] = (8 * sd2[0].XYZW[0] + 14 * sd2[1].XYZW[0] + 2 * sd2[2].XYZW[0]) / 24;cord2[1] = (8 * sd2[0].XYZW[1] + 14 * sd2[1].XYZW[1] + 2 * sd2[2].XYZW[1]) / 24;cord3[0] = (4 * sd2[0].XYZW[0] + 16 * sd2[1].XYZW[0] + 4 * sd2[2].XYZW[0]) / 24;cord3[1] = (4 * sd2[0].XYZW[1] + 16 * sd2[1].XYZW[1] + 4 * sd2[2].XYZW[1]) / 24;cord4[0] = (2 * sd2[0].XYZW[0] + 14 * sd2[1].XYZW[0] + 8 * sd2[2].XYZW[0]) / 24;cord4[1] = (2 * sd2[0].XYZW[1] + 14 * sd2[1].XYZW[1] + 8 * sd2[2].XYZW[1]) / 24;tmp.SetCoords(cord1); tmp2.SetCoords(cord2); tmp3.SetCoords(cord3); tmp4.SetCoords(cord4);Vertices7[4] = tmp;Vertices7[5] = tmp2;Vertices7[6] = tmp3;Vertices7[7] = tmp4;tmp = { { 1.0f, 0.0f, 0.0f, 1.0f }, { 1.0f, 0.0f, 0.0f, 1.0f } };tmp2 = { { 1.0f, 0.0f, 0.0f, 1.0f }, { 1.0f, 0.0f, 0.0f, 1.0f } };tmp3 = { { 1.0f, 0.0f, 0.0f, 1.0f }, { 1.0f, 0.0f, 0.0f, 1.0f } };tmp4 = { { 1.0f, 0.0f, 0.0f, 1.0f }, { 1.0f, 0.0f, 0.0f, 1.0f } };cord1[2] = 0.0f; cord1[3] = 1.0f; cord2[2] = 0.0f; cord2[3] = 1.0f;cord3[2] = 0.0f; cord3[3] = 1.0f; cord4[2] = 0.0f; cord4[3] = 1.0f;cord1[0] = (sd2[5].XYZW[0] + 11 * sd2[6].XYZW[0] + 11 * sd2[7].XYZW[0] + sd2[0].XYZW[0]) / 24;cord1[1] = (sd2[5].XYZW[1] + 11 * sd2[6].XYZW[1] + 11 * sd2[7].XYZW[1] + sd2[0].XYZW[1]) / 24;cord2[0] = (8 * sd2[6].XYZW[0] + 14 * sd2[7].XYZW[0] + 2 * sd2[0].XYZW[0]) / 24;cord2[1] = (8 * sd2[6].XYZW[1] + 14 * sd2[7].XYZW[1] + 2 * sd2[0].XYZW[1]) / 24;cord3[0] = (4 * sd2[6].XYZW[0] + 16 * sd2[7].XYZW[0] + 4 * sd2[0].XYZW[0]) / 24;cord3[1] = (4 * sd2[6].XYZW[1] + 16 * sd2[7].XYZW[1] + 4 * sd2[0].XYZW[1]) / 24;cord4[0] = (2 * sd2[6].XYZW[0] + 14 * sd2[7].XYZW[0] + 8 * sd2[0].XYZW[0]) / 24;cord4[1] = (2 * sd2[6].XYZW[1] + 14 * sd2[7].XYZW[1] + 8 * sd2[0].XYZW[1]) / 24;tmp.SetCoords(cord1); tmp2.SetCoords(cord2); tmp3.SetCoords(cord3); tmp4.SetCoords(cord4);Vertices7[28] = tmp;Vertices7[29] = tmp2;Vertices7[30] = tmp3;Vertices7[31] = tmp4;for (int i = 2; i < 7; i++){Vertex tmp = { { 1.0f, 0.0f, 0.0f, 1.0f }, { 1.0f, 0.0f, 0.0f, 1.0f } };Vertex tmp2 = { { 1.0f, 0.0f, 0.0f, 1.0f }, { 1.0f, 0.0f, 0.0f, 1.0f } };Vertex tmp3 = { { 1.0f, 0.0f, 0.0f, 1.0f }, { 1.0f, 0.0f, 0.0f, 1.0f } };Vertex tmp4 = { { 1.0f, 0.0f, 0.0f, 1.0f }, { 1.0f, 0.0f, 0.0f, 1.0f } };Vertex tmp5 = { { 1.0f, 0.0f, 0.0f, 1.0f }, { 1.0f, 0.0f, 0.0f, 1.0f } };float cord1[4]; float cord2[4]; float cord3[4]; float cord4[4];cord1[2] = 0.0f; cord1[3] = 1.0f; cord2[2] = 0.0f; cord2[3] = 1.0f;cord3[2] = 0.0f; cord3[3] = 1.0f; cord4[2] = 0.0f; cord4[3] = 1.0f;cord1[0] = (sd2[i - 2].XYZW[0] + 11 * sd2[i - 1].XYZW[0] + 11 * sd2[i].XYZW[0] + sd2[i + 1].XYZW[0]) / 24;cord1[1] = (sd2[i - 2].XYZW[1] + 11 * sd2[i - 1].XYZW[1] + 11 * sd2[i].XYZW[1] + sd2[i + 1].XYZW[1]) / 24;cord2[0] = (8 * sd2[i - 1].XYZW[0] + 14 * sd2[i].XYZW[0] + 2*sd2[i + 1].XYZW[0]) / 24;cord2[1] = (8 * sd2[i - 1].XYZW[1] + 14 * sd2[i].XYZW[1] + 2 * sd2[i + 1].XYZW[1]) / 24;cord3[0] = (4 * sd2[i - 1].XYZW[0] + 16 * sd2[i].XYZW[0] + 4 * sd2[i + 1].XYZW[0]) / 24;cord3[1] = (4 * sd2[i - 1].XYZW[1] + 16 * sd2[i].XYZW[1] + 4 * sd2[i + 1].XYZW[1]) / 24;cord4[0] = (2 * sd2[i - 1].XYZW[0] + 14 * sd2[i].XYZW[0] + 8 * sd2[i + 1].XYZW[0]) / 24;cord4[1] = (2 * sd2[i - 1].XYZW[1] + 14 * sd2[i].XYZW[1] + 8 * sd2[i + 1].XYZW[1]) / 24;tmp.SetCoords(cord1); tmp2.SetCoords(cord2); tmp3.SetCoords(cord3); tmp4.SetCoords(cord4);Vertices7[4 * i] = tmp;Vertices7[4 * i + 1] = tmp2;Vertices7[4 * i + 2] = tmp3;Vertices7[4 * i + 3] = tmp4;}//Bezier Curve by De Casterjau's algorithmfor (int i = 0; i < 32; i++){sd2[i] = Vertices7[i];}cord1[2] = 0.0f; cord1[3] = 1.0f;float t = 0; int x;while (t < 1){float m4 = pow(t, 4.0); float n4 = pow((1 - t), 4.0);float m3 = pow(t, 3.0); float n3 = pow((1 - t), 3.0);float m2 = pow(t, 2.0); float n2 = pow((1 - t), 2.0);float m1 = pow(t, 1.0); float n1 = pow((1 - t), 1.0);Vertex tmp = { { 1.0f, 0.0f, 0.0f, 1.0f }, { 1.0f, 1.0f, 0.0f, 1.0f } };cord1[0] = n4*sd2[28].XYZW[0] + 4 * n3*m1 * sd2[29].XYZW[0] + 6 * m2*n2 * sd2[30].XYZW[0] + 4 * m3*n1*sd2[31].XYZW[0] + m4*sd2[0].XYZW[0];cord1[1] = n4*sd2[28].XYZW[1] + 4 * n3*m1 * sd2[29].XYZW[1] + 6 * m2*n2 * sd2[30].XYZW[1] + 4 * m3*n1*sd2[31].XYZW[1] + m4*sd2[0].XYZW[1];tmp.SetCoords(cord1);x = 40 * t;Vertices8[7 * 40 + x] = tmp;t += 0.025;}for (int i = 2; i < 28; i+=4){float t = 0;while (t < 1){int q = i/4;float m4 = pow(t, 4.0); float n4 = pow((1 - t), 4.0);float m3 = pow(t, 3.0); float n3 = pow((1 - t), 3.0);float m2 = pow(t, 2.0); float n2 = pow((1 - t), 2.0);float m1 = pow(t, 1.0); float n1 = pow((1 - t), 1.0);Vertex tmp = { { 1.0f, 0.0f, 0.0f, 1.0f }, { 1.0f, 1.0f, 0.0f, 1.0f } };cord1[0] = n4*sd2[i - 2].XYZW[0] + 4 * n3*m1 * sd2[i - 1].XYZW[0] + 6 * m2*n2 * sd2[i].XYZW[0] + 4 * m3*n1*sd2[i + 1].XYZW[0] + m4*sd2[i + 2].XYZW[0];cord1[1] = n4*sd2[i - 2].XYZW[1] + 4 * n3*m1 * sd2[i - 1].XYZW[1] + 6 * m2*n2 * sd2[i].XYZW[1] + 4 * m3*n1*sd2[i + 1].XYZW[1] + m4*sd2[i + 2].XYZW[1];tmp.SetCoords(cord1);x = 40 * t;Vertices8[40*q+x] = tmp;t += 0.025;}}// ATTN: DERIVE YOUR NEW OBJECTS HERE:// each has one vertices {pos;color} and one indices array (no picking needed here)}void drawScene(void){// Dark blue backgroundglClearColor(0.0f, 0.0f, 0.4f, 0.0f);// Re-clear the screen for real renderingglClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);glUseProgram(programID);{glm::mat4 ModelMatrix = glm::mat4(1.0); // TranslationMatrix * RotationMatrix;glm::mat4 MVP = gProjectionMatrix * gViewMatrix * ModelMatrix;// Send our transformation to the currently bound shader,// in the "MVP" uniformglUniformMatrix4fv(MatrixID, 1, GL_FALSE, &MVP[0][0]);glUniformMatrix4fv(ModelMatrixID, 1, GL_FALSE, &ModelMatrix[0][0]);glUniformMatrix4fv(ViewMatrixID, 1, GL_FALSE, &gViewMatrix[0][0]);glm::vec3 lightPos = glm::vec3(4, 4, 4);glUniform3f(LightID, lightPos.x, lightPos.y, lightPos.z);glEnable(GL_PROGRAM_POINT_SIZE);glBindVertexArray(VertexArrayId[0]);// draw VerticesglBindBuffer(GL_ARRAY_BUFFER, VertexBufferId[0]);glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(Vertices), Vertices);// update buffer data//glDrawElements(GL_LINE_LOOP, NumVert[0], GL_UNSIGNED_SHORT, (void*)0);glDrawElements(GL_POINTS, NumVert[0], GL_UNSIGNED_SHORT, (void*)0);//glVertexPointer(3, GL_FIXED, 0, g_vertex_buffer_data);// ATTN: OTHER BINDING AND DRAWING COMMANDS GO HERE, one set per object://glBindVertexArray(VertexArrayId[<x>]); etc etc//Setting white lineglBindVertexArray(VertexArrayId[1]);glBindBuffer(GL_ARRAY_BUFFER, VertexBufferId[1]);glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(Vertices2), Vertices2);glDrawArrays(GL_LINE_STRIP, 0, 9);//When press '2', show and hide Bezier Curveif (fm2&&glfwGetKey(window, GLFW_KEY_2)==GLFW_PRESS){fm2 = false;cooot2++;KeyLastFrame = glfwGetKey(window, GLFW_KEY_2);}if (KeyLastFrame == GLFW_PRESS&&glfwGetKey(window, GLFW_KEY_2) == GLFW_RELEASE) fm2 = true;if (cooot2 == 1){glBindVertexArray(VertexArrayId[6]);glBindBuffer(GL_ARRAY_BUFFER, VertexBufferId[6]);glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(Vertices7), Vertices7);glDrawElements(GL_POINTS, NumVert[6], GL_UNSIGNED_SHORT, (void*)0);glBindVertexArray(VertexArrayId[7]);glBindBuffer(GL_ARRAY_BUFFER, VertexBufferId[7]);glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(Vertices8), Vertices8);glDrawElements(GL_LINE_LOOP, NumVert[7], GL_UNSIGNED_SHORT, (void*)0);}else cooot2 = 0;//When press '1', show and hide subdivision Curveif (fm&&glfwGetKey(window, GLFW_KEY_1)==GLFW_PRESS){cooot++;fm = false;KeyLastFrame2 = glfwGetKey(window, GLFW_KEY_1);}if (KeyLastFrame2 == GLFW_PRESS&&glfwGetKey(window, GLFW_KEY_1) == GLFW_RELEASE) fm = true;if (cooot == 1){glBindVertexArray(VertexArrayId[2]);glBindBuffer(GL_ARRAY_BUFFER, VertexBufferId[2]);glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(Vertices3), Vertices3);glDrawElements(GL_LINE_LOOP, NumVert[2], GL_UNSIGNED_SHORT, (void*)0);}else if (cooot == 2){glBindVertexArray(VertexArrayId[3]);glBindBuffer(GL_ARRAY_BUFFER, VertexBufferId[3]);glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(Vertices4), Vertices4);glDrawElements(GL_LINE_LOOP, NumVert[3], GL_UNSIGNED_SHORT, (void*)0);}else if (cooot == 3){glBindVertexArray(VertexArrayId[4]);glBindBuffer(GL_ARRAY_BUFFER, VertexBufferId[4]);glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(Vertices5), Vertices5);glDrawElements(GL_LINE_LOOP, NumVert[4], GL_UNSIGNED_SHORT, (void*)0);}else if (cooot == 4){glBindVertexArray(VertexArrayId[5]);glBindBuffer(GL_ARRAY_BUFFER, VertexBufferId[5]);glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(Vertices6), Vertices6);glDrawElements(GL_LINE_LOOP, NumVert[5], GL_UNSIGNED_SHORT, (void*)0);}else if (cooot == 5){ cooot = 0; }//if (glfwGetKey(window, GLFW_KEY_1) == GLFW_RELEASE) KeyLastFrame = true;glBindVertexArray(0);}glUseProgram(0);// Draw GUITwDraw();// Swap buffersglfwSwapBuffers(window);glfwPollEvents();}void pickVertex(void){// Clear the screen in whiteglClearColor(1.0f, 1.0f, 1.0f, 1.0f);glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);glUseProgram(pickingProgramID);{glm::mat4 ModelMatrix = glm::mat4(1.0); // TranslationMatrix * RotationMatrix;glm::mat4 MVP = gProjectionMatrix * gViewMatrix * ModelMatrix;// Send our transformation to the currently bound shader, in the "MVP" uniformglUniformMatrix4fv(PickingMatrixID, 1, GL_FALSE, &MVP[0][0]);glUniform1fv(pickingColorArrayID, NumVert[0], pickingColor);// here we pass in the picking marker array// Draw the pontsglEnable(GL_PROGRAM_POINT_SIZE);glBindVertexArray(VertexArrayId[0]);glBindBuffer(GL_ARRAY_BUFFER, VertexBufferId[0]);glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(Vertices), Vertices);// update buffer dataglDrawElements(GL_POINTS, NumVert[0], GL_UNSIGNED_SHORT, (void*)0);glBindVertexArray(0);}glUseProgram(0);// Wait until all the pending drawing commands are really done.// Ultra-mega-over slow !// There are usually a long time between glDrawElements() and// all the fragments completely rasterized.glFlush();glFinish();glPixelStorei(GL_UNPACK_ALIGNMENT, 1);// Read the pixel at the center of the screen.// You can also use glfwGetMousePos().// Ultra-mega-over slow too, even for 1 pixel,// because the framebuffer is on the GPU.double xpos, ypos;glfwGetCursorPos(window, &xpos, &ypos);unsigned char data[4];glReadPixels(xpos, window_height - ypos, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, data); // OpenGL renders with (0,0) on bottom, mouse reports with (0,0) on top// Convert the color back to an integer IDgPickedIndex = int(data[0]);// Uncomment these lines to see the picking shader in effect//glfwSwapBuffers(window);//continue; // skips the normal rendering}// fill this function in!void moveVertex(void){glm::mat4 ModelMatrix = glm::mat4(1.0);GLint viewport[4];double xpos, ypos;glGetIntegerv(GL_VIEWPORT, viewport);glm::vec4 vp = glm::vec4(viewport[0], viewport[1], viewport[2], viewport[3]);//move pointsglfwGetCursorPos(window, &xpos, &ypos);vec3 sd=glm::unProject(glm::vec3(xpos,ypos,0.0),ModelMatrix,gProjectionMatrix,vp);float sda[4] = { -sd[0], -sd[1], 0.0f, 1.0f };// retrieve your cursor position// get your world coordinates// move pointsif (gPickedIndex >7){ // Full white, must be the background !gMessage = "background";}else if (gPickedIndex == 0){std::ostringstream oss;oss << "point " << gPickedIndex;gMessage = oss.str();Vertices[gPickedIndex].SetCoords(sda);Vertices2[gPickedIndex].SetCoords(sda);Vertices2[8].SetCoords(sda);}else {std::ostringstream oss;oss << "point " << gPickedIndex;gMessage = oss.str();Vertices[gPickedIndex].SetCoords(sda);Vertices2[gPickedIndex].SetCoords(sda);}}int initWindow(void){// Initialise GLFWif (!glfwInit()) {fprintf(stderr, "Failed to initialize GLFW\n");return -1;}glfwWindowHint(GLFW_SAMPLES, 4);glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE);// Open a window and create its OpenGL contextwindow = glfwCreateWindow(window_width, window_height, "Liu,Bohan(66127941)", NULL, NULL);if (window == NULL) {fprintf(stderr, "Failed to open GLFW window. If you have an Intel GPU, they are not 3.3 compatible. Try the 2.1 version of the tutorials.\n");glfwTerminate();return -1;}glfwMakeContextCurrent(window);// Initialize GLEWglewExperimental = true; // Needed for core profileif (glewInit() != GLEW_OK) {fprintf(stderr, "Failed to initialize GLEW\n");return -1;}// Initialize the GUITwInit(TW_OPENGL_CORE, NULL);TwWindowSize(window_width, window_height);TwBar * GUI = TwNewBar("Picking");TwSetParam(GUI, NULL, "refresh", TW_PARAM_CSTRING, 1, "0.1");TwAddVarRW(GUI, "Last picked object", TW_TYPE_STDSTRING, &gMessage, NULL);// Set up inputsglfwSetInputMode(window, GLFW_STICKY_KEYS, GL_FALSE);glfwSetCursorPos(window, window_width / 2, window_height / 2);glfwSetMouseButtonCallback(window, mouseCallback);return 0;}void initOpenGL(void){// Dark blue backgroundglClearColor(0.0f, 0.0f, 0.4f, 0.0f);// Enable depth testglEnable(GL_DEPTH_TEST);// Accept fragment if it closer to the camera than the former oneglDepthFunc(GL_LESS);// Cull triangles which normal is not towards the cameraglEnable(GL_CULL_FACE);// Projection matrix : 45° Field of View, 4:3 ratio, display range : 0.1 unit <-> 100 units//glm::mat4 ProjectionMatrix = glm::perspective(45.0f, 4.0f / 3.0f, 0.1f, 100.0f);// Or, for an ortho camera :gProjectionMatrix = glm::ortho(-4.0f, 4.0f, -3.0f, 3.0f, 0.0f, 100.0f); // In world coordinates// Camera matrixgViewMatrix = glm::lookAt(glm::vec3(0, 0, -5), // Camera is at (4,3,3), in World Spaceglm::vec3(0, 0, 0), // and looks at the originglm::vec3(0, 1, 0)  // Head is up (set to 0,-1,0 to look upside-down));// Create and compile our GLSL program from the shadersprogramID = LoadShaders("StandardShading.vertexshader", "StandardShading.fragmentshader");pickingProgramID = LoadShaders("Picking.vertexshader", "Picking.fragmentshader");// Get a handle for our "MVP" uniformMatrixID = glGetUniformLocation(programID, "MVP");ViewMatrixID = glGetUniformLocation(programID, "V");ModelMatrixID = glGetUniformLocation(programID, "M");PickingMatrixID = glGetUniformLocation(pickingProgramID, "MVP");// Get a handle for our "pickingColorID" uniformpickingColorArrayID = glGetUniformLocation(pickingProgramID, "PickingColorArray");pickingColorID = glGetUniformLocation(pickingProgramID, "PickingColor");// Get a handle for our "LightPosition" uniformLightID = glGetUniformLocation(programID, "LightPosition_worldspace");//Create VAOS for many scenescreateVAOs(Vertices, Indices, sizeof(Vertices), sizeof(Indices), 0);createVAOs(Vertices2, Indices, sizeof(Vertices2), sizeof(Indices), 1);createObjects();    createVAOs(Vertices3, Indices2, sizeof(Vertices3), sizeof(Indices2), 2);    createVAOs(Vertices4, Indices3, sizeof(Vertices4), sizeof(Indices3), 3);    createVAOs(Vertices5, Indices4, sizeof(Vertices5), sizeof(Indices4), 4);    createVAOs(Vertices6, Indices5, sizeof(Vertices6), sizeof(Indices5), 5);createVAOs(Vertices7, Indices6, sizeof(Vertices7), sizeof(Indices6), 6);createVAOs(Vertices8, Indices7, sizeof(Vertices8), sizeof(Indices7), 7);// ATTN: create VAOs for each of the newly created objects here:// createVAOs(<fill this appropriately>);}void createVAOs(Vertex Vertices[], unsigned short Indices[], size_t BufferSize, size_t IdxBufferSize, int ObjectId) {NumVert[ObjectId] = IdxBufferSize / (sizeof GLubyte);GLenum ErrorCheckValue = glGetError();size_t VertexSize = sizeof(Vertices[0]);size_t RgbOffset = sizeof(Vertices[0].XYZW);// Create Vertex Array ObjectglGenVertexArrays(1, &VertexArrayId[ObjectId]);glBindVertexArray(VertexArrayId[ObjectId]);// Create Buffer for vertex dataglGenBuffers(1, &VertexBufferId[ObjectId]);glBindBuffer(GL_ARRAY_BUFFER, VertexBufferId[ObjectId]);glBufferData(GL_ARRAY_BUFFER, BufferSize, Vertices, GL_STATIC_DRAW);// Create Buffer for indicesglGenBuffers(1, &IndexBufferId[ObjectId]);glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, IndexBufferId[ObjectId]);glBufferData(GL_ELEMENT_ARRAY_BUFFER, IdxBufferSize, Indices, GL_STATIC_DRAW);// Assign vertex attributesglVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, VertexSize, 0);glVertexAttribPointer(1, 4, GL_FLOAT, GL_FALSE, VertexSize, (GLvoid*)RgbOffset);glEnableVertexAttribArray(0);// positionglEnableVertexAttribArray(1);// color// Disable our Vertex Buffer ObjectglBindVertexArray(0);ErrorCheckValue = glGetError();if (ErrorCheckValue != GL_NO_ERROR){fprintf(stderr,"ERROR: Could not create a VBO: %s \n",gluErrorString(ErrorCheckValue));}}void cleanup(void){// Cleanup VBO and shaderfor (int i = 0; i < NumObjects; i++) {glDeleteBuffers(1, &VertexBufferId[i]);glDeleteBuffers(1, &IndexBufferId[i]);glDeleteVertexArrays(1, &VertexArrayId[i]);}glDeleteProgram(programID);glDeleteProgram(pickingProgramID);// Close OpenGL window and terminate GLFWglfwTerminate();}static void mouseCallback(GLFWwindow* window, int button, int action, int mods){if (button == GLFW_MOUSE_BUTTON_LEFT && action == GLFW_PRESS) {pickVertex();}}int main(void){// initialize windowint errorCode = initWindow();if (errorCode != 0)return errorCode;// initialize OpenGL pipelineinitOpenGL();// For speed computationdouble lastTime = glfwGetTime();int nbFrames = 0;do {// Measure speeddouble currentTime = glfwGetTime();nbFrames++;if (currentTime - lastTime >= 1.0){ // If last prinf() was more than 1sec ago// printf and resetprintf("%f ms/frame\n", 1000.0 / double(nbFrames));nbFrames = 0;lastTime += 1.0;}// DRAGGING: move current (picked) vertex with cursorif (glfwGetMouseButton(window, GLFW_MOUSE_BUTTON_LEFT)){moveVertex();//RightMouseBUttonPressedLastFrame = glfwGetMouseButton(window, GLFW_MOUSE_BUTTON_RIGHT);}// DRAWING SCENEcreateObjects();// re-evaluate curves in case vertices have been moveddrawScene();} // Check if the ESC key was pressed or the window was closedwhile (glfwGetKey(window, GLFW_KEY_ESCAPE) != GLFW_PRESS &&glfwWindowShouldClose(window) == 0);cleanup();return 0;}

效果如图


0 0
原创粉丝点击