GteTextureBuffer.h
Go to the documentation of this file.
1 // David Eberly, Geometric Tools, Redmond WA 98052
2 // Copyright (c) 1998-2017
3 // Distributed under the Boost Software License, Version 1.0.
4 // http://www.boost.org/LICENSE_1_0.txt
5 // http://www.geometrictools.com/License/Boost/LICENSE_1_0.txt
6 // File Version: 3.0.1 (2016/08/29)
7 
8 #pragma once
9 
10 #include <LowLevel/GteLogger.h>
11 #include <Graphics/GteBuffer.h>
13 #include <Graphics/GteTexture.h>
14 #include <algorithm>
15 
16 namespace gte
17 {
18 
20 {
21 public:
22  // Construction. The HLSL shader contains
23  // tbuffer MyTBuffer { type myArray[numElements]; }
24  // where 'type' is a native type such as 'float4' and the texture buffer
25  // 'format' specifies how the type is interpreted. The 'numElements' of
26  // the constructor must match that of myArray[]. Effectively, the
27  // tbuffer is a 1D texture. If you want to update the contents of the
28  // texture buffer at run time, much like you update a constant buffer,
29  // set 'allowDynamicUpdate' to 'true'; otherwise, the buffer is immutable.
30  TextureBuffer(DFType format, unsigned int numElements,
31  bool allowDynamicUpdate);
32 
33  DFType GetFormat() const;
34 
35  // Access to texture buffer members using the layout of a shader
36  // program itself is allowed as long as you have attached the constant
37  // buffer to a shader first.
38  // std::shared_ptr<VertexShader> vshader = <some shader>;
39  // std::shared_ptr<TextureBuffer> tbuffer = <buffer for the shader>;
40  // vshader->Set("MyTBuffer", tbuffer);
41  // Now you can use SetMember/GetMember calls successfully. In these
42  // calls, you are required to specify the correct type T for the member.
43  // No checking is performed for the size of the input; i.e., too large a
44  // 'value' will cause a memory overwrite within the buffer. The code
45  // does test to ensure that no overwrite occurs outside the buffer.
46 
47  inline void SetLayout(std::vector<MemberLayout> const& layout);
48  inline std::vector<MemberLayout> const& GetLayout() const;
49 
50  // Test for existence of a member with the specified name.
51  bool HasMember(std::string const& name) const;
52 
53  // Set or get a non-array member.
54  template <typename T>
55  bool SetMember(std::string const& name, T const& value);
56 
57  template <typename T>
58  bool GetMember(std::string const& name, T& value) const;
59 
60  // Set or get an array member.
61  template <typename T>
62  bool SetMember(std::string const& name, unsigned int index,
63  T const& value);
64 
65  template <typename T>
66  bool GetMember(std::string const& name, unsigned int index,
67  T& value) const;
68 
69 protected:
70  DFType mFormat;
71  std::vector<MemberLayout> mLayout;
72 
73 public:
74  // For use by the Shader class for storing reflection information.
75  static int const shaderDataLookup = 1;
76 };
77 
78 
79 inline void TextureBuffer::SetLayout(std::vector<MemberLayout> const& layout)
80 {
81  mLayout = layout;
82 }
83 
84 inline std::vector<MemberLayout> const& TextureBuffer::GetLayout() const
85 {
86  return mLayout;
87 }
88 
89 template <typename T>
91 {
92  auto iter = std::find_if(mLayout.begin(), mLayout.end(),
93  [&name](MemberLayout const& item){ return name == item.name; });
94 
95  if (iter == mLayout.end())
96  {
97  LogError("Failed to find member name " + name + ".");
98  return false;
99  }
100 
101  if (iter->numElements > 0)
102  {
103  LogError("Member is an array, use SetMember(name,index,value).");
104  return false;
105  }
106 
107  if (iter->offset + sizeof(T) > mNumBytes)
108  {
109  LogError("Writing will access memory outside the buffer.");
110  return false;
111  }
112 
113  T* target = reinterpret_cast<T*>(mData + iter->offset);
114  *target = value;
115  return true;
116 }
117 
118 template <typename T>
120 {
121  auto iter = std::find_if(mLayout.begin(), mLayout.end(),
122  [&name](MemberLayout const& item){ return name == item.name; });
123 
124  if (iter == mLayout.end())
125  {
126  LogError("Failed to find member name " + name + ".");
127  return false;
128  }
129 
130  if (iter->numElements > 0)
131  {
132  LogError("Member is an array, use GetMember(name,index,value).");
133  return false;
134  }
135 
136  if (iter->offset + sizeof(T) > mNumBytes)
137  {
138  LogError("Reading will access memory outside the buffer.");
139  return false;
140  }
141 
142  T* target = reinterpret_cast<T*>(mData + iter->offset);
143  value = *target;
144  return true;
145 }
146 
147 template <typename T>
148 bool TextureBuffer::SetMember(std::string const& name, unsigned int index,
149  T const& value)
150 {
151  auto iter = std::find_if(mLayout.begin(), mLayout.end(),
152  [&name](MemberLayout const& item){ return name == item.name; });
153 
154  if (iter == mLayout.end())
155  {
156  LogError("Failed to find member name " + name + ".");
157  return false;
158  }
159 
160  if (iter->numElements == 0)
161  {
162  LogError("Member is a singleton, use SetMember(name,value).");
163  return false;
164  }
165 
166  if (index >= iter->numElements)
167  {
168  LogError("Index is out of range for the member array.");
169  return false;
170  }
171 
172  if (iter->offset + (index + 1)*sizeof(T) > mNumBytes)
173  {
174  LogError("Writing will access memory outside the buffer.");
175  return false;
176  }
177 
178  T* target = reinterpret_cast<T*>(mData + iter->offset + index*sizeof(T));
179  *target = value;
180  return true;
181 }
182 
183 template <typename T>
184 bool TextureBuffer::GetMember(std::string const& name, unsigned int index,
185  T& value) const
186 {
187  auto iter = std::find_if(mLayout.begin(), mLayout.end(),
188  [&name](MemberLayout const& item){ return name == item.name; });
189 
190  if (iter == mLayout.end())
191  {
192  LogError("Failed to find member name " + name + ".");
193  return false;
194  }
195 
196  if (iter->numElements == 0)
197  {
198  LogError("Member is a singleton, use GetMember(name,value).");
199  return false;
200  }
201 
202  if (index >= iter->numElements)
203  {
204  LogError("Index is out of range for the member array.");
205  return false;
206  }
207 
208  if (iter->offset + (index + 1)*sizeof(T) > mNumBytes)
209  {
210  LogError("Reading will access memory outside the buffer.");
211  return false;
212  }
213 
214  T* target = reinterpret_cast<T*>(mData + iter->offset + index*sizeof(T));
215  value = *target;
216  return true;
217 }
218 
219 
220 }
std::vector< MemberLayout > const & GetLayout() const
GLsizei const GLfloat * value
Definition: glcorearb.h:819
GLuint const GLchar * name
Definition: glcorearb.h:781
GLenum target
Definition: glcorearb.h:1662
GLsizei const GLchar *const * string
Definition: glcorearb.h:809
#define LogError(message)
Definition: GteLogger.h:92
bool SetMember(std::string const &name, T const &value)
std::vector< MemberLayout > mLayout
GLint GLint GLsizei GLint GLenum format
Definition: glcorearb.h:103
GLuint index
Definition: glcorearb.h:781
void SetLayout(std::vector< MemberLayout > const &layout)
#define GTE_IMPEXP
Definition: GTEngineDEF.h:63
bool GetMember(std::string const &name, T &value) const


geometric_tools_engine
Author(s): Yijiang Huang
autogenerated on Thu Jul 18 2019 04:00:01