1 | /******************************************************************************************* |
2 | * |
3 | * raylib [rlgl] example - Using rlgl module as standalone module |
4 | * |
5 | * NOTE: This example requires OpenGL 3.3 or ES2 versions for shaders support, |
6 | * OpenGL 1.1 does not support shaders but it can also be used. |
7 | * |
8 | * DEPENDENCIES: |
9 | * rlgl.h - OpenGL 1.1 immediate-mode style coding translation layer |
10 | * glad.h - OpenGL extensions initialization library (required by rlgl) |
11 | * raymath.h - 3D math library (required by rlgl) |
12 | * glfw3 - Windows and context initialization library |
13 | * |
14 | * rlgl library is provided as a single-file header-only library, this library |
15 | * allows coding in a pseudo-OpenGL 1.1 style while translating calls to multiple |
16 | * OpenGL versions backends (1.1, 2.1, 3.3, ES 2.0). |
17 | * |
18 | * COMPILATION: |
19 | * gcc -o rlgl_standalone.exe rlgl_standalone.c -s -Iexternal\include -I..\..\src \ |
20 | * -L. -Lexternal\lib -lglfw3 -lopengl32 -lgdi32 -Wall -std=c99 -DGRAPHICS_API_OPENGL_33 |
21 | * |
22 | * LICENSE: zlib/libpng |
23 | * |
24 | * This example is licensed under an unmodified zlib/libpng license, which is an OSI-certified, |
25 | * BSD-like license that allows static linking with closed source software: |
26 | * |
27 | * Copyright (c) 2014-2019 Ramon Santamaria (@raysan5) |
28 | * |
29 | * This software is provided "as-is", without any express or implied warranty. In no event |
30 | * will the authors be held liable for any damages arising from the use of this software. |
31 | * |
32 | * Permission is granted to anyone to use this software for any purpose, including commercial |
33 | * applications, and to alter it and redistribute it freely, subject to the following restrictions: |
34 | * |
35 | * 1. The origin of this software must not be misrepresented; you must not claim that you |
36 | * wrote the original software. If you use this software in a product, an acknowledgment |
37 | * in the product documentation would be appreciated but is not required. |
38 | * |
39 | * 2. Altered source versions must be plainly marked as such, and must not be misrepresented |
40 | * as being the original software. |
41 | * |
42 | * 3. This notice may not be removed or altered from any source distribution. |
43 | * |
44 | ********************************************************************************************/ |
45 | |
46 | #define RLGL_IMPLEMENTATION |
47 | #define RLGL_STANDALONE |
48 | #define RLGL_SUPPORT_TRACELOG |
49 | #include "rlgl.h" // OpenGL 1.1 immediate-mode style coding |
50 | |
51 | #if defined(__EMSCRIPTEN__) |
52 | #define GLFW_INCLUDE_ES2 |
53 | #endif |
54 | |
55 | #include <GLFW/glfw3.h> // Windows/Context and inputs management |
56 | |
57 | #include <stdio.h> // Required for: printf() |
58 | |
59 | #define RED (Color){ 230, 41, 55, 255 } // Red |
60 | #define RAYWHITE (Color){ 245, 245, 245, 255 } // My own White (raylib logo) |
61 | #define DARKGRAY (Color){ 80, 80, 80, 255 } // Dark Gray |
62 | |
63 | //---------------------------------------------------------------------------------- |
64 | // Module specific Functions Declaration |
65 | //---------------------------------------------------------------------------------- |
66 | static void ErrorCallback(int error, const char *description); |
67 | static void KeyCallback(GLFWwindow *window, int key, int scancode, int action, int mods); |
68 | |
69 | // Drawing functions (uses rlgl functionality) |
70 | static void DrawGrid(int slices, float spacing); |
71 | static void DrawCube(Vector3 position, float width, float height, float length, Color color); |
72 | static void DrawCubeWires(Vector3 position, float width, float height, float length, Color color); |
73 | static void DrawRectangleV(Vector2 position, Vector2 size, Color color); |
74 | |
75 | //---------------------------------------------------------------------------------- |
76 | // Main Entry point |
77 | //---------------------------------------------------------------------------------- |
78 | int main(void) |
79 | { |
80 | // Initialization |
81 | //-------------------------------------------------------------------------------------- |
82 | const int screenWidth = 800; |
83 | const int screenHeight = 450; |
84 | |
85 | // GLFW3 Initialization + OpenGL 3.3 Context + Extensions |
86 | //-------------------------------------------------------- |
87 | glfwSetErrorCallback(ErrorCallback); |
88 | |
89 | if (!glfwInit()) |
90 | { |
91 | printf("GLFW3: Can not initialize GLFW\n" ); |
92 | return 1; |
93 | } |
94 | else printf("GLFW3: GLFW initialized successfully\n" ); |
95 | |
96 | glfwWindowHint(GLFW_SAMPLES, 4); |
97 | glfwWindowHint(GLFW_DEPTH_BITS, 16); |
98 | glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3); |
99 | glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3); |
100 | glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); |
101 | //glfwWindowHint(GLFW_OPENGL_DEBUG_CONTEXT, GL_TRUE); |
102 | |
103 | GLFWwindow *window = glfwCreateWindow(screenWidth, screenHeight, "rlgl standalone" , NULL, NULL); |
104 | |
105 | if (!window) |
106 | { |
107 | glfwTerminate(); |
108 | return 2; |
109 | } |
110 | else printf("GLFW3: Window created successfully\n" ); |
111 | |
112 | glfwSetWindowPos(window, 200, 200); |
113 | |
114 | glfwSetKeyCallback(window, KeyCallback); |
115 | |
116 | glfwMakeContextCurrent(window); |
117 | glfwSwapInterval(0); |
118 | |
119 | // Load OpenGL 3.3 supported extensions |
120 | rlLoadExtensions(glfwGetProcAddress); |
121 | //-------------------------------------------------------- |
122 | |
123 | // Initialize OpenGL context (states and resources) |
124 | rlglInit(screenWidth, screenHeight); |
125 | |
126 | // Initialize viewport and internal projection/modelview matrices |
127 | rlViewport(0, 0, screenWidth, screenHeight); |
128 | rlMatrixMode(RL_PROJECTION); // Switch to PROJECTION matrix |
129 | rlLoadIdentity(); // Reset current matrix (PROJECTION) |
130 | rlOrtho(0, screenWidth, screenHeight, 0, 0.0f, 1.0f); // Orthographic projection with top-left corner at (0,0) |
131 | rlMatrixMode(RL_MODELVIEW); // Switch back to MODELVIEW matrix |
132 | rlLoadIdentity(); // Reset current matrix (MODELVIEW) |
133 | |
134 | rlClearColor(245, 245, 245, 255); // Define clear color |
135 | rlEnableDepthTest(); // Enable DEPTH_TEST for 3D |
136 | |
137 | Camera camera = { 0 }; |
138 | camera.position = (Vector3){ 5.0f, 5.0f, 5.0f }; // Camera position |
139 | camera.target = (Vector3){ 0.0f, 0.0f, 0.0f }; // Camera looking at point |
140 | camera.up = (Vector3){ 0.0f, 1.0f, 0.0f }; // Camera up vector (rotation towards target) |
141 | camera.fovy = 45.0f; // Camera field-of-view Y |
142 | |
143 | Vector3 cubePosition = { 0.0f, 0.0f, 0.0f }; // Cube default position (center) |
144 | //-------------------------------------------------------------------------------------- |
145 | |
146 | // Main game loop |
147 | while (!glfwWindowShouldClose(window)) |
148 | { |
149 | // Update |
150 | //---------------------------------------------------------------------------------- |
151 | //camera.position.x += 0.01f; |
152 | //---------------------------------------------------------------------------------- |
153 | |
154 | // Draw |
155 | //---------------------------------------------------------------------------------- |
156 | rlClearScreenBuffers(); // Clear current framebuffer |
157 | |
158 | // Draw '3D' elements in the scene |
159 | //----------------------------------------------- |
160 | // Calculate projection matrix (from perspective) and view matrix from camera look at |
161 | Matrix matProj = MatrixPerspective(camera.fovy*DEG2RAD, (double)screenWidth/(double)screenHeight, 0.01, 1000.0); |
162 | Matrix matView = MatrixLookAt(camera.position, camera.target, camera.up); |
163 | |
164 | SetMatrixModelview(matView); // Set internal modelview matrix (default shader) |
165 | SetMatrixProjection(matProj); // Set internal projection matrix (default shader) |
166 | |
167 | DrawCube(cubePosition, 2.0f, 2.0f, 2.0f, RED); |
168 | DrawCubeWires(cubePosition, 2.0f, 2.0f, 2.0f, RAYWHITE); |
169 | DrawGrid(10, 1.0f); |
170 | |
171 | // NOTE: Internal buffers drawing (3D data) |
172 | rlglDraw(); |
173 | //----------------------------------------------- |
174 | |
175 | // Draw '2D' elements in the scene (GUI) |
176 | //----------------------------------------------- |
177 | #define RLGL_CREATE_MATRIX_MANUALLY |
178 | #if defined(RLGL_CREATE_MATRIX_MANUALLY) |
179 | matProj = MatrixOrtho(0.0, screenWidth, screenHeight, 0.0, 0.0, 1.0); |
180 | matView = MatrixIdentity(); |
181 | |
182 | SetMatrixModelview(matView); // Set internal modelview matrix (default shader) |
183 | SetMatrixProjection(matProj); // Set internal projection matrix (default shader) |
184 | |
185 | #else // Let rlgl generate and multiply matrix internally |
186 | |
187 | rlMatrixMode(RL_PROJECTION); // Enable internal projection matrix |
188 | rlLoadIdentity(); // Reset internal projection matrix |
189 | rlOrtho(0.0, screenWidth, screenHeight, 0.0, 0.0, 1.0); // Recalculate internal projection matrix |
190 | rlMatrixMode(RL_MODELVIEW); // Enable internal modelview matrix |
191 | rlLoadIdentity(); // Reset internal modelview matrix |
192 | #endif |
193 | DrawRectangleV((Vector2){ 10.0f, 10.0f }, (Vector2){ 780.0f, 20.0f }, DARKGRAY); |
194 | |
195 | // NOTE: Internal buffers drawing (2D data) |
196 | rlglDraw(); |
197 | //----------------------------------------------- |
198 | |
199 | glfwSwapBuffers(window); |
200 | glfwPollEvents(); |
201 | //---------------------------------------------------------------------------------- |
202 | } |
203 | |
204 | // De-Initialization |
205 | //-------------------------------------------------------------------------------------- |
206 | rlglClose(); // Unload rlgl internal buffers and default shader/texture |
207 | |
208 | glfwDestroyWindow(window); // Close window |
209 | glfwTerminate(); // Free GLFW3 resources |
210 | //-------------------------------------------------------------------------------------- |
211 | |
212 | return 0; |
213 | } |
214 | |
215 | //---------------------------------------------------------------------------------- |
216 | // Module specific Functions Definitions |
217 | //---------------------------------------------------------------------------------- |
218 | |
219 | // GLFW3: Error callback |
220 | static void ErrorCallback(int error, const char *description) |
221 | { |
222 | fprintf(stderr, description); |
223 | } |
224 | |
225 | // GLFW3: Keyboard callback |
226 | static void KeyCallback(GLFWwindow *window, int key, int scancode, int action, int mods) |
227 | { |
228 | if (key == GLFW_KEY_ESCAPE && action == GLFW_PRESS) |
229 | { |
230 | glfwSetWindowShouldClose(window, GL_TRUE); |
231 | } |
232 | } |
233 | |
234 | // Draw rectangle using rlgl OpenGL 1.1 style coding (translated to OpenGL 3.3 internally) |
235 | static void DrawRectangleV(Vector2 position, Vector2 size, Color color) |
236 | { |
237 | rlBegin(RL_TRIANGLES); |
238 | rlColor4ub(color.r, color.g, color.b, color.a); |
239 | |
240 | rlVertex2i(position.x, position.y); |
241 | rlVertex2i(position.x, position.y + size.y); |
242 | rlVertex2i(position.x + size.x, position.y + size.y); |
243 | |
244 | rlVertex2i(position.x, position.y); |
245 | rlVertex2i(position.x + size.x, position.y + size.y); |
246 | rlVertex2i(position.x + size.x, position.y); |
247 | rlEnd(); |
248 | } |
249 | |
250 | // Draw a grid centered at (0, 0, 0) |
251 | static void DrawGrid(int slices, float spacing) |
252 | { |
253 | int halfSlices = slices / 2; |
254 | |
255 | rlBegin(RL_LINES); |
256 | for(int i = -halfSlices; i <= halfSlices; i++) |
257 | { |
258 | if (i == 0) |
259 | { |
260 | rlColor3f(0.5f, 0.5f, 0.5f); |
261 | rlColor3f(0.5f, 0.5f, 0.5f); |
262 | rlColor3f(0.5f, 0.5f, 0.5f); |
263 | rlColor3f(0.5f, 0.5f, 0.5f); |
264 | } |
265 | else |
266 | { |
267 | rlColor3f(0.75f, 0.75f, 0.75f); |
268 | rlColor3f(0.75f, 0.75f, 0.75f); |
269 | rlColor3f(0.75f, 0.75f, 0.75f); |
270 | rlColor3f(0.75f, 0.75f, 0.75f); |
271 | } |
272 | |
273 | rlVertex3f((float)i*spacing, 0.0f, (float)-halfSlices*spacing); |
274 | rlVertex3f((float)i*spacing, 0.0f, (float)halfSlices*spacing); |
275 | |
276 | rlVertex3f((float)-halfSlices*spacing, 0.0f, (float)i*spacing); |
277 | rlVertex3f((float)halfSlices*spacing, 0.0f, (float)i*spacing); |
278 | } |
279 | rlEnd(); |
280 | } |
281 | |
282 | // Draw cube |
283 | // NOTE: Cube position is the center position |
284 | static void DrawCube(Vector3 position, float width, float height, float length, Color color) |
285 | { |
286 | float x = 0.0f; |
287 | float y = 0.0f; |
288 | float z = 0.0f; |
289 | |
290 | rlPushMatrix(); |
291 | |
292 | // NOTE: Be careful! Function order matters (rotate -> scale -> translate) |
293 | rlTranslatef(position.x, position.y, position.z); |
294 | //rlScalef(2.0f, 2.0f, 2.0f); |
295 | //rlRotatef(45, 0, 1, 0); |
296 | |
297 | rlBegin(RL_TRIANGLES); |
298 | rlColor4ub(color.r, color.g, color.b, color.a); |
299 | |
300 | // Front Face ----------------------------------------------------- |
301 | rlVertex3f(x-width/2, y-height/2, z+length/2); // Bottom Left |
302 | rlVertex3f(x+width/2, y-height/2, z+length/2); // Bottom Right |
303 | rlVertex3f(x-width/2, y+height/2, z+length/2); // Top Left |
304 | |
305 | rlVertex3f(x+width/2, y+height/2, z+length/2); // Top Right |
306 | rlVertex3f(x-width/2, y+height/2, z+length/2); // Top Left |
307 | rlVertex3f(x+width/2, y-height/2, z+length/2); // Bottom Right |
308 | |
309 | // Back Face ------------------------------------------------------ |
310 | rlVertex3f(x-width/2, y-height/2, z-length/2); // Bottom Left |
311 | rlVertex3f(x-width/2, y+height/2, z-length/2); // Top Left |
312 | rlVertex3f(x+width/2, y-height/2, z-length/2); // Bottom Right |
313 | |
314 | rlVertex3f(x+width/2, y+height/2, z-length/2); // Top Right |
315 | rlVertex3f(x+width/2, y-height/2, z-length/2); // Bottom Right |
316 | rlVertex3f(x-width/2, y+height/2, z-length/2); // Top Left |
317 | |
318 | // Top Face ------------------------------------------------------- |
319 | rlVertex3f(x-width/2, y+height/2, z-length/2); // Top Left |
320 | rlVertex3f(x-width/2, y+height/2, z+length/2); // Bottom Left |
321 | rlVertex3f(x+width/2, y+height/2, z+length/2); // Bottom Right |
322 | |
323 | rlVertex3f(x+width/2, y+height/2, z-length/2); // Top Right |
324 | rlVertex3f(x-width/2, y+height/2, z-length/2); // Top Left |
325 | rlVertex3f(x+width/2, y+height/2, z+length/2); // Bottom Right |
326 | |
327 | // Bottom Face ---------------------------------------------------- |
328 | rlVertex3f(x-width/2, y-height/2, z-length/2); // Top Left |
329 | rlVertex3f(x+width/2, y-height/2, z+length/2); // Bottom Right |
330 | rlVertex3f(x-width/2, y-height/2, z+length/2); // Bottom Left |
331 | |
332 | rlVertex3f(x+width/2, y-height/2, z-length/2); // Top Right |
333 | rlVertex3f(x+width/2, y-height/2, z+length/2); // Bottom Right |
334 | rlVertex3f(x-width/2, y-height/2, z-length/2); // Top Left |
335 | |
336 | // Right face ----------------------------------------------------- |
337 | rlVertex3f(x+width/2, y-height/2, z-length/2); // Bottom Right |
338 | rlVertex3f(x+width/2, y+height/2, z-length/2); // Top Right |
339 | rlVertex3f(x+width/2, y+height/2, z+length/2); // Top Left |
340 | |
341 | rlVertex3f(x+width/2, y-height/2, z+length/2); // Bottom Left |
342 | rlVertex3f(x+width/2, y-height/2, z-length/2); // Bottom Right |
343 | rlVertex3f(x+width/2, y+height/2, z+length/2); // Top Left |
344 | |
345 | // Left Face ------------------------------------------------------ |
346 | rlVertex3f(x-width/2, y-height/2, z-length/2); // Bottom Right |
347 | rlVertex3f(x-width/2, y+height/2, z+length/2); // Top Left |
348 | rlVertex3f(x-width/2, y+height/2, z-length/2); // Top Right |
349 | |
350 | rlVertex3f(x-width/2, y-height/2, z+length/2); // Bottom Left |
351 | rlVertex3f(x-width/2, y+height/2, z+length/2); // Top Left |
352 | rlVertex3f(x-width/2, y-height/2, z-length/2); // Bottom Right |
353 | rlEnd(); |
354 | rlPopMatrix(); |
355 | } |
356 | |
357 | // Draw cube wires |
358 | static void DrawCubeWires(Vector3 position, float width, float height, float length, Color color) |
359 | { |
360 | float x = 0.0f; |
361 | float y = 0.0f; |
362 | float z = 0.0f; |
363 | |
364 | rlPushMatrix(); |
365 | |
366 | rlTranslatef(position.x, position.y, position.z); |
367 | //rlRotatef(45, 0, 1, 0); |
368 | |
369 | rlBegin(RL_LINES); |
370 | rlColor4ub(color.r, color.g, color.b, color.a); |
371 | |
372 | // Front Face ----------------------------------------------------- |
373 | // Bottom Line |
374 | rlVertex3f(x-width/2, y-height/2, z+length/2); // Bottom Left |
375 | rlVertex3f(x+width/2, y-height/2, z+length/2); // Bottom Right |
376 | |
377 | // Left Line |
378 | rlVertex3f(x+width/2, y-height/2, z+length/2); // Bottom Right |
379 | rlVertex3f(x+width/2, y+height/2, z+length/2); // Top Right |
380 | |
381 | // Top Line |
382 | rlVertex3f(x+width/2, y+height/2, z+length/2); // Top Right |
383 | rlVertex3f(x-width/2, y+height/2, z+length/2); // Top Left |
384 | |
385 | // Right Line |
386 | rlVertex3f(x-width/2, y+height/2, z+length/2); // Top Left |
387 | rlVertex3f(x-width/2, y-height/2, z+length/2); // Bottom Left |
388 | |
389 | // Back Face ------------------------------------------------------ |
390 | // Bottom Line |
391 | rlVertex3f(x-width/2, y-height/2, z-length/2); // Bottom Left |
392 | rlVertex3f(x+width/2, y-height/2, z-length/2); // Bottom Right |
393 | |
394 | // Left Line |
395 | rlVertex3f(x+width/2, y-height/2, z-length/2); // Bottom Right |
396 | rlVertex3f(x+width/2, y+height/2, z-length/2); // Top Right |
397 | |
398 | // Top Line |
399 | rlVertex3f(x+width/2, y+height/2, z-length/2); // Top Right |
400 | rlVertex3f(x-width/2, y+height/2, z-length/2); // Top Left |
401 | |
402 | // Right Line |
403 | rlVertex3f(x-width/2, y+height/2, z-length/2); // Top Left |
404 | rlVertex3f(x-width/2, y-height/2, z-length/2); // Bottom Left |
405 | |
406 | // Top Face ------------------------------------------------------- |
407 | // Left Line |
408 | rlVertex3f(x-width/2, y+height/2, z+length/2); // Top Left Front |
409 | rlVertex3f(x-width/2, y+height/2, z-length/2); // Top Left Back |
410 | |
411 | // Right Line |
412 | rlVertex3f(x+width/2, y+height/2, z+length/2); // Top Right Front |
413 | rlVertex3f(x+width/2, y+height/2, z-length/2); // Top Right Back |
414 | |
415 | // Bottom Face --------------------------------------------------- |
416 | // Left Line |
417 | rlVertex3f(x-width/2, y-height/2, z+length/2); // Top Left Front |
418 | rlVertex3f(x-width/2, y-height/2, z-length/2); // Top Left Back |
419 | |
420 | // Right Line |
421 | rlVertex3f(x+width/2, y-height/2, z+length/2); // Top Right Front |
422 | rlVertex3f(x+width/2, y-height/2, z-length/2); // Top Right Back |
423 | rlEnd(); |
424 | rlPopMatrix(); |
425 | } |
426 | |