TINYGL: Started replacing the old classes with the new ones.

TINYGL: Removed all the use of the old classes of Vector and Matrix.
This commit is contained in:
Stefano Musumeci 2014-05-28 19:27:00 +01:00
parent f7343ec6ab
commit c1040a9cdf
11 changed files with 357 additions and 616 deletions

View File

@ -25,18 +25,18 @@ void glopArrayElement(GLContext *c, GLParam *param) {
}
if (states & NORMAL_ARRAY) {
i = idx * (3 + c->normal_array_stride);
c->current_normal.X = c->normal_array[i];
c->current_normal.Y = c->normal_array[i + 1];
c->current_normal.Z = c->normal_array[i + 2];
c->current_normal.W = 0.0f;
c->current_normal.setX(c->normal_array[i]);
c->current_normal.setY(c->normal_array[i + 1]);
c->current_normal.setZ(c->normal_array[i + 2]);
c->current_normal.setW(0.0f); // NOTE: this used to be Z but assigning Z again seemed like a bug...
}
if (states & TEXCOORD_ARRAY) {
int size = c->texcoord_array_size;
i = idx * (size + c->texcoord_array_stride);
c->current_tex_coord.X = c->texcoord_array[i];
c->current_tex_coord.Y = c->texcoord_array[i + 1];
c->current_tex_coord.Z = size > 2 ? c->texcoord_array[i + 2] : 0.0f;
c->current_tex_coord.W = size > 3 ? c->texcoord_array[i + 3] : 1.0f;
c->current_tex_coord.setX(c->texcoord_array[i]);
c->current_tex_coord.setY(c->texcoord_array[i + 1]);
c->current_tex_coord.setZ(size > 2 ? c->texcoord_array[i + 2] : 0.0f);
c->current_tex_coord.setW(size > 3 ? c->texcoord_array[i + 3] : 1.0f);
}
if (states & VERTEX_ARRAY) {
GLParam p[5];

View File

@ -4,10 +4,7 @@
namespace TinyGL {
void glopClearColor(GLContext *c, GLParam *p) {
c->clear_color.v[0] = p[1].f;
c->clear_color.v[1] = p[2].f;
c->clear_color.v[2] = p[3].f;
c->clear_color.v[3] = p[4].f;
c->clear_color = Vector4(p[1].f,p[2].f,p[3].f,p[4].f);
}
void glopClearDepth(GLContext *c, GLParam *p) {
@ -17,9 +14,9 @@ void glopClearDepth(GLContext *c, GLParam *p) {
void glopClear(GLContext *c, GLParam *p) {
int mask = p[1].i;
int z = 0;
int r = (int)(c->clear_color.v[0] * 65535);
int g = (int)(c->clear_color.v[1] * 65535);
int b = (int)(c->clear_color.v[2] * 65535);
int r = (int)(c->clear_color.getX() * 65535);
int g = (int)(c->clear_color.getY() * 65535);
int b = (int)(c->clear_color.getZ() * 65535);
// TODO : correct value of Z
ZB_clear(c->zb, mask & TGL_DEPTH_BUFFER_BIT, z, mask & TGL_COLOR_BUFFER_BIT, r, g, b);

View File

@ -17,17 +17,17 @@ void gl_transform_to_viewport(GLContext *c, GLVertex *v) {
float winv;
// coordinates
winv = (float)(1.0 / v->pc.W);
v->zp.x = (int)(v->pc.X * winv * c->viewport.scale.X + c->viewport.trans.X);
v->zp.y = (int)(v->pc.Y * winv * c->viewport.scale.Y + c->viewport.trans.Y);
v->zp.z = (int)(v->pc.Z * winv * c->viewport.scale.Z + c->viewport.trans.Z);
winv = (float)(1.0 / v->pc.getW());
v->zp.x = (int)(v->pc.getX() * winv * c->viewport.scale.getX() + c->viewport.trans.getX());
v->zp.y = (int)(v->pc.getY() * winv * c->viewport.scale.getY() + c->viewport.trans.getY());
v->zp.z = (int)(v->pc.getZ() * winv * c->viewport.scale.getZ() + c->viewport.trans.getZ());
// color
if (c->lighting_enabled) {
v->zp.r = (int)(v->color.v[0] * (ZB_POINT_RED_MAX - ZB_POINT_RED_MIN)
v->zp.r = (int)(v->color.getX() * (ZB_POINT_RED_MAX - ZB_POINT_RED_MIN)
+ ZB_POINT_RED_MIN);
v->zp.g = (int)(v->color.v[1] * (ZB_POINT_GREEN_MAX - ZB_POINT_GREEN_MIN)
v->zp.g = (int)(v->color.getY() * (ZB_POINT_GREEN_MAX - ZB_POINT_GREEN_MIN)
+ ZB_POINT_GREEN_MIN);
v->zp.b = (int)(v->color.v[2] * (ZB_POINT_BLUE_MAX - ZB_POINT_BLUE_MIN)
v->zp.b = (int)(v->color.getZ() * (ZB_POINT_BLUE_MAX - ZB_POINT_BLUE_MIN)
+ ZB_POINT_BLUE_MIN);
} else {
// no need to convert to integer if no lighting : take current color
@ -38,8 +38,8 @@ void gl_transform_to_viewport(GLContext *c, GLVertex *v) {
// texture
if (c->texture_2d_enabled) {
v->zp.s = (int)(v->tex_coord.X * (ZB_POINT_S_MAX - ZB_POINT_S_MIN) + ZB_POINT_S_MIN);
v->zp.t = (int)(v->tex_coord.Y * (ZB_POINT_S_MAX - ZB_POINT_S_MIN) + ZB_POINT_S_MIN);
v->zp.s = (int)(v->tex_coord.getX() * (ZB_POINT_S_MAX - ZB_POINT_S_MIN) + ZB_POINT_S_MIN);
v->zp.t = (int)(v->tex_coord.getY() * (ZB_POINT_S_MAX - ZB_POINT_S_MIN) + ZB_POINT_S_MIN);
}
}
@ -74,14 +74,9 @@ void gl_draw_point(GLContext *c, GLVertex *p0) {
// line
static inline void interpolate(GLVertex *q, GLVertex *p0, GLVertex *p1, float t) {
q->pc.X = p0->pc.X + (p1->pc.X - p0->pc.X) * t;
q->pc.Y = p0->pc.Y + (p1->pc.Y - p0->pc.Y) * t;
q->pc.Z = p0->pc.Z + (p1->pc.Z - p0->pc.Z) * t;
q->pc.W = p0->pc.W + (p1->pc.W - p0->pc.W) * t;
q->color.v[0] = p0->color.v[0] + (p1->color.v[0] - p0->color.v[0]) * t;
q->color.v[1] = p0->color.v[1] + (p1->color.v[1] - p0->color.v[1]) * t;
q->color.v[2] = p0->color.v[2] + (p1->color.v[2] - p0->color.v[2]) * t;
q->pc = p0->pc + (p1->pc - p0->pc) * t;
q->color = p0->color + (p1->color - p0->color) * t;
}
// Line Clipping
@ -130,14 +125,14 @@ void gl_draw_line(GLContext *c, GLVertex *p1, GLVertex *p2) {
} else if ((cc1 & cc2) != 0) {
return;
} else {
dx = p2->pc.X - p1->pc.X;
dy = p2->pc.Y - p1->pc.Y;
dz = p2->pc.Z - p1->pc.Z;
dw = p2->pc.W - p1->pc.W;
x1 = p1->pc.X;
y1 = p1->pc.Y;
z1 = p1->pc.Z;
w1 = p1->pc.W;
dx = p2->pc.getX() - p1->pc.getX();
dy = p2->pc.getY() - p1->pc.getY();
dz = p2->pc.getZ() - p1->pc.getZ();
dw = p2->pc.getW() - p1->pc.getW();
x1 = p1->pc.getX();
y1 = p1->pc.getY();
z1 = p1->pc.getZ();
w1 = p1->pc.getW();
tmin = 0;
tmax = 1;
@ -169,21 +164,21 @@ void gl_draw_line(GLContext *c, GLVertex *p1, GLVertex *p2) {
// of the intersection if x=a+t(b-a).
#define clip_func(name, sign, dir, dir1, dir2) \
static float name(V4 *c, V4 *a, V4 *b) { \
static float name(Vector4 *c, Vector4 *a, Vector4 *b) { \
float t, dX, dY, dZ, dW, den;\
dX = (b->X - a->X); \
dY = (b->Y - a->Y); \
dZ = (b->Z - a->Z); \
dW = (b->W - a->W); \
dX = (b->getX() - a->getX()); \
dY = (b->getY() - a->getY()); \
dZ = (b->getZ() - a->getZ()); \
dW = (b->getW() - a->getW()); \
den = -(sign d ## dir) + dW; \
if (den == 0) \
t = 0; \
else \
t = (sign a->dir - a->W) / den; \
c->dir1 = a->dir1 + t * d ## dir1; \
c->dir2 = a->dir2 + t * d ## dir2; \
c->W = a->W + t * dW; \
c->dir = sign c->W; \
t = (sign a->get ## dir () - a->getW()) / den; \
c->set ## dir1 (a->get ## dir1 () + t * d ## dir1); \
c->set ## dir2 (a->get ## dir2 () + t * d ## dir2); \
c->setW(a->getW() + t * dW); \
c->set ## dir (sign c->getW()); \
return t; \
}
@ -194,7 +189,7 @@ clip_func(clip_ymax, +, Y, X, Z)
clip_func(clip_zmin, -, Z, X, Y)
clip_func(clip_zmax, +, Z, X, Y)
float(*clip_proc[6])(V4 *, V4 *, V4 *) = {
float(*clip_proc[6])(Vector4 *, Vector4 *, Vector4 *) = {
clip_xmin, clip_xmax,
clip_ymin, clip_ymax,
clip_zmin, clip_zmax
@ -203,21 +198,18 @@ float(*clip_proc[6])(V4 *, V4 *, V4 *) = {
static inline void updateTmp(GLContext *c, GLVertex *q,
GLVertex *p0, GLVertex *p1, float t) {
if (c->current_shade_model == TGL_SMOOTH) {
q->color.v[0] = p0->color.v[0] + (p1->color.v[0] - p0->color.v[0]) * t;
q->color.v[1] = p0->color.v[1] + (p1->color.v[1] - p0->color.v[1]) * t;
q->color.v[2] = p0->color.v[2] + (p1->color.v[2] - p0->color.v[2]) * t;
q->color = p0->color + (p1->color - p0->color) * t;
} else {
q->color.v[0] = p0->color.v[0];
q->color.v[1] = p0->color.v[1];
q->color.v[2] = p0->color.v[2];
q->color = p0->color;
}
if (c->texture_2d_enabled) {
q->tex_coord.X = p0->tex_coord.X + (p1->tex_coord.X - p0->tex_coord.X) * t;
q->tex_coord.Y = p0->tex_coord.Y + (p1->tex_coord.Y - p0->tex_coord.Y) * t;
//NOTE: This could be implemented with operator overloading, but i'm not 100% sure that we can completely disregard Z and W components so I'm leaving it like this for now.
q->tex_coord.setX(p0->tex_coord.getX() + (p1->tex_coord.getX() - p0->tex_coord.getX()) * t);
q->tex_coord.setY(p0->tex_coord.getY() + (p1->tex_coord.getY() - p0->tex_coord.getY()) * t);
}
q->clip_code = gl_clipcode(q->pc.X, q->pc.Y, q->pc.Z, q->pc.W);
q->clip_code = gl_clipcode(q->pc.getX(), q->pc.getY(), q->pc.getZ(), q->pc.getW());
if (q->clip_code == 0)
gl_transform_to_viewport(c, q);
}

View File

@ -35,6 +35,7 @@ void tglGetIntegerv(int pname, int *params) {
}
void tglGetFloatv(int pname, float *v) {
TinyGL::Matrix4* m;
int i;
int mnr = 0; // just a trick to return the correct matrix
TinyGL::GLContext *c = TinyGL::gl_get_context();
@ -44,13 +45,11 @@ void tglGetFloatv(int pname, float *v) {
case TGL_PROJECTION_MATRIX:
mnr++;
case TGL_MODELVIEW_MATRIX: {
float *p = &c->matrix_stack_ptr[mnr]->m[0][0];;
for (i = 0; i < 4; i++) {
*v++ = p[0];
*v++ = p[4];
*v++ = p[8];
*v++ = p[12];
p++;
*v++ = c->matrix_stack_ptr[mnr]->get(0,i);
*v++ = c->matrix_stack_ptr[mnr]->get(1,i);
*v++ = c->matrix_stack_ptr[mnr]->get(2,i);
*v++ = c->matrix_stack_ptr[mnr]->get(3,i);
}
}
break;

View File

@ -61,13 +61,13 @@ void glInit(void *zbuffer1) {
// lights
for (int i = 0; i < T_MAX_LIGHTS; i++) {
GLLight *l = &c->lights[i];
l->ambient = gl_V4_New(0, 0, 0, 1);
l->diffuse = gl_V4_New(1, 1, 1, 1);
l->specular = gl_V4_New(1, 1, 1, 1);
l->position = gl_V4_New(0, 0, 1, 0);
l->norm_position = gl_V3_New(0, 0, 1);
l->spot_direction = gl_V3_New(0, 0, -1);
l->norm_spot_direction = gl_V3_New(0, 0, - 1);
l->ambient = Vector4(0, 0, 0, 1);
l->diffuse = Vector4(1, 1, 1, 1);
l->specular = Vector4(1, 1, 1, 1);
l->position = Vector4(0, 0, 1, 0);
l->norm_position = Vector3(0, 0, 1);
l->spot_direction = Vector3(0, 0, -1);
l->norm_spot_direction = Vector3(0, 0, - 1);
l->spot_exponent = 0;
l->spot_cutoff = 180;
l->attenuation[0] = 1;
@ -76,7 +76,7 @@ void glInit(void *zbuffer1) {
l->enabled = 0;
}
c->first_light = NULL;
c->ambient_light_model = gl_V4_New(0.2f, 0.2f, 0.2f, 1);
c->ambient_light_model = Vector4(0.2f, 0.2f, 0.2f, 1);
c->local_light_model = 0;
c->lighting_enabled = 0;
c->light_model_two_side = 0;
@ -84,10 +84,10 @@ void glInit(void *zbuffer1) {
// default materials */
for (int i = 0; i < 2; i++) {
GLMaterial *m = &c->materials[i];
m->emission = gl_V4_New(0, 0, 0, 1);
m->ambient = gl_V4_New(0.2f, 0.2f, 0.2f, 1);
m->diffuse = (gl_V4_New(0.8f, 0.8f, 0.8f, 1));
m->specular = gl_V4_New(0, 0, 0, 1);
m->emission = Vector4(0, 0, 0, 1);
m->ambient = Vector4(0.2f, 0.2f, 0.2f, 1);
m->diffuse = Vector4(0.8f, 0.8f, 0.8f, 1);
m->specular = Vector4(0, 0, 0, 1);
m->shininess = 0;
}
c->current_color_material_mode = TGL_FRONT_AND_BACK;
@ -98,25 +98,16 @@ void glInit(void *zbuffer1) {
glInitTextures(c);
// default state
c->current_color.X = 1.0;
c->current_color.Y = 1.0;
c->current_color.Z = 1.0;
c->current_color.W = 1.0;
c->current_color = Vector4(1.0f,1.0f,1.0f,1.0f);
c->longcurrent_color[0] = 65535;
c->longcurrent_color[1] = 65535;
c->longcurrent_color[2] = 65535;
c->current_normal.X = 1.0;
c->current_normal.Y = 0.0;
c->current_normal.Z = 0.0;
c->current_normal.W = 0.0;
c->current_normal = Vector4(1.0f,0.0f,0.0f,0.0f);
c->current_edge_flag = 1;
c->current_tex_coord.X = 0;
c->current_tex_coord.Y = 0;
c->current_tex_coord.Z = 0;
c->current_tex_coord.W = 1;
c->current_tex_coord = Vector4(0.0f,0.0f,0.0f,1.0f);
c->polygon_mode_front = TGL_FILL;
c->polygon_mode_back = TGL_FILL;
@ -127,10 +118,7 @@ void glInit(void *zbuffer1) {
c->cull_face_enabled = 0;
// clear
c->clear_color.v[0] = 0;
c->clear_color.v[1] = 0;
c->clear_color.v[2] = 0;
c->clear_color.v[3] = 0;
c->clear_color = Vector4(0.0f,0.0f,0.0f,0.0f);
c->clear_depth = 0;
// selection
@ -146,7 +134,7 @@ void glInit(void *zbuffer1) {
c->matrix_stack_depth_max[2] = MAX_TEXTURE_STACK_DEPTH;
for (int i = 0; i < 3; i++) {
c->matrix_stack[i] = (M4 *)gl_zalloc(c->matrix_stack_depth_max[i] * sizeof(M4));
c->matrix_stack[i] = (Matrix4*)gl_zalloc(c->matrix_stack_depth_max[i] * sizeof(Matrix4));
c->matrix_stack_ptr[i] = c->matrix_stack[i];
}

View File

@ -6,7 +6,7 @@ namespace TinyGL {
void glopMaterial(GLContext *c, GLParam *p) {
int mode = p[1].i;
int type = p[2].i;
float v[4] = { p[3].f, p[4].f, p[5].f, p[6].f };
Vector4 v(p[3].f, p[4].f, p[5].f, p[6].f);
GLMaterial *m;
if (mode == TGL_FRONT_AND_BACK) {
@ -21,30 +21,24 @@ void glopMaterial(GLContext *c, GLParam *p) {
switch (type) {
case TGL_EMISSION:
for (int i = 0; i < 4; i++)
m->emission.v[i] = v[i];
m->emission = v;
break;
case TGL_AMBIENT:
for (int i = 0; i < 4; i++)
m->ambient.v[i] = v[i];
m->ambient = v;
break;
case TGL_DIFFUSE:
for (int i = 0; i < 4; i++)
m->diffuse.v[i] = v[i];
m->diffuse = v;
break;
case TGL_SPECULAR:
for (int i = 0; i < 4; i++)
m->specular.v[i] = v[i];
m->specular = v;
break;
case TGL_SHININESS:
m->shininess = v[0];
m->shininess_i = (int)(v[0] / 128.0f) * SPECULAR_BUFFER_RESOLUTION;
m->shininess = v.getX();
m->shininess_i = (int)(v.getX() / 128.0f) * SPECULAR_BUFFER_RESOLUTION;
break;
case TGL_AMBIENT_AND_DIFFUSE:
for (int i = 0; i < 4; i++)
m->diffuse.v[i] = v[i];
for (int i = 0; i < 4; i++)
m->ambient.v[i] = v[i];
m->diffuse = v;
m->ambient = v;
break;
default:
assert(0);
@ -62,16 +56,13 @@ void glopColorMaterial(GLContext *c, GLParam *p) {
void glopLight(GLContext *c, GLParam *p) {
int light = p[1].i;
int type = p[2].i;
V4 v;
Vector4 v(p[3].f, p[4].f,p[5].f,p[6].f);
GLLight *l;
assert(light >= TGL_LIGHT0 && light < TGL_LIGHT0 + T_MAX_LIGHTS);
l = &c->lights[light - TGL_LIGHT0];
for (int i = 0; i < 4; i++)
v.v[i] = p[3 + i].f;
switch (type) {
case TGL_AMBIENT:
l->ambient = v;
@ -83,32 +74,26 @@ void glopLight(GLContext *c, GLParam *p) {
l->specular = v;
break;
case TGL_POSITION: {
V4 pos;
gl_M4_MulV4(&pos, c->matrix_stack_ptr[0], &v);
Vector4 pos = c->matrix_stack_ptr[0]->transform(v);
l->position = pos;
if (l->position.v[3] == 0) {
l->norm_position.X = pos.X;
l->norm_position.Y = pos.Y;
l->norm_position.Z = pos.Z;
gl_V3_Norm(&l->norm_position);
if (l->position.getW() == 0) {
l->norm_position = pos.toVector3();
l->norm_position.normalize();
}
}
break;
case TGL_SPOT_DIRECTION:
for (int i = 0; i < 3; i++) {
l->spot_direction.v[i] = v.v[i];
l->norm_spot_direction.v[i] = v.v[i];
}
gl_V3_Norm(&l->norm_spot_direction);
l->spot_direction = v.toVector3();
l->norm_spot_direction = v.toVector3();
l->norm_spot_direction.normalize();
break;
case TGL_SPOT_EXPONENT:
l->spot_exponent = v.v[0];
l->spot_exponent = v.getX();
break;
case TGL_SPOT_CUTOFF: {
float a = v.v[0];
float a = v.getX();
assert(a == 180 || (a >= 0 && a <= 90));
l->spot_cutoff = a;
if (a != 180)
@ -116,13 +101,13 @@ void glopLight(GLContext *c, GLParam *p) {
}
break;
case TGL_CONSTANT_ATTENUATION:
l->attenuation[0] = v.v[0];
l->attenuation[0] = v.getX();
break;
case TGL_LINEAR_ATTENUATION:
l->attenuation[1] = v.v[0];
l->attenuation[1] = v.getX();
break;
case TGL_QUADRATIC_ATTENUATION:
l->attenuation[2] = v.v[0];
l->attenuation[2] = v.getX();
break;
default:
assert(0);
@ -131,18 +116,16 @@ void glopLight(GLContext *c, GLParam *p) {
void glopLightModel(GLContext *c, GLParam *p) {
int pname = p[1].i;
float v[4] = { p[2].f, p[3].f, p[4].f, p[5].f };
switch (pname) {
case TGL_LIGHT_MODEL_AMBIENT:
for (int i = 0; i < 4; i++)
c->ambient_light_model.v[i] = v[i];
c->ambient_light_model = Vector4(p[2].f, p[3].f, p[4].f, p[5].f);
break;
case TGL_LIGHT_MODEL_LOCAL_VIEWER:
c->local_light_model = (int)v[0];
c->local_light_model = (int)p[2].f;
break;
case TGL_LIGHT_MODEL_TWO_SIDE:
c->light_model_two_side = (int)v[0];
c->light_model_two_side = (int)p[2].f;
break;
default:
warning("glopLightModel: illegal pname: 0x%x", pname);
@ -187,64 +170,56 @@ void gl_shade_vertex(GLContext *c, GLVertex *v) {
float R, G, B, A;
GLMaterial *m;
GLLight *l;
V3 n, s, d;
Vector3 n, s, d;
float dist, tmp, att, dot, dot_spot, dot_spec;
int twoside = c->light_model_two_side;
m = &c->materials[0];
n.X = v->normal.X;
n.Y = v->normal.Y;
n.Z = v->normal.Z;
n = v->normal;
R = m->emission.v[0] + m->ambient.v[0] * c->ambient_light_model.v[0];
G = m->emission.v[1] + m->ambient.v[1] * c->ambient_light_model.v[1];
B = m->emission.v[2] + m->ambient.v[2] * c->ambient_light_model.v[2];
A = clampf(m->diffuse.v[3], 0, 1);
R = m->emission.getX() + m->ambient.getX() * c->ambient_light_model.getX();
G = m->emission.getY() + m->ambient.getY() * c->ambient_light_model.getY();
B = m->emission.getZ() + m->ambient.getZ() * c->ambient_light_model.getZ();
A = clampf(m->diffuse.getW(), 0, 1);
for (l = c->first_light; l != NULL; l = l->next) {
float lR, lB, lG;
// ambient
lR = l->ambient.v[0] * m->ambient.v[0];
lG = l->ambient.v[1] * m->ambient.v[1];
lB = l->ambient.v[2] * m->ambient.v[2];
lR = l->ambient.getX() * m->ambient.getX();
lG = l->ambient.getY() * m->ambient.getY();
lB = l->ambient.getZ() * m->ambient.getZ();
if (l->position.v[3] == 0) {
if (l->position.getW() == 0) {
// light at infinity
d.X = l->position.v[0];
d.Y = l->position.v[1];
d.Z = l->position.v[2];
d = l->position.toVector3();
att = 1;
} else {
// distance attenuation
d.X = l->position.v[0] - v->ec.v[0];
d.Y = l->position.v[1] - v->ec.v[1];
d.Z = l->position.v[2] - v->ec.v[2];
dist = sqrt(d.X * d.X + d.Y * d.Y + d.Z * d.Z);
d = l->position.toVector3() - v->ec.toVector3();
dist = d.getLength();
if (dist > 1E-3) {
tmp = 1 / dist;
d.X *= tmp;
d.Y *= tmp;
d.Z *= tmp;
d *= tmp;
}
att = 1.0f / (l->attenuation[0] + dist * (l->attenuation[1] +
dist * l->attenuation[2]));
}
dot = d.X * n.X + d.Y * n.Y + d.Z * n.Z;
dot = Vector3::dot(d,n);
if (twoside && dot < 0)
dot = -dot;
if (dot > 0) {
// diffuse light
lR += dot * l->diffuse.v[0] * m->diffuse.v[0];
lG += dot * l->diffuse.v[1] * m->diffuse.v[1];
lB += dot * l->diffuse.v[2] * m->diffuse.v[2];
lR += dot * l->diffuse.getX() * m->diffuse.getX();
lG += dot * l->diffuse.getY() * m->diffuse.getY();
lB += dot * l->diffuse.getZ() * m->diffuse.getZ();
// spot light
if (l->spot_cutoff != 180) {
dot_spot = -(d.X * l->norm_spot_direction.v[0] +
d.Y * l->norm_spot_direction.v[1] +
d.Z * l->norm_spot_direction.v[2]);
dot_spot = -(d.getX() * l->norm_spot_direction.getX() +
d.getY() * l->norm_spot_direction.getY() +
d.getZ() * l->norm_spot_direction.getZ());
if (twoside && dot_spot < 0)
dot_spot = -dot_spot;
if (dot_spot < l->cos_spot_cutoff) {
@ -261,26 +236,24 @@ void gl_shade_vertex(GLContext *c, GLVertex *v) {
// specular light
if (c->local_light_model) {
V3 vcoord;
vcoord.X = v->ec.X;
vcoord.Y = v->ec.Y;
vcoord.Z = v->ec.Z;
gl_V3_Norm(&vcoord);
s.X = d.X - vcoord.X;
s.Y = d.Y - vcoord.X;
s.Z = d.Z - vcoord.X;
Vector3 vcoord;
vcoord = v->ec.toVector3();
vcoord.normalize();
s.setX(d.getX() - vcoord.getX());
s.setY(d.getX() - vcoord.getX());
s.setZ(d.getX() - vcoord.getX());
//NOTE: this operation is rather suspicious, this code should be tested.
} else {
s.X = d.X;
s.Y = d.Y;
s.Z = (float)(d.Z + 1.0);
s = d;
s.setZ(s.getZ() + 1.0);
}
dot_spec = n.X * s.X + n.Y * s.Y + n.Z * s.Z;
dot_spec = Vector3::dot(n,s);
if (twoside && dot_spec < 0)
dot_spec = -dot_spec;
if (dot_spec > 0) {
GLSpecBuf *specbuf;
int idx;
tmp = sqrt(s.X * s.X + s.Y * s.Y + s.Z * s.Z);
tmp = s.getLength();
if (tmp > 1E-3) {
dot_spec = dot_spec / tmp;
}
@ -296,9 +269,9 @@ void gl_shade_vertex(GLContext *c, GLVertex *v) {
idx = (int)tmp;
dot_spec = specbuf->buf[idx];
lR += dot_spec * l->specular.v[0] * m->specular.v[0];
lG += dot_spec * l->specular.v[1] * m->specular.v[1];
lB += dot_spec * l->specular.v[2] * m->specular.v[2];
lR += dot_spec * l->specular.getX() * m->specular.getX();
lG += dot_spec * l->specular.getY() * m->specular.getY();
lB += dot_spec * l->specular.getZ() * m->specular.getZ();
}
}
@ -307,10 +280,7 @@ void gl_shade_vertex(GLContext *c, GLVertex *v) {
B += att * lB;
}
v->color.v[0] = clampf(R, 0, 1);
v->color.v[1] = clampf(G, 0, 1);
v->color.v[2] = clampf(B, 0, 1);
v->color.v[3] = A;
v->color = Vector4(clampf(R, 0, 1), clampf(G, 0, 1), clampf(B, 0, 1), A);
}
} // end of namespace TinyGL

View File

@ -33,17 +33,17 @@ void glopMatrixMode(GLContext *c, GLParam *p) {
}
void glopLoadMatrix(GLContext *c, GLParam *p) {
M4 *m;
Matrix4 *m;
GLParam *q;
m = c->matrix_stack_ptr[c->matrix_mode];
q = p + 1;
for (int i = 0; i < 4; i++) {
m->m[0][i] = q[0].f;
m->m[1][i] = q[1].f;
m->m[2][i] = q[2].f;
m->m[3][i] = q[3].f;
m->set(0,i, q[0].f);
m->set(1,i, q[1].f);
m->set(2,i, q[2].f);
m->set(3,i, q[3].f);
q += 4;
}
@ -51,25 +51,25 @@ void glopLoadMatrix(GLContext *c, GLParam *p) {
}
void glopLoadIdentity(GLContext *c, GLParam *) {
gl_M4_Id(c->matrix_stack_ptr[c->matrix_mode]);
*c->matrix_stack_ptr[c->matrix_mode] = Matrix4::identity();
gl_matrix_update(c);
}
void glopMultMatrix(GLContext *c, GLParam *p) {
M4 m;
Matrix4 m;
GLParam *q;
q = p + 1;
for (int i = 0; i < 4; i++) {
m.m[0][i] = q[0].f;
m.m[1][i] = q[1].f;
m.m[2][i] = q[2].f;
m.m[3][i] = q[3].f;
m.set(0,i,q[0].f);
m.set(1,i,q[1].f);
m.set(2,i,q[2].f);
m.set(3,i,q[3].f);
q += 4;
}
gl_M4_MulLeft(c->matrix_stack_ptr[c->matrix_mode], &m);
*c->matrix_stack_ptr[c->matrix_mode] = (*c->matrix_stack_ptr[c->matrix_mode]) * m; // NOTE: verify this, I'm not 100% sure.
gl_matrix_update(c);
}
@ -77,13 +77,13 @@ void glopMultMatrix(GLContext *c, GLParam *p) {
void glopPushMatrix(GLContext *c, GLParam *) {
int n = c->matrix_mode;
M4 *m;
Matrix4 *m;
assert((c->matrix_stack_ptr[n] - c->matrix_stack[n] + 1) < c->matrix_stack_depth_max[n]);
m = ++c->matrix_stack_ptr[n];
gl_M4_Move(&m[0], &m[-1]);
m[0] = m[-1];
gl_matrix_update(c);
}
@ -97,7 +97,7 @@ void glopPopMatrix(GLContext *c, GLParam *) {
}
void glopRotate(GLContext *c, GLParam *p) {
M4 m;
Matrix4 m;
float u[3];
float angle;
int dir_code;
@ -112,19 +112,19 @@ void glopRotate(GLContext *c, GLParam *p) {
switch (dir_code) {
case 0:
gl_M4_Id(&m);
m = Matrix4::identity();
break;
case 4:
if (u[0] < 0) angle = -angle;
gl_M4_Rotate(&m,angle,0);
m = Matrix4::rotation(angle,0);
break;
case 2:
if (u[1] < 0) angle = -angle;
gl_M4_Rotate(&m,angle,1);
m = Matrix4::rotation(angle,1);
break;
case 1:
if (u[2] < 0) angle = -angle;
gl_M4_Rotate(&m,angle,2);
m = Matrix4::rotation(angle,2);
break;
default:
{
@ -144,57 +144,62 @@ void glopRotate(GLContext *c, GLParam *p) {
sint = sin(angle);
// fill in the values
m.m[3][0] = m.m[3][1] = m.m[3][2] = m.m[0][3] = m.m[1][3] = m.m[2][3] = 0.0f;
m.m[3][3] = 1.0f;
m.set(3,0,0.0f);
m.set(3,1,0.0f);
m.set(3,2,0.0f);
m.set(0,3,0.0f);
m.set(1,3,0.0f);
m.set(2,3,0.0f);
m.set(3,3,1.0f);
// do the math
m.m[0][0] = u[0] * u[0] + cost * (1 - u[0] * u[0]);
m.m[1][0] = u[0] * u[1] * (1 -cost) - u[2] * sint;
m.m[2][0] = u[2] * u[0] * (1 -cost) + u[1] * sint;
m.m[0][1] = u[0] * u[1] * (1 -cost) + u[2] * sint;
m.m[1][1] = u[1] * u[1] + cost * (1 - u[1] * u[1]);
m.m[2][1] = u[1] * u[2] * (1 - cost) - u[0] * sint;
m.m[0][2] = u[2] * u[0] * (1 - cost) - u[1] * sint;
m.m[1][2] = u[1] * u[2] * (1 - cost) + u[0] * sint;
m.m[2][2] = u[2] * u[2] + cost * (1 - u[2] * u[2]);
m.set(0,0, u[0] * u[0] + cost * (1 - u[0] * u[0]));
m.set(1,0, u[0] * u[1] * (1 -cost) - u[2] * sint);
m.set(2,0, u[2] * u[0] * (1 -cost) + u[1] * sint);
m.set(0,1, u[0] * u[1] * (1 -cost) + u[2] * sint);
m.set(1,1, u[1] * u[1] + cost * (1 - u[1] * u[1]));
m.set(2,1, u[1] * u[2] * (1 - cost) - u[0] * sint);
m.set(0,2, u[2] * u[0] * (1 - cost) - u[1] * sint);
m.set(1,2, u[1] * u[2] * (1 - cost) + u[0] * sint);
m.set(2,2, u[2] * u[2] + cost * (1 - u[2] * u[2]));
}
}
gl_M4_MulLeft(c->matrix_stack_ptr[c->matrix_mode], &m);
*c->matrix_stack_ptr[c->matrix_mode] = (*c->matrix_stack_ptr[c->matrix_mode]) * m;
gl_matrix_update(c);
}
void glopScale(GLContext *c, GLParam *p) {
float *m;
Matrix4 *m;
float x = p[1].f, y = p[2].f, z = p[3].f;
m = &c->matrix_stack_ptr[c->matrix_mode]->m[0][0];
m = c->matrix_stack_ptr[c->matrix_mode];
m[0] *= x; m[1] *= y; m[2] *= z;
m[4] *= x; m[5] *= y; m[6] *= z;
m[8] *= x; m[9] *= y; m[10] *= z;
m[12] *= x; m[13] *= y; m[14] *= z;
for(int i = 0; i < 4; i++) {
m->set(0,i, m->get(0,i) * x);
m->set(1,i, m->get(1,i) * y);
m->set(2,i, m->get(2,i) * z);
}
gl_matrix_update(c);
}
void glopTranslate(GLContext *c, GLParam *p) {
float *m;
Matrix4 *m;
float x = p[1].f, y = p[2].f, z = p[3].f;
m = &c->matrix_stack_ptr[c->matrix_mode]->m[0][0];
m = c->matrix_stack_ptr[c->matrix_mode];
m[3] = m[0] * x + m[1] * y + m[2] * z + m[3];
m[7] = m[4] * x + m[5] * y + m[6] * z + m[7];
m[11] = m[8] * x + m[9] * y + m[10] * z + m[11];
m[15] = m[12] * x + m[13] * y + m[14] * z + m[15];
m->set(3,0, m->get(0,0) * x + m->get(1,0) * y + m->get(2,0) * z + m->get(3,0));
m->set(3,1, m->get(0,1) * x + m->get(1,1) * y + m->get(2,1) * z + m->get(3,1));
m->set(3,2, m->get(0,2) * x + m->get(1,2) * y + m->get(2,2) * z + m->get(3,2));
m->set(3,3, m->get(0,3) * x + m->get(1,3) * y + m->get(2,3) * z + m->get(3,3));
gl_matrix_update(c);
}
void glopFrustum(GLContext *c, GLParam *p) {
float *r;
M4 m;
Matrix4 m;
float left = p[1].f;
float right = p[2].f;
float bottom = p[3].f;
@ -210,13 +215,12 @@ void glopFrustum(GLContext *c, GLParam *p) {
C = -(farp + nearp) / (farp - nearp);
D = (float)(-(2.0 * farp * nearp) / (farp - nearp));
r = &m.m[0][0];
r[0] = x; r[1] = 0; r[2] = A; r[3] = 0;
r[4] = 0; r[5] = y; r[6] = B; r[7] = 0;
r[8] = 0; r[9] = 0; r[10] = C; r[11] = D;
r[12] = 0; r[13] = 0; r[14] = -1; r[15] = 0;
m.set(0,0, x); m.set(1,0, 0); m.set(2,0, A); m.set(3,0, 0);
m.set(0,1, x); m.set(1,1, y); m.set(2,1, B); m.set(3,1, 0);
m.set(0,2, x); m.set(1,2, 0); m.set(2,2, C); m.set(3,2, D);
m.set(0,3, x); m.set(1,3, 0); m.set(2,3, -1); m.set(3,3, 0);
gl_M4_MulLeft(c->matrix_stack_ptr[c->matrix_mode], &m);
*c->matrix_stack_ptr[c->matrix_mode] = (*c->matrix_stack_ptr[c->matrix_mode]) * m;
gl_matrix_update(c);
}

View File

@ -4,23 +4,11 @@
namespace TinyGL {
void glopNormal(GLContext *c, GLParam *p) {
V3 v;
v.X = p[1].f;
v.Y = p[2].f;
v.Z = p[3].f;
c->current_normal.X = v.X;
c->current_normal.Y = v.Y;
c->current_normal.Z = v.Z;
c->current_normal.W = 0;
c->current_normal = Vector4(p[1].f,p[2].f,p[3].f,0.0f);
}
void glopTexCoord(GLContext *c, GLParam *p) {
c->current_tex_coord.X = p[1].f;
c->current_tex_coord.Y = p[2].f;
c->current_tex_coord.Z = p[3].f;
c->current_tex_coord.W = p[4].f;
c->current_tex_coord = Vector4(p[1].f,p[2].f,p[3].f,p[4].f);
}
void glopEdgeFlag(GLContext *c, GLParam *p) {
@ -28,10 +16,7 @@ void glopEdgeFlag(GLContext *c, GLParam *p) {
}
void glopColor(GLContext *c, GLParam *p) {
c->current_color.X = p[1].f;
c->current_color.Y = p[2].f;
c->current_color.Z = p[3].f;
c->current_color.W = p[4].f;
c->current_color = Vector4(p[1].f,p[2].f,p[3].f,p[4].f);
c->longcurrent_color[0] = p[5].ui;
c->longcurrent_color[1] = p[6].ui;
c->longcurrent_color[2] = p[7].ui;
@ -55,18 +40,17 @@ void gl_eval_viewport(GLContext *c) {
v = &c->viewport;
v->trans.X = (float)(((v->xsize - 0.5) / 2.0) + v->xmin);
v->trans.Y = (float)(((v->ysize - 0.5) / 2.0) + v->ymin);
v->trans.Z = (float)(((zsize - 0.5) / 2.0) + ((1 << ZB_POINT_Z_FRAC_BITS)) / 2);
v->trans.setX((float)(((v->xsize - 0.5) / 2.0) + v->xmin));
v->trans.setY((float)(((v->ysize - 0.5) / 2.0) + v->ymin));
v->trans.setZ((float)(((zsize - 0.5) / 2.0) + ((1 << ZB_POINT_Z_FRAC_BITS)) / 2));
v->scale.X = (float)((v->xsize - 0.5) / 2.0);
v->scale.Y = (float)(-(v->ysize - 0.5) / 2.0);
v->scale.Z = (float)(-((zsize - 0.5) / 2.0));
v->scale.setX((float)((v->xsize - 0.5) / 2.0));
v->scale.setY((float)(-(v->ysize - 0.5) / 2.0));
v->scale.setZ((float)(-((zsize - 0.5) / 2.0)));
}
void glopBegin(GLContext *c, GLParam *p) {
int type;
M4 tmp;
assert(c->in_begin == 0);
@ -79,22 +63,18 @@ void glopBegin(GLContext *c, GLParam *p) {
if (c->matrix_model_projection_updated) {
if (c->lighting_enabled) {
// precompute inverse modelview
gl_M4_Inv(&tmp, c->matrix_stack_ptr[0]);
gl_M4_Transpose(&c->matrix_model_view_inv, &tmp);
c->matrix_model_view_inv = c->matrix_stack_ptr[0]->inverse().transpose();
} else {
float *m = &c->matrix_model_projection.m[0][0];
// precompute projection matrix
gl_M4_Mul(&c->matrix_model_projection,
c->matrix_stack_ptr[1],
c->matrix_stack_ptr[0]);
c->matrix_model_projection = (*c->matrix_stack_ptr[1]) * (*c->matrix_stack_ptr[0]);
// test to accelerate computation
c->matrix_model_projection_no_w_transform = 0;
if (m[12] == 0.0 && m[13] == 0.0 && m[14] == 0.0)
if (c->matrix_model_projection.get(3,0) == 0.0 && c->matrix_model_projection.get(3,1) == 0.0 && c->matrix_model_projection.get(3,2) == 0.0)
c->matrix_model_projection_no_w_transform = 1;
}
// test if the texture matrix is not Identity
c->apply_texture_matrix = !gl_M4_IsId(c->matrix_stack_ptr[2]);
c->apply_texture_matrix = !c->matrix_stack_ptr[2]->IsIdentity();
c->matrix_model_projection_updated = 0;
}
@ -137,55 +117,39 @@ void glopBegin(GLContext *c, GLParam *p) {
// coords, tranformation, clip code and projection
// TODO : handle all cases
static inline void gl_vertex_transform(GLContext *c, GLVertex *v) {
float *m;
V4 *n;
Matrix4 *m;
Vector4 *n;
if (c->lighting_enabled) {
// eye coordinates needed for lighting
m = &c->matrix_stack_ptr[0]->m[0][0];
v->ec.X = (v->coord.X * m[0] + v->coord.Y * m[1] +
v->coord.Z * m[2] + m[3]);
v->ec.Y = (v->coord.X * m[4] + v->coord.Y * m[5] +
v->coord.Z * m[6] + m[7]);
v->ec.Z = (v->coord.X * m[8] + v->coord.Y * m[9] +
v->coord.Z * m[10] + m[11]);
v->ec.W = (v->coord.X * m[12] + v->coord.Y * m[13] +
v->coord.Z * m[14] + m[15]);
m = c->matrix_stack_ptr[0];
v->ec = m->transform(v->coord);
// projection coordinates
m = &c->matrix_stack_ptr[1]->m[0][0];
v->pc.X = (v->ec.X * m[0] + v->ec.Y * m[1] + v->ec.Z * m[2] + v->ec.W * m[3]);
v->pc.Y = (v->ec.X * m[4] + v->ec.Y * m[5] + v->ec.Z * m[6] + v->ec.W * m[7]);
v->pc.Z = (v->ec.X * m[8] + v->ec.Y * m[9] + v->ec.Z * m[10] + v->ec.W * m[11]);
v->pc.W = (v->ec.X * m[12] + v->ec.Y * m[13] + v->ec.Z * m[14] + v->ec.W * m[15]);
m = c->matrix_stack_ptr[1];
v->pc = m->transform(v->ec);
m = &c->matrix_model_view_inv.m[0][0];
m = &c->matrix_model_view_inv;
n = &c->current_normal;
v->normal.X = (n->X * m[0] + n->Y * m[1] + n->Z * m[2]);
v->normal.Y = (n->X * m[4] + n->Y * m[5] + n->Z * m[6]);
v->normal.Z = (n->X * m[8] + n->Y * m[9] + n->Z * m[10]);
v->normal = m->transform3x3(n->toVector3());
if (c->normalize_enabled) {
gl_V3_Norm(&v->normal);
v->normal.normalize();
}
} else {
// no eye coordinates needed, no normal
// NOTE: W = 1 is assumed
m = &c->matrix_model_projection.m[0][0];
m = &c->matrix_model_projection;
v->pc.X = (v->coord.X * m[0] + v->coord.Y * m[1] + v->coord.Z * m[2] + m[3]);
v->pc.Y = (v->coord.X * m[4] + v->coord.Y * m[5] + v->coord.Z * m[6] + m[7]);
v->pc.Z = (v->coord.X * m[8] + v->coord.Y * m[9] + v->coord.Z * m[10] + m[11]);
v->pc = m->transform(v->coord);
if (c->matrix_model_projection_no_w_transform) {
v->pc.W = m[15];
} else {
v->pc.W = (v->coord.X * m[12] + v->coord.Y * m[13] + v->coord.Z * m[14] + m[15]);
v->pc.setW(m->get(3,3));
}
}
v->clip_code = gl_clipcode(v->pc.X, v->pc.Y, v->pc.Z, v->pc.W);
v->clip_code = gl_clipcode(v->pc.getX(), v->pc.getY(), v->pc.getZ(), v->pc.getW());
}
void glopVertex(GLContext *c, GLParam *p) {
@ -215,10 +179,7 @@ void glopVertex(GLContext *c, GLParam *p) {
v = &c->vertex[n];
n++;
v->coord.X = p[1].f;
v->coord.Y = p[2].f;
v->coord.Z = p[3].f;
v->coord.W = p[4].f;
v->coord = Vector4(p[1].f,p[2].f,p[3].f,p[4].f);
gl_vertex_transform(c, v);
@ -234,7 +195,7 @@ void glopVertex(GLContext *c, GLParam *p) {
if (c->texture_2d_enabled) {
if (c->apply_texture_matrix) {
gl_M4_MulV4(&v->tex_coord, c->matrix_stack_ptr[2], &c->current_tex_coord);
v->tex_coord = c->matrix_stack_ptr[2]->transform(c->current_tex_coord);
} else {
v->tex_coord = c->current_tex_coord;
}

View File

@ -54,28 +54,28 @@ struct GLSpecBuf {
};
struct GLLight {
V4 ambient;
V4 diffuse;
V4 specular;
V4 position;
V3 spot_direction;
Vector4 ambient;
Vector4 diffuse;
Vector4 specular;
Vector4 position;
Vector3 spot_direction;
float spot_exponent;
float spot_cutoff;
float attenuation[3];
// precomputed values
float cos_spot_cutoff;
V3 norm_spot_direction;
V3 norm_position;
Vector3 norm_spot_direction;
Vector3 norm_position;
// we use a linked list to know which are the enabled lights
int enabled;
struct GLLight *next, *prev;
};
struct GLMaterial {
V4 emission;
V4 ambient;
V4 diffuse;
V4 specular;
Vector4 emission;
Vector4 ambient;
Vector4 diffuse;
Vector4 specular;
float shininess;
// computed values
@ -86,8 +86,8 @@ struct GLMaterial {
struct GLViewport {
int xmin, ymin, xsize, ysize;
V3 scale;
V3 trans;
Vector3 scale;
Vector3 trans;
int updated;
};
@ -111,14 +111,14 @@ struct GLList {
struct GLVertex {
int edge_flag;
V3 normal;
V4 coord;
V4 tex_coord;
V4 color;
Vector3 normal;
Vector4 coord;
Vector4 tex_coord;
Vector4 color;
// computed values
V4 ec; // eye coordinates
V4 pc; // coordinates in the normalized volume
Vector4 ec; // eye coordinates
Vector4 pc; // coordinates in the normalized volume
int clip_code; // clip code
ZBufferPoint zp; // integer coordinates for the rasterization
};
@ -159,7 +159,7 @@ struct GLContext {
// lights
GLLight lights[T_MAX_LIGHTS];
GLLight *first_light;
V4 ambient_light_model;
Vector4 ambient_light_model;
int local_light_model;
int lighting_enabled;
int light_model_two_side;
@ -184,12 +184,12 @@ struct GLContext {
// matrix
int matrix_mode;
M4 *matrix_stack[3];
M4 *matrix_stack_ptr[3];
Matrix4 *matrix_stack[3];
Matrix4 *matrix_stack_ptr[3];
int matrix_stack_depth_max[3];
M4 matrix_model_view_inv;
M4 matrix_model_projection;
Matrix4 matrix_model_view_inv;
Matrix4 matrix_model_projection;
int matrix_model_projection_updated;
int matrix_model_projection_no_w_transform;
int apply_texture_matrix;
@ -222,13 +222,13 @@ struct GLContext {
// clear
float clear_depth;
V4 clear_color;
Vector4 clear_color;
// current vertex state
V4 current_color;
Vector4 current_color;
unsigned int longcurrent_color[3]; // precomputed integer color
V4 current_normal;
V4 current_tex_coord;
Vector4 current_normal;
Vector4 current_tex_coord;
int current_edge_flag;
// glBegin / glEnd

View File

@ -5,130 +5,6 @@
namespace TinyGL {
void gl_M4_Id(M4 *a) {
for (int i = 0; i < 4; i++) {
for (int j = 0; j < 4; j++) {
if (i == j)
a->m[i][j] = 1.0;
else
a->m[i][j] = 0.0;
}
}
}
int gl_M4_IsId(const M4 *a) {
for (int i = 0; i < 4; i++) {
for (int j = 0; j < 4; j++) {
if (i == j) {
if (a->m[i][j] != 1.0)
return 0;
} else if (a->m[i][j] != 0.0)
return 0;
}
}
return 1;
}
void gl_M4_Mul(M4 *c, const M4 *a, const M4 *b) {
float s;
for (int i = 0; i < 4; i++) {
for (int j = 0; j < 4; j++) {
s = 0.0;
for (int k = 0; k < 4; k++)
s += a->m[i][k] * b->m[k][j];
c->m[i][j] = s;
}
}
}
// c=c*a
void gl_M4_MulLeft(M4 *c, const M4 *b) {
float s;
M4 a;
//memcpy(&a, c, 16 * sizeof(float));
a = *c;
for (int i = 0; i < 4; i++) {
for (int j = 0; j < 4; j++) {
s = 0.0;
for (int k = 0; k < 4; k++)
s += a.m[i][k] * b->m[k][j];
c->m[i][j] = s;
}
}
}
void gl_M4_Move(M4 *a, const M4 *b) {
memcpy(a, b, sizeof(M4));
}
void gl_MoveV3(V3 *a, const V3 *b) {
memcpy(a, b, sizeof(V3));
}
void gl_MulM4V3(V3 *a, const M4 *b, const V3 *c) {
a->X = b->m[0][0] * c->X + b->m[0][1] * c->Y + b->m[0][2] * c->Z + b->m[0][3];
a->Y = b->m[1][0] * c->X + b->m[1][1] * c->Y + b->m[1][2] * c->Z + b->m[1][3];
a->Z = b->m[2][0] * c->X + b->m[2][1] * c->Y + b->m[2][2] * c->Z + b->m[2][3];
}
void gl_MulM3V3(V3 *a, const M4 *b, const V3 *c) {
a->X = b->m[0][0] * c->X + b->m[0][1] * c->Y + b->m[0][2] * c->Z;
a->Y = b->m[1][0] * c->X + b->m[1][1] * c->Y + b->m[1][2] * c->Z;
a->Z = b->m[2][0] * c->X + b->m[2][1] * c->Y + b->m[2][2] * c->Z;
}
void gl_M4_MulV4(V4 *a, const M4 *b, const V4 *c) {
a->X = b->m[0][0] * c->X + b->m[0][1] * c->Y + b->m[0][2] * c->Z + b->m[0][3] * c->W;
a->Y = b->m[1][0] * c->X + b->m[1][1] * c->Y + b->m[1][2] * c->Z + b->m[1][3] * c->W;
a->Z = b->m[2][0] * c->X + b->m[2][1] * c->Y + b->m[2][2] * c->Z + b->m[2][3] * c->W;
a->W = b->m[3][0] * c->X + b->m[3][1] * c->Y + b->m[3][2] * c->Z + b->m[3][3] * c->W;
}
// transposition of a 4x4 matrix
void gl_M4_Transpose(M4 *a, const M4 *b) {
a->m[0][0] = b->m[0][0];
a->m[0][1] = b->m[1][0];
a->m[0][2] = b->m[2][0];
a->m[0][3] = b->m[3][0];
a->m[1][0] = b->m[0][1];
a->m[1][1] = b->m[1][1];
a->m[1][2] = b->m[2][1];
a->m[1][3] = b->m[3][1];
a->m[2][0] = b->m[0][2];
a->m[2][1] = b->m[1][2];
a->m[2][2] = b->m[2][2];
a->m[2][3] = b->m[3][2];
a->m[3][0] = b->m[0][3];
a->m[3][1] = b->m[1][3];
a->m[3][2] = b->m[2][3];
a->m[3][3] = b->m[3][3];
}
// inversion of an orthogonal matrix of type Y=M.X+P
void gl_M4_InvOrtho(M4 *a, const M4 &b) {
int i, j;
float s;
for (i = 0; i < 3; i++) {
for (j = 0; j < 3; j++)
a->m[i][j] = b.m[j][i];
a->m[3][0] = 0.0;
a->m[3][1] = 0.0;
a->m[3][2] = 0.0;
a->m[3][3] = 1.0;
for (i = 0; i < 3; i++) {
s = 0;
for (j = 0; j < 3; j++)
s -= b.m[j][i] * b.m[j][3];
a->m[i][3] = s;
}
}
}
// Inversion of a general nxn matrix.
// Note : m is destroyed
@ -188,85 +64,6 @@ int Matrix_Inv(float *r, float *m, int n) {
return 0;
}
// inversion of a 4x4 matrix
void gl_M4_Inv(M4 *a, const M4 *b) {
M4 tmp;
memcpy(&tmp, b, 16 * sizeof(float));
//tmp = *b
Matrix_Inv(&a->m[0][0], &tmp.m[0][0], 4);
}
void gl_M4_Rotate(M4 *a, float t, int u) {
float s, c;
int v, w;
if ((v = u + 1) > 2)
v = 0;
if ((w = v + 1) > 2)
w = 0;
s = sin(t);
c = cos(t);
gl_M4_Id(a);
a->m[v][v] = c;
a->m[v][w] = -s;
a->m[w][v] = s;
a->m[w][w] = c;
}
/*
// inverse of a 3x3 matrix
void gl_M3_Inv(M3 *a, const M3 *m) {
float det;
det = m->m[0][0] * m->m[1][1] * m->m[2][2] - m->m[0][0] * m->m[1][2] * m->m[2][1] -
m->m[1][0] * m->m[0][1] * m->m[2][2] + m->m[1][0] * m->m[0][2] * m->m[2][1] +
m->m[2][0] * m->m[0][1] * m->m[1][2] - m->m[2][0] * m->m[0][2] * m->m[1][1];
a->m[0][0] = (m->m[1][1] * m->m[2][2] - m->m[1][2] * m->m[2][1]) / det;
a->m[0][1] = -(m->m[0][1] * m->m[2][2] - m->m[0][2] * m->m[2][1]) / det;
a->m[0][2] = -(-m->m[0][1] * m->m[1][2] + m->m[0][2] * m->m[1][1]) / det;
a->m[1][0] = -(m->m[1][0] * m->m[2][2] - m->m[1][2] * m->m[2][0]) / det;
a->m[1][1] = (m->m[0][0] * m->m[2][2] - m->m[0][2] * m->m[2][0]) / det;
a->m[1][2] = -(m->m[0][0] * m->m[1][2] - m->m[0][2] * m->m[1][0]) / det;
a->m[2][0] = (m->m[1][0] * m->m[2][1] - m->m[1][1] * m->m[2][0]) / det;
a->m[2][1] = -(m->m[0][0] * m->m[2][1] - m->m[0][1] * m->m[2][0]) / det;
a->m[2][2] = (m->m[0][0] * m->m[1][1] - m->m[0][1] * m->m[1][0]) / det;
}
*/
// vector arithmetic
int gl_V3_Norm(V3 *a) {
float n;
n = sqrt(a->X * a->X + a->Y * a->Y + a->Z * a->Z);
if (n == 0)
return 1;
a->X /= n;
a->Y /= n;
a->Z /= n;
return 0;
}
V3 gl_V3_New(float x, float y, float z) {
V3 a;
a.X = x;
a.Y = y;
a.Z = z;
return a;
}
V4 gl_V4_New(float x, float y, float z, float w) {
V4 a;
a.X = x;
a.Y = y;
a.Z = z;
a.W = w;
return a;
}
Vector3::Vector3() {
// Empty constructor, no overhead
}
@ -303,11 +100,17 @@ Vector4::Vector4(float x, float y, float z, float w) {
_v[3] = w;
}
Vector4::Vector4(const Vector3 &vec, float w) {
_v[0] = vec.getX();
_v[1] = vec.getY();
_v[2] = vec.getZ();
_v[3] = w;
}
Matrix4::Matrix4() {
// Empty constructor, no overhead
}
Matrix4::Matrix4(const Matrix4 &other) {
memcpy(_m,other._m,sizeof(_m));
}
@ -348,7 +151,7 @@ TinyGL::Matrix4 Matrix4::transpose() const {
return a;
}
TinyGL::Matrix4 Matrix4::inverseOrtho() const {
Matrix4 Matrix4::inverseOrtho() const {
Matrix4 a;
int i, j;
@ -371,7 +174,7 @@ TinyGL::Matrix4 Matrix4::inverseOrtho() const {
return a;
}
TinyGL::Matrix4 Matrix4::inverse() const {
Matrix4 Matrix4::inverse() const {
Matrix4 source(*this);
int k;
float max, tmp, t;
@ -424,7 +227,7 @@ TinyGL::Matrix4 Matrix4::inverse() const {
return result;
}
TinyGL::Matrix4 Matrix4::rotation(float t, int u) const {
Matrix4 Matrix4::rotation(float t, int u) {
Matrix4 a = identity();
float s, c;
int v, w;
@ -443,31 +246,29 @@ TinyGL::Matrix4 Matrix4::rotation(float t, int u) const {
return a;
}
TinyGL::Vector3 Matrix4::transform(const Vector3 &vector) const {
return Vector3(
vector.getX() * get(0,0) + vector.getY() * get(0,1) + vector.getZ() * get(0,2) + get(0,3),
vector.getX() * get(1,0) + vector.getY() * get(1,1) + vector.getZ() * get(1,2) + get(1,3),
vector.getX() * get(2,0) + vector.getY() * get(2,1) + vector.getZ() * get(2,2) + get(2,3));
Vector3 Matrix4::transform(const Vector3 &vector) const {
return Vector3(
vector.getX() * get(0,0) + vector.getY() * get(0,1) + vector.getZ() * get(0,2) + get(0,3),
vector.getX() * get(1,0) + vector.getY() * get(1,1) + vector.getZ() * get(1,2) + get(1,3),
vector.getX() * get(2,0) + vector.getY() * get(2,1) + vector.getZ() * get(2,2) + get(2,3));
}
TinyGL::Vector3 Matrix4::transform3x3( const Vector3 &vector ) const
{
return Vector3(
vector.getX() * get(0,0) + vector.getY() * get(0,1) + vector.getZ() * get(0,2),
vector.getX() * get(1,0) + vector.getY() * get(1,1) + vector.getZ() * get(1,2),
vector.getX() * get(2,0) + vector.getY() * get(2,1) + vector.getZ() * get(2,2));
Vector3 Matrix4::transform3x3(const Vector3 &vector) const {
return Vector3(
vector.getX() * get(0,0) + vector.getY() * get(0,1) + vector.getZ() * get(0,2),
vector.getX() * get(1,0) + vector.getY() * get(1,1) + vector.getZ() * get(1,2),
vector.getX() * get(2,0) + vector.getY() * get(2,1) + vector.getZ() * get(2,2));
}
TinyGL::Vector4 Matrix4::transform(const Vector4 &vector) const {
return Vector4(
vector.getX() * get(0,0) + vector.getY() * get(0,1) + vector.getZ() * get(0,2) + vector.getW() * get(0,3),
vector.getX() * get(1,0) + vector.getY() * get(1,1) + vector.getZ() * get(1,2) + vector.getW() * get(1,3),
vector.getX() * get(2,0) + vector.getY() * get(2,1) + vector.getZ() * get(2,2) + vector.getW() * get(2,3),
vector.getX() * get(3,0) + vector.getY() * get(3,1) + vector.getZ() * get(3,2) + vector.getW() * get(3,3));
Vector4 Matrix4::transform(const Vector4 &vector) const {
return Vector4(
vector.getX() * get(0,0) + vector.getY() * get(0,1) + vector.getZ() * get(0,2) + vector.getW() * get(0,3),
vector.getX() * get(1,0) + vector.getY() * get(1,1) + vector.getZ() * get(1,2) + vector.getW() * get(1,3),
vector.getX() * get(2,0) + vector.getY() * get(2,1) + vector.getZ() * get(2,2) + vector.getW() * get(2,3),
vector.getX() * get(3,0) + vector.getY() * get(3,1) + vector.getZ() * get(3,2) + vector.getW() * get(3,3));
}
bool Matrix4::IsIdentity() const
{
bool Matrix4::IsIdentity() const {
for (int i = 0; i < 4; i++) {
for (int j = 0; j < 4; j++) {
if (i == j) {

View File

@ -20,6 +20,22 @@ public:
void normalize();
float getLength() const { return sqrt(_v[0] * _v[0] + _v[1] * _v[1] + _v[2] * _v[2]); }
static float dot(const Vector3& a, const Vector3& b) {
return a._v[0] * b._v[0] + a._v[1] * b._v[1] + a._v[2] * b._v[2];
}
bool operator==(const Vector3& other) const
{
return _v[0] == other._v[0] && _v[1] == other._v[1] && _v[2] == other._v[2];
}
bool operator!=(const Vector3& other) const
{
return _v[0] != other._v[0] || _v[1] != other._v[1] || _v[2] != other._v[2];
}
Vector3& operator=(const Vector3 &other)
{
memcpy(_v,other._v,sizeof(_v));
@ -28,7 +44,7 @@ public:
Vector3 operator-() const
{
return Vector3(-_v[0],-_v[1],_v[2]);
return Vector3(-_v[0],-_v[1],-_v[2]);
}
Vector3 operator*(float factor) const {
@ -50,17 +66,17 @@ public:
return *this;
}
Vector3& operator+=(float factor) {
_v[0] += factor;
_v[1] += factor;
_v[2] += factor;
Vector3& operator+=(float value) {
_v[0] += value;
_v[1] += value;
_v[2] += value;
return *this;
}
Vector3& operator-=(float factor) {
_v[0] -= factor;
_v[1] -= factor;
_v[2] -= factor;
Vector3& operator-=(float value) {
_v[0] -= value;
_v[1] -= value;
_v[2] -= value;
return *this;
}
private:
@ -70,7 +86,69 @@ private:
class Vector4 {
public:
Vector4();
Vector4(const Vector3& vec, float w);
Vector4(float x, float y, float z, float w);
Vector4& operator=(const Vector4 &other)
{
memcpy(_v,other._v,sizeof(_v));
return *this;
}
bool operator==(const Vector4& other) const
{
return _v[0] == other._v[0] && _v[1] == other._v[1] && _v[2] == other._v[2] && _v[3] == other._v[3];
}
bool operator!=(const Vector4& other) const
{
return _v[0] != other._v[0] || _v[1] != other._v[1] || _v[2] != other._v[2] || _v[3] != other._v[3];
}
Vector4 operator-() const
{
return Vector4(-_v[0],-_v[1],-_v[2],-_v[3]);
}
Vector4 operator*(float factor) const {
return Vector4(_v[0] * factor, _v[1] * factor, _v[2] * factor,_v[3] * factor);
}
Vector4 operator+(const Vector4 &other) const {
return Vector4(_v[0] + other._v[0], _v[1] + other._v[1], _v[2] + other._v[2], _v[3] + other._v[3]);
}
Vector4 operator-(const Vector4 &other) const {
return Vector4(_v[0] - other._v[0], _v[1] - other._v[1], _v[2] - other._v[2], _v[3] - other._v[3]);
}
Vector4& operator*=(float factor) {
_v[0] *= factor;
_v[1] *= factor;
_v[2] *= factor;
_v[3] *= factor;
return *this;
}
Vector4& operator+=(float value) {
_v[0] += value;
_v[1] += value;
_v[2] += value;
_v[3] += value;
return *this;
}
Vector4& operator-=(float value) {
_v[0] -= value;
_v[1] -= value;
_v[2] -= value;
_v[3] -= value;
return *this;
}
Vector3 toVector3() const {
return Vector3(_v[0],_v[1],_v[2]);
}
float getX() const { return _v[0]; }
float getY() const { return _v[1]; }
@ -82,7 +160,6 @@ public:
void setZ(float val) { _v[2] = val; }
void setW(float val) { _v[3] = val; }
private:
float _v[4];
};
@ -138,6 +215,7 @@ public:
}
static Matrix4 identity();
static Matrix4 rotation(float t, int u);
void fill(float val) {
for(int i = 0; i < 4; i++) {
@ -158,7 +236,6 @@ public:
Matrix4 transpose() const;
Matrix4 inverseOrtho() const;
Matrix4 inverse() const;
Matrix4 rotation(float t, int u) const;
Vector3 transform(const Vector3 &vector) const;
Vector3 transform3x3(const Vector3 &vector) const; // Transform the vector as if this were a 3x3 matrix.
@ -167,54 +244,6 @@ private:
float _m[4][4];
};
struct M4 {
float m[4][4];
};
struct M3 {
float m[3][3];
};
struct M34 {
float m[3][4];
};
#define X v[0]
#define Y v[1]
#define Z v[2]
#define W v[3]
struct V3 {
float v[3];
};
struct V4 {
float v[4];
};
void gl_M4_Id(M4 *a); // Done
int gl_M4_IsId(const M4 *a); // Done
void gl_M4_Move(M4 *a, const M4 *b); // Done (= operator)
void gl_MoveV3(V3 *a, const V3 *b); // Done (= operator)
void gl_MulM4V3(V3 *a, const M4 *b, const V3 *c); // Done
void gl_MulM3V3(V3 *a, const M4 *b, const V3 *c); // Done
void gl_M4_MulV4(V4 *a, const M4 *b, const V4 *c); // Done
void gl_M4_InvOrtho(M4 *a, const M4 &b); // Done
void gl_M4_Inv(M4 *a, const M4 *b); // Done
void gl_M4_Mul(M4 *c, const M4 *a, const M4 *b); // Done
void gl_M4_MulLeft(M4 *c, const M4 *a); // Done
void gl_M4_Transpose(M4 *a, const M4 *b); // Done
void gl_M4_Rotate(M4 *c, float t, int u); // Done
int gl_V3_Norm(V3 *a); // Done
V3 gl_V3_New(float x, float y, float z); // Done
V4 gl_V4_New(float x, float y, float z, float w); // Done
int gl_Matrix_Inv(float *r, float *m, int n); // Only for internal use - could be removed.
} // end of namespace TinyGL
#endif