46 for (
unsigned i = 0; i < 6; i++)
47 if (
vec_dot(center, frustum[i]) < -radius)
57 throw runtime_error(
"Failed to compile shader.");
60 GL_CHECK(glGenVertexArrays(1, &vao));
65 Mesh::Mesh(
const char *vs_shader,
const char *tc_shader,
const char *te_shader,
66 const char *geom_shader,
const char *fs_shader)
69 geom_shader, fs_shader);
72 throw runtime_error(
"Failed to compile shader.");
75 GL_CHECK(glGenVertexArrays(1, &vao));
89 GL_CHECK(glDeleteVertexArrays(1, &vao));
106 const GLushort restart_index = 0xffff;
109 int strips = height - 1;
115 for (
int z = 0; z < strips; z++)
118 int step_odd = 1 - step_even;
119 int pos = z * stride + vertex_buffer_offset;
121 for (
int x = 0;
x < 2 * width - 1;
x++)
124 pos += (
x & 1) ? step_odd : step_even;
130 ibo.push_back(restart_index);
136 GL_CHECK(glActiveTexture(GL_TEXTURE0 + 0));
138 GL_CHECK(glActiveTexture(GL_TEXTURE0 + 1));
140 GL_CHECK(glActiveTexture(GL_TEXTURE0 + 2));
142 GL_CHECK(glActiveTexture(GL_TEXTURE0 + 3));
147 :
Mesh(
"water.vs",
"water.fs")
155 return clamp(level, 0.0
f, max_lod);
175 vec2 newpos = scale * (patch.pos + block_offset) + half_block;
176 vec3 dist = cam_pos -
vec3(newpos.
x, 0.0f, newpos.
y);
179 BoundingSphere bs(vec3(newpos.
x, 0.0f, newpos.
y), vec3(10.0
f + half_block.
x, 20.0f, 10.0f + half_block.
y));
183 for (
unsigned z = 0; z <
blocks_z; z++)
187 float lod = patches[z * blocks_x +
x].lod;
193 GL_CHECK(glBindBuffer(GL_PIXEL_UNPACK_BUFFER,
pbo));
199 return clamp(GLubyte(round(v * 32.0
f)), GLubyte(0), GLubyte(255));
202 GL_CHECK(glUnmapBuffer(GL_PIXEL_UNPACK_BUFFER));
205 GL_CHECK(glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0,
206 blocks_x, blocks_z, GL_RED, GL_UNSIGNED_BYTE,
nullptr));
208 GL_CHECK(glBindTexture(GL_TEXTURE_2D, 0));
209 GL_CHECK(glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0));
212 lod.full.instances = 0;
215 GL_CHECK(
PatchData *ubo_data = static_cast<PatchData*>(glMapBufferRange(GL_UNIFORM_BUFFER,
221 LOGE(
"Failed to map buffer!");
226 for (
unsigned z = 0; z <
blocks_z; z++)
230 if (!patches[z * blocks_x +
x].visible)
234 unsigned px =
x ? (
x - 1) : 0;
235 unsigned pz = z ? (z - 1) : 0;
236 unsigned nx =
min(
x + 1, blocks_x - 1);
237 unsigned nz =
min(z + 1, blocks_z - 1);
247 float left_lod =
max(left, center);
248 float top_lod =
max(top, center);
249 float right_lod =
max(right, center);
250 float bottom_lod =
max(bottom, center);
251 int center_lod =
int(center);
253 auto &lod = lod_meshes[center_lod];
255 unsigned ubo_offset = center_lod * blocks_x *
blocks_z;
257 ubo_data[ubo_offset + lod.full.instances].Offsets =
vec4(
258 patches[z * blocks_x +
x].pos + block_offset,
259 patches[z * blocks_x +
x].pos);
260 ubo_data[ubo_offset + lod.full.instances].LODs =
vec4(left_lod, top_lod, right_lod, bottom_lod);
261 ubo_data[ubo_offset + lod.full.instances].InnerLOD =
vec4(center);
263 lod.full.instances++;
267 GL_CHECK(glUnmapBuffer(GL_UNIFORM_BUFFER));
277 GL_CHECK(glDrawElementsInstanced(GL_TRIANGLE_STRIP,
elems, GL_UNSIGNED_SHORT,
278 reinterpret_cast<const GLvoid*>(uintptr_t(
offset *
sizeof(GLushort))),
305 GL_CHECK(glActiveTexture(GL_TEXTURE0 + 4));
308 GL_CHECK(glEnable(GL_PRIMITIVE_RESTART_FIXED_INDEX));
309 for (
unsigned i = 0; i <
lods; i++)
311 GL_CHECK(glDisable(GL_PRIMITIVE_RESTART_FIXED_INDEX));
314 GL_CHECK(glBindBufferBase(GL_UNIFORM_BUFFER, 0, 0));
320 int size_1 = size + 1;
327 for (
int y = 0;
y < size_1;
y++)
328 for (
int x = 0;
x < size_1;
x++)
347 memset(
v.lod_weight, 0,
sizeof(
v.lod_weight));
365 for (
unsigned z = 0; z <
blocks_z; z++)
375 GL_CHECK(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR));
376 GL_CHECK(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR));
377 GL_CHECK(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE));
378 GL_CHECK(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE));
379 GL_CHECK(glBindTexture(GL_TEXTURE_2D, 0));
394 for (
unsigned i = 0; i <
lods; i++)
407 GL_CHECK(glBindBuffer(GL_UNIFORM_BUFFER, 0));
411 GL_CHECK(glBindBuffer(GL_PIXEL_UNPACK_BUFFER,
pbo));
413 GL_CHECK(glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0));
420 GL_CHECK(glEnableVertexAttribArray(0));
421 GL_CHECK(glEnableVertexAttribArray(1));
423 GL_CHECK(glVertexAttribIPointer(0, 4, GL_UNSIGNED_BYTE,
sizeof(
Vertex), 0));
424 GL_CHECK(glVertexAttribPointer(1, 4, GL_UNSIGNED_BYTE, GL_FALSE,
sizeof(
Vertex), reinterpret_cast<const GLvoid*>(uintptr_t(4))));
426 GL_CHECK(glBindBuffer(GL_ELEMENT_ARRAY_BUFFER,
ibo));
427 GL_CHECK(glBufferData(GL_ELEMENT_ARRAY_BUFFER,
indices.size() *
sizeof(GLushort),
indices.data(), GL_STATIC_DRAW));
430 GL_CHECK(glBindBuffer(GL_ARRAY_BUFFER, 0));
431 GL_CHECK(glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0));
435 :
Mesh(
"water_tess.vs",
"water_tess.tesc",
"water_tess.tese", nullptr,
"water.fs")
447 for (
unsigned z = 0; z <
blocks_z; z++)
451 verts[z * blocks_x +
x].x =
x;
452 verts[z * blocks_x +
x].y = z;
467 GL_CHECK(glBufferData(GL_ARRAY_BUFFER, verts.size() *
sizeof(
ubvec2), verts.data(), GL_STATIC_DRAW));
468 GL_CHECK(glEnableVertexAttribArray(0));
469 GL_CHECK(glVertexAttribIPointer(0, 2, GL_UNSIGNED_BYTE, 0, 0));
472 GL_CHECK(glBindBuffer(GL_ARRAY_BUFFER, 0));
void draw(GLuint ubo, unsigned ubo_offset)
static constexpr float patch_size
GLuint height_displacement
GLboolean GLboolean GLboolean GLboolean a
std::vector< Patch > patches
float vec_dot(const T &a, const T &b)
GLint GLsizei GLsizei height
float min(float x, float y)
std::vector< float > lod_buffer
GLenum GLuint GLintptr offset
float clamp(float x, float min, float max)
GLuint common_compile_shader_from_file(const char *vs_source, const char *fs_source)
static constexpr unsigned max_instances
const T::data_type * value_ptr(const T &vec)
std::vector< Vertex > vertices
static constexpr unsigned blocks_x
static void generate_block_indices(vector< GLushort > &ibo, int vertex_buffer_offset, int width, int height, int stride)
bool test_frustum(const vec4 *frustum) const
#define GL_PATCH_VERTICES_EXT
static constexpr float lod0_distance
void build_lod(unsigned lod)
void calculate_lods(const RenderInfo &info)
float vec_length(const T &vec)
void bind_textures(const RenderInfo &info)
GLsizei GLenum const void * indices
void render(const RenderInfo &info) override
static constexpr unsigned blocks_z
static constexpr unsigned patch_size
static constexpr float lod0_distance
static constexpr unsigned blocks_x
float max(float x, float y)
static constexpr unsigned lods
detail::ivec2< uint8_t > ubvec2
GLenum GLuint GLintptr GLsizeiptr size
GLint GLint GLint GLint GLint x
GLenum GLuint GLint level
const void GLsizei GLsizei stride
static constexpr unsigned blocks_z
GLboolean GLboolean GLboolean b
std::vector< LOD > lod_meshes
Mesh(const char *vs_shader, const char *fs_shader)
T vec_round(const T &vec)
typedef GLuint(GL_APIENTRYP PFNGLGETDEBUGMESSAGELOGKHRPROC)(GLuint count
detail::ivec2< int32_t > ivec2
void render(const RenderInfo &info) override
static float lod_factor(float max_lod, float distance_mod, vec3 dist)