Skip to content

Commit

Permalink
Added tutorial 55
Browse files Browse the repository at this point in the history
  • Loading branch information
emeiri committed Oct 22, 2024
1 parent 8c0a163 commit cf8800f
Show file tree
Hide file tree
Showing 14 changed files with 884 additions and 75 deletions.
111 changes: 111 additions & 0 deletions Common/Shaders/infinite_grid.fs
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
/*
Copyright 2024 Etay Meiri
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 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/

#version 330

in vec3 WorldPos;

layout(location = 0) out vec4 FragColor;

uniform vec3 gCameraWorldPos;
uniform float gGridSize = 100.0;
uniform float gGridMinPixelsBetweenCells = 2.0;
uniform float gGridCellSize = 0.025;
uniform vec4 gGridColorThin = vec4(0.5, 0.5, 0.5, 1.0);
uniform vec4 gGridColorThick = vec4(0.0, 0.0, 0.0, 1.0);


float log10(float x)
{
float f = log(x) / log(10.0);
return f;
}


float satf(float x)
{
float f = clamp(x, 0.0, 1.0);
return f;
}


vec2 satv(vec2 x)
{
vec2 v = clamp(x, vec2(0.0), vec2(1.0));
return v;
}


float max2(vec2 v)
{
float f = max(v.x, v.y);
return f;
}


void main()
{
vec2 dvx = vec2(dFdx(WorldPos.x), dFdy(WorldPos.x));
vec2 dvy = vec2(dFdx(WorldPos.z), dFdy(WorldPos.z));

float lx = length(dvx);
float ly = length(dvy);

vec2 dudv = vec2(lx, ly);

float l = length(dudv);

float LOD = max(0.0, log10(l * gGridMinPixelsBetweenCells / gGridCellSize) + 1.0);

float GridCellSizeLod0 = gGridCellSize * pow(10.0, floor(LOD));
float GridCellSizeLod1 = GridCellSizeLod0 * 10.0;
float GridCellSizeLod2 = GridCellSizeLod1 * 10.0;

dudv *= 4.0;

vec2 mod_div_dudv = mod(WorldPos.xz, GridCellSizeLod0) / dudv;
float Lod0a = max2(vec2(1.0) - abs(satv(mod_div_dudv) * 2.0 - vec2(1.0)) );

mod_div_dudv = mod(WorldPos.xz, GridCellSizeLod1) / dudv;
float Lod1a = max2(vec2(1.0) - abs(satv(mod_div_dudv) * 2.0 - vec2(1.0)) );

mod_div_dudv = mod(WorldPos.xz, GridCellSizeLod2) / dudv;
float Lod2a = max2(vec2(1.0) - abs(satv(mod_div_dudv) * 2.0 - vec2(1.0)) );

float LOD_fade = fract(LOD);
vec4 Color;

if (Lod2a > 0.0) {
Color = gGridColorThick;
Color.a *= Lod2a;
} else {
if (Lod1a > 0.0) {
Color = mix(gGridColorThick, gGridColorThin, LOD_fade);
Color.a *= Lod1a;
} else {
Color = gGridColorThin;
Color.a *= (Lod0a * (1.0 - LOD_fade));
}
}

float OpacityFalloff = (1.0 - satf(length(WorldPos.xz - gCameraWorldPos.xz) / gGridSize));

Color.a *= OpacityFalloff;

FragColor = Color;
}
50 changes: 50 additions & 0 deletions Common/Shaders/infinite_grid.vs
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
/*
Copyright 2024 Etay Meiri
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 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/

#version 330

out vec3 WorldPos;

uniform mat4 gVP = mat4(1.0);
uniform float gGridSize = 100.0;
uniform vec3 gCameraWorldPos;

const vec3 Pos[4] = vec3[4](
vec3(-1.0, 0.0, -1.0), // bottom left
vec3( 1.0, 0.0, -1.0), // bottom right
vec3( 1.0, 0.0, 1.0), // top right
vec3(-1.0, 0.0, 1.0) // top left
);

const int Indices[6] = int[6](0, 2, 1, 2, 0, 3);


void main()
{
int Index = Indices[gl_VertexID];
vec3 vPos3 = Pos[Index] * gGridSize;

vPos3.x += gCameraWorldPos.x;
vPos3.z += gCameraWorldPos.z;

vec4 vPos4 = vec4(vPos3, 1.0);

gl_Position = gVP * vPos4;

WorldPos = vPos3;
}
55 changes: 55 additions & 0 deletions Common/ogldev_infinite_grid.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
/*
Copyright 2024 Etay Meiri
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 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/


#include "ogldev_infinite_grid.h"


InfiniteGrid::InfiniteGrid()
{

}


void InfiniteGrid::Init()
{
if (!m_infiniteGridTech.Init()) {
printf("Error initializing the infinite grid technique\n");
exit(1);
}
}


void InfiniteGrid::Render(const InfiniteGridConfig& Config, const Matrix4f& VP, const Vector3f& CameraPos)
{
GLint CurProg = 0;
glGetIntegerv(GL_CURRENT_PROGRAM, &CurProg);

m_infiniteGridTech.Enable();

m_infiniteGridTech.SetVP(VP);
m_infiniteGridTech.SetCameraWorldPos(CameraPos);
m_infiniteGridTech.SetCellSize(Config.CellSize);

glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glDrawArraysInstancedBaseInstance(GL_TRIANGLES, 0, 6, 1, 0);
glDisable(GL_BLEND);

glUseProgram(CurProg);
}
72 changes: 72 additions & 0 deletions Common/ogldev_infinite_grid_technique.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
/*
Copyright 2023 Etay Meiri
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 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/


#include "ogldev_infinite_grid_technique.h"


bool InfiniteGridTechnique::Init()
{
if (!Technique::Init()) {
return false;
}

if (!AddShader(GL_VERTEX_SHADER, "../Common/Shaders/infinite_grid.vs")) {
return false;
}

if (!AddShader(GL_FRAGMENT_SHADER, "../Common/Shaders/infinite_grid.fs")) {
return false;
}

if (!Finalize()) {
return false;
}

return InitCommon();
}


bool InfiniteGridTechnique::InitCommon()
{
GET_UNIFORM_AND_CHECK(VPLoc, "gVP");
GET_UNIFORM_AND_CHECK(CameraWorldPosLoc, "gCameraWorldPos");
GET_UNIFORM_AND_CHECK(GridCellSizeLoc, "gGridCellSize");

return true;
}


void InfiniteGridTechnique::SetVP(const Matrix4f& VP)
{
glUniformMatrix4fv(VPLoc, 1, GL_TRUE, (const GLfloat*)VP.m);
}


void InfiniteGridTechnique::SetCameraWorldPos(const Vector3f& CameraWorldPos)
{
glUniform3f(CameraWorldPosLoc, CameraWorldPos.x, CameraWorldPos.y, CameraWorldPos.z);
}


void InfiniteGridTechnique::SetCellSize(float CellSize)
{
glUniform1f(GridCellSizeLoc, CellSize);
}


46 changes: 46 additions & 0 deletions Include/ogldev_infinite_grid.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
/*
Copyright 2024 Etay Meiri
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 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/


#pragma once


#include "ogldev_infinite_grid_technique.h"

struct InfiniteGridConfig {
float Size = 100.0f;
float CellSize = 0.025f;
Vector4f ColorThin = Vector4f(0.5f, 0.5f, 0.5f, 1.0f);
Vector4f ColorThick = Vector4f(0.0f, 0.0f, 0.0f, 1.0f);
float MinPixelsBetweenCells = 2.0f;
};


class InfiniteGrid
{
public:
InfiniteGrid();

void Init();

void Render(const InfiniteGridConfig& Config, const Matrix4f& VP, const Vector3f& CameraPos);

private:

InfiniteGridTechnique m_infiniteGridTech;
};
44 changes: 44 additions & 0 deletions Include/ogldev_infinite_grid_technique.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
/*
Copyright 2024 Etay Meiri
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 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/

#pragma once

#include "ogldev_math_3d.h"
#include "ogldev_util.h"
#include "technique.h"


class InfiniteGridTechnique : public Technique
{
public:
InfiniteGridTechnique() {}

virtual bool Init();

void SetVP(const Matrix4f& VP);
void SetCameraWorldPos(const Vector3f& CameraWorldPos);
void SetCellSize(float CellSize);

private:
bool InitCommon();

GLuint VPLoc = INVALID_UNIFORM_LOCATION;
GLuint CameraWorldPosLoc = INVALID_UNIFORM_LOCATION;
GLuint GridCellSizeLoc = INVALID_UNIFORM_LOCATION;
};

Loading

0 comments on commit cf8800f

Please sign in to comment.