Проблемы OpenGL 4.0 Cubemap

Читал «Кулинарную книгу по языку шейдеров OpenGL 4.0». Но я наткнулся на стену с руководством по кубической карте.

Проблема в том, что модель, которую я рисую, выглядит абсолютно серой. Как будто он не получает никаких данных из текстуры samplerCube.

Весь мой код кажется правильным. Я смотрел на другие учебники, и это то же самое.
Не знаю, отвечает ли мой Intel HD Graphics 4000, но я убедился, что у меня есть расширение GL_ARB_texture_cube_map.

Я использую библиотеку DevIL для загрузки изображений из файла, что, кажется, прекрасно, но из того, что я могу сказать, что-то идет не так при передаче данных в OpenGL.

Я выкладываю загрузку, где я получаю данные из файлов. Все файлы также загружаются правильно.
Я также публикую код рисования, в котором привязываю текстуру к конвейеру.
И я также публикую свой вершинный и фрагментный шейдеры на всякий случай, но, похоже, они работают так, как должны.

Есть идеи?

Код загрузки

uint TARGETS[6] =
{
GL_TEXTURE_CUBE_MAP_POSITIVE_X,
GL_TEXTURE_CUBE_MAP_NEGATIVE_Y,
GL_TEXTURE_CUBE_MAP_POSITIVE_Y,
GL_TEXTURE_CUBE_MAP_NEGATIVE_Y,
GL_TEXTURE_CUBE_MAP_POSITIVE_Z,
GL_TEXTURE_CUBE_MAP_NEGATIVE_Z
};
string EXTS[6] =
{
"posx",
"negx",
"posy",
"negy",
"posz",
"negz"};

// Create & bind cubemap texture
glGenTextures( 1, &cubemap );
glBindTexture( GL_TEXTURE_CUBE_MAP, cubemap );

for( int i = 0; i < 6; i++ )
{
string file = "textures/cubemap_" + EXTS[i] + ".png";
uint image = ilGenImage();

// Load with DevIL
ilBindImage( image );
if( !ilLoadImage( file.c_str() ) )
{
cout << "ERROR: Failed to load image " << endl;
return false;
}

// Fetch info from DevIL
int width   = ilGetInteger( IL_IMAGE_WIDTH );
int height  = ilGetInteger( IL_IMAGE_HEIGHT );
uint format = ilGetInteger( IL_IMAGE_FORMAT );
uint type   = ilGetInteger( IL_IMAGE_TYPE );

// Send data to OpenGL
glTexImage2D(
TARGETS[i],
0,
GL_RGBA,
width,
height,
0,
format,
type,
ilGetData() );

// Error check
if( !ErrorCheck("Failed to bind a side of the cubemap!") )
return false;

// Get rid of DevIL data
ilDeleteImage( image );
}

// Parameters
glTexParameterf( GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
glTexParameterf( GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_LINEAR );
glTexParameterf( GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE );
glTexParameterf( GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE );
glTexParameterf( GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE );

Рисовать код

    // Update
glfwPollEvents();
UpdateTime();

// Clear back buffer for new frame
glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );// Bind shader
shader->Bind();

// Cubemap
shader->SetUniform( "cubemapTexture", 0 );
glActiveTexture( GL_TEXTURE0 );
glBindTexture( GL_TEXTURE_CUBE_MAP, cubemap );

// Bind model
if( model->Bind() )
{
static float angle = 0;
angle += 25.0f * deltaTime;

// Matrices
mat4 world =
translate( vec3( 0.0f, 0.0f, 0.0f) ) *
rotateZ( angle * PI / 180 ) *
rotateX( angle * PI / 180 ) *
scale( vec3( 1.0f, 1.0f, 1.0f) );
mat4 view = ViewMatrix(
cameraPosition,
cameraTarget,
vec3( 0.0f,  0.0f,  1.0f) );
mat4 proj = ProjectionMatrix(
fov,
(float)windowX,
(float)windowY,
nearPlane,
farPlane );

// Uniforms
shader->SetUniform( "uWorld", world );
shader->SetUniform( "uView", view );
shader->SetUniform( "uProj", proj );

shader->SetUniform( "materialColor", vec3( 0.5f, 0.5f, 0.5f ) );

shader->SetUniform( "drawSkybox", false );
shader->SetUniform( "world_cameraPosition", cameraPosition );
shader->SetUniform( "reflectFactor", 0.5f );

// Draw
glDrawElements( GL_TRIANGLES, model->GetIndexCount(), GL_UNSIGNED_SHORT, NULL );
}

// Put the new image on the screen
glfwSwapBuffers( window );

Вершинный шейдер

#version 400

layout(location=0) in vec3 vertex_position;
layout(location=1) in vec3 vertex_normal;
layout(location=2) in vec4 vertex_tangent;
layout(location=3) in vec2 vertex_texCoords;

out vec2 texCoords;
out vec3 reflectDir;

uniform mat4 uWorld;
uniform mat4 uView;
uniform mat4 uProj;

uniform bool drawSkybox;
uniform vec3 world_cameraPosition;

void main()
{
if( drawSkybox )
{
reflectDir = vertex_position;
}
else
{
vec3 world_pos = vec3( uWorld * vec4(vertex_position,1.0) );
vec3 world_norm = vec3( uWorld * vec4(vertex_normal,0.0) );
vec3 world_view = normalize( world_cameraPosition - world_pos );

reflectDir = reflect( -world_view, world_norm );
}

gl_Position = uProj * uView * uWorld * vec4(vertex_position,1.0);
texCoords = vertex_texCoords;
}

Фрагмент шейдера

#version 400

out vec4 fragColor;

in vec2 texCoords;
in vec3 reflectDir;

uniform samplerCube cubemapTexture;

uniform vec3 materialColor;
uniform bool drawSkybox;
uniform float reflectFactor;

void main()
{
vec3 color = texture( cubemapTexture, reflectDir ).rgb;

if( drawSkybox )
{
fragColor = vec4( color, 1.0 );
}
else
{
fragColor = vec4( mix( materialColor, color, reflectFactor ), 1.0 );
}
}

-1

Решение

Текстура вашей карты куба не завершена. Для завершения текстуры кубической карты необходимо указать все 6 сторон. Из спецификации:

Кроме того, текстура карты куба завершена, если выполняются следующие условия: [..] Массивы level_base каждого из шести текстурных изображений, составляющих карту куба, имеют идентичные, положительные и квадратные измерения.

Ваш код не указывает изображение для NEGATIVE_X:

uint TARGETS[6] =
{
GL_TEXTURE_CUBE_MAP_POSITIVE_X,
GL_TEXTURE_CUBE_MAP_NEGATIVE_Y,
GL_TEXTURE_CUBE_MAP_POSITIVE_Y,
GL_TEXTURE_CUBE_MAP_NEGATIVE_Y,
GL_TEXTURE_CUBE_MAP_POSITIVE_Z,
GL_TEXTURE_CUBE_MAP_NEGATIVE_Z
};

Используя эту таблицу, изображение для NEGATIVE_Y указан дважды, но отсутствует NEGATIVE_X, Так должно быть:

uint TARGETS[6] =
{
GL_TEXTURE_CUBE_MAP_POSITIVE_X,
GL_TEXTURE_CUBE_MAP_NEGATIVE_X,
GL_TEXTURE_CUBE_MAP_POSITIVE_Y,
GL_TEXTURE_CUBE_MAP_NEGATIVE_Y,
GL_TEXTURE_CUBE_MAP_POSITIVE_Z,
GL_TEXTURE_CUBE_MAP_NEGATIVE_Z
};

Вместо того, чтобы перечислять 6 целей, вы также можете использовать GL_TEXTURE_CUBE_MAP_POSITIVE_X + i за i в диапазоне 0..5 для решения 6 задач.

2

Другие решения


По вопросам рекламы ammmcru@yandex.ru
Adblock
detector