~ubuntu-branches/ubuntu/saucy/fgfs-atlas/saucy

« back to all changes in this revision

Viewing changes to src/OutputGL.cxx

  • Committer: Bazaar Package Importer
  • Author(s): Ove Kaaven
  • Date: 2006-03-31 13:37:25 UTC
  • Revision ID: james.westby@ubuntu.com-20060331133725-h671cls8c2a2vpwv
Tags: upstream-0.3.0
ImportĀ upstreamĀ versionĀ 0.3.0

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
#include <iostream>
 
2
#include <png.h>
 
3
extern "C" {
 
4
#include <jpeglib.h>
 
5
}
 
6
#include "OutputGL.hxx"
 
7
 
 
8
float OutputGL::circle_x[];
 
9
float OutputGL::circle_y[];
 
10
 
 
11
const float OutputGL::BRIGHTNESS = 0.6f;
 
12
 
 
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)
 
17
{
 
18
  if ( filename == NULL )
 
19
    openFragment( 0, 0, size );
 
20
 
 
21
  glEnable(GL_BLEND);
 
22
  glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA );
 
23
 
 
24
  shade = true;
 
25
  glEnable(GL_LIGHTING);
 
26
  glShadeModel(smooth_shading ? GL_SMOOTH : GL_FLAT);
 
27
 
 
28
  glEnable(GL_COLOR_MATERIAL);
 
29
  glColorMaterial(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE);
 
30
 
 
31
  if (useTexturedFont) {
 
32
    font = new fntTexFont( fontname );
 
33
    textRenderer.setFont( font );
 
34
    textRenderer.setPointSize( 12 );
 
35
  } else {
 
36
    glutFont = new puFont;
 
37
  }
 
38
 
 
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);
 
42
  }
 
43
 
 
44
  image = new GLubyte[size*size*3];
 
45
}
 
46
 
 
47
OutputGL::~OutputGL() {
 
48
  delete [] image;
 
49
 
 
50
  if (useTexturedFont) {
 
51
    delete font;
 
52
  } else {
 
53
    delete glutFont;
 
54
  }
 
55
}
 
56
 
 
57
void OutputGL::openFragment( int x, int y, int s )
 
58
{
 
59
  fragment_size = s;
 
60
  posx = x;
 
61
  posy = y;
 
62
 
 
63
  if ( s == 0 )
 
64
      s = size;
 
65
  glViewport( 0, 0, s, s );
 
66
  glMatrixMode( GL_PROJECTION );
 
67
  glLoadIdentity();
 
68
  glOrtho( x, x+s, y, y+s, -1.0f, 1.0f );
 
69
  glMatrixMode( GL_MODELVIEW );
 
70
  glLoadIdentity();
 
71
}
 
72
 
 
73
void OutputGL::closeFragment() {
 
74
  if (!open)
 
75
    return;
 
76
 
 
77
  GLubyte *subimage = new GLubyte[fragment_size*fragment_size*3];
 
78
  if (!subimage)
 
79
    return;
 
80
 
 
81
  // grab screen
 
82
  glFinish();
 
83
  glReadPixels(0, 0, fragment_size, fragment_size,
 
84
               GL_RGB, GL_UNSIGNED_BYTE, subimage);
 
85
 
 
86
  int sx = fragment_size,
 
87
      sy = fragment_size;
 
88
  if ( posx + sx > size )
 
89
    sx = size - posx;
 
90
  if ( posy + sy > size )
 
91
    sy = size - posy;
 
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];
 
97
    }
 
98
  }
 
99
  delete [] subimage;
 
100
}
 
101
 
 
102
void OutputGL::closeOutput() {
 
103
  if (!open)
 
104
    return;
 
105
 
 
106
  open = false;
 
107
 
 
108
  int scale = rescale;
 
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 ) {
 
116
          int x1 = x2 + x2;
 
117
          int x1_1 = x1 + 1;
 
118
          int y1 = y2 + y2;
 
119
          int y1_1 = y1 + 1;
 
120
 
 
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 ];
 
125
 
 
126
          buffer[ (y2 * new_size + x2) * 3 + c ] = ( t1 + t2 + t3 + t4 ) / 4 ;
 
127
        }
 
128
      }
 
129
    }
 
130
    scale >>= 1;
 
131
    current_size = new_size;
 
132
    delete[] image;
 
133
    image = buffer;
 
134
  }
 
135
 
 
136
  FILE *fp = fopen(filename, "wb");
 
137
  if (!fp) {
 
138
    printf("OutputGL::closeOutput: can't create '%s'\n", filename);
 
139
    return;
 
140
  }
 
141
 
 
142
  if ( jpeg ) {
 
143
    jpeg_compress_struct cinfo;
 
144
    memset( &cinfo, 0, sizeof cinfo );
 
145
 
 
146
    jpeg_error_mgr jerr;
 
147
    memset( &jerr, 0, sizeof jerr );
 
148
    cinfo.err = jpeg_std_error( &jerr );
 
149
 
 
150
    jpeg_create_compress( &cinfo );
 
151
    jpeg_stdio_dest( &cinfo, fp );
 
152
 
 
153
    cinfo.image_width = current_size;
 
154
    cinfo.image_height = current_size;
 
155
    cinfo.input_components = 3;
 
156
    cinfo.in_color_space = JCS_RGB;
 
157
 
 
158
    jpeg_set_defaults(&cinfo);
 
159
    jpeg_set_quality(&cinfo,jpeg_quality,false);
 
160
 
 
161
    jpeg_start_compress( &cinfo, TRUE );
 
162
 
 
163
    while ( cinfo.next_scanline < cinfo.image_height ) {
 
164
       unsigned char *buf;
 
165
       if ( 1 ) {
 
166
          buf = (unsigned char *)&image[ current_size * ( current_size - ( cinfo.next_scanline + 1 ) ) * 3 ];
 
167
       } else {
 
168
          buf = (unsigned char *)&image[ current_size * cinfo.next_scanline * 3 ];
 
169
       }
 
170
       jpeg_write_scanlines( &cinfo, (JSAMPARRAY)&buf, 1 );
 
171
    }
 
172
 
 
173
    jpeg_finish_compress( &cinfo );
 
174
    jpeg_destroy_compress( &cinfo );
 
175
  } else {
 
176
    png_structp png_ptr = png_create_write_struct
 
177
      (PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
 
178
    if (!png_ptr)
 
179
      return;
 
180
 
 
181
    png_infop info_ptr = png_create_info_struct(png_ptr);
 
182
    if (!info_ptr) {
 
183
      png_destroy_write_struct(&png_ptr,
 
184
                               (png_infopp)NULL);
 
185
      return;
 
186
    }
 
187
 
 
188
    if (setjmp(png_ptr->jmpbuf)) {
 
189
      png_destroy_write_struct(&png_ptr, &info_ptr);
 
190
      fclose(fp);
 
191
      return;
 
192
    }
 
193
 
 
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);
 
199
 
 
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);
 
203
    }
 
204
 
 
205
    // actually write the image
 
206
    png_write_image(png_ptr, row_pointers);
 
207
 
 
208
    delete[] row_pointers;
 
209
 
 
210
    png_write_end(png_ptr, info_ptr);
 
211
    png_destroy_write_struct(&png_ptr, &info_ptr);
 
212
  }
 
213
  fclose(fp);
 
214
  printf("Written '%s'\n", filename);
 
215
}
 
216
 
 
217
void OutputGL::setShade( bool shade ) {
 
218
  if (shade) {
 
219
    glEnable( GL_LIGHTING );
 
220
  } else {
 
221
    glDisable( GL_LIGHTING );
 
222
  }
 
223
 
 
224
  this->shade = shade;
 
225
}
 
226
 
 
227
bool OutputGL::getShade() {
 
228
  return shade;
 
229
}
 
230
 
 
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};
 
234
 
 
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 );
 
241
}
 
242
 
 
243
void OutputGL::setColor( const float *rgba ) {
 
244
  glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, rgba);
 
245
  glColor4fv( rgba );
 
246
}
 
247
 
 
248
void OutputGL::clear( const float *rgb ) {
 
249
  glClearColor(rgb[0], rgb[1], rgb[2], 1.0f);
 
250
  glClear(GL_COLOR_BUFFER_BIT);
 
251
}
 
252
 
 
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]);
 
258
  glEnd();
 
259
}
 
260
 
 
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]);
 
266
  glEnd();
 
267
}
 
268
 
 
269
void OutputGL::drawQuad( const sgVec2 *p, const sgVec3 *normals ) {
 
270
  glBegin(GL_QUADS);
 
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] );
 
275
  glEnd();
 
276
}
 
277
 
 
278
void OutputGL::drawQuad( const sgVec2 *p, const sgVec3 *normals, const sgVec4 *color ) {
 
279
  glBegin(GL_QUADS);
 
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] );
 
284
  glEnd();
 
285
}
 
286
 
 
287
void OutputGL::drawCircle( sgVec2 p, int radius ) {
 
288
 
 
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 );
 
293
  }
 
294
  glEnd();
 
295
}
 
296
 
 
297
void OutputGL::drawLine( sgVec2 p1, sgVec2 p2 ) {
 
298
  glBegin(GL_LINES);
 
299
  glVertex2fv(p1);
 
300
  glVertex2fv(p2);
 
301
  glEnd();
 
302
}
 
303
 
 
304
void OutputGL::drawText( sgVec2 p, char *text ) {
 
305
  if (useTexturedFont) {
 
306
    textRenderer.begin();
 
307
    textRenderer.start2fv( p );
 
308
    textRenderer.puts( text );
 
309
    textRenderer.end();
 
310
    glDisable(GL_TEXTURE_2D);
 
311
  } else {
 
312
    glutFont->drawString( text, (int)p[0], (int)p[1] );
 
313
  }
 
314
}