/* Copyright (c) 2001, Stanford University
* All rights reserved
*
* See the file LICENSE.txt for information on redistributing this software.
*/
#include "cr_mem.h"
#include "state.h"
#include "state/cr_statetypes.h"
#include "state_internals.h"
#include "cr_pixeldata.h"
void crStatePolygonInit(CRContext *ctx)
{
CRPolygonState *p = &ctx->polygon;
CRStateBits *sb = GetCurrentBits();
CRPolygonBits *pb = &(sb->polygon);
int i;
p->polygonSmooth = GL_FALSE;
p->polygonOffsetFill = GL_FALSE;
p->polygonOffsetLine = GL_FALSE;
p->polygonOffsetPoint = GL_FALSE;
p->polygonStipple = GL_FALSE;
p->cullFace = GL_FALSE;
RESET(pb->enable, ctx->bitid);
p->offsetFactor = 0;
p->offsetUnits = 0;
RESET(pb->offset, ctx->bitid);
p->cullFaceMode = GL_BACK;
p->frontFace = GL_CCW;
p->frontMode = GL_FILL;
p->backMode = GL_FILL;
RESET(pb->mode, ctx->bitid);
for (i=0; i<32; i++)
p->stipple[i] = 0xFFFFFFFF;
RESET(pb->stipple, ctx->bitid);
RESET(pb->dirty, ctx->bitid);
}
void STATE_APIENTRY crStateCullFace(GLenum mode)
{
CRContext *g = GetCurrentContext();
CRPolygonState *p = &(g->polygon);
CRStateBits *sb = GetCurrentBits();
CRPolygonBits *pb = &(sb->polygon);
if (g->current.inBeginEnd)
{
crStateError(__LINE__, __FILE__, GL_INVALID_OPERATION,
"glCullFace called in begin/end");
return;
}
FLUSH();
if (mode != GL_FRONT && mode != GL_BACK && mode != GL_FRONT_AND_BACK)
{
crStateError(__LINE__, __FILE__, GL_INVALID_ENUM,
"glCullFace called with bogus mode: 0x%x", mode);
return;
}
p->cullFaceMode = mode;
DIRTY(pb->mode, g->neg_bitid);
DIRTY(pb->dirty, g->neg_bitid);
}
void STATE_APIENTRY crStateFrontFace (GLenum mode)
{
CRContext *g = GetCurrentContext();
CRPolygonState *p = &(g->polygon);
CRStateBits *sb = GetCurrentBits();
CRPolygonBits *pb = &(sb->polygon);
if (g->current.inBeginEnd)
{
crStateError(__LINE__, __FILE__, GL_INVALID_OPERATION,
"glFrontFace called in begin/end");
return;
}
FLUSH();
if (mode != GL_CW && mode != GL_CCW)
{
crStateError(__LINE__, __FILE__, GL_INVALID_ENUM,
"glFrontFace called with bogus mode: 0x%x", mode);
return;
}
p->frontFace = mode;
DIRTY(pb->mode, g->neg_bitid);
DIRTY(pb->dirty, g->neg_bitid);
}
void STATE_APIENTRY crStatePolygonMode (GLenum face, GLenum mode)
{
CRContext *g = GetCurrentContext();
CRPolygonState *p = &(g->polygon);
CRStateBits *sb = GetCurrentBits();
CRPolygonBits *pb = &(sb->polygon);
if (g->current.inBeginEnd)
{
crStateError(__LINE__, __FILE__, GL_INVALID_OPERATION,
"glPolygonMode called in begin/end");
return;
}
FLUSH();
if (mode != GL_POINT && mode != GL_LINE && mode != GL_FILL)
{
crStateError(__LINE__, __FILE__, GL_INVALID_ENUM,
"glPolygonMode called with bogus mode: 0x%x", mode);
return;
}
switch (face) {
case GL_FRONT:
p->frontMode = mode;
break;
case GL_FRONT_AND_BACK:
p->frontMode = mode;
case GL_BACK:
p->backMode = mode;
break;
default:
crStateError(__LINE__, __FILE__, GL_INVALID_ENUM,
"glPolygonMode called with bogus face: 0x%x", face);
return;
}
DIRTY(pb->mode, g->neg_bitid);
DIRTY(pb->dirty, g->neg_bitid);
}
void STATE_APIENTRY crStatePolygonOffset (GLfloat factor, GLfloat units)
{
CRContext *g = GetCurrentContext();
CRPolygonState *p = &(g->polygon);
CRStateBits *sb = GetCurrentBits();
CRPolygonBits *pb = &(sb->polygon);
if (g->current.inBeginEnd)
{
crStateError(__LINE__, __FILE__, GL_INVALID_OPERATION,
"glPolygonOffset called in begin/end");
return;
}
FLUSH();
p->offsetFactor = factor;
p->offsetUnits = units;
DIRTY(pb->offset, g->neg_bitid);
DIRTY(pb->dirty, g->neg_bitid);
}
void STATE_APIENTRY crStatePolygonStipple (const GLubyte *p)
{
CRContext *g = GetCurrentContext();
CRPolygonState *poly = &(g->polygon);
CRStateBits *sb = GetCurrentBits();
CRPolygonBits *pb = &(sb->polygon);
if (g->current.inBeginEnd)
{
crStateError(__LINE__, __FILE__, GL_INVALID_OPERATION,
"glPolygonStipple called in begin/end");
return;
}
FLUSH();
if (!p && !crStateIsBufferBound(GL_PIXEL_UNPACK_BUFFER_ARB))
{
crDebug("Void pointer passed to PolygonStipple");
return;
}
/*@todo track mask if buffer is bound?*/
if (!crStateIsBufferBound(GL_PIXEL_UNPACK_BUFFER_ARB))
{
crMemcpy((char*)poly->stipple, (char*)p, 128);
}
DIRTY(pb->dirty, g->neg_bitid);
DIRTY(pb->stipple, g->neg_bitid);
}
void STATE_APIENTRY crStateGetPolygonStipple( GLubyte *b )
{
CRContext *g = GetCurrentContext();
CRPolygonState *poly = &(g->polygon);
if (g->current.inBeginEnd)
{
crStateError(__LINE__, __FILE__, GL_INVALID_OPERATION,
"glGetPolygonStipple called in begin/end");
return;
}
crMemcpy((char*)b, (char*)poly->stipple, 128);
}