}
-/* Build a list of primitives on the fly. Keep
- * ctx->Driver.CurrentExecPrimitive uptodate as well.
+/**
+ * Called from glBegin.
+ * ctx->Driver.CurrentExecPrimitive will be set to <mode>.
*/
static void GLAPIENTRY _tnl_Begin( GLenum mode )
{
if (ctx->Driver.CurrentExecPrimitive == PRIM_OUTSIDE_BEGIN_END) {
/* we're not inside a glBegin/End pair */
TNLcontext *tnl = TNL_CONTEXT(ctx);
- int i;
+ GLuint i;
if (ctx->NewState) {
_mesa_update_state( ctx );
(ctx->FragmentProgram.Enabled && !ctx->FragmentProgram._Enabled)) {
_mesa_error(ctx, GL_INVALID_OPERATION,
"glBegin (invalid vertex/fragment program)");
+ tnl->DiscardPrimitive = GL_TRUE;
return;
}
+ if (ctx->DrawBuffer->_Status != GL_FRAMEBUFFER_COMPLETE_EXT) {
+ _mesa_error(ctx, GL_INVALID_FRAMEBUFFER_OPERATION_EXT,
+ "glBegin(incomplete framebuffer)");
+ tnl->DiscardPrimitive = GL_TRUE;
+ return;
+ }
+
+ tnl->DiscardPrimitive = GL_FALSE;
+
if (!(tnl->Driver.NotifyBegin &&
tnl->Driver.NotifyBegin( ctx, mode )))
CALL_Begin(ctx->Exec, (mode));
}
+/**
+ * Called from glEnd.
+ */
static void GLAPIENTRY _tnl_End( void )
{
GET_CURRENT_CONTEXT( ctx );
if (ctx->Driver.CurrentExecPrimitive != PRIM_OUTSIDE_BEGIN_END) {
+ /* closing an open glBegin primitive */
TNLcontext *tnl = TNL_CONTEXT(ctx);
int idx = tnl->vtx.initial_counter - tnl->vtx.counter;
int i = tnl->vtx.prim_count - 1;
#endif
}
- else
+ else {
+ /* glBegin hasn't been called! */
_mesa_error( ctx, GL_INVALID_OPERATION, "glEnd" );
+ }
}
TNLcontext *tnl = TNL_CONTEXT(ctx);
(void) flags;
- if (ctx->Driver.CurrentExecPrimitive != PRIM_OUTSIDE_BEGIN_END)
+ if (ctx->Driver.CurrentExecPrimitive != PRIM_OUTSIDE_BEGIN_END) {
+ /* still inside a glBegin/End pair. How'd we get here??? */
return;
+ }
+
+ if (tnl->DiscardPrimitive) {
+ /* discard any primitives */
+ tnl->vtx.prim_count = 0;
+ tnl->vtx.counter = tnl->vtx.initial_counter;
+ tnl->vtx.vbptr = tnl->vtx.buffer;
+ }
if (tnl->vtx.counter != tnl->vtx.initial_counter) {
_tnl_flush_vtx( ctx );