This is points.c in view mode; [Download] [Up]
/* $Id: points.c,v 1.2 1996/09/15 14:18:37 brianp Exp $ */
/*
* Mesa 3-D graphics library
* Version: 2.0
* Copyright (C) 1995-1996 Brian Paul
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this library; if not, write to the Free
* Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
/*
* $Log: points.c,v $
* Revision 1.2 1996/09/15 14:18:37 brianp
* now use GLframebuffer and GLvisual
*
* Revision 1.1 1996/09/13 01:38:16 brianp
* Initial revision
*
*/
#include "context.h"
#include "feedback.h"
#include "dlist.h"
#include "macros.h"
#include "pb.h"
#include "span.h"
#include "types.h"
#include "vb.h"
void gl_PointSize( GLcontext *ctx, GLfloat size )
{
if (size<=0.0) {
gl_error( ctx, GL_INVALID_VALUE, "glPointSize" );
return;
}
if (INSIDE_BEGIN_END(ctx)) {
gl_error( ctx, GL_INVALID_OPERATION, "glPointSize" );
return;
}
ctx->Point.Size = size;
ctx->NewState |= NEW_RASTER_OPS;
}
/**********************************************************************/
/***** Rasterization *****/
/**********************************************************************/
/*
* There are 3 pairs (RGBA, CI) of point rendering functions:
* 1. simple: size=1 and no special rasterization functions (fastest)
* 2. size1: size=1 and any rasterization functions
* 3. general: any size and rasterization functions (slowest)
*
* All point rendering functions take the same two arguments: first and
* last which specify that the points specified by VB[first] through
* VB[last] are to be rendered.
*/
/*
* Put points in feedback buffer.
*/
static void feedback_points( GLcontext *ctx, GLuint first, GLuint last )
{
struct vertex_buffer *VB = ctx->VB;
GLuint i;
GLint shift = ctx->ColorShift;
for (i=first;i<=last;i++) {
if (VB->Unclipped[i]) {
GLfloat x, y, z, w, invq;
GLfloat color[4], texcoord[4];
x = VB->Win[i][0];
y = VB->Win[i][1];
z = VB->Win[i][2] / DEPTH_SCALE;
w = VB->Clip[i][3];
/* convert color from integer back to a float in [0,1] */
color[0] = (VB->Color[i][0] >> shift) * ctx->Visual->InvRedScale;
color[1] = (VB->Color[i][1] >> shift) * ctx->Visual->InvGreenScale;
color[2] = (VB->Color[i][2] >> shift) * ctx->Visual->InvBlueScale;
color[3] = (VB->Color[i][3] >> shift) * ctx->Visual->InvAlphaScale;
invq = 1.0F / VB->TexCoord[i][3];
texcoord[0] = VB->TexCoord[i][0] * invq;
texcoord[1] = VB->TexCoord[i][1] * invq;
texcoord[2] = VB->TexCoord[i][2] * invq;
texcoord[3] = VB->TexCoord[i][3];
FEEDBACK_TOKEN( ctx, (GLfloat) GL_POINT_TOKEN );
gl_feedback_vertex( ctx, x, y, z, w, color,
(GLfloat) VB->Index[i], texcoord );
}
}
}
/*
* Put points in selection buffer.
*/
static void select_points( GLcontext *ctx, GLuint first, GLuint last )
{
struct vertex_buffer *VB = ctx->VB;
GLuint i;
for (i=first;i<=last;i++) {
if (VB->Unclipped[i]) {
gl_update_hitflag( ctx, VB->Win[i][2] / DEPTH_SCALE );
}
}
}
/*
* CI points with size == 1.0
*/
void size1_ci_points( GLcontext *ctx, GLuint first, GLuint last )
{
struct vertex_buffer *VB = ctx->VB;
struct pixel_buffer *PB = ctx->PB;
GLfloat *win;
GLint *pbx = PB->x, *pby = PB->y;
GLdepth *pbz = PB->z;
GLuint *pbi = PB->i;
GLuint pbcount = PB->count;
GLuint i;
win = &VB->Win[first][0];
for (i=first;i<=last;i++) {
if (VB->Unclipped[i]) {
pbx[pbcount] = (GLint) win[0];
pby[pbcount] = (GLint) win[1];
pbz[pbcount] = (GLint) (win[2] + ctx->PointZoffset);
pbi[pbcount] = VB->Index[i];
pbcount++;
}
win += 3;
}
PB->count = pbcount;
PB_CHECK_FLUSH(ctx, PB)
}
/*
* RGBA points with size == 1.0
*/
static void size1_rgba_points( GLcontext *ctx, GLuint first, GLuint last )
{
struct vertex_buffer *VB = ctx->VB;
struct pixel_buffer *PB = ctx->PB;
GLuint i;
GLint shift = ctx->ColorShift;
for (i=first;i<=last;i++) {
if (VB->Unclipped[i]) {
GLint x, y, z;
GLint red, green, blue, alpha;
x = (GLint) VB->Win[i][0];
y = (GLint) VB->Win[i][1];
z = (GLint) (VB->Win[i][2] + ctx->PointZoffset);
red = VB->Color[i][0] >> shift;
green = VB->Color[i][1] >> shift;
blue = VB->Color[i][2] >> shift;
alpha = VB->Color[i][3] >> shift;
PB_WRITE_RGBA_PIXEL( PB, x, y, z, red, green, blue, alpha );
}
}
PB_CHECK_FLUSH(ctx,PB)
}
/*
* General CI points.
*/
static void general_ci_points( GLcontext *ctx, GLuint first, GLuint last )
{
struct vertex_buffer *VB = ctx->VB;
struct pixel_buffer *PB = ctx->PB;
GLuint i;
GLint isize;
isize = (GLint) (CLAMP(ctx->Point.Size,MIN_POINT_SIZE,MAX_POINT_SIZE) + 0.5F);
for (i=first;i<=last;i++) {
if (VB->Unclipped[i]) {
GLint x, y, z;
GLint x0, x1, y0, y1;
GLint ix, iy;
x = (GLint) VB->Win[i][0];
y = (GLint) VB->Win[i][1];
z = (GLint) (VB->Win[i][2] + ctx->PointZoffset);
if (isize&1) {
/* odd size */
x0 = x - isize/2;
x1 = x + isize/2;
y0 = y - isize/2;
y1 = y + isize/2;
}
else {
/* even size */
x0 = (GLint) (x + 0.5F) - isize/2;
x1 = x0 + isize-1;
y0 = (GLint) (y + 0.5F) - isize/2;
y1 = y0 + isize-1;
}
PB_SET_INDEX( ctx, PB, VB->Index[i] );
for (iy=y0;iy<=y1;iy++) {
for (ix=x0;ix<=x1;ix++) {
PB_WRITE_PIXEL( PB, ix, iy, z );
}
}
PB_CHECK_FLUSH(ctx,PB)
}
}
}
/*
* General RGBA points.
*/
static void general_rgba_points( GLcontext *ctx, GLuint first, GLuint last )
{
struct vertex_buffer *VB = ctx->VB;
struct pixel_buffer *PB = ctx->PB;
GLuint i;
GLint isize;
GLint shift = ctx->ColorShift;
isize = (GLint) (CLAMP(ctx->Point.Size,MIN_POINT_SIZE,MAX_POINT_SIZE) + 0.5F);
for (i=first;i<=last;i++) {
if (VB->Unclipped[i]) {
GLint x, y, z;
GLint x0, x1, y0, y1;
GLint ix, iy;
x = (GLint) VB->Win[i][0];
y = (GLint) VB->Win[i][1];
z = (GLint) (VB->Win[i][2] + ctx->PointZoffset);
if (isize&1) {
/* odd size */
x0 = x - isize/2;
x1 = x + isize/2;
y0 = y - isize/2;
y1 = y + isize/2;
}
else {
/* even size */
x0 = (GLint) (x + 0.5F) - isize/2;
x1 = x0 + isize-1;
y0 = (GLint) (y + 0.5F) - isize/2;
y1 = y0 + isize-1;
}
PB_SET_COLOR( ctx, PB,
VB->Color[i][0] >> shift,
VB->Color[i][1] >> shift,
VB->Color[i][2] >> shift,
VB->Color[i][3] >> shift );
for (iy=y0;iy<=y1;iy++) {
for (ix=x0;ix<=x1;ix++) {
PB_WRITE_PIXEL( PB, ix, iy, z );
}
}
PB_CHECK_FLUSH(ctx,PB)
}
}
}
/*
* Textured RGBA points.
*/
static void textured_rgba_points( GLcontext *ctx, GLuint first, GLuint last )
{
struct vertex_buffer *VB = ctx->VB;
struct pixel_buffer *PB = ctx->PB;
GLuint i;
GLint shift = ctx->ColorShift;
for (i=first;i<=last;i++) {
if (VB->Unclipped[i]) {
GLint x, y, z;
GLint x0, x1, y0, y1;
GLint ix, iy;
GLint isize;
GLint red, green, blue, alpha;
GLfloat s, t;
x = (GLint) VB->Win[i][0];
y = (GLint) VB->Win[i][1];
z = (GLint) (VB->Win[i][2] + ctx->PointZoffset);
isize = (GLint)
(CLAMP(ctx->Point.Size,MIN_POINT_SIZE,MAX_POINT_SIZE) + 0.5F);
if (isize<1) {
isize = 1;
}
if (isize&1) {
/* odd size */
x0 = x - isize/2;
x1 = x + isize/2;
y0 = y - isize/2;
y1 = y + isize/2;
}
else {
/* even size */
x0 = (GLint) (x + 0.5F) - isize/2;
x1 = x0 + isize-1;
y0 = (GLint) (y + 0.5F) - isize/2;
y1 = y0 + isize-1;
}
red = VB->Color[i][0] >> shift;
green = VB->Color[i][1] >> shift;
blue = VB->Color[i][2] >> shift;
alpha = VB->Color[i][3] >> shift;
s = VB->TexCoord[i][0] / VB->TexCoord[i][3];
t = VB->TexCoord[i][1] / VB->TexCoord[i][3];
/* don't think this is needed
PB_SET_COLOR( red, green, blue, alpha );
*/
for (iy=y0;iy<=y1;iy++) {
for (ix=x0;ix<=x1;ix++) {
PB_WRITE_TEX_PIXEL( PB, ix, iy, z, red, green, blue, alpha, s, t );
}
}
PB_CHECK_FLUSH(ctx,PB)
}
}
}
/*
* Antialiased points with or without texture mapping.
*/
static void antialiased_rgba_points( GLcontext *ctx,
GLuint first, GLuint last )
{
struct vertex_buffer *VB = ctx->VB;
struct pixel_buffer *PB = ctx->PB;
GLuint i;
GLfloat radius, rmin, rmax, rmin2, rmax2, cscale;
GLint shift = ctx->ColorShift;
radius = CLAMP( ctx->Point.Size, MIN_POINT_SIZE, MAX_POINT_SIZE ) * 0.5F;
rmin = radius - 0.7071F; /* 0.7071 = sqrt(2)/2 */
rmax = radius + 0.7071F;
rmin2 = rmin*rmin;
rmax2 = rmax*rmax;
cscale = 256.0F / (rmax2-rmin2);
if (ctx->Texture.Enabled) {
for (i=first;i<=last;i++) {
if (VB->Unclipped[i]) {
GLint xmin, ymin, xmax, ymax;
GLint x, y, z;
GLint red, green, blue, alpha;
GLfloat s, t;
xmin = (GLint) (VB->Win[i][0] - radius);
xmax = (GLint) (VB->Win[i][0] + radius);
ymin = (GLint) (VB->Win[i][1] - radius);
ymax = (GLint) (VB->Win[i][1] + radius);
z = (GLint) (VB->Win[i][2] + ctx->PointZoffset);
red = VB->Color[i][0] >> shift;
green = VB->Color[i][1] >> shift;
blue = VB->Color[i][2] >> shift;
s = VB->TexCoord[i][0] / VB->TexCoord[i][3];
t = VB->TexCoord[i][1] / VB->TexCoord[i][3];
for (y=ymin;y<=ymax;y++) {
for (x=xmin;x<=xmax;x++) {
GLfloat dx = x/*+0.5F*/ - VB->Win[i][0];
GLfloat dy = y/*+0.5F*/ - VB->Win[i][1];
GLfloat dist2 = dx*dx + dy*dy;
if (dist2<rmax2) {
alpha = VB->Color[i][3] >> shift;
if (dist2>=rmin2) {
GLint coverage = (GLint) (256.0F-(dist2-rmin2)*cscale);
/* coverage is in [0,256] */
alpha = (alpha * coverage) >> 8;
}
PB_WRITE_TEX_PIXEL( PB, x,y,z, red, green, blue, alpha, s,t );
}
}
}
PB_CHECK_FLUSH(ctx,PB)
}
}
}
else {
/* Not texture mapped */
for (i=first;i<=last;i++) {
if (VB->Unclipped[i]) {
GLint xmin, ymin, xmax, ymax;
GLint x, y, z;
GLint red, green, blue, alpha;
xmin = (GLint) (VB->Win[i][0] - radius);
xmax = (GLint) (VB->Win[i][0] + radius);
ymin = (GLint) (VB->Win[i][1] - radius);
ymax = (GLint) (VB->Win[i][1] + radius);
z = (GLint) (VB->Win[i][2] + ctx->PointZoffset);
red = VB->Color[i][0] >> shift;
green = VB->Color[i][1] >> shift;
blue = VB->Color[i][2] >> shift;
for (y=ymin;y<=ymax;y++) {
for (x=xmin;x<=xmax;x++) {
GLfloat dx = x/*+0.5F*/ - VB->Win[i][0];
GLfloat dy = y/*+0.5F*/ - VB->Win[i][1];
GLfloat dist2 = dx*dx + dy*dy;
if (dist2<rmax2) {
alpha = VB->Color[i][3] >> shift;
if (dist2>=rmin2) {
GLint coverage = (GLint) (256.0F-(dist2-rmin2)*cscale);
/* coverage is in [0,256] */
alpha = (alpha * coverage) >> 8;
}
PB_WRITE_RGBA_PIXEL( PB, x, y, z, red, green, blue, alpha );
}
}
}
PB_CHECK_FLUSH(ctx,PB)
}
}
}
}
/*
* Examine the current context to determine which point drawing function
* should be used.
*/
void gl_set_point_function( GLcontext *ctx )
{
GLboolean rgbmode = ctx->Visual->RGBAflag;
if (ctx->RenderMode==GL_RENDER) {
if (ctx->Driver.PointsFunc) {
/* Device driver will draw points. */
ctx->PointsFunc = ctx->Driver.PointsFunc;
}
else if (ctx->Point.SmoothFlag && rgbmode) {
ctx->PointsFunc = antialiased_rgba_points;
}
else if (ctx->Texture.Enabled) {
ctx->PointsFunc = textured_rgba_points;
}
else if (ctx->Point.Size==1.0) {
/* size=1, any raster ops */
ctx->PointsFunc = rgbmode ? size1_rgba_points : size1_ci_points;
}
else {
/* every other kind of point rendering */
ctx->PointsFunc = rgbmode ? general_rgba_points
: general_ci_points;
}
}
else if (ctx->RenderMode==GL_FEEDBACK) {
ctx->PointsFunc = feedback_points;
}
else {
/* GL_SELECT mode */
ctx->PointsFunc = select_points;
}
}
These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.