- implement enough of BuilderNative for GZDB to successfully run without crashing

This commit is contained in:
Magnus Norddahl 2019-08-09 23:15:48 +02:00
parent 37876f6d8a
commit 407cc703b8
14 changed files with 214 additions and 95 deletions

View file

@ -3424,7 +3424,7 @@ namespace CodeImp.DoomBuilder.Data
// Make custom rendertarget
const int cubemaptexsize = 1024;
Texture rendertarget = new Texture(cubemaptexsize, cubemaptexsize, 1, Format.A8R8G8B8);
Texture rendertarget = new Texture(cubemaptexsize, cubemaptexsize);
// Start rendering
General.Map.Graphics.StartRendering(true, new Color4(), rendertarget, true);
@ -3452,7 +3452,7 @@ namespace CodeImp.DoomBuilder.Data
yscale *= 1.65f;
// Make cubemap texture
CubeTexture cubemap = new CubeTexture(cubemaptexsize, 1, Format.A8R8G8B8);
CubeTexture cubemap = new CubeTexture(cubemaptexsize);
// Set render settings...
General.Map.Graphics.SetRenderState(RenderState.ZEnable, false);
@ -3652,7 +3652,7 @@ namespace CodeImp.DoomBuilder.Data
// sides[] must contain 6 square Po2 images in this order: North, East, South, West, Top, Bottom
private static CubeTexture MakeSkyBox(Bitmap[] sides, int targetsize, bool fliptop)
{
CubeTexture cubemap = new CubeTexture(targetsize, 1, Format.A8R8G8B8);
CubeTexture cubemap = new CubeTexture(targetsize);
// Draw faces
sides[3].RotateFlip(RotateFlipType.Rotate90FlipNone);
@ -3752,15 +3752,10 @@ namespace CodeImp.DoomBuilder.Data
private static Texture TextureFromBitmap(Image image)
{
using(MemoryStream ms = new MemoryStream())
{
image.Save(ms, ImageFormat.Png);
ms.Seek(0, SeekOrigin.Begin);
// Classic skies textures can be NPo2 (and D3D Texture is resized to Po2 by default),
// so we need to explicitly specify the size
return Texture.FromStream(ms, (int) ms.Length, image.Size.Width, image.Size.Height, 0, Format.Unknown);
}
using (var bitmap = new Bitmap(image))
{
return new Texture(bitmap);
}
}
#endregion

View file

@ -464,22 +464,10 @@ namespace CodeImp.DoomBuilder.Data
// Only do this when texture is not created yet
if(((texture == null) || (texture.Disposed)) && this.IsImageLoaded && !loadfailed)
{
Image img = bitmap;
Bitmap img = bitmap;
if(loadfailed) img = Properties.Resources.Failed;
// Write to memory stream and read from memory
MemoryStream memstream = new MemoryStream((img.Size.Width * img.Size.Height * 4) + 4096);
img.Save(memstream, ImageFormat.Bmp);
memstream.Seek(0, SeekOrigin.Begin);
if(dynamictexture)
{
texture = Texture.FromStream(memstream, (int)memstream.Length, img.Size.Width, img.Size.Height, mipmaplevels, Format.A8R8G8B8);
}
else
{
texture = Texture.FromStream(memstream, (int)memstream.Length, img.Size.Width, img.Size.Height, mipmaplevels, Format.Unknown);
}
memstream.Dispose();
texture = new Texture(img);
if(dynamictexture)
{

View file

@ -1160,16 +1160,11 @@ namespace CodeImp.DoomBuilder.GZBuilder.MD3
// Calculate model radius
mde.Model.Radius = Math.Max(Math.Max(Math.Abs(minY), Math.Abs(maxY)), Math.Max(Math.Abs(minX), Math.Abs(maxX)));
// Create texture
MemoryStream memstream = new MemoryStream((4096 * 4) + 4096);
using(Bitmap bmp = CreateVoxelTexture(palette)) bmp.Save(memstream, ImageFormat.Bmp);
memstream.Seek(0, SeekOrigin.Begin);
Texture texture = Texture.FromStream(memstream, (int)memstream.Length, 64, 64, 0, Format.Unknown);
memstream.Dispose();
// Add texture
mde.Model.Textures.Add(texture);
// Create texture new Texture(bmp.Width)
using(Bitmap bmp = CreateVoxelTexture(palette))
{
mde.Model.Textures.Add(new Texture(bmp));
}
// Create mesh
Mesh mesh = new Mesh(vertexElements, verts.ToArray(), indices.ToArray());
@ -1666,23 +1661,13 @@ namespace CodeImp.DoomBuilder.GZBuilder.MD3
Texture texture = null;
//create texture
if(Path.GetExtension(path) == ".pcx") //pcx format requires special handling...
FileImageReader fir = new FileImageReader();
Bitmap bitmap = fir.ReadAsBitmap(ms);
ms.Close();
if(bitmap != null)
{
FileImageReader fir = new FileImageReader();
Bitmap bitmap = fir.ReadAsBitmap(ms);
ms.Close();
if(bitmap != null)
{
texture.SetPixels(bitmap);
}
}
else
{
texture = Texture.FromStream(ms);
ms.Close();
texture = new Texture(bitmap);
}
return texture;

View file

@ -264,7 +264,6 @@ namespace CodeImp.DoomBuilder.Rendering
public enum TransformState { World, View, Projection }
public enum SamplerState { AddressU, AddressV, AddressW }
public enum TextureAddress { Wrap, Clamp }
public enum Format { Unknown, A8R8G8B8 }
public enum ShaderFlags { None, Debug }
public enum PrimitiveType { LineList, TriangleList, TriangleStrip }
public enum TextureFilter { None, Point, Linear, Anisotropic }

View file

@ -361,11 +361,11 @@ namespace CodeImp.DoomBuilder.Rendering
windowsize.Height = graphics.RenderTarget.ClientSize.Height;
// Create rendertargets textures
plottertex = new Texture(windowsize.Width, windowsize.Height, 1, Format.A8R8G8B8);
thingstex = new Texture(windowsize.Width, windowsize.Height, 1, Format.A8R8G8B8);
backtex = new Texture(windowsize.Width, windowsize.Height, 1, Format.A8R8G8B8);
overlaytex = new Texture(windowsize.Width, windowsize.Height, 1, Format.A8R8G8B8);
surfacetex = new Texture(windowsize.Width, windowsize.Height, 1, Format.A8R8G8B8);
plottertex = new Texture(windowsize.Width, windowsize.Height);
thingstex = new Texture(windowsize.Width, windowsize.Height);
backtex = new Texture(windowsize.Width, windowsize.Height);
overlaytex = new Texture(windowsize.Width, windowsize.Height);
surfacetex = new Texture(windowsize.Width, windowsize.Height);
// Get the real surface sizes
structsize.Width = plottertex.Width;

View file

@ -326,16 +326,11 @@ namespace CodeImp.DoomBuilder.Rendering
texture = null;
}
// Create label image
Bitmap img = CreateLabelImage(text, font, color, backcolor, drawbg, textrect, bgrect, texturesize, textorigin);
//texturesize = img.Size;
// Create texture
MemoryStream memstream = new MemoryStream((img.Size.Width * img.Size.Height * 4) + 4096);
img.Save(memstream, ImageFormat.Bmp);
memstream.Seek(0, SeekOrigin.Begin);
texture = Texture.FromStream(memstream, (int)memstream.Length, img.Size.Width, img.Size.Height, 1, Format.Unknown);
// Create label image
using (Bitmap img = CreateLabelImage(text, font, color, backcolor, drawbg, textrect, bgrect, texturesize, textorigin))
{
texture = new Texture(img);
}
}
//mxd. Create the buffer

View file

@ -32,19 +32,59 @@ namespace CodeImp.DoomBuilder.Rendering
}
}
IntPtr Handle;
protected IntPtr Handle;
[DllImport("BuilderNative.dll", CallingConvention = CallingConvention.Cdecl)]
static extern IntPtr Texture_New();
protected static extern IntPtr Texture_New();
[DllImport("BuilderNative.dll", CallingConvention = CallingConvention.Cdecl)]
static extern void Texture_Delete(IntPtr handle);
protected static extern void Texture_Delete(IntPtr handle);
[DllImport("BuilderNative.dll", CallingConvention = CallingConvention.Cdecl)]
protected static extern void Texture_Set2DImage(IntPtr handle, int width, int height);
[DllImport("BuilderNative.dll", CallingConvention = CallingConvention.Cdecl)]
protected static extern void Texture_SetPixels(IntPtr handle, IntPtr data);
[DllImport("BuilderNative.dll", CallingConvention = CallingConvention.Cdecl)]
protected static extern IntPtr Texture_Lock(IntPtr handle);
[DllImport("BuilderNative.dll", CallingConvention = CallingConvention.Cdecl)]
protected static extern void Texture_Unlock(IntPtr handle);
[DllImport("BuilderNative.dll", CallingConvention = CallingConvention.Cdecl)]
protected static extern void Texture_SetCubeImage(IntPtr handle, int size);
[DllImport("BuilderNative.dll", CallingConvention = CallingConvention.Cdecl)]
protected static extern void Texture_SetCubePixels(IntPtr handle, CubeMapFace face, IntPtr data);
}
public class Texture : BaseTexture
{
public Texture(int width, int height, int levels, Format format)
public Texture(int width, int height)
{
Width = width;
Height = height;
Texture_Set2DImage(Handle, Width, Height);
}
public Texture(System.Drawing.Bitmap bitmap)
{
Width = bitmap.Width;
Height = bitmap.Height;
Texture_Set2DImage(Handle, Width, Height);
SetPixels(bitmap);
}
public Texture(System.Drawing.Image image)
{
using (var bitmap = new System.Drawing.Bitmap(image))
{
Width = bitmap.Width;
Height = bitmap.Height;
Texture_Set2DImage(Handle, Width, Height);
SetPixels(bitmap);
}
}
public int Width { get; private set; }
@ -54,48 +94,50 @@ namespace CodeImp.DoomBuilder.Rendering
public void SetPixels(System.Drawing.Bitmap bitmap)
{
/*
BitmapData bmpdata = bitmap.LockBits(new Rectangle(0, 0, bitmap.Size.Width, bitmap.Size.Height), ImageLockMode.ReadOnly, PixelFormat.Format32bppArgb);
System.Drawing.Imaging.BitmapData bmpdata = bitmap.LockBits(
new System.Drawing.Rectangle(0, 0, bitmap.Size.Width, bitmap.Size.Height),
System.Drawing.Imaging.ImageLockMode.ReadOnly,
System.Drawing.Imaging.PixelFormat.Format32bppArgb);
DataRectangle textureLock = texture.LockRectangle(0, LockFlags.None);
textureLock.Data.WriteRange(bmlock.Scan0, bmlock.Height * bmlock.Stride);
texture.UnlockRectangle(0);
Texture_SetPixels(Handle, bmpdata.Scan0);
bitmap.UnlockBits(bmpdata);
*/
}
internal Plotter LockPlotter(int visibleWidth, int visibleHeight)
{
//return new Plotter((PixelColor*)plotlocked.Data.DataPointer.ToPointer(), plotlocked.Pitch / sizeof(PixelColor), Height, visibleWidth, visibleHeight);
return null;
unsafe
{
IntPtr data = Texture_Lock(Handle);
return new Plotter((PixelColor*)data.ToPointer(), Width, Height, Math.Min(Width, visibleWidth), Math.Min(Height, visibleHeight));
}
}
public void UnlockPlotter()
{
}
public static Texture FromStream(System.IO.Stream stream)
{
return null;
}
public static Texture FromStream(System.IO.Stream stream, int length, int width, int height, int levels, Format format)
{
return null;
Texture_Unlock(Handle);
}
}
public class CubeTexture : BaseTexture
{
public CubeTexture(int size, int levels, Format format)
public CubeTexture(int size)
{
Texture_SetCubeImage(Handle, size);
}
public void SetPixels(CubeMapFace face, System.Drawing.Bitmap bitmap)
{
System.Drawing.Imaging.BitmapData bmpdata = bitmap.LockBits(
new System.Drawing.Rectangle(0, 0, bitmap.Size.Width, bitmap.Size.Height),
System.Drawing.Imaging.ImageLockMode.ReadOnly,
System.Drawing.Imaging.PixelFormat.Format32bppArgb);
Texture_SetCubePixels(Handle, face, bmpdata.Scan0);
bitmap.UnlockBits(bmpdata);
}
}
public enum CubeMapFace { PositiveX, PositiveY, PositiveZ, NegativeX, NegativeY, NegativeZ }
public enum CubeMapFace : int { PositiveX, PositiveY, PositiveZ, NegativeX, NegativeY, NegativeZ }
}

View file

@ -1,12 +1,14 @@
#include "IndexBuffer.h"
IndexBuffer::IndexBuffer(int sizeInBytes)
IndexBuffer::IndexBuffer(int sizeInBytes) : mData(sizeInBytes)
{
}
void IndexBuffer::SetBufferData(const void* data, int64_t size)
{
if (size > 0 && size < (int64_t)mData.size())
memcpy(mData.data(), data, size);
}
/////////////////////////////////////////////////////////////////////////////

View file

@ -1,6 +1,7 @@
#pragma once
#include <cstdint>
#include <vector>
class IndexBuffer
{
@ -8,4 +9,7 @@ public:
IndexBuffer(int sizeInBytes);
void SetBufferData(const void* data, int64_t size);
private:
std::vector<uint8_t> mData;
};

View file

@ -5,6 +5,44 @@ Texture::Texture()
{
}
void Texture::Set2DImage(int width, int height)
{
mCubeTexture = false;
mWidth = width;
mHeight = height;
}
void Texture::SetCubeImage(int size)
{
mCubeTexture = true;
mWidth = size;
mHeight = size;
}
void Texture::SetPixels(const void* data)
{
mPixels[0].resize(mWidth * (size_t)mHeight);
memcpy(mPixels[0].data(), data, sizeof(uint32_t) * mWidth * mHeight);
}
void Texture::SetCubePixels(CubeMapFace face, const void* data)
{
mPixels[(int)face].resize(mWidth * (size_t)mHeight);
memcpy(mPixels[(int)face].data(), data, sizeof(uint32_t) * mWidth * mHeight);
}
void* Texture::Lock()
{
mPixels[0].resize(mWidth * (size_t)mHeight);
return mPixels[0].data();
}
void Texture::Unlock()
{
}
/////////////////////////////////////////////////////////////////////////////
Texture* Texture_New()
{
return new Texture();
@ -14,3 +52,33 @@ void Texture_Delete(Texture* tex)
{
delete tex;
}
void Texture_Set2DImage(Texture* handle, int width, int height)
{
handle->Set2DImage(width, height);
}
void Texture_SetPixels(Texture* handle, const void* data)
{
handle->SetPixels(data);
}
void* Texture_Lock(Texture* handle)
{
return handle->Lock();
}
void Texture_Unlock(Texture* handle)
{
handle->Unlock();
}
void Texture_SetCubeImage(Texture* handle, int size)
{
handle->SetCubeImage(size);
}
void Texture_SetCubePixels(Texture* handle, CubeMapFace face, const void *data)
{
handle->SetCubePixels(face, data);
}

View file

@ -1,9 +1,36 @@
#pragma once
#include <cstdint>
#include <vector>
#include <map>
enum class CubeMapFace : int
{
PositiveX,
PositiveY,
PositiveZ,
NegativeX,
NegativeY,
NegativeZ
};
class Texture
{
public:
Texture();
void Set2DImage(int width, int height);
void SetCubeImage(int size);
void SetPixels(const void* data);
void SetCubePixels(CubeMapFace face, const void* data);
void* Lock();
void Unlock();
private:
int mWidth = 0;
int mHeight = 0;
bool mCubeTexture = false;
std::map<int, std::vector<uint32_t>> mPixels;
};

View file

@ -1,16 +1,20 @@
#include "VertexBuffer.h"
VertexBuffer::VertexBuffer(int sizeInBytes)
VertexBuffer::VertexBuffer(int sizeInBytes) : mData(sizeInBytes)
{
}
void VertexBuffer::SetBufferData(const void* data, int64_t size)
{
if (size > 0 && size < (int64_t)mData.size())
memcpy(mData.data(), data, size);
}
void VertexBuffer::SetBufferSubdata(int64_t destOffset, const void* data, int64_t size)
{
if (destOffset >= 0 && size > 0 && size < (int64_t)mData.size() - destOffset)
memcpy(mData.data() + destOffset, data, size);
}
/////////////////////////////////////////////////////////////////////////////

View file

@ -1,6 +1,7 @@
#pragma once
#include <cstdint>
#include <vector>
class VertexBuffer
{
@ -9,4 +10,7 @@ public:
void SetBufferData(const void* data, int64_t size);
void SetBufferSubdata(int64_t destOffset, const void* data, int64_t size);
private:
std::vector<uint8_t> mData;
};

View file

@ -14,3 +14,9 @@ EXPORTS
IndexBuffer_SetBufferData
Texture_New
Texture_Delete
Texture_Set2DImage
Texture_SetPixels
Texture_Lock
Texture_Unlock
Texture_SetCubeImage
Texture_SetCubePixels