Textures not appearing - c#

Posted this earlier and one person replied with any suggestion, so I'll post one more time I think. I realise it's old technology we're alkling about here, but still - I'm stuck. So any thoughts - anything - would be appreciated.
I'm currently working my way through "Beginning C# Programming", and have hit a problem in chapter 7 when drawing textures.
I have used the same code as on the demo CD, and although I had to change the path of the texture to be absolute, when rendered it is appearing grey.
I have debugged the program to write to file the loaded texture, and this is fine - no problems there. So something after that point is going wrong.
Here are some snippets of code:
public void InitializeGraphics()
{
// set up the parameters
Direct3D.PresentParameters p = new Direct3D.PresentParameters();
p.SwapEffect = Direct3D.SwapEffect.Discard;
...
graphics = new Direct3D.Device( 0, Direct3D.DeviceType.Hardware, this,
Direct3D.CreateFlags.SoftwareVertexProcessing, p );
...
// set up various drawing options
graphics.RenderState.CullMode = Direct3D.Cull.None;
graphics.RenderState.AlphaBlendEnable = true;
graphics.RenderState.AlphaBlendOperation = Direct3D.BlendOperation.Add;
graphics.RenderState.DestinationBlend = Direct3D.Blend.InvSourceAlpha;
graphics.RenderState.SourceBlend = Direct3D.Blend.SourceAlpha;
...
}
public void InitializeGeometry()
{
...
texture = Direct3D.TextureLoader.FromFile(
graphics, "E:\\Programming\\SharpDevelop_Projects\\AdvancedFrameworkv2\\texture.jpg", 0, 0, 0, 0, Direct3D.Format.Unknown,
Direct3D.Pool.Managed, Direct3D.Filter.Linear,
Direct3D.Filter.Linear, 0 );
...
}
protected virtual void Render()
{
graphics.Clear( Direct3D.ClearFlags.Target, Color.White , 1.0f, 0 );
graphics.BeginScene();
// set the texture
graphics.SetTexture( 0, texture );
// set the vertex format
graphics.VertexFormat = Direct3D.CustomVertex.TransformedTextured.Format;
// draw the triangles
graphics.DrawUserPrimitives( Direct3D.PrimitiveType.TriangleStrip, 2, vertexes );
graphics.EndScene();
graphics.Present();
...
}
I can't figure out what is going wrong here. Obviously if I load up the texture in windows it displays fine - so there's something not right in the code examples given in the book. It doesn't actually work, and there must be something wrong with my environment presumably.

Related

Xamarin Rotate Image Captured With Camera

I'm trying to get an image in skiasharp that's left rotated by 90 degrees to be centered and fit perfectly on the canvas. I've tried 2 ways. My own custom way, and another one that seems like a popular solution but maybe I'm not understanding how it works correctly?
My own way.
Here is the code:
SKSurface surf = e.Surface;
SKCanvas canvas = surf.Canvas;
SKSize size = canvasView.CanvasSize;
canvas.Clear();
SKRect rect = SKRect.Create(0.0f, 0.0f, size.Height, size.Width);
canvas.RotateDegrees(85);
canvas.DrawBitmap(m_bm, rect);
"m_bm" is a bitmap that was retrieved in a separate function. That function is:
// Let user take a picture.
var result = await MediaPicker.CapturePhotoAsync(new MediaPickerOptions
{
Title = "Take a picture"
});
// Save stream.
var stream = await result.OpenReadAsync();
// Create the bitmap.
m_bm = SKBitmap.Decode(stream);
// Set to true because the image will be prepared soon.
m_displayedImage = true;
I only put 85 instead of 90 because I wanted to visually see it getting closer but when I do that, it goes off screen. I'm coming from a game programming background so this is normally solved with getting the width of whatever we're working with (like the player in the game) and adding that to the x position, and boom. But with Xamarin, didn't work. That's my own attempt. Then I hit the internet of course to find help, and a different implementation was given to me.
Popular solution.
See here for this popular solution and it's the FIRST answer to this users question. The code I used is SLIGHTLY different because I didn't see the point in returning an image in that users function. Here it is:
// Save stream.
var stream = await result.OpenReadAsync();
using (var bitmap = SKBitmap.Decode(stream))
{
var rotated = new SKBitmap(bitmap.Height, bitmap.Width);
using (var surface = new SKCanvas(rotated))
{
surface.Clear();
surface.Translate(rotated.Height, rotated.Width);
surface.RotateDegrees(90);
surface.DrawBitmap(bitmap, 0, 0);
}
}
I'm drawing the bitmap with the canvas and I thought that would work because testing it in other code samples it did exactly that, so I definitely am not rotating properly or something?
The link that #Cheesebaron gave me in the reply to the original post ended up working out. But a new issue arises but I'll google that myself. Here's my own code:
namespace BugApp
{
public partial class MainPage : ContentPage
{
// Save bitmaps for later use.
static SKBitmap m_bm;
static SKBitmap m_editedBm;
// Boolean for displaying the image captured with the camera.
bool m_displayedImage;
public MainPage()
{
// Set to explicit default values to always be in control of the assignments.
m_bm = null;
m_editedBm = null;
// No picture has been taken yet.
m_displayedImage = false;
InitializeComponent();
}
// Assigned to the button in the xaml page.
private async void SnapPicture(Object sender, System.EventArgs e)
{
// Let user take a picture.
var result = await MediaPicker.CapturePhotoAsync(new MediaPickerOptions
{
Title = "Take a picture"
});
// Save stream.
var stream = await result.OpenReadAsync();
// Create the bitmap.
m_bm = SKBitmap.Decode(stream);
// Get the rotated image.
m_editedBm = Rotate();
// Set to true because the image will be prepared soon.
m_displayedImage = true;
}
public static SKBitmap Rotate()
{
using (var bitmap = m_bm)
{
var rotated = new SKBitmap(bitmap.Height, bitmap.Width);
using (var surface = new SKCanvas(rotated))
{
surface.Translate(bitmap.Width, 0);
surface.RotateDegrees(90);
surface.DrawBitmap(bitmap, 0, 0);
}
return rotated;
}
}
private void OnCanvasViewPaintSurface(object sender, SKPaintSurfaceEventArgs e)
{
if(m_bm != null && m_displayedImage == true)
{
e.Surface.Canvas.Clear();
// Draw in a new rect space.
e.Surface.Canvas.DrawBitmap(m_editedBm, new SKRect(0.0f, 0.0f, 300.0f, 300.0f));
// ---Testing.
// e.Surface.Canvas.DrawBitmap(m_editedBm, new SKRect(112, 238, 184, 310), new SKRect(0, 0, 9, 9));
// Avoid having this function launch again for now.
m_displayedImage = false;
}
}
}
}
The main portion of code that matters is the rotate function which was this one here: Link.
Thanks to everyone that replied.

C#: SharpDX - Draw Basic Stars

The Issue
I've been searching for an answer to this issue for a few days now. I need help finding a way to generate a basic star. I have the code to randomly generate the locations done; however, I am new to DirectX and came from the world of XNA and Unity. DirectX development seems overly-complicated at the best of times. I have found a few tutorials, but, I am finding them difficult to follow. I have been unable to render anything to the screen once I've cleared it. I'm using the basic setup as far as rendering goes, I haven't created any special classes or structs. I have been trying to follow the Richard's Software tutorials that were converted to C# from C++ in the book 3D Game Programming With DirectX 11 by Frank D. Luna. The farthest I have been able to successfully complete was clearing to Color.CornflowerBlue.
Question(s)
Are there any simplistic methods to draw/render objects to the screen, I'm able to render text just fine, but images (sprites) and 3D meshes seem to be giving me issues. Is there a simplistic method to draw basic geometric shapes? For example: Primitives.DrawSphere(float radius, Vector3 location, Color c);
If there aren't any simplistic methods available to draw primitives, what is going to be the simplest approach to rendering stars? I can do spheres, sprites with alpha blending to simulate distance, billboards, etc. What will be the simplest method to implement?
How do I implement the simplest method revealed by question 2 above? Code samples, tutorials (no videos), articles, etc. are greatly appreciated as I am having a hard time tracking down good C# references, it would appear that most are utilizing Unity and Unreal these days, but I don't have those options.
Notes
I work in a government environment and am unable to utilize third party tools that haven't been approved. The approval process is a nightmare so third party tools are typically a no go. All supplied answers, documentation, samples, etc. should be strictly utilizing SharpDX.
My Code
My project is a WindowsFormsApplicaiton where the primary form has been derived from RenderForm. I have created a single class called Engine that handles the DirectX code.
Engine.cs:
internal class Engine : IDisposable {
#region Fields
private Device device;
private SwapChain swapChain;
private DeviceContext context;
private Texture2D backBuffer;
private RenderTargetView renderView;
private SynchronizationContext syncContext;
#endregion
#region Events
public event EventHandler Draw;
public event EventHandler Update;
private void SendDraw(object data) { Draw(this, new EventArgs()); }
private void SendUpdate(object data) { Update(this, new EventArgs()); }
#endregion
#region Constructor(s)
public Engine(RenderForm form) {
SwapChainDescription description = new SwapChainDescription() {
ModeDescription = new ModeDescription(form.Width, form.Height, new Rational(60, 1), Format.R8G8B8A8_UNorm),
SampleDescription = new SampleDescription(1, 0),
Usage = Usage.RenderTargetOutput,
BufferCount = 1,
OutputHandle = form.Handle,
IsWindowed = !form.IsFullscreen
};
Device.CreateWithSwapChain(DriverType.Hardware, DeviceCreationFlags.Debug, description, out device, out swapChain);
backBuffer = Resource.FromSwapChain<Texture2D>(swapChain, 0);
renderView = new RenderTargetView(device, backBuffer);
context = device.ImmediateContext;
context.OutputMerger.SetRenderTargets(renderView);
context.Rasterizer.SetViewport(new Viewport(0, 0, form.Width, form.Height));
renderForm = form;
}
#endregion
#region Public Methods
public void Initialize() {
if (SynchronizationContext.Current != null)
syncContext = SynchronizationContext.Current;
else
syncContext = new SynchronizationContext();
RenderLoop.Run(renderForm, delegate() {
context.ClearRenderTargetView(renderView, Color.CornflowerBlue);
syncContext.Send(SendUpdate, null);
syncContext.Send(SendDraw, null);
swapChain.Present(0, 0);
});
}
public void Dispose() { }
#endregion
}
Form1.cs:
public partial class Form1: RenderForm {
private Engine gameEngine;
int count = 0;
public Form1() {
InitializeComponent();
gameEngine = new Engine(this);
gameEngine.Update += GameEngine_Update;
gameEngine.Draw += GameEngine_Draw;
gameEgnine.Initialize();
}
private void GameEngine_Update(object sender, EventArgs e) => Debug.WriteLine("Updated.");
private void GameEngine_Draw(object sender, EventArgs e) => Debug.WriteLine($"I've drawn {++count} times.");
}
Final Remarks
Any help is appreciated at this point because its going on day 4 and I am still struggling to understand most of the DirectX 11 code. I am by no means new to C# or development; I am just used to Windows Forms, ASP.NET, Unity, XNA, WPF, etc. This is my first experience with DirectX and its definitely over the top. Even worse than when I tried OpenGL ten years ago with hardly any development experience at all.
Few things to start with.
First, DirectX is a very low level API. The only way to get a lower level API on Windows is to go talk to the graphics driver directly, which would be even more of a nightmare. As a result, things tend to be extremely generic, which allows for high flexibility at the cost of being fairly complicated. If you ever wondered what Unity or Unreal were doing under the hood, this is it.
Second, DirectX, and Direct3D in particular, is written in and for C++. C# resources are hard to come by because the API wasn't really intended for use from C# (not that that's a good thing). As a result, discarding the documentation and answers written for C++ is a really bad idea. All the caveats and restrictions on the C++ API also apply to you in the C# world, and you will need to know them.
Third, I will not be able to provide you an entirely C#/SharpDX answer, since I don't use DirectX from C#, but from C++. I'll do what I can to provide accurate mappings, but be aware you are using an API wrapper, which can and will hide some of the details from you. Best option to discover those details would be to have the source code of SharpDX up as you go through the C++ documentation.
Now on to the questions you have. Strap in, this will be long.
First up: there's no simple way to render a primitive object in Direct3D 11. Rendering a six faced cube has the same steps as rendering a 200 million vertex mesh of New York City.
In the rendering loop, we need to do several actions to render anything. In this list, you've already done step 1 and 7, and partially done step 2:
Clear the back buffer and depth/stencil buffers.
Set the input layout, shaders, pipeline state objects, render targets, and viewports used in the current rendering pass.
Set the vertex buffer, index buffer, constant buffers, shader resources and samplers used by the current mesh being drawn.
Issue the draw call for the given mesh.
Repeat steps 3 and 4 for all meshes that must be drawn in the current rendering pass.
Repeat steps 2 through 5 for all passes defined by the application.
Present the swap chain.
Fairly complex, just to render something as simple as a cube. This process needs several objects, of which we already have a few:
A Device object instance, for creating new D3D objects
A DeviceContext object instance, for issuing drawing operations and setting pipeline state
A DXGI.SwapChain object instance, to manage the back buffer(s) and present the next buffer in the chain to the desktop
A Texture2D object instance, to represent the back buffer owned by the swap chain
A RenderTargetView object instance, to allow the graphics card to use a texture as the destination for a rendering operation
A DepthStencilView object instance, if we're are using the depth buffer
VertexShader and PixelShader object instances, representing the shaders used by the GPU during the vertex and pixel shader stages of the graphics pipeline
An InputLayout object instance, representing the exact layout of one vertex in our vertex buffer
A set of Buffer object instances, representing the vertex buffers and index buffers containing our geometry and the constant buffers containing parameters for our shaders
A set of Texture2D object instances with associated ShaderResourceView object instances, representing any textures or surface maps to be applied to our geometry
A set of SamplerState object instances, for sampling the above textures from our shaders
A RasterizerState object instance, to describe the culling, depth biasing, multisampling, and antialiasing parameters the rasterizer should use
A DepthStencilState object instance, to describe how the GPU should conduct the depth test, what causes a depth test fail, and what a fail should do
A BlendState object instance, to describe how the GPU should blend multiple render targets together
Now, what does this look like as actual C# code?
Probably something like this (for rendering):
//Step 1 - Clear the targets
// Clear the back buffer to blue
context.ClearRenderTargetView(BackBufferView, Color.CornflowerBlue);
// Clear the depth buffer to the maximum value.
context.ClearDepthStencilView(DepthStencilBuffer, DepthStencilClearFlags.Depth, 1.0f, 0);
//Step 2 - Set up the pipeline.
// Input Assembler (IA) stage
context.InputAssembler.InputLayout = VertexBufferLayout;
// Vertex Shader (VS) stage
context.VertexShader.Set(SimpleVertexShader);
// Rasterizer (RS) stage
context.Rasterizer.State = SimpleRasterState;
context.Rasterizer.SetViewport(new Viewport(0, 0, form.Width, form.Height));
// Pixel Shader (PS) stage
context.PixelShader.Set(SimplePixelShader);
// Output Merger (OM) stage
context.OutputMerger.SetRenderTargets(DepthStencilBuffer, BackBufferView);
context.OutputMerger.SetDepthStencilState(SimpleDepthStencilState);
context.OutputMerger.SetBlendState(SimpleBlendState);
//Step 3 - Set up the geometry
// Vertex buffers
context.InputAssembler.PrimitiveTopology = PrimitiveTopology.TriangleList;
context.InputAssembler.SetVertexBuffers(0, new VertexBufferBinding(VertexBuffer, sizeof(Vertex), 0));
// Index buffer
context.InputAssembler.SetIndexBuffer(IndexBuffer, Format.R16_UInt, 0);
// Constant buffers
context.VertexShader.SetConstantBuffer(0, TransformationMatrixBuffer);
context.PixelShader.SetConstantBuffer(0, AmbientLightBuffer);
// Shader resources
context.PixelShader.SetShaderResource(0, MeshTexture);
// Samplers
context.PixelShader.SetSampler(0, MeshTextureSampler);
//Step 4 - Draw the object
context.DrawIndexed(IndexBuffer.Count, 0, 0);
//Step 5 - Advance to the next object and repeat.
// No next object currently.
//Step 6 - Advance to the next pipeline configuration
// No next pipeline configuration currently.
//Step 7 - Present to the screen.
swapChain.Present(0, 0);
The vertex and pixel shaders in this example code expect:
A model with position, normal, and texture coordinates per vertex
The position of the camera in world space, the world-view-projection matrix, world inverse transpose matrix, and world matrix as a vertex shader constant buffer
The ambient, diffuse, and specular colors of the light, as well as its position in the world, as a pixel shader constant buffer
The 2D texture to apply to the surface of the model in the pixel shader, and
The sampler to use when accessing the pixels of the above texture.
Now the rendering code itself is fairly simple - the setup is the harder part of it:
//Create the vertex buffer
VertexBuffer = new Buffer(device, RawVertexInfo, new BufferDescription {
SizeInBytes = RawVertexInfo.Length * sizeof(Vertex),
Usage = ResourceUsage.Default,
BindFlags = BindFlags.VertexBuffer,
CpuAccessFlags = CpuAccessFlags.None,
OptionFlags = ResourceOptionFlags.None,
StructureByteStride = sizeof(Vertex)
});
//Create the index buffer
IndexCount = (int)RawIndexInfo.Length;
IndexBuffer = new Buffer(device, RawIndexInfo, new BufferDescription {
SizeInBytes = IndexCount * sizeof(ushort),
Usage = ResourceUsage.Default,
BindFlags = BindFlags.IndexBuffer,
CpuAccessFlags = CpuAccessFlags.None,
OptionFlags = ResourceOptionFlags.None,
StructureByteStride = sizeof(ushort)
});
//Create the Depth/Stencil view.
Texture2D DepthStencilTexture = new Texture2D(device, new Texture2DDescription {
Format = Format.D32_Float,
BindFlags = BindFlags.DepthStencil,
Usage = ResourceUsage.Default,
Height = renderForm.Height,
Width = renderForm.Width,
ArraySize = 1,
MipLevels = 1,
SampleDescription = new SampleDescription {
Count = 1,
Quality = 0,
},
CpuAccessFlags = 0,
OptionFlags = 0
});
DepthStencilBuffer = new DepthStencilView(device, DepthStencilTexture);
SimpleDepthStencilState = new DepthStencilState(device, new DepthStencilStateDescription {
IsDepthEnabled = true,
DepthComparison = Comparison.Less,
});
//default blend state - can be omitted from the application if defaulted.
SimpleBlendState = new BlendState(device, new BlendStateDescription {
});
//Default rasterizer state - can be omitted from the application if defaulted.
SimpleRasterState = new RasterizerState(device, new RasterizerStateDescription {
CullMode = CullMode.Back,
IsFrontCounterClockwise = false,
});
// Input layout.
VertexBufferLayout = new InputLayout(device, VertexShaderByteCode, new InputElement[] {
new InputElement {
SemanticName = "POSITION",
Slot = 0,
SemanticIndex = 0,
Format = Format.R32G32B32_Float,
Classification = InputClassification.PerVertexData,
AlignedByteOffset = 0,
InstanceDataStepRate = 0,
},
new InputElement {
SemanticName = "NORMAL",
Slot = 0,
SemanticIndex = 0,
Format = Format.R32G32B32_Float,
Classification = InputClassification.PerVertexData,
AlignedByteOffset = InputElement.AppendAligned,
InstanceDataStepRate = 0,
},
new InputElement {
SemanticName = "TEXCOORD0",
Slot = 0,
SemanticIndex = 0,
Format = Format.R32G32_Float,
Classification = InputClassification.PerVertexData,
AlignedByteOffset = InputElement.AppendAligned,
InstanceDataStepRate = 0,
},
});
//Vertex/Pixel shaders
SimpleVertexShader = new VertexShader(device, VertexShaderByteCode);
SimplePixelShader = new PixelShader(device, PixelShaderByteCode);
//Constant buffers
TransformationMatrixBuffer = new Buffer(device, new BufferDescription {
SizeInBytes = sizeof(TransformationMatrixParameters),
BindFlags = BindFlags.ConstantBuffer,
Usage = ResourceUsage.Default,
CpuAccessFlags = CpuAccessFlags.None,
});
AmbientLightBuffer = new Buffer(device, new BufferDescription {
SizeInBytes = sizeof(AmbientLightParameters),
BindFlags = BindFlags.ConstantBuffer,
Usage = ResourceUsage.Default,
CpuAccessFlags = CpuAccessFlags.None,
});
// Mesh texture
MeshTexture = new Texture2D(device, new Texture2DDescription {
Format = Format.B8G8R8A8_UNorm,
BindFlags = BindFlags.ShaderResource,
Usage = ResourceUsage.Default,
Height = MeshImage.Height,
Width = MeshImage.Width,
ArraySize = 1,
MipLevels = 0,
CpuAccessFlags = CpuAccessFlags.None,
OptionFlags = ResourceOptionFlags.None,
SampleDescription = new SampleDescription {
Count = 1,
Quality = 0,
}
});
//Shader view for the texture
MeshTextureView = new ShaderResourceView(device, MeshTexture);
//Sampler for the texture
MeshTextureSampler = new SamplerState(device, new SamplerStateDescription {
AddressU = TextureAddressMode.Clamp,
AddressV = TextureAddressMode.Clamp,
AddressW = TextureAddressMode.Border,
BorderColor = new SharpDX.Mathematics.Interop.RawColor4(255, 0, 255, 255),
Filter = Filter.MaximumMinMagMipLinear,
ComparisonFunction = Comparison.Never,
MaximumLod = float.MaxValue,
MinimumLod = float.MinValue,
MaximumAnisotropy = 1,
MipLodBias = 0,
});
As you can see, there's a lot of stuff to get through.
As this has already gotten a lot longer than most people have the patience for, I'd recommend getting and reading the book by Frank D. Luna, as he does a much better job of explaining the pipeline stages and the expectations Direct3D has of your application.
I'd also recommend reading through the C++ documentation for the Direct3D API, as, again, everything there will apply to SharpDX.
In addition, you'll want to look into HLSL, as you'll need to define and compile a shader to make any of the above code even work, and if you want any texturing, you'll need to figure out how to get the image data into Direct3D.
On the bright side, if you manage to implement all of this in a clean, extensible manner, you'll be able to render practically anything with little additional effort.

How to apply barrel distortion (lens correction) with SharpDX?

i've made a small application to grap screenshots from any windowed game and send it to the iPhone to creat an virtual reality app, like oculus rift (see https://github.com/gagagu/VR-Streamer-Windows-Server for more info).
The images will be captured with SharpDX and everything is working fine.
Now i want to implement such like lens correction (barrel distortion) and i'm looking for the fastest way to realize it. I'm looking many internet sites with informations about barrel distortion and i think the fastest way is to use a shader for it, but i'm very new to sharpdx (and no knowledge about shaders) and i don't know how to implement a shader to my code. The most tutorials applys a shader to an object (like a cube) but not to a captured image and so i don't know how to do it.
[STAThread]
public System.Drawing.Bitmap Capture()
{
isInCapture = true;
try
{
// init
bool captureDone = false;
bitmap = new System.Drawing.Bitmap(captureRect.Width, captureRect.Height, PixelFormat.Format32bppArgb);
// the capture needs some time
for (int i = 0; !captureDone; i++)
{
try
{
//capture
duplicatedOutput.AcquireNextFrame(-1, out duplicateFrameInformation, out screenResource);
// only for wait
if (i > 0)
{
using (var screenTexture2D = screenResource.QueryInterface<Texture2D>())
device.ImmediateContext.CopyResource(screenTexture2D, screenTexture);
mapSource = device.ImmediateContext.MapSubresource(screenTexture, 0, MapMode.Read, MapFlags.None);
mapDest = bitmap.LockBits(new System.Drawing.Rectangle(0, 0, captureRect.Width, captureRect.Height),
ImageLockMode.WriteOnly, bitmap.PixelFormat);
sourcePtr = mapSource.DataPointer;
destPtr = mapDest.Scan0;
// set x position offset to rect.x
int rowPitch = mapSource.RowPitch - offsetX;
// set pointer to y position
sourcePtr = IntPtr.Add(sourcePtr, mapSource.RowPitch * captureRect.Y);
for (int y = 0; y < captureRect.Height; y++) // needs to speed up!!
{
// set pointer to x position
sourcePtr = IntPtr.Add(sourcePtr, offsetX);
// copy pixel to bmp
Utilities.CopyMemory(destPtr, sourcePtr, pWidth);
// incement pointert to next line
sourcePtr = IntPtr.Add(sourcePtr, rowPitch);
destPtr = IntPtr.Add(destPtr, mapDest.Stride);
}
bitmap.UnlockBits(mapDest);
device.ImmediateContext.UnmapSubresource(screenTexture, 0);
captureDone = true;
}
screenResource.Dispose();
duplicatedOutput.ReleaseFrame();
}
catch//(Exception ex) // catch (SharpDXException e)
{
//if (e.ResultCode.Code != SharpDX.DXGI.ResultCode.WaitTimeout.Result.Code)
//{
// // throw e;
//}
return new Bitmap(captureRect.Width, captureRect.Height, PixelFormat.Format32bppArgb);
}
}
}
catch
{
return new Bitmap(captureRect.Width, captureRect.Height, PixelFormat.Format32bppArgb);
}
isInCapture = false;
return bitmap;
}
It would be really great to get a little start assist from someone who willing to help.
I've found some shaders on inet but it is written for opengl (https://github.com/dghost/glslRiftDistort/tree/master/libovr-0.4.x/glsl110). Can i use the also for directx (sharpdx)?
Thanks forward for any help!
Now I've never used DirectX myself, but I suppose you'll need to use HLSL instead of GLSL (which should be fairly similar though). The idea is that you'll have to load your "screenshot" into a texture buffer, as an input to your fragment shader (pixel shader). Fragment shaders are deceptively easy to understand, it's just a piece of code (written in GLSL or HLSL) looking very much like a subset of C to which a few math functions has been added (vector and matrices manipulation mostly) executed for every single pixel to be rendered.
The code should be fairly simple, you'll take the current pixel position, apply the barrel distortion transformation to it's coordinates, then look up that coordinate in your screenshot texture. The transformation should look something like that :
vec2 uv;
/// Barrel Distortion ///
float d=length(uv);
float z = sqrt(1.0 - d * d);
float r = atan(d, z) / 3.14159;
float phi = atan(uv.y, uv.x);
uv = vec2(r*cos(phi)+.5,r*sin(phi)+.5);
Here's a shadertoy link if you wanna play with it and figure out how it works
I have no idea how HLSL handles texture filtering (which pixel you'll get when using floating point values for coordinates), but I'd put my money on bilinear filtering, which may very well give an unpleasant pixelyness to your output. You'll have to look at better filtering methods once you get the distortion working. Shouldn't be anything too complicated, familiarize yourself with HLSL syntax, find how to load your screenshot into a texture in DirectX and get rolling.
Edit : I said barrel distortion but the code is actually for the fisheye effect. Of course both are pretty much identical, the barrel distortion being only on one axis. I believe what you need is the fisheye effect though, it's what is commonly used for HMDs if I'm not mistaken.

SharpDX/DX11 Alpha Blend

I am attempting to use alpha blending with SharpDX. If I set my blend state on my output merger, nothing renders at all, and I have absolutely no idea why. When never setting the blend state, everything works fine. Even if I set a blend state with the default blend description, nothing renders. I figure there's some step I'm missing or I am doing something in the wrong order, so I'll just paste what I've got and hope somebody can point something out...
I have a BlendState set up using the following code:
bs = new BlendState(Devices.Device11, new BlendStateDescription());
var blendDesc = new RenderTargetBlendDescription(
true,
BlendOption.SourceAlpha,
BlendOption.InverseSourceAlpha,
BlendOperation.Add,
BlendOption.One,
BlendOption.Zero,
BlendOperation.Add,
ColorWriteMaskFlags.All);
bs.Description.RenderTarget[0] = blendDesc;
...and here are the contents of my render loop. If all I do is comment out context.OutputMerger.SetBlendState(bs), my meshes render fine (without any blending, that is):
var context = Devices.Device11.ImmediateContext;
context.ClearDepthStencilView(DepthStencilView, DepthStencilClearFlags.Depth, 1.0f, 0);
context.ClearRenderTargetView(RenderTargetView, new Color4());
context.OutputMerger.SetTargets(DepthStencilView, RenderTargetView);
context.OutputMerger.SetBlendState(bs);
context.Rasterizer.State = rs;
context.Rasterizer.SetViewport(Viewport);
context.VertexShader.SetConstantBuffer(0, viewProjBuffer);
context.UpdateSubresource(Camera.ViewProjection.ToFloatArray(), viewProjBuffer);
Dictionary<Mesh, Buffer> vBuffers = VertexBuffers.ToDictionary(k => k.Key, v => v.Value);
Dictionary<Mesh, Buffer> iBuffers = IndexBuffers.ToDictionary(k => k.Key, v => v.Value);
foreach (var mesh in vBuffers.Keys)
{
if (mesh.MeshType == MeshType.LineStrip)
{
context.InputAssembler.PrimitiveTopology = PrimitiveTopology.LineStrip;
context.InputAssembler.InputLayout = Effects.LineEffect.InputLayout;
context.VertexShader.Set(Effects.LineEffect.VertexShader);
context.PixelShader.Set(Effects.LineEffect.PixelShader);
}
else
{
context.InputAssembler.PrimitiveTopology = PrimitiveTopology.TriangleList;
context.InputAssembler.InputLayout = Effects.FaceEffect.InputLayout;
context.VertexShader.Set(Effects.FaceEffect.VertexShader);
context.PixelShader.Set(Effects.FaceEffect.PixelShader);
}
context.InputAssembler.SetVertexBuffers(0, new VertexBufferBinding(vBuffers[mesh], GetMeshStride(mesh) * 4, 0));
context.InputAssembler.SetIndexBuffer(iBuffers[mesh], Format.R32_UInt, 0);
context.DrawIndexed(mesh.IndexUsage, 0, 0);
}
context.ResolveSubresource(RenderTarget, 0, SharedTexture, 0, Format.B8G8R8A8_UNorm);
context.Flush();
I am rendering to a texture, which is initialized using the following texture description:
Texture2DDescription colorDesc = new Texture2DDescription
{
BindFlags = BindFlags.RenderTarget | BindFlags.ShaderResource,
Format = Format.B8G8R8A8_UNorm,
Width = width,
Height = height,
MipLevels = 1,
SampleDescription = new SampleDescription(8, 32),
Usage = ResourceUsage.Default,
OptionFlags = ResourceOptionFlags.Shared,
CpuAccessFlags = CpuAccessFlags.None,
ArraySize = 1
};
It is important for me to render to a texture and for me to use that format. I thought that maybe blending worked with particular formats, but I could not find any info suggesting anything of that sort.
I am also multisampling, which is why I call ResolveSubresource(...) at the end of my render method. The texture I am copying to has an identical description to RenderTarget, except with a different SampleDescription.
Speaking of multisampling, here's the RasterizerState I am using:
rs = new RasterizerState(Devices.Device11, new RasterizerStateDescription()
{
FillMode = FillMode.Solid,
CullMode = CullMode.Back,
IsFrontCounterClockwise = true,
DepthBias = 0,
DepthBiasClamp = 0,
SlopeScaledDepthBias = 0,
IsDepthClipEnabled = true,
IsScissorEnabled = false,
IsMultisampleEnabled = true,
IsAntialiasedLineEnabled = true
});
I am rendering with a shader, which is basically a "Hello World" shader plus a camera matrix and basic normal direction lighting. I've verified that my vertex alpha values are what they're supposed to be just as they're being populated into their vertex buffers... and even if I hardcode their alpha to 1 at the end of the pixel shader, I still get nothing, so long as I use that BlendState. Without using BlendState, everything renders opaque as expected, regardless of alpha values. I've even tried implementing the blend state in the shader itself, but that seems to have no effect whatsoever. Everything appears to render as if no blending was defined at all.
If it matters, I'm using FeatureLevel.Level.Level_11_0 with my Device.
Unfortunately this is about as much as I have to go on. Like I said this problem is a total mystery to me at this point.
Just wanted to update this for anyone who comes here in the future. Something that worked for me was quite simply:
BlendStateDescription blendStateDescription = new BlendStateDescription
{
AlphaToCoverageEnable = false,
};
blendStateDescription.RenderTarget[0].IsBlendEnabled = true;
blendStateDescription.RenderTarget[0].SourceBlend = BlendOption.SourceAlpha;
blendStateDescription.RenderTarget[0].DestinationBlend = BlendOption.InverseSourceAlpha;
blendStateDescription.RenderTarget[0].BlendOperation = BlendOperation.Add;
blendStateDescription.RenderTarget[0].SourceAlphaBlend = BlendOption.Zero;
blendStateDescription.RenderTarget[0].DestinationAlphaBlend = BlendOption.Zero;
blendStateDescription.RenderTarget[0].AlphaBlendOperation = BlendOperation.Add;
blendStateDescription.RenderTarget[0].RenderTargetWriteMask = ColorWriteMaskFlags.All;
this._context.OutputMerger.BlendState = new BlendState(_device,blendStateDescription);
I also handled the alpha component in my shader, as well, in case you want to manually add transparency to a model, pseudo code:
float4 PixelShaderMain( PixelShaderArgs pixelShaderArgs )
: SV_Target
{
float u = pixelShaderArgs.col.x;
float v = pixelShaderArgs.col.y;
float4 color = ShaderTexture.Load(int3(convertUVToPixel(u,v),0));
return float4(color.r,color.g,color.b,0.5); // 50% transparency
}
Hope this helps someone instead of getting a dead page that basically points nowhere. Happy coding everyone!

XNA weird terrain tearing

Let me post the images first...
Solid shot where tearing occurs
And wireframe shot of that place
I am mostly using mostly using Riemers tutorial while the render code is..
Main render
public void Render()
{
device.Clear(Color.CornflowerBlue);
RasterizerState rs = new RasterizerState();
rs.CullMode = cullmode;
rs.FillMode = fillmode;
device.RasterizerState = rs;
effect.Parameters["xView"].SetValue(camera.ViewMatrix);
effect.Parameters["xProjection"].SetValue(camera.ProjectionMatrix);
effect.Parameters["xWorld"].SetValue(Matrix.Identity);
effect.Parameters["xEnableLighting"].SetValue(true);
effect.Parameters["xLightDirection"].SetValue(lightDirection);
effect.Parameters["xAmbient"].SetValue(0.5f);
globals.game.terrain.Render();
globals.game.spriteBatch.Begin();
globals.console.Render();
globals.game.spriteBatch.End();
}
Terrain.Render()
public void Render()
{
globals.game.graphics.effect.CurrentTechnique = globals.game.graphics.effect.Techniques["Colored"];
globals.game.graphics.effect.Parameters["xWorld"].SetValue(worldMatrix);
foreach (EffectPass pass in globals.game.graphics.effect.CurrentTechnique.Passes)
{
pass.Apply();
globals.game.graphics.device.Indices = indexBuffer;
globals.game.graphics.device.SetVertexBuffer(vertexBuffer);
globals.game.graphics.device.DrawIndexedPrimitives(PrimitiveType.TriangleList, 0, 0, vertices.Length, 0, indices.Length / 3);
}
}
I was stuck with this problem for pretty long now (not knowing if it is caused by my coding skills, xna or some g-card configuration...) so i wonder if someone have some ideas what might cause it?
Temporarily comment out the spritebatch begin, draw, & end code and see if that makes a difference. It may or may not depending on the vertex order in the buffer.
If it does help, your solution can be found here: http://blogs.msdn.com/b/shawnhar/archive/2010/06/18/spritebatch-and-renderstates-in-xna-game-studio-4-0.aspx

Categories