-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathRenderer.cpp
More file actions
142 lines (116 loc) · 4.33 KB
/
Renderer.cpp
File metadata and controls
142 lines (116 loc) · 4.33 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
#include "Renderer.hpp"
#include <stdexcept>
#include <iostream>
#include <cmath>
// GLFW error callback
static void errorCallback(int error, const char* description) {
std::cerr << "GLFW Error " << error << ": " << description << std::endl;
}
Renderer::Renderer(int w, int h) : width(w), height(h) {
try {
// Initialize GLFW with error callback
glfwSetErrorCallback(errorCallback);
if (!glfwInit()) {
throw std::runtime_error("Failed to initialize GLFW");
}
// Configure GLFW
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 2);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 1);
glfwWindowHint(GLFW_RESIZABLE, GLFW_FALSE);
// Create window
window = glfwCreateWindow(width, height, "Particle Simulation", nullptr, nullptr);
if (!window) {
glfwTerminate();
throw std::runtime_error("Failed to create GLFW window");
}
glfwMakeContextCurrent(window);
glfwSwapInterval(1); // Enable vsync
// Initialize OpenGL
initializeGL();
// Set up keyboard callback
glfwSetWindowUserPointer(window, this);
glfwSetKeyCallback(window, keyCallback);
} catch (const std::exception& e) {
std::cerr << "Error in Renderer constructor: " << e.what() << std::endl;
if (window) {
glfwDestroyWindow(window);
}
glfwTerminate();
throw;
}
}
Renderer::~Renderer() {
if (window) {
glfwDestroyWindow(window);
}
glfwTerminate();
}
void Renderer::initializeGL() {
try {
// Basic OpenGL setup
glEnable(GL_POINT_SMOOTH);
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glClearColor(0.1f, 0.1f, 0.1f, 1.0f);
// Get actual framebuffer size
int fbWidth, fbHeight;
glfwGetFramebufferSize(window, &fbWidth, &fbHeight);
glViewport(0, 0, fbWidth, fbHeight);
// Set up projection matrix
float aspectRatio = static_cast<float>(fbWidth) / static_cast<float>(fbHeight);
float viewHeight = 20.0f;
float viewWidth = viewHeight * aspectRatio;
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(-viewWidth/2, viewWidth/2, -viewHeight/2, viewHeight/2, -1.0, 1.0);
// Reset to modelview matrix
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
// Check for errors
GLenum err;
while ((err = glGetError()) != GL_NO_ERROR) {
std::cerr << "OpenGL initialization error: " << err << std::endl;
}
std::cout << "OpenGL initialized with viewport: "
<< -viewWidth/2 << " to " << viewWidth/2 << " (X), "
<< -viewHeight/2 << " to " << viewHeight/2 << " (Y)" << std::endl;
} catch (const std::exception& e) {
std::cerr << "Error in initializeGL: " << e.what() << std::endl;
throw;
}
}
void Renderer::render(const std::vector<Particle, AlignedAllocator<Particle>>& particles) {
try {
glClear(GL_COLOR_BUFFER_BIT);
glLoadIdentity();
glPointSize(10.0f); // Make particles larger
glBegin(GL_POINTS);
for (const auto& particle : particles) {
const float* pos = (float*)&particle.position;
// Simple white color for visibility
glColor3f(1.0f, 1.0f, 1.0f);
// Only draw if position is valid
if (std::isfinite(pos[0]) && std::isfinite(pos[1])) {
glVertex2f(pos[0], pos[1]);
}
}
glEnd();
glFlush();
glfwSwapBuffers(window);
glfwPollEvents();
}
catch (const std::exception& e) {
std::cerr << "Error in render: " << e.what() << std::endl;
}
}
bool Renderer::shouldClose() const {
return glfwWindowShouldClose(window);
}
bool Renderer::isKeyPressed(char key) const {
return glfwGetKey(window, static_cast<int>(std::toupper(key))) == GLFW_PRESS;
}
void Renderer::keyCallback(GLFWwindow* window, int key, int /*scancode*/, int action, int /*mods*/) {
if (key == GLFW_KEY_ESCAPE && action == GLFW_PRESS) {
glfwSetWindowShouldClose(window, GLFW_TRUE);
}
}