• Announcements

    • khawk

      Download the Game Design and Indie Game Marketing Freebook   07/19/17

      GameDev.net and CRC Press have teamed up to bring a free ebook of content curated from top titles published by CRC Press. The freebook, Practices of Game Design & Indie Game Marketing, includes chapters from The Art of Game Design: A Book of Lenses, A Practical Guide to Indie Game Marketing, and An Architectural Approach to Level Design. The GameDev.net FreeBook is relevant to game designers, developers, and those interested in learning more about the challenges in game development. We know game development can be a tough discipline and business, so we picked several chapters from CRC Press titles that we thought would be of interest to you, the GameDev.net audience, in your journey to design, develop, and market your next game. The free ebook is available through CRC Press by clicking here. The Curated Books The Art of Game Design: A Book of Lenses, Second Edition, by Jesse Schell Presents 100+ sets of questions, or different lenses, for viewing a game’s design, encompassing diverse fields such as psychology, architecture, music, film, software engineering, theme park design, mathematics, anthropology, and more. Written by one of the world's top game designers, this book describes the deepest and most fundamental principles of game design, demonstrating how tactics used in board, card, and athletic games also work in video games. It provides practical instruction on creating world-class games that will be played again and again. View it here. A Practical Guide to Indie Game Marketing, by Joel Dreskin Marketing is an essential but too frequently overlooked or minimized component of the release plan for indie games. A Practical Guide to Indie Game Marketing provides you with the tools needed to build visibility and sell your indie games. With special focus on those developers with small budgets and limited staff and resources, this book is packed with tangible recommendations and techniques that you can put to use immediately. As a seasoned professional of the indie game arena, author Joel Dreskin gives you insight into practical, real-world experiences of marketing numerous successful games and also provides stories of the failures. View it here. An Architectural Approach to Level Design This is one of the first books to integrate architectural and spatial design theory with the field of level design. The book presents architectural techniques and theories for level designers to use in their own work. It connects architecture and level design in different ways that address the practical elements of how designers construct space and the experiential elements of how and why humans interact with this space. Throughout the text, readers learn skills for spatial layout, evoking emotion through gamespaces, and creating better levels through architectural theory. View it here. Learn more and download the ebook by clicking here. Did you know? GameDev.net and CRC Press also recently teamed up to bring GDNet+ Members up to a 20% discount on all CRC Press books. Learn more about this and other benefits here.
Sign in to follow this  
Followers 0
Megafont

DirectX11 SDK Tutorial #6 SlimDX Problem

2 posts in this topic

I've translated the code of DirectX11 SDK tutorial #6 to C# and SlimDX. Unlike the previous tutorials though, I am having a very bizarre problem with this one. Instead of rendering a cube like it should, it just renders large apparently stretched to infinity polygons. Even when I move the Eye and LookAt positions I can't see everything. For example, if I change Y to 100, the polygons seem to be on the same horizontal plane as the Eye and still stretch far off. This output makes no sense whatsoever and after 2 days of screwing with this darn program I still haven't been able to get it to work. Hopefully someone on here might be able to help me solve it.

Here is the code of Program.cs.
[CODE]
using System;
using System.Runtime.InteropServices;
using System.Windows.Forms;
using SlimDX;
using SlimDX.D3DCompiler;
using SlimDX.Direct3D11;
using Buffer = SlimDX.Direct3D11.Buffer; // I added this line to fix ambiguity between SlimDX.Direct3D11.Buffer and System.Buffer. This tells it to use the SlimDX Buffer class rather than the one in the System namespace when I reference the type Buffer.
using SlimDX.DXGI;
using SlimDX.Windows;
using Device = SlimDX.Direct3D11.Device;
using Resource = SlimDX.Direct3D11.Resource;

//--------------------------------------------------------------------------------------
// NOTE:
//--------------------------------------------------------------------------------------
// I modified this program and its shaders.fx file to help with debugging a bug that
// I was having a hell of a time solving. See the note at the top of the shaders.fx
// file for info on changes I made to that file.
//--------------------------------------------------------------------------------------
namespace Test_1
{
struct SimpleVertex
{
Vector3 Position;
Vector3 Normal;
Vector4 Color;
public SimpleVertex(Vector3 position, Vector3 normal, Vector4 color)
{
Position = position;
Normal = normal;
Color = color;
}
};

struct ConstantBuffer
{
public Matrix mWorld;
public Matrix mView;
public Matrix mProjection;
public Vector4[] vLightDir;
public Vector4[] vLightColor;
public Vector4 vOutputColor;

public ConstantBuffer(Matrix world, Matrix view, Matrix projection)
{
mWorld = world;
mView = view;
mProjection = projection;
vLightDir = new Vector4[2];
vLightColor = new Vector4[2];
vOutputColor = new Vector4();
}
};

static class Program
{
static float rotationY = 0.785f; // Y Rotation in radians per second (0.785 radians = 45 degrees)

static int startTime;
static int curTime;

static RenderForm form;
static Buffer constantBuffer;
static Buffer indexBuffer;
static Buffer vertexBuffer;
static DataStream constants;
static DataStream indices;
static DataStream vertices;
static DepthStencilView depthStencilView;
static Device device;
static DeviceContext context;
static InputLayout layout;
static PixelShader pixelShader;
static PixelShader pixelShaderSolid;
static PixelShader pixelShaderColor;
static RenderTargetView renderTarget;
static ShaderSignature inputSignature;
static SwapChain swapChain;
static Texture2D depthStencil;
static VertexShader vertexShader;
static Viewport viewport;
static Matrix matrix_World;
static Matrix matrix_View;
static Matrix matrix_Projection;


static void Main()
{
form = new RenderForm("OMG a Window!!");
var description = new SwapChainDescription()
{
BufferCount = 2,
Usage = Usage.RenderTargetOutput,
OutputHandle = form.Handle,
IsWindowed = true,
ModeDescription = new ModeDescription(0, 0, new Rational(60, 1), Format.R8G8B8A8_UNorm),
SampleDescription = new SampleDescription(1, 0),
Flags = SwapChainFlags.AllowModeSwitch,
SwapEffect = SwapEffect.Discard
};

Device.CreateWithSwapChain(DriverType.Hardware,
DeviceCreationFlags.Debug,
description,
out device,
out swapChain);

// create a view of our render target, which is the backbuffer of the swap chain we just created
using (var resource = Resource.FromSwapChain<Texture2D>(swapChain, 0))
{
renderTarget = new RenderTargetView(device, resource);
};

// Create the depth stencil texture
Texture2DDescription depthStencilDesc = new Texture2DDescription();
depthStencilDesc.Width = form.ClientSize.Width;
depthStencilDesc.Height = form.ClientSize.Height;
depthStencilDesc.MipLevels = 1;
depthStencilDesc.ArraySize = 1;
depthStencilDesc.Format = Format.D24_UNorm_S8_UInt;
depthStencilDesc.SampleDescription = new SampleDescription(1, 0);
depthStencilDesc.Usage = ResourceUsage.Default;
depthStencilDesc.BindFlags = BindFlags.DepthStencil;
depthStencilDesc.CpuAccessFlags = CpuAccessFlags.None;
depthStencilDesc.OptionFlags = ResourceOptionFlags.None;
depthStencil = new Texture2D(device, depthStencilDesc);

// Create the Depth Stencil View
DepthStencilViewDescription depthStencilViewDesc = new DepthStencilViewDescription();
depthStencilViewDesc.Format = depthStencilDesc.Format;
depthStencilViewDesc.Dimension = DepthStencilViewDimension.Texture2D;
depthStencilViewDesc.MipSlice = 0;
depthStencilView = new DepthStencilView(device, depthStencil, depthStencilViewDesc);
// setting a viewport is required if you want to actually see anything
context = device.ImmediateContext;
viewport = new Viewport(0.0f,
0.0f,
form.ClientSize.Width,
form.ClientSize.Height,
0.0f,
1.0f);
context.OutputMerger.SetTargets(depthStencilView, renderTarget);
context.Rasterizer.SetViewports(viewport);

// Setup our shaders
InitShaders();

// Setup our vertex data
InitVertexData();

// Setup our matrices
InitMatrices();

// Set the shaders
context.VertexShader.Set(vertexShader);
context.PixelShader.Set(pixelShader);

// Prevent DXGI handling of Alt+Enter, which doesn't work properly with Winforms
using (var factory = swapChain.GetParent<Factory>())
{
factory.SetWindowAssociation(form.Handle,
WindowAssociationFlags.IgnoreAltEnter);
};

// Handle Alt+Enter ourselves
form.KeyDown += (o, e) =>
{
if (e.Alt && e.KeyCode == Keys.Enter)
{
swapChain.IsFullScreen = !swapChain.IsFullScreen;
}
};

// Handle form size changes
form.UserResized += (o, e) =>
{
renderTarget.Dispose();
depthStencil.Dispose();
depthStencilView.Dispose();

swapChain.ResizeBuffers(2,
0,
0,
Format.R8G8B8A8_UNorm,
SwapChainFlags.AllowModeSwitch);

using (var resource = Resource.FromSwapChain<Texture2D>(swapChain, 0))
{
renderTarget = new RenderTargetView(device, resource);
}

depthStencilDesc.Width = form.ClientSize.Width;
depthStencilDesc.Height = form.ClientSize.Height;
depthStencil = new Texture2D(device, depthStencilDesc);
depthStencilView = new DepthStencilView(device, depthStencil, depthStencilViewDesc);

context.OutputMerger.SetTargets(depthStencilView, renderTarget);
context.Rasterizer.SetViewports(new Viewport(0, 0, form.ClientSize.Width, form.ClientSize.Height, 0.0f, 1.0f));
};
startTime = Environment.TickCount;
MessagePump.Run(form, RenderFrame);


// Clean up all resources
// anything we missed will show up in the IDE's debug output
vertices.Close();
vertexBuffer.Dispose();
layout.Dispose();
inputSignature.Dispose();
vertexShader.Dispose();
pixelShader.Dispose();
renderTarget.Dispose();
swapChain.Dispose();
device.Dispose();
indexBuffer.Dispose();
indices.Dispose();
constantBuffer.Dispose();
constants.Dispose();
depthStencil.Dispose();
depthStencilView.Dispose();
pixelShaderSolid.Dispose();
pixelShaderColor.Dispose();
}

static void InitShaders()
{
// load and compile the vertex shader
string vsCompileError = "Vertex Shader Compile Error!!!";
using (var bytecode = ShaderBytecode.CompileFromFile("shaders.fx", "VS", "vs_4_0", ShaderFlags.EnableStrictness | ShaderFlags.Debug, EffectFlags.None, null, null, out vsCompileError))
{
inputSignature = ShaderSignature.GetInputSignature(bytecode);
vertexShader = new VertexShader(device, bytecode);
}

// load and compile the pixel shader
string psCompileError = "Pixel Shader Compile Error!!!";
using (var bytecode = ShaderBytecode.CompileFromFile("shaders.fx", "PS", "ps_4_0", ShaderFlags.EnableStrictness | ShaderFlags.Debug, EffectFlags.None, null, null, out psCompileError))
{
pixelShader = new PixelShader(device, bytecode);
}
// load and compile the solid pixel shader
psCompileError = "Solid Pixel Shader Compile Error!!!";
using (var bytecode = ShaderBytecode.CompileFromFile("shaders.fx", "PSSolid", "ps_4_0", ShaderFlags.EnableStrictness | ShaderFlags.Debug, EffectFlags.None, null, null, out psCompileError))
{
pixelShaderSolid = new PixelShader(device, bytecode);
}
// load and compile the color pixel shader
psCompileError = "Color Pixel Shader Compile Error!!!";
using (var bytecode = ShaderBytecode.CompileFromFile("shaders.fx", "PSColor", "ps_4_0", ShaderFlags.EnableStrictness | ShaderFlags.Debug, EffectFlags.None, null, null, out psCompileError))
{
pixelShaderColor = new PixelShader(device, bytecode);
}
}
static void InitMatrices()
{
// world matrix
matrix_World = Matrix.Identity;
// view matrix
Vector3 vEye = new Vector3(0.0f, 4.0f, -10.0f);
Vector3 vLookAt = new Vector3(0.0f, 1.0f, 0.0f);
Vector3 vUp = new Vector3(0.0f, 1.0f, 0.0f);
matrix_View = Matrix.LookAtLH(vEye,
vLookAt,
vUp);

// projection matrix
matrix_Projection = Matrix.PerspectiveFovLH((float)Math.PI / 4, // Vertical Field of View
(float)form.ClientSize.Width / (float)form.ClientSize.Height, // Aspect Ratio
0.01f, // Near Z
100.0f); // Far Z

// Write the matrices we just generated into the DataStream
ConstantBuffer cb = new ConstantBuffer(Matrix.Transpose(matrix_World),
Matrix.Transpose(matrix_View),
Matrix.Transpose(matrix_Projection));
constants = new DataStream(Marshal.SizeOf(cb), true, true);
constants.Write<ConstantBuffer>(cb);
constants.Position = 0;

// Create the constant buffer
constantBuffer = new Buffer(device,
constants,
(int)constants.Length,
ResourceUsage.Default,
BindFlags.ConstantBuffer,
CpuAccessFlags.None,
ResourceOptionFlags.None,
0);
context.UpdateSubresource(new DataBox(0, 0, constants),
constantBuffer,
0);
context.VertexShader.SetConstantBuffer(constantBuffer, 0);
}
static void InitVertexData()
{
// Create test vertex data, making sure to rewind the stream afterward.
vertices = new DataStream(Marshal.SizeOf(new SimpleVertex(Vector3.Zero, Vector3.Zero, Vector4.Zero)) * 24, true, true);
SimpleVertex[] tempVertexArray =
{
new SimpleVertex(new Vector3(-1.0f, 1.0f, -1.0f), new Vector3( 0.0f, 1.0f, 0.0f), new Vector4(0.0f, 0.0f, 1.0f, 1.0f)),
new SimpleVertex(new Vector3( 1.0f, 1.0f, -1.0f), new Vector3( 0.0f, 1.0f, 0.0f), new Vector4(0.0f, 1.0f, 0.0f, 1.0f)),
new SimpleVertex(new Vector3( 1.0f, 1.0f, 1.0f), new Vector3( 0.0f, 1.0f, 0.0f), new Vector4(0.0f, 1.0f, 1.0f, 1.0f)),
new SimpleVertex(new Vector3(-1.0f, 1.0f, 1.0f), new Vector3( 0.0f, 1.0f, 0.0f), new Vector4(1.0f, 0.0f, 0.0f, 1.0f)),
new SimpleVertex(new Vector3(-1.0f, -1.0f, -1.0f), new Vector3( 0.0f, -1.0f, 0.0f), new Vector4(1.0f, 0.0f, 1.0f, 1.0f)),
new SimpleVertex(new Vector3( 1.0f, -1.0f, -1.0f), new Vector3( 0.0f, -1.0f, 0.0f), new Vector4(1.0f, 1.0f, 0.0f, 1.0f)),
new SimpleVertex(new Vector3( 1.0f, -1.0f, 1.0f), new Vector3( 0.0f, -1.0f, 0.0f), new Vector4(1.0f, 1.0f, 1.0f, 1.0f)),
new SimpleVertex(new Vector3(-1.0f, -1.0f, 1.0f), new Vector3( 0.0f, -1.0f, 0.0f), new Vector4(0.0f, 0.0f, 0.0f, 1.0f)),
new SimpleVertex(new Vector3(-1.0f, -1.0f, 1.0f), new Vector3(-1.0f, 0.0f, 0.0f), new Vector4(0.0f, 0.0f, 0.0f, 1.0f)),
new SimpleVertex(new Vector3(-1.0f, -1.0f, -1.0f), new Vector3(-1.0f, 0.0f, 0.0f), new Vector4(1.0f, 0.0f, 1.0f, 1.0f)),
new SimpleVertex(new Vector3(-1.0f, 1.0f, -1.0f), new Vector3(-1.0f, 0.0f, 0.0f), new Vector4(0.0f, 0.0f, 1.0f, 1.0f)),
new SimpleVertex(new Vector3(-1.0f, 1.0f, 1.0f), new Vector3(-1.0f, 0.0f, 0.0f), new Vector4(1.0f, 0.0f, 0.0f, 1.0f)),
new SimpleVertex(new Vector3( 1.0f, -1.0f, 1.0f), new Vector3( 1.0f, 0.0f, 0.0f), new Vector4(1.0f, 1.0f, 1.0f, 1.0f)),
new SimpleVertex(new Vector3( 1.0f, -1.0f, -1.0f), new Vector3( 1.0f, 0.0f, 0.0f), new Vector4(1.0f, 1.0f, 0.0f, 1.0f)),
new SimpleVertex(new Vector3( 1.0f, 1.0f, -1.0f), new Vector3( 1.0f, 0.0f, 0.0f), new Vector4(0.0f, 1.0f, 0.0f, 1.0f)),
new SimpleVertex(new Vector3( 1.0f, 1.0f, 1.0f), new Vector3( 1.0f, 0.0f, 0.0f), new Vector4(0.0f, 1.0f, 1.0f, 1.0f)),
new SimpleVertex(new Vector3(-1.0f, -1.0f, -1.0f), new Vector3( 0.0f, 0.0f, -1.0f), new Vector4(1.0f, 0.0f, 1.0f, 1.0f)),
new SimpleVertex(new Vector3( 1.0f, -1.0f, -1.0f), new Vector3( 0.0f, 0.0f, -1.0f), new Vector4(1.0f, 1.0f, 0.0f, 1.0f)),
new SimpleVertex(new Vector3( 1.0f, 1.0f, -1.0f), new Vector3( 0.0f, 0.0f, -1.0f), new Vector4(0.0f, 1.0f, 0.0f, 1.0f)),
new SimpleVertex(new Vector3(-1.0f, 1.0f, -1.0f), new Vector3( 0.0f, 0.0f, -1.0f), new Vector4(0.0f, 0.0f, 1.0f, 1.0f)),
new SimpleVertex(new Vector3(-1.0f, -1.0f, 1.0f), new Vector3( 0.0f, 0.0f, 1.0f), new Vector4(0.0f, 0.0f, 0.0f, 1.0f)),
new SimpleVertex(new Vector3( 1.0f, -1.0f, 1.0f), new Vector3( 0.0f, 0.0f, 1.0f), new Vector4(1.0f, 1.0f, 1.0f, 1.0f)),
new SimpleVertex(new Vector3( 1.0f, 1.0f, 1.0f), new Vector3( 0.0f, 0.0f, 1.0f), new Vector4(0.0f, 1.0f, 1.0f, 1.0f)),
new SimpleVertex(new Vector3(-1.0f, 1.0f, 1.0f), new Vector3( 0.0f, 0.0f, 1.0f), new Vector4(1.0f, 0.0f, 0.0f, 1.0f)),
};

foreach (SimpleVertex vertex in tempVertexArray)
{
vertices.Write(vertex);
}
vertices.Position = 0;
// create the vertex layout and vertex buffer
var elements = new[] { new InputElement("POSITION", 0, Format.R32G32B32_Float, 0, 0, SlimDX.Direct3D11.InputClassification.PerVertexData, 0),
new InputElement("NORMAL", 0, Format.R32G32B32_Float, 12, 0, SlimDX.Direct3D11.InputClassification.PerVertexData, 0),
new InputElement("COLOR", 0, Format.R32G32B32A32_Float, 24, 0, SlimDX.Direct3D11.InputClassification.PerVertexData, 0)};
layout = new InputLayout(device,
inputSignature,
elements);
vertexBuffer = new Buffer(device,
vertices,
(int)vertices.Length,
ResourceUsage.Default,
BindFlags.VertexBuffer,
CpuAccessFlags.None,
ResourceOptionFlags.None,
0);
// Setup the test index data, making sure to rewind the stream afterward.
UInt16[] indicesList = { 3, 1, 0,
2, 1, 3,
6, 4, 5,
7, 4, 6,
11, 9, 8,
10, 9, 11,
14, 12, 13,
15, 12, 14,
19, 17, 16,
18, 17, 19,
22, 20, 21,
23, 20, 22
};
// As you can see in the indices list above, we have 36 values total, each of which
// is a UInt16 value (or 2-byte short integer)
indices = new DataStream(36 * 2, true, true);
foreach (UInt16 index in indicesList)
{
indices.Write(index);
}
indices.Position = 0;
// Now create the index buffer.
indexBuffer = new Buffer(device,
indices,
(int)indices.Length,
ResourceUsage.Default,
BindFlags.IndexBuffer,
CpuAccessFlags.None,
ResourceOptionFlags.None,
0);

// Configure the Input Assembler portion of the graphics pipeline with the vertex data.
context.InputAssembler.InputLayout = layout;
context.InputAssembler.PrimitiveTopology = PrimitiveTopology.TriangleList;
context.InputAssembler.SetVertexBuffers(0,
new VertexBufferBinding(vertexBuffer, 40, 0));
context.InputAssembler.SetIndexBuffer(indexBuffer,
Format.R16_UInt,
0);
}

static void RenderFrame()
{
curTime = Environment.TickCount;
float t = (curTime - startTime) / 1000.0f; // Calculate elapsed time since start in seconds

// 1st Cube: Rotate around the origin.
matrix_World = Matrix.RotationY(t * rotationY);
// Setup our lighting parameters
Vector4[] vLightDirs =
{
new Vector4(-0.577f, 0.577f, -0.577f, 1.0f),
new Vector4(0.0f, 0.0f, -1.0f, 1.0f)
};
Vector4[] vLightColors =
{
new Vector4(0.5f, 0.5f, 0.5f, 1.0f),
new Vector4(0.5f, 0.0f, 0.0f, 1.0f)
};
// Rotate the second light around the origin
Matrix mRotate = Matrix.RotationY(-2.0f * t);
Vector4 vLightDir = vLightDirs[1];
vLightDir = Vector4.Transform(vLightDir, mRotate);
vLightDirs[1] = vLightDir;
// Clear the render target to a soothing blue
context.ClearRenderTargetView(renderTarget,
new Color4(0.0f, 0.125f, 0.3f, 1.0f));
// Clear the Depth buffer to 1.0 (max depth)
context.ClearDepthStencilView(depthStencilView, DepthStencilClearFlags.Depth, 1.0f, 0);

// Update the constant buffer variables
ConstantBuffer cb = new ConstantBuffer(Matrix.Transpose(matrix_World),
Matrix.Transpose(matrix_View),
Matrix.Transpose(matrix_Projection));
cb.vLightDir[0] = vLightDirs[0];
cb.vLightDir[1] = vLightDirs[1];
cb.vLightColor[0] = vLightColors[0];
cb.vLightColor[1] = vLightColors[1];
cb.vOutputColor = new Vector4(0, 0, 0, 0);
constants.Position = 0;
constants.Write<ConstantBuffer>(cb);
constants.Position = 0;
// Give GPU updated matrices data.
context.UpdateSubresource(new DataBox(0, 0, constants),
constantBuffer,
0);

// Render the cube
context.VertexShader.Set(vertexShader);
context.VertexShader.SetConstantBuffer(constantBuffer, 0);
context.PixelShader.Set(pixelShaderColor);
context.PixelShader.SetConstantBuffer(constantBuffer, 0);
context.DrawIndexed(36,
0,
0);
/*
// Render each light
for (int m = 0; m < 2; m++)
{
Matrix mLight = Matrix.Translation(5.0f * new Vector3(vLightDirs[m].X, vLightDirs[m].Y, vLightDirs[m].Z));
Matrix mLightScale = Matrix.Scaling(0.2f, 0.2f, 0.2f);
mLight = mLightScale * mLight;
// Update the world variable to reflect the current light
cb.mWorld = Matrix.Transpose(mLight);
cb.vOutputColor = vLightColors[m];
constants.Position = 0;
constants.Write<ConstantBuffer>(cb);
constants.Position = 0;
context.UpdateSubresource(new DataBox(0, 0, constants),
constantBuffer,
0);
context.PixelShader.Set(pixelShaderSolid);

context.DrawIndexed(36,
0,
0);
}
*/
// Present the frame we just rendered.
swapChain.Present(0,
PresentFlags.None);
}
}
}
[/CODE]

And here is the code of the shaders.fx file which contains the shaders:
[CODE]
//--------------------------------------------------------------------------------------
// File: Tutorial06.fx
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//--------------------------------------------------------------------------------------

//--------------------------------------------------------------------------------------
// NOTE:
//--------------------------------------------------------------------------------------
// I modified this file by adding color to the VS_INPUT and PS_INPUT structs.
// I also added the Pixel Shader from the DirectX11 SDK tutorial 5 program and named
// it as PSColor. I also added one line in the Vertex Shader to return the vertex
// color in the output so the pixel shader has access to the color.
//--------------------------------------------------------------------------------------
//--------------------------------------------------------------------------------------
// Constant Buffer Variables
//--------------------------------------------------------------------------------------
cbuffer ConstantBuffer : register( b0 )
{
matrix World;
matrix View;
matrix Projection;
float4 vLightDir[2];
float4 vLightColor[2];
float4 vOutputColor;
}

//--------------------------------------------------------------------------------------
struct VS_INPUT
{
float4 Pos : POSITION;
float3 Norm : NORMAL;
float4 Color: COLOR;
};
struct PS_INPUT
{
float4 Pos : SV_POSITION;
float3 Norm : TEXCOORD0;
float4 Color: COLOR;
};

//--------------------------------------------------------------------------------------
// Vertex Shader
//--------------------------------------------------------------------------------------
PS_INPUT VS( VS_INPUT input )
{
PS_INPUT output = (PS_INPUT)0;
output.Pos = mul( input.Pos, World );
output.Pos = mul( output.Pos, View );
output.Pos = mul( output.Pos, Projection );
output.Norm = mul( input.Norm, World );

// I added this line.
output.Color = input.Color;
return output;
}

//--------------------------------------------------------------------------------------
// Pixel Shader
//--------------------------------------------------------------------------------------
float4 PS( PS_INPUT input) : SV_Target
{
float4 finalColor = 0;

//do NdotL lighting for 2 lights
for(int i=0; i<2; i++)
{
finalColor += saturate( dot( (float3)vLightDir[i],input.Norm) * vLightColor[i] );
}
finalColor.a = 1;
return finalColor;
}

//--------------------------------------------------------------------------------------
// PSSolid - render a solid color
//--------------------------------------------------------------------------------------
float4 PSSolid( PS_INPUT input) : SV_Target
{
return vOutputColor;
}

//--------------------------------------------------------------------------------------
// PSColor - render using vertex colors
//--------------------------------------------------------------------------------------
float4 PSColor( PS_INPUT input) : SV_Target
{
return input.Color;
}
[/CODE]


As you can see, I added the Pixel Shader from tutorial 5 (renamed to PSColor) to the bottom of the shaders.fx file and added a color attribute to the shader input data. I then changed the render code to use this shader instead of the PSSolid pixel shader. And lastly I added the color data from tutorial 5 into the vertex list of this program. I can see where one face ends and the next begins now, but what I'm seeing I can't make any sense out of. The code to render the lights is commented out to see what difference that made. I need to get it to draw a cube for now like it is supposed to. Then I'll go back and uncomment that code to enable the lights again.

Any help would be greatly appreciated. I'm totally stumped here. [img]http://public.gamedev.net//public/style_emoticons/default/wacko.png[/img] Thanks
0

Share this post


Link to post
Share on other sites
I haven't taken an in-depth look at the rest of it, but the first thing that jumps out is that you're using a managed array in your constant buffer. A managed array is a reference to memory elsewhere, so the copy to the GPU isn't going to do what you want.
0

Share this post


Link to post
Share on other sites
Hi and thank you very much. I did a little research into how to setup my structure properly. It no longer is drawing nonsense on the screen, but the problem is that now it draws absolutely nothing on the screen after it clears it each frame. I'm not sure what's going on but obviously something somewhere is still screwed up unfortunately.

Here is what my code looks like now with the structure updated, and I also now copy the structure into the constant buffer using Marshal.StructureToPtr().
[CODE]
using System;
using System.Runtime.InteropServices;
using System.Windows.Forms;
using SlimDX;
using SlimDX.D3DCompiler;
using SlimDX.Direct3D11;
using Buffer = SlimDX.Direct3D11.Buffer; // I added this line to fix ambiguity between SlimDX.Direct3D11.Buffer and System.Buffer. This tells it to use the SlimDX Buffer class rather than the one in the System namespace when I reference the type Buffer.
using SlimDX.DXGI;
using SlimDX.Windows;
using Device = SlimDX.Direct3D11.Device;
using Resource = SlimDX.Direct3D11.Resource;

//--------------------------------------------------------------------------------------
// NOTE:
//--------------------------------------------------------------------------------------
// I modified this program and its shaders.fx file to help with debugging a bug that
// I was having a hell of a time solving. See the note at the top of the shaders.fx
// file for info on changes I made to that file.
//--------------------------------------------------------------------------------------
namespace Test_1
{
struct SimpleVertex
{
Vector3 Position;
Vector3 Normal;
Vector4 Color;
public SimpleVertex(Vector3 position, Vector3 normal, Vector4 color)
{
Position = position;
Normal = normal;
Color = color;
}
};

[StructLayout(LayoutKind.Sequential, Pack=1)]
struct ConstantBufferStruct
{
public Matrix mWorld;
public Matrix mView;
public Matrix mProjection;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 2)]
public Vector4[] vLightDir;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 2)]
public Vector4[] vLightColor;

public Vector4 vOutputColor;
};

static class Program
{
static float rotationY = 0.785f; // Y Rotation in radians per second (0.785 radians = 45 degrees)

static int startTime;
static int curTime;
static RenderForm form;
static Buffer constantBuffer;
static Buffer indexBuffer;
static Buffer vertexBuffer;
static DataStream constants;
static DataStream indices;
static DataStream vertices;
static DepthStencilView depthStencilView;
static Device device;
static DeviceContext context;
static InputLayout layout;
static PixelShader pixelShader;
static PixelShader pixelShaderSolid;
static PixelShader pixelShaderColor;
static RenderTargetView renderTarget;
static ShaderSignature inputSignature;
static SwapChain swapChain;
static Texture2D depthStencil;
static VertexShader vertexShader;
static Viewport viewport;
static Matrix matrix_World;
static Matrix matrix_View;
static Matrix matrix_Projection;
static ConstantBufferStruct cbStruct = new ConstantBufferStruct();

static void Main()
{
form = new RenderForm("OMG a Window!!");
var description = new SwapChainDescription()
{
BufferCount = 2,
Usage = Usage.RenderTargetOutput,
OutputHandle = form.Handle,
IsWindowed = true,
ModeDescription = new ModeDescription(0, 0, new Rational(60, 1), Format.R8G8B8A8_UNorm),
SampleDescription = new SampleDescription(1, 0),
Flags = SwapChainFlags.AllowModeSwitch,
SwapEffect = SwapEffect.Discard
};

Device.CreateWithSwapChain(DriverType.Hardware,
DeviceCreationFlags.Debug,
description,
out device,
out swapChain);

// create a view of our render target, which is the backbuffer of the swap chain we just created
using (var resource = Resource.FromSwapChain<Texture2D>(swapChain, 0))
{
renderTarget = new RenderTargetView(device, resource);
};

// Create the depth stencil texture
Texture2DDescription depthStencilDesc = new Texture2DDescription();
depthStencilDesc.Width = form.ClientSize.Width;
depthStencilDesc.Height = form.ClientSize.Height;
depthStencilDesc.MipLevels = 1;
depthStencilDesc.ArraySize = 1;
depthStencilDesc.Format = Format.D24_UNorm_S8_UInt;
depthStencilDesc.SampleDescription = new SampleDescription(1, 0);
depthStencilDesc.Usage = ResourceUsage.Default;
depthStencilDesc.BindFlags = BindFlags.DepthStencil;
depthStencilDesc.CpuAccessFlags = CpuAccessFlags.None;
depthStencilDesc.OptionFlags = ResourceOptionFlags.None;
depthStencil = new Texture2D(device, depthStencilDesc);

// Create the Depth Stencil View
DepthStencilViewDescription depthStencilViewDesc = new DepthStencilViewDescription();
depthStencilViewDesc.Format = depthStencilDesc.Format;
depthStencilViewDesc.Dimension = DepthStencilViewDimension.Texture2D;
depthStencilViewDesc.MipSlice = 0;
depthStencilView = new DepthStencilView(device, depthStencil, depthStencilViewDesc);
// setting a viewport is required if you want to actually see anything
context = device.ImmediateContext;
viewport = new Viewport(0.0f,
0.0f,
form.ClientSize.Width,
form.ClientSize.Height,
0.0f,
1.0f);
context.OutputMerger.SetTargets(depthStencilView, renderTarget);
context.Rasterizer.SetViewports(viewport);

// Setup our shaders
InitShaders();

// Setup our vertex data
InitVertexData();

// Setup our matrices
InitMatrices();

// Set the shaders
context.VertexShader.Set(vertexShader);
context.PixelShader.Set(pixelShader);

// Prevent DXGI handling of Alt+Enter, which doesn't work properly with Winforms
using (var factory = swapChain.GetParent<Factory>())
{
factory.SetWindowAssociation(form.Handle,
WindowAssociationFlags.IgnoreAltEnter);
};

// Handle Alt+Enter ourselves
form.KeyDown += (o, e) =>
{
if (e.Alt && e.KeyCode == Keys.Enter)
{
swapChain.IsFullScreen = !swapChain.IsFullScreen;
}
};

// Handle form size changes
form.UserResized += (o, e) =>
{
renderTarget.Dispose();
depthStencil.Dispose();
depthStencilView.Dispose();

swapChain.ResizeBuffers(2,
0,
0,
Format.R8G8B8A8_UNorm,
SwapChainFlags.AllowModeSwitch);

using (var resource = Resource.FromSwapChain<Texture2D>(swapChain, 0))
{
renderTarget = new RenderTargetView(device, resource);
}

depthStencilDesc.Width = form.ClientSize.Width;
depthStencilDesc.Height = form.ClientSize.Height;
depthStencil = new Texture2D(device, depthStencilDesc);
depthStencilView = new DepthStencilView(device, depthStencil, depthStencilViewDesc);

context.OutputMerger.SetTargets(depthStencilView, renderTarget);
context.Rasterizer.SetViewports(new Viewport(0, 0, form.ClientSize.Width, form.ClientSize.Height, 0.0f, 1.0f));
};
startTime = Environment.TickCount;
MessagePump.Run(form, RenderFrame);


// Clean up all resources
// anything we missed will show up in the IDE's debug output
vertices.Close();
vertexBuffer.Dispose();
layout.Dispose();
inputSignature.Dispose();
vertexShader.Dispose();
pixelShader.Dispose();
renderTarget.Dispose();
swapChain.Dispose();
device.Dispose();
indexBuffer.Dispose();
indices.Dispose();
constantBuffer.Dispose();
constants.Dispose();
depthStencil.Dispose();
depthStencilView.Dispose();
pixelShaderSolid.Dispose();
pixelShaderColor.Dispose();
}

static void InitShaders()
{
// load and compile the vertex shader
string vsCompileError = "Vertex Shader Compile Error!!!";
using (var bytecode = ShaderBytecode.CompileFromFile("shaders.fx", "VS", "vs_4_0", ShaderFlags.EnableStrictness | ShaderFlags.Debug, EffectFlags.None, null, null, out vsCompileError))
{
inputSignature = ShaderSignature.GetInputSignature(bytecode);
vertexShader = new VertexShader(device, bytecode);
}

// load and compile the pixel shader
string psCompileError = "Pixel Shader Compile Error!!!";
using (var bytecode = ShaderBytecode.CompileFromFile("shaders.fx", "PS", "ps_4_0", ShaderFlags.EnableStrictness | ShaderFlags.Debug, EffectFlags.None, null, null, out psCompileError))
{
pixelShader = new PixelShader(device, bytecode);
}
// load and compile the solid pixel shader
psCompileError = "Solid Pixel Shader Compile Error!!!";
using (var bytecode = ShaderBytecode.CompileFromFile("shaders.fx", "PSSolid", "ps_4_0", ShaderFlags.EnableStrictness | ShaderFlags.Debug, EffectFlags.None, null, null, out psCompileError))
{
pixelShaderSolid = new PixelShader(device, bytecode);
}
// load and compile the color pixel shader
psCompileError = "Color Pixel Shader Compile Error!!!";
using (var bytecode = ShaderBytecode.CompileFromFile("shaders.fx", "PSColor", "ps_4_0", ShaderFlags.EnableStrictness | ShaderFlags.Debug, EffectFlags.None, null, null, out psCompileError))
{
pixelShaderColor = new PixelShader(device, bytecode);
}
}
static void InitMatrices()
{
// world matrix
matrix_World = Matrix.Identity;
// view matrix
Vector3 vEye = new Vector3(0.0f, 4.0f, -10.0f);
Vector3 vLookAt = new Vector3(0.0f, 1.0f, 0.0f);
Vector3 vUp = new Vector3(0.0f, 1.0f, 0.0f);
matrix_View = Matrix.LookAtLH(vEye,
vLookAt,
vUp);

// projection matrix
matrix_Projection = Matrix.PerspectiveFovLH((float)Math.PI / 2, // Vertical Field of View
(float)form.ClientSize.Width / (float)form.ClientSize.Height, // Aspect Ratio
0.01f, // Near Z
100.0f); // Far Z

// Write the matrices we just generated into the DataStream
cbStruct.mWorld = Matrix.Transpose(matrix_World);
cbStruct.mView = Matrix.Transpose(matrix_View);
cbStruct.mProjection = Matrix.Transpose(matrix_Projection);
cbStruct.vLightColor = new Vector4[2];
cbStruct.vLightDir = new Vector4[2];

constants = new DataStream(Marshal.SizeOf(typeof(ConstantBufferStruct)), true, true);

// If no specific marshalling is needed, can use
// dataStream.Write(value) for better performance.
Marshal.StructureToPtr(cbStruct, constants.DataPointer, false);
ConstantBufferStruct temp = new ConstantBufferStruct();
temp.vLightColor = new Vector4[2];
temp.vLightColor = new Vector4[2];
temp.vOutputColor = new Vector4(1.0f, 0.5f, 0.5f, 1.0f);
temp = (ConstantBufferStruct) Marshal.PtrToStructure(constants.DataPointer, typeof(ConstantBufferStruct));
if (temp.mWorld.Equals(cbStruct.mWorld) &&
temp.mView.Equals(cbStruct.mView) &&
temp.mProjection.Equals(cbStruct.mProjection))
{
System.Diagnostics.Debug.WriteLine("MATRICES ARE CORRECT!");
}
else
{
System.Diagnostics.Debug.WriteLine("MATRICES ARE NOT CORRECT!");
}
if (temp.vOutputColor.Equals(cbStruct.vOutputColor))
{
System.Diagnostics.Debug.WriteLine("OUTPUT COLOR IS CORRECT!");
}
else
{
System.Diagnostics.Debug.WriteLine("OUTPUT COLOR IS NOT CORRECT!");
}
// Create the constant buffer
constantBuffer = new Buffer(device,
constants,
(int)constants.Length,
ResourceUsage.Default,
BindFlags.ConstantBuffer,
CpuAccessFlags.None,
ResourceOptionFlags.None,
0);
context.UpdateSubresource(new DataBox(0, 0, constants),
constantBuffer,
0);
context.VertexShader.SetConstantBuffer(constantBuffer, 0);
}
static void InitVertexData()
{
// Create test vertex data, making sure to rewind the stream afterward.
vertices = new DataStream(Marshal.SizeOf(new SimpleVertex(Vector3.Zero, Vector3.Zero, Vector4.Zero)) * 24, true, true);
SimpleVertex[] tempVertexArray =
{
new SimpleVertex(new Vector3(-1.0f, 1.0f, -1.0f), new Vector3( 0.0f, 1.0f, 0.0f), new Vector4(0.0f, 0.0f, 1.0f, 1.0f)),
new SimpleVertex(new Vector3( 1.0f, 1.0f, -1.0f), new Vector3( 0.0f, 1.0f, 0.0f), new Vector4(0.0f, 1.0f, 0.0f, 1.0f)),
new SimpleVertex(new Vector3( 1.0f, 1.0f, 1.0f), new Vector3( 0.0f, 1.0f, 0.0f), new Vector4(0.0f, 1.0f, 1.0f, 1.0f)),
new SimpleVertex(new Vector3(-1.0f, 1.0f, 1.0f), new Vector3( 0.0f, 1.0f, 0.0f), new Vector4(1.0f, 0.0f, 0.0f, 1.0f)),
new SimpleVertex(new Vector3(-1.0f, -1.0f, -1.0f), new Vector3( 0.0f, -1.0f, 0.0f), new Vector4(1.0f, 0.0f, 1.0f, 1.0f)),
new SimpleVertex(new Vector3( 1.0f, -1.0f, -1.0f), new Vector3( 0.0f, -1.0f, 0.0f), new Vector4(1.0f, 1.0f, 0.0f, 1.0f)),
new SimpleVertex(new Vector3( 1.0f, -1.0f, 1.0f), new Vector3( 0.0f, -1.0f, 0.0f), new Vector4(1.0f, 1.0f, 1.0f, 1.0f)),
new SimpleVertex(new Vector3(-1.0f, -1.0f, 1.0f), new Vector3( 0.0f, -1.0f, 0.0f), new Vector4(0.0f, 0.0f, 0.0f, 1.0f)),
new SimpleVertex(new Vector3(-1.0f, -1.0f, 1.0f), new Vector3(-1.0f, 0.0f, 0.0f), new Vector4(0.0f, 0.0f, 0.0f, 1.0f)),
new SimpleVertex(new Vector3(-1.0f, -1.0f, -1.0f), new Vector3(-1.0f, 0.0f, 0.0f), new Vector4(1.0f, 0.0f, 1.0f, 1.0f)),
new SimpleVertex(new Vector3(-1.0f, 1.0f, -1.0f), new Vector3(-1.0f, 0.0f, 0.0f), new Vector4(0.0f, 0.0f, 1.0f, 1.0f)),
new SimpleVertex(new Vector3(-1.0f, 1.0f, 1.0f), new Vector3(-1.0f, 0.0f, 0.0f), new Vector4(1.0f, 0.0f, 0.0f, 1.0f)),
new SimpleVertex(new Vector3( 1.0f, -1.0f, 1.0f), new Vector3( 1.0f, 0.0f, 0.0f), new Vector4(1.0f, 1.0f, 1.0f, 1.0f)),
new SimpleVertex(new Vector3( 1.0f, -1.0f, -1.0f), new Vector3( 1.0f, 0.0f, 0.0f), new Vector4(1.0f, 1.0f, 0.0f, 1.0f)),
new SimpleVertex(new Vector3( 1.0f, 1.0f, -1.0f), new Vector3( 1.0f, 0.0f, 0.0f), new Vector4(0.0f, 1.0f, 0.0f, 1.0f)),
new SimpleVertex(new Vector3( 1.0f, 1.0f, 1.0f), new Vector3( 1.0f, 0.0f, 0.0f), new Vector4(0.0f, 1.0f, 1.0f, 1.0f)),
new SimpleVertex(new Vector3(-1.0f, -1.0f, -1.0f), new Vector3( 0.0f, 0.0f, -1.0f), new Vector4(1.0f, 0.0f, 1.0f, 1.0f)),
new SimpleVertex(new Vector3( 1.0f, -1.0f, -1.0f), new Vector3( 0.0f, 0.0f, -1.0f), new Vector4(1.0f, 1.0f, 0.0f, 1.0f)),
new SimpleVertex(new Vector3( 1.0f, 1.0f, -1.0f), new Vector3( 0.0f, 0.0f, -1.0f), new Vector4(0.0f, 1.0f, 0.0f, 1.0f)),
new SimpleVertex(new Vector3(-1.0f, 1.0f, -1.0f), new Vector3( 0.0f, 0.0f, -1.0f), new Vector4(0.0f, 0.0f, 1.0f, 1.0f)),
new SimpleVertex(new Vector3(-1.0f, -1.0f, 1.0f), new Vector3( 0.0f, 0.0f, 1.0f), new Vector4(0.0f, 0.0f, 0.0f, 1.0f)),
new SimpleVertex(new Vector3( 1.0f, -1.0f, 1.0f), new Vector3( 0.0f, 0.0f, 1.0f), new Vector4(1.0f, 1.0f, 1.0f, 1.0f)),
new SimpleVertex(new Vector3( 1.0f, 1.0f, 1.0f), new Vector3( 0.0f, 0.0f, 1.0f), new Vector4(0.0f, 1.0f, 1.0f, 1.0f)),
new SimpleVertex(new Vector3(-1.0f, 1.0f, 1.0f), new Vector3( 0.0f, 0.0f, 1.0f), new Vector4(1.0f, 0.0f, 0.0f, 1.0f)),
};

foreach (SimpleVertex vertex in tempVertexArray)
{
vertices.Write(vertex);
}
vertices.Position = 0;

// create the vertex layout and vertex buffer
var elements = new[] { new InputElement("POSITION", 0, Format.R32G32B32_Float, 0, 0, SlimDX.Direct3D11.InputClassification.PerVertexData, 0),
new InputElement("NORMAL", 0, Format.R32G32B32_Float, 12, 0, SlimDX.Direct3D11.InputClassification.PerVertexData, 0),
new InputElement("COLOR", 0, Format.R32G32B32A32_Float, 24, 0, SlimDX.Direct3D11.InputClassification.PerVertexData, 0)};
layout = new InputLayout(device,
inputSignature,
elements);
vertexBuffer = new Buffer(device,
vertices,
(int)vertices.Length,
ResourceUsage.Default,
BindFlags.VertexBuffer,
CpuAccessFlags.None,
ResourceOptionFlags.None,
0);

// Setup the test index data, making sure to rewind the stream afterward.
UInt16[] indicesList = { 3, 1, 0,
2, 1, 3,
6, 4, 5,
7, 4, 6,
11, 9, 8,
10, 9, 11,
14, 12, 13,
15, 12, 14,
19, 17, 16,
18, 17, 19,
22, 20, 21,
23, 20, 22
};
// As you can see in the indices list above, we have 36 values total, each of which
// is a UInt16 value (or 2-byte short integer)
indices = new DataStream(36 * 2, true, true);
foreach (UInt16 index in indicesList)
{
indices.Write(index);
}
indices.Position = 0;

// Now create the index buffer.
indexBuffer = new Buffer(device,
indices,
(int)indices.Length,
ResourceUsage.Default,
BindFlags.IndexBuffer,
CpuAccessFlags.None,
ResourceOptionFlags.None,
0);


// Configure the Input Assembler portion of the graphics pipeline with the vertex data.
context.InputAssembler.InputLayout = layout;
context.InputAssembler.PrimitiveTopology = PrimitiveTopology.TriangleList;
context.InputAssembler.SetVertexBuffers(0,
new VertexBufferBinding(vertexBuffer, 40, 0));
context.InputAssembler.SetIndexBuffer(indexBuffer,
Format.R16_UInt,
0);
}

static void RenderFrame()
{
curTime = Environment.TickCount;
float t = (curTime - startTime) / 1000.0f; // Calculate elapsed time since start in seconds

// 1st Cube: Rotate around the origin.
matrix_World = Matrix.RotationY(t * rotationY);

// Setup our lighting parameters
Vector4[] vLightDirs =
{
new Vector4(-0.577f, 0.577f, -0.577f, 1.0f),
new Vector4(0.0f, 0.0f, -1.0f, 1.0f)
};
Vector4[] vLightColors =
{
new Vector4(0.5f, 0.5f, 0.5f, 1.0f),
new Vector4(0.5f, 0.0f, 0.0f, 1.0f)
};

// Rotate the second light around the origin
Matrix mRotate = Matrix.RotationY(-2.0f * t);
Vector4 vLightDir = vLightDirs[1];
vLightDir = Vector4.Transform(vLightDir, mRotate);
vLightDirs[1] = vLightDir;

// Clear the render target to a soothing blue
context.ClearRenderTargetView(renderTarget,
new Color4(0.0f, 0.125f, 0.3f, 1.0f));
// Clear the Depth buffer to 1.0 (max depth)
context.ClearDepthStencilView(depthStencilView, DepthStencilClearFlags.Depth, 1.0f, 0);

// Update the constant buffer variables
cbStruct.mWorld = Matrix.Transpose(matrix_World);
cbStruct.mView = Matrix.Transpose(matrix_View);
cbStruct.mProjection = Matrix.Transpose(matrix_Projection);
cbStruct.vLightDir[0] = vLightDirs[0];
cbStruct.vLightDir[1] = vLightDirs[1];
cbStruct.vLightColor[0] = vLightColors[0];
cbStruct.vLightColor[1] = vLightColors[1];
cbStruct.vOutputColor = new Vector4(0, 0, 0, 0);
// If no specific marshalling is needed, can use
// dataStream.Write(value) for better performance.
Marshal.StructureToPtr(cbStruct, constants.DataPointer, false);

// Give GPU updated matrices data.
context.UpdateSubresource(new DataBox(0, 0, constants),
constantBuffer,
0);

// Render the cube
context.VertexShader.Set(vertexShader);
context.VertexShader.SetConstantBuffer(constantBuffer, 0);
context.PixelShader.Set(pixelShaderSolid);
context.PixelShader.SetConstantBuffer(constantBuffer, 0);
context.DrawIndexed(36,
0,
0);


// Render each light
for (int m = 0; m < 2; m++)
{
Matrix mLight = Matrix.Translation(5.0f * new Vector3(vLightDirs[m].X, vLightDirs[m].Y, vLightDirs[m].Z));
Matrix mLightScale = Matrix.Scaling(0.2f, 0.2f, 0.2f);
mLight = mLightScale * mLight;
// Update the world variable to reflect the current light
cbStruct.mWorld = Matrix.Transpose(mLight);
cbStruct.vOutputColor = vLightColors[m];
// If no specific marshalling is needed, can use
// dataStream.Write(value) for better performance.
Marshal.StructureToPtr((object)cbStruct, constants.DataPointer, false);
context.UpdateSubresource(new DataBox(0, 0, constants),
constantBuffer,
0);
context.PixelShader.Set(pixelShaderSolid);

context.DrawIndexed(36,
0,
0);
}

// Present the frame we just rendered.
swapChain.Present(0,
PresentFlags.None);
}
}
}
[/CODE]

Thanks again for you're help and hopefully someone can help me solve this second issue. I'm just not sure whether the problem is still with the packing of the data in the constant buffer, or if the problem lies elsewhere. I don't know how to check to make sure that the data is getting into the constant buffer correctly. If its not, the arrays are where the problem lies, like you said, because the struct works fine in previous tutorials with the Matrices stored the same way, but there are no arrays in the struct in those tutorials.



[b]UPDATE:[/b]
I got the demo to work by making a small function that writes all the data from the structure one item at a time into the DataStream using the [b]DataStream.Write()[/b] method. The program is now working properly. It would seem that when I used [b]Marshal.StructToPtr()[/b] it was doing something wrong. The two spots in the render code that update the Constant Buffer seemed to be fighting each other in some way. If I had one update using [color=#008000][b]Marshal.StructToPtr()[/b][/color] and the other using [color=#008000][b]constants.Write(cbStruct)[/b][/color], then half of the draw code would work. Which half works was determined by which way I set up the two updates. So if I flipped it so the first update used [color=#008000][b]constants.Write(cbStruct)[/b][/color] and the second update of the constant buffer used [color=#008000][b]Marshal.StructToPtr()[/b][/color], then the other half of the render code worked but the half that worked before stopped working. If both updates use [b]constants.Write(cbStruct)[/b] or if both updates use [b]Marshal.StructToPtr()[/b], then I get an empty screen with nothing but the background color. Very strange indeed.

When I change the Render code so that both of the updates to the Constant Buffer use my little util function that writes the data to the DataStream one item at a time using the [b]DataStream.Write()[/b] method, the program works exactly as it should. Both halves of the render code function correctly with this setup and I see 3 cubes on the screen with lighting on the center cube as expected.

So in short, the problem obviously has to do with the way the struct was getting written to the Constant Buffer when I used [b]Marshal.StructToPtr()[/b]. So apparently there is still something not quite right about how my struct is set up. Here's what the struct looks like now. Let me know if I'm doing something wrong. Thanks.
[CODE]
[StructLayout(LayoutKind.Sequential, Pack=1)]
public struct ConstantBufferStruct
{
public Matrix mWorld;
public Matrix mView;
public Matrix mProjection;

[MarshalAs(UnmanagedType.ByValArray, SizeConst = 2)]
public Vector4[] vLightDir;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 2)]
public Vector4[] vLightColor;

public Vector4 vOutputColor;
};
[/CODE] Edited by Megafont
0

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!


Register a new account

Sign in

Already have an account? Sign in here.


Sign In Now
Sign in to follow this  
Followers 0