opengl glDrawArray выдает исключение

#c #opengl-es

#c #opengl-es

Вопрос:

Я новичок в OpenGL, и мне нужно напрямую использовать его для отладки, возможно, кто-нибудь может сказать мне, пожалуйста, почему в этом коде glDrawArray должен выдавать исключение (пытаясь получить доступ к памяти в 0x00000000)

 glEnableClientState(GL_VERTEX_ARRAY);
float data[8];
data[0] = 10;
data[1] = 10; 
data[2] = 10;
data[3] = 20; 
data[4] = 20;
data[5] = 20; 
data[6] = 20;
data[7] = 10; 
glVertexPointer(2,GL_FLOAT,0,data);
glDrawArrays(GL_LINE_LOOP,0,4);
glDisableClientState(GL_VERTEX_ARRAY);
  

Комментарии:

1. Вы вызываете это с допустимым контекстом GL? Возможно, вы вызываете его не из того потока

2. в моей программе есть только один поток, поэтому она не может быть вызвана из неправильного потока.

3. Опубликуйте полную минимальную программу, которая демонстрирует проблему.

4. это будет просто копирование и вставка игрового движка, я только что добавил эти строки для функции рисования одного из его образцов. если вам все еще интересен полный исходный код, вы можете загрузить cocos2d-x и в примере helloworld переопределить функцию рисования class HelloWorld и добавить к ней эти строки. в другом примере этот код работает отлично, поэтому я думаю, что должны быть некоторые предварительные действия перед их вызовом, но я не смог их найти.

Ответ №1:

Ваш glDrawArrays вызов эквивалентен:

 glBegin(GL_LINE_LOOP);
glVertex2fv(data    0);
glVertex2fv(data    2);
glVertex2fv(data    4);
glVertex2fv(data    6);
glVertex2fv(data    8);
glVertex2fv(data   10);
glVertex2fv(data   12);
glVertex2fv(data   14);
glEnd();
  

Таким образом, вы определенно пытаетесь получить доступ к некоторой памяти за пределами data .

Комментарии:

1. Как сказал Тибур. 8 в glDrawArrays должно быть числом вершин для рисования, а не числом с плавающей точкой.

2. Произойдет ли сбой вашего приложения, если вы замените свое glDrawArray эквивалентным кодом glBegin / glEnd? (Только с первыми 4 glVertex2fv вызовами)

3. я пытался это сделать, но я разрабатываю игру для Iphone, и, похоже, в OpenGLES нет glBegin или glEnd

Ответ №2:

Возможно, вы включили другой массив с glEnableClientState в другой точке вашей программы и не отключили его. Поэтому glDrawArrays пытается прочитать из другого массива, что вызывает проблему.

РЕДАКТИРОВАТЬ:: Также может быть, что код, который вы нам показали, не является реальным кодом, и вы вызываете glVertexPointer в совершенно другом месте, чем glDrawArrays . Передавая data в качестве указателя на вершину, вы только указываете ему, чтобы он брал вершины из data , когда glDrawArrays вызывается. Данные вершины не копируются, поэтому data должны все еще существовать при glDrawArrays вызове (на данный момент это локальная переменная, но с фрагментом кода, который вы нам дали, это должно сработать).

РЕДАКТИРОВАТЬ: Я также полагаю, что вы не используете какие-либо объекты buffer, поскольку это также может быть проблемой, если при вызове привязывается буфер вершин glVertexPointer .

Комментарии:

1. я не уверен в этом, но я думаю, что это не так, потому что это вызвало бы исключение, как access violation while trying to access 0x0000000 кажется, что массив, в который я передаю glVertexPointer , вообще не сохранен.

2. @Gajet Но разве это не та ошибка, о которой вы упоминали в своем вопросе?

3. @christian : да, это та же проблема, и это именно тот код, который генерирует исключение. вы правы, его основное использование — это что-то другое в другом месте, но когда я переместил его в свой основной вызов draw там, это вызвало ту же проблему, поэтому я просто вставил этот код, основное использование было для рисования отладочной информации объектов box2d.

4. @Gajet Тот факт, что вы не уверены в этом, показывает мне, что вы действительно не совсем знаете, в каком состоянии другие части вашей программы покидают GL. Поэтому хорошей идеей было бы изучить эту проблему. Просто попробуйте вызвать glDisableClientState для всех других массивов. PS.: Массив не сохранен, есть только его адрес (посмотрите на мой подтвержденный ответ).

5. после отключения GL_COLOR_ARRAY и GL_TEXTURE_COORD_ARRAY исключение исправлено, но оно по-прежнему ничего не отображает на экране и идеи?

Ответ №3:

Попробуйте:

 glDrawArrays(GL_LINE_LOOP,0,4);
  

В вашем вызове glVertexPointer() вы говорите, что каждая вершина имеет два элемента с плавающей точкой. Но при вызове glDrawArrays() вы не указываете количество элементов в массиве, вы указываете количество координат, в данном случае их четыре.

Комментарии:

1. тибур также предложил это, но я все еще получаю ошибку после этого исправления.