Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions fabric/src/main/resources/canvas.accesswidener
Original file line number Diff line number Diff line change
Expand Up @@ -154,3 +154,5 @@ accessible field net/minecraft/client/renderer/entity/EntityRenderDispatcher SHA
accessible field net/minecraft/client/renderer/ShaderInstance name Ljava/lang/String;

extendable method com/mojang/blaze3d/pipeline/MainTarget createFrameBuffer (II)V

accessible class net/minecraft/client/resources/model/ModelManager$ReloadState
2 changes: 2 additions & 0 deletions fabric/src/main/resources/mixins.canvas.client.json
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@
"MixinLightTexture",
"MixinMinecraft",
"MixinModelBlockRenderer",
"MixinModelManager",
"MixinNativeImage",
"MixinParticle",
"MixinParticleEngine",
Expand All @@ -43,6 +44,7 @@
"MixinSimpleTexture",
"MixinSpriteContents",
"MixinSpriteInterpolation",
"MixinStitchResult",
"MixinTextureAtlas",
"MixinTextureSheetParticle",
"MixinTropicalFishModelA",
Expand Down
60 changes: 60 additions & 0 deletions src/main/java/grondag/canvas/mixin/MixinModelManager.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
/*
* This file is part of Canvas Renderer and is licensed to the project under
* terms that are compatible with the GNU Lesser General Public License.
* See the NOTICE file distributed with this work for additional information
* regarding copyright ownership and licensing.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/

package grondag.canvas.mixin;

import java.util.concurrent.CompletableFuture;
import java.util.concurrent.Executor;

import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;

import net.minecraft.client.Minecraft;
import net.minecraft.client.resources.model.ModelManager;
import net.minecraft.server.packs.resources.PreparableReloadListener;
import net.minecraft.server.packs.resources.ResourceManager;
import net.minecraft.util.profiling.ProfilerFiller;

import grondag.canvas.texture.pbr.PbrLoader;

@Mixin(ModelManager.class)
public abstract class MixinModelManager {
@Shadow public abstract CompletableFuture<Void> reload(PreparableReloadListener.PreparationBarrier preparationBarrier, ResourceManager resourceManager, ProfilerFiller profilerFiller, ProfilerFiller profilerFiller2, Executor executor, Executor executor2);

private static ResourceManager canvas_resourceManager;

@Inject(method = "reload", at = @At("HEAD"))
private void onReload(PreparableReloadListener.PreparationBarrier preparationBarrier, ResourceManager resourceManager, ProfilerFiller profilerFiller, ProfilerFiller profilerFiller2, Executor executor, Executor executor2, CallbackInfoReturnable<CompletableFuture<Void>> cir) {
canvas_resourceManager = resourceManager;
}
@Inject(method = "apply", at = @At("HEAD"))
private void onApply(ModelManager.ReloadState reloadState, ProfilerFiller profilerFiller, CallbackInfo ci) {
if (canvas_resourceManager == null) {
PbrLoader.errorOrdering();
} else {
PbrLoader.reload(canvas_resourceManager, reloadState.atlasPreparations().values());
canvas_resourceManager = null;
}
}
}
47 changes: 47 additions & 0 deletions src/main/java/grondag/canvas/mixin/MixinStitchResult.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
/*
* This file is part of Canvas Renderer and is licensed to the project under
* terms that are compatible with the GNU Lesser General Public License.
* See the NOTICE file distributed with this work for additional information
* regarding copyright ownership and licensing.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/

package grondag.canvas.mixin;

import org.spongepowered.asm.mixin.Final;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;

import net.minecraft.client.renderer.texture.SpriteLoader;
import net.minecraft.client.renderer.texture.TextureAtlas;
import net.minecraft.client.resources.model.AtlasSet;

import grondag.canvas.mixinterface.StitchResultExt;

@Mixin(AtlasSet.StitchResult.class)
public class MixinStitchResult implements StitchResultExt {
@Final @Shadow private TextureAtlas atlas;
@Final @Shadow private SpriteLoader.Preparations preparations;

@Override
public TextureAtlas canvas_atlas() {
return atlas;
}

@Override
public SpriteLoader.Preparations canvas_preparations() {
return preparations;
}
}
29 changes: 29 additions & 0 deletions src/main/java/grondag/canvas/mixinterface/StitchResultExt.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
/*
* This file is part of Canvas Renderer and is licensed to the project under
* terms that are compatible with the GNU Lesser General Public License.
* See the NOTICE file distributed with this work for additional information
* regarding copyright ownership and licensing.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/

package grondag.canvas.mixinterface;

import net.minecraft.client.renderer.texture.SpriteLoader;
import net.minecraft.client.renderer.texture.TextureAtlas;

public interface StitchResultExt {
TextureAtlas canvas_atlas();
SpriteLoader.Preparations canvas_preparations();
}
49 changes: 49 additions & 0 deletions src/main/java/grondag/canvas/texture/pbr/ColorEncode.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
/*
* This file is part of Canvas Renderer and is licensed to the project under
* terms that are compatible with the GNU Lesser General Public License.
* See the NOTICE file distributed with this work for additional information
* regarding copyright ownership and licensing.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/

package grondag.canvas.texture.pbr;

// TODO: this class has to already exist somewhere..
public class ColorEncode {
static int encode(int r, int g, int b, int a) {
return ((r & 0xFF) << 0) | ((g & 0xFF) << 8) | ((b & 0xFF) << 16) | ((a & 0xFF) << 24);
}

static int r(int color) {
return (color >> 0) & 0xFF;
}

static int g(int color) {
return (color >> 8) & 0xFF;
}

static int b(int color) {
return (color >> 16) & 0xFF;
}

static int a(int color) {
return (color >> 24) & 0xFF;
}

static final int RED_BYTE_OFFSET = 0;
static final int GREEN_BYTE_OFFSET = 1;
static final int BLUE_BYTE_OFFSET = 2;
static final int ALPHA_BYTE_OFFSET = 3;
}
158 changes: 158 additions & 0 deletions src/main/java/grondag/canvas/texture/pbr/InputTextureManager.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,158 @@
/*
* This file is part of Canvas Renderer and is licensed to the project under
* terms that are compatible with the GNU Lesser General Public License.
* See the NOTICE file distributed with this work for additional information
* regarding copyright ownership and licensing.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/

package grondag.canvas.texture.pbr;

import java.io.InputStream;
import java.nio.ByteBuffer;

import it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap;

import com.mojang.blaze3d.platform.NativeImage;
import com.mojang.blaze3d.platform.TextureUtil;

import net.minecraft.client.renderer.texture.atlas.SpriteSource;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.server.packs.resources.ResourceManager;

import grondag.canvas.CanvasMod;
import grondag.canvas.render.CanvasTextureState;
import grondag.canvas.varia.GFX;

public class InputTextureManager {
final Object2ObjectOpenHashMap<ResourceLocation, InputTexture> textures = new Object2ObjectOpenHashMap<>();
private final InputTexture EMPTY_INPUT = new InputTexture();

void addInputResource(ResourceManager resourceManager, ResourceLocation location) {
if (!textures.containsKey(location)) {
final var resource = resourceManager.getResource(location);
InputTexture added = EMPTY_INPUT;

if (resource.isPresent()) {
try (InputStream inputStream = resource.get().open()) {
added = new ImageInput(location, NativeImage.read(inputStream), true);
} catch (Throwable e) {
CanvasMod.LOG.error("Unable to load PBR texture " + location + " due to exception:\n" + e);
}
}

textures.put(location, added);
}
}

void addInputImage(ResourceLocation id, NativeImage image) {
var location = SpriteSource.TEXTURE_ID_CONVERTER.idToFile(id);

if (!textures.containsKey(location)) {
textures.put(location, new ImageInput(location, image, false));
}
}

InputTexture getInput(ResourceLocation location) {
return textures.get(location);
}

InputTexture getSpriteDefault(ResourceLocation id) {
var location = SpriteSource.TEXTURE_ID_CONVERTER.idToFile(id);

return textures.get(location);
}

void uploadInputs() {
GFX.pixelStore(GFX.GL_UNPACK_SKIP_PIXELS, 0);
GFX.pixelStore(GFX.GL_UNPACK_SKIP_ROWS, 0);
GFX.pixelStore(GFX.GL_UNPACK_ROW_LENGTH, 0);
GFX.pixelStore(GFX.GL_UNPACK_ALIGNMENT, 1);

for (var i : textures.values()) {
i.upload();
}
}

void clear() {
for (var entry : textures.values()) {
entry.close();
}

textures.clear();
}

static class InputTexture {
boolean present() {
return false;
}

int getTexId() {
return -1;
}

protected void upload() {
}

protected void close() {
}
}

static class ImageInput extends InputTexture {
final ResourceLocation location;
final NativeImage image;
final boolean autoClose;
private int texId = -1;

public ImageInput(ResourceLocation location, NativeImage image, boolean autoClose) {
this.location = location;
this.image = image;
this.autoClose = autoClose;
}

@Override
public boolean present() {
return texId != -1;
}

@Override
public int getTexId() {
return texId;
}

@Override
protected void upload() {
if (texId == -1) {
texId = TextureUtil.generateTextureId();
}

CanvasTextureState.bindTexture(texId);
GFX.texImage2D(GFX.GL_TEXTURE_2D, 0, GFX.GL_RGBA8, image.getWidth(), image.getHeight(), 0, image.format().glFormat(), GFX.GL_UNSIGNED_BYTE, (ByteBuffer) null);
image.upload(0, 0, 0, autoClose);
}

@Override
protected void close() {
if (texId != -1) {
TextureUtil.releaseTextureId(texId);
texId = -1;
}

if (autoClose) {
image.close();
}
}
}
}
Loading