2016-09-22 5 views
1

Я пытаюсь использовать OpenGL2.0 и создавать несколько кубов в 3D-пространстве, для устройств Android.Почему GLES20.glGetAttribLocation возвращает разные значения для разных устройств?

код он прекрасно работает в некоторых устройствах, но не в других, и я не знаю, почему ... (Все устройства имеют OpenGL 2.0 поддерживаются, и есть последние андроид версии [5.0 или 6.0])

Я только знаю, что проблема заключается в значении -1 возврата (см вниз)

int vertexShader = loadGLShader(GLES20.GL_VERTEX_SHADER, R.raw.vertex); 
int gridShader = loadGLShader(GLES20.GL_FRAGMENT_SHADER, R.raw.grid_fragment); 
int passthroughShader = loadGLShader(GLES20.GL_FRAGMENT_SHADER, R.raw.fragment_color); 

    cubeProgram1 = GLES20.glCreateProgram(); 
    GLES20.glAttachShader(cubeProgram1, vertexShader); 
    GLES20.glAttachShader(cubeProgram1, passthroughShader); 
    GLES20.glLinkProgram(cubeProgram1); 
    GLES20.glUseProgram(cubeProgram1); 

    cubePositionParam1 = GLES20.glGetAttribLocation(cubeProgram1, "a_Position"); 
    cubeNormalParam1 = GLES20.glGetAttribLocation(cubeProgram1, "a_Normal"); ----> Returns -1 Value 
    cubeLightPosParam1 = GLES20.glGetUniformLocation(cubeProgram1, "u_LightPos"); 
    cubeModelParam1 = GLES20.glGetUniformLocation(cubeProgram1, "u_Model") cubeModelViewParam1 = GLES20.glGetUniformLocation(cubeProgram1, "u_MVMatrix"); 
    cubeModelViewProjectionParam1 = GLES20.glGetUniformLocation(cubeProgram1, "u_MVP"); 

....

GLES20.glEnableVertexAttribArray(cubeNormalParam1); ---> Returns -1 ... 

в cubeNormalParam1 = GLES20.glGetAttribLocation(cubeProgram1, "a_Normal"); возвращает значение 2 в некоторых устройствах, и -1 в других , Те, кто имеет значение -1, дает ошибку и не работает ...

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

uniform mat4 u_Model; 
uniform mat4 u_MVP; 
uniform mat4 u_MVMatrix; 
uniform vec3 u_LightPos; 

attribute vec4 a_Position; 
attribute vec4 a_Color; 
attribute vec3 a_Normal; 
attribute vec2 a_TexCoordinate; 

varying vec4 v_Color; 
varying vec3 v_Grid; 
varying vec2 v_TexCoordinate; 

void main() { 
    v_Grid = vec3(u_Model * a_Position); 


    vec3 modelViewVertex = vec3(u_MVMatrix * a_Position); 
    vec3 modelViewNormal = vec3(u_MVMatrix * vec4(a_Normal, 0.0)); 

    float distance = length(u_LightPos - modelViewVertex); 
    vec3 lightVector = normalize(u_LightPos - modelViewVertex); 
    float diffuse = max(dot(modelViewNormal, lightVector), 0.5); 

    diffuse = diffuse * (1.0/(1.0 + (0.00001 * distance * distance))); 
    v_Color = a_Color * diffuse; 

    v_TexCoordinate = a_TexCoordinate; 

    gl_Position = u_MVP * a_Position; 
} 

Почему это случилось? Является ли аппаратное обеспечение?

Любое решение, чтобы исправить это?


Чтобы нарисовать куб я имею это:

public void drawCube1() { 
     cubeNumber = 1; 

     GLES20.glUseProgram(cubeProgram1); 
     GLES20.glUniform3fv(cubeLightPosParam1, 1, lightPosInEyeSpace, 0); 
     // Set the Model in the shader, used to calculate lighting 
     GLES20.glUniformMatrix4fv(cubeModelParam1, 1, false, modelCube, 0); 
     // Set the ModelView in the shader, used to calculate lighting 
     GLES20.glUniformMatrix4fv(cubeModelViewParam1, 1, false, modelView, 0); 
     // Set the ModelViewProjection matrix in the shader. 
     GLES20.glUniformMatrix4fv(cubeModelViewProjectionParam1, 1, false, modelViewProjection1, 0); 
     // Set the position of the cube 
     GLES20.glVertexAttribPointer(
       cubePositionParam1, COORDS_PER_VERTEX, GLES20.GL_FLOAT, false, 0, cubeVertices); 
     // Set the normal positions of the cube, again for shading 
     GLES20.glVertexAttribPointer(cubeNormalParam1, 3, GLES20.GL_FLOAT, false, 0, cubeNormals); 
     // Set the active texture unit to texture unit 0. 
     GLES20.glActiveTexture(GLES20.GL_TEXTURE0); 
     // Bind the texture to this unit. 
     GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, mTextura1); 

     isLookingAtObject_Number(cubeNumber); 

     // Tell the texture uniform sampler to use this texture in the shader by binding to texture unit 0. 
     GLES20.glUniform1i(mTextureUniform, 0); 

     GLES20.glVertexAttribPointer(mTextureCoordinate, 2, GLES20.GL_FLOAT, false, 0, cubeTexture); 
     GLES20.glEnableVertexAttribArray(mTextureCoordinate); 

     GLES20.glEnableVertexAttribArray(cubePositionParam1); 
     GLES20.glEnableVertexAttribArray(cubeNormalParam1); 

     GLES20.glDrawArrays(GLES20.GL_TRIANGLES, 0, 36); 
     checkGLError("Drawing cube"); 
    } 
+0

Что вы подразумеваете под «различными устройствами»? Различные графические процессоры? –

+0

Различные мобильные телефоны для Android и очки VR, например. Он работает в очках и некоторых мобильных телефонах, но в других мобильных телефонах не работает (например, S7 Edge). Графический процессор всех, поддержка OpenGL 1.0, 2.0, 3.0. –

+0

Ошибка: E/Menu: Drawing cube: glError 1281. –

ответ

0

Решение - умножения с -1 значение

... = GLES20.glGetAttribLocation(cubeProgram1, "a_Normal") * -1; 

или

int value; 
if(GLES20.glGetAttribLocation(cubeProgram1, "a_Normal") < 0){ 
     value = -1; 
} 
else { 
     value = 1; 
} 

... = GLES20.glGetAttribLocation(cubeProgram1, "a_Normal") * value; 

Разве это не лучшее решение, но теперь он работает.

+0

Это не работает - вы просто скрываете ошибку, а не исправляете ее. Вы превращаете -1 (атрибут не используется) в +1 (который является местом привязки для совершенно другого атрибута). – solidpixel

+0

Это правда, я скрываю ошибку и не исправляю ее. Но это единственное решение, которое я могу найти, чтобы оно работало в устройстве, и оно работает. Я не могу найти другое решение для этого: \ –

+0

Исправление состоит в том, чтобы остановить вызов 'GLES20.glEnableVertexAttribArray (cubeNormalParam1)', если местоположение, возвращаемое из 'GLES20.glGetAttribLocation()', равно -1. Пропустите 'GLES20.glVertexAttibPointer' тоже. – solidpixel

5
Why GLES20.glGetAttribLocation returns different values for different devices? 

... потому, что различные устройства будут иметь различное оборудование для создания связывания таблиц, а в некоторых случаях может полностью оптимизировать избыточные вычислений и переупаковки использованных атрибутов для экономии места. Это точно, почему API имеет вызов функции для получения привязки местоположений на устройстве во время выполнения; если они были детерминированными константами, вам вообще не понадобится звонок во время выполнения ...

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

Однако это не значит, что вы не можете с уверенностью предположить, (например), что a_Position всегда атрибут 0, a_Color всегда 1, a_Normal всегда 2 и т.д. Если вы жёстко, что в вашем коде, то это полностью возможно, вы загружаете неправильные данные в каждый атрибут. Вы должны запросить места привязки, чтобы получить номера привязки для использования (или использовать статическое связывание на основе шейдера, добавленное в OpenGL ES 3.x).

Какой фактический вызов API GL устанавливает состояние ошибки GL?

+0

Я использую openGL2.0. Ошибка возникает несколько раз постоянно. 10301-10382/com.google.vrtoolkit.cardboard.samples.treasurehunt E/Menu: Рисунок куба: glError 1281 –

+0

... да, это говорит вам, что такое ошибка, но не вызов какой функции вызывает ее задавать. Без дополнительной информации о том, какой вызов функции идет не так, это невозможно. Вызовите функцию checkError после каждого вашего вызова API и сообщите о конкретной функции, которая устанавливает ошибку, просто сообщив, что «что-то пошло не так» в конце не особенно полезно для отладки ... – solidpixel

+0

Спасибо, Я делаю это , проблема в том, что теперь приложение запускается и ничего не показывает, остается черным. Я положил функцию drawCube, при обновлении, в вопрос. Может быть, ошибка есть ... но я не могу ее найти, потому что приложение работает и не ломается. Initialy, ошибка была здесь: GLES20.glEnableVertexAttribArray (cubeNormalParam1); Это было на, onSurfaceCreated (EGLConfig config) {... (и он возвращает -1, вот почему я думаю, что проблема была там) Я изменил его для cubeDraw(), и теперь он запускается (с Ошибка 1281), но ничего не отображается на экране. –

Смежные вопросы