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

Propagating Particle

parent 50078d12
Branches
Tags
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