File: palettes_base.hpp

package info (click to toggle)
glvis 4.5-1
  • links: PTS, VCS
  • area: main
  • in suites: sid
  • size: 7,780 kB
  • sloc: cpp: 35,217; ansic: 5,695; sh: 340; makefile: 301; python: 193
file content (231 lines) | stat: -rw-r--r-- 6,596 bytes parent folder | download
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
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
// Copyright (c) 2010-2026, Lawrence Livermore National Security, LLC. Produced
// at the Lawrence Livermore National Laboratory. All Rights reserved. See files
// LICENSE and NOTICE for details. LLNL-CODE-443271.
//
// This file is part of the GLVis visualization tool and library. For more
// information and source code availability see https://glvis.org.
//
// GLVis is free software; you can redistribute it and/or modify it under the
// terms of the BSD-3 license. We welcome feedback and contributions, see file
// CONTRIBUTING.md for details.

#ifndef GLVIS_PALETTESBASE_HPP
#define GLVIS_PALETTESBASE_HPP

#include "gl/types.hpp"

#include <array>
#include <string>
#include <iostream>
#include <memory>
#include <vector>

struct RGBAf
{
   float r, g, b, a;

   constexpr RGBAf(float r = 0.0, float g = 0.0, float b = 0.0, float a = 1.0)
      : r(r), g(g), b(b), a(a) {}

   void Print(std::ostream& os = std::cout) const;

   std::array<float, 4> AsArray() const { return {r, g, b, a}; }
};


class Palette
{
public:
   const std::string name;

   /// Constructors
   Palette(const std::string& name) : name(name) {}

   /// Constructor from vector of RGBAf
   Palette(const std::string& name, const std::vector<RGBAf>& colors)
      : name(name), colors(colors) {}

   /// Constructor from Nx3 array
   template <size_t N>
   Palette(const std::string& name, const std::array<std::array<float,3>,N>& arr);

   /// Constructor from Nx4 array
   template <size_t N>
   Palette(const std::string& name, const std::array<std::array<float,4>,N>& arr);

   /// Get size
   int Size() const { return colors.size(); }

   /// Add color to palette
   void AddColor(float r, float g, float b, float a = 1.0);

   /// Print each color of this palette to a stream
   void Print(std::ostream& os = std::cout) const;

   /// Get color at index i (optionally, use reversed order)
   RGBAf Color(int i, bool reversed = false) const;

   /// Get all colors as a vector of float arrays
   std::vector<std::array<float,4>> GetData(bool reversed = false) const;

   /// Are any alpha != 1.0?
   bool IsTranslucent() const;

private:
   std::vector<RGBAf> colors;
};

/// Generates the texture data for a given palette, to be used in OpenGL
class Texture
{
   using TexHandle = gl3::resource::TextureHandle;
public:
   // What type of texture is this (discrete, smooth, alphamap)
   enum class TextureType
   {
      DISCRETE = 0,
      SMOOTH = 1,
      ALPHAMAP = 2,
   };

   /// Empty constructor
   Texture() {}

   /// Constructor - generates texture
   Texture(const Palette* palette,
           TextureType textype = TextureType::DISCRETE,
           int cycles = 1, int colors = 0);

   /// Constructor for alphamap
   Texture(float matAlpha, float matAlphaCenter);

   /// Get texture size.
   int Size() { return tsize; }

   /// Get the GL texture
   GLuint Get() const { return texture; }

   /// Generate the GL texture and binds it to `texture`
   void Generate();

   /// Update alpha/regular texture parameters
   void UpdateAlphaParameters(float matAlpha, float matAlphaCenter);
   void UpdateParameters(int cycles, int colors);

private:
   /// The palette to create a texture of
   const Palette* palette;
   // What type of texture is this (discrete, smooth, alphamap)
   TextureType textype;

   /// GL static parameters
   static GLenum alpha_internal;
   static GLenum alpha_channel;
   static GLenum rgba_internal;
   static GLenum rgba_channel;
   static int max_texture_size;

   /// Repeat the palette multiple times (negative for reverse); cannot be 0
   int nrepeat;
   /// Number of colors to discretize with (0 uses the original number of colors)
   int ncolors;
   /// Is the texture reversed?
   bool reversed;
   /// Texture size
   int tsize;
   /// The GL texture
   TexHandle texture;
   /// Only used for alphamap
   float alpha;
   float alpha_center;

   /// Initialize Static GL parameters
   static void InitStaticGL();

   /// Generate alpha/regular texture data
   std::vector<float> GenerateAlphaTextureData();
   std::vector<std::array<float,4>> GenerateTextureData();

   /// Set the number of cycles
   void SetCycles(int cycles);

   /// Set the number of colors
   void SetColors(int colors);

   /// Update the texture size (may change ncolors and/or cycles if too large)
   void UpdateTextureSize();
};


/// Behaves like make_unique (only available in >= c++14)
template<typename T, typename... Args>
std::unique_ptr<T> as_unique(Args&&... args)
{
   return std::unique_ptr<T>(new T(std::forward<Args>(args)...));
}

/// Holds a vector of unique_ptr<Palette>. Besides holding the
/// palettes this should be stateless (put state in PaletteState)
class PaletteRegistry
{
private:
   std::vector<std::unique_ptr<Palette>> palettes;

   int default_palette = -1; // index of the default palette

public:
   /// Empty constructor
   PaletteRegistry() {}

   /// Constructor via a const vector of Palettes; if name already exists, skip
   /// Used for loading compiled palettes (i.e. `palettes_default.cpp`)
   PaletteRegistry(const std::vector<Palette>& paletteRefs);

   /// Adds an existing palette to the registry
   void AddPalette(Palette& palette);

   /// Create a new palette with the given name and add it to the registry
   void AddPalette(const std::string& name);

   /// Returns true if name is unique
   bool IsNameUnique(const std::string& name) const;

   /// Get a palette pointer by index; if not found, returns last palette
   Palette* Get(int index) const;

   /// Get a palette pointer by name; if not found, returns last palette
   Palette* Get(const std::string& name) const;

   /// Find the index of a palette by name
   int GetIndexByName(const std::string& name) const;

   /// Set the index of the default palette by name
   void SetDefault(const std::string& name);

   /// Get the index of the default palette
   int GetDefault() const { return default_palette; };

   /// Prints a summary (index + name) of all palettes
   void PrintSummary(std::ostream& os = std::cout) const;

   /// Prints all colors for all palettes
   void PrintAll(std::ostream& os = std::cout) const;

   /// Number of palettes in the registry
   int NumPalettes() const { return palettes.size(); }

   /// Loads palette(s) from a file.
   /**  Format is:
      palette <palette_name> <RGBf/RGBAf>
      <r1> <g1> <b1> [<a1>]
      <r2> <g2> <b2> [<a2>]
      ...

      see `share/palettes-crameri.txt` for an example */
   void Load(const std::string& palette_filename);
};


extern PaletteRegistry BasePalettes;

#endif // GLVIS_PALETTESBASE_HPP