refactor: Refactor shader uniform management
This commit is contained in:
parent
ef2d119783
commit
a541782f08
15 changed files with 531 additions and 412 deletions
|
@ -123,24 +123,26 @@ void Console::executeInputText() {
|
|||
|
||||
void Console::render() const {
|
||||
float height = kLineCount * _font->height();
|
||||
{
|
||||
glm::mat4 transform(1.0f);
|
||||
transform = glm::scale(transform, glm::vec3(_opts.width, height, 1.0f));
|
||||
|
||||
glm::mat4 model(1.0f);
|
||||
model = glm::scale(model, glm::vec3(_opts.width, height, 1.0f));
|
||||
|
||||
ShaderManager &shaders = Shaders;
|
||||
shaders.activate(ShaderProgram::GUIGUI);
|
||||
shaders.setUniform("model", model);
|
||||
shaders.setUniform("color", glm::vec3(0.0f));
|
||||
shaders.setUniform("alpha", 0.5f);
|
||||
LocalUniforms locals;
|
||||
locals.model = move(transform);
|
||||
locals.color = glm::vec3(0.0f);
|
||||
locals.alpha = 0.5f;
|
||||
|
||||
Shaders.activate(ShaderProgram::GUIGUI, locals);
|
||||
}
|
||||
DefaultQuad.render(GL_TRIANGLES);
|
||||
|
||||
string text("> " + _inputText);
|
||||
{
|
||||
glm::mat4 transform(1.0f);
|
||||
transform = glm::translate(transform, glm::vec3(3.0f, height - 0.5f * _font->height(), 0.0f));
|
||||
|
||||
glm::mat4 transform(1.0f);
|
||||
transform = glm::translate(transform, glm::vec3(3.0f, height - 0.5f * _font->height(), 0.0f));
|
||||
|
||||
_font->render(text, transform, glm::vec3(1.0f), TextGravity::Right);
|
||||
_font->render(text, transform, glm::vec3(1.0f), TextGravity::Right);
|
||||
}
|
||||
}
|
||||
|
||||
bool Console::isOpen() const {
|
||||
|
|
|
@ -223,10 +223,10 @@ void Game::drawWorld() {
|
|||
void Game::drawGUI() {
|
||||
glDisable(GL_DEPTH_TEST);
|
||||
|
||||
ShaderUniforms uniforms;
|
||||
uniforms.projection = glm::ortho(0.0f, static_cast<float>(_options.graphics.width), static_cast<float>(_options.graphics.height), 0.0f);
|
||||
GlobalUniforms globals;
|
||||
globals.projection = glm::ortho(0.0f, static_cast<float>(_options.graphics.width), static_cast<float>(_options.graphics.height), 0.0f);
|
||||
|
||||
Shaders.setGlobalUniforms(uniforms);
|
||||
Shaders.setGlobalUniforms(globals);
|
||||
|
||||
switch (_screen) {
|
||||
case Screen::InGame:
|
||||
|
@ -252,10 +252,10 @@ void Game::drawGUI() {
|
|||
void Game::drawGUI3D() {
|
||||
glDisable(GL_DEPTH_TEST);
|
||||
|
||||
ShaderUniforms uniforms;
|
||||
uniforms.projection = glm::ortho(0.0f, static_cast<float>(_options.graphics.width), static_cast<float>(_options.graphics.height), 0.0f);
|
||||
GlobalUniforms globals;
|
||||
globals.projection = glm::ortho(0.0f, static_cast<float>(_options.graphics.width), static_cast<float>(_options.graphics.height), 0.0f);
|
||||
|
||||
Shaders.setGlobalUniforms(uniforms);
|
||||
Shaders.setGlobalUniforms(globals);
|
||||
|
||||
switch (_screen) {
|
||||
case Screen::MainMenu:
|
||||
|
@ -271,10 +271,11 @@ void Game::drawGUI3D() {
|
|||
void Game::drawCursor() {
|
||||
glDisable(GL_DEPTH_TEST);
|
||||
|
||||
ShaderUniforms uniforms;
|
||||
uniforms.projection = glm::ortho(0.0f, static_cast<float>(_options.graphics.width), static_cast<float>(_options.graphics.height), 0.0f);
|
||||
GlobalUniforms globals;
|
||||
globals.projection = glm::ortho(0.0f, static_cast<float>(_options.graphics.width), static_cast<float>(_options.graphics.height), 0.0f);
|
||||
globals.view = glm::mat4(1.0f);
|
||||
|
||||
Shaders.setGlobalUniforms(uniforms);
|
||||
Shaders.setGlobalUniforms(globals);
|
||||
|
||||
_window.drawCursor();
|
||||
}
|
||||
|
|
|
@ -23,6 +23,8 @@
|
|||
#include "../../render/shaders.h"
|
||||
#include "../../resources/resources.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
using namespace reone::render;
|
||||
using namespace reone::resources;
|
||||
|
||||
|
@ -55,10 +57,10 @@ void TargetOverlay::drawReticle(Texture &texture, const glm::vec3 &screenCoords)
|
|||
transform = glm::translate(transform, glm::vec3((_opts.width * screenCoords.x) - width / 2, (_opts.height * (1.0f - screenCoords.y)) - height / 2, 0.0f));
|
||||
transform = glm::scale(transform, glm::vec3(width, height, 1.0f));
|
||||
|
||||
ShaderManager &shaders = Shaders;
|
||||
shaders.activate(ShaderProgram::GUIGUI);
|
||||
shaders.setUniform("model", transform);
|
||||
shaders.setUniform("alpha", 1.0f);
|
||||
LocalUniforms locals;
|
||||
locals.model = move(transform);
|
||||
|
||||
Shaders.activate(ShaderProgram::GUIGUI, locals);
|
||||
|
||||
glActiveTexture(GL_TEXTURE0);
|
||||
texture.bind();
|
||||
|
|
|
@ -212,11 +212,6 @@ void Control::update(float dt) {
|
|||
void Control::render(const glm::ivec2 &offset, const string &textOverride) const {
|
||||
if (!_visible) return;
|
||||
|
||||
ShaderManager &shaders = Shaders;
|
||||
shaders.activate(ShaderProgram::GUIGUI);
|
||||
shaders.setUniform("color", glm::vec3(1.0f));
|
||||
shaders.setUniform("alpha", 1.0f);
|
||||
|
||||
glm::ivec2 size(_extent.width, _extent.height);
|
||||
|
||||
if (_focus && _hilight) {
|
||||
|
@ -233,6 +228,7 @@ void Control::render(const glm::ivec2 &offset, const string &textOverride) const
|
|||
|
||||
void Control::drawBorder(const Border &border, const glm::ivec2 &offset, const glm::ivec2 &size) const {
|
||||
ShaderManager &shaders = Shaders;
|
||||
|
||||
Quad &defaultQuad = DefaultQuad;
|
||||
Quad &xFlippedQuad = XFlippedQuad;
|
||||
Quad &yFlippedQuad = YFlippedQuad;
|
||||
|
@ -241,15 +237,22 @@ void Control::drawBorder(const Border &border, const glm::ivec2 &offset, const g
|
|||
glActiveTexture(GL_TEXTURE0);
|
||||
|
||||
if (border.fill) {
|
||||
int x = _extent.left + border.dimension + offset.x;
|
||||
int y = _extent.top + border.dimension + offset.y;
|
||||
int w = size.x - 2 * border.dimension;
|
||||
int h = size.y - 2 * border.dimension;
|
||||
{
|
||||
int x = _extent.left + border.dimension + offset.x;
|
||||
int y = _extent.top + border.dimension + offset.y;
|
||||
int w = size.x - 2 * border.dimension;
|
||||
int h = size.y - 2 * border.dimension;
|
||||
|
||||
glm::mat4 transform(glm::translate(glm::mat4(1.0f), glm::vec3(x, y, 0.0f)));
|
||||
transform = glm::scale(transform, glm::vec3(w, h, 1.0f));
|
||||
glm::mat4 transform(1.0f);
|
||||
transform = glm::translate(transform, glm::vec3(x, y, 0.0f));
|
||||
transform = glm::scale(transform, glm::vec3(w, h, 1.0f));
|
||||
|
||||
LocalUniforms locals;
|
||||
locals.model = move(transform);
|
||||
|
||||
shaders.activate(ShaderProgram::GUIGUI, locals);
|
||||
}
|
||||
|
||||
shaders.setUniform("model", transform);
|
||||
border.fill->bind();
|
||||
|
||||
GLint blendSrcRgb, blendSrcAlpha, blendDstRgb, blendDstAlpha;
|
||||
|
@ -261,20 +264,17 @@ void Control::drawBorder(const Border &border, const glm::ivec2 &offset, const g
|
|||
glGetIntegerv(GL_BLEND_DST_ALPHA, &blendDstAlpha);
|
||||
glBlendFunc(GL_ONE, GL_ONE);
|
||||
}
|
||||
|
||||
defaultQuad.render(GL_TRIANGLES);
|
||||
|
||||
if (additive) {
|
||||
glBlendFuncSeparate(blendSrcRgb, blendDstRgb, blendSrcAlpha, blendDstAlpha);
|
||||
}
|
||||
|
||||
border.fill->unbind();
|
||||
}
|
||||
if (border.edge) {
|
||||
int width = size.x - 2 * border.dimension;
|
||||
int height = size.y - 2 * border.dimension;
|
||||
glm::mat4 edgeTransform(1.0f);
|
||||
shaders.setUniform("color", border.color);
|
||||
|
||||
border.edge->bind();
|
||||
|
||||
if (height > 0.0f) {
|
||||
|
@ -282,18 +282,34 @@ void Control::drawBorder(const Border &border, const glm::ivec2 &offset, const g
|
|||
int y = _extent.top + border.dimension + offset.y;
|
||||
|
||||
// Left edge
|
||||
edgeTransform = glm::translate(glm::mat4(1.0f), glm::vec3(x, y, 0.0f));
|
||||
edgeTransform = glm::scale(edgeTransform, glm::vec3(border.dimension, height, 1.0f));
|
||||
edgeTransform = glm::rotate(edgeTransform, glm::half_pi<float>(), glm::vec3(0.0f, 0.0f, 1.0f));
|
||||
edgeTransform = glm::rotate(edgeTransform, glm::pi<float>(), glm::vec3(1.0f, 0.0f, 0.0f));
|
||||
shaders.setUniform("model", edgeTransform);
|
||||
{
|
||||
glm::mat4 transform(1.0f);
|
||||
transform = glm::translate(transform, glm::vec3(x, y, 0.0f));
|
||||
transform = glm::scale(transform, glm::vec3(border.dimension, height, 1.0f));
|
||||
transform = glm::rotate(transform, glm::half_pi<float>(), glm::vec3(0.0f, 0.0f, 1.0f));
|
||||
transform = glm::rotate(transform, glm::pi<float>(), glm::vec3(1.0f, 0.0f, 0.0f));
|
||||
|
||||
LocalUniforms locals;
|
||||
locals.model = move(transform);
|
||||
locals.color = border.color;
|
||||
|
||||
shaders.activate(ShaderProgram::GUIGUI, locals);
|
||||
}
|
||||
defaultQuad.render(GL_TRIANGLES);
|
||||
|
||||
// Right edge
|
||||
edgeTransform = glm::translate(glm::mat4(1.0f), glm::vec3(x + size.x, y, 0.0f));
|
||||
edgeTransform = glm::scale(edgeTransform, glm::vec3(border.dimension, height, 1.0f));
|
||||
edgeTransform = glm::rotate(edgeTransform, glm::half_pi<float>(), glm::vec3(0.0f, 0.0f, 1.0f));
|
||||
shaders.setUniform("model", edgeTransform);
|
||||
{
|
||||
glm::mat4 transform(1.0f);
|
||||
transform = glm::translate(transform, glm::vec3(x + size.x, y, 0.0f));
|
||||
transform = glm::scale(transform, glm::vec3(border.dimension, height, 1.0f));
|
||||
transform = glm::rotate(transform, glm::half_pi<float>(), glm::vec3(0.0f, 0.0f, 1.0f));
|
||||
|
||||
LocalUniforms locals;
|
||||
locals.model = move(transform);
|
||||
locals.color = border.color;
|
||||
|
||||
shaders.activate(ShaderProgram::GUIGUI, locals);
|
||||
}
|
||||
xFlippedQuad.render(GL_TRIANGLES);
|
||||
}
|
||||
|
||||
|
@ -302,15 +318,31 @@ void Control::drawBorder(const Border &border, const glm::ivec2 &offset, const g
|
|||
int y = _extent.top + offset.y;
|
||||
|
||||
// Top edge
|
||||
edgeTransform = glm::translate(glm::mat4(1.0f), glm::vec3(x, y, 0.0f));
|
||||
edgeTransform = glm::scale(edgeTransform, glm::vec3(width, border.dimension, 1.0f));
|
||||
shaders.setUniform("model", edgeTransform);
|
||||
{
|
||||
glm::mat4 transform(1.0f);
|
||||
transform = glm::translate(transform, glm::vec3(x, y, 0.0f));
|
||||
transform = glm::scale(transform, glm::vec3(width, border.dimension, 1.0f));
|
||||
|
||||
LocalUniforms locals;
|
||||
locals.model = move(transform);
|
||||
locals.color = border.color;
|
||||
|
||||
shaders.activate(ShaderProgram::GUIGUI, locals);
|
||||
}
|
||||
defaultQuad.render(GL_TRIANGLES);
|
||||
|
||||
// Bottom edge
|
||||
edgeTransform = glm::translate(glm::mat4(1.0f), glm::vec3(x, y + size.y - border.dimension, 0.0f));
|
||||
edgeTransform = glm::scale(edgeTransform, glm::vec3(width, border.dimension, 1.0f));
|
||||
shaders.setUniform("model", edgeTransform);
|
||||
{
|
||||
glm::mat4 transform(1.0f);
|
||||
transform = glm::translate(transform, glm::vec3(x, y + size.y - border.dimension, 0.0f));
|
||||
transform = glm::scale(transform, glm::vec3(width, border.dimension, 1.0f));
|
||||
|
||||
LocalUniforms locals;
|
||||
locals.model = move(transform);
|
||||
locals.color = border.color;
|
||||
|
||||
shaders.activate(ShaderProgram::GUIGUI, locals);
|
||||
}
|
||||
yFlippedQuad.render(GL_TRIANGLES);
|
||||
}
|
||||
|
||||
|
@ -319,31 +351,63 @@ void Control::drawBorder(const Border &border, const glm::ivec2 &offset, const g
|
|||
if (border.corner) {
|
||||
int x = _extent.left + offset.x;
|
||||
int y = _extent.top + offset.y;
|
||||
glm::mat4 cornerTransform(1.0f);
|
||||
|
||||
border.corner->bind();
|
||||
|
||||
// Top left corner
|
||||
cornerTransform = glm::translate(glm::mat4(1.0f), glm::vec3(x, y, 0.0f));
|
||||
cornerTransform = glm::scale(cornerTransform, glm::vec3(border.dimension, border.dimension, 1.0f));
|
||||
shaders.setUniform("model", cornerTransform);
|
||||
{
|
||||
glm::mat4 transform(1.0f);
|
||||
transform = glm::translate(transform, glm::vec3(x, y, 0.0f));
|
||||
transform = glm::scale(transform, glm::vec3(border.dimension, border.dimension, 1.0f));
|
||||
|
||||
LocalUniforms locals;
|
||||
locals.model = move(transform);
|
||||
locals.color = border.color;
|
||||
|
||||
shaders.activate(ShaderProgram::GUIGUI, locals);
|
||||
}
|
||||
defaultQuad.render(GL_TRIANGLES);
|
||||
|
||||
// Bottom left corner
|
||||
cornerTransform = glm::translate(glm::mat4(1.0f), glm::vec3(x, y + size.y - border.dimension, 0.0f));
|
||||
cornerTransform = glm::scale(cornerTransform, glm::vec3(border.dimension, border.dimension, 1.0f));
|
||||
shaders.setUniform("model", cornerTransform);
|
||||
{
|
||||
glm::mat4 transform(1.0f);
|
||||
transform = glm::translate(transform, glm::vec3(x, y + size.y - border.dimension, 0.0f));
|
||||
transform = glm::scale(transform, glm::vec3(border.dimension, border.dimension, 1.0f));
|
||||
|
||||
LocalUniforms locals;
|
||||
locals.model = move(transform);
|
||||
locals.color = border.color;
|
||||
|
||||
shaders.activate(ShaderProgram::GUIGUI, locals);
|
||||
}
|
||||
yFlippedQuad.render(GL_TRIANGLES);
|
||||
|
||||
// Top right corner
|
||||
cornerTransform = glm::translate(glm::mat4(1.0f), glm::vec3(x + size.x - border.dimension, y, 0.0f));
|
||||
cornerTransform = glm::scale(cornerTransform, glm::vec3(border.dimension, border.dimension, 1.0f));
|
||||
shaders.setUniform("model", cornerTransform);
|
||||
{
|
||||
glm::mat4 transform(1.0f);
|
||||
transform = glm::translate(transform, glm::vec3(x + size.x - border.dimension, y, 0.0f));
|
||||
transform = glm::scale(transform, glm::vec3(border.dimension, border.dimension, 1.0f));
|
||||
|
||||
LocalUniforms locals;
|
||||
locals.model = move(transform);
|
||||
locals.color = border.color;
|
||||
|
||||
shaders.activate(ShaderProgram::GUIGUI, locals);
|
||||
}
|
||||
xFlippedQuad.render(GL_TRIANGLES);
|
||||
|
||||
// Bottom right corner
|
||||
cornerTransform = glm::translate(glm::mat4(1.0f), glm::vec3(x + size.x - border.dimension, y + size.y - border.dimension, 0.0f));
|
||||
cornerTransform = glm::scale(cornerTransform, glm::vec3(border.dimension, border.dimension, 1.0f));
|
||||
shaders.setUniform("model", cornerTransform);
|
||||
{
|
||||
glm::mat4 transform(1.0f);
|
||||
transform = glm::translate(transform, glm::vec3(x + size.x - border.dimension, y + size.y - border.dimension, 0.0f));
|
||||
transform = glm::scale(transform, glm::vec3(border.dimension, border.dimension, 1.0f));
|
||||
|
||||
LocalUniforms locals;
|
||||
locals.model = move(transform);
|
||||
locals.color = border.color;
|
||||
|
||||
shaders.activate(ShaderProgram::GUIGUI, locals);
|
||||
}
|
||||
xyFlippedQuad.render(GL_TRIANGLES);
|
||||
|
||||
border.corner->unbind();
|
||||
|
@ -438,21 +502,21 @@ void Control::render3D(const glm::ivec2 &offset) const {
|
|||
glGetIntegerv(GL_VIEWPORT, viewport);
|
||||
|
||||
ShaderManager &shaders = Shaders;
|
||||
ShaderUniforms uniforms;
|
||||
Framebuffer *framebuffer = _scene3d.framebuffer.get();
|
||||
|
||||
// Render to framebuffer
|
||||
{
|
||||
GlobalUniforms globals;
|
||||
globals.projection = glm::ortho(
|
||||
0.0f,
|
||||
static_cast<float>(framebuffer->width()),
|
||||
static_cast<float>(framebuffer->height()),
|
||||
0.0f,
|
||||
-1024.0f,
|
||||
1024.0f);
|
||||
|
||||
uniforms.projection = glm::ortho(
|
||||
0.0f,
|
||||
static_cast<float>(framebuffer->width()),
|
||||
static_cast<float>(framebuffer->height()),
|
||||
0.0f,
|
||||
-1024.0f,
|
||||
1024.0f);
|
||||
|
||||
shaders.setGlobalUniforms(uniforms);
|
||||
|
||||
shaders.setGlobalUniforms(globals);
|
||||
}
|
||||
framebuffer->bind();
|
||||
|
||||
glEnable(GL_DEPTH_TEST);
|
||||
|
@ -466,19 +530,21 @@ void Control::render3D(const glm::ivec2 &offset) const {
|
|||
framebuffer->unbind();
|
||||
|
||||
// Render control
|
||||
{
|
||||
glm::mat4 transform(1.0f);
|
||||
transform = glm::translate(transform, glm::vec3(_extent.left + offset.x, _extent.top + offset.y, 0.0f));
|
||||
transform = glm::scale(transform, glm::vec3(_extent.width, _extent.height, 1.0f));
|
||||
|
||||
uniforms.projection = glm::ortho(0.0f, static_cast<float>(viewport[2]), static_cast<float>(viewport[3]), 0.0f);
|
||||
shaders.setGlobalUniforms(uniforms);
|
||||
GlobalUniforms globals;
|
||||
globals.projection = glm::ortho(0.0f, static_cast<float>(viewport[2]), static_cast<float>(viewport[3]), 0.0f);
|
||||
|
||||
glm::mat4 transform(1.0f);
|
||||
transform = glm::translate(transform, glm::vec3(_extent.left + offset.x, _extent.top + offset.y, 0.0f));
|
||||
transform = glm::scale(transform, glm::vec3(_extent.width, _extent.height, 1.0f));
|
||||
shaders.setGlobalUniforms(globals);
|
||||
|
||||
shaders.activate(ShaderProgram::GUIGUI);
|
||||
shaders.setUniform("model", transform);
|
||||
shaders.setUniform("color", glm::vec3(1.0f));
|
||||
shaders.setUniform("alpha", 1.0f);
|
||||
LocalUniforms locals;
|
||||
locals.model = move(transform);
|
||||
|
||||
shaders.activate(ShaderProgram::GUIGUI, locals);
|
||||
}
|
||||
glActiveTexture(GL_TEXTURE0);
|
||||
framebuffer->bindTexture();
|
||||
|
||||
|
|
|
@ -35,11 +35,6 @@ ImageButton::ImageButton() : Control(ControlType::ImageButton) {
|
|||
void ImageButton::render(const glm::ivec2 &offset, const string &textOverride, const shared_ptr<Texture> &icon) const {
|
||||
if (!_visible) return;
|
||||
|
||||
ShaderManager &shaders = Shaders;
|
||||
shaders.activate(ShaderProgram::GUIGUI);
|
||||
shaders.setUniform("color", glm::vec3(1.0f));
|
||||
shaders.setUniform("alpha", 1.0f);
|
||||
|
||||
glm::ivec2 borderOffset(offset);
|
||||
borderOffset.x += _extent.height;
|
||||
|
||||
|
@ -62,22 +57,25 @@ void ImageButton::render(const glm::ivec2 &offset, const string &textOverride, c
|
|||
void ImageButton::drawIcon(const glm::ivec2 &offset, const shared_ptr<Texture> &icon) const {
|
||||
if (!_iconFrame && !icon) return;
|
||||
|
||||
ShaderManager &shaders = Shaders;
|
||||
|
||||
glm::mat4 transform(1.0f);
|
||||
transform = glm::translate(transform, glm::vec3(offset.x + _extent.left, offset.y + _extent.top, 0.0f));
|
||||
transform = glm::scale(transform, glm::vec3(_extent.height, _extent.height, 1.0f));
|
||||
{
|
||||
glm::vec3 frameColor(1.0f);
|
||||
if (_focus && _hilight) {
|
||||
frameColor = _hilight->color;
|
||||
} else if (_border) {
|
||||
frameColor = _border->color;
|
||||
}
|
||||
|
||||
glm::vec3 frameColor(1.0f);
|
||||
if (_focus && _hilight) {
|
||||
frameColor = _hilight->color;
|
||||
} else if (_border) {
|
||||
frameColor = _border->color;
|
||||
LocalUniforms locals;
|
||||
locals.model = transform;
|
||||
locals.color = move(frameColor);
|
||||
|
||||
shaders.activate(ShaderProgram::GUIGUI, locals);
|
||||
}
|
||||
|
||||
ShaderManager &shaders = Shaders;
|
||||
shaders.setUniform("model", transform);
|
||||
shaders.setUniform("color", frameColor);
|
||||
shaders.setUniform("alpha", 1.0f);
|
||||
|
||||
glActiveTexture(0);
|
||||
|
||||
if (_iconFrame) {
|
||||
|
@ -85,9 +83,12 @@ void ImageButton::drawIcon(const glm::ivec2 &offset, const shared_ptr<Texture> &
|
|||
DefaultQuad.render(GL_TRIANGLES);
|
||||
_iconFrame->unbind();
|
||||
}
|
||||
{
|
||||
LocalUniforms locals;
|
||||
locals.model = transform;
|
||||
|
||||
shaders.setUniform("color", glm::vec3(1.0f));
|
||||
|
||||
shaders.activate(ShaderProgram::GUIGUI, locals);
|
||||
}
|
||||
if (icon) {
|
||||
icon->bind();
|
||||
DefaultQuad.render(GL_TRIANGLES);
|
||||
|
|
|
@ -50,10 +50,6 @@ void ScrollBar::load(const GffStruct &gffs) {
|
|||
void ScrollBar::render(const glm::ivec2 &offset, const string &textOverride) const {
|
||||
if (!_dir.image) return;
|
||||
|
||||
Shaders.activate(ShaderProgram::GUIGUI);
|
||||
Shaders.setUniform("color", glm::vec3(1.0f));
|
||||
Shaders.setUniform("alpha", 1.0f);
|
||||
|
||||
glActiveTexture(0);
|
||||
_dir.image->bind();
|
||||
|
||||
|
@ -64,21 +60,27 @@ void ScrollBar::render(const glm::ivec2 &offset, const string &textOverride) con
|
|||
}
|
||||
|
||||
void ScrollBar::drawUpArrow(const glm::vec2 &offset) const {
|
||||
glm::mat4 arrowTransform(glm::translate(glm::mat4(1.0f), glm::vec3(_extent.left + offset.x, _extent.top + offset.y, 0.0f)));
|
||||
arrowTransform = glm::scale(arrowTransform, glm::vec3(_extent.width, _extent.width, 1.0f));
|
||||
glm::mat4 transform(1.0f);
|
||||
transform = glm::translate(transform, glm::vec3(_extent.left + offset.x, _extent.top + offset.y, 0.0f));
|
||||
transform = glm::scale(transform, glm::vec3(_extent.width, _extent.width, 1.0f));
|
||||
|
||||
Shaders.setUniform("model", arrowTransform);
|
||||
LocalUniforms locals;
|
||||
locals.model = move(transform);
|
||||
|
||||
Shaders.activate(ShaderProgram::GUIGUI, locals);
|
||||
DefaultQuad.render(GL_TRIANGLES);
|
||||
}
|
||||
|
||||
void ScrollBar::drawDownArrow(const glm::vec2 &offset) const {
|
||||
glm::mat4 arrowTransform(glm::translate(glm::mat4(1.0f), glm::vec3(_extent.left + offset.x, _extent.top + _extent.height + offset.y, 0.0f)));
|
||||
arrowTransform = glm::scale(arrowTransform, glm::vec3(_extent.width, _extent.width, 1.0f));
|
||||
arrowTransform = glm::rotate(arrowTransform, glm::pi<float>(), glm::vec3(1.0f, 0.0f, 0.0f));
|
||||
glm::mat4 transform(1.0f);
|
||||
transform = glm::translate(transform, glm::vec3(_extent.left + offset.x, _extent.top + _extent.height + offset.y, 0.0f));
|
||||
transform = glm::scale(transform, glm::vec3(_extent.width, _extent.width, 1.0f));
|
||||
transform = glm::rotate(transform, glm::pi<float>(), glm::vec3(1.0f, 0.0f, 0.0f));
|
||||
|
||||
Shaders.setUniform("model", arrowTransform);
|
||||
LocalUniforms locals;
|
||||
locals.model = move(transform);
|
||||
|
||||
Shaders.activate(ShaderProgram::GUIGUI, locals);
|
||||
DefaultQuad.render(GL_TRIANGLES);
|
||||
}
|
||||
|
||||
|
|
|
@ -231,13 +231,13 @@ void GUI::render() const {
|
|||
}
|
||||
|
||||
void GUI::drawBackground() const {
|
||||
glm::mat4 transform(glm::scale(glm::mat4(1.0f), glm::vec3(_gfxOpts.width, _gfxOpts.height, 1.0f)));
|
||||
glm::mat4 transform(1.0f);
|
||||
transform = glm::scale(transform, glm::vec3(_gfxOpts.width, _gfxOpts.height, 1.0f));
|
||||
|
||||
ShaderManager &shaders = Shaders;
|
||||
shaders.activate(ShaderProgram::GUIGUI);
|
||||
shaders.setUniform("model", transform);
|
||||
shaders.setUniform("color", glm::vec3(1.0f));
|
||||
shaders.setUniform("alpha", 1.0f);
|
||||
LocalUniforms locals;
|
||||
locals.model = move(transform);
|
||||
|
||||
Shaders.activate(ShaderProgram::GUIGUI, locals);
|
||||
|
||||
glActiveTexture(0);
|
||||
_background->bind();
|
||||
|
|
|
@ -111,8 +111,6 @@ void Font::render(const string &text, const glm::mat4 &transform, const glm::vec
|
|||
if (text.empty()) return;
|
||||
|
||||
ShaderManager &shaders = Shaders;
|
||||
shaders.activate(ShaderProgram::GUIGUI);
|
||||
shaders.setUniform("color", color);
|
||||
|
||||
assert(_texture);
|
||||
glActiveTexture(GL_TEXTURE0);
|
||||
|
@ -139,8 +137,11 @@ void Font::render(const string &text, const glm::mat4 &transform, const glm::vec
|
|||
glm::mat4 textTransform(glm::translate(transform, textOffset));
|
||||
|
||||
for (auto &glyph : text) {
|
||||
assert(glyph < _glyphCount);
|
||||
shaders.setUniform("model", textTransform);
|
||||
LocalUniforms locals;
|
||||
locals.model = textTransform;
|
||||
locals.color = color;
|
||||
|
||||
shaders.activate(ShaderProgram::GUIGUI, locals);
|
||||
|
||||
int off = kIndicesPerGlyph * glyph * sizeof(uint16_t);
|
||||
glDrawElements(GL_TRIANGLES, kIndicesPerGlyph, GL_UNSIGNED_SHORT, reinterpret_cast<void *>(off));
|
||||
|
|
|
@ -63,12 +63,12 @@ AABBMesh::AABBMesh() {
|
|||
}
|
||||
|
||||
void AABBMesh::render(const AABB &aabb, const glm::mat4 &transform) const {
|
||||
glm::mat4 transform2(transform * aabb.transform());
|
||||
glm::mat4 finalTransform(transform * aabb.transform());
|
||||
|
||||
ShaderManager &shaders = Shaders;
|
||||
shaders.activate(ShaderProgram::ModelWhite);
|
||||
shaders.setUniform("model", transform2);
|
||||
shaders.setUniform("alpha", 1.0f);
|
||||
LocalUniforms locals;
|
||||
locals.model = finalTransform;
|
||||
|
||||
Shaders.activate(ShaderProgram::ModelWhite, locals);
|
||||
|
||||
Mesh::render(GL_LINES);
|
||||
}
|
||||
|
|
|
@ -61,10 +61,10 @@ CubeMesh::CubeMesh() {
|
|||
}
|
||||
|
||||
void CubeMesh::render(const glm::mat4 &transform) const {
|
||||
ShaderManager &shaders = Shaders;
|
||||
shaders.activate(ShaderProgram::ModelWhite);
|
||||
shaders.setUniform("model", transform);
|
||||
shaders.setUniform("alpha", 1.0f);
|
||||
LocalUniforms locals;
|
||||
locals.model = transform;
|
||||
|
||||
Shaders.activate(ShaderProgram::ModelWhite, locals);
|
||||
|
||||
Mesh::render(GL_TRIANGLES);
|
||||
}
|
||||
|
|
|
@ -55,53 +55,36 @@ void MeshSceneNode::updateDistanceToCamera(const glm::vec3 &cameraPosition) {
|
|||
_distanceToCamera = glm::distance2(_center, cameraPosition);
|
||||
}
|
||||
|
||||
static const string &getLightUniformName(int index, const char *propName) {
|
||||
static unordered_map<int, unordered_map<const char *, string>> cache;
|
||||
auto &cacheByIndex = cache[index];
|
||||
|
||||
auto nameIt = cacheByIndex.find(propName);
|
||||
if (nameIt != cacheByIndex.end()) {
|
||||
return nameIt->second;
|
||||
}
|
||||
|
||||
string name(str(boost::format("lights[%d].%s") % index % propName));
|
||||
auto pair = cacheByIndex.insert(make_pair(propName, name));
|
||||
|
||||
return pair.first->second;
|
||||
}
|
||||
|
||||
void MeshSceneNode::render() const {
|
||||
shared_ptr<ModelMesh> mesh(_modelNode->mesh());
|
||||
shared_ptr<ModelNode::Skin> skin(_modelNode->skin());
|
||||
const ModelSceneNode::AnimationState &animState = _model->animationState();
|
||||
bool skeletal = skin && !animState.name.empty();
|
||||
|
||||
ShaderManager &shaders = Shaders;
|
||||
shaders.activate(ShaderProgram::ModelModel);
|
||||
shaders.setUniform("model", _absoluteTransform);
|
||||
shaders.setUniform("alpha", _model->alpha() * _modelNode->alpha());
|
||||
LocalUniforms locals;
|
||||
locals.model = _absoluteTransform;
|
||||
locals.alpha = _model->alpha() * _modelNode->alpha();
|
||||
|
||||
if (mesh->hasEnvmapTexture()) {
|
||||
shaders.setUniform("envmapEnabled", true);
|
||||
shaders.setUniform("envmap", 1);
|
||||
locals.features.envmapEnabled = true;
|
||||
locals.textures.envmap = 1;
|
||||
}
|
||||
if (mesh->hasLightmapTexture()) {
|
||||
shaders.setUniform("lightmapEnabled", true);
|
||||
shaders.setUniform("lightmap", 2);
|
||||
locals.features.lightmapEnabled = true;
|
||||
locals.textures.lightmap = 2;
|
||||
}
|
||||
if (mesh->hasBumpyShinyTexture()) {
|
||||
shaders.setUniform("bumpyShinyEnabled", true);
|
||||
shaders.setUniform("bumpyShiny", 3);
|
||||
locals.features.bumpyShinyEnabled = true;
|
||||
locals.textures.bumpyShiny = 3;
|
||||
}
|
||||
if (mesh->hasBumpmapTexture()) {
|
||||
shaders.setUniform("bumpmapEnabled", true);
|
||||
shaders.setUniform("bumpmap", 4);
|
||||
locals.features.bumpmapEnabled = true;
|
||||
locals.textures.bumpmap = 4;
|
||||
}
|
||||
|
||||
if (skeletal) {
|
||||
shaders.setUniform("skeletalEnabled", true);
|
||||
shaders.setUniform("absTransform", _modelNode->absoluteTransform());
|
||||
shaders.setUniform("absTransformInv", _modelNode->absoluteTransformInverse());
|
||||
locals.features.skeletalEnabled = true;
|
||||
locals.skeletal.absTransform = _modelNode->absoluteTransform();
|
||||
locals.skeletal.absTransformInv = _modelNode->absoluteTransformInverse();
|
||||
|
||||
const unordered_map<uint16_t, uint16_t> &nodeIdxByBoneIdx = skin->nodeIdxByBoneIdx;
|
||||
vector<glm::mat4> bones(nodeIdxByBoneIdx.size(), glm::mat4(1.0f));
|
||||
|
@ -116,58 +99,34 @@ void MeshSceneNode::render() const {
|
|||
bones[boneIdx] = bone->second;
|
||||
}
|
||||
|
||||
shaders.setUniform("bones", bones);
|
||||
locals.skeletal.bones = move(bones);
|
||||
}
|
||||
|
||||
if (_modelNode->isSelfIllumEnabled()) {
|
||||
shaders.setUniform("selfIllumEnabled", true);
|
||||
shaders.setUniform("selfIllumColor", _modelNode->selfIllumColor());
|
||||
locals.features.selfIllumEnabled = true;
|
||||
locals.selfIllumColor = _modelNode->selfIllumColor();
|
||||
}
|
||||
|
||||
int lightCount = 0;
|
||||
|
||||
if (_model->isLightingEnabled()) {
|
||||
const vector<LightSceneNode *> &lights = _model->lightsAffectedBy();
|
||||
lightCount = static_cast<int>(lights.size());
|
||||
|
||||
shaders.setUniform("lightingEnabled", true);
|
||||
shaders.setUniform("lightCount", lightCount);
|
||||
shaders.setUniform("ambientLightColor", _sceneGraph->ambientLightColor());
|
||||
locals.features.lightingEnabled = true;
|
||||
locals.lighting.ambientColor = _sceneGraph->ambientLightColor();
|
||||
locals.lighting.lights.clear();
|
||||
|
||||
for (int i = 0; i < lightCount; ++i) {
|
||||
LightSceneNode *light = lights[i];
|
||||
shaders.setUniform(getLightUniformName(i, "ambientOnly"), light->modelNode().light()->ambientOnly);
|
||||
shaders.setUniform(getLightUniformName(i, "position"), glm::vec3(light->absoluteTransform()[3]));
|
||||
shaders.setUniform(getLightUniformName(i, "radius"), light->modelNode().radius());
|
||||
shaders.setUniform(getLightUniformName(i, "color"), light->modelNode().color());
|
||||
shaders.setUniform(getLightUniformName(i, "multiplier"), light->modelNode().multiplier());
|
||||
for (auto &light : lights) {
|
||||
ShaderLight shaderLight;
|
||||
shaderLight.position = light->absoluteTransform()[3];
|
||||
shaderLight.radius = light->modelNode().radius();
|
||||
shaderLight.color = light->modelNode().color();
|
||||
|
||||
locals.lighting.lights.push_back(move(shaderLight));
|
||||
}
|
||||
}
|
||||
Shaders.activate(ShaderProgram::ModelModel, locals);
|
||||
|
||||
mesh->render(_model->textureOverride());
|
||||
|
||||
if (skeletal) {
|
||||
shaders.setUniform("skeletalEnabled", false);
|
||||
}
|
||||
if (_model->isLightingEnabled()) {
|
||||
shaders.setUniform("lightingEnabled", false);
|
||||
}
|
||||
if (_modelNode->isSelfIllumEnabled()) {
|
||||
shaders.setUniform("selfIllumEnabled", false);
|
||||
}
|
||||
if (mesh->hasEnvmapTexture()) {
|
||||
shaders.setUniform("envmapEnabled", false);
|
||||
}
|
||||
if (mesh->hasLightmapTexture()) {
|
||||
shaders.setUniform("lightmapEnabled", false);
|
||||
}
|
||||
if (mesh->hasBumpyShinyTexture()) {
|
||||
shaders.setUniform("bumpyShinyEnabled", false);
|
||||
}
|
||||
if (mesh->hasBumpmapTexture()) {
|
||||
shaders.setUniform("bumpmapEnabled", false);
|
||||
}
|
||||
|
||||
SceneNode::render();
|
||||
}
|
||||
|
||||
|
|
|
@ -86,12 +86,12 @@ void SceneGraph::render() const {
|
|||
|
||||
glEnable(GL_DEPTH_TEST);
|
||||
|
||||
ShaderUniforms uniforms;
|
||||
uniforms.projection = _activeCamera->projection();
|
||||
uniforms.view = _activeCamera->view();
|
||||
uniforms.cameraPosition = _activeCamera->absoluteTransform()[3];
|
||||
GlobalUniforms globals;
|
||||
globals.projection = _activeCamera->projection();
|
||||
globals.view = _activeCamera->view();
|
||||
globals.cameraPosition = _activeCamera->absoluteTransform()[3];
|
||||
|
||||
Shaders.setGlobalUniforms(uniforms);
|
||||
Shaders.setGlobalUniforms(globals);
|
||||
|
||||
for (auto &node : _rootNodes) {
|
||||
node->render();
|
||||
|
|
|
@ -36,18 +36,18 @@ namespace render {
|
|||
static const GLchar kGUIVertexShader[] = R"END(
|
||||
#version 330
|
||||
|
||||
uniform mat4 projection;
|
||||
uniform mat4 view;
|
||||
uniform mat4 model;
|
||||
uniform mat4 uProjection;
|
||||
uniform mat4 uView;
|
||||
uniform mat4 uModel;
|
||||
|
||||
layout(location = 0) in vec3 position;
|
||||
layout(location = 2) in vec2 texCoords;
|
||||
layout(location = 0) in vec3 aPosition;
|
||||
layout(location = 2) in vec2 aTexCoords;
|
||||
|
||||
out vec2 fragTexCoords;
|
||||
|
||||
void main() {
|
||||
gl_Position = projection * view * model * vec4(position, 1.0);
|
||||
fragTexCoords = texCoords;
|
||||
gl_Position = uProjection * uView * uModel * vec4(aPosition, 1.0);
|
||||
fragTexCoords = aTexCoords;
|
||||
}
|
||||
)END";
|
||||
|
||||
|
@ -56,21 +56,21 @@ static const GLchar kModelVertexShader[] = R"END(
|
|||
|
||||
const int MAX_BONES = 128;
|
||||
|
||||
uniform mat4 projection;
|
||||
uniform mat4 view;
|
||||
uniform mat4 model;
|
||||
uniform mat4 uProjection;
|
||||
uniform mat4 uView;
|
||||
uniform mat4 uModel;
|
||||
|
||||
uniform bool skeletalEnabled;
|
||||
uniform mat4 absTransform;
|
||||
uniform mat4 absTransformInv;
|
||||
uniform mat4 bones[MAX_BONES];
|
||||
uniform bool uSkeletalEnabled;
|
||||
uniform mat4 uAbsTransform;
|
||||
uniform mat4 uAbsTransformInv;
|
||||
uniform mat4 uBones[MAX_BONES];
|
||||
|
||||
layout(location = 0) in vec3 position;
|
||||
layout(location = 1) in vec3 normal;
|
||||
layout(location = 2) in vec2 texCoords;
|
||||
layout(location = 3) in vec2 lightmapCoords;
|
||||
layout(location = 4) in vec4 boneWeights;
|
||||
layout(location = 5) in vec4 boneIndices;
|
||||
layout(location = 0) in vec3 aPosition;
|
||||
layout(location = 1) in vec3 aNormal;
|
||||
layout(location = 2) in vec2 aTexCoords;
|
||||
layout(location = 3) in vec2 aLightmapCoords;
|
||||
layout(location = 4) in vec4 aBoneWeights;
|
||||
layout(location = 5) in vec4 aBoneIndices;
|
||||
|
||||
out vec3 fragPosition;
|
||||
out vec3 fragNormal;
|
||||
|
@ -80,64 +80,63 @@ out vec2 fragLightmapCoords;
|
|||
void main() {
|
||||
vec3 newPosition = vec3(0.0);
|
||||
|
||||
if (skeletalEnabled) {
|
||||
float weight0 = boneWeights.x;
|
||||
float weight1 = boneWeights.y;
|
||||
float weight2 = boneWeights.z;
|
||||
float weight3 = boneWeights.w;
|
||||
if (uSkeletalEnabled) {
|
||||
float weight0 = aBoneWeights.x;
|
||||
float weight1 = aBoneWeights.y;
|
||||
float weight2 = aBoneWeights.z;
|
||||
float weight3 = aBoneWeights.w;
|
||||
|
||||
int index0 = int(boneIndices.x);
|
||||
int index1 = int(boneIndices.y);
|
||||
int index2 = int(boneIndices.z);
|
||||
int index3 = int(boneIndices.w);
|
||||
int index0 = int(aBoneIndices.x);
|
||||
int index1 = int(aBoneIndices.y);
|
||||
int index2 = int(aBoneIndices.z);
|
||||
int index3 = int(aBoneIndices.w);
|
||||
|
||||
vec4 position4 = vec4(position, 1.0);
|
||||
vec4 position4 = vec4(aPosition, 1.0);
|
||||
|
||||
newPosition += weight0 * (absTransformInv * bones[index0] * absTransform * position4).xyz;
|
||||
newPosition += weight1 * (absTransformInv * bones[index1] * absTransform * position4).xyz;
|
||||
newPosition += weight2 * (absTransformInv * bones[index2] * absTransform * position4).xyz;
|
||||
newPosition += weight3 * (absTransformInv * bones[index3] * absTransform * position4).xyz;
|
||||
newPosition += weight0 * (uAbsTransformInv * uBones[index0] * uAbsTransform * position4).xyz;
|
||||
newPosition += weight1 * (uAbsTransformInv * uBones[index1] * uAbsTransform * position4).xyz;
|
||||
newPosition += weight2 * (uAbsTransformInv * uBones[index2] * uAbsTransform * position4).xyz;
|
||||
newPosition += weight3 * (uAbsTransformInv * uBones[index3] * uAbsTransform * position4).xyz;
|
||||
|
||||
} else {
|
||||
newPosition = position;
|
||||
newPosition = aPosition;
|
||||
}
|
||||
|
||||
vec4 newPosition4 = vec4(newPosition, 1.0);
|
||||
|
||||
gl_Position = projection * view * model * newPosition4;
|
||||
fragPosition = vec3(model * newPosition4);
|
||||
fragNormal = mat3(transpose(inverse(model))) * normal;
|
||||
fragTexCoords = texCoords;
|
||||
fragLightmapCoords = lightmapCoords;
|
||||
gl_Position = uProjection * uView * uModel * newPosition4;
|
||||
fragPosition = vec3(uModel * newPosition4);
|
||||
fragNormal = mat3(transpose(inverse(uModel))) * aNormal;
|
||||
fragTexCoords = aTexCoords;
|
||||
fragLightmapCoords = aLightmapCoords;
|
||||
}
|
||||
)END";
|
||||
|
||||
static const GLchar kWhiteFragmentShader[] = R"END(
|
||||
#version 330
|
||||
|
||||
uniform float alpha;
|
||||
uniform float uAlpha;
|
||||
|
||||
out vec4 fragColor;
|
||||
|
||||
void main() {
|
||||
fragColor = vec4(1.0, 1.0, 1.0, alpha);
|
||||
fragColor = vec4(1.0, 1.0, 1.0, uAlpha);
|
||||
}
|
||||
)END";
|
||||
|
||||
static const GLchar kGUIFragmentShader[] = R"END(
|
||||
#version 330
|
||||
|
||||
uniform sampler2D image;
|
||||
uniform vec3 color;
|
||||
uniform float alpha;
|
||||
uniform sampler2D uTexture;
|
||||
uniform vec3 uColor;
|
||||
uniform float uAlpha;
|
||||
|
||||
in vec2 fragTexCoords;
|
||||
|
||||
out vec4 fragColor;
|
||||
|
||||
void main() {
|
||||
vec4 imageSample = texture(image, fragTexCoords);
|
||||
fragColor = vec4(color * imageSample.rgb, alpha * imageSample.a);
|
||||
vec4 textureSample = texture(uTexture, fragTexCoords);
|
||||
fragColor = vec4(uColor * textureSample.rgb, uAlpha * textureSample.a);
|
||||
}
|
||||
)END";
|
||||
|
||||
|
@ -147,32 +146,33 @@ static const GLchar kModelFragmentShader[] = R"END(
|
|||
const int MAX_LIGHTS = 8;
|
||||
const vec3 RGB_TO_LUMINOSITY = vec3(0.2126, 0.7152, 0.0722);
|
||||
|
||||
uniform struct Light {
|
||||
struct Light {
|
||||
vec3 position;
|
||||
float radius;
|
||||
vec3 color;
|
||||
float multiplier;
|
||||
} lights[MAX_LIGHTS];
|
||||
float radius;
|
||||
};
|
||||
|
||||
uniform bool lightmapEnabled;
|
||||
uniform bool envmapEnabled;
|
||||
uniform bool bumpyShinyEnabled;
|
||||
uniform bool bumpmapEnabled;
|
||||
uniform bool lightingEnabled;
|
||||
uniform bool selfIllumEnabled;
|
||||
uniform bool uLightmapEnabled;
|
||||
uniform bool uEnvmapEnabled;
|
||||
uniform bool uBumpyShinyEnabled;
|
||||
uniform bool uBumpmapEnabled;
|
||||
uniform bool uSkeletalEnabled;
|
||||
uniform bool uLightingEnabled;
|
||||
uniform bool uSelfIllumEnabled;
|
||||
|
||||
uniform sampler2D diffuse;
|
||||
uniform sampler2D lightmap;
|
||||
uniform sampler2D bumpmap;
|
||||
uniform samplerCube envmap;
|
||||
uniform samplerCube bumpyShiny;
|
||||
uniform sampler2D uDiffuse;
|
||||
uniform sampler2D uLightmap;
|
||||
uniform sampler2D uBumpmap;
|
||||
uniform samplerCube uEnvmap;
|
||||
uniform samplerCube uBumpyShiny;
|
||||
|
||||
uniform vec3 cameraPosition;
|
||||
uniform float alpha;
|
||||
uniform vec3 uCameraPosition;
|
||||
uniform float uAlpha;
|
||||
|
||||
uniform int lightCount;
|
||||
uniform vec3 ambientLightColor;
|
||||
uniform vec3 selfIllumColor;
|
||||
uniform int uLightCount;
|
||||
uniform vec3 uAmbientLightColor;
|
||||
uniform vec3 uSelfIllumColor;
|
||||
uniform Light uLights[MAX_LIGHTS];
|
||||
|
||||
in vec3 fragPosition;
|
||||
in vec3 fragNormal;
|
||||
|
@ -182,12 +182,12 @@ in vec2 fragLightmapCoords;
|
|||
out vec4 fragColor;
|
||||
|
||||
void applyLightmap(inout vec3 color) {
|
||||
vec4 lightmapSample = texture(lightmap, fragLightmapCoords);
|
||||
vec4 lightmapSample = texture(uLightmap, fragLightmapCoords);
|
||||
color *= lightmapSample.rgb;
|
||||
}
|
||||
|
||||
void applyEnvmap(samplerCube image, vec3 normal, float a, inout vec3 color) {
|
||||
vec3 I = normalize(fragPosition - cameraPosition);
|
||||
vec3 I = normalize(fragPosition - uCameraPosition);
|
||||
vec3 R = reflect(I, normal);
|
||||
vec4 sample = texture(image, R);
|
||||
|
||||
|
@ -195,15 +195,15 @@ void applyEnvmap(samplerCube image, vec3 normal, float a, inout vec3 color) {
|
|||
}
|
||||
|
||||
void applyLighting(vec3 normal, inout vec3 color) {
|
||||
color += ambientLightColor;
|
||||
color += uAmbientLightColor;
|
||||
|
||||
if (lightCount == 0) return;
|
||||
if (uLightCount == 0) return;
|
||||
|
||||
for (int i = 0; i < lightCount; ++i) {
|
||||
vec3 surfaceToLight = lights[i].position - fragPosition;
|
||||
for (int i = 0; i < uLightCount; ++i) {
|
||||
vec3 surfaceToLight = uLights[i].position - fragPosition;
|
||||
vec3 lightDir = normalize(surfaceToLight);
|
||||
|
||||
vec3 surfaceToCamera = normalize(cameraPosition - fragPosition);
|
||||
vec3 surfaceToCamera = normalize(uCameraPosition - fragPosition);
|
||||
float diffuseCoeff = max(dot(normal, lightDir), 0.0);
|
||||
float specularCoeff = 0.0;
|
||||
|
||||
|
@ -212,46 +212,46 @@ void applyLighting(vec3 normal, inout vec3 color) {
|
|||
}
|
||||
float distToLight = length(surfaceToLight);
|
||||
|
||||
float attenuation = clamp(1.0 - distToLight / lights[i].radius, 0.0, 1.0);
|
||||
float attenuation = clamp(1.0 - distToLight / uLights[i].radius, 0.0, 1.0);
|
||||
attenuation *= attenuation;
|
||||
|
||||
color += attenuation * (diffuseCoeff + specularCoeff) * lights[i].color;
|
||||
color += attenuation * (diffuseCoeff + specularCoeff) * uLights[i].color;
|
||||
}
|
||||
}
|
||||
|
||||
void applySelfIllum(inout vec3 color) {
|
||||
vec4 diffuseSample = texture(diffuse, fragTexCoords);
|
||||
vec4 diffuseSample = texture(uDiffuse, fragTexCoords);
|
||||
float luminosity = dot(diffuseSample.rgb, RGB_TO_LUMINOSITY);
|
||||
|
||||
color += 0.5 * smoothstep(0.5, 1.0, luminosity) * selfIllumColor;
|
||||
color += 0.5 * smoothstep(0.5, 1.0, luminosity) * uSelfIllumColor;
|
||||
}
|
||||
|
||||
void main() {
|
||||
vec4 diffuseSample = texture(diffuse, fragTexCoords);
|
||||
vec4 diffuseSample = texture(uDiffuse, fragTexCoords);
|
||||
vec3 surfaceColor = diffuseSample.rgb;
|
||||
vec3 lightColor = vec3(0.0);
|
||||
vec3 normal = normalize(fragNormal);
|
||||
|
||||
if (lightmapEnabled) {
|
||||
if (uLightmapEnabled) {
|
||||
applyLightmap(surfaceColor);
|
||||
}
|
||||
if (envmapEnabled) {
|
||||
applyEnvmap(envmap, normal, 1.0 - diffuseSample.a, surfaceColor);
|
||||
} else if (bumpyShinyEnabled) {
|
||||
applyEnvmap(bumpyShiny, normal, 1.0 - diffuseSample.a, surfaceColor);
|
||||
if (uEnvmapEnabled) {
|
||||
applyEnvmap(uEnvmap, normal, 1.0 - diffuseSample.a, surfaceColor);
|
||||
} else if (uBumpyShinyEnabled) {
|
||||
applyEnvmap(uBumpyShiny, normal, 1.0 - diffuseSample.a, surfaceColor);
|
||||
}
|
||||
if (lightingEnabled) {
|
||||
if (uLightingEnabled) {
|
||||
applyLighting(normal, lightColor);
|
||||
lightColor = min(lightColor, 1.0);
|
||||
} else {
|
||||
lightColor = vec3(1.0);
|
||||
}
|
||||
if (selfIllumEnabled) {
|
||||
if (uSelfIllumEnabled) {
|
||||
applySelfIllum(lightColor);
|
||||
}
|
||||
float finalAlpha = alpha;
|
||||
float finalAlpha = uAlpha;
|
||||
|
||||
if (!envmapEnabled && !bumpyShinyEnabled) {
|
||||
if (!uEnvmapEnabled && !uBumpyShinyEnabled) {
|
||||
finalAlpha *= diffuseSample.a;
|
||||
}
|
||||
fragColor = vec4(lightColor * surfaceColor, finalAlpha);
|
||||
|
@ -261,20 +261,20 @@ void main() {
|
|||
static const GLchar kGaussianBlurFragmentShader[] = R"END(
|
||||
#version 330
|
||||
|
||||
uniform sampler2D image;
|
||||
uniform vec2 resolution;
|
||||
uniform vec2 direction;
|
||||
uniform sampler2D uTexture;
|
||||
uniform vec2 uResolution;
|
||||
uniform vec2 uDirection;
|
||||
|
||||
out vec4 fragColor;
|
||||
|
||||
void main() {
|
||||
vec2 uv = vec2(gl_FragCoord.xy / resolution);
|
||||
vec2 off1 = vec2(1.3333333333333333) * direction;
|
||||
vec2 uv = vec2(gl_FragCoord.xy / uResolution);
|
||||
vec2 off1 = vec2(1.3333333333333333) * uDirection;
|
||||
|
||||
vec4 color = vec4(0.0);
|
||||
color += texture2D(image, uv) * 0.29411764705882354;
|
||||
color += texture2D(image, uv + (off1 / resolution)) * 0.35294117647058826;
|
||||
color += texture2D(image, uv - (off1 / resolution)) * 0.35294117647058826;
|
||||
color += texture2D(uTexture, uv) * 0.29411764705882354;
|
||||
color += texture2D(uTexture, uv + (off1 / uResolution)) * 0.35294117647058826;
|
||||
color += texture2D(uTexture, uv - (off1 / uResolution)) * 0.35294117647058826;
|
||||
|
||||
fragColor = color;
|
||||
}
|
||||
|
@ -354,13 +354,15 @@ void ShaderManager::deinitGL() {
|
|||
_shaders.clear();
|
||||
}
|
||||
|
||||
void ShaderManager::activate(ShaderProgram program) {
|
||||
if (_activeProgram == program) return;
|
||||
void ShaderManager::activate(ShaderProgram program, const LocalUniforms &locals) {
|
||||
if (_activeProgram != program) {
|
||||
unsigned int ordinal = getOrdinal(program);
|
||||
glUseProgram(ordinal);
|
||||
|
||||
unsigned int ordinal = getOrdinal(program);
|
||||
glUseProgram(ordinal);
|
||||
_activeProgram = program;
|
||||
_activeOrdinal = ordinal;
|
||||
_activeProgram = program;
|
||||
_activeOrdinal = ordinal;
|
||||
}
|
||||
setLocalUniforms(locals);
|
||||
}
|
||||
|
||||
unsigned int ShaderManager::getOrdinal(ShaderProgram program) const {
|
||||
|
@ -371,6 +373,109 @@ unsigned int ShaderManager::getOrdinal(ShaderProgram program) const {
|
|||
return it->second;
|
||||
}
|
||||
|
||||
static const string &getLightUniformName(int index, const char *propName) {
|
||||
static unordered_map<int, unordered_map<const char *, string>> cache;
|
||||
auto &cacheByIndex = cache[index];
|
||||
auto maybeName = cacheByIndex.find(propName);
|
||||
|
||||
if (maybeName != cacheByIndex.end()) {
|
||||
return maybeName->second;
|
||||
}
|
||||
string name(str(boost::format("uLights[%d].%s") % index % propName));
|
||||
auto pair = cacheByIndex.insert(make_pair(propName, name));
|
||||
|
||||
return pair.first->second;
|
||||
}
|
||||
|
||||
void ShaderManager::setLocalUniforms(const LocalUniforms &locals) {
|
||||
setUniform("uModel", locals.model);
|
||||
setUniform("uColor", locals.color);
|
||||
setUniform("uAlpha", locals.alpha);
|
||||
setUniform("uLightmapEnabled", locals.features.lightmapEnabled);
|
||||
setUniform("uEnvmapEnabled", locals.features.envmapEnabled);
|
||||
setUniform("uLightmapEnabled", locals.features.lightmapEnabled);
|
||||
setUniform("uBumpyShinyEnabled", locals.features.bumpyShinyEnabled);
|
||||
setUniform("uBumpmapEnabled", locals.features.bumpmapEnabled);
|
||||
setUniform("uSkeletalEnabled", locals.features.skeletalEnabled);
|
||||
setUniform("uLightingEnabled", locals.features.lightingEnabled);
|
||||
setUniform("uSelfIllumEnabled", locals.features.selfIllumEnabled);
|
||||
|
||||
if (locals.features.lightmapEnabled) {
|
||||
setUniform("uLightmap", locals.textures.lightmap);
|
||||
}
|
||||
if (locals.features.envmapEnabled) {
|
||||
setUniform("uEnvmap", locals.textures.envmap);
|
||||
}
|
||||
if (locals.features.bumpyShinyEnabled) {
|
||||
setUniform("uBumpyShiny", locals.textures.bumpyShiny);
|
||||
}
|
||||
if (locals.features.bumpmapEnabled) {
|
||||
setUniform("uBumpmap", locals.textures.bumpmap);
|
||||
}
|
||||
if (locals.features.skeletalEnabled) {
|
||||
setUniform("uAbsTransform", locals.skeletal.absTransform);
|
||||
setUniform("uAbsTransformInv", locals.skeletal.absTransformInv);
|
||||
setUniform("uBones", locals.skeletal.bones);
|
||||
}
|
||||
if (locals.features.lightingEnabled) {
|
||||
int lightCount = static_cast<int>(locals.lighting.lights.size());
|
||||
setUniform("uLightCount", lightCount);
|
||||
setUniform("uAmbientLightColor", locals.lighting.ambientColor);
|
||||
|
||||
for (int i = 0; i < lightCount; ++i) {
|
||||
const ShaderLight &light = locals.lighting.lights[i];
|
||||
setUniform(getLightUniformName(i, "position"), light.position);
|
||||
setUniform(getLightUniformName(i, "color"), light.color);
|
||||
setUniform(getLightUniformName(i, "radius"), light.radius);
|
||||
}
|
||||
}
|
||||
if (locals.features.selfIllumEnabled) {
|
||||
setUniform("uSelfIllumColor", locals.selfIllumColor);
|
||||
}
|
||||
}
|
||||
|
||||
void ShaderManager::setUniform(const string &name, const glm::mat4 &m) {
|
||||
GLint loc = glGetUniformLocation(_activeOrdinal, name.c_str());
|
||||
if (loc == -1) return;
|
||||
|
||||
glUniformMatrix4fv(loc, 1, GL_FALSE, glm::value_ptr(m));
|
||||
}
|
||||
|
||||
void ShaderManager::setUniform(const string &name, int value) {
|
||||
GLint loc = glGetUniformLocation(_activeOrdinal, name.c_str());
|
||||
if (loc == -1) return;
|
||||
|
||||
glUniform1i(loc, value);
|
||||
}
|
||||
|
||||
void ShaderManager::setUniform(const string &name, float value) {
|
||||
GLint loc = glGetUniformLocation(_activeOrdinal, name.c_str());
|
||||
if (loc == -1) return;
|
||||
|
||||
glUniform1f(loc, value);
|
||||
}
|
||||
|
||||
void ShaderManager::setUniform(const string &name, const glm::vec2 &v) {
|
||||
GLint loc = glGetUniformLocation(_activeOrdinal, name.c_str());
|
||||
if (loc == -1) return;
|
||||
|
||||
glUniform2f(loc, v.x, v.y);
|
||||
}
|
||||
|
||||
void ShaderManager::setUniform(const string &name, const glm::vec3 &v) {
|
||||
GLint loc = glGetUniformLocation(_activeOrdinal, name.c_str());
|
||||
if (loc == -1) return;
|
||||
|
||||
glUniform3f(loc, v.x, v.y, v.z);
|
||||
}
|
||||
|
||||
void ShaderManager::setUniform(const string &name, const vector<glm::mat4> &arr) {
|
||||
GLint loc = glGetUniformLocation(_activeOrdinal, name.c_str());
|
||||
if (loc == -1) return;
|
||||
|
||||
glUniformMatrix4fv(loc, static_cast<GLsizei>(arr.size()), GL_FALSE, reinterpret_cast<const GLfloat *>(&arr[0]));
|
||||
}
|
||||
|
||||
void ShaderManager::deactivate() {
|
||||
if (_activeProgram == ShaderProgram::None) return;
|
||||
|
||||
|
@ -379,82 +484,19 @@ void ShaderManager::deactivate() {
|
|||
_activeOrdinal = 0;
|
||||
}
|
||||
|
||||
void ShaderManager::setGlobalUniforms(const ShaderUniforms &uniforms) {
|
||||
for (auto &pair : _programs) {
|
||||
activate(pair.first);
|
||||
void ShaderManager::setGlobalUniforms(const GlobalUniforms &globals) {
|
||||
uint32_t ordinal = _activeOrdinal;
|
||||
|
||||
setUniform(_activeOrdinal, "projection", uniforms.projection);
|
||||
setUniform(_activeOrdinal, "view", uniforms.view);
|
||||
setUniform(_activeOrdinal, "cameraPosition", uniforms.cameraPosition);
|
||||
for (auto &program : _programs) {
|
||||
glUseProgram(program.second);
|
||||
_activeOrdinal = program.second;
|
||||
|
||||
setUniform("uProjection", globals.projection);
|
||||
setUniform("uView", globals.view);
|
||||
setUniform("uCameraPosition", globals.cameraPosition);
|
||||
}
|
||||
|
||||
deactivate();
|
||||
}
|
||||
|
||||
void ShaderManager::setUniform(unsigned int ordinal, const string &name, const glm::mat4 &m) {
|
||||
GLint loc = glGetUniformLocation(ordinal, name.c_str());
|
||||
if (loc == -1) return;
|
||||
|
||||
glUniformMatrix4fv(loc, 1, GL_FALSE, glm::value_ptr(m));
|
||||
}
|
||||
|
||||
void ShaderManager::setUniform(const string &name, int value) {
|
||||
setUniform(_activeOrdinal, name, value);
|
||||
}
|
||||
|
||||
void ShaderManager::setUniform(unsigned int ordinal, const string &name, int value) {
|
||||
GLint loc = glGetUniformLocation(ordinal, name.c_str());
|
||||
if (loc == -1) return;
|
||||
|
||||
glUniform1i(loc, value);
|
||||
}
|
||||
|
||||
void ShaderManager::setUniform(const string &name, float value) {
|
||||
setUniform(_activeOrdinal, name, value);
|
||||
}
|
||||
|
||||
void ShaderManager::setUniform(unsigned int ordinal, const string &name, float value) {
|
||||
GLint loc = glGetUniformLocation(ordinal, name.c_str());
|
||||
if (loc == -1) return;
|
||||
|
||||
glUniform1f(loc, value);
|
||||
}
|
||||
|
||||
void ShaderManager::setUniform(const string &name, const glm::vec2 &v) {
|
||||
setUniform(_activeOrdinal, name, v);
|
||||
}
|
||||
|
||||
void ShaderManager::setUniform(unsigned int ordinal, const string &name, const glm::vec2 &v) {
|
||||
GLint loc = glGetUniformLocation(ordinal, name.c_str());
|
||||
if (loc == -1) return;
|
||||
|
||||
glUniform2f(loc, v.x, v.y);
|
||||
}
|
||||
|
||||
void ShaderManager::setUniform(const string &name, const glm::vec3 &v) {
|
||||
setUniform(_activeOrdinal, name, v);
|
||||
}
|
||||
|
||||
void ShaderManager::setUniform(unsigned int ordinal, const string &name, const glm::vec3 &v) {
|
||||
GLint loc = glGetUniformLocation(ordinal, name.c_str());
|
||||
if (loc == -1) return;
|
||||
|
||||
glUniform3f(loc, v.x, v.y, v.z);
|
||||
}
|
||||
|
||||
void ShaderManager::setUniform(const string &name, const glm::mat4 &m) {
|
||||
setUniform(_activeOrdinal, name, m);
|
||||
}
|
||||
|
||||
void ShaderManager::setUniform(const string &name, const vector<glm::mat4> &arr) {
|
||||
setUniform(_activeOrdinal, name, arr);
|
||||
}
|
||||
|
||||
void ShaderManager::setUniform(unsigned int ordinal, const string &name, const vector<glm::mat4> &arr) {
|
||||
GLint loc = glGetUniformLocation(ordinal, name.c_str());
|
||||
if (loc == -1) return;
|
||||
|
||||
glUniformMatrix4fv(loc, static_cast<GLsizei>(arr.size()), GL_FALSE, reinterpret_cast<const GLfloat *>(&arr[0]));
|
||||
glUseProgram(ordinal);
|
||||
_activeOrdinal = ordinal;
|
||||
}
|
||||
|
||||
} // namespace render
|
||||
|
|
|
@ -17,6 +17,7 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
#include <cstdint>
|
||||
#include <string>
|
||||
#include <unordered_map>
|
||||
#include <vector>
|
||||
|
@ -34,27 +35,68 @@ enum class ShaderProgram {
|
|||
ModelModel
|
||||
};
|
||||
|
||||
struct ShaderUniforms {
|
||||
struct GlobalUniforms {
|
||||
glm::mat4 projection { 1.0f };
|
||||
glm::mat4 view { 1.0f };
|
||||
glm::vec3 cameraPosition { 0.0f };
|
||||
};
|
||||
|
||||
struct FeatureUniforms {
|
||||
bool lightmapEnabled { false };
|
||||
bool envmapEnabled { false };
|
||||
bool bumpyShinyEnabled { false };
|
||||
bool bumpmapEnabled { false };
|
||||
bool skeletalEnabled { false };
|
||||
bool lightingEnabled { false };
|
||||
bool selfIllumEnabled { false };
|
||||
};
|
||||
|
||||
struct TextureUniforms {
|
||||
int lightmap { 0 };
|
||||
int envmap { 0 };
|
||||
int bumpyShiny { 0 };
|
||||
int bumpmap { 0 };
|
||||
};
|
||||
|
||||
struct SkeletalUniforms {
|
||||
glm::mat4 absTransform { 1.0f };
|
||||
glm::mat4 absTransformInv { 1.0f };
|
||||
std::vector<glm::mat4> bones;
|
||||
};
|
||||
|
||||
struct ShaderLight {
|
||||
glm::vec3 position { 0.0f };
|
||||
glm::vec3 color { 1.0f };
|
||||
float radius { 1.0f };
|
||||
};
|
||||
|
||||
struct LightingUniforms {
|
||||
glm::vec3 ambientColor { 1.0f };
|
||||
std::vector<ShaderLight> lights;
|
||||
};
|
||||
|
||||
struct LocalUniforms {
|
||||
FeatureUniforms features;
|
||||
TextureUniforms textures;
|
||||
SkeletalUniforms skeletal;
|
||||
LightingUniforms lighting;
|
||||
|
||||
glm::mat4 model { 1.0f };
|
||||
glm::vec3 color { 1.0f };
|
||||
float alpha { 1.0f };
|
||||
glm::vec3 selfIllumColor { 1.0f };
|
||||
};
|
||||
|
||||
class ShaderManager {
|
||||
public:
|
||||
static ShaderManager &instance();
|
||||
|
||||
void initGL();
|
||||
void deinitGL();
|
||||
void activate(ShaderProgram program);
|
||||
void activate(ShaderProgram program, const LocalUniforms &uniforms);
|
||||
void deactivate();
|
||||
void setGlobalUniforms(const ShaderUniforms &uniforms);
|
||||
void setUniform(const std::string &name, int value);
|
||||
void setUniform(const std::string &name, float value);
|
||||
void setUniform(const std::string &name, const glm::vec2 &v);
|
||||
void setUniform(const std::string &name, const glm::vec3 &v);
|
||||
void setUniform(const std::string &name, const glm::mat4 &m);
|
||||
void setUniform(const std::string &name, const std::vector<glm::mat4> &arr);
|
||||
|
||||
void setGlobalUniforms(const GlobalUniforms &globals);
|
||||
|
||||
private:
|
||||
enum class ShaderName {
|
||||
|
@ -66,10 +108,10 @@ private:
|
|||
FragmentGaussianBlur
|
||||
};
|
||||
|
||||
std::unordered_map<ShaderName, unsigned int> _shaders;
|
||||
std::unordered_map<ShaderProgram, unsigned int> _programs;
|
||||
std::unordered_map<ShaderName, uint32_t> _shaders;
|
||||
std::unordered_map<ShaderProgram, uint32_t> _programs;
|
||||
ShaderProgram _activeProgram { ShaderProgram::None };
|
||||
unsigned int _activeOrdinal { 0 };
|
||||
uint32_t _activeOrdinal { 0 };
|
||||
|
||||
ShaderManager() = default;
|
||||
ShaderManager(const ShaderManager &) = delete;
|
||||
|
@ -80,12 +122,13 @@ private:
|
|||
void initShader(ShaderName name, unsigned int type, const char *source);
|
||||
void initProgram(ShaderProgram program, ShaderName vertexShader, ShaderName fragmentShader);
|
||||
unsigned int getOrdinal(ShaderProgram program) const;
|
||||
void setUniform(unsigned int ordinal, const std::string &name, int value);
|
||||
void setUniform(unsigned int ordinal, const std::string &name, float value);
|
||||
void setUniform(unsigned int ordinal, const std::string &name, const glm::vec2 &v);
|
||||
void setUniform(unsigned int ordinal, const std::string &name, const glm::vec3 &v);
|
||||
void setUniform(unsigned int ordinal, const std::string &name, const glm::mat4 &m);
|
||||
void setUniform(unsigned int ordinal, const std::string &name, const std::vector<glm::mat4> &arr);
|
||||
void setLocalUniforms(const LocalUniforms &locals);
|
||||
void setUniform(const std::string &name, int value);
|
||||
void setUniform(const std::string &name, float value);
|
||||
void setUniform(const std::string &name, const glm::vec2 &v);
|
||||
void setUniform(const std::string &name, const glm::vec3 &v);
|
||||
void setUniform(const std::string &name, const glm::mat4 &m);
|
||||
void setUniform(const std::string &name, const std::vector<glm::mat4> &arr);
|
||||
};
|
||||
|
||||
#define Shaders render::ShaderManager::instance()
|
||||
|
|
|
@ -162,14 +162,14 @@ void RenderWindow::drawCursor() const {
|
|||
|
||||
if (!texture) return;
|
||||
|
||||
glm::mat4 transform(glm::translate(glm::mat4(1.0f), glm::vec3(x, y, 0.0f)));
|
||||
glm::mat4 transform(1.0f);
|
||||
transform = glm::translate(transform, glm::vec3(x, y, 0.0f));
|
||||
transform = glm::scale(transform, glm::vec3(texture->width(), texture->height(), 1.0f));
|
||||
|
||||
ShaderManager &shaders = Shaders;
|
||||
shaders.activate(ShaderProgram::GUIGUI);
|
||||
shaders.setUniform("model", transform);
|
||||
shaders.setUniform("color", glm::vec3(1.0f));
|
||||
shaders.setUniform("alpha", 1.0f);
|
||||
LocalUniforms locals;
|
||||
locals.model = move(transform);
|
||||
|
||||
Shaders.activate(ShaderProgram::GUIGUI, locals);
|
||||
|
||||
glActiveTexture(0);
|
||||
texture->bind();
|
||||
|
|
Loading…
Reference in a new issue