summaryrefslogtreecommitdiffhomepage
path: root/examples/shaders/shaders_palette_switch.c
blob: ad09ca73e0f19ffef0b7c0396143012febdcddf3 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
/*******************************************************************************************
*
*   raylib [shaders] example - Apply a postprocessing shader to a scene
*
*   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), to test this example
*         on OpenGL ES 2.0 platforms (Android, Raspberry Pi, HTML5), use #version 100 shaders
*         raylib comes with shaders ready for both versions, check raylib/shaders install folder
*
*   This example has been created using raylib 2.x (www.raylib.com)
*   raylib is licensed under an unmodified zlib/libpng license (View raylib.h for details)
*
*   Copyright (c) 2015 Ramon Santamaria (@raysan5)
*
********************************************************************************************/

#include "raylib.h"

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

#define MAX_PALETTES            3
#define COLORS_PER_PALETTE      8
#define VALUES_PER_COLOR        3

static const int palettes[MAX_PALETTES][COLORS_PER_PALETTE * VALUES_PER_COLOR] = {
    {
        0, 0, 0,
        255, 0, 0,
        0, 255, 0,
        0, 0, 255,
        0, 255, 255,
        255, 0, 255,
        255, 255, 0,
        255, 255, 255,
    },
    {
        4, 12, 6,
        17, 35, 24,
        30, 58, 41,
        48, 93, 66,
        77, 128, 97,
        137, 162, 87,
        190, 220, 127,
        238, 255, 204,
    },
    {
        21, 25, 26,
        138, 76, 88,
        217, 98, 117,
        230, 184, 193,
        69, 107, 115,
        75, 151, 166,
        165, 189, 194,
        255, 245, 247,
    }
};

static const char *paletteText[] = {
    "3-BIT RGB",
    "AMMO-8 (GameBoy-like)",
    "RKBV (2-strip film)"
};

int main()
{
    // Initialization
    //--------------------------------------------------------------------------------------
    int screenWidth = 800;
    int screenHeight = 450;

    InitWindow(screenWidth, screenHeight, "raylib [shaders] example - palette-switch shader");

    // Load shader to be used on some parts drawing
    // NOTE 1: Using GLSL 330 shader version, on OpenGL ES 2.0 use GLSL 100 shader version
    // NOTE 2: Defining 0 (NULL) for vertex shader forces usage of internal default vertex shader
    Shader shader = LoadShader(0, FormatText("resources/shaders/glsl%i/palette-switch.fs", GLSL_VERSION));

    // Get variable (uniform) location on the shader to connect with the program
    // NOTE: If uniform variable could not be found in the shader, function returns -1
    int paletteLoc = GetShaderLocation(shader, "palette");

    // Initial index not set, will be automatically bounded below.
    int currentPalette = -1;

    SetTargetFPS(60);                       // Set our game to run at 60 frames-per-second
    //--------------------------------------------------------------------------------------

    // Main game loop
    while (!WindowShouldClose())            // Detect window close button or ESC key
    {
        // Update
        //----------------------------------------------------------------------------------
        int paletteIndex = currentPalette;
        if (IsKeyPressed(KEY_RIGHT)) paletteIndex++;
        else if (IsKeyPressed(KEY_LEFT)) paletteIndex--;

        if (paletteIndex >= MAX_PALETTES) paletteIndex = 0;
        else if (paletteIndex < 0) paletteIndex = MAX_PALETTES - 1;

        // Send new value to the shader to be used on drawing.
        // Note that we are sending RGB triplets w/o the alpha channel *only* if the current
        // palette index has changed (in order to save performances).
        if (currentPalette != paletteIndex) {
            currentPalette = paletteIndex;
            SetShaderValueArrayi(shader, paletteLoc, palettes[currentPalette], VALUES_PER_COLOR, COLORS_PER_PALETTE);
        }
        //----------------------------------------------------------------------------------

        // Draw
        //----------------------------------------------------------------------------------
        BeginDrawing();

            ClearBackground(RAYWHITE);

            BeginShaderMode(shader);

                // Draw horizontal screen-wide rectangles with increasing "palette index".
                // The used palette index is encoded in the RGB components of the pixel.
                int linesPerRectangle = screenHeight / COLORS_PER_PALETTE;
                int leftover = screenHeight % COLORS_PER_PALETTE;
                int y = 0;

                for (int i = 0; i < COLORS_PER_PALETTE; ++i) {
                    int height = linesPerRectangle;
                    if (leftover > 0) {
                        height += 1;
                        leftover -= 1;
                    }

                    DrawRectangle(0, y, screenWidth, height, CLITERAL{ i, i, i, 255 });

                    y += height;
                }

            EndShaderMode();

            DrawText("CURRENT PALETTE:", 10, 15, 20, RAYWHITE);
            DrawText(paletteText[currentPalette], 240, 15, 20, RED);
            DrawText("< >", 540, 10, 30, DARKBLUE);

            DrawFPS(700, 15);

        EndDrawing();
        //----------------------------------------------------------------------------------
    }

    // De-Initialization
    //--------------------------------------------------------------------------------------
    UnloadShader(shader);       // Unload shader

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

    return 0;
}