OpenTK textured Cubes show up black? - c#

Im trying to follow this tut here http://neokabuto.blogspot.com/2014/07/opentk-tutorial-6-part-3-putting-it-all.html (backup http://web.archive.org/web/20190125230120/http://neokabuto.blogspot.com/2014/07/opentk-tutorial-6-part-3-putting-it-all.html) But I have been threw the code like a hundred times but I still keep getting black cubes :(.
Heres a download link for my hole project https://mega.nz/folder/t8NAxDRJ#MEIlwc96FZEPi_pUuB2xaA
heres what it looks like
Heres my main script, maby the errors in that?
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Drawing;
using OpenTK;
//using OpenTK.Graphics;
using OpenTK.Graphics.OpenGL;
using System.IO;
using OpenTK.Input;
using System.Windows.Media.Imaging;
using System.Drawing.Imaging;
//using System.Windows.Input;
namespace OpenTKTutorial1
{
class Game: GameWindow
{
public Game() : base(1000,500, new OpenTK.Graphics.GraphicsMode(32,24,0,4))
{
}
//Just like we had a Dictionary to allow us to use strings to
//organize our shaders, we'll use another to keep track of our
//texture IDs. Add this to the Game class:
Dictionary<string, int> textures = new Dictionary<string, int>();
Vector2[] texcoorddata;
Camera cam;
Vector2 lastMousePos = new Vector2();
float time = 0.0f;
int ibo_elements;
Dictionary<string, ShaderProgram> shaders = new Dictionary<string, ShaderProgram>();
string activeShader = "default";
Vector3[] vertdata;
Vector3[] coldata;
List<Volume> objects = new List<Volume>();
int[] indicedata;
protected override void OnLoad(EventArgs e)
{
base.OnLoad(e);
cam = new Camera();
initProgram();
Title = "Hello OpenTK!";
GL.ClearColor(Color.CornflowerBlue);
GL.PointSize(5f);
}
void initProgram()
{
lastMousePos = new Vector2(Mouse.X, Mouse.Y);
GL.GenBuffers(1, out ibo_elements);
shaders.Add("default", new ShaderProgram("Shaders/vs.glsl", "Shaders/fs.glsl", true));
shaders.Add("textured", new ShaderProgram("Shaders/vs_tex.glsl", "Shaders/fs_tex.glsl", true));
activeShader = "textured";
textures.Add("pictures/opentksquare.png", loadImage("pictures/opentksquare.png"));
textures.Add("pictures/opentksquare2.png", loadImage("pictures/opentksquare2.png"));
TexturedCube tc = new TexturedCube();
tc.TextureID = textures["pictures/opentksquare.png"];
objects.Add(tc);
TexturedCube tc2 = new TexturedCube();
tc2.Position += new Vector3(1f, 1f, 1f);
tc2.TextureID = textures["pictures/opentksquare2.png"];
objects.Add(tc2);
cam.Position += new Vector3(0f, 0f, 3f);
}
protected override void OnRenderFrame(FrameEventArgs e)
{
base.OnRenderFrame(e);
GL.Viewport(0, 0, Width, Height);
GL.Clear(ClearBufferMask.ColorBufferBit | ClearBufferMask.DepthBufferBit);
GL.Enable(EnableCap.DepthTest);
shaders[activeShader].EnableVertexAttribArrays();
int indiceat = 0;
foreach (Volume v in objects)
{
GL.ActiveTexture(TextureUnit.Texture0);
GL.BindTexture(TextureTarget.Texture2D, v.TextureID);
GL.UniformMatrix4(shaders[activeShader].GetUniform("modelview"), false, ref v.ModelViewProjectionMatrix);
if (shaders[activeShader].GetUniform("maintexture") != -1)
{
GL.Uniform1(shaders[activeShader].GetUniform("maintexture"), 0);
}
GL.DrawElements(BeginMode.Triangles, v.IndiceCount, DrawElementsType.UnsignedInt, indiceat * sizeof(uint));
indiceat += v.IndiceCount;
}
shaders[activeShader].DisableVertexAttribArrays();
GL.Flush();
SwapBuffers();
}
private void ProcessInput()
{
if(OpenTK.Input.Keyboard.GetState().IsKeyDown(Key.Escape))
{
Exit();
}
if (OpenTK.Input.Keyboard.GetState().IsKeyDown(Key.W))
{
cam.Move(0f, 0.1f, 0f);
}
if (OpenTK.Input.Keyboard.GetState().IsKeyDown(Key.S))
{
cam.Move(0f, -0.1f, 0f);
}
if (OpenTK.Input.Keyboard.GetState().IsKeyDown(Key.A))
{
cam.Move(-0.1f, 0f, 0f);
}
if (OpenTK.Input.Keyboard.GetState().IsKeyDown(Key.D))
{
cam.Move(0.1f, 0f, 0f);
}
if (OpenTK.Input.Keyboard.GetState().IsKeyDown(Key.Q))
{
cam.Move(0f, 0f, 0.1f);
}
if (OpenTK.Input.Keyboard.GetState().IsKeyDown(Key.E))
{
cam.Move(0f, 0f, -0.1f);
}
if (Focused)
{
Vector2 delta = lastMousePos - new Vector2(OpenTK.Input.Mouse.GetState().X, OpenTK.Input.Mouse.GetState().Y);
lastMousePos += delta;
cam.AddRotation(delta.X, delta.Y);
lastMousePos = new Vector2(OpenTK.Input.Mouse.GetState().X, OpenTK.Input.Mouse.GetState().Y);
}
}
protected override void OnUpdateFrame (FrameEventArgs e){
time += (float)e.Time;
ProcessInput();
// base.OnUpdateFrame();
Vector2[] texcoorddata;
List<Vector3> verts = new List<Vector3>();
List<int> inds = new List<int>();
List<Vector3> colors = new List<Vector3>();
List<Vector2> texcoords = new List<Vector2>();
int vertcount = 0;
foreach (Volume v in objects)
{
verts.AddRange(v.GetVerts().ToList());
inds.AddRange(v.GetIndices(vertcount).ToList());
colors.AddRange(v.GetColorData().ToList());
texcoords.AddRange(v.GetTextureCoords());
texcoorddata = texcoords.ToArray();
// texcoords.AddRange(v.GetTextureCoords());
vertcount += v.VertCount;
}
vertdata = verts.ToArray();
indicedata = inds.ToArray();
coldata = colors.ToArray();
texcoorddata = texcoords.ToArray();
GL.BindBuffer(BufferTarget.ArrayBuffer, shaders[activeShader].GetBuffer("vPosition"));
GL.BufferData<Vector3>(BufferTarget.ArrayBuffer, (IntPtr)(vertdata.Length * Vector3.SizeInBytes), vertdata, BufferUsageHint.StaticDraw);
GL.VertexAttribPointer(shaders[activeShader].GetAttribute("vPosition"), 3, VertexAttribPointerType.Float, false, 0, 0);
if (shaders[activeShader].GetAttribute("vColor") != -1)
{
GL.BindBuffer(BufferTarget.ArrayBuffer, shaders[activeShader].GetBuffer("vColor"));
GL.BufferData<Vector3>(BufferTarget.ArrayBuffer, (IntPtr)(coldata.Length * Vector3.SizeInBytes), coldata, BufferUsageHint.StaticDraw);
GL.VertexAttribPointer(shaders[activeShader].GetAttribute("vColor"), 3, VertexAttribPointerType.Float, true, 0, 0);
}
if (shaders[activeShader].GetAttribute("texcoord") != -1)
{
GL.BindBuffer(BufferTarget.ArrayBuffer, shaders[activeShader].GetBuffer("texcoord"));
GL.BufferData<Vector2>(BufferTarget.ArrayBuffer, (IntPtr)(texcoorddata.Length * Vector2.SizeInBytes), texcoorddata, BufferUsageHint.StaticDraw);
GL.VertexAttribPointer(shaders[activeShader].GetAttribute("texcoord"), 2, VertexAttribPointerType.Float, true, 0, 0);
}
// objects[0].Position = new Vector3(0.3f, -0.5f + (float) Math.Sin(time), -3.0f);
objects[0].Rotation = new Vector3(0.55f * time, 0.25f * time, 0);
objects[0].Scale = new Vector3(1, 1, 1);
objects[1].Position = new Vector3(-5f, 0.5f + (float)Math.Cos(time), -2.0f);
objects[1].Rotation = new Vector3(-0.25f * time, -0.35f * time, 0);
objects[1].Scale = new Vector3(2, 1, 2);
foreach (Volume v in objects)
{
v.CalculateModelMatrix();
v.ViewProjectionMatrix = cam.GetViewMatrix() * Matrix4.CreatePerspectiveFieldOfView(1.3f, ClientSize.Width / (float)ClientSize.Height, 1.0f, 40.0f);
v.ModelViewProjectionMatrix = v.ModelMatrix * v.ViewProjectionMatrix;
}
//GL.UniformMatrix4(uniform_mview, false, ref mviewdata[0]);
GL.UseProgram(shaders[activeShader].ProgramID);
GL.BindBuffer(BufferTarget.ArrayBuffer, 0);
GL.BindBuffer(BufferTarget.ElementArrayBuffer, ibo_elements);
GL.BufferData(BufferTarget.ElementArrayBuffer, (IntPtr)(indicedata.Length * sizeof(int)), indicedata, BufferUsageHint.StaticDraw);
}
protected override void OnResize(EventArgs e)
{
base.OnResize(e);
GL.Viewport(ClientRectangle.X, ClientRectangle.Y, ClientRectangle.Width, ClientRectangle.Height);
Matrix4 projection = Matrix4.CreatePerspectiveFieldOfView((float)Math.PI / 4, Width / (float)Height, 1.0f, 64.0f);
GL.MatrixMode(MatrixMode.Projection);
GL.LoadMatrix(ref projection);
}
void loadShader(String filename,ShaderType type, int program, out int address)
{
address = GL.CreateShader(type);
try{
using (StreamReader sr = new StreamReader(filename))
{
GL.ShaderSource(address, sr.ReadToEnd());
}
}
catch (Exception ex){
Console.WriteLine("error loading shader : " + ex);
}
GL.CompileShader(address);
GL.AttachShader(program, address);
Console.WriteLine(GL.GetShaderInfoLog(address));
}
///
///This function will load an image as a bitmap,
/// and then store the data of it in the graphics
/// card's memory. It returns an int, the address
/// of the texture so that we can retrieve the data
/// when we want to draw the texture.
int loadImage(Bitmap image){
int texID = GL.GenTexture();
GL.BindTexture(TextureTarget.Texture2D, texID);
BitmapData data = image.LockBits(new System.Drawing.Rectangle(0, 0, image.Width, image.Height),
ImageLockMode.ReadOnly, System.Drawing.Imaging.PixelFormat.Format32bppArgb);
GL.TexImage2D(TextureTarget.Texture2D, 0, PixelInternalFormat.Rgba, data.Width, data.Height, 0,
OpenTK.Graphics.OpenGL.PixelFormat.Bgra, PixelType.UnsignedByte, data.Scan0);
image.UnlockBits(data);
GL.GenerateMipmap(GenerateMipmapTarget.Texture2D);
return texID;
}
int loadImage(string filename)
{
try
{
Bitmap file = new Bitmap(filename);
return loadImage(file);
}
catch (Exception e)
{
Console.WriteLine(e);
return -1;
}
}
}
}
You can see all my referances for the project in the picture

The mistake is very simple. The attribute TextureID exists twice. Fist it is declared in the class Volume:
public abstract class Volume
{
// [...]
public int TextureID;
// [...]
}
Then an attribute with the same name is declared in the class TexturedCube, which is (indirectly) derived from Volume:
public class TexturedCube : Cube
{
// [...]
public int TextureID;
// [...]
}
Hence the 2nd attribute covers the 1st one. Remove the attribute from the class TexturedCube:
By the way, the same applies to the IsTextured and TextureCoordsCount attribute.

Related

OpenTK doesn't render the color of my triangle

I am learning to program a game engine which is why I followed a tutorial, with that tutorial I have gotten this far and even though my code is identical to theirs (theirs did work in the videos) its not working the way it is meant to. The triangle stays black no matter what. There is not any errors.
Main Program Script:
using System;
using OpenTK.Mathematics;
using OpenTK.Windowing.Desktop;
using OpenTK.Windowing.Common;
using System.Drawing;
using OpenTK.Graphics.OpenGL4;
using System.IO;
namespace Game_Engine
{
public static class Program
{
static void Main(string[] args)
{
Console.WriteLine("Hello World!");
GameWindowSettings gws = GameWindowSettings.Default;
NativeWindowSettings nws = NativeWindowSettings.Default;
gws.IsMultiThreaded = false;
gws.RenderFrequency = 60;
gws.UpdateFrequency = 60;
nws.APIVersion = Version.Parse("4.1.0");
nws.AutoLoadBindings = true;
nws.Size = new Vector2i(1280, 720);
nws.Title = "Horizon";
GameWindow window = new GameWindow(gws, nws);
window.UpdateFrame += (FrameEventArgs args) => {
};
ShaderProgram shaderProgram = new ShaderProgram(){id = 0};
window.Load += () =>
{
Console.WriteLine("Hello");
ShaderProgram shaderProgram = LoadShaderProgram("../../../../vertex_shader.glsl", "../../../../fragment_shader.glsl");
};
window.RenderFrame += (FrameEventArgs args) =>
{
GL.UseProgram( shaderProgram.id );
GL.ClearColor(1.0f, 0.0f, 0.0f, 0.0f);
GL.Clear(ClearBufferMask.ColorBufferBit);
float[] verts = { -0.5f, -0.5f, 0.0f, 0.5f, -0.5f, 0.0f, 0.0f, 0.5f, 0.0f };
float[] color = { 1f, 0, 0, 0, 1f ,0 ,0, 0, 1f };
int vao = GL.GenVertexArray();
int vertices = GL.GenBuffer();
int colors = GL.GenBuffer();
GL.BindVertexArray(vao);
GL.BindBuffer(BufferTarget.ArrayBuffer, vertices);
GL.BufferData( BufferTarget.ArrayBuffer, verts.Length * sizeof(float), verts, BufferUsageHint.StaticCopy);
GL.EnableVertexAttribArray( 0 );
GL.VertexAttribPointer( 0, 3, VertexAttribPointerType.Float, false, 0, 0 );
GL.BindBuffer(BufferTarget.ArrayBuffer, colors);
GL.BufferData(BufferTarget.ArrayBuffer, color.Length * sizeof(float), color, BufferUsageHint.StaticCopy);
GL.EnableVertexAttribArray(1);
GL.VertexAttribPointer(1, 3, VertexAttribPointerType.Float, false, 0, 0);
GL.DrawArrays(PrimitiveType.Triangles, 0, 3);
GL.BindBuffer(BufferTarget.ArrayBuffer, 0);
GL.BindVertexArray(0);
GL.DeleteBuffer(vertices);
GL.DeleteBuffer(colors);
GL.DeleteVertexArray( vao );
window.SwapBuffers();
};
window.Run();
}
private static Shader LoadShader(string shaderLocation, ShaderType type)
{
int shaderId = GL.CreateShader( type );
GL.ShaderSource( shaderId, File.ReadAllText( shaderLocation ) );
GL.CompileShader( shaderId );
string infoLog = GL.GetShaderInfoLog( shaderId );
if (!string.IsNullOrEmpty(infoLog))
{
throw new Exception(infoLog);
}
return new Shader() { id = shaderId };
}
private static ShaderProgram LoadShaderProgram( string vertextShaderLocation, string fragmentShaderLocation)
{
int shaderProgramId = GL.CreateProgram();
Shader vertextShader = LoadShader(vertextShaderLocation, ShaderType.VertexShader);
Shader fragmentShader = LoadShader(fragmentShaderLocation, ShaderType.FragmentShader);
GL.AttachShader(shaderProgramId, vertextShader.id);
GL.AttachShader(shaderProgramId, fragmentShader.id);
GL.LinkProgram(shaderProgramId);
GL.DetachShader(shaderProgramId, vertextShader.id);
GL.DetachShader(shaderProgramId, fragmentShader.id);
GL.DeleteShader(vertextShader.id);
GL.DeleteShader(fragmentShader.id);
string infoLog = GL.GetProgramInfoLog(shaderProgramId);
if (!string.IsNullOrEmpty(infoLog))
{
throw new Exception(infoLog);
}
return new ShaderProgram() { id = shaderProgramId };
}
public struct Shader
{
public int id;
}
public struct ShaderProgram
{
public int id;
}
}
}
Fragment Shader (in glsl):
#version 400
in vec3 color_in;
out vec4 color_out;
void main(){
color_out = vec4(color_in.r, color_in.g, color_in.b, 1);
}
VertexShader (in glsl):
#version 330
layout(location = 0) in vec3 vPosition;
layout(location = 1) in vec3 vColors;
out vec3 color_in;
void main() {
color_in = vColors;
gl_Position = vec4( vPosition, 1.0 );
}
I have tried everything I could with my very limited knowledge of OpenTK and nothing has changed. I have searched on the web and for answer they still have not helped
You actually assign the shader program to a local variable in the event callback function's scope. You need to assign it to the variable in scope of Main:
ShaderProgram shaderProgram = new ShaderProgram() { id = 0 };
window.Load += () =>
{
Console.WriteLine("Hello");
// ShaderProgram shaderProgram = LoadShaderProgram("../../../../vertex_shader.glsl", "../../../../fragment_shader.glsl");
shaderProgram = LoadShaderProgram("../../../../vertex_shader.glsl", "../../../../fragment_shader.glsl");
};

SharpDX draw multiple primitives at the same time

I am trying to create a high level API with sharpdx. It has to be able to draw, but I am stuck on how to make it work with multiple Draw calls at the same time.
This is how I call the class
DirectXFinalD d33d = new DirectXFinalD();
Here I create a new object of the type viereck(rectangle)
Viereck viereck = new Viereck(0, 0, 0.2, 0.1, myBrush, myBrush, 1, false);
Here I pass the object to the class
d33d.DrawDirectX(viereck);
And it already works, but the problem is, I want it to be able that you can pass more objects at any given time, and let them be drawn.
I already tried to always update the vertexbuffer and always += the vertices, but the problem is that different shapes need different topologies. Here is the class:
namespace DrawHost
{
public class DirectXFinalD : DrawHost.DirectXBaseD<D3D11>, IDrawable
{
;
public DirectXFinalD(IDrawable objectToDraw = null, DataStream stream = null)
{
this.objectToDraw = objectToDraw;
if (stream == null)
stream = new DataStream(32 * 612500, true, true);
else
this.stream = stream;
}
protected override void Attach()
{
#region Shader
if (Renderer == null)
return;
device = Renderer.Device;
context = device.ImmediateContext;
// Compile Vertex and Pixel shaders
vertexShaderByteCode = ShaderBytecode.CompileFromFile("MiniTri.fx", "VS", "vs_4_0", ShaderFlags.None, EffectFlags.None);
vertexShader = new VertexShader(device, vertexShaderByteCode);
pixelShaderByteCode = ShaderBytecode.CompileFromFile("MiniTri.fx", "PS", "ps_4_0", ShaderFlags.None, EffectFlags.None);
pixelShader = new PixelShader(device, pixelShaderByteCode);
// Layout from VertexShader input signature
layout = new InputLayout(device, ShaderSignature.GetInputSignature(vertexShaderByteCode), new[] {
new InputElement("POSITION",0,Format.R32G32B32A32_Float,0,0),
new InputElement("COLOR",0,Format.R32G32B32A32_Float,16,0)
});
#endregion
if (objectToDraw == null) { }
else
{
float r = 0;
float g = 0;
float b = 0;
switch (objectToDraw.ToString())
{
#region Dreieck
case "Dreieck":
Dreieck dreieck = (Dreieck)objectToDraw;
topology = PrimitiveTopology.TriangleStrip;
ConvertColor(ref r, ref g, ref b, ((System.Windows.Media.SolidColorBrush)dreieck.Color).Color);
streamList.Add(new Vector4((Convert.ToSingle(dreieck.X)), (Convert.ToSingle(dreieck.Y) / 10), 0f, 1.0f)); streamList.Add(new Vector4(r, g, b, 1.0f));
streamList.Add(new Vector4(((Convert.ToSingle(dreieck.X) + Convert.ToSingle(dreieck.Width))), -(Convert.ToSingle(dreieck.Y)), 0f, 1.0f)); streamList.Add(new Vector4(r, g, b, 1.0f));
streamList.Add(new Vector4(-(Convert.ToSingle(dreieck.X)), -((Convert.ToSingle(dreieck.Y) + Convert.ToSingle(dreieck.Height) )), 0f, 1.0f)); streamList.Add(new Vector4(r, g, b, 1.0f));
break;
#endregion
#region Viereck
case "Viereck":
Viereck viereck = (Viereck)objectToDraw;
topology = PrimitiveTopology.TriangleStrip;
ConvertColor(ref r, ref g, ref b, ((System.Windows.Media.SolidColorBrush)viereck.Color).Color);
streamList.Add(new Vector4((Convert.ToSingle(viereck.X)), (Convert.ToSingle(viereck.Y)), 0f, 1.0f)); streamList.Add(new Vector4(r, g, b, 1.0f));// ok
streamList.Add(new Vector4(((Convert.ToSingle(viereck.X))), (Convert.ToSingle(viereck.Y) + Convert.ToSingle(viereck.Height)), 0f, 1.0f)); streamList.Add(new Vector4(r, g, b, 1.0f));// ok
streamList.Add(new Vector4((Convert.ToSingle(viereck.X) + Convert.ToSingle(viereck.Width)), (Convert.ToSingle(viereck.Y) ), 0f, 1.0f)); streamList.Add(new Vector4(r, g, b, 1.0f));// ok
streamList.Add(new Vector4((Convert.ToSingle(viereck.X) + Convert.ToSingle(viereck.Width)), ((Convert.ToSingle(viereck.Y) + Convert.ToSingle(viereck.Height))), 0f, 1.0f)); streamList.Add(new Vector4(r, g, b, 1.0f));// ok
break;
#endregion
#region Kreis
case "Kreis":
topology = PrimitiveTopology.Undefined;
Kreis kreis = (Kreis)objectToDraw;
ConvertColor(ref r, ref g, ref b, ((System.Windows.Media.SolidColorBrush)kreis.Color).Color);
for (float j = 0; j <= 360; j++)
{
for (double i = 0; i <= 360; i++) //254
{
double rad = i * (Math.PI / 180);
float x = (float)Math.Cos(rad) * ((float)kreis.Width / 2);
float y = (float)Math.Sin(rad) * ((float)kreis.Height / 2);
streamList.Add(new Vector4(x , y, 0f, 1.0f)); streamList.Add(new Vector4(r, g, b, 1.0f));
}
}
break;
#endregion
};
foreach (Vector4 a in streamList)
{
stream.WriteRange(new[] { a });
}
stream.Position = 0;
streamGV streamGV = new streamGV(stream);
//streamGV.GetList(streamList);
//streamList = null;
GC.Collect();
}
vertices = new Buffer(device, stream, new BufferDescription()
{
BindFlags = BindFlags.VertexBuffer,
CpuAccessFlags = CpuAccessFlags.None,
OptionFlags = ResourceOptionFlags.None,
SizeInBytes = (int)stream.Length,
Usage = ResourceUsage.Default,
StructureByteStride = 0,
});
stream.Dispose();
// Prepare All the stages
context.InputAssembler.InputLayout = (layout);
context.InputAssembler.PrimitiveTopology = topology;
context.InputAssembler.SetVertexBuffers(0, new VertexBufferBinding(vertices, 32, 0));
context.VertexShader.Set(vertexShader);
context.PixelShader.Set(pixelShader);
}
public override void RenderScene(DrawEventArgs args)
{
Renderer.Device.ImmediateContext.ClearRenderTargetView(Renderer.RenderTargetView, new Color4(0.6f, 0, 0, 0));
Renderer.Device.ImmediateContext.Draw((int)stream.Length, 0);
return;
}
public override void Case(DXElement dxviewer)
{
dxviewer11 = dxviewer;
}
public override void DrawDirectX(IDrawable objectToDraw)
{
this.objectToDraw = objectToDraw;
//dxviewer11.Renderer = new Scene_11();
//Renderer = new D3D11();
stream = new DataStream(32 * 612500, true, true);
streamGV strean = new streamGV();
dxviewer11.Renderer = new DirectXFinalD(objectToDraw, stream) { Renderer = new D3D11() };
}
private void ConvertColor(ref float r, ref float g, ref float b, System.Windows.Media.Color color)
{
r = (float)(color.R * 255);
g = (float)(color.G * 255);
b = (float)(color.B * 255);
}
}
How can I make it possible to draw all of them at the same time? I am using sharpdx as my renderform. One problem is that I always have to change the topology, for example triangle needs trianglelistbut for the circle I use Linestrip. Any help would be appreciated
As I can see you're calling the Attach ones. In this attach method you're only creating 1 vertex buffer, with a mesh depending on objectToDraw.
You should decouple you shader compilation code and your vertexbuffer setup.
You could create a class that will manage the vertexbuffer and 'knows' how to draw the mesh.
For example: (PSEUDO)
[StructLayout(LayoutKind.Sequential)]
public struct Vertex
{
public const int Stride = 16 + 16;
public Vector4 Pos;
public Color4 Color;
}
public class Mesh
{
private Vertex[] _vertices;
private int[] _indices;
private SharpDX.Direct3D11.Buffer _indexBuffer;
private SharpDX.Direct3D11.Buffer _vertexBuffer;
private VertexBufferBinding _vertexBufferBinding;
public Mesh(Vertex[] vertices, int[] indices)
{
// save the vertices in a field
_vertices = value;
var vbd = new BufferDescription(
SharpDX.Utilities.SizeOf<Vertex>() * _vertices.Length,
ResourceUsage.Immutable,
BindFlags.VertexBuffer,
CpuAccessFlags.None,
ResourceOptionFlags.None,
0);
// setup the vertex buffer
_vertexBuffer = SharpDX.Direct3D11.Buffer.Create<Vertex>(DX11.Device, _vertices, vbd);
// create the binding
_vertexBufferBinding = new VertexBufferBinding(_vertexBuffer, Vertex.Stride, 0);
_indices = value;
var ibd = new BufferDescription(
sizeof(int) * _indices.Length,
ResourceUsage.Immutable,
BindFlags.IndexBuffer,
CpuAccessFlags.None,
ResourceOptionFlags.None,
0);
// setup the index buffer
_indexBuffer = SharpDX.Direct3D11.Buffer.Create<int>(DX11.Device, _indices, ibd);
}
// the SelectBuffers will select the right vertex buffer.
// this could be combined with the Draw method, but I rather not
// You should call this ones even when you draw multiple the same mesh.
public void SelectBuffers()
{
DX11.Device.ImmediateContext.InputAssembler.SetVertexBuffers(0, _vertexBufferBinding);
DX11.Device.ImmediateContext.InputAssembler.SetIndexBuffer(_indexBuffer, SharpDX.DXGI.Format.R32_UInt, 0);
}
public void Draw()
{
DX11.Device.ImmediateContext.DrawIndexed(_indices.Length, 0, 0);
}
}
List<Mesh> _meshes = new List<Mesh>();
public void SetupShaders()
{
vertexShaderByteCode = ShaderBytecode.CompileFromFile("MiniTri.fx", "VS", "vs_4_0", ShaderFlags.None, EffectFlags.None);
vertexShader = new VertexShader(device, vertexShaderByteCode);
pixelShaderByteCode = ShaderBytecode.CompileFromFile("MiniTri.fx", "PS", "ps_4_0", ShaderFlags.None, EffectFlags.None);
...... etc
}
public Mesh SetupMesh(object objectToDraw)
{
switch(.....)
{
// .. implement your beautiful switch ;-)
}
return new Mesh(vertices, indices);
}
public void Init()
{
SetupShaders();
_meshes.Add(SetupMesh(new Dreieck(.....)));
_meshes.Add(SetupMesh(new Viereck(.....)));
_meshes.Add(SetupMesh(new Kreis(.....)));
}
public override void RenderScene(DrawEventArgs args)
{
Renderer.Device.ImmediateContext.ClearRenderTargetView(Renderer.RenderTargetView, new Color4(0.6f, 0, 0, 0));
foreach(var mesh in _meshes)
{
mesh.SelectBuffers();
mesh.Draw();
}
return;
}
Something like that...

How to draw a 3D Hectogon using OpenTK C#

I have generated a 2D Hectogon in my scene view, however I am now confused as to how to make the shape three dimensional. Any help in the maths or method that is used to calculate this would be greatly appreciated. I have only just started with C# and I feel this is a tall order considering the lack of new relevant content on OpenTk in terms of most of the calls used in most tutorials are now obsolete.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Drawing;
using System.IO;
using OpenTK;
using OpenTK.Input;
using OpenTK.Graphics.OpenGL;
using OpenTK.Graphics;
namespace SimpleGame
{
class Game : GameWindow
{
public Game() : base(1280, 720, new GraphicsMode(32, 24, 0, 4)) // screen resilotion
{
}
int pgmID;
int vsID;
int fsID;
int attribute_vcol;
int attribute_vpos;
int uniform_mview;
int vbo_position;
int vbo_color;
int vbo_mview;
int ibo_elements;
Vector3[] vertdata;
Vector3[] coldata;
Matrix4[] mviewdata;
int[] indicedata;
float time = 0.0f;
void initProgram()
{
pgmID = GL.CreateProgram();
loadShader("F:/Year 1/Semester 2/Simulation In Games/SimpleGame/SimpleGame/vs.glsl", ShaderType.VertexShader, pgmID, out vsID);
loadShader("F:/Year 1/Semester 2/Simulation In Games/SimpleGame/SimpleGame/fs.glsl", ShaderType.FragmentShader, pgmID, out fsID);
GL.LinkProgram(pgmID);
Console.WriteLine(GL.GetProgramInfoLog(pgmID));
attribute_vpos = GL.GetAttribLocation(pgmID, "vPosition");
attribute_vcol = GL.GetAttribLocation(pgmID, "vColor");
uniform_mview = GL.GetUniformLocation(pgmID, "modelview");
GL.GenBuffers(1, out vbo_position);
GL.GenBuffers(1, out vbo_color);
GL.GenBuffers(1, out vbo_mview);
GL.GenBuffers(1, out ibo_elements);
}
protected override void OnLoad(EventArgs e)
{
base.OnLoad(e);
initProgram();
vertdata = new Vector3[] {
//new Vector3(0.0f,0.0f,0.0f), // center
//new Vector3(2.0f, 0f,0f), // right hand side
//new Vector3(0f,2f,0f), // up
new Vector3(0.0f,0.0f,-0.8f), // center point
new Vector3(2.0f,0.0f,-0.8f), // right hand side
new Vector3(1.0f,1.7f,-0.8f), // right hand top
new Vector3(-1.0f,1.7f,-0.8f), // right hand top
new Vector3(-2.0f,0.0f,-0.8f), // left hand top
new Vector3(-1.0f,-1.7f,-0.8f),
new Vector3(1.0f,-1.7f,-0.8f), // right hand top
};
indicedata = new int[]{
//front
0, 1, 2,
0, 2, 3,
//back
0, 3, 4,
0, 4, 5,
//left
0, 5, 6,
0, 6, 1,
};
coldata = new Vector3[] { new Vector3(1f, 0f, 0f),
new Vector3( 0f, 0f, 1f),
new Vector3( 0f, 1f, 0f),new Vector3(1f, 0f, 0f),
new Vector3( 0f, 0f, 1f),
new Vector3( 0f, 1f, 0f),new Vector3(1f, 0f, 0f),
new Vector3( 0f, 0f, 1f)};
mviewdata = new Matrix4[]{
Matrix4.Identity
};
Title = "Hello OpenTK!";
GL.ClearColor(Color.DarkTurquoise);
GL.PointSize(5f);
}
void loadShader(String filename, ShaderType type, int program, out int address)
{
address = GL.CreateShader(type);
using (StreamReader sr = new StreamReader(filename))
{
GL.ShaderSource(address, sr.ReadToEnd());
}
GL.CompileShader(address);
GL.AttachShader(program, address);
Console.WriteLine(GL.GetShaderInfoLog(address));
}
protected override void OnRenderFrame(FrameEventArgs e)
{
base.OnRenderFrame(e);
GL.Viewport(0, 0, Width, Height);
GL.Clear(ClearBufferMask.ColorBufferBit | ClearBufferMask.DepthBufferBit);
GL.Enable(EnableCap.DepthTest);
GL.EnableVertexAttribArray(attribute_vpos);
GL.EnableVertexAttribArray(attribute_vcol);
GL.DrawElements(BeginMode.Triangles, indicedata.Length, DrawElementsType.UnsignedInt, 0);
GL.DisableVertexAttribArray(attribute_vpos);
GL.DisableVertexAttribArray(attribute_vcol);
GL.Flush();
SwapBuffers();
}
protected override void OnUpdateFrame(FrameEventArgs e)
{
base.OnUpdateFrame(e);
GL.BindBuffer(BufferTarget.ArrayBuffer, vbo_position);
GL.BufferData<Vector3>(BufferTarget.ArrayBuffer, (IntPtr)(vertdata.Length * Vector3.SizeInBytes), vertdata, BufferUsageHint.StaticDraw);
GL.VertexAttribPointer(attribute_vpos, 3, VertexAttribPointerType.Float, false, 0, 0);
GL.BindBuffer(BufferTarget.ArrayBuffer, vbo_color);
GL.BufferData<Vector3>(BufferTarget.ArrayBuffer, (IntPtr)(coldata.Length * Vector3.SizeInBytes), coldata, BufferUsageHint.StaticDraw);
GL.VertexAttribPointer(attribute_vcol, 3, VertexAttribPointerType.Float, true, 0, 0);
time += (float)e.Time;
mviewdata[0] = Matrix4.CreateRotationY(0.2f time) Matrix4.CreateRotationX(0.0f time) Matrix4.CreateTranslation(0.0f, -1.0f, -4.0f) *
Matrix4.CreatePerspectiveFieldOfView(1.3f, ClientSize.Width / (float)ClientSize.Height, 1.0f, 40.0f); // rotation
GL.UniformMatrix4(uniform_mview, false, ref mviewdata[0]);
GL.UseProgram(pgmID);
GL.BindBuffer(BufferTarget.ArrayBuffer, 0);
GL.BindBuffer(BufferTarget.ElementArrayBuffer, ibo_elements);
GL.BufferData(BufferTarget.ElementArrayBuffer, (IntPtr)(indicedata.Length * sizeof(int)), indicedata, BufferUsageHint.StaticDraw);
}
}
}
I don't think there is a built in method for creating prisms. A prism based on a heptagon (7-sided polygon) is made up from two heptagons (one on the bottom, one on the top) plus 7 vertical 4-sided polygons. So the algorithm for extruding a prism from a horizontal polygon would be (in pseudo code)
create_prism(bottom : polygon, height : float) : body
var top : polygon
top = bottom.Clone()
for all vertices v of top
v.z = v.z + height
end
var b = new body
b.Add(bottom)
b.Add(top)
for i : integer = 0 to bottom.Count - 1
var j : integer
j = (i + 1) modulo bottom.Count
var side = new polygon[4]
side[0] = bottom[i]
side[1] = bottom[j]
side[2] = top[j]
side[3] = top[i]
b.Add(side)
end
return b
end

Texturing primitives with custom vertex declaration

I'm having a problem with XNA 4.0 and couldn't even google it. It occurs in my main project as well as in my test project which is very plain version to reduce unnecessary code.
I need to use my own custom vertex declaration and use it to draw textured primitives (or why not models too).
Drawing and texturing works fine with BasicEffect and any built-in vertex declarations (like VertexPositionColorTexture)...but what on earth is wrong that textures aren't drawn properly if I use BasicEffect with my custom vertex declaration? I'd love to keep all combinations of built-in types in one VD. My only idea as a fix is that I should make a new vertex/pixel shader but would it help? And if it would, how should I do it?
I tried to upload images to describe but I'd need at least 10 reputation so I'll explain in words:
With my custom VD, textures of my square (and any other shape) object seems to be tiled instead of scaled/fit. Also, textures won't rotate when I rotate the object.
Here's my custom vertex declaration:
namespace WindowsGame2
{
public struct VertexPositionNormalColorTexture : IVertexType
{
public Vector3 Position;
public Vector3 Normal;
public Color Color;
public Vector2 TextureCoordinate;
VertexDeclaration IVertexType.VertexDeclaration
{
get { return VertexDeclaration; }
}
public readonly static VertexDeclaration VertexDeclaration =
new VertexDeclaration(
new VertexElement(0, VertexElementFormat.Vector3, VertexElementUsage.Position, 0),
new VertexElement(sizeof(float) * 3, VertexElementFormat.Vector3, VertexElementUsage.Normal, 0),
new VertexElement((sizeof(float) * 3) * 2, VertexElementFormat.Color, VertexElementUsage.Color, 0),
new VertexElement((sizeof(float) * 3) * 3, VertexElementFormat.Vector2, VertexElementUsage.TextureCoordinate, 0)
);
public VertexPositionNormalColorTexture(Vector3 p)
{
Position = p;
Normal = Vector3.Zero;
Color = Color.White;
TextureCoordinate = Vector2.Zero;
}
public VertexPositionNormalColorTexture(Vector3 p, Color c)
{
Position = p;
Normal = Vector3.Zero;
Color = c;
TextureCoordinate = Vector2.Zero;
}
public VertexPositionNormalColorTexture(Vector3 p, Vector2 t)
{
Position = p;
Normal = Vector3.Zero;
Color = Color.White;
TextureCoordinate = t;
}
public VertexPositionNormalColorTexture(Vector3 p, Color c, Vector2 t)
{
Position = p;
Normal = Vector3.Zero;
Color = c;
TextureCoordinate = t;
}
public VertexPositionNormalColorTexture(Vector3 p, Vector3 n, Color c)
{
Position = p;
Normal = n;
Color = c;
TextureCoordinate = Vector2.Zero;
}
public VertexPositionNormalColorTexture(Vector3 p, Vector3 n, Vector2 t)
{
Position = p;
Normal = n;
Color = Color.White;
TextureCoordinate = t;
}
public VertexPositionNormalColorTexture(Vector3 p, Vector3 n, Color c, Vector2 t)
{
Position = p;
Normal = n;
Color = c;
TextureCoordinate = t;
}
}
}
And the game class:
using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.GamerServices;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Media;
namespace WindowsGame2
{
public class Game1 : Microsoft.Xna.Framework.Game
{
GraphicsDeviceManager graphics;
SpriteBatch spriteBatch;
ViewerManager viewer;
List<VertexPositionNormalColorTexture> vertices;
List<short> indices;
Texture2D thumbnail;
VertexBuffer vertexBuf;
IndexBuffer indexBuf;
RasterizerState rasterizerState;
BasicEffect basicEffect;
Matrix worldMatrix;
Matrix viewMatrix;
Matrix projectionMatrix;
public Game1()
{
graphics = new GraphicsDeviceManager(this);
Content.RootDirectory = "Content";
}
protected override void Initialize()
{
viewer = new ViewerManager(graphics, new Vector3(0.0f, 0.0f, 5.0f), new Vector3(0.0f, 0.0f, 0.0f), 500);
vertices = new List<VertexPositionNormalColorTexture>() {
new VertexPositionNormalColorTexture(new Vector3(-1, -1, 0), Color.Yellow, new Vector2(0, 1)),
new VertexPositionNormalColorTexture(new Vector3(-1, 1, 0), Color.Yellow, new Vector2(0, 0)),
new VertexPositionNormalColorTexture(new Vector3(1, 1, 0), Color.Yellow, new Vector2(1, 0)),
new VertexPositionNormalColorTexture(new Vector3(-1, -1, 0), Color.Yellow, new Vector2(0, 1)),
new VertexPositionNormalColorTexture(new Vector3(1, 1, 0), Color.Yellow, new Vector2(1, 0)),
new VertexPositionNormalColorTexture(new Vector3(1, -1, 0), Color.Yellow, new Vector2(1, 1)),
};
indices = new List<short>() {
0, 1, 2, 3, 4, 5
};
basicEffect = new BasicEffect(graphics.GraphicsDevice);
worldMatrix = Matrix.CreateTranslation(0.0f, 0.0f, 0.0f) * Matrix.CreateScale(3);
viewMatrix = Matrix.CreateLookAt(new Vector3(0.0f, 0.0f, 5.0f), new Vector3(0.0f, 0.0f, 0.0f), Vector3.Up);
projectionMatrix = Matrix.CreatePerspectiveFieldOfView(MathHelper.ToRadians(90), graphics.GraphicsDevice.Viewport.AspectRatio, 1f, 50f);
vertexBuf = new VertexBuffer(graphics.GraphicsDevice, VertexPositionNormalColorTexture.VertexDeclaration, 500, BufferUsage.WriteOnly);
indexBuf = new IndexBuffer(graphics.GraphicsDevice, IndexElementSize.SixteenBits, 500, BufferUsage.WriteOnly);
rasterizerState = new RasterizerState();
rasterizerState.CullMode = CullMode.None;
base.Initialize();
}
protected override void LoadContent()
{
spriteBatch = new SpriteBatch(GraphicsDevice);
thumbnail = this.Content.Load<Texture2D>("GameThumbnail");
}
protected override void UnloadContent()
{
this.Content.Unload();
}
protected override void Update(GameTime gameTime)
{
if (Keyboard.GetState().IsKeyDown(Keys.Escape))
this.Exit();
base.Update(gameTime);
}
protected override void Draw(GameTime gameTime)
{
GraphicsDevice.Clear(Color.CornflowerBlue);
graphics.GraphicsDevice.RasterizerState = rasterizerState;
basicEffect.World = worldMatrix;
basicEffect.View = viewMatrix;
basicEffect.Projection = projectionMatrix;
basicEffect.VertexColorEnabled = true;
basicEffect.TextureEnabled = true;
basicEffect.Texture = thumbnail;
vertexBuf.SetData<VertexPositionNormalColorTexture>(vertices.ToArray());
indexBuf.SetData<short>(indices.ToArray());
graphics.GraphicsDevice.SetVertexBuffer(vertexBuf);
graphics.GraphicsDevice.Indices = indexBuf;
foreach (EffectPass pass in basicEffect.CurrentTechnique.Passes)
{
pass.Apply();
graphics.GraphicsDevice.DrawUserIndexedPrimitives(
PrimitiveType.TriangleList,
vertices.ToArray(),
0,
vertices.Count,
indices.ToArray(),
0,
2,
VertexPositionNormalColorTexture.VertexDeclaration);
}
graphics.GraphicsDevice.Indices = null;
graphics.GraphicsDevice.SetVertexBuffer(null);
base.Draw(gameTime);
}
}
}
I found out the problem. I allocated too much memory for a vertex which resulted in weird texturing. It's in this part of the vertex declaration:
new VertexElement((sizeof(float) * 3) * 2, VertexElementFormat.Color, VertexElementUsage.Color, 0),
new VertexElement((sizeof(float) * 3) * 3, VertexElementFormat.Vector2, VertexElementUsage.TextureCoordinate, 0)
Size of type Color isn't actually float/int but byte. Therefore I had to put it like this:
new VertexElement((sizeof(float) * 3) * 2 + 4, VertexElementFormat.Vector2, VertexElementUsage.TextureCoordinate, 0)

Texture is lacking colors

I have a following picture:
Window displays two textures, the left texture is generated by binding it to a FBO and rendering to FBO, 50 random triangles.
The right texture is generated by glTexImage2D with full-color image of Mona Lisa, but as you can see the image is lacking red colors, I think the problem is in OpenGL part, since I've investigated bytes that are passed to glTexImage2D and they do contain Red...
Here is C#/Mono/OpenTK source
using System;
using System.Drawing;
using System.Drawing.Imaging;
using System.Drawing.Drawing2D;
using System.Runtime.InteropServices;
using OpenTK;
using OpenTK.Graphics;
using OpenTK.Graphics.OpenGL;
using OpenTK.Platform;
using OpenTK.Platform.X11;
using OpenTK.Input;
using ManOCL;
namespace GlTest
{
public class MainClass: GameWindow
{
public MainClass()
: base(800, 600, new GraphicsMode(new ColorFormat(0, 0, 0, 0), 32, 0))
{
this.VSync = VSyncMode.Off;
}
public uint fbo;
public uint textureA;
public uint textureB;
public int textureAWidth = 1024;
public int textureAHeight = 1024;
public int textureBWidth;
public int textureBHeight;
Random rand = new Random();
protected override void OnLoad(EventArgs e)
{
GL.Enable(EnableCap.Blend);
GL.ShadeModel(ShadingModel.Smooth);
GL.BlendFunc(BlendingFactorSrc.SrcAlpha, BlendingFactorDest.OneMinusSrcAlpha);
GL.Disable(EnableCap.DepthTest);
GL.Disable(EnableCap.CullFace);
// GL.PolygonMode(MaterialFace.Back, PolygonMode.Line);
// Create Color Tex
GL.GenTextures(1, out textureA);
GL.BindTexture(TextureTarget.Texture2D, textureA);
GL.TexImage2D(TextureTarget.Texture2D, 0, PixelInternalFormat.Rgba8, textureAWidth, textureAHeight, 0, OpenTK.Graphics.OpenGL.PixelFormat.Rgba, PixelType.UnsignedByte, IntPtr.Zero);
GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMinFilter, (int) TextureMinFilter.Linear);
GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMagFilter, (int) TextureMagFilter.Linear);
GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureWrapS, (int) TextureWrapMode.ClampToBorder);
GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureWrapT, (int) TextureWrapMode.ClampToBorder);
GL.GenTextures(1, out textureB);
GL.BindTexture(TextureTarget.Texture2D, textureB);
Bitmap bmp = new Bitmap("/Projects/MonaLisa/MonaLisa.bmp");
Console.WriteLine(textureBWidth = bmp.Width);
Console.WriteLine(textureBHeight = bmp.Height);
//get the data out of the bitmap
System.Drawing.Imaging.BitmapData bmpBits = bmp.LockBits
(
new System.Drawing.Rectangle(0,0,textureBWidth, textureBHeight),
System.Drawing.Imaging.ImageLockMode.ReadOnly,
System.Drawing.Imaging.PixelFormat.Format32bppRgb
);
for (int row = 0; row < 1; row++)
{
for (int col = 0; col < 32; col++)
{
Console.WriteLine
(
"{0}, {1}, {2}, {3}",
Marshal.ReadByte(bmpBits.Scan0, (row * textureBWidth + col) * 4 + 0),
Marshal.ReadByte(bmpBits.Scan0, (row * textureBWidth + col) * 4 + 1),
Marshal.ReadByte(bmpBits.Scan0, (row * textureBWidth + col) * 4 + 2),
Marshal.ReadByte(bmpBits.Scan0, (row * textureBWidth + col) * 4 + 3)
);
}
}
Console.WriteLine(bmpBits.Width);
Console.WriteLine(bmpBits.Height);
GL.TexImage2D
(
TextureTarget.Texture2D,
0,
PixelInternalFormat.Rgba,
textureBWidth,
textureBHeight,
0,
OpenTK.Graphics.OpenGL.PixelFormat.Rgba,
PixelType.UnsignedByte,
bmpBits.Scan0
);
// GL.TexImage2D(TextureTarget.Texture2D, 0, PixelInternalFormat.Rgba8, textureBWidth, textureBHeight, 0, OpenTK.Graphics.OpenGL.PixelFormat.Rgba, PixelType.UnsignedByte, IntPtr.Zero);
GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMinFilter, (int) TextureMinFilter.Linear);
GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMagFilter, (int) TextureMagFilter.Linear);
GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureWrapS, (int) TextureWrapMode.ClampToBorder);
GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureWrapT, (int) TextureWrapMode.ClampToBorder);
//free the bitmap data (we dont need it anymore because it has been passed to the OpenGL driver
bmp.UnlockBits(bmpBits);
// Create a FBO and attach the textures
GL.Ext.GenFramebuffers(1, out fbo);
GL.Ext.BindFramebuffer(FramebufferTarget.FramebufferExt, fbo);
GL.Ext.FramebufferTexture2D(FramebufferTarget.FramebufferExt, FramebufferAttachment.ColorAttachment0Ext, TextureTarget.Texture2D, textureA, 0);
#region Test for Error
switch (GL.Ext.CheckFramebufferStatus(FramebufferTarget.FramebufferExt))
{
case FramebufferErrorCode.FramebufferCompleteExt:
{
Console.WriteLine("FBO: The framebuffer is complete and valid for rendering.");
break;
}
case FramebufferErrorCode.FramebufferIncompleteAttachmentExt:
{
Console.WriteLine("FBO: One or more attachment points are not framebuffer attachment complete. This could mean there’s no texture attached or the format isn’t renderable. For color textures this means the base format must be RGB or RGBA and for depth textures it must be a DEPTH_COMPONENT format. Other causes of this error are that the width or height is zero or the z-offset is out of range in case of render to volume.");
break;
}
case FramebufferErrorCode.FramebufferIncompleteMissingAttachmentExt:
{
Console.WriteLine("FBO: There are no attachments.");
break;
}
/* case FramebufferErrorCode.GL_FRAMEBUFFER_INCOMPLETE_DUPLICATE_ATTACHMENT_EXT:
{
Console.WriteLine("FBO: An object has been attached to more than one attachment point.");
break;
}*/
case FramebufferErrorCode.FramebufferIncompleteDimensionsExt:
{
Console.WriteLine("FBO: Attachments are of different size. All attachments must have the same width and height.");
break;
}
case FramebufferErrorCode.FramebufferIncompleteFormatsExt:
{
Console.WriteLine("FBO: The color attachments have different format. All color attachments must have the same format.");
break;
}
case FramebufferErrorCode.FramebufferIncompleteDrawBufferExt:
{
Console.WriteLine("FBO: An attachment point referenced by GL.DrawBuffers() doesn’t have an attachment.");
break;
}
case FramebufferErrorCode.FramebufferIncompleteReadBufferExt:
{
Console.WriteLine("FBO: The attachment point referenced by GL.ReadBuffers() doesn’t have an attachment.");
break;
}
case FramebufferErrorCode.FramebufferUnsupportedExt:
{
Console.WriteLine("FBO: This particular FBO configuration is not supported by the implementation.");
break;
}
default:
{
Console.WriteLine("FBO: Status unknown. (yes, this is really bad.)");
break;
}
}
// using FBO might have changed states, e.g. the FBO might not support stereoscopic views or double buffering
int[] queryinfo = new int[6];
GL.GetInteger(GetPName.MaxColorAttachmentsExt, out queryinfo[0]);
GL.GetInteger(GetPName.AuxBuffers, out queryinfo[1]);
GL.GetInteger(GetPName.MaxDrawBuffers, out queryinfo[2]);
GL.GetInteger(GetPName.Stereo, out queryinfo[3]);
GL.GetInteger(GetPName.Samples, out queryinfo[4]);
GL.GetInteger(GetPName.Doublebuffer, out queryinfo[5]);
Console.WriteLine("max. ColorBuffers: " + queryinfo[0] + " max. AuxBuffers: " + queryinfo[1] + " max. DrawBuffers: " + queryinfo[2] +
"\nStereo: " + queryinfo[3] + " Samples: " + queryinfo[4] + " DoubleBuffer: " + queryinfo[5]);
Console.WriteLine("Last GL Error: " + GL.GetError());
#endregion Test for Error
GL.PushAttrib(AttribMask.ViewportBit);
{
GL.Viewport(0, 0, textureAWidth, textureAHeight);
OpenTK.Matrix4 orthogonal = OpenTK.Matrix4.CreateOrthographicOffCenter(0, 1, 0, 1, -3, 3);
GL.MatrixMode(MatrixMode.Projection);
GL.LoadMatrix(ref orthogonal);
Matrix4 lookat = Matrix4.LookAt(0, 0, 1, 0, 0, 0, 0, 1, 0);
GL.MatrixMode(MatrixMode.Modelview);
GL.LoadMatrix(ref lookat);
// clear the screen in red, to make it very obvious what the clear affected. only the FBO, not the real framebuffer
GL.ClearColor(0f, 0f, 0f, 0f);
GL.Clear(ClearBufferMask.ColorBufferBit);
// smack 50 random triangles into the FBO's textures
GL.Begin(BeginMode.Triangles);
{
for (int i = 0; i < 50; i++)
{
GL.Color4(((float)(rand.NextDouble())), ((float)(rand.NextDouble())), ((float)(rand.NextDouble())), ((float)(rand.NextDouble())));
GL.Vertex3(((float)(rand.NextDouble())), ((float)(rand.NextDouble())), 0);
GL.Color4(((float)(rand.NextDouble())), ((float)(rand.NextDouble())), ((float)(rand.NextDouble())), ((float)(rand.NextDouble())));
GL.Vertex3(((float)(rand.NextDouble())), ((float)(rand.NextDouble())), 0);
GL.Color4(((float)(rand.NextDouble())), ((float)(rand.NextDouble())), ((float)(rand.NextDouble())), ((float)(rand.NextDouble())));
GL.Vertex3(((float)(rand.NextDouble())), ((float)(rand.NextDouble())), 0);
}
}
GL.End();
}
GL.PopAttrib();
GL.Ext.BindFramebuffer(FramebufferTarget.FramebufferExt, 0); // disable rendering into the FBO
GL.ClearColor(1f, 1f, 1f, 0.0f);
GL.Color3(1f, 1f, 1f);
GL.Enable(EnableCap.Texture2D); // enable Texture Mapping
GL.BindTexture(TextureTarget.Texture2D, 0); // bind default texture
// IntPtr cglContext = Monobjc.OpenGL.CGL.GetCurrentContext();
//
// IntPtr cglShareGroup = Monobjc.OpenGL.CGL.GetShareGroup(cglContext);
//
// ManOCL.Context.ShareWithCGL(cglShareGroup);
//
// Kernel kernel = ManOCL.Kernel.Create
// (
// "kernel1",
// #"__kernel void kernel1(__global int *srcimg, __global int * output, __global int *smp)
// {
// }",
// new Argument[]
// {
// DeviceGlobalMemory.CreateFromArray(new int[1]),
// DeviceGlobalMemory.CreateFromArray(new int[2]),
// DeviceGlobalMemory.CreateFromArray(new int[1])
// }
// );
// Console.WriteLine("Success!");
// Console.WriteLine(kernel);
}
protected override void OnUnload(EventArgs e)
{
// Clean up what we allocated before exiting
GL.DeleteTextures(1, ref textureA);
GL.DeleteTextures(1, ref textureB);
GL.Ext.DeleteFramebuffers(1, ref fbo);
base.OnUnload(e);
}
protected override void OnResize (EventArgs e)
{
GL.Viewport(0, 0, Width, Height);
double aspect_ratio = Width / (double)Height;
OpenTK.Matrix4 perspective = OpenTK.Matrix4.CreatePerspectiveFieldOfView(MathHelper.PiOver4 * 3 / 2, (float)aspect_ratio, 1, 64);
GL.MatrixMode(MatrixMode.Projection);
GL.LoadMatrix(ref perspective);
Matrix4 lookat = Matrix4.LookAt(0, 0, 3, 0, 0, 0, 0, 1, 0);
GL.MatrixMode(MatrixMode.Modelview);
GL.LoadMatrix(ref lookat);
base.OnResize(e);
}
protected override void OnUpdateFrame (FrameEventArgs e)
{
base.OnUpdateFrame(e);
if (Keyboard[Key.Escape])
{
this.Exit();
}
}
protected override void OnRenderFrame(FrameEventArgs e)
{
this.Title = "Frames per Second: " + (1.0 / e.Time);
GL.Clear(ClearBufferMask.ColorBufferBit | ClearBufferMask.DepthBufferBit);
GL.PushMatrix();
{
// Draw the Color Texture
GL.Translate(-1f, 0f, 0f);
GL.BindTexture(TextureTarget.Texture2D, textureA);
GL.Begin(BeginMode.Quads);
{
GL.TexCoord2(0f, 1f);
GL.Vertex2(-1.0f, 1.0f);
GL.TexCoord2(0.0f, 0.0f);
GL.Vertex2(-1.0f, -1.0f);
GL.TexCoord2(1.0f, 0.0f);
GL.Vertex2(1.0f, -1.0f);
GL.TexCoord2(1.0f, 1.0f);
GL.Vertex2(1.0f, 1.0f);
}
GL.End();
GL.Translate(2f, 0f, 0f);
GL.BindTexture(TextureTarget.Texture2D, textureB);
GL.Begin(BeginMode.Quads);
{
GL.TexCoord2(0f, 0f);
GL.Vertex2(-1.0f, 1.0f);
GL.TexCoord2(0.0f, 1.0f);
GL.Vertex2(-1.0f, -1.0f);
GL.TexCoord2(1.0f, 1.0f);
GL.Vertex2(1.0f, -1.0f);
GL.TexCoord2(1.0f, 0.0f);
GL.Vertex2(1.0f, 1.0f);
}
GL.End();
GL.Translate(0f, 0f, 0f);
}
GL.PopMatrix();
this.SwapBuffers();
}
#region public static void Main()
/// <summary>
/// Entry point of this example.
/// </summary>
[STAThread]
public static void Main()
{
using (MainClass example = new MainClass())
{
example.Title = "FrameBufferObjects";
example.Run(1.0, 0.0);
}
}
#endregion
}
}
In the bit of code where you set your texture data:
GL.TexImage2D
(
TextureTarget.Texture2D,
0,
PixelInternalFormat.Rgba,
textureBWidth,
textureBHeight,
0,
OpenTK.Graphics.OpenGL.PixelFormat.Rgba,
PixelType.UnsignedByte,
bmpBits.Scan0
);
Change your pixel format to
OpenTK.Graphics.OpenGL.PixelFormat.Bgra;
Windows bitmaps and opengl have a different endianess on pixels i.e. the bytes are reversed.

Categories