Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #version 150
- in vec2 Tex_coord;
- out vec4 outColor;
- uniform sampler2D tex;
- void main() {
- outColor = texture(tex, Tex_coord);
- }
- #version 150
- in vec2 position;
- in vec2 tex_coord;
- out vec2 Tex_coord;
- void main() {
- gl_Position = vec4(position, 0.0, 1.0);
- Tex_coord = tex_coord;
- }
- #include "Draw_Buffer.h"
- #include <memory>
- #include <algorithm>
- #include <stdexcept>
- #include <vector>
- #include <sstream>
- #include <fstream>
- #include <string>
- // Util function to compile a shader from source
- void compile_shader(GLuint &shader, const std::string &src) {
- std::ifstream is(src);
- std::string code;
- std::string temp_str;
- while (std::getline(is, temp_str)) {
- code += temp_str + 'n';
- }
- const char *c_code = code.c_str();
- glShaderSource(shader, 1, &c_code, NULL);
- glCompileShader(shader);
- }
- Draw_Buffer::Draw_Buffer(Window<int> *win, const std::string &vertex_shader_src, const std::string &frag_shader_src) :
- window(win), buffer(std::vector<RGB>(window->size())), pos_iter(buffer.begin()) {
- // Initialise GLFW
- if (!glfwInit()) {
- throw std::runtime_error("error: GLFW unable to initialise");
- }
- // Set up the window
- glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
- glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 2);
- glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
- glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE);
- glfwWindowHint(GLFW_RESIZABLE, GL_FALSE);
- screen.reset(glfwCreateWindow(win->width(), win->height(), "Mandelbrot Fractal", nullptr, nullptr));
- make_current();
- // Initialise glew
- glewExperimental = GL_TRUE;
- GLenum glewinit = glewInit();
- if (glewinit != GLEW_OK) {
- std::ostringstream ss;
- ss << "error: Glew unable to initialise" << glewinit;
- throw std::runtime_error(ss.str());
- }
- // Clear
- glClearColor(0, 0, 0, 0);
- glClear(GL_COLOR_BUFFER_BIT);
- // Generate shaders
- GLuint vertex_shader = glCreateShader(GL_VERTEX_SHADER);
- GLuint frag_shader = glCreateShader(GL_VERTEX_SHADER);
- GLint compile_status;
- compile_shader(vertex_shader, vertex_shader_src);
- glGetShaderiv(vertex_shader, GL_COMPILE_STATUS, &compile_status);
- if (compile_status != GL_TRUE) {
- char buffer[512];
- glGetShaderInfoLog(vertex_shader, 512, NULL, buffer);
- throw std::runtime_error(buffer);
- }
- compile_shader(frag_shader, frag_shader_src);
- glGetShaderiv(frag_shader, GL_COMPILE_STATUS, &compile_status);
- if (compile_status != GL_TRUE) {
- char buffer[512];
- glGetShaderInfoLog(frag_shader, 512, NULL, buffer);
- throw std::runtime_error(buffer);
- }
- // Put shaders into shader program
- shader_prog = glCreateProgram();
- glAttachShader(shader_prog, vertex_shader);
- glAttachShader(shader_prog, frag_shader);
- glBindFragDataLocation(shader_prog, 0, "outColor");
- glLinkProgram(shader_prog);
- glUseProgram(shader_prog);
- // Set shader attributes
- GLint pos_attrib = glGetAttribLocation(shader_prog, "position");
- glVertexAttribPointer(pos_attrib, 2, GL_FLOAT, GL_FALSE, 4 * sizeof(GLfloat), 0);
- glEnableVertexAttribArray(pos_attrib);
- GLint tex_coord_attrib = glGetAttribLocation(shader_prog, "tex_coord");
- glEnableVertexAttribArray(tex_coord_attrib);
- glVertexAttribPointer(tex_coord_attrib, 2, GL_FLOAT, GL_FALSE,
- 4 * sizeof(GLfloat), (void*)(2 * sizeof(GLfloat)));
- // Generate texture
- glGenTextures(1, &mandelbrot_tex);
- }
- Draw_Buffer::~Draw_Buffer() {
- // Terminate GLFW
- glfwTerminate();
- }
- void Draw_Buffer::flush() {
- // Render pixels to image
- glBindTexture(GL_TEXTURE_2D, mandelbrot_tex);
- glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, window->width(), window->height(), 0, GL_RGB, GL_FLOAT, &buffer[0]);
- 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);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
- // Draw a rectangle
- const static GLfloat vertices[] = {
- // Position Tex-coords
- -1.0f, 1.0f, 0.0f, 0.0f, // Top-left
- 1.0f, 1.0f, 1.0f, 0.0f, // Top-right
- 1.0f, -1.0f, 1.0f, 1.0f, // Bottom-right
- -1.0f, -1.0f, 0.0f, 1.0f // Bottom-left
- };
- GLuint vbo;
- glGenBuffers(1, &vbo);
- glBindBuffer(GL_ARRAY_BUFFER, vbo);
- glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STREAM_DRAW);
- const static GLuint elements[] = {
- 0, 1, 2,
- 2, 3, 0
- };
- GLuint ebo;
- glGenBuffers(1, &ebo);
- glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ebo);
- glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(elements), elements, GL_STREAM_DRAW);
- glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0);
- glfwSwapBuffers(screen.get());
- }
- void Draw_Buffer::keep_window_open() {
- while(!glfwWindowShouldClose(screen.get())) {
- glfwPollEvents();
- }
- }
- Draw_Buffer &operator<<(Draw_Buffer &db, const RGB &pixel) {
- if (db.pos_iter != db.buffer.end()) {
- *(db.pos_iter) = pixel;
- ++db.pos_iter;
- return db;
- }
- else {
- throw std::runtime_error("error: Cannot append past end of buffer : Remember to flush the buffer");
- return db;
- }
- }
- #include "Window.h"
- #include "Cleanup.h"
- struct RGB {
- float r;
- float g;
- float b;
- };
- class Draw_Buffer {
- friend Draw_Buffer &operator<<(Draw_Buffer &db, const RGB &pixel);
- std::unique_ptr<Window<int>> window;
- std::unique_ptr<GLFWwindow, Cleaner> screen;
- std::vector<RGB> buffer;
- // Tracks position of appending in buffer
- std::vector<RGB>::iterator pos_iter;
- // Texture where pixels are written to
- GLuint mandelbrot_tex;
- // GLSL Shader program
- GLuint shader_prog;
- public:
- Draw_Buffer(Window<int> *, const std::string &, const std::string &);
- ~Draw_Buffer();
- void make_current() {
- glfwMakeContextCurrent(screen.get());
- }
- void flush();
- void keep_window_open();
- };
- Draw_Buffer &operator<<(Draw_Buffer &db, const RGB &pixel);
- #endif //MANDELBROT_FRACTAL_DRAWER_DRAW_BUFFER_H
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement