I'am starting to learn SharpDX and Holographic template for C#.
While compiling project I have error at compilation of shader file.
var vertexShaderByteCode = ShaderBytecode.CompileFromFile("Content/Shaders/VertexSharderShared.hlsl", "VS", "vs_5_0", ShaderFlags.Debug);
fxc.exe exited with code 1.
In the sample they use some .cso file while loading shader into byte code:
code img
As I don't really understand where that .cso comes from and what Vprt is, I prefer loading hlsl file directly. I'm using SharpDX 3.0.2, SharpDX.Direct3D11 3.0.2 and SharpDX.D3DCompiler 3.0.2.
Thanks!
The CSO files need to be loaded then the relevant shader created. Below is an example of a function I use to load the shader. Please note, that you should hold onto the byte code as well as the vertex shader in this example.
The Helper function is my cross uwp/mfc wrapper, but it basically returns the file in a datastream in memory.
The CSO file is byte code, you need to attach it to the correct Sharpdx.Direct3D11 shader class.
The bytecode is also used to reference the semantic interface (for Vertex buffers only). once you have created that, your draw call can match the data against the GPU register that it is associated to. But the code below at least will load your CSO file in and create the vertexshader.
goodluck.
using (Stream fileStream = Helper.GetFileStream(a_fileName, a_filePath))
{
a_byteCode = new D3DCompiler.ShaderBytecode(fileStream);
if (a_byteCode != null)
{
a_child = new D3D11.VertexShader(a_device, a_byteCode)
{
DebugName = "a_fileName"
};
}
else
{
throw new Exception("Unable to load file: " + a_fileName);
}
}
Related
I am currently maintaining an old project which I would very much like to keep the old code and avoid refactoring of the old code if it's possible. To upload it to google play store, I have used play asset delivery PAD system which is requiring asset bundle system.
I am able to successfully loading asset bundles in an asynchronous way with coroutines following the tutorials.
My question is that; is it possible to access bundled assets without changing original way of accessing such as
UnityEditor.AssetDatabase.LoadAssetAtPath("Assets/Prefabs/Game/Tiles/Tile.prefab", typeof(Tile)) as Tile;
instead of implementing the following code?
var assets = AssetDatabase.FindAssets("t:Sprite",
new[] {"Assets/Images"});
foreach (var guid in assets)
{
string assetPath = AssetDatabase.GUIDToAssetPath(guid);
Sprite loadedSprite = null;
if (imageDictionary.TryGetValue(assetPath, out loadedSprite)
== false)
{
loadedSprite = AssetDatabase.LoadAssetAtPath<Sprite>(
assetPath);
if (loadedSprite != null)
{
imageDictionary.Add(assetPath, loadedSprite);
AddImageToList(assetPath, loadedSprite);
}
}
}
I am currently using 2 asset bundles consists of texture and spine animation folders.I have created 2 asset bundles which are texture folder (110 MB) and spine animation bundle (23 MB) and base asset. When I created the aab file, file size increased to 370 MB.
(I know that I need to split my bundles to match play store requirement of 150 MB for base assets but this is a different issue.)
And also, my educated guess is that, unity is not only adding asset bundles but also adding assets in old fashioned way which is an issue might relate to this question.
I was also facing the same problem.
The initially built AAB file exceeded 150MB and could not be uploaded to the store.
But I found a way to upload.
order
Put the build scene in "File - BuildSetting - Scene In Build".
Check "Build App Bundle" in "File - BuildSetting".
Close BuildSetting and click "Google - Build Android App Bundle"
Build.
(In this process, I did not create an AssetBundle. I used the original program as it was)
Ignore the large size alarm in the middle of the build.
When the build is completed, the size will be larger than 150MB.
Don't worry about the size of the build file and upload it to the Google console.
"Google - Build Android App Bundle" The file built with this goes up.
I hope the problem is resolved.
#Alp, Google's PAD tutorial is quite limited and it only guesses you're trying to access textures, which might not be always the case.
You can actually access the bundles directly, and load them into memory, and if you've packed your prefab as an assetBundle, when you load your assetBundle this way you can just cast it to a GameObject later and then use the prefab as a GameObject to instantiate it or do whatever you need.
There is only one official way of loading asset bundles if you packed them as install-time,
public static IEnumerator LoadAssetBundleFromMemoryAsync(string packName, string assetName, Action<AssetBundle> callback)
{
var packRequest = PlayAssetDelivery.RetrieveAssetPackAsync(packName);
while (!packRequest.IsDone)
{
yield return null;
}
AssetLocation location = packRequest.GetAssetLocation(assetName);
long size = (long)location.Size;
long offset = (long)location.Offset;
using (Stream stream = File.OpenRead(location.Path))
{
byte[] bytes = new byte[size];
stream.Seek(offset, SeekOrigin.Begin);
stream.Read(bytes, 0, bytes.Length);
AssetBundleCreateRequest request = AssetBundle.LoadFromMemoryAsync(bytes);
yield return request;
callback(request.assetBundle);
}
}
And then, I also figured out an unofficial way of loading asset bundles directly from file. It turns out that the location we get for a given assetBundle is going to be inside the split apk module with the same name as the assetPack.
But if we just replace the split_pack.apk with base.apk, we can actually read it directly from the File without needing to actually pre-load the bundle into memory. Load from memory will put it into memory in advance, while using the LoadFromFile way, you can actually load the bundle to memory when it's needed.
Something like this:
public static IEnumerator LoadAssetBundleFromFileAsync (string packName, string assetName, Action<AssetBundle> callback)
{
var packRequest = PlayAssetDelivery.RetrieveAssetPackAsync(packName);
while (!packRequest.IsDone)
{
yield return null;
}
AssetLocation location = packRequest.GetAssetLocation(assetName);
string path = location.Path.Replace($"split_{packName}.apk", "base.apk");
string basePath = $"{path}!assets/assetpack/{assetName}";
AssetBundleCreateRequest request = AssetBundle.LoadFromFileAsync(basePath);
while (!request.isDone)
{
yield return null;
}
callback(request.assetBundle);
}
You could also maybe only return the 'assetPath' and load it later.
These are only for install-time asset packs.
If you're trying to load any file from a fast-follow or on-demand asset pack, then all you need is the location.Path to load it from, as a raw file.
public static IEnumerator GetAssetLocationFromAssetPack (string packName, string assetName, Action<string> callback)
{
PlayAssetPackRequest packRequest = PlayAssetDelivery.RetrieveAssetPackAsync(packName);
while (!packRequest.IsDone)
{
yield return null;
}
AssetLocation location = packRequest.GetAssetLocation(assetName);
callback(location.Path);
}
I hope it helps, and be wary that any folder or assets contained in your StreamingAssets if also set to be in an assetPack will be added in double, everything contained in StreamingAssets will be in your base.apk (within the AAB), so if you have something from StreamingAssets that will actually be loaded from a pack, delete it from Streaming to avoid an AAB bigger than expected.
I'm using SharpDX and its accompanying WIC and Direct2D wrappers to do some serverside image manipulation.
The following code works great with JPEG images and is modeled after the SharpDX docs and this Microsoft sample using D2D directly via C++.
However, I get a BadImage error when I try to load a TIFF CCITT (bitonal 1bpp) image. The BadImage error is only thrown at EndDraw, (which happens later on in the commented DrawEndorsement function), or at this line of code which I inserted to make the point at which the issue occurs more obvious:
SharpDX.Direct2D1.Bitmap bitmap = SharpDX.Direct2D1.Bitmap.FromWicBitmap(_renderTarget, _wicBitmap);
The JPEG image I pass in gets to this point and continues with no issues, but the TIFF I pass in gets to this point and causes FromWicBitmap to barf with a BadImage error.
I'm using FormatConverter to convert the TIFF/JPEG pixel formats to an appropriate and supported D2D pixel format, and the converter does change the pixel format GUID for both images, but, again, FromWicBitmap barfs only on the TIFF.
I assumed I was doing something wrong with conversion or misusing SharpDX/D2D, but when I built and ran the aforementioned Microsoft C++ D2D image viewer sample, it loaded and rendered this same TIFF file with no errors. I double checked the sample's code to verify that I was using all the same pixel formats, options, etc, and it looks like I'm doing almost exactly the same thing with SharpDX that the sample is doing with D2D directly.
Clearly Direct2D doesn't like the pixel format of the TIFF image that WIC is handing it, but why didn't the MS sample exhibit the same behavior, and why didn't FormatConverter fix it?
Am I missing something that the D2D sample code is doing?
Am I missing some trick with SharpDX?
Is this a SharpDX bug?
Thanks!
public byte[] BuildImage(byte[] image, Format saveFormat)
{
SharpDX.WIC.Bitmap _wicBitmap;
WicRenderTarget _renderTarget;
BitmapFrameDecode bSource;
FormatConverter converter = new FormatConverter(_factoryManager.WicFactory);
using (MemoryStream systemStream = new MemoryStream(image))
using (WICStream wicStream = new WICStream(_factoryManager.WicFactory, systemStream))
{
BitmapDecoder inDecoder = new BitmapDecoder(_factoryManager.WicFactory, wicStream, DecodeOptions.CacheOnLoad);
if (inDecoder.FrameCount > 0)
{
bSource = inDecoder.GetFrame(0);
converter.Initialize(bSource, SharpDX.WIC.PixelFormat.Format32bppPRGBA, BitmapDitherType.Solid, null, 0.0f, BitmapPaletteType.MedianCut);
_imageWidth = bSource.Size.Width;
_imageHeight = bSource.Size.Height;
}
else
{
throw new Exception("No frames found!");
}
}
_wicBitmap = new SharpDX.WIC.Bitmap(
_factoryManager.WicFactory,
converter,
BitmapCreateCacheOption.CacheOnDemand
);
_renderTarget = new WicRenderTarget(_factoryManager.D2DFactory, _wicBitmap, new RenderTargetProperties());
SharpDX.Direct2D1.Bitmap bitmap = SharpDX.Direct2D1.Bitmap.FromWicBitmap(_renderTarget, _wicBitmap);
//DrawEndorsement(_renderTarget);
_renderTarget.Dispose();
bSource.Dispose();
converter.Dispose();
return SaveImage(saveFormat, _wicBitmap);
}
As xoofx pointed out, turns out that this was caused by my disposing of the WIC/MemoryStreams underlying the FormatConverter while it was still in use.
This was causing JPEGs to be corrupted on write, and weirdly causing the TIFFs to fail even before that.
Extended the using scope accordingly and that fixed it.
I have imported a greyscale 16-bit image. I have it bot as a BitmapSource and an Image (of Controls namespace). How can i access the individual pixels? Is the CopyPixels i have read about the only or best way? If so, i don't get how to set the stride, and which pixel contains the pixel intensity value.
Method1:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Threading;
using System.IO;
using Nikon;
using WindowsFormsApplication1;
using System.Windows.Media.Imaging;
using System.Drawing;
using System.Drawing.Imaging;
using System.Windows.Controls;
namespace Map
{
class OpenTIFF
{
static void OpenOne()
{
// Open a Stream and decode a TIFF image
Stream imageStreamSource = new FileStream("C:\\Users\\Me\\Desktop\\"MyTif.tif", FileMode.Open, FileAccess.Read, FileShare.Read);
TiffBitmapDecoder decoder = new TiffBitmapDecoder(imageStreamSource, BitmapCreateOptions.PreservePixelFormat, BitmapCacheOption.Default);
BitmapSource bitmapSource = decoder.Frames[0];
System.Windows.Controls.Image image = new System.Windows.Controls.Image();
image.Source = bitmapSource;
}
}
}
I think this might be simpler (found here), but then i am unclear how to access individual pixels in a 1D byte array.
Method 2:
static void OpenTwo()
{
System.Drawing.Image imageToConvert = System.Drawing.Image.FromFile("aa.tif", true);
byte[] Ret = new byte[0];
using (MemoryStream ms = new MemoryStream())
{
imageToConvert.Save(ms, ImageFormat.Tiff);
Ret = ms.ToArray();
}
}
Thanks,
Dan
You might want to check out the free image library.
It has a C# wrapper.
http://freeimage.sourceforge.net/index.html
To get you started and give a quick example:
download the binary distribution
open FreeImage.NET.sln in visual studio (I used 2010)
build the Library project
if you receive errors in the XML comments do the following: go in the project properties, under build, change "treat warnings as errors" from "all" to "none"
Create new console project.
Add reference to the assembly you built in step 3.
FreeImage3154Win32\FreeImage\Wrapper\FreeImage.NET\cs\Library\bin\Debug\FreeImageNET.dll
Add the following code to Program.cs
using FreeImageAPI;
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
// load image, this can by your 16-bit tif
FIBITMAP dib = FreeImage.LoadEx("myfile.tif");
// convert to 8-bits
dib = FreeImage.ConvertToGreyscale(dib);
// rotate image by 90 degrees
dib = FreeImage.Rotate(dib, 90);
// save image
FreeImage.SaveEx(dib, "newfile.png");
// unload bitmap
FreeImage.UnloadEx(ref dib);
}
}
}
copy the FreeImage binary dll that you downloaded into the bin directory.
FreeImage3154Win32\FreeImage\Dist\FreeImage.dll
Run the application
There is a good selection of examples in the solution that contained the Library project.
Your detailed steps are very much what i needed...much thanks.
I followed directions similar to yours for installation (your steps 1-3) in a related thread. This was successful, and exactly as Romulus said.
Below are some additional details needed and errors I ran into (i hope its not too much detail...hope to help anyone else who runs into this).
I followed your directions from step 4 onwards (except i added it into my exisitng windows application). I copied the FreeImage.dll (step 8) into the bin directory of my project.
I run the code, and get this error:
An unhandled exception of type 'System.BadImageFormatException' occurred in WindowsFormsApplication1.exe
Additional information: An attempt was made to load a program with an incorrect format. (Exception from HRESULT: 0x8007000B)
I had two errors. First was that I had not copied to FreeImage binary dll (step 8 above) into the correct bin directory of the project (I had copied it to bin and not bin\Debug 8-). I copied it to:
\WindowsFormsApplication1\bin\Debug
Second, if I run it now, I get an error:
An unhandled exception of type 'System.TypeInitializationException' occurred in WindowsFormsApplication1.exe
Additional information: The type initializer for 'WindowsFormsApplication1.Form1' threw an exception.
The solution here is to change the Build platform to x86. I found either selecting x86, or Any CPU with the Prefer 32-bit box checked work. Tip for beginners like myself: The Build platform is accessed by right-clicking on the Project name (not the Solution) and selecting Properties. It can also be accessed from the DEBUG menu, where at the bottom will be "MyProject Properties".
or this also works:
So with these two fixes, the code runs fine. However, the file output is 0KB. But that's another post...
Thanks!
Dan
I'm trying to create a 2D array in XNA which I'll be using as a tile map for a game I'm working on. I've read various solutions but none of them seem to be working for me. One of the main issues I'm having is an error:
Cannot autodetect which importer to use for "map.txt". There are no importers which handle this file type. Specify the importer that handles this file type in your project.
This appears to be caused by the StreamReader class that I'm attempting to use.
I'm using XNA 4.0.
My .txt file looks like this (example):
0,0,0,0,0
0,0,0,0,0
0,0,1,0,0
0,1,1,1,0
1,1,1,1,1
My C# and XNA looks like this:
string line = string.Empty;
using (StreamReader sr = new StreamReader("5x5-map"))
{
while ((line = sr.ReadLine()) != null)
{
//reads line by line until eof
//do whatever you want with the text
}
}
If anyone could help me, or point me in the direction of a working example that would be great.
Change the build action to "None" in the properties window for that file, if you're manually reading it with StreamReader. The message comes from the content pipeline trying to import it for you.
Specify the importer that handles this file type in your project.
Find the file in your content project, open the properties menu, and select an importer.
According to MSDN: Verifying the Content Importer
A DLL file contains some images inside PNG resource type.
I can view the PNG images in softwares like Resource Hacker, Anolis Resourcer & Resource Tuner. Check this screenshot of Anolis Resourcer for more details:
Can someone tell me how do I get the PNG image no. 5220 from the DLL file and put it inside a PictureBox? I don't think APIs like LoadImage or LoadBitmap will work.
// get the assembly containing the image
var assembly = Assembly.GetExecutingAssembly();
// set the picturebox image to read the embedded resource
pictureBox1.Image = Image.FromStream(
assembly.GetManifestResourceStream("AssemblyName.test.png")
);
where AssemblyName.test.png is the fully qualified name of the embedded resource inside the assembly.
UPDATE:
It seems that you are trying to extract resources from a native assembly. You may take a look at the following article which illustrates how this could be done using P/Invoke.
The link that Darin posted (which has consequently been marked as the answer) does not contain functional code. I've evaluated the code posted there (http://khason.net/blog/how-to-load-unmanaged-native-resources-from-managed-c-code/) and found that it does not work properly for any Bitmap image embedded in any win32 dll as a bitmap resource.
Additionally, Hans Passant leaves off a myriad of steps effectively rendering his post useless.
The only somewhat close solution that I've been able to find comes from an article written in 2004 for the XP Theme dll junk. You can find the 'GetResourcePNG' method in ThemeManager.cs here http://www.codeproject.com/KB/miscctrl/XPTaskBar.aspx
However, it should be noted that I've been having a lot of difficulty with this method, as the call to bitmap.RotateFlip(RotateFlipType.Rotate180FlipX); causes memory issues when trying to access pngs within authui.dll on my system
Update:
I've found the code listed here (http://www.vbaccelerator.com/home/NET/Code/Controls/Explorer_Bar/ExplorerBar_Control_Source_Code.asp) to be by far the most functional, produce the fewest errors and produces the fastest results. The code is written in c# even though the domain name would indicate otherwise. Using the two classes; ImageUtility and ResourceLibrary, you can easily pull a PNG out of a standard, non-.net resource library/dll:
public static Bitmap GetStandardResourceBitmap(String dllName, String resourceId) {
Bitmap result = null;
using (ResourceLibrary library = new ResourceLibrary() { Filename = dllName }) {
IntPtr hDib = library.GetResource(resourceId, ResourceLibrary.ImageType.IMAGE_BITMAP, ResourceLibrary.ImageLoadOptions.LR_CREATEDIBSECTION);
if (!hDib.Equals(IntPtr.Zero)) {
result = ImageUtility.DibToBitmap(hDib);
ImageUtility.DeleteObject(hDib);
}
}
return result;
}
I chose to have resourceId in my method a String, only because it doesn't require an overload and using numbered resource Ids is as simple as prepending a '#'.
GetStandardResourceBitmap("shell32.dll", "#632");
Cheers
A PNG image is not one of the standard Win32 resource types. It is usually embedded as a binary blob with the named resource type "PNG", although that's not guaranteed. By far the easiest way to figure this out is by opening the file with Visual Studio's File + Open + File command. You'll see the embedded resources organized in a tree, hopefully with a descriptive name, right-click a candidate and select Export to save it to disk.
Doing this programmatically requires a lot of gritty pinvoke. It is tricky because both the resource type and the resource ID can be either a string or an IntPtr so you'll need 4 overloads for FindResource. In order, you'll need LoadLibraryEx() to load the file without executing any of its code. FindResource to get a handle to the resource. SizeOfResource to know how large it is. LoadResource + LockResource to get a pointer to the resource data. Marshal.Copy() to copy the resource data into a byte[]. Clean up with FreeResource and FreeLibrary.