Merge branch GLdc:master into master
This commit is contained in:
commit
455e1652bc
@ -6,7 +6,7 @@
|
|||||||
|
|
||||||
#include "../containers/stack.h"
|
#include "../containers/stack.h"
|
||||||
|
|
||||||
#define DEG2RAD (0.01745329251994329576923690768489)
|
#define DEG2RAD (0.01745329251994329576923690768489f)
|
||||||
|
|
||||||
|
|
||||||
/* Depth range */
|
/* Depth range */
|
||||||
@ -174,8 +174,8 @@ void APIENTRY glRotatef(GLfloat angle, GLfloat x, GLfloat y, GLfloat z) {
|
|||||||
};
|
};
|
||||||
|
|
||||||
float r = DEG2RAD * angle;
|
float r = DEG2RAD * angle;
|
||||||
float c = cos(r);
|
float c = cosf(r);
|
||||||
float s = sin(r);
|
float s = sinf(r);
|
||||||
|
|
||||||
VEC3_NORMALIZE(x, y, z);
|
VEC3_NORMALIZE(x, y, z);
|
||||||
|
|
||||||
|
|||||||
@ -445,7 +445,7 @@ static inline void CompilePolyHeader(PolyHeader *dst, const PolyContext *src) {
|
|||||||
dst->d3 = dst->d4 = 0xffffffff;
|
dst->d3 = dst->d4 = 0xffffffff;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef BACKEND_KOSPVR
|
#ifdef __DREAMCAST__
|
||||||
#include "platforms/sh4.h"
|
#include "platforms/sh4.h"
|
||||||
#else
|
#else
|
||||||
#include "platforms/software.h"
|
#include "platforms/software.h"
|
||||||
|
|||||||
@ -1,3 +1,5 @@
|
|||||||
|
#include <float.h>
|
||||||
|
|
||||||
#include "../platform.h"
|
#include "../platform.h"
|
||||||
#include "sh4.h"
|
#include "sh4.h"
|
||||||
|
|
||||||
@ -30,19 +32,32 @@ void InitGPU(_Bool autosort, _Bool fsaa) {
|
|||||||
(autosort) ? 0 : 1 /* Disable translucent auto-sorting to match traditional GL */
|
(autosort) ? 0 : 1 /* Disable translucent auto-sorting to match traditional GL */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/* Newer versions of KOS add an extra parameter to pvr_init_params_t
|
||||||
|
* called opb_overflow_count. To remain compatible we set that last
|
||||||
|
* parameter to something only if it exists */
|
||||||
|
const int opb_offset = offsetof(pvr_init_params_t, autosort_disabled) + 4;
|
||||||
|
if(sizeof(pvr_init_params_t) > opb_offset) {
|
||||||
|
int* opb_count = (int*)(((char*)¶ms) + opb_offset);
|
||||||
|
*opb_count = 2; // Two should be enough for anybody.. right?
|
||||||
|
}
|
||||||
|
|
||||||
pvr_init(¶ms);
|
pvr_init(¶ms);
|
||||||
|
|
||||||
|
#ifndef _arch_sub_naomi
|
||||||
/* If we're PAL and we're NOT VGA, then use 50hz by default. This is the safest
|
/* If we're PAL and we're NOT VGA, then use 50hz by default. This is the safest
|
||||||
thing to do. If someone wants to force 60hz then they can call vid_set_mode later and hopefully
|
thing to do. If someone wants to force 60hz then they can call vid_set_mode later and hopefully
|
||||||
that'll work... */
|
that'll work... */
|
||||||
|
|
||||||
int cable = vid_check_cable();
|
int cable = vid_check_cable();
|
||||||
int region = flashrom_get_region();
|
|
||||||
|
|
||||||
if(region == FLASHROM_REGION_EUROPE && cable != CT_VGA) {
|
if(cable != CT_VGA) {
|
||||||
printf("PAL region without VGA - enabling 50hz");
|
int region = flashrom_get_region();
|
||||||
vid_set_mode(DM_640x480_PAL_IL, PM_RGB565);
|
if (region == FLASHROM_REGION_EUROPE) {
|
||||||
|
printf("PAL region without VGA - enabling 50hz");
|
||||||
|
vid_set_mode(DM_640x480_PAL_IL, PM_RGB565);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void SceneBegin() {
|
void SceneBegin() {
|
||||||
@ -93,6 +108,10 @@ static inline void _glFlushBuffer() {
|
|||||||
static inline void _glPushHeaderOrVertex(Vertex* v) {
|
static inline void _glPushHeaderOrVertex(Vertex* v) {
|
||||||
TRACE();
|
TRACE();
|
||||||
|
|
||||||
|
#if CLIP_DEBUG
|
||||||
|
fprintf(stderr, "{%f, %f, %f, %f}, // %x (%x)\n", v->xyz[0], v->xyz[1], v->xyz[2], v->w, v->flags, v);
|
||||||
|
#endif
|
||||||
|
|
||||||
uint32_t* s = (uint32_t*) v;
|
uint32_t* s = (uint32_t*) v;
|
||||||
sq[0] = *(s++);
|
sq[0] = *(s++);
|
||||||
sq[1] = *(s++);
|
sq[1] = *(s++);
|
||||||
@ -110,12 +129,13 @@ static inline void _glClipEdge(const Vertex* const v1, const Vertex* const v2, V
|
|||||||
const static float o = 0.003921569f; // 1 / 255
|
const static float o = 0.003921569f; // 1 / 255
|
||||||
const float d0 = v1->w + v1->xyz[2];
|
const float d0 = v1->w + v1->xyz[2];
|
||||||
const float d1 = v2->w + v2->xyz[2];
|
const float d1 = v2->w + v2->xyz[2];
|
||||||
const float t = (fabs(d0) * (1.0f / sqrtf((d1 - d0) * (d1 - d0)))) + 0.000001f;
|
const float t = (fabs(d0) * (1.0f / sqrtf((d1 - d0) * (d1 - d0))));
|
||||||
const float invt = 1.0f - t;
|
const float invt = 1.0f - t;
|
||||||
|
|
||||||
vout->xyz[0] = invt * v1->xyz[0] + t * v2->xyz[0];
|
vout->xyz[0] = invt * v1->xyz[0] + t * v2->xyz[0];
|
||||||
vout->xyz[1] = invt * v1->xyz[1] + t * v2->xyz[1];
|
vout->xyz[1] = invt * v1->xyz[1] + t * v2->xyz[1];
|
||||||
vout->xyz[2] = invt * v1->xyz[2] + t * v2->xyz[2];
|
vout->xyz[2] = invt * v1->xyz[2] + t * v2->xyz[2];
|
||||||
|
vout->xyz[2] = (vout->xyz[2] < FLT_EPSILON) ? FLT_EPSILON : vout->xyz[2];
|
||||||
|
|
||||||
vout->uv[0] = invt * v1->uv[0] + t * v2->uv[0];
|
vout->uv[0] = invt * v1->uv[0] + t * v2->uv[0];
|
||||||
vout->uv[1] = invt * v1->uv[1] + t * v2->uv[1];
|
vout->uv[1] = invt * v1->uv[1] + t * v2->uv[1];
|
||||||
@ -136,7 +156,22 @@ static volatile uint32_t* PVR_LMMODE0 = (uint32_t*) 0xA05F6884;
|
|||||||
static volatile uint32_t *PVR_LMMODE1 = (uint32_t*) 0xA05F6888;
|
static volatile uint32_t *PVR_LMMODE1 = (uint32_t*) 0xA05F6888;
|
||||||
static volatile uint32_t *QACR = (uint32_t*) 0xFF000038;
|
static volatile uint32_t *QACR = (uint32_t*) 0xFF000038;
|
||||||
|
|
||||||
void SceneListSubmit(Vertex* v2, int n) {
|
enum Visible {
|
||||||
|
NONE_VISIBLE = 0,
|
||||||
|
FIRST_VISIBLE = 1,
|
||||||
|
SECOND_VISIBLE = 2,
|
||||||
|
THIRD_VISIBLE = 4,
|
||||||
|
FIRST_AND_SECOND_VISIBLE = FIRST_VISIBLE | SECOND_VISIBLE,
|
||||||
|
SECOND_AND_THIRD_VISIBLE = SECOND_VISIBLE | THIRD_VISIBLE,
|
||||||
|
FIRST_AND_THIRD_VISIBLE = FIRST_VISIBLE | THIRD_VISIBLE,
|
||||||
|
ALL_VISIBLE = 7
|
||||||
|
};
|
||||||
|
|
||||||
|
static inline bool is_header(Vertex* v) {
|
||||||
|
return !(v->flags == GPU_CMD_VERTEX || v->flags == GPU_CMD_VERTEX_EOL);
|
||||||
|
}
|
||||||
|
|
||||||
|
void SceneListSubmit(Vertex* vertices, int n) {
|
||||||
TRACE();
|
TRACE();
|
||||||
|
|
||||||
/* You need at least a header, and 3 vertices to render anything */
|
/* You need at least a header, and 3 vertices to render anything */
|
||||||
@ -156,97 +191,111 @@ void SceneListSubmit(Vertex* v2, int n) {
|
|||||||
QACR[1] = QACR[0] = 0x11;
|
QACR[1] = QACR[0] = 0x11;
|
||||||
|
|
||||||
#if CLIP_DEBUG
|
#if CLIP_DEBUG
|
||||||
Vertex* vertex = (Vertex*) src;
|
|
||||||
for(int i = 0; i < n; ++i) {
|
|
||||||
fprintf(stderr, "{%f, %f, %f, %f}, // %x (%x)\n", vertex[i].xyz[0], vertex[i].xyz[1], vertex[i].xyz[2], vertex[i].w, vertex[i].flags, &vertex[i]);
|
|
||||||
}
|
|
||||||
|
|
||||||
fprintf(stderr, "----\n");
|
fprintf(stderr, "----\n");
|
||||||
|
|
||||||
|
Vertex* vertex = (Vertex*) vertices;
|
||||||
|
for(int i = 0; i < n; ++i) {
|
||||||
|
fprintf(stderr, "IN: {%f, %f, %f, %f}, // %x (%x)\n", vertex[i].xyz[0], vertex[i].xyz[1], vertex[i].xyz[2], vertex[i].w, vertex[i].flags, &vertex[i]);
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
uint8_t visible_mask = 0;
|
|
||||||
uint8_t counter = 0;
|
/* This is a bit cumbersome - in some cases (particularly case 2)
|
||||||
|
we finish the vertex submission with a duplicated final vertex so
|
||||||
|
that the tri-strip can be continued. However, if the next triangle in the
|
||||||
|
strip is not visible then the duplicated vertex would've been sent without
|
||||||
|
the EOL flag. We won't know if we need the EOL flag or not when processing
|
||||||
|
case 2. To workaround this we may queue a vertex temporarily here, in the normal
|
||||||
|
case it will be submitted by the next iteration with the same flags it had, but
|
||||||
|
in the invisible case it will be overridden to submit with EOL */
|
||||||
|
static Vertex __attribute__((aligned(32))) qv;
|
||||||
|
Vertex* queued_vertex = NULL;
|
||||||
|
|
||||||
|
#define QUEUE_VERTEX(v) \
|
||||||
|
do { queued_vertex = &qv; *queued_vertex = *(v); } while(0)
|
||||||
|
|
||||||
|
#define SUBMIT_QUEUED_VERTEX(sflags) \
|
||||||
|
do { if(queued_vertex) { queued_vertex->flags = (sflags); _glPushHeaderOrVertex(queued_vertex); queued_vertex = NULL; } } while(0)
|
||||||
|
|
||||||
|
int visible_mask = 0;
|
||||||
|
|
||||||
sq = SQ_BASE_ADDRESS;
|
sq = SQ_BASE_ADDRESS;
|
||||||
|
|
||||||
for(int i = 0; i < n; ++i, ++v2) {
|
Vertex* v0 = vertices;
|
||||||
PREFETCH(v2 + 1);
|
for(int i = 0; i < n - 1; ++i, ++v0) {
|
||||||
switch(v2->flags) {
|
if(is_header(v0)) {
|
||||||
case GPU_CMD_VERTEX_EOL:
|
_glPushHeaderOrVertex(v0);
|
||||||
if(counter < 2) {
|
visible_mask = 0;
|
||||||
continue;
|
|
||||||
}
|
|
||||||
counter = 0;
|
|
||||||
break;
|
|
||||||
case GPU_CMD_VERTEX:
|
|
||||||
++counter;
|
|
||||||
if(counter < 3) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
_glPushHeaderOrVertex(v2);
|
|
||||||
counter = 0;
|
|
||||||
continue;
|
continue;
|
||||||
};
|
|
||||||
|
|
||||||
Vertex* const v0 = v2 - 2;
|
|
||||||
Vertex* const v1 = v2 - 1;
|
|
||||||
|
|
||||||
visible_mask = (
|
|
||||||
(v0->xyz[2] > -v0->w) << 0 |
|
|
||||||
(v1->xyz[2] > -v1->w) << 1 |
|
|
||||||
(v2->xyz[2] > -v2->w) << 2 |
|
|
||||||
(counter == 0) << 3
|
|
||||||
);
|
|
||||||
|
|
||||||
switch(visible_mask) {
|
|
||||||
case 15: /* All visible, but final vertex in strip */
|
|
||||||
{
|
|
||||||
_glPerspectiveDivideVertex(v0, h);
|
|
||||||
_glPushHeaderOrVertex(v0);
|
|
||||||
|
|
||||||
_glPerspectiveDivideVertex(v1, h);
|
|
||||||
_glPushHeaderOrVertex(v1);
|
|
||||||
|
|
||||||
_glPerspectiveDivideVertex(v2, h);
|
|
||||||
_glPushHeaderOrVertex(v2);
|
|
||||||
}
|
}
|
||||||
break;
|
|
||||||
case 7:
|
|
||||||
/* All visible, push the first vertex and move on */
|
|
||||||
_glPerspectiveDivideVertex(v0, h);
|
|
||||||
_glPushHeaderOrVertex(v0);
|
|
||||||
break;
|
|
||||||
case 9:
|
|
||||||
/* First vertex was visible, last in strip */
|
|
||||||
{
|
|
||||||
Vertex __attribute__((aligned(32))) scratch[2];
|
|
||||||
Vertex* a = &scratch[0];
|
|
||||||
Vertex* b = &scratch[1];
|
|
||||||
|
|
||||||
_glClipEdge(v0, v1, a);
|
Vertex* v1 = v0 + 1;
|
||||||
a->flags = GPU_CMD_VERTEX;
|
Vertex* v2 = (i < n - 2) ? v0 + 2 : NULL;
|
||||||
|
|
||||||
_glClipEdge(v2, v0, b);
|
assert(!is_header(v1));
|
||||||
b->flags = GPU_CMD_VERTEX_EOL;
|
|
||||||
|
// We are trailing if we're on the penultimate vertex, or the next but one vertex is
|
||||||
|
// an EOL, or v1 is an EOL (FIXME: possibly unnecessary and coverted by the other case?)
|
||||||
|
bool is_trailing = (v1->flags == GPU_CMD_VERTEX_EOL) || ((v2) ? is_header(v2) : true);
|
||||||
|
|
||||||
|
if(is_trailing) {
|
||||||
|
// OK so we've hit a new context header
|
||||||
|
// we need to finalize this strip and move on
|
||||||
|
|
||||||
|
// If the last triangle was all visible, we need
|
||||||
|
// to submit the last two vertices, any clipped triangles
|
||||||
|
// would've
|
||||||
|
if(visible_mask == ALL_VISIBLE) {
|
||||||
|
SUBMIT_QUEUED_VERTEX(qv.flags);
|
||||||
|
|
||||||
_glPerspectiveDivideVertex(v0, h);
|
_glPerspectiveDivideVertex(v0, h);
|
||||||
_glPushHeaderOrVertex(v0);
|
_glPushHeaderOrVertex(v0);
|
||||||
|
|
||||||
_glPerspectiveDivideVertex(a, h);
|
v1->flags = GPU_CMD_VERTEX_EOL;
|
||||||
_glPushHeaderOrVertex(a);
|
|
||||||
|
|
||||||
_glPerspectiveDivideVertex(b, h);
|
_glPerspectiveDivideVertex(v1, h);
|
||||||
_glPushHeaderOrVertex(b);
|
_glPushHeaderOrVertex(v1);
|
||||||
|
} else {
|
||||||
|
// If the previous triangle wasn't all visible, and we
|
||||||
|
// queued a vertex - we force it to be EOL and submit
|
||||||
|
SUBMIT_QUEUED_VERTEX(GPU_CMD_VERTEX_EOL);
|
||||||
}
|
}
|
||||||
break;
|
|
||||||
case 1:
|
|
||||||
/* First vertex was visible, but not last in strip */
|
|
||||||
{
|
|
||||||
Vertex __attribute__((aligned(32))) scratch[2];
|
|
||||||
Vertex* a = &scratch[0];
|
|
||||||
Vertex* b = &scratch[1];
|
|
||||||
|
|
||||||
|
i++;
|
||||||
|
v0++;
|
||||||
|
visible_mask = 0;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
visible_mask = (
|
||||||
|
(v0->xyz[2] >= -v0->w) << 0 |
|
||||||
|
(v1->xyz[2] >= -v1->w) << 1 |
|
||||||
|
(v2->xyz[2] >= -v2->w) << 2
|
||||||
|
);
|
||||||
|
|
||||||
|
/* If we've gone behind the plane, we finish the strip
|
||||||
|
otherwise we submit however it was */
|
||||||
|
if(visible_mask == NONE_VISIBLE) {
|
||||||
|
SUBMIT_QUEUED_VERTEX(GPU_CMD_VERTEX_EOL);
|
||||||
|
} else {
|
||||||
|
SUBMIT_QUEUED_VERTEX(qv.flags);
|
||||||
|
}
|
||||||
|
|
||||||
|
#if CLIP_DEBUG
|
||||||
|
fprintf(stderr, "0x%x 0x%x 0x%x -> %d\n", v0, v1, v2, visible_mask);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
Vertex __attribute__((aligned(32))) scratch[4];
|
||||||
|
Vertex* a = &scratch[0], *b = &scratch[1], *c = &scratch[2], *d = &scratch[3];
|
||||||
|
|
||||||
|
switch(visible_mask) {
|
||||||
|
case ALL_VISIBLE:
|
||||||
|
_glPerspectiveDivideVertex(v0, h);
|
||||||
|
QUEUE_VERTEX(v0);
|
||||||
|
break;
|
||||||
|
case NONE_VISIBLE:
|
||||||
|
break;
|
||||||
|
break;
|
||||||
|
case FIRST_VISIBLE:
|
||||||
_glClipEdge(v0, v1, a);
|
_glClipEdge(v0, v1, a);
|
||||||
a->flags = GPU_CMD_VERTEX;
|
a->flags = GPU_CMD_VERTEX;
|
||||||
|
|
||||||
@ -261,19 +310,10 @@ void SceneListSubmit(Vertex* v2, int n) {
|
|||||||
|
|
||||||
_glPerspectiveDivideVertex(b, h);
|
_glPerspectiveDivideVertex(b, h);
|
||||||
_glPushHeaderOrVertex(b);
|
_glPushHeaderOrVertex(b);
|
||||||
_glPushHeaderOrVertex(b);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case 10:
|
|
||||||
case 2:
|
|
||||||
/* Second vertex was visible. In self case we need to create a triangle and produce
|
|
||||||
two new vertices: 1-2, and 2-3. */
|
|
||||||
{
|
|
||||||
Vertex __attribute__((aligned(32))) scratch[3];
|
|
||||||
Vertex* a = &scratch[0];
|
|
||||||
Vertex* b = &scratch[1];
|
|
||||||
Vertex* c = &scratch[2];
|
|
||||||
|
|
||||||
|
QUEUE_VERTEX(b);
|
||||||
|
break;
|
||||||
|
case SECOND_VISIBLE:
|
||||||
memcpy_vertex(c, v1);
|
memcpy_vertex(c, v1);
|
||||||
|
|
||||||
_glClipEdge(v0, v1, a);
|
_glClipEdge(v0, v1, a);
|
||||||
@ -289,48 +329,9 @@ void SceneListSubmit(Vertex* v2, int n) {
|
|||||||
_glPushHeaderOrVertex(c);
|
_glPushHeaderOrVertex(c);
|
||||||
|
|
||||||
_glPerspectiveDivideVertex(b, h);
|
_glPerspectiveDivideVertex(b, h);
|
||||||
_glPushHeaderOrVertex(b);
|
QUEUE_VERTEX(b);
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
case 11:
|
case THIRD_VISIBLE:
|
||||||
case 3: /* First and second vertex were visible */
|
|
||||||
{
|
|
||||||
Vertex __attribute__((aligned(32))) scratch[3];
|
|
||||||
Vertex* a = &scratch[0];
|
|
||||||
Vertex* b = &scratch[1];
|
|
||||||
Vertex* c = &scratch[2];
|
|
||||||
|
|
||||||
memcpy_vertex(c, v1);
|
|
||||||
|
|
||||||
_glClipEdge(v2, v0, b);
|
|
||||||
b->flags = GPU_CMD_VERTEX;
|
|
||||||
|
|
||||||
_glPerspectiveDivideVertex(v0, h);
|
|
||||||
_glPushHeaderOrVertex(v0);
|
|
||||||
|
|
||||||
_glClipEdge(v1, v2, a);
|
|
||||||
a->flags = v2->flags;
|
|
||||||
|
|
||||||
_glPerspectiveDivideVertex(c, h);
|
|
||||||
_glPushHeaderOrVertex(c);
|
|
||||||
|
|
||||||
_glPerspectiveDivideVertex(b, h);
|
|
||||||
_glPushHeaderOrVertex(b);
|
|
||||||
|
|
||||||
_glPerspectiveDivideVertex(a, h);
|
|
||||||
_glPushHeaderOrVertex(c);
|
|
||||||
_glPushHeaderOrVertex(a);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case 12:
|
|
||||||
case 4:
|
|
||||||
/* Third vertex was visible. */
|
|
||||||
{
|
|
||||||
Vertex __attribute__((aligned(32))) scratch[3];
|
|
||||||
Vertex* a = &scratch[0];
|
|
||||||
Vertex* b = &scratch[1];
|
|
||||||
Vertex* c = &scratch[2];
|
|
||||||
|
|
||||||
memcpy_vertex(c, v2);
|
memcpy_vertex(c, v2);
|
||||||
|
|
||||||
_glClipEdge(v2, v0, a);
|
_glClipEdge(v2, v0, a);
|
||||||
@ -340,117 +341,90 @@ void SceneListSubmit(Vertex* v2, int n) {
|
|||||||
b->flags = GPU_CMD_VERTEX;
|
b->flags = GPU_CMD_VERTEX;
|
||||||
|
|
||||||
_glPerspectiveDivideVertex(a, h);
|
_glPerspectiveDivideVertex(a, h);
|
||||||
|
//_glPushHeaderOrVertex(a);
|
||||||
_glPushHeaderOrVertex(a);
|
_glPushHeaderOrVertex(a);
|
||||||
|
|
||||||
if(counter % 2 == 1) {
|
|
||||||
_glPushHeaderOrVertex(a);
|
|
||||||
}
|
|
||||||
|
|
||||||
_glPerspectiveDivideVertex(b, h);
|
_glPerspectiveDivideVertex(b, h);
|
||||||
_glPushHeaderOrVertex(b);
|
_glPushHeaderOrVertex(b);
|
||||||
|
|
||||||
|
_glPerspectiveDivideVertex(c, h);
|
||||||
|
QUEUE_VERTEX(c);
|
||||||
|
break;
|
||||||
|
case FIRST_AND_SECOND_VISIBLE:
|
||||||
|
memcpy_vertex(c, v1);
|
||||||
|
|
||||||
|
_glClipEdge(v2, v0, b);
|
||||||
|
b->flags = GPU_CMD_VERTEX;
|
||||||
|
|
||||||
|
_glPerspectiveDivideVertex(v0, h);
|
||||||
|
_glPushHeaderOrVertex(v0);
|
||||||
|
|
||||||
|
_glClipEdge(v1, v2, a);
|
||||||
|
a->flags = v2->flags;
|
||||||
|
|
||||||
_glPerspectiveDivideVertex(c, h);
|
_glPerspectiveDivideVertex(c, h);
|
||||||
_glPushHeaderOrVertex(c);
|
_glPushHeaderOrVertex(c);
|
||||||
}
|
|
||||||
|
_glPerspectiveDivideVertex(b, h);
|
||||||
|
_glPushHeaderOrVertex(b);
|
||||||
|
|
||||||
|
_glPerspectiveDivideVertex(a, h);
|
||||||
|
_glPushHeaderOrVertex(c);
|
||||||
|
|
||||||
|
QUEUE_VERTEX(a);
|
||||||
break;
|
break;
|
||||||
case 13:
|
case SECOND_AND_THIRD_VISIBLE:
|
||||||
{
|
memcpy_vertex(c, v1);
|
||||||
Vertex __attribute__((aligned(32))) scratch[3];
|
memcpy_vertex(d, v2);
|
||||||
Vertex* a = &scratch[0];
|
|
||||||
Vertex* b = &scratch[1];
|
|
||||||
Vertex* c = &scratch[2];
|
|
||||||
|
|
||||||
memcpy_vertex(c, v2);
|
_glClipEdge(v0, v1, a);
|
||||||
c->flags = GPU_CMD_VERTEX;
|
a->flags = GPU_CMD_VERTEX;
|
||||||
|
|
||||||
_glClipEdge(v0, v1, a);
|
_glClipEdge(v2, v0, b);
|
||||||
a->flags = GPU_CMD_VERTEX;
|
b->flags = GPU_CMD_VERTEX;
|
||||||
|
|
||||||
_glClipEdge(v1, v2, b);
|
_glPerspectiveDivideVertex(a, h);
|
||||||
b->flags = GPU_CMD_VERTEX;
|
_glPushHeaderOrVertex(a);
|
||||||
|
|
||||||
_glPerspectiveDivideVertex(v0, h);
|
_glPerspectiveDivideVertex(c, h);
|
||||||
_glPushHeaderOrVertex(v0);
|
_glPushHeaderOrVertex(c);
|
||||||
|
|
||||||
_glPerspectiveDivideVertex(a, h);
|
_glPerspectiveDivideVertex(b, h);
|
||||||
_glPushHeaderOrVertex(a);
|
_glPushHeaderOrVertex(b);
|
||||||
|
_glPushHeaderOrVertex(c);
|
||||||
|
|
||||||
_glPerspectiveDivideVertex(c, h);
|
_glPerspectiveDivideVertex(d, h);
|
||||||
_glPushHeaderOrVertex(c);
|
QUEUE_VERTEX(d);
|
||||||
_glPerspectiveDivideVertex(b, h);
|
|
||||||
_glPushHeaderOrVertex(b);
|
|
||||||
|
|
||||||
c->flags = GPU_CMD_VERTEX_EOL;
|
|
||||||
_glPushHeaderOrVertex(c);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case 5: /* First and third vertex were visible */
|
|
||||||
{
|
|
||||||
Vertex __attribute__((aligned(32))) scratch[3];
|
|
||||||
Vertex* a = &scratch[0];
|
|
||||||
Vertex* b = &scratch[1];
|
|
||||||
Vertex* c = &scratch[2];
|
|
||||||
|
|
||||||
memcpy_vertex(c, v2);
|
|
||||||
c->flags = GPU_CMD_VERTEX;
|
|
||||||
|
|
||||||
_glClipEdge(v0, v1, a);
|
|
||||||
a->flags = GPU_CMD_VERTEX;
|
|
||||||
|
|
||||||
_glClipEdge(v1, v2, b);
|
|
||||||
b->flags = GPU_CMD_VERTEX;
|
|
||||||
|
|
||||||
_glPerspectiveDivideVertex(v0, h);
|
|
||||||
_glPushHeaderOrVertex(v0);
|
|
||||||
|
|
||||||
_glPerspectiveDivideVertex(a, h);
|
|
||||||
_glPushHeaderOrVertex(a);
|
|
||||||
|
|
||||||
_glPerspectiveDivideVertex(c, h);
|
|
||||||
_glPushHeaderOrVertex(c);
|
|
||||||
_glPerspectiveDivideVertex(b, h);
|
|
||||||
_glPushHeaderOrVertex(b);
|
|
||||||
_glPushHeaderOrVertex(c);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case 14:
|
|
||||||
case 6: /* Second and third vertex were visible */
|
|
||||||
{
|
|
||||||
Vertex __attribute__((aligned(32))) scratch[4];
|
|
||||||
Vertex* a = &scratch[0];
|
|
||||||
Vertex* b = &scratch[1];
|
|
||||||
Vertex* c = &scratch[2];
|
|
||||||
Vertex* d = &scratch[3];
|
|
||||||
|
|
||||||
memcpy_vertex(c, v1);
|
|
||||||
memcpy_vertex(d, v2);
|
|
||||||
|
|
||||||
_glClipEdge(v0, v1, a);
|
|
||||||
a->flags = GPU_CMD_VERTEX;
|
|
||||||
|
|
||||||
_glClipEdge(v2, v0, b);
|
|
||||||
b->flags = GPU_CMD_VERTEX;
|
|
||||||
|
|
||||||
_glPerspectiveDivideVertex(a, h);
|
|
||||||
_glPushHeaderOrVertex(a);
|
|
||||||
|
|
||||||
_glPerspectiveDivideVertex(c, h);
|
|
||||||
_glPushHeaderOrVertex(c);
|
|
||||||
|
|
||||||
_glPerspectiveDivideVertex(b, h);
|
|
||||||
_glPushHeaderOrVertex(b);
|
|
||||||
_glPushHeaderOrVertex(c);
|
|
||||||
|
|
||||||
_glPerspectiveDivideVertex(d, h);
|
|
||||||
_glPushHeaderOrVertex(d);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case 8:
|
|
||||||
default:
|
|
||||||
break;
|
break;
|
||||||
|
case FIRST_AND_THIRD_VISIBLE:
|
||||||
|
memcpy_vertex(c, v2);
|
||||||
|
c->flags = GPU_CMD_VERTEX;
|
||||||
|
|
||||||
|
_glClipEdge(v0, v1, a);
|
||||||
|
a->flags = GPU_CMD_VERTEX;
|
||||||
|
|
||||||
|
_glClipEdge(v1, v2, b);
|
||||||
|
b->flags = GPU_CMD_VERTEX;
|
||||||
|
|
||||||
|
_glPerspectiveDivideVertex(v0, h);
|
||||||
|
_glPushHeaderOrVertex(v0);
|
||||||
|
|
||||||
|
_glPerspectiveDivideVertex(a, h);
|
||||||
|
_glPushHeaderOrVertex(a);
|
||||||
|
|
||||||
|
_glPerspectiveDivideVertex(c, h);
|
||||||
|
_glPushHeaderOrVertex(c);
|
||||||
|
_glPerspectiveDivideVertex(b, h);
|
||||||
|
_glPushHeaderOrVertex(b);
|
||||||
|
QUEUE_VERTEX(c);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
fprintf(stderr, "ERROR\n");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SUBMIT_QUEUED_VERTEX(GPU_CMD_VERTEX_EOL);
|
||||||
|
|
||||||
_glFlushBuffer();
|
_glFlushBuffer();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -1211,6 +1211,7 @@ static int _determineConversion(GLint internalFormat, GLenum format, GLenum type
|
|||||||
{_a8_to_argb4444, GL_ARGB4444_KOS, GL_ALPHA, GL_UNSIGNED_BYTE, false, false},
|
{_a8_to_argb4444, GL_ARGB4444_KOS, GL_ALPHA, GL_UNSIGNED_BYTE, false, false},
|
||||||
{_rgba8888_to_argb4444, GL_ARGB4444_KOS, GL_RGBA, GL_UNSIGNED_BYTE, false, false},
|
{_rgba8888_to_argb4444, GL_ARGB4444_KOS, GL_RGBA, GL_UNSIGNED_BYTE, false, false},
|
||||||
{_rgba4444_to_argb4444, GL_ARGB4444_KOS, GL_RGBA, GL_UNSIGNED_SHORT_4_4_4_4, false, false},
|
{_rgba4444_to_argb4444, GL_ARGB4444_KOS, GL_RGBA, GL_UNSIGNED_SHORT_4_4_4_4, false, false},
|
||||||
|
{_rgba4444_to_argb4444, GL_ARGB4444_TWID_KOS, GL_RGBA, GL_UNSIGNED_SHORT_4_4_4_4, true, false},
|
||||||
{NULL, GL_ARGB4444_KOS, GL_BGRA, GL_UNSIGNED_SHORT_4_4_4_4_REV, false, false},
|
{NULL, GL_ARGB4444_KOS, GL_BGRA, GL_UNSIGNED_SHORT_4_4_4_4_REV, false, false},
|
||||||
{NULL, GL_ARGB4444_TWID_KOS, GL_BGRA, GL_UNSIGNED_SHORT_4_4_4_4_REV_TWID_KOS, false, false},
|
{NULL, GL_ARGB4444_TWID_KOS, GL_BGRA, GL_UNSIGNED_SHORT_4_4_4_4_REV_TWID_KOS, false, false},
|
||||||
{_rgba8888_to_argb4444, GL_ARGB4444_TWID_KOS, GL_RGBA, GL_UNSIGNED_BYTE, true, false},
|
{_rgba8888_to_argb4444, GL_ARGB4444_TWID_KOS, GL_RGBA, GL_UNSIGNED_BYTE, true, false},
|
||||||
@ -2041,7 +2042,8 @@ GLuint _glFreeContiguousTextureMemory() {
|
|||||||
return alloc_count_continuous(ALLOC_BASE);
|
return alloc_count_continuous(ALLOC_BASE);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void update_data_pointer(void* src, void* dst, void*) {
|
static void update_data_pointer(void* src, void* dst, void* data) {
|
||||||
|
_GL_UNUSED(data);
|
||||||
for(size_t id = 0; id < MAX_TEXTURE_COUNT; id++){
|
for(size_t id = 0; id < MAX_TEXTURE_COUNT; id++){
|
||||||
TextureObject* txr = (TextureObject*) named_array_get(&TEXTURE_OBJECTS, id);
|
TextureObject* txr = (TextureObject*) named_array_get(&TEXTURE_OBJECTS, id);
|
||||||
if(txr && txr->data == src) {
|
if(txr && txr->data == src) {
|
||||||
|
|||||||
@ -20,7 +20,7 @@ void InitGL(int Width, int Height) // We call this right after our OpenG
|
|||||||
glEnable(GL_DEPTH_TEST); // Enables Depth Testing
|
glEnable(GL_DEPTH_TEST); // Enables Depth Testing
|
||||||
glShadeModel(GL_SMOOTH); // Enables Smooth Color Shading
|
glShadeModel(GL_SMOOTH); // Enables Smooth Color Shading
|
||||||
glEnable(GL_TEXTURE_2D);
|
glEnable(GL_TEXTURE_2D);
|
||||||
glEnable(GL_CULL_FACE);
|
glDisable(GL_CULL_FACE);
|
||||||
|
|
||||||
glMatrixMode(GL_PROJECTION);
|
glMatrixMode(GL_PROJECTION);
|
||||||
glLoadIdentity(); // Reset The Projection Matrix
|
glLoadIdentity(); // Reset The Projection Matrix
|
||||||
@ -64,30 +64,38 @@ int check_start() {
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static GLfloat movement = -10.0f;
|
||||||
|
static GLfloat rotation = 0.0f;
|
||||||
|
|
||||||
|
void update_movement() {
|
||||||
|
#ifdef __DREAMCAST__
|
||||||
|
maple_device_t *cont;
|
||||||
|
cont_state_t *state;
|
||||||
|
|
||||||
|
cont = maple_enum_type(0, MAPLE_FUNC_CONTROLLER);
|
||||||
|
|
||||||
|
if(cont) {
|
||||||
|
state = (cont_state_t *)maple_dev_status(cont);
|
||||||
|
if(state) {
|
||||||
|
if(state->buttons & CONT_DPAD_UP) {
|
||||||
|
movement += 0.5f;
|
||||||
|
} else if(state->buttons & CONT_DPAD_DOWN) {
|
||||||
|
movement -= 0.5f;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(state->buttons & CONT_DPAD_LEFT) {
|
||||||
|
rotation += 0.5f;
|
||||||
|
} else if(state->buttons & CONT_DPAD_RIGHT) {
|
||||||
|
rotation -= 0.5f;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
/* The main drawing function. */
|
/* The main drawing function. */
|
||||||
void DrawGLScene()
|
void DrawGLScene()
|
||||||
{
|
{
|
||||||
static GLfloat movement = 0.0f;
|
|
||||||
static GLfloat rotation = 0.0f;
|
|
||||||
static GLboolean increasing = GL_TRUE;
|
|
||||||
|
|
||||||
if(movement > 10.0) {
|
|
||||||
increasing = GL_FALSE;
|
|
||||||
} else if(movement < -10.0f) {
|
|
||||||
increasing = GL_TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(increasing) {
|
|
||||||
movement += 0.05f;
|
|
||||||
} else {
|
|
||||||
movement -= 0.05f;
|
|
||||||
}
|
|
||||||
|
|
||||||
rotation += 0.1f;
|
|
||||||
if(rotation > 360.0f) {
|
|
||||||
rotation -= 360.0f;
|
|
||||||
}
|
|
||||||
|
|
||||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // Clear The Screen And The Depth Buffer
|
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // Clear The Screen And The Depth Buffer
|
||||||
glLoadIdentity(); // Reset The View
|
glLoadIdentity(); // Reset The View
|
||||||
|
|
||||||
@ -95,24 +103,58 @@ void DrawGLScene()
|
|||||||
glTranslatef(0.0f, -1.0f, movement);
|
glTranslatef(0.0f, -1.0f, movement);
|
||||||
glRotatef(rotation, 0.0f, 1.0, 0.0f);
|
glRotatef(rotation, 0.0f, 1.0, 0.0f);
|
||||||
|
|
||||||
glBegin(GL_TRIANGLE_STRIP);
|
/* We create a horseshoe shape tri-strip here because that allows for situations where a strip
|
||||||
glColor3f(1.0f, 1.0f, 0.0f);
|
leaves and re-enters the viewport */
|
||||||
glVertex3f(-2.5f, 0.0f, 5.0f);
|
|
||||||
|
|
||||||
glColor3f(1.0f, 0.0f, 0.0f);
|
glBegin(GL_TRIANGLE_STRIP);
|
||||||
glVertex3f(2.5f, 0.0f, 5.0f);
|
// Left side
|
||||||
|
glColor3f(1.0f, 1.0f, 0.0f);
|
||||||
|
glVertex3f(-2.0f, 0.0f, 5.0f);
|
||||||
|
|
||||||
|
glColor3f(1.0f, 1.0f, 0.0f);
|
||||||
|
glVertex3f(-1.0f, 0.0f, 5.0f);
|
||||||
|
|
||||||
|
glColor3f(1.0f, 1.0f, 0.0f);
|
||||||
|
glVertex3f(-2.0f, 0.0f, 3.0f);
|
||||||
|
|
||||||
|
glColor3f(1.0f, 1.0f, 0.0f);
|
||||||
|
glVertex3f(-1.0f, 0.0f, 3.0f);
|
||||||
|
|
||||||
|
glColor3f(1.0f, 1.0f, 0.0f);
|
||||||
|
glVertex3f(-2.0f, 0.0f, 1.0f);
|
||||||
|
|
||||||
|
glColor3f(1.0f, 1.0f, 0.0f);
|
||||||
|
glVertex3f(-1.0f, 0.0f, 1.0f);
|
||||||
|
|
||||||
|
// Curve
|
||||||
|
glColor3f(0.0f, 1.0f, 0.0f);
|
||||||
|
glVertex3f(-1.0f, 0.0f, -1.0f);
|
||||||
|
|
||||||
glColor3f(0.0f, 1.0f, 0.0f);
|
glColor3f(0.0f, 1.0f, 0.0f);
|
||||||
glVertex3f(-2.5f, 0.0f, -5.0f);
|
glVertex3f(1.0f, 0.0f, 1.0f);
|
||||||
|
|
||||||
glColor3f(0.0f, 0.0f, 1.0f);
|
glColor3f(0.0f, 1.0f, 0.0f);
|
||||||
glVertex3f(2.5f, 0.0f, -5.0f);
|
glVertex3f(1.0f, 0.0f, -1.0f);
|
||||||
|
|
||||||
glColor3f(0.0f, 1.0f, 1.0f);
|
// Right side
|
||||||
glVertex3f(-2.5f, 0.0f, -10.0f);
|
// Degenerate to reverse ordering
|
||||||
|
glColor3f(1.0f, 0.0f, 0.0f);
|
||||||
|
glVertex3f(2.0f, 0.0f, 1.0f);
|
||||||
|
|
||||||
glColor3f(1.0f, 0.0f, 1.0f);
|
glColor3f(0.0f, 1.0f, 0.0f);
|
||||||
glVertex3f(2.5f, 0.0f, -10.0f);
|
glVertex3f(1.0f, 0.0f, 1.0f);
|
||||||
|
|
||||||
|
glColor3f(1.0f, 0.0f, 0.0f);
|
||||||
|
glVertex3f(1.0f, 0.0f, 3.0f);
|
||||||
|
|
||||||
|
glColor3f(1.0f, 0.0f, 0.0f);
|
||||||
|
glVertex3f(2.0f, 0.0f, 3.0f);
|
||||||
|
|
||||||
|
glColor3f(1.0f, 0.0f, 0.0f);
|
||||||
|
glVertex3f(1.0f, 0.0f, 5.0f);
|
||||||
|
|
||||||
|
glColor3f(1.0f, 0.0f, 0.0f);
|
||||||
|
glVertex3f(2.0f, 0.0f, 5.0f);
|
||||||
glEnd();
|
glEnd();
|
||||||
glPopMatrix();
|
glPopMatrix();
|
||||||
|
|
||||||
@ -131,6 +173,8 @@ int main(int argc, char **argv)
|
|||||||
if(check_start())
|
if(check_start())
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
update_movement();
|
||||||
|
|
||||||
DrawGLScene();
|
DrawGLScene();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user