Add GEDX9Texture

This commit is contained in:
Benau 2021-04-23 10:58:19 +08:00
parent 18690fad3a
commit a5f29bc560
5 changed files with 305 additions and 1 deletions

View File

@ -8,5 +8,6 @@ add_library(graphics_engine STATIC
src/vulkan.c
src/ge_main.cpp
src/ge_texture.cpp
src/ge_dx9_texture.cpp
src/ge_gl_texture.cpp
)

View File

@ -0,0 +1,201 @@
#include "IrrCompileConfig.h"
#ifdef _IRR_COMPILE_WITH_DIRECT3D_9_
#include "ge_dx9_texture.hpp"
#include "ge_main.hpp"
#include "ge_texture.hpp"
#include <vector>
namespace GE
{
GEDX9Texture::GEDX9Texture(const std::string& path,
std::function<void(video::IImage*)> image_mani)
: video::ITexture(path.c_str()), m_image_mani(image_mani),
m_device_9(NULL), m_texture_9(NULL), m_texture_size(0),
m_disable_reload(false)
{
getDevice9();
reload();
} // GEDX9Texture
// ----------------------------------------------------------------------------
GEDX9Texture::GEDX9Texture(video::IImage* img, const std::string& name)
: video::ITexture(name.c_str()), m_image_mani(nullptr),
m_device_9(NULL), m_texture_9(NULL), m_texture_size(0),
m_disable_reload(true)
{
getDevice9();
if (!m_device_9 || !img)
return;
uint8_t* data = NULL;
m_size = m_orig_size = img->getDimension();
HRESULT hr = m_device_9->CreateTexture(m_size.Width, m_size.Height,
0, D3DUSAGE_AUTOGENMIPMAP, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED,
&m_texture_9, NULL);
if (FAILED(hr))
goto exit;
data = (uint8_t*)img->lock();
upload(data);
exit:
img->unlock();
img->drop();
} // GEDX9Texture
// ----------------------------------------------------------------------------
GEDX9Texture::GEDX9Texture(const std::string& name, unsigned int size)
: video::ITexture(name.c_str()), m_image_mani(nullptr),
m_device_9(NULL), m_texture_9(NULL), m_texture_size(0),
m_disable_reload(true)
{
getDevice9();
if (!m_device_9)
return;
m_orig_size.Width = size;
m_orig_size.Height = size;
m_size = m_orig_size;
HRESULT hr = m_device_9->CreateTexture(m_size.Width, m_size.Height,
0, D3DUSAGE_AUTOGENMIPMAP, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED,
&m_texture_9, NULL);
if (FAILED(hr))
return;
std::vector<uint8_t> data;
data.resize(size * size * 4, 0);
upload(data.data());
} // GEDX9Texture
// ----------------------------------------------------------------------------
GEDX9Texture::~GEDX9Texture()
{
if (m_texture_9)
m_texture_9->Release();
if (m_device_9)
m_device_9->Release();
} // ~GEDX9Texture
// ----------------------------------------------------------------------------
void GEDX9Texture::getDevice9()
{
m_device_9 = GE::getDriver()->getExposedVideoData().D3D9.D3DDev9;
if (m_device_9)
m_device_9->AddRef();
} // getDevice9
// ----------------------------------------------------------------------------
void GEDX9Texture::reload()
{
if (!m_device_9 || m_disable_reload)
return;
video::IImage* texture_image = getResizedImage(NamedPath.getPtr(),
&m_orig_size);
if (texture_image == NULL)
return;
m_size = texture_image->getDimension();
if (m_image_mani)
m_image_mani(texture_image);
if (m_texture_9 != NULL)
{
m_texture_9->Release();
m_texture_9 = NULL;
}
uint8_t* data = (uint8_t*)texture_image->lock();
HRESULT hr = m_device_9->CreateTexture(m_size.Width, m_size.Height,
0, D3DUSAGE_AUTOGENMIPMAP, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED,
&m_texture_9, NULL);
if (FAILED(hr))
goto exit;
upload(data);
exit:
texture_image->unlock();
texture_image->drop();
} // reload
// ----------------------------------------------------------------------------
void GEDX9Texture::upload(uint8_t* data)
{
const unsigned int w = m_size.Width;
const unsigned int h = m_size.Height;
HRESULT hr;
D3DLOCKED_RECT rect;
hr = m_texture_9->LockRect(0, &rect, 0, 0);
if (FAILED(hr))
return;
uint8_t* dst = (uint8_t*)rect.pBits;
for (u32 i = 0; i < h; i++)
{
memcpy(dst, data, w * 4);
data += w * 4;
dst += rect.Pitch;
}
hr = m_texture_9->UnlockRect(0);
if (FAILED(hr))
return;
m_texture_9->GenerateMipSubLevels();
m_texture_size = w * h * 4;
} // upload
// ----------------------------------------------------------------------------
void* GEDX9Texture::lock(video::E_TEXTURE_LOCK_MODE mode, u32 mipmap_level)
{
if (mode != video::ETLM_READ_ONLY || !m_texture_9)
return NULL;
HRESULT hr;
D3DLOCKED_RECT rect;
hr = m_texture_9->LockRect(0, &rect, 0,
(mode == video::ETLM_READ_ONLY) ? D3DLOCK_READONLY : 0);
if (FAILED(hr))
return NULL;
return rect.pBits;
} // lock
//-----------------------------------------------------------------------------
void GEDX9Texture::updateTexture(void* data, video::ECOLOR_FORMAT format,
u32 w, u32 h, u32 x, u32 y)
{
if (!m_texture_9)
return;
std::vector<uint8_t> image_data;
uint8_t* src = NULL;
if (format == video::ECF_R8)
{
const unsigned int size = w * h;
image_data.resize(size * 4, 255);
uint8_t* orig_data = (uint8_t*)data;
for (unsigned int i = 0; i < size; i++)
image_data[4 * i + 3] = orig_data[i];
src = image_data.data();
}
else if (format == video::ECF_A8R8G8B8)
{
src = (uint8_t*)data;
}
if (src == NULL)
return;
HRESULT hr;
D3DLOCKED_RECT rect;
RECT subimg;
subimg.left = x;
subimg.top = y;
subimg.right = x + w;
subimg.bottom = y + h;
hr = m_texture_9->LockRect(0, &rect, &subimg, 0);
if (FAILED(hr))
return;
uint8_t* dst = (uint8_t*)rect.pBits;
for (u32 i = 0; i < h; i++)
{
memcpy(dst, src, w * 4);
src += w * 4;
dst += rect.Pitch;
}
hr = m_texture_9->UnlockRect(0);
if (FAILED(hr))
return;
m_texture_9->GenerateMipSubLevels();
} // updateTexture
}
#endif

View File

@ -0,0 +1,88 @@
#ifndef HEADER_GE_DX9_TEXTURE_HPP
#define HEADER_GE_DX9_TEXTURE_HPP
#include "IrrCompileConfig.h"
#ifdef _IRR_COMPILE_WITH_DIRECT3D_9_
#include <d3d9.h>
#include <functional>
#include <string>
#include <ITexture.h>
using namespace irr;
namespace GE
{
class GEDX9Texture : public video::ITexture
{
private:
core::dimension2d<u32> m_size, m_orig_size;
std::function<void(video::IImage*)> m_image_mani;
IDirect3DDevice9* m_device_9;
IDirect3DTexture9* m_texture_9;
unsigned int m_texture_size;
const bool m_disable_reload;
// ------------------------------------------------------------------------
void getDevice9();
// ------------------------------------------------------------------------
void upload(uint8_t* data);
public:
// ------------------------------------------------------------------------
GEDX9Texture(const std::string& path,
std::function<void(video::IImage*)> image_mani = nullptr);
// ------------------------------------------------------------------------
GEDX9Texture(video::IImage* img, const std::string& name);
// ------------------------------------------------------------------------
GEDX9Texture(const std::string& name, unsigned int size);
// ------------------------------------------------------------------------
virtual ~GEDX9Texture();
// ------------------------------------------------------------------------
virtual void* lock(video::E_TEXTURE_LOCK_MODE mode =
video::ETLM_READ_WRITE, u32 mipmap_level = 0);
// ------------------------------------------------------------------------
virtual void unlock()
{
if (m_texture_9)
m_texture_9->UnlockRect(0);
}
// ------------------------------------------------------------------------
virtual const core::dimension2d<u32>& getOriginalSize() const
{ return m_orig_size; }
// ------------------------------------------------------------------------
virtual const core::dimension2d<u32>& getSize() const { return m_size; }
// ------------------------------------------------------------------------
virtual video::E_DRIVER_TYPE getDriverType() const
{ return video::EDT_DIRECT3D9; }
// ------------------------------------------------------------------------
virtual video::ECOLOR_FORMAT getColorFormat() const
{ return video::ECF_A8R8G8B8; }
// ------------------------------------------------------------------------
virtual u32 getPitch() const { return 0; }
// ------------------------------------------------------------------------
virtual bool hasMipMaps() const { return true; }
// ------------------------------------------------------------------------
virtual void regenerateMipMapLevels(void* mipmap_data = NULL) {}
// ------------------------------------------------------------------------
virtual u64 getTextureHandler() const { return (u64)m_texture_9; }
// ------------------------------------------------------------------------
virtual unsigned int getTextureSize() const { return m_texture_size; }
// ------------------------------------------------------------------------
virtual void reload();
// ------------------------------------------------------------------------
virtual void updateTexture(void* data, irr::video::ECOLOR_FORMAT format,
u32 w, u32 h, u32 x, u32 y);
}; // GEDX9Texture
}
#endif
#endif

View File

@ -1,4 +1,5 @@
#include "ge_main.hpp"
#include "ge_dx9_texture.hpp"
#include "ge_gl_texture.hpp"
#include "ge_texture.hpp"
@ -55,6 +56,10 @@ irr::video::ITexture* createTexture(const std::string& path,
case video::EDT_OPENGL:
case video::EDT_OGLES2:
return new GEGLTexture(path, image_mani);
#ifdef _IRR_COMPILE_WITH_DIRECT3D_9_
case video::EDT_DIRECT3D9:
return new GEDX9Texture(path, image_mani);
#endif
default:
return NULL;
}
@ -69,6 +74,10 @@ irr::video::ITexture* createTexture(video::IImage* img,
case video::EDT_OPENGL:
case video::EDT_OGLES2:
return new GEGLTexture(img, name);
#ifdef _IRR_COMPILE_WITH_DIRECT3D_9_
case video::EDT_DIRECT3D9:
return new GEDX9Texture(img, name);
#endif
default:
return NULL;
}
@ -83,6 +92,10 @@ irr::video::ITexture* createFontTexture(const std::string& name,
case video::EDT_OPENGL:
case video::EDT_OGLES2:
return new GEGLTexture(name, size, single_channel);
#ifdef _IRR_COMPILE_WITH_DIRECT3D_9_
case video::EDT_DIRECT3D9:
return new GEDX9Texture(name, size);
#endif
default:
return NULL;
}

View File

@ -751,7 +751,8 @@ bool CD3D9Driver::setActiveTexture(u32 stage, const video::ITexture* texture)
}
else
{
pID3DDevice->SetTexture(stage, ((const CD3D9Texture*)texture)->getDX9Texture());
IDirect3DBaseTexture9* tex = (IDirect3DBaseTexture9*)texture->getTextureHandler();
pID3DDevice->SetTexture(stage, tex);
}
return true;
}