【发布时间】:2013-11-19 01:20:07
【问题描述】:
我正在开发一个“实时图像编辑器”以在三个 js 中应用纹理。
我的应用程序有两个部分,一个 2D 画布编辑器和一个显示在 2D 部分中完成的合成的 3D 模型。
您在 2d 部分中进行图像拼贴,将此构图保存在图像文件中,然后以 3d 模型进行充电。
我的问题是当用户进行更改时我无法重新加载图像文件。哟可以做第一个构图并在3d模型中正确充电,但如果你对构图进行另一次更改,请再次保存,并尝试应用于3d模型,不会重新加载文件中的数据,并显示旧图像.如果您加载另一个图像文件,它可以正常工作,但使用相同的图像文件名(数据更改,但名称相同)不会显示真实数据。
我的代码:
var cubeCamera, projector;
var texturas=[false,false,false];
var FAR = 1000;
var light, controls;
var SCREEN_WIDTH = _ANCHO3D = 380 ;
var SCREEN_HEIGHT = _ALTO3D = 340;
var container;
var camera, scene, projector, renderer;
var loader;
var composer;
var testParams, testPass;
var tex, tex2, tex3;
var auxi=1;
$("#visor3D").append("<div id='conten3D' style='width:"+_ANCHO3D+"px; height:"+_ALTO3D+"px; border: 1px solid green;'></div>");
var clock = new THREE.Clock();
init();
animate();
function init()
{
camera = new THREE.PerspectiveCamera( 40, SCREEN_WIDTH / SCREEN_HEIGHT, 1, 900 );
camera.position.set( -270, 45, 1 );
// SCENE
scene = new THREE.Scene();
// LIGHTS
var ambientLight = new THREE.AmbientLight(0xffffff,1.5);
scene.add(ambientLight);
hemiLight = new THREE.HemisphereLight( 0xffffff, 0xffffff, 1.5 );
scene.add(hemiLight);
renderer = new THREE.WebGLRenderer({ antialias: true, preserveDrawingBuffer : true } );
renderer.setSize( SCREEN_WIDTH, SCREEN_HEIGHT );
container=$("#conten3D");
container.append(renderer.domElement);
renderer.gammaInput = true;
renderer.gammaOutput = true;
// CONTROLS
controls = new THREE.TrackballControls( camera, renderer.domElement );
controls_set();
loader = new THREE.OBJMTLLoader();
loader.addEventListener('load', function ( event )
{
object = event.content;
object.position.y = 44;
object.scale.x =0.15;
object.scale.y =0.15;
object.scale.z =0.15;
tex=new THREE.Texture();
tex2=new THREE.Texture();
tex3=new THREE.Texture();
object.children[11].material.map=THREE.ImageUtils.loadTexture( "obj/maps/blanco.jpg");
object.children[10].material.map=THREE.ImageUtils.loadTexture( "obj/maps/blanco.jpg");
object.children[6].material.map=THREE.ImageUtils.loadTexture( "obj/maps/blanco.jpg");
object.children[8].material.map=THREE.ImageUtils.loadTexture( "obj/maps/blanco.jpg");
object.children[15].material.map=THREE.ImageUtils.loadTexture( "obj/maps/blanco.jpg");
//aplicartexturas();
scene.add( object );
});
loader.load( 'obj/demo.obj', 'obj/demo0.mtl' );
}
function animate()
{
requestAnimationFrame( animate );
render();
rotar();
}
function render()
{
tex.needsUpdate = true;
tex2.needsUpdate = true;
tex3.needsUpdate = true;
var delta = clock.getDelta();
controls.update( delta );
renderer.render( scene, camera );
}
function aplicartexturas()
{
tex=THREE.ImageUtils.loadTexture( "disenos/"+userid+"_LD.png" );
tex2=THREE.ImageUtils.loadTexture("disenos/"+userid+"_LI.png");
tex3=THREE.ImageUtils.loadTexture( "disenos/"+userid+"_BA.png" );
object.children[11].material.map=tex;
object.children[10].material.map=tex2;
object.children[6].material.map=tex3;
object.children[8].material.map=tex3;
object.children[15].material.map=tex3;
}
当给物体充电时,我对所有物体都应用白色纹理 后来,当我在 2d 编辑器中进行更改时,我将这些更改应用到函数“aplicartexturas()”中。在这个函数中,“userid”是页面中的一个全局变量,供不同的多个用户访问。
谢谢。
【问题讨论】:
-
试试这个: (1) 从渲染循环中删除
needsUpdate = true--loadTexture为您设置该标志。 (2) 加载是异步的。在加载后分配新加载的纹理——在loadTexture回调中。 (3) 可以共享白色纹理。无需多次加载。 -
是这个问题吗?如果是这样,我会发布一个答案。
-
感谢您的回答。我删除了
needsUpdate=true(1),现在我使用一个变量来加载白色纹理并将这个变量分配给所有贴图 (2)。但这很奇怪,我在回调tex2=THREE.ImageUtils.loadTexture("disenos/"+userid+"_LI.png", null, function(){ object.children[10].material.map=tex2; });中分配了新加载的纹理,但没有任何变化;也尝试将新加载的纹理直接分配给地图object.children[10].material.map=new THREE.ImageUtils.loadTexture("disenos/"+userid+"_LI.png");,但没有任何事情发生,但如果我同时做,那么它可以工作。再次感谢。 -
好吧,如果你需要进一步的帮助,你将不得不发布一个简单的、活生生的例子来演示这个问题。