Line data Source code
1 0 : /*
2 :
3 : OOCrosshairs.m
4 : Oolite
5 :
6 :
7 : Copyright (C) 2008 Jens Ayton
8 :
9 : Permission is hereby granted, free of charge, to any person obtaining a copy
10 : of this software and associated documentation files (the "Software"), to deal
11 : in the Software without restriction, including without limitation the rights
12 : to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
13 : copies of the Software, and to permit persons to whom the Software is
14 : furnished to do so, subject to the following conditions:
15 :
16 : The above copyright notice and this permission notice shall be included in all
17 : copies or substantial portions of the Software.
18 :
19 : THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20 : IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21 : FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
22 : AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
23 : LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
24 : OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
25 : SOFTWARE.
26 :
27 : */
28 :
29 : #import "OOCrosshairs.h"
30 : #import "OOColor.h"
31 : #import "OOCollectionExtractors.h"
32 : #import "Universe.h"
33 : #import "MyOpenGLView.h"
34 : #import "OOMacroOpenGL.h"
35 :
36 :
37 : @interface OOCrosshairs (Private)
38 :
39 0 : - (void) setUpDataWithPoints:(NSArray *)points
40 : scale:(GLfloat)scale
41 : color:(OOColor *)color
42 : overallAlpha:(GLfloat)alpha;
43 :
44 0 : - (void) setUpDataForOnePoint:(NSArray *)pointInfo
45 : scale:(GLfloat)scale
46 : colorComps:(float[4])colorComps
47 : overallAlpha:(GLfloat)alpha
48 : data:(GLfloat *)ioBuffer;
49 :
50 : @end
51 :
52 :
53 : @implementation OOCrosshairs
54 :
55 : - (id) initWithPoints:(NSArray *)points
56 : scale:(GLfloat)scale
57 : color:(OOColor *)color
58 : overallAlpha:(GLfloat)alpha
59 : {
60 : if ((self = [super init]))
61 : {
62 : if (alpha > 0.0f && (color == nil || [color alphaComponent] != 0.0f))
63 : {
64 : [self setUpDataWithPoints:points scale:scale color:color overallAlpha:alpha];
65 : }
66 : }
67 :
68 : return self;
69 : }
70 :
71 :
72 0 : - (void) dealloc
73 : {
74 : free(_data);
75 :
76 : [super dealloc];
77 : }
78 :
79 :
80 : - (void) render
81 : {
82 : if (_data != NULL)
83 : {
84 : OO_ENTER_OPENGL();
85 : OOSetOpenGLState(OPENGL_STATE_OVERLAY);
86 :
87 : OOGL(glPushAttrib(GL_ENABLE_BIT));
88 : OOGL(glDisable(GL_LIGHTING));
89 : OOGL(glDisable(GL_TEXTURE_2D));
90 : OOGLPushModelView();
91 : OOGLTranslateModelView(make_vector(0.0, 0.0, [[UNIVERSE gameView] display_z]));
92 :
93 : OOGL(glVertexPointer(2, GL_FLOAT, sizeof (GLfloat) * 6, _data));
94 : OOGL(glColorPointer(4, GL_FLOAT, sizeof (GLfloat) * 6, _data + 2));
95 :
96 : OOGL(glEnableClientState(GL_VERTEX_ARRAY));
97 : OOGL(glEnableClientState(GL_COLOR_ARRAY));
98 :
99 : OOGL(glDrawArrays(GL_LINES, 0, _count * 2));
100 :
101 : OOGL(glDisableClientState(GL_VERTEX_ARRAY));
102 : OOGL(glDisableClientState(GL_COLOR_ARRAY));
103 :
104 : OOGLPopModelView();
105 : OOGL(glPopAttrib());
106 :
107 : OOVerifyOpenGLState();
108 : OOCheckOpenGLErrors(@"OOCrosshairs after rendering");
109 : }
110 : }
111 :
112 :
113 0 : - (void) setUpDataWithPoints:(NSArray *)points
114 : scale:(GLfloat)scale
115 : color:(OOColor *)color
116 : overallAlpha:(GLfloat)alpha
117 : {
118 : NSUInteger i;
119 : float colorComps[4] = { 0.0f, 1.0f, 0.0f, 1.0f };
120 : GLfloat *data = NULL;
121 :
122 : _count = [points count];
123 : if (_count == 0) return;
124 :
125 : _data = malloc(sizeof (GLfloat) * 12 * _count); // 2 coordinates, 4 colour components for each endpoint of each line segment
126 : [color getRed:&colorComps[0] green:&colorComps[1] blue:&colorComps[2] alpha:&colorComps[3]];
127 :
128 : // Turn NSArray into GL-friendly element array
129 : data = _data;
130 : for (i = 0; i < _count; i++)
131 : {
132 : [self setUpDataForOnePoint:[points oo_arrayAtIndex:i]
133 : scale:scale
134 : colorComps:colorComps
135 : overallAlpha:alpha
136 : data:data];
137 : data += 12;
138 : }
139 : }
140 :
141 :
142 0 : - (void) setUpDataForOnePoint:(NSArray *)pointInfo
143 : scale:(GLfloat)scale
144 : colorComps:(float[4])colorComps
145 : overallAlpha:(GLfloat)alpha
146 : data:(GLfloat *)ioBuffer
147 : {
148 : GLfloat x1, y1, a1, x2, y2, a2;
149 : GLfloat r, g, b, a;
150 :
151 : if ([pointInfo count] >= 6)
152 : {
153 : a1 = [pointInfo oo_floatAtIndex:0];
154 : x1 = [pointInfo oo_floatAtIndex:1] * scale;
155 : y1 = [pointInfo oo_floatAtIndex:2] * scale;
156 : a2 = [pointInfo oo_floatAtIndex:3];
157 : x2 = [pointInfo oo_floatAtIndex:4] * scale;
158 : y2 = [pointInfo oo_floatAtIndex:5] * scale;
159 : r = colorComps[0];
160 : g = colorComps[1];
161 : b = colorComps[2];
162 : a = colorComps[3];
163 :
164 : /* a1/a2 * a is hud.plist and crosshairs.plist - specified alpha,
165 : which must be clamped to 0..1 so the plist-specified alpha can't
166 : "escape" the overall alpha range. The result of scaling this by
167 : overall HUD alpha is then clamped again for robustness.
168 : */
169 : a1 = OOClamp_0_1_f(OOClamp_0_1_f(a1 * a) * alpha);
170 : a2 = OOClamp_0_1_f(OOClamp_0_1_f(a2 * a) * alpha);
171 : }
172 : else
173 : {
174 : // Bad entry, write red point in middle.
175 : x1 = -0.01f;
176 : x2 = 0.01f;
177 : y1 = y2 = 0.0f;
178 : r = 1.0f;
179 : g = b = 0.0f;
180 : a1 = a2 = 1.0;
181 : }
182 :
183 : *ioBuffer++ = x1;
184 : *ioBuffer++ = y1;
185 : *ioBuffer++ = r;
186 : *ioBuffer++ = g;
187 : *ioBuffer++ = b;
188 : *ioBuffer++ = a1;
189 :
190 : *ioBuffer++ = x2;
191 : *ioBuffer++ = y2;
192 : *ioBuffer++ = r;
193 : *ioBuffer++ = g;
194 : *ioBuffer++ = b;
195 : *ioBuffer++ = a2;
196 :
197 : (void)ioBuffer;
198 : }
199 :
200 : @end
|