conf flag for singlepass; Shader fixes;

This commit is contained in:
bjorn 2018-08-23 12:51:53 -07:00
parent b50c2d018a
commit 7569b7934f
6 changed files with 58 additions and 31 deletions

View File

@ -257,16 +257,26 @@ int l_lovrGraphicsInit(lua_State* L) {
luax_registertype(L, "ShaderBlock", lovrShaderBlock);
luax_registertype(L, "Texture", lovrTexture);
luax_extendtype(L, "Texture", "Canvas", lovrTexture, lovrCanvas);
lovrGraphicsInit();
luax_pushconf(L);
// Set gamma correct
// Gamma correct
lua_getfield(L, -1, "gammacorrect");
bool gammaCorrect = lua_toboolean(L, -1);
lovrGraphicsSetGammaCorrect(gammaCorrect);
lua_pop(L, 1);
// Singlepass
bool singlepass = false;
lua_getfield(L, -1, "graphics");
if (!lua_isnil(L, -1)) {
lua_getfield(L, -1, "singlepass");
singlepass = lua_toboolean(L, -1);
lua_pop(L, 1);
}
lua_pop(L, 1);
lovrGraphicsInit(gammaCorrect, singlepass);
// Create window if needed
lua_getfield(L, -1, "window");
if (!lua_isnil(L, -1)) {

View File

@ -22,8 +22,9 @@ static void onCloseWindow(GLFWwindow* window) {
// Base
void lovrGraphicsInit() {
// This page intentionally left blank
void lovrGraphicsInit(bool gammaCorrect, bool singlepass) {
state.gammaCorrect = gammaCorrect;
state.singlepass = singlepass;
}
void lovrGraphicsDestroy() {
@ -105,7 +106,7 @@ void lovrGraphicsCreateWindow(int w, int h, bool fullscreen, int msaa, const cha
glfwSwapInterval(0);
#endif
lovrGpuInit(state.gammaCorrect, glfwGetProcAddress);
lovrGpuInit(state.gammaCorrect, state.singlepass, glfwGetProcAddress);
VertexFormat format;
vertexFormatInit(&format);
vertexFormatAppend(&format, "lovrPosition", ATTR_FLOAT, 3);
@ -285,10 +286,6 @@ bool lovrGraphicsIsGammaCorrect() {
return state.gammaCorrect;
}
void lovrGraphicsSetGammaCorrect(bool gammaCorrect) {
state.gammaCorrect = gammaCorrect;
}
float lovrGraphicsGetLineWidth() {
return state.pipelines[state.pipeline].lineWidth;
}

View File

@ -157,6 +157,7 @@ typedef struct {
typedef struct {
bool initialized;
bool gammaCorrect;
bool singlepass;
int msaa;
void* window;
Camera camera;
@ -172,7 +173,7 @@ typedef struct {
} GraphicsState;
// Base
void lovrGraphicsInit();
void lovrGraphicsInit(bool gammaCorrect, bool singlepass);
void lovrGraphicsDestroy();
void lovrGraphicsPresent();
void lovrGraphicsCreateWindow(int w, int h, bool fullscreen, int msaa, const char* title, const char* icon);
@ -204,7 +205,6 @@ void lovrGraphicsSetDepthTest(CompareMode depthTest, bool write);
Font* lovrGraphicsGetFont();
void lovrGraphicsSetFont(Font* font);
bool lovrGraphicsIsGammaCorrect();
void lovrGraphicsSetGammaCorrect(bool gammaCorrect);
float lovrGraphicsGetLineWidth();
void lovrGraphicsSetLineWidth(float width);
float lovrGraphicsGetPointSize();
@ -250,7 +250,7 @@ void lovrGraphicsFill(Texture* texture);
typedef void (*gpuProc)(void);
void lovrGpuInit(bool srgb, gpuProc (*getProcAddress)(const char*));
void lovrGpuInit(bool srgb, bool singlepass, gpuProc (*getProcAddress)(const char*));
void lovrGpuDestroy();
void lovrGpuClear(Canvas** canvas, int canvasCount, Color* color, float* depth, int* stencil);
void lovrGpuDraw(DrawCommand* command);

View File

@ -62,7 +62,7 @@ static struct {
float viewport[4];
vec_void_t incoherents[MAX_BARRIERS];
bool srgb;
bool supportsSinglepass;
bool singlepass;
GraphicsLimits limits;
GraphicsStats stats;
} state;
@ -544,7 +544,7 @@ static void lovrGpuUseProgram(uint32_t program) {
}
}
void lovrGpuInit(bool srgb, gpuProc (*getProcAddress)(const char*)) {
void lovrGpuInit(bool srgb, bool singlepass, gpuProc (*getProcAddress)(const char*)) {
#ifndef EMSCRIPTEN
gladLoadGLLoader((GLADloadproc) getProcAddress);
glEnable(GL_LINE_SMOOTH);
@ -554,7 +554,7 @@ void lovrGpuInit(bool srgb, gpuProc (*getProcAddress)(const char*)) {
} else {
glDisable(GL_FRAMEBUFFER_SRGB);
}
state.supportsSinglepass = GLAD_GL_ARB_viewport_array && GLAD_GL_NV_viewport_array2 && GLAD_GL_NV_stereo_view_rendering;
state.singlepass = singlepass && GLAD_GL_ARB_viewport_array && GLAD_GL_NV_viewport_array2 && GLAD_GL_NV_stereo_view_rendering;
#endif
glEnable(GL_BLEND);
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
@ -908,7 +908,7 @@ void lovrGpuDraw(DrawCommand* command) {
lovrMeshBind(mesh, shader);
bool stereo = pipeline->canvasCount == 0 && command->camera.stereo == true;
int drawCount = 1 + (stereo == true && !state.supportsSinglepass);
int drawCount = 1 + (stereo == true && !state.singlepass);
// Draw (TODEW)
for (int i = 0; i < drawCount; i++) {
@ -917,7 +917,7 @@ void lovrGpuDraw(DrawCommand* command) {
int height = lovrTextureGetHeight((Texture*) pipeline->canvas[0], 0);
lovrGpuSetViewport((float[4]) { 0, 0, width, height });
#ifndef EMSCRIPTEN
} else if (state.supportsSinglepass) {
} else if (state.singlepass) {
glViewportArrayv(0, 2, command->camera.viewport[0]);
#endif
} else {
@ -925,8 +925,8 @@ void lovrGpuDraw(DrawCommand* command) {
}
// Bind uniforms
int eye = (stereo && state.supportsSinglepass) ? -1 : i;
lovrShaderSetInts(shader, "lovrEye", &eye, 0, 1);
lovrShaderSetInts(shader, "lovrIsStereo", &(int) { stereo && state.singlepass }, 0, 1);
lovrShaderSetInts(shader, "_lovrEye", &i, 0, 1);
lovrShaderBind(shader);
uint32_t rangeStart, rangeCount;

View File

@ -58,6 +58,9 @@ function lovr.boot()
timer = true
},
gammacorrect = false,
graphics = {
singlepass = true,
},
headset = {
drivers = { 'openvr', 'webvr', 'fake' },
mirror = true,

View File

@ -29,6 +29,7 @@ const char* lovrShaderVertexPrefix = ""
"#ifdef GL_NV_stereo_view_rendering \n"
"#extension GL_NV_viewport_array2 : enable \n"
"#extension GL_NV_stereo_view_rendering : enable \n"
"#define SUPPORTS_SINGLEPASS 1 \n"
"#endif \n"
#endif
"#define VERTEX VERTEX \n"
@ -46,7 +47,9 @@ const char* lovrShaderVertexPrefix = ""
"in vec4 lovrBoneWeights; \n"
"out vec2 texCoord; \n"
"out vec4 vertexColor; \n"
"uniform int lovrEye; \n"
"int lovrEye; \n"
"uniform int _lovrEye; \n"
"uniform int lovrIsStereo; \n"
"uniform mat4 lovrModel; \n"
"uniform mat4 lovrViews[2]; \n"
"uniform mat4 lovrProjections[2]; \n"
@ -67,15 +70,18 @@ const char* lovrShaderVertexSuffix = ""
" lovrPose[lovrBones[2]] * lovrBoneWeights[2] + \n"
" lovrPose[lovrBones[3]] * lovrBoneWeights[3]; \n"
" gl_PointSize = lovrPointSize; \n"
"#if defined(GL_NV_viewport_array2) && defined(GL_NV_stereo_view_rendering) \n"
" if (lovrEye < 0) { \n"
"#ifdef SUPPORTS_SINGLEPASS \n"
" if (lovrIsStereo != 0) { \n"
" lovrEye = 0; \n"
" gl_Position = position(lovrProjections[0], lovrTransforms[0], pose * vec4(lovrPosition, 1.0)); \n"
" lovrEye = 1; \n"
" gl_SecondaryPositionNV = position(lovrProjections[1], lovrTransforms[1], pose * vec4(lovrPosition, 1.0)); \n"
" gl_ViewportMask[0] = (1 << 0); \n"
" gl_SecondaryViewportMaskNV[0] = (1 << 1); \n"
" return; \n"
" }\n"
"#endif \n"
" lovrEye = _lovrEye; \n"
" gl_Position = position(lovrProjection, lovrTransform, pose * vec4(lovrPosition, 1.0)); \n"
"}";
@ -87,6 +93,7 @@ const char* lovrShaderFragmentPrefix = ""
"#version 150 \n"
"#extension GL_NV_viewport_array2 : enable \n"
"#extension GL_ARB_fragment_layer_viewport : enable \n"
"#define SUPPORTS_SINGLEPASS GL_NV_stereo_view_rendering \n"
"in vec4 gl_FragCoord; \n"
#endif
"#define PIXEL PIXEL \n"
@ -94,6 +101,9 @@ const char* lovrShaderFragmentPrefix = ""
"in vec2 texCoord; \n"
"in vec4 vertexColor; \n"
"out vec4 lovrCanvas[gl_MaxDrawBuffers]; \n"
"int lovrEye; \n"
"uniform int _lovrEye; \n"
"uniform int lovrIsStereo; \n"
"uniform float lovrMetalness; \n"
"uniform float lovrRoughness; \n"
"uniform vec4 lovrColor; \n"
@ -110,6 +120,12 @@ const char* lovrShaderFragmentPrefix = ""
const char* lovrShaderFragmentSuffix = ""
"void main() { \n"
" lovrEye = _lovrEye; \n"
"#ifdef SUPPORTS_SINGLEPASS \n"
" if (lovrIsStereo != 0) { \n"
" lovrEye = gl_ViewportIndex; \n"
" } \n"
"#endif \n"
"#ifdef MULTICANVAS \n"
" colors(lovrColor, lovrDiffuseTexture, texCoord); \n"
"#else \n"
@ -137,25 +153,26 @@ const char* lovrDefaultFragmentShader = ""
"}";
const char* lovrCubeVertexShader = ""
"out vec3 texturePosition; \n"
"out vec3 texturePosition[2]; \n"
"vec4 position(mat4 projection, mat4 transform, vec4 vertex) { \n"
" texturePosition = inverse(mat3(transform)) * (inverse(projection) * vertex).xyz; \n"
" texturePosition.y *= -1.; \n"
" texturePosition[lovrEye] = inverse(mat3(transform)) * (inverse(projection) * vertex).xyz; \n"
" texturePosition[lovrEye].y *= -1.; \n"
" return vertex; \n"
"}";
const char* lovrCubeFragmentShader = ""
"in vec3 texturePosition; \n"
"in vec3 texturePosition[2]; \n"
"vec4 color(vec4 graphicsColor, sampler2D image, vec2 uv) { \n"
" return graphicsColor * texture(lovrEnvironmentTexture, texturePosition); \n"
" return graphicsColor * texture(lovrEnvironmentTexture, texturePosition[lovrEye]); \n"
"}";
const char* lovrPanoFragmentShader = ""
"in vec3 texturePosition; \n"
"in vec3 texturePosition[2]; \n"
"#define PI 3.141592653589 \n"
"vec4 color(vec4 graphicsColor, sampler2D image, vec2 uv) { \n"
" float theta = acos(texturePosition.y / length(texturePosition)); \n"
" float phi = atan(texturePosition.x, texturePosition.z); \n"
" vec3 direction = texturePosition[lovrEye]; \n"
" float theta = acos(direction.y / length(direction)); \n"
" float phi = atan(direction.x, direction.z); \n"
" uv = vec2(.5 + phi / (2. * PI), theta / PI); \n"
" return graphicsColor * texture(lovrDiffuseTexture, uv); \n"
"}";