Skip to content

Commit

Permalink
Add view port effect for post processing
Browse files Browse the repository at this point in the history
  • Loading branch information
levinli303 committed Oct 10, 2020
1 parent 1f8cc6b commit 17cd02b
Show file tree
Hide file tree
Showing 22 changed files with 675 additions and 44 deletions.
8 changes: 8 additions & 0 deletions shaders/passthrough_frag.glsl
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
varying vec2 texCoord;

uniform sampler2D tex;

void main(void)
{
gl_FragColor = texture2D(tex, texCoord);
}
10 changes: 10 additions & 0 deletions shaders/passthrough_vert.glsl
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
attribute vec2 in_Position;
attribute vec2 in_TexCoord0;

varying vec2 texCoord;

void main(void)
{
gl_Position = vec4(in_Position.xy, 0.0, 1.0);
texCoord = in_TexCoord0.st;
}
9 changes: 9 additions & 0 deletions shaders/warpmesh_frag.glsl
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
varying vec2 texCoord;
varying float intensity;

uniform sampler2D tex;

void main(void)
{
gl_FragColor = vec4(texture2D(tex, texCoord).rgb * intensity, 1.0);
}
16 changes: 16 additions & 0 deletions shaders/warpmesh_vert.glsl
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
attribute vec2 in_Position;
attribute vec2 in_TexCoord0;
attribute float in_Intensity;

varying vec2 texCoord;
varying float intensity;

uniform float screenRatio;

void main(void)
{
float offset = 0.5 - screenRatio * 0.5;
gl_Position = vec4(in_Position.x * screenRatio, in_Position.y, 0.0, 1.0);
texCoord = vec2(in_TexCoord0.x * screenRatio + offset, in_TexCoord0.y);
intensity = in_Intensity;
}
4 changes: 4 additions & 0 deletions src/celengine/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,8 @@ set(CELENGINE_SOURCES
location.h
lodspheremesh.cpp
lodspheremesh.h
mapmanager.cpp
mapmanager.h
marker.cpp
marker.h
meshmanager.cpp
Expand Down Expand Up @@ -168,6 +170,8 @@ set(CELENGINE_SOURCES
vecgl.h
vertexobject.cpp
vertexobject.h
viewporteffect.h
viewporteffect.cpp
virtualtex.cpp
virtualtex.h
visibleregion.cpp
Expand Down
13 changes: 7 additions & 6 deletions src/celengine/framebuffer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,8 @@ FramebufferObject::generateFbo(unsigned int attachments)
{
// Create the FBO
glGenFramebuffers(1, &m_fboId);
GLint oldFboId;
glGetIntegerv(GL_FRAMEBUFFER_BINDING, &oldFboId);
glBindFramebuffer(GL_FRAMEBUFFER, m_fboId);

#ifndef GL_ES
Expand All @@ -151,7 +153,7 @@ FramebufferObject::generateFbo(unsigned int attachments)
m_status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
if (m_status != GL_FRAMEBUFFER_COMPLETE)
{
glBindFramebuffer(GL_FRAMEBUFFER, 0);
glBindFramebuffer(GL_FRAMEBUFFER, oldFboId);
cleanup();
return;
}
Expand All @@ -171,7 +173,7 @@ FramebufferObject::generateFbo(unsigned int attachments)
m_status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
if (m_status != GL_FRAMEBUFFER_COMPLETE)
{
glBindFramebuffer(GL_FRAMEBUFFER, 0);
glBindFramebuffer(GL_FRAMEBUFFER, oldFboId);
cleanup();
return;
}
Expand All @@ -182,7 +184,7 @@ FramebufferObject::generateFbo(unsigned int attachments)
}

// Restore default frame buffer
glBindFramebuffer(GL_FRAMEBUFFER, 0);
glBindFramebuffer(GL_FRAMEBUFFER, oldFboId);
}

// Delete all GL objects associated with this framebuffer object
Expand Down Expand Up @@ -218,9 +220,8 @@ FramebufferObject::bind()
}

bool
FramebufferObject::unbind()
FramebufferObject::unbind(GLint oldfboId)
{
// Restore default frame buffer
glBindFramebuffer(GL_FRAMEBUFFER, 0);
glBindFramebuffer(GL_FRAMEBUFFER, oldfboId);
return true;
}
2 changes: 1 addition & 1 deletion src/celengine/framebuffer.h
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ class FramebufferObject
GLuint depthTexture() const;

bool bind();
bool unbind();
bool unbind(GLint oldfboId);

private:
void generateColorTexture();
Expand Down
196 changes: 196 additions & 0 deletions src/celengine/mapmanager.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,196 @@
//
// mapmanager.cpp
//
// Copyright © 2020 Celestia Development Team. All rights reserved.
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 2
// of the License, or (at your option) any later version.

#include <celutil/debug.h>
#include <fstream>
#include "mapmanager.h"

using namespace std;

WarpMesh::WarpMesh(int nx, int ny, float *data) :
nx(nx),
ny(ny),
data(data)
{
}

WarpMesh::~WarpMesh()
{
delete data;
}

void WarpMesh::scopedDataForRendering(const function<void (float*, int)>& f) const
{
int step = 5 * 6;
int size = (nx - 1) * (ny - 1) * step * sizeof(float);
float *renderingData = new float[size];
for (int y = 0; y < ny - 1; y += 1)
{
for (int x = 0; x < nx - 1; x += 1)
{
float *destination = &renderingData[(y * (nx - 1) + x) * step];
float *source = &data[(y * nx + x) * 5];
// Top left triangle
memcpy(destination, source + 5 * nx, sizeof(float) * 5);
memcpy(destination + 5, source, sizeof(float) * 5);
memcpy(destination + 10, source + 5, sizeof(float) * 5);
// Bottom right triangle
memcpy(destination + 15, source + 5 * nx, sizeof(float) * 5);
memcpy(destination + 20, source + 5, sizeof(float) * 5);
memcpy(destination + 25, source + 5 * nx + 5, sizeof(float) * 5);
}
}
f(renderingData, size);
delete[] renderingData;
}

int WarpMesh::count() const
{
return 6 * (nx - 1) * (ny - 1);
}

bool WarpMesh::mapVertex(float x, float y, float* u, float* v) const
{
float minX = data[0];
float minY = data[1];
float maxX = data[(nx * ny - 1) * 5];
float maxY = data[(nx * ny - 1) * 5 + 1];

float stepX = (maxX - minX) / (nx - 1);
float stepY = (maxY - minY) / (ny - 1);

float locX = (x - minX) / stepX;
float locY = (y - minY) / stepY;
int floX = floorf(locX);
int floY = floorf(locY);
locX -= floX;
locY -= floY;

if (floX < 0 || floX >= nx - 1 || floY < 0 || floY >= ny - 1)
return false;

float p1x = data[(floY * nx + floX) * 5 + 2];
float p1y = data[(floY * nx + floX) * 5 + 3];
float p2x = data[(floY * nx + floX + 1) * 5 + 2];
float p2y = data[(floY * nx + floX + 1) * 5 + 3];
float p3x = data[(floY * nx + floX + nx) * 5 + 2];
float p3y = data[(floY * nx + floX + nx) * 5 + 3];
float p4x = data[(floY * nx + floX + nx + 1) * 5 + 2];
float p4y = data[(floY * nx + floX + nx + 1) * 5 + 3];

if (locX + locY <= 1)
{
// the top left part triangle
*u = p1x + locX * (p2x - p1x) + locY * (p3x - p1x);
*v = p1y + locX * (p2y - p1y) + locY * (p3y - p1y);
}
else
{
// the bottom right triangle
locX -= 1;
locY -= 1;
*u = p4x + locX * (p4x - p3x) + locY * (p4x - p2x);
*v = p4y + locX * (p4y - p3y) + locY * (p4y - p2y);
}
// Texture coordinate is [0, 1], normalize to [-1, 1]
*u = (*u) * 2 - 1;
*v = (*v) * 2 - 1;
return true;
}

WarpMeshManager* GetWarpMeshManager()
{
static WarpMeshManager* warpMeshManager = nullptr;
if (warpMeshManager == nullptr)
warpMeshManager = new WarpMeshManager("warp");
return warpMeshManager;
}

static string resolveWildcard(const string& filename)
{
string base(filename, 0, filename.length() - 1);

string mapfile = base + "map";
ifstream in(mapfile);
if (in.good())
return mapfile;

return {};
}

fs::path WarpMeshInfo::resolve(const fs::path& baseDir)
{
bool wildcard = false;
if (!source.empty() && source.at(source.length() - 1) == '*')
wildcard = true;

fs::path filename = baseDir / source;
if (wildcard)
{
string matched = resolveWildcard(filename.string());
if (matched.empty())
return filename; // . . . for lack of any better way to handle it.
else
return matched;
}

return filename;
}


WarpMesh* WarpMeshInfo::load(const fs::path& name)
{
#define MESHTYPE_RECT 2
ifstream f(name.string());
if (!f.good())
return nullptr;

int type, nx, ny;
if (!(f >> type))
{
DPRINTF(LOG_LEVEL_ERROR, "Failed to read mesh header\n");
return nullptr;
}

if (type != MESHTYPE_RECT)
{
DPRINTF(LOG_LEVEL_ERROR, "Unsupported mesh type found: %d\n", type);
return nullptr;
}

if (!(f >> nx >> ny))
{
DPRINTF(LOG_LEVEL_ERROR, "Failed to read mesh header\n");
return nullptr;
}

if (nx < 2 || ny < 2)
{
DPRINTF(LOG_LEVEL_ERROR, "Row and column numbers should be larger than 2\n");
return nullptr;
}

float *data = new float[nx * ny * 5];
for (int y = 0; y < ny; y += 1)
{
for (int x = 0; x < nx; x += 1)
{
float *base = &data[(y * nx + x) * 5];
if (!(f >> base[0] >> base[1] >> base[2] >> base[3] >> base[4]))
{
DPRINTF(LOG_LEVEL_ERROR, "Failed to read mesh data\n");
delete[] data;
return nullptr;
}
}
}
DPRINTF(LOG_LEVEL_INFO, "Read a mesh of %d * %d\n", nx, ny);
return new WarpMesh(nx, ny, data);
}
57 changes: 57 additions & 0 deletions src/celengine/mapmanager.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
//
// mapmanager.h
//
// Copyright © 2020 Celestia Development Team. All rights reserved.
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 2
// of the License, or (at your option) any later version.

#pragma once

#include <string>
#include <map>
#include <functional>
#include <celutil/resmanager.h>

// File format for data used to warp an image, for
// detail, see http://paulbourke.net/dataformats/meshwarp/
class WarpMesh
{
public:
WarpMesh(int nx, int ny, float* data);
~WarpMesh();

// Map data to triangle vertices used for drawing
void scopedDataForRendering(const std::function<void(float*, int)>&) const;
int count() const; // Number of vertices

// Convert a vertex coordinate to texture coordinate
bool mapVertex(float x, float y, float* u, float* v) const;

private:
int nx;
int ny;
float* data;
};

class WarpMeshInfo : public ResourceInfo<WarpMesh>
{
public:
std::string source;

WarpMeshInfo(const std::string& source) : source(source) {};

fs::path resolve(const fs::path&) override;
WarpMesh* load(const fs::path&) override;
};

inline bool operator<(const WarpMeshInfo& wi0, const WarpMeshInfo& wi1)
{
return wi0.source < wi1.source;
}

typedef ResourceManager<WarpMeshInfo> WarpMeshManager;

WarpMeshManager* GetWarpMeshManager();
4 changes: 3 additions & 1 deletion src/celengine/renderglsl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -910,6 +910,8 @@ void renderGeometryShadow_GLSL(Geometry* geometry,
if (prog == nullptr)
return;

GLint oldFboId;
glGetIntegerv(GL_FRAMEBUFFER_BINDING, &oldFboId);
shadowFbo->bind();
glViewport(0, 0, shadowFbo->width(), shadowFbo->height());

Expand Down Expand Up @@ -939,5 +941,5 @@ void renderGeometryShadow_GLSL(Geometry* geometry,
// Re-enable the color buffer
glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
glCullFace(GL_BACK);
shadowFbo->unbind();
shadowFbo->unbind(oldFboId);
}
Loading

0 comments on commit 17cd02b

Please sign in to comment.