1 //********************************************************************************************
2 //*
3 //*    This file is part of the opengl extensions library. This library is
4 //*    distributed with Egoboo.
5 //*
6 //*    Egoboo is free software: you can redistribute it and/or modify it
7 //*    under the terms of the GNU General Public License as published by
8 //*    the Free Software Foundation, either version 3 of the License, or
9 //*    (at your option) any later version.
10 //*
11 //*    Egoboo is distributed in the hope that it will be useful, but
12 //*    WITHOUT ANY WARRANTY; without even the implied warranty of
13 //*    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14 //*    General Public License for more details.
15 //*
16 //*    You should have received a copy of the GNU General Public License
17 //*    along with Egoboo.  If not, see <http://www.gnu.org/licenses/>.
18 //*
19 //********************************************************************************************
20 
21 /// @file extensions/ogl_extensions.c
22 /// @ingroup _ogl_extensions_
23 /// @brief Implementation of extended functions and variables for OpenGL
24 /// @details
25 
26 #include "ogl_extensions.h"
27 #include "ogl_debug.h"
28 
29 #include <math.h>
30 #include <string.h>
31 
32 //--------------------------------------------------------------------------------------------
33 //--------------------------------------------------------------------------------------------
34 #define LOCAL_STDOUT ((NULL == _oglx_stdout) ? stdout : _oglx_stdout)
35 
36 //--------------------------------------------------------------------------------------------
37 //--------------------------------------------------------------------------------------------
38 oglx_caps_t ogl_caps;
39 
40 static FILE * _oglx_stdout = NULL;
41 
42 //--------------------------------------------------------------------------------------------
43 //--------------------------------------------------------------------------------------------
oglx_report_caps()44 void oglx_report_caps()
45 {
46     oglx_Get_Screen_Info( &ogl_caps );
47 
48     fprintf( LOCAL_STDOUT, "\nOpenGL state parameters\n" );
49     fprintf( LOCAL_STDOUT, "\tgl_version    == %s\n", ogl_caps.gl_version );
50     fprintf( LOCAL_STDOUT, "\tgl_vendor     == %s\n", ogl_caps.gl_vendor );
51     fprintf( LOCAL_STDOUT, "\tgl_renderer   == %s\n", ogl_caps.gl_renderer );
52     fprintf( LOCAL_STDOUT, "\tgl_extensions == %s\n", ogl_caps.gl_extensions );
53 
54     fprintf( LOCAL_STDOUT, "\tglu_version    == %s\n", ogl_caps.glu_version );
55     fprintf( LOCAL_STDOUT, "\tglu_extensions == %s\n\n", ogl_caps.glu_extensions );
56 
57     fprintf( LOCAL_STDOUT, "\tGL_MAX_MODELVIEW_STACK_DEPTH     == %d\n", ogl_caps.max_modelview_stack_depth );
58     fprintf( LOCAL_STDOUT, "\tGL_MAX_PROJECTION_STACK_DEPTH    == %d\n", ogl_caps.max_projection_stack_depth );
59     fprintf( LOCAL_STDOUT, "\tGL_MAX_TEXTURE_STACK_DEPTH       == %d\n", ogl_caps.max_texture_stack_depth );
60     fprintf( LOCAL_STDOUT, "\tGL_MAX_NAME_STACK_DEPTH          == %d\n", ogl_caps.max_name_stack_depth );
61     fprintf( LOCAL_STDOUT, "\tGL_MAX_ATTRIB_STACK_DEPTH        == %d\n", ogl_caps.max_attrib_stack_depth );
62     fprintf( LOCAL_STDOUT, "\tGL_MAX_CLIENT_ATTRIB_STACK_DEPTH == %d\n\n", ogl_caps.max_client_attrib_stack_depth );
63 
64     fprintf( LOCAL_STDOUT, "\tGL_SUBPIXEL_BITS          == %d\n",      ogl_caps.subpixel_bits );
65     fprintf( LOCAL_STDOUT, "\tGL_POINT_SIZE_RANGE       == %f - %f\n", ogl_caps.point_size_range[0], ogl_caps.point_size_range[1] );
66     fprintf( LOCAL_STDOUT, "\tGL_POINT_SIZE_GRANULARITY == %f\n",      ogl_caps.point_size_granularity );
67     fprintf( LOCAL_STDOUT, "\tGL_LINE_WIDTH_RANGE       == %f - %f\n", ogl_caps.line_width_range[0], ogl_caps.line_width_range[1] );
68     fprintf( LOCAL_STDOUT, "\tGL_LINE_WIDTH_GRANULARITY == %f\n\n",    ogl_caps.line_width_granularity );
69 
70     fprintf( LOCAL_STDOUT, "\tGL_MAX_VIEWPORT_DIMS == %d, %d\n", ogl_caps.max_viewport_dims[0], ogl_caps.max_viewport_dims[1] );
71     fprintf( LOCAL_STDOUT, "\tGL_AUX_BUFFERS       == %d\n", ogl_caps.aux_buffers );
72     fprintf( LOCAL_STDOUT, "\tGL_RGBA_MODE         == %s\n", ogl_caps.rgba_mode ? "TRUE" : "FALSE" );
73     fprintf( LOCAL_STDOUT, "\tGL_INDEX_MODE        == %s\n", ogl_caps.index_mode ? "TRUE" : "FALSE" );
74     fprintf( LOCAL_STDOUT, "\tGL_DOUBLEBUFFER      == %s\n", ogl_caps.doublebuffer ? "TRUE" : "FALSE" );
75     fprintf( LOCAL_STDOUT, "\tGL_STEREO            == %s\n", ogl_caps.stereo ? "TRUE" : "FALSE" );
76     fprintf( LOCAL_STDOUT, "\tGL_RED_BITS          == %d\n", ogl_caps.red_bits );
77     fprintf( LOCAL_STDOUT, "\tGL_GREEN_BITS        == %d\n", ogl_caps.green_bits );
78     fprintf( LOCAL_STDOUT, "\tGL_BLUE_BITS         == %d\n", ogl_caps.blue_bits );
79     fprintf( LOCAL_STDOUT, "\tGL_ALPHA_BITS        == %d\n", ogl_caps.alpha_bits );
80     fprintf( LOCAL_STDOUT, "\tGL_INDEX_BITS        == %d\n", ogl_caps.index_bits );
81     fprintf( LOCAL_STDOUT, "\tGL_DEPTH_BITS        == %d\n", ogl_caps.depth_bits );
82     fprintf( LOCAL_STDOUT, "\tGL_STENCIL_BITS      == %d\n", ogl_caps.stencil_bits );
83     fprintf( LOCAL_STDOUT, "\tGL_ACCUM_RED_BITS    == %d\n", ogl_caps.accum_red_bits );
84     fprintf( LOCAL_STDOUT, "\tGL_ACCUM_GREEN_BITS  == %d\n", ogl_caps.accum_green_bits );
85     fprintf( LOCAL_STDOUT, "\tGL_ACCUM_BLUE_BITS   == %d\n", ogl_caps.accum_blue_bits );
86     fprintf( LOCAL_STDOUT, "\tGL_ACCUM_ALPHA_BITS  == %d\n\n", ogl_caps.accum_alpha_bits );
87 
88     fprintf( LOCAL_STDOUT, "\tGL_MAX_LIGHTS        == %d\n",   ogl_caps.max_lights );
89     fprintf( LOCAL_STDOUT, "\tGL_MAX_CLIP_PLANES   == %d\n",   ogl_caps.max_clip_planes );
90     fprintf( LOCAL_STDOUT, "\tGL_MAX_TEXTURE_SIZE  == %d\n\n", ogl_caps.max_texture_size );
91 
92     fprintf( LOCAL_STDOUT, "\tGL_MAX_PIXEL_MAP_TABLE == %d\n",   ogl_caps.max_pixel_map_table );
93     fprintf( LOCAL_STDOUT, "\tGL_MAX_LIST_NESTING    == %d\n",   ogl_caps.max_list_nesting );
94     fprintf( LOCAL_STDOUT, "\tGL_MAX_EVAL_ORDER      == %d\n\n", ogl_caps.max_eval_order );
95 
96     if ( ogl_caps.anisotropic_supported )
97     {
98         fprintf( LOCAL_STDOUT, "\tGL_MAX_TEXTURE_MAX_ANISOTROPY_EXT == %f\n", ogl_caps.maxAnisotropy );
99     }
100 
101     fprintf( LOCAL_STDOUT, "==============================================================\n" );
102 
103     fflush( LOCAL_STDOUT );
104 }
105 
106 //--------------------------------------------------------------------------------------------
107 //--------------------------------------------------------------------------------------------
oglx_bind(GLenum target,GLuint id,GLint wrap_s,GLint wrap_t,GLint min_f,GLint mag_f,GLfloat anisotropy)108 void oglx_bind( GLenum target, GLuint id, GLint wrap_s, GLint wrap_t, GLint min_f, GLint mag_f, GLfloat anisotropy )
109 {
110     GL_DEBUG( glBindTexture )( target, id );
111     GL_DEBUG( glTexParameteri )( target, GL_TEXTURE_WRAP_S, wrap_s );
112     GL_DEBUG( glTexParameteri )( target, GL_TEXTURE_WRAP_T, wrap_t );
113 
114     GL_DEBUG( glTexParameteri )( target, GL_TEXTURE_MAG_FILTER, mag_f );
115     GL_DEBUG( glTexParameteri )( target, GL_TEXTURE_MIN_FILTER, min_f );
116 
117     if ( GL_TEXTURE_2D == target && ogl_caps.anisotropic_supported && anisotropy > 1.0f )
118     {
119         GL_DEBUG( glTexParameterf )( GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, anisotropy );
120     }
121 }
122 
123 //--------------------------------------------------------------------------------------------
oglx_upload_1d(GLboolean use_alpha,GLsizei w,const GLvoid * data)124 void oglx_upload_1d( GLboolean use_alpha, GLsizei w, const GLvoid * data )
125 {
126     if ( use_alpha )
127     {
128         GL_DEBUG( glTexImage1D )( GL_TEXTURE_1D, 0, GL_RGBA, w, 0, GL_RGBA, GL_UNSIGNED_BYTE, data );
129     }
130     else
131     {
132         GL_DEBUG( glTexImage1D )( GL_TEXTURE_1D, 0, GL_RGB, w, 0, GL_BGR_EXT, GL_UNSIGNED_BYTE, data );
133     }
134 }
135 
136 //--------------------------------------------------------------------------------------------
oglx_upload_2d(GLboolean use_alpha,GLsizei w,GLsizei h,const GLvoid * data)137 void oglx_upload_2d( GLboolean use_alpha, GLsizei w, GLsizei h, const GLvoid * data )
138 {
139     if ( use_alpha )
140     {
141         GL_DEBUG( glTexImage2D )( GL_TEXTURE_2D, 0, GL_RGBA, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, data );
142     }
143     else
144     {
145         GL_DEBUG( glTexImage2D )( GL_TEXTURE_2D, 0, GL_RGB, w, h, 0, GL_BGR_EXT, GL_UNSIGNED_BYTE, data );
146     }
147 }
148 
149 //--------------------------------------------------------------------------------------------
oglx_upload_2d_mipmap(GLboolean use_alpha,GLsizei w,GLsizei h,const GLvoid * data)150 void oglx_upload_2d_mipmap( GLboolean use_alpha, GLsizei w, GLsizei h, const GLvoid * data )
151 {
152     if ( use_alpha )
153     {
154         GL_DEBUG( gluBuild2DMipmaps )( GL_TEXTURE_2D, 4, w, h, GL_RGBA, GL_UNSIGNED_BYTE, data );
155     }
156     else
157     {
158         GL_DEBUG( gluBuild2DMipmaps )( GL_TEXTURE_2D, GL_RGB, w, h, GL_BGR_EXT, GL_UNSIGNED_BYTE, data );
159     }
160 }
161 
162 //--------------------------------------------------------------------------------------------
163 //--------------------------------------------------------------------------------------------
oglx_Get_Screen_Info(oglx_caps_t * pcaps)164 void oglx_Get_Screen_Info( oglx_caps_t * pcaps )
165 {
166 
167     memset( pcaps, 0, sizeof( *pcaps ) );
168 
169     // get any pure OpenGL device caps
170 
171     pcaps->gl_version     = GL_DEBUG( glGetString )( GL_VERSION );
172     pcaps->gl_vendor      = GL_DEBUG( glGetString )( GL_VENDOR );
173     pcaps->gl_renderer    = GL_DEBUG( glGetString )( GL_RENDERER );
174     pcaps->gl_extensions  = GL_DEBUG( glGetString )( GL_EXTENSIONS );
175 
176     pcaps->glu_version    = GL_DEBUG( gluGetString )( GL_VERSION );
177     pcaps->glu_extensions = GL_DEBUG( gluGetString )( GL_EXTENSIONS );
178 
179     GL_DEBUG( glGetIntegerv )( GL_MAX_MODELVIEW_STACK_DEPTH,     &pcaps->max_modelview_stack_depth );
180     GL_DEBUG( glGetIntegerv )( GL_MAX_PROJECTION_STACK_DEPTH,    &pcaps->max_projection_stack_depth );
181     GL_DEBUG( glGetIntegerv )( GL_MAX_TEXTURE_STACK_DEPTH,       &pcaps->max_texture_stack_depth );
182     GL_DEBUG( glGetIntegerv )( GL_MAX_NAME_STACK_DEPTH,          &pcaps->max_name_stack_depth );
183     GL_DEBUG( glGetIntegerv )( GL_MAX_ATTRIB_STACK_DEPTH,        &pcaps->max_attrib_stack_depth );
184     GL_DEBUG( glGetIntegerv )( GL_MAX_CLIENT_ATTRIB_STACK_DEPTH, &pcaps->max_client_attrib_stack_depth );
185 
186     GL_DEBUG( glGetIntegerv )( GL_SUBPIXEL_BITS,        &pcaps->subpixel_bits );
187     GL_DEBUG( glGetFloatv )( GL_POINT_SIZE_RANGE,        pcaps->point_size_range );
188     GL_DEBUG( glGetFloatv )( GL_POINT_SIZE_GRANULARITY, &pcaps->point_size_granularity );
189     GL_DEBUG( glGetFloatv )( GL_LINE_WIDTH_RANGE,        pcaps->line_width_range );
190     GL_DEBUG( glGetFloatv )( GL_LINE_WIDTH_GRANULARITY, &pcaps->line_width_granularity );
191 
192     GL_DEBUG( glGetIntegerv )( GL_MAX_VIEWPORT_DIMS, pcaps->max_viewport_dims );
193     GL_DEBUG( glGetBooleanv )( GL_AUX_BUFFERS,      &pcaps->aux_buffers );
194     GL_DEBUG( glGetBooleanv )( GL_RGBA_MODE,        &pcaps->rgba_mode );
195     GL_DEBUG( glGetBooleanv )( GL_INDEX_MODE,       &pcaps->index_mode );
196     GL_DEBUG( glGetBooleanv )( GL_DOUBLEBUFFER,     &pcaps->doublebuffer );
197     GL_DEBUG( glGetBooleanv )( GL_STEREO,           &pcaps->stereo );
198     GL_DEBUG( glGetIntegerv )( GL_RED_BITS,         &pcaps->red_bits );
199     GL_DEBUG( glGetIntegerv )( GL_GREEN_BITS,       &pcaps->green_bits );
200     GL_DEBUG( glGetIntegerv )( GL_BLUE_BITS,        &pcaps->blue_bits );
201     GL_DEBUG( glGetIntegerv )( GL_ALPHA_BITS,       &pcaps->alpha_bits );
202     GL_DEBUG( glGetIntegerv )( GL_INDEX_BITS,       &pcaps->index_bits );
203     GL_DEBUG( glGetIntegerv )( GL_DEPTH_BITS,       &pcaps->depth_bits );
204     GL_DEBUG( glGetIntegerv )( GL_STENCIL_BITS,     &pcaps->stencil_bits );
205     GL_DEBUG( glGetIntegerv )( GL_ACCUM_RED_BITS,   &pcaps->accum_red_bits );
206     GL_DEBUG( glGetIntegerv )( GL_ACCUM_GREEN_BITS, &pcaps->accum_green_bits );
207     GL_DEBUG( glGetIntegerv )( GL_ACCUM_BLUE_BITS,  &pcaps->accum_blue_bits );
208     GL_DEBUG( glGetIntegerv )( GL_ACCUM_ALPHA_BITS, &pcaps->accum_alpha_bits );
209 
210     GL_DEBUG( glGetIntegerv )( GL_MAX_LIGHTS,       &pcaps->max_lights );
211     GL_DEBUG( glGetIntegerv )( GL_MAX_CLIP_PLANES,  &pcaps->max_clip_planes );
212     GL_DEBUG( glGetIntegerv )( GL_MAX_TEXTURE_SIZE, &pcaps->max_texture_size );
213 
214     GL_DEBUG( glGetIntegerv )( GL_MAX_PIXEL_MAP_TABLE, &pcaps->max_pixel_map_table );
215     GL_DEBUG( glGetIntegerv )( GL_MAX_LIST_NESTING,    &pcaps->max_list_nesting );
216     GL_DEBUG( glGetIntegerv )( GL_MAX_EVAL_ORDER,      &pcaps->max_eval_order );
217 
218     pcaps->maxAnisotropy  = 0;
219     pcaps->log2Anisotropy = 0;
220 
221     /// get the supported values for anisotropic filtering
222     pcaps->anisotropic_supported = GL_FALSE;
223     pcaps->maxAnisotropy  = 1.0f;
224     pcaps->log2Anisotropy = 0.0f;
225     if ( NULL != pcaps->gl_extensions && NULL != strstr(( char* )pcaps->gl_extensions, "GL_EXT_texture_filter_anisotropic" ) )
226     {
227         pcaps->anisotropic_supported = GL_TRUE;
228         GL_DEBUG( glGetFloatv )( GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, &( pcaps->maxAnisotropy ) );
229         pcaps->log2Anisotropy = ( 0 == pcaps->maxAnisotropy ) ? 0.0f : floor( log( pcaps->maxAnisotropy + 1e-6 ) / log( 2.0f ) );
230     }
231 }
232 
233 //--------------------------------------------------------------------------------------------
oglx_video_parameters_default(oglx_video_parameters_t * pvid)234 GLboolean oglx_video_parameters_default( oglx_video_parameters_t * pvid )
235 {
236     if ( NULL == pvid ) return GL_FALSE;
237 
238     pvid->multisample     = GL_FALSE;            ///< current antialiasing used through GL_MULTISAMPLES
239     pvid->multisample_arb = GL_FALSE;            ///< current antialiasing used through GL_MULTISAMPLES_ARB
240     pvid->perspective     = GL_FASTEST;          ///< current correction hint
241     pvid->dither          = GL_FALSE;            ///< current dithering flag
242     pvid->shading         = GL_SMOOTH;           ///< current shading type
243     pvid->userAnisotropy  = 0.0f;
244 
245     return GL_TRUE;
246 }
247 
248 //--------------------------------------------------------------------------------------------
249 //--------------------------------------------------------------------------------------------
oglx_set_stdout(FILE * pfile)250 FILE * oglx_set_stdout( FILE * pfile )
251 {
252     FILE * pfile_old = _oglx_stdout;
253 
254     if ( NULL == pfile )
255     {
256         _oglx_stdout = stdout;
257     }
258     else
259     {
260         _oglx_stdout = pfile;
261     }
262 
263     return pfile_old;
264 }
265