What is the easiest way to give 2D texture in OpenGL (lwjgl) some kind of "Thickness". Of course i could get the border of the texture somehow and add Quads, orriented by the normal of the quad that the texture is drawn on, in the color of the adjacent texture pixel. But there has to be an easier way to do it.
Minecraft is using lwigl as well and there are the (new) 3D Items, that spin down on the ground and don't cause as much of a performance issue, as is if they were drawn of dozends of polygons. As well, when you hold an item in your hand, there is that kind of "stretched" Texture in depth, which also works with high resolution textures.
Does anyone know how that is done?
A 2D texture is always infinitely thin. If you want actual thickness (when you look edge onto it) you need geometry. In Minecraft things look blocky, because they've been modeled that way.
If you look at some angle and ignore the edges you can use parallax mapping to "fake" some depth in the texture. Or you can use a depth map and use a combination of tesselation shaders and vertex shaders to implement a displacement map, that generates geometry from the texture.
Related
I want to reduce draw calls on my isometric map implementation so I thought about combining multiple meshes and draw them in one go. I am currently creating a mesh from all tiles in a 8x8 "chunk". This means a mesh containing floors, walls and objects. These floors, walls and objects are just quads placed along the regular axis where Y is up. A rotated orthographic camera provides the isometric projection matrix. Most floors and walls fill up the full quad with an opaque texture but some, and most objects have alpha transparency like a window, broken floor or a chair object. I am building the "chunk" mesh by adding individual meshes to it, I do this in order of drawing back to front and bottom to top otherwise the combined chunk mesh is not properly rendered at all. I render all of the needed chunks also in the same order and this works great.
However the drawing problems start when I need to add additional objects "inside" these mesh chunks. For example a moving player which is also just a quad with a transparent texture. I need to be able to put him inside that chunk mesh, perhaps on a tile where he is in front of a wall and behind a window. If I would render the player prior to the chunk, it's transparent pixels would not show the chunk mesh. If I would render the player after the chunk the player would not be visible trough a transparent quad in the chunk. If this could be solved easily and not to expensive on the CPU/GPU that would be the solution to my question. However I am considering myself new to OpenGL so I do not know it's magic very well.
I can think of a view solutions to tackle this problem that do not involve OpenGL:
Dump the chunk mesh method and just draw back to front. I either need a more efficient way of drawing or don't allow to zoom out as much to reduce draw calls since this is a bottleneck.
Get rid of the quads with transparency and make them full 3D. I feel this should be a design choice and not a mandatory thing, besides that it would add a lot of additional work to creating all these assets. Now I just have a textures projected on a quad instead of fully UV'd models with individual textures.
Draw all transparent objects after the chunks in proper order. This feels kinda hacky and error prone since some objects need to go into that chunk mesh and some don't.
Only combine floors in a batch mesh. The floors are the biggest bottleneck, the bottom of the map has all floor tiles filled which are about 4000 draw calls when drawn individually, a big building uses a lot of floors too for each Z level. Walls and objects are drawn significantly less, probably just a couple hundred maximum all the way zoomed out. SO for each chunk draw all floors in one call and then each individual object, I'd reduce draw calls a lot by just combining the floors. When drawing walls and objects I have to check if there is a potential dynamic object to be rendered or just check if there are dynamic objects within the chunk and sort them with all the walls and objects before drawing them.
This is how I currently render.
Gdx.gl.glEnable(GL20.GL_DEPTH_TEST);
Gdx.gl.glEnable(GL20.GL_BLEND);
Gdx.gl.glBlendFunc(GL20.GL_SRC_ALPHA, GL20.GL_ONE_MINUS_SRC_ALPHA);
shader.begin();
shader.setUniformMatrix("u_worldView", cam.combined);
// If I draw the player before the chunk the transparency of the player would not render the chunk.
player.getMesh().render(shader, GL20.GL_TRIANGLES);
// Drawing the mesh chunk combines of floors, walls and objects of each tile within the chunk.
chunk.getCombinedMesh().render(shader, GL20.GL_TRIANGLES);
// If I draw the player after the chunk the player would not be drawn if it is behind a transparent mesh like a window or a tree.
player.getMesh().render(shader, GL20.GL_TRIANGLES);
shader.end();
So what are my options here? Can I fix this by using some magic tricks out of the OpenGL hat? Or do you have another suggestion to put on the list above? I am using LibGDX for my project.
Let's say I have a triangular face in 3d space, and I have the 3d coordinates of each vertex of this triangle, and would also have other information about the triangle(angles, lengths of sides, etc.). In Java, if I have the viewing screen and its information, how can I draw that plane, without using libraries like LWJGL, to that image, assuming I can properly project, accounting for perspective, any 3d point to that 2d image.
Would the best course of action just be to run a loop that draws each point on the plain to a point on the image(i.e. setting the corresponding pixel), which will most likely set the same pixel multiple times? If I'd do this, what would be the best way to identify each point in an oblique triangle, or a triangle that doesn't line up nicely with the axes?
tl;dr: I have a triangular face in 3d space, a "camera" looking at the face, and an image in which I can set each pixel. Using no GL libraries, what's the best way to project and draw that face onto the image?
Projection :
won't detail as you seems to know it
Drawing a line
you can look at Bresenham algorithm if you wanna start with the basics
(hardwared in recent graphics card)
Filling
you can fill between left and right borders of the triangle while you use Bresenham on both (you could use a floodfill algorithm starting ... i don't know, maybe at the projection of the center of the triangle)
Your best bet is to check out the g.fillPolygon() function for Java. It allows you to draw polygons with as many sides as possible and theres also g.drawPolygon() if you don't want it solid. Then you can just do some simple maths for the points. Such as each point is basically it's x and y except if the polygon is further away the points move closer to the center of the polygon and if the polygon is closer they move further away from the center of the polygon.
A second idea could be using some sort of array to store pixels and then researching line drawing algorithms and drawing lines then putting all the line data in another array and using some sort of flood-fill. Then whilst it's in that array you could try and do some weird stuff to the pixels if you wanted textures or something.
Im making a game and id like to implement raycasting for the hero's laser (and other stuff in the future), i have my sprites in a sprite sheet which i bind in the beggining and access when i draw since each element knows how to draw itself, but the spritesheet is a PNG, and thus some elements posess transparency, which works ok in openGL. i know each element's position, size etc but if some sprites have transparency, the position and size arent enough for the ray cast to be perfect since it would only hit the "bounding box". So is there a way to throw a ray using Bresenham algorithm (i believe it is the lightest way, correct me if im wrong) and make it pixel perfect in openGL, so that i can acquire the collision point of the ray with the actual non-transparent zone of the first sprite it appears in the way?
There is no easy way to do this. You would have to create a custom collision checker for your raycast to see if it would pass through or if it would collide with part of the sprite.
However it might be a better idea to use a smaller bounding box, or a circle to represent it, or both. These are much easier and faster to calculate then checking every pixel within the texture.
I am generating very large hex grids (up to 120k total hexes at 32px wide hexes results in over 12k wide images) and I'm trying to find an efficient way to bind these to OpenGL textures in libgdx. I was thinking of using multiple FBOs and breaking the grid up as necessary into tiles, but I'm not sure how to ensure continuity between the FBOs. I can't start with one massive FBO, because that is backed up by a texture so it would fail from trying to load it to video memory. I can't use a standard bitmap on the heap because I need the drawing functionality of an OpenGL surface.
So what I was thinking was I would need to overdraw on the FBOs and somehow pick up on the next FBO exactly where the previous left off. However I'm not sure how to go about this. I'm drawing the hex grid with a series of hexagonal meshes, FYI.
Of course, there's probably some other much simpler and more efficient way to do this that I'm not even thinking of, which is why I pose this question to you fine people!
You have to draw it in pieces. You need to be able to draw your hex grid from an arbitrary position. This means being able to compute which hexes to draw based on a rectangle overlaid over the map. This isn't a hard problem, and I wouldn't worry too much about drawing extra stuff off-screen. You should master this ability to view the hexmap from any position before moving on.
Once you've mastered that, it's really simple.
Draw the top-left corner and store the pixel data. Then move the area you're drawing over exactly one image width. Draw and store that. Move the area over one image width. Draw and store it. Keep doing that until you've covered the entire width.
Move down one image height and repeat the process. Once you've run out of width and height, you're done. Save your mega-huge image.
You don't need FBOs for this. You could draw it to the screen if you wanted. Though if you want maximum performance, I would suggest using FBOs, double buffering them, and using glReadPixels though a pixel buffer object. That should cut down a lot on latency.
I have been working on an isometric minecraft-esque game engine for a strategy game I plan on making. As you can see, it really needs some lighting. It is difficult to distinguish between separate elevations because everything is the same shade. So my question is: can I shade just a specific section of a sprite? All of those blocks are just sprites, so if I shaded the entire image, it would shade the whole block.
Well, it depends on how you do your lighting.
Basically, sprites are just textured quads made of two triangles.
Traditional vertex based lighting (which is supported by the built-in but now deprecated functions) will just calculate the lighting for the 4 corners of that quad and everything else will be interpolated. This is quite fast but might result in the wrong lighting - especially with spot lights and big quads.
If you use directional lighting only, you might apply a normal map to your quads and thus influence lighting in a per-texel way, but that might still not be what you want.
The modern way would be to use shaders, i.e. the lighting is evaluated per-pixel. You'd then have to provide per-texel lighting information for your quad which is then used in the fragment/pixel shader.
Just to clarify, the meanings of some terms in this context:
per-texel: per pixel in the texture, those value might be interpolated
per-pixel: per output pixel, i.e. per screen pixel
Edit:
I just looked at your screenshot and it seems you'll have to change the shade of sprite's edges if the adjacent sprite is not on the same level. Assuming you already know which sprite edge should be visible (i.e. there's a level change at that edge) you might just change the shading of the vertices that form that edge.
If you don't use any lighting, you might just start setting the vertex color to white and to some darker color for the vertices that need shading. Then multiply your texture color with the vertex color which should result in darker edges.
Alternatively, if those level have different depths (i.e. different z values) you could use some shader for edge detection (e.g. some SSAO implementation).
Edit 2:
If you use plain old vertex lighting, applying weighted normals might help. Basically you calculate the weighted vertex normals from the normals of those triangles that share a vertex.
There are several methods doing this, one being to weight the faces based on the angle at that vertex. You could multiply the normals by those angles, add then together and finally normalize the resulting normal.
The result of that calculation might be something like this (ASCII art):
| | /
|_______|________/
| / | |
|/______|_______|
Lines pointing up are the normals, the bottom lines would be your sprites in a side view.