Last active
August 29, 2015 14:10
-
-
Save elliotpotts/e84f1737fa0ed71abdbd to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#version 440 | |
smooth in vec3 out_normal; | |
out vec4 colour; | |
void main() { | |
colour = vec4(out_normal, 1.0); | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <iostream> | |
#include <GL/glew.h> | |
#include <GLFW/glfw3.h> | |
#include <oglplus/all.hpp> | |
#include <oglplus/interop/glm.hpp> | |
#include <memory> | |
#include <string> | |
#include <vector> | |
#include <random> | |
#include <glm/glm.hpp> | |
#include <glm/gtc/matrix_transform.hpp> | |
#include <glm/gtc/quaternion.hpp> | |
#include <tinyobjloader/tiny_obj_loader.h> | |
#include <btBulletDynamicsCommon.h> | |
#include <btBulletCollisionCommon.h> | |
#include "micro/MeshRenderer.hpp" | |
class Suzanne { | |
private: | |
std::unique_ptr<btSphereShape> shape; | |
std::unique_ptr<btDefaultMotionState> motion_state; | |
std::unique_ptr<btRigidBody> body; | |
public: | |
Suzanne(btDiscreteDynamicsWorld& world, glm::vec3 position = {0.0f, 0.0f, 0.0f}) : | |
shape(std::make_unique<btSphereShape>(0.8)), | |
motion_state(std::make_unique<btDefaultMotionState>(btTransform(btQuaternion::getIdentity(), btVector3(position.x, position.y, position.z)))) | |
{ | |
btScalar mass = 1; | |
btVector3 fall_inertia; | |
shape->calculateLocalInertia(mass, fall_inertia); | |
auto construction_info = btRigidBody::btRigidBodyConstructionInfo{mass, motion_state.get(), shape.get(), fall_inertia}; | |
body = std::make_unique<btRigidBody>(construction_info); | |
world.addRigidBody(body.get()); | |
}; | |
glm::mat4 model() { | |
return glm::translate(glm::mat4(), position()) * glm::mat4_cast(orientation()); | |
} | |
glm::vec3 position() { | |
btTransform transform; | |
motion_state->getWorldTransform(transform); | |
return {transform.getOrigin().getX(), transform.getOrigin().getY(), transform.getOrigin().getZ()}; | |
} | |
glm::quat orientation() { | |
btTransform transform; | |
motion_state->getWorldTransform(transform); | |
return glm::angleAxis( | |
transform.getRotation().getAngle(), | |
glm::normalize(glm::vec3( | |
transform.getRotation().getAxis().getX(), | |
transform.getRotation().getAxis().getY(), | |
transform.getRotation().getAxis().getZ() | |
)) | |
); | |
} | |
void apply_impulse(glm::vec3 impulse) { | |
body->applyCentralImpulse(btVector3(impulse.x, impulse.y, impulse.z)); | |
} | |
}; | |
static micro::Mesh load_suzanne() { | |
std::vector<tinyobj::shape_t> shapes; | |
std::vector<tinyobj::material_t> materials; | |
std::string error = tinyobj::LoadObj(shapes, materials, "assets/suzzane.obj"); | |
std::cout << error << "\n"; | |
return {shapes[0].mesh}; | |
} | |
using gl = oglplus::Context; | |
void error_callback(int error, const char* description) { | |
std::cout << "Error " << error << "\n"; | |
std::cout << description << "\n"; | |
} | |
int main() { | |
glfwSetErrorCallback(error_callback); | |
if(!glfwInit()) { | |
std::cout << "glfw didn't init\n"; | |
return -1; | |
} | |
glfwWindowHint(GLFW_SAMPLES, 80); | |
GLFWwindow* window = glfwCreateWindow(640, 480, "Hello, World", nullptr, nullptr); | |
if(!window) { | |
std::cout << "couldn't create window\n"; | |
glfwTerminate(); | |
return -1; | |
} | |
glfwMakeContextCurrent(window); | |
if(glewInit() != GLEW_OK) { | |
std::cout << "glew didn't init\n"; | |
return -1; | |
} | |
auto broadphase = std::make_unique<btDbvtBroadphase>(); | |
auto collision_configuration = std::make_unique<btDefaultCollisionConfiguration>(); | |
auto collision_dispatcher = std::make_unique<btCollisionDispatcher>(collision_configuration.get()); | |
auto solver = std::make_unique<btSequentialImpulseConstraintSolver>(); | |
auto world = std::make_unique<btDiscreteDynamicsWorld>(collision_dispatcher.get(), broadphase.get(), solver.get(), collision_configuration.get()); | |
world->setGravity(btVector3(0, -10, 0)); | |
auto ground_shape = std::make_unique<btStaticPlaneShape>(btVector3(0, 1, 0), 0); | |
auto ground_motion_state = std::make_unique<btDefaultMotionState>(btTransform(btQuaternion(0, 0, 0, 1), btVector3(0, 0, 0))); | |
auto ground_construction_info = btRigidBody::btRigidBodyConstructionInfo{0, ground_motion_state.get(), ground_shape.get(), btVector3(0, 0, 0)}; | |
auto ground_rigid_body = std::make_unique<btRigidBody>(ground_construction_info); | |
world->addRigidBody(ground_rigid_body.get()); | |
std::vector<Suzanne> suzannes; | |
{ | |
std::mt19937 random_engine; | |
std::uniform_real_distribution<double> random_range(0.0, 50.0); | |
for(int i = 0; i < 30; i++) { | |
suzannes.emplace_back(*world, glm::vec3(random_range(random_engine), random_range(random_engine), random_range(random_engine))); | |
} | |
} | |
Suzanne suzanne(*world, glm::vec3(0.0f, 50.0f, 0.0f)); | |
micro::Mesh suzanne_mesh = load_suzanne(); | |
micro::MeshRenderer renderer; | |
auto projection = glm::infinitePerspective(90.0f, 1.0f, 0.004f); | |
double camera_ρ = 1.0; | |
double camera_θ = 1.0; | |
double camera_φ = 0.0; | |
auto global_up = glm::vec3(0.0f, 1.0f, 0.0f); | |
auto origin = glm::vec3(0.0f, 0.0f, 0.0f); | |
while(!glfwWindowShouldClose(window)) { | |
glfwPollEvents(); | |
int width, height; | |
glfwGetFramebufferSize(window, &width, &height); | |
gl::Viewport(width, height); | |
projection = glm::infinitePerspective(90.0f, static_cast<float>(width)/static_cast<float>(height), 0.004f); | |
if(glfwGetKey(window, GLFW_KEY_LEFT) == GLFW_PRESS) { | |
camera_φ -= 0.05; | |
suzanne.apply_impulse({1.0f, 0.0f, 1.0f}); | |
} | |
if(glfwGetKey(window, GLFW_KEY_RIGHT) == GLFW_PRESS) { | |
camera_φ += 0.05; | |
suzanne.apply_impulse({-1.0f, 0.0f, -1.0f}); | |
} | |
if(glfwGetKey(window, GLFW_KEY_UP) == GLFW_PRESS) { | |
camera_θ += 0.05; | |
} | |
if(glfwGetKey(window, GLFW_KEY_DOWN) == GLFW_PRESS) { | |
camera_θ -= 0.05; | |
} | |
if(glfwGetKey(window, GLFW_KEY_LEFT_SHIFT) == GLFW_PRESS) { | |
camera_ρ -= 0.05; | |
} | |
if(glfwGetKey(window, GLFW_KEY_LEFT_CONTROL) == GLFW_PRESS) { | |
camera_ρ += 0.05; | |
} | |
camera_φ = glm::mod(camera_φ, 2.0 * glm::pi<double>()); | |
camera_θ = glm::mod(camera_θ, 2.0 * glm::pi<double>()); | |
glm::tvec3<float> camera_pos( | |
camera_ρ * std::sin(camera_θ) * std::sin(camera_φ), | |
camera_ρ * std::cos(camera_θ), | |
camera_ρ * std::sin(camera_θ) * std::cos(camera_φ) | |
); | |
camera_pos.x = 0.0f; | |
camera_pos.y = 10.0f; | |
camera_pos.z = -4.0f; | |
world->stepSimulation(1 / 50.f, 0); | |
renderer.Render( | |
suzanne.model(), | |
glm::lookAt(camera_pos, suzanne.position(), global_up), | |
projection, | |
suzanne_mesh | |
); | |
/* Commenting out this section fixes it! */ | |
for(auto& s : suzannes) { | |
renderer.Render( | |
s.model(), | |
glm::lookAt(camera_pos, suzanne.position(), global_up), | |
projection, | |
suzanne_mesh | |
); | |
} | |
/* commenting out the above section fixes it */ | |
glfwSwapBuffers(window); | |
} | |
glfwDestroyWindow(window); | |
glfwTerminate(); | |
return 0; | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
void micro::MeshRenderer::Render(glm::mat4 model, glm::mat4 view, glm::mat4 projection, const Mesh& mesh) { | |
program.Use(); | |
model_uniform.Set(model); | |
view_uniform.Set(view); | |
projection_uniform.Set(projection); | |
oglplus::VertexArray vertex_attributes; | |
vertex_attributes.Bind(); | |
oglplus::VertexArrayAttrib position(program, "position"); | |
mesh.positions.Bind(oglplus::Buffer::Target::Array); | |
position.Setup<float>(3); | |
position.Enable(); | |
oglplus::VertexArrayAttrib normal(program, "in_normal"); | |
mesh.normals.Bind(oglplus::Buffer::Target::Array); | |
normal.Setup<float>(3); | |
normal.Enable(); | |
mesh.elements.Bind(oglplus::Buffer::Target::ElementArray); | |
gl::Clear().ColorBuffer(); | |
gl::Clear().DepthBuffer(); | |
gl::DrawElements(oglplus::PrimitiveType::Triangles, oglplus::Buffer::Size(oglplus::Buffer::Target::ElementArray), oglplus::DataType::UnsignedInt); | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#version 440 | |
in vec3 position; | |
in vec3 in_normal; | |
out vec3 out_normal; | |
uniform mat4 model; | |
uniform mat4 view; | |
uniform mat4 projection; | |
void main() { | |
out_normal = in_normal; | |
gl_Position = projection * view * model * vec4(position, 1.0); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment