-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathbuffer.c
More file actions
112 lines (94 loc) · 3.75 KB
/
Copy pathbuffer.c
File metadata and controls
112 lines (94 loc) · 3.75 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
#include "buffer.h"
#include <stdio.h>
#include <stdlib.h>
#include <gl.h>
static void buffer_set_index(Buffer *b, const Bwhich which, const PBindex index);
static void buffer_check_shape(Buffer *b, const int width, const int height);
void buffer_allocate(Buffer *b, const Bwhich which, const PBindex index, const int width, const int height, const char *data) {
buffer_check_shape(b, width, height);
if (which == screen) {
fprintf(stderr, "[%s] cannot allocate the screen buffer", b->name);
exit(EXIT_FAILURE);
}
glActiveTexture(GL_TEXTURE0 + index);
glBindTexture(GL_TEXTURE_2D, b->textures->items[index]);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, b->minmag_filter);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, b->minmag_filter);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, b->wrap_st);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, b->wrap_st);
// Write data to texture
glTexImage2D(GL_TEXTURE_2D, 0, b->dim.iformat, width, height, 0, b->dim.format, GL_FLOAT, data);
// Bind framebuffer
glBindFramebuffer(GL_FRAMEBUFFER, b->framebuffers->items[index]);
// Clear buffer to 0
glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
glClear(GL_COLOR_BUFFER_BIT);
// Attach the framebuffer to the texture
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, b->textures->items[index], 0);
if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) {
fprintf(stderr, "[%s] framebuffer is not complete", b->name);
exit(EXIT_FAILURE);
}
buffer_set_index(b, which, index);
b->width = width;
b->height = height;
}
void buffer_reallocate(Buffer *b, const Bwhich which, const int width, const int height) {
buffer_allocate(b, which, b->current, width, height, NULL);
}
void buffer_flip(Buffer *b) {
PBindex temp = b->current;
b->current = b->other;
b->other = temp;
}
void buffer_bind(Buffer *b, const Bwhich which) {
GLint framebuffer = 0;
switch (which) {
case current: {
framebuffer = b->framebuffers->items[b->current];
} break;
case other: {
framebuffer = b->framebuffers->items[b->other];
} break;
case screen: {
framebuffer = 0;
} break;
}
glBindFramebuffer(GL_FRAMEBUFFER, framebuffer);
glViewport(0, 0, b->width, b->height); // Change the viewport to the size of the 1D texture vector
glClear(GL_COLOR_BUFFER_BIT); // Dont need to clear it as its writing to each pixel anyway
}
void buffer_update(Buffer *b) {
(void)b;
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); // Need to only write 4 points since vertex shader makes them into a quad over the entire screen anyway
}
void buffer_update_n(Buffer *b, const int P) {
(void)b;
glDrawArrays(GL_POINTS, 0, P);
}
static void buffer_set_index(Buffer *b, const Bwhich which, const PBindex index) {
switch (which) {
case current: {
b->current = index;
} break;
case other: {
b->other = index;
} break;
case screen: {
fprintf(stderr, "[%s] can't set object index to screen buffer", b->name);
exit(EXIT_FAILURE);
} break;
}
}
static void buffer_check_shape(Buffer *b, const int width, const int height) {
GLint max_renderbuffer_size;
glGetIntegerv(GL_MAX_RENDERBUFFER_SIZE, &max_renderbuffer_size);
if (width > max_renderbuffer_size) {
fprintf(stderr, "[%s] Physics framebuffer width (%d) larger than renderbuffer size (%d)", b->name, width, max_renderbuffer_size);
exit(EXIT_FAILURE);
}
if (height > max_renderbuffer_size) {
fprintf(stderr, "[%s] Physics framebuffer width (%d) larger than renderbuffer size (%d)", b->name, height, max_renderbuffer_size);
exit(EXIT_FAILURE);
}
}