/* QGLView Copyright (C) 2012 Ivan Pelipenko peri4ko@gmail.com This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include "glvbo.h" GLVBO::GLVBO(GLenum usage_) { buffer_ = 0; usage = usage_; changed = true; } GLVBO::~GLVBO() { //destroy(); } void GLVBO::init() { if (!isIinit()) glGenBuffers(1, &buffer_); changed = true; } bool GLVBO::rebuffer(bool clear_) { QVector data; //data.clear(); data << vertices_; if (!normals_.isEmpty()) { data << normals_; has_normals = true; } else has_normals = false; if (!texcoords_.isEmpty()) { data << texcoords_; has_texcoords = true; } else has_texcoords = false; if (!colors_.isEmpty()) { data << colors_; has_colors = true; } else has_colors = false; glBindBuffer(GL_ARRAY_BUFFER, buffer_); glBufferData(GL_ARRAY_BUFFER, data.size() * sizeof(GLfloat), data.constData(), usage); glBindBuffer(GL_ARRAY_BUFFER, 0); vert_count = vertices_.size() / 3; changed = false; //qDebug() << "rebuff" << buffer_ << vert_count; if (clear_) clear(); return !isEmpty(); } void GLVBO::draw(GLenum type, bool simplest) { if (buffer_ == 0 || vert_count == 0) return; if (changed) rebuffer(); //qDebug() << "draw" << vert_count; void * offset = (void*)(vert_count * 3 * sizeof(GLfloat)); glBindBuffer(GL_ARRAY_BUFFER, buffer_); glMultiTexCoord3f(GL_TEXTURE2, 0.f, 1.f, 0.f); glVertexPointer(3, GL_FLOAT, 0, 0); if (!simplest) { if (has_normals) { glEnableClientState(GL_NORMAL_ARRAY); glNormalPointer(GL_FLOAT, 0, offset); offset = (void*)(llong(offset) + vert_count * 3 * sizeof(GLfloat)); } else glDisableClientState(GL_NORMAL_ARRAY); if (has_texcoords) { glEnableClientState(GL_TEXTURE_COORD_ARRAY); glTexCoordPointer(2, GL_FLOAT, 0, offset); offset = (void*)(llong(offset) + vert_count * 2 * sizeof(GLfloat)); } else glDisableClientState(GL_TEXTURE_COORD_ARRAY); if (has_colors) { glEnableClientState(GL_COLOR_ARRAY); glColorPointer(4, GL_FLOAT, 0, offset); } else glDisableClientState(GL_COLOR_ARRAY); }/* else { glDisable(GL_NORMAL_ARRAY); glDisable(GL_TEXTURE_COORD_ARRAY); glDisable(GL_COLOR_ARRAY); }*/ glDrawArrays(type, 0, vert_count); glBindBuffer(GL_ARRAY_BUFFER, 0); } void GLVBO::clear() { vertices_.clear(); normals_.clear(); texcoords_.clear(); colors_.clear(); } bool GLVBO::saveToFile(const QString & filename) { if (filename.isEmpty()) return false; QFile f(filename); QByteArray ba; if (f.open(QFile::WriteOnly)) { QDataStream out(&ba, QFile::WriteOnly); out << vertices_ << normals_ << texcoords_ << colors_; ba = qCompress(ba); f.resize(0); f.write(ba); f.close(); return true; } return false; } bool GLVBO::loadFromFile(const QString & filename) { if (filename.isEmpty()) return false; QFile f(filename); QByteArray ba; if (f.open(QFile::ReadOnly)) { ba = f.readAll(); if (ba.isEmpty()) return false; ba = qUncompress(ba); QDataStream in(ba); in >> vertices_ >> normals_ >> texcoords_ >> colors_; changed = true; f.close(); return !isEmpty(); } return false; }