OpenTK/C# - 2D text rendering works, how about 3D? - c#

Edit: Bad angle picture was due to Depth Testing. Still need the 'right' way to do 3d text rendering though!
I got 2D text rendering in OpenTK working. It's very simple, I use .NET Graphics class methods to draw a string to Bitmap, which I can load into GPU via OpenTK. Ok great, but how about 3D?
I'm thinking about this in terms of a cylinder. What is a cylinder? It's just a circle stretched out over a certain height. That's EXACTLY what I want to do here! I researched a bunch...but surprisingly there isn't all that much info readily available IMO for such a basic task.
Here's what I've tried:
1) Rendering the bitmap 100 times from Z = 0.0f to 1.0f. This actually works pretty well! For certain rotations anyway.
2) Drawing 16x16x16 Voxels (well, I think I'm drawing voxels). Basically the idea is, use the typical GL.TexCoord3 and GL.Vertex3 methods for drawing the SURFACE of a cube, but because we are drawing so freakin many of them, I figured it would actually give depth to my text. It sort of does, but the results are actually worse than attempt 1.
I want to get this working with a really simple solution, if one exists. I'm using Immediate mode, and if possible I'd like to keep using that.
This is what solution 1 looks like at a good angle:
Bad Angle:
I know that my method is inherently flawed because these bitmaps dont actually have a depth when I draw them, which is why at some critical angles either the text becomes flat looking, or disappears from view.

Related

Depth Buffer not working

In my XNA 3D game, for some reason, the depth buffer is off and ignored - even though I've done everything I can find to enable it (which admittedly isn't much, but it's supposed to be simple... not to mention default)
Before the models are rendered:
global.GraphicsDevice.DepthStencilState = DepthStencilState.Default;
Somewhere earlier:
graphics.PreferredDepthStencilFormat = DepthFormat.Depth24Stencil8;
graphics.ApplyChanges();
the models are rendered using a Vertex/Index list with device.DrawUserIndexedPrimitives and a BasicEffect.
It comes out like this:
The purple object is very far from the camera, and is drawn 1st.
The gray object is very near the camera, and is drawn 2nd.
The blue object is medium-distance to the camera and is drawn 3rd.
The gray object is rendering behind the blue object - that is correct if you're going off the draw order, but I want it to organize by distance from the camera (Using the depth buffer), in which case the gray object should draw in front of the blue object.
(And, no, just quickly sorting them manually, while it may provide a temporary solution, is not the way to fix this problem)
Update: This is directly related to the fact that I'm rendering onto a RenderTarget2D instead of straight onto the screen. (If I render on-screen instead of to the rendertarget, the depth is calculated correctly. The rendertarget is needed for other parts of the program... or an equivalent system.)
Well I found what I missed on my own after searching randomly:
A RenderTarget2D has its DepthBuffer disabled by default.
I just had to set the DepthFormat on the rendertarget I was drawing too.
Knew I missed something obvious...
(I'll green-check-mark-this in 4 hours when the site lets me.)
ED: that is, unless, in that time, somebody posts a nice list of everywhere XNA depth buffer data could/should be set, to better help people who might find this topic by google.

Making a lightsystem like Terraria?

I am trying to make my lighting similar to Terraria's, block-lighting. Now, I know how to make blocks darker, I can assign blocks to a certain lightlevel, but, how would I make an actual light entity, that emits light in a round shape (Can be diamond-shaped too)?
Help would be greatly appreciated, also, if I wasn't clear in my question, feel free to ask.
Basic 2D lighting is very simple. Just do a distance check from your block, to your light, and use that value to scale your light.
This is something you could do fairly simple, since Spritebatch.Draw has a nice Color tint parameter [link]
A pseudo function could be
distance = (block.position - light.position). Length();
lightPower = distance / light.MaxDistance;
finalTint = light.Color * lightPower;
Render Block, with finalTint
For more nice looking light, you could replace "distance / light.MaxDistance" with a more smooth effect.
If you also want lights to go through a few blocks like Terraria, you could count all blocks between your block and the light source. Scale your lightPower down by that amount, and you get the same effect like Terraria has.
Of course, this is a non optimized way of doing it, but should work.
The latest Terraria version however seems to have smooth per pixel lighting instead of per block [preview]. For that I assume they used a second render target and/or Pixel Shader to keep fast performance. This could be a little difficult if you are not familiar with rendering pipelines though.
Hope this helps!
I'm working on a game with a similar lighting model, and the way we do it is this:
Draw the scene, without lighting, to a render target (called the 'Scene Buffer')
Draw the scene's lights, represented as grayscale gradients of any required shape, to a second render target (called the 'Light Map')
Draw the Scene Buffer to the screen, passing in the Light Map as a parameter to the pixel shader
In the pixel shader, query the value of the Light Map at each pixel and adjust the color of the final pixel up or down as necessary.
This also gives you the ability to have colored lighting; all you have to do is tint the light gradients that you render to the Light Map. Just remember to use additive alpha blending.
The downside of this approach is that it's rather naive, and provides no easy way to occlude the lights (that is to say, they pass through walls). In our case, this isn't an issue; you might decide otherwise.

Incorrect Geometry When Enabling Alpha Blending

I have a test application with enabled transparency achieved through alpha blending. The application is built in C# using SlimDX. However, on one of my objects that has alpha blending applied, I am getting a strange 'missing triangle' effect (see below).
The object is almost a cylinder.
I wondered if anyone more experienced in 3D computer graphics and/or the use of alpha blending might be able to point me in the right direction so I might understand this result - and hopefully remove it.
EDIT
I have tried to use an order independent blending shader and I get the same result. It would appear as though the pixels/fragments are being discarded due to failing the depth test. This does not make any sense to me.
You need to select a blending function that is order independent or try to sort you triangles along the view axis (which is impossible). See why here.
EDIT:
The problem is that the Z buffer prevents OpenGL from drawing pixels that are behind things that have already been drawn. Generally, that's pretty convenient, but when the thing in front is translucent, you need to see the things that are behind it.
To get a correct looking geometry:
Put your depth buffer to read only mode.
Select an order independent blending function.

List Coordinates of Pixels Inside a Triangle

I'm making a game in C# and XNA, and I was trying to come up with a method to render massive terrains without using a tremendous amount of memory or passing the poly limit hard-coded into XNA.
My solution so far is to create a massive heightmap, and that heightmap is loaded into memory at the beginning of the game in the initialization phase. Then, terrain is only generated nearest to the camera. This is accomplished by projecting a triangle whose vertex is the character and the other two endpoints extend to the sides of the character's viewing area. Then, all the pixels inside that triangle on the heightmap are rendered and drawn into the game, thus only rendering what is seen.
The problem is, I've successfully found (I think, can't test until I get terrain rendering) the three vertices of the triangle. Now I need to find a list of the coordinates for every single pixel inside that triangle - whole numbers only, because I just need a list of pixels to render.
I know it sounds a little confusing, so here's the gist of it:
I have an image, and I project a triangle onto that image. The only thing I know about that triangle are the three vertices. I need a list of the pixels inside that triangle.
I've been Googling around for maybe 20 minutes now, and I figured I midas well go ahead and post something here due to the fact that what I'm trying to do isn't all that common. If I find an answer, I'll be sure to post it here.
But until then, can anyone tell me how to accomplish this?
Edit: A formula, please. If you can provide a formula or algorithm, and an explanation, that would be just perfect.
Edit: I've posted a new question, as I've ditched this method of rendering large terrains. The question is here.
Start here:
http://mathworld.wolfram.com/TriangleInterior.html
One of the non-trivial problems, not mentioned there, that you have to deal with is the pixelization along the boundary.

.NET high level graphics library

I am programming various simulation tools in C#/.NET
What I am looking for is a high level visualization library; create a scene, with a camera with some standard controls, and render a few hunderd thousand spheres to it, or some wireframes. That kind of thing. If it takes more than one line to initialize a context, it deviates from my ideal.
Ive looked at slimDX, but its way lower level than im looking for (at least the documented parts, but I dont really care for any other). WPF perspective looked cool, but it seems targeted at static XAML defined scenes, and that doesnt really suit me either.
Basically, im looking for the kind of features languages like blitzbasic used to provide. Does that exist at all?
I'm also interested in this (as I'm also developing simulation tools) and ended up hacking together some stuff in XNA. It's definitely a lot more work than you've described, however. Note that anything you can do in WPF via XAML can also be done via code, as XAML is merely a representation of an object hierarchy and its relationships. I think that may be your best bet, though I don't have any metrics on what kind of performance you could expect with a few hundred thousand spheres (you're absolutely going to need some culling in that case and the culling itself may be expensive if you don't use optimizations like grid partitioning.)
EDIT: If you really need to support 100K entities and they can all be rendered as spheres, I would recommend that you bypass the 3d engine entirely and only use XNA for math. I would imagine an approach like the following:
Use XNA to set up Camera (View) and Perspective matrices. It has some handy Matrix static functions that make this easy.
Compute the Projection matrix and project all of your 'sphere' origin points to the viewing frustrum. This will give you X,Y screen coordinates and Z depth in the frustrum. You can either express this as 100K individual matrix multiplications or multiplication of the Projection matrix by a single 3 x 100K element matrix. In the former case, this is a great candidate for parallelism using the new .NET 4 Parallel functionality.
If you find that the 100K matrix multplications are a problem, you can reduce this significantly by performing culling of points before transformation if you know that only a small subset of them will be visible at a given time. For instance, you can invert the Projection matrix to find the bounds of your frustrum in your original space and create an axis-aligned bounding box for the frustrum. You can then exclude all points outside this box (simple comparison tests in X, Y and Z.) You only need to recompute this bounding box when the Projection matrix changes, so if it changes infrequently, this can be a reasonable optimization.
Once you have your transformed points, clip any outside the frustum (Z < 0, Z > maxDist, X<0, Y<0, X>width, Y>height). You can now render each point by drawing a filled circle, with its radius proportional to Z (Z=0 would have largest radius and Z=maxDist would probably fade to a single point.) If you want to provide a sense of shading/depth, you can render with a shaded brush to very loosely emulate lighting on spheres. This works because everything in your scene is a sphere and you're presumably not worried about things like shadows. All of this would be fairly easy to do in WPF (including the Shaded Brush), but be sure to use DrawingVisual classes and not framework elements. Also, you'll need to make sure you draw in the correct Z order, so it helps if you store the transformed points in a data structure that sorts as you add.
If you're still having performance problems, there are further optimizations you can pursue. For instance, if you know that only a subset of your points are moving, you can cache the transformed locations for the immobile points. It really depends on the nature of your data set and how it evolves.
Since your data set is so large, you might consider changing the way you visualize it. Instead of rendering 100K points, partition your working space into a volumetric grid and record the number (density) of points inside each grid cube. You can Project only the center of the grid and render it as a 'sphere' with some additional feedback (like color, opacity or brush texture) to indicate the point density. You can combine this technique with the traditional rendering approach, by rendering near points as 'spheres' and far points as 'cluster' objects with some brush patterning to match the density. One simple algorithm is to consider a bounding sphere around the camera; all points inside the sphere will be transformed normally; beyond the sphere, you will only render using the density grid.
Maybe the XNA Game studio is what you are looking for.
Also take a look at DirectX.
WPF perspective looked cool, but it seems targeted at static XAML defined scenes
Look again, WPF can be as dynamic as you will ever need.
You can write any WPF program, including 3D, totally without XAML.
Do you have to use C#/.Net or would MonoDevelop be good enough? I can recomend http://unity3d.com/ if you want a powerful 3D-engine.

Categories

Resources