Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <iostream>
- #include "GL/glew.h"
- #include "GL/3dgl.h"
- #include "GL/glut.h"
- #include "GL/freeglut_ext.h"
- #pragma comment (lib, "glew32.lib")
- using namespace std;
- using namespace _3dgl;
- //bool reverseskybox = true;
- //
- const char * skyboxtextures[6] = { "models\\skyboxfront2.jpg", "models\\skyboxleft2.jpg", "models\\skyboxback2.jpg",
- "models\\skyboxright2.jpg", "models\\skyboxup.jpg", "models\\skyboxup2.jpg" };
- // window size (used for FBO)
- int ScreenWidth = 800;
- int ScreenHeight = 600;
- // 3D Models
- C3dglTerrain terrain, reflectedterrain, water;
- // Skybox
- C3dglSkyBox skybox, reflectedskybox;
- // texture ids
- GLuint idTexGrass; // grass texture
- GLuint idTexSand; // sand texture
- GLuint idTexWater; // water texture
- GLuint idTexNone;
- GLuint stencilTexture, fb, depth_stencil_rb;
- // particle ids
- GLuint idBufferVelocity;
- GLuint idBufferStartTime;
- // GLSL Objects (Shader Program)
- C3dglProgram ProgramBasic;
- C3dglProgram ProgramWater;
- C3dglProgram ProgramTerrain;
- C3dglProgram ProgramParticle;
- // Water specific variables
- float waterLevel = 4.6f;
- // setup clipping plane array
- float Nx = 0, Ny = 1, Nz = 0, d = 0;
- float clipPlane[4] = { Nx, Ny, Nz, d };
- // camera position (for first person type camera navigation)
- float matrixView[16]; // The View Matrix
- float angleTilt = 0; // Tilt Angle
- float deltaX = 0, deltaY = 0, deltaZ = 0; // Camera movement values
- // world camera position (used for reflection texture)
- float cameraVector[3];
- GLfloat cameraMatrix[16];
- // Particle System Params
- const float PERIOD = 0.000075f; // each recycled particle will obtain it's start time PERIOD seconds after the previous has died
- const float LIFETIME = 6; // life time of each particle
- const int NPARTICLES = (int)(LIFETIME / PERIOD); // number of particles that need to be present before any new particles are born (8000, in this case)
- bool init()
- {
- // rendering states
- glEnable(GL_DEPTH_TEST); // depth test is necessary for most 3D scenes
- glEnable(GL_NORMALIZE); // normalization is needed by AssImp library models
- glShadeModel(GL_SMOOTH); // smooth shading mode is the default one; try GL_FLAT here!
- glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); // this is the default one; try GL_LINE!
- glEnable(GL_BLEND);
- glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
- // Initialise Shaders
- C3dglShader VertexShader;
- C3dglShader FragmentShader;
- if (!VertexShader.Create(GL_VERTEX_SHADER)) return false;
- if (!VertexShader.LoadFromFile("shaders/basic.vert")) return false;
- if (!VertexShader.Compile()) return false;
- if (!FragmentShader.Create(GL_FRAGMENT_SHADER)) return false;
- if (!FragmentShader.LoadFromFile("shaders/basic.frag")) return false;
- if (!FragmentShader.Compile()) return false;
- if (!ProgramBasic.Create()) return false;
- if (!ProgramBasic.Attach(VertexShader)) return false;
- if (!ProgramBasic.Attach(FragmentShader)) return false;
- if (!ProgramBasic.Link()) return false;
- if (!ProgramBasic.Use(true)) return false;
- if (!VertexShader.Create(GL_VERTEX_SHADER)) return false;
- if (!VertexShader.LoadFromFile("shaders/water.vert")) return false;
- if (!VertexShader.Compile()) return false;
- if (!FragmentShader.Create(GL_FRAGMENT_SHADER)) return false;
- if (!FragmentShader.LoadFromFile("shaders/water.frag")) return false;
- if (!FragmentShader.Compile()) return false;
- if (!ProgramWater.Create()) return false;
- if (!ProgramWater.Attach(VertexShader)) return false;
- if (!ProgramWater.Attach(FragmentShader)) return false;
- if (!ProgramWater.Link()) return false;
- if (!ProgramWater.Use(true)) return false;
- if (!VertexShader.Create(GL_VERTEX_SHADER)) return false;
- if (!VertexShader.LoadFromFile("shaders/terrain.vert")) return false;
- if (!VertexShader.Compile()) return false;
- if (!FragmentShader.Create(GL_FRAGMENT_SHADER)) return false;
- if (!FragmentShader.LoadFromFile("shaders/terrain.frag")) return false;
- if (!FragmentShader.Compile()) return false;
- if (!ProgramTerrain.Create()) return false;
- if (!ProgramTerrain.Attach(VertexShader)) return false;
- if (!ProgramTerrain.Attach(FragmentShader)) return false;
- if (!ProgramTerrain.Link()) return false;
- if (!ProgramTerrain.Use(true)) return false;
- //if (!VertexShader.Create(GL_VERTEX_SHADER)) return false;
- //if (!VertexShader.LoadFromFile("shaders/particle.vert")) return false;
- //if (!VertexShader.Compile()) return false;
- //if (!FragmentShader.Create(GL_FRAGMENT_SHADER)) return false;
- //if (!FragmentShader.LoadFromFile("shaders/particle.frag")) return false;
- //if (!FragmentShader.Compile()) return false;
- //if (!ProgramParticle.Create()) return false;
- //if (!ProgramParticle.Attach(VertexShader)) return false;
- //if (!ProgramParticle.Attach(FragmentShader)) return false;
- //if (!ProgramParticle.Link()) return false;
- //if (!ProgramParticle.Use(true)) return false;
- // glut additional setup
- glutSetVertexAttribCoord3(ProgramBasic.GetAttribLocation("aVertex"));
- glutSetVertexAttribNormal(ProgramBasic.GetAttribLocation("aNormal"));
- // enable alpha blending
- glEnable(GL_BLEND);
- glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
- // load your 3D models here!
- if (!terrain.loadHeightmap("models\\heightmap.png", 10)) return false;
- if (!reflectedterrain.loadHeightmap("models\\heightmap.png", -10)) return false;
- if (!water.loadHeightmap("models\\watermap.png", 10)) return false;
- if (!skybox.load(skyboxtextures[0], skyboxtextures[1], skyboxtextures[2],
- skyboxtextures[3], skyboxtextures[4], skyboxtextures[5])) return false;
- if (!reflectedskybox.load("models\\skyboxback.jpg", "models\\skyboxright.jpg", "models\\skyboxfront.jpg",
- "models\\skyboxleft.jpg", "models\\skyboxdown.jpg", "models\\skyboxup.jpg")) return false;
- // create & load textures
- C3dglBitmap bm, bm2;
- glActiveTexture(GL_TEXTURE0);
- // Grass texture
- bm.Load("models/grass.png", GL_RGBA);
- glGenTextures(1, &idTexGrass);
- glBindTexture(GL_TEXTURE_2D, idTexGrass);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
- glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, bm.GetWidth(), bm.GetHeight(), 0, GL_RGBA, GL_UNSIGNED_BYTE, bm.GetBits());
- // Sand texture
- bm.Load("models/sand.png", GL_RGBA);
- glGenTextures(1, &idTexSand);
- glBindTexture(GL_TEXTURE_2D, idTexSand);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
- glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, bm.GetWidth(), bm.GetHeight(), 0, GL_RGBA, GL_UNSIGNED_BYTE, bm.GetBits());
- // Water texture
- bm.Load("models/water.png", GL_RGBA);
- glGenTextures(1, &idTexWater);
- glBindTexture(GL_TEXTURE_2D, idTexWater);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
- glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, bm.GetWidth(), bm.GetHeight(), 0, GL_RGBA, GL_UNSIGNED_BYTE, bm.GetBits());
- // the textures to mix for terrain
- glActiveTexture(GL_TEXTURE1);
- glBindTexture(GL_TEXTURE_2D, idTexSand);
- glActiveTexture(GL_TEXTURE2);
- glBindTexture(GL_TEXTURE_2D, idTexGrass);
- // Prepare the particle buffers
- std::vector<float> bufferVelocity;
- std::vector<float> bufferStartTime;
- float time = 0;
- float M_PI = 3.14;
- for (int i = 0; i < NPARTICLES; i++)
- {
- float theta = (float)M_PI / 6.f * (float)rand() / (float)RAND_MAX;
- float phi = (float)M_PI * 2.f * (float)rand() / (float)RAND_MAX;
- float x = sin(theta) * cos(phi);
- float y = cos(theta);
- float z = sin(theta) * sin(phi);
- float v = 2 + 0.5f * (float)rand() / (float)RAND_MAX;
- bufferVelocity.push_back(x * v);
- bufferVelocity.push_back(y * v);
- bufferVelocity.push_back(z * v);
- bufferStartTime.push_back(time);
- time += PERIOD;
- }
- glGenBuffers(1, &idBufferVelocity);
- glBindBuffer(GL_ARRAY_BUFFER, idBufferVelocity);
- glBufferData(GL_ARRAY_BUFFER, sizeof(float) * bufferVelocity.size(), &bufferVelocity[0], GL_STATIC_DRAW);
- glGenBuffers(1, &idBufferStartTime); glBindBuffer(GL_ARRAY_BUFFER, idBufferStartTime);
- glBufferData(GL_ARRAY_BUFFER, sizeof(float) * bufferStartTime.size(), &bufferStartTime[0], GL_STATIC_DRAW);
- // send texture channel info to shaders
- ProgramBasic.SendUniform("texture0", 0);
- ProgramTerrain.SendUniform("texture0", 0);
- ProgramWater.SendUniform("texture0", 0);
- ProgramParticle.SendUniform("texture0", 0);
- ProgramTerrain.SendUniform("textureUnderwater", 1);
- ProgramTerrain.SendUniform("textureShore", 2);
- ProgramWater.SendUniform("texture3", 3);
- // setup lights (for basic and terrain programs only, water does not use these lights)
- ProgramBasic.SendUniform("lightAmbient.on", 1);
- ProgramBasic.SendUniform("lightAmbient.color", 0.1, 0.1, 0.1);
- ProgramBasic.SendUniform("lightDir.on", 1);
- ProgramBasic.SendUniform("lightDir.direction", 1.0, 0.5, 1.0);
- ProgramBasic.SendUniform("lightDir.diffuse", 1.0, 1.0, 1.0);
- ProgramTerrain.SendUniform("lightAmbient.on", 1);
- ProgramTerrain.SendUniform("lightAmbient.color", 0.1, 0.1, 0.1);
- ProgramTerrain.SendUniform("lightDir.on", 1);
- ProgramTerrain.SendUniform("lightDir.direction", 1.0, 0.5, 1.0);
- ProgramTerrain.SendUniform("lightDir.diffuse", 1.0, 1.0, 1.0);
- // base material setup (basic and terrain shaders only)
- ProgramBasic.SendUniform("materialAmbient", 1.0, 1.0, 1.0); // full power (note: ambient light is extremely dim)
- ProgramBasic.SendUniform("materialDiffuse", 1.0, 1.0, 1.0);
- ProgramTerrain.SendUniform("materialAmbient", 1.0, 1.0, 1.0); // full power (note: ambient light is extremely dim)
- ProgramTerrain.SendUniform("materialDiffuse", 1.0, 1.0, 1.0);
- // setup water colour and water level
- ProgramWater.SendUniform("waterColor", 0.2f, 0.22f, 0.2f);
- ProgramWater.SendUniform("skyColor", 0.2f, 0.6f, 1.0f);
- // send waterLevel to terrain shader
- ProgramTerrain.SendUniform("waterLevel", waterLevel);
- // underwater fog values sending to terrain shaders
- ProgramTerrain.SendUniform("fogColor", 0.2f, 0.22f, 0.2f);
- ProgramTerrain.SendUniform("fogThickness", 0.3); // higher value for more thickness
- // send terrain clip plane info
- //ProgramTerrain.SendUniform("clipPlane", clipPlane);
- // set flip terrain textures to false initially (use when rendering terrain upside down to match blended above-water texture)
- ProgramTerrain.SendUniform("flipTextures", 0);
- // Setup the particle system
- //ProgramParticle.SendUniform("initialPos", -10.7865f, 8.21369f, 12.5494f);
- ProgramParticle.SendUniform("gravity", 0.0f, -0.5f, 0.0f);
- ProgramParticle.SendUniform("particleLifetime", LIFETIME);
- // Initialise the View Matrix (initial position for the first-person camera)
- glMatrixMode(GL_MODELVIEW);
- angleTilt = 15;
- glLoadIdentity();
- glRotatef(angleTilt, 1, 0, 0);
- gluLookAt(4.0, 0.4, 30.0,
- 4.0, 0.4, 0.0,
- 0.0, 1.0, 0.0);
- glGetFloatv(GL_MODELVIEW_MATRIX, matrixView);
- cout << endl;
- cout << "Use:" << endl;
- cout << " WASD or arrow key to navigate" << endl;
- cout << " QE or PgUp/Dn to move the camera up and down" << endl;
- cout << " Drag the mouse to look around" << endl;
- cout << endl;
- return true;
- }
- void getCamPos()
- {
- // getting position of camera in 'world space'
- GLfloat cameraMatrix[16];
- glGetFloatv(GL_MODELVIEW_MATRIX, cameraMatrix);
- cameraVector[0] = -(cameraMatrix[0] * cameraMatrix[12] + cameraMatrix[1] * cameraMatrix[13] + cameraMatrix[2] * cameraMatrix[14]); // x
- cameraVector[1] = -(cameraMatrix[4] * cameraMatrix[12] + cameraMatrix[5] * cameraMatrix[13] + cameraMatrix[6] * cameraMatrix[14]); // y
- cameraVector[2] = -(cameraMatrix[8] * cameraMatrix[12] + cameraMatrix[9] * cameraMatrix[13] + cameraMatrix[10] * cameraMatrix[14]); // z
- cout << "x, y, z \n";
- cout << cameraVector[0]; cout << "f, ";
- cout << cameraVector[1]; cout << "f, ";
- cout << cameraVector[2]; cout << "f, ";
- cout << "\n";
- }
- void done()
- {
- }
- // called before window opened or resized - to setup the Projection Matrix
- void reshape(int w, int h)
- {
- // find screen aspect ratio
- float ratio = w * 1.0f / h; // we hope that h is not zero
- // setup the projection matrix
- glMatrixMode(GL_PROJECTION);
- glLoadIdentity();
- glViewport(0, 0, w, h);
- gluPerspective(60.0, ratio, 0.02, 1000.0);
- float matrix[16];
- glGetFloatv(GL_PROJECTION_MATRIX, matrix);
- ProgramBasic.SendUniform("matrixProjection", matrix);
- ProgramTerrain.SendUniform("matrixProjection", matrix);
- ProgramWater.SendUniform("matrixProjection", matrix);
- ProgramParticle.SendUniform("matrixProjection", matrix);
- }
- void renderTerrain()
- {
- float matrix[16];
- float matrixinvert[16];
- // upright terrain
- glEnable(GL_CLIP_DISTANCE0);
- gluInvertMatrix(matrixView, matrixinvert);
- ProgramTerrain.SendUniform("matrixViewInvert", matrixinvert);
- glActiveTexture(GL_TEXTURE0);
- glBindTexture(GL_TEXTURE_2D, idTexGrass);
- ProgramTerrain.Use();
- glPushMatrix();
- //glTranslatef(0.0f, 9.5f, 0.0f);
- glGetFloatv(GL_MODELVIEW_MATRIX, matrix);
- ProgramTerrain.SendUniform("matrixModelView", matrix);
- terrain.render();
- glPopMatrix();
- glDisable(GL_CLIP_DISTANCE0);
- }
- void renderWater()
- {
- float matrix[16];
- // water
- glActiveTexture(GL_TEXTURE3);
- glBindTexture(GL_TEXTURE_2D, stencilTexture);
- ProgramWater.Use();
- glPushMatrix();
- glTranslatef(0.0f, waterLevel, 0.0f);
- glScalef(0.5f, 1.0f, 0.5f);
- glGetFloatv(GL_MODELVIEW_MATRIX, matrix);
- ProgramWater.SendUniform("matrixModelView", matrix);
- water.render();
- glPopMatrix();
- }
- void reflectedTerrain()
- {
- float matrix[16];
- float matrixinvert[16];
- // ..and reverse lighting
- ProgramTerrain.SendUniform("lightDir.direction", -1.0, 0.5, -1.0);
- // upside-down terrain
- glEnable(GL_CLIP_DISTANCE1);
- gluInvertMatrix(matrixView, matrixinvert);
- ProgramTerrain.SendUniform("matrixViewInvert", matrixinvert);
- glActiveTexture(GL_TEXTURE0);
- glBindTexture(GL_TEXTURE_2D, idTexGrass);
- ProgramTerrain.SendUniform("flipTextures", 1);
- ProgramTerrain.Use();
- glPushMatrix();
- glTranslatef(0.0f, 9.2f, 0.0f);
- glGetFloatv(GL_MODELVIEW_MATRIX, matrix);
- ProgramTerrain.SendUniform("matrixModelView", matrix);
- reflectedterrain.render();
- glPopMatrix();
- ProgramTerrain.SendUniform("flipTextures", 0);
- glDisable(GL_CLIP_DISTANCE1);
- ProgramTerrain.SendUniform("lightDir.direction", 1.0, 0.5, 1.0);
- }
- void particleSystem()
- {
- float matrix[16];
- ProgramParticle.Use();
- glPointSize(55);
- glEnable(GL_POINT_SPRITE);
- glEnable(GL_VERTEX_PROGRAM_POINT_SIZE);
- ProgramParticle.SendUniform("initialPos", cameraVector[0], cameraVector[1] + 1, cameraVector[2]);
- glGetFloatv(GL_MODELVIEW_MATRIX, matrix);
- ProgramParticle.SendUniform("matrixModelView", matrix);
- // render the buffer
- glEnableVertexAttribArray(0);
- // velocity
- glEnableVertexAttribArray(1);
- // start time
- glBindBuffer(GL_ARRAY_BUFFER, idBufferVelocity);
- glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, 0);
- glBindBuffer(GL_ARRAY_BUFFER, idBufferStartTime);
- glVertexAttribPointer(1, 1, GL_FLOAT, GL_FALSE, 0, 0);
- glDrawArrays(GL_POINTS, 0, NPARTICLES);
- glDisableVertexAttribArray(0);
- glDisableVertexAttribArray(1);
- }
- void stencilTest()
- {
- // Don't update color or depth
- glDisable(GL_DEPTH_TEST);
- glDepthMask(GL_FALSE);
- glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
- // draw 1 into the stencil buffer.
- glEnable(GL_STENCIL_TEST);
- glStencilOp(GL_REPLACE, GL_REPLACE, GL_REPLACE);
- glStencilFunc(GL_ALWAYS, 1, 0xffffffff);
- renderWater();
- // re-enable update of color and depth
- glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
- glEnable(GL_DEPTH_TEST);
- glDepthMask(GL_TRUE);
- // only render where stencil is set to 1
- glStencilFunc(GL_EQUAL, 1, 0xffffffff); // draw if stencil == 1
- glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);
- reflectedTerrain();
- glDisable(GL_STENCIL_TEST);
- }
- void render()
- {
- // getting position of camera in 'world space'
- glGetFloatv(GL_MODELVIEW_MATRIX, cameraMatrix);
- cameraVector[0] = -(cameraMatrix[0] * cameraMatrix[12] + cameraMatrix[1] * cameraMatrix[13] + cameraMatrix[2] * cameraMatrix[14]); // x
- cameraVector[1] = -(cameraMatrix[4] * cameraMatrix[12] + cameraMatrix[5] * cameraMatrix[13] + cameraMatrix[6] * cameraMatrix[14]); // y
- cameraVector[2] = -(cameraMatrix[8] * cameraMatrix[12] + cameraMatrix[9] * cameraMatrix[13] + cameraMatrix[10] * cameraMatrix[14]); // z
- //prepareReflectionTexture();
- float matrix[16];
- float matrixinvert[16];
- // clear screen and buffers
- glClearColor(0.2f, 0.6f, 1.f, 1.0f); // blue sky colour
- glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
- // setup the View Matrix (camera)
- glMatrixMode(GL_MODELVIEW);
- glLoadIdentity();
- glRotatef(angleTilt, 1, 0, 0); // switch tilt off
- glTranslatef(deltaX, deltaY, deltaZ); // animate camera motion (controlled by WASD keys)
- glRotatef(-angleTilt, 1, 0, 0); // switch tilt on
- glMultMatrixf(matrixView);
- glGetFloatv(GL_MODELVIEW_MATRIX, matrixView);
- // set the camera height above the ground
- //gluInvertMatrix(matrixView, matrix);
- glTranslatef(0, -max(terrain.getInterpolatedHeight(matrix[12], matrix[14]), waterLevel), 0);
- // setup View Matrix
- glGetFloatv(GL_MODELVIEW_MATRIX, matrix);
- ProgramBasic.SendUniform("matrixView", matrix);
- ProgramTerrain.SendUniform("matrixView", matrix);
- // send time 't' to water shaders
- ProgramWater.SendUniform("t", glutGet(GLUT_ELAPSED_TIME) / 3000.f);
- // send time 'time' to particle shaders
- ProgramParticle.SendUniform("time", glutGet(GLUT_ELAPSED_TIME) / 1000.f - 2);
- // render the skybox
- ProgramBasic.Use();
- ProgramBasic.SendUniform("materialAmbient", 10.0f, 10.0f, 10.0f);
- ProgramBasic.SendUniform("materialDiffuse", 0.0f, 0.0f, 0.0f);
- skybox.render();
- stencilTest();
- renderWater();
- renderTerrain();
- particleSystem();
- // essential for double-buffering technique
- glutSwapBuffers();
- // proceed the animation
- glutPostRedisplay();
- }
- // Handle WASDQE keys
- void onKeyDown(unsigned char key, int x, int y)
- {
- switch (tolower(key))
- {
- case 'w': deltaZ = max(deltaZ * 1.05f, 0.01f); break;
- case 's': deltaZ = min(deltaZ * 1.05f, -0.01f); break;
- case 'a': deltaX = max(deltaX * 1.05f, 0.01f); break;
- case 'd': deltaX = min(deltaX * 1.05f, -0.01f); break;
- case 'e': deltaY = max(deltaY * 1.05f, 0.01f); break;
- case 'q': deltaY = min(deltaY * 1.05f, -0.01f); break;
- }
- // speed limit
- deltaX = max(-0.15f, min(0.15f, deltaX));
- deltaY = max(-0.15f, min(0.15f, deltaY));
- deltaZ = max(-0.15f, min(0.15f, deltaZ));
- }
- // Handle WASDQE keys (key up)
- void onKeyUp(unsigned char key, int x, int y)
- {
- switch (tolower(key))
- {
- case 'w': deltaZ = 0; getCamPos(); break;
- case 's': deltaZ = 0; break;
- case 'a':
- case 'd': deltaX = 0; break;
- case 'q':
- case 'e': deltaY = 0; break;
- case ' ': deltaY = 0; break;
- }
- }
- // Handle arrow keys and Alt+F4
- void onSpecDown(int key, int x, int y)
- {
- switch (key)
- {
- case GLUT_KEY_F4: if ((glutGetModifiers() & GLUT_ACTIVE_ALT) != 0) exit(0); break;
- case GLUT_KEY_UP: onKeyDown('w', x, y); break;
- case GLUT_KEY_DOWN: onKeyDown('s', x, y); break;
- case GLUT_KEY_LEFT: onKeyDown('a', x, y); break;
- case GLUT_KEY_RIGHT: onKeyDown('d', x, y); break;
- case GLUT_KEY_PAGE_UP: onKeyDown('q', x, y); break;
- case GLUT_KEY_PAGE_DOWN:onKeyDown('e', x, y); break;
- case GLUT_KEY_F11: glutFullScreenToggle();
- }
- }
- // Handle arrow keys (key up)
- void onSpecUp(int key, int x, int y)
- {
- switch (key)
- {
- case GLUT_KEY_UP: onKeyUp('w', x, y); break;
- case GLUT_KEY_DOWN: onKeyUp('s', x, y); break;
- case GLUT_KEY_LEFT: onKeyUp('a', x, y); break;
- case GLUT_KEY_RIGHT: onKeyUp('d', x, y); break;
- case GLUT_KEY_PAGE_UP: onKeyUp('q', x, y); break;
- case GLUT_KEY_PAGE_DOWN:onKeyUp('e', x, y); break;
- }
- }
- // Handle mouse click
- void onMouse(int button, int state, int x, int y)
- {
- int cx = glutGet(GLUT_WINDOW_WIDTH) / 2;
- int cy = glutGet(GLUT_WINDOW_HEIGHT) / 2;
- if (state == GLUT_DOWN)
- {
- glutSetCursor(GLUT_CURSOR_CROSSHAIR);
- glutWarpPointer(cx, cy);
- }
- else
- glutSetCursor(GLUT_CURSOR_INHERIT);
- }
- // handle mouse move
- void onMotion(int x, int y)
- {
- int cx = glutGet(GLUT_WINDOW_WIDTH) / 2;
- int cy = glutGet(GLUT_WINDOW_HEIGHT) / 2;
- if (x == cx && y == cy)
- return; // caused by glutWarpPointer
- float amp = 0.25;
- float deltaTilt = amp * (y - cy);
- float deltaPan = amp * (x - cx);
- glutWarpPointer(cx, cy);
- // handle camera tilt (mouse move up & down)
- glMatrixMode(GL_MODELVIEW);
- glLoadIdentity();
- glRotatef(deltaTilt, 1, 0, 0);
- glMultMatrixf(matrixView);
- glGetFloatv(GL_MODELVIEW_MATRIX, matrixView);
- angleTilt += deltaTilt;
- // handle camera pan (mouse move left & right)
- glMatrixMode(GL_MODELVIEW);
- glLoadIdentity();
- glRotatef(angleTilt, 1, 0, 0);
- glRotatef(deltaPan, 0, 1, 0);
- glRotatef(-angleTilt, 1, 0, 0);
- glMultMatrixf(matrixView);
- glGetFloatv(GL_MODELVIEW_MATRIX, matrixView);
- }
- int main(int argc, char **argv)
- {
- // init GLUT and create Window
- glutInit(&argc, argv);
- glutInitDisplayMode(GLUT_DEPTH | GLUT_DOUBLE | GLUT_RGBA);
- glutInitWindowPosition(100, 100);
- glutInitWindowSize(800, 600);
- glutCreateWindow("CI5520 3D Graphics Programming");
- // init glew
- GLenum err = glewInit();
- if (GLEW_OK != err)
- {
- cerr << "GLEW Error: " << glewGetErrorString(err) << endl;
- return 0;
- }
- cout << "Using GLEW " << glewGetString(GLEW_VERSION) << endl;
- // register callbacks
- glutDisplayFunc(render);
- glutReshapeFunc(reshape);
- glutKeyboardFunc(onKeyDown);
- glutSpecialFunc(onSpecDown);
- glutKeyboardUpFunc(onKeyUp);
- glutSpecialUpFunc(onSpecUp);
- glutMouseFunc(onMouse);
- glutMotionFunc(onMotion);
- cout << "Vendor: " << glGetString(GL_VENDOR) << endl;
- cout << "Renderer: " << glGetString(GL_RENDERER) << endl;
- cout << "Version: " << glGetString(GL_VERSION) << endl;
- // init light and everything – not a GLUT or callback function!
- if (!init())
- {
- cerr << "Application failed to initialise" << endl;
- return 0;
- }
- // enter GLUT event processing cycle
- glutMainLoop();
- done();
- return 1;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement