Added glm, fbo, shader, texture and texture generator
This commit is contained in:
+18
-9
@@ -1,11 +1,20 @@
|
||||
set(HEADERS
|
||||
${HEADERS}
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/peripherals.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/peripherals_glfw.h
|
||||
PARENT_SCOPE
|
||||
)
|
||||
${HEADERS}
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/colour.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/fbo.h
|
||||
${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
|
||||
${SOURCE}
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/peripherals_glfw.cpp
|
||||
PARENT_SCOPE
|
||||
)
|
||||
${SOURCE}
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/fbo.cpp
|
||||
${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
|
||||
#include <glad/glad.h>
|
||||
|
||||
#define BEGIN_NAMESPACE namespace acidrain {
|
||||
#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
|
||||
#include "peripherals.h"
|
||||
#include <glad/glad.h>
|
||||
|
||||
// forward declares
|
||||
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