diff --git a/src/graphics/font.c b/src/graphics/font.c index 3c12e1c2..88d2d867 100644 --- a/src/graphics/font.c +++ b/src/graphics/font.c @@ -277,7 +277,7 @@ void lovrFontAddGlyph(Font* font, Glyph* glyph) { glyph->y = atlas->y; // Paste glyph into texture - lovrGraphicsBindTexture(font->texture); + lovrGraphicsBindTexture(font->texture, TEXTURE_2D, 0); glTexSubImage2D(GL_TEXTURE_2D, 0, atlas->x, atlas->y, glyph->tw, glyph->th, FORMAT_RGB.glFormat, GL_UNSIGNED_BYTE, glyph->data); // Advance atlas cursor diff --git a/src/graphics/graphics.c b/src/graphics/graphics.c index 245308da..c99daf39 100644 --- a/src/graphics/graphics.c +++ b/src/graphics/graphics.c @@ -463,21 +463,21 @@ static void lovrGraphicsDrawPrimitive(GLenum mode, int hasNormals, int hasTexCoo } void lovrGraphicsPoints(float* points, int count) { - lovrGraphicsBindTexture(NULL); + lovrGraphicsBindTexture(NULL, TEXTURE_2D, 0); lovrGraphicsSetDefaultShader(SHADER_DEFAULT); lovrGraphicsSetShapeData(points, count); lovrGraphicsDrawPrimitive(GL_POINTS, 0, 0, 0); } void lovrGraphicsLine(float* points, int count) { - lovrGraphicsBindTexture(NULL); + lovrGraphicsBindTexture(NULL, TEXTURE_2D, 0); lovrGraphicsSetDefaultShader(SHADER_DEFAULT); lovrGraphicsSetShapeData(points, count); lovrGraphicsDrawPrimitive(GL_LINE_STRIP, 0, 0, 0); } void lovrGraphicsTriangle(DrawMode mode, float* points) { - lovrGraphicsBindTexture(NULL); + lovrGraphicsBindTexture(NULL, TEXTURE_2D, 0); lovrGraphicsSetDefaultShader(SHADER_DEFAULT); if (mode == DRAW_MODE_LINE) { @@ -510,7 +510,7 @@ void lovrGraphicsPlane(DrawMode mode, Texture* texture, mat4 transform) { -.5, -.5, 0 }; - lovrGraphicsBindTexture(NULL); + lovrGraphicsBindTexture(NULL, TEXTURE_2D, 0); lovrGraphicsSetDefaultShader(SHADER_DEFAULT); lovrGraphicsSetShapeData(points, 12); lovrGraphicsDrawPrimitive(GL_LINE_LOOP, 0, 0, 0); @@ -522,7 +522,7 @@ void lovrGraphicsPlane(DrawMode mode, Texture* texture, mat4 transform) { .5, -.5, 0, 0, 0, -1, 1, 1 }; - lovrGraphicsBindTexture(texture); + lovrGraphicsBindTexture(texture, TEXTURE_2D, 0); lovrGraphicsSetDefaultShader(SHADER_DEFAULT); lovrGraphicsSetShapeData(data, 32); lovrGraphicsDrawPrimitive(GL_TRIANGLE_STRIP, 1, 1, 0); @@ -539,7 +539,7 @@ void lovrGraphicsPlaneFullscreen(Texture* texture) { 1, -1, 0, 1, 0 }; - lovrGraphicsBindTexture(texture); + lovrGraphicsBindTexture(texture, TEXTURE_2D, 0); lovrGraphicsSetDefaultShader(SHADER_FULLSCREEN); lovrGraphicsSetShapeData(data, 20); lovrGraphicsDrawPrimitive(GL_TRIANGLE_STRIP, 0, 1, 0); @@ -571,7 +571,7 @@ void lovrGraphicsBox(DrawMode mode, Texture* texture, mat4 transform) { 0, 4, 1, 5, 2, 6, 3, 7 // Connections }; - lovrGraphicsBindTexture(NULL); + lovrGraphicsBindTexture(NULL, TEXTURE_2D, 0); lovrGraphicsSetDefaultShader(SHADER_DEFAULT); lovrGraphicsSetShapeData(points, 24); lovrGraphicsSetIndexData(indices, 24); @@ -619,7 +619,7 @@ void lovrGraphicsBox(DrawMode mode, Texture* texture, mat4 transform) { .5, .5, .5, 0, 1, 0, 1, 0 }; - lovrGraphicsBindTexture(texture); + lovrGraphicsBindTexture(texture, TEXTURE_2D, 0); lovrGraphicsSetDefaultShader(SHADER_DEFAULT); lovrGraphicsSetShapeData(data, 208); lovrGraphicsDrawPrimitive(GL_TRIANGLE_STRIP, 1, 1, 0); @@ -727,7 +727,7 @@ void lovrGraphicsCylinder(float x1, float y1, float z1, float x2, float y2, floa } } - lovrGraphicsBindTexture(NULL); + lovrGraphicsBindTexture(NULL, TEXTURE_2D, 0); lovrGraphicsSetDefaultShader(SHADER_DEFAULT); lovrGraphicsDrawPrimitive(GL_TRIANGLES, 1, 0, 1); #undef PUSH_CYLINDER_VERTEX @@ -839,12 +839,10 @@ void lovrGraphicsSkybox(Texture* texture, float angle, float ax, float ay, float 1.f, 1.f, 1.f }; - glActiveTexture(GL_TEXTURE1); lovrGraphicsSetShapeData(cube, 78); - lovrGraphicsBindTexture(texture); + lovrGraphicsBindTexture(texture, TEXTURE_CUBE, 1); lovrGraphicsPrepare(); lovrGraphicsDrawPrimitive(GL_TRIANGLE_STRIP, 0, 0, 0); - glActiveTexture(GL_TEXTURE0); } else if (texture->type == TEXTURE_2D) { lovrGraphicsSphere(NULL, 30); } @@ -864,7 +862,7 @@ void lovrGraphicsPrint(const char* str, mat4 transform, float wrap, HorizontalAl lovrGraphicsMatrixTransform(MATRIX_MODEL, transform); lovrGraphicsScale(MATRIX_MODEL, scale, scale, scale); lovrGraphicsTranslate(MATRIX_MODEL, 0, offsety, 0); - lovrGraphicsBindTexture(font->texture); + lovrGraphicsBindTexture(font->texture, TEXTURE_2D, 0); lovrGraphicsSetDefaultShader(SHADER_FONT); glDepthMask(GL_FALSE); lovrGraphicsDrawPrimitive(GL_TRIANGLES, 0, 1, 0); @@ -912,11 +910,11 @@ void lovrGraphicsBindFramebuffer(int framebuffer) { glBindFramebuffer(GL_FRAMEBUFFER, framebuffer); } -Texture* lovrGraphicsGetTexture() { - return state.texture; +Texture* lovrGraphicsGetTexture(int slot) { + return state.textures[slot]; } -void lovrGraphicsBindTexture(Texture* texture) { +void lovrGraphicsBindTexture(Texture* texture, TextureType type, int slot) { if (!texture) { if (!state.defaultTexture) { TextureData* textureData = lovrTextureDataGetBlank(1, 1, 0xff, FORMAT_RGBA); @@ -926,9 +924,15 @@ void lovrGraphicsBindTexture(Texture* texture) { texture = state.defaultTexture; } - if (texture != state.texture) { - state.texture = texture; - glBindTexture(texture->type, texture->id); + if (texture != state.textures[slot]) { + if (state.textures[slot]) { + lovrRelease(&state.textures[slot]->ref); + } + + state.textures[slot] = texture; + glActiveTexture(GL_TEXTURE0 + slot); + glBindTexture(type, texture->id); + lovrRetain(&texture->ref); } } diff --git a/src/graphics/graphics.h b/src/graphics/graphics.h index 262814a3..692ef6b5 100644 --- a/src/graphics/graphics.h +++ b/src/graphics/graphics.h @@ -10,6 +10,7 @@ #define MAX_TRANSFORMS 60 #define INTERNAL_TRANSFORMS 4 #define DEFAULT_SHADER_COUNT 4 +#define MAX_TEXTURES 16 typedef enum { BLEND_ALPHA, @@ -95,7 +96,7 @@ typedef struct { vec_uint_t streamIndices; CanvasState canvases[MAX_CANVASES]; int canvas; - Texture* texture; + Texture* textures[MAX_TEXTURES]; uint32_t program; uint32_t vertexArray; uint32_t vertexBuffer; @@ -169,7 +170,7 @@ void lovrGraphicsSetProjection(mat4 projection); void lovrGraphicsSetViewport(int x, int y, int w, int h); void lovrGraphicsBindFramebuffer(int framebuffer); Texture* lovrGraphicsGetTexture(); -void lovrGraphicsBindTexture(Texture* texture); +void lovrGraphicsBindTexture(Texture* texture, TextureType type, int slot); void lovrGraphicsSetDefaultShader(DefaultShader defaultShader); Shader* lovrGraphicsGetActiveShader(); void lovrGraphicsBindProgram(uint32_t program); diff --git a/src/graphics/mesh.c b/src/graphics/mesh.c index b39abcd9..e0f8e280 100644 --- a/src/graphics/mesh.c +++ b/src/graphics/mesh.c @@ -121,7 +121,7 @@ void lovrMeshDraw(Mesh* mesh, mat4 transform) { } lovrGraphicsSetDefaultShader(SHADER_DEFAULT); - lovrGraphicsBindTexture(NULL); + lovrGraphicsBindTexture(NULL, TEXTURE_2D, 0); lovrGraphicsPrepare(); lovrGraphicsBindVertexArray(mesh->vao); lovrMeshBindAttributes(mesh); diff --git a/src/graphics/texture.c b/src/graphics/texture.c index c5b5dcbd..678497ec 100644 --- a/src/graphics/texture.c +++ b/src/graphics/texture.c @@ -60,7 +60,7 @@ Texture* lovrTextureCreate(TextureType type, TextureData* slices[6], int sliceCo texture->framebuffer = 0; texture->depthBuffer = 0; glGenTextures(1, &texture->id); - lovrGraphicsBindTexture(texture); + lovrGraphicsBindTexture(texture, type, 0); lovrTextureCreateStorage(texture); lovrTextureRefresh(texture); lovrTextureSetFilter(texture, lovrGraphicsGetDefaultFilter()); @@ -173,7 +173,7 @@ void lovrTextureResolveMSAA(Texture* texture) { } void lovrTextureRefresh(Texture* texture) { - lovrGraphicsBindTexture(texture); + lovrGraphicsBindTexture(texture, texture->type, 0); validateSlices(texture->type, texture->slices, texture->sliceCount); texture->width = texture->slices[0]->width; @@ -208,7 +208,7 @@ TextureFilter lovrTextureGetFilter(Texture* texture) { void lovrTextureSetFilter(Texture* texture, TextureFilter filter) { int hasMipmaps = texture->slices[0]->format.compressed || texture->slices[0]->mipmaps.generated; float anisotropy = filter.mode == FILTER_ANISOTROPIC ? MAX(filter.anisotropy, 1.) : 1.; - lovrGraphicsBindTexture(texture); + lovrGraphicsBindTexture(texture, texture->type, 0); texture->filter = filter; switch (filter.mode) { @@ -248,7 +248,7 @@ TextureWrap lovrTextureGetWrap(Texture* texture) { void lovrTextureSetWrap(Texture* texture, TextureWrap wrap) { texture->wrap = wrap; - lovrGraphicsBindTexture(texture); + lovrGraphicsBindTexture(texture, texture->type, 0); glTexParameteri(texture->type, GL_TEXTURE_WRAP_S, wrap.s); glTexParameteri(texture->type, GL_TEXTURE_WRAP_T, wrap.t); if (texture->type == TEXTURE_CUBE) { diff --git a/src/headset/openvr.c b/src/headset/openvr.c index e004cee5..bd91ff70 100644 --- a/src/headset/openvr.c +++ b/src/headset/openvr.c @@ -724,7 +724,8 @@ void lovrHeadsetRenderTo(headsetRenderCallback callback, void* userdata) { lovrTextureResolveMSAA(state.texture); // OpenVR changes the OpenGL texture binding, so we reset it after rendering - Texture* oldTexture = lovrGraphicsGetTexture(); + glActiveTexture(GL_TEXTURE0); + Texture* oldTexture = lovrGraphicsGetTexture(0); // Submit uintptr_t texture = (uintptr_t) state.texture->id;