mirror of
https://github.com/love2d/love.git
synced 2026-08-16 08:11:02 +02:00
d215d8a91e
Gamma-correct blending and shader math can be enabled globally via the new 't.gammacorrect' boolean flag in love.conf. The new function love.graphics.isGammaCorrect will return true if it was requested in love.conf and is supported on the system. When gamma correct rendering is enabled, colors (including the colors of pixels from images) are automatically converted from sRGB to linear RGB before use. When drawing to the main screen or to a canvas with the 'normal' or 'srgb' format, the final output colors of pixel shaders are automatically converted from linear RGB to sRGB after blending and before the color is stored in the pixel. This lets the rendering pipeline do math using linear RGB values for colors rather than sRGB values, so the math is correct, without making users of the APIs manually linearize their colors with the love.math.gammaToLinear function (which still exists). The final output of the screen is encoded as sRGB, which is what systems expect. Canvases (except when otherwise requested) store their contents with sRGB encoding for increased precision with darker colors. the 'srgb' window setting flag has been removed, as well as the 'srgb' image flag. A new image flag 'linear' has been added, which when set to true will cause the colors of the image to always be treated as linear RGB rather than sRGB, when gamma-correct rendering is enabled. A new function 'Shader:sendColor' has been added, which has the same argument structure as 'Shader:send' but expects colors in the range of [0, 255]. When gamma-correct rendering is enabled it automatically gamma-corrects the given colors (by applying gammaToLinear to them.) New shader code functions have been added: gammaToLinear, linearToGamma, gammaCorrectColor, and unGammaCorrectColor. When gamma-correct rendering is enabled, the LOVE_GAMMA_CORRECT #define is set and gammaCorrectColor and unGammaCorrectColor are aliases for gammaToLinear and linearToGamma respectively, otherwise the functions do nothing. The new shader functions have 'precise' and 'fast' variants. If the LOVE_PRECISE_GAMMA define is set, then the normal functions default to the precise variants, otherwise they default to the fast variants. Currently the define is set in vertex shaders and not set in pixel shaders. The default per-vertex color is automatically gamma-corrected by LÖVE when gamma correct rendering is enabled, but any custom named per-vertex attribute specified with the new custom attribute Mesh functionality won't be, unless 'gammaCorrectColor' or similar functions are explicitly used (preferably inside the vertex shader code that has the custom attribute.)
182 lines
5.4 KiB
C++
182 lines
5.4 KiB
C++
/**
|
|
* Copyright (c) 2006-2015 LOVE Development Team
|
|
*
|
|
* This software is provided 'as-is', without any express or implied
|
|
* warranty. In no event will the authors be held liable for any damages
|
|
* arising from the use of this software.
|
|
*
|
|
* Permission is granted to anyone to use this software for any purpose,
|
|
* including commercial applications, and to alter it and redistribute it
|
|
* freely, subject to the following restrictions:
|
|
*
|
|
* 1. The origin of this software must not be misrepresented; you must not
|
|
* claim that you wrote the original software. If you use this software
|
|
* in a product, an acknowledgment in the product documentation would be
|
|
* appreciated but is not required.
|
|
* 2. Altered source versions must be plainly marked as such, and must not be
|
|
* misrepresented as being the original software.
|
|
* 3. This notice may not be removed or altered from any source distribution.
|
|
**/
|
|
|
|
#ifndef LOVE_GRAPHICS_OPENGL_CANVAS_H
|
|
#define LOVE_GRAPHICS_OPENGL_CANVAS_H
|
|
|
|
#include "common/config.h"
|
|
#include "graphics/Color.h"
|
|
#include "image/Image.h"
|
|
#include "image/ImageData.h"
|
|
#include "common/Matrix.h"
|
|
#include "common/StringMap.h"
|
|
#include "common/int.h"
|
|
#include "graphics/Texture.h"
|
|
#include "graphics/Volatile.h"
|
|
#include "OpenGL.h"
|
|
|
|
namespace love
|
|
{
|
|
namespace graphics
|
|
{
|
|
namespace opengl
|
|
{
|
|
|
|
class Canvas : public Texture, public Volatile
|
|
{
|
|
public:
|
|
|
|
// Different Canvas render target formats.
|
|
enum Format
|
|
{
|
|
FORMAT_NORMAL, // Usually SRGB, RGBA8 or a similar fallback. Always supported.
|
|
FORMAT_HDR, // Usually RGBA16F. Not always supported.
|
|
FORMAT_RGBA4, // RGBA with 4 bits per channel.
|
|
FORMAT_RGB5A1, // RGB with 5 bits per channel, and A with 1 bit.
|
|
FORMAT_RGB565, // RGB with 5, 6, and 5 bits each, respectively.
|
|
FORMAT_R8, // Single (red) 8-bit channel.
|
|
FORMAT_RG8, // Two-channel (red and green) with 8 bits per channel.
|
|
FORMAT_RGBA8, // RGBA with 8 bits per channel.
|
|
FORMAT_RGB10A2, // RGB with 10 bits each, and A with 2 bits.
|
|
FORMAT_RG11B10F, // Floating point [0, +inf]. RG with 11 FP bits each, and B with 10 FP bits.
|
|
FORMAT_R16F, // Floating point [-inf, +inf]. R with 16 FP bits.
|
|
FORMAT_RG16F, // Floating point [-inf, +inf]. RG with 16 FP bits per channel.
|
|
FORMAT_RGBA16F, // Floating point [-inf, +inf]. RGBA with 16 FP bits per channel.
|
|
FORMAT_R32F, // Floating point [-inf, +inf]. R with 32 FP bits.
|
|
FORMAT_RG32F, // Floating point [-inf, +inf]. RG with 32 FP bits per channel.
|
|
FORMAT_RGBA32F, // Floating point [-inf, +inf]. RGBA with 32 FP bits per channel.
|
|
FORMAT_SRGB, // sRGB with 8 bits per channel, plus 8 bit linear A.
|
|
FORMAT_MAX_ENUM
|
|
};
|
|
|
|
Canvas(int width, int height, Format format = FORMAT_NORMAL, int msaa = 0);
|
|
virtual ~Canvas();
|
|
|
|
// Implements Volatile.
|
|
virtual bool loadVolatile();
|
|
virtual void unloadVolatile();
|
|
|
|
// Implements Drawable.
|
|
virtual void draw(float x, float y, float angle, float sx, float sy, float ox, float oy, float kx, float ky);
|
|
|
|
// Implements Texture.
|
|
virtual void drawq(Quad *quad, float x, float y, float angle, float sx, float sy, float ox, float oy, float kx, float ky);
|
|
virtual void setFilter(const Texture::Filter &f);
|
|
virtual bool setWrap(const Texture::Wrap &w);
|
|
virtual const void *getHandle() const;
|
|
|
|
/**
|
|
* @param canvases A list of other canvases to temporarily attach to this one,
|
|
* to allow drawing to multiple canvases at once.
|
|
**/
|
|
void startGrab(const std::vector<Canvas *> &canvases);
|
|
void startGrab();
|
|
void stopGrab(bool switchingToOtherCanvas = false);
|
|
|
|
/**
|
|
* Create and attach a stencil buffer to this Canvas' framebuffer, if necessary.
|
|
**/
|
|
bool checkCreateStencil();
|
|
|
|
love::image::ImageData *newImageData(love::image::Image *image, int x, int y, int w, int h);
|
|
|
|
inline const std::vector<Canvas *> &getAttachedCanvases() const
|
|
{
|
|
return attachedCanvases;
|
|
}
|
|
|
|
inline GLenum getStatus() const
|
|
{
|
|
return status;
|
|
}
|
|
|
|
inline Format getTextureFormat() const
|
|
{
|
|
return format;
|
|
}
|
|
|
|
inline int getMSAA() const
|
|
{
|
|
return actual_samples;
|
|
}
|
|
|
|
static bool isSupported();
|
|
static bool isMultiCanvasSupported();
|
|
static bool isMultiFormatMultiCanvasSupported();
|
|
static bool isFormatSupported(Format format);
|
|
|
|
static Canvas *current;
|
|
|
|
// The viewport dimensions of the system (default) framebuffer.
|
|
static OpenGL::Viewport systemViewport;
|
|
|
|
// Whether the main screen should have linear -> sRGB conversions enabled.
|
|
static bool screenHasSRGB;
|
|
|
|
static int canvasCount;
|
|
|
|
static bool getConstant(const char *in, Format &out);
|
|
static bool getConstant(Format in, const char *&out);
|
|
|
|
private:
|
|
|
|
void setupGrab();
|
|
|
|
bool createMSAAFBO(GLenum internalformat);
|
|
bool resolveMSAA(bool restoreprev);
|
|
|
|
void drawv(const Matrix4 &t, const Vertex *v);
|
|
|
|
static Format getSizedFormat(Format format);
|
|
static void convertFormat(Format format, GLenum &internalformat, GLenum &externalformat, GLenum &type);
|
|
static size_t getFormatBitsPerPixel(Format format);
|
|
|
|
GLuint fbo;
|
|
GLuint resolve_fbo;
|
|
|
|
GLuint texture;
|
|
GLuint msaa_buffer;
|
|
GLuint depth_stencil;
|
|
|
|
Format format;
|
|
|
|
GLenum status;
|
|
|
|
std::vector<Canvas *> attachedCanvases;
|
|
|
|
int requested_samples;
|
|
int actual_samples;
|
|
|
|
size_t texture_memory;
|
|
|
|
static bool supportedFormats[FORMAT_MAX_ENUM];
|
|
static bool checkedFormats[FORMAT_MAX_ENUM];
|
|
|
|
static StringMap<Format, FORMAT_MAX_ENUM>::Entry formatEntries[];
|
|
static StringMap<Format, FORMAT_MAX_ENUM> formats;
|
|
|
|
}; // Canvas
|
|
|
|
} // opengl
|
|
} // graphics
|
|
} // love
|
|
|
|
#endif // LOVE_GRAPHICS_OPENGL_CANVAS_H
|