Android OGLES 2: шейдерная указка для цвета - PullRequest
0 голосов
/ 29 февраля 2012

У меня проблема с обновлением программы до шейдеров в OGLES 2.

Это структура данных:

namespace packt {
class GraphicsService {
public:
 ...
   struct ESMatrix{ GLfloat m[4][4]; };

    typedef struct
    {  // Handle to a program object
       GLuint programObject;
       // Attribute locations
       GLint  positionLoc;
       // Uniform locations
       GLint  mvpLoc;
       // Vertex data
       GLfloat  *vertices;
       GLuint   *indices;
       int       numIndices;
       // Rotation angle
       GLfloat   angle;
       // MVP matrix
       ESMatrix  mvpMatrix;
    } UserData;
...
  }
}

В android_main контекст установлен:

packt::GraphicsService lGraphicsService(pApplication,&lTimeService);
packt::Context lContext = { &lGraphicsService, &lTimeService };

Но тогда вместо использования glColor4f, который не является частью OGLES 2, теперь мы пытаемся заменить эту команду шейдерами. Вот как это происходит с методом настройки:

void GraphicsService::setup() {
    glEnable(GL_TEXTURE_2D);
        GLbyte vShaderStr[] =
           "uniform mat4 u_mvpMatrix;                   \n"
           "attribute vec4 a_position;                  \n"
           "void main()                                 \n"
           "{                                           \n"
           "   gl_Position = u_mvpMatrix * a_position;  \n"
           "}                                           \n";

        GLbyte fShaderStr[] =
           "precision mediump float;                            \n"
           "void main()                                         \n"
           "{                                                   \n"
           "  gl_FragColor = vec4( 1.0, 0.0, 0.0, 1.0 );        \n"
           "}                                                   \n";
        // Load the shaders and get a linked program object

        // replaced :: //glColor4f(1.0f, 1.0f, 1.0f, 1.0f); 
        UserData *userData = mContext->userData;
        userData->programObject = esLoadProgram (vShaderStr, fShaderStr);
    glDisable(GL_DEPTH_TEST);
}

Что дает следующее сообщение компилятора:

error: UserData *userData = mContext->userData;
    - 'void*' is not a pointer-to-object type
error: userData->programObject = esLoadProgram (vShaderStr, fShaderStr);
    - invalid conversion from 'GLbyte*' to 'const char*'
    - initializing argument 1 of 'GLuint esLoadProgram(const char*, const char*)'
    - initializing argument 2 of 'GLuint esLoadProgram(const char*, const char*)'

Есть предложения как это исправить? Все комментарии высоко ценятся.

Ответы [ 2 ]

1 голос
/ 29 февраля 2012

1.

Объект контекста, на который указывает mContext, содержит поле «userData», которое, вероятно, объявлено как void*.В этом поле вы храните указатель на ваш фактический UserData объект.Преобразование из UserData* в void* работает неявно, но чтобы получить UserData* из void*, вам необходимо явное приведение:

UserData *userData = reinterpret_cast<UserData*>( mContext->userData );

Обратите внимание, что reinterpret_cast потенциально опасно;когда вы используете его, убедитесь, что ваш void* действительно произошел от UserData*, в противном случае плохие вещи произойдут .

2.

Сообщение об ошибке говорит само за себя: esLoadProgram ожидает аргументы типа const char*, и вы передаете аргументы типа GLbyte*.Объявите ваши vShaderStr и fShaderStr соответственно, как в:

const char *vShaderStr =
    "uniform ...
0 голосов
/ 29 февраля 2012

Я последовал вашему предложению, изменив его, где это необходимо:

UserData *userData = static_cast<UserData*>( esContext->userData );
...
const char vShaderStr[] ={
  "uniform mat4 u_mvpMatrix;                   \n"
  "attribute vec4 a_position;                  \n"
  "void main()                                 \n"
  "{                                           \n"
  "   gl_Position = u_mvpMatrix * a_position;  \n"
  "}                                           \n"};

Большое спасибо!

...