typedef struct { DerivedMesh dm; MVert *mvert; MEdge *medge; MFace *mface; } CDDerivedMesh; typedef struct { float color[4]; float active[4]; float selected[4]; float object[4]; } DrawColors; void set_lambert_param(Mesh *mesh, MFace *face); void set_draw_color(Object *obj, MFace *face, DrawColors *colors); void create_vertex(Object *obj, MVert *vert, int index, int flag); void draw_outline(Base *base, Object *obj, DrawColors *colors); void draw_mesh_selected_outline(Mesh *mesh, Object *obj); void drawVertex(Object *obj, float orig[3]); void insertVertex(Object *obj, MVert *vert); void insertNormal(Object *obj, short orig[3]); void get_colors(DrawColors *colors); void get_material_color(Material *mat, DrawColors *colors); void get_light0(Object *obj); void get_light(Object *obj); float vec[3]; void create_vertex(Object *obj, MVert *vert, int index, int flag) { if(flag & ME_SMOOTH){ short *no = vert[index].no; // float nvect[3] = { ((float) no[0]) / 32767.0f, ((float) no[1]) / 32767.0f, ((float) no[2]) / 32767.0f }; // Mat4MulVecfl(obj->obmat, nvect); glNormal3sv(no); } // float vect[3] = {vert[index].co[0], vert[index].co[1], vert[index].co[2] }; // Mat4MulVecfl(obj->obmat, vect); glVertex3fv(vert[index].co); } void draw_outline(Base *base, Object *obj, DrawColors *colors) { Mesh *mesh = obj->data; glDisable(GL_DEPTH_TEST); if(obj == OBACT || (base->flag & (SELECT+BA_WAS_SEL))){ if(obj == OBACT) glColor4fv(colors->active); else glColor4fv(colors->selected); glLineWidth(2.0); draw_mesh_selected_outline(mesh, obj); glLineWidth(1.0); } glEnable(GL_DEPTH_TEST); } void set_draw_color(Object *obj, MFace *face, DrawColors *colors) { Material *mat; Mesh *mesh = obj->data; if(BTST(obj->colbits, face->mat_nr)){ mat = obj->mat[face->mat_nr]; get_material_color(mat, colors); glColor4fv(colors->color); } else if(mesh->mat){ mat = mesh->mat[face->mat_nr]; get_material_color(mat, colors); glColor4fv(colors->color); } else{ glColor4fv(colors->object); } } void set_lambert_param(Mesh *mesh, MFace *face) { Material *mat; GLint location = get_lambert_ref(); int error; if(location == -1) exit(0); if(mesh->mat){ mat = mesh->mat[face->mat_nr]; glUniform1fARB(location, mat->ref); } else glUniform1fARB(location, 0.8); } void glsl_draw_mesh(Base *base){ Object *ob = base->object, *ol; DerivedMesh *dm= mesh_get_derived_final(ob, get_viewedit_datamask()); CDDerivedMesh *cddm = (CDDerivedMesh *) dm; MFace *face = cddm->mface; MVert *vert = cddm->mvert; bScreen *bs= G.curscreen; Scene *scene= bs->scene; DrawColors colors; Base *b = scene->base.first; float *nors = dm->getFaceDataArray(dm, CD_NORMAL); int i; get_colors(&colors); // draw_outline(base, ob, &colors); glMatrixMode(GL_MODELVIEW); glPushMatrix(); // glLoadIdentity(); glMultMatrixf(ob->obmat); glShadeModel(face->flag & ME_SMOOTH?GL_SMOOTH:GL_FLAT); glUseProgramObjectARB(get_material_shader()); while(b != NULL){ Object *obj = b->object; if(obj->type == OB_LAMP){ ol = obj; get_light(ol); break; } b = b->next; } for(i = 0; i < dm->numFaceData; i++, face++){ set_lambert_param(ob->data, face); set_draw_color(ob, face, &colors); glBegin(face->v4?GL_QUADS:GL_TRIANGLES); if(!(face->flag & ME_SMOOTH)){ if(nors){ float vect[3] = { nors[0], nors[1], nors[2] }; // Mat4MulVecfl(ob->obmat, vect); glNormal3fv(nors); } else{ float nor[3]; if(face->v4) { CalcNormFloat4(vert[face->v1].co, vert[face->v2].co, vert[face->v3].co, vert[face->v4].co, nor); } else { CalcNormFloat(vert[face->v1].co, vert[face->v2].co, vert[face->v3].co, nor); } // Mat4MulVecfl(ob->obmat, nor); glNormal3fv(nor); } } create_vertex(ob, vert, face->v1, face->flag); create_vertex(ob, vert, face->v2, face->flag); create_vertex(ob, vert, face->v3, face->flag); if(face->v4) create_vertex(ob, vert, face->v4, face->flag); if(nors) nors += 3; glEnd(); } glUseProgramObjectARB (0); glShadeModel(GL_FLAT); glPopMatrix(); } void draw_mesh_selected_outline(Mesh *mesh, Object *obj) { MEdge *edge; MVert *v1, *v2; int i; glBegin(GL_LINES); for(i = 0; i < mesh->totedge; i++){ edge = &mesh->medge[i]; v1 = &mesh->mvert[edge->v1]; v2 = &mesh->mvert[edge->v2]; glVertex3fv(v1->co); glVertex3fv(v2->co); } glEnd(); glLineWidth(1.0); } void get_light(Object *obj) { int loc = get_light0_location(); glUniform3fv(loc, 1, obj->loc); } void get_light0(Object *obj) { int loc = get_light0_location(); SolidLight light = U.light[0]; glUniform4f(loc, light.vec[0], light.vec[1], light.vec[2], light.vec[3]); } void get_colors(DrawColors *colors) { bTheme *bt = U.themes.first; ThemeSpace ts = bt->tv3d; int i; for(i = 0; i < 4; i++){ colors->active[i] = ts.active[i] / 255.0; colors->selected[i] = ts.select[i] / 255.0; colors->object[i] = ts.shade1[i] / 255.0; } } void insertNormal(Object *obj, short orig[3]) { int i; for(i = 0; i < 3; i++){ vec[i] = ((float) orig[i]) / 32767.0; } Mat4MulVecfl(obj->obmat, vec); glNormal3fv(vec); } void get_material_color(Material *mat, DrawColors *colors) { colors->color[0] = mat->r; colors->color[1] = mat->g; colors->color[2] = mat->b; colors->color[3] = mat->alpha; } /***********/ /* SHADERS */ /***********/ /* Vertex Shader */ varying vec3 normal, pos; void main() { normal = normalize(gl_NormalMatrix * gl_Normal); gl_FrontColor = gl_Color; gl_Position = ftransform(); pos = gl_ModelViewMatrix * gl_Vertex; } /* Fragment Shader */ uniform float ref; uniform vec3 light0; varying vec3 normal, pos; void main(){ vec3 lightVec = normalize(light0 - pos); float NdotL = max(dot(normal, lightVec), 0.0); gl_FragColor = gl_Color * NdotL * ref; }