PageRenderTime 52ms CodeModel.GetById 1ms RepoModel.GetById 0ms app.codeStats 0ms

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

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