mirror of
				https://github.com/raysan5/raylib.git
				synced 2025-11-04 09:44:20 +00:00 
			
		
		
		
	REVIEWED: shaders_spotlight example
It seems something is not working properly...
This commit is contained in:
		@@ -1,27 +1,29 @@
 | 
			
		||||
#version 330
 | 
			
		||||
 | 
			
		||||
// Input vertex attributes (from vertex shader)
 | 
			
		||||
in vec2 fragTexCoord;
 | 
			
		||||
in vec4 fragColor;
 | 
			
		||||
 | 
			
		||||
// Output fragment color
 | 
			
		||||
out vec4 finalColor;
 | 
			
		||||
 | 
			
		||||
#define     MAX_SPOTS			4
 | 
			
		||||
#define		RADIUS				256
 | 
			
		||||
#define		INNER				200
 | 
			
		||||
// NOTE: Add here your custom variables
 | 
			
		||||
 | 
			
		||||
// Inputs
 | 
			
		||||
// array of spotlight positions
 | 
			
		||||
uniform vec2 spots[MAX_SPOTS];
 | 
			
		||||
#define     MAX_SPOTS			2
 | 
			
		||||
#define		RADIUS				128
 | 
			
		||||
#define		INNER				96
 | 
			
		||||
 | 
			
		||||
uniform float screenWidth; // width of the screen
 | 
			
		||||
uniform vec2 spots[MAX_SPOTS];      // Spotlight positions array
 | 
			
		||||
uniform float screenWidth;          // Width of the screen
 | 
			
		||||
 | 
			
		||||
void main()
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
	float alpha;
 | 
			
		||||
	// get the position of the current fragment (screen coordinates!)
 | 
			
		||||
	float alpha = 0.0;
 | 
			
		||||
    
 | 
			
		||||
	// Get the position of the current fragment (screen coordinates!)
 | 
			
		||||
	vec2 pos = vec2(gl_FragCoord.x, gl_FragCoord.y);
 | 
			
		||||
 | 
			
		||||
	
 | 
			
		||||
	// find out which spotlight is nearest
 | 
			
		||||
	// Find out which spotlight is nearest
 | 
			
		||||
	float d = 65000; // some high value
 | 
			
		||||
	float di = 0;
 | 
			
		||||
 | 
			
		||||
@@ -32,22 +34,16 @@ void main()
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    // d now equals distance to nearest spot...
 | 
			
		||||
    if (d > RADIUS) {
 | 
			
		||||
		alpha = 1.0;
 | 
			
		||||
	} else {
 | 
			
		||||
		if (d < INNER) {
 | 
			
		||||
			alpha = 0.0;
 | 
			
		||||
		} else {
 | 
			
		||||
			alpha = (d - INNER) / (RADIUS - INNER);
 | 
			
		||||
		}
 | 
			
		||||
    if (d > RADIUS) alpha = 1.0;
 | 
			
		||||
	else
 | 
			
		||||
    {
 | 
			
		||||
		if (d < INNER) alpha = 0.0;
 | 
			
		||||
		else alpha = (d - INNER)/(RADIUS - INNER);
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	// right hand side of screen is dimly lit, could make the
 | 
			
		||||
	// threshold value user definable.
 | 
			
		||||
	if (pos.x>screenWidth/2.0 && alpha >0.9) {
 | 
			
		||||
		alpha = 0.9;
 | 
			
		||||
	}
 | 
			
		||||
	// Right hand side of screen is dimly lit, 
 | 
			
		||||
    // could make the threshold value user definable
 | 
			
		||||
	if ((pos.x > screenWidth/2.0) && (alpha > 0.9)) alpha = 0.9;
 | 
			
		||||
 | 
			
		||||
	// could make the black out colour user definable...
 | 
			
		||||
    finalColor = vec4( 0, 0, 0, alpha);
 | 
			
		||||
    finalColor = vec4(0, 0, 0, alpha);
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -1,107 +1,91 @@
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright (c) 2019 Chris Camacho (codifies -  http://bedroomcoders.co.uk/)
 | 
			
		||||
 *
 | 
			
		||||
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 | 
			
		||||
 * of this software and associated documentation files (the "Software"), to deal
 | 
			
		||||
 * in the Software without restriction, including without limitation the rights
 | 
			
		||||
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 | 
			
		||||
 * copies of the Software, and to permit persons to whom the Software is
 | 
			
		||||
 * furnished to do so, subject to the following conditions:
 | 
			
		||||
 *
 | 
			
		||||
 * The above copyright notice and this permission notice shall be included in
 | 
			
		||||
 * all copies or substantial portions of the Software.
 | 
			
		||||
 *
 | 
			
		||||
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 | 
			
		||||
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 | 
			
		||||
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 | 
			
		||||
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 | 
			
		||||
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 | 
			
		||||
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 | 
			
		||||
 * SOFTWARE.
 | 
			
		||||
 *
 | 
			
		||||
 */
 | 
			
		||||
 
 | 
			
		||||
/* The shader makes alpha holes in the forground to give the apearance of a top
 | 
			
		||||
 * down look at a spotlight casting a pool of light...
 | 
			
		||||
 * 
 | 
			
		||||
 * The right hand side of the screen there is just enough light to see whats
 | 
			
		||||
 * going on without the spot light, great for a stealth type game where you
 | 
			
		||||
 * have to avoid the spotlights.
 | 
			
		||||
 * 
 | 
			
		||||
 * The left hand side of the screen is in pitch dark except for where the spotlights
 | 
			
		||||
 * are.
 | 
			
		||||
 * 
 | 
			
		||||
 * Although this example doesn't scale like the letterbox example, you could integrate
 | 
			
		||||
 * the two techniques, but by scaling the actual colour of the render texture rather
 | 
			
		||||
 * than using alpha as a mask.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#include <stddef.h>
 | 
			
		||||
#include <stdint.h>
 | 
			
		||||
/*******************************************************************************************
 | 
			
		||||
*
 | 
			
		||||
*   raylib [shaders] example - Simple shader mask
 | 
			
		||||
*
 | 
			
		||||
*   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 Chris Camacho (@codifies -  http://bedroomcoders.co.uk/) 
 | 
			
		||||
*   and reviewed by Ramon Santamaria (@raysan5)
 | 
			
		||||
*
 | 
			
		||||
*   Copyright (c) 2019 Chris Camacho (@codifies) and Ramon Santamaria (@raysan5)
 | 
			
		||||
*
 | 
			
		||||
********************************************************************************************
 | 
			
		||||
*
 | 
			
		||||
*   The shader makes alpha holes in the forground to give the apearance of a top
 | 
			
		||||
*   down look at a spotlight casting a pool of light...
 | 
			
		||||
* 
 | 
			
		||||
*   The right hand side of the screen there is just enough light to see whats
 | 
			
		||||
*   going on without the spot light, great for a stealth type game where you
 | 
			
		||||
*   have to avoid the spotlights.
 | 
			
		||||
* 
 | 
			
		||||
*   The left hand side of the screen is in pitch dark except for where the spotlights are.
 | 
			
		||||
* 
 | 
			
		||||
*   Although this example doesn't scale like the letterbox example, you could integrate
 | 
			
		||||
*   the two techniques, but by scaling the actual colour of the render texture rather
 | 
			
		||||
*   than using alpha as a mask.
 | 
			
		||||
*
 | 
			
		||||
********************************************************************************************/
 | 
			
		||||
 | 
			
		||||
#include "raylib.h"
 | 
			
		||||
#include "raymath.h"
 | 
			
		||||
 | 
			
		||||
#include <stddef.h>
 | 
			
		||||
#include <stdint.h>
 | 
			
		||||
 | 
			
		||||
#if defined(PLATFORM_DESKTOP)
 | 
			
		||||
    #define GLSL_VERSION            330
 | 
			
		||||
#else   // PLATFORM_RPI, PLATFORM_ANDROID, PLATFORM_WEB
 | 
			
		||||
    #define GLSL_VERSION            100
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
// single digit only!
 | 
			
		||||
#define MAXSPOT 4
 | 
			
		||||
#define MAXSPOT           2
 | 
			
		||||
#define numStars        400
 | 
			
		||||
 | 
			
		||||
#define numStars 400
 | 
			
		||||
 | 
			
		||||
#define screenWidth 1280
 | 
			
		||||
#define screenHeight 720
 | 
			
		||||
 | 
			
		||||
// the stars in the star field have a position and velocity
 | 
			
		||||
typedef struct star {
 | 
			
		||||
// Stars in the star field have a position and velocity
 | 
			
		||||
typedef struct Star {
 | 
			
		||||
    Vector2 pos;
 | 
			
		||||
    Vector2 vel;
 | 
			
		||||
} star;
 | 
			
		||||
} Star;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
void updateStar(star *s);
 | 
			
		||||
void resetStar(star *s);
 | 
			
		||||
void UpdateStar(Star *s);
 | 
			
		||||
void ResetStar(Star *s);
 | 
			
		||||
 | 
			
		||||
int main(void)
 | 
			
		||||
{
 | 
			
		||||
    // Initialization
 | 
			
		||||
    //--------------------------------------------------------------------------------------
 | 
			
		||||
    star stars[numStars];
 | 
			
		||||
    const int screenWidth = 800;
 | 
			
		||||
    const int screenHeight = 450;
 | 
			
		||||
 | 
			
		||||
    for (int n=0; n < numStars; n++) {
 | 
			
		||||
        resetStar(&stars[n]);
 | 
			
		||||
    InitWindow(screenWidth, screenHeight, "raylib - shader spotlight");
 | 
			
		||||
 | 
			
		||||
    Texture texRay = LoadTexture("resources/raysan.png");
 | 
			
		||||
    
 | 
			
		||||
    Star stars[numStars] = { 0 };
 | 
			
		||||
 | 
			
		||||
    for (int n = 0; n < numStars; n++) ResetStar(&stars[n]);
 | 
			
		||||
 | 
			
		||||
    // Progress all the stars on, so they don't all start in the centre
 | 
			
		||||
    for (int m = 0; m < screenWidth/2.0; m++) 
 | 
			
		||||
    {
 | 
			
		||||
        for (int n = 0; n < numStars; n++) UpdateStar(&stars[n]);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // progress all the stars on, so they don't all start in the centre
 | 
			
		||||
    for (int m=0; m < screenWidth / 2.0; m++) {
 | 
			
		||||
        for (int n=0; n<numStars; n++) {
 | 
			
		||||
            updateStar(&stars[n]);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    int frameCounter = 0;
 | 
			
		||||
 | 
			
		||||
    //SetConfigFlags(FLAG_FULLSCREEN_MODE);
 | 
			
		||||
    InitWindow(screenWidth, screenHeight, "raylib - test");
 | 
			
		||||
 | 
			
		||||
    Texture rayTex = LoadTexture("resources/raysan.png"); 
 | 
			
		||||
 | 
			
		||||
    // frame counter
 | 
			
		||||
    int frame = 0;
 | 
			
		||||
 | 
			
		||||
    unsigned int spotLoc[MAXSPOT]; // shader locations    
 | 
			
		||||
    unsigned int spotLoc[MAXSPOT];  // shader locations    
 | 
			
		||||
 
 | 
			
		||||
    Vector2 spotPos[MAXSPOT];  // position and velocity
 | 
			
		||||
    Vector2 spotPos[MAXSPOT];       // position and velocity
 | 
			
		||||
    Vector2 spotVel[MAXSPOT];
 | 
			
		||||
       
 | 
			
		||||
    // use default vert shader
 | 
			
		||||
    // Use default vert shader
 | 
			
		||||
    Shader spotShader = LoadShader(0, FormatText("resources/shaders/glsl%i/spotlight.fs", GLSL_VERSION));
 | 
			
		||||
    
 | 
			
		||||
	// get the locations of spots in the shader
 | 
			
		||||
	// Get the locations of spots in the shader
 | 
			
		||||
    char spotName[32] = "spots[x]\0";
 | 
			
		||||
    for (int i = 0; i<MAXSPOT; i++) {
 | 
			
		||||
    for (int i = 0; i < MAXSPOT; i++) 
 | 
			
		||||
    {
 | 
			
		||||
		spotName[6] = '0' + i;
 | 
			
		||||
		spotLoc[i] = GetShaderLocation(spotShader, spotName);
 | 
			
		||||
	}
 | 
			
		||||
@@ -110,47 +94,47 @@ int main(void)
 | 
			
		||||
	// a pitch black half and a dimly lit half.
 | 
			
		||||
	{
 | 
			
		||||
		unsigned int wLoc = GetShaderLocation(spotShader, "screenWidth");
 | 
			
		||||
		float sw = screenWidth;
 | 
			
		||||
		float sw = (float)GetScreenWidth();
 | 
			
		||||
		SetShaderValue(spotShader, wLoc, &sw, UNIFORM_FLOAT);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
    // randomise the locations and velocities of the spotlights
 | 
			
		||||
    for (int i=0; i<MAXSPOT; i++) {
 | 
			
		||||
		spotPos[i].x = GetRandomValue(128, screenWidth-128);
 | 
			
		||||
		spotPos[i].y = GetRandomValue(128, screenHeight-128);
 | 
			
		||||
		spotVel[i] = (Vector2){0, 0};
 | 
			
		||||
		while (fabs(spotVel[i].x)+fabs(spotVel[i].y)<2) {
 | 
			
		||||
			spotVel[i].x = GetRandomValue(-40,40)/10.0;
 | 
			
		||||
			spotVel[i].y = GetRandomValue(-40,40)/10.0;
 | 
			
		||||
    for (int i = 0; i < MAXSPOT; i++)
 | 
			
		||||
    {
 | 
			
		||||
		spotPos[i].x = GetRandomValue(64, screenWidth - 64);
 | 
			
		||||
		spotPos[i].y = GetRandomValue(64, screenHeight - 64);
 | 
			
		||||
		spotVel[i] = (Vector2){ 0, 0 };
 | 
			
		||||
        
 | 
			
		||||
		while ((fabs(spotVel[i].x) + fabs(spotVel[i].y)) < 2)
 | 
			
		||||
        {
 | 
			
		||||
			spotVel[i].x = GetRandomValue(-40, 40)/10.0;
 | 
			
		||||
			spotVel[i].y = GetRandomValue(-40, 40)/10.0;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
  
 | 
			
		||||
 | 
			
		||||
    SetTargetFPS(60);               // Set  to run at 60 frames-per-second
 | 
			
		||||
    //--------------------------------------------------------------------------------------
 | 
			
		||||
    
 | 
			
		||||
    // Main game loop
 | 
			
		||||
    while (!WindowShouldClose())    // Detect window close button or ESC key
 | 
			
		||||
    {
 | 
			
		||||
        // Update
 | 
			
		||||
        //----------------------------------------------------------------------------------
 | 
			
		||||
        frameCounter++;
 | 
			
		||||
 | 
			
		||||
        frame ++;
 | 
			
		||||
 | 
			
		||||
		// move the stars, resetting them if the go offscreen
 | 
			
		||||
        for (int n=0; n<numStars; n++) {
 | 
			
		||||
            updateStar(&stars[n]);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
		// update the spots, send them to the shader
 | 
			
		||||
		for (int i=0; i<MAXSPOT; i++) {
 | 
			
		||||
		// Move the stars, resetting them if the go offscreen
 | 
			
		||||
        for (int n = 0; n < numStars; n++) UpdateStar(&stars[n]);
 | 
			
		||||
 | 
			
		||||
		// Update the spots, send them to the shader
 | 
			
		||||
		for (int i = 0; i < MAXSPOT; i++)
 | 
			
		||||
        {
 | 
			
		||||
			spotPos[i].x += spotVel[i].x;					
 | 
			
		||||
			spotPos[i].y += spotVel[i].y;
 | 
			
		||||
			
 | 
			
		||||
			if (spotPos[i].x < 128) spotVel[i].x = -spotVel[i].x;					
 | 
			
		||||
			if (spotPos[i].x > screenWidth-128) spotVel[i].x = -spotVel[i].x;					
 | 
			
		||||
			if (spotPos[i].y < 128) spotVel[i].y = -spotVel[i].y;					
 | 
			
		||||
			if (spotPos[i].y > screenHeight-128) spotVel[i].y = -spotVel[i].y;
 | 
			
		||||
			if (spotPos[i].x < 64) spotVel[i].x = -spotVel[i].x;					
 | 
			
		||||
			if (spotPos[i].x > screenWidth - 64) spotVel[i].x = -spotVel[i].x;					
 | 
			
		||||
			if (spotPos[i].y < 64) spotVel[i].y = -spotVel[i].y;					
 | 
			
		||||
			if (spotPos[i].y > screenHeight - 64) spotVel[i].y = -spotVel[i].y;
 | 
			
		||||
			
 | 
			
		||||
			SetShaderValue(spotShader, spotLoc[i], &spotPos[i].x, UNIFORM_VEC2);				
 | 
			
		||||
		}
 | 
			
		||||
@@ -159,22 +143,24 @@ int main(void)
 | 
			
		||||
        //----------------------------------------------------------------------------------
 | 
			
		||||
        BeginDrawing();
 | 
			
		||||
 | 
			
		||||
            ClearBackground((Color){0,32,128,255});
 | 
			
		||||
            ClearBackground(DARKBLUE);
 | 
			
		||||
 | 
			
		||||
			// stars and bobs
 | 
			
		||||
            for (int n=0; n<numStars; n++) {
 | 
			
		||||
				// single pixel is just too small these days!
 | 
			
		||||
			// Draw stars and bobs
 | 
			
		||||
            for (int n = 0; n < numStars; n++)
 | 
			
		||||
            {
 | 
			
		||||
				// Single pixel is just too small these days!
 | 
			
		||||
                DrawRectangle(stars[n].pos.x, stars[n].pos.y, 2, 2, WHITE);
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            for (int i=0; i<16; i++) {
 | 
			
		||||
                DrawTexture(rayTex,
 | 
			
		||||
                    (screenWidth/2.0)+cos((frame+i*8)/51.45)*(screenWidth/2.2)-32,
 | 
			
		||||
                    (screenHeight/2.0)+sin((frame+i*8)/17.87)*(screenHeight/4.2),
 | 
			
		||||
            for (int i = 0; i < 16; i++)
 | 
			
		||||
            {
 | 
			
		||||
                DrawTexture(texRay,
 | 
			
		||||
                    (screenWidth/2.0) + cos((frameCounter + i*8)/51.45f)*(screenWidth/2.2) - 32,
 | 
			
		||||
                    (screenHeight/2.0) + sin((frameCounter + i*8)/17.87f)*(screenHeight/4.2),
 | 
			
		||||
                    WHITE);
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
			// spot lights
 | 
			
		||||
			// Draw spot lights
 | 
			
		||||
			BeginShaderMode(spotShader);
 | 
			
		||||
				// instead of a blank rectangle you could render here
 | 
			
		||||
				// a render texture of the full screen used to do screen
 | 
			
		||||
@@ -185,15 +171,13 @@ int main(void)
 | 
			
		||||
 | 
			
		||||
            DrawFPS(10, 10);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
        EndDrawing();
 | 
			
		||||
        //----------------------------------------------------------------------------------
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // De-Initialization
 | 
			
		||||
    //--------------------------------------------------------------------------------------
 | 
			
		||||
 | 
			
		||||
    UnloadTexture(rayTex);
 | 
			
		||||
    UnloadTexture(texRay);
 | 
			
		||||
 | 
			
		||||
    CloseWindow();        // Close window and OpenGL context
 | 
			
		||||
    //--------------------------------------------------------------------------------------
 | 
			
		||||
@@ -202,23 +186,28 @@ int main(void)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
void resetStar(star *s)
 | 
			
		||||
void ResetStar(Star *s)
 | 
			
		||||
{
 | 
			
		||||
    (*s).pos = (Vector2){screenWidth/2.0, screenHeight/2.0 };
 | 
			
		||||
    do {
 | 
			
		||||
        (*s).vel.x = (float)GetRandomValue(-1000,1000) / 100.0;
 | 
			
		||||
        (*s).vel.y = (float)GetRandomValue(-1000,1000) / 100.0;
 | 
			
		||||
    } while (!(fabs((*s).vel.x)+fabs((*s).vel.y)>1));
 | 
			
		||||
    (*s).pos = Vector2Add( (*s).pos,
 | 
			
		||||
                    Vector2MultiplyV((*s).vel,(Vector2){8,8} ));
 | 
			
		||||
    s->pos = (Vector2){ GetScreenWidth()/2.0f, GetScreenHeight()/2.0f };
 | 
			
		||||
    
 | 
			
		||||
    do
 | 
			
		||||
    {
 | 
			
		||||
        s->vel.x = (float)GetRandomValue(-1000, 1000)/100.0f;
 | 
			
		||||
        s->vel.y = (float)GetRandomValue(-1000, 1000)/100.0f;
 | 
			
		||||
        
 | 
			
		||||
    } while (!(fabs(s->vel.x) + fabs(s->vel.y) > 1));
 | 
			
		||||
    
 | 
			
		||||
    s->pos = Vector2Add(s->pos, Vector2MultiplyV(s->vel, (Vector2){ 8, 8 }));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void updateStar(star *s)
 | 
			
		||||
void UpdateStar(Star *s)
 | 
			
		||||
{
 | 
			
		||||
    (*s).pos = Vector2Add((*s).pos, (*s).vel);
 | 
			
		||||
    if ((*s).pos.x < 0 || (*s).pos.x > screenWidth ||
 | 
			
		||||
        (*s).pos.y < 0 || (*s).pos.y > screenHeight) {
 | 
			
		||||
            resetStar(s);
 | 
			
		||||
    s->pos = Vector2Add(s->pos, s->vel);
 | 
			
		||||
    
 | 
			
		||||
    if (s->pos.x < 0 || s->pos.x > GetScreenWidth() ||
 | 
			
		||||
        s->pos.y < 0 || s->pos.y > GetScreenHeight())
 | 
			
		||||
    {
 | 
			
		||||
        ResetStar(s);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user