NoobsDeSroobs

OpenGL Accidental Spotlight

Aug 4th, 2014
780
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 14.85 KB | None | 0 0
  1. //Fragment shader
  2. #version 430
  3.  
  4. in vec3 theNormal;  //The interpolated normal.
  5. in vec3 thePos;     //Same for pos.
  6. in vec3 color;      //Same for colour.
  7.  
  8. uniform vec3 diffuseLightPos;   //Here the light position is entered.
  9. uniform vec3 ambientLight;  
  10.  
  11. out vec4 outColor;
  12.  
  13. void main()
  14. {
  15.     vec3 lightVector = normalize(diffuseLightPos - thePos); //Calculate the normal vector that point to the light.
  16.     float brightness = max(dot(lightVector, theNormal), 0); //Get the cosine of theta between the now rotated normal and the
  17.     //lightvector.
  18.         vec3 shade = color * (ambientLight + vec3(brightness, brightness, brightness)); //Add all the lighting to the colour.
  19.         outColor = vec4(shade, 1.0f);
  20. }
  21.  
  22. //Vertex shader
  23. #version 430
  24.  
  25. in layout(location=0) vec3 position;    //Vertex position vector
  26. in layout(location=1) vec3 inColor; //Vertex colour
  27. in layout(location=2) mat4 worldMatrix; //The matrix that changes it from local to world. (translation and rotation)
  28. in layout(location=6) vec3 normal;  //The normal of each vertex
  29.  
  30.  
  31. uniform mat4 projAndViewMatrix; //The view and projection matrices.
  32.  
  33. out vec3 theNormal;     //We need to pass the normal to the fragment shader so that it can be interpolated and used.
  34. out vec3 thePos;    //Same for the position.
  35. out vec3 color;     //Same for colour.
  36.  
  37. void main()
  38. {
  39.     vec4 v = vec4(position, 1.0f);
  40.     vec4 relativePos = worldMatrix * v; //Here we calculate the relative position of this vertex in the world
  41.     gl_Position = projAndViewMatrix * relativePos; //Here we calculate where in regards to the screen it should be.
  42.     theNormal = vec3(worldMatrix * vec4(normal, 1)); //Send the rotated normal to the fragment shader.
  43.     //I know it should be vec4(normal, 0) to avoid the translation, but it works if I do.
  44.     color = inColor;
  45.     thePos = relativePos.xyz;
  46. }
  47.  
  48. //Main.cpp - Where most of the setup and drawing etc occurs. Only relevant code left behind.
  49. #define GLEW_STATIC
  50. #define _USE_MATH_DEFINES
  51. #define TRANSLATION_PER_FRAME 0.01f
  52.  
  53. #include "Shape.h"
  54. #include <SFML/System.hpp>
  55. #include <SFML/Window.hpp>
  56.  
  57. #include <fstream>
  58. #include <streambuf>
  59. #include <string>
  60. #include <cerrno>
  61. #include <cmath>
  62. #include <memory>
  63. #include <glm/glm.hpp>
  64. #include <glm/gtc/matrix_transform.hpp>
  65. #include <glm/gtc/type_ptr.hpp>
  66. #include <iostream>
  67. #include "Vertex.h"
  68. #include "GenerateShape.h"
  69. #include "Camera.h"
  70. #include "Prop.h"
  71. #include "OBJReader.h"
  72.  
  73.     bool running = true;
  74.  
  75. GLuint hollowCubicPolynomial(GLuint num)
  76. {
  77.     if(num == 1) return 1;
  78.             //Floor          +  The rest of the layers.
  79.     return pow((num*2-1), 2) + pow(((num-1)*2-1), 2);
  80. }
  81.  
  82. std::string get_file_contents(const char *filename)
  83. {
  84.     std::ifstream in(filename, std::ios::in | std::ios::binary);
  85.     if (in)
  86.     {
  87.         return(std::string((std::istreambuf_iterator<char>(in)), std::istreambuf_iterator<char>()));
  88.     }
  89.     throw(errno);
  90. }
  91.  
  92. GLuint compileShaders(void)
  93. {
  94.     GLint status;
  95.  
  96.     //Vertex shader
  97.     std::string src = get_file_contents("VertexShader.txt");
  98.     const char *vsSource = src.c_str();
  99.     GLuint vertexShader = glCreateShader(GL_VERTEX_SHADER);
  100.     glShaderSource(vertexShader, 1, &vsSource, NULL);
  101.     glCompileShader(vertexShader);
  102.     glGetShaderiv(vertexShader, GL_COMPILE_STATUS, &status);
  103.     if(status != GL_TRUE){
  104.         printf("Vertex shader didnt compile propely.\n%s\n", vsSource);
  105.         char buffer[512];
  106.         glGetShaderInfoLog(vertexShader, 512, NULL, buffer);
  107.         printf("%s\n", buffer);
  108.         sf::sleep(sf::seconds(10.f));    
  109.     }
  110.  
  111.     //Fragment shader
  112.     src = get_file_contents("FragmentShader.txt");
  113.     const GLchar* fsSource = src.c_str();
  114.     GLuint fragmentShader = glCreateShader(GL_FRAGMENT_SHADER);
  115.     glShaderSource(fragmentShader, 1, &fsSource, NULL);
  116.     glCompileShader(fragmentShader);
  117.     glGetShaderiv(fragmentShader, GL_COMPILE_STATUS, &status);
  118.     if(status != GL_TRUE){
  119.         printf("Fragment shader didnt compile propely.\n%s\n", fsSource);
  120.         char buffer[512];
  121.         glGetShaderInfoLog(fragmentShader, 512, NULL, buffer);
  122.         printf("%s\n", buffer);
  123.         sf::sleep(sf::seconds(10.f));    
  124.         running = false;
  125.     }
  126.  
  127.     //Compile the final shader
  128.     GLuint fullShader = glCreateProgram();
  129.     glAttachShader(fullShader, vertexShader);
  130.     glAttachShader(fullShader, fragmentShader);
  131.  
  132.     glBindFragDataLocation(fullShader, 0, "outColor");
  133.     glLinkProgram(fullShader);
  134.     glUseProgram(fullShader);  
  135.     return fullShader;
  136. }
  137.  
  138.  
  139. int main()
  140. {
  141.     //test();
  142.     //return 0;
  143.     sf::Window window(sf::VideoMode::getDesktopMode(), "OpenGL", sf::Style::Close);
  144.     window.setMouseCursorVisible(false);
  145.     width = window.getSize().x;
  146.     height = window.getSize().y;
  147.     window.setFramerateLimit(60);
  148.  
  149.     glewExperimental = GL_TRUE;
  150.     glewInit();
  151.     glEnable(GL_DEPTH_TEST);
  152.     glEnable(GL_CULL_FACE);
  153.     glEnable(GL_LIGHTING);
  154.    
  155.     GLuint numPuramidLevels = 25;
  156.    
  157.     Camera Camera;
  158.     Camera.setCenter(width, height);
  159.     shape myCube = GenerateShape::makeCube();
  160.     Prop testProp;
  161.     testProp.Shape = myCube;
  162.     testProp.matrices.resize(hollowCubicPolynomial(numPuramidLevels)+1);
  163.    
  164.     //The projection matrix will not change for this test program so I put it here at the top.
  165.     glm::mat4 projectionMatrix = glm::perspective(80.0f, (float)width/(float)height, 0.1f, 200.0f);
  166.    
  167.  
  168.     GLuint vao;
  169.     glGenVertexArrays(1, &vao);
  170.     glBindVertexArray(vao);
  171.  
  172.     //Load the test cube data.
  173.     GLuint vbo;
  174.     glGenBuffers(1, &vbo); //Maybe I should gen all the buffers at once?
  175.     glBindBuffer(GL_ARRAY_BUFFER, vbo);
  176.     glBufferData(GL_ARRAY_BUFFER, testProp.Shape.vertexBufferSize(), &testProp.Shape.vertices[0], GL_STATIC_DRAW);
  177.    
  178.     GLuint ebo;
  179.     glGenBuffers(1, &ebo);
  180.     glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ebo);
  181.     glBufferData(GL_ELEMENT_ARRAY_BUFFER,
  182.         myCube.indexBufferSize(), &myCube.indices[0], GL_DYNAMIC_DRAW);
  183.  
  184.     //Compile the shaders
  185.     GLuint fullShader = compileShaders();
  186.  
  187.     //Vertex attributes
  188.     GLint posAttrib = glGetAttribLocation(fullShader, "position");
  189.     glEnableVertexAttribArray(posAttrib);
  190.     glVertexAttribPointer(posAttrib, 3, GL_FLOAT, GL_FALSE,
  191.         9*sizeof(float), 0);
  192.  
  193.     GLint colAttrib = glGetAttribLocation(fullShader, "inColor");
  194.     glEnableVertexAttribArray(colAttrib);
  195.     glVertexAttribPointer(colAttrib, 3, GL_FLOAT, GL_FALSE,
  196.         9*sizeof(float), (void*)(3*sizeof(float)));
  197.  
  198.        
  199.    
  200.     //Lighting
  201.     GLuint ambientLightUniformLocation = glGetUniformLocation(fullShader, "ambientLight");
  202.     glm::vec3 ambientLight(0.05f, 0.05f, 0.05f);
  203.     glUniform3fv(ambientLightUniformLocation, 1, &ambientLight[0]);
  204.    
  205.     //This diffuse lighting uniform is the position in the world the light should originate from. I placed a cube there to
  206.     //represent the location when rendering.
  207.     GLuint diffuseLightUniformLocation = glGetUniformLocation(fullShader, "diffuseLightPos");
  208.     glm::vec3 diffuseLightPos(15.0f, -10.0f, 0.0f);
  209.     testProp.matrices[hollowCubicPolynomial(numPuramidLevels)] = glm::translate(glm::mat4(), diffuseLightPos);
  210.     glUniform3fv(diffuseLightUniformLocation, 1, &diffuseLightPos[0]);
  211.     //Since I need to apply the lighting after the translation and rotation, but before the world to view and projection, I need to
  212.     //send the matrices to be applied in the shader as we can not extract the rotation and translation from the final matrix.
  213.     GLuint projectionAndWorldToViewMatrixLocationID = glGetUniformLocation(fullShader, "projAndViewMatrix");
  214.     glm::mat4 worldMatrix = projectionMatrix*Camera.getWorld2ViewMatrix();
  215.     //The world matrix = translate + rotation
  216.     glUniformMatrix4fv(projectionAndWorldToViewMatrixLocationID, 1, GL_FALSE, &worldMatrix[0][0]);
  217.  
  218.     //The normal of each vertex also need to be sent to the
  219.     GLint normalAttrib = glGetAttribLocation(fullShader, "normal");
  220.     glEnableVertexAttribArray(normalAttrib);
  221.     glVertexAttribPointer(normalAttrib, 3, GL_FLOAT, GL_FALSE,
  222.         9*sizeof(float), (void*)(6*sizeof(float)));
  223.  
  224.    
  225.     //MatrixBuffer for the cubes
  226.     GLuint matricesBufferID;
  227.     glGenBuffers(1, &matricesBufferID);
  228.     glBindBuffer(GL_ARRAY_BUFFER, matricesBufferID);
  229.     glVertexAttribPointer(2, 4, GL_FLOAT, GL_FALSE, sizeof(glm::mat4), (void *)(sizeof(float) * 0));
  230.     glVertexAttribPointer(3, 4, GL_FLOAT, GL_FALSE, sizeof(glm::mat4), (void *)(sizeof(float) * 4));
  231.     glVertexAttribPointer(4, 4, GL_FLOAT, GL_FALSE, sizeof(glm::mat4), (void *)(sizeof(float) * 8));
  232.     glVertexAttribPointer(5, 4, GL_FLOAT, GL_FALSE, sizeof(glm::mat4), (void *)(sizeof(float) * 12));
  233.     glEnableVertexAttribArray(2);
  234.     glEnableVertexAttribArray(3);
  235.     glEnableVertexAttribArray(4);
  236.     glEnableVertexAttribArray(5);
  237.     glVertexAttribDivisor(2, 1);
  238.     glVertexAttribDivisor(3, 1);
  239.     glVertexAttribDivisor(4, 1);
  240.     glVertexAttribDivisor(5, 1);
  241.  
  242.     while(running){
  243.        
  244.         //Loads of code to handle keyboard and mouseinput.
  245.         //These commands will change the Camera matrix, or world to view matrix, and thus we need to rebuild the data being
  246.         //sent to the graphics card.
  247.         glBindBuffer(GL_ARRAY_BUFFER, matricesBufferID);
  248.         testProp.generateHollowCubeTowerMatrices(numPuramidLevels, glm::vec3(0.0f, 0.0f, 0.0f), &Camera, &projectionMatrix);   
  249.         worldMatrix = projectionMatrix*Camera.getWorld2ViewMatrix();
  250.         glUniformMatrix4fv(projectionAndWorldToViewMatrixLocationID, 1, GL_FALSE, &worldMatrix[0][0]);
  251.         glBufferData(GL_ARRAY_BUFFER, sizeof(glm::mat4)*testProp.matrices.size(), &testProp.matrices[0], GL_DYNAMIC_DRAW);
  252.  
  253.         // Clear the screen to black
  254.         glClearColor(0.1f, 0.1f, 0.1f, 1.0f);
  255.         glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
  256.         glViewport(0, 0, width, height);
  257.        
  258.         // Draw
  259.         glDrawElementsInstanced(GL_TRIANGLES, (GLsizei)testProp.Shape.numIndices, GL_UNSIGNED_SHORT, 0,
  260.         (GLsizei)testProp.matrices.size());
  261.  
  262.         // Swap buffers
  263.         window.display();
  264.     }
  265.     //Clean up
  266.     glDeleteProgram(fullShader);
  267.     glDeleteShader(fragmentShader);
  268.     glDeleteShader(vertexShader);
  269.  
  270.     glDeleteBuffers(1, &ebo);
  271.     glDeleteBuffers(1, &vbo);
  272.     glDeleteBuffers(1, &matricesBufferID);
  273.  
  274.     glDeleteVertexArrays(1, &vao);
  275.  
  276.     sf::sleep(sf::seconds(1.f));
  277.     return 0;
  278. }
  279.  
  280. //Cube data
  281. vertex verts[] = {
  282.         //Position          //Colour            //Normal vector         //Corner ID-Vertex ID
  283.         //Front
  284.         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
  285.         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
  286.         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
  287.         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
  288.         //Back                                                                                             
  289.         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
  290.         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
  291.         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
  292.         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
  293.         //Top                                                                                              
  294.         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
  295.         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
  296.         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
  297.         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
  298.         //Bottom                                                                                           
  299.         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
  300.         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
  301.         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
  302.         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
  303.         //Left                                                                 
  304.         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
  305.         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
  306.         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
  307.         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
  308.         //Right                                                                              
  309.         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
  310.         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
  311.         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
  312.         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
  313.  
  314.     };
  315.  
  316.     //Triangle sets
  317.     GLushort elements[] = {
  318.         //Front
  319.         0, 1, 3,
  320.         1, 2, 3,
  321.  
  322.         //Back                                                                                                             
  323.         5, 4, 6,
  324.         4, 7, 6,
  325.  
  326.         //Top  
  327.         11, 8, 10,
  328.         11, 9, 8,
  329.  
  330.         //Bottom           
  331.         13, 15, 14,
  332.         13, 12, 15,
  333.  
  334.         //Left 
  335.         19, 17, 18,
  336.         19, 16, 17,
  337.  
  338.         //Right
  339.         20, 23, 21,
  340.         20, 22, 23
  341.     };
  342.  
  343. //Vertex struct
  344. struct vertex{
  345. public:
  346.     glm::vec3 position;
  347.     glm::vec3 colour;
  348.     glm::vec3 normal;
  349.     //GLfloat alpha;
  350. };
  351.  
  352. //Generating the hollow pyramid.
  353.  
  354. void Prop::generateHollowCubeTowerMatrices(GLuint numLevels, glm::vec3 offset, Camera* camera, glm::mat4* projectionMatrix)
  355. {  
  356.     GLuint matrixLoc = 1;
  357.     //The start location in the ZX plain for the first cube in the next layer down.
  358.     glm::vec2 startCoord;
  359.     //Only the top is rotated 90 degrees around the Z axis for comparison.
  360.     matrices[0] = glm::rotate(glm::translate(glm::mat4(), offset),
  361.         90.0f, glm::vec3(0.0f, 0.0f, 1.0f));
  362.  
  363.     for(uint32_t i = 1; i < numLevels; ++i)//Skip the one we just made.
  364.     {
  365.         startCoord.x = (float)i+1;
  366.         startCoord.y = (float)i+1;
  367.  
  368.         for (uint32_t j = i*2+1; j  > 0; --j)
  369.         {
  370.             for (uint32_t k = i*2+1; k > 0; --k)
  371.             {
  372.                 //If we are at any of the edges OR it is the last level, then we "add a cube".
  373.                 //We are really adding the translation matrix so that the vertices are translated correctly.
  374.                 if (j==1 || j == i*2+1 || k==1 || k == i*2+1 || i == numLevels-1)
  375.                 {
  376.                     matrices[matrixLoc] =  
  377.                         glm::translate(glm::mat4(), glm::vec3((float)(startCoord.x - (float)j - offset.x),
  378.                          -(float)i + offset.y, (float)(startCoord.y - (float)k - offset.z)));
  379.                     ++matrixLoc;
  380.                 }
  381.             }
  382.         }
  383.     }
  384. }
  385.  
  386. //The camera and how it changes
  387. void Camera::moveForward()
  388. {
  389.     position += (MOVEMENT_SPEED*SPEEDBOOSTER) * viewDir;
  390. }
  391.  
  392. void Camera::moveBackward()
  393. {
  394.     position -= (MOVEMENT_SPEED*SPEEDBOOSTER) * viewDir;
  395. }
  396.  
  397. void Camera::strafeLeft()
  398. {
  399.     position += (MOVEMENT_SPEED*SPEEDBOOSTER) * strafeDir;
  400. }
  401.  
  402. void Camera::strafeRight()
  403. {
  404.     position -= (MOVEMENT_SPEED*SPEEDBOOSTER) * strafeDir;
  405. }
  406.  
  407. void Camera::ascend()
  408. {
  409.     position += (MOVEMENT_SPEED*SPEEDBOOSTER) * upVector;
  410. }
  411.  
  412. void Camera::descend()
  413. {
  414.     position -= (MOVEMENT_SPEED*SPEEDBOOSTER) * upVector;
  415. }
  416.  
  417. void Camera::setCenter(int width, int height) {
  418.         center.x = (float)width/2;
  419.         center.y = (float)height/2;
  420.     }
  421.  
  422. glm::mat4 getWorld2ViewMatrix() const{
  423.         //The lookat point is given by adding the viewDir to the position of the camera.
  424.         return glm::lookAt(position, position + viewDir, upVector);
  425.     }
Advertisement
Add Comment
Please, Sign In to add comment