Ticket #7970: fb2opengl11.h

File fb2opengl11.h, 9.5 KB (added by SF/luke_br, 18 years ago)

FIXED! Sorry, my fault.

Line 
1/* FrameBuffer renderer in an OpenGL texture
2 Andre Souza <asouza@olinux.com.br> */
3
4#include <GL/gl.h>
5#include <SDL/SDL.h>
6#include <stdlib.h>
7#include <string.h>
8
9/* FLAGS */
10#define FB2GL_FS 1 /* FULLSCREEN */
11#define FB2GL_RGBA 2 /* Use RGBA (else use palette) */
12#define FB2GL_320 4 /* 320x256 texture (else use 256x256) */
13#define FB2GL_AUDIO 8 /* Activate SDL Audio */
14#define FB2GL_PITCH 16 /* On fb2l_update, use pitch (else bytes per pixel) */
15#define FB2GL_EXPAND 32 /* Create a RGB fb with the color lookup table*/
16
17/* Framebuffer for 8 bpp */
18unsigned char ogl_fb[256][256];
19unsigned char ogl_fbb[256][64];
20/* Framebuffer for RGBA */
21unsigned char ogl_fb1[256][256][4];
22unsigned char ogl_fb2[256][64][4];
23/* Texture(s) */
24GLuint texture;
25GLuint textureb;
26/* Display list */
27GLuint dlist;
28/* Color Table (256 colors, RGB) */
29char ogl_ctable[256][3];
30char ogl_temp_ctable[256][3]; /* Support for OpenGL 1.1 */
31/* Use RGBA? */
32char fb2gl_RGBA=0;
33/* If so, expand the 8 bit fb to RGB? */
34char fb2gl_expand=0;
35/* 320x256? */
36char fb2gl_t320=0;
37/* Use pitch? Else, bytes per pixel */
38char use_pitch=0;
39/* Methods */
40void fb2gl_maketex();
41void fb2gl_makedlist(int xf, int yf);
42void fb2gl_display();
43
44/* Public */
45SDL_Surface *screen;
46void fb2gl_init(int width, int height, int xfix, int yfix, char flags);
47void fb2gl_update(void *fb, int width, int height, int pitch, int xskip, int yskip);
48void fb2gl_palette(int index, int r, int g, int b);
49void fb2gl_set_palette(int first, int ncolors);
50
51
52void fb2gl_maketex()
53{
54 glGenTextures(0,&texture);
55 glBindTexture(GL_TEXTURE_2D,texture);
56
57 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
58 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
59
60 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
61 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
62/*
63 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
64 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
65*/
66 if (fb2gl_RGBA) {
67 glTexImage2D(GL_TEXTURE_2D,0,GL_RGBA,256,256,0,GL_RGBA, GL_UNSIGNED_BYTE, ogl_fb1);
68 }
69 else {
70 glTexImage2D(GL_TEXTURE_2D,0,GL_COLOR_INDEX,256,256,0,GL_COLOR_INDEX, GL_UNSIGNED_BYTE, ogl_fb);
71 }
72
73 if (fb2gl_t320) {
74 glGenTextures(1,&textureb);
75 glBindTexture(GL_TEXTURE_2D,textureb);
76
77 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
78 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
79
80 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
81 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
82/*
83 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
84 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
85*/
86 if (fb2gl_RGBA) {
87 glTexImage2D(GL_TEXTURE_2D,0,GL_RGBA,64,256,0,GL_RGBA,
88 GL_UNSIGNED_BYTE, ogl_fb2);
89 }
90 else {
91 glTexImage2D(GL_TEXTURE_2D,0,GL_COLOR_INDEX,64,256,0,GL_COLOR_INDEX,
92 GL_UNSIGNED_BYTE, ogl_fbb);
93 }
94 }
95
96}
97
98void fb2gl_makedlist(int xf, int yf)
99{
100 double xfix=(double)xf/128; /* 128 = 256/2 (half texture => 0.0 to 1.0) */
101 double yfix=(double)yf/128;
102 double texend = (double)615/1024; /* End of 256x256 (from -1.0 to 1.0) */
103
104 dlist=glGenLists(1);
105 glNewList(dlist,GL_COMPILE);
106
107 glEnable(GL_TEXTURE_2D);
108
109 glBindTexture(GL_TEXTURE_2D, texture);
110
111 if (!fb2gl_t320) { /* Normal 256x256 */
112 glBegin(GL_QUADS);
113 glTexCoord2f(0.0,1.0); glVertex2f(-1.0,-1.0-yfix); /* upper left */
114 glTexCoord2f(0.0,0.0); glVertex2f(-1.0,1.0); /* lower left */
115 glTexCoord2f(1.0,0.0); glVertex2f(1.0+xfix,1.0); /* lower right */
116 glTexCoord2f(1.0,1.0); glVertex2f(1.0+xfix,-1.0-yfix); /* upper right */
117 glEnd();
118 }
119 else { /* 320x256 */
120
121 /* First, the 256x256 texture */
122 glBegin(GL_QUADS);
123 glTexCoord2f(0.0,1.0); glVertex2f(-1.0,-1.0-yfix); /* upper left */
124 glTexCoord2f(0.0,0.0); glVertex2f(-1.0,1.0); /* lower left */
125 glTexCoord2f(1.0,0.0); glVertex2f(texend+xfix,1.0); /* lower right */
126 glTexCoord2f(1.0,1.0); glVertex2f(texend+xfix,-1.0-yfix); /* upper right*/
127 glEnd();
128
129 /* 64x256 */
130 glBindTexture(GL_TEXTURE_2D, textureb);
131
132 glBegin(GL_QUADS);
133 glTexCoord2f(0.0,1.0); glVertex2f(texend+xfix,-1.0-yfix); /* upper left */
134 glTexCoord2f(0.0,0.0); glVertex2f(texend+xfix,1.0); /* lower left */
135 glTexCoord2f(1.0,0.0); glVertex2f(1.0+xfix,1.0); /* lower right */
136 glTexCoord2f(1.0,1.0); glVertex2f(1.0+xfix,-1.0-yfix); /* upper right */
137 glEnd();
138 }
139
140 glDisable(GL_TEXTURE_2D);
141
142 glEndList();
143}
144
145void fb2gl_init(int width, int height, int xfix, int yfix, char flags)
146{
147 char fs=0;
148 char audio=0;
149 char gl_ext[4096];
150
151 /* Test the flags */
152 if (flags & FB2GL_FS) fs=1; else fs=0;
153 if (flags & FB2GL_RGBA) fb2gl_RGBA=1; else fb2gl_RGBA=0;
154 if (flags & FB2GL_320) fb2gl_t320=1; else fb2gl_t320=0;
155 if (flags & FB2GL_AUDIO) audio=1; else audio=0;
156 if (flags & FB2GL_PITCH) use_pitch=1; else use_pitch=0;
157 if (flags & FB2GL_EXPAND) fb2gl_expand=1; else fb2gl_expand=0;
158/*
159 if (audio) SDL_Init(SDL_INIT_VIDEO | SDL_INIT_AUDIO);
160 else SDL_Init(SDL_INIT_VIDEO);
161
162 atexit(SDL_Quit);
163*/
164
165
166 if (fs) {
167 screen = SDL_SetVideoMode(width, height, 0, SDL_HWSURFACE | SDL_OPENGL | SDL_GL_DOUBLEBUFFER | SDL_FULLSCREEN);
168 }
169 else {
170 screen = SDL_SetVideoMode(width, height, 0, SDL_HWPALETTE | SDL_HWSURFACE | SDL_OPENGL | SDL_GL_DOUBLEBUFFER);
171 }
172
173 if (!screen) {
174 fprintf(stderr, "Couldn't start video res %dx%d\n", width, height);
175 }
176
177#ifndef OGL_1_1
178 if (!fb2gl_RGBA) {
179 /* Paletted Texture Extension */
180 strcpy(gl_ext, (char *)glGetString(GL_EXTENSIONS));
181
182 if ( strstr( gl_ext , "GL_EXT_paletted_texture") )
183 glEnable(GL_EXT_paletted_texture);
184 else {
185 fprintf(stderr,"Your OpenGL version doesn't support paletted texture\n");
186 exit(0);
187 }
188 }
189#endif
190
191 fb2gl_maketex();
192 fb2gl_makedlist(xfix, yfix);
193
194}
195
196void fb2gl_display()
197{
198 glCallList(dlist);
199 SDL_GL_SwapBuffers();
200}
201
202/* Changed the way xskip and yskip work for use with scummvm (shaking) */
203void fb2gl_update(void *fb, int w, int h, int pitch, int xskip, int yskip) {
204 unsigned char *fb1=(unsigned char *)fb;
205 int x,y,scr_pitch,byte=0;
206
207 if (use_pitch) scr_pitch=pitch;
208 else {
209 scr_pitch=w*pitch;
210 byte = pitch; /* Bytes perl pixel (for RGBA mode) */
211 }
212
213 if (fb2gl_RGBA) {
214
215 if (fb2gl_expand) { /* Expand the 8 bit fb into a RGB fb */
216
217 for (y=yskip; y<h; y++) {
218 for (x=xskip; x<w; x++) {
219 if (x<256) {
220 ogl_fb1[y][x][0] = ogl_ctable[*(fb1+x)][0];
221 ogl_fb1[y][x][1] = ogl_ctable[*(fb1+x)][1];
222 ogl_fb1[y][x][2] = ogl_ctable[*(fb1+x)][2];
223 /* ogl_fb1[y-yskip][x-xskip][3]=255; */
224 }
225 else {
226 ogl_fb2[y][x-256][0] = ogl_ctable[*(fb1+x)][0];
227 ogl_fb2[y][x-256][1] = ogl_ctable[*(fb1+x)][1];
228 ogl_fb2[y][x-256][2] = ogl_ctable[*(fb1+x)][2];
229 /* ogl_fb2[y-yskip][x-256][3]=255; */
230 }
231 }
232 fb1 += scr_pitch;
233 }
234 }
235 else { /* No expansion */
236 for (y=yskip; y<h; y++) {
237 for (x=xskip; x<w; x++) {
238 if (x<256) {
239 ogl_fb1[y-yskip][x-xskip][0] = *(fb1+(x*byte));
240 ogl_fb1[y-yskip][x-xskip][1] = *(fb1+(x*byte)+1);
241 ogl_fb1[y-yskip][x-xskip][2] = *(fb1+(x*byte)+2);
242 /* ogl_fb1[y-yskip][x-xskip][3]=255; */
243 }
244 else {
245 ogl_fb2[y-yskip][x-256][0] = *(fb1+(x*byte));
246 ogl_fb2[y-yskip][x-256][1] = *(fb1+(x*byte)+1);
247 ogl_fb2[y-yskip][x-256][2] = *(fb1+(x*byte)+2);
248 /* ogl_fb2[y-yskip][x-256][3]=255; */
249 }
250 }
251 fb1 += scr_pitch;
252 }
253 }
254
255 /* Update 256x256 texture */
256 glBindTexture(GL_TEXTURE_2D,texture);
257 glFlush();
258 glTexSubImage2D(GL_TEXTURE_2D,0,xskip,yskip,256-xskip,256-yskip,GL_RGBA,
259 GL_UNSIGNED_BYTE,ogl_fb1);
260
261 if (fb2gl_t320) {
262 /* Update 64x256 texture */
263 glBindTexture(GL_TEXTURE_2D,textureb);
264 glFlush();
265 glTexSubImage2D(GL_TEXTURE_2D,0,xskip,yskip,64-xskip,256-yskip,GL_RGBA,
266 GL_UNSIGNED_BYTE,ogl_fb2);
267 }
268
269 }
270 else { /* non RGBA */
271
272 for (y=0; y<h; y++)
273 for (x=0; x<w; x++) {
274 if (x<256) {
275 ogl_fb[ y ][ x ] = *(fb1 + (y)*scr_pitch + x);
276 }
277 else {
278 ogl_fbb[ y ][ x - 256 ] = *(fb1 + y*scr_pitch + x);
279 }
280 }
281
282 /* Update 256x256 texture */
283 glBindTexture(GL_TEXTURE_2D,texture);
284 glTexSubImage2D(GL_TEXTURE_2D,0,xskip,yskip,256-xskip,256-yskip,
285 GL_COLOR_INDEX, GL_UNSIGNED_BYTE,ogl_fb);
286
287 if (fb2gl_t320) {
288 /* Update 64x256 texture */
289 glBindTexture(GL_TEXTURE_2D,textureb);
290 glTexSubImage2D(GL_TEXTURE_2D,0,xskip,yskip,64-xskip,256-yskip,
291 GL_COLOR_INDEX, GL_UNSIGNED_BYTE,ogl_fbb);
292 }
293
294 }
295
296 fb2gl_display();
297
298}
299
300void fb2gl_palette(int i, int r, int g, int b) {
301#ifdef OGL_1_1
302 ogl_temp_ctable[i][0]=r;
303 ogl_temp_ctable[i][1]=g;
304 ogl_temp_ctable[i][2]=b;
305#else
306 ogl_ctable[i][0]=r;
307 ogl_ctable[i][1]=g;
308 ogl_ctable[i][2]=b;
309#endif
310}
311
312void fb2gl_set_palette(int f, int n) {
313 char temp[256][3];
314 int i;
315
316#ifdef OGL_1_1
317 /* No ColorTable Extension. Expand option MUST be set. */
318 for (i=f; i<n; i++) {
319 ogl_ctable[i][0] = ogl_temp_ctable[i][0];
320 ogl_ctable[i][1] = ogl_temp_ctable[i][1];
321 ogl_ctable[i][2] = ogl_temp_ctable[i][2];
322 }
323#else
324 if (!fb2gl_expand)
325 {
326
327 glBindTexture(GL_TEXTURE_2D,texture);
328 glGetColorTable(GL_TEXTURE_2D,GL_RGB,GL_UNSIGNED_BYTE,&temp);
329
330 for (i=f; i<n; i++) {
331 temp[i][0] = ogl_ctable[i][0];
332 temp[i][1] = ogl_ctable[i][1];
333 temp[i][2] = ogl_ctable[i][2];
334 }
335
336 glColorTable(GL_TEXTURE_2D,GL_RGB,256,GL_RGB,GL_UNSIGNED_BYTE,&temp);
337
338 if (fb2gl_t320) {
339 glBindTexture(GL_TEXTURE_2D,textureb);
340 glColorTable(GL_TEXTURE_2D,GL_RGB,256,GL_RGB,GL_UNSIGNED_BYTE,&temp);
341 }
342
343 }
344#endif
345}