Jump to content

[SOLVED] Tessellator Troubles


Flenix

Recommended Posts

Hey guys,

 

I want to get the hang of the Tessellator. One of the mods I'm working on is almost entirely modelled stuff, so if I can use the tessellator to model them without a tile entity, then that would be a huge bonus!

 

However, I seem to be struggling on the texturing part. As far as I can tell my quads are ok (maybe not? Can't see them to check!) but I can't even get the purple/black missing texture to show. I've tried looking through RenderBlocks to no avail.

 

here's the code. Can anyone point me in the right direction?

package co.uk.silvania.roads.block.tess.renderers;

import org.lwjgl.opengl.GL11;

import co.uk.silvania.roads.client.ClientProxy;
import net.minecraft.block.Block;
import net.minecraft.client.Minecraft;
import net.minecraft.client.renderer.RenderBlocks;
import net.minecraft.client.renderer.Tessellator;
import net.minecraft.client.renderer.texture.TextureMap;
import net.minecraft.util.Icon;
import net.minecraft.util.ResourceLocation;
import net.minecraft.world.IBlockAccess;
import cpw.mods.fml.client.registry.ISimpleBlockRenderingHandler;
import cpw.mods.fml.relauncher.Side;
import cpw.mods.fml.relauncher.SideOnly;

public class ShortRampRenderer implements ISimpleBlockRenderingHandler {

Tessellator tes = Tessellator.instance;

//Whole renderInventoryBlock Method borrowed from another mod purely for testing purposes, so I can be sure my block is using this render class.
//It will be removed and rewritten before compiling
@Override
public void renderInventoryBlock(Block block, int metadata, int modelID, RenderBlocks renderblocks) 
{
         if(modelID == ClientProxy.RoadsRampShortRenderID) 
         {
        	 for(int i = 1; i <= 21; ++i) 
        	 {
        		 switch(i) 
        		 {
        		 //top row
        		 case 1: renderblocks.setRenderBounds(0.15D, 0.0D, 0.15D, 0.25D, 1.0D, 0.25D); break;
        		 case 2: renderblocks.setRenderBounds(0.45D, 0.0D, 0.15D, 0.55D, 1.0D, 0.25D); break;
        		 case 3: renderblocks.setRenderBounds(0.75D, 0.0D, 0.15D, 0.85D, 1.0D, 0.25D); break;
        		 //middle row
        		 case 4: renderblocks.setRenderBounds(0.15D, 0.0D, 0.45D, 0.25D, 1.0D, 0.55D); break;
        		 case 5: renderblocks.setRenderBounds(0.45D, 0.0D, 0.45D, 0.55D, 1.0D, 0.55D); break;
        		 case 6: renderblocks.setRenderBounds(0.75D, 0.0D, 0.45D, 0.85D, 1.0D, 0.55D); break;
        		 }
                 
        		 GL11.glTranslatef(-0.5F, -0.5F, -0.5F);
        		 float var7 = 0.0F;
        		 tes.startDrawingQuads();
        		 tes.setNormal(0.0F, -1.0F, 0.0F);
        		 renderblocks.renderFaceZNeg(block, 0.0D, 0.0D, 0.0D, block.getBlockTextureFromSide(0));
        		 tes.draw();
        		 tes.startDrawingQuads();
        		 tes.setNormal(0.0F, 1.0F, 0.0F);
        		 renderblocks.renderFaceZPos(block, 0.0D, 0.0D, 0.0D, block.getBlockTextureFromSide(1));
        		 tes.draw();
        		 tes.startDrawingQuads();
        		 tes.setNormal(0.0F, 0.0F, -1.0F);
        		 tes.addTranslation(0.0F, 0.0F, var7);
        		 renderblocks.renderFaceXPos(block, 0.0D, 0.0D, 0.0D, block.getBlockTextureFromSide(2));
        		 tes.addTranslation(0.0F, 0.0F, -var7);
        		 tes.draw();
        		 tes.startDrawingQuads();
        		 tes.setNormal(0.0F, 0.0F, 1.0F);
        		 tes.addTranslation(0.0F, 0.0F, -var7);
        		 renderblocks.renderFaceXNeg(block, 0.0D, 0.0D, 0.0D, block.getBlockTextureFromSide(3));
        		 tes.addTranslation(0.0F, 0.0F, var7);
        		 tes.draw();
        		 tes.startDrawingQuads();
        		 tes.setNormal(-1.0F, 0.0F, 0.0F);
        		 tes.addTranslation(var7, 0.0F, 0.0F);
        		 renderblocks.renderFaceYPos(block, 0.0D, 0.0D, 0.0D, block.getBlockTextureFromSide(4));
        		 tes.addTranslation(-var7, 0.0F, 0.0F);
        		 tes.draw();
        		 tes.startDrawingQuads();
        		 tes.setNormal(1.0F, 0.0F, 0.0F);
        		 tes.addTranslation(-var7, 0.0F, 0.0F);
        		 renderblocks.renderFaceYNeg(block, 0.0D, 0.0D, 0.0D, block.getBlockTextureFromSide(5));
        		 tes.addTranslation(var7, 0.0F, 0.0F);
        		 tes.draw();
        		 GL11.glTranslatef(0.5F, 0.5F, 0.5F);
        		 
        	 }
         }
}

@Override
public boolean renderWorldBlock(IBlockAccess world, int x, int y, int z, Block block, int modelId, RenderBlocks renderer) {
	if(modelId == ClientProxy.RoadsRampShortRenderID)
		return RenderShortRamp(block, x, y, z, renderer);  
	else
		return false;
}

public boolean shouldRender3DInInventory() {
	return true;
}

@Override
public int getRenderId() {
	return 0;
}

    public Icon getBlockIconFromSide(Block par1Block, int par2) {
        return this.getIconSafe(par1Block.getBlockTextureFromSide(par2));
    }
    
    public Icon getIconSafe(Icon par1Icon) {
        if (par1Icon == null) {
            par1Icon = ((TextureMap)Minecraft.getMinecraft().func_110434_K().func_110581_b(TextureMap.field_110575_b)).func_110572_b("missingno");
        }

        return (Icon)par1Icon;
    }

@SideOnly(Side.CLIENT)
public boolean RenderShortRamp(Block block, int x, int y, int z, RenderBlocks render) {
        Icon icon = this.getBlockIconFromSide(block, 0);
        
        if (render.hasOverrideBlockTexture()) {
        	icon = render.overrideBlockTexture;
        }
        
        tes.addVertexWithUV(0.0, 1.0, 1.0, 12, 24);
        tes.addVertexWithUV(1.0, 1.0, 1.0, 12, 24);
        tes.addVertexWithUV(1.0, 1.0, 0.0, 12, 24);
        tes.addVertexWithUV(0.0, 1.0, 0.0, 12, 24);
        tes.draw();
        tes.startDrawingQuads();
        tes.addVertexWithUV(0.0, 0.0, 1.0, 12, 24);
        tes.addVertexWithUV(0.0, 1.0, 1.0, 12, 24);
        tes.addVertexWithUV(0.0, 1.0, 0.0, 12, 24);
        tes.addVertexWithUV(0.0, 0.0, 0.0, 12, 24);

	return true;
}
}

 

 

From my understanding of quads, the above should theoretically draw two full faces of a standard block. I've only ever touched quads in a simple block modeller used for a spout plugin though, never actually coded with them.

 

Once I understand this, I want to take the above modeller and modify it, so anyone else who wants to use the tessellator can make their actual models in there and just import the code.

 

 




 

As this thread is 4 posts long, I'll save you all SOME time if you're trying to learn from it. Below is my current ISBRH, fully working. It's up to you to figure out the implementation.

The model in this example is a simple slope, similar to that Slopes mod from a while ago. I thought it was a good, simple model to use for the example throughout this post, but remember with the ISBRH and tessellator you can make things much more complex than in Techne.

 

 

package co.uk.silvania.roads.block.tess.renderers;

import org.lwjgl.opengl.GL11;

import co.uk.silvania.roads.client.ClientProxy;

import net.minecraft.block.Block;
import net.minecraft.client.Minecraft;
import net.minecraft.client.renderer.RenderBlocks;
import net.minecraft.client.renderer.Tessellator;
import net.minecraft.util.Icon;
import net.minecraft.util.ResourceLocation;
import net.minecraft.world.IBlockAccess;
import cpw.mods.fml.client.registry.ISimpleBlockRenderingHandler;
import cpw.mods.fml.relauncher.Side;
import cpw.mods.fml.relauncher.SideOnly;

public class ShortRampRenderer implements ISimpleBlockRenderingHandler {

@Override
public void renderInventoryBlock(Block block, int metadata, int modelID, RenderBlocks renderer) {

}

    @Override
    @SideOnly(Side.CLIENT)
    public boolean renderWorldBlock(IBlockAccess world, int x, int y, int z, Block block, int modelId, RenderBlocks renderer) {
    	int meta = world.getBlockMetadata(x, y, z);
    	Icon c = block.getIcon(0, meta);
    	Icon b = block.getIcon(1, meta);
    	
    	int brightness = Block.blocksList[block.stone.blockID].getMixedBrightnessForBlock(world, x, y, z);
    	
    	float u = c.getMinU();
    	float v = c.getMinV();
    	float U = c.getMaxU();
    	float V = c.getMaxV();
    	
    	float u1 = b.getMinU();
    	float v1 = b.getMinV();
    	float U1 = b.getMaxU();
    	float V1 = b.getMaxV();
    	
	Tessellator tess = Tessellator.instance;
	tess.addTranslation(x, y, z);
	tess.setBrightness(brightness);
	tess.setColorOpaque_F(1.0F, 1.0F, 1.0F);
	//Base
	tess.addVertexWithUV(0, -0.25, 1, u, v);
	tess.addVertexWithUV(0, -0.25, 0, u, V);
	tess.addVertexWithUV(1, -0.25, 0, U, V);
	tess.addVertexWithUV(1, -0.25, 1, U, v);
	//Top Slope
	tess.addVertexWithUV(0, -0.25, 1, u1, v1);
	tess.addVertexWithUV(1, 0.75, 1, u1, V1);
	tess.addVertexWithUV(1, 0.75, 0, U1, V1);
	tess.addVertexWithUV(0, -0.25, 0, U1, v1);

	tess.addVertexWithUV(1, -0.25, 0, u, v);
	tess.addVertexWithUV(1, 0.75, 0, u, V);
	tess.addVertexWithUV(1, 0.75, 1, U, V);
	tess.addVertexWithUV(1, -0.25, 1, U, v);

	tess.addVertexWithUV(1, 0.75, 0, u, v);
	tess.addVertexWithUV(1, -0.25, 0, u, V);
	tess.addVertexWithUV(0, -0.25, 0, U, V);
	tess.addVertexWithUV(1, 0.75, 0, U, v);

	tess.addVertexWithUV(1, 0.75, 1, u, v);
	tess.addVertexWithUV(0, -0.25, 1, u, V);
	tess.addVertexWithUV(1, -0.25, 1, U, V);
	tess.addVertexWithUV(1, 0.75, 1, U, v);

	tess.addTranslation(-x, -y, -z);
        return true;
    }

@Override
public boolean shouldRender3DInInventory() {
	return false;
}

@Override
public int getRenderId() {
	return ClientProxy.RoadsRampShortRenderID;
}
}

width=463 height=200

http://s13.postimg.org/z9mlly2av/siglogo.png[/img]

My mods (Links coming soon)

Cities | Roads | Remula | SilvaniaMod | MoreStats

Link to comment
Share on other sites

  • Replies 83
  • Created
  • Last Reply

Top Posters In This Topic

hey, have you been looking at my tut ?

 

so first this is weird:

tes.addVertexWithUV(0.0, 1.0, 1.0, 12, 24);

because that would mean you want to fit the image 12 time horizintally and 24 times vertically (so there would be 12*24 time the image im your quad)

 

also, have you made any println in your render method to make sure its actually beign called

 

i think you should start by a very simple quad and buidl from there ( not try to copy paste the whole thing and expect it to work :P)

 

i think if you're not using a TESR you cant have animations (just extra info)

 

im here to help ask me anything :)

how to debug 101:http://www.minecraftforge.net/wiki/Debug_101

-hydroflame, author of the forge revolution-

Link to comment
Share on other sites

extra:

RenderShortRamp this method is VERY weird

 

specially :

 

tes.addVertexWithUV(0.0, 1.0, 0.0, 12, 24);
tes.draw();
tes.startDrawingQuads();
tes.addVertexWithUV(0.0, 0.0, 1.0, 12, 24);

and no other call to draw() or startDrawing() in the same method

whoever made this code really has no idea how this works

 

you should always have matching startDrawing() and draw() in the same method unless you really know what you're doing and\or youre doing something very special

 

 

how to debug 101:http://www.minecraftforge.net/wiki/Debug_101

-hydroflame, author of the forge revolution-

Link to comment
Share on other sites

I made that part, and no I don't have any idea how it works. Noone on IRC was able to help so I was literally stabbing in the dark, trial-and-error to see what I could do.

 

I was basing off the little knowledge of quads I had. I figured that the 5 doubles were the x/y/z of the vertices, and then I assumed the x/y coords from the texture (You say it's actually tiling the texture though?)

 

I also figured you'd need four vertices to make a quad, one for each corner. The draw and startDrawing were a guess as to a way to seperate one quad from the next. The reason I don't have them at the start or end is because that's handled in the borrowed code - if I put startDrawingQuads before everything, the game crashes.

 

It's only that part I'm even having issues with. The in-hand rendering (the borrowed code) works:

51fa8ab23efd4.jpg

 

 

I hadn't seen any tutorial at all, been trying to find one all day. Can you link me to yours?

width=463 height=200

http://s13.postimg.org/z9mlly2av/siglogo.png[/img]

My mods (Links coming soon)

Cities | Roads | Remula | SilvaniaMod | MoreStats

Link to comment
Share on other sites

yes here:http://www.minecraftforge.net/wiki/Tessellator

 

 

you dont have to make 4 call to addVertexWithUV before calling another draw()/startDrawing()

but it has to be  multple of 4 if you started with "startDrawingQuads()"

(extra info, you cna if you want startDrawing(GL11.GL_TRIANGLES) but stick with quads becseu itll be easier in your case

 

and yes the reason you don't have any texture is mostly becasue there no call to renderEngine.func_110577_a(ResourceLocation); at all, so the render engine doesn't have any texture to place on your quads

 

 

how to debug 101:http://www.minecraftforge.net/wiki/Debug_101

-hydroflame, author of the forge revolution-

Link to comment
Share on other sites

if you need more reference code, you can look at renderBlockTorch and renderTorchAtAngle in the RenderBlocks class. it's pretty simple since it only adds 6 sides. you'll also be able to figure out some uses of icons from those methods

Link to comment
Share on other sites

yes here:http://www.minecraftforge.net/wiki/Tessellator

 

 

you dont have to make 4 call to addVertexWithUV before calling another draw()/startDrawing()

but it has to be  multple of 4 if you started with "startDrawingQuads()"

(extra info, you cna if you want startDrawing(GL11.GL_TRIANGLES) but stick with quads becseu itll be easier in your case

 

Oh I get it, so I can have startDrawingQuads, then say 12 vertex, then draw, without anything in the middle and the code will be clever and know thats 3 different quads? Cool

 

and yes the reason you don't have any texture is mostly becasue there no call to renderEngine.func_110577_a(ResourceLocation); at all, so the render engine doesn't have any texture to place on your quads

 

Ah fair enough. I'll toy around with that.

 

 

Also, with your tutorial - is it ok if I fix a few spelling mistakes etc? Just noticed a couple is all.

 

 

if you need more reference code, you can look at renderBlockTorch and renderTorchAtAngle in the RenderBlocks class. it's pretty simple since it only adds 6 sides. you'll also be able to figure out some uses of icons from those methods

 

Thanks, I'll look there if I get stuck :D

 

 

width=463 height=200

http://s13.postimg.org/z9mlly2av/siglogo.png[/img]

My mods (Links coming soon)

Cities | Roads | Remula | SilvaniaMod | MoreStats

Link to comment
Share on other sites

Also, with your tutorial - is it ok if I fix a few spelling mistakes etc? Just noticed a couple is all.

english is not my first language (french is) so yes please do :)

 

Oh I get it, so I can have startDrawingQuads, then say 12 vertex, then draw, without anything in the middle and the code will be clever and know thats 3 different quads? Cool

yes but you can not change texture for the 3 different quads or change the color

 

how to debug 101:http://www.minecraftforge.net/wiki/Debug_101

-hydroflame, author of the forge revolution-

Link to comment
Share on other sites

ok well first you need to make a new ResourceLocation

 

like this

public static final ResourceLocation myImage = new ResourceLocation("modid", "path/to/texture")

the 2nd string must NOT start with a "/" btw

ex:

public static final ResourceLocation myImage = new ResourceLocation("forgerev", "textures/models/spacepirate.png")

and the file system for that will be:

mcp/src/minecraft/assets/forgerev/textures/models/spacepirate.png

 

then just

renderEngine.func_110577_a(myImage);

 

also surround ALL your render code with

 

GL11.glPushMatrix();

//render code

GL11.glPopMatrix();

 

how to debug 101:http://www.minecraftforge.net/wiki/Debug_101

-hydroflame, author of the forge revolution-

Link to comment
Share on other sites

When I tried using the ResourceLocation, very very strange things started happening... mostly involving chunks de-rendering :P

 

i'm currently cleaning up my code right now and i'm currently removing tile entities that i was too lazy to use isimpleblockrenakdjsfak for and i ran into that. i haven't really looked into block rendering too much until now, but what i've been able to figure out is:

 

mc renders in bulk. it doesn't render per block per chunk. it goes through each block in the chunk and adds the vertices but doesn't render them. once it's done with each block, that's when it renders everything. and since they're rendered in bulk, when you change the texture being used, you change it for every block in the chunk. so you're either gonna have to use icons to include your textures in the terrain texture (can icons be larger than 16x16? still gonna test it out later) or do what hydroflame suggested (but you'll have to figure out a way around the problem).. or something else. i dunno. i vote icons if they work

 

if I put startDrawingQuads before everything, the game crashes.

 

that's because it's already been called beforehand. and draw() is called after mc is done going through the blocks in the chunk. unless you want to do something else, all you really need to do is supply the vertices

 

also, if you want it to render with the correct brightness, seems like you'll have to add it for each side yourself. depending on how you want that to work, it could go from a few lines of code to buttloads. basically, the more complicated your block is, the more tedious it gets. the plus side is that the code seems pretty straightforward and easy to read despite the amount of it

 

anyway, like i said, i'm still digging through the rendering code. if i made a mistake, feel free to tell me :)

Link to comment
Share on other sites

When I tried using the ResourceLocation, very very strange things started happening... mostly involving chunks de-rendering :P

 

i'm currently cleaning up my code right now and i'm currently removing tile entities that i was too lazy to use isimpleblockrenakdjsfak for and i ran into that. i haven't really looked into block rendering too much until now, but what i've been able to figure out is:

 

mc renders in bulk. it doesn't render per block per chunk. it goes through each block in the chunk and adds the vertices but doesn't render them. once it's done with each block, that's when it renders everything. and since they're rendered in bulk, when you change the texture being used, you change it for every block in the chunk. so you're either gonna have to use icons to include your textures in the terrain texture (can icons be larger than 16x16? still gonna test it out later) or do what hydroflame suggested (but you'll have to figure out a way around the problem).. or something else. i dunno. i vote icons if they work

 

if I put startDrawingQuads before everything, the game crashes.

 

that's because it's already been called beforehand. and draw() is called after mc is done going through the blocks in the chunk. unless you want to do something else, all you really need to do is supply the vertices

 

also, if you want it to render with the correct brightness, seems like you'll have to add it for each side yourself. depending on how you want that to work, it could go from a few lines of code to buttloads. basically, the more complicated your block is, the more tedious it gets. the plus side is that the code seems pretty straightforward and easy to read despite the amount of it

 

anyway, like i said, i'm still digging through the rendering code. if i made a mistake, feel free to tell me :)

 

hydroflame, do you know a fix for this? I got my texture to work but it plunges my world into darkness:

before:

51fb7862c36b6.jpg

 

after:

51fb78664d4fd.jpg

 

Code:

package co.uk.silvania.roads.block.tess.renderers;

import org.lwjgl.opengl.GL11;

import co.uk.silvania.roads.client.ClientProxy;
import net.minecraft.block.Block;
import net.minecraft.client.Minecraft;
import net.minecraft.client.renderer.RenderBlocks;
import net.minecraft.client.renderer.Tessellator;
import net.minecraft.client.renderer.texture.TextureManager;
import net.minecraft.client.renderer.texture.TextureMap;
import net.minecraft.util.Icon;
import net.minecraft.util.ResourceLocation;
import net.minecraft.world.IBlockAccess;
import cpw.mods.fml.client.registry.ISimpleBlockRenderingHandler;
import cpw.mods.fml.relauncher.Side;
import cpw.mods.fml.relauncher.SideOnly;

public class ShortRampRenderer implements ISimpleBlockRenderingHandler {

public static final ResourceLocation texture = new ResourceLocation("roads", "textures/blocks/roadBlockMiscSingles0.png");

Tessellator tes = Tessellator.instance;

//Whole renderInventoryBlock Method borrowed from another mod purely for testing purposes, so I can be sure my block is using this render class.
//It will be removed and rewritten before compiling
@Override
public void renderInventoryBlock(Block block, int metadata, int modelID, RenderBlocks renderblocks) 
{
         if(modelID == ClientProxy.RoadsRampShortRenderID) 
         {
        	 for(int i = 1; i <= 21; ++i) 
        	 {
        		 switch(i) 
        		 {
        		 //top row
        		 case 1: renderblocks.setRenderBounds(0.15D, 0.0D, 0.15D, 0.25D, 1.0D, 0.25D); break;
        		 case 2: renderblocks.setRenderBounds(0.45D, 0.0D, 0.15D, 0.55D, 1.0D, 0.25D); break;
        		 case 3: renderblocks.setRenderBounds(0.75D, 0.0D, 0.15D, 0.85D, 1.0D, 0.25D); break;
        		 //middle row
        		 case 4: renderblocks.setRenderBounds(0.15D, 0.0D, 0.45D, 0.25D, 1.0D, 0.55D); break;
        		 case 5: renderblocks.setRenderBounds(0.45D, 0.0D, 0.45D, 0.55D, 1.0D, 0.55D); break;
        		 case 6: renderblocks.setRenderBounds(0.75D, 0.0D, 0.45D, 0.85D, 1.0D, 0.55D); break;
        		 }
                 
        		 GL11.glTranslatef(-0.5F, -0.5F, -0.5F);
        		 float var7 = 0.0F;
        		 tes.startDrawingQuads();
        		 tes.setNormal(0.0F, -1.0F, 0.0F);
        		 renderblocks.renderFaceZNeg(block, 0.0D, 0.0D, 0.0D, block.getBlockTextureFromSide(0));
        		 tes.draw();
        		 tes.startDrawingQuads();
        		 tes.setNormal(0.0F, 1.0F, 0.0F);
        		 renderblocks.renderFaceZPos(block, 0.0D, 0.0D, 0.0D, block.getBlockTextureFromSide(1));
        		 tes.draw();
        		 tes.startDrawingQuads();
        		 tes.setNormal(0.0F, 0.0F, -1.0F);
        		 tes.addTranslation(0.0F, 0.0F, var7);
        		 renderblocks.renderFaceXPos(block, 0.0D, 0.0D, 0.0D, block.getBlockTextureFromSide(2));
        		 tes.addTranslation(0.0F, 0.0F, -var7);
        		 tes.draw();
        		 tes.startDrawingQuads();
        		 tes.setNormal(0.0F, 0.0F, 1.0F);
        		 tes.addTranslation(0.0F, 0.0F, -var7);
        		 renderblocks.renderFaceXNeg(block, 0.0D, 0.0D, 0.0D, block.getBlockTextureFromSide(3));
        		 tes.addTranslation(0.0F, 0.0F, var7);
        		 tes.draw();
        		 tes.startDrawingQuads();
        		 tes.setNormal(-1.0F, 0.0F, 0.0F);
        		 tes.addTranslation(var7, 0.0F, 0.0F);
        		 renderblocks.renderFaceYPos(block, 0.0D, 0.0D, 0.0D, block.getBlockTextureFromSide(4));
        		 tes.addTranslation(-var7, 0.0F, 0.0F);
        		 tes.draw();
        		 tes.startDrawingQuads();
        		 tes.setNormal(1.0F, 0.0F, 0.0F);
        		 tes.addTranslation(-var7, 0.0F, 0.0F);
        		 renderblocks.renderFaceYNeg(block, 0.0D, 0.0D, 0.0D, block.getBlockTextureFromSide(5));
        		 tes.addTranslation(var7, 0.0F, 0.0F);
        		 tes.draw();
        		 GL11.glTranslatef(0.5F, 0.5F, 0.5F);
        		 
        	 }
         }
}

@Override
public boolean renderWorldBlock(IBlockAccess world, int x, int y, int z, Block block, int modelId, RenderBlocks renderer) {
	if(modelId == ClientProxy.RoadsRampShortRenderID)
		return RenderShortRamp(block, x, y, z, renderer);  
	else
		return false;
}

public boolean shouldRender3DInInventory() {
	return true;
}

@Override
public int getRenderId() {
	return 0;
}

    public Icon getBlockIconFromSide(Block par1Block, int par2) {
        return this.getIconSafe(par1Block.getBlockTextureFromSide(par2));
    }
    
    public Icon getIconSafe(Icon par1Icon) {
        if (par1Icon == null) {
            par1Icon = ((TextureMap)Minecraft.getMinecraft().func_110434_K().func_110581_b(TextureMap.field_110575_b)).func_110572_b("missingno");
        }

        return (Icon)par1Icon;
    }

@SideOnly(Side.CLIENT)
public boolean RenderShortRamp(Block block, int x, int y, int z, RenderBlocks render) {
        Icon icon = this.getBlockIconFromSide(block, 0);
        
        if (render.hasOverrideBlockTexture()) {
        	icon = render.overrideBlockTexture;
        }
        
        GL11.glPushMatrix();
        Minecraft.getMinecraft().renderEngine.func_110577_a(texture);
        GL11.glPopMatrix();
        
        tes.addVertexWithUV(0, 0, 0, 0, 0);
        tes.addVertexWithUV(0, 1, 0, 0, 1);
        tes.addVertexWithUV(1, 1, 0, 1, 1);
        tes.addVertexWithUV(1, 0, 0, 1, 0);

        tes.addVertexWithUV(0, 0, 0, 0, 0);
        tes.addVertexWithUV(1, 0, 0, 0, 1);
        tes.addVertexWithUV(1, 1, 0, 1, 1);
        tes.addVertexWithUV(0, 1, 0, 1, 0);

	return true;
}
}

 

Did I do something wrong somewhere? :P

width=463 height=200

http://s13.postimg.org/z9mlly2av/siglogo.png[/img]

My mods (Links coming soon)

Cities | Roads | Remula | SilvaniaMod | MoreStats

Link to comment
Share on other sites

GL11.glPushMatrix();

Minecraft.getMinecraft().renderEngine.func_110577_a(texture);

GL11.glPopMatrix();

ahahahah no meant ALL the render code

 

public void renderInventoryBlock(Block block, int metadata, int modelID, RenderBlocks renderblocks) 
{
    GL11.glPushMatrix();
    //code you already have
    GL11.glPopMatrix();
}

 

mc renders in bulk. it doesn't render per block per chunk. it goes through each block in the chunk and adds the vertices but doesn't render them. once it's done with each block, that's when it renders everything. and since they're rendered in bulk, when you change the texture being used, you change it for every block in the chunk. so you're either gonna have to use icons to include your textures in the terrain texture (can icons be larger than 16x16? still gonna test it out later) or do what hydroflame suggested (but you'll have to figure out a way around the problem).. or something else. i dunno. i vote icons if they work

now if thats true it means that there is a seeeeeeeeeeeeeeeerious problem with mc render engine !

and it also mean that ISBRH is way usefull then i tought

sorry for not being that much help, i usually use TESR becasue you can add animation to it :\

 

 

but basicly considering what pelep said, it is worth to note that the calls to startDrawingQuads and draw() should probably not appear in a ISBRH

how to debug 101:http://www.minecraftforge.net/wiki/Debug_101

-hydroflame, author of the forge revolution-

Link to comment
Share on other sites

I still get the same issue even when trying that.

 

Do you have a TESR tutorial? I always thought that was just another name for the tessellator, but from what you're saying it's both different and might be better, especially as I'll be animating some of these blocks.

width=463 height=200

http://s13.postimg.org/z9mlly2av/siglogo.png[/img]

My mods (Links coming soon)

Cities | Roads | Remula | SilvaniaMod | MoreStats

Link to comment
Share on other sites

you mean TESR == ISBRH ? or  TESR == tessellator ?

becasue TESR and ISBRH are kindof similar except the TESR gets called every frame while the ISBRH gets called ... every ... 50 tick ? more ?

 

so animation is NOT possible with the ISBRH (which is  why i kinda hate it :\ but i understand its purpose, aka rendering things like cactus)

 

and yes i made a tutorial on TESR, just look on our wiki for "TESR" or "Tile entity special renderer"

actually heres the link :

http://www.minecraftforge.net/wiki/TESR

 

how to debug 101:http://www.minecraftforge.net/wiki/Debug_101

-hydroflame, author of the forge revolution-

Link to comment
Share on other sites

Alright, I do still need to use the tessellator then. The main reason for this is that I want to avoid Tile Entites.

 

Do you have a working class using the tessellator I can look at? Maybe I can figure out my issue by comparing them and seeing what is different?

 

(Sorry for the late reply, I was out over the weekend)

width=463 height=200

http://s13.postimg.org/z9mlly2av/siglogo.png[/img]

My mods (Links coming soon)

Cities | Roads | Remula | SilvaniaMod | MoreStats

Link to comment
Share on other sites

The main reason for this is that I want to avoid Tile Entites.

why ? TE are awesome, as long as you dont have 20 000 of them per chunk

Do you have a working class using the tessellator I can look at?

yessir

 

heres my teleporter (it include a wavefront model btw)

 

public class RenderTeleporter extends TileEntitySpecialRenderer{
private IModelCustom teleporter;
private ResourceLocation texture = new ResourceLocation(TheMod.modid, "/models/textures/teleporter.png");
private float[] pos;
int displayList = -1;//unused for now

public RenderTeleporter(){
	teleporter = AdvancedModelLoader.loadModel("/teleporter.obj");
	pos = new float[30];
	for(int i = 0; i < pos.length; i++){
		pos[i] = (float) Math.random()*2;
	}
}

@Override
public void renderTileEntityAt(TileEntity tileentity, double d0, double d1,
		double d2, float f) {


	//here
	for(int i =0; i < pos.length; i++){
	}
	float size = 0.1f;
	Tessellator tess = Tessellator.instance;
	for(int i = 0; i < pos.length; i++){
		pos[i]+=0.01f;
		if(pos[i] > 2){ 
			pos[i] = 0;
		}
	}
	Minecraft.getMinecraft().renderEngine.func_110577_a(ForgeRevCommonProxy.portalParticle);
	GL11.glPushMatrix();
	GL11.glTranslated(d0+0.5, d1+1, d2+0.5);
	for(int i = 0; i < pos.length; i++){
		GL11.glRotated(360/pos.length, 0, 1, 0);
		GL11.glPushMatrix();
		GL11.glTranslated(0, pos[i], 1);
		tess.startDrawingQuads();
		tess.addVertexWithUV(-size, -size, 0, 0, 0);
		tess.addVertexWithUV(-size, size, 0, 0, 1);
		tess.addVertexWithUV(size, size, 0, 1, 1);
		tess.addVertexWithUV(size, -size, 0, 1, 0);

		tess.addVertexWithUV(-size, -size, 0, 0, 0);
		tess.addVertexWithUV(size, -size, 0, 1, 0);
		tess.addVertexWithUV(size, size, 0, 1, 1);
		tess.addVertexWithUV(-size, size, 0, 0, 1);
		tess.draw();
		GL11.glPopMatrix();
	}
	GL11.glPopMatrix();
	GL11.glColor3f(1, 1, 1);
	Minecraft.getMinecraft().renderEngine.func_110577_a(texture);
	GL11.glPushMatrix();
	GL11.glTranslated(d0+0.5, d1+1, d2+0.5);
	GL11.glScaled(1.3, 1.3, 1.3);
	Tessellator.instance.setColorOpaque_F(1, 1, 1);
	teleporter.renderAll();
	Minecraft.getMinecraft().renderEngine.func_110577_a(ForgeRevCommonProxy.portalRune);
	GL11.glTranslated(0, 0.2, 0);
	GL11.glRotated(System.nanoTime()/100000000f, 0, 1, 0);
	tess.startDrawingQuads();
	tess.addVertexWithUV(-0.5, 0, -0.5, 0, 0);
	tess.addVertexWithUV(-0.5, 0, 0.5, 0, 1);
	tess.addVertexWithUV(0.5, 0, 0.5, 1, 1);
	tess.addVertexWithUV(0.5, 0, -0.5, 1, 0);
	tess.draw();
	GL11.glPopMatrix();

}
}

 

 

EDIT:

a video of what this code does :

 

how to debug 101:http://www.minecraftforge.net/wiki/Debug_101

-hydroflame, author of the forge revolution-

Link to comment
Share on other sites

mc renders in bulk. it doesn't render per block per chunk. it goes through each block in the chunk and adds the vertices but doesn't render them. once it's done with each block, that's when it renders everything. and since they're rendered in bulk, when you change the texture being used, you change it for every block in the chunk. so you're either gonna have to use icons to include your textures in the terrain texture (can icons be larger than 16x16? still gonna test it out later) or do what hydroflame suggested (but you'll have to figure out a way around the problem).. or something else. i dunno. i vote icons if they work

now if thats true it means that there is a seeeeeeeeeeeeeeeerious problem with mc render engine !

and it also mean that ISBRH is way usefull then i tought

sorry for not being that much help, i usually use TESR becasue you can add animation to it :\

 

 

but basicly considering what pelep said, it is worth to note that the calls to startDrawingQuads and draw() should probably not appear in a ISBRH

I can confirm this problem  :( Sadly.

Link to comment
Share on other sites

The main reason for this is that I want to avoid Tile Entites.

why ? TE are awesome, as long as you dont have 20 000 of them per chunk

 

Honestly, thats exactly what I'm trying to achieve. My mod adds decorative things which people will literally have hundreds of in a single chunk. We tried doing some basic building and it was apparent very quickly that using Tile Entites it simply isn't gonna end well.

 

yessir

 

heres my teleporter (it include a wavefront model btw)

 

public class RenderTeleporter extends TileEntitySpecialRenderer{
private IModelCustom teleporter;
private ResourceLocation texture = new ResourceLocation(TheMod.modid, "/models/textures/teleporter.png");
private float[] pos;
int displayList = -1;//unused for now

public RenderTeleporter(){
	teleporter = AdvancedModelLoader.loadModel("/teleporter.obj");
	pos = new float[30];
	for(int i = 0; i < pos.length; i++){
		pos[i] = (float) Math.random()*2;
	}
}

@Override
public void renderTileEntityAt(TileEntity tileentity, double d0, double d1,
		double d2, float f) {


	//here
	for(int i =0; i < pos.length; i++){
	}
	float size = 0.1f;
	Tessellator tess = Tessellator.instance;
	for(int i = 0; i < pos.length; i++){
		pos[i]+=0.01f;
		if(pos[i] > 2){ 
			pos[i] = 0;
		}
	}
	Minecraft.getMinecraft().renderEngine.func_110577_a(ForgeRevCommonProxy.portalParticle);
	GL11.glPushMatrix();
	GL11.glTranslated(d0+0.5, d1+1, d2+0.5);
	for(int i = 0; i < pos.length; i++){
		GL11.glRotated(360/pos.length, 0, 1, 0);
		GL11.glPushMatrix();
		GL11.glTranslated(0, pos[i], 1);
		tess.startDrawingQuads();
		tess.addVertexWithUV(-size, -size, 0, 0, 0);
		tess.addVertexWithUV(-size, size, 0, 0, 1);
		tess.addVertexWithUV(size, size, 0, 1, 1);
		tess.addVertexWithUV(size, -size, 0, 1, 0);

		tess.addVertexWithUV(-size, -size, 0, 0, 0);
		tess.addVertexWithUV(size, -size, 0, 1, 0);
		tess.addVertexWithUV(size, size, 0, 1, 1);
		tess.addVertexWithUV(-size, size, 0, 0, 1);
		tess.draw();
		GL11.glPopMatrix();
	}
	GL11.glPopMatrix();
	GL11.glColor3f(1, 1, 1);
	Minecraft.getMinecraft().renderEngine.func_110577_a(texture);
	GL11.glPushMatrix();
	GL11.glTranslated(d0+0.5, d1+1, d2+0.5);
	GL11.glScaled(1.3, 1.3, 1.3);
	Tessellator.instance.setColorOpaque_F(1, 1, 1);
	teleporter.renderAll();
	Minecraft.getMinecraft().renderEngine.func_110577_a(ForgeRevCommonProxy.portalRune);
	GL11.glTranslated(0, 0.2, 0);
	GL11.glRotated(System.nanoTime()/100000000f, 0, 1, 0);
	tess.startDrawingQuads();
	tess.addVertexWithUV(-0.5, 0, -0.5, 0, 0);
	tess.addVertexWithUV(-0.5, 0, 0.5, 0, 1);
	tess.addVertexWithUV(0.5, 0, 0.5, 1, 1);
	tess.addVertexWithUV(0.5, 0, -0.5, 1, 0);
	tess.draw();
	GL11.glPopMatrix();

}
}

 

So will the tessellator code there work in an ISBRH? As I said above, any blocks I don't need a TE for I'd really rather not use one.

width=463 height=200

http://s13.postimg.org/z9mlly2av/siglogo.png[/img]

My mods (Links coming soon)

Cities | Roads | Remula | SilvaniaMod | MoreStats

Link to comment
Share on other sites

Even when using your tessellator code, I still get the same issue.

 

What did pelep and gotolink mean with the icon thing by the way? Maybe that's the issue I'm having. I'm starting to think what I'm trying to do isn't possible for a normal mod... I can't think of any other mods which do it either.

width=463 height=200

http://s13.postimg.org/z9mlly2av/siglogo.png[/img]

My mods (Links coming soon)

Cities | Roads | Remula | SilvaniaMod | MoreStats

Link to comment
Share on other sites

nope it is, you just fucked up somewhere

you should try to start with smaller code

like draw 1 quad, then add more

what you're asking is tottally possible, you can draw ANYTHING inside ISBRH except if you want animation :)

how to debug 101:http://www.minecraftforge.net/wiki/Debug_101

-hydroflame, author of the forge revolution-

Link to comment
Share on other sites

Even when using your tessellator code, I still get the same issue.

 

What did pelep and gotolink mean with the icon thing by the way? Maybe that's the issue I'm having. I'm starting to think what I'm trying to do isn't possible for a normal mod... I can't think of any other mods which do it either.

 

well, like i said, changing the texture there will change it for all the blocks in the chunk. and since your texture is black, you're effectively "plunging your world into darkness". and it's possible, i just did it. regarding icons, did you take a look at the methods i mentioned above? because you can learn how to use them from there.

Link to comment
Share on other sites

@pelep, well that or start with a call to draw(), change texture to the one you need, startDrawing(), bunch of addVertexWithUV, draw(), rechange back to vanilla texture, startDrawingQuads() to resetup for vanilla drawing.

 

i dont know what are the implication of that btw, so test with care

how to debug 101:http://www.minecraftforge.net/wiki/Debug_101

-hydroflame, author of the forge revolution-

Link to comment
Share on other sites

@pelep, well that or start with a call to draw(), change texture to the one you need, startDrawing(), bunch of addVertexWithUV, draw(), rechange back to vanilla texture, startDrawingQuads() to resetup for vanilla drawing.

 

yeah, but draw() returns an int which is used by MC afterward. according to the comments, it gets sent to the gpu. and i honestly don't know enough about how to handle gpu/hardware related stuff, so i decided not to mess with it and opted to use icons instead :)

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Unfortunately, your content contains terms that we do not allow. Please edit your content to remove the highlighted words below.
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.




  • Recently Browsing

    • No registered users viewing this page.
  • Posts

    • I'm developing a dimension, but it's kinda resource intensive so some times during player teleporting it lags behind making the player phase down into the void, so im trying to implement some kind of pregeneration to force the game loading a small set of chunks in the are the player will teleport to. Some of the things i've tried like using ServerLevel and ServerChunkCache methods like getChunk() dont actually trigger chunk generation if the chunk isn't already on persistent storage (already generated) or placing tickets, but that doesn't work either. Ideally i should be able to check when the task has ended too. I've peeked around some pregen engines, but they're too complex for my current understanding of the system of which I have just a basic understanding (how ServerLevel ,ServerChunkCache  and ChunkMap work) of. Any tips or other classes I should be looking into to understand how to do this correctly?
    • https://mclo.gs/4UC49Ao
    • Way back in the Forge 1.17 days, work started for adding JPMS (Java Platform Module Support) to ModLauncher and ForgeModLoader. This has been used internally by Forge and some libraries for a while now, but mods (those with mods.toml specifically) have not been able to take advantage of it. As of Forge 1.21.1 and 1.21.3, this is now possible!   What is JPMS and what does it mean for modders? JPMS is the Java Platform Module System, introduced in Java 9. It allows you to define modules, which are collections of packages and resources that can be exported or hidden from other modules. This allows for much more fine-tuned control over visibility, cleaner syntax for service declarations and support for sealed types across packages. For example, you might have a mod with a module called `com.example.mod` that exports `com.example.mod.api` and `com.example.mod.impl` to other mods, but hides `com.example.mod.internal` from them. This would allow you to have a clean API for other mods to use, while keeping your internal implementation details hidden from IDE hints, helping prevent accidental usage of internals that might break without prior notice. This is particularly useful if you'd like to use public records with module-private constructors or partially module-private record components, as you can create a sealed interface that only your record implements, having the interface be exported and the record hidden. It's also nice for declaring and using services, as you'll get compile-time errors from the Java compiler for typos and the like, rather than deferring to runtime errors. In more advanced cases, you can also have public methods that are only accessible to specific other modules -- handy if you want internal interactions between multiple of your own mods.   How do I bypass it? We understand there may be drama in implementing a system that prevents mods from accessing each other's internals when necessary (like when a mod is abandoned or you need to fix a compat issue) -- after all, we are already modding a game that doesn't have explicit support for Java mods yet. We have already thought of this and are offering APIs from day one to selectively bypass module restrictions. Let me be clear: Forge mods are not required to use JPMS. If you don't want to use it, you don't have to. The default behaviour is to have fully open, fully exported automatic modules. In Java, you can use the `Add-Opens` and `Add-Exports` manifest attributes to selectively bypass module restrictions of other mods at launch time, and we've added explicit support for these when loading your Forge mods. At compile-time, you can use existing solutions such as the extra-java-module-info Gradle plugin to deal with non-modular dependencies and add extra opens and exports to other modules. Here's an example on how to make the internal package `com.example.examplemod.internal` open to your mod in your build.gradle: tasks.named('jar', Jar) { manifest { attributes([ 'Add-Opens' : 'com.example.examplemod/com.example.examplemod.internal' 'Specification-Title' : mod_id, 'Specification-Vendor' : mod_authors // (...) ]) } } With the above in your mod's jar manifest, you can now reflectively access the classes inside that internal package. Multiple entries are separated with a space, as per Java's official spec. You can also use Add-Exports to directly call without reflection, however you'd need to use the Gradle plugin mentioned earlier to be able to compile. The syntax for Add-Exports is the same as Add-Opens, and instructions for the compile-time step with the Gradle plugin are detailed later in this post. Remember to prefer the opens and exports keywords inside module-info.java for sources you control. The Add-Opens/Add-Exports attributes are only intended for forcing open other mods.   What else is new with module support? Previously, the runtime module name was always forced to the first mod ID in your `mods.toml` file and all packages were forced fully open and exported. Module names are now distinguished from mod IDs, meaning the module name in your module-info.java can be different from the mod ID in your `mods.toml`. This allows you to have a more descriptive module name that doesn't have to be the same as your mod ID, however we strongly recommend including your mod ID as part of your module name to aid troubleshooting. The `Automatic-Module-Name` manifest attribute is now also honoured, allowing you to specify a module name for your mod without needing to create a `module-info.java` file. This is particularly useful for mods that don't care about JPMS features but want to have a more descriptive module name and easier integration with other mods that do use JPMS.   How do I use it? The first step is to create a `module-info.java` file in your mod's source directory. This file should be in the same package as your main mod class, and should look something like this: open module com.example.examplemod { requires net.minecraftforge.eventbus; requires net.minecraftforge.fmlcore; requires net.minecraftforge.forge; requires net.minecraftforge.javafmlmod; requires net.minecraftforge.mergetool.api; requires org.slf4j; requires logging; } For now, we're leaving the whole module open to reflection, which is a good starting point. When we know we want to close something off, we can remove the open modifier from the module and open or export individual packages instead. Remember that you need to be open to Forge (module name net.minecraftforge.forge), otherwise it can't call your mod's constructor. Next is fixing modules in Gradle. While Forge and Java support modules properly, Gradle does not put automatic modules on the module path by default, meaning that the logging module (from com.mojang:logging) is not found. To fix this, add the Gradle plugin and add a compile-time module definition for that Mojang library: plugins { // (...) id 'org.gradlex.extra-java-module-info' version "1.9" } // (...) extraJavaModuleInfo { failOnMissingModuleInfo = false automaticModule("com.mojang:logging", "logging") } The automatic module override specified in your build.gradle should match the runtime one to avoid errors. You can do the same for any library or mod dependency that is missing either a module-info or explicit Automatic-Module-Name, however be aware that you may need to update your mod once said library adds one. That's all you need to get started with module support in your mods. You can learn more about modules and how to use them at dev.java.
    • Faire la mise à jour grâce à ce lien m'a aider personnellement, merci à @Paint_Ninja. https://www.amd.com/en/support 
    • When I came across the 'Exit Code: I got a 1 error in my Minecraft mods, so I decided to figure out what was wrong. First, I took a look at the logs. In the mods folder (usually where you'd find logs or crash reports), I found the latest.log file or the corresponding crash report. I read it through carefully, looking for any lines with errors or warnings. Then I checked the Minecraft Forge support site, where you can often find info on what causes errors and how to fix them. I then disabled half of my mods and tried running the game. If the error disappeared, it meant that the problem was with the disabled mod. I repeated this several times to find the problem mod.
  • Topics

×
×
  • Create New...

Important Information

By using this site, you agree to our Terms of Use.