• Advertisement
Sign in to follow this  

(XNA) possible to change 3D model textures during gameplay?

This topic is 3454 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hoping this is possible. I have basic skybox which everyone knows about. I want to be able to change the textures on the skybox during gameplay. So it essentially is a basic way of animating the sky. Any examples or links would be great. [Edited by - soarah on August 3, 2008 9:10:59 PM]

Share this post


Link to post
Share on other sites
Advertisement
Sure, just call SetValue on the EffectParameter that corresponds to the texture. The model processor will do this when the model is first loaded with the texture specified in the material, but you can just simply override that whenever you want.

Share this post


Link to post
Share on other sites

Had a go, but it didn't like it and gave me an ArgumentNullException

foreach (ModelMesh mesh in model.Meshes)
{
foreach (BasicEffect effect in mesh.Effects)
{

//effect.Texture = texture;

effect.CurrentTechnique = effect.Techniques["Textured"]; //exception here
effect.Parameters["xTexture"].SetValue(texture);

effect.EnableDefaultLighting();

effect.View = viewMatrix;
effect.Projection = projectionMatrix;
effect.World = transforms[mesh.ParentBone.Index] * worldMatrix;
}
mesh.Draw();
}







[Edited by - soarah on August 4, 2008 4:05:27 AM]

Share this post


Link to post
Share on other sites
Well wait a minute here...are you using a custom HLSL effect or are you using a BasicEffect? I'd assume you're using a custom effect since you're rendering a skybox...in which case you shouldn't have BasicEffect's bound to your ModelMesh materials. You should have just regular Effect instances.

If somehow you are using BasicEffect, you wouldn't set the HLSL parameter directly...you'd set the texture to the Texture property.

Share this post


Link to post
Share on other sites
Yeah I am just using the BasicEffect, It seems to be possible to render the skybox using HLSL or BasicEffect.

Quote:
If somehow you are using BasicEffect, you wouldn't set the HLSL parameter directly...you'd set the texture to the Texture property.


effect.Texture = texture; ?

I tried this but it doesn't want to change during game play, only each time you start the game.



Also in theory every time you want to change the texture; say with the press of a button... you would have to call the whole Draw function for the model. Doesn't that go through the process of drawing the model AGAIN and not just change the texture.

[Edited by - soarah on August 4, 2008 7:42:15 PM]

Share this post


Link to post
Share on other sites
Anyone else have any ideas? doesn't just have to be a skybox can be any 3d model.

Share this post


Link to post
Share on other sites
Quote:
Original post by soarah
Also in theory every time you want to change the texture; say with the press of a button... you would have to call the whole Draw function for the model. Doesn't that go through the process of drawing the model AGAIN and not just change the texture.


Well of course, you can't change what's already been drawn. All you can do is overwrite it.

Share this post


Link to post
Share on other sites
For me, i did something like this with a mouse cursor

you can have 1 texture per frame and 1 texture called "CurrentSkyTexture"
in each game loop, increment some counter [perhaps i?]
lets say you had 5 frames
(int i = 0 outside of main)
texture frame1;
texture frame2;
texture frame3;
texture frame4;
texture frame5;
texture currentFrame;
switch(++i)
{
case 1: currentframe = frame2; break;
case 2: currentframe = frame3; break;
case 3: currentframe = frame4; break;
case 4: currentframe = frame5; break;
default: currentframe = frame1; i = 0; break;
}
that shold do it =/
hope that helps?
[although i think im telling you the wrong thing or something]

Share this post


Link to post
Share on other sites
Quote:
Original post by warthog518
For me, i did something like this with a mouse cursor

you can have 1 texture per frame and 1 texture called "CurrentSkyTexture"
in each game loop, increment some counter [perhaps i?]
lets say you had 5 frames
(int i = 0 outside of main)
texture frame1;
texture frame2;
texture frame3;
texture frame4;
texture frame5;
texture currentFrame;
switch(++i)
{
case 1: currentframe = frame2; break;
case 2: currentframe = frame3; break;
case 3: currentframe = frame4; break;
case 4: currentframe = frame5; break;
default: currentframe = frame1; i = 0; break;
}
that shold do it =/
hope that helps?
[although i think im telling you the wrong thing or something]



Yeah I understand what your doing here

Share this post


Link to post
Share on other sites
Quote:
Original post by MJP
Quote:
Original post by soarah
Also in theory every time you want to change the texture; say with the press of a button... you would have to call the whole Draw function for the model. Doesn't that go through the process of drawing the model AGAIN and not just change the texture.


Well of course, you can't change what's already been drawn. All you can do is overwrite it.


Ok so now your more or less saying you cant change the texture of a 3D model while your playing the game, because once you call your drawModel method that's it drawn and you cant go back and change things about it during run time.

Share this post


Link to post
Share on other sites
Quote:
Original post by soarah
Ok so now your more or less saying you cant change the texture of a 3D model while your playing the game, because once you call your drawModel method that's it drawn and you cant go back and change things about it during run time.


For that frame, sure. Once you've drawn the model, changing textures isn't going to do jack shit unless you draw it again.

Share this post


Link to post
Share on other sites
Quote:
Original post by superpig
Quote:
Original post by soarah
Ok so now your more or less saying you cant change the texture of a 3D model while your playing the game, because once you call your drawModel method that's it drawn and you cant go back and change things about it during run time.


For that frame, sure. Once you've drawn the model, changing textures isn't going to do jack shit unless you draw it again.


question answered; thanks. Now back to the drawing board.

Share this post


Link to post
Share on other sites
You MUST render the model again in order to see any changes such as switching textures.


using System;
using System.Collections.Generic;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.GamerServices;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Net;
using Microsoft.Xna.Framework.Storage;

namespace SwitchTexture
{
public class SwitchTextureGame : Microsoft.Xna.Framework.Game
{
GraphicsDeviceManager graphics;

// Create an array for holding 2 textures which we will switch between
Texture2D[] textures = new Texture2D[2];

// The index of the texture to use
int currentTexture = 0;

// The model we will be rendering with the current texture
Model model = null;

public SwitchTextureGame()
{
graphics = new GraphicsDeviceManager(this);
Content.RootDirectory = "Content";
}

protected override void LoadContent()
{
// Load both textures
textures[0] = Content.Load<Texture2D>("textures\\gold");
textures[1] = Content.Load<Texture2D>("textures\\silver");

// And the model we want to use
model = Content.Load<Model>("models\\sphere");
}


protected override void Update(GameTime gameTime)
{
// Allow switching the texture
if (Keyboard.GetState().IsKeyDown(Keys.Space))
currentTexture = 1; // SPACE DOWN: use silver texture
else
currentTexture = 0; // SPACE UP: use gold texture

base.Update(gameTime);
}

protected override void Draw(GameTime gameTime)
{
graphics.GraphicsDevice.Clear(Color.CornflowerBlue);

// Draw the model
foreach (ModelMesh mesh in model.Meshes)
{
foreach (BasicEffect effect in mesh.Effects)
{
// Make sure lighting and texturing is enabled so we can see the result
effect.EnableDefaultLighting();
effect.TextureEnabled = true;

// Begin to render with the specified texture
effect.Texture = textures[currentTexture];

effect.World = Matrix.Identity;
effect.View = Matrix.CreateLookAt(new Vector3(0.0f, 2.0f, 5.0f), Vector3.Zero, Vector3.Up);
effect.Projection = Matrix.CreatePerspectiveFieldOfView(MathHelper.PiOver4, 800.0f / 600.0f, 1.0f, 100.0f);
}
// Draw the mesh
mesh.Draw();
}

base.Draw(gameTime);
}
}

public class Application
{
public static void Main(string[] args)
{
SwitchTextureGame game = new SwitchTextureGame();
game.Run();
}
}
}



Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement