1 /*
2  * Mesa 3-D graphics library
3  *
4  * Copyright (C) 1999-2007  Brian Paul   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 "Software"),
8  * to deal in the Software without restriction, including without limitation
9  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
10  * and/or sell copies of the Software, and to permit persons to whom the
11  * Software is furnished to do so, subject to the following conditions:
12  *
13  * The above copyright notice and this permission notice shall be included
14  * in all copies or substantial portions of the Software.
15  *
16  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
17  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
19  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
20  * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
21  * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
22  * OTHER DEALINGS IN THE SOFTWARE.
23  */
24 
25 #include "main/glheader.h"
26 #include "main/feedback.h"
27 #include "main/macros.h"
28 
29 #include "s_context.h"
30 #include "s_feedback.h"
31 #include "s_triangle.h"
32 
33 
34 
35 static void
feedback_vertex(struct gl_context * ctx,const SWvertex * v,const SWvertex * pv)36 feedback_vertex(struct gl_context * ctx, const SWvertex * v, const SWvertex * pv)
37 {
38    GLfloat win[4];
39    const GLfloat *vtc = v->attrib[VARYING_SLOT_TEX0];
40    const GLfloat *color = v->attrib[VARYING_SLOT_COL0];
41 
42    win[0] = v->attrib[VARYING_SLOT_POS][0];
43    win[1] = v->attrib[VARYING_SLOT_POS][1];
44    win[2] = v->attrib[VARYING_SLOT_POS][2] / ctx->DrawBuffer->_DepthMaxF;
45    win[3] = 1.0F / v->attrib[VARYING_SLOT_POS][3];
46 
47    _mesa_feedback_vertex(ctx, win, color, vtc);
48 }
49 
50 
51 /*
52  * Put triangle in feedback buffer.
53  */
54 void
_swrast_feedback_triangle(struct gl_context * ctx,const SWvertex * v0,const SWvertex * v1,const SWvertex * v2)55 _swrast_feedback_triangle(struct gl_context *ctx, const SWvertex *v0,
56                           const SWvertex *v1, const SWvertex *v2)
57 {
58    if (!_swrast_culltriangle(ctx, v0, v1, v2)) {
59       _mesa_feedback_token(ctx, (GLfloat) (GLint) GL_POLYGON_TOKEN);
60       _mesa_feedback_token(ctx, (GLfloat) 3); /* three vertices */
61 
62       if (ctx->Light.ShadeModel == GL_SMOOTH) {
63          feedback_vertex(ctx, v0, v0);
64          feedback_vertex(ctx, v1, v1);
65          feedback_vertex(ctx, v2, v2);
66       }
67       else {
68          feedback_vertex(ctx, v0, v2);
69          feedback_vertex(ctx, v1, v2);
70          feedback_vertex(ctx, v2, v2);
71       }
72    }
73 }
74 
75 
76 void
_swrast_feedback_line(struct gl_context * ctx,const SWvertex * v0,const SWvertex * v1)77 _swrast_feedback_line(struct gl_context *ctx, const SWvertex *v0,
78                       const SWvertex *v1)
79 {
80    GLenum token = GL_LINE_TOKEN;
81    SWcontext *swrast = SWRAST_CONTEXT(ctx);
82 
83    if (swrast->StippleCounter == 0)
84       token = GL_LINE_RESET_TOKEN;
85 
86    _mesa_feedback_token(ctx, (GLfloat) (GLint) token);
87 
88    if (ctx->Light.ShadeModel == GL_SMOOTH) {
89       feedback_vertex(ctx, v0, v0);
90       feedback_vertex(ctx, v1, v1);
91    }
92    else {
93       feedback_vertex(ctx, v0, v1);
94       feedback_vertex(ctx, v1, v1);
95    }
96 
97    swrast->StippleCounter++;
98 }
99 
100 
101 void
_swrast_feedback_point(struct gl_context * ctx,const SWvertex * v)102 _swrast_feedback_point(struct gl_context *ctx, const SWvertex *v)
103 {
104    _mesa_feedback_token(ctx, (GLfloat) (GLint) GL_POINT_TOKEN);
105    feedback_vertex(ctx, v, v);
106 }
107 
108 
109 void
_swrast_select_triangle(struct gl_context * ctx,const SWvertex * v0,const SWvertex * v1,const SWvertex * v2)110 _swrast_select_triangle(struct gl_context *ctx, const SWvertex *v0,
111                         const SWvertex *v1, const SWvertex *v2)
112 {
113    if (!_swrast_culltriangle(ctx, v0, v1, v2)) {
114       const GLfloat zs = 1.0F / ctx->DrawBuffer->_DepthMaxF;
115 
116       _mesa_update_hitflag( ctx, v0->attrib[VARYING_SLOT_POS][2] * zs );
117       _mesa_update_hitflag( ctx, v1->attrib[VARYING_SLOT_POS][2] * zs );
118       _mesa_update_hitflag( ctx, v2->attrib[VARYING_SLOT_POS][2] * zs );
119    }
120 }
121 
122 
123 void
_swrast_select_line(struct gl_context * ctx,const SWvertex * v0,const SWvertex * v1)124 _swrast_select_line(struct gl_context *ctx, const SWvertex *v0, const SWvertex *v1)
125 {
126    const GLfloat zs = 1.0F / ctx->DrawBuffer->_DepthMaxF;
127    _mesa_update_hitflag( ctx, v0->attrib[VARYING_SLOT_POS][2] * zs );
128    _mesa_update_hitflag( ctx, v1->attrib[VARYING_SLOT_POS][2] * zs );
129 }
130 
131 
132 void
_swrast_select_point(struct gl_context * ctx,const SWvertex * v)133 _swrast_select_point(struct gl_context *ctx, const SWvertex *v)
134 {
135    const GLfloat zs = 1.0F / ctx->DrawBuffer->_DepthMaxF;
136    _mesa_update_hitflag( ctx, v->attrib[VARYING_SLOT_POS][2] * zs );
137 }
138