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 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_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 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 Val * randstruct(int depth) { Val *r, *p; int i, n; char buff[1024]; r = gcmalloc(sizeof(Val)); r->t = STRUCT; r->Cstruct.members = vec(); n = rand() % MAXSTRUCTM; for(i = 0; i < n; i++) vecappend(r->Cstruct.members, randval(depth + 1)); snprintf(buff, sizeof buff, "s%d", structcount++); r->Cstruct.name = gcstrdup(buff); printf("struct %s {\n", r->Cstruct.name); for(i = 0; i < r->Cstruct.members->len; i++) { p = vecget(r->Cstruct.members, i); printf("\t"); printvaltype(p); printf(" m%d;\n", i); } printf("};\n"); return r; }
void recv_create_object(void) { /* Unpack the object header. */ int i = new_object(); int n = recv_index(); int j, k; struct object *o = get_object(i); struct object_mesh *m = NULL; o->count = 1; /* Unpack the vertices and meshes. */ o->vv = recv_vector(); o->mv = vecnew(n, sizeof (struct object_mesh)); for (j = 0; j < n; ++j) if ((k = vecadd(o->mv)) >= 0) { m = (struct object_mesh *) vecget(o->mv, k); m->brush = recv_index(); m->fv = recv_vector(); m->ev = recv_vector(); } /* Encapsulate this object in an entity. */ recv_create_entity(); }
static void call(Node *n) { int i, nargs, nintargs, cleanup; Vec *args; Node *arg; args = n->Call.args; i = nargs = args->len; /* Push args in reverse order */ while(i-- != 0) { arg = vecget(args, i); if(!isitype(arg->type) && !isptr(arg->type) && !isarray(arg->type) && !isfunc(arg->type)) errorposf(&arg->pos, "unimplemented arg type\n"); expr(arg); pushq("rax"); } nintargs = nargs; if(nintargs > 6) nintargs = 6; for(i = 0; i < nintargs; i++) popq(intargregs[i]); expr(n->Call.funclike); outi("call *%%rax\n"); cleanup = 8 * (nargs - nintargs); if(cleanup) { outi("add $%d, %%rsp\n", cleanup); stackoffset -= cleanup; } }
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); } }
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); }
static void comma(Node *n) { int i; for(i = 0; i < n->Comma.exprs->len; i++) { expr(vecget(n->Comma.exprs, i)); } }
NUMBER matrix2get( MATRIX *pmatrix, int row, int column){ VECTOR *pvec; NUMBER val; assert( row >=0); assert( row < (pmatrix->count) ); pvec = (pmatrix->list)[row]; val = vecget( pvec, column); return(val); }
void emitend() { int i; out(".data\n\n"); for(i = 0; i < pendingdata->len; i++) data(vecget(pendingdata, 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 void read_v(const char *line) { int i; if ((i = vecadd(_vv)) >= 0) { struct vec3 *vp = (struct vec3 *) vecget(_vv, i); sscanf(line, "%f %f %f", &vp->x, &vp->y, &vp->z); } }
static void read_vt(const char *line) { int i; if ((i = vecadd(_uv)) >= 0) { struct vec2 *up = (struct vec2 *) vecget(_uv, i); sscanf(line, "%f %f", &up->u, &up->v); } }
static void block(Node *n) { Vec *v; int i; v = n->Block.stmts; for(i = 0; i < v->len ; i++) { stmt(vecget(v, i)); } }
static void decl(Node *n) { int i; Sym *sym; for(i = 0; i < n->Decl.syms->len; i++) { sym = vecget(n->Decl.syms, i); emitsym(sym); } }
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; }
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 addtentativesym(Sym *sym) { int i; Sym *s; for(i = 0; i < tentativesyms->len; i++) { s = vecget(tentativesyms, i); if(s == sym) return; } vecappend(tentativesyms, sym); }
static void data(Data *d) { InitMember *initmemb; int i, offset; char *l; if(!d->init) { out(".comm %s, %d, %d\n", d->label, d->type->size, d->type->align); return; } if(d->isglobal) out(".globl %s\n", d->label); out("%s:\n", d->label); if(ischararray(d->type)) if(d->init->t == NSTR) { out(".string %s\n", d->init->Str.v); return; } if(ischarptr(d->type)) if(d->init->t == NSTR) { l = newlabel(); out(".quad %s\n", l); out("%s:\n", l); out(".string %s\n", d->init->Str.v); return; } if(isitype(d->type) || isptr(d->type)) { itypedata(d->init); return; } if(isarray(d->type) || isstruct(d->type)) { if(d->init->t != NINIT) errorposf(&d->init->pos, "array/struct expects a '{' style initializer"); offset = 0; for(i = 0; i < d->init->Init.inits->len ; i++) { initmemb = vecget(d->init->Init.inits, i); if(initmemb->offset != offset) out(".fill %d, 1, 0\n", initmemb->offset - offset); itypedata(initmemb->n); offset = initmemb->offset + initmemb->n->type->size; } if(offset < d->type->size) out(".fill %d, 1, 0\n", d->type->size - offset); return; } panic("internal error"); }
void addstructmember(SrcPos *pos, CTy *t, char *name, CTy *membt) { StructMember *sm, *subsm; int i, align, sz; sm = gcmalloc(sizeof(StructMember)); sm->name = name; sm->type = membt; if(!isstruct(t)) panic("internal error"); if(sm->name == 0 && isstruct(sm->type)) { for(i = 0; i < sm->type->Struct.members->len; i++) { subsm = vecget(sm->type->Struct.members, i); addstructmember(pos, t, subsm->name, subsm->type); } return; } if(sm->name) { for(i = 0; i < t->Struct.members->len; i++) { subsm = vecget(t->Struct.members, i); if(subsm->name) if(strcmp(sm->name, subsm->name) == 0) errorposf(pos ,"struct already has a member named %s", sm->name); } } if(membt->align < t->align) t->align = membt->align; sz = t->size; align = membt->align; if(sz % align) sz = sz + align - (sz % align); sm->offset = sz; sz += sm->type->size; t->size = sz; vecappend(t->Struct.members, sm); }
/* TODO: proper efficient set for tentative syms */ static void removetentativesym(Sym *sym) { int i; Vec *newv; Sym *s; newv = vec(); for(i = 0; i < tentativesyms->len; i++) { s = vecget(tentativesyms, i); if(s == sym) continue; vecappend(newv, s); } tentativesyms = newv; }
static void func(Node *f, char *label, int isglobal) { Vec *v; Sym *sym; int i; calcslotoffsets(f); out("\n"); out(".text\n"); out("# function %s\n", f->Func.name); if(isglobal) out(".globl %s\n", label); out("%s:\n", label); pushq("rbp"); outi("movq %%rsp, %%rbp\n"); if(f->type->Func.isvararg) { stackoffset += 176; outi("sub $176, %%rsp\n"); outi("movq %%rdi, (%%rsp)\n"); outi("movq %%rsi, 8(%%rsp)\n"); outi("movq %%rdx, 16(%%rsp)\n"); outi("movq %%rcx, 24(%%rsp)\n"); outi("movq %%r8, 32(%%rsp)\n"); outi("movq %%r9, 40(%%rsp)\n"); } if(f->Func.localsz) { outi("sub $%d, %%rsp\n", f->Func.localsz); stackoffset += f->Func.localsz; } v = f->Func.params; for(i = 0; i < v->len; i++) { sym = vecget(v, i); if(!isitype(sym->type) && !isptr(sym->type) && !isarray(sym->type)) errorposf(&f->pos, "unimplemented arg type"); if(i < 6) { outi("movq %%%s, %d(%%rbp)\n", intargregs[i], sym->Local.slot->offset); } else { outi("movq %d(%%rbp), %%rcx\n", 16 + 8 * (i - 6)); outi("leaq %d(%%rbp), %%rax\n", sym->Local.slot->offset); store(sym->type); } } block(f->Func.body); outi("leave\n"); outi("ret\n"); }
StructMember * getstructmember(CTy *t, char *n) { int i; StructMember *sm; if(isptr(t)) t = t->Ptr.subty; if(!isstruct(t)) panic("internal error"); for(i = 0; i < t->Struct.members->len; i++) { sm = vecget(t->Struct.members, i); if(strcmp(n, sm->name) == 0) return sm; } return 0; }
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 parse() { int i; Sym *sym; switchdepth = 0; brkdepth = 0; contdepth = 0; nscopes = 0; tentativesyms = vec(); pushscope(); next(); next(); while(tok->k != TOKEOF) decl(); for(i = 0; i < tentativesyms->len; i++) { sym = vecget(tentativesyms, i); emitsym(sym); } }
static struct object_mesh *read_usemtl(vector_t mv, const char *line, const char *file) { int i; if ((i = vecadd(mv)) >= 0) { struct object_mesh *m = (struct object_mesh *) vecget(mv, i); if (line) m->brush = send_create_brush(file, parse_name(line)); else m->brush = 0; m->fv = vecnew(0, sizeof (struct object_face)); m->ev = vecnew(0, sizeof (struct object_edge)); return m; } return NULL; }