{
  "choices": [
    {
      "subContentId": "aaaaaaaa-0001-0000-0000-000000000001",
      "question": "<p>When implementing multiple light sources in OpenGL, what GLSL keyword defines a reusable light data structure passed to the shader?</p>",
      "answers": [
        "struct",
        "uniform",
        "layout",
        "attribute"
      ]
    },
    {
      "subContentId": "aaaaaaaa-0001-0000-0000-000000000002",
      "question": "<p>In the Phong reflection model, which three components are summed to produce the final fragment colour?</p>",
      "answers": [
        "Ambient, diffuse, and specular",
        "Emissive, diffuse, and refraction",
        "Ambient, reflection, and transmission",
        "Diffuse, subsurface, and occlusion"
      ]
    },
    {
      "subContentId": "aaaaaaaa-0001-0000-0000-000000000003",
      "question": "<p>How is an array of light structs declared as a uniform in GLSL?</p>",
      "answers": [
        "uniform LightData lights[MAX_LIGHTS];",
        "attribute LightData lights[];",
        "varying LightData lights[MAX_LIGHTS];",
        "in LightData lights[MAX_LIGHTS];"
      ]
    },
    {
      "subContentId": "aaaaaaaa-0001-0000-0000-000000000004",
      "question": "<p>Which OpenGL API call sets a single vec3 element inside a uniform array, for example lights[1].position?</p>",
      "answers": [
        "glUniform3fv with the indexed uniform location",
        "glVertexAttrib3f with the binding point",
        "glBufferSubData with a byte offset",
        "glUniformMatrix3fv with a stride argument"
      ]
    },
    {
      "subContentId": "aaaaaaaa-0001-0000-0000-000000000005",
      "question": "<p>Point light attenuation is commonly modelled using which formula involving distance d?</p>",
      "answers": [
        "1.0 / (kc + kl * d + kq * d * d)",
        "1.0 / (kl * d)",
        "exp(-kq * d)",
        "clamp(1.0 - d / range, 0.0, 1.0)"
      ]
    },
    {
      "subContentId": "aaaaaaaa-0001-0000-0000-000000000006",
      "question": "<p>What is the key difference between a directional light and a point light in a GLSL shader?</p>",
      "answers": [
        "A directional light has a fixed direction and no position; a point light computes direction from its world-space position to the fragment",
        "A directional light uses the view matrix; a point light uses the model matrix",
        "A directional light is stored in a UBO; a point light uses vertex attributes",
        "A directional light applies attenuation; a point light does not"
      ]
    },
    {
      "subContentId": "aaaaaaaa-0001-0000-0000-000000000007",
      "question": "<p>When accumulating the contribution of N point lights in a fragment shader, what operation combines each light's result?</p>",
      "answers": [
        "Add each light's computed colour to a running total",
        "Multiply each light's computed colour into a running product",
        "Average all contributions using a divide by N",
        "Take the maximum component-wise value across all lights"
      ]
    },
    {
      "subContentId": "aaaaaaaa-0001-0000-0000-000000000008",
      "question": "<p>In Dear ImGui, which function creates an interactive slider for a float uniform such as a light's intensity?</p>",
      "answers": [
        "ImGui::SliderFloat",
        "ImGui::InputFloat",
        "ImGui::DragScalar",
        "ImGui::Knob"
      ]
    },
    {
      "subContentId": "aaaaaaaa-0001-0000-0000-000000000009",
      "question": "<p>What GLEW call must be made after creating an OpenGL context with GLFW before any OpenGL 3.x core function can be used?</p>",
      "answers": [
        "glewInit()",
        "glInit()",
        "glfwInit()",
        "glLoadIdentity()"
      ]
    },
    {
      "subContentId": "aaaaaaaa-0001-0000-0000-000000000010",
      "question": "<p>A spotlight is differentiated from a point light by which additional property checked in the fragment shader?</p>",
      "answers": [
        "The angle between the light direction and the fragment direction must fall within a defined cutoff cone",
        "The light must be located above the horizon plane of the scene",
        "The light colour must be in the sRGB colour space",
        "The fragment must pass a stencil test before the spotlight contribution is added"
      ]
    },
    {
      "subContentId": "aaaaaaaa-0001-0000-0000-000000000011",
      "question": "<p>Which Dear ImGui window function must wrap all widget calls for a labelled panel?</p>",
      "answers": [
        "ImGui::Begin and ImGui::End",
        "ImGui::Open and ImGui::Close",
        "ImGui::Push and ImGui::Pop",
        "ImGui::StartPanel and ImGui::EndPanel"
      ]
    },
    {
      "subContentId": "aaaaaaaa-0001-0000-0000-000000000012",
      "question": "<p>To retrieve the uniform location for the second light's diffuse colour declared as uniform LightData lights[2], which string is passed to glGetUniformLocation?</p>",
      "answers": [
        "\"lights[1].diffuse\"",
        "\"lights.diffuse[1]\"",
        "\"LightData[1].diffuse\"",
        "\"diffuse[lights=1]\""
      ]
    }
  ],
  "overallFeedback": [
    {
      "from": 0,
      "to": 49,
      "feedback": "Keep reviewing the concepts."
    },
    {
      "from": 50,
      "to": 74,
      "feedback": "Good effort — a few gaps to address."
    },
    {
      "from": 75,
      "to": 100,
      "feedback": "Great work!"
    }
  ],
  "behaviour": {
    "autoContinue": false,
    "timeoutCorrect": 2000,
    "timeoutWrong": 3000,
    "soundEffectsEnabled": true,
    "enableRetry": true,
    "enableSolutionsButton": false,
    "passPercentage": 100
  },
  "l10n": {
    "nextButtonLabel": "Next question",
    "showSolutionButtonLabel": "Show solution",
    "retryButtonLabel": "Retry",
    "solutionViewTitle": "Solution list"
  }
}