source: opengl-game/pong.cpp@ 237ec28

feature/imgui-sdl points-test
Last change on this file since 237ec28 was 237ec28, checked in by Dmitry Portnoy <dmp1488@…>, 7 years ago

Finish writing the logic to create circles, and make the ball bounce of the paddle and the back wall

  • Property mode set to 100644
File size: 8.2 KB
Line 
1#include "logger.h"
2
3#include <GL/glew.h>
4#include <GLFW/glfw3.h>
5
6#include <cstdio>
7#include <iostream>
8#include <fstream>
9#include <cmath>
10
11using namespace std;
12
13GLuint loadShader(GLenum type, string file);
14GLuint createDataBuffer(size_t size, GLfloat* data);
15GLuint createArrayBuffer(GLuint points_vbo, GLuint colors_vbo);
16
17GLfloat* createCirclePoints(unsigned int smoothness, GLfloat centerX, GLfloat centerY, GLfloat radius);
18GLfloat* createCircleColors(unsigned int smoothness);
19
20const double PI = 3.1415926535897;
21const bool FULLSCREEN = false;
22
23void glfw_error_callback(int error, const char* description) {
24 gl_log_err("GLFW ERROR: code %i msg: %s\n", error, description);
25}
26
27int main(int argc, char* argv[]) {
28 cout << "New OpenGL Game" << endl;
29
30 if (!restart_gl_log()) {}
31 gl_log("starting GLFW\n%s\n", glfwGetVersionString());
32
33 glfwSetErrorCallback(glfw_error_callback);
34 if (!glfwInit()) {
35 fprintf(stderr, "ERROR: could not start GLFW3\n");
36 return 1;
37 }
38
39#ifdef __APPLE__
40 glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
41 glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
42 glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE);
43 glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
44#endif
45
46 glfwWindowHint(GLFW_SAMPLES, 4);
47
48 GLFWwindow* window = NULL;
49
50 int width = 640;
51 int height = 480;
52
53 if (FULLSCREEN) {
54 GLFWmonitor* mon = glfwGetPrimaryMonitor();
55 const GLFWvidmode* vmode = glfwGetVideoMode(mon);
56
57 cout << "Fullscreen resolution " << vmode->width << "x" << vmode->height << endl;
58 window = glfwCreateWindow(vmode->width, vmode->height, "Extended GL Init", mon, NULL);
59
60 width = vmode->width;
61 height = vmode->height;
62 } else {
63 window = glfwCreateWindow(width, height, "Hello Triangle", NULL, NULL);
64 }
65
66 if (!window) {
67 fprintf(stderr, "ERROR: could not open window with GLFW3\n");
68 glfwTerminate();
69 return 1;
70 }
71 glfwMakeContextCurrent(window);
72 glewExperimental = GL_TRUE;
73 glewInit();
74
75 // glViewport(0, 0, width*2, height*2);
76
77 const GLubyte* renderer = glGetString(GL_RENDERER);
78 const GLubyte* version = glGetString(GL_VERSION);
79 printf("Renderer: %s\n", renderer);
80 printf("OpenGL version supported %s\n", version);
81
82 glEnable(GL_DEPTH_TEST);
83 glDepthFunc(GL_LESS);
84
85 glEnable(GL_CULL_FACE);
86 // glCullFace(GL_BACK);
87 // glFrontFace(GL_CW);
88
89 unsigned int numBallPoints = 36;
90
91 GLfloat ballRadius = 0.2f;
92 GLfloat paddleThickness = 0.1f;
93
94 GLfloat* points = createCirclePoints(numBallPoints, 0.0f, 0.0f, ballRadius);
95 GLfloat* colors = createCircleColors(numBallPoints);
96
97 GLfloat points_paddle[] = {
98 -1.0f, 0.15f, 0.0f,
99 -1.0f, -0.15f, 0.0f,
100 -0.9f, -0.15f, 0.0f,
101 -1.0f, 0.15f, 0.0f,
102 -0.9f, -0.15f, 0.0f,
103 -0.9f, 0.15f, 0.0f,
104 };
105
106 GLfloat colors_paddle[] = {
107 1.0, 0.0, 0.0,
108 1.0, 0.0, 0.0,
109 1.0, 0.0, 0.0,
110 1.0, 0.0, 0.0,
111 1.0, 0.0, 0.0,
112 1.0, 0.0, 0.0,
113 };
114
115 GLfloat model[] = {
116 1.0f, 0.0f, 0.0f, 0.0f, // column 1
117 0.0f, 1.0f, 0.0f, 0.0f, // column 2
118 0.0f, 0.0f, 1.0f, 0.0f, // column 3
119 0.0f, 0.0f, 0.0f, 1.0f, // column 4
120 };
121
122 GLuint ball_points_vbo = createDataBuffer(numBallPoints*9*sizeof(GLfloat), points);
123 GLuint ball_colors_vbo = createDataBuffer(numBallPoints*9*sizeof(GLfloat), colors);
124 GLuint ball_vao = createArrayBuffer(ball_points_vbo, ball_colors_vbo);
125
126 GLuint paddle_points_vbo = createDataBuffer(sizeof(points_paddle), points_paddle);
127 GLuint paddle_colors_vbo = createDataBuffer(sizeof(colors_paddle), colors_paddle);
128 GLuint paddle_vao = createArrayBuffer(paddle_points_vbo, paddle_colors_vbo);
129
130 GLuint vs = loadShader(GL_VERTEX_SHADER, "./test.vert");
131 GLuint fs = loadShader(GL_FRAGMENT_SHADER, "./test.frag");
132
133 GLuint shader_program = glCreateProgram();
134 glAttachShader(shader_program, vs);
135 glAttachShader(shader_program, fs);
136
137 glLinkProgram(shader_program);
138 glUseProgram(shader_program);
139
140 GLint location = glGetUniformLocation(shader_program, "model");
141
142 float speed = 1.0f;
143 float last_position = 0.0f;
144 float last_paddle_pos = 0.0f;
145
146 double previous_seconds = glfwGetTime();
147 while (!glfwWindowShouldClose(window)) {
148 double current_seconds = glfwGetTime();
149 double elapsed_seconds = current_seconds - previous_seconds;
150 previous_seconds = current_seconds;
151
152 if (last_position > 1.0f-ballRadius) {
153 speed = -speed;
154 }
155
156 if (last_position < -1.0f+ballRadius+paddleThickness &&
157 fabs(last_paddle_pos) < 0.15f) {
158 speed = -speed;
159 }
160
161 // if the ball hits the paddle on a corner, I should make it bounce
162 // off at an angle
163
164 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
165
166 model[12] = 0.0f;
167 model[13] = last_paddle_pos;
168 glUniformMatrix4fv(location, 1, GL_FALSE, model);
169
170 glBindVertexArray(paddle_vao);
171 glEnableVertexAttribArray(0);
172 glEnableVertexAttribArray(1);
173
174 glDrawArrays(GL_TRIANGLES, 0, sizeof(points_paddle)/sizeof(GLfloat)/3);
175
176 model[12] = last_position + speed*elapsed_seconds;
177 last_position = model[12];
178 model[13] = 0.0f;
179 glUniformMatrix4fv(location, 1, GL_FALSE, model);
180
181 glBindVertexArray(ball_vao);
182 glEnableVertexAttribArray(0);
183 glEnableVertexAttribArray(1);
184
185 glDrawArrays(GL_TRIANGLES, 0, numBallPoints*3);
186
187 glfwPollEvents();
188 glfwSwapBuffers(window);
189
190 if (GLFW_PRESS == glfwGetKey(window, GLFW_KEY_ESCAPE)) {
191 glfwSetWindowShouldClose(window, 1);
192 }
193 if (GLFW_PRESS == glfwGetKey(window, GLFW_KEY_UP)) {
194 last_paddle_pos += 1.0f * elapsed_seconds;
195 if (last_paddle_pos > 0.85f) {
196 last_paddle_pos = 0.85f;
197 }
198 }
199 if (GLFW_PRESS == glfwGetKey(window, GLFW_KEY_DOWN)) {
200 last_paddle_pos -= 1.0f * elapsed_seconds;
201 if (last_paddle_pos < -0.85f) {
202 last_paddle_pos = -0.85f;
203 }
204 }
205 }
206
207 glfwTerminate();
208
209 delete points;
210 delete colors;
211
212 return 0;
213}
214
215GLuint loadShader(GLenum type, string file) {
216 cout << "Loading shader from file " << file << endl;
217
218 ifstream shaderFile(file);
219 GLuint shaderId = 0;
220
221 if (shaderFile.is_open()) {
222 string line, shaderString;
223
224 while(getline(shaderFile, line)) {
225 shaderString += line + "\n";
226 }
227 shaderFile.close();
228 const char* shaderCString = shaderString.c_str();
229
230 shaderId = glCreateShader(type);
231 glShaderSource(shaderId, 1, &shaderCString, NULL);
232 glCompileShader(shaderId);
233
234 cout << "Loaded successfully" << endl;
235 } else {
236 cout << "Failed to loade the file" << endl;
237 }
238
239 return shaderId;
240}
241
242GLuint createDataBuffer(size_t size, GLfloat* data) {
243 GLuint vbo = 0;
244 glGenBuffers(1, &vbo);
245 glBindBuffer(GL_ARRAY_BUFFER, vbo);
246 glBufferData(GL_ARRAY_BUFFER, size, data, GL_STATIC_DRAW);
247 return vbo;
248}
249
250GLuint createArrayBuffer(GLuint points_vbo, GLuint colors_vbo) {
251 GLuint vao = 0;
252 glGenVertexArrays(1, &vao);
253 glBindVertexArray(vao);
254 glBindBuffer(GL_ARRAY_BUFFER, points_vbo);
255 glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, NULL);
256 glBindBuffer(GL_ARRAY_BUFFER, colors_vbo);
257 glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 0, NULL);
258 return vao;
259}
260
261GLfloat* createCirclePoints(unsigned int smoothness, GLfloat centerX, GLfloat centerY, GLfloat radius) {
262 GLfloat* points = new GLfloat[smoothness*9];
263
264 GLfloat curX, curY, nextX, nextY;
265 curX = centerX;
266 curY = centerY+radius;
267
268 for (unsigned int i=0; i<smoothness; i++) {
269 double radians = PI/2 + 2*PI * (i+1)/smoothness;
270 nextX = centerX + cos(radians)*radius;
271 nextY = centerY + sin(radians)*radius;
272
273 points[i*9] = curX;
274 points[i*9+1] = curY;
275 points[i*9+2] = 0.5f;
276 points[i*9+3] = nextX;
277 points[i*9+4] = nextY;
278 points[i*9+5] = 0.5f;
279 points[i*9+6] = centerX;
280 points[i*9+7] = centerY;
281 points[i*9+8] = 0.5f;
282
283 curX = nextX;
284 curY = nextY;
285 }
286
287 return points;
288}
289
290GLfloat* createCircleColors(unsigned int smoothness) {
291 GLfloat* colors = new GLfloat[smoothness*9];
292
293 for (unsigned int i=0; i<smoothness*3; i++) {
294 colors[i*3] = 0.0f;
295 colors[i*3+1] = 1.0f;
296 colors[i*3+2] = 0.0f;
297 }
298
299 return colors;
300}
Note: See TracBrowser for help on using the repository browser.