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
|
#include "../../include/mgl/graphics/texture.h"
#include "../../include/mgl/graphics/image.h"
#include "../../include/mgl/mgl.h"
#include <stdio.h>
/* TODO: Check for glTexImage2D failure */
static int mgl_texture_format_to_opengl_format(mgl_texture_format format) {
switch(format) {
case MGL_TEXTURE_FORMAT_ALPHA: return GL_ALPHA8;
case MGL_TEXTURE_FORMAT_GRAY: return GL_LUMINANCE8;
case MGL_TEXTURE_FORMAT_GRAY_ALPHA: return GL_LUMINANCE8_ALPHA8;
case MGL_TEXTURE_FORMAT_RGB: return GL_RGB8;
case MGL_TEXTURE_FORMAT_RGBA: return GL_RGBA8;
}
return 0;
}
static int mgl_texture_format_to_compressed_opengl_format(mgl_texture_format format) {
switch(format) {
case MGL_TEXTURE_FORMAT_ALPHA: return GL_ALPHA8;
case MGL_TEXTURE_FORMAT_GRAY: return GL_LUMINANCE8;
case MGL_TEXTURE_FORMAT_GRAY_ALPHA: return GL_LUMINANCE8_ALPHA8;
case MGL_TEXTURE_FORMAT_RGB: return GL_COMPRESSED_RGB_S3TC_DXT1_EXT;
case MGL_TEXTURE_FORMAT_RGBA: return GL_COMPRESSED_RGBA_S3TC_DXT5_EXT;
}
return 0;
}
static int mgl_texture_format_to_source_opengl_format(mgl_texture_format format) {
switch(format) {
case MGL_TEXTURE_FORMAT_ALPHA: return GL_ALPHA;
case MGL_TEXTURE_FORMAT_GRAY: return GL_LUMINANCE8;
case MGL_TEXTURE_FORMAT_GRAY_ALPHA: return GL_LUMINANCE8_ALPHA8;
case MGL_TEXTURE_FORMAT_RGB: return GL_RGB;
case MGL_TEXTURE_FORMAT_RGBA: return GL_RGBA;
}
return 0;
}
static mgl_texture_format mgl_image_format_to_mgl_texture_format(mgl_image_format image_format) {
switch(image_format) {
case MGL_IMAGE_FORMAT_ALPHA: return MGL_TEXTURE_FORMAT_ALPHA;
case MGL_IMAGE_FORMAT_GRAY: return MGL_TEXTURE_FORMAT_GRAY;
case MGL_IMAGE_FORMAT_GRAY_ALPHA: return MGL_TEXTURE_FORMAT_GRAY_ALPHA;
case MGL_IMAGE_FORMAT_RGB: return MGL_TEXTURE_FORMAT_RGB;
case MGL_IMAGE_FORMAT_RGBA: return MGL_TEXTURE_FORMAT_RGBA;
}
return 0;
}
int mgl_texture_load_from_file(mgl_texture *self, const char *filepath, mgl_texture_load_options *load_options) {
self->id = 0;
self->width = 0;
self->height = 0;
mgl_image image;
if(mgl_image_load_from_file(&image, filepath) != 0)
return -1;
int result = mgl_texture_load_from_image(self, &image, load_options);
mgl_image_unload(&image);
return result;
}
int mgl_texture_load_from_image(mgl_texture *self, const mgl_image *image, mgl_texture_load_options *load_options) {
return mgl_texture_load_from_memory(self, image->data, image->width, image->height, image->format, load_options);
}
int mgl_texture_load_from_memory(mgl_texture *self, const unsigned char *data, int width, int height, mgl_image_format format, mgl_texture_load_options *load_options) {
self->id = 0;
self->width = width;
self->height = height;
self->format = mgl_image_format_to_mgl_texture_format(format);
mgl_context *context = mgl_get_context();
context->gl.glGenTextures(1, &self->id);
if(self->id == 0) {
fprintf(stderr, "Error: failed to load image from memory (glGenTextures failed)\n");
mgl_texture_unload(self);
return -1;
}
const int opengl_texture_format = load_options && load_options->compressed ? mgl_texture_format_to_compressed_opengl_format(self->format) : mgl_texture_format_to_opengl_format(self->format);
context->gl.glBindTexture(GL_TEXTURE_2D, self->id);
context->gl.glTexImage2D(GL_TEXTURE_2D, 0, opengl_texture_format, self->width, self->height, 0, mgl_texture_format_to_source_opengl_format(self->format), GL_UNSIGNED_BYTE, data);
context->gl.glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
context->gl.glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
context->gl.glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
context->gl.glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
context->gl.glBindTexture(GL_TEXTURE_2D, 0);
return 0;
}
void mgl_texture_unload(mgl_texture *self) {
mgl_context *context = mgl_get_context();
if(self->id) {
context->gl.glDeleteTextures(1, &self->id);
self->id = 0;
}
self->width = 0;
self->height = 0;
self->format = 0;
}
|