2013-03-02 00:11:18 +01:00
|
|
|
/*---------------------------------------------------------------------------------
|
|
|
|
|
|
|
|
KubKraft
|
|
|
|
Copyright (C) 2012 Quent42340 <quent42340@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 <http://www.gnu.org/licenses/>.
|
|
|
|
|
|
|
|
---------------------------------------------------------------------------------*/
|
|
|
|
#include <iostream>
|
|
|
|
#include <vector>
|
|
|
|
#include <map>
|
2013-03-11 21:09:55 +01:00
|
|
|
#include <unordered_map>
|
2013-03-02 00:11:18 +01:00
|
|
|
#include <cmath>
|
|
|
|
|
|
|
|
#include <SDL/SDL.h>
|
2013-03-07 07:58:55 +01:00
|
|
|
#include <GL/glew.h>
|
2013-03-02 00:11:18 +01:00
|
|
|
|
|
|
|
#include "types.h"
|
2013-03-02 06:06:07 +01:00
|
|
|
#include "config.h"
|
2013-03-02 00:11:18 +01:00
|
|
|
#include "player.h"
|
|
|
|
#include "cube.h"
|
|
|
|
#include "chunk.h"
|
2013-03-02 06:06:07 +01:00
|
|
|
#include "map.h"
|
2013-03-02 04:54:21 +01:00
|
|
|
#include "game.h"
|
2013-03-02 00:11:18 +01:00
|
|
|
|
|
|
|
using namespace std;
|
|
|
|
|
2013-04-29 15:29:22 +02:00
|
|
|
Chunk::Chunk(int x, int y, int z) {
|
2013-03-02 00:11:18 +01:00
|
|
|
srand(time(NULL));
|
|
|
|
|
|
|
|
m_x = x;
|
|
|
|
m_y = y;
|
|
|
|
m_z = z;
|
|
|
|
|
2013-03-07 07:58:55 +01:00
|
|
|
m_surroundingChunks = new Chunk*[6];
|
|
|
|
for (int i = 0; i < 6; i++) m_surroundingChunks[i] = NULL;
|
|
|
|
|
|
|
|
m_vboVertices = 0; glGenBuffers(1, &m_vboVertices);
|
|
|
|
m_vboTexCoords = 0; glGenBuffers(1, &m_vboTexCoords);
|
|
|
|
m_vboColors = 0; glGenBuffers(1, &m_vboColors);
|
|
|
|
m_vboVertexCount = 0;
|
2013-03-02 00:11:18 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
Chunk::~Chunk() {
|
2013-03-07 07:58:55 +01:00
|
|
|
glDeleteBuffers(1, &m_vboVertices);
|
|
|
|
glDeleteBuffers(1, &m_vboTexCoords);
|
|
|
|
glDeleteBuffers(1, &m_vboColors);
|
|
|
|
|
2013-03-11 21:09:55 +01:00
|
|
|
for(std::unordered_map<int, Cube*>::iterator it = m_cubes.begin() ; it != m_cubes.end() ; it++) {
|
|
|
|
delete it->second;
|
2013-03-02 00:11:18 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
m_cubes.clear();
|
2013-03-07 07:58:55 +01:00
|
|
|
|
|
|
|
delete[] m_surroundingChunks;
|
2013-03-02 00:11:18 +01:00
|
|
|
}
|
|
|
|
|
2013-03-09 03:23:13 +01:00
|
|
|
void Chunk::setSurroundingChunk(unsigned char face, Chunk* chunk) {
|
|
|
|
if ((face >= 0) && (face < 6)) {
|
|
|
|
m_surroundingChunks[face] = chunk;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-03-02 00:11:18 +01:00
|
|
|
void Chunk::deleteCube(Cube *cube) {
|
2013-03-11 21:09:55 +01:00
|
|
|
for(std::unordered_map<int, Cube*>::iterator it = m_cubes.begin(); it != m_cubes.end() ; it++) {
|
|
|
|
if(it->second == NULL) continue;
|
|
|
|
if(it->second->x() == cube->x() && it->second->y() == cube->y() && it->second->z() == cube->z()) {
|
2013-03-02 00:11:18 +01:00
|
|
|
if(cube->selected()) {
|
2013-03-02 06:06:07 +01:00
|
|
|
Game::map->map()[MAP_POS(cube->x(), cube->y(), cube->z())] = 0;
|
2013-03-02 00:11:18 +01:00
|
|
|
m_cubes.erase(it);
|
2013-03-10 16:15:24 +01:00
|
|
|
refreshVBO();
|
|
|
|
if((cube->x() - 1 <= m_x) && (m_surroundingChunks[0] != NULL)) m_surroundingChunks[0]->refreshVBO();
|
|
|
|
if((cube->x() + 1 >= m_x + CHUNK_WIDTH - 1) && (m_surroundingChunks[1] != NULL)) m_surroundingChunks[1]->refreshVBO();
|
|
|
|
if((cube->y() - 1 <= m_y) && (m_surroundingChunks[2] != NULL)) m_surroundingChunks[2]->refreshVBO();
|
|
|
|
if((cube->y() + 1 >= m_y + CHUNK_DEPTH - 1) && (m_surroundingChunks[3] != NULL)) m_surroundingChunks[3]->refreshVBO();
|
|
|
|
if((cube->z() + 1 >= m_z + CHUNK_HEIGHT - 1) && (m_surroundingChunks[4] != NULL)) m_surroundingChunks[4]->refreshVBO();
|
|
|
|
if((cube->z() - 1 <= m_z) && (m_surroundingChunks[5] != NULL)) m_surroundingChunks[5]->refreshVBO();
|
|
|
|
delete cube;
|
2013-03-02 00:11:18 +01:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-03-11 21:09:55 +01:00
|
|
|
void Chunk::addCube(Cube *selectedCube, int type) {
|
|
|
|
int x = selectedCube->x();
|
|
|
|
int y = selectedCube->y();
|
|
|
|
int z = selectedCube->z();
|
|
|
|
|
2013-04-29 15:29:22 +02:00
|
|
|
/*if(x == 0) {
|
|
|
|
m_surroundingChunks[0]->addCube(m_surroundingChunks[0]->getCube(CHUNK_WIDTH - 1, y, z), type);
|
|
|
|
return;
|
|
|
|
}*/
|
|
|
|
|
2013-03-11 21:09:55 +01:00
|
|
|
if((selectedCube == NULL) || (selectedCube->selectedFace() == -1)) {
|
|
|
|
m_cubes[CUBE_POS(x, y, z)] = selectedCube;
|
2013-03-09 15:20:18 +01:00
|
|
|
return;
|
2013-03-02 07:10:06 +01:00
|
|
|
}
|
|
|
|
else if(selectedCube->selectedFace() == 0) {
|
2013-03-11 21:09:55 +01:00
|
|
|
if((MAP_POS(x, y + 1, z) >= 0) && (MAP_POS(x, y + 1, z) < Game::map->width() * Game::map->depth() * Game::map->height())) {
|
|
|
|
Game::map->map()[MAP_POS(x, y + 1, z)] = type;
|
2013-03-11 23:50:53 +01:00
|
|
|
m_cubes[CUBE_POS(x, y + 1, z)] = new Cube(x, y + 1, z, type);
|
2013-03-09 15:20:18 +01:00
|
|
|
}
|
2013-03-02 00:11:18 +01:00
|
|
|
}
|
|
|
|
else if(selectedCube->selectedFace() == 1) {
|
2013-03-11 21:09:55 +01:00
|
|
|
if((MAP_POS(x + 1, y, z) >= 0) && (MAP_POS(x + 1, y, z) < Game::map->width() * Game::map->depth() * Game::map->height())) {
|
|
|
|
Game::map->map()[MAP_POS(x + 1, y, z)] = type;
|
2013-03-11 23:50:53 +01:00
|
|
|
m_cubes[CUBE_POS(x + 1, y, z)] = new Cube(x + 1, y, z, type);
|
2013-03-09 15:20:18 +01:00
|
|
|
}
|
2013-03-02 00:11:18 +01:00
|
|
|
}
|
|
|
|
else if(selectedCube->selectedFace() == 2) {
|
2013-03-11 21:09:55 +01:00
|
|
|
if((MAP_POS(x - 1, y, z) >= 0) && (MAP_POS(x - 1, y, z) < Game::map->width() * Game::map->depth() * Game::map->height())) {
|
|
|
|
Game::map->map()[MAP_POS(x - 1, y, z)] = type;
|
2013-03-11 23:50:53 +01:00
|
|
|
m_cubes[CUBE_POS(x - 1, y, z)] = new Cube(x - 1, y, z, type);
|
2013-03-09 15:20:18 +01:00
|
|
|
}
|
2013-03-02 00:11:18 +01:00
|
|
|
}
|
|
|
|
else if(selectedCube->selectedFace() == 3) {
|
2013-03-11 21:09:55 +01:00
|
|
|
if((MAP_POS(x, y - 1, z) >= 0) && (MAP_POS(x, y - 1, z) < Game::map->width() * Game::map->depth() * Game::map->height())) {
|
|
|
|
Game::map->map()[MAP_POS(x, y - 1, z)] = type;
|
2013-03-11 23:50:53 +01:00
|
|
|
m_cubes[CUBE_POS(x, y - 1, z)] = new Cube(x, y - 1, z, type);
|
2013-03-09 15:20:18 +01:00
|
|
|
}
|
2013-03-02 00:11:18 +01:00
|
|
|
}
|
|
|
|
else if(selectedCube->selectedFace() == 4) {
|
2013-03-11 21:09:55 +01:00
|
|
|
if((MAP_POS(x, y, z + 1) >= 0) && (MAP_POS(x, y, z + 1) < Game::map->width() * Game::map->depth() * Game::map->height())) {
|
|
|
|
Game::map->map()[MAP_POS(x, y, z + 1)] = type;
|
2013-03-11 23:50:53 +01:00
|
|
|
m_cubes[CUBE_POS(x, y, z + 1)] = new Cube(x, y, z + 1, type);
|
2013-03-09 15:20:18 +01:00
|
|
|
}
|
2013-03-02 00:11:18 +01:00
|
|
|
}
|
|
|
|
else if(selectedCube->selectedFace() == 5) {
|
2013-03-11 21:09:55 +01:00
|
|
|
if((MAP_POS(x, y, z - 1) >= 0) && (MAP_POS(x, y, z - 1) < Game::map->width() * Game::map->depth() * Game::map->height())) {
|
|
|
|
Game::map->map()[MAP_POS(x, y, z - 1)] = type;
|
2013-03-11 23:50:53 +01:00
|
|
|
m_cubes[CUBE_POS(x, y, z - 1)] = new Cube(x, y, z - 1, type);
|
2013-03-09 15:20:18 +01:00
|
|
|
}
|
2013-03-02 00:11:18 +01:00
|
|
|
}
|
2013-03-11 02:05:34 +01:00
|
|
|
|
2013-03-09 01:44:47 +01:00
|
|
|
refreshVBO();
|
2013-03-11 02:05:34 +01:00
|
|
|
if((selectedCube->x() == m_x) && (m_surroundingChunks[0] != NULL)) m_surroundingChunks[0]->refreshVBO();
|
|
|
|
if((selectedCube->x() == m_x + CHUNK_WIDTH - 1) && (m_surroundingChunks[1] != NULL)) m_surroundingChunks[1]->refreshVBO();
|
|
|
|
if((selectedCube->y() == m_y) && (m_surroundingChunks[2] != NULL)) m_surroundingChunks[2]->refreshVBO();
|
|
|
|
if((selectedCube->y() == m_y + CHUNK_DEPTH - 1) && (m_surroundingChunks[3] != NULL)) m_surroundingChunks[3]->refreshVBO();
|
|
|
|
if((selectedCube->z() == m_z + CHUNK_HEIGHT - 1) && (m_surroundingChunks[4] != NULL)) m_surroundingChunks[4]->refreshVBO();
|
|
|
|
if((selectedCube->z() == m_z) && (m_surroundingChunks[5] != NULL)) m_surroundingChunks[5]->refreshVBO();
|
2013-03-02 00:11:18 +01:00
|
|
|
}
|
|
|
|
|
2013-03-07 07:58:55 +01:00
|
|
|
Cube* Chunk::getCube(int x, int y, int z) {
|
|
|
|
if ((x < 0) || (x >= CHUNK_WIDTH) || (y < 0) || (y >= CHUNK_DEPTH) || (z < 0) || (z >= CHUNK_HEIGHT)) {
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
2013-03-11 21:09:55 +01:00
|
|
|
int coords = x + (y * CHUNK_WIDTH) + (z * CHUNK_WIDTH * CHUNK_DEPTH);
|
|
|
|
Cube *cube = m_cubes[coords];
|
2013-03-11 23:14:43 +01:00
|
|
|
|
|
|
|
if(cube == NULL) {
|
2013-03-11 21:09:55 +01:00
|
|
|
m_cubes.erase(coords);
|
2013-03-11 02:05:34 +01:00
|
|
|
return NULL;
|
2013-03-07 07:58:55 +01:00
|
|
|
}
|
2013-03-11 18:56:48 +01:00
|
|
|
else return cube;
|
2013-03-07 07:58:55 +01:00
|
|
|
}
|
|
|
|
|
2013-04-29 23:53:31 +02:00
|
|
|
float Chunk::getTexOffsetU(int type, int i, Cube *cube) {
|
|
|
|
if((type == 2) && (cube != NULL)) {
|
|
|
|
Cube *higherCube = NULL;
|
|
|
|
|
|
|
|
// Little bug with this way: Dirt blocks at chunk borders are grassed too...
|
|
|
|
if(cube->z() < m_z + CHUNK_HEIGHT - 1) higherCube = getCube(cube->x() - m_x, cube->y() - m_y, cube->z() - m_z + 1);
|
|
|
|
else {
|
|
|
|
if(m_surroundingChunks[4] != NULL) higherCube = m_surroundingChunks[4]->getCube(cube->x() - m_x, cube->y() - m_y, 0);
|
2013-04-29 15:58:15 +02:00
|
|
|
}
|
2013-04-29 23:53:31 +02:00
|
|
|
|
|
|
|
if((higherCube == NULL) || (higherCube->type() == 0)) {
|
|
|
|
if((i == 0) || (i == 1) || (i == 2) || (i == 3)) {
|
|
|
|
return type * 0.125;
|
|
|
|
}
|
|
|
|
else if(i == 4) {
|
|
|
|
return (type + 1) * 0.125;
|
|
|
|
} else {
|
|
|
|
return (type - 1) * 0.125;
|
|
|
|
}
|
2013-04-29 15:58:15 +02:00
|
|
|
} else {
|
|
|
|
return (type - 1) * 0.125;
|
|
|
|
}
|
2013-04-29 23:53:31 +02:00
|
|
|
} else {
|
|
|
|
return (type - 1) * 0.125;
|
2013-04-29 15:58:15 +02:00
|
|
|
}
|
2013-03-07 07:58:55 +01:00
|
|
|
}
|
|
|
|
|
2013-04-29 23:53:31 +02:00
|
|
|
float Chunk::getTexOffsetV(int type) {
|
2013-03-25 18:37:17 +01:00
|
|
|
if(type > 8) {
|
2013-03-25 18:43:25 +01:00
|
|
|
type <<= 3; // Here 8 ( remember x * 8 == x << 3 ) is the texture image width
|
2013-03-25 18:37:17 +01:00
|
|
|
return 1 - type * 0.125;
|
|
|
|
}
|
2013-03-07 07:58:55 +01:00
|
|
|
return 0.875;
|
|
|
|
}
|
|
|
|
|
|
|
|
void Chunk::refreshVBO() {
|
|
|
|
m_vboVertexCount = 0;
|
2013-03-09 03:23:13 +01:00
|
|
|
|
2013-03-11 23:14:43 +01:00
|
|
|
if(m_cubes.size() == 0) return;
|
2013-03-07 07:58:55 +01:00
|
|
|
|
|
|
|
float cubeCoords[6 * 12] = {
|
|
|
|
0, 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 1,
|
|
|
|
1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 1, 1,
|
|
|
|
0, 0, 1, 0, 0, 0, 1, 0, 0, 1, 0, 1,
|
|
|
|
1, 1, 1, 1, 1, 0, 0, 1, 0, 0, 1, 1,
|
|
|
|
0, 1, 1, 0, 0, 1, 1, 0, 1, 1, 1, 1,
|
|
|
|
1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0
|
|
|
|
};
|
|
|
|
|
|
|
|
unsigned char grey[6] = {159, 191, 127, 223, 255, 95};
|
|
|
|
|
|
|
|
std::vector<float> vertices = std::vector<float>();
|
|
|
|
std::vector<float> texCoords = std::vector<float>();
|
|
|
|
std::vector<unsigned char> colors = std::vector<unsigned char>();
|
|
|
|
|
2013-03-11 23:14:43 +01:00
|
|
|
for(int qc = 0 ; qc < CHUNK_WIDTH * CHUNK_DEPTH * CHUNK_HEIGHT ; qc++) {
|
2013-03-07 07:58:55 +01:00
|
|
|
int x = qc % CHUNK_WIDTH;
|
|
|
|
int y = (qc / CHUNK_WIDTH) % CHUNK_DEPTH;
|
|
|
|
int z = (qc / CHUNK_WIDTH) / CHUNK_DEPTH;
|
2013-03-11 23:14:43 +01:00
|
|
|
Cube *qe = getCube(x, y, z);
|
2013-03-07 07:58:55 +01:00
|
|
|
if (qe == NULL) continue;
|
2013-03-11 23:14:43 +01:00
|
|
|
Cube *cube = NULL;
|
2013-03-07 07:58:55 +01:00
|
|
|
|
|
|
|
int coords[6 * 3] = {
|
|
|
|
x-1, y, z,
|
|
|
|
x+1, y, z,
|
|
|
|
x, y-1, z,
|
|
|
|
x, y+1, z,
|
|
|
|
x, y, z+1,
|
|
|
|
x, y, z-1
|
|
|
|
};
|
|
|
|
|
2013-03-11 23:14:43 +01:00
|
|
|
for(int i = 0 ; i < 6 ; i++) {
|
2013-03-07 07:58:55 +01:00
|
|
|
cube = getCube(coords[i*3], coords[i*3 + 1], coords[i*3 + 2]);
|
2013-03-11 02:05:34 +01:00
|
|
|
|
2013-03-07 07:58:55 +01:00
|
|
|
if ((coords[i*3] < 0) && (m_surroundingChunks[0] != NULL)) {
|
|
|
|
cube = m_surroundingChunks[0]->getCube(coords[i*3] + CHUNK_WIDTH, coords[i*3 + 1], coords[i*3 + 2]);
|
|
|
|
}
|
|
|
|
else if ((coords[i*3] >= CHUNK_WIDTH) && (m_surroundingChunks[1] != NULL)) {
|
|
|
|
cube = m_surroundingChunks[1]->getCube(coords[i*3] - CHUNK_WIDTH, coords[i*3 + 1], coords[i*3 + 2]);
|
|
|
|
}
|
2013-03-11 02:05:34 +01:00
|
|
|
|
2013-03-07 07:58:55 +01:00
|
|
|
if ((coords[i*3 + 1] < 0) && (m_surroundingChunks[2] != NULL)) {
|
|
|
|
cube = m_surroundingChunks[2]->getCube(coords[i*3], coords[i*3 + 1] + CHUNK_DEPTH, coords[i*3 + 2]);
|
|
|
|
}
|
|
|
|
else if ((coords[i*3 + 1] >= CHUNK_DEPTH) && (m_surroundingChunks[3] != NULL)) {
|
|
|
|
cube = m_surroundingChunks[3]->getCube(coords[i*3], coords[i*3 + 1] - CHUNK_DEPTH, coords[i*3 + 2]);
|
|
|
|
}
|
|
|
|
|
|
|
|
if ((coords[i*3 + 2] >= CHUNK_HEIGHT) && (m_surroundingChunks[4] != NULL)) {
|
|
|
|
cube = m_surroundingChunks[4]->getCube(coords[i*3], coords[i*3 + 1], coords[i*3 + 2] - CHUNK_HEIGHT);
|
|
|
|
}
|
|
|
|
else if ((coords[i*3 + 2] < 0) && (m_surroundingChunks[5] != NULL)) {
|
|
|
|
cube = m_surroundingChunks[5]->getCube(coords[i*3], coords[i*3 + 1], coords[i*3 + 2] + CHUNK_HEIGHT);
|
|
|
|
}
|
2013-03-09 03:23:13 +01:00
|
|
|
|
2013-03-07 07:58:55 +01:00
|
|
|
if ((cube == NULL) || (cube->type() == 0)) {
|
2013-03-11 02:05:34 +01:00
|
|
|
for(int j = 0 ; j < 4 ; j++) {
|
2013-03-07 07:58:55 +01:00
|
|
|
vertices.push_back(x + cubeCoords[(i * 12) + (j * 3)]);
|
|
|
|
vertices.push_back(y + cubeCoords[(i * 12) + (j * 3) + 1]);
|
|
|
|
vertices.push_back(z + cubeCoords[(i * 12) + (j * 3) + 2]);
|
2013-04-29 23:53:31 +02:00
|
|
|
texCoords.push_back(getTexOffsetU(qe->type(), i, qe) + (cubeCoords[48 + (j * 3)] * 0.125));
|
2013-03-10 16:15:24 +01:00
|
|
|
texCoords.push_back(getTexOffsetV(qe->type()) + (cubeCoords[48 + (j * 3) + 1] * 0.125));
|
2013-03-07 07:58:55 +01:00
|
|
|
colors.push_back(grey[i]);
|
|
|
|
colors.push_back(grey[i]);
|
|
|
|
colors.push_back(grey[i]);
|
|
|
|
colors.push_back(255);
|
|
|
|
|
|
|
|
m_vboVertexCount++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
glBindBuffer(GL_ARRAY_BUFFER, m_vboVertices);
|
|
|
|
glBufferData(GL_ARRAY_BUFFER, vertices.size() * sizeof(float), vertices.data(), GL_DYNAMIC_DRAW);
|
|
|
|
glBindBuffer(GL_ARRAY_BUFFER, m_vboTexCoords);
|
|
|
|
glBufferData(GL_ARRAY_BUFFER, texCoords.size() * sizeof(float), texCoords.data(), GL_DYNAMIC_DRAW);
|
|
|
|
glBindBuffer(GL_ARRAY_BUFFER, m_vboColors);
|
|
|
|
glBufferData(GL_ARRAY_BUFFER, colors.size() * sizeof(unsigned char), colors.data(), GL_DYNAMIC_DRAW);
|
|
|
|
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
|
|
|
|
|
|
|
vertices.clear();
|
|
|
|
texCoords.clear();
|
|
|
|
colors.clear();
|
|
|
|
}
|
|
|
|
|
|
|
|
void Chunk::render() {
|
|
|
|
if(m_vboVertexCount == 0) return;
|
|
|
|
|
|
|
|
glBindBuffer(GL_ARRAY_BUFFER, m_vboVertices);
|
|
|
|
glVertexPointer(3, GL_FLOAT, 0, 0);
|
|
|
|
glBindBuffer(GL_ARRAY_BUFFER, m_vboTexCoords);
|
|
|
|
glTexCoordPointer(2, GL_FLOAT, 0, 0);
|
|
|
|
glBindBuffer(GL_ARRAY_BUFFER, m_vboColors);
|
|
|
|
glColorPointer(4, GL_UNSIGNED_BYTE, 0, 0);
|
|
|
|
glDrawArrays(GL_QUADS, 0, m_vboVertexCount);
|
|
|
|
}
|
|
|
|
|