3#include "OpenGLCommon.Texture.hpp"
4#include <alicorn/std.hpp>
6#ifndef GL_DEPTH_COMPONENT
7# define GL_DEPTH_COMPONENT 0
10namespace covellite::api::renderer
13OpenGLCommon::Texture::Texture(
const Component::Texture & _Data) :
14 m_Destination(GetDestination(_Data.Index, _Data.Destination, _Data.Name)),
15 m_Format(GetFormat(_Data.Destination)),
16 m_TextureId(BuildTexture()),
17 m_IsMapping(_Data.IsMapping),
18 m_Capacity(_Data.Capacity),
19 m_Target(GL_TEXTURE_2D)
21 MakeContent(_Data.Width, _Data.Height, _Data.pTextureData);
24OpenGLCommon::Texture::Texture(
const Component::Texture & _Data,
bool) :
25 m_Destination(GetDestination(_Data.Index, _Data.Destination, _Data.Name)),
27 m_TextureId(BuildTexture()),
28 m_IsMapping(_Data.IsMapping),
29 m_Capacity(_Data.Capacity),
30 m_Target(GL_TEXTURE_2D_ARRAY)
33 glTexStorage3D(GL_TEXTURE_2D_ARRAY, _Data.IsUsingMipmapping ? 8 : 1, GL_RGBA8,
34 _Data.Width, _Data.Height, _Data.DataCount);
35 glTexSubImage3D(GL_TEXTURE_2D_ARRAY, 0, 0, 0, 0, _Data.Width, _Data.Height,
36 _Data.DataCount, m_Format, GL_UNSIGNED_BYTE, ::std::data(_Data.Data));
37 if (_Data.IsUsingMipmapping) glGenerateMipmap(GL_TEXTURE_2D_ARRAY);
40 const auto Error = glGetError();
41 if (Error != GL_NO_ERROR)
43 throw STD_EXCEPTION <<
"Create texture error: " << Error;
47 OpenGLCommon::Texture::~Texture(
void)
noexcept
49 glDeleteTextures(1, &m_TextureId);
53void OpenGLCommon::Texture::Bind(
const bool _IsActivate)
noexcept
55 glBindTexture(m_Target, _IsActivate ? m_TextureId : 0);
58void OpenGLCommon::Texture::MakeContent(
60 const GLsizei _Height,
61 const GLvoid * _pData)
65# if !defined(GL_RGBA32F)
66# define GL_RGBA32F GL_RGBA
69# if !defined(GL_RGBA16F)
70# define GL_RGBA16F GL_RGBA
73# if !defined(GL_HALF_FLOAT)
74# define GL_HALF_FLOAT GL_FLOAT
77 const GLint InternalFormat =
78 (m_Format == GL_DEPTH_COMPONENT) ? GL_DEPTH_COMPONENT :
79 (m_Capacity == 32) ? GL_RGBA32F :
80 (m_Capacity == 16) ? GL_RGBA16F :
84 (InternalFormat == GL_RGBA) ? GL_UNSIGNED_BYTE :
85 (m_Capacity == 32) ? GL_FLOAT :
86 (m_Capacity == 16) ? GL_HALF_FLOAT :
91 glTexImage2D(GL_TEXTURE_2D, 0,
95 m_Format == GL_DEPTH_COMPONENT ? GL_UNSIGNED_INT : Format,
115 const auto Error = glGetError();
116 if (Error != GL_NO_ERROR)
118 throw STD_EXCEPTION <<
"Create texture error: " << Error;
123 m_ReadCopyData.resize(
static_cast<size_t>(_Width) * _Height * 4, 0x00);
127 auto OpenGLCommon::Texture::GetDestination(
const int _Index,
128 const String_t & _Destination,
const String_t & _Name) -> Destination_t
132 using namespace ::alicorn::extension::std;
134 return { _Index, string_cast<::std::string, Encoding::Ascii128>(_Name) };
137 if (_Destination == uT(
"diffuse"))
return { 0,
"TexDiffuse" };
139 static const ::std::vector<::std::pair<String_t, const char *>> Destinations =
141 { uT(
"albedo"),
"TexAlbedo" },
142 { uT(
"metalness"),
"TexMetalness" },
143 { uT(
"roughness"),
"TexRoughness" },
144 { uT(
"normal"),
"TexNormal" },
145 { uT(
"occlusion"),
"TexOcclusion" },
146 { uT(
"depth"),
"TexDepth" },
149 const auto itValue = ::std::find_if(Destinations.cbegin(),
150 Destinations.cend(), [&](const ::std::pair<String_t, const char *> & _Dest)
152 return (_Destination == _Dest.first);
154 if (itValue == Destinations.cend())
156 throw STD_EXCEPTION <<
"Unexpected destination texture: " <<
157 _Destination << uT(
" [id=???") << uT(
"].");
160 const auto IndexDestination =
161 static_cast<GLint
>(::std::distance(Destinations.cbegin(), itValue));
162 return { IndexDestination, Destinations[IndexDestination].second };
165 GLint OpenGLCommon::Texture::GetFormat(
const String_t & _Destination)
167 return (_Destination == uT(
"depth")) ? GL_DEPTH_COMPONENT : GL_RGBA;
170 GLuint OpenGLCommon::Texture::BuildTexture(
void)
noexcept
172 GLuint TextureId = 0;
173 glGenTextures(1, &TextureId);