Compare commits
No commits in common. "main" and "feature/texture-import" have entirely different histories.
main
...
feature/te
|
@ -7,7 +7,6 @@ stages:
|
||||||
|
|
||||||
variables:
|
variables:
|
||||||
VCPKG_ROOT: "/vcpkg"
|
VCPKG_ROOT: "/vcpkg"
|
||||||
CMAKE_BUILD_TYPE: "Release"
|
|
||||||
|
|
||||||
build:
|
build:
|
||||||
stage: build
|
stage: build
|
||||||
|
|
11
CHANGELOG.md
11
CHANGELOG.md
|
@ -1,11 +0,0 @@
|
||||||
## [v0.0.2] - 2024-08-25
|
|
||||||
### Changed
|
|
||||||
- Refactored uniform handling in the initial geometry pass to improve maintainability.
|
|
||||||
|
|
||||||
## [v0.0.3] - 2024-08-28
|
|
||||||
### Changed
|
|
||||||
- Correctly manage window resizing for camera aspect ratio
|
|
||||||
|
|
||||||
## [v0.0.4] - 2024-08-28
|
|
||||||
### Changed
|
|
||||||
- Added dynamic tessellation determined by the slope of the terrain
|
|
|
@ -1,15 +1,9 @@
|
||||||
cmake_minimum_required(VERSION 3.10)
|
cmake_minimum_required(VERSION 3.10)
|
||||||
project(TerraVisor VERSION 0.0.4)
|
project(TerraVisor)
|
||||||
|
|
||||||
set(CMAKE_CXX_STANDARD 17)
|
set(CMAKE_CXX_STANDARD 17)
|
||||||
set(CMAKE_CXX_STANDARD_REQUIRED ON)
|
set(CMAKE_CXX_STANDARD_REQUIRED ON)
|
||||||
|
|
||||||
configure_file(
|
|
||||||
"${PROJECT_SOURCE_DIR}/include/config.h.in"
|
|
||||||
"${PROJECT_BINARY_DIR}/config.h"
|
|
||||||
)
|
|
||||||
include_directories("${PROJECT_BINARY_DIR}")
|
|
||||||
|
|
||||||
# Find packages using vcpkg
|
# Find packages using vcpkg
|
||||||
find_package(GLEW CONFIG REQUIRED)
|
find_package(GLEW CONFIG REQUIRED)
|
||||||
find_package(glfw3 CONFIG REQUIRED)
|
find_package(glfw3 CONFIG REQUIRED)
|
||||||
|
|
3
COPYING
3
COPYING
|
@ -677,5 +677,4 @@ Public License instead of this License. But first, please read
|
||||||
|
|
||||||
This project also includes third-party software with different licenses:
|
This project also includes third-party software with different licenses:
|
||||||
|
|
||||||
The FreeImage open source image library. See http://freeimage.sourceforge.net for details.
|
- FreeImage is licensed under the FreeImage Public License (FIPL). See `licenses/LICENSE-FreeImage.txt` for details.
|
||||||
FreeImage is used under the (GNU GPL or FIPL), version (license version).
|
|
|
@ -0,0 +1,2 @@
|
||||||
|
This project is licensed under the GNU General Public License v3.0.
|
||||||
|
See the COPYING file for more details.
|
|
@ -79,7 +79,7 @@ GLEW - OpenGL Extension Wrangler Library \
|
||||||
GLFW - OpenGL Framework \
|
GLFW - OpenGL Framework \
|
||||||
GLM - OpenGL Mathematics \
|
GLM - OpenGL Mathematics \
|
||||||
ASSIMP - Open Asset Import Library \
|
ASSIMP - Open Asset Import Library \
|
||||||
FreeImage - Open Source Image Library \
|
FreeImage - Graphics Import Library \
|
||||||
Dear ImGui - GUI framework
|
Dear ImGui - GUI framework
|
||||||
|
|
||||||
## Contact
|
## Contact
|
||||||
|
|
30
imgui.ini
30
imgui.ini
|
@ -4,8 +4,8 @@ Size=400,400
|
||||||
Collapsed=0
|
Collapsed=0
|
||||||
|
|
||||||
[Window][Terrain Controls]
|
[Window][Terrain Controls]
|
||||||
Pos=861,19
|
Pos=925,19
|
||||||
Size=419,701
|
Size=403,701
|
||||||
Collapsed=0
|
Collapsed=0
|
||||||
DockId=0x00000002,0
|
DockId=0x00000002,0
|
||||||
|
|
||||||
|
@ -19,31 +19,17 @@ Collapsed=0
|
||||||
|
|
||||||
[Window][TerraVisor]
|
[Window][TerraVisor]
|
||||||
Pos=0,0
|
Pos=0,0
|
||||||
Size=2880,1676
|
Size=1328,720
|
||||||
Collapsed=0
|
Collapsed=0
|
||||||
|
|
||||||
[Window][Scene Window]
|
[Window][Scene Window]
|
||||||
Pos=0,19
|
Pos=0,19
|
||||||
Size=859,701
|
Size=923,701
|
||||||
Collapsed=0
|
Collapsed=0
|
||||||
DockId=0x00000003,0
|
DockId=0x00000001,0
|
||||||
|
|
||||||
[Window][Viewport]
|
|
||||||
Pos=0,34
|
|
||||||
Size=2178,1641
|
|
||||||
Collapsed=0
|
|
||||||
DockId=0x00000003,0
|
|
||||||
|
|
||||||
[Window][Scene Settings]
|
|
||||||
Pos=2181,34
|
|
||||||
Size=699,1641
|
|
||||||
Collapsed=0
|
|
||||||
DockId=0x00000004,0
|
|
||||||
|
|
||||||
[Docking][Data]
|
[Docking][Data]
|
||||||
DockSpace ID=0x6F42A598 Window=0xE80F322C Pos=0,34 Size=2880,1641 Split=X Selected=0x9F2D9299
|
DockSpace ID=0x6F42A598 Window=0xE80F322C Pos=0,19 Size=1328,701 Split=X Selected=0x9F2D9299
|
||||||
DockNode ID=0x00000001 Parent=0x6F42A598 SizeRef=0,0 Split=X Selected=0x13926F0B
|
DockNode ID=0x00000001 Parent=0x6F42A598 SizeRef=875,701 CentralNode=1 Selected=0x9F2D9299
|
||||||
DockNode ID=0x00000003 Parent=0x00000001 SizeRef=578,701 CentralNode=1 Selected=0x13926F0B
|
DockNode ID=0x00000002 Parent=0x6F42A598 SizeRef=403,701 Selected=0xF69494A7
|
||||||
DockNode ID=0x00000004 Parent=0x00000001 SizeRef=699,701 Selected=0x413E6147
|
|
||||||
DockNode ID=0x00000002 Parent=0x6F42A598 SizeRef=419,701 Selected=0xF69494A7
|
|
||||||
|
|
||||||
|
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
@ -2,7 +2,6 @@
|
||||||
|
|
||||||
#include <GL/glew.h>
|
#include <GL/glew.h>
|
||||||
#include <glm/glm.hpp>
|
#include <glm/glm.hpp>
|
||||||
#include <string>
|
|
||||||
|
|
||||||
namespace Uniforms
|
namespace Uniforms
|
||||||
{
|
{
|
||||||
|
@ -16,17 +15,6 @@ namespace Uniforms
|
||||||
glm::vec4 eye_w = glm::vec4(0.0f, 0.0f, 3.0f, 1.0f); //world-space eye position
|
glm::vec4 eye_w = glm::vec4(0.0f, 0.0f, 3.0f, 1.0f); //world-space eye position
|
||||||
};
|
};
|
||||||
|
|
||||||
struct GeoUniforms
|
|
||||||
{
|
|
||||||
glm::mat4 PV;
|
|
||||||
glm::mat4 M;
|
|
||||||
|
|
||||||
float minTessellation = 1.0f;
|
|
||||||
float maxTessellation = 32.0f;
|
|
||||||
float displacementScale = 0.007f;
|
|
||||||
int gridDensity = 16;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct LightUniforms
|
struct LightUniforms
|
||||||
{
|
{
|
||||||
glm::vec4 La = glm::vec4(0.5f, 0.5f, 0.55f, 1.0f); //ambient light color
|
glm::vec4 La = glm::vec4(0.5f, 0.5f, 0.55f, 1.0f); //ambient light color
|
||||||
|
@ -46,13 +34,11 @@ namespace Uniforms
|
||||||
extern SceneUniforms SceneData;
|
extern SceneUniforms SceneData;
|
||||||
extern LightUniforms LightData;
|
extern LightUniforms LightData;
|
||||||
extern MaterialUniforms MaterialData;
|
extern MaterialUniforms MaterialData;
|
||||||
extern GeoUniforms GeoData;
|
|
||||||
|
|
||||||
//IDs for the buffer objects holding the uniform block data
|
//IDs for the buffer objects holding the uniform block data
|
||||||
extern GLuint sceneUbo;
|
extern GLuint scene_ubo;
|
||||||
extern GLuint lightUbo;
|
extern GLuint light_ubo;
|
||||||
extern GLuint materialUbo;
|
extern GLuint material_ubo;
|
||||||
extern GLuint geoUbo;
|
|
||||||
|
|
||||||
namespace UboBinding
|
namespace UboBinding
|
||||||
{
|
{
|
||||||
|
@ -60,7 +46,6 @@ namespace Uniforms
|
||||||
extern int scene;
|
extern int scene;
|
||||||
extern int light;
|
extern int light;
|
||||||
extern int material;
|
extern int material;
|
||||||
extern int geo;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
//Locations for the uniforms which are not in uniform blocks
|
//Locations for the uniforms which are not in uniform blocks
|
|
@ -1,4 +0,0 @@
|
||||||
#define PROJECT_NAME "@PROJECT_NAME@"
|
|
||||||
#define PROJECT_VERSION_MAJOR @PROJECT_VERSION_MAJOR@
|
|
||||||
#define PROJECT_VERSION_MINOR @PROJECT_VERSION_MINOR@
|
|
||||||
#define PROJECT_VERSION_PATCH @PROJECT_VERSION_PATCH@
|
|
|
@ -13,7 +13,6 @@ struct Framebuffer {
|
||||||
|
|
||||||
namespace FBO {
|
namespace FBO {
|
||||||
Framebuffer GenerateFramebuffer(int width, int height);
|
Framebuffer GenerateFramebuffer(int width, int height);
|
||||||
void UpdateFrameBuffer(Framebuffer& fbo, int width, int height);
|
|
||||||
void Bind(const Framebuffer& fbo);
|
void Bind(const Framebuffer& fbo);
|
||||||
void Unbind();
|
void Unbind();
|
||||||
void Cleanup(const Framebuffer& fbo);
|
void Cleanup(const Framebuffer& fbo);
|
||||||
|
|
|
@ -1,29 +0,0 @@
|
||||||
#ifndef INTERFACE_H_
|
|
||||||
#define INTERFACE_H_
|
|
||||||
|
|
||||||
#include <GLFW/glfw3.h>
|
|
||||||
#include <imgui.h>
|
|
||||||
#include <string>
|
|
||||||
#include <vector>
|
|
||||||
#include <functional>
|
|
||||||
|
|
||||||
struct Window {
|
|
||||||
std::string name;
|
|
||||||
ImVec2 size;
|
|
||||||
ImVec2 position;
|
|
||||||
bool isOpen = true;
|
|
||||||
|
|
||||||
std::function<void()> renderContent;
|
|
||||||
|
|
||||||
Window(const std::string& name, std::function<void()> renderFunc)
|
|
||||||
: name(name), size(ImVec2(512, 512)), position(ImVec2(0, 0)), renderContent(renderFunc) {}
|
|
||||||
};
|
|
||||||
|
|
||||||
namespace Interface {
|
|
||||||
void ApplyUIScaling(GLFWwindow* window);
|
|
||||||
void AddWindow(std::vector<Window>& windows, const std::string& name, std::function<void()> renderFunc);
|
|
||||||
Window* GetWindowByName(std::vector<Window>& windows, const std::string& name);
|
|
||||||
void RenderWindows(std::vector<Window>& windows);
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif // INTERFACE_H_
|
|
|
@ -8,7 +8,6 @@
|
||||||
|
|
||||||
#include "fbo.h"
|
#include "fbo.h"
|
||||||
#include "camera.h"
|
#include "camera.h"
|
||||||
#include "interface.h"
|
|
||||||
|
|
||||||
struct Vertex {
|
struct Vertex {
|
||||||
glm::vec3 position;
|
glm::vec3 position;
|
||||||
|
@ -26,21 +25,15 @@ class Scene {
|
||||||
void DrawGui(GLFWwindow* window);
|
void DrawGui(GLFWwindow* window);
|
||||||
void Idle();
|
void Idle();
|
||||||
void ReloadShader();
|
void ReloadShader();
|
||||||
void UpdateCamera();
|
|
||||||
void OnScreenResize(Window* viewport);
|
|
||||||
void UpdateViewport();
|
|
||||||
std::vector<int16_t> LoadHGT(const std::string& filename, int width, int height);
|
std::vector<int16_t> LoadHGT(const std::string& filename, int width, int height);
|
||||||
|
|
||||||
int window_width;
|
int window_width;
|
||||||
int window_height;
|
int window_height;
|
||||||
|
|
||||||
std::vector<Window> windows_;
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void InitBuffers();
|
void InitBuffers();
|
||||||
void InitQuadBuffers();
|
void InitQuadBuffers();
|
||||||
void InitShaders();
|
void InitShaders();
|
||||||
void InitUI();
|
|
||||||
|
|
||||||
Camera activeCamera_;
|
Camera activeCamera_;
|
||||||
Framebuffer geo_fbo_;
|
Framebuffer geo_fbo_;
|
||||||
|
@ -59,6 +52,7 @@ class Scene {
|
||||||
glm::mat4 view_matrix_;
|
glm::mat4 view_matrix_;
|
||||||
glm::mat4 projection_matrix_;
|
glm::mat4 projection_matrix_;
|
||||||
|
|
||||||
|
void UpdateCamera();
|
||||||
int16_t SwapEndian(int16_t val);
|
int16_t SwapEndian(int16_t val);
|
||||||
GLuint CreateHeightmapTexture(std::vector<int16_t> data, int width, int height);
|
GLuint CreateHeightmapTexture(std::vector<int16_t> data, int width, int height);
|
||||||
};
|
};
|
||||||
|
|
|
@ -9,6 +9,12 @@ in TE_OUT {
|
||||||
vec3 normal;
|
vec3 normal;
|
||||||
} fs_in;
|
} fs_in;
|
||||||
|
|
||||||
|
layout(std140, binding = 0) uniform SceneUniforms
|
||||||
|
{
|
||||||
|
mat4 PV; //camera projection * view matrix
|
||||||
|
vec4 eye_w; //world-space eye position
|
||||||
|
};
|
||||||
|
|
||||||
layout(location = 0) out vec4 albedoGbuffer;
|
layout(location = 0) out vec4 albedoGbuffer;
|
||||||
layout(location = 1) out vec4 positionGbuffer;
|
layout(location = 1) out vec4 positionGbuffer;
|
||||||
layout(location = 2) out vec4 normalGbuffer;
|
layout(location = 2) out vec4 normalGbuffer;
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
#version 450 core
|
#version 430
|
||||||
|
precision highp float;
|
||||||
|
|
||||||
out vec4 frag_color;
|
out vec4 frag_color;
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
#version 450 core
|
#version 430
|
||||||
|
|
||||||
layout(location = 0) in vec3 pos_attrib; //this variable holds the position of mesh vertices
|
layout(location = 0) in vec3 pos_attrib; //this variable holds the position of mesh vertices
|
||||||
layout(location = 1) in vec2 tex_coord_attrib;
|
layout(location = 1) in vec2 tex_coord_attrib;
|
||||||
layout(location = 2) in vec3 normal_attrib;
|
layout(location = 2) in vec3 normal_attrib;
|
||||||
|
|
|
@ -2,20 +2,6 @@
|
||||||
|
|
||||||
layout(vertices = 4) out;
|
layout(vertices = 4) out;
|
||||||
|
|
||||||
layout(binding = 0) uniform sampler2D heightTexture;
|
|
||||||
uniform float tessellationFactor;
|
|
||||||
|
|
||||||
layout(std140, binding = 4) uniform GeoUniforms
|
|
||||||
{
|
|
||||||
mat4 PV;
|
|
||||||
mat4 M;
|
|
||||||
|
|
||||||
float minTessellation;
|
|
||||||
float maxTessellation;
|
|
||||||
float displacementScale;
|
|
||||||
int gridDensity;
|
|
||||||
};
|
|
||||||
|
|
||||||
in VS_OUT {
|
in VS_OUT {
|
||||||
vec3 position;
|
vec3 position;
|
||||||
vec2 texCoord;
|
vec2 texCoord;
|
||||||
|
@ -24,48 +10,23 @@ in VS_OUT {
|
||||||
out TC_OUT {
|
out TC_OUT {
|
||||||
vec3 position;
|
vec3 position;
|
||||||
vec2 texCoord;
|
vec2 texCoord;
|
||||||
float tessLevel;
|
|
||||||
} tc_out[];
|
} tc_out[];
|
||||||
|
|
||||||
float getHeight(vec2 uv) {
|
uniform float tessellationFactor;
|
||||||
return texture(heightTexture, uv).r * displacementScale;
|
|
||||||
}
|
|
||||||
|
|
||||||
float calculateSlope() {
|
|
||||||
float step = 1.0f / (float(gridDensity) * maxTessellation + 1.0f);
|
|
||||||
|
|
||||||
// Find surrounding heights
|
|
||||||
float hLeft = getHeight(tc_in[gl_InvocationID].texCoord + vec2(-step, 0.0f));
|
|
||||||
float hRight = getHeight(tc_in[gl_InvocationID].texCoord + vec2(step, 0.0f));
|
|
||||||
float hUp = getHeight(tc_in[gl_InvocationID].texCoord + vec2(0.0f, step));
|
|
||||||
float hDown = getHeight(tc_in[gl_InvocationID].texCoord + vec2(0.0f, -step));
|
|
||||||
|
|
||||||
float slopeX = abs(hLeft - hRight) * displacementScale;
|
|
||||||
float slopeY = abs(hUp - hDown) * displacementScale;
|
|
||||||
|
|
||||||
float maxSlope = max(slopeX, slopeY);
|
|
||||||
|
|
||||||
return maxSlope;
|
|
||||||
}
|
|
||||||
|
|
||||||
void main() {
|
void main() {
|
||||||
|
// Set tessellation levels
|
||||||
|
if (gl_InvocationID == 0) {
|
||||||
|
gl_TessLevelOuter[0] = tessellationFactor; // Level of tessellation along one edge
|
||||||
|
gl_TessLevelOuter[1] = tessellationFactor; // Level of tessellation along another edge
|
||||||
|
gl_TessLevelOuter[2] = tessellationFactor; // Level of tessellation along the other edge
|
||||||
|
gl_TessLevelOuter[3] = tessellationFactor; // Level of tessellation along the other edge
|
||||||
|
|
||||||
|
gl_TessLevelInner[0] = tessellationFactor; // Level of tessellation for the inner part
|
||||||
|
gl_TessLevelInner[1] = tessellationFactor; // Level of tessellation for the inner part
|
||||||
|
}
|
||||||
|
|
||||||
// Pass through position and texture coordinates to the tessellation evaluation shader
|
// Pass through position and texture coordinates to the tessellation evaluation shader
|
||||||
tc_out[gl_InvocationID].position = tc_in[gl_InvocationID].position;
|
tc_out[gl_InvocationID].position = tc_in[gl_InvocationID].position;
|
||||||
tc_out[gl_InvocationID].texCoord = tc_in[gl_InvocationID].texCoord;
|
tc_out[gl_InvocationID].texCoord = tc_in[gl_InvocationID].texCoord;
|
||||||
|
|
||||||
float slope = calculateSlope();
|
|
||||||
float tessLevel = tessellationFactor * (1.0f + slope * 10.0f);
|
|
||||||
tessLevel = max(tessLevel, maxTessellation);
|
|
||||||
tc_out[gl_InvocationID].tessLevel = tessLevel;
|
|
||||||
|
|
||||||
// Set tessellation levels
|
|
||||||
if (gl_InvocationID == 0) {
|
|
||||||
gl_TessLevelOuter[0] = tessLevel;
|
|
||||||
gl_TessLevelOuter[1] = tessLevel;
|
|
||||||
gl_TessLevelOuter[2] = tessLevel;
|
|
||||||
gl_TessLevelOuter[3] = tessLevel;
|
|
||||||
|
|
||||||
gl_TessLevelInner[0] = tessLevel;
|
|
||||||
gl_TessLevelInner[1] = tessLevel;
|
|
||||||
}
|
|
||||||
}
|
}
|
|
@ -3,22 +3,20 @@
|
||||||
layout(quads, fractional_even_spacing, cw) in;
|
layout(quads, fractional_even_spacing, cw) in;
|
||||||
|
|
||||||
layout(binding = 0) uniform sampler2D heightTexture;
|
layout(binding = 0) uniform sampler2D heightTexture;
|
||||||
|
layout(location = 0) uniform mat4 M;
|
||||||
|
|
||||||
layout(std140, binding = 4) uniform GeoUniforms
|
uniform float displacementScale = 0.025f;
|
||||||
|
uniform float tessellationFactor;
|
||||||
|
|
||||||
|
layout(std140, binding = 0) uniform SceneUniforms
|
||||||
{
|
{
|
||||||
mat4 PV;
|
mat4 PV; //camera projection * view matrix
|
||||||
mat4 M;
|
vec4 eye_w; //world-space eye position
|
||||||
|
|
||||||
float minTessellation;
|
|
||||||
float maxTessellation;
|
|
||||||
float displacementScale;
|
|
||||||
int gridDensity;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
in TC_OUT {
|
in TC_OUT {
|
||||||
vec3 position;
|
vec3 position;
|
||||||
vec2 texCoord;
|
vec2 texCoord;
|
||||||
float tessLevel;
|
|
||||||
} te_in[];
|
} te_in[];
|
||||||
|
|
||||||
out TE_OUT {
|
out TE_OUT {
|
||||||
|
@ -31,25 +29,16 @@ float getHeight(vec2 uv) {
|
||||||
return texture(heightTexture, uv).r * displacementScale;
|
return texture(heightTexture, uv).r * displacementScale;
|
||||||
}
|
}
|
||||||
|
|
||||||
float getNeighbor(float tessFactor) {
|
|
||||||
return (float(gridDensity) * tessFactor + 1.0f);
|
|
||||||
}
|
|
||||||
|
|
||||||
vec3 calculateSmoothNormal(vec3 pos, vec2 coord) {
|
vec3 calculateSmoothNormal(vec3 pos, vec2 coord) {
|
||||||
// Currently hardcoded to match patch density
|
float step = 1.0f / (16.0f * tessellationFactor + 1.0f);
|
||||||
//float step = 1.0f / (float(gridDensity) * tessLevel + 1.0f);
|
|
||||||
float stepU = 1.0f / (float(gridDensity) * gl_TessLevelInner[0]);
|
|
||||||
float stepV = 1.0f / (float(gridDensity) * gl_TessLevelInner[1]);
|
|
||||||
|
|
||||||
// Find surrounding heights
|
float hLeft = getHeight(coord + vec2(-step, 0.0f));
|
||||||
float hLeft = getHeight(coord + vec2(-stepU, 0.0f));
|
float hRight = getHeight(coord + vec2(step, 0.0f));
|
||||||
float hRight = getHeight(coord + vec2(stepU, 0.0f));
|
float hUp = getHeight(coord + vec2(0.0f, step));
|
||||||
float hUp = getHeight(coord + vec2(0.0f, stepV));
|
float hDown = getHeight(coord + vec2(0.0f, -step));
|
||||||
float hDown = getHeight(coord + vec2(0.0f, -stepV));
|
|
||||||
|
|
||||||
// Calculate tangents
|
vec3 tangentX = normalize(vec3(step, hRight - hLeft, 0.0));
|
||||||
vec3 tangentX = normalize(vec3(stepU, hRight - hLeft, 0.0));
|
vec3 tangentY = normalize(vec3(0.0, hUp - hDown, step));
|
||||||
vec3 tangentY = normalize(vec3(0.0, hUp - hDown, stepV));
|
|
||||||
|
|
||||||
return normalize(cross(tangentY, tangentX));
|
return normalize(cross(tangentY, tangentX));
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
#version 450 core
|
#version 450 core
|
||||||
|
|
||||||
layout(location = 0) in vec3 posAttrib;
|
layout(location = 0) in vec3 inPosition;
|
||||||
layout(location = 1) in vec2 texCoordAttrib;
|
layout(location = 1) in vec2 inTexCoord;
|
||||||
|
|
||||||
out VS_OUT {
|
out VS_OUT {
|
||||||
vec3 position;
|
vec3 position;
|
||||||
|
@ -9,6 +9,6 @@ out VS_OUT {
|
||||||
} vs_out;
|
} vs_out;
|
||||||
|
|
||||||
void main() {
|
void main() {
|
||||||
vs_out.position = (vec4(posAttrib, 1.0f)).xyz;
|
vs_out.position = (vec4(inPosition, 1.0f)).xyz;
|
||||||
vs_out.texCoord = texCoordAttrib;
|
vs_out.texCoord = inTexCoord;
|
||||||
}
|
}
|
|
@ -10,106 +10,106 @@ using namespace std;
|
||||||
// Create a NULL-terminated string by reading the provided file
|
// Create a NULL-terminated string by reading the provided file
|
||||||
static char* readShaderSource(const char* shaderFile)
|
static char* readShaderSource(const char* shaderFile)
|
||||||
{
|
{
|
||||||
ifstream ifs(shaderFile, ios::in | ios::binary | ios::ate);
|
ifstream ifs(shaderFile, ios::in | ios::binary | ios::ate);
|
||||||
if (ifs.is_open())
|
if (ifs.is_open())
|
||||||
{
|
{
|
||||||
unsigned int filesize = static_cast<unsigned int>(ifs.tellg());
|
unsigned int filesize = static_cast<unsigned int>(ifs.tellg());
|
||||||
ifs.seekg(0, ios::beg);
|
ifs.seekg(0, ios::beg);
|
||||||
char* bytes = new char[filesize + 1];
|
char* bytes = new char[filesize + 1];
|
||||||
memset(bytes, 0, filesize + 1);
|
memset(bytes, 0, filesize + 1);
|
||||||
ifs.read(bytes, filesize);
|
ifs.read(bytes, filesize);
|
||||||
ifs.close();
|
ifs.close();
|
||||||
return bytes;
|
return bytes;
|
||||||
}
|
}
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
void printShaderCompileError(GLuint shader)
|
void printShaderCompileError(GLuint shader)
|
||||||
{
|
{
|
||||||
GLint logSize;
|
GLint logSize;
|
||||||
glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &logSize);
|
glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &logSize);
|
||||||
char* logMsg = new char[logSize];
|
char* logMsg = new char[logSize];
|
||||||
glGetShaderInfoLog(shader, logSize, NULL, logMsg);
|
glGetShaderInfoLog(shader, logSize, NULL, logMsg);
|
||||||
std::cerr << logMsg << std::endl;
|
std::cerr << logMsg << std::endl;
|
||||||
delete[] logMsg;
|
delete[] logMsg;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void printProgramLinkError(GLuint program)
|
void printProgramLinkError(GLuint program)
|
||||||
{
|
{
|
||||||
GLint logSize;
|
GLint logSize;
|
||||||
glGetProgramiv(program, GL_INFO_LOG_LENGTH, &logSize);
|
glGetProgramiv(program, GL_INFO_LOG_LENGTH, &logSize);
|
||||||
char* logMsg = new char[logSize];
|
char* logMsg = new char[logSize];
|
||||||
glGetProgramInfoLog(program, logSize, NULL, logMsg);
|
glGetProgramInfoLog(program, logSize, NULL, logMsg);
|
||||||
std::cerr << logMsg << std::endl;
|
std::cerr << logMsg << std::endl;
|
||||||
delete[] logMsg;
|
delete[] logMsg;
|
||||||
}
|
}
|
||||||
|
|
||||||
GLuint InitShader(const char* computeShaderFile)
|
GLuint InitShader(const char* computeShaderFile)
|
||||||
{
|
{
|
||||||
bool error = false;
|
bool error = false;
|
||||||
struct Shader
|
struct Shader
|
||||||
{
|
{
|
||||||
const char* filename;
|
const char* filename;
|
||||||
GLenum type;
|
GLenum type;
|
||||||
GLchar* source;
|
GLchar* source;
|
||||||
} shaders[1] =
|
} shaders[1] =
|
||||||
{
|
{
|
||||||
{ computeShaderFile, GL_COMPUTE_SHADER, NULL }
|
{ computeShaderFile, GL_COMPUTE_SHADER, NULL }
|
||||||
};
|
};
|
||||||
|
|
||||||
GLuint program = glCreateProgram();
|
GLuint program = glCreateProgram();
|
||||||
|
|
||||||
for (int i = 0; i < 1; ++i)
|
for (int i = 0; i < 1; ++i)
|
||||||
{
|
{
|
||||||
Shader& s = shaders[i];
|
Shader& s = shaders[i];
|
||||||
s.source = readShaderSource(s.filename);
|
s.source = readShaderSource(s.filename);
|
||||||
if (shaders[i].source == NULL)
|
if (shaders[i].source == NULL)
|
||||||
{
|
{
|
||||||
std::cerr << "Failed to read " << s.filename << std::endl;
|
std::cerr << "Failed to read " << s.filename << std::endl;
|
||||||
error = true;
|
error = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
GLuint shader = glCreateShader(s.type);
|
GLuint shader = glCreateShader(s.type);
|
||||||
glShaderSource(shader, 1, (const GLchar**)&s.source, NULL);
|
glShaderSource(shader, 1, (const GLchar**)&s.source, NULL);
|
||||||
glCompileShader(shader);
|
glCompileShader(shader);
|
||||||
|
|
||||||
GLint compiled;
|
GLint compiled;
|
||||||
glGetShaderiv(shader, GL_COMPILE_STATUS, &compiled);
|
glGetShaderiv(shader, GL_COMPILE_STATUS, &compiled);
|
||||||
if (!compiled)
|
if (!compiled)
|
||||||
{
|
{
|
||||||
std::cerr << s.filename << " failed to compile:" << std::endl;
|
std::cerr << s.filename << " failed to compile:" << std::endl;
|
||||||
printShaderCompileError(shader);
|
printShaderCompileError(shader);
|
||||||
error = true;
|
error = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
delete[] s.source;
|
delete[] s.source;
|
||||||
|
|
||||||
glAttachShader(program, shader);
|
glAttachShader(program, shader);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* link and error check */
|
/* link and error check */
|
||||||
glLinkProgram(program);
|
glLinkProgram(program);
|
||||||
|
|
||||||
GLint linked;
|
GLint linked;
|
||||||
glGetProgramiv(program, GL_LINK_STATUS, &linked);
|
glGetProgramiv(program, GL_LINK_STATUS, &linked);
|
||||||
if (!linked)
|
if (!linked)
|
||||||
{
|
{
|
||||||
std::cerr << "Shader program failed to link" << std::endl;
|
std::cerr << "Shader program failed to link" << std::endl;
|
||||||
printProgramLinkError(program);
|
printProgramLinkError(program);
|
||||||
|
|
||||||
error = true;
|
error = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (error == true)
|
if (error == true)
|
||||||
{
|
{
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* use program object */
|
/* use program object */
|
||||||
glUseProgram(program);
|
glUseProgram(program);
|
||||||
|
|
||||||
return program;
|
return program;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -117,301 +117,294 @@ GLuint InitShader(const char* computeShaderFile)
|
||||||
GLuint InitShader(const char* vShaderFile, const char* fShaderFile)
|
GLuint InitShader(const char* vShaderFile, const char* fShaderFile)
|
||||||
{
|
{
|
||||||
|
|
||||||
bool error = false;
|
bool error = false;
|
||||||
struct Shader
|
struct Shader
|
||||||
{
|
{
|
||||||
const char* filename;
|
const char* filename;
|
||||||
GLenum type;
|
GLenum type;
|
||||||
GLchar* source;
|
GLchar* source;
|
||||||
} shaders[2] =
|
} shaders[2] =
|
||||||
{
|
{
|
||||||
{ vShaderFile, GL_VERTEX_SHADER, NULL },
|
{ vShaderFile, GL_VERTEX_SHADER, NULL },
|
||||||
{ fShaderFile, GL_FRAGMENT_SHADER, NULL }
|
{ fShaderFile, GL_FRAGMENT_SHADER, NULL }
|
||||||
};
|
};
|
||||||
|
|
||||||
GLuint program = glCreateProgram();
|
GLuint program = glCreateProgram();
|
||||||
|
|
||||||
for (int i = 0; i < 2; ++i)
|
for (int i = 0; i < 2; ++i)
|
||||||
{
|
{
|
||||||
Shader& s = shaders[i];
|
Shader& s = shaders[i];
|
||||||
s.source = readShaderSource(s.filename);
|
s.source = readShaderSource(s.filename);
|
||||||
if (shaders[i].source == NULL)
|
if (shaders[i].source == NULL)
|
||||||
{
|
{
|
||||||
std::cerr << "Failed to read " << s.filename << std::endl;
|
std::cerr << "Failed to read " << s.filename << std::endl;
|
||||||
error = true;
|
error = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
GLuint shader = glCreateShader(s.type);
|
GLuint shader = glCreateShader(s.type);
|
||||||
glShaderSource(shader, 1, (const GLchar**)&s.source, NULL);
|
glShaderSource(shader, 1, (const GLchar**)&s.source, NULL);
|
||||||
glCompileShader(shader);
|
glCompileShader(shader);
|
||||||
|
|
||||||
GLint compiled;
|
GLint compiled;
|
||||||
glGetShaderiv(shader, GL_COMPILE_STATUS, &compiled);
|
glGetShaderiv(shader, GL_COMPILE_STATUS, &compiled);
|
||||||
if (!compiled)
|
if (!compiled)
|
||||||
{
|
{
|
||||||
std::cerr << s.filename << " failed to compile:" << std::endl;
|
std::cerr << s.filename << " failed to compile:" << std::endl;
|
||||||
printShaderCompileError(shader);
|
printShaderCompileError(shader);
|
||||||
error = true;
|
error = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
delete[] s.source;
|
delete[] s.source;
|
||||||
|
|
||||||
glAttachShader(program, shader);
|
glAttachShader(program, shader);
|
||||||
}
|
}
|
||||||
|
|
||||||
//set shader attrib locations
|
//set shader attrib locations
|
||||||
const int posLoc = 0;
|
const int pos_loc = 0;
|
||||||
const int texCoordLoc = 1;
|
const int tex_coord_loc = 1;
|
||||||
const int normalLoc = 2;
|
const int normal_loc = 2;
|
||||||
|
|
||||||
glBindAttribLocation(program, posLoc, "posAttrib");
|
glBindAttribLocation(program, pos_loc, "pos_attrib");
|
||||||
glBindAttribLocation(program, texCoordLoc, "texCoordAttrib");
|
glBindAttribLocation(program, tex_coord_loc, "tex_coord_attrib");
|
||||||
glBindAttribLocation(program, normalLoc, "normalAttrib");
|
glBindAttribLocation(program, normal_loc, "normal_attrib");
|
||||||
|
|
||||||
/* link and error check */
|
/* link and error check */
|
||||||
glLinkProgram(program);
|
glLinkProgram(program);
|
||||||
|
|
||||||
GLint linked;
|
GLint linked;
|
||||||
glGetProgramiv(program, GL_LINK_STATUS, &linked);
|
glGetProgramiv(program, GL_LINK_STATUS, &linked);
|
||||||
if (!linked)
|
if (!linked)
|
||||||
{
|
{
|
||||||
std::cerr << "Shader program failed to link" << std::endl;
|
std::cerr << "Shader program failed to link" << std::endl;
|
||||||
printProgramLinkError(program);
|
printProgramLinkError(program);
|
||||||
|
|
||||||
error = true;
|
error = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (error == true)
|
if (error == true)
|
||||||
{
|
{
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* use program object */
|
/* use program object */
|
||||||
glUseProgram(program);
|
glUseProgram(program);
|
||||||
return program;
|
return program;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create a GLSL program object from vertex and fragment shader files
|
// Create a GLSL program object from vertex and fragment shader files
|
||||||
GLuint InitShader(const char* vShaderFile, const char* gShaderFile, const char* fShaderFile)
|
GLuint InitShader(const char* vShaderFile, const char* gShaderFile, const char* fShaderFile)
|
||||||
{
|
{
|
||||||
bool error = false;
|
bool error = false;
|
||||||
struct Shader
|
struct Shader
|
||||||
{
|
{
|
||||||
const char* filename;
|
const char* filename;
|
||||||
GLenum type;
|
GLenum type;
|
||||||
GLchar* source;
|
GLchar* source;
|
||||||
} shaders[3] =
|
} shaders[3] =
|
||||||
{
|
{
|
||||||
{ vShaderFile, GL_VERTEX_SHADER, NULL },
|
{ vShaderFile, GL_VERTEX_SHADER, NULL },
|
||||||
{ gShaderFile, GL_GEOMETRY_SHADER, NULL },
|
{ gShaderFile, GL_GEOMETRY_SHADER, NULL },
|
||||||
{ fShaderFile, GL_FRAGMENT_SHADER, NULL }
|
{ fShaderFile, GL_FRAGMENT_SHADER, NULL }
|
||||||
};
|
};
|
||||||
|
|
||||||
GLuint program = glCreateProgram();
|
GLuint program = glCreateProgram();
|
||||||
|
|
||||||
for (int i = 0; i < 3; ++i)
|
for (int i = 0; i < 3; ++i)
|
||||||
{
|
{
|
||||||
Shader& s = shaders[i];
|
Shader& s = shaders[i];
|
||||||
s.source = readShaderSource(s.filename);
|
s.source = readShaderSource(s.filename);
|
||||||
if (shaders[i].source == NULL)
|
if (shaders[i].source == NULL)
|
||||||
{
|
{
|
||||||
std::cerr << "Failed to read " << s.filename << std::endl;
|
std::cerr << "Failed to read " << s.filename << std::endl;
|
||||||
error = true;
|
error = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
GLuint shader = glCreateShader(s.type);
|
GLuint shader = glCreateShader(s.type);
|
||||||
glShaderSource(shader, 1, (const GLchar**)&s.source, NULL);
|
glShaderSource(shader, 1, (const GLchar**)&s.source, NULL);
|
||||||
glCompileShader(shader);
|
glCompileShader(shader);
|
||||||
|
|
||||||
GLint compiled;
|
GLint compiled;
|
||||||
glGetShaderiv(shader, GL_COMPILE_STATUS, &compiled);
|
glGetShaderiv(shader, GL_COMPILE_STATUS, &compiled);
|
||||||
if (!compiled)
|
if (!compiled)
|
||||||
{
|
{
|
||||||
std::cerr << s.filename << " failed to compile:" << std::endl;
|
std::cerr << s.filename << " failed to compile:" << std::endl;
|
||||||
printShaderCompileError(shader);
|
printShaderCompileError(shader);
|
||||||
error = true;
|
error = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
delete[] s.source;
|
delete[] s.source;
|
||||||
|
|
||||||
glAttachShader(program, shader);
|
glAttachShader(program, shader);
|
||||||
}
|
}
|
||||||
|
|
||||||
//set shader attrib locations
|
//set shader attrib locations
|
||||||
const int posLoc = 0;
|
const int pos_loc = 0;
|
||||||
const int texCoordLoc = 1;
|
const int tex_coord_loc = 1;
|
||||||
const int normalLoc = 2;
|
const int normal_loc = 2;
|
||||||
|
|
||||||
glBindAttribLocation(program, posLoc, "posAttrib");
|
glBindAttribLocation(program, pos_loc, "pos_attrib");
|
||||||
glBindAttribLocation(program, texCoordLoc, "texCoordAttrib");
|
glBindAttribLocation(program, tex_coord_loc, "tex_coord_attrib");
|
||||||
glBindAttribLocation(program, normalLoc, "normalAttrib");
|
glBindAttribLocation(program, normal_loc, "normal_attrib");
|
||||||
|
|
||||||
/* link and error check */
|
/* link and error check */
|
||||||
glLinkProgram(program);
|
glLinkProgram(program);
|
||||||
|
|
||||||
GLint linked;
|
GLint linked;
|
||||||
glGetProgramiv(program, GL_LINK_STATUS, &linked);
|
glGetProgramiv(program, GL_LINK_STATUS, &linked);
|
||||||
if (!linked)
|
if (!linked)
|
||||||
{
|
{
|
||||||
std::cerr << "Shader program failed to link" << std::endl;
|
std::cerr << "Shader program failed to link" << std::endl;
|
||||||
printProgramLinkError(program);
|
printProgramLinkError(program);
|
||||||
|
|
||||||
error = true;
|
error = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (error == true)
|
if (error == true)
|
||||||
{
|
{
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* use program object */
|
/* use program object */
|
||||||
glUseProgram(program);
|
glUseProgram(program);
|
||||||
|
|
||||||
return program;
|
return program;
|
||||||
}
|
}
|
||||||
|
|
||||||
GLuint InitShader( const char* vShaderFile, const char* tcShader, const char* teShader, const char* fShaderFile )
|
GLuint InitShader( const char* vShaderFile, const char* tcShader, const char* teShader, const char* fShaderFile )
|
||||||
{
|
{
|
||||||
bool error = false;
|
bool error = false;
|
||||||
struct Shader
|
struct Shader
|
||||||
{
|
{
|
||||||
const char* filename;
|
const char* filename;
|
||||||
GLenum type;
|
GLenum type;
|
||||||
std::string source;
|
std::string source;
|
||||||
} shaders[4] =
|
} shaders[4] =
|
||||||
{
|
{
|
||||||
{ vShaderFile, GL_VERTEX_SHADER, "" },
|
{ vShaderFile, GL_VERTEX_SHADER, "" },
|
||||||
{ tcShader, GL_TESS_CONTROL_SHADER, "" },
|
{ tcShader, GL_TESS_CONTROL_SHADER, "" },
|
||||||
{ teShader, GL_TESS_EVALUATION_SHADER, "" },
|
{ teShader, GL_TESS_EVALUATION_SHADER, "" },
|
||||||
{ fShaderFile, GL_FRAGMENT_SHADER, "" }
|
{ fShaderFile, GL_FRAGMENT_SHADER, "" }
|
||||||
};
|
};
|
||||||
|
|
||||||
GLuint program = glCreateProgram();
|
GLuint program = glCreateProgram();
|
||||||
|
|
||||||
for ( int i = 0; i < 4; ++i )
|
for ( int i = 0; i < 4; ++i )
|
||||||
{
|
{
|
||||||
Shader& s = shaders[i];
|
Shader& s = shaders[i];
|
||||||
s.source = readShaderSource(s.filename);
|
s.source = readShaderSource(s.filename);
|
||||||
if ( shaders[i].source.length() == 0 )
|
if ( shaders[i].source.length() == 0 )
|
||||||
{
|
{
|
||||||
std::cerr << "Failed to read " << s.filename << std::endl;
|
std::cerr << "Failed to read " << s.filename << std::endl;
|
||||||
error = true;
|
error = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
GLuint shader = glCreateShader( s.type );
|
GLuint shader = glCreateShader( s.type );
|
||||||
const char *c_str = s.source.c_str();
|
const char *c_str = s.source.c_str();
|
||||||
glShaderSource(shader, 1, (const GLchar**)&c_str, NULL);
|
glShaderSource(shader, 1, (const GLchar**)&c_str, NULL);
|
||||||
glCompileShader( shader );
|
glCompileShader( shader );
|
||||||
|
|
||||||
GLint compiled;
|
GLint compiled;
|
||||||
glGetShaderiv( shader, GL_COMPILE_STATUS, &compiled );
|
glGetShaderiv( shader, GL_COMPILE_STATUS, &compiled );
|
||||||
if ( !compiled )
|
if ( !compiled )
|
||||||
{
|
{
|
||||||
std::cerr << s.filename << " failed to compile:" << std::endl;
|
std::cerr << s.filename << " failed to compile:" << std::endl;
|
||||||
printShaderCompileError(shader);
|
printShaderCompileError(shader);
|
||||||
error = true;
|
error = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
glAttachShader( program, shader );
|
glAttachShader( program, shader );
|
||||||
}
|
}
|
||||||
|
|
||||||
//set shader attrib locations
|
/* link and error check */
|
||||||
const int posLoc = 0;
|
glLinkProgram(program);
|
||||||
const int texCoordLoc = 1;
|
|
||||||
|
|
||||||
glBindAttribLocation(program, posLoc, "posAttrib");
|
GLint linked;
|
||||||
glBindAttribLocation(program, texCoordLoc, "texCoordAttrib");
|
glGetProgramiv( program, GL_LINK_STATUS, &linked );
|
||||||
|
if ( !linked )
|
||||||
|
{
|
||||||
|
std::cerr << "Shader program failed to link" << std::endl;
|
||||||
|
printProgramLinkError(program);
|
||||||
|
|
||||||
/* link and error check */
|
error = true;
|
||||||
glLinkProgram(program);
|
}
|
||||||
|
|
||||||
GLint linked;
|
if(error == true)
|
||||||
glGetProgramiv( program, GL_LINK_STATUS, &linked );
|
{
|
||||||
if ( !linked )
|
return -1;
|
||||||
{
|
}
|
||||||
std::cerr << "Shader program failed to link" << std::endl;
|
|
||||||
printProgramLinkError(program);
|
|
||||||
|
|
||||||
error = true;
|
/* use program object */
|
||||||
}
|
glUseProgram(program);
|
||||||
|
|
||||||
if(error == true)
|
return program;
|
||||||
{
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* use program object */
|
|
||||||
glUseProgram(program);
|
|
||||||
|
|
||||||
return program;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
GLuint InitShader( const char* vShaderFile, const char* tcShader, const char* teShader, const char* gShaderFile, const char* fShaderFile )
|
GLuint InitShader( const char* vShaderFile, const char* tcShader, const char* teShader, const char* gShaderFile, const char* fShaderFile )
|
||||||
{
|
{
|
||||||
bool error = false;
|
bool error = false;
|
||||||
struct Shader
|
struct Shader
|
||||||
{
|
{
|
||||||
const char* filename;
|
const char* filename;
|
||||||
GLenum type;
|
GLenum type;
|
||||||
std::string source;
|
std::string source;
|
||||||
} shaders[5] =
|
} shaders[5] =
|
||||||
{
|
{
|
||||||
{ vShaderFile, GL_VERTEX_SHADER, "" },
|
{ vShaderFile, GL_VERTEX_SHADER, "" },
|
||||||
{ tcShader, GL_TESS_CONTROL_SHADER, "" },
|
{ tcShader, GL_TESS_CONTROL_SHADER, "" },
|
||||||
{ teShader, GL_TESS_EVALUATION_SHADER, "" },
|
{ teShader, GL_TESS_EVALUATION_SHADER, "" },
|
||||||
{ gShaderFile, GL_GEOMETRY_SHADER, "" },
|
{ gShaderFile, GL_GEOMETRY_SHADER, "" },
|
||||||
{ fShaderFile, GL_FRAGMENT_SHADER, "" }
|
{ fShaderFile, GL_FRAGMENT_SHADER, "" }
|
||||||
};
|
};
|
||||||
|
|
||||||
GLuint program = glCreateProgram();
|
GLuint program = glCreateProgram();
|
||||||
|
|
||||||
for ( int i = 0; i < 5; ++i )
|
for ( int i = 0; i < 5; ++i )
|
||||||
{
|
{
|
||||||
Shader& s = shaders[i];
|
Shader& s = shaders[i];
|
||||||
s.source = readShaderSource(s.filename);
|
s.source = readShaderSource(s.filename);
|
||||||
if ( shaders[i].source.length() == 0 )
|
if ( shaders[i].source.length() == 0 )
|
||||||
{
|
{
|
||||||
std::cerr << "Failed to read " << s.filename << std::endl;
|
std::cerr << "Failed to read " << s.filename << std::endl;
|
||||||
error = true;
|
error = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
GLuint shader = glCreateShader( s.type );
|
GLuint shader = glCreateShader( s.type );
|
||||||
const char *c_str = s.source.c_str();
|
const char *c_str = s.source.c_str();
|
||||||
glShaderSource( shader, 1, (const GLchar**) &c_str, NULL );
|
glShaderSource( shader, 1, (const GLchar**) &c_str, NULL );
|
||||||
glCompileShader( shader );
|
glCompileShader( shader );
|
||||||
|
|
||||||
GLint compiled;
|
GLint compiled;
|
||||||
glGetShaderiv( shader, GL_COMPILE_STATUS, &compiled );
|
glGetShaderiv( shader, GL_COMPILE_STATUS, &compiled );
|
||||||
if ( !compiled )
|
if ( !compiled )
|
||||||
{
|
{
|
||||||
std::cerr << s.filename << " failed to compile:" << std::endl;
|
std::cerr << s.filename << " failed to compile:" << std::endl;
|
||||||
printShaderCompileError(shader);
|
printShaderCompileError(shader);
|
||||||
error = true;
|
error = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
glAttachShader( program, shader );
|
glAttachShader( program, shader );
|
||||||
}
|
}
|
||||||
|
|
||||||
/* link and error check */
|
/* link and error check */
|
||||||
glLinkProgram(program);
|
glLinkProgram(program);
|
||||||
|
|
||||||
GLint linked;
|
GLint linked;
|
||||||
glGetProgramiv( program, GL_LINK_STATUS, &linked );
|
glGetProgramiv( program, GL_LINK_STATUS, &linked );
|
||||||
if ( !linked )
|
if ( !linked )
|
||||||
{
|
{
|
||||||
std::cerr << "Shader program failed to link" << std::endl;
|
std::cerr << "Shader program failed to link" << std::endl;
|
||||||
printProgramLinkError(program);
|
printProgramLinkError(program);
|
||||||
|
|
||||||
error = true;
|
error = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(error == true)
|
if(error == true)
|
||||||
{
|
{
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* use program object */
|
/* use program object */
|
||||||
glUseProgram(program);
|
glUseProgram(program);
|
||||||
|
|
||||||
return program;
|
return program;
|
||||||
}
|
}
|
|
@ -1,4 +1,4 @@
|
||||||
#include "uniforms.h"
|
#include "Uniforms.h"
|
||||||
#include <GL/glew.h>
|
#include <GL/glew.h>
|
||||||
|
|
||||||
namespace Uniforms
|
namespace Uniforms
|
||||||
|
@ -6,13 +6,11 @@ namespace Uniforms
|
||||||
SceneUniforms SceneData;
|
SceneUniforms SceneData;
|
||||||
LightUniforms LightData;
|
LightUniforms LightData;
|
||||||
MaterialUniforms MaterialData;
|
MaterialUniforms MaterialData;
|
||||||
GeoUniforms GeoData;
|
|
||||||
|
|
||||||
//IDs for the buffer objects holding the uniform block data
|
//IDs for the buffer objects holding the uniform block data
|
||||||
GLuint sceneUbo = 0;
|
GLuint scene_ubo = -1;
|
||||||
GLuint lightUbo = 0;
|
GLuint light_ubo = -1;
|
||||||
GLuint materialUbo = 0;
|
GLuint material_ubo = -1;
|
||||||
GLuint geoUbo = 0;
|
|
||||||
|
|
||||||
namespace UboBinding
|
namespace UboBinding
|
||||||
{
|
{
|
||||||
|
@ -20,7 +18,6 @@ namespace Uniforms
|
||||||
int scene = 0;
|
int scene = 0;
|
||||||
int light = 1;
|
int light = 1;
|
||||||
int material = 2;
|
int material = 2;
|
||||||
int geometry = 4;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
//Locations for the uniforms which are not in uniform blocks
|
//Locations for the uniforms which are not in uniform blocks
|
||||||
|
@ -33,37 +30,28 @@ namespace Uniforms
|
||||||
void Init()
|
void Init()
|
||||||
{
|
{
|
||||||
//Create and initialize uniform buffers
|
//Create and initialize uniform buffers
|
||||||
glGenBuffers(1, &Uniforms::sceneUbo);
|
glGenBuffers(1, &Uniforms::scene_ubo);
|
||||||
glBindBuffer(GL_UNIFORM_BUFFER, sceneUbo);
|
glBindBuffer(GL_UNIFORM_BUFFER, scene_ubo);
|
||||||
glBufferData(GL_UNIFORM_BUFFER, sizeof(SceneUniforms), nullptr, GL_STREAM_DRAW); //Allocate memory for the buffer, but don't copy (since pointer is null).
|
glBufferData(GL_UNIFORM_BUFFER, sizeof(SceneUniforms), nullptr, GL_STREAM_DRAW); //Allocate memory for the buffer, but don't copy (since pointer is null).
|
||||||
glBindBufferBase(GL_UNIFORM_BUFFER, UboBinding::scene, sceneUbo); //Associate this uniform buffer with the uniform block in the shader that has the same binding.
|
glBindBufferBase(GL_UNIFORM_BUFFER, UboBinding::scene, scene_ubo); //Associate this uniform buffer with the uniform block in the shader that has the same binding.
|
||||||
|
|
||||||
glGenBuffers(1, &lightUbo);
|
glGenBuffers(1, &light_ubo);
|
||||||
glBindBuffer(GL_UNIFORM_BUFFER, lightUbo);
|
glBindBuffer(GL_UNIFORM_BUFFER, light_ubo);
|
||||||
glBufferData(GL_UNIFORM_BUFFER, sizeof(LightUniforms), &LightData, GL_STREAM_DRAW); //Allocate memory for the buffer, but don't copy (since pointer is null).
|
glBufferData(GL_UNIFORM_BUFFER, sizeof(LightUniforms), &LightData, GL_STREAM_DRAW); //Allocate memory for the buffer, but don't copy (since pointer is null).
|
||||||
glBindBufferBase(GL_UNIFORM_BUFFER, UboBinding::light, lightUbo); //Associate this uniform buffer with the uniform block in the shader that has the same binding.
|
glBindBufferBase(GL_UNIFORM_BUFFER, UboBinding::light, light_ubo); //Associate this uniform buffer with the uniform block in the shader that has the same binding.
|
||||||
|
|
||||||
glGenBuffers(1, &materialUbo);
|
glGenBuffers(1, &material_ubo);
|
||||||
glBindBuffer(GL_UNIFORM_BUFFER, materialUbo);
|
glBindBuffer(GL_UNIFORM_BUFFER, material_ubo);
|
||||||
glBufferData(GL_UNIFORM_BUFFER, sizeof(MaterialUniforms), &MaterialData, GL_STREAM_DRAW); //Allocate memory for the buffer, but don't copy (since pointer is null).
|
glBufferData(GL_UNIFORM_BUFFER, sizeof(MaterialUniforms), &MaterialData, GL_STREAM_DRAW); //Allocate memory for the buffer, but don't copy (since pointer is null).
|
||||||
glBindBufferBase(GL_UNIFORM_BUFFER, UboBinding::material, materialUbo); //Associate this uniform buffer with the uniform block in the shader that has the same binding.
|
glBindBufferBase(GL_UNIFORM_BUFFER, UboBinding::material, material_ubo); //Associate this uniform buffer with the uniform block in the shader that has the same binding.
|
||||||
|
|
||||||
glGenBuffers(1, &geoUbo);
|
|
||||||
glBindBuffer(GL_UNIFORM_BUFFER, geoUbo);
|
|
||||||
glBufferData(GL_UNIFORM_BUFFER, sizeof(GeoUniforms), &GeoData, GL_STREAM_DRAW); //Allocate memory for the buffer, but don't copy (since pointer is null).
|
|
||||||
glBindBufferBase(GL_UNIFORM_BUFFER, UboBinding::geometry, geoUbo); //Associate this uniform buffer with the uniform block in the shader that has the same binding.
|
|
||||||
|
|
||||||
glBindBuffer(GL_UNIFORM_BUFFER, 0);
|
glBindBuffer(GL_UNIFORM_BUFFER, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
void BufferSceneData()
|
void BufferSceneData()
|
||||||
{
|
{
|
||||||
glBindBuffer(GL_UNIFORM_BUFFER, sceneUbo); //Bind the OpenGL UBO before we update the data.
|
glBindBuffer(GL_UNIFORM_BUFFER, scene_ubo); //Bind the OpenGL UBO before we update the data.
|
||||||
glBufferSubData(GL_UNIFORM_BUFFER, 0, sizeof(SceneData), &SceneData); //Upload the new uniform values.
|
glBufferSubData(GL_UNIFORM_BUFFER, 0, sizeof(SceneData), &SceneData); //Upload the new uniform values.
|
||||||
glBindBuffer(GL_UNIFORM_BUFFER, 0); //unbind the ubo
|
glBindBuffer(GL_UNIFORM_BUFFER, 0); //unbind the ubo
|
||||||
|
|
||||||
glBindBuffer(GL_UNIFORM_BUFFER, geoUbo); //Bind the OpenGL UBO before we update the data.
|
|
||||||
glBufferSubData(GL_UNIFORM_BUFFER, 0, sizeof(GeoData), &GeoData); //Upload the new uniform values.
|
|
||||||
glBindBuffer(GL_UNIFORM_BUFFER, 0); //unbind the ubo
|
|
||||||
}
|
}
|
||||||
};
|
};
|
|
@ -1,7 +1,6 @@
|
||||||
#include <glm/glm.hpp>
|
#include <glm/glm.hpp>
|
||||||
|
|
||||||
#include "callbacks.h"
|
#include "callbacks.h"
|
||||||
#include "interface.h"
|
|
||||||
|
|
||||||
namespace Callbacks {
|
namespace Callbacks {
|
||||||
Scene* scene_ = nullptr;
|
Scene* scene_ = nullptr;
|
||||||
|
@ -53,17 +52,11 @@ void Callbacks::MouseButton(GLFWwindow* window, int button, int action, int mods
|
||||||
|
|
||||||
void Callbacks::Resize(GLFWwindow* window, int width, int height)
|
void Callbacks::Resize(GLFWwindow* window, int width, int height)
|
||||||
{
|
{
|
||||||
Window* viewport = Interface::GetWindowByName(scene_->windows_, "Viewport");
|
width = glm::max(1, width);
|
||||||
|
height = glm::max(1, height);
|
||||||
scene_->window_width = static_cast<int>(viewport->size.x);
|
//Set viewport to cover entire framebuffer
|
||||||
scene_->window_height = static_cast<int>(viewport->size.y);
|
glViewport(0, 0, width, height);
|
||||||
|
|
||||||
scene_->OnScreenResize(viewport);
|
|
||||||
|
|
||||||
//Set aspect ratio used in view matrix calculation
|
//Set aspect ratio used in view matrix calculation
|
||||||
// scene_->window_width = width;
|
|
||||||
// scene_->window_height = height;
|
|
||||||
// scene_->Scene::UpdateCamera();
|
|
||||||
//Scene::Camera::Aspect = float(width) / float(height);
|
//Scene::Camera::Aspect = float(width) / float(height);
|
||||||
//Scene::Camera::UpdateP();
|
//Scene::Camera::UpdateP();
|
||||||
}
|
}
|
|
@ -54,13 +54,6 @@ namespace FBO {
|
||||||
Framebuffer GenerateFramebuffer(int width, int height) {
|
Framebuffer GenerateFramebuffer(int width, int height) {
|
||||||
Framebuffer fbo;
|
Framebuffer fbo;
|
||||||
fbo.id = CreateFramebuffer();
|
fbo.id = CreateFramebuffer();
|
||||||
|
|
||||||
UpdateFrameBuffer(fbo, width, height);
|
|
||||||
|
|
||||||
return fbo;
|
|
||||||
}
|
|
||||||
|
|
||||||
void UpdateFrameBuffer(Framebuffer& fbo, int width, int height) {
|
|
||||||
glBindFramebuffer(GL_FRAMEBUFFER, fbo.id);
|
glBindFramebuffer(GL_FRAMEBUFFER, fbo.id);
|
||||||
|
|
||||||
fbo.albedoTexture = CreateTexture(width, height, GL_RGBA);
|
fbo.albedoTexture = CreateTexture(width, height, GL_RGBA);
|
||||||
|
@ -80,6 +73,8 @@ namespace FBO {
|
||||||
}
|
}
|
||||||
|
|
||||||
glBindFramebuffer(GL_FRAMEBUFFER, 0);
|
glBindFramebuffer(GL_FRAMEBUFFER, 0);
|
||||||
|
|
||||||
|
return fbo;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Bind(const Framebuffer& fbo) {
|
void Bind(const Framebuffer& fbo) {
|
||||||
|
|
|
@ -1,107 +0,0 @@
|
||||||
#include "interface.h"
|
|
||||||
|
|
||||||
#include <imgui_impl_glfw.h>
|
|
||||||
#include <imgui_impl_opengl3.h>
|
|
||||||
#include <algorithm>
|
|
||||||
#include <iostream>
|
|
||||||
#include <filesystem>
|
|
||||||
|
|
||||||
namespace Interface {
|
|
||||||
|
|
||||||
void ApplyUIScaling(GLFWwindow* window) {
|
|
||||||
float xScale, yScale;
|
|
||||||
glfwGetWindowContentScale(window, &xScale, &yScale);
|
|
||||||
|
|
||||||
float scale = (xScale + yScale) * 0.5f;
|
|
||||||
|
|
||||||
ImGui::GetIO().FontGlobalScale = scale;
|
|
||||||
ImGuiStyle& style = ImGui::GetStyle();
|
|
||||||
style.ScaleAllSizes(scale);
|
|
||||||
|
|
||||||
ImGuiIO& io = ImGui::GetIO();
|
|
||||||
io.Fonts->Clear();
|
|
||||||
|
|
||||||
#ifdef _WIN32
|
|
||||||
io.Fonts->AddFontFromFileTTF("imgui/misc/fonts/JetBrainsMono/JetBrainsMono-Medium.ttf", 8.0f * scale);
|
|
||||||
#else
|
|
||||||
io.Fonts->AddFontFromFileTTF("../imgui/misc/fonts/JetBrainsMono/JetBrainsMono-Medium.ttf", 8.0f * scale);
|
|
||||||
#endif
|
|
||||||
io.Fonts->Build();
|
|
||||||
}
|
|
||||||
|
|
||||||
void AddWindow(std::vector<Window>& windows, const std::string& name, std::function<void()> renderFunc) {
|
|
||||||
windows.emplace_back(name, renderFunc);
|
|
||||||
}
|
|
||||||
|
|
||||||
Window* GetWindowByName(std::vector<Window>& windows, const std::string& name) {
|
|
||||||
auto it = std::find_if(windows.begin(), windows.end(), [&name](const Window& window) {
|
|
||||||
return window.name == name;
|
|
||||||
});
|
|
||||||
|
|
||||||
if (it != windows.end()) {
|
|
||||||
return &(*it); // Return pointer to the found window
|
|
||||||
} else {
|
|
||||||
return nullptr; // Return nullptr if the window was not found
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void RenderWindows(std::vector<Window>& windows) {
|
|
||||||
ImGui_ImplOpenGL3_NewFrame();
|
|
||||||
ImGui_ImplGlfw_NewFrame();
|
|
||||||
|
|
||||||
ImGuiIO& io = ImGui::GetIO();
|
|
||||||
io.ConfigFlags |= ImGuiConfigFlags_DockingEnable;
|
|
||||||
|
|
||||||
ImGui::NewFrame();
|
|
||||||
|
|
||||||
static ImGuiDockNodeFlags dockspace_flags = ImGuiDockNodeFlags_PassthruCentralNode;
|
|
||||||
ImGuiWindowFlags window_flags = ImGuiWindowFlags_MenuBar | ImGuiWindowFlags_NoDocking;
|
|
||||||
|
|
||||||
// Style windows
|
|
||||||
const ImGuiViewport* viewport = ImGui::GetMainViewport();
|
|
||||||
ImGui::SetNextWindowPos(viewport->WorkPos);
|
|
||||||
ImGui::SetNextWindowSize(viewport->WorkSize);
|
|
||||||
ImGui::SetNextWindowViewport(viewport->ID);
|
|
||||||
ImGui::PushStyleVar(ImGuiStyleVar_WindowRounding, 0.0f);
|
|
||||||
ImGui::PushStyleVar(ImGuiStyleVar_WindowBorderSize, 0.0f);
|
|
||||||
window_flags |= ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_NoCollapse | ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoMove;
|
|
||||||
window_flags |= ImGuiWindowFlags_NoBringToFrontOnFocus | ImGuiWindowFlags_NoNavFocus;
|
|
||||||
window_flags |= ImGuiWindowFlags_NoBackground;
|
|
||||||
|
|
||||||
ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, ImVec2(0.0f, 0.0f));
|
|
||||||
ImGui::Begin("TerraVisor", nullptr, window_flags);
|
|
||||||
ImGui::PopStyleVar(3);
|
|
||||||
|
|
||||||
// Submit the DockSpace
|
|
||||||
if (io.ConfigFlags & ImGuiConfigFlags_DockingEnable) {
|
|
||||||
ImGuiID dockspace_id = ImGui::GetID("MyDockSpace");
|
|
||||||
ImGui::DockSpace(dockspace_id, ImVec2(0.0f, 0.0f), dockspace_flags);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ImGui::BeginMenuBar()) {
|
|
||||||
if (ImGui::BeginMenu("Options")) {
|
|
||||||
ImGui::Text("Nothing Here Yet, Check Back Later!");
|
|
||||||
|
|
||||||
ImGui::EndMenu();
|
|
||||||
}
|
|
||||||
|
|
||||||
ImGui::EndMenuBar();
|
|
||||||
}
|
|
||||||
|
|
||||||
ImGui::End();
|
|
||||||
|
|
||||||
for (auto& window : windows) {
|
|
||||||
if (window.isOpen && ImGui::Begin(window.name.c_str(), &window.isOpen)) {
|
|
||||||
window.size = ImGui::GetWindowSize();
|
|
||||||
window.position = ImGui::GetWindowPos();
|
|
||||||
if (window.renderContent) {
|
|
||||||
window.renderContent();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
ImGui::End();
|
|
||||||
}
|
|
||||||
|
|
||||||
ImGui::Render();
|
|
||||||
ImGui_ImplOpenGL3_RenderDrawData(ImGui::GetDrawData());
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -28,8 +28,6 @@
|
||||||
#include <GL/glew.h>
|
#include <GL/glew.h>
|
||||||
#include <GLFW/glfw3.h>
|
#include <GLFW/glfw3.h>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <string>
|
|
||||||
#include <sstream>
|
|
||||||
#include <chrono>
|
#include <chrono>
|
||||||
#include <thread>
|
#include <thread>
|
||||||
|
|
||||||
|
@ -39,10 +37,8 @@
|
||||||
|
|
||||||
#include <FreeImage.h>
|
#include <FreeImage.h>
|
||||||
|
|
||||||
#include "config.h"
|
|
||||||
#include "callbacks.h"
|
#include "callbacks.h"
|
||||||
#include "scene.h"
|
#include "scene.h"
|
||||||
#include "interface.h"
|
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
|
@ -65,11 +61,7 @@ GLFWwindow* CreateGlfwWindow() {
|
||||||
glfwWindowHint(GLFW_OPENGL_DEBUG_CONTEXT, GL_TRUE);
|
glfwWindowHint(GLFW_OPENGL_DEBUG_CONTEXT, GL_TRUE);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
std::stringstream ss;
|
GLFWwindow* window = glfwCreateWindow(kInitWindowWidth, kInitWindowHeight, "TerraVisor", nullptr, nullptr);
|
||||||
ss << PROJECT_NAME << " " << PROJECT_VERSION_MAJOR << "." << PROJECT_VERSION_MINOR << "." << PROJECT_VERSION_PATCH;
|
|
||||||
|
|
||||||
std::string title = ss.str();
|
|
||||||
GLFWwindow* window = glfwCreateWindow(kInitWindowWidth, kInitWindowHeight, title.c_str(), nullptr, nullptr);
|
|
||||||
if (!window) {
|
if (!window) {
|
||||||
std::cerr << "Failed to create GLFW window" << std::endl;
|
std::cerr << "Failed to create GLFW window" << std::endl;
|
||||||
glfwTerminate();
|
glfwTerminate();
|
||||||
|
@ -157,7 +149,6 @@ int main() {
|
||||||
scene.Init();
|
scene.Init();
|
||||||
InitializeImGui(window);
|
InitializeImGui(window);
|
||||||
FreeImage_Initialise();
|
FreeImage_Initialise();
|
||||||
Interface::ApplyUIScaling(window);
|
|
||||||
|
|
||||||
// Check if we're in test mode
|
// Check if we're in test mode
|
||||||
const char* testEnv = std::getenv("TEST_MODE");
|
const char* testEnv = std::getenv("TEST_MODE");
|
||||||
|
|
125
source/scene.cpp
125
source/scene.cpp
|
@ -9,6 +9,10 @@
|
||||||
#include <glm/gtx/transform.hpp>
|
#include <glm/gtx/transform.hpp>
|
||||||
#include <glm/gtc/type_ptr.hpp>
|
#include <glm/gtc/type_ptr.hpp>
|
||||||
|
|
||||||
|
#include <imgui.h>
|
||||||
|
#include <imgui_impl_glfw.h>
|
||||||
|
#include <imgui_impl_opengl3.h>
|
||||||
|
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
|
@ -21,11 +25,10 @@
|
||||||
|
|
||||||
#include "scene.h"
|
#include "scene.h"
|
||||||
#include "camera.h"
|
#include "camera.h"
|
||||||
#include "uniforms.h"
|
#include "Uniforms.h"
|
||||||
#include "InitShader.h"
|
#include "InitShader.h"
|
||||||
#include "DebugCallback.h"
|
#include "DebugCallback.h"
|
||||||
#include "load_texture.h"
|
#include "load_texture.h"
|
||||||
#include "interface.h"
|
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
|
@ -88,7 +91,6 @@ void Scene::Init() {
|
||||||
InitBuffers();
|
InitBuffers();
|
||||||
ReloadShader();
|
ReloadShader();
|
||||||
InitQuadBuffers();
|
InitQuadBuffers();
|
||||||
InitUI();
|
|
||||||
|
|
||||||
CameraControls::SetPosition(activeCamera_, glm::vec3(1.4f, 1.4f, 0.0f));
|
CameraControls::SetPosition(activeCamera_, glm::vec3(1.4f, 1.4f, 0.0f));
|
||||||
CameraControls::SetRotation(activeCamera_, -glm::normalize(CameraControls::GetPosition(activeCamera_)));
|
CameraControls::SetRotation(activeCamera_, -glm::normalize(CameraControls::GetPosition(activeCamera_)));
|
||||||
|
@ -137,7 +139,7 @@ void Scene::GenerateGrid(int divisions, std::vector<Vertex>& verts, std::vector<
|
||||||
|
|
||||||
// Currently creates a test triangle and initializes its buffers
|
// Currently creates a test triangle and initializes its buffers
|
||||||
void Scene::InitBuffers() {
|
void Scene::InitBuffers() {
|
||||||
int divisions = Uniforms::GeoData.gridDensity; // Number of divisions along one axis of the grid
|
int divisions = 16; // Number of divisions along one axis of the grid
|
||||||
GenerateGrid(divisions, vertices, indices);
|
GenerateGrid(divisions, vertices, indices);
|
||||||
|
|
||||||
// Create and bind VAO, VBO, and EBO, and pass the data to OpenGL
|
// Create and bind VAO, VBO, and EBO, and pass the data to OpenGL
|
||||||
|
@ -195,25 +197,6 @@ void Scene::InitQuadBuffers() {
|
||||||
glBindVertexArray(0);
|
glBindVertexArray(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Scene::InitUI() {
|
|
||||||
Interface::AddWindow(windows_, "Viewport", [this]() {
|
|
||||||
ImGui::Image((void*)(intptr_t)lht_fbo_.albedoTexture, ImVec2(window_width, window_height), ImVec2(0, 1), ImVec2(1, 0));
|
|
||||||
});
|
|
||||||
|
|
||||||
Interface::AddWindow(windows_, "Scene Settings", [this]() {
|
|
||||||
// if (ImGui::Button("Quit")) {
|
|
||||||
// glfwSetWindowShouldClose(window, GLFW_TRUE);
|
|
||||||
// }
|
|
||||||
|
|
||||||
ImGui::Text("Application average %.3f ms/frame (%.1f FPS)", 1000.0f / ImGui::GetIO().Framerate, ImGui::GetIO().Framerate);
|
|
||||||
|
|
||||||
ImGui::SliderFloat("Tessellation Level", &Uniforms::GeoData.maxTessellation, 1.0f, 64.0f);
|
|
||||||
ImGui::SliderInt("Patch Grid Density", &Uniforms::GeoData.gridDensity, 1, 24);
|
|
||||||
ImGui::SliderFloat("Max Height", &Uniforms::GeoData.displacementScale, 0.0f, 1.0f);
|
|
||||||
Window* viewport = Interface::GetWindowByName(windows_, "Viewport");
|
|
||||||
ImGui::Text("Viewport size: (%.3f, %.3f)", viewport->size.x, viewport->size.y);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
// Allows for runtime shader updates
|
// Allows for runtime shader updates
|
||||||
void Scene::ReloadShader() {
|
void Scene::ReloadShader() {
|
||||||
|
@ -240,17 +223,13 @@ void Scene::Display(GLFWwindow* window) {
|
||||||
|
|
||||||
glUseProgram(shader_program_);
|
glUseProgram(shader_program_);
|
||||||
|
|
||||||
// glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
|
//glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
|
||||||
|
|
||||||
Window* viewport = Interface::GetWindowByName(windows_, "Viewport");
|
Uniforms::SceneData.PV = projection_matrix_ * CameraControls::GetViewMatrix(activeCamera_); // Projection-View matrix
|
||||||
if (viewport && viewport->size.x > 0 && viewport->size.y > 0) {
|
|
||||||
OnScreenResize(viewport);
|
|
||||||
}
|
|
||||||
|
|
||||||
Uniforms::GeoData.PV = projection_matrix_ * CameraControls::GetViewMatrix(activeCamera_); // Projection-View matrix
|
|
||||||
Uniforms::BufferSceneData();
|
Uniforms::BufferSceneData();
|
||||||
|
|
||||||
Uniforms::GeoData.M = glm::rotate(angle_, glm::vec3(1.0f, 0.0f, 0.0f)) * glm::scale(glm::vec3(scale_));
|
glm::mat4 model_matrix = glm::rotate(angle_, glm::vec3(1.0f, 0.0f, 0.0f)) * glm::scale(glm::vec3(scale_));
|
||||||
|
glUniformMatrix4fv(Uniforms::UniformLocs::M, 1, false, glm::value_ptr(model_matrix));
|
||||||
|
|
||||||
glActiveTexture(GL_TEXTURE0);
|
glActiveTexture(GL_TEXTURE0);
|
||||||
glBindTexture(GL_TEXTURE_2D, tex_id);
|
glBindTexture(GL_TEXTURE_2D, tex_id);
|
||||||
|
@ -269,9 +248,7 @@ void Scene::Display(GLFWwindow* window) {
|
||||||
glPatchParameteri(GL_PATCH_VERTICES, 4);
|
glPatchParameteri(GL_PATCH_VERTICES, 4);
|
||||||
glDrawElements(GL_PATCHES, indices.size(), GL_UNSIGNED_INT, 0);
|
glDrawElements(GL_PATCHES, indices.size(), GL_UNSIGNED_INT, 0);
|
||||||
|
|
||||||
FBO::Unbind();
|
//glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
|
||||||
|
|
||||||
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
|
|
||||||
|
|
||||||
FBO::Bind(lht_fbo_);
|
FBO::Bind(lht_fbo_);
|
||||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||||
|
@ -298,24 +275,78 @@ void Scene::Display(GLFWwindow* window) {
|
||||||
|
|
||||||
FBO::Unbind();
|
FBO::Unbind();
|
||||||
|
|
||||||
//DrawGui(window);
|
DrawGui(window);
|
||||||
Interface::RenderWindows(windows_);
|
|
||||||
glfwSwapBuffers(window);
|
glfwSwapBuffers(window);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Scene::OnScreenResize(Window* viewport) {
|
void Scene::DrawGui(GLFWwindow* window) {
|
||||||
if (window_width != static_cast<int>(viewport->size.x) || window_height != static_cast<int>(viewport->size.y)) {
|
// Begin ImGui frame
|
||||||
window_width = static_cast<int>(viewport->size.x);
|
ImGui_ImplOpenGL3_NewFrame();
|
||||||
window_height = static_cast<int>(viewport->size.y);
|
ImGui_ImplGlfw_NewFrame();
|
||||||
|
|
||||||
UpdateCamera();
|
// Enable docking
|
||||||
|
ImGuiIO& io = ImGui::GetIO();
|
||||||
|
io.ConfigFlags |= ImGuiConfigFlags_DockingEnable;
|
||||||
|
|
||||||
|
ImGui::NewFrame();
|
||||||
|
|
||||||
|
static ImGuiDockNodeFlags dockspace_flags = ImGuiDockNodeFlags_PassthruCentralNode;
|
||||||
|
|
||||||
|
// Add menu bar
|
||||||
|
ImGuiWindowFlags window_flags = ImGuiWindowFlags_MenuBar | ImGuiWindowFlags_NoDocking;
|
||||||
|
|
||||||
|
// Style windows
|
||||||
|
const ImGuiViewport* viewport = ImGui::GetMainViewport();
|
||||||
|
ImGui::SetNextWindowPos(viewport->WorkPos);
|
||||||
|
ImGui::SetNextWindowSize(viewport->WorkSize);
|
||||||
|
ImGui::SetNextWindowViewport(viewport->ID);
|
||||||
|
ImGui::PushStyleVar(ImGuiStyleVar_WindowRounding, 0.0f);
|
||||||
|
ImGui::PushStyleVar(ImGuiStyleVar_WindowBorderSize, 0.0f);
|
||||||
|
window_flags |= ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_NoCollapse | ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoMove;
|
||||||
|
window_flags |= ImGuiWindowFlags_NoBringToFrontOnFocus | ImGuiWindowFlags_NoNavFocus;
|
||||||
|
window_flags |= ImGuiWindowFlags_NoBackground;
|
||||||
|
|
||||||
|
ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, ImVec2(0.0f, 0.0f));
|
||||||
|
ImGui::Begin("TerraVisor", nullptr, window_flags);
|
||||||
|
ImGui::PopStyleVar(3);
|
||||||
|
|
||||||
|
// Submit the DockSpace
|
||||||
|
if (io.ConfigFlags & ImGuiConfigFlags_DockingEnable) {
|
||||||
|
ImGuiID dockspace_id = ImGui::GetID("MyDockSpace");
|
||||||
|
ImGui::DockSpace(dockspace_id, ImVec2(0.0f, 0.0f), dockspace_flags);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
void Scene::UpdateViewport() {
|
if (ImGui::BeginMenuBar()) {
|
||||||
window_width = ImGui::GetWindowSize().x;
|
if (ImGui::BeginMenu("Options")) {
|
||||||
window_height = ImGui::GetWindowSize().y;
|
ImGui::Text("Nothing Here Yet, Check Back Later!");
|
||||||
UpdateCamera();
|
|
||||||
|
ImGui::EndMenu();
|
||||||
|
}
|
||||||
|
|
||||||
|
ImGui::EndMenuBar();
|
||||||
|
}
|
||||||
|
|
||||||
|
ImGui::End();
|
||||||
|
|
||||||
|
// Draw Gui
|
||||||
|
ImGui::Begin("Terrain Controls");
|
||||||
|
if (ImGui::Button("Quit")) {
|
||||||
|
glfwSetWindowShouldClose(window, GLFW_TRUE);
|
||||||
|
}
|
||||||
|
|
||||||
|
ImGui::Text("Application average %.3f ms/frame (%.1f FPS)", 1000.0f / ImGui::GetIO().Framerate, ImGui::GetIO().Framerate);
|
||||||
|
|
||||||
|
ImGui::SliderFloat("Tessellation Level", &tessellationFactor, 1.0f, 64.0f);
|
||||||
|
ImGui::End();
|
||||||
|
|
||||||
|
// Draw FBO to ImGui window
|
||||||
|
ImGui::Begin("Scene Window");
|
||||||
|
ImVec2 windowSize = ImGui::GetContentRegionAvail();
|
||||||
|
ImGui::Image((void*)(intptr_t)lht_fbo_.albedoTexture, windowSize, ImVec2(0, 1), ImVec2(1, 0));
|
||||||
|
ImGui::End();
|
||||||
|
|
||||||
|
ImGui::Render();
|
||||||
|
ImGui_ImplOpenGL3_RenderDrawData(ImGui::GetDrawData());
|
||||||
}
|
}
|
||||||
|
|
||||||
void Scene::Idle() {
|
void Scene::Idle() {
|
||||||
|
@ -352,7 +383,7 @@ std::vector<int16_t> Scene::LoadHGT(const std::string& filename, int width, int
|
||||||
}
|
}
|
||||||
|
|
||||||
void Scene::UpdateCamera() {
|
void Scene::UpdateCamera() {
|
||||||
projection_matrix_ = glm::perspective(CameraControls::GetFOV(activeCamera_), static_cast<float>(window_width) / window_height, activeCamera_.nearPlane, activeCamera_.farPlane);
|
projection_matrix_ = glm::perspective(CameraControls::GetFOV(activeCamera_), aspect_, activeCamera_.nearPlane, activeCamera_.farPlane);
|
||||||
}
|
}
|
||||||
|
|
||||||
GLuint Scene::CreateHeightmapTexture(std::vector<int16_t> data, int width, int height) {
|
GLuint Scene::CreateHeightmapTexture(std::vector<int16_t> data, int width, int height) {
|
||||||
|
|
Loading…
Reference in New Issue