File: attr_traits.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 (160 lines) | stat: -rw-r--r-- 5,384 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
// 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_ATTR_TRAITS_HPP
#define GLVIS_ATTR_TRAITS_HPP

#include "renderer_core.hpp"

namespace gl3
{

struct AttrNone
{
   static void setup() { }
   static void setupLegacy(void*) { }
   static void clear() { }
   static void clearLegacy() { }
   enum { exists = false };
};

// Base class to generate vertex attribute setup functions.
template<
   typename TV, typename TAttr, TAttr TV::*Attrib, typename TAttrInfo>
struct AttrBase
{
   constexpr static TAttr* getAttrOffset()
   {
      return &(((TV*)0)->*Attrib);
   }

   // Sets up vertex attributes in the currently-bound buffer object.
   static void setup()
   {
      glEnableVertexAttribArray(TAttrInfo::ShaderIdx);
      glVertexAttribPointer(TAttrInfo::ShaderIdx,
                            TAttrInfo::NumTuples,
                            TAttrInfo::AttrGLType,
                            TAttrInfo::NormalizeAttr,
                            sizeof(TV),
                            (void*) getAttrOffset());
   }

   // Sets up client-side vertex pointers for the given buffer.
   static void setupLegacy(TV* buffer)
   {
      glEnableClientState(TAttrInfo::FFArrayIdx);
      TAttrInfo::FFSetupFunc(TAttrInfo::NumTuples,
                             TAttrInfo::AttrGLType,
                             sizeof(TV),
                             (char*) buffer + (size_t) getAttrOffset());
   }

   // Disables the attribute array.
   static void clear()
   {
      glDisableVertexAttribArray(TAttrInfo::ShaderIdx);
   }

   // Disables the client-side vertex array.
   static void clearLegacy()
   {
      glDisableClientState(TAttrInfo::FFArrayIdx);
   }

   enum { exists = true };
};

// Default attribute traits for vertex types. Provides no-op setup/clear
// functions if an attribute doesn't exist.
template<typename TV, typename = int>
struct AttrCoord : AttrNone { };

template<typename TV, typename = int>
struct AttrNormal : AttrNone { };

template<typename TV, typename = int>
struct AttrColor : AttrNone { };

template<typename TV, typename = int>
struct AttrTexcoord : AttrNone { };

// Template specializations for attribute traits. If an attribute exists in a
// vertex, generates setup and clear functions which setup OpenGL vertex
// attributes.
//
// Each attribute specialization defines static parameters which are passed to
// the AttrBase base class via CRTP to generate the attribute setup functions:
//  - AttrGLType: the OpenGL type of the attribute data
//  - ShaderIdx: the index of the generic vertex attribute
//  - FFArrayIdx: the index of the client-side vertex attribute array
//  - FFSetupFunc: the function to use when setting up the FF array pointer;
//      this can either be a direct pointer to a gl*Pointer function or a custom
//      function
template<typename TV>
struct AttrCoord<TV, decltype((void)TV::coord, 0)>
: AttrBase<TV, decltype(TV::coord), &TV::coord,
AttrCoord<TV, decltype((void)TV::coord, 0)>>
{
   constexpr static bool NormalizeAttr = false;
   constexpr static int NumTuples = 3;
   const static GLenum AttrGLType = GL_FLOAT;
   const static int ShaderIdx = CoreGLDevice::ATTR_VERTEX;
   const static GLenum FFArrayIdx = GL_VERTEX_ARRAY;
   constexpr static auto FFSetupFunc = glVertexPointer;
};

template<typename TV>
struct AttrNormal<TV, decltype((void)TV::norm, 0)>
: AttrBase<TV, decltype(TV::norm), &TV::norm,
AttrNormal<TV, decltype((void)TV::norm, 0)>>
{
   constexpr static bool NormalizeAttr = false;
   constexpr static int NumTuples = 3;
   const static GLenum AttrGLType = GL_FLOAT;
   const static int ShaderIdx = CoreGLDevice::ATTR_NORMAL;
   const static GLenum FFArrayIdx = GL_NORMAL_ARRAY;
   static void FFSetupFunc(GLint /*size*/, GLenum type, GLsizei stride,
                           const GLvoid* ptr)
   {
      glNormalPointer(type, stride, ptr);
   }
};

template<typename TV>
struct AttrColor<TV, decltype((void)TV::color, 0)>
: AttrBase<TV, decltype(TV::color), &TV::color,
AttrColor<TV, decltype((void)TV::color, 0)>>
{
   constexpr static bool NormalizeAttr = true;
   constexpr static int NumTuples = 4;
   const static GLenum AttrGLType = GL_UNSIGNED_BYTE;
   const static int ShaderIdx = CoreGLDevice::ATTR_COLOR;
   const static GLenum FFArrayIdx = GL_COLOR_ARRAY;
   constexpr static auto FFSetupFunc = glColorPointer;
};

template<typename TV>
struct AttrTexcoord<TV, decltype((void)TV::texCoord, 0)>
: AttrBase<TV, decltype(TV::texCoord), &TV::texCoord,
AttrTexcoord<TV, decltype((void)TV::texCoord, 0)>>
{
   constexpr static bool NormalizeAttr = false;
   constexpr static int NumTuples = 1;
   const static GLenum AttrGLType = GL_FLOAT;
   const static int ShaderIdx = CoreGLDevice::ATTR_TEXCOORD0;
   const static GLenum FFArrayIdx = GL_TEXTURE_COORD_ARRAY;
   constexpr static auto FFSetupFunc = glTexCoordPointer;
};

}

#endif // GLVIS_ATTR_TRAITS_HPP