mirror of https://github.com/bjornbytes/lovr.git
Compare commits
4 Commits
dc9e93103f
...
5c43ad0792
Author | SHA1 | Date |
---|---|---|
bjorn | 5c43ad0792 | |
bjorn | 0a3ccb4f8a | |
bjorn | fbf2a039b7 | |
bjorn | f729320793 |
|
@ -1,7 +1,7 @@
|
|||
#include "shaders/unlit.vert.h"
|
||||
#include "shaders/unlit.frag.h"
|
||||
|
||||
#include "shaders/font.frag.h"
|
||||
#include "shaders/fill.vert.h"
|
||||
|
||||
#include "shaders/lovr.glsl.h"
|
||||
|
||||
|
|
|
@ -0,0 +1,14 @@
|
|||
#version 460
|
||||
#extension GL_EXT_multiview : require
|
||||
#extension GL_GOOGLE_include_directive : require
|
||||
|
||||
#include "lovr.glsl"
|
||||
|
||||
void main() {
|
||||
FragColor = VertexColor * Color;
|
||||
float x = -1 + float((VertexIndex & 1) << 2);
|
||||
float y = -1 + float((VertexIndex & 2) << 1);
|
||||
FragUV = vec2(x, y) * .5 + .5;
|
||||
Position = vec4(x, y, 0., 1.);
|
||||
PointSize = 1.f;
|
||||
}
|
|
@ -1104,6 +1104,12 @@ static int l_lovrGraphicsNewMaterial(lua_State* L) {
|
|||
|
||||
if (texture) {
|
||||
info.texture = texture;
|
||||
info.data.color[0] = 1.f;
|
||||
info.data.color[1] = 1.f;
|
||||
info.data.color[2] = 1.f;
|
||||
info.data.color[3] = 1.f;
|
||||
info.data.uvScale[0] = 1.f;
|
||||
info.data.uvScale[1] = 1.f;
|
||||
} else {
|
||||
luaL_checktype(L, 1, LUA_TTABLE);
|
||||
|
||||
|
|
|
@ -241,7 +241,8 @@ static int l_lovrPassSetDepthClamp(lua_State* L) {
|
|||
static int l_lovrPassSetMaterial(lua_State* L) {
|
||||
Pass* pass = luax_checktype(L, 1, Pass);
|
||||
Material* material = luax_totype(L, 2, Material);
|
||||
lovrPassSetMaterial(pass, material);
|
||||
Texture* texture = luax_totype(L, 2, Texture);
|
||||
lovrPassSetMaterial(pass, material, texture);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -552,6 +553,13 @@ static int l_lovrPassText(lua_State* L) {
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int l_lovrPassFill(lua_State* L) {
|
||||
Pass* pass = luax_checktype(L, 1, Pass);
|
||||
Texture* texture = luax_totype(L, 2, Texture);
|
||||
lovrPassFill(pass, texture);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int l_lovrPassMesh(lua_State* L) {
|
||||
Pass* pass = luax_checktype(L, 1, Pass);
|
||||
Buffer* vertices = !lua_toboolean(L, 2) ? NULL : luax_totype(L, 2, Buffer);
|
||||
|
@ -802,6 +810,7 @@ const luaL_Reg lovrPass[] = {
|
|||
{ "sphere", l_lovrPassSphere },
|
||||
{ "torus", l_lovrPassTorus },
|
||||
{ "text", l_lovrPassText },
|
||||
{ "fill", l_lovrPassFill },
|
||||
{ "mesh", l_lovrPassMesh },
|
||||
{ "multimesh", l_lovrPassMultimesh },
|
||||
|
||||
|
|
|
@ -1141,6 +1141,7 @@ static Image* loadKTX2(Blob* blob) {
|
|||
|
||||
static Image* loadSTB(Blob* blob) {
|
||||
void* data;
|
||||
uint32_t flags;
|
||||
TextureFormat format;
|
||||
int width, height, channels;
|
||||
if (stbi_is_16_bit_from_memory(blob->data, (int) blob->size)) {
|
||||
|
@ -1151,12 +1152,14 @@ static Image* loadSTB(Blob* blob) {
|
|||
case 4: format = FORMAT_RGBA16; break;
|
||||
default: lovrThrow("Unsupported channel count for 16 bit image: %d", channels);
|
||||
}
|
||||
flags = IMAGE_SRGB;
|
||||
} else if (stbi_is_hdr_from_memory(blob->data, (int) blob->size)) {
|
||||
data = stbi_loadf_from_memory(blob->data, (int) blob->size, &width, &height, NULL, 4);
|
||||
format = FORMAT_RGBA32F;
|
||||
} else {
|
||||
data = stbi_load_from_memory(blob->data, (int) blob->size, &width, &height, NULL, 4);
|
||||
format = FORMAT_RGBA8;
|
||||
flags = IMAGE_SRGB;
|
||||
}
|
||||
|
||||
if (!data) {
|
||||
|
@ -1168,6 +1171,7 @@ static Image* loadSTB(Blob* blob) {
|
|||
Image* image = calloc(1, sizeof(Image));
|
||||
lovrAssert(image, "Out of memory");
|
||||
image->ref = 1;
|
||||
image->flags = flags;
|
||||
image->width = width;
|
||||
image->height = height;
|
||||
image->format = format;
|
||||
|
|
|
@ -58,6 +58,7 @@ struct Texture {
|
|||
uint32_t ref;
|
||||
gpu_texture* gpu;
|
||||
gpu_texture* renderView;
|
||||
Material* material;
|
||||
TextureInfo info;
|
||||
Sync sync;
|
||||
};
|
||||
|
@ -176,6 +177,7 @@ typedef enum {
|
|||
VERTEX_SHAPE,
|
||||
VERTEX_POINT,
|
||||
VERTEX_GLYPH,
|
||||
VERTEX_EMPTY,
|
||||
VERTEX_FORMAT_COUNT
|
||||
} VertexFormat;
|
||||
|
||||
|
@ -478,6 +480,16 @@ bool lovrGraphicsInit(bool debug, bool vsync) {
|
|||
.attributes[4] = { 1, 14, 0, GPU_TYPE_F32x4 }
|
||||
};
|
||||
|
||||
state.vertexFormats[VERTEX_EMPTY] = (gpu_vertex_format) {
|
||||
.bufferCount = 2,
|
||||
.attributeCount = 5,
|
||||
.attributes[0] = { 1, 10, 0, GPU_TYPE_F32x2 },
|
||||
.attributes[1] = { 1, 11, 0, GPU_TYPE_F32x4 },
|
||||
.attributes[2] = { 1, 12, 0, GPU_TYPE_F32x2 },
|
||||
.attributes[3] = { 1, 13, 16, GPU_TYPE_F32x4 },
|
||||
.attributes[4] = { 1, 14, 0, GPU_TYPE_F32x4 }
|
||||
};
|
||||
|
||||
state.defaultMaterial = lovrMaterialCreate(&(MaterialInfo) {
|
||||
.data.color = { 1.f, 1.f, 1.f, 1.f },
|
||||
.texture = state.defaultTexture
|
||||
|
@ -1119,6 +1131,7 @@ Texture* lovrTextureCreateView(TextureViewInfo* view) {
|
|||
void lovrTextureDestroy(void* ref) {
|
||||
Texture* texture = ref;
|
||||
if (texture != state.window) {
|
||||
lovrRelease(texture->material, lovrMaterialDestroy);
|
||||
lovrRelease(texture->info.parent, lovrTextureDestroy);
|
||||
if (texture->renderView && texture->renderView != texture->gpu) gpu_texture_destroy(texture->renderView);
|
||||
if (texture->gpu) gpu_texture_destroy(texture->gpu);
|
||||
|
@ -1130,6 +1143,22 @@ const TextureInfo* lovrTextureGetInfo(Texture* texture) {
|
|||
return &texture->info;
|
||||
}
|
||||
|
||||
static Material* lovrTextureGetMaterial(Texture* texture) {
|
||||
if (!texture->material) {
|
||||
texture->material = lovrMaterialCreate(&(MaterialInfo) {
|
||||
.data.color = { 1.f, 1.f, 1.f, 1.f },
|
||||
.data.uvScale = { 1.f, 1.f },
|
||||
.texture = texture
|
||||
});
|
||||
|
||||
// Since the Material refcounts the Texture, this creates a cycle. Release the texture to make
|
||||
// sure this is a weak relationship (the automaterial does not keep the texture refcounted).
|
||||
lovrRelease(texture, lovrTextureDestroy);
|
||||
}
|
||||
|
||||
return texture->material;
|
||||
}
|
||||
|
||||
// Sampler
|
||||
|
||||
Sampler* lovrGraphicsGetDefaultSampler(FilterMode mode) {
|
||||
|
@ -1328,6 +1357,11 @@ Shader* lovrGraphicsGetDefaultShader(DefaultShader type) {
|
|||
info.stages[1] = lovrBlobCreate((void*) lovr_shader_font_frag, sizeof(lovr_shader_font_frag), "Font Fragment Shader");
|
||||
info.label = "font";
|
||||
break;
|
||||
case SHADER_FILL:
|
||||
info.stages[0] = lovrBlobCreate((void*) lovr_shader_fill_vert, sizeof(lovr_shader_fill_vert), "Fill Vertex Shader");
|
||||
info.stages[1] = lovrBlobCreate((void*) lovr_shader_unlit_frag, sizeof(lovr_shader_unlit_frag), "Unlit Fragment Shader");
|
||||
info.label = "fill";
|
||||
break;
|
||||
default: lovrUnreachable();
|
||||
}
|
||||
|
||||
|
@ -2185,7 +2219,11 @@ void lovrPassSetDepthClamp(Pass* pass, bool clamp) {
|
|||
}
|
||||
}
|
||||
|
||||
void lovrPassSetMaterial(Pass* pass, Material* material) {
|
||||
void lovrPassSetMaterial(Pass* pass, Material* material, Texture* texture) {
|
||||
if (texture) {
|
||||
material = lovrTextureGetMaterial(texture);
|
||||
}
|
||||
|
||||
material = material ? material : state.defaultMaterial;
|
||||
|
||||
if (pass->pipeline->material != material) {
|
||||
|
@ -3371,6 +3409,16 @@ void lovrPassText(Pass* pass, Font* font, const char* text, uint32_t length, flo
|
|||
}
|
||||
}
|
||||
|
||||
void lovrPassFill(Pass* pass, Texture* texture) {
|
||||
lovrPassDraw(pass, &(Draw) {
|
||||
.mode = VERTEX_TRIANGLES,
|
||||
.shader = SHADER_FILL,
|
||||
.material = texture ? lovrTextureGetMaterial(texture) : NULL,
|
||||
.vertex.format = VERTEX_EMPTY,
|
||||
.count = 3
|
||||
});
|
||||
}
|
||||
|
||||
void lovrPassMesh(Pass* pass, Buffer* vertices, Buffer* indices, float* transform, uint32_t start, uint32_t count, uint32_t instances) {
|
||||
if (count == ~0u) {
|
||||
count = (indices ? indices : vertices)->info.length - start;
|
||||
|
|
|
@ -251,6 +251,7 @@ const SamplerInfo* lovrSamplerGetInfo(Sampler* sampler);
|
|||
typedef enum {
|
||||
SHADER_UNLIT,
|
||||
SHADER_FONT,
|
||||
SHADER_FILL,
|
||||
DEFAULT_SHADER_COUNT
|
||||
} DefaultShader;
|
||||
|
||||
|
@ -459,7 +460,7 @@ void lovrPassSetDepthTest(Pass* pass, CompareMode test);
|
|||
void lovrPassSetDepthWrite(Pass* pass, bool write);
|
||||
void lovrPassSetDepthOffset(Pass* pass, float offset, float sloped);
|
||||
void lovrPassSetDepthClamp(Pass* pass, bool clamp);
|
||||
void lovrPassSetMaterial(Pass* pass, Material* material);
|
||||
void lovrPassSetMaterial(Pass* pass, Material* material, Texture* texture);
|
||||
void lovrPassSetSampler(Pass* pass, Sampler* sampler);
|
||||
void lovrPassSetScissor(Pass* pass, uint32_t scissor[4]);
|
||||
void lovrPassSetShader(Pass* pass, Shader* shader);
|
||||
|
@ -481,6 +482,7 @@ void lovrPassCircle(Pass* pass, float* transform, DrawStyle style, float angle1,
|
|||
void lovrPassSphere(Pass* pass, float* transform, uint32_t segmentsH, uint32_t segmentsV);
|
||||
void lovrPassTorus(Pass* pass, float* transform, uint32_t segmentsT, uint32_t segmentsP);
|
||||
void lovrPassText(Pass* pass, Font* font, const char* text, uint32_t length, float* transform, float wrap, HorizontalAlign halign, VerticalAlign valign);
|
||||
void lovrPassFill(Pass* pass, Texture* texture);
|
||||
void lovrPassMesh(Pass* pass, Buffer* vertices, Buffer* indices, float* transform, uint32_t start, uint32_t count, uint32_t instances);
|
||||
void lovrPassMultimesh(Pass* pass, Buffer* vertices, Buffer* indices, Buffer* indirect, uint32_t count, uint32_t offset, uint32_t stride);
|
||||
void lovrPassCompute(Pass* pass, uint32_t x, uint32_t y, uint32_t z, Buffer* indirect, uint32_t offset);
|
||||
|
|
Loading…
Reference in New Issue