Added glm, fbo, shader, texture and texture generator
This commit is contained in:
@@ -0,0 +1,3 @@
|
|||||||
|
[submodule "lib/glm"]
|
||||||
|
path = lib/glm
|
||||||
|
url = git@github.com:g-truc/glm.git
|
||||||
@@ -9,6 +9,7 @@ find_package(OpenGL REQUIRED)
|
|||||||
|
|
||||||
include_directories("src/")
|
include_directories("src/")
|
||||||
include_directories("gl/include")
|
include_directories("gl/include")
|
||||||
|
add_subdirectory(lib/glm EXCLUDE_FROM_ALL)
|
||||||
add_subdirectory(src)
|
add_subdirectory(src)
|
||||||
|
|
||||||
add_executable(demo main.cpp gl/src/glad.c ${SOURCE})
|
add_executable(demo main.cpp gl/src/glad.c ${SOURCE})
|
||||||
|
|||||||
Submodule
+1
Submodule lib/glm added at cc98465e35
@@ -1,23 +1,20 @@
|
|||||||
#include "peripherals_glfw.h"
|
#include "peripherals_glfw.h"
|
||||||
|
|
||||||
|
|
||||||
int main() {
|
int main() {
|
||||||
acidrain::peripherals_glfw peripherals;
|
acidrain::peripherals_glfw peripherals;
|
||||||
peripherals.init();
|
peripherals.init();
|
||||||
|
|
||||||
glDisable(GL_DEPTH_TEST);
|
glDisable(GL_DEPTH_TEST);
|
||||||
|
|
||||||
double alpha = 0.0;
|
double alpha = 0.0;
|
||||||
// while (!glfwWindowShouldClose(window)) {
|
while (!peripherals.should_close()) {
|
||||||
while (!peripherals.should_close()) {
|
alpha += 0.01;
|
||||||
alpha += 0.01;
|
if (alpha > 1.0) alpha = 0.0;
|
||||||
if (alpha > 1.0) alpha = 0.0;
|
|
||||||
|
|
||||||
glClearColor(0.0 * alpha, 0.1 * alpha, 1.0 * alpha, 1 * alpha);
|
glClearColor(0.0 * alpha, 0.1 * alpha, 1.0 * alpha, 1 * alpha);
|
||||||
glClear(GL_COLOR_BUFFER_BIT);
|
glClear(GL_COLOR_BUFFER_BIT);
|
||||||
|
|
||||||
peripherals.swap_buffers();
|
|
||||||
peripherals.poll_events();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
peripherals.swap_buffers();
|
||||||
|
peripherals.poll_events();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+18
-9
@@ -1,11 +1,20 @@
|
|||||||
set(HEADERS
|
set(HEADERS
|
||||||
${HEADERS}
|
${HEADERS}
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/peripherals.h
|
${CMAKE_CURRENT_SOURCE_DIR}/colour.h
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/peripherals_glfw.h
|
${CMAKE_CURRENT_SOURCE_DIR}/fbo.h
|
||||||
PARENT_SCOPE
|
${CMAKE_CURRENT_SOURCE_DIR}/peripherals.h
|
||||||
)
|
${CMAKE_CURRENT_SOURCE_DIR}/peripherals_glfw.h
|
||||||
|
${CMAKE_CURRENT_SOURCE_DIR}/shader.h
|
||||||
|
${CMAKE_CURRENT_SOURCE_DIR}/texture.h
|
||||||
|
${CMAKE_CURRENT_SOURCE_DIR}/texture_generator.h
|
||||||
|
PARENT_SCOPE
|
||||||
|
)
|
||||||
set(SOURCE
|
set(SOURCE
|
||||||
${SOURCE}
|
${SOURCE}
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/peripherals_glfw.cpp
|
${CMAKE_CURRENT_SOURCE_DIR}/fbo.cpp
|
||||||
PARENT_SCOPE
|
${CMAKE_CURRENT_SOURCE_DIR}/peripherals_glfw.cpp
|
||||||
)
|
${CMAKE_CURRENT_SOURCE_DIR}/shader.cpp
|
||||||
|
${CMAKE_CURRENT_SOURCE_DIR}/texture.cpp
|
||||||
|
${CMAKE_CURRENT_SOURCE_DIR}/texture_generator.cpp
|
||||||
|
PARENT_SCOPE
|
||||||
|
)
|
||||||
|
|||||||
@@ -0,0 +1,14 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <cstdint>
|
||||||
|
#include "glm/vec4.hpp"
|
||||||
|
|
||||||
|
typedef glm::vec4 colour;
|
||||||
|
|
||||||
|
inline uint32_t as_int(const glm::vec4 &col) {
|
||||||
|
unsigned char rr = static_cast<unsigned char>(col.r * 255);
|
||||||
|
unsigned char gg = static_cast<unsigned char>(col.g * 255);
|
||||||
|
unsigned char bb = static_cast<unsigned char>(col.b * 255);
|
||||||
|
unsigned char aa = static_cast<unsigned char>(col.a * 255);
|
||||||
|
return rr + (gg << 8) + (bb << 16) + (aa << 24);
|
||||||
|
}
|
||||||
@@ -1,5 +1,8 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
#include <glad/glad.h>
|
||||||
|
|
||||||
#define BEGIN_NAMESPACE namespace acidrain {
|
#define BEGIN_NAMESPACE namespace acidrain {
|
||||||
#define END_NAMESPACE };
|
#define END_NAMESPACE };
|
||||||
|
|
||||||
|
static int SCREEN_WIDTH = 800;
|
||||||
|
static int SCREEN_HEIGHT = 600;
|
||||||
|
|||||||
+73
@@ -0,0 +1,73 @@
|
|||||||
|
#include "fbo.h"
|
||||||
|
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
|
BEGIN_NAMESPACE
|
||||||
|
|
||||||
|
fbo::fbo(int w, int h)
|
||||||
|
: width(w),
|
||||||
|
height(h) {
|
||||||
|
|
||||||
|
glGenFramebuffers(1, &frame_buffer_id);
|
||||||
|
glGenTextures(1, &color_buffer_id);
|
||||||
|
glGenRenderbuffers(1, &depth_buffer_id);
|
||||||
|
|
||||||
|
glBindFramebuffer(GL_FRAMEBUFFER, frame_buffer_id);
|
||||||
|
|
||||||
|
glBindTexture(GL_TEXTURE_2D_MULTISAMPLE, color_buffer_id);
|
||||||
|
glTexImage2DMultisample(GL_TEXTURE_2D_MULTISAMPLE,
|
||||||
|
4, // number of samples for multisampling
|
||||||
|
GL_RGBA8,
|
||||||
|
width, height,
|
||||||
|
false);
|
||||||
|
|
||||||
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||||
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||||
|
glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D_MULTISAMPLE, color_buffer_id,
|
||||||
|
0);
|
||||||
|
|
||||||
|
glBindRenderbuffer(GL_RENDERBUFFER, depth_buffer_id);
|
||||||
|
glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT24, width, height);
|
||||||
|
glFramebufferRenderbuffer(GL_DRAW_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, depth_buffer_id);
|
||||||
|
}
|
||||||
|
|
||||||
|
int fbo::get_width() const {
|
||||||
|
return width;
|
||||||
|
}
|
||||||
|
|
||||||
|
int fbo::get_height() const {
|
||||||
|
return height;
|
||||||
|
}
|
||||||
|
|
||||||
|
GLuint fbo::get_color_buffer_id() const {
|
||||||
|
return color_buffer_id;
|
||||||
|
}
|
||||||
|
|
||||||
|
GLuint fbo::get_depth_buffer_id() const {
|
||||||
|
return depth_buffer_id;
|
||||||
|
}
|
||||||
|
|
||||||
|
void fbo::use() {
|
||||||
|
old_width = SCREEN_WIDTH;
|
||||||
|
old_height = SCREEN_HEIGHT;
|
||||||
|
|
||||||
|
SCREEN_WIDTH = width;
|
||||||
|
SCREEN_HEIGHT = height;
|
||||||
|
|
||||||
|
glBindFramebuffer(GL_FRAMEBUFFER, frame_buffer_id);
|
||||||
|
glViewport(0, 0, width, height);
|
||||||
|
}
|
||||||
|
|
||||||
|
void fbo::unuse() {
|
||||||
|
glBindFramebuffer(GL_FRAMEBUFFER, 0);
|
||||||
|
glViewport(0, 0, old_width, old_height);
|
||||||
|
|
||||||
|
SCREEN_WIDTH = old_width;
|
||||||
|
SCREEN_HEIGHT = old_height;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::shared_ptr<texture> fbo::get_texture() {
|
||||||
|
return std::make_shared<texture>(color_buffer_id, width, height);
|
||||||
|
}
|
||||||
|
|
||||||
|
END_NAMESPACE
|
||||||
@@ -0,0 +1,36 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "texture.h"
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
|
BEGIN_NAMESPACE
|
||||||
|
|
||||||
|
class fbo {
|
||||||
|
public:
|
||||||
|
explicit fbo(int width, int height);
|
||||||
|
~fbo() = default;
|
||||||
|
|
||||||
|
void use();
|
||||||
|
void unuse();
|
||||||
|
|
||||||
|
int get_width() const;
|
||||||
|
int get_height() const;
|
||||||
|
|
||||||
|
GLuint get_color_buffer_id() const;
|
||||||
|
GLuint get_depth_buffer_id() const;
|
||||||
|
|
||||||
|
std::shared_ptr<texture> get_texture();
|
||||||
|
|
||||||
|
private:
|
||||||
|
int width;
|
||||||
|
int height;
|
||||||
|
|
||||||
|
int old_width;
|
||||||
|
int old_height;
|
||||||
|
|
||||||
|
GLuint frame_buffer_id;
|
||||||
|
GLuint color_buffer_id;
|
||||||
|
GLuint depth_buffer_id;
|
||||||
|
};
|
||||||
|
|
||||||
|
END_NAMESPACE
|
||||||
@@ -1,6 +1,5 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
#include "peripherals.h"
|
#include "peripherals.h"
|
||||||
#include <glad/glad.h>
|
|
||||||
|
|
||||||
// forward declares
|
// forward declares
|
||||||
class GLFWwindow;
|
class GLFWwindow;
|
||||||
|
|||||||
+114
@@ -0,0 +1,114 @@
|
|||||||
|
#include "shader.h"
|
||||||
|
#include <string>
|
||||||
|
#include <iostream>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
BEGIN_NAMESPACE
|
||||||
|
|
||||||
|
void check_compile_error(GLuint shaderId) {
|
||||||
|
GLint isCompiled = 0;
|
||||||
|
glGetShaderiv(shaderId, GL_COMPILE_STATUS, &isCompiled);
|
||||||
|
if (isCompiled == GL_FALSE) {
|
||||||
|
GLint maxLength = 0;
|
||||||
|
glGetShaderiv(shaderId, GL_INFO_LOG_LENGTH, &maxLength);
|
||||||
|
|
||||||
|
//The maxLength includes the NULL character
|
||||||
|
char errorLog[maxLength];
|
||||||
|
glGetShaderInfoLog(shaderId, maxLength, &maxLength, &errorLog[0]);
|
||||||
|
|
||||||
|
std::cout << "Shader error: " << errorLog << std::endl;
|
||||||
|
|
||||||
|
//Provide the infolog in whatever manor you deem best.
|
||||||
|
//Exit with failure.
|
||||||
|
glDeleteShader(shaderId); //Don't leak the shader.
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
shader::shader(const char *vs_content, const char *ps_content) {
|
||||||
|
shader_ids[0] = glCreateShader(GL_VERTEX_SHADER);
|
||||||
|
glShaderSource(shader_ids[0], 1, &vs_content, nullptr);
|
||||||
|
glCompileShader(shader_ids[0]);
|
||||||
|
check_compile_error(shader_ids[0]);
|
||||||
|
|
||||||
|
shader_ids[1] = glCreateShader(GL_FRAGMENT_SHADER);
|
||||||
|
glShaderSource(shader_ids[1], 1, &ps_content, nullptr);
|
||||||
|
glCompileShader(shader_ids[1]);
|
||||||
|
check_compile_error(shader_ids[1]);
|
||||||
|
|
||||||
|
program_id = glCreateProgram();
|
||||||
|
glAttachShader(program_id, shader_ids[0]);
|
||||||
|
glAttachShader(program_id, shader_ids[1]);
|
||||||
|
|
||||||
|
// TODO Adrian: these should come from an external enumeration
|
||||||
|
glBindAttribLocation(program_id, 0, "position");
|
||||||
|
glBindAttribLocation(program_id, 1, "normal");
|
||||||
|
glBindAttribLocation(program_id, 2, "texCoords");
|
||||||
|
|
||||||
|
glLinkProgram(program_id);
|
||||||
|
glUseProgram(program_id);
|
||||||
|
}
|
||||||
|
|
||||||
|
shader::~shader() {
|
||||||
|
glDetachShader(program_id, shader_ids[0]);
|
||||||
|
glDetachShader(program_id, shader_ids[1]);
|
||||||
|
|
||||||
|
glDeleteShader(shader_ids[0]);
|
||||||
|
glDeleteShader(shader_ids[1]);
|
||||||
|
|
||||||
|
glDeleteProgram(program_id);
|
||||||
|
}
|
||||||
|
|
||||||
|
void shader::use() const {
|
||||||
|
glUseProgram(program_id);
|
||||||
|
}
|
||||||
|
|
||||||
|
void shader::unuse() const {
|
||||||
|
glUseProgram(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
int shader::getUniform(const char *uniformName) {
|
||||||
|
if (uniformCache.count(uniformName) == 0) {
|
||||||
|
uniformCache[uniformName] = glGetUniformLocation(program_id, uniformName);
|
||||||
|
}
|
||||||
|
return uniformCache[uniformName];
|
||||||
|
}
|
||||||
|
|
||||||
|
void shader::setMatrix3Uniform(float *matrix, const char *uniformName) {
|
||||||
|
GLint location = getUniform(uniformName);
|
||||||
|
if (location != -1)
|
||||||
|
glUniformMatrix3fv(location, 1, false, matrix);
|
||||||
|
}
|
||||||
|
|
||||||
|
void shader::setMatrix4Uniform(float *matrix, const char *uniformName) {
|
||||||
|
GLint location = getUniform(uniformName);
|
||||||
|
if (location != -1)
|
||||||
|
glUniformMatrix4fv(location, 1, false, matrix);
|
||||||
|
}
|
||||||
|
|
||||||
|
void shader::setVec3Uniform(float *value, const char *uniformName) {
|
||||||
|
GLint location = getUniform(uniformName);
|
||||||
|
if (location != -1)
|
||||||
|
glUniform3fv(location, 1, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
void shader::setVec4Uniform(float *value, const char *uniformName) {
|
||||||
|
GLint location = getUniform(uniformName);
|
||||||
|
if (location != -1)
|
||||||
|
glUniform4fv(location, 1, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
void shader::setIntUniform(int value, const char *uniformName) {
|
||||||
|
GLint location = getUniform(uniformName);
|
||||||
|
if (location != -1)
|
||||||
|
glUniform1i(location, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
void shader::setFloatUniform(float value, const char *uniformName) {
|
||||||
|
GLint location = getUniform(uniformName);
|
||||||
|
if (location != -1)
|
||||||
|
glUniform1f(location, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
END_NAMESPACE
|
||||||
@@ -0,0 +1,34 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "defines.h"
|
||||||
|
#include <map>
|
||||||
|
|
||||||
|
BEGIN_NAMESPACE
|
||||||
|
|
||||||
|
class shader {
|
||||||
|
public:
|
||||||
|
|
||||||
|
shader(const char *vs_content, const char *ps_content);
|
||||||
|
virtual ~shader();
|
||||||
|
|
||||||
|
void use() const;
|
||||||
|
void unuse() const;
|
||||||
|
|
||||||
|
GLuint getId() const { return program_id; }
|
||||||
|
int getUniform(const char *uniformName);
|
||||||
|
|
||||||
|
void setMatrix3Uniform(float *value, const char *uniformName);
|
||||||
|
void setMatrix4Uniform(float *value, const char *uniformName);
|
||||||
|
void setVec3Uniform(float *value, const char *uniformName);
|
||||||
|
void setVec4Uniform(float *value, const char *uniformName);
|
||||||
|
void setFloatUniform(float value, const char *uniformName);
|
||||||
|
void setIntUniform(int value, const char *uniformName);
|
||||||
|
|
||||||
|
private:
|
||||||
|
GLuint program_id;
|
||||||
|
GLuint shader_ids[2];
|
||||||
|
std::map<const char *, int> uniformCache;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
END_NAMESPACE
|
||||||
@@ -0,0 +1,62 @@
|
|||||||
|
#include "texture.h"
|
||||||
|
|
||||||
|
BEGIN_NAMESPACE
|
||||||
|
|
||||||
|
texture::texture(int w, int h, uint8_t *buffer)
|
||||||
|
: width(w),
|
||||||
|
height(h),
|
||||||
|
destroyable(true) {
|
||||||
|
|
||||||
|
glGenTextures(1, &id);
|
||||||
|
glBindTexture(GL_TEXTURE_2D, id);
|
||||||
|
|
||||||
|
// select modulate to mix texture with color for shading
|
||||||
|
// glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
|
||||||
|
|
||||||
|
// // only set this when we do have mipmaps
|
||||||
|
// glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
|
||||||
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||||
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||||
|
|
||||||
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
|
||||||
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
|
||||||
|
|
||||||
|
// for versions up to 3
|
||||||
|
// glTexParameteri(GL_TEXTURE_2D, GL_GENERATE_MIPMAP, GL_TRUE);
|
||||||
|
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA,
|
||||||
|
width, height,
|
||||||
|
0, GL_RGBA, GL_UNSIGNED_BYTE,
|
||||||
|
buffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
texture::texture(GLuint id, int w, int h)
|
||||||
|
: id(id),
|
||||||
|
width(w),
|
||||||
|
height(h),
|
||||||
|
destroyable(false) {
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
texture::~texture() {
|
||||||
|
if (destroyable)
|
||||||
|
glDeleteTextures(1, &id);
|
||||||
|
}
|
||||||
|
|
||||||
|
int texture::get_width() const {
|
||||||
|
return width;
|
||||||
|
}
|
||||||
|
|
||||||
|
int texture::get_height() const {
|
||||||
|
return height;
|
||||||
|
}
|
||||||
|
|
||||||
|
void texture::use() const {
|
||||||
|
glBindTexture(GL_TEXTURE_2D, id);
|
||||||
|
}
|
||||||
|
|
||||||
|
void texture::unuse() const {
|
||||||
|
glBindTexture(GL_TEXTURE_2D, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
END_NAMESPACE
|
||||||
@@ -0,0 +1,27 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "peripherals.h"
|
||||||
|
|
||||||
|
BEGIN_NAMESPACE
|
||||||
|
|
||||||
|
class texture {
|
||||||
|
public:
|
||||||
|
texture(int width, int height, uint8_t *buffer);
|
||||||
|
texture(GLuint id, int width, int height);
|
||||||
|
virtual ~texture();
|
||||||
|
|
||||||
|
int get_width() const;
|
||||||
|
int get_height() const;
|
||||||
|
GLuint get_id() const { return id; }
|
||||||
|
|
||||||
|
void use() const;
|
||||||
|
void unuse() const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
int width;
|
||||||
|
int height;
|
||||||
|
bool destroyable;
|
||||||
|
GLuint id = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
END_NAMESPACE
|
||||||
@@ -0,0 +1,232 @@
|
|||||||
|
#include "texture_generator.h"
|
||||||
|
#include <cmath>
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
|
BEGIN_NAMESPACE
|
||||||
|
|
||||||
|
texture_generator::texture_generator(uint16_t w, uint16_t h)
|
||||||
|
: width(w), height(h) {
|
||||||
|
|
||||||
|
for (auto &layer: layers)
|
||||||
|
layer = new uint8_t[width * height * 4];
|
||||||
|
}
|
||||||
|
|
||||||
|
texture_generator::~texture_generator() {
|
||||||
|
for (auto &layer: layers)
|
||||||
|
delete[] layer;
|
||||||
|
}
|
||||||
|
|
||||||
|
texture_generator &texture_generator::checker_board(uint8_t layer,
|
||||||
|
uint8_t block_size,
|
||||||
|
colour on,
|
||||||
|
colour off) {
|
||||||
|
|
||||||
|
auto *input = reinterpret_cast<uint32_t *>(layers[layer]);
|
||||||
|
|
||||||
|
uint32_t on_color = as_int(on);
|
||||||
|
uint32_t off_color = as_int(off);
|
||||||
|
|
||||||
|
for (auto y = 0; y < height; y++) {
|
||||||
|
for (auto x = 0; x < width; x++) {
|
||||||
|
bool in_block = (
|
||||||
|
((x % (2 * block_size)) < block_size) &&
|
||||||
|
((y % (2 * block_size)) < block_size)
|
||||||
|
);
|
||||||
|
|
||||||
|
*input++ = in_block ? on_color : off_color;
|
||||||
|
// *input++ = 0xffffffff;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
texture_generator &texture_generator::env_map(uint8_t layer, uint8_t size) {
|
||||||
|
auto *input = reinterpret_cast<uint32_t *>(layers[layer]);
|
||||||
|
|
||||||
|
colour col{1};
|
||||||
|
|
||||||
|
float size_squared = size * size;
|
||||||
|
for (uint16_t y = 0; y < height; y++) {
|
||||||
|
for (uint16_t x = 0; x < width; x++) {
|
||||||
|
int32_t rx = x - width / 2;
|
||||||
|
int32_t ry = y - height / 2;
|
||||||
|
float r_square = static_cast<float>(rx * rx + ry * ry);
|
||||||
|
|
||||||
|
if (r_square <= size_squared) {
|
||||||
|
float a = 1.0f - (r_square / size_squared);
|
||||||
|
col.r = col.g = col.b = a;
|
||||||
|
// col.a = 1;
|
||||||
|
} else {
|
||||||
|
col.r = col.g = col.b = 0;
|
||||||
|
// col.a = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
*input++ = as_int(col);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
texture_generator &texture_generator::lens(uint8_t layer, uint8_t size) {
|
||||||
|
auto *input = reinterpret_cast<uint32_t *>(layers[layer]);
|
||||||
|
|
||||||
|
colour col{0};
|
||||||
|
|
||||||
|
float size_squared = size * size;
|
||||||
|
float c;
|
||||||
|
for (uint16_t y = 0; y < height; y++) {
|
||||||
|
for (uint16_t x = 0; x < width; x++) {
|
||||||
|
int32_t rx = x - width / 2;
|
||||||
|
int32_t ry = y - height / 2;
|
||||||
|
auto r_squared = static_cast<float>(rx * rx + ry * ry);
|
||||||
|
|
||||||
|
if (r_squared <= size_squared) {
|
||||||
|
// double r = sqrt(static_cast<double>rsquare) / static_cast<double>(size);
|
||||||
|
float r = 0;
|
||||||
|
c = 1.0f - r;
|
||||||
|
c = c * c;
|
||||||
|
if (r > 1.0f)
|
||||||
|
c = 0.0f;
|
||||||
|
col = glm::vec4(c);
|
||||||
|
} else {
|
||||||
|
col = glm::vec4(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
*input++ = as_int(col);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
texture_generator &texture_generator::roll(uint8_t layer, uint8_t x, uint8_t y) {
|
||||||
|
uint8_t *input = layers[layer];
|
||||||
|
auto *output = new uint8_t[width * height * 4];
|
||||||
|
uint8_t *out_ptr = output;
|
||||||
|
|
||||||
|
for (uint16_t j = 0; j < height; j++) {
|
||||||
|
for (uint16_t i = 0; i < width; i++) {
|
||||||
|
uint32_t index = ((j + y) % height) * width + ((i + x) % width);
|
||||||
|
*out_ptr++ = input[index * 4 + 0];
|
||||||
|
*out_ptr++ = input[index * 4 + 1];
|
||||||
|
*out_ptr++ = input[index * 4 + 2];
|
||||||
|
*out_ptr++ = input[index * 4 + 3];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
memcpy(input, output, width * height * 4);
|
||||||
|
delete[] output;
|
||||||
|
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
uint8_t *texture_generator::get(uint8_t layer) {
|
||||||
|
return layers[layer];
|
||||||
|
}
|
||||||
|
|
||||||
|
std::shared_ptr<texture> texture_generator::get_texture(uint8_t layer) {
|
||||||
|
return std::make_shared<texture>(width, height, get(layer));
|
||||||
|
}
|
||||||
|
|
||||||
|
texture_generator &texture_generator::white_noise(uint8_t layer) {
|
||||||
|
auto *input = reinterpret_cast<uint32_t *>(layers[layer]);
|
||||||
|
for (uint16_t y = 0; y < height; y++) {
|
||||||
|
for (uint16_t x = 0; x < width; x++) {
|
||||||
|
*input++ = rand();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
texture_generator &texture_generator::polar_grid(uint8_t layer) {
|
||||||
|
uint8_t *input = layers[layer];
|
||||||
|
|
||||||
|
auto *output = new uint8_t[width * height * 4];
|
||||||
|
uint8_t *out_ptr = output;
|
||||||
|
|
||||||
|
for (int j = 0; j < height; j++) {
|
||||||
|
double theta = M_PI * (j - (height - 1) / 2.0) / static_cast<double>(height - 1);
|
||||||
|
for (int i = 0; i < width; i++) {
|
||||||
|
double phi = 2 * M_PI * (i - width / 2.0) / static_cast<double>(width);
|
||||||
|
double phi2 = phi * cos(theta);
|
||||||
|
int i2 = phi2 * width / (2 * M_PI) + width / 2;
|
||||||
|
if (i2 < 0 || i2 > width - 1) {
|
||||||
|
*out_ptr++ = 255;
|
||||||
|
*out_ptr++ = 0;
|
||||||
|
*out_ptr++ = 0;
|
||||||
|
*out_ptr++ = 1;
|
||||||
|
|
||||||
|
} else {
|
||||||
|
*out_ptr++ = input[(j * width + i2) * 4 + 0];
|
||||||
|
*out_ptr++ = input[(j * width + i2) * 4 + 1];
|
||||||
|
*out_ptr++ = input[(j * width + i2) * 4 + 2];
|
||||||
|
*out_ptr++ = input[(j * width + i2) * 4 + 3];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
memcpy(input, output, width * height * 4);
|
||||||
|
delete[] output;
|
||||||
|
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
texture_generator &texture_generator::brick(uint8_t layer,
|
||||||
|
uint8_t brick_width,
|
||||||
|
uint8_t brick_height,
|
||||||
|
uint8_t gap_size,
|
||||||
|
colour mortar_col,
|
||||||
|
colour brick_col) {
|
||||||
|
|
||||||
|
auto *input = reinterpret_cast<uint32_t *>(layers[layer]);
|
||||||
|
|
||||||
|
uint32_t mortar = as_int(mortar_col);
|
||||||
|
uint32_t brick = as_int(brick_col);
|
||||||
|
|
||||||
|
for (int i = 0; i < width * height; i++) {
|
||||||
|
input[i] = brick;
|
||||||
|
}
|
||||||
|
|
||||||
|
int y = 0;
|
||||||
|
while (y < height) {
|
||||||
|
for (int i = 0; i < gap_size; i++) {
|
||||||
|
if ((y + i) < height) {
|
||||||
|
for (int x = 0; x < width; x++) {
|
||||||
|
input[x + (y + i) * width] = mortar;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
y += brick_height + gap_size;
|
||||||
|
}
|
||||||
|
|
||||||
|
int offset = 0;
|
||||||
|
bool is_odd_row = false;
|
||||||
|
y = gap_size;
|
||||||
|
while (y < height) {
|
||||||
|
int x = is_odd_row ? 0 : brick_width / 2;
|
||||||
|
while (x < width) {
|
||||||
|
for (int i = 0; i < gap_size; i++) {
|
||||||
|
for (int current_brick_y = 0; current_brick_y < brick_height; current_brick_y++) {
|
||||||
|
input[x + i + (current_brick_y + y) * width] = mortar;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
x += gap_size + brick_width;
|
||||||
|
}
|
||||||
|
|
||||||
|
y += brick_height + gap_size;
|
||||||
|
is_odd_row = !is_odd_row;
|
||||||
|
}
|
||||||
|
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
END_NAMESPACE
|
||||||
@@ -0,0 +1,43 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "texture.h"
|
||||||
|
#include "colour.h"
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
|
BEGIN_NAMESPACE
|
||||||
|
|
||||||
|
class texture_generator {
|
||||||
|
public:
|
||||||
|
texture_generator(uint16_t width, uint16_t height);
|
||||||
|
virtual ~texture_generator();
|
||||||
|
|
||||||
|
texture_generator &checker_board(uint8_t layer,
|
||||||
|
uint8_t block_size,
|
||||||
|
colour on,
|
||||||
|
colour off);
|
||||||
|
texture_generator &brick(uint8_t layer,
|
||||||
|
uint8_t brick_width,
|
||||||
|
uint8_t brick_height,
|
||||||
|
uint8_t gap_size,
|
||||||
|
colour mortar_col,
|
||||||
|
colour brick_col);
|
||||||
|
|
||||||
|
texture_generator &white_noise(uint8_t layer);
|
||||||
|
texture_generator &env_map(uint8_t layer, uint8_t size);
|
||||||
|
texture_generator &lens(uint8_t layer, uint8_t size);
|
||||||
|
|
||||||
|
texture_generator &roll(uint8_t layer, uint8_t x, uint8_t y);
|
||||||
|
texture_generator &polar_grid(uint8_t layer);
|
||||||
|
|
||||||
|
uint8_t *get(uint8_t layer);
|
||||||
|
std::shared_ptr<texture> get_texture(uint8_t layer);
|
||||||
|
|
||||||
|
uint16_t width;
|
||||||
|
uint16_t height;
|
||||||
|
|
||||||
|
private:
|
||||||
|
static const int NUM_LAYERS = 4;
|
||||||
|
uint8_t *layers[NUM_LAYERS] = {nullptr};
|
||||||
|
};
|
||||||
|
|
||||||
|
END_NAMESPACE
|
||||||
Reference in New Issue
Block a user