Then get it here.
Yeah I know, but I don't have it here.
Array in constant buffer
"I AM ZE EMPRAH OPENGL 3.3 THE CORE, I DEMAND FROM THEE ZE SHADERZ AND MATRIXEZ"
My journals: dustArtemis ECS framework and Making a Terrain Generator
I have searched for them and the ones I used didn't work. That's why I came here.
Well I tried it but it didn't work. By the way, I did it slightly differently
Anyway, whatever I do, it's always a black screen.
This is why people keep asking for source. All anyone can do without it is blindly guess and point you to working implementations. If you still can't make it work, then you're obviously doing something wrong. If you want some actual, constructive help, post the code!
--- Official D Blog | Learning D | The One With D | D Bits
Well I'm working on making an simplified example and I'll probably have it ready tomorrow, otherwise it may have to wait until next week.
Well it's a real mess. I've made a simplified example - about as simple as I think it could even be. As it turns out, I'm not even sure my constant buffer data is getting through at all! (Except that I'm pretty sure the transformation matrix is going through, otherwise how would the multiplication work? And it usually does, but right now I can't tell because the screen is black anyway.)
This is some test code I've written to draw a single triangle using a constant buffer. Don't worry about the texture coordinates, because it's ignoring them, but they never interfered with anything anyway. All I'm trying to do is put a test color into the constant buffer and make the pixel shader always output that color, so that it just draws one triangle that is that color:
using SharpDX;
using SharpDX.Direct3D;
using SharpDX.Direct3D11;
using SharpDX.DXGI;
using SharpDX.Windows;
using SharpDX.D3DCompiler;
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace test_namespace
{
class Test
{
[StructLayout(LayoutKind.Explicit, Size = 80, Pack = 16)]
public struct Data
{
[FieldOffset(0)]
public Matrix mat;
[FieldOffset(64)]
public Vector4 testColor;
}
[StructLayout(LayoutKind.Explicit)]
public struct Point
{
[FieldOffset(0)]
public Vector4 pos;
[FieldOffset(16)]
public Vector2 tex;
}
int width = 1000;
int height = 1000;
const int vertSize = 6 * sizeof(float);
RenderForm form;
PictureBox pic;
SharpDX.Direct3D11.Device dev;
DeviceContext dc;
SwapChainDescription scd;
SwapChain sc;
RasterizerStateDescription rsd;
RasterizerState rs;
Viewport vp;
Texture2DDescription depthDesc;
DepthStencilView dsv;
RenderTargetView rtv;
SharpDX.Direct3D11.Buffer buffer;
InputLayout il;
VertexShader vs;
ShaderBytecode vsCode;
PixelShader ps;
ShaderBytecode psCode;
Matrix view;
Matrix proj;
Matrix mat;
Data data;
DataStream pointStream;
SharpDX.Direct3D11.Buffer pointBuffer;
public Test()
{
init();
initMat();
data.testColor = new Vector4(1.0f, 0.5f, 0.25f, 0.0f);
string code = "struct vert { float4 pos : POSITION; float2 tex : TEXCOORD; };\n"
+ "struct pix { float4 pos : SV_POSITION; float2 tex : TEXCOORD; };\n"
+ "cbuffer buf1 : register(b0) { float4x4 mat; float4 testColor; }\n"
+ "pix VS(vert vertIn) { pix pixOut = (pix)0; pixOut.pos = mul(vertIn.pos, mat); pixOut.tex = vertIn.tex; return pixOut; }\n"
+ "float4 PS(pix pixIn) : SV_Target { return testColor; }";
vsCode = ShaderBytecode.Compile(code, "VS", "vs_5_0");
vs = new VertexShader(dev, vsCode);
psCode = ShaderBytecode.Compile(code, "PS", "ps_5_0");
ps = new PixelShader(dev, psCode);
dc.VertexShader.Set(vs);
dc.PixelShader.Set(ps);
il = new InputLayout(dev, ShaderSignature.GetInputSignature(vsCode),
new InputElement[] {new InputElement("POSITION", 0, Format.R32G32B32_Float, 0, 0),
new InputElement("TEXCOORD", 0, Format.R32G32_Float, 16, 0)});
dc.InputAssembler.InputLayout = il;
dc.InputAssembler.PrimitiveTopology = PrimitiveTopology.TriangleList;
updateBuffer();
RenderLoop.Run(form, () =>
{
dc.ClearDepthStencilView(dsv, DepthStencilClearFlags.Depth, 1.0f, 0);
dc.ClearRenderTargetView(rtv, Color4.Black);
float dist = 10.0f;
draw(new Vector3(-dist, -dist, dist), Vector2.Zero, new Vector3(-dist, dist, dist), Vector2.UnitY,
new Vector3(dist, dist, dist), Vector2.One);
});
}
void init()
{
form = new RenderForm();
form.ClientSize = new System.Drawing.Size(width, height);
form.BackColor = System.Drawing.Color.Black;
form.FormClosed += form_FormClosed;
pic = new PictureBox();
pic.Location = new System.Drawing.Point(0, 0);
pic.Size = new Size(width, height);
pic.Show();
form.Controls.Add(pic);
scd = new SwapChainDescription();
scd.BufferCount = 1;
scd.Flags = SwapChainFlags.AllowModeSwitch;
scd.IsWindowed = true;
scd.ModeDescription = new ModeDescription(width, height, new Rational(60, 1), Format.R8G8B8A8_UNorm);
scd.OutputHandle = pic.Handle;
scd.SampleDescription = new SampleDescription(1, 0);
scd.SwapEffect = SwapEffect.Discard;
scd.Usage = Usage.RenderTargetOutput;
rsd = new RasterizerStateDescription();
rsd.CullMode = CullMode.None;
rsd.DepthBias = 0;
rsd.DepthBiasClamp = 0;
rsd.FillMode = FillMode.Solid;
rsd.IsAntialiasedLineEnabled = true;
rsd.IsDepthClipEnabled = true;
rsd.IsFrontCounterClockwise = false;
rsd.IsMultisampleEnabled = true;
rsd.IsScissorEnabled = false;
rsd.SlopeScaledDepthBias = 0;
SharpDX.Direct3D11.Device.CreateWithSwapChain(DriverType.Hardware, DeviceCreationFlags.Debug, scd, out dev, out sc);
rs = new RasterizerState(dev, rsd);
vp = new Viewport(0, 0, width, height, 0.0f, 1.0f);
dc = dev.ImmediateContext;
dc.Rasterizer.State = rs;
dc.Rasterizer.SetViewports(vp);
depthDesc = new Texture2DDescription();
depthDesc.ArraySize = 1;
depthDesc.BindFlags = BindFlags.DepthStencil;
depthDesc.CpuAccessFlags = CpuAccessFlags.None;
depthDesc.Format = Format.D32_Float_S8X24_UInt;
depthDesc.Height = height;
depthDesc.MipLevels = 1;
depthDesc.OptionFlags = ResourceOptionFlags.None;
depthDesc.SampleDescription = new SampleDescription(1, 0);
depthDesc.Usage = ResourceUsage.Default;
depthDesc.Width = width;
dsv = new DepthStencilView(dev, new Texture2D(dev, depthDesc));
rtv = new RenderTargetView(dev, (SharpDX.Direct3D11.Resource)SharpDX.Direct3D11.Resource.FromSwapChain<Texture2D>(sc, 0));
dc.OutputMerger.SetTargets(dsv, rtv);
buffer = new SharpDX.Direct3D11.Buffer(dev, Marshal.SizeOf(typeof(Data)),
ResourceUsage.Default, BindFlags.ConstantBuffer, CpuAccessFlags.None, ResourceOptionFlags.None, 0);
dc.VertexShader.SetConstantBuffer(0, buffer);
}
void initMat()
{
view = Matrix.LookAtLH(Vector3.Zero, Vector3.UnitZ, Vector3.UnitY);
proj = Matrix.PerspectiveFovLH((float)Math.PI / 4.0f, (float)width / (float)height, 0.001f, 10000.0f);
mat = view * proj;
mat.Transpose();
data.mat = mat;
}
void updateBuffer()
{
dc.UpdateSubresource<Data>(ref data, buffer);
}
public void draw(Vector3 p1, Vector2 t1, Vector3 p2, Vector2 t2, Vector3 p3, Vector2 t3)
{
Vector3[] p = new Vector3[3] {p1, p2, p3};
Vector2[] t = new Vector2[3] {t1, t2, t3};
Point[] points = new Point[3];
for(int i = 0; i < 3; i++)
{
points = new Point();
points.pos = new Vector4(p.X, p.Y, p.Z, 1.0f);
points.tex = new Vector2(t.X, t.Y);
}
using(pointStream = new DataStream(vertSize * 3, true, true))
{
pointStream.WriteRange<Point>(points);
using(pointBuffer = new SharpDX.Direct3D11.Buffer(dev, pointStream, vertSize * 3,
ResourceUsage.Default, BindFlags.VertexBuffer, CpuAccessFlags.None, ResourceOptionFlags.None, 0))
{
dc.InputAssembler.PrimitiveTopology = PrimitiveTopology.TriangleList;
dc.InputAssembler.SetVertexBuffers(0, new VertexBufferBinding(pointBuffer, vertSize, 0));
dc.Draw(3, 0);
}
}
}
void form_FormClosed(object sender, FormClosedEventArgs e)
{
buffer.Dispose();
il.Dispose();
ps.Dispose();
psCode.Dispose();
vs.Dispose();
vsCode.Dispose();
rtv.Dispose();
dsv.Dispose();
dc.ClearState();
dc.Flush();
dc.Dispose();
dev.Dispose();
sc.Dispose();
}
}
}
Also, here is the shader code formatted in a more readable way:
struct vert
{
float4 pos : POSITION;
float2 tex : TEXCOORD;
};
struct pix
{
float4 pos : SV_POSITION;
float2 tex : TEXCOORD;
};
cbuffer buf1 : register(b0)
{
float4x4 mat;
float4 testColor;
}
pix VS(vert vertIn)
{
pix pixOut = (pix)0;
pixOut.pos = mul(vertIn.pos, mat);
pixOut.tex = vertIn.tex;
return out;
}
float4 PS(pix pixIn) : SV_Target
{
return testColor;
}
Right now it's just black. I've tried replacing the line in the pixel shader that returns the color by making it return a hard-coded constant color instead. That doesn't work, so I guess something is wrong with it's ability to draw anything at all. I didn't have time to mess with it as much as I'd like, but there's no way around that. I also tried pulling the stuff out of the render loop to see if it would just run once, and calling form.Show(), but that didn't work either.
Anyway, I'm sure getting it to display a triangle is easy and I overlooked something simple, but I don't know what.
Then the next step would be to get it to actually use the testColor variable in the constant buffer to display the color I specify.
Once that works, I need to be able to get an arbitrary number of possibly large arrays into the constant buffer (and make it multiple constant buffers or texture buffers if necessary), and make sure it's still able to read all that data.
If you want to test it, you should be able to just copy all the code into one file, then make another main file that calls the constructor to make the window. It's that simple.
I can't seem to get any of it working though. Does anyone have any ideas?
Well you wanted a code sample. I've made one. It's complete and should compile.
Does anyone have any ideas how to fix it?
Not to rush, but I really would like it soon if possible, because I only have time to work on this on Saturdays, so if I can't fix it by then, it's delayed another week!
God, everyone says post source code, then when I spend hours putting something together that I can post and actually do, I hear no more responses. What happened?
I can guide you through the how-to if you wish (it's usually better to learn the debugging techniques than just be given the solution ).
For the future: You seem to be under a restrictive NDA, so I'd advertise that more clearly (e.g. in your signature). Otherwise your threads will continue to look this way.
God, everyone says post source code, then when I spend hours putting something together that I can post and actually do, I hear no more responses. What happened?
That was just standard advice to make it more likely that someone would be able to help you, not a guarantee. Always keep in mind that there are a number of people coming here from different timezones around the world, with varying skill sets. It sometimes may take a while before someone with the ability to recognize your problem comes along, if at all. Some problems are easier to solve than others, but posting source is a minimal first step.
--- Official D Blog | Learning D | The One With D | D Bits
I know, Aldacron. It's just that I was getting frustrated and perhaps a bit impatient and it had been a few days, and I really wanted a solution by tomorrow.
Thanks, unbird, I'll look at your example. Also, it has occurred to me after looking at another example (a little different because it's C++ and using a buffer description object instead of putting all those parameters directly into the buffer constructor) that maybe part of the problem is that I don't have the cpu access flags set to write, and the usage is not set to dynamic.
Might this be part of the problem and did you change that in the example? (I'll look at your example tomorrow when I have more time).
unbird, thanks a lot! I had a chance to look at your code (I haven't been able to try it out yet, but I'll do that tomorrow).
It looks like you fixed a lot of problems. Would this also work with a tbuffer? Because I was making such big arrays that it was telling me that the cbuffer ran out of memory but then I changed to a tbuffer and stopped getting that error.
Anyway, I can't wait to try it out!