-
Notifications
You must be signed in to change notification settings - Fork 15
/
Copy pathbackground.c
120 lines (94 loc) · 2.89 KB
/
background.c
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
113
114
115
116
117
118
119
120
#include <gdk/gdk.h>
#include <GL/gl.h>
#include "program.h"
static GLuint texture;
static GLuint vao, vbo;
// Each vertex has space and texture coordinates:
struct vertex {
float x;
float y;
float u;
float v;
} __attribute__((packed));
void
background_set_window (int width, int height)
{
float wd = (float)width / 16;
float ht = (float)height / 16;
// The background quad is made of four vertices:
//
// 3--2
// | |
// 0--1
//
struct vertex vertex[4] = {
{ -1, -1, 0, 0 }, // Bottom left
{ 1, -1, wd, 0 }, // Bottom right
{ 1, 1, wd, ht }, // Top right
{ -1, 1, 0, ht }, // Top left
};
GLint loc_vertex = program_bkgd_loc(LOC_BKGD_VERTEX);
GLint loc_texture = program_bkgd_loc(LOC_BKGD_TEXTURE);
glBindVertexArray(vao);
glEnableVertexAttribArray(loc_vertex);
glEnableVertexAttribArray(loc_texture);
glBindBuffer(GL_ARRAY_BUFFER, vbo);
glBufferData(GL_ARRAY_BUFFER, sizeof(vertex), vertex, GL_STATIC_DRAW);
glVertexAttribPointer(loc_vertex, 2, GL_FLOAT, GL_FALSE,
sizeof(struct vertex),
(void *) offsetof(struct vertex, x));
glVertexAttribPointer(loc_texture, 2, GL_FLOAT, GL_FALSE,
sizeof(struct vertex),
(void *) offsetof(struct vertex, u));
glBindVertexArray(0);
}
void
background_draw (void)
{
// Array of indices. We define two counterclockwise triangles:
// 0-2-3 and 2-0-1
static GLubyte index[6] = {
0, 2, 3,
2, 0, 1,
};
program_bkgd_use();
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, texture);
glBindVertexArray(vao);
glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_BYTE, index);
glBindVertexArray(0);
}
void
background_init (void)
{
// Inline data declaration:
extern char _binary_textures_background_png_start[];
extern char _binary_textures_background_png_end[];
char *start = _binary_textures_background_png_start;
size_t len = _binary_textures_background_png_end
- _binary_textures_background_png_start;
GInputStream *stream;
GdkPixbuf *pixbuf;
// Create an input stream from inline data:
stream = g_memory_input_stream_new_from_data(start, len, NULL);
// Generate a pixbuf from the input stream:
pixbuf = gdk_pixbuf_new_from_stream(stream, NULL, NULL);
// Destroy the stream:
g_object_unref(stream);
// Generate an OpenGL texture from pixbuf;
// hack a bit by not accounting for pixbuf rowstride:
glGenTextures(1, &texture);
glBindTexture(GL_TEXTURE_2D, texture);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB,
gdk_pixbuf_get_width(pixbuf),
gdk_pixbuf_get_height(pixbuf), 0, GL_RGB, GL_UNSIGNED_BYTE,
gdk_pixbuf_get_pixels(pixbuf));
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_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
// Generate empty buffer:
glGenBuffers(1, &vbo);
// Generate empty vertex array object:
glGenVertexArrays(1, &vao);
}