package com.mojang.blaze3d.pipeline; import com.mojang.blaze3d.vertex.BufferBuilder; import com.mojang.blaze3d.vertex.Tesselator; import com.mojang.blaze3d.vertex.DefaultVertexFormat; import java.nio.IntBuffer; import com.mojang.blaze3d.platform.TextureUtil; import com.mojang.blaze3d.platform.GlConst; import com.mojang.blaze3d.platform.GlStateManager; import com.mojang.blaze3d.systems.RenderSystem; public class RenderTarget { public int width; public int height; public int viewWidth; public int viewHeight; public final boolean useDepth; public int frameBufferId; public int colorTextureId; public int depthBufferId; public final float[] clearChannels; public int filterMode; public RenderTarget(final int integer1, final int integer2, final boolean boolean3, final boolean boolean4) { RenderSystem.assertThread(RenderSystem::isOnRenderThreadOrInit); this.useDepth = boolean3; this.frameBufferId = -1; this.colorTextureId = -1; this.depthBufferId = -1; (this.clearChannels = new float[4])[0] = 1.0f; this.clearChannels[1] = 1.0f; this.clearChannels[2] = 1.0f; this.clearChannels[3] = 0.0f; this.resize(integer1, integer2, boolean4); } public void resize(final int integer1, final int integer2, final boolean boolean3) { if (!RenderSystem.isOnRenderThread()) { RenderSystem.recordRenderCall(() -> this._resize(integer1, integer2, boolean3)); } else { this._resize(integer1, integer2, boolean3); } } private void _resize(final int integer1, final int integer2, final boolean boolean3) { RenderSystem.assertThread(RenderSystem::isOnRenderThreadOrInit); GlStateManager._enableDepthTest(); if (this.frameBufferId >= 0) { this.destroyBuffers(); } this.createBuffers(integer1, integer2, boolean3); GlStateManager._glBindFramebuffer(GlConst.GL_FRAMEBUFFER, 0); } public void destroyBuffers() { RenderSystem.assertThread(RenderSystem::isOnRenderThreadOrInit); this.unbindRead(); this.unbindWrite(); if (this.depthBufferId > -1) { TextureUtil.releaseTextureId(this.depthBufferId); this.depthBufferId = -1; } if (this.colorTextureId > -1) { TextureUtil.releaseTextureId(this.colorTextureId); this.colorTextureId = -1; } if (this.frameBufferId > -1) { GlStateManager._glBindFramebuffer(GlConst.GL_FRAMEBUFFER, 0); GlStateManager._glDeleteFramebuffers(this.frameBufferId); this.frameBufferId = -1; } } public void copyDepthFrom(final RenderTarget dgf) { RenderSystem.assertThread(RenderSystem::isOnRenderThreadOrInit); if (GlStateManager.supportsFramebufferBlit()) { GlStateManager._glBindFramebuffer(36008, dgf.frameBufferId); GlStateManager._glBindFramebuffer(36009, this.frameBufferId); GlStateManager._glBlitFrameBuffer(0, 0, dgf.width, dgf.height, 0, 0, this.width, this.height, 256, 9728); } else { GlStateManager._glBindFramebuffer(GlConst.GL_FRAMEBUFFER, this.frameBufferId); final int integer3 = GlStateManager.getFramebufferDepthTexture(); if (integer3 != 0) { final int integer4 = GlStateManager.getActiveTextureName(); GlStateManager._bindTexture(integer3); GlStateManager._glBindFramebuffer(GlConst.GL_FRAMEBUFFER, dgf.frameBufferId); GlStateManager._glCopyTexSubImage2D(3553, 0, 0, 0, 0, 0, Math.min(this.width, dgf.width), Math.min(this.height, dgf.height)); GlStateManager._bindTexture(integer4); } } GlStateManager._glBindFramebuffer(GlConst.GL_FRAMEBUFFER, 0); } public void createBuffers(final int integer1, final int integer2, final boolean boolean3) { RenderSystem.assertThread(RenderSystem::isOnRenderThreadOrInit); this.viewWidth = integer1; this.viewHeight = integer2; this.width = integer1; this.height = integer2; this.frameBufferId = GlStateManager.glGenFramebuffers(); this.colorTextureId = TextureUtil.generateTextureId(); if (this.useDepth) { GlStateManager._bindTexture(this.depthBufferId = TextureUtil.generateTextureId()); GlStateManager._texParameter(3553, 10241, 9728); GlStateManager._texParameter(3553, 10240, 9728); GlStateManager._texParameter(3553, 10242, 10496); GlStateManager._texParameter(3553, 10243, 10496); GlStateManager._texParameter(3553, 34892, 0); GlStateManager._texImage2D(3553, 0, 6402, this.width, this.height, 0, 6402, 5126, null); } this.setFilterMode(9728); GlStateManager._bindTexture(this.colorTextureId); GlStateManager._texImage2D(3553, 0, 32856, this.width, this.height, 0, 6408, 5121, null); GlStateManager._glBindFramebuffer(GlConst.GL_FRAMEBUFFER, this.frameBufferId); GlStateManager._glFramebufferTexture2D(GlConst.GL_FRAMEBUFFER, GlConst.GL_COLOR_ATTACHMENT0, 3553, this.colorTextureId, 0); if (this.useDepth) { GlStateManager._glFramebufferTexture2D(GlConst.GL_FRAMEBUFFER, GlConst.GL_DEPTH_ATTACHMENT, 3553, this.depthBufferId, 0); } this.checkStatus(); this.clear(boolean3); this.unbindRead(); } public void setFilterMode(final int integer) { RenderSystem.assertThread(RenderSystem::isOnRenderThreadOrInit); this.filterMode = integer; GlStateManager._bindTexture(this.colorTextureId); GlStateManager._texParameter(3553, 10241, integer); GlStateManager._texParameter(3553, 10240, integer); GlStateManager._texParameter(3553, 10242, 10496); GlStateManager._texParameter(3553, 10243, 10496); GlStateManager._bindTexture(0); } public void checkStatus() { RenderSystem.assertThread(RenderSystem::isOnRenderThreadOrInit); final int integer2 = GlStateManager.glCheckFramebufferStatus(GlConst.GL_FRAMEBUFFER); if (integer2 == GlConst.GL_FRAMEBUFFER_COMPLETE) { return; } if (integer2 == GlConst.GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT) { throw new RuntimeException("GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT"); } if (integer2 == GlConst.GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT) { throw new RuntimeException("GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT"); } if (integer2 == GlConst.GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER) { throw new RuntimeException("GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER"); } if (integer2 == GlConst.GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER) { throw new RuntimeException("GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER"); } throw new RuntimeException("glCheckFramebufferStatus returned unknown status:" + integer2); } public void bindRead() { RenderSystem.assertThread(RenderSystem::isOnRenderThread); GlStateManager._bindTexture(this.colorTextureId); } public void unbindRead() { RenderSystem.assertThread(RenderSystem::isOnRenderThreadOrInit); GlStateManager._bindTexture(0); } public void bindWrite(final boolean boolean1) { if (!RenderSystem.isOnRenderThread()) { RenderSystem.recordRenderCall(() -> this._bindWrite(boolean1)); } else { this._bindWrite(boolean1); } } private void _bindWrite(final boolean boolean1) { RenderSystem.assertThread(RenderSystem::isOnRenderThreadOrInit); GlStateManager._glBindFramebuffer(GlConst.GL_FRAMEBUFFER, this.frameBufferId); if (boolean1) { GlStateManager._viewport(0, 0, this.viewWidth, this.viewHeight); } } public void unbindWrite() { if (!RenderSystem.isOnRenderThread()) { RenderSystem.recordRenderCall(() -> GlStateManager._glBindFramebuffer(GlConst.GL_FRAMEBUFFER, 0)); } else { GlStateManager._glBindFramebuffer(GlConst.GL_FRAMEBUFFER, 0); } } public void setClearColor(final float float1, final float float2, final float float3, final float float4) { this.clearChannels[0] = float1; this.clearChannels[1] = float2; this.clearChannels[2] = float3; this.clearChannels[3] = float4; } public void blitToScreen(final int integer1, final int integer2) { this.blitToScreen(integer1, integer2, true); } public void blitToScreen(final int integer1, final int integer2, final boolean boolean3) { RenderSystem.assertThread(RenderSystem::isOnGameThreadOrInit); if (!RenderSystem.isInInitPhase()) { RenderSystem.recordRenderCall(() -> this._blitToScreen(integer1, integer2, boolean3)); } else { this._blitToScreen(integer1, integer2, boolean3); } } private void _blitToScreen(final int integer1, final int integer2, final boolean boolean3) { RenderSystem.assertThread(RenderSystem::isOnRenderThread); GlStateManager._colorMask(true, true, true, false); GlStateManager._disableDepthTest(); GlStateManager._depthMask(false); GlStateManager._matrixMode(5889); GlStateManager._loadIdentity(); GlStateManager._ortho(0.0, integer1, integer2, 0.0, 1000.0, 3000.0); GlStateManager._matrixMode(5888); GlStateManager._loadIdentity(); GlStateManager._translatef(0.0f, 0.0f, -2000.0f); GlStateManager._viewport(0, 0, integer1, integer2); GlStateManager._enableTexture(); GlStateManager._disableLighting(); GlStateManager._disableAlphaTest(); if (boolean3) { GlStateManager._disableBlend(); GlStateManager._enableColorMaterial(); } GlStateManager._color4f(1.0f, 1.0f, 1.0f, 1.0f); this.bindRead(); final float float5 = (float)integer1; final float float6 = (float)integer2; final float float7 = this.viewWidth / (float)this.width; final float float8 = this.viewHeight / (float)this.height; final Tesselator dhn9 = RenderSystem.renderThreadTesselator(); final BufferBuilder dhg10 = dhn9.getBuilder(); dhg10.begin(7, DefaultVertexFormat.POSITION_TEX_COLOR); dhg10.vertex(0.0, float6, 0.0).uv(0.0f, 0.0f).color(255, 255, 255, 255).endVertex(); dhg10.vertex(float5, float6, 0.0).uv(float7, 0.0f).color(255, 255, 255, 255).endVertex(); dhg10.vertex(float5, 0.0, 0.0).uv(float7, float8).color(255, 255, 255, 255).endVertex(); dhg10.vertex(0.0, 0.0, 0.0).uv(0.0f, float8).color(255, 255, 255, 255).endVertex(); dhn9.end(); this.unbindRead(); GlStateManager._depthMask(true); GlStateManager._colorMask(true, true, true, true); } public void clear(final boolean boolean1) { RenderSystem.assertThread(RenderSystem::isOnRenderThreadOrInit); this.bindWrite(true); GlStateManager._clearColor(this.clearChannels[0], this.clearChannels[1], this.clearChannels[2], this.clearChannels[3]); int integer3 = 16384; if (this.useDepth) { GlStateManager._clearDepth(1.0); integer3 |= 0x100; } GlStateManager._clear(integer3, boolean1); this.unbindWrite(); } }