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; }
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; }
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 ); } }
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 ); //} }
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); }
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(); }
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(); }
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(); }
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(); }
CPicoSurface::CPicoSurface(picoSurface_t *pSurface) { refCount = 1; m_pSurface = pSurface; // PicoFixSurfaceNormals( pSurface ); AccumulateBBox(); m_shader = QERApp_Shader_ForName(GetShaderName()); }
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; }
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(); } } }
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)); } } }
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 ); }
/*!\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; }
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; } }