mirror of
https://github.com/love2d/love.git
synced 2026-08-14 10:13:46 +02:00
Cleaned up and simplified some graphics code.
--HG-- branch : minor
This commit is contained in:
@@ -2141,7 +2141,7 @@
|
||||
08FB7793FE84155DC02AAC07 /* Project object */ = {
|
||||
isa = PBXProject;
|
||||
attributes = {
|
||||
LastUpgradeCheck = 0600;
|
||||
LastUpgradeCheck = 0610;
|
||||
};
|
||||
buildConfigurationList = 1DEB928908733DD80010E9CD /* Build configuration list for PBXProject "love-framework" */;
|
||||
compatibilityVersion = "Xcode 3.2";
|
||||
|
||||
@@ -243,10 +243,6 @@ bool Graphics::setMode(int width, int height, bool &sRGB)
|
||||
// Enable blending
|
||||
glEnable(GL_BLEND);
|
||||
|
||||
// Enable all color component writes.
|
||||
bool colormask[] = {true, true, true, true};
|
||||
setColorMask(colormask);
|
||||
|
||||
// Auto-generated mipmaps should be the best quality possible
|
||||
glHint(GL_GENERATE_MIPMAP_HINT, GL_NICEST);
|
||||
|
||||
@@ -1151,12 +1147,11 @@ love::image::ImageData *Graphics::newScreenshot(love::image::Image *image, bool
|
||||
int w = getWidth();
|
||||
int h = getHeight();
|
||||
|
||||
int row = 4*w;
|
||||
int row = 4 * w;
|
||||
int size = row * h;
|
||||
|
||||
int size = row*h;
|
||||
|
||||
GLubyte *pixels = 0;
|
||||
GLubyte *screenshot = 0;
|
||||
GLubyte *pixels = nullptr;
|
||||
GLubyte *screenshot = nullptr;
|
||||
|
||||
try
|
||||
{
|
||||
@@ -1181,15 +1176,15 @@ love::image::ImageData *Graphics::newScreenshot(love::image::Image *image, bool
|
||||
}
|
||||
|
||||
// OpenGL sucks and reads pixels from the lower-left. Let's fix that.
|
||||
|
||||
GLubyte *src = pixels - row, *dst = screenshot + size;
|
||||
GLubyte *src = pixels - row;
|
||||
GLubyte *dst = screenshot + size;
|
||||
|
||||
for (int i = 0; i < h; ++i)
|
||||
memcpy(dst-=row, src+=row, row);
|
||||
|
||||
delete[] pixels;
|
||||
|
||||
love::image::ImageData *img = 0;
|
||||
love::image::ImageData *img = nullptr;
|
||||
try
|
||||
{
|
||||
// Tell the new ImageData that it owns the screenshot data, so we don't
|
||||
|
||||
@@ -365,20 +365,6 @@ void Image::unloadVolatile()
|
||||
}
|
||||
}
|
||||
|
||||
void Image::uploadImageData(int xoffset, int yoffset, int w, int h)
|
||||
{
|
||||
const image::pixel *pdata = (const image::pixel *) data->getData();
|
||||
pdata += yoffset * data->getWidth() + xoffset;
|
||||
|
||||
{
|
||||
thread::Lock lock(data->getMutex());
|
||||
glTexSubImage2D(GL_TEXTURE_2D, 0, xoffset, yoffset, w, h, GL_RGBA,
|
||||
GL_UNSIGNED_BYTE, pdata);
|
||||
}
|
||||
|
||||
generateMipmaps();
|
||||
}
|
||||
|
||||
bool Image::refresh(int xoffset, int yoffset, int w, int h)
|
||||
{
|
||||
// No effect if the texture hasn't been created yet.
|
||||
@@ -396,7 +382,18 @@ bool Image::refresh(int xoffset, int yoffset, int w, int h)
|
||||
if (isCompressed())
|
||||
loadTextureFromCompressedData();
|
||||
else
|
||||
uploadImageData(xoffset, yoffset, w, h);
|
||||
{
|
||||
const image::pixel *pdata = (const image::pixel *) data->getData();
|
||||
pdata += yoffset * data->getWidth() + xoffset;
|
||||
|
||||
{
|
||||
thread::Lock lock(data->getMutex());
|
||||
glTexSubImage2D(GL_TEXTURE_2D, 0, xoffset, yoffset, w, h, GL_RGBA,
|
||||
GL_UNSIGNED_BYTE, pdata);
|
||||
}
|
||||
|
||||
generateMipmaps();
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -159,7 +159,6 @@ private:
|
||||
void loadDefaultTexture();
|
||||
void loadTextureFromCompressedData();
|
||||
void loadTextureFromImageData();
|
||||
void uploadImageData(int xoffset, int yoffset, int w, int h);
|
||||
|
||||
GLenum getCompressedFormat(image::CompressedData::Format cformat) const;
|
||||
|
||||
|
||||
@@ -97,10 +97,7 @@ void Mesh::setVertices(const std::vector<Vertex> &verts)
|
||||
}
|
||||
|
||||
if (!vbo)
|
||||
{
|
||||
// Full memory backing because we might access the data at any time.
|
||||
vbo = VertexBuffer::Create(size, GL_ARRAY_BUFFER, GL_DYNAMIC_DRAW, VertexBuffer::BACKING_FULL);
|
||||
}
|
||||
vbo = VertexBuffer::Create(size, GL_ARRAY_BUFFER, GL_DYNAMIC_DRAW);
|
||||
|
||||
vertex_count = verts.size();
|
||||
|
||||
@@ -183,10 +180,7 @@ void Mesh::setVertexMap(const std::vector<uint32> &map)
|
||||
}
|
||||
|
||||
if (!ibo && size > 0)
|
||||
{
|
||||
// Full memory backing because we might access the data at any time.
|
||||
ibo = VertexBuffer::Create(size, GL_ELEMENT_ARRAY_BUFFER, GL_DYNAMIC_DRAW, VertexBuffer::BACKING_FULL);
|
||||
}
|
||||
ibo = VertexBuffer::Create(size, GL_ELEMENT_ARRAY_BUFFER, GL_DYNAMIC_DRAW);
|
||||
|
||||
element_count = map.size();
|
||||
|
||||
|
||||
@@ -531,32 +531,20 @@ void OpenGL::setTextureFilter(graphics::Texture::Filter &f)
|
||||
|
||||
void OpenGL::setTextureWrap(const graphics::Texture::Wrap &w)
|
||||
{
|
||||
GLint gs, gt;
|
||||
|
||||
switch (w.s)
|
||||
auto glWrapMode = [](Texture::WrapMode wmode) -> GLint
|
||||
{
|
||||
case Texture::WRAP_CLAMP:
|
||||
gs = GL_CLAMP_TO_EDGE;
|
||||
break;
|
||||
case Texture::WRAP_REPEAT:
|
||||
default:
|
||||
gs = GL_REPEAT;
|
||||
break;
|
||||
}
|
||||
switch (wmode)
|
||||
{
|
||||
case Texture::WRAP_CLAMP:
|
||||
return GL_CLAMP_TO_EDGE;
|
||||
case Texture::WRAP_REPEAT:
|
||||
default:
|
||||
return GL_REPEAT;
|
||||
}
|
||||
};
|
||||
|
||||
switch (w.t)
|
||||
{
|
||||
case Texture::WRAP_CLAMP:
|
||||
gt = GL_CLAMP_TO_EDGE;
|
||||
break;
|
||||
case Texture::WRAP_REPEAT:
|
||||
default:
|
||||
gt = GL_REPEAT;
|
||||
break;
|
||||
}
|
||||
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, gs);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, gt);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, glWrapMode(w.s));
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, glWrapMode(w.t));
|
||||
}
|
||||
|
||||
int OpenGL::getMaxTextureSize() const
|
||||
|
||||
@@ -36,30 +36,34 @@ namespace opengl
|
||||
|
||||
// VertexBuffer
|
||||
|
||||
VertexBuffer *VertexBuffer::Create(size_t size, GLenum target, GLenum usage, MemoryBacking backing)
|
||||
VertexBuffer *VertexBuffer::Create(size_t size, GLenum target, GLenum usage)
|
||||
{
|
||||
return new VertexBuffer(size, target, usage, backing);
|
||||
return new VertexBuffer(size, target, usage);
|
||||
}
|
||||
|
||||
VertexBuffer::VertexBuffer(size_t size, GLenum target, GLenum usage, MemoryBacking backing)
|
||||
VertexBuffer::VertexBuffer(size_t size, GLenum target, GLenum usage)
|
||||
: is_bound(false)
|
||||
, is_mapped(false)
|
||||
, size(size)
|
||||
, target(target)
|
||||
, usage(usage)
|
||||
, backing(backing)
|
||||
, vbo(0)
|
||||
, memory_map(nullptr)
|
||||
, is_dirty(false)
|
||||
{
|
||||
if (getMemoryBacking() == BACKING_FULL)
|
||||
memory_map = (char *) malloc(getSize());
|
||||
try
|
||||
{
|
||||
memory_map = new char[size];
|
||||
}
|
||||
catch (std::bad_alloc &)
|
||||
{
|
||||
throw love::Exception("Out of memory.");
|
||||
}
|
||||
|
||||
bool ok = load(false);
|
||||
|
||||
if (!ok)
|
||||
{
|
||||
free(memory_map);
|
||||
delete[] memory_map;
|
||||
throw love::Exception("Could not load VBO.");
|
||||
}
|
||||
}
|
||||
@@ -67,10 +71,9 @@ VertexBuffer::VertexBuffer(size_t size, GLenum target, GLenum usage, MemoryBacki
|
||||
VertexBuffer::~VertexBuffer()
|
||||
{
|
||||
if (vbo != 0)
|
||||
unload(false);
|
||||
unload();
|
||||
|
||||
if (memory_map)
|
||||
free(memory_map);
|
||||
delete[] memory_map;
|
||||
}
|
||||
|
||||
void *VertexBuffer::map()
|
||||
@@ -78,19 +81,6 @@ void *VertexBuffer::map()
|
||||
if (is_mapped)
|
||||
return memory_map;
|
||||
|
||||
if (!memory_map)
|
||||
{
|
||||
memory_map = (char *) malloc(getSize());
|
||||
if (!memory_map)
|
||||
throw love::Exception("Out of memory (oh the humanity!)");
|
||||
}
|
||||
|
||||
if (is_dirty)
|
||||
{
|
||||
glGetBufferSubData(getTarget(), 0, (GLsizeiptr) getSize(), memory_map);
|
||||
is_dirty = false;
|
||||
}
|
||||
|
||||
is_mapped = true;
|
||||
|
||||
return memory_map;
|
||||
@@ -167,16 +157,10 @@ void VertexBuffer::unbind()
|
||||
|
||||
void VertexBuffer::fill(size_t offset, size_t size, const void *data)
|
||||
{
|
||||
if (is_mapped || getMemoryBacking() == BACKING_FULL)
|
||||
memcpy(memory_map + offset, data, size);
|
||||
memcpy(memory_map + offset, data, size);
|
||||
|
||||
if (!is_mapped)
|
||||
{
|
||||
glBufferSubData(getTarget(), (GLintptr) offset, (GLsizeiptr) size, data);
|
||||
|
||||
if (getMemoryBacking() != BACKING_FULL)
|
||||
is_dirty = true;
|
||||
}
|
||||
}
|
||||
|
||||
const void *VertexBuffer::getPointer(size_t offset) const
|
||||
@@ -191,7 +175,7 @@ bool VertexBuffer::loadVolatile()
|
||||
|
||||
void VertexBuffer::unloadVolatile()
|
||||
{
|
||||
unload(true);
|
||||
unload();
|
||||
}
|
||||
|
||||
bool VertexBuffer::load(bool restore)
|
||||
@@ -213,15 +197,8 @@ bool VertexBuffer::load(bool restore)
|
||||
return (GL_NO_ERROR == err);
|
||||
}
|
||||
|
||||
void VertexBuffer::unload(bool save)
|
||||
void VertexBuffer::unload()
|
||||
{
|
||||
// Save data before unloading, if we need to.
|
||||
if (save && getMemoryBacking() == BACKING_PARTIAL)
|
||||
{
|
||||
VertexBuffer::Bind bind(*this);
|
||||
map(); // saves buffer content to memory_map.
|
||||
}
|
||||
|
||||
is_mapped = false;
|
||||
|
||||
glDeleteBuffers(1, &vbo);
|
||||
|
||||
@@ -49,18 +49,6 @@ class VertexBuffer : public Volatile
|
||||
{
|
||||
public:
|
||||
|
||||
// Different guarantees for VertexBuffer data storage.
|
||||
enum MemoryBacking
|
||||
{
|
||||
// The VertexBuffer is will have a valid copy of its data in main memory
|
||||
// at all times.
|
||||
BACKING_FULL,
|
||||
|
||||
// The VertexBuffer will have a valid copy of its data in main memory
|
||||
// when it needs to be reloaded and when it's mapped.
|
||||
BACKING_PARTIAL
|
||||
};
|
||||
|
||||
/**
|
||||
* Create a new VertexBuffer.
|
||||
*
|
||||
@@ -70,7 +58,7 @@ public:
|
||||
* @param backing Determines what guarantees are placed on the data.
|
||||
* @return A new VertexBuffer.
|
||||
*/
|
||||
static VertexBuffer *Create(size_t size, GLenum target, GLenum usage, MemoryBacking backing = BACKING_PARTIAL);
|
||||
static VertexBuffer *Create(size_t size, GLenum target, GLenum usage);
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
@@ -80,7 +68,7 @@ public:
|
||||
* @param usage Usage hint, e.g. GL_DYNAMIC_DRAW.
|
||||
* @param backing Determines what guarantees are placed on the data.
|
||||
*/
|
||||
VertexBuffer(size_t size, GLenum target, GLenum usage, MemoryBacking backing = BACKING_PARTIAL);
|
||||
VertexBuffer(size_t size, GLenum target, GLenum usage);
|
||||
|
||||
/**
|
||||
* Destructor.
|
||||
@@ -127,11 +115,6 @@ public:
|
||||
return is_mapped;
|
||||
}
|
||||
|
||||
MemoryBacking getMemoryBacking() const
|
||||
{
|
||||
return backing;
|
||||
}
|
||||
|
||||
/**
|
||||
* Map the VertexBuffer to client memory.
|
||||
*
|
||||
@@ -267,13 +250,7 @@ private:
|
||||
* @return True on success, false otherwise.
|
||||
*/
|
||||
bool load(bool restore);
|
||||
|
||||
/**
|
||||
* Optionally save the data in the VBO, then delete it.
|
||||
*
|
||||
* @param save True to save the data before deleting.
|
||||
*/
|
||||
void unload(bool save);
|
||||
void unload();
|
||||
|
||||
void unmapStatic(size_t offset, size_t size);
|
||||
void unmapStream();
|
||||
@@ -293,20 +270,12 @@ private:
|
||||
// Usage hint. GL_[DYNAMIC, STATIC, STREAM]_DRAW.
|
||||
GLenum usage;
|
||||
|
||||
//
|
||||
MemoryBacking backing;
|
||||
|
||||
// The VBO identifier. Assigned by OpenGL.
|
||||
GLuint vbo;
|
||||
|
||||
// A pointer to mapped memory. Will be inialized on the first
|
||||
// call to map().
|
||||
// A pointer to mapped memory.
|
||||
char *memory_map;
|
||||
|
||||
// Set if the buffer was modified while operating on gpu memory
|
||||
// and needs to be synchronized.
|
||||
bool is_dirty;
|
||||
|
||||
}; // VertexBuffer
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user