rev |
line source |
nuclear@14
|
1 #include "imago2.h"
|
nuclear@14
|
2
|
nuclear@14
|
3 /* to avoid dependency to OpenGL, I'll define all the relevant GL macros manually */
|
nuclear@14
|
4 #define GL_UNSIGNED_BYTE 0x1401
|
nuclear@14
|
5 #define GL_FLOAT 0x1406
|
nuclear@14
|
6
|
nuclear@14
|
7 #define GL_LUMINANCE 0x1909
|
nuclear@14
|
8 #define GL_RGB 0x1907
|
nuclear@14
|
9 #define GL_RGBA 0x1908
|
nuclear@14
|
10
|
nuclear@14
|
11 #define GL_RGBA32F 0x8814
|
nuclear@14
|
12 #define GL_RGB32F 0x8815
|
nuclear@14
|
13 #define GL_LUMINANCE32F 0x8818
|
nuclear@14
|
14
|
nuclear@14
|
15 #define GL_TEXTURE_2D 0x0de1
|
nuclear@14
|
16 #define GL_TEXTURE_WRAP_S 0x2802
|
nuclear@14
|
17 #define GL_TEXTURE_WRAP_T 0x2803
|
nuclear@14
|
18 #define GL_TEXTURE_MAG_FILTER 0x2800
|
nuclear@14
|
19 #define GL_TEXTURE_MIN_FILTER 0x2801
|
nuclear@14
|
20 #define GL_LINEAR 0x2601
|
nuclear@14
|
21 #define GL_REPEAT 0x2901
|
nuclear@14
|
22
|
nuclear@14
|
23
|
nuclear@14
|
24 typedef unsigned int GLenum;
|
nuclear@14
|
25 typedef unsigned int GLuint;
|
nuclear@14
|
26 typedef int GLint;
|
nuclear@14
|
27 typedef int GLsizei;
|
nuclear@14
|
28 typedef void GLvoid;
|
nuclear@14
|
29
|
nuclear@14
|
30 /* for the same reason I'll load GL functions dynamically */
|
nuclear@14
|
31 #ifndef WIN32
|
nuclear@14
|
32 typedef void (*gl_gen_textures_func)(GLsizei, GLuint*);
|
nuclear@14
|
33 typedef void (*gl_bind_texture_func)(GLenum, GLuint);
|
nuclear@14
|
34 typedef void (*gl_tex_parameteri_func)(GLenum, GLenum, GLint);
|
nuclear@14
|
35 typedef void (*gl_tex_image2d_func)(GLenum, GLint, GLint, GLsizei, GLsizei, GLint, GLenum, GLenum, const GLvoid*);
|
nuclear@14
|
36 #else
|
nuclear@14
|
37 typedef void (__stdcall *gl_gen_textures_func)(GLsizei, GLuint*);
|
nuclear@14
|
38 typedef void (__stdcall *gl_bind_texture_func)(GLenum, GLuint);
|
nuclear@14
|
39 typedef void (__stdcall *gl_tex_parameteri_func)(GLenum, GLenum, GLint);
|
nuclear@14
|
40 typedef void (__stdcall *gl_tex_image2d_func)(GLenum, GLint, GLint, GLsizei, GLsizei, GLint, GLenum, GLenum, const GLvoid*);
|
nuclear@14
|
41 #endif
|
nuclear@14
|
42
|
nuclear@14
|
43 static gl_gen_textures_func gl_gen_textures;
|
nuclear@14
|
44 static gl_bind_texture_func gl_bind_texture;
|
nuclear@14
|
45 static gl_tex_parameteri_func gl_tex_parameteri;
|
nuclear@14
|
46 static gl_tex_image2d_func gl_tex_image2d;
|
nuclear@14
|
47
|
nuclear@14
|
48 static int load_glfunc(void);
|
nuclear@14
|
49
|
nuclear@14
|
50 unsigned int img_fmt_glfmt(enum img_fmt fmt)
|
nuclear@14
|
51 {
|
nuclear@14
|
52 switch(fmt) {
|
nuclear@14
|
53 case IMG_FMT_GREY8:
|
nuclear@14
|
54 case IMG_FMT_GREYF:
|
nuclear@14
|
55 return GL_LUMINANCE;
|
nuclear@14
|
56
|
nuclear@14
|
57 case IMG_FMT_RGB24:
|
nuclear@14
|
58 case IMG_FMT_RGBF:
|
nuclear@14
|
59 return GL_RGB;
|
nuclear@14
|
60
|
nuclear@14
|
61 case IMG_FMT_RGBA32:
|
nuclear@14
|
62 case IMG_FMT_RGBAF:
|
nuclear@14
|
63 return GL_RGBA;
|
nuclear@14
|
64
|
nuclear@14
|
65 default:
|
nuclear@14
|
66 break;
|
nuclear@14
|
67 }
|
nuclear@14
|
68 return 0;
|
nuclear@14
|
69 }
|
nuclear@14
|
70
|
nuclear@14
|
71 unsigned int img_fmt_gltype(enum img_fmt fmt)
|
nuclear@14
|
72 {
|
nuclear@14
|
73 switch(fmt) {
|
nuclear@14
|
74 case IMG_FMT_GREY8:
|
nuclear@14
|
75 case IMG_FMT_RGB24:
|
nuclear@14
|
76 case IMG_FMT_RGBA32:
|
nuclear@14
|
77 return GL_UNSIGNED_BYTE;
|
nuclear@14
|
78
|
nuclear@14
|
79 case IMG_FMT_GREYF:
|
nuclear@14
|
80 case IMG_FMT_RGBF:
|
nuclear@14
|
81 case IMG_FMT_RGBAF:
|
nuclear@14
|
82 return GL_FLOAT;
|
nuclear@14
|
83
|
nuclear@14
|
84 default:
|
nuclear@14
|
85 break;
|
nuclear@14
|
86 }
|
nuclear@14
|
87 return 0;
|
nuclear@14
|
88 }
|
nuclear@14
|
89
|
nuclear@14
|
90 unsigned int img_fmt_glintfmt(enum img_fmt fmt)
|
nuclear@14
|
91 {
|
nuclear@14
|
92 switch(fmt) {
|
nuclear@14
|
93 case IMG_FMT_GREY8:
|
nuclear@14
|
94 return GL_LUMINANCE;
|
nuclear@14
|
95 case IMG_FMT_RGB24:
|
nuclear@14
|
96 return GL_RGB;
|
nuclear@14
|
97 case IMG_FMT_RGBA32:
|
nuclear@14
|
98 return GL_RGBA;
|
nuclear@14
|
99 case IMG_FMT_GREYF:
|
nuclear@14
|
100 return GL_LUMINANCE32F;
|
nuclear@14
|
101 case IMG_FMT_RGBF:
|
nuclear@14
|
102 return GL_RGB32F;
|
nuclear@14
|
103 case IMG_FMT_RGBAF:
|
nuclear@14
|
104 return GL_RGBA32F;
|
nuclear@14
|
105 default:
|
nuclear@14
|
106 break;
|
nuclear@14
|
107 }
|
nuclear@14
|
108 return 0;
|
nuclear@14
|
109 }
|
nuclear@14
|
110
|
nuclear@14
|
111 unsigned int img_glfmt(struct img_pixmap *img)
|
nuclear@14
|
112 {
|
nuclear@14
|
113 return img_fmt_glfmt(img->fmt);
|
nuclear@14
|
114 }
|
nuclear@14
|
115
|
nuclear@14
|
116 unsigned int img_gltype(struct img_pixmap *img)
|
nuclear@14
|
117 {
|
nuclear@14
|
118 return img_fmt_gltype(img->fmt);
|
nuclear@14
|
119 }
|
nuclear@14
|
120
|
nuclear@14
|
121 unsigned int img_glintfmt(struct img_pixmap *img)
|
nuclear@14
|
122 {
|
nuclear@14
|
123 return img_fmt_glintfmt(img->fmt);
|
nuclear@14
|
124 }
|
nuclear@14
|
125
|
nuclear@14
|
126 unsigned int img_gltexture(struct img_pixmap *img)
|
nuclear@14
|
127 {
|
nuclear@14
|
128 unsigned int tex;
|
nuclear@14
|
129 unsigned int intfmt, fmt, type;
|
nuclear@14
|
130
|
nuclear@14
|
131 if(!gl_gen_textures) {
|
nuclear@14
|
132 if(load_glfunc() == -1) {
|
nuclear@14
|
133 fprintf(stderr, "imago: failed to initialize the OpenGL helpers\n");
|
nuclear@14
|
134 return 0;
|
nuclear@14
|
135 }
|
nuclear@14
|
136 }
|
nuclear@14
|
137
|
nuclear@14
|
138 intfmt = img_glintfmt(img);
|
nuclear@14
|
139 fmt = img_glfmt(img);
|
nuclear@14
|
140 type = img_gltype(img);
|
nuclear@14
|
141
|
nuclear@14
|
142 gl_gen_textures(1, &tex);
|
nuclear@14
|
143 gl_bind_texture(GL_TEXTURE_2D, tex);
|
nuclear@14
|
144 gl_tex_parameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
nuclear@14
|
145 gl_tex_parameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
nuclear@14
|
146 gl_tex_parameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
|
nuclear@14
|
147 gl_tex_parameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
|
nuclear@14
|
148 gl_tex_image2d(GL_TEXTURE_2D, 0, intfmt, img->width, img->height, 0, fmt, type, img->pixels);
|
nuclear@14
|
149 return tex;
|
nuclear@14
|
150 }
|
nuclear@14
|
151
|
nuclear@14
|
152 unsigned int img_gltexture_load(const char *fname)
|
nuclear@14
|
153 {
|
nuclear@14
|
154 struct img_pixmap img;
|
nuclear@14
|
155 unsigned int tex;
|
nuclear@14
|
156
|
nuclear@14
|
157 img_init(&img);
|
nuclear@14
|
158 if(img_load(&img, fname) == -1) {
|
nuclear@14
|
159 img_destroy(&img);
|
nuclear@14
|
160 return 0;
|
nuclear@14
|
161 }
|
nuclear@14
|
162
|
nuclear@14
|
163 tex = img_gltexture(&img);
|
nuclear@14
|
164 img_destroy(&img);
|
nuclear@14
|
165 return tex;
|
nuclear@14
|
166 }
|
nuclear@14
|
167
|
nuclear@14
|
168 unsigned int img_gltexture_read_file(FILE *fp)
|
nuclear@14
|
169 {
|
nuclear@14
|
170 struct img_pixmap img;
|
nuclear@14
|
171 unsigned int tex;
|
nuclear@14
|
172
|
nuclear@14
|
173 img_init(&img);
|
nuclear@14
|
174 if(img_read_file(&img, fp) == -1) {
|
nuclear@14
|
175 img_destroy(&img);
|
nuclear@14
|
176 return 0;
|
nuclear@14
|
177 }
|
nuclear@14
|
178
|
nuclear@14
|
179 tex = img_gltexture(&img);
|
nuclear@14
|
180 img_destroy(&img);
|
nuclear@14
|
181 return tex;
|
nuclear@14
|
182 }
|
nuclear@14
|
183
|
nuclear@14
|
184 unsigned int img_gltexture_read(struct img_io *io)
|
nuclear@14
|
185 {
|
nuclear@14
|
186 struct img_pixmap img;
|
nuclear@14
|
187 unsigned int tex;
|
nuclear@14
|
188
|
nuclear@14
|
189 img_init(&img);
|
nuclear@14
|
190 if(img_read(&img, io) == -1) {
|
nuclear@14
|
191 img_destroy(&img);
|
nuclear@14
|
192 return 0;
|
nuclear@14
|
193 }
|
nuclear@14
|
194
|
nuclear@14
|
195 tex = img_gltexture(&img);
|
nuclear@14
|
196 img_destroy(&img);
|
nuclear@14
|
197 return tex;
|
nuclear@14
|
198 }
|
nuclear@14
|
199
|
nuclear@14
|
200 #if defined(__unix__) || defined(__APPLE__)
|
nuclear@14
|
201 #ifndef __USE_GNU
|
nuclear@14
|
202 #define __USE_GNU
|
nuclear@14
|
203 #endif
|
nuclear@14
|
204
|
nuclear@14
|
205 #include <dlfcn.h>
|
nuclear@14
|
206 #endif
|
nuclear@14
|
207 #ifdef WIN32
|
nuclear@14
|
208 #include <windows.h>
|
nuclear@14
|
209 #endif
|
nuclear@14
|
210
|
nuclear@14
|
211 static int load_glfunc(void)
|
nuclear@14
|
212 {
|
nuclear@14
|
213 #if defined(__unix__) || defined(__APPLE__)
|
nuclear@14
|
214 gl_gen_textures = (gl_gen_textures_func)dlsym(RTLD_DEFAULT, "glGenTextures");
|
nuclear@14
|
215 gl_bind_texture = (gl_bind_texture_func)dlsym(RTLD_DEFAULT, "glBindTexture");
|
nuclear@14
|
216 gl_tex_parameteri = (gl_tex_parameteri_func)dlsym(RTLD_DEFAULT, "glTexParameteri");
|
nuclear@14
|
217 gl_tex_image2d = (gl_tex_image2d_func)dlsym(RTLD_DEFAULT, "glTexImage2D");
|
nuclear@14
|
218 #endif
|
nuclear@14
|
219
|
nuclear@14
|
220 #ifdef WIN32
|
nuclear@14
|
221 HANDLE dll = LoadLibrary("opengl32.dll");
|
nuclear@14
|
222 if(dll) {
|
nuclear@14
|
223 gl_gen_textures = (gl_gen_textures_func)GetProcAddress(dll, "glGenTextures");
|
nuclear@14
|
224 gl_bind_texture = (gl_bind_texture_func)GetProcAddress(dll, "glBindTexture");
|
nuclear@14
|
225 gl_tex_parameteri = (gl_tex_parameteri_func)GetProcAddress(dll, "glTexParameteri");
|
nuclear@14
|
226 gl_tex_image2d = (gl_tex_image2d_func)GetProcAddress(dll, "glTexImage2D");
|
nuclear@14
|
227 }
|
nuclear@14
|
228 #endif
|
nuclear@14
|
229
|
nuclear@14
|
230 return (gl_gen_textures && gl_bind_texture && gl_tex_parameteri && gl_tex_image2d) ? 0 : -1;
|
nuclear@14
|
231 }
|