Permalink
Browse files

Add an adjustment to each matrix. This allows a scale/translate to be

applied to each matrix before it is loaded into hardware.  This is useful
for implementing flipped textures, and also to deal with the difference
between OpenGL and PSP in interpreting integer vertex and texture coords
(OpenGL treats them as plain integers, PSP treats them as -1 - 1).
  • Loading branch information...
1 parent 7fe2a0d commit 6720419c973c79c7d3fc062d900e256e0d7ae9a9 jsgf committed Feb 18, 2006
Showing with 133 additions and 13 deletions.
  1. +4 −1 eglCreateContext.c
  2. +6 −0 glTexCoordPointer.c
  3. +6 −0 glVertexPointer.c
  4. +107 −5 pspgl_context.c
  5. +6 −0 pspgl_internal.h
  6. +4 −7 pspgl_texobj.c
View
@@ -20,12 +20,15 @@ static GLboolean init_matrix_stack(struct pspgl_matrix_stack *mstk, int limit, u
mstk->depth = 0;
mstk->flags = flags | MF_DIRTY;
+ mstk->scale[0] = mstk->scale[1] = mstk->scale[2] = mstk->scale[3] = 1.0f;
+ mstk->trans[0] = mstk->trans[1] = mstk->trans[2] = mstk->trans[3] = 0.0f;
+
return GL_TRUE;
}
EGLContext eglCreateContext (EGLDisplay dpy, EGLConfig config, EGLContext share_context, const EGLint *attrib_list)
{
- struct pspgl_context *ctx = malloc(sizeof(struct pspgl_context));
+ struct pspgl_context *ctx = memalign(VFPU_ALIGNMENT, sizeof(struct pspgl_context));
if (!ctx)
goto out_error;
View
@@ -28,6 +28,12 @@ void glTexCoordPointer (GLint size, GLenum type, GLsizei stride, const GLvoid *p
pointer, __pspgl_bufferobj_deref(pspgl_curctx->vertex_array.arraybuffer, (void *)pointer),
size, type, stride, native);
+ /* If we're changed vertex formats, then mark the texture
+ matrix as dirty, so that any adjustment for this format can
+ be applied. */
+ if (va->type != type)
+ pspgl_curctx->texture_stack.flags |= MF_DIRTY;
+
va->size = size;
va->type = type;
va->stride = stride;
View
@@ -27,6 +27,12 @@ void glVertexPointer (GLint size, GLenum type, GLsizei stride, const GLvoid *poi
pointer, __pspgl_bufferobj_deref(pspgl_curctx->vertex_array.arraybuffer, (void *)pointer),
size, type, stride, native);
+ /* If we're changed vertex formats, then mark the modelview matrix
+ as dirty, so that any adjustment for this format can be
+ applied. */
+ if (va->type != type)
+ pspgl_curctx->modelview_stack.flags |= MF_DIRTY;
+
va->size = size;
va->type = type;
va->stride = stride;
View
@@ -17,7 +17,6 @@ void __pspgl_context_writereg (struct pspgl_context *c, uint32_t cmd,
}
}
-
void __pspgl_context_writereg_masked (struct pspgl_context *c, uint32_t cmd,
uint32_t argi, uint32_t mask)
{
@@ -85,6 +84,7 @@ static void flush_matrix(struct pspgl_context *c, unsigned opcode, int index,
struct pspgl_matrix_stack *stk)
{
const GLfloat *m;
+ GLfloat adjusted[16];
if (!(stk->flags & MF_DIRTY))
return;
@@ -98,6 +98,45 @@ static void flush_matrix(struct pspgl_context *c, unsigned opcode, int index,
m = stk->stack[stk->depth].mat;
}
+ if (stk->flags & MF_ADJUST) {
+ /* Apply adjustment to the matrix. This is used for
+ scaling OpenGL integral vertex and texcoord data to
+ PSP integral vertex/texture coords (OpenGL
+ interprets them as literal integers, but the PSP
+ treats them as being in the range [-1, 1]). Also
+ used for flipping inverted textures. */
+ pspvfpu_use_matrices(c->vfpu_context, 0, VMAT4 | VMAT5 | VMAT6);
+
+ asm volatile("vmzero.t m500\n"
+
+ /* original matrix */
+ "lv.q c600, 0 + %3\n"
+ "lv.q c610, 16 + %3\n"
+ "lv.q c620, 32 + %3\n"
+ "lv.q c630, 48 + %3\n"
+
+ /* translate */
+ "lv.q c530, 0 + %2\n"
+
+ /* scale - doesn't seem to be a way of
+ loading a diagonal in one go... */
+ "lv.s s500, 0 + %1\n"
+ "lv.s s511, 4 + %1\n"
+ "lv.s s522, 8 + %1\n"
+
+ "vidt.q r503\n"
+
+ "vmmul.q m400, m600, m500\n"
+
+ "usv.q c400, 0 + %0\n"
+ "usv.q c410, 16 + %0\n"
+ "usv.q c420, 32 + %0\n"
+ "usv.q c430, 48 + %0\n"
+ : "=m" (adjusted) : "m" (stk->scale[0]), "m" (stk->trans[0]), "m" (m[0]));
+
+ m = adjusted;
+ }
+
/*
Different matrices skip different rows:
PROJ is a full 4x4 projective matrix
@@ -206,11 +245,74 @@ void __pspgl_context_render_setup(struct pspgl_context *c, unsigned vtxfmt,
}
}
- if (c->texture_stack.stack[c->texture_stack.depth].flags & MF_IDENTITY)
- __pspgl_context_writereg(c, CMD_TEXMAPMODE, (GE_UV << 8) | GE_TEXTURE_COORDS);
- else
- __pspgl_context_writereg(c, CMD_TEXMAPMODE, (GE_UV << 8) | GE_TEXTURE_MATRIX);
+ __pspgl_context_writereg(c, CMD_TEXMAPMODE, (GE_UV << 8) | GE_TEXTURE_MATRIX);
+
+ /* If we're using an integral texcoord format (byte or
+ short), then we need to add a scaling factor. GL
+ interprets the texcoord as a simple integer,
+ whereas the PSP treats it as number scaled (-1, 1).
+
+ This is combined with flipping for flipped textures.
+ */
+ {
+ struct pspgl_matrix_stack *tm = &c->texture_stack;
+ float su = 1.f, sv = 1.f;
+ float tu = 0.f, tv = 0.f;
+
+ switch(vtxfmt & GE_TEXTURE_SHIFT(3)) {
+ case GE_TEXTURE_8BIT:
+ su = 127.f;
+ sv = 127.f;
+ break;
+
+ case GE_TEXTURE_16BIT:
+ su = 32767.f;
+ sv = 32767.f;
+ break;
+ }
+
+ if (tobj->flags & TOF_FLIPPED) {
+ sv = -sv;
+ tv = 1.f;
+ }
+
+ tm->flags &= ~MF_ADJUST;
+ if (su != 1 || sv != 1 || tu != 0 || tv != 0) {
+ tm->flags |= MF_ADJUST;
+ tm->scale[0] = su;
+ tm->scale[1] = sv;
+ tm->scale[2] = 1.f;
+ tm->trans[0] = tu;
+ tm->trans[1] = tv;
+ tm->trans[2] = 0.f;
+ }
+ }
+ }
+ /* If the program is used 8 or 16 bit vertex coords, we need
+ to scale them to match what the PSP hardware wants. OpenGL
+ defines integral coords as just signed integers, but the
+ PSP interprets them as scaled floats in the range -1 - 1.
+ Therefore, we need to apply an appropriate scale factor as
+ a backend adjustment. The modelview matrix is the first one to
+ be applied to a vertex, so put the scaling there (XXX
+ except for bones when skinning is enabled...) */
+ c->modelview_stack.flags &= ~MF_ADJUST;
+
+ switch(vtxfmt & GE_VERTEX_SHIFT(3)) {
+ case GE_VERTEX_8BIT:
+ c->modelview_stack.scale[0] = 127.f;
+ c->modelview_stack.scale[1] = 127.f;
+ c->modelview_stack.scale[2] = 127.f;
+ c->modelview_stack.flags |= MF_ADJUST;
+ break;
+
+ case GE_VERTEX_16BIT:
+ c->modelview_stack.scale[0] = 32767.f;
+ c->modelview_stack.scale[1] = 32767.f;
+ c->modelview_stack.scale[2] = 32767.f;
+ c->modelview_stack.flags |= MF_ADJUST;
+ break;
}
__pspgl_context_writereg(c, CMD_VERTEXTYPE, vtxfmt);
View
@@ -39,6 +39,7 @@ struct pspgl_shared_context {
#define MF_DISABLED (1<<1) /* always load with identity (stack) */
#define MF_IDENTITY (1<<2) /* is identity matrix (matrix) */
#define MF_VFPU (1<<3) /* matrix stack top is in VFPU (stack) */
+#define MF_ADJUST (1<<4) /* some pre-use adjustments to apply */
#define VFPU_STACKTOP VMAT7 /* use matrix 7 for top-of-stack */
@@ -51,7 +52,12 @@ struct pspgl_matrix {
};
struct pspgl_matrix_stack {
+ /* adjustments to be applied before use */
+ float scale[4] __attribute__((aligned(VFPU_ALIGNMENT)));
+ float trans[4] __attribute__((aligned(VFPU_ALIGNMENT)));
+
struct pspgl_matrix *stack;
+
unsigned limit;
unsigned depth;
unsigned flags;
View
@@ -551,11 +551,8 @@ void __pspgl_update_texenv(struct pspgl_texobj *tobj)
__pspgl_context_writereg_masked(pspgl_curctx, CMD_TEXENV_FUNC,
(fmt->flags & TF_ALPHA) ? GE_TEXENV_RGBA : GE_TEXENV_RGB, 0x100);
- if (tobj->flags & TOF_FLIPPED) {
- sendCommandf(CMD_TEXTURE_SV, -1.0f);
- sendCommandf(CMD_TEXTURE_TV, 1.0f);
- } else {
- sendCommandf(CMD_TEXTURE_SV, 1.0f);
- sendCommandf(CMD_TEXTURE_TV, 0.0f);
- }
+ /* If we've switched textures or changed the flip status, mark
+ the texture matrix as dirty so that any adjustment can be
+ applied. */
+ pspgl_curctx->texture_stack.flags |= MF_DIRTY;
}

0 comments on commit 6720419

Please sign in to comment.