util: Implement YUV and subsampled RGB format conversion.
[mesa.git] / progs / osdemos / osdemo.c
index 95e2ff9787595ac9bcc821f8c10d42ff630b5e45..bc0168fb97bc3e9a63c6509a726137fed4aacfd4 100644 (file)
@@ -1,11 +1,10 @@
-
 /*
  * Demo of off-screen Mesa rendering
  *
  * See Mesa/include/GL/osmesa.h for documentation of the OSMesa functions.
  *
  * If you want to render BIG images you'll probably have to increase
- * MAX_WIDTH and MAX_HEIGHT in src/config.h.
+ * MAX_WIDTH and MAX_Height in src/config.h.
  *
  * This program is in the public domain.
  *
  * PPM output provided by Joerg Schmalzl.
  * ASCII PPM output added by Brian Paul.
  *
- * Usage: osdemo [-perf] [filename]
- *
- * -perf: Redraws the image 1000 times, displaying the FPS every 5 secs.
- * filename: file to store the TGA or PPM output
+ * Usage: osdemo [filename]
  */
 
 
+#include <math.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
 #include "GL/osmesa.h"
-#include "GL/glut.h"
+#include "GL/glu.h"
 
 
 #define SAVE_TARGA
 
+static int Width = 400;
+static int Height = 400;
+
+
+static void
+Sphere(float radius, int slices, int stacks)
+{
+   GLUquadric *q = gluNewQuadric();
+   gluQuadricNormals(q, GLU_SMOOTH);
+   gluSphere(q, radius, slices, stacks);
+   gluDeleteQuadric(q);
+}
+
 
-#define WIDTH 400
-#define HEIGHT 400
+static void
+Cone(float base, float height, int slices, int stacks)
+{
+   GLUquadric *q = gluNewQuadric();
+   gluQuadricDrawStyle(q, GLU_FILL);
+   gluQuadricNormals(q, GLU_SMOOTH);
+   gluCylinder(q, base, 0.0, height, slices, stacks);
+   gluDeleteQuadric(q);
+}
+
+
+static void
+Torus(float innerRadius, float outerRadius, int sides, int rings)
+{
+   /* from GLUT... */
+   int i, j;
+   GLfloat theta, phi, theta1;
+   GLfloat cosTheta, sinTheta;
+   GLfloat cosTheta1, sinTheta1;
+   const GLfloat ringDelta = 2.0 * M_PI / rings;
+   const GLfloat sideDelta = 2.0 * M_PI / sides;
+
+   theta = 0.0;
+   cosTheta = 1.0;
+   sinTheta = 0.0;
+   for (i = rings - 1; i >= 0; i--) {
+      theta1 = theta + ringDelta;
+      cosTheta1 = cos(theta1);
+      sinTheta1 = sin(theta1);
+      glBegin(GL_QUAD_STRIP);
+      phi = 0.0;
+      for (j = sides; j >= 0; j--) {
+         GLfloat cosPhi, sinPhi, dist;
+
+         phi += sideDelta;
+         cosPhi = cos(phi);
+         sinPhi = sin(phi);
+         dist = outerRadius + innerRadius * cosPhi;
+
+         glNormal3f(cosTheta1 * cosPhi, -sinTheta1 * cosPhi, sinPhi);
+         glVertex3f(cosTheta1 * dist, -sinTheta1 * dist, innerRadius * sinPhi);
+         glNormal3f(cosTheta * cosPhi, -sinTheta * cosPhi, sinPhi);
+         glVertex3f(cosTheta * dist, -sinTheta * dist,  innerRadius * sinPhi);
+      }
+      glEnd();
+      theta = theta1;
+      cosTheta = cosTheta1;
+      sinTheta = sinTheta1;
+   }
+}
 
-static GLint T0 = 0;
-static GLint Frames = 0;
-static int perf = 0;
 
-static void render_image( void )
+static void
+render_image(void)
 {
    GLfloat light_ambient[] = { 0.0, 0.0, 0.0, 1.0 };
    GLfloat light_diffuse[] = { 1.0, 1.0, 1.0, 1.0 };
@@ -72,20 +128,20 @@ static void render_image( void )
    glTranslatef(-0.75, 0.5, 0.0); 
    glRotatef(90.0, 1.0, 0.0, 0.0);
    glMaterialfv( GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, red_mat );
-   glutSolidTorus(0.275, 0.85, 20, 20);
+   Torus(0.275, 0.85, 20, 20);
    glPopMatrix();
 
    glPushMatrix();
    glTranslatef(-0.75, -0.5, 0.0); 
    glRotatef(270.0, 1.0, 0.0, 0.0);
    glMaterialfv( GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, green_mat );
-   glutSolidCone(1.0, 2.0, 16, 1);
+   Cone(1.0, 2.0, 16, 1);
    glPopMatrix();
 
    glPushMatrix();
    glTranslatef(0.75, 0.0, -1.0); 
    glMaterialfv( GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, blue_mat );
-   glutSolidSphere(1.0, 20, 20);
+   Sphere(1.0, 20, 20);
    glPopMatrix();
 
    glPopMatrix();
@@ -94,18 +150,6 @@ static void render_image( void )
     * Make sure buffered commands are finished!!!
     */
    glFinish();
-
-   Frames++;
-   if (perf) {
-     GLint t = glutGet(GLUT_ELAPSED_TIME);
-     if (t - T0 >= 5000) {
-        GLfloat seconds = (t - T0) / 1000.0;
-        GLfloat fps = Frames / seconds;
-        printf("%d frames in %6.3f seconds = %6.3f FPS\n", Frames, seconds, fps);
-        T0 = t;
-        Frames = 0;
-     }
-   }
 }
 
 
@@ -131,10 +175,10 @@ write_targa(const char *filename, const GLubyte *buffer, int width, int height)
       fputc (0x00, f);
       fputc (0x00, f); /* Y-origin of Image    */
       fputc (0x00, f);
-      fputc (WIDTH & 0xff, f);      /* Image Width     */
-      fputc ((WIDTH>>8) & 0xff, f);
-      fputc (HEIGHT & 0xff, f);     /* Image Height    */
-      fputc ((HEIGHT>>8) & 0xff, f);
+      fputc (Width & 0xff, f);      /* Image Width     */
+      fputc ((Width>>8) & 0xff, f);
+      fputc (Height & 0xff, f);     /* Image Height    */
+      fputc ((Height>>8) & 0xff, f);
       fputc (0x18, f);         /* Pixel Depth, 0x18 => 24 Bits */
       fputc (0x20, f);         /* Image Descriptor     */
       fclose(f);
@@ -201,38 +245,46 @@ write_ppm(const char *filename, const GLubyte *buffer, int width, int height)
 
 
 
-int main( int argc, char *argv[] )
+int
+main(int argc, char *argv[])
 {
+   OSMesaContext ctx;
    void *buffer;
-   int i;
    char *filename = NULL;
 
+   if (argc < 2) {
+      fprintf(stderr, "Usage:\n");
+      fprintf(stderr, "  osdemo filename [width height]\n");
+      return 0;
+   }
+
+   filename = argv[1];
+   if (argc == 4) {
+      Width = atoi(argv[2]);
+      Height = atoi(argv[3]);
+   }
+
    /* Create an RGBA-mode context */
 #if OSMESA_MAJOR_VERSION * 100 + OSMESA_MINOR_VERSION >= 305
    /* specify Z, stencil, accum sizes */
-   OSMesaContext ctx = OSMesaCreateContextExt( OSMESA_RGBA, 16, 0, 0, NULL );
+   ctx = OSMesaCreateContextExt( OSMESA_RGBA, 16, 0, 0, NULL );
 #else
-   OSMesaContext ctx = OSMesaCreateContext( OSMESA_RGBA, NULL );
+   ctx = OSMesaCreateContext( OSMESA_RGBA, NULL );
 #endif
    if (!ctx) {
       printf("OSMesaCreateContext failed!\n");
       return 0;
    }
 
-   for ( i=1; i<argc; i++ ) {
-      if (argv[i][0] != '-') filename = argv[i];
-      if (strcmp(argv[i], "-perf")==0) perf = 1;
-   }
-
    /* Allocate the image buffer */
-   buffer = malloc( WIDTH * HEIGHT * 4 * sizeof(GLubyte) );
+   buffer = malloc( Width * Height * 4 * sizeof(GLubyte) );
    if (!buffer) {
       printf("Alloc image buffer failed!\n");
       return 0;
    }
 
    /* Bind the buffer to the context and make it current */
-   if (!OSMesaMakeCurrent( ctx, buffer, GL_UNSIGNED_BYTE, WIDTH, HEIGHT )) {
+   if (!OSMesaMakeCurrent( ctx, buffer, GL_UNSIGNED_BYTE, Width, Height )) {
       printf("OSMesaMakeCurrent failed!\n");
       return 0;
    }
@@ -247,15 +299,12 @@ int main( int argc, char *argv[] )
    }
 
    render_image();
-   if (perf)
-      for(i=0; i< 1000; i++)
-         render_image();
 
    if (filename != NULL) {
 #ifdef SAVE_TARGA
-      write_targa(filename, buffer, WIDTH, HEIGHT);
+      write_targa(filename, buffer, Width, Height);
 #else
-      write_ppm(filename, buffer, WIDTH, HEIGHT);
+      write_ppm(filename, buffer, Width, Height);
 #endif
    }
    else {