OpenGL World To Screen ve Screen To World

Merhabalar. Projem için gerekli olan w2s ve s2s fonksiyonlarını araştırıyordum. Ancak ingilizce kaynak bile az sayıda vardı ve hepsi anlaşılır değildi. Uzun bir uğraş istediğim sonuca ulaştım ve kaynak yetersizliğinden dolayı kendi derlediğim bu kodları internette paylaşmaya karar verdim.



glm::vec2 WorldToScreen(glm::mat4 viewMatrix,
      glm::mat4 projectionMatrix, glm::vec3 point)
{
 glm::mat4 mvpmatrix = projectionMatrix * viewMatrix;
 const float *pSource = (const float *)glm::value_ptr(mvpmatrix);
 glm::vec4 clipCoords;
 clipCoords.x = point.x * pSource[0] + point.y * pSource[4] + point.z * pSource[8] + pSource[12];
 clipCoords.y = point.x * pSource[1] + point.y * pSource[5] + point.z * pSource[9] + pSource[13];
 clipCoords.z = point.x * pSource[2] + point.y * pSource[6] + point.z * pSource[10] + pSource[14];
 clipCoords.w = point.x * pSource[3] + point.y * pSource[7] + point.z * pSource[11] + pSource[15];

 glm::vec3 normalizedDeviceCoordinates;
 normalizedDeviceCoordinates.x = clipCoords.x / clipCoords.w;
 normalizedDeviceCoordinates.y = clipCoords.y / clipCoords.w;
 normalizedDeviceCoordinates.z = clipCoords.z / clipCoords.w;

 GLint viewport[4] = {0};
 glGetIntegerv(GL_VIEWPORT, viewport); // viewport = (0, 0, width, height)
 glm::vec3 winPos;
 winPos.x = (viewport[2] / 2 * normalizedDeviceCoordinates.x) + (normalizedDeviceCoordinates.x + viewport[2] / 2);
 winPos.y = -(viewport[3] / 2 * normalizedDeviceCoordinates.y) + (normalizedDeviceCoordinates.y + viewport[3] / 2);
 winPos.z = 0;

 return winPos;
}

glm::vec3 ScreenToWorld(glm::mat4 viewMatrix, glm::mat4 projectionMatrix, glm::vec2 point)
{
 GLfloat winX, winY, winZ;
 GLint viewport[4] = {0};
 glGetIntegerv(GL_VIEWPORT, viewport); // viewport = (0, 0, width, height)

 winX = (float)point.x;
 winY = (float)viewport[3] - (float)point.y;
 glReadPixels(point.x, int(winY), 1, 1, GL_DEPTH_COMPONENT, GL_FLOAT, &winZ);

 glm::vec3 ret = glm::unProject(glm::vec3(winX, winY, winZ), viewMatrix, projectionMatrix, glm::vec4(viewport[0], viewport[1], viewport[2], viewport[3]));
 return ret;
}

       

Yorumlar