Like it says in the title I am attempting to update my old mod which can render cubes of any position, rotation, and scale in world space to the new rendering engine in 1.15 with little success. I got it to start rendering the cubes by using the MatrixStack but it only renders them what appears to be screen space. I've also converted all of my GlStateManager calls to RenderSystem calls. Below is some of the code from the project which deals with cube rendering.
Render Entry
@SubscribeEvent
public static void onWorldRender(RenderWorldLastEvent event) {
// Grab Minecraft instance and check if player exists (in world).
Minecraft mc = Minecraft.getInstance();
ClientPlayerEntity player = mc.player;
if(player == null) return;
CubeBatch batch = new CubeBatch();
batch.begin(event.getMatrixStack(), mc.gameRenderer.getActiveRenderInfo().getProjectedView());
for(ICubeScene scene : scenes) {
if(!scene.isVisible()) continue;
scene.render(batch, player, event.getPartialTicks());
}
batch.end();
}
Cube Batch
public class CubeBatch {
private List<Cube> buffer;
private Vec3d origin;
private MatrixStack matrixStack;
/**
* @return the current origin.
*/
public Vec3d getOrigin() {
return origin;
}
/**
* @return the current matrix stack.
*/
public MatrixStack getMatrixStack() {
return matrixStack;
}
/**
* Starts a CubeBatch instruction instance.
* @param matrixStack -
* @param origin - The origin for the CubeRenderer.
*/
public void begin(MatrixStack matrixStack, Vec3d origin) {
this.matrixStack = matrixStack;
this.origin = origin;
this.buffer = new ArrayList<Cube>();
}
/**
* Flushes the Cube Batch to the CubeRenderer.
*/
public void flush() {
CuRender.begin(matrixStack, origin);
for(Cube cube : buffer) {
CuRender.cube(cube);
}
CuRender.end();
buffer.clear();
}
/**
* Stops and flushes the CubeBatch.
*/
public void end() {
flush();
buffer = null;
origin = null;
}
/**
* Renders this cube to the world when flushed.
* @param cube
*/
public void draw(Cube cube) {
if(!cube.isVisible()) return;
buffer.add(cube.clone());
}
/**
* Renders a blend of the two cubes to the world when flushed.
* @param cube1
* @param cube2
* @param blend - A number between 0 and 1 (0 - Only Cube1, 1 - Only Cube2)
*/
public void blend(Cube cube1, Cube cube2, float blend) {
if(blend < 0) blend = 0;
else if(blend > 1) blend = 1;
Cube c1 = cube1.clone();
Cube c2 = cube2.clone();
c1.scaleOpacity(1 - blend);
c2.scaleOpacity(blend);
buffer.add(c1);
buffer.add(c2);
}
}
Rendering Process
public final class CuRender {
private static boolean rendering = false;
private static MatrixStack matrixStack;
/**
* Sets up the OpenGL environment for rendering in world space.
* @param origin - Origin of the camera (typically player's eye position).
*/
public static void begin(MatrixStack matrixStack, Vec3d origin) {
if(rendering) throw new IllegalStateException("Cannot begin while rendering.");
rendering = true;
CuRender.matrixStack = matrixStack;
matrixStack.push();
matrixStack.translate(0.5 - origin.x, 0.5 - origin.y, 0.5 - origin.z);
RenderSystem.disableDepthTest();
RenderSystem.disableTexture();
RenderSystem.disableLighting();
RenderSystem.enableBlend();
GL11.glBlendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA);
}
/**
* Returns the OpenGL environment back to normal.
*/
public static void end() {
if(!rendering) return;
RenderSystem.disableBlend();
RenderSystem.enableLighting();
RenderSystem.enableTexture();
RenderSystem.enableDepthTest();
matrixStack.pop();
rendering = false;
}
/**
* Renders the cube in world space.
* @param cube
*/
public static void cube(Cube cube) {
matrixStack.push();
// Position
matrixStack.translate(-cube.getX(), -cube.getY(), -cube.getZ());
// Rotate
// GlStateManager.translated(cube.getOriginX() / 2, cube.getOriginY() / 2, cube.getOriginZ() / 2);
// GlStateManager.rotatef(-cube.getYaw(), 0, 1, 0);
// GlStateManager.rotatef(cube.getPitch(), 1, 0, 0);
// GlStateManager.scaled(cube.getScaleX(), cube.getScaleY(), cube.getScaleZ()); // Scale
// GlStateManager.translated(-cube.getOriginX() / 2, -cube.getOriginY() / 2, -cube.getOriginZ() / 2);
matrixStack.scale(0.5f, 0.5f, 0.5f); // Normalize
if(cube.isWired()) {
// Wire Cube
renderEdges(cube.getWireColor(), null);
}
else if(cube.isSolid()) {
// Solid Cube
for(int i = 0; i < UnitCube.FACE_COUNT; i++) {
Face face = UnitCube.FACES[i];
quad(cube.getFaceColor(i), face.v1, face.v2, face.v3, face.v4);
}
}
else {
// Mixed Cube
boolean[] removedEdge = new boolean[UnitCube.EDGE_COUNT];
for(int i = 0; i < UnitCube.FACE_COUNT; i++) {
if(!cube.isFaceSolid(i)) continue;
Face face = UnitCube.FACES[i];
quad(cube.getFaceColor(i), face.v1, face.v2, face.v3, face.v4);
quad(cube.getFaceColor(i), face.v1, face.v4, face.v3, face.v2);
for(Edge edge : face.edges) {
int j = UnitCube.getEdgeIndex(edge);
removedEdge[j] = true;
}
}
renderEdges(cube.getWireColor(), removedEdge);
}
matrixStack.pop();
}
private static void renderEdges(Color4f color, boolean[] removedEdges) {
glColor4f(color);
GL11.glBegin(GL11.GL_LINES);
for(int i = 0; i < UnitCube.EDGE_COUNT; i++) {
if(removedEdges != null && removedEdges[i]) continue;
Edge edge = UnitCube.EDGES[i];
glVertex3d(edge.v1);
glVertex3d(edge.v2);
}
GL11.glEnd();
}
/**
* Renders a quad with the specified vertices. OpenGL must be in GL_QUADS mode to work.
* @param v1
* @param v2
* @param v3
* @param v4
*/
public static void quad(Color4f color, Vec3d v1, Vec3d v2, Vec3d v3, Vec3d v4) {
glColor4f(color);
GL11.glBegin(GL11.GL_QUADS);
glVertex3d(v1);
glVertex3d(v2);
glVertex3d(v3);
glVertex3d(v4);
GL11.glEnd();
}
private static void glVertex3d(Vec3d v) {
GL11.glVertex3d(v.x, v.y, v.z);
}
private static void glColor4f(Color4f c) {
GL11.glColor4f(c.r, c.g, c.b, c.a);
}
}
Sample Cube Scene
public class DebugScene extends CubeScene {
public static final Cube CUBE_TEMPLATE = new Cube().wire().setColor(1f, 0f, 0f, 0.5f);
@Override
public void render(CubeBatch batch, ClientPlayerEntity player, float partialTicks) {
World world = player.getEntityWorld();
int px = (int) player.lastTickPosX;
int pz = (int) player.lastTickPosZ;
// Loop through all chunks in the chunk render distance.
for(int x = px - 50; x <= px + 50; x++) {
for(int z = pz - 50; z <= pz + 50; z++) {
int maxY = world.getHeight(Type.WORLD_SURFACE, x, z);
for(int y = 0; y <= maxY; y++) {
BlockState state = world.getBlockState(new BlockPos(x, y, z));
if(state.getBlock() instanceof OreBlock) {
batch.draw(CUBE_TEMPLATE.clone().setPosition(x, y, z));
}
}
}
}
}
}
Any direct help or even resources to how the new rendering system works is greatly appreciated. If anymore information is needed please don't hesitate to ask.