#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? (Только с первыми 4glVertex2fv
вызовами)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. тибур также предложил это, но я все еще получаю ошибку после этого исправления.