mirror of
https://github.com/love2d/love.git
synced 2026-08-12 08:30:56 +02:00
Cleaned up some shader code.
--HG-- branch : minor
This commit is contained in:
@@ -389,7 +389,7 @@ void Canvas::setupGrab()
|
||||
|
||||
// bind the framebuffer object.
|
||||
gl.bindFramebuffer(GL_FRAMEBUFFER, fbo);
|
||||
gl.setViewport(OpenGL::Viewport(0, 0, width, height));
|
||||
gl.setViewport({0, 0, width, height});
|
||||
|
||||
// Set up the projection matrix
|
||||
gl.matrices.projection.push_back(Matrix::ortho(0.0, width, 0.0, height));
|
||||
|
||||
@@ -219,7 +219,7 @@ void Graphics::setViewportSize(int width, int height)
|
||||
setCanvas();
|
||||
|
||||
// Set the viewport to top-left corner.
|
||||
gl.setViewport(OpenGL::Viewport(0, 0, width, height));
|
||||
gl.setViewport({0, 0, width, height});
|
||||
|
||||
// If a canvas was bound before this function was called, it needs to be
|
||||
// made aware of the new system viewport size.
|
||||
@@ -512,7 +512,7 @@ bool Graphics::isCreated() const
|
||||
|
||||
void Graphics::setScissor(int x, int y, int width, int height)
|
||||
{
|
||||
OpenGL::Viewport box(x, y, width, height);
|
||||
OpenGL::Viewport box = {x, y, width, height};
|
||||
|
||||
states.back().scissor = true;
|
||||
glEnable(GL_SCISSOR_TEST);
|
||||
|
||||
@@ -52,8 +52,9 @@ OpenGL::OpenGL()
|
||||
, contextInitialized(false)
|
||||
, maxAnisotropy(1.0f)
|
||||
, maxTextureSize(0)
|
||||
, maxRenderTargets(0)
|
||||
, maxRenderTargets(1)
|
||||
, maxRenderbufferSamples(0)
|
||||
, maxTextureUnits(1)
|
||||
, vendor(VENDOR_UNKNOWN)
|
||||
, state()
|
||||
{
|
||||
@@ -83,6 +84,8 @@ void OpenGL::setupContext()
|
||||
if (!contextInitialized)
|
||||
return;
|
||||
|
||||
initMaxValues();
|
||||
|
||||
state.color = Color(255, 255, 255, 255);
|
||||
GLfloat glcolor[4] = {1.0f, 1.0f, 1.0f, 1.0f};
|
||||
glVertexAttrib4fv(ATTRIB_COLOR, glcolor);
|
||||
@@ -102,11 +105,7 @@ void OpenGL::setupContext()
|
||||
|
||||
// Initialize multiple texture unit support for shaders.
|
||||
state.boundTextures.clear();
|
||||
|
||||
GLint maxtextureunits;
|
||||
glGetIntegerv(GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS, &maxtextureunits);
|
||||
|
||||
state.boundTextures.resize(maxtextureunits, 0);
|
||||
state.boundTextures.resize(maxTextureUnits, 0);
|
||||
|
||||
GLenum curgltextureunit;
|
||||
glGetIntegerv(GL_ACTIVE_TEXTURE, (GLint *) &curgltextureunit);
|
||||
@@ -125,7 +124,6 @@ void OpenGL::setupContext()
|
||||
BlendState blend = {GL_ONE, GL_ONE, GL_ZERO, GL_ZERO, GL_FUNC_ADD};
|
||||
setBlendState(blend);
|
||||
|
||||
initMaxValues();
|
||||
createDefaultTexture();
|
||||
|
||||
// Invalidate the cached matrices by setting some elements to NaN.
|
||||
@@ -257,6 +255,8 @@ void OpenGL::initMaxValues()
|
||||
}
|
||||
else
|
||||
maxRenderbufferSamples = 0;
|
||||
|
||||
glGetIntegerv(GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS, &maxTextureUnits);
|
||||
}
|
||||
|
||||
void OpenGL::initMatrices()
|
||||
@@ -484,21 +484,29 @@ void OpenGL::bindTexture(GLuint texture)
|
||||
}
|
||||
}
|
||||
|
||||
void OpenGL::bindTextureToUnit(GLuint texture, int textureunit, bool restoreprev)
|
||||
void OpenGL::bindTextures(GLuint first, GLsizei count, const GLuint *textures)
|
||||
{
|
||||
if (textureunit < 0 || (size_t) textureunit >= state.boundTextures.size())
|
||||
throw love::Exception("Invalid texture unit index.");
|
||||
if (first + count > (GLuint) maxTextureUnits)
|
||||
return;
|
||||
|
||||
if (texture != state.boundTextures[textureunit])
|
||||
if (GLAD_VERSION_4_4 || GLAD_ARB_multi_bind)
|
||||
glBindTextures(first, count, textures);
|
||||
else
|
||||
{
|
||||
int oldtextureunit = state.curTextureUnit;
|
||||
setTextureUnit(textureunit);
|
||||
for (GLint i = 0; i < count; i++)
|
||||
{
|
||||
GLuint texture = textures != nullptr ? textures[i] : 0;
|
||||
|
||||
state.boundTextures[textureunit] = texture;
|
||||
glBindTexture(GL_TEXTURE_2D, texture);
|
||||
if (state.boundTextures[first + i] != texture)
|
||||
{
|
||||
glActiveTexture(GL_TEXTURE0 + first + i);
|
||||
glBindTexture(GL_TEXTURE_2D, texture);
|
||||
|
||||
if (restoreprev)
|
||||
setTextureUnit(oldtextureunit);
|
||||
state.boundTextures[first + i] = texture;
|
||||
}
|
||||
}
|
||||
|
||||
glActiveTexture(GL_TEXTURE0 + state.curTextureUnit);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -598,6 +606,11 @@ int OpenGL::getMaxRenderbufferSamples() const
|
||||
return maxRenderbufferSamples;
|
||||
}
|
||||
|
||||
int OpenGL::getMaxTextureUnits() const
|
||||
{
|
||||
return maxTextureUnits;
|
||||
}
|
||||
|
||||
void OpenGL::updateTextureMemorySize(size_t oldsize, size_t newsize)
|
||||
{
|
||||
int64 memsize = (int64) stats.textureMemory + ((int64 )newsize - (int64) oldsize);
|
||||
|
||||
@@ -55,7 +55,6 @@ enum VertexAttribID
|
||||
ATTRIB_POS = 0,
|
||||
ATTRIB_TEXCOORD,
|
||||
ATTRIB_COLOR,
|
||||
ATTRIB_PSEUDO_INSTANCE_ID, // Instance ID used with pseudo-instancing.
|
||||
ATTRIB_MAX_ENUM
|
||||
};
|
||||
|
||||
@@ -93,14 +92,6 @@ public:
|
||||
int x, y;
|
||||
int w, h;
|
||||
|
||||
Viewport()
|
||||
: x(0), y(0), w(0), h(0)
|
||||
{}
|
||||
|
||||
Viewport(int _x, int _y, int _w, int _h)
|
||||
: x(_x), y(_y), w(_w), h(_h)
|
||||
{}
|
||||
|
||||
bool operator == (const Viewport &rhs) const
|
||||
{
|
||||
return x == rhs.x && y == rhs.y && w == rhs.w && h == rhs.h;
|
||||
@@ -271,12 +262,10 @@ public:
|
||||
void bindTexture(GLuint texture);
|
||||
|
||||
/**
|
||||
* Helper for binding a texture to a specific texture unit.
|
||||
*
|
||||
* @param textureunit Index in the range of [0, maxtextureunits-1]
|
||||
* @param restoreprev Restore previously bound texture unit when done.
|
||||
* Binds multiple textures to texture units without changing the active
|
||||
* texture unit. Equivalent to glBindTextures.
|
||||
**/
|
||||
void bindTextureToUnit(GLuint texture, int textureunit, bool restoreprev);
|
||||
void bindTextures(GLuint first, GLsizei count, const GLuint *textures);
|
||||
|
||||
/**
|
||||
* Helper for deleting an OpenGL texture.
|
||||
@@ -311,6 +300,11 @@ public:
|
||||
**/
|
||||
int getMaxRenderbufferSamples() const;
|
||||
|
||||
/**
|
||||
* Returns the maximum number of accessible texture units.
|
||||
**/
|
||||
int getMaxTextureUnits() const;
|
||||
|
||||
void updateTextureMemorySize(size_t oldsize, size_t newsize);
|
||||
|
||||
/**
|
||||
@@ -337,6 +331,7 @@ private:
|
||||
int maxTextureSize;
|
||||
int maxRenderTargets;
|
||||
int maxRenderbufferSamples;
|
||||
int maxTextureUnits;
|
||||
|
||||
Vendor vendor;
|
||||
|
||||
|
||||
@@ -66,7 +66,6 @@ Shader *Shader::defaultShader = nullptr;
|
||||
|
||||
Shader::ShaderSource Shader::defaultCode[Graphics::RENDERER_MAX_ENUM];
|
||||
|
||||
GLint Shader::maxTexUnits = 0;
|
||||
std::vector<int> Shader::textureCounters;
|
||||
|
||||
Shader::Shader(const ShaderSource &source)
|
||||
@@ -80,16 +79,9 @@ Shader::Shader(const ShaderSource &source)
|
||||
if (source.vertex.empty() && source.pixel.empty())
|
||||
throw love::Exception("Cannot create shader: no source code!");
|
||||
|
||||
if (maxTexUnits <= 0)
|
||||
{
|
||||
GLint maxtexunits;
|
||||
glGetIntegerv(GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS, &maxtexunits);
|
||||
maxTexUnits = std::max(maxtexunits - 1, 0);
|
||||
}
|
||||
|
||||
// initialize global texture id counters if needed
|
||||
if (textureCounters.size() < (size_t) maxTexUnits)
|
||||
textureCounters.resize(maxTexUnits, 0);
|
||||
if ((int) textureCounters.size() < gl.getMaxTextureUnits())
|
||||
textureCounters.resize(gl.getMaxTextureUnits(), 0);
|
||||
|
||||
// load shader source and create program object
|
||||
loadVolatile();
|
||||
@@ -224,7 +216,7 @@ bool Shader::loadVolatile()
|
||||
|
||||
// zero out active texture list
|
||||
activeTexUnits.clear();
|
||||
activeTexUnits.insert(activeTexUnits.begin(), maxTexUnits, 0);
|
||||
activeTexUnits.insert(activeTexUnits.begin(), gl.getMaxTextureUnits(), 0);
|
||||
|
||||
std::vector<GLuint> shaderids;
|
||||
|
||||
@@ -263,16 +255,8 @@ bool Shader::loadVolatile()
|
||||
// Bind generic vertex attribute indices to names in the shader.
|
||||
for (int i = 0; i < int(ATTRIB_MAX_ENUM); i++)
|
||||
{
|
||||
VertexAttribID attrib = (VertexAttribID) i;
|
||||
|
||||
// FIXME: We skip this both because pseudo-instancing is temporarily
|
||||
// disabled (see graphics.lua), and because binding a non-existant
|
||||
// attribute name to a location causes a shader linker warning.
|
||||
if (attrib == ATTRIB_PSEUDO_INSTANCE_ID)
|
||||
continue;
|
||||
|
||||
const char *name = nullptr;
|
||||
if (attribNames.find(attrib, name))
|
||||
if (attribNames.find((VertexAttribID) i, name))
|
||||
glBindAttribLocation(program, i, (const GLchar *) name);
|
||||
}
|
||||
|
||||
@@ -336,7 +320,7 @@ void Shader::unloadVolatile()
|
||||
|
||||
// active texture list is probably invalid, clear it
|
||||
activeTexUnits.clear();
|
||||
activeTexUnits.resize(maxTexUnits, 0);
|
||||
activeTexUnits.resize(gl.getMaxTextureUnits(), 0);
|
||||
|
||||
// same with uniform location list
|
||||
uniforms.clear();
|
||||
@@ -398,14 +382,7 @@ void Shader::attach(bool temporary)
|
||||
{
|
||||
// make sure all sent textures are properly bound to their respective texture units
|
||||
// note: list potentially contains texture ids of deleted/invalid textures!
|
||||
for (size_t i = 0; i < activeTexUnits.size(); ++i)
|
||||
{
|
||||
if (activeTexUnits[i] > 0)
|
||||
gl.bindTextureToUnit(activeTexUnits[i], (int) i + 1, false);
|
||||
}
|
||||
|
||||
// We always want to use texture unit 0 for everyhing else.
|
||||
gl.setTextureUnit(0);
|
||||
gl.bindTextures(1, (GLsizei) activeTexUnits.size(), &activeTexUnits[0]);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -546,13 +523,10 @@ void Shader::sendTexture(const std::string &name, Texture *texture)
|
||||
checkSetUniformError(u, 1, 1, UNIFORM_SAMPLER);
|
||||
|
||||
// bind texture to assigned texture unit and send uniform to shader program
|
||||
gl.bindTextureToUnit(gltex, texunit, false);
|
||||
gl.bindTextures(texunit, 1, &gltex);
|
||||
|
||||
glUniform1i(u.location, texunit);
|
||||
|
||||
// reset texture unit
|
||||
gl.setTextureUnit(0);
|
||||
|
||||
// increment global shader texture id counter for this texture unit, if we haven't already
|
||||
if (activeTexUnits[texunit-1] == 0)
|
||||
++textureCounters[texunit-1];
|
||||
@@ -849,7 +823,6 @@ StringMap<VertexAttribID, ATTRIB_MAX_ENUM>::Entry Shader::attribNameEntries[] =
|
||||
{"VertexPosition", ATTRIB_POS},
|
||||
{"VertexTexCoord", ATTRIB_TEXCOORD},
|
||||
{"VertexColor", ATTRIB_COLOR},
|
||||
{"love_PseudoInstanceID", ATTRIB_PSEUDO_INSTANCE_ID},
|
||||
};
|
||||
|
||||
StringMap<VertexAttribID, ATTRIB_MAX_ENUM> Shader::attribNames(Shader::attribNameEntries, sizeof(Shader::attribNameEntries));
|
||||
|
||||
@@ -250,9 +250,6 @@ private:
|
||||
Canvas *lastCanvas;
|
||||
OpenGL::Viewport lastViewport;
|
||||
|
||||
// Max GPU texture units available for sent images
|
||||
static GLint maxTexUnits;
|
||||
|
||||
// Counts total number of textures bound to each texture unit in all shaders
|
||||
static std::vector<int> textureCounters;
|
||||
|
||||
|
||||
@@ -94,15 +94,9 @@ int w_Image_getData(lua_State *L)
|
||||
Image *i = luax_checkimage(L, 1);
|
||||
|
||||
if (i->isCompressed())
|
||||
{
|
||||
love::image::CompressedData *t = i->getCompressedData();
|
||||
luax_pushtype(L, IMAGE_COMPRESSED_DATA_ID, t);
|
||||
}
|
||||
luax_pushtype(L, IMAGE_COMPRESSED_DATA_ID, i->getCompressedData());
|
||||
else
|
||||
{
|
||||
love::image::ImageData *t = i->getImageData();
|
||||
luax_pushtype(L, IMAGE_IMAGE_DATA_ID, t);
|
||||
}
|
||||
luax_pushtype(L, IMAGE_IMAGE_DATA_ID, i->getImageData());
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -308,7 +308,7 @@ int w_Shader_send(lua_State *L)
|
||||
// Texture (Image or Canvas).
|
||||
p = (Proxy *) lua_touserdata(L, 3);
|
||||
|
||||
if (typeFlags[p->type][GRAPHICS_TEXT_ID])
|
||||
if (typeFlags[p->type][GRAPHICS_TEXTURE_ID])
|
||||
return w_Shader_sendTexture(L);
|
||||
|
||||
break;
|
||||
|
||||
Reference in New Issue
Block a user