mirror of
https://github.com/GTNewHorizons/bdlib.git
synced 2026-11-12 00:07:31 +00:00
Added connected textures renderer
This commit is contained in:
1 parent
490433a7f4
commit
9fdc6bd880
4 files changed
+279
No files matched your search
@@ -0,0 +1,23 @@
|
||||
/*
|
||||
* Copyright (c) bdew, 2013 - 2014
|
||||
* https://github.com/bdew/bdlib
|
||||
*
|
||||
* This mod is distributed under the terms of the Minecraft Mod Public
|
||||
* License 1.0, or MMPL. Please check the contents of the license located in
|
||||
* https://raw.github.com/bdew/bdlib/master/MMPL-1.0.txt
|
||||
*/
|
||||
|
||||
package net.bdew.lib.render.connected
|
||||
|
||||
import net.bdew.lib.gui.Color
|
||||
import net.minecraft.util.IIcon
|
||||
import net.minecraft.world.IBlockAccess
|
||||
import net.minecraftforge.common.util.ForgeDirection
|
||||
|
||||
case class FaceOverlay(icon: IIcon, color: Color) {
|
||||
def this(icon: IIcon, color: (Float, Float, Float)) = this(icon, new Color(color._1, color._2, color._3))
|
||||
}
|
||||
|
||||
trait BlockAdditionalRender {
|
||||
def getFaceOverlays(world: IBlockAccess, x: Int, y: Int, z: Int, face: ForgeDirection): List[FaceOverlay]
|
||||
}
|
||||
@@ -0,0 +1,121 @@
|
||||
/*
|
||||
* Copyright (c) bdew, 2013 - 2014
|
||||
* https://github.com/bdew/bdlib
|
||||
*
|
||||
* This mod is distributed under the terms of the Minecraft Mod Public
|
||||
* License 1.0, or MMPL. Please check the contents of the license located in
|
||||
* https://raw.github.com/bdew/bdlib/master/MMPL-1.0.txt
|
||||
*/
|
||||
|
||||
package net.bdew.lib.render.connected
|
||||
|
||||
import net.bdew.lib.block.BlockRef
|
||||
import net.minecraft.client.renderer.Tessellator
|
||||
import net.minecraft.util.IIcon
|
||||
import net.minecraftforge.common.util.ForgeDirection
|
||||
|
||||
object ConnectedHelper {
|
||||
val edgeWidth = 1 / 16F
|
||||
|
||||
// Represents the rectangles of all edges/corners on a 2d pane
|
||||
// 701
|
||||
// 6 2
|
||||
// 543
|
||||
// 8 is a special case for the full face
|
||||
val faceEdges = Array(
|
||||
RectF(0, 1 - edgeWidth, 1, 1),
|
||||
RectF(1 - edgeWidth, 1 - edgeWidth, 1, 1),
|
||||
RectF(1 - edgeWidth, 0, 1, 1),
|
||||
RectF(1 - edgeWidth, 0, 1, edgeWidth),
|
||||
RectF(0, 0, 1, edgeWidth),
|
||||
RectF(0, 0, edgeWidth, edgeWidth),
|
||||
RectF(0, 0, edgeWidth, 1),
|
||||
RectF(0, 1 - edgeWidth, edgeWidth, 1),
|
||||
RectF(0, 0, 1, 1)
|
||||
)
|
||||
|
||||
val faceAdjanced = (for (x <- ForgeDirection.VALID_DIRECTIONS) yield x -> new FaceAdjanced(x)).toMap
|
||||
|
||||
// Maps edge number + face to 3d vertices
|
||||
val draw =
|
||||
(for ((rect, n) <- faceEdges.zipWithIndex; face <- ForgeDirection.VALID_DIRECTIONS)
|
||||
yield (face, n) -> new EdgeDraw(rect, face)).toMap
|
||||
|
||||
val brightnessMultiplier = Map(
|
||||
ForgeDirection.UP -> 1F,
|
||||
ForgeDirection.DOWN -> 0.5F,
|
||||
ForgeDirection.NORTH -> 0.8F,
|
||||
ForgeDirection.SOUTH -> 0.8F,
|
||||
ForgeDirection.WEST -> 0.6F,
|
||||
ForgeDirection.EAST -> 0.6F
|
||||
)
|
||||
|
||||
case class Vec3F(x: Float, y: Float, z: Float) {
|
||||
def *(m: Float) = Vec3F(x * m, y * m, z * m)
|
||||
def +(m: Vec3F) = Vec3F(x + m.x, y + m.y, z + m.z)
|
||||
def -(m: Vec3F) = Vec3F(x - m.x, y - m.y, z - m.z)
|
||||
def +(d: ForgeDirection) = Vec3F(x + d.offsetX, y + d.offsetY, z + d.offsetZ)
|
||||
def toInts = (x.toInt, y.toInt, z.toInt)
|
||||
def asBlockRef = BlockRef(x.toInt, y.toInt, z.toInt)
|
||||
}
|
||||
|
||||
case class RectF(x1: Float, y1: Float, x2: Float, y2: Float) {
|
||||
def corners = Seq(Vec2F(x1, y1), Vec2F(x2, y1), Vec2F(x2, y2), Vec2F(x1, y2))
|
||||
}
|
||||
|
||||
case class Vec2F(u: Float, v: Float)
|
||||
|
||||
case class VecPair(pos: Vec3F, tex: Vec2F)
|
||||
|
||||
class EdgeDraw(rect: RectF, face: ForgeDirection) {
|
||||
val vertices = rect.corners map { d =>
|
||||
val v = face match {
|
||||
case ForgeDirection.UP => Vec3F(d.u, 1, 1 - d.v)
|
||||
case ForgeDirection.DOWN => Vec3F(d.u, 0, d.v)
|
||||
case ForgeDirection.NORTH => Vec3F(1 - d.u, d.v, 0)
|
||||
case ForgeDirection.SOUTH => Vec3F(d.u, d.v, 1)
|
||||
case ForgeDirection.EAST => Vec3F(1, d.v, 1 - d.u)
|
||||
case ForgeDirection.WEST => Vec3F(0, d.v, d.u)
|
||||
case _ => sys.error("Invalid face")
|
||||
}
|
||||
VecPair(extend(v, 0.001F), d)
|
||||
}
|
||||
|
||||
def doDraw(pos: Vec3F, icon: IIcon) {
|
||||
for (v <- vertices)
|
||||
addVertextWithUV(v.pos + pos, mapToIcon(v.tex, icon))
|
||||
}
|
||||
}
|
||||
|
||||
def extend(v: Vec3F, o: Float) = Vec3F(
|
||||
if (v.x == 0F) -o else if (v.x == 1F) 1 + o else v.x,
|
||||
if (v.y == 0F) -o else if (v.y == 1F) 1 + o else v.y,
|
||||
if (v.z == 0F) -o else if (v.z == 1F) 1 + o else v.z
|
||||
)
|
||||
|
||||
def mapToIcon(v: Vec2F, i: IIcon) = Vec2F(i.getInterpolatedU(v.u * 16), i.getInterpolatedV((1 - v.v) * 16))
|
||||
|
||||
def addVertextWithUV(p: Vec3F, t: Vec2F) =
|
||||
Tessellator.instance.addVertexWithUV(p.x, p.y, p.z, t.u, t.v)
|
||||
|
||||
class FaceAdjanced(d: ForgeDirection) {
|
||||
val top = d match {
|
||||
case ForgeDirection.UP => ForgeDirection.NORTH
|
||||
case ForgeDirection.DOWN => ForgeDirection.SOUTH
|
||||
case _ => ForgeDirection.UP
|
||||
}
|
||||
|
||||
val right = d match {
|
||||
case ForgeDirection.UP => ForgeDirection.EAST
|
||||
case ForgeDirection.DOWN => ForgeDirection.EAST
|
||||
case ForgeDirection.NORTH => ForgeDirection.WEST
|
||||
case ForgeDirection.WEST => ForgeDirection.SOUTH
|
||||
case ForgeDirection.SOUTH => ForgeDirection.EAST
|
||||
case ForgeDirection.EAST => ForgeDirection.NORTH
|
||||
case _ => ForgeDirection.UNKNOWN
|
||||
}
|
||||
val bottom = top.getOpposite
|
||||
val left = right.getOpposite
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,113 @@
|
||||
/*
|
||||
* Copyright (c) bdew, 2013 - 2014
|
||||
* https://github.com/bdew/bdlib
|
||||
*
|
||||
* This mod is distributed under the terms of the Minecraft Mod Public
|
||||
* License 1.0, or MMPL. Please check the contents of the license located in
|
||||
* https://raw.github.com/bdew/bdlib/master/MMPL-1.0.txt
|
||||
*/
|
||||
|
||||
package net.bdew.lib.render.connected
|
||||
|
||||
import cpw.mods.fml.client.registry.{ISimpleBlockRenderingHandler, RenderingRegistry}
|
||||
import net.bdew.lib.block.BlockRef
|
||||
import net.minecraft.block.Block
|
||||
import net.minecraft.client.renderer.{RenderBlocks, Tessellator}
|
||||
import net.minecraft.world.IBlockAccess
|
||||
import net.minecraftforge.common.util.ForgeDirection
|
||||
import org.lwjgl.opengl.GL11
|
||||
|
||||
object ConnectedRenderer extends ISimpleBlockRenderingHandler {
|
||||
val id = RenderingRegistry.getNextAvailableRenderId
|
||||
RenderingRegistry.registerBlockHandler(this)
|
||||
|
||||
def doRenderItemSide(d: ForgeDirection, r: RenderBlocks, block: Block, meta: Int) = {
|
||||
val icon = r.getBlockIconFromSideAndMetadata(block, d.ordinal(), meta)
|
||||
Tessellator.instance.setNormal(d.offsetX, d.offsetY, d.offsetZ)
|
||||
d match {
|
||||
case ForgeDirection.DOWN => r.renderFaceYNeg(block, 0.0D, 0.0D, 0.0D, icon)
|
||||
case ForgeDirection.UP => r.renderFaceYPos(block, 0.0D, 0.0D, 0.0D, icon)
|
||||
case ForgeDirection.NORTH => r.renderFaceZNeg(block, 0.0D, 0.0D, 0.0D, icon)
|
||||
case ForgeDirection.SOUTH => r.renderFaceZPos(block, 0.0D, 0.0D, 0.0D, icon)
|
||||
case ForgeDirection.WEST => r.renderFaceXNeg(block, 0.0D, 0.0D, 0.0D, icon)
|
||||
case ForgeDirection.EAST => r.renderFaceXPos(block, 0.0D, 0.0D, 0.0D, icon)
|
||||
case _ => sys.error("Invalid side")
|
||||
}
|
||||
}
|
||||
|
||||
override def renderInventoryBlock(block: Block, metadata: Int, modelID: Int, renderer: RenderBlocks) {
|
||||
val tessellator = Tessellator.instance
|
||||
GL11.glTranslatef(-0.5F, -0.5F, -0.5F)
|
||||
|
||||
val edge = block.asInstanceOf[ConnectedTextureBlock].edgeIcon
|
||||
|
||||
for (side <- ForgeDirection.VALID_DIRECTIONS) {
|
||||
tessellator.startDrawingQuads()
|
||||
doRenderItemSide(side, renderer, block, metadata)
|
||||
val m = ConnectedHelper.brightnessMultiplier(side)
|
||||
ConnectedHelper.draw(side, 8).doDraw(ConnectedHelper.Vec3F(0, 0, 0), edge)
|
||||
tessellator.draw()
|
||||
}
|
||||
|
||||
GL11.glTranslatef(0.5F, 0.5F, 0.5F)
|
||||
}
|
||||
|
||||
override def renderWorldBlock(world: IBlockAccess, x: Int, y: Int, z: Int, block: Block, modelId: Int, renderer: RenderBlocks): Boolean = {
|
||||
renderer.renderStandardBlock(block, x, y, z)
|
||||
|
||||
val pos = ConnectedHelper.Vec3F(x, y, z)
|
||||
for (face <- ForgeDirection.VALID_DIRECTIONS)
|
||||
if (block.shouldSideBeRendered(world, x + face.offsetX, y + face.offsetY, z + face.offsetZ, face.ordinal()))
|
||||
drawFaceEdges(world, pos, face, block.asInstanceOf[ConnectedTextureBlock])
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
def drawFaceEdges(world: IBlockAccess, pos: ConnectedHelper.Vec3F, face: ForgeDirection, block: ConnectedTextureBlock) {
|
||||
val edge = block.edgeIcon
|
||||
val canConnect = block.canConnect(world, pos.asBlockRef, _: BlockRef)
|
||||
val sides = ConnectedHelper.faceAdjanced(face)
|
||||
|
||||
val m = ConnectedHelper.brightnessMultiplier(face)
|
||||
Tessellator.instance.setColorOpaque_F(m, m, m)
|
||||
|
||||
val fo = pos + face
|
||||
val b = block.getMixedBrightnessForBlock(world, fo.x.toInt, fo.y.toInt, fo.z.toInt)
|
||||
Tessellator.instance.setBrightness(b)
|
||||
|
||||
val U = !canConnect((pos + sides.top).asBlockRef)
|
||||
val D = !canConnect((pos + sides.bottom).asBlockRef)
|
||||
val L = !canConnect((pos + sides.left).asBlockRef)
|
||||
val R = !canConnect((pos + sides.right).asBlockRef)
|
||||
|
||||
if (!U && !R && !canConnect((pos + sides.top + sides.right).asBlockRef))
|
||||
ConnectedHelper.draw(face, 1).doDraw(pos, edge)
|
||||
|
||||
if (!U && !L && !canConnect((pos + sides.top + sides.left).asBlockRef))
|
||||
ConnectedHelper.draw(face, 7).doDraw(pos, edge)
|
||||
|
||||
if (!D && !R && !canConnect((pos + sides.bottom + sides.right).asBlockRef))
|
||||
ConnectedHelper.draw(face, 3).doDraw(pos, edge)
|
||||
|
||||
if (!D && !L && !canConnect((pos + sides.bottom + sides.left).asBlockRef))
|
||||
ConnectedHelper.draw(face, 5).doDraw(pos, edge)
|
||||
|
||||
if (U) ConnectedHelper.draw(face, 0).doDraw(pos, edge)
|
||||
if (D) ConnectedHelper.draw(face, 4).doDraw(pos, edge)
|
||||
if (R) ConnectedHelper.draw(face, 2).doDraw(pos, edge)
|
||||
if (L) ConnectedHelper.draw(face, 6).doDraw(pos, edge)
|
||||
|
||||
if (block.isInstanceOf[BlockAdditionalRender]) {
|
||||
val overlays = block.asInstanceOf[BlockAdditionalRender].getFaceOverlays(world, pos.x.toInt, pos.y.toInt, pos.z.toInt, face)
|
||||
for (overlay <- overlays) {
|
||||
Tessellator.instance.setColorOpaque_F(overlay.color.r, overlay.color.g, overlay.color.b)
|
||||
ConnectedHelper.draw(face, 8).doDraw(pos, overlay.icon)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override def shouldRender3DInInventory(modelId: Int) = true
|
||||
override def getRenderId = id
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,22 @@
|
||||
/*
|
||||
* Copyright (c) bdew, 2013 - 2014
|
||||
* https://github.com/bdew/bdlib
|
||||
*
|
||||
* This mod is distributed under the terms of the Minecraft Mod Public
|
||||
* License 1.0, or MMPL. Please check the contents of the license located in
|
||||
* https://raw.github.com/bdew/bdlib/master/MMPL-1.0.txt
|
||||
*/
|
||||
|
||||
package net.bdew.lib.render.connected
|
||||
|
||||
import net.bdew.lib.block.BlockRef
|
||||
import net.minecraft.block.Block
|
||||
import net.minecraft.util.IIcon
|
||||
import net.minecraft.world.IBlockAccess
|
||||
|
||||
trait ConnectedTextureBlock extends Block {
|
||||
def edgeIcon: IIcon
|
||||
def canConnect(world: IBlockAccess, origin: BlockRef, target: BlockRef): Boolean
|
||||
|
||||
override def getRenderType = ConnectedRenderer.id
|
||||
}
|
||||
Reference in new issue
Block a user