2017-01-03 16 views
0

Я использую raytracer для рендеринга Sphereflake, но у меня возникают проблемы с попыткой получить больше объектов, чем объект. В приведенной ниже сцене я просто пытаюсь проверить наличие двух сфер в сцене, но по какой-то причине на сцене появляется только одна сфера и обычно ее сфера с наибольшим радиусом.C++ Raytracer - только один объект, появляющийся в сцене

Еще одна особенность в том, что в сцене есть камера, кажется, что выходное окно всегда показывает преобладающий объект в центре ((0,0) с координатами экрана между [-1, - 1] -> [1,1]), а не в отношении координатного пространства камеры.

Я не уверен, является ли это проблемой родительской иерархии или как я обрабатываю объекты, но любое понимание того, почему проблема сохраняется, будет с благодарностью.

main.cpp (создает сцены делают объекты)

#include <stdio.h> 
#include <iostream> 
#include <vector> 
#include <math.h> 
#include <glm.hpp> 
#include <gtc/matrix_transform.hpp> 

#include <Raytracer/Raytracer.h> 

using namespace glm; 
using namespace Raytracer; 
using namespace Raytracer::Scenes; 
using namespace Raytracer::Objects; 

/** 
* Places a few spheres in the scene and adds some lights. 
* 
* @param scene The scene 
*/ 
Scene *BuildScene(int depth, float aspect) 
{ 
    const int materialCount = 6; 

    vec3 colors[materialCount] = 
    { 
     vec3(1.0f, 0.0f, 0.0f), 
     vec3(1.0f, 1.0f, 0.0f), 
     vec3(0.0f, 1.0f, 0.0f), 
     vec3(0.0f, 1.0f, 1.0f), 
     vec3(0.0f, 0.0f, 1.0f), 
     vec3(1.0f, 0.0f, 1.0f) 
    }; 

    Material *materials[materialCount]; 

    for (int i = 0; i < materialCount; i++) 
    { 
     materials[i] = new Material(); 
     if (materials[i] == NULL) 
      return NULL; 

     vec3 ambient = colors[i] * 0.01f; 
     materials[i]->SetAmbient(ambient); 
     materials[i]->SetDiffuse(colors[i]); 
     materials[i]->SetShininess(25.0f); 
    } 

    if (depth <= 0) 
     return NULL; 

    // Create the scene. 
    Scene *scene = new Scene(); 
    if (scene == NULL) 
     return NULL; 

    Sphere * s1 = new Sphere(0.33f, materials[5]); 
    s1->SetPosition(vec3(5.0f, 0.0f, -2.0f)); 
    Sphere * s2 = new Sphere(0.33f, materials[1]); 
    s2->SetPosition(vec3((5.0f, 0.33f, -2.0f)); 

    s1->AddChild(s2); 

    // Create a light. 
    Light *light = new PointLight(vec3(10.0f)); 
    if (light == NULL) 
    { 
    delete scene; 
    return NULL; 
    } 

    light->SetPosition(vec3(-5.0f, 3.0f, 2.0f)); 
    scene->AddChild(light); 

    // Create a camera. 
    Camera *camera = new Camera(vec3(-2.0f, 2.0f, 4.0f), vec3(0.0f, 0.0f, 0.0f), 
    vec3(0.0f, 1.0f, 0.0f), Camera::DefaultFov, aspect); 

    scene->AddChild(s1); 

    if (camera == NULL) 
    { 
    delete scene; 
    return NULL; 
    } 
    scene->AddChild(camera); 
    scene->SetActiveCamera(camera); 

    return scene; 
} 

/** 
* Renders the scene and saves the result to a BMP file. 
* 
* @param fileName The name of the file 
* @param width The image width 
* @param height The image height 
*/ 
void Render(const char *fileName, int width, int height) 
{ 
    if (fileName == NULL || width <= 0 || height <= 0) 
    return; 

    SimpleRenderer renderer; 

    renderer.SetAccelerator(new SimpleAccelerator()); 
    renderer.SetIntegrator(new PhongIntegrator()); 

    puts("Generiere Szene..."); 
    Scene *scene = BuildScene(3, (float)width/height); 
    if (scene == NULL) 
    return; 

    puts("Rendere Bild..."); 
    Image *image = renderer.Render(*scene, width, height); 
    if (image != NULL) 
    { 
    puts("Speichere Ergebnis..."); 
    image->SaveBMP(fileName, 2.2f); 
    delete image; 
    } 

    delete scene; 
} 

/** 
* The main program 
*/ 
int main() 
{ 
    Render("image.bmp", 512, 512); 
    return 0; 
} 

примера сцены с двумя сферами, как указаны выше, с s1.radius = 0.33f & s2.radius = 0.33f

scene 1

другого примера сцены с двумя сферами с s1.radius = 0.33f & s2.radius = 1.0f

scene 2

Как вы можете видеть, камера кажется недействительной как точка перспективы, так как независимо от положения сферы, единственное различие заключается в ее освещении, но она всегда будет находиться в центре окна дисплея

+0

'vec4 pos = vec4 (s2-> GetPosition(), 1.0f) * s2-> GetTransformation() * RotationY (30); 'Делает размножение левой стороны действительно то, что вы хотите здесь? Как правило, 3d-преобразования - это 'matrix * vec', а не наоборот. – Frank

+0

извинения, это был всего лишь тестовый код, его действительно не желаемый результат, изначально у меня была позиция радиуса длиной от s1, так что две сферы были бы в сцене, касаясь, но ничто, похоже, не работает, как еще только одна сфера появляется в сцене –

ответ

0

поскольку s2 прилагается в качестве ребенка s1, он втягивается 5 единиц дальше вниз по оси X, чем s1:

s2->SetPosition(vec3((5.0f, 0.33f, -2.0f)); 
... 
s1->AddChild(s2); 

а поскольку камеры смотрит вниз положительную ось х:

Camera *camera = new Camera(vec3(-2.0f, 2.0f, 4.0f), 
    vec3(0.0f, 0.0f, 0.0f), vec3(0.0f, 1.0f, 0.0f), Camera::DefaultFov, aspect); 

s2 просто рисуется за s1.

+0

Спасибо за комментарий, я взял то, что вы сказали, и поставил positon s2 в 's2-> SetPosition (vec3 (0.0f, 0.33f, 0.0f));' и все еще появляется только один из объектов, я надеюсь, что теперь он появится поверх s1, но все равно ничего. –

+0

Одна вещь, хотя, если это так, то если второй объект рисуется с большим радиусом и помещается дальше вниз ось x, то она должна по-прежнему появляться за первой сферой, но независимо от того, что я установил для позиций, только одна сфера появляется в сцене –

+0

любая идея, почему только один объект когда-либо показывает, я прошел через функцию снова и снова d не могу размахивать головой, чтобы найти проблему –

0

Оказывается, это не было проблемой для моего сценариста, но как работает дочернее/родительское наследство в другом классе SceneObject*. Во всяком случае, я исправил функцию AddChild, и теперь код теперь работает с перспективой камеры и с множеством элементов в сцене