summaryrefslogtreecommitdiff
path: root/graphics/asymptote/GLTextures.h
blob: f2507a75b0b89c2434ba6c5b3aff4dab1a248812 (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
//
// Created by jamie on 8/23/21.
//

#pragma once

#include "common.h"

#ifdef HAVE_GL

#include "GL/glew.h"

namespace gl
{
struct GLTexturesFmt
{
  GLint minFilter=GL_LINEAR_MIPMAP_LINEAR;
  GLint magFilter=GL_LINEAR;
  GLint wrapS=GL_REPEAT;
  GLint wrapT=GL_REPEAT;
  GLint wrapR=GL_REPEAT;

  GLuint format=GL_RGBA;
  GLuint internalFmt=GL_RGBA;
};

class AGLTexture
{
protected:
  AGLTexture() = default;
  explicit AGLTexture(int textureNumber);

  AGLTexture(AGLTexture const&) = delete;
  AGLTexture& operator=(AGLTexture const&) = delete;

  AGLTexture(AGLTexture&& glTex) noexcept;
  AGLTexture& operator=(AGLTexture&& glTex) noexcept;

public:
  virtual ~AGLTexture();
  void setActive() const;
  virtual void setUniform(GLint uniformNumber) const = 0;

protected:
  GLuint textureId=0;
  int textureNumber=-1;
};

template<typename T=float, GLuint GLDataType=GL_FLOAT>
class GLTexture2 : public AGLTexture
{
public:
  GLTexture2() = default;
  GLTexture2(GLTexture2 const& glTex)=delete;
  GLTexture2& operator= (GLTexture2 const& glTex)=delete;

  GLTexture2(GLTexture2&& glTex) noexcept: AGLTexture(std::move(glTex))
  {
  }

  GLTexture2& operator=(GLTexture2&& glTex) noexcept
  {
    AGLTexture::operator=(std::move(glTex));
    return *this;
  }

  GLTexture2(T const* data, std::pair<int, int> size,
             int textureNumber, GLTexturesFmt const& fmt) : AGLTexture(textureNumber)
  {
    glGenTextures(1, &textureId);

    glActiveTexture(GL_TEXTURE0+textureNumber);
    glBindTexture(GL_TEXTURE_2D, textureId);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, fmt.minFilter);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, fmt.magFilter);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, fmt.wrapS);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, fmt.wrapT);
    glTexImage2D(GL_TEXTURE_2D, 0, fmt.internalFmt, size.first, size.second, 0,
                 fmt.format, GLDataType, data);
    glGenerateMipmap(GL_TEXTURE_2D);
    glActiveTexture(0);
  }

  void setUniform(GLint uniformNumber) const override
  {
    glActiveTexture(GL_TEXTURE0+textureNumber);
    glBindTexture(GL_TEXTURE_2D, textureId);
    glUniform1i(uniformNumber, textureNumber);
    glActiveTexture(0);
  }
};

template<typename T=float, GLuint GLDataType=GL_FLOAT>
class GLTexture3 : public AGLTexture
{
public:
  GLTexture3() = default;
  GLTexture3(T const* data, std::tuple<int, int, int> size,
             int textureNumber, GLTexturesFmt const& fmt) : AGLTexture(textureNumber)
  {
    int width=std::get<0>(size);
    int height=std::get<1>(size);
    int depth=std::get<2>(size);
    glEnable(GL_TEXTURE_3D);

    glGenTextures(1, &textureId);
    glActiveTexture(GL_TEXTURE0+textureNumber);
    glBindTexture(GL_TEXTURE_3D, textureId);
    glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_S, fmt.wrapS);
    glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_T, fmt.wrapT);
    glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_R, fmt.wrapR);
    glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAX_LEVEL, 0);
    glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MIN_FILTER, fmt.minFilter);
    glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAG_FILTER, fmt.magFilter);

    glTexImage3D(GL_TEXTURE_3D, 0, fmt.internalFmt, width, height, depth, 0, fmt.format,
                 GLDataType, data);
    glGenerateMipmap(GL_TEXTURE_3D);
    glActiveTexture(0);
  }

  void setUniform(GLint uniformNumber) const override
  {
    glActiveTexture(GL_TEXTURE0+textureNumber);
    glBindTexture(GL_TEXTURE_3D, textureId);
    glUniform1i(uniformNumber, textureNumber);
    glActiveTexture(0);
  }
};

} // namespace gl

#endif