Yay all opengl is in opengl.c;

This commit is contained in:
bjorn 2018-07-17 14:53:21 -07:00
parent 2cf0e15eb0
commit f1f2c7b401
12 changed files with 92 additions and 87 deletions

View File

@ -46,6 +46,7 @@ const char* BlendModes[] = {
};
const char* CompareModes[] = {
[COMPARE_NONE] = "always",
[COMPARE_EQUAL] = "equal",
[COMPARE_NEQUAL] = "notequal",
[COMPARE_LESS] = "less",
@ -1107,7 +1108,7 @@ int l_lovrGraphicsNewTexture(lua_State* L) {
for (int i = 0; i < depth; i++) {
lua_rawgeti(L, 1, i + 1);
TextureData* textureData = luax_checktexturedata(L, -1);
lovrTextureReplacePixels(texture, textureData, i);
lovrTextureReplacePixels(texture, textureData, 0, 0, i);
lovrRelease(textureData);
lua_pop(L, 1);
}

View File

@ -62,7 +62,7 @@ int l_lovrTextureReplacePixels(lua_State* L) {
Texture* texture = luax_checktype(L, 1, Texture);
TextureData* textureData = luax_checktype(L, 2, TextureData);
int slice = luaL_optinteger(L, 3, 1);
lovrTextureReplacePixels(texture, textureData, slice - 1);
lovrTextureReplacePixels(texture, textureData, 0, 0, slice - 1);
return 0;
}

View File

@ -148,14 +148,14 @@ void lovrRasterizerLoadGlyph(Rasterizer* rasterizer, uint32_t character, Glyph*
glyph->dx = metrics->horiBearingX >> 6;
glyph->dy = metrics->horiBearingY >> 6;
glyph->advance = metrics->horiAdvance >> 6;
glyph->data = malloc(glyph->tw * glyph->th * 3 * sizeof(uint8_t));
glyph->data = lovrTextureDataGetBlank(glyph->tw, glyph->th, 0, FORMAT_RGB);
// Render SDF
float tx = GLYPH_PADDING + -glyph->dx;
float ty = GLYPH_PADDING + glyph->h - glyph->dy;
msShapeNormalize(shape);
msEdgeColoringSimple(shape, 3.0, 0);
msGenerateMSDF(glyph->data, glyph->tw, glyph->th, shape, 4., 1, 1, tx, ty);
msGenerateMSDF(glyph->data->blob.data, glyph->tw, glyph->th, shape, 4., 1, 1, tx, ty);
msShapeDestroy(shape);
}

View File

@ -1,4 +1,5 @@
#include "data/blob.h"
#include "data/textureData.h"
#include "lib/map/map.h"
#include "util.h"
#include <stdint.h>
@ -30,7 +31,7 @@ typedef struct {
int dx;
int dy;
int advance;
uint8_t* data;
TextureData* data;
} Glyph;
typedef map_t(Glyph) map_glyph_t;

View File

@ -19,8 +19,6 @@ bool lovrCanvasSupportsFormat(TextureFormat format);
Canvas* lovrCanvasCreate(int width, int height, TextureFormat format, CanvasFlags flags);
void lovrCanvasDestroy(void* ref);
uint32_t lovrCanvasGetId(Canvas* canvas); // FIXME temporary
void lovrCanvasBind(Canvas** canvases, int canvasCount);
void lovrCanvasResolve(Canvas* canvas);
TextureFormat lovrCanvasGetFormat(Canvas* canvas);
int lovrCanvasGetMSAA(Canvas* canvas);

View File

@ -10,8 +10,6 @@
#include <stdlib.h>
#include <stdio.h>
#include "graphics/opengl.h"
static float* lovrFontAlignLine(float* x, float* lineEnd, float width, HorizontalAlign halign) {
while(x < lineEnd) {
if (halign == ALIGN_CENTER) {
@ -277,8 +275,7 @@ void lovrFontAddGlyph(Font* font, Glyph* glyph) {
glyph->y = atlas->y;
// Paste glyph into texture
lovrGpuBindTexture(font->texture, 0);
glTexSubImage2D(GL_TEXTURE_2D, 0, atlas->x, atlas->y, glyph->tw, glyph->th, GL_RGB, GL_UNSIGNED_BYTE, glyph->data);
lovrTextureReplacePixels(font->texture, glyph->data, atlas->x, atlas->y, 0);
// Advance atlas cursor
atlas->x += glyph->tw + atlas->padding;

View File

@ -74,6 +74,7 @@ void lovrGraphicsCreateWindow(int w, int h, bool fullscreen, int msaa, const cha
glfwWindowHint(GLFW_REFRESH_RATE, mode->refreshRate);
}
state.msaa = msaa;
state.window = glfwCreateWindow(w ? w : mode->width, h ? h : mode->height, title, fullscreen ? monitor : NULL, NULL);
if (!state.window) {
glfwTerminate();
@ -105,6 +106,14 @@ void lovrGraphicsCreateWindow(int w, int h, bool fullscreen, int msaa, const cha
state.initialized = true;
}
void lovrGraphicsGetDimensions(int* width, int* height) {
glfwGetFramebufferSize(state.window, width, height);
}
int lovrGraphicsGetMSAA() {
return state.msaa;
}
void lovrGraphicsSetCamera(Camera* camera, bool clear) {
if (!camera) {
int width, height;
@ -127,10 +136,6 @@ void lovrGraphicsSetCamera(Camera* camera, bool clear) {
}
}
void lovrGraphicsGetDimensions(int* width, int* height) {
glfwGetFramebufferSize(state.window, width, height);
}
// State
void lovrGraphicsReset() {
@ -358,7 +363,7 @@ void lovrGraphicsClear(Color* color, float* depth, int* stencil) {
if (pipeline->canvasCount > 0) {
lovrGpuClear(pipeline->canvas, pipeline->canvasCount, color, depth, stencil);
} else {
lovrGpuClear(&state.camera.canvas, 1, color, depth, stencil);
lovrGpuClear(&state.camera.canvas, state.camera.canvas != NULL, color, depth, stencil);
}
}

View File

@ -142,6 +142,7 @@ typedef struct {
typedef struct {
bool initialized;
bool gammaCorrect;
int msaa;
void* window;
Camera camera;
Shader* defaultShaders[MAX_DEFAULT_SHADERS];
@ -161,6 +162,7 @@ void lovrGraphicsDestroy();
void lovrGraphicsPresent();
void lovrGraphicsCreateWindow(int w, int h, bool fullscreen, int msaa, const char* title, const char* icon);
void lovrGraphicsGetDimensions(int* width, int* height);
int lovrGraphicsGetMSAA();
void lovrGraphicsSetCamera(Camera* camera, bool clear);
GraphicsLimits lovrGraphicsGetLimits();
GraphicsStats lovrGraphicsGetStats();
@ -238,4 +240,4 @@ void lovrGpuDraw(DrawCommand* command);
void lovrGpuPresent();
void lovrGpuBindTexture(Texture* texture, int slot);
Texture* lovrGpuGetTexture(int slot);
void lovrGpuRebindTexture(int slot);

View File

@ -43,6 +43,8 @@ static struct {
bool stencilWriting;
Winding winding;
bool wireframe;
Canvas* canvas[MAX_CANVASES];
int canvasCount;
uint32_t framebuffer;
uint32_t indexBuffer;
uint32_t program;
@ -337,6 +339,13 @@ void lovrGpuBindTexture(Texture* texture, int slot) {
}
}
void lovrGpuRebindTexture(int slot) {
lovrAssert(slot >= 0 && slot < MAX_TEXTURES, "Invalid texture slot %d", slot);
Texture* texture = state.textures[slot];
glActiveTexture(GL_TEXTURE0 + slot);
glBindTexture(texture->glType, lovrTextureGetId(texture));
}
static void lovrGpuBindVertexArray(uint32_t vertexArray) {
if (state.vertexArray != vertexArray) {
state.vertexArray = vertexArray;
@ -351,11 +360,6 @@ static void lovrGpuBindVertexBuffer(uint32_t vertexBuffer) {
}
}
Texture* lovrGpuGetTexture(int slot) {
lovrAssert(slot >= 0 && slot < MAX_TEXTURES, "Invalid texture slot %d", slot);
return state.textures[slot];
}
static void lovrGpuSetViewport(uint32_t viewport[4]) {
if (memcmp(state.viewport, viewport, 4 * sizeof(uint32_t))) {
memcpy(state.viewport, viewport, 4 * sizeof(uint32_t));
@ -387,17 +391,17 @@ void lovrGpuInit(bool srgb, gpuProc (*getProcAddress)(const char*)) {
state.srgb = srgb;
state.blendMode = -1;
state.blendAlphaMode = -1;
state.culling = -1;
state.depthEnabled = -1;
state.depthTest = -1;
state.depthWrite = -1;
state.lineWidth = -1;
state.stencilEnabled = -1;
state.stencilMode = -1;
state.stencilValue = -1;
state.culling = false;
state.depthEnabled = false;
state.depthTest = COMPARE_LESS;
state.depthWrite = true;
state.lineWidth = 1;
state.stencilEnabled = false;
state.stencilMode = COMPARE_NONE;
state.stencilValue = 0;
state.stencilWriting = false;
state.winding = -1;
state.wireframe = -1;
state.winding = WINDING_COUNTERCLOCKWISE;
state.wireframe = false;
}
void lovrGpuDestroy() {
@ -408,7 +412,7 @@ void lovrGpuDestroy() {
}
void lovrGpuClear(Canvas** canvas, int canvasCount, Color* color, float* depth, int* stencil) {
lovrGpuBindFramebuffer(canvasCount > 0 ? lovrCanvasGetId(canvas[0]) : 0);
lovrGpuBindFramebuffer(canvasCount > 0 ? canvas[0]->framebuffer : 0);
if (color) {
gammaCorrectColor(color);
@ -420,12 +424,18 @@ void lovrGpuClear(Canvas** canvas, int canvasCount, Color* color, float* depth,
}
if (depth) {
state.depthWrite = true;
glDepthMask(state.depthWrite);
glClearBufferfv(GL_DEPTH, 0, depth);
}
if (stencil) {
glClearBufferiv(GL_STENCIL, 0, stencil);
}
if (canvasCount > 0) {
lovrCanvasResolve(canvas[0]);
}
}
void lovrGraphicsStencil(StencilAction action, int replaceValue, StencilCallback callback, void* userdata) {
@ -551,7 +561,7 @@ void lovrGpuDraw(DrawCommand* command) {
// Line width
if (state.lineWidth != pipeline->lineWidth) {
state.lineWidth = state.lineWidth;
state.lineWidth = pipeline->lineWidth;
glLineWidth(state.lineWidth);
}
@ -661,18 +671,45 @@ void lovrGpuDraw(DrawCommand* command) {
}
// Canvas
Canvas** canvas = pipeline->canvasCount > 0 ? pipeline->canvas : &command->camera.canvas;
int canvasCount = pipeline->canvasCount > 0 ? pipeline->canvasCount : (command->camera.canvas != NULL);
if (memcmp(state.canvas, canvas, canvasCount * sizeof(Canvas*))) {
if (state.canvasCount > 0) {
lovrCanvasResolve(state.canvas[0]);
}
state.canvasCount = canvasCount;
if (canvasCount > 0) {
memcpy(state.canvas, canvas, canvasCount * sizeof(Canvas*));
lovrGpuBindFramebuffer(canvas[0]->framebuffer);
GLenum buffers[MAX_CANVASES];
for (int i = 0; i < canvasCount; i++) {
buffers[i] = GL_COLOR_ATTACHMENT0 + i;
glFramebufferTexture2D(GL_FRAMEBUFFER, buffers[i], GL_TEXTURE_2D, lovrTextureGetId((Texture*) canvas[i]), 0);
}
glDrawBuffers(canvasCount, buffers);
GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
lovrAssert(status != GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS, "All multicanvas canvases must have the same dimensions");
lovrAssert(status == GL_FRAMEBUFFER_COMPLETE, "Unable to bind framebuffer");
} else {
lovrGpuBindFramebuffer(0);
}
}
// Viewport
if (pipeline->canvasCount > 0) {
lovrCanvasBind(pipeline->canvas, pipeline->canvasCount);
int width = lovrTextureGetWidth((Texture*) pipeline->canvas);
int height = lovrTextureGetHeight((Texture*) pipeline->canvas);
int width = lovrTextureGetWidth((Texture*) pipeline->canvas[0]);
int height = lovrTextureGetHeight((Texture*) pipeline->canvas[0]);
lovrGpuSetViewport((uint32_t[4]) { 0, 0, width, height });
} else {
lovrCanvasBind(&command->camera.canvas, command->camera.canvas != NULL);
lovrGpuSetViewport(command->camera.viewport);
}
// Shader
lovrGpuUseProgram(lovrShaderGetProgram(shader));
lovrGpuUseProgram(shader->program);
lovrShaderBind(shader);
// Attributes
@ -809,7 +846,7 @@ Texture* lovrTextureCreate(TextureType type, TextureData** slices, int depth, bo
if (slices) {
for (int i = 0; i < depth; i++) {
lovrTextureReplacePixels(texture, slices[i], i);
lovrTextureReplacePixels(texture, slices[i], 0, 0, i);
}
}
@ -846,16 +883,18 @@ TextureType lovrTextureGetType(Texture* texture) {
return texture->type;
}
void lovrTextureReplacePixels(Texture* texture, TextureData* textureData, int slice) {
void lovrTextureReplacePixels(Texture* texture, TextureData* textureData, int x, int y, int slice) {
lovrRetain(textureData);
lovrRelease(texture->slices[slice]);
texture->slices[slice] = textureData;
lovrGpuBindTexture(texture, 0);
if (!texture->allocated) {
lovrAssert(texture->type != TEXTURE_CUBE || textureData->width == textureData->height, "Cubemap images must be square");
lovrTextureAllocate(texture, textureData);
} else {
lovrAssert(textureData->width == texture->width && textureData->height == texture->height, "All texture slices must have the same dimensions");
bool overflow = (x + textureData->width > texture->width) || (y + textureData->height > texture->height);
lovrAssert(!overflow, "Trying to replace pixels outside the texture's bounds");
}
if (!textureData->blob.data) {
@ -876,7 +915,7 @@ void lovrTextureReplacePixels(Texture* texture, TextureData* textureData, int sl
break;
case TEXTURE_ARRAY:
case TEXTURE_VOLUME:
glCompressedTexSubImage3D(binding, i, 0, 0, slice, m.width, m.height, 1, glInternalFormat, m.size, m.data);
glCompressedTexSubImage3D(binding, i, x, y, slice, m.width, m.height, 1, glInternalFormat, m.size, m.data);
break;
}
}
@ -884,11 +923,11 @@ void lovrTextureReplacePixels(Texture* texture, TextureData* textureData, int sl
switch (texture->type) {
case TEXTURE_2D:
case TEXTURE_CUBE:
glTexSubImage2D(binding, 0, 0, 0, textureData->width, textureData->height, glFormat, GL_UNSIGNED_BYTE, textureData->blob.data);
glTexSubImage2D(binding, 0, x, y, textureData->width, textureData->height, glFormat, GL_UNSIGNED_BYTE, textureData->blob.data);
break;
case TEXTURE_ARRAY:
case TEXTURE_VOLUME:
glTexSubImage3D(binding, 0, 0, 0, slice, textureData->width, textureData->height, 1, glFormat, GL_UNSIGNED_BYTE, textureData->blob.data);
glTexSubImage3D(binding, 0, x, y, slice, textureData->width, textureData->height, 1, glFormat, GL_UNSIGNED_BYTE, textureData->blob.data);
break;
}
@ -1030,33 +1069,6 @@ void lovrCanvasDestroy(void* ref) {
lovrTextureDestroy(ref);
}
uint32_t lovrCanvasGetId(Canvas* canvas) {
return canvas->framebuffer;
}
void lovrCanvasBind(Canvas** canvases, int canvasCount) {
if (canvasCount == 0) {
lovrGpuBindFramebuffer(0);
return;
}
lovrGpuBindFramebuffer(canvases[0]->texture.id);
if (memcmp(canvases, canvases[0]->attachments, MAX_CANVASES * sizeof(Canvas*))) {
memcpy(canvases[0]->attachments, canvases, MAX_CANVASES * sizeof(Canvas*));
GLenum buffers[MAX_CANVASES];
for (int i = 0; i < canvasCount; i++) {
buffers[i] = GL_COLOR_ATTACHMENT0 + i;
glFramebufferTexture2D(GL_FRAMEBUFFER, buffers[i], GL_TEXTURE_2D, lovrTextureGetId((Texture*) canvases[i]), 0);
}
glDrawBuffers(canvasCount, buffers);
GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
lovrAssert(status != GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS, "All multicanvas canvases must have the same dimensions");
lovrAssert(status == GL_FRAMEBUFFER_COMPLETE, "Unable to bind framebuffer");
}
}
void lovrCanvasResolve(Canvas* canvas) {
if (canvas->flags.msaa > 0) {
int width = canvas->texture.width;
@ -1290,10 +1302,6 @@ void lovrShaderDestroy(void* ref) {
free(shader);
}
uint32_t lovrShaderGetProgram(Shader* shader) {
return shader->program;
}
void lovrShaderBind(Shader* shader) {
map_iter_t iter = map_iter(&shader->uniforms);
const char* key;

View File

@ -24,7 +24,6 @@ typedef struct Shader Shader;
Shader* lovrShaderCreate(const char* vertexSource, const char* fragmentSource);
Shader* lovrShaderCreateDefault(DefaultShader type);
void lovrShaderDestroy(void* ref);
uint32_t lovrShaderGetProgram(Shader* shader);
void lovrShaderBind(Shader* shader);
int lovrShaderGetAttributeId(Shader* shader, const char* name);
bool lovrShaderHasUniform(Shader* shader, const char* name);

View File

@ -38,12 +38,12 @@ typedef struct Texture Texture;
Texture* lovrTextureCreate(TextureType type, TextureData** slices, int depth, bool srgb, bool mipmaps);
void lovrTextureDestroy(void* ref);
uint32_t lovrTextureGetId(Texture* texture); // FIXME temporary
uint32_t lovrTextureGetId(Texture* texture);
int lovrTextureGetWidth(Texture* texture);
int lovrTextureGetHeight(Texture* texture);
int lovrTextureGetDepth(Texture* texture);
TextureType lovrTextureGetType(Texture* texture);
void lovrTextureReplacePixels(Texture* texture, TextureData* data, int slice);
void lovrTextureReplacePixels(Texture* texture, TextureData* data, int x, int y, int slice);
TextureFilter lovrTextureGetFilter(Texture* texture);
void lovrTextureSetFilter(Texture* texture, TextureFilter filter);
TextureWrap lovrTextureGetWrap(Texture* texture);

View File

@ -16,8 +16,6 @@
#pragma pack(pop)
#endif
#include "graphics/opengl.h"
// From openvr_capi.h
extern intptr_t VR_InitInternal(EVRInitError *peError, EVRApplicationType eType);
extern void VR_ShutdownInternal();
@ -249,9 +247,7 @@ static void ensureCanvas() {
return;
}
glBindFramebuffer(GL_FRAMEBUFFER, 0);
int msaa = 0;
glGetIntegerv(GL_SAMPLES, &msaa);
int msaa = lovrGraphicsGetMSAA();
state.system->GetRecommendedRenderTargetSize(&state.renderWidth, &state.renderHeight);
CanvasFlags flags = { .msaa = msaa, .depth = true, .stencil = true, .mipmaps = false };
state.canvas = lovrCanvasCreate(state.renderWidth * 2, state.renderHeight, FORMAT_RGB, flags);
@ -692,8 +688,6 @@ static void openvrRenderTo(void (*callback)(void*), void* userdata) {
}
// Submit
glActiveTexture(GL_TEXTURE0);
Texture* oldTexture = lovrGpuGetTexture(0);
uintptr_t texture = (uintptr_t) lovrTextureGetId((Texture*) state.canvas);
EColorSpace colorSpace = lovrGraphicsIsGammaCorrect() ? EColorSpace_ColorSpace_Linear : EColorSpace_ColorSpace_Gamma;
Texture_t eyeTexture = { (void*) texture, ETextureType_TextureType_OpenGL, colorSpace };
@ -701,7 +695,7 @@ static void openvrRenderTo(void (*callback)(void*), void* userdata) {
VRTextureBounds_t right = { .5, 0, 1., 1. };
state.compositor->Submit(EVREye_Eye_Left, &eyeTexture, &left, EVRSubmitFlags_Submit_Default);
state.compositor->Submit(EVREye_Eye_Right, &eyeTexture, &right, EVRSubmitFlags_Submit_Default);
glBindTexture(GL_TEXTURE_2D, lovrTextureGetId(oldTexture));
lovrGpuRebindTexture(0);
lovrGraphicsSetCamera(NULL, false);
state.isRendering = false;