OpenGL ES 2.0 / MonoTouch: рендеринг текстур с графическим интерфейсом ничего не показывает - PullRequest
1 голос
/ 04 ноября 2011

Я строю простой фреймворк для OpenGL UI для MonoTouch.Я все настроил и также успешно рендерил 3D-модели, но простой 2D-объект текстуры не работает.Текстура имеет размер 256x256, поэтому она невелика и имеет мощность два.

Вот некоторый код рендеринга (Примечание: я удалил существующий и рабочий код):

// Render the gui objects ( flat )
Projection = Matrix4x4.Orthographic(0, WindowProperties.Width, WindowProperties.Height, 0);
View = new Matrix4x4();
GL.Disable(All.CullFace);
GL.Disable(All.DepthTest);
_Stage.RenderGui();

Стадия:

public void RenderGui ()
{
    Draw(this);
    // Renders every child control, all of them call "DrawImage" when rendering something
}


public void DrawImage (Control caller, ITexture2D texture, PointF position, SizeF size)
{
    PointF gposition = caller.GlobalPosition; // Resulting position is 0,0 in my tests
    gposition.X += position.X;
    gposition.Y += position.Y;

    // Renders the ui model, this is done by using a existing ( and working vertex buffer )
    // The shader gets some parameters ( this works too in 3d space )   
    _UIModel.Render(new RenderParameters() {
        Model = Matrix4x4.Scale(size.Width, size.Height, 1) * Matrix4x4.Translation(gposition.X, gposition.Y, 0),
       TextureParameters = new TextureParameter[] {
           new TextureParameter("texture", texture)
       }
    });
}

Модель использует вектор2 для позиций, другие шейдеры не задаются никакими другими атрибутами.

Шейдер ниже должен отображать текстуру.

Вершина:

attribute vec2 position;        
uniform mat4 modelViewMatrix;           
varying mediump vec2 textureCoordinates;

void main()
{
    gl_Position = modelViewMatrix * vec4(position.xy, -3.0, 1.0);
    textureCoordinates = position;
}

Фрагмент:

varying mediump vec2 textureCoordinates;
uniform sampler2D texture;          

void main()
{
    gl_FragColor = texture2D(texture, textureCoordinates) + vec4(0.5, 0.5, 0.5, 0.5);
}

Я обнаружил, что проблема с рисованием вызвана шейдером.Эта строка выдает GL_INVALID_OPERATION (работает с другими шейдерами):

GL.UniformMatrix4(uni.Location, 1, false, (parameters.Model * _Device.View * _Device.Projection).ToArray());

РЕДАКТИРОВАТЬ:

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

Как уже упоминалось в другом потоке, текстура неправильная, но это другая проблема ( OpenGL ES 2.0 / MonoTouch: Текстура окрашена в красный цвет )

Инициализация шейдера с упомянутой выше проблемой GL.GetUniformLocation:

[... Compile shaders ...]
// Attach vertex shader to program.
GL.AttachShader (_Program, vertexShader);

// Attach fragment shader to program.
GL.AttachShader (_Program, pixelShader);        

// Bind attribute locations
for (int i = 0; i < _VertexAttributeList.Length; i++) {
    ShaderAttribute attribute = _VertexAttributeList [i];
    GL.BindAttribLocation (_Program, i, attribute.Name);
}

// Link program
if (!LinkProgram (_Program)) {
    GL.DeleteShader (vertexShader);
    GL.DeleteShader (pixelShader);
    GL.DeleteProgram (_Program);

    throw new Exception ("Shader could not be linked");
}

// Get uniform locations
for (int i = 0; i < _UniformList.Length; i++) {
    ShaderUniform uniform = _UniformList [i];
    uniform.Location = GL.GetUniformLocation (_Program, uniform.Name);
    Console.WriteLine ("Uniform: {0} Location: {1}", uniform.Name, uniform.Location);
}

// Detach shaders
GL.DetachShader (_Program, vertexShader);
GL.DetachShader (_Program, pixelShader);

GL.DeleteShader (vertexShader);
GL.DeleteShader (pixelShader);

// Shader is initialized add it to the device
_Device.AddResource (this);

Ответы [ 2 ]

3 голосов
/ 04 ноября 2011

Я не знаю, что Matrix4x4.Orthographic использует в качестве ближней дальности, но если это что-то простое, например [-1,1], объект может просто находиться за пределами ближней дальности, поскольку вы устанавливаете его Значение z явно равно -3.0 в вершинном шейдере (и ни масштаб, ни перевод матрицы модели не изменят это). Попробуйте вместо этого использовать z of 0.0. В любом случае, почему это -3?

РЕДАКТИРОВАТЬ: Таким образом, если функция GL.UniformMatrix4 выдает GL_INVALID_OPERATION, кажется, вы не получили соответствующее местоположение uniorm успешно. Так что код, в котором вы это делаете, также может помочь найти проблему.

Или, возможно, вы вызываете GL.UniformMatrix4 перед использованием соответствующей шейдерной программы. Имейте в виду, что униформу можно установить только после активации программы (GL.UseProgram или что-то похожее было вызвано с программой шейдера).

И, между прочим, вы все равно умножаете матрицы в неправильном порядке (учитывая ваш шейдер и код установки матрицы). Если это действительно работает для других визуализаций, то вам либо просто повезло, либо у вас есть серьезные концептуальные и математические несоответствия в вашей матричной библиотеке.

0 голосов
/ 16 ноября 2011

Оказывается, что шейдерная форма меняется в неизвестное время.Все создается и инициализируется, когда я спрашиваю OpenGL ES о единообразном расположении, поэтому это должно быть ошибкой в ​​OpenGL.

Вызов GL.GetUniformLocation (..) каждый раз, когда я устанавливаю шейдерную форму, решает проблему.

...