6
#include "OutputGL.hxx"
8
float OutputGL::circle_x[];
9
float OutputGL::circle_y[];
11
const float OutputGL::BRIGHTNESS = 0.6f;
13
OutputGL::OutputGL( char *filename, int size, bool smooth_shading,
14
bool useTexturedFont, char *fontname, bool jpg, int q, int r ) :
15
GfxOutput(filename, size), filename(filename),
16
useTexturedFont(useTexturedFont), jpeg(jpg), jpeg_quality(q), rescale(r)
18
if ( filename == NULL )
19
openFragment( 0, 0, size );
22
glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA );
25
glEnable(GL_LIGHTING);
26
glShadeModel(smooth_shading ? GL_SMOOTH : GL_FLAT);
28
glEnable(GL_COLOR_MATERIAL);
29
glColorMaterial(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE);
31
if (useTexturedFont) {
32
font = new fntTexFont( fontname );
33
textRenderer.setFont( font );
34
textRenderer.setPointSize( 12 );
36
glutFont = new puFont;
39
for (int i = 0; i < SUBDIVISIONS; i++) {
40
circle_x[i] = cos(2*SG_PI / SUBDIVISIONS * i);
41
circle_y[i] = sin(2*SG_PI / SUBDIVISIONS * i);
44
image = new GLubyte[size*size*3];
47
OutputGL::~OutputGL() {
50
if (useTexturedFont) {
57
void OutputGL::openFragment( int x, int y, int s )
65
glViewport( 0, 0, s, s );
66
glMatrixMode( GL_PROJECTION );
68
glOrtho( x, x+s, y, y+s, -1.0f, 1.0f );
69
glMatrixMode( GL_MODELVIEW );
73
void OutputGL::closeFragment() {
77
GLubyte *subimage = new GLubyte[fragment_size*fragment_size*3];
83
glReadPixels(0, 0, fragment_size, fragment_size,
84
GL_RGB, GL_UNSIGNED_BYTE, subimage);
86
int sx = fragment_size,
88
if ( posx + sx > size )
90
if ( posy + sy > size )
92
for ( int i = 0; i < sx; ++i ) {
93
for ( int j = 0; j < sy; ++j ) {
94
image[(( j+posy ) * size + ( i+posx )) * 3] = subimage[(j * fragment_size + i) * 3];
95
image[(( j+posy ) * size + ( i+posx )) * 3 + 1] = subimage[(j * fragment_size + i) * 3 + 1];
96
image[(( j+posy ) * size + ( i+posx )) * 3 + 2] = subimage[(j * fragment_size + i) * 3 + 2];
102
void OutputGL::closeOutput() {
109
int current_size = size;
110
while ( scale && ( scale & 1 ) == 0 ) {
111
int new_size = current_size / 2;
112
GLubyte *buffer = new GLubyte[new_size*new_size*3];
113
for ( int x2 = 0; x2 < new_size; ++x2 ) {
114
for ( int y2 = 0; y2 < new_size; ++y2 ) {
115
for ( int c = 0; c < 3; ++c ) {
121
int t1 = image[ (y1 * current_size + x1 ) * 3 + c ];
122
int t2 = image[ (y1_1 * current_size + x1 ) * 3 + c ];
123
int t3 = image[ (y1 * current_size + x1_1) * 3 + c ];
124
int t4 = image[ (y1_1 * current_size + x1_1) * 3 + c ];
126
buffer[ (y2 * new_size + x2) * 3 + c ] = ( t1 + t2 + t3 + t4 ) / 4 ;
131
current_size = new_size;
136
FILE *fp = fopen(filename, "wb");
138
printf("OutputGL::closeOutput: can't create '%s'\n", filename);
143
jpeg_compress_struct cinfo;
144
memset( &cinfo, 0, sizeof cinfo );
147
memset( &jerr, 0, sizeof jerr );
148
cinfo.err = jpeg_std_error( &jerr );
150
jpeg_create_compress( &cinfo );
151
jpeg_stdio_dest( &cinfo, fp );
153
cinfo.image_width = current_size;
154
cinfo.image_height = current_size;
155
cinfo.input_components = 3;
156
cinfo.in_color_space = JCS_RGB;
158
jpeg_set_defaults(&cinfo);
159
jpeg_set_quality(&cinfo,jpeg_quality,false);
161
jpeg_start_compress( &cinfo, TRUE );
163
while ( cinfo.next_scanline < cinfo.image_height ) {
166
buf = (unsigned char *)&image[ current_size * ( current_size - ( cinfo.next_scanline + 1 ) ) * 3 ];
168
buf = (unsigned char *)&image[ current_size * cinfo.next_scanline * 3 ];
170
jpeg_write_scanlines( &cinfo, (JSAMPARRAY)&buf, 1 );
173
jpeg_finish_compress( &cinfo );
174
jpeg_destroy_compress( &cinfo );
176
png_structp png_ptr = png_create_write_struct
177
(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
181
png_infop info_ptr = png_create_info_struct(png_ptr);
183
png_destroy_write_struct(&png_ptr,
188
if (setjmp(png_ptr->jmpbuf)) {
189
png_destroy_write_struct(&png_ptr, &info_ptr);
194
png_init_io(png_ptr, fp);
195
png_set_IHDR(png_ptr, info_ptr, current_size, current_size, 8, PNG_COLOR_TYPE_RGB,
196
PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_DEFAULT,
197
PNG_FILTER_TYPE_DEFAULT);
198
png_write_info(png_ptr, info_ptr);
200
png_byte **row_pointers = new png_byte*[current_size];
201
for (int i = 1; i <= current_size; i++) {
202
row_pointers[i-1] = (png_byte*)(image + current_size * (current_size-i) * 3);
205
// actually write the image
206
png_write_image(png_ptr, row_pointers);
208
delete[] row_pointers;
210
png_write_end(png_ptr, info_ptr);
211
png_destroy_write_struct(&png_ptr, &info_ptr);
214
printf("Written '%s'\n", filename);
217
void OutputGL::setShade( bool shade ) {
219
glEnable( GL_LIGHTING );
221
glDisable( GL_LIGHTING );
227
bool OutputGL::getShade() {
231
void OutputGL::setLightVector( sgVec3 light ) {
232
GLfloat ambient[] = {BRIGHTNESS/3.0f, BRIGHTNESS/3.0f, BRIGHTNESS/3.0f,1.0f};
233
GLfloat diffuse[] = {BRIGHTNESS, BRIGHTNESS, BRIGHTNESS, 1.0f};
235
sgCopyVec3( light_vector, light );
236
light_vector[3] = 0.0f;
237
glLightfv( GL_LIGHT0, GL_AMBIENT, ambient );
238
glLightfv( GL_LIGHT0, GL_DIFFUSE, diffuse );
239
glLightfv( GL_LIGHT0, GL_POSITION, light_vector );
240
glEnable( GL_LIGHT0 );
243
void OutputGL::setColor( const float *rgba ) {
244
glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, rgba);
248
void OutputGL::clear( const float *rgb ) {
249
glClearColor(rgb[0], rgb[1], rgb[2], 1.0f);
250
glClear(GL_COLOR_BUFFER_BIT);
253
void OutputGL::drawTriangle( const sgVec2 *p, const sgVec3 *normals ) {
254
glBegin(GL_TRIANGLES);
255
glNormal3fv( normals[0] ); glVertex2fv( p[0] );
256
glNormal3fv( normals[1] ); glVertex2fv( p[1] );
257
glNormal3fv( normals[2] ); glVertex2fv( p[2]);
261
void OutputGL::drawTriangle( const sgVec2 *p, const sgVec3 *normals, const sgVec4 *color ) {
262
glBegin(GL_TRIANGLES);
263
glColor4fv( color[0] );glNormal3fv( normals[0] ); glVertex2fv( p[0] );
264
glColor4fv( color[1] );glNormal3fv( normals[1] ); glVertex2fv( p[1] );
265
glColor4fv( color[2] );glNormal3fv( normals[2] ); glVertex2fv( p[2]);
269
void OutputGL::drawQuad( const sgVec2 *p, const sgVec3 *normals ) {
271
glNormal3fv( normals[0] ); glVertex2fv( p[0] );
272
glNormal3fv( normals[1] ); glVertex2fv( p[1] );
273
glNormal3fv( normals[2] ); glVertex2fv( p[2] );
274
glNormal3fv( normals[3] ); glVertex2fv( p[3] );
278
void OutputGL::drawQuad( const sgVec2 *p, const sgVec3 *normals, const sgVec4 *color ) {
280
glColor4fv( color[0] );glNormal3fv( normals[0] ); glVertex2fv( p[0] );
281
glColor4fv( color[1] );glNormal3fv( normals[1] ); glVertex2fv( p[1] );
282
glColor4fv( color[2] );glNormal3fv( normals[2] ); glVertex2fv( p[2] );
283
glColor4fv( color[3] );glNormal3fv( normals[3] ); glVertex2fv( p[3] );
287
void OutputGL::drawCircle( sgVec2 p, int radius ) {
289
glBegin(GL_LINE_LOOP);
290
for (int i = 0; i < SUBDIVISIONS; i++) {
291
glVertex2f( p[0] + circle_x[i] * radius,
292
p[1] + circle_y[i] * radius );
297
void OutputGL::drawLine( sgVec2 p1, sgVec2 p2 ) {
304
void OutputGL::drawText( sgVec2 p, char *text ) {
305
if (useTexturedFont) {
306
textRenderer.begin();
307
textRenderer.start2fv( p );
308
textRenderer.puts( text );
310
glDisable(GL_TEXTURE_2D);
312
glutFont->drawString( text, (int)p[0], (int)p[1] );