Texture Loading Problem in c# using sharpDx Direct3D11

I started doing my 3d engine in sharpdx and it works pretty well, but there is small one problem with the texture(How it looks on objects). So the texture loader works as well with shaders but how can i achieve the full texture(The texture fit my object vertices) on my objects(I’m using simple brick texture in png format and only what i see is wrapped stripes).

My code:

Main Dx11 Parts

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
<code>private void InitDX11()
{
Logger.Log($"Starting initializing dx11..", LogType.INFO);
lastFrameTime = 0f; // Zainicjuj czas ostatniej klatki
// Create the RenderForm
renderForm = new RenderForm("DirectX 3D Cube")
{
FormBorderStyle = FormBorderStyle.None,
KeyPreview = true,
TopLevel = false,
Dock = DockStyle.Fill,
};
this.WindowState = FormWindowState.Normal;
renderForm.MouseClick += (sender, e) =>
{
renderForm.Focus();
};
renderForm.MouseLeave += (sender, e) =>
{
this.Focus();
};
renderForm.MouseMove += (sender, e) =>
{
if (!Initialized)
{
return; // Ignoruj zdarzenia myszy, jeśli program jeszcze się nie załadował.
}
if (attachCursor)
{
var centerX = renderForm.ClientSize.Width / 2;
var centerY = renderForm.ClientSize.Height / 2;
// Calculate mouse movement delta
var deltaX = e.X - centerX;
var deltaY = e.Y - centerY;
// Update camera rotation based on mouse movement
cameraYaw += deltaX * sensitivity;
cameraPitch += -(deltaY * sensitivity);
// Constrain the pitch to avoid gimbal lock (restrict pitch angle)
cameraPitch = MathUtil.Clamp(cameraPitch, -MathUtil.PiOverTwo + 0.01f, MathUtil.PiOverTwo - 0.01f);
// Center cursor back to the screen center (to keep continuous movement)
Cursor.Position = renderForm.PointToScreen(new System.Drawing.Point(centerX, centerY));
}
};
renderForm.KeyDown += (sender, e) =>
{
if (attachCursor)
{
if (e.KeyCode == Keys.W) isWKeyPressed = true;
else if (e.KeyCode == Keys.S) isSKeyPressed = true;
else if (e.KeyCode == Keys.A) isAKeyPressed = true;
else if (e.KeyCode == Keys.D) isDKeyPressed = true;
else if (e.KeyCode == Keys.Space) isSpacePressed = true; // Spacebar pressed (upward)
else if (e.KeyCode == Keys.ShiftKey) isShiftPressed = true; // Shift pressed (downward)
else if (e.KeyCode == Keys.ControlKey) isCtrlPressed = true; // Shift pressed (downward)
}
};
renderForm.KeyUp += (sender, e) =>
{
switch (e.KeyCode)
{
case Keys.F5:
SetFullScreen(true);
break;
case Keys.F4:
SetFullScreen(false);
break;
case Keys.F3:
ToggleAttachCursor();
break;
}
if (attachCursor)
{
if (e.KeyCode == Keys.W) isWKeyPressed = false;
else if (e.KeyCode == Keys.Oemtilde)
{
ToggleAttachCursor();
ToggleConsole();
}
else if (e.KeyCode == Keys.S) isSKeyPressed = false;
else if (e.KeyCode == Keys.A) isAKeyPressed = false;
else if (e.KeyCode == Keys.D) isDKeyPressed = false;
else if (e.KeyCode == Keys.Space) isSpacePressed = false; // Spacebar released
else if (e.KeyCode == Keys.ShiftKey) isShiftPressed = false; // Shift released
else if (e.KeyCode == Keys.ControlKey) isCtrlPressed = false; // Shift released
}
};
Logger.Log($"Events Added", LogType.INFO);
dxApiRenderPanel.Controls.Add(renderForm);
renderForm.BringToFront();
renderForm.Show();
// Set up the SwapChain description
desc = new SwapChainDescription()
{
BufferCount = 2, // Number of back buffers
ModeDescription = new ModeDescription(dxApiRenderPanel.ClientSize.Width, dxApiRenderPanel.ClientSize.Height, new Rational(60, 1), Format.R8G8B8A8_UNorm), // Resolution, refresh rate, and format
IsWindowed = true, // Windowed mode
OutputHandle = renderForm.Handle, // Handle to the window
SampleDescription = new SampleDescription(8, 0), // multisampling
SwapEffect = SwapEffect.Discard, // Swap effect
Usage = Usage.RenderTargetOutput // Usage of the back buffer
};
Logger.Log($"Creating device using swapchain..", LogType.INFO);
try
{
// Create Device and SwapChain
Device.CreateWithSwapChain(DriverType.Hardware, DeviceCreationFlags.None, desc, out device, out swapChain);
context = device.ImmediateContext;
}
catch
{
Logger.Log($"Cannot create device with swapchain!", LogType.ERROR);
}
Logger.Log($"Succesfully created and added device with context!", LogType.INFO);
Logger.Log($"Creating factory and making window association..", LogType.INFO);
try
{
// Ignore all windows events
var factory = swapChain.GetParent<SharpDX.DXGI.Factory>();
var adapter = factory.GetAdapter(0);
var adapterDescription = adapter.Description;
this.Text = $"RapidEngine11 - GPU: {adapterDescription.Description}";
factory.MakeWindowAssociation(renderForm.Handle, WindowAssociationFlags.IgnoreAll);
}
catch
{
Logger.Log($"Cannot create factory!", LogType.ERROR);
}
Logger.Log($"Succesfully created and added factory with window association!", LogType.INFO);
Logger.Log($"Compiling shaders..", LogType.INFO);
try
{
// Compile Shaders
var vertexShaderByteCode = ShaderBytecode.CompileFromFile("Shader.fx", "VS", "vs_4_0");
vertexShader = new VertexShader(device, vertexShaderByteCode);
var pixelShaderByteCode = ShaderBytecode.CompileFromFile("Shader.fx", "PS", "ps_4_0");
pixelShader = new PixelShader(device, pixelShaderByteCode);
try
{
var signature = ShaderSignature.GetInputSignature(vertexShaderByteCode);
layout = new InputLayout(device, signature, new[]
{
new InputElement("POSITION", 0, Format.R32G32B32A32_Float, 0, 0),
new InputElement("COLOR", 0, Format.R32G32B32A32_Float, 16, 0),
new InputElement("TEXCOORD", 0, Format.R32G32_Float, 32, 0)
});
}
catch
{
Logger.Log($"Cannot create layout!", LogType.ERROR);
}
}
catch
{
Logger.Log($"Cannot compile shaders!", LogType.ERROR);
}
Logger.Log($"Succesfully compiled shaders and created shaders layout!", LogType.INFO);
Logger.Log($"Preparing for objects initialization..", LogType.INFO);
try
{
InitObjects();
}
catch
{
Logger.Log($"Cannot initialize objects!", LogType.ERROR);
}
Logger.Log($"Succesfully initialized objects!", LogType.INFO);
Logger.Log($"Preparing for constant buffer creation..", LogType.INFO);
try
{
// Create Constant Buffer for transformation matrices
contantBuffer = new Buffer(device, Utilities.SizeOf<Matrix>(), ResourceUsage.Dynamic, BindFlags.ConstantBuffer, CpuAccessFlags.Write, ResourceOptionFlags.None, 0);
}
catch
{
Logger.Log($"Cannot create constant buffer!", LogType.ERROR);
}
Logger.Log($"Succesfully created constant buffer!", LogType.INFO);
Logger.Log($"Setting up rendering state..", LogType.INFO);
try
{
// Set up Render State
context.InputAssembler.InputLayout = layout;
context.InputAssembler.PrimitiveTopology = PrimitiveTopology.TriangleList;
context.VertexShader.SetConstantBuffer(0, contantBuffer);
context.VertexShader.Set(vertexShader);
context.PixelShader.Set(pixelShader);
}
catch
{
Logger.Log($"Cannot set up rendering state!", LogType.ERROR);
}
Logger.Log($"Succesfully set up rendering state!", LogType.INFO);
Logger.Log($"Preparing camera setup..", LogType.INFO);
try
{
// Prepare matrices for the view and projection and initialize camera setup
view = Matrix.LookAtLH(new Vector3(0, 0, -5), new Vector3(0, 0, 1), new Vector3(0, 1, 0)); // View matrix
proj = Matrix.Identity; // Projection matrix
}
catch
{
Logger.Log($"Cannot prepare for camera setup!", LogType.ERROR);
}
Logger.Log($"Succesfully prepared camera setup!", LogType.INFO);
renderForm.Focus();
// Define a RasterizerStateDescription with backface culling enabled
rasterizerStateDescription = new RasterizerStateDescription
{
FillMode = SharpDX.Direct3D11.FillMode.Solid,
CullMode = CullMode.None, // Enable backface culling
IsMultisampleEnabled = true,
};
Logger.Log($"Starting RenderLoop", LogType.INFO);
// Start rendering loop
RenderLoop.Run(renderForm, () =>
{
RenderingLoop();
});
}
private void InitObjects()
{
// Create a root TreeNode for the scene
scene = new TreeNode
{
ImageIndex = 0,
SelectedImageIndex = 0,
Text = "Scene",
Tag = "Scene"
};
// Add the scene root node to the objectsView TreeView
objectsView.Nodes.Add(scene);
// Initialize Cube and Floor objects
Cube cube1 = new Cube("Cube1", ObjectType.Cube);
var cubeBuffer = Buffer.Create(device, BindFlags.VertexBuffer, cube1.VertexData);
cube1.Pos = new Vector3(-2f, 0, 0);
cube1.HasTexture = true;
cube1.VertexBuffer = cubeBuffer;
try
{
Texture2D texture;
ShaderResourceView textureView;
texture = TextureLoader.CreateTexture2DFromBitmap(device, TextureLoader.LoadBitmap(new SharpDX.WIC.ImagingFactory2(), "brick_texture.png"));
textureView = new ShaderResourceView(device, texture);
cube1.TextureView = textureView;
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
Cylinder cylinder1 = new Cylinder("Cylinder1", ObjectType.Cylinder);
var cylinder1Buffer = Buffer.Create(device, BindFlags.VertexBuffer, cylinder1.VertexData);
cylinder1.Pos = new Vector3(2f, 0, 0);
cylinder1.VertexBuffer = cylinder1Buffer;
Floor floor1 = new Floor("Floor1", ObjectType.Floor);
var floorBuffer = Buffer.Create(device, BindFlags.VertexBuffer, floor1.VertexData);
floor1.VertexBuffer = floorBuffer;
floor1.Pos = new Vector3(0f, (-1.01f) - 0.05f, 0f);
try
{
// Add the objects to the scene
objects.Add(cube1);
objects.Add(cylinder1);
objects.Add(floor1);
}
catch
{
Logger.Log($"Cannot add objects!", LogType.ERROR);
}
// Now add the objects to the scene TreeNode
foreach (Object obj in objects)
{
TreeNode objectNode = new TreeNode
{
ImageIndex = 1,
SelectedImageIndex = 1,
Tag = "Object",
Text = obj.Name // Set the name of the object as the text for the node
};
scene.Nodes.Add(objectNode);
Logger.Log($"Succesfully added object {obj.Name}", LogType.INFO);
}
// Refresh the objectsView TreeView to display the newly added nodes
objectsView.ExpandAll();
}
SamplerState samplerState;
private void RenderObjects()
{
context.InputAssembler.PrimitiveTopology = PrimitiveTopology.TriangleList; // Define the primitive topology
foreach (var rObject in objects)
{
// Convert degrees to radians
float radiansX = MathUtil.DegreesToRadians(rObject.Rotation.X);
float radiansY = MathUtil.DegreesToRadians(rObject.Rotation.Y);
float radiansZ = MathUtil.DegreesToRadians(rObject.Rotation.Z);
// Calculate world transformation matrices
var worldRotationX = Matrix.RotationX(radiansX); // Rotation around X-axis
var worldRotationY = Matrix.RotationY(radiansY); // Rotation around Y-axis
var worldRotationZ = Matrix.RotationZ(radiansZ); // Rotation around Z-axis
var worldRotation = worldRotationX * worldRotationY * worldRotationZ;
var worldTranslation = Matrix.Translation(rObject.Pos.X, rObject.Pos.Y, rObject.Pos.Z); // Position
var worldScaling = Matrix.Scaling(rObject.Scale.X, rObject.Scale.Y, rObject.Scale.Z); // Scale
// Combine transformations: Scaling -> Rotation -> Translation
var worldMatrix = worldScaling * worldRotation * worldTranslation;
var worldViewProj = worldMatrix * viewProj;
worldViewProj.Transpose();
// Check if the object has a texture
if (rObject.HasTexture)
{
// Set the texture
context.PixelShader.SetShaderResource(0, rObject.TextureView);
// Create and set sampler state
if (samplerState == null)
{
SamplerStateDescription samplerDesc = new SamplerStateDescription
{
Filter = SharpDX.Direct3D11.Filter.MinimumMinMagLinearMipPoint,
AddressU = TextureAddressMode.Wrap,
AddressV = TextureAddressMode.Wrap,
AddressW = TextureAddressMode.Wrap,
ComparisonFunction = Comparison.Never,
BorderColor = Color4.White,
MinimumLod = 0,
MaximumLod = float.MaxValue
};
samplerState = new SamplerState(device, samplerDesc);
}
context.PixelShader.SetSampler(0, samplerState);
}
else
{
context.PixelShader.SetShaderResource(0, null); // Unset texture to use color
}
// Map the constant buffer for writing (use MapMode.WriteDiscard)
DataStream dataStream;
context.MapSubresource(contantBuffer, 0, MapMode.WriteDiscard, SharpDX.Direct3D11.MapFlags.None, out dataStream);
// Write the worldViewProj matrix to the constant buffer
dataStream.Write(worldViewProj);
// Unmap the constant buffer, allowing the GPU to use it
context.UnmapSubresource(contantBuffer, 0);
// Set the object's vertex buffer and input layout
context.InputAssembler.SetVertexBuffers(0, new VertexBufferBinding(rObject.VertexBuffer, Utilities.SizeOf<Vertex>(), 0));
// Draw the object
context.Draw(rObject.VertexData.Length, 0);
}
}
</code>
<code>private void InitDX11() { Logger.Log($"Starting initializing dx11..", LogType.INFO); lastFrameTime = 0f; // Zainicjuj czas ostatniej klatki // Create the RenderForm renderForm = new RenderForm("DirectX 3D Cube") { FormBorderStyle = FormBorderStyle.None, KeyPreview = true, TopLevel = false, Dock = DockStyle.Fill, }; this.WindowState = FormWindowState.Normal; renderForm.MouseClick += (sender, e) => { renderForm.Focus(); }; renderForm.MouseLeave += (sender, e) => { this.Focus(); }; renderForm.MouseMove += (sender, e) => { if (!Initialized) { return; // Ignoruj zdarzenia myszy, jeśli program jeszcze się nie załadował. } if (attachCursor) { var centerX = renderForm.ClientSize.Width / 2; var centerY = renderForm.ClientSize.Height / 2; // Calculate mouse movement delta var deltaX = e.X - centerX; var deltaY = e.Y - centerY; // Update camera rotation based on mouse movement cameraYaw += deltaX * sensitivity; cameraPitch += -(deltaY * sensitivity); // Constrain the pitch to avoid gimbal lock (restrict pitch angle) cameraPitch = MathUtil.Clamp(cameraPitch, -MathUtil.PiOverTwo + 0.01f, MathUtil.PiOverTwo - 0.01f); // Center cursor back to the screen center (to keep continuous movement) Cursor.Position = renderForm.PointToScreen(new System.Drawing.Point(centerX, centerY)); } }; renderForm.KeyDown += (sender, e) => { if (attachCursor) { if (e.KeyCode == Keys.W) isWKeyPressed = true; else if (e.KeyCode == Keys.S) isSKeyPressed = true; else if (e.KeyCode == Keys.A) isAKeyPressed = true; else if (e.KeyCode == Keys.D) isDKeyPressed = true; else if (e.KeyCode == Keys.Space) isSpacePressed = true; // Spacebar pressed (upward) else if (e.KeyCode == Keys.ShiftKey) isShiftPressed = true; // Shift pressed (downward) else if (e.KeyCode == Keys.ControlKey) isCtrlPressed = true; // Shift pressed (downward) } }; renderForm.KeyUp += (sender, e) => { switch (e.KeyCode) { case Keys.F5: SetFullScreen(true); break; case Keys.F4: SetFullScreen(false); break; case Keys.F3: ToggleAttachCursor(); break; } if (attachCursor) { if (e.KeyCode == Keys.W) isWKeyPressed = false; else if (e.KeyCode == Keys.Oemtilde) { ToggleAttachCursor(); ToggleConsole(); } else if (e.KeyCode == Keys.S) isSKeyPressed = false; else if (e.KeyCode == Keys.A) isAKeyPressed = false; else if (e.KeyCode == Keys.D) isDKeyPressed = false; else if (e.KeyCode == Keys.Space) isSpacePressed = false; // Spacebar released else if (e.KeyCode == Keys.ShiftKey) isShiftPressed = false; // Shift released else if (e.KeyCode == Keys.ControlKey) isCtrlPressed = false; // Shift released } }; Logger.Log($"Events Added", LogType.INFO); dxApiRenderPanel.Controls.Add(renderForm); renderForm.BringToFront(); renderForm.Show(); // Set up the SwapChain description desc = new SwapChainDescription() { BufferCount = 2, // Number of back buffers ModeDescription = new ModeDescription(dxApiRenderPanel.ClientSize.Width, dxApiRenderPanel.ClientSize.Height, new Rational(60, 1), Format.R8G8B8A8_UNorm), // Resolution, refresh rate, and format IsWindowed = true, // Windowed mode OutputHandle = renderForm.Handle, // Handle to the window SampleDescription = new SampleDescription(8, 0), // multisampling SwapEffect = SwapEffect.Discard, // Swap effect Usage = Usage.RenderTargetOutput // Usage of the back buffer }; Logger.Log($"Creating device using swapchain..", LogType.INFO); try { // Create Device and SwapChain Device.CreateWithSwapChain(DriverType.Hardware, DeviceCreationFlags.None, desc, out device, out swapChain); context = device.ImmediateContext; } catch { Logger.Log($"Cannot create device with swapchain!", LogType.ERROR); } Logger.Log($"Succesfully created and added device with context!", LogType.INFO); Logger.Log($"Creating factory and making window association..", LogType.INFO); try { // Ignore all windows events var factory = swapChain.GetParent<SharpDX.DXGI.Factory>(); var adapter = factory.GetAdapter(0); var adapterDescription = adapter.Description; this.Text = $"RapidEngine11 - GPU: {adapterDescription.Description}"; factory.MakeWindowAssociation(renderForm.Handle, WindowAssociationFlags.IgnoreAll); } catch { Logger.Log($"Cannot create factory!", LogType.ERROR); } Logger.Log($"Succesfully created and added factory with window association!", LogType.INFO); Logger.Log($"Compiling shaders..", LogType.INFO); try { // Compile Shaders var vertexShaderByteCode = ShaderBytecode.CompileFromFile("Shader.fx", "VS", "vs_4_0"); vertexShader = new VertexShader(device, vertexShaderByteCode); var pixelShaderByteCode = ShaderBytecode.CompileFromFile("Shader.fx", "PS", "ps_4_0"); pixelShader = new PixelShader(device, pixelShaderByteCode); try { var signature = ShaderSignature.GetInputSignature(vertexShaderByteCode); layout = new InputLayout(device, signature, new[] { new InputElement("POSITION", 0, Format.R32G32B32A32_Float, 0, 0), new InputElement("COLOR", 0, Format.R32G32B32A32_Float, 16, 0), new InputElement("TEXCOORD", 0, Format.R32G32_Float, 32, 0) }); } catch { Logger.Log($"Cannot create layout!", LogType.ERROR); } } catch { Logger.Log($"Cannot compile shaders!", LogType.ERROR); } Logger.Log($"Succesfully compiled shaders and created shaders layout!", LogType.INFO); Logger.Log($"Preparing for objects initialization..", LogType.INFO); try { InitObjects(); } catch { Logger.Log($"Cannot initialize objects!", LogType.ERROR); } Logger.Log($"Succesfully initialized objects!", LogType.INFO); Logger.Log($"Preparing for constant buffer creation..", LogType.INFO); try { // Create Constant Buffer for transformation matrices contantBuffer = new Buffer(device, Utilities.SizeOf<Matrix>(), ResourceUsage.Dynamic, BindFlags.ConstantBuffer, CpuAccessFlags.Write, ResourceOptionFlags.None, 0); } catch { Logger.Log($"Cannot create constant buffer!", LogType.ERROR); } Logger.Log($"Succesfully created constant buffer!", LogType.INFO); Logger.Log($"Setting up rendering state..", LogType.INFO); try { // Set up Render State context.InputAssembler.InputLayout = layout; context.InputAssembler.PrimitiveTopology = PrimitiveTopology.TriangleList; context.VertexShader.SetConstantBuffer(0, contantBuffer); context.VertexShader.Set(vertexShader); context.PixelShader.Set(pixelShader); } catch { Logger.Log($"Cannot set up rendering state!", LogType.ERROR); } Logger.Log($"Succesfully set up rendering state!", LogType.INFO); Logger.Log($"Preparing camera setup..", LogType.INFO); try { // Prepare matrices for the view and projection and initialize camera setup view = Matrix.LookAtLH(new Vector3(0, 0, -5), new Vector3(0, 0, 1), new Vector3(0, 1, 0)); // View matrix proj = Matrix.Identity; // Projection matrix } catch { Logger.Log($"Cannot prepare for camera setup!", LogType.ERROR); } Logger.Log($"Succesfully prepared camera setup!", LogType.INFO); renderForm.Focus(); // Define a RasterizerStateDescription with backface culling enabled rasterizerStateDescription = new RasterizerStateDescription { FillMode = SharpDX.Direct3D11.FillMode.Solid, CullMode = CullMode.None, // Enable backface culling IsMultisampleEnabled = true, }; Logger.Log($"Starting RenderLoop", LogType.INFO); // Start rendering loop RenderLoop.Run(renderForm, () => { RenderingLoop(); }); } private void InitObjects() { // Create a root TreeNode for the scene scene = new TreeNode { ImageIndex = 0, SelectedImageIndex = 0, Text = "Scene", Tag = "Scene" }; // Add the scene root node to the objectsView TreeView objectsView.Nodes.Add(scene); // Initialize Cube and Floor objects Cube cube1 = new Cube("Cube1", ObjectType.Cube); var cubeBuffer = Buffer.Create(device, BindFlags.VertexBuffer, cube1.VertexData); cube1.Pos = new Vector3(-2f, 0, 0); cube1.HasTexture = true; cube1.VertexBuffer = cubeBuffer; try { Texture2D texture; ShaderResourceView textureView; texture = TextureLoader.CreateTexture2DFromBitmap(device, TextureLoader.LoadBitmap(new SharpDX.WIC.ImagingFactory2(), "brick_texture.png")); textureView = new ShaderResourceView(device, texture); cube1.TextureView = textureView; } catch (Exception ex) { MessageBox.Show(ex.Message); } Cylinder cylinder1 = new Cylinder("Cylinder1", ObjectType.Cylinder); var cylinder1Buffer = Buffer.Create(device, BindFlags.VertexBuffer, cylinder1.VertexData); cylinder1.Pos = new Vector3(2f, 0, 0); cylinder1.VertexBuffer = cylinder1Buffer; Floor floor1 = new Floor("Floor1", ObjectType.Floor); var floorBuffer = Buffer.Create(device, BindFlags.VertexBuffer, floor1.VertexData); floor1.VertexBuffer = floorBuffer; floor1.Pos = new Vector3(0f, (-1.01f) - 0.05f, 0f); try { // Add the objects to the scene objects.Add(cube1); objects.Add(cylinder1); objects.Add(floor1); } catch { Logger.Log($"Cannot add objects!", LogType.ERROR); } // Now add the objects to the scene TreeNode foreach (Object obj in objects) { TreeNode objectNode = new TreeNode { ImageIndex = 1, SelectedImageIndex = 1, Tag = "Object", Text = obj.Name // Set the name of the object as the text for the node }; scene.Nodes.Add(objectNode); Logger.Log($"Succesfully added object {obj.Name}", LogType.INFO); } // Refresh the objectsView TreeView to display the newly added nodes objectsView.ExpandAll(); } SamplerState samplerState; private void RenderObjects() { context.InputAssembler.PrimitiveTopology = PrimitiveTopology.TriangleList; // Define the primitive topology foreach (var rObject in objects) { // Convert degrees to radians float radiansX = MathUtil.DegreesToRadians(rObject.Rotation.X); float radiansY = MathUtil.DegreesToRadians(rObject.Rotation.Y); float radiansZ = MathUtil.DegreesToRadians(rObject.Rotation.Z); // Calculate world transformation matrices var worldRotationX = Matrix.RotationX(radiansX); // Rotation around X-axis var worldRotationY = Matrix.RotationY(radiansY); // Rotation around Y-axis var worldRotationZ = Matrix.RotationZ(radiansZ); // Rotation around Z-axis var worldRotation = worldRotationX * worldRotationY * worldRotationZ; var worldTranslation = Matrix.Translation(rObject.Pos.X, rObject.Pos.Y, rObject.Pos.Z); // Position var worldScaling = Matrix.Scaling(rObject.Scale.X, rObject.Scale.Y, rObject.Scale.Z); // Scale // Combine transformations: Scaling -> Rotation -> Translation var worldMatrix = worldScaling * worldRotation * worldTranslation; var worldViewProj = worldMatrix * viewProj; worldViewProj.Transpose(); // Check if the object has a texture if (rObject.HasTexture) { // Set the texture context.PixelShader.SetShaderResource(0, rObject.TextureView); // Create and set sampler state if (samplerState == null) { SamplerStateDescription samplerDesc = new SamplerStateDescription { Filter = SharpDX.Direct3D11.Filter.MinimumMinMagLinearMipPoint, AddressU = TextureAddressMode.Wrap, AddressV = TextureAddressMode.Wrap, AddressW = TextureAddressMode.Wrap, ComparisonFunction = Comparison.Never, BorderColor = Color4.White, MinimumLod = 0, MaximumLod = float.MaxValue }; samplerState = new SamplerState(device, samplerDesc); } context.PixelShader.SetSampler(0, samplerState); } else { context.PixelShader.SetShaderResource(0, null); // Unset texture to use color } // Map the constant buffer for writing (use MapMode.WriteDiscard) DataStream dataStream; context.MapSubresource(contantBuffer, 0, MapMode.WriteDiscard, SharpDX.Direct3D11.MapFlags.None, out dataStream); // Write the worldViewProj matrix to the constant buffer dataStream.Write(worldViewProj); // Unmap the constant buffer, allowing the GPU to use it context.UnmapSubresource(contantBuffer, 0); // Set the object's vertex buffer and input layout context.InputAssembler.SetVertexBuffers(0, new VertexBufferBinding(rObject.VertexBuffer, Utilities.SizeOf<Vertex>(), 0)); // Draw the object context.Draw(rObject.VertexData.Length, 0); } } </code>
private void InitDX11()
{
    Logger.Log($"Starting initializing dx11..", LogType.INFO);
    lastFrameTime = 0f;  // Zainicjuj czas ostatniej klatki
    // Create the RenderForm
    renderForm = new RenderForm("DirectX 3D Cube")
    {
        FormBorderStyle = FormBorderStyle.None,
        KeyPreview = true,
        TopLevel = false,
        Dock = DockStyle.Fill,
    };
    this.WindowState = FormWindowState.Normal;

    renderForm.MouseClick += (sender, e) =>
    {
        renderForm.Focus();
    };

    renderForm.MouseLeave += (sender, e) =>
    {
        this.Focus();
    };

    renderForm.MouseMove += (sender, e) =>
    {
        if (!Initialized)
        {
            return; // Ignoruj zdarzenia myszy, jeśli program jeszcze się nie załadował.
        }

        if (attachCursor)
        {
            var centerX = renderForm.ClientSize.Width / 2;
            var centerY = renderForm.ClientSize.Height / 2;

            // Calculate mouse movement delta
            var deltaX = e.X - centerX;
            var deltaY = e.Y - centerY;

            // Update camera rotation based on mouse movement
            cameraYaw += deltaX * sensitivity;
            cameraPitch += -(deltaY * sensitivity);

            // Constrain the pitch to avoid gimbal lock (restrict pitch angle)
            cameraPitch = MathUtil.Clamp(cameraPitch, -MathUtil.PiOverTwo + 0.01f, MathUtil.PiOverTwo - 0.01f);

            // Center cursor back to the screen center (to keep continuous movement)
            Cursor.Position = renderForm.PointToScreen(new System.Drawing.Point(centerX, centerY));
        }
    };

    renderForm.KeyDown += (sender, e) =>
    {
        if (attachCursor)
        {
            if (e.KeyCode == Keys.W) isWKeyPressed = true;
            else if (e.KeyCode == Keys.S) isSKeyPressed = true;
            else if (e.KeyCode == Keys.A) isAKeyPressed = true;
            else if (e.KeyCode == Keys.D) isDKeyPressed = true;
            else if (e.KeyCode == Keys.Space) isSpacePressed = true; // Spacebar pressed (upward)
            else if (e.KeyCode == Keys.ShiftKey) isShiftPressed = true; // Shift pressed (downward)
            else if (e.KeyCode == Keys.ControlKey) isCtrlPressed = true; // Shift pressed (downward)
        }
    };

    renderForm.KeyUp += (sender, e) =>
    {
        switch (e.KeyCode)
        {
            case Keys.F5:
                SetFullScreen(true);
                break;
            case Keys.F4:
                SetFullScreen(false);
                break;
            case Keys.F3:
                ToggleAttachCursor();
                break;

        }
        if (attachCursor)
        {
            if (e.KeyCode == Keys.W) isWKeyPressed = false;
            else if (e.KeyCode == Keys.Oemtilde)
            {
                ToggleAttachCursor();
                ToggleConsole();
            }
            else if (e.KeyCode == Keys.S) isSKeyPressed = false;
            else if (e.KeyCode == Keys.A) isAKeyPressed = false;
            else if (e.KeyCode == Keys.D) isDKeyPressed = false;
            else if (e.KeyCode == Keys.Space) isSpacePressed = false; // Spacebar released
            else if (e.KeyCode == Keys.ShiftKey) isShiftPressed = false; // Shift released
            else if (e.KeyCode == Keys.ControlKey) isCtrlPressed = false; // Shift released
        }
    };

    Logger.Log($"Events Added", LogType.INFO);

    dxApiRenderPanel.Controls.Add(renderForm);
    renderForm.BringToFront();
    renderForm.Show();

    // Set up the SwapChain description
    desc = new SwapChainDescription()
    {
        BufferCount = 2, // Number of back buffers
        ModeDescription = new ModeDescription(dxApiRenderPanel.ClientSize.Width, dxApiRenderPanel.ClientSize.Height, new Rational(60, 1), Format.R8G8B8A8_UNorm), // Resolution, refresh rate, and format
        IsWindowed = true, // Windowed mode
        OutputHandle = renderForm.Handle, // Handle to the window
        SampleDescription = new SampleDescription(8, 0), // multisampling
        SwapEffect = SwapEffect.Discard, // Swap effect
        Usage = Usage.RenderTargetOutput // Usage of the back buffer
    };


    Logger.Log($"Creating device using swapchain..", LogType.INFO);
    try
    {
        // Create Device and SwapChain
        Device.CreateWithSwapChain(DriverType.Hardware, DeviceCreationFlags.None, desc, out device, out swapChain);
        context = device.ImmediateContext;
    }
    catch
    {
        Logger.Log($"Cannot create device with swapchain!", LogType.ERROR);
    }
    Logger.Log($"Succesfully created and added device with context!", LogType.INFO);


    Logger.Log($"Creating factory and making window association..", LogType.INFO);
    try
    {
        // Ignore all windows events
        var factory = swapChain.GetParent<SharpDX.DXGI.Factory>();
        var adapter = factory.GetAdapter(0);
        var adapterDescription = adapter.Description;
        this.Text = $"RapidEngine11 - GPU: {adapterDescription.Description}";
        factory.MakeWindowAssociation(renderForm.Handle, WindowAssociationFlags.IgnoreAll);
    }
    catch
    {
        Logger.Log($"Cannot create factory!", LogType.ERROR);
    }
    Logger.Log($"Succesfully created and added factory with window association!", LogType.INFO);


    Logger.Log($"Compiling shaders..", LogType.INFO);
    try
    {
        // Compile Shaders
        var vertexShaderByteCode = ShaderBytecode.CompileFromFile("Shader.fx", "VS", "vs_4_0");
        vertexShader = new VertexShader(device, vertexShaderByteCode);

        var pixelShaderByteCode = ShaderBytecode.CompileFromFile("Shader.fx", "PS", "ps_4_0");
        pixelShader = new PixelShader(device, pixelShaderByteCode);

        try
        {
            var signature = ShaderSignature.GetInputSignature(vertexShaderByteCode);
            layout = new InputLayout(device, signature, new[]
            {
                new InputElement("POSITION", 0, Format.R32G32B32A32_Float, 0, 0),
                new InputElement("COLOR", 0, Format.R32G32B32A32_Float, 16, 0),
                new InputElement("TEXCOORD", 0, Format.R32G32_Float, 32, 0)
            });
        }
        catch
        {
            Logger.Log($"Cannot create layout!", LogType.ERROR);
        }

    }
    catch
    {
        Logger.Log($"Cannot compile shaders!", LogType.ERROR);
    }
    Logger.Log($"Succesfully compiled shaders and created shaders layout!", LogType.INFO);

    Logger.Log($"Preparing for objects initialization..", LogType.INFO);
    try
    {
        InitObjects();
    }
    catch
    {
        Logger.Log($"Cannot initialize objects!", LogType.ERROR);
    }
    Logger.Log($"Succesfully initialized objects!", LogType.INFO);


    Logger.Log($"Preparing for constant buffer creation..", LogType.INFO);
    try
    {
        // Create Constant Buffer for transformation matrices
        contantBuffer = new Buffer(device, Utilities.SizeOf<Matrix>(), ResourceUsage.Dynamic, BindFlags.ConstantBuffer, CpuAccessFlags.Write, ResourceOptionFlags.None, 0);
    }
    catch
    {
        Logger.Log($"Cannot create constant buffer!", LogType.ERROR);
    }
    Logger.Log($"Succesfully created constant buffer!", LogType.INFO);


    Logger.Log($"Setting up rendering state..", LogType.INFO);
    try
    {
        // Set up Render State
        context.InputAssembler.InputLayout = layout;
        context.InputAssembler.PrimitiveTopology = PrimitiveTopology.TriangleList;
        context.VertexShader.SetConstantBuffer(0, contantBuffer);
        context.VertexShader.Set(vertexShader);
        context.PixelShader.Set(pixelShader);
    }
    catch
    {
        Logger.Log($"Cannot set up rendering state!", LogType.ERROR);
    }
    Logger.Log($"Succesfully set up rendering state!", LogType.INFO);


    Logger.Log($"Preparing camera setup..", LogType.INFO);
    try
    {
        // Prepare matrices for the view and projection and initialize camera setup
        view = Matrix.LookAtLH(new Vector3(0, 0, -5), new Vector3(0, 0, 1), new Vector3(0, 1, 0)); // View matrix
        proj = Matrix.Identity; // Projection matrix
    }
    catch
    {
        Logger.Log($"Cannot prepare for camera setup!", LogType.ERROR);
    }
    Logger.Log($"Succesfully prepared camera setup!", LogType.INFO);



    renderForm.Focus();

    // Define a RasterizerStateDescription with backface culling enabled
    rasterizerStateDescription = new RasterizerStateDescription
    {
        FillMode = SharpDX.Direct3D11.FillMode.Solid,
        CullMode = CullMode.None, // Enable backface culling
        IsMultisampleEnabled = true,
    };


    Logger.Log($"Starting RenderLoop", LogType.INFO);
    // Start rendering loop
    RenderLoop.Run(renderForm, () =>
    {
        RenderingLoop();
    });
}

private void InitObjects()
{
    // Create a root TreeNode for the scene
    scene = new TreeNode
    {
        ImageIndex = 0,
        SelectedImageIndex = 0,
        Text = "Scene",
        Tag = "Scene"
    };

    // Add the scene root node to the objectsView TreeView
    objectsView.Nodes.Add(scene);


    // Initialize Cube and Floor objects
    Cube cube1 = new Cube("Cube1", ObjectType.Cube);
    var cubeBuffer = Buffer.Create(device, BindFlags.VertexBuffer, cube1.VertexData);
    cube1.Pos = new Vector3(-2f, 0, 0);
    cube1.HasTexture = true;
    cube1.VertexBuffer = cubeBuffer;


    try
    {
        Texture2D texture;
        ShaderResourceView textureView;

        texture = TextureLoader.CreateTexture2DFromBitmap(device, TextureLoader.LoadBitmap(new SharpDX.WIC.ImagingFactory2(), "brick_texture.png"));
        textureView = new ShaderResourceView(device, texture);

        cube1.TextureView = textureView;
    }
    catch (Exception ex)
    {
        MessageBox.Show(ex.Message);
    }
    


    Cylinder cylinder1 = new Cylinder("Cylinder1", ObjectType.Cylinder);
    var cylinder1Buffer = Buffer.Create(device, BindFlags.VertexBuffer, cylinder1.VertexData);
    cylinder1.Pos = new Vector3(2f, 0, 0);
    cylinder1.VertexBuffer = cylinder1Buffer;

    Floor floor1 = new Floor("Floor1", ObjectType.Floor);
    var floorBuffer = Buffer.Create(device, BindFlags.VertexBuffer, floor1.VertexData);
    floor1.VertexBuffer = floorBuffer;
    floor1.Pos = new Vector3(0f, (-1.01f) - 0.05f, 0f);

    try
    {
        // Add the objects to the scene
        objects.Add(cube1);
        objects.Add(cylinder1);
        objects.Add(floor1);
    }
    catch
    {
        Logger.Log($"Cannot add objects!", LogType.ERROR);
    }

    // Now add the objects to the scene TreeNode
    foreach (Object obj in objects)
    {
        TreeNode objectNode = new TreeNode
        {
            ImageIndex = 1,
            SelectedImageIndex = 1,
            Tag = "Object",
            Text = obj.Name // Set the name of the object as the text for the node
        };
        scene.Nodes.Add(objectNode);
        Logger.Log($"Succesfully added object {obj.Name}", LogType.INFO);
    }


    // Refresh the objectsView TreeView to display the newly added nodes
    objectsView.ExpandAll();
}

SamplerState samplerState;
private void RenderObjects()
{
    context.InputAssembler.PrimitiveTopology = PrimitiveTopology.TriangleList; // Define the primitive topology
                                                                               
    foreach (var rObject in objects)
    {
        // Convert degrees to radians
        float radiansX = MathUtil.DegreesToRadians(rObject.Rotation.X);
        float radiansY = MathUtil.DegreesToRadians(rObject.Rotation.Y);
        float radiansZ = MathUtil.DegreesToRadians(rObject.Rotation.Z);
        // Calculate world transformation matrices
        var worldRotationX = Matrix.RotationX(radiansX); // Rotation around X-axis
        var worldRotationY = Matrix.RotationY(radiansY); // Rotation around Y-axis
        var worldRotationZ = Matrix.RotationZ(radiansZ); // Rotation around Z-axis


        var worldRotation = worldRotationX * worldRotationY * worldRotationZ;
        var worldTranslation = Matrix.Translation(rObject.Pos.X, rObject.Pos.Y, rObject.Pos.Z); // Position
        var worldScaling = Matrix.Scaling(rObject.Scale.X, rObject.Scale.Y, rObject.Scale.Z); // Scale
                                                                                              // Combine transformations: Scaling -> Rotation -> Translation
        var worldMatrix = worldScaling * worldRotation * worldTranslation;
        var worldViewProj = worldMatrix * viewProj;
        worldViewProj.Transpose();

        // Check if the object has a texture
        if (rObject.HasTexture)
        {
            // Set the texture
            context.PixelShader.SetShaderResource(0, rObject.TextureView);

            // Create and set sampler state
            if (samplerState == null)
            {
                SamplerStateDescription samplerDesc = new SamplerStateDescription
                {
                    Filter = SharpDX.Direct3D11.Filter.MinimumMinMagLinearMipPoint,
                    AddressU = TextureAddressMode.Wrap,
                    AddressV = TextureAddressMode.Wrap,
                    AddressW = TextureAddressMode.Wrap,
                    ComparisonFunction = Comparison.Never,
                    BorderColor = Color4.White,
                    MinimumLod = 0,
                    MaximumLod = float.MaxValue
                };

                samplerState = new SamplerState(device, samplerDesc);
            }
            context.PixelShader.SetSampler(0, samplerState);
        }
        else
        {
            context.PixelShader.SetShaderResource(0, null); // Unset texture to use color
        }

        // Map the constant buffer for writing (use MapMode.WriteDiscard)
        DataStream dataStream;
        context.MapSubresource(contantBuffer, 0, MapMode.WriteDiscard, SharpDX.Direct3D11.MapFlags.None, out dataStream);

        // Write the worldViewProj matrix to the constant buffer
        dataStream.Write(worldViewProj);

        // Unmap the constant buffer, allowing the GPU to use it
        context.UnmapSubresource(contantBuffer, 0);

        // Set the object's vertex buffer and input layout
        context.InputAssembler.SetVertexBuffers(0, new VertexBufferBinding(rObject.VertexBuffer, Utilities.SizeOf<Vertex>(), 0));

        // Draw the object
        context.Draw(rObject.VertexData.Length, 0);
    }
}

Other Classes that i use

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
<code>public class TextureLoader
{
/// <summary>
/// Loads a bitmap using WIC.
/// </summary>
/// <param name="deviceManager"></param>
/// <param name="filename"></param>
/// <returns></returns>
public static SharpDX.WIC.BitmapSource LoadBitmap(SharpDX.WIC.ImagingFactory2 factory, string filename)
{
var bitmapDecoder = new SharpDX.WIC.BitmapDecoder(
factory,
filename,
SharpDX.WIC.DecodeOptions.CacheOnDemand
);
var formatConverter = new SharpDX.WIC.FormatConverter(factory);
formatConverter.Initialize(
bitmapDecoder.GetFrame(0),
SharpDX.WIC.PixelFormat.Format32bppPRGBA,
SharpDX.WIC.BitmapDitherType.None,
null,
0.0,
SharpDX.WIC.BitmapPaletteType.Custom);
return formatConverter;
}
/// <summary>
/// Creates a <see cref="SharpDX.Direct3D11.Texture2D"/> from a WIC <see cref="SharpDX.WIC.BitmapSource"/>
/// </summary>
/// <param name="device">The Direct3D11 device</param>
/// <param name="bitmapSource">The WIC bitmap source</param>
/// <returns>A Texture2D</returns>
public static SharpDX.Direct3D11.Texture2D CreateTexture2DFromBitmap(SharpDX.Direct3D11.Device device, SharpDX.WIC.BitmapSource bitmapSource)
{
// Allocate DataStream to receive the WIC image pixels
int stride = bitmapSource.Size.Width * 4;
using (var buffer = new SharpDX.DataStream(bitmapSource.Size.Height * stride, true, true))
{
// Copy the content of the WIC to the buffer
bitmapSource.CopyPixels(stride, buffer);
return new SharpDX.Direct3D11.Texture2D(device, new SharpDX.Direct3D11.Texture2DDescription()
{
Width = bitmapSource.Size.Width,
Height = bitmapSource.Size.Height,
ArraySize = 1,
BindFlags = SharpDX.Direct3D11.BindFlags.ShaderResource,
Usage = SharpDX.Direct3D11.ResourceUsage.Immutable,
CpuAccessFlags = SharpDX.Direct3D11.CpuAccessFlags.None,
Format = SharpDX.DXGI.Format.R8G8B8A8_UNorm,
MipLevels = 1,
OptionFlags = SharpDX.Direct3D11.ResourceOptionFlags.None,
SampleDescription = new SharpDX.DXGI.SampleDescription(1, 0),
}, new SharpDX.DataRectangle(buffer.DataPointer, stride));
}
}
}
internal class Cube : Object
{
public Cube(string name, ObjectType objType) : base(name, objType)
{
VertexData = new Vertex[]
{
// Front Face
new Vertex(new Vector4(-1.0f, -1.0f, -1.0f, 1.0f), new Color4(1.0f, 0.0f, 0.0f, 1.0f), new Vector2(0.0f, 1.0f)),
new Vertex(new Vector4(-1.0f, 1.0f, -1.0f, 1.0f), new Color4(1.0f, 0.0f, 0.0f, 1.0f), new Vector2(0.0f, 0.0f)),
new Vertex(new Vector4( 1.0f, 1.0f, -1.0f, 1.0f), new Color4(1.0f, 0.0f, 0.0f, 1.0f), new Vector2(1.0f, 0.0f)),
new Vertex(new Vector4(-1.0f, -1.0f, -1.0f, 1.0f), new Color4(1.0f, 0.0f, 0.0f, 1.0f), new Vector2(0.0f, 1.0f)),
new Vertex(new Vector4( 1.0f, 1.0f, -1.0f, 1.0f), new Color4(1.0f, 0.0f, 0.0f, 1.0f), new Vector2(1.0f, 0.0f)),
new Vertex(new Vector4( 1.0f, -1.0f, -1.0f, 1.0f), new Color4(1.0f, 0.0f, 0.0f, 1.0f), new Vector2(1.0f, 1.0f)),
// Back Face
new Vertex(new Vector4(-1.0f, -1.0f, 1.0f, 1.0f), new Color4(0.0f, 1.0f, 0.0f, 1.0f), new Vector2(0.0f, 1.0f)),
new Vertex(new Vector4( 1.0f, 1.0f, 1.0f, 1.0f), new Color4(0.0f, 1.0f, 0.0f, 1.0f), new Vector2(1.0f, 0.0f)),
new Vertex(new Vector4(-1.0f, 1.0f, 1.0f, 1.0f), new Color4(0.0f, 1.0f, 0.0f, 1.0f), new Vector2(0.0f, 0.0f)),
new Vertex(new Vector4(-1.0f, -1.0f, 1.0f, 1.0f), new Color4(0.0f, 1.0f, 0.0f, 1.0f), new Vector2(0.0f, 1.0f)),
new Vertex(new Vector4( 1.0f, -1.0f, 1.0f, 1.0f), new Color4(0.0f, 1.0f, 0.0f, 1.0f), new Vector2(1.0f, 1.0f)),
new Vertex(new Vector4( 1.0f, 1.0f, 1.0f, 1.0f), new Color4(0.0f, 1.0f, 0.0f, 1.0f), new Vector2(1.0f, 0.0f)),
// Top Face
new Vertex(new Vector4(-1.0f, 1.0f, -1.0f, 1.0f), new Color4(0.0f, 0.0f, 1.0f, 1.0f), new Vector2(0.0f, 1.0f)),
new Vertex(new Vector4(-1.0f, 1.0f, 1.0f, 1.0f), new Color4(0.0f, 0.0f, 1.0f, 1.0f), new Vector2(0.0f, 0.0f)),
new Vertex(new Vector4( 1.0f, 1.0f, 1.0f, 1.0f), new Color4(0.0f, 0.0f, 1.0f, 1.0f), new Vector2(1.0f, 0.0f)),
new Vertex(new Vector4(-1.0f, 1.0f, -1.0f, 1.0f), new Color4(0.0f, 0.0f, 1.0f, 1.0f), new Vector2(0.0f, 1.0f)),
new Vertex(new Vector4( 1.0f, 1.0f, 1.0f, 1.0f), new Color4(0.0f, 0.0f, 1.0f, 1.0f), new Vector2(1.0f, 0.0f)),
new Vertex(new Vector4( 1.0f, 1.0f, -1.0f, 1.0f), new Color4(0.0f, 0.0f, 1.0f, 1.0f), new Vector2(1.0f, 1.0f)),
// Bottom Face
new Vertex(new Vector4(-1.0f, -1.0f, -1.0f, 1.0f), new Color4(1.0f, 1.0f, 0.0f, 1.0f), new Vector2(0.0f, 1.0f)),
new Vertex(new Vector4( 1.0f, -1.0f, 1.0f, 1.0f), new Color4(1.0f, 1.0f, 0.0f, 1.0f), new Vector2(1.0f, 0.0f)),
new Vertex(new Vector4(-1.0f, -1.0f, 1.0f, 1.0f), new Color4(1.0f, 1.0f, 0.0f, 1.0f), new Vector2(0.0f, 0.0f)),
new Vertex(new Vector4(-1.0f, -1.0f, -1.0f, 1.0f), new Color4(1.0f, 1.0f, 0.0f, 1.0f), new Vector2(0.0f, 1.0f)),
new Vertex(new Vector4( 1.0f, -1.0f, -1.0f, 1.0f), new Color4(1.0f, 1.0f, 0.0f, 1.0f), new Vector2(1.0f, 1.0f)),
new Vertex(new Vector4( 1.0f, -1.0f, 1.0f, 1.0f), new Color4(1.0f, 1.0f, 0.0f, 1.0f), new Vector2(1.0f, 0.0f)),
// Left Face
new Vertex(new Vector4(-1.0f, -1.0f, -1.0f, 1.0f), new Color4(0.0f, 1.0f, 1.0f, 1.0f), new Vector2(0.0f, 1.0f)),
new Vertex(new Vector4(-1.0f, 1.0f, 1.0f, 1.0f), new Color4(0.0f, 1.0f, 1.0f, 1.0f), new Vector2(1.0f, 0.0f)),
new Vertex(new Vector4(-1.0f, 1.0f, -1.0f, 1.0f), new Color4(0.0f, 1.0f, 1.0f, 1.0f), new Vector2(0.0f, 0.0f)),
new Vertex(new Vector4(-1.0f, -1.0f, -1.0f, 1.0f), new Color4(0.0f, 1.0f, 1.0f, 1.0f), new Vector2(0.0f, 1.0f)),
new Vertex(new Vector4(-1.0f, -1.0f, 1.0f, 1.0f), new Color4(0.0f, 1.0f, 1.0f, 1.0f), new Vector2(1.0f, 1.0f)),
new Vertex(new Vector4(-1.0f, 1.0f, 1.0f, 1.0f), new Color4(0.0f, 1.0f, 1.0f, 1.0f), new Vector2(1.0f, 0.0f)),
// Right Face
new Vertex(new Vector4( 1.0f, -1.0f, -1.0f, 1.0f), new Color4(1.0f, 0.0f, 1.0f, 1.0f), new Vector2(0.0f, 1.0f)),
new Vertex(new Vector4( 1.0f, 1.0f, 1.0f, 1.0f), new Color4(1.0f, 0.0f, 1.0f, 1.0f), new Vector2(1.0f, 0.0f)),
new Vertex(new Vector4( 1.0f, 1.0f, -1.0f, 1.0f), new Color4(1.0f, 0.0f, 1.0f, 1.0f), new Vector2(0.0f, 0.0f)),
new Vertex(new Vector4( 1.0f, -1.0f, -1.0f, 1.0f), new Color4(1.0f, 0.0f, 1.0f, 1.0f), new Vector2(0.0f, 1.0f)),
new Vertex(new Vector4( 1.0f, -1.0f, 1.0f, 1.0f), new Color4(1.0f, 0.0f, 1.0f, 1.0f), new Vector2(1.0f, 1.0f)),
new Vertex(new Vector4( 1.0f, 1.0f, 1.0f, 1.0f), new Color4(1.0f, 0.0f, 1.0f, 1.0f), new Vector2(1.0f, 0.0f)),
};
}
}
public abstract class Object
{
// Basic transformation properties
public Vector3 Rotation { get; set; } = new Vector3 (0.0f, 0.0f, 0.0f);
public Vector3 Scale { get; set; } = new Vector3 (1.0f, 1.0f, 1.0f);
public Vector3 Pos { get; set; }
public Vertex[] VertexData { get; set; }
public Buffer VertexBuffer { get; set; }
// Name of the object (required by all derived classes)
public string Name { get; private set; }
public string Tag { get; private set; }
public ObjectType ObjectType { get; private set; }
public bool HasTexture { get; set; }
public ShaderResourceView TextureView { get; set; }
// Constructor that enforces providing a name
public Object(string name, ObjectType objectType = ObjectType.Cube, bool hasTexture = false, string tag = null)
{
Name = name ?? throw new ArgumentNullException(nameof(name), "Object name cannot be null");
Tag = tag;
HasTexture = hasTexture;
ObjectType = objectType;
}
// Dispose resources
public virtual void Dispose()
{
VertexBuffer?.Dispose();
}
}
public enum ObjectType
{
Cube,
Cylinder,
Floor
}
[StructLayout(LayoutKind.Sequential)]
public struct Vertex
{
public Vector4 Position;
public Color4 Color;
public Vector2? TexCoord; // Add texture coordinates
public Vertex(Vector4 position, Color4 color, Vector2? texCoord = null)
{
Position = position;
Color = color;
TexCoord = texCoord;
}
}
</code>
<code>public class TextureLoader { /// <summary> /// Loads a bitmap using WIC. /// </summary> /// <param name="deviceManager"></param> /// <param name="filename"></param> /// <returns></returns> public static SharpDX.WIC.BitmapSource LoadBitmap(SharpDX.WIC.ImagingFactory2 factory, string filename) { var bitmapDecoder = new SharpDX.WIC.BitmapDecoder( factory, filename, SharpDX.WIC.DecodeOptions.CacheOnDemand ); var formatConverter = new SharpDX.WIC.FormatConverter(factory); formatConverter.Initialize( bitmapDecoder.GetFrame(0), SharpDX.WIC.PixelFormat.Format32bppPRGBA, SharpDX.WIC.BitmapDitherType.None, null, 0.0, SharpDX.WIC.BitmapPaletteType.Custom); return formatConverter; } /// <summary> /// Creates a <see cref="SharpDX.Direct3D11.Texture2D"/> from a WIC <see cref="SharpDX.WIC.BitmapSource"/> /// </summary> /// <param name="device">The Direct3D11 device</param> /// <param name="bitmapSource">The WIC bitmap source</param> /// <returns>A Texture2D</returns> public static SharpDX.Direct3D11.Texture2D CreateTexture2DFromBitmap(SharpDX.Direct3D11.Device device, SharpDX.WIC.BitmapSource bitmapSource) { // Allocate DataStream to receive the WIC image pixels int stride = bitmapSource.Size.Width * 4; using (var buffer = new SharpDX.DataStream(bitmapSource.Size.Height * stride, true, true)) { // Copy the content of the WIC to the buffer bitmapSource.CopyPixels(stride, buffer); return new SharpDX.Direct3D11.Texture2D(device, new SharpDX.Direct3D11.Texture2DDescription() { Width = bitmapSource.Size.Width, Height = bitmapSource.Size.Height, ArraySize = 1, BindFlags = SharpDX.Direct3D11.BindFlags.ShaderResource, Usage = SharpDX.Direct3D11.ResourceUsage.Immutable, CpuAccessFlags = SharpDX.Direct3D11.CpuAccessFlags.None, Format = SharpDX.DXGI.Format.R8G8B8A8_UNorm, MipLevels = 1, OptionFlags = SharpDX.Direct3D11.ResourceOptionFlags.None, SampleDescription = new SharpDX.DXGI.SampleDescription(1, 0), }, new SharpDX.DataRectangle(buffer.DataPointer, stride)); } } } internal class Cube : Object { public Cube(string name, ObjectType objType) : base(name, objType) { VertexData = new Vertex[] { // Front Face new Vertex(new Vector4(-1.0f, -1.0f, -1.0f, 1.0f), new Color4(1.0f, 0.0f, 0.0f, 1.0f), new Vector2(0.0f, 1.0f)), new Vertex(new Vector4(-1.0f, 1.0f, -1.0f, 1.0f), new Color4(1.0f, 0.0f, 0.0f, 1.0f), new Vector2(0.0f, 0.0f)), new Vertex(new Vector4( 1.0f, 1.0f, -1.0f, 1.0f), new Color4(1.0f, 0.0f, 0.0f, 1.0f), new Vector2(1.0f, 0.0f)), new Vertex(new Vector4(-1.0f, -1.0f, -1.0f, 1.0f), new Color4(1.0f, 0.0f, 0.0f, 1.0f), new Vector2(0.0f, 1.0f)), new Vertex(new Vector4( 1.0f, 1.0f, -1.0f, 1.0f), new Color4(1.0f, 0.0f, 0.0f, 1.0f), new Vector2(1.0f, 0.0f)), new Vertex(new Vector4( 1.0f, -1.0f, -1.0f, 1.0f), new Color4(1.0f, 0.0f, 0.0f, 1.0f), new Vector2(1.0f, 1.0f)), // Back Face new Vertex(new Vector4(-1.0f, -1.0f, 1.0f, 1.0f), new Color4(0.0f, 1.0f, 0.0f, 1.0f), new Vector2(0.0f, 1.0f)), new Vertex(new Vector4( 1.0f, 1.0f, 1.0f, 1.0f), new Color4(0.0f, 1.0f, 0.0f, 1.0f), new Vector2(1.0f, 0.0f)), new Vertex(new Vector4(-1.0f, 1.0f, 1.0f, 1.0f), new Color4(0.0f, 1.0f, 0.0f, 1.0f), new Vector2(0.0f, 0.0f)), new Vertex(new Vector4(-1.0f, -1.0f, 1.0f, 1.0f), new Color4(0.0f, 1.0f, 0.0f, 1.0f), new Vector2(0.0f, 1.0f)), new Vertex(new Vector4( 1.0f, -1.0f, 1.0f, 1.0f), new Color4(0.0f, 1.0f, 0.0f, 1.0f), new Vector2(1.0f, 1.0f)), new Vertex(new Vector4( 1.0f, 1.0f, 1.0f, 1.0f), new Color4(0.0f, 1.0f, 0.0f, 1.0f), new Vector2(1.0f, 0.0f)), // Top Face new Vertex(new Vector4(-1.0f, 1.0f, -1.0f, 1.0f), new Color4(0.0f, 0.0f, 1.0f, 1.0f), new Vector2(0.0f, 1.0f)), new Vertex(new Vector4(-1.0f, 1.0f, 1.0f, 1.0f), new Color4(0.0f, 0.0f, 1.0f, 1.0f), new Vector2(0.0f, 0.0f)), new Vertex(new Vector4( 1.0f, 1.0f, 1.0f, 1.0f), new Color4(0.0f, 0.0f, 1.0f, 1.0f), new Vector2(1.0f, 0.0f)), new Vertex(new Vector4(-1.0f, 1.0f, -1.0f, 1.0f), new Color4(0.0f, 0.0f, 1.0f, 1.0f), new Vector2(0.0f, 1.0f)), new Vertex(new Vector4( 1.0f, 1.0f, 1.0f, 1.0f), new Color4(0.0f, 0.0f, 1.0f, 1.0f), new Vector2(1.0f, 0.0f)), new Vertex(new Vector4( 1.0f, 1.0f, -1.0f, 1.0f), new Color4(0.0f, 0.0f, 1.0f, 1.0f), new Vector2(1.0f, 1.0f)), // Bottom Face new Vertex(new Vector4(-1.0f, -1.0f, -1.0f, 1.0f), new Color4(1.0f, 1.0f, 0.0f, 1.0f), new Vector2(0.0f, 1.0f)), new Vertex(new Vector4( 1.0f, -1.0f, 1.0f, 1.0f), new Color4(1.0f, 1.0f, 0.0f, 1.0f), new Vector2(1.0f, 0.0f)), new Vertex(new Vector4(-1.0f, -1.0f, 1.0f, 1.0f), new Color4(1.0f, 1.0f, 0.0f, 1.0f), new Vector2(0.0f, 0.0f)), new Vertex(new Vector4(-1.0f, -1.0f, -1.0f, 1.0f), new Color4(1.0f, 1.0f, 0.0f, 1.0f), new Vector2(0.0f, 1.0f)), new Vertex(new Vector4( 1.0f, -1.0f, -1.0f, 1.0f), new Color4(1.0f, 1.0f, 0.0f, 1.0f), new Vector2(1.0f, 1.0f)), new Vertex(new Vector4( 1.0f, -1.0f, 1.0f, 1.0f), new Color4(1.0f, 1.0f, 0.0f, 1.0f), new Vector2(1.0f, 0.0f)), // Left Face new Vertex(new Vector4(-1.0f, -1.0f, -1.0f, 1.0f), new Color4(0.0f, 1.0f, 1.0f, 1.0f), new Vector2(0.0f, 1.0f)), new Vertex(new Vector4(-1.0f, 1.0f, 1.0f, 1.0f), new Color4(0.0f, 1.0f, 1.0f, 1.0f), new Vector2(1.0f, 0.0f)), new Vertex(new Vector4(-1.0f, 1.0f, -1.0f, 1.0f), new Color4(0.0f, 1.0f, 1.0f, 1.0f), new Vector2(0.0f, 0.0f)), new Vertex(new Vector4(-1.0f, -1.0f, -1.0f, 1.0f), new Color4(0.0f, 1.0f, 1.0f, 1.0f), new Vector2(0.0f, 1.0f)), new Vertex(new Vector4(-1.0f, -1.0f, 1.0f, 1.0f), new Color4(0.0f, 1.0f, 1.0f, 1.0f), new Vector2(1.0f, 1.0f)), new Vertex(new Vector4(-1.0f, 1.0f, 1.0f, 1.0f), new Color4(0.0f, 1.0f, 1.0f, 1.0f), new Vector2(1.0f, 0.0f)), // Right Face new Vertex(new Vector4( 1.0f, -1.0f, -1.0f, 1.0f), new Color4(1.0f, 0.0f, 1.0f, 1.0f), new Vector2(0.0f, 1.0f)), new Vertex(new Vector4( 1.0f, 1.0f, 1.0f, 1.0f), new Color4(1.0f, 0.0f, 1.0f, 1.0f), new Vector2(1.0f, 0.0f)), new Vertex(new Vector4( 1.0f, 1.0f, -1.0f, 1.0f), new Color4(1.0f, 0.0f, 1.0f, 1.0f), new Vector2(0.0f, 0.0f)), new Vertex(new Vector4( 1.0f, -1.0f, -1.0f, 1.0f), new Color4(1.0f, 0.0f, 1.0f, 1.0f), new Vector2(0.0f, 1.0f)), new Vertex(new Vector4( 1.0f, -1.0f, 1.0f, 1.0f), new Color4(1.0f, 0.0f, 1.0f, 1.0f), new Vector2(1.0f, 1.0f)), new Vertex(new Vector4( 1.0f, 1.0f, 1.0f, 1.0f), new Color4(1.0f, 0.0f, 1.0f, 1.0f), new Vector2(1.0f, 0.0f)), }; } } public abstract class Object { // Basic transformation properties public Vector3 Rotation { get; set; } = new Vector3 (0.0f, 0.0f, 0.0f); public Vector3 Scale { get; set; } = new Vector3 (1.0f, 1.0f, 1.0f); public Vector3 Pos { get; set; } public Vertex[] VertexData { get; set; } public Buffer VertexBuffer { get; set; } // Name of the object (required by all derived classes) public string Name { get; private set; } public string Tag { get; private set; } public ObjectType ObjectType { get; private set; } public bool HasTexture { get; set; } public ShaderResourceView TextureView { get; set; } // Constructor that enforces providing a name public Object(string name, ObjectType objectType = ObjectType.Cube, bool hasTexture = false, string tag = null) { Name = name ?? throw new ArgumentNullException(nameof(name), "Object name cannot be null"); Tag = tag; HasTexture = hasTexture; ObjectType = objectType; } // Dispose resources public virtual void Dispose() { VertexBuffer?.Dispose(); } } public enum ObjectType { Cube, Cylinder, Floor } [StructLayout(LayoutKind.Sequential)] public struct Vertex { public Vector4 Position; public Color4 Color; public Vector2? TexCoord; // Add texture coordinates public Vertex(Vector4 position, Color4 color, Vector2? texCoord = null) { Position = position; Color = color; TexCoord = texCoord; } } </code>
public class TextureLoader
{
    /// <summary>
    /// Loads a bitmap using WIC.
    /// </summary>
    /// <param name="deviceManager"></param>
    /// <param name="filename"></param>
    /// <returns></returns>
    public static SharpDX.WIC.BitmapSource LoadBitmap(SharpDX.WIC.ImagingFactory2 factory, string filename)
    {
        var bitmapDecoder = new SharpDX.WIC.BitmapDecoder(
            factory,
            filename,
            SharpDX.WIC.DecodeOptions.CacheOnDemand
            );

        var formatConverter = new SharpDX.WIC.FormatConverter(factory);

        formatConverter.Initialize(
            bitmapDecoder.GetFrame(0),
            SharpDX.WIC.PixelFormat.Format32bppPRGBA,
            SharpDX.WIC.BitmapDitherType.None,
            null,
            0.0,
            SharpDX.WIC.BitmapPaletteType.Custom);

        return formatConverter;
    }

    /// <summary>
    /// Creates a <see cref="SharpDX.Direct3D11.Texture2D"/> from a WIC <see cref="SharpDX.WIC.BitmapSource"/>
    /// </summary>
    /// <param name="device">The Direct3D11 device</param>
    /// <param name="bitmapSource">The WIC bitmap source</param>
    /// <returns>A Texture2D</returns>
    public static SharpDX.Direct3D11.Texture2D CreateTexture2DFromBitmap(SharpDX.Direct3D11.Device device, SharpDX.WIC.BitmapSource bitmapSource)
    {
        // Allocate DataStream to receive the WIC image pixels
        int stride = bitmapSource.Size.Width * 4;
        using (var buffer = new SharpDX.DataStream(bitmapSource.Size.Height * stride, true, true))
        {
            // Copy the content of the WIC to the buffer
            bitmapSource.CopyPixels(stride, buffer);
            return new SharpDX.Direct3D11.Texture2D(device, new SharpDX.Direct3D11.Texture2DDescription()
            {
                Width = bitmapSource.Size.Width,
                Height = bitmapSource.Size.Height,
                ArraySize = 1,
                BindFlags = SharpDX.Direct3D11.BindFlags.ShaderResource,
                Usage = SharpDX.Direct3D11.ResourceUsage.Immutable,
                CpuAccessFlags = SharpDX.Direct3D11.CpuAccessFlags.None,
                Format = SharpDX.DXGI.Format.R8G8B8A8_UNorm,
                MipLevels = 1,
                OptionFlags = SharpDX.Direct3D11.ResourceOptionFlags.None,
                SampleDescription = new SharpDX.DXGI.SampleDescription(1, 0),
            }, new SharpDX.DataRectangle(buffer.DataPointer, stride));
        }
    }
}


internal class Cube : Object
{
    public Cube(string name, ObjectType objType) : base(name, objType)
    {
        VertexData = new Vertex[]
        {
            // Front Face
            new Vertex(new Vector4(-1.0f, -1.0f, -1.0f, 1.0f), new Color4(1.0f, 0.0f, 0.0f, 1.0f), new Vector2(0.0f, 1.0f)),
            new Vertex(new Vector4(-1.0f,  1.0f, -1.0f, 1.0f), new Color4(1.0f, 0.0f, 0.0f, 1.0f), new Vector2(0.0f, 0.0f)),
            new Vertex(new Vector4( 1.0f,  1.0f, -1.0f, 1.0f), new Color4(1.0f, 0.0f, 0.0f, 1.0f), new Vector2(1.0f, 0.0f)),
            new Vertex(new Vector4(-1.0f, -1.0f, -1.0f, 1.0f), new Color4(1.0f, 0.0f, 0.0f, 1.0f), new Vector2(0.0f, 1.0f)),
            new Vertex(new Vector4( 1.0f,  1.0f, -1.0f, 1.0f), new Color4(1.0f, 0.0f, 0.0f, 1.0f), new Vector2(1.0f, 0.0f)),
            new Vertex(new Vector4( 1.0f, -1.0f, -1.0f, 1.0f), new Color4(1.0f, 0.0f, 0.0f, 1.0f), new Vector2(1.0f, 1.0f)),

            // Back Face
            new Vertex(new Vector4(-1.0f, -1.0f,  1.0f, 1.0f), new Color4(0.0f, 1.0f, 0.0f, 1.0f), new Vector2(0.0f, 1.0f)),
            new Vertex(new Vector4( 1.0f,  1.0f,  1.0f, 1.0f), new Color4(0.0f, 1.0f, 0.0f, 1.0f), new Vector2(1.0f, 0.0f)),
            new Vertex(new Vector4(-1.0f,  1.0f,  1.0f, 1.0f), new Color4(0.0f, 1.0f, 0.0f, 1.0f), new Vector2(0.0f, 0.0f)),
            new Vertex(new Vector4(-1.0f, -1.0f,  1.0f, 1.0f), new Color4(0.0f, 1.0f, 0.0f, 1.0f), new Vector2(0.0f, 1.0f)),
            new Vertex(new Vector4( 1.0f, -1.0f,  1.0f, 1.0f), new Color4(0.0f, 1.0f, 0.0f, 1.0f), new Vector2(1.0f, 1.0f)),
            new Vertex(new Vector4( 1.0f,  1.0f,  1.0f, 1.0f), new Color4(0.0f, 1.0f, 0.0f, 1.0f), new Vector2(1.0f, 0.0f)),

            // Top Face
            new Vertex(new Vector4(-1.0f, 1.0f, -1.0f,  1.0f), new Color4(0.0f, 0.0f, 1.0f, 1.0f), new Vector2(0.0f, 1.0f)),
            new Vertex(new Vector4(-1.0f, 1.0f,  1.0f,  1.0f), new Color4(0.0f, 0.0f, 1.0f, 1.0f), new Vector2(0.0f, 0.0f)),
            new Vertex(new Vector4( 1.0f, 1.0f,  1.0f,  1.0f), new Color4(0.0f, 0.0f, 1.0f, 1.0f), new Vector2(1.0f, 0.0f)),
            new Vertex(new Vector4(-1.0f, 1.0f, -1.0f,  1.0f), new Color4(0.0f, 0.0f, 1.0f, 1.0f), new Vector2(0.0f, 1.0f)),
            new Vertex(new Vector4( 1.0f, 1.0f,  1.0f,  1.0f), new Color4(0.0f, 0.0f, 1.0f, 1.0f), new Vector2(1.0f, 0.0f)),
            new Vertex(new Vector4( 1.0f, 1.0f, -1.0f,  1.0f), new Color4(0.0f, 0.0f, 1.0f, 1.0f), new Vector2(1.0f, 1.0f)),

            // Bottom Face
            new Vertex(new Vector4(-1.0f, -1.0f, -1.0f,  1.0f), new Color4(1.0f, 1.0f, 0.0f, 1.0f), new Vector2(0.0f, 1.0f)),
            new Vertex(new Vector4( 1.0f, -1.0f,  1.0f,  1.0f), new Color4(1.0f, 1.0f, 0.0f, 1.0f), new Vector2(1.0f, 0.0f)),
            new Vertex(new Vector4(-1.0f, -1.0f,  1.0f,  1.0f), new Color4(1.0f, 1.0f, 0.0f, 1.0f), new Vector2(0.0f, 0.0f)),
            new Vertex(new Vector4(-1.0f, -1.0f, -1.0f,  1.0f), new Color4(1.0f, 1.0f, 0.0f, 1.0f), new Vector2(0.0f, 1.0f)),
            new Vertex(new Vector4( 1.0f, -1.0f, -1.0f,  1.0f), new Color4(1.0f, 1.0f, 0.0f, 1.0f), new Vector2(1.0f, 1.0f)),
            new Vertex(new Vector4( 1.0f, -1.0f,  1.0f,  1.0f), new Color4(1.0f, 1.0f, 0.0f, 1.0f), new Vector2(1.0f, 0.0f)),

            // Left Face
            new Vertex(new Vector4(-1.0f, -1.0f, -1.0f,  1.0f), new Color4(0.0f, 1.0f, 1.0f, 1.0f), new Vector2(0.0f, 1.0f)),
            new Vertex(new Vector4(-1.0f,  1.0f,  1.0f,  1.0f), new Color4(0.0f, 1.0f, 1.0f, 1.0f), new Vector2(1.0f, 0.0f)),
            new Vertex(new Vector4(-1.0f,  1.0f, -1.0f,  1.0f), new Color4(0.0f, 1.0f, 1.0f, 1.0f), new Vector2(0.0f, 0.0f)),
            new Vertex(new Vector4(-1.0f, -1.0f, -1.0f,  1.0f), new Color4(0.0f, 1.0f, 1.0f, 1.0f), new Vector2(0.0f, 1.0f)),
            new Vertex(new Vector4(-1.0f, -1.0f,  1.0f,  1.0f), new Color4(0.0f, 1.0f, 1.0f, 1.0f), new Vector2(1.0f, 1.0f)),
            new Vertex(new Vector4(-1.0f,  1.0f,  1.0f,  1.0f), new Color4(0.0f, 1.0f, 1.0f, 1.0f), new Vector2(1.0f, 0.0f)),

            // Right Face
            new Vertex(new Vector4( 1.0f, -1.0f, -1.0f,  1.0f), new Color4(1.0f, 0.0f, 1.0f, 1.0f), new Vector2(0.0f, 1.0f)),
            new Vertex(new Vector4( 1.0f,  1.0f,  1.0f,  1.0f), new Color4(1.0f, 0.0f, 1.0f, 1.0f), new Vector2(1.0f, 0.0f)),
            new Vertex(new Vector4( 1.0f,  1.0f, -1.0f,  1.0f), new Color4(1.0f, 0.0f, 1.0f, 1.0f), new Vector2(0.0f, 0.0f)),
            new Vertex(new Vector4( 1.0f, -1.0f, -1.0f,  1.0f), new Color4(1.0f, 0.0f, 1.0f, 1.0f), new Vector2(0.0f, 1.0f)),
            new Vertex(new Vector4( 1.0f, -1.0f,  1.0f,  1.0f), new Color4(1.0f, 0.0f, 1.0f, 1.0f), new Vector2(1.0f, 1.0f)),
            new Vertex(new Vector4( 1.0f,  1.0f,  1.0f,  1.0f), new Color4(1.0f, 0.0f, 1.0f, 1.0f), new Vector2(1.0f, 0.0f)),
        };
    }
}

public abstract class Object
{
    // Basic transformation properties
    public Vector3 Rotation { get; set; } = new Vector3 (0.0f, 0.0f, 0.0f);
    public Vector3 Scale { get; set; } = new Vector3 (1.0f, 1.0f, 1.0f);
    public Vector3 Pos { get; set; }

    public Vertex[] VertexData { get; set; }

    public Buffer VertexBuffer { get; set; }

    // Name of the object (required by all derived classes)
    public string Name { get; private set; }
    public string Tag { get; private set; }

    public ObjectType ObjectType { get; private set; }

    public bool HasTexture { get; set; }
    public ShaderResourceView TextureView { get; set; }

    // Constructor that enforces providing a name
    public Object(string name, ObjectType objectType = ObjectType.Cube, bool hasTexture = false, string tag = null)
    {
        Name = name ?? throw new ArgumentNullException(nameof(name), "Object name cannot be null");
        Tag = tag;
        HasTexture = hasTexture;
        ObjectType = objectType;
    }

    // Dispose resources
    public virtual void Dispose()
    {
        VertexBuffer?.Dispose();
    }
}

public enum ObjectType
{
    Cube,
    Cylinder,
    Floor
}

 [StructLayout(LayoutKind.Sequential)]
 public struct Vertex
 {
     public Vector4 Position;
     public Color4 Color;
     public Vector2? TexCoord; // Add texture coordinates

     public Vertex(Vector4 position, Color4 color, Vector2? texCoord = null)
     {
         Position = position;
         Color = color;
         TexCoord = texCoord;
     }
 }

My Shader code

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
<code>// Shader.fx
cbuffer MatrixBuffer : register(b0)
{
matrix WorldViewProj;
};
Texture2D tex : register(t0); // Add texture sampler
SamplerState samp : register(s0);
struct VS_IN
{
float4 pos : POSITION;
float4 col : COLOR;
float2 tex : TEXCOORD; // Add texture coordinates
};
struct PS_IN
{
float4 pos : SV_POSITION;
float4 col : COLOR;
float2 tex : TEXCOORD;
};
float4x4 worldViewProj;
PS_IN VS(VS_IN input)
{
PS_IN output = (PS_IN)0;
output.pos = mul(input.pos, WorldViewProj);
output.col = input.col;
output.tex = input.tex;
return output;
}
float4 PS(PS_IN input) : SV_Target
{
float4 textureColor = tex.Sample(samp, input.tex);
// Debugging: Check the sampled color
// Uncomment the line below to see the texture color being sampled
//return textureColor;
// Fallback to vertex color if texture alpha is zero
return (textureColor.a > 0.0f) ? textureColor : input.col;
}
</code>
<code>// Shader.fx cbuffer MatrixBuffer : register(b0) { matrix WorldViewProj; }; Texture2D tex : register(t0); // Add texture sampler SamplerState samp : register(s0); struct VS_IN { float4 pos : POSITION; float4 col : COLOR; float2 tex : TEXCOORD; // Add texture coordinates }; struct PS_IN { float4 pos : SV_POSITION; float4 col : COLOR; float2 tex : TEXCOORD; }; float4x4 worldViewProj; PS_IN VS(VS_IN input) { PS_IN output = (PS_IN)0; output.pos = mul(input.pos, WorldViewProj); output.col = input.col; output.tex = input.tex; return output; } float4 PS(PS_IN input) : SV_Target { float4 textureColor = tex.Sample(samp, input.tex); // Debugging: Check the sampled color // Uncomment the line below to see the texture color being sampled //return textureColor; // Fallback to vertex color if texture alpha is zero return (textureColor.a > 0.0f) ? textureColor : input.col; } </code>
// Shader.fx

cbuffer MatrixBuffer : register(b0)
{
    matrix WorldViewProj;
};

Texture2D tex : register(t0);  // Add texture sampler
SamplerState samp : register(s0); 

struct VS_IN
{
    float4 pos : POSITION;
    float4 col : COLOR;
    float2 tex : TEXCOORD;  // Add texture coordinates
};

struct PS_IN
{
    float4 pos : SV_POSITION;
    float4 col : COLOR;
    float2 tex : TEXCOORD;
};

float4x4 worldViewProj;

PS_IN VS(VS_IN input)
{
    PS_IN output = (PS_IN)0;
    
    output.pos = mul(input.pos, WorldViewProj);
    output.col = input.col;
    output.tex = input.tex;
    
    return output;
}

float4 PS(PS_IN input) : SV_Target
{
    float4 textureColor = tex.Sample(samp, input.tex);

    // Debugging: Check the sampled color
    // Uncomment the line below to see the texture color being sampled
    //return textureColor;

    // Fallback to vertex color if texture alpha is zero
    return (textureColor.a > 0.0f) ? textureColor : input.col;
}

I hope someone will try to figure this out!

I expected that the textures will be kind of fitting all of the sides on object and not be messy, I Used brick texture for example but i dont get bricks i get brick strips, here is the texture look

Texture:

How the texture looks in my engine

Trang chủ Giới thiệu Sinh nhật bé trai Sinh nhật bé gái Tổ chức sự kiện Biểu diễn giải trí Dịch vụ khác Trang trí tiệc cưới Tổ chức khai trương Tư vấn dịch vụ Thư viện ảnh Tin tức - sự kiện Liên hệ Chú hề sinh nhật Trang trí YEAR END PARTY công ty Trang trí tất niên cuối năm Trang trí tất niên xu hướng mới nhất Trang trí sinh nhật bé trai Hải Đăng Trang trí sinh nhật bé Khánh Vân Trang trí sinh nhật Bích Ngân Trang trí sinh nhật bé Thanh Trang Thuê ông già Noel phát quà Biểu diễn xiếc khỉ Xiếc quay đĩa Dịch vụ tổ chức sự kiện 5 sao Thông tin về chúng tôi Dịch vụ sinh nhật bé trai Dịch vụ sinh nhật bé gái Sự kiện trọn gói Các tiết mục giải trí Dịch vụ bổ trợ Tiệc cưới sang trọng Dịch vụ khai trương Tư vấn tổ chức sự kiện Hình ảnh sự kiện Cập nhật tin tức Liên hệ ngay Thuê chú hề chuyên nghiệp Tiệc tất niên cho công ty Trang trí tiệc cuối năm Tiệc tất niên độc đáo Sinh nhật bé Hải Đăng Sinh nhật đáng yêu bé Khánh Vân Sinh nhật sang trọng Bích Ngân Tiệc sinh nhật bé Thanh Trang Dịch vụ ông già Noel Xiếc thú vui nhộn Biểu diễn xiếc quay đĩa Dịch vụ tổ chức tiệc uy tín Khám phá dịch vụ của chúng tôi Tiệc sinh nhật cho bé trai Trang trí tiệc cho bé gái Gói sự kiện chuyên nghiệp Chương trình giải trí hấp dẫn Dịch vụ hỗ trợ sự kiện Trang trí tiệc cưới đẹp Khởi đầu thành công với khai trương Chuyên gia tư vấn sự kiện Xem ảnh các sự kiện đẹp Tin mới về sự kiện Kết nối với đội ngũ chuyên gia Chú hề vui nhộn cho tiệc sinh nhật Ý tưởng tiệc cuối năm Tất niên độc đáo Trang trí tiệc hiện đại Tổ chức sinh nhật cho Hải Đăng Sinh nhật độc quyền Khánh Vân Phong cách tiệc Bích Ngân Trang trí tiệc bé Thanh Trang Thuê dịch vụ ông già Noel chuyên nghiệp Xem xiếc khỉ đặc sắc Xiếc quay đĩa thú vị
Trang chủ Giới thiệu Sinh nhật bé trai Sinh nhật bé gái Tổ chức sự kiện Biểu diễn giải trí Dịch vụ khác Trang trí tiệc cưới Tổ chức khai trương Tư vấn dịch vụ Thư viện ảnh Tin tức - sự kiện Liên hệ Chú hề sinh nhật Trang trí YEAR END PARTY công ty Trang trí tất niên cuối năm Trang trí tất niên xu hướng mới nhất Trang trí sinh nhật bé trai Hải Đăng Trang trí sinh nhật bé Khánh Vân Trang trí sinh nhật Bích Ngân Trang trí sinh nhật bé Thanh Trang Thuê ông già Noel phát quà Biểu diễn xiếc khỉ Xiếc quay đĩa
Thiết kế website Thiết kế website Thiết kế website Cách kháng tài khoản quảng cáo Mua bán Fanpage Facebook Dịch vụ SEO Tổ chức sinh nhật