Merge branch 'scissor' into 'master'
Implement glScissor correctly See merge request simulant/GLdc!67
This commit is contained in:
commit
fc1a18e002
|
@ -139,6 +139,7 @@ gen_sample(terrain samples/terrain/main.c)
|
||||||
gen_sample(zclip samples/zclip/main.c)
|
gen_sample(zclip samples/zclip/main.c)
|
||||||
gen_sample(zclip_triangle samples/zclip_triangle/main.c)
|
gen_sample(zclip_triangle samples/zclip_triangle/main.c)
|
||||||
gen_sample(zclip_trianglestrip samples/zclip_trianglestrip/main.c)
|
gen_sample(zclip_trianglestrip samples/zclip_trianglestrip/main.c)
|
||||||
|
gen_sample(scissor samples/scissor/main.c)
|
||||||
|
|
||||||
if(PLATFORM_DREAMCAST)
|
if(PLATFORM_DREAMCAST)
|
||||||
gen_sample(polymark samples/polymark/main.c)
|
gen_sample(polymark samples/polymark/main.c)
|
||||||
|
|
10
GL/flush.c
10
GL/flush.c
|
@ -18,6 +18,14 @@ PolyList* _glActivePolyList() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
PolyList* _glOpaquePolyList() {
|
||||||
|
return &OP_LIST;
|
||||||
|
}
|
||||||
|
|
||||||
|
PolyList* _glPunchThruPolyList() {
|
||||||
|
return &PT_LIST;
|
||||||
|
}
|
||||||
|
|
||||||
PolyList *_glTransparentPolyList() {
|
PolyList *_glTransparentPolyList() {
|
||||||
return &TR_LIST;
|
return &TR_LIST;
|
||||||
}
|
}
|
||||||
|
@ -105,6 +113,8 @@ void APIENTRY glKosSwapBuffers() {
|
||||||
aligned_vector_clear(&PT_LIST.vector);
|
aligned_vector_clear(&PT_LIST.vector);
|
||||||
aligned_vector_clear(&TR_LIST.vector);
|
aligned_vector_clear(&TR_LIST.vector);
|
||||||
|
|
||||||
|
_glApplyScissor(true);
|
||||||
|
|
||||||
profiler_checkpoint("scene");
|
profiler_checkpoint("scene");
|
||||||
profiler_pop();
|
profiler_pop();
|
||||||
|
|
||||||
|
|
|
@ -265,6 +265,8 @@ float _glClipLineToNearZ(const Vertex* v1, const Vertex* v2, Vertex* vout);
|
||||||
void _glClipTriangleStrip(SubmissionTarget* target, uint8_t fladeShade);
|
void _glClipTriangleStrip(SubmissionTarget* target, uint8_t fladeShade);
|
||||||
|
|
||||||
PolyList *_glActivePolyList();
|
PolyList *_glActivePolyList();
|
||||||
|
PolyList* _glOpaquePolyList();
|
||||||
|
PolyList* _glPunchThruPolyList();
|
||||||
PolyList *_glTransparentPolyList();
|
PolyList *_glTransparentPolyList();
|
||||||
|
|
||||||
void _glInitAttributePointers();
|
void _glInitAttributePointers();
|
||||||
|
@ -356,6 +358,8 @@ GLuint _glFreeTextureMemory();
|
||||||
GLuint _glUsedTextureMemory();
|
GLuint _glUsedTextureMemory();
|
||||||
GLuint _glFreeContiguousTextureMemory();
|
GLuint _glFreeContiguousTextureMemory();
|
||||||
|
|
||||||
|
void _glApplyScissor(bool force);
|
||||||
|
|
||||||
#define MAX_TEXTURE_UNITS 2
|
#define MAX_TEXTURE_UNITS 2
|
||||||
#define MAX_LIGHTS 8
|
#define MAX_LIGHTS 8
|
||||||
|
|
||||||
|
|
90
GL/state.c
90
GL/state.c
|
@ -29,10 +29,22 @@ static GLboolean POLYGON_OFFSET_ENABLED = GL_FALSE;
|
||||||
|
|
||||||
static GLboolean NORMALIZE_ENABLED = GL_FALSE;
|
static GLboolean NORMALIZE_ENABLED = GL_FALSE;
|
||||||
|
|
||||||
|
static struct {
|
||||||
|
GLint x;
|
||||||
|
GLint y;
|
||||||
|
GLsizei width;
|
||||||
|
GLsizei height;
|
||||||
|
GLboolean applied;
|
||||||
|
} SCISSOR_RECT = {
|
||||||
|
0, 0, 640, 480, false
|
||||||
|
};
|
||||||
|
|
||||||
GLboolean _glIsSharedTexturePaletteEnabled() {
|
GLboolean _glIsSharedTexturePaletteEnabled() {
|
||||||
return SHARED_PALETTE_ENABLED;
|
return SHARED_PALETTE_ENABLED;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void _glApplyScissor(bool force);
|
||||||
|
|
||||||
static int _calc_pvr_face_culling() {
|
static int _calc_pvr_face_culling() {
|
||||||
if(!CULLING_ENABLED) {
|
if(!CULLING_ENABLED) {
|
||||||
return GPU_CULLING_NONE;
|
return GPU_CULLING_NONE;
|
||||||
|
@ -261,6 +273,13 @@ void _glInitContext() {
|
||||||
GL_CONTEXT.fmt.uv = GPU_UVFMT_32BIT;
|
GL_CONTEXT.fmt.uv = GPU_UVFMT_32BIT;
|
||||||
GL_CONTEXT.gen.color_clamp = GPU_CLRCLAMP_DISABLE;
|
GL_CONTEXT.gen.color_clamp = GPU_CLRCLAMP_DISABLE;
|
||||||
|
|
||||||
|
const VideoMode* mode = GetVideoMode();
|
||||||
|
|
||||||
|
SCISSOR_RECT.x = 0;
|
||||||
|
SCISSOR_RECT.y = 0;
|
||||||
|
SCISSOR_RECT.width = mode->width;
|
||||||
|
SCISSOR_RECT.height = mode->height;
|
||||||
|
|
||||||
glClearDepth(1.0f);
|
glClearDepth(1.0f);
|
||||||
glDepthFunc(GL_LESS);
|
glDepthFunc(GL_LESS);
|
||||||
glDepthMask(GL_TRUE);
|
glDepthMask(GL_TRUE);
|
||||||
|
@ -302,6 +321,7 @@ GLAPI void APIENTRY glEnable(GLenum cap) {
|
||||||
} break;
|
} break;
|
||||||
case GL_SCISSOR_TEST: {
|
case GL_SCISSOR_TEST: {
|
||||||
GL_CONTEXT.gen.clip_mode = GPU_USERCLIP_INSIDE;
|
GL_CONTEXT.gen.clip_mode = GPU_USERCLIP_INSIDE;
|
||||||
|
_glApplyScissor(false);
|
||||||
} break;
|
} break;
|
||||||
case GL_LIGHTING: {
|
case GL_LIGHTING: {
|
||||||
LIGHTING_ENABLED = GL_TRUE;
|
LIGHTING_ENABLED = GL_TRUE;
|
||||||
|
@ -537,6 +557,23 @@ void glPixelStorei(GLenum pname, GLint param) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void APIENTRY glScissor(GLint x, GLint y, GLsizei width, GLsizei height) {
|
||||||
|
if(SCISSOR_RECT.x == x &&
|
||||||
|
SCISSOR_RECT.y == y &&
|
||||||
|
SCISSOR_RECT.width == width &&
|
||||||
|
SCISSOR_RECT.height == height) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
SCISSOR_RECT.x = x;
|
||||||
|
SCISSOR_RECT.y = y;
|
||||||
|
SCISSOR_RECT.width = width;
|
||||||
|
SCISSOR_RECT.height = height;
|
||||||
|
SCISSOR_RECT.applied = false;
|
||||||
|
|
||||||
|
_glApplyScissor(false);
|
||||||
|
}
|
||||||
|
|
||||||
/* Setup the hardware user clip rectangle.
|
/* Setup the hardware user clip rectangle.
|
||||||
|
|
||||||
The minimum clip rectangle is a 32x32 area which is dependent on the tile
|
The minimum clip rectangle is a 32x32 area which is dependent on the tile
|
||||||
|
@ -549,30 +586,55 @@ void glPixelStorei(GLenum pname, GLint param) {
|
||||||
glScissor(0, 0, 32, 32) allows only the 'tile' in the lower left
|
glScissor(0, 0, 32, 32) allows only the 'tile' in the lower left
|
||||||
hand corner of the screen to be modified and glScissor(0, 0, 0, 0)
|
hand corner of the screen to be modified and glScissor(0, 0, 0, 0)
|
||||||
disallows modification to all 'tiles' on the screen.
|
disallows modification to all 'tiles' on the screen.
|
||||||
|
|
||||||
|
We call this in the following situations:
|
||||||
|
|
||||||
|
- glEnable(GL_SCISSOR_TEST) is called
|
||||||
|
- glScissor() is called
|
||||||
|
- After glKosSwapBuffers()
|
||||||
|
|
||||||
|
This ensures that a clip command is added to every vertex list
|
||||||
|
at the right place, either when enabling the scissor test, or
|
||||||
|
when the scissor test changes.
|
||||||
*/
|
*/
|
||||||
void APIENTRY glScissor(GLint x, GLint y, GLsizei width, GLsizei height) {
|
void _glApplyScissor(bool force) {
|
||||||
/*!!! FIXME: Shouldn't this be added to *all* lists? */
|
/* Don't do anyting if clipping is disabled */
|
||||||
PVRTileClipCommand *c = aligned_vector_extend(&_glActivePolyList()->vector, 1);
|
if(GL_CONTEXT.gen.clip_mode == GPU_USERCLIP_DISABLE) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Don't apply if we already applied - nothing changed */
|
||||||
|
if(SCISSOR_RECT.applied && !force) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
PVRTileClipCommand c;
|
||||||
|
|
||||||
GLint miny, maxx, maxy;
|
GLint miny, maxx, maxy;
|
||||||
|
|
||||||
const VideoMode* vid_mode = GetVideoMode();
|
const VideoMode* vid_mode = GetVideoMode();
|
||||||
|
|
||||||
GLsizei gl_scissor_width = MAX( MIN(width, vid_mode->width), 0 );
|
GLsizei scissor_width = MAX(MIN(SCISSOR_RECT.width, vid_mode->width), 0);
|
||||||
GLsizei gl_scissor_height = MAX( MIN(height, vid_mode->height), 0 );
|
GLsizei scissor_height = MAX(MIN(SCISSOR_RECT.height, vid_mode->height), 0);
|
||||||
|
|
||||||
/* force the origin to the lower left-hand corner of the screen */
|
/* force the origin to the lower left-hand corner of the screen */
|
||||||
miny = (vid_mode->height - gl_scissor_height) - y;
|
miny = (vid_mode->height - scissor_height) - SCISSOR_RECT.y;
|
||||||
maxx = (gl_scissor_width + x);
|
maxx = (scissor_width + SCISSOR_RECT.x);
|
||||||
maxy = (gl_scissor_height + miny);
|
maxy = (scissor_height + miny);
|
||||||
|
|
||||||
/* load command structure while mapping screen coords to TA tiles */
|
/* load command structure while mapping screen coords to TA tiles */
|
||||||
c->flags = GPU_CMD_USERCLIP;
|
c.flags = GPU_CMD_USERCLIP;
|
||||||
c->d1 = c->d2 = c->d3 = 0;
|
c.d1 = c.d2 = c.d3 = 0;
|
||||||
c->sx = CLAMP(x / 32, 0, vid_mode->width / 32);
|
c.sx = CLAMP(SCISSOR_RECT.x / 32, 0, vid_mode->width / 32);
|
||||||
c->sy = CLAMP(miny / 32, 0, vid_mode->height / 32);
|
c.sy = CLAMP(miny / 32, 0, vid_mode->height / 32);
|
||||||
c->ex = CLAMP((maxx / 32) - 1, 0, vid_mode->width / 32);
|
c.ex = CLAMP((maxx / 32) - 1, 0, vid_mode->width / 32);
|
||||||
c->ey = CLAMP((maxy / 32) - 1, 0, vid_mode->height / 32);
|
c.ey = CLAMP((maxy / 32) - 1, 0, vid_mode->height / 32);
|
||||||
|
|
||||||
|
aligned_vector_push_back(&_glOpaquePolyList()->vector, &c, 1);
|
||||||
|
aligned_vector_push_back(&_glPunchThruPolyList()->vector, &c, 1);
|
||||||
|
aligned_vector_push_back(&_glTransparentPolyList()->vector, &c, 1);
|
||||||
|
|
||||||
|
SCISSOR_RECT.applied = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
GLboolean APIENTRY glIsEnabled(GLenum cap) {
|
GLboolean APIENTRY glIsEnabled(GLenum cap) {
|
||||||
|
|
126
samples/scissor/main.c
Normal file
126
samples/scissor/main.c
Normal file
|
@ -0,0 +1,126 @@
|
||||||
|
#include "GL/gl.h"
|
||||||
|
#include "GL/glu.h"
|
||||||
|
#include "GL/glkos.h"
|
||||||
|
|
||||||
|
|
||||||
|
void InitGL(int Width, int Height)
|
||||||
|
{
|
||||||
|
glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
|
||||||
|
glClearDepth(1.0);
|
||||||
|
glDepthFunc(GL_LEQUAL);
|
||||||
|
glEnable(GL_DEPTH_TEST);
|
||||||
|
glShadeModel(GL_SMOOTH);
|
||||||
|
|
||||||
|
glMatrixMode(GL_PROJECTION);
|
||||||
|
glLoadIdentity();
|
||||||
|
|
||||||
|
gluPerspective(45.0f,(GLfloat)Width/(GLfloat)Height,0.1f,100.0f);
|
||||||
|
|
||||||
|
glMatrixMode(GL_MODELVIEW);
|
||||||
|
|
||||||
|
/* We cut out a square in the middle of the viewport to render to */
|
||||||
|
glEnable(GL_SCISSOR_TEST);
|
||||||
|
glScissor(160, 120, 320, 240);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* The function called when our window is resized (which shouldn't happen, because we're fullscreen) */
|
||||||
|
void ReSizeGLScene(int Width, int Height)
|
||||||
|
{
|
||||||
|
if (Height == 0)
|
||||||
|
Height = 1;
|
||||||
|
|
||||||
|
glViewport(0, 0, Width, Height);
|
||||||
|
|
||||||
|
glMatrixMode(GL_PROJECTION);
|
||||||
|
glLoadIdentity();
|
||||||
|
|
||||||
|
gluPerspective(45.0f,(GLfloat)Width/(GLfloat)Height,0.1f,100.0f);
|
||||||
|
glMatrixMode(GL_MODELVIEW);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* The main drawing function. */
|
||||||
|
void DrawGLScene()
|
||||||
|
{
|
||||||
|
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||||
|
glLoadIdentity();
|
||||||
|
|
||||||
|
glTranslatef(-3.0f, 1.5f, -10.0f);
|
||||||
|
|
||||||
|
glBegin(GL_TRIANGLES);
|
||||||
|
glVertex3f( 0.0f, 1.0f, 0.0f);
|
||||||
|
glVertex3f( 1.0f,-1.0f, 0.0f);
|
||||||
|
glVertex3f(-1.0f,-1.0f, 0.0f);
|
||||||
|
glEnd();
|
||||||
|
|
||||||
|
glTranslatef(3.0f, 0.0f, 0.0f);
|
||||||
|
|
||||||
|
|
||||||
|
glBegin(GL_QUADS);
|
||||||
|
glVertex3f(-1.0f, 1.0f, 0.0f);
|
||||||
|
glVertex3f( 1.0f, 1.0f, 0.0f);
|
||||||
|
glVertex3f( 1.0f,-1.0f, 0.0f);
|
||||||
|
glVertex3f(-1.0f,-1.0f, 0.0f);
|
||||||
|
glEnd();
|
||||||
|
|
||||||
|
glTranslatef(3.0f, 0.0f, 0.0f);
|
||||||
|
|
||||||
|
glBegin(GL_POLYGON);
|
||||||
|
glVertex3f(-0.0f, 1.0f, 0.0f);
|
||||||
|
glVertex3f(-0.75f, 0.75f, 0.0f);
|
||||||
|
glVertex3f(-1.0f, 0.0f, 0.0f);
|
||||||
|
glVertex3f(-0.75f,-0.75f, 0.0f);
|
||||||
|
glVertex3f(-0.0f,-1.0f, 0.0f);
|
||||||
|
glVertex3f( 0.75f,-0.75f, 0.0f);
|
||||||
|
glVertex3f( 1.0f, 0.0f, 0.0f);
|
||||||
|
glVertex3f( 0.75f, 0.75f, 0.0f);
|
||||||
|
glEnd();
|
||||||
|
|
||||||
|
glTranslatef(-6.0f, -3.0f, 0.0f);
|
||||||
|
|
||||||
|
|
||||||
|
glBegin(GL_POLYGON);
|
||||||
|
glVertex3f( 0.0f, 1.0f, 0.0f);
|
||||||
|
glVertex3f( 1.0f,-1.0f, 0.0f);
|
||||||
|
glVertex3f(-1.0f,-1.0f, 0.0f);
|
||||||
|
glEnd();
|
||||||
|
|
||||||
|
glTranslatef(3.0f, 0.0f, 0.0f);
|
||||||
|
|
||||||
|
|
||||||
|
glBegin(GL_POLYGON);
|
||||||
|
glVertex3f(-1.0f, 1.0f, 0.0f);
|
||||||
|
glVertex3f( 1.0f, 1.0f, 0.0f);
|
||||||
|
glVertex3f( 1.0f,-1.0f, 0.0f);
|
||||||
|
glVertex3f(-1.0f,-1.0f, 0.0f);
|
||||||
|
glEnd();
|
||||||
|
|
||||||
|
glTranslatef(3.0f, 0.0f, 0.0f);
|
||||||
|
|
||||||
|
glBegin(GL_POLYGON);
|
||||||
|
glVertex3f(-0.0f, 1.0f, 0.0f);
|
||||||
|
glVertex3f(-0.75f, 0.75f, 0.0f);
|
||||||
|
glVertex3f(-1.0f, 0.0f, 0.0f);
|
||||||
|
glVertex3f(-0.75f,-0.75f, 0.0f);
|
||||||
|
glVertex3f(-0.0f,-1.0f, 0.0f);
|
||||||
|
glVertex3f( 0.75f,-0.75f, 0.0f);
|
||||||
|
glVertex3f( 1.0f, 0.0f, 0.0f);
|
||||||
|
glVertex3f( 0.75f, 0.75f, 0.0f);
|
||||||
|
glEnd();
|
||||||
|
|
||||||
|
glKosSwapBuffers();
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(int argc, char **argv)
|
||||||
|
{
|
||||||
|
glKosInit();
|
||||||
|
|
||||||
|
InitGL(640, 480);
|
||||||
|
ReSizeGLScene(640, 480);
|
||||||
|
|
||||||
|
while(1) {
|
||||||
|
DrawGLScene();
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user