Raylib4 direct c with pb

Everything related to 3D programming
User avatar
idle
Always Here
Always Here
Posts: 5042
Joined: Fri Sep 21, 2007 5:52 am
Location: New Zealand

Raylib4 direct c with pb

Post by idle »

Tested using Raylib4 directly in PB with c backend, import what you need or not.

Code: Select all

; /*******************************************************************************************
; *
; *   raylib [shaders] example - julia sets
; *
; *   NOTE: This example requires raylib OpenGL 3.3 Or ES2 versions For shaders support,
; *         OpenGL 1.1 does Not support shaders, recompile raylib To OpenGL 3.3 version.
; *
; *   NOTE: Shaders used in this example are #version 330 (OpenGL 3.3).
; *
; *   This example has been created using raylib 2.5 (www.raylib.com)
; *   raylib is licensed under an unmodIfied zlib/libpng license (View raylib.h For details)
; *
; *   Example contributed by eggmund (@eggmund) And reviewed by Ramon Santamaria (@raysan5)
; *
; *   Copyright (c) 2019 eggmund (@eggmund) And Ramon Santamaria (@raysan5)
; *
; ********************************************************************************************/

ImportC "E:\raylib-4.0.0_win64_msvc16\raylibdll.lib"
  IsMouseButtonDown(button) 
  IsKeyPressed(key) 
EndImport 

!//gccflags -IC:\llvm-mingw-20211002-msvcrt-x86_64\lib\clang\13.0.0\include;
!//#include "E:\raylib-4.0.0_win64_msvc16\include\raylib.h"; 

!#if defined(PLATFORM_DESKTOP)
!    #define GLSL_VERSION            330
!#else   // PLATFORM_RPI, PLATFORM_ANDROID, PLATFORM_WEB
!   #define GLSL_VERSION            100
!#endif

Global pause,showControls,*shaderpath 

#Key_F1 = 290 
#KEY_RIGHT = 262
#KEY_LEFT   = 263
#MOUSE_BUTTON_LEFT    = 0;       // Mouse button left
#MOUSE_BUTTON_RIGHT   = 1;       // Mouse button right
#MOUSE_BUTTON_MIDDLE  = 2;       // Mouse button middle (pressed wheel)
#MOUSE_BUTTON_SIDE    = 3;       // Mouse button side (advanced mouse device)
#MOUSE_BUTTON_EXTRA   = 4;       // Mouse button extra (advanced mouse device)
#MOUSE_BUTTON_FORWARD = 5;       // Mouse button fordward (advanced mouse device)
#MOUSE_BUTTON_BACK    = 6;       // Mouse button back (advanced mouse device)

;// A few good julia sets
!const float pointsOfInterest[6][2] = {{ -0.348827f, 0.607167f },{ -0.786268f, 0.169728f },{ -0.8f, 0.156f },{ 0.285f, 0.0f },{ -0.835f, -0.2321f },{ -0.70176f, -0.3842f }};

;// Initialization
;//--------------------------------------------------------------------------------------
!const int screenWidth = 800;
!const int screenHeight = 450;

!SetConfigFlags(FLAG_WINDOW_HIGHDPI);
!InitWindow(screenWidth, screenHeight, "raylib [shaders] example - julia sets");

;// Load julia set shader
;// NOTE: Defining 0 (NULL) For vertex shader forces usage of internal Default vertex shader

*shaderpath = UTF8("E:\raylib-4.0.0_win64_msvc16\examples\shaders\resources\shaders\glsl100\julia_set.fs")
!Shader shader = LoadShader(0, TextFormat(p_shaderpath, GLSL_VERSION));
FreeMemory(*shaderpath) 

;// Create a RenderTexture2D To be used For render To texture
!RenderTexture2D target = LoadRenderTexture(GetScreenWidth(), GetScreenHeight());
    
;// c constant To use in z^2 + c
!float c[2] = { pointsOfInterest[0][0], pointsOfInterest[0][1] };
    
;// Offset And zoom To draw the julia set at. (centered on screen And Default size)
!float offset[2] = { -(float)GetScreenWidth()/2, -(float)GetScreenHeight()/2 };
!float zoom = 1.0f                                                            ;
    
!Vector2 offsetSpeed = { 0.0f, 0.0f };
    
;// Get variable (unIform) locations on the shader To connect With the program
;// NOTE: If unIform variable could Not be found in the shader, function returns -1
!int cLoc = GetShaderLocation(shader, "c");
!int zoomLoc = GetShaderLocation(shader, "zoom");
!int offsetLoc = GetShaderLocation(shader, "offset");
        
;// Tell the shader what the screen dimensions, zoom, offset And c are
!float screenDims[2] = { (float)GetScreenWidth(), (float)GetScreenHeight() };
!SetShaderValue(shader, GetShaderLocation(shader, "screenDims"), screenDims, SHADER_UNIFORM_VEC2);
        
!SetShaderValue(shader, cLoc, c, SHADER_UNIFORM_VEC2);
!SetShaderValue(shader, zoomLoc, &zoom, SHADER_UNIFORM_FLOAT);
!SetShaderValue(shader, offsetLoc, offset, SHADER_UNIFORM_VEC2);
        
!int incrementSpeed = 0;     // Multiplier of speed to change c value
ShowControls = -1;           // Show controls
pause = 0      ;             // Pause animation
        
!SetTargetFPS(60);           // Set our game to run at 60 frames-per-second
;//--------------------------------------------------------------------------------------

Repeat 
  ;Press [1 - 6] To reset c To a point of interest
  If Not IsKeyPressed(0) 
    If IsKeyPressed(Asc("1"))
      !c[0] = pointsOfInterest[0][0];
      !c[1] = pointsOfInterest[0][1];
    ElseIf IsKeyPressed(Asc("2"))
      !c[0] = pointsOfInterest[1][0];
      !c[1] = pointsOfInterest[1][1];
    ElseIf IsKeyPressed(Asc("3"))
      !c[0] = pointsOfInterest[2][0];
      !c[1] = pointsOfInterest[2][1];
    ElseIf IsKeyPressed(Asc("4"))
      !c[0] = pointsOfInterest[3][0];
      !c[1] = pointsOfInterest[3][1];
    ElseIf IsKeyPressed(Asc("5"))
      !c[0] = pointsOfInterest[4][0];
      !c[1] = pointsOfInterest[4][1];
    ElseIf IsKeyPressed(Asc("6"))
      !c[0] = pointsOfInterest[5][0];
      !c[1] = pointsOfInterest[5][1];
    EndIf      
    !SetShaderValue(shader, cLoc, c, SHADER_UNIFORM_VEC2);
  EndIf 
  
  If IsKeyPressed(Asc(" ")) 
    pause = ~pause;
  EndIf          
  If IsKeyPressed(#KEY_F1) 
    showControls = ~showControls 
  EndIf                       
  If Not pause
    If IsKeyPressed(#KEY_RIGHT) 
      !incrementSpeed++;
    ElseIf IsKeyPressed(#KEY_LEFT)
      !incrementSpeed--;
    EndIf   
    If (IsMouseButtonDown(#MOUSE_BUTTON_LEFT) Or IsMouseButtonDown(#MOUSE_BUTTON_RIGHT))
      If IsMouseButtonDown(#MOUSE_BUTTON_LEFT) 
        !zoom += zoom*0.003f;
      EndIf   
      If IsMouseButtonDown(#MOUSE_BUTTON_RIGHT)
        !zoom -= zoom*0.003f;
      EndIf                               
      !Vector2 mousePos = GetMousePosition();
      
      !offsetSpeed.x = mousePos.x -(float)screenWidth/2;
      !offsetSpeed.y = mousePos.y -(float)screenHeight/2;
      
      !offset[0] += GetFrameTime()*offsetSpeed.x*0.8f;
      !offset[1] += GetFrameTime()*offsetSpeed.y*0.8f;
    Else 
      !offsetSpeed = (Vector2) { 0.0f, 0.0f };
    EndIf                                
    
    !SetShaderValue(shader, zoomLoc, &zoom, SHADER_UNIFORM_FLOAT);
    !SetShaderValue(shader, offsetLoc, offset, SHADER_UNIFORM_VEC2);
    
    ;// Increment c value With time
    !float amount = GetFrameTime()*incrementSpeed*0.0005f;
    !c[0] += amount                                      ;
    !c[1] += amount                                      ;
    
    !SetShaderValue(shader, cLoc, c, SHADER_UNIFORM_VEC2);
  EndIf 
  ;//----------------------------------------------------------------------------------
  ;// Draw
  ;//----------------------------------------------------------------------------------
  ;// Using a render texture To draw Julia set
  !BeginTextureMode(target);       // Enable drawing to texture
  !ClearBackground(BLACK)  ;     // Clear the render texture
  
  ;// Draw a rectangle in shader mode To be used As shader canvas
  ;// NOTE: Rectangle uses font white character texture coordinates,
  ;// so shader can Not be applied here directly because input vertexTexCoord
  ;// do Not represent full screen coordinates (space where want To apply shader)
  !DrawRectangle(0, 0, GetScreenWidth(), GetScreenHeight(), BLACK);
  !EndTextureMode()                                               ;
  
  !BeginDrawing();
  !ClearBackground(BLACK);     // Clear screen background
  
  ;// Draw the saved texture And rendered julia set With shader
  ;// NOTE: We do Not invert texture on Y, already considered inside shader
  !BeginShaderMode(shader);
  ;// WARNING: If FLAG_WINDOW_HIGHDPI is enabled, HighDPI monitor scaling should be considered
  ;// when rendering the RenderTexture2D To fit in the HighDPI scaled Window
  !DrawTextureEx(target.texture, (Vector2){ 0.0f, 0.0f }, 0.0f, 1.0f, WHITE);
  !EndShaderMode()                                                          ;
  
  If showControls
    !DrawText("Press Mouse buttons right/left to zoom in/out and move", 10, 15, 10, RAYWHITE);
    !DrawText("Press KEY_F1 to toggle these controls", 10, 30, 10, RAYWHITE)                 ;
    !DrawText("Press KEYS [1 - 6] to change point of interest", 10, 45, 10, RAYWHITE)        ;
    !DrawText("Press KEY_LEFT | KEY_RIGHT to change speed", 10, 60, 10, RAYWHITE)            ;
    !DrawText("Press KEY_SPACE to pause movement animation", 10, 75, 10, RAYWHITE)           ;
  EndIf 
  !EndDrawing();
  !v_close = WindowShouldClose();  
Until close 

;                                     // De-Initialization
;                                     //--------------------------------------------------------------------------------------
!UnloadShader(shader);               // Unload shader
!UnloadRenderTexture(target);        // Unload render texture

!CloseWindow();                      // Close window and OpenGL context
;                                    //--------------------------------------------------------------------------------------
                                        
                                                            

needs the compiler flag tool.
https://www.purebasic.fr/english/viewtopic.php?t=78558

For x64 windows
https://www.dropbox.com/s/v3dh0v5e11jkc ... 6.zip?dl=0

Image
Ziltch
User
User
Posts: 52
Joined: Sun Aug 03, 2003 12:05 am
Location: Australia

Re: Raylib4 direct c with pb

Post by Ziltch »

That is great!
Rinzwind
Enthusiast
Enthusiast
Posts: 636
Joined: Wed Mar 11, 2009 4:06 pm
Location: NL

Re: Raylib4 direct c with pb

Post by Rinzwind »

Just use C 8)

(Of course still thanks for any mix examples cause it could come helpful one time)
User avatar
idle
Always Here
Always Here
Posts: 5042
Joined: Fri Sep 21, 2007 5:52 am
Location: New Zealand

Re: Raylib4 direct c with pb

Post by idle »

Ziltch wrote: Tue Mar 29, 2022 12:58 amThat is great!
👍 thanks, I think the c backend is awesome but it will only get better if we try.

Someone had asked for raylib4 in the raylib3 module thread and it was a good example for mixed use as raylib passes a few structures by value normally you would write wrapper functions and customize the c build or make strange looking imports and wrap them in a macro.

It took me all of an hour to download build and try it in pb and once you know the limitations it's easy to work with.

At some time in the future you will just be able to include a c lib and use it directly in PB, no imports or defines required but that's a wee way down the track. I have researched the tools and partially done it, but it's like pulling hen teeth and I'm easily distracted, so it will be a project for winter.
User avatar
Caronte3D
Addict
Addict
Posts: 1027
Joined: Fri Jan 22, 2016 5:33 pm
Location: Some Universe

Re: Raylib4 direct c with pb

Post by Caronte3D »

idle wrote: Tue Mar 29, 2022 3:28 am At some time in the future you will just be able to include a c lib and use it directly in PB, no imports or defines required...
Thanks for your research that sounds awesome :wink:
User avatar
idle
Always Here
Always Here
Posts: 5042
Joined: Fri Sep 21, 2007 5:52 am
Location: New Zealand

Re: Raylib4 direct c with pb

Post by idle »

I've had lots of fun exploring the possibilities of the c backend and with clang it's easy to dump the AST and port the headers automatically.

I'm not sure how to get around passing structures by value but everything else is doable.
Post Reply