From 93d3212914393f89c545848c7489441d5274b4da Mon Sep 17 00:00:00 2001 From: Stephan Soller Date: Mon, 19 Apr 2021 20:28:14 +0200 Subject: [PATCH] [examples] Added an example for raylib OpenGL interop (#1726) * Added an example for raylib OpenGL interop. * Removed C99 variable-length array to fix MSVC errors * Moved the opengl interop example from shaders to others. --- examples/others/opengl_interop.c | 132 ++++++++++++++++++ examples/others/opengl_interop.png | Bin 0 -> 268859 bytes .../shaders/glsl100/point_particle.fs | 16 +++ .../shaders/glsl100/point_particle.vs | 24 ++++ .../shaders/glsl330/point_particle.fs | 17 +++ .../shaders/glsl330/point_particle.vs | 24 ++++ 6 files changed, 213 insertions(+) create mode 100644 examples/others/opengl_interop.c create mode 100644 examples/others/opengl_interop.png create mode 100644 examples/others/resources/shaders/glsl100/point_particle.fs create mode 100644 examples/others/resources/shaders/glsl100/point_particle.vs create mode 100644 examples/others/resources/shaders/glsl330/point_particle.fs create mode 100644 examples/others/resources/shaders/glsl330/point_particle.vs diff --git a/examples/others/opengl_interop.c b/examples/others/opengl_interop.c new file mode 100644 index 00000000..50003de0 --- /dev/null +++ b/examples/others/opengl_interop.c @@ -0,0 +1,132 @@ +/******************************************************************************************* +* +* raylib [shaders] example - OpenGL point particle system +* +* This example has been created using raylib 2ad3eb1 (www.raylib.com) +* raylib is licensed under an unmodified zlib/libpng license (View raylib.h for details) +* +* Example contributed by Stephan Soller (@arkanis - http://arkanis.de/) +* and reviewed by Ramon Santamaria (@raysan5) +* +* Copyright (c) 2021 Stephan Soller (@arkanis) and Ramon Santamaria (@raysan5) +* +******************************************************************************************** +* +* Mixes raylib and plain OpenGL code to draw a GL_POINTS based particle system. The +* primary point is to demonstrate raylib and OpenGL interop. +* +* rlgl batched draw operations internally so we have to flush the current batch before +* doing our own OpenGL work (rlDrawRenderBatchActive()). +* +* The example also demonstrates how to get the current model view projection matrix of +* raylib. That way raylib cameras and so on work as expected. +* +********************************************************************************************/ + +#include "raylib.h" +#include "rlgl.h" +#include "glad.h" + +#if defined(PLATFORM_DESKTOP) + #define GLSL_VERSION 330 +#else // PLATFORM_RPI, PLATFORM_ANDROID, PLATFORM_WEB + #define GLSL_VERSION 100 +#endif + +int main() +{ + // Initialization + //-------------------------------------------------------------------------------------- + const int screenWidth = 800; + const int screenHeight = 450; + + InitWindow(screenWidth, screenHeight, "raylib - point particles"); + + Shader shader = LoadShader( + TextFormat("resources/shaders/glsl%i/point_particle.vs", GLSL_VERSION), + TextFormat("resources/shaders/glsl%i/point_particle.fs", GLSL_VERSION)); + int currentTimeLoc = GetShaderLocation(shader, "currentTime"); + int colorLoc = GetShaderLocation(shader, "color"); + + // Initialize the vertex buffer for the particles and assign each particle random values + struct { float x, y, period; } particles[10000]; + const size_t particleCount = sizeof(particles) / sizeof(particles[0]); + for (size_t i = 0; i < particleCount; i++) + { + particles[i].x = GetRandomValue(20, screenWidth - 20); + particles[i].y = GetRandomValue(50, screenHeight - 20); + // Give each particle a slightly different period. But don't spread it to much. This way the particles line up + // every so often and you get a glimps of what is going on. + particles[i].period = GetRandomValue(10, 30) / 10.0f; + } + + // Create a plain OpenGL vertex buffer with the data and an vertex array object that feeds the data from the buffer + // into the vertexPosition shader attribute. + GLuint vao = 0, vbo = 0; + glGenVertexArrays(1, &vao); + glBindVertexArray(vao); + glGenBuffers(1, &vbo); + glBindBuffer(GL_ARRAY_BUFFER, vbo); + glBufferData(GL_ARRAY_BUFFER, sizeof(particles), particles, GL_STATIC_DRAW); + // Note: LoadShader() automatically fetches the attribute index of "vertexPosition" and saves it in shader.locs[SHADER_LOC_VERTEX_POSITION] + glVertexAttribPointer(shader.locs[SHADER_LOC_VERTEX_POSITION], 3, GL_FLOAT, GL_FALSE, 0, 0); + glEnableVertexAttribArray(0); + glBindBuffer(GL_ARRAY_BUFFER, 0); + glBindVertexArray(0); + + // Allows the vertex shader to set the point size of each particle individually + glEnable(GL_PROGRAM_POINT_SIZE); + + SetTargetFPS(60); + //-------------------------------------------------------------------------------------- + + // Main game loop + while (!WindowShouldClose()) // Detect window close button or ESC key + { + // Draw + //---------------------------------------------------------------------------------- + BeginDrawing(); + ClearBackground(WHITE); + + DrawRectangle(10, 10, 210, 30, MAROON); + DrawText(TextFormat("%zu particles in one vertex buffer", particleCount), 20, 20, 10, RAYWHITE); + + // Switch to plain OpenGL + //------------------------------------------------------------------------------ + // rlglDraw() in raylib 3.5 + rlDrawRenderBatchActive(); + glUseProgram(shader.id); + glUniform1f(currentTimeLoc, GetTime()); + + Vector4 color = ColorNormalize((Color){ 255, 0, 0, 128 }); + glUniform4fv(colorLoc, 1, (float*)&color); + + // The the current model view projection matrix so the particle system is displayed and transformed + // (e.g. by cameras) just like everything else. + // GetMatrixModelview() and GetMatrixProjection() in raylib 3.5 + Matrix modelViewProjection = MatrixMultiply(rlGetMatrixModelview(), rlGetMatrixProjection()); + glUniformMatrix4fv(shader.locs[SHADER_LOC_MATRIX_MVP], 1, false, MatrixToFloat(modelViewProjection)); + + glBindVertexArray(vao); + glDrawArrays(GL_POINTS, 0, particleCount); + glBindVertexArray(0); + glUseProgram(0); + + // And back to raylib again + //------------------------------------------------------------------------------ + DrawFPS(screenWidth - 100, 10); + EndDrawing(); + //---------------------------------------------------------------------------------- + } + + // De-Initialization + //-------------------------------------------------------------------------------------- + glDeleteBuffers(1, &vbo); + glDeleteVertexArrays(1, &vao); + + UnloadShader(shader); + CloseWindow(); // Close window and OpenGL context + //-------------------------------------------------------------------------------------- + + return 0; +} \ No newline at end of file diff --git a/examples/others/opengl_interop.png b/examples/others/opengl_interop.png new file mode 100644 index 0000000000000000000000000000000000000000..74d7acaeab3a3896715945a6408aa682eb83cef9 GIT binary patch literal 268859 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

A}gha`) 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