mirror of https://github.com/bjornbytes/lovr.git
Equirectangular Skybox rough draft;
This commit is contained in:
parent
ac7a97fe77
commit
4feeb4d4ab
|
@ -683,8 +683,13 @@ int l_lovrGraphicsNewShader(lua_State* L) {
|
||||||
int l_lovrGraphicsNewSkybox(lua_State* L) {
|
int l_lovrGraphicsNewSkybox(lua_State* L) {
|
||||||
void* data[6];
|
void* data[6];
|
||||||
size_t size[6];
|
size_t size[6];
|
||||||
|
SkyboxType type;
|
||||||
|
|
||||||
if (lua_istable(L, 1)) {
|
if (lua_gettop(L) == 1 && lua_type(L, 1) == LUA_TSTRING) {
|
||||||
|
const char* filename = lua_tostring(L, 1);
|
||||||
|
data[0] = lovrFilesystemRead(filename, size);
|
||||||
|
type = SKYBOX_PANORAMA;
|
||||||
|
} else if (lua_istable(L, 1)) {
|
||||||
if (lua_objlen(L, 1) != 6) {
|
if (lua_objlen(L, 1) != 6) {
|
||||||
return luaL_argerror(L, 1, "Expected 6 strings or a table containing 6 strings");
|
return luaL_argerror(L, 1, "Expected 6 strings or a table containing 6 strings");
|
||||||
}
|
}
|
||||||
|
@ -700,14 +705,18 @@ int l_lovrGraphicsNewSkybox(lua_State* L) {
|
||||||
data[i] = lovrFilesystemRead(filename, size + i);
|
data[i] = lovrFilesystemRead(filename, size + i);
|
||||||
lua_pop(L, 1);
|
lua_pop(L, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type = SKYBOX_CUBE;
|
||||||
} else {
|
} else {
|
||||||
for (int i = 0; i < 6; i++) {
|
for (int i = 0; i < 6; i++) {
|
||||||
const char* filename = luaL_checkstring(L, i + 1);
|
const char* filename = luaL_checkstring(L, i + 1);
|
||||||
data[i] = lovrFilesystemRead(filename, size + i);
|
data[i] = lovrFilesystemRead(filename, size + i);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type = SKYBOX_CUBE;
|
||||||
}
|
}
|
||||||
|
|
||||||
Skybox* skybox = lovrSkyboxCreate(data, size);
|
Skybox* skybox = lovrSkyboxCreate(data, size, type);
|
||||||
luax_pushtype(L, Skybox, skybox);
|
luax_pushtype(L, Skybox, skybox);
|
||||||
lovrRelease(&skybox->ref);
|
lovrRelease(&skybox->ref);
|
||||||
|
|
||||||
|
|
|
@ -677,62 +677,113 @@ void lovrGraphicsSkybox(Skybox* skybox, float angle, float ax, float ay, float a
|
||||||
lovrGraphicsOrigin();
|
lovrGraphicsOrigin();
|
||||||
lovrGraphicsRotate(angle, ax, ay, az);
|
lovrGraphicsRotate(angle, ax, ay, az);
|
||||||
|
|
||||||
float cube[] = {
|
if (skybox->type == SKYBOX_CUBE) {
|
||||||
// Front
|
float cube[] = {
|
||||||
1.f, -1.f, -1.f,
|
// Front
|
||||||
1.f, 1.f, -1.f,
|
1.f, -1.f, -1.f,
|
||||||
-1.f, -1.f, -1.f,
|
1.f, 1.f, -1.f,
|
||||||
-1.f, 1.f, -1.f,
|
-1.f, -1.f, -1.f,
|
||||||
|
-1.f, 1.f, -1.f,
|
||||||
|
|
||||||
// Left
|
// Left
|
||||||
-1.f, 1.f, -1.f,
|
-1.f, 1.f, -1.f,
|
||||||
-1.f, 1.f, 1.f,
|
-1.f, 1.f, 1.f,
|
||||||
-1.f, -1.f, -1.f,
|
-1.f, -1.f, -1.f,
|
||||||
-1.f, -1.f, 1.f,
|
-1.f, -1.f, 1.f,
|
||||||
|
|
||||||
// Back
|
// Back
|
||||||
-1.f, -1.f, 1.f,
|
-1.f, -1.f, 1.f,
|
||||||
1.f, -1.f, 1.f,
|
1.f, -1.f, 1.f,
|
||||||
-1.f, 1.f, 1.f,
|
-1.f, 1.f, 1.f,
|
||||||
1.f, 1.f, 1.f,
|
1.f, 1.f, 1.f,
|
||||||
|
|
||||||
// Right
|
// Right
|
||||||
1.f, 1.f, 1.f,
|
1.f, 1.f, 1.f,
|
||||||
1.f, -1.f, 1.f,
|
1.f, -1.f, 1.f,
|
||||||
1.f, 1.f, -1.f,
|
1.f, 1.f, -1.f,
|
||||||
1.f, -1.f, -1.f,
|
1.f, -1.f, -1.f,
|
||||||
|
|
||||||
// Bottom
|
// Bottom
|
||||||
1.f, -1.f, -1.f,
|
1.f, -1.f, -1.f,
|
||||||
1.f, -1.f, 1.f,
|
1.f, -1.f, 1.f,
|
||||||
-1.f, -1.f, -1.f,
|
-1.f, -1.f, -1.f,
|
||||||
-1.f, -1.f, 1.f,
|
-1.f, -1.f, 1.f,
|
||||||
|
|
||||||
// Adjust
|
// Adjust
|
||||||
-1.f, -1.f, 1.f,
|
-1.f, -1.f, 1.f,
|
||||||
-1.f, 1.f, -1.f,
|
-1.f, 1.f, -1.f,
|
||||||
|
|
||||||
// Top
|
// Top
|
||||||
-1.f, 1.f, -1.f,
|
-1.f, 1.f, -1.f,
|
||||||
-1.f, 1.f, 1.f,
|
-1.f, 1.f, 1.f,
|
||||||
1.f, 1.f, -1.f,
|
1.f, 1.f, -1.f,
|
||||||
1.f, 1.f, 1.f
|
1.f, 1.f, 1.f
|
||||||
};
|
};
|
||||||
|
|
||||||
lovrGraphicsSetShapeData(cube, 156);
|
lovrGraphicsSetShapeData(cube, 156);
|
||||||
|
|
||||||
glDepthMask(GL_FALSE);
|
glDepthMask(GL_FALSE);
|
||||||
glActiveTexture(GL_TEXTURE1);
|
glActiveTexture(GL_TEXTURE1);
|
||||||
glBindTexture(GL_TEXTURE_CUBE_MAP, skybox->texture);
|
glBindTexture(GL_TEXTURE_CUBE_MAP, skybox->texture);
|
||||||
|
|
||||||
int wasCulling = lovrGraphicsIsCullingEnabled();
|
int wasCulling = lovrGraphicsIsCullingEnabled();
|
||||||
lovrGraphicsSetCullingEnabled(0);
|
lovrGraphicsSetCullingEnabled(0);
|
||||||
lovrGraphicsDrawPrimitive(GL_TRIANGLE_STRIP, NULL, 0, 0, 0);
|
lovrGraphicsDrawPrimitive(GL_TRIANGLE_STRIP, NULL, 0, 0, 0);
|
||||||
lovrGraphicsSetCullingEnabled(wasCulling);
|
lovrGraphicsSetCullingEnabled(wasCulling);
|
||||||
|
|
||||||
glBindTexture(GL_TEXTURE_CUBE_MAP, 0);
|
glBindTexture(GL_TEXTURE_CUBE_MAP, 0);
|
||||||
glActiveTexture(GL_TEXTURE0);
|
glActiveTexture(GL_TEXTURE0);
|
||||||
glDepthMask(GL_TRUE);
|
glDepthMask(GL_TRUE);
|
||||||
|
} else if (skybox->type == SKYBOX_PANORAMA) {
|
||||||
|
int resolution = 40;
|
||||||
|
float sphere[8000]; // resolution * resolution * 5
|
||||||
|
|
||||||
|
for (int i = 0; i < resolution; i++) {
|
||||||
|
float theta = i * M_PI / resolution;
|
||||||
|
float sinTheta = sin(theta);
|
||||||
|
float cosTheta = cos(theta);
|
||||||
|
|
||||||
|
for (int j = 0; j < resolution; j++) {
|
||||||
|
float phi = j * 2 * M_PI / resolution;
|
||||||
|
float sinPhi = sin(phi);
|
||||||
|
float cosPhi = cos(phi);
|
||||||
|
|
||||||
|
float x = sinPhi * sinTheta;
|
||||||
|
float y = cosTheta;
|
||||||
|
float z = -cosPhi * sinTheta;
|
||||||
|
float u = j / resolution;
|
||||||
|
float v = i / resolution;
|
||||||
|
|
||||||
|
sphere[i * resolution + j * 5 + 0] = x;
|
||||||
|
sphere[i * resolution + j * 5 + 1] = y;
|
||||||
|
sphere[i * resolution + j * 5 + 2] = z;
|
||||||
|
sphere[i * resolution + j * 5 + 3] = u;
|
||||||
|
sphere[i * resolution + j * 5 + 4] = v;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int indices[9600]; // resolution * resolution * 6
|
||||||
|
for (int i = 0; i < resolution; i++) {
|
||||||
|
int offset0 = i * (resolution + 1);
|
||||||
|
int offset1 = (i + 1) * (resolution + 1);
|
||||||
|
for (int j = 0; j < resolution; j++) {
|
||||||
|
int index0 = offset0 + j;
|
||||||
|
int index1 = offset1 + j;
|
||||||
|
indices[i * resolution + j * 6 + 0] = index0;
|
||||||
|
indices[i * resolution + j * 6 + 1] = index1;
|
||||||
|
indices[i * resolution + j * 6 + 2] = index0 + 1;
|
||||||
|
indices[i * resolution + j * 6 + 3] = index1;
|
||||||
|
indices[i * resolution + j * 6 + 4] = index1 + 1;
|
||||||
|
indices[i * resolution + j * 6 + 5] = index0 + 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
lovrGraphicsSetShapeData(sphere, 8000);
|
||||||
|
lovrGraphicsSetIndexData(indices, 9600);
|
||||||
|
glDepthMask(GL_FALSE);
|
||||||
|
lovrGraphicsDrawPrimitive(GL_TRIANGLES, skybox->texture, 0, 1, 1);
|
||||||
|
glDepthMask(GL_TRUE);
|
||||||
|
}
|
||||||
|
|
||||||
lovrGraphicsSetShader(lastShader);
|
lovrGraphicsSetShader(lastShader);
|
||||||
lovrRelease(&lastShader->ref);
|
lovrRelease(&lastShader->ref);
|
||||||
|
|
|
@ -2,14 +2,27 @@
|
||||||
#include "lib/stb/stb_image.h"
|
#include "lib/stb/stb_image.h"
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
|
||||||
Skybox* lovrSkyboxCreate(void** data, size_t* size) {
|
Skybox* lovrSkyboxCreate(void** data, size_t* size, SkyboxType type) {
|
||||||
Skybox* skybox = lovrAlloc(sizeof(Skybox), lovrSkyboxDestroy);
|
Skybox* skybox = lovrAlloc(sizeof(Skybox), lovrSkyboxDestroy);
|
||||||
if (!skybox) return NULL;
|
if (!skybox) return NULL;
|
||||||
|
|
||||||
glGenTextures(1, &skybox->texture);
|
skybox->type = type;
|
||||||
glBindTexture(GL_TEXTURE_CUBE_MAP, skybox->texture);
|
|
||||||
|
|
||||||
for (int i = 0; i < 6; i++) {
|
GLenum binding;
|
||||||
|
int count;
|
||||||
|
|
||||||
|
if (type == SKYBOX_CUBE) {
|
||||||
|
binding = GL_TEXTURE_CUBE_MAP;
|
||||||
|
count = 6;
|
||||||
|
} else {
|
||||||
|
binding = GL_TEXTURE_2D;
|
||||||
|
count = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
glGenTextures(1, &skybox->texture);
|
||||||
|
glBindTexture(binding, skybox->texture);
|
||||||
|
|
||||||
|
for (int i = 0; i < count; i++) {
|
||||||
int width, height, channels;
|
int width, height, channels;
|
||||||
stbi_set_flip_vertically_on_load(0);
|
stbi_set_flip_vertically_on_load(0);
|
||||||
unsigned char* image = stbi_load_from_memory(data[i], size[i], &width, &height, &channels, 3);
|
unsigned char* image = stbi_load_from_memory(data[i], size[i], &width, &height, &channels, 3);
|
||||||
|
@ -18,15 +31,23 @@ Skybox* lovrSkyboxCreate(void** data, size_t* size) {
|
||||||
error("Could not load skybox image %d", i);
|
error("Could not load skybox image %d", i);
|
||||||
}
|
}
|
||||||
|
|
||||||
glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, GL_RGB, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, image);
|
if (type == SKYBOX_CUBE) {
|
||||||
|
glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, GL_RGB, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, image);
|
||||||
|
} else {
|
||||||
|
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, image);
|
||||||
|
}
|
||||||
|
|
||||||
free(image);
|
free(image);
|
||||||
}
|
}
|
||||||
|
|
||||||
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
glTexParameteri(binding, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||||
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
glTexParameteri(binding, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||||
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
|
glTexParameteri(binding, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
||||||
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
glTexParameteri(binding, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
||||||
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
|
||||||
|
if (type == SKYBOX_CUBE) {
|
||||||
|
glTexParameteri(binding, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
|
||||||
|
}
|
||||||
|
|
||||||
return skybox;
|
return skybox;
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,10 +3,16 @@
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
SKYBOX_CUBE,
|
||||||
|
SKYBOX_PANORAMA
|
||||||
|
} SkyboxType;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
Ref ref;
|
Ref ref;
|
||||||
|
SkyboxType type;
|
||||||
GLuint texture;
|
GLuint texture;
|
||||||
} Skybox;
|
} Skybox;
|
||||||
|
|
||||||
Skybox* lovrSkyboxCreate(void** data, size_t* size);
|
Skybox* lovrSkyboxCreate(void** data, size_t* size, int count);
|
||||||
void lovrSkyboxDestroy(const Ref* ref);
|
void lovrSkyboxDestroy(const Ref* ref);
|
||||||
|
|
Loading…
Reference in New Issue