Jump to content

Rendering Backgrounds/Foregrounds


elcoo
 Share

Recommended Posts

Hi,

I was trying to render a background like I was used to from LE 2.5.

I basicly have 2 worlds: One main world and one background world. The Background would be rendered first, then the main world directly after it, like this:

 

background_camera->SetRotation(camera->GetRotation(1), 1);

 

background_world->Update();

background_world->Render();

 

world->Update();

world->Render();

 

context->Sync(false);

 

I set the main camera clear color to transparent, like this:

 

 

camera->SetClearColor(Vec4(0, 0, 0, 0));

 

 

But the clear color doesn't seem to be transparent. The background isn't visible at any point, even if there is not a single object in the main world.

 

What am I doing wrong?

Link to comment
Share on other sites

  • 3 weeks later...

I've gotten closer to a solution:

 

//Header:
#pragma once
#include "Leadwerks.h"
using namespace Leadwerks;
class App
{
public:
Leadwerks::Window* window;
Context* context;
World* world;
Camera* camera;
Camera* camera2;
Buffer* mainbuffer;
Buffer* foregroundbuffer1;
World* world2;
Texture* foregroundtexture1;
App();
virtual ~App();
virtual bool Start();
virtual bool Loop();
};
//CPP:
#include "App.h"
using namespace Leadwerks;
App::App() : window(NULL), context(NULL), world(NULL), camera(NULL) {}
App::~App() { delete world; delete window; }
Vec3 camerarotation;
#if defined (PLATFORM_WINDOWS) || defined (PLATFORM_MACOS)
bool freelookmode=true;
#else
bool freelookmode=false;
#endif
bool App::Start()
{
//Initialize Steamworks (optional)
/*if (!Steamworks::Initialize())
{
System::Print("Error: Failed to initialize Steam.");
return false;
}*/
//Create a window
window = Leadwerks::Window::Create("spectest");

//Create a context
context = Context::Create(window);

//Create a world
world = World::Create();
//Create a camera
camera = Camera::Create();
camera->Move(0,2,-5);
camera->SetMultisampleMode(4);

//Hide the mouse cursor
window->HideMouse();
mainbuffer = Buffer::GetCurrent();
foregroundbuffer1 = Buffer::Create(context->GetWidth(), context->GetHeight(), 2, 0);
foregroundtexture1 = Texture::Create(context->GetWidth(), context->GetHeight(), Texture::RGBA, 0, 1, 0);
foregroundtexture1->SetFilter(Texture::Smooth);
foregroundbuffer1->SetColorTexture(foregroundtexture1);
foregroundbuffer1->Disable();
Model* b = Model::Box();
b->SetColor(Vec4(0, 0, 1, 1));
b->SetPosition(Vec3(2, 0, 2));
Light* l = DirectionalLight::Create();
l->SetRotation(Vec3(45, 45, 45));
//Move the mouse to the center of the screen
window->SetMousePosition(context->GetWidth()/2,context->GetHeight()/2);
world2 = World::Create();
World::SetCurrent(world2);
Model::Box()->SetColor(Vec4(1,0,0,1));
camera2 = Camera::Create();
camera2->Move(0, 2, -5);
camera2->SetClearColor(Vec4(0,1,0,0));
camera2->SetMultisampleMode(4);
l = DirectionalLight::Create();
l->SetRotation(Vec3(45,45,45));
return true;
}
bool App::Loop()
{
//Close the window to end the program
if (window->Closed()) return false;

//Press escape to end freelook mode
if (window->KeyHit(Key::Escape))
{
if (!freelookmode) return false;
freelookmode=false;
window->ShowMouse();
}

if (freelookmode)
{
//Keyboard movement
float strafe = (window->KeyDown(Key:) - window->KeyDown(Key::A))*Leadwerks::Time::GetSpeed() * 0.05;
float move = (window->KeyDown(Key::W) - window->KeyDown(Key::S))*Leadwerks::Time::GetSpeed() * 0.05;
camera->Move(strafe,0,move);
//Get the mouse movement
float sx = context->GetWidth()/2;
float sy = context->GetHeight()/2;
Vec3 mouseposition = window->GetMousePosition();
float dx = mouseposition.x - sx;
float dy = mouseposition.y - sy;
//Adjust and set the camera rotation
camerarotation.x += dy / 10.0;
camerarotation.y += dx / 10.0;
camera->SetRotation(camerarotation);
//Move the mouse to the center of the screen
window->SetMousePosition(sx,sy);
}
camera2->SetMatrix(camera->GetMatrix());
Leadwerks::Time::Update();
Buffer::SetCurrent(mainbuffer);
world->Update();
world->Render();
foregroundbuffer1->Enable();
Buffer::SetCurrent(foregroundbuffer1);
world2->Update();
world2->Render();
foregroundbuffer1->Disable();
Buffer::SetCurrent(mainbuffer);
context->SetBlendMode(Blend::Alpha);
context->DrawImage(foregroundtexture1, 0, 0);
context->Sync(false);

return true;
}

 

As you can see the red Box is always in the foreground now, as it's drawn after the blue box. However you'll notice the edge around the red box which appears when multisampling is enabled. I set the clear color to green so it's more visible.

 

Also theres a problem with specular lighting. For the blue box, everything is ok, but if you take a closer look at the red box, you'll notice the specular light changing with the rotation of the camera.

 

Any tips?

 

Edit:

In case it's unclear what I'm aiming for, this is exactly what I need:

 

http://www.leadwerks.com/files/Tutorials/CPP/Rendering_Sky.pdf

 

Unfortunately this Tutorial is LE2 only.

Link to comment
Share on other sites

Here is an working example for rendering skybox as background world :

 

#include "App.h"

using namespace Leadwerks;

App::App() : window(NULL), context(NULL), world(NULL), camera(NULL) {}

App::~App() { delete world; delete window; }

Vec3 camerarotation;
#if defined (PLATFORM_WINDOWS) || defined (PLATFORM_MACOS)
bool freelookmode=true;
#else
bool freelookmode=false;
#endif

World* backworld = NULL;
Camera* skycam = NULL;
Model* skybox = NULL;
Buffer* foreground = NULL;
Buffer* background = NULL;
Texture* backtex = NULL;
Texture* fortex = NULL;

bool App::Start()
{
   //Initialize Steamworks (optional)
   /*if (!Steamworks::Initialize())
   {
       System::Print("Error: Failed to initialize Steam.");
       return false;
   }*/

   //Create a window
   window = Leadwerks::Window::Create("cpp_worlds");

   //Create a context
   context = Context::Create(window);

   //Create a world
   world = World::Create();
   backworld = World::Create();

   //create buffer for background
   background = Buffer::Create(context->GetWidth(), context->GetHeight(), 1, 0, 0);
   backtex = Texture::Create(context->GetWidth(), context->GetHeight(), Texture::RGBA, 0, 1, 0);

   //create buffer for foreground
   foreground = Buffer::Create(context->GetWidth(), context->GetHeight(), 1, 1, 0);
   fortex = Texture::Create(context->GetWidth(), context->GetHeight(), Texture::RGBA, 0, 1, 0);

   //create skybox camera in background
   World::SetCurrent(backworld);
   skycam = Camera::Create();

   //create a flipped box and paint it with sky material
   skybox = Model::Box();
   skybox->FlipNormals();
   skybox->SetMaterial(Material::Load("Materials/Sky/skybox_texture.mat"));

   //create camera for the forground
   World::SetCurrent(world);
   camera = Camera::Create();
   camera->Move(0, 2, -5);

   //Hide the mouse cursor
   window->HideMouse();

   //Load the map
   std::string mapname = System::GetProperty("map","Maps/start.map");
   Map::Load(mapname);

   //Move the mouse to the center of the screen
   window->SetMousePosition(context->GetWidth()/2,context->GetHeight()/2);

   return true;
}

bool App::Loop()
{
   //Close the window to end the program
   if (window->Closed()) return false;

   //Press escape to end freelook mode
   if (window->KeyHit(Key::Escape))
   {
       if (!freelookmode) return false;
       freelookmode=false;
       window->ShowMouse();
   }

   if (freelookmode)
   {
       //Keyboard movement
       float strafe = (window->KeyDown(Key:) - window->KeyDown(Key::A))*Leadwerks::Time::GetSpeed() * 0.05;
       float move = (window->KeyDown(Key::W) - window->KeyDown(Key::S))*Leadwerks::Time::GetSpeed() * 0.05;
       camera->Move(strafe,0,move);

       //Get the mouse movement
       float sx = context->GetWidth()/2;
       float sy = context->GetHeight()/2;
       Vec3 mouseposition = window->GetMousePosition();
       float dx = mouseposition.x - sx;
       float dy = mouseposition.y - sy;

       //Adjust and set the camera rotation
       camerarotation.x += dy / 10.0;
       camerarotation.y += dx / 10.0;
       camera->SetRotation(camerarotation);

       //Move the mouse to the center of the screen
       window->SetMousePosition(sx,sy);
   }

   Leadwerks::Time::Update();

   //Parent skybox camera to the main camera
   skycam->SetRotation(camera->GetRotation());

   //Render background
   background->Enable();
   backworld->Update();
   backworld->Render();
   background->Disable();

   //Render foreground
   foreground->Enable();
   world->Update();
   world->Render();
   foreground->Disable();

   //Draw both worlds.
   context->Enable();
   context->SetBlendMode(Blend::Alpha);
   context->DrawImage(background->GetColorTexture(), 0, 0);
   context->DrawImage(foreground->GetColorTexture(), 0, 0);
   context->SetBlendMode(Blend::Solid);

   context->Sync(false);

   return true;
}

HP Omen - 16GB - i7 - Nvidia GTX 1060 6GB

Link to comment
Share on other sites

Shadmar, your solution works fine unless you have a foreground object that has some material alpha set. If it does you will see the background behind it. This is fine if you're looking through a window, but not if you're looking at an object that's intended to be solid but is using alpha for another purpose (setting a shader value, etc)

 

I THINK what you want to try to do here is use the foreground's depth buffer as the alpha mask for the foreground (not sure--just a guess)?

--"There is no spoon"

Link to comment
Share on other sites

Shadmar,

thanks for your example! Unfortunately the problems I described still apply to it. As soon as you enable Multisampling, a visible edge appears arround the foreground objects. And the specular lighting changes with the camera rotation, which it obviously shouldn't do.

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

 Share

×
×
  • Create New...