3D Draw 3d objects to surfaces

angelwire

Member
I was playing around with applying shaders to 3d games when I ran into a roadblock. I can't find any way to draw 3d objects to different surfaces. What I'd like to be able to do is draw the player's first person view 2 or 3 times with different shaders applied to each, and then combine them in the draw GUI action.

So basically what I'd like to do is something like this pseudocode:
(obviously some parts are missing so it's not so long)
Code:
set_surface(lighting_surface)
set_shader(lighting_shader)
d3d_draw_model(...)
reset_shader()
surface_reset_target()

set_surface(outline_surface)
set_shader(outline_shader)
d3d_draw_model(...)
reset_shader()
surface_reset_target()

//Draw GUI
draw_surface(lighting_shader)
draw_surface(outline_shader)
This is basically just some general pseudo code of what I'd like to do, I've tried several different ways but nothing seems to work right.

Is something like this even possible? I've found a complicated workaround using views, but I think that method is pretty slow, and it's definitely not easy to use. I hope I've explained myself well enough, if not I'll be happy to clarify anything.
Thanks for the help.
 
O

orange451

Guest
Of course it's possible!

Try to set your 3d projection when start drawing to a surface. Though without all of your current code, it's hard to diagnose.
 

angelwire

Member
Thanks for the quick reply!
I'm usually reluctant to share the actual code I'm using because of my crazy style that tends to complicate matters, but here's what I have in a test project:

Code:
if surface_exists(gun_surface)
{
surface_set_target(gun_surface)
d3d_set_projection(x,y,z+(dsin(angus)*2),x+(dcos(direction+dsin(angy))*dcos(zdirection)),y-(dsin(direction+dsin(angy))*dcos(zdirection)),z+dsin(zdirection)+(dsin(angus)*2),0,0,1)
d3d_transform_set_identity()
d3d_transform_add_rotation_x(-zdirection)
d3d_transform_add_rotation_z(direction+90)
d3d_transform_add_translation(x,y,z);
d3d_model_draw(my_model,2,0,0,bgt(gun_texture))
d3d_transform_set_identity()
surface_reset_target()
}
else
{
gun_surface = surface_create(1920,1200);
}

d3d_set_projection(x,y,z+(dsin(angus)*2),x+(dcos(direction+dsin(angy))*dcos(zdirection)),y-(dsin(direction+dsin(angy))*dcos(zdirection)),z+dsin(zdirection)+(dsin(angus)*2),0,0,1)

d3d_draw_floor(0,room_height,0,room_width,0,0,bgt(ground_texture),1,1)
d3d_transform_set_identity()
d3d_transform_add_rotation_x(-zdirection)
d3d_transform_add_rotation_z(direction+90)
d3d_transform_add_translation(x,y,z);
d3d_model_draw(my_model,2,0,0,bgt(red_gun_texture))
d3d_transform_set_identity()

//Draw GUI:
draw_surface_ext(application_surface,0,0,window_get_width()/res_x,window_get_height()/res_y,0,c_white,1)
if surface_exists(gun_surface)
{
draw_surface_ext(gun_surface,0,0,1,1,0,c_white,1) // The surface is already the proper size, so I don't need to scale it
}
//I'm not currently using shaders in this project, I'm simplifying things just to get the surfaces working proplerly
The red gun and all the other world objects are being drawn, but the gun_surface is completely blank.
 
O

orange451

Guest
Firstly try something simpler! Ensure that you can get your surfaces working.

HTML:
if ( surface_exists( gun_surface ) ) {
   // Set this as our render-target
   surface_set_target( gun_surface );

   // Clear depth and color buffer to black
   draw_clear_alpha( c_black, 0.0 );

   // Update View and Projection matrices
   d3d_set_projection( 32, 32, 32, 0, 0, 0, 0, 0, 1 );

   // Draw a block inside the cameras frustum
   d3d_draw_block( -8, -8, 16, 8, 8, 0, background_get_texture( gun_texture ), 1, 1 );

   // Reset drawing back to the default frame-buffer
   surface_reset_target();
} else {
   // Create surface
   gun_surface = surface_create( 1920,1200 );
   show_debug_message("Created surface");
}

I put the debug message in, so you can know if the surface is constantly creating itself.
 

angelwire

Member
Wow, that's awesome! All I needed to add was the draw_clear_alpha. I'm curious as to why that's needed, but I'm happy that it finally works. Thank you very much for your help!
 
Top