eqemu

view src/mesh.cc @ 4:3d3656360a82

rendering properly, added picking, almost done...
author John Tsiombikas <nuclear@member.fsf.org>
date Thu, 17 Jul 2014 08:51:17 +0300
parents f9274bebe55e
children 2656099aff12
line source
1 #include <stdio.h>
2 #include <string.h>
3 #include <math.h>
4 #include <GL/glew.h>
5 #include "mesh.h"
7 #define ALL_VALID 0xffffffff
9 Mesh::Mesh()
10 {
11 buf_valid = ALL_VALID;
12 bsph_valid = false;
14 for(int i=0; i<NUM_MESH_ATTRIBS; i++) {
15 attr[i] = 0;
16 attr_size[i] = 0;
17 buf_valid &= ~(1 << i);
18 }
19 vcount = 0;
20 glGenBuffers(NUM_MESH_ATTRIBS, vbo);
21 }
23 Mesh::~Mesh()
24 {
25 for(int i=0; i<NUM_MESH_ATTRIBS; i++) {
26 delete [] attr[i];
27 }
28 glDeleteBuffers(NUM_MESH_ATTRIBS, vbo);
29 }
31 float *Mesh::set_attrib(int aidx, int count, int elemsz, float *data)
32 {
33 delete [] attr[aidx];
34 attr[aidx] = new float[count * elemsz];
35 memcpy(attr[aidx], data, count * elemsz * sizeof *data);
36 vcount = count;
37 attr_size[aidx] = elemsz;
38 buf_valid &= ~(1 << aidx);
40 if(aidx == MESH_ATTR_VERTEX) {
41 bsph_valid = false;
42 }
44 return attr[aidx];
45 }
47 float *Mesh::get_attrib(int aidx)
48 {
49 buf_valid &= ~(1 << aidx);
50 if(aidx == MESH_ATTR_VERTEX) {
51 bsph_valid = false;
52 }
53 return attr[aidx];
54 }
56 const float *Mesh::get_attrib(int aidx) const
57 {
58 return attr[aidx];
59 }
61 void Mesh::draw() const
62 {
63 if(!vcount) return;
65 update_buffers();
67 if(!vbo[MESH_ATTR_VERTEX]) {
68 fprintf(stderr, "trying to render without a vertex buffer\n");
69 return;
70 }
72 glBindBuffer(GL_ARRAY_BUFFER, vbo[MESH_ATTR_VERTEX]);
73 glEnableClientState(GL_VERTEX_ARRAY);
74 glVertexPointer(attr_size[MESH_ATTR_VERTEX], GL_FLOAT, 0, 0);
76 if(vbo[MESH_ATTR_NORMAL]) {
77 glBindBuffer(GL_ARRAY_BUFFER, vbo[MESH_ATTR_NORMAL]);
78 glEnableClientState(GL_NORMAL_ARRAY);
79 glNormalPointer(GL_FLOAT, 0, 0);
80 }
81 if(vbo[MESH_ATTR_TEXCOORD]) {
82 glBindBuffer(GL_ARRAY_BUFFER, vbo[MESH_ATTR_TEXCOORD]);
83 glEnableClientState(GL_TEXTURE_COORD_ARRAY);
84 glTexCoordPointer(attr_size[MESH_ATTR_TEXCOORD], GL_FLOAT, 0, 0);
85 }
86 glBindBuffer(GL_ARRAY_BUFFER, 0);
88 glDrawArrays(GL_TRIANGLES, 0, vcount);
90 glDisableClientState(GL_VERTEX_ARRAY);
91 if(vbo[MESH_ATTR_NORMAL]) {
92 glDisableClientState(GL_NORMAL_ARRAY);
93 }
94 if(vbo[MESH_ATTR_TEXCOORD]) {
95 glDisableClientState(GL_TEXTURE_COORD_ARRAY);
96 }
97 }
99 BSphere &Mesh::get_bounds()
100 {
101 calc_bsph();
102 return bsph;
103 }
105 const BSphere &Mesh::get_bounds() const
106 {
107 calc_bsph();
108 return bsph;
109 }
111 void Mesh::update_buffers() const
112 {
113 if(buf_valid == ALL_VALID) {
114 return;
115 }
117 for(int i=0; i<NUM_MESH_ATTRIBS; i++) {
118 if((buf_valid & (1 << i)) == 0) {
119 glBindBuffer(GL_ARRAY_BUFFER, vbo[i]);
120 glBufferData(GL_ARRAY_BUFFER, vcount * attr_size[i] * sizeof(float),
121 attr[i], GL_STATIC_DRAW);
122 buf_valid |= 1 << i;
123 }
124 }
125 }
127 void Mesh::calc_bsph() const
128 {
129 if(bsph_valid || !vcount) {
130 return;
131 }
133 Vector3 center;
135 float *vptr = attr[MESH_ATTR_VERTEX];
136 for(int i=0; i<vcount; i++) {
137 center = center + Vector3(vptr[0], vptr[1], vptr[2]);
138 vptr += 3;
139 }
140 center = center * (1.0f / (float)vcount);
142 float max_lensq = 0.0f;
143 vptr = attr[MESH_ATTR_VERTEX];
144 for(int i=0; i<vcount; i++) {
145 Vector3 v = Vector3(vptr[0], vptr[1], vptr[2]) - center;
146 float lensq = dot(v, v);
147 if(lensq > max_lensq) {
148 max_lensq = lensq;
149 }
150 }
152 bsph.set_center(center);
153 bsph.set_radius(sqrt(max_lensq));
155 bsph_valid = true;
156 }