2025-04-27 07:49:33 -04:00

282 lines
7.4 KiB
C

/*
** Copyright 1992, Silicon Graphics, Inc.
** All Rights Reserved.
**
** This is UNPUBLISHED PROPRIETARY SOURCE CODE of Silicon Graphics, Inc.;
** the contents of this file may not be disclosed to third parties, copied or
** duplicated in any form, in whole or in part, without the prior written
** permission of Silicon Graphics, Inc.
**
** RESTRICTED RIGHTS LEGEND:
** Use, duplication or disclosure by the Government is subject to restrictions
** as set forth in subdivision (c)(1)(ii) of the Rights in Technical Data
** and Computer Software clause at DFARS 252.227-7013, and/or in similar or
** successor clauses in the FAR, DOD or NASA FAR Supplement. Unpublished -
** rights reserved under the Copyright Laws of the United States.
*/
#include <windows.h>
#include <GL/gl.h>
#include "conform.h"
#include "util.h"
#include "utilm.h"
static long Compare(GLint x, GLint y, GLint color, GLfloat *buf)
{
long i;
i = WINDSIZEX * y + x;
return AutoColorCompare(buf[i], color);
}
long XFormTestBuf(GLfloat *buf, GLfloat *point, GLint index, GLenum polyMode)
{
GLint i=0, j=0;
switch (polyMode) {
case GL_POINT:
i = (GLint)((1.0 + point[0]) * WINDSIZEX / 2.0);
j = (GLint)((1.0 + point[1]) * WINDSIZEY / 2.0);
break;
case GL_LINE:
i = (GLint)Round((1.0+point[0])*WINDSIZEX/2.0);
j = (GLint)Round((1.0+point[1])*WINDSIZEY/2.0);
break;
case GL_FILL:
i = (GLint)(((1.0 + point[0]) * WINDSIZEX / 2.0) - 0.5);
j = (GLint)(((1.0 + point[1]) * WINDSIZEY / 2.0) - 0.5);
break;
}
/*
** Test the 9 pixels around the target.
*/
if (!(Compare(i-1, j+1, index, buf) ||
Compare(i , j+1, index, buf) ||
Compare(i+1, j+1, index, buf) ||
Compare(i-1, j , index, buf) ||
Compare(i , j , index, buf) ||
Compare(i+1, j , index, buf) ||
Compare(i-1, j-1, index, buf) ||
Compare(i , j-1, index, buf) ||
Compare(i+1, j-1, index, buf))) {
return ERROR;
}
return NO_ERROR;
}
static void Translate(xFormRec *data, GLfloat *in, GLfloat *out)
{
out[0] = in[0] + data->x;
out[1] = in[1] + data->y;
out[2] = in[2] + data->z;
}
static void Scale(xFormRec *data, GLfloat *in, GLfloat *out)
{
out[0] = in[0] * data->x;
out[1] = in[1] * data->y;
out[2] = in[2] * data->z;
}
static void Rotate(xFormRec *data, GLfloat *in, GLfloat *out)
{
float angleCos, angleSin;
float m[3][3], axis[3], len, tmp[3];
angleCos = COS(data->angle*PI/180.0);
angleSin = SIN(data->angle*PI/180.0);
len = data->x * data->x + data->y * data->y + data->z * data->z;
len = SQRT(len);
axis[0] = data->x / len;
axis[1] = data->y / len;
axis[2] = data->z / len;
m[0][0] = axis[0] * axis[0] * (1.0 - angleCos) + angleCos;
m[0][1] = axis[0] * axis[1] * (1.0 - angleCos) - angleSin * axis[2];
m[0][2] = axis[0] * axis[2] * (1.0 - angleCos) + angleSin * axis[1];
m[1][0] = axis[1] * axis[0] * (1.0 - angleCos) + angleSin * axis[2];
m[1][1] = axis[1] * axis[1] * (1.0 - angleCos) + angleCos;
m[1][2] = axis[1] * axis[2] * (1.0 - angleCos) - angleSin * axis[0];
m[2][0] = axis[2] * axis[0] * (1.0 - angleCos) - angleSin * axis[1];
m[2][1] = axis[2] * axis[1] * (1.0 - angleCos) + angleSin * axis[0];
m[2][2] = axis[2] * axis[2] * (1.0 - angleCos) + angleCos;
tmp[0] = m[0][0] * in[0] + m[0][1] * in[1] + m[0][2] * in[2];
tmp[1] = m[1][0] * in[0] + m[1][1] * in[1] + m[1][2] * in[2];
tmp[2] = m[2][0] * in[0] + m[2][1] * in[1] + m[2][2] * in[2];
out[0] = tmp[0];
out[1] = tmp[1];
out[2] = tmp[2];
}
static void Ortho(xFormRec *data, GLfloat *in, GLfloat *out)
{
out[0] = in[0] * (GLfloat)(2.0 / data->d1);
out[1] = in[1] * (GLfloat)(2.0 / data->d2);
out[2] = in[2] * (GLfloat)(-2.0 / data->d3);
}
void XFormCalcTrue(long type, xFormRec *data, GLfloat *in, GLfloat *out)
{
switch (type) {
case XFORM_TRANSLATE:
Translate(data, in, out);
break;
case XFORM_SCALE:
Scale(data, in, out);
break;
case XFORM_ROTATE:
Rotate(data, in, out);
break;
case XFORM_ORTHO:
Ortho(data, in, out);
break;
}
}
void XFormCalcGL(long type, xFormRec *data)
{
switch (type) {
case XFORM_TRANSLATE:
glTranslatef(data->x, data->y, data->z);
break;
case XFORM_SCALE:
glScalef(data->x, data->y, data->z);
break;
case XFORM_ROTATE:
glRotatef(data->angle, data->x, data->y, data->z);
break;
case XFORM_ORTHO:
glOrtho(-data->d1/2.0, data->d1/2.0, -data->d2/2.0, data->d2/2.0,
-data->d3/2.0, data->d3/2.0);
break;
case XFORM_FRUSTUM:
glFrustum(data->d1, data->d2, data->d3, data->d4, data->d5, data->d6);
break;
}
}
void XFormMake(long *type, xFormRec *data)
{
*type = Random(XFORM_TRANSLATE, XFORM_ROTATE+0.9);
switch (*type) {
case XFORM_TRANSLATE:
data->x = Random(-0.75, 0.75);
data->y = Random(-0.75, 0.75);
data->z = 0.0;
break;
case XFORM_SCALE:
data->x = Random(-4.0, 4.0);
data->y = Random(-4.0, 4.0);
data->z = 1.0;
break;
case XFORM_ROTATE:
data->x = Random(-2.0, 2.0);
data->y = Random(-2.0, 2.0);
data->z = Random(-2.0, 2.0);
data->angle = Random(-180.0, 180.0);
break;
}
}
void XFormMakeMatrix(long type, xFormRec *data, GLfloat *matrix)
{
GLfloat sine, cosine;
MakeIdentMatrix(matrix);
/*
** Note - LoadMatrix takes matrices in COLUMN major order.
** These matrices will be expressed as ROW major, so the numbers
** will appear transposed.
*/
switch (type) {
case XFORM_TRANSLATE:
matrix[12] = data->x;
matrix[13] = data->y;
matrix[14] = data->z;
break;
case XFORM_SCALE:
matrix[0] = data->x;
matrix[5] = data->y;
matrix[10] = data->z;
break;
case XFORM_ROTATE:
/*
** Doing only rotations around z-axis.
*/
cosine = COS(data->angle*PI/180.0);
sine = SIN(data->angle*PI/180.0);
matrix[0] = cosine;
matrix[1] = sine;
matrix[4] = -sine;
matrix[5] = cosine;
break;
case XFORM_ORTHO:
matrix[0] = (GLfloat)(2.0 / data->d1);
matrix[5] = (GLfloat)(2.0 / data->d2);
matrix[10] = (GLfloat)(-2.0 / data->d3);
break;
case XFORM_FRUSTUM:
matrix[0] = (GLfloat)((2.0 * data->d5) / (data->d2 - data->d1));
matrix[5] = (GLfloat)((2.0 * data->d5) / (data->d4 - data->d3));
matrix[10] = (GLfloat)(-(data->d6 + data->d5) / (data->d6 - data->d5));
matrix[8] = (GLfloat)((data->d2 + data->d1) / (data->d2 - data->d1));
matrix[9] = (GLfloat)((data->d4 + data->d3) / (data->d4 - data->d3));
matrix[14] = (GLfloat)(-(2.0 * data->d5 * data->d6) / (data->d6 -
data->d5));
matrix[11] = -1.0;
matrix[15] = 0.0;
break;
}
return;
}
long XFormValid(long type, xFormRec *data)
{
switch (type) {
case XFORM_TRANSLATE:
return NO_ERROR;
case XFORM_SCALE:
if (data->x * data->y * data->z == 0.0) {
return ERROR;
} else {
return NO_ERROR;
}
break;
case XFORM_ROTATE:
if ((data->x*data->x+data->y*data->y+data->z*data->z) == 0.0) {
return ERROR;
} else {
return NO_ERROR;
}
}
return NO_ERROR;
}
long XFormCompareMatrix(GLfloat *m1, GLfloat *m2)
{
long i;
for (i = 0; i < 16; i++) {
if (ABS(m1[i]-m2[i]) > epsilon.zero) {
return ERROR;
}
}
return NO_ERROR;
}