2 * $Id: gl_common.c,v 1.5 2007-10-14 09:30:16 nkeynes Exp $
4 * Common GL code that doesn't depend on a specific implementation
6 * Copyright (c) 2005 Nathan Keynes.
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
23 #include "drivers/gl_common.h"
25 extern uint32_t video_width, video_height;
26 static GLuint frame_last_texid = 0, fbuf_id = 0;
27 static uint32_t frame_width = 0;
28 static uint32_t frame_height = 0;
29 static uint32_t frame_colour = 0;
30 static gboolean frame_inverted = FALSE;
34 char *required_extensions[] = { "GL_EXT_framebuffer_object", NULL };
37 * Test if a specific extension is supported. From opengl.org
38 * @param extension extension name to check for
39 * @return TRUE if supported, otherwise FALSE.
41 gboolean isGLExtensionSupported( const char *extension )
43 const GLubyte *extensions = NULL;
45 GLubyte *where, *terminator;
47 /* Extension names should not have spaces. */
48 where = (GLubyte *) strchr(extension, ' ');
49 if (where || *extension == '\0')
51 extensions = glGetString(GL_EXTENSIONS);
52 /* It takes a bit of care to be fool-proof about parsing the
53 OpenGL extensions string. Don't be fooled by sub-strings,
57 where = (GLubyte *) strstr((const char *) start, extension);
60 terminator = where + strlen(extension);
61 if (where == start || *(where - 1) == ' ')
62 if (*terminator == ' ' || *terminator == '\0')
69 gboolean hasRequiredGLExtensions( )
74 for( i=0; required_extensions[i] != NULL; i++ ) {
75 if( !isGLExtensionSupported(required_extensions[i]) ) {
76 ERROR( "Required OpenGL extension not supported: %s", required_extensions[i] );
83 void gl_frame_buffer_to_tex_rectangle( frame_buffer_t frame, GLuint texid )
85 GLenum type = colour_formats[frame->colour_format].type;
86 GLenum format = colour_formats[frame->colour_format].format;
87 int bpp = colour_formats[frame->colour_format].bpp;
88 int rowstride = (frame->rowstride / bpp) - frame->width;
90 glPixelStorei( GL_UNPACK_ROW_LENGTH, rowstride );
91 glBindTexture( GL_TEXTURE_RECTANGLE_ARB, texid );
92 glTexImage2D( GL_TEXTURE_RECTANGLE_ARB, 0, GL_RGB,
93 frame->width, frame->height, 0, format, type, frame->data );
96 void gl_display_tex_rectangle( GLuint texid, uint32_t tex_width, uint32_t tex_height, gboolean invert )
100 top = ((float)tex_height) - 0.5;
104 bottom = ((float)tex_height) - 0.5;
107 /* Reset display parameters */
108 glViewport( 0, 0, video_width, video_height );
109 glMatrixMode(GL_PROJECTION);
111 glOrtho( 0, video_width, video_height, 0, 0, -65535 );
112 glMatrixMode(GL_MODELVIEW);
114 glDisable( GL_TEXTURE_2D );
115 glDisable( GL_ALPHA_TEST );
116 glDisable( GL_DEPTH_TEST );
117 glDisable( GL_SCISSOR_TEST );
118 glDisable( GL_CULL_FACE );
122 int x1=0,y1=0,x2=video_width,y2=video_height;
124 int ah = video_width * 0.75;
126 if( ah > video_height ) {
127 int w = (video_height/0.75);
128 x1 = (video_width - w)/2;
134 glVertex2f( x1, video_height );
135 glVertex2f( 0, video_height);
137 glVertex2f( video_width, 0 );
138 glVertex2f( video_width, video_height );
139 glVertex2f( x2, video_height);
141 } else if( ah < video_height ) {
142 y1 = (video_height - ah)/2;
146 glVertex2f( video_width, 0 );
147 glVertex2f( video_width, y1 );
150 glVertex2f( video_width, y2 );
151 glVertex2f( video_width, video_height );
152 glVertex2f( 0, video_height );
156 /* Render the textured rectangle */
157 glEnable( GL_TEXTURE_RECTANGLE_ARB );
158 glBindTexture( GL_TEXTURE_RECTANGLE_ARB, texid );
159 glTexEnvi( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE );
160 glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
161 glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
162 glEnable( GL_BLEND );
163 glBlendFunc( GL_ONE, GL_ZERO );
165 glTexCoord2f( 0.5, top );
166 glVertex2f( x1, y1 );
167 glTexCoord2f( ((float)tex_width)-0.5, top );
168 glVertex2f( x2, y1 );
169 glTexCoord2f( ((float)tex_width)-0.5, bottom );
170 glVertex2f( x2, y2 );
171 glTexCoord2f( 0.5, bottom );
172 glVertex2f( x1, y2 );
174 glDisable( GL_TEXTURE_RECTANGLE_ARB );
176 frame_last_texid = texid;
177 frame_width = tex_width;
178 frame_height = tex_height;
179 frame_inverted = invert;
182 gboolean gl_display_frame_buffer( frame_buffer_t frame )
185 glGenTextures( 1, &fbuf_id );
187 gl_frame_buffer_to_tex_rectangle( frame, fbuf_id );
188 gl_display_tex_rectangle( fbuf_id, frame->width, frame->height, FALSE );
192 gboolean gl_display_blank( uint32_t colour )
194 glViewport( 0, 0, video_width, video_height );
195 glMatrixMode( GL_PROJECTION );
197 glOrtho( 0, video_width, video_height, 0, 0, -65535 );
198 glMatrixMode(GL_MODELVIEW);
200 glColor3b( (colour >> 16) & 0xFF, (colour >> 8) & 0xFF, colour & 0xFF );
201 glRecti(0,0, video_width, video_height );
203 frame_colour = colour;
204 frame_last_texid = 0;
208 void gl_redisplay_last()
210 if( frame_last_texid == 0 ) {
211 gl_display_blank( frame_colour );
213 gl_display_tex_rectangle( frame_last_texid, frame_width, frame_height, frame_inverted );
218 * Generic GL read_render_buffer. This function assumes that the caller
219 * has already set the appropriate glReadBuffer(); in other words, unless
220 * there's only one buffer this needs to be wrapped.
222 gboolean gl_read_render_buffer( render_buffer_t buffer, unsigned char *target )
224 if( buffer->address == -1 )
227 GLenum type = colour_formats[buffer->colour_format].type;
228 GLenum format = colour_formats[buffer->colour_format].format;
229 // int line_size = buffer->width * colour_formats[buffer->colour_format].bpp;
230 // int size = line_size * buffer->height;
231 // int rowstride = (buffer->rowstride / colour_formats[buffer->colour_format].bpp) - buffer->width;
232 // glPixelStorei( GL_PACK_ROW_LENGTH, rowstride );
234 glReadPixels( 0, 0, buffer->width, buffer->height, format, type, target );
.