home *** CD-ROM | disk | FTP | other *** search
/ Magazyn Amiga 5 / MA_Cover_5.iso / ppc / mesa / src / misc.c < prev    next >
Encoding:
C/C++ Source or Header  |  1998-01-31  |  13.1 KB  |  476 lines

  1. /* $Id: misc.c,v 1.21 1997/10/29 01:29:09 brianp Exp $ */
  2.  
  3. /*
  4.  * Mesa 3-D graphics library
  5.  * Version:  2.5
  6.  * Copyright (C) 1995-1997  Brian Paul
  7.  *
  8.  * This library is free software; you can redistribute it and/or
  9.  * modify it under the terms of the GNU Library General Public
  10.  * License as published by the Free Software Foundation; either
  11.  * version 2 of the License, or (at your option) any later version.
  12.  *
  13.  * This library 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 GNU
  16.  * Library General Public License for more details.
  17.  *
  18.  * You should have received a copy of the GNU Library General Public
  19.  * License along with this library; if not, write to the Free
  20.  * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  21.  */
  22.  
  23.  
  24. /*
  25.  * $Log: misc.c,v $
  26.  * Revision 1.21  1997/10/29 01:29:09  brianp
  27.  * added GL_EXT_point_parameters extension from Daniel Barrero
  28.  *
  29.  * Revision 1.20  1997/10/16 02:32:19  brianp
  30.  * added GL_EXT_shared_texture_palette extension
  31.  *
  32.  * Revision 1.19  1997/10/14 00:17:48  brianp
  33.  * added 3DFX_set_global_palette to extension string for 3Dfx
  34.  *
  35.  * Revision 1.18  1997/09/27 00:13:44  brianp
  36.  * added GL_EXT_paletted_texture extension
  37.  *
  38.  * Revision 1.17  1997/08/13 01:26:40  brianp
  39.  * changed version string to 2.4
  40.  *
  41.  * Revision 1.16  1997/07/24 01:23:16  brianp
  42.  * changed precompiled header symbol from PCH to PC_HEADER
  43.  *
  44.  * Revision 1.15  1997/06/20 02:21:36  brianp
  45.  * don't clear buffers if RenderMode != GL_RENDER
  46.  *
  47.  * Revision 1.14  1997/05/28 03:25:43  brianp
  48.  * added precompiled header (PCH) support
  49.  *
  50.  * Revision 1.13  1997/04/12 12:31:18  brianp
  51.  * removed gl_Rectf()
  52.  *
  53.  * Revision 1.12  1997/03/21 01:58:54  brianp
  54.  * now call Driver.RendererString() in gl_GetString()
  55.  *
  56.  * Revision 1.11  1997/02/10 20:40:51  brianp
  57.  * added GL_MESA_resize_buffers to extensions string
  58.  *
  59.  * Revision 1.10  1997/02/09 18:44:35  brianp
  60.  * added GL_EXT_texture3D support
  61.  *
  62.  * Revision 1.9  1997/01/08 20:55:02  brianp
  63.  * added GL_EXT_texture_object
  64.  *
  65.  * Revision 1.8  1996/11/05 01:41:45  brianp
  66.  * fixed potential scissor/clear color buffer bug
  67.  *
  68.  * Revision 1.7  1996/10/30 03:14:02  brianp
  69.  * incremented version to 2.1
  70.  *
  71.  * Revision 1.6  1996/10/11 03:42:17  brianp
  72.  * added GL_EXT_polygon_offset to extensions string
  73.  *
  74.  * Revision 1.5  1996/10/02 02:51:44  brianp
  75.  * created clear_color_buffers() which handles draw mode GL_FRONT_AND_BACK
  76.  *
  77.  * Revision 1.4  1996/09/25 03:22:14  brianp
  78.  * glDrawBuffer(GL_NONE) works now
  79.  *
  80.  * Revision 1.3  1996/09/24 00:16:10  brianp
  81.  * set NewState flag in glRead/DrawBuffer() and glHint()
  82.  * fixed display list bug in gl_Hint()
  83.  *
  84.  * Revision 1.2  1996/09/15 14:18:37  brianp
  85.  * now use GLframebuffer and GLvisual
  86.  *
  87.  * Revision 1.1  1996/09/13 01:38:16  brianp
  88.  * Initial revision
  89.  *
  90.  */
  91.  
  92.  
  93. #ifdef PC_HEADER
  94. #include "all.h"
  95. #else
  96. #include <stdlib.h>
  97. #include <string.h>
  98. #include "accum.h"
  99. #include "alphabuf.h"
  100. #include "context.h"
  101. #include "depth.h"
  102. #include "macros.h"
  103. #include "masking.h"
  104. #include "misc.h"
  105. #include "stencil.h"
  106. #include "types.h"
  107. #endif
  108.  
  109.  
  110.  
  111. void gl_ClearIndex( GLcontext *ctx, GLfloat c )
  112. {
  113.    if (INSIDE_BEGIN_END(ctx)) {
  114.       gl_error( ctx, GL_INVALID_OPERATION, "glClearIndex" );
  115.       return;
  116.    }
  117.    ctx->Color.ClearIndex = (GLuint) c;
  118.    if (!ctx->Visual->RGBAflag) {
  119.       /* it's OK to call glClearIndex in RGBA mode but it should be a NOP */
  120.       (*ctx->Driver.ClearIndex)( ctx, ctx->Color.ClearIndex );
  121.    }
  122. }
  123.  
  124.  
  125.  
  126. void gl_ClearColor( GLcontext *ctx, GLclampf red, GLclampf green,
  127.             GLclampf blue, GLclampf alpha )
  128. {
  129.    if (INSIDE_BEGIN_END(ctx)) {
  130.       gl_error( ctx, GL_INVALID_OPERATION, "glClearColor" );
  131.       return;
  132.    }
  133.  
  134.    ctx->Color.ClearColor[0] = CLAMP( red,   0.0F, 1.0F );
  135.    ctx->Color.ClearColor[1] = CLAMP( green, 0.0F, 1.0F );
  136.    ctx->Color.ClearColor[2] = CLAMP( blue,  0.0F, 1.0F );
  137.    ctx->Color.ClearColor[3] = CLAMP( alpha, 0.0F, 1.0F );
  138.  
  139.    if (ctx->Visual->RGBAflag) {
  140.       GLubyte r = (GLint) (ctx->Color.ClearColor[0] * ctx->Visual->RedScale);
  141.       GLubyte g = (GLint) (ctx->Color.ClearColor[1] * ctx->Visual->GreenScale);
  142.       GLubyte b = (GLint) (ctx->Color.ClearColor[2] * ctx->Visual->BlueScale);
  143.       GLubyte a = (GLint) (ctx->Color.ClearColor[3] * ctx->Visual->AlphaScale);
  144.       (*ctx->Driver.ClearColor)( ctx, r, g, b, a );
  145.    }
  146. }
  147.  
  148.  
  149.  
  150.  
  151. /*
  152.  * Clear the color buffer when glColorMask or glIndexMask is in effect.
  153.  */
  154. static void clear_color_buffer_with_masking( GLcontext *ctx )
  155. {
  156.    GLint x, y, height, width;
  157.  
  158.    /* Compute region to clear */
  159.    if (ctx->Scissor.Enabled) {
  160.       x = ctx->Buffer->Xmin;
  161.       y = ctx->Buffer->Ymin;
  162.       height = ctx->Buffer->Ymax - ctx->Buffer->Ymin + 1;
  163.       width  = ctx->Buffer->Xmax - ctx->Buffer->Xmin + 1;
  164.    }
  165.    else {
  166.       x = 0;
  167.       y = 0;
  168.       height = ctx->Buffer->Height;
  169.       width  = ctx->Buffer->Width;
  170.    }
  171.  
  172.    if (ctx->Visual->RGBAflag) {
  173.       /* RGBA mode */
  174.       GLubyte red[MAX_WIDTH], green[MAX_WIDTH];
  175.       GLubyte blue[MAX_WIDTH], alpha[MAX_WIDTH];
  176.       GLubyte r = ctx->Color.ClearColor[0] * ctx->Visual->RedScale;
  177.       GLubyte g = ctx->Color.ClearColor[1] * ctx->Visual->GreenScale;
  178.       GLubyte b = ctx->Color.ClearColor[2] * ctx->Visual->BlueScale;
  179.       GLubyte a = ctx->Color.ClearColor[3] * ctx->Visual->AlphaScale;
  180.       GLint i;
  181.       for (i=0;i<height;i++,y++) {
  182.      MEMSET( red,   (int) r, width );
  183.      MEMSET( green, (int) g, width );
  184.      MEMSET( blue,  (int) b, width );
  185.      MEMSET( alpha, (int) a, width );
  186.      gl_mask_color_span( ctx, width, x, y, red, green, blue, alpha );
  187.      (*ctx->Driver.WriteColorSpan)( ctx,
  188.                  width, x, y, red, green, blue, alpha, NULL );
  189.      if (ctx->RasterMask & ALPHABUF_BIT) {
  190.         gl_write_alpha_span( ctx, width, x, y, alpha, NULL );
  191.      }
  192.       }
  193.    }
  194.    else {
  195.       /* Color index mode */
  196.       GLuint indx[MAX_WIDTH];
  197.       GLubyte mask[MAX_WIDTH];
  198.       GLint i, j;
  199.       MEMSET( mask, 1, width );
  200.       for (i=0;i<height;i++,y++) {
  201.      for (j=0;j<width;j++) {
  202.         indx[j] = ctx->Color.ClearIndex;
  203.      }
  204.      gl_mask_index_span( ctx, width, x, y, indx );
  205.      (*ctx->Driver.WriteIndexSpan)( ctx, width, x, y, indx, mask );
  206.       }
  207.    }
  208. }
  209.  
  210.  
  211.  
  212. /*
  213.  * Clear the front and/or back color buffers.  Also clear the alpha
  214.  * buffer(s) if present.
  215.  */
  216. static void clear_color_buffers( GLcontext *ctx )
  217. {
  218.    if (ctx->Color.SWmasking) {
  219.       clear_color_buffer_with_masking( ctx );
  220.    }
  221.    else {
  222.       GLint x = ctx->Buffer->Xmin;
  223.       GLint y = ctx->Buffer->Ymin;
  224.       GLint height = ctx->Buffer->Ymax - ctx->Buffer->Ymin + 1;
  225.       GLint width  = ctx->Buffer->Xmax - ctx->Buffer->Xmin + 1;
  226.       (*ctx->Driver.Clear)( ctx, !ctx->Scissor.Enabled,
  227.                 x, y, width, height );
  228.       if (ctx->RasterMask & ALPHABUF_BIT) {
  229.      /* front and/or back alpha buffers will be cleared here */
  230.      gl_clear_alpha_buffers( ctx );
  231.       }
  232.    }
  233.  
  234.    if (ctx->RasterMask & FRONT_AND_BACK_BIT) {
  235.       /*** Also clear the back buffer ***/
  236.       (*ctx->Driver.SetBuffer)( ctx, GL_BACK );
  237.       if (ctx->Color.SWmasking) {
  238.      clear_color_buffer_with_masking( ctx );
  239.       }
  240.       else {
  241.      GLint x = ctx->Buffer->Xmin;
  242.      GLint y = ctx->Buffer->Ymin;
  243.      GLint height = ctx->Buffer->Ymax - ctx->Buffer->Ymin + 1;
  244.      GLint width  = ctx->Buffer->Xmax - ctx->Buffer->Xmin + 1;
  245.      (*ctx->Driver.Clear)( ctx, !ctx->Scissor.Enabled,
  246.                    x, y, width, height );
  247.       }
  248.       (*ctx->Driver.SetBuffer)( ctx, GL_FRONT );
  249.    }
  250. }
  251.  
  252.  
  253.  
  254. void gl_Clear( GLcontext *ctx, GLbitfield mask )
  255. {
  256. #ifdef PROFILE
  257.    GLdouble t0 = gl_time();
  258. #endif
  259.  
  260.    if (INSIDE_BEGIN_END(ctx)) {
  261.       gl_error( ctx, GL_INVALID_OPERATION, "glClear" );
  262.       return;
  263.    }
  264.  
  265.    if (ctx->RenderMode==GL_RENDER) {
  266.       if (ctx->NewState) {
  267.      gl_update_state( ctx );
  268.       }
  269.  
  270.       if (mask & GL_COLOR_BUFFER_BIT)   clear_color_buffers( ctx );
  271.       if (mask & GL_DEPTH_BUFFER_BIT)   (*ctx->Driver.ClearDepthBuffer)( ctx );
  272.       if (mask & GL_ACCUM_BUFFER_BIT)   gl_clear_accum_buffer( ctx );
  273.       if (mask & GL_STENCIL_BUFFER_BIT) gl_clear_stencil_buffer( ctx );
  274.  
  275. #ifdef PROFILE
  276.       ctx->ClearTime += gl_time() - t0;
  277.       ctx->ClearCount++;
  278. #endif
  279.    }
  280. }
  281.  
  282.  
  283.  
  284. const GLubyte *gl_GetString( GLcontext *ctx, GLenum name )
  285. {
  286.    static char renderer[1000];
  287.    static char *vendor = "Brian Paul";
  288.    static char *version = "1.1 Mesa 2.5";
  289. #ifdef FX
  290.    static char *extensions = "GL_EXT_blend_color GL_EXT_blend_minmax GL_EXT_blend_logic_op GL_EXT_blend_subtract GL_EXT_paletted_texture GL_EXT_point_parameters GL_EXT_polygon_offset GL_EXT_vertex_array GL_EXT_texture_object GL_EXT_texture3D GL_MESA_window_pos GL_MESA_resize_buffers GL_EXT_shared_texture_palette 3DFX_set_global_palette";
  291. #else
  292.    static char *extensions = "GL_EXT_blend_color GL_EXT_blend_minmax GL_EXT_blend_logic_op GL_EXT_blend_subtract GL_EXT_paletted_texture GL_EXT_point_parameters GL_EXT_polygon_offset GL_EXT_vertex_array GL_EXT_texture_object GL_EXT_texture3D GL_MESA_window_pos GL_MESA_resize_buffers GL_EXT_shared_texture_palette";
  293. #endif
  294.  
  295.    if (INSIDE_BEGIN_END(ctx)) {
  296.       gl_error( ctx, GL_INVALID_OPERATION, "glGetString" );
  297.       return (GLubyte *) 0;
  298.    }
  299.  
  300.    switch (name) {
  301.       case GL_VENDOR:
  302.      return (GLubyte *) vendor;
  303.       case GL_RENDERER:
  304.      strcpy(renderer, "Mesa");
  305.      if (ctx->Driver.RendererString) {
  306.         strcat(renderer, " ");
  307.         strcat(renderer, (*ctx->Driver.RendererString)());
  308.      }
  309.      return (GLubyte *) renderer;
  310.       case GL_VERSION:
  311.      return (GLubyte *) version;
  312.       case GL_EXTENSIONS:
  313.      return (GLubyte *) extensions;
  314.       default:
  315.      gl_error( ctx, GL_INVALID_ENUM, "glGetString" );
  316.      return (GLubyte *) 0;
  317.    }
  318. }
  319.  
  320.  
  321.  
  322. void gl_Finish( GLcontext *ctx )
  323. {
  324.    /* Don't compile into display list */
  325.    if (INSIDE_BEGIN_END(ctx)) {
  326.       gl_error( ctx, GL_INVALID_OPERATION, "glFinish" );
  327.       return;
  328.    }
  329.    if (ctx->Driver.Finish) {
  330.       (*ctx->Driver.Finish)( ctx );
  331.    }
  332. }
  333.  
  334.  
  335.  
  336. void gl_Flush( GLcontext *ctx )
  337. {
  338.    /* Don't compile into display list */
  339.    if (INSIDE_BEGIN_END(ctx)) {
  340.       gl_error( ctx, GL_INVALID_OPERATION, "glFlush" );
  341.       return;
  342.    }
  343.    if (ctx->Driver.Flush) {
  344.       (*ctx->Driver.Flush)( ctx );
  345.    }
  346. }
  347.  
  348.  
  349.  
  350. void gl_Hint( GLcontext *ctx, GLenum target, GLenum mode )
  351. {
  352.    if (INSIDE_BEGIN_END(ctx)) {
  353.       gl_error( ctx, GL_INVALID_OPERATION, "glHint" );
  354.       return;
  355.    }
  356.    if (mode!=GL_DONT_CARE && mode!=GL_FASTEST && mode!=GL_NICEST) {
  357.       gl_error( ctx, GL_INVALID_ENUM, "glHint(mode)" );
  358.       return;
  359.    }
  360.    switch (target) {
  361.       case GL_FOG_HINT:
  362.      ctx->Hint.Fog = mode;
  363.      break;
  364.       case GL_LINE_SMOOTH_HINT:
  365.      ctx->Hint.LineSmooth = mode;
  366.      break;
  367.       case GL_PERSPECTIVE_CORRECTION_HINT:
  368.      ctx->Hint.PerspectiveCorrection = mode;
  369.      break;
  370.       case GL_POINT_SMOOTH_HINT:
  371.      ctx->Hint.PointSmooth = mode;
  372.      break;
  373.       case GL_POLYGON_SMOOTH_HINT:
  374.      ctx->Hint.PolygonSmooth = mode;
  375.      break;
  376.       default:
  377.      gl_error( ctx, GL_INVALID_ENUM, "glHint(target)" );
  378.    }
  379.    ctx->NewState |= NEW_ALL;   /* just to be safe */
  380.    {
  381.     int i;
  382.     i++;
  383.    }
  384. }
  385.  
  386.  
  387.  
  388. void gl_DrawBuffer( GLcontext *ctx, GLenum mode )
  389. {
  390.    if (INSIDE_BEGIN_END(ctx)) {
  391.       gl_error( ctx, GL_INVALID_OPERATION, "glDrawBuffer" );
  392.       return;
  393.    }
  394.    switch (mode) {
  395.       case GL_FRONT:
  396.       case GL_FRONT_LEFT:
  397.       case GL_FRONT_AND_BACK:
  398.      if ( (*ctx->Driver.SetBuffer)( ctx, GL_FRONT ) == GL_FALSE ) {
  399.         gl_error( ctx, GL_INVALID_ENUM, "glDrawBuffer" );
  400.         return;
  401.      }
  402.      ctx->Color.DrawBuffer = mode;
  403.      ctx->Buffer->Alpha = ctx->Buffer->FrontAlpha;
  404.      ctx->NewState |= NEW_RASTER_OPS;
  405.      break;
  406.       case GL_BACK:
  407.       case GL_BACK_LEFT:
  408.      if ( (*ctx->Driver.SetBuffer)( ctx, GL_BACK ) == GL_FALSE) {
  409.         gl_error( ctx, GL_INVALID_ENUM, "glDrawBuffer" );
  410.         return;
  411.      }
  412.      ctx->Color.DrawBuffer = mode;
  413.      ctx->Buffer->Alpha = ctx->Buffer->BackAlpha;
  414.      ctx->NewState |= NEW_RASTER_OPS;
  415.      break;
  416.       case GL_NONE:
  417.      ctx->Color.DrawBuffer = mode;
  418.      ctx->Buffer->Alpha = NULL;
  419.      ctx->NewState |= NEW_RASTER_OPS;
  420.      break;
  421.       case GL_FRONT_RIGHT:
  422.       case GL_BACK_RIGHT:
  423.       case GL_LEFT:
  424.       case GL_RIGHT:
  425.       case GL_AUX0:
  426.      gl_error( ctx, GL_INVALID_OPERATION, "glDrawBuffer" );
  427.      break;
  428.       default:
  429.      gl_error( ctx, GL_INVALID_ENUM, "glDrawBuffer" );
  430.    }
  431. }
  432.  
  433.  
  434.  
  435. void gl_ReadBuffer( GLcontext *ctx, GLenum mode )
  436. {
  437.    if (INSIDE_BEGIN_END(ctx)) {
  438.       gl_error( ctx, GL_INVALID_OPERATION, "glReadBuffer" );
  439.       return;
  440.    }
  441.    switch (mode) {
  442.       case GL_FRONT:
  443.       case GL_FRONT_LEFT:
  444.      if ( (*ctx->Driver.SetBuffer)( ctx, GL_FRONT ) == GL_FALSE) {
  445.         gl_error( ctx, GL_INVALID_ENUM, "glReadBuffer" );
  446.         return;
  447.      }
  448.      ctx->Pixel.ReadBuffer = mode;
  449.      ctx->Buffer->Alpha = ctx->Buffer->FrontAlpha;
  450.      ctx->NewState |= NEW_RASTER_OPS;
  451.      break;
  452.       case GL_BACK:
  453.       case GL_BACK_LEFT:
  454.      if ( (*ctx->Driver.SetBuffer)( ctx, GL_BACK ) == GL_FALSE) {
  455.         gl_error( ctx, GL_INVALID_ENUM, "glReadBuffer" );
  456.         return;
  457.      }
  458.      ctx->Pixel.ReadBuffer = mode;
  459.      ctx->Buffer->Alpha = ctx->Buffer->BackAlpha;
  460.      ctx->NewState |= NEW_RASTER_OPS;
  461.      break;
  462.       case GL_FRONT_RIGHT:
  463.       case GL_BACK_RIGHT:
  464.       case GL_LEFT:
  465.       case GL_RIGHT:
  466.       case GL_AUX0:
  467.      gl_error( ctx, GL_INVALID_OPERATION, "glReadBuffer" );
  468.      break;
  469.       default:
  470.      gl_error( ctx, GL_INVALID_ENUM, "glReadBuffer" );
  471.    }
  472.  
  473.    /* Remember, the draw buffer is the default state */
  474.    (void) (*ctx->Driver.SetBuffer)( ctx, ctx->Color.DrawBuffer );
  475. }
  476.