feedback.c revision 848b8605
1848b8605Smrg/* 2848b8605Smrg * Mesa 3-D graphics library 3848b8605Smrg * 4848b8605Smrg * Copyright (C) 1999-2008 Brian Paul All Rights Reserved. 5848b8605Smrg * Copyright (C) 2009 VMware, Inc. All Rights Reserved. 6848b8605Smrg * 7848b8605Smrg * Permission is hereby granted, free of charge, to any person obtaining a 8848b8605Smrg * copy of this software and associated documentation files (the "Software"), 9848b8605Smrg * to deal in the Software without restriction, including without limitation 10848b8605Smrg * the rights to use, copy, modify, merge, publish, distribute, sublicense, 11848b8605Smrg * and/or sell copies of the Software, and to permit persons to whom the 12848b8605Smrg * Software is furnished to do so, subject to the following conditions: 13848b8605Smrg * 14848b8605Smrg * The above copyright notice and this permission notice shall be included 15848b8605Smrg * in all copies or substantial portions of the Software. 16848b8605Smrg * 17848b8605Smrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 18848b8605Smrg * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19848b8605Smrg * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 20848b8605Smrg * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR 21848b8605Smrg * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 22848b8605Smrg * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 23848b8605Smrg * OTHER DEALINGS IN THE SOFTWARE. 24848b8605Smrg */ 25848b8605Smrg 26848b8605Smrg/** 27848b8605Smrg * \file feedback.c 28848b8605Smrg * Selection and feedback modes functions. 29848b8605Smrg */ 30848b8605Smrg 31848b8605Smrg 32848b8605Smrg#include "glheader.h" 33848b8605Smrg#include "colormac.h" 34848b8605Smrg#include "context.h" 35848b8605Smrg#include "enums.h" 36848b8605Smrg#include "feedback.h" 37848b8605Smrg#include "macros.h" 38848b8605Smrg#include "mtypes.h" 39848b8605Smrg#include "main/dispatch.h" 40848b8605Smrg 41848b8605Smrg 42848b8605Smrg#define FB_3D 0x01 43848b8605Smrg#define FB_4D 0x02 44848b8605Smrg#define FB_COLOR 0x04 45848b8605Smrg#define FB_TEXTURE 0X08 46848b8605Smrg 47848b8605Smrg 48848b8605Smrg 49848b8605Smrgvoid GLAPIENTRY 50848b8605Smrg_mesa_FeedbackBuffer( GLsizei size, GLenum type, GLfloat *buffer ) 51848b8605Smrg{ 52848b8605Smrg GET_CURRENT_CONTEXT(ctx); 53848b8605Smrg 54848b8605Smrg if (ctx->RenderMode==GL_FEEDBACK) { 55848b8605Smrg _mesa_error( ctx, GL_INVALID_OPERATION, "glFeedbackBuffer" ); 56848b8605Smrg return; 57848b8605Smrg } 58848b8605Smrg if (size<0) { 59848b8605Smrg _mesa_error( ctx, GL_INVALID_VALUE, "glFeedbackBuffer(size<0)" ); 60848b8605Smrg return; 61848b8605Smrg } 62848b8605Smrg if (!buffer && size > 0) { 63848b8605Smrg _mesa_error( ctx, GL_INVALID_VALUE, "glFeedbackBuffer(buffer==NULL)" ); 64848b8605Smrg ctx->Feedback.BufferSize = 0; 65848b8605Smrg return; 66848b8605Smrg } 67848b8605Smrg 68848b8605Smrg switch (type) { 69848b8605Smrg case GL_2D: 70848b8605Smrg ctx->Feedback._Mask = 0; 71848b8605Smrg break; 72848b8605Smrg case GL_3D: 73848b8605Smrg ctx->Feedback._Mask = FB_3D; 74848b8605Smrg break; 75848b8605Smrg case GL_3D_COLOR: 76848b8605Smrg ctx->Feedback._Mask = (FB_3D | FB_COLOR); 77848b8605Smrg break; 78848b8605Smrg case GL_3D_COLOR_TEXTURE: 79848b8605Smrg ctx->Feedback._Mask = (FB_3D | FB_COLOR | FB_TEXTURE); 80848b8605Smrg break; 81848b8605Smrg case GL_4D_COLOR_TEXTURE: 82848b8605Smrg ctx->Feedback._Mask = (FB_3D | FB_4D | FB_COLOR | FB_TEXTURE); 83848b8605Smrg break; 84848b8605Smrg default: 85848b8605Smrg _mesa_error( ctx, GL_INVALID_ENUM, "glFeedbackBuffer" ); 86848b8605Smrg return; 87848b8605Smrg } 88848b8605Smrg 89848b8605Smrg FLUSH_VERTICES(ctx, _NEW_RENDERMODE); /* Always flush */ 90848b8605Smrg ctx->Feedback.Type = type; 91848b8605Smrg ctx->Feedback.BufferSize = size; 92848b8605Smrg ctx->Feedback.Buffer = buffer; 93848b8605Smrg ctx->Feedback.Count = 0; /* Becaues of this. */ 94848b8605Smrg} 95848b8605Smrg 96848b8605Smrg 97848b8605Smrgvoid GLAPIENTRY 98848b8605Smrg_mesa_PassThrough( GLfloat token ) 99848b8605Smrg{ 100848b8605Smrg GET_CURRENT_CONTEXT(ctx); 101848b8605Smrg 102848b8605Smrg if (ctx->RenderMode==GL_FEEDBACK) { 103848b8605Smrg FLUSH_VERTICES(ctx, 0); 104848b8605Smrg _mesa_feedback_token( ctx, (GLfloat) (GLint) GL_PASS_THROUGH_TOKEN ); 105848b8605Smrg _mesa_feedback_token( ctx, token ); 106848b8605Smrg } 107848b8605Smrg} 108848b8605Smrg 109848b8605Smrg 110848b8605Smrg/** 111848b8605Smrg * Put a vertex into the feedback buffer. 112848b8605Smrg */ 113848b8605Smrgvoid 114848b8605Smrg_mesa_feedback_vertex(struct gl_context *ctx, 115848b8605Smrg const GLfloat win[4], 116848b8605Smrg const GLfloat color[4], 117848b8605Smrg const GLfloat texcoord[4]) 118848b8605Smrg{ 119848b8605Smrg _mesa_feedback_token( ctx, win[0] ); 120848b8605Smrg _mesa_feedback_token( ctx, win[1] ); 121848b8605Smrg if (ctx->Feedback._Mask & FB_3D) { 122848b8605Smrg _mesa_feedback_token( ctx, win[2] ); 123848b8605Smrg } 124848b8605Smrg if (ctx->Feedback._Mask & FB_4D) { 125848b8605Smrg _mesa_feedback_token( ctx, win[3] ); 126848b8605Smrg } 127848b8605Smrg if (ctx->Feedback._Mask & FB_COLOR) { 128848b8605Smrg _mesa_feedback_token( ctx, color[0] ); 129848b8605Smrg _mesa_feedback_token( ctx, color[1] ); 130848b8605Smrg _mesa_feedback_token( ctx, color[2] ); 131848b8605Smrg _mesa_feedback_token( ctx, color[3] ); 132848b8605Smrg } 133848b8605Smrg if (ctx->Feedback._Mask & FB_TEXTURE) { 134848b8605Smrg _mesa_feedback_token( ctx, texcoord[0] ); 135848b8605Smrg _mesa_feedback_token( ctx, texcoord[1] ); 136848b8605Smrg _mesa_feedback_token( ctx, texcoord[2] ); 137848b8605Smrg _mesa_feedback_token( ctx, texcoord[3] ); 138848b8605Smrg } 139848b8605Smrg} 140848b8605Smrg 141848b8605Smrg 142848b8605Smrg/**********************************************************************/ 143848b8605Smrg/** \name Selection */ 144848b8605Smrg/*@{*/ 145848b8605Smrg 146848b8605Smrg/** 147848b8605Smrg * Establish a buffer for selection mode values. 148848b8605Smrg * 149848b8605Smrg * \param size buffer size. 150848b8605Smrg * \param buffer buffer. 151848b8605Smrg * 152848b8605Smrg * \sa glSelectBuffer(). 153848b8605Smrg * 154848b8605Smrg * \note this function can't be put in a display list. 155848b8605Smrg * 156848b8605Smrg * Verifies we're not in selection mode, flushes the vertices and initialize 157848b8605Smrg * the fields in __struct gl_contextRec::Select with the given buffer. 158848b8605Smrg */ 159848b8605Smrgvoid GLAPIENTRY 160848b8605Smrg_mesa_SelectBuffer( GLsizei size, GLuint *buffer ) 161848b8605Smrg{ 162848b8605Smrg GET_CURRENT_CONTEXT(ctx); 163848b8605Smrg 164848b8605Smrg if (size < 0) { 165848b8605Smrg _mesa_error(ctx, GL_INVALID_VALUE, "glSelectBuffer(size)"); 166848b8605Smrg return; 167848b8605Smrg } 168848b8605Smrg 169848b8605Smrg if (ctx->RenderMode==GL_SELECT) { 170848b8605Smrg _mesa_error( ctx, GL_INVALID_OPERATION, "glSelectBuffer" ); 171848b8605Smrg return; /* KW: added return */ 172848b8605Smrg } 173848b8605Smrg 174848b8605Smrg FLUSH_VERTICES(ctx, _NEW_RENDERMODE); 175848b8605Smrg ctx->Select.Buffer = buffer; 176848b8605Smrg ctx->Select.BufferSize = size; 177848b8605Smrg ctx->Select.BufferCount = 0; 178848b8605Smrg ctx->Select.HitFlag = GL_FALSE; 179848b8605Smrg ctx->Select.HitMinZ = 1.0; 180848b8605Smrg ctx->Select.HitMaxZ = 0.0; 181848b8605Smrg} 182848b8605Smrg 183848b8605Smrg 184848b8605Smrg/** 185848b8605Smrg * Write a value of a record into the selection buffer. 186848b8605Smrg * 187848b8605Smrg * \param ctx GL context. 188848b8605Smrg * \param value value. 189848b8605Smrg * 190848b8605Smrg * Verifies there is free space in the buffer to write the value and 191848b8605Smrg * increments the pointer. 192848b8605Smrg */ 193848b8605Smrgstatic inline void 194848b8605Smrgwrite_record(struct gl_context *ctx, GLuint value) 195848b8605Smrg{ 196848b8605Smrg if (ctx->Select.BufferCount < ctx->Select.BufferSize) { 197848b8605Smrg ctx->Select.Buffer[ctx->Select.BufferCount] = value; 198848b8605Smrg } 199848b8605Smrg ctx->Select.BufferCount++; 200848b8605Smrg} 201848b8605Smrg 202848b8605Smrg 203848b8605Smrg/** 204848b8605Smrg * Update the hit flag and the maximum and minimum depth values. 205848b8605Smrg * 206848b8605Smrg * \param ctx GL context. 207848b8605Smrg * \param z depth. 208848b8605Smrg * 209848b8605Smrg * Sets gl_selection::HitFlag and updates gl_selection::HitMinZ and 210848b8605Smrg * gl_selection::HitMaxZ. 211848b8605Smrg */ 212848b8605Smrgvoid 213848b8605Smrg_mesa_update_hitflag(struct gl_context *ctx, GLfloat z) 214848b8605Smrg{ 215848b8605Smrg ctx->Select.HitFlag = GL_TRUE; 216848b8605Smrg if (z < ctx->Select.HitMinZ) { 217848b8605Smrg ctx->Select.HitMinZ = z; 218848b8605Smrg } 219848b8605Smrg if (z > ctx->Select.HitMaxZ) { 220848b8605Smrg ctx->Select.HitMaxZ = z; 221848b8605Smrg } 222848b8605Smrg} 223848b8605Smrg 224848b8605Smrg 225848b8605Smrg/** 226848b8605Smrg * Write the hit record. 227848b8605Smrg * 228848b8605Smrg * \param ctx GL context. 229848b8605Smrg * 230848b8605Smrg * Write the hit record, i.e., the number of names in the stack, the minimum and 231848b8605Smrg * maximum depth values and the number of names in the name stack at the time 232848b8605Smrg * of the event. Resets the hit flag. 233848b8605Smrg * 234848b8605Smrg * \sa gl_selection. 235848b8605Smrg */ 236848b8605Smrgstatic void 237848b8605Smrgwrite_hit_record(struct gl_context *ctx) 238848b8605Smrg{ 239848b8605Smrg GLuint i; 240848b8605Smrg GLuint zmin, zmax, zscale = (~0u); 241848b8605Smrg 242848b8605Smrg /* HitMinZ and HitMaxZ are in [0,1]. Multiply these values by */ 243848b8605Smrg /* 2^32-1 and round to nearest unsigned integer. */ 244848b8605Smrg 245848b8605Smrg assert( ctx != NULL ); /* this line magically fixes a SunOS 5.x/gcc bug */ 246848b8605Smrg zmin = (GLuint) ((GLfloat) zscale * ctx->Select.HitMinZ); 247848b8605Smrg zmax = (GLuint) ((GLfloat) zscale * ctx->Select.HitMaxZ); 248848b8605Smrg 249848b8605Smrg write_record( ctx, ctx->Select.NameStackDepth ); 250848b8605Smrg write_record( ctx, zmin ); 251848b8605Smrg write_record( ctx, zmax ); 252848b8605Smrg for (i = 0; i < ctx->Select.NameStackDepth; i++) { 253848b8605Smrg write_record( ctx, ctx->Select.NameStack[i] ); 254848b8605Smrg } 255848b8605Smrg 256848b8605Smrg ctx->Select.Hits++; 257848b8605Smrg ctx->Select.HitFlag = GL_FALSE; 258848b8605Smrg ctx->Select.HitMinZ = 1.0; 259848b8605Smrg ctx->Select.HitMaxZ = -1.0; 260848b8605Smrg} 261848b8605Smrg 262848b8605Smrg 263848b8605Smrg/** 264848b8605Smrg * Initialize the name stack. 265848b8605Smrg * 266848b8605Smrg * Verifies we are in select mode and resets the name stack depth and resets 267848b8605Smrg * the hit record data in gl_selection. Marks new render mode in 268848b8605Smrg * __struct gl_contextRec::NewState. 269848b8605Smrg */ 270848b8605Smrgvoid GLAPIENTRY 271848b8605Smrg_mesa_InitNames( void ) 272848b8605Smrg{ 273848b8605Smrg GET_CURRENT_CONTEXT(ctx); 274848b8605Smrg FLUSH_VERTICES(ctx, 0); 275848b8605Smrg 276848b8605Smrg /* Record the hit before the HitFlag is wiped out again. */ 277848b8605Smrg if (ctx->RenderMode == GL_SELECT) { 278848b8605Smrg if (ctx->Select.HitFlag) { 279848b8605Smrg write_hit_record( ctx ); 280848b8605Smrg } 281848b8605Smrg } 282848b8605Smrg ctx->Select.NameStackDepth = 0; 283848b8605Smrg ctx->Select.HitFlag = GL_FALSE; 284848b8605Smrg ctx->Select.HitMinZ = 1.0; 285848b8605Smrg ctx->Select.HitMaxZ = 0.0; 286848b8605Smrg ctx->NewState |= _NEW_RENDERMODE; 287848b8605Smrg} 288848b8605Smrg 289848b8605Smrg 290848b8605Smrg/** 291848b8605Smrg * Load the top-most name of the name stack. 292848b8605Smrg * 293848b8605Smrg * \param name name. 294848b8605Smrg * 295848b8605Smrg * Verifies we are in selection mode and that the name stack is not empty. 296848b8605Smrg * Flushes vertices. If there is a hit flag writes it (via write_hit_record()), 297848b8605Smrg * and replace the top-most name in the stack. 298848b8605Smrg * 299848b8605Smrg * sa __struct gl_contextRec::Select. 300848b8605Smrg */ 301848b8605Smrgvoid GLAPIENTRY 302848b8605Smrg_mesa_LoadName( GLuint name ) 303848b8605Smrg{ 304848b8605Smrg GET_CURRENT_CONTEXT(ctx); 305848b8605Smrg 306848b8605Smrg if (ctx->RenderMode != GL_SELECT) { 307848b8605Smrg return; 308848b8605Smrg } 309848b8605Smrg if (ctx->Select.NameStackDepth == 0) { 310848b8605Smrg _mesa_error( ctx, GL_INVALID_OPERATION, "glLoadName" ); 311848b8605Smrg return; 312848b8605Smrg } 313848b8605Smrg 314848b8605Smrg FLUSH_VERTICES(ctx, _NEW_RENDERMODE); 315848b8605Smrg 316848b8605Smrg if (ctx->Select.HitFlag) { 317848b8605Smrg write_hit_record( ctx ); 318848b8605Smrg } 319848b8605Smrg if (ctx->Select.NameStackDepth < MAX_NAME_STACK_DEPTH) { 320848b8605Smrg ctx->Select.NameStack[ctx->Select.NameStackDepth-1] = name; 321848b8605Smrg } 322848b8605Smrg else { 323848b8605Smrg ctx->Select.NameStack[MAX_NAME_STACK_DEPTH-1] = name; 324848b8605Smrg } 325848b8605Smrg} 326848b8605Smrg 327848b8605Smrg 328848b8605Smrg/** 329848b8605Smrg * Push a name into the name stack. 330848b8605Smrg * 331848b8605Smrg * \param name name. 332848b8605Smrg * 333848b8605Smrg * Verifies we are in selection mode and that the name stack is not full. 334848b8605Smrg * Flushes vertices. If there is a hit flag writes it (via write_hit_record()), 335848b8605Smrg * and adds the name to the top of the name stack. 336848b8605Smrg * 337848b8605Smrg * sa __struct gl_contextRec::Select. 338848b8605Smrg */ 339848b8605Smrgvoid GLAPIENTRY 340848b8605Smrg_mesa_PushName( GLuint name ) 341848b8605Smrg{ 342848b8605Smrg GET_CURRENT_CONTEXT(ctx); 343848b8605Smrg 344848b8605Smrg if (ctx->RenderMode != GL_SELECT) { 345848b8605Smrg return; 346848b8605Smrg } 347848b8605Smrg 348848b8605Smrg FLUSH_VERTICES(ctx, _NEW_RENDERMODE); 349848b8605Smrg if (ctx->Select.HitFlag) { 350848b8605Smrg write_hit_record( ctx ); 351848b8605Smrg } 352848b8605Smrg if (ctx->Select.NameStackDepth >= MAX_NAME_STACK_DEPTH) { 353848b8605Smrg _mesa_error( ctx, GL_STACK_OVERFLOW, "glPushName" ); 354848b8605Smrg } 355848b8605Smrg else 356848b8605Smrg ctx->Select.NameStack[ctx->Select.NameStackDepth++] = name; 357848b8605Smrg} 358848b8605Smrg 359848b8605Smrg 360848b8605Smrg/** 361848b8605Smrg * Pop a name into the name stack. 362848b8605Smrg * 363848b8605Smrg * Verifies we are in selection mode and that the name stack is not empty. 364848b8605Smrg * Flushes vertices. If there is a hit flag writes it (via write_hit_record()), 365848b8605Smrg * and removes top-most name in the name stack. 366848b8605Smrg * 367848b8605Smrg * sa __struct gl_contextRec::Select. 368848b8605Smrg */ 369848b8605Smrgvoid GLAPIENTRY 370848b8605Smrg_mesa_PopName( void ) 371848b8605Smrg{ 372848b8605Smrg GET_CURRENT_CONTEXT(ctx); 373848b8605Smrg 374848b8605Smrg if (ctx->RenderMode != GL_SELECT) { 375848b8605Smrg return; 376848b8605Smrg } 377848b8605Smrg 378848b8605Smrg FLUSH_VERTICES(ctx, _NEW_RENDERMODE); 379848b8605Smrg if (ctx->Select.HitFlag) { 380848b8605Smrg write_hit_record( ctx ); 381848b8605Smrg } 382848b8605Smrg if (ctx->Select.NameStackDepth == 0) { 383848b8605Smrg _mesa_error( ctx, GL_STACK_UNDERFLOW, "glPopName" ); 384848b8605Smrg } 385848b8605Smrg else 386848b8605Smrg ctx->Select.NameStackDepth--; 387848b8605Smrg} 388848b8605Smrg 389848b8605Smrg/*@}*/ 390848b8605Smrg 391848b8605Smrg 392848b8605Smrg/**********************************************************************/ 393848b8605Smrg/** \name Render Mode */ 394848b8605Smrg/*@{*/ 395848b8605Smrg 396848b8605Smrg/** 397848b8605Smrg * Set rasterization mode. 398848b8605Smrg * 399848b8605Smrg * \param mode rasterization mode. 400848b8605Smrg * 401848b8605Smrg * \note this function can't be put in a display list. 402848b8605Smrg * 403848b8605Smrg * \sa glRenderMode(). 404848b8605Smrg * 405848b8605Smrg * Flushes the vertices and do the necessary cleanup according to the previous 406848b8605Smrg * rasterization mode, such as writing the hit record or resent the select 407848b8605Smrg * buffer index when exiting the select mode. Updates 408848b8605Smrg * __struct gl_contextRec::RenderMode and notifies the driver via the 409848b8605Smrg * dd_function_table::RenderMode callback. 410848b8605Smrg */ 411848b8605SmrgGLint GLAPIENTRY 412848b8605Smrg_mesa_RenderMode( GLenum mode ) 413848b8605Smrg{ 414848b8605Smrg GET_CURRENT_CONTEXT(ctx); 415848b8605Smrg GLint result; 416848b8605Smrg ASSERT_OUTSIDE_BEGIN_END_WITH_RETVAL(ctx, 0); 417848b8605Smrg 418848b8605Smrg if (MESA_VERBOSE & VERBOSE_API) 419848b8605Smrg _mesa_debug(ctx, "glRenderMode %s\n", _mesa_lookup_enum_by_nr(mode)); 420848b8605Smrg 421848b8605Smrg FLUSH_VERTICES(ctx, _NEW_RENDERMODE); 422848b8605Smrg 423848b8605Smrg switch (ctx->RenderMode) { 424848b8605Smrg case GL_RENDER: 425848b8605Smrg result = 0; 426848b8605Smrg break; 427848b8605Smrg case GL_SELECT: 428848b8605Smrg if (ctx->Select.HitFlag) { 429848b8605Smrg write_hit_record( ctx ); 430848b8605Smrg } 431848b8605Smrg if (ctx->Select.BufferCount > ctx->Select.BufferSize) { 432848b8605Smrg /* overflow */ 433848b8605Smrg#ifdef DEBUG 434848b8605Smrg _mesa_warning(ctx, "Feedback buffer overflow"); 435848b8605Smrg#endif 436848b8605Smrg result = -1; 437848b8605Smrg } 438848b8605Smrg else { 439848b8605Smrg result = ctx->Select.Hits; 440848b8605Smrg } 441848b8605Smrg ctx->Select.BufferCount = 0; 442848b8605Smrg ctx->Select.Hits = 0; 443848b8605Smrg ctx->Select.NameStackDepth = 0; 444848b8605Smrg break; 445848b8605Smrg case GL_FEEDBACK: 446848b8605Smrg if (ctx->Feedback.Count > ctx->Feedback.BufferSize) { 447848b8605Smrg /* overflow */ 448848b8605Smrg result = -1; 449848b8605Smrg } 450848b8605Smrg else { 451848b8605Smrg result = ctx->Feedback.Count; 452848b8605Smrg } 453848b8605Smrg ctx->Feedback.Count = 0; 454848b8605Smrg break; 455848b8605Smrg default: 456848b8605Smrg _mesa_error( ctx, GL_INVALID_ENUM, "glRenderMode" ); 457848b8605Smrg return 0; 458848b8605Smrg } 459848b8605Smrg 460848b8605Smrg switch (mode) { 461848b8605Smrg case GL_RENDER: 462848b8605Smrg break; 463848b8605Smrg case GL_SELECT: 464848b8605Smrg if (ctx->Select.BufferSize==0) { 465848b8605Smrg /* haven't called glSelectBuffer yet */ 466848b8605Smrg _mesa_error( ctx, GL_INVALID_OPERATION, "glRenderMode" ); 467848b8605Smrg } 468848b8605Smrg break; 469848b8605Smrg case GL_FEEDBACK: 470848b8605Smrg if (ctx->Feedback.BufferSize==0) { 471848b8605Smrg /* haven't called glFeedbackBuffer yet */ 472848b8605Smrg _mesa_error( ctx, GL_INVALID_OPERATION, "glRenderMode" ); 473848b8605Smrg } 474848b8605Smrg break; 475848b8605Smrg default: 476848b8605Smrg _mesa_error( ctx, GL_INVALID_ENUM, "glRenderMode" ); 477848b8605Smrg return 0; 478848b8605Smrg } 479848b8605Smrg 480848b8605Smrg ctx->RenderMode = mode; 481848b8605Smrg if (ctx->Driver.RenderMode) 482848b8605Smrg ctx->Driver.RenderMode( ctx, mode ); 483848b8605Smrg 484848b8605Smrg return result; 485848b8605Smrg} 486848b8605Smrg 487848b8605Smrg/*@}*/ 488848b8605Smrg 489848b8605Smrg 490848b8605Smrg/**********************************************************************/ 491848b8605Smrg/** \name Initialization */ 492848b8605Smrg/*@{*/ 493848b8605Smrg 494848b8605Smrg/** 495848b8605Smrg * Initialize context feedback data. 496848b8605Smrg */ 497848b8605Smrgvoid _mesa_init_feedback( struct gl_context * ctx ) 498848b8605Smrg{ 499848b8605Smrg /* Feedback */ 500848b8605Smrg ctx->Feedback.Type = GL_2D; /* TODO: verify */ 501848b8605Smrg ctx->Feedback.Buffer = NULL; 502848b8605Smrg ctx->Feedback.BufferSize = 0; 503848b8605Smrg ctx->Feedback.Count = 0; 504848b8605Smrg 505848b8605Smrg /* Selection/picking */ 506848b8605Smrg ctx->Select.Buffer = NULL; 507848b8605Smrg ctx->Select.BufferSize = 0; 508848b8605Smrg ctx->Select.BufferCount = 0; 509848b8605Smrg ctx->Select.Hits = 0; 510848b8605Smrg ctx->Select.NameStackDepth = 0; 511848b8605Smrg 512848b8605Smrg /* Miscellaneous */ 513848b8605Smrg ctx->RenderMode = GL_RENDER; 514848b8605Smrg} 515848b8605Smrg 516848b8605Smrg/*@}*/ 517