컨텍스트·버전·프로파일
요청한 버전과 실제 컨텍스트를 구분하고, Core·Compatibility와 GLSL 지원을 확인합니다.
Category
Preparing references and filters for this topic. 이 주제의 레퍼런스와 필터를 준비하고 있습니다.
요청한 버전과 실제 컨텍스트를 구분하고, Core·Compatibility와 GLSL 지원을 확인합니다.
GLUT·freeglut·GLFW의 창 관리, GLAD·GLEW의 함수 로딩, GLU·GLM의 보조 역할을 구분합니다.
GLFW 3.4와 GLAD 2의 헤더·빌드·컨텍스트·함수 로딩 순서를 맞춰 OpenGL 3.3 Core를 실행합니다.
GLFW 라이브러리 + GLAD 2 생성 파일 준비
→ GLFW 초기화 → GL 3.3 Core 요청 → 창 생성
→ 현재 컨텍스트 설정 → gladLoadGL → 실제 3.3 지원 확인
→ GL 자원 생성·렌더링 → GL 자원 정리 → 창 파괴 → GLFW 종료GLUT 계열 예제를 freeglut에서 실행하고, 표시·입력 콜백과 재그리기·종료 흐름을 구분합니다.
glutInit → 버전·프로파일·표시 모드 지정 → glutCreateWindow
→ GL 함수 로딩 → display·reshape·입력 콜백 등록
→ glutMainLoop → 이벤트에 맞는 콜백 실행
→ display에서 그리기·glutSwapBuffers초기화와 매 프레임 작업을 나누고, 지우기·그리기·버퍼 교체·이벤트 처리의 순서를 맞춥니다.
한 번: 컨텍스트·로더 준비 → 버퍼·셰이더 등 자원 생성
반복: 이벤트 처리 → 크기 확인 → 상태·viewport 설정
→ 출력 지우기 → 그리기 → back buffer 표시
종료: GL 자원 정리 → 창 파괴 → 창 라이브러리 종료객체 이름·저장소·바인딩을 구분하고, 생성과 삭제를 컨텍스트의 수명에 맞춥니다.
객체 이름 준비 → 객체·저장소 생성 → 필요한 위치에 바인딩
→ 상태 설정·사용 → 참조 해제·삭제 요청 → 컨텍스트 종료현재 컨텍스트의 스레드 소유와 공유 가능한 객체를 나누고 작업 전달·가시성·종료 순서를 맞춥니다.
공유할 컨텍스트를 지정해 새 컨텍스트 생성
→ 작업 스레드에서 그 스레드의 현재 컨텍스트 설정
→ 자원 생성·업로드 → 완료 신호와 CPU 데이터 전달
→ 소비 컨텍스트에서 필요한 대기·재바인딩 → 사용실제 컨텍스트의 버전·확장·자원 제한을 읽고, 함수 로딩과 기능 지원을 구분합니다.
// GL 3.3 Core, GLAD 초기화 후
GLint count = 0;
glGetIntegerv(GL_NUM_EXTENSIONS, &count);
for (GLint i = 0; i < count; ++i) {
std::printf("%s\n", reinterpret_cast<const char*>(glGetStringi(GL_EXTENSIONS, i)));
}
GLint attributes = 0, textureSize = 0;
glGetIntegerv(GL_MAX_VERTEX_ATTRIBS, &attributes);
glGetIntegerv(GL_MAX_TEXTURE_SIZE, &textureSize);즉시 모드·클라이언트 배열·버퍼 기반 입력을 비교하고, GL 3.3 Core 삼각형의 실행 흐름을 완성합니다.
버퍼 바이트를 GLSL 입력으로 해석하는 타입·정규화·stride·offset과 VAO 상태를 맞춥니다.
// GL 3.3 Core: vao와 vbo는 생성되었고 vbo 저장소에 Vertex 배열이 있습니다.
struct Vertex {
float position[3];
unsigned char color[4];
};
glBindVertexArray(vao);
glBindBuffer(GL_ARRAY_BUFFER, vbo);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex),
reinterpret_cast<void*>(offsetof(Vertex, position)));
glVertexAttribPointer(1, 4, GL_UNSIGNED_BYTE, GL_TRUE, sizeof(Vertex),
reinterpret_cast<void*>(offsetof(Vertex, color)));
glEnableVertexAttribArray(0);
glEnableVertexAttribArray(1);DrawArrays·DrawElements의 개수·타입·오프셋과 프리미티브 연결 규칙을 구분합니다.
// GL 3.3 Core: vao의 정점 버퍼에 정점 4개, 링크된 프로그램이 준비되어 있습니다.
const unsigned short indices[] = {0, 1, 2, 2, 3, 0};
GLuint ebo = 0;
glGenBuffers(1, &ebo);
glBindVertexArray(vao);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ebo);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW);
glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_SHORT, nullptr);
// 마지막 사용 뒤 정리합니다.
glDeleteBuffers(1, &ebo);가변·불변 저장소와 SubData·복사·매핑의 사용 조건을 나누고 크기·범위를 맞춥니다.
매 프레임 갱신의 대기를 줄이기 위해 orphaning·범위 매핑·링 버퍼·영속 매핑을 비교합니다.
같은 메시의 정점과 인스턴스별 데이터를 나누고 divisor·ID·행렬 슬롯을 설정합니다.
// GL 3.3 Core: vao에는 메시 속성, instanceVbo에는 vec3 위치 배열이 있습니다.
glBindVertexArray(vao);
glBindBuffer(GL_ARRAY_BUFFER, instanceVbo);
glVertexAttribPointer(2, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), nullptr);
glEnableVertexAttribArray(2);
glVertexAttribDivisor(2, 1);
glDrawArraysInstanced(GL_TRIANGLES, 0, vertexCount, instanceCount);셰이더 컴파일과 프로그램 링크를 별도로 확인하고, 로그·실패 처리·자원 정리까지 연결합니다.
단계별: CreateShader → ShaderSource → CompileShader
→ COMPILE_STATUS·shader log
조합: CreateProgram → AttachShader → LinkProgram
→ LINK_STATUS·program log → UseProgram
정리: shader 삭제 요청 → program 사용 종료·삭제정점 속성·단계 간 변수·프래그먼트 출력을 연결하고, 보간 방식과 위치 지정의 버전 조건을 구분합니다.
// GL 3.3 Core 정점 셰이더
#version 330 core
layout(location = 0) in vec3 position;
layout(location = 1) in vec3 vertexColor;
out vec3 tint;
void main() {
gl_Position = vec4(position, 1.0);
tint = vertexColor;
}uniform의 위치·타입·배열·행렬 업로드를 프로그램 상태와 연결하고 재링크 후 갱신을 처리합니다.
// GL 3.3 Core: program은 링크 성공했고 tint uniform을 실제 사용합니다.
glUseProgram(program);
GLint tint = glGetUniformLocation(program, "tint");
if (tint >= 0) glUniform4f(tint, 1.0f, 0.5f, 0.2f, 1.0f);블록 인덱스·바인딩 포인트·버퍼 범위를 나누고 std140의 패딩과 CPU 메모리를 맞춥니다.
GLSL uniform block 선언 → 링크 → block index 조회
→ 프로그램의 block을 binding point에 연결
→ 같은 point에 UBO 바인딩 → std140 배치로 데이터 업로드통합 링크와 단계별 프로그램 조합을 비교하고 현재 프로그램·파이프라인의 우선순위를 맞춥니다.
각 program에 PROGRAM_SEPARABLE 설정 → 단계별 컴파일·링크 확인
→ program pipeline 생성 → 단계별 program 연결
→ glUseProgram(0) → pipeline 선택 → 인터페이스 검증·draw셰이더 소스·구현별 프로그램 캐시·SPIR-V 입력을 나누고 실패 시 재생성 경로를 정합니다.
행렬의 곱 순서·메모리 배치·uniform 업로드를 맞추고, 구형 행렬 스택과 비교합니다.
#version 330 core
layout(location = 0) in vec3 position;
uniform mat4 model;
uniform mat4 view;
uniform mat4 projection;
void main() {
gl_Position = projection * view * model * vec4(position, 1.0);
}투영·NDC·창 깊이를 구분하고 OpenGL 기본 규약과 clip control·reverse-Z의 조건을 연결합니다.
world → view → projection → clip 좌표
→ w로 나누기 → NDC → viewport·depth range → 창 좌표위치·법선·광원 공간을 일치시키고 고정 기능 조명을 GLSL 입력과 계산으로 나눕니다.
// GLSL 330 core, world 공간 계산의 핵심 식
// model: mat4, position/normal: vec3, lightPosition: vec3
vec3 worldPosition = vec3(model * vec4(position, 1.0));
mat3 normalMatrix = transpose(inverse(mat3(model)));
vec3 N = normalize(normalMatrix * normal);
vec3 L = normalize(lightPosition - worldPosition);
float diffuse = max(dot(N, L), 0.0);본 인덱스·가중치·변환 팔레트의 공간을 맞추고 uniform·UBO·SSBO의 선택 조건을 정리합니다.
// GL 3.3 Core / GLSL 330 core의 정점 변형 구간
// ids: ivec4, weights: vec4, bones: mat4[32], position: vec3
mat4 skin = weights.x * bones[ids.x]
+ weights.y * bones[ids.y]
+ weights.z * bones[ids.z]
+ weights.w * bones[ids.w];
vec4 skinnedPosition = skin * vec4(position, 1.0);GPU 저장 형식과 CPU 픽셀 형식을 나누고, 정렬·할당·갱신·셰이더 연결을 확인합니다.
// GL 3.3 Core: 새 컨텍스트의 기본 unpack 상태, 로더 준비 후 초기화 구간
const unsigned char pixel[] = {255, 128, 0};
GLuint texture = 0;
glGenTextures(1, &texture);
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, texture);
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB8, 1, 1, 0,
GL_RGB, GL_UNSIGNED_BYTE, pixel);
glPixelStorei(GL_UNPACK_ALIGNMENT, 4); // 이 예제의 초기 상태로 복원
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
// 사용이 끝나면 유효한 컨텍스트에서 glDeleteTextures(1, &texture);텍스처 객체·유닛·sampler uniform·sampler object가 연결되는 위치를 구분합니다.
// GL 3.3 Core, texture는 완전한 2D 텍스처, program은 링크 완료입니다.
glActiveTexture(GL_TEXTURE0 + 2);
glBindTexture(GL_TEXTURE_2D, texture);
glUseProgram(program);
glUniform1i(glGetUniformLocation(program, "albedo"), 2);확대·축소 필터, 좌표 경계, LOD와 깊이 비교를 텍스처 완전성과 함께 설정합니다.
// GL 3.3 Core: unit 0의 텍스처에 모든 필요한 밉 레벨이 준비되어 있습니다.
GLuint sampler = 0;
glGenSamplers(1, &sampler);
glSamplerParameteri(sampler, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
glSamplerParameteri(sampler, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glSamplerParameteri(sampler, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glSamplerParameteri(sampler, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glBindSampler(0, sampler);
// 마지막 사용 뒤 glBindSampler(0, 0); glDeleteSamplers(1, &sampler);레벨 크기·생성·범위와 압축 블록을 맞추고 저장소와 샘플링 완전성을 구분합니다.
기본 이미지 크기·형식 결정 → 레벨 수 계산·저장소 준비
→ 기본 레벨 업로드 또는 전체 압축 레벨 업로드
→ 밉 생성이 필요한 경우 생성 → 유효 레벨 범위·필터 설정면·레이어·볼륨 데이터를 target·좌표·샘플러·밉 레벨 구조로 구분합니다.
색 텍스처의 읽기 변환과 프레임버퍼 쓰기 변환을 나누고 HDR 값의 표시 경계를 정합니다.
sRGB 색 이미지 → sRGB internal format에서 샘플링 시 선형화
→ 선형 공간의 조명·혼합 → 필요하면 부동소수 HDR 첨부
→ tone mapping → sRGB 출력 변환을 한 번 적용 → 표시read buffer·pack 상태·PBO 오프셋을 맞추고 비동기 전송과 결과 회수 시점을 구분합니다.
// GL 3.3 Core: 읽을 framebuffer·read buffer가 선택되어 있습니다.
// GL_PIXEL_PACK_BUFFER는 0, rgba는 width*height*4 바이트 이상입니다.
glPixelStorei(GL_PACK_ALIGNMENT, 1);
glReadPixels(0, 0, width, height, GL_RGBA, GL_UNSIGNED_BYTE, rgba);기본·사용자 프레임버퍼를 구분하고 첨부 이미지, draw/read buffer와 완전성 조건을 맞춥니다.
이미지 저장소 준비 → FBO 생성·바인딩 → 첨부 연결
→ draw/read buffer 선택 → completeness 확인
→ viewport·출력 상태 설정 → draw → 다음 패스의 입력으로 사용논리 창과 픽셀 크기를 구분하고 viewport·scissor·첨부 저장소·투영을 함께 갱신합니다.
새 framebuffer 픽셀 크기 확인
→ 0 크기면 그리기 보류, 이벤트는 계속 처리
→ 크기가 바뀐 출력 이미지 재할당·FBO 확인
→ viewport·scissor 갱신 → projection 종횡비 갱신 → draw깊이 비교·기록·지우기·범위를 구분하고 불투명·투명 패스의 상태를 맞춥니다.
// GL 3.3 Core, 선택한 FBO에 깊이 저장소가 있습니다.
glEnable(GL_DEPTH_TEST);
glDepthFunc(GL_LESS);
glDepthMask(GL_TRUE);
glClearDepth(1.0);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);비교 마스크·쓰기 마스크와 세 결과별 연산을 구분해 화면 영역을 표시하고 재사용합니다.
스텐실 첨부 준비·0으로 clear
→ 마스크 패스: ALWAYS, REPLACE, 쓰기 허용
→ 색 패스: EQUAL, KEEP, 쓰기 차단
→ 스텐실 상태·색/깊이 마스크를 다음 패스 계약으로 복원색·알파의 혼합 인수와 식을 구분하고 premultiplied alpha·정렬·깊이 기록을 맞춥니다.
// GL 3.3 Core, 일반(straight) alpha 출력을 누적합니다.
glEnable(GL_BLEND);
glBlendEquationSeparate(GL_FUNC_ADD, GL_FUNC_ADD);
glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA,
GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
// premultiplied RGB이면 첫 GL_SRC_ALPHA를 GL_ONE으로 바꿉니다.앞면 판정·제거할 면·채움 방식·깊이 오프셋과 점·선 크기 제한을 구분합니다.
// GL 3.3 Core, 반시계 방향을 앞면으로 쓰는 메시
glFrontFace(GL_CCW);
glEnable(GL_CULL_FACE);
glCullFace(GL_BACK);
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);다중 샘플 저장소를 구성하고 단일 샘플 출력·후처리로 넘기는 resolve의 제약을 정리합니다.
지원 샘플 수·형식 확인 → 다중 샘플 색·깊이 첨부 구성
→ 동일 크기·샘플 조건으로 그리기
→ 단일 샘플 FBO로 resolve → 후처리·읽기·표시프리미티브 단위 입력·정점 방출·출력 한도와 레이어 지정을 구분합니다.
#version 330 core
layout(triangles) in;
layout(triangle_strip, max_vertices = 3) out;
void main() {
for (int i = 0; i < 3; ++i) {
gl_Position = gl_in[i].gl_Position;
EmitVertex();
}
EndPrimitive();
}patch 입력과 control·evaluation 단계를 연결하고 분할 레벨·간격·경계 조건을 맞춥니다.
GL 4.0 지원 → patch 정점 수 지정 → GL_PATCHES draw
→ tessellation control: 출력 제어점·분할 레벨
→ 고정 분할기 → tessellation evaluation: 생성 위치 계산
→ 래스터화 또는 geometry 단계정점 처리 출력을 버퍼에 기록하고 다음 처리에서 재사용하는 순서와 입력·출력 분리를 설명합니다.
캡처할 varying 지정 → 프로그램 링크
→ 충분한 출력 버퍼를 TF binding point에 연결
→ 필요하면 RASTERIZER_DISCARD
→ BeginTransformFeedback → draw → EndTransformFeedback
→ 입력·출력 버퍼 역할 교체작업 그룹·전역 ID·범위 검사·그룹 내 동기화를 구분하고 계산 결과를 다음 명령에 연결합니다.
#version 430 core
layout(local_size_x = 64) in;
layout(std430, binding = 0) buffer Values {
float values[];
};
uniform uint count;
void main() {
uint i = gl_GlobalInvocationID.x;
if (i >= count) return;
values[i] *= 2.0;
}셰이더의 읽기·쓰기 저장소를 타입·레이아웃·바인딩과 원자적 연산의 범위로 구분합니다.
memory barrier·fence·client/server wait·flush·finish를 소비자와 완료 조건에 따라 구분합니다.
glGetError와 디버그 콜백의 역할을 나누고 지원 확인·필터·라벨·콜백 제약을 설명합니다.
3.3 기본: 오류 의심 구간 → glGetError 반복 조회
4.3 또는 KHR_debug: 지원 확인 → debug output 활성화
→ 콜백·필터 등록 → 객체 라벨·그룹 → 메시지 분류
셰이더 실패: 위와 별개로 compile/link status·log 조회컨텍스트부터 최종 출력까지 원인을 좁히고 바인딩·셰이더·좌표·상태의 증상을 구분합니다.
단색 clear도 안 보임 → 창·현재 컨텍스트·기본 FBO·swap·크기
단색 clear는 보임 → 셰이더·VAO·draw·좌표·깊이·컬링
삼각형은 보임 → 텍스처·uniform·입력 데이터·패스 연결
특정 패스만 실패 → FBO·viewport·읽기/쓰기 충돌·이전 상태CPU 제출 시간과 GPU 쿼리를 나누고 결과 회수 지연·occlusion 판정의 비용을 설명합니다.
관찰할 패스 범위 지정 → GPU query 기록
→ 다음 프레임의 다른 작업 진행 → RESULT_AVAILABLE 확인
→ 준비된 결과만 회수 → 제출·GPU·표시 대기를 구분해 해석상태 정렬·다중 draw·GPU 명령 버퍼를 구분하고 인덱스·명령 크기·소비자 동기화를 맞춥니다.
첨부 출력과 텍스처 입력의 역할을 나누고 ping-pong·패스 상태·피드백 예외를 구분합니다.
패스 A: 이미지 A에 출력 → 패스 종료
패스 B: 이미지 A를 읽고 이미지 B에 출력
다음 반복: A/B의 읽기·쓰기 역할 교체의도적인 창 재생성과 그래픽스 reset을 구분하고 CPU 원본·공유 그룹·복구 정책을 정리합니다.
의도적 재생성: 새 환경 준비 → 보존/재생성할 자원 결정 → 이전 컨텍스트 종료
reset 감지: 새 제출 중단 → 영향 범위 확인 → 새 컨텍스트·자원 재생성
→ 지원·필수 초기 상태 확인 → 재개 또는 오류 안내·종료