Logo Search packages:      
Sourcecode: vertex version File versions

editortexture.c

#include <stdio.h>
#include <malloc.h>
#include <string.h>
#include <ctype.h>
#include <limits.h>

#include <gtk/gtk.h>
#include <gtkgl/gtkglarea.h>


#include "../include/disk.h"
#include "../include/string.h"
#include "../include/strexp.h"

#include "cdialog.h"

#include "v3dtex.h"
#include "v3dmh.h"
#include "v3dmp.h"
#include "v3dmodel.h"

#include "texbrowser.h"
#include "texbrowsercb.h"
#include "editor.h"
#include "editorcb.h"
#include "editorviewcb.h"
#include "editorlist.h"
#include "editortexture.h"

#include "vmacfg.h"
#include "vma.h"
#include "config.h"

#ifdef MEMWATCH
# include "memwatch.h"
#endif


void EditorTexturePrimitiveRealize( 
        ma_editor_struct *editor,
        mp_texture_select_struct *mp_texture_select,
        gbool rerealize
);
void EditorTexturePrimitiveUnrealize(
        ma_editor_struct *editor,
        mp_texture_select_struct *mp_texture_select
);

v3d_texture_ref_struct *EditorMatchTextureByName(
      ma_editor_struct *editor,
      const char *name, int *tex_num
);
int EditorTextureLoad(
      ma_editor_struct *editor,
      const char *name, const char *path, double priority
);
int EditorTextureLoadAll(ma_editor_struct *editor);

void EditorTextureChangeName(
      ma_editor_struct *editor,
      v3d_model_struct *model,
      const char *old_name, const char *new_name
);

void EditorTextureListDeleteAll(ma_editor_struct *editor);


/*
 *      (Re)loads the given V3DMP_TYPE_TEXTURE_SELECT primitive with
 *      respect to the specified editor.
 *
 *      If data is already loaded (realized) then it will only be reloaded
 *      if rerealize is TRUE.
 *
 *      The first 3D view on the editor may be placed into context by
 *      this function.
 */
void EditorTexturePrimitiveRealize(
        ma_editor_struct *editor,
        mp_texture_select_struct *mp_texture_select,
        gbool rerealize
)
{
        int tex_num;
        v3d_texture_ref_struct *t;


        if((editor == NULL) ||
           (mp_texture_select == NULL)
        )
            return;

      /* Since mp_texture_select is always considered realized,
       * we need to rerealize it always.
       */
      if(1)
      {
          /* Match new index referance to actual loaded
           * texture on editor structure.
           */
          t = EditorMatchTextureByName(
            editor,
            mp_texture_select->name,
            &tex_num
          );
          /* Update client_data value on primitive to reffer
           * to the correct index (if available) of the
           * actually loaded texture on the editor structure.
           */
          if((tex_num >= 0) && (t != NULL))
            mp_texture_select->client_data = (void *)tex_num;
          else
            mp_texture_select->client_data = (void *)0;
      }
}

/*
 *      Unrealizes the given V3DMP_TYPE_TEXTURE_SELECT primitive with
 *      respect to the specified editor.
 *
 *      The first 3D view on the editor may be placed into context by
 *      this function.
 */
void EditorTexturePrimitiveUnrealize(
        ma_editor_struct *editor,
        mp_texture_select_struct *mp_texture_select
)
{
        if((editor == NULL) ||
           (mp_texture_select == NULL)
        )
            return;

      mp_texture_select->client_data = (void *)0;

      return;
}


/*
 *    Returns the pointer to the texture matching
 *    the given referance name and sets tex_num to indicate
 *    the index number matched on the list.
 *
 *    Can return NULL on no match.
 */
v3d_texture_ref_struct *EditorMatchTextureByName(
        ma_editor_struct *editor,
        const char *name,
      int *tex_num
)
{
      int i;
      v3d_texture_ref_struct *t;


      if(tex_num != NULL)
          (*tex_num) = -1;

      if((editor == NULL) ||
         (name == NULL)
      )
          return(NULL);

      for(i = 0; i < editor->total_textures; i++)
      {
          t = editor->texture[i];
          if(t == NULL)
            continue;

          if(!strcasecmp(t->name, name))
          {
            if(tex_num != NULL)
                (*tex_num) = i;

            return(t);
          }
      }

      return(NULL);
}

/*
 *    Loads the specified texture to the editor. If the path is not an
 *    absolute path then the base_dir from the editor's texture
 *    browser will be prepended to it.
 *
 *    Loaded texture will be added to the editor structure's
 *    actual loaded textures list at the first available NULL pointer
 *    in the list. If none is available then the list will be
 *    reallocated one new pointer and the newly located texture
 *    will be appended to the list.
 *
 *    Does not realize any primitives on the editor or update the
 *    texture browser.
 *
 *    Returns 0 on success or non-zero on error.
 */
int EditorTextureLoad(
      ma_editor_struct *editor,
      const char *name,
      const char *path,
      double priority
)
{
      int n;
      GtkWidget *w;
      v3d_texture_ref_struct *t;
      char *base_dir = NULL;
      char tmp_path[PATH_MAX + NAME_MAX];
      ma_texture_browser_struct *tb;


      if((editor == NULL) || (path == NULL))
          return(-1);

      tb = &editor->texture_browser;

      /* Get texture base directory from texture browser, since it
       * should be in sync with or overriding the editor's model
       * header item specified texture base directory.
       */
      w = tb->base_dir_entry;
      if(w != NULL)
          base_dir = gtk_entry_get_text(GTK_ENTRY(w));

      /* Set up tmp_path which will be used as the path to
       * load the file.
       */
      if(ISPATHABSOLUTE(path))
      {
          strncpy(tmp_path, path, PATH_MAX + NAME_MAX);
      }
      else
      {
          const char *cstrptr = (const char *)PrefixPaths(base_dir, path);

          strncpy(
            tmp_path,
            ((cstrptr == NULL) ? path : cstrptr),
            PATH_MAX + NAME_MAX
          );
      }
      tmp_path[PATH_MAX + NAME_MAX - 1] = '\0';


      /* Need to put the first 3D view glarea into context
       * so the texture gets loaded for that view.
       */
      if(VMA_MAX_3D_VIEWS_PER_EDITOR > 0)
          View3DGLEnableContext(editor->view3d[0]);

      /* Load texture. */
      t = V3DTextureLoadFromFile2DPreempt(
          tmp_path, name,
          V3D_TEX_FORMAT_RGBA       /* Destination format. */
      );
      if(t == NULL)
      {
          char text[PATH_MAX + NAME_MAX + 256];

          sprintf(
            text,
            "Could not load texture:\n    %s",
            tmp_path
          );
          CDialogGetResponse(
"Texture load failed",
text,
"The specified texture file could not be loaded. Please\n\
verify that both the path to the texture file and the\n\
texture base directory set correctly. If this error occured\n\
while you are loading a file you can simply say OK and\n\
then specify the texture base directory in the Textures\n\
Browser after the file has been loaded.",
                CDIALOG_ICON_ERROR,
                CDIALOG_BTNFLAG_OK | CDIALOG_BTNFLAG_HELP,
                CDIALOG_BTNFLAG_OK
          );
/* Use and check for ignore response? */
          return(-1);
      }
      /* Set priority on newly loaded texture. */
      V3DTexturePriority(t, priority);



      /* Add texture to editor list. */
        if(editor->total_textures < 0) 
            editor->total_textures = 0;

      /* Look for an available pointer that is NULL. */
      for(n = 0; n < editor->total_textures; n++)
      {
          if(editor->texture[n] == NULL)
            break;
      }
      if(n >= editor->total_textures)
      {
          /* No available NULL pointer, allocate one more. */
          n = editor->total_textures;
          editor->total_textures++;
          editor->texture = (v3d_texture_ref_struct **)realloc(
            editor->texture,
            editor->total_textures * sizeof(v3d_texture_ref_struct *)
          );
          if(editor->texture == NULL)
          {
            editor->total_textures = 0;
            V3DTextureDestroy(t);
            return(-1);
          }
      }
      /* Set just loaded texture to newly allocated pointer n. */
      editor->texture[n] = t;


      return(0);
}

/*
 *    Loads all textures specified in the model header items to the
 *    editor.
 *
 *    The texture browser's texture base directory will be updated
 *    if it is not overriding.
 *
 *    Does not unload any existing textures already loaded on the
 *    editor or realize any primitives.
 */
int EditorTextureLoadAll(ma_editor_struct *editor)
{
      GtkWidget *w;
      int i, status;
      int textures_loaded = 0;
      void *p;
      ma_texture_browser_struct *tb;

      mh_texture_base_directory_struct *mh_tbd;
      mh_texture_load_struct *mh_texture_load;


      if(editor == NULL)
          return(textures_loaded);

      tb = &editor->texture_browser;

      for(i = 0; i < editor->total_mh_items; i++)
      {
          p = editor->mh_item[i];
          if(p == NULL)
            continue;

          switch(*(int *)p)
          {
            case V3DMH_TYPE_TEXTURE_BASE_DIRECTORY:
            mh_tbd = p;
                w = tb->base_dir_entry;
                if(!tb->base_dir_override && (w != NULL) &&
                   (mh_tbd->path != NULL)
            )
                {
                    gtk_entry_set_text(
                        GTK_ENTRY(w),
                        mh_tbd->path
                    );
                }
            break;

            case V3DMH_TYPE_TEXTURE_LOAD:
            mh_texture_load = p;
            status = EditorTextureLoad(
                editor,
                mh_texture_load->name,
                mh_texture_load->path,
                mh_texture_load->priority
            );
            if(!status)
                textures_loaded++;
            break;
          }
      }

      return(textures_loaded);
}


/*
 *      Changes all texture referance names primitives of type
 *    V3DMP_TYPE_TEXTURE_SELECT on the given model from the
 *    old_name to the new_name.
 *
 *    Does not actually update the client data referances to texture
 *    numbers or their listing in the lists.
 */
void EditorTextureChangeName(          
        ma_editor_struct *editor,
        v3d_model_struct *model,
        const char *old_name, const char *new_name
)
{
        int i;
        void *p;
        mp_texture_select_struct *mp_texture_select;


        if((editor == NULL) ||
           (model == NULL) ||
           (old_name == NULL)
        )
            return;

      /* Go through each primitive on the model. */
        for(i = 0; i < model->total_primitives; i++)
        {
            p = model->primitive[i];
            if(p == NULL)
                continue;

            switch(*(int *)p)
            {
              case V3DMP_TYPE_TEXTURE_SELECT:
                mp_texture_select = p;
            if(mp_texture_select->name == NULL)
                break;

            if(!strcasecmp(mp_texture_select->name, old_name))
            {
                free(mp_texture_select->name);
                mp_texture_select->name = ((new_name == NULL) ?
                  NULL : strdup(new_name)
                );
            }
                break;
            }
        }
}




/*
 *    Deletes all textures in the real list and gui texture
 *    browser list.
 */
void EditorTextureListDeleteAll(
      ma_editor_struct *editor
)
{
      int i;
      ma_texture_browser_struct *tb;


      if(editor == NULL)
          return;

      tb = &editor->texture_browser;

      /* Clear texture browser list. */
      TexBrowserListDeleteAll(tb);

      /* Delete all real textures on the editor, first put first
       * 3D view into context.
       */
        if(VMA_MAX_3D_VIEWS_PER_EDITOR > 0)
            View3DGLEnableContext(editor->view3d[0]);
        for(i = 0; i < editor->total_textures; i++)
            V3DTextureDestroy(editor->texture[i]);   

        free(editor->texture);
        editor->texture = NULL;
        editor->total_textures = 0;
}

Generated by  Doxygen 1.6.0   Back to index