Cogs.Core
CurtainViewSystem.cpp
1#include "CurtainViewSystem.h"
2
3#include "Resources/MaterialManager.h"
4#include "Resources/MeshManager.h"
5#include "Resources/TextureManager.h"
6
7#include "Components/Core/MeshComponent.h"
8#include "Components/Core/MeshRenderComponent.h"
9
11{
13}
15{
16 for (auto & component : pool) {
17 CurtainViewData &data = getData(&component);
18 auto entity = component.getContainer();
19 // Swap resources
20 if (data.uploading && data.texture[1]->isActive() && data.mesh[1]->isActive()) {
21 data.uploading = false;
22 // Swap Mesh
23 auto tmp0 = data.mesh[0];
24 data.mesh[0] = data.mesh[1];
25 data.mesh[1] = tmp0;
26 auto* meshComp = entity->getComponent<MeshComponent>();
27 meshComp->meshHandle = data.mesh[0];
28 meshComp->setChanged();
29 // Swap textures
30 TextureHandle tmp = data.texture[0];
31 data.texture[0] = data.texture[1];
32 data.texture[1] = tmp;
33 auto key = material->getTextureKey("Velocity");
34 data.material->setTextureAddressMode(key, SamplerState::Clamp);
35 data.material->setTextureProperty(key, data.texture[0]);
36 }
37 if(!component.hasChanged()) continue;
38
39 // Update Gradient
40 {
41 auto key = material->getTextureKey("Gradient");
42 if(component.gradientClamp) data.material->setTextureAddressMode(key, SamplerState::Clamp);
43 else data.material->setTextureAddressMode(key, SamplerState::Wrap);
44 data.material->setTextureProperty(key, component.gradient);
45 }
46 // Update Material Data
47 {
48 float mul = 1.0f/(component.max-component.min);
49 float add = -component.min*mul;
50 data.material->setProperty("gradientMul", &mul, sizeof(mul));
51 data.material->setProperty("gradientAdd", &add, sizeof(add));
52 data.material->setVariant("ShadedCurtain", component.shadedCurtain);
53 data.material->setProperty("gloss", &component.gloss, sizeof(component.gloss));
54 data.material->setProperty("specular", &component.specular, sizeof(component.specular));
55 }
56 // Set Material
57 {
58 auto meshRenderComp = entity->getComponent<MeshRenderComponent>();
59 meshRenderComp->material = data.material;
60 meshRenderComp->setChanged();
61 }
62 // Upload resources
63 if(data.uploading) continue;
64 if(component.positions == nullptr || component.positions.size() <= 1 || component.depth <= 1) continue;
65 data.uploading = true;
66 {
67 uint32_t width = (uint32_t)component.positions.size();
68 uint32_t mesh_height = 2;
69 std::vector<glm::vec3> vertexBuffer(width*mesh_height);
70 std::vector<glm::vec2> texCoordBuffer(width*mesh_height);
71 for(uint32_t w=0; w<width; w++){
72 glm::vec3 p0 = component.positions[w];
73 glm::vec3 p1 = component.end[w];
74
75 int sampleOffset = component.sampleOffsets[w];
76 int numSamples = component.samples[w];
77 float firstTextureCoord = sampleOffset / (float)component.depth;
78 float lastTextureCoord = (sampleOffset + numSamples) / (float)component.depth;
79
80 for(uint32_t h=0; h<mesh_height; h++){
81 uint32_t idx = w*mesh_height+h;
82 float rate = h/(float)(mesh_height-1);
83 glm::vec3 p = p0*(1.0f-rate) + p1*(rate);
84 vertexBuffer[idx] = p;
85
86 float tx = firstTextureCoord * (1.0f-rate) + lastTextureCoord *rate;
87 texCoordBuffer[idx] = glm::vec2(tx, (w+0.5f)/(float)(width));
88 }
89 }
90 std::vector<uint32_t> indexBuffer(width*2*(mesh_height-1) + (mesh_height-2)*2);
91 for(uint32_t h=0; h<mesh_height-1; h++){
92 for(uint32_t w=0; w<width; w++){
93 uint32_t idx = (h*width+w)*2 + h*2;
94 if(w==0 && h!=0) indexBuffer[idx-1] = w*mesh_height+h;
95 indexBuffer[idx+0] = w*mesh_height+h;
96 indexBuffer[idx+1] = w*mesh_height+(h+1);
97 if(w==width-2 && h!=mesh_height-2) indexBuffer[idx+4] = (w+1)*mesh_height+(h+1);
98 }
99 }
100 std::vector<glm::vec3> normalBuffer(width*mesh_height, glm::vec3(0.0));
101 for(uint32_t h=0; h<mesh_height-1; h++){
102 for(uint32_t w=0; w<(width-1); w++){
103 int ia = w*mesh_height+h;
104 int ib = w*mesh_height+(h+1);
105 int ic = (w+1)*mesh_height+h;
106 int id = (w+1)*mesh_height+(h+1);
107 glm::vec3 a = vertexBuffer[ia];
108 glm::vec3 b = vertexBuffer[ib];
109 glm::vec3 c = vertexBuffer[ic];
110 glm::vec3 d = vertexBuffer[id];
111 glm::vec3 na = glm::cross(b-a, c-a);
112 glm::vec3 nb = glm::cross(c-d, b-d);
113 normalBuffer[ia] += na;
114 normalBuffer[ib] += na + nb;
115 normalBuffer[ic] += na + nb;
116 normalBuffer[id] += nb;
117 }
118 }
119 for(uint32_t i=0; i<normalBuffer.size(); i++)
120 normalBuffer[i] = glm::normalize(normalBuffer[i]);
121 MeshHandle &mesh = data.mesh[1];
123 mesh->setPositions(vertexBuffer.data(), vertexBuffer.data()+vertexBuffer.size());
124 mesh->setNormals(normalBuffer.data(), normalBuffer.data()+normalBuffer.size());
125 mesh->setTexCoords(texCoordBuffer.data(), texCoordBuffer.data()+texCoordBuffer.size());
126 mesh->setIndexes(std::move(indexBuffer));
127 }
128 // Update Velocity
129 {
130 ResourceId id = data.texture->getId();
131 TextureFormat format = TextureFormat::R32_FLOAT;
132 int width = (int)component.positions.size();
133 int stride = 0;
134 data.texture[1] = context->textureManager->loadTexture2D((void*)component.velocity.data(), component.depth, width, format, stride, id, TextureLoadFlags::LinearColorSpace);
135 }
136 }
137}
138
140{
141 material = context->materialManager->loadMaterial("Materials/Curtain.material");
142 context->materialManager->processLoading();
143
146 CurtainViewData &data = getData(component);
147
148 data.material = context->materialInstanceManager->createMaterialInstance(material);
149 data.mesh[0] = context->meshManager->create();
150 data.mesh[1] = context->meshManager->create();
151 data.texture[0] = context->textureManager->getOrCreate(context->textureManager->getNextResourceId());
152 data.texture[1] = context->textureManager->getOrCreate(context->textureManager->getNextResourceId());
153
154 if(component->gradient == TextureHandle::NoHandle){
155 component->gradient = context->textureManager->getOrCreate(context->textureManager->getNextResourceId());
156 uint32_t colors[] = {0xfff9fb15, 0xfff8ba3d, 0xff81cc59, 0xff0bbdbd, 0xff2b91ef, 0xff4758f8, 0xff3e26a8};
157 TextureFormat format = TextureFormat::R8G8B8A8_UNORM_SRGB;
158
159 for(size_t i=0; i<sizeof(colors)/sizeof(colors[0]); i++){
160 uint32_t color = colors[i];
161 uint32_t ret = color;
162 ret = ret & 0xff000000;
163 ret |= (((uint32_t)(powf(((color>>0)&0xff)*(1.0f/255.0f), 1.0f/2.2f)*255.0f))&0xff)<<0;
164 ret |= (((uint32_t)(powf(((color>>8)&0xff)*(1.0f/255.0f), 1.0f/2.2f)*255.0f))&0xff)<<8;
165 ret |= (((uint32_t)(powf(((color>>16)&0xff)*(1.0f/255.0f), 1.0f/2.2f)*255.0f))&0xff)<<16;
166 colors[i] = ret;
167 }
168
170 info.resourceId = component->gradient->getId();
171 info.target = ResourceDimensions::Texture2D;
172 info.resourceData.resize(sizeof(colors));
173 memcpy(info.resourceData.data(), (const void*)&colors[0], sizeof(colors));
175 info.handle = component->gradient;
176 info.format = format;
177 if(component->gradientClamp)
178 info.addressMode = SamplerState::AddressMode::Clamp;
179 else
180 info.addressMode = SamplerState::AddressMode::Wrap;
181 info.width = static_cast<int>(sizeof(colors)/sizeof(colors[0]));
182 info.height = 1;
183 info.depth = 1;
184 info.stride = 0;
185 info.flip = 0;
186 info.preloading = false;
187 context->textureManager->loadFromData(&info);
188 assert((component->gradient->description.flags & TextureFlags::GenerateMipMaps) == 0);
189 component->gradient->description.target = ResourceDimensions::Texture2D;
190 }
191
192 return handle;
193}
virtual ComponentHandle createComponent()
Create a new component instance.
Context * context
Pointer to the Context instance the system lives in.
virtual void initialize(Context *context)
Initialize the system.
void update()
Updates the system state to that of the current frame.
A Context instance contains all the services, systems and runtime components needed to use Cogs.
Definition: Context.h:83
Contains a handle to a Mesh resource to use when rendering using the MeshRenderComponent.
Definition: MeshComponent.h:15
MeshHandle meshHandle
Handle to a Mesh resource to use when rendering.
Definition: MeshComponent.h:29
Renders the contents of a MeshComponent using the given materials.
MaterialInstanceHandle material
Material used to render the mesh.
ResourceLoadFlags
Flags for describing how to load a resource.
Definition: ResourceFlags.h:16
@ LinearColorSpace
For textures with RGBA format without color space information, mark the data as being in linear color...
Handle to a Component instance.
Definition: Component.h:67
ComponentType * resolveComponent() const
Definition: Component.h:90
void initialize(Context *context) override
Initialize the system.
void setIndexes(std::span< const uint32_t > collection)
Set the index data to the collection given.
Definition: Mesh.h:596
void setTexCoords(std::span< const glm::vec2 > texCoords)
Set the texture coordinate data of the Mesh.
Definition: Mesh.h:504
void setNormals(std::span< const glm::vec3 > normals)
Set the normal data of the Mesh.
Definition: Mesh.h:392
void setPositions(std::span< const glm::vec3 > positions)
Set the position data of the Mesh.
Definition: Mesh.h:315
ResourceId getId() const
Get the resource id of this instance.
Definition: ResourceBase.h:215
static const ResourceHandle_t NoHandle
Handle representing a default (or none if default not present) resource.
ResourceId resourceId
Unique resource identifier. Must be unique among resources of the same kind.
ResourceHandleBase handle
Handle to resource structure for holding actual resource data.
std::vector< uint8_t > resourceData
Resource load data.
ResourceLoadFlags loadFlags
Desired loading flags. Used to specify how the resource will be loaded.
@ TriangleStrip
Triangle strip.
Definition: Common.h:118
@ Clamp
Texture coordinates are clamped to the [0, 1] range.
Definition: SamplerState.h:17
@ Wrap
Texture coordinates automatically wrap around to [0, 1] range.
Definition: SamplerState.h:19
@ GenerateMipMaps
The texture supports automatic mipmap generation performed by the graphics device.
Definition: Flags.h:124