Как я могу получить входные данные для вершинного шейдера типа uint_fast64_t? в языке нет такого типа, как я могу передать его по-другому?
Мой код таков:
#version 330 core
#define CHUNK_SIZE 16
#define BLOCK_SIZE_X 0.1
#define BLOCK_SIZE_Y 0.1
#define BLOCK_SIZE_Z 0.1
// input vertex and UV coordinates, different for all executions of this shader
layout(location = 0) in uint_fast64_t vertexPosition_modelspace;
layout(location = 1) in vec2 vertexUV;
// Output data ; will be interpolated for each fragment.
out vec2 UV;
// model view projection matrix
uniform mat4 MVP;
int getAxis(uint_fast64_t p, int choice) { // axis: 0=x 1=y 2=z 3=index_x 4=index_z
switch (choice) {
case 0:
return (int)((p>>59 ) & 0xF); //extract the x axis int but i only want 4bits
case 1:
return (int)((p>>23 ) & 0xFF);//extract the y axis int but i only want 8bits
case 2:
return (int)((p>>55 ) & 0xF);//extract the z axis int but i only want 4bits
case 3:
return (int)(p & 0x807FFFFF);//extract the index_x 24bits
case 4:
return (int)((p>>32) & 0x807FFFFF);//extract the index_z 24bits
}
}
void main()
{
// assign vertex position
float x = (getAxis(vertexPosition_modelspace,0) + getAxis(vertexPosition_modelspace,3)*CHUNK_SIZE)*BLOCK_SIZE_X;
float y = getAxis(vertexPosition_modelspace,1)*BLOCK_SIZE_Y;
float z = (getAxis(vertexPosition_modelspace,2) + getAxis(vertexPosition_modelspace,3)*CHUNK_SIZE)*BLOCK_SIZE_Z;
gl_Position = MVP * vec4(x,y,z, 1.0);
// UV of the vertex. No special space for this one.
UV = vertexUV;
}
Сообщение об ошибке, которое я принимаю:
Пробовал ставить uint64_t но та же проблема
Вы пробовали заменить uint_fast64_t на ivec2 или ivec4?
Кстати, вам действительно не следует использовать uint_fast64_t. Просто используйте uint64_t, как и все остальные. Количество реализаций, которые на самом деле используют другой тип для них, практически отсутствует.
Unextended GLSL для OpenGL не имеет возможности напрямую использовать 64-битные целочисленные значения. И даже довольно широко поддерживаемое расширение ARB , которое позволяет использовать 64-битные целые числа в шейдерах, на самом деле не позволяет использовать их в качестве атрибутов вершинного шейдера. Для этого требуется расширение NVIDIA, поддерживаемое только... NVIDIA.
Однако вы можете отправлять 32-битные целые числа, а 64-битное целое число — это всего лишь два 32-битных целых числа. Вы можете поместить 64-битные целые числа в буфер и передать их как 2 32-битных целых числа без знака в формате атрибута вашей вершины:
glVertexAttribIFormat(0, 2, GL_UNSIGNED_INT, <byte_offset>);
Ваш шейдер получит их в качестве ввода uvec2:
layout(location = 0) in uvec2 vertexPosition_modelspace;
Компонент x вектора будет иметь первые 4 байта, а компонент y будет хранить вторые 4 байта. Но поскольку «первый» и «второй» определяются порядком байтов вашего ЦП, вам нужно знать, является ли ваш ЦП прямым порядком байтов или обратным порядком байтов, чтобы иметь возможность их использовать. Поскольку большинство настольных реализаций GL работают в паре с процессорами с прямым порядком байтов, мы предполагаем, что это так.
В этом случае vertexPosition_modelspace.x содержит младшие 4 байта 64-битного целого числа, а vertexPosition_modelspace.y содержит старшие 4 байта.
Таким образом, ваш код можно настроить следующим образом (с некоторой очисткой):
const vec3 BLOCK_SIZE(0.1, 0.1, 0.1);
//Get the three axes all at once.
uvec3 getAxes(in uvec2 p)
{
return uvec3(
(p.y >> 27) & 0xF),
(p.x >> 23) & 0xFF),
(p.y >> 23) & 0xF)
);
}
//Get the indices
uvec2 getIndices(in uvec2 p)
{
return p & 0x807FFFFF; //Performs component-wise bitwise &
}
void main()
{
uvec3 iPos = getAxes(vertexPosition_modelspace);
uvec2 indices = getIndices(vertexPosition_modelspace);
vec3 pos = vec3(
iPos.x + (indices.x * CHUNK_SIZE),
iPos.y,
iPos.z + (indices.x * CHUNK_SIZE) //You used index 3 in your code, so I used .x here, but I think you meant index 4.
);
pos *= BLOCK_SIZE;
...
}
Uvec2 по умолчанию имеет плоскую заливку?
@ user253751: Это не по теме, поскольку квалификаторы интерполяции не применяются к входным переменным вершинного шейдера. Но целые (и двойные) типы по умолчанию не имеют значения flat. Но они также не могут использовать ничего, кроме flat. Поэтому, если вы не укажете на них flat явно, вы получите ошибку компиляции.
Glsl без расширений не имеет 64-битных целочисленных типов.