OptiX - optix7course Example 03 분석

선비Sunbei·2023년 9월 2일
0

OptiX

목록 보기
17/25
post-thumbnail
https://github.com/ingowald/optix7course

Example02에서 달라진 점 위주로 설명한다.


Example03


Example03은 Example02의 결과물을 OpenGL을 통해서 실시간 렌더링한다.

// main.cpp
#include "SampleRenderer.h"

// our helper library for window handling
#include "glfWindow/GLFWindow.h"
#include <GL/gl.h>

/*! \namespace osc - Optix Siggraph Course */
namespace osc {

  struct SampleWindow : public GLFWindow
  {
    SampleWindow(const std::string &title)
      : GLFWindow(title)
    {}
    
    virtual void render() override
    {
      sample.render();
    }
    
    virtual void draw() override
    {
      sample.downloadPixels(pixels.data());
      if (fbTexture == 0)
        glGenTextures(1, &fbTexture);
      
      glBindTexture(GL_TEXTURE_2D, fbTexture);
      GLenum texFormat = GL_RGBA;
      GLenum texelType = GL_UNSIGNED_BYTE;
      glTexImage2D(GL_TEXTURE_2D, 0, texFormat, fbSize.x, fbSize.y, 0, GL_RGBA,
                   texelType, pixels.data());

      glDisable(GL_LIGHTING);
      glColor3f(1, 1, 1);

      glMatrixMode(GL_MODELVIEW);
      glLoadIdentity();

      glEnable(GL_TEXTURE_2D);
      glBindTexture(GL_TEXTURE_2D, fbTexture);
      glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
      glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
      
      glDisable(GL_DEPTH_TEST);

      glViewport(0, 0, fbSize.x, fbSize.y);

      glMatrixMode(GL_PROJECTION);
      glLoadIdentity();
      glOrtho(0.f, (float)fbSize.x, 0.f, (float)fbSize.y, -1.f, 1.f);

      glBegin(GL_QUADS);
      {
        glTexCoord2f(0.f, 0.f);
        glVertex3f(0.f, 0.f, 0.f);
      
        glTexCoord2f(0.f, 1.f);
        glVertex3f(0.f, (float)fbSize.y, 0.f);
      
        glTexCoord2f(1.f, 1.f);
        glVertex3f((float)fbSize.x, (float)fbSize.y, 0.f);
      
        glTexCoord2f(1.f, 0.f);
        glVertex3f((float)fbSize.x, 0.f, 0.f);
      }
      glEnd();
    }
    
    virtual void resize(const vec2i &newSize) 
    {
      fbSize = newSize;
      sample.resize(newSize);
      pixels.resize(newSize.x*newSize.y);
    }

    vec2i                 fbSize;
    GLuint                fbTexture {0};
    SampleRenderer        sample;
    std::vector<uint32_t> pixels;
  };
  
  
  /*! main entry point to this example - initially optix, print hello
    world, then exit */
  extern "C" int main(int ac, char **av)
  {
    try {
      SampleWindow *window = new SampleWindow("Optix 7 Course Example");
      window->run();
      
    } catch (std::runtime_error& e) {
      std::cout << GDT_TERMINAL_RED << "FATAL ERROR: " << e.what()
                << GDT_TERMINAL_DEFAULT << std::endl;
      exit(1);
    }
    return 0;
  }
  
} // ::osc

glfw을 통해서 window를 만들고, window에 그린다.
각 frame마다 draw() 함수를 통해 그린다.

draw() 함수는 SampleRenderer에서 ray tracing 결과물을 Texture로 만들어서 결과물을 보여준다.

glGenTextures는 OpenGL에서 texture를 위한 id를 반환한다.
이때 id는 겹치치 않게끔 id를 반환할 뿐이고, device에 memory 할당은 하지 않는다.

glBindTexture 함수를 통해 glGenTextures에서 만든 texture id를 현재 texture로 사용한다. 그리고 glTexImage2D 함수를 통해서 device에 memory를 할당하지 않았었다면 할당을 하고, 해당 memory에 이미지를 채운다.

void glTexImage2D(	
    GLenum target,
 	GLint level,
 	GLint internalformat,
 	GLsizei width,
 	GLsizei height,
 	GLint border,
 	GLenum format,
 	GLenum type,
 	const void * data
    );

level은 minimap reduction image로 0으로 설정 시 기본가 된다.
border는 반드시 0으로 설정되어야 한다.

internalformat은(texFormat, GL_RGBA) texture의 내부 포맷이라는 뜻으로 OpenGL이 texture 데이터를 처리하는 방식을 지정한다. 실제 하드웨어에서 사용되는 텍스처의 데이터 형식을 나타낸다.

foramt(GL_RGBA)는 texture data의 foramt을 나타낸다. 이것은 텍스처 이미지의 실제 데이터 형식을 지정한다. internalformat과 동일할 필요는 없다.

type(GL_UNSIGNED_BYTE)는 texture 데이터의 데이터 형식(data type)을 나타낸다. GL_UNSIGNED_BYTE, GL_FLOAT 등을 사용하여 지정할 수 있다. textrue data의 각 컴포넌트가 어떤 type으로 저장되어 있는지에 대해 정의한다.

Lighting을 현재 예제에서 사용하지 않으므로 끄고, 색을 하얀색으로 설정한다.
glMatrixMode(GL_MODELVIEW)는 model space에서의 SRT를 얘기한다. (object SRT, object space to camera space 포함) glLoadIdentity() 함수는 이전 frame에서 설정한 SRT를 identity 행렬로 초기화시켜준다.

OpenGL에서 texture를 사용하기 위해서는 glEnable(GL_TEXUTRE_2D)를 설정하여 사용한다고 알려줘야 한다. glBindTexture는 위에서 만든 texture id로 현재 texture로 설정한다.
glTexParameteri는 texture에 대한 설정을 할 수 있다. 만약 확대되거나 축소되었을 때 linear interpolation을 통해서 확대, 축소를 한다.

2차원이므로 glDisable(GL_DEPTH_TEST)를 통해 깊이 검사를 하지 않는다.

glViewport는 현재 window에 이미지를 가득채우게 설정한다.

glMatrixMode(GL_PROJECTION)을 통해서 camera space to world space에 대한 변환을 하는 모드로 변경한다. 마찬가지로 glLoadIdentity() 함수로 이전 frame에서의 설정을 identity matrix로 초기화 해준다.
glOrtho 함수를 통해 정투영을 한다.

그리고 사각형 도형을 그리는데, 각 vetex와 vertex에 texture coordinate (u,v)를 매핑시킨다.

// devicePrograms.cu
  extern "C" __global__ void __raygen__renderFrame()
  {
    const int frameID = optixLaunchParams.frameID;
    if (frameID == 0 &&
        optixGetLaunchIndex().x == 0 &&
        optixGetLaunchIndex().y == 0) {
      // we could of course also have used optixGetLaunchDims to query
      // the launch size, but accessing the optixLaunchParams here
      // makes sure they're not getting optimized away (because
      // otherwise they'd not get used)
      printf("############################################\n");
      printf("Hello world from OptiX 7 raygen program!\n(within a %ix%i-sized launch)\n",
             optixLaunchParams.fbSize.x,
             optixLaunchParams.fbSize.y);
      printf("############################################\n");
  }

    // ------------------------------------------------------------------
    // for this example, produce a simple test pattern:
    // ------------------------------------------------------------------

    // compute a test pattern based on pixel ID
    const int ix = optixGetLaunchIndex().x;
    const int iy = optixGetLaunchIndex().y;

    const int r = ((ix+frameID) % 256);
    const int g = ((iy+frameID) % 256);
    const int b = ((ix+iy+frameID) % 256);

    // convert to 32-bit rgba value (we explicitly set alpha to 0xff
    // to make stb_image_write happy ...
    const uint32_t rgba = 0xff000000
      | (r<<0) | (g<<8) | (b<<16);

    // and write to frame buffer ...
    const uint32_t fbIndex = ix+iy*optixLaunchParams.fbSize.x;
    optixLaunchParams.colorBuffer[fbIndex] = rgba;
  }
    const int r = ((ix+frameID) % 256);
    const int g = ((iy+frameID) % 256);
    const int b = ((ix+iy+frameID) % 256);

Example02에서 frameID를 더하는 것만 변했다.
이를 통해서 움직이는 것과 같은 효과를 발생시킨다.

0개의 댓글