Rendering terrain chunks with new shader system
This commit is contained in:
parent
f97823604e
commit
bf47e058ee
11 changed files with 115 additions and 61 deletions
|
@ -3,7 +3,6 @@
|
|||
#include OPENGL_FUNCTIONS_INCLUDE
|
||||
#include <cmath>
|
||||
#include <QImage>
|
||||
#include <QOpenGLTexture>
|
||||
#include "ColorProfile.h"
|
||||
#include "CameraDefinition.h"
|
||||
#include "OpenGLRenderer.h"
|
||||
|
@ -13,13 +12,13 @@
|
|||
ExplorerChunkTerrain::ExplorerChunkTerrain(OpenGLRenderer* renderer, double x, double z, double size, int nbchunks, double water_height):
|
||||
_renderer(renderer)
|
||||
{
|
||||
_color_profile = new ColorProfile;
|
||||
_color_profile = new ColorProfile(ColorProfile::TONE_MAPPING_REIHNARD, 2.0);
|
||||
|
||||
priority = 0.0;
|
||||
_reset_needed = false;
|
||||
|
||||
_texture = new QImage(1, 1, QImage::Format_ARGB32);
|
||||
texture = new QOpenGLTexture(*_texture);
|
||||
_texture = new QImage(1, 1, QImage::Format_RGBA8888);
|
||||
texture_id = 0;
|
||||
_texture_changed = false;
|
||||
_texture_current_size = 0;
|
||||
_texture_max_size = 0;
|
||||
|
@ -52,7 +51,6 @@ ExplorerChunkTerrain::~ExplorerChunkTerrain()
|
|||
_lock_data.lock();
|
||||
delete _color_profile;
|
||||
delete _texture;
|
||||
delete texture;
|
||||
delete tessellated;
|
||||
_lock_data.unlock();
|
||||
}
|
||||
|
@ -85,9 +83,9 @@ bool ExplorerChunkTerrain::maintain()
|
|||
if (_texture_current_size <= 1 || i % 2 != 0 || j % 2 != 0)
|
||||
{
|
||||
Color color = getTextureColor((double)i / (double)new_texture_size, (double)j / (double)new_texture_size);
|
||||
color = _color_profile->apply(color);
|
||||
//color = _color_profile->apply(color);
|
||||
color.normalize();
|
||||
new_image->setPixel(i, j, color.to32BitBGRA());
|
||||
new_image->setPixel(i, j, color.to32BitRGBA());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -213,24 +211,34 @@ void ExplorerChunkTerrain::updatePriority(CameraDefinition* camera)
|
|||
_lock_data.unlock();
|
||||
}
|
||||
|
||||
void ExplorerChunkTerrain::render(OpenGLFunctions* functions)
|
||||
void ExplorerChunkTerrain::render(QOpenGLShaderProgram* program, OpenGLFunctions* functions)
|
||||
{
|
||||
// Put texture in place
|
||||
_lock_data.lock();
|
||||
if (_texture_changed)
|
||||
{
|
||||
_texture_changed = false;
|
||||
texture->destroy();
|
||||
|
||||
// TODO Only do the scale if not power-of-two textures are unsupported by GPU
|
||||
texture->setData(_texture->scaled(_texture_current_size, _texture_current_size, Qt::IgnoreAspectRatio, Qt::SmoothTransformation));
|
||||
//texture->setData(*_texture);
|
||||
texture->setWrapMode(QOpenGLTexture::DirectionS, QOpenGLTexture::ClampToEdge);
|
||||
texture->setWrapMode(QOpenGLTexture::DirectionT, QOpenGLTexture::ClampToEdge);
|
||||
QImage tex = _texture->scaled(_texture_current_size, _texture_current_size, Qt::IgnoreAspectRatio, Qt::SmoothTransformation);
|
||||
|
||||
if (texture_id == 0)
|
||||
{
|
||||
GLuint texid;
|
||||
functions->glGenTextures(1, &texid);
|
||||
texture_id = texid;
|
||||
}
|
||||
|
||||
functions->glBindTexture(GL_TEXTURE_2D, texture_id);
|
||||
functions->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
functions->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
functions->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
||||
functions->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
||||
functions->glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, tex.width(), tex.height(), 0, GL_RGBA, GL_UNSIGNED_BYTE, tex.bits());
|
||||
}
|
||||
texture->bind();
|
||||
_lock_data.unlock();
|
||||
|
||||
// Delegate poly rendering to subclass
|
||||
// Render tessellated mesh
|
||||
if (!_reset_needed)
|
||||
{
|
||||
_lock_data.lock();
|
||||
|
@ -243,15 +251,12 @@ void ExplorerChunkTerrain::render(OpenGLFunctions* functions)
|
|||
}
|
||||
|
||||
_lock_data.lock(); // TEMP
|
||||
int n = tessellated->getIndexCount();
|
||||
functions->glBegin(GL_TRIANGLES);
|
||||
for (int i = 0; i < n; i++)
|
||||
{
|
||||
TerrainVertex v = tessellated->getVertexByIndex(i);
|
||||
functions->glTexCoord2d(v.uv[0], v.uv[1]);
|
||||
functions->glVertex3d(v.location[0], v.location[1], v.location[2]);
|
||||
}
|
||||
functions->glEnd();
|
||||
// TEMP
|
||||
functions->glActiveTexture(GL_TEXTURE0 + 3);
|
||||
functions->glBindTexture(GL_TEXTURE_2D, texture_id);
|
||||
program->setUniformValue("groundTexture", 3);
|
||||
|
||||
tessellated->render(program, functions);
|
||||
_lock_data.unlock(); // TEMP
|
||||
}
|
||||
}
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
|
||||
#include <QMutex>
|
||||
class QImage;
|
||||
class QOpenGLTexture;
|
||||
class QOpenGLShaderProgram;
|
||||
|
||||
namespace paysages {
|
||||
namespace opengl {
|
||||
|
@ -25,7 +25,7 @@ public:
|
|||
|
||||
bool maintain();
|
||||
void updatePriority(CameraDefinition* camera);
|
||||
void render(OpenGLFunctions* functions);
|
||||
void render(QOpenGLShaderProgram* program, OpenGLFunctions* functions);
|
||||
|
||||
void askReset();
|
||||
void setMaxTextureSize(int size);
|
||||
|
@ -62,7 +62,7 @@ private:
|
|||
bool _reset_needed;
|
||||
|
||||
QImage* _texture;
|
||||
QOpenGLTexture* texture;
|
||||
unsigned int texture_id;
|
||||
bool _texture_changed;
|
||||
int _texture_current_size;
|
||||
int _texture_max_size;
|
||||
|
|
|
@ -46,7 +46,7 @@ void OpenGLShaderProgram::addFragmentSource(QString path)
|
|||
}
|
||||
else
|
||||
{
|
||||
logError("Can't open fragment file %s", file.fileName().toStdString().c_str());
|
||||
logError() << "Can't open fragment file " << file.fileName();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -22,15 +22,17 @@ public:
|
|||
void drawTriangles(float* vertices, int triangle_count);
|
||||
void drawTriangleStrip(float* vertices, int vertex_count);
|
||||
|
||||
protected:
|
||||
void bind();
|
||||
void release();
|
||||
|
||||
inline QOpenGLShaderProgram* getProgram() const {return program;}
|
||||
inline OpenGLRenderer* getRenderer() const {return renderer;}
|
||||
|
||||
protected:
|
||||
friend class OpenGLVariable;
|
||||
|
||||
private:
|
||||
void compile();
|
||||
void bind();
|
||||
void release();
|
||||
|
||||
bool compiled;
|
||||
|
||||
|
|
|
@ -80,33 +80,16 @@ void OpenGLTerrain::update()
|
|||
{
|
||||
}
|
||||
|
||||
// TEMP
|
||||
#include "GL/gl.h"
|
||||
#include "GL/glu.h"
|
||||
|
||||
void OpenGLTerrain::render()
|
||||
{
|
||||
CameraDefinition* camera = renderer->getScenery()->getCamera();
|
||||
program->bind();
|
||||
|
||||
glMatrixMode(GL_PROJECTION);
|
||||
glLoadIdentity();
|
||||
CameraPerspective perspective = camera->getPerspective();
|
||||
gluPerspective(perspective.yfov * 180.0 / M_PI, perspective.xratio, perspective.znear, perspective.zfar);
|
||||
|
||||
glMatrixMode(GL_MODELVIEW);
|
||||
glLoadIdentity();
|
||||
Vector3 camera_location = camera->getLocation();
|
||||
Vector3 camera_target = camera->getTarget();
|
||||
Vector3 camera_up = camera->getUpVector();
|
||||
gluLookAt(camera_location.x, camera_location.y, camera_location.z, camera_target.x, camera_target.y, camera_target.z, camera_up.x, camera_up.y, camera_up.z);
|
||||
|
||||
// Render chunks
|
||||
glEnable(GL_TEXTURE_2D);
|
||||
for (int i = 0; i < _chunks.count(); i++)
|
||||
{
|
||||
glColor3f(1.0, 1.0, 1.0);
|
||||
_chunks[i]->render(renderer->getOpenGlFunctions());
|
||||
_chunks[i]->render(program->getProgram(), renderer->getOpenGlFunctions());
|
||||
}
|
||||
|
||||
program->release();
|
||||
}
|
||||
|
||||
static bool _cmpChunks(const ExplorerChunkTerrain* c1, const ExplorerChunkTerrain* c2)
|
||||
|
|
|
@ -1 +0,0 @@
|
|||
#include "VertexArray.h"
|
|
@ -3,7 +3,9 @@
|
|||
|
||||
#include "opengl_global.h"
|
||||
|
||||
#include OPENGL_FUNCTIONS_INCLUDE
|
||||
#include <cassert>
|
||||
#include <QOpenGLShaderProgram>
|
||||
|
||||
namespace paysages {
|
||||
namespace opengl {
|
||||
|
@ -21,7 +23,7 @@ public:
|
|||
vertex_count = 1;
|
||||
vertices = new Vertex[1];
|
||||
index_count = 1;
|
||||
indices = new int[1];
|
||||
indices = new unsigned short[1];
|
||||
}
|
||||
|
||||
~VertexArray()
|
||||
|
@ -74,7 +76,7 @@ public:
|
|||
int cell_count = edge_vertex_count - 1;
|
||||
|
||||
index_count = (cell_count / stride) * (cell_count / stride) * 6;
|
||||
indices = new int[index_count];
|
||||
indices = new unsigned short[index_count];
|
||||
|
||||
int idx = 0;
|
||||
for (int y = 0; y < cell_count; y += stride)
|
||||
|
@ -99,7 +101,7 @@ public:
|
|||
return vertices[position];
|
||||
}
|
||||
|
||||
Vertex getVertexByIndex(int index)
|
||||
Vertex getVertexByIndex(unsigned short index)
|
||||
{
|
||||
assert(index >= 0 and index < index_count);
|
||||
|
||||
|
@ -111,13 +113,31 @@ public:
|
|||
return getVertex(y * edge_vertex_count + x);
|
||||
}
|
||||
|
||||
int getIndex(int position)
|
||||
unsigned short getIndex(int position)
|
||||
{
|
||||
assert(position >= 0 and position < index_count);
|
||||
|
||||
return indices[position];
|
||||
}
|
||||
|
||||
void render(QOpenGLShaderProgram* program, OpenGLFunctions* functions)
|
||||
{
|
||||
size_t ptr = (size_t)vertices;
|
||||
|
||||
GLuint vertex = program->attributeLocation("vertex");
|
||||
program->setAttributeArray(vertex, GL_FLOAT, (void*)(ptr + offsetof(Vertex, location)), 3, sizeof(Vertex));
|
||||
program->enableAttributeArray(vertex);
|
||||
|
||||
GLuint uv = program->attributeLocation("uv");
|
||||
program->setAttributeArray(uv, GL_FLOAT, (void*)(ptr + offsetof(Vertex, uv)), 2, sizeof(Vertex));
|
||||
program->enableAttributeArray(uv);
|
||||
|
||||
functions->glDrawElements(GL_TRIANGLES, index_count, GL_UNSIGNED_SHORT, indices);
|
||||
|
||||
program->disableAttributeArray(vertex);
|
||||
program->disableAttributeArray(uv);
|
||||
}
|
||||
|
||||
private:
|
||||
bool ready;
|
||||
bool changed;
|
||||
|
@ -126,7 +146,7 @@ private:
|
|||
Vertex* vertices;
|
||||
|
||||
int index_count;
|
||||
int* indices;
|
||||
unsigned short* indices;
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
@ -23,8 +23,7 @@ SOURCES += \
|
|||
OpenGLWater.cpp \
|
||||
OpenGLSharedState.cpp \
|
||||
OpenGLVariable.cpp \
|
||||
OpenGLTerrain.cpp \
|
||||
VertexArray.cpp
|
||||
OpenGLTerrain.cpp
|
||||
|
||||
HEADERS +=\
|
||||
opengl_global.h \
|
||||
|
@ -83,4 +82,6 @@ OTHER_FILES += \
|
|||
shaders/water.frag \
|
||||
shaders/bruneton.frag \
|
||||
shaders/bruneton.frag \
|
||||
shaders/tonemapping.frag
|
||||
shaders/tonemapping.frag \
|
||||
shaders/terrain.frag \
|
||||
shaders/terrain.vert
|
||||
|
|
|
@ -6,5 +6,7 @@
|
|||
<file>water.vert</file>
|
||||
<file>bruneton.frag</file>
|
||||
<file>tonemapping.frag</file>
|
||||
<file>terrain.frag</file>
|
||||
<file>terrain.vert</file>
|
||||
</qresource>
|
||||
</RCC>
|
||||
|
|
30
src/render/opengl/shaders/terrain.frag
Normal file
30
src/render/opengl/shaders/terrain.frag
Normal file
|
@ -0,0 +1,30 @@
|
|||
uniform sampler2D groundTexture;
|
||||
varying vec2 texcoord;
|
||||
|
||||
void main(void)
|
||||
{
|
||||
gl_FragColor = texture2D(groundTexture, texcoord);
|
||||
|
||||
float yoffset = GROUND_OFFSET - waterHeight;
|
||||
vec3 camera = vec3(cameraLocation.x, max(cameraLocation.y + yoffset, 0.0), cameraLocation.z);
|
||||
vec3 location = vec3(unprojected.x, max(unprojected.y + yoffset, 0.0), unprojected.z);
|
||||
vec3 x = vec3(0.0, Rg + camera.y * WORLD_SCALING, 0.0);
|
||||
vec3 v = normalize(location - camera);
|
||||
vec3 s = normalize(sunDirection * SUN_DISTANCE_SCALED - x);
|
||||
|
||||
if (v.y == 0.0)
|
||||
{
|
||||
v.y = -0.000001;
|
||||
}
|
||||
|
||||
float r = length(x);
|
||||
float mu = dot(x, v) / r;
|
||||
float t = length(location - camera) * WORLD_SCALING;
|
||||
|
||||
vec3 attenuation;
|
||||
vec3 inscattering = _getInscatterColor(x, t, v, s, r, mu, attenuation);
|
||||
|
||||
gl_FragColor = gl_FragColor * vec4(attenuation, 0.0) + vec4(inscattering, 0.0);
|
||||
|
||||
gl_FragColor = _toneMappingUncharted(gl_FragColor, 2.0);
|
||||
}
|
12
src/render/opengl/shaders/terrain.vert
Normal file
12
src/render/opengl/shaders/terrain.vert
Normal file
|
@ -0,0 +1,12 @@
|
|||
attribute highp vec4 vertex;
|
||||
attribute highp vec2 uv;
|
||||
uniform highp mat4 viewMatrix;
|
||||
varying vec3 unprojected;
|
||||
varying vec2 texcoord;
|
||||
|
||||
void main(void)
|
||||
{
|
||||
unprojected = vertex.xyz;
|
||||
texcoord = uv;
|
||||
gl_Position = viewMatrix * vertex;
|
||||
}
|
Loading…
Reference in a new issue