imbusy GSoC'09 branch merge (Vertex Buffer Object support)

This commit is contained in:
Lukas Steiblys 2009-10-03 15:35:01 +00:00
parent 8204dffe8a
commit e80d2cc426
19 changed files with 3127 additions and 376 deletions

View File

@ -314,6 +314,7 @@ class USERPREF_PT_system(bpy.types.Panel):
sub1.itemL(text="OpenGL:")
sub1.itemR(system, "clip_alpha", slider=True)
sub1.itemR(system, "use_mipmaps")
sub1.itemR(system, "use_vbos")
sub1.itemL(text="Window Draw Method:")
sub1.row().itemR(system, "window_draw_method", expand=True)
sub1.itemL(text="Textures:")

View File

@ -58,6 +58,7 @@ struct ModifierData;
struct MCol;
struct ColorBand;
struct GPUVertexAttribs;
struct GPUDrawObject;
/* number of sub-elements each mesh element has (for interpolation) */
#define SUB_ELEMS_VERT 0
@ -72,6 +73,7 @@ struct DerivedMesh {
int needsFree; /* checked on ->release, is set to 0 for cached results */
int deformedOnly; /* set by modifier stack if only deformed from original */
BVHCache bvhCache;
struct GPUDrawObject *drawObject;
/* Misc. Queries */

View File

@ -88,6 +88,8 @@ typedef struct SculptSession {
struct SculptStroke *stroke;
struct StrokeCache *cache;
struct GPUDrawObject *drawobject;
} SculptSession;
void free_sculptsession(SculptSession **);

View File

@ -84,6 +84,7 @@
#include "BIF_gl.h"
#include "BIF_glutil.h"
#include "gpu_buffers.h"
#include "GPU_draw.h"
#include "GPU_extensions.h"
#include "GPU_material.h"
@ -218,7 +219,7 @@ int DM_release(DerivedMesh *dm)
{
if (dm->needsFree) {
bvhcache_free(&dm->bvhCache);
GPU_drawobject_free( dm );
CustomData_free(&dm->vertData, dm->numVertData);
CustomData_free(&dm->edgeData, dm->numEdgeData);
CustomData_free(&dm->faceData, dm->numFaceData);
@ -491,14 +492,55 @@ static void emDM_drawMappedEdges(DerivedMesh *dm, int (*setDrawOptions)(void *us
}
glEnd();
} else {
glBegin(GL_LINES);
for(i=0,eed= emdm->em->edges.first; eed; i++,eed= eed->next) {
if(!setDrawOptions || setDrawOptions(userData, i)) {
glVertex3fv(eed->v1->co);
glVertex3fv(eed->v2->co);
}
GPUBuffer *buffer = 0;
float *varray;
if( setDrawOptions == 0 ) {
buffer = GPU_buffer_alloc( sizeof(float)*3*2*emdm->em->totedge, 0 );
}
glEnd();
if( buffer != 0 && (varray = GPU_buffer_lock_stream( buffer )) ) {
int prevdraw = 0;
int numedges = 0;
int draw = 0;
int datatype[] = { GPU_BUFFER_INTER_V3F, GPU_BUFFER_INTER_END };
GPU_buffer_unlock( buffer );
GPU_interleaved_setup( buffer, datatype );
varray = GPU_buffer_lock_stream( buffer );
for(i=0,eed= emdm->em->edges.first; eed; i++,eed= eed->next) {
if(!setDrawOptions || setDrawOptions(userData, i)) {
draw = 1;
} else {
draw = 0;
}
if( prevdraw != draw && prevdraw != 0 && numedges > 0) {
GPU_buffer_unlock( buffer );
glDrawArrays(GL_LINES,0,numedges*2);
varray = GPU_buffer_lock_stream( buffer );
numedges = 0;
}
if( draw != 0 ) {
VECCOPY(&varray[numedges*6],eed->v1->co);
VECCOPY(&varray[numedges*6+3],eed->v2->co);
numedges++;
}
prevdraw = draw;
}
GPU_buffer_unlock( buffer );
if( prevdraw != 0 && numedges > 0) {
glDrawArrays(GL_LINES,0,numedges*2);
}
GPU_buffer_unbind();
} else {
glBegin(GL_LINES);
for(i=0,eed= emdm->em->edges.first; eed; i++,eed= eed->next) {
if(!setDrawOptions || setDrawOptions(userData, i)) {
glVertex3fv(eed->v1->co);
glVertex3fv(eed->v2->co);
}
}
glEnd();
}
if( buffer != 0 )
GPU_buffer_free( buffer, 0 );
}
}
static void emDM_drawEdges(DerivedMesh *dm, int drawLooseEdges)
@ -627,8 +669,8 @@ static void emDM_drawMappedFaces(DerivedMesh *dm, int (*setDrawOptions)(void *us
draw = setDrawOptions==NULL ? 1 : setDrawOptions(userData, i, &drawSmooth);
if(draw) {
if (draw==2) { /* enabled with stipple */
glEnable(GL_POLYGON_STIPPLE);
glPolygonStipple(stipple_quarttone);
glEnable(GL_POLYGON_STIPPLE);
glPolygonStipple(stipple_quarttone);
}
glShadeModel(drawSmooth?GL_SMOOTH:GL_FLAT);
@ -659,41 +701,135 @@ static void emDM_drawMappedFaces(DerivedMesh *dm, int (*setDrawOptions)(void *us
}
}
} else {
for (i=0,efa= emdm->em->faces.first; efa; i++,efa= efa->next) {
int drawSmooth = (efa->flag & ME_SMOOTH);
draw = setDrawOptions==NULL ? 1 : setDrawOptions(userData, i, &drawSmooth);
if(draw) {
if (draw==2) { /* enabled with stipple */
glEnable(GL_POLYGON_STIPPLE);
glPolygonStipple(stipple_quarttone);
GPUBuffer *buffer = 0;
float *varray;
if( setDrawOptions == 0 ) {
/* 3 floats for position, 3 for normal and times two because the faces may actually be quads instead of triangles */
buffer = GPU_buffer_alloc( sizeof(float)*6*emdm->em->totface*3*2, 0 );
}
if( buffer != 0 && (varray = GPU_buffer_lock_stream( buffer )) ) {
int prevdraw = 0;
int numfaces = 0;
int datatype[] = { GPU_BUFFER_INTER_V3F, GPU_BUFFER_INTER_N3F, GPU_BUFFER_INTER_END };
GPU_buffer_unlock( buffer );
GPU_interleaved_setup( buffer, datatype );
glShadeModel(GL_SMOOTH);
varray = GPU_buffer_lock_stream( buffer );
for (i=0,efa= emdm->em->faces.first; efa; i++,efa= efa->next) {
int drawSmooth = (efa->flag & ME_SMOOTH);
draw = setDrawOptions==NULL ? 1 : setDrawOptions(userData, i, &drawSmooth);
if( prevdraw != draw && prevdraw != 0 && numfaces > 0) {
if( prevdraw==2 ) {
glEnable(GL_POLYGON_STIPPLE);
glPolygonStipple(stipple_quarttone);
}
GPU_buffer_unlock( buffer );
glDrawArrays(GL_TRIANGLES,0,numfaces*3);
if( prevdraw==2 ) {
glDisable(GL_POLYGON_STIPPLE);
}
varray = GPU_buffer_lock_stream( buffer );
numfaces = 0;
}
glShadeModel(drawSmooth?GL_SMOOTH:GL_FLAT);
if( draw != 0 ) {
if(!drawSmooth) {
VECCOPY(&varray[numfaces*18],efa->v1->co);
VECCOPY(&varray[numfaces*18+3],efa->n);
glBegin(efa->v4?GL_QUADS:GL_TRIANGLES);
if (!drawSmooth) {
glNormal3fv(efa->n);
glVertex3fv(efa->v1->co);
glVertex3fv(efa->v2->co);
glVertex3fv(efa->v3->co);
if(efa->v4) glVertex3fv(efa->v4->co);
} else {
glNormal3fv(efa->v1->no);
glVertex3fv(efa->v1->co);
glNormal3fv(efa->v2->no);
glVertex3fv(efa->v2->co);
glNormal3fv(efa->v3->no);
glVertex3fv(efa->v3->co);
if(efa->v4) {
glNormal3fv(efa->v4->no);
glVertex3fv(efa->v4->co);
VECCOPY(&varray[numfaces*18+6],efa->v2->co);
VECCOPY(&varray[numfaces*18+9],efa->n);
VECCOPY(&varray[numfaces*18+12],efa->v3->co);
VECCOPY(&varray[numfaces*18+15],efa->n);
numfaces++;
if( efa->v4 ) {
VECCOPY(&varray[numfaces*18],efa->v3->co);
VECCOPY(&varray[numfaces*18+3],efa->n);
VECCOPY(&varray[numfaces*18+6],efa->v4->co);
VECCOPY(&varray[numfaces*18+9],efa->n);
VECCOPY(&varray[numfaces*18+12],efa->v1->co);
VECCOPY(&varray[numfaces*18+15],efa->n);
numfaces++;
}
}
else {
VECCOPY(&varray[numfaces*18],efa->v1->co);
VECCOPY(&varray[numfaces*18+3],efa->v1->no);
VECCOPY(&varray[numfaces*18+6],efa->v2->co);
VECCOPY(&varray[numfaces*18+9],efa->v2->no);
VECCOPY(&varray[numfaces*18+12],efa->v3->co);
VECCOPY(&varray[numfaces*18+15],efa->v3->no);
numfaces++;
if( efa->v4 ) {
VECCOPY(&varray[numfaces*18],efa->v3->co);
VECCOPY(&varray[numfaces*18+3],efa->v3->no);
VECCOPY(&varray[numfaces*18+6],efa->v4->co);
VECCOPY(&varray[numfaces*18+9],efa->v4->no);
VECCOPY(&varray[numfaces*18+12],efa->v1->co);
VECCOPY(&varray[numfaces*18+15],efa->v1->no);
numfaces++;
}
}
}
glEnd();
if (draw==2)
prevdraw = draw;
}
GPU_buffer_unlock( buffer );
if( prevdraw != 0 && numfaces > 0) {
if( prevdraw==2 ) {
glEnable(GL_POLYGON_STIPPLE);
glPolygonStipple(stipple_quarttone);
}
glDrawArrays(GL_TRIANGLES,0,numfaces*3);
if( prevdraw==2 ) {
glDisable(GL_POLYGON_STIPPLE);
}
}
GPU_buffer_unbind();
} else {
for (i=0,efa= emdm->em->faces.first; efa; i++,efa= efa->next) {
int drawSmooth = (efa->flag & ME_SMOOTH);
draw = setDrawOptions==NULL ? 1 : setDrawOptions(userData, i, &drawSmooth);
if(draw) {
if (draw==2) { /* enabled with stipple */
glEnable(GL_POLYGON_STIPPLE);
glPolygonStipple(stipple_quarttone);
}
glShadeModel(drawSmooth?GL_SMOOTH:GL_FLAT);
glBegin(efa->v4?GL_QUADS:GL_TRIANGLES);
if (!drawSmooth) {
glNormal3fv(efa->n);
glVertex3fv(efa->v1->co);
glVertex3fv(efa->v2->co);
glVertex3fv(efa->v3->co);
if(efa->v4) glVertex3fv(efa->v4->co);
} else {
glNormal3fv(efa->v1->no);
glVertex3fv(efa->v1->co);
glNormal3fv(efa->v2->no);
glVertex3fv(efa->v2->co);
glNormal3fv(efa->v3->no);
glVertex3fv(efa->v3->co);
if(efa->v4) {
glNormal3fv(efa->v4->no);
glVertex3fv(efa->v4->co);
}
}
glEnd();
if (draw==2)
glDisable(GL_POLYGON_STIPPLE);
}
}
}
if( buffer != 0 )
GPU_buffer_free( buffer, 0 );
}
}

File diff suppressed because it is too large Load Diff

View File

@ -726,6 +726,10 @@ const LayerTypeInfo LAYERTYPEINFO[CD_NUMTYPES] = {
layerFree_mdisps, layerInterp_mdisps, layerSwap_mdisps, NULL},
{sizeof(MCol)*4, "MCol", 4, "WeightCol", NULL, NULL, layerInterp_mcol,
layerSwap_mcol, layerDefault_mcol},
{sizeof(MCol)*4, "MCol", 4, "IDCol", NULL, NULL, layerInterp_mcol,
layerSwap_mcol, layerDefault_mcol},
{sizeof(MCol)*4, "MCol", 4, "TexturedCol", NULL, NULL, layerInterp_mcol,
layerSwap_mcol, layerDefault_mcol},
};
const char *LAYERTYPENAMES[CD_NUMTYPES] = {

View File

@ -197,6 +197,7 @@ void gla2DSetMap(gla2DDrawInfo *di, struct rctf *rect);
/* use this for platform hacks. glPointSize is solved here */
void bglBegin(int mode);
void bglEnd(void);
int bglPointHack();
void bglVertex3fv(float *vec);
void bglVertex3f(float x, float y, float z);
void bglVertex2fv(float *vec);

View File

@ -720,6 +720,18 @@ void bglBegin(int mode)
}
}
int bglPointHack() {
float value[4];
int pointhack;
glGetFloatv(GL_POINT_SIZE_RANGE, value);
if(value[1]<2.0) {
glGetFloatv(GL_POINT_SIZE, value);
pointhack= floor(value[0]+0.5);
if(pointhack>4) pointhack= 4;
return pointhack;
}
return 0;
}
void bglVertex3fv(float *vec)
{

View File

@ -91,6 +91,7 @@
#include "RE_shader_ext.h" /*for multitex_ext*/
#include "GPU_draw.h"
#include "gpu_buffers.h"
#include <math.h>
#include <stdlib.h>
@ -304,21 +305,34 @@ static void calc_area_normal(Sculpt *sd, SculptSession *ss, float out[3], const
static void do_draw_brush(Sculpt *sd, SculptSession *ss, const ListBase* active_verts)
{
float area_normal[3];
int j;
ActiveData *node= active_verts->first;
float* buffer;
calc_area_normal(sd, ss, area_normal, active_verts);
buffer = (float *)GPU_buffer_lock( ss->drawobject->vertices );
while(node){
float *co= ss->mvert[node->Index].co;
const float val[3]= {co[0]+area_normal[0]*ss->cache->radius*node->Fade*ss->cache->scale[0],
co[1]+area_normal[1]*ss->cache->radius*node->Fade*ss->cache->scale[1],
co[2]+area_normal[2]*ss->cache->radius*node->Fade*ss->cache->scale[2]};
if( buffer != 0 ) {
IndexLink *cur = &ss->drawobject->indices[node->Index];
while( cur != 0 && cur->element != -1 ) {
sculpt_clip(sd, ss, &buffer[cur->element*3], val);
cur = cur->next;
}
}
sculpt_clip(sd, ss, co, val);
node= node->next;
}
if( buffer != 0 )
GPU_buffer_unlock( ss->drawobject->vertices );
}
/* For the smooth brush, uses the neighboring vertices around vert to calculate
@ -368,6 +382,7 @@ static void neighbor_average(SculptSession *ss, float avg[3], const int vert)
static void do_smooth_brush(Sculpt *s, SculptSession *ss, const ListBase* active_verts)
{
ActiveData *node= active_verts->first;
float *buffer = (float *)GPU_buffer_lock( ss->drawobject->vertices );
int i;
for(i = 0; i < 2; ++i) {
@ -380,24 +395,45 @@ static void do_smooth_brush(Sculpt *s, SculptSession *ss, const ListBase* active
val[1] = co[1]+(avg[1]-co[1])*node->Fade;
val[2] = co[2]+(avg[2]-co[2])*node->Fade;
sculpt_clip(s, ss, co, val);
sculpt_clip(s, ss, co, val);
if( buffer != 0 ) {
IndexLink *cur = &ss->drawobject->indices[node->Index];
while( cur != 0 && cur->element != -1 ) {
sculpt_clip(s, ss, &buffer[cur->element*3], val);
cur = cur->next;
}
}
node= node->next;
}
}
if( buffer != 0 )
GPU_buffer_unlock( ss->drawobject->vertices );
}
static void do_pinch_brush(Sculpt *s, SculptSession *ss, const ListBase* active_verts)
{
ActiveData *node= active_verts->first;
float *buffer = (float *)GPU_buffer_lock( ss->drawobject->vertices );
while(node) {
float *co= ss->mvert[node->Index].co;
const float val[3]= {co[0]+(ss->cache->location[0]-co[0])*node->Fade,
co[1]+(ss->cache->location[1]-co[1])*node->Fade,
co[2]+(ss->cache->location[2]-co[2])*node->Fade};
if( buffer != 0 ) {
IndexLink *cur = &ss->drawobject->indices[node->Index];
while( cur != 0 && cur->element != -1 ) {
sculpt_clip(s, ss, &buffer[cur->element*3], val);
cur = cur->next;
}
}
sculpt_clip(s, ss, co, val);
node= node->next;
}
if( buffer != 0 )
GPU_buffer_unlock( ss->drawobject->vertices );
}
static void do_grab_brush(Sculpt *sd, SculptSession *ss)
@ -405,6 +441,7 @@ static void do_grab_brush(Sculpt *sd, SculptSession *ss)
ActiveData *node= ss->cache->grab_active_verts[ss->cache->symmetry].first;
float add[3];
float grab_delta[3];
float *buffer = (float *)GPU_buffer_lock( ss->drawobject->vertices );
VecCopyf(grab_delta, ss->cache->grab_delta_symmetry);
@ -414,10 +451,21 @@ static void do_grab_brush(Sculpt *sd, SculptSession *ss)
VecCopyf(add, grab_delta);
VecMulf(add, node->Fade);
VecAddf(add, add, co);
if( buffer != 0 ) {
IndexLink *cur = &ss->drawobject->indices[node->Index];
while( cur != 0 && cur->element != -1 ) {
sculpt_clip(sd, ss, &buffer[cur->element*3], add);
cur = cur->next;
}
}
sculpt_clip(sd, ss, co, add);
node= node->next;
}
if( buffer != 0 )
GPU_buffer_unlock( ss->drawobject->vertices );
}
@ -425,6 +473,7 @@ static void do_layer_brush(Sculpt *sd, SculptSession *ss, const ListBase *active
{
float area_normal[3];
ActiveData *node= active_verts->first;
float *buffer;
float lim= ss->cache->radius / 4;
if(ss->cache->flip)
@ -432,6 +481,7 @@ static void do_layer_brush(Sculpt *sd, SculptSession *ss, const ListBase *active
calc_area_normal(sd, ss, area_normal, active_verts);
buffer = (float *)GPU_buffer_lock( ss->drawobject->vertices );
while(node){
float *disp= &ss->layer_disps[node->Index];
float *co= ss->mvert[node->Index].co;
@ -447,17 +497,28 @@ static void do_layer_brush(Sculpt *sd, SculptSession *ss, const ListBase *active
val[1] = ss->mesh_co_orig[node->Index][1]+area_normal[1] * *disp*ss->cache->scale[1];
val[2] = ss->mesh_co_orig[node->Index][2]+area_normal[2] * *disp*ss->cache->scale[2];
if( buffer != 0 ) {
IndexLink *cur = &ss->drawobject->indices[node->Index];
while( cur != 0 && cur->element != -1 ) {
sculpt_clip(sd, ss, &buffer[cur->element*3], val);
cur = cur->next;
}
}
sculpt_clip(sd, ss, co, val);
node= node->next;
}
if( buffer != 0 )
GPU_buffer_unlock( ss->drawobject->vertices );
}
static void do_inflate_brush(Sculpt *s, SculptSession *ss, const ListBase *active_verts)
{
ActiveData *node= active_verts->first;
float add[3];
float *buffer = (float *)GPU_buffer_lock( ss->drawobject->vertices );
while(node) {
float *co= ss->mvert[node->Index].co;
short *no= ss->mvert[node->Index].no;
@ -471,10 +532,20 @@ static void do_inflate_brush(Sculpt *s, SculptSession *ss, const ListBase *activ
add[2]*= ss->cache->scale[2];
VecAddf(add, add, co);
if( buffer != 0 ) {
IndexLink *cur = &ss->drawobject->indices[node->Index];
while( cur != 0 && cur->element != -1 ) {
sculpt_clip(s, ss, &buffer[cur->element*3], add);
cur = cur->next;
}
}
sculpt_clip(s, ss, co, add);
node= node->next;
}
if( buffer != 0 )
GPU_buffer_unlock( ss->drawobject->vertices );
}
static void calc_flatten_center(SculptSession *ss, ActiveData *node, float co[3])
@ -535,7 +606,7 @@ static void do_flatten_clay_brush(Sculpt *sd, SculptSession *ss, const ListBase
float area_normal[3];
float cntr[3], cntr2[3], bstr = 0;
int flip = 0;
float *buffer;
calc_area_normal(sd, ss, area_normal, active_verts);
calc_flatten_center(ss, node, cntr);
@ -547,7 +618,9 @@ static void do_flatten_clay_brush(Sculpt *sd, SculptSession *ss, const ListBase
cntr2[2]=cntr[2]+area_normal[2]*bstr*ss->cache->scale[2];
flip = bstr < 0;
}
buffer = (float *)GPU_buffer_lock( ss->drawobject->vertices );
while(node){
float *co= ss->mvert[node->Index].co;
float intr[3], val[3];
@ -573,11 +646,21 @@ static void do_flatten_clay_brush(Sculpt *sd, SculptSession *ss, const ListBase
VecAddf(val, val, co);
if( buffer != 0 ) {
IndexLink *cur = &ss->drawobject->indices[node->Index];
while( cur != 0 && cur->element != -1 ) {
sculpt_clip(sd, ss, &buffer[cur->element*3], val);
cur = cur->next;
}
}
sculpt_clip(sd, ss, co, val);
}
node= node->next;
}
if( buffer != 0 )
GPU_buffer_unlock( ss->drawobject->vertices );
}
/* Uses symm to selectively flip any axis of a coordinate. */
@ -898,7 +981,8 @@ static void add_face_normal(vec3f *norm, MVert *mvert, const MFace* face, float
static void update_damaged_vert(SculptSession *ss, ListBase *lb)
{
ActiveData *vert;
float *buffer = (float *)GPU_buffer_lock( ss->drawobject->normals );
for(vert= lb->first; vert; vert= vert->next) {
vec3f norm= {0,0,0};
IndexNode *face= ss->fmap[vert->Index].first;
@ -915,7 +999,32 @@ static void update_damaged_vert(SculptSession *ss, ListBase *lb)
ss->mvert[vert->Index].no[0]=norm.x*32767;
ss->mvert[vert->Index].no[1]=norm.y*32767;
ss->mvert[vert->Index].no[2]=norm.z*32767;
if( buffer != 0 ) {
IndexLink *cur = &ss->drawobject->indices[vert->Index];
while( cur != 0 && cur->element != -1 ) {
int i = ss->drawobject->faceRemap[cur->element/3];
if( ss->mface[i].flag & ME_SMOOTH ) {
VECCOPY(&buffer[cur->element*3],ss->mvert[vert->Index].no);
}
else {
float norm[3];
if( ss->mface[i].v4 )
CalcNormFloat4(ss->mvert[ss->mface[i].v1].co, ss->mvert[ss->mface[i].v2].co, ss->mvert[ss->mface[i].v3].co, ss->mvert[ss->mface[i].v4].co, norm);
else
CalcNormFloat(ss->mvert[ss->mface[i].v1].co, ss->mvert[ss->mface[i].v2].co, ss->mvert[ss->mface[i].v3].co, norm);
VECCOPY(&buffer[cur->element*3],norm);
VECCOPY(&buffer[cur->element*3],norm);
VECCOPY(&buffer[cur->element*3],norm);
}
//VECCOPY(&buffer[cur->element*3],ss->mvert[vert->Index].no);
cur = cur->next;
}
}
}
if( buffer != 0 )
GPU_buffer_unlock( ss->drawobject->normals );
}
static void calc_damaged_verts(SculptSession *ss)
@ -1004,9 +1113,10 @@ static void sculpt_update_mesh_elements(bContext *C)
Object *ob = CTX_data_active_object(C);
SculptSession *ss = ob->sculpt;
int oldtotvert = ss->totvert;
DerivedMesh *dm = mesh_get_derived_final(CTX_data_scene(C), ob, CD_MASK_BAREMESH);
if((ss->multires = sculpt_multires_active(ob))) {
DerivedMesh *dm = mesh_get_derived_final(CTX_data_scene(C), ob, CD_MASK_BAREMESH);
//DerivedMesh *dm = mesh_get_derived_final(CTX_data_scene(C), ob, CD_MASK_BAREMESH);
ss->totvert = dm->getNumVerts(dm);
ss->totface = dm->getNumFaces(dm);
ss->mvert = dm->getVertDataArray(dm, CD_MVERT);
@ -1021,6 +1131,12 @@ static void sculpt_update_mesh_elements(bContext *C)
ss->mface = me->mface;
ss->face_normals = NULL;
}
if( GPU_buffer_legacy( dm ) ) {
ss->drawobject = 0;
}
else {
ss->drawobject = dm->drawObject;
}
if(ss->totvert != oldtotvert) {
if(ss->projverts) MEM_freeN(ss->projverts);
@ -1332,16 +1448,27 @@ static void sculpt_restore_mesh(Sculpt *sd, SculptSession *ss)
{
StrokeCache *cache = ss->cache;
Brush *brush = paint_brush(&sd->paint);
float *buffer;
int i;
/* Restore the mesh before continuing with anchored stroke */
if((brush->flag & BRUSH_ANCHORED) && ss->mesh_co_orig) {
buffer = (float *)GPU_buffer_lock( ss->drawobject->normals );
for(i = 0; i < ss->totvert; ++i) {
VecCopyf(ss->mvert[i].co, ss->mesh_co_orig[i]);
ss->mvert[i].no[0] = cache->orig_norms[i][0];
ss->mvert[i].no[1] = cache->orig_norms[i][1];
ss->mvert[i].no[2] = cache->orig_norms[i][2];
if( buffer != 0 ) {
IndexLink *cur = &ss->drawobject->indices[i];
while( cur != 0 && cur->element != -1 ) {
VECCOPY(&buffer[cur->element*3],cache->orig_norms[i]);
cur = cur->next;
}
}
}
if( buffer != 0 )
GPU_buffer_unlock( ss->drawobject->normals );
if(ss->face_normals) {
float *fn = ss->face_normals;

View File

@ -70,6 +70,7 @@
#include "UI_resources.h"
#include "UI_interface_icons.h"
#include "gpu_buffers.h"
#include "GPU_extensions.h"
#include "GPU_draw.h"
@ -398,8 +399,7 @@ static void draw_textured_end()
glPopMatrix();
}
static int draw_tface__set_draw(MTFace *tface, MCol *mcol, int matnr)
static int draw_tface__set_draw_legacy(MTFace *tface, MCol *mcol, int matnr)
{
if (tface && (tface->mode&TF_INVISIBLE)) return 0;
@ -421,6 +421,87 @@ static int draw_tface__set_draw(MTFace *tface, MCol *mcol, int matnr)
return 1; /* Set color from mcol */
}
}
static int draw_tface__set_draw(MTFace *tface, MCol *mcol, int matnr)
{
if (tface && (tface->mode&TF_INVISIBLE)) return 0;
if (tface && set_draw_settings_cached(0, Gtexdraw.istex, tface, Gtexdraw.islit, Gtexdraw.ob, matnr, TF_TWOSIDE)) {
return 2; /* Don't set color */
} else if (tface && tface->mode&TF_OBCOL) {
return 2; /* Don't set color */
} else if (!mcol) {
return 2; /* Don't set color */
} else {
return 1; /* Set color from mcol */
}
}
static void add_tface_color_layer(DerivedMesh *dm)
{
MTFace *tface = DM_get_face_data_layer(dm, CD_MTFACE);
MFace *mface = DM_get_face_data_layer(dm, CD_MFACE);
MCol *finalCol;
int i,j;
MCol *mcol = dm->getFaceDataArray(dm, CD_WEIGHT_MCOL);
if(!mcol)
mcol = dm->getFaceDataArray(dm, CD_MCOL);
finalCol = MEM_mallocN(sizeof(MCol)*4*dm->getNumFaces(dm),"add_tface_color_layer");
for(i=0;i<dm->getNumFaces(dm);i++) {
if (tface && (tface->mode&TF_INVISIBLE)) {
if( mcol )
memcpy(&finalCol[i*4],&mcol[i*4],sizeof(MCol)*4);
else
for(j=0;j<4;j++) {
finalCol[i*4+j].b = 255;
finalCol[i*4+j].g = 255;
finalCol[i*4+j].r = 255;
}
}
else if (tface && mface && set_draw_settings_cached(0, Gtexdraw.istex, tface, Gtexdraw.islit, Gtexdraw.ob, mface[i].mat_nr, TF_TWOSIDE)) {
for(j=0;j<4;j++) {
finalCol[i*4+j].b = 255;
finalCol[i*4+j].g = 0;
finalCol[i*4+j].r = 255;
}
} else if (tface && tface->mode&TF_OBCOL) {
for(j=0;j<4;j++) {
finalCol[i*4+j].r = Gtexdraw.obcol[0];
finalCol[i*4+j].g = Gtexdraw.obcol[1];
finalCol[i*4+j].b = Gtexdraw.obcol[2];
}
} else if (!mcol) {
if (tface) {
for(j=0;j<4;j++) {
finalCol[i*4+j].b = 255;
finalCol[i*4+j].g = 255;
finalCol[i*4+j].r = 255;
}
}
else {
Material *ma= give_current_material(Gtexdraw.ob, mface[i].mat_nr+1);
if(ma)
for(j=0;j<4;j++) {
finalCol[i*4+j].b = ma->b;
finalCol[i*4+j].g = ma->g;
finalCol[i*4+j].r = ma->r;
}
else
for(j=0;j<4;j++) {
finalCol[i*4+j].b = 255;
finalCol[i*4+j].g = 255;
finalCol[i*4+j].r = 255;
}
}
} else {
for(j=0;j<4;j++) {
finalCol[i*4+j].b = mcol[i*4+j].r;
finalCol[i*4+j].g = mcol[i*4+j].g;
finalCol[i*4+j].r = mcol[i*4+j].b;
}
}
}
CustomData_add_layer( &dm->faceData, CD_TEXTURE_MCOL, CD_ASSIGN, finalCol, dm->numFaceData );
}
static int draw_tface_mapped__set_draw(void *userData, int index)
{
@ -561,6 +642,7 @@ void draw_mesh_textured(Scene *scene, View3D *v3d, RegionView3D *rv3d, Object *o
draw_textured_begin(scene, v3d, rv3d, ob);
if(ob == scene->obedit) {
glColor4f(1.0f,1.0f,1.0f,1.0f);
dm->drawMappedFacesTex(dm, draw_em_tf_mapped__set_draw, me->edit_mesh);
} else if(faceselect) {
if(ob->mode & OB_MODE_WEIGHT_PAINT)
@ -569,7 +651,14 @@ void draw_mesh_textured(Scene *scene, View3D *v3d, RegionView3D *rv3d, Object *o
dm->drawMappedFacesTex(dm, draw_tface_mapped__set_draw, me);
}
else {
dm->drawFacesTex(dm, draw_tface__set_draw);
if( GPU_buffer_legacy(dm) )
dm->drawFacesTex(dm, draw_tface__set_draw_legacy);
else {
glColor4f(1.0f,1.0f,1.0f,1.0f);
if( !CustomData_has_layer(&dm->faceData,CD_TEXTURE_MCOL) )
add_tface_color_layer(dm);
dm->drawFacesTex(dm, draw_tface__set_draw);
}
}
/* draw game engine text hack */

View File

@ -102,6 +102,7 @@
#include "GPU_draw.h"
#include "GPU_material.h"
#include "GPU_extensions.h"
#include "gpu_buffers.h"
#include "ED_mesh.h"
#include "ED_particle.h"
@ -113,6 +114,7 @@
#include "UI_interface_icons.h"
#include "WM_api.h"
#include "wm_subwindow.h"
#include "BLF_api.h"
#include "view3d_intern.h" // own include
@ -1550,15 +1552,72 @@ static void draw_dm_verts__mapFunc(void *userData, int index, float *co, float *
}
}
}
/* originally defined in DerivedMesh.c */
typedef struct {
DerivedMesh dm;
EditMesh *em;
float (*vertexCos)[3];
float (*vertexNos)[3];
float (*faceNos)[3];
} EditMeshDerivedMesh;
static void draw_dm_verts(DerivedMesh *dm, int sel, EditVert *eve_act)
{
struct { int sel; EditVert *eve_act; } data;
GPUBuffer *buffer;
float *varray;
data.sel = sel;
data.eve_act = eve_act;
bglBegin(GL_POINTS);
dm->foreachMappedVert(dm, draw_dm_verts__mapFunc, &data);
bglEnd();
/* first come the unselected vertices, then the selected */
buffer = GPU_buffer_alloc( sizeof(float)*3*dm->getNumVerts(dm)*2, 0 );
if( (varray = GPU_buffer_lock_stream( buffer )) && bglPointHack() == 0 ) {
EditMeshDerivedMesh *emdm= (EditMeshDerivedMesh*) dm;
EditVert *eve;
int i;
int numverts = 0, numselected = 0;
int datatype[] = { GPU_BUFFER_INTER_V3F, GPU_BUFFER_INTER_END };
GPU_buffer_unlock( buffer );
GPU_interleaved_setup( buffer, datatype );
varray = GPU_buffer_lock_stream( buffer );
glBegin(GL_POINTS);
for (i=0,eve= emdm->em->verts.first; eve; i++,eve=eve->next) {
if (eve->h==0 && (eve->f&SELECT)==data.sel) {
if (eve==data.eve_act) {
if (emdm->vertexCos) {
VECCOPY(&varray[3*(dm->getNumVerts(dm)+numselected)],emdm->vertexCos[i]);
}
else {
VECCOPY(&varray[3*(dm->getNumVerts(dm)+numselected)],eve->co);
}
numselected++;
} else {
if (emdm->vertexCos) {
VECCOPY(&varray[3*numverts],emdm->vertexCos[i]);
} else {
VECCOPY(&varray[3*numverts],eve->co);
}
numverts++;
}
}
}
glEnd();
GPU_buffer_unlock( buffer );
glDrawArrays(GL_POINTS,0,numverts);
UI_ThemeColor4(TH_EDITMESH_ACTIVE);
glDrawArrays(GL_POINTS,dm->getNumVerts(dm),numselected);
UI_ThemeColor4(data.sel?TH_VERTEX_SELECT:TH_VERTEX);
GPU_buffer_unbind();
}
else {
bglBegin(GL_POINTS);
dm->foreachMappedVert(dm, draw_dm_verts__mapFunc, &data);
bglEnd();
}
GPU_buffer_free( buffer, 0 );
}
/* Draw edges with color set based on selection */
@ -1626,12 +1685,57 @@ static void draw_dm_edges_sel_interp__setDrawInterpOptions(void *userData, int i
col0[2] + (col1[2]-col0[2])*t,
col0[3] + (col1[3]-col0[3])*t);
}
static void draw_dm_edges_sel_interp(DerivedMesh *dm, unsigned char *baseCol, unsigned char *selCol)
{
unsigned char *cols[2];
int elemsize = sizeof(float)*3+sizeof(unsigned char)*4;
EditMeshDerivedMesh *emdm = (EditMeshDerivedMesh *)dm;
EditMesh *em= emdm->em;
unsigned char *varray;
int i;
GPUBuffer *buffer;
cols[0] = baseCol;
cols[1] = selCol;
dm->drawMappedEdgesInterp(dm, draw_dm_edges_sel_interp__setDrawOptions, draw_dm_edges_sel_interp__setDrawInterpOptions, cols);
buffer = GPU_buffer_alloc( elemsize*em->totedge*2, 0 );
if( (varray = GPU_buffer_lock_stream( buffer )) ) {
EditEdge *eed;
int numedges = 0;
int datatype[] = { GPU_BUFFER_INTER_V3F, GPU_BUFFER_INTER_C4UB, GPU_BUFFER_INTER_END };
GPU_buffer_unlock( buffer );
GPU_interleaved_setup( buffer, datatype );
varray = GPU_buffer_lock_stream( buffer );
for (i=0,eed= em->edges.first; eed; i++,eed= eed->next) {
if(eed->h==0) {
unsigned char *col0 = cols[(eed->v1->f&SELECT)?1:0];
unsigned char *col1 = cols[(eed->v2->f&SELECT)?1:0];
if( emdm->vertexCos ) {
VECCOPY(((float *)&varray[elemsize*numedges*2]),emdm->vertexCos[(int) eed->v1->tmp.l]);
}
else {
VECCOPY(((float *)&varray[elemsize*numedges*2]),eed->v1->co);
}
QUATCOPY(&varray[elemsize*numedges*2+sizeof(float)*3],col0);
if( emdm->vertexCos ) {
VECCOPY(((float *)&varray[elemsize*numedges*2+elemsize]),emdm->vertexCos[(int) eed->v2->tmp.l]);
}
else {
VECCOPY(((float *)&varray[elemsize*numedges*2+elemsize]),eed->v2->co);
}
QUATCOPY(&varray[elemsize*numedges*2+elemsize+sizeof(float)*3],col1);
numedges++;
}
}
GPU_buffer_unlock( buffer );
glDrawArrays(GL_LINES,0,numedges*2);
GPU_buffer_unbind();
}
else {
dm->drawMappedEdgesInterp(dm, draw_dm_edges_sel_interp__setDrawOptions, draw_dm_edges_sel_interp__setDrawInterpOptions, cols);
}
GPU_buffer_free( buffer, 0 );
}
/* Draw only seam edges */
@ -1685,12 +1789,237 @@ static int draw_dm_faces_sel__setDrawOptions(void *userData, int index, int *dra
static void draw_dm_faces_sel(DerivedMesh *dm, unsigned char *baseCol, unsigned char *selCol, unsigned char *actCol, EditFace *efa_act)
{
struct { unsigned char *cols[3]; EditFace *efa_act; } data;
//EditMeshDerivedMesh *emdm = (EditMeshDerivedMesh *)dm;
EditFace *efa;
unsigned char *col;
unsigned char *colors;
GPUBuffer *buffer;
unsigned char *varray;
unsigned char black[] = { 0, 0, 0, 0 };
int i,j,draw=0;
int elemsize = (sizeof(float)*6+sizeof(unsigned char)*4);
data.cols[0] = baseCol;
data.cols[1] = selCol;
data.cols[2] = actCol;
data.efa_act = efa_act;
dm->drawMappedFaces(dm, draw_dm_faces_sel__setDrawOptions, &data, 0);
buffer = GPU_buffer_alloc( elemsize*dm->getNumFaces(dm)*3*2, 0 );
if( dm->getVertCos == 0 && (varray = GPU_buffer_lock_stream( buffer )) ) {
int prevdraw = 0;
int numfaces = 0;
int datatype[] = { GPU_BUFFER_INTER_V3F, GPU_BUFFER_INTER_N3F, GPU_BUFFER_INTER_C4UB, GPU_BUFFER_INTER_END };
GPU_buffer_unlock( buffer );
GPU_interleaved_setup( buffer, datatype );
glShadeModel(GL_SMOOTH);
varray = GPU_buffer_lock_stream( buffer );
for (i=0,efa= efa_act; efa; i++,efa= efa->next) {
int drawSmooth = (efa->flag & ME_SMOOTH);
if (efa->h==0) {
if (efa == data.efa_act) {
draw = 2;
} else {
col = data.cols[(efa->f&SELECT)?1:0];
if (col[3]==0) draw = 0;
else draw = 1;
}
}
else {
draw = 0;
}
if( prevdraw != draw && prevdraw != 0 && numfaces > 0) {
if( prevdraw==2 ) {
glEnable(GL_POLYGON_STIPPLE);
glPolygonStipple(stipple_quarttone);
}
GPU_buffer_unlock( buffer );
glDrawArrays(GL_TRIANGLES,0,numfaces*3);
if( prevdraw==2 ) {
glDisable(GL_POLYGON_STIPPLE);
}
varray = GPU_buffer_lock_stream( buffer );
numfaces = 0;
}
if( draw != 0 ) {
if(!drawSmooth) {
/*if (emdm->vertexCos) {
VECCOPY((float *)&varray[elemsize*3*numfaces],emdm->vertexCos[(int) efa->v1->tmp.l]);
VECCOPY((float *)&varray[elemsize*3*numfaces+sizeof(float)*3],emdm->faceNos[i]);
VECCOPY((float *)&varray[elemsize*3*numfaces+elemsize],emdm->vertexCos[(int) efa->v2->tmp.l]);
VECCOPY((float *)&varray[elemsize*3*numfaces+elemsize+sizeof(float)*3],emdm->faceNos[i]);
VECCOPY((float *)&varray[elemsize*3*numfaces+elemsize*2],emdm->vertexCos[(int) efa->v3->tmp.l]);
VECCOPY((float *)&varray[elemsize*3*numfaces+elemsize*2+sizeof(float)*3],emdm->faceNos[i]);
}
else {*/
VECCOPY((float *)&varray[elemsize*3*numfaces],efa->v1->co);
VECCOPY((float *)&varray[elemsize*3*numfaces+sizeof(float)*3],efa->n);
VECCOPY((float *)&varray[elemsize*3*numfaces+elemsize],efa->v2->co);
VECCOPY((float *)&varray[elemsize*3*numfaces+elemsize+sizeof(float)*3],efa->n);
VECCOPY((float *)&varray[elemsize*3*numfaces+elemsize*2],efa->v3->co);
VECCOPY((float *)&varray[elemsize*3*numfaces+elemsize*2+sizeof(float)*3],efa->n);
/*}*/
if( draw == 2 ) {
QUATCOPY(&varray[elemsize*3*numfaces+sizeof(float)*6],data.cols[2]);
QUATCOPY(&varray[elemsize*3*numfaces+elemsize+sizeof(float)*6],data.cols[2]);
QUATCOPY(&varray[elemsize*3*numfaces+elemsize*2+sizeof(float)*6],data.cols[2]);
}
else if( draw == 1 ) {
QUATCOPY(&varray[elemsize*3*numfaces+sizeof(float)*6],data.cols[(efa->f&SELECT)?1:0]);
QUATCOPY(&varray[elemsize*3*numfaces+elemsize+sizeof(float)*6],data.cols[(efa->f&SELECT)?1:0]);
QUATCOPY(&varray[elemsize*3*numfaces+elemsize*2+sizeof(float)*6],data.cols[(efa->f&SELECT)?1:0]);
}
else {
QUATCOPY(&varray[elemsize*3*numfaces+sizeof(float)*6],black);
QUATCOPY(&varray[elemsize*3*numfaces+elemsize+sizeof(float)*6],black);
QUATCOPY(&varray[elemsize*3*numfaces+elemsize*2+sizeof(float)*6],black);
}
numfaces++;
if( efa->v4 ) {
/*if (emdm->vertexCos) {
VECCOPY((float *)&varray[elemsize*3*numfaces],emdm->vertexCos[(int) efa->v3->tmp.l]);
VECCOPY((float *)&varray[elemsize*3*numfaces+sizeof(float)*3],emdm->faceNos[i]);
VECCOPY((float *)&varray[elemsize*3*numfaces+elemsize],emdm->vertexCos[(int) efa->v4->tmp.l]);
VECCOPY((float *)&varray[elemsize*3*numfaces+elemsize+sizeof(float)*3],emdm->faceNos[i]);
VECCOPY((float *)&varray[elemsize*3*numfaces+elemsize*2],emdm->vertexCos[(int) efa->v1->tmp.l]);
VECCOPY((float *)&varray[elemsize*3*numfaces+elemsize*2+sizeof(float)*3],emdm->faceNos[i]);
}
else {*/
VECCOPY((float *)&varray[elemsize*3*numfaces],efa->v3->co);
VECCOPY((float *)&varray[elemsize*3*numfaces+sizeof(float)*3],efa->n);
VECCOPY((float *)&varray[elemsize*3*numfaces+elemsize],efa->v4->co);
VECCOPY((float *)&varray[elemsize*3*numfaces+elemsize+sizeof(float)*3],efa->n);
VECCOPY((float *)&varray[elemsize*3*numfaces+elemsize*2],efa->v1->co);
VECCOPY((float *)&varray[elemsize*3*numfaces+elemsize*2+sizeof(float)*3],efa->n);
/*}*/
if( draw == 2 ) {
QUATCOPY(&varray[elemsize*3*numfaces+sizeof(float)*6],data.cols[2]);
QUATCOPY(&varray[elemsize*3*numfaces+elemsize+sizeof(float)*6],data.cols[2]);
QUATCOPY(&varray[elemsize*3*numfaces+elemsize*2+sizeof(float)*6],data.cols[2]);
}
else if( draw == 1 ) {
QUATCOPY(&varray[elemsize*3*numfaces+sizeof(float)*6],data.cols[(efa->f&SELECT)?1:0]);
QUATCOPY(&varray[elemsize*3*numfaces+elemsize+sizeof(float)*6],data.cols[(efa->f&SELECT)?1:0]);
QUATCOPY(&varray[elemsize*3*numfaces+elemsize*2+sizeof(float)*6],data.cols[(efa->f&SELECT)?1:0]);
}
else {
QUATCOPY(&varray[elemsize*3*numfaces+sizeof(float)*6],black);
QUATCOPY(&varray[elemsize*3*numfaces+elemsize+sizeof(float)*6],black);
QUATCOPY(&varray[elemsize*3*numfaces+elemsize*2+sizeof(float)*6],black);
}
numfaces++;
}
}
else {
/*if (emdm->vertexCos) {
VECCOPY((float *)&varray[elemsize*3*numfaces],emdm->vertexCos[(int) efa->v1->tmp.l]);
VECCOPY((float *)&varray[elemsize*3*numfaces+sizeof(float)*3],emdm->vertexNos[(int) efa->v1->tmp.l]);
VECCOPY((float *)&varray[elemsize*3*numfaces+elemsize],emdm->vertexCos[(int) efa->v2->tmp.l]);
VECCOPY((float *)&varray[elemsize*3*numfaces+elemsize+sizeof(float)*3],emdm->vertexNos[(int) efa->v2->tmp.l]);
VECCOPY((float *)&varray[elemsize*3*numfaces+elemsize*2],emdm->vertexCos[(int) efa->v3->tmp.l]);
VECCOPY((float *)&varray[elemsize*3*numfaces+elemsize*2+sizeof(float)*3],emdm->vertexNos[(int) efa->v3->tmp.l]);
}
else {*/
VECCOPY((float *)&varray[elemsize*3*numfaces],efa->v1->co);
VECCOPY((float *)&varray[elemsize*3*numfaces+sizeof(float)*3],efa->v1->no);
VECCOPY((float *)&varray[elemsize*3*numfaces+elemsize],efa->v2->co);
VECCOPY((float *)&varray[elemsize*3*numfaces+elemsize+sizeof(float)*3],efa->v2->no);
VECCOPY((float *)&varray[elemsize*3*numfaces+elemsize*2],efa->v3->co);
VECCOPY((float *)&varray[elemsize*3*numfaces+elemsize*2+sizeof(float)*3],efa->v3->no);
/*}*/
if( draw == 2 ) {
QUATCOPY(&varray[elemsize*3*numfaces+sizeof(float)*6],data.cols[2]);
QUATCOPY(&varray[elemsize*3*numfaces+elemsize+sizeof(float)*6],data.cols[2]);
QUATCOPY(&varray[elemsize*3*numfaces+elemsize*2+sizeof(float)*6],data.cols[2]);
}
else if( draw == 1 ) {
QUATCOPY(&varray[elemsize*3*numfaces+sizeof(float)*6],data.cols[(efa->f&SELECT)?1:0]);
QUATCOPY(&varray[elemsize*3*numfaces+elemsize+sizeof(float)*6],data.cols[(efa->f&SELECT)?1:0]);
QUATCOPY(&varray[elemsize*3*numfaces+elemsize*2+sizeof(float)*6],data.cols[(efa->f&SELECT)?1:0]);
}
else {
QUATCOPY(&varray[elemsize*3*numfaces+sizeof(float)*6],black);
QUATCOPY(&varray[elemsize*3*numfaces+elemsize+sizeof(float)*6],black);
QUATCOPY(&varray[elemsize*3*numfaces+elemsize*2+sizeof(float)*6],black);
}
numfaces++;
if( efa->v4 ) {
/*if (emdm->vertexCos) {
VECCOPY((float *)&varray[elemsize*3*numfaces],emdm->vertexCos[(int) efa->v3->tmp.l]);
VECCOPY((float *)&varray[elemsize*3*numfaces+sizeof(float)*3],emdm->vertexNos[(int) efa->v1->tmp.l]);
VECCOPY((float *)&varray[elemsize*3*numfaces+elemsize],emdm->vertexCos[(int) efa->v4->tmp.l]);
VECCOPY((float *)&varray[elemsize*3*numfaces+elemsize+sizeof(float)*3],emdm->vertexNos[(int) efa->v2->tmp.l]);
VECCOPY((float *)&varray[elemsize*3*numfaces+elemsize*2],emdm->vertexCos[(int) efa->v1->tmp.l]);
VECCOPY((float *)&varray[elemsize*3*numfaces+elemsize*2+sizeof(float)*3],emdm->vertexNos[(int) efa->v3->tmp.l]);
}
else {*/
VECCOPY((float *)&varray[elemsize*3*numfaces],efa->v3->co);
VECCOPY((float *)&varray[elemsize*3*numfaces+sizeof(float)*3],efa->v3->no);
VECCOPY((float *)&varray[elemsize*3*numfaces+elemsize],efa->v4->co);
VECCOPY((float *)&varray[elemsize*3*numfaces+elemsize+sizeof(float)*3],efa->v4->no);
VECCOPY((float *)&varray[elemsize*3*numfaces+elemsize*2],efa->v1->co);
VECCOPY((float *)&varray[elemsize*3*numfaces+elemsize*2+sizeof(float)*3],efa->v1->no);
/*}*/
if( draw == 2 ) {
QUATCOPY(&varray[elemsize*3*numfaces+sizeof(float)*6],data.cols[2]);
QUATCOPY(&varray[elemsize*3*numfaces+elemsize+sizeof(float)*6],data.cols[2]);
QUATCOPY(&varray[elemsize*3*numfaces+elemsize*2+sizeof(float)*6],data.cols[2]);
}
else if( draw == 1 ) {
QUATCOPY(&varray[elemsize*3*numfaces+sizeof(float)*6],data.cols[(efa->f&SELECT)?1:0]);
QUATCOPY(&varray[elemsize*3*numfaces+elemsize+sizeof(float)*6],data.cols[(efa->f&SELECT)?1:0]);
QUATCOPY(&varray[elemsize*3*numfaces+elemsize*2+sizeof(float)*6],data.cols[(efa->f&SELECT)?1:0]);
}
else {
QUATCOPY(&varray[elemsize*3*numfaces+sizeof(float)*6],black);
QUATCOPY(&varray[elemsize*3*numfaces+elemsize+sizeof(float)*6],black);
QUATCOPY(&varray[elemsize*3*numfaces+elemsize*2+sizeof(float)*6],black);
}
numfaces++;
}
}
}
prevdraw = draw;
}
GPU_buffer_unlock( buffer );
if( prevdraw != 0 && numfaces > 0) {
if( prevdraw==2 ) {
glEnable(GL_POLYGON_STIPPLE);
glPolygonStipple(stipple_quarttone);
}
glDrawArrays(GL_TRIANGLES,0,numfaces*3);
if( prevdraw==2 ) {
glDisable(GL_POLYGON_STIPPLE);
}
}
GPU_buffer_unbind();
} else {
dm->drawMappedFaces(dm, draw_dm_faces_sel__setDrawOptions, &data, 0);
}
GPU_buffer_free( buffer, 0 );
}
static int draw_dm_creases__setDrawOptions(void *userData, int index)
@ -2103,12 +2432,115 @@ static void draw_em_fancy(Scene *scene, View3D *v3d, RegionView3D *rv3d, Object
}
}
else {
/* 3 floats for position, 3 for normal and times two because the faces may actually be quads instead of triangles */
GPUBuffer *buffer = GPU_buffer_alloc( sizeof(float)*6*em->totface*3*2, 0 );
float *varray;
EditFace *efa;
int i, curmat = 0, draw = 0;
glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, me->flag & ME_TWOSIDED);
glEnable(GL_LIGHTING);
glFrontFace((ob->transflag&OB_NEG_SCALE)?GL_CW:GL_CCW);
finalDM->drawMappedFaces(finalDM, draw_em_fancy__setFaceOpts, 0, 0);
if( finalDM->getVertCos == 0 && (varray = GPU_buffer_lock_stream( buffer )) ) {
int prevdraw = 0, prevmat = 0;
int numfaces = 0;
int datatype[] = { GPU_BUFFER_INTER_V3F, GPU_BUFFER_INTER_N3F, GPU_BUFFER_INTER_END };
GPU_buffer_unlock( buffer );
GPU_interleaved_setup( buffer, datatype );
glShadeModel(GL_SMOOTH);
varray = GPU_buffer_lock_stream( buffer );
for (i=0,efa= em->faces.first; efa; i++,efa= efa->next) {
int drawSmooth = (efa->flag & ME_SMOOTH);
if( efa->h == 0 ) {
curmat = efa->mat_nr+1;
draw = 1;
}
else {
draw = 0;
}
if( ((prevdraw != draw) || (curmat != prevmat)) && prevdraw != 0 && numfaces > 0) {
if( prevdraw==2 ) {
glEnable(GL_POLYGON_STIPPLE);
glPolygonStipple(stipple_quarttone);
}
GPU_buffer_unlock( buffer );
GPU_enable_material(prevmat, NULL);
glDrawArrays(GL_TRIANGLES,0,numfaces*3);
if( prevdraw==2 ) {
glDisable(GL_POLYGON_STIPPLE);
}
varray = GPU_buffer_lock_stream( buffer );
numfaces = 0;
}
if( draw != 0 ) {
if(!drawSmooth) {
VECCOPY(&varray[numfaces*18],efa->v1->co);
VECCOPY(&varray[numfaces*18+3],efa->n);
VECCOPY(&varray[numfaces*18+6],efa->v2->co);
VECCOPY(&varray[numfaces*18+9],efa->n);
VECCOPY(&varray[numfaces*18+12],efa->v3->co);
VECCOPY(&varray[numfaces*18+15],efa->n);
numfaces++;
if( efa->v4 ) {
VECCOPY(&varray[numfaces*18],efa->v3->co);
VECCOPY(&varray[numfaces*18+3],efa->n);
VECCOPY(&varray[numfaces*18+6],efa->v4->co);
VECCOPY(&varray[numfaces*18+9],efa->n);
VECCOPY(&varray[numfaces*18+12],efa->v1->co);
VECCOPY(&varray[numfaces*18+15],efa->n);
numfaces++;
}
}
else {
VECCOPY(&varray[numfaces*18],efa->v1->co);
VECCOPY(&varray[numfaces*18+3],efa->v1->no);
VECCOPY(&varray[numfaces*18+6],efa->v2->co);
VECCOPY(&varray[numfaces*18+9],efa->v2->no);
VECCOPY(&varray[numfaces*18+12],efa->v3->co);
VECCOPY(&varray[numfaces*18+15],efa->v3->no);
numfaces++;
if( efa->v4 ) {
VECCOPY(&varray[numfaces*18],efa->v3->co);
VECCOPY(&varray[numfaces*18+3],efa->v3->no);
VECCOPY(&varray[numfaces*18+6],efa->v4->co);
VECCOPY(&varray[numfaces*18+9],efa->v4->no);
VECCOPY(&varray[numfaces*18+12],efa->v1->co);
VECCOPY(&varray[numfaces*18+15],efa->v1->no);
numfaces++;
}
}
}
prevdraw = draw;
prevmat = curmat;
}
GPU_buffer_unlock( buffer );
if( prevdraw != 0 && numfaces > 0) {
if( prevdraw==2 ) {
glEnable(GL_POLYGON_STIPPLE);
glPolygonStipple(stipple_quarttone);
}
GPU_enable_material(prevmat, NULL);
glDrawArrays(GL_TRIANGLES,0,numfaces*3);
if( prevdraw==2 ) {
glDisable(GL_POLYGON_STIPPLE);
}
}
GPU_buffer_unbind();
}
else {
finalDM->drawMappedFaces(finalDM, draw_em_fancy__setFaceOpts, 0, 0);
}
GPU_buffer_free(buffer,0);
glFrontFace(GL_CCW);
glDisable(GL_LIGHTING);
@ -5607,6 +6039,16 @@ static int bbs_mesh_solid__setDrawOpts(void *userData, int index, int *drawSmoot
{
Mesh *me = userData;
if (!(me->mface[index].flag&ME_HIDE)) {
return 1;
} else {
return 0;
}
}
static int bbs_mesh_solid__setDrawOpts_legacy(void *userData, int index, int *drawSmooth_r)
{
Mesh *me = userData;
if (!(me->mface[index].flag&ME_HIDE)) {
WM_set_framebuffer_index_color(index+1);
return 1;
@ -5620,9 +6062,41 @@ static void bbs_mesh_solid(Scene *scene, View3D *v3d, Object *ob)
{
DerivedMesh *dm = mesh_get_derived_final(scene, ob, v3d->customdata_mask);
Mesh *me = (Mesh*)ob->data;
MCol *colors;
int i,j;
glColor3ub(0, 0, 0);
dm->drawMappedFaces(dm, bbs_mesh_solid__setDrawOpts, me, 0);
if( !GPU_buffer_legacy(dm) ) {
int *index = DM_get_face_data_layer(dm, CD_ORIGINDEX);
int ind;
colors = MEM_mallocN(dm->getNumFaces(dm)*sizeof(MCol)*4,"bbs_mesh_solid");
for(i=0;i<dm->getNumFaces(dm);i++) {
if( index != 0 )
ind = index[i];
else
ind = i;
if (!(me->mface[ind].flag&ME_HIDE)) {
unsigned int fbindex = index_to_framebuffer(ind+1);
for(j=0;j<4;j++) {
colors[i*4+j].b = ((fbindex)&0xFF);
colors[i*4+j].g = (((fbindex)>>8)&0xFF);
colors[i*4+j].r = (((fbindex)>>16)&0xFF);
}
}
else {
memset(&colors[i*4],0,sizeof(MCol)*4);
}
}
CustomData_add_layer( &dm->faceData, CD_ID_MCOL, CD_ASSIGN, colors, dm->numFaceData );
GPU_buffer_free(dm->drawObject->colors,0);
dm->drawObject->colors = 0;
dm->drawMappedFaces(dm, bbs_mesh_solid__setDrawOpts, me, 1);
}
else {
dm->drawMappedFaces(dm, bbs_mesh_solid__setDrawOpts_legacy, me, 0);
}
dm->release(dm);
}

View File

@ -0,0 +1,157 @@
/**
* $Id: gpu_buffers.h 20687 2009-06-07 11:26:46Z imbusy $
*
* ***** BEGIN GPL LICENSE BLOCK *****
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version. The Blender
* Foundation also sells licenses for use in proprietary software under
* the Blender License. See http://www.blender.org/BL/ for information
* about this.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*
* The Original Code is Copyright (C) 2005 Blender Foundation.
* All rights reserved.
*
* The Original Code is: all of this file.
*
* Contributor(s): Brecht Van Lommel.
*
* ***** END GPL LICENSE BLOCK *****
*/
#ifndef __GPU_BUFFERS_H__
#define __GPU_BUFFERS_H__
#define MAX_FREE_GPU_BUFFERS 8
#ifdef _DEBUG
/*#define DEBUG_VBO(X) printf(X)*/
#define DEBUG_VBO(X)
#else
#define DEBUG_VBO(X)
#endif
struct DerivedMesh;
/* V - vertex, N - normal, T - uv, C - color
F - float, UB - unsigned byte */
#define GPU_BUFFER_INTER_V3F 1
#define GPU_BUFFER_INTER_N3F 2
#define GPU_BUFFER_INTER_T2F 3
#define GPU_BUFFER_INTER_C3UB 4
#define GPU_BUFFER_INTER_C4UB 5
#define GPU_BUFFER_INTER_END -1
typedef struct GPUBuffer
{
int size; /* in bytes */
void *pointer; /* used with vertex arrays */
unsigned int id; /* used with vertex buffer objects */
} GPUBuffer;
typedef struct GPUBufferPool
{
int size; /* number of allocated buffers stored */
int start; /* for a queue like structure */
/* when running out of space for storing buffers,
the last one used will be thrown away */
GPUBuffer* buffers[MAX_FREE_GPU_BUFFERS];
} GPUBufferPool;
typedef struct GPUBufferMaterial
{
int start; /* at which vertex in the buffer the material starts */
int end; /* at which vertex it ends */
char mat_nr;
} GPUBufferMaterial;
typedef struct IndexLink {
int element;
struct IndexLink *next;
} IndexLink;
typedef struct GPUDrawObject
{
GPUBuffer *vertices;
GPUBuffer *normals;
GPUBuffer *uv;
GPUBuffer *colors;
GPUBuffer *edges;
GPUBuffer *uvedges;
int *faceRemap; /* at what index was the face originally in DerivedMesh */
IndexLink *indices; /* given an index, find all elements using it */
IndexLink *indexMem; /* for faster memory allocation/freeing */
int indexMemUsage; /* how many are already allocated */
int colType;
GPUBufferMaterial *materials;
int nmaterials;
int nelements; /* (number of faces) * 3 */
int nlooseverts;
int nedges;
int nindices;
int legacy; /* if there was a failure allocating some buffer, use old rendering code */
} GPUDrawObject;
typedef struct GPUAttrib
{
int index;
int size;
int type;
} GPUAttrib;
GPUBufferPool *GPU_buffer_pool_new();
void GPU_buffer_pool_free( GPUBufferPool *pool ); /* TODO: Find a place where to call this function on exit */
GPUBuffer *GPU_buffer_alloc( int size, GPUBufferPool *pool );
void GPU_buffer_free( GPUBuffer *buffer, GPUBufferPool *pool );
GPUDrawObject *GPU_drawobject_new( struct DerivedMesh *dm );
void GPU_drawobject_free( struct DerivedMesh *dm );
/* called before drawing */
void GPU_vertex_setup( struct DerivedMesh *dm );
void GPU_normal_setup( struct DerivedMesh *dm );
void GPU_uv_setup( struct DerivedMesh *dm );
void GPU_color_setup( struct DerivedMesh *dm );
void GPU_edge_setup( struct DerivedMesh *dm ); /* does not mix with other data */
void GPU_uvedge_setup( struct DerivedMesh *dm );
void GPU_interleaved_setup( GPUBuffer *buffer, int data[] );
int GPU_attrib_element_size( GPUAttrib data[], int numdata );
void GPU_interleaved_attrib_setup( GPUBuffer *buffer, GPUAttrib data[], int numdata );
/* can't lock more than one buffer at once */
void *GPU_buffer_lock( GPUBuffer *buffer );
void *GPU_buffer_lock_stream( GPUBuffer *buffer );
void GPU_buffer_unlock( GPUBuffer *buffer );
/* upload three unsigned chars, representing RGB colors, for each vertex. Resets dm->drawObject->colType to -1 */
void GPU_color3_upload( struct DerivedMesh *dm, char *data );
/* upload four unsigned chars, representing RGBA colors, for each vertex. Resets dm->drawObject->colType to -1 */
void GPU_color4_upload( struct DerivedMesh *dm, char *data );
/* switch color rendering on=1/off=0 */
void GPU_color_switch( int mode );
void GPU_buffer_draw_elements( GPUBuffer *elements, unsigned int mode, int start, int count );
/* called after drawing */
void GPU_buffer_unbind();
int GPU_buffer_legacy( struct DerivedMesh *dm );
#endif

File diff suppressed because it is too large Load Diff

View File

@ -76,7 +76,9 @@ typedef struct CustomData {
#define CD_TANGENT 18
#define CD_MDISPS 19
#define CD_WEIGHT_MCOL 20 /* for displaying weightpaint colors */
#define CD_NUMTYPES 21
#define CD_ID_MCOL 21
#define CD_TEXTURE_MCOL 22
#define CD_NUMTYPES 23
/* Bits for CustomDataMask */
#define CD_MASK_MVERT (1 << CD_MVERT)

View File

@ -446,6 +446,7 @@ extern UserDef U; /* from blenkernel blender.c */
#define USER_DEPRECATED_FLAG 1
#define USER_DISABLE_SOUND 2
#define USER_DISABLE_MIPMAP 4
#define USER_DISABLE_VBO 8
/* wm draw method */
#define USER_DRAW_TRIPLE 0

View File

@ -2173,6 +2173,10 @@ static void rna_def_userdef_system(BlenderRNA *brna)
RNA_def_property_boolean_negative_sdna(prop, NULL, "gameflags", USER_DISABLE_MIPMAP);
RNA_def_property_ui_text(prop, "Mipmaps", "Scale textures for the 3d View (looks nicer but uses more memory and slows image reloading.)");
prop= RNA_def_property(srna, "use_vbos", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_negative_sdna(prop, NULL, "gameflags", USER_DISABLE_VBO);
RNA_def_property_ui_text(prop, "VBOs", "Use Vertex Buffer Objects (or Vertex Arrays, if unsupported) for viewport rendering.");
prop= RNA_def_property(srna, "gl_texture_limit", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_sdna(prop, NULL, "glreslimit");
RNA_def_property_enum_items(prop, gl_texture_clamp_items);

View File

@ -86,6 +86,7 @@
#include "UI_interface.h"
#include "BLF_api.h"
#include "gpu_buffers.h"
#include "GPU_extensions.h"
#include "GPU_draw.h"
@ -252,6 +253,7 @@ void WM_exit(bContext *C)
// XXX UI_filelist_free_icons();
}
GPU_buffer_pool_free(0);
GPU_extensions_exit();
// if (copybuf) MEM_freeN(copybuf);

View File

@ -434,7 +434,7 @@ static int wm_get_colordepth(void)
/* apple seems to round colors to below and up on some configs */
static unsigned int index_to_framebuffer(int index)
unsigned int index_to_framebuffer(int index)
{
unsigned int i= index;
@ -464,7 +464,7 @@ static unsigned int index_to_framebuffer(int index)
/* this is the old method as being in use for ages.... seems to work? colors are rounded to lower values */
static unsigned int index_to_framebuffer(int index)
unsigned int index_to_framebuffer(int index)
{
unsigned int i= index;

View File

@ -45,6 +45,7 @@ void wm_subwindow_getsize(wmWindow *win, int swinid, int *x, int *y);
void wm_subwindow_getorigin(wmWindow *win, int swinid, int *x, int *y);
void wm_subwindow_getmatrix(wmWindow *win, int swinid, float mat[][4]);
unsigned int index_to_framebuffer(int index);
#endif /* WM_SUBWINDOW_H */