- iOS/Objective-C 元类和类别
- objective-c - -1001 错误,当 NSURLSession 通过 httpproxy 和/etc/hosts
- java - 使用网络类获取 url 地址
- ios - 推送通知中不播放声音
This question询问是否可以依靠编译器不弄乱 struct
的值顺序和填充。
根据该问题的答案,
OpenGL defines, very clearly, what the byte layout of a
std140
interface block is.C++11 defines a concept called "standard layout types".
The only things C++ tells you about standard layout types with regard to layout is that empty base classes are ignored (so long as it remains standard layout) and that the first NSDM will be at the very beginning of the class. That is, there will never be padding at the front.
The other thing the standard says is that NSDMs of the same access class will be allocated in order, with later ones having larger offsets than earlier ones.
But that's it, as far as the C++ standard is concerned. [class.mem]/13 states that implementations can add padding between members for various reasons.
可能但并不总是存在的填充确实会把事情搞砸,最糟糕的是 - 这取决于编译器。
为了避免错误和噩梦,使用与编译器无关的方法不是更好吗?
例如:
class BufferData
{
private:
GLfloat data[12];
public:
GLfloat* getCameraPosition()
{
return (GLfloat*) &data[0];
}
GLfloat* getLightPosition()
{
return (GLfloat*) &data[4];
}
GLfloat* getLightDiffuse()
{
return (GLfloat*) &data[8];
}
GLfloat* getData()
{
return data;
}
};
相对于天真:
struct BufferData
{
GLfloat camera_position[4];
GLfloat light_position[4];
GLfloat light_diffuse[4];
};
还是天真的方法就足够好了?
(让我们假设类/结构不仅如此,而且可能会改变)
最佳答案
“与编译器无关”?没有这种动物。你写一个的尝试证明了这一点。考虑您的结构成员定义:
GLfloat data[12];
这需要存在 GLfloat
类型。但问题是,C++ 没有定义那种类型。 OpenGL 可以。
OpenGL 非常清楚地定义了该类型:它是一个 IEEE-754 floating-point type, using the BINARY32 format .
事实是,C++ 不要求 float
符合这一点。事实上,C++ 并不要求它的任何类型都符合这一点。如果编译器想让 float
使用 IEEE-754 以外的东西,那很好。
现在,您可能会说 OpenGL header 可以将 GLfloat
定义为一个类类型,大小为 32 位,它将从编译器的 float
类型转换为IEEE-754。当然,这可能会发生……除非没有办法获得 32 位值。
有 9 位字节的系统。或 18 位字节。这些系统有 C++ 编译器。这样的系统不能声明只有 32 位大小的类型。
但是能够传递 32 位值(更不用说 16 位和 8 位)是 OpenGL 的一个硬性要求。没有它,您将无法在缓冲区对象中传递任何数据。然而,C++ 不需要它。
说到顶点数据,半现代 OpenGL 中最基本的功能之一是 glVertexAttribPointer
。它依赖于您将字节偏移量转换为 void*
,然后它会转换回来。
C++ 不保证这有效。 C++ 标准中没有任何地方要求如果你将一个整数转换为一个指针,然后将该指针转换回一个整数,你将得到相同的整数(它确实说 ptr->int->ptr 有效,但是这并不意味着相反)。
然而 OpenGL 需要它。除非您使用单独的属性缓冲区(和 I strongly suggest you do if it's available ),否则您的代码和您调用的 OpenGL 代码都依赖于这种未定义的行为。
OpenGL 将 GLint
定义为带符号的 32 位补码。但是 C++ 不要求任何整数类型是二进制补码。
但是 OpenGL 可以。
OpenGL 无法在类型大小不正常的系统上运行。它不能在具有 9 位字节的系统上运行。它不能在使用一个补码进行有符号整数数学运算的系统上运行。我可以继续这样做,但我认为我的观点很明确。
通过选择完全使用 OpenGL(如果您想知道,也可以选择 Vulkan),您已经依赖于实现定义的行为。那么,当您已经依赖大量其他实现定义的行为时,为什么还要让您的生活更加困难来避免这种特定的实现定义行为呢?
马出了谷仓;现在关门无济于事。
关于c++ - 如何制作可移植且与编译器无关的 glBufferData?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38429628/
我想在一个页面上做一个按钮,可以在同一页面调用一个JS函数。该函数将需要创建(打开)新窗口,其 HTML 代码由 JS 函数本身提供。我该怎么做? 这样做的目的是从特定页面生成一个打印友好的页面。 请
我一直在用 php 开发这个项目。该项目的一半是使用 mysql_query 完成的,最新的模块是使用 mysqli 制作的。有很多模块,我不想更改代码。如果是这样的话会不会产生问题。或者我应该将其全
我安装了好几次 qt creator,但它从来没有像我现在的 PC 那样花钱;首先,我使用我的 Pendrive(Qt 5.8 的)上一直有的安装程序,告诉我我无法下载一些存储库,我下载了相同安装程序
我安装了 Qt Creator 5.10.1,当我构建项目时出现错误:“无法确定要运行哪个”make“命令。检查构建配置中的”make“步骤。”。 我已经在另一台 PC 上安装了 Qt,我看到了这个问
看看这个 makefile,它有某种原始的进度指示(可能是一个进度条)。 请给我建议/意见! # BUILD 最初是未定义的 ifndef 构建 # max 等于 256 个 x 十六:= x x x
这个问题会有点长,对此我很抱歉:) 我花了几天时间寻找最好的解决方案,以在 asp mvc 和 JQuery 中制作图像库。 主要问题是当用户点击拇指时显示图像。 我想让整个浏览器 View 变成黑色
我是Python方面的 super 高手。我一直在努力寻找适当的解决方案。这是列表,L = [0, 0, 0, 3, 4, 5, 6, 0, 0, 0, 0, 11, 12, 13, 14, 0, 0
让我们考虑两个简化的 CMakeLists.txt set(GTEST "/usr/local/lib/libgtest.a") set(GMOCK "/usr/local/lib/libgmock.
我如何制作 Makefile,因为这是按源代码分发程序的最佳方式。请记住,这是针对 C++ 程序的,而我是从 C 开发领域开始的。但是可以为我的 Python 程序制作 Makefile 吗? 最佳答
由于 Ord 是 Eq 的子类,我发现很难理解创建该类的新类型实例的样子。 我已经设法做到了: newtype NT1 = NT1 Integer instance Eq NT1 wh
在 PowerShell 中,我想编写一个函数,它接受不同的选项作为参数。没关系,如果它接收多个参数,但它必须接收至少一个参数。我想通过参数定义而不是之后的代码来强制执行它。我可以使用以下代码让它工作
我正在通过构建包使用 enable-ssl 在 heroku (ubuntu) 上安装 ffmpeg。我能够一直构建到这些错误: install: cannot create regular file
我是 FFmpeg 的新手,但作为一个学习一些 mysql 数据库的项目,我正在尝试创建一个视频上传网站。 当我尝试使用此代码制作缩略图时: shell_exec("/usr/local/bin/ff
我想要一个绘制可绘制对象的 Actor ,但将其剪辑为 Actor 的大小。我从 Widget 派生这个类,并使用一些硬编码的值作为一个简单的测试: public class MyWidget ext
我一直在查看 Faxien+Sinan 和 Rebar,Erlang OTP 的基本理念似乎是,在单个 Erlang 镜像实例上安装应用程序和版本。保持发布自包含的最佳实践是什么?有没有办法打包发布,
我正在尝试克隆存储库,但它应该是彼此独立的副本。这背后有什么魔法吗,或者只是使用 svn 客户端并克隆它? 谢谢 最佳答案 试试 svnadmin hotcopy .您可以在 repo mainten
我想做一个这样的菜单: Item 1 Item 2 Item 3 Subitem 1 Subitem 2 但我得到了这个:
为 Yii 创建扩展的最佳方式是什么? 这是我到目前为止所做的 我希望它可以通过 composer 安装,所以我为它创建了一个 github repo。 我在文件夹 vendor/githubname
我尝试制作一个ActionListener,但它给了我一个错误。我导入了事件,但它仍然不起作用。这是我的代码: send.addActionListener(new jj); private clas
我需要能够将 div 内的 HTML 代码恢复为页面就绪状态。我需要这个,因为我想在页面准备好后对 HTML 代码进行一些更改,然后在需要时将其恢复到页面准备好时的状态.. 我想使用克隆,但是如何只复
我是一名优秀的程序员,十分优秀!