Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- //Fragment shader
- #version 430
- in vec3 theNormal; //The interpolated normal.
- in vec3 thePos; //Same for pos.
- in vec3 color; //Same for colour.
- uniform vec3 diffuseLightPos; //Here the light position is entered.
- uniform vec3 ambientLight;
- out vec4 outColor;
- void main()
- {
- vec3 lightVector = normalize(diffuseLightPos - thePos); //Calculate the normal vector that point to the light.
- float brightness = max(dot(lightVector, theNormal), 0); //Get the cosine of theta between the now rotated normal and the
- //lightvector.
- vec3 shade = color * (ambientLight + vec3(brightness, brightness, brightness)); //Add all the lighting to the colour.
- outColor = vec4(shade, 1.0f);
- }
- //Vertex shader
- #version 430
- in layout(location=0) vec3 position; //Vertex position vector
- in layout(location=1) vec3 inColor; //Vertex colour
- in layout(location=2) mat4 worldMatrix; //The matrix that changes it from local to world. (translation and rotation)
- in layout(location=6) vec3 normal; //The normal of each vertex
- uniform mat4 projAndViewMatrix; //The view and projection matrices.
- out vec3 theNormal; //We need to pass the normal to the fragment shader so that it can be interpolated and used.
- out vec3 thePos; //Same for the position.
- out vec3 color; //Same for colour.
- void main()
- {
- vec4 v = vec4(position, 1.0f);
- vec4 relativePos = worldMatrix * v; //Here we calculate the relative position of this vertex in the world
- gl_Position = projAndViewMatrix * relativePos; //Here we calculate where in regards to the screen it should be.
- theNormal = vec3(worldMatrix * vec4(normal, 1)); //Send the rotated normal to the fragment shader.
- //I know it should be vec4(normal, 0) to avoid the translation, but it works if I do.
- color = inColor;
- thePos = relativePos.xyz;
- }
- //Main.cpp - Where most of the setup and drawing etc occurs. Only relevant code left behind.
- #define GLEW_STATIC
- #define _USE_MATH_DEFINES
- #define TRANSLATION_PER_FRAME 0.01f
- #include "Shape.h"
- #include <SFML/System.hpp>
- #include <SFML/Window.hpp>
- #include <fstream>
- #include <streambuf>
- #include <string>
- #include <cerrno>
- #include <cmath>
- #include <memory>
- #include <glm/glm.hpp>
- #include <glm/gtc/matrix_transform.hpp>
- #include <glm/gtc/type_ptr.hpp>
- #include <iostream>
- #include "Vertex.h"
- #include "GenerateShape.h"
- #include "Camera.h"
- #include "Prop.h"
- #include "OBJReader.h"
- bool running = true;
- GLuint hollowCubicPolynomial(GLuint num)
- {
- if(num == 1) return 1;
- //Floor + The rest of the layers.
- return pow((num*2-1), 2) + pow(((num-1)*2-1), 2);
- }
- std::string get_file_contents(const char *filename)
- {
- std::ifstream in(filename, std::ios::in | std::ios::binary);
- if (in)
- {
- return(std::string((std::istreambuf_iterator<char>(in)), std::istreambuf_iterator<char>()));
- }
- throw(errno);
- }
- GLuint compileShaders(void)
- {
- GLint status;
- //Vertex shader
- std::string src = get_file_contents("VertexShader.txt");
- const char *vsSource = src.c_str();
- GLuint vertexShader = glCreateShader(GL_VERTEX_SHADER);
- glShaderSource(vertexShader, 1, &vsSource, NULL);
- glCompileShader(vertexShader);
- glGetShaderiv(vertexShader, GL_COMPILE_STATUS, &status);
- if(status != GL_TRUE){
- printf("Vertex shader didnt compile propely.\n%s\n", vsSource);
- char buffer[512];
- glGetShaderInfoLog(vertexShader, 512, NULL, buffer);
- printf("%s\n", buffer);
- sf::sleep(sf::seconds(10.f));
- }
- //Fragment shader
- src = get_file_contents("FragmentShader.txt");
- const GLchar* fsSource = src.c_str();
- GLuint fragmentShader = glCreateShader(GL_FRAGMENT_SHADER);
- glShaderSource(fragmentShader, 1, &fsSource, NULL);
- glCompileShader(fragmentShader);
- glGetShaderiv(fragmentShader, GL_COMPILE_STATUS, &status);
- if(status != GL_TRUE){
- printf("Fragment shader didnt compile propely.\n%s\n", fsSource);
- char buffer[512];
- glGetShaderInfoLog(fragmentShader, 512, NULL, buffer);
- printf("%s\n", buffer);
- sf::sleep(sf::seconds(10.f));
- running = false;
- }
- //Compile the final shader
- GLuint fullShader = glCreateProgram();
- glAttachShader(fullShader, vertexShader);
- glAttachShader(fullShader, fragmentShader);
- glBindFragDataLocation(fullShader, 0, "outColor");
- glLinkProgram(fullShader);
- glUseProgram(fullShader);
- return fullShader;
- }
- int main()
- {
- //test();
- //return 0;
- sf::Window window(sf::VideoMode::getDesktopMode(), "OpenGL", sf::Style::Close);
- window.setMouseCursorVisible(false);
- width = window.getSize().x;
- height = window.getSize().y;
- window.setFramerateLimit(60);
- glewExperimental = GL_TRUE;
- glewInit();
- glEnable(GL_DEPTH_TEST);
- glEnable(GL_CULL_FACE);
- glEnable(GL_LIGHTING);
- GLuint numPuramidLevels = 25;
- Camera Camera;
- Camera.setCenter(width, height);
- shape myCube = GenerateShape::makeCube();
- Prop testProp;
- testProp.Shape = myCube;
- testProp.matrices.resize(hollowCubicPolynomial(numPuramidLevels)+1);
- //The projection matrix will not change for this test program so I put it here at the top.
- glm::mat4 projectionMatrix = glm::perspective(80.0f, (float)width/(float)height, 0.1f, 200.0f);
- GLuint vao;
- glGenVertexArrays(1, &vao);
- glBindVertexArray(vao);
- //Load the test cube data.
- GLuint vbo;
- glGenBuffers(1, &vbo); //Maybe I should gen all the buffers at once?
- glBindBuffer(GL_ARRAY_BUFFER, vbo);
- glBufferData(GL_ARRAY_BUFFER, testProp.Shape.vertexBufferSize(), &testProp.Shape.vertices[0], GL_STATIC_DRAW);
- GLuint ebo;
- glGenBuffers(1, &ebo);
- glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ebo);
- glBufferData(GL_ELEMENT_ARRAY_BUFFER,
- myCube.indexBufferSize(), &myCube.indices[0], GL_DYNAMIC_DRAW);
- //Compile the shaders
- GLuint fullShader = compileShaders();
- //Vertex attributes
- GLint posAttrib = glGetAttribLocation(fullShader, "position");
- glEnableVertexAttribArray(posAttrib);
- glVertexAttribPointer(posAttrib, 3, GL_FLOAT, GL_FALSE,
- 9*sizeof(float), 0);
- GLint colAttrib = glGetAttribLocation(fullShader, "inColor");
- glEnableVertexAttribArray(colAttrib);
- glVertexAttribPointer(colAttrib, 3, GL_FLOAT, GL_FALSE,
- 9*sizeof(float), (void*)(3*sizeof(float)));
- //Lighting
- GLuint ambientLightUniformLocation = glGetUniformLocation(fullShader, "ambientLight");
- glm::vec3 ambientLight(0.05f, 0.05f, 0.05f);
- glUniform3fv(ambientLightUniformLocation, 1, &ambientLight[0]);
- //This diffuse lighting uniform is the position in the world the light should originate from. I placed a cube there to
- //represent the location when rendering.
- GLuint diffuseLightUniformLocation = glGetUniformLocation(fullShader, "diffuseLightPos");
- glm::vec3 diffuseLightPos(15.0f, -10.0f, 0.0f);
- testProp.matrices[hollowCubicPolynomial(numPuramidLevels)] = glm::translate(glm::mat4(), diffuseLightPos);
- glUniform3fv(diffuseLightUniformLocation, 1, &diffuseLightPos[0]);
- //Since I need to apply the lighting after the translation and rotation, but before the world to view and projection, I need to
- //send the matrices to be applied in the shader as we can not extract the rotation and translation from the final matrix.
- GLuint projectionAndWorldToViewMatrixLocationID = glGetUniformLocation(fullShader, "projAndViewMatrix");
- glm::mat4 worldMatrix = projectionMatrix*Camera.getWorld2ViewMatrix();
- //The world matrix = translate + rotation
- glUniformMatrix4fv(projectionAndWorldToViewMatrixLocationID, 1, GL_FALSE, &worldMatrix[0][0]);
- //The normal of each vertex also need to be sent to the
- GLint normalAttrib = glGetAttribLocation(fullShader, "normal");
- glEnableVertexAttribArray(normalAttrib);
- glVertexAttribPointer(normalAttrib, 3, GL_FLOAT, GL_FALSE,
- 9*sizeof(float), (void*)(6*sizeof(float)));
- //MatrixBuffer for the cubes
- GLuint matricesBufferID;
- glGenBuffers(1, &matricesBufferID);
- glBindBuffer(GL_ARRAY_BUFFER, matricesBufferID);
- glVertexAttribPointer(2, 4, GL_FLOAT, GL_FALSE, sizeof(glm::mat4), (void *)(sizeof(float) * 0));
- glVertexAttribPointer(3, 4, GL_FLOAT, GL_FALSE, sizeof(glm::mat4), (void *)(sizeof(float) * 4));
- glVertexAttribPointer(4, 4, GL_FLOAT, GL_FALSE, sizeof(glm::mat4), (void *)(sizeof(float) * 8));
- glVertexAttribPointer(5, 4, GL_FLOAT, GL_FALSE, sizeof(glm::mat4), (void *)(sizeof(float) * 12));
- glEnableVertexAttribArray(2);
- glEnableVertexAttribArray(3);
- glEnableVertexAttribArray(4);
- glEnableVertexAttribArray(5);
- glVertexAttribDivisor(2, 1);
- glVertexAttribDivisor(3, 1);
- glVertexAttribDivisor(4, 1);
- glVertexAttribDivisor(5, 1);
- while(running){
- //Loads of code to handle keyboard and mouseinput.
- //These commands will change the Camera matrix, or world to view matrix, and thus we need to rebuild the data being
- //sent to the graphics card.
- glBindBuffer(GL_ARRAY_BUFFER, matricesBufferID);
- testProp.generateHollowCubeTowerMatrices(numPuramidLevels, glm::vec3(0.0f, 0.0f, 0.0f), &Camera, &projectionMatrix);
- worldMatrix = projectionMatrix*Camera.getWorld2ViewMatrix();
- glUniformMatrix4fv(projectionAndWorldToViewMatrixLocationID, 1, GL_FALSE, &worldMatrix[0][0]);
- glBufferData(GL_ARRAY_BUFFER, sizeof(glm::mat4)*testProp.matrices.size(), &testProp.matrices[0], GL_DYNAMIC_DRAW);
- // Clear the screen to black
- glClearColor(0.1f, 0.1f, 0.1f, 1.0f);
- glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
- glViewport(0, 0, width, height);
- // Draw
- glDrawElementsInstanced(GL_TRIANGLES, (GLsizei)testProp.Shape.numIndices, GL_UNSIGNED_SHORT, 0,
- (GLsizei)testProp.matrices.size());
- // Swap buffers
- window.display();
- }
- //Clean up
- glDeleteProgram(fullShader);
- glDeleteShader(fragmentShader);
- glDeleteShader(vertexShader);
- glDeleteBuffers(1, &ebo);
- glDeleteBuffers(1, &vbo);
- glDeleteBuffers(1, &matricesBufferID);
- glDeleteVertexArrays(1, &vao);
- sf::sleep(sf::seconds(1.f));
- return 0;
- }
- //Cube data
- vertex verts[] = {
- //Position //Colour //Normal vector //Corner ID-Vertex ID
- //Front
- glm::vec3(-0.5f, -0.5f, 0.5f), glm::vec3(1.0f, 0.0f, 0.0f), glm::vec3(0.0f, 0.0f, 1.0f), //0 - 0
- glm::vec3(0.5f, -0.5f, 0.5f), glm::vec3(1.0f, 0.0f, 0.0f), glm::vec3(0.0f, 0.0f, 1.0f), //1 - 1
- glm::vec3(0.5f, 0.5f, 0.5f), glm::vec3(1.0f, 0.0f, 0.0f), glm::vec3(0.0f, 0.0f, 1.0f), //2 - 2
- glm::vec3(-0.5f, 0.5f, 0.5f), glm::vec3(1.0f, 0.0f, 0.0f), glm::vec3(0.0f, 0.0f, 1.0f), //3 - 3
- //Back
- glm::vec3(-0.5f, 0.5f, -0.5f), glm::vec3(1.0f, 1.0f, 0.0f), glm::vec3(0.0f, 0.0f, -1.0f), //4 - 4
- glm::vec3(-0.5f, -0.5f, -0.5f), glm::vec3(1.0f, 1.0f, 0.0f), glm::vec3(0.0f, 0.0f, -1.0f), //5 - 5
- glm::vec3(0.5f, -0.5f, -0.5f), glm::vec3(1.0f, 1.0f, 0.0f), glm::vec3(0.0f, 0.0f, -1.0f), //6 - 6
- glm::vec3(0.5f, 0.5f, -0.5f), glm::vec3(1.0f, 1.0f, 0.0f), glm::vec3(0.0f, 0.0f, -1.0f), //7 - 7
- //Top
- glm::vec3(-0.5f, -0.5f, 0.5f), glm::vec3(0.0f, 1.0f, 1.0f), glm::vec3(0.0f, -1.0f, 0.0f), //0 - 8
- glm::vec3(0.5f, -0.5f, 0.5f), glm::vec3(0.0f, 1.0f, 1.0f), glm::vec3(0.0f, -1.0f, 0.0f), //1 - 9
- glm::vec3(-0.5f, -0.5f, -0.5f), glm::vec3(0.0f, 1.0f, 1.0f), glm::vec3(0.0f, -1.0f, 0.0f), //5 - 10
- glm::vec3(0.5f, -0.5f, -0.5f), glm::vec3(0.0f, 1.0f, 1.0f), glm::vec3(0.0f, -1.0f, 0.0f), //6 - 11
- //Bottom
- glm::vec3(0.5f, 0.5f, 0.5f), glm::vec3(0.0f, 0.0f, 1.0f), glm::vec3(0.0f, 1.0f, 0.0f), //2 - 12
- glm::vec3(-0.5f, 0.5f, 0.5f), glm::vec3(0.0f, 0.0f, 1.0f), glm::vec3(0.0f, 1.0f, 0.0f), //3 - 13
- glm::vec3(-0.5f, 0.5f, -0.5f), glm::vec3(0.0f, 0.0f, 1.0f), glm::vec3(0.0f, 1.0f, 0.0f), //4 - 14
- glm::vec3(0.5f, 0.5f, -0.5f), glm::vec3(0.0f, 0.0f, 1.0f), glm::vec3(0.0f, 1.0f, 0.0f), //7 - 15
- //Left
- glm::vec3(-0.5f, -0.5f, 0.5f), glm::vec3(1.0f, 0.0f, 1.0f), glm::vec3(-1.0f, 0.0f, 0.0f), //0 - 16
- glm::vec3(-0.5f, 0.5f, 0.5f), glm::vec3(1.0f, 0.0f, 1.0f), glm::vec3(-1.0f, 0.0f, 0.0f), //3 - 17
- glm::vec3(-0.5f, 0.5f, -0.5f), glm::vec3(1.0f, 0.0f, 1.0f), glm::vec3(-1.0f, 0.0f, 0.0f), //4 - 18
- glm::vec3(-0.5f, -0.5f, -0.5f), glm::vec3(1.0f, 0.0f, 1.0f), glm::vec3(-1.0f, 0.0f, 0.0f), //5 - 19
- //Right
- glm::vec3(0.5f, -0.5f, 0.5f), glm::vec3(0.0f, 1.0f, 0.0f), glm::vec3(1.0f, 0.0f, 0.0f), //1 - 20
- glm::vec3(0.5f, 0.5f, 0.5f), glm::vec3(0.0f, 1.0f, 0.0f), glm::vec3(1.0f, 0.0f, 0.0f), //2 - 21
- glm::vec3(0.5f, -0.5f, -0.5f), glm::vec3(0.0f, 1.0f, 0.0f), glm::vec3(1.0f, 0.0f, 0.0f), //6 - 22
- glm::vec3(0.5f, 0.5f, -0.5f), glm::vec3(0.0f, 1.0f, 0.0f), glm::vec3(1.0f, 0.0f, 0.0f), //7 - 23
- };
- //Triangle sets
- GLushort elements[] = {
- //Front
- 0, 1, 3,
- 1, 2, 3,
- //Back
- 5, 4, 6,
- 4, 7, 6,
- //Top
- 11, 8, 10,
- 11, 9, 8,
- //Bottom
- 13, 15, 14,
- 13, 12, 15,
- //Left
- 19, 17, 18,
- 19, 16, 17,
- //Right
- 20, 23, 21,
- 20, 22, 23
- };
- //Vertex struct
- struct vertex{
- public:
- glm::vec3 position;
- glm::vec3 colour;
- glm::vec3 normal;
- //GLfloat alpha;
- };
- //Generating the hollow pyramid.
- void Prop::generateHollowCubeTowerMatrices(GLuint numLevels, glm::vec3 offset, Camera* camera, glm::mat4* projectionMatrix)
- {
- GLuint matrixLoc = 1;
- //The start location in the ZX plain for the first cube in the next layer down.
- glm::vec2 startCoord;
- //Only the top is rotated 90 degrees around the Z axis for comparison.
- matrices[0] = glm::rotate(glm::translate(glm::mat4(), offset),
- 90.0f, glm::vec3(0.0f, 0.0f, 1.0f));
- for(uint32_t i = 1; i < numLevels; ++i)//Skip the one we just made.
- {
- startCoord.x = (float)i+1;
- startCoord.y = (float)i+1;
- for (uint32_t j = i*2+1; j > 0; --j)
- {
- for (uint32_t k = i*2+1; k > 0; --k)
- {
- //If we are at any of the edges OR it is the last level, then we "add a cube".
- //We are really adding the translation matrix so that the vertices are translated correctly.
- if (j==1 || j == i*2+1 || k==1 || k == i*2+1 || i == numLevels-1)
- {
- matrices[matrixLoc] =
- glm::translate(glm::mat4(), glm::vec3((float)(startCoord.x - (float)j - offset.x),
- -(float)i + offset.y, (float)(startCoord.y - (float)k - offset.z)));
- ++matrixLoc;
- }
- }
- }
- }
- }
- //The camera and how it changes
- void Camera::moveForward()
- {
- position += (MOVEMENT_SPEED*SPEEDBOOSTER) * viewDir;
- }
- void Camera::moveBackward()
- {
- position -= (MOVEMENT_SPEED*SPEEDBOOSTER) * viewDir;
- }
- void Camera::strafeLeft()
- {
- position += (MOVEMENT_SPEED*SPEEDBOOSTER) * strafeDir;
- }
- void Camera::strafeRight()
- {
- position -= (MOVEMENT_SPEED*SPEEDBOOSTER) * strafeDir;
- }
- void Camera::ascend()
- {
- position += (MOVEMENT_SPEED*SPEEDBOOSTER) * upVector;
- }
- void Camera::descend()
- {
- position -= (MOVEMENT_SPEED*SPEEDBOOSTER) * upVector;
- }
- void Camera::setCenter(int width, int height) {
- center.x = (float)width/2;
- center.y = (float)height/2;
- }
- glm::mat4 getWorld2ViewMatrix() const{
- //The lookat point is given by adding the viewDir to the position of the camera.
- return glm::lookAt(position, position + viewDir, upVector);
- }
Advertisement
Add Comment
Please, Sign In to add comment