aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authordec05eba <dec05eba@protonmail.com>2020-02-19 22:14:12 +0100
committerdec05eba <dec05eba@protonmail.com>2021-11-18 15:22:10 +0100
commit8d9b24b1b84107c90a77d94c86a810cc068fe073 (patch)
tree5f06bd2f1690080b9f18727ec832bcb65770b4ff
parent92a30e08849f45fa6f5efb1dd8897a4a69c063a6 (diff)
Fix rendering of texture with multiple frames
-rw-r--r--heightmap.jpgbin0 -> 56920 bytes
-rw-r--r--include/RenderBackend/OpenGL/DeviceFrame.hpp26
-rw-r--r--include/RenderBackend/OpenGL/DeviceMemory.hpp37
-rw-r--r--include/RenderBackend/OpenGL/ShaderFrame.hpp35
-rw-r--r--include/RenderBackend/OpenGL/ShaderProgram.hpp14
-rw-r--r--include/RenderBackend/OpenGL/Texture2D.hpp3
-rw-r--r--include/RenderBackend/OpenGL/Uniform.hpp2
-rw-r--r--shaders/fragment.frag1
-rw-r--r--shaders/sand_fragment.frag6
-rw-r--r--shaders/sand_vertex.vert8
-rw-r--r--src/RenderBackend/OpenGL/DeviceFrame.cpp39
-rw-r--r--src/RenderBackend/OpenGL/DeviceMemory.cpp80
-rw-r--r--src/RenderBackend/OpenGL/ShaderFrame.cpp54
-rw-r--r--src/RenderBackend/OpenGL/ShaderProgram.cpp57
-rw-r--r--src/RenderBackend/OpenGL/Texture2D.cpp24
-rw-r--r--src/main.cpp126
16 files changed, 262 insertions, 250 deletions
diff --git a/heightmap.jpg b/heightmap.jpg
new file mode 100644
index 0000000..e03ecc0
--- /dev/null
+++ b/heightmap.jpg
Binary files differ
diff --git a/include/RenderBackend/OpenGL/DeviceFrame.hpp b/include/RenderBackend/OpenGL/DeviceFrame.hpp
deleted file mode 100644
index 3fa7fe7..0000000
--- a/include/RenderBackend/OpenGL/DeviceFrame.hpp
+++ /dev/null
@@ -1,26 +0,0 @@
-#pragma once
-
-#include "../../types.hpp"
-#include "../../utils.hpp"
-#include <vector>
-
-namespace amalgine
-{
- class DeviceMemory;
- class ShaderProgram;
-
- class DeviceFrame
- {
- DISABLE_COPY(DeviceFrame)
- public:
- DeviceFrame();
- ~DeviceFrame();
-
- // The returned pointers cleaned when the frame is cleaned. Do not deallocate the returned pointer!
- DeviceMemory* alloc();
- void draw(ShaderProgram *shader);
- private:
- u32 vertexArrayObjectId;
- std::vector<DeviceMemory*> buffers;
- };
-}
diff --git a/include/RenderBackend/OpenGL/DeviceMemory.hpp b/include/RenderBackend/OpenGL/DeviceMemory.hpp
index 5f593fc..802230d 100644
--- a/include/RenderBackend/OpenGL/DeviceMemory.hpp
+++ b/include/RenderBackend/OpenGL/DeviceMemory.hpp
@@ -5,6 +5,8 @@
#include "../../Triangle.hpp"
#include "../../Vec.hpp"
+#include <memory>
+
namespace amalgine {
enum class DeviceMemoryType {
NONE,
@@ -12,11 +14,10 @@ namespace amalgine {
VEC3
};
- class DeviceMemory
- {
+ class DeviceMemory {
DISABLE_COPY(DeviceMemory)
- friend class DeviceFrame;
- friend class ShaderProgram;
+ friend class ShaderFrame;
+ friend class std::default_delete<DeviceMemory>;
public:
enum class StorageType
{
@@ -30,26 +31,20 @@ namespace amalgine {
STREAM
};
- enum class PrimitiveType
- {
- TRIANGLE
- };
-
- //void copy(const DataView<f32> &data, StorageType storageType, PrimitiveType primitiveType = PrimitiveType::TRIANGLE);
- void copy(const DataView<vec2f> &texture_coords, StorageType storageType);
- void copy(const DataView<Triangle2D> &triangles, StorageType storageType);
- void copy(const DataView<Triangle3D> &triangles, StorageType storageType);
- void draw();
+ void set(const DataView<vec2f> &texture_coords, StorageType storageType);
+ void set(const DataView<Triangle2D> &triangles, StorageType storageType);
+ void set(const DataView<Triangle3D> &triangles, StorageType storageType);
- DeviceMemoryType get_type() const { return type; }
+ i32 get_num_vertices() const { return num_vertices; }
private:
- DeviceMemory();
+ DeviceMemory(u32 vertex_array_object_id, i32 attrib_location);
~DeviceMemory();
- void use() const;
+ void use();
private:
- u32 vertexBufferObjectId;
- u32 primitiveType;
- u32 numVertices;
- DeviceMemoryType type;
+ u32 vertex_array_object_id;
+ u32 vertex_buffer_object_id;
+ i32 attrib_location;
+ i32 num_vertices;
+ DeviceMemoryType memory_type;
};
}
diff --git a/include/RenderBackend/OpenGL/ShaderFrame.hpp b/include/RenderBackend/OpenGL/ShaderFrame.hpp
new file mode 100644
index 0000000..da0918e
--- /dev/null
+++ b/include/RenderBackend/OpenGL/ShaderFrame.hpp
@@ -0,0 +1,35 @@
+#pragma once
+
+#include "../../Result.hpp"
+#include "../../types.hpp"
+#include "../../utils.hpp"
+#include "Uniform.hpp"
+#include "DeviceMemory.hpp"
+
+#include <map>
+#include <memory>
+#include <string>
+
+namespace amalgine {
+ class ShaderFrame {
+ DISABLE_COPY(ShaderFrame)
+ friend class ShaderProgram;
+ public:
+ ~ShaderFrame();
+ ShaderFrame(ShaderFrame &&other) = default;
+ ShaderFrame& operator=(ShaderFrame &&other) = default;
+
+ DeviceMemory* get_input_by_name(const char *name);
+ Result<Uniform> get_uniform_by_name(const char *name);
+
+ void draw();
+ private:
+ ShaderFrame(u32 shader_program_id);
+ private:
+ u32 shader_program_id;
+ u32 vertex_array_object_id;
+
+ // TODO: Use a const char* as a key instead
+ std::map<std::string, std::unique_ptr<DeviceMemory>> shader_inputs;
+ };
+}
diff --git a/include/RenderBackend/OpenGL/ShaderProgram.hpp b/include/RenderBackend/OpenGL/ShaderProgram.hpp
index 177e43c..a1db6a0 100644
--- a/include/RenderBackend/OpenGL/ShaderProgram.hpp
+++ b/include/RenderBackend/OpenGL/ShaderProgram.hpp
@@ -3,14 +3,10 @@
#include "../../Result.hpp"
#include "../../types.hpp"
#include "../../utils.hpp"
-#include "../../Vec.hpp"
-#include "Uniform.hpp"
-#include "DeviceMemory.hpp"
+#include "ShaderFrame.hpp"
-#include <vector>
#include <memory>
-#include <glm/gtc/matrix_transform.hpp>
-#include <glm/gtc/type_ptr.hpp>
+#include <vector>
namespace amalgine {
class Shader;
@@ -21,11 +17,7 @@ namespace amalgine {
public:
~ShaderProgram();
static Result<std::unique_ptr<ShaderProgram>> build(const std::vector<Shader*> &shaders);
-
- Result<Uniform> get_uniform_by_name(const char *name);
- int set_input_data(const char *name, const DeviceMemory &data);
-
- void use();
+ ShaderFrame create_frame();
private:
ShaderProgram(u32 shader_program_id);
private:
diff --git a/include/RenderBackend/OpenGL/Texture2D.hpp b/include/RenderBackend/OpenGL/Texture2D.hpp
index 48b613b..c0bfbd2 100644
--- a/include/RenderBackend/OpenGL/Texture2D.hpp
+++ b/include/RenderBackend/OpenGL/Texture2D.hpp
@@ -11,9 +11,12 @@ namespace amalgine
{
DISABLE_COPY(Texture2D)
public:
+ Texture2D();
// Not thread safe
Texture2D(Image *image);
~Texture2D();
+ Texture2D(Texture2D &&other);
+ Texture2D& operator=(Texture2D &&other);
i32 get_texture_id() const { return texture_id; }
private:
diff --git a/include/RenderBackend/OpenGL/Uniform.hpp b/include/RenderBackend/OpenGL/Uniform.hpp
index dbffa03..d6e6e64 100644
--- a/include/RenderBackend/OpenGL/Uniform.hpp
+++ b/include/RenderBackend/OpenGL/Uniform.hpp
@@ -11,7 +11,7 @@
namespace amalgine {
class Uniform {
DISABLE_COPY(Uniform)
- friend class ShaderProgram;
+ friend class ShaderFrame;
friend class Result<Uniform>;
public:
Uniform(Uniform&&) = default;
diff --git a/shaders/fragment.frag b/shaders/fragment.frag
index b078a58..ee6106d 100644
--- a/shaders/fragment.frag
+++ b/shaders/fragment.frag
@@ -8,4 +8,5 @@ uniform sampler2D tex;
void main() {
out_color = texture(tex, texcoord_frag);
+ //out_color = vec4(1.0, 0.0, 0.0, 1.0);
} \ No newline at end of file
diff --git a/shaders/sand_fragment.frag b/shaders/sand_fragment.frag
index 60791c2..b078a58 100644
--- a/shaders/sand_fragment.frag
+++ b/shaders/sand_fragment.frag
@@ -1,9 +1,11 @@
#version 330 core
+in vec2 texcoord_frag;
+
out vec4 out_color;
-uniform vec3 triangle_color;
+uniform sampler2D tex;
void main() {
- out_color = vec4(triangle_color, 1.0);
+ out_color = texture(tex, texcoord_frag);
} \ No newline at end of file
diff --git a/shaders/sand_vertex.vert b/shaders/sand_vertex.vert
index f254dbc..8f746ad 100644
--- a/shaders/sand_vertex.vert
+++ b/shaders/sand_vertex.vert
@@ -1,15 +1,21 @@
#version 330 core
in vec3 position;
+in vec2 texcoord_vert;
+
+out vec2 texcoord_frag;
uniform float time;
uniform mat4 proj;
uniform mat4 view;
uniform mat4 model;
+uniform sampler2D tex;
void main() {
+ texcoord_frag = texcoord_vert;
vec3 pos = position;
- pos.z = sin(pos.x + time) * cos(pos.y + time);
+ //pos.z = sin(pos.x + time) * cos(pos.y + time);
+ pos.z = texture2D(tex, pos.xy).r * 0.05;
gl_Position = proj * view * model * vec4(pos, 1.0);
} \ No newline at end of file
diff --git a/src/RenderBackend/OpenGL/DeviceFrame.cpp b/src/RenderBackend/OpenGL/DeviceFrame.cpp
deleted file mode 100644
index 2132f83..0000000
--- a/src/RenderBackend/OpenGL/DeviceFrame.cpp
+++ /dev/null
@@ -1,39 +0,0 @@
-#include "../../../include/RenderBackend/OpenGL/DeviceFrame.hpp"
-#include "../../../include/RenderBackend/OpenGL/DeviceMemory.hpp"
-#include "../../../include/RenderBackend/OpenGL/opengl.hpp"
-#include "../../../include/RenderBackend/OpenGL/ShaderProgram.hpp"
-
-namespace amalgine
-{
- DeviceFrame::DeviceFrame()
- {
- glGenVertexArrays(1, &vertexArrayObjectId);
- }
-
- DeviceFrame::~DeviceFrame()
- {
- for(DeviceMemory *deviceMemory : buffers)
- {
- delete deviceMemory;
- }
- glDeleteVertexArrays(1, &vertexArrayObjectId);
- }
-
- DeviceMemory* DeviceFrame::alloc()
- {
- glBindVertexArray(vertexArrayObjectId);
- DeviceMemory *deviceMemory = new DeviceMemory();
- buffers.push_back(deviceMemory);
- return deviceMemory;
- }
-
- void DeviceFrame::draw(ShaderProgram *shader) {
- shader->use();
- //glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
- for(DeviceMemory *deviceMemory : buffers)
- {
- deviceMemory->draw();
- }
- //glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
- }
-}
diff --git a/src/RenderBackend/OpenGL/DeviceMemory.cpp b/src/RenderBackend/OpenGL/DeviceMemory.cpp
index a82cdaa..7447657 100644
--- a/src/RenderBackend/OpenGL/DeviceMemory.cpp
+++ b/src/RenderBackend/OpenGL/DeviceMemory.cpp
@@ -2,12 +2,9 @@
#include "../../../include/RenderBackend/OpenGL/opengl.hpp"
#include <cassert>
-namespace amalgine
-{
- u32 getOpenglStorageType(DeviceMemory::StorageType storageType)
- {
- switch(storageType)
- {
+namespace amalgine {
+ u32 getOpenglStorageType(DeviceMemory::StorageType storageType) {
+ switch(storageType) {
case DeviceMemory::StorageType::STATIC: return GL_STATIC_DRAW;
case DeviceMemory::StorageType::DYNAMIC: return GL_DYNAMIC_DRAW;
case DeviceMemory::StorageType::STREAM: return GL_STREAM_DRAW;
@@ -15,58 +12,47 @@ namespace amalgine
}
}
- DeviceMemory::DeviceMemory() : primitiveType(0), numVertices(0), type(DeviceMemoryType::NONE)
- {
- glGenBuffers(1, &vertexBufferObjectId);
+ DeviceMemory::DeviceMemory(u32 vertex_array_object_id, i32 attrib_location) :
+ vertex_array_object_id(vertex_array_object_id), vertex_buffer_object_id(-1), attrib_location(attrib_location),
+ num_vertices(0), memory_type(DeviceMemoryType::NONE) {
+ glGenBuffers(1, &vertex_buffer_object_id);
}
- DeviceMemory::~DeviceMemory()
- {
- glDeleteBuffers(1, &vertexBufferObjectId);
+ DeviceMemory::~DeviceMemory() {
+ glDeleteBuffers(1, &vertex_buffer_object_id);
}
- void DeviceMemory::use() const
- {
- // TODO: Bind vao here?
- glBindBuffer(GL_ARRAY_BUFFER, vertexBufferObjectId);
+ void DeviceMemory::use() {
+ glBindBuffer(GL_ARRAY_BUFFER, vertex_buffer_object_id);
}
- /*
- void DeviceMemory::copy(const DataView<f32> &data, StorageType storageType, PrimitiveType primitiveType)
- {
- glBindBuffer(GL_ARRAY_BUFFER, vertexBufferObjectId);
- glBufferData(GL_ARRAY_BUFFER, data.getByteSize(), data.data, getOpenglStorageType(storageType));
- this->primitiveType = getOpenglPrimitiveType(primitiveType);
- numVertices = getPrimitiveTypePointsPerVertices(primitiveType);
- }
- */
- void DeviceMemory::copy(const DataView<vec2f> &texture_coords, StorageType storageType) {
- glBindBuffer(GL_ARRAY_BUFFER, vertexBufferObjectId);
+
+ void DeviceMemory::set(const DataView<vec2f> &texture_coords, StorageType storageType) {
+ glBindBuffer(GL_ARRAY_BUFFER, vertex_buffer_object_id);
glBufferData(GL_ARRAY_BUFFER, texture_coords.getByteSize(), texture_coords.data, getOpenglStorageType(storageType));
- primitiveType = GL_TRIANGLES;
- numVertices = texture_coords.size * 2;
- type = DeviceMemoryType::VEC2;
+ num_vertices = texture_coords.size * 2;
+ memory_type = DeviceMemoryType::VEC2;
+
+ glBindVertexArray(vertex_array_object_id); // Encapsulate DeviceMemory (vertex buffer object) inside the active vertex array object
+ glVertexAttribPointer(attrib_location, 2, GL_FLOAT, GL_FALSE, 0, 0);
}
- void DeviceMemory::copy(const DataView<Triangle2D> &triangles, StorageType storageType)
- {
- glBindBuffer(GL_ARRAY_BUFFER, vertexBufferObjectId);
+ void DeviceMemory::set(const DataView<Triangle2D> &triangles, StorageType storageType) {
+ glBindBuffer(GL_ARRAY_BUFFER, vertex_buffer_object_id);
glBufferData(GL_ARRAY_BUFFER, triangles.getByteSize(), triangles.data, getOpenglStorageType(storageType));
- primitiveType = GL_TRIANGLES;
- numVertices = triangles.size * 2;
- type = DeviceMemoryType::VEC2;
+ num_vertices = triangles.size * 2;
+ memory_type = DeviceMemoryType::VEC2;
+
+ glBindVertexArray(vertex_array_object_id); // Encapsulate DeviceMemory (vertex buffer object) inside the active vertex array object
+ glVertexAttribPointer(attrib_location, 2, GL_FLOAT, GL_FALSE, 0, 0);
}
- void DeviceMemory::copy(const DataView<Triangle3D> &triangles, StorageType storageType)
- {
- glBindBuffer(GL_ARRAY_BUFFER, vertexBufferObjectId);
+ void DeviceMemory::set(const DataView<Triangle3D> &triangles, StorageType storageType) {
+ glBindBuffer(GL_ARRAY_BUFFER, vertex_buffer_object_id);
glBufferData(GL_ARRAY_BUFFER, triangles.getByteSize(), triangles.data, getOpenglStorageType(storageType));
- primitiveType = GL_TRIANGLES;
- numVertices = triangles.size * 3;
- type = DeviceMemoryType::VEC3;
- }
-
- void DeviceMemory::draw()
- {
- glDrawArrays(primitiveType, 0, numVertices);
+ num_vertices = triangles.size * 3;
+ memory_type = DeviceMemoryType::VEC3;
+
+ glBindVertexArray(vertex_array_object_id); // Encapsulate DeviceMemory (vertex buffer object) inside the active vertex array object
+ glVertexAttribPointer(attrib_location, 3, GL_FLOAT, GL_FALSE, 0, 0);
}
}
diff --git a/src/RenderBackend/OpenGL/ShaderFrame.cpp b/src/RenderBackend/OpenGL/ShaderFrame.cpp
new file mode 100644
index 0000000..3f7ff01
--- /dev/null
+++ b/src/RenderBackend/OpenGL/ShaderFrame.cpp
@@ -0,0 +1,54 @@
+#include "../../../include/RenderBackend/OpenGL/ShaderFrame.hpp"
+#include "../../../include/RenderBackend/OpenGL/opengl.hpp"
+
+namespace amalgine {
+ ShaderFrame::ShaderFrame(u32 shader_program_id) : shader_program_id(shader_program_id), vertex_array_object_id(-1) {
+ glGenVertexArrays(1, &vertex_array_object_id);
+ }
+
+ ShaderFrame::~ShaderFrame() {
+ glDeleteVertexArrays(1, &vertex_array_object_id);
+ }
+
+ DeviceMemory* ShaderFrame::get_input_by_name(const char *name) {
+ auto it = shader_inputs.find(name);
+ if(it != shader_inputs.end())
+ return it->second.get();
+
+ GLint attrib_location = glGetAttribLocation(shader_program_id, name);
+ if(attrib_location == -1) {
+ fprintf(stderr, "No such attribute in shader: %s\n", name);
+ return nullptr;
+ }
+
+ glBindVertexArray(vertex_array_object_id); // Encapsulate DeviceMemory (vertex buffer object) inside the active vertex array object
+ DeviceMemory *device_memory_ptr = new DeviceMemory(vertex_array_object_id, attrib_location);
+ std::unique_ptr<DeviceMemory> device_memory(device_memory_ptr);
+ device_memory->use();
+ glEnableVertexAttribArray(attrib_location);
+
+ shader_inputs[name] = std::move(device_memory);
+ return device_memory_ptr;
+ }
+
+ Result<Uniform> ShaderFrame::get_uniform_by_name(const char *name) {
+ GLint uniform_id = glGetUniformLocation(shader_program_id, name);
+ if(uniform_id == -1)
+ return Result<Uniform>::Err(std::string("Uniform with name ") + name + " was not found");
+
+ Uniform uniform(uniform_id, shader_program_id);
+ return Result<Uniform>::Ok(std::move(uniform));
+ }
+
+ void ShaderFrame::draw() {
+ glUseProgram(shader_program_id);
+ glBindVertexArray(vertex_array_object_id); // Set the active shader to use the data encapsulated by the vertex array object
+ // TODO: Cache this num_vertices count (and reset it when device memory has changed)
+ int num_vertices = 0;
+ for(const auto &it : shader_inputs) {
+ num_vertices = std::max(num_vertices, it.second->get_num_vertices());
+ }
+ // TODO: Allow specifying mode different than GL_TRIANGLES
+ glDrawArrays(GL_TRIANGLES, 0, num_vertices);
+ }
+}
diff --git a/src/RenderBackend/OpenGL/ShaderProgram.cpp b/src/RenderBackend/OpenGL/ShaderProgram.cpp
index 7990a82..ba0e6dd 100644
--- a/src/RenderBackend/OpenGL/ShaderProgram.cpp
+++ b/src/RenderBackend/OpenGL/ShaderProgram.cpp
@@ -28,26 +28,6 @@ namespace amalgine {
delete []attachedShaders;
}
- #if 0
- bool ShaderProgram::setPixelShader(CompiledPixelShader *pixelShader)
- {
- if(!pixelShader) return false;
-
- // TODO: Do not allow adding shader if the program has already been built
- glAttachShader(shaderProgramId, pixelShader->getShaderId());
-
- const auto &pixelAttributes = pixelShader->getPixelAttributes();
- for(const auto &pixelAttribute : pixelAttributes)
- {
- const string &attributeName = pixelAttribute.first;
- i32 attributeLocation = pixelAttribute.second;
- glBindFragDataLocation(shaderProgramId, attributeLocation, attributeName.c_str());
- }
-
- return true;
- }
- #endif
-
// static
Result<std::unique_ptr<ShaderProgram>> ShaderProgram::build(const std::vector<Shader*> &shaders) {
u32 shader_program_id = glCreateProgram();
@@ -64,40 +44,7 @@ namespace amalgine {
return Result<std::unique_ptr<ShaderProgram>>::Ok(std::move(shader_program));
}
- Result<Uniform> ShaderProgram::get_uniform_by_name(const char *name) {
- GLint uniform_id = glGetUniformLocation(program_id, name);
- if(uniform_id == -1)
- return Result<Uniform>::Err(std::string("Uniform with name ") + name + " was not found");
-
- Uniform uniform(uniform_id, program_id);
- return Result<Uniform>::Ok(std::move(uniform));
- }
-
- int ShaderProgram::set_input_data(const char *name, const DeviceMemory &data) {
- GLint attrib_location = glGetAttribLocation(program_id, name);
- if(attrib_location == -1) {
- fprintf(stderr, "No such attribute in shader: %s\n", name);
- return -1;
- }
-
- data.use();
- glEnableVertexAttribArray(attrib_location);
- switch(data.get_type()) {
- case DeviceMemoryType::NONE:
- return -1;
- case DeviceMemoryType::VEC2: {
- glVertexAttribPointer(attrib_location, 2, GL_FLOAT, GL_FALSE, 0, 0);
- break;
- }
- case DeviceMemoryType::VEC3: {
- glVertexAttribPointer(attrib_location, 3, GL_FLOAT, GL_FALSE, 0, 0);
- break;
- }
- }
- return 0;
- }
-
- void ShaderProgram::use() {
- glUseProgram(program_id);
+ ShaderFrame ShaderProgram::create_frame() {
+ return { program_id };
}
}
diff --git a/src/RenderBackend/OpenGL/Texture2D.cpp b/src/RenderBackend/OpenGL/Texture2D.cpp
index dcb9cef..f4326a8 100644
--- a/src/RenderBackend/OpenGL/Texture2D.cpp
+++ b/src/RenderBackend/OpenGL/Texture2D.cpp
@@ -39,6 +39,10 @@ namespace amalgine {
static TextureIdAllocator *texture_id_allocator = nullptr;
+ Texture2D::Texture2D() : texture_id(-1), texture_ref(-1) {
+
+ }
+
Texture2D::Texture2D(Image *image)
{
assert(image);
@@ -46,6 +50,8 @@ namespace amalgine {
texture_id_allocator = new TextureIdAllocator();
texture_id = texture_id_allocator->get_free_texture_id();
+ printf("texture id: %d\n", texture_id);
+ texture_ref = -1;
glGenTextures(1, &texture_ref);
glActiveTexture(GL_TEXTURE0 + texture_id);
glBindTexture(GL_TEXTURE_2D, texture_ref);
@@ -60,7 +66,21 @@ namespace amalgine {
Texture2D::~Texture2D()
{
- texture_id_allocator->free_texture_id(texture_id);
- glDeleteTextures(1, &texture_ref);
+ if(texture_ref != -1) {
+ texture_id_allocator->free_texture_id(texture_id);
+ glDeleteTextures(1, &texture_ref);
+ }
+ }
+
+ Texture2D::Texture2D(Texture2D &&other) {
+ this->operator=(std::move(other));
+ }
+
+ Texture2D& Texture2D::operator=(Texture2D &&other) {
+ texture_id = other.texture_id;
+ texture_ref = other.texture_ref;
+ other.texture_id = -1;
+ other.texture_ref = -1;
+ return *this;
}
}
diff --git a/src/main.cpp b/src/main.cpp
index 22bfe1c..a2ea0b8 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -2,7 +2,6 @@
#include "../include/RenderBackend/OpenGL/Shader.hpp"
#include "../include/RenderBackend/OpenGL/ShaderProgram.hpp"
#include "../include/RenderBackend/OpenGL/DeviceMemory.hpp"
-#include "../include/RenderBackend/OpenGL/DeviceFrame.hpp"
#include "../include/RenderBackend/OpenGL/Texture2D.hpp"
#include "../include/Image.hpp"
#include "../include/Triangle.hpp"
@@ -34,24 +33,27 @@ static std::vector<Triangle3D> generate_sand() {
const int columns = 50;
std::vector<Triangle3D> vertices(rows * columns * 2);
int i = 0;
- float div = 0.3f;
+ float div = 1.0f / (float)rows;
for(int y = 0; y < rows; ++y) {
for(int x = 0; x < columns; ++x) {
vertices[i++] = {
- Vertex3D{x * div + 0.0f, y * div + 0.0f, 0.0f},
- Vertex3D{x * div + 1.0f * div, y * div + 0.0f, 0.0f},
- Vertex3D{x * div + 0.0f, y * div + 1.0f * div, 0.0f}
+ Vertex3D{x * div + 0.0f * div, y * div + 0.0f * div, 0.0f},
+ Vertex3D{x * div + 1.0f * div, y * div + 0.0f * div, 0.0f},
+ Vertex3D{x * div + 1.0f * div, y * div + 1.0f * div, 0.0f}
};
vertices[i++] = {
- Vertex3D{x * div + 1.0f * div, y * div + 0.0f, 0.0f},
Vertex3D{x * div + 1.0f * div, y * div + 1.0f * div, 0.0f},
- Vertex3D{x * div + 0.0f, y * div + 1.0f * div, 0.0f}
+ Vertex3D{x * div + 0.0f * div, y * div + 1.0f * div, 0.0f},
+ Vertex3D{x * div + 0.0f * div, y * div + 0.0f * div, 0.0f}
};
}
}
return vertices;
}
+static void create_sand(DeviceMemory *triangles, DeviceMemory *texcoords, Texture2D *texture);
+static DeviceMemory* load_model(const char *filepath);
+
int main()
{
initGlfw();
@@ -60,52 +62,52 @@ int main()
int window_width = 1;
int window_height = 1;
glfwGetWindowSize(window, &window_width, &window_height);
-
- DeviceFrame frame;
-
- std::vector<Triangle3D> cpu_sand = generate_sand();
- DeviceMemory *gpuSand = frame.alloc();
- gpuSand->copy({cpu_sand.data(), cpu_sand.size()}, DeviceMemory::StorageType::STATIC);
+
+ glm::mat4 proj = glm::perspective(glm::radians(75.0f), (float)window_width / (float)window_height, 0.2f, 1000.0f);
std::unique_ptr<Shader> sand_vertex_shader = load_shader_from_file("shaders/sand_vertex.vert", Shader::Type::VERTEX);
std::unique_ptr<Shader> sand_pixel_shader = load_shader_from_file("shaders/sand_fragment.frag", Shader::Type::PIXEL);
std::unique_ptr<ShaderProgram> sand_shader_program = build_shader_program_from_shaders({ sand_vertex_shader.get(), sand_pixel_shader.get() });
+ ShaderFrame sand_frame = sand_shader_program->create_frame();
+
+ DeviceMemory *sand_triangles = sand_frame.get_input_by_name("position");
+ DeviceMemory *sand_texcoords = sand_frame.get_input_by_name("texcoord_vert");
+ Texture2D sand_texture;
+ create_sand(sand_triangles, sand_texcoords, &sand_texture);
+
+ Result<Uniform> sand_proj_uniform = sand_frame.get_uniform_by_name("proj");
+ Result<Uniform> sand_view_uniform = sand_frame.get_uniform_by_name("view");
+ Result<Uniform> sand_model_uniform = sand_frame.get_uniform_by_name("model");
+ //Result<Uniform> sand_time = sand_frame.get_uniform_by_name("time");
+ Result<Uniform> sand_heightmap_uniform = sand_frame.get_uniform_by_name("tex");
+
+ sand_proj_uniform->set(proj);
+ sand_heightmap_uniform->set(sand_texture);
- std::vector<Triangle3D> triangles;
- std::vector<vec2f> texture_coords;
- Image *image;
- ObjModelLoader::load_from_file("/home/dec05eba/Downloads/ELI4OS.obj", triangles, texture_coords, &image);
- DeviceMemory *gpuModel = frame.alloc();
- gpuModel->copy({triangles.data(), triangles.size()}, DeviceMemory::StorageType::STATIC);
- Texture2D model_texture(image);
- DeviceMemory *model_gpu_texture = frame.alloc();
- model_gpu_texture->copy({texture_coords.data(), texture_coords.size()}, DeviceMemory::StorageType::STATIC);
std::unique_ptr<Shader> vertex_shader = load_shader_from_file("shaders/vertex.vert", Shader::Type::VERTEX);
std::unique_ptr<Shader> pixel_shader = load_shader_from_file("shaders/fragment.frag", Shader::Type::PIXEL);
std::unique_ptr<ShaderProgram> shader_program = build_shader_program_from_shaders({ vertex_shader.get(), pixel_shader.get() });
+ ShaderFrame model_frame = shader_program->create_frame();
- glm::mat4 proj = glm::perspective(glm::radians(75.0f), (float)window_width / (float)window_height, 0.2f, 1000.0f);
- vec3f triangle_color = { 1.0f, 0.0f, 0.0f };
-
- Result<Uniform> sand_proj_uniform = sand_shader_program->get_uniform_by_name("proj");
- Result<Uniform> sand_view_uniform = sand_shader_program->get_uniform_by_name("view");
- Result<Uniform> sand_model_uniform = sand_shader_program->get_uniform_by_name("model");
- Result<Uniform> sand_time = sand_shader_program->get_uniform_by_name("time");
- Result<Uniform> sand_triangle_color_uniform = sand_shader_program->get_uniform_by_name("triangle_color");
+ std::vector<Triangle3D> triangles;
+ std::vector<vec2f> texture_coords;
+ Image *image;
+ ObjModelLoader::load_from_file("/home/dec05eba/Downloads/ELI4OS.obj", triangles, texture_coords, &image);
+ DeviceMemory *gpuModel = model_frame.get_input_by_name("position");
+ gpuModel->set({triangles.data(), triangles.size()}, DeviceMemory::StorageType::STATIC);
- Result<Uniform> proj_uniform = shader_program->get_uniform_by_name("proj");
- Result<Uniform> view_uniform = shader_program->get_uniform_by_name("view");
- Result<Uniform> model_uniform = shader_program->get_uniform_by_name("model");
- Result<Uniform> tex_uniform = shader_program->get_uniform_by_name("tex");
+ Texture2D model_texture(image);
+ DeviceMemory *model_gpu_texcoords = model_frame.get_input_by_name("texcoord_vert");
+ model_gpu_texcoords->set({texture_coords.data(), texture_coords.size()}, DeviceMemory::StorageType::STATIC);
- sand_proj_uniform->set(proj);
- sand_triangle_color_uniform->set(triangle_color);
+ Result<Uniform> proj_uniform = model_frame.get_uniform_by_name("proj");
+ Result<Uniform> view_uniform = model_frame.get_uniform_by_name("view");
+ Result<Uniform> model_uniform = model_frame.get_uniform_by_name("model");
+ Result<Uniform> tex_uniform = model_frame.get_uniform_by_name("tex");
proj_uniform->set(proj);
-
- shader_program->set_input_data("texcoord_vert", *model_gpu_texture);
tex_uniform->set(model_texture);
Userdata userdata;
@@ -121,6 +123,9 @@ int main()
});
glEnable(GL_CULL_FACE);
+ glEnable(GL_DEPTH_TEST);
+ glDepthFunc(GL_LESS);
+
float time = 0.0f;
while(!glfwWindowShouldClose(window)) {
glfwPollEvents();
@@ -158,11 +163,19 @@ int main()
0.0f,
glm::vec3(0.0f, 0.0f, 1.0f)
);
- sand_model_uniform->set(model);
model_uniform->set(model);
+ glm::mat4 sand_model = glm::mat4(1.0f);
+ sand_model = glm::rotate(
+ sand_model,
+ 0.0f,
+ glm::vec3(0.0f, 0.0f, 1.0f)
+ );
+ sand_model = glm::scale(sand_model, glm::vec3(50.0f, 50.0f, 50.0f));
+ sand_model_uniform->set(sand_model);
+
//printf("now: %f\n", time);
- sand_time->set(time);
+ //sand_time->set(time);
// Set color for clearing
glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
@@ -170,11 +183,8 @@ int main()
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
//glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
- shader_program->set_input_data("position", *gpuModel);
- frame.draw(shader_program.get());
-
- sand_shader_program->set_input_data("position", *gpuSand);
- frame.draw(sand_shader_program.get());
+ model_frame.draw();
+ sand_frame.draw();
//glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
glfwSwapBuffers(window);
@@ -185,6 +195,32 @@ int main()
return 0;
}
+void create_sand(DeviceMemory *triangles, DeviceMemory *texcoords, Texture2D *texture) {
+ std::vector<Triangle3D> cpu_sand = generate_sand();
+ triangles->set({cpu_sand.data(), cpu_sand.size()}, DeviceMemory::StorageType::STATIC);
+
+ Result<Image*> height_map_image = Image::loadFromFile("heightmap.jpg");
+ if(!height_map_image) {
+ fprintf(stderr, "Error: failed to load image: heightmap.jpg\n");
+ exit(1);
+ }
+
+ std::vector<vec2f> height_map_texcoord;
+ for(const Triangle3D &triangle : cpu_sand) {
+ height_map_texcoord.push_back(vec2f{ triangle.p1.x, triangle.p1.y });
+ height_map_texcoord.push_back(vec2f{ triangle.p2.x, triangle.p2.y });
+ height_map_texcoord.push_back(vec2f{ triangle.p3.x, triangle.p3.y });
+ }
+
+ Texture2D height_map_texture(height_map_image.unwrap());
+ *texture = std::move(height_map_texture);
+ texcoords->set({height_map_texcoord.data(), height_map_texcoord.size()}, DeviceMemory::StorageType::STATIC);
+}
+
+DeviceMemory* load_model(const char *filepath) {
+ return nullptr;
+}
+
void glfwErrorHandler(int errorCode, const char *errorDescription)
{
printf("GLFW error code: %d, description: %s\n", errorCode, errorDescription);