Как получить положение модели (объекта) в координате окна - PullRequest
0 голосов
/ 20 октября 2019

Я создаю приложение, используя OpenGL и c ++, для отображения прозрачного объекта на экране с несколькими источниками света вокруг и имитации различного возможного отражения от прозрачного объекта. Затем я сделаю снимок экрана в фиксированном положении камеры и перемещу объект случайным образом, чтобы имитировать отражение, и сохраню его как файл BMP в локальной папке вместе с текстовым файлом с тем же именем файла.

Далее мне нужно получить положение объекта в координате окна [x, y] и сохранить его в моем выходном текстовом файле.

Теперь проблема для меня состоит в том, чтобы получить местоположение объекта, как в координате окна. Например. Созданное окно - 1920 X 1080. Мне нужно расположение центра объектов в том же формате, что и [x * y].

Это мой основной cpp файл

int RandGenerator()
{

std::random_device rd;
std::default_random_engine generator(rd());
std::uniform_real_distribution<double> distribution(-3.0, 3.0);
double number = distribution(generator);    

std::this_thread::sleep_for(std::chrono::milliseconds(100));

return number;

}

int RandGenerator_1()
{

std::random_device rd;
std::default_random_engine generator(rd());
std::uniform_real_distribution<double> distribution(-3.0, 3.0); 
double number1 = distribution(generator);
std::this_thread::sleep_for(std::chrono::milliseconds(100));

return number1;

}


int main()
{
mainWindow = Window(1920, 1080);    
mainWindow.initialise();

CreateObjects();
CreateShaders();

camera = Camera(glm::vec3(0.0f, 0.0f, 7.0f), glm::vec3(0.0f, 1.0f, 0.0f), 
-90.0f, 0.0f, 5.0f, 0.2f);

shinyMaterial = Material(4.0f, 156);
dullMaterial = Material(0.5f, 4);

groundfloor = Model();
groundfloor.LoadModel("res/models/blender/Floor.obj");  

blackhawk = Model();
blackhawk.LoadModel("res/models/blender/cup.obj");

cup2 = Model();
cup2.LoadModel("res/models/blender/cup.obj");

mainLight = DirectionalLight(1.0f, 1.0f, 1.0f, 
                            0.1f, 0.1f, 
                            0.5f, -1.0f, 20.0f);

unsigned int pointLightCount = 0;

pointLights[0] = PointLight(0.0f, 0.0f,1.0f,
                            1.0f, 1.0f,
                            3.0f, 0.0f, 1.0f,
                            1.0f, 0.2f, 0.1f);

pointLightCount++;

pointLights[1] = PointLight(1.0f, 1.0f, 1.0f,
                            1.0f, 1.0f,
                            -3.0f, 0.0f, 1.0f,
                            1.0f, 0.2f, 0.1f);

pointLightCount++;  


GLuint uniformProjection = 0, uniformModel = 0, uniformView = 0, 
   uniformEyePosition = 0,
       uniformSpecularIntensity =0,uniformShininess = 0;
glm::mat4 projection = glm::perspective(45.0f, 
 (GLfloat)mainWindow.getBufferWidth() / 
 (GLfloat)mainWindow.getBufferHeight(), 
 0.1f, 100.0f); 

//Main game Loop 
while (!mainWindow.getShouldClose()) 
{
    GLfloat now = glfwGetTime();
    deltaTime = now - lastTime;
    lastTime = now;

    // Handle user inputs and events
    glfwPollEvents();

    camera.keyControl(mainWindow.getKeys(), deltaTime);
    camera.mouseControl(mainWindow.getXchange(), mainWindow.getYchange());

    //clear the window
    glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

    shaderList[0].UseShader();
    uniformProjection = shaderList[0].GetProjectionLocation();
    uniformModel = shaderList[0].GetModelLocation();
    uniformView = shaderList[0].GetViewLocation();
    uniformEyePosition = shaderList[0].GetEyePosition();
    uniformSpecularIntensity = shaderList[0].GetSpecularIntensityLoc();
    uniformShininess = shaderList[0].GetShininessLoc();

    glm::vec3 lowerLight = camera.GetCameraPosition();
    lowerLight.y -= 0.3f;

    glm::vec3 camerayaw = camera.GetCameraDirection();

    glm::vec3 dlightPos = mainLight.GetLightPos();      

    shaderList[0].SetDirectionalLight(&mainLight);
    shaderList[0].SetPointLights(pointLights, pointLightCount);
    shaderList[0].SetSpotLights(spotLights, spotLightCount);        

    glUniformMatrix4fv(uniformProjection, 1, GL_FALSE, 
    glm::value_ptr(projection));
    glUniformMatrix4fv(uniformView, 1, GL_FALSE, 
    glm::value_ptr(camera.calulateViewMatrix()));
    glUniform3f(uniformEyePosition, camera.GetCameraPosition().x, 
    camera.GetCameraPosition().y, camera.GetCameraPosition().z);        

    glEnable(GL_DEPTH_TEST);

    model = glm::mat4(1.0f);
    model = glm::translate(model, glm::vec3(0.0f, 0.0f, -0.46f));
    model = glm::scale(model, glm::vec3(0.5f, 0.5f, 0.5f));
    model = glm::rotate(model, 90.0f*toRad, glm::vec3(1.0f, 0.0f, 0.0f));
    glUniformMatrix4fv(uniformModel, 1, GL_FALSE, glm::value_ptr(model));
    dullMaterial.UseMaterial(uniformSpecularIntensity, uniformShininess);
    groundfloor.RenderModel();              

    glEnable(GL_BLEND);
    glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
    glCullFace(GL_BACK);
    glEnable(GL_CULL_FACE);
    glDepthMask(GL_FALSE);

    glm::vec3 translation(RandGenerator(), RandGenerator_1(), 0.0f);

    model = glm::mat4(1.0f);
    model = glm::translate(model, translation);
    model = glm::scale(model, glm::vec3(1.0f, 1.0f, 1.0f));
    viewmat = camera.calulateViewMatrix();
    glm::mat4 model_view = projection * viewmat * model;        
    glUniformMatrix4fv(uniformModel, 1, GL_FALSE, glm::value_ptr(model));
    shinyMaterial.UseMaterial(uniformSpecularIntensity, uniformShininess);
    blackhawk.RenderModel();

    glDisable(GL_CULL_FACE);
    glDisable(GL_BLEND);        
    glDepthMask(GL_TRUE);


    glUseProgram(0);

    mainWindow.swapBuffers();
}

return 0;}

Это моя вершинаФайл шейдера

#version 330

layout (location =0) in vec3 pos;
layout (location =1) in vec2 tex;
layout (location =2) in vec3 normal;

out vec4 vCol;
out vec2 TexCoords;
out vec3 NormalValue;
out vec3 FragPos;


uniform mat4 model;
uniform mat4 view;
uniform mat4 projection;
uniform vec3 clipSpacePos;

void main()
{
gl_Position = projection * view *  model* vec4(pos, 1.0f);  

vCol = vec4(clamp(pos, 0.0f, 1.0f), 0.2f);

TexCoords = tex;

NormalValue = mat3(transpose(inverse(model))) * normal;

FragPos = (model* vec4(pos, 1.0f)).xyz;
} 

Пожалуйста, прости меня, если вопрос очень простой, я новичок в OpenGL, а также в программировании. Заранее спасибо, Выходное изображение:

img

1 Ответ

0 голосов
/ 21 октября 2019

Чтобы получить координаты экрана из координат вашей сцены, вам нужно применить к ней все матрицы преобразования и выполнить перспективное деление.

Вы не предоставили пример кода, поэтому неясно, используете ли вы старый API или новыйодин ... а также какие матрицы (или что-то еще) и порядок умножения вы получили ...

См. эти два связанных QA:

для математических вещей, как это сделать.

Теперь, что за отражениеи прозрачность?

  1. Для реальной сделки вам нужен рендеринг трассировки лучей

    , например, что-то вроде этого:

    , но обычно это дорогое время ...

  2. Для дешевой подделки вы можете использовать Blending +техника куба окружающей средыЗадание

    Прозрачность можно сделать так:

    для отражения, которое выпросто добавьте карту куба среды. Это означает, что у вас есть скайбокс (вашего окружения) в GL_CUBE_MAP_TEXTURE, и вы вычисляете отраженный луч от нормали поверхности и направления к камере ... и добавляете соответствующий тексель карты куба к результирующему цвету ... Это также выполнимо в старом стилеAPI, но гораздо проще использовать вместо этого шейдеры.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...