diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 45fd7ebc09..185191b8ce 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -3130,27 +3130,19 @@ void Application::updateShadowMap(RenderArgs* renderArgs) { activeRenderingThread = nullptr; } -const GLfloat WORLD_AMBIENT_COLOR[] = { 0.525f, 0.525f, 0.6f }; -const GLfloat WORLD_DIFFUSE_COLOR[] = { 0.6f, 0.525f, 0.525f }; -const GLfloat WORLD_SPECULAR_COLOR[] = { 0.08f, 0.08f, 0.08f, 1.0f }; - -const glm::vec3 GLOBAL_LIGHT_COLOR = { 0.6f, 0.525f, 0.525f }; - -void Application::setupWorldLight() { - - // Setup 3D lights (after the camera transform, so that they are positioned in world space) - glEnable(GL_COLOR_MATERIAL); - glColorMaterial(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE); - - glm::vec3 sunDirection = getSunDirection(); - GLfloat light_position0[] = { sunDirection.x, sunDirection.y, sunDirection.z, 0.0 }; - glLightfv(GL_LIGHT0, GL_POSITION, light_position0); - glLightfv(GL_LIGHT0, GL_AMBIENT, WORLD_AMBIENT_COLOR); - glLightfv(GL_LIGHT0, GL_DIFFUSE, WORLD_DIFFUSE_COLOR); - glLightfv(GL_LIGHT0, GL_SPECULAR, WORLD_SPECULAR_COLOR); - glMaterialfv(GL_FRONT, GL_SPECULAR, WORLD_SPECULAR_COLOR); - glMateriali(GL_FRONT, GL_SHININESS, 96); +static gpu::Light defaultLight{ + vec3( 0.525f, 0.525f, 0.6f), // ambient + vec3( 0.6f, 0.525f, 0.525f), // diffuse + vec4(0.08f, 0.08f, 0.08f, 1.0f), // specular + vec4( 0, 0, 0, 0 ), // position + 96 // shininess +}; +void Application::setupWorldLight(RenderArgs* renderArgs) { + gpu::Batch batch; + defaultLight._position = vec4(getSunDirection(), 0); + batch.setLight(0, defaultLight); + renderArgs->_context->render(batch); } bool Application::shouldRenderMesh(float largestDimension, float distanceToCamera) { @@ -3418,7 +3410,7 @@ void Application::displaySide(RenderArgs* renderArgs, Camera& theCamera, bool se // Setup 3D lights (after the camera transform, so that they are positioned in world space) { PerformanceTimer perfTimer("lights"); - setupWorldLight(); + setupWorldLight(renderArgs); } // setup shadow matrices (again, after the camera transform) diff --git a/interface/src/Application.h b/interface/src/Application.h index c5445db1e8..3cdf6e729a 100644 --- a/interface/src/Application.h +++ b/interface/src/Application.h @@ -262,7 +262,7 @@ public: void controlledBroadcastToNodes(const QByteArray& packet, const NodeSet& destinationNodeTypes); - virtual void setupWorldLight(); + virtual void setupWorldLight(RenderArgs* renderArgs); virtual bool shouldRenderMesh(float largestDimension, float distanceToCamera); QImage renderAvatarBillboard(RenderArgs* renderArgs); diff --git a/libraries/gpu/src/gpu/Batch.cpp b/libraries/gpu/src/gpu/Batch.cpp index e3e9088afa..f8d530bb74 100644 --- a/libraries/gpu/src/gpu/Batch.cpp +++ b/libraries/gpu/src/gpu/Batch.cpp @@ -288,3 +288,26 @@ void Batch::getQuery(const QueryPointer& query) { _params.push_back(_queries.cache(query)); } + +void push_back(Batch::Params& params, const vec3& v) { + params.push_back(v.x); + params.push_back(v.y); + params.push_back(v.z); +} + +void push_back(Batch::Params& params, const vec4& v) { + params.push_back(v.x); + params.push_back(v.y); + params.push_back(v.z); + params.push_back(v.a); +} + +void Batch::setLight(uint8_t index, const Light& light) { + ADD_COMMAND(setLight); + _params.push_back(index); + push_back(_params, light._ambientColor); + push_back(_params, light._diffuseColor); + push_back(_params, light._position); + push_back(_params, light._specularColor); + _params.push_back(light._shininess); +} \ No newline at end of file diff --git a/libraries/gpu/src/gpu/Batch.h b/libraries/gpu/src/gpu/Batch.h index 2f1d2e8ece..3954127783 100644 --- a/libraries/gpu/src/gpu/Batch.h +++ b/libraries/gpu/src/gpu/Batch.h @@ -14,6 +14,7 @@ #include #include "Framebuffer.h" +#include "Light.h" #include "Pipeline.h" #include "Query.h" #include "Stream.h" @@ -76,6 +77,8 @@ public: void setIndexBuffer(Type type, const BufferPointer& buffer, Offset offset); void setIndexBuffer(const BufferView& buffer); // not a command, just a shortcut from a BufferView + void setLight(uint8_t index, const Light& light); + // Transform Stage // Vertex position is transformed by ModelTransform from object space to world space // Then by the inverse of the ViewTransform from world space to eye space @@ -169,6 +172,8 @@ public: COMMAND_setInputBuffer, COMMAND_setIndexBuffer, + COMMAND_setLight, + COMMAND_setModelTransform, COMMAND_setViewTransform, COMMAND_setProjectionTransform, diff --git a/libraries/gpu/src/gpu/GLBackend.cpp b/libraries/gpu/src/gpu/GLBackend.cpp index 29f432e498..f6b9bb8706 100644 --- a/libraries/gpu/src/gpu/GLBackend.cpp +++ b/libraries/gpu/src/gpu/GLBackend.cpp @@ -26,6 +26,8 @@ GLBackend::CommandCall GLBackend::_commandCalls[Batch::NUM_COMMANDS] = (&::gpu::GLBackend::do_setInputBuffer), (&::gpu::GLBackend::do_setIndexBuffer), + (&::gpu::GLBackend::do_setLight), + (&::gpu::GLBackend::do_setModelTransform), (&::gpu::GLBackend::do_setViewTransform), (&::gpu::GLBackend::do_setProjectionTransform), @@ -747,45 +749,3 @@ void GLBackend::do_glLineWidth(Batch& batch, uint32 paramOffset) { glLineWidth(batch._params[paramOffset]._float); (void) CHECK_GL_ERROR(); } - -void GLBackend::loadMatrix(GLenum target, const glm::mat4 & m) { - glMatrixMode(target); - glLoadMatrixf(glm::value_ptr(m)); -} - -void GLBackend::fetchMatrix(GLenum target, glm::mat4 & m) { - switch (target) { - case GL_MODELVIEW_MATRIX: - case GL_PROJECTION_MATRIX: - break; - - // Lazy cheating - case GL_MODELVIEW: - target = GL_MODELVIEW_MATRIX; - break; - case GL_PROJECTION: - target = GL_PROJECTION_MATRIX; - break; - default: - Q_ASSERT_X(false, "GLBackend::fetchMatrix", "Bad matrix target"); - } - glGetFloatv(target, glm::value_ptr(m)); -} - -void GLBackend::checkGLStackStable(std::function f) { -#ifdef DEBUG - GLint mvDepth, prDepth; - glGetIntegerv(GL_MODELVIEW_STACK_DEPTH, &mvDepth); - glGetIntegerv(GL_PROJECTION_STACK_DEPTH, &prDepth); -#endif - - f(); - -#ifdef DEBUG - GLint mvDepthFinal, prDepthFinal; - glGetIntegerv(GL_MODELVIEW_STACK_DEPTH, &mvDepthFinal); - glGetIntegerv(GL_PROJECTION_STACK_DEPTH, &prDepthFinal); - Q_ASSERT(mvDepth == mvDepthFinal); - Q_ASSERT(prDepth == prDepthFinal); -#endif -} diff --git a/libraries/gpu/src/gpu/GLBackend.h b/libraries/gpu/src/gpu/GLBackend.h index 2cdab49f29..eab880f14d 100644 --- a/libraries/gpu/src/gpu/GLBackend.h +++ b/libraries/gpu/src/gpu/GLBackend.h @@ -107,10 +107,6 @@ public: static GLShader* syncGPUObject(const Shader& shader); static GLuint getShaderID(const ShaderPointer& shader); - // FIXME: Please remove these 2 calls once the text renderer doesn't use naked gl calls anymore - static void loadMatrix(GLenum target, const glm::mat4 & m); - static void fetchMatrix(GLenum target, glm::mat4 & m); - class GLState : public GPUObject { public: class Command { @@ -257,6 +253,8 @@ protected: void do_setInputBuffer(Batch& batch, uint32 paramOffset); void do_setIndexBuffer(Batch& batch, uint32 paramOffset); + void do_setLight(Batch& batch, uint32 paramOffset); + void initInput(); void killInput(); void syncInputStateCache(); diff --git a/libraries/gpu/src/gpu/GLBackendInput.cpp b/libraries/gpu/src/gpu/GLBackendInput.cpp index 34b1b1761f..e356dbcb9a 100755 --- a/libraries/gpu/src/gpu/GLBackendInput.cpp +++ b/libraries/gpu/src/gpu/GLBackendInput.cpp @@ -298,3 +298,31 @@ void GLBackend::do_setIndexBuffer(Batch& batch, uint32 paramOffset) { } (void) CHECK_GL_ERROR(); } + +template +void popParam(Batch::Params& params, uint32& paramOffset, V& v) { + for (size_t i = 0; i < v.length(); ++i) { + v[i] = params[paramOffset++]._float; + } +} + +void GLBackend::do_setLight(Batch& batch, uint32 paramOffset) { + int index = batch._params[paramOffset++]._uint; + gpu::Light light; + popParam(batch._params, paramOffset, light._ambientColor); + popParam(batch._params, paramOffset, light._diffuseColor); + popParam(batch._params, paramOffset, light._position); + popParam(batch._params, paramOffset, light._specularColor); + light._shininess = batch._params[paramOffset++]._int; + + // Setup 3D lights (after the camera transform, so that they are positioned in world space) + glEnable(GL_COLOR_MATERIAL); + glColorMaterial(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE); + glLightfv(GL_LIGHT0 + index, GL_POSITION, &light._position.x); + glLightfv(GL_LIGHT0 + index, GL_AMBIENT, &light._ambientColor.r); + glLightfv(GL_LIGHT0 + index, GL_DIFFUSE, &light._diffuseColor.r); + glLightfv(GL_LIGHT0 + index, GL_SPECULAR, &light._specularColor.r); + glMaterialfv(GL_FRONT + index, GL_SPECULAR, &light._specularColor.r); + glMateriali(GL_FRONT + index, GL_SHININESS, light._shininess); +} + diff --git a/libraries/gpu/src/gpu/GLBackendShared.h b/libraries/gpu/src/gpu/GLBackendShared.h index 365934379f..27f58fcbe3 100644 --- a/libraries/gpu/src/gpu/GLBackendShared.h +++ b/libraries/gpu/src/gpu/GLBackendShared.h @@ -53,6 +53,4 @@ static const GLenum _elementTypeToGLType[gpu::NUM_TYPES] = { // #define CHECK_GL_ERROR() gpu::GLBackend::checkGLErrorDebug(__FUNCTION__ ":" CHECK_GL_ERROR_HELPER(__LINE__)) #define CHECK_GL_ERROR() gpu::GLBackend::checkGLErrorDebug(__FUNCTION__) -#define CHECK_GL_STACK_STABLE(f) gpu::GLBackend::checkGLStackStable(f) - #endif diff --git a/libraries/gpu/src/gpu/Light.h b/libraries/gpu/src/gpu/Light.h new file mode 100644 index 0000000000..080a117405 --- /dev/null +++ b/libraries/gpu/src/gpu/Light.h @@ -0,0 +1,31 @@ +// +// Created by Bradley Austin Davis 2015/07/18 +// Copyright 2014 High Fidelity, Inc. +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +// +#pragma once +#ifndef hifi_gpu_Light_h +#define hifi_gpu_Light_h + +#include + +namespace gpu { + +struct Light { + Light() {} + Light(const vec3& ambient, const vec3& diffuse, const vec4& position, const vec4& specular = vec4(), int shininess = 0) : + _ambientColor(ambient), _diffuseColor(diffuse), _specularColor(specular), _position(position), _shininess(shininess) { + + } + vec3 _ambientColor; + vec3 _diffuseColor; + vec4 _position; + vec4 _specularColor; + int _shininess{0}; +}; + +} + +#endif