I am trying to make my opengl program emit balls from a cube. There are two types of balls - a small blue one and a larger orange one. The balls should fall due to gravity. However at the moment it only seems to emit one of each ball and thats it.
I have tried drawing the balls inside a loop, as follows:
for (int i = 0; i < 100; i = i + 1)
{
Matrix4 mSphereOrange = Matrix4.CreateScale(mOrangeRadius) * Matrix4.CreateTranslation(mOrangePosition);
SetUniformVariables(0.19125f, 0.0735f, 0.054f, 1, 0.647f, 0f, 0.256777f, 0.137622f, 0.086014f, 0.5f);
GL.UniformMatrix4(uModelLocation, true, ref mSphereOrange);
GL.BindVertexArray(mVAO_IDs[2]);
GL.DrawElements(BeginMode.Triangles, mSphereModelUtility.Indices.Length, DrawElementsType.UnsignedInt, 0);
Matrix4 mSphereBlue = Matrix4.CreateScale(mBlueRadius) * Matrix4.CreateTranslation(mBluePosition);
SetUniformVariables(0, 0.1f, 0.06f, 0.0f, 0.50980392f, 0.50980392f, 0.50196078f, 0.50196078f, 0.50196078f, 10f);
GL.UniformMatrix4(uModelLocation, true, ref mSphereBlue);
GL.BindVertexArray(mVAO_IDs[2]);
GL.DrawElements(BeginMode.Triangles, mSphereModelUtility.Indices.Length, DrawElementsType.UnsignedInt, 0);
}
Can anyone see why this may not be working? Or suggest a better way to create an emitter?
Any help would be much appreciated,
Lucy
I'm sure that the problem is related with for loop. You create simultaneously 100 orange spheres and 100 blue spheres at the same position.
Related
I have a semicircle like game object which I made by putting two arcs in an empty game object (SCircle) and rotating the 15° (for left arc) and -15° (for right arc) as seen below.
SCircle has an Orientation enum with two valuesLeft (rotates SCircle to 45°) and Right (rotates SCircle to -45°) as seen in the image below.
I use the following coroutine to move SCircle between orientations.
IEnumerator RotateLeftOrRight(Vector3 byAngles, float inTime)
{
Quaternion fromAngle = gameObject.transform.rotation ;
Quaternion toAngle = Quaternion.Euler (transform.eulerAngles);
if (circOrientation == Orientation.Left) {
toAngle = Quaternion.Euler (gameObject.transform.eulerAngles - byAngles);
circOrientation = Orientation.Right;
}
else if (circOrientation == Orientation.Right) {
toAngle = Quaternion.Euler (gameObject.transform.eulerAngles + byAngles);
circOrientation = Orientation.Left;
}
for(float t = 0f ; t <= 1f ; t += Time.deltaTime/inTime)
{
gameObject.transform.rotation = Quaternion.Lerp(fromAngle, toAngle, t) ;
yield return null ;
}
gameObject.transform.rotation = Quaternion.Lerp(fromAngle, toAngle, 1);
}
I also used a very similar coroutine to move the individual arcs by 30° (in opposite directions) from say, Orientation Left, as seen below in the coroutine and image:
IEnumerator RotateArc(GameObject arcGO, Vector3 byAngles, float inTime)
{
Quaternion fromAngle = arcGO.transform.rotation ;
Quaternion toAngle = Quaternion.Euler (arcGO.transform.eulerAngles);
if (rightArc.arcOrientation == Arc.Orientation.Down) {
toAngle = Quaternion.Euler (arcGO.transform.eulerAngles + byAngles);
rightArc.arcOrientation = Arc.Orientation.Up;
}
else if (rightArc.arcOrientation == Arc.Orientation.Down) {
toAngle = Quaternion.Euler (arcGO.transform.eulerAngles - byAngles);
rightArc.arcOrientation = Arc.Orientation.Up;
}
for(float t = 0f ; t <= 1f ; t += Time.deltaTime/inTime)
{
arcGO.transform.rotation = Quaternion.Lerp(fromAngle, toAngle, t) ;
yield return null ;
}
arcGO.transform.rotation = Quaternion.Lerp(fromAngle, toAngle, 1);
}
Since SCircle Coroutine is activated by a mouse click, I have the case where the individual arcs coroutine is run and before it is complete the parent SCircle coroutine is also run. In this case the arcs end up moving from Left to A, which is not the behavior I need. I would want the behavior of them ending up at B when moving from the Left. Likewise, from B, when the SCircle coroutine is run while the arcs coroutine is in progress the orientation will return to the Left.
Please note that the blue arrow represents the movement of the left Arc, the red represents the right Arc and the black represents movement of SCircle - the parent object.
I believe the issue you're having is caused by the fact that as you rotate the individual arcs, what they're rotating around is also rotating itself.
In other words, your SCircle's axes are rotating, and your arcs are using those same axes to determine their own rotations. So if you look at your example A, you tell it to rotate in world space by -90, then immediately tell to rotate in world space by 30. To solve this, you want to get the arcs to rotate locally, not in world space.
I think you can solve this by setting up this structure:
Empty GameObject SCircle
------Empty gameObject BlueArcCenter -> position 0,0,0
-----------blue arc -> change position here to make it offset from zero ex:(radius, 0, 0)
------Empty gameObject RedArcCenter -> position (0,0,0)
-----------red arc -> change position here to make it offset from zero ex:(-radius, 0, 0)
Now alter your code so that:
To rotate the blue and red arcs individually you rotate their arcCenters,
To rotate the whole configuration, rotate SCircle. This will in turn rotate both ArcCenters, which will in turn rotate both the arcs irrespective of how they are oriented relative to each other, or whether they are rotating themselves.
Note:
Also, I've read that people are using Quaternions a lot less these days since they don't really make sense when you read the code. You might want to change your code to normal rotations to make it more readable.
If you have the setup listed above, use something like:
to spin circle:
thisSCircle.transform.Rotate(0, -90, 0, Space.Self);
to rotate arcs around their common center:
blueArcCenter.transform.Rotate(0, -30, 0, Space.Self)
redArcCemter.transform.Rotate(0, 30, 0, Space.Self)
(you'd need to add lerps in and stuff but this should get you started).
I've been working on something that loads the geometry of a game and follows the players position and view but I've ran into a problem: I can't rotate the view without all the axis being messed up.
Here's a screenshot of the program with a pitch and yaw of 0 (just like the game's client):
http://i.stack.imgur.com/DXhIr.jpg
Here's my view matrix code:
public void UpdateViewMatrix()
{
Vector3 pos = Position;
pos.X *= -1;
pos.Y *= -1;
pos.Z *= -1;
this.ViewMatrix = Matrix.CreateScale(1) * Matrix.CreateLookAt(Vector3.Zero, new Vector3(1, 0, 0), new Vector3(0, 0, 1)) * Matrix.CreateTranslation(pos) * Matrix.CreateFromYawPitchRoll(-MathHelper.PiOver2, -MathHelper.PiOver2, MathHelper.Pi);
this.Frustum.Matrix = (this.ViewMatrix * this.ProjectionMatrix);
if (this.CameraUpdated != null) this.CameraUpdated(this, new EventArgs());
}
I'm unsure why I have to flip all the coordinates as well before I update the view matrix.
Thanks in advance!
I'm unsure why I have to flip all the coordinates as well before I
update the view matrix
You probably don't.
In an Xna first person shooter, an easy way to handle the camera's view matrix to follow a character is to create a copy of that character's world matrix, offset it behind and slightly above, then invert it. That way, all the rotation and position manipulation that is done for the player does not have to be duplicated for the camera. This is a simple example of this:
//player moved and rotated and player's world matrix is determined
Matrix cameraWorld = playerWorld;
cameraWorld.Translation += (cameraWorld.Backward * followingDistance) +
(cameraWorld.Up * verticalOffset);
ViewMatrix = Matrix.Invert(cameraWorld);
Now the camera view matrix is orientated identically as the player and will stick to him like glue.
I just got a problem with drawing two 3D cubes standing in line. In my code, I made a cube class, and in the game1 class, I built two cubes, A on the right side, B on the left side. I also setup an FPS camera in the 3D world. The problem is if I draw cube B first(Blue), and move the camera to the left side to cube B, A(Red) is still standing in front of B, which is apparently wrong.
I guess some pics can make much sense.
Then, I move the camera to the other side, the situation is like:
This is wrong....
From this view, the red cube, A should be behind the blue one, B....
Could somebody give me help please?
This is the draw in the Cube class
Matrix center = Matrix.CreateTranslation(
new Vector3(-0.5f, -0.5f, -0.5f));
Matrix scale = Matrix.CreateScale(0.5f);
Matrix translate = Matrix.CreateTranslation(location);
effect.World = center * scale * translate;
effect.View = camera.View;
effect.Projection = camera.Projection;
foreach (EffectPass pass in effect.CurrentTechnique.Passes)
{
pass.Apply();
device.SetVertexBuffer(cubeBuffer);
RasterizerState rs = new RasterizerState();
rs.CullMode = CullMode.None;
rs.FillMode = FillMode.Solid;
device.RasterizerState = rs;
device.DrawPrimitives(
PrimitiveType.TriangleList,
0,
cubeBuffer.VertexCount / 3);
}
This is the Draw method in game1
A.Draw(camera, effect); B.Draw(camera, effect);
It seems like your depth buffer does not work. Have you turned it off? Make sure to use a correct DepthStencilState and that you have a bound depth buffer (both should be set up correctly by default).
Another possible reason is the effect not returning reasonable depth information. However, this seems unlikely.
Hello I'm trying to make a terrain engine similar to that of Minecraft.
I was able to get a chunk loaded. It is very laggy and when there is more than one chunk loaded at once it becomes unplayable.
This is my render code:
public static void renderNormalBlock(GraphicsDevice g, Chunk chunk,Texture2D texture, int x, int y, int z)
{
float tileSize = 0.5F;
Vector3 blockPosition = new Vector3(x / tileSize, y / tileSize, z / tileSize);
Model blockModel = Main.defaultBlockModel;
ModelMesh mesh = blockModel.Meshes[0];
g.SamplerStates[0] = SamplerState.PointWrap;
BasicEffect effect = (BasicEffect)mesh.Effects[0];
effect.TextureEnabled = true;
effect.Texture = texture;
effect.View = Main.camera;
effect.Projection = Matrix.CreatePerspectiveFieldOfView(MathHelper.ToRadians(45), g.DisplayMode.AspectRatio, 1, 128);
effect.World = Matrix.CreateWorld(blockPosition, Vector3.Forward, Vector3.Up);
mesh.Draw();
}
As You can see I am not using for-each or for loops because as it's only a cube; It is not required.
I did some research and the best answer I found was that I need to hide the cube's faces that are not visible. So say if there's 2 cubes next to each other, I don't want to render the in between faces.
This is where I get stuck, Most people are using cubes that were drawn in XNA, and I'm using a model.
I'm new to XNA and I don't understand too much of the Math involved in manually drawing a cube since I'm currently in grade 9, so I used a model.
So how would I go about rendering only the faces that are visible?
your starting to develop a game before learning the basics. you wont get too far this way. First grab a book about XNA development and go through it. This is a basic subject that will be covered there. In addition, go visit techCraft http://techcraft.codeplex.com/ and download their implementation which comes with all the code. you will learn alot from that alone.
Good day everyone.
I hope you can help me with my question.
Is there a way to transform or directly render sprite like so?
Without using 3d. I know it can be easily done in 3d, but the project I'm working on doesn't use 3d at all, so I don't really want to also include 3d just because of that small thing...
(example image is from some random game)
So basically what I need:
Take a sprite as a rectangle, and then transform it in a free way, meaning that I can set points of that sprite to any coorditates, not just as rectangle.
Thanks in advance.
The technique used in that image is raycasting 2d. that was used first time with wolfenstein 3d, and implements a fake 3d over 2D.
here you can find a tutotial http://lodev.org/cgtutor/
though this is not what you want.
the best way to achieve what you want is define two triangles and use GraphicsDevice.DrawUserPrimitives with a basiceffect to draw it.
// Init Triangles with four points A,B,C and D
VertexPOsitionTexture[] Vertex = new VertexPositionTexture[6];
Vertex[0].Position = (A.X,A.Y,0);
Vertex[1].Position = (B.X,B.Y,0);
Vertex[2].Position = (C.X,C.Y,0);
Vertex[3].Position = (C.X,C.Y,0);
Vertex[4].Position = (B.X,B.Y,0);
Vertex[5].Position = (D.X,D.Y,0);
Vertex[0].Texture= (0,0);
Vertex[1].Texture= (1,0);
Vertex[2].Texture= (0,1);
Vertex[3].Texture= (0,1);
Vertex[4].Texture= (1,0);
Vertex[5].Texture= (1,1);
// Init Effect from http://blogs.msdn.com/b/shawnhar/archive/2010/04/05/spritebatch-and-custom-shaders-in-xna-game-studio-4-0.aspx
Matrix projection = Matrix.CreateOrthographicOffCenter(0, viewport.Width, viewport.Height, 0, 0, 1);
Matrix halfPixelOffset = Matrix.CreateTranslation(-0.5f, -0.5f, 0);
BasicEffect effect = new BasicEffect();
effect.Texture = your texture;
effect.TextureEnabled = true;
effect.World = Matrix.Identity;
effect.View = Matrix.Identity;
effect.Projection = halfPixelOffset * projection;
// Draw Triangles
effect.Apply():
GraphicsDevice.DrawUserPrimitives<VertexPositionTexture>(vertex, TriangleList, ...,...);
this code have to be understand as pseudocode, it's not tested but it shows the relevant actions to be done.