Skip to content

Commit

Permalink
Feat: Image resource example
Browse files Browse the repository at this point in the history
  • Loading branch information
brenocq committed Aug 19, 2022
1 parent e8cfcea commit 71017f5
Show file tree
Hide file tree
Showing 10 changed files with 189 additions and 10 deletions.
5 changes: 5 additions & 0 deletions image-resource/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
cmake_minimum_required(VERSION 3.14)
project(image-resource VERSION 1.0.0 LANGUAGES CXX)
find_package(atta 0.1.0.0 REQUIRED)

atta_add_target(projectScript "src/projectScript.cpp")
14 changes: 14 additions & 0 deletions image-resource/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
<!--
title: Image Resource
description: Introduction to atta images
image: https://storage.googleapis.com/atta-images/docs/tutorial/image-resource/2022-08-20.gif
-->
# Image Resource

<div align="center">
<img src="https://storage.googleapis.com/atta-images/docs/tutorial/image-resource/2022-08-20.gif" height="400">
</div>

Images can be created and updated dynamically in atta.

In this example we create two planes and update their textures dynamically.
Binary file added image-resource/image-resource.atta
Binary file not shown.
136 changes: 136 additions & 0 deletions image-resource/src/projectScript.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,136 @@
//--------------------------------------------------
// Image Resource
// projectScript.cpp
// Date: 2022-08-19
// By Breno Cunha Queiroz
//--------------------------------------------------
#include "projectScript.h"
#include <atta/component/interface.h>
#include <atta/resource/interface.h>
#include <atta/resource/resources/image.h>
#include <chrono>

namespace rsc = atta::resource;
namespace cmp = atta::component;
const cmp::Entity plane(0);

void Project::onLoad() {
rsc::Image::CreateInfo info;
info.width = 100;
info.height = 100;
info.format = rsc::Image::Format::RGBA8;
rsc::Image* img = rsc::create<rsc::Image>("animation", info);
rsc::Image* gameOfLife = rsc::create<rsc::Image>("gameOfLife", info);

// Init gameOfLife as white
uint8_t* data = gameOfLife->getData();
for (int i = 0; i < info.width * info.height * 4; i++)
data[i] = 255;

std::vector<atta::vec2i> blinkers = {{10, 10}, {20, 20}, {10, 20}, {20, 10}};
std::vector<atta::vec2i> gliders = {{30, 30}, {20, 50}, {10, 5}, {5, 5}, {80, 30}, {40, 90}, {90, 10}, {90, 50}};
std::vector<atta::vec2i> liveCells = {};

for (atta::vec2i blinker : blinkers) {
liveCells.push_back(blinker + atta::vec2i(0, 0));
liveCells.push_back(blinker + atta::vec2i(1, 0));
liveCells.push_back(blinker + atta::vec2i(0, 1));
}

for (atta::vec2i glider : gliders) {
liveCells.push_back(glider + atta::vec2i(0, -1));
liveCells.push_back(glider + atta::vec2i(1, 0));
liveCells.push_back(glider + atta::vec2i(-1, 1));
liveCells.push_back(glider + atta::vec2i(0, 1));
liveCells.push_back(glider + atta::vec2i(1, 1));
}

for (atta::vec2i cell : liveCells) {
unsigned idx = (cell.y * info.width + cell.x) * 4;
data[idx] = data[idx + 1] = data[idx + 2] = 0;
}

gameOfLife->update();
}

void Project::onAttaLoop() {
updateAnimation();
updateGameOfLife();
}

void Project::updateAnimation() {
static auto start = std::chrono::system_clock::now();
auto end = std::chrono::system_clock::now();
int time = std::chrono::duration_cast<std::chrono::milliseconds>(end - start).count() / 50;

// Change random pattern with time
rsc::Image* img = rsc::get<rsc::Image>("animation");
uint32_t w = img->getWidth();
uint32_t h = img->getHeight();
uint8_t* data = img->getData();
for (int i = 0; i < w * h * 4; i++)
data[i] = 255;

for (int y = 0; y < h; y++)
for (int x = 0; x < w; x++) {
int X = x + time;
int Y = y + time * 2;
X %= w;
Y %= h;
uint32_t idx = (w * Y + X) * 4;
data[idx + 0] = 255 * sin(x / float(w) * M_PI * 5);
data[idx + 1] = 255 * sin(y / float(h) * M_PI * 5);
data[idx + 2] = 255;
}
img->update();
}

void Project::updateGameOfLife() {
static auto start = std::chrono::system_clock::now();
auto end = std::chrono::system_clock::now();
int time = std::chrono::duration_cast<std::chrono::milliseconds>(end - start).count()/100;

// Update every second
if (time > 0) {
start = end;

rsc::Image* gameOfLife = rsc::get<rsc::Image>("gameOfLife");
uint32_t w = gameOfLife->getWidth();
uint32_t h = gameOfLife->getHeight();
uint8_t* data = gameOfLife->getData();

uint8_t* backup = new uint8_t[w * h * 4];
for (int i = 0; i < w * h * 4; i++)
backup[i] = data[i];

for (int y = 0; y < h; y++) {
for (int x = 0; x < w; x++) {
int idx = (y * w + x) * 4;
int numNeighbors = 0;
bool isAlive = backup[idx] == 0;
// Count neightbors
for (int yn = y - 1; yn <= y + 1; yn++)
for (int xn = x - 1; xn <= x + 1; xn++) {
// Ignore center
if (yn == y && xn == x)
continue;
// Wrap coord
int X = (xn + w) % w;
int Y = (yn + h) % h;
if (backup[(Y * w + X) * 4] == 0)
numNeighbors++;
}

// Update cell
if (isAlive && (numNeighbors == 2 || numNeighbors == 3))
continue;
else if (!isAlive && numNeighbors == 3)
data[idx] = data[idx + 1] = data[idx + 2] = 0;
else
data[idx] = data[idx + 1] = data[idx + 2] = 255;
}
}
delete[] backup;
gameOfLife->update();
}
}
25 changes: 25 additions & 0 deletions image-resource/src/projectScript.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
//--------------------------------------------------
// Image Resource
// projectScript.h
// Date: 2022-08-19
// By Breno Cunha Queiroz
//--------------------------------------------------
#ifndef PROJECT_SCRIPT_H
#define PROJECT_SCRIPT_H
#include <atta/script/projectScript.h>

namespace scr = atta::script;

class Project : public scr::ProjectScript {
public:
void onLoad() override;
void onAttaLoop() override;

private:
void updateAnimation();
void updateGameOfLife();
};

ATTA_REGISTER_PROJECT_SCRIPT(Project)

#endif // PROJECT_SCRIPT_H
9 changes: 4 additions & 5 deletions logging/src/projectScript.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,11 @@

namespace scr = atta::script;

class Project : public scr::ProjectScript
{
public:
void onLoad() override;
class Project : public scr::ProjectScript {
public:
void onLoad() override;
};

ATTA_REGISTER_PROJECT_SCRIPT(Project)

#endif// PROJECT_SCRIPT_H
#endif // PROJECT_SCRIPT_H
File renamed without changes.
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
cmake_minimum_required(VERSION 3.14)
project(materials VERSION 1.0.0 LANGUAGES CXX)
project(material-resource VERSION 1.0.0 LANGUAGES CXX)
find_package(atta 0.1.0.0 REQUIRED)

# Download resources
Expand Down
8 changes: 4 additions & 4 deletions materials/README.md → material-resource/README.md
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
<!--
title: Materials
title: Material Resource
description: Introduction to atta materials
image: https://storage.googleapis.com/atta-images/docs/tutorial/materials/2022-08-19.png
image: https://storage.googleapis.com/atta-images/docs/tutorial/material-resource/2022-08-19.png
-->
# Materials
# Material Resource

<div align="center">
<img src="https://storage.googleapis.com/atta-images/docs/tutorial/materials/2022-08-19.png" height="400">
<img src="https://storage.googleapis.com/atta-images/docs/tutorial/material-resource/2022-08-19.png" height="400">
</div>

Entities are only rendered with a material if they also have `cmp::Transform` and `cmp::Mesh` components.
Expand Down
File renamed without changes.

0 comments on commit 71017f5

Please sign in to comment.