Comunidad Game Maker

Ayuda => Preguntas y respuestas => Mensaje iniciado por: DarkKRuleR en Febrero 06, 2015, 01:17:17 AM

Título: [Resuelto] Mi surface actúa de forma muy extraña
Publicado por: DarkKRuleR en Febrero 06, 2015, 01:17:17 AM
Buenash, pues no sé qué ocurre... tengo este code

d3d_end(); d3d_set_lighting(false);
   
    scrIniciaCambioTextura();
    draw_sprite(sprEliMano, 1, 64, 64);
    draw_sprite(sprEliPluma, 0, 64, 64);
    textura1 = scrAsignaCambioTextura();

......................................
   
    scrIniciaCambioTextura();
    draw_sprite(sprEliMano, 3, 64, 64);
    draw_sprite(sprEliPluma, 1, 64, 64);
    textura8 = scrAsignaCambioTextura();
   
    d3d_start(); d3d_set_lighting(true);


Los puntos suspensivos significa que hay muchos más "fragmentos" como los dos que véis (llamada a scrInicia, dos draw sprite y scrAsigna), hago muchos en orden, os pongo sólo el primero y el último. Ahora las funciones

if (!surface_exists(surface128)) surface128 = surface_create(128, 128);
    surface_set_target(surface128);
    draw_clear_alpha(c_white, 0);


surface_reset_target();
return surface_get_texture(surface128);


Como véis, tras desactivar el 3D y la iluminación, me dispongo a MODIFICAR varias texturas que tengo previamente creadas. Para comenzar inicializo llamando a la primera función: si la surface no existe la creo, entonces le hago target, la limpio transparente y entonces puedo dibujar. Para finalizar reseteo y devuelvo la textura.

El problema? Al finalizar, TODAS LAS TEXTURAS, digamos... son la misma, o aproximadamente. Por ejemplo, el sprEliPluma tiene 8 subimagenes, en cada textura le meto una distinta, pues al finalizar... resulta que a TODAS se ha aplicado la misma subimagen... e igual con sprEliMano. ¿Qué hago mal?

También tenía antes una versión en que el SET y el RESET de la surface lo hacía SÓLo al inicio y final y, entre medio, hacía todos los get_texture y todos los draw. También fallaba.

Las texturas que modifico (textura1, textura2...) son creadas previamente en create y usadas en draw.
Título: Re:Mi surface actúa de forma muy extraña
Publicado por: penumbra en Febrero 06, 2015, 01:25:08 AM
Si se dibuja siempre la misma subimagen, lo más probable es que el error esté en el código que dibuja esas subimágenes, pero no veo que hayas colocado ese código en los ejemplos de arriba.
Título: Re:Mi surface actúa de forma muy extraña
Publicado por: DarkKRuleR en Febrero 06, 2015, 02:13:40 AM
Demasiado código para ponerlo.. pero lo he chequeado y está bien.

Una segunda comprobación:

txtManoLR = sprite_get_texture(sprEliMano, 1);
txtManoLUR = sprite_get_texture(sprEliMano, 3);
txtManoLU = sprite_get_texture(sprEliMano, 3);
txtManoLUL = sprite_get_texture(sprEliMano, 3);
txtManoLL = sprite_get_texture(sprEliMano, 1);
txtManoLDL = sprite_get_texture(sprEliMano, 1);
txtManoLD = sprite_get_texture(sprEliMano, 3);
txtManoLDR = sprite_get_texture(sprEliMano, 3);

Esa es la textura de la mano. Hay 2 posibles valores. Al testearlo ANTES de aplicar el código anterior de la surface, SE DIBUJA CORRECTAMENTE, es decir, en 3 casos se usa la subimagen 1, y en 5 casos la subimagen 3. Es decir, que las texturas originales funcionan, y el draw es correcto. Cuando hago el código de la surface que os he puesto antes, QUE SOLO MODIFICA ESAS TEXTURAS ANTERIORMENTE CREADAS CUYO DRAW EJECUTABA BIEN, al instante pasa a dibujarse sólo la subimagen 3 para los ocho casos, es decir, el código que hago en step, al pulsar la tecla P, con las surfaces, DEBE estar mal

scrIniciaCambioTextura(128);
    draw_sprite(sprEliMano, 1, 64, 64);
    draw_sprite(sprEliPluma, 0, 64, 64);
    txtManoLR = scrAsignaCambioTextura(128);
   
    scrIniciaCambioTextura(128);
    draw_sprite(sprEliMano, 3, 64, 64);
    draw_sprite(sprEliPluma, 1, 64, 64);
    txtManoLUR = scrAsignaCambioTextura(128);
   
    scrIniciaCambioTextura(128);
    draw_sprite(sprEliMano, 3, 64, 64);
    draw_sprite(sprEliPluma, 2, 64, 64);
    txtManoLU = scrAsignaCambioTextura(128);
   
    scrIniciaCambioTextura(128);
    draw_sprite(sprEliMano, 3, 64, 64);
    draw_sprite(sprEliPluma, 3, 64, 64);
    txtManoLUL = scrAsignaCambioTextura(128);
   
    scrIniciaCambioTextura(128);
    draw_sprite(sprEliMano, 1, 64, 64);
    draw_sprite(sprEliPluma, 4, 64, 64);
    txtManoLL = scrAsignaCambioTextura(128);
   
    scrIniciaCambioTextura(128);
    draw_sprite(sprEliMano, 1, 64, 64);
    draw_sprite(sprEliPluma, 5, 64, 64);
    txtManoLDL = scrAsignaCambioTextura(128);
   
    scrIniciaCambioTextura(128);
    draw_sprite(sprEliMano, 3, 64, 64);
    draw_sprite(sprEliPluma, 6, 64, 64);
    txtManoLD = scrAsignaCambioTextura(128);
   
    scrIniciaCambioTextura(128);
    draw_sprite(sprEliMano, 3, 64, 64);
    draw_sprite(sprEliPluma, 7, 64, 64);
    txtManoLDR = scrAsignaCambioTextura(128);


Y ahí véis claramente que, igual que la textura original, yo asigno la 1 en tres casos, y la 3 en cinco casos, pero los ocho se dibujan como la 3. Igual que con la Pluma, que asigno 8 subimágenes distintas, pero a la hora de dibujar sólo se aplica la número 0 en los ocho casos. Y el draw es correcto por lo dicho anteriormente, que antes de aplicar esto el draw va bien.

Debe haber algo que se me escapa con la surface, si realmente no encontrárais error os puedo pasar el draw, pero prefiero no hacerlo si no hace falta, porque veo que funciona
Título: Re:Mi surface actúa de forma muy extraña
Publicado por: penumbra en Febrero 06, 2015, 02:34:26 AM
Este código
if (!surface_exists(surface128)) surface128 = surface_create(128, 128);
    surface_set_target(surface128);
    draw_clear_alpha(c_white, 0);

¿corresponde a scrIniciaCambioTextura();?

y este otro
surface_reset_target();
return surface_get_texture(surface128);

¿corresponde a scrAsignaCambioTextura?
Título: Re:Mi surface actúa de forma muy extraña
Publicado por: DarkKRuleR en Febrero 06, 2015, 03:03:47 AM
Exacto
Título: Re:Mi surface actúa de forma muy extraña
Publicado por: DarkKRuleR en Febrero 07, 2015, 08:54:09 PM
up
Título: Re:Mi surface actúa de forma muy extraña
Publicado por: penumbra en Febrero 07, 2015, 09:40:09 PM
No logro ver dónde está la falla. Quizás en otra parte del código. Yo usaría el debugger para ver si los indices de las texturas son diferentes JUSTO ANTES de dibujarlas en DRAW. Tengo una duda. En el primer código que subiste, escribiste:

scrIniciaCambioTextura();
    draw_sprite(sprEliMano, 1, 64, 64);
    draw_sprite(sprEliPluma, 0, 64, 64);
    textura1 = scrAsignaCambioTextura();


pero en el último mensaje, le estás pasando argumentos a los dos scripts
scrIniciaCambioTextura(128);
    draw_sprite(sprEliMano, 1, 64, 64);
    draw_sprite(sprEliPluma, 0, 64, 64);
    txtManoLR = scrAsignaCambioTextura(128);


¿Qué hace el 128? porque en el código de ambos scripts, al menos los que pusiste al principio, no había nada para hacer referencia a argumentos, y cuando hay esta discrepancia, GM lanza un error. Fuera de eso, el código me parece bien, Compruebas si existe una surface, la limpias, dibujas en ella, cambias el target de nuevo a la pantalla, devuelves el índice de la textura y la guardas en una variable. Eso se ve bien, a mi entender. Lo que no tengo claro es las coordenadas de 64, 64 que usas para dibujar los sprites, pero supongo que tiene que ver con cómo tienes acomodados los orígenes de los sprites.
Título: Re:Mi surface actúa de forma muy extraña
Publicado por: DarkKRuleR en Febrero 09, 2015, 08:11:48 PM
Olvida el 128, es para detectar si debo crear-usar-devolver una surface de 128x128 o de 64x64, depende el tamaño de los sprites. Las coordenadas son porque el centro del sprite es el origen.

No entiendo lo que dices de mirar los índices de las texturas.. si yo tengo una variable que guarda una textura, la uso para dibujar, todo correcto, y al hacer el cambio... las 8 texturas se guardan con la MISMA imagen, cuando claramente no es así, la cosa es que... se asigna una misma a las 8, es muuy raro. No acabo de entender qué hacer :(

En el ejemplo que os puse arriba:
draw_sprite(sprEliPluma, i, 64, 64);

donde 0 <= i <= 7, añado distintas subimágenes de Pluma a cada textura, pues he hecho la prueba, y se utiliza la subimagen i=7 en las OCHO texturas cuando, claramente, guardo una distinta en cada una... es decir, es como si, al acabar el código, guardara en las OCHO texturas el resultado de la ÚLTIMA, cuando claramente estoy guardando una imagen distinta en cada textura
Título: Re:Mi surface actúa de forma muy extraña
Publicado por: penumbra en Febrero 09, 2015, 08:24:28 PM
Pues al menos ya diste con el problema. EN algún (código que no pegaste en los ejemplos de arriba) se está dibujando la última subimagen. Podrías ponerle comentarios a todos los draw e ir habilitando uno por una para ver cuál actúa de manera incorrecta
Título: Re:Mi surface actúa de forma muy extraña
Publicado por: DarkKRuleR en Febrero 09, 2015, 09:07:34 PM
Perdona por liar tanto el problema, vengo con el testeo DEFINITIVO. SIN FUNCIONES AUXILIARES, así es más fácil

// Pruebas
if (keyP(ord('P'))) {
    d3d_end(); d3d_set_lighting(false);
    if (!surface_exists(surface128)) surface128 = surface_create(128, 128);
    surface_set_target(surface128);
   
    draw_clear_alpha(c_white, 0);
        draw_sprite(sprEliMano, 1, 64, 64);
        draw_sprite(sprEliPluma, 0, 64, 64);
    txtManoLR = surface_get_texture(surface128);
   
    draw_clear_alpha(c_white, 0);
        draw_sprite(sprEliMano, 3, 64, 64);
        draw_sprite(sprEliPluma, 1, 64, 64);
    txtManoLUR = surface_get_texture(surface128);
   
    draw_clear_alpha(c_white, 0);
        draw_sprite(sprEliMano, 3, 64, 64);
        draw_sprite(sprEliPluma, 2, 64, 64);
    txtManoLU = surface_get_texture(surface128);
   
    draw_clear_alpha(c_white, 0);
        draw_sprite(sprEliMano, 3, 64, 64);
        draw_sprite(sprEliPluma, 3, 64, 64);
    txtManoLUL = surface_get_texture(surface128);
   
    draw_clear_alpha(c_white, 0);
        draw_sprite(sprEliMano, 1, 64, 64);
        draw_sprite(sprEliPluma, 4, 64, 64);
    txtManoLL = surface_get_texture(surface128);
   
    draw_clear_alpha(c_white, 0);
        draw_sprite(sprEliMano, 1, 64, 64);
        draw_sprite(sprEliPluma, 5, 64, 64);
    txtManoLDL = surface_get_texture(surface128);
   
    draw_clear_alpha(c_white, 0);
        draw_sprite(sprEliMano, 3, 64, 64);
        draw_sprite(sprEliPluma, 6, 64, 64);
    txtManoLD = surface_get_texture(surface128);
   
    draw_clear_alpha(c_white, 0);
        draw_sprite(sprEliMano, 3, 64, 64);
        draw_sprite(sprEliPluma, 7, 64, 64);
    txtManoLDR = surface_get_texture(surface128);
   
    if (txtManoLR == txtManoLUR and txtManoLUR == txtManoLU and txtManoLU == txtManoLUL and txtManoLUL == txtManoLL and txtManoLL == txtManoLDL and txtManoLDL == txtManoLD and txtManoLD == txtManoLDR) show_message("EL MUNDO ESTA LOCO");
   
    surface_reset_target();
    d3d_start(); d3d_set_lighting(true);
}


Adivina qué... un precioso cartel mostrando EL MUNDO ESTA LOCO se muestra ^_^ La idea es que LAS OCHO TEXTURAS acaban siendo la misma, no tenía nada que ver con el draw... es MUY RARO. Y lo más raro, esque las ocho son igual a la ÚLTIMA. Este código lo tengo en step, press tecla, para cambiar la textura

Las 8 variables de textura las inicio en Create, y son diferentes (testeado al hacer draw)

NOTA: en la versión anterior, que TAMPOCO funcionaba, hacía un set_target ANTES de CADA draw, y un reset_target al final, antes de coger CADA la textura. El problema puede no ser ese
Título: Re:Mi surface actúa de forma muy extraña
Publicado por: penumbra en Febrero 09, 2015, 09:26:40 PM
Cita de: DarkKRuleR en Febrero 09, 2015, 09:07:34 PM
Y lo más raro, esque las ocho son igual a la ÚLTIMA. Este código lo tengo en step, press tecla, para cambiar la textura

No es raro, es normal, eso es lo que hace tu código. Como en el último código que pusiste, no hay una orden para limpiar la surface antes de dibujar en ella, pues todo se dibuja empalmado, y sólo se ve lo último que se dibujó, que es la subimagen 7 (si es que esa subimagen ocupa toda la superficie del sprite y no tiene áreas transparentes)

Si todos los sprites son del mismo tamaño y todos tienen el mismo origen y todos son completamente opacos, entonces siempre se va a ver el último que se dibuje en la surface (antes de dibujar la surface en draw).


Creo que ya sé lo que está pasando y ya  recordé por qué te mencioné que usaras el debugger para ver el id de la textura. Quizás me equivoque, pero el problema es que estás usando la función
surface_get_texture(surface_id); Cada que dibujas algo en la textura, usas distintas variables para almacenar el ÍNDICE de la textura. Tú vas dibujando distintas cosas en la surface, pero lo que se guarda en esas variables ES SIEMPRE LO MISMO, EL ÍNDICE DE TEXTURA, QUE SIEMPRE ES LA MISMA TEXTURA, POR LO TANTO LAS 8 VARIABLES CONTIENEN UN PUNTERO (COMO LO INDICA EL MANUAL) QUE ES EL MISMO SIEMPRE, Y CUANDO USAS ESE PUNTERO EN DRAW, SE DIBUJA LO MISMO, ES DECIR, LO ÚLTIMO QUE SE DIBUJÓ EN LA TEXTURA.


Solución (SI ES QUE MI RAZONAMIENTO ESTÁ BIEN): no guardar un puntero en las variables, guardar una textura distinta en cada una.

Título: Re:Mi surface actúa de forma muy extraña
Publicado por: DarkKRuleR en Febrero 09, 2015, 10:09:34 PM
Tiene sentido.. o sea, que surface_get_texture no devuelve la textura en sí, sino un puntero a la textura DE LA SURFACE... lo cual a su vez es malo, porque si la surface se borra daría error... pero tiene muuucho sentido...
PD: probé lo del debugger pero no me daba ninguna información (la nueva actualización del GM Studio..), a parte no sabía a qué te referías con id de textura, porque yo pensaba que el get_texture te daba literalmente la textura, no un puntero

EDIT: vale, el manual dice específicamente que devuelve un puntero (qué ganas de liar...) mi culpa, pensé que había leido el manual, se me escapó eso.

background_get_texture(background_create_from_surface(surface128, 0, 0, 128, 128, false, false));

Con esto ya funciona, muchas gracias :D tema resuelto