mirror of https://github.com/bjornbytes/lovr.git
Refactor GL extension code;
This commit is contained in:
parent
265a81c411
commit
613b1ea67f
|
@ -52,7 +52,7 @@ Font* lovrFontCreate(FontData* fontData) {
|
|||
font->texture = lovrTextureCreate(textureData);
|
||||
lovrTextureSetWrap(font->texture, WRAP_CLAMP, WRAP_CLAMP);
|
||||
|
||||
if (GLAD_GL_VERSION_3_0) {
|
||||
if (lovrGraphicsIsSupported(FEATURE_SWIZZLE)) {
|
||||
int swizzle[4] = { GL_RED, GL_RED, GL_RED, GL_GREEN };
|
||||
glTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_RGBA, swizzle);
|
||||
}
|
||||
|
@ -292,11 +292,7 @@ void lovrFontAddGlyph(Font* font, Glyph* glyph) {
|
|||
|
||||
// Paste glyph into texture
|
||||
lovrGraphicsBindTexture(font->texture);
|
||||
if (GLAD_GL_VERSION_3_0 || GLAD_GL_ARB_texture_rg || GLAD_GL_EXT_texture_rg) {
|
||||
glTexSubImage2D(GL_TEXTURE_2D, 0, atlas->x, atlas->y, glyph->w, glyph->h, GL_RG, GL_UNSIGNED_BYTE, glyph->data);
|
||||
} else {
|
||||
glTexSubImage2D(GL_TEXTURE_2D, 0, atlas->x, atlas->y, glyph->w, glyph->h, GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, glyph->data);
|
||||
}
|
||||
glTexSubImage2D(GL_TEXTURE_2D, 0, atlas->x, atlas->y, glyph->w, glyph->h, lovrTextureGetGLFormat(FORMAT_RG), GL_UNSIGNED_BYTE, glyph->data);
|
||||
|
||||
// Advance atlas cursor
|
||||
atlas->x += glyph->w + atlas->padding;
|
||||
|
|
|
@ -26,8 +26,10 @@ static void onCloseWindow(GLFWwindow* window) {
|
|||
|
||||
void lovrGraphicsInit() {
|
||||
#ifdef EMSCRIPTEN
|
||||
#define loadGLLoader gladLoadGLES2Loader
|
||||
glfwWindowHint(GLFW_CLIENT_API, GLFW_OPENGL_ES_API);
|
||||
#else
|
||||
#define loadGLLoader gladLoadGLLoader
|
||||
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
|
||||
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
|
||||
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
|
||||
|
@ -36,29 +38,22 @@ void lovrGraphicsInit() {
|
|||
glfwWindowHint(GLFW_RESIZABLE, GL_FALSE);
|
||||
#endif
|
||||
|
||||
// Create window
|
||||
const char* title = lovrFilesystemGetIdentity();
|
||||
title = title ? title : "LÖVR";
|
||||
state.window = glfwCreateWindow(800, 600, title, NULL, NULL);
|
||||
|
||||
state.window = glfwCreateWindow(800, 600, title ? title : "LÖVR", NULL, NULL);
|
||||
if (!state.window) {
|
||||
glfwTerminate();
|
||||
error("Could not create window");
|
||||
}
|
||||
|
||||
// Initialize all the things
|
||||
glfwMakeContextCurrent(state.window);
|
||||
glfwSetWindowCloseCallback(state.window, onCloseWindow);
|
||||
|
||||
#ifdef EMSCRIPTEN
|
||||
gladLoadGLES2Loader((GLADloadproc) glfwGetProcAddress);
|
||||
#else
|
||||
gladLoadGLLoader((GLADloadproc) glfwGetProcAddress);
|
||||
#endif
|
||||
|
||||
glfwSetTime(0);
|
||||
loadGLLoader((GLADloadproc) glfwGetProcAddress);
|
||||
glEnable(GL_BLEND);
|
||||
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||
glPixelStorei(GL_UNPACK_ALIGNMENT, 2);
|
||||
|
||||
if (GLAD_GL_VERSION_3_0) {
|
||||
glfwSwapInterval(0);
|
||||
glEnable(GL_LINE_SMOOTH);
|
||||
|
@ -71,7 +66,7 @@ void lovrGraphicsInit() {
|
|||
state.activeTexture = NULL;
|
||||
glGenBuffers(1, &state.shapeBuffer);
|
||||
glGenBuffers(1, &state.shapeIndexBuffer);
|
||||
if (GLAD_GL_VERSION_3_0) {
|
||||
if (lovrGraphicsIsSupported(FEATURE_VAO)) {
|
||||
glGenVertexArrays(1, &state.shapeArray);
|
||||
}
|
||||
vec_init(&state.shapeData);
|
||||
|
@ -89,6 +84,7 @@ void lovrGraphicsInit() {
|
|||
state.defaultTexture = lovrTextureCreate(lovrTextureDataGetBlank(1, 1, 0xff, FORMAT_RGBA));
|
||||
|
||||
// System Limits
|
||||
glGetIntegerv(GL_MAX_TEXTURE_SIZE, &state.maxTextureSize);
|
||||
if (GLAD_GL_VERSION_2_0) {
|
||||
float pointSizes[2];
|
||||
glGetFloatv(GL_POINT_SIZE_RANGE, pointSizes);
|
||||
|
@ -99,8 +95,6 @@ void lovrGraphicsInit() {
|
|||
state.maxTextureMSAA = 1;
|
||||
}
|
||||
|
||||
glGetIntegerv(GL_MAX_TEXTURE_SIZE, &state.maxTextureSize);
|
||||
|
||||
// State
|
||||
state.depthTest = -1;
|
||||
lovrGraphicsReset();
|
||||
|
@ -123,7 +117,7 @@ void lovrGraphicsDestroy() {
|
|||
lovrRelease(&state.defaultTexture->ref);
|
||||
glDeleteBuffers(1, &state.shapeBuffer);
|
||||
glDeleteBuffers(1, &state.shapeIndexBuffer);
|
||||
if (GLAD_GL_VERSION_3_0) {
|
||||
if (lovrGraphicsIsSupported(FEATURE_VAO)) {
|
||||
glDeleteVertexArrays(1, &state.shapeArray);
|
||||
}
|
||||
vec_deinit(&state.shapeData);
|
||||
|
@ -227,7 +221,7 @@ void lovrGraphicsSetBlendMode(BlendMode mode, BlendAlphaMode alphaMode) {
|
|||
break;
|
||||
|
||||
case BLEND_LIGHTEN:
|
||||
if (GLAD_GL_VERSION_2_0 || GLAD_GL_EXT_blend_minmax) {
|
||||
if (lovrGraphicsIsSupported(FEATURE_LIGHTEN)) {
|
||||
glBlendEquation(GL_MAX);
|
||||
glBlendFuncSeparate(srcRGB, GL_ZERO, GL_ONE, GL_ZERO);
|
||||
} else {
|
||||
|
@ -236,7 +230,7 @@ void lovrGraphicsSetBlendMode(BlendMode mode, BlendAlphaMode alphaMode) {
|
|||
break;
|
||||
|
||||
case BLEND_DARKEN:
|
||||
if (GLAD_GL_VERSION_2_0 || GLAD_GL_EXT_blend_minmax) {
|
||||
if (lovrGraphicsIsSupported(FEATURE_LIGHTEN)) {
|
||||
glBlendEquation(GL_MIN);
|
||||
glBlendFuncSeparate(srcRGB, GL_ZERO, GL_ONE, GL_ZERO);
|
||||
} else {
|
||||
|
@ -397,7 +391,7 @@ float lovrGraphicsGetPointSize() {
|
|||
}
|
||||
|
||||
void lovrGraphicsSetPointSize(float size) {
|
||||
if (GLAD_GL_VERSION_2_0) {
|
||||
if (lovrGraphicsIsSupported(FEATURE_POINT_SIZE)) {
|
||||
state.pointSize = size;
|
||||
glPointSize(size);
|
||||
}
|
||||
|
@ -446,7 +440,7 @@ int lovrGraphicsIsWireframe() {
|
|||
}
|
||||
|
||||
void lovrGraphicsSetWireframe(int wireframe) {
|
||||
if (GLAD_GL_VERSION_3_0 && state.isWireframe != wireframe) {
|
||||
if (lovrGraphicsIsSupported(FEATURE_WIREFRAME) && state.isWireframe != wireframe) {
|
||||
state.isWireframe = wireframe;
|
||||
glPolygonMode(GL_FRONT_AND_BACK, wireframe ? GL_LINE : GL_FILL);
|
||||
}
|
||||
|
@ -473,6 +467,20 @@ float lovrGraphicsGetSystemLimit(GraphicsLimit limit) {
|
|||
}
|
||||
}
|
||||
|
||||
int lovrGraphicsIsSupported(GraphicsFeature feature) {
|
||||
switch (feature) {
|
||||
case FEATURE_LIGHTEN: return GLAD_GL_VERSION_2_0 || GLAD_GL_EXT_blend_minmax;
|
||||
case FEATURE_MAPPED_BUFFERS: return GLAD_GL_VERSION_3_0 || GLAD_GL_ARB_map_buffer_range;
|
||||
case FEATURE_POINT_SIZE: return GLAD_GL_VERSION_2_0;
|
||||
case FEATURE_SHADER_INTS: return GLAD_GL_VERSION_2_0;
|
||||
case FEATURE_SWIZZLE: return GLAD_GL_VERSION_3_0;
|
||||
case FEATURE_TEXTURE_RG: return GLAD_GL_VERSION_3_0 || GLAD_GL_ARB_texture_rg || GLAD_GL_EXT_texture_rg;
|
||||
case FEATURE_TEXTURE_FANCY_WRAPS: return !GLAD_GL_ES_VERSION_2_0;
|
||||
case FEATURE_VAO: return GLAD_GL_VERSION_3_0;
|
||||
case FEATURE_WIREFRAME: return GLAD_GL_VERSION_3_0;
|
||||
}
|
||||
}
|
||||
|
||||
void lovrGraphicsPushCanvas() {
|
||||
if (++state.canvas >= MAX_CANVASES) {
|
||||
error("Canvas overflow");
|
||||
|
@ -553,7 +561,7 @@ void lovrGraphicsDrawPrimitive(GLenum mode, int hasNormals, int hasTexCoords, in
|
|||
int strideBytes = stride * sizeof(float);
|
||||
|
||||
lovrGraphicsPrepare();
|
||||
if (GLAD_GL_VERSION_3_0) {
|
||||
if (lovrGraphicsIsSupported(FEATURE_VAO)) {
|
||||
glBindVertexArray(state.shapeArray);
|
||||
}
|
||||
glBindBuffer(GL_ARRAY_BUFFER, state.shapeBuffer);
|
||||
|
@ -584,7 +592,7 @@ void lovrGraphicsDrawPrimitive(GLenum mode, int hasNormals, int hasTexCoords, in
|
|||
glDrawArrays(mode, 0, state.shapeData.length / stride);
|
||||
}
|
||||
|
||||
if (GLAD_GL_VERSION_3_0) {
|
||||
if (lovrGraphicsIsSupported(FEATURE_VAO)) {
|
||||
glBindVertexArray(0);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -55,6 +55,18 @@ typedef enum {
|
|||
LIMIT_TEXTURE_MSAA
|
||||
} GraphicsLimit;
|
||||
|
||||
typedef enum {
|
||||
FEATURE_LIGHTEN,
|
||||
FEATURE_MAPPED_BUFFERS,
|
||||
FEATURE_POINT_SIZE,
|
||||
FEATURE_SHADER_INTS,
|
||||
FEATURE_SWIZZLE,
|
||||
FEATURE_TEXTURE_RG,
|
||||
FEATURE_TEXTURE_FANCY_WRAPS,
|
||||
FEATURE_VAO,
|
||||
FEATURE_WIREFRAME
|
||||
} GraphicsFeature;
|
||||
|
||||
typedef struct {
|
||||
int x;
|
||||
int y;
|
||||
|
@ -150,6 +162,7 @@ void lovrGraphicsSetWireframe(int wireframe);
|
|||
int lovrGraphicsGetWidth();
|
||||
int lovrGraphicsGetHeight();
|
||||
float lovrGraphicsGetSystemLimit(GraphicsLimit limit);
|
||||
int lovrGraphicsIsSupported(GraphicsFeature feature);
|
||||
void lovrGraphicsPushCanvas();
|
||||
void lovrGraphicsPopCanvas();
|
||||
void lovrGraphicsSetViewport(int x, int y, int w, int h);
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
|
||||
static void lovrMeshBindAttributes(Mesh* mesh) {
|
||||
Shader* shader = lovrGraphicsGetShader();
|
||||
if (!shader || (shader == mesh->lastShader && !mesh->attributesDirty && GLAD_GL_VERSION_3_0)) {
|
||||
if (!shader || (shader == mesh->lastShader && !mesh->attributesDirty && lovrGraphicsIsSupported(FEATURE_VAO))) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -23,7 +23,7 @@ static void lovrMeshBindAttributes(Mesh* mesh) {
|
|||
glEnableVertexAttribArray(location);
|
||||
|
||||
if (attribute.type == MESH_INT) {
|
||||
if (GLAD_GL_ES_VERSION_2_0) {
|
||||
if (lovrGraphicsIsSupported(FEATURE_SHADER_INTS)) {
|
||||
error("Integer attributes are not supported on this platform.");
|
||||
} else {
|
||||
glVertexAttribIPointer(location, attribute.count, attribute.type, mesh->stride, (void*) offset);
|
||||
|
@ -92,11 +92,11 @@ Mesh* lovrMeshCreate(int count, MeshFormat* format, MeshDrawMode drawMode, MeshU
|
|||
glGenBuffers(1, &mesh->ibo);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, mesh->vbo);
|
||||
glBufferData(GL_ARRAY_BUFFER, mesh->count * mesh->stride, NULL, mesh->usage);
|
||||
if (GLAD_GL_VERSION_3_0) {
|
||||
if (lovrGraphicsIsSupported(FEATURE_VAO)) {
|
||||
glGenVertexArrays(1, &mesh->vao);
|
||||
}
|
||||
|
||||
if (!GLAD_GL_VERSION_3_0 && !GL_ARB_map_buffer_range) {
|
||||
if (!lovrGraphicsIsSupported(FEATURE_MAPPED_BUFFERS)) {
|
||||
mesh->data = malloc(mesh->count * mesh->stride);
|
||||
}
|
||||
|
||||
|
@ -110,7 +110,7 @@ void lovrMeshDestroy(const Ref* ref) {
|
|||
}
|
||||
glDeleteBuffers(1, &mesh->vbo);
|
||||
glDeleteBuffers(1, &mesh->ibo);
|
||||
if (GLAD_GL_VERSION_3_0) {
|
||||
if (lovrGraphicsIsSupported(FEATURE_VAO)) {
|
||||
glDeleteVertexArrays(1, &mesh->vao);
|
||||
}
|
||||
vec_deinit(&mesh->map);
|
||||
|
@ -131,7 +131,7 @@ void lovrMeshDraw(Mesh* mesh, mat4 transform) {
|
|||
lovrGraphicsBindTexture(mesh->texture);
|
||||
lovrGraphicsPrepare();
|
||||
|
||||
if (GLAD_GL_VERSION_3_0) {
|
||||
if (lovrGraphicsIsSupported(FEATURE_VAO)) {
|
||||
glBindVertexArray(mesh->vao);
|
||||
}
|
||||
|
||||
|
@ -266,7 +266,7 @@ void lovrMeshSetTexture(Mesh* mesh, Texture* texture) {
|
|||
}
|
||||
|
||||
void* lovrMeshMap(Mesh* mesh, int start, int count) {
|
||||
if (!GLAD_GL_VERSION_3_0 && !GLAD_GL_ARB_map_buffer_range) {
|
||||
if (!lovrGraphicsIsSupported(FEATURE_MAPPED_BUFFERS)) {
|
||||
mesh->isMapped = 1;
|
||||
mesh->mapStart = start;
|
||||
mesh->mapCount = count;
|
||||
|
@ -287,7 +287,7 @@ void* lovrMeshMap(Mesh* mesh, int start, int count) {
|
|||
}
|
||||
|
||||
void lovrMeshUnmap(Mesh* mesh) {
|
||||
if (!GLAD_GL_VERSION_3_0 && !GLAD_GL_ARB_map_buffer_range) {
|
||||
if (!lovrGraphicsIsSupported(FEATURE_MAPPED_BUFFERS)) {
|
||||
mesh->isMapped = 0;
|
||||
int start = mesh->mapStart * mesh->stride;
|
||||
int count = mesh->mapCount * mesh->stride;
|
||||
|
|
|
@ -5,27 +5,13 @@
|
|||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
|
||||
static GLenum getGLFormat(TextureFormat format) {
|
||||
GLenum lovrTextureGetGLFormat(TextureFormat format) {
|
||||
switch (format) {
|
||||
case FORMAT_RED:
|
||||
if (GLAD_GL_VERSION_3_0 || GLAD_GL_ARB_texture_rg || GLAD_GL_EXT_texture_rg) {
|
||||
return GL_RED;
|
||||
} else {
|
||||
return GL_LUMINANCE;
|
||||
}
|
||||
|
||||
case FORMAT_RG:
|
||||
if (GLAD_GL_VERSION_3_0 || GLAD_GL_ARB_texture_rg || GLAD_GL_EXT_texture_rg) {
|
||||
return GL_RG;
|
||||
} else {
|
||||
return GL_LUMINANCE_ALPHA;
|
||||
}
|
||||
|
||||
case FORMAT_RED: return lovrGraphicsIsSupported(FEATURE_TEXTURE_RG) ? GL_RED : GL_LUMINANCE;
|
||||
case FORMAT_RG: return lovrGraphicsIsSupported(FEATURE_TEXTURE_RG) ? GL_RG : GL_LUMINANCE_ALPHA;
|
||||
case FORMAT_RGB: return GL_RGB;
|
||||
case FORMAT_RGBA: return GL_RGBA;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
Texture* lovrTextureCreate(TextureData* textureData) {
|
||||
|
@ -158,7 +144,7 @@ void lovrTextureRefresh(Texture* texture) {
|
|||
TextureData* textureData = texture->textureData;
|
||||
int w = textureData->width;
|
||||
int h = textureData->height;
|
||||
GLenum format = getGLFormat(textureData->format);
|
||||
GLenum format = lovrTextureGetGLFormat(textureData->format);
|
||||
lovrGraphicsBindTexture(texture);
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, format, w, h, 0, format, GL_UNSIGNED_BYTE, textureData->data);
|
||||
}
|
||||
|
@ -190,7 +176,7 @@ void lovrTextureGetWrap(Texture* texture, WrapMode* horizontal, WrapMode* vertic
|
|||
}
|
||||
|
||||
void lovrTextureSetWrap(Texture* texture, WrapMode horizontal, WrapMode vertical) {
|
||||
if (GLAD_GL_ES_VERSION_2_0) {
|
||||
if (!lovrGraphicsIsSupported(FEATURE_TEXTURE_FANCY_WRAPS)) {
|
||||
horizontal = vertical = WRAP_CLAMP;
|
||||
}
|
||||
|
||||
|
|
|
@ -37,6 +37,8 @@ typedef struct {
|
|||
int msaa;
|
||||
} Texture;
|
||||
|
||||
GLenum lovrTextureGetGLFormat(TextureFormat format);
|
||||
|
||||
Texture* lovrTextureCreate(TextureData* textureData);
|
||||
Texture* lovrTextureCreateWithFramebuffer(TextureData* textureData, TextureProjection projection, int msaa);
|
||||
void lovrTextureDestroy(const Ref* ref);
|
||||
|
|
Loading…
Reference in New Issue