REVIEWED: shaders_spotlight example
It seems something is not working properly...
This commit is contained in:
parent
05abaee0e0
commit
5e670be239
2 changed files with 134 additions and 149 deletions
|
@ -1,27 +1,29 @@
|
||||||
#version 330
|
#version 330
|
||||||
|
|
||||||
|
// Input vertex attributes (from vertex shader)
|
||||||
|
in vec2 fragTexCoord;
|
||||||
|
in vec4 fragColor;
|
||||||
|
|
||||||
// Output fragment color
|
// Output fragment color
|
||||||
out vec4 finalColor;
|
out vec4 finalColor;
|
||||||
|
|
||||||
#define MAX_SPOTS 4
|
// NOTE: Add here your custom variables
|
||||||
#define RADIUS 256
|
|
||||||
#define INNER 200
|
|
||||||
|
|
||||||
// Inputs
|
#define MAX_SPOTS 2
|
||||||
// array of spotlight positions
|
#define RADIUS 128
|
||||||
uniform vec2 spots[MAX_SPOTS];
|
#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()
|
void main()
|
||||||
{
|
{
|
||||||
|
float alpha = 0.0;
|
||||||
|
|
||||||
float alpha;
|
// Get the position of the current fragment (screen coordinates!)
|
||||||
// get the position of the current fragment (screen coordinates!)
|
|
||||||
vec2 pos = vec2(gl_FragCoord.x, gl_FragCoord.y);
|
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 d = 65000; // some high value
|
||||||
float di = 0;
|
float di = 0;
|
||||||
|
|
||||||
|
@ -32,22 +34,16 @@ void main()
|
||||||
}
|
}
|
||||||
|
|
||||||
// d now equals distance to nearest spot...
|
// d now equals distance to nearest spot...
|
||||||
if (d > RADIUS) {
|
if (d > RADIUS) alpha = 1.0;
|
||||||
alpha = 1.0;
|
else
|
||||||
} else {
|
{
|
||||||
if (d < INNER) {
|
if (d < INNER) alpha = 0.0;
|
||||||
alpha = 0.0;
|
else alpha = (d - INNER)/(RADIUS - INNER);
|
||||||
} else {
|
|
||||||
alpha = (d - INNER) / (RADIUS - INNER);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// right hand side of screen is dimly lit, could make the
|
// Right hand side of screen is dimly lit,
|
||||||
// threshold value user definable.
|
// could make the threshold value user definable
|
||||||
if (pos.x>screenWidth/2.0 && alpha >0.9) {
|
if ((pos.x > screenWidth/2.0) && (alpha > 0.9)) 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
|
* raylib [shaders] example - Simple shader mask
|
||||||
* 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
|
* This example has been created using raylib 2.5 (www.raylib.com)
|
||||||
* all copies or substantial portions of the Software.
|
* raylib is licensed under an unmodified zlib/libpng license (View raylib.h for details)
|
||||||
*
|
*
|
||||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
* Example contributed by Chris Camacho (@codifies - http://bedroomcoders.co.uk/)
|
||||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
* and reviewed by Ramon Santamaria (@raysan5)
|
||||||
* 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.
|
|
||||||
*
|
*
|
||||||
*/
|
* 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
|
********************************************************************************************
|
||||||
|
*
|
||||||
|
* 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...
|
* 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
|
* 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
|
* going on without the spot light, great for a stealth type game where you
|
||||||
* have to avoid the spotlights.
|
* have to avoid the spotlights.
|
||||||
*
|
*
|
||||||
* The left hand side of the screen is in pitch dark except for where the spotlights
|
* The left hand side of the screen is in pitch dark except for where the spotlights are.
|
||||||
* are.
|
|
||||||
*
|
*
|
||||||
* Although this example doesn't scale like the letterbox example, you could integrate
|
* 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
|
* the two techniques, but by scaling the actual colour of the render texture rather
|
||||||
* than using alpha as a mask.
|
* than using alpha as a mask.
|
||||||
*/
|
*
|
||||||
|
********************************************************************************************/
|
||||||
#include <stddef.h>
|
|
||||||
#include <stdint.h>
|
|
||||||
|
|
||||||
#include "raylib.h"
|
#include "raylib.h"
|
||||||
#include "raymath.h"
|
#include "raymath.h"
|
||||||
|
|
||||||
|
#include <stddef.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
#if defined(PLATFORM_DESKTOP)
|
#if defined(PLATFORM_DESKTOP)
|
||||||
#define GLSL_VERSION 330
|
#define GLSL_VERSION 330
|
||||||
#else // PLATFORM_RPI, PLATFORM_ANDROID, PLATFORM_WEB
|
#else // PLATFORM_RPI, PLATFORM_ANDROID, PLATFORM_WEB
|
||||||
#define GLSL_VERSION 100
|
#define GLSL_VERSION 100
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// single digit only!
|
#define MAXSPOT 2
|
||||||
#define MAXSPOT 4
|
|
||||||
|
|
||||||
#define numStars 400
|
#define numStars 400
|
||||||
|
|
||||||
#define screenWidth 1280
|
// Stars in the star field have a position and velocity
|
||||||
#define screenHeight 720
|
typedef struct Star {
|
||||||
|
|
||||||
// the stars in the star field have a position and velocity
|
|
||||||
typedef struct star {
|
|
||||||
Vector2 pos;
|
Vector2 pos;
|
||||||
Vector2 vel;
|
Vector2 vel;
|
||||||
} star;
|
} Star;
|
||||||
|
|
||||||
|
void UpdateStar(Star *s);
|
||||||
void updateStar(star *s);
|
void ResetStar(Star *s);
|
||||||
void resetStar(star *s);
|
|
||||||
|
|
||||||
int main(void)
|
int main(void)
|
||||||
{
|
{
|
||||||
// Initialization
|
// Initialization
|
||||||
//--------------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------------
|
||||||
star stars[numStars];
|
const int screenWidth = 800;
|
||||||
|
const int screenHeight = 450;
|
||||||
|
|
||||||
for (int n=0; n < numStars; n++) {
|
InitWindow(screenWidth, screenHeight, "raylib - shader spotlight");
|
||||||
resetStar(&stars[n]);
|
|
||||||
|
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
|
int frameCounter = 0;
|
||||||
for (int m=0; m < screenWidth / 2.0; m++) {
|
|
||||||
for (int n=0; n<numStars; n++) {
|
|
||||||
updateStar(&stars[n]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//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];
|
Vector2 spotVel[MAXSPOT];
|
||||||
|
|
||||||
// use default vert shader
|
// Use default vert shader
|
||||||
Shader spotShader = LoadShader(0, FormatText("resources/shaders/glsl%i/spotlight.fs", GLSL_VERSION));
|
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";
|
char spotName[32] = "spots[x]\0";
|
||||||
for (int i = 0; i<MAXSPOT; i++) {
|
for (int i = 0; i < MAXSPOT; i++)
|
||||||
|
{
|
||||||
spotName[6] = '0' + i;
|
spotName[6] = '0' + i;
|
||||||
spotLoc[i] = GetShaderLocation(spotShader, spotName);
|
spotLoc[i] = GetShaderLocation(spotShader, spotName);
|
||||||
}
|
}
|
||||||
|
@ -110,47 +94,47 @@ int main(void)
|
||||||
// a pitch black half and a dimly lit half.
|
// a pitch black half and a dimly lit half.
|
||||||
{
|
{
|
||||||
unsigned int wLoc = GetShaderLocation(spotShader, "screenWidth");
|
unsigned int wLoc = GetShaderLocation(spotShader, "screenWidth");
|
||||||
float sw = screenWidth;
|
float sw = (float)GetScreenWidth();
|
||||||
SetShaderValue(spotShader, wLoc, &sw, UNIFORM_FLOAT);
|
SetShaderValue(spotShader, wLoc, &sw, UNIFORM_FLOAT);
|
||||||
}
|
}
|
||||||
|
|
||||||
// randomise the locations and velocities of the spotlights
|
// randomise the locations and velocities of the spotlights
|
||||||
for (int i=0; i<MAXSPOT; i++) {
|
for (int i = 0; i < MAXSPOT; i++)
|
||||||
spotPos[i].x = GetRandomValue(128, screenWidth-128);
|
{
|
||||||
spotPos[i].y = GetRandomValue(128, screenHeight-128);
|
spotPos[i].x = GetRandomValue(64, screenWidth - 64);
|
||||||
|
spotPos[i].y = GetRandomValue(64, screenHeight - 64);
|
||||||
spotVel[i] = (Vector2){ 0, 0 };
|
spotVel[i] = (Vector2){ 0, 0 };
|
||||||
while (fabs(spotVel[i].x)+fabs(spotVel[i].y)<2) {
|
|
||||||
|
while ((fabs(spotVel[i].x) + fabs(spotVel[i].y)) < 2)
|
||||||
|
{
|
||||||
spotVel[i].x = GetRandomValue(-40, 40)/10.0;
|
spotVel[i].x = GetRandomValue(-40, 40)/10.0;
|
||||||
spotVel[i].y = GetRandomValue(-40, 40)/10.0;
|
spotVel[i].y = GetRandomValue(-40, 40)/10.0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
SetTargetFPS(60); // Set to run at 60 frames-per-second
|
SetTargetFPS(60); // Set to run at 60 frames-per-second
|
||||||
//--------------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------------
|
||||||
|
|
||||||
// Main game loop
|
// Main game loop
|
||||||
while (!WindowShouldClose()) // Detect window close button or ESC key
|
while (!WindowShouldClose()) // Detect window close button or ESC key
|
||||||
{
|
{
|
||||||
// Update
|
// Update
|
||||||
//----------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------
|
||||||
|
frameCounter++;
|
||||||
|
|
||||||
frame ++;
|
// Move the stars, resetting them if the go offscreen
|
||||||
|
for (int n = 0; n < numStars; n++) UpdateStar(&stars[n]);
|
||||||
// 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++) {
|
|
||||||
|
|
||||||
|
// Update the spots, send them to the shader
|
||||||
|
for (int i = 0; i < MAXSPOT; i++)
|
||||||
|
{
|
||||||
spotPos[i].x += spotVel[i].x;
|
spotPos[i].x += spotVel[i].x;
|
||||||
spotPos[i].y += spotVel[i].y;
|
spotPos[i].y += spotVel[i].y;
|
||||||
|
|
||||||
if (spotPos[i].x < 128) spotVel[i].x = -spotVel[i].x;
|
if (spotPos[i].x < 64) spotVel[i].x = -spotVel[i].x;
|
||||||
if (spotPos[i].x > screenWidth-128) spotVel[i].x = -spotVel[i].x;
|
if (spotPos[i].x > screenWidth - 64) spotVel[i].x = -spotVel[i].x;
|
||||||
if (spotPos[i].y < 128) spotVel[i].y = -spotVel[i].y;
|
if (spotPos[i].y < 64) spotVel[i].y = -spotVel[i].y;
|
||||||
if (spotPos[i].y > screenHeight-128) 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);
|
SetShaderValue(spotShader, spotLoc[i], &spotPos[i].x, UNIFORM_VEC2);
|
||||||
}
|
}
|
||||||
|
@ -159,22 +143,24 @@ int main(void)
|
||||||
//----------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------
|
||||||
BeginDrawing();
|
BeginDrawing();
|
||||||
|
|
||||||
ClearBackground((Color){0,32,128,255});
|
ClearBackground(DARKBLUE);
|
||||||
|
|
||||||
// stars and bobs
|
// Draw stars and bobs
|
||||||
for (int n=0; n<numStars; n++) {
|
for (int n = 0; n < numStars; n++)
|
||||||
// single pixel is just too small these days!
|
{
|
||||||
|
// Single pixel is just too small these days!
|
||||||
DrawRectangle(stars[n].pos.x, stars[n].pos.y, 2, 2, WHITE);
|
DrawRectangle(stars[n].pos.x, stars[n].pos.y, 2, 2, WHITE);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int i=0; i<16; i++) {
|
for (int i = 0; i < 16; i++)
|
||||||
DrawTexture(rayTex,
|
{
|
||||||
(screenWidth/2.0)+cos((frame+i*8)/51.45)*(screenWidth/2.2)-32,
|
DrawTexture(texRay,
|
||||||
(screenHeight/2.0)+sin((frame+i*8)/17.87)*(screenHeight/4.2),
|
(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);
|
WHITE);
|
||||||
}
|
}
|
||||||
|
|
||||||
// spot lights
|
// Draw spot lights
|
||||||
BeginShaderMode(spotShader);
|
BeginShaderMode(spotShader);
|
||||||
// instead of a blank rectangle you could render here
|
// instead of a blank rectangle you could render here
|
||||||
// a render texture of the full screen used to do screen
|
// a render texture of the full screen used to do screen
|
||||||
|
@ -185,15 +171,13 @@ int main(void)
|
||||||
|
|
||||||
DrawFPS(10, 10);
|
DrawFPS(10, 10);
|
||||||
|
|
||||||
|
|
||||||
EndDrawing();
|
EndDrawing();
|
||||||
//----------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------
|
||||||
}
|
}
|
||||||
|
|
||||||
// De-Initialization
|
// De-Initialization
|
||||||
//--------------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------------
|
||||||
|
UnloadTexture(texRay);
|
||||||
UnloadTexture(rayTex);
|
|
||||||
|
|
||||||
CloseWindow(); // Close window and OpenGL context
|
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 };
|
s->pos = (Vector2){ GetScreenWidth()/2.0f, GetScreenHeight()/2.0f };
|
||||||
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} ));
|
|
||||||
}
|
|
||||||
|
|
||||||
void updateStar(star *s)
|
do
|
||||||
{
|
{
|
||||||
(*s).pos = Vector2Add((*s).pos, (*s).vel);
|
s->vel.x = (float)GetRandomValue(-1000, 1000)/100.0f;
|
||||||
if ((*s).pos.x < 0 || (*s).pos.x > screenWidth ||
|
s->vel.y = (float)GetRandomValue(-1000, 1000)/100.0f;
|
||||||
(*s).pos.y < 0 || (*s).pos.y > screenHeight) {
|
|
||||||
resetStar(s);
|
} 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)
|
||||||
|
{
|
||||||
|
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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue