Skip to content

Instantly share code, notes, and snippets.

@OllieReynolds
Created August 28, 2015 12:53
Show Gist options
  • Save OllieReynolds/71bc384009be2e2e7bb7 to your computer and use it in GitHub Desktop.
Save OllieReynolds/71bc384009be2e2e7bb7 to your computer and use it in GitHub Desktop.
#define GLFW_DLL
#include <GL/glew.h>
#include <GLFW/glfw3.h>
#include <glm\mat4x4.hpp>
#include <glm/gtc/type_ptr.hpp>
#include <glm\gtc\quaternion.hpp>
#include <glm\gtc\matrix_transform.hpp>
#include <SOIL.h>
#include <string>
#include "Shader.hpp"
#include "Cube.hpp"
#include "lighting.hpp"
#include "camera.hpp"
#include "material.hpp"
#include "utility.hpp"
#include "model.hpp"
#pragma region "Constants"
const char* TITLE = "Predator-Prey Simulation";
const float WIDTH = 1920.f;
const float HEIGHT = 1080.f;
const float FIELD_OF_VIEW = 90.f;
const float NEAR_PLANE = 0.1f;
const float FAR_PLANE = 100.f;
const glm::vec3 START_CAMERA_POSITION = glm::vec3(0.f, 2.f, 4.f);
const glm::vec3 START_CAMERA_FRONT = glm::vec3(0.f, 0.f, -1.f);
const glm::vec3 START_CAMERA_UP = glm::vec3(0.f, 1.f, 0.f);
const char* DEFAULT_VERTEX_SHADER_FILE = "vert.glsl";
const char* DEFAULT_FRAGMENT_SHADER_FILE = "frag.glsl";
const char* LIGHT_OBJECT_FRAGMENT_SHADER_FILE = "light.glsl";
const bool USE_POINT_LIGHTING = true;
const bool USE_DIRECTIONAL_LIGHTING = true;
const bool USE_SPOT_LIGHTING = true;
const int NUM_POINT_LIGHTS = 3;
#pragma endregion
Model model;
Material material;
PointLight pointLight[NUM_POINT_LIGHTS];
DirectionalLight directionalLight;
SpotLight spotLight;
Camera camera;
Orientation orientation;
FrameTiming frameTiming;
Input input;
Shader shader;
Shader lightShader;
Cube cube;
Cube cubeLamp;
GLFWwindow* window;
glm::mat4 projectionMatrix;
glm::vec3 cubePositions[] = {
glm::vec3(0.0f, 0.0f, 0.0f),
glm::vec3(2.0f, 5.0f, -4.0f),
glm::vec3(-1.5f, -2.2f, -2.5f),
glm::vec3(-3.8f, -2.0f, -6.3f),
glm::vec3(2.4f, -0.4f, -3.5f),
glm::vec3(-1.7f, 3.0f, -7.5f),
glm::vec3(1.3f, -2.0f, -2.5f),
glm::vec3(1.5f, 2.0f, -2.5f),
glm::vec3(1.5f, 0.2f, -1.5f),
glm::vec3(-1.3f, 1.0f, -1.5f)
};
GLuint amount = 104907;
glm::mat4* modelMatrices;
float* instanceColours;
void instancedRender() {
lightShader.use();
glUniformMatrix4fv(glGetUniformLocation(lightShader.program, "projection"), 1, GL_FALSE, value_ptr(projectionMatrix));
glUniformMatrix4fv(glGetUniformLocation(lightShader.program, "view"), 1, GL_FALSE, value_ptr(camera.viewMatrix));
glUniform3fv(glGetUniformLocation(lightShader.program, "pointLight.ambient"), 1, value_ptr(glm::vec3(1.f)));
glUniform3fv(glGetUniformLocation(lightShader.program, "pointLight.diffuse"), 1, value_ptr(glm::vec3(1.f)));
glUniform3fv(glGetUniformLocation(lightShader.program, "pointLight.specular"), 1, value_ptr(glm::vec3(1.f)));
glBindVertexArray(cube.vao);
glDrawArraysInstanced(GL_TRIANGLES, 0, 36, amount);
glBindVertexArray(0);
}
void initInstancedRender() {
lightShader = Shader(DEFAULT_VERTEX_SHADER_FILE, LIGHT_OBJECT_FRAGMENT_SHADER_FILE);
camera.position = START_CAMERA_POSITION;
camera.front = START_CAMERA_FRONT;
camera.up = START_CAMERA_UP;
camera.speed = 50.f;
camera.viewMatrix = lookAt(camera.position, camera.position + camera.front, camera.up);
projectionMatrix = glm::infinitePerspective(glm::radians(FIELD_OF_VIEW), WIDTH / HEIGHT, 0.1f);
modelMatrices = new glm::mat4[amount];
int index = 0;
for (GLint x = 0; x < 187; x++) {
for (GLint z = 0; z < 561; z++) {
glm::mat4 model;
model = glm::scale(model, glm::vec3(3.F, 1.F, 1.F));
model = glm::translate(model, glm::vec3(-x * 1.9F, 0.f, -z * 1.9F));
modelMatrices[index++] = model;
}
}
instanceColours = new float[amount];
std::fstream in;
in.open("data5.txt", std::fstream::in);
std::string line;
std::vector<float> v;
std::getline(in, line);
float value;
std::istringstream iss(line);
std::copy(std::istream_iterator<float>(iss),
std::istream_iterator<float>(),
std::back_inserter(v));
in.close();
int i1 = 0;
for (float f : v) {
instanceColours[i1] = v.at(i1);
i1++;
}
cube.init();
orientation.pitch = -25.f;
orientation.yaw = -90.f;
orientation.roll = 0.f;
input.previousMousePosX = WIDTH / 2.f;
input.previousMousePosY = HEIGHT / 2.f;
input.mouseInitiallyMoved = true;
input.mouseSensitivity = 0.2f;
GLuint buffer;
GLuint buffer2;
glBindVertexArray(cube.vao);
glGenBuffers(1, &buffer);
glBindBuffer(GL_ARRAY_BUFFER, buffer);
glBufferData(GL_ARRAY_BUFFER, amount * sizeof(glm::mat4), &modelMatrices[0], GL_STATIC_DRAW);
// Set attribute pointers for matrix (4 times vec4)
glEnableVertexAttribArray(3);
glVertexAttribPointer(3, 4, GL_FLOAT, GL_FALSE, sizeof(glm::mat4), (GLvoid*)0);
glEnableVertexAttribArray(4);
glVertexAttribPointer(4, 4, GL_FLOAT, GL_FALSE, sizeof(glm::mat4), (GLvoid*)(sizeof(glm::vec4)));
glEnableVertexAttribArray(5);
glVertexAttribPointer(5, 4, GL_FLOAT, GL_FALSE, sizeof(glm::mat4), (GLvoid*)(2 * sizeof(glm::vec4)));
glEnableVertexAttribArray(6);
glVertexAttribPointer(6, 4, GL_FLOAT, GL_FALSE, sizeof(glm::mat4), (GLvoid*)(3 * sizeof(glm::vec4)));
glVertexAttribDivisor(3, 1);
glVertexAttribDivisor(4, 1);
glVertexAttribDivisor(5, 1);
glVertexAttribDivisor(6, 1);
glGenBuffers(1, &buffer2);
glBindBuffer(GL_ARRAY_BUFFER, buffer2);
glBufferData(GL_ARRAY_BUFFER, amount * sizeof(float), &instanceColours[0], GL_STATIC_DRAW);
glEnableVertexAttribArray(7);
glVertexAttribPointer(7, 1, GL_FLOAT, GL_FALSE, sizeof(float), (GLvoid*)0);
glVertexAttribDivisor(7, 1);
glBindVertexArray(0);
}
void initSimulation()
{
shader = Shader(DEFAULT_VERTEX_SHADER_FILE, DEFAULT_FRAGMENT_SHADER_FILE);
lightShader = Shader(DEFAULT_VERTEX_SHADER_FILE, LIGHT_OBJECT_FRAGMENT_SHADER_FILE);
camera.position = START_CAMERA_POSITION;
camera.front = START_CAMERA_FRONT;
camera.up = START_CAMERA_UP;
camera.speed = 5.f;
camera.viewMatrix = lookAt(camera.position, camera.position + camera.front, camera.up);
projectionMatrix = glm::perspective(glm::radians(FIELD_OF_VIEW), WIDTH / HEIGHT, NEAR_PLANE, FAR_PLANE);
//RED
pointLight[0].ambient = glm::vec3(0.05f, 0.f, 0.0f);
pointLight[0].diffuse = glm::vec3(0.7f, 0.f, 0.0f);
pointLight[0].specular = glm::vec3(1.f, 0.f, 0.f);
pointLight[0].attenuation.constant = 1.f;
pointLight[0].attenuation.linear = 0.14f;
pointLight[0].attenuation.quadratic = 0.07f;
pointLight[0].position = glm::vec3(0.f);
//GREEN
pointLight[1].ambient = glm::vec3(0.0f, 0.05f, 0.0f);
pointLight[1].diffuse = glm::vec3(0.0f, 0.7f, 0.0f);
pointLight[1].specular = glm::vec3(0.f, 1.f, 0.f);
pointLight[1].attenuation.constant = 1.f;
pointLight[1].attenuation.linear = 0.14f;
pointLight[1].attenuation.quadratic = 0.07f;
pointLight[1].position = glm::vec3(1.f, 0.f, 0.f);
//BLUE
pointLight[2].ambient = glm::vec3(0.0f, 0.f, 0.05f);
pointLight[2].diffuse = glm::vec3(0.0f, 0.f, 0.9f);
pointLight[2].specular = glm::vec3(0.f, 0.f, 1.f);
pointLight[2].attenuation.constant = 1.f;
pointLight[2].attenuation.linear = 0.14f;
pointLight[2].attenuation.quadratic = 0.07f;
pointLight[2].position = glm::vec3(2.f, 0.f, 0.f);
directionalLight.ambient = glm::vec3(0.1f, 0.1f, 0.1f);
directionalLight.diffuse = glm::vec3(0.3f, 0.3f, 0.3f);
directionalLight.specular = glm::vec3(1.f, 1.f, 1.f);
directionalLight.direction = glm::vec3(0.f, 1.f, 0.f);
spotLight.ambient = glm::vec3(0.0f, 0.f, 1.f);
spotLight.diffuse = glm::vec3(0.0f, 0.f, 1.f);
spotLight.specular = glm::vec3(0.f, 0.f, 1.f);
spotLight.attenuation.constant = 1.f;
spotLight.attenuation.linear = 0.045f;
spotLight.attenuation.quadratic = 0.0075f;
spotLight.position = camera.position;
spotLight.direction = camera.front;
spotLight.innerCutoffAngle = 6.f;
spotLight.outerCutoffAngle = 20.f;
material.shininess = 32.f;
glGenTextures(1, &material.diffuseMap);
int width;
int height;
unsigned char* img;
img = SOIL_load_image("box_diffuse.png", &width, &height, nullptr, SOIL_LOAD_RGB);
glBindTexture(GL_TEXTURE_2D, material.diffuseMap);
glTexImage2D(GL_TEXTURE_2D, 0, GL_SRGB, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, img);
glGenerateMipmap(GL_TEXTURE_2D);
SOIL_free_image_data(img);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST_MIPMAP_NEAREST);
glGenTextures(1, &material.specularMap);
img = SOIL_load_image("box_specular.png", &width, &height, nullptr, SOIL_LOAD_RGB);
glBindTexture(GL_TEXTURE_2D, material.specularMap);
glTexImage2D(GL_TEXTURE_2D, 0, GL_SRGB, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, img);
glGenerateMipmap(GL_TEXTURE_2D);
SOIL_free_image_data(img);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST_MIPMAP_NEAREST);
cubeLamp = Cube();
cubeLamp.init();
cube = Cube();
cube.init();
model = Model("Metroid/metroid.DAE");
orientation.pitch = -25.f;
orientation.yaw = -90.f;
orientation.roll = 0.f;
input.previousMousePosX = WIDTH / 2.f;
input.previousMousePosY = HEIGHT / 2.f;
input.mouseInitiallyMoved = true;
input.mouseSensitivity = 0.2f;
}
void key_callback(GLFWwindow* window, int key, int scancode, int action, int mode);
void mouse_callback(GLFWwindow* window, double xpos, double ypos);
void moveCamera() {
auto movementFactor = camera.speed * frameTiming.deltaTime;
if (input.keyPressedStates[GLFW_KEY_W])
camera.position += camera.front * movementFactor;
if (input.keyPressedStates[GLFW_KEY_S])
camera.position -= camera.front * movementFactor;
if (input.keyPressedStates[GLFW_KEY_A])
camera.position -= normalize(cross(camera.front, camera.up)) * movementFactor;
if (input.keyPressedStates[GLFW_KEY_D])
camera.position += normalize(cross(camera.front, camera.up)) * movementFactor;
}
void renderObject()
{
shader.use();
glUniform3fv(glGetUniformLocation(shader.program, "cameraPosition"), 1, value_ptr(camera.position));
glUniform1i(glGetUniformLocation(shader.program, "material.diffuse"), 0);
glUniform1i(glGetUniformLocation(shader.program, "material.specular"), 1);
glUniform1f(glGetUniformLocation(shader.program, "material.shininess"), material.shininess);
for (auto i = 0; i < NUM_POINT_LIGHTS; i++)
{
auto index = std::to_string(i);
//pointLight[i].position.x = sin(glfwGetTime() + i * 300);
//pointLight[i].position.z = -2.f + cos(glfwGetTime() + i * 300);
//pointLight[i].position.y = 1.f;
glUniform3fv(glGetUniformLocation(shader.program, ("pointLight[" + index + "].ambient").c_str()), 1, value_ptr(pointLight[i].ambient));
glUniform3fv(glGetUniformLocation(shader.program, ("pointLight[" + index + "].diffuse").c_str()), 1, value_ptr(pointLight[i].diffuse));
glUniform3fv(glGetUniformLocation(shader.program, ("pointLight[" + index + "].specular").c_str()), 1, value_ptr(pointLight[i].specular));
glUniform3fv(glGetUniformLocation(shader.program, ("pointLight[" + index + "].position").c_str()), 1, value_ptr(pointLight[i].position));
glUniform1f(glGetUniformLocation(shader.program, ("pointLight[" + index + "].attenuation.constant").c_str()), pointLight[i].attenuation.constant);
glUniform1f(glGetUniformLocation(shader.program, ("pointLight[" + index + "].attenuation.linear").c_str()), pointLight[i].attenuation.linear);
glUniform1f(glGetUniformLocation(shader.program, ("pointLight[" + index + "].attenuation.quadratic").c_str()), pointLight[i].attenuation.quadratic);
}
glUniform3fv(glGetUniformLocation(shader.program, "directionalLight.ambient"), 1, value_ptr(directionalLight.ambient));
glUniform3fv(glGetUniformLocation(shader.program, "directionalLight.diffuse"), 1, value_ptr(directionalLight.diffuse));
glUniform3fv(glGetUniformLocation(shader.program, "directionalLight.specular"), 1, value_ptr(directionalLight.specular));
glUniform3fv(glGetUniformLocation(shader.program, "directionalLight.direction"), 1, value_ptr(directionalLight.direction));
spotLight.position = camera.position;
spotLight.direction = camera.front;
glUniform3fv(glGetUniformLocation(shader.program, "spotLight.ambient"), 1, value_ptr(spotLight.ambient));
glUniform3fv(glGetUniformLocation(shader.program, "spotLight.diffuse"), 1, value_ptr(spotLight.diffuse));
glUniform3fv(glGetUniformLocation(shader.program, "spotLight.specular"), 1, value_ptr(spotLight.specular));
glUniform3fv(glGetUniformLocation(shader.program, "spotLight.position"), 1, value_ptr(spotLight.position));
glUniform1f(glGetUniformLocation(shader.program, "spotLight.attenuation.constant"), spotLight.attenuation.constant);
glUniform1f(glGetUniformLocation(shader.program, "spotLight.attenuation.linear"), spotLight.attenuation.linear);
glUniform1f(glGetUniformLocation(shader.program, "spotLight.attenuation.quadratic"), spotLight.attenuation.quadratic);
glUniform3fv(glGetUniformLocation(shader.program, "spotLight.position"), 1, value_ptr(spotLight.position));
glUniform3fv(glGetUniformLocation(shader.program, "spotLight.direction"), 1, value_ptr(spotLight.direction));
glUniform1f(glGetUniformLocation(shader.program, "spotLight.innerCutoffAngle"), glm::cos(glm::radians(spotLight.innerCutoffAngle)));
glUniform1f(glGetUniformLocation(shader.program, "spotLight.outerCutoffAngle"), glm::cos(glm::radians(spotLight.outerCutoffAngle)));
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, material.diffuseMap);
glActiveTexture(GL_TEXTURE1);
glBindTexture(GL_TEXTURE_2D, material.specularMap);
for (auto i = 0; i < 10; i++)
{
glm::mat4 model;
model = translate(model, cubePositions[i]);
model = rotate(model, 0.f, glm::vec3(1.0f, 0.3f, 0.5f));
auto MVP = projectionMatrix * camera.viewMatrix * model;
glUniformMatrix4fv(glGetUniformLocation(shader.program, "MVP"), 1, GL_FALSE, value_ptr(MVP));
glUniformMatrix4fv(glGetUniformLocation(shader.program, "modelMatrix"), 1, GL_FALSE, value_ptr(model));
cube.render();
}
glm::mat4 m;
m = translate(m, glm::vec3(0.0f, -1.75f, -2.0f));
m = scale(m, glm::vec3(0.05f, 0.05f, 0.05f));
auto MVP = projectionMatrix * camera.viewMatrix * m;
glUniformMatrix4fv(glGetUniformLocation(shader.program, "MVP"), 1, GL_FALSE, value_ptr(MVP));
glUniformMatrix4fv(glGetUniformLocation(shader.program, "modelMatrix"), 1, GL_FALSE, value_ptr(m));
model.draw(shader);
}
void renderPointLight()
{
lightShader.use();
for (auto i = 0; i < 3; i++) {
glm::mat4 model;
model = translate(model, pointLight[i].position);
auto MVP = projectionMatrix * camera.viewMatrix * model;
glUniformMatrix4fv(glGetUniformLocation(lightShader.program, "MVP"), 1, GL_FALSE, value_ptr(MVP));
glUniform3fv(glGetUniformLocation(lightShader.program, "pointLight.ambient"), 1, value_ptr(pointLight[i].ambient));
glUniform3fv(glGetUniformLocation(lightShader.program, "pointLight.diffuse"), 1, value_ptr(pointLight[i].diffuse));
glUniform3fv(glGetUniformLocation(lightShader.program, "pointLight.specular"), 1, value_ptr(pointLight[i].specular));
cubeLamp.render();
}
}
void updateSimulation()
{
frameTiming.updateDeltaTime();
camera.viewMatrix = lookAt(camera.position, camera.position + camera.front, camera.up);
moveCamera();
}
void renderSimulation()
{
instancedRender();
//renderObject();
//renderPointLight();
}
int main()
{
glfwInit();
//glfwWindowHint(GLFW_SAMPLES, 4);
glfwWindowHint(GLFW_SRGB_CAPABLE, true);
window = glfwCreateWindow(static_cast<int>(WIDTH), static_cast<int>(HEIGHT), TITLE, nullptr, nullptr);
glfwMakeContextCurrent(window);
glfwSetKeyCallback(window, key_callback);
glfwSetCursorPos(window, WIDTH / 2, HEIGHT / 2);
glfwSetCursorPosCallback(window, mouse_callback);
glewExperimental = GL_TRUE;
glewInit();
glEnable(GL_FRAMEBUFFER_SRGB);
//glEnable(GL_MULTISAMPLE);
glEnable(GL_DEPTH_TEST);
glDepthFunc(GL_LESS);
//initSimulation();
glClearColor(0.f, 0.f, 0.f, 1.f);
initInstancedRender();
while (!glfwWindowShouldClose(window))
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
updateSimulation();
renderSimulation();
glfwSwapBuffers(window);
glfwPollEvents();
}
glfwTerminate();
return 0;
}
void key_callback(GLFWwindow* window, int key, int /*scancode*/, int action, int /*mode*/)
{
if (action == GLFW_PRESS)
{
input.keyPressedStates[key] = true;
}
else if (action == GLFW_RELEASE)
{
input.keyPressedStates[key] = false;
}
if (key == GLFW_KEY_ESCAPE && action == GLFW_PRESS)
glfwSetWindowShouldClose(window, GL_TRUE);
}
void mouse_callback(GLFWwindow* /*window*/, double xpos, double ypos)
{
if (input.mouseInitiallyMoved)
{
input.previousMousePosX = xpos;
input.previousMousePosY = ypos;
input.mouseInitiallyMoved = false;
}
float xOffset = (xpos - input.previousMousePosX) * input.mouseSensitivity;
float yOffset = (input.previousMousePosY - ypos) * input.mouseSensitivity;
input.previousMousePosX = xpos;
input.previousMousePosY = ypos;
orientation.yaw += xOffset;
orientation.pitch += yOffset;
if (orientation.pitch > 89.f)
orientation.pitch = 89.f;
else if (orientation.pitch < -89.f)
{
orientation.pitch = -89.f;
}
glm::vec3 front;
front.x = cos(glm::radians(orientation.yaw)) * cos(glm::radians(orientation.pitch));
front.y = sin(glm::radians(orientation.pitch));
front.z = sin(glm::radians(orientation.yaw)) * cos(glm::radians(orientation.pitch));
camera.front = normalize(front);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment