Фрагментный шейдер OpenGL 2.0 не работает с Cocos2d-X

Я разрабатываю игру, используя Cocos2d-X 2.2.3 и Marmalade SDK 7.4, и я создал фрагментный шейдер, чтобы обесцветить некоторые из моих спрайтов или, другими словами, удалить из них все цвета и показать их только в оттенках серого (черный). и белый).

Шейдер, который я написал, таков:

#ifdef GL_ES
precision mediump float;
#endif

varying vec2 v_texCoord;
uniform sampler2D u_texture;

void main()
{
    float grayScaleValue;
    vec3 originalColor;

    originalColor = texture2D(u_texture, v_texCoord).rgb;

    grayScaleValue = 0.21 * originalColor.r + 0.72 * originalColor.g + 0.07 * originalColor.b;

    gl_FragColor = vec4(grayScaleValue, grayScaleValue, grayScaleValue, 1);
}

Я взял алгоритм для расчета значений оттенков серого из этого< /а> страница.

Код, который я использую для загрузки этого шейдера, следующий:

// Please note that the class: GameObjectSprite is a subclass of CCSprite.
void GameObjectSprite::initShaders()
{
    const GLchar *shaderSource = (const GLchar*) CCString::createWithContentsOfFile("shaders/Grayscale.fsh")->getCString();

    shader = new CCGLProgram();
    shader->initWithVertexShaderByteArray(ccPositionTextureA8Color_vert, shaderSource);
    shader->addAttribute(kCCAttributeNamePosition, kCCVertexAttribFlag_Position);
    shader->addAttribute(kCCAttributeNameColor, kCCVertexAttribFlag_TexCoords);

    CHECK_GL_ERROR_DEBUG();
    shader->link();

    shader->updateUniforms();
    CHECK_GL_ERROR_DEBUG();

    this->setShaderProgram(shader);
    this->getShaderProgram()->use();
}

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


person Felipe    schedule 16.09.2014    source источник
comment
Вы также должны применять шейдер при рисовании спрайтов. Где-то в коде рисования вам нужно иметь getShaderProgram()->use();.   -  person glampert    schedule 16.09.2014
comment
Привет, на самом деле я думаю, что проблема заключалась в том, что я использовал узел пакетной обработки спрайтов для рендеринга своих спрайтов. Я считаю, что пакетный узел переопределяет вызов отрисовки для каждого спрайта, и поэтому ничего не происходит. Однако у меня все еще есть проблема: теперь, когда я действительно использую свой шейдер, все мои спрайты исчезли. Я изменил свой код, чтобы он имел только: gl_FragColor = texture2D(u_texture, v_texCoord); как обычный шейдер, но мои спрайты по-прежнему отсутствуют. Примечание. Я также добавил getShaderProgram()->use(); в метод рисования.   -  person Felipe    schedule 17.09.2014
comment
Это может быть проблема с вершинным шейдером. Вы должны убедиться, что матрицы установлены правильно, чтобы вершины трансформировались.   -  person glampert    schedule 17.09.2014
comment
Ну, я считаю, что использую стандартный вершинный шейдер (ccPositionTextureA8Color_vert). И я использую это, чтобы отправить положение спрайта в шейдер: shader->addAttribute(kCCAttributeNamePosition, kCCVertexAttribFlag_Position);. Есть ли что-нибудь еще, что я должен сделать?   -  person Felipe    schedule 17.09.2014
comment
Да, позиция, вероятно, умножается на матрицу (MVP matrix), которая является юниформ-переменной этого шейдера. Вы должны установить эту переменную перед рисованием.   -  person glampert    schedule 17.09.2014


Ответы (1)


Мне удалось это решить. Я думаю, что, как сказал @glampert, я неправильно загружал матрицу MVP. Вот мой новый код:

void GameLayer::loadShaders()
{
    CCGLProgram *shader;
    const GLchar *fragmentShader;

    shader = new CCGLProgram();

    fragmentShader = CCString::stringWithContentsOfFile("Grayscale.fsh")->getCString();

    shader->initWithVertexShaderByteArray(ccPositionTextureA8Color_vert, fragmentShader);
    shader->addAttribute(kCCAttributeNamePosition, kCCVertexAttrib_Position);
    shader->addAttribute(kCCAttributeNameTexCoord, kCCVertexAttrib_TexCoords);

    CHECK_GL_ERROR_DEBUG();
    shader->link();

    shader->updateUniforms();
    CHECK_GL_ERROR_DEBUG();

    sprite->setShaderProgram(shader);
    sprite->getShaderProgram()->use();
}

Обратите внимание, что я изменил значение строк ниже:

shader->addAttribute(kCCAttributeNamePosition, kCCVertexAttribFlag_Position);
shader->addAttribute(kCCAttributeNameColor, kCCVertexAttribFlag_TexCoords);

To:

shader->addAttribute(kCCAttributeNamePosition, kCCVertexAttrib_Position);
shader->addAttribute(kCCAttributeNameTexCoord, kCCVertexAttrib_TexCoords);    

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

person Felipe    schedule 17.09.2014