Jump to content

Recommended Posts

Posted

Hello, here's the deal:

I am making a custom rendered model for a tile entity. Most parts of it are static and do not need changing, so that's simple. But one part has to change its texture depending on the state of the tile entity. Now, I want to make this as clean and efficient as possible, so I'm asking you, the people of Forge. The model class extends ModelBase and contains a few ModelRenderers. Four of them are static, and one has to have variable textures. Specifically, the Screen. Here is the code:

ModelRenderer Base;
ModelRenderer Controls;
ModelRenderer Body;
ModelRenderer Top;
ModelRenderer Screen;

public ModelArcadeGameTop() {
textureWidth = 64;
textureHeight = 64;

Base = new ModelRenderer(this, 0, 0);
Base.addBox(0F, 0F, 0F, 16, 2, 16);
Base.setRotationPoint(-8F, 22F, -8F);
Base.setTextureSize(64, 64);
Base.mirror = true;
setRotation(Base, 0F, 0F, 0F);

Controls = new ModelRenderer(this, 0, 41);
Controls.addBox(-8F, 0F, 0F, 16, 2, 7);
Controls.setRotationPoint(0F, 22F, -8F);
Controls.setTextureSize(64, 64);
Controls.mirror = true;
setRotation(Controls, 0.2792527F, 0F, 0F);

Body = new ModelRenderer(this, 0, 18);
Body.addBox(0F, 0F, 0F, 16, 13, 10);
Body.setRotationPoint(-8F, 9F, -2F);
Body.setTextureSize(64, 64);
Body.mirror = true;
setRotation(Body, 0F, 0F, 0F);

Top = new ModelRenderer(this, 0, 50);
Top.addBox(0F, 0F, 0F, 16, 1, 11);
Top.setRotationPoint(-8F, 8F, -3F);
Top.setTextureSize(64, 64);
Top.mirror = true;
setRotation(Top, 0F, 0F, 0F);


textureWidth = 32;
textureHeight = 32;

Screen = new ModelRenderer(this, 0, 0);
Screen.addBox(0F, 0F, 0F, 14, 10, 0);
Screen.setRotationPoint(-7F, 10F, -2F);
Screen.setTextureSize(32, 32);
Screen.mirror = true;
setRotation(Screen, 0F, 0F, 0F);
}

As you can see, I've initialized the texture offset for the Screen in the constructor of this ModelBase. It also has different texture size, because it uses a separate texture file to all the other parts.

 

I've come up with two options for changing the texture. The one above only intializes the Screen variable once, but requires more than one texture file for it, since the offset is already set here and I think it can't be changed (correct me if I'm wrong). So, I'd have to make a few ResourceLocations and then swap them in the renderer.

 

The second option would be to create a separate function for the rendering of this one part, like so:

public void renderScreen(int textXOffset, int textYOffset, int sizeX, int sizeY, int sizeZ, float offX, float offY, float offZ, float moveX, float moveY, float moveZ, float rotX, float rotY, float rotZ, int textWidth, int textHeight, float f)
{
textureWidth = textWidth;
textureHeight = textHeight;

Screen = new ModelRenderer(this, textXOffset, textYOffset);
Screen.addBox(offX, offY, offZ, sizeX, sizeY, sizeZ);
Screen.setRotationPoint(moveX, moveY, moveZ);
Screen.setTextureSize(textWidth, textHeight);
Screen.mirror = true;
setRotation(Screen, rotX, rotY, rotZ);
Screen.render(f);
}

However, this option creates a new ModelRenderer every time the model is rendered, so very, very often. On the other hand, it can be set so that there is one texture file, and a few options in it, and I can just change the offset of the Screen. Besides, both options seem kinda dirty, so maybe there is some kinda method for changing the texture offset in the file? So, I'm asking which option is better, and if there are any other ones. Thanks in advance.

Posted

I'd have to do some digging to be sure, but I don't know if method 1 will work.  Have you traced out how the models components use textureWidth/Height.  Is it a static grab or referenced later during the render process.  I'm betting its the latter.

 

If my guess is right, just make them all the same size.  You don't have to use the full 64x64.

 

As far as methods go, I would move where I bind the texture from the renderer class to the model class.

 

Follow a pattern of

1) bind texture

2) Render relevant model components

 

rinse and repeat.

 

There are a few other ways, but this is how I would do it(and have in the past).

 

In your model have everything the same texture size.  Have 4 'Screens' as you have named them. Identical in place, rotation, ect, except that they point to a different part of the texture file.  This way each version of your 'screen' has its own unique texture inside of one file.

 

During the render step, choose which of the 4 'screens' to render.  Very low processing load.  Tradeoff is you will have a bit larger of a model and texture file.

 

Long time Bukkit & Forge Programmer

Happy to try and help

Posted

Method 1 works, because I've already tested it, but I think I'll follow your advice and create a few Screens, each one pointing to a different place in the same texture file.

 

As to moving the texture binding methods into the model, look at my Renderer code. Shouldn't all this GL11 stuff stay in the Renderer?

@Override
public void renderTileEntityAt(TileEntity tileEntity, double x, double y, double z, float f1) {
int dir = tileEntity.getWorldObj().getBlockMetadata(tileEntity.xCoord, tileEntity.yCoord, tileEntity.zCoord);

GL11.glPushMatrix();
GL11.glTranslatef((float)x + 0.5F, (float)y + 1.5F, (float)z + 0.5F);
GL11.glRotatef(180.0F, 0.0F, 0.0F, 1.0F);
GL11.glRotatef(dir * 90.0F, 0.0F, 1.0F, 0.0F);

bindTexture(fileTexture);
modelArcadeGameTop.renderModel(0.0625F);

bindTexture(fileScreenTexture);
modelArcadeGameTop.Screen.render(0.0625F);
GL11.glPopMatrix();
}

Posted

Doesn't have to.  Typically if you are using a vanilla model or renderer, you need to make sure to follow the pattern.

 

If you have a custom render and a custom model, go nutz and do whatever.

 

What you have shown below though should work fine.

Long time Bukkit & Forge Programmer

Happy to try and help

Posted

And now it refuses to work. I have to use 7 different screen versions, so I decided I'll use an array instead of 7 variables, because they are the same. For some reason, Minecraft/GL hates arrays and crashes. Here's how the code looks. Model:

ModelRenderer base;
ModelRenderer controls;
ModelRenderer body;
ModelRenderer top;
ModelRenderer[] screens = new ModelRenderer[7];
ModelRenderer fff;
ModelRenderer fff2;

public ModelArcadeGameTop() {
	textureWidth = 64;
	textureHeight = 256;

	base = new ModelRenderer(this, 0, 0);
	base.addBox(0F, 0F, 0F, 16, 2, 16);
	base.setRotationPoint(-8F, 22F, -8F);
	base.setTextureSize(64, 256);
	base.mirror = true;
	setRotation(base, 0F, 0F, 0F);

	controls = new ModelRenderer(this, 0, 41);
	controls.addBox(-8F, 0F, 0F, 16, 2, 7);
	controls.setRotationPoint(0F, 22F, -8F);
	controls.setTextureSize(64, 256);
	controls.mirror = true;
	setRotation(controls, 0.2792527F, 0F, 0F);

	body = new ModelRenderer(this, 0, 18);
	body.addBox(0F, 0F, 0F, 16, 13, 10);
	body.setRotationPoint(-8F, 9F, -2F);
	body.setTextureSize(64, 256);
	body.mirror = true;
	setRotation(body, 0F, 0F, 0F);

	top = new ModelRenderer(this, 0, 50);
	top.addBox(0F, 0F, 0F, 16, 1, 11);
	top.setRotationPoint(-8F, 8F, -3F);
	top.setTextureSize(64, 256);
	top.mirror = true;
	setRotation(top, 0F, 0F, 0F);

	int textOffsetY = 66;
	for (ModelRenderer screen : screens) {
		screen = new ModelRenderer(this, 0, textOffsetY);
		screen.addBox(0F, 0F, 0F, 28, 20, 0);
		screen.setRotationPoint(-14F, 20F, -4F);
		screen.setTextureSize(64, 256);
		screen.mirror = true;
		setRotation(screen, 0F, 0F, 0F);
		textOffsetY += 21;
		System.out.println(screens.length);
	}

	fff = new ModelRenderer(this, 0, 66);
	fff.addBox(0F, 0F, 0F, 28, 20, 0);
	fff.setRotationPoint(-14F, 20F, -4F);
	fff.setTextureSize(64, 256);
	fff.mirror = true;
	setRotation(fff, 0F, 0F, 0F);

	fff2 = new ModelRenderer(this, 0, 87);
	fff2.addBox(0F, 0F, 0F, 28, 20, 0);
	fff2.setRotationPoint(-14F, 20F, -4F);
	fff2.setTextureSize(64, 256);
	fff2.mirror = true;
	setRotation(fff2, 0F, 0F, 0F);
}

Renderer:

@Override
public void renderTileEntityAt(TileEntity tileEntity, double x, double y, double z, float f1) {
	int dir = tileEntity.getWorldObj().getBlockMetadata(tileEntity.xCoord, tileEntity.yCoord, tileEntity.zCoord);

	GL11.glPushMatrix();
		GL11.glTranslatef((float)x + 0.5F, (float)y + 1.5F, (float)z + 0.5F);
		GL11.glRotatef(180.0F, 0.0F, 0.0F, 1.0F);
		GL11.glRotatef(dir * 90.0F, 0.0F, 1.0F, 0.0F);

		bindTexture(fileTexture);
		modelArcadeGameTop.renderModel(0.0625F);

		GL11.glScalef(0.5F, 0.5F, 0.5F);
		//modelArcadeGameTop.screens[2].render(0.0625F);
		modelArcadeGameTop.fff.render(0.0625F);
		modelArcadeGameTop.fff2.render(0.0625F);
	GL11.glPopMatrix();
}

fff and fff2 are just for testing. When I comment out the rendering call for the screens, everything works fine. However, when I try to access any of the 7 screens in the screens array and render it, the game crashes. Here's the log: https://gist.github.com/anonymous/53c149bc11bebe6f11dd, from line 183.What is up with this, and why won't it work?

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.

Announcements



  • Recently Browsing

    • No registered users viewing this page.
  • Posts

    • I've been using this modpack for a few days now with no issues, it was working properly just an hour or two ago and now all of a sudden when I try to load it I get this error: 'The game crashed: exception in server tick loop Error: com.google.gson.JsonSyntaxException: java.lang.IllegalStateException: Expected BEGIN_OBJECT but was STRING at line 1 column 1 path $' debug log: https://pastebin.com/1htBuhsP crash report: https://pastebin.com/QggHKYDg
    • Everything worked fine until I decided to install supplementaries squared, amendments and a couple other mods like artifacts, and compats for it. I'm having a hard time fixing this, and I get this crash whenever I try to enter a world. Not even a new world is feasible. Any help would be highly appreciated!! https://pastebin.com/7KXYZ6fM
    • Internal Exception: com.google.gson.JsonParseException: Error loading registry data: Unknown element: ResourceKey[minecraft:worldgen/configured_feature / minecraft:crimson_forest_vegetation]   This error is there when i try to join my friends server. We had some mods and it was okay but after 3 days i cant join.
    • It just says the mod i had but i dont have now.. and i didnt even use these mods and it still was crashing with the mods  
    • Hello,   I've been back and forth in emails with some CurseForge support staff on the issue but there's been no progress. In the CurseForge app, I have custom profiles and some public modpacks that will not load no matter what. I've goen through every link sent to me, I've reinstalled Minecraft, reinstalled the launcher, repaired the installations individually, uninstalled and reinstalled the public modpacks, downloaded the latest Java--all of it. But each time, I'm always met with either "java runtime exception", "exit code 1" on the rare occasions Minecraft does launch, or "java is out of date" (which literally cannot be possible since I reinstalled the latest version a few different times.) Making a new profile works, but I want to be able to play the ones I had before.  I had gotten one of the old public Minecraft modpacks to work, the prehistoric one about dinosaurs being featured right now, but then it only worked once. I've tried to retrace my steps and it just would not work. I have genuinely no clue what's going on.
  • Topics

×
×
  • Create New...

Important Information

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