Skip to content

Commit

Permalink
Gloom: Use texture buffers for materials, planes, and SSAO noise
Browse files Browse the repository at this point in the history
  • Loading branch information
skyjake committed Sep 1, 2019
1 parent 4b4bc39 commit c38762c
Show file tree
Hide file tree
Showing 9 changed files with 76 additions and 63 deletions.
75 changes: 39 additions & 36 deletions doomsday/tests/test_gloom/gloom/render/databuffer.h
Expand Up @@ -19,80 +19,83 @@
#ifndef GLOOM_DATABUFFER_H
#define GLOOM_DATABUFFER_H

#include <de/GLBuffer>
#include <de/GLTexture>
#include <de/GLUniform>
#include <de/Image>
#include <de/Vector>

namespace gloom {

using namespace de;

template <typename Type>
struct DataBuffer
{
int elementCount = 0;
de::GLUniform var;
de::GLTexture buf;
de::Vec2ui size;
GLUniform var;
GLBuffer buf;
GLuint bufTex{0};
QVector<Type> data;
de::Image::Format format;
uint texelsPerElement; // number of pixels needed to represent one element
uint maxWidth;
Image::Format format;
gl::Usage usage;

DataBuffer(const char * uName,
de::Image::Format format,
uint texelsPerElement = 1,
uint maxWidth = 0)
: var{uName, de::GLUniform::Sampler2D}
DataBuffer(const char * uName,
Image::Format format,
gl::Usage usage = gl::Stream)
: var{uName, GLUniform::SamplerBuffer}
, buf{GLBuffer::Texture}
, format(format)
, texelsPerElement(texelsPerElement)
, maxWidth(maxWidth)
{
buf.setAutoGenMips(false);
buf.setFilter(de::gl::Nearest, de::gl::Nearest, de::gl::MipNone);
var = buf;
}
, usage(usage)
{}

void init(int count)
{
elementCount = count;
size.x = de::max(4u, uint(std::sqrt(count) + 0.5));
if (maxWidth) size.x = de::min(maxWidth, size.x);
size.y = de::max(4u, uint((count + size.x - 1) / size.x));
data.resize(size.area());
data.resize(count);
data.fill(Type{});
}

void clear()
{
elementCount = 0;
if (bufTex)
{
LIBGUI_GL.glDeleteTextures(1, &bufTex);
bufTex = 0;
}
buf.clear();
data.clear();
size = de::Vec2ui();
}

int size() const
{
return data.size();
}

void setData(uint index, const Type &value)
{
const int x = index % size.x;
const int y = index / size.x;
data[x + y*size.x] = value;
data[index] = value;
}

uint32_t append(const Type &value)
{
DENG2_ASSERT(maxWidth > 0);
size.x = maxWidth;
size.y++;
elementCount++;
const uint32_t oldSize = data.size();
data << value;
return oldSize;
}

void update()
{
buf.setImage(de::Image{de::Image::Size(size.x * texelsPerElement, size.y),
format,
de::ByteRefArray(data.constData(), sizeof(data[0]) * size.area())});
buf.setData(data.constData(), data.size() * sizeof(data[0]), usage);

auto &GL = LIBGUI_GL;
if (!bufTex)
{
GL.glGenTextures(1, &bufTex);
var = bufTex;
}
GL.glBindTexture(GL_TEXTURE_BUFFER, bufTex);
GL.glTexBuffer(GL_TEXTURE_BUFFER, Image::glFormat(format).internalFormat, buf.glName());
LIBGUI_ASSERT_GL_OK();
GL.glBindTexture(GL_TEXTURE_BUFFER, 0);
}
};

Expand Down
4 changes: 2 additions & 2 deletions doomsday/tests/test_gloom/gloom/render/light.h
Expand Up @@ -57,8 +57,8 @@ class Light : public ICamera
float aspectRatio() const;
float falloffDistance() const;

de::Mat4f lightMatrix() const;
de::Mat4f lightMatrix(de::gl::CubeFace) const;
de::Mat4f lightMatrix() const;
de::Mat4f lightMatrix(de::gl::CubeFace) const;

de::Vec3f cameraPosition() const;
de::Vec3f cameraFront() const;
Expand Down
2 changes: 1 addition & 1 deletion doomsday/tests/test_gloom/gloom/render/lightrender.cpp
Expand Up @@ -51,7 +51,7 @@ static constexpr int MAX_SHADOWS = 6;

DENG2_PIMPL(LightRender)
{
using VBuf = GLBufferT<Vertex3>;
using VBuf = GLBufferT<Vertex3>;
using Lights = QHash<ID, std::shared_ptr<Light>>;

std::unique_ptr<Light> skyLight;
Expand Down
2 changes: 1 addition & 1 deletion doomsday/tests/test_gloom/gloom/render/maprender.cpp
Expand Up @@ -53,7 +53,7 @@ DENG2_PIMPL(MapRender)
Vec2f speed;
};

DataBuffer<Metrics> textureMetrics{"uTextureMetrics", Image::RGBA_32f, 2 * TextureMapCount, 1};
DataBuffer<Metrics> textureMetrics{"uTextureMetrics", Image::RGBA_32f, gl::Static}; //2 * TextureMapCount, 1};
DataBuffer<float> planes {"uPlanes", Image::R_32f};
DataBuffer<TexOffsetData> texOffsets {"uTexOffsets", Image::RGBA_32f};

Expand Down
9 changes: 4 additions & 5 deletions doomsday/tests/test_gloom/gloom/render/ssao.cpp
Expand Up @@ -40,7 +40,7 @@ DENG2_PIMPL(SSAO)

ScreenQuad quad;
GLUniform uSamples{"uSamples", GLUniform::Vec3Array, SAMPLE_COUNT};
DataBuffer<Vec3f> noise{"uNoise", Image::RGB_16f};
DataBuffer<Vec2f> noise{"uNoise", Image::RG_32f, gl::Static};
GLFramebuffer ssaoFrameBuf[2];
GLTexture ssaoBuf[2];
GLUniform uNoisyFactors{"uNoisyFactors", GLUniform::Sampler2D};
Expand Down Expand Up @@ -101,11 +101,10 @@ DENG2_PIMPL(SSAO)
// Noise.
{
noise.init(16);
for (int i = 0; i < noise.elementCount; ++i)
for (int i = 0; i < noise.size(); ++i)
{
noise.setData(i, Vec3f{Rangef(0, 2).random() - 1,
Rangef(0, 2).random() - 1,
0});
noise.setData(i, Vec2f{Rangef(0, 2).random() - 1,
Rangef(0, 2).random() - 1});
}
noise.update();
quad.program() << noise.var;
Expand Down
Expand Up @@ -4,8 +4,8 @@
#include "defs.glsl"
#include "miplevel.glsl"

uniform sampler2D uTextureAtlas[4];
uniform sampler2D uTextureMetrics;
uniform sampler2D uTextureAtlas[4];
uniform samplerBuffer uTextureMetrics;

struct Metrics {
bool isValid;
Expand All @@ -22,17 +22,22 @@ const vec4 Material_DefaultTextureValue[4] = vec4[4] (
vec4(0.5, 0.5, 0.5, 1.0) // normal/displacement
);

const int Material_TextureMetricsTexelsPerTexture = 2;
const int Material_TextureMetricsTexelsPerElement =
Material_TextureMetricsTexelsPerTexture * 4;

Metrics Gloom_TextureMetrics(uint matIndex, int texture) {
Metrics metrics;
int x = texture * 2;
vec3 texelSize = texelFetch(uTextureMetrics, ivec2(x + 1, matIndex), 0).xyz;
int bufPos = int(matIndex) * Material_TextureMetricsTexelsPerElement +
texture * Material_TextureMetricsTexelsPerTexture;
vec3 texelSize = texelFetch(uTextureMetrics, bufPos + 1).xyz;
metrics.sizeInTexels = texelSize.xy;
// Not all textures are defined/present.
if (metrics.sizeInTexels == vec2(0.0)) {
metrics.isValid = false;
return metrics;
}
metrics.uvRect = texelFetch(uTextureMetrics, ivec2(x, matIndex), 0);
metrics.uvRect = texelFetch(uTextureMetrics, bufPos);
metrics.texelsPerMeter = texelSize.z;
metrics.scale = vec2(metrics.texelsPerMeter) / metrics.sizeInTexels;
metrics.isValid = true;
Expand Down
@@ -1,7 +1,7 @@
#ifndef GLOOM_SURFACE_H
#define GLOOM_SURFACE_H

uniform sampler2D uPlanes;
uniform samplerBuffer uPlanes;

DENG_ATTRIB vec4 aVertex;
DENG_ATTRIB vec4 aUV; // s, t, wallLength, rotation angle
Expand All @@ -24,8 +24,8 @@ struct Surface {
};

float Gloom_FetchPlaneY(uint planeIndex) {
uint dw = uint(textureSize(uPlanes, 0).x);
return texelFetch(uPlanes, ivec2(planeIndex % dw, planeIndex / dw), 0).r;
// int dw = textureSize(uPlanes, 0).x);
return texelFetch(uPlanes, int(planeIndex)).r;
}

Surface Gloom_LoadVertexSurface(void) {
Expand Down
Expand Up @@ -5,13 +5,19 @@
const int SAMPLE_COUNT = 64;
const float RADIUS = 0.5;
const int NOISE_SIZE = 4;
const int NOISE_MASK = 3;

uniform vec3 uSamples[SAMPLE_COUNT];
uniform sampler2D uNoise;
uniform mat4 uProjMatrix;
uniform vec3 uSamples[SAMPLE_COUNT];
uniform samplerBuffer uNoise;
uniform mat4 uProjMatrix;

int noiseIndex(ivec2 pos) {
pos &= NOISE_MASK;
return pos.y * NOISE_SIZE + pos.x;
}

void main(void) {
vec3 randomVec = texelFetch(uNoise, ivec2(gl_FragCoord.xy) % NOISE_SIZE, 0).rgb;
vec3 randomVec = texelFetch(uNoise, noiseIndex(ivec2(gl_FragCoord.xy))).rgb;
vec3 normal = GBuffer_FragViewSpaceNormal();
vec3 fragPos = GBuffer_FragViewSpacePos().xyz;

Expand Down
Expand Up @@ -4,10 +4,10 @@
#include "common/surface.glsl"
#include "common/tangentspace.glsl"

uniform mat4 uCameraMvpMatrix;
uniform vec4 uCameraPos; // world space
uniform sampler2D uTexOffsets;
uniform float uCurrentTime;
uniform mat4 uCameraMvpMatrix;
uniform vec4 uCameraPos; // world space
uniform samplerBuffer uTexOffsets;
uniform float uCurrentTime;

DENG_ATTRIB float aTexture0; // front material
DENG_ATTRIB float aTexture1; // back material
Expand All @@ -23,8 +23,8 @@ flat DENG_VAR float vMaterial;
flat DENG_VAR uint vFlags;

vec4 fetchTexOffset(uint offsetIndex) {
uint dw = uint(textureSize(uTexOffsets, 0).x);
return texelFetch(uTexOffsets, ivec2(offsetIndex % dw, offsetIndex / dw), 0);
// uint dw = uint(textureSize(uTexOffsets, 0).x);
return texelFetch(uTexOffsets, int(offsetIndex));
}

void main(void) {
Expand Down

0 comments on commit c38762c

Please sign in to comment.