aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/main.cc143
-rw-r--r--src/window.h59
2 files changed, 130 insertions, 72 deletions
diff --git a/src/main.cc b/src/main.cc
index a691322..7446609 100644
--- a/src/main.cc
+++ b/src/main.cc
@@ -8,6 +8,8 @@
#include <memory>
#include <algorithm>
+#include "window.h"
+
#include "particle_vertex_buffer.h"
#include "texture_display_buffer.h"
@@ -26,18 +28,11 @@ const unsigned int particle_count = 2500;
const unsigned int max_ups = 100;
const unsigned int texture_count = 20;
-unsigned int window_width = 800;
-unsigned int window_height = 600;
-float world_width, world_height;
-glm::mat4 MVP;
-
-std::vector<std::unique_ptr<TextureBuffer>> textureBuffers;
-std::unique_ptr<ParticleVertexBuffer> particleBuffer;
-
-void updateMVP() {
- world_width = 20.f;
- world_height = world_width / window_width * window_height;
+float getWorldHeight(int window_width, int window_height, float world_width) {
+ return world_width / window_width * window_height;
+}
+glm::mat4 getMVP(float world_width, float world_height) {
glm::mat4 projection = glm::ortho(
-(world_width /2), world_width/2,
-(world_height/2), world_height/2,
@@ -50,21 +45,10 @@ void updateMVP() {
glm::vec3(0,1,0)
);
- MVP = projection * view;
-}
-
-void window_size_callback(GLFWwindow*, int width, int height) {
- window_width = width;
- window_height = height;
-
- for ( auto& textureBuffer : textureBuffers ) {
- textureBuffer->resize(width, height);
- }
-
- updateMVP();
+ return projection * view;
}
-std::vector<GLfloat> makeInitialParticles(std::size_t count) {
+std::vector<GLfloat> makeInitialParticles(std::size_t count, float world_width, float world_height) {
std::vector<GLfloat> buffer;
buffer.reserve(3*count);
@@ -92,106 +76,121 @@ std::string getShaderFunction(const std::string& fx, const std::string& fy) {
int main() {
if( !glfwInit() ) {
- std::cerr << "Failed to initialize GLFW" << std::endl;
+ std::cerr << "Failed to initialize GLFW." << std::endl;
return -1;
}
- GLFWwindow* const window = glfwCreateWindow(window_width, window_height, "computicle", NULL, NULL);
+ Window window("computicle");
- if( window == nullptr ){
- std::cerr << "Failed to open GLFW window." << std::endl;
+ if ( !window.isGood() ) {
+ std::cerr << "Failed to open window." << std::endl;
glfwTerminate();
return -1;
}
- glfwSetWindowSizeCallback(window, window_size_callback);
- glfwMakeContextCurrent(window);
- if ( glewInit() != GLEW_OK ) {
- std::cerr << "Failed to initialize GLEW" << std::endl;
- glfwTerminate();
- return -1;
- }
+ int window_width = window.getWidth();
+ int window_height = window.getHeight();
- updateMVP();
+ float world_width = 20.0;
+ float world_height = getWorldHeight(window_width, window_height, world_width);
- for ( unsigned int i = 0; i < texture_count; ++i ) {
- textureBuffers.emplace_back(
- new TextureBuffer(window_width, window_height));
- }
+ glm::mat4 MVP = getMVP(world_width, world_height);
+
+ std::vector<std::unique_ptr<TextureBuffer>> texture_buffers;
+
+ std::unique_ptr<ParticleVertexBuffer> particle_buffer;
+ std::unique_ptr<TextureDisplayBuffer> display_buffer;
- particleBuffer = std::make_unique<ParticleVertexBuffer>(
- makeInitialParticles(particle_count));
+ std::unique_ptr<GraphicShader> scene_shader;
+ std::unique_ptr<ComputeShader> compute_shader;
+ std::unique_ptr<GraphicShader> display_shader;
- GraphicShader sceneShader(VERTEX_SHADER_CODE, FRAGMENT_SHADER_CODE);
+ window.init([&]() {
+ for ( unsigned int i = 0; i < texture_count; ++i ) {
+ texture_buffers.emplace_back(
+ new TextureBuffer(window_width, window_height));
+ }
- ComputeShader computeShader(
- getShaderFunction("cos(v.x*sin(v.y))",
- "sin(v.x-v.y)"));
- computeShader.workOn(particleBuffer->getBuffer());
+ particle_buffer = std::make_unique<ParticleVertexBuffer>(
+ makeInitialParticles(particle_count, world_width, world_height));
+ display_buffer = std::make_unique<TextureDisplayBuffer>();
- GraphicShader displayShader(DISPLAY_VERTEX_SHADER_CODE,
- DISPLAY_FRAGMENT_SHADER_CODE);
- TextureDisplayBuffer displayBuffer;
+ scene_shader = std::make_unique<GraphicShader>(
+ VERTEX_SHADER_CODE, FRAGMENT_SHADER_CODE);
+ compute_shader = std::make_unique<ComputeShader>(
+ getShaderFunction("cos(v.x*sin(v.y))",
+ "sin(v.x-v.y)"));
+ compute_shader->workOn(particle_buffer->getBuffer());
+ display_shader = std::make_unique<GraphicShader>(
+ DISPLAY_VERTEX_SHADER_CODE, DISPLAY_FRAGMENT_SHADER_CODE);
+ });
auto lastFrame = std::chrono::high_resolution_clock::now();
auto lastRotate = std::chrono::high_resolution_clock::now();
bool justRotated = true;
std::vector<GLuint> textures;
- for ( const auto& textureBuffer : textureBuffers ) {
- textures.emplace_back(textureBuffer->getTexture());
+ for ( const auto& texture_buffer : texture_buffers ) {
+ textures.emplace_back(texture_buffer->getTexture());
}
- do {
+ window.render([&]() {
+ if ( window.getWidth() != window_width
+ || window.getHeight() != window_height ) {
+ window_width = window.getWidth();
+ window_height = window.getHeight();
+ world_height = getWorldHeight(window_width, window_height, world_width);
+
+ MVP = getMVP(world_width, world_height);
+
+ for ( auto& texture_buffer : texture_buffers ) {
+ texture_buffer->resize(window_width, window_height);
+ }
+ }
+
if ( util::millisecondsSince(lastFrame) >= 1000/max_ups ) {
- auto guard = computeShader.use();
+ auto guard = compute_shader->use();
- computeShader.setUniform("world", world_width, world_height);
- computeShader.dispatch(particle_count);
+ compute_shader->setUniform("world", world_width, world_height);
+ compute_shader->dispatch(particle_count);
lastFrame = std::chrono::high_resolution_clock::now();
}
if ( util::millisecondsSince(lastRotate) >= 1000/10 ) {
std::rotate(textures.begin(), textures.end()-1, textures.end());
- std::rotate(textureBuffers.begin(), textureBuffers.end()-1, textureBuffers.end());
+ std::rotate(texture_buffers.begin(), texture_buffers.end()-1, texture_buffers.end());
justRotated = true;
lastRotate = std::chrono::high_resolution_clock::now();
}
{
- auto texGuard = textureBuffers[0]->use();
- auto sdrGuard = sceneShader.use();
+ auto texGuard = texture_buffers[0]->use();
+ auto sdrGuard = scene_shader->use();
- sceneShader.setUniform("MVP", MVP);
+ scene_shader->setUniform("MVP", MVP);
if ( justRotated ) {
glClear(GL_COLOR_BUFFER_BIT);
justRotated = false;
}
- particleBuffer->draw();
+ particle_buffer->draw();
}
{
- auto guard = displayShader.use();
+ auto guard = display_shader->use();
- displayShader.setUniform("screen_textures", textures);
- displayShader.setUniform("screen_textures_size", textures.size());
+ display_shader->setUniform("screen_textures", textures);
+ display_shader->setUniform("screen_textures_size", textures.size());
glClear(GL_COLOR_BUFFER_BIT);
- displayBuffer.draw(textures);
+ display_buffer->draw(textures);
}
-
- glfwSwapBuffers(window);
- glfwPollEvents();
- }
- while( glfwGetKey(window, GLFW_KEY_ESCAPE ) != GLFW_PRESS &&
- glfwWindowShouldClose(window) == 0 );
+ });
glfwTerminate();
-
return 0;
}
diff --git a/src/window.h b/src/window.h
new file mode 100644
index 0000000..76f1e6a
--- /dev/null
+++ b/src/window.h
@@ -0,0 +1,59 @@
+#pragma once
+
+class Window {
+private:
+ bool _good = false;
+ int _width = 800;
+ int _height = 600;
+
+ GLFWwindow* const _handle;
+
+public:
+ Window(const std::string& title):
+ _handle(glfwCreateWindow(_width, _height, title.c_str(), NULL, NULL)) {
+ if ( _handle != nullptr ) {
+ glfwMakeContextCurrent(_handle);
+ if ( glewInit() == GLEW_OK ) {
+ _good = true;
+ }
+ glfwMakeContextCurrent(nullptr);
+ }
+ }
+
+ bool isGood() const {
+ return _good;
+ }
+
+ int getWidth() const {
+ return _width;
+ }
+
+ int getHeight() const {
+ return _height;
+ }
+
+ template <class F>
+ void init(F f) {
+ glfwMakeContextCurrent(_handle);
+ f();
+ glfwMakeContextCurrent(nullptr);
+ }
+
+ template <class F>
+ void render(F loop) {
+ glfwMakeContextCurrent(_handle);
+
+ while ( glfwGetKey(_handle, GLFW_KEY_ESCAPE ) != GLFW_PRESS &&
+ glfwWindowShouldClose(_handle) == 0 ) {
+ glfwGetWindowSize(_handle, &_width, &_height);
+
+ loop();
+
+ glfwSwapBuffers(_handle);
+ glfwPollEvents();
+ }
+
+ glfwMakeContextCurrent(nullptr);
+ }
+
+};