Replace the entire matrix stack handling to work towards fixing lighting
This commit is contained in:
parent
4218111ab8
commit
f9cdefcd81
48
GL/draw.c
48
GL/draw.c
|
@ -123,15 +123,36 @@ static void _parseIndex(GLshort* out, const GLubyte* in, GLenum type) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
inline void mat_trans_float3_nodiv(const GLfloat* mat, GLfloat* v) {
|
||||||
|
GLfloat x = v[0] * mat[0] + v[1] * mat[4] + v[2] * mat[8] + mat[12];
|
||||||
|
GLfloat y = v[0] * mat[1] + v[1] * mat[5] + v[2] * mat[9] + mat[13];
|
||||||
|
GLfloat z = v[0] * mat[2] + v[1] * mat[6] + v[2] * mat[10] + mat[14];
|
||||||
|
|
||||||
|
v[0] = x;
|
||||||
|
v[1] = y;
|
||||||
|
v[2] = z;
|
||||||
|
} */
|
||||||
|
|
||||||
|
void transformToEyeSpace(GLfloat* point) {
|
||||||
|
_matrixLoadModelView();
|
||||||
|
mat_trans_single3_nodiv(point[0], point[1], point[2]);
|
||||||
|
}
|
||||||
|
|
||||||
|
void transformNormalToEyeSpace(GLfloat* normal) {
|
||||||
|
_matrixLoadNormal();
|
||||||
|
mat_trans_normal3(normal[0], normal[1], normal[2]);
|
||||||
|
}
|
||||||
|
|
||||||
static void submitVertices(GLenum mode, GLsizei first, GLsizei count, GLenum type, const GLvoid* indices) {
|
static void submitVertices(GLenum mode, GLsizei first, GLsizei count, GLenum type, const GLvoid* indices) {
|
||||||
static float normal[3];
|
static GLfloat normal[3] = {0.0f, 0.0f, -1.0f};
|
||||||
|
static GLfloat eye_P[3];
|
||||||
|
static GLfloat eye_N[3];
|
||||||
|
|
||||||
if(!(ENABLED_VERTEX_ATTRIBUTES & VERTEX_ENABLED_FLAG)) {
|
if(!(ENABLED_VERTEX_ATTRIBUTES & VERTEX_ENABLED_FLAG)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
_glKosMatrixApplyRender(); /* Apply the Render Matrix Stack */
|
|
||||||
|
|
||||||
const GLsizei elements = (mode == GL_QUADS) ? 4 : (mode == GL_TRIANGLES) ? 3 : (mode == GL_LINES) ? 2 : count;
|
const GLsizei elements = (mode == GL_QUADS) ? 4 : (mode == GL_TRIANGLES) ? 3 : (mode == GL_LINES) ? 2 : count;
|
||||||
|
|
||||||
// Make room for the element + the header
|
// Make room for the element + the header
|
||||||
|
@ -185,7 +206,6 @@ static void submitVertices(GLenum mode, GLsizei first, GLsizei count, GLenum typ
|
||||||
}
|
}
|
||||||
|
|
||||||
_parseFloats(&vertex->x, vptr + (idx * vstride), VERTEX_POINTER.size, VERTEX_POINTER.type);
|
_parseFloats(&vertex->x, vptr + (idx * vstride), VERTEX_POINTER.size, VERTEX_POINTER.type);
|
||||||
transformVertex(&vertex->x, &vertex->x, &vertex->y, &vertex->z);
|
|
||||||
|
|
||||||
if(ENABLED_VERTEX_ATTRIBUTES & DIFFUSE_ENABLED_FLAG) {
|
if(ENABLED_VERTEX_ATTRIBUTES & DIFFUSE_ENABLED_FLAG) {
|
||||||
_parseColour(&vertex->argb, cptr + (idx * cstride), DIFFUSE_POINTER.size, DIFFUSE_POINTER.type);
|
_parseColour(&vertex->argb, cptr + (idx * cstride), DIFFUSE_POINTER.size, DIFFUSE_POINTER.type);
|
||||||
|
@ -197,6 +217,9 @@ static void submitVertices(GLenum mode, GLsizei first, GLsizei count, GLenum typ
|
||||||
|
|
||||||
if(ENABLED_VERTEX_ATTRIBUTES & NORMAL_ENABLED_FLAG) {
|
if(ENABLED_VERTEX_ATTRIBUTES & NORMAL_ENABLED_FLAG) {
|
||||||
_parseFloats(normal, nptr + (idx * nstride), NORMAL_POINTER.size, NORMAL_POINTER.type);
|
_parseFloats(normal, nptr + (idx * nstride), NORMAL_POINTER.size, NORMAL_POINTER.type);
|
||||||
|
} else {
|
||||||
|
normal[0] = normal[1] = 0.0f;
|
||||||
|
normal[2] = -1.0f;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(lighting_enabled) {
|
if(lighting_enabled) {
|
||||||
|
@ -205,12 +228,22 @@ static void submitVertices(GLenum mode, GLsizei first, GLsizei count, GLenum typ
|
||||||
GLfloat contribution [] = {0.0f, 0.0f, 0.0f, 0.0f};
|
GLfloat contribution [] = {0.0f, 0.0f, 0.0f, 0.0f};
|
||||||
GLfloat to_add [] = {0.0f, 0.0f, 0.0f, 0.0f};
|
GLfloat to_add [] = {0.0f, 0.0f, 0.0f, 0.0f};
|
||||||
|
|
||||||
/* FIXME!!! Transform the position to eye space */
|
/* Transform the vertex and normal into eye-space */
|
||||||
|
eye_P[0] = vertex->x;
|
||||||
|
eye_P[1] = vertex->y;
|
||||||
|
eye_P[2] = vertex->z;
|
||||||
|
|
||||||
|
eye_N[0] = normal[0];
|
||||||
|
eye_N[1] = normal[1];
|
||||||
|
eye_N[2] = normal[2];
|
||||||
|
|
||||||
|
transformToEyeSpace(eye_P);
|
||||||
|
transformNormalToEyeSpace(eye_N);
|
||||||
|
|
||||||
GLubyte j;
|
GLubyte j;
|
||||||
for(j = 0; j < MAX_LIGHTS; ++j) {
|
for(j = 0; j < MAX_LIGHTS; ++j) {
|
||||||
if(isLightEnabled(i)) {
|
if(isLightEnabled(i)) {
|
||||||
calculateLightingContribution(j, &vertex->x, normal, to_add);
|
calculateLightingContribution(j, eye_P, eye_N, to_add);
|
||||||
|
|
||||||
contribution[0] += to_add[0];
|
contribution[0] += to_add[0];
|
||||||
contribution[1] += to_add[1];
|
contribution[1] += to_add[1];
|
||||||
|
@ -222,6 +255,9 @@ static void submitVertices(GLenum mode, GLsizei first, GLsizei count, GLenum typ
|
||||||
vertex->argb = PVR_PACK_COLOR(contribution[3], contribution[0], contribution[1], contribution[2]);
|
vertex->argb = PVR_PACK_COLOR(contribution[3], contribution[0], contribution[1], contribution[2]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_applyRenderMatrix(); /* Apply the Render Matrix Stack */
|
||||||
|
transformVertex(&vertex->x, &vertex->x, &vertex->y, &vertex->z);
|
||||||
|
|
||||||
++dst;
|
++dst;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -64,12 +64,12 @@ void APIENTRY glKosInit() {
|
||||||
|
|
||||||
_initPVR();
|
_initPVR();
|
||||||
|
|
||||||
|
initMatrices();
|
||||||
initAttributePointers();
|
initAttributePointers();
|
||||||
initContext();
|
initContext();
|
||||||
initLights();
|
initLights();
|
||||||
initImmediateMode();
|
initImmediateMode();
|
||||||
|
|
||||||
_glKosInitMatrix();
|
|
||||||
_glKosInitTextures();
|
_glKosInitTextures();
|
||||||
|
|
||||||
OP_LIST.list_type = PVR_LIST_OP_POLY;
|
OP_LIST.list_type = PVR_LIST_OP_POLY;
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <dc/vec3f.h>
|
||||||
#include "private.h"
|
#include "private.h"
|
||||||
|
|
||||||
static GLfloat SCENE_AMBIENT [] = {0.2, 0.2, 0.2, 1.0};
|
static GLfloat SCENE_AMBIENT [] = {0.2, 0.2, 0.2, 1.0};
|
||||||
|
@ -196,7 +198,69 @@ void APIENTRY glMaterialfv(GLenum face, GLenum pname, const GLfloat *params) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void calculateLightingContribution(const GLint light, const GLfloat* pos, const GLfloat* normal, GLfloat* colour) {
|
inline void initVec3(struct vec3f* v, const GLfloat* src) {
|
||||||
colour[0] = colour[3] = 0.0f;
|
memcpy(v, src, sizeof(GLfloat) * 3);
|
||||||
colour[1] = colour[2] = 0.0f;
|
}
|
||||||
|
|
||||||
|
/* Fast POW Implementation - Less accurate, but much faster than math.h */
|
||||||
|
#define EXP_A 184
|
||||||
|
#define EXP_C 16249
|
||||||
|
|
||||||
|
static float FEXP(float y) {
|
||||||
|
union {
|
||||||
|
float d;
|
||||||
|
struct {
|
||||||
|
short j, i;
|
||||||
|
} n;
|
||||||
|
} eco;
|
||||||
|
eco.n.i = EXP_A * (y) + (EXP_C);
|
||||||
|
eco.n.j = 0;
|
||||||
|
return eco.d;
|
||||||
|
}
|
||||||
|
|
||||||
|
static float FLOG(float y) {
|
||||||
|
int *nTemp = (int *)&y;
|
||||||
|
y = (*nTemp) >> 16;
|
||||||
|
return (y - EXP_C) / EXP_A;
|
||||||
|
}
|
||||||
|
|
||||||
|
static float FPOW(float b, float p) {
|
||||||
|
return FEXP(FLOG(b) * p);
|
||||||
|
}
|
||||||
|
|
||||||
|
void calculateLightingContribution(const GLint light, const GLfloat* pos, const GLfloat* normal, GLfloat* colour) {
|
||||||
|
LightSource* l = &LIGHTS[light];
|
||||||
|
|
||||||
|
struct vec3f L, N, V;
|
||||||
|
|
||||||
|
L.x = l->position[0] - pos[0];
|
||||||
|
L.y = l->position[1] - pos[1];
|
||||||
|
L.z = l->position[2] - pos[2];
|
||||||
|
|
||||||
|
N.x = normal[0];
|
||||||
|
N.y = normal[1];
|
||||||
|
N.z = normal[2];
|
||||||
|
|
||||||
|
V.x = -pos[0];
|
||||||
|
V.y = -pos[1];
|
||||||
|
V.z = -pos[2];
|
||||||
|
|
||||||
|
vec3f_normalize(L.x, L.y, L.z);
|
||||||
|
vec3f_normalize(V.x, V.y, V.z);
|
||||||
|
|
||||||
|
GLfloat LdotN;
|
||||||
|
vec3f_dot(L.x, L.y, L.z, N.x, N.y, N.z, LdotN);
|
||||||
|
|
||||||
|
GLfloat f = (LdotN < 0) ? 0 : 1;
|
||||||
|
|
||||||
|
GLfloat VdotN;
|
||||||
|
vec3f_dot(V.x, V.y, V.z, N.x, N.y, N.z, VdotN);
|
||||||
|
|
||||||
|
GLfloat VdotR = VdotN - LdotN;
|
||||||
|
GLfloat specularPower = FPOW(VdotR > 0 ? VdotR : 0, MATERIAL.exponent);
|
||||||
|
|
||||||
|
colour[0] = l->ambient[0] * MATERIAL.ambient[0] + f * (l->diffuse[0] * MATERIAL.diffuse[0] * LdotN); // + l->specular[0] * MATERIAL.specular[0] * specularPower);
|
||||||
|
colour[1] = l->ambient[1] * MATERIAL.ambient[1] + f * (l->diffuse[1] * MATERIAL.diffuse[1] * LdotN); // + l->specular[1] * MATERIAL.specular[1] * specularPower);
|
||||||
|
colour[2] = l->ambient[2] * MATERIAL.ambient[2] + f * (l->diffuse[2] * MATERIAL.diffuse[2] * LdotN); // + l->specular[2] * MATERIAL.specular[2] * specularPower);
|
||||||
|
colour[3] = MATERIAL.diffuse[3];
|
||||||
}
|
}
|
||||||
|
|
370
GL/matrix.c
Normal file
370
GL/matrix.c
Normal file
|
@ -0,0 +1,370 @@
|
||||||
|
#include <dc/matrix.h>
|
||||||
|
|
||||||
|
#include "../include/gl.h"
|
||||||
|
#include "../containers/stack.h"
|
||||||
|
#include "../gl-sh4.h"
|
||||||
|
|
||||||
|
/* Viewport mapping */
|
||||||
|
static GLfloat gl_viewport_scale[3], gl_viewport_offset[3];
|
||||||
|
|
||||||
|
/* Depth range */
|
||||||
|
static GLclampf gl_depthrange_near, gl_depthrange_far;
|
||||||
|
|
||||||
|
/* Viewport size */
|
||||||
|
static GLint gl_viewport_x1, gl_viewport_y1, gl_viewport_width, gl_viewport_height;
|
||||||
|
|
||||||
|
static Stack MATRIX_STACKS[3]; // modelview, projection, texture
|
||||||
|
static matrix_t NORMAL_MATRIX __attribute__((aligned(32)));
|
||||||
|
static matrix_t SCREENVIEW_MATRIX __attribute__((aligned(32)));
|
||||||
|
static matrix_t RENDER_MATRIX __attribute__((aligned(32)));
|
||||||
|
|
||||||
|
static GLenum MATRIX_MODE = GL_MODELVIEW;
|
||||||
|
static GLubyte MATRIX_IDX = 0;
|
||||||
|
|
||||||
|
static const matrix_t IDENTITY = {
|
||||||
|
{1.0f, 0.0f, 0.0f, 0.0f},
|
||||||
|
{0.0f, 1.0f, 0.0f, 0.0f},
|
||||||
|
{0.0f, 0.0f, 1.0f, 0.0f},
|
||||||
|
{0.0f, 0.0f, 0.0f, 1.0f}
|
||||||
|
};
|
||||||
|
|
||||||
|
void APIENTRY glDepthRange(GLclampf n, GLclampf f);
|
||||||
|
|
||||||
|
void initMatrices() {
|
||||||
|
init_stack(&MATRIX_STACKS[0], sizeof(matrix_t), 32);
|
||||||
|
init_stack(&MATRIX_STACKS[1], sizeof(matrix_t), 32);
|
||||||
|
init_stack(&MATRIX_STACKS[2], sizeof(matrix_t), 32);
|
||||||
|
|
||||||
|
stack_push(&MATRIX_STACKS[0], IDENTITY);
|
||||||
|
stack_push(&MATRIX_STACKS[1], IDENTITY);
|
||||||
|
stack_push(&MATRIX_STACKS[2], IDENTITY);
|
||||||
|
|
||||||
|
memcpy(NORMAL_MATRIX, IDENTITY, sizeof(matrix_t));
|
||||||
|
memcpy(SCREENVIEW_MATRIX, IDENTITY, sizeof(matrix_t));
|
||||||
|
|
||||||
|
glDepthRange(0.0f, 1.0f);
|
||||||
|
glViewport(0, 0, vid_mode->width, vid_mode->height);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void recalculateNormalMatrix() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void APIENTRY glMatrixMode(GLenum mode) {
|
||||||
|
MATRIX_MODE = mode;
|
||||||
|
MATRIX_IDX = mode & 0xF;
|
||||||
|
}
|
||||||
|
|
||||||
|
void APIENTRY glPushMatrix() {
|
||||||
|
stack_push(MATRIX_STACKS + MATRIX_IDX, stack_top(MATRIX_STACKS + MATRIX_IDX));
|
||||||
|
}
|
||||||
|
|
||||||
|
void APIENTRY glPopMatrix() {
|
||||||
|
stack_pop(MATRIX_STACKS + MATRIX_IDX);
|
||||||
|
if(MATRIX_MODE == GL_MODELVIEW) {
|
||||||
|
recalculateNormalMatrix();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void APIENTRY glLoadIdentity() {
|
||||||
|
stack_replace(MATRIX_STACKS + MATRIX_IDX, IDENTITY);
|
||||||
|
}
|
||||||
|
|
||||||
|
void APIENTRY glTranslatef(GLfloat x, GLfloat y, GLfloat z) {
|
||||||
|
mat_load(stack_top(MATRIX_STACKS + MATRIX_IDX));
|
||||||
|
mat_translate(x, y, z);
|
||||||
|
mat_store(stack_top(MATRIX_STACKS + MATRIX_IDX));
|
||||||
|
|
||||||
|
if(MATRIX_MODE == GL_MODELVIEW) {
|
||||||
|
recalculateNormalMatrix();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void APIENTRY glScalef(GLfloat x, GLfloat y, GLfloat z) {
|
||||||
|
mat_load(stack_top(MATRIX_STACKS + MATRIX_IDX));
|
||||||
|
mat_scale(x, y, z);
|
||||||
|
mat_store(stack_top(MATRIX_STACKS + MATRIX_IDX));
|
||||||
|
|
||||||
|
if(MATRIX_MODE == GL_MODELVIEW) {
|
||||||
|
recalculateNormalMatrix();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void APIENTRY glRotatef(GLfloat angle, GLfloat x, GLfloat y, GLfloat z) {
|
||||||
|
float r = DEG2RAD * -angle;
|
||||||
|
|
||||||
|
vec3f_normalize(x, y, z);
|
||||||
|
|
||||||
|
mat_load(stack_top(MATRIX_STACKS + MATRIX_IDX));
|
||||||
|
mat_rotate(r * x, r * y, r * z);
|
||||||
|
mat_store(stack_top(MATRIX_STACKS + MATRIX_IDX));
|
||||||
|
|
||||||
|
if(MATRIX_MODE == GL_MODELVIEW) {
|
||||||
|
recalculateNormalMatrix();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Load an arbitrary matrix */
|
||||||
|
void APIENTRY glLoadMatrixf(const GLfloat *m) {
|
||||||
|
stack_replace(MATRIX_STACKS + MATRIX_IDX, m);
|
||||||
|
|
||||||
|
if(MATRIX_MODE == GL_MODELVIEW) {
|
||||||
|
recalculateNormalMatrix();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Ortho */
|
||||||
|
void APIENTRY glOrtho(GLfloat left, GLfloat right,
|
||||||
|
GLfloat bottom, GLfloat top,
|
||||||
|
GLfloat znear, GLfloat zfar) {
|
||||||
|
|
||||||
|
/* Ortho Matrix */
|
||||||
|
static matrix_t OrthoMatrix __attribute__((aligned(32))) = {
|
||||||
|
{ 0.0f, 0.0f, 0.0f, 0.0f },
|
||||||
|
{ 0.0f, 0.0f, 0.0f, 0.0f },
|
||||||
|
{ 0.0f, 0.0f, 0.0f, 0.0f },
|
||||||
|
{ 0.0f, 0.0f, 0.0f, 1.0f }
|
||||||
|
};
|
||||||
|
|
||||||
|
OrthoMatrix[0][0] = 2.0f / (right - left);
|
||||||
|
OrthoMatrix[1][1] = 2.0f / (top - bottom);
|
||||||
|
OrthoMatrix[2][2] = -2.0f / (zfar - znear);
|
||||||
|
OrthoMatrix[3][0] = -(right + left) / (right - left);;
|
||||||
|
OrthoMatrix[3][1] = -(top + bottom) / (top - bottom);
|
||||||
|
OrthoMatrix[3][2] = -(zfar + znear) / (zfar - znear);
|
||||||
|
|
||||||
|
mat_load(stack_top(MATRIX_STACKS + MATRIX_MODE));
|
||||||
|
mat_apply(&OrthoMatrix);
|
||||||
|
mat_store(stack_top(MATRIX_STACKS + MATRIX_MODE));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Set the GL frustum */
|
||||||
|
void APIENTRY glFrustum(GLfloat left, GLfloat right,
|
||||||
|
GLfloat bottom, GLfloat top,
|
||||||
|
GLfloat znear, GLfloat zfar) {
|
||||||
|
|
||||||
|
/* Frustum Matrix */
|
||||||
|
static matrix_t FrustumMatrix __attribute__((aligned(32))) = {
|
||||||
|
{ 0.0f, 0.0f, 0.0f, 0.0f },
|
||||||
|
{ 0.0f, 0.0f, 0.0f, 0.0f },
|
||||||
|
{ 0.0f, 0.0f, 0.0f, -1.0f },
|
||||||
|
{ 0.0f, 0.0f, 0.0f, 0.0f }
|
||||||
|
};
|
||||||
|
|
||||||
|
FrustumMatrix[0][0] = (2.0f * znear) / (right - left);
|
||||||
|
FrustumMatrix[2][0] = (right + left) / (right - left);
|
||||||
|
FrustumMatrix[1][1] = (2.0f * znear) / (top - bottom);
|
||||||
|
FrustumMatrix[2][1] = (top + bottom) / (top - bottom);
|
||||||
|
FrustumMatrix[2][2] = zfar / (zfar - znear);
|
||||||
|
FrustumMatrix[3][2] = -(zfar * znear) / (zfar - znear);
|
||||||
|
|
||||||
|
mat_load(stack_top(MATRIX_STACKS + MATRIX_IDX));
|
||||||
|
mat_apply(&FrustumMatrix);
|
||||||
|
mat_store(stack_top(MATRIX_STACKS + MATRIX_IDX));
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Set the Perspective */
|
||||||
|
void gluPerspective(GLfloat angle, GLfloat aspect,
|
||||||
|
GLfloat znear, GLfloat zfar) {
|
||||||
|
GLfloat xmin, xmax, ymin, ymax;
|
||||||
|
|
||||||
|
ymax = znear * ftan(angle * F_PI / 360.0f);
|
||||||
|
ymin = -ymax;
|
||||||
|
xmin = ymin * aspect;
|
||||||
|
xmax = ymax * aspect;
|
||||||
|
|
||||||
|
glFrustum(xmin, xmax, ymin, ymax, znear, zfar);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Multiply the current matrix by an arbitrary matrix */
|
||||||
|
void glMultMatrixf(const GLfloat *m) {
|
||||||
|
static matrix_t TEMP __attribute__((aligned(32))) = {
|
||||||
|
{ 1.0f, 0.0f, 0.0f, 0.0f },
|
||||||
|
{ 0.0f, 1.0f, 0.0f, 0.0f },
|
||||||
|
{ 0.0f, 0.0f, 1.0f, 0.0f },
|
||||||
|
{ 0.0f, 0.0f, 0.0f, 1.0f }
|
||||||
|
};
|
||||||
|
|
||||||
|
memcpy(TEMP, m, sizeof(matrix_t));
|
||||||
|
|
||||||
|
mat_load(stack_top(MATRIX_STACKS + MATRIX_IDX));
|
||||||
|
mat_apply(&TEMP);
|
||||||
|
mat_store(stack_top(MATRIX_STACKS + MATRIX_IDX));
|
||||||
|
|
||||||
|
if(MATRIX_MODE == GL_MODELVIEW) {
|
||||||
|
recalculateNormalMatrix();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Load an arbitrary transposed matrix */
|
||||||
|
void glLoadTransposeMatrixf(const GLfloat *m) {
|
||||||
|
stack_replace(MATRIX_STACKS + MATRIX_IDX, m);
|
||||||
|
transpose(stack_top(MATRIX_STACKS + MATRIX_IDX));
|
||||||
|
|
||||||
|
if(MATRIX_MODE == GL_MODELVIEW) {
|
||||||
|
recalculateNormalMatrix();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Multiply the current matrix by an arbitrary transposed matrix */
|
||||||
|
void glMultTransposeMatrixf(const GLfloat *m) {
|
||||||
|
static matrix_t ml;
|
||||||
|
|
||||||
|
ml[0][0] = m[0];
|
||||||
|
ml[0][1] = m[4];
|
||||||
|
ml[0][2] = m[8];
|
||||||
|
ml[0][3] = m[12];
|
||||||
|
ml[1][0] = m[1];
|
||||||
|
ml[1][1] = m[5];
|
||||||
|
ml[1][2] = m[9];
|
||||||
|
ml[1][3] = m[13];
|
||||||
|
ml[2][0] = m[2];
|
||||||
|
ml[2][1] = m[6];
|
||||||
|
ml[2][2] = m[10];
|
||||||
|
ml[2][3] = m[14];
|
||||||
|
ml[3][0] = m[3];
|
||||||
|
ml[3][1] = m[7];
|
||||||
|
ml[3][2] = m[11];
|
||||||
|
ml[3][3] = m[15];
|
||||||
|
|
||||||
|
mat_load(stack_top(MATRIX_STACKS + MATRIX_IDX));
|
||||||
|
mat_apply(&ml);
|
||||||
|
mat_store(stack_top(MATRIX_STACKS + MATRIX_IDX));
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Set the GL viewport */
|
||||||
|
void APIENTRY glViewport(GLint x, GLint y, GLsizei width, GLsizei height) {
|
||||||
|
gl_viewport_x1 = x;
|
||||||
|
gl_viewport_y1 = y;
|
||||||
|
gl_viewport_width = width;
|
||||||
|
gl_viewport_height = height;
|
||||||
|
|
||||||
|
/* Calculate the viewport scale and offset */
|
||||||
|
gl_viewport_scale[0] = (GLfloat)width / 2.0f;
|
||||||
|
gl_viewport_offset[0] = gl_viewport_scale[0] + (GLfloat)x;
|
||||||
|
gl_viewport_scale[1] = (GLfloat)height / 2.0f;
|
||||||
|
gl_viewport_offset[1] = gl_viewport_scale[1] + (GLfloat)y;
|
||||||
|
gl_viewport_scale[2] = (gl_depthrange_far - gl_depthrange_near) / 2.0f;
|
||||||
|
gl_viewport_offset[2] = (gl_depthrange_near + gl_depthrange_far) / 2.0f;
|
||||||
|
|
||||||
|
gl_viewport_offset[2] += 0.0001f;
|
||||||
|
|
||||||
|
/* Set the Screenview Matrix based on the viewport */
|
||||||
|
SCREENVIEW_MATRIX[0][0] = gl_viewport_scale[0];
|
||||||
|
SCREENVIEW_MATRIX[1][1] = -gl_viewport_scale[1];
|
||||||
|
SCREENVIEW_MATRIX[2][2] = 1;
|
||||||
|
SCREENVIEW_MATRIX[3][0] = gl_viewport_offset[0];
|
||||||
|
SCREENVIEW_MATRIX[3][1] = vid_mode->height - gl_viewport_offset[1];
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Set the depth range */
|
||||||
|
void APIENTRY glDepthRange(GLclampf n, GLclampf f) {
|
||||||
|
/* clamp the values... */
|
||||||
|
if(n < 0.0f) n = 0.0f;
|
||||||
|
else if(n > 1.0f) n = 1.0f;
|
||||||
|
|
||||||
|
if(f < 0.0f) f = 0.0f;
|
||||||
|
else if(f > 1.0f) f = 1.0f;
|
||||||
|
|
||||||
|
gl_depthrange_near = n;
|
||||||
|
gl_depthrange_far = f;
|
||||||
|
|
||||||
|
/* Adjust the viewport scale and offset for Z */
|
||||||
|
gl_viewport_scale[2] = ((f - n) / 2.0f);
|
||||||
|
gl_viewport_offset[2] = (n + f) / 2.0f;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Vector Cross Product - Used by glhLookAtf2 */
|
||||||
|
static inline void vec3f_cross(vector3f v1, vector3f v2, vector3f result) {
|
||||||
|
result[0] = v1[1] * v2[2] - v1[2] * v2[1];
|
||||||
|
result[1] = v1[2] * v2[0] - v1[0] * v2[2];
|
||||||
|
result[2] = v1[0] * v2[1] - v1[1] * v2[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
/* glhLookAtf2 adapted from http://www.opengl.org/wiki/GluLookAt_code */
|
||||||
|
void glhLookAtf2(vector3f eyePosition3D,
|
||||||
|
vector3f center3D,
|
||||||
|
vector3f upVector3D) {
|
||||||
|
|
||||||
|
/* Look-At Matrix */
|
||||||
|
static matrix4f MatrixLookAt __attribute__((aligned(32))) = {
|
||||||
|
{ 1.0f, 0.0f, 0.0f, 0.0f },
|
||||||
|
{ 0.0f, 1.0f, 0.0f, 0.0f },
|
||||||
|
{ 0.0f, 0.0f, 1.0f, 0.0f },
|
||||||
|
{ 0.0f, 0.0f, 0.0f, 1.0f }
|
||||||
|
};
|
||||||
|
|
||||||
|
vector3f forward, side, up;
|
||||||
|
|
||||||
|
vec3f_sub_normalize(center3D[0], center3D[1], center3D[2],
|
||||||
|
eyePosition3D[0], eyePosition3D[1], eyePosition3D[2],
|
||||||
|
forward[0], forward[1], forward[2]);
|
||||||
|
|
||||||
|
//Side = forward x up
|
||||||
|
vec3f_cross(forward, upVector3D, side);
|
||||||
|
vec3f_normalize(side[0], side[1], side[2]);
|
||||||
|
|
||||||
|
//Recompute up as: up = side x forward
|
||||||
|
vec3f_cross(side, forward, up);
|
||||||
|
|
||||||
|
MatrixLookAt[0][0] = side[0];
|
||||||
|
MatrixLookAt[1][0] = side[1];
|
||||||
|
MatrixLookAt[2][0] = side[2];
|
||||||
|
MatrixLookAt[3][0] = 0;
|
||||||
|
|
||||||
|
MatrixLookAt[0][1] = up[0];
|
||||||
|
MatrixLookAt[1][1] = up[1];
|
||||||
|
MatrixLookAt[2][1] = up[2];
|
||||||
|
MatrixLookAt[3][1] = 0;
|
||||||
|
|
||||||
|
MatrixLookAt[0][2] = -forward[0];
|
||||||
|
MatrixLookAt[1][2] = -forward[1];
|
||||||
|
MatrixLookAt[2][2] = -forward[2];
|
||||||
|
MatrixLookAt[3][2] = 0;
|
||||||
|
|
||||||
|
MatrixLookAt[0][3] =
|
||||||
|
MatrixLookAt[1][3] =
|
||||||
|
MatrixLookAt[2][3] = 0;
|
||||||
|
MatrixLookAt[3][3] = 1;
|
||||||
|
|
||||||
|
// Does not modify internal Modelview matrix
|
||||||
|
mat_load(&MatrixLookAt);
|
||||||
|
mat_translate(-eyePosition3D[0], -eyePosition3D[1], -eyePosition3D[2]);
|
||||||
|
|
||||||
|
mat_apply(stack_top(MATRIX_STACKS + (GL_MODELVIEW & 0xF)));
|
||||||
|
mat_store(stack_top(MATRIX_STACKS + (GL_MODELVIEW & 0xF)));
|
||||||
|
}
|
||||||
|
|
||||||
|
void gluLookAt(GLfloat eyex, GLfloat eyey, GLfloat eyez, GLfloat centerx,
|
||||||
|
GLfloat centery, GLfloat centerz, GLfloat upx, GLfloat upy,
|
||||||
|
GLfloat upz) {
|
||||||
|
vector3f eye = { eyex, eyey, eyez };
|
||||||
|
vector3f point = { centerx, centery, centerz };
|
||||||
|
vector3f up = { upx, upy, upz };
|
||||||
|
glhLookAtf2(eye, point, up);
|
||||||
|
}
|
||||||
|
|
||||||
|
void _applyRenderMatrix() {
|
||||||
|
mat_load(&SCREENVIEW_MATRIX);
|
||||||
|
mat_apply(stack_top(MATRIX_STACKS + (GL_PROJECTION & 0xF)));
|
||||||
|
mat_apply(stack_top(MATRIX_STACKS + (GL_MODELVIEW & 0xF)));
|
||||||
|
mat_store(&RENDER_MATRIX);
|
||||||
|
}
|
||||||
|
|
||||||
|
void _matrixLoadRender() {
|
||||||
|
mat_load(&RENDER_MATRIX);
|
||||||
|
}
|
||||||
|
|
||||||
|
void _matrixLoadTexture() {
|
||||||
|
mat_load(stack_top(MATRIX_STACKS + (GL_TEXTURE & 0xF)));
|
||||||
|
}
|
||||||
|
|
||||||
|
void _matrixLoadModelView() {
|
||||||
|
mat_load(stack_top(MATRIX_STACKS + (GL_MODELVIEW & 0xF)));
|
||||||
|
}
|
||||||
|
|
||||||
|
void _matrixLoadNormal() {
|
||||||
|
mat_load(&NORMAL_MATRIX);
|
||||||
|
}
|
|
@ -72,6 +72,14 @@ void initAttributePointers();
|
||||||
void initContext();
|
void initContext();
|
||||||
void initLights();
|
void initLights();
|
||||||
void initImmediateMode();
|
void initImmediateMode();
|
||||||
|
void initMatrices();
|
||||||
|
|
||||||
|
void _matrixLoadNormal();
|
||||||
|
void _matrixLoadModelView();
|
||||||
|
void _matrixLoadTexture();
|
||||||
|
void _matrixLoadRender();
|
||||||
|
void _applyRenderMatrix();
|
||||||
|
|
||||||
GLubyte checkImmediateModeInactive(const char* func);
|
GLubyte checkImmediateModeInactive(const char* func);
|
||||||
|
|
||||||
pvr_poly_cxt_t* getPVRContext();
|
pvr_poly_cxt_t* getPVRContext();
|
||||||
|
|
50
containers/stack.h
Normal file
50
containers/stack.h
Normal file
|
@ -0,0 +1,50 @@
|
||||||
|
#ifndef STACK_H
|
||||||
|
#define STACK_H
|
||||||
|
|
||||||
|
#include <malloc.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
unsigned char* data;
|
||||||
|
unsigned int capacity;
|
||||||
|
unsigned int size;
|
||||||
|
unsigned int element_size;
|
||||||
|
} Stack;
|
||||||
|
|
||||||
|
void init_stack(Stack* stack, unsigned int element_size, unsigned int capacity) {
|
||||||
|
stack->size = 0;
|
||||||
|
stack->capacity = capacity;
|
||||||
|
stack->element_size = element_size;
|
||||||
|
stack->data = (unsigned char*) memalign(0x20, element_size * capacity);
|
||||||
|
}
|
||||||
|
|
||||||
|
void* stack_top(Stack* stack) {
|
||||||
|
return &stack->data[(stack->size - 1) * stack->element_size];
|
||||||
|
}
|
||||||
|
|
||||||
|
void* stack_replace(Stack* stack, const void* element) {
|
||||||
|
memcpy(stack->data + ((stack->size - 1) * stack->element_size), element, stack->element_size);
|
||||||
|
return stack_top(stack);
|
||||||
|
}
|
||||||
|
|
||||||
|
void* stack_push(Stack* stack, const void* element) {
|
||||||
|
if(stack->size + 1 == stack->capacity) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
memcpy(stack->data + (stack->size * stack->element_size), element, stack->element_size);
|
||||||
|
stack->size++;
|
||||||
|
|
||||||
|
return stack_top(stack);
|
||||||
|
}
|
||||||
|
|
||||||
|
void stack_pop(Stack* stack) {
|
||||||
|
if(stack->size == 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
stack->size--;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#endif // STACK_H
|
|
@ -362,8 +362,3 @@ void _glKosVertexComputeLighting(pvr_vertex_t *v, int verts) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void _glKosLightTransformScreenSpace(float *xyz) {
|
|
||||||
_glKosMatrixApplyScreenSpace();
|
|
||||||
mat_trans_single(xyz[0], xyz[1], xyz[2]);
|
|
||||||
_glKosMatrixLoadRender();
|
|
||||||
}
|
|
||||||
|
|
413
gl-matrix.c
413
gl-matrix.c
|
@ -1,413 +0,0 @@
|
||||||
/* KallistiGL for KallistiOS ##version##
|
|
||||||
|
|
||||||
libgl/gl-matrix.c
|
|
||||||
Copyright (C) 2013-2014 Josh Pearson
|
|
||||||
Copyright (C) 2014 Lawrence Sebald
|
|
||||||
|
|
||||||
Some functionality adapted from the original KOS libgl:
|
|
||||||
Copyright (C) 2001 Dan Potter
|
|
||||||
|
|
||||||
The GL matrix operations use the KOS SH4 matrix operations.
|
|
||||||
Basically, we keep two seperate matrix stacks:
|
|
||||||
1.) Internal GL API Matrix Stack ( screenview, modelview, etc. ) ( fixed stack size )
|
|
||||||
2.) External Matrix Stack for client to push / pop ( size of each stack is determined by MAX_MATRICES )
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <string.h>
|
|
||||||
|
|
||||||
#include "gl.h"
|
|
||||||
#include "glu.h"
|
|
||||||
#include "gl-api.h"
|
|
||||||
#include "gl-sh4.h"
|
|
||||||
|
|
||||||
/* This Matrix contains the GL Base Stack */
|
|
||||||
static matrix4f Matrix[GL_MATRIX_COUNT] __attribute__((aligned(32)));
|
|
||||||
static GLsizei MatrixMode = 0;
|
|
||||||
|
|
||||||
/* This Matrix contains the GL Push/Pop Stack ( fixed size per mode, 32 matrices )*/
|
|
||||||
static const GLsizei MAX_MATRICES = 32;
|
|
||||||
static matrix4f MatrixStack[GL_MATRIX_COUNT][32] __attribute__((aligned(32)));
|
|
||||||
static GLsizei MatrixStackPos[GL_MATRIX_COUNT];
|
|
||||||
|
|
||||||
/* Viewport mapping */
|
|
||||||
static GLfloat gl_viewport_scale[3], gl_viewport_offset[3];
|
|
||||||
|
|
||||||
/* Depth range */
|
|
||||||
static GLclampf gl_depthrange_near, gl_depthrange_far;
|
|
||||||
|
|
||||||
/* Viewport size */
|
|
||||||
static GLint gl_viewport_x1, gl_viewport_y1, gl_viewport_width, gl_viewport_height;
|
|
||||||
|
|
||||||
/* Frustum attributes */
|
|
||||||
typedef struct {
|
|
||||||
float left, right, bottom, top, znear, zfar;
|
|
||||||
} gl_frustum_t;
|
|
||||||
|
|
||||||
static gl_frustum_t gl_frustum;
|
|
||||||
|
|
||||||
/* Frustum Matrix */
|
|
||||||
static matrix4f FrustumMatrix __attribute__((aligned(32))) = {
|
|
||||||
{ 0.0f, 0.0f, 0.0f, 0.0f },
|
|
||||||
{ 0.0f, 0.0f, 0.0f, 0.0f },
|
|
||||||
{ 0.0f, 0.0f, 0.0f, -1.0f },
|
|
||||||
{ 0.0f, 0.0f, 0.0f, 0.0f }
|
|
||||||
};
|
|
||||||
|
|
||||||
/* Ortho Matrix */
|
|
||||||
static matrix4f OrthoMatrix __attribute__((aligned(32))) = {
|
|
||||||
{ 0.0f, 0.0f, 0.0f, 0.0f },
|
|
||||||
{ 0.0f, 0.0f, 0.0f, 0.0f },
|
|
||||||
{ 0.0f, 0.0f, 0.0f, 0.0f },
|
|
||||||
{ 0.0f, 0.0f, 0.0f, 1.0f }
|
|
||||||
};
|
|
||||||
|
|
||||||
/* Matrix for user to submit externally, ensure 32byte allignment */
|
|
||||||
static matrix4f ml __attribute__((aligned(32)));
|
|
||||||
|
|
||||||
/* Look-At Matrix */
|
|
||||||
static matrix4f MatrixLookAt __attribute__((aligned(32))) = {
|
|
||||||
{ 1.0f, 0.0f, 0.0f, 0.0f },
|
|
||||||
{ 0.0f, 1.0f, 0.0f, 0.0f },
|
|
||||||
{ 0.0f, 0.0f, 1.0f, 0.0f },
|
|
||||||
{ 0.0f, 0.0f, 0.0f, 1.0f }
|
|
||||||
};
|
|
||||||
|
|
||||||
/* Modelview Rotation Matrix - Applied to Vertex Normal when Lighting is Enabled */
|
|
||||||
static matrix4f MatrixMdlRot __attribute__((aligned(32))) = {
|
|
||||||
{ 1.0f, 0.0f, 0.0f, 0.0f },
|
|
||||||
{ 0.0f, 1.0f, 0.0f, 0.0f },
|
|
||||||
{ 0.0f, 0.0f, 1.0f, 0.0f },
|
|
||||||
{ 0.0f, 0.0f, 0.0f, 1.0f }
|
|
||||||
};
|
|
||||||
|
|
||||||
void glMatrixMode(GLenum mode) {
|
|
||||||
if(mode >= GL_SCREENVIEW && mode <= GL_IDENTITY)
|
|
||||||
MatrixMode = mode;
|
|
||||||
}
|
|
||||||
|
|
||||||
void glPushMatrix() {
|
|
||||||
if(MatrixStackPos[MatrixMode] < MAX_MATRICES - 1) {
|
|
||||||
mat_load(Matrix + MatrixMode);
|
|
||||||
mat_store(&MatrixStack[MatrixMode][MatrixStackPos[MatrixMode]]);
|
|
||||||
++MatrixStackPos[MatrixMode];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void glPopMatrix() {
|
|
||||||
if(MatrixStackPos[MatrixMode]) {
|
|
||||||
--MatrixStackPos[MatrixMode];
|
|
||||||
mat_load(&MatrixStack[MatrixMode][MatrixStackPos[MatrixMode]]);
|
|
||||||
mat_store(Matrix + MatrixMode);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void glLoadIdentity() {
|
|
||||||
mat_load(Matrix + GL_IDENTITY);
|
|
||||||
mat_store(Matrix + MatrixMode);
|
|
||||||
|
|
||||||
if(MatrixMode == GL_MODELVIEW) {
|
|
||||||
mat_store(&MatrixMdlRot);
|
|
||||||
mat_store(&MatrixLookAt);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void glTranslatef(GLfloat x, GLfloat y, GLfloat z) {
|
|
||||||
mat_load(Matrix + MatrixMode);
|
|
||||||
mat_translate(x, y, z);
|
|
||||||
mat_store(Matrix + MatrixMode);
|
|
||||||
}
|
|
||||||
|
|
||||||
void glScalef(GLfloat x, GLfloat y, GLfloat z) {
|
|
||||||
mat_load(Matrix + MatrixMode);
|
|
||||||
mat_scale(x, y, z);
|
|
||||||
mat_store(Matrix + MatrixMode);
|
|
||||||
}
|
|
||||||
|
|
||||||
void glRotatef(GLfloat angle, GLfloat x, GLfloat y, GLfloat z) {
|
|
||||||
float r = DEG2RAD * -angle;
|
|
||||||
|
|
||||||
vec3f_normalize(x, y, z);
|
|
||||||
|
|
||||||
mat_load(Matrix + MatrixMode);
|
|
||||||
mat_rotate(r * x, r * y, r * z);
|
|
||||||
mat_store(Matrix + MatrixMode);
|
|
||||||
|
|
||||||
if(MatrixMode == GL_MODELVIEW) {
|
|
||||||
mat_load(&MatrixMdlRot);
|
|
||||||
mat_rotate(r * x, r * y, r * z);
|
|
||||||
mat_store(&MatrixMdlRot);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Load an arbitrary matrix */
|
|
||||||
void glLoadMatrixf(const GLfloat *m) {
|
|
||||||
memcpy(ml, m, sizeof(matrix4f));
|
|
||||||
mat_load(&ml);
|
|
||||||
mat_store(Matrix + MatrixMode);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Load an arbitrary transposed matrix */
|
|
||||||
void glLoadTransposeMatrixf(const GLfloat *m) {
|
|
||||||
ml[0][0] = m[0];
|
|
||||||
ml[0][1] = m[4];
|
|
||||||
ml[0][2] = m[8];
|
|
||||||
ml[0][3] = m[12];
|
|
||||||
ml[1][0] = m[1];
|
|
||||||
ml[1][1] = m[5];
|
|
||||||
ml[1][2] = m[9];
|
|
||||||
ml[1][3] = m[13];
|
|
||||||
ml[2][0] = m[2];
|
|
||||||
ml[2][1] = m[6];
|
|
||||||
ml[2][2] = m[10];
|
|
||||||
ml[2][3] = m[14];
|
|
||||||
ml[3][0] = m[3];
|
|
||||||
ml[3][1] = m[7];
|
|
||||||
ml[3][2] = m[11];
|
|
||||||
ml[3][3] = m[15];
|
|
||||||
|
|
||||||
mat_load(&ml);
|
|
||||||
mat_store(Matrix + MatrixMode);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Multiply the current matrix by an arbitrary matrix */
|
|
||||||
void glMultMatrixf(const GLfloat *m) {
|
|
||||||
memcpy(ml, m, sizeof(matrix4f));
|
|
||||||
mat_load(Matrix + MatrixMode);
|
|
||||||
mat_apply(&ml);
|
|
||||||
mat_store(Matrix + MatrixMode);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Multiply the current matrix by an arbitrary transposed matrix */
|
|
||||||
void glMultTransposeMatrixf(const GLfloat *m) {
|
|
||||||
ml[0][0] = m[0];
|
|
||||||
ml[0][1] = m[4];
|
|
||||||
ml[0][2] = m[8];
|
|
||||||
ml[0][3] = m[12];
|
|
||||||
ml[1][0] = m[1];
|
|
||||||
ml[1][1] = m[5];
|
|
||||||
ml[1][2] = m[9];
|
|
||||||
ml[1][3] = m[13];
|
|
||||||
ml[2][0] = m[2];
|
|
||||||
ml[2][1] = m[6];
|
|
||||||
ml[2][2] = m[10];
|
|
||||||
ml[2][3] = m[14];
|
|
||||||
ml[3][0] = m[3];
|
|
||||||
ml[3][1] = m[7];
|
|
||||||
ml[3][2] = m[11];
|
|
||||||
ml[3][3] = m[15];
|
|
||||||
|
|
||||||
mat_load(Matrix + MatrixMode);
|
|
||||||
mat_apply(&ml);
|
|
||||||
mat_store(Matrix + MatrixMode);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Set the depth range */
|
|
||||||
void glDepthRange(GLclampf n, GLclampf f) {
|
|
||||||
/* clamp the values... */
|
|
||||||
if(n < 0.0f) n = 0.0f;
|
|
||||||
else if(n > 1.0f) n = 1.0f;
|
|
||||||
|
|
||||||
if(f < 0.0f) f = 0.0f;
|
|
||||||
else if(f > 1.0f) f = 1.0f;
|
|
||||||
|
|
||||||
gl_depthrange_near = n;
|
|
||||||
gl_depthrange_far = f;
|
|
||||||
|
|
||||||
/* Adjust the viewport scale and offset for Z */
|
|
||||||
gl_viewport_scale[2] = ((f - n) / 2.0f);
|
|
||||||
gl_viewport_offset[2] = (n + f) / 2.0f;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Set the GL viewport */
|
|
||||||
void glViewport(GLint x, GLint y, GLsizei width, GLsizei height) {
|
|
||||||
gl_viewport_x1 = x;
|
|
||||||
gl_viewport_y1 = y;
|
|
||||||
gl_viewport_width = width;
|
|
||||||
gl_viewport_height = height;
|
|
||||||
|
|
||||||
/* Calculate the viewport scale and offset */
|
|
||||||
gl_viewport_scale[0] = (GLfloat)width / 2.0f;
|
|
||||||
gl_viewport_offset[0] = gl_viewport_scale[0] + (GLfloat)x;
|
|
||||||
gl_viewport_scale[1] = (GLfloat)height / 2.0f;
|
|
||||||
gl_viewport_offset[1] = gl_viewport_scale[1] + (GLfloat)y;
|
|
||||||
gl_viewport_scale[2] = (gl_depthrange_far - gl_depthrange_near) / 2.0f;
|
|
||||||
gl_viewport_offset[2] = (gl_depthrange_near + gl_depthrange_far) / 2.0f;
|
|
||||||
|
|
||||||
gl_viewport_offset[2] += 0.0001f;
|
|
||||||
|
|
||||||
/* Set the Screenview Matrix based on the viewport */
|
|
||||||
Matrix[GL_SCREENVIEW][0][0] = gl_viewport_scale[0];
|
|
||||||
Matrix[GL_SCREENVIEW][1][1] = -gl_viewport_scale[1];
|
|
||||||
Matrix[GL_SCREENVIEW][2][2] = 1;
|
|
||||||
Matrix[GL_SCREENVIEW][3][0] = gl_viewport_offset[0];
|
|
||||||
Matrix[GL_SCREENVIEW][3][1] = vid_mode->height - gl_viewport_offset[1];
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Set the GL frustum */
|
|
||||||
void glFrustum(GLfloat left, GLfloat right,
|
|
||||||
GLfloat bottom, GLfloat top,
|
|
||||||
GLfloat znear, GLfloat zfar) {
|
|
||||||
gl_frustum.left = left;
|
|
||||||
gl_frustum.right = right;
|
|
||||||
gl_frustum.bottom = bottom;
|
|
||||||
gl_frustum.top = top;
|
|
||||||
gl_frustum.znear = znear;
|
|
||||||
gl_frustum.zfar = zfar;
|
|
||||||
|
|
||||||
FrustumMatrix[0][0] = (2.0f * znear) / (right - left);
|
|
||||||
FrustumMatrix[2][0] = (right + left) / (right - left);
|
|
||||||
FrustumMatrix[1][1] = (2.0f * znear) / (top - bottom);
|
|
||||||
FrustumMatrix[2][1] = (top + bottom) / (top - bottom);
|
|
||||||
FrustumMatrix[2][2] = zfar / (zfar - znear);
|
|
||||||
FrustumMatrix[3][2] = -(zfar * znear) / (zfar - znear);
|
|
||||||
|
|
||||||
mat_load(Matrix + MatrixMode);
|
|
||||||
mat_apply(&FrustumMatrix);
|
|
||||||
mat_store(Matrix + MatrixMode);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Ortho */
|
|
||||||
void glOrtho(GLfloat left, GLfloat right,
|
|
||||||
GLfloat bottom, GLfloat top,
|
|
||||||
GLfloat znear, GLfloat zfar) {
|
|
||||||
OrthoMatrix[0][0] = 2.0f / (right - left);
|
|
||||||
OrthoMatrix[1][1] = 2.0f / (top - bottom);
|
|
||||||
OrthoMatrix[2][2] = -2.0f / (zfar - znear);
|
|
||||||
OrthoMatrix[3][0] = -(right + left) / (right - left);;
|
|
||||||
OrthoMatrix[3][1] = -(top + bottom) / (top - bottom);
|
|
||||||
OrthoMatrix[3][2] = -(zfar + znear) / (zfar - znear);
|
|
||||||
|
|
||||||
mat_load(Matrix + MatrixMode);
|
|
||||||
mat_apply(&OrthoMatrix);
|
|
||||||
mat_store(Matrix + MatrixMode);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Set the Perspective */
|
|
||||||
void gluPerspective(GLfloat angle, GLfloat aspect,
|
|
||||||
GLfloat znear, GLfloat zfar) {
|
|
||||||
GLfloat xmin, xmax, ymin, ymax;
|
|
||||||
|
|
||||||
ymax = znear * ftan(angle * F_PI / 360.0f);
|
|
||||||
ymin = -ymax;
|
|
||||||
xmin = ymin * aspect;
|
|
||||||
xmax = ymax * aspect;
|
|
||||||
|
|
||||||
glFrustum(xmin, xmax, ymin, ymax, znear, zfar);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Vector Cross Product - Used by glhLookAtf2 */
|
|
||||||
void vec3f_cross(vector3f v1, vector3f v2, vector3f result) {
|
|
||||||
result[0] = v1[1] * v2[2] - v1[2] * v2[1];
|
|
||||||
result[1] = v1[2] * v2[0] - v1[0] * v2[2];
|
|
||||||
result[2] = v1[0] * v2[1] - v1[1] * v2[0];
|
|
||||||
}
|
|
||||||
|
|
||||||
/* glhLookAtf2 adapted from http://www.opengl.org/wiki/GluLookAt_code */
|
|
||||||
void glhLookAtf2(vector3f eyePosition3D,
|
|
||||||
vector3f center3D,
|
|
||||||
vector3f upVector3D) {
|
|
||||||
vector3f forward, side, up;
|
|
||||||
|
|
||||||
_glKosSetEyePosition(eyePosition3D);
|
|
||||||
|
|
||||||
vec3f_sub_normalize(center3D[0], center3D[1], center3D[2],
|
|
||||||
eyePosition3D[0], eyePosition3D[1], eyePosition3D[2],
|
|
||||||
forward[0], forward[1], forward[2]);
|
|
||||||
|
|
||||||
//Side = forward x up
|
|
||||||
vec3f_cross(forward, upVector3D, side);
|
|
||||||
vec3f_normalize(side[0], side[1], side[2]);
|
|
||||||
|
|
||||||
//Recompute up as: up = side x forward
|
|
||||||
vec3f_cross(side, forward, up);
|
|
||||||
|
|
||||||
MatrixLookAt[0][0] = side[0];
|
|
||||||
MatrixLookAt[1][0] = side[1];
|
|
||||||
MatrixLookAt[2][0] = side[2];
|
|
||||||
MatrixLookAt[3][0] = 0;
|
|
||||||
|
|
||||||
MatrixLookAt[0][1] = up[0];
|
|
||||||
MatrixLookAt[1][1] = up[1];
|
|
||||||
MatrixLookAt[2][1] = up[2];
|
|
||||||
MatrixLookAt[3][1] = 0;
|
|
||||||
|
|
||||||
MatrixLookAt[0][2] = -forward[0];
|
|
||||||
MatrixLookAt[1][2] = -forward[1];
|
|
||||||
MatrixLookAt[2][2] = -forward[2];
|
|
||||||
MatrixLookAt[3][2] = 0;
|
|
||||||
|
|
||||||
MatrixLookAt[0][3] =
|
|
||||||
MatrixLookAt[1][3] =
|
|
||||||
MatrixLookAt[2][3] = 0;
|
|
||||||
MatrixLookAt[3][3] = 1;
|
|
||||||
|
|
||||||
// Does not modify internal Modelview matrix
|
|
||||||
mat_load(&MatrixLookAt);
|
|
||||||
mat_translate(-eyePosition3D[0], -eyePosition3D[1], -eyePosition3D[2]);
|
|
||||||
|
|
||||||
mat_apply(Matrix + GL_MODELVIEW);
|
|
||||||
mat_store(Matrix + GL_MODELVIEW);
|
|
||||||
}
|
|
||||||
|
|
||||||
void gluLookAt(GLfloat eyex, GLfloat eyey, GLfloat eyez, GLfloat centerx,
|
|
||||||
GLfloat centery, GLfloat centerz, GLfloat upx, GLfloat upy,
|
|
||||||
GLfloat upz) {
|
|
||||||
vector3f eye = { eyex, eyey, eyez };
|
|
||||||
vector3f point = { centerx, centery, centerz };
|
|
||||||
vector3f up = { upx, upy, upz };
|
|
||||||
glhLookAtf2(eye, point, up);
|
|
||||||
}
|
|
||||||
|
|
||||||
void _glKosMatrixApplyRender() {
|
|
||||||
mat_load(Matrix + GL_SCREENVIEW);
|
|
||||||
mat_apply(Matrix + GL_PROJECTION);
|
|
||||||
mat_apply(Matrix + GL_MODELVIEW);
|
|
||||||
mat_store(Matrix + GL_RENDER);
|
|
||||||
}
|
|
||||||
|
|
||||||
void _glKosMatrixLoadRender() {
|
|
||||||
mat_load(Matrix + GL_RENDER);
|
|
||||||
}
|
|
||||||
|
|
||||||
void _glKosMatrixLoadTexture() {
|
|
||||||
mat_load(Matrix + GL_TEXTURE);
|
|
||||||
}
|
|
||||||
|
|
||||||
void _glKosMatrixLoadModelView() {
|
|
||||||
mat_load(Matrix + GL_MODELVIEW);
|
|
||||||
}
|
|
||||||
|
|
||||||
void _glKosMatrixLoadModelRot() {
|
|
||||||
mat_load(&MatrixMdlRot);
|
|
||||||
}
|
|
||||||
|
|
||||||
void _glKosMatrixApplyScreenSpace() {
|
|
||||||
mat_load(Matrix + GL_SCREENVIEW);
|
|
||||||
mat_apply(Matrix + GL_PROJECTION);
|
|
||||||
mat_apply(&MatrixLookAt);
|
|
||||||
}
|
|
||||||
|
|
||||||
void _glKosInitMatrix() {
|
|
||||||
mat_identity();
|
|
||||||
mat_store(Matrix + GL_SCREENVIEW);
|
|
||||||
mat_store(Matrix + GL_PROJECTION);
|
|
||||||
mat_store(Matrix + GL_MODELVIEW);
|
|
||||||
mat_store(Matrix + GL_TEXTURE);
|
|
||||||
mat_store(Matrix + GL_IDENTITY);
|
|
||||||
mat_store(Matrix + GL_RENDER);
|
|
||||||
|
|
||||||
int i;
|
|
||||||
|
|
||||||
for(i = 0; i < GL_MATRIX_COUNT; i++)
|
|
||||||
MatrixStackPos[i] = 0;
|
|
||||||
|
|
||||||
glDepthRange(0.0f, 1.0f);
|
|
||||||
glViewport(0, 0, vid_mode->width, vid_mode->height);
|
|
||||||
}
|
|
||||||
|
|
||||||
void glKosGetMatrix(GLenum mode, GLfloat *params) {
|
|
||||||
if(mode < GL_SCREENVIEW || mode > GL_RENDER)
|
|
||||||
*params = (GLfloat)GL_INVALID_ENUM;
|
|
||||||
|
|
||||||
memcpy(params, Matrix + mode, sizeof(GLfloat) * 16);
|
|
||||||
}
|
|
10
include/gl.h
10
include/gl.h
|
@ -56,13 +56,9 @@ __BEGIN_DECLS
|
||||||
|
|
||||||
/* Matrix modes */
|
/* Matrix modes */
|
||||||
#define GL_MATRIX_MODE 0x0BA0
|
#define GL_MATRIX_MODE 0x0BA0
|
||||||
#define GL_SCREENVIEW 0x00
|
#define GL_MODELVIEW 0x1700
|
||||||
#define GL_MODELVIEW 0x01
|
#define GL_PROJECTION 0x1701
|
||||||
#define GL_PROJECTION 0x02
|
#define GL_TEXTURE 0x1702
|
||||||
#define GL_TEXTURE 0x03
|
|
||||||
#define GL_IDENTITY 0x04
|
|
||||||
#define GL_RENDER 0x05
|
|
||||||
#define GL_MATRIX_COUNT 0x06
|
|
||||||
|
|
||||||
#define GL_MODELVIEW_MATRIX 0x0BA6
|
#define GL_MODELVIEW_MATRIX 0x0BA6
|
||||||
#define GL_PROJECTION_MATRIX 0x0BA7
|
#define GL_PROJECTION_MATRIX 0x0BA7
|
||||||
|
|
Loading…
Reference in New Issue
Block a user