Felix K.
Felix K.

Reputation: 6281

OpenGL ES 2.0 / MonoTouch: Texture is colorized red

I'm currently loading a cube-map into my application but it's shown in a red tone. Edit: The channel problem is also present when using 2D-Textures, it seems the channels are not in the correct order. Is there any way to change the order of the channels using the iOS methods?

That's the code for texture loading:

public TextureCube (Generic3DView device, UIImage right, UIImage left, UIImage top, UIImage bottom, UIImage front, UIImage back)
    : base(device)
{
    _Device = device;
    GL.GenTextures (1, ref _Handle);
    GL.BindTexture (TextureType, _Handle);
    LoadTexture(All.TextureCubeMapPositiveX, right);
    LoadTexture(All.TextureCubeMapNegativeX, left);
    LoadTexture(All.TextureCubeMapPositiveY, top);
    LoadTexture(All.TextureCubeMapNegativeY, bottom);   
    LoadTexture(All.TextureCubeMapPositiveZ, front);
    LoadTexture(All.TextureCubeMapNegativeZ, back);
        
    GL.TexParameter(All.TextureCubeMap, All.TextureMinFilter, (Int32)All.LinearMipmapLinear);
    GL.TexParameter(All.TextureCubeMap, All.TextureMagFilter, (Int32)All.Linear);
    GL.GenerateMipmap(All.TextureCubeMap);
}
            
private void LoadTexture(All usage, UIImage image) 
{
    GL.TexImage2D(usage, 0, (Int32)All.Rgba, (Int32)image.Size.Width,
                  (Int32)image.Size.Height, 0, All.Rgba, All.UnsignedByte, RequestImagePixelData(image));
}

protected CGBitmapContext CreateARGBBitmapContext (CGImage inImage)
{
    var pixelsWide = inImage.Width;
    var pixelsHigh = inImage.Height;
    var bitmapBytesPerRow = pixelsWide * 4;
    var bitmapByteCount = bitmapBytesPerRow * pixelsHigh;
    //Note implicit colorSpace.Dispose() 
    using (var colorSpace = CGColorSpace.CreateDeviceRGB()) {
         //Allocate the bitmap and create context
         var bitmapData = Marshal.AllocHGlobal (bitmapByteCount);
         if (bitmapData == IntPtr.Zero) {
             throw new Exception ("Memory not allocated.");
         }

         var context = new CGBitmapContext (bitmapData, pixelsWide, pixelsHigh, 8,
                            bitmapBytesPerRow, colorSpace, CGImageAlphaInfo.PremultipliedFirst);
         if (context == null) {
              throw new Exception ("Context not created");
         }
         return context;
     }
}

//Store pixel data as an ARGB Bitmap
protected IntPtr RequestImagePixelData (UIImage inImage)
{
     var imageSize = inImage.Size;
     CGBitmapContext ctxt = CreateARGBBitmapContext (inImage.CGImage);
     var rect = new RectangleF (0.0f, 0.0f, imageSize.Width, imageSize.Height);
     ctxt.DrawImage (rect, inImage.CGImage);
     var data = ctxt.Data;
     return data;
}

I think the channels are inverted, but maybe there is a way to invert the bitmap without some custom code.

This is the image which is rendered( ignore the fancy model in front of it ):

Image rendered

And the expected image: Image expected

Edit:

The GL_INVALID_OPERATION issue has been fixed, but it does not solve the issue with the red texture.

The vertex-shader:

attribute vec3 position;            
uniform mat4 modelViewMatrix;           

varying mediump vec3 texture;           
        
void main()
{   
    texture = position.xyz;         
    gl_Position = modelViewMatrix * vec4(position.xyz, 1.0);    
}

The fragment-shader:

varying mediump vec3 texture;
uniform samplerCube cubeMap;        
        
void main()
{
    mediump vec3 cube = vec3(textureCube(cubeMap, texture));
    gl_FragColor = vec4(cube.xyz, 1.0);
}

Upvotes: 2

Views: 1155

Answers (4)

Sidney
Sidney

Reputation: 36

The problem is your function CreateARGBBitmapContext the line

var context = new CGBitmapContext (bitmapData, pixelsWide, pixelsHigh, 8, bitmapBytesPerRow, colorSpace, CGImageAlphaInfo.PremultipliedFirst);

If you change

CGImageAlphaInfo.PremultipliedFirst 

to

CGImageAlphaInfo.PremultipliedLast 

that should fix your code.

Upvotes: 2

TheBuzzSaw
TheBuzzSaw

Reputation: 8826

I see that you are using RGBA for both settings during your TexImage2D step. Judging by how blue your original image and how red your resulting image is, I suggest swapping one of them for BGRA.

Upvotes: 0

Felix K.
Felix K.

Reputation: 6281

After some testing i decided to use the code from "XnaTouch" to load textures, this solves the problem with the red texture.

Of course this has not been the end, because there has been no alpha channel when loading png images. Because this is not acceptable and consumes to much time i decided to write a dds loader ( based on code from http://humus.name/ ).

Upvotes: 1

Dr. Snoopy
Dr. Snoopy

Reputation: 56377

Did you use the program (with glUseProgram) before using glUniform? Because it doesn't work and would generate that error in this case.

You can also check what are the causes for that GL error in the glUniform man page (at the end).

Upvotes: 0

Related Questions