68 public void render(
float alphaMult) {
69 if (alphaMult <= 0)
return;
71 float distClose = delegate.getPulsarInnerRadius();
72 float distFar = delegate.getPulsarOuterRadius();
74 if (distFar < distClose + 10f) distFar = distClose + 10f;
76 float length = distFar - distClose;
78 float wClose = delegate.getPulsarInnerWidth();
79 float wFar = delegate.getPulsarOuterWidth();
81 float pixelsPerSegment = 25f;
82 float segments = Math.round(wFar / pixelsPerSegment);
83 pixelsPerSegment = wFar / segments;
86 Vector2f loc = delegate.getPulsarCenterLoc();
92 GL11.glTranslatef(x, y, 0);
94 GL11.glEnable(GL11.GL_TEXTURE_2D);
102 GL11.glEnable(GL11.GL_BLEND);
103 GL11.glBlendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE);
107 float texHeight = delegate.getPulsarTexture().getTextureHeight();
108 float imageHeight = delegate.getPulsarTexture().getHeight();
109 float texPerSegment = texHeight / segments;
113 float texWidth = delegate.getPulsarTexture().getTextureWidth();
114 float imageWidth = delegate.getPulsarTexture().getWidth();
118 float numIter = (float)Math.ceil(distFar - distClose) / (imageWidth * texWidth);
119 float widthFactor = ((wClose + wFar) / 2f) / (imageHeight * texHeight);
120 numIter /= widthFactor;
122 float texPerUnitLength = 1f / (imageWidth * widthFactor);
124 float angle = currAngle;
128 float fadeInDist = Math.min(1000f, length * 0.25f);
129 float fadeOutDist = Math.min(1500f, length * 0.25f);
131 boolean wireframe =
false;
134 GL11.glPolygonMode(GL11.GL_FRONT_AND_BACK, GL11.GL_LINE);
135 GL11.glDisable(GL11.GL_TEXTURE_2D);
139 float [] rPrev =
new float [(int) segments + 1];
140 float [] blockedPrev =
new float [(int) segments + 1];
142 float [] xPrev =
new float [(int) segments + 1];
143 float [] yPrev =
new float [(int) segments + 1];
145 float [] texPrev =
new float [(int) segments + 1];
147 int numInnerSegments = (int) ((length - fadeInDist - fadeOutDist) / (pixelsPerSegment * 5f));
148 if (numInnerSegments < 1) numInnerSegments = 1;
149 numInnerSegments = 1;
151 int numSegments = 2 + numInnerSegments;
152 float distPerInnerSegment = (length - fadeInDist - fadeOutDist) / (
float) numInnerSegments;
154 boolean arrays =
false;
157 int numVertices = (numSegments) * ((
int) segments + 1) * 2;
160 if (vertexBuffer ==
null) {
161 vertexBuffer = ByteBuffer.allocateDirect(numVertices * 4 * 2).order(ByteOrder.nativeOrder()).asFloatBuffer();
163 if (textureBuffer ==
null) {
164 textureBuffer = ByteBuffer.allocateDirect(numVertices * 4 * 2).order(ByteOrder.nativeOrder()).asFloatBuffer();
166 if (colorBuffer ==
null) {
167 colorBuffer = ByteBuffer.allocateDirect(numVertices * 4).order(ByteOrder.nativeOrder());
170 vertexBuffer.clear();
171 textureBuffer.clear();
183 delegate.getPulsarTexture().bindTexture();
186 for (
int j = 0; j < numSegments; j++) {
189 boolean isFirst = j == 0;
190 boolean isLast = j == numSegments - 1;
191 boolean isMid = !isFirst && !isLast;
193 float alphaCloser = 1f;
194 float alphaFarther = 1f;
195 float r1 = distClose;
202 r2 = distClose + fadeInDist;
209 r1 = distClose + (j - 1) * distPerInnerSegment + fadeInDist;
210 r2 = r1 + distPerInnerSegment;
216 r1 = distFar - fadeOutDist;
222 float w1 = wClose + (wFar - wClose) * (r1 - distClose) / length;
223 float w2 = wClose + (wFar - wClose) * (r2 - distClose) / length;
225 float arcClose = (float) Math.toRadians(Misc.computeAngleSpan(w1 / 2f, r1));
226 float arcFar = (float) Math.toRadians(Misc.computeAngleSpan(w2 / 2f, r2));
228 float closeAnglePerSegment = arcClose / segments;
229 float farAnglePerSegment = arcFar / segments;
231 float currCloseAngle = (float) Math.toRadians(angle) - arcClose / 2f;
232 float currFarAngle = (float) Math.toRadians(angle) - arcFar / 2f;
241 float texProgress = 0f;
244 GL11.glBegin(GL11.GL_QUAD_STRIP);
245 for (
float i = 0; i < segments + 1; i++) {
246 float blockedAt = 1f;
247 float blockerMax = 100000f;
248 if (isMid && blocker !=
null) {
249 blockerMax = blocker.
getCurrMaxAt((
float) Math.toDegrees((currCloseAngle)));
253 if (blockerMax < fadeInDist + 100) {
254 blockerMax = fadeInDist + 100;
256 blockedAt = (blockerMax - r1) / (r2 - r1);
257 if (blockedAt > 1) blockedAt = 1;
258 if (blockedAt < 0) blockedAt = 0;
260 rPrev[(int) i] = Math.min(r2, blockerMax);
261 blockedPrev[(int) i] = blockedAt;
267 float extraAlpha = 1f;
279 curr1 = rPrev[(int) i];
280 float block = blockedPrev[(int) i];
281 curr2 = curr1 + Math.max(300f, fadeOutDist * block);
289 w2 = wClose + (wFar - wClose) * (curr2 - distClose) / length;
290 arcFar = (float) Math.toRadians(Misc.computeAngleSpan(w2 / 2f, curr2));
291 farAnglePerSegment = arcFar / segments;
292 currFarAngle = (float) Math.toRadians(angle) - arcFar / 2f + farAnglePerSegment * i;
296 float cosClose = (float) Math.cos(currCloseAngle);
297 float sinClose = (float) Math.sin(currCloseAngle);
299 float cosFar = (float) Math.cos(currFarAngle);
300 float sinFar = (float) Math.sin(currFarAngle);
302 float x1 = cosClose * curr1;
303 float y1 = sinClose * curr1;
304 float x2 = cosFar * curr2;
305 float y2 = sinFar * curr2;
308 if (isMid || isLast) {
314 x2 = x1 + (x2 - x1) * blockedAt;
315 y2 = y1 + (y2 - y1) * blockedAt;
320 float closeTX = texWidth * texPerUnitLength * (curr1 - distClose) - texOffset;
321 float farTX = texWidth * texPerUnitLength * ((curr1 + (curr2 - curr1) * blockedAt) - distClose) - texOffset;
323 if (isMid || isLast) {
324 closeTX = texPrev[(int) i];
326 texPrev[(int) i] = farTX;
332 }
else if (i > segments - 1 - max) {
333 edgeMult = 1f - (i - (segments - max)) / max;
336 Color color = delegate.getPulsarColorForAngle(angle);
340 vertexBuffer.put(x1).put(y1).put(x2).put(y2);
343 textureBuffer.put(closeTX).put(texProgress).put(farTX).put(texProgress);
344 colorBuffer.put((
byte)color.getRed()).
345 put((
byte)color.getGreen()).
346 put((
byte)color.getBlue()).
347 put((
byte)((float) color.getAlpha() * alphaMult * alphaCloser * edgeMult * extraAlpha));
348 colorBuffer.put((
byte)color.getRed()).
349 put((
byte)color.getGreen()).
350 put((
byte)color.getBlue()).
351 put((
byte)((float) color.getAlpha() * alphaMult * alphaFarther * edgeMult * extraAlpha));
353 GL11.glColor4ub((
byte)color.getRed(),
354 (byte)color.getGreen(),
355 (byte)color.getBlue(),
356 (byte)((
float) color.getAlpha() * alphaMult * alphaCloser * edgeMult * extraAlpha));
358 GL11.glTexCoord2f(closeTX, texProgress);
359 GL11.glVertex2f(x1, y1);
361 GL11.glColor4ub((
byte)color.getRed(),
362 (byte)color.getGreen(),
363 (byte)color.getBlue(),
364 (byte)((
float) color.getAlpha() * alphaMult * alphaFarther * edgeMult * extraAlpha));
365 GL11.glTexCoord2f(farTX, texProgress);
366 GL11.glVertex2f(x2, y2);
371 texProgress += texPerSegment * 1f;
372 currCloseAngle += closeAnglePerSegment;
373 currFarAngle += farAnglePerSegment;
383 vertexBuffer.position(0);
384 textureBuffer.position(0);
385 colorBuffer.position(0);
387 GL11.glEnableClientState(GL11.GL_VERTEX_ARRAY);
388 GL11.glEnableClientState(GL11.GL_TEXTURE_COORD_ARRAY);
389 GL11.glEnableClientState(GL11.GL_COLOR_ARRAY);
391 GL11.glTexCoordPointer(2, 0, textureBuffer);
392 GL11.glColorPointer(4,
true, 0, colorBuffer);
393 GL11.glVertexPointer(2, 0, vertexBuffer);
396 GL11.glDrawArrays(GL11.GL_QUAD_STRIP, 0, numVertices);
398 GL11.glDisableClientState(GL11.GL_VERTEX_ARRAY);
399 GL11.glDisableClientState(GL11.GL_TEXTURE_COORD_ARRAY);
400 GL11.glDisableClientState(GL11.GL_COLOR_ARRAY);
404 if (wireframe) GL11.glPolygonMode(GL11.GL_FRONT_AND_BACK, GL11.GL_FILL);