목록Season 1 (107)
Graphics Programming
OpenGL 처음 배울 때 glUniform()으로 일일이 값 설정하게 짜놓은 코드를 아직도 쓰고 있다. UBO를 쓸까 말까 고민만 하다 이제야 도입하고 있다. 1. DX11에서 constant buffer를 써보니 넘 편했다. 2. model-view transform, camera position 등 한 프레임에서 일정한 유니폼들은 한 번 설정해놓고 잊어버리는 게 편하고 코드 잘못 짤 가능성도 적어진다. 원래는 셰이더 프로그램마다 이런 유니폼들을 각자 선언하고 셰이더 바뀔 때마다 업데이트했다. 이런 유니폼들은 한 프레임에 한 번만 설정하면 전부 맞거나 전부 틀리니 디버깅도 쉽다. 그런데 막상 써보니 넘 구렸다. packed, shared, std140 등 여러 레이아웃이 있지만 오프셋은 아무튼 GL ..
포워드, 디퍼드 렌더링만 만들다가... PBR을 하려니 레이트레이싱을 알아야 하는 것 같아서 뒤늦게 코딩해보고 있다. 맨날 책에서 읽고 만들어야지 하다가 말았는데 겨우 첫 걸음을 떼었다. 요즘 너무 예제 코드를 그대로 치는 것 같아서 기억에만 의존해서 코딩을 해봤는데 다행히 성공했다. 완전히 빡대가리가 되지는 않았나 보다. 그래도 머리가 예전처럼 잘 안 돌아가는 걸 느낀다. 벌써 이러면 나중에 어떡하지... 화면의 각 픽셀에 대응하는 3D 점은 무수히 많다. 그런 점들 중 하나를 uv로부터 얻어내고 가상의 카메라 위치에서 이 점으로 광선을 쏜다. 광선과 구가 교차하는지 검사하고, 그렇다면 구의 방정식에서 P(위치), N(법선) 등을 얻을 수 있다. 이후 셰이딩은 포워드/디퍼드에서 하던 것과 동일하다. 구..
OpenGL 시작할 때는 화면에 뭘 그리는 거에 관심이 있었지 코어 프로필, GL 컨텍스트 생성, OS/벤더 확장이 뭔지 관심도 없었다. 그런 것들은 튜토리얼 따라하면서 freeglut, glew 등으로 대충 떼우고 기억 속에서 잊혀졌다. 빌드 환경, 프로그램 초기화 과정, 버전 관리가 중요하다는 걸 깨닫고 뒤늦게 신경쓰고 있다. DirectX 11, Vulkan을 디버깅할 때 RenderDoc를 유용하게 써서 OpenGL에도 써볼려고 했더니 나니? GL 4.6인데? 검색을 좀 해보니 freeglut에서 OpenGL 컨텍스트 버전과 프로필을 명시해야 하는 것 같다. // glutInit() 호출 후glutInitContextVersion(4, 3);glutInitContextProfile(GLUT_COR..
불칸 책을 다 읽고 뭔가를 만들려고 보니 코딩 분량이 너무 막막해서 예전에 버린 OpenGL 프로젝트를 다시 꺼내들었다.PBR을 조금 알아봤는데 계산만 복잡하지 기존의 블린-퐁 셰이딩과 구현 방법이 별로 다르지 않아서 이거나 해볼려고 했는데 프로젝트를 열어보니 DOF를 만들다 말았었다. DOF는 대략 이런 식으로 구현한다.1. 일단 장면을 그린다.2. 장면 텍스처의 subsum을 컴퓨트 셰이더로 계산한다.3. subsum을 가지고 박스 블러를 계산한다. 이 때 박스 블러의 세기는 각 픽셀의 깊이값을 가지고 결정한다. 뷰에 의존적인 이펙트여서 뷰 스페이스에서 픽셀의 z값을 가지고 계산해야 하는데 내 디퍼드 렌더러를 가만히 보니 라이팅 계산을 월드 스페이스에서 하고 있다. 다행히 추가로 바꿀 것은 별로 없었..
베이스가 되는 Packet 클래스가 있고, 이를 상속한 PacketA, PacketB, PacketC 클래스가 있다. 그리고 각 패킷 클래스에 대응하는 enum이 있다. // packet.henum class PacketType : uint16_t {PACKET_A = 0,PACKET_B = 1,PACKET_C = 2,NUM_PACKETS = 3} struct Packet {Packet(PacketType type);PacketType type;}; struct PacketA : Packet {PacketA();}; struct PacketB : Packet {PacketB();}; struct PacketC : Packet {PacketC();}; // packet.cpp Packet::Packet(P..
로그를 찍을 때 작업의 디테일한 정도나 호출 순서를 알아보기 쉽게 하려고 들여쓰기를 쓰는 경우가 있다. 단순한 상황으로 함수 A 안에서 함수 B를 호출할 때, 콘솔에 A를 쓰고 들여쓰기한 다음 B를 쓴다고 치자. #include void A() { std::cout
※ 이 글은 미완성입니다.※ 혼동의 여지가 있는 용어는 그대로 적었습니다. 실제 코드와 관련된 경우 영어 단어를 그대로 쓴 것도 있습니다. 목표: 절대로 다 번역하지 못한다. 쭉 훑어보면서 핵심만 번역하고 4.5와의 차이에 집중 OpenGL 4.6 Core: https://www.khronos.org/registry/OpenGL/specs/gl/glspec46.core.pdfGLSL 4.6: https://www.khronos.org/registry/OpenGL/specs/gl/GLSLangSpec.4.60.pdf OpenGL 4.6 Core 목차서문OpenGL 명세서의 서식OpenGL 그래픽스 시스템이란 무엇인가관련 API버그 리포트 작성OpenGL 기초실행 모델커맨드 신택스스테이트 설정 커맨드를 위한..
[MSDN] Thread Pools: https://msdn.microsoft.com/en-us/library/windows/desktop/ms686760(v=vs.85).aspx 쓰레드를 직접 생성하고 관리하는 것이 아니라 워크 오브젝트를 쓰레드 풀에 제출한다. 쓰레드를 생성할 때 콜백 함수와 콜백 함수가 받을 인자를 지정하는데, 워크 오브젝트도 마찬가지다. 쓰레드 풀은 윈도우즈 커널이 알아서 관리하며, 제출된 워크 오브젝트들을 적절히 스케줄링하여 처리한다. // 의 예제 코드를 조금 수정한 것 #include #include #include #include /* 1. Invoke InitializeThreadpoolEnvironment().2. Create work objects.3. Invoke S..