Skocz do zawartości

Surface - Optymalizacja


Rekomendowane odpowiedzi

Hej, kolejne pytanie dotyczyć będzie optymalizacji, z racji tego, iż zacząłem bawić się w efekty cząsteczkowe, oraz, że w roomach znajduje się często dużo obiektów, zaczęły ostro spadać FPSy. Zauważyłem, że najwięcej zżerają ściany i podobne obiekty solid, oraz wszelkiego rodzaju pierdoły(kamyki, patyki, śmieci). Dezaktywacja się średnio spisuje, ponieważ mimo tego samego punktu wyłączania przeciwników i obiektów solid, po ponownej aktywacji wrogowie potrafią siedzieć w ścianach, albo w innych dziwnych miejscach, generalnie słabo. Postanowiłem spróbować z surface, które nie wiem, czy w ogóle w jakimkolwiek stopniu działa, ponieważ po jego włączeniu obiekty typu ściany i w sumie wszystkie objęte surfem stają się... cieniami, przez które można przeniknąć. 

Screen - bez surface

Screen - z surface

 

Kod surface wygląda następująco :

 

Create:

surface = surface_create( room_width , room_height )
surface_set_target( surface )
draw_set_color( c_white )
draw_rectangle( 0 , 0 , room_width , room_height , 0 ) 



for( i = 0 ; i < instance_number( cialo_par ) ; i += 1 )
{
    ID = instance_find( cialo_par , i )
    draw_sprite_ext( ID. sprite_index , 0 , ID.x , ID.y , ID.image_xscale , ID.image_yscale , ID.image_angle , -1 , 1 )
}

surface_reset_target()
with( cialo_par ) instance_destroy()

Draw:

 


draw_set_blend_mode_ext( bm_dest_color , bm_zero )
draw_surface( surface , 0 , 0 )
draw_set_blend_mode( bm_normal )

"cialo_par" - To rodzina tych obiektów, które mają być optymalizowane. Dlaczego pojawia się taki durny efekt ?

Odnośnik do komentarza
Udostępnij na innych stronach

  • Administratorzy

1) nie rysujemy poza draw w Studio

2) trzeba sprawdzać czy surface istnieje w każdym kroku

// create
surf = -1;

// draw
if (!surface_exists(surf)) {
    surf = surface_create(...);
}

surface_set_target(surf);
... rysujemy
surface_reset_target();
...
draw_surface(....);

Nie mniej to niewiele pomoże, bo GM i tak sam odrzuca z rysowania to co jest poza ekranem :) A efekt pojawia się bo robisz jakieś draw_set_blend_mode_ext nie wiadomo po co.

Odnośnik do komentarza
Udostępnij na innych stronach

No okej, obiekty wróciły, ale zniknął kursor za to, jakim cudem ? :D

 

Taki kod w DRAW, nie dość, że kursora ni ma, to FPS spadł bardziej, niż wcześniej xd

 

if (!surface_exists(surf)) {
    surf = surface_create( room_width , room_height );
}

surface_set_target(surf);
draw_set_color( c_white )
draw_rectangle( 0 , 0 , room_width , room_height , 0 ) 



for( i = 0 ; i < instance_number( cialo_par ) ; i += 1 )
{
    ID = instance_find( cialo_par , i )
    draw_sprite_ext( ID. sprite_index , 0 , ID.x , ID.y , ID.image_xscale , ID.image_yscale , ID.image_angle , -1 , 1 )
}
surface_reset_target();

draw_surface(surf,room_width , room_height);





 

Odnośnik do komentarza
Udostępnij na innych stronach

Mam swój własny, ale nie widać żadnego. Zamieniłem rozmiar rooma, na view, zrobił się jeszcze większy bajzel, nadal tnie, a przy okazji wszystko zniknęło.

 

Draw

if (!surface_exists(surf)) {
    surf = surface_create( x+view_xview, y+view_yview );
}

surface_set_target(surf);
draw_set_color( c_white )
draw_rectangle( 0 , 0 ,  x+view_xview , y+view_yview , 0 ) 



for( i = 0 ; i < instance_number( cialo_par ) ; i += 1 )
{
    ID = instance_find( cialo_par , i )
    draw_sprite_ext( ID. sprite_index , 0 , ID.x , ID.y , ID.image_xscale , ID.image_yscale , ID.image_angle , -1 , 1 )
}
surface_reset_target();

draw_surface(surf, x+view_xview[0] , y+view_yview[0]);





 

Odnośnik do komentarza
Udostępnij na innych stronach

Próbowałem na różne sposoby i nadal się ów proceder powtarzał, poza tym z samej deaktywacji niewiele wynika, bo czasem się ostro odwala w samym polu widzenia (przy jakiejś ostrzejszej wymianie ognia wszystko fruwa) Uważam, że deaktywacja, tylko po części rozwiązuje problem, potrzebne też są surface.

Odnośnik do komentarza
Udostępnij na innych stronach

A ta krew i części ciała to wszystko są osobne instancje? Ja kiedyś jak robiłem takie efekty to miałem surface 256x256 i rysowałem na nim wszystkie efekty krwi po czym robiłem z tego texturę i kładłem ją na ziemi po czym usuwałem instancje. 

Texturki były położone jak tilesy obok siebie, taka technika podobna do wypalania statycznej Light Mapy

Odnośnik do komentarza
Udostępnij na innych stronach

Jak dobrze pamiętam on to robi w GM8.1 a tam 200 pustych instancji na ekranie i już spadki fpsów są :D

 

Z ciekawości zrobiłem mały test bo nigdy go nie robiłem go w GMS2, wygenerowałem 30000 instancji na ekranie które rysują jeden z 3 spritów:

NReIKMT.png

 

I ku mojemu zdziwieniu jeszcze trochę ich by tam weszło zanim by fps spadł poniżej 60. 
Weź to zrób w starszych GMach :D:D 

Odnośnik do komentarza
Udostępnij na innych stronach

Sorki, mam mały remont na kwadracie, nie miałem jak odpisać. Sprawa wygląda tak: Każdy kawałek, krew itp jest osobnym obiektem, które ma zapisane w create np. losowy kierunek itp.

Po drugie, programuję w GM8 (nie w 8.1 - bo jest jakiś niedorobiony) Wiem, że to prehistoryczny program, ale jakoś nie mam ochoty łożyć na GMSa, grami zajmuję się w charakterze hobby ^^  A co do kradnięcia pamięci, to wiele obiektów robi cienie, za pomocą draw, po drugie, same ciała, ze względu na zastosowany ragdoll mogą mulić(aczkolwiek same ciała chyba aż tak nie szkodzą) w każdym poziomie jest sporo titlesetów. 

Także jeszcze raz, co powinienem zrobić, niekoniecznie zmieniając efekty, które już zaimplementowałem. Pozdro ;)

@Edit Same ciała nie mulą, bardziej te wszystkie flaki, odłamki itp, podejrzewam, że solidy też mogą mieć swój wkład w to.

Odnośnik do komentarza
Udostępnij na innych stronach

Znalazłem w pomocy zakładkę "Drawing Surface" - oto wpis:

 

Cytuj

This functionality is only available in the Pro Edition of Game Maker.

In certain situations you might want to paint not directly on the screen but on a canvas that can then later be used to paint things on the screen. Such a canvas is called a surface. For example, you want to let the user draw on the screen. The paint should not be drawn on the screen (because it will be removed each next step), but instead you want to draw it on a separate surface that is copied onto the screen in each step. Or you want to use a texture that changes over time.

Surfaces make this all possible. They are actually rather simple to use. You first create a surface. Next you indicate that further drawing should happen on this surface. From that moment on all drawing functions operate on the surface. Once you are done you reset the drawing target and further drawing happens on the screen again. You can draw the surface on the screen in many different ways or use it as a texture. There are though a few things you must be aware of. See the remarks at the end.

The following functions exist to deal with surfaces

 

surface_create(w,h) Creates a surface of the indicated width and height. Returns the id of the surface, which must be used in all further calls. Note that the surface will not be cleared. This is the responsibility of the user. (Set it as a target and call the appropriate clear function.)
surface_free(id) Frees the memory used by the surface.
surface_exists(id) Returns whether the surface with the indicated id exists.

surface_get_width(id) Returns the width of the surface.
surface_get_height(id) Returns the height of the surface.
surface_get_texture(id) Returns the texture corresponding to the surface. This can be used to draw textured objects with the image of the surface.

surface_set_target(id) Sets the indicated surface as the drawing target. All subsequent drawing happens on this surface. It resets the projection to simply cover the surface.
surface_reset_target() Resets the drawing target to the normal screen.

surface_getpixel(id,x,y) Returns the color of the pixel corresponding to position (x,y) in the surface. This is not very fast, so use with care.
surface_save(id,fname) Saves a png image of the surface in the given filename. Useful for making screenshots.
surface_save_part(id,fname,x,y,w,h) Saves part of the surface in the given png filename.

draw_surface(id,x,y) Draws the surface at position (x,y). (Without color blending and no alpha transparency.)
draw_surface_stretched(id,x,y,w,h) Draws the surface stretched to the indicated region.
draw_surface_tiled(id,x,y) Draws the surface tiled so that it fills the entire room.
draw_surface_part(id,left,top,width,height,x,y) Draws the indicated part of the surface with its origin at position (x,y).
draw_surface_ext(id,x,y,xscale,yscale,rot,color,alpha) Draws the surface scaled and rotated with blending color (use c_white for no blending) and transparency alpha (0-1).
draw_surface_stretched_ext(id,x,y,w,h,color,alpha) Draws the surface stretched to the indicated region. color is the blending color and alpha indicates the transparency setting.
draw_surface_tiled_ext(id,x,y,xscale,yscale,color,alpha) Draws the surface tiled so that it fills the entire room but now with scale factors and a color and transparency setting.
draw_surface_part_ext(id,left,top,width,height,x,y,xscale,yscale,color,alpha) Draws the indicated part of the surface with its origin at position (x,y) but now with scale factors and a color and transparency setting.
draw_surface_general(id,left,top,width,height,x,y,xscale,yscale,rot,c1,c2,c3,c4,alpha) The most general drawing function. It draws the indicated part of the surface with its origin at position (x,y) but now with scale factors, a rotation angle, a color for each of the four vertices (top-left, top-right, bottom-right, and bottom-left), and an alpha transparency value.

surface_copy(destination,x,y,source) Copies the source surface at position (x,y) in the destination surface. (Without any form of blending.)
surface_copy_part(destination,x,y,source,xs,ys,ws,hs) Copies the indicated part of the source surface at position (x,y) in the destination surface. (Without any form of blending.)

Note that there are no functions to copy part of the screen to a surface. (This is impossible due to possible format differences between the screen and the surfaces.) If this is required you must set a surface as render target and next draw the room. You can then use the surface copying routines to get parts of it.

Note that you can also create sprites and backgrounds from surfaces. See the section on changing resources for more information.

Some care must be taken when using these functions. In particular please notice the following:

  • You should never change the drawing target while you are actually drawing on the screen, that is, never use it in drawing events. This will cause serious problems with the projection and viewport.
  • Surfaces do not work correctly with 3D mode. You can use them while not in 3D mode (by calling d3d_end() before using them), but once you start 3D mode again the surfaces will be destroyed.
  • For reasons of speed, the surface is maintained in videomemory only. As a result, you might loose the surface when e.g. the screen resolution changes or the screensaver pops up.
  • Surfaces will not be saved when saving a game.

 

 

Oraz wpis o titlesach:

 

Cytuj

As you should know you can add tiles to rooms. A tile is a part of a background resource. Tiles are just visible images. They do not react to events and they do not generate collisions. As a result, tiles are handled a lot faster than objects. Anything that does not need events or collisions can best be done through tiles. Also, often one better uses a tile for the nice graphics while a simple object is used to generate the collision events.

You actually have more control over tiles than you might think. You can add them when designing the room but you can also add them during the running of the game. You can change their position, and even scale them or make them partially transparent. A tile has the following properties:

  • background. The background resource from which the tile is taken.
  • left, top, width, height. The part of the background that is used.
  • x,y. The position of the top left corner of the tile in the room.
  • depth. The depth of the tile. You can choose any depth you like, making tiles appear between object instances.
  • visible. Whether the tile is visible.
  • xscale, yscale. Each tile can be drawn scaled (default is 1).
  • blend. A blending color used when drawing the tile.
  • alpha. An alpha value indicating tile transparency. 1 = not transparent, 0 = fully transparent.

To change the properties of a particular tile you need to know its id. When you add tiles when creating rooms the id is shown in the information bar at the bottom. There is also a function to find the id of a tile at a particular position.

The following functions exist that deal with tiles:

 

tile_add(background,left,top,width,height,x,y,depth) Adds a new tile to the room with the indicated values (see above for their meaning). The function returns the id of the tile that can be used later on.
tile_delete(id) Deletes the tile with the given id.
tile_exists(id) Returns whether a tile with the given id exists.

tile_get_x(id) Returns the x-position of the tile with the given id.
tile_get_y(id) Returns the y-position of the tile with the given id.
tile_get_left(id) Returns the left value of the tile with the given id.
tile_get_top(id) Returns the top value of the tile with the given id.
tile_get_width(id) Returns the width of the tile with the given id.
tile_get_height(id) Returns the height of the tile with the given id.
tile_get_depth(id) Returns the depth of the tile with the given id.
tile_get_visible(id) Returns whether the tile with the given id is visible.
tile_get_xscale(id) Returns the xscale of the tile with the given id.
tile_get_yscale(id) Returns the yscale of the tile with the given id.
tile_get_background(id) Returns the background of the tile with the given id.
tile_get_blend(id) Returns the blending color of the tile with the given id.
tile_get_alpha(id) Returns the alpha value of the tile with the given id.

tile_set_position(id,x,y) Sets the position of the tile with the given id.
tile_set_region(id,left,top,width,height) Sets the region of the tile with the given id in its background.
tile_set_background(id,background) Sets the background for the tile with the given id.
tile_set_visible(id,visible) Sets whether the tile with the given id is visible.
tile_set_depth(id,depth) Sets the depth of the tile with the given id.
tile_set_scale(id,xscale,yscale) Sets the scaling of the tile with the given id.
tile_set_blend(id,color) Sets the blending color of the tile with the given id. Only available in the Pro Edition!
tile_set_alpha(id,alpha) Sets the alpha value of the tile with the given id.

The following functions deal with layers of tiles, that is, collections of tiles at the same depth.

 

tile_layer_hide(depth) Hides all tiles at the indicated depth layer.
tile_layer_show(depth) Shows all tiles at the indicated depth layer.
tile_layer_delete(depth) Deletes all tiles at the indicated depth layer.
tile_layer_shift(depth,x,y) Shifts all tiles at the indicated depth layer over the vector x,y. Can be used to create scrolling layers of tiles.
tile_layer_find(depth,x,y) Returns the id of the tile with the given depth at position (x,y). When no tile exists at the position -1 is returned. When multiple tiles with the given depth exist at the position the first one is returned.
tile_layer_delete_at(depth,x,y) Deletes the tile with the given depth at position (x,y). When multiple tiles with the given depth exist at the position they are all deleted.
tile_layer_depth(depth,newdepth) Changes the depth of all tiles at the indicated depth to the new depth. With this function you can move whole tile layers to a new depth.

 

 

Odnośnik do komentarza
Udostępnij na innych stronach

  • Administratorzy

tile_add(background,left,top,width,height,x,y,depth) Adds a new tile to the room with the indicated values (see above for their meaning). The function returns the id of the tile that can be used later on.

 

No chyba już sam odpowiedziałeś, raczej nic więcej w GM8 nie ma.

Odnośnik do komentarza
Udostępnij na innych stronach

  • Administratorzy

W tak starym GM, to nawet nam się nie chce szukać, jakie funkcje były dostępne, ale raczej nie. Tam cały pipeline od rysowania inaczej działał, to jest jednak 8/9-letnie oprogramowanie, jeszcze przed Windowsem 8...

Odnośnik do komentarza
Udostępnij na innych stronach

  • Administratorzy
46 minut temu, LolikZabijaka napisał:

Można w jakiś sposób wypróbować gmsa? Niekoniecznie go wykupując, bo nie wiem, czy ten silnik, który mam w ogóle pójdzie.

 

3 sekundy i wiesz, że jest wersja trial za free: https://www.yoyogames.com/get

Odnośnik do komentarza
Udostępnij na innych stronach

Jeśli chcesz dodać odpowiedź, zaloguj się lub zarejestruj nowe konto

Jedynie zarejestrowani użytkownicy mogą komentować zawartość tej strony.

Zarejestruj nowe konto

Załóż nowe konto. To bardzo proste!

Zarejestruj się

Zaloguj się

Posiadasz już konto? Zaloguj się poniżej.

Zaloguj się
  • Ostatnio przeglądający   0 użytkowników

    • Brak zarejestrowanych użytkowników przeglądających tę stronę.
×
×
  • Dodaj nową pozycję...