SHARE
TWEET

Untitled

PhoenixMee Apr 11th, 2019 108 Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. #include <iostream>
  2. #include "GL/glew.h"
  3. #include "GL/3dgl.h"
  4. #include "GL/glut.h"
  5. #include "GL/freeglut_ext.h"
  6.  
  7. #pragma comment (lib, "glew32.lib")
  8.  
  9. using namespace std;
  10. using namespace _3dgl;
  11.  
  12. //bool reverseskybox = true;
  13. //
  14. const char * skyboxtextures[6] = { "models\\skyboxfront2.jpg", "models\\skyboxleft2.jpg", "models\\skyboxback2.jpg",
  15.                                    "models\\skyboxright2.jpg", "models\\skyboxup.jpg", "models\\skyboxup2.jpg" };
  16.  
  17. // window size (used for FBO)
  18. int ScreenWidth = 800;
  19. int ScreenHeight = 600;
  20.  
  21. // 3D Models
  22. C3dglTerrain terrain, reflectedterrain, water;
  23.  
  24. // Skybox
  25. C3dglSkyBox skybox, reflectedskybox;
  26.  
  27. // texture ids
  28. GLuint idTexGrass;      // grass texture
  29. GLuint idTexSand;       // sand texture
  30. GLuint idTexWater;      // water texture
  31. GLuint idTexNone;
  32. GLuint stencilTexture, fb, depth_stencil_rb;
  33.  
  34. // particle ids
  35. GLuint idBufferVelocity;
  36. GLuint idBufferStartTime;
  37.  
  38. // GLSL Objects (Shader Program)
  39. C3dglProgram ProgramBasic;
  40. C3dglProgram ProgramWater;
  41. C3dglProgram ProgramTerrain;
  42. C3dglProgram ProgramParticle;
  43.  
  44. // Water specific variables
  45. float waterLevel = 4.6f;
  46.  
  47. // setup clipping plane array
  48. float Nx = 0, Ny = 1, Nz = 0, d = 0;
  49. float clipPlane[4] = { Nx, Ny, Nz, d };
  50.  
  51. // camera position (for first person type camera navigation)
  52. float matrixView[16];       // The View Matrix
  53. float angleTilt = 0;        // Tilt Angle
  54. float deltaX = 0, deltaY = 0, deltaZ = 0;   // Camera movement values
  55.  
  56. // world camera position (used for reflection texture)
  57. float cameraVector[3];
  58. GLfloat cameraMatrix[16];
  59.  
  60. // Particle System Params
  61. const float PERIOD = 0.000075f;                     // each recycled particle will obtain it's start time PERIOD seconds after the previous has died
  62. const float LIFETIME = 6;                           // life time of each particle
  63. const int NPARTICLES = (int)(LIFETIME / PERIOD);    // number of particles that need to be present before any new particles are born (8000, in this case)
  64.  
  65. bool init()
  66. {
  67.     // rendering states
  68.     glEnable(GL_DEPTH_TEST);    // depth test is necessary for most 3D scenes
  69.     glEnable(GL_NORMALIZE);     // normalization is needed by AssImp library models
  70.     glShadeModel(GL_SMOOTH);    // smooth shading mode is the default one; try GL_FLAT here!
  71.     glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);  // this is the default one; try GL_LINE!
  72.  
  73.     glEnable(GL_BLEND);
  74.     glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
  75.  
  76.  
  77.  
  78.     // Initialise Shaders
  79.     C3dglShader VertexShader;
  80.     C3dglShader FragmentShader;
  81.  
  82.     if (!VertexShader.Create(GL_VERTEX_SHADER)) return false;
  83.     if (!VertexShader.LoadFromFile("shaders/basic.vert")) return false;
  84.     if (!VertexShader.Compile()) return false;
  85.  
  86.     if (!FragmentShader.Create(GL_FRAGMENT_SHADER)) return false;
  87.     if (!FragmentShader.LoadFromFile("shaders/basic.frag")) return false;
  88.     if (!FragmentShader.Compile()) return false;
  89.  
  90.     if (!ProgramBasic.Create()) return false;
  91.     if (!ProgramBasic.Attach(VertexShader)) return false;
  92.     if (!ProgramBasic.Attach(FragmentShader)) return false;
  93.     if (!ProgramBasic.Link()) return false;
  94.     if (!ProgramBasic.Use(true)) return false;
  95.  
  96.     if (!VertexShader.Create(GL_VERTEX_SHADER)) return false;
  97.     if (!VertexShader.LoadFromFile("shaders/water.vert")) return false;
  98.     if (!VertexShader.Compile()) return false;
  99.  
  100.     if (!FragmentShader.Create(GL_FRAGMENT_SHADER)) return false;
  101.     if (!FragmentShader.LoadFromFile("shaders/water.frag")) return false;
  102.     if (!FragmentShader.Compile()) return false;
  103.  
  104.     if (!ProgramWater.Create()) return false;
  105.     if (!ProgramWater.Attach(VertexShader)) return false;
  106.     if (!ProgramWater.Attach(FragmentShader)) return false;
  107.     if (!ProgramWater.Link()) return false;
  108.     if (!ProgramWater.Use(true)) return false;
  109.  
  110.     if (!VertexShader.Create(GL_VERTEX_SHADER)) return false;
  111.     if (!VertexShader.LoadFromFile("shaders/terrain.vert")) return false;
  112.     if (!VertexShader.Compile()) return false;
  113.  
  114.     if (!FragmentShader.Create(GL_FRAGMENT_SHADER)) return false;
  115.     if (!FragmentShader.LoadFromFile("shaders/terrain.frag")) return false;
  116.     if (!FragmentShader.Compile()) return false;
  117.  
  118.     if (!ProgramTerrain.Create()) return false;
  119.     if (!ProgramTerrain.Attach(VertexShader)) return false;
  120.     if (!ProgramTerrain.Attach(FragmentShader)) return false;
  121.     if (!ProgramTerrain.Link()) return false;
  122.     if (!ProgramTerrain.Use(true)) return false;
  123.  
  124.     //if (!VertexShader.Create(GL_VERTEX_SHADER)) return false;
  125.     //if (!VertexShader.LoadFromFile("shaders/particle.vert")) return false;
  126.     //if (!VertexShader.Compile()) return false;
  127.  
  128.     //if (!FragmentShader.Create(GL_FRAGMENT_SHADER)) return false;
  129.     //if (!FragmentShader.LoadFromFile("shaders/particle.frag")) return false;
  130.     //if (!FragmentShader.Compile()) return false;
  131.  
  132.     //if (!ProgramParticle.Create()) return false;
  133.     //if (!ProgramParticle.Attach(VertexShader)) return false;
  134.     //if (!ProgramParticle.Attach(FragmentShader)) return false;
  135.     //if (!ProgramParticle.Link()) return false;
  136.     //if (!ProgramParticle.Use(true)) return false;
  137.  
  138.     // glut additional setup
  139.     glutSetVertexAttribCoord3(ProgramBasic.GetAttribLocation("aVertex"));
  140.     glutSetVertexAttribNormal(ProgramBasic.GetAttribLocation("aNormal"));
  141.  
  142.     // enable alpha blending
  143.     glEnable(GL_BLEND);
  144.     glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
  145.  
  146.     // load your 3D models here!
  147.     if (!terrain.loadHeightmap("models\\heightmap.png", 10)) return false;
  148.     if (!reflectedterrain.loadHeightmap("models\\heightmap.png", -10)) return false;
  149.     if (!water.loadHeightmap("models\\watermap.png", 10)) return false;
  150.     if (!skybox.load(skyboxtextures[0], skyboxtextures[1], skyboxtextures[2],
  151.         skyboxtextures[3], skyboxtextures[4], skyboxtextures[5])) return false;
  152.     if (!reflectedskybox.load("models\\skyboxback.jpg", "models\\skyboxright.jpg", "models\\skyboxfront.jpg",
  153.         "models\\skyboxleft.jpg", "models\\skyboxdown.jpg", "models\\skyboxup.jpg")) return false;
  154.  
  155.     // create & load textures
  156.     C3dglBitmap bm, bm2;
  157.     glActiveTexture(GL_TEXTURE0);
  158.    
  159.     // Grass texture
  160.     bm.Load("models/grass.png", GL_RGBA);
  161.     glGenTextures(1, &idTexGrass);
  162.     glBindTexture(GL_TEXTURE_2D, idTexGrass);
  163.     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
  164.     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, bm.GetWidth(), bm.GetHeight(), 0, GL_RGBA, GL_UNSIGNED_BYTE, bm.GetBits());
  165.  
  166.     // Sand texture
  167.     bm.Load("models/sand.png", GL_RGBA);
  168.     glGenTextures(1, &idTexSand);
  169.     glBindTexture(GL_TEXTURE_2D, idTexSand);
  170.     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
  171.     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, bm.GetWidth(), bm.GetHeight(), 0, GL_RGBA, GL_UNSIGNED_BYTE, bm.GetBits());
  172.  
  173.     // Water texture
  174.     bm.Load("models/water.png", GL_RGBA);
  175.     glGenTextures(1, &idTexWater);
  176.     glBindTexture(GL_TEXTURE_2D, idTexWater);
  177.     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
  178.     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, bm.GetWidth(), bm.GetHeight(), 0, GL_RGBA, GL_UNSIGNED_BYTE, bm.GetBits());
  179.  
  180.     // the textures to mix for terrain
  181.     glActiveTexture(GL_TEXTURE1);
  182.     glBindTexture(GL_TEXTURE_2D, idTexSand);
  183.  
  184.     glActiveTexture(GL_TEXTURE2);
  185.     glBindTexture(GL_TEXTURE_2D, idTexGrass);
  186.  
  187.     // Prepare the particle buffers
  188.     std::vector<float> bufferVelocity;
  189.     std::vector<float> bufferStartTime;
  190.     float time = 0;
  191.     float M_PI = 3.14;
  192.  
  193.     for (int i = 0; i < NPARTICLES; i++)
  194.     {
  195.         float theta = (float)M_PI / 6.f * (float)rand() / (float)RAND_MAX;
  196.         float phi = (float)M_PI * 2.f * (float)rand() / (float)RAND_MAX;
  197.         float x = sin(theta) * cos(phi);
  198.         float y = cos(theta);
  199.         float z = sin(theta) * sin(phi);
  200.         float v = 2 + 0.5f * (float)rand() / (float)RAND_MAX;
  201.  
  202.         bufferVelocity.push_back(x * v);
  203.         bufferVelocity.push_back(y * v);
  204.         bufferVelocity.push_back(z * v);
  205.         bufferStartTime.push_back(time);
  206.  
  207.         time += PERIOD;
  208.     }
  209.  
  210.     glGenBuffers(1, &idBufferVelocity);
  211.     glBindBuffer(GL_ARRAY_BUFFER, idBufferVelocity);
  212.     glBufferData(GL_ARRAY_BUFFER, sizeof(float) * bufferVelocity.size(), &bufferVelocity[0], GL_STATIC_DRAW);
  213.     glGenBuffers(1, &idBufferStartTime); glBindBuffer(GL_ARRAY_BUFFER, idBufferStartTime);
  214.     glBufferData(GL_ARRAY_BUFFER, sizeof(float) * bufferStartTime.size(), &bufferStartTime[0], GL_STATIC_DRAW);
  215.  
  216.     // send texture channel info to shaders
  217.     ProgramBasic.SendUniform("texture0", 0);
  218.     ProgramTerrain.SendUniform("texture0", 0);
  219.     ProgramWater.SendUniform("texture0", 0);
  220.     ProgramParticle.SendUniform("texture0", 0);
  221.     ProgramTerrain.SendUniform("textureUnderwater", 1);
  222.     ProgramTerrain.SendUniform("textureShore", 2);
  223.     ProgramWater.SendUniform("texture3", 3);
  224.  
  225.     // setup lights (for basic and terrain programs only, water does not use these lights)
  226.     ProgramBasic.SendUniform("lightAmbient.on", 1);
  227.     ProgramBasic.SendUniform("lightAmbient.color", 0.1, 0.1, 0.1);
  228.     ProgramBasic.SendUniform("lightDir.on", 1);
  229.     ProgramBasic.SendUniform("lightDir.direction", 1.0, 0.5, 1.0);
  230.     ProgramBasic.SendUniform("lightDir.diffuse", 1.0, 1.0, 1.0);
  231.  
  232.     ProgramTerrain.SendUniform("lightAmbient.on", 1);
  233.     ProgramTerrain.SendUniform("lightAmbient.color", 0.1, 0.1, 0.1);
  234.     ProgramTerrain.SendUniform("lightDir.on", 1);
  235.     ProgramTerrain.SendUniform("lightDir.direction", 1.0, 0.5, 1.0);
  236.     ProgramTerrain.SendUniform("lightDir.diffuse", 1.0, 1.0, 1.0);
  237.  
  238.     // base material setup (basic and terrain shaders only)
  239.     ProgramBasic.SendUniform("materialAmbient", 1.0, 1.0, 1.0);     // full power (note: ambient light is extremely dim)
  240.     ProgramBasic.SendUniform("materialDiffuse", 1.0, 1.0, 1.0);
  241.  
  242.     ProgramTerrain.SendUniform("materialAmbient", 1.0, 1.0, 1.0);       // full power (note: ambient light is extremely dim)
  243.     ProgramTerrain.SendUniform("materialDiffuse", 1.0, 1.0, 1.0);
  244.  
  245.     // setup water colour and water level
  246.     ProgramWater.SendUniform("waterColor", 0.2f, 0.22f, 0.2f);
  247.     ProgramWater.SendUniform("skyColor", 0.2f, 0.6f, 1.0f);
  248.  
  249.     // send waterLevel to terrain shader
  250.     ProgramTerrain.SendUniform("waterLevel", waterLevel);
  251.  
  252.     // underwater fog values sending to terrain shaders
  253.     ProgramTerrain.SendUniform("fogColor", 0.2f, 0.22f, 0.2f);
  254.     ProgramTerrain.SendUniform("fogThickness", 0.3); // higher value for more thickness
  255.  
  256.     // send terrain clip plane info
  257.     //ProgramTerrain.SendUniform("clipPlane", clipPlane);
  258.  
  259.     // set flip terrain textures to false initially (use when rendering terrain upside down to match blended above-water texture)
  260.     ProgramTerrain.SendUniform("flipTextures", 0);
  261.  
  262.     // Setup the particle system
  263.     //ProgramParticle.SendUniform("initialPos", -10.7865f, 8.21369f, 12.5494f);
  264.     ProgramParticle.SendUniform("gravity", 0.0f, -0.5f, 0.0f);
  265.     ProgramParticle.SendUniform("particleLifetime", LIFETIME);
  266.  
  267.     // Initialise the View Matrix (initial position for the first-person camera)
  268.     glMatrixMode(GL_MODELVIEW);
  269.     angleTilt = 15;
  270.     glLoadIdentity();
  271.     glRotatef(angleTilt, 1, 0, 0);
  272.     gluLookAt(4.0, 0.4, 30.0,
  273.               4.0, 0.4, 0.0,
  274.               0.0, 1.0, 0.0);
  275.     glGetFloatv(GL_MODELVIEW_MATRIX, matrixView);
  276.  
  277.     cout << endl;
  278.     cout << "Use:" << endl;
  279.     cout << "  WASD or arrow key to navigate" << endl;
  280.     cout << "  QE or PgUp/Dn to move the camera up and down" << endl;
  281.     cout << "  Drag the mouse to look around" << endl;
  282.     cout << endl;
  283.  
  284.     return true;
  285. }
  286.  
  287. void getCamPos()
  288. {
  289.     // getting position of camera in 'world space'
  290.     GLfloat cameraMatrix[16];
  291.     glGetFloatv(GL_MODELVIEW_MATRIX, cameraMatrix);
  292.     cameraVector[0] = -(cameraMatrix[0] * cameraMatrix[12] + cameraMatrix[1] * cameraMatrix[13] + cameraMatrix[2] * cameraMatrix[14]); // x
  293.     cameraVector[1] = -(cameraMatrix[4] * cameraMatrix[12] + cameraMatrix[5] * cameraMatrix[13] + cameraMatrix[6] * cameraMatrix[14]); // y
  294.     cameraVector[2] = -(cameraMatrix[8] * cameraMatrix[12] + cameraMatrix[9] * cameraMatrix[13] + cameraMatrix[10] * cameraMatrix[14]); // z
  295.     cout << "x, y, z \n";
  296.     cout << cameraVector[0]; cout << "f,  ";
  297.     cout << cameraVector[1]; cout << "f,  ";
  298.     cout << cameraVector[2]; cout << "f,  ";
  299.     cout << "\n";
  300. }
  301.  
  302. void done()
  303. {
  304. }
  305.  
  306. // called before window opened or resized - to setup the Projection Matrix
  307. void reshape(int w, int h)
  308. {
  309.     // find screen aspect ratio
  310.     float ratio = w * 1.0f / h;      // we hope that h is not zero
  311.  
  312.                                      // setup the projection matrix
  313.     glMatrixMode(GL_PROJECTION);
  314.     glLoadIdentity();
  315.     glViewport(0, 0, w, h);
  316.     gluPerspective(60.0, ratio, 0.02, 1000.0);
  317.  
  318.     float matrix[16];
  319.     glGetFloatv(GL_PROJECTION_MATRIX, matrix);
  320.     ProgramBasic.SendUniform("matrixProjection", matrix);
  321.     ProgramTerrain.SendUniform("matrixProjection", matrix);
  322.     ProgramWater.SendUniform("matrixProjection", matrix);
  323.     ProgramParticle.SendUniform("matrixProjection", matrix);
  324. }
  325.  
  326. void renderTerrain()
  327. {
  328.     float matrix[16];
  329.     float matrixinvert[16];
  330.  
  331.     // upright terrain
  332.     glEnable(GL_CLIP_DISTANCE0);
  333.     gluInvertMatrix(matrixView, matrixinvert);
  334.     ProgramTerrain.SendUniform("matrixViewInvert", matrixinvert);
  335.     glActiveTexture(GL_TEXTURE0);
  336.     glBindTexture(GL_TEXTURE_2D, idTexGrass);
  337.     ProgramTerrain.Use();
  338.     glPushMatrix();
  339.     //glTranslatef(0.0f, 9.5f, 0.0f);
  340.     glGetFloatv(GL_MODELVIEW_MATRIX, matrix);
  341.     ProgramTerrain.SendUniform("matrixModelView", matrix);
  342.     terrain.render();
  343.     glPopMatrix();
  344.     glDisable(GL_CLIP_DISTANCE0);
  345. }
  346.  
  347. void renderWater()
  348. {
  349.     float matrix[16];
  350.  
  351.     // water
  352.     glActiveTexture(GL_TEXTURE3);
  353.     glBindTexture(GL_TEXTURE_2D, stencilTexture);
  354.     ProgramWater.Use();
  355.     glPushMatrix();
  356.     glTranslatef(0.0f, waterLevel, 0.0f);
  357.     glScalef(0.5f, 1.0f, 0.5f);
  358.     glGetFloatv(GL_MODELVIEW_MATRIX, matrix);
  359.     ProgramWater.SendUniform("matrixModelView", matrix);
  360.     water.render();
  361.     glPopMatrix();
  362. }
  363.  
  364. void reflectedTerrain()
  365. {
  366.     float matrix[16];
  367.     float matrixinvert[16];
  368.  
  369.     // ..and reverse lighting
  370.     ProgramTerrain.SendUniform("lightDir.direction", -1.0, 0.5, -1.0);
  371.     // upside-down terrain
  372.     glEnable(GL_CLIP_DISTANCE1);
  373.     gluInvertMatrix(matrixView, matrixinvert);
  374.     ProgramTerrain.SendUniform("matrixViewInvert", matrixinvert);
  375.     glActiveTexture(GL_TEXTURE0);
  376.     glBindTexture(GL_TEXTURE_2D, idTexGrass);
  377.     ProgramTerrain.SendUniform("flipTextures", 1);
  378.     ProgramTerrain.Use();
  379.     glPushMatrix();
  380.     glTranslatef(0.0f, 9.2f, 0.0f);
  381.     glGetFloatv(GL_MODELVIEW_MATRIX, matrix);
  382.     ProgramTerrain.SendUniform("matrixModelView", matrix);
  383.     reflectedterrain.render();
  384.     glPopMatrix();
  385.     ProgramTerrain.SendUniform("flipTextures", 0);
  386.     glDisable(GL_CLIP_DISTANCE1);
  387.     ProgramTerrain.SendUniform("lightDir.direction", 1.0, 0.5, 1.0);
  388. }
  389.  
  390. void particleSystem()
  391. {
  392.     float matrix[16];
  393.  
  394.     ProgramParticle.Use();
  395.  
  396.     glPointSize(55);
  397.     glEnable(GL_POINT_SPRITE);
  398.     glEnable(GL_VERTEX_PROGRAM_POINT_SIZE);
  399.  
  400.     ProgramParticle.SendUniform("initialPos", cameraVector[0], cameraVector[1] + 1, cameraVector[2]);
  401.    
  402.     glGetFloatv(GL_MODELVIEW_MATRIX, matrix);
  403.     ProgramParticle.SendUniform("matrixModelView", matrix);
  404.    
  405.     // render the buffer
  406.     glEnableVertexAttribArray(0);
  407.     // velocity
  408.     glEnableVertexAttribArray(1);
  409.     // start time
  410.     glBindBuffer(GL_ARRAY_BUFFER, idBufferVelocity);
  411.     glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, 0);
  412.     glBindBuffer(GL_ARRAY_BUFFER, idBufferStartTime);
  413.     glVertexAttribPointer(1, 1, GL_FLOAT, GL_FALSE, 0, 0);
  414.     glDrawArrays(GL_POINTS, 0, NPARTICLES);
  415.     glDisableVertexAttribArray(0);
  416.     glDisableVertexAttribArray(1);
  417. }
  418.  
  419. void stencilTest()
  420. {
  421.     // Don't update color or depth
  422.     glDisable(GL_DEPTH_TEST);
  423.     glDepthMask(GL_FALSE);
  424.     glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
  425.  
  426.     // draw 1 into the stencil buffer.
  427.     glEnable(GL_STENCIL_TEST);
  428.     glStencilOp(GL_REPLACE, GL_REPLACE, GL_REPLACE);
  429.     glStencilFunc(GL_ALWAYS, 1, 0xffffffff);
  430.  
  431.     renderWater();
  432.  
  433.     // re-enable update of color and depth
  434.     glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
  435.     glEnable(GL_DEPTH_TEST);
  436.     glDepthMask(GL_TRUE);
  437.  
  438.     // only render where stencil is set to 1
  439.     glStencilFunc(GL_EQUAL, 1, 0xffffffff);  // draw if stencil == 1
  440.     glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);
  441.  
  442.     reflectedTerrain();
  443.  
  444.     glDisable(GL_STENCIL_TEST);
  445. }
  446.  
  447. void render()
  448. {
  449.     // getting position of camera in 'world space'
  450.     glGetFloatv(GL_MODELVIEW_MATRIX, cameraMatrix);
  451.     cameraVector[0] = -(cameraMatrix[0] * cameraMatrix[12] + cameraMatrix[1] * cameraMatrix[13] + cameraMatrix[2] * cameraMatrix[14]); // x
  452.     cameraVector[1] = -(cameraMatrix[4] * cameraMatrix[12] + cameraMatrix[5] * cameraMatrix[13] + cameraMatrix[6] * cameraMatrix[14]); // y
  453.     cameraVector[2] = -(cameraMatrix[8] * cameraMatrix[12] + cameraMatrix[9] * cameraMatrix[13] + cameraMatrix[10] * cameraMatrix[14]); // z
  454.  
  455.     //prepareReflectionTexture();
  456.  
  457.     float matrix[16];
  458.     float matrixinvert[16];
  459.  
  460.     // clear screen and buffers
  461.     glClearColor(0.2f, 0.6f, 1.f, 1.0f);   // blue sky colour
  462.     glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
  463.  
  464.     // setup the View Matrix (camera)
  465.     glMatrixMode(GL_MODELVIEW);
  466.     glLoadIdentity();
  467.     glRotatef(angleTilt, 1, 0, 0);                  // switch tilt off
  468.     glTranslatef(deltaX, deltaY, deltaZ);           // animate camera motion (controlled by WASD keys)
  469.     glRotatef(-angleTilt, 1, 0, 0);                 // switch tilt on
  470.     glMultMatrixf(matrixView);
  471.     glGetFloatv(GL_MODELVIEW_MATRIX, matrixView);
  472.  
  473.     // set the camera height above the ground
  474.     //gluInvertMatrix(matrixView, matrix);
  475.     glTranslatef(0, -max(terrain.getInterpolatedHeight(matrix[12], matrix[14]), waterLevel),  0);
  476.  
  477.     // setup View Matrix
  478.     glGetFloatv(GL_MODELVIEW_MATRIX, matrix);
  479.     ProgramBasic.SendUniform("matrixView", matrix);
  480.     ProgramTerrain.SendUniform("matrixView", matrix);
  481.  
  482.     // send time 't' to water shaders
  483.     ProgramWater.SendUniform("t", glutGet(GLUT_ELAPSED_TIME) / 3000.f);
  484.  
  485.     // send time 'time' to particle shaders
  486.     ProgramParticle.SendUniform("time", glutGet(GLUT_ELAPSED_TIME) / 1000.f - 2);
  487.  
  488.     // render the skybox
  489.     ProgramBasic.Use();
  490.     ProgramBasic.SendUniform("materialAmbient", 10.0f, 10.0f, 10.0f);
  491.     ProgramBasic.SendUniform("materialDiffuse", 0.0f, 0.0f, 0.0f);
  492.     skybox.render();
  493.  
  494.     stencilTest();
  495.    
  496.     renderWater();
  497.     renderTerrain();
  498.     particleSystem();
  499.  
  500.     // essential for double-buffering technique
  501.     glutSwapBuffers();
  502.  
  503.     // proceed the animation
  504.     glutPostRedisplay();
  505. }
  506.  
  507. // Handle WASDQE keys
  508. void onKeyDown(unsigned char key, int x, int y)
  509. {
  510.     switch (tolower(key))
  511.     {
  512.     case 'w': deltaZ = max(deltaZ * 1.05f, 0.01f); break;
  513.     case 's': deltaZ = min(deltaZ * 1.05f, -0.01f); break;
  514.     case 'a': deltaX = max(deltaX * 1.05f, 0.01f); break;
  515.     case 'd': deltaX = min(deltaX * 1.05f, -0.01f); break;
  516.     case 'e': deltaY = max(deltaY * 1.05f, 0.01f); break;
  517.     case 'q': deltaY = min(deltaY * 1.05f, -0.01f); break;
  518.     }
  519.     // speed limit
  520.     deltaX = max(-0.15f, min(0.15f, deltaX));
  521.     deltaY = max(-0.15f, min(0.15f, deltaY));
  522.     deltaZ = max(-0.15f, min(0.15f, deltaZ));
  523. }
  524.  
  525. // Handle WASDQE keys (key up)
  526. void onKeyUp(unsigned char key, int x, int y)
  527. {
  528.     switch (tolower(key))
  529.     {
  530.     case 'w': deltaZ = 0; getCamPos(); break;
  531.     case 's': deltaZ = 0; break;
  532.     case 'a':
  533.     case 'd': deltaX = 0; break;
  534.     case 'q':
  535.     case 'e': deltaY = 0; break;
  536.     case ' ': deltaY = 0; break;
  537.     }
  538. }
  539.  
  540. // Handle arrow keys and Alt+F4
  541. void onSpecDown(int key, int x, int y)
  542. {
  543.     switch (key)
  544.     {
  545.     case GLUT_KEY_F4:       if ((glutGetModifiers() & GLUT_ACTIVE_ALT) != 0) exit(0); break;
  546.     case GLUT_KEY_UP:       onKeyDown('w', x, y); break;
  547.     case GLUT_KEY_DOWN:     onKeyDown('s', x, y); break;
  548.     case GLUT_KEY_LEFT:     onKeyDown('a', x, y); break;
  549.     case GLUT_KEY_RIGHT:    onKeyDown('d', x, y); break;
  550.     case GLUT_KEY_PAGE_UP:  onKeyDown('q', x, y); break;
  551.     case GLUT_KEY_PAGE_DOWN:onKeyDown('e', x, y); break;
  552.     case GLUT_KEY_F11:      glutFullScreenToggle();
  553.     }
  554. }
  555.  
  556. // Handle arrow keys (key up)
  557. void onSpecUp(int key, int x, int y)
  558. {
  559.     switch (key)
  560.     {
  561.     case GLUT_KEY_UP:       onKeyUp('w', x, y); break;
  562.     case GLUT_KEY_DOWN:     onKeyUp('s', x, y); break;
  563.     case GLUT_KEY_LEFT:     onKeyUp('a', x, y); break;
  564.     case GLUT_KEY_RIGHT:    onKeyUp('d', x, y); break;
  565.     case GLUT_KEY_PAGE_UP:  onKeyUp('q', x, y); break;
  566.     case GLUT_KEY_PAGE_DOWN:onKeyUp('e', x, y); break;
  567.     }
  568. }
  569.  
  570. // Handle mouse click
  571. void onMouse(int button, int state, int x, int y)
  572. {
  573.     int cx = glutGet(GLUT_WINDOW_WIDTH) / 2;
  574.     int cy = glutGet(GLUT_WINDOW_HEIGHT) / 2;
  575.  
  576.     if (state == GLUT_DOWN)
  577.     {
  578.         glutSetCursor(GLUT_CURSOR_CROSSHAIR);
  579.         glutWarpPointer(cx, cy);
  580.     }
  581.     else
  582.         glutSetCursor(GLUT_CURSOR_INHERIT);
  583. }
  584.  
  585. // handle mouse move
  586. void onMotion(int x, int y)
  587. {
  588.     int cx = glutGet(GLUT_WINDOW_WIDTH) / 2;
  589.     int cy = glutGet(GLUT_WINDOW_HEIGHT) / 2;
  590.     if (x == cx && y == cy)
  591.         return; // caused by glutWarpPointer
  592.  
  593.     float amp = 0.25;
  594.     float deltaTilt = amp * (y - cy);
  595.     float deltaPan  = amp * (x - cx);
  596.  
  597.     glutWarpPointer(cx, cy);
  598.  
  599.     // handle camera tilt (mouse move up & down)
  600.     glMatrixMode(GL_MODELVIEW);
  601.     glLoadIdentity();
  602.     glRotatef(deltaTilt, 1, 0, 0);
  603.     glMultMatrixf(matrixView);
  604.     glGetFloatv(GL_MODELVIEW_MATRIX, matrixView);
  605.  
  606.     angleTilt += deltaTilt;
  607.  
  608.     // handle camera pan (mouse move left & right)
  609.     glMatrixMode(GL_MODELVIEW);
  610.     glLoadIdentity();
  611.     glRotatef(angleTilt, 1, 0, 0);
  612.     glRotatef(deltaPan, 0, 1, 0);
  613.     glRotatef(-angleTilt, 1, 0, 0);
  614.     glMultMatrixf(matrixView);
  615.     glGetFloatv(GL_MODELVIEW_MATRIX, matrixView);
  616. }
  617.  
  618. int main(int argc, char **argv)
  619. {
  620.     // init GLUT and create Window
  621.     glutInit(&argc, argv);
  622.     glutInitDisplayMode(GLUT_DEPTH | GLUT_DOUBLE | GLUT_RGBA);
  623.     glutInitWindowPosition(100, 100);
  624.     glutInitWindowSize(800, 600);
  625.     glutCreateWindow("CI5520 3D Graphics Programming");
  626.  
  627.     // init glew
  628.     GLenum err = glewInit();
  629.     if (GLEW_OK != err)
  630.     {
  631.         cerr << "GLEW Error: " << glewGetErrorString(err) << endl;
  632.         return 0;
  633.     }
  634.     cout << "Using GLEW " << glewGetString(GLEW_VERSION) << endl;
  635.  
  636.     // register callbacks
  637.     glutDisplayFunc(render);
  638.     glutReshapeFunc(reshape);
  639.     glutKeyboardFunc(onKeyDown);
  640.     glutSpecialFunc(onSpecDown);
  641.     glutKeyboardUpFunc(onKeyUp);
  642.     glutSpecialUpFunc(onSpecUp);
  643.     glutMouseFunc(onMouse);
  644.     glutMotionFunc(onMotion);
  645.  
  646.     cout << "Vendor: " << glGetString(GL_VENDOR) << endl;
  647.     cout << "Renderer: " << glGetString(GL_RENDERER) << endl;
  648.     cout << "Version: " << glGetString(GL_VERSION) << endl;
  649.  
  650.     // init light and everything – not a GLUT or callback function!
  651.     if (!init())
  652.     {
  653.         cerr << "Application failed to initialise" << endl;
  654.         return 0;
  655.     }
  656.  
  657.     // enter GLUT event processing cycle
  658.     glutMainLoop();
  659.  
  660.     done();
  661.  
  662.     return 1;
  663. }
RAW Paste Data
We use cookies for various purposes including analytics. By continuing to use Pastebin, you agree to our use of cookies as described in the Cookies Policy. OK, I Understand
 
Top