mirror of
https://github.com/love2d/love.git
synced 2026-08-15 15:51:12 +02:00
Added GLSL ES 1.00 (OpenGL ES 2) shader support.
--HG-- branch : minor
This commit is contained in:
@@ -87,6 +87,13 @@ public:
|
||||
SUPPORT_MAX_ENUM
|
||||
};
|
||||
|
||||
enum Renderer
|
||||
{
|
||||
RENDERER_OPENGL = 0,
|
||||
RENDERER_OPENGLES,
|
||||
RENDERER_MAX_ENUM
|
||||
};
|
||||
|
||||
enum SystemLimit
|
||||
{
|
||||
LIMIT_POINT_SIZE,
|
||||
|
||||
@@ -295,7 +295,10 @@ bool Graphics::setMode(int width, int height, bool &sRGB)
|
||||
|
||||
// We always need a default shader.
|
||||
if (!Shader::defaultShader)
|
||||
Shader::defaultShader = newShader(Shader::defaultCode[0]);
|
||||
{
|
||||
Renderer renderer = GLAD_ES_VERSION_2_0 ? RENDERER_OPENGLES : RENDERER_OPENGL;
|
||||
Shader::defaultShader = newShader(Shader::defaultCode[renderer]);
|
||||
}
|
||||
|
||||
if (!getShader())
|
||||
setShader(Shader::defaultShader);
|
||||
@@ -944,7 +947,7 @@ Graphics::LineJoin Graphics::getLineJoin() const
|
||||
|
||||
void Graphics::setPointSize(float size)
|
||||
{
|
||||
glPointSize(size);
|
||||
gl.setPointSize(size);
|
||||
states.back().pointSize = size;
|
||||
}
|
||||
|
||||
|
||||
@@ -97,6 +97,11 @@ void OpenGL::setupContext()
|
||||
glGetIntegerv(GL_SCISSOR_BOX, (GLint *) &state.scissor.x);
|
||||
state.scissor.y = state.viewport.h - (state.scissor.y + state.scissor.h);
|
||||
|
||||
if (GLAD_VERSION_1_0)
|
||||
glGetFloatv(GL_POINT_SIZE, &state.pointSize);
|
||||
else
|
||||
state.pointSize = 1.0f;
|
||||
|
||||
// Initialize multiple texture unit support for shaders.
|
||||
state.textureUnits.clear();
|
||||
|
||||
@@ -290,27 +295,41 @@ void OpenGL::prepareDraw()
|
||||
}
|
||||
}
|
||||
|
||||
const float *curproj = matrices.projection.back().getElements();
|
||||
const float *lastproj = state.lastProjectionMatrix.getElements();
|
||||
const Matrix &curproj = matrices.projection.back();
|
||||
const Matrix &curxform = matrices.transform.back();
|
||||
|
||||
// We only need to re-upload the projection matrix if it's changed.
|
||||
if (memcmp(curproj, lastproj, sizeof(float) * 16) != 0)
|
||||
if (GLAD_ES_VERSION_2_0 && shader)
|
||||
{
|
||||
glMatrixMode(GL_PROJECTION);
|
||||
glLoadMatrixf(curproj);
|
||||
glMatrixMode(GL_MODELVIEW);
|
||||
// Send built-in uniforms to the current shader.
|
||||
shader->sendBuiltinMatrix(Shader::BUILTIN_TRANSFORM_MATRIX, 4, curxform.getElements(), 1);
|
||||
shader->sendBuiltinMatrix(Shader::BUILTIN_PROJECTION_MATRIX, 4, curproj.getElements(), 1);
|
||||
|
||||
state.lastProjectionMatrix = matrices.projection.back();
|
||||
Matrix tp_matrix(curproj * curxform);
|
||||
shader->sendBuiltinMatrix(Shader::BUILTIN_TRANSFORM_PROJECTION_MATRIX, 4, tp_matrix.getElements(), 1);
|
||||
|
||||
shader->sendBuiltinFloat(Shader::BUILTIN_POINT_SIZE, 1, &state.pointSize, 1);
|
||||
}
|
||||
|
||||
const float *curxform = matrices.transform.back().getElements();
|
||||
const float *lastxform = state.lastTransformMatrix.getElements();
|
||||
|
||||
// Same with the transform matrix.
|
||||
if (memcmp(curxform, lastxform, sizeof(float) * 16) != 0)
|
||||
else if (GLAD_VERSION_1_0)
|
||||
{
|
||||
glLoadMatrixf(curxform);
|
||||
state.lastTransformMatrix = matrices.transform.back();
|
||||
const Matrix &lastproj = state.lastProjectionMatrix;
|
||||
const Matrix &lastxform = state.lastTransformMatrix;
|
||||
|
||||
// We only need to re-upload the projection matrix if it's changed.
|
||||
if (memcmp(curproj.getElements(), lastproj.getElements(), sizeof(float) * 16) != 0)
|
||||
{
|
||||
glMatrixMode(GL_PROJECTION);
|
||||
glLoadMatrixf(curproj.getElements());
|
||||
glMatrixMode(GL_MODELVIEW);
|
||||
|
||||
state.lastProjectionMatrix = matrices.projection.back();
|
||||
}
|
||||
|
||||
// Same with the transform matrix.
|
||||
if (memcmp(curxform.getElements(), lastxform.getElements(), sizeof(float) * 16) != 0)
|
||||
{
|
||||
glLoadMatrixf(curxform.getElements());
|
||||
state.lastTransformMatrix = matrices.transform.back();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -450,6 +469,19 @@ OpenGL::BlendState OpenGL::getBlendState() const
|
||||
return state.blend;
|
||||
}
|
||||
|
||||
void OpenGL::setPointSize(float size)
|
||||
{
|
||||
if (GLAD_VERSION_1_0)
|
||||
glPointSize(size);
|
||||
|
||||
state.pointSize = size;
|
||||
}
|
||||
|
||||
float OpenGL::getPointSize() const
|
||||
{
|
||||
return state.pointSize;
|
||||
}
|
||||
|
||||
GLuint OpenGL::getDefaultFBO() const
|
||||
{
|
||||
return state.defaultFBO;
|
||||
|
||||
@@ -247,6 +247,16 @@ public:
|
||||
**/
|
||||
BlendState getBlendState() const;
|
||||
|
||||
/**
|
||||
* Sets the global point size.
|
||||
**/
|
||||
void setPointSize(float size);
|
||||
|
||||
/**
|
||||
* Gets the global point size.
|
||||
**/
|
||||
float getPointSize() const;
|
||||
|
||||
/**
|
||||
* This will usually be 0 (system drawable), but some platforms require a
|
||||
* non-zero FBO for rendering.
|
||||
@@ -352,6 +362,8 @@ private:
|
||||
Viewport viewport;
|
||||
Viewport scissor;
|
||||
|
||||
float pointSize;
|
||||
|
||||
GLuint defaultFBO;
|
||||
GLuint defaultTexture;
|
||||
|
||||
|
||||
@@ -64,7 +64,7 @@ namespace
|
||||
Shader *Shader::current = nullptr;
|
||||
Shader *Shader::defaultShader = nullptr;
|
||||
|
||||
Shader::ShaderSource Shader::defaultCode[1]; // TODO: RENDERER_MAX_ENUM
|
||||
Shader::ShaderSource Shader::defaultCode[Graphics::RENDERER_MAX_ENUM];
|
||||
|
||||
GLint Shader::maxTexUnits = 0;
|
||||
std::vector<int> Shader::textureCounters;
|
||||
@@ -224,11 +224,13 @@ bool Shader::loadVolatile()
|
||||
|
||||
std::vector<GLuint> shaderids;
|
||||
|
||||
// The shader program must have both vertex and pixel shader stages.
|
||||
const ShaderSource &defaults = defaultCode[0];
|
||||
const ShaderSource *defaults = &defaultCode[Graphics::RENDERER_OPENGL];
|
||||
if (GLAD_ES_VERSION_2_0)
|
||||
defaults = &defaultCode[Graphics::RENDERER_OPENGLES];
|
||||
|
||||
const std::string &vertexcode = shaderSource.vertex.empty() ? defaults.vertex : shaderSource.vertex;
|
||||
const std::string &pixelcode = shaderSource.pixel.empty() ? defaults.pixel : shaderSource.pixel;
|
||||
// The shader program must have both vertex and pixel shader stages.
|
||||
const std::string &vertexcode = shaderSource.vertex.empty() ? defaults->vertex : shaderSource.vertex;
|
||||
const std::string &pixelcode = shaderSource.pixel.empty() ? defaults->pixel : shaderSource.pixel;
|
||||
|
||||
try
|
||||
{
|
||||
@@ -627,6 +629,33 @@ bool Shader::hasBuiltinUniform(BuiltinUniform builtin) const
|
||||
return builtinUniforms[int(builtin)] != -1;
|
||||
}
|
||||
|
||||
bool Shader::sendBuiltinMatrix(BuiltinUniform builtin, int size, const GLfloat *m, int count)
|
||||
{
|
||||
if (!hasBuiltinUniform(builtin))
|
||||
return false;
|
||||
|
||||
GLint location = builtinUniforms[GLint(builtin)];
|
||||
|
||||
TemporaryAttacher attacher(this);
|
||||
|
||||
switch (size)
|
||||
{
|
||||
case 2:
|
||||
glUniformMatrix2fv(location, count, GL_FALSE, m);
|
||||
break;
|
||||
case 3:
|
||||
glUniformMatrix3fv(location, count, GL_FALSE, m);
|
||||
break;
|
||||
case 4:
|
||||
glUniformMatrix4fv(location, count, GL_FALSE, m);
|
||||
break;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Shader::sendBuiltinFloat(BuiltinUniform builtin, int size, const GLfloat *vec, int count)
|
||||
{
|
||||
if (!hasBuiltinUniform(builtin))
|
||||
@@ -822,6 +851,10 @@ StringMap<VertexAttribID, ATTRIB_MAX_ENUM> Shader::attribNames(Shader::attribNam
|
||||
|
||||
StringMap<Shader::BuiltinUniform, Shader::BUILTIN_MAX_ENUM>::Entry Shader::builtinNameEntries[] =
|
||||
{
|
||||
{"TransformMatrix", Shader::BUILTIN_TRANSFORM_MATRIX},
|
||||
{"ProjectionMatrix", Shader::BUILTIN_PROJECTION_MATRIX},
|
||||
{"TransformProjectionMatrix", Shader::BUILTIN_TRANSFORM_PROJECTION_MATRIX},
|
||||
{"love_PointSize", Shader::BUILTIN_POINT_SIZE},
|
||||
{"love_ScreenSize", Shader::BUILTIN_SCREEN_SIZE},
|
||||
};
|
||||
|
||||
|
||||
@@ -24,6 +24,7 @@
|
||||
// LOVE
|
||||
#include "common/Object.h"
|
||||
#include "common/StringMap.h"
|
||||
#include "graphics/Graphics.h"
|
||||
#include "OpenGL.h"
|
||||
#include "Texture.h"
|
||||
|
||||
@@ -56,6 +57,10 @@ public:
|
||||
// Built-in uniform (extern) variables.
|
||||
enum BuiltinUniform
|
||||
{
|
||||
BUILTIN_TRANSFORM_MATRIX = 0,
|
||||
BUILTIN_PROJECTION_MATRIX,
|
||||
BUILTIN_TRANSFORM_PROJECTION_MATRIX,
|
||||
BUILTIN_POINT_SIZE,
|
||||
BUILTIN_SCREEN_SIZE,
|
||||
BUILTIN_MAX_ENUM
|
||||
};
|
||||
@@ -84,7 +89,7 @@ public:
|
||||
static Shader *defaultShader;
|
||||
|
||||
// Default shader code (a shader is always required internally.)
|
||||
static ShaderSource defaultCode[1]; // TODO: RENDERER_MAX_ENUM
|
||||
static ShaderSource defaultCode[Graphics::RENDERER_MAX_ENUM];
|
||||
|
||||
/**
|
||||
* Creates a new Shader using a list of source codes.
|
||||
@@ -173,6 +178,7 @@ public:
|
||||
**/
|
||||
bool hasVertexAttrib(VertexAttribID attrib) const;
|
||||
bool hasBuiltinUniform(BuiltinUniform builtin) const;
|
||||
bool sendBuiltinMatrix(BuiltinUniform builtin, int size, const GLfloat *m, int count);
|
||||
bool sendBuiltinFloat(BuiltinUniform builtin, int size, const GLfloat *m, int count);
|
||||
void checkSetScreenParams();
|
||||
|
||||
|
||||
@@ -971,7 +971,18 @@ int w_setDefaultShaderCode(lua_State *L)
|
||||
|
||||
lua_pop(L, 3);
|
||||
|
||||
Shader::defaultCode[0] = openglcode;
|
||||
lua_getfield(L, 1, "opengles");
|
||||
lua_rawgeti(L, -1, 1);
|
||||
lua_rawgeti(L, -2, 2);
|
||||
|
||||
Shader::ShaderSource openglescode;
|
||||
openglescode.vertex = luax_checkstring(L, -2);
|
||||
openglescode.pixel = luax_checkstring(L, -1);
|
||||
|
||||
lua_pop(L, 3);
|
||||
|
||||
Shader::defaultCode[Graphics::RENDERER_OPENGL] = openglcode;
|
||||
Shader::defaultCode[Graphics::RENDERER_OPENGLES] = openglescode;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user