浏览代码

some lighting stuff

feature/new-lighting-engine
Martin Dørum 3 年前
父节点
当前提交
97884a06bb

+ 0
- 1
core.mod/src/entities/PlayerEntity.cc 查看文件

rnd.drawRect(body_.pos, body_.size); rnd.drawRect(body_.pos, body_.size);


rnd.drawLight(1, body_.topMid() + Swan::Vec2{0, 0.3}); rnd.drawLight(1, body_.topMid() + Swan::Vec2{0, 0.3});
rnd.drawLight(1, {0, 0});
} }


void PlayerEntity::update(const Swan::Context &ctx, float dt) { void PlayerEntity::update(const Swan::Context &ctx, float dt) {

+ 1
- 1
core.mod/src/main.cc 查看文件

.name = "torch", .name = "torch",
.image = "core::tile/torch", .image = "core::tile/torch",
.isSolid = false, .isSolid = false,
.lightLevel = 80/255.0,
.lightLevel = 3,
}); });


registerItem({ registerItem({

+ 1
- 1
libcygnet/include/cygnet/gl.h 查看文件

#include <SDL_opengles2.h>
#include <GLES3/gl3.h>

+ 46
- 11
libcygnet/src/Renderer.cc 查看文件

~LightingProg() { deinit(); } ~LightingProg() { deinit(); }


GLint inverseCamera = uniformLoc("inverseCamera"); GLint inverseCamera = uniformLoc("inverseCamera");
GLint camera = uniformLoc("camera");
GLint lightPos = uniformLoc("lightPos"); GLint lightPos = uniformLoc("lightPos");
GLint lightLevel = uniformLoc("lightLevel"); GLint lightLevel = uniformLoc("lightLevel");
GLint opacityTex = uniformLoc("opacityTex");
GLint vertex = attribLoc("vertex"); GLint vertex = attribLoc("vertex");


GLuint vbo; GLuint vbo;


static constexpr GLfloat vertexes[] = { static constexpr GLfloat vertexes[] = {
-1.0f, -1.0f, // pos 0: top left -1.0f, -1.0f, // pos 0: top left
-1.0f, 1.0f , // pos 1: bottom left
1.0f, 1.0f, // pos 2: bottom right
1.0f, 1.0f, // pos 2: bottom right
-1.0f, 1.0f, // pos 1: bottom left
1.0f, 1.0f, // pos 2: bottom right
1.0f, 1.0f, // pos 2: bottom right
1.0f, -1.0f, // pos 3: top right 1.0f, -1.0f, // pos 3: top right
-1.0f, -1.0f, // pos 0: top left -1.0f, -1.0f, // pos 0: top left
}; };
glVertexAttribPointer(vertex, 2, GL_FLOAT, GL_FALSE, 0, (void *)0); glVertexAttribPointer(vertex, 2, GL_FLOAT, GL_FALSE, 0, (void *)0);
glEnableVertexAttribArray(vertex); glEnableVertexAttribArray(vertex);
glCheck(); glCheck();

glUniform1i(opacityTex, 0);
} }


void disable() { void disable() {
GLuint opacityFramebuffer = 0; GLuint opacityFramebuffer = 0;
GLuint opacityTex = 0; GLuint opacityTex = 0;
GLuint atlasTex = 0; GLuint atlasTex = 0;
GLuint ditherTex = 0;
SwanCommon::Vec2 atlasTexSize; SwanCommon::Vec2 atlasTexSize;
}; };


// Bayer dither pattern
static const unsigned char ditherPattern[] = {
0, 32, 8, 40, 2, 34, 10, 42,
48, 16, 56, 24, 50, 18, 58, 26,
12, 44, 4, 36, 14, 46, 6, 38,
60, 28, 52, 20, 62, 30, 54, 22,
3, 35, 11, 43, 1, 33, 9, 41,
51, 19, 59, 27, 49, 17, 57, 25,
15, 47, 7, 39, 13, 45, 5, 37,
63, 31, 55, 23, 61, 29, 53, 21,
};

Renderer::Renderer(): state_(std::make_unique<RendererState>()) { Renderer::Renderer(): state_(std::make_unique<RendererState>()) {
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glEnable(GL_BLEND); glEnable(GL_BLEND);
glCheck(); glCheck();


glGenTextures(1, &state_->atlasTex);
glCheck();

glGenFramebuffers(1, &state_->lightingFramebuffer); glGenFramebuffers(1, &state_->lightingFramebuffer);
glCheck(); glCheck();
glGenTextures(1, &state_->lightingTex); glGenTextures(1, &state_->lightingTex);
glCheck(); glCheck();
glGenTextures(1, &state_->opacityTex); glGenTextures(1, &state_->opacityTex);
glCheck(); glCheck();

glGenTextures(1, &state_->atlasTex);
glCheck();

glGenTextures(1, &state_->ditherTex);
glCheck();
glBindTexture(GL_TEXTURE_2D, state_->ditherTex);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexImage2D(
GL_TEXTURE_2D, 0, GL_LUMINANCE, 8, 8, 0, GL_LUMINANCE,
GL_UNSIGNED_BYTE, ditherPattern);
glCheck();
} }


Renderer::~Renderer() { Renderer::~Renderer() {
glTexImage2D( glTexImage2D(
GL_TEXTURE_2D, 0, GL_RGBA, cam.size.x, cam.size.y, 0, GL_TEXTURE_2D, 0, GL_RGBA, cam.size.x, cam.size.y, 0,
GL_RGBA, GL_UNSIGNED_BYTE, NULL); GL_RGBA, GL_UNSIGNED_BYTE, NULL);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glCheck(); glCheck();


glBindTexture(GL_TEXTURE_2D, state_->opacityTex); glBindTexture(GL_TEXTURE_2D, state_->opacityTex);
glCheck(); glCheck();
glTexImage2D( glTexImage2D(
GL_TEXTURE_2D, 0, GL_RGBA, cam.size.x, cam.size.y, 0,
GL_TEXTURE_2D, 0, GL_RGBA, cam.size.x / 2, cam.size.y / 8, 0,
GL_RGBA, GL_UNSIGNED_BYTE, NULL); GL_RGBA, GL_UNSIGNED_BYTE, NULL);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glCheck(); glCheck();
} }


glClear(GL_COLOR_BUFFER_BIT); glClear(GL_COLOR_BUFFER_BIT);
glCheck(); glCheck();


glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, state_->ditherTex);
glCheck();

glBlendFunc(GL_ONE, GL_ONE); glBlendFunc(GL_ONE, GL_ONE);
lightingProg.enable(); lightingProg.enable();
glUniformMatrix3fv(lightingProg.inverseCamera, 1, GL_TRUE, invCamMat.data()); glUniformMatrix3fv(lightingProg.inverseCamera, 1, GL_TRUE, invCamMat.data());

+ 1
- 1
libcygnet/src/Window.cc 查看文件

Window::Window(const char *name, int w, int h): Window::Window(const char *name, int w, int h):
state_(std::make_unique<WindowState>()), w_(w), h_(h) { state_(std::make_unique<WindowState>()), w_(w), h_(h) {
SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_ES); SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_ES);
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 2);
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3);
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 0); SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 0);
SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1); SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 24); SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 24);

+ 37
- 20
libcygnet/src/shaders.cc 查看文件

const char *lightingVx = R"glsl( const char *lightingVx = R"glsl(
precision mediump float; precision mediump float;
uniform mat3 inverseCamera; uniform mat3 inverseCamera;
uniform mat3 camera;
uniform vec2 lightPos;
attribute vec2 vertex; attribute vec2 vertex;
varying vec2 v_pos; varying vec2 v_pos;
varying vec2 v_opacityCoord;
varying vec2 v_lightCoord;


void main() { void main() {
v_opacityCoord = (vertex + 1.0) / 4.0 + 0.25;
v_lightCoord = ((camera * vec3(lightPos, 1)).xy + 1.0) / 4.0 + 0.25;
v_pos = (inverseCamera * vec3(vertex, 1)).xy; v_pos = (inverseCamera * vec3(vertex, 1)).xy;
gl_Position = vec4(vertex.xy, 0, 1); gl_Position = vec4(vertex.xy, 0, 1);
} }
const char *lightingFr = R"glsl( const char *lightingFr = R"glsl(
precision mediump float; precision mediump float;
varying vec2 v_pos; varying vec2 v_pos;
varying vec2 v_opacityCoord;
varying vec2 v_lightCoord;
uniform vec2 lightPos; uniform vec2 lightPos;
uniform float lightLevel; uniform float lightLevel;
uniform sampler2D opacityTex;
uniform sampler2D ditherTex;
const float power = 1.0 / 2.4;


void main() { void main() {
vec2 diff = lightPos - v_pos; vec2 diff = lightPos - v_pos;
float squareDist = diff.x * diff.x + diff.y * diff.y; float squareDist = diff.x * diff.x + diff.y * diff.y;
float dist = sqrt(squareDist); float dist = sqrt(squareDist);
float attenuated = 1.0 / (1.0 + 1.0 * dist + 0.2 * squareDist);
float light = lightLevel * attenuated;
gl_FragColor = vec4(light, light, light, light);
}
)glsl";

const char *tileVx = R"glsl(
precision mediump float;
uniform mat3 camera;
uniform mat3 transform;
attribute vec2 vertex;
varying vec2 v_tileCoord;

void main() {
vec3 pos = camera * transform * vec3(vertex, 1);
gl_Position = vec4(pos.xy, 0, 1);
v_tileCoord = vertex;
squareDist = dist * dist;
//float attenuated = 1.0 / (1.0 * (dist / lightLevel) + 0.1 * (squareDist / lightLevel));
//float attenuated = 1.0 / (1.0 + exp(dist / lightLevel - 2.0));
//float attenuated = 1.0 / (1.0 + 0.2 * squareDist + dist);
float attenuated = 1.0 / (1.0 + squareDist);
float light = attenuated * lightLevel;

gl_FragColor = vec4(light, 0, 0, 0);
gl_FragColor += vec4(texture2D(ditherTex, gl_FragCoord.xy / 8.0).r / 32.0 - (1.0 / 128.0));
} }
)glsl"; )glsl";


const float power = 1.0 / 2.4; const float power = 1.0 / 2.4;


void main() { void main() {
vec4 linear = texture2D(tex, v_texCoord);
vec4 srgb = 1.055 * pow(linear, vec4(power, power, power, power)) - 0.055;
gl_FragColor = srgb;
float linear = texture2D(tex, v_texCoord).r;
float srgb = 1.055 * pow(linear, power) - 0.055;
gl_FragColor = vec4(srgb, srgb, srgb, srgb);
}
)glsl";

const char *tileVx = R"glsl(
precision mediump float;
uniform mat3 camera;
uniform mat3 transform;
attribute vec2 vertex;
varying vec2 v_tileCoord;

void main() {
vec3 pos = camera * transform * vec3(vertex, 1);
gl_Position = vec4(pos.xy, 0, 1);
v_tileCoord = vertex;
} }
)glsl"; )glsl";



正在加载...
取消
保存