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//----------------------------------------------------------------------------------
66static void ErrorCallback(int error, const char *description);
67static void KeyCallback(GLFWwindow *window, int key, int scancode, int action, int mods);
68
69// Drawing functions (uses rlgl functionality)
70static void DrawGrid(int slices, float spacing);
71static void DrawCube(Vector3 position, float width, float height, float length, Color color);
72static void DrawCubeWires(Vector3 position, float width, float height, float length, Color color);
73static void DrawRectangleV(Vector2 position, Vector2 size, Color color);
74
75//----------------------------------------------------------------------------------
76// Main Entry point
77//----------------------------------------------------------------------------------
78int 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
220static void ErrorCallback(int error, const char *description)
221{
222 fprintf(stderr, description);
223}
224
225// GLFW3: Keyboard callback
226static 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)
235static 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)
251static 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
284static 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
358static 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