I try to create an WPF Application with an integrated OpenGL visualization.
I found the sample project SharpGL it helped me to integrate the opengl code into my wpf program.
now I just want to draw a rectangle which has the following attributes:
40 x coordinates = columns
48 y coordinates = rows
Each (x,y) coordinate has a value which I have defined in an List<float>.
The List<float> is dynamically, so it will change all the time.
The goal is too show the values in real time in the drawed rectangle.
Like:
y-coord
x coord 0 2 0 3 7 0 1 ..40
4 5 3 0 6 0 5 ..40
. .
. .
48 48
Unfortunately I fail already when I try to draw the rectangle.
private void openGLControl_OpenGLDraw(object sender, OpenGLEventArgs args)
{
// Get the OpenGL object.
OpenGL gl = openGLControl.OpenGL;
// Clear the color and depth buffer.
gl.Clear(OpenGL.GL_COLOR_BUFFER_BIT);
// Load the identity matrix.
//gl.LoadIdentity();
gl.PolygonMode(FaceMode.FrontAndBack, PolygonMode.Filled);
gl.Color(0,0,0);
// Draw a coloured pyramid.
gl.Begin(OpenGL.GL_QUADS);
gl.Vertex(-1.0f, 1.0f);
gl.Color(200,1,1);
gl.Vertex(-1.0f, 0.0f);
gl.Color(200, 1, 1);
gl.Vertex(1.0f, 0.0f);
gl.Color(200, 1, 1);
gl.Vertex(1.0f, 1.0f);
gl.Color(200, 1, 1);
gl.End();
// Nudge the rotation.
//rotation += 3.0f;
}
My code shows just a black window.
How could I realize that?
Most likely you forgot to call gl.Flush() or gl.Finish() at the end of your openGLControl_OpenGLDraw() method. Until you call any of these methods (or gl.SwapBuffers() in case of double buffering) every drawing method you call will only be buffered but not executed.
Related
So there is a problem that whenever I use Physics.OverlapBox to check how many objects in that area exist it always output 0.
Here is my stripped down code:
void Update () {
a();
}
void a()
{
Collider[] c = Physics.OverlapBox(new Vector3(10, 10,10), new Vector3(-10, -10, -10));
Debug.Log(c.Length);
}
My scene setup:
A simple cube placed at position(0,0,0) with scale of (1,1,1)
An empty object where I attach this script
As you can see, my OverlapBox bounds are much bigger than my cube, so it should find my cube, right? Well, no. The output I get from the console is 0.
One more thing: if I set the scale of that cube to something higher than 40 in all axis, the script finally detects my cube and outputs 1.
How do I get this working so the script would find my cube with default scale?
I had this same issue. I was using TransformVector to calculate the size of my box:
Vector3 size = itemTransform.TransformVector(itemCollider.size / 2);
Collider[] results = Physics.OverlapBox(itemTransform.position, size);
The results weren't consistent. I realised that TransformVector was returning negative values for the size so I simply had to Mathf.Abs the Vector:
Vector3 size = itemTransform.TransformVector(itemCollider.size / 2);
size.x = Mathf.Abs(size.x);
size.y = Mathf.Abs(size.y);
size.z = Mathf.Abs(size.z);
Collider[] results = Physics.OverlapBox(itemTransform.position, size);
According to the documentation, you are setting the size of the overlapping box to -20, -20, -20, which is not quite logic. It could explain why you have to set the scale of your cube to something bigger than 40, 40, 40.
Also, Physics-related operations should be processed in the FixedUpdate function instead of the Update one
I have followed a SharpGL tutorial that can display a rotating block. Initially this only had default colors drawn on it with gl.Color(r, g, b). After this succeeded I tried to texture the cube with an uv map.
When I run the application fullscreen while only coloring the cube (with the sharpGL component covering the entire inside of the application) I get 70~80 fps only for displaying a colored cube. When I enable OpenGL.GL_TEXTURE_2D and draw the textures on a singular cube I get 8~9 fps.
Whenever a bitmap is loaded for use as a texture, it is stored in the memory. This drop in framerates only occurs after I enable OpenGL.GL_TEXTURE_2D and call gl.TexCoord(c1, c2) for all coordinates. Actually moving the object with gl.Rotate(angle, x, y, z) does not noticably affect performance.
The provided data for the method including GetBlockUv and CubeCoordinates are static float-arrays.
Is SharpGL supposed to perform this poorly (i.e. on displaying a singular cube) or is there another reason? Am I doing something wrong that is affecting performance? Is applying textures supposed to affect the performance like that?
The main draw Event happens in a Block:
public void DrawBlock(object sender, OpenGLEventArgs args)
{
// Get the OpenGL instance that's been passed to us.
OpenGL gl = args.OpenGL;
// Reset the modelview.
gl.LoadIdentity();
// Move the block to its location
gl.Translate(Coord.X, Coord.Y, Coord.Z);
gl.Rotate(angle, 1.0f, 1.0f, 0.5f);
angle += 3;
// retrieve the right texture for this block and bind it.
Texture blockTex = BlockTexture.GetBlockTexture(gl, _type);
blockTex.Bind(gl);
// retrieve the uv map for this block
float[] uv = BlockTexture.GetBlockUv(_type);
// retrieve the coordinates for a cube
float[] cube = CubeCoordinates();
gl.Enable(OpenGL.GL_TEXTURE_2D);
// Draw the cube with the bound texture.
gl.Begin(OpenGL.GL_QUADS);
//
//
// Begin by allowing all colors.
gl.Color(1.0f, 1.0f, 1.0f);
// since the uv index increments with 2 each time, we will be keeping track of this separately.
int uvInd = 0;
// i denotes the current coordinate. Each coordinate consists of 3
// values (x, y, z), thus letting us skip 3.
//
// Seeing as we are creating quads, it is expected that cube.Length
// is 3 * 4 * N (where n is a whole number)
for (int i = 0; i < cube.Length; i += 3)
{
// color experiment
//if (i < cube.Length / 3)
//{
// gl.Color(1.0f, 0.00f, 0.00f);
//}
//else if (i < 2 * (cube.Length / 3))
//{
// gl.Color(0.0f, 1.0f, 0.0f);
//}
//else
//{
// gl.Color(0.0f, 0.0f, 1.0f);
//}
try
{
// set the coordinate for the texture
gl.TexCoord(uv[uvInd], uv[uvInd + 1]);
// set the vertex
gl.Vertex(cube[i], cube[i + 1], cube[i + 2]);
}
catch (IndexOutOfRangeException e)
{
throw new IndexOutOfRangeException(
"This exception is thrown because the cube map and uv map do not match size");
}
// increment the uv index
uvInd += 2;
}
gl.End();
gl.Disable(OpenGL.GL_TEXTURE_2D);
}
OpenGL is initialized elsewhere
private void OpenGLControl_OpenGLDraw(object sender, OpenGLEventArgs args)
{
// Get the OpenGL instance that's been passed to us.
OpenGL gl = args.OpenGL;
// Clear the color and depth buffers.
gl.Clear(OpenGL.GL_COLOR_BUFFER_BIT | OpenGL.GL_DEPTH_BUFFER_BIT);
// call the draw method of the GameRunner if the
// GameRunner has already been created.
game?.DrawOpenGL(sender, args);
// Flush OpenGL.
gl.Flush();
}
private void OpenGLControl_OpenGLInitialized(object sender, OpenGLEventArgs args)
{
// Enable the OpenGL depth testing functionality.
args.OpenGL.Enable(OpenGL.GL_DEPTH_TEST);
}
All the intermediate GameRunner does right now is call the DrawBlock routine.
What I mainly would want to know is some insight into the performance I can expect of openGL / sharpGL and whether there are better alternatives. I would like to keep using the WPF architecture surrounding the game, but if openGL inside WPF is more meant as a gimmick, that might not be the best course of action.
I've been having the exact same issue, and it seems to be the case that either SharpGL or the WPF control itself are using software rendering. I tested this by disabling my main display adapter in Device Manager and got the exact same performance as I did with it enabled.
I don't know how to enable hardware acceleration though, so I don't actually know how to fix the issue.
First off I have looked around and I can see many posts about this and they all point towards the Z position of the text, however I have changed this to minus and positive and my text is always drawn behind my GUITexture.
So this is what I have setup
My GUI has 4 text boxes
Score
Lives
Level
Time
Now I have an object called GameManager which uses this code below to draw my two GUI sprites
void OnGUI()
{
float screenHeight = Screen.height / 12f * 1.5f;
GUI.DrawTexture (new Rect (0, 0, Screen.width * 2, screenHeight), textureBand);
GUI.DrawTexture (new Rect (0, Screen.height - screenHeight, Screen.width * 2, screenHeight), textureBand);
}
However what ever I do my text is always drawn below my GUITexture so I can never see my text, could I get a little help with this one.
If you're drawing into the same location, you need to specify the depth of each draw to make sure they're sorted correctly. Take a look at the unity docs here:
http://docs.unity3d.com/ScriptReference/GUI-depth.html
Set a higher depth value for the textures you want drawn further back (behind the text) like so:
GUI.depth = 1;
I've got drawing sprites to work with OpenTK in my 2d game engine now. Only problem I'm having is that custom drawn objects with opengl (anything but sprites really) show up as the background color. Example:
I'm Drawing a 2.4f width black line here. There's also a quad and a point in the example, but they do not overlap anything that's actually visible. The line overlaps the magenta sprite, but the color is just wrong. My question is: Am I missing an OpenGL feature, or doing something horrible wrong?
These are the samples of my project concerning drawing: (you can also find the project on https://github.com/Villermen/HatlessEngine if there's questions about the code)
Initialization:
Window = new GameWindow(windowSize.Width, windowSize.Height);
//OpenGL initialization
GL.Enable(EnableCap.PointSmooth);
GL.Hint(HintTarget.PointSmoothHint, HintMode.Nicest);
GL.Enable(EnableCap.LineSmooth);
GL.Hint(HintTarget.LineSmoothHint, HintMode.Nicest);
GL.Enable(EnableCap.Blend);
GL.BlendFunc(BlendingFactorSrc.SrcAlpha, BlendingFactorDest.OneMinusSrcAlpha);
GL.ClearColor(Color.Gray);
GL.Enable(EnableCap.Texture2D);
GL.Enable(EnableCap.DepthTest);
GL.DepthFunc(DepthFunction.Lequal);
GL.ClearDepth(1d);
GL.DepthRange(1d, 0d); //does not seem right, but it works (see it as duct-tape)
Every draw cycle:
GL.Clear(ClearBufferMask.ColorBufferBit | ClearBufferMask.DepthBufferBit);
//reset depth and color to be consistent over multiple frames
DrawX.Depth = 0;
DrawX.DefaultColor = Color.Black;
foreach(View view in Resources.Views)
{
CurrentDrawArea = view.Area;
GL.Viewport((int)view.Viewport.Left * Window.Width, (int)view.Viewport.Top * Window.Height, (int)view.Viewport.Right * Window.Width, (int)view.Viewport.Bottom * Window.Height);
GL.MatrixMode(MatrixMode.Projection);
GL.LoadIdentity();
GL.Ortho(view.Area.Left, view.Area.Right, view.Area.Bottom, view.Area.Top, -1f, 1f);
GL.MatrixMode(MatrixMode.Modelview);
//drawing
foreach (LogicalObject obj in Resources.Objects)
{
//set view's coords for clipping?
obj.Draw();
}
}
GL.Flush();
Window.Context.SwapBuffers();
DrawX.Line:
public static void Line(PointF pos1, PointF pos2, Color color, float width = 1)
{
RectangleF lineRectangle = new RectangleF(pos1.X, pos1.Y, pos2.X - pos1.X, pos2.Y - pos1.Y);
if (lineRectangle.IntersectsWith(Game.CurrentDrawArea))
{
GL.LineWidth(width);
GL.Color3(color);
GL.Begin(PrimitiveType.Lines);
GL.Vertex3(pos1.X, pos1.Y, GLDepth);
GL.Vertex3(pos2.X, pos2.Y, GLDepth);
GL.End();
}
}
Edit: If I disable the blendcap before and enable it after drawing the line it does show up with the right color, but I must have it blended.
I forgot to unbind the texture in the texture-drawing method...
GL.BindTexture(TextureTarget.Texture2D, 0);
I'm not sure why this code isn't simply drawing a triangle to screen (orthographically). I'm using OpenTK 1.1 which is the same thing as OpenGL 1.1.
List<Vector3> simpleVertices = new List<Vector3>();
simpleVertices.Add(new Vector3(0,0,0));
simpleVertices.Add(new Vector3(100,0,0));
simpleVertices.Add(new Vector3(100,100,0));
GL.MatrixMode(All.Projection);
GL.LoadIdentity();
GL.MatrixMode(All.Projection);
GL.Ortho(0, 480, 320, 0,0,1000);
GL.MatrixMode(All.Modelview);
GL.LoadIdentity();
GL.Translate(0,0,10);
unsafe
{
Vector3* data = (Vector3*)Marshal.AllocHGlobal(
Marshal.SizeOf(typeof(Vector3)) * simpleVertices.Count);
for(int i = 0; i < simpleVertices.Count; i++)
{
((Vector3*)data)[i] = simpleVertices[i];
}
GL.VertexPointer(3, All.Float, sizeof(Vector3), new IntPtr(data));
GL.DrawArrays(All.Triangles, 0, simpleVertices.Count);
}
The code executes once every update cycle in a draw function. What I think I'm doing (but evidentially am not) is creating a set of position vertices to form a triangle and drawing it 10 units in front of the camera.
Why is this code not drawing a triangle?
In OpenGL, the Z axis points out of the screen, so when you write
GL.Translate(0,0,10);
it actually translates it "in front" of the screen.
Now your two last parameters to GL.Ortho are 0,1000. This means that everything between 0 and 1000 in the MINUS Z direction ( = in front of the camera ) will be displayed.
In other words, GL.Translate(0,0,-10); will put your object in front of the camera, while GL.Translate(0,0,10); will put it behind.