#include "GL/gl3w.h" #include "GL/gl.h" #include "basicTextureShader.hpp" #include "basicTextureShaderGLSL.hpp" #include "BehaviourScripts/Renderable.hpp" #include "Color.hpp" #include "interfaces/ITexture.hpp" #define SHADER_VERTEX_INDEX 0 #define SHADER_COLOR_INDEX 1 #define SHADER_UV_INDEX 2 #define SHADER_TID_INDEX 3 #define SHADER_PACKAGE_SIZE (sizeof(float) * (3 + 4 + 2 + 1)) TSE::OpenGL::BasicTextureShader* TSE::OpenGL::BasicTextureShader::instance = nullptr; std::map TSE::OpenGL::BasicTextureShader::textureSlots; TSE::OpenGL::BasicTextureShader *TSE::OpenGL::BasicTextureShader::Instance() { return instance; } void TSE::OpenGL::BasicTextureShader::Destroy() { if(instance != nullptr) delete instance; instance = nullptr; } void TSE::OpenGL::BasicTextureShader::Init(float width, float height) { std::vector> parts; parts.push_back(ShaderPart::LoadFromString(vertT, GL_VERTEX_SHADER)); parts.push_back(ShaderPart::LoadFromString(fragT, GL_FRAGMENT_SHADER)); instance = new BasicTextureShader(std::move(parts)); instance->Enable(); int texIDs[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32 }; instance->SetUniform("textures", &texIDs[0], 33); instance->Disable(); } TSE::OpenGL::BasicTextureShader::BasicTextureShader(std::vector> &&parts) : Shader(parts) { PackageSize = SHADER_PACKAGE_SIZE; } void TSE::OpenGL::BasicTextureShader::OnEnable() const { glEnableVertexAttribArray(SHADER_VERTEX_INDEX); glVertexAttribPointer(SHADER_VERTEX_INDEX, 3, GL_FLOAT, false, SHADER_PACKAGE_SIZE, (void*)0); glEnableVertexAttribArray(SHADER_COLOR_INDEX); glVertexAttribPointer(SHADER_COLOR_INDEX, 4, GL_FLOAT, false, SHADER_PACKAGE_SIZE, (void*)(sizeof(float) * 3)); glEnableVertexAttribArray(SHADER_UV_INDEX); glVertexAttribPointer(SHADER_UV_INDEX, 2, GL_FLOAT, false, SHADER_PACKAGE_SIZE, (void*)(sizeof(float) * 7)); glEnableVertexAttribArray(SHADER_TID_INDEX); glVertexAttribPointer(SHADER_TID_INDEX, 1, GL_FLOAT, false, SHADER_PACKAGE_SIZE, (void*)(sizeof(float) * 9)); } void TSE::OpenGL::BasicTextureShader::OnDisable() const { glDisableVertexAttribArray(SHADER_VERTEX_INDEX); glDisableVertexAttribArray(SHADER_COLOR_INDEX); glDisableVertexAttribArray(SHADER_UV_INDEX); glDisableVertexAttribArray(SHADER_TID_INDEX); } void TSE::OpenGL::BasicTextureShader::OnFlush() { auto it = textureSlots.begin(); for (int i = 0; i < textureSlots.size(); i++, it++) { glActiveTexture(GL_TEXTURE0 + i); glBindTexture(GL_TEXTURE_2D, it->first); } } void TSE::OpenGL::BasicTextureShader::OnDrawCall(int indexCount) { glDrawElements(GL_TRIANGLES, indexCount, GL_UNSIGNED_SHORT, NULL); } void TSE::OpenGL::BasicTextureShader::OnSubmit(const Transformable &t, float *&target, TransformationStack &stack, void (*restartDrawcall)(IRenderer &), IRenderer &rnd) { auto* r = dynamic_cast(t.GetBehaviourScript(RENDERABLE)); if (!r) return; if(!r->GetMaterial()->HasValue("mainTex")) return; const ITexture* tex = r->GetMaterial()->GetValue("mainTex"); float ts = 0; auto it = textureSlots.find(tex->GetTextureId()); if (it != textureSlots.end()) { ts = it->second; } else { if(textureSlots.size() == 32) { restartDrawcall(rnd); textureSlots.clear(); } textureSlots[tex->GetTextureId()] = textureSlots.size(); ts = textureSlots[tex->GetTextureId()]; } const Vector3* verts = r->GetVertices(); const Vector2* uvs = r->GetUVs(); ushort vCount = r->GetVertexCount(); const Color color = r->GetMaterial()->GetValue("mainColor"); Matrix4x4 matr = t.GetLocalMatrix(); stack.Push(matr); const Matrix4x4& top = stack.Top(); //Todo transformable.lastmatrix hier ergänzen for (ushort i = 0; i < vCount; i++) { Vector3 p = top * verts[i]; Vector2 uv = uvs[i]; *target++ = p.x; *target++ = p.y; *target++ = p.z; *target++ = color.r; *target++ = color.g; *target++ = color.b; *target++ = color.a; *target++ = uv.x; *target++ = uv.y; *target++ = ts; } stack.Pop(); }