rlgl_standalone.c 21 KB

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