Jump to content


  • Posts

  • Joined

  • Last visited

Everything posted by Elix_x

  1. But getExtendedState is called on the same thread, and right before getQuads... So, would it not change anything?
  2. I understand that concurrency is an issue that can occur at any time. But what's the other way of passing required information to the model? You could compile everything you need into immutable objects to be passed, and that work on that in tessellation, but that creates compilation (+decompilation) overhead.
  3. Hmmm.... Doesn't look like this thread exists anymore. It seems like it was long ago enough for it to vanish somewhere... And me to forget what exactly was it about.
  4. Yep, you have to declare them in block class to make MC know about them, and actually provide/update them. FYI: This is similar for saved, actual and extended props. The declaration of all 3 is in createBlockState, saved props are handled by meta<->state methods, actuals by getActualState and extended - by getExtendedState. The difference between actual and extended, is that actual is used on server and client, has a limited number of serializeable values it can take and can be used in state mapping (~json model). Extended state is used only on client, can take any values of any type, and cannot be used for state mapping - aka only custom IBaked models. FYI 2: Actually, if you can create a single unlisted property for tile entity and pass it directly, instead of world and position. I'm just using 2 separate props, because i'm using them for other blocks too, which don't always have a tile entity, or i simply don't need it.
  5. If you won't be animating, use custom IBakedModel. If you do want to animate, as Draco said, use Fast TESR. By creating custom implementation of IBakedModel, you can override getQuads. In order to provide tile's data to get quads, pass unlisted properties from your block to model (override unlisted prop methods in your block class). getQuads is called each time model is drawn (item / in-world render update). So, in there, get baked models for all your parts, stream all the quads transforming accordingly, collect into a list and that list (considering your frame is rather a non-full block, you should do it only when side arg is null - side arg is for adjacency culling - ). Example (might be too many files to all link here) : IBaked, Helper, Uses client baked lib and client baked pipeline (and here), Model reg manager for using loaded & mapped json/obj/baked models for custom stuff, and a lot more...
  6. Just as Draco said, you have to translate the lid such that it's origin is world origin, rotate, then translate it back. Notice GlStateManager.translate(x, y, z) in the beginning of the method. This method translates tile entity in the world view space. Now the origin (0,0,0) is "actually" the XYZ of the tile entity, AKA you're working in local coordinates - coordinates relative to the origin of tile/model. So you have to translate the lid by it's local model coordinates to local origin and back. Ex: GL.trans(-lidModelCoords).rot(rot).trans(lidModelCoords).
  7. This is the definition of matrices. Understanding matrices will definitely help you solve this. I recommend watching this: Linear transformations and matrices | Essence of linear algebra, chapter 3* As for how to rotate around an axis, in 3D, you can look at how utility method is implemented in JOML: https://github.com/JOML-CI/JOML/blob/c312304fefbe757e3d37cba866f5742b3448a85c/src/org/joml/Matrix4f.java#L11379 This is generic use case, but now i have to correct you. What you put in the "What is happening" is not correct. Because in both translation, rotation and scaling, coordinates do "the same" what the model does (it is actually the opposite - model does whatever you do to the coordinate system). That said, the transformations you apply further down in the stack, actually apply to the already transformed coordinates as a whole, so
  8. The texture UVs you have are actually the global UV coordinates on the texture atlas. So what you will need is figure out a way to access the texture atlas sprite that was used to bake the quad. In the sprite, you will find min & max global UV coordinates. Now just do some math, and apply the values. Note: if you're trying to reduce the resolution of the texture, you have to do it completely differently. As for manipulating quads data, you can't just do it on that raw data. Because quads for blocks and quads for items are in a different VertexFormat - the index defining each format element is different. You'll have unpack the quad first (into forge's UnpackedBakedQuad), then manipulate the more conveniently, but still not very, stored vertex data. Take a look at the VertexFormat class to see how it is constructed. PS: I have a library i use to unpack models, quads & vertices into Java friendly format (easy get&set operations). If you want, you can check it out here.
  9. Considering above, there is a way to render based on ticks, and it is used by Vanilla entities, chests, etc... Very often in the render/draw method, you get a float parameter partialTick. It is between 0 and 1 and it represents how much in-between 2 ticks the current frame is. Use it to interpolate between previous and next tick and you get smooth transitions / animations.
  10. Registry events work as any other Forge event - you subscribe it to the event bus, and that's it. Forge will call it when stuff will be registered.
  11. When stencils don't work for me right away, i usually enable the color write and draw the stencil'ed region with colors, then i go into debug mode and play with it until i get it to work.
  12. Make sure that you enabled (created) stencil buffer. By default, MC does not create one. Alternatively, because you're in 2D, use scissors.
  13. First, ICustomModelLoader has nothing to do with this. Custom IBakedModels should be replaced in the registry in the ModelBake event. Second, to provide data to custom unbaked you can use IUnlistedProperties. Just like block has properties, it also has unlisted properties. While normal properties are both server and client, can be use for logic and require fixed amount of allowed values, unlisted properties are only used for rendering and can hold absolutely any values (even Worlds!). You have to implement (similarly named methods) getUnlistedState&Container in the block class and cast IBlockState to unlisted state container (don't remember exact class name, sorry) to be able to retrieve unlisted properties.
  14. o_0 So... which one? WorldSavedData is not a correct place to store per chunk data. You have access to chunk NBT in both chunk load a save events for a reason ;). Did you know, that vanilla already has a ChunkPos class? Also, hash maps won't work if you don't implement hashCode and equals (use your IDE to generate them).
  15. First, when i helped you previously i told you how to render these models without TESR. On top of that you told me you don't really like neither tile entities neither TESR. And now you are using TESR.. o_0 ? ? ? (Hint: it is using custom IBakedModel, which will also resolve current transparency issues). Second, i am pretty sure it has to do with the render pass. Try rendering it in pass 0 instead.
  16. Well, tile entities can even be as simple data storage things now. Not be used for ticking nor for rendering. Ok. I see now. I'd still personally prefer tiles for this, but at this point it does not matter much. Because java's native/default type is integer?
  17. 1. I forgot to mention - since 1.8, Tile Entity =/= Lag. Because since 1.8, tile entities can be not tickable (aka not require update). Just look at Chisel & Bits - the great example. 2. This way, you will never support all the blocks. Minecraft Forge is limited to 4096 block ids and 16 states/block... In 70% of modpacks, amount of used up block ids can be easily beyond 60%. You just can't create duplicate for every variation in the space that is left. 3. Just don't tell me you store your data in a block like this: public class CompressedBlock extends Block { public Block unCompressedVariant; }
  18. I did understand that you wanted to make support for all blocks, but i though that you have already set up the tile entity. Apparently you did not. Tile Entities can be used to store additional data with blocks that is not serializeable in 4 bytes of metadata. And it is what you want to use to store the original block (or even IBlockState ). Just implement load/save to NBT methods to make sure that it is saved (Block can be saved by saving its' registry name, simple/meta-serializeable IBlockStateby saving block and serializing it into metadata and complex/not-serializeable IBlockState can be saved by saving block and than a map of properties to serialized values). How to pass original block/state from tile to model? Implement Block#getUnlistedProperties (or similarly named method) - it allows to pass unlisted properties (properties that can store absolutely any values) to the IBaked. Now just create a (static) unlisted property holding original block/state and then in the method (you have both world and pos) retrieve tile, get original and store it in unlisted prop. Now in the IBaked, you can back the original by retrieving value of unlisted property from state you have as param. Getting model of the original: (i don't remember exact methods, so) Look through model classes - ModelLoader, ModelBakery. All models (items and blocks) should be cached there somewhere. Just find how to get to them. PS: Try using this method of quads "clamping". If there will be important FPS drops, i have an idea on how to make it a lot better. But it involves interaction with Open GL directly (without MC engine & wrappers) and a lot of infrastructure. So if it is not required, there's no need in implementing it.
  19. Use custom IBakedModel for your block. In the getQuads method, find model of the "original" block and retrieve its' quads. Now, just re-add these qauds applying necessary transforms as many times as you want. You can find the basics of applying transformation matrices to quads here: https://github.com/Elix-x/EXCore/blob/rendering--vertex-pipeline/src/main/java/code/elix_x/excore/utils/client/render/pipeline_old/MatVecApplicator.java#L52. And you probably also want to cache models to not recalculate quads each time (RIP FPS). I have a model cache here, it is free to use. Just register it as a reload listener and you're good to go.
  20. https://github.com/MightyPirates/OpenComputers#in-your-own-mod
  21. It would not make it incompatible with other mods. Just make sure to "save" GL state before you start rendering with shaders to restore it after. First, create custom shader helper class, that sets all uniforms, uploads shader, binds, etc... Now, if you want your shader to be customizable with resource packs, implement and register IResourceManagerReloadListener, in which you load/reload shaders. Otherwise, just upload it in post init. Now, when your TESR is called, bind your shader, render OBJ model and then unbind the shader. Seems easy? It isn't. For the rendering part, as i said previously, you can either change how you upload things to shader or how you shader reads things. The first option is easier. Just create all necessary classes using modern GL functions - Mesh, Matrix Handler, etc... For the mesh, it is recommended to use VAO with indexed position VBO and non-indexed texture & normal VBOs, because that's how OBJ model is encoded. Now you just have to write your own OBJ reader and compiler (which compiles it into a mesh). There are plenty of tutorials online on how to do this. Read, compile and upload your model into mesh either in resource reload listener or post init and render this mesh in TESR. Now just make sure that you inform users of your mod that at least GL3 support is required (all modern graphics cards support it, so no much worries). Note: Rendering performance can be improved very much, by binding shader once... But i'll let you think on how that can be done .
  22. Vanilla does not support custom shaders by itself (except ones activated when you spectate as a spider/creeper/enderman). So you have to use LWJGL and Open GL directly. But be ready to either completely change the way you draw model in-code or the way your shaders accept data. Because how vanilla MC pushes stuff to GL and how shaders normally work do not match at all.
  23. Because biomes use forge registries now (just like item and blocks), you can replace them using substitution aliases. First, read up on forge registries here - http://mcforge.readthedocs.io/en/latest/concepts/registries/. Now, to replace forest biome, register your own forest biome just like you would a new biome, then retrieve biome registry (either trough Biome or GameRegistry) and call #addSubstitutionAlias(String modid, ResourceLocation nameToReplace, Biome replacement).
  • Create New...

Important Information

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