| 133 | |
| 134 | |
| 135 | bool OnUserUpdate(float fElapsedTime) override |
| 136 | { |
| 137 | // spin stuff |
| 138 | fThetaX += fElapsedTime * 0.1f; |
| 139 | fThetaY += fElapsedTime * 0.05f; |
| 140 | |
| 141 | olc::mf4d m1, m2, m3, m4; |
| 142 | |
| 143 | // fake a pseudo-view matrix by transforming in an identity view |
| 144 | m1.rotateY(fThetaY); |
| 145 | m2.rotateX(fThetaX); |
| 146 | m3.translate(0.0, 0.0, -10.0); |
| 147 | matView = m3 * m2 * m1; |
| 148 | |
| 149 | // Clear background |
| 150 | ClearBuffer(olc::CYAN, true); |
| 151 | |
| 152 | // Update light positions |
| 153 | fLightTime += fElapsedTime; |
| 154 | lights[0] = { 6.0f * sin(fLightTime * 2.5f), 6.0f * cos(fLightTime * 2.5f), 0.0f }; |
| 155 | lights[1] = { 0.0f, 6.0f * sin(fLightTime), 6.0f * cos(fLightTime) }; |
| 156 | lights[2] = { 6.0f * cos(fLightTime * 1.7f), 0.0f, 6.0f * sin(fLightTime * 1.7f) }; |
| 157 | |
| 158 | // World Space lighting! The 3 lights are used as directional light sources |
| 159 | // so i dont need to pre-compute all the geometry on the CPU. This is a |
| 160 | // limitation of the hw3d approach but like I said, its for basic 3D usage. |
| 161 | for (size_t i = 0; i < meshCube.pos.size(); i += 3) |
| 162 | { |
| 163 | const auto& p0 = meshCube.pos[i + 0]; |
| 164 | const auto& p1 = meshCube.pos[i + 1]; |
| 165 | const auto& p2 = meshCube.pos[i + 2]; |
| 166 | |
| 167 | // Hand calculate surface normal (i know i know the norms are already there...) |
| 168 | olc::vf3d vCross = olc::vf3d(p1[0] - p0[0], p1[1] - p0[1], p1[2] - p0[2]).cross(olc::vf3d(p2[0] - p0[0], p2[1] - p0[1], p2[2] - p0[2])).norm(); |
| 169 | |
| 170 | // Additive colouring |
| 171 | meshCube.col[i + 0] = olc::BLACK; |
| 172 | meshCube.col[i + 1] = olc::BLACK; |
| 173 | meshCube.col[i + 2] = olc::BLACK; |
| 174 | |
| 175 | olc::Pixel c[] = { olc::RED, olc::GREEN, olc::BLUE }; |
| 176 | for (int j = 0; j < 3; j++) |
| 177 | { |
| 178 | olc::vf3d vLight = -lights[j].norm(); |
| 179 | float illum = std::max(-vCross.dot(vLight), 0.0f) * 0.8f + 0.2f; |
| 180 | meshCube.col[i + 0] += olc::PixelF(illum, illum, illum, 1.0f) * c[j]; |
| 181 | meshCube.col[i + 1] += olc::PixelF(illum, illum, illum, 1.0f) * c[j]; |
| 182 | meshCube.col[i + 2] += olc::PixelF(illum, illum, illum, 1.0f) * c[j]; |
| 183 | } |
| 184 | } |
| 185 | |
| 186 | |
| 187 | // Draw all cubes |
| 188 | for (const auto& cube : cubes) |
| 189 | { |
| 190 | matWorld.translate(cube); |
| 191 | HW3D_DrawObject((matView * matWorld).m, texCube.Decal(), meshCube.layout, meshCube.pos, meshCube.uv, meshCube.col); |
| 192 | } |