diff --git a/TSE_Core/src/BehaviourScripts/Camera.cpp b/TSE_Core/src/BehaviourScripts/Camera.cpp index 60c7b59..3adea2d 100644 --- a/TSE_Core/src/BehaviourScripts/Camera.cpp +++ b/TSE_Core/src/BehaviourScripts/Camera.cpp @@ -1,217 +1,239 @@ -#include "Camera.hpp" -#include "elements/Transformable.hpp" -#include "interfaces/IRenderer.hpp" -#include "uuid.h" - -TSE::Camera* TSE::Camera::mainCamera = nullptr; -TSE::ICameraHelper* TSE::Camera::helper = nullptr; - -float TSE::Camera::GetRenderScale() const -{ - return RenderScale; -} - -TSE::ProjectionType TSE::Camera::GetProjection() const -{ - return projection; -} - -float TSE::Camera::GetNearClippingPlane() const -{ - return nearClippingPlane; -} - -float TSE::Camera::GetFarClippingPlane() const -{ - return farClippingPlane; -} - -float TSE::Camera::GetFov() const -{ - return fov; -} - -const TSE::Vector2 &TSE::Camera::GetRenderTargetSize() const -{ - return lastRtSize; -} - -TSE::Vector3 TSE::Camera::SceenPositionToGamePosition(Vector2 screenPos) -{ - float x = 2.0f * screenPos.x / lastRtSize.x -1.0f; - float y = 1.0f - 2.0f * screenPos.y / lastRtSize.y; - float z = -1.0f; - Vector4 ndc(x,y,x,1); - - Matrix4x4 InversProj = Matrix4x4(*projectionMatrix); - InversProj.Invert(); - Vector4 camSpace = InversProj * ndc; - camSpace = camSpace / camSpace.w; - Vector3 relativPos(camSpace); - relativPos.z = 0; - return baseObject->LocalToGlobalPosition(relativPos); -} - -void TSE::Camera::SetRenderScale(float v) -{ - RenderScale = v; RecalculateProjMatrix(); -} - -void TSE::Camera::SetProjection(ProjectionType v) -{ - projection = v; RecalculateProjMatrix(); -} - -void TSE::Camera::SetNearClippingPlane(float v) -{ - nearClippingPlane = v; RecalculateProjMatrix(); -} - -void TSE::Camera::SetFarClippingPlane(float v) -{ - farClippingPlane = v; RecalculateProjMatrix(); -} - -void TSE::Camera::SetFov(float v) -{ - fov = v; RecalculateProjMatrix(); -} - -TSE::Camera::Camera() -{ -} - -TSE::Camera::~Camera() -{ - delete(projectionMatrix); - if(mainCamera == this) - mainCamera = nullptr; -} - -void TSE::Camera::OnResize(float width, float height, IResizable *wnd) -{ - lastRtSize = {width, height}; - RecalculateProjMatrix(); -} - -void TSE::Camera::SetRenderTarget(IRenderTarget *target) -{ - if(rt != nullptr) - rt->RemoveResizeNotifiable(this); - if(target != nullptr) - target->AddResizeNotifiable(this); - rt = target; - if(lastRtSize != rt->GetRawIResizableSize()) - { - lastRtSize = rt->GetRawIResizableSize(); - RecalculateProjMatrix(); - } -} - -TSE::IRenderTarget *TSE::Camera::GetRenderTarget() -{ - return rt; -} - -void TSE::Camera::RecalculateProjMatrix() -{ - if(projectionMatrix) - delete(projectionMatrix); - - if(projection == ProjectionType::Orthographic) - { - float x = lastRtSize.x / RenderScale; - float y = lastRtSize.y / RenderScale; - float mx = -x; - float my = -y; - projectionMatrix = new Matrix4x4(Matrix4x4::Orthographic(mx, x, my, y, nearClippingPlane, farClippingPlane)); - } - else if(projection == ProjectionType::Perspective) - { - float x = lastRtSize.x / RenderScale; - float y = lastRtSize.y / RenderScale; - - float aspectRatio = x / y; - - projectionMatrix = new Matrix4x4(Matrix4x4::Perspective(fov, aspectRatio, nearClippingPlane, farClippingPlane)); - } -} - -void TSE::Camera::OnUpdate() -{ - if(mainCamera == nullptr && baseObject->name != ".EditorCamera") - { - mainCamera = this; - } - - if(rt != nullptr) - IRenderer::camerasToRenderWith.push_back(this); -} - -void TSE::Camera::Start() -{ - if(mainCamera == nullptr && baseObject->name != ".EditorCamera") - { - mainCamera = this; - } -} - - -TSE::Matrix4x4 BuildView_Zplus_RH(const TSE::Matrix4x4& world) -{ - using namespace TSE; - // Welt-Position (w=1) - Vector3 pos = Vector3(world * Vector4(0,0,0,1)); - - // Richtungsachsen in Welt (w=0, KEINE Translation!) - Vector3 fwdWS = Vector3(world * Vector4(0,0,1,0)); // +Z vorwärts in Welt - Vector3 upWS = Vector3(world * Vector4(0,1,0,0)); // +Y oben in Welt - - // Orthonormale Basis aufbauen (X+ soll "right" sein) - Vector3 f = Vector3::Normalize(fwdWS); - Vector3 r = Vector3::Normalize(Vector3::Cross(upWS, f)); // right = up × forward => (+1,0,0) im Identity-Fall - Vector3 u = Vector3::Cross(f, r); // re-orthonormalisiertes up - - Matrix4x4 view(1.0f); // Identität als Basis - - // Row-major befüllen (Zeilen = r,u,-f), letzte Spalte = -dot(row, pos) bzw. +dot(f,pos) - view.m[0][0] = r.x; view.m[0][1] = r.y; view.m[0][2] = r.z; view.m[0][3] = -Vector3::Dot(r, pos); - view.m[1][0] = u.x; view.m[1][1] = u.y; view.m[1][2] = u.z; view.m[1][3] = -Vector3::Dot(u, pos); - view.m[2][0] = -f.x; view.m[2][1] = -f.y; view.m[2][2] = -f.z; view.m[2][3] = Vector3::Dot(f, pos); - view.m[3][0] = 0.0f; view.m[3][1] = 0.0f; view.m[3][2] = 0.0f; view.m[3][3] = 1.0f; - - return view; -} - -void TSE::Camera::PreDraw(IShader *shader) -{ - rt->Bind(); - shader->SetUniform("prMatrix", projectionMatrix); - - auto worlmatrix = baseObject->GetGlobalMatrix(); - - viewMatrix = BuildView_Zplus_RH(worlmatrix); - - shader->SetUniform("camMatrix", &viewMatrix); - helper->OnRenderTargetChanged(lastRtSize.x, lastRtSize.y); -} - -void TSE::Camera::PostDraw() -{ - rt->Unbind(); -} - -void TSE::Camera::Bind() -{ - rt->Bind(); -} - -void TSE::Camera::Unbind() -{ - rt->Unbind(); -} - -void TSE::Camera::UpdateRenderTarget() -{ - rt->Update(); -} +#include "Camera.hpp" +#include "elements/Transformable.hpp" +#include "interfaces/IRenderer.hpp" +#include "uuid.h" + +TSE::Camera* TSE::Camera::mainCamera = nullptr; +TSE::ICameraHelper* TSE::Camera::helper = nullptr; + +float TSE::Camera::GetRenderScale() const +{ + return RenderScale; +} + +TSE::ProjectionType TSE::Camera::GetProjection() const +{ + return projection; +} + +float TSE::Camera::GetNearClippingPlane() const +{ + return nearClippingPlane; +} + +float TSE::Camera::GetFarClippingPlane() const +{ + return farClippingPlane; +} + +float TSE::Camera::GetFov() const +{ + return fov; +} + +const TSE::Vector2 &TSE::Camera::GetRenderTargetSize() const +{ + return lastRtSize; +} + +TSE::Vector3 TSE::Camera::SceenPositionToGamePosition(Vector2 screenPos) +{ + float x = 2.0f * screenPos.x / lastRtSize.x -1.0f; + float y = 1.0f - 2.0f * screenPos.y / lastRtSize.y; + float z = -1.0f; + Vector4 ndc(x,y,x,1); + + Matrix4x4 InversProj = Matrix4x4(*projectionMatrix); + InversProj.Invert(); + Vector4 camSpace = InversProj * ndc; + camSpace = camSpace / camSpace.w; + Vector3 relativPos(camSpace); + relativPos.z = 0; + return baseObject->LocalToGlobalPosition(relativPos); +} + +void TSE::Camera::SetRenderScale(float v) +{ + RenderScale = v; RecalculateProjMatrix(); +} + +void TSE::Camera::SetProjection(ProjectionType v) +{ + projection = v; RecalculateProjMatrix(); +} + +void TSE::Camera::SetNearClippingPlane(float v) +{ + nearClippingPlane = v; RecalculateProjMatrix(); +} + +void TSE::Camera::SetFarClippingPlane(float v) +{ + farClippingPlane = v; RecalculateProjMatrix(); +} + +void TSE::Camera::SetFov(float v) +{ + fov = v; RecalculateProjMatrix(); +} + +TSE::Camera::Camera() +{ +} + +TSE::Camera::~Camera() +{ + delete(projectionMatrix); + if(mainCamera == this) + mainCamera = nullptr; +} + +void TSE::Camera::OnResize(float width, float height, IResizable *wnd) +{ + lastRtSize = {width, height}; + RecalculateProjMatrix(); +} + +void TSE::Camera::SetRenderTarget(IRenderTarget *target) +{ + if(rt != nullptr) + rt->RemoveResizeNotifiable(this); + if(target != nullptr) + target->AddResizeNotifiable(this); + rt = target; + if(lastRtSize != rt->GetRawIResizableSize()) + { + lastRtSize = rt->GetRawIResizableSize(); + RecalculateProjMatrix(); + } +} + +TSE::IRenderTarget *TSE::Camera::GetRenderTarget() +{ + return rt; +} + +void TSE::Camera::RecalculateProjMatrix() +{ + if(projectionMatrix) + delete(projectionMatrix); + + if(projection == ProjectionType::Orthographic) + { + float x = lastRtSize.x / RenderScale; + float y = lastRtSize.y / RenderScale; + float mx = -x; + float my = -y; + projectionMatrix = new Matrix4x4(Matrix4x4::Orthographic(mx, x, my, y, nearClippingPlane, farClippingPlane)); + } + else if(projection == ProjectionType::Perspective) + { + float x = lastRtSize.x / RenderScale; + float y = lastRtSize.y / RenderScale; + + float aspectRatio = x / y; + + projectionMatrix = new Matrix4x4(Matrix4x4::Perspective(fov, aspectRatio, nearClippingPlane, farClippingPlane)); + } +} + +void TSE::Camera::OnUpdate() +{ + if(mainCamera == nullptr && baseObject->name != ".EditorCamera") + { + mainCamera = this; + } + + if(rt != nullptr) + IRenderer::camerasToRenderWith.push_back(this); +} + +void TSE::Camera::Start() +{ + if(mainCamera == nullptr && baseObject->name != ".EditorCamera") + { + mainCamera = this; + } +} + + +TSE::Matrix4x4 BuildView_Zplus_RH(const TSE::Matrix4x4& world) +{ + using namespace TSE; + // Welt-Position (w=1) + Vector3 pos = Vector3(world * Vector4(0,0,0,1)); + + // Richtungsachsen in Welt (w=0, KEINE Translation!) + Vector3 fwdWS = Vector3(world * Vector4(0,0,1,0)); // +Z vorwärts in Welt + Vector3 upWS = Vector3(world * Vector4(0,1,0,0)); // +Y oben in Welt + + // Orthonormale Basis aufbauen (X+ soll "right" sein) + Vector3 f = Vector3::Normalize(fwdWS); + Vector3 r = Vector3::Normalize(Vector3::Cross(upWS, f)); // right = up × forward => (+1,0,0) im Identity-Fall + Vector3 u = Vector3::Cross(f, r); // re-orthonormalisiertes up + + Matrix4x4 view(1.0f); // Identität als Basis + + // Row-major befüllen (Zeilen = r,u,-f), letzte Spalte = -dot(row, pos) bzw. +dot(f,pos) + view.m[0][0] = r.x; view.m[0][1] = r.y; view.m[0][2] = r.z; view.m[0][3] = -Vector3::Dot(r, pos); + view.m[1][0] = u.x; view.m[1][1] = u.y; view.m[1][2] = u.z; view.m[1][3] = -Vector3::Dot(u, pos); + view.m[2][0] = -f.x; view.m[2][1] = -f.y; view.m[2][2] = -f.z; view.m[2][3] = Vector3::Dot(f, pos); + view.m[3][0] = 0.0f; view.m[3][1] = 0.0f; view.m[3][2] = 0.0f; view.m[3][3] = 1.0f; + + return view; +} + +void TSE::Camera::PreDraw(IShader *shader) +{ + rt->Bind(); + // shader->SetUniform("prMatrix", projectionMatrix); + + // auto worlmatrix = baseObject->GetGlobalMatrix(); + + // viewMatrix = BuildView_Zplus_RH(worlmatrix); + + // shader->SetUniform("camMatrix", &viewMatrix); + // helper->OnRenderTargetChanged(lastRtSize.x, lastRtSize.y); + + Vector3 pos = baseObject->GetGlobalPosition(); + Vector3 right = baseObject->LocalToGlobalPosition(Vector3::right) - pos; + Vector3 up = baseObject->LocalToGlobalPosition(Vector3::up) - pos; + Vector3 forward = baseObject->LocalToGlobalPosition(Vector3::forward) - pos; + forward.Normalize(); + + shader->SetUniform("CamPos", &pos); + shader->SetUniform("CamRight", &right); + shader->SetUniform("CamUp", &up); + shader->SetUniform("CamForward", &forward); + + float x = lastRtSize.x / RenderScale; + float y = lastRtSize.y / RenderScale; + float mx = -x; + float my = -y; + shader->SetUniform("OrthoLeft", mx); + shader->SetUniform("OrthoRight", x); + shader->SetUniform("OrthoBottom", my); + shader->SetUniform("OrthoTop", y); + shader->SetUniform("NearPlane", nearClippingPlane); + shader->SetUniform("FarPlane", farClippingPlane); +} + +void TSE::Camera::PostDraw() +{ + rt->Unbind(); +} + +void TSE::Camera::Bind() +{ + rt->Bind(); +} + +void TSE::Camera::Unbind() +{ + rt->Unbind(); +} + +void TSE::Camera::UpdateRenderTarget() +{ + rt->Update(); +} diff --git a/TSE_OpenGlImpl/src/TextureHelperOpenGL.cpp b/TSE_OpenGlImpl/src/TextureHelperOpenGL.cpp index 310c03d..f9e4d1b 100644 --- a/TSE_OpenGlImpl/src/TextureHelperOpenGL.cpp +++ b/TSE_OpenGlImpl/src/TextureHelperOpenGL.cpp @@ -1,165 +1,165 @@ -#include "GL/gl3w.h" -#include "GL/gl.h" -#include "TextureHelperOpenGL.hpp" - -void TSE::OpenGL::TextureHelperOpenGL::Bind(const Texture *tex) -{ - glBindTexture(GL_TEXTURE_2D, tex->GetTextureId()); -} - -void TSE::OpenGL::TextureHelperOpenGL::UnBind(const Texture *tex) -{ - glBindTexture(GL_TEXTURE_2D, 0); -} - -void TSE::OpenGL::TextureHelperOpenGL::Apply(Texture *tex) -{ - glBindTexture(GL_TEXTURE_2D, tex->GetTextureId()); - if(tex->Chanels() == 1) - { - if (tex->bpp() == 8) - glTexImage2D(GL_TEXTURE_2D, 0,GL_R8, tex->Width(), tex->Height(), 0, GL_RED, GL_UNSIGNED_BYTE, tex->GetImagePtr()); - if (tex->bpp() == 16) - glTexImage2D(GL_TEXTURE_2D, 0, GL_R16I, tex->Width(), tex->Height(), 0, GL_RED, GL_SHORT, tex->GetImagePtr()); - } - if(tex->Chanels() == 3) - { - if(tex->bpp() == 24) - glTexImage2D(GL_TEXTURE_2D, 0,GL_RGB, tex->Width(), tex->Height(), 0, GL_BGR, GL_UNSIGNED_BYTE, tex->GetImagePtr()); - } - else if(tex->Chanels() == 4) - { - if(tex->bpp() == 32) - glTexImage2D(GL_TEXTURE_2D, 0,GL_RGBA, tex->Width(), tex->Height(), 0, GL_BGRA, GL_UNSIGNED_BYTE, tex->GetImagePtr()); - if (tex->bpp() == 8) //need to decode it with bitwise operations in shader - glTexImage2D(GL_TEXTURE_2D, 0,GL_RGBA2, tex->Width(), tex->Height(), 0, GL_RED, GL_UNSIGNED_BYTE, tex->GetImagePtr()); - } - - glGenerateMipmap(GL_TEXTURE_2D); - - glBindTexture(GL_TEXTURE_2D, 0); -} - -void TSE::OpenGL::TextureHelperOpenGL::Regist(Texture *tex) -{ - uint TextureID; - - glGenTextures(1, &TextureID); - glBindTexture(GL_TEXTURE_2D, TextureID); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); - - tex->SetTextureId(TextureID); - - tex->Apply(); -} - -void TSE::OpenGL::TextureHelperOpenGL::PlatromDestroy(Texture *tex) -{ - uint id = tex->GetTextureId(); - glDeleteTextures(1, &id); -} - -void TSE::OpenGL::TextureHelperOpenGL::Bind3D(const VolumeTexture3D *tex) -{ - glBindTexture(GL_TEXTURE_3D, tex->GetTextureId()); -} - -void TSE::OpenGL::TextureHelperOpenGL::UnBind3D(const VolumeTexture3D *tex) -{ - glBindTexture(GL_TEXTURE_3D, 0); -} - -void TSE::OpenGL::TextureHelperOpenGL::Apply3D(VolumeTexture3D *tex) -{ - glBindTexture(GL_TEXTURE_3D, tex->GetTextureId()); - ushort internal,input,size; - - if(tex->Chanels() == 1) - { - if (tex->bpp() == 8) - { - internal = GL_R8; - input = GL_RED; - size = GL_UNSIGNED_BYTE; - } - if (tex->bpp() == 16) - { - internal = GL_R16I; - input = GL_RED; - size = GL_SHORT; - } - } - if(tex->Chanels() == 3) - { - if(tex->bpp() == 24) - { - internal = GL_RGB; - input = GL_BGR; - size = GL_UNSIGNED_BYTE; - } - } - else if(tex->Chanels() == 4) - { - if(tex->bpp() == 32) - { - internal = GL_RGBA; - input = GL_BGRA; - size = GL_UNSIGNED_BYTE; - } - if (tex->bpp() == 8) //need to decode it with bitwise operations in shader - { - internal = GL_RGBA2; - input = GL_RED; - size = GL_UNSIGNED_BYTE; - } - } - - glTexImage3D(GL_TEXTURE_3D, 0, internal, tex->Width(), tex->Height(), tex->Depth(), 0, input, size, nullptr); - - for (int z = 0; z < tex->Depth(); ++z) - { - glTexSubImage3D( - GL_TEXTURE_3D, - 0, - 0, - 0, - z, - tex->Width(), - tex->Height(), - 1, - input, - size, - tex->GetImagePtr(z) - ); - } - - glGenerateMipmap(GL_TEXTURE_3D); - - glBindTexture(GL_TEXTURE_3D, 0); -} - -void TSE::OpenGL::TextureHelperOpenGL::Regist3D(VolumeTexture3D *tex) -{ - uint TextureID; - - glGenTextures(1, &TextureID); - glBindTexture(GL_TEXTURE_3D, TextureID); - glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); - glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); - glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); - glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE); - - tex->SetTextureId(TextureID); - - tex->Apply(); -} - -void TSE::OpenGL::TextureHelperOpenGL::PlatromDestroy3D(VolumeTexture3D *tex) -{ - uint id = tex->GetTextureId(); - glDeleteTextures(1, &id); -} +#include "GL/gl3w.h" +#include "GL/gl.h" +#include "TextureHelperOpenGL.hpp" + +void TSE::OpenGL::TextureHelperOpenGL::Bind(const Texture *tex) +{ + glBindTexture(GL_TEXTURE_2D, tex->GetTextureId()); +} + +void TSE::OpenGL::TextureHelperOpenGL::UnBind(const Texture *tex) +{ + glBindTexture(GL_TEXTURE_2D, 0); +} + +void TSE::OpenGL::TextureHelperOpenGL::Apply(Texture *tex) +{ + glBindTexture(GL_TEXTURE_2D, tex->GetTextureId()); + if(tex->Chanels() == 1) + { + if (tex->bpp() == 8) + glTexImage2D(GL_TEXTURE_2D, 0,GL_R8, tex->Width(), tex->Height(), 0, GL_RED, GL_UNSIGNED_BYTE, tex->GetImagePtr()); + if (tex->bpp() == 16) + glTexImage2D(GL_TEXTURE_2D, 0, GL_R16I, tex->Width(), tex->Height(), 0, GL_RED, GL_SHORT, tex->GetImagePtr()); + } + if(tex->Chanels() == 3) + { + if(tex->bpp() == 24) + glTexImage2D(GL_TEXTURE_2D, 0,GL_RGB, tex->Width(), tex->Height(), 0, GL_BGR, GL_UNSIGNED_BYTE, tex->GetImagePtr()); + } + else if(tex->Chanels() == 4) + { + if(tex->bpp() == 32) + glTexImage2D(GL_TEXTURE_2D, 0,GL_RGBA, tex->Width(), tex->Height(), 0, GL_BGRA, GL_UNSIGNED_BYTE, tex->GetImagePtr()); + if (tex->bpp() == 8) //need to decode it with bitwise operations in shader + glTexImage2D(GL_TEXTURE_2D, 0,GL_RGBA2, tex->Width(), tex->Height(), 0, GL_RED, GL_UNSIGNED_BYTE, tex->GetImagePtr()); + } + + glGenerateMipmap(GL_TEXTURE_2D); + + glBindTexture(GL_TEXTURE_2D, 0); +} + +void TSE::OpenGL::TextureHelperOpenGL::Regist(Texture *tex) +{ + uint TextureID; + + glGenTextures(1, &TextureID); + glBindTexture(GL_TEXTURE_2D, TextureID); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + + tex->SetTextureId(TextureID); + + tex->Apply(); +} + +void TSE::OpenGL::TextureHelperOpenGL::PlatromDestroy(Texture *tex) +{ + uint id = tex->GetTextureId(); + glDeleteTextures(1, &id); +} + +void TSE::OpenGL::TextureHelperOpenGL::Bind3D(const VolumeTexture3D *tex) +{ + glBindTexture(GL_TEXTURE_3D, tex->GetTextureId()); +} + +void TSE::OpenGL::TextureHelperOpenGL::UnBind3D(const VolumeTexture3D *tex) +{ + glBindTexture(GL_TEXTURE_3D, 0); +} + +void TSE::OpenGL::TextureHelperOpenGL::Apply3D(VolumeTexture3D *tex) +{ + glBindTexture(GL_TEXTURE_3D, tex->GetTextureId()); + ushort internal,input,size; + + if(tex->Chanels() == 1) + { + if (tex->bpp() == 8) + { + internal = GL_R8; + input = GL_RED; + size = GL_UNSIGNED_BYTE; + } + if (tex->bpp() == 16) + { + internal = GL_R16I; + input = GL_RED; + size = GL_SHORT; + } + } + if(tex->Chanels() == 3) + { + if(tex->bpp() == 24) + { + internal = GL_RGB; + input = GL_BGR; + size = GL_UNSIGNED_BYTE; + } + } + else if(tex->Chanels() == 4) + { + if(tex->bpp() == 32) + { + internal = GL_R16; + input = GL_BGRA; + size = GL_UNSIGNED_BYTE; + } + if (tex->bpp() == 8) //need to decode it with bitwise operations in shader + { + internal = GL_RGBA2; + input = GL_RED; + size = GL_UNSIGNED_BYTE; + } + } + + glTexImage3D(GL_TEXTURE_3D, 0, internal, tex->Width(), tex->Height(), tex->Depth(), 0, input, size, nullptr); + + for (int z = 0; z < tex->Depth(); ++z) + { + glTexSubImage3D( + GL_TEXTURE_3D, + 0, + 0, + 0, + z, + tex->Width(), + tex->Height(), + 1, + input, + size, + tex->GetImagePtr(z) + ); + } + + //glGenerateMipmap(GL_TEXTURE_3D); + + glBindTexture(GL_TEXTURE_3D, 0); +} + +void TSE::OpenGL::TextureHelperOpenGL::Regist3D(VolumeTexture3D *tex) +{ + uint TextureID; + + glGenTextures(1, &TextureID); + glBindTexture(GL_TEXTURE_3D, TextureID); + glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE); + + tex->SetTextureId(TextureID); + + tex->Apply(); +} + +void TSE::OpenGL::TextureHelperOpenGL::PlatromDestroy3D(VolumeTexture3D *tex) +{ + uint id = tex->GetTextureId(); + glDeleteTextures(1, &id); +}