PDA

View Full Version : Skybox texture error



Jippie
01-20-2018, 12:06 AM
Dear community,

Currently in my adventure into the OpenGL world I've come across skyboxes. As interesting as they are, I can't seem to get them to work! In the following piece of code I load in a skybox (C#):

public Cubemap(string folder, string extension)
{
cubemapID = GL.GenTexture();
GL.BindTexture(TextureTarget.TextureCubeMap, cubemapID);

// the actual paths to the files we're looking for.
string[] files = new string[]
{
folder + "/right" + extension,
folder + "/left" + extension,
folder + "/top" + extension,
folder + "/bottom" + extension,
folder + "/back" + extension,
folder + "/front" + extension,
};

// the targets that fit the paths.
TextureTarget[] targets = new TextureTarget[]
{
TextureTarget.TextureCubeMapPositiveX,
TextureTarget.TextureCubeMapNegativeX,
TextureTarget.TextureCubeMapPositiveY,
TextureTarget.TextureCubeMapNegativeY,
TextureTarget.TextureCubeMapPositiveZ,
TextureTarget.TextureCubeMapNegativeZ
};

// load in all files individually.
for(int j = 0; j < 6; j++)
{
string file = files[j];
Bitmap b = new Bitmap(file);

// copy image into our byte array (from http://neokabuto.blogspot.nl/2014/04/opentk-tutorial-6-part-2-loading.html)
BitmapData data = b.LockBits(new System.Drawing.Rectangle(0, 0, b.Width, b.Height),
ImageLockMode.ReadOnly, System.Drawing.Imaging.PixelFormat.Format32bppArgb );

// fill in the buffer and generate mipmaps.
GL.TexImage2D(targets[j], 0, PixelInternalFormat.Rgb, data.Width, data.Height, 0, OpenTK.Graphics.OpenGL4.PixelFormat.Rgb, PixelType.UnsignedByte, data.Scan0);
}

// set texture parameters for the cubemap.
GL.TexParameter(TextureTarget.TextureCubeMap, TextureParameterName.TextureMinFilter, (int)TextureMinFilter.Linear);
GL.TexParameter(TextureTarget.TextureCubeMap, TextureParameterName.TextureMagFilter, (int)TextureMagFilter.Linear);
GL.TexParameter(TextureTarget.TextureCubeMap, TextureParameterName.TextureWrapS, (int)TextureWrapMode.ClampToEdge);
GL.TexParameter(TextureTarget.TextureCubeMap, TextureParameterName.TextureWrapT, (int)TextureWrapMode.ClampToEdge);
GL.TexParameter(TextureTarget.TextureCubeMap, TextureParameterName.TextureWrapR, (int)TextureWrapMode.ClampToEdge);
GL.GenerateMipmap(GenerateMipmapTarget.TextureCube Map);

// unbind our cubemap so that we do not accidentally change it somewhere else.
GL.BindTexture(TextureTarget.TextureCubeMap, 0);
}

And I have the following two vertex / fragment shaders:


#version 330 core

// vertex data we receive.
layout(location = 0) in vec3 position;
layout(location = 1) in vec3 normal;
layout(location = 2) in vec2 coords;

// data we send to the fragment shader.
out vec3 fragPosition;

// global data set by the host.
uniform mat4 local;
uniform mat4 view;
uniform mat4 projection;

void main()
{
fragPosition = position;

// we use swizzling to ensure that the z component is always 1.0 - this allows optimisations for the GPU.
gl_Position = projection * view * local * vec4(position, 1.0);
}


#version 330 core

// data we receive from the vertex shader.
in vec3 fragPosition;

// the cubemap from that we receive from the host.
uniform samplerCube skybox;

// our output for the rest of the pipeline.
out vec4 pixel;

void main() {

// vec4(fragPosition, 1.0);
// we use the fragment position as a direction. Take note that it does not need to be normalized.
pixel = texture(skybox, fragPosition);
}

However, the following is the result:
2602
A close up of the result:
2603

The imagery is loaded in properly, when view as a bitmap through the standard Windows Forms I get back the original image.

I've tried looking around on the internet, but there are very scarce examples of C# in combination with OpenGL. when I compared my solution to C or C++ solutions, I did not notice any major differences in what's happening.

Could anyone see where things go odd? Or perhaps point me in the right direction?

I hope to hear from you,

Best regards,

Jip

GClements
01-20-2018, 12:43 AM
BitmapData data = b.LockBits(new System.Drawing.Rectangle(0, 0, b.Width, b.Height),
ImageLockMode.ReadOnly, System.Drawing.Imaging.PixelFormat.Format32bppArgb );

// fill in the buffer and generate mipmaps.
GL.TexImage2D(targets[j], 0, PixelInternalFormat.Rgb, data.Width, data.Height, 0, OpenTK.Graphics.OpenGL4.PixelFormat.Rgb, PixelType.UnsignedByte, data.Scan0);


It looks like you're requesting BGRA data then telling OpenGL that it's RGB. That would cause the R/G/B colour bands which appear in your image.

Note that you need to use GL_BGRA for Format32bppArgb. OpenGL formats are named based upon the order of bytes in memory, so GL_BGRA is "BB GG RR AA". On a little-endian architecture (e.g. x86), this corresponds to 0xAARRGGBB when read as a 32-bit word, which is equivalent to Format32bppArgb (the .NET pixel formats are named based upon the order of bits within a word, with the most-significant bits first).

Also, if you want to use 24-bpp RGB data and the image width isn't guaranteed to be a multiple of 4, you need to use glPixelStorei(GL_UNPACK_ALIGNMENT,1).

Jippie
01-21-2018, 03:23 AM
Ah, thanks!
You were right, that was indeed the error.

Perhaps you can lend me a hand with the following too:
2607

All faces are correct, but the bottom one. The directions do appear correct (when choosing the coordinates as final 'colors'). Would you happen to know what is going on there?

Best regards,

Jip