FreeBASIC  0.91.0
gfx_opengl.c
Go to the documentation of this file.
1 /* OpenGL core support functions */
2 
3 #include "fb_gfx.h"
4 #include "fb_gfx_gl.h"
5 
6 #ifdef DISABLE_OPENGL
7 
8 FBCALL void *fb_GfxGetGLProcAddress(const char *proc)
9 {
10  /* Stub function in case OpenGL support is disabled at compile time */
11  return NULL;
12 }
13 
14 #else /* DISABLE_OPENGL */
15 
16 #define FBGL_TEXTURE 0x1
17 #define FBGL_BLEND 0x2
18 
19 #ifndef GL_BGRA
20 #define GL_BGRA 0x80E1
21 #endif
22 
25 
26 static int next_pow2(int n)
27 {
28  n--;
29  n |= (n >> 1);
30  n |= (n >> 2);
31  n |= (n >> 4);
32  n |= (n >> 8);
33  n |= (n >> 16);
34  n++;
35  return n;
36 }
37 
39 {
40  if ((!__fb_gfx) || (!(__fb_gfx->flags & OPENGL_SUPPORT)))
41  return NULL;
42  return fb_hGL_GetProcAddress(proc);
43 }
44 
45 int fb_hGL_ExtensionSupported(const char *extension)
46 {
47  ssize_t len;
48  char *string = __fb_gl.extensions;
49 
50  len = strlen(extension);
51  while ((string = strstr(string, extension)) != NULL) {
52  string += len;
53  if ((*string == ' ') || (*string == '\0'))
54  return TRUE;
55  }
56 
57  return FALSE;
58 }
59 
61 {
62  int diffs;
63 
64  diffs = state ^ __fb_gl.state;
65  __fb_gl.state = state;
66 
67  if (diffs & FBGL_TEXTURE) {
68  if (state & FBGL_TEXTURE)
69  __fb_gl.Enable(GL_TEXTURE_2D);
70  else
71  __fb_gl.Disable(GL_TEXTURE_2D);
72  }
73  if (diffs & FBGL_BLEND) {
74  }
75 }
76 
77 GLuint fb_hGL_ImageCreate(PUT_HEADER *image, unsigned int color)
78 {
79  int w, h;
80  GLuint id;
81  unsigned char *data;
82 
83  w = next_pow2(image->width);
84  h = next_pow2(image->height);
85  data = (unsigned char *)calloc(1, w * h * 4);
86  fb_hPixelSet(data, color, w * h);
87  __fb_gl.GenTextures(1, &id);
88  __fb_gl.BindTexture(GL_TEXTURE_2D, id);
89  __fb_gl.TexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, w, h, 0, GL_BGRA, GL_UNSIGNED_BYTE, data);
90  free(data);
91 
92  return id;
93 }
94 
95 void fb_hGL_ImageDestroy(GLuint id)
96 {
97  __fb_gl.DeleteTextures(1, &id);
98 }
99 
100 void fb_hGL_NormalizeParameters(int gl_options)
101 {
102  int default_color_bits[4] = { 0, 5, 8, 8 };
103  int default_alpha_bits[4] = { 0, 0, 0, 8 };
104  int bpp;
105 
106  if (!__fb_gl_params.color_bits) {
107  __fb_gl_params.color_bits = __fb_gl_params.color_red_bits +
108  __fb_gl_params.color_green_bits +
109  __fb_gl_params.color_blue_bits +
110  __fb_gl_params.color_alpha_bits;
111  if (!__fb_gl_params.color_bits)
112  __fb_gl_params.color_bits = __fb_gfx->depth;
113  }
114  bpp = BYTES_PER_PIXEL(__fb_gl_params.color_bits) - 1;
115  if (bpp > 3) bpp = 3;
116  if (!__fb_gl_params.color_red_bits)
117  __fb_gl_params.color_red_bits = default_color_bits[bpp];
118  if (!__fb_gl_params.color_green_bits)
119  __fb_gl_params.color_green_bits = default_color_bits[bpp];
120  if (!__fb_gl_params.color_blue_bits)
121  __fb_gl_params.color_blue_bits = default_color_bits[bpp];
122  if (!__fb_gl_params.color_alpha_bits)
123  __fb_gl_params.color_alpha_bits = default_alpha_bits[bpp];
124 
125  if (!__fb_gl_params.accum_bits) {
126  __fb_gl_params.accum_bits = __fb_gl_params.accum_red_bits +
127  __fb_gl_params.accum_green_bits +
128  __fb_gl_params.accum_blue_bits +
129  __fb_gl_params.accum_alpha_bits;
130  }
131  bpp = BYTES_PER_PIXEL(__fb_gl_params.accum_bits) - 1;
132  if (bpp > 3) bpp = 3;
133  if ((bpp < 0) && (gl_options & HAS_ACCUMULATION_BUFFER)) {
134  __fb_gl_params.accum_bits = 32;
135  bpp = 3;
136  }
137  if (bpp >= 0) {
138  if (!__fb_gl_params.accum_red_bits)
139  __fb_gl_params.accum_red_bits = default_color_bits[bpp];
140  if (!__fb_gl_params.accum_green_bits)
141  __fb_gl_params.accum_green_bits = default_color_bits[bpp];
142  if (!__fb_gl_params.accum_blue_bits)
143  __fb_gl_params.accum_blue_bits = default_color_bits[bpp];
144  if (!__fb_gl_params.accum_alpha_bits)
145  __fb_gl_params.accum_alpha_bits = default_alpha_bits[bpp];
146  }
147 
148  if (!__fb_gl_params.depth_bits)
149  __fb_gl_params.depth_bits = 16;
150 
151  if ((!__fb_gl_params.stencil_bits) && (gl_options & HAS_STENCIL_BUFFER))
152  __fb_gl_params.stencil_bits = 8;
153 
154  if ((!__fb_gl_params.num_samples) && (gl_options & HAS_MULTISAMPLE))
155  __fb_gl_params.num_samples = 4;
156 }
157 
158 int fb_hGL_Init(FB_DYLIB lib, char *os_extensions)
159 {
160  const char *gl_funcs[] = { "glEnable", "glDisable", "glGetString", "glViewport", "glMatrixMode",
161  "glLoadIdentity", "glOrtho", "glShadeModel", "glDepthMask", "glClearColor",
162  "glClear", "glGenTextures", "glDeleteTextures", "glBindTexture",
163  "glTexImage2D" };
164  FB_GL *funcs = &__fb_gl;
165  void **funcs_ptr = (void **)funcs;
166  int res = 0, size = FBGL_EXTENSIONS_STRING_SIZE - 1;
167 
168  fb_hMemSet(&__fb_gl, 0, sizeof(FB_GL));
169 
170  if (fb_hDynLoadAlso(lib, gl_funcs, funcs_ptr, sizeof(gl_funcs) / sizeof(const char *)))
171  return -1;
172 
173  strncpy(__fb_gl.extensions, (char *)__fb_gl.GetString(GL_EXTENSIONS), size);
174  size -= strlen(__fb_gl.extensions);
175  if (os_extensions)
176  strncat(__fb_gl.extensions, os_extensions, size);
177  __fb_gl.extensions[FBGL_EXTENSIONS_STRING_SIZE - 1] = '\0';
178 
179  res |= !fb_hGL_ExtensionSupported("GL_EXT_bgra");
180 
181  return res;
182 }
183 
185 {
186  __fb_gl.Viewport(0, 0, __fb_gfx->w, __fb_gfx->h);
187  __fb_gl.MatrixMode(GL_PROJECTION);
188  __fb_gl.LoadIdentity();
189  __fb_gl.Ortho(-0.325, __fb_gfx->w - 0.325, __fb_gfx->h - 0.325, -0.325, -1.0, 1.0);
190  __fb_gl.MatrixMode(GL_MODELVIEW);
191  __fb_gl.LoadIdentity();
192  __fb_gl.ShadeModel(GL_FLAT);
193  __fb_gl.Disable(GL_DEPTH_TEST);
194  __fb_gl.DepthMask(GL_FALSE);
195  __fb_gl.ClearColor(0.0, 0.0, 0.0, 1.0);
196  __fb_gl.Clear(GL_COLOR_BUFFER_BIT);
197 }
198 
199 #endif /* DISABLE_OPENGL */