更新问题:
在先前的问题描述中,我犯了几个严重的错误,这使问题很难理解和解决。现在,我将分享我的最新代码。
右面顺时针旋转90度,顶面顺时针旋转180度。
因此,当设置由两个三角形(3-7-8和8-4-3)组成的右面的纹理坐标时,我们需要将面逆时针旋转90度,因此3使用7的坐标,即7-> 8,8-> 4,4->3。当设置由两个三角形(1-4-8和8-6-1)组成的顶面的纹理坐标时,我们需要将脸部逆时针旋转90度,因此1将使用8的坐标,即4-> 6,8-> 1,6-> 4。
有效的代码:
const splitCamelCase = str => str.match(/^[A-Z]?[^A-Z]*|[A-Z][^A-Z]*/g).join(' ');
console.log(splitCamelCase('fooMyCamelCaseString'));
console.log(splitCamelCase('MyCamelCaseString'));
console.log(splitCamelCase('XYZMyCamelCaseString'));
console.log(splitCamelCase('alllowercase'));
-------------------------------------------------- -原始问题------------------------------------------------- -
我有一个360度视频,它是cubemap3x2格式的,我想在OpenGL中使用cubemap纹理进行渲染。但是,立方体的背面和顶面沿不同的方向旋转。背面顺时针旋转90度,顶面顺时针旋转180度。现在我可以通过内存复制正确地渲染立方体贴图,但是我想知道是否有一种方法可以通过使用OpenGL的内置功能来避免这种情况?
我需要渲染的框架:
顶点着色器:
bool setupCoordinates() {
this->vertexCount = 36;
float skyboxVertices[] = {
// positions
// back
-1.0f, 1.0f, -1.0f,
-1.0f, -1.0f, -1.0f,
1.0f, -1.0f, -1.0f,
1.0f, -1.0f, -1.0f,
1.0f, 1.0f, -1.0f,
-1.0f, 1.0f, -1.0f,
// Left
-1.0f, -1.0f, 1.0f,
-1.0f, -1.0f, -1.0f,
-1.0f, 1.0f, -1.0f,
-1.0f, 1.0f, -1.0f,
-1.0f, 1.0f, 1.0f,
-1.0f, -1.0f, 1.0f,
// Right
1.0f, -1.0f, -1.0f,
1.0f, -1.0f, 1.0f,
1.0f, 1.0f, 1.0f,
1.0f, 1.0f, 1.0f,
1.0f, 1.0f, -1.0f,
1.0f, -1.0f, -1.0f,
// Front
-1.0f, -1.0f, 1.0f,
-1.0f, 1.0f, 1.0f,
1.0f, 1.0f, 1.0f,
1.0f, 1.0f, 1.0f,
1.0f, -1.0f, 1.0f,
-1.0f, -1.0f, 1.0f,
// Top
-1.0f, 1.0f, -1.0f,
1.0f, 1.0f, -1.0f,
1.0f, 1.0f, 1.0f,
1.0f, 1.0f, 1.0f,
-1.0f, 1.0f, 1.0f,
-1.0f, 1.0f, -1.0f,
// Bottom
-1.0f, -1.0f, -1.0f,
-1.0f, -1.0f, 1.0f,
1.0f, -1.0f, -1.0f,
1.0f, -1.0f, -1.0f,
-1.0f, -1.0f, 1.0f,
1.0f, -1.0f, 1.0f
};
float skyboxTextures[] = {
// positions
// Back same as skyboxVertices
-1.0f, 1.0f, -1.0f,
-1.0f, -1.0f, -1.0f,
1.0f, -1.0f, -1.0f,
1.0f, -1.0f, -1.0f,
1.0f, 1.0f, -1.0f,
-1.0f, 1.0f, -1.0f,
// Left same as skyboxVertices
-1.0f, -1.0f, 1.0f,
-1.0f, -1.0f, -1.0f,
-1.0f, 1.0f, -1.0f,
-1.0f, 1.0f, -1.0f,
-1.0f, 1.0f, 1.0f,
-1.0f, -1.0f, 1.0f,
// Right rotate in 90 ccw
1.0f, -1.0f, 1.0f,
1.0f, 1.0f, 1.0f,
1.0f, 1.0f, -1.0f,
1.0f, 1.0f, -1.0f,
1.0f, -1.0f, -1.0f,
1.0f, -1.0f, 1.0f,
// Front same as skyboxVertices
-1.0f, -1.0f, 1.0f,
-1.0f, 1.0f, 1.0f,
1.0f, 1.0f, 1.0f,
1.0f, 1.0f, 1.0f,
1.0f, -1.0f, 1.0f,
-1.0f, -1.0f, 1.0f,
// Top rotate in 180 ccw
1.0f, 1.0f, 1.0f,
-1.0f, 1.0f, 1.0f,
-1.0f, 1.0f, -1.0f,
-1.0f, 1.0f, -1.0f,
1.0f, 1.0f, -1.0f,
1.0f, 1.0f, 1.0f,
// Bottom same as skyboxVertices
-1.0f, -1.0f, -1.0f,
-1.0f, -1.0f, 1.0f,
1.0f, -1.0f, -1.0f,
1.0f, -1.0f, -1.0f,
-1.0f, -1.0f, 1.0f,
1.0f, -1.0f, 1.0f
};
glGenVertexArrays(1, &sceneVAO);
glBindVertexArray(sceneVAO);
glGenBuffers(1, &sceneVertexBuffer);
glBindBuffer(GL_ARRAY_BUFFER, sceneVertexBuffer);
glBufferData(GL_ARRAY_BUFFER, sizeof(skyboxVertices), &skyboxVertices, GL_STATIC_DRAW);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), (void*)0);
glGenBuffers(1, &sceneUVBuffer);
glBindBuffer(GL_ARRAY_BUFFER, sceneUVBuffer);
glBufferData(GL_ARRAY_BUFFER, sizeof(skyboxTextures), &skyboxTextures, GL_STATIC_DRAW);
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), (void *)0);
glBindVertexArray(0);
return true;
}
void drawFrame() {
glBindTexture(GL_TEXTURE_CUBE_MAP, sceneTextureID);
glPixelStorei(GL_UNPACK_ROW_LENGTH, videoFrameWidth);
int width = videoFrameWidth / 3;
int height = width;
// back
glPixelStorei(GL_UNPACK_SKIP_ROWS, 0);
glPixelStorei(GL_UNPACK_SKIP_PIXELS, 0);
glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_Z, 0, GL_RGB, width, width, 0, GL_RGB, GL_UNSIGNED_BYTE, textureData);
// left
glPixelStorei(GL_UNPACK_SKIP_ROWS, 0);
glPixelStorei(GL_UNPACK_SKIP_PIXELS, width);
glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_X, 0, GL_RGB, width, width, 0, GL_RGB, GL_UNSIGNED_BYTE, textureData);
// front
glPixelStorei(GL_UNPACK_SKIP_ROWS, 0);
glPixelStorei(GL_UNPACK_SKIP_PIXELS, width * 2);
glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_Z, 0, GL_RGB, width, width, 0, GL_RGB, GL_UNSIGNED_BYTE, textureData);
// bottom
glPixelStorei(GL_UNPACK_SKIP_ROWS, width);
glPixelStorei(GL_UNPACK_SKIP_PIXELS, 0);
glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_Y, 0, GL_RGB, width, width, 0, GL_RGB, GL_UNSIGNED_BYTE, textureData);
// right
glPixelStorei(GL_UNPACK_SKIP_ROWS, width);
glPixelStorei(GL_UNPACK_SKIP_PIXELS, width);
glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X, 0, GL_RGB,width,width,0,GL_RGB,GL_UNSIGNED_BYTE, textureData);
// top
glPixelStorei(GL_UNPACK_SKIP_ROWS, width);
glPixelStorei(GL_UNPACK_SKIP_PIXELS, width * 2);
glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_Y, 0, GL_RGB, width, width, 0, GL_RGB, GL_UNSIGNED_BYTE, textureData);
}
片段着色器:
#version 410 core
uniform mat4 matrix;
out vec3 TexCoords;
layout(location = 0) in vec4 position;
layout(location = 1) in vec3 textureIn;
void main() {
TexCoords = textureIn;
gl_Position = matrix * position;
}
我用来渲染的代码:
#version 410 core
varying vec3 TexCoords;
uniform samplerCube mytexture;
void main() {
gl_FragColor = texture(mytexture, TexCoords);
}
我用来构建立方体贴图的坐标:
答案 0 :(得分:1)
您可以通过glTexImage2D
直接指定立方体贴图的边:
glPixelStorei(GL_UNPACK_ROW_LENGTH, frameWidth);
// Render left face
[...]
// Render front face
[...]
// Render right face
[...]
// Render bottom face
[...]
// Render back face
glPixelStorei(GL_UNPACK_SKIP_ROWS, width);
glPixelStorei(GL_UNPACK_SKIP_PIXELS, width);
glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X, 0, GL_RGB, width, width, 0, GL_RGB, GL_UNSIGNED_BYTE, textureData);
// Render top face
glPixelStorei(GL_UNPACK_SKIP_ROWS, width);
glPixelStorei(GL_UNPACK_SKIP_PIXELS, width*2);
glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_Y, 0, GL_RGB, width, width, 0, GL_RGB, GL_UNSIGNED_BYTE, textureData);
但是您必须更改右侧和顶部的纹理坐标。请注意,您弄乱了多维数据集贴图侧面到多维数据集侧面的映射,但是无论如何仍然有效:
float skyboxTextures[] = {
// positions
// Back
// [...]
// Left
// [...]
// Right
1.0f, -1.0f, 1.0f,
1.0f, 1.0f, 1.0f,
1.0f, 1.0f, -1.0f,
1.0f, 1.0f, -1.0f,
1.0f, -1.0f, -1.0f,
1.0f, -1.0f, 1.0f,
// Front
// [...]
// Top
1.0f, 1.0f, 1.0f,
-1.0f, 1.0f, 1.0f,
-1.0f, 1.0f, -1.0f,
-1.0f, 1.0f, -1.0f,
1.0f, 1.0f, -1.0f,
1.0f, 1.0f, 1.0f,
// Bottom
// [...]
};
查看结果:
由于侧面的映射似乎被弄乱了,所以我宁愿像这样加载侧面:
glPixelStorei(GL_UNPACK_ROW_LENGTH, frameWidth);
// Render back face
glPixelStorei(GL_UNPACK_SKIP_ROWS, width);
glPixelStorei(GL_UNPACK_SKIP_PIXELS, width);
glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_Z, 0, GL_RGB, width, width, 0, GL_RGB, GL_UNSIGNED_BYTE, textureData);
// Render left face
glPixelStorei(GL_UNPACK_SKIP_ROWS, 0);
glPixelStorei(GL_UNPACK_SKIP_PIXELS, 0);
glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_X, 0, GL_RGB, width, width, 0, GL_RGB, GL_UNSIGNED_BYTE, textureData);
// Render right face
glPixelStorei(GL_UNPACK_SKIP_ROWS, 0);
glPixelStorei(GL_UNPACK_SKIP_PIXELS, width * 2);
glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X, 0, GL_RGB, width, width, 0, GL_RGB, GL_UNSIGNED_BYTE, textureData);
// Render front face
glPixelStorei(GL_UNPACK_SKIP_ROWS, 0);
glPixelStorei(GL_UNPACK_SKIP_PIXELS, width);
glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_Z, 0, GL_RGB, width, width, 0, GL_RGB, GL_UNSIGNED_BYTE, textureData);
// Render top face
glPixelStorei(GL_UNPACK_SKIP_ROWS, width);
glPixelStorei(GL_UNPACK_SKIP_PIXELS, width*2);
glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_Y, 0, GL_RGB, width, width, 0, GL_RGB, GL_UNSIGNED_BYTE, textureData);
// Render bottom face
glPixelStorei(GL_UNPACK_SKIP_ROWS, width);
glPixelStorei(GL_UNPACK_SKIP_PIXELS, 0);
glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_Y, 0, GL_RGB, width, width, 0, GL_RGB, GL_UNSIGNED_BYTE, textureData);
,并使用以下纹理坐标:
float skyboxTextures[] = {
// positions
// Back
-1.0f, -1.0f, -1.0f,
1.0f, -1.0f, -1.0f,
1.0f, 1.0f, -1.0f,
1.0f, 1.0f, -1.0f,
-1.0f, 1.0f, -1.0f,
-1.0f, -1.0f, -1.0f,
// Left
-1.0f, -1.0f, 1.0f,
-1.0f, -1.0f, -1.0f,
-1.0f, 1.0f, -1.0f,
-1.0f, 1.0f, -1.0f,
-1.0f, 1.0f, 1.0f,
-1.0f, -1.0f, 1.0f,
// Right
1.0f, -1.0f, -1.0f,
1.0f, -1.0f, 1.0f,
1.0f, 1.0f, 1.0f,
1.0f, 1.0f, 1.0f,
1.0f, 1.0f, -1.0f,
1.0f, -1.0f, -1.0f,
// Front
-1.0f, -1.0f, 1.0f,
-1.0f, 1.0f, 1.0f,
1.0f, 1.0f, 1.0f,
1.0f, 1.0f, 1.0f,
1.0f, -1.0f, 1.0f,
-1.0f, -1.0f, 1.0f,
// Top
-1.0f, 1.0f, 1.0f,
-1.0f, 1.0f, -1.0f,
1.0f, 1.0f, -1.0f,
1.0f, 1.0f, -1.0f,
1.0f, 1.0f, 1.0f,
-1.0f, 1.0f, 1.0f,
// Bottom
1.0f, -1.0f, -1.0f,
-1.0f, -1.0f, -1.0f,
1.0f, -1.0f, 1.0f,
1.0f, -1.0f, 1.0f,
-1.0f, -1.0f, -1.0f,
-1.0f, -1.0f, 1.0f
};
但是请注意,y和z轴仍被交换。我认为这是因为场景中的世界空间矢量是(0,1,0)。