如果要渲染冒名顶质几何体(比如球体),则标准练习是使用两个三角形绘制它(例如,通过传递一个顶点并使用几何着色器制作三角形条带).
这很好,因为它允许相当简单地设置广告牌的范围:直接计算实际的世界空间位置.
几何着色器可以交替输出点基元,我没有看到它们不应该的原因.唯一的问题是找到一些扩展方法,gl_PointSize以便你获得这种效果.
我能找到的唯一先例是这个问题(我的答案我不确定是正确的)和这个问题(没有答案).
值得注意的是,用距离正确地缩放点是相当简单的(通过这样做gl_PointSize = constant/length(gl_Position),但这是不可控的;你不能说例如:我希望这一点看起来像是两个世界单位.
那么:谁知道怎么做?
这是一个SSCCE:
class Vec final {
public:
float data[4];
inline Vec(void) {}
inline ~Vec(void) {}
};
Vec operator*(float const& scalar, Vec const& vec) {
Vec result;
#if 1
for (int k=0;k<4;++k) result.data[k]=scalar*vec.data[k];
#else
float const*__restrict src = vec.data;
float *__restrict dst = result.data;
for (int k=0;k<4;++k) dst[k]=scalar*src[k];
#endif
return result;
}
int main(int /*argc*/, char* /*argv*/[]) {
Vec vec;
Vec scaledf = 2.0f * vec;
return 0;
}
Run Code Online (Sandbox Code Playgroud)
编译时,MSVC 2013通知我(/Qvec-report:2)
main.cpp(11):info C5002:由于'1200'原因,循环未向量化
这意味着"[l] oop包含循环携带的数据依赖性".
我注意到,对构造函数或析构函数进行注释Vec(编辑:或者默认它们,例如 …
strlen是一个相当简单的函数,显然是O(n)来计算.但是,我已经看到一些方法一次对多个角色进行操作.见例如5 此处或这种方法在这里.这些工作的基本方法是将char const*缓冲区重新解释为uint32_t const*缓冲区,然后一次检查四个字节.
就个人而言,我的直觉反应是这是一个段错等待发生,因为我可能会在有效内存之外取消引用三个字节.然而,这个解决方案似乎已经存在,似乎很奇怪,明显破碎的东西经得起时间的考验.
我认为这包括UB有两个原因:
(请注意,没有别名问题;有人可能会认为uint32_t别名是不兼容的类型,并且代码strlen(例如可能更改字符串的代码)之后的代码可能会无序运行strlen,但事实证明这char是一个严格别名的显式异常).
但是,在实践中失败的可能性有多大?至少,我认为3在字符串文字数据部分之后需要字节填充,malloc需要是4字节或更大的对齐(实际上大多数系统都是这种情况),并且malloc需要分配3额外的字节.还有与别名相关的其他标准.这对编译器实现来说很好,这些实现创建了自己的环境,但这些条件在现代硬件上用于用户代码的频率是多少?
在我的基于物理的渲染器中,我遇到了内存损坏错误(程序崩溃,调试器给出了一个毫无价值的虚假堆栈跟踪).我追溯到这个SSCCE.带有构造函数的行似乎是触发错误的原因:
#include <cstdint>
class Foo final {
public:
uint8_t packed;
public:
inline Foo(void) : packed(0xFF) {} //causes error
inline ~Foo(void) = default;
};
static_assert(sizeof(Foo)==sizeof(uint8_t),"Implementation error!");
int main(int /*argc*/, char* /*argv*/[]) {
Foo* arr = new Foo[4]; //Tried a bunch of different sizes. All fail.
delete [] arr;
return 0;
}
Run Code Online (Sandbox Code Playgroud)
MSVC或GCC不会出现此问题,只有英特尔编译器(其版本为16.0).但是,由于这是一个内存损坏错误,这并不意味着什么.在我提交错误报告之前,有人可以确认这不是我滥用C++吗?
我为所有[u]int{8|16|32|64}_t类型重载了一堆函数:
std::string f( uint8_t) { /*something*/ }
std::string f( int8_t) { /*something*/ }
std::string f(uint16_t) { /*something*/ }
std::string f( int16_t) { /*something*/ }
std::string f(uint32_t) { /*something*/ }
std::string f( int32_t) { /*something*/ }
std::string f(uint64_t) { /*something*/ }
std::string f( int64_t) { /*something*/ }
//A few more overloads with a few more types (bool, float, const char*, etc.)
Run Code Online (Sandbox Code Playgroud)
我现在使用类型的参数调用函数名称long unsigned int:
template <typename type_blah> class Something { public:
//...
std::string call_f(void) const {
return …Run Code Online (Sandbox Code Playgroud) 这是一个10行的C++ 11程序,从我正在编写的程序中大大简化:
template <typename T> class Base { public:
template <typename S> Base(S x) {}
};
template <typename T> class Child : public Base<T> { public:
using Base<T>::Base;
};
template <> class Child<int> : public Base<int> { public:
using Base<int>::Base;
};
int main()
{
Child<int> child(8.0f);
}
Run Code Online (Sandbox Code Playgroud)
MSVC 2015产出:
1>------ Build started: Project: MyProject, Configuration: Debug Win32 ------
1> filename.cpp
1>path\to\filename(10): fatal error C1001: An internal error has occurred in the compiler.
1> (compiler file 'msc1.cpp', line 1393)
1> To …Run Code Online (Sandbox Code Playgroud) c++ visual-c++ c++11 internal-compiler-error visual-studio-2015
在我之前的问题中,已经确定,当对四边形进行纹理化时,将面分解为三角形并且以仿射方式内插纹理坐标.
不幸的是,我不知道如何解决这个问题.该提供的链接是有用的,但它并没有得到预期的效果.作者得出结论:"请注意,图像看起来好像是一个延伸到距离的长矩形四边形......它可能变得非常混乱......因为它会产生"虚假的深度感知".
我想做的是让纹理保留纹理的原始缩放.例如,在梯形情况下,我希望纹素的垂直间距相同(使用绘图程序创建的示例):

请注意,由于垂直间距相同,但四边形明显失真,纹理空间中的直线不再是世界空间中的直线.因此,我认为所需的映射是非线性的.
问题是:这在固定功能管道中是否可能?对于更普通的四边形,我甚至不确定"正确的答案"究竟是什么.我想插值函数可以非常快速地变得非常复杂,我意识到"保留原始缩放"并不是一个算法.世界空间三角形在纹理空间中不再是线性的.
顺便说一句,我并不真正了解3 次和4 次纹理坐标; 如果有人能指出我的资源,这将是伟大的.
我已经看到了一些与半相关的问题,但没有任何问题可以解决这个问题:
该模式是每个解决方案包含多个项目,每个项目都有几个配置.您可以使用"批量构建"功能构建所有这些项目/配置.
现在我需要一种方法同时"批量构建"几个解决方案(一个命令).我的研究似乎表明这不是直接可能的.任何解决方法?我正在使用VS 2013,如果重要的话.
我希望能够手动预测任意算术的长度(即没有分支或内存,尽管这也很好)x86-64汇编代码将采用特定的体系结构,考虑到指令重新排序,超标量,延迟,消费者价格指数等
什么/描述必须遵循的规则才能实现这一目标?
我想我已经找到了一些初步规则,但是我没有找到任何关于将任何示例代码分解为这个详细程度的引用,所以我不得不做一些猜测.(例如,英特尔优化手册甚至几乎没有提到指令重新排序.)
至少,我正在寻找(1)确认每条规则是正确的,或者是每条规则的正确陈述,以及(2)我可能忘记的任何规则的列表.
addps并且subps使用相同的功能) unit?我如何确定?).和:4此循环已经发出少于超标量宽度(通常)指令的数量.例如,请考虑以下示例代码(计算交叉产品):
shufps xmm3, xmm2, 210
shufps xmm0, xmm1, 201
shufps xmm2, xmm2, 201
mulps xmm0, xmm3
shufps xmm1, xmm1, 210
mulps xmm1, xmm2
subps xmm0, xmm1
Run Code Online (Sandbox Code Playgroud)
我试图预测Haswell的延迟看起来像这样:
; `mulps` Haswell latency=5, CPI=0.5
; `shufps` Haswell latency=1, CPI=1
; `subps` Haswell latency=3, CPI=1
shufps xmm3, xmm2, 210 ; cycle 1
shufps xmm0, xmm1, 201 ; cycle 2
shufps xmm2, xmm2, 201 ; …Run Code Online (Sandbox Code Playgroud)