mirror of
https://github.com/rwengine/openrw.git
synced 2024-11-22 02:12:45 +01:00
Improve water rendering
This commit is contained in:
parent
65b5c84b92
commit
77aa71df7e
@ -352,8 +352,8 @@ void GameData::loadWaterpro(const std::string& path)
|
||||
ifstr.read(reinterpret_cast<char*>(&waterHeights), sizeof(float)*48);
|
||||
|
||||
ifstr.seekg(0x03C4);
|
||||
ifstr.read(reinterpret_cast<char*>(&visibleWater), sizeof(float)*64*64);
|
||||
ifstr.read(reinterpret_cast<char*>(&realWater), sizeof(float)*128*128);
|
||||
ifstr.read(reinterpret_cast<char*>(&visibleWater), sizeof(char)*64*64);
|
||||
ifstr.read(reinterpret_cast<char*>(&realWater), sizeof(char)*128*128);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -110,7 +110,7 @@ uniform float size;
|
||||
uniform mat4 MVP;
|
||||
void main()
|
||||
{
|
||||
TexCoords = position;
|
||||
TexCoords = position * 2.0;
|
||||
gl_Position = MVP * vec4(position * size, height, 1.0);
|
||||
})";
|
||||
|
||||
@ -435,26 +435,66 @@ void GameRenderer::renderWorld(float alpha)
|
||||
glBindVertexArray( waterDraw.getVAOName() );
|
||||
glUseProgram( waterProgram );
|
||||
|
||||
// TODO: label all the variables!
|
||||
// TODO: Add some kind of draw distance
|
||||
#define NO_WATER_INDEX 48
|
||||
#define WATER_LQ_DATA_SIZE 64
|
||||
#define WATER_HQ_DATA_SIZE 128
|
||||
#define WATER_WORLD_SIZE 4096.f
|
||||
#define WATER_HQ_DISTANCE 128.f
|
||||
|
||||
float blockLQSize = WATER_WORLD_SIZE/WATER_LQ_DATA_SIZE;
|
||||
float blockHQSize = WATER_WORLD_SIZE/WATER_HQ_DATA_SIZE;
|
||||
|
||||
glm::vec2 waterOffset { -WATER_WORLD_SIZE/2.f, -WATER_WORLD_SIZE/2.f };
|
||||
glm::mat4 waterModel;
|
||||
glUniform1i(waterTexture, 0);
|
||||
float blockSize = 4096.f/64.f;
|
||||
auto waterTex = engine->gameData.textures["water_old"];
|
||||
glActiveTexture(GL_TEXTURE0);
|
||||
glBindTexture(GL_TEXTURE_2D, waterTex.texName);
|
||||
|
||||
// TODO: high / low quality water. Projected grid?
|
||||
auto camposFlat = glm::vec2(camera.worldPos);
|
||||
|
||||
for( int x = 0; x < 64; x++ ) {
|
||||
for( int y = 0; y < 64; y++ ) {
|
||||
int i = (x*64) + y;
|
||||
// Draw High detail water
|
||||
glUniform1f(waterSize, blockHQSize);
|
||||
for( int x = 0; x < WATER_HQ_DATA_SIZE; x++ ) {
|
||||
for( int y = 0; y < WATER_HQ_DATA_SIZE; y++ ) {
|
||||
auto waterWS = waterOffset + glm::vec2(blockHQSize) * glm::vec2(x, y);
|
||||
auto cullWS = waterWS + (blockHQSize / 2.f);
|
||||
|
||||
// Check that this is the right time to draw the HQ water
|
||||
if( glm::distance(camposFlat, cullWS) - blockHQSize >= WATER_HQ_DISTANCE ) continue;
|
||||
|
||||
waterModel = glm::mat4();
|
||||
waterModel = glm::translate(waterModel, glm::vec3(waterWS, 0.f));
|
||||
int i = (x*WATER_HQ_DATA_SIZE) + y;
|
||||
int hI = engine->gameData.realWater[i];
|
||||
if( hI >= NO_WATER_INDEX ) continue;
|
||||
float h = engine->gameData.waterHeights[hI];
|
||||
|
||||
glUniform1f(waterHeight, h);
|
||||
auto MVP = proj * view * waterModel;
|
||||
glUniformMatrix4fv(waterMVP, 1, GL_FALSE, glm::value_ptr(MVP));
|
||||
glDrawArrays(waterDraw.getFaceType(), 0, 4);
|
||||
}
|
||||
}
|
||||
|
||||
glUniform1f(waterSize, blockLQSize);
|
||||
for( int x = 0; x < WATER_LQ_DATA_SIZE; x++ ) {
|
||||
for( int y = 0; y < WATER_LQ_DATA_SIZE; y++ ) {
|
||||
auto waterWS = waterOffset + glm::vec2(blockLQSize) * glm::vec2(x, y);
|
||||
auto cullWS = waterWS + (blockLQSize / 2.f);
|
||||
|
||||
// Check that this is the right time to draw the LQ
|
||||
if( glm::distance(camposFlat, cullWS) - blockHQSize/4.f < WATER_HQ_DISTANCE ) continue;
|
||||
if( glm::distance(camposFlat, cullWS) - blockLQSize/2.f > camera.frustum.far ) continue;
|
||||
|
||||
waterModel = glm::mat4();
|
||||
waterModel = glm::translate(waterModel, glm::vec3(waterWS, 0.f));
|
||||
int i = (x*WATER_LQ_DATA_SIZE) + y;
|
||||
int hI = engine->gameData.visibleWater[i];
|
||||
if( hI >= NO_WATER_INDEX ) continue;
|
||||
float h = engine->gameData.waterHeights[hI];
|
||||
waterModel = glm::mat4();
|
||||
waterModel = glm::translate(waterModel, {-2048.f + x * blockSize, -2048.f + y * blockSize, 0.f});
|
||||
glUniform1f(waterSize, blockSize);
|
||||
|
||||
glUniform1f(waterHeight, h);
|
||||
auto MVP = proj * view * waterModel;
|
||||
glUniformMatrix4fv(waterMVP, 1, GL_FALSE, glm::value_ptr(MVP));
|
||||
|
@ -67,7 +67,7 @@ void ViewerWidget::paintGL()
|
||||
|
||||
auto& r = gworld->renderer;
|
||||
|
||||
r.camera.frustum.far = 100.f;
|
||||
r.camera.frustum.far = 500.f;
|
||||
r.camera.frustum.near = 0.1f;
|
||||
r.camera.frustum.fov = 90.f;
|
||||
r.camera.frustum.aspectRatio = width()/(height()*1.f);
|
||||
|
Loading…
Reference in New Issue
Block a user