• Hey Guest! Ever feel like entering a Game Jam, but the time limit is always too much pressure? We get it... You lead a hectic life and dedicating 3 whole days to make a game just doesn't work for you! So, why not enter the GMC SLOW JAM? Take your time! Kick back and make your game over 4 months! Interested? Then just click here!

Texture Each Side Of A Cube

OliverSB

Member
How do I learn how to create 3D games in gamemaker. Is there certain types of maths to study to achieve different effects with gamemaker studio 2?

In this specific case, I have worked out that vertex_submit allows me to submit a texture. But how do I make it so each side has its own texture?

An example, of another problem I would have trouble working out without any guidance is allowing user to click on any side of the cube to change the texture.

Like this stuff seems relativity complex problems for me to solve and idk how people manage to pull off these crazy 3d effects. Gotta start somewhere but no idea were I start. All I know is I want to create a simple 3d game.

I've been thinking about creating my own custom 3d level design tools in gamemaker but at this moment I am trying to make a simple game.
 

GMWolf

aka fel666
Is there certain types of maths to study to achieve different effects with gamemaker studio 2?
Learn vectors and matrices.

In this specific case, I have worked out that vertex_submit allows me to submit a texture. But how do I make it so each side has its own texture?
There are quite a few ways of doing so:
You could submit each face separately with different textures.
You could have each face using different UVs (texture coordinates) and have one texture with the different faces on it.
Or (advanced) you could use multitexturing, where you setup multiple textures for a shader to use.


I would recommend you start with the first option. Just draw each face separately.
Then when you have that running, try changing the texture coordinates of your faces and see how you can use it to change what portion of the texture your face shows.
Then, try to have it so all faces use the same texture, but show a different portion of it.
 

marasovec

Member
I made a vertex cube with UV and repetitive textures and it was really hard to find a solution so I hope this will make your work easier :D

Each block has 8x8x8 pixels so if you need them bigger just change the "8" values

create event:
Code:
z = 0;
height = 8;
alarm 1: (activated from obj_game_control)
Code:
image_xscale = round(image_xscale);
image_yscale = round(image_yscale);
ixs = image_xscale*8;
iys = image_yscale*8;

for(var ih = 0; ih < height; ih += 8)
    {
    for(var iy = 0; iy < iys; iy += 8)
        {
        // side4
        vertex_position_3d(obj_game_control.buff_grass, x, y+iy, z+ih);
        vertex_texcoord(obj_game_control.buff_grass, 0.75, 0.25);
        vertex_position_3d(obj_game_control.buff_grass, x, y+iy, z+ih+8);
        vertex_texcoord(obj_game_control.buff_grass, 1, 0.25);
        vertex_position_3d(obj_game_control.buff_grass, x, y+iy+8, z+ih);
        vertex_texcoord(obj_game_control.buff_grass, 0.75, 0.5);
        vertex_position_3d(obj_game_control.buff_grass, x, y+iy, z+ih+8);
        vertex_texcoord(obj_game_control.buff_grass, 1, 0.25);
        vertex_position_3d(obj_game_control.buff_grass, x, y+iy+8, z+ih+8);
        vertex_texcoord(obj_game_control.buff_grass, 1, 0.5);
        vertex_position_3d(obj_game_control.buff_grass, x, y+iy+8, z+ih);
        vertex_texcoord(obj_game_control.buff_grass, 0.75, 0.5);
        // side2
        vertex_position_3d(obj_game_control.buff_grass, x+ixs, y+iy+8, z+ih);
        vertex_texcoord(obj_game_control.buff_grass, 0.25, 0.25);
        vertex_position_3d(obj_game_control.buff_grass, x+ixs, y+iy+8, z+ih+8);
        vertex_texcoord(obj_game_control.buff_grass, 0.5, 0.25);
        vertex_position_3d(obj_game_control.buff_grass, x+ixs, y+iy, z+ih);
        vertex_texcoord(obj_game_control.buff_grass, 0.25, 0.5);
        vertex_position_3d(obj_game_control.buff_grass, x+ixs, y+iy+8, z+ih+8);
        vertex_texcoord(obj_game_control.buff_grass, 0.5, 0.25);
        vertex_position_3d(obj_game_control.buff_grass, x+ixs, y+iy, z+ih+8);
        vertex_texcoord(obj_game_control.buff_grass, 0.5, 0.5);
        vertex_position_3d(obj_game_control.buff_grass, x+ixs, y+iy, z+ih);
        vertex_texcoord(obj_game_control.buff_grass, 0.25, 0.5);
        }
    for(var ix = 0; ix < ixs; ix += 8)
        {
        // side1
        vertex_position_3d(obj_game_control.buff_grass, x+ix+8, y, z+ih);
        vertex_texcoord(obj_game_control.buff_grass, 0, 0.25);
        vertex_position_3d(obj_game_control.buff_grass, x+ix+8, y, z+ih+8);
        vertex_texcoord(obj_game_control.buff_grass, 0.25, 0.25);
        vertex_position_3d(obj_game_control.buff_grass, x+ix, y, z+ih);
        vertex_texcoord(obj_game_control.buff_grass, 0, 0.5);
        vertex_position_3d(obj_game_control.buff_grass, x+ix+8, y, z+ih+8);
        vertex_texcoord(obj_game_control.buff_grass, 0.25, 0.25);
        vertex_position_3d(obj_game_control.buff_grass, x+ix, y, z+ih+8);
        vertex_texcoord(obj_game_control.buff_grass, 0.25, 0.5);
        vertex_position_3d(obj_game_control.buff_grass, x+ix, y, z+ih);
        vertex_texcoord(obj_game_control.buff_grass, 0, 0.5);
        // side3
        vertex_position_3d(obj_game_control.buff_grass, x+ix, y+iys, z+ih);
        vertex_texcoord(obj_game_control.buff_grass, 0.5, 0.25);
        vertex_position_3d(obj_game_control.buff_grass, x+ix, y+iys, z+ih+8);
        vertex_texcoord(obj_game_control.buff_grass, 0.75, 0.25);
        vertex_position_3d(obj_game_control.buff_grass, x+ix+8, y+iys, z+ih);
        vertex_texcoord(obj_game_control.buff_grass, 0.5, 0.5);
        vertex_position_3d(obj_game_control.buff_grass, x+ix, y+iys, z+ih+8);
        vertex_texcoord(obj_game_control.buff_grass, 0.75, 0.25);
        vertex_position_3d(obj_game_control.buff_grass, x+ix+8, y+iys, z+ih+8);
        vertex_texcoord(obj_game_control.buff_grass, 0.75, 0.5);
        vertex_position_3d(obj_game_control.buff_grass, x+ix+8, y+iys, z+ih);
        vertex_texcoord(obj_game_control.buff_grass, 0.5, 0.5);
        }
    }

for(var iy = 0; iy < iys; iy += 8)
    {
    for(var ix = 0; ix < ixs; ix += 8)
        {
        // top
        vertex_position_3d(obj_game_control.buff_grass, x+ix, y+iy, z+height);
        vertex_texcoord(obj_game_control.buff_grass, 0.25, 0);
        vertex_position_3d(obj_game_control.buff_grass, x+ix+8, y+iy, z+height);
        vertex_texcoord(obj_game_control.buff_grass, 0.5, 0);
        vertex_position_3d(obj_game_control.buff_grass, x+ix, y+iy+8, z+height);
        vertex_texcoord(obj_game_control.buff_grass, 0.25, 0.25);
        vertex_position_3d(obj_game_control.buff_grass, x+ix+8, y+iy, z+height);
        vertex_texcoord(obj_game_control.buff_grass, 0.5, 0);
        vertex_position_3d(obj_game_control.buff_grass, x+ix+8, y+iy+8, z+height);
        vertex_texcoord(obj_game_control.buff_grass, 0.5, 0.25);
        vertex_position_3d(obj_game_control.buff_grass, x+ix, y+iy+8, z+height);
        vertex_texcoord(obj_game_control.buff_grass, 0.25, 0.25);
        // floor
        vertex_position_3d(obj_game_control.buff_grass, x+ix+8, y+iy, z);
        vertex_texcoord(obj_game_control.buff_grass, 0.25, 0.5);
        vertex_position_3d(obj_game_control.buff_grass, x+ix, y+iy, z);
        vertex_texcoord(obj_game_control.buff_grass, 0.5, 0.5);
        vertex_position_3d(obj_game_control.buff_grass, x+ix+8, y+iy+8, z);
        vertex_texcoord(obj_game_control.buff_grass, 0.25, 0.75);
        vertex_position_3d(obj_game_control.buff_grass, x+ix, y+iy, z);
        vertex_texcoord(obj_game_control.buff_grass, 0.5, 0.5);
        vertex_position_3d(obj_game_control.buff_grass, x+ix, y+iy+8, z);
        vertex_texcoord(obj_game_control.buff_grass, 0.5, 0.75);
        vertex_position_3d(obj_game_control.buff_grass, x+ix+8, y+iy+8, z);
        vertex_texcoord(obj_game_control.buff_grass, 0.25, 0.75);
        }
    }


(I use a control object that loads and draws all vertexes at once because it's faster)

create event
Code:
vertex_format_begin();
vertex_format_add_position_3d();
vertex_format_add_textcoord();
format = vertex_format_end();

buff_grass = vertex_create_buffer();
tex_grass = -1;

alarm[0] = 2; // let all the blocks load before drawing them
alarm 0:
Code:
if instance_exists(obj_block_grass)
    {
    vertex_begin(buff_grass, format);
    with(obj_block_grass) event_perform(ev_alarm, 0); // call the obj_grass_blocks alarms and load the vertex stuff from ALL grass blocks
    vertex_end(buff_grass);
    vertex_freeze(buff_grass);
    tex_grass = background_get_texture(uv_grass); break;
    }
draw event:
Code:
if tex_grass != -1 vertex_submit(buff_grass, pr_trianglelist, tex_grass);

Because I'm an idiot I somehow rotated the all vertexes so sides have to be rotated to -90° to be drawn correctly

uv_grass


uv map placement


result:
 
Last edited:

marasovec

Member
Or here's an easier, shorter version where every block draws only itself
create event
Code:
z = 0;
height = 8;
once = false;

vertex_format_begin();
vertex_format_add_position_3d();
vertex_format_add_textcoord();
format = vertex_format_end();

buff = vertex_create_buffer();
step event
Code:
if once exit;
once = true;

var ixs = image_xscale*8;
var iys = image_yscale*8;

vertex_begin(buff, format);

for(var ih = 0; ih < height; ih += 8)
    {
    for(var iy = 0; iy < ixs; iy += 8)
        {
        // s4
        vertex_position_3d(buff, x, y+iy, z+ih);
        vertex_texcoord(buff, 0.75, 0.25);
        vertex_position_3d(buff, x, y+iy, z+ih+8);
        vertex_texcoord(buff, 1, 0.25);
        vertex_position_3d(buff, x, y+iy+8, z+ih);
        vertex_texcoord(buff, 0.75, 0.5);
        vertex_position_3d(buff, x, y+iy, z+ih+8);
        vertex_texcoord(buff, 1, 0.25);
        vertex_position_3d(buff, x, y+iy+8, z+ih+8);
        vertex_texcoord(buff, 1, 0.5);
        vertex_position_3d(buff, x, y+iy+8, z+ih);
        vertex_texcoord(buff, 0.75, 0.5);
        // s2
        vertex_position_3d(buff, x+ixs, y+iy+8, z+ih);
        vertex_texcoord(buff, 0.25, 0.25);
        vertex_position_3d(buff, x+ixs, y+iy+8, z+ih+8);
        vertex_texcoord(buff, 0.5, 0.25);
        vertex_position_3d(buff, x+ixs, y+iy, z+ih);
        vertex_texcoord(buff, 0.25, 0.5);
        vertex_position_3d(buff, x+ixs, y+iy+8, z+ih+8);
        vertex_texcoord(buff, 0.5, 0.25);
        vertex_position_3d(buff, x+ixs, y+iy, z+ih+8);
        vertex_texcoord(buff, 0.5, 0.5);
        vertex_position_3d(buff, x+ixs, y+iy, z+ih);
        vertex_texcoord(buff, 0.25, 0.5);
        }
    for(var ix = 0; ix < iys; ix += 8)
        {
        // s1
        vertex_position_3d(buff, x+ix+8, y, z+ih);
        vertex_texcoord(buff, 0, 0.25);
        vertex_position_3d(buff, x+ix+8, y, z+ih+8);
        vertex_texcoord(buff, 0.25, 0.25);
        vertex_position_3d(buff, x+ix, y, z+ih);
        vertex_texcoord(buff, 0, 0.5);
        vertex_position_3d(buff, x+ix+8, y, z+ih+8);
        vertex_texcoord(buff, 0.25, 0.25);
        vertex_position_3d(buff, x+ix, y, z+ih+8);
        vertex_texcoord(buff, 0.25, 0.5);
        vertex_position_3d(buff, x+ix, y, z+ih);
        vertex_texcoord(buff, 0, 0.5);
        // s3
        vertex_position_3d(buff, x+ix, y+iys, z+ih);
        vertex_texcoord(buff, 0.5, 0.25);
        vertex_position_3d(buff, x+ix, y+iys, z+ih+8);
        vertex_texcoord(buff, 0.75, 0.25);
        vertex_position_3d(buff, x+ix+8, y+iys, z+ih);
        vertex_texcoord(buff, 0.5, 0.5);
        vertex_position_3d(buff, x+ix, y+iys, z+ih+8);
        vertex_texcoord(buff, 0.75, 0.25);
        vertex_position_3d(buff, x+ix+8, y+iys, z+ih+8);
        vertex_texcoord(buff, 0.75, 0.5);
        vertex_position_3d(buff, x+ix+8, y+iys, z+ih);
        vertex_texcoord(buff, 0.5, 0.5);
        }
    }

for(var iy = 0; iy < ixs; iy += 8)
    {
    for(var ix = 0; ix < iys; ix += 8)
        {
        // top
        vertex_position_3d(buff, x+ix, y+iy, z+height);
        vertex_texcoord(buff, 0.25, 0);
        vertex_position_3d(buff, x+ix+8, y+iy, z+height);
        vertex_texcoord(buff, 0.5, 0);
        vertex_position_3d(buff, x+ix, y+iy+8, z+height);
        vertex_texcoord(buff, 0.25, 0.25);
        vertex_position_3d(buff, x+ix+8, y+iy, z+height);
        vertex_texcoord(buff, 0.5, 0);
        vertex_position_3d(buff, x+ix+8, y+iy+8, z+height);
        vertex_texcoord(buff, 0.5, 0.25);
        vertex_position_3d(buff, x+ix, y+iy+8, z+height);
        vertex_texcoord(buff, 0.25, 0.25);
        // floor
        vertex_position_3d(buff, x+ix+8, y+iy, z);
        vertex_texcoord(buff, 0.25, 0.5);
        vertex_position_3d(buff, x+ix, y+iy, z);
        vertex_texcoord(buff, 0.5, 0.5);
        vertex_position_3d(buff, x+ix+8, y+iy+8, z);
        vertex_texcoord(buff, 0.25, 0.75);
        vertex_position_3d(buff, x+ix, y+iy, z);
        vertex_texcoord(buff, 0.5, 0.5);
        vertex_position_3d(buff, x+ix, y+iy+8, z);
        vertex_texcoord(buff, 0.5, 0.75);
        vertex_position_3d(buff, x+ix+8, y+iy+8, z);
        vertex_texcoord(buff, 0.25, 0.75);
        }
    }
vertex_end(buff);
vertex_freeze(buff);

tex = background_get_texture(uv_grass);
draw event
Code:
vertex_submit(buff, pr_trianglelist, tex);
 

OliverSB

Member
I ended up just using vertex_submit for each individual texture. marasovec's solution looks good though. Good to know how to plot the UV coordinates on a cube.
 
Top