Moved dissolve shader to Minecraft's new custom shader rendertype.
This commit is contained in:
@@ -37,7 +37,6 @@ import nl.requios.effortlessbuilding.proxy.ServerProxy;
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
|
||||
// The value here should match an entry in the META-INF/mods.toml file
|
||||
@Mod(EffortlessBuilding.MODID)
|
||||
public class EffortlessBuilding {
|
||||
|
||||
|
||||
@@ -1,16 +1,21 @@
|
||||
package nl.requios.effortlessbuilding;
|
||||
|
||||
import com.mojang.blaze3d.vertex.DefaultVertexFormat;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.renderer.ShaderInstance;
|
||||
import net.minecraft.client.renderer.texture.TextureAtlas;
|
||||
import net.minecraft.client.renderer.texture.TextureAtlasSprite;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraftforge.api.distmarker.Dist;
|
||||
import net.minecraftforge.client.event.RegisterShadersEvent;
|
||||
import net.minecraftforge.client.event.TextureStitchEvent;
|
||||
import net.minecraftforge.eventbus.api.SubscribeEvent;
|
||||
import net.minecraftforge.fml.common.Mod;
|
||||
import nl.requios.effortlessbuilding.buildmode.BuildModes;
|
||||
import nl.requios.effortlessbuilding.buildmode.ModeOptions;
|
||||
import nl.requios.effortlessbuilding.render.BuildRenderTypes;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.HashMap;
|
||||
|
||||
@Mod.EventBusSubscriber(bus = Mod.EventBusSubscriber.Bus.MOD, value = {Dist.CLIENT})
|
||||
@@ -43,4 +48,12 @@ public class ModClientEventHandler {
|
||||
public static TextureAtlasSprite getModeOptionIcon(ModeOptions.ActionEnum action) {
|
||||
return Minecraft.getInstance().getModelManager().getAtlas(TextureAtlas.LOCATION_BLOCKS).getSprite(modeOptionIcons.get(action));
|
||||
}
|
||||
|
||||
@SubscribeEvent
|
||||
public static void registerShaders(RegisterShadersEvent event) throws IOException {
|
||||
event.registerShader(new ShaderInstance(event.getResourceManager(),
|
||||
new ResourceLocation(EffortlessBuilding.MODID, "dissolve"),
|
||||
DefaultVertexFormat.BLOCK),
|
||||
shaderInstance -> BuildRenderTypes.dissolveShaderInstance = shaderInstance);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,7 +5,6 @@ import net.minecraft.world.level.block.state.BlockState;
|
||||
import net.minecraft.world.level.block.SoundType;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.player.LocalPlayer;
|
||||
import net.minecraft.client.gui.screens.MenuScreens;
|
||||
import net.minecraft.client.gui.screens.Screen;
|
||||
import net.minecraft.client.resources.language.I18n;
|
||||
import net.minecraft.client.KeyMapping;
|
||||
@@ -29,28 +28,23 @@ import net.minecraftforge.client.settings.KeyConflictContext;
|
||||
import net.minecraftforge.client.settings.KeyModifier;
|
||||
import net.minecraftforge.event.TickEvent;
|
||||
import net.minecraftforge.eventbus.api.SubscribeEvent;
|
||||
import net.minecraftforge.fml.DeferredWorkQueue;
|
||||
import net.minecraftforge.fml.LogicalSide;
|
||||
import net.minecraftforge.fml.common.Mod;
|
||||
import net.minecraftforge.fml.event.lifecycle.FMLClientSetupEvent;
|
||||
import net.minecraftforge.fml.event.lifecycle.FMLCommonSetupEvent;
|
||||
import net.minecraftforge.fmlclient.registry.ClientRegistry;
|
||||
import net.minecraftforge.fmllegacy.network.NetworkEvent;
|
||||
import net.minecraftforge.registries.DeferredRegister;
|
||||
import net.minecraftforge.registries.ForgeRegistries;
|
||||
import nl.requios.effortlessbuilding.EffortlessBuilding;
|
||||
import nl.requios.effortlessbuilding.buildmode.BuildModes;
|
||||
import nl.requios.effortlessbuilding.buildmode.ModeOptions;
|
||||
import nl.requios.effortlessbuilding.buildmode.ModeSettingsManager;
|
||||
import nl.requios.effortlessbuilding.buildmodifier.ModifierSettingsManager;
|
||||
import nl.requios.effortlessbuilding.compatibility.CompatHelper;
|
||||
import nl.requios.effortlessbuilding.gui.RandomizerBagScreen;
|
||||
import nl.requios.effortlessbuilding.gui.buildmode.PlayerSettingsGui;
|
||||
import nl.requios.effortlessbuilding.gui.buildmode.RadialMenu;
|
||||
import nl.requios.effortlessbuilding.gui.buildmodifier.ModifierSettingsGui;
|
||||
import nl.requios.effortlessbuilding.helper.ReachHelper;
|
||||
import nl.requios.effortlessbuilding.network.*;
|
||||
import nl.requios.effortlessbuilding.render.ShaderHandler;
|
||||
import org.lwjgl.glfw.GLFW;
|
||||
|
||||
import javax.annotation.ParametersAreNonnullByDefault;
|
||||
@@ -66,7 +60,6 @@ public class ClientProxy implements IProxy {
|
||||
public static int ticksInGame = 0;
|
||||
private static int placeCooldown = 0;
|
||||
private static int breakCooldown = 0;
|
||||
private static boolean shadersInitialized = false;
|
||||
|
||||
@SubscribeEvent
|
||||
public static void onClientTick(TickEvent.ClientTickEvent event) {
|
||||
@@ -102,12 +95,6 @@ public class ClientProxy implements IProxy {
|
||||
if (gui == null || !gui.isPauseScreen()) {
|
||||
ticksInGame++;
|
||||
}
|
||||
|
||||
//Init shaders in the first tick. Doing it anywhere before this seems to crash the game.
|
||||
if (!shadersInitialized) {
|
||||
ShaderHandler.init();
|
||||
shadersInitialized = true;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -276,12 +263,6 @@ public class ClientProxy implements IProxy {
|
||||
}
|
||||
}
|
||||
|
||||
//For shader development
|
||||
if (keyBindings.length >= 8 && keyBindings[7].consumeClick()) {
|
||||
ShaderHandler.init();
|
||||
EffortlessBuilding.log(player, "Reloaded shaders");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static void openModifierSettings() {
|
||||
@@ -367,7 +348,6 @@ public class ClientProxy implements IProxy {
|
||||
keyBindings[4] = new KeyMapping("key.effortlessbuilding.undo.desc", KeyConflictContext.IN_GAME, KeyModifier.CONTROL, InputConstants.getKey(GLFW.GLFW_KEY_Z, 0), "key.effortlessbuilding.category");
|
||||
keyBindings[5] = new KeyMapping("key.effortlessbuilding.redo.desc", KeyConflictContext.IN_GAME, KeyModifier.CONTROL, InputConstants.getKey(GLFW.GLFW_KEY_Y, 0), "key.effortlessbuilding.category");
|
||||
keyBindings[6] = new KeyMapping("key.effortlessbuilding.altplacement.desc", KeyConflictContext.IN_GAME, InputConstants.getKey(GLFW.GLFW_KEY_LEFT_CONTROL, 0), "key.effortlessbuilding.category");
|
||||
//keyBindings[7] = new KeyBinding("Reload shaders", KeyConflictContext.UNIVERSAL, InputMappings.getInputByCode(GLFW.GLFW_KEY_TAB, 0), "key.effortlessbuilding.category");
|
||||
|
||||
// register all the key bindings
|
||||
for (KeyMapping keyBinding : keyBindings) {
|
||||
|
||||
@@ -1,26 +1,38 @@
|
||||
package nl.requios.effortlessbuilding.render;
|
||||
|
||||
import com.mojang.blaze3d.shaders.Uniform;
|
||||
import com.mojang.blaze3d.systems.RenderSystem;
|
||||
import com.mojang.blaze3d.vertex.VertexFormat;
|
||||
import net.minecraft.Util;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.renderer.RenderStateShard;
|
||||
import net.minecraft.client.renderer.RenderType;
|
||||
import net.minecraft.client.renderer.ShaderInstance;
|
||||
import net.minecraft.client.renderer.texture.TextureAtlas;
|
||||
import com.mojang.blaze3d.vertex.DefaultVertexFormat;
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.world.phys.Vec3;
|
||||
import nl.requios.effortlessbuilding.BuildConfig;
|
||||
import nl.requios.effortlessbuilding.EffortlessBuilding;
|
||||
import org.lwjgl.opengl.*;
|
||||
|
||||
import java.util.OptionalDouble;
|
||||
import java.util.function.Consumer;
|
||||
import java.util.function.Function;
|
||||
|
||||
public class BuildRenderTypes extends RenderType {
|
||||
public static ResourceLocation shaderMaskTextureLocation = new ResourceLocation(EffortlessBuilding.MODID, "textures/shader_mask.png");
|
||||
|
||||
public static final RenderType LINES;
|
||||
public static final RenderType PLANES;
|
||||
|
||||
private static final int primaryTextureUnit = 0;
|
||||
private static final int secondaryTextureUnit = 2;
|
||||
public static ShaderInstance dissolveShaderInstance;
|
||||
private static final ShaderStateShard RENDERTYPE_DISSOLVE_SHADER = new ShaderStateShard(() -> dissolveShaderInstance);
|
||||
|
||||
//Between 0 and 7, but dont override vanilla textures
|
||||
//Also update dissolve.fsh SamplerX
|
||||
private static final int maskTextureIndex = 7;
|
||||
|
||||
static {
|
||||
final LineStateShard LINE = new LineStateShard(OptionalDouble.of(2.0));
|
||||
@@ -58,39 +70,27 @@ public class BuildRenderTypes extends RenderType {
|
||||
DefaultVertexFormat.POSITION_COLOR, VertexFormat.Mode.TRIANGLE_STRIP, INITIAL_BUFFER_SIZE, false, false, renderState);
|
||||
}
|
||||
|
||||
|
||||
// Dummy constructor needed to make java happy
|
||||
public BuildRenderTypes(String p_173178_, VertexFormat p_173179_, VertexFormat.Mode p_173180_, int p_173181_, boolean p_173182_, boolean p_173183_, Runnable p_173184_, Runnable p_173185_) {
|
||||
super(p_173178_, p_173179_, p_173180_, p_173181_, p_173182_, p_173183_, p_173184_, p_173185_);
|
||||
}
|
||||
|
||||
public static RenderType getBlockPreviewRenderType(float dissolve, BlockPos blockPos, BlockPos firstPos,
|
||||
BlockPos secondPos, boolean red) {
|
||||
// RenderSystem.pushLightingAttributes();
|
||||
// RenderSystem.pushTextureAttributes();
|
||||
// RenderSystem.enableCull();
|
||||
// RenderSystem.enableTexture();
|
||||
// Minecraft.getInstance().textureManager.bindTexture(ShaderHandler.shaderMaskTextureLocation);
|
||||
//
|
||||
// RenderSystem.enableBlend();
|
||||
// RenderSystem.blendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA);
|
||||
// RenderSystem.blendColor(1f, 1f, 1f, 0.8f);
|
||||
//end
|
||||
// ShaderHandler.releaseShader();
|
||||
public static RenderType getBlockPreviewRenderType(float dissolve, BlockPos blockPos, BlockPos firstPos, BlockPos secondPos, boolean red) {
|
||||
|
||||
//highjacking texturing state (which does nothing by default) to do my own things
|
||||
Boolean useShaders = BuildConfig.visuals.useShaders.get();
|
||||
//TODO 1.17 don't use shaders if config says no
|
||||
|
||||
String stateName = "eb_texturing_" + dissolve + "_" + blockPos + "_" + firstPos + "_" + secondPos + "_" + red;
|
||||
RenderStateShard.TexturingStateShard MY_TEXTURING = new RenderStateShard.TexturingStateShard(stateName, () -> {
|
||||
// RenderSystem.pushLightingAttributes();
|
||||
// RenderSystem.pushTextureAttributes();
|
||||
|
||||
ShaderHandler.useShader(ShaderHandler.dissolve, generateShaderCallback(dissolve, Vec3.atLowerCornerOf(blockPos), Vec3.atLowerCornerOf(firstPos), Vec3.atLowerCornerOf(secondPos), blockPos == secondPos, red));
|
||||
TexturingStateShard MY_TEXTURING = new TexturingStateShard(stateName, () -> {
|
||||
setShaderParameters(dissolveShaderInstance, dissolve, Vec3.atLowerCornerOf(blockPos), Vec3.atLowerCornerOf(firstPos), Vec3.atLowerCornerOf(secondPos), blockPos == secondPos, red);
|
||||
RenderSystem.setShaderColor(1f, 1f, 1f, 0.8f);
|
||||
}, ShaderHandler::releaseShader);
|
||||
}, () -> {});
|
||||
|
||||
RenderType.CompositeState renderState = RenderType.CompositeState.builder()
|
||||
.setShaderState(RenderStateShard.RENDERTYPE_TRANSLUCENT_SHADER)
|
||||
.setTextureState(new RenderStateShard.TextureStateShard(ShaderHandler.shaderMaskTextureLocation, false, false))
|
||||
.setShaderState(RENDERTYPE_DISSOLVE_SHADER)
|
||||
.setTexturingState(MY_TEXTURING)
|
||||
.setTextureState(new RenderStateShard.TextureStateShard(shaderMaskTextureLocation, false, false))
|
||||
.setTransparencyState(TRANSLUCENT_TRANSPARENCY)
|
||||
//TODO 1.17
|
||||
// .setDiffuseLightingState(DIFFUSE_LIGHTING_DISABLED)
|
||||
@@ -105,49 +105,26 @@ public class BuildRenderTypes extends RenderType {
|
||||
DefaultVertexFormat.BLOCK, VertexFormat.Mode.QUADS, 256, true, true, renderState);
|
||||
}
|
||||
|
||||
private static Consumer<Integer> generateShaderCallback(final float dissolve, final Vec3 blockpos,
|
||||
private static void setShaderParameters(ShaderInstance shader, final float dissolve, final Vec3 blockpos,
|
||||
final Vec3 firstpos, final Vec3 secondpos,
|
||||
final boolean highlight, final boolean red) {
|
||||
Minecraft mc = Minecraft.getInstance();
|
||||
return (Integer shader) -> {
|
||||
int percentileUniform = ARBShaderObjects.glGetUniformLocationARB(shader, "dissolve");
|
||||
int highlightUniform = ARBShaderObjects.glGetUniformLocationARB(shader, "highlight");
|
||||
int redUniform = ARBShaderObjects.glGetUniformLocationARB(shader, "red");
|
||||
int blockposUniform = ARBShaderObjects.glGetUniformLocationARB(shader, "blockpos");
|
||||
int firstposUniform = ARBShaderObjects.glGetUniformLocationARB(shader, "firstpos");
|
||||
int secondposUniform = ARBShaderObjects.glGetUniformLocationARB(shader, "secondpos");
|
||||
int imageUniform = ARBShaderObjects.glGetUniformLocationARB(shader, "image");
|
||||
int maskUniform = ARBShaderObjects.glGetUniformLocationARB(shader, "mask");
|
||||
Uniform percentileUniform = shader.getUniform("dissolve");
|
||||
Uniform highlightUniform = shader.getUniform("highlight");
|
||||
Uniform redUniform = shader.getUniform("red");
|
||||
Uniform blockposUniform = shader.getUniform("blockpos");
|
||||
Uniform firstposUniform = shader.getUniform("firstpos");
|
||||
Uniform secondposUniform = shader.getUniform("secondpos");
|
||||
|
||||
RenderSystem.enableTexture();
|
||||
GL11.glGetInteger(GL11.GL_TEXTURE_BINDING_2D);
|
||||
RenderSystem.setShaderTexture(0, TextureAtlas.LOCATION_BLOCKS);
|
||||
RenderSystem.setShaderTexture(maskTextureIndex, shaderMaskTextureLocation);
|
||||
|
||||
//mask
|
||||
ARBShaderObjects.glUniform1iARB(maskUniform, secondaryTextureUnit);
|
||||
glActiveTexture(ARBMultitexture.GL_TEXTURE0_ARB + secondaryTextureUnit);
|
||||
RenderSystem.setShaderTexture(0, ShaderHandler.shaderMaskTextureLocation);
|
||||
//mc.getTextureManager().bindForSetup(ShaderHandler.shaderMaskTextureLocation);//getTexture(ShaderHandler.shaderMaskTextureLocation).bindTexture();
|
||||
//GL11.glBindTexture(GL11.GL_TEXTURE_2D, mc.getTextureManager().getTexture(ShaderHandler.shaderMaskTextureLocation).getGlTextureId());
|
||||
percentileUniform.set(dissolve);
|
||||
highlightUniform.set(highlight ? 1 : 0);
|
||||
redUniform.set(red ? 1 : 0);
|
||||
|
||||
//image
|
||||
ARBShaderObjects.glUniform1iARB(imageUniform, primaryTextureUnit);
|
||||
glActiveTexture(ARBMultitexture.GL_TEXTURE0_ARB + primaryTextureUnit);
|
||||
RenderSystem.setShaderTexture(0, TextureAtlas.LOCATION_BLOCKS);
|
||||
//mc.getTextureManager().bindForSetup(TextureAtlas.LOCATION_BLOCKS);//.getTexture(AtlasTexture.LOCATION_BLOCKS_TEXTURE).bindTexture();
|
||||
//GL11.glBindTexture(GL11.GL_TEXTURE_2D, mc.getTextureManager().getTexture(AtlasTexture.LOCATION_BLOCKS_TEXTURE).getGlTextureId());
|
||||
|
||||
//blockpos
|
||||
ARBShaderObjects.glUniform3fARB(blockposUniform, (float) blockpos.x, (float) blockpos.y, (float) blockpos.z);
|
||||
ARBShaderObjects.glUniform3fARB(firstposUniform, (float) firstpos.x, (float) firstpos.y, (float) firstpos.z);
|
||||
ARBShaderObjects.glUniform3fARB(secondposUniform, (float) secondpos.x, (float) secondpos.y, (float) secondpos.z);
|
||||
|
||||
//dissolve
|
||||
ARBShaderObjects.glUniform1fARB(percentileUniform, dissolve);
|
||||
//highlight
|
||||
ARBShaderObjects.glUniform1iARB(highlightUniform, highlight ? 1 : 0);
|
||||
//red
|
||||
ARBShaderObjects.glUniform1iARB(redUniform, red ? 1 : 0);
|
||||
};
|
||||
blockposUniform.set((float) blockpos.x, (float) blockpos.y, (float) blockpos.z);
|
||||
firstposUniform.set((float) firstpos.x, (float) firstpos.y, (float) firstpos.z);
|
||||
secondposUniform.set((float) secondpos.x, (float) secondpos.y, (float) secondpos.z);
|
||||
}
|
||||
|
||||
public static void glActiveTexture(int texture) {
|
||||
|
||||
@@ -1,201 +0,0 @@
|
||||
/**
|
||||
* This class was created by <Vazkii>. It's distributed as
|
||||
* part of the Botania Mod. Get the Source Code in github:
|
||||
* https://github.com/Vazkii/Botania
|
||||
* <p>
|
||||
* Modified by Requios
|
||||
* <p>
|
||||
* Botania is Open Source and distributed under the
|
||||
* Botania License: http://botaniamod.net/license.php
|
||||
* <p>
|
||||
* File Created @ [Apr 9, 2014, 11:20:26 PM (GMT)]
|
||||
*/
|
||||
package nl.requios.effortlessbuilding.render;
|
||||
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import nl.requios.effortlessbuilding.BuildConfig;
|
||||
import nl.requios.effortlessbuilding.EffortlessBuilding;
|
||||
import nl.requios.effortlessbuilding.proxy.ClientProxy;
|
||||
import org.apache.logging.log4j.Level;
|
||||
import org.lwjgl.opengl.*;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.InputStream;
|
||||
import java.io.InputStreamReader;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
public final class ShaderHandler {
|
||||
|
||||
private static final int VERT_ST = ARBVertexShader.GL_VERTEX_SHADER_ARB;
|
||||
private static final int FRAG_ST = ARBFragmentShader.GL_FRAGMENT_SHADER_ARB;
|
||||
|
||||
private static final int VERT = 1;
|
||||
private static final int FRAG = 2;
|
||||
|
||||
private static final String VERT_EXTENSION = ".vert";
|
||||
private static final String FRAG_EXTENSION = ".frag";
|
||||
|
||||
public static int rawColor;
|
||||
public static int dissolve;
|
||||
|
||||
public static ResourceLocation shaderMaskTextureLocation = new ResourceLocation(EffortlessBuilding.MODID, "textures/shader_mask.png");
|
||||
|
||||
public static void init() {
|
||||
if (!doUseShaders())
|
||||
return;
|
||||
|
||||
// rawColor = createProgram("/assets/effortlessbuilding/shaders/raw_color", FRAG);
|
||||
dissolve = createProgram("/assets/effortlessbuilding/shaders/dissolve", VERT + FRAG);
|
||||
}
|
||||
|
||||
public static void useShader(int shader, Consumer<Integer> callback) {
|
||||
if (!doUseShaders())
|
||||
return;
|
||||
|
||||
ARBShaderObjects.glUseProgramObjectARB(shader);
|
||||
|
||||
if (shader != 0) {
|
||||
int time = ARBShaderObjects.glGetUniformLocationARB(shader, "time");
|
||||
ARBShaderObjects.glUniform1iARB(time, ClientProxy.ticksInGame);
|
||||
|
||||
if (callback != null)
|
||||
callback.accept(shader);
|
||||
}
|
||||
}
|
||||
|
||||
public static void useShader(int shader) {
|
||||
useShader(shader, null);
|
||||
}
|
||||
|
||||
public static void releaseShader() {
|
||||
useShader(0);
|
||||
}
|
||||
|
||||
public static boolean doUseShaders() {
|
||||
//Extracted from OpenGLHelper in 1.13 and earlier
|
||||
//Can probably be simplified
|
||||
GLCapabilities glcapabilities = GL.getCapabilities();
|
||||
boolean openGL14 = glcapabilities.OpenGL14 || glcapabilities.GL_EXT_blend_func_separate;
|
||||
boolean openGL21 = glcapabilities.OpenGL21;
|
||||
boolean framebufferSupported = openGL14 && (glcapabilities.GL_ARB_framebuffer_object || glcapabilities.GL_EXT_framebuffer_object || glcapabilities.OpenGL30);
|
||||
boolean shadersAvailable = openGL21 || glcapabilities.GL_ARB_vertex_shader && glcapabilities.GL_ARB_fragment_shader && glcapabilities.GL_ARB_shader_objects;
|
||||
boolean shadersSupported = framebufferSupported && shadersAvailable;
|
||||
return BuildConfig.visuals.useShaders.get() && shadersSupported;
|
||||
}
|
||||
|
||||
private static int createProgram(String s, int sides) {
|
||||
boolean vert = (sides & VERT) != 0;
|
||||
boolean frag = (sides & FRAG) != 0;
|
||||
|
||||
return createProgram(vert ? s + VERT_EXTENSION : null, frag ? s + FRAG_EXTENSION : null);
|
||||
}
|
||||
|
||||
// Most of the code taken from the LWJGL wiki
|
||||
// http://lwjgl.org/wiki/index.php?title=GLSL_Shaders_with_LWJGL
|
||||
|
||||
private static int createProgram(String vert, String frag) {
|
||||
int vertId = 0, fragId = 0, program;
|
||||
if (vert != null)
|
||||
vertId = createShader(vert, VERT_ST);
|
||||
if (frag != null)
|
||||
fragId = createShader(frag, FRAG_ST);
|
||||
|
||||
program = ARBShaderObjects.glCreateProgramObjectARB();
|
||||
if (program == 0)
|
||||
return 0;
|
||||
|
||||
if (vert != null)
|
||||
ARBShaderObjects.glAttachObjectARB(program, vertId);
|
||||
if (frag != null)
|
||||
ARBShaderObjects.glAttachObjectARB(program, fragId);
|
||||
|
||||
ARBShaderObjects.glLinkProgramARB(program);
|
||||
if (ARBShaderObjects.glGetObjectParameteriARB(program, ARBShaderObjects.GL_OBJECT_LINK_STATUS_ARB) == GL11.GL_FALSE) {
|
||||
EffortlessBuilding.logger.log(Level.ERROR, getLogInfo(program));
|
||||
return 0;
|
||||
}
|
||||
|
||||
ARBShaderObjects.glValidateProgramARB(program);
|
||||
if (ARBShaderObjects.glGetObjectParameteriARB(program, ARBShaderObjects.GL_OBJECT_VALIDATE_STATUS_ARB) == GL11.GL_FALSE) {
|
||||
EffortlessBuilding.logger.log(Level.ERROR, getLogInfo(program));
|
||||
return 0;
|
||||
}
|
||||
|
||||
return program;
|
||||
}
|
||||
|
||||
private static int createShader(String filename, int shaderType) {
|
||||
int shader = 0;
|
||||
try {
|
||||
shader = ARBShaderObjects.glCreateShaderObjectARB(shaderType);
|
||||
|
||||
if (shader == 0)
|
||||
return 0;
|
||||
|
||||
ARBShaderObjects.glShaderSourceARB(shader, readFileAsString(filename));
|
||||
ARBShaderObjects.glCompileShaderARB(shader);
|
||||
|
||||
if (ARBShaderObjects.glGetObjectParameteriARB(shader, ARBShaderObjects.GL_OBJECT_COMPILE_STATUS_ARB) == GL11.GL_FALSE)
|
||||
throw new RuntimeException("Error creating shader: " + getLogInfo(shader));
|
||||
|
||||
return shader;
|
||||
} catch (Exception e) {
|
||||
ARBShaderObjects.glDeleteObjectARB(shader);
|
||||
e.printStackTrace();
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
private static String getLogInfo(int obj) {
|
||||
return ARBShaderObjects.glGetInfoLogARB(obj, ARBShaderObjects.glGetObjectParameteriARB(obj, ARBShaderObjects.GL_OBJECT_INFO_LOG_LENGTH_ARB));
|
||||
}
|
||||
|
||||
private static String readFileAsString(String filename) throws Exception {
|
||||
StringBuilder source = new StringBuilder();
|
||||
InputStream in = ShaderHandler.class.getResourceAsStream(filename);
|
||||
Exception exception = null;
|
||||
BufferedReader reader;
|
||||
|
||||
if (in == null)
|
||||
return "";
|
||||
|
||||
try {
|
||||
reader = new BufferedReader(new InputStreamReader(in, StandardCharsets.UTF_8));
|
||||
|
||||
Exception innerExc = null;
|
||||
try {
|
||||
String line;
|
||||
while ((line = reader.readLine()) != null)
|
||||
source.append(line).append('\n');
|
||||
} catch (Exception exc) {
|
||||
exception = exc;
|
||||
} finally {
|
||||
try {
|
||||
reader.close();
|
||||
} catch (Exception exc) {
|
||||
innerExc = exc;
|
||||
}
|
||||
}
|
||||
|
||||
if (innerExc != null)
|
||||
throw innerExc;
|
||||
} catch (Exception exc) {
|
||||
exception = exc;
|
||||
} finally {
|
||||
try {
|
||||
in.close();
|
||||
} catch (Exception exc) {
|
||||
if (exception == null)
|
||||
exception = exc;
|
||||
else exc.printStackTrace();
|
||||
}
|
||||
|
||||
if (exception != null)
|
||||
throw exception;
|
||||
}
|
||||
|
||||
return source.toString();
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user