#include "../../device/device.h"
#include "ogl4_context.h"
#include "ogl4_driver.h"

#include <cstddef>

static const GLuint ogl4_render_mode[] =
{
    GL_POINTS,
    GL_LINES,
    GL_LINE_LOOP,
    GL_TRIANGLES,
    GL_QUADS
};

namespace sleek
{
    namespace driver
    {
        ogl4_driver::ogl4_driver(std::shared_ptr<device::Device> dev, std::shared_ptr<context> c) noexcept
            : driver(dev, c)
        {


//              int workgroup_count[3];
//              int workgroup_size[3];
//              int workgroup_invocations;
//
//              glGetIntegeri_v(GL_MAX_COMPUTE_WORK_GROUP_COUNT, 0, &workgroup_count[0]);
//              glGetIntegeri_v(GL_MAX_COMPUTE_WORK_GROUP_COUNT, 1, &workgroup_count[1]);
//              glGetIntegeri_v(GL_MAX_COMPUTE_WORK_GROUP_COUNT, 2, &workgroup_count[2]);
//
//              printf ("Taille maximale des workgroups:\n\tx:%u\n\ty:%u\n\tz:%u\n",
//              workgroup_size[0], workgroup_size[1], workgroup_size[2]);
//
//              glGetIntegeri_v(GL_MAX_COMPUTE_WORK_GROUP_SIZE, 0, &workgroup_size[0]);
//              glGetIntegeri_v(GL_MAX_COMPUTE_WORK_GROUP_SIZE, 1, &workgroup_size[1]);
//              glGetIntegeri_v(GL_MAX_COMPUTE_WORK_GROUP_SIZE, 2, &workgroup_size[2]);
//
//              printf ("Nombre maximal d'invocation locale:\n\tx:%u\n\ty:%u\n\tz:%u\n",
//              workgroup_size[0], workgroup_size[1], workgroup_size[2]);
//
//              glGetIntegerv (GL_MAX_COMPUTE_WORK_GROUP_INVOCATIONS, &workgroup_invocations);
//              printf ("Nombre maximum d'invocation de workgroups:\n\t%u\n", workgroup_invocations);
//            quad  = glGenLists(1);
//            quadc = glGenLists(1);
//            cubec = glGenLists(1);
//
//            glNewList(quad , GL_COMPILE);
//                glBegin(GL_QUADS);
//                glQuad();
//                glEnd();
//            glEndList();
//
//            glNewList(quadc, GL_COMPILE);
//                glBegin(GL_QUADS);
//                glQuadCenter();
//                glEnd();
//            glEndList();
//
//            glNewList(quadc, GL_COMPILE);
//                glBegin(GL_QUADS);
//                glCubeCenter();
//                glEnd();
//            glEndList();
//
//            setActiveMaterial(mat);
        }

        ogl4_driver::~ogl4_driver() noexcept
        {
//            glDeleteLists(quad , 1);
//            glDeleteLists(quadc, 1);
//            glDeleteLists(cubec, 1);
        }

        void ogl4_driver::beginTo2D() const noexcept
        {
//            glMatrixMode(GL_PROJECTION);
//            glPushMatrix();
//            glLoadIdentity();
//            glOrtho(0, ctx->getViewport().x, ctx->getViewport().y, 0, -1.f, 1.f);
//            glMatrixMode(GL_MODELVIEW);
//            glPushMatrix();
//            glLoadIdentity();
//            glDisable(GL_DEPTH_TEST);
//            glDisable(GL_CULL_FACE);
        }

        void ogl4_driver::endFrom2D() const noexcept
        {
//            glEnable(GL_DEPTH_TEST);
//            glMatrixMode(GL_PROJECTION);
//            glPopMatrix();
//            glMatrixMode(GL_MODELVIEW);
//            glPopMatrix();
        }

        void ogl4_driver::ObjectRenderBegin() const noexcept
        {
//            glPushMatrix();
//            if(mat && mat->effect)
//                mat->effect->update();
//            glColor4ub(255,255,255,255);
        }

        void ogl4_driver::ObjectRenderEnd() const noexcept
        {
//            glPopMatrix();
        }

        void ogl4_driver::drawPixel(const math::vec2i pos, const math::pixel clr) const noexcept
        {
//            ObjectRenderBegin();
//                beginTo2D();
//                    glColor4ub(clr.red, clr.green, clr.blue, clr.alpha);
//                    glBegin(GL_POINTS);
//                        glVertex2f(pos.x, pos.y);
//                    glEnd();
//                endFrom2D();
//            ObjectRenderEnd();
        }

        void ogl4_driver::drawPixel(const math::vec3f pos, const math::pixel clr) const noexcept
        {
//            if(!src->ready()) return;
//            ObjectRenderBegin();
//                glColor4ub(clr.red, clr.green, clr.blue, clr.alpha);
//                glBegin(GL_POINTS);
//                    glVertex3f(pos.x, pos.y, pos.z);
//                glEnd();
//            ObjectRenderEnd();
        }

        void ogl4_driver::drawLine(const math::vec2i a, const math::vec2i b, const math::pixel clr) const noexcept
        {
//            if(!src->ready()) return;
//            ObjectRenderBegin();
//                beginTo2D();
//                    glBegin(GL_LINES);
//                        glColor4ub(clr.red, clr.green, clr.blue, clr.alpha);
//                        glVertex2f(a.x, a.y);
//                        glVertex2f(b.x, b.y);
//                    glEnd();
//                endFrom2D();
//            ObjectRenderEnd();
        }

        void ogl4_driver::drawLine(const math::vec3f a, const math::vec3f b, const math::pixel clr) const noexcept
        {
//            if(!src->ready()) return;
//            ObjectRenderBegin();
//                glBegin(GL_LINES);
//                    glColor4ub(clr.red, clr.green, clr.blue, clr.alpha);
//                    glVertex3f(a.x, a.y, a.z);
//                    glVertex3f(b.x, b.y, b.z);
//                glEnd();
//            ObjectRenderEnd();
        }

        void ogl4_driver::drawArc(const math::vec2i pos, u32 radius, u32 start, u32 end, const math::pixel clr) const noexcept
        {
//            if(!src->ready()) return;
//            f32 p = sqrt(radius*radius);
//            math::vec2i vdata[] = { math::vec2i(sin(start*DegToRad)*radius+pos.x, cos(start*DegToRad)*radius+pos.y), pos };
//            for(f32 i = start+p; i<end+p; i += p)
//            {
//                vdata[1] = math::vec2i(sin(i*DegToRad)*radius+pos.x, cos(i*DegToRad)*radius+pos.y);
//                drawLine(vdata[0], vdata[1], clr);
//                vdata[0] = vdata[1];
//            }
        }

        void ogl4_driver::drawCube(const math::aabbox2di c, const math::vec3f rot, const math::pixel upperleft, const math::pixel upperright, const math::pixel lowerleft, const math::pixel lowerright) const noexcept
        {
//            if(!src->ready()) return;
//            math::vec2i pos = c.getCenter();
//
//            ObjectRenderBegin();
//                beginTo2D();
//                    glTranslatef(pos.x,pos.y,0);
//                    glRotatef(rot.x,rot.y,rot.z);
//                    glScalef(c.getSize().x, c.getSize().y,1);
//
//                    glBegin(ogl4_render_mode[mat->getMode()]);
//                    glNormal3f(0,0,0);
//
//                    glColor4ub(lowerleft.red, lowerleft.green, lowerleft.blue, lowerleft.alpha);
//                    glTexCoord3i(0,0,0);
//                    glVertex3f(-0.5f, 0.5f,0);
//
//                    glColor4ub(upperleft.red, upperleft.green, upperleft.blue, upperleft.alpha);
//                    glTexCoord3i(0,1,0);
//                    glVertex3f(-0.5f,-0.5f,0);
//
//                    glColor4ub(upperright.red, upperright.green, upperright.blue, upperright.alpha);
//                    glTexCoord3i(1,1,0);
//                    glVertex3f( 0.5f,-0.5f,0);
//
//                    glColor4ub(lowerright.red, lowerright.green, lowerright.blue, lowerright.alpha);
//                    glTexCoord3i(1,0,0);
//                    glVertex3f( 0.5f, 0.5f,0);
//
//                    glEnd();
//                endFrom2D();
//            ObjectRenderEnd();
        }

        void ogl4_driver::drawCube(const math::aabbox2di c, const math::vec3f rot, const math::pixel clr) const noexcept
        {
//            if(!src->ready()) return;
//            math::vec2i pos = c.getCenter();
//
//            ObjectRenderBegin();
//                beginTo2D();
//                    glTranslatef(pos.x,pos.y,0);
//                    glRotatef(rot.x,rot.y,rot.z);
//                    glScalef(c.getSize().x, c.getSize().y,1);
//                    glBegin(ogl4_render_mode[mat->getMode()]);
//                        glColor4ub(clr.red, clr.green, clr.blue, clr.alpha);
//                        glQuadCenter();
//                    glEnd();
//                endFrom2D();
//            ObjectRenderEnd();
        }

        void ogl4_driver::drawCube(const math::aabbox3df c, const math::vec3f rot, const math::pixel clr) const noexcept
        {
//            if(!src->ready()) return;
//            math::vec3f pos = c.getCenter();
//
//            ObjectRenderBegin();
//                glTranslatef(pos.x,pos.y,pos.z);
//                glRotatef(rot.x,rot.y,rot.z);
//                glScalef(c.getSize().x, c.getSize().y, c.getSize().z);
//                glBegin(GL_QUADS);
//                    glColor4ub(clr.red, clr.green, clr.blue, clr.alpha);
//                    glCubeCenter();
//                glEnd();
//            ObjectRenderEnd();
        }

        void ogl4_driver::drawCube(const math::vec2i a, const math::vec2i b, const math::vec3f rot, const math::pixel clr) const noexcept
        {
            drawCube(math::aabbox2di(a,b), rot, clr);
        }

        void ogl4_driver::drawCube(const math::vec3f a, const math::vec3f b, const math::vec3f rot, const math::pixel clr) const noexcept
        {
            drawCube(math::aabbox3df(a,b), rot, clr);
        }

        void ogl4_driver::drawCircle(const math::vec2i pos, u32 radius, const math::pixel clr) const noexcept
        {
//            f32 p = sqrt(radius*radius);
//            math::vec2i start = math::vec2i(sin(0*DegToRad)*radius, cos(0*DegToRad)*radius);
//            for(register f32 i = 0; i<360; i += 12)
//            {
//                math::vec2i end = math::vec2i(sin(i*DegToRad)*radius, cos(i*DegToRad)*radius);
//                drawLine(start+pos, end+pos, clr);
//                start = end;
//            }
        }

        void ogl4_driver::drawPolygon(const math::vec2i a, const math::vec2i b, const math::vec2i c, const math::pixel clr) const noexcept
        {
            drawLine(a, b, clr);
            drawLine(b, c, clr);
            drawLine(c, a, clr);
        }

        void ogl4_driver::drawPolygon(const math::vec3f a, const math::vec3f b, const math::vec3f c, const math::pixel clr) const noexcept
        {
            drawLine(a, b, clr);
            drawLine(b, c, clr);
            drawLine(c, a, clr);
        }

        void ogl4_driver::drawPolygonList(const math::vec2i *a, u32 n, const math::vec2i pos, const math::vec3f rot, const math::pixel clr) const noexcept
        {
//            ObjectRenderBegin();
//                beginTo2D();
//                    glTranslatef(pos.x,pos.y,0);
//                    glRotatef(rot.x,rot.y,rot.z);
//                        glBegin(ogl4_render_mode[mat->getMode()]);
//                            glColor4ub(clr.red, clr.green, clr.blue, clr.alpha);
//                            for(u32 i = 0; i< n; ++i)
//                                glVertex2f(a[i].x,a[i].y);
//                        glEnd();
//                endFrom2D();
//            ObjectRenderEnd();
        }

        void ogl4_driver::drawPolygonList(const math::vec3f *a, u32 n, const math::vec3f pos, const math::vec3f rot, const math::pixel clr) const noexcept
        {
//            ObjectRenderBegin();
//                glTranslatef(pos.x,pos.y,pos.z);
//                glRotatef(rot.x,rot.y,rot.z);
//                glBegin(ogl4_render_mode[mat->getMode()]);
//                    glColor4ub(clr.red, clr.green, clr.blue, clr.alpha);
//                    for(u32 i = 0; i< n; ++i)
//                        glVertex3f(a[i].x,a[i].y, a[i].z);
//                glEnd();
//            ObjectRenderEnd();
        }

        void ogl4_driver::drawFBO(fbo *tex) const noexcept
        {
//            ObjectRenderBegin();
//                beginTo2D();
//                    glEnable(GL_TEXTURE_2D);
//                    glActiveTexture(GL_TEXTURE0_ARB);
//                    tex->bind();
//                    glColor4ub(255,255,255,255);
//                    glTranslatef(0,0,0);
//                    glScalef(tex->getSize().x,tex->getSize().y,1);
//                    glCallList(quad);
//                    glDisable(GL_TEXTURE_2D);
//                endFrom2D();
//            ObjectRenderEnd();
        }

        void ogl4_driver::drawTexture(texture *tex, const math::vec2i pos, const math::vec3f rot, const math::vec2f uv) const noexcept
        {
//            ObjectRenderBegin();
//                beginTo2D();
//                    glEnable(GL_TEXTURE_2D);
//                    glActiveTexture(GL_TEXTURE0_ARB);
//                    tex->getIdentifier()->bind();
//                    glColor4ub(255,255,255,255);
//                    glTranslatef(pos.x,pos.y,0);
//                    glRotatef(rot.x,rot.y,rot.z);
//                    glScalef(tex->getOriginalSize().x,tex->getOriginalSize().y,1);
//                    glBegin(GL_QUADS);
//                        glNormal3f(0,0,0);
//                        glTexCoord3f(0,0,0);        glVertex3f(0,0,0);
//                        glTexCoord3f(uv.x,0,0);     glVertex3f(1,0,0);
//                        glTexCoord3f(uv.x,uv.y,0);  glVertex3f(1,1,0);
//                        glTexCoord3f(0,uv.y,0);     glVertex3f(0,1,0);
//                    glEnd();
//                    tex->getIdentifier()->unbind();
//                endFrom2D();
//            ObjectRenderEnd();
        }

        void ogl4_driver::drawTexture(texture *tex, const math::vec3f pos, const math::vec3f rot, const math::vec2f uv) const noexcept
        {
//            ObjectRenderBegin();
//                glEnable(GL_TEXTURE_2D);
//                glActiveTexture(GL_TEXTURE0_ARB);
//                tex->getIdentifier()->bind();
//                glColor4ub(255,255,255,255);
//                glTranslatef(pos.x,pos.y,pos.z);
//                glRotatef(rot.x,rot.y,rot.z);
//                glScalef(tex->getOriginalSize().x,tex->getOriginalSize().y,1);
//                glBegin(GL_QUADS);
//                    glNormal3f(0,0,0);
//                    glTexCoord3f(0,uv.y,0);     glVertex3f(-0.5f,-0.5f,0);
//                    glTexCoord3f(uv.x,uv.y,0);  glVertex3f( 0.5f,-0.5f,0);
//                    glTexCoord3f(uv.x,0,0);     glVertex3f( 0.5f, 0.5f,0);
//                    glTexCoord3f(0,0,0);        glVertex3f(-0.5f, 0.5f,0);
//                glEnd();
//                tex->getIdentifier()->unbind();
//            ObjectRenderEnd();
        }

        void ogl4_driver::drawTextureScale(texture *tex, const math::vec2i pos, const math::vec3f rot, const math::vec3f scl, const math::vec2f uv) const noexcept
        {
//            ObjectRenderBegin();
//                beginTo2D();
//                    glEnable(GL_TEXTURE_2D);
//                    glActiveTexture(GL_TEXTURE0_ARB);
//                    tex->getIdentifier()->bind();
//                    glColor4ub(255,255,255,255);
//                    glTranslatef(pos.x,pos.y,0);
//                    glRotatef(rot.x,rot.y,rot.z);
//                    glScalef(scl.x,scl.y,scl.z);
//                    glBegin(GL_QUADS);
//                        glNormal3f(0,0,0);
//                        glTexCoord3f(0,0,0);        glVertex3f(0,0,0);
//                        glTexCoord3f(uv.x,0,0);     glVertex3f(1,0,0);
//                        glTexCoord3f(uv.x,uv.y,0);  glVertex3f(1,1,0);
//                        glTexCoord3f(0,uv.y,0);     glVertex3f(0,1,0);
//                    glEnd();
//                    tex->getIdentifier()->unbind();
//                endFrom2D();
//            ObjectRenderEnd();
        }

        void ogl4_driver::drawTextureScale(texture *tex, const math::vec3f pos, const math::vec3f rot, const math::vec3f scl, const math::vec2f uv) const noexcept
        {
//            ObjectRenderBegin();
//                glEnable(GL_TEXTURE_2D);
//                glActiveTexture(GL_TEXTURE0_ARB);
//                tex->getIdentifier()->bind();
//                glColor4ub(255,255,255,255);
//                glTranslatef(pos.x,pos.y,pos.z);
//                glRotatef(rot.x,rot.y,rot.z);
//                glScalef(scl.x,scl.y,scl.z);
//                glBegin(GL_QUADS);
//                    glNormal3f(0,0,0);
//                    glTexCoord3f(0,uv.y,0);     glVertex3f(-0.5f,-0.5f,0);
//                    glTexCoord3f(uv.x,uv.y,0);  glVertex3f( 0.5f,-0.5f,0);
//                    glTexCoord3f(uv.x,0,0);     glVertex3f( 0.5f, 0.5f,0);
//                    glTexCoord3f(0,0,0);        glVertex3f(-0.5f, 0.5f,0);
//                glEnd();
//                tex->getIdentifier()->unbind();
//            ObjectRenderEnd();
        }

        void ogl4_driver::drawTextureCenter(texture *tex, const math::vec2i pos, const math::vec3f rot, const math::vec2f uv) const noexcept
        {
//            ObjectRenderBegin();
//                beginTo2D();
//                    glEnable(GL_TEXTURE_2D);
//                    glActiveTexture(GL_TEXTURE0_ARB);
//                    tex->getIdentifier()->bind();
//                    glColor4ub(255,255,255,255);
//                    glTranslatef(pos.x,pos.y,0);
//                    glRotatef(rot.x,rot.y,rot.z);
//                    glScalef(tex->getOriginalSize().x,tex->getOriginalSize().y,1);
//                    glBegin(GL_QUADS);
//                        glNormal3f(0,0,0);
//                        glTexCoord3f(0,uv.y,0);     glVertex3f(-0.5f,-0.5f,0);
//                        glTexCoord3f(uv.x,uv.y,0);  glVertex3f( 0.5f,-0.5f,0);
//                        glTexCoord3f(uv.x,0,0);     glVertex3f( 0.5f, 0.5f,0);
//                        glTexCoord3f(0,0,0);        glVertex3f(-0.5f, 0.5f,0);
//                    glEnd();
//                    tex->getIdentifier()->unbind();
//                endFrom2D();
//            ObjectRenderEnd();
        }

        void ogl4_driver::drawTextureCenter(texture *tex, const math::vec3f pos, const math::vec3f rot, const math::vec2f uv) const noexcept
        {
//            ObjectRenderBegin();
//                glEnable(GL_TEXTURE_2D);
//                glActiveTexture(GL_TEXTURE0_ARB);
//                tex->getIdentifier()->bind();
//                glColor4ub(255,255,255,255);
//                glTranslatef(pos.x,pos.y,pos.z);
//                glRotatef(rot.x,rot.y,rot.z);
//                glScalef(tex->getOriginalSize().x,tex->getOriginalSize().y,1);
//                glBegin(GL_QUADS);
//                    glNormal3f(0,0,1);
//                    glTexCoord3f(0,uv.y,0);     glVertex3f(-0.5f,-0.5f,0);
//                    glTexCoord3f(uv.x,uv.y,0);  glVertex3f( 0.5f,-0.5f,0);
//                    glTexCoord3f(uv.x,0,0);     glVertex3f( 0.5f, 0.5f,0);
//                    glTexCoord3f(0,0,0);        glVertex3f(-0.5f, 0.5f,0);
//                glEnd();
//                glDisable(GL_TEXTURE_2D);
//            ObjectRenderEnd();
        }

        void ogl4_driver::drawMesh(MeshBuffer *m, const math::vec3f pos, const math::vec3f rot) const noexcept
        {
//            ObjectRenderBegin();
//                glColor4ub(255,255,255,255);
//                glTranslatef(pos.x,pos.y,pos.z);
//                glRotatef(rot.x,rot.y,rot.z);
//                glScalef(mat->getScale().x,mat->getScale().y,mat->getScale().z);
//
//                glEnableClientState(GL_NORMAL_ARRAY);
//                glEnableClientState(GL_VERTEX_ARRAY);
//                glEnableClientState(GL_COLOR_ARRAY);
//                glEnableClientState(GL_INDEX_ARRAY);
//                glEnableClientState(GL_TEXTURE_COORD_ARRAY);
//
//                ///////////////////////////////////////
//
//                local_bind indices(m->getIdentifier(VBO_INDEX_BUFFER));
//                local_bind vertices(m->getIdentifier(VBO_VERTEX_BUFFER));
//
//                void *iptr = indices.ifNotBind(m->indices.data());
//                void *vptr = vertices.ifNotBind(m->vertices.data());
//
//                glVertexPointer(3, GL_FLOAT, sizeof(vertex), vptr + offsetof(vertex, Pos));
//                glNormalPointer(GL_FLOAT, sizeof(vertex), vptr + offsetof(vertex, Normal));
//                glColorPointer(4, GL_UNSIGNED_BYTE, sizeof(vertex), vptr + offsetof(vertex, Color));
//                glTexCoordPointer(2, GL_FLOAT, sizeof(vertex), vptr + offsetof(vertex, Coord));
//
//                glDrawElements(ogl4_render_mode[mat->getMode()], m->indices.size()*3, GL_UNSIGNED_INT, iptr);
//
//                ///////////////////////////////////////
//
//                glDisableClientState(GL_COLOR_ARRAY);
//                glDisableClientState(GL_INDEX_ARRAY);
//                glDisableClientState(GL_NORMAL_ARRAY);
//                glDisableClientState(GL_VERTEX_ARRAY);
//                glDisableClientState(GL_TEXTURE_COORD_ARRAY);
//            ObjectRenderEnd();
        }

        void ogl4_driver::setActiveMaterial(std::shared_ptr<material> i) noexcept
        {
            ctx->testError(__LINE__, __FILE__);
            static void(*_glState[2])(GLenum) = {&glDisable, &glEnable};

//            if(mat)
//            {
//                if(mat->effect)
//                    mat->effect->unbind();
//                else
//                {
//                    int start = i ? i->Texture.size() : 0;
//                    for(int stage = start; stage<mat->Texture.size(); ++stage)
//                    {
//                        glActiveTexture(GL_TEXTURE0_ARB+stage);
//                        if(mat->Texture[stage])
//                            mat->Texture[stage]->unbind();
//                    }
//                }
//            }
//
//            _glState[bool(i.get())](GL_BLEND);
//            ctx->testError(__LINE__, __FILE__);
//
//            if(i)
//            {
//                _glState[bool(i->ant & ral_polygone)](GL_POLYGON_SMOOTH);
//                _glState[bool(i->ant & ral_line)](GL_LINE_SMOOTH);
//                _glState[bool(i->mat & rmt_solid)](GL_DEPTH_TEST);
//                _glState[bool(i->mat & rmt_lighting)](GL_LIGHTING);
//                _glState[bool(i->mat & rmt_fog)](GL_FOG);
//                _glState[bool(i->fac != rfc_off)](GL_CULL_FACE);
//
//                glShadeModel(i->shd & rsd_flat ? GL_FLAT : GL_SMOOTH);
//
//                if(!mat || mat->psize != i->psize)
//                {
//                    // deprecated & performance cost
//                    glPointSize(i->psize);
//                    glLineWidth(i->psize);
//                }
//
//                /////////////////////////////////////////
//
//                static const GLenum _wire[] = {
//                    GL_FILL, GL_LINE
//                };
//
//                static const GLenum _cull[] = {
//                    0, GL_BACK,
//                    GL_FRONT, 0,
//                    GL_FRONT_AND_BACK
//                };
//
//                //if(!mat || mat->wire != i->wire)
//                //    glPolygonMode(_cull[i->fac], _wire[i->wire]);
//
//                if(i->fac != rfc_off && (!mat || mat->fac != i->fac))
//                    glCullFace(_cull[i->fac]);
//
//                /////////////////////////////////////////
//
////                if(!mat || mat->mat != i->mat)
////                {
////                    if(i->mat == rmt_solid)
////                         glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
////                    else if(i->mat == rmt_add)
////                         glBlendFunc(GL_ONE, GL_ONE);
////                    else if(i->mat == rmt_sub)
////                         glBlendFunc(GL_ONE_MINUS_SRC_COLOR, GL_ZERO);
////                    else
////                         glBlendFunc(GL_ONE, GL_ZERO);
////                }
//
//                /////////////////////////////////////////
//
//                ctx->testError(__LINE__, __FILE__);
//
//                if(i->effect)
//                    i->effect->bind();
//                else
//                {
//                    int stage = 0;
//                    if(mat)
//                    {
//                        int end = std::min(mat->Texture.size(), i->Texture.size());
//                        for(; stage<end; ++stage)
//                        {
//                            if(i->Texture[stage] == mat->Texture[stage])
//                                continue;
//
//                            glActiveTextureARB(GL_TEXTURE0_ARB+stage);
//
//                            if(i->Texture[stage])
//                                i->Texture[stage]->bind();
//
//                            glTexEnvf(GL_TEXTURE_ENV, GL_COMBINE_RGB_EXT, GL_ADD);
//                        }
//                    }
//                    for(; stage<i->Texture.size(); ++stage)
//                    {
//                        glActiveTextureARB(GL_TEXTURE0_ARB+stage);
//
//                        if(i->Texture[stage])
//                            i->Texture[stage]->bind();
//
//                        glTexEnvf(GL_TEXTURE_ENV, GL_COMBINE_RGB_EXT, GL_ADD);
//                    }
//                }
//            }
//
//            ctx->testError(__LINE__, __FILE__);
            mat = i;
        }

        std::shared_ptr<material> ogl4_driver::getActiveMaterial() const noexcept
        {
            return mat;
        }
    }
}