Reputation: 11
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
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
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
// 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
How the texture looks in my engine
Upvotes: 0
Views: 56