one side with texture other coloured yellow XNA C# - c#

This time I have this cube made of triangles. My code assignes texture to each triangle. How to change the code so only one wall will be left as texture and other will be painted yellow?
public class Game1 : Microsoft.Xna.Framework.Game
{
private float angle = .9f;
private float SecondAngle = -1f;
//MyVertexFormat struct to go here
struct MyVertexFormat
{
private Vector3 position;
private Vector2 texCoord;
public MyVertexFormat(Vector3 position, Vector2 texCoord)
{
this.position = position;
this.texCoord = texCoord;
}
//Add VertexDeclaration here
public readonly static VertexDeclaration VertexDeclaration = new
VertexDeclaration(
new VertexElement(0, VertexElementFormat.Vector3,
VertexElementUsage.Position, 0),
new VertexElement(sizeof(float) * 3,
VertexElementFormat.Vector2,
VertexElementUsage.TextureCoordinate, 0));
}
GraphicsDeviceManager graphics;
GraphicsDevice device;
Effect effect;
Matrix viewMatrix;
Matrix projectionMatrix;
VertexBuffer vertexBuffer;
Vector3 cameraPos;
Texture2D wallTexture;
public Game1()
{
graphics = new GraphicsDeviceManager(this);
Content.RootDirectory = "Content";
}
protected override void Initialize()
{
graphics.PreferredBackBufferWidth = 500;
graphics.PreferredBackBufferHeight = 500;
graphics.IsFullScreen = false;
graphics.ApplyChanges();
Window.Title = "HLSL Start";
base.Initialize();
}
protected override void LoadContent()
{
device = GraphicsDevice;
wallTexture = Content.Load<Texture2D>("wall");
effect = Content.Load<Effect>("Effect1");
SetUpVertices();
SetUpCamera();
}
private void SetUpVertices()
{
MyVertexFormat[] vertices = new MyVertexFormat[36];
//Back
vertices[0] = new MyVertexFormat(new Vector3(-1, -1, -1),
new Vector2(1.0f, 0.0f));
vertices[1] = new MyVertexFormat(new Vector3(1, 1, -1),
new Vector2(0.0f, 1.0f));
vertices[2] = new MyVertexFormat(new Vector3(-1, 1, -1),
new Vector2(1.0f, 1.0f));
vertices[3] = new MyVertexFormat(new Vector3(-1, -1, -1),
new Vector2(1.0f, 0.0f));
vertices[4] = new MyVertexFormat(new Vector3(1, -1, -1),
new Vector2(0.0f, 0.0f));
vertices[5] = new MyVertexFormat(new Vector3(1, 1, -1),
new Vector2(0.0f, 1.0f));
//Bottom
vertices[6] = new MyVertexFormat(new Vector3(1, -1, 1),
new Vector2(1.0f, 1.0f));
vertices[7] = new MyVertexFormat(new Vector3(1, -1, -1),
new Vector2(1.0f, 0.0f));
vertices[8] = new MyVertexFormat(new Vector3(-1, -1, -1),
new Vector2(0.0f, 0.0f));
vertices[9] = new MyVertexFormat(new Vector3(-1, -1, -1),
new Vector2(0.0f, 0.0f));
vertices[10] = new MyVertexFormat(new Vector3(-1, -1, 1),
new Vector2(0.0f, 1.0f));
vertices[11] = new MyVertexFormat(new Vector3(1, -1, 1),
new Vector2(1.0f, 1.0f));
//Top
vertices[12] = new MyVertexFormat(new Vector3(-1, 1, 1),
new Vector2(0.0f, 1.0f));
vertices[13] = new MyVertexFormat(new Vector3(-1, 1, -1),
new Vector2(1.0f, 1.0f));
vertices[14] = new MyVertexFormat(new Vector3(1, 1, 1),
new Vector2(0.0f, 0.0f));
vertices[15] = new MyVertexFormat(new Vector3(1, 1, 1),
new Vector2(0.0f, 0.0f));
vertices[16] = new MyVertexFormat(new Vector3(-1, 1, -1),
new Vector2(1.0f, 1.0f));
vertices[17] = new MyVertexFormat(new Vector3(1, 1, -1),
new Vector2(1.0f, 0.0f));
//Right side
vertices[18] = new MyVertexFormat(new Vector3(1, 1, 1),
new Vector2(1.0f, 1.0f));
vertices[19] = new MyVertexFormat(new Vector3(1, -1, -1),
new Vector2(0.0f, 0.0f));
vertices[20] = new MyVertexFormat(new Vector3(1, -1, 1),
new Vector2(1.0f, 0.0f));
vertices[21] = new MyVertexFormat(new Vector3(1, -1, -1),
new Vector2(0.0f, 0.0f));
vertices[22] = new MyVertexFormat(new Vector3(1, 1, 1),
new Vector2(1.0f, 1.0f));
vertices[23] = new MyVertexFormat(new Vector3(1, 1, -1),
new Vector2(0.0f, 1.0f));
//Left side
vertices[24] = new MyVertexFormat(new Vector3(-1, -1, 1),
new Vector2(0.0f, 0.0f));
vertices[25] = new MyVertexFormat(new Vector3(-1, -1, -1),
new Vector2(1.0f, 0.0f));
vertices[26] = new MyVertexFormat(new Vector3(-1, 1, 1),
new Vector2(0.0f, 1.0f));
vertices[29] = new MyVertexFormat(new Vector3(-1, 1, 1),
new Vector2(0.0f, 1.0f));
vertices[28] = new MyVertexFormat(new Vector3(-1, 1, -1),
new Vector2(1.0f, 1.0f));
vertices[27] = new MyVertexFormat(new Vector3(-1, -1, -1),
new Vector2(1.0f, 0.0f));
//Front
vertices[30] = new MyVertexFormat(new Vector3(-1, 1, 1),
new Vector2(1.0f, 1.0f));
vertices[31] = new MyVertexFormat(new Vector3(1, 1, 1),
new Vector2(0.0f, 1.0f));
vertices[32] = new MyVertexFormat(new Vector3(-1, -1, 1),
new Vector2(1.0f, 0.0f));
vertices[33] = new MyVertexFormat(new Vector3(1, -1, 1),
new Vector2(0.0f, 0.0f));
vertices[34] = new MyVertexFormat(new Vector3(-1, -1, 1),
new Vector2(1.0f, 0.0f));
vertices[35] = new MyVertexFormat(new Vector3(1, 1, 1),
new Vector2(0.0f, 1.0f));
vertexBuffer = new VertexBuffer(device,
MyVertexFormat.VertexDeclaration, vertices.Length,
BufferUsage.WriteOnly);
vertexBuffer.SetData(vertices);
}
private void SetUpCamera()
{
cameraPos = new Vector3(0, 5, 6);
viewMatrix = Matrix.CreateLookAt(cameraPos, new Vector3(0, 0, 1), new Vector3(0, 1, 0));
projectionMatrix = Matrix.CreatePerspectiveFieldOfView(MathHelper.PiOver4, device.Viewport.AspectRatio, 1.0f, 200.0f);
}
protected override void UnloadContent()
{
}
protected override void Update(GameTime gameTime)
{
if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed)
this.Exit();
viewMatrix = Matrix.CreateRotationY(MathHelper.ToRadians(angle)) *
Matrix.CreateRotationX(MathHelper.ToRadians(SecondAngle)) *
viewMatrix;
base.Update(gameTime);
}
protected override void Draw(GameTime gameTime)
{
device.Clear(ClearOptions.Target | ClearOptions.DepthBuffer, Color.DarkSlateBlue, 1.0f, 0);
effect.CurrentTechnique = effect.Techniques["Shaded"];
effect.Parameters["View"].SetValue(viewMatrix);
effect.Parameters["Projection"].SetValue(projectionMatrix);
effect.Parameters["World"].SetValue(Matrix.Identity);
effect.Parameters["myTexture"].SetValue(wallTexture);
foreach (EffectPass pass in effect.CurrentTechnique.Passes)
{
pass.Apply();
device.SetVertexBuffer(vertexBuffer);
device.DrawPrimitives(PrimitiveType.TriangleList, 0, 12);
}
base.Draw(gameTime);
}
}
}
effect file:
float4x4 World;
float4x4 View;
float4x4 Projection;
Texture myTexture;
sampler TextureSampler = sampler_state {
texture = <myTexture>;
MinFilter = Anisotropic; // Minification Filter
MagFilter = Anisotropic; // Magnification Filter
MipFilter = Linear; // Mip-mapping
AddressU = Wrap; // Address Mode for U Coordinates
AddressV = Wrap; // Address Mode for V Coordinates
};
struct VertexShaderInput
{
float4 Position : POSITION0;
float2 UV: TEXCOORD0;
};
struct VertexShaderOutput
{
float4 Position : POSITION0;
float2 UV: TEXCOORD0;
};
VertexShaderOutput VertexShaderFunction(VertexShaderInput input)
{
VertexShaderOutput output;
float4 worldPosition = mul(input.Position, World);
float4 viewPosition = mul(worldPosition, View);
output.Position = mul(viewPosition, Projection);
output.UV = input.UV;
return output;
}
float4 PixelShaderFunction(VertexShaderOutput input) : COLOR0
{
float3 output = float3(1, 1, 1);
output *= tex2D(TextureSampler, input.UV);
return float4(output, 1);
}
technique Shaded
{
pass Pass1
{
VertexShader = compile vs_2_0 VertexShaderFunction();
PixelShader = compile ps_2_0 PixelShaderFunction();
}
}
Any idea anyone?

Add yellow to a small area of your texture, and set the (U,V) texture coords of the triangles you want to be yellow to map that area.
[EDIT]
Add a Colour channel to your vertex format struct:
Class
struct MyVertexFormat
{
private Vector3 position;
private Vector2 texCoord;
private Color color;
public MyVertexFormat(Vector3 position, Vector2 texCoord, Color color)
{
this.position = position;
this.texCoord = texCoord;
this.color = color;
}
//Add VertexDeclaration here
public readonly static VertexDeclaration VertexDeclaration =
new VertexDeclaration(
new VertexElement(0, VertexElementFormat.Vector3,
VertexElementUsage.Position, 0),
new VertexElement(sizeof(float) * 3,
VertexElementFormat.Vector2,
VertexElementUsage.TextureCoordinate, 0)),
new VertexElement(sizeof(float) * 7,
VertexElementFormat.Color,
VertexElementUsage.Color, 0));
}
Effect
struct VertexShaderInput
{
float4 Position : POSITION0;
float2 UV: TEXCOORD0;
float4 Color: Color0;
};
As a note, I think is better to inherit your vertex struct from IVertexType.

Related

Unable to draw Primitives on Texture in SharpDX

I have a little problem with rendering in my SharpDX Direct11 App.
I had being tested rendering scene on a texture, and then draw this texture on backBuffer... but unfortunately renderTexture do not contains primitives which should be drawn. Texture is only filled by color.
Whole project on github: https://github.com/Kordi3112/SharpDXTest11
Main code part with rendering methods:
public override void Render()
{
//Camera
var proj = Matrix.OrthoLH(3 * Form.Bounds.Width / Form.Bounds.Height, 3, 0.01f, 100f);
var view = Matrix.LookAtLH(new Vector3(0, 0, -10), new Vector3(0, 0, 20), Vector3.UnitY);
var viewProj = Matrix.Multiply(view, proj);
var world = Matrix.Identity;
var worldViewProj = world * viewProj;
worldViewProj.Transpose();
//Update wvp matrix
Context.UpdateSubresource(ref worldViewProj, ContantBuffer);
DrawOnTexture();
//Set BackBuffer as render target
Context.OutputMerger.SetTargets(depthView, renderView);
// Clear views
Context.ClearDepthStencilView(depthView, DepthStencilClearFlags.Depth, 1.0f, 0);
Context.ClearRenderTargetView(renderView, Color.Pink);
//Set TextureColor Shader
Effect2.ApplyShader(Context);
//Set Buffers
Context.InputAssembler.SetVertexBuffers(0, new VertexBufferBinding(VertexBuffer2, Utilities.SizeOf<VertexPositionColorTexture>(), 0));
Context.InputAssembler.SetIndexBuffer(IndexBuffer, Format.R32_UInt, 0);
//Set Texture to Shader
Context.PixelShader.SetShaderResource(0, RenderTexture.ShaderResourceView);
//Draw
Context.DrawIndexed(6, 0, 0);
// Present!
SwapChain.Present(0, PresentFlags.None);
}
private void DrawOnTexture()
{
//Set Color Shader
Effect1.ApplyShader(Context);
//Set Buffers
Context.InputAssembler.SetVertexBuffers(0, new VertexBufferBinding(VertexBuffer, Utilities.SizeOf<VertexPositionColor>(), 0));
Context.InputAssembler.SetIndexBuffer(IndexBuffer, Format.R32_UInt, 0);
//Set Target
RenderTexture.SetRenderTarget(Context, depthView);
//Clear Targets - Green Bgound
RenderTexture.ClearRenderTarget(Context, depthView, 0, 1, 0, 1);
//Draw on RenderTarget
Context.DrawIndexed(6, 0, 0);
}
After call: Context.DrawIndexed(6, 0, 0); in private void DrawOnTexture() primitive should be drawn.
What this code above do
What i wanted to get
What's wrong with my code?
I'm sure the problem is not matrix or camera. When i will modify code to render primitive directly on backBuffer then its drawing normaly.
public override void Render()
{
//Camera
var proj = Matrix.OrthoLH(3 * Form.Bounds.Width / Form.Bounds.Height, 3, 0.01f, 100f);
var view = Matrix.LookAtLH(new Vector3(0, 0, -10), new Vector3(0, 0, 20), Vector3.UnitY);
var viewProj = Matrix.Multiply(view, proj);
var world = Matrix.Identity;
var worldViewProj = world * viewProj;
worldViewProj.Transpose();
//Update wvp matrix
Context.UpdateSubresource(ref worldViewProj, ContantBuffer);
//DrawOnTexture();
//Set BackBuffer as render target
Context.OutputMerger.SetTargets(depthView, renderView);
// Clear views
Context.ClearDepthStencilView(depthView, DepthStencilClearFlags.Depth, 1.0f, 0);
Context.ClearRenderTargetView(renderView, Color.Pink);
//Set Color Shader
Effect1.ApplyShader(Context);
//Set Buffers
Context.InputAssembler.SetVertexBuffers(0, new VertexBufferBinding(VertexBuffer, Utilities.SizeOf<VertexPositionColor>(), 0));
Context.InputAssembler.SetIndexBuffer(IndexBuffer, Format.R32_UInt, 0);
//Set Texture to Shader
//Context.PixelShader.SetShaderResource(0, RenderTexture.ShaderResourceView);
//Draw
Context.DrawIndexed(6, 0, 0);
// Present!
SwapChain.Present(0, PresentFlags.None);
}
output
Vertex Buffers declaration:
//Position Color
VertexBuffer = Buffer.Create(Device, BindFlags.VertexBuffer, new[] {
new VertexPositionColor(new Vector4(-1, -1, 0, 1), Color.Red.ToVector4()),
new VertexPositionColor(new Vector4(-1, 1, 0, 1), Color.Green.ToVector4()),
new VertexPositionColor(new Vector4(1, 1, 0, 1), Color.Blue.ToVector4()),
new VertexPositionColor(new Vector4(1, -1, 0, 1), Color.Yellow.ToVector4())
});
//Position Color Texture
VertexBuffer2 = Buffer.Create(Device, BindFlags.VertexBuffer, new[] {
new VertexPositionColorTexture(new Vector4(-1, -1, 0, 1), Color.White.ToVector4(), new Vector2(0,1)),
new VertexPositionColorTexture(new Vector4(-1, 1, 0, 1), Color.White.ToVector4(),new Vector2(0,0)),
new VertexPositionColorTexture(new Vector4(1, 1, 0, 1), Color.White.ToVector4(),new Vector2(1,0)),
new VertexPositionColorTexture(new Vector4(1, -1, 0, 1), Color.White.ToVector4(),new Vector2(1,1))
});
IndexBuffer = Buffer.Create(Device, BindFlags.IndexBuffer, new[] {
0,1,2,
0,2,3
});

Lighting a 2D mesh in a 3d environnement

I'm making a 2.5D game with Monogame. I have 2D meshes in a 3D space, and I want them to shine. But if I activate default lighting, they're pitch black.
Here the render code:
BasicEffect effect = new BasicEffect(graphicsDevice);
VertexPositionTexture[] vertices =
{
new VertexPositionTexture(new Vector3(-.5f + Position.X, 0.5f + Position.Y, 0.0f), new Vector2(0, 0)),
new VertexPositionTexture(new Vector3(-.5f + Position.X, -.5f + Position.Y, 0.0f), new Vector2(0, 1)),
new VertexPositionTexture(new Vector3(0.5f + Position.X, 0.5f + Position.Y, 0.0f), new Vector2(1, 0)),
new VertexPositionTexture(new Vector3(0.5f + Position.X, -.5f + Position.Y, 0.0f), new Vector2(1, 1)),
};
graphicsDevice.BlendState = BlendState.AlphaBlend;
effect.EnableDefaultLighting();
effect.LightingEnabled = true;
//effect.AmbientLightColor = new Vector3(.75f, .75f, .75f);
effect.DirectionalLight0.DiffuseColor = new Vector3(.75f, .75f, .75f);
effect.DirectionalLight0.Direction = new Vector3(0, 0, -1);
effect.DirectionalLight0.SpecularColor = new Vector3(.75f, .60f, .60f);
effect.TextureEnabled = true;
effect.Texture = Subtexture;
effect.Projection = camera.Fov;
effect.View = camera.ViewMatrix;
effect.World = camera.WorldMatrix;
VertexBuffer buffer = new VertexBuffer(graphicsDevice, typeof(VertexPositionTexture), vertices.Length, BufferUsage.WriteOnly);
buffer.SetData(vertices);
graphicsDevice.SetVertexBuffer(buffer);
graphicsDevice.RasterizerState = RasterizerState.CullNone;
foreach (EffectPass pass in effect.CurrentTechnique.Passes)
{
pass.Apply();
graphicsDevice.DrawUserPrimitives(PrimitiveType.TriangleStrip, vertices, 0, 2);
}

How do I change the color of a vertex in C# OpenGL?

I want to change the color of a few vertices under an event but I cannot seem to make it work.
How is the usual procedure done when you want to change a vertex color?
I have an initialization where I give instructions on how the cube is going to be made and a onRenderFrame(); where I draw the cube so the shape and color are already set but I cannot seem to manage to make a color change under an event (like an if-statement).
I will send the whole code. It also involves a connection between Arduino which will play part in the color change
using System;
using System.IO.Ports;
using Tao.FreeGlut;
using OpenGL;
namespace Arduino
{
class Program
{
private static int width = 1200, height = 720;
private static ShaderProgram program;
private static VBO<Vector3> squareColor;
private static VBO<Vector3> square;
private static VBO<int> squareElements;
private static System.Diagnostics.Stopwatch watch;
private static float angle;
private static bool exitWhile = false;
private static bool initOK = true;
static void Main(string[] args)
{
while(exitWhile == false)
{
if(initOK == true)
{
Init();
}
}
}
private static void Init()
{
Glut.glutInit();
Glut.glutInitDisplayMode(Glut.GLUT_DOUBLE | Glut.GLUT_DEPTH);
Glut.glutInitWindowSize(width, height);
Glut.glutCreateWindow("OpenGL Arduino");
SerialPort myArduino = new SerialPort();
myArduino.BaudRate = 9600;
myArduino.PortName = "COM3";
myArduino.Open();
myArduino.DataReceived += new SerialDataReceivedEventHandler(Comm);
Glut.glutIdleFunc(OnRenderFrame);
Glut.glutDisplayFunc(OnDisplay);
Glut.glutCloseFunc(OnClose);
Gl.Enable(EnableCap.DepthTest);
program = new ShaderProgram(VertexShader, Fragmentshader);
program.Use();
program["projection_matrix"].SetValue(Matrix4.CreatePerspectiveFieldOfView(0.45f, (float)width / height, 0.1f, 1000f));
program["view_matrix"].SetValue(Matrix4.LookAt(new Vector3(0, 0, 10), Vector3.Zero, Vector3.UnitY));
square = new VBO<Vector3>(new Vector3[] {
new Vector3(1, 1, -1), new Vector3(-1, 1, -1), new Vector3(-1, 1, 1), new Vector3(1, 1, 1),
new Vector3(1, -1, 1), new Vector3(-1, -1, 1), new Vector3(-1, -1, -1), new Vector3(1, -1, -1),
new Vector3(1, 1, 1), new Vector3(-1, 1, 1), new Vector3(-1, -1, 1), new Vector3(1, -1, 1),
new Vector3(1, -1, -1), new Vector3(-1, -1, -1), new Vector3(-1, 1, -1), new Vector3(1, 1, -1),
new Vector3(-1, 1, 1), new Vector3(-1, 1, -1), new Vector3(-1, -1, -1), new Vector3(-1, -1, 1),
new Vector3(1, 1, -1), new Vector3(1, 1, 1), new Vector3(1, -1, 1), new Vector3(1, -1, -1) });
squareColor = new VBO<Vector3>(new Vector3[] {
new Vector3(1, 1, 1), new Vector3(1, 1, 1), new Vector3(1, 1, 1), new Vector3(1, 1, 1),
new Vector3(1, 1, 1), new Vector3(1, 1, 1), new Vector3(1, 1, 1), new Vector3(1, 1, 1),
new Vector3(1, 1, 1), new Vector3(1, 1, 1), new Vector3(1, 1, 1), new Vector3(1, 1, 1),
new Vector3(1, 1, 1), new Vector3(1, 1, 1), new Vector3(1, 1, 1), new Vector3(1, 1, 1),
new Vector3(1, 1, 1), new Vector3(1, 1, 1), new Vector3(1, 1, 1), new Vector3(1, 1, 1),
new Vector3(1, 1, 1), new Vector3(1, 1, 1), new Vector3(1, 1, 1), new Vector3(1, 1, 1) });
squareElements = new VBO<int>(new int[] { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23 }, BufferTarget.ElementArrayBuffer);
watch = System.Diagnostics.Stopwatch.StartNew();
initOK = false;
Glut.glutMainLoop();
}
static void Comm(Object Sender, SerialDataReceivedEventArgs args)
{
SerialPort sp = (SerialPort)Sender;
string indata = sp.ReadExisting();
Console.Write(indata);
if (indata.Contains("1.10"))
{
Vector3[] vertexBuffer = (new Vector3[] {
new Vector3(1, 1, 1), new Vector3(1, 1, 1), new Vector3(1, 0, 0), new Vector3(1, 1, 1),
new Vector3(1, 1, 1), new Vector3(1, 0, 0), new Vector3(1, 1, 1), new Vector3(1, 1, 1),
new Vector3(1, 1, 1), new Vector3(1, 0, 0), new Vector3(1, 0, 0), new Vector3(1, 1, 1),
new Vector3(1, 1, 1), new Vector3(1, 1, 1), new Vector3(1, 1, 1), new Vector3(1, 1, 1),
new Vector3(1, 0, 0), new Vector3(1, 1, 1), new Vector3(1, 1, 1), new Vector3(1, 0, 0),
new Vector3(1, 1, 1), new Vector3(1, 1, 1), new Vector3(1, 1, 1), new Vector3(1, 1, 1) });
squareColor.BufferSubData(vertexBuffer);
}
}
private static void OnClose()
{
square.Dispose();
squareColor.Dispose();
squareColorChange.Dispose();
squareElements.Dispose();
program.DisposeChildren = true;
program.Dispose();
exitWhile = true;
}
private static void OnDisplay()
{
}
private static void OnRenderFrame()
{
watch.Stop();
float deltaTime = watch.ElapsedMilliseconds / 1000f;
watch.Restart();
angle += deltaTime;
Gl.Viewport(0, 0, width, height);
Gl.Clear(ClearBufferMask.ColorBufferBit | ClearBufferMask.DepthBufferBit);
program.Use();
//Square draw
program["model_matrix"].SetValue(Matrix4.CreateRotationY(angle) * Matrix4.CreateTranslation(new Vector3(1.5f, 0, 0)));
Gl.BindBufferToShaderAttribute(square, program, "vertexPosition");
Gl.BindBufferToShaderAttribute(squareColor, program, "vertexColor");
Gl.BindBufferToShaderAttribute(squareColorChange, program, "vertexColor");
Gl.BindBuffer(squareElements);
Gl.DrawElements(BeginMode.Quads, squareElements.Count, DrawElementsType.UnsignedInt, IntPtr.Zero);
Glut.glutSwapBuffers();
}
public static string VertexShader = #"
in vec3 vertexPosition;
in vec3 vertexColor;
out vec3 color;
uniform mat4 projection_matrix;
uniform mat4 view_matrix;
uniform mat4 model_matrix;
void main(void)
{
color = vertexColor;
gl_Position = projection_matrix * view_matrix * model_matrix * vec4(vertexPosition, 1);
}
";
public static string Fragmentshader = #"
in vec3 color;
out vec4 fragment;
void main(void)
{
fragment = vec4(color, 1);
}
";
}
It may look a little rough and that's because I am pretty new in both C# and asking questions on Stackoverflow.
I edited the code by adding a subBuffer to my event, although it does not render the new color anyway. Have I forgotten to do something?
Thanks in advance!

How to prevent triangles in OpenGL from rendering on top of triangles in front of themselves

I've been working with OpenGL using the OpenTK library for .NET, writing my own engine. I placed 3 different objects, one spinning cube and 2 adjacent cubes. Everything seemed to work fine until I changed the color of the quad on top of the objects.
I'm rendering cubes with a green top, on the left the block on the back is being rendered over the block in the front. I can't seem to find out where I'm going wrong with this, when the camera is set to look from the other side it renders correctly.
The following is the related code in classes with irrelevant or unrelated methods, properties and attributes omitted:
GameState.cs
class GameState : State
{
// TEMP: Test Block
SimpleBlock block;
int i = 0;
public override void Render()
{
base.Render();
// Set OpenGL Settings
GL.Viewport(0, 0, 1024, 768);
GL.Enable(EnableCap.CullFace);
// Reset the Matrices
Matrices.ClearMatrices();
// Set Camera Settings (Field of view in radians)
Matrices.ProjectionMatrix = Matrix4.CreatePerspectiveFieldOfView((float)Math.PI / 2, (1024.0f / 768.0f), 1, 1000);
// Create the Camera
// this has to be in reverse
Matrix4 viewMatrix = Matrix4.CreateRotationX((float)Math.PI/8);
viewMatrix = viewMatrix.Translate(0, -2, -4);
// Multiply it with the ModelView (Which at this point is set to a value that we can just use = and it has the same result)
Matrices.ModelViewMatrix = viewMatrix;
// Render the Block
Matrices.Push();
Matrices.ModelViewMatrix = Matrices.ModelViewMatrix.Translate(2, 0, 0);
Matrices.ModelViewMatrix = Matrices.ModelViewMatrix.Translate(0.5f, 0, 0.5f);
Matrices.ModelViewMatrix = Matrices.ModelViewMatrix.Rotate(0, i / 40.0f, 0);
block.Render();
Matrices.Pop();
// Render the Block Again Twice
Matrices.Push();
Matrices.ModelViewMatrix = Matrices.ModelViewMatrix.Translate(-2, 0, 0);
Matrices.ModelViewMatrix = Matrices.ModelViewMatrix.Translate(0.5f, 0, 0.5f);
block.Render();
Matrices.ModelViewMatrix = Matrices.ModelViewMatrix.Translate(0, 0, -1);
block.Render();
Matrices.Pop();
// Increment Rotation Test Variable
i++;
}
}
SimpleBlock.cs
class SimpleBlock : IBlock
{
public void Render()
{
// Send the Shader Parameters to the GPU
Shader.Bind();
Shader.SendMatrices();
// Begin Rendering the Polys
GL.Begin(BeginMode.Triangles);
// Front Quad
Shader.SetColor(Color4.SaddleBrown);
GL.Normal3(0, 0, 1);
GLUtils.QuadVertices(
new Vector3(-0.5f, 1, 0.5f),
new Vector3(-0.5f, 0, 0.5f),
new Vector3( 0.5f, 1, 0.5f),
new Vector3( 0.5f, 0, 0.5f));
// Right Quad
GL.Normal3(1, 0, 0);
GLUtils.QuadVertices(
new Vector3(0.5f, 1, 0.5f),
new Vector3(0.5f, 0, 0.5f),
new Vector3(0.5f, 1, -0.5f),
new Vector3(0.5f, 0, -0.5f));
// Back Quad
GL.Normal3(0, 0, -1);
GLUtils.QuadVertices(
new Vector3( 0.5f, 1, -0.5f),
new Vector3( 0.5f, 0, -0.5f),
new Vector3(-0.5f, 1, -0.5f),
new Vector3(-0.5f, 0, -0.5f));
// Left Quad
GL.Normal3(-1, 0, 0);
GLUtils.QuadVertices(
new Vector3(-0.5f, 1, -0.5f),
new Vector3(-0.5f, 0, -0.5f),
new Vector3(-0.5f, 1, 0.5f),
new Vector3(-0.5f, 0, 0.5f));
// Bottom Quad
GL.Normal3(0, -1, 0);
GLUtils.QuadVertices(
new Vector3(-0.5f, 0, 0.5f),
new Vector3(-0.5f, 0, -0.5f),
new Vector3( 0.5f, 0, 0.5f),
new Vector3( 0.5f, 0, -0.5f));
// Top Quad
Shader.SetColor(Color4.Green);
GL.Normal3(0, 1, 0);
GLUtils.QuadVertices(
new Vector3(-0.5f, 1, -0.5f),
new Vector3(-0.5f, 1, 0.5f),
new Vector3(0.5f, 1, -0.5f),
new Vector3(0.5f, 1, 0.5f));
// Done!
GL.End();
}
}
BasicFragment.glfs
#version 130
// MultiColor Attribute
in vec4 multiColor;
// Output color
out vec4 gl_FragColor;
void main()
{
// Set fragment
gl_FragColor = multiColor;
}
BasicVertex.glvs
#version 130
// Transformation Matrices
uniform mat4 ProjectionMatrix;
uniform mat4 ModelViewMatrix;
// Vertex Position Attribute
in vec3 VertexPos;
// MultiColor Attributes
in vec4 MultiColor;
out vec4 multiColor;
void main()
{
// Process Colors
multiColor = MultiColor;
// Process Vertex
gl_Position = ProjectionMatrix * ModelViewMatrix * vec4(VertexPos.x, VertexPos.y, VertexPos.z, 1);
}
MainWindow.cs
// Extends OpenTK's GameWindow Class
class MainWindow : GameWindow
{
public MainWindow()
: base(1024, 768, new GraphicsMode(32, 0, 0, 4))
{
this.Title = "Trench Wars";
this.WindowBorder = WindowBorder.Fixed;
this.ClientSize = new Size(1024, 768);
// Set VSync On
this.VSync = VSyncMode.Adaptive;
}
protected override void OnRenderFrame(FrameEventArgs e)
{
base.OnRenderFrame(e);
// Clear Screen
GL.ClearColor(Color4.CornflowerBlue);
GL.Clear(ClearBufferMask.ColorBufferBit | ClearBufferMask.DepthBufferBit);
// Do State-Specific Rendering
StateEngine.Render();
// Pull a Wicked Bluffing move in Poker
GL.Flush();
// Swap Buffers
this.SwapBuffers();
}
}
It seems like you did forget to enable depth testing. glEnable(GL_DEPTH_TEST) before rendering the geometry is your friend (or given the language bindings you're using GL.Enable(EnableCap.DepthTest);).

reusing xna primitives via class

Is there any way to make a primitive and use it over and over again? ex: if I make one cube, can I create 100 and make a 10x10 grid? I've tried using a for loop and updating the x and z coords with each loop thru, but it only moves the one cube thats created in the beginning. My class was created using an example from a book. I know how to move the cube around the area by changing the coords in the PositionCube method. What can I do in my main game class that will allow me to create a simple 10x10 grid?
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
namespace Cube_Chaser
{
class Cube
{
private GraphicsDevice device;
private Texture2D texture;
public Vector3 location;
private Vector3 position;
private VertexBuffer cubeVertexBuffer;
private List<VertexPositionTexture> vertices = new List<VertexPositionTexture>();
public Cube(GraphicsDevice graphicsDevice, Vector3 playerLocation, float minDistance, Texture2D texture)
{
device = graphicsDevice;
this.texture = texture;
PositionCube(playerLocation, minDistance);
BuildFace(new Vector3(0, 0, 0), new Vector3(0, 1, 1));
BuildFace(new Vector3(0, 0, 1), new Vector3(1, 1, 1));
BuildFace(new Vector3(1, 0, 1), new Vector3(1, 1, 0));
BuildFace(new Vector3(1, 0, 0), new Vector3(0, 1, 0));
BuildFaceHorizontal(new Vector3(0, 1, 0), new Vector3(1, 1, 1));
BuildFaceHorizontal(new Vector3(0, 0, 1), new Vector3(1, 0, 0));
cubeVertexBuffer = new VertexBuffer(device, VertexPositionTexture.VertexDeclaration, vertices.Count, BufferUsage.WriteOnly);
cubeVertexBuffer.SetData<VertexPositionTexture>(vertices.ToArray());
this.position = position;
}
private void BuildFace(Vector3 p1, Vector3 p2)
{
vertices.Add(BuildVertex(p1.X, p1.Y, p1.Z, 1, 0));
vertices.Add(BuildVertex(p1.X, p2.Y, p1.Z, 1, 1));
vertices.Add(BuildVertex(p2.X, p2.Y, p2.Z, 0, 1));
vertices.Add(BuildVertex(p2.X, p2.Y, p2.Z, 0, 1));
vertices.Add(BuildVertex(p2.X, p1.Y, p2.Z, 0, 0));
vertices.Add(BuildVertex(p1.X, p1.Y, p1.Z, 1, 0));
}
private void BuildFaceHorizontal(Vector3 p1, Vector3 p2)
{
vertices.Add(BuildVertex(p1.X, p1.Y, p1.Z, 0, 1));
vertices.Add(BuildVertex(p2.X, p1.Y, p1.Z, 1, 1));
vertices.Add(BuildVertex(p2.X, p2.Y, p2.Z, 1, 0));
vertices.Add(BuildVertex(p1.X, p1.Y, p1.Z, 0, 1));
vertices.Add(BuildVertex(p2.X, p2.Y, p2.Z, 1, 0));
vertices.Add(BuildVertex(p1.X, p1.Y, p2.Z, 0, 0));
}
private VertexPositionTexture BuildVertex(float x, float y, float z, float u, float v)
{
return new VertexPositionTexture(new Vector3(x, y, z), new Vector2(u, v));
}
public void PositionCube(Vector3 playerLocation, float minDistance)
{
location = new Vector3(.5f, .5f, .5f);
}
public void Draw(Camera camera, BasicEffect effect)
{
effect.VertexColorEnabled = false;
effect.TextureEnabled = true;
effect.Texture = texture;
Matrix center = Matrix.CreateTranslation(new Vector3(-0.5f, -0.5f, -0.5f));
Matrix scale = Matrix.CreateScale(0.05f);
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(cubeVertexBuffer);
device.DrawPrimitives(PrimitiveType.TriangleList, 0, cubeVertexBuffer.VertexCount / 3);
}
}
}
}
I took #nico-schetler 's answer and created the classes for you.
Cube.cs
class Cube
{
private GraphicsDevice device;
private VertexBuffer cubeVertexBuffer;
public Cube(GraphicsDevice graphicsDevice)
{
device = graphicsDevice;
var vertices = new List<VertexPositionTexture>();
BuildFace(vertices, new Vector3(0, 0, 0), new Vector3(0, 1, 1));
BuildFace(vertices, new Vector3(0, 0, 1), new Vector3(1, 1, 1));
BuildFace(vertices, new Vector3(1, 0, 1), new Vector3(1, 1, 0));
BuildFace(vertices, new Vector3(1, 0, 0), new Vector3(0, 1, 0));
BuildFaceHorizontal(vertices, new Vector3(0, 1, 0), new Vector3(1, 1, 1));
BuildFaceHorizontal(vertices, new Vector3(0, 0, 1), new Vector3(1, 0, 0));
cubeVertexBuffer = new VertexBuffer(device, VertexPositionTexture.VertexDeclaration, vertices.Count, BufferUsage.WriteOnly);
cubeVertexBuffer.SetData<VertexPositionTexture>(vertices.ToArray());
}
private void BuildFace(List<VertexPositionTexture> vertices, Vector3 p1, Vector3 p2)
{
vertices.Add(BuildVertex(p1.X, p1.Y, p1.Z, 1, 0));
vertices.Add(BuildVertex(p1.X, p2.Y, p1.Z, 1, 1));
vertices.Add(BuildVertex(p2.X, p2.Y, p2.Z, 0, 1));
vertices.Add(BuildVertex(p2.X, p2.Y, p2.Z, 0, 1));
vertices.Add(BuildVertex(p2.X, p1.Y, p2.Z, 0, 0));
vertices.Add(BuildVertex(p1.X, p1.Y, p1.Z, 1, 0));
}
private void BuildFaceHorizontal(List<VertexPositionTexture> vertices, Vector3 p1, Vector3 p2)
{
vertices.Add(BuildVertex(p1.X, p1.Y, p1.Z, 0, 1));
vertices.Add(BuildVertex(p2.X, p1.Y, p1.Z, 1, 1));
vertices.Add(BuildVertex(p2.X, p2.Y, p2.Z, 1, 0));
vertices.Add(BuildVertex(p1.X, p1.Y, p1.Z, 0, 1));
vertices.Add(BuildVertex(p2.X, p2.Y, p2.Z, 1, 0));
vertices.Add(BuildVertex(p1.X, p1.Y, p2.Z, 0, 0));
}
private VertexPositionTexture BuildVertex(float x, float y, float z, float u, float v)
{
return new VertexPositionTexture(new Vector3(x, y, z), new Vector2(u, v));
}
public void Draw( BasicEffect effect)
{
foreach (EffectPass pass in effect.CurrentTechnique.Passes)
{
pass.Apply();
device.SetVertexBuffer(cubeVertexBuffer);
device.DrawPrimitives(PrimitiveType.TriangleList, 0, cubeVertexBuffer.VertexCount / 3);
}
}
}
CubeDrawable.cs
public class DrawableList<T> : DrawableGameComponent
{
private BasicEffect effect;
private Camera camera;
private class Entity
{
public Vector3 Position { get; set; }
public Matrix Orientation { get; set; }
public Texture2D Texture { get; set; }
}
private Cube cube;
private List<Entity> entities = new List<Entity>();
public DrawableList (Game game, Camera camera, BasicEffect effect)
: base( game )
{
this.effect = effect;
cube = new Cube (game.GraphicsDevice);
this.camera = camera;
}
public void Add( Vector3 position, Matrix orientation, Texture2D texture )
{
entities.Add (new Entity() {
Position = position,
Orientation = orientation,
Texture = texture
});
}
public override void Draw (GameTime gameTime )
{
base.Draw (gameTime);
foreach (var item in entities) {
effect.VertexColorEnabled = false;
effect.TextureEnabled = true;
effect.Texture = item.Texture;
Matrix center = Matrix.CreateTranslation(new Vector3(-0.5f, -0.5f, -0.5f));
Matrix scale = Matrix.CreateScale(0.05f);
Matrix translate = Matrix.CreateTranslation(item.Position);
effect.World = center * scale * translate;
effect.View = camera.View;
effect.Projection = camera.Projection;
cube.Draw (effect);
}
}
}
Usage
camera = new Camera (graphics.GraphicsDevice);
effect = new BasicEffect (graphics.GraphicsDevice);
cubes = new DrawableList<Cube> (this, camera, effect);
Components.Add (cubes);
for (int i=0 ; i < 50; i++)
{
cubes.Add (new Vector3( i*0.5f, 50.0f, 50.0f), Matrix.Identity, logoTexture);
}
You should separate the logical representation of the cube from the physical one. The physical representation would be the vertex buffer etc. This is the same for every cube. You can affect the rendering through e.g. world transforms (as you already did).
The logical representation is your cube class. You will need 100 instances of them (each with their own position, scale etc.). The logical representation can reference the physical one. So there is no need to have more than one vertex buffer.

Categories