mkxp-z/src/glstate.cpp
Jonas Kulla 6c481e5eb8 Eliminate GLEW dependency
GL entrypoint resolution is now done manually. This has a couple
immediate benefits, such as not having to retrieve hundreds of
functions pointers that we'll never use. It's also nice to have
an exact overview of all the entrypoints used by mkxp.

This change allows mkxp to run fine with core contexts, not sure
how relevant that is going to be in the future.

What's noteworthy is that  _all_ entrypoints, even the ones core
in 1.1 and guaranteed to be in every libGL, are resolved
dynamically.
This has the added benefit of not having to link directly against
libGL anymore, which also cleans up the output of `ldd` quite
a bit (SDL2 loads most system deps dynamically at runtime).

GL headers are still required at build time.
2014-06-13 18:46:45 +02:00

113 lines
2.7 KiB
C++

/*
** glstate.cpp
**
** This file is part of mkxp.
**
** Copyright (C) 2013 Jonas Kulla <Nyocurio@gmail.com>
**
** mkxp is free software: you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published by
** the Free Software Foundation, either version 2 of the License, or
** (at your option) any later version.
**
** mkxp is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
** GNU General Public License for more details.
**
** You should have received a copy of the GNU General Public License
** along with mkxp. If not, see <http://www.gnu.org/licenses/>.
*/
#include "glstate.h"
#include "shader.h"
#include "etc.h"
#include "gl-fun.h"
#include <SDL_rect.h>
void GLClearColor::apply(const Vec4 &value)
{
gl.ClearColor(value.x, value.y, value.z, value.w);
}
void GLScissorBox::apply(const IntRect &value)
{
gl.Scissor(value.x, value.y, value.w, value.h);
}
void GLScissorBox::setIntersect(const IntRect &value)
{
IntRect &current = get();
SDL_Rect r1 = { current.x, current.y, current.w, current.h };
SDL_Rect r2 = { value.x, value.y, value.w, value.h };
SDL_Rect result;
if (!SDL_IntersectRect(&r1, &r2, &result))
result.w = result.h = 0;
set(IntRect(result.x, result.y, result.w, result.h));
}
void GLScissorTest::apply(const bool &value)
{
value ? gl.Enable(GL_SCISSOR_TEST) : gl.Disable(GL_SCISSOR_TEST);
}
void GLBlendMode::apply(const BlendType &value)
{
switch (value)
{
case BlendNone :
gl.BlendEquation(GL_FUNC_ADD);
gl.BlendFunc(GL_ONE, GL_ZERO);
break;
case BlendNormal :
gl.BlendEquation(GL_FUNC_ADD);
gl.BlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA,
GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
break;
case BlendAddition :
gl.BlendEquation(GL_FUNC_ADD);
gl.BlendFuncSeparate(GL_SRC_ALPHA, GL_ONE,
GL_ONE, GL_ONE);
break;
case BlendSubstraction :
// FIXME Alpha calculation is untested
gl.BlendEquation(GL_FUNC_REVERSE_SUBTRACT);
gl.BlendFuncSeparate(GL_SRC_ALPHA, GL_ONE,
GL_ONE, GL_ONE);
break;
}
}
void GLViewport::apply(const IntRect &value)
{
gl.Viewport(value.x, value.y, value.w, value.h);
}
void GLProgram::apply(const unsigned int &value)
{
gl.UseProgram(value);
}
GLState::Caps::Caps()
{
gl.GetIntegerv(GL_MAX_TEXTURE_SIZE, &maxTexSize);
}
GLState::GLState()
{
gl.Enable(GL_BLEND);
gl.Disable(GL_DEPTH_TEST);
clearColor.init(Vec4(0, 0, 0, 1));
blendMode.init(BlendNormal);
scissorTest.init(false);
scissorBox.init(IntRect(0, 0, 640, 480));
program.init(0);
}