filename | src/drivers/video_gl.c |
changeset | 1236:d93175c36387 |
prev | 1222:a4545699a82b |
next | 1239:be3121267597 |
author | nkeynes |
date | Fri Feb 24 21:17:47 2012 +1000 (11 years ago) |
permissions | -rw-r--r-- |
last change | Factor video_width/video_height out into video_gl.c Convert immediate-mode bits in video_gl.c into a structure for glDrawArray Move setOrtho into defineOrthoMatrix in glutil.c Rearrange various GL settings to keep a consistent state |
view | annotate | diff | log | raw |
1 /**
2 * $Id$
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 "display.h"
22 #include "pvr2/pvr2.h"
23 #include "pvr2/glutil.h"
24 #include "drivers/video_gl.h"
26 uint32_t video_width, video_height;
27 struct video_vertex {
28 float x,y;
29 float u,v;
30 float r,g,b;
31 };
33 static struct video_box_t {
34 float viewMatrix[16];
35 struct video_vertex gap1[4];
36 struct video_vertex gap2[4];
37 struct video_vertex video_view[4];
38 struct video_vertex invert_view[4];
39 } video_box;
41 void gl_set_video_size( uint32_t width, uint32_t height )
42 {
43 video_width = width;
44 video_height = height;
46 int x1=0,y1=0,x2=video_width,y2=video_height;
48 int ah = video_width * 0.75;
50 if( ah > video_height ) {
51 int w = (video_height/0.75);
52 x1 = (video_width - w)/2;
53 x2 -= x1;
54 video_box.gap1[0].x = 0; video_box.gap1[0].y = 0;
55 video_box.gap1[1].x = x1; video_box.gap1[1].y = 0;
56 video_box.gap1[2].x = 0; video_box.gap1[2].y = video_height;
57 video_box.gap1[3].x = x2; video_box.gap1[3].y = video_height;
58 video_box.gap2[0].x = x2; video_box.gap2[0].y = 0;
59 video_box.gap2[1].x = video_width; video_box.gap2[1].y = 0;
60 video_box.gap2[2].x = x2; video_box.gap2[2].y = video_height;
61 video_box.gap2[3].x = video_width; video_box.gap2[3].y = video_height;
62 } else if( ah < video_height ) {
63 y1 = (video_height - ah)/2;
64 y2 -= y1;
66 video_box.gap1[0].x = 0; video_box.gap1[0].y = 0;
67 video_box.gap1[1].x = video_width; video_box.gap1[1].y = 0;
68 video_box.gap1[2].x = 0; video_box.gap1[2].y = y1;
69 video_box.gap1[3].x = video_width; video_box.gap1[3].y = y1;
70 video_box.gap2[0].x = 0; video_box.gap2[0].y = y2;
71 video_box.gap2[1].x = video_width; video_box.gap2[1].y = y2;
72 video_box.gap2[2].x = 0; video_box.gap2[2].y = video_height;
73 video_box.gap2[3].x = video_width; video_box.gap2[3].y = video_height;
74 }
76 video_box.video_view[0].x = x1; video_box.video_view[0].y = y1;
77 video_box.video_view[0].u = 0; video_box.video_view[0].v = 0;
78 video_box.video_view[1].x = x2; video_box.video_view[1].y = y1;
79 video_box.video_view[1].u = 1; video_box.video_view[1].v = 0;
80 video_box.video_view[2].x = x1; video_box.video_view[2].y = y2;
81 video_box.video_view[2].u = 0; video_box.video_view[2].v = 1;
82 video_box.video_view[3].x = x2; video_box.video_view[3].y = y2;
83 video_box.video_view[3].u = 1; video_box.video_view[3].v = 1;
85 memcpy( &video_box.invert_view, &video_box.video_view, sizeof(video_box.video_view) );
86 video_box.invert_view[0].v = 1; video_box.invert_view[1].v = 1;
87 video_box.invert_view[2].v = 0; video_box.invert_view[3].v = 0;
89 defineOrthoMatrix(video_box.viewMatrix, video_width, video_height, 0, 65535);
90 }
92 /**
93 * Setup the gl context for writes to the display output.
94 */
95 void gl_framebuffer_setup()
96 {
97 glLoadMatrixf(video_box.viewMatrix);
98 glBlendFunc( GL_ONE, GL_ZERO );
99 glTexEnvi( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE );
100 glViewport( 0, 0, video_width, video_height );
101 glVertexPointer(2, GL_FLOAT, sizeof(struct video_vertex), &video_box.gap1[0].x);
102 glColorPointer(3, GL_FLOAT, sizeof(struct video_vertex), &video_box.gap1[0].r);
103 glTexCoordPointer(2, GL_FLOAT, sizeof(struct video_vertex), &video_box.gap1[0].u);
104 glEnableClientState( GL_VERTEX_ARRAY );
105 glEnableClientState( GL_COLOR_ARRAY );
106 glEnableClientState( GL_TEXTURE_COORD_ARRAY );
107 }
109 void gl_display_render_buffer( render_buffer_t buffer )
110 {
111 gl_texture_window( buffer->width, buffer->height, buffer->buf_id, buffer->inverted );
112 }
114 /**
115 * Convert window coordinates to dreamcast device coords (640x480) using the
116 * same viewable area as gl_texture_window.
117 * If the coordinates are outside the viewable area, the result is -1,-1.
118 */
119 void gl_window_to_system_coords( int *x, int *y )
120 {
121 int x1=0,y1=0,x2=video_width,y2=video_height;
123 int ah = video_width * 0.75;
125 if( ah > video_height ) {
126 int w = (video_height/0.75);
127 x1 = (video_width - w)/2;
128 x2 -= x1;
129 } else if( ah < video_height ) {
130 y1 = (video_height - ah)/2;
131 y2 -= y1;
132 }
133 if( *x < x1 || *x >= x2 || *y < y1 || *y >= y2 ) {
134 *x = -1;
135 *y = -1;
136 } else {
137 *x = (*x - x1) * DISPLAY_WIDTH / (x2-x1);
138 *y = (*y - y1) * DISPLAY_HEIGHT / (y2-y1);
139 }
140 }
142 void gl_texture_window( int width, int height, int tex_id, gboolean inverted )
143 {
144 /* Reset display parameters */
145 gl_framebuffer_setup();
146 glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
147 glDrawArrays(GL_TRIANGLE_STRIP, 4, 4);
148 glEnable(GL_TEXTURE_2D);
149 glBindTexture(GL_TEXTURE_2D,tex_id);
150 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
151 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
152 glDrawArrays(GL_TRIANGLE_STRIP, inverted ? 12 : 8, 4);
153 glDisable(GL_TEXTURE_2D);
154 glFlush();
155 }
157 gboolean gl_load_frame_buffer( frame_buffer_t frame, int tex_id )
158 {
159 GLenum type = colour_formats[frame->colour_format].type;
160 GLenum format = colour_formats[frame->colour_format].format;
161 int bpp = colour_formats[frame->colour_format].bpp;
162 int rowstride = (frame->rowstride / bpp) - frame->width;
164 glPixelStorei( GL_UNPACK_ROW_LENGTH, rowstride );
165 glBindTexture( GL_TEXTURE_2D, tex_id );
166 glTexSubImage2D( GL_TEXTURE_2D, 0, 0,0,
167 frame->width, frame->height, format, type, frame->data );
168 glPixelStorei( GL_UNPACK_ROW_LENGTH, 0 );
169 return TRUE;
170 }
172 void gl_display_blank( uint32_t colour )
173 {
174 /* Set the video_box background colour */
175 video_box.video_view[0].r = ((float)(((colour >> 16) & 0xFF) + 1)) / 256.0;
176 video_box.video_view[0].g = ((float)(((colour >> 8) & 0xFF) + 1)) / 256.0;
177 video_box.video_view[0].b = ((float)((colour & 0xFF) + 1)) / 256.0;
178 memcpy( &video_box.video_view[1].r, &video_box.video_view[0].r, sizeof(float)*3 );
179 memcpy( &video_box.video_view[2].r, &video_box.video_view[0].r, sizeof(float)*3 );
180 memcpy( &video_box.video_view[3].r, &video_box.video_view[0].r, sizeof(float)*3 );
182 /* And render */
183 gl_framebuffer_setup();
184 glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
185 glDrawArrays(GL_TRIANGLE_STRIP, 4, 4);
186 glDrawArrays(GL_TRIANGLE_STRIP, 8, 4);
187 glFlush();
188 }
190 /**
191 * Generic GL read_render_buffer. This function assumes that the caller
192 * has already set the appropriate glReadBuffer(); in other words, unless
193 * there's only one buffer this needs to be wrapped.
194 */
195 gboolean gl_read_render_buffer( unsigned char *target, render_buffer_t buffer,
196 int rowstride, int colour_format )
197 {
198 glFinish();
199 GLenum type = colour_formats[colour_format].type;
200 GLenum format = colour_formats[colour_format].format;
201 // int line_size = buffer->width * colour_formats[colour_format].bpp;
202 // int size = line_size * buffer->height;
203 int glrowstride = (rowstride / colour_formats[colour_format].bpp) - buffer->width;
204 glPixelStorei( GL_PACK_ROW_LENGTH, glrowstride );
205 glReadPixels( 0, 0, buffer->width, buffer->height, format, type, target );
206 glPixelStorei( GL_PACK_ROW_LENGTH, 0 );
207 return TRUE;
208 }
.