minecraft-src/com/mojang/blaze3d/opengl/Uniform.java
2025-07-04 03:45:38 +03:00

189 lines
4.6 KiB
Java

package com.mojang.blaze3d.opengl;
import com.mojang.blaze3d.shaders.UniformType;
import com.mojang.logging.LogUtils;
import java.nio.FloatBuffer;
import java.nio.IntBuffer;
import net.fabricmc.api.EnvType;
import net.fabricmc.api.Environment;
import org.joml.Matrix4f;
import org.joml.Vector3f;
import org.lwjgl.system.MemoryUtil;
import org.slf4j.Logger;
@Environment(EnvType.CLIENT)
public class Uniform extends AbstractUniform implements AutoCloseable {
private static final Logger LOGGER = LogUtils.getLogger();
private int location;
private final UniformType type;
private final IntBuffer intValues;
private final FloatBuffer floatValues;
private final String name;
private boolean dirty;
public Uniform(String name, UniformType type) {
this.name = name;
this.type = type;
if (type.isIntStorage()) {
this.intValues = MemoryUtil.memAllocInt(type.count());
this.floatValues = null;
} else {
this.intValues = null;
this.floatValues = MemoryUtil.memAllocFloat(type.count());
}
this.location = -1;
}
public static int glGetUniformLocation(int program, CharSequence name) {
return GlStateManager._glGetUniformLocation(program, name);
}
public static void uploadInteger(int location, int value) {
GlStateManager._glUniform1i(location, value);
}
public void close() {
if (this.intValues != null) {
MemoryUtil.memFree(this.intValues);
}
if (this.floatValues != null) {
MemoryUtil.memFree(this.floatValues);
}
}
public void setLocation(int location) {
this.location = location;
}
public String getName() {
return this.name;
}
public UniformType getType() {
return this.type;
}
@Override
public final void set(float value) {
this.floatValues.position(0);
this.floatValues.put(0, value);
this.dirty = true;
}
@Override
public final void set(float value1, float value2) {
this.floatValues.position(0);
this.floatValues.put(0, value1);
this.floatValues.put(1, value2);
this.dirty = true;
}
@Override
public final void set(float value1, float value2, float value3) {
this.floatValues.position(0);
this.floatValues.put(0, value1);
this.floatValues.put(1, value2);
this.floatValues.put(2, value3);
this.dirty = true;
}
@Override
public final void set(Vector3f values) {
this.floatValues.position(0);
values.get(this.floatValues);
this.dirty = true;
}
@Override
public final void set(float value1, float value2, float value3, float value4) {
this.floatValues.position(0);
this.floatValues.put(value1);
this.floatValues.put(value2);
this.floatValues.put(value3);
this.floatValues.put(value4);
this.floatValues.flip();
this.dirty = true;
}
@Override
public final void set(int value) {
this.intValues.position(0);
this.intValues.put(0, value);
this.dirty = true;
}
@Override
public final void set(int value1, int value2, int value3) {
this.intValues.position(0);
this.intValues.put(0, value1);
this.intValues.put(1, value2);
this.intValues.put(2, value3);
this.dirty = true;
}
@Override
public final void set(float[] values) {
if (values.length < this.type.count()) {
LOGGER.warn("Uniform.set called with a too-small value array (expected {}, got {}). Ignoring.", this.type.count(), values.length);
} else {
this.floatValues.position(0);
this.floatValues.put(values);
this.floatValues.position(0);
this.dirty = true;
}
}
@Override
public final void set(int[] values) {
if (values.length < this.type.count()) {
LOGGER.warn("Uniform.set called with a too-small value array (expected {}, got {}). Ignoring.", this.type.count(), values.length);
} else {
this.intValues.position(0);
this.intValues.put(values);
this.intValues.position(0);
this.dirty = true;
}
}
@Override
public final void set(Matrix4f values) {
this.floatValues.position(0);
values.get(this.floatValues);
this.dirty = true;
}
public void upload() {
if (this.dirty) {
if (this.type.isIntStorage()) {
switch (this.type) {
case INT:
GlStateManager._glUniform1(this.location, this.intValues);
break;
case IVEC3:
GlStateManager._glUniform3(this.location, this.intValues);
}
} else {
switch (this.type) {
case FLOAT:
GlStateManager._glUniform1(this.location, this.floatValues);
break;
case VEC2:
GlStateManager._glUniform2(this.location, this.floatValues);
break;
case VEC3:
GlStateManager._glUniform3(this.location, this.floatValues);
break;
case VEC4:
GlStateManager._glUniform4(this.location, this.floatValues);
break;
case MATRIX4X4:
GlStateManager._glUniformMatrix4(this.location, this.floatValues);
}
}
this.dirty = false;
}
}
}