mirror of
https://github.com/love2d/love.git
synced 2026-08-12 08:30:56 +02:00
Simplify quad drawing code, and use glDrawElementsBaseVertex when available.
This commit is contained in:
@@ -18,12 +18,7 @@
|
||||
* 3. This notice may not be removed or altered from any source distribution.
|
||||
**/
|
||||
|
||||
#include "common/config.h"
|
||||
#include "Buffer.h"
|
||||
#include "Graphics.h"
|
||||
#include "common/Exception.h"
|
||||
|
||||
#include <algorithm> // std::min
|
||||
|
||||
namespace love
|
||||
{
|
||||
@@ -43,103 +38,5 @@ Buffer::~Buffer()
|
||||
{
|
||||
}
|
||||
|
||||
// QuadIndices
|
||||
|
||||
static const int MAX_VERTICES_PER_DRAW = LOVE_UINT16_MAX;
|
||||
static const int MAX_QUADS_PER_DRAW = MAX_VERTICES_PER_DRAW / 4;
|
||||
|
||||
size_t QuadIndices::objectCount = 0;
|
||||
|
||||
Buffer *QuadIndices::indexBuffer = nullptr;
|
||||
|
||||
QuadIndices::QuadIndices(Graphics *gfx)
|
||||
{
|
||||
if (indexBuffer == nullptr)
|
||||
{
|
||||
size_t buffersize = sizeof(uint16) * MAX_QUADS_PER_DRAW * 6;
|
||||
|
||||
indexBuffer = gfx->newBuffer(buffersize, nullptr, BUFFER_INDEX, vertex::USAGE_STATIC, 0);
|
||||
|
||||
Buffer::Mapper map(*indexBuffer);
|
||||
vertex::fillIndices(vertex::TriangleIndexMode::QUADS, 0, MAX_VERTICES_PER_DRAW, (uint16 *) map.get());
|
||||
}
|
||||
|
||||
objectCount++;
|
||||
}
|
||||
|
||||
QuadIndices::QuadIndices(const QuadIndices &)
|
||||
{
|
||||
objectCount++;
|
||||
}
|
||||
|
||||
QuadIndices &QuadIndices::operator = (const QuadIndices &)
|
||||
{
|
||||
return *this;
|
||||
}
|
||||
|
||||
QuadIndices::~QuadIndices()
|
||||
{
|
||||
--objectCount;
|
||||
|
||||
// Delete the buffer if we were the last living QuadIndices object.
|
||||
if (objectCount <= 0)
|
||||
{
|
||||
delete indexBuffer;
|
||||
indexBuffer = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
static inline void advanceVertexOffsets(const vertex::Attributes &attributes, vertex::Buffers &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++)
|
||||
{
|
||||
if (!attributes.isEnabled(i))
|
||||
continue;
|
||||
|
||||
auto &attrib = attributes.attribs[i];
|
||||
|
||||
uint32 bufferbit = 1u << attrib.bufferindex;
|
||||
if ((touchedbuffers & bufferbit) == 0)
|
||||
{
|
||||
touchedbuffers |= bufferbit;
|
||||
buffers.info[attrib.bufferindex].offset += attrib.stride * vertexcount;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void QuadIndices::draw(Graphics *gfx, int quadstart, int quadcount, const vertex::Attributes &attributes, vertex::Buffers buffers, Texture *texture)
|
||||
{
|
||||
Graphics::DrawIndexedCommand cmd(&attributes, &buffers, indexBuffer);
|
||||
cmd.primitiveType = PRIMITIVE_TRIANGLES;
|
||||
cmd.indexBufferOffset = 0;
|
||||
cmd.indexType = INDEX_UINT16;
|
||||
cmd.texture = texture;
|
||||
|
||||
// TODO: We can use glDrawElementsBaseVertex when supported, instead of
|
||||
// advancing the vertex offset.
|
||||
if (quadstart > 0)
|
||||
advanceVertexOffsets(attributes, buffers, quadstart * 4);
|
||||
|
||||
for (int quadindex = 0; quadindex < quadcount; quadindex += MAX_QUADS_PER_DRAW)
|
||||
{
|
||||
int quaddrawcount = std::min(MAX_QUADS_PER_DRAW, quadcount - quadindex);
|
||||
|
||||
if (quadindex > 0)
|
||||
advanceVertexOffsets(attributes, buffers, quaddrawcount * 4);
|
||||
|
||||
cmd.indexCount = quaddrawcount * 6;
|
||||
gfx->draw(cmd);
|
||||
}
|
||||
}
|
||||
|
||||
Buffer *QuadIndices::getBuffer() const
|
||||
{
|
||||
return indexBuffer;
|
||||
}
|
||||
|
||||
} // graphics
|
||||
} // love
|
||||
|
||||
@@ -34,9 +34,6 @@ namespace love
|
||||
namespace graphics
|
||||
{
|
||||
|
||||
class Graphics;
|
||||
class Texture;
|
||||
|
||||
/**
|
||||
* A block of GPU-owned memory. Currently meant for internal use.
|
||||
**/
|
||||
@@ -150,57 +147,5 @@ protected:
|
||||
|
||||
}; // Buffer
|
||||
|
||||
/**
|
||||
* QuadIndices manages one shared Buffer that stores the indices for an element
|
||||
* array. Vertex arrays using the vertex structure (or anything else that can
|
||||
* use the pattern below) can request a size and use it for the indexed draw
|
||||
* call.
|
||||
*
|
||||
* indices[i*6 + 0] = i*4 + 0;
|
||||
* indices[i*6 + 1] = i*4 + 1;
|
||||
* indices[i*6 + 2] = i*4 + 2;
|
||||
*
|
||||
* indices[i*6 + 3] = i*4 + 2;
|
||||
* indices[i*6 + 4] = i*4 + 1;
|
||||
* indices[i*6 + 5] = i*4 + 3;
|
||||
*
|
||||
* There will always be a large enough Buffer around until all QuadIndices
|
||||
* instances have been deleted.
|
||||
*
|
||||
* Q: Why have something like QuadIndices?
|
||||
* A: The indices for the SpriteBatch do not change, only the array size varies.
|
||||
* Using one Buffer for all element arrays removes this duplicated data and
|
||||
* saves some memory.
|
||||
*/
|
||||
class QuadIndices
|
||||
{
|
||||
public:
|
||||
|
||||
/**
|
||||
* Adds an entry to the list of sizes and resizes the Buffer
|
||||
* if needed. A size of 1 allocates a group of 6 indices for 4 vertices
|
||||
* creating 1 face.
|
||||
*/
|
||||
QuadIndices(Graphics *gfx);
|
||||
|
||||
QuadIndices(const QuadIndices &other);
|
||||
QuadIndices &operator = (const QuadIndices &other);
|
||||
|
||||
/**
|
||||
* Removes an entry from the list of sizes and resizes the GLBuffer
|
||||
* if needed.
|
||||
*/
|
||||
~QuadIndices();
|
||||
|
||||
void draw(Graphics *gfx, int quadstart, int quadcount, const vertex::Attributes &attributes, vertex::Buffers buffers, Texture *texture);
|
||||
Buffer *getBuffer() const;
|
||||
|
||||
private:
|
||||
|
||||
static size_t objectCount;
|
||||
static Buffer *indexBuffer;
|
||||
|
||||
}; // QuadIndices
|
||||
|
||||
} // graphics
|
||||
} // love
|
||||
|
||||
@@ -119,6 +119,7 @@ Graphics::Graphics()
|
||||
, canvasSwitchCount(0)
|
||||
, drawCalls(0)
|
||||
, drawCallsBatched(0)
|
||||
, quadIndexBuffer(nullptr)
|
||||
, capabilities()
|
||||
, cachedShaderStages()
|
||||
{
|
||||
@@ -134,6 +135,8 @@ Graphics::Graphics()
|
||||
|
||||
Graphics::~Graphics()
|
||||
{
|
||||
delete quadIndexBuffer;
|
||||
|
||||
// Clean up standard shaders before the active shader. If we do it after,
|
||||
// the active shader may try to activate a standard shader when deactivating
|
||||
// itself, which will cause problems since it calls Graphics methods in the
|
||||
@@ -161,6 +164,18 @@ Graphics::~Graphics()
|
||||
Shader::deinitialize();
|
||||
}
|
||||
|
||||
void Graphics::createQuadIndexBuffer()
|
||||
{
|
||||
if (quadIndexBuffer != nullptr)
|
||||
return;
|
||||
|
||||
size_t size = sizeof(uint16) * (LOVE_UINT16_MAX / 4) * 6;
|
||||
quadIndexBuffer = newBuffer(size, nullptr, BUFFER_INDEX, vertex::USAGE_STATIC, 0);
|
||||
|
||||
Buffer::Mapper map(*quadIndexBuffer);
|
||||
vertex::fillIndices(vertex::TriangleIndexMode::QUADS, 0, LOVE_UINT16_MAX, (uint16 *) map.get());
|
||||
}
|
||||
|
||||
Quad *Graphics::newQuad(Quad::Viewport v, double sw, double sh)
|
||||
{
|
||||
return new Quad(v, sw, sh);
|
||||
|
||||
@@ -851,6 +851,7 @@ public:
|
||||
|
||||
virtual void draw(const DrawCommand &cmd) = 0;
|
||||
virtual void draw(const DrawIndexedCommand &cmd) = 0;
|
||||
virtual void drawQuads(int start, int count, const vertex::Attributes &attributes, const vertex::Buffers &buffers, Texture *texture) = 0;
|
||||
|
||||
void flushStreamDraws();
|
||||
StreamVertexData requestStreamDraw(const StreamDrawCommand &command);
|
||||
@@ -996,6 +997,8 @@ protected:
|
||||
virtual void initCapabilities() = 0;
|
||||
virtual void getAPIStats(int &shaderswitches) const = 0;
|
||||
|
||||
void createQuadIndexBuffer();
|
||||
|
||||
Canvas *getTemporaryCanvas(PixelFormat format, int w, int h, int samples);
|
||||
|
||||
void restoreState(const DisplayState &s);
|
||||
@@ -1035,6 +1038,8 @@ protected:
|
||||
int drawCalls;
|
||||
int drawCallsBatched;
|
||||
|
||||
Buffer *quadIndexBuffer;
|
||||
|
||||
Capabilities capabilities;
|
||||
|
||||
Deprecations deprecations;
|
||||
|
||||
@@ -95,7 +95,6 @@ ParticleSystem::ParticleSystem(Graphics *gfx, Texture *texture, uint32 size)
|
||||
, relativeRotation(false)
|
||||
, vertexAttributes(vertex::CommonFormat::XYf_STf_RGBAub, 0)
|
||||
, buffer(nullptr)
|
||||
, quadIndices(gfx)
|
||||
{
|
||||
if (size == 0 || size > MAX_PARTICLES)
|
||||
throw love::Exception("Invalid ParticleSystem size.");
|
||||
@@ -157,7 +156,6 @@ ParticleSystem::ParticleSystem(const ParticleSystem &p)
|
||||
, relativeRotation(p.relativeRotation)
|
||||
, vertexAttributes(p.vertexAttributes)
|
||||
, buffer(nullptr)
|
||||
, quadIndices(p.quadIndices)
|
||||
{
|
||||
setBufferSize(maxParticles);
|
||||
}
|
||||
@@ -194,8 +192,6 @@ void ParticleSystem::createBuffers(size_t size)
|
||||
|
||||
size_t bytes = sizeof(Vertex) * size * 4;
|
||||
buffer = gfx->newBuffer(bytes, nullptr, BUFFER_VERTEX, vertex::USAGE_STREAM, 0);
|
||||
|
||||
quadIndices = QuadIndices(gfx);
|
||||
}
|
||||
catch (std::bad_alloc &)
|
||||
{
|
||||
@@ -1101,7 +1097,7 @@ void ParticleSystem::draw(Graphics *gfx, const Matrix4 &m)
|
||||
vertex::Buffers vertexbuffers;
|
||||
vertexbuffers.set(0, buffer, 0);
|
||||
|
||||
quadIndices.draw(gfx, 0, pCount, vertexAttributes, vertexbuffers, texture);
|
||||
gfx->drawQuads(0, pCount, vertexAttributes, vertexbuffers, texture);
|
||||
}
|
||||
|
||||
bool ParticleSystem::getConstant(const char *in, AreaSpreadDistribution &out)
|
||||
|
||||
@@ -702,9 +702,6 @@ private:
|
||||
const vertex::Attributes vertexAttributes;
|
||||
Buffer *buffer;
|
||||
|
||||
// Vertex index buffer.
|
||||
QuadIndices quadIndices;
|
||||
|
||||
static StringMap<AreaSpreadDistribution, DISTRIBUTION_MAX_ENUM>::Entry distributionsEntries[];
|
||||
static StringMap<AreaSpreadDistribution, DISTRIBUTION_MAX_ENUM> distributions;
|
||||
|
||||
|
||||
@@ -47,7 +47,6 @@ SpriteBatch::SpriteBatch(Graphics *gfx, Texture *texture, int size, vertex::Usag
|
||||
, color(255, 255, 255, 255)
|
||||
, color_active(false)
|
||||
, array_buf(nullptr)
|
||||
, quad_indices(gfx)
|
||||
, range_start(-1)
|
||||
, range_count(-1)
|
||||
{
|
||||
@@ -394,7 +393,7 @@ void SpriteBatch::draw(Graphics *gfx, const Matrix4 &m)
|
||||
count = std::min(count, next - start);
|
||||
|
||||
if (count > 0)
|
||||
quad_indices.draw(gfx, start, count, attributes, buffers, texture);
|
||||
gfx->drawQuads(start, count, attributes, buffers, texture);
|
||||
}
|
||||
|
||||
} // graphics
|
||||
|
||||
@@ -140,8 +140,7 @@ private:
|
||||
size_t vertex_stride;
|
||||
|
||||
love::graphics::Buffer *array_buf;
|
||||
QuadIndices quad_indices;
|
||||
|
||||
|
||||
std::unordered_map<std::string, AttachedAttribute> attached_attributes;
|
||||
|
||||
int range_start;
|
||||
|
||||
@@ -34,7 +34,6 @@ Text::Text(Graphics *gfx, Font *font, const std::vector<Font::ColoredString> &te
|
||||
: font(font)
|
||||
, vertexAttributes(Font::vertexFormat, 0)
|
||||
, vbo(nullptr)
|
||||
, quadIndices(gfx)
|
||||
, vert_offset(0)
|
||||
, texture_cache_id((uint32) -1)
|
||||
{
|
||||
@@ -264,7 +263,7 @@ void Text::draw(Graphics *gfx, const Matrix4 &m)
|
||||
Graphics::TempTransform transform(gfx, m);
|
||||
|
||||
for (const Font::DrawCommand &cmd : draw_commands)
|
||||
quadIndices.draw(gfx, cmd.startvertex / 4, cmd.vertexcount / 4, vertexAttributes, vertexBuffers, cmd.texture);
|
||||
gfx->drawQuads(cmd.startvertex / 4, cmd.vertexcount / 4, vertexAttributes, vertexBuffers, cmd.texture);
|
||||
}
|
||||
|
||||
} // graphics
|
||||
|
||||
@@ -89,7 +89,6 @@ private:
|
||||
vertex::Buffers vertexBuffers;
|
||||
|
||||
Buffer *vbo;
|
||||
QuadIndices quadIndices;
|
||||
|
||||
std::vector<Font::DrawCommand> draw_commands;
|
||||
|
||||
|
||||
@@ -55,8 +55,7 @@ namespace opengl
|
||||
{
|
||||
|
||||
Graphics::Graphics()
|
||||
: quadIndices(nullptr)
|
||||
, windowHasStencil(false)
|
||||
: windowHasStencil(false)
|
||||
, mainVAO(0)
|
||||
{
|
||||
gl = OpenGL();
|
||||
@@ -87,8 +86,6 @@ Graphics::Graphics()
|
||||
|
||||
Graphics::~Graphics()
|
||||
{
|
||||
if (quadIndices)
|
||||
delete quadIndices;
|
||||
}
|
||||
|
||||
const char *Graphics::getName() const
|
||||
@@ -226,13 +223,7 @@ bool Graphics::setMode(int width, int height, int pixelwidth, int pixelheight, b
|
||||
if (!Volatile::loadAll())
|
||||
::printf("Could not reload all volatile objects.\n");
|
||||
|
||||
// Create a quad indices object owned by love.graphics, so at least one
|
||||
// QuadIndices object is alive at all times while love.graphics is alive.
|
||||
// This makes sure there aren't too many expensive destruction/creations of
|
||||
// index buffer objects, since the shared index buffer used by QuadIndices
|
||||
// objects is destroyed when the last object is destroyed.
|
||||
if (quadIndices == nullptr)
|
||||
quadIndices = new QuadIndices(this);
|
||||
createQuadIndexBuffer();
|
||||
|
||||
// Restore the graphics state.
|
||||
restoreState(states.back());
|
||||
@@ -354,6 +345,76 @@ void Graphics::draw(const DrawIndexedCommand &cmd)
|
||||
++drawCalls;
|
||||
}
|
||||
|
||||
static inline void advanceVertexOffsets(const vertex::Attributes &attributes, vertex::Buffers &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++)
|
||||
{
|
||||
if (!attributes.isEnabled(i))
|
||||
continue;
|
||||
|
||||
auto &attrib = attributes.attribs[i];
|
||||
|
||||
uint32 bufferbit = 1u << attrib.bufferindex;
|
||||
if ((touchedbuffers & bufferbit) == 0)
|
||||
{
|
||||
touchedbuffers |= bufferbit;
|
||||
buffers.info[attrib.bufferindex].offset += attrib.stride * vertexcount;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Graphics::drawQuads(int start, int count, const vertex::Attributes &attributes, const vertex::Buffers &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;
|
||||
|
||||
gl.prepareDraw();
|
||||
gl.bindTextureToUnit(texture, 0, false);
|
||||
gl.setCullMode(CULL_NONE);
|
||||
|
||||
gl.bindBuffer(BUFFER_INDEX, quadIndexBuffer->getHandle());
|
||||
|
||||
if (gl.isBaseVertexSupported())
|
||||
{
|
||||
gl.setVertexAttributes(attributes, buffers);
|
||||
|
||||
int basevertex = start;
|
||||
|
||||
for (int quadindex = 0; quadindex < count; quadindex += MAX_QUADS_PER_DRAW)
|
||||
{
|
||||
int quadcount = std::min(MAX_QUADS_PER_DRAW, count - quadindex);
|
||||
|
||||
glDrawElementsBaseVertex(GL_TRIANGLES, quadcount * 6, GL_UNSIGNED_SHORT, BUFFER_OFFSET(0), basevertex);
|
||||
++drawCalls;
|
||||
|
||||
basevertex += quadcount * 4;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
vertex::Buffers bufferscopy = buffers;
|
||||
if (start > 0)
|
||||
advanceVertexOffsets(attributes, bufferscopy, start * 4);
|
||||
|
||||
for (int quadindex = 0; quadindex < count; quadindex += MAX_QUADS_PER_DRAW)
|
||||
{
|
||||
gl.setVertexAttributes(attributes, bufferscopy);
|
||||
|
||||
int quadcount = std::min(MAX_QUADS_PER_DRAW, count - quadindex);
|
||||
|
||||
glDrawElements(GL_TRIANGLES, quadcount * 6, GL_UNSIGNED_SHORT, BUFFER_OFFSET(0));
|
||||
++drawCalls;
|
||||
|
||||
if (count > MAX_QUADS_PER_DRAW)
|
||||
advanceVertexOffsets(attributes, bufferscopy, quadcount * 4);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void APIENTRY debugCB(GLenum source, GLenum type, GLuint id, GLenum severity, GLsizei /*len*/, const GLchar *msg, const GLvoid* /*usr*/)
|
||||
{
|
||||
// Human-readable strings for the debug info.
|
||||
|
||||
@@ -71,6 +71,7 @@ public:
|
||||
|
||||
void draw(const DrawCommand &cmd) override;
|
||||
void draw(const DrawIndexedCommand &cmd) override;
|
||||
void drawQuads(int start, int count, const vertex::Attributes &attributes, const vertex::Buffers &buffers, Texture *texture) override;
|
||||
|
||||
void clear(OptionalColorf color, OptionalInt stencil, OptionalDouble depth) override;
|
||||
void clear(const std::vector<OptionalColorf> &colors, OptionalInt stencil, OptionalDouble depth) override;
|
||||
@@ -127,7 +128,6 @@ private:
|
||||
void setDebug(bool enable);
|
||||
|
||||
std::unordered_map<uint32, GLuint> framebufferObjects;
|
||||
QuadIndices *quadIndices;
|
||||
bool windowHasStencil;
|
||||
GLuint mainVAO;
|
||||
|
||||
|
||||
@@ -95,6 +95,7 @@ OpenGL::OpenGL()
|
||||
: stats()
|
||||
, contextInitialized(false)
|
||||
, pixelShaderHighpSupported(false)
|
||||
, baseVertexSupported(false)
|
||||
, maxAnisotropy(1.0f)
|
||||
, max2DTextureSize(0)
|
||||
, max3DTextureSize(0)
|
||||
@@ -375,6 +376,32 @@ void OpenGL::initOpenGLFunctions()
|
||||
fp_glCompressedTexSubImage3D = fp_glCompressedTexSubImage3DOES;
|
||||
fp_glFramebufferTexture3D = fp_glFramebufferTexture3DOES;
|
||||
}
|
||||
|
||||
if (!GLAD_VERSION_3_2 && !GLAD_ES_VERSION_3_2 && !GLAD_ARB_draw_elements_base_vertex)
|
||||
{
|
||||
if (GLAD_OES_draw_elements_base_vertex)
|
||||
{
|
||||
fp_glDrawElementsBaseVertex = fp_glDrawElementsBaseVertexOES;
|
||||
|
||||
if (GLAD_ES_VERSION_3_0)
|
||||
{
|
||||
fp_glDrawRangeElementsBaseVertex = fp_glDrawRangeElementsBaseVertexOES;
|
||||
fp_glDrawElementsInstancedBaseVertex = fp_glDrawElementsInstancedBaseVertexOES;
|
||||
}
|
||||
|
||||
}
|
||||
else if (GLAD_EXT_draw_elements_base_vertex)
|
||||
{
|
||||
fp_glDrawElementsBaseVertex = fp_glDrawElementsBaseVertexEXT;
|
||||
|
||||
if (GLAD_ES_VERSION_3_0)
|
||||
{
|
||||
fp_glDrawRangeElementsBaseVertex = fp_glDrawRangeElementsBaseVertexEXT;
|
||||
fp_glDrawElementsInstancedBaseVertex = fp_glDrawElementsInstancedBaseVertexEXT;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void OpenGL::initMaxValues()
|
||||
@@ -389,6 +416,9 @@ void OpenGL::initMaxValues()
|
||||
else
|
||||
pixelShaderHighpSupported = true;
|
||||
|
||||
baseVertexSupported = GLAD_VERSION_3_2 || GLAD_ES_VERSION_3_2 || GLAD_ARB_draw_elements_base_vertex
|
||||
|| GLAD_OES_draw_elements_base_vertex || GLAD_EXT_draw_elements_base_vertex;
|
||||
|
||||
// We'll need this value to clamp anisotropy.
|
||||
if (GLAD_EXT_texture_filter_anisotropic)
|
||||
glGetFloatv(GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, &maxAnisotropy);
|
||||
@@ -1177,6 +1207,11 @@ bool OpenGL::isSamplerLODBiasSupported() const
|
||||
return GLAD_VERSION_1_4;
|
||||
}
|
||||
|
||||
bool OpenGL::isBaseVertexSupported() const
|
||||
{
|
||||
return baseVertexSupported;
|
||||
}
|
||||
|
||||
int OpenGL::getMax2DTextureSize() const
|
||||
{
|
||||
return std::max(max2DTextureSize, 1);
|
||||
|
||||
@@ -334,6 +334,7 @@ public:
|
||||
bool isInstancingSupported() const;
|
||||
bool isDepthCompareSampleSupported() const;
|
||||
bool isSamplerLODBiasSupported() const;
|
||||
bool isBaseVertexSupported() const;
|
||||
|
||||
/**
|
||||
* Returns the maximum supported width or height of a texture.
|
||||
@@ -413,6 +414,8 @@ private:
|
||||
bool contextInitialized;
|
||||
|
||||
bool pixelShaderHighpSupported;
|
||||
bool baseVertexSupported;
|
||||
|
||||
float maxAnisotropy;
|
||||
float maxLODBias;
|
||||
int max2DTextureSize;
|
||||
|
||||
Reference in New Issue
Block a user