eqemu

diff src/mesh.cc @ 3:f9274bebe55e

adding 3d graphics stuff
author John Tsiombikas <nuclear@member.fsf.org>
date Thu, 17 Jul 2014 02:35:19 +0300
parents
children 3d3656360a82
line diff
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/src/mesh.cc	Thu Jul 17 02:35:19 2014 +0300
     1.3 @@ -0,0 +1,101 @@
     1.4 +#include <stdio.h>
     1.5 +#include <string.h>
     1.6 +#include <GL/glew.h>
     1.7 +#include "mesh.h"
     1.8 +
     1.9 +#define ALL_VALID	0xffffffff
    1.10 +
    1.11 +Mesh::Mesh()
    1.12 +{
    1.13 +	buf_valid = ALL_VALID;
    1.14 +
    1.15 +	for(int i=0; i<vcount; i++) {
    1.16 +		attr[i] = 0;
    1.17 +		attr_size[i] = 0;
    1.18 +		buf_valid &= ~(1 << i);
    1.19 +	}
    1.20 +	vcount = 0;
    1.21 +	glGenBuffers(NUM_MESH_ATTRIBS, vbo);
    1.22 +}
    1.23 +
    1.24 +Mesh::~Mesh()
    1.25 +{
    1.26 +	for(int i=0; i<vcount; i++) {
    1.27 +		delete [] attr[i];
    1.28 +	}
    1.29 +	glDeleteBuffers(NUM_MESH_ATTRIBS, vbo);
    1.30 +}
    1.31 +
    1.32 +float *Mesh::set_attrib(int aidx, int count, int elemsz, float *data)
    1.33 +{
    1.34 +	if(attr[aidx]) {
    1.35 +		delete [] attr[aidx];
    1.36 +	}
    1.37 +	attr[aidx] = new float[count * elemsz];
    1.38 +	attr_size[aidx] = elemsz;
    1.39 +	buf_valid &= ~(1 << aidx);
    1.40 +	return attr[aidx];
    1.41 +}
    1.42 +
    1.43 +float *Mesh::get_attrib(int aidx)
    1.44 +{
    1.45 +	buf_valid &= ~(1 << aidx);
    1.46 +	return attr[aidx];
    1.47 +}
    1.48 +
    1.49 +const float *Mesh::get_attrib(int aidx) const
    1.50 +{
    1.51 +	return attr[aidx];
    1.52 +}
    1.53 +
    1.54 +void Mesh::draw() const
    1.55 +{
    1.56 +	update_buffers();
    1.57 +
    1.58 +	if(!vbo[MESH_ATTR_VERTEX]) {
    1.59 +		fprintf(stderr, "trying to render without a vertex buffer\n");
    1.60 +		return;
    1.61 +	}
    1.62 +
    1.63 +	glBindBuffer(GL_ARRAY_BUFFER, vbo[MESH_ATTR_VERTEX]);
    1.64 +	glEnableClientState(GL_VERTEX_ARRAY);
    1.65 +	glVertexPointer(attr_size[MESH_ATTR_VERTEX], GL_FLOAT, 0, 0);
    1.66 +
    1.67 +	if(vbo[MESH_ATTR_NORMAL]) {
    1.68 +		glBindBuffer(GL_ARRAY_BUFFER, vbo[MESH_ATTR_NORMAL]);
    1.69 +		glEnableClientState(GL_NORMAL_ARRAY);
    1.70 +		glNormalPointer(GL_FLOAT, 0, 0);
    1.71 +	}
    1.72 +	if(vbo[MESH_ATTR_TEXCOORD]) {
    1.73 +		glBindBuffer(GL_ARRAY_BUFFER, vbo[MESH_ATTR_TEXCOORD]);
    1.74 +		glEnableClientState(GL_TEXTURE_COORD_ARRAY);
    1.75 +		glTexCoordPointer(attr_size[MESH_ATTR_TEXCOORD], GL_FLOAT, 0, 0);
    1.76 +	}
    1.77 +	glBindBuffer(GL_ARRAY_BUFFER, 0);
    1.78 +
    1.79 +	glDrawArrays(GL_TRIANGLES, 0, vcount);
    1.80 +
    1.81 +	glDisableClientState(GL_VERTEX_ARRAY);
    1.82 +	if(vbo[MESH_ATTR_NORMAL]) {
    1.83 +		glDisableClientState(GL_NORMAL_ARRAY);
    1.84 +	}
    1.85 +	if(vbo[MESH_ATTR_TEXCOORD]) {
    1.86 +		glDisableClientState(GL_TEXTURE_COORD_ARRAY);
    1.87 +	}
    1.88 +}
    1.89 +
    1.90 +void Mesh::update_buffers() const
    1.91 +{
    1.92 +	if(buf_valid == ALL_VALID) {
    1.93 +		return;
    1.94 +	}
    1.95 +
    1.96 +	for(int i=0; i<NUM_MESH_ATTRIBS; i++) {
    1.97 +		if((buf_valid & (1 << i)) == 0) {
    1.98 +			glBindBuffer(GL_ARRAY_BUFFER, vbo[i]);
    1.99 +			glBufferData(GL_ARRAY_BUFFER, vcount * attr_size[i] * sizeof(float),
   1.100 +					attr[i], GL_STATIC_DRAW);
   1.101 +			buf_valid |= 1 << i;
   1.102 +		}
   1.103 +	}
   1.104 +}