001package com.fs.starfarer.api.util; 002 003import java.awt.Color; 004 005import org.lwjgl.opengl.GL11; 006 007import com.fs.starfarer.api.graphics.SpriteAPI; 008 009public class WarpingSpriteRendererUtil { 010 011 public static class MutatingValue { 012 013 public float value; 014 015 public float min; 016 public float max; 017 018 public float rate; 019 public float rateSign; 020 021 public float sign = 0; 022 023 public MutatingValue() { 024 025 } 026 public MutatingValue(float min, float max, float rate) { 027 this.min = min; 028 this.max = max; 029 this.rate = Math.abs(rate); 030 031 value = min + (float) Math.random() * (max - min); 032 rateSign = Math.signum(rate); 033 } 034 035 public void set(float min, float max) { 036 this.min = min; 037 this.max = max; 038 value = min + (float) Math.random() * (max - min); 039 } 040 041 public void advance(float amount) { 042 if (rateSign != 0) { 043 value += amount * rate * rateSign; 044 } else { 045 value += amount * rate; 046 } 047 if (value > max) { 048 value = max; 049 rateSign = -1f; 050 } else if (value < min) { 051 value = min; 052 rateSign = 1f; 053 } 054 } 055 056 public float getValue() { 057 if (sign != 0) return value * sign; 058 return value; 059 } 060 061 public void setValue(float value) { 062 this.value = value; 063 } 064 065 public float getMin() { 066 return min; 067 } 068 069 public void setMin(float min) { 070 this.min = min; 071 } 072 073 public float getMax() { 074 return max; 075 } 076 077 public void setMax(float max) { 078 this.max = max; 079 } 080 081 public float getRate() { 082 return rate; 083 } 084 085 public void setRate(float rate) { 086 //System.out.println("RATE: " + rate); 087 this.rate = Math.abs(rate); 088 //rateSign = Math.signum(rate); 089 } 090 091 public float getSign() { 092 return sign; 093 } 094 095 public void setSign(float sign) { 096 this.sign = Math.signum(sign); 097 } 098 099 public void setRandomSign() { 100 sign = (float) Math.signum(Math.random() - 0.5f); 101 if (sign == 0) sign = 1; 102 } 103 public void setRandomRateSign() { 104 rateSign = (float) Math.signum(Math.random() - 0.5f); 105 if (rateSign == 0) rateSign = 1; 106 } 107 108 public float getRateSign() { 109 return rateSign; 110 } 111 112 public void setRateSign(float rateSign) { 113 this.rateSign = rateSign; 114 } 115 116 } 117 118 119 public static class WSVertex { 120 public MutatingValue theta; 121 public MutatingValue radius; 122 123 public WSVertex() { 124 //theta = new MutatingValue(-360f * ((float) Math.random() * 3f + 1f), 360f * ((float) Math.random() * 3f + 1f), 30f + 70f * (float) Math.random()); 125 theta = new MutatingValue(-360f * ((float) Math.random() * 30f + 1f), 360f * ((float) Math.random() * 30f + 1f), 30f + 70f * (float) Math.random()); 126 radius = new MutatingValue(0, 10f + 15f * (float) Math.random(), 3f + 7f * (float) Math.random()); 127 } 128 129 public void advance(float amount) { 130 theta.advance(amount); 131 radius.advance(amount); 132 } 133 134 Object writeReplace() { 135 theta.setMax((int)theta.getMax()); 136 theta.setMin((int)theta.getMin()); 137 theta.setRate((int)theta.getRate()); 138 theta.setValue((int)theta.getValue()); 139 140 radius.setMax((int)radius.getMax()); 141 radius.setMin((int)radius.getMin()); 142 radius.setRate((int)radius.getRate()); 143 radius.setValue((int)radius.getValue()); 144 return this; 145 } 146 } 147 148 private int verticesWide, verticesTall; 149 private WSVertex [] [] vertices; 150 151 public WarpingSpriteRendererUtil(int verticesWide, int verticesTall, float minWarpRadius, float maxWarpRadius, 152 float warpRateMult) { 153 this.verticesWide = verticesWide; 154 this.verticesTall = verticesTall; 155 156 vertices = new WSVertex[verticesWide][verticesTall]; 157 for (int i = 0; i < verticesWide; i++) { 158 for (int j = 0; j < verticesTall; j++) { 159 vertices[i][j] = new WSVertex(); 160 161 vertices[i][j].radius.set(minWarpRadius, maxWarpRadius); 162 vertices[i][j].radius.rate *= warpRateMult; 163 vertices[i][j].theta.rate *= warpRateMult; 164 165 } 166 } 167 168 readResolve(); 169 } 170 171 Object readResolve() { 172 return this; 173 } 174 175 public void advance(float amount) { 176 for (int i = 0; i < verticesWide; i++) { 177 for (int j = 0; j < verticesTall; j++) { 178 vertices[i][j].advance(amount); 179 } 180 } 181 } 182 183 public void renderNoBlendOrRotate(SpriteAPI sprite, float x, float y) { 184 renderNoBlendOrRotate(sprite, x, y, true); 185 } 186 187 public void renderNoBlendOrRotate(SpriteAPI sprite, float xOff, float yOff, boolean disableBlend) { 188 189 sprite.bindTexture(); 190 GL11.glPushMatrix(); 191 192 Color color = sprite.getColor(); 193 GL11.glColor4ub((byte) color.getRed(), (byte) color.getGreen(), 194 (byte) color.getBlue(), (byte)(color.getAlpha() * sprite.getAlphaMult())); 195 196 // translate to the right location and prepare to draw 197 GL11.glTranslatef(xOff, yOff, 0); 198 199 GL11.glEnable(GL11.GL_TEXTURE_2D); 200 if (disableBlend) { 201 GL11.glDisable(GL11.GL_BLEND); 202 } 203 204 float w = sprite.getWidth(); 205 float h = sprite.getHeight(); 206 float tw = sprite.getTextureWidth() - 0.001f; 207 float th = sprite.getTextureHeight() - 0.001f; 208 209 float cw = w / (float) (verticesWide - 1); 210 float ch = h / (float) (verticesTall- 1); 211 float ctw = tw / (float) (verticesWide - 1); 212 float cth = th / (float) (verticesTall- 1); 213 214 for (float i = 0; i < verticesWide - 1; i++) { 215 //for (float i = 5; i < 7; i++) { 216 GL11.glBegin(GL11.GL_QUAD_STRIP); 217 { 218 for (float j = 0; j < verticesTall; j++) { 219 float x1 = cw * i; 220 float y1 = ch * j; 221 float x2 = cw * (i + 1f); 222 float y2 = ch * j; 223 224 float tx1 = ctw * i; 225 float ty1 = cth * j; 226 float tx2 = ctw * (i + 1f); 227 float ty2 = cth * j; 228 229 if (i != 0 && i != verticesWide - 1 && j != 0 && j != verticesTall - 1) { 230 float theta = (float) Math.toRadians(vertices[(int)i][(int)j].theta.getValue()); 231 float radius = vertices[(int)i][(int)j].radius.getValue(); 232 float sin = (float) Math.sin(theta); 233 float cos = (float) Math.cos(theta); 234 235 x1 += cos * radius; 236 y1 += sin * radius; 237 //System.out.println("Radius: " + radius); 238 } 239 240 if (i + 1 != 0 && i + 1 != verticesWide - 1 && j != 0 && j != verticesTall - 1) { 241 float theta = (float) Math.toRadians(vertices[(int)i + 1][(int)j].theta.getValue()); 242 float radius = vertices[(int)i + 1][(int)j].radius.getValue(); 243 float sin = (float) Math.sin(theta); 244 float cos = (float) Math.cos(theta); 245 246 x2 += cos * radius; 247 y2 += sin * radius; 248 //System.out.println("Radius: " + radius); 249 } 250 251 GL11.glTexCoord2f(tx1, ty1); 252 GL11.glVertex2f(x1, y1); 253 254 GL11.glTexCoord2f(tx2, ty2); 255 GL11.glVertex2f(x2, y2); 256 } 257 } 258 GL11.glEnd(); 259 260 } 261// GL11.glDisable(GL11.GL_TEXTURE_2D); 262// GL11.glPointSize(32f); 263// GLUtils.setColor(Color.white); 264// GL11.glBegin(GL11.GL_POINTS); 265// for (float i = 0; i < verticesWide - 1; i++) { 266// for (float j = 0; j < verticesTall; j++) { 267// float x1 = cw * i; 268// float y1 = ch * j; 269// float x2 = cw * (i + 1f); 270// float y2 = ch * j; 271// 272// if (i != 0 && i != verticesWide - 1 && j != 0 && j != verticesTall - 1) { 273// float theta = (float) Math.toRadians(vertices[(int)i][(int)j].theta.getValue()); 274// float radius = vertices[(int)i][(int)j].radius.getValue(); 275// float sin = (float) Math.sin(theta); 276// float cos = (float) Math.cos(theta); 277// 278// x1 += cos * radius; 279// y1 += sin * radius; 280// //System.out.println("Radius: " + radius); 281// } 282// 283// 284// GL11.glVertex2f(x1, y1); 285// } 286// } 287// GL11.glEnd(); 288 289 GL11.glPopMatrix(); 290 } 291 292} 293 294 295 296 297 298 299 300 301 302 303 304 305 306