Skip to content
Snippets Groups Projects
Commit 90b6ceb2 authored by Armin Co's avatar Armin Co
Browse files

Propagating Particle

parent 50078d12
No related branches found
No related tags found
No related merge requests found
...@@ -2,6 +2,7 @@ cmake_minimum_required(VERSION 3.10) ...@@ -2,6 +2,7 @@ cmake_minimum_required(VERSION 3.10)
project(QPong VERSION 0.0.1 LANGUAGES C CXX) project(QPong VERSION 0.0.1 LANGUAGES C CXX)
set(CMAKE_CXX_STANDARD 20) set(CMAKE_CXX_STANDARD 20)
set(CMAKE_BUILD_TYPE Release)
# Check for PkgConfig # Check for PkgConfig
find_package(PkgConfig REQUIRED) find_package(PkgConfig REQUIRED)
......
add_executable(QPongApp add_executable(QPongApp
GameLayer.cpp
Log.cpp Log.cpp
MainMenuLayer.cpp
PlayingLayer.cpp PlayingLayer.cpp
QPongApp.cpp QPongApp.cpp
QPongAppLayer.cpp
Window.cpp Window.cpp
) )
...@@ -16,4 +17,5 @@ target_include_directories(QPongApp PUBLIC ...@@ -16,4 +17,5 @@ target_include_directories(QPongApp PUBLIC
target_link_libraries(QPongApp PUBLIC target_link_libraries(QPongApp PUBLIC
GuiCore GuiCore
fftw3 fftw3
fftw3_omp
) )
/// @file GameLayer.cpp
/// @author Armin Co
///
#include <GL/gl3w.h>
#include <GLFW/glfw3.h>
#include <imgui/imgui.h>
#include <glm/gtc/type_ptr.hpp>
#include <glm/gtc/matrix_transform.hpp>
#include <GuiCore/Log.hpp>
#include <GuiCore/Input.hpp>
#include "GameLayer.hpp"
#include "Log.hpp"
QPong::GameLayer::GameLayer(QPong::GameLayer::Properties props)
:Layer("GameLayer")
, m_vertexShaderPath{"assets/shaders/test.vert.glsl"}
, m_fragmentShaderPath{"assets/shaders/test.frag.glsl"}
, m_arraySize{props.resolution}
, m_propagate{false}
{
m_arrayElements = m_arraySize * m_arraySize;
m_numberOfQuads = (m_arraySize - 1) * (m_arraySize - 1);
m_numberOfIndices = m_numberOfQuads * 6;
m_initialParticleProperties.position.x = 0.0;
m_initialParticleProperties.position.y = 0.0;
m_initialParticleProperties.position.z = 0.0;
m_initialParticleProperties.momentum.x = 0.1;
m_initialParticleProperties.momentum.y = 0.0;
m_initialParticleProperties.momentum.z = 0.00;
m_initialParticleProperties.smoothEdge = 100.0;
m_initialParticleProperties.startValue = 0.1;
m_initialParticleProperties.hbar = 0.0002;
}
void QPong::GameLayer::calculatePointPositions(float *positions)
{
float xMin {-3.0f};
float xMax {0.0f};
float yMin {-1.5f};
float yMax {1.5f};
float dx = (xMax - xMin) / (m_arraySize - 1.0f); // "spacing"
float dy = (yMax - yMin) / (m_arraySize - 1.0f);
{
uint32_t i {0}; // array index
for (uint32_t yId{0}; yId < m_arraySize; ++yId)
{
for (uint32_t xId{0}; xId < m_arraySize; ++xId)
{
positions[i++] = xMin + (static_cast<float>(xId) * dx); // x-Pos
positions[i++] = yMax - (static_cast<float>(yId) * dy); // y-Pos
positions[i++] = 0.0f; // z-Pos
}
}
}
}
void QPong::GameLayer::calculateTriangleIndices(uint32_t *indices)
{
uint32_t i{0};
for (uint32_t row {0}; row < (m_arraySize - 1); ++row)
{
for (uint32_t k {0}; k < (m_arraySize - 1); ++k)
{
uint32_t offset = row * m_arraySize;
indices[i++] = offset + k;
indices[i++] = offset + k + 1;
indices[i++] = offset + k + m_arraySize;
indices[i++] = offset + k + 1;
indices[i++] = offset + k + m_arraySize;
indices[i++] = offset + k + m_arraySize + 1;
}
}
}
double const QPong::GameLayer::posAt(int pos) const
{
return 2.0 * pos / m_arraySize - 1.0;
}
double const QPong::GameLayer::xAtIndex(int i) const
{
return posAt(i % m_arraySize);
}
double const QPong::GameLayer::yAtIndex(int i) const
{
return posAt(i / m_arraySize);
}
double const QPong::GameLayer::potentialAt(int pos) const
{
if (pos > m_arraySize / 2)
{
pos -= m_arraySize;
}
return pos * M_PI * m_initialParticleProperties.hbar;
}
double const QPong::GameLayer::pxAtIndex(int i) const
{
return potentialAt(i % m_arraySize);
}
double const QPong::GameLayer::pyAtIndex(int i) const
{
return potentialAt(i / m_arraySize);
}
template <typename T>
const T pow2(const T v)
{
return v * v;
}
void QPong::GameLayer::initialiseParticleMomentum()
{
constexpr std::complex<double> ci {0.0, 1.0}; // complex number
const double hbar = m_initialParticleProperties.hbar;
const double A0 = m_initialParticleProperties.startValue;
const double px0 = m_initialParticleProperties.momentum.x / 20.0;
const double py0 = m_initialParticleProperties.momentum.y / 20.0;
const double x0 = m_initialParticleProperties.position.x;
const double y0 = m_initialParticleProperties.position.y;
const double lambda = m_initialParticleProperties.smoothEdge;
double sum {0.0};
m_particleAbsouluteSumStart = 0.0;
double y{0.0};
double x{0.0};
for (auto i {0}; i < m_arrayElements; ++i)
{
x = xAtIndex(i);
y = yAtIndex(i);
m_psi[i] = A0 * exp( ci / hbar * ( x * px0 + y * py0) - lambda * (pow2(x-x0) + pow2(y-y0)));
sum += pow2(std::real(m_psi[i])) + pow2(std::imag(m_psi[i]));
}
for (auto i {0}; i < m_arrayElements; ++i)
{
m_psi[i] *= (10.0 * (m_arraySize / 512.0)) / sqrt(sum);
m_particleAbsouluteSumStart += pow2(std::real(m_psi[i])) + pow2(std::imag(m_psi[i]));
}
Log::get()->trace("Particle initialised");
}
void QPong::GameLayer::propagateStep(double dt)
{
constexpr std::complex<double> ci {0.0, 1.0};
const double hbar = m_initialParticleProperties.hbar;
// manipulate particle in postion
double x {0.0};
double y {0.0};
const double potential = 1.0;
for (int i {0}; i < m_arrayElements; ++i)
{
auto psi = m_psi[i] * exp(-ci * dt/hbar * potential * 1.0);
m_psi[i] = psi;
}
// plan forward
fftw_execute(m_planForward);
// manipulate in momentum space
double px {0.0};
double py {0.0};
constexpr double m = 1.0;
const double N = 1.0 / static_cast<double>(m_arrayElements);
for (int i{0}; i<m_arrayElements; ++i)
{
px = pxAtIndex(i);
py = pyAtIndex(i);
double E = (pow2(px) + pow2(py)) / (2.0 * m);
m_psi[i] *= exp(-ci * dt / hbar * E) * N;
}
// plan backwards
fftw_execute(m_planBackwards);
}
void QPong::GameLayer::onAttach()
{
m_shader = GuiCore::Shader::fromGLSLTextFiles(
m_vertexShaderPath,
m_fragmentShaderPath
);
// static verticie positions
float *positions = new float[m_arrayElements * 3];
calculatePointPositions(positions);
// Vertex array to store all buffers
glGenVertexArrays(1, &m_vertexArray);
glBindVertexArray(m_vertexArray);
// Buffer of all point locations
glGenBuffers(1, &m_pointsBuffer);
glBindBuffer(GL_ARRAY_BUFFER, m_pointsBuffer);
glBufferData(GL_ARRAY_BUFFER, sizeof(float) * 3 * (m_arrayElements), positions, GL_STATIC_DRAW);
glEnableVertexAttribArray(0);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(float) * 3, 0);
uint32_t *indices = new uint32_t[m_numberOfIndices];
calculateTriangleIndices(indices);
glGenBuffers(1, &m_indicesBuffer);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_indicesBuffer);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(uint32_t) * m_numberOfIndices, indices, GL_STATIC_DRAW);
delete(positions);
delete(indices);
m_memorySize = sizeof(fftw_complex) * m_arrayElements;
m_psi = static_cast<std::complex<double>*>(fftw_malloc(m_memorySize));
glGenBuffers(1, &m_particleBuffer);
glBindBuffer(GL_ARRAY_BUFFER, m_particleBuffer);
glBufferData(GL_ARRAY_BUFFER, m_memorySize, nullptr, GL_DYNAMIC_DRAW);
glEnableVertexAttribArray(1);
glVertexAttribPointer(1, 2, GL_DOUBLE, GL_FALSE, sizeof(fftw_complex), 0);
// Set orthografic view projectin "camera" which will not change.
m_viewPojection = glm::ortho(-3.2f, 3.2f, -1.8f, 1.8f, -1.0f, 1.0f);
m_viewProjectionLocation = glGetUniformLocation(m_shader->getRendererID(), "u_viewProjection");
fftw_init_threads();
m_planForward = fftw_plan_dft_2d(m_arraySize, m_arraySize, (fftw_complex *)m_psi, (fftw_complex *)m_psi, FFTW_FORWARD, FFTW_MEASURE);
m_planBackwards = fftw_plan_dft_2d(m_arraySize, m_arraySize, (fftw_complex *)m_psi, (fftw_complex *)m_psi, FFTW_BACKWARD, FFTW_MEASURE);
initialiseParticleMomentum();
}
void QPong::GameLayer::onDetach()
{
glDeleteVertexArrays(1, &m_vertexArray);
glDeleteBuffers(1, &m_pointsBuffer);
glDeleteBuffers(1, &m_indicesBuffer);
glDeleteBuffers(1, &m_particleBuffer);
fftw_free(m_psi);
}
void QPong::GameLayer::onEvent(GuiCore::Event& event)
{
}
void QPong::GameLayer::onUpdate(GuiCore::Timestep ts)
{
if (m_restart)
{
initialiseParticleMomentum();
m_restart = false;
}
glBufferSubData(GL_ARRAY_BUFFER, 0, m_memorySize, m_psi);
glUseProgram(m_shader->getRendererID());
glUniformMatrix4fv(m_viewProjectionLocation, 1, GL_FALSE, &m_viewPojection[0][0]);
glBindVertexArray(m_vertexArray);
glDrawElements(GL_TRIANGLES, m_numberOfIndices, GL_UNSIGNED_INT, nullptr);
if (m_propagate)
{
propagateStep(ts.getSeconds()*m_speedScale);
}
}
void QPong::GameLayer::onGuiRender()
{
ImGui::Begin("Controls");
// Select initial momentum
ImGui::DragFloat2("Momentum [x,y]", glm::value_ptr(m_initialParticleProperties.momentum), 0.01f, -1.0f, 1.0f);
ImGui::DragFloat("Speed Factor", &m_speedScale, 0.1, 0.1, 20.0);
// Start/Stop propagating
if (m_propagate)
{
if (ImGui::Button("Pause"))
{
m_propagate = false;
}
}
else
{
if (ImGui::Button("Play"))
{
m_propagate = true;
}
}
// Restart game
if (ImGui::Button("Restart"))
{
m_restart = true;
}
ImGui::End();
}
\ No newline at end of file
/// @file GameLayer.hpp
/// @author Armin Co
///
#ifndef QPONG_GAME_LAYER_HPP
#define QPONG_GAME_LAYER_HPP
#include <glm/glm.hpp>
#include <GuiCore/Layer.hpp>
#include <GuiCore/Shader.hpp>
#include <GuiCore/Timestep.hpp>
#include <complex>
#include <fftw3.h>
namespace QPong
{
class GameLayer : public GuiCore::Layer
{
public:
struct Properties
{
int resolution;
Properties(int res) : resolution {res}{};
};
struct ParticleProps
{
glm::vec3 position;
glm::vec3 momentum;
double smoothEdge;
double startValue;
double hbar;
};
GameLayer(Properties props);
virtual ~GameLayer(){};
virtual void onAttach() override;
virtual void onDetach() override;
virtual void onUpdate(GuiCore::Timestep ts) override;
virtual void onGuiRender() override;
virtual void onEvent(GuiCore::Event &event) override;
private:
void calculatePointPositions(float *points);
void calculateTriangleIndices(uint32_t *indices);
void initialiseParticleMomentum();
void propagateStep(double dt);
// positions at array index
inline const double posAt(int pos) const;
inline const double xAtIndex(int i) const;
inline const double yAtIndex(int i) const;
inline const double potentialAt(int pos) const;
inline const double pxAtIndex(int i) const;
inline const double pyAtIndex(int i) const;
GuiCore::Shader *m_shader;
std::string m_vertexShaderPath;
std::string m_fragmentShaderPath;
int m_arraySize;
int m_arrayElements;
int m_numberOfQuads;
int m_numberOfIndices;
GLuint m_vertexArray; ///< OpenGL object that "knows" all buffers.
GLuint m_pointsBuffer; ///< Buffer with the location for each element in the particle array
GLuint m_indicesBuffer; ///< Indicies to draw trinagles from the points to fill the "canvas"
GLuint m_particleBuffer; ///< Reference for OpenGL to load the paritcle data to the GPU
GLuint m_gameObjectsBuffer; ///< Buffer for game objects like borders and bats.
glm::mat4 m_viewPojection;
int m_viewProjectionLocation;
ParticleProps m_initialParticleProperties;
double m_particleAbsouluteSumStart;
fftw_plan m_planForward;
fftw_plan m_planBackwards;
bool m_restart;
bool m_propagate;
size_t m_memorySize {0};
float m_speedScale {1.0f};
std::complex<double> *m_psi;
};
}
#endif
\ No newline at end of file
/// @file MainMenuLayer.cpp
/// @author Armin Co
///
#include "MainMenuLayer.hpp"
#include <imgui/imgui.h>
#include <GuiCore/Application.hpp>
#include "GameLayer.hpp"
#include <glm/gtc/type_ptr.hpp>
using namespace QPong;
MainMenuLayer::MainMenuLayer()
: m_selectedResolution {512}
, m_resetOnce {false}
, m_gameAttached {false}
{
}
void MainMenuLayer::onAttach()
{
glEnable(GL_DEPTH_TEST);
glDepthFunc(GL_LESS);
m_backgroundColor = {0.2f, 0.2f, 0.2f};
createNewGame();
}
void MainMenuLayer::onDetach()
{
}
void MainMenuLayer::createNewGame()
{
m_resetOnce = false;
if (m_gameAttached)
{
GuiCore::Application::get().popLayer(m_gameLayer);
m_gameAttached = false;
}
m_gameLayer = std::make_shared<GameLayer>(m_selectedResolution);
GuiCore::Application::get().pushLayer(m_gameLayer);
m_gameAttached = true;
}
void MainMenuLayer::onUpdate(GuiCore::Timestep ts)
{
m_fps = 1000.0 / ts.getMilliseconds();
glClearColor(m_backgroundColor.r, m_backgroundColor.g, m_backgroundColor.b, 1.0f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
if (m_resetOnce)
{
createNewGame();
}
}
void MainMenuLayer::onGuiRender()
{
ImGui::Begin("Main Menu");
ImGui::Text("FPS: %3.1f", m_fps);
ImGui::DragInt("Resolution", &m_selectedResolution, 16, 16, 1088);
ImGui::ColorEdit3("Background Color", glm::value_ptr(m_backgroundColor));
if (ImGui::Button("Reset")){ m_resetOnce = true; }
if (ImGui::IsItemHovered()) {
ImGui::SetTooltip("Reinitialise Simulation with selected array resolution.");
}
ImGui::End();
}
void MainMenuLayer::onEvent(GuiCore::Event &event)
{
}
/// @file QPongAppLayer.hpp /// @file MainMenuLayer.hpp
/// @author Armin Co /// @author Armin Co
/// ///
#ifndef QPONG_APP_LAYER_HPP #ifndef QPONG_MAIN_MENU_LAYER_HPP
#define QPONG_APP_LAYER_HPP #define QPONG_MAIN_MENU_LAYER_HPP
#include <glm/glm.hpp>
#include <GuiCore/Layer.hpp> #include <GuiCore/Layer.hpp>
#include <GuiCore/Shader.hpp>
#include <GuiCore/Timestep.hpp> #include <GuiCore/Timestep.hpp>
#include <complex> #include <glm/glm.hpp>
namespace QPong namespace QPong
{ {
class AppLayer : public GuiCore::Layer /// @brief The main menu holds the controls to restart the game
/// with different simulation settings.
///
class MainMenuLayer : public GuiCore::Layer
{ {
public: public:
AppLayer(); MainMenuLayer();
virtual ~AppLayer(){}; virtual ~MainMenuLayer(){};
virtual void onAttach() override; virtual void onAttach() override;
virtual void onDetach() override; virtual void onDetach() override;
virtual void onUpdate(GuiCore::Timestep ts) override; virtual void onUpdate(GuiCore::Timestep ts) override;
...@@ -27,17 +27,14 @@ public: ...@@ -27,17 +27,14 @@ public:
virtual void onEvent(GuiCore::Event &event) override; virtual void onEvent(GuiCore::Event &event) override;
private: private:
GuiCore::Shader *m_shader; void createNewGame();
GLuint m_vertexArray;
GLuint m_pointsBuffer;
GLuint m_indicesBuffer;
GLuint m_particleBuffer;
GLuint m_gameObjectsBuffer;
float m_pixelBrightness = 1.0f; int m_selectedResolution; ///< selected res in the gui
uint32_t m_arraySize; bool m_resetOnce; ///< restart simulation if set
size_t m_memorySize {0}; std::shared_ptr<GuiCore::Layer> m_gameLayer; ///< holds ref to the game
std::complex<double> *m_psi; bool m_gameAttached;
float m_fps;
glm::vec3 m_backgroundColor;
}; };
} }
#endif #endif
\ No newline at end of file
...@@ -22,6 +22,13 @@ namespace QPong ...@@ -22,6 +22,13 @@ namespace QPong
virtual void onEvent(GuiCore::Event &event) override; virtual void onEvent(GuiCore::Event &event) override;
private: private:
bool m_startNow;
struct Player
{
int totalScore;
};
}; };
} }
#endif #endif
\ No newline at end of file
...@@ -6,7 +6,8 @@ ...@@ -6,7 +6,8 @@
#include <GuiCore/Application.hpp> #include <GuiCore/Application.hpp>
#include "QPongAppLayer.hpp" #include "MainMenuLayer.hpp"
#include "GameLayer.hpp"
#include "PlayingLayer.hpp" #include "PlayingLayer.hpp"
#include "Log.hpp" #include "Log.hpp"
class App : public GuiCore::Application class App : public GuiCore::Application
...@@ -16,8 +17,7 @@ public: ...@@ -16,8 +17,7 @@ public:
: Application("QPong Application") : Application("QPong Application")
{ {
QPong::Log::setup(); QPong::Log::setup();
pushLayer(std::make_shared<QPong::AppLayer>()); pushLayer(std::make_shared<QPong::MainMenuLayer>());
pushLayer(std::make_shared<QPong::PlayingLayer>());
} }
}; };
......
/// @file QPongAppLayer.cpp
/// @author Armin Co
///
#include <GL/gl3w.h>
#include <GLFW/glfw3.h>
#include <imgui/imgui.h>
#include <glm/gtc/type_ptr.hpp>
#include <glm/gtc/matrix_transform.hpp>
#include <GuiCore/Log.hpp>
#include <GuiCore/Input.hpp>
#include "QPongAppLayer.hpp"
#include <fftw3.h>
QPong::AppLayer::AppLayer()
:Layer("QPongAppLayer")
, m_arraySize{256}
{
}
void QPong::AppLayer::onAttach()
{
glEnable(GL_DEPTH_TEST);
glDepthFunc(GL_LESS);
m_shader = GuiCore::Shader::fromGLSLTextFiles(
"assets/shaders/test.vert.glsl",
"assets/shaders/test.frag.glsl"
);
// static verticie positions
float *positions = new float[m_arraySize * m_arraySize * 3];
float xMin {-3.0f};
float xMax {0.0f};
float yMin {-1.5f};
float yMax {1.5f};
float dx = (xMax - xMin) / (m_arraySize - 1.0f); // "spacing"
float dy = (yMax - yMin) / (m_arraySize - 1.0f);
{
uint32_t i {0}; // array index
for (uint32_t yId{0}; yId < m_arraySize; ++yId)
{
for (uint32_t xId{0}; xId < m_arraySize; ++xId)
{
positions[i++] = xMin + (static_cast<float>(xId) * dx); // x-Pos
positions[i++] = yMax - (static_cast<float>(yId) * dy); // y-Pos
positions[i++] = 0.0f; // z-Pos
}
}
}
// Vertex array to store all buffers
glGenVertexArrays(1, &m_vertexArray);
glBindVertexArray(m_vertexArray);
// Buffer of all point locations
glGenBuffers(1, &m_pointsBuffer);
glBindBuffer(GL_ARRAY_BUFFER, m_pointsBuffer);
glBufferData(GL_ARRAY_BUFFER, sizeof(float) * 3 * (m_arraySize * m_arraySize), positions, GL_STATIC_DRAW);
glEnableVertexAttribArray(0);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(float) * 3, 0);
uint32_t numQuads = (m_arraySize - 1) * (m_arraySize - 1);
uint32_t numIndices = numQuads * 6;
uint32_t *indices = new uint32_t[numIndices];
{
uint32_t i{0};
for (uint32_t row {0}; row < (m_arraySize - 1); ++row)
{
for (uint32_t k {0}; k < (m_arraySize - 1); ++k)
{
uint32_t offset = row * m_arraySize;
indices[i++] = offset + k;
indices[i++] = offset + k + 1;
indices[i++] = offset + k + m_arraySize;
indices[i++] = offset + k + 1;
indices[i++] = offset + k + m_arraySize;
indices[i++] = offset + k + m_arraySize + 1;
}
}
}
glGenBuffers(1, &m_indicesBuffer);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_indicesBuffer);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(uint32_t) * numIndices, indices, GL_STATIC_DRAW);
delete(positions);
delete(indices);
// allocate color buffer
// m_psi = new float[m_arraySize * m_arraySize * 3];
m_memorySize = sizeof(fftw_complex) * m_arraySize * m_arraySize;
m_psi = static_cast<std::complex<double>*>(fftw_malloc(m_memorySize));
glGenBuffers(1, &m_particleBuffer);
glBindBuffer(GL_ARRAY_BUFFER, m_particleBuffer);
glBufferData(GL_ARRAY_BUFFER, m_memorySize, nullptr, GL_DYNAMIC_DRAW);
glEnableVertexAttribArray(1);
glVertexAttribPointer(1, 2, GL_DOUBLE, GL_FALSE, sizeof(fftw_complex), 0);
}
void QPong::AppLayer::onDetach()
{
glDeleteVertexArrays(1, &m_vertexArray);
glDeleteBuffers(1, &m_pointsBuffer);
glDeleteBuffers(1, &m_indicesBuffer);
glDeleteBuffers(1, &m_particleBuffer);
fftw_free(m_psi);
}
void QPong::AppLayer::onEvent(GuiCore::Event& event)
{
// Events here
}
void QPong::AppLayer::onUpdate(GuiCore::Timestep ts)
{
uint32_t i {0};
using namespace std::complex_literals;
std::complex<double> color = static_cast<double>(m_pixelBrightness) + 1i;
while (i < m_arraySize * m_arraySize)
{
m_psi[i++] = color;
}
glBufferSubData(GL_ARRAY_BUFFER, 0, m_memorySize, m_psi);
glClearColor(0.1f, 0.1f, 0.1f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glUseProgram(m_shader->getRendererID());
glm::mat4 proj = glm::ortho(-3.2f, 3.2f, -1.8f, 1.8f, -1.0f, 1.0f);
int location = glGetUniformLocation(m_shader->getRendererID(), "u_ViewProjection");
glUniformMatrix4fv(location, 1, GL_FALSE, &proj[0][0]);
glBindVertexArray(m_vertexArray);
uint32_t numQuads = (m_arraySize - 1) * (m_arraySize - 1);
uint32_t numIndices = numQuads * 6;
glDrawElements(GL_TRIANGLES, numIndices, GL_UNSIGNED_INT, nullptr);
}
void QPong::AppLayer::onGuiRender()
{
ImGui::Begin("Controls");
auto[x,y] = GuiCore::Input::getMousePosition();
ImGui::Text("%f,%f", x, y);
ImGui::DragFloat("Pixel Brightness", &m_pixelBrightness, 0.005f, 0.0f, 1.0f);
ImGui::End();
}
\ No newline at end of file
#version 450 core #version 450 core
in vec3 fragmentColor; in vec3 v_fragmentColor;
out vec3 pixelColor; out vec3 pixelColor;
void main() void main()
{ {
pixelColor = fragmentColor; pixelColor = v_fragmentColor;
} }
\ No newline at end of file
#version 450 core #version 450 core
layout (location = 0) in vec3 v_position; layout (location = 0) in vec3 v_position;
layout (location = 1) in vec2 v_particle_complex; layout (location = 1) in vec2 v_particle_complex;
uniform mat4 u_ViewProjection; uniform mat4 u_viewProjection;
out vec3 fragmentColor; out vec3 fragmentColor;
void main() void main()
{ {
gl_Position = u_ViewProjection * vec4(v_position, 1.0f); gl_Position = u_viewProjection * vec4(v_position, 1.0f);
float real = v_particle_complex[0];
float imag = v_particle_complex[1];
float real2 = real * real;
float imag2 = imag * imag;
fragmentColor = vec3( fragmentColor = vec3(
0.0f, sqrt(real2) * 20.0,
v_particle_complex[0] * v_particle_complex[0], sqrt(real2) * 15.0 + sqrt(imag2) * 15.0,
v_particle_complex[1] * v_particle_complex[1]); sqrt(imag2) * 20.0);
} }
\ No newline at end of file
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment