mirror of
https://github.com/love2d/love.git
synced 2026-08-16 00:02:12 +02:00
Merge branch '12.0-development' into metal
This commit is contained in:
@@ -107,6 +107,7 @@ love::graphics::Graphics *createInstance()
|
||||
Graphics::Graphics()
|
||||
: windowHasStencil(false)
|
||||
, mainVAO(0)
|
||||
, defaultBuffers()
|
||||
, supportedFormats()
|
||||
{
|
||||
gl = OpenGL();
|
||||
@@ -162,9 +163,9 @@ love::graphics::Shader *Graphics::newShaderInternal(love::graphics::ShaderStage
|
||||
return new Shader(vertex, pixel);
|
||||
}
|
||||
|
||||
love::graphics::Buffer *Graphics::newBuffer(size_t size, const void *data, BufferType type, vertex::Usage usage, uint32 mapflags)
|
||||
love::graphics::Buffer *Graphics::newBuffer(const Buffer::Settings &settings, const std::vector<Buffer::DataDeclaration> &format, const void *data, size_t size, size_t arraylength)
|
||||
{
|
||||
return new Buffer(size, data, type, usage, mapflags);
|
||||
return new Buffer(this, settings, format, data, size, arraylength);
|
||||
}
|
||||
|
||||
void Graphics::setViewportSize(int width, int height, int pixelwidth, int pixelheight)
|
||||
@@ -255,11 +256,32 @@ bool Graphics::setMode(void *context, int width, int height, int pixelwidth, int
|
||||
{
|
||||
// Initial sizes that should be good enough for most cases. It will
|
||||
// resize to fit if needed, later.
|
||||
batchedDrawState.vb[0] = CreateStreamBuffer(BUFFER_VERTEX, 1024 * 1024 * 1);
|
||||
batchedDrawState.vb[1] = CreateStreamBuffer(BUFFER_VERTEX, 256 * 1024 * 1);
|
||||
batchedDrawState.indexBuffer = CreateStreamBuffer(BUFFER_INDEX, sizeof(uint16) * LOVE_UINT16_MAX);
|
||||
batchedDrawState.vb[0] = CreateStreamBuffer(BUFFERTYPE_VERTEX, 1024 * 1024 * 1);
|
||||
batchedDrawState.vb[1] = CreateStreamBuffer(BUFFERTYPE_VERTEX, 256 * 1024 * 1);
|
||||
batchedDrawState.indexBuffer = CreateStreamBuffer(BUFFERTYPE_INDEX, sizeof(uint16) * LOVE_UINT16_MAX);
|
||||
}
|
||||
|
||||
if (capabilities.features[FEATURE_TEXEL_BUFFER] && defaultBuffers[BUFFERTYPE_TEXEL].get() == nullptr)
|
||||
{
|
||||
Buffer::Settings settings(Buffer::TYPEFLAG_TEXEL, 0, BUFFERUSAGE_STATIC);
|
||||
std::vector<Buffer::DataDeclaration> format = {{"", DATAFORMAT_FLOAT_VEC4, 0}};
|
||||
|
||||
const float texel[] = {0.0f, 0.0f, 0.0f, 1.0f};
|
||||
|
||||
love::graphics::Buffer *buffer = newBuffer(settings, format, texel, sizeof(texel), 1);
|
||||
defaultBuffers[BUFFERTYPE_TEXEL].set(buffer, Acquire::NORETAIN);
|
||||
}
|
||||
|
||||
// Load default resources before other Volatile.
|
||||
for (int i = 0; i < BUFFERTYPE_MAX_ENUM; i++)
|
||||
{
|
||||
if (defaultBuffers[i].get())
|
||||
((Buffer *) defaultBuffers[i].get())->loadVolatile();
|
||||
}
|
||||
|
||||
if (defaultBuffers[BUFFERTYPE_TEXEL].get())
|
||||
gl.setDefaultTexelBuffer((GLuint) defaultBuffers[BUFFERTYPE_TEXEL]->getTexelBufferHandle());
|
||||
|
||||
// Reload all volatile objects.
|
||||
if (!Volatile::loadAll())
|
||||
::printf("Could not reload all volatile objects.\n");
|
||||
@@ -269,12 +291,11 @@ bool Graphics::setMode(void *context, int width, int height, int pixelwidth, int
|
||||
// Restore the graphics state.
|
||||
restoreState(states.back());
|
||||
|
||||
int gammacorrect = isGammaCorrect() ? 1 : 0;
|
||||
Shader::Language target = getShaderLanguageTarget();
|
||||
|
||||
// We always need a default shader.
|
||||
for (int i = 0; i < Shader::STANDARD_MAX_ENUM; i++)
|
||||
{
|
||||
auto stype = (Shader::StandardShader) i;
|
||||
|
||||
if (i == Shader::STANDARD_ARRAY && !capabilities.textureTypes[TEXTURE_2D_ARRAY])
|
||||
continue;
|
||||
|
||||
@@ -284,8 +305,10 @@ bool Graphics::setMode(void *context, int width, int height, int pixelwidth, int
|
||||
{
|
||||
if (!Shader::standardShaders[i])
|
||||
{
|
||||
const auto &code = defaultShaderCode[i][target][gammacorrect];
|
||||
Shader::standardShaders[i] = love::graphics::Graphics::newShader(code.source[ShaderStage::STAGE_VERTEX], code.source[ShaderStage::STAGE_PIXEL]);
|
||||
std::vector<std::string> stages;
|
||||
stages.push_back(Shader::getDefaultCode(stype, ShaderStage::STAGE_VERTEX));
|
||||
stages.push_back(Shader::getDefaultCode(stype, ShaderStage::STAGE_PIXEL));
|
||||
Shader::standardShaders[i] = newShader(stages);
|
||||
}
|
||||
}
|
||||
catch (love::Exception &)
|
||||
@@ -376,7 +399,7 @@ void Graphics::draw(const DrawIndexedCommand &cmd)
|
||||
GLenum glprimitivetype = OpenGL::getGLPrimitiveType(cmd.primitiveType);
|
||||
GLenum gldatatype = OpenGL::getGLIndexDataType(cmd.indexType);
|
||||
|
||||
gl.bindBuffer(BUFFER_INDEX, cmd.indexBuffer->getHandle());
|
||||
gl.bindBuffer(BUFFERTYPE_INDEX, cmd.indexBuffer->getHandle());
|
||||
|
||||
if (cmd.instanceCount > 1)
|
||||
glDrawElementsInstanced(glprimitivetype, cmd.indexCount, gldatatype, gloffset, cmd.instanceCount);
|
||||
@@ -386,13 +409,13 @@ void Graphics::draw(const DrawIndexedCommand &cmd)
|
||||
++drawCalls;
|
||||
}
|
||||
|
||||
static inline void advanceVertexOffsets(const vertex::Attributes &attributes, vertex::BufferBindings &buffers, int vertexcount)
|
||||
static inline void advanceVertexOffsets(const VertexAttributes &attributes, BufferBindings &buffers, int vertexcount)
|
||||
{
|
||||
// TODO: Figure out a better way to avoid touching the same buffer multiple
|
||||
// times, if multiple attributes share the buffer.
|
||||
uint32 touchedbuffers = 0;
|
||||
|
||||
for (unsigned int i = 0; i < vertex::Attributes::MAX; i++)
|
||||
for (unsigned int i = 0; i < VertexAttributes::MAX; i++)
|
||||
{
|
||||
if (!attributes.isEnabled(i))
|
||||
continue;
|
||||
@@ -409,7 +432,7 @@ static inline void advanceVertexOffsets(const vertex::Attributes &attributes, ve
|
||||
}
|
||||
}
|
||||
|
||||
void Graphics::drawQuads(int start, int count, const vertex::Attributes &attributes, const vertex::BufferBindings &buffers, love::graphics::Texture *texture)
|
||||
void Graphics::drawQuads(int start, int count, const VertexAttributes &attributes, const BufferBindings &buffers, love::graphics::Texture *texture)
|
||||
{
|
||||
const int MAX_VERTICES_PER_DRAW = LOVE_UINT16_MAX;
|
||||
const int MAX_QUADS_PER_DRAW = MAX_VERTICES_PER_DRAW / 4;
|
||||
@@ -418,7 +441,7 @@ void Graphics::drawQuads(int start, int count, const vertex::Attributes &attribu
|
||||
gl.bindTextureToUnit(texture, 0, false);
|
||||
gl.setCullMode(CULL_NONE);
|
||||
|
||||
gl.bindBuffer(BUFFER_INDEX, quadIndexBuffer->getHandle());
|
||||
gl.bindBuffer(BUFFERTYPE_INDEX, quadIndexBuffer->getHandle());
|
||||
|
||||
if (gl.isBaseVertexSupported())
|
||||
{
|
||||
@@ -438,7 +461,7 @@ void Graphics::drawQuads(int start, int count, const vertex::Attributes &attribu
|
||||
}
|
||||
else
|
||||
{
|
||||
vertex::BufferBindings bufferscopy = buffers;
|
||||
BufferBindings bufferscopy = buffers;
|
||||
if (start > 0)
|
||||
advanceVertexOffsets(attributes, bufferscopy, start * 4);
|
||||
|
||||
@@ -525,7 +548,7 @@ void Graphics::setRenderTargetsInternal(const RenderTargets &rts, int w, int h,
|
||||
endPass();
|
||||
|
||||
bool iswindow = rts.getFirstTarget().texture == nullptr;
|
||||
vertex::Winding vertexwinding = state.winding;
|
||||
Winding vertexwinding = state.winding;
|
||||
|
||||
if (iswindow)
|
||||
{
|
||||
@@ -543,10 +566,10 @@ void Graphics::setRenderTargetsInternal(const RenderTargets &rts, int w, int h,
|
||||
|
||||
// Flip front face winding when rendering to a texture, since our
|
||||
// projection matrix is flipped.
|
||||
vertexwinding = vertexwinding == vertex::WINDING_CW ? vertex::WINDING_CCW : vertex::WINDING_CW;
|
||||
vertexwinding = vertexwinding == WINDING_CW ? WINDING_CCW : WINDING_CW;
|
||||
}
|
||||
|
||||
glFrontFace(vertexwinding == vertex::WINDING_CW ? GL_CW : GL_CCW);
|
||||
glFrontFace(vertexwinding == WINDING_CW ? GL_CW : GL_CCW);
|
||||
|
||||
gl.setViewport({0, 0, pixelw, pixelh});
|
||||
|
||||
@@ -1246,7 +1269,7 @@ void Graphics::setDepthMode(CompareMode compare, bool write)
|
||||
}
|
||||
}
|
||||
|
||||
void Graphics::setFrontFaceWinding(vertex::Winding winding)
|
||||
void Graphics::setFrontFaceWinding(Winding winding)
|
||||
{
|
||||
DisplayState &state = states.back();
|
||||
|
||||
@@ -1256,9 +1279,9 @@ void Graphics::setFrontFaceWinding(vertex::Winding winding)
|
||||
state.winding = winding;
|
||||
|
||||
if (isRenderTargetActive())
|
||||
winding = winding == vertex::WINDING_CW ? vertex::WINDING_CCW : vertex::WINDING_CW;
|
||||
winding = winding == WINDING_CW ? WINDING_CCW : WINDING_CW;
|
||||
|
||||
glFrontFace(winding == vertex::WINDING_CW ? GL_CW : GL_CCW);
|
||||
glFrontFace(winding == WINDING_CW ? GL_CW : GL_CCW);
|
||||
}
|
||||
|
||||
void Graphics::setColor(Colorf c)
|
||||
@@ -1388,17 +1411,19 @@ void Graphics::initCapabilities()
|
||||
capabilities.features[FEATURE_GLSL3] = GLAD_ES_VERSION_3_0 || gl.isCoreProfile();
|
||||
capabilities.features[FEATURE_GLSL4] = GLAD_ES_VERSION_3_1 || (gl.isCoreProfile() && GLAD_VERSION_4_3);
|
||||
capabilities.features[FEATURE_INSTANCING] = gl.isInstancingSupported();
|
||||
static_assert(FEATURE_MAX_ENUM == 10, "Graphics::initCapabilities must be updated when adding a new graphics feature!");
|
||||
capabilities.features[FEATURE_TEXEL_BUFFER] = gl.areTexelBuffersSupported();
|
||||
static_assert(FEATURE_MAX_ENUM == 11, "Graphics::initCapabilities must be updated when adding a new graphics feature!");
|
||||
|
||||
capabilities.limits[LIMIT_POINT_SIZE] = gl.getMaxPointSize();
|
||||
capabilities.limits[LIMIT_TEXTURE_SIZE] = gl.getMax2DTextureSize();
|
||||
capabilities.limits[LIMIT_TEXTURE_LAYERS] = gl.getMaxTextureLayers();
|
||||
capabilities.limits[LIMIT_VOLUME_TEXTURE_SIZE] = gl.getMax3DTextureSize();
|
||||
capabilities.limits[LIMIT_CUBE_TEXTURE_SIZE] = gl.getMaxCubeTextureSize();
|
||||
capabilities.limits[LIMIT_TEXEL_BUFFER_SIZE] = gl.getMaxTexelBufferSize();
|
||||
capabilities.limits[LIMIT_RENDER_TARGETS] = gl.getMaxRenderTargets();
|
||||
capabilities.limits[LIMIT_TEXTURE_MSAA] = gl.getMaxSamples();
|
||||
capabilities.limits[LIMIT_ANISOTROPY] = gl.getMaxAnisotropy();
|
||||
static_assert(LIMIT_MAX_ENUM == 8, "Graphics::initCapabilities must be updated when adding a new system limit!");
|
||||
static_assert(LIMIT_MAX_ENUM == 9, "Graphics::initCapabilities must be updated when adding a new system limit!");
|
||||
|
||||
for (int i = 0; i < TEXTURE_MAX_ENUM; i++)
|
||||
capabilities.textureTypes[i] = gl.isTextureTypeSupported((TextureType) i);
|
||||
@@ -1524,18 +1549,6 @@ bool Graphics::isPixelFormatSupported(PixelFormat format, bool rendertarget, boo
|
||||
return supported.value;
|
||||
}
|
||||
|
||||
Shader::Language Graphics::getShaderLanguageTarget() const
|
||||
{
|
||||
if (gl.isCoreProfile())
|
||||
return Shader::LANGUAGE_GLSL3;
|
||||
else if (GLAD_ES_VERSION_3_0)
|
||||
return Shader::LANGUAGE_ESSL3;
|
||||
else if (GLAD_ES_VERSION_2_0)
|
||||
return Shader::LANGUAGE_ESSL1;
|
||||
else
|
||||
return Shader::LANGUAGE_GLSL1;
|
||||
}
|
||||
|
||||
} // opengl
|
||||
} // graphics
|
||||
} // love
|
||||
|
||||
Reference in New Issue
Block a user