Ivy::Math::Matrix Ivy::Math::Matrix::CreateLookAtLH(Vector3 eye, Vector3 at, Vector3 up) { glm::mat4 lookAt = lookAtLH(eye.GetRawData(), at.GetRawData(), up.GetRawData()); return Matrix(lookAt[0][0], lookAt[0][1], lookAt[0][2], lookAt[0][3], lookAt[1][0], lookAt[1][1], lookAt[1][2], lookAt[1][3], lookAt[2][0], lookAt[2][1], lookAt[2][2], lookAt[2][3], lookAt[3][0], lookAt[3][1], lookAt[3][2], lookAt[3][3]); }
void PVScene::draw(int x, int y, int w, int h) { static float time = 0.0f; time += 0.01f; viewMatrix = lookAtLH(float3(cosf(time) * 5, 2, sinf(time) * 5), float3(0, 0, 0), float3(0, 1, 0)); float4x4 viewProjectionMatrix = projectionMatrix * viewMatrix; glClearColor(0.0f, 0.0f, 0.0f, 1.0f); glClearDepth(1.0f); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glBindVertexArray(vertexArray); shader->bind(); GLuint viewProjectionLocation = shader->getUniformLocation("viewProjection"); glUniformMatrix4fv(viewProjectionLocation, 1, true, &viewProjectionMatrix.m[0][0]); GLuint lightColorLocation = shader->getUniformLocation("lightColor"); GLuint lightPositionLocation = shader->getUniformLocation("lightPosition"); GLuint numLightsLocation = shader->getUniformLocation("numLights"); float lightPositions[3 * 4]; float lightColors[3 * 4]; int numLights = lights.size(); if (numLights > 4) numLights = 4; for (int i = 0; i < numLights; i++) { PVLight *light = lights[i]; float3 lightPosition = light->getPosition(); float3 lightColor = light->getColor(); lightPositions[i * 3 + 0] = lightPosition.x; lightPositions[i * 3 + 1] = lightPosition.y; lightPositions[i * 3 + 2] = lightPosition.z; lightColors[i * 3 + 0] = lightColor.x; lightColors[i * 3 + 1] = lightColor.y; lightColors[i * 3 + 2] = lightColor.z; } glUniform3fv(lightPositionLocation, numLights, lightPositions); glUniform3fv(lightColorLocation, numLights, lightColors); glUniform1i(numLightsLocation, numLights); glEnable(GL_DEPTH_TEST); glEnable(GL_CULL_FACE); glCullFace(GL_BACK); glFrontFace(GL_CW); glViewport(x, y, w, h); for (PVMesh *mesh : meshes) mesh->draw(shader); glDisable(GL_CULL_FACE); glActiveTexture(GL_TEXTURE0); glDisable(GL_DEPTH_TEST); glUseProgram(0); glBindVertexArray(0); GLCHECK(); }
PVScene::PVScene(Scene *scene) { glGenVertexArrays(1, &vertexArray); glBindVertexArray(vertexArray); GLCHECK(); glGenBuffers(1, &vertexBuffer); glBindBuffer(GL_ARRAY_BUFFER, vertexBuffer); GLCHECK(); glEnableVertexAttribArray(0); glEnableVertexAttribArray(1); glEnableVertexAttribArray(2); glEnableVertexAttribArray(3); glVertexAttribPointer(0, 3, GL_FLOAT, false, 64, (void *)0); glVertexAttribPointer(1, 3, GL_FLOAT, false, 64, (void *)16); glVertexAttribPointer(2, 3, GL_FLOAT, false, 64, (void *)32); glVertexAttribPointer(3, 2, GL_FLOAT, false, 64, (void *)48); GLCHECK(); std::vector<Vertex> vertices; int vertexCount = 0; int vertexOffset = 0; int curr_material = scene->getTriangles()[0].material_id; for (Triangle & tri : scene->getTriangles()) { if (curr_material != tri.material_id) { addMesh(scene, curr_material, vertexOffset, vertexCount); vertexOffset += vertexCount; vertexCount = 0; curr_material = tri.material_id; } vertices.push_back(tri.v[0]); vertices.push_back(tri.v[1]); vertices.push_back(tri.v[2]); vertexCount += 3; } addMesh(scene, curr_material, vertexOffset, vertexCount); Camera *camera = scene->getCamera(); viewMatrix = lookAtLH(camera->getPosition(), camera->getTarget(), camera->getUp()); projectionMatrix = perspectiveLH(camera->getFOV(), camera->getAspectRatio(), 0.1f, 100.0f); GLCHECK(); glBufferData(GL_ARRAY_BUFFER, vertices.size() * sizeof(Vertex), &vertices[0], GL_DYNAMIC_DRAW); GLCHECK(); glBindVertexArray(0); GLCHECK(); for (int i = 0; i < scene->getNumLights(); i++) { PointLight *light = (PointLight *)scene->getLight(i); lights.push_back(new PVLight(light->getPosition(), light->getRadiance())); } shader = new PVShader(vs3d_source, fs3d_source); GLCHECK(); }