Begin OpenGL quarantine;

This commit is contained in:
bjorn 2018-07-07 16:54:07 -07:00
parent b7a43e1762
commit 89c8ee3d06
11 changed files with 136 additions and 110 deletions

View File

@ -1,4 +1,5 @@
#include "graphics/canvas.h"
#include "graphics/gpu.h"
#include "graphics/graphics.h"
#include "data/blob.h"
#include "util.h"
@ -30,7 +31,7 @@ Canvas* lovrCanvasCreate(int width, int height, TextureFormat format, CanvasFlag
// Framebuffer
glGenFramebuffers(1, &canvas->framebuffer);
glBindFramebuffer(GL_FRAMEBUFFER, canvas->framebuffer);
gpuBindFramebuffer(canvas->framebuffer);
// Color attachment
if (flags.msaa > 0) {
@ -66,15 +67,15 @@ Canvas* lovrCanvasCreate(int width, int height, TextureFormat format, CanvasFlag
// Resolve framebuffer
if (flags.msaa > 0) {
glGenFramebuffers(1, &canvas->resolveFramebuffer);
glBindFramebuffer(GL_FRAMEBUFFER, canvas->resolveFramebuffer);
gpuBindFramebuffer(canvas->resolveFramebuffer);
glBindTexture(GL_TEXTURE_2D, canvas->texture.id);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, canvas->texture.id, 0);
glBindFramebuffer(GL_FRAMEBUFFER, canvas->framebuffer);
gpuBindFramebuffer(canvas->framebuffer);
}
lovrAssert(glCheckFramebufferStatus(GL_FRAMEBUFFER) == GL_FRAMEBUFFER_COMPLETE, "Error creating Canvas");
lovrGraphicsClear(true, true, true, (Color) { 0, 0, 0, 0 }, 1., 0);
glBindFramebuffer(GL_FRAMEBUFFER, 0);
gpuBindFramebuffer(0);
return canvas;
}
@ -121,7 +122,7 @@ TextureData* lovrCanvasNewTextureData(Canvas* canvas) {
TextureData* textureData = lovrTextureDataGetBlank(canvas->texture.width, canvas->texture.height, 0, FORMAT_RGBA);
if (!textureData) return NULL;
lovrGraphicsBindFramebuffer(canvas->framebuffer);
gpuBindFramebuffer(canvas->framebuffer);
glReadPixels(0, 0, canvas->texture.width, canvas->texture.height, GL_RGBA, GL_UNSIGNED_BYTE, textureData->blob.data);
return textureData;

26
src/graphics/gpu.h Normal file
View File

@ -0,0 +1,26 @@
#include <stdint.h>
#include <stdbool.h>
#ifdef EMSCRIPTEN
#include <GLES3/gl3.h>
#include <GLES2/gl2ext.h>
#else
#include "lib/glad/glad.h"
#endif
#pragma once
typedef struct {
uint32_t shaderSwitches;
} GpuStats;
typedef void (*gpuProc)(void);
void gpuInit(bool srgb, gpuProc (*getProcAddress)(const char*));
void gpuPresent();
void gpuBindFramebuffer(uint32_t framebuffer);
void gpuBindIndexBuffer(uint32_t indexBuffer);
void gpuBindVertexArray(uint32_t vertexArray);
void gpuBindVertexBuffer(uint32_t vertexBuffer);
void gpuSetViewport(uint32_t viewport[4]);
void gpuUseProgram(uint32_t program);

View File

@ -110,7 +110,7 @@ void lovrGraphicsReset() {
void lovrGraphicsClear(bool clearColor, bool clearDepth, bool clearStencil, Color color, float depth, int stencil) {
Layer layer = state.layers[state.layer];
Canvas* canvas = state.canvasCount > 0 ? state.canvas[0] : layer.canvas;
lovrGraphicsBindFramebuffer(canvas ? canvas->framebuffer : 0);
gpuBindFramebuffer(canvas ? canvas->framebuffer : 0);
if (clearColor) {
gammaCorrectColor(&color);
@ -134,7 +134,7 @@ void lovrGraphicsPresent() {
glfwSwapBuffers(state.window);
state.stats.drawCalls = 0;
state.stats.shaderSwitches = 0;
state.program = -1; // Fixes a driver bug with instancing seen on macOS
gpuPresent();
}
void lovrGraphicsCreateWindow(int w, int h, bool fullscreen, int msaa, const char* title, const char* icon) {
@ -184,19 +184,9 @@ void lovrGraphicsCreateWindow(int w, int h, bool fullscreen, int msaa, const cha
#ifndef EMSCRIPTEN
}
gladLoadGLLoader((GLADloadproc) glfwGetProcAddress);
glfwSwapInterval(0);
glEnable(GL_LINE_SMOOTH);
glEnable(GL_PROGRAM_POINT_SIZE);
if (state.gammaCorrect) {
glEnable(GL_FRAMEBUFFER_SRGB);
} else {
glDisable(GL_FRAMEBUFFER_SRGB);
}
#endif
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
gpuInit(state.gammaCorrect, glfwGetProcAddress);
VertexFormat format;
vertexFormatInit(&format);
vertexFormatAppend(&format, "lovrPosition", ATTR_FLOAT, 3);
@ -316,7 +306,7 @@ void lovrGraphicsSetCanvas(Canvas** canvas, int count) {
if (count > 0) {
memcpy(state.canvas, canvas, count * sizeof(Canvas*));
lovrGraphicsBindFramebuffer(canvas[0]->framebuffer);
gpuBindFramebuffer(canvas[0]->framebuffer);
GLenum buffers[MAX_CANVASES];
for (int i = 0; i < count; i++) {
@ -1039,25 +1029,11 @@ void lovrGraphicsDraw(Mesh* mesh, mat4 transform, DefaultShader defaultShader, i
// Layer
Layer layer = state.layers[state.layer];
Canvas* canvas = state.canvasCount > 0 ? state.canvas[0] : layer.canvas;
lovrGraphicsBindFramebuffer(canvas ? canvas->framebuffer : 0);
uint32_t viewport[4];
if (state.canvasCount > 0) {
viewport[0] = 0;
viewport[1] = 0;
viewport[2] = state.canvas[0]->texture.width;
viewport[3] = state.canvas[0]->texture.height;
} else {
viewport[0] = layer.viewport[0];
viewport[1] = layer.viewport[1];
viewport[2] = layer.viewport[2];
viewport[3] = layer.viewport[3];
}
if (memcmp(state.viewport, viewport, 4 * sizeof(uint32_t))) {
memcpy(state.viewport, viewport, 4 * sizeof(uint32_t));
glViewport(viewport[0], viewport[1], viewport[2], viewport[3]);
}
gpuBindFramebuffer(canvas ? canvas->framebuffer : 0);
gpuSetViewport(state.canvasCount > 0 ?
(uint32_t[4]) { 0, 0, state.canvas[0]->texture.width, state.canvas[0]->texture.height } :
layer.viewport
);
// Transforms
if (transform) {
@ -1140,7 +1116,7 @@ void lovrGraphicsDraw(Mesh* mesh, mat4 transform, DefaultShader defaultShader, i
lovrShaderSetTexture(shader, lovrShaderTextureUniforms[i], &texture, 1);
}
lovrGraphicsUseProgram(shader->program);
gpuUseProgram(shader->program);
lovrShaderBind(shader);
lovrMeshBind(mesh, shader);
@ -1231,39 +1207,3 @@ Material* lovrGraphicsGetDefaultMaterial() {
return state.defaultMaterial;
}
void lovrGraphicsUseProgram(uint32_t program) {
if (state.program != program) {
state.program = program;
glUseProgram(program);
state.stats.shaderSwitches++;
}
}
void lovrGraphicsBindFramebuffer(uint32_t framebuffer) {
if (state.framebuffer != framebuffer) {
state.framebuffer = framebuffer;
glBindFramebuffer(GL_FRAMEBUFFER, framebuffer);
}
}
void lovrGraphicsBindVertexArray(uint32_t vertexArray) {
if (state.vertexArray != vertexArray) {
state.vertexArray = vertexArray;
glBindVertexArray(vertexArray);
}
}
void lovrGraphicsBindVertexBuffer(uint32_t vertexBuffer) {
if (state.vertexBuffer != vertexBuffer) {
state.vertexBuffer = vertexBuffer;
glBindBuffer(GL_ARRAY_BUFFER, vertexBuffer);
}
}
void lovrGraphicsBindIndexBuffer(uint32_t indexBuffer) {
if (state.indexBuffer != indexBuffer) {
state.indexBuffer = indexBuffer;
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indexBuffer);
}
}

View File

@ -1,3 +1,4 @@
#include "graphics/gpu.h"
#include "graphics/canvas.h"
#include "graphics/font.h"
#include "graphics/material.h"
@ -75,7 +76,7 @@ typedef struct {
float projection[16];
float view[16];
Canvas* canvas;
int viewport[4];
uint32_t viewport[4];
} Layer;
typedef struct {
@ -126,12 +127,6 @@ typedef struct {
Texture* textures[MAX_TEXTURES];
bool stencilEnabled;
bool stencilWriting;
uint32_t program;
uint32_t framebuffer;
uint32_t viewport[4];
uint32_t vertexArray;
uint32_t vertexBuffer;
uint32_t indexBuffer;
GraphicsStats stats;
} GraphicsState;
@ -213,8 +208,3 @@ void lovrGraphicsSetViewport(uint32_t x, uint32_t y, uint32_t width, uint32_t he
Texture* lovrGraphicsGetTexture(int slot);
void lovrGraphicsBindTexture(Texture* texture, GLenum type, int slot);
Material* lovrGraphicsGetDefaultMaterial();
void lovrGraphicsUseProgram(uint32_t program);
void lovrGraphicsBindFramebuffer(uint32_t framebuffer);
void lovrGraphicsBindVertexArray(uint32_t vao);
void lovrGraphicsBindVertexBuffer(uint32_t vbo);
void lovrGraphicsBindIndexBuffer(uint32_t ibo);

View File

@ -1,4 +1,5 @@
#include "graphics/mesh.h"
#include "graphics/gpu.h"
#include "graphics/graphics.h"
#include "math/math.h"
#include <limits.h>
@ -25,7 +26,7 @@ Mesh* lovrMeshCreate(uint32_t count, VertexFormat format, MeshDrawMode drawMode,
glGenBuffers(1, &mesh->vbo);
glGenBuffers(1, &mesh->ibo);
lovrGraphicsBindVertexBuffer(mesh->vbo);
gpuBindVertexBuffer(mesh->vbo);
glBufferData(GL_ARRAY_BUFFER, count * format.stride, NULL, mesh->usage);
glGenVertexArrays(1, &mesh->vao);
@ -87,11 +88,11 @@ void lovrMeshBind(Mesh* mesh, Shader* shader) {
MeshAttachment layout[MAX_ATTACHMENTS];
memset(layout, 0, MAX_ATTACHMENTS * sizeof(MeshAttachment));
lovrGraphicsBindVertexArray(mesh->vao);
gpuBindVertexArray(mesh->vao);
lovrMeshUnmapVertices(mesh);
lovrMeshUnmapIndices(mesh);
if (mesh->indexCount > 0) {
lovrGraphicsBindIndexBuffer(mesh->ibo);
gpuBindIndexBuffer(mesh->ibo);
}
while ((key = map_next(&mesh->attachments, &iter)) != NULL) {
@ -128,7 +129,7 @@ void lovrMeshBind(Mesh* mesh, Shader* shader) {
}
if (previous.mesh != current.mesh || previous.attributeIndex != current.attributeIndex) {
lovrGraphicsBindVertexBuffer(current.mesh->vbo);
gpuBindVertexBuffer(current.mesh->vbo);
VertexFormat* format = &current.mesh->format;
Attribute attribute = format->attributes[current.attributeIndex];
switch (attribute.type) {
@ -225,7 +226,7 @@ void lovrMeshUnmapVertices(Mesh* mesh) {
}
size_t stride = mesh->format.stride;
lovrGraphicsBindVertexBuffer(mesh->vbo);
gpuBindVertexBuffer(mesh->vbo);
if (mesh->usage == MESH_STREAM) {
glBufferData(GL_ARRAY_BUFFER, mesh->count * stride, mesh->data.bytes, mesh->usage);
} else {
@ -263,8 +264,8 @@ IndexPointer lovrMeshWriteIndices(Mesh* mesh, uint32_t count, size_t size) {
return (IndexPointer) { .raw = NULL };
}
lovrGraphicsBindVertexArray(mesh->vao);
lovrGraphicsBindIndexBuffer(mesh->ibo);
gpuBindVertexArray(mesh->vao);
gpuBindIndexBuffer(mesh->ibo);
mesh->mappedIndices = true;
if (mesh->indexCapacity < size * count) {
@ -282,14 +283,14 @@ void lovrMeshUnmapIndices(Mesh* mesh) {
}
mesh->mappedIndices = false;
lovrGraphicsBindIndexBuffer(mesh->ibo);
gpuBindIndexBuffer(mesh->ibo);
glBufferSubData(GL_ELEMENT_ARRAY_BUFFER, 0, mesh->indexCount * mesh->indexSize, mesh->indices.raw);
}
void lovrMeshResize(Mesh* mesh, uint32_t count) {
if (mesh->count < count) {
mesh->count = nextPo2(count);
lovrGraphicsBindVertexBuffer(mesh->vbo);
gpuBindVertexBuffer(mesh->vbo);
mesh->data.raw = realloc(mesh->data.raw, count * mesh->format.stride);
glBufferData(GL_ARRAY_BUFFER, count * mesh->format.stride, mesh->data.raw, mesh->usage);
}

View File

@ -1,7 +1,7 @@
#include "graphics/gpu.h"
#include "graphics/material.h"
#include "graphics/shader.h"
#include "data/vertexData.h"
#include "lib/glfw.h"
#include "lib/map/map.h"
#include "util.h"
#include <stdbool.h>

75
src/graphics/opengl.c Normal file
View File

@ -0,0 +1,75 @@
#include "graphics/gpu.h"
#include <string.h>
static struct {
uint32_t framebuffer;
uint32_t indexBuffer;
uint32_t program;
uint32_t vertexArray;
uint32_t vertexBuffer;
uint32_t viewport[4];
GpuStats stats;
} state;
void gpuInit(bool srgb, gpuProc (*getProcAddress)(const char*)) {
#ifndef EMSCRIPTEN
gladLoadGLLoader((GLADloadproc) getProcAddress);
glEnable(GL_LINE_SMOOTH);
glEnable(GL_PROGRAM_POINT_SIZE);
if (srgb) {
glEnable(GL_FRAMEBUFFER_SRGB);
} else {
glDisable(GL_FRAMEBUFFER_SRGB);
}
#endif
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
}
void gpuPresent() {
memset(&state.stats, 0, sizeof(state.stats));
}
void gpuBindFramebuffer(uint32_t framebuffer) {
if (state.framebuffer != framebuffer) {
state.framebuffer = framebuffer;
glBindFramebuffer(GL_FRAMEBUFFER, framebuffer);
}
}
void gpuBindIndexBuffer(uint32_t indexBuffer) {
if (state.indexBuffer != indexBuffer) {
state.indexBuffer = indexBuffer;
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indexBuffer);
}
}
void gpuBindVertexArray(uint32_t vertexArray) {
if (state.vertexArray != vertexArray) {
state.vertexArray = vertexArray;
glBindVertexArray(vertexArray);
}
}
void gpuBindVertexBuffer(uint32_t vertexBuffer) {
if (state.vertexBuffer != vertexBuffer) {
state.vertexBuffer = vertexBuffer;
glBindBuffer(GL_ARRAY_BUFFER, vertexBuffer);
}
}
void gpuSetViewport(uint32_t viewport[4]) {
if (memcmp(state.viewport, viewport, 4 * sizeof(uint32_t))) {
memcpy(state.viewport, viewport, 4 * sizeof(uint32_t));
glViewport(viewport[0], viewport[1], viewport[2], viewport[3]);
}
}
void gpuUseProgram(uint32_t program) {
if (state.program != program) {
state.program = program;
glUseProgram(program);
state.stats.shaderSwitches++;
}
}

View File

@ -1,4 +1,5 @@
#include "graphics/shader.h"
#include "graphics/gpu.h"
#include "graphics/graphics.h"
#include "math/math.h"
#include "resources/shaders.h"
@ -146,7 +147,7 @@ Shader* lovrShaderCreate(const char* vertexSource, const char* fragmentSource) {
uint32_t program = linkShaders(vertexShader, fragmentShader);
shader->program = program;
lovrGraphicsUseProgram(program);
gpuUseProgram(program);
glVertexAttrib4fv(LOVR_SHADER_VERTEX_COLOR, (float[4]) { 1., 1., 1., 1. });
glVertexAttribI4iv(LOVR_SHADER_BONES, (int[4]) { 0., 0., 0., 0. });
glVertexAttrib4fv(LOVR_SHADER_BONE_WEIGHTS, (float[4]) { 1., 0., 0., 0. });

View File

@ -1,6 +1,6 @@
#include "graphics/texture.h"
#include "graphics/gpu.h"
#include "lib/map/map.h"
#include "lib/glfw.h"
#include "util.h"
#include <stdbool.h>

View File

@ -1,5 +1,5 @@
#include "graphics/gpu.h"
#include "data/textureData.h"
#include "lib/glfw.h"
#include "util.h"
#include <stdbool.h>

View File

@ -1,16 +1,8 @@
#pragma once
#if EMSCRIPTEN
#define GLFW_INCLUDE_ES3
#define GLFW_INCLUDE_GLEXT
#elif __APPLE__
#define GLFW_INCLUDE_GLCOREARB
#elif _WIN32
#ifdef _WIN32
#define APIENTRY __stdcall
#endif
#ifndef EMSCRIPTEN
#include "glad/glad.h"
#endif
#include "graphics/gpu.h"
#include <GLFW/glfw3.h>