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 352:f0df7a6d4703
next424:421d68e78c46
author nkeynes
date Sun Feb 11 10:09:32 2007 +0000 (17 years ago)
permissions -rw-r--r--
last change Bug 27: Implement opengl framebuffer objects
Rewrite much of the final video output stage. Now uses generic "render
buffers", implemented on GL using framebuffer objects + textures.
file annotate diff log raw
nkeynes@352
     1
/**
nkeynes@352
     2
 * $Id: gl_common.c,v 1.1 2007-02-11 10:09:32 nkeynes Exp $
nkeynes@352
     3
 *
nkeynes@352
     4
 * Common GL code that doesn't depend on a specific implementation
nkeynes@352
     5
 *
nkeynes@352
     6
 * Copyright (c) 2005 Nathan Keynes.
nkeynes@352
     7
 *
nkeynes@352
     8
 * This program is free software; you can redistribute it and/or modify
nkeynes@352
     9
 * it under the terms of the GNU General Public License as published by
nkeynes@352
    10
 * the Free Software Foundation; either version 2 of the License, or
nkeynes@352
    11
 * (at your option) any later version.
nkeynes@352
    12
 *
nkeynes@352
    13
 * This program is distributed in the hope that it will be useful,
nkeynes@352
    14
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
nkeynes@352
    15
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
nkeynes@352
    16
 * GNU General Public License for more details.
nkeynes@352
    17
 */
nkeynes@352
    18
nkeynes@352
    19
#include <GL/gl.h>
nkeynes@352
    20
#include "dream.h"
nkeynes@352
    21
#include "drivers/gl_common.h"
nkeynes@352
    22
nkeynes@352
    23
extern uint32_t video_width, video_height;
nkeynes@352
    24
nkeynes@352
    25
char *required_extensions[] = { "GL_EXT_framebuffer_object", NULL };
nkeynes@352
    26
nkeynes@352
    27
/**
nkeynes@352
    28
 * Test if a specific extension is supported. From opengl.org
nkeynes@352
    29
 * @param extension extension name to check for
nkeynes@352
    30
 * @return TRUE if supported, otherwise FALSE.
nkeynes@352
    31
 */
nkeynes@352
    32
gboolean isGLExtensionSupported( const char *extension )
nkeynes@352
    33
{
nkeynes@352
    34
    const GLubyte *extensions = NULL;
nkeynes@352
    35
    const GLubyte *start;
nkeynes@352
    36
    GLubyte *where, *terminator;
nkeynes@352
    37
nkeynes@352
    38
    /* Extension names should not have spaces. */
nkeynes@352
    39
    where = (GLubyte *) strchr(extension, ' ');
nkeynes@352
    40
    if (where || *extension == '\0')
nkeynes@352
    41
	return 0;
nkeynes@352
    42
    extensions = glGetString(GL_EXTENSIONS);
nkeynes@352
    43
    /* It takes a bit of care to be fool-proof about parsing the
nkeynes@352
    44
       OpenGL extensions string. Don't be fooled by sub-strings,
nkeynes@352
    45
       etc. */
nkeynes@352
    46
    start = extensions;
nkeynes@352
    47
    for (;;) {
nkeynes@352
    48
	where = (GLubyte *) strstr((const char *) start, extension);
nkeynes@352
    49
	if (!where)
nkeynes@352
    50
	    break;
nkeynes@352
    51
	terminator = where + strlen(extension);
nkeynes@352
    52
	if (where == start || *(where - 1) == ' ')
nkeynes@352
    53
	    if (*terminator == ' ' || *terminator == '\0')
nkeynes@352
    54
		return TRUE;
nkeynes@352
    55
	start = terminator;
nkeynes@352
    56
    }
nkeynes@352
    57
    return FALSE;
nkeynes@352
    58
}
nkeynes@352
    59
nkeynes@352
    60
gboolean hasRequiredGLExtensions( ) 
nkeynes@352
    61
{
nkeynes@352
    62
    int i;
nkeynes@352
    63
    gboolean isOK = TRUE;
nkeynes@352
    64
nkeynes@352
    65
    for( i=0; required_extensions[i] != NULL; i++ ) {
nkeynes@352
    66
	if( !isGLExtensionSupported(required_extensions[i]) ) {
nkeynes@352
    67
	    ERROR( "Required OpenGL extension not supported: %s", required_extensions[i] );
nkeynes@352
    68
	    isOK = FALSE;
nkeynes@352
    69
	}
nkeynes@352
    70
    }
nkeynes@352
    71
    return isOK;
nkeynes@352
    72
}
nkeynes@352
    73
nkeynes@352
    74
nkeynes@352
    75
gboolean gl_display_frame_buffer( frame_buffer_t frame )
nkeynes@352
    76
{
nkeynes@352
    77
    GLenum type = colour_formats[frame->colour_format].type;
nkeynes@352
    78
    GLenum format = colour_formats[frame->colour_format].format;
nkeynes@352
    79
    int bpp = colour_formats[frame->colour_format].bpp;
nkeynes@352
    80
    GLint texid;
nkeynes@352
    81
nkeynes@352
    82
    glViewport( 0, 0, video_width, video_height );
nkeynes@352
    83
    glMatrixMode(GL_PROJECTION);
nkeynes@352
    84
    glLoadIdentity();
nkeynes@352
    85
    glOrtho( 0, video_width, video_height, 0, 0, -65535 );
nkeynes@352
    86
    glMatrixMode(GL_MODELVIEW);
nkeynes@352
    87
    glLoadIdentity();
nkeynes@352
    88
    
nkeynes@352
    89
    /* Disable everything */
nkeynes@352
    90
    glDisable( GL_TEXTURE_2D );
nkeynes@352
    91
    glDisable( GL_ALPHA_TEST );
nkeynes@352
    92
    glDisable( GL_DEPTH_TEST );
nkeynes@352
    93
    glDisable( GL_SCISSOR_TEST );
nkeynes@352
    94
    glDisable( GL_CULL_FACE );
nkeynes@352
    95
nkeynes@352
    96
    float scale = ((float)video_height) / frame->height;
nkeynes@352
    97
    int rowstride = (frame->rowstride / bpp) - frame->width;
nkeynes@352
    98
    
nkeynes@352
    99
    
nkeynes@352
   100
    /*
nkeynes@352
   101
    glGenTextures( 1, &texid );
nkeynes@352
   102
    glBindTexture( GL_TEXTURE_2D, texid );
nkeynes@352
   103
    glTexImage2D( GL_TEXTURE_2D, 0, colour_formats[frame->colour_format].int_format,
nkeynes@352
   104
		  frame->width, frame->height, 0, format, type, frame->data );
nkeynes@352
   105
    glBegin( GL_QUADS );
nkeynes@352
   106
    glTexCoord2i( 0, 1.0 );
nkeynes@352
   107
    glVertex2f( 0.0, 0.0 );
nkeynes@352
   108
    glTexCoord2i( 1.0, 1.0 );
nkeynes@352
   109
    glVertex2f( frame->width, 0.0 );
nkeynes@352
   110
    glTexCoord2i( 1.0, 0.0 );
nkeynes@352
   111
    glVertex2f( frame->width, frame->height );
nkeynes@352
   112
    glTexCoord2i( 0, 0.0 );
nkeynes@352
   113
    glVertex2f( 0.0, frame->height );
nkeynes@352
   114
    glEnd();
nkeynes@352
   115
    glDeleteTextures( 1, &texid );
nkeynes@352
   116
    */
nkeynes@352
   117
    glRasterPos2i( 0, 0 );
nkeynes@352
   118
    glPixelZoom( 1.0f, -scale );
nkeynes@352
   119
    glPixelStorei( GL_UNPACK_ROW_LENGTH, rowstride );
nkeynes@352
   120
    glDrawPixels( frame->width, frame->height, format, type,
nkeynes@352
   121
		  frame->data );
nkeynes@352
   122
    
nkeynes@352
   123
    glFlush();
nkeynes@352
   124
    return TRUE;
nkeynes@352
   125
}
nkeynes@352
   126
nkeynes@352
   127
gboolean gl_display_blank( uint32_t colour )
nkeynes@352
   128
{
nkeynes@352
   129
    glViewport( 0, 0, video_width, video_height );
nkeynes@352
   130
    glMatrixMode( GL_PROJECTION );
nkeynes@352
   131
    glLoadIdentity();
nkeynes@352
   132
    glOrtho( 0, video_width, video_height, 0, 0, -65535 );
nkeynes@352
   133
    glMatrixMode(GL_MODELVIEW);
nkeynes@352
   134
    glLoadIdentity();
nkeynes@352
   135
    glColor3b( (colour >> 16) & 0xFF, (colour >> 8) & 0xFF, colour & 0xFF );
nkeynes@352
   136
    glRecti(0,0, video_width, video_height );
nkeynes@352
   137
    glFlush();
nkeynes@352
   138
    return TRUE;
nkeynes@352
   139
}
nkeynes@352
   140
nkeynes@352
   141
/**
nkeynes@352
   142
 * Generic GL read_render_buffer. This function assumes that the caller
nkeynes@352
   143
 * has already set the appropriate glReadBuffer(); in other words, unless
nkeynes@352
   144
 * there's only one buffer this needs to be wrapped.
nkeynes@352
   145
 */
nkeynes@352
   146
gboolean gl_read_render_buffer( render_buffer_t buffer, char *target ) 
nkeynes@352
   147
{
nkeynes@352
   148
    if( buffer->address == -1 )
nkeynes@352
   149
	return FALSE;
nkeynes@352
   150
    glFinish();
nkeynes@352
   151
    GLenum type = colour_formats[buffer->colour_format].type;
nkeynes@352
   152
    GLenum format = colour_formats[buffer->colour_format].format;
nkeynes@352
   153
    int line_size = buffer->width * colour_formats[buffer->colour_format].bpp;
nkeynes@352
   154
    int size = line_size * buffer->height;
nkeynes@352
   155
    int rowstride = (buffer->rowstride / colour_formats[buffer->colour_format].bpp) - buffer->width;
nkeynes@352
   156
    // glPixelStorei( GL_PACK_ROW_LENGTH, rowstride );
nkeynes@352
   157
    
nkeynes@352
   158
    glReadPixels( 0, 0, buffer->width, buffer->height, format, type, target );
nkeynes@352
   159
    return TRUE;
nkeynes@352
   160
}
.