mightymandel v16

GPU-based Mandelbrot set explorer

fp32_fillc.c
Go to the documentation of this file.
1 // mightymandel -- GPU-based Mandelbrot Set explorer
2 // Copyright (C) 2012,2013,2014,2015 Claude Heiland-Allen
3 // License GPL3+ http://www.gnu.org/licenses/gpl.html
4 
5 #include "fp32_fillc.h"
6 #include "shader.h"
7 #include "logging.h"
8 #include "texture.h"
9 
10 extern const char *fp32_fillc_vert;
11 extern const char *fp32_fillc_frag;
12 
13 void fp32_fillc_begin(struct fp32_fillc *s) {
15  s->aspect = glGetUniformLocation(s->program, "aspect");D;
16  s->slice_offset = glGetUniformLocation(s->program, "slice_offset");D;
17  s->ida0 = glGetUniformLocation(s->program, "ida0");D;
18  s->p = glGetAttribLocation(s->program, "p");D;
19  glGenVertexArrays(1, &s->vao);D;
20  glGenBuffers(1, &s->vbo);D;
21 }
22 
23 void fp32_fillc_end(struct fp32_fillc *s) {
24  glDeleteProgram(s->program);D;
25  glDeleteBuffers(1, &s->vbo);D;
26  glDeleteVertexArrays(1, &s->vao);D;
27  glDeleteBuffers(1, &s->vbo);D;
28 }
29 
30 void fp32_fillc_do(struct fp32_fillc *s, GLuint vbo, GLuint fbo, GLuint tex, GLuint tex2, int width, int height, int pass, int slice, int slicex, int slicey) {
31  debug_message("fp32_fillc_do(%p, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d)\n", s, vbo, fbo, tex, tex2, width, height, pass, slice, slicex, slicey);
32  glBindFramebuffer(GL_FRAMEBUFFER, fbo);D;
33  if (pass == 0 && slicex == 0 && slicey == 0) {
34  glFramebufferTexture(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, tex, 0);D;
35  GLenum buffers[1] = { GL_COLOR_ATTACHMENT0 };
36  glDrawBuffers(1, buffers);D;
37  glViewport(0, 0, width, height);D;
38  glClearColor(-1,0,0,0); // FIXME spec says glClearColor clamps to [0,1]
39  glClear(GL_COLOR_BUFFER_BIT);
40  }
41  glFramebufferTexture(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, tex2, 0);D;
42  GLenum buffers[1] = { GL_COLOR_ATTACHMENT0 };
43  glDrawBuffers(1, buffers);D;
44  glViewport(0, 0, width >> slice, height >> slice);D;
45  glUseProgram(s->program);D;
46  glUniform1i(s->ida0, TEX_RAW);D;
47  double aspect = width / (double) height;
48  glUniform1f(s->aspect, 1.0 / aspect);D;
49  double pixel_delta = 2.0 / (height >> slice);
50  glUniform2f(s->slice_offset, ((slicex + 0.5) / (1 << slice) - 0.5) * pixel_delta, ((slicey + 0.5) / (1 << slice) - 0.5) * pixel_delta);
51  GLfloat quad[] = {
52  -aspect, -1, 0, 0,
53  -aspect, 1, 0, 1,
54  aspect, -1, 1, 0,
55  aspect, 1, 1, 1
56  };
57  glBindVertexArray(s->vao);D;
58  glBindBuffer(GL_ARRAY_BUFFER, s->vbo);D;
59  glBufferData(GL_ARRAY_BUFFER, 16 * sizeof(GLfloat), &quad, GL_STATIC_DRAW);D;
60  glVertexAttribPointer(s->p, 4, GL_FLOAT, GL_FALSE, 0, 0);D;
61  glEnableVertexAttribArray(s->p);D;
62  glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);D;
63  glDisableVertexAttribArray(s->p);D;
64  glBindBuffer(GL_ARRAY_BUFFER, 0);D;
65  glBindVertexArray(0);D;
66  glUseProgram(0);D;
67  // Copy texture to vertex buffer.
68  glBindBuffer(GL_PIXEL_PACK_BUFFER, vbo);D;
69  glReadPixels(0, 0, width >> slice, height >> slice, GL_RGBA, GL_FLOAT, 0);D;
70  glBindBuffer(GL_PIXEL_PACK_BUFFER, 0);D;
71  debug_message("VBO fillc: ? -> %d\n", vbo);
72  glFramebufferTexture(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, tex, 0);D;
73  glDrawBuffers(1, buffers);D;
74  glViewport(0, 0, width, height);D;
75 }