OpenGL klasa do obsługi wierzchołków - SIGSEGV

0

Napisałem klasę do obsługi wierzchołków. Klasa korzysta z pomocniczej klasy wektora 4-wymiarowego Vec4, ale może przyjmować też liczby float. Kompiluje się, wszystko ładnie jest tylko jeden szkopuł - nie działa:) Po uruchomieniu programu testującego włącza się tylko terminal i wyświetla, że proces zwrócił -1 - krótko mówiąc nic się nie dzieje. Debugger zwraca SIGSEGV. Callstack:

#0 in ??() (??:??)
#1 Render::setVbo(this=0x669be0 <vertexarray>) VertexArray.cpp:71
#2 Render::setVao<3ul>(this=0x669be0 <vertexarray>, tab=..., co=@0x7fffffffe4dc: 0) VertexArray.h:52
#3 Render::VertexArray<3ul>(this=0x669be0 <vertexarray>, tab=..., co=@0x7fffffffe4dc: 0) VertexArray.h:36
#4 __static_initialization_and_destruction_0(__initialize_p=1, __priority=65535) test.cpp:44
#5 _GLOBAL__sub_I_main() test.cpp:61
#6 in __libc_csu_init() (??:??)
#7 __libc_start_main()
#8 in _start() (??:??)

Klasa wierzchołków:

namespace Render
{
    class VertexArray
    {
        private:
            GLsizei colorOffset;
            GLuint vbo, ibo, vao;
            vector<Vec4> vertexData;
            vector<unsigned> elementsData;

            void setVbo();
            void setIbo();
            void firstVbo();
        public:
            template<size_t N>
                VertexArray(const float (&tab) [N], const GLsizei &co = 0);
            template<size_t N>
                VertexArray(const float (&tab) [N], const vector<unsigned> indexData, const GLsizei &co = 0);
            template<size_t N, size_t M>
                VertexArray(const float (&tab) [N], const unsigned (&indexData) [M], const GLsizei &co = 0);

            template<size_t N>
                VertexArray(const Vec4 (&tab) [N], const GLsizei &co = 0) {vertexData = setVao(tab, co);} //ten konstruktor jest używany w przykladzie; tę linię wskazuje callstack
            template<size_t N>
                VertexArray(const Vec4 (&tab) [N], const vector<unsigned> indexData, const GLsizei &co = 0);
            template<size_t N, size_t M>
                VertexArray(const Vec4 (&tab) [N], const unsigned (&indexData) [M], const GLsizei &co = 0) ;

            VertexArray(const vector<Vec4> &vert, const GLsizei &co = 0) : colorOffset(co);
            VertexArray(const vector<Vec4> &vert, const vector<unsigned> indexData, const GLsizei  co = 0);
            template<size_t M>
                VertexArray(const vector<Vec4> &vert, const unsigned (&indexData) [M], const GLsizei &co = 0);

            ~VertexArray();

            template<size_t N>
                vector<Vec4> setVao(const float (&tab) [N], const GLsizei &co = 0);
            template<size_t N>
                vector<Vec4> setVao(const Vec4 (&tab) [N], const GLsizei &co = 0) {colorOffset = co; vertexData = Vec4::Vec4tovector(tab, N); setVbo(); return vertexData;} //tu wskazuje callstack
            vector<Vec4> setVao(const vector<Vec4> &vect, const GLsizei &co = 0);

            template<size_t N>
                vector<Vec4> setVaoC(const float (&tab) [N], const GLsizei &co = 0);
            template<size_t N>
                vector<Vec4> setVaoC(const Vec4 (&tab) [N], const GLsizei &co = 0);

            template<size_t N>
                vector<Vec4> *addVert(const Vec4(&tab) [N]);
            vector<Vec4> *addVert(const vector<Vec4> &vect);

            vector<Vec4> *getVao();

            vector<unsigned> setElements(const vector<unsigned> &indexData);
            template<size_t M>
                vector<unsigned> setElements(const unsigned (&tab) [M]);

            vector<unsigned> *addElements(const vector<unsigned> &indexData);
            template<size_t M>
                vector<unsigned> *addElements(const unsigned (&tab) [M]);

            vector<unsigned> *getElements() {return &elementsData;}
            void cleanElements();

            template<size_t M>
                static vector<unsigned> unsitovector(const unsigned (&tab) [M]);

            void DrawArrays(const GLenum&, const GLint&, const GLsizei&) const;
            void DrawElements(const GLenum&, const GLint&, const GLenum&, const GLvoid*) const;
            void DrawElementsBaseVertex(const GLenum&, const GLint&, const GLenum&, const GLvoid*, const GLint&) const;
    };

} //Render

Fragment głównej części programu:

Render::Vec4 vertarray[] = {Render::Vec4(-0.2f, 0.3f, 0.0f, 1.0f),
                     Render::Vec4(-0.2f, -0.1f, 0.0f, 1.0f),
                     Render::Vec4(0.1f, 0.3f, 0.0f, 1.0f)};

Render::VertexArray vertexarray(vertarray); //linia 44 wskazywana przez callstack
void init()
{
    Render::Program program("data/vertShader.vert", "data/fragShader.frag"); //wykorzystuję tu inną swoją klasę
}

void display()
{
    glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
    glClear(GL_COLOR_BUFFER_BIT);
    vertexarray.DrawArrays(GL_TRIANGLES, 0, 3);
    glutSwapBuffers();
}

void reshape(int w, int h)
{
    glViewport(0, 0, w, h);
} //i tu tez callstack

Fragment VertexArray.cpp:

    void VertexArray::setVbo()
    {
        glGenBuffers(1, &vbo); //linia 71, również wskazywana
        glBindBuffer(GL_ARRAY_BUFFER, vbo);
        glBufferData(GL_ARRAY_BUFFER, sizeof(vertexData), &vertexData[0], GL_STATIC_DRAW);

        glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, 0, 0);
        if(colorOffset)
        {
            glVertexAttribPointer(1, 4, GL_FLOAT, GL_FALSE, 0, (void*)colorOffset);
        }
        glBindBuffer(GL_ARRAY_BUFFER, 0);
    }

Jakie naruszenie ochrony pamięci? Gdzie kompilator widzi problem?
PS starałem się dać jak najwięcej informacji, ale nie zaśmiecając postu - jeśli trzeba więcej, oczywiście podam.

0
kpusmo napisał(a):

Fragment VertexArray.cpp:

    void VertexArray::setVbo()
    {
        glGenBuffers(1, &vbo); //linia 71, również wskazywana
        glBindBuffer(GL_ARRAY_BUFFER, vbo);
        glBufferData(GL_ARRAY_BUFFER, sizeof(vertexData), &vertexData[0], GL_STATIC_DRAW);

        glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, 0, 0);
        if(colorOffset)
        {
            glVertexAttribPointer(1, 4, GL_FLOAT, GL_FALSE, 0, (void*)colorOffset);
        }
        glBindBuffer(GL_ARRAY_BUFFER, 0);
    }

.

nie 'glBufferData(GL_ARRAY_BUFFER, sizeof(vertexData), &vertexData[0], GL_STATIC_DRAW);' tylko 'glBufferData(GL_ARRAY_BUFFER, sizeof(Vec4) * vertexData.size(), &vertexData[0], GL_STATIC_DRAW);'

0
vector<Vec4> vertexData;
glBufferData(GL_ARRAY_BUFFER, sizeof(vertexData), &vertexData[0], GL_STATIC_DRAW);

Tak to niestety nie zadziała (sizeof(vertexData) tzn). Sizeof jest obliczany/podstawiany na etapie kompilacji i jest stały - to po prostu wielkość struktury reprezentującej wektor (dokładna wartość zależnie od implementacji. Dla odważnych, poszukaj definicji swojego wektora być gdzieś tutaj: http://gcc.gnu.org/onlinedocs/gcc-4.6.2/libstdc++/api/a01117_source.html) Jeśli chcesz poznać ilość pamięci jaką potrzebujesz na przechowania zawartości wektora, powinieneś użyć czegoś w rodzaju:

vertexData.size() * sizeof(vertexData[0])
1

glBufferData(GL_ARRAY_BUFFER, sizeof(vertexData), &vertexData[0], GL_STATIC_DRAW);
Jeszcze dodam, że to nie jest thread-safe. Oczywiście nie musi być, ale warto udokumentować: nie dotykać wektorów z innego wątka niż rysującego.

0

Problem rozwiązany: zmienna typu VertexArray była deklarowana jako globalna, czyli przed postawieniem kontekstu ogl, a w konstruktorze były wykorzystywane funkcje opengl. Usunąłem konstruktory, dodałem domyślny i śmiga.

1 użytkowników online, w tym zalogowanych: 0, gości: 1