Search
lxdream.org :: lxdream/src/drivers/gl_common.c
lxdream 0.9.1
released Jun 29
Download Now
filename src/drivers/gl_common.c
changeset 444:74c38d57eb11
prev443:1163eb5c0590
next477:9a373f2ff009
author nkeynes
date Tue Oct 16 12:27:28 2007 +0000 (13 years ago)
permissions -rw-r--r--
last change Unbind the framebuffer after initialization
view annotate diff log raw
     1 /**
     2  * $Id: gl_common.c,v 1.5 2007-10-14 09:30:16 nkeynes Exp $
     3  *
     4  * Common GL code that doesn't depend on a specific implementation
     5  *
     6  * Copyright (c) 2005 Nathan Keynes.
     7  *
     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.
    12  *
    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.
    17  */
    19 #include <sys/time.h>
    21 #include <GL/gl.h>
    22 #include "dream.h"
    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 };
    36 /**
    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.
    40  */
    41 gboolean isGLExtensionSupported( const char *extension )
    42 {
    43     const GLubyte *extensions = NULL;
    44     const GLubyte *start;
    45     GLubyte *where, *terminator;
    47     /* Extension names should not have spaces. */
    48     where = (GLubyte *) strchr(extension, ' ');
    49     if (where || *extension == '\0')
    50 	return 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,
    54        etc. */
    55     start = extensions;
    56     for (;;) {
    57 	where = (GLubyte *) strstr((const char *) start, extension);
    58 	if (!where)
    59 	    break;
    60 	terminator = where + strlen(extension);
    61 	if (where == start || *(where - 1) == ' ')
    62 	    if (*terminator == ' ' || *terminator == '\0')
    63 		return TRUE;
    64 	start = terminator;
    65     }
    66     return FALSE;
    67 }
    69 gboolean hasRequiredGLExtensions( ) 
    70 {
    71     int i;
    72     gboolean isOK = TRUE;
    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] );
    77 	    isOK = FALSE;
    78 	}
    79     }
    80     return isOK;
    81 }
    83 void gl_frame_buffer_to_tex_rectangle( frame_buffer_t frame, GLuint texid )
    84 {
    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 );
    94 }
    96 void gl_display_tex_rectangle( GLuint texid, uint32_t tex_width, uint32_t tex_height, gboolean invert )
    97 {
    98     float top, bottom;
    99     if( invert ) {
   100 	top = ((float)tex_height) - 0.5;
   101 	bottom = 0.5;
   102     } else {
   103 	top = 0.5;
   104 	bottom = ((float)tex_height) - 0.5;
   105     }
   107     /* Reset display parameters */
   108     glViewport( 0, 0, video_width, video_height );
   109     glMatrixMode(GL_PROJECTION);
   110     glLoadIdentity();
   111     glOrtho( 0, video_width, video_height, 0, 0, -65535 );
   112     glMatrixMode(GL_MODELVIEW);
   113     glLoadIdentity();
   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 );
   119     glColor3f( 0,0,0 );
   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;
   129 	x2 -= x1;
   131 	glBegin( GL_QUADS );
   132 	glVertex2f( 0, 0 );
   133 	glVertex2f( x1, 0 );
   134 	glVertex2f( x1, video_height );
   135 	glVertex2f( 0, video_height);
   136 	glVertex2f( x2, 0 );
   137 	glVertex2f( video_width, 0 );
   138 	glVertex2f( video_width, video_height );
   139 	glVertex2f( x2, video_height);
   140 	glEnd();
   141     } else if( ah < video_height ) {
   142 	y1 = (video_height - ah)/2;
   143 	y2 -= y1;
   144 	glBegin( GL_QUADS );
   145 	glVertex2f( 0, 0 );
   146 	glVertex2f( video_width, 0 );
   147 	glVertex2f( video_width, y1 );
   148 	glVertex2f( 0, y1 );
   149 	glVertex2f( 0, y2 );
   150 	glVertex2f( video_width, y2 );
   151 	glVertex2f( video_width, video_height );
   152 	glVertex2f( 0, video_height );
   153 	glEnd();
   154     }
   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 );
   164     glBegin( GL_QUADS );
   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 );
   173     glEnd();
   174     glDisable( GL_TEXTURE_RECTANGLE_ARB );
   175     glFlush();
   176     frame_last_texid = texid;
   177     frame_width = tex_width;
   178     frame_height = tex_height;
   179     frame_inverted = invert;
   180 }
   182 gboolean gl_display_frame_buffer( frame_buffer_t frame )
   183 {
   184     if( fbuf_id == 0 ) {
   185 	glGenTextures( 1, &fbuf_id );
   186     }
   187     gl_frame_buffer_to_tex_rectangle( frame, fbuf_id );
   188     gl_display_tex_rectangle( fbuf_id, frame->width, frame->height, FALSE );
   189     return TRUE;
   190 }
   192 gboolean gl_display_blank( uint32_t colour )
   193 {
   194     glViewport( 0, 0, video_width, video_height );
   195     glMatrixMode( GL_PROJECTION );
   196     glLoadIdentity();
   197     glOrtho( 0, video_width, video_height, 0, 0, -65535 );
   198     glMatrixMode(GL_MODELVIEW);
   199     glLoadIdentity();
   200     glColor3b( (colour >> 16) & 0xFF, (colour >> 8) & 0xFF, colour & 0xFF );
   201     glRecti(0,0, video_width, video_height );
   202     glFlush();
   203     frame_colour = colour;
   204     frame_last_texid = 0;
   205     return TRUE;
   206 }
   208 void gl_redisplay_last()
   209 {
   210     if( frame_last_texid == 0 ) {
   211 	gl_display_blank( frame_colour );
   212     } else {
   213 	gl_display_tex_rectangle( frame_last_texid, frame_width, frame_height, frame_inverted );
   214     }
   215 }
   217 /**
   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.
   221  */
   222 gboolean gl_read_render_buffer( render_buffer_t buffer, unsigned char *target ) 
   223 {
   224     if( buffer->address == -1 )
   225 	return FALSE;
   226     glFinish();
   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 );
   235     return TRUE;
   236 }
.