PageRenderTime 45ms CodeModel.GetById 24ms RepoModel.GetById 0ms app.codeStats 0ms

/newcode/src/com/prupe/mcpatcher/ctm/RenderPass.java

https://bitbucket.org/SevenBits/mcpatcher
Java | 342 lines | 297 code | 42 blank | 3 comment | 58 complexity | 9e8b87acd88985c480dd581b59b609d8 MD5 | raw file
  1. package com.prupe.mcpatcher.ctm;
  2. import com.prupe.mcpatcher.*;
  3. import com.prupe.mcpatcher.mal.block.BlockAPI;
  4. import com.prupe.mcpatcher.mal.block.RenderPassAPI;
  5. import net.minecraft.src.*;
  6. import org.lwjgl.opengl.GL11;
  7. import java.util.*;
  8. public class RenderPass {
  9. private static final MCLogger logger = MCLogger.getLogger(MCPatcherUtils.BETTER_GLASS);
  10. private static final ResourceLocation RENDERPASS_PROPERTIES = TexturePackAPI.newMCPatcherResourceLocation("renderpass.properties");
  11. private static final Map<Block, Integer> baseRenderPass = new IdentityHashMap<Block, Integer>();
  12. private static final Map<Block, Integer> extraRenderPass = new IdentityHashMap<Block, Integer>();
  13. private static final Map<Block, Integer> renderPassBits = new IdentityHashMap<Block, Integer>();
  14. private static final Set<Block> customRenderPassBlocks = new HashSet<Block>();
  15. private static BlendMethod blendMethod;
  16. private static ResourceLocation blendBlankResource;
  17. private static boolean enableLightmap;
  18. private static boolean enableColormap;
  19. private static final boolean[] backfaceCulling = new boolean[RenderPassAPI.NUM_RENDER_PASSES];
  20. private static int currentRenderPass = -1;
  21. private static int maxRenderPass = 1;
  22. private static boolean canRenderInThisPass;
  23. private static boolean hasCustomRenderPasses;
  24. private static boolean ambientOcclusion;
  25. private static final int COLOR_POS_0 = 3;
  26. private static final int COLOR_POS_1 = COLOR_POS_0 + 7;
  27. private static final int COLOR_POS_2 = COLOR_POS_1 + 7;
  28. private static final int COLOR_POS_3 = COLOR_POS_2 + 7;
  29. private static int saveColor0;
  30. private static int saveColor1;
  31. private static int saveColor2;
  32. private static int saveColor3;
  33. static {
  34. RenderPassAPI.instance = new RenderPassAPI() {
  35. @Override
  36. public boolean skipDefaultRendering(Block block) {
  37. return currentRenderPass > MAX_BASE_RENDER_PASS;
  38. }
  39. @Override
  40. public boolean skipThisRenderPass(Block block, int pass) {
  41. if (currentRenderPass < 0) {
  42. return pass > MAX_BASE_RENDER_PASS;
  43. }
  44. if (pass < 0) {
  45. pass = RenderPassMap.instance.getDefaultRenderPass(block);
  46. }
  47. return pass != currentRenderPass;
  48. }
  49. @Override
  50. public boolean useColorMultiplierThisPass(Block block) {
  51. return currentRenderPass != OVERLAY_RENDER_PASS || enableColormap;
  52. }
  53. @Override
  54. public boolean useLightmapThisPass() {
  55. return currentRenderPass != OVERLAY_RENDER_PASS || enableLightmap;
  56. }
  57. @Override
  58. public void clear() {
  59. canRenderInThisPass = false;
  60. maxRenderPass = MAX_BASE_RENDER_PASS - 1;
  61. baseRenderPass.clear();
  62. extraRenderPass.clear();
  63. renderPassBits.clear();
  64. customRenderPassBlocks.clear();
  65. blendMethod = BlendMethod.ALPHA;
  66. blendBlankResource = blendMethod.getBlankResource();
  67. if (blendBlankResource == null) {
  68. blendBlankResource = BlendMethod.ALPHA.getBlankResource();
  69. }
  70. enableLightmap = true;
  71. enableColormap = false;
  72. Arrays.fill(backfaceCulling, true);
  73. backfaceCulling[RenderPassAPI.BACKFACE_RENDER_PASS] = false;
  74. for (Block block : BlockAPI.getAllBlocks()) {
  75. baseRenderPass.put(block, RenderPassMap.instance.getDefaultRenderPass(block));
  76. }
  77. }
  78. @Override
  79. public void refreshBlendingOptions() {
  80. Properties properties = TexturePackAPI.getProperties(RENDERPASS_PROPERTIES);
  81. if (properties != null) {
  82. properties = remapProperties(properties);
  83. String method = properties.getProperty("blend.overlay", "alpha").trim().toLowerCase();
  84. blendMethod = BlendMethod.parse(method);
  85. if (blendMethod == null) {
  86. logger.error("%s: unknown blend method '%s'", RENDERPASS_PROPERTIES, method);
  87. blendMethod = BlendMethod.ALPHA;
  88. }
  89. blendBlankResource = blendMethod.getBlankResource();
  90. if (blendBlankResource == null) {
  91. blendBlankResource = BlendMethod.ALPHA.getBlankResource();
  92. }
  93. enableLightmap = MCPatcherUtils.getBooleanProperty(properties, "enableLightmap.overlay", !blendMethod.isColorBased());
  94. enableColormap = MCPatcherUtils.getBooleanProperty(properties, "enableColormap.overlay", false);
  95. backfaceCulling[RenderPassAPI.OVERLAY_RENDER_PASS] = MCPatcherUtils.getBooleanProperty(properties, "backfaceCulling.overlay", true);
  96. backfaceCulling[RenderPassAPI.CUTOUT_RENDER_PASS] = backfaceCulling[RenderPassMap.instance.getCutoutRenderPass()] = MCPatcherUtils.getBooleanProperty(properties, "backfaceCulling.cutout", true);
  97. backfaceCulling[RenderPassAPI.CUTOUT_MIPPED_RENDER_PASS] = MCPatcherUtils.getBooleanProperty(properties, "backfaceCulling.cutout_mipped", backfaceCulling[RenderPassAPI.CUTOUT_RENDER_PASS]);
  98. backfaceCulling[RenderPassAPI.TRANSLUCENT_RENDER_PASS] = MCPatcherUtils.getBooleanProperty(properties, "backfaceCulling.translucent", true);
  99. }
  100. }
  101. private Properties remapProperties(Properties properties) {
  102. Properties newProperties = new Properties();
  103. for (Map.Entry<Object, Object> entry : properties.entrySet()) {
  104. String key = (String) entry.getKey();
  105. key = key.replaceFirst("\\.3$", ".overlay");
  106. key = key.replaceFirst("\\.2$", ".backface");
  107. if (!key.equals(entry.getKey())) {
  108. logger.warning("%s: %s is deprecated in 1.8. Use %s instead", RENDERPASS_PROPERTIES, entry.getKey(), key);
  109. }
  110. newProperties.put(key, entry.getValue());
  111. }
  112. return newProperties;
  113. }
  114. @Override
  115. public void setRenderPassForBlock(Block block, int pass) {
  116. if (block == null || pass < 0) {
  117. return;
  118. }
  119. String name;
  120. if (pass <= MAX_BASE_RENDER_PASS) {
  121. baseRenderPass.put(block, pass);
  122. name = "base";
  123. } else {
  124. extraRenderPass.put(block, pass);
  125. name = "extra";
  126. }
  127. logger.fine("%s %s render pass -> %s",
  128. BlockAPI.getBlockName(block), name, RenderPassAPI.instance.getRenderPassName(pass)
  129. );
  130. customRenderPassBlocks.add(block);
  131. maxRenderPass = Math.max(maxRenderPass, pass);
  132. }
  133. @Override
  134. public ResourceLocation getBlankResource(int pass) {
  135. return pass == OVERLAY_RENDER_PASS ? blendBlankResource : super.getBlankResource(pass);
  136. }
  137. @Override
  138. public ResourceLocation getBlankResource() {
  139. return getBlankResource(currentRenderPass);
  140. }
  141. };
  142. TexturePackChangeHandler.register(new TexturePackChangeHandler(MCPatcherUtils.BETTER_GLASS, 4) {
  143. @Override
  144. public void beforeChange() {
  145. }
  146. @Override
  147. public void afterChange() {
  148. for (Block block : BlockAPI.getAllBlocks()) {
  149. int bits = 0;
  150. Integer i = baseRenderPass.get(block);
  151. if (i != null && i >= 0) {
  152. bits |= (1 << i);
  153. }
  154. i = extraRenderPass.get(block);
  155. if (i != null && i >= 0) {
  156. bits |= (1 << i);
  157. }
  158. renderPassBits.put(block, bits);
  159. }
  160. }
  161. });
  162. }
  163. public static void start(int pass) {
  164. currentRenderPass = RenderPassMap.instance.vanillaToMCPatcher(pass);
  165. CTMUtils.setBlankResource();
  166. }
  167. public static void finish() {
  168. currentRenderPass = -1;
  169. CTMUtils.setBlankResource();
  170. }
  171. public static boolean skipAllRenderPasses(boolean[] skipRenderPass) {
  172. return skipRenderPass[0] && skipRenderPass[1] && skipRenderPass[2] && skipRenderPass[3];
  173. }
  174. public static boolean checkRenderPasses(Block block, boolean moreRenderPasses) {
  175. int bits = renderPassBits.get(block) >>> currentRenderPass;
  176. canRenderInThisPass = (bits & 1) != 0;
  177. hasCustomRenderPasses = customRenderPassBlocks.contains(block);
  178. return moreRenderPasses || (bits >>> 1) != 0;
  179. }
  180. public static boolean canRenderInThisPass(boolean canRender) {
  181. return hasCustomRenderPasses ? canRenderInThisPass : canRender;
  182. }
  183. // pre-14w02a
  184. public static boolean shouldSideBeRendered(Block block, IBlockAccess blockAccess, int i, int j, int k, int face) {
  185. if (BlockAPI.shouldSideBeRendered(block, blockAccess, i, j, k, face)) {
  186. return true;
  187. } else if (!extraRenderPass.containsKey(block)) {
  188. Block neighbor = BlockAPI.getBlockAt(blockAccess, i, j, k);
  189. return extraRenderPass.containsKey(neighbor);
  190. } else {
  191. return false;
  192. }
  193. }
  194. // 14w02a+
  195. public static boolean shouldSideBeRendered(Block block, IBlockAccess blockAccess, Position position, Direction direction) {
  196. if (block.shouldSideBeRendered(blockAccess, position, direction)) {
  197. return true;
  198. } else if (!extraRenderPass.containsKey(block)) {
  199. Block neighbor = blockAccess.getBlock(position);
  200. return extraRenderPass.containsKey(neighbor);
  201. } else {
  202. return false;
  203. }
  204. }
  205. public static boolean setAmbientOcclusion(boolean ambientOcclusion) {
  206. RenderPass.ambientOcclusion = ambientOcclusion;
  207. return ambientOcclusion;
  208. }
  209. public static float getAOBaseMultiplier(float multiplier) {
  210. return RenderPassAPI.instance.useLightmapThisPass() ? multiplier : 1.0f;
  211. }
  212. public static boolean useBlockShading() {
  213. return RenderPassAPI.instance.useLightmapThisPass();
  214. }
  215. // *sigh* Mojang removed the "unshaded" model face buffer in 14w11a, making this hack necessary again
  216. public static void unshadeBuffer(int[] b) {
  217. if (!useBlockShading()) {
  218. saveColor0 = b[COLOR_POS_0];
  219. saveColor1 = b[COLOR_POS_1];
  220. saveColor2 = b[COLOR_POS_2];
  221. saveColor3 = b[COLOR_POS_3];
  222. b[COLOR_POS_0] = b[COLOR_POS_1] = b[COLOR_POS_2] = b[COLOR_POS_3] = -1;
  223. }
  224. }
  225. public static void reshadeBuffer(int[] b) {
  226. if (!useBlockShading()) {
  227. b[COLOR_POS_0] = saveColor0;
  228. b[COLOR_POS_1] = saveColor1;
  229. b[COLOR_POS_2] = saveColor2;
  230. b[COLOR_POS_3] = saveColor3;
  231. }
  232. }
  233. public static boolean preRenderPass(int pass) {
  234. currentRenderPass = pass;
  235. if (pass > maxRenderPass) {
  236. return false;
  237. }
  238. switch (pass) {
  239. case RenderPassAPI.SOLID_RENDER_PASS:
  240. case RenderPassAPI.CUTOUT_MIPPED_RENDER_PASS:
  241. case RenderPassAPI.CUTOUT_RENDER_PASS:
  242. case RenderPassAPI.TRANSLUCENT_RENDER_PASS:
  243. case RenderPassAPI.BACKFACE_RENDER_PASS:
  244. if (!backfaceCulling[pass]) {
  245. GL11.glDisable(GL11.GL_CULL_FACE);
  246. }
  247. break;
  248. case RenderPassAPI.OVERLAY_RENDER_PASS:
  249. GL11.glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
  250. GL11.glPolygonOffset(-2.0f, -2.0f);
  251. GL11.glEnable(GL11.GL_POLYGON_OFFSET_FILL);
  252. if (backfaceCulling[pass]) {
  253. GL11.glEnable(GL11.GL_CULL_FACE);
  254. } else {
  255. GL11.glDisable(GL11.GL_CULL_FACE);
  256. }
  257. if (ambientOcclusion) {
  258. GL11.glShadeModel(GL11.GL_SMOOTH);
  259. }
  260. blendMethod.applyBlending();
  261. break;
  262. default:
  263. break;
  264. }
  265. return true;
  266. }
  267. public static int postRenderPass(int value) {
  268. switch (currentRenderPass) {
  269. case RenderPassAPI.SOLID_RENDER_PASS:
  270. case RenderPassAPI.CUTOUT_MIPPED_RENDER_PASS:
  271. case RenderPassAPI.CUTOUT_RENDER_PASS:
  272. case RenderPassAPI.TRANSLUCENT_RENDER_PASS:
  273. case RenderPassAPI.BACKFACE_RENDER_PASS:
  274. if (!backfaceCulling[currentRenderPass]) {
  275. GL11.glEnable(GL11.GL_CULL_FACE);
  276. }
  277. break;
  278. case RenderPassAPI.OVERLAY_RENDER_PASS:
  279. GL11.glPolygonOffset(0.0f, 0.0f);
  280. GL11.glDisable(GL11.GL_POLYGON_OFFSET_FILL);
  281. if (!backfaceCulling[currentRenderPass]) {
  282. GL11.glEnable(GL11.GL_CULL_FACE);
  283. }
  284. GL11.glDisable(GL11.GL_BLEND);
  285. GL11.glShadeModel(GL11.GL_FLAT);
  286. break;
  287. default:
  288. break;
  289. }
  290. currentRenderPass = -1;
  291. return value;
  292. }
  293. public static void enableDisableLightmap(EntityRenderer renderer, double partialTick) {
  294. if (RenderPassAPI.instance.useLightmapThisPass()) {
  295. renderer.enableLightmap(partialTick);
  296. } else {
  297. renderer.disableLightmap(partialTick);
  298. }
  299. }
  300. }