eqemu

view src/mesh.cc @ 12:2656099aff12

added copyright notices and license
author John Tsiombikas <nuclear@member.fsf.org>
date Fri, 18 Jul 2014 07:04:21 +0300
parents 3d3656360a82
children
line source
1 /*
2 eqemu - electronic queue system emulator
3 Copyright (C) 2014 John Tsiombikas <nuclear@member.fsf.org>,
4 Eleni-Maria Stea <eleni@mutantstargoat.com>
6 This program is free software: you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation, either version 3 of the License, or
9 (at your option) any later version.
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with this program. If not, see <http://www.gnu.org/licenses/>.
18 */
19 #include <stdio.h>
20 #include <string.h>
21 #include <math.h>
22 #include <GL/glew.h>
23 #include "mesh.h"
25 #define ALL_VALID 0xffffffff
27 Mesh::Mesh()
28 {
29 buf_valid = ALL_VALID;
30 bsph_valid = false;
32 for(int i=0; i<NUM_MESH_ATTRIBS; i++) {
33 attr[i] = 0;
34 attr_size[i] = 0;
35 buf_valid &= ~(1 << i);
36 }
37 vcount = 0;
38 glGenBuffers(NUM_MESH_ATTRIBS, vbo);
39 }
41 Mesh::~Mesh()
42 {
43 for(int i=0; i<NUM_MESH_ATTRIBS; i++) {
44 delete [] attr[i];
45 }
46 glDeleteBuffers(NUM_MESH_ATTRIBS, vbo);
47 }
49 float *Mesh::set_attrib(int aidx, int count, int elemsz, float *data)
50 {
51 delete [] attr[aidx];
52 attr[aidx] = new float[count * elemsz];
53 memcpy(attr[aidx], data, count * elemsz * sizeof *data);
54 vcount = count;
55 attr_size[aidx] = elemsz;
56 buf_valid &= ~(1 << aidx);
58 if(aidx == MESH_ATTR_VERTEX) {
59 bsph_valid = false;
60 }
62 return attr[aidx];
63 }
65 float *Mesh::get_attrib(int aidx)
66 {
67 buf_valid &= ~(1 << aidx);
68 if(aidx == MESH_ATTR_VERTEX) {
69 bsph_valid = false;
70 }
71 return attr[aidx];
72 }
74 const float *Mesh::get_attrib(int aidx) const
75 {
76 return attr[aidx];
77 }
79 void Mesh::draw() const
80 {
81 if(!vcount) return;
83 update_buffers();
85 if(!vbo[MESH_ATTR_VERTEX]) {
86 fprintf(stderr, "trying to render without a vertex buffer\n");
87 return;
88 }
90 glBindBuffer(GL_ARRAY_BUFFER, vbo[MESH_ATTR_VERTEX]);
91 glEnableClientState(GL_VERTEX_ARRAY);
92 glVertexPointer(attr_size[MESH_ATTR_VERTEX], GL_FLOAT, 0, 0);
94 if(vbo[MESH_ATTR_NORMAL]) {
95 glBindBuffer(GL_ARRAY_BUFFER, vbo[MESH_ATTR_NORMAL]);
96 glEnableClientState(GL_NORMAL_ARRAY);
97 glNormalPointer(GL_FLOAT, 0, 0);
98 }
99 if(vbo[MESH_ATTR_TEXCOORD]) {
100 glBindBuffer(GL_ARRAY_BUFFER, vbo[MESH_ATTR_TEXCOORD]);
101 glEnableClientState(GL_TEXTURE_COORD_ARRAY);
102 glTexCoordPointer(attr_size[MESH_ATTR_TEXCOORD], GL_FLOAT, 0, 0);
103 }
104 glBindBuffer(GL_ARRAY_BUFFER, 0);
106 glDrawArrays(GL_TRIANGLES, 0, vcount);
108 glDisableClientState(GL_VERTEX_ARRAY);
109 if(vbo[MESH_ATTR_NORMAL]) {
110 glDisableClientState(GL_NORMAL_ARRAY);
111 }
112 if(vbo[MESH_ATTR_TEXCOORD]) {
113 glDisableClientState(GL_TEXTURE_COORD_ARRAY);
114 }
115 }
117 BSphere &Mesh::get_bounds()
118 {
119 calc_bsph();
120 return bsph;
121 }
123 const BSphere &Mesh::get_bounds() const
124 {
125 calc_bsph();
126 return bsph;
127 }
129 void Mesh::update_buffers() const
130 {
131 if(buf_valid == ALL_VALID) {
132 return;
133 }
135 for(int i=0; i<NUM_MESH_ATTRIBS; i++) {
136 if((buf_valid & (1 << i)) == 0) {
137 glBindBuffer(GL_ARRAY_BUFFER, vbo[i]);
138 glBufferData(GL_ARRAY_BUFFER, vcount * attr_size[i] * sizeof(float),
139 attr[i], GL_STATIC_DRAW);
140 buf_valid |= 1 << i;
141 }
142 }
143 }
145 void Mesh::calc_bsph() const
146 {
147 if(bsph_valid || !vcount) {
148 return;
149 }
151 Vector3 center;
153 float *vptr = attr[MESH_ATTR_VERTEX];
154 for(int i=0; i<vcount; i++) {
155 center = center + Vector3(vptr[0], vptr[1], vptr[2]);
156 vptr += 3;
157 }
158 center = center * (1.0f / (float)vcount);
160 float max_lensq = 0.0f;
161 vptr = attr[MESH_ATTR_VERTEX];
162 for(int i=0; i<vcount; i++) {
163 Vector3 v = Vector3(vptr[0], vptr[1], vptr[2]) - center;
164 float lensq = dot(v, v);
165 if(lensq > max_lensq) {
166 max_lensq = lensq;
167 }
168 }
170 bsph.set_center(center);
171 bsph.set_radius(sqrt(max_lensq));
173 bsph_valid = true;
174 }