Refactor viewport handling

This commit is contained in:
Luke Benstead 2021-04-25 13:05:56 +01:00
parent 57bb8c65c5
commit 40678836e0
3 changed files with 70 additions and 32 deletions

View File

@ -1075,7 +1075,6 @@ static void light(SubmissionTarget* target) {
VertexExtra* extra = aligned_vector_at(target->extras, 0);
EyeSpaceData* eye_space = (EyeSpaceData*) eye_space_data->data;
_glMatrixLoadModelView();
mat_transform3(vertex->xyz, eye_space->xyz, target->count, sizeof(Vertex), sizeof(EyeSpaceData));
_glMatrixLoadNormal();
@ -1093,8 +1092,20 @@ GL_FORCE_INLINE void divide(SubmissionTarget* target) {
ITERATE(target->count) {
float f = MATH_Fast_Invert(vertex->w);
/* Convert to NDC */
vertex->xyz[0] *= f;
vertex->xyz[1] *= f;
/* Apply viewport */
vertex->xyz[0] = MATH_fmac(
VIEWPORT.hwidth, vertex->xyz[0], VIEWPORT.x_plus_hwidth
);
vertex->xyz[1] = GetVideoMode()->height - MATH_fmac(
VIEWPORT.hheight, vertex->xyz[1], VIEWPORT.y_plus_hheight
);
/* Apply depth range */
vertex->xyz[2] = MAX(
1.0f - MATH_fmac(vertex->xyz[2] * f, 0.5f, 0.5f),
PVR_MIN_Z
@ -1217,15 +1228,33 @@ GL_FORCE_INLINE void submitVertices(GLenum mode, GLsizei first, GLuint count, GL
/* Make room for the vertices and header */
aligned_vector_extend(&target->output->vector, target->count + 1);
_glApplyRenderMatrix(); /* Apply the Render Matrix Stack */
/* If we're lighting, then we need to do some work in
* eye-space, so we only transform vertices by the modelview
* matrix, and then later multiply by projection.
*
* If we're not doing lighting though we can optimise by taking
* vertices straight to clip-space */
if(doLighting) {
_glMatrixLoadModelView();
} else {
_glMatrixLoadModelViewProjection();
}
/* If we're FAST_PATH_ENABLED, then this will do the transform for us */
generate(target, mode, first, count, (GLubyte*) indices, type);
/* No fast path, then we have to do another iteration :( */
if(!FAST_PATH_ENABLED) {
/* Multiply by modelview */
transform(target);
}
if(doLighting){
light(target);
}
if(!FAST_PATH_ENABLED) {
/* OK eye-space work done, now move into clip space */
_glMatrixLoadProjection();
transform(target);
}

View File

@ -13,12 +13,12 @@
GLfloat DEPTH_RANGE_MULTIPLIER_L = (1 - 0) / 2;
GLfloat DEPTH_RANGE_MULTIPLIER_H = (0 + 1) / 2;
/* 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 Matrix4x4 NORMAL_MATRIX __attribute__((aligned(32)));
static Matrix4x4 SCREENVIEW_MATRIX __attribute__((aligned(32)));
Viewport VIEWPORT = {
0, 0, 640, 480, 320.0f, 240.0f, 320.0f, 240.0f
};
static GLenum MATRIX_MODE = GL_MODELVIEW;
static GLubyte MATRIX_IDX = 0;
@ -50,7 +50,6 @@ void _glInitMatrices() {
stack_push(&MATRIX_STACKS[2], IDENTITY);
MEMCPY4(NORMAL_MATRIX, IDENTITY, sizeof(Matrix4x4));
MEMCPY4(SCREENVIEW_MATRIX, IDENTITY, sizeof(Matrix4x4));
const VideoMode* vid_mode = GetVideoMode();
@ -370,22 +369,14 @@ void glMultTransposeMatrixf(const GLfloat *m) {
/* Set the GL viewport */
void APIENTRY glViewport(GLint x, GLint y, GLsizei width, GLsizei height) {
const VideoMode* vid_mode = GetVideoMode();
gl_viewport_x1 = x;
gl_viewport_y1 = y;
gl_viewport_width = width;
gl_viewport_height = height;
GLfloat hw = ((GLfloat) width) / 2.0f;
GLfloat hh = ((GLfloat) height) / 2.0f;
y *= -1; // Flip
SCREENVIEW_MATRIX[M0] = hw;
SCREENVIEW_MATRIX[M5] = -hh;
SCREENVIEW_MATRIX[M10] = 1;
SCREENVIEW_MATRIX[M12] = hw + x;
SCREENVIEW_MATRIX[M13] = vid_mode->height - hh + y;
VIEWPORT.x = x;
VIEWPORT.y = y;
VIEWPORT.width = width;
VIEWPORT.height = height;
VIEWPORT.hwidth = ((GLfloat) VIEWPORT.width) * 0.5f;
VIEWPORT.hheight = ((GLfloat) VIEWPORT.height) * 0.5f;
VIEWPORT.x_plus_hwidth = VIEWPORT.x + VIEWPORT.hwidth;
VIEWPORT.y_plus_hheight = VIEWPORT.y + VIEWPORT.hheight;
}
/* Set the depth range */
@ -468,12 +459,6 @@ void gluLookAt(GLfloat eyex, GLfloat eyey, GLfloat eyez, GLfloat centerx,
DownloadMatrix4x4(stack_top(MATRIX_STACKS + (GL_MODELVIEW & 0xF)));
}
void _glApplyRenderMatrix() {
UploadMatrix4x4((const Matrix4x4*) &SCREENVIEW_MATRIX);
MultiplyMatrix4x4((const Matrix4x4*) stack_top(MATRIX_STACKS + (GL_PROJECTION & 0xF)));
MultiplyMatrix4x4((const Matrix4x4*) stack_top(MATRIX_STACKS + (GL_MODELVIEW & 0xF)));
}
void _glMatrixLoadTexture() {
UploadMatrix4x4((const Matrix4x4*) stack_top(MATRIX_STACKS + (GL_TEXTURE & 0xF)));
}
@ -482,6 +467,15 @@ void _glMatrixLoadModelView() {
UploadMatrix4x4((const Matrix4x4*) stack_top(MATRIX_STACKS + (GL_MODELVIEW & 0xF)));
}
void _glMatrixLoadProjection() {
UploadMatrix4x4((const Matrix4x4*) stack_top(MATRIX_STACKS + (GL_PROJECTION & 0xF)));
}
void _glMatrixLoadModelViewProjection() {
UploadMatrix4x4((const Matrix4x4*) stack_top(MATRIX_STACKS + (GL_PROJECTION & 0xF)));
MultiplyMatrix4x4((const Matrix4x4*) stack_top(MATRIX_STACKS + (GL_MODELVIEW & 0xF)));
}
void _glMatrixLoadNormal() {
UploadMatrix4x4((const Matrix4x4*) &NORMAL_MATRIX);
}

View File

@ -98,6 +98,20 @@ typedef struct {
AlignedVector vector;
} PolyList;
typedef struct {
GLint x;
GLint y;
GLint width;
GLint height;
float x_plus_hwidth;
float y_plus_hheight;
float hwidth; /* width * 0.5f */
float hheight; /* height * 0.5f */
} Viewport;
extern Viewport VIEWPORT;
typedef struct {
/* Palette data is always stored in RAM as RGBA8888 and packed as ARGB8888
* when uploaded to the PVR */
@ -278,8 +292,9 @@ void _glInitFramebuffers();
void _glMatrixLoadNormal();
void _glMatrixLoadModelView();
void _glMatrixLoadProjection();
void _glMatrixLoadTexture();
void _glApplyRenderMatrix();
void _glMatrixLoadModelViewProjection();
extern GLfloat DEPTH_RANGE_MULTIPLIER_L;
extern GLfloat DEPTH_RANGE_MULTIPLIER_H;