1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126
|
/* This file is part of the Spring engine (GPL v2 or later), see LICENSE.html */
#ifndef BUMP_WATER_H
#define BUMP_WATER_H
#include "Rendering/GL/FBO.h"
#include "Rendering/GL/myGL.h"
#include "IWater.h"
#include "System/EventClient.h"
#include "System/Misc/RectangleOptimizer.h"
namespace Shader {
struct IProgramObject;
}
class CBumpWater : public IWater, public CEventClient
{
public:
//! CEventClient interface
bool WantsEvent(const std::string& eventName) {
return shoreWaves && (eventName == "UnsyncedHeightMapUpdate");
}
bool GetFullRead() const { return true; }
int GetReadAllyTeam() const { return AllAccessTeam; }
public:
CBumpWater();
virtual ~CBumpWater();
void Update();
void UpdateWater(CGame* game);
void OcclusionQuery();
void DrawReflection(CGame* game);
void DrawRefraction(CGame* game);
void Draw();
int GetID() const { return WATER_RENDERER_BUMPMAPPED; }
const char* GetName() const { return "bumpmapped"; }
private:
void SetUniforms(); ///< @see #useUniforms
void SetupUniforms( std::string& definitions );
void GetUniformLocations(const Shader::IProgramObject*);
private:
//! coastmap (needed for shorewaves)
struct CoastAtlasRect {
CoastAtlasRect(const SRectangle& rect);
bool isCoastline; ///< if false, then the whole rect is either above water or below water (no coastline -> no need to calc/render distfield)
int ix1, iy1;
int ix2, iy2;
int xsize, ysize;
float x1, y1;
float x2, y2;
float tx1, ty1;
float tx2, ty2;
};
std::vector<CoastAtlasRect> coastmapAtlasRects;
CRectangleOptimizer heightmapUpdates;
void UploadCoastline(const bool forceFull = false);
void UpdateCoastmap();
void UpdateDynWaves(const bool initialize = false);
int atlasX,atlasY;
void UnsyncedHeightMapUpdate(const SRectangle& rect);
private:
//! user options
char reflection; ///< 0:=off, 1:=don't render the terrain, 2:=render everything+terrain
char refraction; ///< 0:=off, 1:=screencopy, 2:=own rendering cycle
int reflTexSize;
bool depthCopy; ///< uses a screen depth copy, which allows a nicer interpolation between deep sea and shallow water
float anisotropy;
char depthBits; ///< depthBits for reflection/refraction RBO
bool blurRefl;
bool shoreWaves;
bool endlessOcean; ///< render the water around the whole map
bool dynWaves; ///< only usable if bumpmap/normal texture is a TileSet
bool useUniforms; ///< use Uniforms instead of \#define'd const. Warning: this is much slower, but has the advantage that you can change the params on runtime.
unsigned char* tileOffsets; ///< used to randomize the wave/bumpmap/normal texture
int normalTextureX; ///< needed for dynamic waves
int normalTextureY;
GLuint target; ///< for screen copies (color/depth), can be GL_TEXTURE_RECTANGLE (nvidia) or GL_TEXTURE_2D (others)
int screenTextureX;
int screenTextureY;
FBO reflectFBO;
FBO refractFBO;
FBO coastFBO;
FBO dynWavesFBO;
GLuint displayList;
GLuint refractTexture;
GLuint reflectTexture;
GLuint depthTexture; ///< screen depth copy
GLuint waveRandTexture;
GLuint foamTexture;
GLuint normalTexture; ///< final used
GLuint normalTexture2; ///< updates normalTexture with dynamic waves turned on
GLuint coastTexture;
GLuint coastUpdateTexture;
std::vector<GLuint> caustTextures;
Shader::IProgramObject* waterShader;
Shader::IProgramObject* blurShader;
GLuint uniforms[20]; ///< see useUniforms
bool wasLastFrameVisible;
GLuint occlusionQuery;
GLuint occlusionQueryResult;
float3 windVec;
float3 windndir;
float windStrength;
};
#endif // BUMP_WATER_H
|