static void draw_object(int i, int j, int f, float a) { struct object *o = get_object(i); struct object_mesh *m = NULL; float alpha = get_entity_alpha(j) * a; init_object(i); glPushMatrix(); { /* Apply the local coordinate system transformation. */ transform_entity(j); /* Render this object. */ if (test_entity_aabb(j) >= 0) { glPushClientAttrib(GL_CLIENT_VERTEX_ARRAY_BIT); glPushAttrib(GL_LIGHTING_BIT | GL_TEXTURE_BIT); { int k, n = vecnum(o->mv); /* Bind a vertex buffer or array. */ if (GL_has_vertex_buffer_object) { glBindBufferARB(GL_ARRAY_BUFFER_ARB, o->buffer); draw_vert(0); } else draw_vert(vecget(o->vv, 0)); /* Draw each surface. */ for (k = 0; k < n; ++k) { m = (struct object_mesh *) vecget(o->mv, k); if (vecnum(m->fv) > 0 || vecnum(m->ev) > 0) draw_mesh(m, alpha); } } glPopAttrib(); glPopClientAttrib(); } /* Render all child entities in this coordinate system. */ draw_entity_tree(j, f, a * get_entity_alpha(j)); } glPopMatrix(); }
static void read_face_vertices(vector_t vv, const char *line) { const char *c = line; int dc; int vj, vc = vecnum(_vv); int uj, uc = vecnum(_uv); int nj, nc = vecnum(_nv); int i; /* Scan down the face string recording index set specifications. */ while ((dc = read_face_indices(c, &vj, &uj, &nj))) if ((i = vecadd(vv)) >= 0) { struct object_vert *v = (struct object_vert *) vecget(vv, i); /* Convert a face index to a vector index. */ int ui = (uj > 0) ? uj - 1 : uj + uc; int ni = (nj > 0) ? nj - 1 : nj + nc; int vi = (vj > 0) ? vj - 1 : vj + vc; /* Locate the indexed values in the vector caches. */ struct vec2 *up = (0 <= ui && ui < uc) ? vecget(_uv, ui) : NULL; struct vec3 *np = (0 <= ni && ni < nc) ? vecget(_nv, ni) : NULL; struct vec3 *vp = (0 <= vi && vi < vc) ? vecget(_vv, vi) : NULL; /* Initialize the new vertex, defaulting on bad input. */ v->u[0] = up ? up->u : 0.0f; v->u[1] = up ? up->v : 0.0f; v->n[0] = np ? np->x : 0.0f; v->n[1] = np ? np->y : 0.0f; v->n[2] = np ? np->z : 1.0f; v->v[0] = vp ? vp->x : 0.0f; v->v[1] = vp ? vp->y : 0.0f; v->v[2] = vp ? vp->z : 0.0f; /* Note bad indices. */ if (uj && !up) uerr++; if (nj && !np) nerr++; if (vj && !vp) verr++; c += dc; } }
static struct uniform *get_uniform(struct brush *b, const char *n) { struct uniform *u = NULL; /* Ensure that the uniform vector exists. */ if (b->uniform == NULL) b->uniform = vecnew(4, sizeof (struct uniform)); if (b->uniform) { int i; /* Search for an existing uniform of the given name. */ for (i = 0; i < vecnum(b->uniform); ++i) if (!strcmp(((struct uniform *) vecget(b->uniform, i))->name, n)) return (struct uniform *) vecget(b->uniform, i); /* This uniform does not exist. Create it. */ if ((u = (struct uniform *) vecget(b->uniform, vecadd(b->uniform)))) { u->name = memdup(n, 1, strlen(n) + 1); u->rows = 0; u->cols = 0; u->indx = 0; u->vals = NULL; } } return u; }
static void free_object(int i) { struct object *o = get_object(i); if (o->count > 0) { o->count--; if (o->count == 0) { int j; fini_object(i); for (j = 0; j < vecnum(o->mv); ++j) { struct object_mesh *m = vecget(o->mv, j); send_delete_brush(m->brush); vecdel(m->fv); vecdel(m->ev); } vecdel(o->vv); vecdel(o->mv); memset(o, 0, sizeof (struct object)); } } }
static void read_edge_vertices(vector_t vv, const char *line) { const char *c = line; int dc; int vj, vc = vecnum(_vv); int tj, tc = vecnum(_uv); int i; /* Scan down the face string recording index set specifications. */ while ((dc = read_edge_indices(c, &vj, &tj))) if ((i = vecadd(vv)) >= 0) { struct object_vert *v = (struct object_vert *) vecget(vv, i); /* Convert an edge index to a vector index. */ int ui = (tj > 0) ? tj - 1 : tj + tc; int vi = (vj > 0) ? vj - 1 : vj + vc; /* Locate the indexed values in the vector caches. */ struct vec2 *up = (0 <= ui && ui < tc) ? vecget(_uv, ui) : NULL; struct vec3 *vp = (0 <= vi && vi < vc) ? vecget(_vv, vi) : NULL; /* Initialize the new vertex, defaulting on bad input. */ v->u[0] = up ? up->u : 0.0f; v->u[1] = up ? up->v : 0.0f; v->n[0] = 0.0f; v->n[1] = 0.0f; v->n[2] = 1.0f; v->v[0] = vp ? vp->x : 0.0f; v->v[1] = vp ? vp->y : 0.0f; v->v[2] = vp ? vp->z : 0.0f; /* Note bad indices. */ if (tj && !up) uerr++; if (vj && !vp) verr++; c += dc; } }
static void calc_tbn(struct object *o) { int i; /* Compute tangent and bitangent for all vertices used by this object. */ for (i = 0; i < vecnum(o->mv); ++i) calc_mesh_tbn((const struct object_mesh *) vecget(o->mv, i), o->vv); /* Normalize all tangent and bitangent vectors. */ for (i = 0; i < vecnum(o->vv); ++i) { normalize(((struct object_vert *) vecget(o->vv, i))->t); normalize(((struct object_vert *) vecget(o->vv, i))->b); } }
void fini_brushes(void) { int i, n = vecnum(brush); for (i = 0; i < n; ++i) if (get_brush(i)->count) fini_brush(i); }
void nuke_brushes(void) { int i, n = vecnum(brush); for (i = 1; i < n; ++i) while (get_brush(i)->count) send_delete_brush(i); }
static void calc_mesh_tbn(const struct object_mesh *m, vector_t vv) { int i; /* Compute tangent and bitangent for all vertices used by this mesh. */ for (i = 0; i < vecnum(m->fv); ++i) calc_face_tbn((const struct object_face *) vecget(m->fv, i), vv); }
static int new_object(void) { int i, n = vecnum(object); for (i = 0; i < n; ++i) if (get_object(i)->count == 0) return i; return vecadd(object); }
static int new_sprite(void) { int i, n = vecnum(sprite); for (i = 0; i < n; ++i) if (get_sprite(i)->count == 0) return i; return vecadd(sprite); }
static int new_camera(void) { int i, n = vecnum(camera); for (i = 0; i < n; ++i) if (get_camera(i)->count == 0) return i; return vecadd(camera); }
static int new_brush(void) { int i, n = vecnum(brush); for (i = 0; i < n; ++i) if (get_brush(i)->count == 0) return i; return vecadd(brush); }
static int new_galaxy(void) { int i, n = vecnum(galaxy); for (i = 0; i < n; ++i) if (get_galaxy(i)->count == 0) return i; return vecadd(galaxy); }
static void delete_vert(int i, int j) { struct object *o = get_object(i); int k; int l; /* Remove this vertex from the vertex vector. */ memmove(vecget(o->vv, j), vecget(o->vv, j + 1), vecsiz(o->vv) * (vecnum(o->vv) - j - 1)); vecpop(o->vv); /* Remove all references to this vertex from all meshes. */ for (k = 0; k < get_mesh_count(i); ++k) { /* Delete all referencing faces. Move later references down. */ for (l = 0; l < get_face_count(i, k); ++l) { struct object_face *f = get_object_face(i, k, l); if (f->vi[0] == j || f->vi[1] == j || f->vi[2] == j) delete_face(i, k, l--); else { if (f->vi[0] > j) f->vi[0]--; if (f->vi[1] > j) f->vi[1]--; if (f->vi[2] > j) f->vi[2]--; } } /* Delete all referencing edges. Move later references down. */ for (l = 0; l < get_edge_count(i, k); ++l) { struct object_edge *e = get_object_edge(i, k, l); if (e->vi[0] == j || e->vi[1] == j) delete_edge(i, k, l--); else { if (e->vi[0] > j) e->vi[0]--; if (e->vi[1] > j) e->vi[1]--; } } } /* Invalidate the object's vertex buffer and bounding volume. */ fini_object(i); }
static int free_brush(int i) { struct brush *b = get_brush(i); struct uniform *u; if (i > 0) { if (b->count > 0) { b->count--; if (b->count == 0) { fini_brush(i); /* Release all uniforms. */ if (b->uniform) { for (i = 0; i < vecnum(b->uniform); ++i) { u = (struct uniform *) vecget(b->uniform, i); if (u->name) free(u->name); if (u->vals) free(u->vals); } vecdel(b->uniform); } /* Release all string buffers. */ if (b->file) free(b->file); if (b->name) free(b->name); if (b->frag) free(b->frag); if (b->vert) free(b->vert); if (b->vert_text) free(b->vert_text); if (b->frag_text) free(b->frag_text); /* Release all images. */ if (b->image[0]) send_delete_image(b->image[0]); if (b->image[1]) send_delete_image(b->image[1]); if (b->image[2]) send_delete_image(b->image[2]); if (b->image[3]) send_delete_image(b->image[3]); memset(b, 0, sizeof (struct brush)); return 1; } } } return 0; }
static void delete_face(int i, int j, int k) { struct object_mesh *m = get_object_mesh(i, j); /* Remove this face from the face vector. */ memmove(vecget(m->fv, k), vecget(m->fv, k + 1), vecsiz(m->fv) * (vecnum(m->fv) - k - 1)); vecpop(m->fv); }
static void read_l(vector_t vv, vector_t ev, const char *line) { int i, i0, i1, j; /* Scan down the edge string recording index set specifications. */ i0 = vecnum(vv); read_edge_vertices(vv, line); i1 = vecnum(vv); /* Convert our N new vertices into N-1 new edges. */ for (i = i0; i < i1 - 1; ++i) if ((j = vecadd(ev)) >= 0) { struct object_edge *e = (struct object_edge *) vecget(ev, j); e->vi[0] = i; e->vi[1] = i + 1; } }
void init_brush(int i) { struct brush *b = get_brush(i); if (b->state == 0) { int p; /* Initialize and vertex and fragment shaders and uniforms. */ if (GL_has_shader_objects) { if (b->vert_text) b->vert_shad = opengl_shader_object(GL_VERTEX_SHADER_ARB, b->vert_text); if (b->frag_text) b->frag_shad = opengl_shader_object(GL_FRAGMENT_SHADER_ARB, b->frag_text); if (b->vert_shad || b->frag_shad) b->shad_prog = opengl_program_object(b->vert_shad, b->frag_shad); if (b->shad_prog && b->uniform) for (p = 0; p < vecnum(b->uniform); ++p) use_uniform(b, (struct uniform *) vecget(b->uniform, p)); } /* Initialize any vertex program and parameters. */ if (b->vert && GL_has_vertex_program) { b->vert_prog = opengl_vert_prog(b->vert); for (p = 0; p < MAX_PARAM; ++p) glProgramLocalParameter4fvARB(GL_VERTEX_PROGRAM_ARB, p, b->vert_param[p]); } /* Initialize any fragment program and parameters. */ if (b->frag && GL_has_fragment_program) { b->frag_prog = opengl_frag_prog(b->frag); for (p = 0; p < MAX_PARAM; ++p) glProgramLocalParameter4fvARB(GL_FRAGMENT_PROGRAM_ARB, p, b->frag_param[p]); } b->state = 1; } }
static void read_f(vector_t vv, vector_t fv, const char *line) { int i, i0, i1, j; /* Scan down the face string recording index set specifications. */ i0 = vecnum(vv); read_face_vertices(vv, line); i1 = vecnum(vv); /* Convert our N new vertices into N-2 new triangles. */ for (i = i0; i < i1 - 2; ++i) if ((j = vecadd(fv)) >= 0) { struct object_face *f = (struct object_face *) vecget(fv, j); f->vi[0] = i0; f->vi[1] = i + 1; f->vi[2] = i + 2; } }
static void aabb_object(int i, float aabb[6]) { struct object *o = get_object(i); /* If the bounding box cache is invalid... */ if (o->aabb_state == 0) { int j, n = vecnum(o->vv); /* Find the object's bounding box. */ if (n > 0) { const float *v = ((struct object_vert *) vecget(o->vv, 0))->v; o->aabb_cache[0] = v[0]; o->aabb_cache[1] = v[1]; o->aabb_cache[2] = v[2]; o->aabb_cache[3] = v[0]; o->aabb_cache[4] = v[1]; o->aabb_cache[5] = v[2]; } else memset(o->aabb_cache, 0, 6 * sizeof (float)); for (j = 0; j < n; ++j) { const float *v = ((struct object_vert *) vecget(o->vv, j))->v; o->aabb_cache[0] = MIN(v[0], o->aabb_cache[0]); o->aabb_cache[1] = MIN(v[1], o->aabb_cache[1]); o->aabb_cache[2] = MIN(v[2], o->aabb_cache[2]); o->aabb_cache[3] = MAX(v[0], o->aabb_cache[3]); o->aabb_cache[4] = MAX(v[1], o->aabb_cache[4]); o->aabb_cache[5] = MAX(v[2], o->aabb_cache[5]); } o->aabb_state = 1; } /* Return the current bounding box. */ aabb[0] = o->aabb_cache[0]; aabb[1] = o->aabb_cache[1]; aabb[2] = o->aabb_cache[2]; aabb[3] = o->aabb_cache[3]; aabb[4] = o->aabb_cache[4]; aabb[5] = o->aabb_cache[5]; }
static void delete_mesh(int i, int j) { struct object *o = get_object(i); struct object_mesh *m = get_object_mesh(i, j); /* Release this mesh's resources. */ vecdel(m->fv); vecdel(m->ev); /* Remove this mesh from the mesh vector. */ memmove(vecget(o->mv, j), vecget(o->mv, j + 1), vecsiz(o->mv) * (vecnum(o->mv) - j - 1)); vecpop(o->mv); }
/* * Attach the found massbuss adapter. Setup its interrupt vectors, * reset it and go searching for drives on it. */ void mbaattach(device_t parent, device_t self, void *aux) { struct mba_softc * const sc = device_private(self); struct sbi_attach_args * const sa = aux; struct mba_attach_args ma; int i, j; aprint_normal("\n"); sc->sc_dev = self; sc->sc_iot = sa->sa_iot; sc->sc_ioh = sa->sa_ioh; /* * Set up interrupt vectors for this MBA. */ for (i = 0x14; i < 0x18; i++) scb_vecalloc(vecnum(0, i, sa->sa_nexnum), mbaintr, sc, SCB_ISTACK, &sc->sc_intrcnt); evcnt_attach_dynamic(&sc->sc_intrcnt, EVCNT_TYPE_INTR, NULL, device_xname(self), "intr"); STAILQ_INIT(&sc->sc_xfers); MBA_WCSR(MBA_CR, MBACR_INIT); /* Reset adapter */ MBA_WCSR(MBA_CR, MBACR_IE); /* Enable interrupts */ for (i = 0; i < MAXMBADEV; i++) { sc->sc_state = SC_AUTOCONF; if ((MBA_RCSR(MUREG(i, MU_DS)) & MBADS_DPR) == 0) continue; /* We have a drive, ok. */ ma.ma_unit = i; ma.ma_type = MBA_RCSR(MUREG(i, MU_DT)) & 0xf1ff; for (j = 0; mbaunit[j].nr; j++) if (mbaunit[j].nr == ma.ma_type) break; ma.ma_devtyp = mbaunit[j].devtyp; ma.ma_name = mbaunit[j].name; ma.ma_iot = sc->sc_iot; ma.ma_ioh = sc->sc_ioh + MUREG(i, 0); config_found(sc->sc_dev, &ma, mbaprint); } }
static void init_object(int i) { struct object *o = get_object(i); if (o->state == 0) { /* Initialize the buffer object. */ if (GL_has_vertex_buffer_object) { glGenBuffersARB(1, &o->buffer); glBindBufferARB(GL_ARRAY_BUFFER_ARB, o->buffer); glBufferDataARB(GL_ARRAY_BUFFER_ARB, vecnum(o->vv) * sizeof (struct object_vert), vecbuf(o->vv), GL_STATIC_DRAW_ARB); } o->state = 1; } }
int send_create_object(const char *filename) { int i; if ((i = new_object()) >= 0) { struct object *o = get_object(i); struct object_mesh *m = NULL; if (read_obj(filename, o)) { int j, n = vecnum(o->mv); o->count = 1; /* Send the object header. */ send_event(EVENT_CREATE_OBJECT); send_index(n); /* Send the vertices and meshes. */ send_vector(o->vv); for (j = 0; j < n; ++j) { m = (struct object_mesh *) vecget(o->mv, j); send_index (m->brush); send_vector(m->fv); send_vector(m->ev); } /* Encapsulate this object in an entity. */ return send_create_entity(TYPE_OBJECT, i); } } return -1; }
static void draw_mesh(const struct object_mesh *m, float alpha) { glPushAttrib(GL_TEXTURE_BIT); { int transparent = draw_brush(m->brush, alpha); /* If this object is transparent then don't write depth. */ /* Render back and front faces separately. */ if (transparent) { glPushAttrib(GL_DEPTH_BUFFER_BIT); glDepthMask(GL_FALSE); glCullFace(GL_FRONT); if (vecnum(m->fv) > 0) glDrawElements(GL_TRIANGLES, 3 * vecnum(m->fv), GL_UNSIGNED_INT, vecbuf(m->fv)); glCullFace(GL_BACK); } /* Render all faces and edges. */ if (vecnum(m->fv) > 0) glDrawElements(GL_TRIANGLES, 3 * vecnum(m->fv), GL_UNSIGNED_INT, vecbuf(m->fv)); if (vecnum(m->ev) > 0) glDrawElements(GL_LINES, 2 * vecnum(m->ev), GL_UNSIGNED_INT, vecbuf(m->ev)); if (transparent) glPopAttrib(); if (GL_has_shader_objects) glUseProgramObjectARB(0); } glPopAttrib(); }
int get_edge_count(int i, int j) { return vecnum(get_object_mesh(i, j)->ev); }
int get_face_count(int i, int j) { return vecnum(get_object_mesh(i, j)->fv); }
int get_vert_count(int i) { return vecnum(get_object(i)->vv); }
int get_mesh_count(int i) { return vecnum(get_object(i)->mv); }