有没有办法根据template
参数在类中生成变量的名称?
template<class T, (someconstruct) t>
class Item {
public:
T t;
};
Item<float, "Position"> myItem;
myItem.Position = 0.123f;
Run Code Online (Sandbox Code Playgroud)
这样我实例化的是一个类型的变量T
,带有标识符t
(t
由程序员传入的地方,也就是说Position
,我们有一个T
被调用的Position
?或者这是否将模板元编程概念拉得太远了?:p
有人能告诉我看似不必要的复杂的统一缓冲区吗?我已经阅读了OpenGL Superbible 5中的部分,我在博客上看了一些例子,我已经阅读了官方规范,但我仍然没有得到它.
具体来说,所有示例似乎都需要一个着色器程序,以便最初使用glGetActiveUniformsiv设置统一缓冲区.我不明白这一点.为什么接口不允许您在不参考着色器程序的情况下定义结构,在链接时针对程序验证缓冲区/ s格式?
其次,如果我从一个程序获得结构布局,假设所有使用该组制服的程序的结构布局相同,那么结构是否保证具有相同的偏移量,数据大小等等?我会这么认为.
第三,我不明白约束点.我必须使用索引调用glBindBufferBase,然后使用块索引调用glUniformBlockBinding,并将索引传递给glBindBufferBase.我无法直观地看到这里发生了什么.Superbible缺乏清晰度,我见过的规格和样品也是如此.
OpenGL规范在于(或者这是一个错误?)...参考std140的布局,使用共享的统一缓冲区,它指出:
"GLL编译器使用Tabl e L-1中显示的规则集来布局符合std140的统一块中的成员.块中成员的偏移量是根据块中先前成员的大小累加的(那些在有问题的变量之前声明的那些,以及起始偏移量.第一个成员的起始偏移量总是为零.
标量变量类型(bool,int,uint,float) - 基本机器类型中标量的大小"
(http://www.opengl-redbook.com/appendices/AppL.pdf)
所以,有了这些信息,我在我的着色器中设置了一个看起来像这样的统一块:
// Spotlight.
layout (std140) uniform Spotlight
{
float Light_Intensity;
vec4 Light_Ambient;
vec3 Light_Position;
};
Run Code Online (Sandbox Code Playgroud)
...只是发现它不适用于我在CPU端设置的后续std140布局.这是前4个字节是浮点数(GLfloat的机器标量类型的大小),接下来的16个字节是vec4,后面的12个字节是vec3(末尾有4个字节,考虑到规则vec3真的是一个vec4).
当我改变CPU端以指定浮点数与vec4的大小相同时,即16个字节,并做我的偏移和缓冲区大小做出这个假设,着色器按预期工作.
所以,无论是规范是错还是我在这种情况下误解了"标量"的含义,或者ATI有驱动程序错误.任何人都可以对这个谜团有所了解吗?
我一直在阅读很多关于多线程渲染的内容.人们一直在提出各种奇怪而精彩的方案,用于通过线程向GPU提交工作,以加快帧速率并获得更多的东西,但是我对整个事情有一点概念上的问题而且我以为我会在这里由大师来看看你的想法.
据我所知,GPU上的基本并发单位是Warp.也就是说,它在像素级别下降而不是在几何提交级别上升.因此,考虑到GPU上的并发单位是warp,驱动程序必须与互斥锁紧密锁定,以防止多个线程搞砸彼此的提交.如果是这种情况,我不知道编码D3D或OpenGL多线程原语的好处在哪里.
当然,在多线程场景中使用GPU的最有效方法是在更高的抽象级别,在提交之前,您要收集多批工作?我的意思是,而不是随机地交叉来自多个线程的命令,我会认为一个块接受来自多个线程的工作,但是在其内部具有一点智能以确保在提交给渲染器之前为了更好的性能而排序事物,将是如果你想使用多个线程,会获得更大的收益.
那么,D3D/OpenGL多线程渲染是否支持实际的API?
帮助我解决困惑!
我想这是纯C ++问题和OpenGL问题之间的一种交叉。我有一个统一的缓冲区,正在其中分配sizeof(ShaderData)字节的空间。我在着色器的GPU端使用std140布局。
根据std140规则,我需要在结构的各个位置添加填充以确保矢量正确对齐。下面的结构是一个示例(针对我的观点):
struct ShaderData {
float Light_Intensity;
float _pad1[3]; // align following vec3 on 4N boundary
Math::Vec3f Light_Position;
float _pad2; // align following vec4 on 4N boundary
Math::Colour4f Light_Ambient;
Math::Colour4f Light_Diffuse;
Math::Colour4f Light_Specular;
float Light_AttenuationMin;
float Light_AttenuationMax;
} MyShaderData;
Run Code Online (Sandbox Code Playgroud)
这是人们通常用C ++进行操作的方式吗?还是有一些特殊的关键字或实用说明来使结构CPU端的各个元素对齐?
我一直在思索使用unique_ptr
VS shared_ptr
VS own_solution
.我已经贴现后,我几乎肯定会弄错了,但我有一个问题,都unique_ptr
和shared_ptr
中,无论是捕捉恰恰就是我想要的.我想创建一个显式拥有资源的资源管理器,但是我希望资源管理器也能分发对资源的引用.
如果我unique_ptr
在资源管理器中使用并分发原始指针,那么他们可能会逃到其他地方(尽管这会违反我认为的类"合同").如果我使用shared_ptr
和分发weak_ptr
,那么没有什么能阻止调用者将其转换weak_ptr
为a shared_ptr
并存储它,从而可能创建一个循环或更糟的是,资源生存在资源管理器的生命周期之外.因此,我认为我正在寻找的是一种weak_ptr
无法转化为无法实现的shared_ptr
.
或者我只是想在代码中使用一些措辞强烈的评论强制执行合同?
感谢您对此可能有的任何想法.
关于 RGB 和 sRGB,我的以下理解(或不正确)是否正确?
GL_SRGB8
格式纹理。
GL_RGB8
纹理。
GL_FRAMEBUFFER_SRGB
在管道的最后阶段设置为 true。
GL_RGBA16F
)
我在这里阅读了一个答案,展示了如何使用以下一(2)个内容将整个流读入std :: string:
std::istreambuf_iterator<char> eos;
std::string s(std::istreambuf_iterator<char>(stream), eos);
Run Code Online (Sandbox Code Playgroud)
对于做类似的读取一个二进制流成的东西std::vector
,为什么我不能简单地替换char
用uint8_t
和std::string
用std::vector
?
auto stream = std::ifstream(path, std::ios::in | std::ios::binary);
auto eos = std::istreambuf_iterator<uint8_t>();
auto buffer = std::vector<uint8_t>(std::istreambuf_iterator<uint8_t>(stream), eos);
Run Code Online (Sandbox Code Playgroud)
以上产生编译器错误(VC2013):
1> d:\non-svn\c ++\library\i\file\filereader.cpp(62):错误C2440:'':无法从'std :: basic_ifstream>'转换为'std :: istreambuf_iterator>'1>
with 1> [1> _Elem = uint8_t 1>] 1>
没有构造函数可以采用源类型,或者构造函数重载解析是模糊的
在阅读了datenwolf 2011 年关于 OpenGL 中基于图块的渲染设置的答案后,我尝试实现他的解决方案。源图像如下所示(800 x 600)
生成的图像具有 2x2 图块,每个图块大小为 800 x 600,如下所示。
正如你所看到的,它们并不完全匹配,尽管我可以看到发生了一些隐约有趣的事情。我确信我在某个地方犯了一个基本错误,但我看不出来。
我正在执行 4 次传递,其中:
w, h are 2,2 (2x2 tiles)
x, y are (0,0) (1,0) (0,1) and (1,1) in each of the 4 passes
MyFov is 1.30899692 (75 degrees)
MyWindowWidth, MyWindowHeight are 800, 600
MyNearPlane, MyFarPlane are 0.1, 200.0
Run Code Online (Sandbox Code Playgroud)
计算每个图块的截锥体的算法是:
auto aspect = static_cast<float>(MyWindowWidth) / static_cast<float>(MyWindowHeight);
auto right = -0.5f * Math::Tan(MyFov) * MyShaderData.Camera_NearPlane;
auto left = -right;
auto top = aspect * right;
auto …
Run Code Online (Sandbox Code Playgroud) 我试图用一个模板化的类来替换我的所有"获取/发布"RAII类(我现在每种资源都有一个).获取的一般形式是一些类型是Acquire(),一些是Acquire(p1),一些是Acquire(p1,p2)等.Release也是如此.但是,如果资源是使用参数获取的,则需要使用相同的参数释放它.
我想我可以使用可变参数模板,将参数存储在元组中.当然,我已经贬低了语法.有人可以帮忙吗?
#include <tuple>
template<class T, typename... Args>
class Raii
{
public:
Raii(T * s, Args&& ... a) : subect(s), arguments(a)
{
subject->Acquire(arguments);
}
~Raii()
{
subject->Release(arguments);
}
private:
T subject;
std::tuple<Args...> arguments;
};
class Framebuffer
{
public:
void Acquire() {}
void Release() {}
};
class Sampler
{
public:
void Acquire(int channel) {}
void Release(int channel) {}
};
class Buffer
{
public:
void Acquire(int target, int location) {}
void Release(int target, int location) {}
};
int main(void)
{
Framebuffer f; …
Run Code Online (Sandbox Code Playgroud)