Ejemplo n.º 1
0
int WINAPI QERApp_LoadShadersFromDir (const char* path)
{
  int count = 0;
	// scan g_Shaders, and call QERApp_Shader_ForName for each in the given path
	// this will load the texture if needed and will set it in use..
	int nSize = g_Shaders.GetSize();
	for (int i = 0; i < nSize; i++)
	{
		CShader *pShader = reinterpret_cast<CShader*>(g_Shaders.ElementAt(i));
		if (strstr(pShader->getShaderFileName(), path) || strstr(pShader->getName(), path))
		{
      count++;
			// request the shader, this will load the texture if needed and set "inuse"
			//++timo FIXME: should we put an Activate member on CShader?
			// this QERApp_Shader_ForName call is a kind of hack
			IShader *pFoo = QERApp_Shader_ForName(pShader->getName());
#ifdef _DEBUG
			// check we activated the right shader
			// NOTE: if there was something else loaded, the size of g_Shaders may have changed and strange behaviours are to be expected
			if (pFoo != pShader)
				Sys_Printf("WARNING: unexpected pFoo != pShader in QERApp_LoadShadersFromDir\n");
#endif
		}
  }
  return count;
}
Ejemplo n.º 2
0
IShader* WINAPI QERApp_Shader_ForName(const char* name)
{
	//++timo FIXME: do we allow NULL and "" calling?
	// how does it deal with notexture? can we simply replace by "textures/radiant/notex"?
	if (name == NULL || strlen(name) == 0)
	{
		Sys_Printf("FIXME: name == NULL || strlen(name) == 0 in QERApp_Shader_ForName\n");
		return QERApp_Shader_ForName("radiant/notex"); //++timo ???
	}

	// entities that should be represented with plain colors instead of textures
	// request a texture name with (r g b) (it's stored in their class_t)
	if (name[0]=='(')
	{
		return QERApp_ColorShader_ForName(name);
	}

	CShader* pShader = static_cast<CShader*>(QERApp_Try_Shader_ForName( name ));
	if (pShader)
	{
		pShader->SetDisplayed( true );
		return pShader;
	}
	// we don't know this shader, maybe it's a straight texture 
	pShader = new CShader;
	pShader->CreateDefault( name );
  // hook it into the shader list
	g_Shaders.Add( (LPVOID)pShader );
	pShader->IncRef();
	// if it can't find the texture, "textures/radiant/notex" will be used
  pShader->Activate();
  pShader->SetDisplayed( true );
	return pShader;
}
Ejemplo n.º 3
0
  void construct_shaders()
  {
    IShader* global_shader = shader_for_remap("*");

    unsigned int numSurfaces = m_model->GetNumSurfaces();
    m_shaders.reserve(numSurfaces);
    // now go through our surface and find our shaders, remap if needed
    for(unsigned int j = 0; j < numSurfaces; j++ )
    {
      const char* surfShaderName = m_model->GetShaderNameForSurface(j);
      IShader* shader = shader_for_remap(surfShaderName);
      // Determine which shader it is going to be
      if( !shader ) {
        if( global_shader ) {
          shader = global_shader;
        } else {
          shader = QERApp_Shader_ForName(surfShaderName);
        }
      }
      // Add reference
      shader->IncRef();
      // Done, continue
      m_shaders.push_back( shader );
    }
  }
Ejemplo n.º 4
0
void Patch_Parse( patchMesh_t *pPatch ){
	int i, j;
	char *str;

	char *token = Token();

	GetToken( true ); //{

	// parse shader name
	GetToken( true );
	str = new char[strlen( token ) + 10];
	strcpy( str, "textures/" );
	strcpy( str + 9, token );
	pPatch->pShader = QERApp_Shader_ForName( str );
	pPatch->d_texture = pPatch->pShader->getTexture();
	delete [] str;

	GetToken( true ); //(

	// parse matrix dimensions
	GetToken( false );
	pPatch->width = atoi( token );
	GetToken( false );
	pPatch->height = atoi( token );

	// ignore contents/flags/value
	GetToken( false );
	GetToken( false );
	GetToken( false );

	GetToken( false ); //)

	// parse matrix
	GetToken( true ); //(
	for ( i = 0; i < pPatch->width; i++ )
	{
		GetToken( true ); //(
		for ( j = 0; j < pPatch->height; j++ )
		{
			GetToken( false ); //(

			GetToken( false );
			pPatch->ctrl[i][j].xyz[0] = atof( token );
			GetToken( false );
			pPatch->ctrl[i][j].xyz[1] = atof( token );
			GetToken( false );
			pPatch->ctrl[i][j].xyz[2] = atof( token );
			GetToken( false );
			pPatch->ctrl[i][j].st[0] = atof( token );
			GetToken( false );
			pPatch->ctrl[i][j].st[1] = atof( token );

			GetToken( false ); //)
		}
		GetToken( false ); //)
	}
	GetToken( true ); //)

	GetToken( true ); //}
}
Ejemplo n.º 5
0
IShader *WINAPI QERApp_Shader_ForName (const char *name)
{
  if (name == NULL || strlen (name) == 0)
  {
    // Hydra: This error can occur if the user loaded a map with/dropped an entity that
    // did not set a texture name "(r g b)" - check the entity definition loader

    g_FuncTable.m_pfnSysFPrintf (SYS_ERR, "FIXME: name == NULL || strlen(name) == 0 in QERApp_Shader_ForName\n");
    return QERApp_Shader_ForName (SHADER_NOT_FOUND);
  }
  // entities that should be represented with plain colors instead of textures
  // request a texture name with (r g b) (it's stored in their class_t)
  if (name[0] == '(')
  {
    return QERApp_ColorShader_ForName (name);
  }

  CShader *pShader = static_cast < CShader * >(QERApp_Try_Shader_ForName (name));
  if (pShader)
  {
    pShader->SetDisplayed (true);
    return pShader;
  }
  return QERApp_CreateShader_ForTextureName (name);
}
Ejemplo n.º 6
0
void AddFaceWithTextureScaled(scene::Node* brush, vec3_t va, vec3_t vb, vec3_t vc,
                              const char* texture, bool bVertScale, bool bHorScale,
                              float minX, float minY, float maxX, float maxY)
{
    qtexture_t* pqtTexInfo;

    // TTimo: there used to be a call to pfnHasShader here
    //   this was not necessary. In Radiant everything is shader.
    //   If a texture doesn't have a shader script, a default shader object is used.
    // The IShader object was leaking also
    // collect texture info: sizes, etc
    IShader* i = QERApp_Shader_ForName(texture);
    pqtTexInfo = i->getTexture();	// shader width/height doesn't come out properly

    if(pqtTexInfo)
    {
        float scale[2] = {0.5f, 0.5f};
        float shift[2] = {0, 0};

        if(bHorScale)
        {
            int texWidth = pqtTexInfo->width;
            float width = maxX - minX;

            scale[0] = width/texWidth;
            shift[0] = -(float)((int)maxX%(int)width)/scale[0];
        }

        if(bVertScale)
        {
            int texHeight = pqtTexInfo->height;
            float height = maxY - minY;

            scale[1] = height/texHeight;
            shift[1] = (float)((int)minY%(int)height)/scale[1];
        }

        _QERFaceData addFace;
        FillDefaultTexture(&addFace, va, vb, vc, texture);
        addFace.m_texdef.scale[0] = scale[0];
        addFace.m_texdef.scale[1] = scale[1];
        addFace.m_texdef.shift[0] = shift[0];
        addFace.m_texdef.shift[1] = shift[1];

#if 0
        brush->m_brush->addPlane(addFace.m_p0, addFace.m_p1, addFace.m_p2, addFace.m_texdef);
#endif
    }
    else
    {
        // shouldn't even get here, as default missing texture should be returned if
        // texture doesn't exist, but just in case
        AddFaceWithTexture(brush, va, vb, vc, texture, FALSE);
        Sys_ERROR("BobToolz::Invalid Texture Name-> %s", texture);
    }
    // the IShader is not kept referenced, DecRef it
    i->DecRef();
}
Ejemplo n.º 7
0
void SetShader( face_t * f ){
	// unhook current shader
	f->pShader->DecRef();
	// don't access the texdef! it's DEAD
	f->d_texture = NULL;
	// hook
	// NOTE TTimo this function increments the refcount, don't incref ourselves
	f->pShader = QERApp_Shader_ForName( f->texdef.GetName() );
	f->d_texture = f->pShader->getTexture();
}
Ejemplo n.º 8
0
void SetShader( patchMesh_t * patch ){
	// unhook current shader
	patch->pShader->DecRef();
	// don't access this one! it has been deleted .. it's DEAD
	patch->d_texture = NULL;
	// hook the new one, increment the refcount
	// NOTE TTimo this function increments the refcount, don't incref ourselves
	patch->pShader = QERApp_Shader_ForName( ShaderNameLookup( patch ) );
	patch->d_texture = patch->pShader->getTexture();
}
Ejemplo n.º 9
0
void SetShader(face_t * f)
{
	// unhook current shader
	f->pShader->DecRef();
	// don't access the texdef! it's DEAD
	f->d_texture = NULL;
	// hook and increment refcount
	f->pShader = QERApp_Shader_ForName(f->texdef.name);
	f->pShader->IncRef();
	f->d_texture = f->pShader->getTexture();
}
Ejemplo n.º 10
0
CPicoSurface::CPicoSurface(picoSurface_t *pSurface)
{
  refCount = 1;

  m_pSurface = pSurface;

  // PicoFixSurfaceNormals( pSurface );
	
  AccumulateBBox();

  m_shader = QERApp_Shader_ForName(GetShaderName());
}
Ejemplo n.º 11
0
 inline IShader* shader_for_remap(const char* remap)
 {
   remap_t *pRemap;
   remaps_t::iterator i;
   for(i = m_remaps.begin(); i != m_remaps.end(); ++i)
   {
     pRemap = (*i);
     if( stricmp( remap, pRemap->original ) == 0 )
       break;
   }
   return (i != m_remaps.end()) ? QERApp_Shader_ForName(pRemap->remap) : NULL;
 }
Ejemplo n.º 12
0
void Patch_XMLParse( patchMesh_t *pPatch, xmlNodePtr surface ){
	char *str, *content;
	int i, j;

	for ( xmlNodePtr current = surface->children; current != NULL; current = current->next )
	{
		if ( current->type != XML_ELEMENT_NODE ) {
			continue;
		}
		if ( !strcmp( (char *)current->name, "matrix" ) ) {
			str = (char *)xmlGetProp( current, (xmlChar *)"width" );
			pPatch->width = atoi( str );
			xmlFree( str );
			str = (char *)xmlGetProp( current, (xmlChar *)"height" );
			pPatch->height = atoi( str );
			xmlFree( str );

			content = Q_StrDup( (char *)current->children->content );

			str = strtok( content, " \n\r\t\v\0" );
			for ( i = 0; i < pPatch->width; i++ )
			{
				for ( j = 0; j < pPatch->height; j++ )
				{
					pPatch->ctrl[i][j].xyz[0] = atof( str );
					str = strtok( NULL, " \n\r\t\v\0" );
					pPatch->ctrl[i][j].xyz[1] = atof( str );
					str = strtok( NULL, " \n\r\t\v\0" );
					pPatch->ctrl[i][j].xyz[2] = atof( str );
					str = strtok( NULL, " \n\r\t\v\0" );
					pPatch->ctrl[i][j].st[0] = atof( str );
					str = strtok( NULL, " \n\r\t\v\0" );
					pPatch->ctrl[i][j].st[1] = atof( str );
					str = strtok( NULL, " \n\r\t\v\0" );
				}
			}

			delete [] content;
		}
		else if ( !strcmp( (char *)current->name, "shader" ) ) {
			pPatch->pShader = QERApp_Shader_ForName( (char*)current->children->content );
			pPatch->d_texture = pPatch->pShader->getTexture();
		}
	}
}
Ejemplo n.º 13
0
  void construct_shaders()
  {
    IShader* global_shader = shader_for_remap("*");

    unsigned int numSurfaces = m_model->GetNumSurfaces();
    m_shaders.reserve(numSurfaces);
    // now go through our surface and find our shaders, remap if needed
    for(unsigned int j = 0; j < numSurfaces; j++ )
    {
      const char* surfShaderName = m_model->GetShaderNameForSurface(j);
      IShader* shader = shader_for_remap(surfShaderName);
//      m_shaders.push_back((shader) ? shader : (global_shader) ? global_shader : QERApp_Shader_ForName(surfShaderName));
      if( shader ) {
        m_shaders.push_back(shader);
      } else if( global_shader ) {
        m_shaders.push_back(global_shader);
      } else {
        m_shaders.push_back(QERApp_Shader_ForName(surfShaderName));
      }
    }
  }
Ejemplo n.º 14
0
void LoadSpriteModel(entity_interfaces_t *interfaces, const char *name)
{
  IShader *pShader;

  pShader = QERApp_Shader_ForName(name);

  if (!pShader)
  {
    Sys_Printf("ERROR: can't find shader (or image) for: %s\n", name );
    return;
  }

  CSpriteModel *model = new CSpriteModel();
  model->Construct(pShader);
  interfaces->pRender = (IRender*)model;
  interfaces->pRender->IncRef();
  //interfaces->pSelect = (ISelect*)model;
  //interfaces->pSelect->IncRef();
  interfaces->pSelect = NULL;
  interfaces->pEdit = NULL;
  model->DecRef();

}
void SI_FaceList_FitTexture( texdef_to_face_t* si_texdef_face_list, int nHeight, int nWidth ){
	texdef_to_face_t* temp_texdef_face_list;
	brushprimit_texdef_t bp;

	if ( !si_texdef_face_list ) {
		return;
	}

	for ( temp_texdef_face_list = si_texdef_face_list; temp_texdef_face_list; temp_texdef_face_list = temp_texdef_face_list->next )
	{
		Face_FitTexture( temp_texdef_face_list->face, nHeight, nWidth );
		Brush_Build( temp_texdef_face_list->brush,true,true,false,false );
		// Write changes to our working Texdef list

		if ( g_qeglobals.m_bBrushPrimitMode ) {
			ConvertTexMatWithQTexture( &temp_texdef_face_list->face->brushprimit_texdef, QERApp_Shader_ForName( temp_texdef_face_list->face->texdef.GetName() )->getTexture(), &bp, NULL );
			TexMatToFakeTexCoords( bp.coords, temp_texdef_face_list->face->texdef.shift, &temp_texdef_face_list->face->texdef.rotate, temp_texdef_face_list->face->texdef.scale );
		}
		temp_texdef_face_list->texdef = temp_texdef_face_list->face->texdef;
	}

	Sys_UpdateWindows( W_CAMERA );

}
Ejemplo n.º 16
0
/*!\todo Possibly make the import Undo-friendly by calling Undo_End for new brushes and ents */
void Map_ImportEntities( CPtrArray *ents, bool bAddSelected = false ){
	int num_ents, num_brushes;
	CPtrArray *brushes;
	vec3_t mins, maxs;
	entity_t *e;
	brush_t *b;
	face_t *f;
	int i,j;

	GPtrArray *new_ents = g_ptr_array_new();

	g_qeglobals.bPrimitBrushes = false;

	brush_t *pBrushList = ( bAddSelected ) ? &selected_brushes : &active_brushes;

	bool bDoneBPCheck = false;
	g_qeglobals.bNeedConvert = false;
	// HACK: find out if this map file was a BP one
	// check the first brush in the file that is NOT a patch
	// this will not be necessary when we allow both formats in the same file
	num_ents = ents->GetSize();
	for ( i = 0; !bDoneBPCheck && i < num_ents; i++ )
	{
		e = (entity_t*)ents->GetAt( i );
		brushes = (CPtrArray*)e->pData;
		num_brushes = brushes->GetSize();
		for ( j = 0; !bDoneBPCheck && j < num_brushes; j++ )
		{
			/*!todo Allow mixing texdef formats per-face. */
			b = (brush_t *)brushes->GetAt( j );
			if ( b->patchBrush ) {
				continue;
			}
			bDoneBPCheck = true;
			int BP_param = -1;
			if ( b->bBrushDef && !g_qeglobals.m_bBrushPrimitMode ) {
				BP_param = 0;
			}
			else if ( !b->bBrushDef && g_qeglobals.m_bBrushPrimitMode ) {
				BP_param = 1;
			}

			if ( BP_param != -1 ) {
				switch ( BP_MessageBox( BP_param ) )
				{
				case 0:
					Map_FreeEntities( ents );
					return;
				case 1:
					g_qeglobals.bNeedConvert = true;
					break;
				case 2:
					g_qeglobals.bNeedConvert = false;
					break;
				}
			}
		}
	}

	// process the entities into the world geometry
	num_ents = ents->GetSize();
	for ( i = 0; i < num_ents; i++ )
	{
		num_brushes = 0;
		e = (entity_t*)ents->GetAt( i );
		brushes = (CPtrArray*)e->pData;

		num_brushes = brushes->GetSize();
		// link brushes into entity
		for ( j = 0; j < num_brushes; j++ )
		{
			Entity_LinkBrush( e, (brush_t *)brushes->GetAt( j ) );
			g_qeglobals.d_parsed_brushes++;
		}
		brushes->RemoveAll();
		delete brushes;
		e->pData = NULL;

		// set entity origin
		GetVectorForKey( e, "origin", e->origin );
		// set entity eclass
		/*!\todo Make SetKeyValue check for "classname" change and assign appropriate eclass */
		e->eclass = Eclass_ForName( ValueForKey( e, "classname" ),
									( e->brushes.onext != &e->brushes ) );

		// go through all parsed brushes and build stuff
		for ( b = e->brushes.onext; b != &e->brushes; b = b->onext )
		{
			for ( f = b->brush_faces; f != NULL; f = f->next )
			{
				f->pShader = QERApp_Shader_ForName( f->texdef.GetName() );
				f->d_texture = f->pShader->getTexture();
			}

			// when brushes are in final state, build the planes and windings
			// NOTE: also converts BP brushes if g_qeglobals.bNeedConvert is true
			Brush_Build( b );
		}

//#define TERRAIN_HACK
#undef TERRAIN_HACK

#ifdef TERRAIN_HACK
		if ( ( strcmp( ValueForKey( e, "terrain" ),"1" ) == 0 && strcmp( e->eclass->name,"func_group" ) == 0 ) ) {

			// two aux pointers to the shaders used in the terrain entity
			// we don't keep refcount on them since they are only temporary
			// this avoids doing expensive lookups by name for all faces
			IShader *pTerrainShader, *pCaulk;

			pTerrainShader = NULL;
			pCaulk = QERApp_Shader_ForName( SHADER_CAULK );

			for ( b = e->brushes.onext; b != &e->brushes; b = b->onext )
			{
				if ( pTerrainShader == NULL ) {
					for ( f = b->brush_faces; f != NULL; f = f->next )
						if ( strcmp( f->texdef.GetName(), SHADER_CAULK ) != 0 ) {
							pTerrainShader = f->pShader;
						}
				}

				if ( pTerrainShader ) {
					for ( f = b->brush_faces; f != NULL; f = f->next )
					{
						if ( strcmp( f->texdef.GetName(), SHADER_CAULK ) != 0 ) { // not caulk
							Face_SetShader( f, pTerrainShader->getName() );
						}
						else{
							Face_SetShader( f, pCaulk->getName() );
						}
					}
				}
				else{
					Sys_FPrintf( SYS_WRN, "WARNING: no terrain shader found for brush\n" );
				}
			}
		}
#endif

#define PATCH_HACK
#ifdef PATCH_HACK
		for ( b = e->brushes.onext; b != &e->brushes; b = b->onext )
		{
			// patch hack, to be removed when dependency on brush_faces is removed
			if ( b->patchBrush ) {
				Patch_CalcBounds( b->pPatch, mins, maxs );
				for ( int i = 0; i < 3; i++ )
				{
					if ( (int)mins[i] == (int)maxs[i] ) {
						mins[i] -= 4;
						maxs[i] += 4;
					}
				}
				Brush_Resize( b, mins, maxs );
				Brush_Build( b );
			}
		}
#endif
		// add brush for fixedsize entity
		if ( e->eclass->fixedsize ) {
			vec3_t mins, maxs;
			VectorAdd( e->eclass->mins, e->origin, mins );
			VectorAdd( e->eclass->maxs, e->origin, maxs );
			b = Brush_Create( mins, maxs, &e->eclass->texdef );
			Entity_LinkBrush( e, b );
			Brush_Build( b );
		}

		for ( b = e->brushes.onext; b != &e->brushes; b = b->onext )
			Brush_AddToList( b, pBrushList );

		if ( strcmp( e->eclass->name, "worldspawn" ) == 0 ) {
			if ( world_entity ) {
				while ( e->brushes.onext != &e->brushes )
				{
					b = e->brushes.onext;
					Entity_UnlinkBrush( b );
					Entity_LinkBrush( world_entity, b );
				}
				Entity_Free( e );
			}
			else
			{
				world_entity = e;
			}
		}
		else if ( strcmp( e->eclass->name, "group_info" ) == 0 ) {
			// it's a group thing!
			Group_Add( e );
			Entity_Free( e );
		}
		else
		{
			// fix target/targetname collisions
			if ( ( g_PrefsDlg.m_bDoTargetFix ) && ( strcmp( ValueForKey( e, "target" ), "" ) != 0 ) ) {
				GPtrArray *t_ents = g_ptr_array_new();
				entity_t *e_target;
				const char *target = ValueForKey( e, "target" );
				qboolean bCollision = FALSE;

				// check the current map entities for an actual collision
				for ( e_target = entities.next; e_target != &entities; e_target = e_target->next )
				{
					if ( !strcmp( target, ValueForKey( e_target, "target" ) ) ) {
						bCollision = TRUE;
						// make sure the collision is not between two imported entities
						for ( j = 0; j < (int)new_ents->len; j++ )
						{
							if ( e_target == g_ptr_array_index( new_ents, j ) ) {
								bCollision = FALSE;
							}
						}
					}
				}

				// find the matching targeted entity(s)
				if ( bCollision ) {
					for ( j = num_ents - 1; j > 0; j-- )
					{
						e_target = (entity_t*)ents->GetAt( j );
						if ( e_target != NULL && e_target != e ) {
							const char *targetname = ValueForKey( e_target, "targetname" );
							if ( ( targetname != NULL ) && ( strcmp( target, targetname ) == 0 ) ) {
								g_ptr_array_add( t_ents, (gpointer)e_target );
							}
						}
					}
					if ( t_ents->len > 0 ) {
						// link the first to get a unique target/targetname
						Entity_Connect( e, (entity_t*)g_ptr_array_index( t_ents,0 ) );
						// set the targetname of the rest of them manually
						for ( j = 1; j < (int)t_ents->len; j++ )
							SetKeyValue( (entity_t*)g_ptr_array_index( t_ents, j ), "targetname", ValueForKey( e, "target" ) );
					}
					g_ptr_array_free( t_ents, FALSE );
				}
			}

			// add the entity to the end of the entity list
			Entity_AddToList( e, &entities );
			g_qeglobals.d_num_entities++;

			// keep a list of ents added to avoid testing collisions against them
			g_ptr_array_add( new_ents, (gpointer)e );
		}
	}
	g_ptr_array_free( new_ents, FALSE );

	ents->RemoveAll();

	g_qeglobals.bNeedConvert = false;
}
Ejemplo n.º 17
0
void SI_GetSelFacesTexdef(texdef_to_face_t *allocd_block_texdef)
{
    int		i;
    face_t	*f;
    brush_t	*b;
    texdef_to_face_t *position, *prev_pos;
    brushprimit_texdef_t bp;

    if(selected_brushes.next != &selected_brushes)
    {
        prev_pos = position = allocd_block_texdef;
        for(b=selected_brushes.next; b!=&selected_brushes; b=b->next)
        {
            if ( !(b->patchBrush) )
            {
                for(f=b->brush_faces; f ; f = f->next)
                {
                    position->face = f;
                    position->brush = b;
                    position->texdef = f->texdef;
                    if(g_qeglobals.m_bBrushPrimitMode)
                    {
                        ConvertTexMatWithQTexture(&f->brushprimit_texdef, QERApp_Shader_ForName( f->texdef.GetName() )->getTexture(), &bp, NULL);
                        TexMatToFakeTexCoords(bp.coords, position->texdef.shift, &position->texdef.rotate, position->texdef.scale);
                        position->orig_bp_texdef = bp;
                    }
                    position->orig_texdef = position->texdef;
                    prev_pos->next = position;
                    prev_pos = position;
                    position++;
                }
                prev_pos->next = NULL;
            }
        }
    }
    else if(g_ptrSelectedFaces.GetSize() != 0)
    {
        f = (face_t *) g_ptrSelectedFaces.GetAt(0);
        b = (brush_t *) g_ptrSelectedFaceBrushes.GetAt(0);
        position = (texdef_to_face_t*) allocd_block_texdef;
        position->face = f;
        position->brush = b;
        position->texdef = f->texdef;
        if(g_qeglobals.m_bBrushPrimitMode)
        {
            ConvertTexMatWithQTexture(&f->brushprimit_texdef, QERApp_Shader_ForName( f->texdef.GetName() )->getTexture(), &bp, NULL);
            TexMatToFakeTexCoords(bp.coords, position->texdef.shift, &position->texdef.rotate, position->texdef.scale);
            position->orig_bp_texdef = bp;
        }
        position->orig_texdef = position->texdef;
        prev_pos = position;
        for(i=1; i<g_ptrSelectedFaces.GetSize(); i++)
        {
            f = (face_t *) g_ptrSelectedFaces.GetAt(i);
            b = (brush_t *) g_ptrSelectedFaceBrushes.GetAt(i);
            position = allocd_block_texdef + i;
            position->face = f;
            position->brush = b;
            position->texdef = f->texdef;
            if(g_qeglobals.m_bBrushPrimitMode)
            {
                ConvertTexMatWithQTexture(&f->brushprimit_texdef, QERApp_Shader_ForName( f->texdef.GetName() )->getTexture(), &bp, NULL);
                TexMatToFakeTexCoords(bp.coords, position->texdef.shift, &position->texdef.rotate, position->texdef.scale);
                position->orig_bp_texdef = bp;
            }
            position->orig_texdef = position->texdef;
            prev_pos->next = position;
            prev_pos = position;
        }
        position->next = NULL;
    }

}