Subversion Repositories Kolibri OS

Rev

Rev 4358 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
4358 Serge 1
/**************************************************************************
2
 *
3
 * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas.
4
 * All Rights Reserved.
5
 *
6
 * Permission is hereby granted, free of charge, to any person obtaining a
7
 * copy of this software and associated documentation files (the
8
 * "Software"), to deal in the Software without restriction, including
9
 * without limitation the rights to use, copy, modify, merge, publish,
10
 * distribute, sub license, and/or sell copies of the Software, and to
11
 * permit persons to whom the Software is furnished to do so, subject to
12
 * the following conditions:
13
 *
14
 * The above copyright notice and this permission notice (including the
15
 * next paragraph) shall be included in all copies or substantial portions
16
 * of the Software.
17
 *
18
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
19
 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
20
 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
21
 * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
22
 * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
23
 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
24
 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
25
 *
26
 **************************************************************************/
27
 
28
/**
29
 * GL_SELECT and GL_FEEDBACK render modes.
30
 * Basically, we use a private instance of the 'draw' module for doing
31
 * selection/feedback.  It would be nice to use the transform_feedback
32
 * hardware feature, but it's defined as happening pre-clip and we want
33
 * post-clipped primitives.  Also, there's concerns about the efficiency
34
 * of using the hardware for this anyway.
35
 *
36
 * Authors:
37
 *   Brian Paul
38
 */
39
 
40
#include "main/imports.h"
41
#include "main/context.h"
42
#include "main/feedback.h"
43
 
44
#include "vbo/vbo.h"
45
 
46
#include "st_context.h"
47
#include "st_draw.h"
48
#include "st_cb_feedback.h"
49
 
50
#include "pipe/p_context.h"
51
#include "pipe/p_defines.h"
52
 
53
#include "draw/draw_context.h"
54
#include "draw/draw_pipe.h"
55
 
56
 
57
/**
58
 * This is actually used for both feedback and selection.
59
 */
60
struct feedback_stage
61
{
62
   struct draw_stage stage;   /**< Base class */
63
   struct gl_context *ctx;            /**< Rendering context */
64
   GLboolean reset_stipple_counter;
65
};
66
 
67
 
68
/**********************************************************************
69
 * GL Feedback functions
70
 **********************************************************************/
71
 
72
static INLINE struct feedback_stage *
73
feedback_stage( struct draw_stage *stage )
74
{
75
   return (struct feedback_stage *)stage;
76
}
77
 
78
 
79
static void
80
feedback_vertex(struct gl_context *ctx, const struct draw_context *draw,
81
                const struct vertex_header *v)
82
{
83
   const struct st_context *st = st_context(ctx);
84
   GLfloat win[4];
85
   const GLfloat *color, *texcoord;
86
   GLuint slot;
87
 
88
   win[0] = v->data[0][0];
4401 Serge 89
   if (st_fb_orientation(ctx->DrawBuffer) == Y_0_TOP)
4358 Serge 90
   win[1] = ctx->DrawBuffer->Height - v->data[0][1];
4401 Serge 91
   else
92
      win[1] = v->data[0][1];
4358 Serge 93
   win[2] = v->data[0][2];
94
   win[3] = 1.0F / v->data[0][3];
95
 
96
   /* XXX
97
    * When we compute vertex layout, save info about position of the
98
    * color and texcoord attribs to use here.
99
    */
100
 
101
   slot = st->vertex_result_to_slot[VARYING_SLOT_COL0];
102
   if (slot != ~0U)
103
      color = v->data[slot];
104
   else
105
      color = ctx->Current.Attrib[VERT_ATTRIB_COLOR0];
106
 
107
   slot = st->vertex_result_to_slot[VARYING_SLOT_TEX0];
108
   if (slot != ~0U)
109
      texcoord = v->data[slot];
110
   else
111
      texcoord = ctx->Current.Attrib[VERT_ATTRIB_TEX0];
112
 
113
   _mesa_feedback_vertex(ctx, win, color, texcoord);
114
}
115
 
116
 
117
static void
118
feedback_tri( struct draw_stage *stage, struct prim_header *prim )
119
{
120
   struct feedback_stage *fs = feedback_stage(stage);
121
   struct draw_context *draw = stage->draw;
122
   _mesa_feedback_token(fs->ctx, (GLfloat) GL_POLYGON_TOKEN);
123
   _mesa_feedback_token(fs->ctx, (GLfloat) 3); /* three vertices */
124
   feedback_vertex(fs->ctx, draw, prim->v[0]);
125
   feedback_vertex(fs->ctx, draw, prim->v[1]);
126
   feedback_vertex(fs->ctx, draw, prim->v[2]);
127
}
128
 
129
 
130
static void
131
feedback_line( struct draw_stage *stage, struct prim_header *prim )
132
{
133
   struct feedback_stage *fs = feedback_stage(stage);
134
   struct draw_context *draw = stage->draw;
135
   if (fs->reset_stipple_counter) {
136
      _mesa_feedback_token(fs->ctx, (GLfloat) GL_LINE_RESET_TOKEN);
137
      fs->reset_stipple_counter = GL_FALSE;
138
   }
139
   else {
140
      _mesa_feedback_token(fs->ctx, (GLfloat) GL_LINE_TOKEN);
141
   }
142
   feedback_vertex(fs->ctx, draw, prim->v[0]);
143
   feedback_vertex(fs->ctx, draw, prim->v[1]);
144
}
145
 
146
 
147
static void
148
feedback_point( struct draw_stage *stage, struct prim_header *prim )
149
{
150
   struct feedback_stage *fs = feedback_stage(stage);
151
   struct draw_context *draw = stage->draw;
152
   _mesa_feedback_token(fs->ctx, (GLfloat) GL_POINT_TOKEN);
153
   feedback_vertex(fs->ctx, draw, prim->v[0]);
154
}
155
 
156
 
157
static void
158
feedback_flush( struct draw_stage *stage, unsigned flags )
159
{
160
   /* no-op */
161
}
162
 
163
 
164
static void
165
feedback_reset_stipple_counter( struct draw_stage *stage )
166
{
167
   struct feedback_stage *fs = feedback_stage(stage);
168
   fs->reset_stipple_counter = GL_TRUE;
169
}
170
 
171
 
172
static void
173
feedback_destroy( struct draw_stage *stage )
174
{
175
   /* no-op */
176
}
177
 
178
/**
179
 * Create GL feedback drawing stage.
180
 */
181
static struct draw_stage *
182
draw_glfeedback_stage(struct gl_context *ctx, struct draw_context *draw)
183
{
184
   struct feedback_stage *fs = ST_CALLOC_STRUCT(feedback_stage);
185
 
186
   fs->stage.draw = draw;
187
   fs->stage.next = NULL;
188
   fs->stage.point = feedback_point;
189
   fs->stage.line = feedback_line;
190
   fs->stage.tri = feedback_tri;
191
   fs->stage.flush = feedback_flush;
192
   fs->stage.reset_stipple_counter = feedback_reset_stipple_counter;
193
   fs->stage.destroy = feedback_destroy;
194
   fs->ctx = ctx;
195
 
196
   return &fs->stage;
197
}
198
 
199
 
200
 
201
/**********************************************************************
202
 * GL Selection functions
203
 **********************************************************************/
204
 
205
static void
206
select_tri( struct draw_stage *stage, struct prim_header *prim )
207
{
208
   struct feedback_stage *fs = feedback_stage(stage);
209
   _mesa_update_hitflag( fs->ctx, prim->v[0]->data[0][2] );
210
   _mesa_update_hitflag( fs->ctx, prim->v[1]->data[0][2] );
211
   _mesa_update_hitflag( fs->ctx, prim->v[2]->data[0][2] );
212
}
213
 
214
static void
215
select_line( struct draw_stage *stage, struct prim_header *prim )
216
{
217
   struct feedback_stage *fs = feedback_stage(stage);
218
   _mesa_update_hitflag( fs->ctx, prim->v[0]->data[0][2] );
219
   _mesa_update_hitflag( fs->ctx, prim->v[1]->data[0][2] );
220
}
221
 
222
 
223
static void
224
select_point( struct draw_stage *stage, struct prim_header *prim )
225
{
226
   struct feedback_stage *fs = feedback_stage(stage);
227
   _mesa_update_hitflag( fs->ctx, prim->v[0]->data[0][2] );
228
}
229
 
230
 
231
static void
232
select_flush( struct draw_stage *stage, unsigned flags )
233
{
234
   /* no-op */
235
}
236
 
237
 
238
static void
239
select_reset_stipple_counter( struct draw_stage *stage )
240
{
241
   /* no-op */
242
}
243
 
244
static void
245
select_destroy( struct draw_stage *stage )
246
{
247
   /* no-op */
248
}
249
 
250
 
251
/**
252
 * Create GL selection mode drawing stage.
253
 */
254
static struct draw_stage *
255
draw_glselect_stage(struct gl_context *ctx, struct draw_context *draw)
256
{
257
   struct feedback_stage *fs = ST_CALLOC_STRUCT(feedback_stage);
258
 
259
   fs->stage.draw = draw;
260
   fs->stage.next = NULL;
261
   fs->stage.point = select_point;
262
   fs->stage.line = select_line;
263
   fs->stage.tri = select_tri;
264
   fs->stage.flush = select_flush;
265
   fs->stage.reset_stipple_counter = select_reset_stipple_counter;
266
   fs->stage.destroy = select_destroy;
267
   fs->ctx = ctx;
268
 
269
   return &fs->stage;
270
}
271
 
272
 
273
static void
274
st_RenderMode(struct gl_context *ctx, GLenum newMode )
275
{
276
   struct st_context *st = st_context(ctx);
277
   struct draw_context *draw = st->draw;
278
 
279
   if (newMode == GL_RENDER) {
280
      /* restore normal VBO draw function */
281
      vbo_set_draw_func(ctx, st_draw_vbo);
282
   }
283
   else if (newMode == GL_SELECT) {
284
      if (!st->selection_stage)
285
         st->selection_stage = draw_glselect_stage(ctx, draw);
286
      draw_set_rasterize_stage(draw, st->selection_stage);
287
      /* Plug in new vbo draw function */
288
      vbo_set_draw_func(ctx, st_feedback_draw_vbo);
289
   }
290
   else {
291
      if (!st->feedback_stage)
292
         st->feedback_stage = draw_glfeedback_stage(ctx, draw);
293
      draw_set_rasterize_stage(draw, st->feedback_stage);
294
      /* Plug in new vbo draw function */
295
      vbo_set_draw_func(ctx, st_feedback_draw_vbo);
296
      /* need to generate/use a vertex program that emits pos/color/tex */
297
      st->dirty.st |= ST_NEW_VERTEX_PROGRAM;
298
   }
299
}
300
 
301
 
302
 
303
void st_init_feedback_functions(struct dd_function_table *functions)
304
{
305
   functions->RenderMode = st_RenderMode;
306
}